1

i have this code i don´t have experience in windows:

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


   typedef BOOL (WINAPI *P_GDFSE)(LPCTSTR, PULARGE_INTEGER, 
                                  PULARGE_INTEGER, PULARGE_INTEGER);

   void main (int argc, char **argv)
   {
      BOOL  fResult;

      char  *pszDrive  = NULL,
             szDrive[4];

      DWORD dwSectPerClust,
            dwBytesPerSect,
            dwFreeClusters,
            dwTotalClusters;

      P_GDFSE pGetDiskFreeSpaceEx = NULL;

      unsigned __int64 i64FreeBytesToCaller,
                       i64TotalBytes,
                       i64FreeBytes;


      if (argc != 2)
      {
         printf ("usage:  %s <drive|UNC path>\n", argv[0]);
         printf ("\texample:  %s C:\\\n", argv[0]);
         return;
      }

      pszDrive = argv[1];

      if (pszDrive[1] == ':')
      {
         szDrive[0] = pszDrive[0];
         szDrive[1] = ':';
         szDrive[2] = '\\';
         szDrive[3] = '\0';

         pszDrive = szDrive;
      }

     // FIRST ERROR  kernel32.dll
      pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress (
                               GetModuleHandle ("kernel32.dll"),
                                              "GetDiskFreeSpaceExA");
       // SECOND ERROR pszDrive
      if (pGetDiskFreeSpaceEx)
      {
         fResult = pGetDiskFreeSpaceEx (pszDrive,
                                 (PULARGE_INTEGER)&i64FreeBytesToCaller,
                                 (PULARGE_INTEGER)&i64TotalBytes,
                                 (PULARGE_INTEGER)&i64FreeBytes);
         if (fResult)
         {
            printf ("\n\nGetDiskFreeSpaceEx reports\n\n");
            printf ("Available space to caller = %I64u MB\n",
                    i64FreeBytesToCaller / (1024*1024));
            printf ("Total space               = %I64u MB\n",
                    i64TotalBytes / (1024*1024));
            printf ("Free space on drive       = %I64u MB\n",
                    i64FreeBytes / (1024*1024));
         }
      }
      else
      {
         // ERROR 3 pszDrive
         fResult = GetDiskFreeSpace (pszDrive, 
                                     &dwSectPerClust,
                                     &dwBytesPerSect, 
                                     &dwFreeClusters,
                                     &dwTotalClusters);
         if (fResult)
         {
            /* force 64-bit math */ 
            i64TotalBytes = (__int64)dwTotalClusters * dwSectPerClust *
                              dwBytesPerSect;
            i64FreeBytes = (__int64)dwFreeClusters * dwSectPerClust *
                              dwBytesPerSect;

            printf ("GetDiskFreeSpace reports\n\n");
            printf ("Free space  = %I64u MB\n", 
                    i64FreeBytes / (1024*1024));
            printf ("Total space = %I64u MB\n", 
                    i64TotalBytes / (1024*1024));
         }
      }

      if (!fResult)
         printf ("error: %lu:  could not get free space for \"%s\"\n",
                 GetLastError(), argv[1]);
   }

i'm getting these errors(visual studio 2010 ultimate):

at kernel32.dll:

pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress ( GetModuleHandle ("kernel32.dll"), "GetDiskFreeSpaceExA");

Error: argument of type const char* is incompatible with parameter of type "LPCWSTR"

at pszDrive:

fResult = pGetDiskFreeSpaceEx (pszDrive,
                                 (PULARGE_INTEGER)&i64FreeBytesToCaller,
                                 (PULARGE_INTEGER)&i64TotalBytes,
                                 (PULARGE_INTEGER)&i64FreeBytes);

Error: argument of type char* is incompatible with parameter of type "LPCTSTR"

at pszDrive:

 fResult = GetDiskFreeSpace (pszDrive, 
                                     &dwSectPerClust,
                                     &dwBytesPerSect, 
                                     &dwFreeClusters,
                                     &dwTotalClusters);

Error: argument of type char* is incompatible with parameter of type "LPCWSTR"

thanks a lot

fbm_bcn
  • 23
  • 1
  • 5

3 Answers3

4

The simplest solution would be to change the project settings to the multi-byte character set.

