SlavSSoftPHP · JavaScript · Windows

Программы и технологии

на скрипте Ikonboard

Версия для печати

-Территория SlavSSoft (http://www.slavssoft.ru/cgi-bin/ikonboard/ikonboard.cgi)
--Delphi (http://www.slavssoft.ru/cgi-bin/ikonboard/forums.cgi?forum=11)
---Функции и процедуры (http://www.slavssoft.ru/cgi-bin/ikonboard/forums.cgi?forum=11&topic=2)


-- Отправил Predator 17 марта 2005 7:57

Здравствуйте, люди добрые, :val:

Может кто знает как узнать серийник именно физического диска? Куда не посмотришь, везде советуют GetVolumeInformation, но это поможет узнать только лишь номер тома!  :pain25:
Например так:

procedure  TForm1.Button1Click(Sender: TObject);
var

SerialNum : dword;
a, b : dword;
Buffer  : array [0..255] of char;
begin
if  GetVolumeInformation('c:\', Buffer, SizeOf(Buffer), @SerialNum, a, b, nil, 0) then
Label1.Caption := IntToStr(SerialNum);
end;  
Или так (хотя  у меня компилятор ругается):gulp:

procedure  TForm1.Button1Click(Sender: TObject);
var
VolumeName,
FileSystemName : array [0..MAX_PATH-1] of Char;
VolumeSerialNo : DWord;
MaxComponentLength,
FileSystemFlags : Integer;
begin
GetVolumeInformation('C:\',VolumeName, MAX_PATH, @VolumeSerialNo,
MaxComponentLength, FileSystemFlags,
FileSystemName, MAX_PATH);
Memo1.Lines.Add('VName = '+VolumeName);
Memo1.Lines.Add('SerialNo = $'+IntToHex(VolumeSerialNo,8));
Memo1.Lines.Add('CompLen = '+IntToStr(MaxComponentLength));
Memo1.Lines.Add('Flags = $'+IntToHex(FileSystemFlags,4));
Memo1.Lines.Add('FSName = '+FileSystemName);
end;  

Но это все номер тома,  :upset:



-- Отправил silver 17 марта 2005 17:06

Вот пример. Должен работать под всеми версиями windows.

{$IFDEF VER150}
{$DEFINE VER140}
{$ENDIF}

{$IFNDEF VER140}
procedure RaiseLastOSError;
begin
 RaiseLastWin32Error;
end;
{$ENDIF}


function GetIdeDiskSerialNumber( ControllerNumber, DriveNumber : Integer ) : 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 for future use.  Must be zero.
 end;
 IDEREGS   = TIDERegs;
 PIDERegs  = ^TIDERegs;

 TSendCmdInParams = packed record
   cBufferSize  : DWORD;                // Buffer size in bytes
   irDriveRegs  : TIDERegs;             // Structure with drive register values.
   bDriveNumber : Byte;                 // Physical drive number to send command to (0,1,2,3).
   bReserved    : Array[0..2] of Byte;  // Reserved for future expansion.
   dwReserved   : Array[0..3] of DWORD; // For future use.
   bBuffer      : Array[0..0] of Byte;  // Input buffer.
  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;
 s : String;
 pInData : PSendCmdInParams;
 pOutData : Pointer; // PSendCmdInParams;
 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
     Str(ControllerNumber,s);
     // Get SCSI port handle
     hDevice := CreateFile(
       PChar('\\.\Scsi'+s+':'),
       GENERIC_READ or GENERIC_WRITE,
       FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );
      if  hDevice=INVALID_HANDLE_VALUE  then  RaiseLastOSError;
      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 := DriveNumber;
         with irDriveRegs do
         begin
           bFeaturesReg     := 0;
           bSectorCountReg  := 1;
           bSectorNumberReg := 1;
           bCylLowReg       := 0;
           bCylHighReg      := 0;
           bDriveHeadReg    := $A0 or ((DriveNumber and 1) shl 4);
           bCommandReg      := IDE_ID_FUNCTION;
          end;
        end;
        if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil ) then RaiseLastOSError;
      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_HANDLE_VALUE then RaiseLastOSError;
      try
       pInData := PSendCmdInParams(@Buffer);
       pOutData := PChar(@pInData^.bBuffer);
       with pInData^ do
        begin
         cBufferSize  := IDENTIFY_BUFFER_SIZE;
         bDriveNumber := DriveNumber;
         with irDriveRegs do
          begin
           bFeaturesReg     := 0;
           bSectorCountReg  := 1;
           bSectorNumberReg := 1;
           bCylLowReg       := 0;
           bCylHighReg      := 0;
           bDriveHeadReg    := $A0 or ((DriveNumber and 1) shl 4);
           bCommandReg      := IDE_ID_FUNCTION;
          end;
        end;
        if not  DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, pInData, SizeOf(TSendCmdInParams)-1, pOutData, W9xBufferSize, cbBytesReturned, nil )  then  RaiseLastOSError;
      finally
       CloseHandle(hDevice);
      end;
    end;

  with PIdSector(PChar(pOutData)+16)^ do
  begin
   ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));
   SetString(Result,sSerialNumber,SizeOf(sSerialNumber));
  end;

 Result := Trim(Result);

end;

//-------------------------------------------------------------
function GetIdeSN : String;
var
 iController, iDrive, maxController : Integer;
begin
 Result := '';
 maxController := 15;
  if  Win32Platform<>VER_PLATFORM_WIN32_NT then maxController := 0;
  for iController := 0 to maxController do
  begin
    for iDrive := 0 to 4 do
    begin
      try
       Result := GetIdeDiskSerialNumber(iController,iDrive);
        if  Result<>''  then Exit;
      except
       // ignore exceptions
      end;
    end;
  end;
