mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			93 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "windows.h"
 | 
						|
#include "msiquery.h"
 | 
						|
 | 
						|
/* Print a debug message to the installer log file.
 | 
						|
 * To see the debug messages, install with
 | 
						|
 * msiexec /i pythonxy.msi /l*v python.log
 | 
						|
 */
 | 
						|
static UINT debug(MSIHANDLE hInstall, LPCSTR msg)
 | 
						|
{
 | 
						|
	MSIHANDLE hRec = MsiCreateRecord(1);
 | 
						|
	if (!hRec || MsiRecordSetStringA(hRec, 1, msg) != ERROR_SUCCESS) {
 | 
						|
		return ERROR_INSTALL_FAILURE;
 | 
						|
	}
 | 
						|
	MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRec);
 | 
						|
	MsiCloseHandle(hRec);
 | 
						|
	return ERROR_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/* Check whether the TARGETDIR exists and is a directory.
 | 
						|
 * Set TargetExists appropriately.
 | 
						|
 */
 | 
						|
UINT __declspec(dllexport) __stdcall CheckDir(MSIHANDLE hInstall)
 | 
						|
{
 | 
						|
#define PSIZE 1024
 | 
						|
	WCHAR wpath[PSIZE];
 | 
						|
	char path[PSIZE];
 | 
						|
	UINT result;
 | 
						|
	DWORD size = PSIZE;
 | 
						|
	DWORD attributes;
 | 
						|
 | 
						|
	
 | 
						|
	result = MsiGetPropertyW(hInstall, L"TARGETDIR", wpath, &size);
 | 
						|
	if (result != ERROR_SUCCESS)
 | 
						|
		return result;
 | 
						|
	wpath[size] = L'\0';
 | 
						|
	path[size] = L'\0';
 | 
						|
 | 
						|
	attributes = GetFileAttributesW(wpath);
 | 
						|
	if (attributes == INVALID_FILE_ATTRIBUTES ||
 | 
						|
		!(attributes & FILE_ATTRIBUTE_DIRECTORY)) 
 | 
						|
	{
 | 
						|
		return MsiSetPropertyA(hInstall, "TargetExists", "0");
 | 
						|
	} else {
 | 
						|
		return MsiSetPropertyA(hInstall, "TargetExists", "1");
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/* Update the state of the REGISTRY.tcl component according to the
 | 
						|
 * Extension and TclTk features. REGISTRY.tcl must be installed
 | 
						|
 * if both features are installed, and must be absent otherwise.
 | 
						|
 */
 | 
						|
UINT __declspec(dllexport) __stdcall UpdateEditIDLE(MSIHANDLE hInstall)
 | 
						|
{
 | 
						|
	INSTALLSTATE ext_old, ext_new, tcl_old, tcl_new, reg_new;
 | 
						|
	UINT result;
 | 
						|
 | 
						|
	result = MsiGetFeatureStateA(hInstall, "Extensions", &ext_old, &ext_new);
 | 
						|
	if (result != ERROR_SUCCESS)
 | 
						|
		return result;
 | 
						|
	result = MsiGetFeatureStateA(hInstall, "TclTk", &tcl_old, &tcl_new);
 | 
						|
	if (result != ERROR_SUCCESS)
 | 
						|
		return result;
 | 
						|
 | 
						|
	/* If the current state is Absent, and the user did not select
 | 
						|
	   the feature in the UI, Installer apparently sets the "selected"
 | 
						|
	   state to unknown. Update it to the current value, then. */
 | 
						|
	if (ext_new == INSTALLSTATE_UNKNOWN)
 | 
						|
		ext_new = ext_old;
 | 
						|
	if (tcl_new == INSTALLSTATE_UNKNOWN)
 | 
						|
		tcl_new = tcl_old;
 | 
						|
 | 
						|
	// XXX consider current state of REGISTRY.tcl?
 | 
						|
	if (((tcl_new == INSTALLSTATE_LOCAL) ||
 | 
						|
		 (tcl_new == INSTALLSTATE_SOURCE) ||
 | 
						|
		 (tcl_new == INSTALLSTATE_DEFAULT)) &&
 | 
						|
		((ext_new == INSTALLSTATE_LOCAL) ||
 | 
						|
		 (ext_new == INSTALLSTATE_SOURCE) ||
 | 
						|
		 (ext_new == INSTALLSTATE_DEFAULT))) {
 | 
						|
		reg_new = INSTALLSTATE_SOURCE;
 | 
						|
	} else { 
 | 
						|
		reg_new = INSTALLSTATE_ABSENT;
 | 
						|
	}
 | 
						|
	result = MsiSetComponentStateA(hInstall, "REGISTRY.tcl", reg_new);
 | 
						|
	return result;
 | 
						|
}
 | 
						|
 | 
						|
BOOL APIENTRY DllMain(HANDLE hModule, 
 | 
						|
                      DWORD  ul_reason_for_call, 
 | 
						|
                      LPVOID lpReserved)
 | 
						|
{
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 |