Toon posts:

[Delphi/C++] Drivespace code werkt niet :(

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo!
Ik heb een klein monitorprogje geschreven genaamd MCO (Memory and CPU Observer, zie website www.beam.ti/mco voor meer info).
Nu hebben enkele mensen mij gerapporteerd dat zij onder Windows 98 SE problemen hebben met de drivespace informatie. De C drive wordt bijvoorbeeld niet weergegeven terwijl de D drive wel wordt weergegeven.
Nu ben ik eens goed in de code van mij gaan kijken, maar ik kan niet echt een "fout" ontdekken. :?

Heeft iemand misschien een idee wat ik (hier) fout doe???

Ik heb onderstaande code gebruikt, dit is de code voor het bepalen van het aantal drives op een pc.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
type 
  TUsage = record
   DriveNumber: array [1..10] of Byte;
   DriveName: array [1..10] of Char;
  end;

var
  Usage: TUsage;

procedure GetDriveCount;
var Drive: integer;
    i: integer;
    Ch: Char;
    s: String;
begin
 Drive := 0;
 i := 0;
 for Ch := 'A' to 'Z' do
  begin
   i := i + 1;
   s := Ch + ':';
   if (GetDriveType (PChar (s)) = DRIVE_FIXED) or (GetDriveType (PChar (s)) = DRIVE_REMOTE) then
    begin
     Drive := Drive + 1;
     if Drive <= 10 then
    begin
     Usage.DriveNumber[Drive] := i;
     Usage.DriveName[Drive] := Ch;
    end;
    end;
  end;
 if Drive > 10 then Drive := 10;
 Usage.DriveCount := Drive;
end;

  • Belgar
  • Registratie: Januari 2002
  • Laatst online: 17-08 22:31

Belgar

Archmaster ranzige code..

dit stukje telt de drives. welk commando gebruik je voor het eigenlijke ophalen van de info? gebruik in C++ altijd de interface call 'DeviceIoControl'

...Als het maar werkt


Verwijderd

Topicstarter
Oh... daarvoor gebruik ik een Delphi functie namenlijk DiskFree... ;)
code:
1
function DiskFree(Drive: Byte): Int64;

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 14:38

curry684

left part of the evil twins

code:
1
if (GetDriveType (PChar (s)) = DRIVE_FIXED) or (GetDriveType (PChar (s)) = DRIVE_REMOTE) then

Ik vind deze regel nogal bot, hierbij negeer je CD-Roms en removable disks. Ik zou het eerder als volgt schrijven:
code:
1
if (GetDriveType (PChar (s)) <> DRIVE_UNKNOWN) and (GetDriveType (PChar (s)) <> DRIVE_NO_ROOT_DIR) then

Kzeg niet dat dit het is, maar wel correcter iig: het is altijd beter om de foutconditie te checken dan een mogelijke toekomstige geldige conditie bij voorbaat uit te sluiten. Nog beter is overigens om die call vantevoren uit te voeren, want ik weet niet of Delphi slim genoeg is om hier zelf 1 API-call van te fabrieken.

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 14:38

curry684

left part of the evil twins

Belangrijkere fout... lees de MSDN docs over GetDriveType:
GetDriveType
The GetDriveType function determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.
code:
1
2
3
UINT GetDriveType(
  LPCTSTR lpRootPathName   // root directory
);

Parameters
lpRootPathName [in] Pointer to a null-terminated string that specifies the root directory of the disk to return information about. A trailing backslash is required. If lpRootPathName is NULL, the function uses the root of the current directory.

Professionele website nodig?


Verwijderd

Topicstarter
Hardstikke bedankt voor de hulp :)

