Delphi Pages Forums  

Go Back   Delphi Pages Forums > Delphi Forum > General

Lost Password?

Reply
 
Thread Tools Display Modes
  #1  
Old 09-03-2009, 09:47 PM
Jasser Jasser is offline
Moderator
 
Join Date: Jan 2005
Location: Saudi Arabia
Posts: 5,060
Default GetDiskSerialNumber

I use the bellow function to get hard drive manufacture serial number. It works under XP but with VISTA the "CreatFile" function fails. I think it has something to do with the privilege parameter (the fourth parameter). Anybody knows how to get the right privilege to make the call?


Code:
Function GetDiskSerialNumber : String;
const
         IDENTIFY_BUFFER_SIZE = 512;
type
         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 for future use.  Must be zero.
         end;
         TSendCmdInParams = packed record
            // Buffer size in bytes
            cBufferSize  : DWORD;
            // Structure with drive register values.
            irDriveRegs  : TIDERegs;
            // Physical drive number to send command to (0,1,2,3).
            bDriveNumber : BYTE;
            bReserved    : Array[0..2] of Byte;
            dwReserved   : Array[0..3] of DWORD;
            bBuffer      : Array[0..0] of Byte;  // Input buffer.
         end;
         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    : DWORD;
            wMultSectorStuff           : Word;
            ulTotalAddressableSectors  : DWORD;
            wSingleWordDMA             : Word;
            wMultiWordDMA              : Word;
            bReserved                  : Array[0..127] of BYTE;
         end;
         PIdSector = ^TIdSector;
         TDriverStatus = packed record
            // Error code from driver, or 0 if no error.
            bDriverError : Byte;
            // Contents of IDE Error register. Only valid when bDriverError is SMART_IDE_ERROR.
            bIDEStatus   : Byte;
            bReserved    : Array[0..1] of Byte;
            dwReserved   : Array[0..1] of DWORD;
         end;
         TSendCmdOutParams = packed record
            // Size of bBuffer in bytes
            cBufferSize  : DWORD;
            // Driver status structure.
            DriverStatus : TDriverStatus;
            // Buffer of arbitrary length in which to store the data read from the drive.
            bBuffer      : Array[0..0] of BYTE;
         end;

var
         hDevice : THandle;
         cbBytesReturned : DWORD;
         SCIP : TSendCmdInParams;
         aIdOutCmd : Array [0..(SizeOf(TSendCmdOutParams)+IDENTIFY_BUFFER_SIZE-1)-1] of Byte;
         IdOutCmd  : TSendCmdOutParams absolute aIdOutCmd;
         Security  : PSecurityAttributes;

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 := ''; // return empty string on error

         Security.nLength := 100;
         Security.lpSecurityDescriptor := nil;
         Security.bInheritHandle := True;

         if SysUtils.Win32Platform=VER_PLATFORM_WIN32_NT then begin// Windows NT, Windows 2000
            // warning! change name for other drives: ex.: second drive '\\.\PhysicalDrive1\'
            hDevice := CreateFile( '\\.\PhysicalDrive0',
                                   GENERIC_READ    or GENERIC_WRITE,
                                   FILE_SHARE_READ or FILE_SHARE_WRITE,
                                   nil,
                                   OPEN_EXISTING,
                                   0,
                                   0 );

         end else // Version Windows 95 OSR2, Windows 98
            hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 );

         if hDevice=INVALID_HANDLE_VALUE then
            Exit;

         try
            FillChar(SCIP,SizeOf(TSendCmdInParams)-1,#0);
            FillChar(aIdOutCmd,SizeOf(aIdOutCmd),#0);
            cbBytesReturned := 0;
            // Set up data structures for IDENTIFY command.
            with SCIP do begin
                 cBufferSize  := IDENTIFY_BUFFER_SIZE;
                 irDriveRegs.bSectorCountReg  := 1;
                 irDriveRegs.bSectorNumberReg := 1;
                 irDriveRegs.bDriveHeadReg    := $A0;
                 irDriveRegs.bCommandReg      := $EC;
            end;
            if NOT DeviceIoControl( hDevice, $0007c088, @SCIP, SizeOf(TSendCmdInParams)-1,@aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil ) then
               exit;
         finally
            CloseHandle(hDevice);
         end;

         with PIdSector(@IdOutCmd.bBuffer)^ do begin
              ChangeByteOrder( sSerialNumber, SizeOf(sSerialNumber) );
             (PChar(@sSerialNumber)+SizeOf(sSerialNumber))^ := #0;
              Result := Trim(PChar(@sSerialNumber));
         end;
end;
__________________
Regards,
Abdulaziz Jasser
Reply With Quote
  #2  
Old 09-03-2009, 11:48 PM
Glenn1234 Glenn1234 is offline
Senior Member
 
Join Date: Aug 2009
Posts: 131
Default

http://www.microsoft.com/communities...r=HK&sloc=&p=1

It would seem that your code is incompatible with Vista. The solution that seems to be indicated is to use the WMI class Win32_DiskDrive in order to accomplish this.

http://msdn.microsoft.com/en-us/libr...32(VS.85).aspx
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump


All times are GMT. The time now is 06:26 PM.


Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2019, vBulletin Solutions, Inc.