Toon posts:

[Win32 API] Probleem met DeviceIoControl

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo allemaal,

ik ben bezig met een programma dat wat info van een ntfs volume haalt, dit is de code

C++:
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#ifndef _WIN32_WINNT
    #define _WIN32_WINNT 0x0400
#endif

#include <windows.h>
#include <winioctl.h>
#include <stdio.h>

int Error();

int main()
{
    NTFS_VOLUME_DATA_BUFFER dataBuffer;
    BOOL bResult;
    HANDLE hVolume;
    DWORD dSize;
    
    hVolume = CreateFile("\\\\.\\PhysicalDrive0",0,FILE_SHARE_READ |FILE_SHARE_WRITE,
                            NULL, OPEN_EXISTING, 0, NULL);


    if (hVolume == INVALID_HANDLE_VALUE) // check if CreateFile was succesfull
    {
        printf("Invalid Handle\n");
        return 0;
    }
    
    bResult = DeviceIoControl(hVolume, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &dataBuffer, 
                                sizeof(NTFS_VOLUME_DATA_BUFFER),&dSize,NULL);
    CloseHandle(hVolume);
    
    if(Error()) // error checking
        return 0;
    
    printf("Volume serial number: %n", dataBuffer.VolumeSerialNumber);
    
    return 0;
    
    
}

int Error()
{
    LPVOID lpMsgBuf;

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
                    NULL,GetLastError(),0, (LPTSTR) &lpMsgBuf,0,NULL); 
    
    printf("Error: %s\n", (LPCTSTR)lpMsgBuf);
    return 1;
    
    
    return 0;

}


er gaat wat fout bij de aanroep van DeviceIoControl en met GetLastError() krijg ik de error "Incorrect Function" terug, er is dus duidelijk wat mis met die aanroep :P

Na heel wat uren zoeken 8)7 ben ik er nog steeds niet uit, misschien zie ik wat over het hoofd.

De compiler geeft geen error of warning (visual c++ 6), en als ik zonder error check door ga dan crashed het programma.

greetz rremzie

[ Voor 8% gewijzigd door Verwijderd op 25-10-2003 16:55 ]


Verwijderd

Waar wordt geheugen gealloceerd voor databuffer?
De code stopt nu altijd bij aanroep van de functie Error()
Waarom wordt de waarde van bResult niet gecontroleerd?
Je moet de Error functie aanroepen direct na de DeviceIOControl functie, dus voor CloseHandle.

Wellicht een alternatief, maar voorkomt niet eerder genoemde problemen.

[ Voor 13% gewijzigd door Verwijderd op 26-10-2003 01:43 ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Hmmm tricky, ben er nu een half uur mee gaan stoeien maar krijg het ook niet aan de praat op XP SP1 met VC.NET. En ik heb alle parameters nog 3 keer doorgenomen maar je doet het echt goed afaics.... :/ Ook niet in KB gevonden, is mij echt een raadsel dit :'(

Professionele website nodig?


Verwijderd

Topicstarter
er staat ook nergens in de documentatie iets over die Incorrect Funtion van getlasterror. Maarja verder zoeken dan maar.

sinaasappelsap: deze functie kan nog meer informatie opvragen zoals cluster etc, dus vandaar dat ik deze aan de praat wil krijgen

[ Voor 36% gewijzigd door Verwijderd op 26-10-2003 09:25 ]


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Er zitten 2 fouten in, of eigenlijk 3 als het printen meerekend:
1.
Aan CreateFile geef je geen enkele rechten mee (2e parameter is 0), maar de documentatie van FSCTL_GET_NTFS_VOLUME_DATA zegt dat je FILE_READ_ATTRIBUTES nodig hebt (of WRITE maar dat lijkt me minder verstandig als je alleen wilt lezen). Op 1 of andere manier werkt zelfs dat nog niet, maar GENERIC_READ weer wel..

2.
Je wilt een *volume* openen, niet een physical drive. Je kan niet de NTFS properties opvragen van een disk, omdat daar misschien wel 3 volumes op kunnen staan. In plaats van "\\\\.\\PhysicalDrive0" moet je dan ook "\\\\.\\C:" gebruiken. De C kun je natuurlijk vervangen door de andere volume letters. Het geheel wordt dus:
C++:
1
2
hVolume = CreateFile("\\\\.\\C:",GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE, 
                     NULL, OPEN_EXISTING, 0, NULL);


3.
Nu zou ie moeten werken maar crasht ie in de printf. VolumeSerialNumber is namelijk een LARGE_INTEGER van 64-bits, en die moet je dus ook zo uitprinten (niet als %n). Ik weet niet of er een 64-bit print mogelijkheid is in printf, maar je kan em ook in delen printen:
C++:
1
2
3
printf("Volume serial number: %08X-%08X\n", 
       dataBuffer.VolumeSerialNumber.HighPart,
       dataBuffer.VolumeSerialNumber.LowPart); 

edit: Als je toch C++ gebruikt kan je ipv printf natuurlijk cout gebruiken en dan heb je dit soort problemen niet..

[ Voor 7% gewijzigd door madwizard op 26-10-2003 10:04 ]

www.madwizard.org


  • igmar
  • Registratie: April 2000
  • Laatst online: 29-06 18:56

igmar

ISO20022

madwizard schreef op 26 oktober 2003 @ 10:01:
Ik weet niet of er een 64-bit print mogelijkheid is in printf
%ll is de conversion, %lld voor een long long, %llu voor een unsigned long long.

Verwijderd

Topicstarter
madwizard heel erg bedankt _/-\o_

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Madwizard: hmmm 1 had ik al gezien en gecorrigeerd, maar 2 compleet overheen gekeken :P Held _o_

Professionele website nodig?


  • The End
  • Registratie: Maart 2000
  • Laatst online: 13:56

The End

!Beginning

madwizard schreef op 26 October 2003 @ 10:01:

[knip]

3.
Nu zou ie moeten werken maar crasht ie in de printf. VolumeSerialNumber is namelijk een LARGE_INTEGER van 64-bits, en die moet je dus ook zo uitprinten (niet als %n). Ik weet niet of er een 64-bit print mogelijkheid is in printf, maar je kan em ook in delen printen:
C++:
1
2
3
printf("Volume serial number: %08X-%08X\n", 
       dataBuffer.VolumeSerialNumber.HighPart,
       dataBuffer.VolumeSerialNumber.LowPart); 

edit: Als je toch C++ gebruikt kan je ipv printf natuurlijk cout gebruiken en dan heb je dit soort problemen niet..
Je kan op deze manier een 64 bits integer printen:
C++:
1
printf("%I64d",dataBuffer.VolumeSerialNumber);

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

The End schreef op 27 October 2003 @ 11:37:
[...]
Je kan op deze manier een 64 bits integer printen:
C++:
1
printf("%I64d",dataBuffer.VolumeSerialNumber);
Dan zit je vast aan VC++, zie hier bijv.

Professionele website nodig?

Pagina: 1