HOWTO: Use the SetupAPI's SetupIterateCabinet() Function

ID: Q189085

The information in this article applies to:

SUMMARY

This article contains a sample that demonstrates how to use the SetupAPI's SetupIterateCabinet() function to extract files out of a CAB file. When you use SetupIterateCabinet(), you do not need an .inf file.

MORE INFORMATION

This sample looks for a CAB file named TestCab.cab. You should put TestCab.cab in the same directory that contains the sample executable.

Sample Code

Create a new console application in Visual C++ version 5.0, and add the following code:

   #include <windows.h>    // Includes basic windows functionality.
   #include <stdio.h>      // Includes the standard i/o functions.
   #include <string.h>     // Includes the string functions.
   #include <tchar.h>      // Includes the string functions.
   #include <setupapi.h>   // Includes the SetupAPI.

   // Link with SetupAPI.Lib.
   #pragma comment (lib, "setupapi.lib")

   #define CAB_FILE_NAME      TEXT("TestCab.Cab")

   // Global variable holding destination directory.
   TCHAR g_szTargetPath[MAX_PATH];

   void IterateCabinet(PTSTR pszCabFile);

   void main()
   {
      TCHAR szSourcePath[MAX_PATH];
      TCHAR szInfFileName[MAX_PATH];

      GetModuleFileName(NULL, szSourcePath, MAX_PATH);
      // Strip setup.exe off path.
      *(strrchr(szSourcePath, '\\') + 1) = '\0';


      // Make the .exe directory the Target directory.
      lstrcpy(g_szTargetPath, szSourcePath);

      // Assume that CAB_FILE_NAME is in the .exe directory.
      lstrcpy(szInfFileName, szSourcePath);
      lstrcat(szInfFileName, CAB_FILE_NAME);

      IterateCabinet(szInfFileName);
   }


   LRESULT
   WINAPI
   CabinetCallback ( IN PVOID pMyInstallData,
                     IN UINT Notification,
                     IN UINT Param1,
                     IN UINT Param2 )
   {
      LRESULT lRetVal = NO_ERROR;
      TCHAR szTarget[MAX_PATH];
      FILE_IN_CABINET_INFO *pInfo = NULL;
      FILEPATHS *pFilePaths = NULL;

      lstrcpy(szTarget,g_szTargetPath);

      switch(Notification)
      {
         case SPFILENOTIFY_FILEINCABINET:
            pInfo = (FILE_IN_CABINET_INFO *)Param1;
            lstrcat(szTarget, pInfo->NameInCabinet);
            lstrcpy(pInfo->FullTargetName, szTarget);
            lRetVal = FILEOP_DOIT;  // Extract the file.
            break;

         case SPFILENOTIFY_FILEEXTRACTED:
            pFilePaths = (FILEPATHS *)Param1;
            printf ( "Extracted %s\n",pFilePaths->Target);
            lRetVal = NO_ERROR;
            break;

         case SPFILENOTIFY_NEEDNEWCABINET: // Unexpected.
            lRetVal = NO_ERROR;
            break;
      }

      return lRetVal;
   }

   void IterateCabinet(PTSTR pszCabFile)
   {
      LPVOID lpMsgBuf;

      if (  !SetupIterateCabinet(pszCabFile,
            0, (PSP_FILE_CALLBACK)CabinetCallback, 0) )
      {
         FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
                        FORMAT_MESSAGE_FROM_SYSTEM |
                        FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
                        GetLastError(), MAKELANGID(LANG_NEUTRAL,
                        SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );

         MessageBox( NULL,(LPTSTR) lpMsgBuf,
                     "SetupIterateCabinet() Error :",
                     MB_OK | MB_ICONEXCLAMATION | MB_TOPMOST);
      }
   }

REFERENCES

You can create cab files by using CabArc.exe in the Microsoft Cabinet SDK, which is available for download at the following Web site:

   http://www.microsoft.com/workshop/management/cab/cabdl.asp

Additional query words:
Keywords          : kbnokeyword
Platform          : WINDOWS
Issue type        : kbhowto

Last Reviewed: July 7, 1998