Ejemplo n.º 1
0
VOID
EnumerateDrivers(PVOID Context, HDEVINFO hList, PSP_DEVINFO_DATA pInfoData)
{
    HSPFILEQ hQueue;
    SP_DEVINSTALL_PARAMS DeviceInstallParams = {0};
    SP_DRVINFO_DATA DriverInfoData;
    DWORD Result;

    DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
    if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams))
        return;

    DeviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
    if (!SetupDiSetDeviceInstallParams(hList, pInfoData, &DeviceInstallParams))
        return;

    if (!SetupDiBuildDriverInfoList(hList, pInfoData, SPDIT_CLASSDRIVER))
        return;

    DriverInfoData.cbSize = sizeof(DriverInfoData);
    if (!SetupDiEnumDriverInfoW(hList, pInfoData, SPDIT_CLASSDRIVER, 0, &DriverInfoData))
        return;

    DriverInfoData.cbSize = sizeof(DriverInfoData);
    if (!SetupDiSetSelectedDriverW(hList, pInfoData, &DriverInfoData))
         return;

    hQueue = SetupOpenFileQueue();
    if (hQueue == (HSPFILEQ)INVALID_HANDLE_VALUE)
        return;

    DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
    if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams))
    {
        SetupCloseFileQueue(hQueue);
        return;
    }

    DeviceInstallParams.FileQueue = hQueue;
    DeviceInstallParams.Flags |= DI_NOVCP;

    if (!SetupDiSetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams))
    {
        SetupCloseFileQueue(hQueue);
        return;
    }

    if(!SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hList, pInfoData))
    {
        SetupCloseFileQueue(hQueue);
        return;
    }


    /* enumerate the driver files */
    SetupScanFileQueueW(hQueue, SPQ_SCAN_USE_CALLBACK, NULL, DriverFilesCallback, Context, &Result);
    SetupCloseFileQueue(hQueue);
}
Ejemplo n.º 2
0
BOOL InfFile::UninstallFiles(const char *pFilesSection) const
{
  if (!pPath)
    return FALSE;

  int res;
  HINF hInf;

  do {
    res = IDCONTINUE;

    UINT errLine;
    hInf = SetupOpenInfFile(pPath, NULL, INF_STYLE_WIN4, &errLine);

    if (hInf == INVALID_HANDLE_VALUE)
      res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupOpenInfFile(%s) on line %u", pPath, errLine);
  } while (res == IDTRYAGAIN);

  if (res != IDCONTINUE)
    return FALSE;

  do {
    res = IDCONTINUE;

    HSPFILEQ hFileQueue = SetupOpenFileQueue();

    if (hFileQueue != INVALID_HANDLE_VALUE) {
      if (SetupQueueDeleteSection(hFileQueue, hInf, NULL, pFilesSection)) {
        PVOID pContext = SetupInitDefaultQueueCallback(NULL);

        if (pContext) {
          if(!SetupCommitFileQueue(NULL, hFileQueue, FileCallback, pContext))
            res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupCommitFileQueue()");

          SetupTermDefaultQueueCallback(pContext);
        } else {
          res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupInitDefaultQueueCallback()");
        }
      } else {
        res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupQueueDeleteSection(%s)", pFilesSection);
      }

      SetupCloseFileQueue(hFileQueue);
    } else {
      res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupOpenFileQueue()");
    }
  } while (res == IDTRYAGAIN);

  SetupCloseInfFile(hInf);

  if (res != IDCONTINUE)
    return FALSE;

  return TRUE;
}
Ejemplo n.º 3
0
/***********************************************************************
 *      AdvInstallFileW (ADVPACK.@)
 *
 * Copies a file from the source to a destination.
 *
 * PARAMS
 *   hwnd           [I] Handle to the window used for messages.
 *   lpszSourceDir  [I] Source directory.
 *   lpszSourceFile [I] Source filename.
 *   lpszDestDir    [I] Destination directory.
 *   lpszDestFile   [I] Optional destination filename.
 *   dwFlags        [I] See advpub.h.
 *   dwReserved     [I] Reserved.  Must be 0.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * NOTES
 *   If lpszDestFile is NULL, the destination filename is the same as
 *   lpszSourceFIle.
 */
