设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 3938|回复: 5
打印 上一主题 下一主题

如何用API的GetVolumeInformation 调用磁盘卷序列号

[复制链接]
跳转到指定楼层
1#
发表于 2002-7-5 18:36:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
同上
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅
2#
发表于 2002-7-5 22:58:00 | 只看该作者
为方便你我查阅现将有关内容贴如下:
What are APIs, why use them, how to use them, and how to find out more
What are APIs?
API stands for Application Programming Interface. Essentially, it is a way of interfacing with the Windows environment.
Why use APIs
There are several reasons why you might wish to use APIs instead of or in addition to the built-in VBA functions:
Speed - although there might be only a fraction of a millisecond's difference between a VBA function and using an API call, if you are using it repeatedly, then this difference mounts up. A good example of this is recursively searching for a file through the directories and sub-directories;
Reliability - you wish to ensure a more reliable application, either to avoid 'DLL Hell', caused by setting a reference to a particular version of a common dll, such as ComCtl32.dll, or a setting that can be 'confused', such as Environ;
Extensibility - you wish to perform something that cannot be achieved using VBA functions.
However, there is a steep learning curve with APIs - you are more likely to either crash Access or even the system when testing APIs. Therefore saving your code before you test it is vital. Fortunately, once you have the code working, there shouldn't be any problems.

How to use APIs?
In general, an API is declared as below:
[Private|Public] Declare [Function|Sub] APIName Lib [DLLName] (Alias APIName) (Arguments) (Return Type)

For example:

Private Declare Function apiGetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Long) As Long

[Private|Public]:

This determines the scope of the function of subprocedure. This is mostly a matter of preference. I prefer to declare my API calls private within a module, and then use a function to call them. This allows me to have a module that is stand-alone and can be copied to another database without reliance on other modules.

[Function|Sub]:

Whether it is a subprocedure or a function. Nearly all APIs are functions, and they nearly all return a value directly.

[DLLName]:

The name of the DLL that the procedure is in. For the standard DLLs, user32.dll, kernel32.dll or gdi32.dll you can omit the file extension, but for all other DLLs you must include the file extension.

(Alias APIName):

If you have declared the API as being different from the name that it is known within the DLL you must specify the correct name here. There are several reasons why you may wish to do this:

The name of the API is not a valid VBA function name, such as '_lwrite';
You are declaring it twice, for example to accept different argument types to get around the 'As Any' variable type;
You wish to have a common naming policy for API calls, such as prefixing them all with 'api'
Note that the API name must be in the correct case - 'findfile' is not equal to 'FINDFILE'
(Arguments):

As with VBA procedures, APIs may accept various arguments. However, this is one area where care needs to be taken to ensure that you pass ByRef or ByValue as needed. You will often also need to predeclare string arguments to be a certain length. You may also find that you pass a Type Structure as an argument, and the values that you want are in that Type Structure.

(Return Value):

The datatype that the API returns. Normally this will be a Long Integer, with 0 often indicating an error.

How to find out more about them
There are several very good resources for APIs, both written and on the Web:
Site Notes
The Access Web Over 60 APIs set up for use in Access, including using the Windows File Open/Save dialog box and returning the name of the user logged into the Operating System.  
Randy Birch's VBNet A VB-orientated site that covers more APIs, but for a VB environment
AllAPI.net A huge site that lists most, if not all, of the Windows APIs in great detail, including a description of the various arguments that are required, as well as examples.
Windows API Guide Another site dealing with Windows APIs for the VB programmer. Unfortunately, this will no longer be kept current.

Book Notes
VBA Devel
3#
 楼主| 发表于 2002-7-6 00:33:00 | 只看该作者
非常感谢,但英文俺不懂
4#
发表于 2002-7-6 16:38:00 | 只看该作者

磁盘的序列号每次格式化都会不一样的。用处不大呢

‘这句是Declare陈述式宣告一个API函数。
Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long

