Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.06.17;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.62 MB
Время: 0.051 c
2-1180174977
GeLLeR
2007-05-26 14:22
2007.06.17
Вопрос про dll.


2-1180100114
забыл ник %)
2007-05-25 17:35
2007.06.17
Подсказка в трее


15-1177671511
GTR86
2007-04-27 14:58
2007.06.17
Защита программы от копирования


9-1153370196
aKirill.INFO
2006-07-20 08:36
2007.06.17
Несколько экранов


3-1175082815
Thely
2007-03-28 15:53
2007.06.17
IB и ADO?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский