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 |
|
---|