windows-nt/Source/XPSP1/NT/sdktools/idwlog/network.cpp

1755 lines
49 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <winver.h>
#include <winnetwk.h>
#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"));
//<Do some minimal task here. To alert? What? I'll think of later.>
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;
//____<Thread Probing >______________________________________________________________________
// 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;
//____<Thread Probing >______________________________________________________________________
}
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"));
// <At this point we could purge the file locally?>
// 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);
}
}
/*
//____<Below is Authentication with guest account probe>___________
// 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"));
//____<Below is File probe>___________
// 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;
}
}