| #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; |
| } |
| |