HRESULT WINAPI AdvInstallFileW(HWND hwnd, LPCWSTR lpszSourceDir, LPCWSTR lpszSourceFile,
                               LPCWSTR lpszDestDir, LPCWSTR lpszDestFile,
                               DWORD dwFlags, DWORD dwReserved)
{
    PSP_FILE_CALLBACK_W pFileCallback;
    LPWSTR szDestFilename;
    LPCWSTR szPath;
    WCHAR szRootPath[ROOT_LENGTH];
    DWORD dwLen, dwLastError;
    HSPFILEQ fileQueue;
    PVOID pContext;

    TRACE("(%p, %s, %s, %s, %s, %d, %d)\n", hwnd, debugstr_w(lpszSourceDir),
          debugstr_w(lpszSourceFile), debugstr_w(lpszDestDir),
          debugstr_w(lpszDestFile), dwFlags, dwReserved);

    if (!lpszSourceDir || !lpszSourceFile || !lpszDestDir)
        return E_INVALIDARG;
        
    fileQueue = SetupOpenFileQueue();
    if (fileQueue == INVALID_HANDLE_VALUE)
        return HRESULT_FROM_WIN32(GetLastError());

    pContext = NULL;
    dwLastError = ERROR_SUCCESS;

    lstrcpynW(szRootPath, lpszSourceDir, ROOT_LENGTH);
    szPath = lpszSourceDir + ROOT_LENGTH;

    /* use lpszSourceFile as destination filename if lpszDestFile is NULL */
    if (lpszDestFile)
    {
        dwLen = lstrlenW(lpszDestFile);
        szDestFilename = HeapAlloc(GetProcessHeap(), 0, (dwLen+1) * sizeof(WCHAR));
        lstrcpyW(szDestFilename, lpszDestFile);
    }
    else
    {
        dwLen = lstrlenW(lpszSourceFile);
        szDestFilename = HeapAlloc(GetProcessHeap(), 0, (dwLen+1) * sizeof(WCHAR));
        lstrcpyW(szDestFilename, lpszSourceFile);
    }

    /* add the file copy operation to the setup queue */
    if (!SetupQueueCopyW(fileQueue, szRootPath, szPath, lpszSourceFile, NULL,
                         NULL, lpszDestDir, szDestFilename, dwFlags))
    {
        dwLastError = GetLastError();
        goto done;
    }

    pContext = SetupInitDefaultQueueCallbackEx(hwnd, INVALID_HANDLE_VALUE,
                                               0, 0, NULL);
    if (!pContext)
    {
        dwLastError = GetLastError();
        goto done;
    }

    /* don't output anything for AIF_QUIET */
    if (dwFlags & AIF_QUIET)
        pFileCallback = pQuietQueueCallback;
    else
        pFileCallback = pQueueCallback;

    /* perform the file copy */
    if (!SetupCommitFileQueueW(hwnd, fileQueue, pFileCallback, pContext))
    {
        dwLastError = GetLastError();
        goto done;
    }

done:
    SetupTermDefaultQueueCallback(pContext);
    SetupCloseFileQueue(fileQueue);
    
    HeapFree(GetProcessHeap(), 0, szDestFilename);
    
    return HRESULT_FROM_WIN32(dwLastError);
}
Ejemplo n.º 4
0
HRESULT
xDiEnumDriverFiles(
	__in_opt HWND Owner,
	__in LPCWSTR OemInfFullPath,
	__in DWORD Flags,
	__in XDI_ENUM_DRIVER_FILE_CALLBACK EnumCallback,
	__in LPVOID EnumContext)
{
	HRESULT hr;
	BOOL success;

	WCHAR infFullPath[MAX_PATH];

	DWORD n = GetFullPathNameW(OemInfFullPath, MAX_PATH, infFullPath, NULL);
	if (0 == n)
	{
		hr = HRESULT_FROM_WIN32(GetLastError());
		hr = (SUCCEEDED(hr)) ? E_FAIL : hr;
		goto error0;
	}

	HDEVINFO devInfoSet = SetupDiCreateDeviceInfoList(NULL, Owner);
	if (INVALID_HANDLE_VALUE == devInfoSet)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error0;
	}

	SP_DEVINFO_DATA devInfoData = { sizeof(SP_DEVINFO_DATA) };

	success = SetupDiCreateDeviceInfoW(
		devInfoSet,
		L"XDI_Temporary_Enumerator",
		&GUID_NULL,
		NULL,
		NULL,
		DICD_GENERATE_ID,
		&devInfoData);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error1;
	}

	HSPFILEQ fileQueueHandle = SetupOpenFileQueue();

	if (INVALID_HANDLE_VALUE == fileQueueHandle)
	{
		// Error from SetupOpenFileQueue is only from out-of-memory situation
		// without the last error set
		hr = E_OUTOFMEMORY;
		goto error2;
	}

	SP_DEVINSTALL_PARAMS devInstallParams = {sizeof(SP_DEVINSTALL_PARAMS)};

	success = SetupDiGetDeviceInstallParamsW(
		devInfoSet,
		&devInfoData,
		&devInstallParams);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error3;
	}

	//
	// Specify the search path
	//

	hr = StringCchCopyW(
		devInstallParams.DriverPath,
		MAX_PATH,
		infFullPath);

	if (FAILED(hr))
	{
		goto error3;
	}

	devInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
	devInstallParams.FileQueue = fileQueueHandle;
	devInstallParams.Flags |= DI_NOVCP;
	devInstallParams.Flags |= DI_ENUMSINGLEINF;

	success = SetupDiSetDeviceInstallParamsW(
		devInfoSet,
		&devInfoData,
		&devInstallParams);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error3;
	}

	//
	// use DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE if possible 
	// to ensure we look at duplicate nodes (which is broken in itself)
	//