Private sub buttoncommand_click()  ‘请在窗体上建一个按钮
Dim x
If Isnull(me.text1) then        ‘请在窗体建一个文本框text1以输入硬盘分区用。
    Msgbox “未输入磁碟机分区代号,无法查询”
Exit sub
Endif

If len (me.text1)<3 then
    X=left(me.text1,1) & “:\”
Else
    X=left(me.text1,3)
Endif

Dim nRet as long ,VolName as string, VolSN as long,MaxComplen as long
Dim VolFlags as long , VolFileSys as string
    Volname=Space$(256)
    VolFileSys=Space$(256)
    nRet=GetVolumeinformation(x,Volname,Len(Volname),VolSN,MaxCompLen,VolFalgs,VolFileSys,Len(VolFileSys))

If nRet=1 then
   me.Lable1.Caption=”Volumn Name为” & Volname‘请在窗体建一个Lable1的标签
   me.lable2.Caption=”Serial Number为” & VolSN‘请在窗体建一个Lable2的标签
Else
   me.Lable1.Caption=”代码输入错误”
   me.lable2.Caption=””
Endif
End sub


另外加一段API的中文说明
GetVolumeInformation

VB声明
Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long
说明
获取与一个磁盘卷有关的信息
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
参数表
参数 类型及说明
lpRootPathName String,欲获取信息的那个卷的根路径
lpVolumeNameBuffer String,用于装载卷名(卷标)的一个字串
nVolumeNameSize Long,lpVolumeNameBuffer字串的长度
lpVolumeSerialNumber Long,用于装载磁盘卷序列号的变量
lpMaximumComponentLength Long,指定一个变量,用于装载文件名每一部分的长度。例如,在“c:\component1\component2.ext”的情况下,它就代表component1或component2名称的长度
lpFileSystemFlags Long,用于装载一个或多个二进制位标志的变量。对这些标志位的解释如下:
FS_CASE_IS_PRESERVED 文件名的大小写记录于文件系统
FS_CASE_SENSITIVE 文件名要区分大小写
FS_UNICODE_STORED_ON_DISK 文件名保存为Unicode格式
FS_PERSISTANT_ACLS 文件系统支持文件的访问控制列表(ACL)安全机制
FS_FILE_COMPRESSION 文件系统支持逐文件的进行文件压缩
FS_VOL_IS_COMPRESSED 整个磁盘卷都是压缩的
lpFileSystemNameBuffer String,指定一个缓冲区,用于装载文件系统的名称(如FAT,NTFS以及其他)
nFileSystemNameSize Long,lpFileSystemNameBuffer字串的长度

5#
 楼主| 发表于 2002-7-7 07:57:00 | 只看该作者
多谢,可用作软件注册
6#
发表于 2002-9-28 01:03:00 | 只看该作者
我用他取Ide硬盘序列号:
function GetIdeDiskSerialNumber : String;
type
TSrbIoControl = packed record
HeaderLength : ULONG;
Signature : Array[0..7] of Char;
Timeout : ULONG;
ControlCode : ULONG;
ReturnCode : ULONG;
Length : ULONG;
end;
SRB_IO_CONTROL = TSrbIoControl;
PSrbIoControl = ^TSrbIoControl;

TIDERegs = packed record
bFeaturesReg : Byte; // Used for specifying SMART "commands".
bSectorCountReg : Byte; // IDE sector count register
bSectorNumberReg : Byte; // IDE sector number register
bCylLowReg : Byte; // IDE low order cylinder value
bCylHighReg : Byte; // IDE high order cylinder value
bDriveHeadReg : Byte; // IDE drive/head register
bCommandReg : Byte; // Actual IDE command.
bReserved : Byte; // reserved. Must be zero.
end;
IDEREGS = TIDERegs;
PIDERegs = ^TIDERegs;

