본문 바로가기

카테고리 없음

[시스템] drive의 일련번호 바꾸기

반응형
>How can I change floppy serial number (e.g. 1111-2222) in Delphi 4?

[1] Borland TI 475D, Getting and setting a disks serial number
    http://www.borland.com/devsupport/delphi/ti_list/TI475D.html


[2] The volume serial number is stored in bytes 39-42 of the boot sector
    on the disk. So, the basic approach looks like this:

type
   TSector = array[0..511] of Byte;

procedure ChangeVolumeSerialNumber(Drive: Char;
   SerialNumber: LongWord);
   var
     Boot: TSector;
   begin
   ReadBoot(Drive, Boot);
   Move(SerialNumber, Boot[39], SizeOf(SerialNumber));
   WriteBoot(Drive, Boot) end;

A complication occurs, however, because reading and writing the boot
sector in NT requires completely different code from that used in
reading and writing the boot sector in Win95/98.

So here's the complete code, taking into account the differences
between NT and Win95/98:

type
   TSector = array[0..511] of Byte;

procedure ReadBootNT(Drive: Char; var Boot: TSector);
   var
     BytesRead: Cardinal;
     H: THandle;
   begin
   H := CreateFile(PChar(Format('\.%s:', [UpCase(Drive)])),
     GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
   if H = INVALID_HANDLE_VALUE then
     raise Exception.Create(SysErrorMessage(GetLastError));
   try
     if not ReadFile(H, Boot, SizeOf(Boot), BytesRead, nil)then
       raise Exception.Create(SysErrorMessage(GetLastError));
   finally
     CloseHandle(H) end end;

procedure WriteBootNT(Drive: Char; var Boot: TSector);
   var
     BytesWritten: Cardinal;
     H: THandle;
   begin
   H := CreateFile(PChar(Format('\.%s:', [UpCase(Drive)])),
     GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
   if H = INVALID_HANDLE_VALUE then
     raise Exception.Create(SysErrorMessage(GetLastError));
   try
     if not WriteFile(H, Boot, SizeOf(Boot), BytesWritten, nil)then
       raise Exception.Create(SysErrorMessage(GetLastError));
   finally
     CloseHandle(H) end end;

type
   TDiocRegisters = record
     EBX, EDX, ECX, EAX, EDI, ESI, Flags: LongWord end;

   TVWin32CtlCode = (ccNone, ccVWin32IntIoctl, ccVWin32Int25,
     ccVWin32Int26, ccVWin32Int13);

function VWin32(CtlCode: TVWin32CtlCode;
   var Regs: TDiocRegisters): Boolean;
   var
     Device: THandle;
     Count: LongWord;
   begin
   Device := CreateFile('\.VWIN32', 0, 0, nil, 0,
     FILE_FLAG_DELETE_ON_CLOSE, 0);
   if Device = INVALID_HANDLE_VALUE then
     raise Exception.Create(SysErrorMessage(GetLastError));
   try
     Result := DeviceIoControl(Device, Ord(CtlCode), @Regs,
       SizeOf(Regs), @Regs, SizeOf(Regs), Count, nil);
   finally
     CloseHandle(Device) end end;

procedure ReadBoot95(Drive: Char; var Boot: TSector);
   var
     Regs: TDiocRegisters;
   begin
   with Regs do begin
     EAX := Ord(UpCase(Drive)) - Ord('A');
     EBX := LongWord(@Boot);
     ECX := 1;
     EDX := 0 end;
   if not VWin32(ccVWin32Int25, Regs) then
     raise Exception.Create(SysErrorMessage(GetLastError)) end;

procedure WriteBoot95(Drive: Char; var Boot: TSector);
   var
     Regs: TDiocRegisters;
   begin
   with Regs do begin
     EAX := Ord(UpCase(Drive)) - Ord('A');
     EBX := LongWord(@Boot);
     ECX := 1;
     EDX := 0 end;
   if not VWin32(ccVWin32Int26, Regs) then
     raise Exception.Create(SysErrorMessage(GetLastError)) end;

procedure ChangeVolumeSerialNumber(Drive: Char;
   SerialNumber: LongWord);
   var
     Boot: TSector;
   begin
   case Win32Platform of
     VER_PLATFORM_WIN32_WINDOWS:
       ReadBoot95(Drive, Boot);
     VER_PLATFORM_WIN32_NT:
       ReadBootNT(Drive, Boot) end;
   Move(SerialNumber, Boot[39], SizeOf(SerialNumber));
   case Win32Platform of
     VER_PLATFORM_WIN32_WINDOWS:
       WriteBoot95(Drive, Boot);
     VER_PLATFORM_WIN32_NT:
       WriteBootNT(Drive, Boot) end end;
반응형