#ifndef DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE
#define DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE  0x08000000L  // Don't remove identical driver nodes from the class list
#endif

	if (xDipWindowsXPOrLater())
	{
		devInstallParams.FlagsEx |= DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE;

		success = SetupDiSetDeviceInstallParamsW(
			devInfoSet,
			&devInfoData,
			&devInstallParams);

		if (!success)
		{
			devInstallParams.FlagsEx &= ~DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE;
		}
	}

	//
	// Build a class driver list with every driver
	//

	success = SetupDiBuildDriverInfoList(
		devInfoSet,
		&devInfoData,
		SPDIT_CLASSDRIVER);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error3;
	}

	SP_DRVINFO_DATA drvInfoData = { sizeof(SP_DRVINFO_DATA) };

	for (DWORD index = 0; ; ++index)
	{
		success = SetupDiEnumDriverInfoW(
			devInfoSet, 
			&devInfoData, 
			SPDIT_CLASSDRIVER, 
			index, 
			&drvInfoData);

		if (!success)
		{
			break;
		}

		SP_DRVINFO_DETAIL_DATA drvInfoDetail = { sizeof(SP_DRVINFO_DETAIL_DATA) };

		success = SetupDiGetDriverInfoDetailW(
			devInfoSet, 
			&devInfoData,
			&drvInfoData,
			&drvInfoDetail,
			sizeof(SP_DRVINFO_DETAIL_DATA),
			NULL);

		if (!success && ERROR_INSUFFICIENT_BUFFER != GetLastError())
		{
			hr = HRESULT_FROM_SETUPAPI(GetLastError());
			goto error4;
		}

		success = SetupDiSetSelectedDriverW(
			devInfoSet,
			&devInfoData,
			&drvInfoData);

		if (!success)
		{
			hr = HRESULT_FROM_SETUPAPI(GetLastError());
			goto error4;
		}

		if (Flags & XDI_EDF_NO_CLASS_INSTALLER)
		{
			success = SetupDiInstallDriverFiles(
				devInfoSet, &devInfoData);

			if (!success)
			{
				hr = HRESULT_FROM_SETUPAPI(GetLastError());
				goto error4;
			}
		}
		else
		{
			success = SetupDiCallClassInstaller(
				DIF_INSTALLDEVICEFILES, devInfoSet, &devInfoData);

			if (!success)
			{
				hr = HRESULT_FROM_SETUPAPI(GetLastError());
				goto error4;
			}
		}
	}

	//
	// SPQ_SCAN_USE_CALLBACK_EX checks the digital signature of the file
	// We do not want to check the signature here.
	//
	// SPQ_SCAN_FILE_PRESENCE avoids checking the digital signature of the file
	// in Windows XP or later. (Not in Windows 2000) when used 
	// with SPQ_SCAN_USE_CALLBACK_EX
	//

	XDI_ENUM_FQS_CONTEXT fqsContext = {0};
	fqsContext.Callback = EnumCallback;
	fqsContext.CallbackContext = EnumContext;

	DWORD scanResult;
	success = SetupScanFileQueueW(
		fileQueueHandle, 
		SPQ_SCAN_USE_CALLBACK,
		// SPQ_SCAN_USE_CALLBACKEX | SPQ_SCAN_FILE_PRESENCE,
		Owner,
		xDipEnumFileQueueScanCallback,
		&fqsContext,
		&scanResult);

	if (!success)
	{
		//
		// SetupScanFileQueue may fail using SPQ_SCAN_FILE_PRESENSE flag
		// Try again without SPQ_SCAN_FILE_PRESENSE
		// (when using SPQ_SCAN_USE_CALLBACKEX)
		//
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error4;
	}

	hr = S_OK;

#pragma warning(disable: 4533) // to use goto in cpp

error4:

	SetupDiDestroyDriverInfoList(
		devInfoSet, &devInfoData, SPDIT_CLASSDRIVER);

