Funkcja GetVolumeInformation

0
#include <Windows.h>
#include <cstdio>
#include <io.h>
#include <fcntl.h>

void OpenConsole()
{
	int hCrt;
   FILE *hf;

   AllocConsole();
   hCrt = _open_osfhandle(
             (long) GetStdHandle(STD_OUTPUT_HANDLE),
             _O_TEXT
          );
   hf = _fdopen( hCrt, "w" );
   *stdout = *hf;
   setvbuf( stdout, NULL, _IONBF, 0 );
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdin , int showMode)
{
	LPTSTR volumeNameBuffer=NULL,fileSystemNameBuffer=NULL;
	LPDWORD volumeSerialNumber,maximumComponentLength,fileSystemFlags;
	
	OpenConsole();

	printf("C volume info: \n");
	
//(1)	if(!GetVolumeInformation("C:\\",volumeNameBuffer,MAX_PATH+1,volumeSerialNumber,maximumComponentLength,fileSystemFlags,fileSystemNameBuffer,10))
		MessageBox(0,"Error!","Error!",0);

//(2)
	/*if(!GetVolumeInformation(volumeNameBuffer,MAX_PATH,fileSystemNameBuffer,10))
		MessageBox(0,"Error!","Error!",0);*/
	

	printf("volume name: %s, file system: %s\n",volumeNameBuffer, fileSystemNameBuffer);

	Sleep(10000);
	
	return 0;
}

Informacje n.t naszej nieszczęsnej funkcji:
http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k%28GETVOLUMEINFORMATION%29;k%28DevLang-%22C%2B%2B%22%29&rd=true

Problem jest następujący: w pierwszym przypadku (1) korzystam z rozszerzonej wersji funkcji(podaję wszystkie parametry, łącznie z opcjonalnymi). Wychodzi run-time error:

Run-Time Check Failure #3 - The variable 'fileSystemFlags' is being used without being initialized.

Po co niby miałem to inicjalizować, skoro do tej zmiennej ma wchodzić output funkcji?

(2)
Wyskakuje błąd kompilacji,wynika z niego tak jakby wszystkie parametry były obowiązkowe:

1>c:\users\tomek\documents\visual studio 2010\projects\file_creation_winapi\file_creation_winapi\file_creation_main.cpp(33): error C2660: 'GetVolumeInformationA' : function does not take 4 arguments

0

Ehhh...
(1) bo niby skąd funkcja ma wiedzieć, że używasz tego parametru czy nie? Wiesz w ogóle co to jest LPDWORD? To jest nic innego jak DWORD*, LPDWORD zamień na DWORD.
(2) no błąd wyskakuje, ponieważ funkcja GetVolumeInformation(A/W) nie przyjmuje 4 parametrów tylko 8, chyba, że liczyć nie umiem.

btw: nie ten dział

0
byku_guzio napisał(a)

Wiesz w ogóle co to jest LPDWORD? To jest nic innego jak DWORD*, LPDWORD zamień na DWORD.
(2) no błąd wyskakuje, ponieważ funkcja GetVolumeInformation(A/W) nie przyjmuje 4 parametrów tylko 8, chyba, że liczyć nie umiem.

Po zamianie na DWORD wyskakuje błąd kompilacji , co jest zrozumiałe bo w deklaracji funkcji mamy LPDWORD . Specjalnie wstawiłem hiperłącze do oficjalnej dokumentacji.

(2) __out_opt nie znaczy że parametr jest opcjonalny? Myślałem że jest "overridden" wersja funkcji która przyjmuje 4 argumenty...

0

A jest gdzieś napisane, że jest takie przeładowanie? I jak takie przeładowania miałyby wyglądać np. jeżeli chciałbyś wrzucić wszystkie parametry bez lpVolumeSerialNumber i druga wersja bez lpMaximumComponentLength?

Jak nie chcesz dostać czy przekazać jakiś opcjonalnych danych to trzeba w to miejsce przekazać NULL.