TSendCmdInParams = packed record
cBufferSize : DWORD;
irDriveRegs : TIDERegs;
bDriveNumber : Byte;
bReserved : Array[0..2] of Byte;
dwReserved : Array[0..3] of DWORD;
bBuffer : Array[0..0] of Byte;
end;
SENDCMDINPARAMS = TSendCmdInParams;
PSendCmdInParams = ^TSendCmdInParams;

TIdSector = packed record
wGenConfig : Word;
wNumCyls : Word;
wReserved : Word;
wNumHeads : Word;
wBytesPerTrack : Word;
wBytesPerSector : Word;
wSectorsPerTrack : Word;
wVendorUnique : Array[0..2] of Word;
sSerialNumber : Array[0..19] of Char;
wBufferType : Word;
wBufferSize : Word;
wECCSize : Word;
sFirmwareRev : Array[0..7] of Char;
sModelNumber : Array[0..39] of Char;
wMoreVendorUnique : Word;
wDoubleWordIO : Word;
wCapabilities : Word;
wReserved1 : Word;
wPIOTiming : Word;
wDMATiming : Word;
wBS : Word;
wNumCurrentCyls : Word;
wNumCurrentHeads : Word;
wNumCurrentSectorsPerTrack : Word;
ulCurrentSectorCapacity : ULONG;
wMultSectorStuff : Word;
ulTotalAddressableSectors : ULONG;
wSingleWordDMA : Word;
wMultiWordDMA : Word;
bReserved : Array[0..127] of Byte;
end;
PIdSector = ^TIdSector;

const
IDE_ID_FUNCTION = $EC;
IDENTIFY_BUFFER_SIZE = 512;
DFP_RECEIVE_DRIVE_DATA = $0007c088;
IOCTL_SCSI_MINIPORT = $0004d008;
IOCTL_SCSI_MINIPORT_IDENTIFY = $001b0501;
DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;
BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize;
W9xBufferSize = IDENTIFY_BUFFER_SIZE+16;
var
hDevice : THandle;
cbBytesReturned : DWORD;
pInData : PSendCmdInParams;
pOutData : Pointer; // PSendCmdOutParams
Buffer : Array[0..BufferSize-1] of Byte;
srbControl : TSrbIoControl absolute Buffer;

procedure ChangeByteOrder( var Data; Size : Integer );
var ptr : PChar;
i : Integer;
c : Char;
begin
ptr := @Data;
for i := 0 to (Size shr 1)-1 do
begin
c := ptr^;
ptr^ := (ptr+1)^;
(ptr+1)^ := c;
Inc(ptr,2);
end;
end;

begin
Result := '';
FillChar(Buffer,BufferSize,#0);
if Win32Platform=VER_PLATFORM_WIN32_NT then
begin // Windows NT, Windows 2000
// Get SCSI port handle
hDevice := CreateFile( '\\.\Scsi0:',
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0 );
if hDevice=INVALID_HANDLE_VALUE then Exit;
try
srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
System.Move('SCSIDISK',srbControl.Signature,8);
srbControl.Timeout := 2;
srbControl.Length := DataSize;
srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;
pInData := PSendCmdInParams(PChar(@Buffer)
+SizeOf(SRB_IO_CONTROL));
pOutData := pInData;
with pInData^ do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
bDriveNumber := 0;
with irDriveRegs do
begin
bFeaturesReg := 0;
bSectorCountReg := 1;
bSectorNumberReg := 1;
bCylLowReg := 0;
bCylHighReg := 0;
bDriveHeadReg := $A0;
bCommandReg := IDE_ID_FUNCTION;
end;
end;
if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT,
@Buffer, BufferSize, @Buffer, BufferSize,
cbBytesReturned, nil ) then Exit;
finally
CloseHandle(hDevice);
end;
end
else
begin // Windows 95 OSR2, Windows 98
hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil,
CREATE_NEW, 0, 0 );
if hDevice=INVALID
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-18 10:57 , Processed in 0.082094 second(s), 29 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表