error3:

	SetupCloseFileQueue(fileQueueHandle);

error2:

	SetupDiDeleteDeviceInfo(devInfoSet, &devInfoData);

error1:

	SetupDiDestroyDeviceInfoList(devInfoSet);

error0:

#pragma warning(default: 4533)

	return hr;
}
Ejemplo n.º 5
0
BOOL DumpDeviceDriverFiles(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo)
/*++

Routine Description:

    Dump information about what files were installed for driver package
    <tab>Installed using OEM123.INF section [abc.NT]
    <tab><tab>file...

Arguments:

    Devs    )_ uniquely identify device
    DevInfo )

Return Value:

    none

--*/
{
    //
    // do this by 'searching' for the current driver
    // mimmicing a copy-only install to our own file queue
    // and then parsing that file queue
    //
    SP_DEVINSTALL_PARAMS deviceInstallParams;
    SP_DRVINFO_DATA driverInfoData;
    SP_DRVINFO_DETAIL_DATA driverInfoDetail;
    HSPFILEQ queueHandle = INVALID_HANDLE_VALUE;
    DWORD count;
    DWORD scanResult;
    BOOL success = FALSE;

    ZeroMemory(&driverInfoData,sizeof(driverInfoData));
    driverInfoData.cbSize = sizeof(driverInfoData);

    if(!FindCurrentDriver(Devs,DevInfo,&driverInfoData)) {
        Padding(1);
        FormatToStream(stdout, MSG_DUMP_NO_DRIVER);
        return FALSE;
    }

    //
    // get useful driver information
    //
    driverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
    if(!SetupDiGetDriverInfoDetail(Devs,DevInfo,&driverInfoData,&driverInfoDetail,sizeof(SP_DRVINFO_DETAIL_DATA),NULL) &&
       GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        //
        // no information about driver or section
        //
        goto final;
    }
    if(!driverInfoDetail.InfFileName[0] || !driverInfoDetail.SectionName[0]) {
        goto final;
    }

    //
    // pretend to do the file-copy part of a driver install
    // to determine what files are used
    // the specified driver must be selected as the active driver
    //
    if(!SetupDiSetSelectedDriver(Devs, DevInfo, &driverInfoData)) {
        goto final;
    }

    //
    // create a file queue so we can look at this queue later
    //
    queueHandle = SetupOpenFileQueue();

    if ( queueHandle == (HSPFILEQ)INVALID_HANDLE_VALUE ) {
        goto final;
    }

    //
    // modify flags to indicate we're providing our own queue
    //
    ZeroMemory(&deviceInstallParams, sizeof(deviceInstallParams));
    deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
    if ( !SetupDiGetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams) ) {
        goto final;
    }

    //
    // we want to add the files to the file queue, not install them!
    //
    deviceInstallParams.FileQueue = queueHandle;
    deviceInstallParams.Flags |= DI_NOVCP;

    if ( !SetupDiSetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams) ) {
        goto final;
    }

    //
    // now fill queue with files that are to be installed
    // this involves all class/co-installers
    //
    if ( !SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, Devs, DevInfo) ) {
        goto final;
    }

    //
    // we now have a list of delete/rename/copy files
    // iterate the copy queue twice - 1st time to get # of files
    // 2nd time to get files
    // (WinXP has API to get # of files, but we want this to work
    // on Win2k too)
    //

    count = 0;
    scanResult = 0;
    //
    // call once to count
    //
    SetupScanFileQueue(queueHandle,SPQ_SCAN_USE_CALLBACK,NULL,DumpDeviceDriversCallback,&count,&scanResult);
    Padding(1);
    FormatToStream(stdout, count ? MSG_DUMP_DRIVER_FILES : MSG_DUMP_NO_DRIVER_FILES, count, driverInfoDetail.InfFileName, driverInfoDetail.SectionName);
    //
    // call again to dump the files
    //
    SetupScanFileQueue(queueHandle,SPQ_SCAN_USE_CALLBACK,NULL,DumpDeviceDriversCallback,NULL,&scanResult);

    success = TRUE;

