-- Отправил 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 Согласен:) Уже засыпал, когда писал
|