|
1 #include "windows.h" |
|
2 #include "msiquery.h" |
|
3 |
|
4 /* Print a debug message to the installer log file. |
|
5 * To see the debug messages, install with |
|
6 * msiexec /i pythonxy.msi /l*v python.log |
|
7 */ |
|
8 static UINT debug(MSIHANDLE hInstall, LPCSTR msg) |
|
9 { |
|
10 MSIHANDLE hRec = MsiCreateRecord(1); |
|
11 if (!hRec || MsiRecordSetStringA(hRec, 1, msg) != ERROR_SUCCESS) { |
|
12 return ERROR_INSTALL_FAILURE; |
|
13 } |
|
14 MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRec); |
|
15 MsiCloseHandle(hRec); |
|
16 return ERROR_SUCCESS; |
|
17 } |
|
18 |
|
19 /* Check whether the TARGETDIR exists and is a directory. |
|
20 * Set TargetExists appropriately. |
|
21 */ |
|
22 UINT __declspec(dllexport) __stdcall CheckDir(MSIHANDLE hInstall) |
|
23 { |
|
24 #define PSIZE 1024 |
|
25 WCHAR wpath[PSIZE]; |
|
26 char path[PSIZE]; |
|
27 UINT result; |
|
28 DWORD size = PSIZE; |
|
29 DWORD attributes; |
|
30 |
|
31 |
|
32 result = MsiGetPropertyW(hInstall, L"TARGETDIR", wpath, &size); |
|
33 if (result != ERROR_SUCCESS) |
|
34 return result; |
|
35 wpath[size] = L'\0'; |
|
36 path[size] = L'\0'; |
|
37 |
|
38 attributes = GetFileAttributesW(wpath); |
|
39 if (attributes == INVALID_FILE_ATTRIBUTES || |
|
40 !(attributes & FILE_ATTRIBUTE_DIRECTORY)) |
|
41 { |
|
42 return MsiSetPropertyA(hInstall, "TargetExists", "0"); |
|
43 } else { |
|
44 return MsiSetPropertyA(hInstall, "TargetExists", "1"); |
|
45 } |
|
46 } |
|
47 |
|
48 /* Update the state of the REGISTRY.tcl component according to the |
|
49 * Extension and TclTk features. REGISTRY.tcl must be installed |
|
50 * if both features are installed, and must be absent otherwise. |
|
51 */ |
|
52 UINT __declspec(dllexport) __stdcall UpdateEditIDLE(MSIHANDLE hInstall) |
|
53 { |
|
54 INSTALLSTATE ext_old, ext_new, tcl_old, tcl_new, reg_new; |
|
55 UINT result; |
|
56 |
|
57 result = MsiGetFeatureStateA(hInstall, "Extensions", &ext_old, &ext_new); |
|
58 if (result != ERROR_SUCCESS) |
|
59 return result; |
|
60 result = MsiGetFeatureStateA(hInstall, "TclTk", &tcl_old, &tcl_new); |
|
61 if (result != ERROR_SUCCESS) |
|
62 return result; |
|
63 |
|
64 /* If the current state is Absent, and the user did not select |
|
65 the feature in the UI, Installer apparently sets the "selected" |
|
66 state to unknown. Update it to the current value, then. */ |
|
67 if (ext_new == INSTALLSTATE_UNKNOWN) |
|
68 ext_new = ext_old; |
|
69 if (tcl_new == INSTALLSTATE_UNKNOWN) |
|
70 tcl_new = tcl_old; |
|
71 |
|
72 // XXX consider current state of REGISTRY.tcl? |
|
73 if (((tcl_new == INSTALLSTATE_LOCAL) || |
|
74 (tcl_new == INSTALLSTATE_SOURCE) || |
|
75 (tcl_new == INSTALLSTATE_DEFAULT)) && |
|
76 ((ext_new == INSTALLSTATE_LOCAL) || |
|
77 (ext_new == INSTALLSTATE_SOURCE) || |
|
78 (ext_new == INSTALLSTATE_DEFAULT))) { |
|
79 reg_new = INSTALLSTATE_SOURCE; |
|
80 } else { |
|
81 reg_new = INSTALLSTATE_ABSENT; |
|
82 } |
|
83 result = MsiSetComponentStateA(hInstall, "REGISTRY.tcl", reg_new); |
|
84 return result; |
|
85 } |
|
86 |
|
87 BOOL APIENTRY DllMain(HANDLE hModule, |
|
88 DWORD ul_reason_for_call, |
|
89 LPVOID lpReserved) |
|
90 { |
|
91 return TRUE; |
|
92 } |
|
93 |