No to napiszę jeszcze raz. LPDWORD to jest dokładnie DWORD*. Definicja LPDWORD wygląda tak:

typedef DWORD far           *LPDWORD;

czyli to jest po prostu WSKAŹNIK na DWORD. Chyba nie chcesz mi powiedzieć, że nie wiesz jak przekazywać do funkcji zmienne przez wskaźnik. Jak nie wiesz to proponuję poczytać o wskaźnikach i funkcjach.

0
LPDWORD volumeSerialNumber,maximumComponentLength,fileSystemFlags;

Jest poprawnym zapisem podczas gdy

DWORD* volumeSerialNumber,maximumComponentLength,fileSystemFlags;

już nie. W gwoli ścisłości-trzeba wymieniać zmienne oddzielnie, bez przecinków, lub dać gwiazdkę do każdej z 3 zmiennych.

Skoro to samo to po co zmieniać? Moim zdaniem gwiazdki zaśmiecają kod, wolę pisać LPDWORD.

Z resztą już nie ważne, zamiast zmiennych opcjonalnych wrzuciłem NULL'e. Teraz natomiast funkcja nie może uchwycić volumeNameBuffer i fileSystemNameBuffer .

#include <Windows.h>
#include <cstdio>
#include <io.h>
#include <fcntl.h>

void OpenConsole()
{
	int hCrt;
   FILE *hf;

   AllocConsole();
   hCrt = _open_osfhandle(
             (long) GetStdHandle(STD_OUTPUT_HANDLE),
             _O_TEXT
          );
   hf = _fdopen( hCrt, "w" );
   *stdout = *hf;
   setvbuf( stdout, NULL, _IONBF, 0 );
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdin , int showMode)
{
	LPTSTR volumeNameBuffer;
        LPTSTR fileSystemNameBuffer;
	//DWORD* volumeSerialNumber,*maximumComponentLength,*fileSystemFlags;
	
	
	OpenConsole();

	printf("C volume info: \n");
	
	if(!GetVolumeInformation(NULL,volumeNameBuffer,MAX_PATH+1,NULL,NULL,NULL,fileSystemNameBuffer,10))
		MessageBox(0,"Error!","Error!",0);

	
	

	printf("volume name: %s, file system: %s\n",volumeNameBuffer, fileSystemNameBuffer);

	Sleep(10000);
	
	return 0;
}

Run-Time Check Failure #3 - The variable 'fileSystemNameBuffer' is being used without being initialized.

1

Naprawdę chciałem Cię naprowadzić na rozwiązanie, ale właśnie udało mi się rozwiązać pewien problem, otwieram piwo i mam dobry humor to napiszę Ci gotowca. Poczytaj o wskaźnikach, bo zupełnie ich nie rozumiesz, a nawet nie umiesz ich poprawnie deklarować. Zauważ, że LPDWORD jak i LPTSTR TO SĄ WSKAŹNIKI. Wskaźniki muszą na coś pokazywać, a u Ciebie wszystkie pokazują na losowy obszar pamięci i to, że Ci się aplikacja wywala to fart, bo mogłaby nie i wtedy byś pisał w losowych miejscach pamięci co się może skończyć tragicznie.

Musisz też poćwiczyć czytanie dokumentacji, bo tam to wszytko jest opisane ;)

//to są C-stringi - prawie to samo co char napis[100]. TCHAR to jest dokładnie char jeżeli nie jest włączony unicode i wchar_t w przeciwnym wypadku
TCHAR volumeNameBuffer[MAX_PATH +1];
TCHAR fileSystemNameBuffer[MAX_PATH+1];

//Skoro funkcja jako argumenty przyjmuje wskaźniki, bo przez nie zwraca jakieś informacje to te jej wskaźniki muszą pokazywać na adres zmiennej do której te informacje mają zostać wpisane:
DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags;

GetVolumeInformation("C:\\", volumeNameBuffer, MAX_PATH, &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags, fileSystemNameBuffer, MAX_PATH);

1 użytkowników online, w tym zalogowanych: 0, gości: 1