Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.06.17;
Скачать: CL | DM;

Вниз

Поучение геометрии флоппи диска.   Найти похожие ветки 

 
Riply ©   (2007-05-28 08:31) [0]

Здравствуйте !
Пытаюсь использовать DeviceIoControl(..., IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,...
для поучение геометрии флоппика. Но DeviceIoControl возвращает ошибку: ERROR_INVALID_FUNCTION.
В чем может быть причина ?
P.S.
Ошибка с GEOMETRY_EX возникает только для флоппи.
Если использовать IOCTL_DISK_GET_DRIVE_GEOMETRY, то все работает,
но очень не хотелось бы так поступать, т.к. в Help-е сказано,
что IOCTL_DISK_GET_DRIVE_GEOMETRY - устарела.
(Только не говорите, что сам флоппик устарел. Он еще долго будет с нами :)


 
DrPass ©   (2007-05-28 10:46) [1]

А операционка какая? Этот код AFAIK только на ХР и старше работает (кстати, а стоит ли сейчас писать программу, уже на работающую на Вынь2000?)


 
Riply ©   (2007-05-28 11:09) [2]

> [1] DrPass ©   (28.05.07 10:46)
>А операционка какая?
XP SP2
>кстати, а стоит ли сейчас писать программу, уже на работающую на Вынь2000?
А эту фразу не поняла. Поясни, пожалуйста.


 
Игорь Шевченко ©   (2007-05-28 11:13) [3]


> Если использовать IOCTL_DISK_GET_DRIVE_GEOMETRY, то все
> работает,
> но очень не хотелось бы так поступать, т.к. в Help-е сказано,
>  
> что IOCTL_DISK_GET_DRIVE_GEOMETRY - устарела.


Забудь про HELP


 
Riply ©   (2007-05-28 11:16) [4]

> [3] Игорь Шевченко ©   (28.05.07 11:13)
> Забудь про HELP
"Это как-это, это как-это ?" (с) Чья - не помню :)
Кому же, тогда, верить ?


 
Сергей М. ©   (2007-05-28 12:36) [5]


> в Help-е сказано,
> что IOCTL_DISK_GET_DRIVE_GEOMETRY - устарела


Где такой help живет ?
В D7 никакая "устарелость" по этому поводу не фигурирует ..


 
Riply ©   (2007-05-28 12:50) [6]

> [5] Сергей М. ©   (28.05.07 12:36)
>Где такой help живет ?
:)
Такой неправильный Help живет в BDS 2006 :)

The IOCTL_DISK_GET_DRIVE_GEOMETRY control code retrieves information about the physical disk"s geometry:
type, number of cylinders, tracks per cylinder, sectors per track, and bytes per sector.
 Note IOCTL_DISK_GET_DRIVE_GEOMETRY has been superseded by IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
 which retrieves additional information.
..........
..........
The following are obsolete control codes.
IOCTL_DISK_GET_DRIVE_GEOMETRY
IOCTL_DISK_GET_DRIVE_LAYOUT
IOCTL_DISK_GET_PARTITION_INFO
IOCTL_DISK_SET_DRIVE_LAYOUT
IOCTL_DISK_SET_PARTITION_INFO

Platform SDK Release: February 2003


 
Сергей М. ©   (2007-05-28 12:59) [7]


> Riply ©   (28.05.07 12:50) [6]


Ну и где тут про "устарела" ?

IOCTL_DISK_GET_DRIVE_GEOMETRY, согласно msdn, "живет" на всех системах, кроме маздая, в то время как заменяющая (но не отменяющая !!) ее EX-версия "живет" только на ХР/Vista/Longhorn/2003.


 
Riply ©   (2007-05-28 13:14) [8]

> [7] Сергей М. ©   (28.05.07 12:59)
>Ну и где тут про "устарела" ?
The following are obsolete control codes.
IOCTL_DISK_GET_DRIVE_GEOMETRY

obsolete [ ] 1) устарелый; вышедший из употребления; старомодный
Т.е. Не в моде :) Реальные пацаны ее уже не используют :)


 
clickmaker ©   (2007-05-28 13:16) [9]


> Реальные пацаны ее уже не используют :)

судя по анкете, ты вовсе не пацан. Так что можно )


 
Сергей М. ©   (2007-05-28 13:22) [10]


> Riply ©   (28.05.07 13:14) [8]


Вот оригинал:

http://msdn2.microsoft.com/en-us/library/aa365169.aspx

Где там слово "obsolete" ? Ткни меня носом ...

Может поэтому ИШ порекомендовал "забыть" такой help, который по сути дублируя оригинал существенно искажает его содержимое ?


 
Riply ©   (2007-05-28 13:23) [11]

>[9] clickmaker ©   (28.05.07 13:16)
>судя по анкете, ты вовсе не пацан. Так что можно )
Зато - модница ! Разве я могу одеть(исползовать) то, что уже вышло из моды ? :)


 
Сергей М. ©   (2007-05-28 13:25) [12]


> Riply ©   (28.05.07 13:23) [11]


> Зато - модница !


А не ты ли, барышня, не так давно жаловалась, что до Висты и ДлинногоРога пока не доросла ?)


 
Riply ©   (2007-05-28 13:32) [13]

>[10] Сергей М. ©   (28.05.07 13:22)
>Вот оригинал:
>http://msdn2.microsoft.com/en-us/library/aa365169.aspx
>Где там слово "obsolete" ? Ткни меня носом ...
Как просил, тыкаю :) http://msdn2.microsoft.com/en-us/library/aa363979.aspx

