Cette routine me servait autrefois de limiter l'exécution d'un logiciel sur la machine d'un utilisateur via le numéro de serie du disque physique qu'elle renvoie sous DELPHI 7 Entreprise passée sous DELPHI 2009 Architecte apparemment et dans la limite de mes connaissances aucun message que se soit n'est notifié mais la valeur de retour est une chaine vide,
la fonction GetLastError renvoie le message " Indique Deux Numéros de Version Incompatibles ".

Eclairez-moi si c'est possible.
Os Xp SP2
---------------------------------------

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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; // especificar "comandos" SMART 
     bSectorCountReg  : Byte; // registro de contador de setor 
     bSectorNumberReg : Byte; // registro de número de setores 
     bCylLowReg       : Byte; // valor de cilindro (byte mais baixo) 
     bCylHighReg      : Byte; // valor de cilindro (byte mais alto) 
     bDriveHeadReg    : Byte; // registro de drive/cabeça 
     bCommandReg      : Byte; // comando IDE 
     bReserved        : Byte; // reservado- tem que ser 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 
   // Windows NT, Windows 2000, Windows XP 
   begin 
   // recuperar handle da porta SCSI 
     hDevice := CreateFile('\\.\Scsi0:', 
     // Nota: '\\.\C:' precisa de privilégios administrativos 
     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, Windows ME 
     hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 ); 
     if hDevice=INVALID_HANDLE_VALUE then Exit; 
     try 
       pInData := PSendCmdInParams(@Buffer); 
       pOutData := @pInData^.bBuffer; 
       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, DFP_RECEIVE_DRIVE_DATA, 
       pInData, SizeOf(TSendCmdInParams)-1, pOutData, W9xBufferSize, cbBytesReturned, nil ) then 
         Exit; 
       finally 
         CloseHandle(hDevice); 
       end; 
     end; 
 
     with PIdSector(PChar(pOutData)+16)^ do 
     begin 
       ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber)); 
       SetString(Result,sSerialNumber,SizeOf(sSerialNumber)); 
     end; 
end;


how to call the function:
1) Create this variables:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
       s : String; 
       rc : DWORD;
2) on onClick of Event of Button, paste this code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
     s := GetIdeDiskSerialNumber; 
     if s='' then 
     begin 
       rc := GetLastError; 
       if rc=0 then 
         showmessage('Drive IDE don´t suport SMART') 
       else 
         showmessage(SysErrorMessage(rc)); 
     end 
     else 
       showmessage('Fisical serial number disk is: ' + s);