end;


-- Отправил OpMas 24 авг. 2005 16:33

Над проэктом работаю, совершенствуя, уже больше года и что заметил только что.
Добавляю к проэкту компонент(стандартный), к нему процедуру(стандартную) в ней использую раннее используемые компоненты. Нажимаю точку после имени и ... не появляется список возможных методов, свойств и т.д.
Выдается вместо онного ошибка:
Unable to invoke Code Completion due to errors in source code.
то бишь:
Неспособный вызывать Завершение Кода из-за ошибок в исходном тексте.(Gooddy).
Если не смотря на эту беду, набрать код ручками, все компилится и работает.
Какие ошибки, кто знает?


-- Отправил OpMas 27 авг. 2005 3:10

Почему спите? Хоть как-нибудь прокоментируйте.


-- Отправил slavs 27 авг. 2005 7:57

OpMas
Да просто сказать нечего :(
Интересное положение, не сталкивался никогда :)


-- Отправил OpMas 6 сен. 2005 18:10

Что здесь не так, только после этой процедуры косяки, пока поставил ее в конец кода.
procedure TForm1.OpenTab(Sender: TObject);
begin
//открываю таблицы
try
 {Защищенный код}
table1.Open;
table2.Open;table3.Open;table4.Open;table5.Open;
table6.Open;table7.Open;table8.Open;table9.Open;
query1.Open;query2.Open;
query4.Open;query5.Open;
query6.Open;query7.Open;
query8.Open;
form4.Table1.Open;form4.Query2.Open;
opntbl:=true;progressbar1.Visible:=false;
DataSource1.Enabled:=true;
except
 on EDatabaseError do
  if Application.MessageBox(
  'Будет выполнена попыека переиндексации',
  'Ошибка открытия таблиц',
   MB_OKCANCEL + MB_DEFBUTTON1) <> IDOK
   then begin
        showMessage(Возникло исключение :'+#13+Exception(ExceptObject).message);
        exit;end
        else n68.Click;
 end;
end;

(Сообщение отредактировал OpMas 6 сен. 2005 18:14)


-- Отправил slavs 7 сен. 2005 22:52

OpMas
Гляну завтра на работе, на досуге :)


-- Отправил slavs 7 сен. 2005 22:53

Народ, кто знает, как записывать и считывать в файлиз файла данные по строчно?


-- Отправил DimON 8 сен. 2005 12:05


Народ, кто знает, как записывать и считывать в файлиз файла данные по строчно?


Уточните мысль?

-- Отправил slavs 8 сен. 2005 21:24

OpMas
Вроде все правильно писано :(

DimON
ну, типа ini файла. Чтобы считывать данные не из базы данных, а из текстового файла, и записывать туда же, естественно, обращаясь к нужной строчке. :)


-- Отправил SHS 10 сен. 2005 11:17

assignfile(f:textfile, path: string)
rewrite(f) - если чтение/запись.

далее проседурами writeln(f, переменная с данными);
readln(f,переменная с данными).
Поработал - закрой! closefile(f);
чтобы обращаться к нужной строке, продумай идентификацию строк, как это в том же ini сделано.
Это способ простой и надежный, но потребует загрузки всего файла в память и уже работы с ним там. Можно использовать функции перемещения по набору данных. Но там без определенных навыков можно запутаться. Если файл не мегаразмеров, то используй первый способ.


-- Отправил slavs 11 сен. 2005 7:57

SHS
Я так и делаю, а как правильно обращаться к нужной строке, а то получается обращаюсь ко всему файлу, а надо к конкретной строке :(


-- Отправил SHS 14 сен. 2005 1:20

ну вообще говоря при работе с любым файлом система обязана просмотреть файл полностью, дабы определить что он из себя представляет. Tinifile содержит процедуры уже описывающие поиск раздела и чтение/запись. Если у тебя файл не в структуре Ini тогда тебе нужно все делать самому. В принципе такое же дело происходит в БД, только на ином уровне. только листинг файла идет не целиком а порциально. Хотя я может и заблуждаюсь. Тем не мение при работе с текстовиком можно идентифицироваться по номеру строки и использовать пустые readln. Но это редьки не слаще. Можно обратиться за помощью к старине паскалю и попробовать функции определяющие/ставящие позицию ввода в файле. Но я давно этим не пользовался и конкретный пример привести не могу. помните Eof, endof и т.д.? Вот ищите в этой серии.


-- Отправил silver 13 окт. 2005 0:00


Что здесь не так, только после этой процедуры косяки, пока поставил ее в конец кода.


Что бросилось в глаза

table1.Open;


query2.Open;

...
//table1 и query2 уже открыта, след строка приведёт к исключению

form4.Table1.Open;form4.Query2.Open;



ну, типа ini файла

Есть класс TIniFile
В общем случае для работы с файлами лучше использовать TFileStream

ну вообще говоря при работе с любым файлом система обязана просмотреть файл полностью

Неправда ваша

-- Отправил slavs 13 окт. 2005 7:48

silver


//table1 и query2 уже открыта, след строка приведёт к исключению

Не правда ваша :)

-- Отправил silver 13 окт. 2005 11:52

slavs
Согласен:)
Уже засыпал, когда писал


Территория SlavSSoft на скрипте Ikonboard
http://www.ikonboard.com
© 2000 Ikonboard.com

Новые сообщения временно недоступны.