>[12] Сергей М. ©   (28.05.07 13:25)
>А не ты ли, барышня, не так давно жаловалась, что до Висты и ДлинногоРога пока не доросла ?)
Во-первых: не все сразу. Стараюсь расти :)
Во-вторых, я не считаю, что Vista - это модно :)


 
Сергей М. ©   (2007-05-28 13:37) [14]


> Riply ©   (28.05.07 13:32) [13]


> Как просил, тыкаю


Уткнулся, вижу)

Но с учетом "не считаю, что Vista - это модно" волноваться за "устарелость" пока нет повода)


 
Riply ©   (2007-05-28 13:47) [15]

> [14] Сергей М. ©   (28.05.07 13:37)
>Но с учетом "не считаю, что Vista - это модно" волноваться за "устарелость" пока нет повода)
Есть еще один момент:
Со всеми (кроме флоппика) я работаю с "EX - кодами".
Написала несколько "универсальных" процедур для работы.
А DRIVE_GEOMETRY в эту стройную картинку никак не вписывается. Не очень хочется делать так:
Если флоопик, то это, иначе то :)
И еще: случай с ним означает, что не исключены варианты подобных ошибок и с другими Device-ми


 
Сергей М. ©   (2007-05-28 13:51) [16]


> Riply ©   (28.05.07 13:47) [15]


Ты бы хоть ОС свою обозначила  ..


 
Riply ©   (2007-05-28 13:58) [17]

> [16] Сергей М. ©   (28.05.07 13:51)
>Ты бы хоть ОС свою обозначила  ..
WinXP SP2

>[15] Riply ©   (28.05.07 13:47)
Забыла главное написать:
Очень хочется понять причину этого, чтобы не напороться в другом месте.
Может я его неправильно открываю ?
CreateFileA("\\.\A:",....


 
Сергей М. ©   (2007-05-28 14:08) [18]


> Riply ©   (28.05.07 13:58) [17]


Приведи код в максимально упрощенном функциональном фарианте - я попробую у себя его протестировать ..


 
Riply ©   (2007-05-28 14:10) [19]

> [18] Сергей М. ©   (28.05.07 14:08)
>Приведи код в максимально упрощенном функциональном фарианте - я попробую у себя его протестировать ..
Хорошо, но потребуется время :(


 
Riply ©   (2007-05-28 15:24) [20]

>[18] Сергей М. ©   (28.05.07 14:08)
Код, конечно, я подготовила...
Но, учитывая, что все в стадии разработки - он страшен :)
У тебя в роду сердечными болезнями никто не страдал ?
Тогда прибавь еще к этому и то, что его функции выдергивались из разных
модулей, а то, что было "невыдернуть" подгонялось "на лету" - абы компилятор пропустил.
Ты еще готов ?
P.S.
Да и на форуме много "еще духом неокрепших" :)


 
Сергей М. ©   (2007-05-28 15:33) [21]


> Riply ©   (28.05.07 15:24) [20]


Снабди код минимально необходимыми комментариями - остальное как-нить переживу)


 
Игорь Шевченко ©   (2007-05-28 15:35) [22]

Riply ©   (28.05.07 15:24) [20]

А какие, собственно, проблемы ?
Выдаешь запрос с _EX-функцией, если возвращает Invalid function, выдаешь запрос функции без _EX. Глядишь, когда драйвер флопа научится EX-вариант понимать, тебе и переделывать ничего не придется.


 
Riply ©   (2007-05-28 15:36) [23]

> [21] Сергей М. ©   (28.05.07 15:33)
>Снабди код минимально необходимыми комментариями - остальное как-нить переживу)
Я сделала проще: вывела только одну функцию с единственным парамертом TStrings.
Ее и надо "запустить"


 
Riply ©   (2007-05-28 15:39) [24]

unit TempUnit;

interface
uses
Windows,
SysUtils,
Classes;

function RefreshPhysicalDevice(List: TStrings): integer;

implementation
uses
Dialogs;

const                                                               // 162
 FILE_DEVICE_CD_ROM              = $00000002;
 {$EXTERNALSYM FILE_DEVICE_CD_ROM}
 FILE_DEVICE_DISK                = $00000007;
 {$EXTERNALSYM FILE_DEVICE_DISK}

const                                                              // 337
 FILE_ANY_ACCESS     = 0;
 {$EXTERNALSYM FILE_ANY_ACCESS}

const                                                            // 302
 METHOD_BUFFERED   = 0;
 {$EXTERNALSYM METHOD_BUFFERED}
 METHOD_IN_DIRECT  = 1;
 {$EXTERNALSYM METHOD_IN_DIRECT}
 METHOD_OUT_DIRECT = 2;
 {$EXTERNALSYM METHOD_OUT_DIRECT}
 METHOD_NEITHER    = 3;
 {$EXTERNALSYM METHOD_NEITHER}

