#include #include #include #include #include #include "network.h" #include "idw_dbg.h" #include "machines.h" #include "server.h" #define TTEST // Test non-threaded execution for server reporting. /*++ Filename : Network.c Description: Contains the network access code. Created by: Wally Ho History: Created on 28/01/2000. 09.19.2001 Joe Holman fixes for idwlog bugs 409338, 399178, and 352810 Contains these functions: 1. FILE* OpenCookieFile(); 2. VOID CloseCookieFile(IN FILE* fpOpenFile); 3. VOID DeleteCookieFile( VOID ) 4. BOOL WriteIdwlogCookie ( IN LPINSTALL_DATA pId); 5. BOOL ReadIdwlogCookie ( OUT LPINSTALL_DATA lpId); 6. BOOL ServerWriteMinimum (LPINSTALL_DATA pId, LPMACHINE_DETAILS pMd); 7. VOID ServerWriteMaximum (LPTSTR szFileName, LPINSTALL_DATA pId); 8. VOID WriteThread(IN LPSERVER_WRITE_PARAMS pSw); 9. VOID DeleteDatafile (LPINSTALL_DATA); 10. BOOL WriteDataToAvailableServer (LPINSTALL_DATA pId, LPTSTR szServerData) 11. BOOL SetCancelMutex ( VOID ); 12. BOOL ClearCancelMutex ( VOID ); 13. BOOL PauseForMutex( VOID ); 14. BOOL FileExistsEx( IN LPTSTR szFileName); 15 VOID DeleteIPCConnections( VOID ); --*/ // Global Mutex Handle; HANDLE g_hCancelMutex; HANDLE g_hInstanceMutex; FILE* OpenCookieFile(VOID) /*++ Routine Description: This will try drives c through z to find the idwlog.cookie file. Arguments: NONE Return Value: NULL for failure. The file handle if found. Author: Wally Ho (wallyho) Jan 31st, 2000 --*/ { FILE* fpOpenFile; TCHAR szDriveFile [ 20]; UINT i; for (i= TEXT('c'); i <= TEXT('z'); i++){ _stprintf ( szDriveFile, TEXT("%c:\\idwlog.cookie"), i); fpOpenFile = _tfopen(szDriveFile, TEXT("r")); // if we find the file we return the handle to it. if (NULL != fpOpenFile) return fpOpenFile; } // if we get here we know we found nothing. return NULL; } VOID CloseCookieFile(IN FILE* fpOpenFile) /*++ Author: Wally Ho (wallyho) Jan 31st, 2000 Routine Description: This will close the cookie file and Delete it It will try drives c through z to find the idwlog.cookie file. Arguments: The File Handle. Return Value: NONE --*/ { fclose(fpOpenFile); } VOID DeleteCookieFile( VOID ) /*++ Author: Wally Ho (wallyho) Jan 31st, 2000 Routine Description: This will delete the cookiefile. It will try drives c through z to find the idwlog.cookie file. Arguments: NONE Return Value: NONE --*/ { TCHAR szDriveFile [ 20]; UINT i; BOOL bDeleteSuccess = FALSE; // Try to delete the idwlog.cookie file. // specifies. for (i = TEXT('c'); i <= TEXT('z');i++){ _stprintf ( szDriveFile, TEXT("%c:\\idwlog.cookie"), i); // // If we get a non zero return from DeleteFile // then we know the delete file was a success. // if (FALSE != DeleteFile(szDriveFile) ){ bDeleteSuccess = TRUE; break; } } if (FALSE == bDeleteSuccess) Idwlog(TEXT("DeleteCookieFile ERROR - There was a problem deleting the idwlog.cookie file, gle = %ld, file = %s\n"), GetLastError(), szDriveFile ); else Idwlog(TEXT("The idwlog.cookie file was successfully deleted.\n")); } BOOL WriteIdwlogCookie (IN LPINSTALL_DATA pId) /*++ Routine Description: The cookie file will be saved as idwlog.cookie. The file will be hidden and will wind up on the root of the system drive. This cookie file passes information we can only get from the install program over to the second part of the idwlog. The new cookie file format is this. Keyword seprated by 1 space. Much cleaner and easily extensible. ComputerName WALLYHO_DEV SystemBuild 2190 SystemBuildDelta 30 SystemBuildLocation LAB InstallingBuild 2195 InstallingBuildDelta 30 InstallingBuildLocation LAB MachineID 3212115354 Cdrom YES|NO Network YES|NO Type CLEAN|UPGRADE Msi N SPMethod OEMImage YES|NO Arguments: INSTALL_DATA structure. Return Value: NONE --*/ { HANDLE hFile; TCHAR szLineBuffer [ MAX_PATH ]; TCHAR szIdwlogCookieFile[30]; DWORD dwNumWritten; if (TRUE == pId->bFindBLDFile){ // wallyho: // Get the system drive and write the cookie file there. // originally it would write it in the SAVE_FILE and thats // always c:. If this fails say %SystemDrive% doesn't exist in // windows 9X (I don't know if it does?) then we'll default to c: if(FALSE == GetEnvironmentVariable(TEXT("SystemDrive"), szIdwlogCookieFile, 30)) _stprintf(szIdwlogCookieFile,TEXT("c:")); _tcscat(szIdwlogCookieFile,TEXT("\\idwlog.cookie")); hFile = CreateFile (szIdwlogCookieFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL ); if (hFile == INVALID_HANDLE_VALUE){ OutputDebugString ("Unable to write idwlog.cookie file.\n"); Idwlog(TEXT("Problem writing the idwlog.cookie file.\n\ Returning without writing. Last Error %lu\n"), GetLastError()); return FALSE; } /* New format for the idwlog.cookie file. ComputerName WALLYHO_DEV SystemBuild 2190 SystemBuildDelta 30 SystemBuildLocation Lab01_N.000219-2219 InstallingBuild 2195 InstallingBuildDelta 30 InstallingBuildLocation Lab01_N.000219-2219 MachineID 3212115354 Cdrom YES|NO Network YES|NO Type CLEAN|UPGRADE Msi N SPMethod SPMSI YES|NO OEMImage YES|NO IdwlogServer \\ntcore2\idwlog */ // Write into idwlog.cookie ZeroMemory((LPTSTR)szLineBuffer,MAX_PATH); //The computer name _stprintf (szLineBuffer, TEXT("\nComputerName %s\r"), pId->szComputerName); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The user name _stprintf (szLineBuffer, TEXT("\nUserName %s\r"), pId->szUserName ); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The domain name _stprintf (szLineBuffer, TEXT("\nDomainName %s\r"), pId->szUserDomain ); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The System build. _stprintf (szLineBuffer, TEXT("\nSystemBuild %lu\r"), pId->dwSystemBuild); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The System build Delta _stprintf (szLineBuffer, TEXT("\nSystemBuildDelta %lu\r"), pId->dwSystemBuildDelta); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The SP build, same as above different name for backend. _stprintf (szLineBuffer, TEXT("\nSystemSPBuild %lu\r"), pId->dwSystemSPBuild); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The System build location name _stprintf (szLineBuffer, TEXT("\nSystemBuildLocation %s\r"), pId->szSystemBuildSourceLocation); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The Installing build. _stprintf (szLineBuffer, TEXT("\nInstallingBuild %lu\r"), pId->dwInstallingBuild); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The Installing build Delta _stprintf (szLineBuffer, TEXT("\nInstallingBuildDelta %lu\r"), pId->dwInstallingBuildDelta); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The Installing SP build, same as above but with different name for backend. _stprintf (szLineBuffer, TEXT("\nInstallingSPBuild %lu\r"), pId->dwInstallingSPBuild); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The Installing build location name _stprintf (szLineBuffer, TEXT("\nInstallingBuildLocation %s\r"), pId->szInstallingBuildSourceLocation); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The Machine Id. _stprintf (szLineBuffer, TEXT("\nMachineID %0.9lu\r"), pId->dwMachineID); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The Cdrom Bool _stprintf (szLineBuffer, TEXT("\nCdrom %s\r"), pId->bCdrom? TEXT("YES"): TEXT("NO")); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The Network Bool _stprintf (szLineBuffer, TEXT("\nNetwork %s\r"), pId->bNetwork? TEXT("YES"): TEXT("NO")); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); //The Type Bool _stprintf (szLineBuffer, TEXT("\nType %s\r"), pId->bClean? TEXT("CLEAN"): TEXT("UPGRADE")); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); // Check for MSI install _stprintf (szLineBuffer, TEXT("\nMsi %s\r"), pId->bMsi ? TEXT("YES"): TEXT("NO")); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); // Check for SP install type. We can have: uninstall, patch, or full. // if ( pId->bSPUninst ) { _stprintf (szLineBuffer, TEXT("\nSPMethod %s\r"), TEXT("REMOVE")); } if ( pId->bSPPatch ) { _stprintf (szLineBuffer, TEXT("\nSPMethod %s\r"), TEXT("PATCH")); } if ( pId->bSPFull ) { _stprintf (szLineBuffer, TEXT("\nSPMethod %s\r"), TEXT("FULL")); } if ( pId->bSPUpdate ) { _stprintf (szLineBuffer, TEXT("\nSPMethod %s\r"), TEXT("UPDATE")); } WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); // Check for OEM Image // _stprintf (szLineBuffer, TEXT("\nOEMImage %s\r"), pId->bOEMImage? TEXT("YES"): TEXT("NO")); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); // Check for Sku _stprintf (szLineBuffer, TEXT("\nSku %lu\r"), pId->dwSku); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); // Write out the server. _stprintf (szLineBuffer, TEXT("\nIdwlogServer %s\r"), pId->szIdwlogServer); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); CloseHandle (hFile); } else{ // wallyho: // Get the system drive and write the cookie file there. // originally it would write it in the SAVE_FILE and thats // always c:. If this fails say %SystemDrive% doesn't exist in // windows 9X (I don't know if it does?) then we'll default to c: Idwlog(TEXT("Writing the NO_BUILD_DATA cookie. So we know its not a CD BOOT INSTALL.\n")); if(FALSE == GetEnvironmentVariable(TEXT("SystemDrive"), szIdwlogCookieFile, 30)) _stprintf(szIdwlogCookieFile,TEXT("c:")); _tcscat(szIdwlogCookieFile,TEXT("\\idwlog.cookie")); hFile = CreateFile (szIdwlogCookieFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL ); if (hFile == INVALID_HANDLE_VALUE){ OutputDebugString ("Unable to write idwlog.cookie file.\n"); Idwlog(TEXT("Problem writing the idwlog.cookie file.\n\ Returning without writing. Last Error %lu\n"), GetLastError()); return FALSE; } /* New format for the no BLD idwlog.cookie file. NO_BUILD_DATA */ // Write into idwlog.cookie ZeroMemory((LPTSTR)szLineBuffer,MAX_PATH); // The A file to show no build occured. _tcscpy(szLineBuffer, TEXT("\nNO_BUILD_DATA\r")); WriteFile (hFile,(LPTSTR)szLineBuffer,_tcsclen(szLineBuffer)+1 , &dwNumWritten, NULL); CloseHandle (hFile); } return TRUE; } BOOL ReadIdwlogCookie( OUT LPINSTALL_DATA lpId) /*++ Routine Description: This will get the install data from the idwlog cookie file. Arguments: Structure to hold all the data we have from the install. Return Value: TRUE for success. FALSE for non success. Author: Wally Ho (wallyho) Jan 31st, 2000 --*/ { FILE* fpOpenFile; TCHAR szLineBuffer[256]; TCHAR szResponse[10]; TCHAR szDontCare[50]; BOOL b = TRUE; DWORD dw; /* If \idwlog.cookie exists, then use the data from here to create the file on the database. Otherwise ?? Example idwlog.cookie ComputerName WALLYHO_DEV SystemBuild 2190 SystemBuildDelta 30 SystemBuildLocation Lab01_N.000219-2219 InstallingBuild 2195 InstallingBuildDelta 30 InstallingBuildLocation Lab01_N.000219-2219 MachineID 3212115354 Cdrom YES|NO Network YES|NO Type CLEAN|UPGRADE Msi N SPMehthod OEMImage YES|NO IdwlogServer \\ntcore2\idwlog or NO_BUILD_DATA */ fpOpenFile = OpenCookieFile(); if (NULL == fpOpenFile){ // Do something about not finding the cookie. Idwlog(TEXT("Could not find the Cookie file!! Err: %d\n"), GetLastError()); // OutputDebugString (TEXT("Idwlog could not find cookie file\n")); // b = FALSE; }else{ do { // we've found the cookie. // Get the line one after another. _fgetts(szLineBuffer, 256,fpOpenFile); Idwlog(TEXT("ReadIdwlogCookie: szLineBuffer=>>>%s<<<"), szLineBuffer ); // NO_BUILD_DATA if (NULL != _tcsstr(szLineBuffer, TEXT("NO_BUILD_DATA"))){ lpId->bFindBLDFile = FALSE; b = FALSE; } //ComputerName if (NULL != _tcsstr(szLineBuffer, TEXT("ComputerName"))) _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,lpId->szComputerName); //UserName if (NULL != _tcsstr(szLineBuffer, TEXT("UserName"))) _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,lpId->szUserName ); //DomainName if (NULL != _tcsstr(szLineBuffer, TEXT("DomainName"))) _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,lpId->szUserDomain ); //SystemBuild else if( NULL != _tcsstr (szLineBuffer, TEXT("SystemBuild ") )){ _stscanf(szLineBuffer,TEXT("%s %lu"),szDontCare,&dw); lpId->dwSystemBuild = dw; dw = 0; } //SystemBuildDelta else if( NULL != _tcsstr (szLineBuffer, TEXT("SystemBuildDelta ") )){ _stscanf(szLineBuffer,TEXT("%s %lu"),szDontCare, &dw); lpId->dwSystemBuildDelta = dw; dw = 0; } //SystemSPBuild else if( NULL != _tcsstr (szLineBuffer, TEXT("SystemSPBuild ") )){ _stscanf(szLineBuffer,TEXT("%s %lu"),szDontCare, &dw); lpId->dwSystemSPBuild = dw; dw = 0; } //SystemBuildLocation else if( NULL != _tcsstr (szLineBuffer, TEXT("SystemBuildLocation ") )) _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,lpId->szSystemBuildSourceLocation); //InstallingBuild else if( NULL != _tcsstr (szLineBuffer, TEXT("InstallingBuild ") )){ _stscanf(szLineBuffer,TEXT("%s %lu"),szDontCare,&dw); lpId->dwInstallingBuild = dw; dw = 0; } //InstallingBuildDelta else if( NULL != _tcsstr (szLineBuffer, TEXT("InstallingBuildDelta") )){ _stscanf(szLineBuffer,TEXT("%s %lu"),szDontCare,&dw); lpId->dwInstallingBuildDelta = dw; dw = 0; } //InstallingSPBuild else if( NULL != _tcsstr (szLineBuffer, TEXT("InstallingSPBuild") )){ _stscanf(szLineBuffer,TEXT("%s %lu"),szDontCare,&dw); lpId->dwInstallingSPBuild = dw; dw = 0; } //InstallingBuildLocation else if( NULL != _tcsstr (szLineBuffer, TEXT("InstallingBuildLocation") )) _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,lpId->szInstallingBuildSourceLocation); // MachineID else if(NULL != _tcsstr(szLineBuffer, TEXT("MachineID"))){ _stscanf(szLineBuffer,TEXT("%s %lu"),szDontCare,&dw); lpId->dwMachineID = dw; dw = 0; } // Sku else if(NULL != _tcsstr(szLineBuffer, TEXT("Sku"))){ _stscanf(szLineBuffer,TEXT("%s %lu"),szDontCare,&dw); lpId->dwSku = dw; dw = 0; } // Get the server. This prevents server serparation. else if(NULL != _tcsstr(szLineBuffer, TEXT("IdwlogServer"))) _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,lpId->szIdwlogServer); // Cdrom else if(NULL != _tcsstr(szLineBuffer, TEXT("Cdrom"))){ _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,szResponse); if(szResponse[0] == TEXT('Y')) lpId->bCdrom = TRUE; else lpId->bCdrom = FALSE; } // Network else if(NULL != _tcsstr(szLineBuffer, TEXT("Network"))){ _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,szResponse); if(szResponse[0] == TEXT('Y')) lpId->bNetwork = TRUE; else lpId->bNetwork = FALSE; } // Type else if(NULL != _tcsstr(szLineBuffer, TEXT("Type"))){ _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,szResponse); if(szResponse[0] == TEXT('C')){ lpId->bClean = TRUE; lpId->bUpgrade = FALSE; } else{ lpId->bClean = FALSE; lpId->bUpgrade = TRUE; } } // Msi else if(NULL != _tcsstr(szLineBuffer, TEXT("Msi"))){ _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,szResponse); if(szResponse[0] == TEXT('Y')) lpId->bMsi = TRUE; else lpId->bMsi = FALSE; } // SP Method (of install) // else { Idwlog(TEXT("compare: >>>%s<<<\n"), szLineBuffer ); if( _tcsstr(szLineBuffer, TEXT("SPMethod"))){ _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,szResponse); if(szResponse[0] == TEXT('R')) // uninstall/remove lpId->bSPUninst = TRUE; else lpId->bSPUninst = FALSE; if(szResponse[0] == TEXT('P')) // patch lpId->bSPPatch = TRUE; else lpId->bSPPatch = FALSE; if(szResponse[0] == TEXT('F')) // full (winnt32) lpId->bSPFull = TRUE; else lpId->bSPFull = FALSE; if(szResponse[0] == TEXT('U')) // update lpId->bSPUpdate = TRUE; else lpId->bSPUpdate = FALSE; Idwlog(TEXT("read-in values: bSPUninst = %d, bSPPatch = %d, bSPFull = %d, bSPUpdate = %d\n"), lpId->bSPUninst, lpId->bSPPatch, lpId->bSPFull, lpId->bSPUpdate ); } // OEMImage else if(NULL != _tcsstr(szLineBuffer, TEXT("OEMImage"))){ _stscanf(szLineBuffer,TEXT("%s %s"),szDontCare,szResponse); if(szResponse[0] == TEXT('Y')) lpId->bOEMImage = TRUE; else lpId->bOEMImage = FALSE; } } } while( 0 == feof(fpOpenFile) ); CloseCookieFile( fpOpenFile ); } return b; } BOOL ServerWriteMinimum (LPINSTALL_DATA pId, LPMACHINE_DETAILS pMd) /*++ Author: Wally Ho (wallyho) Jan 31st, 2000 Routine Description: This writes a *.2 file when we cannot find a *.1. There isn't any data in this one as its only the title we care about build and machine. This should catch all the CD installs that don't have a *.1 file written. Ie. Its run from setuploader. Arguments: Return Value: NONE --*/ { //TCHAR szServerData[4096]; BOOL bReturn; Idwlog(TEXT("Entered ServerWriteMinimum.\n")); GetNTSoundInfo(pMd); // If we are doing an OEMImage, we NEVER want to say that it was from a CDBOOT. // if ( pId->bOEMImage ) { // OEMImage // _stprintf (g_szServerData, TEXT("OEMImage:YES\r\n") ); } else { // CDBootInstall // _stprintf (g_szServerData, TEXT("CDBootInstall:%s\r\n"), pId->bCDBootInstall? TEXT("YES") : TEXT("NO")); // OEMImage // _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("OEMImage:NO\r\n") ); } // Installed Build _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuild:%lu\r\n"), pId->dwInstallingBuild); // Installed Build Major _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuildMajor:%lu\r\n"), pId->dwInstallingMajorVersion); // Installed Build Minor _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuildMinor:%lu\r\n"), pId->dwInstallingMinorVersion); // Installed Build Delta _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuildDelta:%lu\r\n"), pId->dwInstallingBuildDelta); // same as above but different name for backend _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingSPBuild:%lu\r\n"), pId->dwInstallingSPBuild); // Installed Build Location _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuildLocation:%s\r\n"), pId->szInstallingBuildSourceLocation); // MachineId _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("MachineID:%0.9lu\r\n"), pId->dwMachineID); //UserName _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Username:%s\r\n"),pId->szUserName); _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Platform:%s\r\n"),pId->szPlatform); // Ram _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("RAM:%lu\r\n"),pMd->dwPhysicalRamInMB); // Architeture _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Arch:%s\r\n"), pId->szArch); // Num Processors _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("NumProcs:%lu\r\n"), pMd->dwNumberOfProcessors); // Video Information _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Vidinfo:%s\r\n"),pMd->szVideoInfo); // Display Name _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("VidDriver:%s\r\n"), pMd->szVideoDisplayName); // Locale _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Locale:%s\r\n"), pId->szLocaleId ); // Sound Card _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Sound:%s\r\n"), pMd->iNumWaveOutDevices? pMd->szWaveDriverName[0] : TEXT("NONE") ); // Network Cards. _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("NetCards:%s\r\n"),pMd->szNetcards); // Is ACPI _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("ACPI:%d\r\n"),pMd->bACPI); //Is PcCard? _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("PCMCIA:%d\r\n"), pMd->bPCCard); // Stepping Level of the proccessor _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("CPU:%lu\r\n"), pMd->dwProcessorLevel); // Scsi _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("SCSI:%s\r\n"), pMd->szScsi); // Is Usb? _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("USB:%d\r\n"), pMd->bUSB); // Is Infrared? _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Infrared:%d\r\n"),pMd->bIR); // Modem _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Modem:%s\r\n"), pMd->szModem); // Is Hydra _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Hydra:%d\r\n"), pId->bHydra); // Number of Displays _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Displays:%d\r\n"), pMd->iNumDisplays); // Sku _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Sku:%lu\r\n"),pId->dwSku); Idwlog(TEXT("pId->dwSku = %ld\n"), pId->dwSku); bReturn = WriteDataToAvailableServer(pId, g_szServerData); return bReturn; } BOOL ServerWriteMaximum (LPINSTALL_DATA pId, LPMACHINE_DETAILS pMd) /*++ Author: Wally Ho (wallyho) Jan 31st, 2000 Routine Description: This does the connection to the server machine and then uploads the file. This is the Maximal data case. Arguments: Return Value: TRUE for success and FALSE for 15 minute time out for servers. Try again when rebooting. --*/ { //TCHAR g_szServerData[4096]; BOOL bReturn; Idwlog(TEXT("Entered ServerWriteMaximum.\n")); //wsprintf only accepts 1k buffers. // Wallyho's Addition. I'm going to split it into separate // calls to make sure above is true. It also makes it easier // to read. :-) // OEMImage // if ( pId->bOEMImage ) { _stprintf (g_szServerData, TEXT("OEMImage:YES\r\n") ); } else { _stprintf (g_szServerData, TEXT("OEMImage:NO\r\n") ); } // MachineId _stprintf (g_szServerData, TEXT("MachineID:%0.9lu\r\n"), pId->dwMachineID); // System Build _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("SystemBuild:%lu\r\n"), pId->dwSystemBuild); // System Build Major _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("SystemBuildMajor:%lu\r\n"), pId->dwSystemMajorVersion); // System Build Minor _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("SystemBuildMinor:%lu\r\n"), pId->dwSystemMinorVersion); // System Build Delta _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("SystemBuildDelta:%lu\r\n"), pId->dwSystemBuildDelta); // same as above, but just different name for backend processing. _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("SystemSPBuild:%lu\r\n"), pId->dwSystemSPBuild); // System Build Location _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("SystemBuildLocation:%s\r\n"), pId->szSystemBuildSourceLocation); // Installed Build _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuild:%lu\r\n"), pId->dwInstallingBuild); // Installed Build Major _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuildMajor:%lu\r\n"), pId->dwInstallingMajorVersion); // Installed Build Minor _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuildMinor:%lu\r\n"), pId->dwInstallingMinorVersion); // Installed Build Delta _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuildDelta:%lu\r\n"), pId->dwInstallingBuildDelta); // same as above but different name for backend processing _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingSPBuild:%lu\r\n"), pId->dwInstallingSPBuild); // Installed Build Location _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("InstallingBuildLocation:%s\r\n"), pId->szInstallingBuildSourceLocation); // Source Media _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Source Media:%s\r\n"),pId->bCdrom? TEXT("C"): TEXT("N")); // Upgrade _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Type:%s\r\n"), pId->bUpgrade? TEXT("U"):TEXT("C")); // Sku _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Sku:%lu\r\n"),pId->dwSku); //UserName _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Username:%s\r\n"),pId->szUserName); // Ram _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("RAM:%lu\r\n"),pMd->dwPhysicalRamInMB); //PlatForm _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Platform:%s\r\n"),pId->szPlatform); // Architeture _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Arch:%s\r\n"), pId->szArch); // Num Processors _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("NumProcs:%lu\r\n"), pMd->dwNumberOfProcessors); // Video Information _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Vidinfo:%s\r\n"),pMd->szVideoInfo); // Display Name _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("VidDriver:%s\r\n"), pMd->szVideoDisplayName); // Locale _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Locale:%s\r\n"), pId->szLocaleId ); // Sound Card _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Sound:%s\r\n"), pMd->iNumWaveOutDevices? pMd->szWaveDriverName[0] : TEXT("NONE") ); // Network Cards. _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("NetCards:%s\r\n"),pMd->szNetcards); // Is ACPI _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("ACPI:%d\r\n"),pMd->bACPI); //Is PcCard? _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("PCMCIA:%d\r\n"), pMd->bPCCard); // Stepping Level of the proccessor _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("CPU:%lu\r\n"), pMd->dwProcessorLevel); // Scsi _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("SCSI:%s\r\n"), pMd->szScsi); // Is Usb? _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("USB:%d\r\n"), pMd->bUSB); // Is Infrared? _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Infrared:%d\r\n"),pMd->bIR); // Modem _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Modem:%s\r\n"), pMd->szModem); // Is Hydra _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Hydra:%d\r\n"), pId->bHydra); // Number of Displays _stprintf (g_szServerData+_tcsclen(g_szServerData), TEXT("Displays:%d\r\n"), pMd->iNumDisplays); // Is Msi? _stprintf (g_szServerData + _tcsclen(g_szServerData), TEXT("MSI:%s\r\n"), pId->bMsi? TEXT("Y") : TEXT("N") ); // Is SP uninst ? if ( pId->bSPUninst ) { _stprintf (g_szServerData + _tcsclen(g_szServerData), TEXT("SPMethod:%s\r\n"), TEXT("REMOVE") ); Idwlog(TEXT("ServerWriteMaximum - SPMethod:UNINSTALL\n")); } // Is SP Patching? if ( pId->bSPPatch ) { _stprintf (g_szServerData + _tcsclen(g_szServerData), TEXT("SPMethod:%s\r\n"), TEXT("PATCH") ); Idwlog(TEXT("ServerWriteMaximum - SPMethod:PATCH\n")); } // Is SP Full ? if ( pId->bSPFull ) { _stprintf (g_szServerData + _tcsclen(g_szServerData), TEXT("SPMethod:%s\r\n"), TEXT("FULL") ); Idwlog(TEXT("ServerWriteMaximum - SPMethod:FULL\n")); } // Is SP Update ? if ( pId->bSPUpdate ) { _stprintf (g_szServerData + _tcsclen(g_szServerData), TEXT("SPMethod:%s\r\n"), TEXT("UPDATE") ); Idwlog(TEXT("ServerWriteMaximum - SPMethod:UPDATE\n")); } bReturn = WriteDataToAvailableServer(pId, g_szServerData); return bReturn; } BOOL WriteDataToAvailableServer (LPINSTALL_DATA pId, LPTSTR g_szServerData) /*++ Author: Wally W. Ho (wallyho) Date: 5/22/2000 Routine Description: This routines allows us to time out a write operation so that bad network access won't hold us up. Arguments: LPINSTALL_DATA pId LPTSTR g_szServerData Return Value: TRUE for success. FALSE for failure. --*/ { DWORD dw; DWORD dwTimeOut; HANDLE hThrd; DWORD dwTimeOutInterval; DWORD dwExitCode; BOOL b; //__________________________________________________________________________ // This will stop the probing after say 10 minutes of probing. // Or when it succeeds. #ifdef TTEST Idwlog(TEXT("Entered WriteDataToAvailableServer().\n")); pId->szServerData = g_szServerData; b = WriteThread ( pId ); Idwlog(TEXT("Exiting WriteDataToAvailableServer() with b = %d.\n"), b ); return ( b ); #endif TTEST pId->szServerData = g_szServerData; hThrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteThread, (LPINSTALL_DATA) pId, 0, &dw); // This is in milli seconds so 10 * factor is 10 minutes. dwTimeOutInterval = 10 * (1000 * 60); dwTimeOut = WaitForSingleObject (hThrd, dwTimeOutInterval); // This means the server passed the timeout. if (dwTimeOut == WAIT_TIMEOUT){ // Exit the thread if(FALSE == GetExitCodeThread(hThrd,&dwExitCode)) Idwlog(TEXT("Failed to get the exit code for the write thread.\n")); else{ // // Don't terminate the thread // //TerminateThread(hThrd, dwExitCode); Idwlog(TEXT("Timeout Write Thread: %lu \n"), hThrd); } Idwlog(TEXT("Tried all servers we are concluding after 10 minutes elapsed!.\n")); Idwlog(TEXT("Leaving shortcut, idwlog.exe and cookie available for next reboot.\n")); Idwlog(TEXT("Ending connection to server.\n")); //Leaving everything in place so that a reboot will catch this. CloseHandle (hThrd); return FALSE; } CloseHandle (hThrd); Idwlog(TEXT("Ending connection to server.\n")); return TRUE; //__________________________________________________________________________ } DWORD WINAPI WriteThread(IN LPINSTALL_DATA pId) /*++ Author: Wally W. Ho (wallyho) Date: 2/22/2000 Routine Description: This routine finds the best server to write the data package to. Arguments: LPINSTALL_DATA Return Value: TRUE or FALSE as thread exit codes. --*/ { BOOL bRet; UINT iAttempts; DWORD Actual; DWORD Size; BOOL bWrite = TRUE; HANDLE hWrite = INVALID_HANDLE_VALUE; TCHAR szInstallingBuild [20]; TCHAR szIdwlogUniqueName [ MAX_PATH ]; BOOL b; Idwlog(TEXT("Entered WriteThread().\n")); // Build the name for the file. // ie \\ntcore2\idwlog\computername2195.1 if ( 0 == pId->dwInstallingBuild) _stprintf (szInstallingBuild, TEXT("latest")); else _stprintf (szInstallingBuild, TEXT("%lu"), pId->dwInstallingBuild); // In the 1st case we enter this routine with no known server. // In the second case we get the server from the cookie. // So we should try to see if that server works before // probing. if (TEXT('\0') == pId->szIdwlogServer[0]) b = FALSE; else { SERVERS sb; _tcscpy(sb.szSvr, pId->szIdwlogServer ); b = (BOOL) ServerOnlineThread( &sb); } // This is the retry Loop!> // We'll try the found server 5 times with 5 second spacing. // Then we'll query the server list again and try that server // Do until we get on pausing 1 second between #define NUM_TRIES 5 Idwlog(TEXT("WriteThread - Starting retry loop.\n")); while (TRUE) { if ( FALSE == b ) { pId->bIsServerOnline = FALSE; iAttempts = 0; while (pId->bIsServerOnline == FALSE && iAttempts < NUM_TRIES) { Idwlog(TEXT("WriteThread - SERVER Attempt %d just before IsServerOnLine()\n"), iAttempts); IsServerOnline( pId ); Idwlog(TEXT("WriteThread - after IsServerOnLine(), pId->bIsServerOnLine = %d\n"), pId->bIsServerOnline ); // Wait for 2 seconds between server tries. Sleep( 2 * (1000) ); iAttempts++; // We are going to end here if we can find all the servers in 5 tries. // if ( iAttempts >= NUM_TRIES ) { Idwlog(TEXT("WriteThread ERROR - After %d attempts, we are quitting since we coundn't find a Server.\n"), iAttempts); return (FALSE); } } Idwlog(TEXT("WriteThread - after the while loop.\n") ); }else{ Idwlog( TEXT("Server FOUND no probing attempted.\n") ); pId->bIsServerOnline = TRUE; } // We've got a server!! // Add the server to the end of the datapackage. if ( pId->bIsServerOnline == TRUE ) { _stprintf (pId->szServerData + _tcslen(pId->szServerData), TEXT("IdwlogServer:%s\r\n"),pId->szIdwlogServer ); // Make sure the file gets written. // Don't want stoppage by bandwidth constriction etc.. // Make 3 hits on the same server. iAttempts = 0; bRet = FALSE; while (bRet == FALSE && iAttempts < 3) { _stprintf (szIdwlogUniqueName, TEXT("%s\\%s-%lu-%s.%d"), pId->szIdwlogServer, szInstallingBuild, pId->dwMachineID, pId->szComputerName, pId->iStageSequence); hWrite = CreateFile( szIdwlogUniqueName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL ); if (INVALID_HANDLE_VALUE != hWrite) { // We have a handle to a active server. // Upload the package. SetFilePointer( hWrite, 0, NULL, FILE_END ); Size = _tcsclen( pId->szServerData ); bRet = WriteFile( hWrite, pId->szServerData, Size, &Actual, NULL ); if (FALSE == bRet) { Idwlog(TEXT("FILE Attempt %d: Writing data package to Servershare: %s failed! Last Error is %lu\n"), iAttempts + 1, pId->szIdwlogServer, GetLastError()); } // Flush the buffers to make sure its all makes it to the drive. FlushFileBuffers(hWrite); // wait 3 seconds between attempts Sleep(3000); CloseHandle(hWrite ); }else Idwlog(TEXT("FILE Attempt %d: Failed in trying to directly write the file: %s."), iAttempts + 1, szIdwlogUniqueName); iAttempts++; } if (FALSE == bRet && iAttempts >= 3 ) { Idwlog(TEXT("After %d FILE attempts, still could not write to Servershare: %s! Last Error is %lu.\n"), iAttempts, pId->szIdwlogServer, GetLastError()); WhatErrorMessage(GetLastError()); Idwlog(TEXT("We will try the same server a second time.\n")); Idwlog(TEXT("The servers will be enumerated again at 10 second intervals.\n")); // // Wait for 10 seconds between server tries. Sleep( 10 * ( 1000 ) ); // Means server was not found. Try to find another server. // Get the Server that is online. pId->bIsServerOnline = FALSE; } else { Idwlog(TEXT("Writing data package to Servershare: %s Succeeded.\n"), pId->szIdwlogServer); break; } } b = FALSE; } // Delete all the known connections. DeleteIPCConnections(); Idwlog(TEXT("Exiting WriteThread() with return of TRUE.\n")); return TRUE; } VOID DeleteIPCConnections( VOID ) /*++ Copyright (c) 2000, Microsoft. Author: Wally W. Ho (wallyho) Date: 12/5/2000 Routine Description: This function will delete all the IPC$ NULL net authentications Arguments: NONE Return Value: NONE --*/ { TCHAR szRemoteName [MAX_PATH]; for (INT i = 0; i < sizeof(g_ServerBlock) / sizeof(SERVERS); i++){ // RemoteName is the server name alone without the share. // pServerBlock->szSvr comes in as \\idwlog\idwlogwhstl // make it idwlog only.. _tcscpy(szRemoteName, g_ServerBlock[i].szSvr); *_tcsrchr(szRemoteName,TEXT('\\')) = TEXT('\0'); // make sure it always disconnnected _tcscat(szRemoteName,TEXT("\\IPC$")); WNetCancelConnection2( szRemoteName, 0, TRUE); } } /* //_______________ // Setup the memory for the connection. // Try This Connection then try the file probe. // This will log us onto the service to make it work. // RemoteName is the server name along without the share. // szIdwlogServer comes in as \\idwlog\idwlogwhstl // make is idwlog only.. _tcscpy(szRemoteName,pId->szIdwlogServer); pRemoteName = szRemoteName; pRemoteName = pRemoteName + 2; l = pRemoteName; //*_tcsrchr(pRemoteName,TEXT('\\')) = TEXT('\0'); Idwlog(TEXT("Remote name is %s.\n"), szRemoteName); // if the drive is being used shut it down so we can use it. // WNetCancelConnection2( DRIVE_LETTER_TO_SHARE, CONNECT_UPDATE_PROFILE, TRUE ); ZeroMemory( &NetResource, sizeof( NetResource ) ); NetResource.dwType = RESOURCETYPE_DISK ; NetResource.lpLocalName = DRIVE_LETTER_TO_SHARE; NetResource.lpRemoteName = szRemoteName; NetResource.lpProvider = NULL; _stprintf(szUserId,TEXT("%s\\guest"),szRemoteName); // First, try to connect with the current user ID if (NO_ERROR != ( dwError = WNetAddConnection2( &NetResource, NULL, NULL, 0 )) ){ Idwlog(TEXT("WNetAddConnection2 FAILED with ID = NULL and PWD = NULL.\n")); // Second, try to connect with idwuser as user and pw. if ( NO_ERROR != ( dwError = WNetAddConnection2( &NetResource, NULL, szUserId, 0 )) ) Idwlog(TEXT("WNetAddConnection2 FAILED using authentication credentials on %s. Error %lu.\n"), pId->szIdwlogServer, dwError); } if ( NO_ERROR == dwError ) Idwlog(TEXT("WNetAddConnection2 successfully connected.\n")); //_______________ // ie \\idwlog\idwlog\2195-MachineId-ComputerName.1 _stprintf (szIdwlogUniqueName, TEXT("%s\\%s-%lu-%s.%d"), pId->szIdwlogServer,// DRIVE_LETTER_TO_SHARE, szInstallingBuild, pId->dwMachineID, pId->szComputerName, pId->iStageSequence); hWrite = CreateFile( szIdwlogUniqueName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL ); */ VOID DeleteDatafile (LPINSTALL_DATA pId) /*++ Copyright (c) 2000, Microsoft. Author: Wally W. Ho (wallyho) Date: 8/23/2000 Routine Description: Deletes the file from the server if the user cancels it. Arguments: Data Structure. Return Value: NONE --*/ { TCHAR szFileToDelete[MAX_PATH]; TCHAR szInstallingBuild [20]; TCHAR szServerData[ 200 ]; HANDLE hWrite; BOOL bRet; DWORD dwActual; /* Wallyho: This isn't a trivial problem. Why? Its because I've multithreaded the probing. So we have to check if both the idwlog.exe is running if so kill it. If it writes the Idwlog Cookie then we know it finished. So we have to stop it. The only way is to use a mutex. Which we check. This is just a piece of memory that sits in kernel space or simply its the global space of the computer. We check if its there at the end if so we delete both the cookie and the file off the server. This is the best way I can think of to do this as we have no idea where the file is being written. Two cases occur: 1. If the process writing the file has not finished. We set a mutex in the cancel. Which this checks for. If set we delete the file and the cookie. 2. If the process writing the file is passed the last check then we cannot delete the file in the first process. We then read the cookie for the server. We go to that server and delete the file. Then we delete the cookie and finally the mutex. */ // // If there is no IdwlogServer data, there is nothing to delete // if (NULL == pId->szIdwlogServer || 0 != _tcsncmp(pId->szIdwlogServer, TEXT("\\\\"), 2)) { return; } if ( 0 == pId->dwInstallingBuild) _stprintf (szInstallingBuild, TEXT("latest")); else _stprintf (szInstallingBuild, TEXT("%lu"), pId->dwInstallingBuild); // ie \\ntcore2\idwlog\2195-MachineId-Computername.1 _stprintf (szFileToDelete, TEXT("%s\\%s-%lu-%s.%d"), pId->szIdwlogServer, szInstallingBuild, pId->dwMachineID, pId->szComputerName, pId->iStageSequence); Idwlog(TEXT("File deleted is: %s"), szFileToDelete); SetFileAttributes(szFileToDelete,FILE_ATTRIBUTE_NORMAL); if (TRUE == FileExistsEx(szFileToDelete)) { DeleteFile( szFileToDelete); } else{ szFileToDelete[_tcslen(szFileToDelete) -1] = TEXT('0'); // If we succeed in deleting the file, then don't write a 0. //Create the *.0 file. hWrite = CreateFile( szFileToDelete, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL ); if ( hWrite == INVALID_HANDLE_VALUE ) { Idwlog(TEXT("Problems creating the %lu delete file."), pId->iStageSequence ); } else { // Upgrade: This we need for the timeout in the 0 files _stprintf ( szServerData, TEXT("Type:%s\r\n"), pId->bUpgrade? TEXT("U"):TEXT("C")); bRet = WriteFile( hWrite, szServerData, _tcsclen( szServerData ), &dwActual, NULL ); CloseHandle(hWrite); } } } BOOL SetCancelMutex ( VOID ) /*++ Author: wallyho Routine Description: Arguments: Return Value: --*/ { g_hCancelMutex = CreateMutex( NULL,TRUE, TEXT("IdwlogCancelMutex")); if (g_hCancelMutex == NULL){ Idwlog(TEXT("Could not set mutex.\n")); return FALSE; }else{ Idwlog(TEXT("Mutex set.\n")); return TRUE; } } BOOL ClearCancelMutex ( VOID ) /*++ Author: wallyho Routine Description: Arguments: Return Value: --*/ { if (FALSE == ReleaseMutex(g_hCancelMutex)){ Idwlog(TEXT("Problems releasing cancel mutex.\n")); return TRUE; } else{ Idwlog(TEXT("Released cancel mutex.\n")); return FALSE; } } BOOL PauseForMutex(VOID ) /*++ Author: wallyho Routine Description: This checks a mutex by opening it. we put in the systems global space or as better know the "kernel space". This way the separate processes can synchronize and delete file in case of canceling. Since we randomly find servers online we have no way of finding out what is available or not. We will wait till the cookie is complete and then we delete. Arguments: Return Value: FALSE Immediately if we don't find the mutex. FALSE after we wait for the mutex. --*/ { HANDLE hOpenMutex; hOpenMutex = OpenMutex( MUTEX_ALL_ACCESS, FALSE, TEXT("IdwlogCancelMutex") ); if (hOpenMutex == NULL){ // Idwlog(TEXT("Mutex turned off already. Lets look for the cookie.\n")); return FALSE; }else{ Idwlog(TEXT("Have to wait on -1 to finish then completing cancel.\n")); WaitForSingleObject(hOpenMutex,60000 /* Up to 1 minute wait*/); Idwlog(TEXT("Finished waiting. Continuing....\n")); return FALSE; } } BOOL SetInstanceMutex ( VOID ) /*++ Author: wallyho Routine Description: Arguments: Return Value: TRUE if exists. --*/ { g_hInstanceMutex = CreateMutex( NULL,TRUE, TEXT("IdwlogInstanceMutex")); if (g_hInstanceMutex == NULL){ return FALSE; }else{ if (ERROR_ALREADY_EXISTS == GetLastError()) return TRUE; else return FALSE; } } BOOL ClearInstanceMutex ( VOID ) /*++ Author: wallyho Routine Description: Arguments: Return Value: --*/ { if (FALSE == ReleaseMutex(g_hInstanceMutex)){ Idwlog(TEXT("Problems releasing cancel mutex.\n")); return TRUE; } else{ Idwlog(TEXT("Released cancel mutex.\n")); return FALSE; } } BOOL FileExistsEx( IN LPTSTR szFileName) /*++ Copyright (c) 2000, Microsoft. Author: Wally W. Ho (wallyho) Date: 8/7/2000 Routine Description: This test the existence of a partially matching FileName. Arguments: NONE Return Value: SUCCESS TRUE FAIL FALSE --*/ { HANDLE hFile = INVALID_HANDLE_VALUE; WIN32_FIND_DATA W32FD; hFile = FindFirstFile(szFileName, &W32FD); if( INVALID_HANDLE_VALUE == hFile ){ return FALSE; }else{ FindClose(hFile); return TRUE; } }