mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
[CMAKE]
- Sync with trunk r51165. svn path=/branches/cmake-bringup/; revision=51166
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* German language file by Daniel Reimer <EmuandCo> 2006-06-15
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
|
||||
IDS_HELP, "Ændringer fil-ACL'er (Access Control List) eller viser dem.\n\n\
|
||||
CACLS Filenavn [/T] [/E] [/C] [/G Bruger:Adgang] [/R Bruger [...]]\n\
|
||||
[/P Bruger:Adgang [...]] [/D Bruger [...]]\n\
|
||||
Filnavn Viser ACL'er for angivet filer.\n\
|
||||
/T Ændre ACL'er for angivene filer i mapper\n\
|
||||
og alle undermapper.\n\
|
||||
/E Bearbejde ACL i stedet for at erstatte.\n\
|
||||
/C Forandre ACL'er ved adgangfejl videre.\n\
|
||||
/G Bruger:Adgang Tillade angivene adgangsformer.\n\
|
||||
Adgang kan være: R læse\n\
|
||||
W skrive\n\
|
||||
C ændre (At skrive)\n\
|
||||
F Fuld adgang\n\
|
||||
/R Bruger Fjerne adgangsrette af brugeren (kun gyldig med /E).\n\
|
||||
/P Bruger:Adgang Erstatte adgangsretterne af brugeren.\n\
|
||||
Adgang kan være: N Ingen\n\
|
||||
R Læse\n\
|
||||
W Skrive\n\
|
||||
C ændre (Skrive)\n\
|
||||
F fuld adgang\n\
|
||||
/D Bruger Forbyde adgang for brugeren.\n\
|
||||
Mellemrum(Wildcards) bliver understøttet i filenavn.\n\
|
||||
Man kan angive flere bruger i en kommando.\n\n\
|
||||
Forkortninger:\n\
|
||||
CI - Container overtagelse.\n\
|
||||
ACE-Bidragen bliver overtaget fra mapperne.\n\
|
||||
OI - Objekt overtagelse.\n\
|
||||
ACE-Bidragen bliver overtaget fra filerne.\n\
|
||||
IO - Kun overtagelse.\n\
|
||||
ACE'ens egenskab passer ikke sammen med\n\
|
||||
de aktuelle filer/mapper.\n"
|
||||
|
||||
IDS_ABBR_CI, "(CI)"
|
||||
IDS_ABBR_OI, "(OI)"
|
||||
IDS_ABBR_IO, "(IO)"
|
||||
IDS_ABBR_FULL, "F"
|
||||
IDS_ABBR_READ, "R"
|
||||
IDS_ABBR_WRITE, "W"
|
||||
IDS_ABBR_CHANGE, "C"
|
||||
IDS_ABBR_NONE, "N"
|
||||
IDS_ALLOW, ""
|
||||
IDS_DENY, "(DENY)"
|
||||
IDS_SPECIAL_ACCESS, "(special access:)"
|
||||
IDS_GENERIC_READ, "GENERIC_READ"
|
||||
IDS_GENERIC_WRITE, "GENERIC_WRITE"
|
||||
IDS_GENERIC_EXECUTE, "GENERIC_EXECUTE"
|
||||
IDS_GENERIC_ALL, "GENERIC_ALL"
|
||||
IDS_FILE_GENERIC_EXECUTE, "FILE_GENERIC_EXECUTE"
|
||||
IDS_FILE_GENERIC_READ, "FILE_GENERIC_READ"
|
||||
IDS_FILE_GENERIC_WRITE, "FILE_GENERIC_WRITE"
|
||||
IDS_FILE_READ_DATA, "FILE_READ_DATA"
|
||||
IDS_FILE_WRITE_DATA, "FILE_WRITE_DATA"
|
||||
IDS_FILE_APPEND_DATA, "FILE_APPEND_DATA"
|
||||
IDS_FILE_READ_EA, "FILE_READ_EA"
|
||||
IDS_FILE_WRITE_EA, "FILE_WRITE_EA"
|
||||
IDS_FILE_EXECUTE, "FILE_EXECUTE"
|
||||
IDS_FILE_DELETE_CHILD, "FILE_DELETE_CHILD"
|
||||
IDS_FILE_READ_ATTRIBUTES, "FILE_READ_ATTRIBUTES"
|
||||
IDS_FILE_WRITE_ATTRIBUTES, "FILE_WRITE_ATTRIBUTES"
|
||||
IDS_MAXIMUM_ALLOWED, "MAXIMUM_ALLOWED"
|
||||
IDS_ACCESS_SYSTEM_SECURITY, "ACCESS_SYSTEM_SECURITY"
|
||||
IDS_SPECIFIC_RIGHTS_ALL, "SPECIFIC_RIGHTS_ALL"
|
||||
IDS_STANDARD_RIGHTS_REQUIRED, "STANDARD_RIGHTS_REQUIRED"
|
||||
IDS_SYNCHRONIZE, "SYNCHRONIZE"
|
||||
IDS_WRITE_OWNER, "WRITE_OWNER"
|
||||
IDS_WRITE_DAC, "WRITE_DAC"
|
||||
IDS_READ_CONTROL, "READ_CONTROL"
|
||||
IDS_DELETE, "DELETE"
|
||||
IDS_STANDARD_RIGHTS_ALL, "STANDARD_RIGHTS_ALL"
|
||||
END
|
||||
@@ -0,0 +1,74 @@
|
||||
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
|
||||
IDS_HELP, "Muestra o modifica la lista de control de accesos (ACLs) de los archivos\n\n\
|
||||
CACLS archivo [/T] [/E] [/C] [/G user:perm [...]] [/R usuario [...]]\n\
|
||||
[/P user:perm [...]] [/D usuario [...]]\n\
|
||||
archivo Mostrar ACLs.\n\
|
||||
/T Cambia ACLs de los archivos especificados en\n\
|
||||
el directorio actual y todos sus subdirectorios.\n\
|
||||
/E Edita la ACL en lugar de reemplazarla.\n\
|
||||
/C Continúa en caso de errores de acceso.\n\
|
||||
/G user:perm Da los derechos de acceso al usuario especificado.\n\
|
||||
Perm puede ser: R Lectura\n\
|
||||
W Escritura\n\
|
||||
C Modificación (Escritura)\n\
|
||||
F Control total\n\
|
||||
/R usuario Revoca los derechos de acceso al usuario especificado (unicamente válido con /E).\n\
|
||||
/P user:perm Reemplaza los derechos de acceso del usuario especificado.\n\
|
||||
Perm puede ser: N Nada\n\
|
||||
R Lectura\n\
|
||||
W Escritura\n\
|
||||
C Modificación (Escritura)\n\
|
||||
F Control total\n\
|
||||
/D usuario Revoca el acceso al usuario especificado.\n\
|
||||
Es posible usar comodines para especificar más de un archivo por comando.\n\
|
||||
Se puede especificar más de un usuario por comando.\n\n\
|
||||
Abreviaciones:\n\
|
||||
CI - Herencia del contenedor.\n\
|
||||
ACE será heredado a los directorios.\n\
|
||||
OI - Herencia del objeto.\n\
|
||||
ACE sera heredado a los archivos.\n\
|
||||
IO - Herencia sola.\n\
|
||||
ACE no se aplicará al archivo/directorio actual.\n"
|
||||
|
||||
IDS_ABBR_CI, "(CI)"
|
||||
IDS_ABBR_OI, "(OI)"
|
||||
IDS_ABBR_IO, "(IO)"
|
||||
IDS_ABBR_FULL, "F"
|
||||
IDS_ABBR_READ, "R"
|
||||
IDS_ABBR_WRITE, "W"
|
||||
IDS_ABBR_CHANGE, "C"
|
||||
IDS_ABBR_NONE, "N"
|
||||
IDS_ALLOW, ""
|
||||
IDS_DENY, "(DENEGA)"
|
||||
IDS_SPECIAL_ACCESS, "(acceso especial:)"
|
||||
IDS_GENERIC_READ, "GENERIC_READ"
|
||||
IDS_GENERIC_WRITE, "GENERIC_WRITE"
|
||||
IDS_GENERIC_EXECUTE, "GENERIC_EXECUTE"
|
||||
IDS_GENERIC_ALL, "GENERIC_ALL"
|
||||
IDS_FILE_GENERIC_EXECUTE, "FILE_GENERIC_EXECUTE"
|
||||
IDS_FILE_GENERIC_READ, "FILE_GENERIC_READ"
|
||||
IDS_FILE_GENERIC_WRITE, "FILE_GENERIC_WRITE"
|
||||
IDS_FILE_READ_DATA, "FILE_READ_DATA"
|
||||
IDS_FILE_WRITE_DATA, "FILE_WRITE_DATA"
|
||||
IDS_FILE_APPEND_DATA, "FILE_APPEND_DATA"
|
||||
IDS_FILE_READ_EA, "FILE_READ_EA"
|
||||
IDS_FILE_WRITE_EA, "FILE_WRITE_EA"
|
||||
IDS_FILE_EXECUTE, "FILE_EXECUTE"
|
||||
IDS_FILE_DELETE_CHILD, "FILE_DELETE_CHILD"
|
||||
IDS_FILE_READ_ATTRIBUTES, "FILE_READ_ATTRIBUTES"
|
||||
IDS_FILE_WRITE_ATTRIBUTES, "FILE_WRITE_ATTRIBUTES"
|
||||
IDS_MAXIMUM_ALLOWED, "MAXIMUM_ALLOWED"
|
||||
IDS_ACCESS_SYSTEM_SECURITY, "ACCESS_SYSTEM_SECURITY"
|
||||
IDS_SPECIFIC_RIGHTS_ALL, "SPECIFIC_RIGHTS_ALL"
|
||||
IDS_STANDARD_RIGHTS_REQUIRED, "STANDARD_RIGHTS_REQUIRED"
|
||||
IDS_SYNCHRONIZE, "SYNCHRONIZE"
|
||||
IDS_WRITE_OWNER, "WRITE_OWNER"
|
||||
IDS_WRITE_DAC, "WRITE_DAC"
|
||||
IDS_READ_CONTROL, "READ_CONTROL"
|
||||
IDS_DELETE, "DELETE"
|
||||
IDS_STANDARD_RIGHTS_ALL, "STANDARD_RIGHTS_ALL"
|
||||
END
|
||||
@@ -2,8 +2,10 @@
|
||||
#include "resource.h"
|
||||
|
||||
#include "lang/bg-BG.rc"
|
||||
#include "lang/es-ES.rc"
|
||||
#include "lang/ca-ES.rc"
|
||||
#include "lang/cs-CZ.rc"
|
||||
#include "lang/da-DA.rc"
|
||||
#include "lang/de-DE.rc"
|
||||
#include "lang/el-GR.rc"
|
||||
#include "lang/en-US.rc"
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE BEGIN
|
||||
IDS_APPNAME, "WineMine"
|
||||
IDS_APPNAME, "WinMine"
|
||||
IDS_NOBODY, "Nadie"
|
||||
IDS_ABOUT, "Copyright 2000 Joshua Thielen"
|
||||
END
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE BEGIN
|
||||
IDS_APPNAME, "WineMine"
|
||||
IDS_APPNAME, "WinMine"
|
||||
IDS_NOBODY, "Nessuno"
|
||||
IDS_ABOUT, "Copyright 2000 Joshua Thielen"
|
||||
END
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "lang/bg-BG.rc"
|
||||
#include "lang/de-DE.rc"
|
||||
#include "lang/en-US.rc"
|
||||
#include "lang/es-ES.rc"
|
||||
#include "lang/fr-FR.rc"
|
||||
#include "lang/id-ID.rc"
|
||||
#include "lang/it-IT.rc"
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_BCAST "Broadcast"
|
||||
IDS_P2P "Peer To Peer"
|
||||
IDS_MIXED "Mixto"
|
||||
IDS_HYBRID "Híbrido"
|
||||
IDS_UNKNOWN "Deconocido"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_OTHER "Otro Tipo de Adaptador"
|
||||
IDS_ETH "Adaptador Ethernet"
|
||||
IDS_TOKEN "Adaptador Token Ring"
|
||||
IDS_FDDI "Adaptador FDDI"
|
||||
IDS_PPP "Adaptador PPP"
|
||||
IDS_LOOP "Adaptador Loopback"
|
||||
IDS_SLIP "Adaptador SLIP"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
/* Please keep the spacing/formatting as per En.rc when translating */
|
||||
IDS_USAGE
|
||||
"\nUSO:\n \
|
||||
ipconfig [/? | /all | /renew [adaptador] | /release [adaptador] |\n \
|
||||
/flushdns | /displaydns | /registerdns |\n \
|
||||
/showclassid adaptador |\n \
|
||||
/setclassid adaptador [classid] ]\n \
|
||||
\n \
|
||||
En la cual\n \
|
||||
adaptador Nombre de la conexión\n \
|
||||
(caracteres especiales * and ? autorizados, ver ejemplos)\n \
|
||||
\n \
|
||||
Optiones:\n \
|
||||
/? Muestra este mensaje de ayuda\n \
|
||||
/all Muestra todas las informaciones de configuración.\n \
|
||||
/release Libera la dirección IP para el adaptador especificado.\n \
|
||||
/renew Renueva la dirección IP para el adaptador especificado.\n \
|
||||
/flushdns Purga la cache de Resolución DNS.\n \
|
||||
/registerdns Actualiza todas las concesiones DHCP y registra de nuevo nombres DNS.\n \
|
||||
/displaydns Muestra el contenido del cache de Resolución DNS.\n \
|
||||
/showclassid Muestra todos los class IDs dhcp concedidos al adaptador.\n \
|
||||
/setclassid Modifica el class id dhcp.\n \
|
||||
\n \
|
||||
Generalmente se muestra solamente la dirección IP, la máscara de red y\n \
|
||||
la puerta de enlace predefinidas de cada adaptador relacionado a TCP/IP.\n \
|
||||
\n \
|
||||
Para los parámetros Release y Renew, si no se especifica un adaptador, entonces la(s) dirección(es)\n \
|
||||
IP asignada(s) para todos los adaptadores relacionados a TCP/IP serán liberadas o renovadas.\n \
|
||||
\n \
|
||||
Para Setclassid, si no se especifica algún ClassId, este será removido.\n \
|
||||
\n \
|
||||
Ejemplos:\n \
|
||||
> ipconfig ... Muestra informaciones.\n \
|
||||
> ipconfig /all ... Muestra informaciones detalladas\n \
|
||||
> ipconfig /renew ... Renueva todos los adaptadores\n \
|
||||
> ipconfig /renew EL* ... Renueva todas las direcciones IP de los adaptadores\n \
|
||||
cuyo nombre comienza con EL\n \
|
||||
> ipconfig /release *Con* ... Libera todas las conexiones concernidas,\n \
|
||||
ej. ""Conexión al area local 1"" o\n \
|
||||
""Conexión al area local 2""\n"
|
||||
END
|
||||
@@ -16,7 +16,7 @@ Opzioni:\n\
|
||||
IDS_APPROXIMATE_ROUND_TRIP "Tempo approssimato di andata e ritorno in milli-secondi:\n\0"
|
||||
IDS_MIN_MAX_AVERAGE " Minimo = %1, Massimo = %2, Media = %3\n\0"
|
||||
IDS_NOT_ENOUGH_RESOURCES "Risorse disponibili insufficienti.\n\0"
|
||||
IDS_UNKNOWN_HOST "Host sconosciuto%1.\n\0"
|
||||
IDS_UNKNOWN_HOST "Host sconosciuto %1.\n\0"
|
||||
IDS_SETSOCKOPT_FAILED "setsockopt fallito (%1!d!).\n\0"
|
||||
IDS_COULD_NOT_CREATE_SOCKET "Impossibile creare il socket (#%1!d!).\n\0"
|
||||
IDS_COULD_NOT_INIT_WINSOCK "Impossibile inizializzare winsock dll.\n\0"
|
||||
@@ -24,7 +24,7 @@ Opzioni:\n\
|
||||
IDS_BAD_PARAMETER "Parametro errato %1.\n\0"
|
||||
IDS_BAD_OPTION_FORMAT "Formato opzione errato %1.\n\0"
|
||||
IDS_BAD_OPTION "Opzione errata %1.\n\0"
|
||||
IDS_BAD_VALUE_OPTION_L "Valore errato per il parametro -l, l'intervallo valido è tra 0 to %1!d!.\n\0"
|
||||
IDS_BAD_VALUE_OPTION_L "Valore errato per il parametro -l, è valido un valore tra 0 to %1!d!.\n\0"
|
||||
IDS_REPLY_FROM "Risposta da %1: bytes=%2!d! time%3%4 TTL=%5!d!\n\0"
|
||||
IDS_DEST_UNREACHABLE "Host destinazione irraggiungibile.\n\0"
|
||||
IDS_COULD_NOT_TRANSMIT "Impossibile trasmettere dati (%1!d!).\n\0"
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#ifndef STRSAFE_NO_DEPRECATE
|
||||
#define STRSAFE_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
@@ -10,4 +10,4 @@ int mirrorRotateDlg(void);
|
||||
|
||||
int attributesDlg(void);
|
||||
|
||||
int changeSizeDlg();
|
||||
int changeSizeDlg(void);
|
||||
|
||||
@@ -8,45 +8,37 @@ Description = The most popular and one of the best free Web Browsers out there.
|
||||
Size = 5.8M
|
||||
Category = 5
|
||||
URLSite = http://www.mozilla.com/en-US/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/en-US/Firefox%20Setup%202.0.0.20.exe
|
||||
URLDownload = http://svn.reactos.org/packages/Firefox%20Setup%202.0.0.20.exe
|
||||
CDPath = none
|
||||
|
||||
[Section.0405]
|
||||
Description = Nejpopulárnější a jeden z nejlepších svobodných webových prohlížečů.
|
||||
URLSite = http://www.mozilla-europe.org/cs/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/cs/Firefox%20Setup%202.0.0.20.exe
|
||||
|
||||
[Section.0407]
|
||||
Description = Der populärste und einer der besten freien Webbrowser.
|
||||
URLSite = http://www.mozilla-europe.org/de/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/de/Firefox%20Setup%202.0.0.20.exe
|
||||
|
||||
[Section.040a]
|
||||
Description = El más popular y uno de los mejores navegadores web gratuitos que hay.
|
||||
URLSite = http://www.mozilla-europe.org/es/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/es-ES/Firefox%20Setup%202.0.0.20.exe
|
||||
|
||||
[Section.040c]
|
||||
Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs.
|
||||
URLSite = http://www.mozilla-europe.org/fr/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/fr/Firefox%20Setup%202.0.0.20.exe
|
||||
|
||||
[Section.0414]
|
||||
Description = Mest populære og best også gratis nettleserene der ute.
|
||||
URLSite = http://www.mozilla-europe.org/no/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/nb-NO/Firefox%20Setup%202.0.0.20.exe
|
||||
|
||||
[Section.0415]
|
||||
Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych.
|
||||
URLSite = http://www.mozilla-europe.org/pl/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/pl/Firefox%20Setup%202.0.0.20.exe
|
||||
|
||||
[Section.0419]
|
||||
Description = Один из самых популярных и лучших бесплатных браузеров.
|
||||
URLSite = http://www.mozilla-europe.org/ru/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/ru/Firefox%20Setup%202.0.0.20.exe
|
||||
|
||||
[Section.0422]
|
||||
Description = Найпопулярніший та один з кращих безплатних веб-браузерів.
|
||||
URLSite = http://www.mozilla-europe.org/uk/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.20/win32/uk/Firefox%20Setup%202.0.0.20.exe
|
||||
|
||||
@@ -8,52 +8,44 @@ Description = The most popular and one of the best free Web Browsers out there.
|
||||
Size = 7.2M
|
||||
Category = 5
|
||||
URLSite = http://www.mozilla.com/en-US/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/en-US/Firefox%20Setup%203.0.19.exe
|
||||
URLDownload = http://svn.reactos.org/packages/Firefox%20Setup%203.0.19.exe
|
||||
CDPath = none
|
||||
|
||||
[Section.0405]
|
||||
Description = Nejpopulárnější a jeden z nejlepších svobodných webových prohlížečů.
|
||||
Size = 7.0M
|
||||
URLSite = http://www.mozilla-europe.org/cs/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/cs/Firefox%20Setup%203.0.19.exe
|
||||
|
||||
[Section.0407]
|
||||
Description = Der populärste und einer der besten freien Webbrowser.
|
||||
Size = 7.0M
|
||||
URLSite = http://www.mozilla-europe.org/de/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/de/Firefox%20Setup%203.0.19.exe
|
||||
|
||||
[Section.040a]
|
||||
Description = El más popular y uno de los mejores navegadores web gratuitos que hay.
|
||||
Size = 7.0M
|
||||
URLSite = http://www.mozilla-europe.org/es/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/es-ES/Firefox%20Setup%203.0.19.exe
|
||||
|
||||
[Section.040c]
|
||||
Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs.
|
||||
URLSite = http://www.mozilla-europe.org/fr/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/fr/Firefox%20Setup%203.0.19.exe
|
||||
|
||||
[Section.0414]
|
||||
Description = Mest populære og best også gratis nettleserene der ute.
|
||||
Size = 7.0M
|
||||
URLSite = http://www.mozilla-europe.org/no/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/nb-NO/Firefox%20Setup%203.0.19.exe
|
||||
|
||||
[Section.0415]
|
||||
Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych.
|
||||
Size = 7.9M
|
||||
URLSite = http://www.mozilla-europe.org/pl/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/pl/Firefox%20Setup%203.0.19.exe
|
||||
|
||||
[Section.0419]
|
||||
Description = Один из самых популярных и лучших бесплатных браузеров.
|
||||
Size = 7.8M
|
||||
URLSite = http://www.mozilla-europe.org/ru/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/ru/Firefox%20Setup%203.0.19.exe
|
||||
|
||||
[Section.0422]
|
||||
Description = Найпопулярніший та один з кращих безплатних веб-браузерів.
|
||||
Size = 7.4M
|
||||
URLSite = http://www.mozilla-europe.org/uk/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.0.19-real-real/win32/uk/Firefox%20Setup%203.0.19.exe
|
||||
|
||||
@@ -8,47 +8,47 @@ Description = The most popular and one of the best free Web Browsers out there.
|
||||
Size = 8.2M
|
||||
Category = 5
|
||||
URLSite = http://www.mozilla.com/en-US/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/en-US/Firefox%20Setup%203.6.15.exe
|
||||
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/en-US/Firefox%20Setup%203.6.15.exe
|
||||
CDPath = none
|
||||
|
||||
[Section.0407]
|
||||
Description = Der populärste und einer der besten freien Webbrowser.
|
||||
Size = 8.1M
|
||||
URLSite = http://www.mozilla-europe.org/de/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/de/Firefox%20Setup%203.6.15.exe
|
||||
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/de/Firefox%20Setup%203.6.15.exe
|
||||
|
||||
[Section.040a]
|
||||
Description = El más popular y uno de los mejores navegadores web gratuitos que hay.
|
||||
Size = 8.1M
|
||||
URLSite = http://www.mozilla-europe.org/es/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/es-ES/Firefox%20Setup%203.6.15.exe
|
||||
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/es-ES/Firefox%20Setup%203.6.15.exe
|
||||
|
||||
[Section.040c]
|
||||
Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs.
|
||||
Size = 8.1M
|
||||
URLSite = http://www.mozilla-europe.org/fr/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/fr/Firefox%20Setup%203.6.15.exe
|
||||
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/fr/Firefox%20Setup%203.6.15.exe
|
||||
|
||||
[Section.0414]
|
||||
Description = Mest populære og best også gratis nettleserene der ute.
|
||||
Size = 8.1M
|
||||
URLSite = http://www.mozilla-europe.org/no/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/nb-NO/Firefox%20Setup%203.6.15.exe
|
||||
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/nb-NO/Firefox%20Setup%203.6.15.exe
|
||||
|
||||
[Section.0415]
|
||||
Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych.
|
||||
Size = 8.9M
|
||||
URLSite = http://www.mozilla-europe.org/pl/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/pl/Firefox%20Setup%203.6.15.exe
|
||||
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/pl/Firefox%20Setup%203.6.15.exe
|
||||
|
||||
[Section.0419]
|
||||
Description = Один из самых популярных и лучших бесплатных браузеров.
|
||||
Size = 8.5M
|
||||
URLSite = http://www.mozilla-europe.org/ru/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/ru/Firefox%20Setup%203.6.15.exe
|
||||
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/ru/Firefox%20Setup%203.6.15.exe
|
||||
|
||||
[Section.0422]
|
||||
Description = Найпопулярніший та один з кращих безплатних веб-браузерів.
|
||||
Size = 8.5M
|
||||
URLSite = http://www.mozilla-europe.org/uk/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/firefox/releases/3.6.15/win32/uk/Firefox%20Setup%203.6.15.exe
|
||||
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/uk/Firefox%20Setup%203.6.15.exe
|
||||
|
||||
@@ -8,36 +8,36 @@ Description = THE Open Source Office Suite.
|
||||
Size = 127MB
|
||||
Category = 6
|
||||
URLSite = http://www.openoffice.org/
|
||||
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/stable/2.4.3/OOo_2.4.3_Win32Intel_install_en-US.exe
|
||||
URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/stable/2.4.3/OOo_2.4.3_Win32Intel_install_en-US.exe
|
||||
CDPath = none
|
||||
|
||||
[Section.0407]
|
||||
Description = DIE Open Source Office Suite.
|
||||
URLSite = http://de.openoffice.org/
|
||||
Size = 114.2MB
|
||||
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/de/2.4.3/OOo_2.4.3_Win32Intel_install_de.exe
|
||||
URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/de/2.4.3/OOo_2.4.3_Win32Intel_install_de.exe
|
||||
|
||||
[Section.040a]
|
||||
Description = La suite de ofimática de código abierto.
|
||||
URLSite = http://es.openoffice.org/
|
||||
Size = 113.9MB
|
||||
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/es/2.4.3/OOo_2.4.3_Win32Intel_install_es.exe
|
||||
URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/es/2.4.3/OOo_2.4.3_Win32Intel_install_es.exe
|
||||
|
||||
[Section.040c]
|
||||
Version = 2.4.2
|
||||
Description = LA suite bureautique open source.
|
||||
URLSite = http://fr.openoffice.org/
|
||||
Size = 113.9MB
|
||||
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/fr/2.4.2/OOo_2.4.2_Win32Intel_install_fr.exe
|
||||
URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/fr/2.4.2/OOo_2.4.2_Win32Intel_install_fr.exe
|
||||
|
||||
[Section.0415]
|
||||
URLSite = http://pl.openoffice.org/
|
||||
Description = Otwarty pakiet biurowy.
|
||||
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/pl/2.4.2/OOo_2.4.2_Win32Intel_install_pl.exe
|
||||
URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/pl/2.4.2/OOo_2.4.2_Win32Intel_install_pl.exe
|
||||
Size = 113.9M
|
||||
|
||||
[Section.0422]
|
||||
URLSite = http://ua.openoffice.org/
|
||||
Description = Відкритий офісний пакет.
|
||||
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/ru/2.4.3/OOo_2.4.3_Win32Intel_install_ru.exe
|
||||
URLDownload = http://archive.services.openoffice.org/pub/openoffice-archive/localized/ru/2.4.3/OOo_2.4.3_Win32Intel_install_ru.exe
|
||||
Size = 114.8M
|
||||
|
||||
@@ -8,30 +8,30 @@ Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Ch
|
||||
Size = 10.2MB
|
||||
Category = 5
|
||||
URLSite = http://www.seamonkey-project.org/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/en-US/SeaMonkey%20Setup%202.0.12.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/en-US/SeaMonkey%20Setup%202.0.12.exe
|
||||
CDPath = none
|
||||
|
||||
[Section.0407]
|
||||
Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen.
|
||||
Size = 10.1MB
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/de/SeaMonkey%20Setup%202.0.12.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/de/SeaMonkey%20Setup%202.0.12.exe
|
||||
|
||||
[Section.040a]
|
||||
Description = La suite de Mozilla está viva. Es el primero y único navegador web, gestor de correo, lector de noticias, Chat y editor HTML que necesitarás.
|
||||
Size = 10.1MB
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/es-ES/SeaMonkey%20Setup%202.0.12.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/es-ES/SeaMonkey%20Setup%202.0.12.exe
|
||||
|
||||
[Section.040c]
|
||||
Description = La suite Mozilla est en vie. Ceci est le seul et l'unique package navigateur, client mail, client chat et composer dont vous aurez besoin.
|
||||
Size = 10.1MB
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/fr/SeaMonkey%20Setup%202.0.12.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/fr/SeaMonkey%20Setup%202.0.12.exe
|
||||
|
||||
[Section.0415]
|
||||
Description = Pakiet Mozilla żyje. W zestawie: przeglądarka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz.
|
||||
Size = 11.0MB
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/pl/SeaMonkey%20Setup%202.0.12.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/pl/SeaMonkey%20Setup%202.0.12.exe
|
||||
|
||||
[Section.0419]
|
||||
Description = Продолжение Mozilla Suite. Включает браузер, почтовый клиент, IRC-клиент и HTML-редактор.
|
||||
Size = 10.5MB
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/seamonkey/releases/2.0.12/win32/ru/SeaMonkey%20Setup%202.0.12.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/ru/SeaMonkey%20Setup%202.0.12.exe
|
||||
|
||||
@@ -16,3 +16,6 @@ Description = Sumatra PDF ist ein freies, schlankes, Open-Source PDF-Anzeigeprog
|
||||
|
||||
[Section.0410]
|
||||
Description = Sumatra PDF è un visualizzatore di file PDF. E' molto leggero ed è open source.
|
||||
|
||||
[Section.0415]
|
||||
Description = Sumatra PDF to mały, darmowy, otwarty czytnik PDF.
|
||||
|
||||
@@ -8,41 +8,41 @@ Description = The most popular and one of the best free Mail Clients out there.
|
||||
Size = 9.0M
|
||||
Category = 5
|
||||
URLSite = http://www.mozilla-europe.org/en/products/thunderbird/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/en-US/Thunderbird%20Setup%203.1.9.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/en-US/Thunderbird%20Setup%203.1.9.exe
|
||||
CDPath = none
|
||||
|
||||
[Section.0407]
|
||||
Description = Der populärste und einer der besten freien Mail-Clients.
|
||||
Size = 8.8M
|
||||
URLSite = http://www.mozilla-europe.org/de/products/thunderbird/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/de/Thunderbird%20Setup%203.1.9.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/de/Thunderbird%20Setup%203.1.9.exe
|
||||
|
||||
[Section.040a]
|
||||
Description = El más popular y uno de los mejores clientes mail que hay.
|
||||
Size = 8.8M
|
||||
URLSite = http://www.mozilla-europe.org/es/products/thunderbird/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/es-ES/Thunderbird%20Setup%203.1.9.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/es-ES/Thunderbird%20Setup%203.1.9.exe
|
||||
|
||||
[Section.040c]
|
||||
Description = Le plus populaire et l'un des meilleurs clients mail gratuits disponible.
|
||||
Size = 8.8M
|
||||
URLSite = http://www.mozilla-europe.org/fr/products/thunderbird/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/fr/Thunderbird%20Setup%203.1.9.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/fr/Thunderbird%20Setup%203.1.9.exe
|
||||
|
||||
[Section.0415]
|
||||
Description = Najpopularniejszy i jeden z najlepszych darmowych klientów poczty.
|
||||
Size = 9.7M
|
||||
URLSite = http://www.mozilla-europe.org/pl/products/thunderbird/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/pl/Thunderbird%20Setup%203.1.9.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/pl/Thunderbird%20Setup%203.1.9.exe
|
||||
|
||||
[Section.0419]
|
||||
Description = Один из самых популярных и лучших бесплатных почтовых клиентов.
|
||||
Size = 9.2M
|
||||
URLSite = http://www.mozilla-europe.org/ru/products/thunderbird/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/ru/Thunderbird%20Setup%203.1.9.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/ru/Thunderbird%20Setup%203.1.9.exe
|
||||
|
||||
[Section.0422]
|
||||
Description = Найпопулярніший та один з кращих поштових клієнтів.
|
||||
Size = 9.2M
|
||||
URLSite = http://www.mozillamessaging.com/uk/thunderbird/
|
||||
URLDownload = ftp://ftp.mozilla.org/pub/thunderbird/releases/3.1.9/win32/uk/Thunderbird%20Setup%203.1.9.exe
|
||||
URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.9/win32/uk/Thunderbird%20Setup%203.1.9.exe
|
||||
|
||||
@@ -8,7 +8,7 @@ Description = WinBoard is a graphical chessboard for the Windows/ReactOS that ca
|
||||
Size = 5.9MB
|
||||
Category = 4
|
||||
URLSite = http://www.gnu.org/software/xboard/
|
||||
URLDownload = ftp://ftp.gnu.org/old-gnu/xboard/winboard/winboard-4_2_7b.exe
|
||||
URLDownload = http://ftp.gnu.org/old-gnu/xboard/winboard/winboard-4_2_7b.exe
|
||||
CDPath = none
|
||||
|
||||
[Section.0407]
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
HWND hMainWnd;
|
||||
HINSTANCE hInst;
|
||||
HIMAGELIST hImageListView = NULL;
|
||||
HIMAGELIST hImageTreeView = NULL;
|
||||
INT SelectedEnumType = ENUM_ALL_COMPONENTS;
|
||||
SETTINGS_INFO SettingsInfo;
|
||||
@@ -168,8 +167,8 @@ UpdateApplicationsList(INT EnumType)
|
||||
{
|
||||
WCHAR szBuffer1[MAX_STR_LEN], szBuffer2[MAX_STR_LEN];
|
||||
HICON hIcon;
|
||||
HIMAGELIST hImageListView;
|
||||
|
||||
if (hImageListView) ImageList_Destroy(hImageListView);
|
||||
(VOID) ListView_DeleteAllItems(hListView);
|
||||
|
||||
/* Create image list */
|
||||
@@ -208,7 +207,11 @@ UpdateApplicationsList(INT EnumType)
|
||||
}
|
||||
|
||||
/* Set image list for ListView */
|
||||
(VOID) ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
|
||||
hImageListView = ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
|
||||
|
||||
/* Destroy old image list */
|
||||
if (hImageListView)
|
||||
ImageList_Destroy(hImageListView);
|
||||
|
||||
SelectedEnumType = EnumType;
|
||||
|
||||
@@ -725,7 +728,6 @@ MainWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
FreeAvailableAppList();
|
||||
if (IS_INSTALLED_ENUM(SelectedEnumType))
|
||||
FreeInstalledAppList();
|
||||
if (hImageListView) ImageList_Destroy(hImageListView);
|
||||
if (hImageTreeView) ImageList_Destroy(hImageTreeView);
|
||||
|
||||
PostQuitMessage(0);
|
||||
|
||||
@@ -65,7 +65,7 @@ static void draw_splitbar(HWND hWnd, int x)
|
||||
ReleaseDC(hWnd, hdc);
|
||||
}
|
||||
|
||||
static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy)
|
||||
static void ResizeWnd(int cx, int cy)
|
||||
{
|
||||
HDWP hdwp = BeginDeferWindowPos(3);
|
||||
RECT rt, rs, rb;
|
||||
@@ -77,12 +77,12 @@ static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy)
|
||||
GetWindowRect(hStatusBar, &rs);
|
||||
cy = rs.bottom - rs.top;
|
||||
}
|
||||
GetWindowRect(pChildWnd->hAddressBtnWnd, &rb);
|
||||
cx = pChildWnd->nSplitPos + SPLIT_WIDTH/2;
|
||||
DeferWindowPos(hdwp, pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left - tHeight-2, tHeight, SWP_NOZORDER|SWP_NOACTIVATE);
|
||||
DeferWindowPos(hdwp, pChildWnd->hAddressBtnWnd, 0, rt.right - tHeight, rt.top, tHeight, tHeight, SWP_NOZORDER|SWP_NOACTIVATE);
|
||||
DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + tHeight+2, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
|
||||
DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx, rt.top + tHeight+2, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
|
||||
GetWindowRect(g_pChildWnd->hAddressBtnWnd, &rb);
|
||||
cx = g_pChildWnd->nSplitPos + SPLIT_WIDTH/2;
|
||||
DeferWindowPos(hdwp, g_pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left - tHeight-2, tHeight, SWP_NOZORDER|SWP_NOACTIVATE);
|
||||
DeferWindowPos(hdwp, g_pChildWnd->hAddressBtnWnd, 0, rt.right - tHeight, rt.top, tHeight, tHeight, SWP_NOZORDER|SWP_NOACTIVATE);
|
||||
DeferWindowPos(hdwp, g_pChildWnd->hTreeWnd, 0, rt.left, rt.top + tHeight+2, g_pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
|
||||
DeferWindowPos(hdwp, g_pChildWnd->hListWnd, 0, rt.left+cx, rt.top + tHeight+2, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
|
||||
EndDeferWindowPos(hdwp);
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ static void finish_splitbar(HWND hWnd, int x)
|
||||
last_split = -1;
|
||||
GetClientRect(hWnd, &rt);
|
||||
g_pChildWnd->nSplitPos = x;
|
||||
ResizeWnd(g_pChildWnd, rt.right, rt.bottom);
|
||||
ResizeWnd(rt.right, rt.bottom);
|
||||
ReleaseCapture();
|
||||
}
|
||||
|
||||
@@ -125,7 +125,6 @@ static void finish_splitbar(HWND hWnd, int x)
|
||||
|
||||
static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ChildWnd* pChildWnd = g_pChildWnd;
|
||||
HTREEITEM hSelection;
|
||||
HKEY hRootKey;
|
||||
LPCTSTR keyPath, s;
|
||||
@@ -143,18 +142,18 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
/* TODO */
|
||||
break;
|
||||
case ID_TREE_EXPANDBRANCH:
|
||||
(void)TreeView_Expand(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd), TVE_EXPAND);
|
||||
(void)TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_EXPAND);
|
||||
break;
|
||||
case ID_TREE_COLLAPSEBRANCH:
|
||||
(void)TreeView_Expand(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd), TVE_COLLAPSE);
|
||||
(void)TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_COLLAPSE);
|
||||
break;
|
||||
case ID_TREE_RENAME:
|
||||
SetFocus(pChildWnd->hTreeWnd);
|
||||
(void)TreeView_EditLabel(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd));
|
||||
SetFocus(g_pChildWnd->hTreeWnd);
|
||||
(void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd));
|
||||
break;
|
||||
case ID_TREE_DELETE:
|
||||
hSelection = TreeView_GetSelection(pChildWnd->hTreeWnd);
|
||||
keyPath = GetItemPath(pChildWnd->hTreeWnd, hSelection, &hRootKey);
|
||||
hSelection = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
|
||||
keyPath = GetItemPath(g_pChildWnd->hTreeWnd, hSelection, &hRootKey);
|
||||
|
||||
if (keyPath == 0 || *keyPath == 0)
|
||||
{
|
||||
@@ -164,18 +163,18 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
DeleteNode(g_pChildWnd->hTreeWnd, 0);
|
||||
break;
|
||||
case ID_TREE_EXPORT:
|
||||
ExportRegistryFile(pChildWnd->hTreeWnd);
|
||||
ExportRegistryFile(g_pChildWnd->hTreeWnd);
|
||||
break;
|
||||
case ID_EDIT_FIND:
|
||||
FindDialog(hWnd);
|
||||
break;
|
||||
case ID_EDIT_COPYKEYNAME:
|
||||
hSelection = TreeView_GetSelection(pChildWnd->hTreeWnd);
|
||||
keyPath = GetItemPath(pChildWnd->hTreeWnd, hSelection, &hRootKey);
|
||||
hSelection = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
|
||||
keyPath = GetItemPath(g_pChildWnd->hTreeWnd, hSelection, &hRootKey);
|
||||
CopyKeyName(hWnd, hRootKey, keyPath);
|
||||
break;
|
||||
case ID_EDIT_NEW_KEY:
|
||||
CreateNewKey(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd));
|
||||
CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd));
|
||||
break;
|
||||
case ID_EDIT_NEW_STRINGVALUE:
|
||||
case ID_EDIT_NEW_BINARYVALUE:
|
||||
@@ -183,8 +182,8 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
SendMessage(hFrameWnd, WM_COMMAND, wParam, lParam);
|
||||
break;
|
||||
case ID_SWITCH_PANELS:
|
||||
pChildWnd->nFocusPanel = !pChildWnd->nFocusPanel;
|
||||
SetFocus(pChildWnd->nFocusPanel? pChildWnd->hListWnd: pChildWnd->hTreeWnd);
|
||||
g_pChildWnd->nFocusPanel = !g_pChildWnd->nFocusPanel;
|
||||
SetFocus(g_pChildWnd->nFocusPanel? g_pChildWnd->hListWnd: g_pChildWnd->hTreeWnd);
|
||||
break;
|
||||
default:
|
||||
if ((wID >= ID_TREE_SUGGESTION_MIN) && (wID <= ID_TREE_SUGGESTION_MAX))
|
||||
@@ -196,7 +195,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
s += _tcslen(s) + 1;
|
||||
wID--;
|
||||
}
|
||||
SelectNode(pChildWnd->hTreeWnd, s);
|
||||
SelectNode(g_pChildWnd->hTreeWnd, s);
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -317,7 +316,6 @@ LRESULT CALLBACK AddressBarProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
BOOL Result;
|
||||
ChildWnd* pChildWnd = g_pChildWnd;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
@@ -329,45 +327,45 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
/* load "My Computer" string */
|
||||
LoadString(hInst, IDS_MY_COMPUTER, buffer, sizeof(buffer)/sizeof(TCHAR));
|
||||
|
||||
g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd));
|
||||
g_pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd));
|
||||
if (!g_pChildWnd) return 0;
|
||||
|
||||
if (!pChildWnd) return 0;
|
||||
_tcsncpy(pChildWnd->szPath, buffer, MAX_PATH);
|
||||
pChildWnd->nSplitPos = 250;
|
||||
pChildWnd->hWnd = hWnd;
|
||||
pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP,
|
||||
_tcsncpy(g_pChildWnd->szPath, buffer, MAX_PATH);
|
||||
g_pChildWnd->nSplitPos = 250;
|
||||
g_pChildWnd->hWnd = hWnd;
|
||||
g_pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
hWnd, (HMENU)0, hInst, 0);
|
||||
pChildWnd->hAddressBtnWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Button"), _T("»"), WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_DEFPUSHBUTTON,
|
||||
g_pChildWnd->hAddressBtnWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Button"), _T("»"), WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_DEFPUSHBUTTON,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
hWnd, (HMENU)0, hInst, 0);
|
||||
pChildWnd->hTreeWnd = CreateTreeView(hWnd, pChildWnd->szPath, (HMENU) TREE_WINDOW);
|
||||
pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, pChildWnd->szPath*/);
|
||||
SetFocus(pChildWnd->hTreeWnd);
|
||||
g_pChildWnd->hTreeWnd = CreateTreeView(hWnd, g_pChildWnd->szPath, (HMENU) TREE_WINDOW);
|
||||
g_pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, g_pChildWnd->szPath*/);
|
||||
SetFocus(g_pChildWnd->hTreeWnd);
|
||||
|
||||
/* set the address bar and button font */
|
||||
if ((pChildWnd->hAddressBarWnd) && (pChildWnd->hAddressBtnWnd))
|
||||
if ((g_pChildWnd->hAddressBarWnd) && (g_pChildWnd->hAddressBtnWnd))
|
||||
{
|
||||
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
||||
SendMessage(pChildWnd->hAddressBarWnd,
|
||||
SendMessage(g_pChildWnd->hAddressBarWnd,
|
||||
WM_SETFONT,
|
||||
(WPARAM)hFont,
|
||||
0);
|
||||
SendMessage(pChildWnd->hAddressBtnWnd,
|
||||
SendMessage(g_pChildWnd->hAddressBtnWnd,
|
||||
WM_SETFONT,
|
||||
(WPARAM)hFont,
|
||||
0);
|
||||
}
|
||||
/* Subclass the AddressBar */
|
||||
oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_WNDPROC);
|
||||
SetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_USERDATA, (DWORD_PTR)oldproc);
|
||||
SetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_WNDPROC, (DWORD_PTR)AddressBarProc);
|
||||
oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWL_WNDPROC);
|
||||
SetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWL_USERDATA, (DWORD_PTR)oldproc);
|
||||
SetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWL_WNDPROC, (DWORD_PTR)AddressBarProc);
|
||||
break;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
if(HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
PostMessage(pChildWnd->hAddressBarWnd, WM_KEYUP, VK_RETURN, 0);
|
||||
PostMessage(g_pChildWnd->hAddressBarWnd, WM_KEYUP, VK_RETURN, 0);
|
||||
}
|
||||
else if (!_CmdWndProc(hWnd, message, wParam, lParam))
|
||||
{
|
||||
@@ -383,7 +381,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
ScreenToClient(hWnd, &pt);
|
||||
if (pt.x>=pChildWnd->nSplitPos-SPLIT_WIDTH/2 && pt.x<pChildWnd->nSplitPos+SPLIT_WIDTH/2+1)
|
||||
if (pt.x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && pt.x<g_pChildWnd->nSplitPos+SPLIT_WIDTH/2+1)
|
||||
{
|
||||
SetCursor(LoadCursor(0, IDC_SIZEWE));
|
||||
return TRUE;
|
||||
@@ -392,10 +390,10 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
goto def;
|
||||
case WM_DESTROY:
|
||||
DestroyTreeView();
|
||||
DestroyListView(pChildWnd->hListWnd);
|
||||
DestroyListView(g_pChildWnd->hListWnd);
|
||||
DestroyMainMenu();
|
||||
HeapFree(GetProcessHeap(), 0, pChildWnd);
|
||||
pChildWnd = NULL;
|
||||
HeapFree(GetProcessHeap(), 0, g_pChildWnd);
|
||||
g_pChildWnd = NULL;
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
@@ -403,9 +401,9 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
RECT rt;
|
||||
int x = (short)LOWORD(lParam);
|
||||
GetClientRect(hWnd, &rt);
|
||||
if (x>=pChildWnd->nSplitPos-SPLIT_WIDTH/2 && x<pChildWnd->nSplitPos+SPLIT_WIDTH/2+1)
|
||||
if (x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && x<g_pChildWnd->nSplitPos+SPLIT_WIDTH/2+1)
|
||||
{
|
||||
last_split = pChildWnd->nSplitPos;
|
||||
last_split = g_pChildWnd->nSplitPos;
|
||||
draw_splitbar(hWnd, last_split);
|
||||
SetCapture(hWnd);
|
||||
}
|
||||
@@ -432,7 +430,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
RECT rt;
|
||||
draw_splitbar(hWnd, last_split);
|
||||
GetClientRect(hWnd, &rt);
|
||||
ResizeWnd(pChildWnd, rt.right, rt.bottom);
|
||||
ResizeWnd(rt.right, rt.bottom);
|
||||
last_split = -1;
|
||||
ReleaseCapture();
|
||||
SetCursor(LoadCursor(0, IDC_ARROW));
|
||||
@@ -476,9 +474,9 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
if (pChildWnd != NULL)
|
||||
if (g_pChildWnd != NULL)
|
||||
{
|
||||
SetFocus(pChildWnd->nFocusPanel? pChildWnd->hListWnd: pChildWnd->hTreeWnd);
|
||||
SetFocus(g_pChildWnd->nFocusPanel? g_pChildWnd->hListWnd: g_pChildWnd->hTreeWnd);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -486,22 +484,22 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
break;
|
||||
|
||||
case WM_NOTIFY:
|
||||
if ((int)wParam == TREE_WINDOW)
|
||||
if ((int)wParam == TREE_WINDOW && g_pChildWnd != NULL)
|
||||
{
|
||||
switch (((LPNMHDR)lParam)->code)
|
||||
{
|
||||
case TVN_ITEMEXPANDING:
|
||||
return !OnTreeExpanding(pChildWnd->hTreeWnd, (NMTREEVIEW*)lParam);
|
||||
return !OnTreeExpanding(g_pChildWnd->hTreeWnd, (NMTREEVIEW*)lParam);
|
||||
case TVN_SELCHANGED:
|
||||
{
|
||||
LPCTSTR keyPath, rootName;
|
||||
LPTSTR fullPath;
|
||||
HKEY hRootKey;
|
||||
|
||||
keyPath = GetItemPath(pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, &hRootKey);
|
||||
keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, &hRootKey);
|
||||
if (keyPath)
|
||||
{
|
||||
RefreshListView(pChildWnd->hListWnd, hRootKey, keyPath);
|
||||
RefreshListView(g_pChildWnd->hListWnd, hRootKey, keyPath);
|
||||
rootName = get_root_key_name(hRootKey);
|
||||
fullPath = HeapAlloc(GetProcessHeap(), 0, (_tcslen(rootName) + 1 + _tcslen(keyPath) + 1) * sizeof(TCHAR));
|
||||
if (fullPath)
|
||||
@@ -512,7 +510,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
else
|
||||
fullPath = _tcscpy(fullPath, rootName);
|
||||
SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath);
|
||||
SendMessage(pChildWnd->hAddressBarWnd, WM_SETTEXT, 0, (LPARAM)fullPath);
|
||||
SendMessage(g_pChildWnd->hAddressBarWnd, WM_SETTEXT, 0, (LPARAM)fullPath);
|
||||
HeapFree(GetProcessHeap(), 0, fullPath);
|
||||
/* disable hive manipulation items temporarily (enable only if necessary) */
|
||||
EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_GRAYED);
|
||||
@@ -547,15 +545,15 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
}
|
||||
break;
|
||||
case NM_SETFOCUS:
|
||||
pChildWnd->nFocusPanel = 0;
|
||||
g_pChildWnd->nFocusPanel = 0;
|
||||
break;
|
||||
case TVN_BEGINLABELEDIT:
|
||||
{
|
||||
LPNMTVDISPINFO ptvdi;
|
||||
/* cancel label edit for rootkeys */
|
||||
ptvdi = (LPNMTVDISPINFO) lParam;
|
||||
if (!TreeView_GetParent(pChildWnd->hTreeWnd, ptvdi->item.hItem) ||
|
||||
!TreeView_GetParent(pChildWnd->hTreeWnd, TreeView_GetParent(pChildWnd->hTreeWnd, ptvdi->item.hItem)))
|
||||
if (!TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem) ||
|
||||
!TreeView_GetParent(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem)))
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -571,14 +569,14 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
ptvdi = (LPNMTVDISPINFO) lParam;
|
||||
if (ptvdi->item.pszText)
|
||||
{
|
||||
keyPath = GetItemPath(pChildWnd->hTreeWnd, TreeView_GetParent(pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey);
|
||||
keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey);
|
||||
_sntprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), _T("%s\\%s"), keyPath, ptvdi->item.pszText);
|
||||
keyPath = GetItemPath(pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey);
|
||||
keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey);
|
||||
if (RegOpenKeyEx(hRootKey, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
lResult = FALSE;
|
||||
RegCloseKey(hKey);
|
||||
(void)TreeView_EditLabel(pChildWnd->hTreeWnd, ptvdi->item.hItem);
|
||||
(void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, ptvdi->item.hItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -594,15 +592,15 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((int)wParam == LIST_WINDOW)
|
||||
if ((int)wParam == LIST_WINDOW && g_pChildWnd != NULL)
|
||||
{
|
||||
switch (((LPNMHDR)lParam)->code)
|
||||
{
|
||||
case NM_SETFOCUS:
|
||||
pChildWnd->nFocusPanel = 1;
|
||||
g_pChildWnd->nFocusPanel = 1;
|
||||
break;
|
||||
default:
|
||||
if(!ListWndNotifyProc(pChildWnd->hListWnd, wParam, lParam, &Result))
|
||||
if(!ListWndNotifyProc(g_pChildWnd->hListWnd, wParam, lParam, &Result))
|
||||
{
|
||||
goto def;
|
||||
}
|
||||
@@ -616,27 +614,27 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
case WM_CONTEXTMENU:
|
||||
{
|
||||
POINT pt;
|
||||
if((HWND)wParam == pChildWnd->hListWnd)
|
||||
if((HWND)wParam == g_pChildWnd->hListWnd)
|
||||
{
|
||||
int i, cnt;
|
||||
BOOL IsDefault;
|
||||
pt.x = (short) LOWORD(lParam);
|
||||
pt.y = (short) HIWORD(lParam);
|
||||
cnt = ListView_GetSelectedCount(pChildWnd->hListWnd);
|
||||
i = ListView_GetNextItem(pChildWnd->hListWnd, -1, LVNI_FOCUSED | LVNI_SELECTED);
|
||||
cnt = ListView_GetSelectedCount(g_pChildWnd->hListWnd);
|
||||
i = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_FOCUSED | LVNI_SELECTED);
|
||||
if (pt.x == -1 && pt.y == -1)
|
||||
{
|
||||
RECT rc;
|
||||
if (i != -1)
|
||||
{
|
||||
rc.left = LVIR_BOUNDS;
|
||||
SendMessage(pChildWnd->hListWnd, LVM_GETITEMRECT, i, (LPARAM) &rc);
|
||||
SendMessage(g_pChildWnd->hListWnd, LVM_GETITEMRECT, i, (LPARAM) &rc);
|
||||
pt.x = rc.left + 8;
|
||||
pt.y = rc.top + 8;
|
||||
}
|
||||
else
|
||||
pt.x = pt.y = 0;
|
||||
ClientToScreen(pChildWnd->hListWnd, &pt);
|
||||
ClientToScreen(g_pChildWnd->hListWnd, &pt);
|
||||
}
|
||||
if(i == -1)
|
||||
{
|
||||
@@ -646,7 +644,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
{
|
||||
HMENU mnu = GetSubMenu(hPopupMenus, PM_MODIFYVALUE);
|
||||
SetMenuDefaultItem(mnu, ID_EDIT_MODIFY, MF_BYCOMMAND);
|
||||
IsDefault = IsDefaultValue(pChildWnd->hListWnd, i);
|
||||
IsDefault = IsDefaultValue(g_pChildWnd->hListWnd, i);
|
||||
if(cnt == 1)
|
||||
EnableMenuItem(mnu, ID_EDIT_RENAME, MF_BYCOMMAND | (IsDefault ? MF_DISABLED | MF_GRAYED : MF_ENABLED));
|
||||
else
|
||||
@@ -657,7 +655,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
TrackPopupMenu(mnu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hFrameWnd, NULL);
|
||||
}
|
||||
}
|
||||
else if ((HWND)wParam == pChildWnd->hTreeWnd)
|
||||
else if ((HWND)wParam == g_pChildWnd->hTreeWnd)
|
||||
{
|
||||
TVHITTESTINFO hti;
|
||||
HMENU hContextMenu;
|
||||
@@ -677,13 +675,13 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
if (pt.x == -1 && pt.y == -1)
|
||||
{
|
||||
RECT rc;
|
||||
hti.hItem = TreeView_GetSelection(pChildWnd->hTreeWnd);
|
||||
hti.hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
|
||||
if (hti.hItem != NULL)
|
||||
{
|
||||
TreeView_GetItemRect(pChildWnd->hTreeWnd, hti.hItem, &rc, TRUE);
|
||||
TreeView_GetItemRect(g_pChildWnd->hTreeWnd, hti.hItem, &rc, TRUE);
|
||||
pt.x = rc.left + 8;
|
||||
pt.y = rc.top + 8;
|
||||
ClientToScreen(pChildWnd->hTreeWnd, &pt);
|
||||
ClientToScreen(g_pChildWnd->hTreeWnd, &pt);
|
||||
hti.flags = TVHT_ONITEM;
|
||||
}
|
||||
else
|
||||
@@ -693,19 +691,19 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
{
|
||||
hti.pt.x = pt.x;
|
||||
hti.pt.y = pt.y;
|
||||
ScreenToClient(pChildWnd->hTreeWnd, &hti.pt);
|
||||
(void)TreeView_HitTest(pChildWnd->hTreeWnd, &hti);
|
||||
ScreenToClient(g_pChildWnd->hTreeWnd, &hti.pt);
|
||||
(void)TreeView_HitTest(g_pChildWnd->hTreeWnd, &hti);
|
||||
}
|
||||
|
||||
if (hti.flags & TVHT_ONITEM)
|
||||
{
|
||||
hContextMenu = GetSubMenu(hPopupMenus, PM_TREECONTEXT);
|
||||
(void)TreeView_SelectItem(pChildWnd->hTreeWnd, hti.hItem);
|
||||
(void)TreeView_SelectItem(g_pChildWnd->hTreeWnd, hti.hItem);
|
||||
|
||||
memset(&item, 0, sizeof(item));
|
||||
item.mask = TVIF_STATE | TVIF_CHILDREN;
|
||||
item.hItem = hti.hItem;
|
||||
(void)TreeView_GetItem(pChildWnd->hTreeWnd, &item);
|
||||
(void)TreeView_GetItem(g_pChildWnd->hTreeWnd, &item);
|
||||
|
||||
/* Set the Expand/Collapse menu item appropriately */
|
||||
LoadString(hInst, (item.state & TVIS_EXPANDED) ? IDS_COLLAPSE : IDS_EXPAND, buffer, sizeof(buffer) / sizeof(buffer[0]));
|
||||
@@ -734,7 +732,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
}
|
||||
|
||||
/* Come up with suggestions */
|
||||
keyPath = GetItemPath(pChildWnd->hTreeWnd, NULL, &hRootKey);
|
||||
keyPath = GetItemPath(g_pChildWnd->hTreeWnd, NULL, &hRootKey);
|
||||
SuggestKeys(hRootKey, keyPath, Suggestions, sizeof(Suggestions) / sizeof(Suggestions[0]));
|
||||
if (Suggestions[0])
|
||||
{
|
||||
@@ -758,16 +756,16 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
s += _tcslen(s) + 1;
|
||||
}
|
||||
}
|
||||
TrackPopupMenu(hContextMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, pChildWnd->hWnd, NULL);
|
||||
TrackPopupMenu(hContextMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, g_pChildWnd->hWnd, NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SIZE:
|
||||
if (wParam != SIZE_MINIMIZED && pChildWnd != NULL)
|
||||
if (wParam != SIZE_MINIMIZED && g_pChildWnd != NULL)
|
||||
{
|
||||
ResizeWnd(pChildWnd, LOWORD(lParam), HIWORD(lParam));
|
||||
ResizeWnd(LOWORD(lParam), HIWORD(lParam));
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
|
||||
IDS_USAGE, "Utilización: shutdown [-?] [-l | -s | -r] [-f]\n\n\
|
||||
Ningún argumento o -?\tMuestra este mensaje\n\
|
||||
-l\t\t\tDesconectarse\n\
|
||||
-s\t\t\tApagar el equipo\n\
|
||||
-r\t\t\tApagar y reiniciar el equipo\n\
|
||||
-f\t\t\tObliga las aplicaciones en curso de ejecución a apagarse sin advertencias\n\
|
||||
\t\t\tSi no especifica algún otro parámetro, esta opción\n\
|
||||
\t\t\tprovocará también una desconexión"
|
||||
END
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "lang/el-GR.rc"
|
||||
#include "lang/en-US.rc"
|
||||
#include "lang/fr-FR.rc"
|
||||
#include "lang/es-ES.rc"
|
||||
#include "lang/it-IT.rc"
|
||||
#include "lang/ja-JP.rc"
|
||||
#include "lang/ko-KR.rc"
|
||||
|
||||
@@ -91,8 +91,9 @@ BEGIN
|
||||
|
||||
CONTROL "Boot loader installation", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41
|
||||
|
||||
CONTROL "Install boot loader on the hard disk (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11
|
||||
CONTROL "Install boot loader on the hard disk (MBR and VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "Install boot loader on the hard disk (VBR only)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11
|
||||
CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11
|
||||
PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
PUSHBUTTON "&Cancel", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
END
|
||||
|
||||
@@ -91,8 +91,9 @@ BEGIN
|
||||
|
||||
CONTROL "Bootloader-Installation", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41
|
||||
|
||||
CONTROL "Installiere Bootloader auf Festplatte (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "Keine Bootloader-Installation", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11
|
||||
CONTROL "Installiere Bootloader auf Festplatte (MBR und VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "Installiere Bootloader auf Festplatte (VBR nur)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11
|
||||
CONTROL "Keine Bootloader-Installation", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11
|
||||
PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
PUSHBUTTON "&Abbrechen", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
END
|
||||
|
||||
@@ -91,8 +91,9 @@ BEGIN
|
||||
|
||||
CONTROL "Boot loader installation", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41
|
||||
|
||||
CONTROL "Install boot loader on the hard disk (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11
|
||||
CONTROL "Install boot loader on the hard disk (MBR and VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "Install boot loader on the hard disk (VBR only)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11
|
||||
CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11
|
||||
PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
PUSHBUTTON "&Cancel", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
END
|
||||
|
||||
@@ -89,8 +89,9 @@ BEGIN
|
||||
|
||||
CONTROL "Boot loader installation", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41
|
||||
|
||||
CONTROL "Install boot loader on the hard disk (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11
|
||||
CONTROL "Install boot loader on the hard disk (MBR and VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "Install boot loader on the hard disk (VBR only)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11
|
||||
CONTROL "No installation of bootloader", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11
|
||||
PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
PUSHBUTTON "&Cancel", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
END
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* https://sourceforge.net/projects/reactospl
|
||||
* http://rogers.cyberdusk.pl/
|
||||
* update - niski ([email protected])
|
||||
* updated by Caemyr (Olaf Siejka), Mar 2011
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
|
||||
@@ -97,7 +98,8 @@ BEGIN
|
||||
|
||||
CONTROL "Instalacja bootloadera", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41
|
||||
|
||||
CONTROL "Wgraj bootloader na dysk twardy (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "Wgraj bootloader na dysk twardy (MBR i VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "Wgraj bootloader na dysk twardy (tylko VBR)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11
|
||||
CONTROL "Pomiñ wgrywanie bootloadera", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11
|
||||
PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
PUSHBUTTON "&Anuluj", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* TRANSLATOR : Mário Kaèmár /Mario Kacmar/ aka Kario ([email protected])
|
||||
* DATE OF TR.: xx-xx-2007
|
||||
* LAST UPDATE: 03-12-2008
|
||||
* LAST UPDATE: 02-11-2010
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
|
||||
@@ -94,8 +94,9 @@ BEGIN
|
||||
|
||||
CONTROL "Inštalácia zavádzaèa systému", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41
|
||||
|
||||
CONTROL "Nainštalova� zavádzaè systému na pevný disk (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "Nenainštalova� zavádzaè systému", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11
|
||||
CONTROL "Nainštalova� zavádzaè systému na pevný disk (MBR a VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11
|
||||
CONTROL "Nainštalova� zavádzaè systému na pevný disk (iba VBR)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11
|
||||
CONTROL "Nenainštalova� zavádzaè systému", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,68,278,11
|
||||
PUSHBUTTON "&OK", IDOK, 180,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
PUSHBUTTON "&Zruši�", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE
|
||||
END
|
||||
|
||||
@@ -31,32 +31,33 @@
|
||||
#define IDC_PARTCREATE 2022
|
||||
#define IDC_PARTDELETE 2023
|
||||
#define IDC_INSTFREELDR 2024
|
||||
#define IDC_NOINSTFREELDR 2025
|
||||
#define IDC_PATH 2026
|
||||
#define IDD_PROCESSPAGE 2027
|
||||
#define IDS_PROCESSTITLE 2028
|
||||
#define IDS_PROCESSSUBTITLE 2029
|
||||
#define IDC_ACTIVITY 2030
|
||||
#define IDC_ITEM 2031
|
||||
#define IDC_PROCESSPROGRESS 2032
|
||||
#define IDD_RESTARTPAGE 2033
|
||||
#define IDS_RESTARTTITLE 2034
|
||||
#define IDS_RESTARTSUBTITLE 2035
|
||||
#define IDC_FINISHTITLE 2036
|
||||
#define IDC_RESTART_PROGRESS 2037
|
||||
#define IDS_ABORTSETUP 2038
|
||||
#define IDS_ABORTSETUP2 2039
|
||||
#define IDC_ACTION 2040
|
||||
#define IDC_PARTMOREOPTS 2041
|
||||
#define IDD_BOOTOPTIONS 2042
|
||||
#define IDD_PARTITION 2043
|
||||
#define IDC_UPDOWN1 2044
|
||||
#define IDC_PARTSIZE 2045
|
||||
#define IDC_UNIT 2046
|
||||
#define IDC_FSTYPE 2047
|
||||
#define IDD_SUMMARYPAGE 2048
|
||||
#define IDS_SUMMARYTITLE 2049
|
||||
#define IDS_SUMMARYSUBTITLE 2050
|
||||
#define IDC_DEVICEDRIVER 2051
|
||||
#define IDC_INSTVBRONLY 2025
|
||||
#define IDC_NOINSTFREELDR 2026
|
||||
#define IDC_PATH 2027
|
||||
#define IDD_PROCESSPAGE 2028
|
||||
#define IDS_PROCESSTITLE 2029
|
||||
#define IDS_PROCESSSUBTITLE 2030
|
||||
#define IDC_ACTIVITY 2031
|
||||
#define IDC_ITEM 2032
|
||||
#define IDC_PROCESSPROGRESS 2033
|
||||
#define IDD_RESTARTPAGE 2034
|
||||
#define IDS_RESTARTTITLE 2035
|
||||
#define IDS_RESTARTSUBTITLE 2036
|
||||
#define IDC_FINISHTITLE 2037
|
||||
#define IDC_RESTART_PROGRESS 2038
|
||||
#define IDS_ABORTSETUP 2039
|
||||
#define IDS_ABORTSETUP2 2040
|
||||
#define IDC_ACTION 2041
|
||||
#define IDC_PARTMOREOPTS 2042
|
||||
#define IDD_BOOTOPTIONS 2043
|
||||
#define IDD_PARTITION 2044
|
||||
#define IDC_UPDOWN1 2045
|
||||
#define IDC_PARTSIZE 2046
|
||||
#define IDC_UNIT 2047
|
||||
#define IDC_FSTYPE 2048
|
||||
#define IDD_SUMMARYPAGE 2049
|
||||
#define IDS_SUMMARYTITLE 2050
|
||||
#define IDS_SUMMARYSUBTITLE 2051
|
||||
#define IDC_DEVICEDRIVER 2052
|
||||
|
||||
#define IDI_MAIN 3000
|
||||
|
||||
@@ -944,6 +944,7 @@ CreatePartitionList (SHORT Left,
|
||||
List->Bottom = Bottom;
|
||||
|
||||
List->Line = 0;
|
||||
List->Offset = 0;
|
||||
|
||||
List->TopDisk = (ULONG)-1;
|
||||
List->TopPartition = (ULONG)-1;
|
||||
|
||||
@@ -41,7 +41,7 @@ extern void explorer_show_frame(int cmdshow, LPTSTR lpCmdLine=NULL);
|
||||
extern void explorer_about(HWND hwndParent);
|
||||
|
||||
// test for already running desktop instance
|
||||
extern BOOL IsAnyDesktopRunning();
|
||||
extern BOOL IsAnyDesktopRunning(void);
|
||||
|
||||
// show shutdown dialog
|
||||
extern void ShowExitWindowsDialog(HWND hwndOwner);
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
DECL_NOTIFYHOOK UINT InstallNotifyHook();
|
||||
DECL_NOTIFYHOOK void DeinstallNotifyHook();
|
||||
DECL_NOTIFYHOOK UINT InstallNotifyHook(void);
|
||||
DECL_NOTIFYHOOK void DeinstallNotifyHook(void);
|
||||
|
||||
DECL_NOTIFYHOOK void GetWindowModulePath(HWND hwnd);
|
||||
DECL_NOTIFYHOOK int GetWindowModulePathCopyData(LPARAM lparam, HWND* phwnd, LPSTR buffer, int size);
|
||||
|
||||
@@ -4558,42 +4558,40 @@ DWORD RQueryServiceConfig2A(
|
||||
LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer;
|
||||
LPSTR lpStr;
|
||||
|
||||
*pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA);
|
||||
|
||||
dwError = ScmReadString(hServiceKey,
|
||||
L"Description",
|
||||
&lpDescriptionW);
|
||||
if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
|
||||
goto done;
|
||||
|
||||
*pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA);
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
*pcbBytesNeeded += ((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR));
|
||||
|
||||
if (cbBufSize < *pcbBytesNeeded)
|
||||
{
|
||||
dwError = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (cbBufSize >= *pcbBytesNeeded)
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
lpStr = (LPSTR)(lpServiceDescription + 1);
|
||||
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
lpStr = (LPSTR)(lpServiceDescription + 1);
|
||||
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
lpDescriptionW,
|
||||
-1,
|
||||
lpStr,
|
||||
wcslen(lpDescriptionW),
|
||||
NULL,
|
||||
NULL);
|
||||
lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpServiceDescription->lpDescription = NULL;
|
||||
goto done;
|
||||
}
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
lpDescriptionW,
|
||||
-1,
|
||||
lpStr,
|
||||
wcslen(lpDescriptionW),
|
||||
NULL,
|
||||
NULL);
|
||||
lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
dwError = ERROR_INSUFFICIENT_BUFFER;
|
||||
lpServiceDescription->lpDescription = NULL;
|
||||
dwError = ERROR_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@@ -4681,21 +4679,30 @@ DWORD RQueryServiceConfig2W(
|
||||
dwError = ScmReadString(hServiceKey,
|
||||
L"Description",
|
||||
&lpDescription);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
|
||||
goto done;
|
||||
|
||||
dwRequiredSize = sizeof(SERVICE_DESCRIPTIONW) + ((wcslen(lpDescription) + 1) * sizeof(WCHAR));
|
||||
*pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONW);
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
*pcbBytesNeeded += ((wcslen(lpDescription) + 1) * sizeof(WCHAR));
|
||||
|
||||
if (cbBufSize < dwRequiredSize)
|
||||
if (cbBufSize < *pcbBytesNeeded)
|
||||
{
|
||||
*pcbBytesNeeded = dwRequiredSize;
|
||||
dwError = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto done;
|
||||
}
|
||||
|
||||
lpStr = (LPWSTR)(lpServiceDescription + 1);
|
||||
wcscpy(lpStr, lpDescription);
|
||||
lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
lpStr = (LPWSTR)(lpServiceDescription + 1);
|
||||
wcscpy(lpStr, lpDescription);
|
||||
lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpServiceDescription->lpDescription = NULL;
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||
{
|
||||
|
||||
@@ -102,4 +102,4 @@ void btext_drawhex(unsigned long v);
|
||||
void *ioremap(__u32 phys, __u32 size);
|
||||
void iounmap(void *logical);
|
||||
|
||||
__u32 GetPVR();
|
||||
__u32 GetPVR(void);
|
||||
|
||||
@@ -7,8 +7,8 @@ struct _pci_bar {
|
||||
unsigned long data;
|
||||
};
|
||||
|
||||
void sync();
|
||||
void PpcPrepInit();
|
||||
void sync( void );
|
||||
void PpcPrepInit( void );
|
||||
void ide_seek( void *extension, int low, int high );
|
||||
int ide_read( void *extension, char *buffer, int bytes );
|
||||
void ide_setup( void *extension );
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef struct _PAGE_DIRECTORY_AMD64
|
||||
} PAGE_DIRECTORY_AMD64, *PPAGE_DIRECTORY_AMD64;
|
||||
|
||||
|
||||
VOID FrLdrSetupGdtIdt();
|
||||
VOID FrLdrSetupGdtIdt(VOID);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
VOID PcMachInit(const char *CmdLine);
|
||||
|
||||
VOID PcConsPutChar(int Ch);
|
||||
BOOLEAN PcConsKbHit();
|
||||
int PcConsGetCh();
|
||||
BOOLEAN PcConsKbHit(VOID);
|
||||
int PcConsGetCh(VOID);
|
||||
|
||||
VOID PcVideoClearScreen(UCHAR Attr);
|
||||
VIDEODISPLAYMODE PcVideoSetDisplayMode(char *DisplayMode, BOOLEAN Init);
|
||||
|
||||
@@ -77,8 +77,8 @@ VOID MachInit(const char *CmdLine);
|
||||
extern MACHVTBL MachVtbl;
|
||||
|
||||
VOID MachConsPutChar(int Ch);
|
||||
BOOLEAN MachConsKbHit();
|
||||
int MachConsGetCh();
|
||||
BOOLEAN MachConsKbHit(VOID);
|
||||
int MachConsGetCh(VOID);
|
||||
VOID MachVideoClearScreen(UCHAR Attr);
|
||||
VIDEODISPLAYMODE MachVideoSetDisplayMode(char *DisplayMode, BOOLEAN Init);
|
||||
VOID MachVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth);
|
||||
|
||||
@@ -116,7 +116,7 @@ BEGIN
|
||||
CONTROL "Èçîáðàçÿâàíå íà &ñåíêè ïîä èçáîðíèöòå",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Ïîêàçâàíå íà ñúäúðæàíèåòî íà &ïðîçîðöèòå ïî âðåìå íà âëà÷åíå",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "Ñ&êðèâàíå íà ïîä÷åðòàâàíåòî çà êëàâèàòóðíîòî íàñî÷âàíå, äî íàòèñêàíå íà Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Îòêàç", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -119,7 +119,7 @@ BEGIN
|
||||
CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -112,7 +112,7 @@ BEGIN
|
||||
CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -115,7 +115,7 @@ BEGIN
|
||||
CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -113,7 +113,7 @@ BEGIN
|
||||
CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -112,7 +112,7 @@ BEGIN
|
||||
CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -112,7 +112,7 @@ BEGIN
|
||||
CONTROL "&Ombreggiatura sotto i menu",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Mostrare il contenuto delle finestr mentre le si trascina",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Nascondere la sottolineatura delle lettere di navigazione finche non è premuto il tasto Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Annulla", IDCANCEL, 226, 165, 50, 14
|
||||
@@ -260,6 +260,6 @@ END
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_DISPLAY_SETTINGS "Impostazioni del monitor"
|
||||
IDS_APPLY_FAILED "Impossibile applicare le uove impostazioni..."
|
||||
IDS_APPLY_FAILED "Impossibile applicare le nuove impostazioni..."
|
||||
IDS_APPLY_NEEDS_RESTART "E' necessario riavviare il computer per applicare le modifiche."
|
||||
END
|
||||
|
||||
@@ -114,7 +114,7 @@ BEGIN
|
||||
CONTROL "Sch&aduw onder menu's weergeven",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "De in&houd van het venster tijdens het slepen weergeven",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "Onderstreepte letters voor toetsenbordnavigatie &verbergen tot ALT wordt ingedrukt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Annuleren", IDCANCEL, 246, 165, 50, 14
|
||||
|
||||
@@ -114,7 +114,7 @@ BEGIN
|
||||
CONTROL "Vis sk&ygger under menyer",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Vis &vindu innholdet ved flytting",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Skjul visning av understrekning for tastatur hurtigtast til jeg trykker på Alt tasten",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Avbryt", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -122,7 +122,7 @@ BEGIN
|
||||
CONTROL "Pok&a¿ cienie pod menu",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Poka¿ za&wartoœæ okna podczas przeci¹gania",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "U&kryj podkreœlenie liter do nawigacji klawiatur¹ dopóki nie nacisnê klawisza Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Anuluj", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -116,7 +116,7 @@ BEGIN
|
||||
CONTROL "Afișare u&mbre sub meniuri",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Afișare c&onținut al ferestrelor când sunt trase",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Ascundere litere subliniate pentru navigarea cu tastatura până când apăs Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Anulare", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -112,7 +112,7 @@ BEGIN
|
||||
CONTROL "Îòîáðàæàòü &òåíè, îòáðàñûâàåìûå ìåíþ",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "&Îòîáðàæàòü ñîäåðæèìîå îêíà ïðè ïåðåòàñêèâàíèè",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "Ñêð&ûâàòü óêàçàòåëè âûçîâà ñ êëàâèàòóðû äî íàæàòèÿ <Alt>",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Îòìåíà", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -122,7 +122,7 @@ BEGIN
|
||||
CONTROL "&Zobrazova� tiene pod ponukami",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Zobrazova� &obsah okna poèas presúvania",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Skrýva� podèiarknuté písmená (klávesové skratky) až do stlaèenia klávesu Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Zruši�", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -115,7 +115,7 @@ BEGIN
|
||||
CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -120,7 +120,7 @@ BEGIN
|
||||
CONTROL "³äîáðàæàòè ò³í³ â³ä ìåíþ",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "Ïîêàçàòè &âì³ñò â³êíà ï³ä ÷àñ ïåðåòÿãóâàííÿ",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "&Ïðèõîâóâàòè ïîêàæ÷èêè âèêëèêó ç êëàâ³àòóðè äî íàòèñíåííÿ <Alt>",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "Ñêàñóâàòè", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -121,7 +121,7 @@ BEGIN
|
||||
CONTROL "在菜单下显示阴影(&A)",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19
|
||||
CONTROL "拖动时显示窗口内容(&W)",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19
|
||||
CONTROL "直到我按 Alt 键之前,请隐藏有下划线的字母供键盘使用",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19
|
||||
PUSHBUTTON "取消", IDCANCEL, 226, 165, 50, 14
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "input.h"
|
||||
|
||||
static HWND MainDlgWnd;
|
||||
static HIMAGELIST hImgList;
|
||||
// for SaveInputLang()
|
||||
static INT OldLayoutNum;
|
||||
|
||||
@@ -299,7 +298,7 @@ AddListColumn(HWND hWnd)
|
||||
}
|
||||
|
||||
static VOID
|
||||
InitLangList(HWND hWnd)
|
||||
InitLangList(HWND hWnd, HIMAGELIST hImgList)
|
||||
{
|
||||
HKEY hKey, hSubKey;
|
||||
TCHAR szBuf[MAX_PATH], szPreload[CCH_LAYOUT_ID + 1], szSub[CCH_LAYOUT_ID + 1];
|
||||
@@ -370,11 +369,19 @@ InitLangList(HWND hWnd)
|
||||
VOID
|
||||
UpdateLayoutsList(VOID)
|
||||
{
|
||||
(VOID) ImageList_Destroy(hImgList);
|
||||
HIMAGELIST hImgList;
|
||||
|
||||
/* Clear the list */
|
||||
(VOID) ListView_DeleteAllItems(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST));
|
||||
|
||||
/* Crate new list */
|
||||
hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 0, 1);
|
||||
InitLangList(MainDlgWnd);
|
||||
(VOID) ListView_SetImageList(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), hImgList, LVSIL_SMALL);
|
||||
InitLangList(MainDlgWnd, hImgList);
|
||||
hImgList = ListView_SetImageList(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), hImgList, LVSIL_SMALL);
|
||||
|
||||
/* Destroy old image list */
|
||||
if(hImgList)
|
||||
(VOID) ImageList_Destroy(hImgList);
|
||||
}
|
||||
|
||||
typedef struct _REG_KB_ENTRY_
|
||||
@@ -728,12 +735,14 @@ SettingPageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
HIMAGELIST hImgList;
|
||||
|
||||
MainDlgWnd = hwndDlg;
|
||||
AddListColumn(hwndDlg);
|
||||
(VOID) ListView_SetExtendedListViewStyle(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST),
|
||||
LVS_EX_FULLROWSELECT);
|
||||
hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 0, 1);
|
||||
InitLangList(hwndDlg);
|
||||
InitLangList(hwndDlg, hImgList);
|
||||
(VOID) ListView_SetImageList(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), hImgList, LVSIL_SMALL);
|
||||
}
|
||||
break;
|
||||
@@ -781,7 +790,6 @@ SettingPageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
(VOID) ImageList_Destroy(hImgList);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,10 @@ list(APPEND SOURCE
|
||||
csr/connect.c
|
||||
dbg/dbgui.c
|
||||
ldr/actctx.c
|
||||
ldr/ldrapi.c
|
||||
ldr/ldrinit.c
|
||||
ldr/ldrpe.c
|
||||
ldr/ldrutils.c
|
||||
ldr/startup.c
|
||||
ldr/utils.c
|
||||
rtl/libsupp.c
|
||||
|
||||
@@ -8,6 +8,100 @@
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#define LDR_HASH_TABLE_ENTRIES 32
|
||||
|
||||
typedef struct _LDRP_TLS_DATA
|
||||
{
|
||||
LIST_ENTRY TlsLinks;
|
||||
IMAGE_TLS_DIRECTORY TlsDirectory;
|
||||
} LDRP_TLS_DATA, *PLDRP_TLS_DATA;
|
||||
|
||||
typedef BOOL
|
||||
(NTAPI *PDLLMAIN_FUNC)(HANDLE hInst,
|
||||
ULONG ul_reason_for_call,
|
||||
LPVOID lpReserved);
|
||||
|
||||
/* Global data */
|
||||
extern RTL_CRITICAL_SECTION LdrpLoaderLock;
|
||||
extern BOOLEAN LdrpInLdrInit;
|
||||
extern LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
|
||||
extern BOOLEAN ShowSnaps;
|
||||
extern UNICODE_STRING LdrpDefaultPath;
|
||||
|
||||
/* ldrinit.c */
|
||||
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL);
|
||||
NTSTATUS NTAPI LdrpInitializeThread(IN PCONTEXT Context);
|
||||
NTSTATUS NTAPI LdrpInitializeTls(VOID);
|
||||
NTSTATUS NTAPI LdrpAllocateTls(VOID);
|
||||
VOID NTAPI LdrpFreeTls(VOID);
|
||||
VOID NTAPI LdrpTlsCallback(PVOID BaseAddress, ULONG Reason);
|
||||
BOOLEAN NTAPI LdrpCallDllEntry(PDLLMAIN_FUNC EntryPoint, PVOID BaseAddress, ULONG Reason, PVOID Context);
|
||||
NTSTATUS NTAPI LdrpInitializeProcess(PCONTEXT Context, PVOID SystemArgument1);
|
||||
VOID NTAPI LdrpInitFailure(NTSTATUS Status);
|
||||
|
||||
|
||||
/* ldrpe.c */
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpSnapThunk(IN PVOID ExportBase,
|
||||
IN PVOID ImportBase,
|
||||
IN PIMAGE_THUNK_DATA OriginalThunk,
|
||||
IN OUT PIMAGE_THUNK_DATA Thunk,
|
||||
IN PIMAGE_EXPORT_DIRECTORY ExportEntry,
|
||||
IN ULONG ExportSize,
|
||||
IN BOOLEAN Static,
|
||||
IN LPSTR DllName);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
IN PLDR_DATA_TABLE_ENTRY LdrEntry);
|
||||
|
||||
|
||||
/* ldrutils.c */
|
||||
NTSTATUS NTAPI
|
||||
LdrpGetProcedureAddress(IN PVOID BaseAddress,
|
||||
IN PANSI_STRING Name,
|
||||
IN ULONG Ordinal,
|
||||
OUT PVOID *ProcedureAddress,
|
||||
IN BOOLEAN ExecuteInit);
|
||||
|
||||
PLDR_DATA_TABLE_ENTRY NTAPI
|
||||
LdrpAllocateDataTableEntry(IN PVOID BaseAddress);
|
||||
|
||||
VOID NTAPI
|
||||
LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
LdrpLoadDll(IN BOOLEAN Redirected,
|
||||
IN PWSTR DllPath OPTIONAL,
|
||||
IN PULONG DllCharacteristics OPTIONAL,
|
||||
IN PUNICODE_STRING DllName,
|
||||
OUT PVOID *BaseAddress,
|
||||
IN BOOLEAN CallInit);
|
||||
|
||||
ULONG NTAPI
|
||||
LdrpClearLoadInProgress();
|
||||
|
||||
BOOLEAN NTAPI
|
||||
LdrpCheckForLoadedDll(IN PWSTR DllPath,
|
||||
IN PUNICODE_STRING DllName,
|
||||
IN BOOLEAN Flag,
|
||||
IN BOOLEAN RedirectedDll,
|
||||
OUT PLDR_DATA_TABLE_ENTRY *LdrEntry);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
LdrpMapDll(IN PWSTR SearchPath OPTIONAL,
|
||||
IN PWSTR DllPath2,
|
||||
IN PWSTR DllName OPTIONAL,
|
||||
IN PULONG DllCharacteristics,
|
||||
IN BOOLEAN Static,
|
||||
IN BOOLEAN Redirect,
|
||||
OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry);
|
||||
|
||||
PVOID NTAPI
|
||||
LdrpFetchAddressOfEntryPoint(PVOID ImageBase);
|
||||
|
||||
|
||||
/* FIXME: Cleanup this mess */
|
||||
typedef NTSTATUS (NTAPI *PEPFUNC)(PPEB);
|
||||
NTSTATUS LdrMapSections(HANDLE ProcessHandle,
|
||||
@@ -23,10 +117,6 @@ PEPFUNC LdrPEStartup (PVOID ImageBase,
|
||||
HANDLE SectionHandle,
|
||||
PLDR_DATA_TABLE_ENTRY* Module,
|
||||
PWSTR FullDosName);
|
||||
typedef BOOL
|
||||
(NTAPI *PDLLMAIN_FUNC)(HANDLE hInst,
|
||||
ULONG ul_reason_for_call,
|
||||
LPVOID lpReserved);
|
||||
|
||||
extern HANDLE WindowsApiPort;
|
||||
|
||||
|
||||
@@ -0,0 +1,533 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS NT User Mode Library
|
||||
* FILE: dll/ntdll/ldr/ldrapi.c
|
||||
* PURPOSE: PE Loader Public APIs
|
||||
* PROGRAMMERS: Alex Ionescu ([email protected])
|
||||
* Aleksey Bragin ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntdll.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define LDR_LOCK_HELD 0x2
|
||||
#define LDR_LOCK_FREE 0x1
|
||||
|
||||
LONG LdrpLoaderLockAcquisitonCount;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrUnlockLoaderLock(IN ULONG Flags,
|
||||
IN ULONG Cookie OPTIONAL)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("LdrUnlockLoaderLock(%x %x)\n", Flags, Cookie);
|
||||
|
||||
/* Check for valid flags */
|
||||
if (Flags & ~1)
|
||||
{
|
||||
/* Flags are invalid, check how to fail */
|
||||
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
|
||||
{
|
||||
/* The caller wants us to raise status */
|
||||
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A normal failure */
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't have a cookie, just return */
|
||||
if (!Cookie) return STATUS_SUCCESS;
|
||||
|
||||
/* Validate the cookie */
|
||||
if ((Cookie & 0xF0000000) ||
|
||||
((Cookie >> 16) ^ ((ULONG)(NtCurrentTeb()->RealClientId.UniqueThread) & 0xFFF)))
|
||||
{
|
||||
DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n");
|
||||
|
||||
/* Invalid cookie, check how to fail */
|
||||
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
|
||||
{
|
||||
/* The caller wants us to raise status */
|
||||
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A normal failure */
|
||||
return STATUS_INVALID_PARAMETER_2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ready to release the lock */
|
||||
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
|
||||
{
|
||||
/* Do a direct leave */
|
||||
RtlLeaveCriticalSection(&LdrpLoaderLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wrap this in SEH, since we're not supposed to raise */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Leave the lock */
|
||||
RtlLeaveCriticalSection(&LdrpLoaderLock);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* We should use the LDR Filter instead */
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrLockLoaderLock(IN ULONG Flags,
|
||||
OUT PULONG Result OPTIONAL,
|
||||
OUT PULONG Cookie OPTIONAL)
|
||||
{
|
||||
LONG OldCount;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
BOOLEAN InInit = LdrpInLdrInit;
|
||||
|
||||
DPRINT("LdrLockLoaderLock(%x %p %p)\n", Flags, Result, Cookie);
|
||||
|
||||
/* Zero out the outputs */
|
||||
if (Result) *Result = 0;
|
||||
if (Cookie) *Cookie = 0;
|
||||
|
||||
/* Validate the flags */
|
||||
if (Flags & ~(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS |
|
||||
LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY))
|
||||
{
|
||||
/* Flags are invalid, check how to fail */
|
||||
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
|
||||
{
|
||||
/* The caller wants us to raise status */
|
||||
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
|
||||
}
|
||||
|
||||
/* A normal failure */
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
|
||||
/* Make sure we got a cookie */
|
||||
if (!Cookie)
|
||||
{
|
||||
/* No cookie check how to fail */
|
||||
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
|
||||
{
|
||||
/* The caller wants us to raise status */
|
||||
RtlRaiseStatus(STATUS_INVALID_PARAMETER_3);
|
||||
}
|
||||
|
||||
/* A normal failure */
|
||||
return STATUS_INVALID_PARAMETER_3;
|
||||
}
|
||||
|
||||
/* If the flag is set, make sure we have a valid pointer to use */
|
||||
if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result))
|
||||
{
|
||||
/* No pointer to return the data to */
|
||||
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
|
||||
{
|
||||
/* The caller wants us to raise status */
|
||||
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
|
||||
}
|
||||
|
||||
/* Fail */
|
||||
return STATUS_INVALID_PARAMETER_2;
|
||||
}
|
||||
|
||||
/* Return now if we are in the init phase */
|
||||
if (InInit) return STATUS_SUCCESS;
|
||||
|
||||
/* Check what locking semantic to use */
|
||||
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS)
|
||||
{
|
||||
/* Check if we should enter or simply try */
|
||||
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)
|
||||
{
|
||||
/* Do a try */
|
||||
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
|
||||
{
|
||||
/* It's locked */
|
||||
*Result = LDR_LOCK_HELD;
|
||||
goto Quickie;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It worked */
|
||||
*Result = LDR_LOCK_FREE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do a enter */
|
||||
RtlEnterCriticalSection(&LdrpLoaderLock);
|
||||
|
||||
/* See if result was requested */
|
||||
if (Result) *Result = LDR_LOCK_FREE;
|
||||
}
|
||||
|
||||
/* Increase the acquisition count */
|
||||
OldCount = _InterlockedIncrement(&LdrpLoaderLockAcquisitonCount);
|
||||
|
||||
/* Generate a cookie */
|
||||
*Cookie = (((ULONG)NtCurrentTeb()->RealClientId.UniqueThread & 0xFFF) << 16) | OldCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wrap this in SEH, since we're not supposed to raise */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Check if we should enter or simply try */
|
||||
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)
|
||||
{
|
||||
/* Do a try */
|
||||
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
|
||||
{
|
||||
/* It's locked */
|
||||
*Result = LDR_LOCK_HELD;
|
||||
_SEH2_YIELD(return STATUS_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It worked */
|
||||
*Result = LDR_LOCK_FREE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do an enter */
|
||||
RtlEnterCriticalSection(&LdrpLoaderLock);
|
||||
|
||||
/* See if result was requested */
|
||||
if (Result) *Result = LDR_LOCK_FREE;
|
||||
}
|
||||
|
||||
/* Increase the acquisition count */
|
||||
OldCount = _InterlockedIncrement(&LdrpLoaderLockAcquisitonCount);
|
||||
|
||||
/* Generate a cookie */
|
||||
*Cookie = (((ULONG)NtCurrentTeb()->RealClientId.UniqueThread & 0xFFF) << 16) | OldCount;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* We should use the LDR Filter instead */
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
Quickie:
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrVerifyImageMatchesChecksum(IN HANDLE FileHandle,
|
||||
IN PLDR_CALLBACK Callback,
|
||||
IN PVOID CallbackContext,
|
||||
OUT PUSHORT ImageCharacteristics)
|
||||
{
|
||||
FILE_STANDARD_INFORMATION FileStandardInfo;
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportData;
|
||||
PIMAGE_SECTION_HEADER LastSection;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
HANDLE SectionHandle;
|
||||
SIZE_T ViewSize = 0;
|
||||
PVOID ViewBase = NULL;
|
||||
BOOLEAN Result;
|
||||
NTSTATUS Status;
|
||||
PVOID ImportName;
|
||||
ULONG Size;
|
||||
|
||||
DPRINT("LdrVerifyImageMatchesChecksum() called\n");
|
||||
|
||||
/* Create the section */
|
||||
Status = NtCreateSection(&SectionHandle,
|
||||
SECTION_MAP_EXECUTE,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_EXECUTE,
|
||||
SEC_COMMIT,
|
||||
FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("NtCreateSection() failed (Status 0x%x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map the section */
|
||||
Status = NtMapViewOfSection(SectionHandle,
|
||||
NtCurrentProcess(),
|
||||
&ViewBase,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&ViewSize,
|
||||
ViewShare,
|
||||
0,
|
||||
PAGE_EXECUTE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status);
|
||||
NtClose(SectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get the file information */
|
||||
Status = NtQueryInformationFile(FileHandle,
|
||||
&IoStatusBlock,
|
||||
&FileStandardInfo,
|
||||
sizeof(FILE_STANDARD_INFORMATION),
|
||||
FileStandardInformation);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status);
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
|
||||
NtClose(SectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Protect with SEH */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Verify the checksum */
|
||||
Result = LdrVerifyMappedImageMatchesChecksum(ViewBase,
|
||||
ViewSize,
|
||||
FileStandardInfo.EndOfFile.LowPart);
|
||||
|
||||
/* Check if a callback was supplied */
|
||||
if (Result && Callback)
|
||||
{
|
||||
/* Get the NT Header */
|
||||
NtHeader = RtlImageNtHeader(ViewBase);
|
||||
|
||||
/* Check if caller requested this back */
|
||||
if (ImageCharacteristics)
|
||||
{
|
||||
/* Return to caller */
|
||||
*ImageCharacteristics = NtHeader->FileHeader.Characteristics;
|
||||
}
|
||||
|
||||
/* Get the Import Directory Data */
|
||||
ImportData = RtlImageDirectoryEntryToData(ViewBase,
|
||||
FALSE,
|
||||
IMAGE_DIRECTORY_ENTRY_IMPORT,
|
||||
&Size);
|
||||
|
||||
/* Make sure there is one */
|
||||
if (ImportData)
|
||||
{
|
||||
/* Loop the imports */
|
||||
while (ImportData->Name)
|
||||
{
|
||||
/* Get the name */
|
||||
ImportName = RtlImageRvaToVa(NtHeader,
|
||||
ViewBase,
|
||||
ImportData->Name,
|
||||
&LastSection);
|
||||
|
||||
/* Notify the callback */
|
||||
Callback(CallbackContext, ImportName);
|
||||
ImportData++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* Fail the request returning STATUS_IMAGE_CHECKSUM_MISMATCH */
|
||||
Result = FALSE;
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
/* Unmap file and close handle */
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
|
||||
NtClose(SectionHandle);
|
||||
|
||||
/* Return status */
|
||||
return !Result ? STATUS_IMAGE_CHECKSUM_MISMATCH : Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrGetProcedureAddress_(IN PVOID BaseAddress,
|
||||
IN PANSI_STRING Name,
|
||||
IN ULONG Ordinal,
|
||||
OUT PVOID *ProcedureAddress)
|
||||
{
|
||||
/* Call the internal routine and tell it to execute DllInit */
|
||||
return LdrpGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress, TRUE);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrQueryProcessModuleInformationEx(IN ULONG ProcessId,
|
||||
IN ULONG Reserved,
|
||||
IN PRTL_PROCESS_MODULES ModuleInformation,
|
||||
IN ULONG Size,
|
||||
OUT PULONG ReturnedSize OPTIONAL)
|
||||
{
|
||||
PLIST_ENTRY ModuleListHead, InitListHead;
|
||||
PLIST_ENTRY Entry, InitEntry;
|
||||
PLDR_DATA_TABLE_ENTRY Module, InitModule;
|
||||
PRTL_PROCESS_MODULE_INFORMATION ModulePtr = NULL;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG UsedSize = sizeof(ULONG);
|
||||
ANSI_STRING AnsiString;
|
||||
PCHAR p;
|
||||
|
||||
DPRINT("LdrQueryProcessModuleInformation() called\n");
|
||||
|
||||
/* Acquire loader lock */
|
||||
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
|
||||
/* Check if we were given enough space */
|
||||
if (Size < UsedSize)
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
ModuleInformation->NumberOfModules = 0;
|
||||
ModulePtr = &ModuleInformation->Modules[0];
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Traverse the list of modules */
|
||||
_SEH2_TRY
|
||||
{
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||
|
||||
DPRINT(" Module %wZ\n", &Module->FullDllName);
|
||||
|
||||
/* Increase the used size */
|
||||
UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION);
|
||||
|
||||
if (UsedSize > Size)
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
ModulePtr->ImageBase = Module->DllBase;
|
||||
ModulePtr->ImageSize = Module->SizeOfImage;
|
||||
ModulePtr->Flags = Module->Flags;
|
||||
ModulePtr->LoadCount = Module->LoadCount;
|
||||
ModulePtr->MappedBase = NULL;
|
||||
ModulePtr->InitOrderIndex = 0;
|
||||
ModulePtr->LoadOrderIndex = ModuleInformation->NumberOfModules;
|
||||
|
||||
/* Now get init order index by traversing init list */
|
||||
InitListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
|
||||
InitEntry = InitListHead->Flink;
|
||||
|
||||
while (InitEntry != InitListHead)
|
||||
{
|
||||
InitModule = CONTAINING_RECORD(InitEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
|
||||
|
||||
/* Increase the index */
|
||||
ModulePtr->InitOrderIndex++;
|
||||
|
||||
/* Quit the loop if our module is found */
|
||||
if (InitModule == Module) break;
|
||||
|
||||
/* Advance to the next entry */
|
||||
InitEntry = InitEntry->Flink;
|
||||
}
|
||||
|
||||
/* Prepare ANSI string with the module's name */
|
||||
AnsiString.Length = 0;
|
||||
AnsiString.MaximumLength = sizeof(ModulePtr->FullPathName);
|
||||
AnsiString.Buffer = ModulePtr->FullPathName;
|
||||
RtlUnicodeStringToAnsiString(&AnsiString,
|
||||
&Module->FullDllName,
|
||||
FALSE);
|
||||
|
||||
/* Calculate OffsetToFileName field */
|
||||
p = strrchr(ModulePtr->FullPathName, '\\');
|
||||
if (p != NULL)
|
||||
ModulePtr->OffsetToFileName = p - ModulePtr->FullPathName + 1;
|
||||
else
|
||||
ModulePtr->OffsetToFileName = 0;
|
||||
|
||||
/* Advance to the next module in the output list */
|
||||
ModulePtr++;
|
||||
|
||||
/* Increase number of modules */
|
||||
if (ModuleInformation)
|
||||
ModuleInformation->NumberOfModules++;
|
||||
}
|
||||
|
||||
/* Go to the next entry in the modules list */
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
/* Set returned size if it was provided */
|
||||
if (ReturnedSize)
|
||||
*ReturnedSize = UsedSize;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* Ignoring the exception */
|
||||
} _SEH2_END;
|
||||
|
||||
/* Release the lock */
|
||||
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
|
||||
DPRINT("LdrQueryProcessModuleInformation() done\n");
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation,
|
||||
IN ULONG Size,
|
||||
OUT PULONG ReturnedSize OPTIONAL)
|
||||
{
|
||||
/* Call Ex version of the API */
|
||||
return LdrQueryProcessModuleInformationEx(0, 0, ModuleInformation, Size, ReturnedSize);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,695 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS NT User-Mode Library
|
||||
* FILE: dll/ntdll/ldr/ldrutils.c
|
||||
* PURPOSE: Internal Loader Utility Functions
|
||||
* PROGRAMMERS: Alex Ionescu ([email protected])
|
||||
* Aleksey Bragin ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntdll.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache;
|
||||
|
||||
#define LDR_GET_HASH_ENTRY(x) (RtlUpcaseUnicodeChar((x)) & (LDR_HASH_TABLE_ENTRIES - 1))
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
LdrpCallDllEntry(PDLLMAIN_FUNC EntryPoint,
|
||||
PVOID BaseAddress,
|
||||
ULONG Reason,
|
||||
PVOID Context)
|
||||
{
|
||||
/* Call the entry */
|
||||
return EntryPoint(BaseAddress, Reason, Context);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LdrpTlsCallback(PVOID BaseAddress, ULONG Reason)
|
||||
{
|
||||
PIMAGE_TLS_DIRECTORY TlsDirectory;
|
||||
PIMAGE_TLS_CALLBACK *Array, Callback;
|
||||
ULONG Size;
|
||||
|
||||
/* Get the TLS Directory */
|
||||
TlsDirectory = RtlImageDirectoryEntryToData(BaseAddress,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_TLS,
|
||||
&Size);
|
||||
|
||||
/* Protect against invalid pointers */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Make sure it's valid and we have an array */
|
||||
if (TlsDirectory && (Array = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks))
|
||||
{
|
||||
/* Display debug */
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: Tls Callbacks Found. Imagebase %p Tls %p CallBacks %p\n",
|
||||
BaseAddress, TlsDirectory, Array);
|
||||
}
|
||||
|
||||
/* Loop the array */
|
||||
while (*Array)
|
||||
{
|
||||
/* Get the TLS Entrypoint */
|
||||
Callback = *Array++;
|
||||
|
||||
/* Display debug */
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: Calling Tls Callback Imagebase %p Function %p\n",
|
||||
BaseAddress, Callback);
|
||||
}
|
||||
|
||||
/* Call it */
|
||||
LdrpCallDllEntry((PDLLMAIN_FUNC)Callback, BaseAddress, Reason, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
LdrpFetchAddressOfEntryPoint(PVOID ImageBase)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeaders;
|
||||
ULONG_PTR EntryPoint;
|
||||
|
||||
/* Get entry point offset from NT headers */
|
||||
NtHeaders = RtlImageNtHeader(ImageBase);
|
||||
EntryPoint = NtHeaders->OptionalHeader.AddressOfEntryPoint;
|
||||
|
||||
/* If it's 0 - return so */
|
||||
if (!EntryPoint) return NULL;
|
||||
|
||||
/* Add image base */
|
||||
EntryPoint += (ULONG_PTR)ImageBase;
|
||||
|
||||
/* Return calculated pointer */
|
||||
return (PVOID)EntryPoint;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpMapDll(IN PWSTR SearchPath OPTIONAL,
|
||||
IN PWSTR DllPath2,
|
||||
IN PWSTR DllName OPTIONAL,
|
||||
IN PULONG DllCharacteristics,
|
||||
IN BOOLEAN Static,
|
||||
IN BOOLEAN Redirect,
|
||||
OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
PLDR_DATA_TABLE_ENTRY
|
||||
NTAPI
|
||||
LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
|
||||
{
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
|
||||
PIMAGE_NT_HEADERS NtHeader = RtlImageNtHeader(BaseAddress);
|
||||
|
||||
/* Make sure the header is valid */
|
||||
if (NtHeader)
|
||||
{
|
||||
/* Allocate an entry */
|
||||
LdrEntry = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(LDR_DATA_TABLE_ENTRY));
|
||||
|
||||
/* Make sure we got one */
|
||||
if (LdrEntry)
|
||||
{
|
||||
/* Set it up */
|
||||
LdrEntry->DllBase = BaseAddress;
|
||||
LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
|
||||
LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the entry */
|
||||
return LdrEntry;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
|
||||
{
|
||||
PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr;
|
||||
ULONG i;
|
||||
|
||||
/* Get the Hash entry */
|
||||
i = LDR_GET_HASH_ENTRY(LdrEntry->BaseDllName.Buffer[0]);
|
||||
|
||||
InsertTailList(&LdrpHashTable[i], &LdrEntry->HashLinks);
|
||||
InsertTailList(&PebData->InLoadOrderModuleList, &LdrEntry->InLoadOrderLinks);
|
||||
InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderModuleList);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
LdrpCheckForLoadedDllHandle(IN PVOID Base,
|
||||
OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
|
||||
{
|
||||
PLDR_DATA_TABLE_ENTRY Current;
|
||||
PLIST_ENTRY ListHead, Next;
|
||||
|
||||
/* Check the cache first */
|
||||
if (LdrpLoadedDllHandleCache && LdrpLoadedDllHandleCache->DllBase == Base)
|
||||
{
|
||||
/* We got lucky, return the cached entry */
|
||||
*LdrEntry = LdrpLoadedDllHandleCache;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Time for a lookup */
|
||||
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Next = ListHead->Flink;
|
||||
while(Next != ListHead)
|
||||
{
|
||||
/* Get the current entry */
|
||||
Current = CONTAINING_RECORD(Next,
|
||||
LDR_DATA_TABLE_ENTRY,
|
||||
InLoadOrderLinks);
|
||||
|
||||
/* Make sure it's not unloading and check for a match */
|
||||
if ((Current->InMemoryOrderModuleList.Flink) && (Base == Current->DllBase))
|
||||
{
|
||||
/* Save in cache */
|
||||
LdrpLoadedDllHandleCache = Current;
|
||||
|
||||
/* Return it */
|
||||
*LdrEntry = Current;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Move to the next one */
|
||||
Next = Next->Flink;
|
||||
}
|
||||
|
||||
/* Nothing found */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
LdrpCheckForLoadedDll(IN PWSTR DllPath,
|
||||
IN PUNICODE_STRING DllName,
|
||||
IN BOOLEAN Flag,
|
||||
IN BOOLEAN RedirectedDll,
|
||||
OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
|
||||
{
|
||||
ULONG HashIndex;
|
||||
PLIST_ENTRY ListHead, ListEntry;
|
||||
PLDR_DATA_TABLE_ENTRY CurEntry;
|
||||
BOOLEAN FullPath = FALSE;
|
||||
PWCHAR wc;
|
||||
WCHAR NameBuf[266];
|
||||
UNICODE_STRING FullDllName, NtPathName;
|
||||
ULONG Length;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
NTSTATUS Status;
|
||||
HANDLE FileHandle, SectionHandle;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
PVOID ViewBase = NULL;
|
||||
SIZE_T ViewSize = 0;
|
||||
PIMAGE_NT_HEADERS NtHeader, NtHeader2;
|
||||
DPRINT1("LdrpCheckForLoadedDll('%S' '%wZ' %d %d %p)\n", DllPath, DllName, Flag, RedirectedDll, LdrEntry);
|
||||
/* Check if a dll name was provided */
|
||||
if (!DllName->Buffer || !DllName->Buffer[0]) return FALSE;
|
||||
|
||||
/* Look in the hash table if flag was set */
|
||||
lookinhash:
|
||||
if (Flag)
|
||||
{
|
||||
/* Get hash index */
|
||||
HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
|
||||
|
||||
/* Traverse that list */
|
||||
ListHead = &LdrpHashTable[HashIndex];
|
||||
ListEntry = ListHead->Flink;
|
||||
while (ListEntry != ListHead)
|
||||
{
|
||||
/* Get the current entry */
|
||||
CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
|
||||
|
||||
/* Check base name of that module */
|
||||
if (RtlEqualUnicodeString(DllName, &CurEntry->BaseDllName, TRUE))
|
||||
{
|
||||
/* It matches, return it */
|
||||
*LdrEntry = CurEntry;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Advance to the next entry */
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Module was not found, return failure */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check if there is a full path in this DLL */
|
||||
wc = DllName->Buffer;
|
||||
while (*wc)
|
||||
{
|
||||
/* Check for a slash in the current position*/
|
||||
if (*wc == L'\\' || *wc == L'/')
|
||||
{
|
||||
/* Found the slash, so dll name contains path */
|
||||
FullPath = TRUE;
|
||||
|
||||
/* Setup full dll name string */
|
||||
FullDllName.Buffer = NameBuf;
|
||||
|
||||
Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer,
|
||||
DllName->Buffer,
|
||||
NULL,
|
||||
sizeof(NameBuf) - sizeof(UNICODE_NULL),
|
||||
FullDllName.Buffer,
|
||||
NULL);
|
||||
|
||||
/* Check if that was successful */
|
||||
if (!Length || Length > sizeof(NameBuf) - sizeof(UNICODE_NULL))
|
||||
{
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %ws: 0x%08x\n",
|
||||
DllName->Buffer, Length);
|
||||
}
|
||||
|
||||
/* Return failure */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Full dll name is found */
|
||||
FullDllName.Length = Length;
|
||||
FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
wc++;
|
||||
}
|
||||
|
||||
/* Go check the hash table */
|
||||
if (!FullPath)
|
||||
{
|
||||
Flag = TRUE;
|
||||
goto lookinhash;
|
||||
}
|
||||
|
||||
/* Now go through the InLoadOrder module list */
|
||||
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
ListEntry = ListHead->Flink;
|
||||
|
||||
while (ListEntry != ListHead)
|
||||
{
|
||||
/* Get the containing record of the current entry and advance to the next one */
|
||||
CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||
ListEntry = ListEntry->Flink;
|
||||
|
||||
/* Check if it's already being unloaded */
|
||||
if (!CurEntry->InMemoryOrderModuleList.Flink) continue;
|
||||
|
||||
/* Check if name matches */
|
||||
if (RtlEqualUnicodeString(&FullDllName,
|
||||
&CurEntry->FullDllName,
|
||||
TRUE))
|
||||
{
|
||||
/* Found it */
|
||||
*LdrEntry = CurEntry;
|
||||
|
||||
/* Find activation context */
|
||||
Status = RtlFindActivationContextSectionString(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, DllName, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* The DLL was not found in the load order modules list. Perform a complex check */
|
||||
|
||||
/* Convert given path to NT path */
|
||||
if (!RtlDosPathNameToNtPathName_U(FullDllName.Buffer,
|
||||
&NtPathName,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
/* Fail if conversion failed */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize object attributes and open it */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&NtPathName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenFile(&FileHandle,
|
||||
SYNCHRONIZE | FILE_EXECUTE,
|
||||
&ObjectAttributes,
|
||||
&Iosb,
|
||||
FILE_SHARE_READ | FILE_SHARE_DELETE,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
|
||||
/* Free NT path name */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
|
||||
|
||||
/* If opening the file failed - return failure */
|
||||
if (!NT_SUCCESS(Status)) return FALSE;
|
||||
|
||||
/* Create a section for this file */
|
||||
Status = NtCreateSection(&SectionHandle,
|
||||
SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_WRITE,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_EXECUTE,
|
||||
SEC_COMMIT,
|
||||
FileHandle);
|
||||
|
||||
/* Close file handle */
|
||||
NtClose(FileHandle);
|
||||
|
||||
/* If creating section failed - return failure */
|
||||
if (!NT_SUCCESS(Status)) return FALSE;
|
||||
|
||||
/* Map view of this section */
|
||||
Status = ZwMapViewOfSection(SectionHandle,
|
||||
NtCurrentProcess(),
|
||||
&ViewBase,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&ViewSize,
|
||||
ViewShare,
|
||||
0,
|
||||
PAGE_EXECUTE);
|
||||
/* Close section handle */
|
||||
NtClose(SectionHandle);
|
||||
|
||||
/* If section mapping failed - return failure */
|
||||
if (!NT_SUCCESS(Status)) return FALSE;
|
||||
|
||||
/* Get pointer to the NT header of this section */
|
||||
NtHeader = RtlImageNtHeader(ViewBase);
|
||||
if (!NtHeader)
|
||||
{
|
||||
/* Unmap the section and fail */
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Go through the list of modules */
|
||||
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
ListEntry = ListHead->Flink;
|
||||
|
||||
while (ListEntry != ListHead)
|
||||
{
|
||||
CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||
ListEntry = ListEntry->Flink;
|
||||
|
||||
/* Check if it's already being unloaded */
|
||||
if (!CurEntry->InMemoryOrderModuleList.Flink) continue;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Check if timedate stamp and sizes match */
|
||||
if (CurEntry->TimeDateStamp == NtHeader->FileHeader.TimeDateStamp &&
|
||||
CurEntry->SizeOfImage == NtHeader->OptionalHeader.SizeOfImage)
|
||||
{
|
||||
/* Time, date and size match. Let's compare their headers */
|
||||
NtHeader2 = RtlImageNtHeader(CurEntry->DllBase);
|
||||
|
||||
if (RtlCompareMemory(NtHeader2, NtHeader, sizeof(IMAGE_NT_HEADERS)))
|
||||
{
|
||||
/* Headers match too! Finally ask the kernel to compare mapped files */
|
||||
Status = ZwAreMappedFilesTheSame(CurEntry->DllBase, ViewBase);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH2_YIELD(continue;)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is our entry! */
|
||||
*LdrEntry = CurEntry;
|
||||
|
||||
/* Unmap the section */
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
|
||||
|
||||
_SEH2_YIELD(return TRUE;)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
_SEH2_YIELD(break;)
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
/* Unmap the section */
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpGetProcedureAddress(IN PVOID BaseAddress,
|
||||
IN PANSI_STRING Name,
|
||||
IN ULONG Ordinal,
|
||||
OUT PVOID *ProcedureAddress,
|
||||
IN BOOLEAN ExecuteInit)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
UCHAR ImportBuffer[64];
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
IMAGE_THUNK_DATA Thunk;
|
||||
PVOID ImageBase;
|
||||
PIMAGE_IMPORT_BY_NAME ImportName = NULL;
|
||||
PIMAGE_EXPORT_DIRECTORY ExportDir;
|
||||
ULONG ExportDirSize;
|
||||
PLIST_ENTRY Entry;
|
||||
|
||||
/* Show debug message */
|
||||
if (ShowSnaps) DPRINT1("LDR: LdrGetProcedureAddress by ");
|
||||
|
||||
/* Check if we got a name */
|
||||
if (Name)
|
||||
{
|
||||
/* Show debug message */
|
||||
if (ShowSnaps) DPRINT1("NAME - %s\n", Name->Buffer);
|
||||
|
||||
/* Make sure it's not too long */
|
||||
if ((Name->Length + sizeof(CHAR) + sizeof(USHORT)) > MAXLONG)
|
||||
{
|
||||
/* Won't have enough space to add the hint */
|
||||
return STATUS_NAME_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Check if our buffer is large enough */
|
||||
if (Name->Length >= (sizeof(ImportBuffer) - sizeof(CHAR)))
|
||||
{
|
||||
/* Allocate from heap, plus 2 bytes for the Hint */
|
||||
ImportName = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
Name->Length + sizeof(CHAR) +
|
||||
sizeof(USHORT));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use our internal buffer */
|
||||
ImportName = (PIMAGE_IMPORT_BY_NAME)ImportBuffer;
|
||||
}
|
||||
|
||||
/* Clear the hint */
|
||||
ImportName->Hint = 0;
|
||||
|
||||
/* Copy the name and null-terminate it */
|
||||
RtlMoveMemory(&ImportName->Name, Name->Buffer, Name->Length);
|
||||
ImportName->Name[Name->Length + 1] = 0;
|
||||
|
||||
/* Clear the high bit */
|
||||
ImageBase = ImportName;
|
||||
Thunk.u1.AddressOfData = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do it by ordinal */
|
||||
ImageBase = NULL;
|
||||
|
||||
/* Show debug message */
|
||||
if (ShowSnaps) DPRINT1("ORDINAL - %lx\n", Ordinal);
|
||||
|
||||
if (Ordinal)
|
||||
{
|
||||
Thunk.u1.Ordinal = Ordinal | IMAGE_ORDINAL_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No ordinal */
|
||||
DPRINT1("No ordinal and no name\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/* Acquire lock unless we are initting */
|
||||
if (!LdrpInLdrInit) RtlEnterCriticalSection(&LdrpLoaderLock);
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Try to find the loaded DLL */
|
||||
if (!LdrpCheckForLoadedDllHandle(BaseAddress, &LdrEntry))
|
||||
{
|
||||
/* Invalid base */
|
||||
DPRINT1("Invalid base address\n");
|
||||
Status = STATUS_DLL_NOT_FOUND;
|
||||
_SEH2_YIELD(goto Quickie;)
|
||||
}
|
||||
|
||||
/* Get the pointer to the export directory */
|
||||
ExportDir = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
||||
&ExportDirSize);
|
||||
|
||||
if (!ExportDir)
|
||||
{
|
||||
DPRINT1("Image has no exports\n");
|
||||
Status = STATUS_PROCEDURE_NOT_FOUND;
|
||||
_SEH2_YIELD(goto Quickie;)
|
||||
}
|
||||
|
||||
/* Now get the thunk */
|
||||
Status = LdrpSnapThunk(LdrEntry->DllBase,
|
||||
ImageBase,
|
||||
&Thunk,
|
||||
&Thunk,
|
||||
ExportDir,
|
||||
ExportDirSize,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
/* Finally, see if we're supposed to run the init routines */
|
||||
if (ExecuteInit)
|
||||
{
|
||||
/*
|
||||
* It's possible a forwarded entry had us load the DLL. In that case,
|
||||
* then we will call its DllMain. Use the last loaded DLL for this.
|
||||
*/
|
||||
Entry = NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Blink;
|
||||
LdrEntry = CONTAINING_RECORD(Entry,
|
||||
LDR_DATA_TABLE_ENTRY,
|
||||
InInitializationOrderModuleList);
|
||||
|
||||
/* Make sure we didn't process it yet*/
|
||||
if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
|
||||
{
|
||||
/* Call the init routine */
|
||||
_SEH2_TRY
|
||||
{
|
||||
Status = LdrpRunInitializeRoutines(NULL);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* Get the exception code */
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we're OK till here */
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Return the address */
|
||||
*ProcedureAddress = (PVOID)Thunk.u1.Function;
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* Just ignore exceptions */
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
Quickie:
|
||||
/* Cleanup */
|
||||
if (ImportName && (ImportName != (PIMAGE_IMPORT_BY_NAME)ImportBuffer))
|
||||
{
|
||||
/* We allocated from heap, free it */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ImportName);
|
||||
}
|
||||
|
||||
/* Release the CS if we entered it */
|
||||
if (!LdrpInLdrInit) RtlLeaveCriticalSection(&LdrpLoaderLock);
|
||||
|
||||
/* We're done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpLoadDll(IN BOOLEAN Redirected,
|
||||
IN PWSTR DllPath OPTIONAL,
|
||||
IN PULONG DllCharacteristics OPTIONAL,
|
||||
IN PUNICODE_STRING DllName,
|
||||
OUT PVOID *BaseAddress,
|
||||
IN BOOLEAN CallInit)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
LdrpClearLoadInProgress()
|
||||
{
|
||||
PLIST_ENTRY ListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_DATA_TABLE_ENTRY Module;
|
||||
ULONG ModulesCount = 0;
|
||||
|
||||
/* Traverse the init list */
|
||||
ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
|
||||
Entry = ListHead->Flink;
|
||||
|
||||
while (Entry != ListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
|
||||
|
||||
/* Clear load in progress flag */
|
||||
Module->Flags &= ~LDRP_LOAD_IN_PROGRESS;
|
||||
|
||||
/* Increase counter for modules with entry point count but not processed yet */
|
||||
if (Module->EntryPoint &&
|
||||
!(Module->Flags & LDRP_ENTRY_PROCESSED)) ModulesCount++;
|
||||
|
||||
/* Advance to the next entry */
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
return ModulesCount;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
+32
-66
@@ -16,20 +16,16 @@
|
||||
|
||||
VOID RtlInitializeHeapManager(VOID);
|
||||
VOID LdrpInitLoader(VOID);
|
||||
VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
|
||||
NTSTATUS LdrpAttachThread(VOID);
|
||||
VOID RtlpInitializeVectoredExceptionHandling(VOID);
|
||||
extern PTEB LdrpTopLevelDllBeingLoadedTeb;
|
||||
VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
|
||||
VOID RtlpInitializeVectoredExceptionHandling(VOID);
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
PLDR_DATA_TABLE_ENTRY ExeModule;
|
||||
static RTL_CRITICAL_SECTION PebLock;
|
||||
static RTL_CRITICAL_SECTION LoaderLock;
|
||||
static RTL_BITMAP TlsBitMap;
|
||||
static RTL_BITMAP TlsExpansionBitMap;
|
||||
static volatile BOOLEAN LdrpInitialized = FALSE;
|
||||
static LONG LdrpInitLock = 0;
|
||||
extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry;
|
||||
extern RTL_CRITICAL_SECTION FastPebLock;
|
||||
extern RTL_BITMAP TlsBitMap;
|
||||
extern RTL_BITMAP TlsExpansionBitMap;
|
||||
|
||||
#define VALUE_BUFFER_SIZE 256
|
||||
|
||||
@@ -313,11 +309,10 @@ finish:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
LdrpInit2(PCONTEXT Context,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpInitializeProcess_(PCONTEXT Context,
|
||||
PVOID SystemArgument1)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NTHeaders;
|
||||
PEPFUNC EntryPoint;
|
||||
@@ -444,8 +439,8 @@ LdrpInit2(PCONTEXT Context,
|
||||
RtlpInitializeVectoredExceptionHandling();
|
||||
|
||||
/* initalize peb lock support */
|
||||
RtlInitializeCriticalSection(&PebLock);
|
||||
Peb->FastPebLock = &PebLock;
|
||||
RtlInitializeCriticalSection(&FastPebLock);
|
||||
Peb->FastPebLock = &FastPebLock;
|
||||
|
||||
/* initialize tls bitmaps */
|
||||
RtlInitializeBitMap(&TlsBitMap, Peb->TlsBitmapBits, TLS_MINIMUM_AVAILABLE);
|
||||
@@ -467,8 +462,8 @@ LdrpInit2(PCONTEXT Context,
|
||||
}
|
||||
|
||||
/* initalize loader lock */
|
||||
RtlInitializeCriticalSection(&LoaderLock);
|
||||
Peb->LoaderLock = &LoaderLock;
|
||||
RtlInitializeCriticalSection(&LdrpLoaderLock);
|
||||
Peb->LoaderLock = &LdrpLoaderLock;
|
||||
|
||||
/* create loader information */
|
||||
Peb->Ldr = (PPEB_LDR_DATA) RtlAllocateHeap(Peb->ProcessHeap,
|
||||
@@ -527,17 +522,17 @@ LdrpInit2(PCONTEXT Context,
|
||||
&NtModule->InInitializationOrderModuleList);
|
||||
|
||||
/* add entry for executable (becomes first list entry) */
|
||||
ExeModule = (PLDR_DATA_TABLE_ENTRY)
|
||||
LdrpImageEntry = (PLDR_DATA_TABLE_ENTRY)
|
||||
RtlAllocateHeap(Peb->ProcessHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(LDR_DATA_TABLE_ENTRY));
|
||||
if (ExeModule == NULL)
|
||||
if (LdrpImageEntry == NULL)
|
||||
{
|
||||
DPRINT1("Failed to create loader module infomation\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
ExeModule->DllBase = Peb->ImageBaseAddress;
|
||||
LdrpImageEntry->DllBase = Peb->ImageBaseAddress;
|
||||
|
||||
if ((Peb->ProcessParameters == NULL) ||
|
||||
(Peb->ProcessParameters->ImagePathName.Length == 0))
|
||||
@@ -546,32 +541,32 @@ LdrpInit2(PCONTEXT Context,
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
RtlCreateUnicodeString(&ExeModule->FullDllName,
|
||||
RtlCreateUnicodeString(&LdrpImageEntry->FullDllName,
|
||||
Peb->ProcessParameters->ImagePathName.Buffer);
|
||||
RtlCreateUnicodeString(&ExeModule->BaseDllName,
|
||||
wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1);
|
||||
RtlCreateUnicodeString(&LdrpImageEntry->BaseDllName,
|
||||
wcsrchr(LdrpImageEntry->FullDllName.Buffer, L'\\') + 1);
|
||||
|
||||
DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n", &ExeModule->BaseDllName, &ExeModule->FullDllName);
|
||||
DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n", &LdrpImageEntry->BaseDllName, &LdrpImageEntry->FullDllName);
|
||||
|
||||
ExeModule->Flags = LDRP_ENTRY_PROCESSED;
|
||||
ExeModule->LoadCount = -1; /* don't unload */
|
||||
ExeModule->TlsIndex = -1;
|
||||
ExeModule->SectionPointer = NULL;
|
||||
ExeModule->CheckSum = 0;
|
||||
LdrpImageEntry->Flags = LDRP_ENTRY_PROCESSED;
|
||||
LdrpImageEntry->LoadCount = -1; /* don't unload */
|
||||
LdrpImageEntry->TlsIndex = -1;
|
||||
LdrpImageEntry->SectionPointer = NULL;
|
||||
LdrpImageEntry->CheckSum = 0;
|
||||
|
||||
NTHeaders = RtlImageNtHeader(ExeModule->DllBase);
|
||||
ExeModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
|
||||
ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
||||
NTHeaders = RtlImageNtHeader(LdrpImageEntry->DllBase);
|
||||
LdrpImageEntry->SizeOfImage = LdrpGetResidentSize(NTHeaders);
|
||||
LdrpImageEntry->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
||||
|
||||
LdrpTopLevelDllBeingLoadedTeb = NtCurrentTeb();
|
||||
|
||||
InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
|
||||
&ExeModule->InLoadOrderLinks);
|
||||
&LdrpImageEntry->InLoadOrderLinks);
|
||||
|
||||
LdrpInitLoader();
|
||||
|
||||
EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL);
|
||||
ExeModule->EntryPoint = EntryPoint;
|
||||
LdrpImageEntry->EntryPoint = EntryPoint;
|
||||
|
||||
/* all required dlls are loaded now */
|
||||
Peb->Ldr->Initialized = TRUE;
|
||||
@@ -586,37 +581,8 @@ LdrpInit2(PCONTEXT Context,
|
||||
/* Break into debugger */
|
||||
if (Peb->BeingDebugged)
|
||||
DbgBreakPoint();
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LdrpInit(PCONTEXT Context,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
if (!LdrpInitialized)
|
||||
{
|
||||
if (!_InterlockedExchange(&LdrpInitLock, 1))
|
||||
{
|
||||
LdrpInit2(Context, SystemArgument1, SystemArgument2);
|
||||
LdrpInitialized = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LARGE_INTEGER Interval = {{-200000, -1}};
|
||||
|
||||
do
|
||||
{
|
||||
NtDelayExecution(FALSE, &Interval);
|
||||
}
|
||||
while (!LdrpInitialized);
|
||||
}
|
||||
}
|
||||
|
||||
/* attach the thread */
|
||||
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
LdrpAttachThread();
|
||||
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+65
-627
@@ -31,23 +31,11 @@
|
||||
#define TRACE_LDR(...) if (RtlGetNtGlobalFlags() & FLG_SHOW_LDR_SNAPS) { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(__VA_ARGS__); }
|
||||
#endif
|
||||
|
||||
typedef struct _TLS_DATA
|
||||
{
|
||||
PVOID StartAddressOfRawData;
|
||||
DWORD TlsDataSize;
|
||||
DWORD TlsZeroSize;
|
||||
PIMAGE_TLS_CALLBACK *TlsAddressOfCallBacks;
|
||||
PLDR_DATA_TABLE_ENTRY Module;
|
||||
} TLS_DATA, *PTLS_DATA;
|
||||
|
||||
static BOOLEAN LdrpDllShutdownInProgress = FALSE;
|
||||
static PTLS_DATA LdrpTlsArray = NULL;
|
||||
static ULONG LdrpTlsCount = 0;
|
||||
static ULONG LdrpTlsSize = 0;
|
||||
static HANDLE LdrpKnownDllsDirHandle = NULL;
|
||||
static UNICODE_STRING LdrpKnownDllPath = {0, 0, NULL};
|
||||
extern HANDLE LdrpKnownDllObjectDirectory;
|
||||
extern UNICODE_STRING LdrpKnownDllPath;
|
||||
static PLDR_DATA_TABLE_ENTRY LdrpLastModule = NULL;
|
||||
extern PLDR_DATA_TABLE_ENTRY ExeModule;
|
||||
extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry;
|
||||
|
||||
/* PROTOTYPES ****************************************************************/
|
||||
|
||||
@@ -59,7 +47,6 @@ static NTSTATUS LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
|
||||
IN PUNICODE_STRING Name,
|
||||
OUT PLDR_DATA_TABLE_ENTRY *Module,
|
||||
OUT PVOID *BaseAddress OPTIONAL);
|
||||
static NTSTATUS LdrpAttachProcess(VOID);
|
||||
static VOID LdrpDetachProcess(BOOLEAN UnloadAll);
|
||||
static NTSTATUS LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module, BOOLEAN Unload);
|
||||
|
||||
@@ -118,51 +105,6 @@ static __inline LONG LdrpIncrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEA
|
||||
return LoadCount;
|
||||
}
|
||||
|
||||
static __inline VOID LdrpAcquireTlsSlot(PLDR_DATA_TABLE_ENTRY Module, ULONG Size, BOOLEAN Locked)
|
||||
{
|
||||
if (!Locked)
|
||||
{
|
||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
}
|
||||
Module->TlsIndex = (SHORT)LdrpTlsCount;
|
||||
LdrpTlsCount++;
|
||||
LdrpTlsSize += Size;
|
||||
if (!Locked)
|
||||
{
|
||||
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline VOID LdrpTlsCallback(PLDR_DATA_TABLE_ENTRY Module, ULONG dwReason)
|
||||
{
|
||||
PIMAGE_TLS_CALLBACK *TlsCallback;
|
||||
if (Module->TlsIndex != 0xFFFF && Module->LoadCount == LDRP_PROCESS_CREATION_TIME)
|
||||
{
|
||||
TlsCallback = LdrpTlsArray[Module->TlsIndex].TlsAddressOfCallBacks;
|
||||
if (TlsCallback)
|
||||
{
|
||||
while (*TlsCallback)
|
||||
{
|
||||
TRACE_LDR("%wZ - Calling tls callback at %x\n",
|
||||
&Module->BaseDllName, *TlsCallback);
|
||||
(*TlsCallback)(Module->DllBase, dwReason, NULL);
|
||||
TlsCallback++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOLEAN LdrpCallDllEntry(PLDR_DATA_TABLE_ENTRY Module, DWORD dwReason, PVOID lpReserved)
|
||||
{
|
||||
if (!(Module->Flags & LDRP_IMAGE_DLL) ||
|
||||
Module->EntryPoint == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
LdrpTlsCallback(Module, dwReason);
|
||||
return ((PDLLMAIN_FUNC)Module->EntryPoint)(Module->DllBase, dwReason, lpReserved);
|
||||
}
|
||||
|
||||
static PWSTR
|
||||
LdrpQueryAppPaths(IN PCWSTR ImageName)
|
||||
{
|
||||
@@ -269,127 +211,6 @@ LdrpQueryAppPaths(IN PCWSTR ImageName)
|
||||
return Path;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
LdrpInitializeTlsForThread(VOID)
|
||||
{
|
||||
PVOID* TlsPointers;
|
||||
PTLS_DATA TlsInfo;
|
||||
PVOID TlsData;
|
||||
ULONG i;
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
|
||||
DPRINT("LdrpInitializeTlsForThread() called for %wZ\n", &ExeModule->BaseDllName);
|
||||
|
||||
Teb->StaticUnicodeString.Length = 0;
|
||||
Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer);
|
||||
Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer;
|
||||
|
||||
if (LdrpTlsCount > 0)
|
||||
{
|
||||
TlsPointers = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
LdrpTlsCount * sizeof(PVOID) + LdrpTlsSize);
|
||||
if (TlsPointers == NULL)
|
||||
{
|
||||
DPRINT1("failed to allocate thread tls data\n");
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
TlsData = (PVOID)((ULONG_PTR)TlsPointers + LdrpTlsCount * sizeof(PVOID));
|
||||
Teb->ThreadLocalStoragePointer = TlsPointers;
|
||||
|
||||
TlsInfo = LdrpTlsArray;
|
||||
for (i = 0; i < LdrpTlsCount; i++, TlsInfo++)
|
||||
{
|
||||
TRACE_LDR("Initialize tls data for %wZ\n", &TlsInfo->Module->BaseDllName);
|
||||
TlsPointers[i] = TlsData;
|
||||
if (TlsInfo->TlsDataSize)
|
||||
{
|
||||
memcpy(TlsData, TlsInfo->StartAddressOfRawData, TlsInfo->TlsDataSize);
|
||||
TlsData = (PVOID)((ULONG_PTR)TlsData + TlsInfo->TlsDataSize);
|
||||
}
|
||||
if (TlsInfo->TlsZeroSize)
|
||||
{
|
||||
memset(TlsData, 0, TlsInfo->TlsZeroSize);
|
||||
TlsData = (PVOID)((ULONG_PTR)TlsData + TlsInfo->TlsZeroSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("LdrpInitializeTlsForThread() done\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
LdrpInitializeTlsForProccess(VOID)
|
||||
{
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_DATA_TABLE_ENTRY Module;
|
||||
PIMAGE_TLS_DIRECTORY TlsDirectory;
|
||||
PTLS_DATA TlsData;
|
||||
ULONG Size;
|
||||
|
||||
DPRINT("LdrpInitializeTlsForProccess() called for %wZ\n", &ExeModule->BaseDllName);
|
||||
|
||||
if (LdrpTlsCount > 0)
|
||||
{
|
||||
LdrpTlsArray = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
LdrpTlsCount * sizeof(TLS_DATA));
|
||||
if (LdrpTlsArray == NULL)
|
||||
{
|
||||
DPRINT1("Failed to allocate global tls data\n");
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||
if (Module->LoadCount == LDRP_PROCESS_CREATION_TIME &&
|
||||
Module->TlsIndex != 0xFFFF)
|
||||
{
|
||||
TlsDirectory = (PIMAGE_TLS_DIRECTORY)
|
||||
RtlImageDirectoryEntryToData(Module->DllBase,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_TLS,
|
||||
&Size);
|
||||
ASSERT(Module->TlsIndex < LdrpTlsCount);
|
||||
TlsData = &LdrpTlsArray[Module->TlsIndex];
|
||||
TlsData->StartAddressOfRawData = (PVOID)TlsDirectory->StartAddressOfRawData;
|
||||
TlsData->TlsDataSize = TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData;
|
||||
TlsData->TlsZeroSize = TlsDirectory->SizeOfZeroFill;
|
||||
if (TlsDirectory->AddressOfCallBacks)
|
||||
TlsData->TlsAddressOfCallBacks = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks;
|
||||
else
|
||||
TlsData->TlsAddressOfCallBacks = NULL;
|
||||
TlsData->Module = Module;
|
||||
#if 0
|
||||
DbgPrint("TLS directory for %wZ\n", &Module->BaseDllName);
|
||||
DbgPrint("StartAddressOfRawData: %x\n", TlsDirectory->StartAddressOfRawData);
|
||||
DbgPrint("EndAddressOfRawData: %x\n", TlsDirectory->EndAddressOfRawData);
|
||||
DbgPrint("SizeOfRawData: %d\n", TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData);
|
||||
DbgPrint("AddressOfIndex: %x\n", TlsDirectory->AddressOfIndex);
|
||||
DbgPrint("AddressOfCallBacks: %x\n", TlsDirectory->AddressOfCallBacks);
|
||||
DbgPrint("SizeOfZeroFill: %d\n", TlsDirectory->SizeOfZeroFill);
|
||||
DbgPrint("Characteristics: %x\n", TlsDirectory->Characteristics);
|
||||
#endif
|
||||
/*
|
||||
* FIXME:
|
||||
* Is this region allways writable ?
|
||||
*/
|
||||
*(PULONG)TlsDirectory->AddressOfIndex = Module->TlsIndex;
|
||||
}
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("LdrpInitializeTlsForProccess() done\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
LdrpInitLoader(VOID)
|
||||
{
|
||||
@@ -400,7 +221,7 @@ LdrpInitLoader(VOID)
|
||||
ULONG Length;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("LdrpInitLoader() called for %wZ\n", &ExeModule->BaseDllName);
|
||||
DPRINT("LdrpInitLoader() called for %wZ\n", &LdrpImageEntry->BaseDllName);
|
||||
|
||||
/* Get handle to the 'KnownDlls' directory */
|
||||
RtlInitUnicodeString(&Name,
|
||||
@@ -410,13 +231,13 @@ LdrpInitLoader(VOID)
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtOpenDirectoryObject(&LdrpKnownDllsDirHandle,
|
||||
Status = NtOpenDirectoryObject(&LdrpKnownDllObjectDirectory,
|
||||
DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtOpenDirectoryObject() failed (Status %lx)\n", Status);
|
||||
LdrpKnownDllsDirHandle = NULL;
|
||||
LdrpKnownDllObjectDirectory = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -428,8 +249,8 @@ LdrpInitLoader(VOID)
|
||||
MAX_PATH * sizeof(WCHAR));
|
||||
if (LinkTarget.Buffer == NULL)
|
||||
{
|
||||
NtClose(LdrpKnownDllsDirHandle);
|
||||
LdrpKnownDllsDirHandle = NULL;
|
||||
NtClose(LdrpKnownDllObjectDirectory);
|
||||
LdrpKnownDllObjectDirectory = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -438,7 +259,7 @@ LdrpInitLoader(VOID)
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&Name,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
LdrpKnownDllsDirHandle,
|
||||
LdrpKnownDllObjectDirectory,
|
||||
NULL);
|
||||
Status = NtOpenSymbolicLinkObject(&LinkHandle,
|
||||
SYMBOLIC_LINK_ALL_ACCESS,
|
||||
@@ -446,8 +267,8 @@ LdrpInitLoader(VOID)
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeUnicodeString(&LinkTarget);
|
||||
NtClose(LdrpKnownDllsDirHandle);
|
||||
LdrpKnownDllsDirHandle = NULL;
|
||||
NtClose(LdrpKnownDllObjectDirectory);
|
||||
LdrpKnownDllObjectDirectory = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -458,8 +279,8 @@ LdrpInitLoader(VOID)
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeUnicodeString(&LinkTarget);
|
||||
NtClose(LdrpKnownDllsDirHandle);
|
||||
LdrpKnownDllsDirHandle = NULL;
|
||||
NtClose(LdrpKnownDllObjectDirectory);
|
||||
LdrpKnownDllObjectDirectory = NULL;
|
||||
}
|
||||
|
||||
RtlCreateUnicodeString(&LdrpKnownDllPath,
|
||||
@@ -610,7 +431,7 @@ LdrpMapKnownDll(IN PUNICODE_STRING DllName,
|
||||
|
||||
DPRINT("LdrpMapKnownDll() called\n");
|
||||
|
||||
if (LdrpKnownDllsDirHandle == NULL)
|
||||
if (LdrpKnownDllObjectDirectory == NULL)
|
||||
{
|
||||
DPRINT("Invalid 'KnownDlls' directory\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
@@ -621,7 +442,7 @@ LdrpMapKnownDll(IN PUNICODE_STRING DllName,
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
DllName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
LdrpKnownDllsDirHandle,
|
||||
LdrpKnownDllObjectDirectory,
|
||||
NULL);
|
||||
Status = NtOpenSection(SectionHandle,
|
||||
SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE,
|
||||
@@ -923,7 +744,7 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
||||
if (!(Module->Flags & LDRP_PROCESS_ATTACH_CALLED))
|
||||
{
|
||||
RtlEnterCriticalSection(Peb->LoaderLock);
|
||||
Status = LdrpAttachProcess();
|
||||
Status = LdrpRunInitializeRoutines(NULL);
|
||||
RtlLeaveCriticalSection(Peb->LoaderLock);
|
||||
}
|
||||
if (Module->EntryPointActivationContext) RtlDeactivateActivationContext(0, cookie);
|
||||
@@ -1043,7 +864,7 @@ LdrFindEntryForName(PUNICODE_STRING Name,
|
||||
// NULL is the current process
|
||||
if (Name == NULL)
|
||||
{
|
||||
*Module = ExeModule;
|
||||
*Module = LdrpImageEntry;
|
||||
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
@@ -1368,7 +1189,7 @@ LdrGetExportByName(PVOID BaseAddress,
|
||||
* NOTE
|
||||
*
|
||||
*/
|
||||
static NTSTATUS
|
||||
NTSTATUS
|
||||
LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
|
||||
PVOID ImageBase)
|
||||
{
|
||||
@@ -2093,11 +1914,6 @@ Success:
|
||||
}
|
||||
}
|
||||
|
||||
if (TlsDirectory && TlsSize > 0)
|
||||
{
|
||||
LdrpAcquireTlsSlot(Module, TlsSize, FALSE);
|
||||
}
|
||||
|
||||
if (Module->EntryPointActivationContext) RtlDeactivateActivationContext( 0, cookie );
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
@@ -2216,14 +2032,14 @@ PEPFUNC LdrPEStartup (PVOID ImageBase,
|
||||
}
|
||||
DPRINT("Fixup done\n");
|
||||
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
Status = LdrpInitializeTlsForProccess();
|
||||
Status = LdrpInitializeTls();
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = LdrpAttachProcess();
|
||||
Status = LdrpRunInitializeRoutines(NULL);
|
||||
}
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
LdrpTlsCallback(*Module, DLL_PROCESS_ATTACH);
|
||||
LdrpTlsCallback((*Module)->DllBase, DLL_PROCESS_ATTACH);
|
||||
}
|
||||
|
||||
|
||||
@@ -2599,7 +2415,7 @@ LdrGetDllHandle(IN PWSTR DllPath OPTIONAL,
|
||||
/* NULL is the current executable */
|
||||
if (DllName == NULL)
|
||||
{
|
||||
*DllHandle = ExeModule->DllBase;
|
||||
*DllHandle = LdrpImageEntry->DllBase;
|
||||
DPRINT("BaseAddress 0x%lx\n", *DllHandle);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -2743,7 +2559,7 @@ LdrpDetachProcess(BOOLEAN UnloadAll)
|
||||
static ULONG CallingCount = 0;
|
||||
|
||||
DPRINT("LdrpDetachProcess() called for %wZ\n",
|
||||
&ExeModule->BaseDllName);
|
||||
&LdrpImageEntry->BaseDllName);
|
||||
|
||||
if (UnloadAll)
|
||||
LdrpDllShutdownInProgress = TRUE;
|
||||
@@ -2768,9 +2584,21 @@ LdrpDetachProcess(BOOLEAN UnloadAll)
|
||||
{
|
||||
TRACE_LDR("Unload %wZ - Calling entry point at %x\n",
|
||||
&Module->BaseDllName, Module->EntryPoint);
|
||||
LdrpCallDllEntry(Module,
|
||||
DLL_PROCESS_DETACH,
|
||||
(PVOID)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0));
|
||||
|
||||
/* Check if it has TLS */
|
||||
if (Module->TlsIndex)
|
||||
{
|
||||
/* Call TLS */
|
||||
LdrpTlsCallback(Module->DllBase, DLL_PROCESS_ATTACH);
|
||||
}
|
||||
|
||||
if ((Module->Flags & LDRP_IMAGE_DLL) && Module->EntryPoint)
|
||||
{
|
||||
LdrpCallDllEntry(Module->EntryPoint,
|
||||
Module->DllBase,
|
||||
DLL_PROCESS_DETACH,
|
||||
(PVOID)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2814,71 +2642,6 @@ LdrpDetachProcess(BOOLEAN UnloadAll)
|
||||
DPRINT("LdrpDetachProcess() done\n");
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NAME LOCAL
|
||||
* LdrpAttachProcess
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Initialize all dll's which are prepered for loading
|
||||
*
|
||||
* ARGUMENTS
|
||||
* none
|
||||
*
|
||||
* RETURN VALUE
|
||||
* status
|
||||
*
|
||||
* REVISIONS
|
||||
*
|
||||
* NOTE
|
||||
* The loader lock must be held on entry.
|
||||
*
|
||||
*/
|
||||
static NTSTATUS
|
||||
LdrpAttachProcess(VOID)
|
||||
{
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_DATA_TABLE_ENTRY Module;
|
||||
BOOLEAN Result;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("LdrpAttachProcess() called for %wZ\n",
|
||||
&ExeModule->BaseDllName);
|
||||
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
|
||||
if (!(Module->Flags & (LDRP_LOAD_IN_PROGRESS|LDRP_UNLOAD_IN_PROGRESS|LDRP_ENTRY_PROCESSED)))
|
||||
{
|
||||
Module->Flags |= LDRP_LOAD_IN_PROGRESS;
|
||||
TRACE_LDR("%wZ loaded - Calling init routine at %x for process attaching\n",
|
||||
&Module->BaseDllName, Module->EntryPoint);
|
||||
Result = LdrpCallDllEntry(Module, DLL_PROCESS_ATTACH, (PVOID)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0));
|
||||
if (!Result)
|
||||
{
|
||||
Status = STATUS_DLL_INIT_FAILED;
|
||||
break;
|
||||
}
|
||||
if (Module->Flags & LDRP_IMAGE_DLL && Module->EntryPoint != 0)
|
||||
{
|
||||
Module->Flags |= LDRP_PROCESS_ATTACH_CALLED|LDRP_ENTRY_PROCESSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
Module->Flags |= LDRP_ENTRY_PROCESSED;
|
||||
}
|
||||
Module->Flags &= ~LDRP_LOAD_IN_PROGRESS;
|
||||
}
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
DPRINT("LdrpAttachProcess() done\n");
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -2901,9 +2664,9 @@ LdrShutdownProcess (VOID)
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
NTSTATUS
|
||||
LdrpAttachThread (VOID)
|
||||
NTAPI
|
||||
LdrpInitializeThread(IN PCONTEXT Context)
|
||||
{
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
@@ -2911,11 +2674,11 @@ LdrpAttachThread (VOID)
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("LdrpAttachThread() called for %wZ\n",
|
||||
&ExeModule->BaseDllName);
|
||||
&LdrpImageEntry->BaseDllName);
|
||||
|
||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
|
||||
Status = LdrpInitializeTlsForThread();
|
||||
Status = LdrpAllocateTls();
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
@@ -2931,14 +2694,23 @@ LdrpAttachThread (VOID)
|
||||
{
|
||||
TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n",
|
||||
&Module->BaseDllName, Module->EntryPoint);
|
||||
LdrpCallDllEntry(Module, DLL_THREAD_ATTACH, NULL);
|
||||
|
||||
/* Check if it has TLS */
|
||||
if (Module->TlsIndex)
|
||||
{
|
||||
/* Call TLS */
|
||||
LdrpTlsCallback(Module->DllBase, DLL_THREAD_ATTACH);
|
||||
}
|
||||
|
||||
if ((Module->Flags & LDRP_IMAGE_DLL) && Module->EntryPoint)
|
||||
LdrpCallDllEntry(Module->EntryPoint, Module->DllBase, DLL_THREAD_ATTACH, NULL);
|
||||
}
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
Entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
|
||||
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||
LdrpTlsCallback(Module, DLL_THREAD_ATTACH);
|
||||
LdrpTlsCallback(Module->DllBase, DLL_THREAD_ATTACH);
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
@@ -2960,7 +2732,7 @@ LdrShutdownThread (VOID)
|
||||
PLDR_DATA_TABLE_ENTRY Module;
|
||||
|
||||
DPRINT("LdrShutdownThread() called for %wZ\n",
|
||||
&ExeModule->BaseDllName);
|
||||
&LdrpImageEntry->BaseDllName);
|
||||
|
||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
|
||||
@@ -2976,195 +2748,28 @@ LdrShutdownThread (VOID)
|
||||
{
|
||||
TRACE_LDR("%wZ - Calling entry point at %x for thread detaching\n",
|
||||
&Module->BaseDllName, Module->EntryPoint);
|
||||
LdrpCallDllEntry(Module, DLL_THREAD_DETACH, NULL);
|
||||
/* Check if it has TLS */
|
||||
if (Module->TlsIndex)
|
||||
{
|
||||
/* Call TLS */
|
||||
LdrpTlsCallback(Module->DllBase, DLL_THREAD_DETACH);
|
||||
}
|
||||
|
||||
if ((Module->Flags & LDRP_IMAGE_DLL) && Module->EntryPoint)
|
||||
LdrpCallDllEntry(Module->EntryPoint, Module->DllBase, DLL_THREAD_DETACH, NULL);
|
||||
}
|
||||
Entry = Entry->Blink;
|
||||
}
|
||||
|
||||
/* Free TLS */
|
||||
LdrpFreeTls();
|
||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
|
||||
if (LdrpTlsArray)
|
||||
{
|
||||
RtlFreeHeap (RtlGetProcessHeap(), 0, NtCurrentTeb()->ThreadLocalStoragePointer);
|
||||
}
|
||||
|
||||
DPRINT("LdrShutdownThread() done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* NAME EXPORTED
|
||||
* LdrQueryProcessModuleInformation
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ARGUMENTS
|
||||
*
|
||||
* RETURN VALUE
|
||||
*
|
||||
* REVISIONS
|
||||
*
|
||||
* NOTE
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS NTAPI
|
||||
LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation OPTIONAL,
|
||||
IN ULONG Size OPTIONAL,
|
||||
OUT PULONG ReturnedSize)
|
||||
{
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_DATA_TABLE_ENTRY Module;
|
||||
PRTL_PROCESS_MODULE_INFORMATION ModulePtr = NULL;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG UsedSize = sizeof(ULONG);
|
||||
ANSI_STRING AnsiString;
|
||||
PCHAR p;
|
||||
|
||||
DPRINT("LdrQueryProcessModuleInformation() called\n");
|
||||
// FIXME: This code is ultra-duplicated. see lib\rtl\dbgbuffer.c
|
||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
|
||||
if (ModuleInformation == NULL || Size == 0)
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
ModuleInformation->NumberOfModules = 0;
|
||||
ModulePtr = &ModuleInformation->Modules[0];
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||
|
||||
DPRINT(" Module %wZ\n",
|
||||
&Module->FullDllName);
|
||||
|
||||
if (UsedSize > Size)
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
else if (ModuleInformation != NULL)
|
||||
{
|
||||
ModulePtr->Section = 0;
|
||||
ModulePtr->MappedBase = NULL; // FIXME: ??
|
||||
ModulePtr->ImageBase = Module->DllBase;
|
||||
ModulePtr->ImageSize = Module->SizeOfImage;
|
||||
ModulePtr->Flags = Module->Flags;
|
||||
ModulePtr->LoadOrderIndex = 0; // FIXME: ??
|
||||
ModulePtr->InitOrderIndex = 0; // FIXME: ??
|
||||
ModulePtr->LoadCount = Module->LoadCount;
|
||||
|
||||
AnsiString.Length = 0;
|
||||
AnsiString.MaximumLength = 256;
|
||||
AnsiString.Buffer = ModulePtr->FullPathName;
|
||||
RtlUnicodeStringToAnsiString(&AnsiString,
|
||||
&Module->FullDllName,
|
||||
FALSE);
|
||||
|
||||
p = strrchr(ModulePtr->FullPathName, '\\');
|
||||
if (p != NULL)
|
||||
ModulePtr->OffsetToFileName = p - ModulePtr->FullPathName + 1;
|
||||
else
|
||||
ModulePtr->OffsetToFileName = 0;
|
||||
|
||||
ModulePtr++;
|
||||
ModuleInformation->NumberOfModules++;
|
||||
}
|
||||
UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION);
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
|
||||
if (ReturnedSize != 0)
|
||||
*ReturnedSize = UsedSize;
|
||||
|
||||
DPRINT("LdrQueryProcessModuleInformation() done\n");
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
LdrpCheckImageChecksum (IN PVOID BaseAddress,
|
||||
IN ULONG ImageSize)
|
||||
{
|
||||
PIMAGE_NT_HEADERS Header;
|
||||
PUSHORT Ptr;
|
||||
ULONG Sum;
|
||||
ULONG CalcSum;
|
||||
ULONG HeaderSum;
|
||||
ULONG i;
|
||||
|
||||
Header = RtlImageNtHeader (BaseAddress);
|
||||
if (Header == NULL)
|
||||
return FALSE;
|
||||
|
||||
HeaderSum = Header->OptionalHeader.CheckSum;
|
||||
if (HeaderSum == 0)
|
||||
return TRUE;
|
||||
|
||||
Sum = 0;
|
||||
Ptr = (PUSHORT) BaseAddress;
|
||||
for (i = 0; i < ImageSize / sizeof (USHORT); i++)
|
||||
{
|
||||
Sum += (ULONG)*Ptr;
|
||||
if (HIWORD(Sum) != 0)
|
||||
{
|
||||
Sum = LOWORD(Sum) + HIWORD(Sum);
|
||||
}
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
if (ImageSize & 1)
|
||||
{
|
||||
Sum += (ULONG)*((PUCHAR)Ptr);
|
||||
if (HIWORD(Sum) != 0)
|
||||
{
|
||||
Sum = LOWORD(Sum) + HIWORD(Sum);
|
||||
}
|
||||
}
|
||||
|
||||
CalcSum = (USHORT)(LOWORD(Sum) + HIWORD(Sum));
|
||||
|
||||
/* Subtract image checksum from calculated checksum. */
|
||||
/* fix low word of checksum */
|
||||
if (LOWORD(CalcSum) >= LOWORD(HeaderSum))
|
||||
{
|
||||
CalcSum -= LOWORD(HeaderSum);
|
||||
}
|
||||
else
|
||||
{
|
||||
CalcSum = ((LOWORD(CalcSum) - LOWORD(HeaderSum)) & 0xFFFF) - 1;
|
||||
}
|
||||
|
||||
/* fix high word of checksum */
|
||||
if (LOWORD(CalcSum) >= HIWORD(HeaderSum))
|
||||
{
|
||||
CalcSum -= HIWORD(HeaderSum);
|
||||
}
|
||||
else
|
||||
{
|
||||
CalcSum = ((LOWORD(CalcSum) - HIWORD(HeaderSum)) & 0xFFFF) - 1;
|
||||
}
|
||||
|
||||
/* add file length */
|
||||
CalcSum += ImageSize;
|
||||
|
||||
return (BOOLEAN)(CalcSum == HeaderSum);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute size of an image as it is actually present in virt memory
|
||||
* (i.e. excluding NEVER_LOAD sections)
|
||||
@@ -3194,100 +2799,6 @@ LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders)
|
||||
return ResidentSize;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* NAME EXPORTED
|
||||
* LdrVerifyImageMatchesChecksum
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ARGUMENTS
|
||||
*
|
||||
* RETURN VALUE
|
||||
*
|
||||
* REVISIONS
|
||||
*
|
||||
* NOTE
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS NTAPI
|
||||
LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
|
||||
IN PLDR_CALLBACK Callback,
|
||||
IN PVOID CallbackContext,
|
||||
OUT PUSHORT ImageCharacterstics)
|
||||
{
|
||||
FILE_STANDARD_INFORMATION FileInfo;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE SectionHandle;
|
||||
SIZE_T ViewSize;
|
||||
PVOID BaseAddress;
|
||||
BOOLEAN Result;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("LdrVerifyImageMatchesChecksum() called\n");
|
||||
|
||||
Status = NtCreateSection (&SectionHandle,
|
||||
SECTION_MAP_READ,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_READONLY,
|
||||
SEC_COMMIT,
|
||||
FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("NtCreateSection() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
ViewSize = 0;
|
||||
BaseAddress = NULL;
|
||||
Status = NtMapViewOfSection (SectionHandle,
|
||||
NtCurrentProcess (),
|
||||
&BaseAddress,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&ViewSize,
|
||||
ViewShare,
|
||||
0,
|
||||
PAGE_READONLY);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
|
||||
NtClose (SectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = NtQueryInformationFile(FileHandle,
|
||||
&IoStatusBlock,
|
||||
&FileInfo,
|
||||
sizeof (FILE_STANDARD_INFORMATION),
|
||||
FileStandardInformation);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
|
||||
NtUnmapViewOfSection (NtCurrentProcess(),
|
||||
BaseAddress);
|
||||
NtClose (SectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Result = LdrpCheckImageChecksum(BaseAddress,
|
||||
FileInfo.EndOfFile.u.LowPart);
|
||||
if (Result == FALSE)
|
||||
{
|
||||
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
|
||||
}
|
||||
|
||||
NtUnmapViewOfSection (NtCurrentProcess(),
|
||||
BaseAddress);
|
||||
|
||||
NtClose(SectionHandle);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
PIMAGE_BASE_RELOCATION
|
||||
NTAPI
|
||||
LdrProcessRelocationBlock(
|
||||
@@ -3299,79 +2810,6 @@ LdrProcessRelocationBlock(
|
||||
return LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, Delta);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrLockLoaderLock(IN ULONG Flags,
|
||||
OUT PULONG Disposition OPTIONAL,
|
||||
OUT PULONG Cookie OPTIONAL)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
BOOLEAN Ret;
|
||||
BOOLEAN CookieSet = FALSE;
|
||||
|
||||
if ((Flags != 0x01) && (Flags != 0x02))
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
|
||||
if (!Cookie) return STATUS_INVALID_PARAMETER_3;
|
||||
|
||||
/* Set some defaults for failure while verifying params */
|
||||
_SEH2_TRY
|
||||
{
|
||||
*Cookie = 0;
|
||||
CookieSet = TRUE;
|
||||
if (Disposition) *Disposition = 0;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
if (CookieSet)
|
||||
Status = STATUS_INVALID_PARAMETER_3;
|
||||
else
|
||||
Status = STATUS_INVALID_PARAMETER_2;
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
if (Flags == 0x01)
|
||||
{
|
||||
DPRINT1("Warning: Reporting errors with exception not supported yet!\n");
|
||||
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Disposition) return STATUS_INVALID_PARAMETER_2;
|
||||
|
||||
Ret = RtlTryEnterCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
|
||||
if (Ret)
|
||||
*Disposition = 0x01;
|
||||
else
|
||||
*Disposition = 0x02;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* FIXME: Cookie is based on part of the thread id */
|
||||
*Cookie = (ULONG)NtCurrentTeb()->RealClientId.UniqueThread;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrUnlockLoaderLock(IN ULONG Flags,
|
||||
IN ULONG Cookie OPTIONAL)
|
||||
{
|
||||
if (Flags != 0x01)
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
|
||||
if (Cookie != (ULONG)NtCurrentTeb()->RealClientId.UniqueThread)
|
||||
return STATUS_INVALID_PARAMETER_2;
|
||||
|
||||
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
LdrUnloadAlternateResourceModule(IN PVOID BaseAddress)
|
||||
|
||||
@@ -964,6 +964,9 @@ HardwareDlgProc(IN HWND hwndDlg,
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
/* zero hpd pointer in window data, because it can be used later (WM_DESTROY has not to be last message) */
|
||||
SetWindowLongPtr(hwndDlg, DWL_USER, (DWORD_PTR)NULL);
|
||||
|
||||
/* free devices list */
|
||||
FreeDevicesList(hpd);
|
||||
|
||||
|
||||
+16
-30
@@ -124,38 +124,24 @@ BOOL GdiIsHandleValid(HGDIOBJ hGdiObj)
|
||||
BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData)
|
||||
{
|
||||
PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
|
||||
if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == ObjectType &&
|
||||
( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) ==
|
||||
GDI_HANDLE_GET_TYPE(hGdiObj))
|
||||
|
||||
/* Check if twe have the correct type */
|
||||
if (GDI_HANDLE_GET_TYPE(hGdiObj) != ObjectType ||
|
||||
((Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK) != ObjectType ||
|
||||
(Entry->Type & GDI_ENTRY_BASETYPE_MASK) != (ObjectType & GDI_ENTRY_BASETYPE_MASK))
|
||||
{
|
||||
HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
|
||||
if(pid == NULL || pid == CurrentProcessId)
|
||||
{
|
||||
//
|
||||
// Need to test if we have Read & Write access to the VM address space.
|
||||
//
|
||||
BOOL Result = TRUE;
|
||||
if(Entry->UserData)
|
||||
{
|
||||
volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
|
||||
_SEH2_TRY
|
||||
{
|
||||
*Current = *Current;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Result = FALSE;
|
||||
}
|
||||
_SEH2_END
|
||||
}
|
||||
else
|
||||
Result = FALSE; // Can not be zero.
|
||||
if (Result) *UserData = Entry->UserData;
|
||||
return Result;
|
||||
}
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
|
||||
/* Check if we are the owner */
|
||||
if ((HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1) != CurrentProcessId)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*UserData = Entry->UserData;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PLDC
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "precomp.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
@@ -194,11 +196,9 @@ GetTextExtentExPointW(
|
||||
)
|
||||
{
|
||||
|
||||
/* Windows doesn't check nMaxExtent validity in unicode version */
|
||||
if(nMaxExtent < -1)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
DPRINT("nMaxExtent is invalid: %d\n", nMaxExtent);
|
||||
|
||||
return NtGdiGetTextExtentExW (
|
||||
hdc, (LPWSTR)lpszStr, cchString, nMaxExtent, (PULONG)lpnFit, (PULONG)alpDx, lpSize, 0 );
|
||||
@@ -261,7 +261,8 @@ GetTextExtentPoint32A(
|
||||
UNICODE_STRING StringU;
|
||||
BOOL ret;
|
||||
|
||||
RtlInitAnsiString(&StringA, (LPSTR)lpString);
|
||||
StringA.Buffer = (LPSTR)lpString;
|
||||
StringA.Length = cchString;
|
||||
RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
|
||||
|
||||
ret = GetTextExtentPoint32W(hdc, StringU.Buffer, cchString, lpSize);
|
||||
|
||||
@@ -310,6 +310,12 @@ GetProcAddress( HMODULE hModule, LPCSTR lpProcName )
|
||||
FARPROC fnExp = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (!hModule)
|
||||
{
|
||||
SetLastError(ERROR_PROC_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (HIWORD(lpProcName) != 0)
|
||||
{
|
||||
RtlInitAnsiString (&ProcedureName,
|
||||
@@ -354,8 +360,7 @@ BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
|
||||
{
|
||||
/* this is a LOAD_LIBRARY_AS_DATAFILE module */
|
||||
char *ptr = (char *)hLibModule - 1;
|
||||
UnmapViewOfFile(ptr);
|
||||
return TRUE;
|
||||
return UnmapViewOfFile(ptr);
|
||||
}
|
||||
|
||||
Status = LdrUnloadDll(hLibModule);
|
||||
|
||||
@@ -13,6 +13,7 @@ list(APPEND SOURCE
|
||||
action.c
|
||||
alter.c
|
||||
appsearch.c
|
||||
assembly.c
|
||||
automation.c
|
||||
classes.c
|
||||
cond.tab.c
|
||||
|
||||
+701
-801
File diff suppressed because it is too large
Load Diff
@@ -71,7 +71,7 @@ void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls)
|
||||
x4 = atoiW(ptr + 1);
|
||||
/* FIXME: byte-order dependent? */
|
||||
*ms = x1 << 16 | x2;
|
||||
*ls = x3 << 16 | x4;
|
||||
if (ls) *ls = x3 << 16 | x4;
|
||||
}
|
||||
|
||||
/* Fills in sig with the values from the Signature table, where name is the
|
||||
@@ -796,8 +796,8 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
|
||||
lstrcmpW(findData.cFileName, szDot) &&
|
||||
lstrcmpW(findData.cFileName, szDotDot))
|
||||
strcmpW( findData.cFileName, szDot ) &&
|
||||
strcmpW( findData.cFileName, szDotDot ))
|
||||
{
|
||||
lstrcpyW(subpath, dir);
|
||||
PathAppendW(subpath, findData.cFileName);
|
||||
@@ -808,8 +808,8 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
|
||||
while (rc == ERROR_SUCCESS && !*appValue &&
|
||||
FindNextFileW(hFind, &findData) != 0)
|
||||
{
|
||||
if (!lstrcmpW(findData.cFileName, szDot) ||
|
||||
!lstrcmpW(findData.cFileName, szDotDot))
|
||||
if (!strcmpW( findData.cFileName, szDot ) ||
|
||||
!strcmpW( findData.cFileName, szDotDot ))
|
||||
continue;
|
||||
|
||||
lstrcpyW(subpath, dir);
|
||||
|
||||
@@ -0,0 +1,629 @@
|
||||
/*
|
||||
* Implementation of the Microsoft Installer (msi.dll)
|
||||
*
|
||||
* Copyright 2010 Hans Leidekker for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "msipriv.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||
|
||||
static HRESULT (WINAPI *pCreateAssemblyCacheNet11)( IAssemblyCache **, DWORD );
|
||||
static HRESULT (WINAPI *pCreateAssemblyCacheNet20)( IAssemblyCache **, DWORD );
|
||||
static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD );
|
||||
static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * );
|
||||
static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * );
|
||||
|
||||
static BOOL init_function_pointers( void )
|
||||
{
|
||||
static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
|
||||
static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0};
|
||||
static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0};
|
||||
HMODULE hfusion11 = NULL, hfusion20 = NULL, hmscoree, hsxs;
|
||||
|
||||
if (pCreateAssemblyCacheNet11 || pCreateAssemblyCacheNet20) return TRUE;
|
||||
|
||||
if (!(hmscoree = LoadLibraryA( "mscoree.dll" ))) return FALSE;
|
||||
if (!(pGetFileVersion = (void *)GetProcAddress( hmscoree, "GetFileVersion" ))) goto error;
|
||||
if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" ))) goto error;
|
||||
|
||||
if (!pLoadLibraryShim( szFusion, szVersion11, NULL, &hfusion11 ))
|
||||
pCreateAssemblyCacheNet11 = (void *)GetProcAddress( hfusion11, "CreateAssemblyCache" );
|
||||
|
||||
if (!pLoadLibraryShim( szFusion, szVersion20, NULL, &hfusion20 ))
|
||||
pCreateAssemblyCacheNet20 = (void *)GetProcAddress( hfusion20, "CreateAssemblyCache" );
|
||||
|
||||
if (!pCreateAssemblyCacheNet11 && !pCreateAssemblyCacheNet20) goto error;
|
||||
|
||||
if (!(hsxs = LoadLibraryA( "sxs.dll" ))) goto error;
|
||||
if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" ))) goto error;
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
pCreateAssemblyCacheNet11 = NULL;
|
||||
pCreateAssemblyCacheNet20 = NULL;
|
||||
FreeLibrary( hfusion11 );
|
||||
FreeLibrary( hfusion20 );
|
||||
FreeLibrary( hmscoree );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL init_assembly_caches( MSIPACKAGE *package )
|
||||
{
|
||||
if (!init_function_pointers()) return FALSE;
|
||||
if (package->cache_net[CLR_VERSION_V11] || package->cache_net[CLR_VERSION_V20]) return TRUE;
|
||||
if (pCreateAssemblyCacheSxs( &package->cache_sxs, 0 ) != S_OK) return FALSE;
|
||||
|
||||
if (pCreateAssemblyCacheNet11) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V11], 0 );
|
||||
if (pCreateAssemblyCacheNet20) pCreateAssemblyCacheNet20( &package->cache_net[CLR_VERSION_V20], 0 );
|
||||
|
||||
if (package->cache_net[CLR_VERSION_V11] || package->cache_net[CLR_VERSION_V20])
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (package->cache_net[CLR_VERSION_V11])
|
||||
{
|
||||
IAssemblyCache_Release( package->cache_net[CLR_VERSION_V11] );
|
||||
package->cache_net[CLR_VERSION_V11] = NULL;
|
||||
}
|
||||
if (package->cache_net[CLR_VERSION_V20])
|
||||
{
|
||||
IAssemblyCache_Release( package->cache_net[CLR_VERSION_V20] );
|
||||
package->cache_net[CLR_VERSION_V20] = NULL;
|
||||
}
|
||||
IAssemblyCache_Release( package->cache_sxs );
|
||||
package->cache_sxs = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp )
|
||||
{
|
||||
static const WCHAR query[] = {
|
||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','M','s','i','A','s','s','e','m','b','l','y','`',' ',
|
||||
'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`',
|
||||
' ','=',' ','\'','%','s','\'',0};
|
||||
MSIQUERY *view;
|
||||
MSIRECORD *rec;
|
||||
UINT r;
|
||||
|
||||
r = MSI_OpenQuery( package->db, &view, query, comp );
|
||||
if (r != ERROR_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
r = MSI_ViewExecute( view, NULL );
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
msiobj_release( &view->hdr );
|
||||
return NULL;
|
||||
}
|
||||
r = MSI_ViewFetch( view, &rec );
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
msiobj_release( &view->hdr );
|
||||
return NULL;
|
||||
}
|
||||
if (!MSI_RecordGetString( rec, 4 ))
|
||||
TRACE("component is a global assembly\n");
|
||||
|
||||
msiobj_release( &view->hdr );
|
||||
return rec;
|
||||
}
|
||||
|
||||
struct assembly_name
|
||||
{
|
||||
UINT count;
|
||||
UINT index;
|
||||
WCHAR **attrs;
|
||||
};
|
||||
|
||||
static UINT get_assembly_name_attribute( MSIRECORD *rec, LPVOID param )
|
||||
{
|
||||
static const WCHAR fmtW[] = {'%','s','=','"','%','s','"',0};
|
||||
static const WCHAR nameW[] = {'n','a','m','e',0};
|
||||
struct assembly_name *name = param;
|
||||
const WCHAR *attr = MSI_RecordGetString( rec, 2 );
|
||||
const WCHAR *value = MSI_RecordGetString( rec, 3 );
|
||||
int len = strlenW( fmtW ) + strlenW( attr ) + strlenW( value );
|
||||
|
||||
if (!(name->attrs[name->index] = msi_alloc( len * sizeof(WCHAR) )))
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
if (!strcmpiW( attr, nameW )) strcpyW( name->attrs[name->index++], value );
|
||||
else sprintfW( name->attrs[name->index++], fmtW, attr, value );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static WCHAR *get_assembly_display_name( MSIDATABASE *db, const WCHAR *comp, MSIASSEMBLY *assembly )
|
||||
{
|
||||
static const WCHAR commaW[] = {',',0};
|
||||
static const WCHAR queryW[] = {
|
||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','M','s','i','A','s','s','e','m','b','l','y','N','a','m','e','`',' ',
|
||||
'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`',
|
||||
' ','=',' ','\'','%','s','\'',0};
|
||||
struct assembly_name name;
|
||||
WCHAR *display_name = NULL;
|
||||
MSIQUERY *view;
|
||||
UINT i, r;
|
||||
int len;
|
||||
|
||||
r = MSI_OpenQuery( db, &view, queryW, comp );
|
||||
if (r != ERROR_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
name.count = 0;
|
||||
name.index = 0;
|
||||
name.attrs = NULL;
|
||||
MSI_IterateRecords( view, &name.count, NULL, NULL );
|
||||
if (!name.count) goto done;
|
||||
|
||||
name.attrs = msi_alloc( name.count * sizeof(WCHAR *) );
|
||||
if (!name.attrs) goto done;
|
||||
|
||||
MSI_IterateRecords( view, NULL, get_assembly_name_attribute, &name );
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < name.count; i++) len += strlenW( name.attrs[i] ) + 1;
|
||||
|
||||
display_name = msi_alloc( (len + 1) * sizeof(WCHAR) );
|
||||
if (display_name)
|
||||
{
|
||||
display_name[0] = 0;
|
||||
for (i = 0; i < name.count; i++)
|
||||
{
|
||||
strcatW( display_name, name.attrs[i] );
|
||||
if (i < name.count - 1) strcatW( display_name, commaW );
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
msiobj_release( &view->hdr );
|
||||
for (i = 0; i < name.count; i++) msi_free( name.attrs[i] );
|
||||
msi_free( name.attrs );
|
||||
return display_name;
|
||||
}
|
||||
|
||||
static BOOL is_assembly_installed( IAssemblyCache *cache, const WCHAR *display_name )
|
||||
{
|
||||
HRESULT hr;
|
||||
ASSEMBLY_INFO info;
|
||||
|
||||
memset( &info, 0, sizeof(info) );
|
||||
info.cbAssemblyInfo = sizeof(info);
|
||||
hr = IAssemblyCache_QueryAssemblyInfo( cache, QUERYASMINFO_FLAG_GETSIZE, display_name, &info );
|
||||
if (FAILED( hr ))
|
||||
{
|
||||
TRACE("QueryAssemblyInfo returned 0x%08x\n", hr);
|
||||
return FALSE;
|
||||
}
|
||||
return (info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED);
|
||||
}
|
||||
|
||||
static const WCHAR clr_version_v11[] = {'v','1','.','1','.','4','3','2','2',0};
|
||||
static const WCHAR clr_version_v20[] = {'v','2','.','0','.','5','0','7','2','7',0};
|
||||
static const WCHAR clr_version_unknown[] = {'u','n','k','n','o','w','n',0};
|
||||
|
||||
static const WCHAR *clr_version[] =
|
||||
{
|
||||
clr_version_v11,
|
||||
clr_version_v20
|
||||
};
|
||||
|
||||
static const WCHAR *get_clr_version_str( enum clr_version version )
|
||||
{
|
||||
if (version >= sizeof(clr_version)/sizeof(clr_version[0])) return clr_version_unknown;
|
||||
return clr_version[version];
|
||||
}
|
||||
|
||||
MSIASSEMBLY *load_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
|
||||
{
|
||||
MSIRECORD *rec;
|
||||
MSIASSEMBLY *a;
|
||||
|
||||
if (!(rec = get_assembly_record( package, comp->Component ))) return NULL;
|
||||
if (!init_assembly_caches( package ))
|
||||
{
|
||||
ERR("can't initialize assembly caches\n");
|
||||
msiobj_release( &rec->hdr );
|
||||
return NULL;
|
||||
}
|
||||
if (!(a = msi_alloc_zero( sizeof(MSIASSEMBLY) )))
|
||||
{
|
||||
msiobj_release( &rec->hdr );
|
||||
return NULL;
|
||||
}
|
||||
a->feature = strdupW( MSI_RecordGetString( rec, 2 ) );
|
||||
TRACE("feature %s\n", debugstr_w(a->feature));
|
||||
|
||||
a->manifest = strdupW( MSI_RecordGetString( rec, 3 ) );
|
||||
TRACE("manifest %s\n", debugstr_w(a->manifest));
|
||||
|
||||
a->application = strdupW( MSI_RecordGetString( rec, 4 ) );
|
||||
TRACE("application %s\n", debugstr_w(a->application));
|
||||
|
||||
a->attributes = MSI_RecordGetInteger( rec, 5 );
|
||||
TRACE("attributes %u\n", a->attributes);
|
||||
|
||||
if (!(a->display_name = get_assembly_display_name( package->db, comp->Component, a )))
|
||||
{
|
||||
WARN("can't get display name\n");
|
||||
msiobj_release( &rec->hdr );
|
||||
msi_free( a->feature );
|
||||
msi_free( a->manifest );
|
||||
msi_free( a->application );
|
||||
msi_free( a );
|
||||
return NULL;
|
||||
}
|
||||
TRACE("display name %s\n", debugstr_w(a->display_name));
|
||||
|
||||
if (a->application)
|
||||
{
|
||||
/* We can't check the manifest here because the target path may still change.
|
||||
So we assume that the assembly is not installed and lean on the InstallFiles
|
||||
action to determine which files need to be installed.
|
||||
*/
|
||||
a->installed = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a->attributes == msidbAssemblyAttributesWin32)
|
||||
a->installed = is_assembly_installed( package->cache_sxs, a->display_name );
|
||||
else
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < CLR_VERSION_MAX; i++)
|
||||
{
|
||||
a->clr_version[i] = is_assembly_installed( package->cache_net[i], a->display_name );
|
||||
if (a->clr_version[i])
|
||||
{
|
||||
TRACE("runtime version %s\n", debugstr_w(get_clr_version_str( i )));
|
||||
a->installed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("assembly is %s\n", a->installed ? "installed" : "not installed");
|
||||
msiobj_release( &rec->hdr );
|
||||
return a;
|
||||
}
|
||||
|
||||
static enum clr_version get_clr_version( const WCHAR *filename )
|
||||
{
|
||||
DWORD len;
|
||||
HRESULT hr;
|
||||
enum clr_version version = CLR_VERSION_V11;
|
||||
WCHAR *strW;
|
||||
|
||||
hr = pGetFileVersion( filename, NULL, 0, &len );
|
||||
if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) return CLR_VERSION_V11;
|
||||
if ((strW = msi_alloc( len * sizeof(WCHAR) )))
|
||||
{
|
||||
hr = pGetFileVersion( filename, strW, len, &len );
|
||||
if (hr == S_OK)
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < CLR_VERSION_MAX; i++)
|
||||
if (!strcmpW( strW, clr_version[i] )) version = i;
|
||||
}
|
||||
msi_free( strW );
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
UINT install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
|
||||
{
|
||||
HRESULT hr;
|
||||
const WCHAR *manifest;
|
||||
IAssemblyCache *cache;
|
||||
MSIASSEMBLY *assembly = comp->assembly;
|
||||
MSIFEATURE *feature = NULL;
|
||||
|
||||
if (comp->assembly->feature)
|
||||
feature = get_loaded_feature( package, comp->assembly->feature );
|
||||
|
||||
if (assembly->application)
|
||||
{
|
||||
if (feature) feature->Action = INSTALLSTATE_LOCAL;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
if (assembly->attributes == msidbAssemblyAttributesWin32)
|
||||
{
|
||||
if (!assembly->manifest)
|
||||
{
|
||||
WARN("no manifest\n");
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
manifest = get_loaded_file( package, assembly->manifest )->TargetPath;
|
||||
cache = package->cache_sxs;
|
||||
}
|
||||
else
|
||||
{
|
||||
manifest = get_loaded_file( package, comp->KeyPath )->TargetPath;
|
||||
cache = package->cache_net[get_clr_version( manifest )];
|
||||
}
|
||||
TRACE("installing assembly %s\n", debugstr_w(manifest));
|
||||
|
||||
hr = IAssemblyCache_InstallAssembly( cache, 0, manifest, NULL );
|
||||
if (hr != S_OK)
|
||||
{
|
||||
ERR("Failed to install assembly %s (0x%08x)\n", debugstr_w(manifest), hr);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
if (feature) feature->Action = INSTALLSTATE_LOCAL;
|
||||
assembly->installed = TRUE;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static WCHAR *build_local_assembly_path( const WCHAR *filename )
|
||||
{
|
||||
UINT i;
|
||||
WCHAR *ret;
|
||||
|
||||
if (!(ret = msi_alloc( (strlenW( filename ) + 1) * sizeof(WCHAR) )))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; filename[i]; i++)
|
||||
{
|
||||
if (filename[i] == '\\' || filename[i] == '/') ret[i] = '|';
|
||||
else ret[i] = filename[i];
|
||||
}
|
||||
ret[i] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static LONG open_assemblies_key( UINT context, BOOL win32, HKEY *hkey )
|
||||
{
|
||||
static const WCHAR path_win32[] =
|
||||
{'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||
'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',0};
|
||||
static const WCHAR path_dotnet[] =
|
||||
{'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||
'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\',0};
|
||||
static const WCHAR classes_path_win32[] =
|
||||
{'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',0};
|
||||
static const WCHAR classes_path_dotnet[] =
|
||||
{'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\',0};
|
||||
HKEY root;
|
||||
const WCHAR *path;
|
||||
|
||||
if (context == MSIINSTALLCONTEXT_MACHINE)
|
||||
{
|
||||
root = HKEY_CLASSES_ROOT;
|
||||
if (win32) path = classes_path_win32;
|
||||
else path = classes_path_dotnet;
|
||||
}
|
||||
else
|
||||
{
|
||||
root = HKEY_CURRENT_USER;
|
||||
if (win32) path = path_win32;
|
||||
else path = path_dotnet;
|
||||
}
|
||||
return RegCreateKeyW( root, path, hkey );
|
||||
}
|
||||
|
||||
static LONG open_local_assembly_key( UINT context, BOOL win32, const WCHAR *filename, HKEY *hkey )
|
||||
{
|
||||
LONG res;
|
||||
HKEY root;
|
||||
WCHAR *path;
|
||||
|
||||
if (!(path = build_local_assembly_path( filename )))
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
if ((res = open_assemblies_key( context, win32, &root )))
|
||||
{
|
||||
msi_free( path );
|
||||
return res;
|
||||
}
|
||||
res = RegCreateKeyW( root, path, hkey );
|
||||
RegCloseKey( root );
|
||||
msi_free( path );
|
||||
return res;
|
||||
}
|
||||
|
||||
static LONG delete_local_assembly_key( UINT context, BOOL win32, const WCHAR *filename )
|
||||
{
|
||||
LONG res;
|
||||
HKEY root;
|
||||
WCHAR *path;
|
||||
|
||||
if (!(path = build_local_assembly_path( filename )))
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
if ((res = open_assemblies_key( context, win32, &root )))
|
||||
{
|
||||
msi_free( path );
|
||||
return res;
|
||||
}
|
||||
res = RegDeleteKeyW( root, path );
|
||||
RegCloseKey( root );
|
||||
msi_free( path );
|
||||
return res;
|
||||
}
|
||||
|
||||
static LONG open_global_assembly_key( UINT context, BOOL win32, HKEY *hkey )
|
||||
{
|
||||
static const WCHAR path_win32[] =
|
||||
{'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||
'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',
|
||||
'G','l','o','b','a','l',0};
|
||||
static const WCHAR path_dotnet[] =
|
||||
{'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||
'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\',
|
||||
'G','l','o','b','a','l',0};
|
||||
static const WCHAR classes_path_win32[] =
|
||||
{'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',
|
||||
'G','l','o','b','a','l',0};
|
||||
static const WCHAR classes_path_dotnet[] =
|
||||
{'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\','G','l','o','b','a','l',0};
|
||||
HKEY root;
|
||||
const WCHAR *path;
|
||||
|
||||
if (context == MSIINSTALLCONTEXT_MACHINE)
|
||||
{
|
||||
root = HKEY_CLASSES_ROOT;
|
||||
if (win32) path = classes_path_win32;
|
||||
else path = classes_path_dotnet;
|
||||
}
|
||||
else
|
||||
{
|
||||
root = HKEY_CURRENT_USER;
|
||||
if (win32) path = path_win32;
|
||||
else path = path_dotnet;
|
||||
}
|
||||
return RegCreateKeyW( root, path, hkey );
|
||||
}
|
||||
|
||||
UINT ACTION_MsiPublishAssemblies( MSIPACKAGE *package )
|
||||
{
|
||||
MSICOMPONENT *comp;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
|
||||
{
|
||||
LONG res;
|
||||
HKEY hkey;
|
||||
GUID guid;
|
||||
DWORD size;
|
||||
WCHAR buffer[43];
|
||||
MSIRECORD *uirow;
|
||||
MSIASSEMBLY *assembly = comp->assembly;
|
||||
BOOL win32;
|
||||
|
||||
if (!assembly || !comp->ComponentId) continue;
|
||||
|
||||
if (!comp->Enabled)
|
||||
{
|
||||
TRACE("component is disabled: %s\n", debugstr_w(comp->Component));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
|
||||
{
|
||||
TRACE("Component not scheduled for installation: %s\n", debugstr_w(comp->Component));
|
||||
comp->Action = comp->Installed;
|
||||
continue;
|
||||
}
|
||||
comp->Action = INSTALLSTATE_LOCAL;
|
||||
|
||||
TRACE("publishing %s\n", debugstr_w(comp->Component));
|
||||
|
||||
CLSIDFromString( package->ProductCode, &guid );
|
||||
encode_base85_guid( &guid, buffer );
|
||||
buffer[20] = '>';
|
||||
CLSIDFromString( comp->ComponentId, &guid );
|
||||
encode_base85_guid( &guid, buffer + 21 );
|
||||
buffer[42] = 0;
|
||||
|
||||
win32 = assembly->attributes & msidbAssemblyAttributesWin32;
|
||||
if (assembly->application)
|
||||
{
|
||||
MSIFILE *file = get_loaded_file( package, assembly->application );
|
||||
if ((res = open_local_assembly_key( package->Context, win32, file->TargetPath, &hkey )))
|
||||
{
|
||||
WARN("failed to open local assembly key %d\n", res);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((res = open_global_assembly_key( package->Context, win32, &hkey )))
|
||||
{
|
||||
WARN("failed to open global assembly key %d\n", res);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
}
|
||||
size = sizeof(buffer);
|
||||
if ((res = RegSetValueExW( hkey, assembly->display_name, 0, REG_MULTI_SZ, (const BYTE *)buffer, size )))
|
||||
{
|
||||
WARN("failed to set assembly value %d\n", res);
|
||||
}
|
||||
RegCloseKey( hkey );
|
||||
|
||||
uirow = MSI_CreateRecord( 2 );
|
||||
MSI_RecordSetStringW( uirow, 2, assembly->display_name );
|
||||
ui_actiondata( package, szMsiPublishAssemblies, uirow );
|
||||
msiobj_release( &uirow->hdr );
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package )
|
||||
{
|
||||
MSICOMPONENT *comp;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
|
||||
{
|
||||
LONG res;
|
||||
MSIRECORD *uirow;
|
||||
MSIASSEMBLY *assembly = comp->assembly;
|
||||
BOOL win32;
|
||||
|
||||
if (!assembly || !comp->ComponentId) continue;
|
||||
|
||||
if (!comp->Enabled)
|
||||
{
|
||||
TRACE("component is disabled: %s\n", debugstr_w(comp->Component));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
|
||||
{
|
||||
TRACE("Component not scheduled for removal: %s\n", debugstr_w(comp->Component));
|
||||
comp->Action = comp->Installed;
|
||||
continue;
|
||||
}
|
||||
comp->Action = INSTALLSTATE_ABSENT;
|
||||
|
||||
TRACE("unpublishing %s\n", debugstr_w(comp->Component));
|
||||
|
||||
win32 = assembly->attributes & msidbAssemblyAttributesWin32;
|
||||
if (assembly->application)
|
||||
{
|
||||
MSIFILE *file = get_loaded_file( package, assembly->application );
|
||||
if ((res = delete_local_assembly_key( package->Context, win32, file->TargetPath )))
|
||||
WARN("failed to delete local assembly key %d\n", res);
|
||||
}
|
||||
else
|
||||
{
|
||||
HKEY hkey;
|
||||
if ((res = open_global_assembly_key( package->Context, win32, &hkey )))
|
||||
WARN("failed to delete global assembly key %d\n", res);
|
||||
else
|
||||
{
|
||||
if ((res = RegDeleteValueW( hkey, assembly->display_name )))
|
||||
WARN("failed to delete global assembly value %d\n", res);
|
||||
RegCloseKey( hkey );
|
||||
}
|
||||
}
|
||||
|
||||
uirow = MSI_CreateRecord( 2 );
|
||||
MSI_RecordSetStringW( uirow, 2, assembly->display_name );
|
||||
ui_actiondata( package, szMsiPublishAssemblies, uirow );
|
||||
msiobj_release( &uirow->hdr );
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@@ -87,7 +87,7 @@ static MSIAPPID *load_given_appid( MSIPACKAGE *package, LPCWSTR name )
|
||||
/* check for appids already loaded */
|
||||
LIST_FOR_EACH_ENTRY( appid, &package->appids, MSIAPPID, entry )
|
||||
{
|
||||
if (lstrcmpiW( appid->AppID, name )==0)
|
||||
if (!strcmpiW( appid->AppID, name ))
|
||||
{
|
||||
TRACE("found appid %s %p\n", debugstr_w(name), appid);
|
||||
return appid;
|
||||
@@ -192,7 +192,7 @@ static MSIPROGID *load_given_progid(MSIPACKAGE *package, LPCWSTR name)
|
||||
/* check for progids already loaded */
|
||||
LIST_FOR_EACH_ENTRY( progid, &package->progids, MSIPROGID, entry )
|
||||
{
|
||||
if (strcmpiW( progid->ProgID,name )==0)
|
||||
if (!strcmpiW( progid->ProgID, name ))
|
||||
{
|
||||
TRACE("found progid %s (%p)\n",debugstr_w(name), progid );
|
||||
return progid;
|
||||
@@ -323,7 +323,7 @@ static MSICLASS *load_given_class(MSIPACKAGE *package, LPCWSTR classid)
|
||||
/* check for classes already loaded */
|
||||
LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
|
||||
{
|
||||
if (lstrcmpiW( cls->clsid, classid )==0)
|
||||
if (!strcmpiW( cls->clsid, classid ))
|
||||
{
|
||||
TRACE("found class %s (%p)\n",debugstr_w(classid), cls);
|
||||
return cls;
|
||||
@@ -384,7 +384,7 @@ static MSIMIME *load_given_mime( MSIPACKAGE *package, LPCWSTR mime )
|
||||
/* check for mime already loaded */
|
||||
LIST_FOR_EACH_ENTRY( mt, &package->mimes, MSIMIME, entry )
|
||||
{
|
||||
if (strcmpiW(mt->ContentType,mime)==0)
|
||||
if (!strcmpiW( mt->ContentType, mime ))
|
||||
{
|
||||
TRACE("found mime %s (%p)\n",debugstr_w(mime), mt);
|
||||
return mt;
|
||||
@@ -458,7 +458,7 @@ static MSIEXTENSION *load_given_extension( MSIPACKAGE *package, LPCWSTR name )
|
||||
/* check for extensions already loaded */
|
||||
LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry )
|
||||
{
|
||||
if (strcmpiW( ext->Extension, name )==0)
|
||||
if (!strcmpiW( ext->Extension, name ))
|
||||
{
|
||||
TRACE("extension %s already loaded %p\n", debugstr_w(name), ext);
|
||||
return ext;
|
||||
@@ -578,7 +578,7 @@ static UINT iterate_all_extensions(MSIRECORD *rec, LPVOID param)
|
||||
|
||||
LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry )
|
||||
{
|
||||
if (strcmpiW(extension,ext->Extension))
|
||||
if (strcmpiW(extension, ext->Extension))
|
||||
continue;
|
||||
if (comp == ext->Component)
|
||||
{
|
||||
@@ -850,8 +850,7 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||
}
|
||||
feature->Action = feature->ActionRequest;
|
||||
|
||||
file = get_loaded_file( package, comp->KeyPath );
|
||||
if (!file)
|
||||
if (!comp->KeyPath || !(file = get_loaded_file( package, comp->KeyPath )))
|
||||
{
|
||||
TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid));
|
||||
continue;
|
||||
|
||||
+32
-22
@@ -2323,26 +2323,36 @@ static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b )
|
||||
switch (operator)
|
||||
{
|
||||
case COND_SS:
|
||||
return strstrW( a, b ) ? 1 : 0;
|
||||
return strstrW( a, b ) != 0;
|
||||
case COND_ISS:
|
||||
return strstriW( a, b ) ? 1 : 0;
|
||||
return strstriW( a, b ) != 0;
|
||||
case COND_LHS:
|
||||
return 0 == strncmpW( a, b, lstrlenW( b ) );
|
||||
{
|
||||
int l = strlenW( a );
|
||||
int r = strlenW( b );
|
||||
if (r > l) return 0;
|
||||
return !strncmpW( a, b, r );
|
||||
}
|
||||
case COND_RHS:
|
||||
{
|
||||
int l = lstrlenW( a );
|
||||
int r = lstrlenW( b );
|
||||
int l = strlenW( a );
|
||||
int r = strlenW( b );
|
||||
if (r > l) return 0;
|
||||
return 0 == lstrcmpW( a + (l - r), b );
|
||||
return !strncmpW( a + (l - r), b, r );
|
||||
}
|
||||
case COND_ILHS:
|
||||
return 0 == strncmpiW( a, b, lstrlenW( b ) );
|
||||
{
|
||||
int l = strlenW( a );
|
||||
int r = strlenW( b );
|
||||
if (r > l) return 0;
|
||||
return !strncmpiW( a, b, r );
|
||||
}
|
||||
case COND_IRHS:
|
||||
{
|
||||
int l = lstrlenW( a );
|
||||
int r = lstrlenW( b );
|
||||
int l = strlenW( a );
|
||||
int r = strlenW( b );
|
||||
if (r > l) return 0;
|
||||
return 0 == lstrcmpiW( a + (l - r), b );
|
||||
return !strncmpiW( a + (l - r), b, r );
|
||||
}
|
||||
default:
|
||||
ERR("invalid substring operator\n");
|
||||
@@ -2367,29 +2377,29 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert )
|
||||
switch (operator)
|
||||
{
|
||||
case COND_LT:
|
||||
return -1 == lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) < 0;
|
||||
case COND_GT:
|
||||
return 1 == lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) > 0;
|
||||
case COND_EQ:
|
||||
return 0 == lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) == 0;
|
||||
case COND_NE:
|
||||
return 0 != lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) != 0;
|
||||
case COND_GE:
|
||||
return -1 != lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) >= 0;
|
||||
case COND_LE:
|
||||
return 1 != lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) <= 0;
|
||||
case COND_ILT:
|
||||
return -1 == lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) < 0;
|
||||
case COND_IGT:
|
||||
return 1 == lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) > 0;
|
||||
case COND_IEQ:
|
||||
return 0 == lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) == 0;
|
||||
case COND_INE:
|
||||
return 0 != lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) != 0;
|
||||
case COND_IGE:
|
||||
return -1 != lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) >= 0;
|
||||
case COND_ILE:
|
||||
return 1 != lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) <= 0;
|
||||
default:
|
||||
ERR("invalid string operator\n");
|
||||
return 0;
|
||||
|
||||
+32
-22
@@ -456,26 +456,36 @@ static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b )
|
||||
switch (operator)
|
||||
{
|
||||
case COND_SS:
|
||||
return strstrW( a, b ) ? 1 : 0;
|
||||
return strstrW( a, b ) != 0;
|
||||
case COND_ISS:
|
||||
return strstriW( a, b ) ? 1 : 0;
|
||||
return strstriW( a, b ) != 0;
|
||||
case COND_LHS:
|
||||
return 0 == strncmpW( a, b, lstrlenW( b ) );
|
||||
{
|
||||
int l = strlenW( a );
|
||||
int r = strlenW( b );
|
||||
if (r > l) return 0;
|
||||
return !strncmpW( a, b, r );
|
||||
}
|
||||
case COND_RHS:
|
||||
{
|
||||
int l = lstrlenW( a );
|
||||
int r = lstrlenW( b );
|
||||
int l = strlenW( a );
|
||||
int r = strlenW( b );
|
||||
if (r > l) return 0;
|
||||
return 0 == lstrcmpW( a + (l - r), b );
|
||||
return !strncmpW( a + (l - r), b, r );
|
||||
}
|
||||
case COND_ILHS:
|
||||
return 0 == strncmpiW( a, b, lstrlenW( b ) );
|
||||
{
|
||||
int l = strlenW( a );
|
||||
int r = strlenW( b );
|
||||
if (r > l) return 0;
|
||||
return !strncmpiW( a, b, r );
|
||||
}
|
||||
case COND_IRHS:
|
||||
{
|
||||
int l = lstrlenW( a );
|
||||
int r = lstrlenW( b );
|
||||
int l = strlenW( a );
|
||||
int r = strlenW( b );
|
||||
if (r > l) return 0;
|
||||
return 0 == lstrcmpiW( a + (l - r), b );
|
||||
return !strncmpiW( a + (l - r), b, r );
|
||||
}
|
||||
default:
|
||||
ERR("invalid substring operator\n");
|
||||
@@ -500,29 +510,29 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert )
|
||||
switch (operator)
|
||||
{
|
||||
case COND_LT:
|
||||
return -1 == lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) < 0;
|
||||
case COND_GT:
|
||||
return 1 == lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) > 0;
|
||||
case COND_EQ:
|
||||
return 0 == lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) == 0;
|
||||
case COND_NE:
|
||||
return 0 != lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) != 0;
|
||||
case COND_GE:
|
||||
return -1 != lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) >= 0;
|
||||
case COND_LE:
|
||||
return 1 != lstrcmpW( a, b );
|
||||
return strcmpW( a, b ) <= 0;
|
||||
case COND_ILT:
|
||||
return -1 == lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) < 0;
|
||||
case COND_IGT:
|
||||
return 1 == lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) > 0;
|
||||
case COND_IEQ:
|
||||
return 0 == lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) == 0;
|
||||
case COND_INE:
|
||||
return 0 != lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) != 0;
|
||||
case COND_IGE:
|
||||
return -1 != lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) >= 0;
|
||||
case COND_ILE:
|
||||
return 1 != lstrcmpiW( a, b );
|
||||
return strcmpiW( a, b ) <= 0;
|
||||
default:
|
||||
ERR("invalid string operator\n");
|
||||
return 0;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "msi.h"
|
||||
#include "msiquery.h"
|
||||
#include "objbase.h"
|
||||
@@ -153,7 +154,7 @@ static UINT check_columns( const column_info *col_info )
|
||||
/* check for two columns with the same name */
|
||||
for( c1 = col_info; c1; c1 = c1->next )
|
||||
for( c2 = c1->next; c2; c2 = c2->next )
|
||||
if (!lstrcmpW(c1->column, c2->column))
|
||||
if (!strcmpW( c1->column, c2->column ))
|
||||
return ERROR_BAD_QUERY_SYNTAX;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
+90
-65
@@ -236,7 +236,7 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL
|
||||
}
|
||||
else if (type & msidbCustomActionTypeRollback)
|
||||
{
|
||||
FIXME("Deferring rollback only action... rollbacks not supported yet\n");
|
||||
FIXME("Deferring rollback only action\n");
|
||||
schedule_action(package, ROLLBACK_SCRIPT, deferred);
|
||||
}
|
||||
else
|
||||
@@ -274,6 +274,12 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL
|
||||
|
||||
msi_free(actiondata);
|
||||
}
|
||||
if (type & msidbCustomActionTypeRollback)
|
||||
{
|
||||
FIXME("Rollbacks not supported yet\n");
|
||||
rc = ERROR_SUCCESS;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else if (!check_execution_scheduling_options(package,action,type))
|
||||
{
|
||||
@@ -355,60 +361,88 @@ end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static UINT store_binary_to_temp(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPWSTR tmp_file)
|
||||
static MSIBINARY *create_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll )
|
||||
{
|
||||
static const WCHAR query[] = {
|
||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','B','i' ,'n','a','r','y','`',' ','W','H','E','R','E',' ',
|
||||
'`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0};
|
||||
MSIRECORD *row = 0;
|
||||
MSIRECORD *row;
|
||||
MSIBINARY *binary;
|
||||
HANDLE file;
|
||||
CHAR buffer[1024];
|
||||
WCHAR fmt[MAX_PATH];
|
||||
DWORD sz = MAX_PATH;
|
||||
WCHAR fmt[MAX_PATH], tmpfile[MAX_PATH];
|
||||
DWORD sz = MAX_PATH, write;
|
||||
UINT r;
|
||||
|
||||
if (msi_get_property(package->db, cszTempFolder, fmt, &sz) != ERROR_SUCCESS)
|
||||
GetTempPathW(MAX_PATH, fmt);
|
||||
|
||||
if (GetTempFileNameW(fmt, szMsi, 0, tmp_file) == 0)
|
||||
if (!GetTempFileNameW( fmt, szMsi, 0, tmpfile ))
|
||||
{
|
||||
TRACE("Unable to create file\n");
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
TRACE("unable to create temp file %s (%u)\n", debugstr_w(tmpfile), GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
track_tempfile(package, tmp_file);
|
||||
|
||||
row = MSI_QueryGetRecord(package->db, query, source);
|
||||
if (!row)
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
return NULL;
|
||||
|
||||
/* write out the file */
|
||||
file = CreateFileW(tmp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
r = ERROR_FUNCTION_FAILED;
|
||||
else
|
||||
if (!(binary = msi_alloc_zero( sizeof(MSIBINARY) )))
|
||||
{
|
||||
do
|
||||
msiobj_release( &row->hdr );
|
||||
return NULL;
|
||||
}
|
||||
file = CreateFileW( tmpfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
msiobj_release( &row->hdr );
|
||||
msi_free( binary );
|
||||
return NULL;
|
||||
}
|
||||
do
|
||||
{
|
||||
sz = sizeof(buffer);
|
||||
r = MSI_RecordReadStream( row, 2, buffer, &sz );
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
DWORD write;
|
||||
sz = sizeof buffer;
|
||||
r = MSI_RecordReadStream(row, 2, buffer, &sz);
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("Failed to get stream\n");
|
||||
break;
|
||||
}
|
||||
WriteFile(file, buffer, sz, &write, NULL);
|
||||
} while (sz == sizeof buffer);
|
||||
CloseHandle(file);
|
||||
ERR("Failed to get stream\n");
|
||||
break;
|
||||
}
|
||||
WriteFile( file, buffer, sz, &write, NULL );
|
||||
} while (sz == sizeof buffer);
|
||||
|
||||
CloseHandle( file );
|
||||
msiobj_release( &row->hdr );
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
DeleteFileW( tmpfile );
|
||||
msi_free( binary );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msiobj_release(&row->hdr);
|
||||
/* keep a reference to prevent the dll from being unloaded */
|
||||
if (dll && !(binary->module = LoadLibraryW( tmpfile )))
|
||||
{
|
||||
WARN( "failed to load dll %s (%u)\n", debugstr_w( tmpfile ), GetLastError() );
|
||||
}
|
||||
binary->source = strdupW( source );
|
||||
binary->tmpfile = strdupW( tmpfile );
|
||||
list_add_tail( &package->binaries, &binary->entry );
|
||||
return binary;
|
||||
}
|
||||
|
||||
return r;
|
||||
static MSIBINARY *get_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll )
|
||||
{
|
||||
MSIBINARY *binary;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( binary, &package->binaries, MSIBINARY, entry )
|
||||
{
|
||||
if (!strcmpW( binary->source, source ))
|
||||
return binary;
|
||||
}
|
||||
|
||||
return create_temp_binary( package, source, dll );
|
||||
}
|
||||
|
||||
static void file_running_action(MSIPACKAGE* package, HANDLE Handle,
|
||||
@@ -594,7 +628,7 @@ static void handle_msi_break( LPCWSTR target )
|
||||
if( !GetEnvironmentVariableW( MsiBreak, val, MAX_PATH ))
|
||||
return;
|
||||
|
||||
if( lstrcmpiW( val, target ))
|
||||
if( strcmpiW( val, target ))
|
||||
return;
|
||||
|
||||
msg = msi_alloc( (lstrlenW(format) + 10) * sizeof(WCHAR) );
|
||||
@@ -615,7 +649,7 @@ static UINT get_action_info( const GUID *guid, INT *type, MSIHANDLE *handle,
|
||||
IWineMsiRemoteCustomAction *rca = NULL;
|
||||
HRESULT r;
|
||||
|
||||
r = DllGetClassObject( &CLSID_IWineMsiRemoteCustomAction,
|
||||
r = DllGetClassObject( &CLSID_WineMsiRemoteCustomAction,
|
||||
&IID_IClassFactory, (LPVOID *)&cf );
|
||||
if (FAILED(r))
|
||||
{
|
||||
@@ -683,8 +717,8 @@ static DWORD ACTION_CallDllFunction( const GUID *guid )
|
||||
hModule = LoadLibraryW( dll );
|
||||
if (!hModule)
|
||||
{
|
||||
ERR("failed to load dll %s (%u)\n", debugstr_w( dll ), GetLastError() );
|
||||
return r;
|
||||
WARN( "failed to load dll %s (%u)\n", debugstr_w( dll ), GetLastError() );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
proc = strdupWtoA( function );
|
||||
@@ -875,20 +909,15 @@ static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
{
|
||||
msi_custom_action_info *info;
|
||||
WCHAR tmp_file[MAX_PATH];
|
||||
MSIBINARY *binary;
|
||||
UINT r;
|
||||
|
||||
r = store_binary_to_temp(package, source, tmp_file);
|
||||
if (r != ERROR_SUCCESS)
|
||||
return r;
|
||||
if (!(binary = get_temp_binary( package, source, TRUE )))
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
TRACE("Calling function %s from %s\n",debugstr_w(target),
|
||||
debugstr_w(tmp_file));
|
||||
TRACE("Calling function %s from %s\n", debugstr_w(target), debugstr_w(binary->tmpfile));
|
||||
|
||||
if (!strchrW(tmp_file,'.'))
|
||||
strcatW(tmp_file, szDot);
|
||||
|
||||
info = do_msidbCustomActionTypeDll( package, type, tmp_file, target, action );
|
||||
info = do_msidbCustomActionTypeDll( package, type, binary->tmpfile, target, action );
|
||||
|
||||
r = wait_thread_handle( info );
|
||||
release_custom_action_data( info );
|
||||
@@ -898,7 +927,6 @@ static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source,
|
||||
static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
{
|
||||
WCHAR tmp_file[MAX_PATH];
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION info;
|
||||
BOOL rc;
|
||||
@@ -906,29 +934,27 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
|
||||
WCHAR *deformated = NULL;
|
||||
WCHAR *cmd;
|
||||
static const WCHAR spc[] = {' ',0};
|
||||
MSIBINARY *binary;
|
||||
UINT r;
|
||||
|
||||
memset(&si,0,sizeof(STARTUPINFOW));
|
||||
|
||||
r = store_binary_to_temp(package, source, tmp_file);
|
||||
if (r != ERROR_SUCCESS)
|
||||
return r;
|
||||
if (!(binary = get_temp_binary( package, source, FALSE )))
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
deformat_string(package,target,&deformated);
|
||||
|
||||
len = strlenW(tmp_file)+2;
|
||||
|
||||
len = strlenW( binary->tmpfile ) + 2;
|
||||
if (deformated)
|
||||
len += strlenW(deformated);
|
||||
|
||||
cmd = msi_alloc(sizeof(WCHAR)*len);
|
||||
|
||||
strcpyW(cmd,tmp_file);
|
||||
strcpyW( cmd, binary->tmpfile );
|
||||
if (deformated)
|
||||
{
|
||||
strcatW(cmd,spc);
|
||||
strcatW(cmd,deformated);
|
||||
|
||||
msi_free(deformated);
|
||||
}
|
||||
|
||||
@@ -1121,8 +1147,7 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
|
||||
|
||||
memset(&si, 0, sizeof(STARTUPINFOW));
|
||||
|
||||
workingdir = resolve_folder(package, source, FALSE, FALSE, TRUE, NULL);
|
||||
|
||||
workingdir = resolve_target_folder( package, source, FALSE, TRUE, NULL );
|
||||
if (!workingdir)
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
@@ -1161,13 +1186,13 @@ static DWORD ACTION_CallScript( const GUID *guid )
|
||||
{
|
||||
msi_custom_action_info *info;
|
||||
MSIHANDLE hPackage;
|
||||
UINT r = ERROR_FUNCTION_FAILED;
|
||||
UINT r;
|
||||
|
||||
info = find_action_by_guid( guid );
|
||||
if (!info)
|
||||
{
|
||||
ERR("failed to find action %s\n", debugstr_guid( guid) );
|
||||
return r;
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
TRACE("function %s, script %s\n", debugstr_w( info->target ), debugstr_w( info->source ) );
|
||||
@@ -1176,13 +1201,13 @@ static DWORD ACTION_CallScript( const GUID *guid )
|
||||
if (hPackage)
|
||||
{
|
||||
r = call_script( hPackage, info->type, info->source, info->target, info->action );
|
||||
TRACE("script returned %u\n", r);
|
||||
MsiCloseHandle( hPackage );
|
||||
}
|
||||
else
|
||||
ERR("failed to create handle for %p\n", info->package );
|
||||
|
||||
release_custom_action_data( info );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1433,13 +1458,13 @@ void ACTION_FinishCustomActions(const MSIPACKAGE* package)
|
||||
}
|
||||
|
||||
typedef struct _msi_custom_remote_impl {
|
||||
const IWineMsiRemoteCustomActionVtbl *lpVtbl;
|
||||
IWineMsiRemoteCustomAction IWineMsiRemoteCustomAction_iface;
|
||||
LONG refs;
|
||||
} msi_custom_remote_impl;
|
||||
|
||||
static inline msi_custom_remote_impl* mcr_from_IWineMsiRemoteCustomAction( IWineMsiRemoteCustomAction* iface )
|
||||
static inline msi_custom_remote_impl *impl_from_IWineMsiRemoteCustomAction( IWineMsiRemoteCustomAction *iface )
|
||||
{
|
||||
return (msi_custom_remote_impl*) iface;
|
||||
return CONTAINING_RECORD(iface, msi_custom_remote_impl, IWineMsiRemoteCustomAction_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mcr_QueryInterface( IWineMsiRemoteCustomAction *iface,
|
||||
@@ -1458,14 +1483,14 @@ static HRESULT WINAPI mcr_QueryInterface( IWineMsiRemoteCustomAction *iface,
|
||||
|
||||
static ULONG WINAPI mcr_AddRef( IWineMsiRemoteCustomAction *iface )
|
||||
{
|
||||
msi_custom_remote_impl* This = mcr_from_IWineMsiRemoteCustomAction( iface );
|
||||
msi_custom_remote_impl* This = impl_from_IWineMsiRemoteCustomAction( iface );
|
||||
|
||||
return InterlockedIncrement( &This->refs );
|
||||
}
|
||||
|
||||
static ULONG WINAPI mcr_Release( IWineMsiRemoteCustomAction *iface )
|
||||
{
|
||||
msi_custom_remote_impl* This = mcr_from_IWineMsiRemoteCustomAction( iface );
|
||||
msi_custom_remote_impl* This = impl_from_IWineMsiRemoteCustomAction( iface );
|
||||
ULONG r;
|
||||
|
||||
r = InterlockedDecrement( &This->refs );
|
||||
@@ -1508,7 +1533,7 @@ HRESULT create_msi_custom_remote( IUnknown *pOuter, LPVOID *ppObj )
|
||||
if (!This)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->lpVtbl = &msi_custom_remote_vtbl;
|
||||
This->IWineMsiRemoteCustomAction_iface.lpVtbl = &msi_custom_remote_vtbl;
|
||||
This->refs = 1;
|
||||
|
||||
*ppObj = This;
|
||||
|
||||
+33
-24
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
@@ -79,7 +80,7 @@ static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !lstrcmpW( name, stat.pwcsName ) )
|
||||
if( !strcmpW( name, stat.pwcsName ) )
|
||||
{
|
||||
TRACE("found %s\n", debugstr_w(name));
|
||||
*stm = stream->stm;
|
||||
@@ -888,6 +889,8 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
|
||||
|
||||
static const WCHAR suminfo[] =
|
||||
{'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0};
|
||||
static const WCHAR forcecodepage[] =
|
||||
{'_','F','o','r','c','e','C','o','d','e','p','a','g','e',0};
|
||||
|
||||
TRACE("%p %s %s\n", db, debugstr_w(folder), debugstr_w(file) );
|
||||
|
||||
@@ -910,6 +913,13 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
|
||||
msi_parse_line( &ptr, &types, &num_types );
|
||||
msi_parse_line( &ptr, &labels, &num_labels );
|
||||
|
||||
if (num_columns == 1 && !columns[0][0] && num_labels == 1 && !labels[0][0] &&
|
||||
num_types == 2 && !strcmpW( types[1], forcecodepage ))
|
||||
{
|
||||
r = msi_set_string_table_codepage( db->strings, atoiW( types[0] ) );
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (num_columns != num_types)
|
||||
{
|
||||
r = ERROR_FUNCTION_FAILED;
|
||||
@@ -1087,13 +1097,13 @@ static UINT msi_export_row( MSIRECORD *row, void *arg )
|
||||
return msi_export_record( arg, row, 1 );
|
||||
}
|
||||
|
||||
static UINT msi_export_forcecodepage( HANDLE handle )
|
||||
static UINT msi_export_forcecodepage( HANDLE handle, UINT codepage )
|
||||
{
|
||||
static const char fmt[] = "\r\n\r\n%u\t_ForceCodepage\r\n";
|
||||
char data[sizeof(fmt) + 10];
|
||||
DWORD sz;
|
||||
|
||||
static const char data[] = "\r\n\r\n0\t_ForceCodepage\r\n";
|
||||
|
||||
FIXME("Read the codepage from the strings table!\n");
|
||||
sprintf( data, fmt, codepage );
|
||||
|
||||
sz = lstrlenA(data) + 1;
|
||||
if (!WriteFile(handle, data, sz, &sz, NULL))
|
||||
@@ -1136,9 +1146,10 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table,
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
if (!lstrcmpW( table, forcecodepage ))
|
||||
if (!strcmpW( table, forcecodepage ))
|
||||
{
|
||||
r = msi_export_forcecodepage( handle );
|
||||
UINT codepage = msi_get_string_table_codepage( db->strings );
|
||||
r = msi_export_forcecodepage( handle, codepage );
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1319,7 +1330,7 @@ static BOOL merge_type_match(LPCWSTR type1, LPCWSTR type2)
|
||||
((type2[0] == 'L') || (type2[0] == 'S')))
|
||||
return TRUE;
|
||||
|
||||
return !lstrcmpW(type1, type2);
|
||||
return !strcmpW( type1, type2 );
|
||||
}
|
||||
|
||||
static UINT merge_verify_colnames(MSIQUERY *dbview, MSIQUERY *mergeview)
|
||||
@@ -1341,8 +1352,7 @@ static UINT merge_verify_colnames(MSIQUERY *dbview, MSIQUERY *mergeview)
|
||||
if (!MSI_RecordGetString(mergerec, i))
|
||||
break;
|
||||
|
||||
if (lstrcmpW(MSI_RecordGetString(dbrec, i),
|
||||
MSI_RecordGetString(mergerec, i)))
|
||||
if (strcmpW( MSI_RecordGetString( dbrec, i ), MSI_RecordGetString( mergerec, i ) ))
|
||||
{
|
||||
r = ERROR_DATATYPE_MISMATCH;
|
||||
goto done;
|
||||
@@ -1405,8 +1415,7 @@ static UINT merge_verify_primary_keys(MSIDATABASE *db, MSIDATABASE *mergedb,
|
||||
|
||||
for (i = 1; i <= count; i++)
|
||||
{
|
||||
if (lstrcmpW(MSI_RecordGetString(dbrec, i),
|
||||
MSI_RecordGetString(mergerec, i)))
|
||||
if (strcmpW( MSI_RecordGetString( dbrec, i ), MSI_RecordGetString( mergerec, i ) ))
|
||||
{
|
||||
r = ERROR_DATATYPE_MISMATCH;
|
||||
goto done;
|
||||
@@ -1434,7 +1443,7 @@ static LPWSTR get_key_value(MSIQUERY *view, LPCWSTR key, MSIRECORD *rec)
|
||||
do
|
||||
{
|
||||
str = msi_dup_record_field(colnames, ++i);
|
||||
cmp = lstrcmpW(key, str);
|
||||
cmp = strcmpW( key, str );
|
||||
msi_free(str);
|
||||
} while (cmp);
|
||||
|
||||
@@ -2029,14 +2038,14 @@ MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle )
|
||||
}
|
||||
|
||||
typedef struct _msi_remote_database_impl {
|
||||
const IWineMsiRemoteDatabaseVtbl *lpVtbl;
|
||||
IWineMsiRemoteDatabase IWineMsiRemoteDatabase_iface;
|
||||
MSIHANDLE database;
|
||||
LONG refs;
|
||||
} msi_remote_database_impl;
|
||||
|
||||
static inline msi_remote_database_impl* mrd_from_IWineMsiRemoteDatabase( IWineMsiRemoteDatabase* iface )
|
||||
static inline msi_remote_database_impl *impl_from_IWineMsiRemoteDatabase( IWineMsiRemoteDatabase *iface )
|
||||
{
|
||||
return (msi_remote_database_impl *)iface;
|
||||
return CONTAINING_RECORD(iface, msi_remote_database_impl, IWineMsiRemoteDatabase_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrd_QueryInterface( IWineMsiRemoteDatabase *iface,
|
||||
@@ -2055,14 +2064,14 @@ static HRESULT WINAPI mrd_QueryInterface( IWineMsiRemoteDatabase *iface,
|
||||
|
||||
static ULONG WINAPI mrd_AddRef( IWineMsiRemoteDatabase *iface )
|
||||
{
|
||||
msi_remote_database_impl* This = mrd_from_IWineMsiRemoteDatabase( iface );
|
||||
msi_remote_database_impl* This = impl_from_IWineMsiRemoteDatabase( iface );
|
||||
|
||||
return InterlockedIncrement( &This->refs );
|
||||
}
|
||||
|
||||
static ULONG WINAPI mrd_Release( IWineMsiRemoteDatabase *iface )
|
||||
{
|
||||
msi_remote_database_impl* This = mrd_from_IWineMsiRemoteDatabase( iface );
|
||||
msi_remote_database_impl* This = impl_from_IWineMsiRemoteDatabase( iface );
|
||||
ULONG r;
|
||||
|
||||
r = InterlockedDecrement( &This->refs );
|
||||
@@ -2077,7 +2086,7 @@ static ULONG WINAPI mrd_Release( IWineMsiRemoteDatabase *iface )
|
||||
static HRESULT WINAPI mrd_IsTablePersistent( IWineMsiRemoteDatabase *iface,
|
||||
LPCWSTR table, MSICONDITION *persistent )
|
||||
{
|
||||
msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface );
|
||||
msi_remote_database_impl *This = impl_from_IWineMsiRemoteDatabase( iface );
|
||||
*persistent = MsiDatabaseIsTablePersistentW(This->database, table);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -2085,7 +2094,7 @@ static HRESULT WINAPI mrd_IsTablePersistent( IWineMsiRemoteDatabase *iface,
|
||||
static HRESULT WINAPI mrd_GetPrimaryKeys( IWineMsiRemoteDatabase *iface,
|
||||
LPCWSTR table, MSIHANDLE *keys )
|
||||
{
|
||||
msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface );
|
||||
msi_remote_database_impl *This = impl_from_IWineMsiRemoteDatabase( iface );
|
||||
UINT r = MsiDatabaseGetPrimaryKeysW(This->database, table, keys);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
@@ -2093,7 +2102,7 @@ static HRESULT WINAPI mrd_GetPrimaryKeys( IWineMsiRemoteDatabase *iface,
|
||||
static HRESULT WINAPI mrd_GetSummaryInformation( IWineMsiRemoteDatabase *iface,
|
||||
UINT updatecount, MSIHANDLE *suminfo )
|
||||
{
|
||||
msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface );
|
||||
msi_remote_database_impl *This = impl_from_IWineMsiRemoteDatabase( iface );
|
||||
UINT r = MsiGetSummaryInformationW(This->database, NULL, updatecount, suminfo);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
@@ -2101,14 +2110,14 @@ static HRESULT WINAPI mrd_GetSummaryInformation( IWineMsiRemoteDatabase *iface,
|
||||
static HRESULT WINAPI mrd_OpenView( IWineMsiRemoteDatabase *iface,
|
||||
LPCWSTR query, MSIHANDLE *view )
|
||||
{
|
||||
msi_remote_database_impl *This = mrd_from_IWineMsiRemoteDatabase( iface );
|
||||
msi_remote_database_impl *This = impl_from_IWineMsiRemoteDatabase( iface );
|
||||
UINT r = MsiDatabaseOpenViewW(This->database, query, view);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrd_SetMsiHandle( IWineMsiRemoteDatabase *iface, MSIHANDLE handle )
|
||||
{
|
||||
msi_remote_database_impl* This = mrd_from_IWineMsiRemoteDatabase( iface );
|
||||
msi_remote_database_impl* This = impl_from_IWineMsiRemoteDatabase( iface );
|
||||
This->database = handle;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -2133,7 +2142,7 @@ HRESULT create_msi_remote_database( IUnknown *pOuter, LPVOID *ppObj )
|
||||
if (!This)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->lpVtbl = &msi_remote_database_vtbl;
|
||||
This->IWineMsiRemoteDatabase_iface.lpVtbl = &msi_remote_database_vtbl;
|
||||
This->database = 0;
|
||||
This->refs = 1;
|
||||
|
||||
|
||||
+48
-38
@@ -73,7 +73,7 @@ struct msi_control_tag
|
||||
|
||||
typedef struct msi_font_tag
|
||||
{
|
||||
struct msi_font_tag *next;
|
||||
struct list entry;
|
||||
HFONT hfont;
|
||||
COLORREF color;
|
||||
WCHAR name[1];
|
||||
@@ -90,7 +90,7 @@ struct msi_dialog_tag
|
||||
SIZE size;
|
||||
HWND hwnd;
|
||||
LPWSTR default_font;
|
||||
msi_font *font_list;
|
||||
struct list fonts;
|
||||
struct list controls;
|
||||
HWND hWndFocus;
|
||||
LPWSTR control_default;
|
||||
@@ -310,8 +310,7 @@ static UINT msi_dialog_add_font( MSIRECORD *rec, LPVOID param )
|
||||
name = MSI_RecordGetString( rec, 1 );
|
||||
font = msi_alloc( sizeof *font + strlenW( name )*sizeof (WCHAR) );
|
||||
strcpyW( font->name, name );
|
||||
font->next = dialog->font_list;
|
||||
dialog->font_list = font;
|
||||
list_add_head( &dialog->fonts, &font->entry );
|
||||
|
||||
font->color = MSI_RecordGetInteger( rec, 4 );
|
||||
|
||||
@@ -346,9 +345,9 @@ static UINT msi_dialog_add_font( MSIRECORD *rec, LPVOID param )
|
||||
|
||||
static msi_font *msi_dialog_find_font( msi_dialog *dialog, LPCWSTR name )
|
||||
{
|
||||
msi_font *font;
|
||||
msi_font *font = NULL;
|
||||
|
||||
for( font = dialog->font_list; font; font = font->next )
|
||||
LIST_FOR_EACH_ENTRY( font, &dialog->fonts, msi_font, entry )
|
||||
if( !strcmpW( font->name, name ) ) /* FIXME: case sensitive? */
|
||||
break;
|
||||
|
||||
@@ -578,7 +577,7 @@ static void msi_dialog_update_controls( msi_dialog *dialog, LPCWSTR property )
|
||||
|
||||
LIST_FOR_EACH_ENTRY( control, &dialog->controls, msi_control, entry )
|
||||
{
|
||||
if ( !lstrcmpW( control->property, property ) && control->update )
|
||||
if ( control->property && !strcmpW( control->property, property ) && control->update )
|
||||
control->update( dialog, control );
|
||||
}
|
||||
}
|
||||
@@ -601,7 +600,7 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
|
||||
ctrl = msi_dialog_find_control( dialog, control );
|
||||
if (!ctrl)
|
||||
return;
|
||||
if( !lstrcmpW(attribute, szText) )
|
||||
if( !strcmpW( attribute, szText ) )
|
||||
{
|
||||
font_text = MSI_RecordGetString( rec , 1 );
|
||||
font = msi_dialog_get_style( font_text, &text );
|
||||
@@ -610,7 +609,7 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
|
||||
msi_free( font );
|
||||
msi_dialog_check_messages( NULL );
|
||||
}
|
||||
else if( !lstrcmpW(attribute, szProgress) )
|
||||
else if( !strcmpW( attribute, szProgress ) )
|
||||
{
|
||||
DWORD func, val;
|
||||
|
||||
@@ -640,12 +639,12 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( !lstrcmpW(attribute, szProperty) )
|
||||
else if ( !strcmpW( attribute, szProperty ) )
|
||||
{
|
||||
MSIFEATURE *feature = msi_seltree_get_selected_feature( ctrl );
|
||||
msi_dialog_set_property( dialog->package, ctrl->property, feature->Directory );
|
||||
}
|
||||
else if ( !lstrcmpW(attribute, szSelectionPath) )
|
||||
else if ( !strcmpW( attribute, szSelectionPath ) )
|
||||
{
|
||||
LPWSTR prop = msi_dialog_dup_property( dialog, ctrl->property, TRUE );
|
||||
LPWSTR path;
|
||||
@@ -1368,7 +1367,7 @@ static void msi_dialog_combobox_update( msi_dialog *dialog,
|
||||
for (j = 0; j < info->num_items; j++)
|
||||
{
|
||||
tmp = (LPWSTR) SendMessageW( control->hwnd, CB_GETITEMDATA, j, 0 );
|
||||
if (!lstrcmpW( value, tmp ))
|
||||
if (!strcmpW( value, tmp ))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1743,7 +1742,7 @@ static UINT msi_dialog_maskedit_control( msi_dialog *dialog, MSIRECORD *rec )
|
||||
font = msi_dialog_get_style( font_mask, &mask );
|
||||
if( !mask )
|
||||
{
|
||||
ERR("mask template is empty\n");
|
||||
WARN("mask template is empty\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -1988,7 +1987,7 @@ static UINT msi_dialog_create_radiobutton( MSIRECORD *rec, LPVOID param )
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
control->handler = msi_dialog_radiogroup_handler;
|
||||
|
||||
if (!lstrcmpW(control->name, group->propval))
|
||||
if (group->propval && !strcmpW( control->name, group->propval ))
|
||||
SendMessageW(control->hwnd, BM_SETCHECK, BST_CHECKED, 0);
|
||||
|
||||
prop = MSI_RecordGetString( rec, 1 );
|
||||
@@ -2126,9 +2125,9 @@ static void
|
||||
msi_seltree_update_feature_installstate( HWND hwnd, HTREEITEM hItem,
|
||||
MSIPACKAGE *package, MSIFEATURE *feature, INSTALLSTATE state )
|
||||
{
|
||||
msi_feature_set_state( package, feature, state );
|
||||
feature->ActionRequest = state;
|
||||
msi_seltree_sync_item_state( hwnd, feature, hItem );
|
||||
ACTION_UpdateComponentStates( package, feature->Feature );
|
||||
ACTION_UpdateComponentStates( package, feature );
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2258,7 +2257,11 @@ msi_seltree_add_child_features( MSIPACKAGE *package, HWND hwnd,
|
||||
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
if ( lstrcmpW( parent, feature->Feature_Parent ) )
|
||||
if ( parent && feature->Feature_Parent && strcmpW( parent, feature->Feature_Parent ))
|
||||
continue;
|
||||
else if ( parent && !feature->Feature_Parent )
|
||||
continue;
|
||||
else if ( !parent && feature->Feature_Parent )
|
||||
continue;
|
||||
|
||||
if ( !feature->Title )
|
||||
@@ -2373,14 +2376,19 @@ static UINT msi_dialog_seltree_handler( msi_dialog *dialog,
|
||||
ControlEvent_FireSubscribedEvent( dialog->package, szSelectionDescription, rec );
|
||||
|
||||
dir = MSI_RecordGetString( row, 7 );
|
||||
folder = get_loaded_folder( dialog->package, dir );
|
||||
if (!folder)
|
||||
if (dir)
|
||||
{
|
||||
r = ERROR_FUNCTION_FAILED;
|
||||
goto done;
|
||||
folder = get_loaded_folder( dialog->package, dir );
|
||||
if (!folder)
|
||||
{
|
||||
r = ERROR_FUNCTION_FAILED;
|
||||
goto done;
|
||||
}
|
||||
MSI_RecordSetStringW( rec, 1, folder->ResolvedTarget );
|
||||
}
|
||||
else
|
||||
MSI_RecordSetStringW( rec, 1, NULL );
|
||||
|
||||
MSI_RecordSetStringW( rec, 1, folder->ResolvedTarget );
|
||||
ControlEvent_FireSubscribedEvent( dialog->package, szSelectionPath, rec );
|
||||
|
||||
done:
|
||||
@@ -2682,7 +2690,7 @@ static void msi_dialog_update_directory_list( msi_dialog *dialog, msi_control *c
|
||||
if ( wfd.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY )
|
||||
continue;
|
||||
|
||||
if ( !lstrcmpW( wfd.cFileName, szDot ) || !lstrcmpW( wfd.cFileName, szDotDot ) )
|
||||
if ( !strcmpW( wfd.cFileName, szDot ) || !strcmpW( wfd.cFileName, szDotDot ) )
|
||||
continue;
|
||||
|
||||
item.mask = LVIF_TEXT;
|
||||
@@ -2846,7 +2854,7 @@ static void msi_dialog_vcl_add_columns( msi_dialog *dialog, msi_control *control
|
||||
begin += end - begin + 1;
|
||||
|
||||
/* empty braces or '0' hides the column */
|
||||
if ( !num[0] || !lstrcmpW( num, szZero ) )
|
||||
if ( !num[0] || !strcmpW( num, szZero ) )
|
||||
{
|
||||
count++;
|
||||
msi_free( num );
|
||||
@@ -3151,15 +3159,15 @@ static UINT msi_dialog_set_control_condition( MSIRECORD *rec, LPVOID param )
|
||||
TRACE("%s control %s\n", debugstr_w(action), debugstr_w(name));
|
||||
|
||||
/* FIXME: case sensitive? */
|
||||
if(!lstrcmpW(action, szHide))
|
||||
if (!strcmpW( action, szHide ))
|
||||
ShowWindow(control->hwnd, SW_HIDE);
|
||||
else if(!strcmpW(action, szShow))
|
||||
else if (!strcmpW( action, szShow ))
|
||||
ShowWindow(control->hwnd, SW_SHOW);
|
||||
else if(!strcmpW(action, szDisable))
|
||||
else if (!strcmpW( action, szDisable ))
|
||||
EnableWindow(control->hwnd, FALSE);
|
||||
else if(!strcmpW(action, szEnable))
|
||||
else if (!strcmpW( action, szEnable ))
|
||||
EnableWindow(control->hwnd, TRUE);
|
||||
else if(!strcmpW(action, szDefault))
|
||||
else if (!strcmpW( action, szDefault ))
|
||||
SetFocus(control->hwnd);
|
||||
else
|
||||
FIXME("Unhandled action %s\n", debugstr_w(action));
|
||||
@@ -3844,6 +3852,7 @@ msi_dialog *msi_dialog_create( MSIPACKAGE* package,
|
||||
dialog->event_handler = event_handler;
|
||||
dialog->finished = 0;
|
||||
list_init( &dialog->controls );
|
||||
list_init( &dialog->fonts );
|
||||
|
||||
/* verify that the dialog exists */
|
||||
rec = msi_get_dialog_record( dialog );
|
||||
@@ -3960,6 +3969,8 @@ void msi_dialog_do_preview( msi_dialog *dialog )
|
||||
|
||||
void msi_dialog_destroy( msi_dialog *dialog )
|
||||
{
|
||||
msi_font *font, *next;
|
||||
|
||||
if( uiThreadId != GetCurrentThreadId() )
|
||||
{
|
||||
SendMessageW( hMsiHiddenWindow, WM_MSI_DIALOG_DESTROY, 0, (LPARAM) dialog );
|
||||
@@ -3986,12 +3997,11 @@ void msi_dialog_destroy( msi_dialog *dialog )
|
||||
}
|
||||
|
||||
/* destroy the list of fonts */
|
||||
while( dialog->font_list )
|
||||
LIST_FOR_EACH_ENTRY_SAFE( font, next, &dialog->fonts, msi_font, entry )
|
||||
{
|
||||
msi_font *t = dialog->font_list;
|
||||
dialog->font_list = t->next;
|
||||
DeleteObject( t->hfont );
|
||||
msi_free( t );
|
||||
list_remove( &font->entry );
|
||||
DeleteObject( font->hfont );
|
||||
msi_free( font );
|
||||
}
|
||||
msi_free( dialog->default_font );
|
||||
|
||||
@@ -4022,11 +4032,11 @@ static UINT error_dialog_handler(MSIPACKAGE *package, LPCWSTR event,
|
||||
'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0
|
||||
};
|
||||
|
||||
if ( lstrcmpW( event, end_dialog ) )
|
||||
if ( strcmpW( event, end_dialog ) )
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
if ( !lstrcmpW( argument, error_abort ) || !lstrcmpW( argument, error_cancel ) ||
|
||||
!lstrcmpW( argument, error_no ) )
|
||||
if ( !strcmpW( argument, error_abort ) || !strcmpW( argument, error_cancel ) ||
|
||||
!strcmpW( argument, error_no ) )
|
||||
{
|
||||
msi_set_property( package->db, result_prop, error_abort );
|
||||
}
|
||||
@@ -4108,7 +4118,7 @@ UINT msi_spawn_error_dialog( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR er
|
||||
if ( r != ERROR_SUCCESS)
|
||||
r = ERROR_SUCCESS;
|
||||
|
||||
if ( !lstrcmpW( result, error_abort ) )
|
||||
if ( !strcmpW( result, error_abort ) )
|
||||
r = ERROR_FUNCTION_FAILED;
|
||||
|
||||
done:
|
||||
|
||||
+39
-52
@@ -90,22 +90,18 @@ static UINT event_do_dialog( MSIPACKAGE *package, LPCWSTR name, msi_dialog *pare
|
||||
static UINT ControlEvent_EndDialog(MSIPACKAGE* package, LPCWSTR argument,
|
||||
msi_dialog* dialog)
|
||||
{
|
||||
static const WCHAR szExit[] = {
|
||||
'E','x','i','t',0};
|
||||
static const WCHAR szRetry[] = {
|
||||
'R','e','t','r','y',0};
|
||||
static const WCHAR szIgnore[] = {
|
||||
'I','g','n','o','r','e',0};
|
||||
static const WCHAR szReturn[] = {
|
||||
'R','e','t','u','r','n',0};
|
||||
static const WCHAR szExit[] = {'E','x','i','t',0};
|
||||
static const WCHAR szRetry[] = {'R','e','t','r','y',0};
|
||||
static const WCHAR szIgnore[] = {'I','g','n','o','r','e',0};
|
||||
static const WCHAR szReturn[] = {'R','e','t','u','r','n',0};
|
||||
|
||||
if (lstrcmpW(argument,szExit)==0)
|
||||
if (!strcmpW( argument, szExit ))
|
||||
package->CurrentInstallState = ERROR_INSTALL_USEREXIT;
|
||||
else if (lstrcmpW(argument, szRetry) == 0)
|
||||
else if (!strcmpW( argument, szRetry ))
|
||||
package->CurrentInstallState = ERROR_INSTALL_SUSPEND;
|
||||
else if (lstrcmpW(argument, szIgnore) == 0)
|
||||
else if (!strcmpW( argument, szIgnore ))
|
||||
package->CurrentInstallState = ERROR_SUCCESS;
|
||||
else if (lstrcmpW(argument, szReturn) == 0)
|
||||
else if (!strcmpW( argument, szReturn ))
|
||||
{
|
||||
msi_dialog *parent = msi_dialog_get_parent(dialog);
|
||||
msi_free(package->next_dialog);
|
||||
@@ -167,58 +163,50 @@ static UINT ControlEvent_DoAction(MSIPACKAGE* package, LPCWSTR argument,
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ControlEvent_AddLocal(MSIPACKAGE* package, LPCWSTR argument,
|
||||
msi_dialog* dialog)
|
||||
static UINT ControlEvent_AddLocal( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog )
|
||||
{
|
||||
MSIFEATURE *feature = NULL;
|
||||
MSIFEATURE *feature;
|
||||
|
||||
if (lstrcmpW(szAll,argument))
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
MSI_SetFeatureStateW(package,argument,INSTALLSTATE_LOCAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL);
|
||||
|
||||
ACTION_UpdateComponentStates(package,argument);
|
||||
if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
|
||||
{
|
||||
if (feature->ActionRequest != INSTALLSTATE_LOCAL)
|
||||
msi_set_property( package->db, szPreselected, szOne );
|
||||
MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_LOCAL );
|
||||
}
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ControlEvent_Remove(MSIPACKAGE* package, LPCWSTR argument,
|
||||
msi_dialog* dialog)
|
||||
static UINT ControlEvent_Remove( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog )
|
||||
{
|
||||
MSIFEATURE *feature = NULL;
|
||||
MSIFEATURE *feature;
|
||||
|
||||
if (lstrcmpW(szAll,argument))
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
MSI_SetFeatureStateW(package,argument,INSTALLSTATE_ABSENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
msi_feature_set_state(package, feature, INSTALLSTATE_ABSENT);
|
||||
|
||||
ACTION_UpdateComponentStates(package,argument);
|
||||
if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
|
||||
{
|
||||
if (feature->ActionRequest != INSTALLSTATE_ABSENT)
|
||||
msi_set_property( package->db, szPreselected, szOne );
|
||||
MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_ABSENT );
|
||||
}
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument,
|
||||
msi_dialog* dialog)
|
||||
static UINT ControlEvent_AddSource( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog )
|
||||
{
|
||||
MSIFEATURE *feature = NULL;
|
||||
MSIFEATURE *feature;
|
||||
|
||||
if (lstrcmpW(szAll,argument))
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
MSI_SetFeatureStateW(package,argument,INSTALLSTATE_SOURCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE);
|
||||
ACTION_UpdateComponentStates(package,argument);
|
||||
if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
|
||||
{
|
||||
if (feature->ActionRequest != INSTALLSTATE_SOURCE)
|
||||
msi_set_property( package->db, szPreselected, szOne );
|
||||
MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_SOURCE );
|
||||
}
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@@ -284,10 +272,9 @@ VOID ControlEvent_FireSubscribedEvent( MSIPACKAGE *package, LPCWSTR event,
|
||||
|
||||
LIST_FOR_EACH_ENTRY( sub, &package->subscriptions, struct subscriber, entry )
|
||||
{
|
||||
if (lstrcmpiW(sub->event, event))
|
||||
if (strcmpiW( sub->event, event ))
|
||||
continue;
|
||||
msi_dialog_handle_event( sub->dialog, sub->control,
|
||||
sub->attribute, rec );
|
||||
msi_dialog_handle_event( sub->dialog, sub->control, sub->attribute, rec );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +287,7 @@ VOID ControlEvent_CleanupDialogSubscriptions(MSIPACKAGE *package, LPWSTR dialog)
|
||||
{
|
||||
sub = LIST_ENTRY( i, struct subscriber, entry );
|
||||
|
||||
if ( lstrcmpW( msi_dialog_get_name( sub->dialog ), dialog ))
|
||||
if (strcmpW( msi_dialog_get_name( sub->dialog ), dialog ))
|
||||
continue;
|
||||
|
||||
list_remove( &sub->entry );
|
||||
@@ -441,7 +428,7 @@ UINT ControlEvent_HandleControlEvent(MSIPACKAGE *package, LPCWSTR event,
|
||||
while( Events[i].event != NULL)
|
||||
{
|
||||
LPWSTR wevent = strdupAtoW(Events[i].event);
|
||||
if (lstrcmpW(wevent,event)==0)
|
||||
if (!strcmpW( wevent, event ))
|
||||
{
|
||||
msi_free(wevent);
|
||||
rc = Events[i].handler(package,argument,dialog);
|
||||
|
||||
+204
-67
@@ -60,21 +60,98 @@ static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *ac
|
||||
ui_progress( package, 2, f->FileSize, 0, 0 );
|
||||
}
|
||||
|
||||
static msi_file_state calculate_install_state( MSIFILE *file )
|
||||
{
|
||||
MSICOMPONENT *comp = file->Component;
|
||||
VS_FIXEDFILEINFO *file_version;
|
||||
WCHAR *font_version;
|
||||
msi_file_state state;
|
||||
DWORD file_size;
|
||||
|
||||
if (comp->ActionRequest != INSTALLSTATE_LOCAL || !comp->Enabled ||
|
||||
(comp->assembly && comp->assembly->installed))
|
||||
{
|
||||
TRACE("file %s is not scheduled for install\n", debugstr_w(file->File));
|
||||
return msifs_skipped;
|
||||
}
|
||||
if ((comp->assembly && !comp->assembly->application && !comp->assembly->installed) ||
|
||||
GetFileAttributesW( file->TargetPath ) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
TRACE("file %s is missing\n", debugstr_w(file->File));
|
||||
return msifs_missing;
|
||||
}
|
||||
if (file->Version)
|
||||
{
|
||||
if ((file_version = msi_get_disk_file_version( file->TargetPath )))
|
||||
{
|
||||
TRACE("new %s old %u.%u.%u.%u\n", debugstr_w(file->Version),
|
||||
HIWORD(file_version->dwFileVersionMS),
|
||||
LOWORD(file_version->dwFileVersionMS),
|
||||
HIWORD(file_version->dwFileVersionLS),
|
||||
LOWORD(file_version->dwFileVersionLS));
|
||||
|
||||
if (msi_compare_file_versions( file_version, file->Version ) < 0)
|
||||
state = msifs_overwrite;
|
||||
else
|
||||
{
|
||||
TRACE("destination file version equal or greater, not overwriting\n");
|
||||
state = msifs_present;
|
||||
}
|
||||
msi_free( file_version );
|
||||
return state;
|
||||
}
|
||||
else if ((font_version = font_version_from_file( file->TargetPath )))
|
||||
{
|
||||
TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(font_version));
|
||||
|
||||
if (msi_compare_font_versions( font_version, file->Version ) < 0)
|
||||
state = msifs_overwrite;
|
||||
else
|
||||
{
|
||||
TRACE("destination file version equal or greater, not overwriting\n");
|
||||
state = msifs_present;
|
||||
}
|
||||
msi_free( font_version );
|
||||
return state;
|
||||
}
|
||||
}
|
||||
if ((file_size = msi_get_disk_file_size( file->TargetPath )) != file->FileSize)
|
||||
{
|
||||
return msifs_overwrite;
|
||||
}
|
||||
if (file->hash.dwFileHashInfoSize)
|
||||
{
|
||||
if (msi_file_hash_matches( file ))
|
||||
{
|
||||
TRACE("file hashes match, not overwriting\n");
|
||||
return msifs_hashmatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("file hashes do not match, overwriting\n");
|
||||
return msifs_overwrite;
|
||||
}
|
||||
}
|
||||
/* assume present */
|
||||
return msifs_present;
|
||||
}
|
||||
|
||||
static void schedule_install_files(MSIPACKAGE *package)
|
||||
{
|
||||
MSIFILE *file;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry)
|
||||
{
|
||||
if (file->Component->ActionRequest != INSTALLSTATE_LOCAL || !file->Component->Enabled)
|
||||
{
|
||||
TRACE("File %s is not scheduled for install\n", debugstr_w(file->File));
|
||||
MSICOMPONENT *comp = file->Component;
|
||||
|
||||
ui_progress(package,2,file->FileSize,0,0);
|
||||
file->state = calculate_install_state( file );
|
||||
if (file->state == msifs_overwrite && (comp->Attributes & msidbComponentAttributesNeverOverwrite))
|
||||
{
|
||||
TRACE("not overwriting %s\n", debugstr_w(file->TargetPath));
|
||||
file->state = msifs_skipped;
|
||||
}
|
||||
else
|
||||
file->Component->Action = INSTALLSTATE_LOCAL;
|
||||
comp->Action = INSTALLSTATE_LOCAL;
|
||||
ui_progress( package, 2, file->FileSize, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +231,7 @@ static UINT msi_create_directory( MSIPACKAGE *package, const WCHAR *dir )
|
||||
MSIFOLDER *folder;
|
||||
WCHAR *install_path;
|
||||
|
||||
install_path = resolve_folder( package, dir, FALSE, FALSE, TRUE, &folder );
|
||||
install_path = resolve_target_folder( package, dir, FALSE, TRUE, &folder );
|
||||
if (!install_path)
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
@@ -178,7 +255,7 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
|
||||
f = get_loaded_file(package, file);
|
||||
if (!f)
|
||||
{
|
||||
WARN("unknown file in cabinet (%s)\n", debugstr_w(file));
|
||||
TRACE("unknown file in cabinet (%s)\n", debugstr_w(file));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -186,8 +263,10 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
|
||||
return FALSE;
|
||||
|
||||
msi_file_update_ui(package, f, szInstallFiles);
|
||||
msi_create_directory(package, f->Component->Directory);
|
||||
|
||||
if (!f->Component->assembly || f->Component->assembly->application)
|
||||
{
|
||||
msi_create_directory(package, f->Component->Directory);
|
||||
}
|
||||
*path = strdupW(f->TargetPath);
|
||||
*attrs = f->Attributes;
|
||||
}
|
||||
@@ -210,6 +289,7 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
|
||||
UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
||||
{
|
||||
MSIMEDIAINFO *mi;
|
||||
MSICOMPONENT *comp;
|
||||
UINT rc = ERROR_SUCCESS;
|
||||
MSIFILE *file;
|
||||
|
||||
@@ -222,6 +302,20 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
||||
|
||||
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
|
||||
{
|
||||
rc = msi_load_media_info( package, file, mi );
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("Unable to load media info for %s (%u)\n", debugstr_w(file->File), rc);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
if (!file->Component->Enabled) continue;
|
||||
|
||||
if (file->state != msifs_hashmatch && (rc = ready_media( package, file, mi )))
|
||||
{
|
||||
ERR("Failed to ready media for %s\n", debugstr_w(file->File));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (file->state != msifs_missing && !mi->is_continuous && file->state != msifs_overwrite)
|
||||
continue;
|
||||
|
||||
@@ -230,13 +324,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
||||
{
|
||||
MSICABDATA data;
|
||||
|
||||
rc = ready_media(package, file, mi);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("Failed to ready media for %s\n", debugstr_w(file->File));
|
||||
break;
|
||||
}
|
||||
|
||||
data.mi = mi;
|
||||
data.package = package;
|
||||
data.cb = installfiles_cb;
|
||||
@@ -247,7 +334,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
||||
{
|
||||
ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet));
|
||||
rc = ERROR_INSTALL_FAILURE;
|
||||
break;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,12 +342,13 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
||||
{
|
||||
LPWSTR source = resolve_file_source(package, file);
|
||||
|
||||
TRACE("file paths %s to %s\n", debugstr_w(source),
|
||||
debugstr_w(file->TargetPath));
|
||||
TRACE("copying %s to %s\n", debugstr_w(source), debugstr_w(file->TargetPath));
|
||||
|
||||
msi_file_update_ui(package, file, szInstallFiles);
|
||||
msi_create_directory(package, file->Component->Directory);
|
||||
|
||||
if (!file->Component->assembly || file->Component->assembly->application)
|
||||
{
|
||||
msi_create_directory(package, file->Component->Directory);
|
||||
}
|
||||
rc = copy_install_file(package, file, source);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
@@ -268,19 +356,33 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
||||
debugstr_w(file->TargetPath), rc);
|
||||
rc = ERROR_INSTALL_FAILURE;
|
||||
msi_free(source);
|
||||
break;
|
||||
goto done;
|
||||
}
|
||||
|
||||
msi_free(source);
|
||||
}
|
||||
else if (file->state != msifs_installed)
|
||||
{
|
||||
ERR("compressed file wasn't installed (%s)\n", debugstr_w(file->TargetPath));
|
||||
rc = ERROR_INSTALL_FAILURE;
|
||||
break;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
|
||||
{
|
||||
if (comp->ActionRequest == INSTALLSTATE_LOCAL && comp->Enabled &&
|
||||
comp->assembly && !comp->assembly->installed)
|
||||
{
|
||||
rc = install_assembly( package, comp );
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("Failed to install assembly\n");
|
||||
rc = ERROR_INSTALL_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
msi_free_media_info(mi);
|
||||
return rc;
|
||||
}
|
||||
@@ -406,7 +508,7 @@ static BOOL add_wildcard(FILE_LIST *files, LPWSTR source, LPWSTR dest)
|
||||
|
||||
LIST_FOR_EACH_ENTRY(file, &files->entry, FILE_LIST, entry)
|
||||
{
|
||||
if (lstrcmpW(source, file->source) < 0)
|
||||
if (strcmpW( source, file->source ) < 0)
|
||||
{
|
||||
list_add_before(&file->entry, &new->entry);
|
||||
return TRUE;
|
||||
@@ -663,7 +765,7 @@ static WCHAR *get_duplicate_filename( MSIPACKAGE *package, MSIRECORD *row, const
|
||||
{
|
||||
const WCHAR *dst_key = MSI_RecordGetString( row, 5 );
|
||||
|
||||
dst_path = resolve_folder( package, dst_key, FALSE, FALSE, TRUE, NULL );
|
||||
dst_path = resolve_target_folder( package, dst_key, FALSE, TRUE, NULL );
|
||||
if (!dst_path)
|
||||
{
|
||||
/* try a property */
|
||||
@@ -861,25 +963,25 @@ static BOOL verify_comp_for_removal(MSICOMPONENT *comp, UINT install_mode)
|
||||
{
|
||||
INSTALLSTATE request = comp->ActionRequest;
|
||||
|
||||
if (request == INSTALLSTATE_UNKNOWN)
|
||||
return FALSE;
|
||||
/* special case */
|
||||
if (request != INSTALLSTATE_SOURCE &&
|
||||
comp->Attributes & msidbComponentAttributesSourceOnly &&
|
||||
(install_mode == msidbRemoveFileInstallModeOnRemove ||
|
||||
install_mode == msidbRemoveFileInstallModeOnBoth)) return TRUE;
|
||||
|
||||
if (install_mode == msidbRemoveFileInstallModeOnInstall &&
|
||||
(request == INSTALLSTATE_LOCAL || request == INSTALLSTATE_SOURCE))
|
||||
return TRUE;
|
||||
|
||||
if (request == INSTALLSTATE_ABSENT)
|
||||
switch (request)
|
||||
{
|
||||
if (!comp->ComponentId)
|
||||
return FALSE;
|
||||
|
||||
if (install_mode == msidbRemoveFileInstallModeOnRemove)
|
||||
return TRUE;
|
||||
case INSTALLSTATE_LOCAL:
|
||||
case INSTALLSTATE_SOURCE:
|
||||
if (install_mode == msidbRemoveFileInstallModeOnInstall ||
|
||||
install_mode == msidbRemoveFileInstallModeOnBoth) return TRUE;
|
||||
break;
|
||||
case INSTALLSTATE_ABSENT:
|
||||
if (install_mode == msidbRemoveFileInstallModeOnRemove ||
|
||||
install_mode == msidbRemoveFileInstallModeOnBoth) return TRUE;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (install_mode == msidbRemoveFileInstallModeOnBoth)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -888,24 +990,17 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param)
|
||||
MSIPACKAGE *package = param;
|
||||
MSICOMPONENT *comp;
|
||||
MSIRECORD *uirow;
|
||||
LPCWSTR component, filename, dirprop;
|
||||
LPCWSTR component, dirprop;
|
||||
UINT install_mode;
|
||||
LPWSTR dir = NULL, path = NULL;
|
||||
LPWSTR dir = NULL, path = NULL, filename = NULL;
|
||||
DWORD size;
|
||||
UINT ret = ERROR_SUCCESS;
|
||||
|
||||
component = MSI_RecordGetString(row, 2);
|
||||
filename = MSI_RecordGetString(row, 3);
|
||||
dirprop = MSI_RecordGetString(row, 4);
|
||||
install_mode = MSI_RecordGetInteger(row, 5);
|
||||
|
||||
comp = get_loaded_component(package, component);
|
||||
if (!comp)
|
||||
{
|
||||
ERR("Invalid component: %s\n", debugstr_w(component));
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
if (!comp->Enabled)
|
||||
{
|
||||
TRACE("component is disabled\n");
|
||||
@@ -914,16 +1009,27 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param)
|
||||
|
||||
if (!verify_comp_for_removal(comp, install_mode))
|
||||
{
|
||||
TRACE("Skipping removal due to missing conditions\n");
|
||||
TRACE("Skipping removal due to install mode\n");
|
||||
comp->Action = comp->Installed;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
if (comp->Attributes & msidbComponentAttributesPermanent)
|
||||
{
|
||||
TRACE("permanent component, not removing file\n");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
dir = msi_dup_property(package->db, dirprop);
|
||||
if (!dir)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
size = (filename != NULL) ? lstrlenW(filename) : 0;
|
||||
size = 0;
|
||||
if ((filename = strdupW( MSI_RecordGetString(row, 3) )))
|
||||
{
|
||||
reduce_to_longfilename( filename );
|
||||
size = lstrlenW( filename );
|
||||
}
|
||||
size += lstrlenW(dir) + 2;
|
||||
path = msi_alloc(size * sizeof(WCHAR));
|
||||
if (!path)
|
||||
@@ -954,11 +1060,39 @@ done:
|
||||
ui_actiondata( package, szRemoveFiles, uirow );
|
||||
msiobj_release( &uirow->hdr );
|
||||
|
||||
msi_free(filename);
|
||||
msi_free(path);
|
||||
msi_free(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL has_persistent_dir( MSIPACKAGE *package, MSICOMPONENT *comp )
|
||||
{
|
||||
MSIQUERY *view;
|
||||
UINT r = ERROR_FUNCTION_FAILED;
|
||||
|
||||
static const WCHAR query[] = {
|
||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','C','r','e','a','t','e','F','o','l','d','e','r','`',' ','W','H','E','R','E',' ',
|
||||
'`','C','o','m','p','o','n','e','n','t','_','`',' ','=','\'','%','s','\'',' ','A','N','D',' ',
|
||||
'`','D','i','r','e','c','t','o','r','y','_','`',' ','=','\'','%','s','\'',0};
|
||||
|
||||
if (!MSI_OpenQuery( package->db, &view, query, comp->Component, comp->Directory ))
|
||||
{
|
||||
if (!MSI_ViewExecute( view, NULL ))
|
||||
{
|
||||
MSIRECORD *rec;
|
||||
if (!(r = MSI_ViewFetch( view, &rec )))
|
||||
{
|
||||
TRACE("directory %s is persistent\n", debugstr_w(comp->Directory));
|
||||
msiobj_release( &rec->hdr );
|
||||
}
|
||||
}
|
||||
msiobj_release( &view->hdr );
|
||||
}
|
||||
return (r == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
||||
{
|
||||
MSIQUERY *view;
|
||||
@@ -968,9 +1102,6 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
||||
static const WCHAR query[] = {
|
||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','R','e','m','o','v','e','F','i','l','e','`',0};
|
||||
static const WCHAR folder_query[] = {
|
||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
'`','C','r','e','a','t','e','F','o','l','d','e','r','`',0};
|
||||
|
||||
r = MSI_DatabaseOpenViewW(package->db, query, &view);
|
||||
if (r == ERROR_SUCCESS)
|
||||
@@ -979,10 +1110,6 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
||||
msiobj_release(&view->hdr);
|
||||
}
|
||||
|
||||
r = MSI_DatabaseOpenViewW(package->db, folder_query, &view);
|
||||
if (r == ERROR_SUCCESS)
|
||||
msiobj_release(&view->hdr);
|
||||
|
||||
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
|
||||
{
|
||||
MSIRECORD *uirow;
|
||||
@@ -1002,6 +1129,12 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file->Component->Attributes & msidbComponentAttributesPermanent)
|
||||
{
|
||||
TRACE("permanent component, not removing file\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file->Version)
|
||||
{
|
||||
ver = msi_get_disk_file_version( file->TargetPath );
|
||||
@@ -1015,16 +1148,20 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
||||
}
|
||||
|
||||
TRACE("removing %s\n", debugstr_w(file->File) );
|
||||
|
||||
SetFileAttributesW( file->TargetPath, FILE_ATTRIBUTE_NORMAL );
|
||||
if (!DeleteFileW( file->TargetPath ))
|
||||
{
|
||||
WARN("failed to delete %s\n", debugstr_w(file->TargetPath));
|
||||
WARN("failed to delete %s (%u)\n", debugstr_w(file->TargetPath), GetLastError());
|
||||
}
|
||||
/* FIXME: check persistence for each directory */
|
||||
else if (r && (dir = strdupW( file->TargetPath )))
|
||||
else if (!has_persistent_dir( package, file->Component ))
|
||||
{
|
||||
if ((p = strrchrW( dir, '\\' ))) *p = 0;
|
||||
RemoveDirectoryW( dir );
|
||||
msi_free( dir );
|
||||
if ((dir = strdupW( file->TargetPath )))
|
||||
{
|
||||
if ((p = strrchrW( dir, '\\' ))) *p = 0;
|
||||
RemoveDirectoryW( dir );
|
||||
msi_free( dir );
|
||||
}
|
||||
}
|
||||
file->state = msifs_missing;
|
||||
|
||||
|
||||
+39
-16
@@ -52,6 +52,9 @@ typedef struct _tagTT_NAME_TABLE_HEADER {
|
||||
* from start of the table */
|
||||
} TT_NAME_TABLE_HEADER;
|
||||
|
||||
#define NAME_ID_FULL_FONT_NAME 4
|
||||
#define NAME_ID_VERSION 5
|
||||
|
||||
typedef struct _tagTT_NAME_RECORD {
|
||||
USHORT uPlatformID;
|
||||
USHORT uEncodingID;
|
||||
@@ -80,10 +83,8 @@ static const WCHAR regfont2[] =
|
||||
/*
|
||||
* Code based off of code located here
|
||||
* http://www.codeproject.com/gdi/fontnamefromfile.asp
|
||||
*
|
||||
* Using string index 4 (full font name) instead of 1 (family name)
|
||||
*/
|
||||
static LPWSTR load_ttfname_from(LPCWSTR filename)
|
||||
WCHAR *load_ttf_name_id( const WCHAR *filename, DWORD id )
|
||||
{
|
||||
TT_TABLE_DIRECTORY tblDir;
|
||||
BOOL bFound = FALSE;
|
||||
@@ -142,30 +143,24 @@ static LPWSTR load_ttfname_from(LPCWSTR filename)
|
||||
break;
|
||||
|
||||
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
|
||||
/* 4 is the Full Font Name */
|
||||
if(ttRecord.uNameID == 4)
|
||||
if (ttRecord.uNameID == id)
|
||||
{
|
||||
int nPos;
|
||||
LPSTR buf;
|
||||
static const char tt[] = " (TrueType)";
|
||||
|
||||
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
|
||||
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
|
||||
nPos = SetFilePointer(handle, 0, NULL, FILE_CURRENT);
|
||||
SetFilePointer(handle, tblDir.uOffset +
|
||||
ttRecord.uStringOffset +
|
||||
ttNTHeader.uStorageOffset,
|
||||
NULL, FILE_BEGIN);
|
||||
buf = msi_alloc_zero( ttRecord.uStringLength + 1 + strlen(tt) );
|
||||
SetFilePointer(handle, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset,
|
||||
NULL, FILE_BEGIN);
|
||||
buf = msi_alloc_zero( ttRecord.uStringLength + 1 );
|
||||
ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL);
|
||||
if (strlen(buf) > 0)
|
||||
{
|
||||
strcat(buf,tt);
|
||||
ret = strdupAtoW(buf);
|
||||
msi_free(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
msi_free(buf);
|
||||
SetFilePointer(handle,nPos, NULL, FILE_BEGIN);
|
||||
}
|
||||
@@ -173,8 +168,36 @@ static LPWSTR load_ttfname_from(LPCWSTR filename)
|
||||
|
||||
end:
|
||||
CloseHandle(handle);
|
||||
TRACE("Returning %s\n", debugstr_w(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
TRACE("Returning fontname %s\n",debugstr_w(ret));
|
||||
static WCHAR *font_name_from_file( const WCHAR *filename )
|
||||
{
|
||||
static const WCHAR truetypeW[] = {' ','(','T','r','u','e','T','y','p','e',')',0};
|
||||
WCHAR *name, *ret = NULL;
|
||||
|
||||
if ((name = load_ttf_name_id( filename, NAME_ID_FULL_FONT_NAME )))
|
||||
{
|
||||
ret = msi_alloc( (strlenW( name ) + strlenW( truetypeW ) + 1 ) * sizeof(WCHAR) );
|
||||
strcpyW( ret, name );
|
||||
strcatW( ret, truetypeW );
|
||||
msi_free( name );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WCHAR *font_version_from_file( const WCHAR *filename )
|
||||
{
|
||||
WCHAR *version, *p, *ret = NULL;
|
||||
|
||||
if ((p = version = load_ttf_name_id( filename, NAME_ID_VERSION )))
|
||||
{
|
||||
while (*p && !isdigitW( *p )) p++;
|
||||
ret = msi_alloc( (strlenW( p ) + 1) * sizeof(WCHAR) );
|
||||
strcpyW( ret, p );
|
||||
msi_free( version );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -212,7 +235,7 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
|
||||
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2);
|
||||
|
||||
if (MSI_RecordIsNull(row,2))
|
||||
name = load_ttfname_from( file->TargetPath );
|
||||
name = font_name_from_file( file->TargetPath );
|
||||
else
|
||||
name = msi_dup_record_field(row,2);
|
||||
|
||||
@@ -296,7 +319,7 @@ static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param )
|
||||
RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 );
|
||||
|
||||
if (MSI_RecordIsNull( row, 2 ))
|
||||
name = load_ttfname_from( file->TargetPath );
|
||||
name = font_name_from_file( file->TargetPath );
|
||||
else
|
||||
name = msi_dup_record_field( row, 2 );
|
||||
|
||||
|
||||
@@ -185,7 +185,6 @@ static LPWSTR deformat_component(FORMAT *format, FORMSTR *str)
|
||||
{
|
||||
LPWSTR key, ret = NULL;
|
||||
MSICOMPONENT *comp;
|
||||
BOOL source;
|
||||
|
||||
key = msi_alloc((str->len + 1) * sizeof(WCHAR));
|
||||
lstrcpynW(key, get_formstr_data(format, str), str->len + 1);
|
||||
@@ -194,8 +193,10 @@ static LPWSTR deformat_component(FORMAT *format, FORMSTR *str)
|
||||
if (!comp)
|
||||
goto done;
|
||||
|
||||
source = (comp->Action == INSTALLSTATE_SOURCE) ? TRUE : FALSE;
|
||||
ret = resolve_folder(format->package, comp->Directory, source, FALSE, TRUE, NULL);
|
||||
if (comp->Action == INSTALLSTATE_SOURCE)
|
||||
ret = resolve_source_folder( format->package, comp->Directory, NULL );
|
||||
else
|
||||
ret = resolve_target_folder( format->package, comp->Directory, FALSE, TRUE, NULL );
|
||||
|
||||
done:
|
||||
msi_free(key);
|
||||
|
||||
+108
-81
@@ -104,7 +104,7 @@ MSICOMPONENT* get_loaded_component( MSIPACKAGE* package, LPCWSTR Component )
|
||||
|
||||
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
|
||||
{
|
||||
if (lstrcmpW(Component,comp->Component)==0)
|
||||
if (!strcmpW( Component, comp->Component ))
|
||||
return comp;
|
||||
}
|
||||
return NULL;
|
||||
@@ -116,7 +116,7 @@ MSIFEATURE* get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
|
||||
|
||||
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
if (lstrcmpW( Feature, feature->Feature )==0)
|
||||
if (!strcmpW( Feature, feature->Feature ))
|
||||
return feature;
|
||||
}
|
||||
return NULL;
|
||||
@@ -128,7 +128,7 @@ MSIFILE* get_loaded_file( MSIPACKAGE* package, LPCWSTR key )
|
||||
|
||||
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
|
||||
{
|
||||
if (lstrcmpW( key, file->File )==0)
|
||||
if (!strcmpW( key, file->File ))
|
||||
return file;
|
||||
}
|
||||
return NULL;
|
||||
@@ -141,7 +141,7 @@ int track_tempfile( MSIPACKAGE *package, LPCWSTR path )
|
||||
TRACE("%s\n", debugstr_w(path));
|
||||
|
||||
LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry )
|
||||
if (!lstrcmpW( path, temp->Path ))
|
||||
if (!strcmpW( path, temp->Path ))
|
||||
return 0;
|
||||
|
||||
temp = msi_alloc_zero( sizeof (MSITEMPFILE) );
|
||||
@@ -160,7 +160,7 @@ MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir )
|
||||
|
||||
LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
|
||||
{
|
||||
if (lstrcmpW( dir, folder->Directory )==0)
|
||||
if (!strcmpW( dir, folder->Directory ))
|
||||
return folder;
|
||||
}
|
||||
return NULL;
|
||||
@@ -232,8 +232,7 @@ LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file)
|
||||
if (file->IsCompressed)
|
||||
return NULL;
|
||||
|
||||
p = resolve_folder(package, file->Component->Directory,
|
||||
TRUE, FALSE, TRUE, NULL);
|
||||
p = resolve_source_folder( package, file->Component->Directory, NULL );
|
||||
path = build_directory_name(2, p, file->ShortName);
|
||||
|
||||
if (file->LongName &&
|
||||
@@ -245,24 +244,18 @@ LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file)
|
||||
|
||||
msi_free(p);
|
||||
|
||||
TRACE("file %s source resolves to %s\n", debugstr_w(file->File),
|
||||
debugstr_w(path));
|
||||
|
||||
TRACE("file %s source resolves to %s\n", debugstr_w(file->File), debugstr_w(path));
|
||||
return path;
|
||||
}
|
||||
|
||||
LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
||||
BOOL set_prop, BOOL load_prop, MSIFOLDER **folder)
|
||||
LPWSTR resolve_source_folder( MSIPACKAGE *package, LPCWSTR name, MSIFOLDER **folder )
|
||||
{
|
||||
MSIFOLDER *f;
|
||||
LPWSTR p, path = NULL, parent;
|
||||
|
||||
TRACE("Working to resolve %s\n",debugstr_w(name));
|
||||
TRACE("working to resolve %s\n", debugstr_w(name));
|
||||
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
if (!lstrcmpW(name,cszSourceDir))
|
||||
if (!strcmpW( name, cszSourceDir ))
|
||||
name = cszTargetDir;
|
||||
|
||||
f = get_loaded_folder( package, name );
|
||||
@@ -270,7 +263,58 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
||||
return NULL;
|
||||
|
||||
/* special resolving for Target and Source root dir */
|
||||
if (!strcmpW(name,cszTargetDir))
|
||||
if (!strcmpW( name, cszTargetDir ))
|
||||
{
|
||||
if (!f->ResolvedSource)
|
||||
f->ResolvedSource = get_source_root( package );
|
||||
}
|
||||
|
||||
if (folder)
|
||||
*folder = f;
|
||||
|
||||
if (f->ResolvedSource)
|
||||
{
|
||||
path = strdupW( f->ResolvedSource );
|
||||
TRACE(" already resolved to %s\n", debugstr_w(path));
|
||||
return path;
|
||||
}
|
||||
|
||||
if (!f->Parent)
|
||||
return path;
|
||||
|
||||
parent = f->Parent;
|
||||
TRACE(" ! parent is %s\n", debugstr_w(parent));
|
||||
|
||||
p = resolve_source_folder( package, parent, NULL );
|
||||
|
||||
if (package->WordCount & msidbSumInfoSourceTypeCompressed)
|
||||
path = get_source_root( package );
|
||||
else if (package->WordCount & msidbSumInfoSourceTypeSFN)
|
||||
path = build_directory_name( 3, p, f->SourceShortPath, NULL );
|
||||
else
|
||||
path = build_directory_name( 3, p, f->SourceLongPath, NULL );
|
||||
|
||||
TRACE("-> %s\n", debugstr_w(path));
|
||||
f->ResolvedSource = strdupW( path );
|
||||
msi_free( p );
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
LPWSTR resolve_target_folder( MSIPACKAGE *package, LPCWSTR name, BOOL set_prop, BOOL load_prop,
|
||||
MSIFOLDER **folder )
|
||||
{
|
||||
MSIFOLDER *f;
|
||||
LPWSTR p, path = NULL, parent;
|
||||
|
||||
TRACE("working to resolve %s\n", debugstr_w(name));
|
||||
|
||||
f = get_loaded_folder( package, name );
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
/* special resolving for Target and Source root dir */
|
||||
if (!strcmpW( name, cszTargetDir ))
|
||||
{
|
||||
if (!f->ResolvedTarget && !f->Property)
|
||||
{
|
||||
@@ -286,45 +330,33 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
||||
/* correct misbuilt target dir */
|
||||
path = build_directory_name(2, check_path, NULL);
|
||||
clean_spaces_from_path( path );
|
||||
if (strcmpiW(path,check_path)!=0)
|
||||
if (strcmpiW( path, check_path ))
|
||||
msi_set_property( package->db, cszTargetDir, path );
|
||||
msi_free(check_path);
|
||||
|
||||
f->ResolvedTarget = path;
|
||||
}
|
||||
|
||||
if (!f->ResolvedSource)
|
||||
f->ResolvedSource = get_source_root( package );
|
||||
}
|
||||
|
||||
if (folder)
|
||||
*folder = f;
|
||||
|
||||
if (!source && f->ResolvedTarget)
|
||||
if (f->ResolvedTarget)
|
||||
{
|
||||
path = strdupW( f->ResolvedTarget );
|
||||
TRACE(" already resolved to %s\n",debugstr_w(path));
|
||||
TRACE(" already resolved to %s\n", debugstr_w(path));
|
||||
return path;
|
||||
}
|
||||
|
||||
if (source && f->ResolvedSource)
|
||||
{
|
||||
path = strdupW( f->ResolvedSource );
|
||||
TRACE(" (source)already resolved to %s\n",debugstr_w(path));
|
||||
return path;
|
||||
}
|
||||
|
||||
if (!source && f->Property)
|
||||
if (f->Property)
|
||||
{
|
||||
path = build_directory_name( 2, f->Property, NULL );
|
||||
|
||||
TRACE(" internally set to %s\n",debugstr_w(path));
|
||||
if (set_prop)
|
||||
msi_set_property( package->db, name, path );
|
||||
TRACE(" internally set to %s\n", debugstr_w(path));
|
||||
if (set_prop) msi_set_property( package->db, name, path );
|
||||
return path;
|
||||
}
|
||||
|
||||
if (!source && load_prop && (path = msi_dup_property( package->db, name )))
|
||||
if (load_prop && (path = msi_dup_property( package->db, name )))
|
||||
{
|
||||
f->ResolvedTarget = strdupW( path );
|
||||
TRACE(" property set to %s\n", debugstr_w(path));
|
||||
@@ -336,35 +368,18 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
||||
|
||||
parent = f->Parent;
|
||||
|
||||
TRACE(" ! Parent is %s\n", debugstr_w(parent));
|
||||
TRACE(" ! parent is %s\n", debugstr_w(parent));
|
||||
|
||||
p = resolve_folder(package, parent, source, set_prop, load_prop, NULL);
|
||||
if (!source)
|
||||
{
|
||||
TRACE(" TargetDefault = %s\n", debugstr_w(f->TargetDefault));
|
||||
p = resolve_target_folder( package, parent, set_prop, load_prop, NULL );
|
||||
|
||||
path = build_directory_name( 3, p, f->TargetDefault, NULL );
|
||||
clean_spaces_from_path( path );
|
||||
f->ResolvedTarget = strdupW( path );
|
||||
TRACE("target -> %s\n", debugstr_w(path));
|
||||
if (set_prop)
|
||||
msi_set_property( package->db, name, path );
|
||||
}
|
||||
else
|
||||
{
|
||||
path = NULL;
|
||||
TRACE(" TargetDefault = %s\n", debugstr_w(f->TargetDefault));
|
||||
path = build_directory_name( 3, p, f->TargetDefault, NULL );
|
||||
clean_spaces_from_path( path );
|
||||
f->ResolvedTarget = strdupW( path );
|
||||
|
||||
if (package->WordCount & msidbSumInfoSourceTypeCompressed)
|
||||
path = get_source_root( package );
|
||||
else if (package->WordCount & msidbSumInfoSourceTypeSFN)
|
||||
path = build_directory_name( 3, p, f->SourceShortPath, NULL );
|
||||
else
|
||||
path = build_directory_name( 3, p, f->SourceLongPath, NULL );
|
||||
|
||||
TRACE("source -> %s\n", debugstr_w(path));
|
||||
f->ResolvedSource = strdupW( path );
|
||||
}
|
||||
msi_free(p);
|
||||
TRACE("-> %s\n", debugstr_w(path));
|
||||
if (set_prop) msi_set_property( package->db, name, path );
|
||||
msi_free( p );
|
||||
|
||||
return path;
|
||||
}
|
||||
@@ -479,6 +494,8 @@ LPWSTR build_directory_name(DWORD count, ...)
|
||||
if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')
|
||||
strcatW(dir, szBackSlash);
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
@@ -561,7 +578,7 @@ void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
|
||||
MSIRECORD * row = 0;
|
||||
DWORD size;
|
||||
|
||||
if (!package->LastAction || strcmpW(package->LastAction,action))
|
||||
if (!package->LastAction || strcmpW(package->LastAction, action))
|
||||
{
|
||||
row = MSI_QueryGetRecord(package->db, Query_t, action);
|
||||
if (!row)
|
||||
@@ -639,16 +656,11 @@ LPWSTR create_component_advertise_string(MSIPACKAGE* package,
|
||||
}
|
||||
|
||||
/* update component state based on a feature change */
|
||||
void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
|
||||
void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature )
|
||||
{
|
||||
INSTALLSTATE newstate;
|
||||
MSIFEATURE *feature;
|
||||
ComponentList *cl;
|
||||
|
||||
feature = get_loaded_feature(package,szFeature);
|
||||
if (!feature)
|
||||
return;
|
||||
|
||||
newstate = feature->ActionRequest;
|
||||
|
||||
if (newstate == INSTALLSTATE_ABSENT)
|
||||
@@ -658,15 +670,17 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
|
||||
{
|
||||
MSICOMPONENT* component = cl->component;
|
||||
|
||||
if (!component->Enabled) continue;
|
||||
|
||||
TRACE("MODIFYING(%i): Component %s (Installed %i, Action %i, Request %i)\n",
|
||||
newstate, debugstr_w(component->Component), component->Installed,
|
||||
component->Action, component->ActionRequest);
|
||||
|
||||
if (!component->Enabled)
|
||||
continue;
|
||||
|
||||
if (newstate == INSTALLSTATE_LOCAL)
|
||||
msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
|
||||
{
|
||||
component->Action = INSTALLSTATE_LOCAL;
|
||||
component->ActionRequest = INSTALLSTATE_LOCAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ComponentList *clist;
|
||||
@@ -674,9 +688,10 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
|
||||
|
||||
component->hasLocalFeature = FALSE;
|
||||
|
||||
msi_component_set_state(package, component, newstate);
|
||||
component->Action = newstate;
|
||||
component->ActionRequest = newstate;
|
||||
|
||||
/*if any other feature wants is local we need to set it local*/
|
||||
/* if any other feature wants it local we need to set it local */
|
||||
LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
if ( f->ActionRequest != INSTALLSTATE_LOCAL &&
|
||||
@@ -697,14 +712,26 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
|
||||
if (component->Attributes & msidbComponentAttributesOptional)
|
||||
{
|
||||
if (f->Attributes & msidbFeatureAttributesFavorSource)
|
||||
msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
|
||||
{
|
||||
component->Action = INSTALLSTATE_SOURCE;
|
||||
component->ActionRequest = INSTALLSTATE_SOURCE;
|
||||
}
|
||||
else
|
||||
msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
|
||||
{
|
||||
component->Action = INSTALLSTATE_LOCAL;
|
||||
component->ActionRequest = INSTALLSTATE_LOCAL;
|
||||
}
|
||||
}
|
||||
else if (component->Attributes & msidbComponentAttributesSourceOnly)
|
||||
msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
|
||||
{
|
||||
component->Action = INSTALLSTATE_SOURCE;
|
||||
component->ActionRequest = INSTALLSTATE_SOURCE;
|
||||
}
|
||||
else
|
||||
msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
|
||||
{
|
||||
component->Action = INSTALLSTATE_LOCAL;
|
||||
component->ActionRequest = INSTALLSTATE_LOCAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -747,7 +774,7 @@ BOOL check_unique_action(const MSIPACKAGE *package, LPCWSTR action)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < package->script->UniqueActionsCount; i++)
|
||||
if (!strcmpW(package->script->UniqueActions[i],action))
|
||||
if (!strcmpW(package->script->UniqueActions[i], action))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "msi.h"
|
||||
#include "msiquery.h"
|
||||
#include "objbase.h"
|
||||
@@ -117,7 +118,7 @@ static BOOL msi_columns_in_order(MSIINSERTVIEW *iv, UINT col_count)
|
||||
iv->sv->ops->get_column_info(iv->sv, i, &a, NULL, NULL, NULL);
|
||||
iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL, NULL);
|
||||
|
||||
res = lstrcmpW(a, b);
|
||||
res = strcmpW( a, b );
|
||||
msi_free(a);
|
||||
msi_free(b);
|
||||
|
||||
@@ -168,7 +169,7 @@ static UINT msi_arrange_record(MSIINSERTVIEW *iv, MSIRECORD **values)
|
||||
if (r != ERROR_SUCCESS)
|
||||
goto err;
|
||||
|
||||
res = lstrcmpW(a, b);
|
||||
res = strcmpW( a, b );
|
||||
msi_free(b);
|
||||
|
||||
if (res == 0)
|
||||
|
||||
+36
-22
@@ -282,7 +282,7 @@ done:
|
||||
return r;
|
||||
}
|
||||
|
||||
path = resolve_folder( package, szFolder, FALSE, FALSE, TRUE, NULL );
|
||||
path = resolve_target_folder( package, szFolder, FALSE, TRUE, NULL );
|
||||
msiobj_release( &package->hdr );
|
||||
|
||||
if (!path)
|
||||
@@ -336,7 +336,7 @@ UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MsiGetSourcePath (internal)
|
||||
* MSI_GetSourcePath (internal)
|
||||
*/
|
||||
static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
|
||||
awstring *szPathBuf, LPDWORD pcchPathBuf )
|
||||
@@ -413,10 +413,10 @@ done:
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
path = resolve_folder(package, szFolder, TRUE, FALSE, TRUE, NULL);
|
||||
path = resolve_source_folder( package, szFolder, NULL );
|
||||
msiobj_release( &package->hdr );
|
||||
|
||||
TRACE("path = %s\n",debugstr_w(path));
|
||||
TRACE("path = %s\n", debugstr_w(path));
|
||||
if (!path)
|
||||
return ERROR_DIRECTORY;
|
||||
|
||||
@@ -512,14 +512,14 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
|
||||
attrib & FILE_ATTRIBUTE_READONLY))
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
path = resolve_folder(package,szFolder,FALSE,FALSE,FALSE,&folder);
|
||||
path = resolve_target_folder( package, szFolder, FALSE, FALSE, &folder );
|
||||
if (!path)
|
||||
return ERROR_DIRECTORY;
|
||||
|
||||
msi_free(folder->Property);
|
||||
folder->Property = build_directory_name(2, szFolderPath, NULL);
|
||||
|
||||
if (lstrcmpiW(path, folder->Property) == 0)
|
||||
if (!strcmpiW( path, folder->Property ))
|
||||
{
|
||||
/*
|
||||
* Resolved Target has not really changed, so just
|
||||
@@ -527,7 +527,7 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
|
||||
*/
|
||||
msi_free(folder->ResolvedTarget);
|
||||
folder->ResolvedTarget = NULL;
|
||||
path2 = resolve_folder(package,szFolder,FALSE,TRUE,FALSE,NULL);
|
||||
path2 = resolve_target_folder( package, szFolder, TRUE, FALSE, NULL );
|
||||
msi_free(path2);
|
||||
}
|
||||
else
|
||||
@@ -542,23 +542,23 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
|
||||
|
||||
LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
|
||||
{
|
||||
path2 = resolve_folder(package, f->Directory, FALSE, TRUE, FALSE, NULL);
|
||||
path2 = resolve_target_folder( package, f->Directory, TRUE, FALSE, NULL );
|
||||
msi_free(path2);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
|
||||
{
|
||||
MSICOMPONENT *comp = file->Component;
|
||||
LPWSTR p;
|
||||
LPWSTR dir;
|
||||
|
||||
if (!comp)
|
||||
if (!comp->Enabled || (comp->assembly && !comp->assembly->application))
|
||||
continue;
|
||||
|
||||
p = resolve_folder(package, comp->Directory, FALSE, FALSE, FALSE, NULL);
|
||||
dir = resolve_target_folder( package, comp->Directory, FALSE, FALSE, NULL );
|
||||
msi_free(file->TargetPath);
|
||||
|
||||
file->TargetPath = build_directory_name(2, p, file->FileName);
|
||||
msi_free(p);
|
||||
file->TargetPath = build_directory_name(2, dir, file->FileName);
|
||||
msi_free(dir);
|
||||
}
|
||||
}
|
||||
msi_free(path);
|
||||
@@ -716,6 +716,10 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
|
||||
r = package->need_reboot;
|
||||
break;
|
||||
|
||||
case MSIRUNMODE_LOGENABLED:
|
||||
r = (package->log_file != INVALID_HANDLE_VALUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("unimplemented run mode: %d\n", iRunMode);
|
||||
r = TRUE;
|
||||
@@ -821,14 +825,14 @@ UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
|
||||
feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
msi_feature_set_state(package, feature, iState);
|
||||
feature->ActionRequest = iState;
|
||||
|
||||
ACTION_UpdateComponentStates(package,szFeature);
|
||||
ACTION_UpdateComponentStates( package, feature );
|
||||
|
||||
/* update all the features that are children of this feature */
|
||||
LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
|
||||
{
|
||||
if (lstrcmpW(szFeature, child->Feature_Parent) == 0)
|
||||
if (child->Feature_Parent && !strcmpW( szFeature, child->Feature_Parent ))
|
||||
MSI_SetFeatureStateW(package, child->Feature, iState);
|
||||
}
|
||||
|
||||
@@ -917,9 +921,9 @@ UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
|
||||
*piInstalled = feature->Installed;
|
||||
|
||||
if (piAction)
|
||||
*piAction = feature->Action;
|
||||
*piAction = feature->ActionRequest;
|
||||
|
||||
TRACE("returning %i %i\n", feature->Installed, feature->Action);
|
||||
TRACE("returning %i %i\n", feature->Installed, feature->ActionRequest);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@@ -1158,7 +1162,8 @@ static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
|
||||
if (!comp)
|
||||
return ERROR_UNKNOWN_COMPONENT;
|
||||
|
||||
comp->Installed = iState;
|
||||
if (comp->Enabled)
|
||||
comp->Action = iState;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@@ -1176,13 +1181,22 @@ UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
|
||||
return ERROR_UNKNOWN_COMPONENT;
|
||||
|
||||
if (piInstalled)
|
||||
*piInstalled = comp->Installed;
|
||||
{
|
||||
if (comp->Enabled)
|
||||
*piInstalled = comp->Installed;
|
||||
else
|
||||
*piInstalled = INSTALLSTATE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (piAction)
|
||||
*piAction = comp->Action;
|
||||
{
|
||||
if (comp->Enabled)
|
||||
*piAction = comp->Action;
|
||||
else
|
||||
*piAction = INSTALLSTATE_UNKNOWN;
|
||||
}
|
||||
|
||||
TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
+37
-23
@@ -68,7 +68,7 @@ static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return !lstrcmpW(mi->volume_label, volume_name);
|
||||
return !strcmpW( mi->volume_label, volume_name );
|
||||
}
|
||||
|
||||
static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
|
||||
@@ -331,7 +331,7 @@ static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (lstrcmpiW(mi->cabinet, cab))
|
||||
if (strcmpiW( mi->cabinet, cab ))
|
||||
{
|
||||
ERR("Continuous cabinet does not match the next cabinet in the Media table\n");
|
||||
goto done;
|
||||
@@ -656,7 +656,7 @@ static UINT get_drive_type(const WCHAR *path)
|
||||
return GetDriveTypeW(root);
|
||||
}
|
||||
|
||||
static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
|
||||
UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
|
||||
{
|
||||
MSIRECORD *row;
|
||||
LPWSTR source_dir;
|
||||
@@ -748,23 +748,44 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi)
|
||||
if (r != ERROR_SUCCESS)
|
||||
return r;
|
||||
|
||||
index = 0;
|
||||
volumesz = MAX_PATH;
|
||||
promptsz = MAX_PATH;
|
||||
|
||||
if (last_type[0] == 'n')
|
||||
{
|
||||
while (MsiSourceListEnumSourcesW(package->ProductCode, NULL,
|
||||
package->Context,
|
||||
MSISOURCETYPE_NETWORK, index++,
|
||||
volume, &volumesz) == ERROR_SUCCESS)
|
||||
WCHAR cabinet_file[MAX_PATH];
|
||||
BOOL check_all = FALSE;
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
if (!strncmpiW(source, volume, strlenW(source)))
|
||||
index = 0;
|
||||
volumesz = MAX_PATH;
|
||||
while (MsiSourceListEnumSourcesW(package->ProductCode, NULL,
|
||||
package->Context,
|
||||
MSISOURCETYPE_NETWORK, index++,
|
||||
volume, &volumesz) == ERROR_SUCCESS)
|
||||
{
|
||||
lstrcpyW(mi->sourcedir, source);
|
||||
TRACE("Found network source %s\n", debugstr_w(mi->sourcedir));
|
||||
return ERROR_SUCCESS;
|
||||
if (check_all || !strncmpiW(source, volume, strlenW(source)))
|
||||
{
|
||||
lstrcpyW(cabinet_file, volume);
|
||||
PathAddBackslashW(cabinet_file);
|
||||
lstrcatW(cabinet_file, mi->cabinet);
|
||||
|
||||
if (GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
volumesz = MAX_PATH;
|
||||
if(!check_all)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
lstrcpyW(mi->sourcedir, volume);
|
||||
TRACE("Found network source %s\n", debugstr_w(mi->sourcedir));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_all)
|
||||
check_all = TRUE;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,13 +824,6 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
|
||||
if (mi->is_continuous)
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
rc = msi_load_media_info(package, file, mi);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("Unable to load media info %u\n", rc);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
/* cabinet is internal, no checks needed */
|
||||
if (!mi->cabinet || mi->cabinet[0] == '#')
|
||||
return ERROR_SUCCESS;
|
||||
@@ -841,7 +855,7 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
|
||||
|
||||
/* check volume matches, change media if not */
|
||||
if (mi->volume_label && mi->disk_id > 1 &&
|
||||
lstrcmpW(mi->first_volume, mi->volume_label))
|
||||
strcmpW( mi->first_volume, mi->volume_label ))
|
||||
{
|
||||
LPWSTR source = msi_dup_property(package->db, cszSourceDir);
|
||||
BOOL matches;
|
||||
|
||||
+146
-107
@@ -299,13 +299,14 @@ done:
|
||||
return r;
|
||||
}
|
||||
|
||||
static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR **product_codes )
|
||||
|
||||
static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR ***product_codes )
|
||||
{
|
||||
MSIHANDLE patch, info = 0;
|
||||
UINT r, type;
|
||||
DWORD size;
|
||||
static WCHAR empty[] = {0};
|
||||
WCHAR *codes;
|
||||
WCHAR *codes = NULL;
|
||||
|
||||
r = MsiOpenDatabaseW( szPatchPackage, MSIDBOPEN_READONLY, &patch );
|
||||
if (r != ERROR_SUCCESS)
|
||||
@@ -332,26 +333,25 @@ static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR **product_cod
|
||||
}
|
||||
|
||||
r = MsiSummaryInfoGetPropertyW( info, PID_TEMPLATE, &type, NULL, NULL, codes, &size );
|
||||
if (r != ERROR_SUCCESS)
|
||||
msi_free( codes );
|
||||
else
|
||||
*product_codes = codes;
|
||||
if (r == ERROR_SUCCESS)
|
||||
*product_codes = msi_split_string( codes, ';' );
|
||||
|
||||
done:
|
||||
MsiCloseHandle( info );
|
||||
MsiCloseHandle( patch );
|
||||
msi_free( codes );
|
||||
return r;
|
||||
}
|
||||
|
||||
static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWSTR szCommandLine)
|
||||
{
|
||||
UINT r;
|
||||
UINT r, i;
|
||||
DWORD size;
|
||||
LPCWSTR cmd_ptr = szCommandLine;
|
||||
LPWSTR beg, end, cmd, codes = NULL;
|
||||
LPWSTR cmd, *codes = NULL;
|
||||
BOOL succeeded = FALSE;
|
||||
|
||||
static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
|
||||
static const WCHAR fmt[] = {'%','s',' ','P','A','T','C','H','=','"','%','s','"',0};
|
||||
static WCHAR empty[] = {0};
|
||||
|
||||
if (!szPatchPackage || !szPatchPackage[0])
|
||||
@@ -363,34 +363,27 @@ static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWS
|
||||
if (!szCommandLine)
|
||||
cmd_ptr = empty;
|
||||
|
||||
size = lstrlenW(cmd_ptr) + lstrlenW(patcheq) + lstrlenW(szPatchPackage) + 1;
|
||||
size = strlenW(cmd_ptr) + strlenW(fmt) + strlenW(szPatchPackage) + 1;
|
||||
cmd = msi_alloc(size * sizeof(WCHAR));
|
||||
if (!cmd)
|
||||
{
|
||||
msi_free(codes);
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
lstrcpyW(cmd, cmd_ptr);
|
||||
if (szCommandLine) lstrcatW(cmd, szSpace);
|
||||
lstrcatW(cmd, patcheq);
|
||||
lstrcatW(cmd, szPatchPackage);
|
||||
sprintfW(cmd, fmt, cmd_ptr, szPatchPackage);
|
||||
|
||||
if (szProductCode)
|
||||
r = MsiConfigureProductExW(szProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
|
||||
else
|
||||
{
|
||||
beg = codes;
|
||||
while ((end = strchrW(beg, '}')))
|
||||
for (i = 0; codes[i]; i++)
|
||||
{
|
||||
*(end + 1) = '\0';
|
||||
r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
|
||||
r = MsiConfigureProductExW(codes[i], INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
|
||||
if (r == ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("patch applied\n");
|
||||
succeeded = TRUE;
|
||||
}
|
||||
beg = end + 2;
|
||||
}
|
||||
|
||||
if (succeeded)
|
||||
@@ -688,6 +681,8 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
|
||||
|
||||
static const WCHAR szInstalled[] = {
|
||||
' ','I','n','s','t','a','l','l','e','d','=','1',0};
|
||||
static const WCHAR szInstallLevel[] = {
|
||||
' ','I','N','S','T','A','L','L','L','E','V','E','L','=','3','2','7','6','7',0};
|
||||
static const WCHAR szRemoveAll[] = {
|
||||
' ','R','E','M','O','V','E','=','A','L','L',0};
|
||||
static const WCHAR szMachine[] = {
|
||||
@@ -719,6 +714,9 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
|
||||
if (szCommandLine)
|
||||
sz += lstrlenW(szCommandLine);
|
||||
|
||||
if (eInstallState != INSTALLSTATE_DEFAULT)
|
||||
sz += lstrlenW(szInstallLevel);
|
||||
|
||||
if (eInstallState == INSTALLSTATE_ABSENT)
|
||||
sz += lstrlenW(szRemoveAll);
|
||||
|
||||
@@ -736,6 +734,9 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
|
||||
if (szCommandLine)
|
||||
lstrcpyW(commandline,szCommandLine);
|
||||
|
||||
if (eInstallState != INSTALLSTATE_DEFAULT)
|
||||
lstrcatW(commandline, szInstallLevel);
|
||||
|
||||
if (eInstallState == INSTALLSTATE_ABSENT)
|
||||
lstrcatW(commandline, szRemoveAll);
|
||||
|
||||
@@ -983,22 +984,22 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
|
||||
|
||||
MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
|
||||
|
||||
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLDATEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLSOURCEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_LOCALPACKAGEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PUBLISHERW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_URLINFOABOUTW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_URLUPDATEINFOW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMINORW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMAJORW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTIDW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_REGCOMPANYW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_REGOWNERW))
|
||||
if (!strcmpW( szAttribute, INSTALLPROPERTY_HELPLINKW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_HELPTELEPHONEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_INSTALLDATEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_INSTALLSOURCEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_LOCALPACKAGEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_PUBLISHERW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_URLINFOABOUTW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_URLUPDATEINFOW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_VERSIONMINORW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_VERSIONMAJORW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_PRODUCTIDW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_REGCOMPANYW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_REGOWNERW ))
|
||||
{
|
||||
if (!prodkey)
|
||||
{
|
||||
@@ -1009,25 +1010,25 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
|
||||
if (!userdata)
|
||||
return ERROR_UNKNOWN_PROPERTY;
|
||||
|
||||
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
|
||||
if (!strcmpW( szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ))
|
||||
szAttribute = display_name;
|
||||
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW))
|
||||
else if (!strcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
|
||||
szAttribute = display_version;
|
||||
|
||||
val = msi_reg_get_value(userdata, szAttribute, &type);
|
||||
if (!val)
|
||||
val = empty;
|
||||
}
|
||||
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTANCETYPEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_TRANSFORMSW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTICONW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW) ||
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
|
||||
else if (!strcmpW( szAttribute, INSTALLPROPERTY_INSTANCETYPEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_TRANSFORMSW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_LANGUAGEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_PRODUCTNAMEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_PACKAGECODEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_VERSIONW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_PRODUCTICONW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_PACKAGENAMEW ) ||
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW ))
|
||||
{
|
||||
if (!prodkey)
|
||||
{
|
||||
@@ -1035,10 +1036,10 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
|
||||
if (!strcmpW( szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW ))
|
||||
szAttribute = assignment;
|
||||
|
||||
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
|
||||
if (!strcmpW( szAttribute, INSTALLPROPERTY_PACKAGENAMEW ))
|
||||
{
|
||||
res = RegOpenKeyW(prodkey, sourcelist, &source);
|
||||
if (res != ERROR_SUCCESS)
|
||||
@@ -1061,7 +1062,7 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
|
||||
}
|
||||
|
||||
if (val != empty && type != REG_DWORD &&
|
||||
!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
|
||||
!strcmpW( szAttribute, INSTALLPROPERTY_PACKAGECODEW ))
|
||||
{
|
||||
if (lstrlenW(val) != SQUISH_GUID_SIZE - 1)
|
||||
badconfig = TRUE;
|
||||
@@ -1324,23 +1325,23 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!lstrcmpW(szProperty, INSTALLPROPERTY_HELPLINKW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_HELPTELEPHONEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLLOCATIONW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLSOURCEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_PUBLISHERW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_URLINFOABOUTW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_URLUPDATEINFOW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMINORW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMAJORW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTIDW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_REGCOMPANYW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_REGOWNERW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_INSTANCETYPEW))
|
||||
if (!strcmpW( szProperty, INSTALLPROPERTY_HELPLINKW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_HELPTELEPHONEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_INSTALLDATEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_INSTALLLOCATIONW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_INSTALLSOURCEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_LOCALPACKAGEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_PUBLISHERW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_URLINFOABOUTW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_URLUPDATEINFOW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_VERSIONMINORW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_VERSIONMAJORW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_VERSIONSTRINGW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_PRODUCTIDW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_REGCOMPANYW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_REGOWNERW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_INSTANCETYPEW ))
|
||||
{
|
||||
val = msi_reg_get_value(props, package, &type);
|
||||
if (!val)
|
||||
@@ -1353,9 +1354,9 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
|
||||
|
||||
msi_free(val);
|
||||
|
||||
if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
|
||||
if (!strcmpW( szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ))
|
||||
szProperty = displayname;
|
||||
else if (!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW))
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_VERSIONSTRINGW ))
|
||||
szProperty = displayversion;
|
||||
|
||||
val = msi_reg_get_value(props, szProperty, &type);
|
||||
@@ -1364,14 +1365,14 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
|
||||
|
||||
r = msi_copy_outval(val, szValue, pcchValue);
|
||||
}
|
||||
else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_TRANSFORMSW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_LANGUAGEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_PRODUCTNAMEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_PACKAGECODEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_VERSIONW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_PRODUCTICONW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_PACKAGENAMEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW ))
|
||||
{
|
||||
if (!prod && !classes)
|
||||
goto done;
|
||||
@@ -1389,7 +1390,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
|
||||
|
||||
r = msi_copy_outval(val, szValue, pcchValue);
|
||||
}
|
||||
else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW))
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_PRODUCTSTATEW ))
|
||||
{
|
||||
if (dwContext == MSIINSTALLCONTEXT_MACHINE)
|
||||
{
|
||||
@@ -1423,7 +1424,7 @@ UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
|
||||
|
||||
r = msi_copy_outval(val, szValue, pcchValue);
|
||||
}
|
||||
else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW ))
|
||||
{
|
||||
if (!prod && !classes)
|
||||
goto done;
|
||||
@@ -1554,7 +1555,7 @@ UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode,
|
||||
if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (!lstrcmpW(szUserSid, szLocalSid))
|
||||
if (szUserSid && !strcmpW( szUserSid, szLocalSid ))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (MSIREG_OpenUserDataProductKey(szProductCode, dwContext, NULL,
|
||||
@@ -1575,7 +1576,7 @@ UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode,
|
||||
if (res != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW))
|
||||
if (!strcmpW( szProperty, INSTALLPROPERTY_TRANSFORMSW ))
|
||||
{
|
||||
if (MSIREG_OpenProductKey(szProductCode, NULL, dwContext,
|
||||
&prod, FALSE) != ERROR_SUCCESS)
|
||||
@@ -1594,25 +1595,25 @@ UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode,
|
||||
&udpatch, FALSE) != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
|
||||
if (!strcmpW( szProperty, INSTALLPROPERTY_LOCALPACKAGEW ))
|
||||
{
|
||||
if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
|
||||
szProperty = szManagedPackage;
|
||||
datakey = udpatch;
|
||||
}
|
||||
else if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW))
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_INSTALLDATEW ))
|
||||
{
|
||||
datakey = patch;
|
||||
szProperty = szInstalled;
|
||||
}
|
||||
else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_LOCALPACKAGEW ))
|
||||
{
|
||||
datakey = udpatch;
|
||||
}
|
||||
else if (!lstrcmpW(szProperty, INSTALLPROPERTY_UNINSTALLABLEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_PATCHSTATEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_DISPLAYNAMEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_MOREINFOURLW))
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_UNINSTALLABLEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_PATCHSTATEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_DISPLAYNAMEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_MOREINFOURLW ))
|
||||
{
|
||||
datakey = patch;
|
||||
}
|
||||
@@ -1766,24 +1767,26 @@ UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
|
||||
|
||||
UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
|
||||
{
|
||||
HANDLE file = INVALID_HANDLE_VALUE;
|
||||
|
||||
TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
|
||||
|
||||
msi_free(gszLogFile);
|
||||
gszLogFile = NULL;
|
||||
if (szLogFile)
|
||||
{
|
||||
lstrcpyW(gszLogFile,szLogFile);
|
||||
HANDLE file;
|
||||
|
||||
if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
|
||||
DeleteFileW(szLogFile);
|
||||
file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
file = CreateFileW(szLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
gszLogFile = strdupW(szLogFile);
|
||||
CloseHandle(file);
|
||||
}
|
||||
else
|
||||
ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
|
||||
ERR("Unable to enable log %s (%u)\n", debugstr_w(szLogFile), GetLastError());
|
||||
}
|
||||
else
|
||||
gszLogFile[0] = '\0';
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@@ -1944,6 +1947,7 @@ UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
|
||||
*pdwState = INSTALLSTATE_LOCAL;
|
||||
}
|
||||
|
||||
TRACE("-> %d\n", *pdwState);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1982,6 +1986,11 @@ INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
|
||||
if (lstrlenW(szProduct) != GUID_SIZE - 1)
|
||||
return INSTALLSTATE_INVALIDARG;
|
||||
|
||||
if (szProduct[0] != '{' || szProduct[37] != '}')
|
||||
return INSTALLSTATE_UNKNOWN;
|
||||
|
||||
SetLastError( ERROR_SUCCESS );
|
||||
|
||||
if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
|
||||
&prodkey, FALSE) != ERROR_SUCCESS &&
|
||||
MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
|
||||
@@ -2015,6 +2024,7 @@ done:
|
||||
|
||||
RegCloseKey(prodkey);
|
||||
RegCloseKey(userdata);
|
||||
TRACE("-> %d\n", state);
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -2631,6 +2641,8 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
|
||||
if (!squash_guid( szProduct, squishProduct ))
|
||||
return INSTALLSTATE_INVALIDARG;
|
||||
|
||||
SetLastError( ERROR_SUCCESS );
|
||||
|
||||
if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
|
||||
&hkey, FALSE) != ERROR_SUCCESS &&
|
||||
MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
|
||||
@@ -2711,17 +2723,17 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
|
||||
|
||||
msi_free(path);
|
||||
}
|
||||
|
||||
TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
|
||||
msi_free(components);
|
||||
|
||||
if (missing)
|
||||
return INSTALLSTATE_ADVERTISED;
|
||||
r = INSTALLSTATE_ADVERTISED;
|
||||
else if (source)
|
||||
r = INSTALLSTATE_SOURCE;
|
||||
else
|
||||
r = INSTALLSTATE_LOCAL;
|
||||
|
||||
if (source)
|
||||
return INSTALLSTATE_SOURCE;
|
||||
|
||||
return INSTALLSTATE_LOCAL;
|
||||
TRACE("-> %d\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
@@ -3543,8 +3555,8 @@ UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
|
||||
LPWSTR ptr;
|
||||
DWORD sz;
|
||||
|
||||
FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
|
||||
dwReinstallMode);
|
||||
FIXME("%s %s 0x%08x\n",
|
||||
debugstr_w(szProduct), debugstr_w(szFeature), dwReinstallMode);
|
||||
|
||||
ptr = reinstallmode;
|
||||
|
||||
@@ -3661,8 +3673,10 @@ UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
|
||||
handle = CreateFileW( szFilePath, GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WARN("can't open file %u\n", GetLastError());
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
|
||||
}
|
||||
length = GetFileSize( handle, NULL );
|
||||
|
||||
mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
|
||||
@@ -3771,6 +3785,31 @@ UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD handler,
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MsiInstallMissingComponentA [MSI.@]
|
||||
*/
|
||||
UINT WINAPI MsiInstallMissingComponentA( LPCSTR product, LPCSTR component, INSTALLSTATE state )
|
||||
{
|
||||
UINT r;
|
||||
WCHAR *productW = NULL, *componentW = NULL;
|
||||
|
||||
TRACE("%s, %s, %d\n", debugstr_a(product), debugstr_a(component), state);
|
||||
|
||||
if (product && !(productW = strdupAtoW( product )))
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
if (component && !(componentW = strdupAtoW( component )))
|
||||
{
|
||||
msi_free( productW );
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
r = MsiInstallMissingComponentW( productW, componentW, state );
|
||||
msi_free( productW );
|
||||
msi_free( componentW );
|
||||
return r;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MsiInstallMissingComponentW [MSI.@]
|
||||
*/
|
||||
|
||||
+48
-31
@@ -19,39 +19,47 @@
|
||||
*/
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
#include "version.rc"
|
||||
|
||||
#include "msi_Bg.rc"
|
||||
#include "msi_Da.rc"
|
||||
#include "msi_En.rc"
|
||||
#include "msi_Es.rc"
|
||||
#include "msi_Fi.rc"
|
||||
#include "msi_Hu.rc"
|
||||
#include "msi_Ko.rc"
|
||||
#include "msi_Nl.rc"
|
||||
#include "msi_No.rc"
|
||||
#include "msi_Pl.rc"
|
||||
#include "msi_Sv.rc"
|
||||
#include "msi_Tr.rc"
|
||||
#include "msi_Uk.rc"
|
||||
#include "msi_Zh.rc"
|
||||
|
||||
/* UTF-8 */
|
||||
#include "msi_De.rc"
|
||||
#include "msi_Fr.rc"
|
||||
#include "msi_It.rc"
|
||||
#include "msi_Lt.rc"
|
||||
#include "msi_Pt.rc"
|
||||
#include "msi_Ro.rc"
|
||||
#include "msi_Ru.rc"
|
||||
#include "msi_Si.rc"
|
||||
#include "msi_Sr.rc"
|
||||
STRINGTABLE
|
||||
{
|
||||
4 "The specified installation package could not be opened. Please check the file path and try again."
|
||||
5 "path %s not found"
|
||||
9 "insert disk %s"
|
||||
10 "Windows Installer %s\n\n" \
|
||||
"Usage:\n" \
|
||||
"msiexec command {required parameter} [optional parameter]\n\n" \
|
||||
"Install a product:\n" \
|
||||
"\t/i {package|product_code} [property]\n" \
|
||||
"\t/package {package|product_code} [property]\n" \
|
||||
"\t/a package [property]\n" \
|
||||
"Repair an installation:\n" \
|
||||
"\t/f[p|o|e|d|c|a|u|m|s|v] {package|product_code}\n" \
|
||||
"Uninstall a product:\n" \
|
||||
"\t/uninstall {package|product_code} [property]\n" \
|
||||
"\t/x {package|product_code} [property]\n" \
|
||||
"Advertise a product:\n" \
|
||||
"\t/j[u|m] package [/t transform] [/g languageid]\n" \
|
||||
"Apply a patch:\n" \
|
||||
"\t/p patch_package [property]\n" \
|
||||
"\t/p patch_package /a package [property]\n" \
|
||||
"Log and UI Modifiers for above commands:\n" \
|
||||
"\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \
|
||||
"\t/q{|n|b|r|f|n+|b+|b-}\n" \
|
||||
"Register MSI Service:\n" \
|
||||
"\t/y\n" \
|
||||
"Unregister MSI Service:\n" \
|
||||
"\t/z\n" \
|
||||
"Display this help:\n" \
|
||||
"\t/help\n" \
|
||||
"\t/?\n"
|
||||
11 "enter which folder contains %s"
|
||||
12 "install source for feature missing"
|
||||
13 "network drive for feature missing"
|
||||
14 "feature from:"
|
||||
15 "choose which folder contains %s"
|
||||
}
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
@@ -66,3 +74,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
/* @makedep: instlocal.bmp */
|
||||
0x1003 BITMAP instlocal.bmp
|
||||
|
||||
#define WINE_FILEDESCRIPTION_STR "Wine MSI dll"
|
||||
#define WINE_FILENAME_STR "msi.dll"
|
||||
#define WINE_FILEVERSION 4,5,6001,22159
|
||||
#define WINE_FILEVERSION_STR "4.5.6001.22159"
|
||||
#define WINE_PRODUCTVERSION 4,5,6001,22159
|
||||
#define WINE_PRODUCTVERSION_STR "4.5.6001.22159"
|
||||
|
||||
#include "wine/wine_common_ver.rc"
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
80 stdcall MsiGetTargetPathW(long wstr ptr ptr)
|
||||
81 stdcall MsiGetUserInfoA(str ptr ptr ptr ptr ptr ptr)
|
||||
82 stdcall MsiGetUserInfoW(wstr ptr ptr ptr ptr ptr ptr)
|
||||
83 stub MsiInstallMissingComponentA
|
||||
83 stdcall MsiInstallMissingComponentA(str str long)
|
||||
84 stdcall MsiInstallMissingComponentW(wstr wstr long)
|
||||
85 stub MsiInstallMissingFileA
|
||||
86 stub MsiInstallMissingFileW
|
||||
|
||||
+22
-14
@@ -28,7 +28,9 @@
|
||||
#include "winreg.h"
|
||||
#include "shlwapi.h"
|
||||
#include "oleauto.h"
|
||||
#include "rpcproxy.h"
|
||||
#include "msipriv.h"
|
||||
#include "msiserver.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
@@ -44,7 +46,7 @@ INSTALLUI_HANDLERW gUIHandlerW = NULL;
|
||||
INSTALLUI_HANDLER_RECORD gUIHandlerRecord = NULL;
|
||||
DWORD gUIFilter = 0;
|
||||
LPVOID gUIContext = NULL;
|
||||
WCHAR gszLogFile[MAX_PATH];
|
||||
WCHAR *gszLogFile = NULL;
|
||||
HINSTANCE msi_hInstance;
|
||||
|
||||
static WCHAR msi_path[MAX_PATH];
|
||||
@@ -78,6 +80,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
if (msi_typelib) ITypeLib_Release( msi_typelib );
|
||||
msi_dialog_unregister_class();
|
||||
msi_free_handle_table();
|
||||
msi_free( gszLogFile );
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
@@ -117,14 +120,19 @@ ITypeLib *get_msi_typelib( LPWSTR *path )
|
||||
}
|
||||
|
||||
typedef struct tagIClassFactoryImpl {
|
||||
const IClassFactoryVtbl *lpVtbl;
|
||||
IClassFactory IClassFactory_iface;
|
||||
HRESULT (*create_object)( IUnknown*, LPVOID* );
|
||||
} IClassFactoryImpl;
|
||||
|
||||
static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
|
||||
REFIID riid,LPVOID *ppobj)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
IClassFactoryImpl *This = impl_from_IClassFactory(iface);
|
||||
|
||||
TRACE("%p %s %p\n",This,debugstr_guid(riid),ppobj);
|
||||
|
||||
@@ -153,7 +161,7 @@ static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
|
||||
static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
|
||||
LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
IClassFactoryImpl *This = impl_from_IClassFactory(iface);
|
||||
IUnknown *unk = NULL;
|
||||
HRESULT r;
|
||||
|
||||
@@ -189,9 +197,9 @@ static const IClassFactoryVtbl MsiCF_Vtbl =
|
||||
MsiCF_LockServer
|
||||
};
|
||||
|
||||
static IClassFactoryImpl MsiServer_CF = { &MsiCF_Vtbl, create_msiserver };
|
||||
static IClassFactoryImpl WineMsiCustomRemote_CF = { &MsiCF_Vtbl, create_msi_custom_remote };
|
||||
static IClassFactoryImpl WineMsiRemotePackage_CF = { &MsiCF_Vtbl, create_msi_remote_package };
|
||||
static IClassFactoryImpl MsiServer_CF = { { &MsiCF_Vtbl }, create_msiserver };
|
||||
static IClassFactoryImpl WineMsiCustomRemote_CF = { { &MsiCF_Vtbl }, create_msi_custom_remote };
|
||||
static IClassFactoryImpl WineMsiRemotePackage_CF = { { &MsiCF_Vtbl }, create_msi_remote_package };
|
||||
|
||||
/******************************************************************
|
||||
* DllGetClassObject [MSI.@]
|
||||
@@ -200,28 +208,28 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
||||
|
||||
if ( IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) )
|
||||
if ( IsEqualCLSID (rclsid, &CLSID_MsiInstaller) )
|
||||
{
|
||||
*ppv = &MsiServer_CF;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if ( IsEqualCLSID (rclsid, &CLSID_IWineMsiRemoteCustomAction) )
|
||||
if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemoteCustomAction) )
|
||||
{
|
||||
*ppv = &WineMsiCustomRemote_CF;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if ( IsEqualCLSID (rclsid, &CLSID_IWineMsiRemotePackage) )
|
||||
if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemotePackage) )
|
||||
{
|
||||
*ppv = &WineMsiRemotePackage_CF;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if( IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
|
||||
IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
|
||||
IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
|
||||
IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
|
||||
if( IsEqualCLSID (rclsid, &CLSID_MsiServerMessage) ||
|
||||
IsEqualCLSID (rclsid, &CLSID_MsiServer) ||
|
||||
IsEqualCLSID (rclsid, &CLSID_PSFactoryBuffer) ||
|
||||
IsEqualCLSID (rclsid, &CLSID_MsiServerX3) )
|
||||
{
|
||||
FIXME("create %s object\n", debugstr_guid( rclsid ));
|
||||
}
|
||||
|
||||
+55
-109
@@ -32,6 +32,7 @@
|
||||
#include "msidefs.h"
|
||||
#include "objbase.h"
|
||||
#include "objidl.h"
|
||||
#include "fusion.h"
|
||||
#include "winnls.h"
|
||||
#include "winver.h"
|
||||
#include "wine/list.h"
|
||||
@@ -162,6 +163,14 @@ typedef struct tagMSIPATCHINFO
|
||||
MSIPATCHSTATE state;
|
||||
} MSIPATCHINFO;
|
||||
|
||||
typedef struct tagMSIBINARY
|
||||
{
|
||||
struct list entry;
|
||||
WCHAR *source;
|
||||
WCHAR *tmpfile;
|
||||
HMODULE module;
|
||||
} MSIBINARY;
|
||||
|
||||
typedef struct _column_info
|
||||
{
|
||||
LPCWSTR table;
|
||||
@@ -315,6 +324,13 @@ enum platform
|
||||
PLATFORM_X64
|
||||
};
|
||||
|
||||
enum clr_version
|
||||
{
|
||||
CLR_VERSION_V11,
|
||||
CLR_VERSION_V20,
|
||||
CLR_VERSION_MAX
|
||||
};
|
||||
|
||||
typedef struct tagMSIPACKAGE
|
||||
{
|
||||
MSIOBJECTHDR hdr;
|
||||
@@ -329,8 +345,12 @@ typedef struct tagMSIPACKAGE
|
||||
struct list files;
|
||||
struct list tempfiles;
|
||||
struct list folders;
|
||||
struct list binaries;
|
||||
LPWSTR ActionFormat;
|
||||
LPWSTR LastAction;
|
||||
HANDLE log_file;
|
||||
IAssemblyCache *cache_net[CLR_VERSION_MAX];
|
||||
IAssemblyCache *cache_sxs;
|
||||
|
||||
struct list classes;
|
||||
struct list extensions;
|
||||
@@ -401,6 +421,18 @@ typedef struct tagMSIFEATURE
|
||||
struct list Components;
|
||||
} MSIFEATURE;
|
||||
|
||||
typedef struct tagMSIASSEMBLY
|
||||
{
|
||||
LPWSTR feature;
|
||||
LPWSTR manifest;
|
||||
LPWSTR application;
|
||||
DWORD attributes;
|
||||
LPWSTR display_name;
|
||||
LPWSTR tempdir;
|
||||
BOOL installed;
|
||||
BOOL clr_version[CLR_VERSION_MAX];
|
||||
} MSIASSEMBLY;
|
||||
|
||||
typedef struct tagMSICOMPONENT
|
||||
{
|
||||
struct list entry;
|
||||
@@ -419,6 +451,7 @@ typedef struct tagMSICOMPONENT
|
||||
INT RefCount;
|
||||
LPWSTR FullKeypath;
|
||||
LPWSTR AdvertiseString;
|
||||
MSIASSEMBLY *assembly;
|
||||
|
||||
unsigned int anyAbsent:1;
|
||||
unsigned int hasAdvertiseFeature:1;
|
||||
@@ -466,6 +499,7 @@ typedef enum _msi_file_state {
|
||||
msifs_present,
|
||||
msifs_installed,
|
||||
msifs_skipped,
|
||||
msifs_hashmatch
|
||||
} msi_file_state;
|
||||
|
||||
typedef struct tagMSIFILE
|
||||
@@ -625,14 +659,6 @@ DEFINE_GUID(CLSID_IMsiServerX2, 0x000C1090,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x0
|
||||
DEFINE_GUID(CLSID_IMsiServerX3, 0x000C1094,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
|
||||
DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
|
||||
DEFINE_GUID(CLSID_IWineMsiRemoteCustomAction,0xBA26E6FA,0x4F27,0x4f56,0x95,0x3A,0x3F,0x90,0x27,0x20,0x18,0xAA);
|
||||
DEFINE_GUID(CLSID_IWineMsiRemotePackage,0x902b3592,0x9d08,0x4dfd,0xa5,0x93,0xd0,0x7c,0x52,0x54,0x64,0x21);
|
||||
|
||||
DEFINE_GUID(CLSID_MsiTransform, 0x000c1082,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
DEFINE_GUID(CLSID_MsiDatabase, 0x000c1084,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
DEFINE_GUID(CLSID_MsiPatch, 0x000c1086,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
|
||||
/* handle unicode/ascii output in the Msi* API functions */
|
||||
typedef struct {
|
||||
BOOL unicode;
|
||||
@@ -688,6 +714,8 @@ extern const WCHAR *msi_string_lookup_id( const string_table *st, UINT id );
|
||||
extern HRESULT msi_init_string_table( IStorage *stg );
|
||||
extern string_table *msi_load_string_table( IStorage *stg, UINT *bytes_per_strref );
|
||||
extern UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *bytes_per_strref );
|
||||
extern UINT msi_get_string_table_codepage( const string_table *st );
|
||||
extern UINT msi_set_string_table_codepage( string_table *st, UINT codepage );
|
||||
|
||||
extern BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name );
|
||||
extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table );
|
||||
@@ -823,6 +851,7 @@ extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct);
|
||||
extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct);
|
||||
extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid);
|
||||
extern UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode);
|
||||
extern UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode);
|
||||
extern UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL create);
|
||||
extern UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode);
|
||||
extern UINT MSIREG_DeleteLocalClassesFeaturesKey(LPCWSTR szProductCode);
|
||||
@@ -834,7 +863,9 @@ extern DWORD msi_version_str_to_dword(LPCWSTR p);
|
||||
extern void msi_parse_version_string(LPCWSTR, PDWORD, PDWORD);
|
||||
extern VS_FIXEDFILEINFO *msi_get_disk_file_version(LPCWSTR);
|
||||
extern int msi_compare_file_versions(VS_FIXEDFILEINFO *, const WCHAR *);
|
||||
|
||||
extern int msi_compare_font_versions(const WCHAR *, const WCHAR *);
|
||||
extern DWORD msi_get_disk_file_size(LPCWSTR);
|
||||
extern BOOL msi_file_hash_matches(MSIFILE *);
|
||||
|
||||
extern LONG msi_reg_set_val_str( HKEY hkey, LPCWSTR name, LPCWSTR value );
|
||||
extern LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value );
|
||||
@@ -879,7 +910,7 @@ extern INSTALLUI_HANDLERW gUIHandlerW;
|
||||
extern INSTALLUI_HANDLER_RECORD gUIHandlerRecord;
|
||||
extern DWORD gUIFilter;
|
||||
extern LPVOID gUIContext;
|
||||
extern WCHAR gszLogFile[MAX_PATH];
|
||||
extern WCHAR *gszLogFile;
|
||||
extern HINSTANCE msi_hInstance;
|
||||
|
||||
/* action related functions */
|
||||
@@ -888,102 +919,6 @@ extern UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action, UIN
|
||||
extern void ACTION_FinishCustomActions( const MSIPACKAGE* package);
|
||||
extern UINT ACTION_CustomAction(MSIPACKAGE *package,const WCHAR *action, UINT script, BOOL execute);
|
||||
|
||||
static inline void msi_feature_set_state(MSIPACKAGE *package,
|
||||
MSIFEATURE *feature,
|
||||
INSTALLSTATE state)
|
||||
{
|
||||
if (!package->ProductCode)
|
||||
{
|
||||
feature->ActionRequest = state;
|
||||
feature->Action = state;
|
||||
}
|
||||
else if (state == INSTALLSTATE_ABSENT)
|
||||
{
|
||||
switch (feature->Installed)
|
||||
{
|
||||
case INSTALLSTATE_ABSENT:
|
||||
feature->ActionRequest = INSTALLSTATE_UNKNOWN;
|
||||
feature->Action = INSTALLSTATE_UNKNOWN;
|
||||
break;
|
||||
default:
|
||||
feature->ActionRequest = state;
|
||||
feature->Action = state;
|
||||
}
|
||||
}
|
||||
else if (state == INSTALLSTATE_SOURCE)
|
||||
{
|
||||
switch (feature->Installed)
|
||||
{
|
||||
case INSTALLSTATE_ABSENT:
|
||||
case INSTALLSTATE_SOURCE:
|
||||
feature->ActionRequest = state;
|
||||
feature->Action = state;
|
||||
break;
|
||||
case INSTALLSTATE_LOCAL:
|
||||
feature->ActionRequest = INSTALLSTATE_LOCAL;
|
||||
feature->Action = INSTALLSTATE_LOCAL;
|
||||
break;
|
||||
default:
|
||||
feature->ActionRequest = INSTALLSTATE_UNKNOWN;
|
||||
feature->Action = INSTALLSTATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
feature->ActionRequest = state;
|
||||
feature->Action = state;
|
||||
}
|
||||
if (feature->Attributes & msidbFeatureAttributesUIDisallowAbsent)
|
||||
{
|
||||
feature->Action = INSTALLSTATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void msi_component_set_state(MSIPACKAGE *package,
|
||||
MSICOMPONENT *comp,
|
||||
INSTALLSTATE state)
|
||||
{
|
||||
if (!package->ProductCode)
|
||||
{
|
||||
comp->ActionRequest = state;
|
||||
comp->Action = state;
|
||||
}
|
||||
else if (state == INSTALLSTATE_ABSENT)
|
||||
{
|
||||
switch (comp->Installed)
|
||||
{
|
||||
case INSTALLSTATE_LOCAL:
|
||||
case INSTALLSTATE_SOURCE:
|
||||
case INSTALLSTATE_DEFAULT:
|
||||
comp->ActionRequest = state;
|
||||
comp->Action = state;
|
||||
break;
|
||||
default:
|
||||
comp->ActionRequest = INSTALLSTATE_UNKNOWN;
|
||||
comp->Action = INSTALLSTATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
else if (state == INSTALLSTATE_SOURCE)
|
||||
{
|
||||
if (comp->Installed == INSTALLSTATE_ABSENT ||
|
||||
(comp->Installed == INSTALLSTATE_SOURCE && comp->hasLocalFeature))
|
||||
{
|
||||
comp->ActionRequest = state;
|
||||
comp->Action = state;
|
||||
}
|
||||
else
|
||||
{
|
||||
comp->ActionRequest = INSTALLSTATE_UNKNOWN;
|
||||
comp->Action = INSTALLSTATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
comp->ActionRequest = state;
|
||||
comp->Action = state;
|
||||
}
|
||||
}
|
||||
|
||||
/* actions in other modules */
|
||||
extern UINT ACTION_AppSearch(MSIPACKAGE *package);
|
||||
extern UINT ACTION_CCPSearch(MSIPACKAGE *package);
|
||||
@@ -1003,6 +938,8 @@ extern UINT ACTION_UnregisterExtensionInfo(MSIPACKAGE *package);
|
||||
extern UINT ACTION_UnregisterFonts(MSIPACKAGE *package);
|
||||
extern UINT ACTION_UnregisterMIMEInfo(MSIPACKAGE *package);
|
||||
extern UINT ACTION_UnregisterProgIdInfo(MSIPACKAGE *package);
|
||||
extern UINT ACTION_MsiPublishAssemblies(MSIPACKAGE *package);
|
||||
extern UINT ACTION_MsiUnpublishAssemblies(MSIPACKAGE *package);
|
||||
|
||||
/* Helpers */
|
||||
extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data );
|
||||
@@ -1011,8 +948,8 @@ extern LPWSTR msi_dup_property( MSIDATABASE *db, LPCWSTR prop );
|
||||
extern UINT msi_set_property( MSIDATABASE *, LPCWSTR, LPCWSTR );
|
||||
extern UINT msi_get_property( MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD );
|
||||
extern int msi_get_property_int( MSIDATABASE *package, LPCWSTR prop, int def );
|
||||
extern LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
||||
BOOL set_prop, BOOL load_prop, MSIFOLDER **folder);
|
||||
extern LPWSTR resolve_source_folder(MSIPACKAGE *package, LPCWSTR name, MSIFOLDER **folder);
|
||||
extern LPWSTR resolve_target_folder(MSIPACKAGE *package, LPCWSTR name, BOOL set_prop, BOOL load_prop, MSIFOLDER **folder);
|
||||
extern LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file);
|
||||
extern void msi_reset_folders( MSIPACKAGE *package, BOOL source );
|
||||
extern MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component );
|
||||
@@ -1027,7 +964,7 @@ extern LPWSTR build_directory_name(DWORD , ...);
|
||||
extern BOOL create_full_pathW(const WCHAR *path);
|
||||
extern void reduce_to_longfilename(WCHAR*);
|
||||
extern LPWSTR create_component_advertise_string(MSIPACKAGE*, MSICOMPONENT*, LPCWSTR);
|
||||
extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature);
|
||||
extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, MSIFEATURE *feature);
|
||||
extern UINT register_unique_action(MSIPACKAGE *, LPCWSTR);
|
||||
extern BOOL check_unique_action(const MSIPACKAGE *, LPCWSTR);
|
||||
extern WCHAR* generate_error_string(MSIPACKAGE *, UINT, DWORD, ... );
|
||||
@@ -1035,6 +972,10 @@ extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid,
|
||||
MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value);
|
||||
extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix);
|
||||
extern UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace);
|
||||
extern MSIASSEMBLY *load_assembly(MSIPACKAGE *, MSICOMPONENT *);
|
||||
extern UINT install_assembly(MSIPACKAGE *, MSICOMPONENT *);
|
||||
extern WCHAR *font_version_from_file(const WCHAR *);
|
||||
extern WCHAR **msi_split_string(const WCHAR *, WCHAR);
|
||||
|
||||
/* media */
|
||||
|
||||
@@ -1053,6 +994,7 @@ typedef struct
|
||||
} MSICABDATA;
|
||||
|
||||
extern UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi);
|
||||
extern UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi);
|
||||
extern void msi_free_media_info(MSIMEDIAINFO *mi);
|
||||
extern BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data);
|
||||
|
||||
@@ -1149,8 +1091,12 @@ static const WCHAR szAdminUser[] = {'A','d','m','i','n','U','s','e','r',0};
|
||||
static const WCHAR szIntel[] = {'I','n','t','e','l',0};
|
||||
static const WCHAR szIntel64[] = {'I','n','t','e','l','6','4',0};
|
||||
static const WCHAR szX64[] = {'x','6','4',0};
|
||||
static const WCHAR szAMD64[] = {'A','M','D','6','4',0};
|
||||
static const WCHAR szWow6432NodeCLSID[] = {'W','o','w','6','4','3','2','N','o','d','e','\\','C','L','S','I','D',0};
|
||||
static const WCHAR szWow6432Node[] = {'W','o','w','6','4','3','2','N','o','d','e',0};
|
||||
static const WCHAR szStreams[] = {'_','S','t','r','e','a','m','s',0};
|
||||
static const WCHAR szStorages[] = {'_','S','t','o','r','a','g','e','s',0};
|
||||
static const WCHAR szMsiPublishAssemblies[] = {'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};
|
||||
|
||||
/* memory allocation macro functions */
|
||||
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
|
||||
|
||||
@@ -75,9 +75,9 @@ UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, LPCWSTR table_name, UINT *n
|
||||
NULL, &haystack_table_name );
|
||||
if( r != ERROR_SUCCESS )
|
||||
return r;
|
||||
x = lstrcmpW( name, col_name );
|
||||
x = strcmpW( name, col_name );
|
||||
if( table_name )
|
||||
x |= lstrcmpW( table_name, haystack_table_name );
|
||||
x |= strcmpW( table_name, haystack_table_name );
|
||||
msi_free( col_name );
|
||||
msi_free( haystack_table_name );
|
||||
if( !x )
|
||||
|
||||
@@ -86,6 +86,99 @@ interface IWineMsiRemoteCustomAction : IUnknown
|
||||
[out] BSTR *function, [out] IWineMsiRemotePackage **package );
|
||||
}
|
||||
|
||||
[
|
||||
uuid(000c101c-0000-0000-c000-000000000046),
|
||||
oleautomation,
|
||||
object
|
||||
]
|
||||
interface IMsiServer : IUnknown
|
||||
{
|
||||
/* FIXME: methods */
|
||||
}
|
||||
|
||||
[
|
||||
uuid(000c101d-0000-0000-c000-000000000046),
|
||||
oleautomation,
|
||||
object
|
||||
]
|
||||
interface IMsiMessage : IUnknown
|
||||
{
|
||||
/* FIXME: methods */
|
||||
}
|
||||
|
||||
[
|
||||
uuid(000c1025-0000-0000-c000-000000000046),
|
||||
oleautomation,
|
||||
object
|
||||
]
|
||||
interface IMsiCustomAction : IUnknown
|
||||
{
|
||||
/* FIXME: methods */
|
||||
}
|
||||
|
||||
[
|
||||
uuid(000c1033-0000-0000-c000-000000000046),
|
||||
oleautomation,
|
||||
object
|
||||
]
|
||||
interface IMsiRemoteAPI : IUnknown
|
||||
{
|
||||
/* FIXME: methods */
|
||||
}
|
||||
|
||||
[
|
||||
helpstring("Msi install server"),
|
||||
progid("IMsiServer"),
|
||||
uuid(000c101c-0000-0000-c000-000000000046)
|
||||
]
|
||||
coclass MsiServer { interface IMsiServer; }
|
||||
|
||||
[
|
||||
helpstring("Microsoft Windows Installer Message RPC"),
|
||||
progid("WindowsInstaller.Message"),
|
||||
uuid(000c101d-0000-0000-c000-000000000046)
|
||||
]
|
||||
coclass MsiServerMessage { interface IMsiMessage; }
|
||||
|
||||
[
|
||||
threading(both),
|
||||
uuid(000c103e-0000-0000-c000-000000000046)
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
||||
[
|
||||
uuid(000c1082-0000-0000-c000-000000000046)
|
||||
]
|
||||
coclass MsiTransform { }
|
||||
|
||||
[
|
||||
uuid(000c1084-0000-0000-c000-000000000046)
|
||||
]
|
||||
coclass MsiDatabase { }
|
||||
|
||||
[
|
||||
uuid(000c1086-0000-0000-c000-000000000046)
|
||||
]
|
||||
coclass MsiPatch { }
|
||||
|
||||
[
|
||||
threading(apartment),
|
||||
uuid(000c1094-0000-0000-c000-000000000046)
|
||||
]
|
||||
/* FIXME: unidentified class */
|
||||
coclass MsiServerX3 { interface IMsiServer; }
|
||||
|
||||
[
|
||||
uuid(ba26e6fa-4f27-4f56-953a-3f90272018aa)
|
||||
]
|
||||
coclass WineMsiRemoteCustomAction { interface WineMsiRemoteCustomAction; }
|
||||
|
||||
[
|
||||
uuid(902b3592-9d08-4dfd-a593-d07c52546421)
|
||||
]
|
||||
coclass WineMsiRemotePackage { interface WineMsiRemotePackage; }
|
||||
|
||||
|
||||
[ uuid(000C1092-0000-0000-C000-000000000046), version(1.0) ]
|
||||
library WindowsInstaller
|
||||
{
|
||||
@@ -452,4 +545,12 @@ library WindowsInstaller
|
||||
properties:
|
||||
methods:
|
||||
}
|
||||
|
||||
[
|
||||
helpstring("Microsoft Windows Installer"),
|
||||
threading(apartment),
|
||||
progid("WindowsInstaller.Installer"),
|
||||
uuid(000c1090-0000-0000-c000-000000000046)
|
||||
]
|
||||
coclass MsiInstaller { interface Installer; }
|
||||
}
|
||||
|
||||
+105
-54
@@ -59,8 +59,7 @@ static void remove_tracked_tempfiles( MSIPACKAGE *package )
|
||||
|
||||
list_remove( &temp->entry );
|
||||
TRACE("deleting temp file %s\n", debugstr_w( temp->Path ));
|
||||
if (!DeleteFileW( temp->Path ))
|
||||
ERR("failed to delete %s\n", debugstr_w( temp->Path ));
|
||||
DeleteFileW( temp->Path );
|
||||
msi_free( temp->Path );
|
||||
msi_free( temp );
|
||||
}
|
||||
@@ -111,6 +110,17 @@ static void free_extension( MSIEXTENSION *ext )
|
||||
msi_free( ext );
|
||||
}
|
||||
|
||||
static void free_assembly( MSIASSEMBLY *assembly )
|
||||
{
|
||||
msi_free( assembly->feature );
|
||||
msi_free( assembly->manifest );
|
||||
msi_free( assembly->application );
|
||||
msi_free( assembly->display_name );
|
||||
if (assembly->tempdir) RemoveDirectoryW( assembly->tempdir );
|
||||
msi_free( assembly->tempdir );
|
||||
msi_free( assembly );
|
||||
}
|
||||
|
||||
static void free_package_structures( MSIPACKAGE *package )
|
||||
{
|
||||
INT i;
|
||||
@@ -154,6 +164,7 @@ static void free_package_structures( MSIPACKAGE *package )
|
||||
msi_free( comp->Condition );
|
||||
msi_free( comp->KeyPath );
|
||||
msi_free( comp->FullKeypath );
|
||||
if (comp->assembly) free_assembly( comp->assembly );
|
||||
msi_free( comp );
|
||||
}
|
||||
|
||||
@@ -275,6 +286,20 @@ static void free_package_structures( MSIPACKAGE *package )
|
||||
msi_free( patch );
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_SAFE( item, cursor, &package->binaries )
|
||||
{
|
||||
MSIBINARY *binary = LIST_ENTRY( item, MSIBINARY, entry );
|
||||
|
||||
list_remove( &binary->entry );
|
||||
if (binary->module)
|
||||
FreeLibrary( binary->module );
|
||||
if (!DeleteFileW( binary->tmpfile ))
|
||||
ERR("failed to delete %s (%u)\n", debugstr_w(binary->tmpfile), GetLastError());
|
||||
msi_free( binary->source );
|
||||
msi_free( binary->tmpfile );
|
||||
msi_free( binary );
|
||||
}
|
||||
|
||||
msi_free( package->BaseURL );
|
||||
msi_free( package->PackagePath );
|
||||
msi_free( package->ProductCode );
|
||||
@@ -288,13 +313,19 @@ static void free_package_structures( MSIPACKAGE *package )
|
||||
|
||||
static void MSI_FreePackage( MSIOBJECTHDR *arg)
|
||||
{
|
||||
MSIPACKAGE *package= (MSIPACKAGE*) arg;
|
||||
UINT i;
|
||||
MSIPACKAGE *package = (MSIPACKAGE *)arg;
|
||||
|
||||
if( package->dialog )
|
||||
msi_dialog_destroy( package->dialog );
|
||||
|
||||
msiobj_release( &package->db->hdr );
|
||||
free_package_structures(package);
|
||||
CloseHandle( package->log_file );
|
||||
|
||||
for (i = 0; i < CLR_VERSION_MAX; i++)
|
||||
if (package->cache_net[i]) IAssemblyCache_Release( package->cache_net[i] );
|
||||
if (package->cache_sxs) IAssemblyCache_Release( package->cache_sxs );
|
||||
}
|
||||
|
||||
static UINT create_temp_property_table(MSIPACKAGE *package)
|
||||
@@ -511,7 +542,7 @@ static LPWSTR get_fusion_filename(MSIPACKAGE *package)
|
||||
index++;
|
||||
|
||||
/* verify existence of fusion.dll .Net 3.0 does not install a new one */
|
||||
if (lstrcmpW(ver, name) < 0)
|
||||
if (strcmpW( ver, name ) < 0)
|
||||
{
|
||||
LPWSTR check;
|
||||
size = lstrlenW(windir) + lstrlenW(subdir) + lstrlenW(name) +lstrlenW(fusion) + 3;
|
||||
@@ -1046,6 +1077,7 @@ static MSIPACKAGE *msi_alloc_package( void )
|
||||
list_init( &package->sourcelist_info );
|
||||
list_init( &package->sourcelist_media );
|
||||
list_init( &package->patches );
|
||||
list_init( &package->binaries );
|
||||
}
|
||||
|
||||
return package;
|
||||
@@ -1121,6 +1153,8 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
|
||||
|
||||
if (package->WordCount & msidbSumInfoSourceTypeAdminImage)
|
||||
msi_load_admin_properties( package );
|
||||
|
||||
package->log_file = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
return package;
|
||||
@@ -1313,7 +1347,7 @@ static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
|
||||
package->platform = PLATFORM_INTEL;
|
||||
else if (!strcmpW( template, szIntel64 ))
|
||||
package->platform = PLATFORM_INTEL64;
|
||||
else if (!strcmpW( template, szX64 ))
|
||||
else if (!strcmpW( template, szX64 ) || !strcmpW( template, szAMD64 ))
|
||||
package->platform = PLATFORM_X64;
|
||||
else
|
||||
{
|
||||
@@ -1321,9 +1355,14 @@ static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
|
||||
msi_free( template );
|
||||
return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
|
||||
}
|
||||
|
||||
p++;
|
||||
if (!*p)
|
||||
{
|
||||
msi_free( template );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
count = 1;
|
||||
for (q = ++p; (q = strchrW( q, ',' )); q++) count++;
|
||||
for (q = p; (q = strchrW( q, ',' )); q++) count++;
|
||||
|
||||
package->langids = msi_alloc( count * sizeof(LANGID) );
|
||||
if (!package->langids)
|
||||
@@ -1367,7 +1406,17 @@ static UINT validate_package( MSIPACKAGE *package )
|
||||
}
|
||||
for (i = 0; i < package->num_langids; i++)
|
||||
{
|
||||
if (!package->langids[i] || IsValidLocale( package->langids[i], LCID_INSTALLED ))
|
||||
LANGID langid = package->langids[i];
|
||||
|
||||
if (PRIMARYLANGID( langid ) == LANG_NEUTRAL)
|
||||
{
|
||||
langid = MAKELANGID( PRIMARYLANGID( GetSystemDefaultLangID() ), SUBLANGID( langid ) );
|
||||
}
|
||||
if (SUBLANGID( langid ) == SUBLANG_NEUTRAL)
|
||||
{
|
||||
langid = MAKELANGID( PRIMARYLANGID( langid ), SUBLANGID( GetSystemDefaultLangID() ) );
|
||||
}
|
||||
if (IsValidLocale( langid, LCID_INSTALLED ))
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
return ERROR_INSTALL_LANGUAGE_UNSUPPORTED;
|
||||
@@ -1551,6 +1600,10 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
||||
msi_adjust_privilege_properties( package );
|
||||
}
|
||||
|
||||
if (gszLogFile)
|
||||
package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
|
||||
*pPackage = package;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@@ -1657,17 +1710,13 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
|
||||
{'S','e','t','P','r','o','g','r','e','s','s',0};
|
||||
static const WCHAR szActionText[] =
|
||||
{'A','c','t','i','o','n','T','e','x','t',0};
|
||||
DWORD log_type = 0;
|
||||
LPWSTR message;
|
||||
DWORD sz;
|
||||
DWORD total_size = 0;
|
||||
INT i;
|
||||
INT rc;
|
||||
DWORD sz, total_size = 0, log_type = 0;
|
||||
INT i, rc = 0;
|
||||
char *msg;
|
||||
int len;
|
||||
|
||||
TRACE("%x\n", eMessageType);
|
||||
rc = 0;
|
||||
|
||||
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ERROR)
|
||||
log_type |= INSTALLLOGMODE_ERROR;
|
||||
@@ -1773,20 +1822,12 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
|
||||
MsiCloseHandle( rec );
|
||||
}
|
||||
|
||||
if ((!rc) && (gszLogFile[0]) && !((eMessageType & 0xff000000) ==
|
||||
INSTALLMESSAGE_PROGRESS))
|
||||
if (!rc && package->log_file != INVALID_HANDLE_VALUE &&
|
||||
(eMessageType & 0xff000000) != INSTALLMESSAGE_PROGRESS)
|
||||
{
|
||||
DWORD write;
|
||||
HANDLE log_file = CreateFileW(gszLogFile,GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (log_file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetFilePointer(log_file,0, NULL, FILE_END);
|
||||
WriteFile(log_file,msg,strlen(msg),&write,NULL);
|
||||
WriteFile(log_file,"\n",1,&write,NULL);
|
||||
CloseHandle(log_file);
|
||||
}
|
||||
DWORD written;
|
||||
WriteFile( package->log_file, msg, len - 1, &written, NULL );
|
||||
WriteFile( package->log_file, "\n", 1, &written, NULL );
|
||||
}
|
||||
msi_free( msg );
|
||||
msi_free( message );
|
||||
@@ -2248,14 +2289,14 @@ UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName,
|
||||
}
|
||||
|
||||
typedef struct _msi_remote_package_impl {
|
||||
const IWineMsiRemotePackageVtbl *lpVtbl;
|
||||
IWineMsiRemotePackage IWineMsiRemotePackage_iface;
|
||||
MSIHANDLE package;
|
||||
LONG refs;
|
||||
} msi_remote_package_impl;
|
||||
|
||||
static inline msi_remote_package_impl* mrp_from_IWineMsiRemotePackage( IWineMsiRemotePackage* iface )
|
||||
static inline msi_remote_package_impl *impl_from_IWineMsiRemotePackage( IWineMsiRemotePackage *iface )
|
||||
{
|
||||
return (msi_remote_package_impl*) iface;
|
||||
return CONTAINING_RECORD(iface, msi_remote_package_impl, IWineMsiRemotePackage_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface,
|
||||
@@ -2274,14 +2315,14 @@ static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface,
|
||||
|
||||
static ULONG WINAPI mrp_AddRef( IWineMsiRemotePackage *iface )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
|
||||
return InterlockedIncrement( &This->refs );
|
||||
}
|
||||
|
||||
static ULONG WINAPI mrp_Release( IWineMsiRemotePackage *iface )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
ULONG r;
|
||||
|
||||
r = InterlockedDecrement( &This->refs );
|
||||
@@ -2295,14 +2336,14 @@ static ULONG WINAPI mrp_Release( IWineMsiRemotePackage *iface )
|
||||
|
||||
static HRESULT WINAPI mrp_SetMsiHandle( IWineMsiRemotePackage *iface, MSIHANDLE handle )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
This->package = handle;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHANDLE *handle )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
IWineMsiRemoteDatabase *rdb = NULL;
|
||||
HRESULT hr;
|
||||
MSIHANDLE hdb;
|
||||
@@ -2329,7 +2370,7 @@ static HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHA
|
||||
|
||||
static HRESULT WINAPI mrp_GetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR *value, DWORD *size )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r;
|
||||
|
||||
r = MsiGetPropertyW(This->package, (LPWSTR)property, (LPWSTR)value, size);
|
||||
@@ -2341,63 +2382,63 @@ static HRESULT WINAPI mrp_GetProperty( IWineMsiRemotePackage *iface, BSTR proper
|
||||
|
||||
static HRESULT WINAPI mrp_SetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR value )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiSetPropertyW(This->package, property, value);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_ProcessMessage( IWineMsiRemotePackage *iface, INSTALLMESSAGE message, MSIHANDLE record )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiProcessMessage(This->package, message, record);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_DoAction( IWineMsiRemotePackage *iface, BSTR action )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiDoActionW(This->package, action);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_Sequence( IWineMsiRemotePackage *iface, BSTR table, int sequence )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiSequenceW(This->package, table, sequence);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_GetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR *value, DWORD *size )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiGetTargetPathW(This->package, (LPWSTR)folder, (LPWSTR)value, size);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_SetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value)
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiSetTargetPathW(This->package, folder, value);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_GetSourcePath( IWineMsiRemotePackage *iface, BSTR folder, BSTR *value, DWORD *size )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiGetSourcePathW(This->package, (LPWSTR)folder, (LPWSTR)value, size);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_GetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL *ret )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
*ret = MsiGetMode(This->package, mode);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_SetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL state )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiSetMode(This->package, mode, state);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
@@ -2405,14 +2446,14 @@ static HRESULT WINAPI mrp_SetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode
|
||||
static HRESULT WINAPI mrp_GetFeatureState( IWineMsiRemotePackage *iface, BSTR feature,
|
||||
INSTALLSTATE *installed, INSTALLSTATE *action )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiGetFeatureStateW(This->package, feature, installed, action);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_SetFeatureState( IWineMsiRemotePackage *iface, BSTR feature, INSTALLSTATE state )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiSetFeatureStateW(This->package, feature, state);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
@@ -2420,28 +2461,28 @@ static HRESULT WINAPI mrp_SetFeatureState( IWineMsiRemotePackage *iface, BSTR fe
|
||||
static HRESULT WINAPI mrp_GetComponentState( IWineMsiRemotePackage *iface, BSTR component,
|
||||
INSTALLSTATE *installed, INSTALLSTATE *action )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiGetComponentStateW(This->package, component, installed, action);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_SetComponentState( IWineMsiRemotePackage *iface, BSTR component, INSTALLSTATE state )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiSetComponentStateW(This->package, component, state);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_GetLanguage( IWineMsiRemotePackage *iface, LANGID *language )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
*language = MsiGetLanguage(This->package);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mrp_SetInstallLevel( IWineMsiRemotePackage *iface, int level )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiSetInstallLevel(This->package, level);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
@@ -2450,7 +2491,7 @@ static HRESULT WINAPI mrp_FormatRecord( IWineMsiRemotePackage *iface, MSIHANDLE
|
||||
BSTR *value)
|
||||
{
|
||||
DWORD size = 0;
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiFormatRecordW(This->package, record, NULL, &size);
|
||||
if (r == ERROR_SUCCESS)
|
||||
{
|
||||
@@ -2465,7 +2506,7 @@ static HRESULT WINAPI mrp_FormatRecord( IWineMsiRemotePackage *iface, MSIHANDLE
|
||||
|
||||
static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR condition )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiEvaluateConditionW(This->package, condition);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
@@ -2473,7 +2514,7 @@ static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR
|
||||
static HRESULT WINAPI mrp_GetFeatureCost( IWineMsiRemotePackage *iface, BSTR feature,
|
||||
INT cost_tree, INSTALLSTATE state, INT *cost )
|
||||
{
|
||||
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
||||
UINT r = MsiGetFeatureCostW(This->package, feature, cost_tree, state, cost);
|
||||
return HRESULT_FROM_WIN32(r);
|
||||
}
|
||||
@@ -2514,7 +2555,7 @@ HRESULT create_msi_remote_package( IUnknown *pOuter, LPVOID *ppObj )
|
||||
if (!This)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->lpVtbl = &msi_remote_package_vtbl;
|
||||
This->IWineMsiRemotePackage_iface.lpVtbl = &msi_remote_package_vtbl;
|
||||
This->package = 0;
|
||||
This->refs = 1;
|
||||
|
||||
@@ -2528,6 +2569,11 @@ UINT msi_package_add_info(MSIPACKAGE *package, DWORD context, DWORD options,
|
||||
{
|
||||
MSISOURCELISTINFO *info;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( info, &package->sourcelist_info, MSISOURCELISTINFO, entry )
|
||||
{
|
||||
if (!strcmpW( info->value, value )) return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
info = msi_alloc(sizeof(MSISOURCELISTINFO));
|
||||
if (!info)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
@@ -2546,6 +2592,11 @@ UINT msi_package_add_media_disk(MSIPACKAGE *package, DWORD context, DWORD option
|
||||
{
|
||||
MSIMEDIADISK *disk;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( disk, &package->sourcelist_media, MSIMEDIADISK, entry )
|
||||
{
|
||||
if (disk->disk_id == disk_id) return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
disk = msi_alloc(sizeof(MSIMEDIADISK));
|
||||
if (!disk)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "msi.h"
|
||||
#include "msiquery.h"
|
||||
#include "msipriv.h"
|
||||
@@ -1016,7 +1017,7 @@ BOOL MSI_RecordsAreEqual(MSIRECORD *a, MSIRECORD *b)
|
||||
break;
|
||||
|
||||
case MSIFIELD_WSTR:
|
||||
if (lstrcmpW(a->fields[i].u.szwVal, b->fields[i].u.szwVal))
|
||||
if (strcmpW(a->fields[i].u.szwVal, b->fields[i].u.szwVal))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
|
||||
@@ -1182,6 +1182,21 @@ UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL cr
|
||||
return RegOpenKeyW(HKEY_CLASSES_ROOT, keypath, key);
|
||||
}
|
||||
|
||||
UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode)
|
||||
{
|
||||
WCHAR squished_pc[GUID_SIZE];
|
||||
WCHAR keypath[0x200];
|
||||
|
||||
TRACE("%s\n", debugstr_w(szUpgradeCode));
|
||||
if (!squash_guid(szUpgradeCode, squished_pc))
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
TRACE("squished (%s)\n", debugstr_w(squished_pc));
|
||||
|
||||
sprintfW(keypath, szInstaller_ClassesUpgrade_fmt, squished_pc);
|
||||
|
||||
return RegDeleteTreeW(HKEY_CLASSES_ROOT, keypath);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* MsiDecomposeDescriptorW [MSI.@]
|
||||
*
|
||||
@@ -1549,10 +1564,11 @@ UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
|
||||
sz = SQUISH_GUID_SIZE;
|
||||
r = RegEnumValueW(hkeyComp, index, szValName, &sz, NULL, NULL, NULL, NULL);
|
||||
if( r == ERROR_SUCCESS )
|
||||
{
|
||||
unsquash_guid(szValName, szProduct);
|
||||
|
||||
TRACE("-> %s\n", debugstr_w(szProduct));
|
||||
}
|
||||
RegCloseKey(hkeyComp);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -2140,7 +2156,7 @@ UINT WINAPI MsiEnumPatchesExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
|
||||
if (!szProductCode || !squash_guid(szProductCode, squished_pc))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (!lstrcmpW(szUserSid, szLocalSid))
|
||||
if (szUserSid && !strcmpW( szUserSid, szLocalSid ))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (dwContext & MSIINSTALLCONTEXT_MACHINE && szUserSid)
|
||||
|
||||
@@ -143,6 +143,7 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
|
||||
|
||||
/* Add the session object */
|
||||
hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_ISVISIBLE);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
/* Pass the script to the engine */
|
||||
hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
|
||||
|
||||
+19
-14
@@ -330,7 +330,6 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode,
|
||||
else
|
||||
size = lstrlenW(ptr);
|
||||
|
||||
size = lstrlenW(ptr);
|
||||
if (size >= *pcchDiskPrompt)
|
||||
r = ERROR_MORE_DATA;
|
||||
else if (szDiskPrompt)
|
||||
@@ -592,8 +591,8 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return rc;
|
||||
|
||||
if (!lstrcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW))
|
||||
if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_DISKPROMPTW ))
|
||||
{
|
||||
rc = OpenMediaSubkey(sourcekey, &media, FALSE);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
@@ -602,14 +601,14 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
if (!lstrcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW))
|
||||
if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ))
|
||||
szProperty = mediapack;
|
||||
|
||||
RegQueryValueExW(media, szProperty, 0, 0, (LPBYTE)szValue, pcchValue);
|
||||
RegCloseKey(media);
|
||||
}
|
||||
else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDTYPEW))
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDTYPEW ))
|
||||
{
|
||||
rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
|
||||
0, 0, NULL, &size);
|
||||
@@ -630,7 +629,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
if (!lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDTYPEW))
|
||||
if (!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDTYPEW ))
|
||||
{
|
||||
if (*source != 'n' && *source != 'u' && *source != 'm')
|
||||
{
|
||||
@@ -662,7 +661,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
|
||||
*pcchValue = lstrlenW(ptr);
|
||||
msi_free(source);
|
||||
}
|
||||
else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_PACKAGENAMEW ))
|
||||
{
|
||||
*pcchValue = *pcchValue * sizeof(WCHAR);
|
||||
rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 0,
|
||||
@@ -815,22 +814,22 @@ UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
|
||||
}
|
||||
|
||||
property = szProperty;
|
||||
if (!lstrcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW))
|
||||
if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ))
|
||||
property = media_package;
|
||||
|
||||
rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, dwContext, FALSE);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return rc;
|
||||
|
||||
if (lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW) &&
|
||||
if (strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW ) &&
|
||||
dwOptions & (MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL))
|
||||
{
|
||||
RegCloseKey(sourcekey);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!lstrcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) ||
|
||||
!lstrcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW))
|
||||
if (!strcmpW( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ) ||
|
||||
!strcmpW( szProperty, INSTALLPROPERTY_DISKPROMPTW ))
|
||||
{
|
||||
rc = OpenMediaSubkey(sourcekey, &media, TRUE);
|
||||
if (rc == ERROR_SUCCESS)
|
||||
@@ -839,7 +838,7 @@ UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
|
||||
RegCloseKey(media);
|
||||
}
|
||||
}
|
||||
else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_PACKAGENAMEW ))
|
||||
{
|
||||
DWORD size = (lstrlenW(szValue) + 1) * sizeof(WCHAR);
|
||||
rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0,
|
||||
@@ -847,7 +846,7 @@ UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
|
||||
if (rc != ERROR_SUCCESS)
|
||||
rc = ERROR_UNKNOWN_PROPERTY;
|
||||
}
|
||||
else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW))
|
||||
else if (!strcmpW( szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW ))
|
||||
{
|
||||
if (!(dwOptions & (MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL)))
|
||||
rc = ERROR_INVALID_PARAMETER;
|
||||
@@ -1130,6 +1129,12 @@ UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
|
||||
RegCloseKey(sourcekey);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("can't open subkey %u\n", rc);
|
||||
RegCloseKey(sourcekey);
|
||||
return rc;
|
||||
}
|
||||
|
||||
postfix = (dwOptions & MSISOURCETYPE_NETWORK) ? szBackSlash : szForwardSlash;
|
||||
if (szSource[lstrlenW(szSource) - 1] == *postfix)
|
||||
|
||||
@@ -2872,7 +2872,7 @@ static BOOL SQL_MarkPrimaryKeys( column_info **cols,
|
||||
found = FALSE;
|
||||
for( c = *cols, idx = 0; c && !found; c = c->next, idx++ )
|
||||
{
|
||||
if( lstrcmpW( k->column, c->column ) )
|
||||
if( strcmpW( k->column, c->column ) )
|
||||
continue;
|
||||
c->type |= MSITYPE_KEY;
|
||||
found = TRUE;
|
||||
|
||||
+1
-1
@@ -950,7 +950,7 @@ static BOOL SQL_MarkPrimaryKeys( column_info **cols,
|
||||
found = FALSE;
|
||||
for( c = *cols, idx = 0; c && !found; c = c->next, idx++ )
|
||||
{
|
||||
if( lstrcmpW( k->column, c->column ) )
|
||||
if( strcmpW( k->column, c->column ) )
|
||||
continue;
|
||||
c->type |= MSITYPE_KEY;
|
||||
found = TRUE;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user