const                                                             // 862
 IOCTL_DISK_BASE = FILE_DEVICE_DISK;
 {$EXTERNALSYM IOCTL_DISK_BASE}

 IOCTL_DISK_GET_DRIVE_GEOMETRY = (
   (IOCTL_DISK_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or
   ($0000 shl 2) or METHOD_BUFFERED);
 {$EXTERNALSYM IOCTL_DISK_GET_DRIVE_GEOMETRY}

 IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = (
   (IOCTL_DISK_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or
   ($0028 shl 2) or METHOD_BUFFERED);
 {$EXTERNALSYM IOCTL_DISK_GET_DRIVE_GEOMETRY_EX}

type                                                            // 1262
 _MEDIA_TYPE = (
   Unknown,                // Format is unknown
   F5_1Pt2_512,            // 5.25", 1.2MB,  512 bytes/sector
   F3_1Pt44_512,           // 3.5",  1.44MB, 512 bytes/sector
   F3_2Pt88_512,           // 3.5",  2.88MB, 512 bytes/sector
   F3_20Pt8_512,           // 3.5",  20.8MB, 512 bytes/sector
   F3_720_512,             // 3.5",  720KB,  512 bytes/sector
   F5_360_512,             // 5.25", 360KB,  512 bytes/sector
   F5_320_512,             // 5.25", 320KB,  512 bytes/sector
   F5_320_1024,            // 5.25", 320KB,  1024 bytes/sector
   F5_180_512,             // 5.25", 180KB,  512 bytes/sector
   F5_160_512,             // 5.25", 160KB,  512 bytes/sector
   RemovableMedia,         // Removable media other than floppy
   FixedMedia,             // Fixed hard disk media
   F3_120M_512,            // 3.5", 120M Floppy
   F3_640_512,             // 3.5" ,  640KB,  512 bytes/sector
   F5_640_512,             // 5.25",  640KB,  512 bytes/sector
   F5_720_512,             // 5.25",  720KB,  512 bytes/sector
   F3_1Pt2_512,            // 3.5" ,  1.2Mb,  512 bytes/sector
   F3_1Pt23_1024,          // 3.5" ,  1.23Mb, 1024 bytes/sector
   F5_1Pt23_1024,          // 5.25",  1.23MB, 1024 bytes/sector
   F3_128Mb_512,           // 3.5" MO 128Mb   512 bytes/sector
   F3_230Mb_512,           // 3.5" MO 230Mb   512 bytes/sector
   F8_256_128,             // 8",     256KB,  128 bytes/sector
   F3_200Mb_512,           // 3.5",   200M Floppy (HiFD)
   F3_240M_512,            // 3.5",   240Mb Floppy (HiFD)
   F3_32M_512);            // 3.5",   32Mb Floppy
 {$EXTERNALSYM _MEDIA_TYPE}
 MEDIA_TYPE = _MEDIA_TYPE;
 {$EXTERNALSYM MEDIA_TYPE}
 PMEDIA_TYPE = ^MEDIA_TYPE;
 {$EXTERNALSYM PMEDIA_TYPE}
 TMediaType = MEDIA_TYPE;
 PMediaType = PMEDIA_TYPE;

type                                                            // 1359
 PDISK_GEOMETRY = ^DISK_GEOMETRY;
 {$EXTERNALSYM PDISK_GEOMETRY}
 _DISK_GEOMETRY = record
   Cylinders: LARGE_INTEGER;
   MediaType: MEDIA_TYPE;
   TracksPerCylinder: DWORD;
   SectorsPerTrack: DWORD;
   BytesPerSector: DWORD;
 end;
 {$EXTERNALSYM _DISK_GEOMETRY}
 DISK_GEOMETRY = _DISK_GEOMETRY;
 {$EXTERNALSYM DISK_GEOMETRY}
 TDiskGeometry = DISK_GEOMETRY;
 PDiskGeometry = PDISK_GEOMETRY;

type                                                              // 1490
 _PARTITION_STYLE = (
   PARTITION_STYLE_MBR,
   PARTITION_STYLE_GPT,
   PARTITION_STYLE_RAW);
 {$EXTERNALSYM _PARTITION_STYLE}
 PARTITION_STYLE = _PARTITION_STYLE;
 {$EXTERNALSYM PARTITION_STYLE}
 TPartitionStyle = PARTITION_STYLE;

type                                                              // 1738
 _DETECTION_TYPE = (
   DetectNone,
   DetectInt13,
   DetectExInt13);
 {$EXTERNALSYM _DETECTION_TYPE}
 DETECTION_TYPE = _DETECTION_TYPE;
 {$EXTERNALSYM DETECTION_TYPE}
 TDetectionType = DETECTION_TYPE;

 PDISK_INT13_INFO = ^DISK_INT13_INFO;
 {$EXTERNALSYM PDISK_INT13_INFO}
 _DISK_INT13_INFO = record
   DriveSelect: WORD;
   MaxCylinders: DWORD;
   SectorsPerTrack: WORD;
   MaxHeads: WORD;
   NumberDrives: WORD;
 end;
 {$EXTERNALSYM _DISK_INT13_INFO}
 DISK_INT13_INFO = _DISK_INT13_INFO;
 {$EXTERNALSYM DISK_INT13_INFO}
 TDiskInt13Info = DISK_INT13_INFO;
 PDiskInt13Info = PDISK_INT13_INFO;

 PDISK_EX_INT13_INFO = ^DISK_EX_INT13_INFO;
 {$EXTERNALSYM PDISK_EX_INT13_INFO}
 _DISK_EX_INT13_INFO = record
   ExBufferSize: WORD;
   ExFlags: WORD;
   ExCylinders: DWORD;
   ExHeads: DWORD;
   ExSectorsPerTrack: DWORD;
   ExSectorsPerDrive: Int64;// DWORD64;  // Riply changed !!!
   ExSectorSize: WORD;
   ExReserved: WORD;
 end;
 {$EXTERNALSYM _DISK_EX_INT13_INFO}
 DISK_EX_INT13_INFO = _DISK_EX_INT13_INFO;
 {$EXTERNALSYM DISK_EX_INT13_INFO}
 TDiskExInt13Info = DISK_EX_INT13_INFO;
 PDiskExInt13Info = PDISK_EX_INT13_INFO;

 PDISK_DETECTION_INFO = ^DISK_DETECTION_INFO;
 {$EXTERNALSYM PDISK_DETECTION_INFO}
 _DISK_DETECTION_INFO = record
   SizeOfDetectInfo: DWORD;
   DetectionType: DETECTION_TYPE;
   case Integer of
     0: (
       //
       // If DetectionType == DETECTION_INT13 then we have just the Int13
       // information.
       //
       Int13: DISK_INT13_INFO;
       //
       // If DetectionType == DETECTION_EX_INT13, then we have the
       // extended int 13 information.
       //
       ExInt13: DISK_EX_INT13_INFO); // If DetectionType == DetectExInt13
 end;
 {$EXTERNALSYM _DISK_DETECTION_INFO}
 DISK_DETECTION_INFO = _DISK_DETECTION_INFO;
 {$EXTERNALSYM DISK_DETECTION_INFO}
 TDiskDetectionInfo = DISK_DETECTION_INFO;
 PDiskDetectionInfo = PDISK_DETECTION_INFO;

 PDISK_PARTITION_INFO = ^DISK_PARTITION_INFO;
 {$EXTERNALSYM PDISK_PARTITION_INFO}
 _DISK_PARTITION_INFO = record
   SizeOfPartitionInfo: DWORD;
   PartitionStyle: PARTITION_STYLE; // PartitionStyle = RAW, GPT or MBR
   case Integer of
     0: (                           // If PartitionStyle == MBR
       Signature: DWORD; // MBR Signature
       CheckSum: DWORD); // MBR CheckSum
     1: (                           // If PartitionStyle == GPT
       DiskId: TGUID);//GUID);                                       // Riply changed !!!
 end;
 {$EXTERNALSYM _DISK_PARTITION_INFO}
 DISK_PARTITION_INFO = _DISK_PARTITION_INFO;
 {$EXTERNALSYM DISK_PARTITION_INFO}
 TDiskPartitionInfo = DISK_PARTITION_INFO;
 PDiskPartitionInfo = PDISK_PARTITION_INFO;



 
Riply ©   (2007-05-28 15:40) [25]

type
 PDISK_GEOMETRY_EX = ^DISK_GEOMETRY_EX;
 {$EXTERNALSYM PDISK_GEOMETRY_EX}
 _DISK_GEOMETRY_EX = record
   Geometry: DISK_GEOMETRY;    // Standard disk geometry: may be faked by driver.
   DiskSize: LARGE_INTEGER;    // Must always be correct
   Data: array [0..0] of BYTE; // Partition, Detect info
 end;
 {$EXTERNALSYM _DISK_GEOMETRY_EX}
 DISK_GEOMETRY_EX = _DISK_GEOMETRY_EX;
 {$EXTERNALSYM DISK_GEOMETRY_EX}
 TDiskGeometryEx = DISK_GEOMETRY_EX;
 PDiskGeometryEx = PDISK_GEOMETRY_EX;

type
PSizedData = ^TSizedData;
TSizedData = packed record
 cbSize:   DWord;
 pData: Pointer;
 procedure Init;
 procedure _ReallocMem(const aSize: DWord);
 procedure _WriteData(const aSize : DWord; const Buffer);
 procedure _HoldData(const aSize : DWord; const Buffer);
end;

type
TDeviceControl = class
 private
  FDiskGeometry:    DISK_GEOMETRY;
  FpIoData:         TSizedData;
  FGlobalSize:      Int64;

  FhDevice:         THandle;
  FLastErr:         DWord;

  FDeviceName:      string;

  function _InitializateVariables: Boolean; virtual;
  function _FinalizateVariables(const Mem_Clear: Boolean): Boolean; virtual;
  procedure _ClearVariables(const Mem_Clear: Boolean); virtual;

  function _DeviceOpen(const cbAccess, cbDeviceType: DWord): DWord;

  function _GetGeometry: DWord;
  function _GetGeometryEx: DWord;
 public
  constructor Create;
  destructor Destroy; override;
  procedure Device_Close;

  function SetDeviceName(const DeviceName: string; const cbAccess, cbDeviceType: DWord): DWord;
  function GetGeometry(var RetResult: DWord): PDISK_GEOMETRY;
  function GetGeometryEx(var RetResult: DWord): PDISK_GEOMETRY_EX;

  property DiskGlobalSize: int64 read FGlobalSize;
 end;

type
TDiskIoControl = class(TDeviceControl)
 private
  procedure _ClearVariables(const Mem_Clear: Boolean); override;
 public
  function SetDeviceNum(const DiskNum: Integer; const cbAccess, cbDeviceType: DWord): DWord;
 end;

const
IO_BUFFER_SIZE_INC  = 64;

function Close_Handle(var Handle: DWord): Boolean;
begin
case Handle of
 0: Result := True;
 INVALID_HANDLE_VALUE:
  begin
   Handle := 0;
   Result := True;
  end;
 else
  try
   Result := CloseHandle(Handle);
  finally
   Handle := 0;
  end;
 end;
end;

function Device_IoControlQueryMemory(const hDevice: THandle; const cbIoControlCode: DWord; var pBuffer: Pointer; var cbBuffer, cbReturned: DWord): DWord;
begin
cbReturned := 0;
if pBuffer = nil then
 begin
  cbBuffer := IO_BUFFER_SIZE_INC;
  ReallocMem(pBuffer, cbBuffer);
 end;
Result := ERROR_INVALID_FUNCTION;
try
 repeat
  FillChar(pBuffer^, cbBuffer, 0);
  if not DeviceIoControl(hDevice, cbIoControlCode, nil, 0, pBuffer, cbBuffer, cbReturned, nil)
   then Result := GetLastError
   else Result := ERROR_SUCCESS;
   case Result of
    ERROR_SUCCESS: Break;
    ERROR_MORE_DATA:
     begin
      cbBuffer := cbReturned;
      ReallocMem(pBuffer, cbBuffer);
     end;
    ERROR_INSUFFICIENT_BUFFER:
     begin
      cbBuffer := cbBuffer + IO_BUFFER_SIZE_INC;
      ReallocMem(pBuffer, cbBuffer);
     end;
    else Break
   end;
 until Result = ERROR_SUCCESS;
finally
 if Result <> ERROR_SUCCESS then
  begin
   cbBuffer := 0;
   ReallocMem(pBuffer, 0);
  end;
end;
end;

function Device_GetGeometry(const hDevice: THandle; const pGeometry: PDISK_GEOMETRY): Boolean;
var
Returned : DWord;
begin
Result := DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, nil, 0, pGeometry, SizeOf(DISK_GEOMETRY), Returned, nil);
end;

function Device_GetGeometryEx(const hDevice: THandle; var pGeometryEx: PDISK_GEOMETRY_EX; var cbSize: DWord): DWord;
var
Returned : DWord;
begin
Result := Device_IoControlQueryMemory(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, Pointer(pGeometryEx), cbSize, Returned);
end;

procedure TSizedData.Init;
begin
cbSize := 0;
pData := nil;
end;

procedure TSizedData._ReallocMem(const aSize: DWord);
begin
if cbSize <> aSize then
 begin
  cbSize := aSize;
  ReallocMem(pData, cbSize);
 end;
end;

procedure TSizedData._WriteData(const aSize: DWord; const Buffer);
begin
_ReallocMem(aSize);
Move(Buffer, pData^, cbSize);
end;

procedure TSizedData._HoldData(const aSize: DWord; const Buffer);
begin
if cbSize < aSize
 then _WriteData(aSize, Buffer)
 else Move(Buffer, pData^, aSize);
end;

constructor TDeviceControl.Create;
begin
inherited Create;
_ClearVariables(True);
_InitializateVariables;
end;

destructor TDeviceControl.Destroy;
begin
try
 _FinalizateVariables(True);
finally
 inherited Destroy;
end;
end;

procedure TDeviceControl._ClearVariables(const Mem_Clear: Boolean);
begin
FhDevice := 0;
FGlobalSize := -1;
FDeviceName := "";
FLastErr := ERROR_SUCCESS;
FillChar(FDiskGeometry, SizeOf(DISK_GEOMETRY), 0);
if Mem_Clear then FpIoData.Init;
end;

function TDeviceControl._InitializateVariables: Boolean;
begin
Result := True;
end;

function TDeviceControl._FinalizateVariables(const Mem_Clear: Boolean): Boolean;
begin
try
 Result := Close_Handle(FhDevice);
 if Mem_Clear then FpIoData._ReallocMem(0);
finally
 _ClearVariables(Mem_Clear);
end;
end;

function TDeviceControl._DeviceOpen(const cbAccess, cbDeviceType: DWord): DWord;
begin
FhDevice := CreateFileA(PChar(FDeviceName), cbAccess, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if FhDevice <> INVALID_HANDLE_VALUE then
 begin
  FLastErr := ERROR_SUCCESS;
 end
else FLastErr := GetLastError;
Result := FLastErr;
end;

procedure TDeviceControl.Device_Close;
begin
_FinalizateVariables(False);
end;

function TDeviceControl.SetDeviceName(const DeviceName: string; const cbAccess, cbDeviceType: DWord): DWord;
begin
if (FhDevice = 0) or (FDeviceName <> DeviceName)   then
 begin
  _FinalizateVariables(False);
  FDeviceName := DeviceName;
  Result:= _DeviceOpen(cbAccess, cbDeviceType);
 end
else Result := ERROR_SUCCESS;
end;

function TDeviceControl._GetGeometry: DWord;
begin
if not Device_GetGeometry(FhDevice, @FDiskGeometry) then
 begin
  FGlobalSize := -1;
  FLastErr := GetLastError;
  Result := FLastErr;
 end
else
 begin
  with FDiskGeometry do
   FGlobalSize := Cylinders.QuadPart * TracksPerCylinder * SectorsPerTrack * BytesPerSector;
  Result := ERROR_SUCCESS;
 end;
end;

function TDeviceControl._GetGeometryEx: DWord;
begin
Result := Device_GetGeometryEx(FhDevice, PDISK_GEOMETRY_EX(FpIoData.pData), FpIoData.cbSize);
if Result = ERROR_SUCCESS then
 begin
  with PDISK_GEOMETRY_EX(FpIoData.pData).Geometry do
   FGlobalSize := Cylinders.QuadPart * TracksPerCylinder * SectorsPerTrack * BytesPerSector;
 end
else
 begin
  FGlobalSize := -1;
  FLastErr := Result;
 end;
end;

function TDeviceControl.GetGeometry(var RetResult: DWord): PDISK_GEOMETRY;
begin
RetResult := _GetGeometry;
if RetResult = ERROR_SUCCESS then Result := @FDiskGeometry else Result := nil;
end;


 
Riply ©   (2007-05-28 15:42) [26]

function TDeviceControl.GetGeometryEx(var RetResult: DWord): PDISK_GEOMETRY_EX;
begin
RetResult := _GetGeometryEx;
if RetResult = ERROR_SUCCESS then Result := PDISK_GEOMETRY_EX(FpIoData.pData) else Result := nil;
end;

procedure TDiskIoControl._ClearVariables(const Mem_Clear: Boolean);
begin
inherited _ClearVariables(Mem_Clear);
end;

const
PREFIX_LOCAL        = "\\.";
PREFIX_LOCAL_EX     = "\\.\";
PREFIX_DEVICE       = "\Device\";
PREFIX_PIPE         = "\PIPE\";
PREFIX_SLOT         = "\MailSlot\";
PREFIX_PHDRIVE      = "PhysicalDrive";
PREFIX_CDROM        = "CdRom";
PREFIX_FLOPPY       = "Floppy";
BASE_NAME_PIPE      = "NamedPipe";
BASE_NAME_SLOT      = "MailSlot";
BASE_NAME_HDISK     = "Harddisk";
BASE_NAME_PART      = "Partition";
PR_DEVICE_PIPE      = PREFIX_DEVICE + BASE_NAME_PIPE + "\"; //???
PR_LOCAL_DEVICE     = PREFIX_LOCAL + PREFIX_DEVICE;
PR_LOCAL_PIPE       = PREFIX_LOCAL + PREFIX_PIPE;
PR_LOCAL_SLOT       = PREFIX_LOCAL + PREFIX_SLOT;
PR_LOCAL_PHDRIVE    = PREFIX_LOCAL_EX + PREFIX_PHDRIVE;
PR_LOCAL_CDROM      = PREFIX_LOCAL_EX + PREFIX_CDROM;
PR_LOCAL_FLOPPY     = PREFIX_LOCAL_EX + PREFIX_FLOPPY;
DV_HDISK            = PREFIX_DEVICE + BASE_NAME_HDISK;

const
FILE_DEVICE_FLOPPY_TEMP  = MAXDWORD - 3;

function DeiceTypeToPhysicalPrefix(const cbDeviceType, DeviceNum: DWord; var Prefix: string): Boolean;
begin
Result := True;
case cbDeviceType of
 FILE_DEVICE_DISK:        Prefix := PR_LOCAL_PHDRIVE + IntToStr(DeviceNum);
 FILE_DEVICE_CD_ROM:      Prefix := PR_LOCAL_CDROM + IntToStr(DeviceNum);
 FILE_DEVICE_FLOPPY_TEMP: Prefix := PREFIX_LOCAL_EX + Char(DeviceNum + Ord("A")) + ":";
 else Result := False;
end;
end;

function TDiskIoControl.SetDeviceNum(const DiskNum: Integer; const cbAccess, cbDeviceType: DWord): DWord;
var
Buf: string;
begin
if not DeiceTypeToPhysicalPrefix(cbDeviceType, DiskNum, Buf) then
 begin
  FLastErr := ERROR_DEV_NOT_EXIST;
  Result := FLastErr;
 end
else Result := SetDeviceName(Buf, cbAccess, cbDeviceType);
end;

type
NTSTATUS = Integer;

const
STATUS_SUCCESS                           = NTSTATUS($00000000);
SystemConfigurationInformation = 7;

type
 SYSTEM_CONFIGURATION_INFORMATION = packed record
   DiskCount : ULONG;
   FloppyCount : ULONG;
   CdRomCount : ULONG;
   TapeCount : ULONG;
   SerialCount : ULONG;
   ParallelCount : ULONG;
 end;
 PSYSTEM_CONFIGURATION_INFORMATION = ^SYSTEM_CONFIGURATION_INFORMATION;

function NtQuerySystemInformation(SystemInformationClass: LongInt;
 SystemInformation: Pointer; SystemInformationLength: ULONG;
 ReturnLength: PDWORD): NTSTATUS; stdcall; external "ntdll.dll" name "NtQuerySystemInformation";

function SysInfo_GetSysConfigInformation(const pSysConfigInfo: PSYSTEM_CONFIGURATION_INFORMATION; var cbReturn: DWord): NTSTATUS;
begin
cbReturn := 0;
Result := NtQuerySystemInformation(SystemConfigurationInformation, pSysConfigInfo,
                                   SizeOf(SYSTEM_CONFIGURATION_INFORMATION), @cbReturn);
if Result <> STATUS_SUCCESS then FillChar(pSysConfigInfo^, SizeOf(SYSTEM_CONFIGURATION_INFORMATION), 0);
end;

function SysInfo_GetSysConfigInfoStr(const pSysConfigInfo: PSYSTEM_CONFIGURATION_INFORMATION; const Dlm: string): string;
begin
with pSysConfigInfo^ do
 Result := Format("DiskCount :  %d" + Dlm + "FloppyCount :  %d" + Dlm + "CdRomCount :  %d" + Dlm + "TapeCount :  %d" + Dlm + "SerialCount :  %d" + Dlm + "ParallelCount :  %d",
                  [DiskCount, FloppyCount, CdRomCount, TapeCount, SerialCount, ParallelCount]);
end;

function DiskGeometry_Str(const pGeometry: PDISK_GEOMETRY; const Dlm: string): string;
begin
with pGeometry^ do
 Result := "Cylinders :  " + IntToStr(Cylinders.QuadPart) + Dlm + "MediaType :  " + "Str_MediaType(MediaType)" + Dlm + "TracksPerCylinder :  " + IntToStr(TracksPerCylinder) + Dlm + "SectorsPerTrack :  " + IntToStr(SectorsPerTrack) + Dlm + "BytesPerSector :  " + IntToStr(BytesPerSector);
end;

function DiskGeometryGetPartition(const GeometryEx: DWord): PDISK_PARTITION_INFO;
begin
Result := PDISK_PARTITION_INFO(GeometryEx + 1);
end;

function RefreshPhysicalDevice(List: TStrings): integer;
var
FSysConfigInfo: SYSTEM_CONFIGURATION_INFORMATION;
pGeomEx: PDISK_GEOMETRY_EX;
pGeom: PDISK_GEOMETRY;
cbReturn: DWord;
i: integer;
FDiskIoControl: TDiskIoControl;
begin
FDiskIoControl := TDiskIoControl.Create;
try
 Result := SysInfo_GetSysConfigInformation(@FSysConfigInfo, cbReturn);
 List.Add(SysInfo_GetSysConfigInfoStr(@FSysConfigInfo, #13#10));
 if Result = STATUS_SUCCESS then
  with List, FDiskIoControl do
   try
    BeginUpdate;
    Clear;
    for i := 0 to Pred(FSysConfigInfo.DiskCount) do
     begin
      Add(PREFIX_PHDRIVE + IntToStr(i));
      cbReturn := SetDeviceNum(i, GENERIC_READ, FILE_DEVICE_DISK);
      if cbReturn = ERROR_SUCCESS then
       try
        pGeomEx := GetGeometryEx(cbReturn);
        if pGeomEx <> nil then
         with pGeomEx^ do
           begin
            Add(DiskGeometry_Str(@Geometry, #13#10));
            Add(IntToStr(DiskGlobalSize) + " = " + IntToStr(DiskSize.QuadPart));
            with DiskGeometryGetPartition(DWord(pGeomEx))^ do
             Add(IntToStr(Signature) + " = " + IntToStr(CheckSum) + " = " + GUIDToString(DiskId));
           end
         else ShowMessage("GetGeometryEx" + #13#10 + SysErrorMessage(cbReturn));
        finally
         Device_Close;
        end
       else ShowMessage("SetDeviceNum" + #13#10 + SysErrorMessage(cbReturn));
     end;

    for i := 0 to Pred(FSysConfigInfo.CdRomCount) do
     begin
     Add(PREFIX_CDROM + IntToStr(i));
     cbReturn := SetDeviceNum(i, GENERIC_READ, FILE_DEVICE_CD_ROM);
     if cbReturn = ERROR_SUCCESS then
      try
       pGeomEx := GetGeometryEx(cbReturn);
       if pGeomEx <> nil then
        with pGeomEx^ do
         begin
          Add(DiskGeometry_Str(@Geometry, #13#10));
          Add(IntToStr(DiskGlobalSize) + #13#10 + IntToStr(DiskSize.QuadPart));
          with DiskGeometryGetPartition(DWord(pGeomEx))^ do
           Add(IntToStr(Signature) + " = " + IntToStr(CheckSum) + " = " + GUIDToString(DiskId));
         end
       else ShowMessage("GetGeometryEx" + #13#10 + SysErrorMessage(cbReturn));
      finally
       Device_Close;
      end
     else ShowMessage("SetDeviceNum" + #13#10 + SysErrorMessage(cbReturn));
   end;
// Здесь флоппики запрашиваются с  IOCTL_DISK_GET_DRIVE_GEOMETRY
   for i := 0 to Pred(FSysConfigInfo.FloppyCount) do
    begin
     Add(PREFIX_FLOPPY + IntToStr(i));
     cbReturn := SetDeviceNum(i, GENERIC_READ, FILE_DEVICE_FLOPPY_TEMP);
     if cbReturn = ERROR_SUCCESS then
      try
       pGeom := GetGeometry(cbReturn);
       if pGeom <> nil then
        with pGeom^ do
         begin
          Add(DiskGeometry_Str(pGeom, #13#10));
          Add(IntToStr(DiskGlobalSize));
         end
        else ShowMessage("GetGeometry" + #13#10 + SysErrorMessage(cbReturn));
        finally


 
Игорь Шевченко ©   (2007-05-28 15:43) [27]

http://www.schevchenko.net.ru/SRC/DeviceIoControl_60.zip

и

http://www.schevchenko.net.ru/


 
Riply ©   (2007-05-28 15:44) [28]

// Здесь флоппики запрашиваются с  IOCTL_DISK_GET_DRIVE_GEOMETRY
   for i := 0 to Pred(FSysConfigInfo.FloppyCount) do
    begin
     Add(PREFIX_FLOPPY + IntToStr(i));
     cbReturn := SetDeviceNum(i, GENERIC_READ, FILE_DEVICE_FLOPPY_TEMP);
     if cbReturn = ERROR_SUCCESS then
      try
       pGeom := GetGeometry(cbReturn);
       if pGeom <> nil then
        with pGeom^ do
         begin
          Add(DiskGeometry_Str(pGeom, #13#10));
          Add(IntToStr(DiskGlobalSize));
         end
        else ShowMessage("GetGeometry" + #13#10 + SysErrorMessage(cbReturn));
        finally
         Device_Close;
        end
       else ShowMessage("SetDeviceNum" + #13#10 + SysErrorMessage(cbReturn));
    end;
// А здесь флоппики запрашиваются с  IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
   for i := 0 to Pred(FSysConfigInfo.FloppyCount) do
     begin
      Add(PREFIX_FLOPPY + IntToStr(i));
      cbReturn := SetDeviceNum(i, GENERIC_READ, FILE_DEVICE_FLOPPY_TEMP);
      if cbReturn = ERROR_SUCCESS then
       try
        pGeomEx := GetGeometryEx(cbReturn);
        if pGeomEx <> nil then
         with pGeomEx^ do
           begin
            Add(DiskGeometry_Str(@Geometry, #13#10));
            Add(IntToStr(DiskGlobalSize) + " = " + IntToStr(DiskSize.QuadPart));
            with DiskGeometryGetPartition(DWord(pGeomEx))^ do
             Add(IntToStr(Signature) + " = " + IntToStr(CheckSum) + " = " + GUIDToString(DiskId));
           end
         else ShowMessage("GetGeometryEx" + #13#10 + SysErrorMessage(cbReturn));
        finally
         Device_Close;
        end
       else ShowMessage("SetDeviceNum" + #13#10 + SysErrorMessage(cbReturn));
     end;

  finally
   EndUpdate;
  end;
finally
 FDiskIoControl.Free;
end;
ShowMessage(List.Text);
end;

end.


Последний кусочек :)
с момента // Здесь флоппики запрашиваются с  IOCTL_DISK_GET_DRIVE_GEOMETRY


 
Riply ©   (2007-05-28 15:47) [29]

> [27] Игорь Шевченко ©   (28.05.07 15:43)
>http://www.schevchenko.net.ru/SRC/DeviceIoControl_60.zip
Именно от них(исходников DeviceIoControl_60) я и отталкивалась :)


 
Сергей М. ©   (2007-05-28 15:57) [30]


> Riply


Скопировал.

Гляну на досуге, что там к чему


 
Сергей М. ©   (2007-05-29 10:52) [31]


> Riply


Оттрассировал код в части этой проблемы.
Да, она действительно существует, по кр.мере в XP SP2.
Простейшее решение уже подсказал ИШ.

Посмотри сюда:
http://www.koders.com/cpp/fid69DF2D7A8EE4448E7F0B502B3CBC76AFC82A20C5.aspx


 
Игорь Шевченко ©   (2007-05-29 11:22) [32]

Сергей М. ©   (29.05.07 10:52) [31]

"/* Always try using the new EX ioctls first (>= XP).  If not available,
    fall back to trying the old non-EX ioctls.
    Unfortunately the EX ioctls are not implemented in the floppy driver. */"

Дык!


 
Riply ©   (2007-05-29 12:26) [33]

Спасибо всем огромное !
Как уже не раз говорила: очень здорово, когда все становится на свои места :)
И Форум, в очередной раз, доказывает, что свое имя носит заслуженно.

> [31] Сергей М. ©   (29.05.07 10:52)
>http://www.koders.com/cpp/fid69DF2D7A8EE4448E7F0B502B3CBC76AFC82A20C5.aspx
Хорошая ссылка. Теперь ничего придумывать не надо: переводи себе код и все :)

>[22] Игорь Шевченко ©   (28.05.07 15:35)
>Выдаешь запрос с _EX-функцией, если возвращает Invalid function, выдаешь запрос функции без _EX.
>Глядишь, когда драйвер флопа научится EX-вариант понимать, тебе и переделывать ничего не придется.
Так нечестно. Вы, наверное, в ответ подглядели :)


 
Игорь Шевченко ©   (2007-05-29 12:28) [34]


> Так нечестно. Вы, наверное, в ответ подглядели


Нет, хорошие идею приходят умным людям одновременно.


 
Riply ©   (2007-05-29 12:33) [35]

> [34] Игорь Шевченко ©   (29.05.07 12:28)
>Нет, хорошие идею приходят умным людям одновременно.
Вынуждена согласиться с каждым словом в данном утверждении :)


 
Сергей М. ©   (2007-05-29 12:48) [36]


> Riply


Оффтоп: Как там пайпы твои поживают ?


 
Riply ©   (2007-05-29 18:10) [37]

> [36] Сергей М. ©   (29.05.07 12:48)
>Оффтоп: Как там пайпы твои поживают ?
Тоже оффтоп:
В стадии  Pred(alpha testing)  :)
Более - менее готовы базовые классы.
Пытаюсь использовать их в "реальных условиях" и смотрю, что из этого выходит :)


 
Правильный Вася   (2007-05-29 18:17) [38]


> Поучение геометрии флоппи диска.

да уж, старый флопик новой геометрии не обучишь...
квадратным он точно не станет



Страницы: 1 вся ветка

Текущий архив: 2007.06.17;
Скачать: CL | DM;

Наверх




Память: 0.63 MB
Время: 0.015 c
1-1176644486
Fantom348
2007-04-15 17:41
2007.06.17
Unicode FilePath


15-1179701551
P
2007-05-21 02:52
2007.06.17
Какая религия Вам ближе?


1-1176996961
Dmitry_177
2007-04-19 19:36
2007.06.17
Копия запущенной программы


15-1179705771
Германн
2007-05-21 04:02
2007.06.17
Европа и Россия


2-1179154246
Lordalex
2007-05-14 18:50
2007.06.17
помогите с ошибкой