|
|
//***************************************************************************
//* Copyright (c) Microsoft Corporation 1995-1996. All rights reserved. *
//***************************************************************************
//* *
//* NTAPI.C - *
//* *
//***************************************************************************
//***************************************************************************
//* INCLUDE FILES *
//***************************************************************************
#include "ntapi.h"
#include <winnt.h>
#include "advpack.h"
#include "advpub.h"
#include "globals.h"
#include "resource.h"
UINT WINAPI AIFSetupQueueCallback(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2); UINT WINAPI AIFQuietSetupQueueCallback(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2); UINT WINAPI MyFileQueueCallback2( PVOID Context,UINT Notification,UINT_PTR parm1,UINT_PTR parm2 ); void MakeRootDir(LPSTR pszPath);
//***************************************************************************
//* GLOBAL VARIABLES *
//***************************************************************************
PFSetupDefaultQueueCallback pfSetupDefaultQueueCallback = NULL; PFSetupInstallFromInfSection pfSetupInstallFromInfSection = NULL; PFSetupOpenInfFile pfSetupOpenInfFile = NULL; PFSetupOpenAppendInfFile pfSetupOpenAppendInfFile = NULL; PFSetupCloseInfFile pfSetupCloseInfFile = NULL; PFSetupInitDefaultQueueCallbackEx pfSetupInitDefaultQueueCallbackEx = NULL; PFSetupTermDefaultQueueCallback pfSetupTermDefaultQueueCallback = NULL; PFSetupSetDirectoryId pfSetupSetDirectoryId = NULL; PFSetupGetLineText pfSetupGetLineText = NULL; PFSetupGetLineByIndex pfSetupGetLineByIndex = NULL; PFSetupFindFirstLine pfSetupFindFirstLine = NULL; PFSetupFindNextLine pfSetupFindNextLine = NULL; PFSetupOpenFileQueue pfSetupOpenFileQueue = NULL; PFSetupCloseFileQueue pfSetupCloseFileQueue = NULL; PFSetupQueueCopy pfSetupQueueCopy = NULL; PFSetupCommitFileQueue pfSetupCommitFileQueue = NULL; PFSetupGetStringField pfSetupGetStringField = NULL;
//***************************************************************************
//* *
//* NAME: *
//* *
//* SYNOPSIS: *
//* *
//* REQUIRES: *
//* *
//* RETURNS: *
//* *
//***************************************************************************
BOOL LoadSetupAPIFuncs( VOID ) { pfSetupGetStringField = (PFSetupGetStringField) GetProcAddress( ctx.hSetupLibrary, c_szSetupGetStringField ); pfSetupDefaultQueueCallback = (PFSetupDefaultQueueCallback) GetProcAddress( ctx.hSetupLibrary, c_szSetupDefaultQueueCallback ); pfSetupInstallFromInfSection = (PFSetupInstallFromInfSection) GetProcAddress( ctx.hSetupLibrary, c_szSetupInstallFromInfSection ); pfSetupOpenInfFile = (PFSetupOpenInfFile) GetProcAddress( ctx.hSetupLibrary, c_szSetupOpenInfFile ); pfSetupOpenAppendInfFile = (PFSetupOpenAppendInfFile) GetProcAddress( ctx.hSetupLibrary, c_szSetupOpenAppendInfFile ); pfSetupCloseInfFile = (PFSetupCloseInfFile) GetProcAddress( ctx.hSetupLibrary, c_szSetupCloseInfFile ); pfSetupInitDefaultQueueCallbackEx = (PFSetupInitDefaultQueueCallbackEx) GetProcAddress( ctx.hSetupLibrary, c_szSetupInitDefaultQueueCallbackEx ); pfSetupTermDefaultQueueCallback = (PFSetupTermDefaultQueueCallback) GetProcAddress( ctx.hSetupLibrary, c_szSetupTermDefaultQueueCallback ); pfSetupSetDirectoryId = (PFSetupSetDirectoryId) GetProcAddress( ctx.hSetupLibrary, c_szSetupSetDirectoryId ); pfSetupGetLineText = (PFSetupGetLineText) GetProcAddress( ctx.hSetupLibrary, c_szSetupGetLineText ); pfSetupGetLineByIndex = (PFSetupGetLineByIndex) GetProcAddress( ctx.hSetupLibrary, c_szSetupGetLineByIndex ); pfSetupFindFirstLine = (PFSetupFindFirstLine) GetProcAddress( ctx.hSetupLibrary, c_szSetupFindFirstLine ); pfSetupFindNextLine = (PFSetupFindNextLine) GetProcAddress( ctx.hSetupLibrary, c_szSetupFindNextLine ); pfSetupOpenFileQueue = (PFSetupOpenFileQueue) GetProcAddress( ctx.hSetupLibrary, c_szSetupOpenFileQueue ); pfSetupCloseFileQueue = (PFSetupCloseFileQueue) GetProcAddress( ctx.hSetupLibrary, c_szSetupCloseFileQueue ); pfSetupQueueCopy = (PFSetupQueueCopy) GetProcAddress( ctx.hSetupLibrary, c_szSetupQueueCopy ); pfSetupCommitFileQueue = (PFSetupCommitFileQueue) GetProcAddress( ctx.hSetupLibrary, c_szSetupCommitFileQueue );
if (pfSetupDefaultQueueCallback == NULL || pfSetupInstallFromInfSection == NULL || pfSetupOpenInfFile == NULL || pfSetupCloseInfFile == NULL || pfSetupInitDefaultQueueCallbackEx == NULL || pfSetupTermDefaultQueueCallback == NULL || pfSetupSetDirectoryId == NULL || pfSetupGetLineText == NULL || pfSetupGetLineByIndex == NULL || pfSetupFindFirstLine == NULL || pfSetupFindNextLine == NULL || pfSetupOpenFileQueue == NULL || pfSetupCloseFileQueue == NULL || pfSetupQueueCopy == NULL || pfSetupCommitFileQueue == NULL || pfSetupGetStringField == NULL ) { return FALSE; }
return TRUE; }
//***************************************************************************
//* *
//* NAME: InstallOnNT *
//* *
//* SYNOPSIS: This function will make all the calls to WinNT SUR's *
//* SETUPAPI.DLL to do the installation on NT SUR. *
//* *
//* REQUIRES: pszSection: Section to install *
//* pszSourceDir: Directory to CABs or expanded files *
//* *
//* RETURNS: *
//* *
//***************************************************************************
HRESULT InstallOnNT( PSTR pszSection, PSTR pszSourceDir ) { PVOID pContext = NULL; HRESULT hReturnCode = S_OK; HSPFILEQ hFileQueue = NULL; UINT uFlags;
// Install Files
// Setup Context data structure initialized for us for default UI provided by Setup API.
pContext = pfSetupInitDefaultQueueCallbackEx( NULL, (ctx.wQuietMode) ? INVALID_HANDLE_VALUE : NULL, 0, 0, NULL );
if ( pContext == NULL ) { hReturnCode = HRESULT_FROM_SETUPAPI(GetLastError()); goto done; }
if ( ! pfSetupInstallFromInfSection( NULL, ctx.hInf, pszSection, SPINST_FILES, NULL, pszSourceDir, SP_COPY_NEWER, MyFileQueueCallback2, pContext, NULL, NULL ) ) { hReturnCode = HRESULT_FROM_SETUPAPI(GetLastError()); pfSetupTermDefaultQueueCallback( pContext ); goto done; }
// Free Context Data structure
pfSetupTermDefaultQueueCallback( pContext );
uFlags = SPINST_REGISTRY | SPINST_INIFILES; if ( ctx.wOSVer >= _OSVER_WINNT50 ) uFlags = uFlags | SPINST_PROFILEITEMS;
// Install registry entries
if ( ! pfSetupInstallFromInfSection( NULL, ctx.hInf, pszSection, uFlags, HKEY_LOCAL_MACHINE, NULL, 0, NULL, NULL, NULL, NULL ) ) { hReturnCode = HRESULT_FROM_SETUPAPI(GetLastError()); goto done; }
done:
return hReturnCode; }
//***************************************************************************
//* *
//* NAME: MySetupOpenInfFile *
//* *
//* SYNOPSIS: This function will map to a function in setupapi.dll which *
//* will open the INF file. *
//* *
//* REQUIRES: pszInfFilename: *
//* *
//* RETURNS: DWORD: Return value - OK means successfull. *
//* *
//***************************************************************************
HRESULT MySetupOpenInfFile( PCSTR pszInfFilename ) { UINT line;
if ( ctx.hInf == NULL ) { ctx.hInf = pfSetupOpenInfFile( pszInfFilename, NULL, INF_STYLE_WIN4, NULL );
if ( ctx.hInf == NULL || ctx.hInf == INVALID_HANDLE_VALUE ) { ctx.hInf = NULL; return HRESULT_FROM_SETUPAPI(GetLastError()); }
// process LayoutFile line of [version] section if any
pfSetupOpenAppendInfFile( NULL, ctx.hInf, &line ); }
return S_OK; }
//***************************************************************************
//* *
//* NAME: MySetupCloseInfFile *
//* *
//* SYNOPSIS: This function will map to an API function in setupapi.dll. *
//* *
//* REQUIRES: *
//* *
//* RETURNS: VOID *
//* *
//***************************************************************************
VOID MySetupCloseInfFile( VOID ) { if ( ctx.hInf ) { pfSetupCloseInfFile( ctx.hInf ); ctx.hInf = NULL; } }
//***************************************************************************
//* *
//* NAME: MySetupSetDirectoryId *
//* *
//* SYNOPSIS: This function will map to a function in setupapi.dll to *
//* set the directory ID's that are used in our INF. *
//* *
//* REQUIRES: dwDirID: Numerical value used to define the DirID *
//* pszPath: DirID will point to this path. *
//* *
//* RETURNS: DWORD: Error value (OK if successfull) *
//* *
//***************************************************************************
HRESULT MySetupSetDirectoryId( DWORD dwDirID, PSTR pszPath ) { if ( ! pfSetupSetDirectoryId( ctx.hInf, dwDirID, pszPath ) ) { return HRESULT_FROM_SETUPAPI(GetLastError()); }
return S_OK; }
//***************************************************************************
//* *
//* NAME: MySetupGetLineText *
//* *
//* SYNOPSIS: *
//* *
//* REQUIRES: *
//* *
//* RETURNS: *
//* *
//***************************************************************************
HRESULT MySetupGetLineText( PCSTR pszSection, PCSTR pszKey, PSTR pszReturnBuffer, DWORD dwReturnBufferSize, PDWORD pdwRequiredSize ) { if ( ! pfSetupGetLineText( NULL, ctx.hInf, pszSection, pszKey, pszReturnBuffer, dwReturnBufferSize, pdwRequiredSize ) ) { return HRESULT_FROM_SETUPAPI(GetLastError()); }
return S_OK; }
//***************************************************************************
//* *
//* NAME: MySetupGetLineByIndex *
//* *
//* SYNOPSIS: *
//* *
//* REQUIRES: *
//* *
//* RETURNS: *
//* *
//***************************************************************************
HRESULT MySetupGetLineByIndex( PCSTR c_pszSection, DWORD dwIndex, PSTR pszBuffer, DWORD dwBufferSize, PDWORD pdwRequiredSize ) { HRESULT hReturnCode = S_OK; INFCONTEXT InfContext; DWORD i = 0;
if ( ! pfSetupFindFirstLine( ctx.hInf, c_pszSection, NULL, &InfContext ) ) { hReturnCode = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS); goto done; }
for ( i = 0; i < dwIndex; i += 1 ) { if ( !pfSetupFindNextLine( &InfContext, &InfContext ) ) { hReturnCode = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS); goto done; } }
#if 0
if ( ! pfSetupGetLineByIndex( ctx.hInf, c_pszSection, dwIndex, &InfContext ) ) { hReturnCode = HRESULT_FROM_SETUPAPI(GetLastError()); goto done; } #endif
if ( ! pfSetupGetLineText( &InfContext, NULL, NULL, NULL, pszBuffer, dwBufferSize, pdwRequiredSize ) ) { hReturnCode = HRESULT_FROM_SETUPAPI(GetLastError()); goto done; }
done:
return hReturnCode; }
//***************************************************************************
//* *
//* NAME: MySetupGetStringField *
//* *
//* SYNOPSIS: *
//* *
//* REQUIRES: *
//* *
//* RETURNS: *
//* *
//***************************************************************************
HRESULT MySetupGetStringField( PCSTR c_pszSection, DWORD dwLineIndex, DWORD dwFieldIndex, PSTR pszBuffer, DWORD dwBufferSize, PDWORD pdwRequiredSize ) { HRESULT hReturnCode = S_OK; INFCONTEXT InfContext; DWORD i = 0;
if ( !pfSetupFindFirstLine( ctx.hInf, c_pszSection, NULL, &InfContext ) ) { hReturnCode = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS); goto done; }
for ( i = 0; i < dwLineIndex; i += 1 ) { if ( !pfSetupFindNextLine( &InfContext, &InfContext ) ) { hReturnCode = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS); goto done; } }
if ( !pfSetupGetStringField( &InfContext, dwFieldIndex, pszBuffer, dwBufferSize, pdwRequiredSize ) ) { hReturnCode = HRESULT_FROM_SETUPAPI(GetLastError()); goto done; }
done:
return hReturnCode; }
HRESULT WINAPI AdvInstallFile(HWND hwnd, LPCSTR lpszSourceDir, LPCSTR lpszSourceFile, LPCSTR lpszDestDir, LPCSTR lpszDestFile, DWORD dwFlags, DWORD dwReserved) { HRESULT hr = E_FAIL; HSPFILEQ FileQueue; char szSrcDrv[MAX_PATH]; LPCSTR lpSrcPath; LPVOID lpContext; DWORD dwCopyFlags; DWORD dwRebootCheck;
if ( (lpszSourceDir == NULL) || (*lpszSourceDir == '\0') || (lpszSourceFile == NULL) || (*lpszSourceFile == '\0') || (lstrlen(lpszSourceDir) < 3) || (lpszDestDir == NULL) ) return E_INVALIDARG;
if (!SaveGlobalContext()) return hr;
ctx.hWnd = hwnd;
if ( !CheckOSVersion() ) { RestoreGlobalContext(); return HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION); } dwRebootCheck = InternalNeedRebootInit( ctx.wOSVer );
// LoadLibrary for setupapi.dll
ctx.hSetupLibrary = MyLoadLibrary( SETUPAPIDLL ); if ( ctx.hSetupLibrary == NULL ) { ErrorMsg1Param( NULL, IDS_ERR_LOAD_DLL, SETUPAPIDLL ); hr = HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND); goto Cleanup; } if ( ! LoadSetupAPIFuncs() ) { ErrorMsg( NULL, IDS_ERR_GET_PROC_ADDR ); hr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND); goto Cleanup; }
// SetupOpenFileQueue
FileQueue = pfSetupOpenFileQueue(); if (FileQueue == INVALID_HANDLE_VALUE) { ErrorMsg1Param( NULL, IDS_ERR_LOAD_DLL, c_szSetupOpenFileQueue ); hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto Cleanup; }
lstrcpy(szSrcDrv, lpszSourceDir); MakeRootDir(szSrcDrv); lpSrcPath = lpszSourceDir + lstrlen(szSrcDrv); // This will point to the first subdir.
dwCopyFlags = SP_COPY_SOURCE_ABSOLUTE | SP_COPY_IN_USE_NEEDS_REBOOT| SP_COPY_NEWER | SP_COPY_LANGUAGEAWARE;
if (dwFlags & AIF_FORCE_FILE_IN_USE) dwCopyFlags |= SP_COPY_FORCE_IN_USE;
if (dwFlags & AIF_NOVERSIONCHECK) dwCopyFlags &= ~SP_COPY_NEWER;
if (dwFlags & AIF_NOLANGUAGECHECK) dwCopyFlags &= ~SP_COPY_LANGUAGEAWARE;
if (dwFlags & AIF_NO_VERSION_DIALOG) dwCopyFlags |= SP_COPY_FORCE_NEWER;
if (dwFlags & AIF_REPLACEONLY) dwCopyFlags |= SP_COPY_REPLACEONLY;
if (dwFlags & AIF_NOOVERWRITE) dwCopyFlags |= SP_COPY_NOOVERWRITE;
if (dwFlags & AIF_NOSKIP) dwCopyFlags |= SP_COPY_NOSKIP;
if (dwFlags & AIF_WARNIFSKIP) dwCopyFlags |= SP_COPY_WARNIFSKIP;
if (pfSetupQueueCopy(FileQueue, szSrcDrv, lpSrcPath, lpszSourceFile, NULL, NULL, lpszDestDir, lpszDestFile, dwCopyFlags)) { lpContext = pfSetupInitDefaultQueueCallbackEx(hwnd, INVALID_HANDLE_VALUE, 0, 0, NULL); hr = S_OK;
//
// SetupCommitFileQueue
if (!pfSetupCommitFileQueue( hwnd, FileQueue, (dwFlags & AIF_QUIET)?AIFQuietSetupQueueCallback:AIFSetupQueueCallback, lpContext)) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); }
pfSetupTermDefaultQueueCallback(lpContext); } else hr = HRESULT_FROM_SETUPAPI(GetLastError());
// SetupCloseFileQueue
pfSetupCloseFileQueue(FileQueue);
if ( SUCCEEDED(hr) && InternalNeedReboot( dwRebootCheck, ctx.wOSVer ) ) { hr = ERROR_SUCCESS_REBOOT_REQUIRED; }
Cleanup:
RestoreGlobalContext();
return hr; }
// This callback will display error messages, but will not show any progress dialog
UINT WINAPI AIFSetupQueueCallback(PVOID Context, // context used by the default callback routine
UINT Notification, // queue notification
UINT_PTR Param1, // additional notification information
UINT_PTR Param2 // additional notification information
) { switch (Notification) { case SPFILENOTIFY_STARTQUEUE: case SPFILENOTIFY_ENDQUEUE: case SPFILENOTIFY_STARTSUBQUEUE: case SPFILENOTIFY_ENDSUBQUEUE:
case SPFILENOTIFY_STARTRENAME: case SPFILENOTIFY_ENDRENAME: case SPFILENOTIFY_STARTDELETE: case SPFILENOTIFY_ENDDELETE: case SPFILENOTIFY_STARTCOPY: case SPFILENOTIFY_ENDCOPY: return FILEOP_DOIT;
default: return (pfSetupDefaultQueueCallback(Context, Notification, Param1, Param2)); } }
// This callback will not display any dialog
UINT WINAPI AIFQuietSetupQueueCallback(PVOID Context, // context used by the default callback routine
UINT Notification, // queue notification
UINT_PTR Param1, // additional notification information
UINT_PTR Param2 // additional notification information
) { return FILEOP_DOIT; }
UINT WINAPI MyFileQueueCallback2( PVOID Context,UINT Notification,UINT_PTR parm1,UINT_PTR parm2 ) { switch(Notification) { case SPFILENOTIFY_NEEDMEDIA: { CHAR szDrv[5]; PSOURCE_MEDIA psrcMed;
psrcMed = (PSOURCE_MEDIA)parm1;
if ( lstrlen( psrcMed->SourcePath ) > 3 ) { lstrcpyn( szDrv, psrcMed->SourcePath, 4 );
if ( (szDrv[1] == ':') && (GetDriveType( szDrv ) == DRIVE_REMOVABLE) ) { CHAR szFile[MAX_PATH];
lstrcpy( szFile, psrcMed->SourcePath );
if ( psrcMed->Tagfile && *psrcMed->Tagfile ) AddPath( szFile, psrcMed->Tagfile ); else AddPath( szFile, psrcMed->SourceFile );
if ( FileExists( szFile ) ) { lstrcpy( (PSTR)parm2, psrcMed->SourcePath ); return ( FILEOP_NEWPATH ); } }
} }
default: return ( pfSetupDefaultQueueCallback( Context, Notification, parm1, parm2 ) ); } }
void MakeRootDir(LPSTR pszPath) { LPSTR pTmp; if (pszPath[1] == ':') pszPath[3] = '\0'; else if ((pszPath[0] == '\\') && (pszPath[1]=='\\')) { pTmp = &pszPath[2]; // Find the sever share separation
while ((*pTmp) && (*pTmp != '\\')) pTmp = CharNext(pTmp); if (*pTmp) { pTmp = CharNext(pTmp); // Find the end of the share
while ((*pTmp) && (*pTmp != '\\')) pTmp = CharNext(pTmp); if (*pTmp == '\\') { pTmp = CharNext(pTmp); *pTmp ='\0'; } } } }
|