final:
Ejemplo n.º 6
0
int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
    if (!InitializeOptions(lpCmdLine))
    {
        if (!OptionSilent)
        {
            MessageBox(NULL, "Please specify the correct parameters:\r\n" \
                       "/path <Full path to the INF>\r\n" \
                       "/path:relative <Relative path to the INF from the current directory>\r\n" \
                       "/ddinstall <DDInstall section name to be processed>\r\n" \
                       "/os <Expected OS version in the form of x.y where x is MajorVersion, y is Minor version, ie 5.0 for Windows 2000>\r\n" \
                       "/buildnumber <Expected OS build number, ie 2195 for Windows 2000>\r\n" \
                       "/sp <Expected OS service pack number>\r\n",
                       "Pre-Installer",
                       MB_OK);

        }

        return ERR_FAIL;
    }

    if ((OptionOsVersionCheck) || (OptionOsBuildNumberCheck) || (OptionOsServicePackCheck))
    {
        OSVERSIONINFO OsVersionInfo;
        OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

        if (GetVersionEx(&OsVersionInfo))
        {
            if (OptionOsVersionCheck)
            {
                CHAR Version[32];

                sprintf(Version, "%d.%d", OsVersionInfo.dwMajorVersion, OsVersionInfo.dwMinorVersion);

                if (_stricmp(Version, ExpectedOsVersion))
                {
                    if (!OptionSilent)
                    {
                        CHAR ErrorMsg[256];
                        sprintf(ErrorMsg, "OS version %s doesn't match the expected %s", Version, ExpectedOsVersion);

                        MessageBox(NULL, ErrorMsg, "Pre-Installer", MB_OK);
                    }

                    return ERR_FAIL;
                }
            }

            if (OptionOsBuildNumberCheck)
            {
                if (OsVersionInfo.dwBuildNumber != ExpectedOsBuildNumber)
                {
                    if (!OptionSilent)
                    {
                        CHAR ErrorMsg[256];
                        sprintf(ErrorMsg, "OS build number %d doesn't match the expected %d", OsVersionInfo.dwBuildNumber, ExpectedOsBuildNumber);

                        MessageBox(NULL, ErrorMsg, "Pre-Installer", MB_OK);
                    }

                    return ERR_FAIL;
                }
            }

            if (OptionOsServicePackCheck)
            {
                CHAR ServicePack[32];

                sprintf(ServicePack, "Service Pack %d", ExpectedOsServicePack);

                if (_stricmp(OsVersionInfo.szCSDVersion, ServicePack))
                {
                    if (!OptionSilent)
                    {
                        CHAR ErrorMsg[256];
                        sprintf(ErrorMsg, "OS %s doesn't match the expected %s", OsVersionInfo.szCSDVersion, ServicePack);

                        MessageBox(NULL, ErrorMsg, "Pre-Installer", MB_OK);
                    }

                    return ERR_FAIL;
                }
            }
        }
        else
        {
            return ERR_FAIL;
        }
    }

    HINF InfHandle = SetupOpenInfFile(InfPath, NULL, INF_STYLE_WIN4 , NULL);	// Get INF Handle

    if (InfHandle != INVALID_HANDLE_VALUE)
    {
        HSPFILEQ QueueHandle = SetupOpenFileQueue();

        if (QueueHandle != INVALID_HANDLE_VALUE)
        {
            SetupInstallFilesFromInfSection(InfHandle, NULL, QueueHandle, DDInstallSection, NULL, SP_COPY_FORCE_NEWER);
            //Copies the files

            PVOID Context = SetupInitDefaultQueueCallback(NULL);

            if (Context)
            {
                SetupCommitFileQueue(NULL, QueueHandle, FileCallback, Context);

                SetupTermDefaultQueueCallback(Context);
            }

            SetupCloseFileQueue(QueueHandle);
        }

        // Do not do the following as we do not want to install the drivers yet. When the device is turned on,
        // Windows PnP will take care of the rest of the installation process.
#if 0
        CHAR DDInstallServicesSection[MAX_PATH];

        strcpy(DDInstallServicesSection, DDInstallSection);
        strcat(DDInstallServicesSection, ".Services");

        SetupInstallServicesFromInfSection(InfHandle, DDInstallServicesSection, SPSVCINST_TAGTOFRONT);

        HKEY RegKey = SetupDiOpenClassRegKey((LPGUID)&CLSID_MEDIA, KEY_ALL_ACCESS);

        if (RegKey != INVALID_HANDLE_VALUE)
        {
            SetupInstallFromInfSection(NULL, InfHandle, DDInstallSection, SPINST_REGISTRY, RegKey, NULL, NULL,
                                       NULL, NULL, NULL, NULL);		// Does the AddReg, Del Reg Stuff

            RegCloseKey(RegKey);
        }
#endif // 0

        SetupCloseInfFile(InfHandle);
    }

    if (SetupCopyOEMInf(InfPath, NULL, SPOST_PATH, NULL, NULL ,0, NULL, NULL))
    {
        return SUCCESS;
    }
    else
    {
        DWORD err = GetLastError();

        return ERR_FAIL;
    }
}