To do this, right-click on the project in the Solution Explorer, select Properties. Select General in the left-hand pane of the properties dialog. Find Character Set and change it to "Use Multi-Byte Character Set".

If you're going to be doing a lot of Windows programming, though, you should get used to Unicode. Basically that means using wchar_t (or TCHAR) instead of char, including in constant strings:

      pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress (
                                          GetModuleHandle (L"kernel32.dll"),
                                          "GetDiskFreeSpaceExW");

In this case, as Adam correctly pointed out, you also need to change the function name from the A version to the W version.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
1

Change your code to be more TCHAR aware, since that is what the Win2 API expects when you mix Ansi and Unicode code together like you are:

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

typedef BOOL (WINAPI *P_GDFSE)(LPCTSTR, PULARGE_INTEGER,  
                              PULARGE_INTEGER, PULARGE_INTEGER); 

void _tmain (int argc, TCHAR **argv) 
{ 
    BOOL  fResult; 

    TCHAR *pszDrive = NULL,
          szDrive[4]; 

    DWORD dwSectPerClust, 
          dwBytesPerSect, 
          dwFreeClusters, 
          dwTotalClusters; 

    P_GDFSE pGetDiskFreeSpaceEx = NULL; 

    unsigned __int64 i64FreeBytesToCaller, 
                     i64TotalBytes, 
                     i64FreeBytes; 


    if (argc != 2) 
    { 
        _tprintf (_T("usage:  %s <drive|UNC path>\n"), argv[0]); 
        _tprintf (_T("\texample:  %s C:\\\n"), argv[0]); 
        return; 
    } 

    pszDrive = argv[1]; 

    if (pszDrive[1] == TEXT(':')) 
    { 
        _stprintf(szDrive, _T("%s:\\"), pszDrive[0]); 
        pszDrive = szDrive; 
    } 

    // FIRST ERROR  kernel32.dll 
    pGetDiskFreeSpaceEx = (P_GDFSE) GetProcAddress ( 
                           GetModuleHandle (TEXT("kernel32.dll")), 
                                          #ifdef UNICODE
                                          "GetDiskFreeSpaceExW"); 
                                          #else
                                          "GetDiskFreeSpaceExA"); 
                                          #endif
                           );

    // SECOND ERROR pszDrive 
    if (pGetDiskFreeSpaceEx) 
    { 
        fResult = pGetDiskFreeSpaceEx (pszDrive, 
                             (PULARGE_INTEGER)&i64FreeBytesToCaller, 
                             (PULARGE_INTEGER)&i64TotalBytes, 
                             (PULARGE_INTEGER)&i64FreeBytes); 
        if (fResult) 
        { 
            _tprintf (_T("\n\nGetDiskFreeSpaceEx reports\n\n")); 
            _tprintf (_T("Available space to caller = %I64u MB\n"), 
                i64FreeBytesToCaller / (1024*1024)); 
            _tprintf (_T("Total space               = %I64u MB\n"), 
                i64TotalBytes / (1024*1024)); 
            _tprintf (_T("Free space on drive       = %I64u MB\n"), 
                i64FreeBytes / (1024*1024)); 
        } 
    } 
    else 
    { 
        // ERROR 3 pszDrive 
        fResult = GetDiskFreeSpace (pszDrive,  
                                 &dwSectPerClust, 
                                 &dwBytesPerSect,  
                                 &dwFreeClusters, 
                                 &dwTotalClusters); 
        if (fResult) 
        { 
            /* force 64-bit math */  
            i64TotalBytes = (__int64)dwTotalClusters * dwSectPerClust * 
                          dwBytesPerSect; 
            i64FreeBytes = (__int64)dwFreeClusters * dwSectPerClust * 
                          dwBytesPerSect; 

            _tprintf (_T("GetDiskFreeSpace reports\n\n")); 
            _tprintf (_T("Free space  = %I64u MB\n"),  
                i64FreeBytes / (1024*1024)); 
            _tprintf (_T("Total space = %I64u MB\n"),  
                i64TotalBytes / (1024*1024)); 
        } 
    } 

    if (!fResult) 
        _tprintf (_T("error: %lu:  could not get free space for \"%s\"\n"), 
             GetLastError(), argv[1]); 
} 

