|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
inf.c
Abstract:
Miscellaneous routines for the INF File Operation
Author:
Xiaofeng Zang (xiaoz) 17-Sep-2001 Created
Revision History:
<alias> <date> <comments>
--*/
#include "StdAfx.h"
#include "clmt.h"
HRESULT RegistryRename(HINF hInf, LPTSTR lpszSection,HKEY hKeyRoot,LPTSTR lpszUser); HRESULT FolderMove(HINF hInf, LPTSTR lpszSection,BOOL bAnalyze); HRESULT ChangeServiceStartupType(LPCTSTR, DWORD, DWORD);
HRESULT RegistryRename(HINF hInf, LPTSTR lpszSection,HKEY hKeyRoot,LPTSTR lpszUser) { UINT LineCount,LineNo; INFCONTEXT InfContext; DWORD dwStrType; LPTSTR pSubKeyPath; HKEY hKey; TCHAR szRenameType[MAX_PATH],szStringType[MAX_PATH]; DWORD dwRenameType,dwStringType; DWORD cchMaxOldKeyPathLength = 0; DWORD cchMaxNewKeyPathLength = 0; DWORD cchMaxOldNameLength = 0; DWORD cchMaxNewNameLength = 0; DWORD cchMaxOldDataLength = 0; DWORD cchMaxNewDataLength = 0; DWORD dwAttrib = 0; LPTSTR lpszOldKey,lpszNewKey,lpszOldName,lpszNewName,lpszOldValue,lpszNewValue; HRESULT hr; LONG lstatus;
lpszOldKey = lpszNewKey = lpszOldName = lpszNewName = lpszOldValue = lpszNewValue = NULL; LineCount = (UINT)SetupGetLineCount(hInf,lpszSection); if ((LONG)LineCount < 0) { hr = S_FALSE; DPF(INFwar ,TEXT("section name %s is empty failed !"),lpszSection); goto Cleanup; } for (LineNo = 0; LineNo < LineCount; LineNo++) { DWORD cchTmpOldKeyPathLength,cchTmpNewKeyPathLength ,cchTmpOldNameLength , cchTmpNewNameLength,cchTmpOldDataLength,cchTmpNewDataLength;
if (!SetupGetLineByIndex(hInf,lpszSection,LineNo,&InfContext)) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSection); continue; } if (!SetupGetStringField(&InfContext,1,szRenameType,MAX_PATH,NULL)) { DPF(INFwar ,TEXT("get [%s] 's line %n 's Field 0 failed !"),lpszSection, LineNo); continue; } cchTmpOldKeyPathLength = cchTmpNewKeyPathLength = cchTmpOldNameLength = cchTmpNewNameLength = cchTmpOldDataLength = cchTmpNewDataLength = 0; dwRenameType = _tstoi(szRenameType); switch (dwRenameType) { case TYPE_VALUE_RENAME: if (!SetupGetStringField(&InfContext,2,szStringType,MAX_PATH,NULL) || !SetupGetStringField(&InfContext,3,NULL,0,&cchTmpOldKeyPathLength) || !SetupGetStringField(&InfContext,4,NULL,0,&cchTmpOldNameLength) || ! SetupGetStringField(&InfContext,5,NULL,0,&cchTmpOldDataLength) || ! SetupGetStringField(&InfContext,6,NULL,0,&cchTmpNewDataLength)) { DPF(INFerr ,TEXT("get [%s] 's line %d 's Field 2,3,4,5,6 failed !"),lpszSection ,InfContext.Line); hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); goto Cleanup; } break; case TYPE_VALUENAME_RENAME: if (!SetupGetStringField(&InfContext,2,NULL,0,&cchTmpOldKeyPathLength) || !SetupGetStringField(&InfContext,3,NULL,0,&cchTmpOldNameLength) || ! SetupGetStringField(&InfContext,4,NULL,0,&cchTmpNewNameLength)) { DPF(INFerr ,TEXT("get [%s] 's line %d 's Field ,3,4,5 failed !"),lpszSection ,InfContext.Line); hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); goto Cleanup; } break; case TYPE_KEY_RENAME: if (!SetupGetStringField(&InfContext,2,NULL,0,&cchTmpOldKeyPathLength) || !SetupGetStringField(&InfContext,3,NULL,0,&cchTmpNewKeyPathLength)) { DPF(INFerr ,TEXT("get [%s] 's line %d 's Field ,3,4 failed !"),lpszSection ,InfContext.Line); hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); goto Cleanup; } break; } cchMaxOldKeyPathLength = max(cchTmpOldKeyPathLength,cchMaxOldKeyPathLength); cchMaxNewKeyPathLength = max(cchTmpNewKeyPathLength,cchMaxNewKeyPathLength); cchMaxOldNameLength = max(cchTmpOldNameLength,cchMaxOldNameLength); cchMaxNewNameLength = max(cchTmpNewNameLength,cchMaxNewNameLength); cchMaxOldDataLength = max(cchTmpOldDataLength,cchMaxOldDataLength); cchMaxNewDataLength = max(cchTmpNewDataLength,cchMaxNewDataLength); } if (cchMaxOldKeyPathLength) { if (!(lpszOldKey = malloc(++cchMaxOldKeyPathLength * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } } if (cchMaxNewKeyPathLength) { if (!(lpszNewKey = malloc(++cchMaxNewKeyPathLength * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } } if (cchMaxOldNameLength) { if (!(lpszOldName = malloc(++cchMaxOldNameLength * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } } if (cchMaxNewNameLength) { if (!(lpszNewName = malloc(++cchMaxNewNameLength * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } } if (cchMaxOldDataLength) { if (!(lpszOldValue = malloc(++cchMaxOldDataLength * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } } if (cchMaxNewDataLength) { if (!(lpszNewValue = malloc(++cchMaxNewDataLength * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } } for (LineNo = 0; LineNo < LineCount; LineNo++) { if (!SetupGetLineByIndex(hInf,lpszSection,LineNo,&InfContext)) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSection); continue; } if (!SetupGetStringField(&InfContext,1,szRenameType,MAX_PATH,NULL)) { DPF(INFwar ,TEXT("get [%s] 's line %n 's Field 0 failed !"),lpszSection, LineNo); continue; } dwRenameType = _tstoi(szRenameType); switch (dwRenameType) { case TYPE_VALUE_RENAME: if (!SetupGetStringField(&InfContext,2,szStringType,MAX_PATH,NULL) || !SetupGetStringField(&InfContext,3,lpszOldKey,cchMaxOldKeyPathLength,NULL) || ! SetupGetStringField(&InfContext,4,lpszOldName,cchMaxOldNameLength,NULL) || ! SetupGetStringField(&InfContext,5,lpszOldValue,cchMaxOldDataLength,NULL) || ! SetupGetStringField(&InfContext,6,lpszNewValue ,cchMaxNewDataLength,NULL)) { DPF(INFerr ,TEXT("get [%s] 's line %d 's Field ,3,4,5 failed !"),lpszSection ,InfContext.Line); hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); goto Cleanup; } if (!Str2KeyPath(lpszOldKey,&hKey,&pSubKeyPath)) { DPF(INFerr ,TEXT("format errorin line %d: %s !"),LineNo,lpszOldKey); hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); goto Cleanup; } if (hKeyRoot) { hKey = hKeyRoot; } dwStringType = _tstoi(szStringType); lstatus = RegResetValue(hKey, pSubKeyPath,lpszOldName,dwStringType,lpszOldValue,lpszOldValue, 0, NULL); if (lstatus == ERROR_SUCCESS) { hr = AddRegValueRename(pSubKeyPath,lpszOldName,NULL,lpszOldValue,lpszNewValue,dwStringType,dwAttrib,lpszUser); //Add error checking here
} break; case TYPE_VALUENAME_RENAME: break; case TYPE_KEY_RENAME: break; } }
Cleanup: FreePointer(lpszOldKey); FreePointer(lpszNewKey); FreePointer(lpszOldName); FreePointer(lpszNewName); FreePointer(lpszOldValue); FreePointer(lpszNewValue); return hr; }
HRESULT FolderMove(HINF hInf, LPTSTR lpszSection,BOOL bAnalyze) { LPTSTR lpszOldFolder = NULL,lpszNewFolder = NULL,lpExcludeFileList = NULL; DWORD cchMaxOldFolderSize = 0,cchMaxNewFolderSize = 0,cchMaxExcludeFileListSize = 0; HRESULT hr; UINT LineCount,LineNo; INFCONTEXT InfContext; TCHAR szType[MAX_PATH]; DWORD dwType;
if( (hInf == INVALID_HANDLE_VALUE) || (!lpszSection) ) { hr = E_INVALIDARG; goto Cleanup; }
LineCount = (UINT)SetupGetLineCount(hInf,lpszSection); if ((LONG)LineCount < 0) { hr = S_FALSE; DPF(INFwar ,TEXT("section name %s is empty failed !"),lpszSection); goto Cleanup; } for (LineNo = 0; LineNo < LineCount; LineNo++) { DWORD cchTmpOldFolderSize = 0,cchTmpNewFolderSize = 0,cchTmpExcludeFileListSize = 0; if (!SetupGetLineByIndex(hInf,lpszSection,LineNo,&InfContext)) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSection); continue; } if (!SetupGetStringField(&InfContext,1,szType,MAX_PATH,NULL)) { DPF(INFwar ,TEXT("get [%s] 's line %d 's Field 0 failed !"),lpszSection, LineNo); continue; } dwType = _tstoi(szType); switch (dwType) { case TYPE_SFPFILE_MOVE: case TYPE_FILE_MOVE: case TYPE_DIR_MOVE: if (!SetupGetStringField(&InfContext,2,NULL,0,&cchTmpOldFolderSize) || ! SetupGetStringField(&InfContext,3,NULL,0,&cchTmpNewFolderSize)) { hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); DPF(INFerr ,TEXT("get [%s] 's line %d 's Field 2,3failed !"),lpszSection ,LineNo); goto Cleanup; } if (TYPE_DIR_MOVE == dwType) { BOOL bTmp; bTmp = SetupGetMultiSzField(&InfContext,4,NULL,0,&cchTmpExcludeFileListSize); if (!( bTmp && (cchTmpExcludeFileListSize >= sizeof(TCHAR)))) { cchTmpExcludeFileListSize = 0; } } break; default: DPF(INFerr ,TEXT(" [%s] 's line %d 's Field 1 invalid value !"),lpszSection, LineNo); hr = E_FAIL; goto Cleanup; break; } cchMaxOldFolderSize = max(cchTmpOldFolderSize,cchMaxOldFolderSize); cchMaxNewFolderSize = max(cchTmpNewFolderSize,cchMaxNewFolderSize); cchMaxExcludeFileListSize = max(cchTmpExcludeFileListSize,cchMaxExcludeFileListSize); } if (cchMaxOldFolderSize) { // add one more TCHAR space incase the file is SFPed in which case we need
// provide a multisz string to UnProtectSFPFiles
cchMaxOldFolderSize += 2; if (!(lpszOldFolder = malloc(cchMaxOldFolderSize * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } } if (cchMaxNewFolderSize) { if (!(lpszNewFolder = malloc(++cchMaxNewFolderSize * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } } if (cchMaxExcludeFileListSize) { if (!(lpExcludeFileList = malloc(++cchMaxExcludeFileListSize * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } }
for (LineNo = 0; LineNo < LineCount; LineNo++) { LPTSTR lpTmpExcludeList = NULL;
if (!SetupGetLineByIndex(hInf,lpszSection,LineNo,&InfContext)) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSection); continue; } if (!SetupGetStringField(&InfContext,1,szType,MAX_PATH,NULL)) { DPF(INFwar ,TEXT("get [%s] 's line %d 's Field 0 failed !"),lpszSection, LineNo); continue; } dwType = _tstoi(szType); if (!SetupGetStringField(&InfContext,2,lpszOldFolder,cchMaxOldFolderSize,NULL) || ! SetupGetStringField(&InfContext,3,lpszNewFolder,cchMaxNewFolderSize,NULL)) { hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); DPF(INFerr ,TEXT("get [%s] 's line %d 's Field 2,3failed !"),lpszSection ,LineNo); goto Cleanup; } switch (dwType) { case TYPE_DIR_MOVE: if (cchMaxExcludeFileListSize) { DWORD dwSize; BOOL bTmp = SetupGetMultiSzField(&InfContext,4,lpExcludeFileList, cchMaxExcludeFileListSize,&dwSize); if (!( bTmp && dwSize >= sizeof(TCHAR))) { lpTmpExcludeList = lpExcludeFileList; } } else { lpTmpExcludeList = NULL; } case TYPE_SFPFILE_MOVE: case TYPE_FILE_MOVE: if (bAnalyze) { AddFolderRename(lpszOldFolder,lpszNewFolder,dwType,lpTmpExcludeList); } else { if (lpTmpExcludeList) { LPTSTR lp = lpTmpExcludeList; while (*lp) { if (!MoveFileEx(lp,NULL,MOVEFILE_DELAY_UNTIL_REBOOT)) { DWORD dw = GetLastError(); DPF(INFerr, TEXT("MoveFileEx(delete) failed %s,win32 error = %d"),lp,dw); } lp += (lstrlen(lp)+1); } } if (dwType == TYPE_SFPFILE_MOVE) { lpszOldFolder[lstrlen(lpszOldFolder)+1] = TEXT('\0'); UnProtectSFPFiles(lpszOldFolder,NULL); } if (!MoveFileEx(lpszOldFolder,lpszNewFolder,MOVEFILE_DELAY_UNTIL_REBOOT)) { DWORD dw = GetLastError(); DPF(INFerr, TEXT("MoveFileEx(%s,%s) failed win32 error = %d"),lpszOldFolder,lpszNewFolder,dw); } } break; } }
Cleanup: FreePointer(lpszOldFolder); FreePointer(lpszNewFolder); FreePointer(lpExcludeFileList); return hr; }
HRESULT EnsureDoItemInfFile( LPTSTR lpszInfFile, size_t CchBufSize) {
LPWSTR lpszHeader = L"[Version]\r\nsignature=\"$Windows NT$\"\r\nClassGUID={00000000-0000-0000-0000-000000000000}\r\nlayoutfile=LAYOUT.INF\r\n"; HANDLE hFile = INVALID_HANDLE_VALUE; HRESULT hr = S_OK; DWORD dwWritten; DWORD dwStatusinReg; BOOL bCureMode = FALSE; WORD wBOM=0xFEFF; SECURITY_ATTRIBUTES sa; PSECURITY_DESCRIPTOR pSD = NULL; if (!GetSystemWindowsDirectory(lpszInfFile, CchBufSize)) { hr = HRESULT_FROM_WIN32(GetLastError()); DPF(INFerr, TEXT("Failed to get system directory, hr = 0x%X"), hr); goto Exit; } if (!ConcatenatePaths(lpszInfFile,CLMT_BACKUP_DIR,CchBufSize)) { hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA); DPF(INFerr, TEXT("buffer size too small when creating clmtdo.inf")); goto Exit; } if (!ConcatenatePaths(lpszInfFile,TEXT("CLMTDO.INF"),CchBufSize)) { hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA); DPF(INFerr, TEXT("buffer size too small when creating clmtdo.inf")); goto Exit; } hr = CLMTGetMachineState(&dwStatusinReg); //If we 've done running clmt.exe and called again, usually it's in /cure mode...
//on this case, we will append the INF file
if ( (hr != S_OK) || ( (CLMT_STATE_MIGRATION_DONE != dwStatusinReg) && (CLMT_STATE_FINISH != dwStatusinReg) && (CLMT_STATE_PROGRAMFILES_CURED != dwStatusinReg)) ) { hr = CreateAdminsSd(&pSD); if (hr != S_OK) { goto Exit; } sa.nLength = sizeof(sa); sa.bInheritHandle = FALSE; sa.lpSecurityDescriptor = pSD; hFile = CreateFile(lpszInfFile,GENERIC_WRITE|GENERIC_READ,0, &sa,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
hr = InitChangeLog(); } else { bCureMode = TRUE; hFile = CreateFile(lpszInfFile,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); }
if (INVALID_HANDLE_VALUE == hFile) { DWORD dw = GetLastError(); hr = HRESULT_FROM_WIN32(GetLastError()); DPF(INFerr, TEXT("Create file %s failed with hr = 0x%X"),lpszInfFile,hr); goto Exit; }
if (!bCureMode) { if(! WriteFile(hFile,&wBOM,sizeof(WORD),&dwWritten,NULL)) { hr = HRESULT_FROM_WIN32(GetLastError()); DPF(INFerr, TEXT("write to file %s failed with hr = 0x%X"),lpszInfFile,hr); goto Exit; } if(! WriteFile(hFile,lpszHeader,lstrlenW(lpszHeader)*sizeof(TCHAR),&dwWritten,NULL)) { hr = HRESULT_FROM_WIN32(GetLastError()); DPF(INFerr, TEXT("write to file %s failed with hr = 0x%X"),lpszInfFile,hr); goto Exit; } } Exit: if (INVALID_HANDLE_VALUE != hFile) { CloseHandle(hFile); } if (pSD) { LocalFree(pSD); } return hr; }
HRESULT GetMaxLenEachField( HINF hInf, LPTSTR lpSection, BOOL bExitOnError, DWORD dwMinFieldCount, DWORD dwMaxFieldCount, PDWORD pdwFieldValidFlag, PDWORD pdwSizeRequired, BOOL bMultiSZ ) { HRESULT hr; UINT LineCount,LineNo; UINT nFieldCount, nFieldIndex; INFCONTEXT InfContext; UINT i; UINT cchReqSize;
if( (hInf == INVALID_HANDLE_VALUE) || !lpSection ) { hr = E_INVALIDARG; goto Exit; } if (!dwMinFieldCount || !dwMaxFieldCount || ( dwMaxFieldCount < dwMinFieldCount) || !pdwSizeRequired) { hr = E_INVALIDARG; goto Exit; } for (i = 0; i < dwMaxFieldCount; i++) { pdwSizeRequired[i] = 0; }
LineCount = (UINT)SetupGetLineCount(hInf,lpSection); if ((LONG)LineCount < 0) { hr = S_FALSE; DPF(INFwar ,TEXT("section name %s is empty failed !"),lpSection); goto Exit; } for (LineNo = 0; LineNo < LineCount; LineNo++) { DWORD dwNumField; if (!SetupGetLineByIndex(hInf,lpSection,LineNo,&InfContext)) { if (bExitOnError) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } else { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpSection); continue; } } dwNumField = SetupGetFieldCount(&InfContext); if ( (dwNumField < dwMinFieldCount) || (dwNumField > dwMaxFieldCount) ) { if (bExitOnError) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } else { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpSection); continue; } } for (nFieldIndex = 1 ; nFieldIndex <= dwNumField ; nFieldIndex++) { BOOL bRet;
if (pdwFieldValidFlag && !pdwFieldValidFlag[nFieldIndex]) { continue; } if ((nFieldIndex == dwMaxFieldCount) && bMultiSZ) { bRet = SetupGetMultiSzField(&InfContext,nFieldIndex,NULL,0,&cchReqSize); } else { bRet = SetupGetStringField(&InfContext,nFieldIndex,NULL,0,&cchReqSize); } if (!bRet) { if (bExitOnError) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } else { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpSection); continue; } } pdwSizeRequired[nFieldIndex-1] = max(pdwSizeRequired[nFieldIndex-1],cchReqSize); } } hr = S_OK; Exit: return hr; }
HRESULT RegUpdate(HINF hInf, HKEY hKeyUser , LPTSTR lpszUsersid) { #define REG_UPDATE_FIELD_COUNT 5
HRESULT hr; LPTSTR lpszSectionName = NULL; DWORD cChSecBuffeSize, dwRequestSize = 0; LPTSTR lpszSectionSuffix = NULL; UINT LineCount,LineNo,nFieldIndex; INFCONTEXT InfContext; TCHAR szRegUpdateType[MAX_PATH],szStrType[MAX_PATH]; DWORD dwRegUpdateType,dwStrType; LPTSTR lpszField[REG_UPDATE_FIELD_COUNT+1] = {NULL, szRegUpdateType, NULL, NULL, NULL, NULL}; HKEY hKey; LPTSTR lpSubKey; DWORD pdwSizeRequired[REG_UPDATE_FIELD_COUNT+1] = {0,MAX_PATH,0,0,0,0}; int i; //check the INF file handle
if(hInf == INVALID_HANDLE_VALUE) { hr = E_INVALIDARG; goto Cleanup; }
if (!lpszUsersid || !MyStrCmpI(lpszUsersid,TEXT("Default_User_SID"))) { //If user sid is NULL it means default user
cChSecBuffeSize = lstrlen(TEXT("REG.Update.Default User")) + 1 ; lpszSectionSuffix = DEFAULT_USER; } else if (!lpszUsersid[0]) { //If user sid is "", it means system wide regsitry
cChSecBuffeSize = lstrlen(TEXT("REG.Update.Sys")) + 1 ; lpszSectionSuffix = TEXT("SYS"); } else { //If it's normal user , the section name is "REG.Update.%userSID%"
cChSecBuffeSize = lstrlen(TEXT("REG.Update.")) + lstrlen(lpszUsersid)+2; }
//Alloc memory and contruct the section name
if (!(lpszSectionName = (LPTSTR) malloc(cChSecBuffeSize * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } if (lpszSectionSuffix) { if (FAILED(StringCchPrintf(lpszSectionName,cChSecBuffeSize,TEXT("%s%s"),TEXT("REG.Update."), lpszSectionSuffix))) { hr = E_FAIL; goto Cleanup; } } else { if (FAILED(StringCchPrintf(lpszSectionName,cChSecBuffeSize,TEXT("%s%s"),TEXT("REG.Update."), lpszUsersid))) { hr = E_FAIL; goto Cleanup; } }
//here we got the section name and then try to get how many lines there
LineCount = (UINT)SetupGetLineCount(hInf,lpszSectionName); if ((LONG)LineCount < 0) { //BUGBUG: xiaoz:The error value here needs to be revisted
hr = E_FAIL; goto Cleanup; }
//Scan the INF file section to get the max buf required for each field
for (LineNo = 0; LineNo < LineCount; LineNo++) { DWORD dwNumField; DWORD dwDataStart; if (!SetupGetLineByIndex(hInf,lpszSectionName,LineNo,&InfContext)) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSectionName); continue; } dwNumField = SetupGetFieldCount(&InfContext); if ( dwNumField < 4 ) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSectionName); continue; } if (!SetupGetStringField(&InfContext,1,lpszField[1],pdwSizeRequired[1],NULL)) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSectionName); continue; } dwRegUpdateType = _tstoi(lpszField[1]); switch (dwRegUpdateType) { case CONSTANT_REG_VALUE_DATA_RENAME: if (!SetupGetStringField(&InfContext,2,szStrType,ARRAYSIZE(szStrType),NULL)) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSectionName); continue; } dwStrType = _tstoi(szStrType); dwDataStart = 3; break; case CONSTANT_REG_VALUE_NAME_RENAME: case CONSTANT_REG_KEY_RENAME: dwDataStart = 2; break; } for (nFieldIndex = dwDataStart ; nFieldIndex <= min(dwNumField,REG_UPDATE_FIELD_COUNT) ; nFieldIndex++) { BOOL bRet; DWORD cchReqSize; if ((nFieldIndex == REG_UPDATE_FIELD_COUNT) && (dwStrType == REG_MULTI_SZ)) { bRet = SetupGetMultiSzField(&InfContext,nFieldIndex,NULL,0,&cchReqSize); } else { bRet = SetupGetMultiSzField(&InfContext,nFieldIndex,NULL,0,&cchReqSize); } if (!bRet) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSectionName); continue; } pdwSizeRequired[nFieldIndex] = max(pdwSizeRequired[nFieldIndex],cchReqSize); } } for (i = 2; i<= REG_UPDATE_FIELD_COUNT; i++) { if (pdwSizeRequired[i]) { if ( NULL == (lpszField[i] = malloc(++pdwSizeRequired[i] * sizeof(TCHAR)))) { hr = E_OUTOFMEMORY; goto Cleanup; } } } for(LineNo=0; LineNo<LineCount; LineNo++) { SetupGetLineByIndex(hInf,lpszSectionName,LineNo,&InfContext); SetupGetStringField(&InfContext,1,lpszField[1],pdwSizeRequired[1],NULL); dwRegUpdateType = _tstoi(lpszField[1]); switch (dwRegUpdateType) { case CONSTANT_REG_VALUE_DATA_RENAME: SetupGetStringField(&InfContext,2,szStrType,ARRAYSIZE(szStrType),NULL); dwStrType = _tstoi(szStrType); SetupGetStringField(&InfContext,3,lpszField[3],pdwSizeRequired[3],NULL); SetupGetStringField(&InfContext,4,lpszField[4],pdwSizeRequired[4],NULL); if ((dwStrType & 0xffff) == REG_MULTI_SZ) { SetupGetMultiSzField(&InfContext,5,lpszField[5],pdwSizeRequired[5],NULL); } else if ((dwStrType & 0xffff) == REG_BINARY) { if (!SetupGetBinaryField(&InfContext,5,(LPBYTE)lpszField[5],pdwSizeRequired[5]*sizeof(TCHAR),&dwRequestSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { free(lpszField[5]); if ((lpszField[5] = (LPTSTR)malloc(dwRequestSize)) == NULL) { hr = E_OUTOFMEMORY; goto Cleanup; } SetupGetBinaryField(&InfContext,5,(LPBYTE)lpszField[5],dwRequestSize,NULL); } } else { SetupGetStringField(&InfContext,5,lpszField[5],pdwSizeRequired[5],NULL); }
if (!(*lpszField[3])) { lpSubKey = NULL; } else { Str2KeyPath(lpszField[3],&hKey,&lpSubKey); } if (hKeyUser) { hKey = hKeyUser; } if ( (dwStrType & 0xffff) == REG_DWORD) { MyRegSetDWValue(hKey,lpSubKey,lpszField[4],lpszField[5]); } else { RegResetValue(hKey,lpSubKey,lpszField[4],dwStrType,TEXT(""),lpszField[5],dwRequestSize,lpszUsersid); } break; case CONSTANT_REG_VALUE_NAME_RENAME: case CONSTANT_REG_KEY_RENAME: for (i = 2; i <= 4 ;i++) { SetupGetStringField(&InfContext,i,lpszField[i],pdwSizeRequired[i],NULL); } Str2KeyPath(lpszField[2],&hKey,&lpSubKey); if (hKeyUser) { hKey = hKeyUser; } if (dwRegUpdateType == CONSTANT_REG_VALUE_NAME_RENAME) { RegResetValueName(hKey,lpSubKey,lpszField[3],lpszField[4], lpszUsersid); } else { RegResetKeyName(hKey, lpSubKey, lpszField[3], lpszField[4]); } break; } } hr = S_OK; Cleanup: FreePointer(lpszSectionName); for (i = 2; i< ARRAYSIZE(lpszField); i++) { FreePointer(lpszField[i]); } return hr; }
HRESULT INFCreateHardLink( HINF hInf, LPTSTR lpszSection, BOOL bMakeLinkHidden) { HRESULT hr; INT LineCount,LineNo,nFieldIndex; INFCONTEXT InfContext; TCHAR szFileName[MAX_PATH+1],szExistingFileName[MAX_PATH+1],szHidden[MAX_PATH]; TCHAR szType[10]; DWORD dwType; TCHAR lpszInf[MAX_PATH+1]; HINF hMyInf; BOOL bLocalHidden = bMakeLinkHidden; //check the INF file handle
hMyInf = hInf; if(hMyInf == INVALID_HANDLE_VALUE) { hr = EnsureDoItemInfFile(lpszInf,ARRAYSIZE(lpszInf)); if (FAILED(hr)) { goto Cleanup; } hMyInf = SetupOpenInfFile(lpszInf, NULL, INF_STYLE_WIN4, NULL); if (hMyInf == INVALID_HANDLE_VALUE) { hr = E_INVALIDARG; goto Cleanup; } } LineCount = (UINT)SetupGetLineCount(hMyInf,lpszSection); if ((LONG)LineCount < 0) { hr = S_FALSE; goto Cleanup; } for (LineNo = LineCount -1 ; LineNo >= 0; LineNo--) { BOOL b1,b2,b3,b4;
if (!SetupGetLineByIndex(hMyInf,lpszSection,LineNo,&InfContext)) { continue; } b1 = SetupGetStringField(&InfContext,1,szType,ARRAYSIZE(szType),NULL); b2 = SetupGetStringField(&InfContext,2,szFileName,ARRAYSIZE(szFileName),NULL); b3 = SetupGetStringField(&InfContext,3,szExistingFileName,ARRAYSIZE(szExistingFileName),NULL); if (!b1 || !b2 || !b3) { continue; } b4 = SetupGetStringField(&InfContext,4,szHidden,ARRAYSIZE(szHidden),NULL); bLocalHidden = bMakeLinkHidden; if (b4) { DWORD dwHiddenType; dwHiddenType = _tstoi(szHidden); if (!dwHiddenType) { bLocalHidden = FALSE; } else { bLocalHidden = TRUE; } } dwType = _tstoi(szType); #ifdef CREATE_MINI_HARDLIN
if (g_dwRunningStatus == CLMT_CURE_PROGRAM_FILES) { if (dwType == 0) { continue; } } #endif
#ifdef CONSOLE_UI
wprintf(TEXT("create reparse point between folder %s and %s\n"),szFileName,szExistingFileName); #endif
if (CreateSymbolicLink(szFileName,szExistingFileName,bLocalHidden)) { //hr = S_OK;
} else { //hr = HRESULT_FROM_WIN32(GetLastError());
} } hr = S_OK; Cleanup: if ( (hInf == INVALID_HANDLE_VALUE) && (hMyInf != INVALID_HANDLE_VALUE) ) { SetupCloseInfFile(hMyInf); } return hr; }
//-----------------------------------------------------------------------
//
// Function: AnalyzeServicesStatus
//
// Descrip: Analyze the services running on the system and see if
// they need to be stopped or not
//
// Returns: S_OK if function succeeded.
// else if error occured
//
// Notes: none
//
// History: 04/30/2002 rerkboos created
// 07/08/2002 rerkboos modified
// 09/06/2002 rerkboos modified
//
// Notes: Format of the section in clmt.inf:
// <service name to be stopped>, <action>
//
//-----------------------------------------------------------------------
HRESULT AnalyzeServicesStatus( HINF hInf, // Handle to Migration INF
LPCTSTR lpInfSection // Section to be read from INF
) { HRESULT hr = S_OK; BOOL bRet = TRUE; LONG lLineCount; LONG lLineIndex; INFCONTEXT context; TCHAR szServiceName[128]; TCHAR szControl[8]; TCHAR szCleanupControl[8]; INT iRunningStatus; INT iServiceControl; DWORD dwCleanupControl; SC_HANDLE schService; SC_HANDLE schSCManager; SERVICE_STATUS ssStatus;
if (hInf == INVALID_HANDLE_VALUE || lpInfSection == NULL) { return E_INVALIDARG; }
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (schSCManager != NULL) { // Read the list of services to be reset from INF
lLineCount = SetupGetLineCount(hInf, lpInfSection); for (lLineIndex = 0 ; lLineIndex < lLineCount && bRet ; lLineIndex++) { bRet = SetupGetLineByIndex(hInf, lpInfSection, (DWORD) lLineIndex, &context); if (bRet) { bRet = SetupGetStringField(&context, 1, szServiceName, ARRAYSIZE(szServiceName), NULL) && SetupGetIntField(&context, 2, &iRunningStatus) && SetupGetIntField(&context, 3, &iServiceControl); if (bRet) { schService = OpenService(schSCManager, szServiceName, SERVICE_ALL_ACCESS); if (schService != NULL) { QueryServiceStatus(schService, &ssStatus); if (ssStatus.dwCurrentState == (DWORD) iRunningStatus) { switch (iServiceControl) { case SERVICE_CONTROL_STOP: dwCleanupControl = 0; // 0 means start the service
break;
case SERVICE_CONTROL_PAUSE: dwCleanupControl = SERVICE_CONTROL_CONTINUE; break; }
_itot(iServiceControl, szControl, 10); _ultot(dwCleanupControl, szCleanupControl, 10);
WritePrivateProfileString(TEXT_SERVICE_STATUS_SECTION, szServiceName, szControl, g_szToDoINFFileName);
WritePrivateProfileString(TEXT_SERVICE_STATUS_CLEANUP_SECTION, szServiceName, szCleanupControl, g_szToDoINFFileName); }
CloseServiceHandle(schService); } } } }
CloseServiceHandle(schSCManager); } else { bRet = FALSE; }
hr = (bRet == TRUE ? S_OK : HRESULT_FROM_WIN32(GetLastError()));
return hr; }
//-----------------------------------------------------------------------
//
// Function: AnalyzeServicesStartUp
//
// Descrip: Analyze services startup type. Some components in the system
// need to be stopped and not to start automatically until
// upgraded to .NET server. So, we might need to change those
// services to "Manually Start".
// Change the Service Start Type, there are following type availabe now
// SERVICE_AUTO_START
// SERVICE_BOOT_START
// SERVICE_DEMAND_START
// SERVICE_DISABLED
// SERVICE_SYSTEM_START
//
// Returns: S_OK if function succeeded.
// else if error occured
//
// Notes: none
//
// History: 09/07/2002 rerkboos created
//
// Notes: Format of the section in clmt.inf:
// <service name>, <current start type in system>, <new start type>
//
//-----------------------------------------------------------------------
HRESULT AnalyzeServicesStartUp( HINF hInf, LPCTSTR lpInfSection ) { HRESULT hr = S_OK; BOOL bRet = TRUE; LONG lLineCount; LONG lLineIndex; INFCONTEXT context; WCHAR szServiceName[64]; WCHAR szCurrentStartupType[8]; WCHAR szNewStartupType[8]; INT iCurrentStartupType; INT iNewStartupType; DWORD dwBytesNeeded; SC_HANDLE schService; SC_HANDLE schSCManager; SERVICE_STATUS ssStatus; LPQUERY_SERVICE_CONFIG lpqscBuf = NULL;
if (hInf == INVALID_HANDLE_VALUE) { return E_INVALIDARG; }
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (schSCManager != NULL) { lLineCount = SetupGetLineCount(hInf, lpInfSection); for (lLineIndex = 0 ; lLineIndex < lLineCount && bRet ; lLineIndex++) { bRet = SetupGetLineByIndex(hInf, lpInfSection, (DWORD) lLineIndex, &context); if (bRet) { bRet = SetupGetStringField(&context, 1, szServiceName, ARRAYSIZE(szServiceName), NULL) && SetupGetIntField(&context, 2, &iCurrentStartupType) && SetupGetIntField(&context, 3, &iNewStartupType); if (bRet) { schService = OpenService(schSCManager, szServiceName, SERVICE_QUERY_CONFIG); if (schService != NULL) { lpqscBuf = (LPQUERY_SERVICE_CONFIG) MEMALLOC(4096); if (lpqscBuf != NULL) { bRet = QueryServiceConfig(schService, lpqscBuf, 4096, &dwBytesNeeded); if (bRet) { if (lpqscBuf->dwStartType == (DWORD) iCurrentStartupType) { _itot(iCurrentStartupType, szCurrentStartupType, 10); _itot(iNewStartupType, szNewStartupType, 10); WritePrivateProfileString(TEXT_SERVICE_STARTUP_SECTION, szServiceName, szNewStartupType, g_szToDoINFFileName); WritePrivateProfileString(TEXT_SERVICE_STARTUP_CLEANUP_SECTION, szServiceName, szCurrentStartupType, g_szToDoINFFileName); } }
MEMFREE(lpqscBuf); } else { SetLastError(ERROR_OUTOFMEMORY); }
CloseServiceHandle(schService); } } } }
CloseServiceHandle(schSCManager); } else { bRet = FALSE; }
hr = (bRet == TRUE ? S_OK : HRESULT_FROM_WIN32(GetLastError()));
return hr; }
//-----------------------------------------------------------------------
//
// Function: ResetServicesStatus
//
// Descrip: Reset the services listed in specified section of INF
//
// Returns: S_OK if function succeeded.
// else if error occured
//
// Notes: none
//
// History: 04/30/2002 rerkboos created
// 07/08/2002 rerkboos modified
//
// Notes: Format of the section in clmt.inf:
// <service name to be stopped>, <action>
//
//-----------------------------------------------------------------------
HRESULT ResetServicesStatus( HINF hInf, // Handle to INF
LPCTSTR lpInfSection // Section to be read from INF
) { HRESULT hr = S_OK; BOOL bRet = TRUE; LONG lLineCount; LONG lLineIndex; INFCONTEXT context; WCHAR szServiceName[128]; INT iServiceControl;
if (hInf == INVALID_HANDLE_VALUE || lpInfSection == NULL) { return E_INVALIDARG; }
// Read the list of services to be reset from INF
lLineCount = SetupGetLineCount(hInf, lpInfSection); for (lLineIndex = 0 ; lLineIndex < lLineCount && bRet ; lLineIndex++) { bRet = SetupGetLineByIndex(hInf, lpInfSection, (DWORD) lLineIndex, &context); if (bRet) { bRet = SetupGetStringField(&context, 0, szServiceName, ARRAYSIZE(szServiceName), NULL) && SetupGetIntField(&context, 1, &iServiceControl); if (bRet) { hr = ResetServiceStatus(szServiceName, (DWORD) iServiceControl, 10); } } }
hr = (bRet == TRUE ? S_OK : HRESULT_FROM_WIN32(GetLastError()));
return hr; }
//-----------------------------------------------------------------------
//
// Function: ResetServicesStartUp
//
// Descrip: Reconfigure services start type. Some components in the system
// need to be stopped and not to start automatically until
// upgraded to .NET server. So, we might need to change those
// services to "Manually Start".
// Change the Service Start Type, there are following type availabe now
// SERVICE_AUTO_START
// SERVICE_BOOT_START
// SERVICE_DEMAND_START
// SERVICE_DISABLED
// SERVICE_SYSTEM_START
//
// Returns: S_OK if function succeeded.
// else if error occured
//
// Notes: none
//
// History: 04/30/2002 rerkboos created
//
// Notes: Format of the section in clmt.inf:
// <service name>, <current start type in system>, <new start type>
//
//-----------------------------------------------------------------------
HRESULT ResetServicesStartUp( HINF hInf, LPCTSTR lpInfSection ) { HRESULT hr = S_OK; BOOL bRet = TRUE; LONG lLineCount; LONG lLineIndex; INFCONTEXT context; WCHAR szServiceName[64]; INT iNewStartupType;
if (hInf == INVALID_HANDLE_VALUE) { return E_INVALIDARG; }
lLineCount = SetupGetLineCount(hInf, lpInfSection); for (lLineIndex = 0 ; lLineIndex < lLineCount && bRet ; lLineIndex++) { bRet = SetupGetLineByIndex(hInf, lpInfSection, (DWORD) lLineIndex, &context); if (bRet) { bRet = SetupGetStringField(&context, 0, szServiceName, ARRAYSIZE(szServiceName), NULL) && SetupGetIntField(&context, 1, &iNewStartupType); if (bRet) { hr = ChangeServiceStartupType(szServiceName, iNewStartupType, 10); } } }
hr = (bRet == TRUE ? S_OK : HRESULT_FROM_WIN32(GetLastError()));
return hr; }
HRESULT ChangeServiceStartupType( LPCTSTR lpServiceName, DWORD dwNewStartupType, DWORD dwMaxWait ) { SC_LOCK sclLock = NULL; SERVICE_DESCRIPTION sdBuf; DWORD dwBytesNeeded; DWORD dwStartType; SC_HANDLE schSCManager = NULL; SC_HANDLE schService = NULL; DWORD dwErr = ERROR_SUCCESS; HRESULT hr = S_OK; DWORD dwCnt; BOOL bRet; if (lpServiceName == NULL) { return E_INVALIDARG; }
schSCManager = OpenSCManager(NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS); if (!schSCManager) { dwErr = GetLastError(); goto cleanup; } // Need to acquire database lock before reconfiguring.
for(dwCnt = 0 ; dwCnt < dwMaxWait ; dwCnt++) { sclLock = LockServiceDatabase(schSCManager); if (sclLock == NULL) { // Exit if the database is not locked by another process.
dwErr = GetLastError(); if (dwErr != ERROR_SERVICE_DATABASE_LOCKED) { goto cleanup; } else { Sleep(1000); } } else { break; } }
if (sclLock != NULL) { // The database is locked, so it is safe to make changes.
// Open a handle to the service.
schService = OpenService(schSCManager, // SCManager database
lpServiceName, // name of service
SERVICE_CHANGE_CONFIG | SERVICE_QUERY_CONFIG ); if (schService != NULL) { // Make the changes
bRet = ChangeServiceConfig(schService, // handle of service
SERVICE_NO_CHANGE, // service type: no change
dwNewStartupType, // change service start type
SERVICE_NO_CHANGE, // error control: no change
NULL, // binary path: no change
NULL, // load order group: no change
NULL, // tag ID: no change
NULL, // dependencies: no change
NULL, // account name: no change
NULL, // password: no change
NULL); // display name: no change
if (!bRet) { dwErr = GetLastError(); }
CloseServiceHandle(schService); } else { dwErr = GetLastError(); }
UnlockServiceDatabase(sclLock); }
hr = S_OK;
cleanup:
if (dwErr != ERROR_SUCCESS) { hr = HRESULT_FROM_WIN32(dwErr); }
if (schSCManager) { CloseServiceHandle(schSCManager); }
return hr; }
BOOL LnkFileUpdate(LPTSTR lpszFile) { HRESULT hr ; hr = AddNeedUpdateLnkFile(lpszFile,&g_StrReplaceTable ); if (SUCCEEDED(hr)) { return TRUE; } else { return FALSE; } }
BOOL SecTempUpdate(LPTSTR lpszFile) { HRESULT hr ; hr = UpdateSecurityTemplates(lpszFile,&g_StrReplaceTable ); if (SUCCEEDED(hr)) { return TRUE; } else { return FALSE; } }
//-----------------------------------------------------------------------
//
// Function: ResetServiceStatus
//
// Descrip: Reset the running (start/pause/stop) status of
// the specified service
//
// Returns: S_OK if function succeeded.
// else if error occured
//
// Notes: none
//
// History: 07/09/2002 rerkboos created
//
// Notes: Format of the section in clmt.inf:
// <service name>, <control>
//
//-----------------------------------------------------------------------
HRESULT ResetServiceStatus( LPCTSTR lpServiceName, // Service name
DWORD dwControl, // Control for the specified service
DWORD dwMaxWait // Timeout in seconds
) { HRESULT hr = E_FAIL; BOOL bRet = FALSE; SC_HANDLE schService; SC_HANDLE schSCManager; SERVICE_STATUS ssStatus; DWORD dwSec; DWORD dwFinalStatus;
switch (dwControl) { case SERVICE_CONTROL_CONTINUE: dwFinalStatus = SERVICE_RUNNING; break;
case SERVICE_CONTROL_PAUSE: dwFinalStatus = SERVICE_PAUSED; break;
case SERVICE_CONTROL_STOP: dwFinalStatus = SERVICE_STOPPED; break; case 0: // Start service
dwFinalStatus = SERVICE_RUNNING; break; }
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (schSCManager != NULL) { schService = OpenService(schSCManager, lpServiceName, SERVICE_ALL_ACCESS); if (schService != NULL) { if (dwControl == 0) { // Start service
bRet = StartService(schService, 0, NULL); } else { // Continue, Pause, Stop service
bRet = ControlService(schService, dwControl, &ssStatus); }
if (bRet) { dwSec = 0; hr = S_FALSE;
while (QueryServiceStatus(schService, &ssStatus) && dwSec < dwMaxWait) { if (ssStatus.dwCurrentState != dwFinalStatus) { Sleep(1000); dwSec++; } else { hr = S_OK; break; } }
if (hr != S_OK) { DPF(APPwar, TEXT(" Warning! - [%s] service status cannot change from %d to %d\n"), lpServiceName, ssStatus.dwCurrentState, dwFinalStatus); } }
CloseServiceHandle(schService); }
CloseServiceHandle(schSCManager); }
if (FAILED(hr)) { hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
HRESULT FinalUpdateRegForUser(HKEY hKeyUser, LPTSTR UserName, LPTSTR DomainName, LPTSTR UserSid) { RegUpdate(g_hInfDoItem, hKeyUser, UserSid); return S_OK; }
/*++
Routine Description:
This routine does the per user registry search and replace, the string replace table is in global variable g_StrReplaceTable
Arguments:
hKeyUser - user registry key handle UserName - user name that hKeyUser belongs to DomainName - domain name the UserName belongs to Return Value:
NULL --*/ HRESULT UpdateRegPerUser (HKEY hKeyUser, LPTSTR UserName, LPTSTR DomainName, LPTSTR UserSid) { return RegistryAnalyze(hKeyUser,UserName,UserSid,&g_StrReplaceTable,NULL,0,NULL,TRUE); }
HRESULT UpdateDSObjProp( HINF hInf, LPTSTR lpInfSection) { #define DSOBJNUMOFFIELD 3
DWORD dwFileValid[DSOBJNUMOFFIELD] = {1,1,1}; DWORD arrSizeNeeded[DSOBJNUMOFFIELD]; LPTSTR lpField[DSOBJNUMOFFIELD]; UINT LineCount,LineNo; INFCONTEXT InfContext; HRESULT hr; int i;
for ( i = 0; i < DSOBJNUMOFFIELD; i++) { lpField[i] = NULL; } hr = GetMaxLenEachField(hInf,lpInfSection,FALSE,DSOBJNUMOFFIELD,DSOBJNUMOFFIELD, (PDWORD)dwFileValid,arrSizeNeeded,FALSE); if (hr != S_OK) { goto cleanup; } for (i = 0; i < DSOBJNUMOFFIELD; i++) { if (!(lpField[i] = malloc(arrSizeNeeded[i]*sizeof(TCHAR)))) { goto cleanup; } } LineCount = (UINT)SetupGetLineCount(hInf,lpInfSection); if ((LONG)LineCount < 0) { hr = S_FALSE; goto cleanup; }
//Scan the INF file section to get the max buf required for each field
for (LineNo = 0; LineNo < LineCount; LineNo++) { if (!SetupGetLineByIndex(hInf,lpInfSection,LineNo,&InfContext)) { DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpInfSection); continue; } for (i = 1; i <= DSOBJNUMOFFIELD; i++) { SetupGetStringField(&InfContext,i,lpField[i-1],arrSizeNeeded[i-1],NULL); } PropertyValueHelper( lpField[0],lpField[1],NULL,lpField[2]); } hr =S_OK; cleanup: for (i = 0; i < DSOBJNUMOFFIELD; i++) { FreePointer(lpField[i]); } return hr;
}
void DoServicesAnalyze() { AnalyzeServicesStatus(g_hInf, TEXT_SERVICE_STATUS_SECTION); AnalyzeServicesStartUp(g_hInf, TEXT_SERVICE_STARTUP_SECTION); }
HRESULT INFVerifyHardLink( HINF hInf, LPTSTR lpszSection) { HRESULT hr; INT LineCount,LineNo,nFieldIndex; INFCONTEXT InfContext; TCHAR szFileName[MAX_PATH+1],szExistingFileName[MAX_PATH+1],szCurrLink[MAX_PATH]; TCHAR lpszInf[MAX_PATH+1]; HINF hMyInf; //check the INF file handle
hMyInf = hInf; if(hMyInf == INVALID_HANDLE_VALUE) { hr = EnsureDoItemInfFile(lpszInf,ARRAYSIZE(lpszInf)); if (FAILED(hr)) { goto Cleanup; } hMyInf = SetupOpenInfFile(lpszInf, NULL, INF_STYLE_WIN4, NULL); if (hMyInf == INVALID_HANDLE_VALUE) { hr = E_INVALIDARG; goto Cleanup; } } LineCount = (UINT)SetupGetLineCount(hMyInf,lpszSection); if ((LONG)LineCount < 0) { hr = S_FALSE; goto Cleanup; } for (LineNo = 0 ; LineNo < LineCount; LineNo++) { BOOL b1,b2,b3,b4;
if (!SetupGetLineByIndex(hMyInf,lpszSection,LineNo,&InfContext)) { continue; } b2 = SetupGetStringField(&InfContext,2,szFileName,ARRAYSIZE(szFileName),NULL); b3 = SetupGetStringField(&InfContext,3,szExistingFileName,ARRAYSIZE(szExistingFileName),NULL); if (!b2 || !b3) { continue; } if (GetSymbolicLink(szFileName,szCurrLink,ARRAYSIZE(szCurrLink))) { if (!IsDirExisting(szCurrLink)) { RemoveDirectory(szFileName); } } } hr = S_OK; Cleanup: if ( (hInf == INVALID_HANDLE_VALUE) && (hMyInf != INVALID_HANDLE_VALUE) ) { SetupCloseInfFile(hMyInf); } return hr; }
|