Ik was trouwens vergeten te vermelden dat het hier gaat om Fixed Drives en Mapped Network Drives... |:(

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13:31
Op woensdag 03 juli 2002 21:22 schreef curry684 het volgende:
Nog beter is overigens om die call vantevoren uit te voeren, want ik weet niet of Delphi slim genoeg is om hier zelf 1 API-call van te fabrieken.
Waarschijnlijk doet 'ie dat niet, als zou 'ie het kunnen, omdat de compiler waarschijnlijk niet kan beoordelen wat de side effects van die API call zijn.

Waarschijnlijk zijn die er niet, maar als die er wel zouden zijn, dan zou de geoptimaliseerde versie andere resultaten opleveren dan de ad hoc versie en dat is natuurlijk niet de bedoeling.

Verwijderd

Nu hebben enkele mensen mij gerapporteerd dat zij onder Windows 98 SE problemen hebben met de drivespace informatie. De C drive wordt bijvoorbeeld niet weergegeven terwijl de D drive wel wordt weergegeven.

Ik heb onderstaande code gebruikt, dit is de code voor het bepalen van het aantal drives op een pc.
En als ik nou eens 11 drives heb? :(
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
type 
  TUsage = record
    DriveCount: integer;
    DriveNumber: array [1..10] of Byte;
    DriveName: array [1..10] of Char;
  end;

var
  Usage: TUsage;

function GetDriveCount: integer;
var
  Drives: array[0..(25*4)+1] of char;
  i,j: integer;
begin
  result := 0;

  i := 0;
  j := 1;
  Usage.DriveCount := 0;

  if (GetLogicalDriveStrings(SizeOf(Drives)-1,Drives) <> 0) then
  while ((Drives[i] <> #0) and (j<=10)) do
  begin
    Case GetDriveType(@Drives[i]) of
    DRIVE_FIXED, DRIVE_REMOTE:
      begin
        Usage.DriveName[j] := Drives[i];
        Usage.DriveNumber[j] := Ord(Drives[i]) - Ord('A');
        Usage.DriveCount := j;
        Inc(j);
      end;
    end;
    Inc(i,4);
  end;

  result := j;
end;

Verwijderd

Topicstarter
Als je zelf MCO van plan bent te gebruiken maak ik wel ff van de array 1..10, array 1..15, dan kun jij ook alle drives weergeven in het Drive Window... ;)

NB. het gaat hier dan wel om Fixed en Network drives... ;)

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 14:48

Tomatoman

Fulltime prutser

Aangezien er altijd een schijfletter voorhanden is, zou ik DriveName declareren als een array[1..26] of Integer.

Houd er ook rekening mee dat de compiler snellere code genereert voor het generieke type Integer dan voor het type Byte. Dat een byte (altijd 8 bits) minder geheugen gebruikt dan een integer (16 bits in Delphi 1, 32 bits sinds Delphi 2, wellicht 64 bits in nieuwe versies) maakt tegenwoordig helemaal niets meer uit - geheugen zat. Dat snelheidsverschil is natuurlijk ook te verwaarlozen, maar het is een goede gewoonte om generieke datatypes (zoals Integer en Cardinal) te gebruiken in plaats van datatypes met een vaste lengte (zoals Byte, Smallint en Longint). Dat verzekert je ervan dat je code ook bij toekomstige Delphi-compilers optimaal presteert.
code:
1
2
3
4
5
6
type 
  TUsage = record
    DriveCount: integer;
    DriveNumber: array[1..26] of Integer;
    DriveName: array[1..10] of Char;
  end;

Een goede grap mag vrienden kosten.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 14:38

curry684

left part of the evil twins

Op donderdag 04 juli 2002 00:55 schreef tomatoman het volgende:
...knip...
Ik ben juist overtuigd de mening toegedaan dat je altijd datatypes moet gebruiken waarvan je het formaat exact weet, zodat je tussen verschillende versies en platformen geen verschillen krijgt in overflow/underflow gedrag.

En als die k*t-compiler van Delphi meer moeite heeft met een longword optimizen dan met een integer moet ie linea recta in de vuilnisbak.

Professionele website nodig?


Verwijderd

fout ligt bij M$. . .(dit kun je altijd roepen als je er niet uit komt .. 95% van de tijd is het nog waar ook)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 14:38

curry684

left part of the evil twins

Op donderdag 04 juli 2002 08:55 schreef Skizmo het volgende:
fout ligt bij M$. . .(dit kun je altijd roepen als je er niet uit komt .. 95% van de tijd is het nog waar ook)
Wat is nu exact het nut van deze compleet overbodige troll nadat we hebben vastgesteld dat hijzelf een foutje heeft gemaakt tegen de MS-documentatie en het dus al stomtoevallig was dat het meestal wel werkte? :?

Kun je voortaan eerst het topic lezen voordat je irritant gaat zitten doen? |:(

Professionele website nodig?

Pagina: 1