Otherwise, since you are compiling with UNICODE enabled, just write Unicode-only code instead:

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

typedef BOOL (WINAPI *P_GDFSE)(LPCWSTR, PULARGE_INTEGER,  
                              PULARGE_INTEGER, PULARGE_INTEGER); 

void wmain (int argc, wchar_t **argv) 
{ 
    BOOL  fResult; 

    wchar_t *pszDrive = NULL,
          szDrive[4]; 

    DWORD dwSectPerClust, 
          dwBytesPerSect, 
          dwFreeClusters, 
          dwTotalClusters; 

    P_GDFSE pGetDiskFreeSpaceEx = NULL; 

    unsigned __int64 i64FreeBytesToCaller, 
                     i64TotalBytes, 
                     i64FreeBytes; 


    if (argc != 2) 
    { 
        wprintf (L"usage:  %s <drive|UNC path>\n", argv[0]); 
        wprintf (L"\texample:  %s C:\\\n", argv[0]); 
        return; 
    } 

    pszDrive = argv[1]; 

    if (pszDrive[1] == L':') 
    { 
        _stprintf(szDrive, _T("%s:\\"), pszDrive[0]); 
        pszDrive = szDrive; 
    } 

    // FIRST ERROR  kernel32.dll 
    pGetDiskFreeSpaceEx = (P_GDFSE) GetProcAddress ( 
                           GetModuleHandle (TEXT("kernel32.dll")), 
                                          "GetDiskFreeSpaceExW"
                           ); 
    // SECOND ERROR pszDrive 
    if (pGetDiskFreeSpaceEx) 
    { 
        fResult = pGetDiskFreeSpaceEx (pszDrive, 
                             (PULARGE_INTEGER)&i64FreeBytesToCaller, 
                             (PULARGE_INTEGER)&i64TotalBytes, 
                             (PULARGE_INTEGER)&i64FreeBytes); 
        if (fResult) 
        { 
            wprintf (L"\n\nGetDiskFreeSpaceEx reports\n\n"); 
            wprintf (L"Available space to caller = %I64u MB\n", 
                i64FreeBytesToCaller / (1024*1024)); 
            wprintf (L"Total space               = %I64u MB\n", 
                i64TotalBytes / (1024*1024)); 
            wprintf (L"Free space on drive       = %I64u MB\n", 
                i64FreeBytes / (1024*1024)); 
        } 
    } 
    else 
    { 
        // ERROR 3 pszDrive 
        fResult = GetDiskFreeSpace (pszDrive,  
                                 &dwSectPerClust, 
                                 &dwBytesPerSect,  
                                 &dwFreeClusters, 
                                 &dwTotalClusters); 
        if (fResult) 
        { 
            /* force 64-bit math */  
            i64TotalBytes = (__int64)dwTotalClusters * dwSectPerClust * 
                          dwBytesPerSect; 
            i64FreeBytes = (__int64)dwFreeClusters * dwSectPerClust * 
                          dwBytesPerSect; 

            wprintf (L"GetDiskFreeSpace reports\n\n"); 
            wprintf (L"Free space  = %I64u MB\n",  
                i64FreeBytes / (1024*1024)); 
            wprintf (L"Total space = %I64u MB\n",  
                i64TotalBytes / (1024*1024)); 
        } 
    } 

    if (!fResult) 
        wprintf (L"error: %lu:  could not get free space for \"%s\"\n", 
             GetLastError(), argv[1]); 
} 
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

You are apparently compiling in UNICODE mode. Change the following:

void _tmain (int argc, TCHAR **argv)

and

  TCHAR  *pszDrive  = NULL,
         szDrive[4];

That should get you further along. See the following question for more information: What is the difference between _tmain() and main() in C++?

Community
  • 1
  • 1
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • That won't quite work since OP is explicitly asking for the ANSI variant with `GetProcAddress(..., "GetDiskFreeSpaceExA")`. – Adam Rosenfield Oct 22 '12 at 23:28
  • hi, thanks a lot and for the link i need to read a lot about win programming, i still have the firt error at "kernel32" the others are ok, could you check if i need to change that for UNICODE – fbm_bcn Oct 22 '12 at 23:33