{"id":745,"date":"2008-05-25T08:02:01","date_gmt":"2008-05-25T08:02:01","guid":{"rendered":"http:\/\/6teen.ru\/?p=690"},"modified":"2008-05-25T08:02:01","modified_gmt":"2008-05-25T08:02:01","slug":"9720","status":"publish","type":"post","link":"http:\/\/pblog.ru\/lab\/?p=745","title":{"rendered":"\u0421\u0435\u0440\u0438\u0439\u043d\u044b\u0435 \u043d\u043e\u043c\u0435\u0440\u0430 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0436\u0435\u0441\u0442\u043a\u0438\u0445 \u0434\u0438\u0441\u043a\u043e\u0432"},"content":{"rendered":"<p>\u0421\u0435\u0440\u0438\u0439\u043d\u044b\u0435 \u043d\u043e\u043c\u0435\u0440\u0430 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0436\u0435\u0441\u0442\u043a\u0438\u0445 \u0434\u0438\u0441\u043a\u043e\u0432<br \/>\n<!--more--><\/p>\n<pre class=\"alt2\" style=\"margin:0px; padding:6px; border:1px inset; width:580px; height:320px; overflow:auto\"><div>\u0421\u0435\u0440\u0438\u0439\u043d\u044b\u0435 \u043d\u043e\u043c\u0435\u0440\u0430 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0436\u0435\u0441\u0442\u043a\u0438\u0445 \u0434\u0438\u0441\u043a\u043e\u0432\n\nfunction GetIdeDiskSerialNumber(tomnum: integer) : String;\ntype\n  TSrbIoControl = packed record\n    HeaderLength : ULONG;\n    Signature : Array[0..7] of Char;\n    Timeout : ULONG;\n    ControlCode : ULONG;\n    ReturnCode : ULONG;\n    Length : ULONG;\n  end;\n  SRB_IO_CONTROL = TSrbIoControl;\n  PSrbIoControl = ^TSrbIoControl;\n\n  TIDERegs = packed record\n    bFeaturesReg : Byte; \/\/ Used for specifying SMART \"commands\".\n    bSectorCountReg : Byte; \/\/ IDE sector count register\n    bSectorNumberReg : Byte; \/\/ IDE sector number register\n    bCylLowReg : Byte; \/\/ IDE low order cylinder value\n    bCylHighReg : Byte; \/\/ IDE high order cylinder value\n    bDriveHeadReg : Byte; \/\/ IDE drive\/head register\n    bCommandReg : Byte; \/\/ Actual IDE command.\n    bReserved : Byte; \/\/ reserved for future use. Must be zero.\n  end;\n  IDEREGS = TIDERegs;\n  PIDERegs = ^TIDERegs;\n\n  TSendCmdInParams = packed record\n    cBufferSize : DWORD; \/\/ Buffer size in bytes\n    irDriveRegs : TIDERegs; \/\/ Structure with drive register values.\n    bDriveNumber : Byte; \/\/ Physical drive number to send command to (0,1,2,3).\n    bReserved : Array[0..2] of Byte; \/\/ Reserved for future expansion.\n    dwReserved : Array[0..3] of DWORD; \/\/ For future use.\n    bBuffer : Array[0..0] of Byte; \/\/ Input buffer.\n  end;\n  SENDCMDINPARAMS = TSendCmdInParams;\n  PSendCmdInParams = ^TSendCmdInParams;\n\n  TIdSector = packed record\n    wGenConfig : Word;\n    wNumCyls : Word;\n    wReserved : Word;\n    wNumHeads : Word;\n    wBytesPerTrack : Word;\n    wBytesPerSector : Word;\n    wSectorsPerTrack : Word;\n    wVendorUnique : Array[0..2] of Word;\n    sSerialNumber : Array[0..19] of Char;\n    wBufferType : Word;\n    wBufferSize : Word;\n    wECCSize : Word;\n    sFirmwareRev : Array[0..7] of Char;\n    sModelNumber : Array[0..39] of Char;\n    wMoreVendorUnique : Word;\n    wDoubleWordIO : Word;\n    wCapabilities : Word;\n    wReserved1 : Word;\n    wPIOTiming : Word;\n    wDMATiming : Word;\n    wBS : Word;\n    wNumCurrentCyls : Word;\n    wNumCurrentHeads : Word;\n    wNumCurrentSectorsPerTrack : Word;\n    ulCurrentSectorCapacity : ULONG;\n    wMultSectorStuff : Word;\n    ulTotalAddressableSectors : ULONG;\n    wSingleWordDMA : Word;\n    wMultiWordDMA : Word;\n    bReserved : Array[0..127] of Byte;\n  end;\n  PIdSector = ^TIdSector;\n\nconst\n  IDE_ID_FUNCTION = $EC;\n  IDENTIFY_BUFFER_SIZE = 512;\n  DFP_RECEIVE_DRIVE_DATA = $0007c088;\n  IOCTL_SCSI_MINIPORT = $0004d008;\n  IOCTL_SCSI_MINIPORT_IDENTIFY = $001b0501;\n  DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;\n  BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize;\n  W9xBufferSize = IDENTIFY_BUFFER_SIZE+16;\nvar\n  hDevice : THandle;\n  cbBytesReturned : DWORD;\n  pInData : PSendCmdInParams;\n  pOutData : Pointer; \/\/ PSendCmdInParams;\n  Buffer : Array[0..BufferSize-1] of Byte;\n  srbControl : TSrbIoControl absolute Buffer;\n\n  procedure ChangeByteOrder( var Data; Size : Integer );\n  var ptr : PChar;\n      i : Integer;\n      c : Char;\n  begin\n    ptr := @Data;\n    for i := 0 to (Size shr 1)-1 do\n    begin\n      c := ptr^;\n      ptr^ := (ptr+1)^;\n      (ptr+1)^ := c;\n      Inc(ptr,2);\n    end;\n  end;\n\nbegin\n  Result := '';\n  FillChar(Buffer,BufferSize,#0);\n  if Win32Platform=VER_PLATFORM_WIN32_NT then\n    begin \/\/ Windows NT, Windows 2000\n      \/\/ Get SCSI port handle\n      hDevice := CreateFile( '\\\\.\\Scsi0:', GENERIC_READ or GENERIC_WRITE,\n        FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );\n      if hDevice=INVALID_HANDLE_VALUE then Exit;\n      try\n        srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);\n        System.Move('SCSIDISK',srbControl.Signature,8);\n        srbControl.Timeout := 2;\n        srbControl.Length := DataSize;\n        srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;\n        pInData := PSendCmdInParams(PChar(@Buffer)+SizeOf(SRB_IO_CONTROL));\n        pOutData := pInData;\n        with pInData^ do\n        begin\n          cBufferSize := IDENTIFY_BUFFER_SIZE;\n          bDriveNumber := tomnum;\n          with irDriveRegs do\n          begin\n            bFeaturesReg := 0;\n            bSectorCountReg := 1;\n            bSectorNumberReg := 1;\n            bCylLowReg := 0;\n            bCylHighReg := 0;\n            bDriveHeadReg := $A0;\n            bCommandReg := IDE_ID_FUNCTION;\n          end;\n        end;\n        if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT, @Buffer,\n          BufferSize, @Buffer, BufferSize, cbBytesReturned, nil ) then Exit;\n      finally\n        CloseHandle(hDevice);\n      end;\n    end\n  else\n    begin \/\/ Windows 95 OSR2, Windows 98\n      hDevice := CreateFile( '\\\\.\\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 );\n      if hDevice=INVALID_HANDLE_VALUE then Exit;\n      try\n        pInData := PSendCmdInParams(@Buffer);\n        pOutData := PChar(@pInData^.bBuffer);\n        with pInData^ do\n        begin\n          cBufferSize := IDENTIFY_BUFFER_SIZE;\n          bDriveNumber := tomnum;\n          with irDriveRegs do\n          begin\n            bFeaturesReg := 0;\n            bSectorCountReg := 1;\n            bSectorNumberReg := 1;\n            bCylLowReg := 0;\n            bCylHighReg := 0;\n            bDriveHeadReg := $A0;\n            bCommandReg := IDE_ID_FUNCTION;\n          end;\n        end;\n        if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, pInData,\n           SizeOf(TSendCmdInParams)-1, pOutData, W9xBufferSize,\n           cbBytesReturned, nil ) then Exit;\n      finally\n        CloseHandle(hDevice);\n      end;\n    end;\n    with PIdSector(PChar(pOutData)+16)^ do\n    begin\n      ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));\n      SetString(Result,sSerialNumber,SizeOf(sSerialNumber));\n    end;\nend;\n\nprocedure TForm1.Button1Click(Sender: TObject);\nvar s : String;\n    rc : DWORD;\n    i: integer;\nbegin\nMemo2.Clear;\nfor i:=0 to 3 do\nbegin\n  s := GetIdeDiskSerialNumber(i);\n  if s='' then\n    begin\n      rc := GetLastError;\n      if rc=0 then Memo2.Lines.Add('Disk '+IntToStr(i)+' IDE drive is not support SMART feature')\n      else Memo2.Lines.Add('Disk '+IntToStr(i)+': '+SysErrorMessage(rc));\n    end\n  else Memo2.Lines.Add('Disk '+IntToStr(i)+' serial number: '+Trim(s));\nend;\nMemo2.SetFocus;\nend;\n<\/div><\/pre>\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0421\u0435\u0440\u0438\u0439\u043d\u044b\u0435 \u043d\u043e\u043c\u0435\u0440\u0430 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0436\u0435\u0441\u0442\u043a\u0438\u0445 \u0434\u0438\u0441\u043a\u043e\u0432<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[433,438],"tags":[1298,1321,1487,1712,1824],"_links":{"self":[{"href":"http:\/\/pblog.ru\/lab\/index.php?rest_route=\/wp\/v2\/posts\/745"}],"collection":[{"href":"http:\/\/pblog.ru\/lab\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/pblog.ru\/lab\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/pblog.ru\/lab\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/pblog.ru\/lab\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=745"}],"version-history":[{"count":0,"href":"http:\/\/pblog.ru\/lab\/index.php?rest_route=\/wp\/v2\/posts\/745\/revisions"}],"wp:attachment":[{"href":"http:\/\/pblog.ru\/lab\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=745"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/pblog.ru\/lab\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=745"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/pblog.ru\/lab\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=745"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}