diff --git a/base/applications/cacls/lang/da-DA.rc b/base/applications/cacls/lang/da-DA.rc new file mode 100644 index 00000000000..7663dae602d --- /dev/null +++ b/base/applications/cacls/lang/da-DA.rc @@ -0,0 +1,79 @@ +/* + * German language file by Daniel Reimer 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 vre: R lse\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 vre: N Ingen\n\ + R Lse\n\ + W Skrive\n\ + C ndre (Skrive)\n\ + F fuld adgang\n\ + /D Bruger Forbyde adgang for brugeren.\n\ +Mellemrum(Wildcards) bliver understttet 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 diff --git a/base/applications/cacls/lang/es-ES.rc b/base/applications/cacls/lang/es-ES.rc new file mode 100644 index 00000000000..37ff0bb2763 --- /dev/null +++ b/base/applications/cacls/lang/es-ES.rc @@ -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 Contina 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 Modificacin (Escritura)\n\ + F Control total\n\ + /R usuario Revoca los derechos de acceso al usuario especificado (unicamente vlido 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 Modificacin (Escritura)\n\ + F Control total\n\ + /D usuario Revoca el acceso al usuario especificado.\n\ +Es posible usar comodines para especificar ms de un archivo por comando.\n\ +Se puede especificar ms 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 diff --git a/base/applications/cacls/rsrc.rc b/base/applications/cacls/rsrc.rc index cf19989a441..2585185bb37 100644 --- a/base/applications/cacls/rsrc.rc +++ b/base/applications/cacls/rsrc.rc @@ -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" diff --git a/base/applications/games/winmine/lang/es-ES.rc b/base/applications/games/winmine/lang/es-ES.rc index a6cca74a676..82bde4e757c 100644 --- a/base/applications/games/winmine/lang/es-ES.rc +++ b/base/applications/games/winmine/lang/es-ES.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 diff --git a/base/applications/games/winmine/lang/it-IT.rc b/base/applications/games/winmine/lang/it-IT.rc index 9bf28fca948..9c3643d2e77 100644 --- a/base/applications/games/winmine/lang/it-IT.rc +++ b/base/applications/games/winmine/lang/it-IT.rc @@ -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 diff --git a/base/applications/network/ipconfig/ipconfig.rc b/base/applications/network/ipconfig/ipconfig.rc index d471073b6f7..7627a1de6a2 100644 --- a/base/applications/network/ipconfig/ipconfig.rc +++ b/base/applications/network/ipconfig/ipconfig.rc @@ -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" diff --git a/base/applications/network/ipconfig/lang/es-ES.rc b/base/applications/network/ipconfig/lang/es-ES.rc new file mode 100644 index 00000000000..969900d3826 --- /dev/null +++ b/base/applications/network/ipconfig/lang/es-ES.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 "Hbrido" + 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 conexin\n \ + (caracteres especiales * and ? autorizados, ver ejemplos)\n \ + \n \ + Optiones:\n \ + /? Muestra este mensaje de ayuda\n \ + /all Muestra todas las informaciones de configuracin.\n \ + /release Libera la direccin IP para el adaptador especificado.\n \ + /renew Renueva la direccin IP para el adaptador especificado.\n \ + /flushdns Purga la cache de Resolucin DNS.\n \ + /registerdns Actualiza todas las concesiones DHCP y registra de nuevo nombres DNS.\n \ + /displaydns Muestra el contenido del cache de Resolucin 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 direccin IP, la mscara de red y\n \ + la puerta de enlace predefinidas de cada adaptador relacionado a TCP/IP.\n \ + \n \ + Para los parmetros Release y Renew, si no se especifica un adaptador, entonces la(s) direccin(es)\n \ + IP asignada(s) para todos los adaptadores relacionados a TCP/IP sern liberadas o renovadas.\n \ + \n \ + Para Setclassid, si no se especifica algn 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. ""Conexin al area local 1"" o\n \ + ""Conexin al area local 2""\n" +END diff --git a/base/applications/network/ping/lang/it-IT.rc b/base/applications/network/ping/lang/it-IT.rc index 211918a158b..f23a0f8f1ca 100644 --- a/base/applications/network/ping/lang/it-IT.rc +++ b/base/applications/network/ping/lang/it-IT.rc @@ -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" diff --git a/base/applications/notepad/notepad.h b/base/applications/notepad/notepad.h index bc910ab275e..909eca20b56 100644 --- a/base/applications/notepad/notepad.h +++ b/base/applications/notepad/notepad.h @@ -1,3 +1,7 @@ +#ifndef STRSAFE_NO_DEPRECATE +#define STRSAFE_NO_DEPRECATE +#endif + #include #include #include diff --git a/base/applications/paint/dialogs.h b/base/applications/paint/dialogs.h index 4378045ecc5..377a3198d5e 100644 --- a/base/applications/paint/dialogs.h +++ b/base/applications/paint/dialogs.h @@ -10,4 +10,4 @@ int mirrorRotateDlg(void); int attributesDlg(void); -int changeSizeDlg(); +int changeSizeDlg(void); diff --git a/base/applications/rapps/rapps/firefox2.txt b/base/applications/rapps/rapps/firefox2.txt index 816bf597e62..efb7f8b514c 100644 --- a/base/applications/rapps/rapps/firefox2.txt +++ b/base/applications/rapps/rapps/firefox2.txt @@ -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 diff --git a/base/applications/rapps/rapps/firefox3.txt b/base/applications/rapps/rapps/firefox3.txt index 76855309d81..065202dd921 100644 --- a/base/applications/rapps/rapps/firefox3.txt +++ b/base/applications/rapps/rapps/firefox3.txt @@ -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 diff --git a/base/applications/rapps/rapps/firefox36.txt b/base/applications/rapps/rapps/firefox36.txt index d8a96e71e56..4f5d3b8c96b 100644 --- a/base/applications/rapps/rapps/firefox36.txt +++ b/base/applications/rapps/rapps/firefox36.txt @@ -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 diff --git a/base/applications/rapps/rapps/openoffice2.4.txt b/base/applications/rapps/rapps/openoffice2.4.txt index f2bc9ec0578..907712013be 100644 --- a/base/applications/rapps/rapps/openoffice2.4.txt +++ b/base/applications/rapps/rapps/openoffice2.4.txt @@ -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 diff --git a/base/applications/rapps/rapps/seamonkey.txt b/base/applications/rapps/rapps/seamonkey.txt index 82e5a0401ff..2564895cac8 100644 --- a/base/applications/rapps/rapps/seamonkey.txt +++ b/base/applications/rapps/rapps/seamonkey.txt @@ -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 diff --git a/base/applications/rapps/rapps/sumatrapdf.txt b/base/applications/rapps/rapps/sumatrapdf.txt index abb9bc6926e..1e142ed113a 100644 --- a/base/applications/rapps/rapps/sumatrapdf.txt +++ b/base/applications/rapps/rapps/sumatrapdf.txt @@ -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. diff --git a/base/applications/rapps/rapps/thunderbird.txt b/base/applications/rapps/rapps/thunderbird.txt index 644933e5867..e91eb6c7182 100644 --- a/base/applications/rapps/rapps/thunderbird.txt +++ b/base/applications/rapps/rapps/thunderbird.txt @@ -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 diff --git a/base/applications/rapps/rapps/winboard.txt b/base/applications/rapps/rapps/winboard.txt index 9e58a153fd0..a7a0db6ffb5 100644 --- a/base/applications/rapps/rapps/winboard.txt +++ b/base/applications/rapps/rapps/winboard.txt @@ -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] diff --git a/base/applications/rapps/winmain.c b/base/applications/rapps/winmain.c index 33e6f6f9e0a..9f6a0fc65f7 100644 --- a/base/applications/rapps/winmain.c +++ b/base/applications/rapps/winmain.c @@ -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); diff --git a/base/applications/regedit/childwnd.c b/base/applications/regedit/childwnd.c index 005432c2bbd..fcf5db21a03 100644 --- a/base/applications/regedit/childwnd.c +++ b/base/applications/regedit/childwnd.c @@ -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.xnSplitPos+SPLIT_WIDTH/2+1) + if (pt.x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && pt.xnSplitPos+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 && xnSplitPos+SPLIT_WIDTH/2+1) + if (x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && xnSplitPos+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: diff --git a/base/applications/shutdown/lang/es-ES.rc b/base/applications/shutdown/lang/es-ES.rc new file mode 100644 index 00000000000..47a5f45296e --- /dev/null +++ b/base/applications/shutdown/lang/es-ES.rc @@ -0,0 +1,14 @@ +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +BEGIN + +IDS_USAGE, "Utilizacin: shutdown [-?] [-l | -s | -r] [-f]\n\n\ + Ningn 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 ejecucin a apagarse sin advertencias\n\ + \t\t\tSi no especifica algn otro parmetro, esta opcin\n\ + \t\t\tprovocar tambin una desconexin" +END diff --git a/base/applications/shutdown/rsrc.rc b/base/applications/shutdown/rsrc.rc index eda9b52beb0..c06b62f28f9 100644 --- a/base/applications/shutdown/rsrc.rc +++ b/base/applications/shutdown/rsrc.rc @@ -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" diff --git a/base/setup/reactos/lang/cs-CZ.rc b/base/setup/reactos/lang/cs-CZ.rc index 2ee2f142c9a..505042b65f9 100644 --- a/base/setup/reactos/lang/cs-CZ.rc +++ b/base/setup/reactos/lang/cs-CZ.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 diff --git a/base/setup/reactos/lang/de-DE.rc b/base/setup/reactos/lang/de-DE.rc index 4c44f64b83c..1c8a1f4fb0e 100644 --- a/base/setup/reactos/lang/de-DE.rc +++ b/base/setup/reactos/lang/de-DE.rc @@ -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 diff --git a/base/setup/reactos/lang/en-US.rc b/base/setup/reactos/lang/en-US.rc index b548ba979fc..e0f4eccf865 100644 --- a/base/setup/reactos/lang/en-US.rc +++ b/base/setup/reactos/lang/en-US.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 diff --git a/base/setup/reactos/lang/fr-FR.rc b/base/setup/reactos/lang/fr-FR.rc index 17655c95e5b..68e3cc1a41a 100644 --- a/base/setup/reactos/lang/fr-FR.rc +++ b/base/setup/reactos/lang/fr-FR.rc @@ -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 diff --git a/base/setup/reactos/lang/pl-PL.rc b/base/setup/reactos/lang/pl-PL.rc index 31c951397cf..2a3a4ea6bad 100644 --- a/base/setup/reactos/lang/pl-PL.rc +++ b/base/setup/reactos/lang/pl-PL.rc @@ -4,6 +4,7 @@ * https://sourceforge.net/projects/reactospl * http://rogers.cyberdusk.pl/ * update - niski (bjauy@o2.pl) + * 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 diff --git a/base/setup/reactos/lang/sk-SK.rc b/base/setup/reactos/lang/sk-SK.rc index 56ff08c7e5b..6cbeb134664 100644 --- a/base/setup/reactos/lang/sk-SK.rc +++ b/base/setup/reactos/lang/sk-SK.rc @@ -1,6 +1,6 @@ /* TRANSLATOR : Mrio Kamr /Mario Kacmar/ aka Kario (kario@szm.sk) * 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 "Intalcia zavdzaa systmu", IDC_STATIC, "Button", BS_GROUPBOX, 4,36,298,41 - CONTROL "Naintalova zavdza systmu na pevn disk (MBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 - CONTROL "Nenaintalova zavdza systmu", IDC_NOINSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED , 10,57,278,11 + CONTROL "Naintalova zavdza systmu na pevn disk (MBR a VBR)", IDC_INSTFREELDR, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,46,278,11 + CONTROL "Naintalova zavdza systmu na pevn disk (iba VBR)", IDC_INSTVBRONLY, "Button", BS_AUTORADIOBUTTON | WS_TABSTOP, 10,57,278,11 + CONTROL "Nenaintalova zavdza systmu", 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 "&Zrui", IDCANCEL, 240,83,50,15, WS_TABSTOP | WS_VISIBLE END diff --git a/base/setup/reactos/resource.h b/base/setup/reactos/resource.h index f4d6b2210bf..82e9d7c6fcd 100644 --- a/base/setup/reactos/resource.h +++ b/base/setup/reactos/resource.h @@ -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 diff --git a/base/setup/usetup/partlist.c b/base/setup/usetup/partlist.c index 7e2c7510976..52a0259d99e 100644 --- a/base/setup/usetup/partlist.c +++ b/base/setup/usetup/partlist.c @@ -944,6 +944,7 @@ CreatePartitionList (SHORT Left, List->Bottom = Bottom; List->Line = 0; + List->Offset = 0; List->TopDisk = (ULONG)-1; List->TopPartition = (ULONG)-1; diff --git a/base/shell/explorer/externals.h b/base/shell/explorer/externals.h index 0d3eb518ef6..5e9d5fa0794 100644 --- a/base/shell/explorer/externals.h +++ b/base/shell/explorer/externals.h @@ -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); diff --git a/base/shell/explorer/notifyhook/notifyhook.h b/base/shell/explorer/notifyhook/notifyhook.h index 0982d71113e..bfa4b356156 100644 --- a/base/shell/explorer/notifyhook/notifyhook.h +++ b/base/shell/explorer/notifyhook/notifyhook.h @@ -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); diff --git a/base/system/services/rpcserver.c b/base/system/services/rpcserver.c index cc45ff5f1e4..9c42b81cfa0 100644 --- a/base/system/services/rpcserver.c +++ b/base/system/services/rpcserver.c @@ -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) { diff --git a/boot/freeldr/freeldr/arch/powerpc/compat.h b/boot/freeldr/freeldr/arch/powerpc/compat.h index 3bc1b7998d7..b81894233ec 100644 --- a/boot/freeldr/freeldr/arch/powerpc/compat.h +++ b/boot/freeldr/freeldr/arch/powerpc/compat.h @@ -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); diff --git a/boot/freeldr/freeldr/arch/powerpc/prep.h b/boot/freeldr/freeldr/arch/powerpc/prep.h index ea03fa0ae1f..4761d8f9c15 100644 --- a/boot/freeldr/freeldr/arch/powerpc/prep.h +++ b/boot/freeldr/freeldr/arch/powerpc/prep.h @@ -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 ); diff --git a/boot/freeldr/freeldr/include/arch/amd64/amd64.h b/boot/freeldr/freeldr/include/arch/amd64/amd64.h index 9068e00f90a..e5c73d4b4e5 100644 --- a/boot/freeldr/freeldr/include/arch/amd64/amd64.h +++ b/boot/freeldr/freeldr/include/arch/amd64/amd64.h @@ -58,7 +58,7 @@ typedef struct _PAGE_DIRECTORY_AMD64 } PAGE_DIRECTORY_AMD64, *PPAGE_DIRECTORY_AMD64; -VOID FrLdrSetupGdtIdt(); +VOID FrLdrSetupGdtIdt(VOID); #endif diff --git a/boot/freeldr/freeldr/include/arch/amd64/machpc.h b/boot/freeldr/freeldr/include/arch/amd64/machpc.h index 2efd7e8c74a..efcf293dcab 100644 --- a/boot/freeldr/freeldr/include/arch/amd64/machpc.h +++ b/boot/freeldr/freeldr/include/arch/amd64/machpc.h @@ -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); diff --git a/boot/freeldr/freeldr/include/machine.h b/boot/freeldr/freeldr/include/machine.h index 65952056faa..ba2be4fdf6a 100644 --- a/boot/freeldr/freeldr/include/machine.h +++ b/boot/freeldr/freeldr/include/machine.h @@ -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); diff --git a/dll/cpl/desk/lang/bg-BG.rc b/dll/cpl/desk/lang/bg-BG.rc index ad7e006fb9d..bf54e27e10e 100644 --- a/dll/cpl/desk/lang/bg-BG.rc +++ b/dll/cpl/desk/lang/bg-BG.rc @@ -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 diff --git a/dll/cpl/desk/lang/cs-CZ.rc b/dll/cpl/desk/lang/cs-CZ.rc index 0ca4627f511..717e214d7d8 100644 --- a/dll/cpl/desk/lang/cs-CZ.rc +++ b/dll/cpl/desk/lang/cs-CZ.rc @@ -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 diff --git a/dll/cpl/desk/lang/el-GR.rc b/dll/cpl/desk/lang/el-GR.rc index e9988ab2b53..9c832b0846b 100644 --- a/dll/cpl/desk/lang/el-GR.rc +++ b/dll/cpl/desk/lang/el-GR.rc @@ -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 diff --git a/dll/cpl/desk/lang/fr-FR.rc b/dll/cpl/desk/lang/fr-FR.rc index 1158e2cde64..0bdebbc73ed 100644 --- a/dll/cpl/desk/lang/fr-FR.rc +++ b/dll/cpl/desk/lang/fr-FR.rc @@ -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 diff --git a/dll/cpl/desk/lang/hu-HU.rc b/dll/cpl/desk/lang/hu-HU.rc index 874408398e1..202fe1559fd 100644 --- a/dll/cpl/desk/lang/hu-HU.rc +++ b/dll/cpl/desk/lang/hu-HU.rc @@ -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 diff --git a/dll/cpl/desk/lang/id-ID.rc b/dll/cpl/desk/lang/id-ID.rc index c081f87009c..be3a3803d0f 100644 --- a/dll/cpl/desk/lang/id-ID.rc +++ b/dll/cpl/desk/lang/id-ID.rc @@ -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 diff --git a/dll/cpl/desk/lang/it-IT.rc b/dll/cpl/desk/lang/it-IT.rc index 7e21fbc95ed..30af0cd3ded 100644 --- a/dll/cpl/desk/lang/it-IT.rc +++ b/dll/cpl/desk/lang/it-IT.rc @@ -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 diff --git a/dll/cpl/desk/lang/nl-NL.rc b/dll/cpl/desk/lang/nl-NL.rc index 74f1842a013..9165bcecee1 100644 --- a/dll/cpl/desk/lang/nl-NL.rc +++ b/dll/cpl/desk/lang/nl-NL.rc @@ -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 diff --git a/dll/cpl/desk/lang/no-NO.rc b/dll/cpl/desk/lang/no-NO.rc index 61edf39a2fd..5c6494fa9e6 100644 --- a/dll/cpl/desk/lang/no-NO.rc +++ b/dll/cpl/desk/lang/no-NO.rc @@ -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 diff --git a/dll/cpl/desk/lang/pl-PL.rc b/dll/cpl/desk/lang/pl-PL.rc index 436b9d40f6c..80c38df7b7d 100644 --- a/dll/cpl/desk/lang/pl-PL.rc +++ b/dll/cpl/desk/lang/pl-PL.rc @@ -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 przecigania",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 podkrelenie liter do nawigacji klawiatur dopki nie nacisn klawisza Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Anuluj", IDCANCEL, 226, 165, 50, 14 diff --git a/dll/cpl/desk/lang/ro-RO.rc b/dll/cpl/desk/lang/ro-RO.rc index 39b0b41c41e..e74329a20f0 100644 --- a/dll/cpl/desk/lang/ro-RO.rc +++ b/dll/cpl/desk/lang/ro-RO.rc @@ -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 diff --git a/dll/cpl/desk/lang/ru-RU.rc b/dll/cpl/desk/lang/ru-RU.rc index 519da21015f..dad783a73ee 100644 --- a/dll/cpl/desk/lang/ru-RU.rc +++ b/dll/cpl/desk/lang/ru-RU.rc @@ -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 "& ",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "", IDCANCEL, 226, 165, 50, 14 diff --git a/dll/cpl/desk/lang/sk-SK.rc b/dll/cpl/desk/lang/sk-SK.rc index 0743898065c..ec8bfcee042 100644 --- a/dll/cpl/desk/lang/sk-SK.rc +++ b/dll/cpl/desk/lang/sk-SK.rc @@ -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 poas presvania",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 CONTROL "&Skrva podiarknut psmen (klvesov skratky) a do stlaenia klvesu Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "Zrui", IDCANCEL, 226, 165, 50, 14 diff --git a/dll/cpl/desk/lang/sv-SE.rc b/dll/cpl/desk/lang/sv-SE.rc index 49f8c7bda2c..b73e7fa6ca6 100644 --- a/dll/cpl/desk/lang/sv-SE.rc +++ b/dll/cpl/desk/lang/sv-SE.rc @@ -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 diff --git a/dll/cpl/desk/lang/uk-UA.rc b/dll/cpl/desk/lang/uk-UA.rc index bcbefe72481..ff8888a85a9 100644 --- a/dll/cpl/desk/lang/uk-UA.rc +++ b/dll/cpl/desk/lang/uk-UA.rc @@ -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 "& ",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 PUSHBUTTON "", IDCANCEL, 226, 165, 50, 14 diff --git a/dll/cpl/desk/lang/zh-CN.rc b/dll/cpl/desk/lang/zh-CN.rc index f09d566fa7f..0cd960d51ca 100644 --- a/dll/cpl/desk/lang/zh-CN.rc +++ b/dll/cpl/desk/lang/zh-CN.rc @@ -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 diff --git a/dll/cpl/input/settings.c b/dll/cpl/input/settings.c index 393359dd7a2..5f1ca81e066 100644 --- a/dll/cpl/input/settings.c +++ b/dll/cpl/input/settings.c @@ -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; } diff --git a/dll/ntdll/CMakeLists.txt b/dll/ntdll/CMakeLists.txt index aab01f16052..dff520c4a0d 100644 --- a/dll/ntdll/CMakeLists.txt +++ b/dll/ntdll/CMakeLists.txt @@ -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 diff --git a/dll/ntdll/include/ntdllp.h b/dll/ntdll/include/ntdllp.h index b413f3840bb..a01a960cef2 100644 --- a/dll/ntdll/include/ntdllp.h +++ b/dll/ntdll/include/ntdllp.h @@ -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; diff --git a/dll/ntdll/ldr/ldrapi.c b/dll/ntdll/ldr/ldrapi.c new file mode 100644 index 00000000000..0a19351dab8 --- /dev/null +++ b/dll/ntdll/ldr/ldrapi.c @@ -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 (alex@relsoft.net) + * Aleksey Bragin (aleksey@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* 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 */ diff --git a/dll/ntdll/ldr/ldrinit.c b/dll/ntdll/ldr/ldrinit.c index 77baa0a5ed8..cccaa4ee4f3 100644 --- a/dll/ntdll/ldr/ldrinit.c +++ b/dll/ntdll/ldr/ldrinit.c @@ -19,6 +19,69 @@ HKEY ImageExecOptionsKey; HKEY Wow64ExecOptionsKey; UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"); UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L""); +UNICODE_STRING NtDllString = RTL_CONSTANT_STRING(L"ntdll.dll"); + +BOOLEAN LdrpInLdrInit; +LONG LdrpProcessInitialized; +BOOLEAN LdrpLoaderLockInit; +BOOLEAN LdrpLdrDatabaseIsSetup; + +BOOLEAN LdrpDllValidation; + +PLDR_DATA_TABLE_ENTRY LdrpImageEntry; +PUNICODE_STRING LdrpTopLevelDllBeingLoaded; +extern PTEB LdrpTopLevelDllBeingLoadedTeb; // defined in rtlsupp.c! +PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer; +PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry; + +RTL_BITMAP TlsBitMap; +RTL_BITMAP TlsExpansionBitMap; +RTL_BITMAP FlsBitMap; +BOOLEAN LdrpImageHasTls; +LIST_ENTRY LdrpTlsList; +ULONG LdrpNumberOfTlsEntries; +ULONG LdrpNumberOfProcessors; +PVOID NtDllBase; +LARGE_INTEGER RtlpTimeout; +BOOLEAN RtlpTimeoutDisable; +LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]; +LIST_ENTRY LdrpDllNotificationList; +HANDLE LdrpKnownDllObjectDirectory; +UNICODE_STRING LdrpKnownDllPath; +WCHAR LdrpKnownDllPathBuffer[128]; +UNICODE_STRING LdrpDefaultPath; + +PEB_LDR_DATA PebLdr; + +RTL_CRITICAL_SECTION_DEBUG LdrpLoaderLockDebug; +RTL_CRITICAL_SECTION LdrpLoaderLock = +{ + &LdrpLoaderLockDebug, + -1, + 0, + 0, + 0, + 0 +}; +RTL_CRITICAL_SECTION FastPebLock; + +BOOLEAN ShowSnaps; + +ULONG LdrpFatalHardErrorCount; + +//extern LIST_ENTRY RtlCriticalSectionList; + +VOID RtlpInitializeVectoredExceptionHandling(VOID); +VOID NTAPI RtlpInitDeferedCriticalSection(VOID); +VOID RtlInitializeHeapManager(VOID); +extern BOOLEAN RtlpPageHeapEnabled; +extern ULONG RtlpDphGlobalFlags; + +NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase); +NTSTATUS NTAPI +LdrpInitializeProcess_(PCONTEXT Context, + PVOID SystemArgument1); + /* FUNCTIONS *****************************************************************/ @@ -317,4 +380,1274 @@ LdrQueryImageFileExecutionOptions(IN PUNICODE_STRING SubKey, FALSE); } +VOID +NTAPI +LdrpEnsureLoaderLockIsHeld() +{ + // Ignored atm +} + +PVOID +NTAPI +LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage) +{ + PIMAGE_LOAD_CONFIG_DIRECTORY ConfigDir; + ULONG DirSize; + PVOID Cookie = NULL; + + /* Check NT header first */ + if (!RtlImageNtHeader(BaseAddress)) return NULL; + + /* Get the pointer to the config directory */ + ConfigDir = RtlImageDirectoryEntryToData(BaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, + &DirSize); + + /* Check for sanity */ + if (!ConfigDir || + (DirSize != 64 && ConfigDir->Size != DirSize) || + (ConfigDir->Size < 0x48)) + return NULL; + + /* Now get the cookie */ + Cookie = (PVOID)ConfigDir->SecurityCookie; + + /* Check this cookie */ + if (Cookie == NULL || + (PCHAR)Cookie <= (PCHAR)BaseAddress || + (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage) + { + Cookie = NULL; + } + + /* Return validated security cookie */ + return Cookie; +} + +PVOID +NTAPI +LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry) +{ + PVOID Cookie; + + /* Fetch address of the cookie */ + Cookie = LdrpFetchAddressOfSecurityCookie(LdrEntry->DllBase, LdrEntry->SizeOfImage); + + if (Cookie) + { + UNIMPLEMENTED; + Cookie = NULL; + } + + return Cookie; +} + +NTSTATUS +NTAPI +LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL) +{ + PLDR_DATA_TABLE_ENTRY LocalArray[16]; + PLIST_ENTRY ListHead; + PLIST_ENTRY NextEntry; + PLDR_DATA_TABLE_ENTRY LdrEntry, *LdrRootEntry, OldInitializer; + PVOID EntryPoint; + ULONG Count, i; + //ULONG BreakOnInit; + NTSTATUS Status = STATUS_SUCCESS; + PPEB Peb = NtCurrentPeb(); + RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx; + ULONG BreakOnDllLoad; + PTEB OldTldTeb; + BOOLEAN DllStatus; + + DPRINT("LdrpRunInitializeRoutines() called for %wZ\n", &LdrpImageEntry->BaseDllName); + + /* Check the Loader Lock */ + LdrpEnsureLoaderLockIsHeld(); + + /* Get the number of entries to call */ + if ((Count = LdrpClearLoadInProgress())) + { + /* Check if we can use our local buffer */ + if (Count > 16) + { + /* Allocate space for all the entries */ + LdrRootEntry = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + Count * sizeof(LdrRootEntry)); + if (!LdrRootEntry) return STATUS_NO_MEMORY; + } + else + { + /* Use our local array */ + LdrRootEntry = LocalArray; + } + } + else + { + /* Don't need one */ + LdrRootEntry = NULL; + } + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("[%x,%x] LDR: Real INIT LIST for Process %wZ\n", + NtCurrentTeb()->RealClientId.UniqueThread, + NtCurrentTeb()->RealClientId.UniqueProcess, + &Peb->ProcessParameters->ImagePathName); + } + + /* Loop in order */ + ListHead = &Peb->Ldr->InInitializationOrderModuleList; + NextEntry = ListHead->Flink; + i = 0; + while (NextEntry != ListHead) + { + /* Get the Data Entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); + + /* Check if we have a Root Entry */ + if (LdrRootEntry) + { + /* Check flags */ + if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED)) + { + /* Setup the Cookie for the DLL */ + LdrpInitSecurityCookie(LdrEntry); + + /* Check for valid entrypoint */ + if (LdrEntry->EntryPoint) + { + /* Write in array */ + LdrRootEntry[i] = LdrEntry; + + /* Display debug message */ + if (ShowSnaps) + { + DPRINT1("[%x,%x] LDR: %wZ init routine %p\n", + NtCurrentTeb()->RealClientId.UniqueThread, + NtCurrentTeb()->RealClientId.UniqueProcess, + &LdrEntry->FullDllName, + LdrEntry->EntryPoint); + } + i++; + } + } + } + + /* Set the flag */ + LdrEntry->Flags |= LDRP_ENTRY_PROCESSED; + NextEntry = NextEntry->Flink; + } + + /* If we got a context, then we have to call Kernel32 for TS support */ + if (Context) + { + /* Check if we have one */ + //if (Kernel32ProcessInitPostImportfunction) + //{ + /* Call it */ + //Kernel32ProcessInitPostImportfunction(); + //} + + /* Clear it */ + //Kernel32ProcessInitPostImportfunction = NULL; + UNIMPLEMENTED; + } + + /* No root entry? return */ + if (!LdrRootEntry) return STATUS_SUCCESS; + + /* Set the TLD TEB */ + OldTldTeb = LdrpTopLevelDllBeingLoadedTeb; + LdrpTopLevelDllBeingLoadedTeb = NtCurrentTeb(); + + /* Loop */ + i = 0; + while (i < Count) + { + /* Get an entry */ + LdrEntry = LdrRootEntry[i]; + + /* FIXME: Verify NX Compat */ + + /* Move to next entry */ + i++; + + /* Get its entrypoint */ + EntryPoint = LdrEntry->EntryPoint; + + /* Are we being debugged? */ + BreakOnDllLoad = 0; + if (Peb->BeingDebugged || Peb->ReadImageFileExecOptions) + { + /* Check if we should break on load */ + Status = LdrQueryImageFileExecutionOptions(&LdrEntry->BaseDllName, + L"BreakOnDllLoad", + REG_DWORD, + &BreakOnDllLoad, + sizeof(ULONG), + NULL); + if (!NT_SUCCESS(Status)) BreakOnDllLoad = 0; + } + + /* Break if aksed */ + if (BreakOnDllLoad) + { + /* Check if we should show a message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ loaded.", &LdrEntry->BaseDllName); + DPRINT1(" - About to call init routine at %p\n", EntryPoint); + } + + /* Break in debugger */ + DbgBreakPoint(); + } + + /* Make sure we have an entrypoint */ + if (EntryPoint) + { + /* Save the old Dll Initializer and write the current one */ + OldInitializer = LdrpCurrentDllInitializer; + LdrpCurrentDllInitializer = LdrEntry; + + /* Set up the Act Ctx */ + ActCtx.Size = sizeof(ActCtx); + ActCtx.Frame.Flags = ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID; + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + + /* Activate the ActCtx */ + RtlActivateActivationContextUnsafeFast(&ActCtx, + LdrEntry->EntryPointActivationContext); + + /* Check if it has TLS */ + if (LdrEntry->TlsIndex && Context) + { + /* Call TLS */ + LdrpTlsCallback(LdrEntry->DllBase, DLL_PROCESS_ATTACH); + } + + /* Call the Entrypoint */ + if (ShowSnaps) + { + DPRINT1("%wZ - Calling entry point at %p for DLL_PROCESS_ATTACH\n", + &LdrEntry->BaseDllName, EntryPoint); + } + DllStatus = LdrpCallDllEntry(EntryPoint, + LdrEntry->DllBase, + DLL_PROCESS_ATTACH, + Context); + + /* Deactivate the ActCtx */ + RtlDeactivateActivationContextUnsafeFast(&ActCtx); + + /* Save the Current DLL Initializer */ + LdrpCurrentDllInitializer = OldInitializer; + + /* Mark the entry as processed */ + LdrEntry->Flags |= LDRP_PROCESS_ATTACH_CALLED; + + /* Fail if DLL init failed */ + if (!DllStatus) + { + DPRINT1("LDR: DLL_PROCESS_ATTACH for dll \"%wZ\" (InitRoutine: %p) failed\n", + &LdrEntry->BaseDllName, EntryPoint); + + Status = STATUS_DLL_INIT_FAILED; + goto Quickie; + } + } + } + + /* Loop in order */ + ListHead = &Peb->Ldr->InInitializationOrderModuleList; + NextEntry = NextEntry->Flink; + while (NextEntry != ListHead) + { + /* Get the Data Entrry */ + LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList); + + /* FIXME: Verify NX Compat */ + // LdrpCheckNXCompatibility() + + /* Next entry */ + NextEntry = NextEntry->Flink; + } + + /* Check for TLS */ + if (LdrpImageHasTls && Context) + { + /* Set up the Act Ctx */ + ActCtx.Size = sizeof(ActCtx); + ActCtx.Frame.Flags = ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID; + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + + /* Activate the ActCtx */ + RtlActivateActivationContextUnsafeFast(&ActCtx, + LdrpImageEntry->EntryPointActivationContext); + + /* Do TLS callbacks */ + LdrpTlsCallback(Peb->ImageBaseAddress, DLL_PROCESS_ATTACH); + + /* Deactivate the ActCtx */ + RtlDeactivateActivationContextUnsafeFast(&ActCtx); + } + +Quickie: + /* Restore old TEB */ + LdrpTopLevelDllBeingLoadedTeb = OldTldTeb; + + /* Check if the array is in the heap */ + if (LdrRootEntry != LocalArray) + { + /* Free the array */ + RtlFreeHeap(RtlGetProcessHeap(), 0, LdrRootEntry); + } + + /* Return to caller */ + DPRINT("LdrpRunInitializeRoutines() done\n"); + return Status; +} + +NTSTATUS +NTAPI +LdrpInitializeTls(VOID) +{ + PLIST_ENTRY NextEntry, ListHead; + PLDR_DATA_TABLE_ENTRY LdrEntry; + PIMAGE_TLS_DIRECTORY TlsDirectory; + PLDRP_TLS_DATA TlsData; + ULONG Size; + + /* Initialize the TLS List */ + InitializeListHead(&LdrpTlsList); + + /* Loop all the modules */ + ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) + { + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + NextEntry = NextEntry->Flink; + + /* Get the TLS directory */ + TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_TLS, + &Size); + + /* Check if we have a directory */ + if (!TlsDirectory) continue; + + /* Check if the image has TLS */ + if (!LdrpImageHasTls) LdrpImageHasTls = TRUE; + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: Tls Found in %wZ at %p\n", + &LdrEntry->BaseDllName, + TlsDirectory); + } + + /* Allocate an entry */ + TlsData = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LDRP_TLS_DATA)); + if (!TlsData) return STATUS_NO_MEMORY; + + /* Lock the DLL and mark it for TLS Usage */ + LdrEntry->LoadCount = -1; + LdrEntry->TlsIndex = -1; + + /* Save the cached TLS data */ + TlsData->TlsDirectory = *TlsDirectory; + InsertTailList(&LdrpTlsList, &TlsData->TlsLinks); + + /* Update the index */ + *(PLONG)TlsData->TlsDirectory.AddressOfIndex = LdrpNumberOfTlsEntries; + TlsData->TlsDirectory.Characteristics = LdrpNumberOfTlsEntries++; + } + + /* Done setting up TLS, allocate entries */ + return LdrpAllocateTls(); +} + +NTSTATUS +NTAPI +LdrpAllocateTls(VOID) +{ + PTEB Teb = NtCurrentTeb(); + PLIST_ENTRY NextEntry, ListHead; + PLDRP_TLS_DATA TlsData; + ULONG TlsDataSize; + PVOID *TlsVector; + + /* Check if we have any entries */ + if (LdrpNumberOfTlsEntries) + return 0; + + /* Allocate the vector array */ + TlsVector = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + LdrpNumberOfTlsEntries * sizeof(PVOID)); + if (!TlsVector) return STATUS_NO_MEMORY; + Teb->ThreadLocalStoragePointer = TlsVector; + + /* Loop the TLS Array */ + ListHead = &LdrpTlsList; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the entry */ + TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks); + NextEntry = NextEntry->Flink; + + /* Allocate this vector */ + TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData - + TlsData->TlsDirectory.StartAddressOfRawData; + TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + TlsDataSize); + if (!TlsVector[TlsData->TlsDirectory.Characteristics]) + { + /* Out of memory */ + return STATUS_NO_MEMORY; + } + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: TlsVector %x Index %d = %x copied from %x to %x\n", + TlsVector, + TlsData->TlsDirectory.Characteristics, + &TlsVector[TlsData->TlsDirectory.Characteristics], + TlsData->TlsDirectory.StartAddressOfRawData, + TlsVector[TlsData->TlsDirectory.Characteristics]); + } + + /* Copy the data */ + RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics], + (PVOID)TlsData->TlsDirectory.StartAddressOfRawData, + TlsDataSize); + } + + /* Done */ + return STATUS_SUCCESS; +} + +VOID +NTAPI +LdrpFreeTls(VOID) +{ + PLIST_ENTRY ListHead, NextEntry; + PLDRP_TLS_DATA TlsData; + PVOID *TlsVector; + PTEB Teb = NtCurrentTeb(); + + /* Get a pointer to the vector array */ + TlsVector = Teb->ThreadLocalStoragePointer; + if (!TlsVector) return; + + /* Loop through it */ + ListHead = &LdrpTlsList; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks); + NextEntry = NextEntry->Flink; + + /* Free each entry */ + if (TlsVector[TlsData->TlsDirectory.Characteristics]) + { + RtlFreeHeap(RtlGetProcessHeap(), + 0, + TlsVector[TlsData->TlsDirectory.Characteristics]); + } + } + + /* Free the array itself */ + RtlFreeHeap(RtlGetProcessHeap(), + 0, + TlsVector); +} + +NTSTATUS +NTAPI +LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PULONG Options) +{ + UNIMPLEMENTED; + *Options = 0; + return STATUS_SUCCESS; +} + +VOID +NTAPI +LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry) +{ + UNIMPLEMENTED; +} + +NTSTATUS +NTAPI +LdrpInitializeProcess(IN PCONTEXT Context, + IN PVOID SystemArgument1) +{ + RTL_HEAP_PARAMETERS HeapParameters; + ULONG ComSectionSize; + //ANSI_STRING FunctionName = RTL_CONSTANT_STRING("BaseQueryModuleData"); + PVOID OldShimData; + OBJECT_ATTRIBUTES ObjectAttributes; + //UNICODE_STRING LocalFileName, FullImageName; + HANDLE SymLinkHandle; + //ULONG DebugHeapOnly; + UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString; + PPEB Peb = NtCurrentPeb(); + BOOLEAN IsDotNetImage = FALSE; + BOOLEAN FreeCurDir = FALSE; + //HKEY CompatKey; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + //LPWSTR ImagePathBuffer; + ULONG ConfigSize; + UNICODE_STRING CurrentDirectory; + ULONG ExecuteOptions; + ULONG HeapFlags; + PIMAGE_NT_HEADERS NtHeader; + LPWSTR NtDllName = NULL; + NTSTATUS Status; + NLSTABLEINFO NlsTable; + PIMAGE_LOAD_CONFIG_DIRECTORY LoadConfig; + PTEB Teb = NtCurrentTeb(); + PLIST_ENTRY ListHead; + PLIST_ENTRY NextEntry; + ULONG i; + PWSTR ImagePath; + ULONG DebugProcessHeapOnly = 0; + WCHAR FullNtDllPath[MAX_PATH]; + PLDR_DATA_TABLE_ENTRY NtLdrEntry; + PWCHAR Current; + + /* Set a NULL SEH Filter */ + RtlSetUnhandledExceptionFilter(NULL); + + /* Get the image path */ + ImagePath = Peb->ProcessParameters->ImagePathName.Buffer; + + /* Check if it's normalized */ + if (Peb->ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_NORMALIZED) + { + /* Normalize it*/ + ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters); + } + + /* Create a unicode string for the Image Path */ + ImagePathName.Length = Peb->ProcessParameters->ImagePathName.Length; + ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR); + ImagePathName.Buffer = ImagePath; + + /* Get the NT Headers */ + NtHeader = RtlImageNtHeader(Peb->ImageBaseAddress); + + /* Get the execution options */ + Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &ExecuteOptions); + + /* Check if this is a .NET executable */ + if (RtlImageDirectoryEntryToData(Peb->ImageBaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, + &ComSectionSize)) + { + /* Remeber this for later */ + IsDotNetImage = TRUE; + } + + /* Save the NTDLL Base address */ + NtDllBase = SystemArgument1; + + /* If this is a Native Image */ + if (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE) + { + /* Then do DLL Validation */ + LdrpDllValidation = TRUE; + } + + /* Save the old Shim Data */ + OldShimData = Peb->pShimData; + + /* Clear it */ + Peb->pShimData = NULL; + + /* Save the number of processors and CS Timeout */ + LdrpNumberOfProcessors = Peb->NumberOfProcessors; + RtlpTimeout = Peb->CriticalSectionTimeout; + + /* Normalize the parameters */ + ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters); + ProcessParameters = Peb->ProcessParameters; + if (ProcessParameters) + { + /* Save the Image and Command Line Names */ + ImageFileName = ProcessParameters->ImagePathName; + CommandLine = ProcessParameters->CommandLine; + } + else + { + /* It failed, initialize empty strings */ + RtlInitUnicodeString(&ImageFileName, NULL); + RtlInitUnicodeString(&CommandLine, NULL); + } + + /* Initialize NLS data */ + RtlInitNlsTables(Peb->AnsiCodePageData, + Peb->OemCodePageData, + Peb->UnicodeCaseTableData, + &NlsTable); + + /* Reset NLS Translations */ + RtlResetRtlTranslations(&NlsTable); + + /* Get the Image Config Directory */ + LoadConfig = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, + &ConfigSize); + + /* Setup the Heap Parameters */ + RtlZeroMemory(&HeapParameters, sizeof(RTL_HEAP_PARAMETERS)); + HeapFlags = HEAP_GROWABLE; + HeapParameters.Length = sizeof(RTL_HEAP_PARAMETERS); + + /* Check if we have Configuration Data */ + if ((LoadConfig) && (ConfigSize == sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))) + { + /* FIXME: Custom heap settings and misc. */ + DPRINT1("We don't support LOAD_CONFIG data yet\n"); + } + + /* Check for custom affinity mask */ + if (Peb->ImageProcessAffinityMask) + { + /* Set it */ + Status = NtSetInformationProcess(NtCurrentProcess(), + ProcessAffinityMask, + &Peb->ImageProcessAffinityMask, + sizeof(Peb->ImageProcessAffinityMask)); + } + + /* Check if verbose debugging (ShowSnaps) was requested */ + ShowSnaps = TRUE;//Peb->NtGlobalFlag & FLG_SHOW_LDR_SNAPS; + + /* Start verbose debugging messages right now if they were requested */ + if (ShowSnaps) + { + DPRINT1("LDR: PID: 0x%x started - '%wZ'\n", + Teb->ClientId.UniqueProcess, + &CommandLine); + } + + /* If the timeout is too long */ + if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000)) + { + /* Then disable CS Timeout */ + RtlpTimeoutDisable = TRUE; + } + + /* Initialize Critical Section Data */ + RtlpInitDeferedCriticalSection(); + + /* Initialize VEH Call lists */ + RtlpInitializeVectoredExceptionHandling(); + + /* Set TLS/FLS Bitmap data */ + Peb->FlsBitmap = &FlsBitMap; + Peb->TlsBitmap = &TlsBitMap; + Peb->TlsExpansionBitmap = &TlsExpansionBitMap; + + /* Initialize FLS Bitmap */ + RtlInitializeBitMap(&FlsBitMap, + Peb->FlsBitmapBits, + FLS_MAXIMUM_AVAILABLE); + RtlSetBit(&FlsBitMap, 0); + + /* Initialize TLS Bitmap */ + RtlInitializeBitMap(&TlsBitMap, + Peb->TlsBitmapBits, + TLS_MINIMUM_AVAILABLE); + RtlSetBit(&TlsBitMap, 0); + RtlInitializeBitMap(&TlsExpansionBitMap, + Peb->TlsExpansionBitmapBits, + TLS_EXPANSION_SLOTS); + RtlSetBit(&TlsExpansionBitMap, 0); + + /* Initialize the Hash Table */ + for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++) + { + InitializeListHead(&LdrpHashTable[i]); + } + + /* Initialize the Loader Lock */ + //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList); + //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock; + UNIMPLEMENTED; + LdrpLoaderLockInit = TRUE; + + /* Check if User Stack Trace Database support was requested */ + if (Peb->NtGlobalFlag & FLG_USER_STACK_TRACE_DB) + { + DPRINT1("We don't support user stack trace databases yet\n"); + } + + /* Setup Fast PEB Lock */ + RtlInitializeCriticalSection(&FastPebLock); + Peb->FastPebLock = &FastPebLock; + //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection; + //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection; + + /* Setup Callout Lock and Notification list */ + //RtlInitializeCriticalSection(&RtlpCalloutEntryLock); + InitializeListHead(&LdrpDllNotificationList); + + /* For old executables, use 16-byte aligned heap */ + if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) && + (NtHeader->OptionalHeader.MinorSubsystemVersion < 51)) + { + HeapFlags |= HEAP_CREATE_ALIGN_16; + } + + /* Setup the Heap */ + RtlInitializeHeapManager(); + Peb->ProcessHeap = RtlCreateHeap(HeapFlags, + NULL, + NtHeader->OptionalHeader.SizeOfHeapReserve, + NtHeader->OptionalHeader.SizeOfHeapCommit, + NULL, + &HeapParameters); + + if (!Peb->ProcessHeap) + { + DPRINT1("Failed to create process heap\n"); + return STATUS_NO_MEMORY; + } + + /* Allocate an Activation Context Stack */ + Status = RtlAllocateActivationContextStack((PVOID *)&Teb->ActivationContextStackPointer); + if (!NT_SUCCESS(Status)) return Status; + + // FIXME: Loader private heap is missing + DPRINT1("Loader private heap is missing\n"); + + /* Check for Debug Heap */ + DPRINT1("Check for a debug heap is missing\n"); + if (FALSE) + { + /* Query the setting */ + Status = LdrQueryImageFileKeyOption(NULL,//hKey + L"DebugProcessHeapOnly", + REG_DWORD, + &DebugProcessHeapOnly, + sizeof(ULONG), + NULL); + + if (NT_SUCCESS(Status)) + { + /* Reset DPH if requested */ + if (RtlpPageHeapEnabled && DebugProcessHeapOnly) + { + RtlpDphGlobalFlags &= ~0x40; + RtlpPageHeapEnabled = FALSE; + } + } + } + + /* Build the NTDLL Path */ + FullPath.Buffer = FullNtDllPath; + FullPath.Length = 0; + FullPath.MaximumLength = sizeof(FullNtDllPath); + RtlInitUnicodeString(&NtSystemRoot, SharedUserData->NtSystemRoot); + RtlAppendUnicodeStringToString(&FullPath, &NtSystemRoot); + RtlAppendUnicodeToString(&FullPath, L"\\System32\\"); + + /* Open the Known DLLs directory */ + RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls"); + InitializeObjectAttributes(&ObjectAttributes, + &KnownDllString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwOpenDirectoryObject(&LdrpKnownDllObjectDirectory, + DIRECTORY_QUERY | DIRECTORY_TRAVERSE, + &ObjectAttributes); + + /* Check if it exists */ + if (!NT_SUCCESS(Status)) + { + /* It doesn't, so assume System32 */ + LdrpKnownDllObjectDirectory = NULL; + RtlInitUnicodeString(&LdrpKnownDllPath, FullPath.Buffer); + LdrpKnownDllPath.Length -= sizeof(WCHAR); + } + else + { + /* Open the Known DLLs Path */ + InitializeObjectAttributes(&ObjectAttributes, + &KnownDllString, + OBJ_CASE_INSENSITIVE, + LdrpKnownDllObjectDirectory, + NULL); + Status = NtOpenSymbolicLinkObject(&SymLinkHandle, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + /* Query the path */ + LdrpKnownDllPath.Length = 0; + LdrpKnownDllPath.MaximumLength = sizeof(LdrpKnownDllPathBuffer); + LdrpKnownDllPath.Buffer = LdrpKnownDllPathBuffer; + Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL); + NtClose(SymLinkHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status); + return Status; + } + } + } + + /* If we have process parameters, get the default path and current path */ + if (ProcessParameters) + { + /* Check if we have a Dll Path */ + if (ProcessParameters->DllPath.Length) + { + /* Get the path */ + LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath; + } + else + { + /* We need a valid path */ + LdrpInitFailure(STATUS_INVALID_PARAMETER); + } + + /* Set the current directory */ + CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath; + + /* Check if it's empty or invalid */ + if ((!CurrentDirectory.Buffer) || + (CurrentDirectory.Buffer[0] == UNICODE_NULL) || + (!CurrentDirectory.Length)) + { + /* Allocate space for the buffer */ + CurrentDirectory.Buffer = RtlAllocateHeap(Peb->ProcessHeap, + 0, + 3 * sizeof(WCHAR) + + sizeof(UNICODE_NULL)); + + /* Copy the drive of the system root */ + RtlMoveMemory(CurrentDirectory.Buffer, + SharedUserData->NtSystemRoot, + 3 * sizeof(WCHAR)); + CurrentDirectory.Buffer[3] = UNICODE_NULL; + CurrentDirectory.Length = 3 * sizeof(WCHAR); + CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR); + + FreeCurDir = TRUE; + } + else + { + /* Use the local buffer */ + CurrentDirectory.Length = NtSystemRoot.Length; + CurrentDirectory.Buffer = NtSystemRoot.Buffer; + } + } + + /* Setup Loader Data */ + Peb->Ldr = &PebLdr; + InitializeListHead(&PebLdr.InLoadOrderModuleList); + InitializeListHead(&PebLdr.InMemoryOrderModuleList); + InitializeListHead(&PebLdr.InInitializationOrderModuleList); + PebLdr.Length = sizeof(PEB_LDR_DATA); + PebLdr.Initialized = TRUE; + + /* Allocate a data entry for the Image */ + LdrpImageEntry = NtLdrEntry = LdrpAllocateDataTableEntry(Peb->ImageBaseAddress); + + /* Set it up */ + NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase); + NtLdrEntry->LoadCount = -1; + NtLdrEntry->EntryPointActivationContext = 0; + NtLdrEntry->FullDllName.Length = ImageFileName.Length; + NtLdrEntry->FullDllName.Buffer = ImageFileName.Buffer; + if (IsDotNetImage) + NtLdrEntry->Flags = LDRP_COR_IMAGE; + else + NtLdrEntry->Flags = 0; + + /* Check if the name is empty */ + if (!ImageFileName.Buffer[0]) + { + /* Use the same Base name */ + NtLdrEntry->BaseDllName = NtLdrEntry->BaseDllName; + } + else + { + /* Find the last slash */ + Current = ImageFileName.Buffer; + while (*Current) + { + if (*Current++ == '\\') + { + /* Set this path */ + NtDllName = Current; + } + } + + /* Did we find anything? */ + if (!NtDllName) + { + /* Use the same Base name */ + NtLdrEntry->BaseDllName = NtLdrEntry->FullDllName; + } + else + { + /* Setup the name */ + NtLdrEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName); + NtLdrEntry->BaseDllName.MaximumLength = NtLdrEntry->BaseDllName.Length + sizeof(WCHAR); + NtLdrEntry->BaseDllName.Buffer = (PWSTR)((ULONG_PTR)ImageFileName.Buffer + + (ImageFileName.Length - NtLdrEntry->BaseDllName.Length)); + } + } + + /* Processing done, insert it */ + LdrpInsertMemoryTableEntry(NtLdrEntry); + NtLdrEntry->Flags |= LDRP_ENTRY_PROCESSED; + + /* Now add an entry for NTDLL */ + NtLdrEntry = LdrpAllocateDataTableEntry(SystemArgument1); + NtLdrEntry->Flags = LDRP_IMAGE_DLL; + NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase); + NtLdrEntry->LoadCount = -1; + NtLdrEntry->EntryPointActivationContext = 0; + //NtLdrEntry->BaseDllName.Length = NtSystemRoot.Length; + //RtlAppendUnicodeStringToString(&NtSystemRoot, &NtDllString); + NtLdrEntry->BaseDllName.Length = NtDllString.Length; + NtLdrEntry->BaseDllName.MaximumLength = NtDllString.MaximumLength; + NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer; + + // FIXME: Full DLL name?! + + /* Processing done, insert it */ + LdrpNtDllDataTableEntry = NtLdrEntry; + LdrpInsertMemoryTableEntry(NtLdrEntry); + + /* Let the world know */ + if (ShowSnaps) + { + DPRINT1("LDR: NEW PROCESS\n"); + DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName); + DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory); + DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath); + } + + /* Link the Init Order List */ + InsertHeadList(&Peb->Ldr->InInitializationOrderModuleList, + &LdrpNtDllDataTableEntry->InInitializationOrderModuleList); + + /* Set the current directory */ + Status = RtlSetCurrentDirectory_U(&CurrentDirectory); + if (!NT_SUCCESS(Status)) + { + /* We failed, check if we should free it */ + if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory); + + /* Set it to the NT Root */ + CurrentDirectory = NtSystemRoot; + RtlSetCurrentDirectory_U(&CurrentDirectory); + } + else + { + /* We're done with it, free it */ + if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory); + } + + /* Check if we should look for a .local file */ + if (ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH) + { + /* FIXME */ + DPRINT1("We don't support .local overrides yet\n"); + } + + /* Check if the Application Verifier was enabled */ + if (Peb->NtGlobalFlag & FLG_POOL_ENABLE_TAIL_CHECK) + { + /* FIXME */ + DPRINT1("We don't support Application Verifier yet\n"); + } + + if (IsDotNetImage) + { + /* FIXME */ + DPRINT1("We don't support .NET applications yet\n"); + } + + /* FIXME: Load support for Terminal Services */ + if (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) + { + /* Load kernel32 and call BasePostImportInit... */ + DPRINT1("Unimplemented codepath!\n"); + } + + /* Walk the IAT and load all the DLLs */ + LdrpWalkImportDescriptor(LdrpDefaultPath.Buffer, LdrpImageEntry); + + /* Check if relocation is needed */ + if (Peb->ImageBaseAddress != (PVOID)NtHeader->OptionalHeader.ImageBase) + { + DPRINT("LDR: Performing relocations\n"); + Status = LdrPerformRelocations(NtHeader, Peb->ImageBaseAddress); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LdrPerformRelocations() failed\n"); + return STATUS_INVALID_IMAGE_FORMAT; + } + } + + /* Lock the DLLs */ + ListHead = &Peb->Ldr->InLoadOrderModuleList; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) + { + NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + NtLdrEntry->LoadCount = -1; + NextEntry = NextEntry->Flink; + } + + /* Phase 0 is done */ + LdrpLdrDatabaseIsSetup = TRUE; + + /* Initialize TLS */ + Status = LdrpInitializeTls(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n", + Status); + return Status; + } + + /* FIXME Mark the DLL Ranges for Stack Traces later */ + + /* Notify the debugger now */ + if (Peb->BeingDebugged) + { + /* Break */ + DbgBreakPoint(); + + /* Update show snaps again */ + ShowSnaps = Peb->NtGlobalFlag & FLG_SHOW_LDR_SNAPS; + } + + /* Validate the Image for MP Usage */ + if (LdrpNumberOfProcessors > 1) LdrpValidateImageForMp(LdrpImageEntry); + + /* Check NX Options */ + if (SharedUserData->NXSupportPolicy == 1) + { + ExecuteOptions = 0xD; + } + else if (!SharedUserData->NXSupportPolicy) + { + ExecuteOptions = 0xA; + } + + /* Let Mm know */ + ZwSetInformationProcess(NtCurrentProcess(), + ProcessExecuteFlags, + &ExecuteOptions, + sizeof(ULONG)); + + /* Check if we had Shim Data */ + if (OldShimData) + { + /* Load the Shim Engine */ + Peb->AppCompatInfo = NULL; + //LdrpLoadShimEngine(OldShimData, ImagePathName, OldShimData); + DPRINT1("We do not support shims yet\n"); + } + else + { + /* Check for Application Compatibility Goo */ + //LdrQueryApplicationCompatibilityGoo(hKey); + DPRINT1("Querying app compat hacks is missing!\n"); + } + + /* + * FIXME: Check for special images, SecuROM, SafeDisc and other NX- + * incompatible images. + */ + + /* Now call the Init Routines */ + Status = LdrpRunInitializeRoutines(Context); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n", + Status); + return Status; + } + + /* FIXME: Unload the Shim Engine if it was loaded */ + + /* Check if we have a user-defined Post Process Routine */ + if (NT_SUCCESS(Status) && Peb->PostProcessInitRoutine) + { + DPRINT1("CP\n"); + /* Call it */ + Peb->PostProcessInitRoutine(); + } + + ///* Close the key if we have one opened */ + //if (hKey) NtClose(hKey); +DbgBreakPoint(); + /* Return status */ + return Status; +} + +VOID +NTAPI +LdrpInitFailure(NTSTATUS Status) +{ + ULONG Response; + + /* Print a debug message */ + DPRINT1("LDR: Process initialization failure; NTSTATUS = %08lx\n", Status); + + /* Raise a hard error */ + if (!LdrpFatalHardErrorCount) + { + ZwRaiseHardError(STATUS_APP_INIT_FAILURE, 1, 0, (PULONG_PTR)&Status, OptionOk, &Response); + } +} + +VOID +NTAPI +LdrpInit(PCONTEXT Context, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + LARGE_INTEGER Timeout; + PTEB Teb = NtCurrentTeb(); + NTSTATUS Status, LoaderStatus = STATUS_SUCCESS; + MEMORY_BASIC_INFORMATION MemoryBasicInfo; + PPEB Peb = NtCurrentPeb(); + + DPRINT("LdrpInit()\n"); + + /* Check if we have a deallocation stack */ + if (!Teb->DeallocationStack) + { + /* We don't, set one */ + Status = NtQueryVirtualMemory(NtCurrentProcess(), + Teb->NtTib.StackLimit, + MemoryBasicInformation, + &MemoryBasicInfo, + sizeof(MEMORY_BASIC_INFORMATION), + NULL); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + LdrpInitFailure(Status); + RtlRaiseStatus(Status); + return; + } + + /* Set the stack */ + Teb->DeallocationStack = MemoryBasicInfo.AllocationBase; + } + + /* Now check if the process is already being initialized */ + while (_InterlockedCompareExchange(&LdrpProcessInitialized, + 1, + 0) == 1) + { + /* Set the timeout to 30 seconds */ + Timeout.QuadPart = Int32x32To64(30, -10000); + + /* Make sure the status hasn't changed */ + while (!LdrpProcessInitialized) + { + /* Do the wait */ + ZwDelayExecution(FALSE, &Timeout); + } + } + + /* Check if we have already setup LDR data */ + if (!Peb->Ldr) + { + /* Setup the Loader Lock */ + Peb->LoaderLock = &LdrpLoaderLock; + + /* Let other code know we're initializing */ + LdrpInLdrInit = TRUE; + + /* Protect with SEH */ + _SEH2_TRY + { + /* Initialize the Process */ + LoaderStatus = LdrpInitializeProcess_(Context, + SystemArgument1); + + /* Check for success and if MinimumStackCommit was requested */ + if (NT_SUCCESS(LoaderStatus) && Peb->MinimumStackCommit) + { + /* Enforce the limit */ + //LdrpTouchThreadStack(Peb->MinimumStackCommit); + UNIMPLEMENTED; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + LoaderStatus = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + /* We're not initializing anymore */ + LdrpInLdrInit = FALSE; + + /* Check if init worked */ + if (NT_SUCCESS(LoaderStatus)) + { + /* Set the process as Initialized */ + _InterlockedIncrement(&LdrpProcessInitialized); + } + } + else + { + /* Loader data is there... is this a fork() ? */ + if(Peb->InheritedAddressSpace) + { + /* Handle the fork() */ + //LoaderStatus = LdrpForkProcess(); + LoaderStatus = STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + } + else + { + /* This is a new thread initializing */ + LdrpInitializeThread(Context); + } + } + + /* All done, test alert the thread */ + NtTestAlert(); + + /* Return */ + if (!NT_SUCCESS(LoaderStatus)) + { + /* Fail */ + LdrpInitFailure(LoaderStatus); + RtlRaiseStatus(LoaderStatus); + } +} + /* EOF */ diff --git a/dll/ntdll/ldr/ldrpe.c b/dll/ntdll/ldr/ldrpe.c new file mode 100644 index 00000000000..730d260d836 --- /dev/null +++ b/dll/ntdll/ldr/ldrpe.c @@ -0,0 +1,1041 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: lib/ntdll/ldr/ldrpe.c + * PURPOSE: Loader Functions dealing low-level PE Format structures + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ +ULONG LdrpFatalHardErrorCount; +PVOID LdrpManifestProberRoutine; + +/* PROTOTYPES ****************************************************************/ + +#define IMAGE_REL_BASED_HIGH3ADJ 11 + +NTSTATUS +NTAPI +LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, + IN LPSTR ImportName, + IN PVOID DllBase, + OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry, + OUT PBOOLEAN Existing); + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS +NTAPI +LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, + IN PLDR_DATA_TABLE_ENTRY ImportLdrEntry, + IN PIMAGE_IMPORT_DESCRIPTOR IatEntry, + IN BOOLEAN EntriesValid) +{ + PIMAGE_EXPORT_DIRECTORY ExportDirectory; + ULONG ExportSize; + PVOID Iat; + SIZE_T ImportSize; + ULONG IatSize; + //PPEB Peb = NtCurrentPeb(); + NTSTATUS Status; + PIMAGE_THUNK_DATA OriginalThunk, FirstThunk; + LPSTR ImportName; + ULONG ForwarderChain; + PIMAGE_NT_HEADERS NtHeader; + PIMAGE_SECTION_HEADER SectionHeader; + ULONG i, Rva; + ULONG OldProtect; + + DPRINT("LdrpSnapIAT(%wZ %wZ %p %d)\n", &ExportLdrEntry->BaseDllName, &ImportLdrEntry->BaseDllName, IatEntry, EntriesValid); + + /* Get export directory */ + ExportDirectory = RtlImageDirectoryEntryToData(ExportLdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ExportSize); + + /* Make sure it has one */ + if (!ExportDirectory) return STATUS_INVALID_IMAGE_FORMAT; + + /* Get the IAT */ + Iat = RtlImageDirectoryEntryToData(ImportLdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IAT, + &IatSize); + ImportSize = IatSize; + + /* Check if we don't have one */ + if (!Iat) + { + /* Get the NT Header and the first section */ + NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase); + SectionHeader = IMAGE_FIRST_SECTION(NtHeader); + + /* Get the RVA of the import directory */ + Rva = NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + + /* Make sure we got one */ + if (Rva) + { + /* Loop all the sections */ + for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++) + { + /* Check if we are inside this section */ + if ((Rva >= SectionHeader->VirtualAddress) && + (Rva < (SectionHeader->VirtualAddress + + SectionHeader->SizeOfRawData))) + { + /* We are, so set the IAT here */ + Iat = (PVOID)((ULONG_PTR)(ImportLdrEntry->DllBase) + + SectionHeader->VirtualAddress); + + /* Set the size */ + IatSize = SectionHeader->Misc.VirtualSize; + + /* Deal with Watcom and other retarded compilers */ + if (!IatSize) + { + IatSize = SectionHeader->SizeOfRawData; + } + + /* Found it, get out */ + break; + } + + /* No match, move to the next section */ + SectionHeader++; + } + } + + /* If we still don't have an IAT, that's bad */ + if (!Iat) return STATUS_INVALID_IMAGE_FORMAT; + + /* Set the right size */ + ImportSize = IatSize; + } + + /* Unprotect the IAT */ + Status = NtProtectVirtualMemory(NtCurrentProcess(), + &Iat, + &ImportSize, + PAGE_READWRITE, + &OldProtect); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if the Thunks are already valid */ + if (EntriesValid) + { + /* We'll only do forwarders. Get the import name */ + ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase + IatEntry->Name); + + /* Get the list of forwaders */ + ForwarderChain = IatEntry->ForwarderChain; + + /* Loop them */ + while (ForwarderChain != -1) + { + /* Get the cached thunk VA*/ + OriginalThunk = (PIMAGE_THUNK_DATA) + ((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->OriginalFirstThunk + + (ForwarderChain * sizeof(IMAGE_THUNK_DATA))); + + /* Get the first thunk */ + FirstThunk = (PIMAGE_THUNK_DATA) + ((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->FirstThunk + + (ForwarderChain * sizeof(IMAGE_THUNK_DATA))); + + /* Get the Forwarder from the thunk */ + ForwarderChain = (ULONG)FirstThunk->u1.Ordinal; + + /* Snap the thunk */ + _SEH2_TRY + { + Status = LdrpSnapThunk(ExportLdrEntry->DllBase, + ImportLdrEntry->DllBase, + OriginalThunk, + FirstThunk, + ExportDirectory, + ExportSize, + TRUE, + ImportName); + + /* Move to the next thunk */ + FirstThunk++; + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + Status = _SEH2_GetExceptionCode(); + } _SEH2_END; + + /* If we messed up, exit */ + if (!NT_SUCCESS(Status)) break; + } + } + else if (IatEntry->FirstThunk) + { + /* Full snapping. Get the First thunk */ + FirstThunk = (PIMAGE_THUNK_DATA) + ((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->FirstThunk); + + /* Get the NT Header */ + NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase); + + /* Get the Original thunk VA, watch out for weird images */ + if ((IatEntry->Characteristics < NtHeader->OptionalHeader.SizeOfHeaders) || + (IatEntry->Characteristics >= NtHeader->OptionalHeader.SizeOfImage)) + { + /* Refuse it, this is a strange linked file */ + OriginalThunk = FirstThunk; + } + else + { + /* Get the address from the field and convert to VA */ + OriginalThunk = (PIMAGE_THUNK_DATA) + ((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->OriginalFirstThunk); + } + + /* Get the Import name VA */ + ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase + + IatEntry->Name); + + /* Loop while it's valid */ + while (OriginalThunk->u1.AddressOfData) + { + /* Snap the Thunk */ + _SEH2_TRY + { + Status = LdrpSnapThunk(ExportLdrEntry->DllBase, + ImportLdrEntry->DllBase, + OriginalThunk, + FirstThunk, + ExportDirectory, + ExportSize, + TRUE, + ImportName); + + /* Next thunks */ + OriginalThunk++; + FirstThunk++; + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + Status = _SEH2_GetExceptionCode(); + } _SEH2_END; + + /* If we failed the snap, break out */ + if (!NT_SUCCESS(Status)) break; + } + } + + /* Protect the IAT again */ + NtProtectVirtualMemory(NtCurrentProcess(), + &Iat, + &ImportSize, + OldProtect, + &OldProtect); + + /* Also flush out the cache */ + NtFlushInstructionCache(NtCurrentProcess(), Iat, IatSize); + + /* Return to Caller */ + return Status; +} + +NTSTATUS +NTAPI +LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry, + IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry, + IN PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry) +{ + LPSTR ImportName = NULL, BoundImportName, ForwarderName; + NTSTATUS Status; + BOOLEAN AlreadyLoaded = FALSE, Stale; + PIMAGE_IMPORT_DESCRIPTOR ImportEntry; + PLDR_DATA_TABLE_ENTRY DllLdrEntry, ForwarderLdrEntry; + PIMAGE_BOUND_FORWARDER_REF ForwarderEntry; + PPEB Peb = NtCurrentPeb(); + ULONG i, IatSize; + + /* Get the name's VA */ + BoundImportName = (LPSTR)(BoundEntry + BoundEntry->OffsetModuleName); + + /* Show debug mesage */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ bound to %s\n", &LdrEntry->BaseDllName, BoundImportName); + } + + /* Load the module for this entry */ + Status = LdrpLoadImportModule(DllPath, + BoundImportName, + LdrEntry->DllBase, + &DllLdrEntry, + &AlreadyLoaded); + if (!NT_SUCCESS(Status)) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ failed to load import module %s; status = %x\n", + &LdrEntry->BaseDllName, + BoundImportName, + Status); + } + goto Quickie; + } + + /* Check if it wasn't already loaded */ + if (!AlreadyLoaded) + { + /* Add it to our list */ + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &DllLdrEntry->InInitializationOrderModuleList); + } + + /* Check if the Bound Entry is now invalid */ + if ((BoundEntry->TimeDateStamp != DllLdrEntry->TimeDateStamp) || + (DllLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE)) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ has stale binding to %s\n", + &DllLdrEntry->BaseDllName, + BoundImportName); + } + + /* Remember it's become stale */ + Stale = TRUE; + } + else + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ has correct binding to %s\n", + &DllLdrEntry->BaseDllName, + BoundImportName); + } + + /* Remember it's valid */ + Stale = FALSE; + } + + /* Get the forwarders */ + ForwarderEntry = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1); + + /* Loop them */ + for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++) + { + /* Get the name */ + ForwarderName = (LPSTR)(FirstEntry + ForwarderEntry->OffsetModuleName); + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ bound to %s via forwarder(s) from %wZ\n", + &LdrEntry->BaseDllName, + ForwarderName, + &DllLdrEntry->BaseDllName); + } + + /* Load the module */ + Status = LdrpLoadImportModule(DllPath, + ForwarderName, + LdrEntry->DllBase, + &ForwarderLdrEntry, + &AlreadyLoaded); + if (NT_SUCCESS(Status)) + { + /* Loaded it, was it already loaded? */ + if (!AlreadyLoaded) + { + /* Add it to our list */ + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &ForwarderLdrEntry->InInitializationOrderModuleList); + } + } + + /* Check if the Bound Entry is now invalid */ + if (!(NT_SUCCESS(Status)) || + (ForwarderEntry->TimeDateStamp != ForwarderLdrEntry->TimeDateStamp) || + (ForwarderLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE)) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ has stale binding to %s\n", + &ForwarderLdrEntry->BaseDllName, + ForwarderName); + } + + /* Remember it's become stale */ + Stale = TRUE; + } + else + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ has correct binding to %s\n", + &ForwarderLdrEntry->BaseDllName, + ForwarderName); + } + + /* Remember it's valid */ + Stale = FALSE; + } + + /* Move to the next one */ + ForwarderEntry++; + } + + /* Set the next bound entry to the forwarder */ + FirstEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)ForwarderEntry; + + /* Check if the binding was stale */ + if (Stale) + { + /* It was, so find the IAT entry for it */ + ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &IatSize); + + /* Make sure it has a name */ + while (ImportEntry->Name) + { + /* Get the name */ + ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name); + + /* Compare it */ + if (!_stricmp(ImportName, BoundImportName)) break; + + /* Move to next entry */ + ImportEntry += 1; + } + + /* If we didn't find a name, fail */ + if (!ImportEntry->Name) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: LdrpWalkImportTable - failing with" + "STATUS_OBJECT_NAME_INVALID due to no import descriptor name\n"); + } + + /* Return error */ + Status = STATUS_OBJECT_NAME_INVALID; + goto Quickie; + } + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: Stale Bind %s from %wZ\n", + ImportName, + &LdrEntry->BaseDllName); + } + + /* Snap the IAT Entry*/ + Status = LdrpSnapIAT(DllLdrEntry, + LdrEntry, + ImportEntry, + FALSE); + + /* Make sure we didn't fail */ + if (!NT_SUCCESS(Status)) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %wZ failed to load import module %s; status = %x\n", + &LdrEntry->BaseDllName, + BoundImportName, + Status); + } + + /* Return */ + goto Quickie; + } + } + + /* All done */ + Status = STATUS_SUCCESS; + +Quickie: + /* Write where we are now and return */ + *BoundEntry = *FirstEntry; + return Status; +} + +NTSTATUS +NTAPI +LdrpHandleNewFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry, + IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry) +{ + PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry = BoundEntry; + NTSTATUS Status; + + /* Make sure we have a name */ + while (BoundEntry->OffsetModuleName) + { + /* Parse this descriptor */ + Status = LdrpHandleOneNewFormatImportDescriptor(DllPath, + LdrEntry, + BoundEntry, + FirstEntry); + if (!NT_SUCCESS(Status)) return Status; + } + + /* Done */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +LdrpHandleOneOldFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry, + IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry) +{ + //ULONG IatSize, i; + LPSTR ImportName; + NTSTATUS Status; + BOOLEAN AlreadyLoaded = FALSE, StaticEntriesValid = FALSE, SkipSnap = FALSE; + PLDR_DATA_TABLE_ENTRY DllLdrEntry; + PIMAGE_THUNK_DATA FirstThunk; + PPEB Peb = NtCurrentPeb(); + + /* Get the import name's VA */ + ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name); + + /* Get the first thunk */ + FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrEntry->DllBase + + ImportEntry->FirstThunk); + + /* Make sure it's valid */ + if (!FirstThunk->u1.Function) goto SkipEntry; + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: %s used by %wZ\n", + ImportName, + &LdrEntry->BaseDllName); + } + + /* Load the module associated to it */ + Status = LdrpLoadImportModule(DllPath, + ImportName, + LdrEntry->DllBase, + &DllLdrEntry, + &AlreadyLoaded); + if (!NT_SUCCESS(Status)) return Status; + + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: Snapping imports for %wZ from %s\n", + &LdrEntry->BaseDllName, + ImportName); + } + + /* Check if the image was bound when compiled */ + if (ImportEntry->OriginalFirstThunk) + { + /* It was, so check if the static IAT entries are still valid */ + if ((ImportEntry->TimeDateStamp) && + (ImportEntry->TimeDateStamp == DllLdrEntry->TimeDateStamp) && + (!(DllLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE))) + { + /* Show debug message */ + if (ShowSnaps) + { + DPRINT1("LDR: Snap bypass %s from %wZ\n", + ImportName, + &LdrEntry->BaseDllName); + } + + /* + * They are still valid, so we can skip snapping them. + * Additionally, if we have no forwarders, we are totally + * done. + */ + if (ImportEntry->ForwarderChain == -1) + { + /* Totally skip LdrpSnapIAT */ + SkipSnap = TRUE; + } + else + { + /* Set this so LdrpSnapIAT will only do forwarders */ + StaticEntriesValid = TRUE; + } + } + } + + /* Check if it wasn't already loaded */ + if (!AlreadyLoaded) + { + /* Add the DLL to our list */ + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &DllLdrEntry->InInitializationOrderModuleList); + } + + /* Check if we should snap at all */ + if (!SkipSnap) + { + /* Now snap the IAT Entry */ + Status = LdrpSnapIAT(DllLdrEntry, + LdrEntry, + ImportEntry, + StaticEntriesValid); + if (!NT_SUCCESS(Status)) return Status; + } + +SkipEntry: + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +LdrpHandleOldFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry, + IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry) +{ + NTSTATUS Status; + + /* Check for Name and Thunk */ + while (ImportEntry->Name && ImportEntry->FirstThunk) + { + /* Parse this descriptor */ + Status = LdrpHandleOneOldFormatImportDescriptor(DllPath, + LdrEntry, + ImportEntry); + if (!NT_SUCCESS(Status)) return Status; + + /* Move to the next entry */ + ImportEntry++; + } + + /* Done */ + return STATUS_SUCCESS; +} + +USHORT NTAPI +LdrpNameToOrdinal(LPSTR ImportName, + ULONG NumberOfNames, + PVOID ExportBase, + PULONG NameTable, + PUSHORT OrdinalTable) +{ + UNIMPLEMENTED; + return 0; +} + +NTSTATUS +NTAPI +LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, + IN PLDR_DATA_TABLE_ENTRY LdrEntry) +{ + RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx; + PPEB Peb = NtCurrentPeb(); + NTSTATUS Status = STATUS_SUCCESS; + PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry = NULL; + PIMAGE_IMPORT_DESCRIPTOR ImportEntry; + ULONG BoundSize, IatSize; +DPRINT1("LdrpWalkImportDescriptor('%S' %x)\n", DllPath, LdrEntry); + /* Set up the Act Ctx */ + ActCtx.Size = sizeof(ActCtx); + ActCtx.Frame.Flags = ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID; + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + + /* Check if we have a manifest prober routine */ + if (LdrpManifestProberRoutine) + { + DPRINT1("We don't support manifests yet, much less prober routines\n"); + } + + /* Check if we failed above */ + if (!NT_SUCCESS(Status)) return Status; + + /* Get the Active ActCtx */ + Status = RtlGetActiveActivationContext(&LdrEntry->EntryPointActivationContext); + if (!NT_SUCCESS(Status)) return Status; + + /* Activate the ActCtx */ + RtlActivateActivationContextUnsafeFast(&ActCtx, + LdrEntry->EntryPointActivationContext); + + /* Check if we were directed */ + if (!(LdrEntry->Flags & LDRP_REDIRECTED)) + { + /* Get the Bound IAT */ + BoundEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, + &BoundSize); + } + + /* Get the regular IAT, for fallback */ + ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &IatSize); + + /* Check if we got at least one */ + if (BoundEntry || ImportEntry) + { + /* Do we have a Bound IAT */ + if (BoundEntry) + { + /* Handle the descriptor */ + Status = LdrpHandleNewFormatImportDescriptors(DllPath, + LdrEntry, + BoundEntry); + } + else + { + /* Handle the descriptor */ + Status = LdrpHandleOldFormatImportDescriptors(DllPath, + LdrEntry, + ImportEntry); + } + + /* Check the status of the handlers */ + if (NT_SUCCESS(Status)) + { + /* Check for Per-DLL Heap Tagging */ + if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAG_BY_DLL) + { + /* FIXME */ + DPRINT1("We don't support Per-DLL Heap Tagging yet!\n"); + } + + /* Check if Page Heap was enabled */ + if (Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS) + { + /* FIXME */ + DPRINT1("We don't support Page Heaps yet!\n"); + } + + /* Check if Application Verifier was enabled */ + if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAIL_CHECK) + { + /* FIXME */ + DPRINT1("We don't support Application Verifier yet!\n"); + } + + /* Just to be safe */ + Status = STATUS_SUCCESS; + } + } + + /* Release the activation context */ + RtlDeactivateActivationContextUnsafeFast(&ActCtx); + + /* Return status */ + return Status; +} + +NTSTATUS +NTAPI +LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, + IN LPSTR ImportName, + IN PVOID DllBase, + OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry, + OUT PBOOLEAN Existing) +{ + ANSI_STRING AnsiString; + PUNICODE_STRING ImpDescName; + NTSTATUS Status; + PPEB Peb = RtlGetCurrentPeb(); + PTEB Teb = NtCurrentTeb(); +DPRINT1("LdrpLoadImportModule('%S' '%s' %p %p %p)\n", DllPath, ImportName, DllBase, DataTableEntry, Existing); + /* Convert import descriptor name to unicode string */ + ImpDescName = &Teb->StaticUnicodeString; + RtlInitAnsiString(&AnsiString, ImportName); + Status = RtlAnsiStringToUnicodeString(ImpDescName, &AnsiString, FALSE); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if it's loaded */ + if (LdrpCheckForLoadedDll(DllPath, + ImpDescName, + TRUE, + FALSE, + DataTableEntry)) + { + /* It's already existing in the list */ + *Existing = TRUE; + return STATUS_SUCCESS; + } + + /* We're loading it for the first time */ + *Existing = FALSE; + + /* Map it */ + Status = LdrpMapDll(DllPath, + ImpDescName->Buffer, + NULL, + NULL, + TRUE, + FALSE, + DataTableEntry); + + if (!NT_SUCCESS(Status)) return Status; + + /* Walk its import descriptor table */ + Status = LdrpWalkImportDescriptor(DllPath, + *DataTableEntry); + if (!NT_SUCCESS(Status)) + { + /* Add it to the in-init-order list in case of failure */ + InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, + &(*DataTableEntry)->InInitializationOrderModuleList); + } + + return Status; +} + +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) +{ + BOOLEAN IsOrdinal; + USHORT Ordinal; + ULONG OriginalOrdinal = 0; + PIMAGE_IMPORT_BY_NAME AddressOfData; + PULONG NameTable; + PUSHORT OrdinalTable; + LPSTR ImportName = NULL; + USHORT Hint; + NTSTATUS Status; + ULONG_PTR HardErrorParameters[3]; + UNICODE_STRING HardErrorDllName, HardErrorEntryPointName; + ANSI_STRING TempString; + ULONG Mask; + ULONG Response; + PULONG AddressOfFunctions; + UNICODE_STRING TempUString; + ANSI_STRING ForwarderName; + PANSI_STRING ForwardName; + PVOID ForwarderHandle; + ULONG ForwardOrdinal; + + /* Check if the snap is by ordinal */ + if ((IsOrdinal = IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal))) + { + /* Get the ordinal number, and its normalized version */ + OriginalOrdinal = IMAGE_ORDINAL(OriginalThunk->u1.Ordinal); + Ordinal = (USHORT)(OriginalOrdinal - ExportEntry->Base); + } + else + { + /* First get the data VA */ + AddressOfData = (PIMAGE_IMPORT_BY_NAME) + ((ULONG_PTR)ImportBase + + ((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff)); + + /* Get the name */ + ImportName = (LPSTR)AddressOfData->Name; + + /* Now get the VA of the Name and Ordinal Tables */ + NameTable = (PULONG)((ULONG_PTR)ExportBase + + (ULONG_PTR)ExportEntry->AddressOfNames); + OrdinalTable = (PUSHORT)((ULONG_PTR)ExportBase + + (ULONG_PTR)ExportEntry->AddressOfNameOrdinals); + + /* Get the hint */ + Hint = AddressOfData->Hint; + + /* Try to get a match by using the hint */ + if (((ULONG)Hint < ExportEntry->NumberOfNames) && + (!strcmp(ImportName, ((LPSTR)((ULONG_PTR)ExportBase + NameTable[Hint]))))) + { + /* We got a match, get the Ordinal from the hint */ + Ordinal = OrdinalTable[Hint]; + } + else + { + /* Well bummer, hint didn't work, do it the long way */ + Ordinal = LdrpNameToOrdinal(ImportName, + ExportEntry->NumberOfNames, + ExportBase, + NameTable, + OrdinalTable); + } + } + + /* Check if the ordinal is invalid */ + if ((ULONG)Ordinal >= ExportEntry->NumberOfFunctions) + { +FailurePath: + /* Is this a static snap? */ + if (Static) + { + /* These are critical errors. Setup a string for the DLL name */ + RtlInitAnsiString(&TempString, DllName ? DllName : "Unknown"); + RtlAnsiStringToUnicodeString(&HardErrorDllName, &TempString, TRUE); + + /* Set it as the parameter */ + HardErrorParameters[1] = (ULONG_PTR)&HardErrorDllName; + Mask = 2; + + /* Check if we have an ordinal */ + if (IsOrdinal) + { + /* Then set the ordinal as the 1st parameter */ + HardErrorParameters[0] = OriginalOrdinal; + } + else + { + /* We don't, use the entrypoint. Set up a string for it */ + RtlInitAnsiString(&TempString, ImportName); + RtlAnsiStringToUnicodeString(&HardErrorEntryPointName, + &TempString, + TRUE); + + /* Set it as the parameter */ + HardErrorParameters[0] = (ULONG_PTR)&HardErrorEntryPointName; + Mask = 3; + } + + /* Raise the error */ + NtRaiseHardError(IsOrdinal ? STATUS_ORDINAL_NOT_FOUND : + STATUS_ENTRYPOINT_NOT_FOUND, + 2, + Mask, + HardErrorParameters, + OptionOk, + &Response); + + /* Increase the error count */ + if (LdrpInLdrInit) LdrpFatalHardErrorCount++; + + /* Free our string */ + RtlFreeUnicodeString(&HardErrorDllName); + if (!IsOrdinal) + { + /* Free our second string. Return entrypoint error */ + RtlFreeUnicodeString(&HardErrorEntryPointName); + RtlRaiseStatus(STATUS_ENTRYPOINT_NOT_FOUND); + } + + /* Return ordinal error */ + RtlRaiseStatus(STATUS_ORDINAL_NOT_FOUND); + } + + /* Set this as a bad DLL */ + Thunk->u1.Function = (ULONG_PTR)0xffbadd11; + + /* Return the right error code */ + Status = IsOrdinal ? STATUS_ORDINAL_NOT_FOUND : + STATUS_ENTRYPOINT_NOT_FOUND; + } + else + { + /* The ordinal seems correct, get the AddressOfFunctions VA */ + AddressOfFunctions = (PULONG) + ((ULONG_PTR)ExportBase + + (ULONG_PTR)ExportEntry->AddressOfFunctions); + + /* Write the function pointer*/ + Thunk->u1.Function = (ULONG_PTR)ExportBase + AddressOfFunctions[Ordinal]; + + /* Make sure it's within the exports */ + if ((Thunk->u1.Function > (ULONG_PTR)ExportEntry) && + (Thunk->u1.Function < ((ULONG_PTR)ExportEntry + ExportSize))) + { + /* Get the Import and Forwarder Names */ + ImportName = (LPSTR)Thunk->u1.Function; + ForwarderName.Buffer = ImportName; + ForwarderName.Length = (USHORT)(strchr(ImportName, '.') - ImportName); + ForwarderName.MaximumLength = ForwarderName.Length; + Status = RtlAnsiStringToUnicodeString(&TempUString, + &ForwarderName, + TRUE); + + /* Make sure the conversion was OK */ + if (NT_SUCCESS(Status)) + { + /* Load the forwarder, free the temp string */ + Status = LdrpLoadDll(FALSE, + NULL, + NULL, + &TempUString, + &ForwarderHandle, + FALSE); + RtlFreeUnicodeString(&TempUString); + } + + /* If the load or conversion failed, use the failure path */ + if (!NT_SUCCESS(Status)) goto FailurePath; + + /* Now set up a name for the actual forwarder dll */ + RtlInitAnsiString(&ForwarderName, + ImportName + ForwarderName.Length + sizeof(CHAR)); + + /* Check if it's an ordinal forward */ + if ((ForwarderName.Length > 1) && (*ForwarderName.Buffer == '#')) + { + /* We don't have an actual function name */ + ForwardName = NULL; + + /* Convert the string into an ordinal */ + Status = RtlCharToInteger(ForwarderName.Buffer + sizeof(CHAR), + 0, + &ForwardOrdinal); + + /* If this fails, then error out */ + if (!NT_SUCCESS(Status)) goto FailurePath; + } + else + { + /* Import by name */ + ForwardName = &ForwarderName; + } + + /* Get the pointer */ + Status = LdrpGetProcedureAddress(ForwarderHandle, + ForwardName, + ForwardOrdinal, + (PVOID*)&Thunk->u1.Function, + FALSE); + /* If this fails, then error out */ + if (!NT_SUCCESS(Status)) goto FailurePath; + } + else + { + /* It's not within the exports, let's hope it's valid */ + if (!AddressOfFunctions[Ordinal]) goto FailurePath; + } + + /* If we got here, then it's success */ + Status = STATUS_SUCCESS; + } + + /* Return status */ + return Status; +} + +/* EOF */ diff --git a/dll/ntdll/ldr/ldrutils.c b/dll/ntdll/ldr/ldrutils.c new file mode 100644 index 00000000000..8c2783755ae --- /dev/null +++ b/dll/ntdll/ldr/ldrutils.c @@ -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 (alex@relsoft.net) + * Aleksey Bragin (aleksey@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* 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 */ diff --git a/dll/ntdll/ldr/startup.c b/dll/ntdll/ldr/startup.c index 06b90b07558..f063aefdc0d 100644 --- a/dll/ntdll/ldr/startup.c +++ b/dll/ntdll/ldr/startup.c @@ -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 */ diff --git a/dll/ntdll/ldr/utils.c b/dll/ntdll/ldr/utils.c index e7213b3df07..c9bb89bbb51 100644 --- a/dll/ntdll/ldr/utils.c +++ b/dll/ntdll/ldr/utils.c @@ -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) diff --git a/dll/win32/devmgr/hwpage.c b/dll/win32/devmgr/hwpage.c index 0b26bd67866..57b52d22e0f 100644 --- a/dll/win32/devmgr/hwpage.c +++ b/dll/win32/devmgr/hwpage.c @@ -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); diff --git a/dll/win32/gdi32/misc/misc.c b/dll/win32/gdi32/misc/misc.c index 408a658d72e..8fedb8fb820 100644 --- a/dll/win32/gdi32/misc/misc.c +++ b/dll/win32/gdi32/misc/misc.c @@ -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 diff --git a/dll/win32/gdi32/objects/text.c b/dll/win32/gdi32/objects/text.c index 75b79c30b8a..d1bb5d5b4d5 100644 --- a/dll/win32/gdi32/objects/text.c +++ b/dll/win32/gdi32/objects/text.c @@ -1,5 +1,7 @@ #include "precomp.h" +#define NDEBUG +#include /* * @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); diff --git a/dll/win32/kernel32/misc/ldr.c b/dll/win32/kernel32/misc/ldr.c index 6a954ae802c..decc300fbab 100644 --- a/dll/win32/kernel32/misc/ldr.c +++ b/dll/win32/kernel32/misc/ldr.c @@ -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); diff --git a/dll/win32/msi/CMakeLists.txt b/dll/win32/msi/CMakeLists.txt index 3057f0e70af..94cad134fcd 100644 --- a/dll/win32/msi/CMakeLists.txt +++ b/dll/win32/msi/CMakeLists.txt @@ -13,6 +13,7 @@ list(APPEND SOURCE action.c alter.c appsearch.c + assembly.c automation.c classes.c cond.tab.c diff --git a/dll/win32/msi/action.c b/dll/win32/msi/action.c index 808386f96e9..f806f18cb34 100644 --- a/dll/win32/msi/action.c +++ b/dll/win32/msi/action.c @@ -35,7 +35,6 @@ #include "shlobj.h" #include "objbase.h" #include "mscoree.h" -#include "fusion.h" #include "shlwapi.h" #include "wine/unicode.h" #include "winver.h" @@ -110,8 +109,6 @@ static const WCHAR szIsolateComponents[] = {'I','s','o','l','a','t','e','C','o','m','p','o','n','e','n','t','s',0}; static const WCHAR szMigrateFeatureStates[] = {'M','i','g','r','a','t','e','F','e','a','t','u','r','e','S','t','a','t','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}; static const WCHAR szMsiUnpublishAssemblies[] = {'M','s','i','U','n','p','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0}; static const WCHAR szInstallODBC[] = @@ -165,10 +162,6 @@ static const WCHAR szValidateProductID[] = static const WCHAR szWriteEnvironmentStrings[] = {'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0}; -/******************************************************** - * helper functions - ********************************************************/ - static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action) { static const WCHAR Query_t[] = @@ -214,86 +207,173 @@ static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start, msiobj_release(&row->hdr); } +enum parse_state +{ + state_whitespace, + state_token, + state_quote +}; + +static int parse_prop( const WCHAR *str, WCHAR *value, int *quotes ) +{ + enum parse_state state = state_quote; + const WCHAR *p; + WCHAR *out = value; + int ignore, in_quotes = 0, count = 0, len = 0; + + for (p = str; *p; p++) + { + ignore = 0; + switch (state) + { + case state_whitespace: + switch (*p) + { + case ' ': + if (!count) goto done; + in_quotes = 1; + ignore = 1; + break; + case '"': + state = state_quote; + if (in_quotes) count--; + else count++; + break; + default: + state = state_token; + if (!count) in_quotes = 0; + else in_quotes = 1; + len++; + break; + } + break; + + case state_token: + switch (*p) + { + case '"': + state = state_quote; + if (in_quotes) count--; + else count++; + break; + case ' ': + state = state_whitespace; + if (!count) goto done; + in_quotes = 1; + break; + default: + if (!count) in_quotes = 0; + else in_quotes = 1; + len++; + break; + } + break; + + case state_quote: + switch (*p) + { + case '"': + if (in_quotes) count--; + else count++; + break; + case ' ': + state = state_whitespace; + if (!count || !len) goto done; + in_quotes = 1; + break; + default: + state = state_token; + if (!count) in_quotes = 0; + else in_quotes = 1; + len++; + break; + } + break; + + default: break; + } + if (!ignore) *out++ = *p; + } + +done: + if (!len) *value = 0; + else *out = 0; + + *quotes = count; + return p - str; +} + +static void remove_quotes( WCHAR *str ) +{ + WCHAR *p = str; + int len = strlenW( str ); + + while ((p = strchrW( p, '"' ))) + { + memmove( p, p + 1, (len - (p - str)) * sizeof(WCHAR) ); + p++; + } +} + UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine, BOOL preserve_case ) { - LPCWSTR ptr,ptr2; - BOOL quote; + LPCWSTR ptr, ptr2; + int quotes; DWORD len; - LPWSTR prop = NULL, val = NULL; + WCHAR *prop, *val; + UINT r; if (!szCommandLine) return ERROR_SUCCESS; ptr = szCommandLine; - while (*ptr) { - if (*ptr==' ') - { - ptr++; - continue; - } + while (*ptr == ' ') ptr++; + if (!*ptr) break; - TRACE("Looking at %s\n",debugstr_w(ptr)); - - ptr2 = strchrW(ptr,'='); - if (!ptr2) - { - ERR("command line contains unknown string : %s\n", debugstr_w(ptr)); - break; - } + ptr2 = strchrW( ptr, '=' ); + if (!ptr2) return ERROR_INVALID_COMMAND_LINE; - quote = FALSE; + len = ptr2 - ptr; + if (!len) return ERROR_INVALID_COMMAND_LINE; - len = ptr2-ptr; - prop = msi_alloc((len+1)*sizeof(WCHAR)); - memcpy(prop,ptr,len*sizeof(WCHAR)); - prop[len]=0; - - if (!preserve_case) - struprW(prop); + prop = msi_alloc( (len + 1) * sizeof(WCHAR) ); + memcpy( prop, ptr, len * sizeof(WCHAR) ); + prop[len] = 0; + if (!preserve_case) struprW( prop ); ptr2++; - - len = 0; - ptr = ptr2; - while (*ptr && (quote || (!quote && *ptr!=' '))) - { - if (*ptr == '"') - quote = !quote; - ptr++; - len++; - } - - if (*ptr2=='"') - { - ptr2++; - len -= 2; - } - val = msi_alloc((len+1)*sizeof(WCHAR)); - memcpy(val,ptr2,len*sizeof(WCHAR)); - val[len] = 0; + while (*ptr2 == ' ') ptr2++; - if (lstrlenW(prop) > 0) + quotes = 0; + val = msi_alloc( (strlenW( ptr2 ) + 1) * sizeof(WCHAR) ); + len = parse_prop( ptr2, val, "es ); + if (quotes % 2) { - UINT r = msi_set_property( package->db, prop, val ); - - TRACE("Found commandline property (%s) = (%s)\n", - debugstr_w(prop), debugstr_w(val)); - - if (r == ERROR_SUCCESS && !strcmpW( prop, cszSourceDir )) - msi_reset_folders( package, TRUE ); + WARN("unbalanced quotes\n"); + msi_free( val ); + msi_free( prop ); + return ERROR_INVALID_COMMAND_LINE; } - msi_free(val); - msi_free(prop); + remove_quotes( val ); + TRACE("Found commandline property %s = %s\n", debugstr_w(prop), debugstr_w(val)); + + r = msi_set_property( package->db, prop, val ); + if (r == ERROR_SUCCESS && !strcmpW( prop, cszSourceDir )) + msi_reset_folders( package, TRUE ); + + msi_free( val ); + msi_free( prop ); + + ptr = ptr2 + len; } return ERROR_SUCCESS; } - -static LPWSTR* msi_split_string( LPCWSTR str, WCHAR sep ) +WCHAR **msi_split_string( const WCHAR *str, WCHAR sep ) { LPCWSTR pc; LPWSTR p, *ret = NULL; @@ -445,7 +525,7 @@ UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ) guids = msi_split_string( guid_list, ';' ); for ( i = 0; guids[i] && ret != ERROR_SUCCESS; i++ ) { - if (!lstrcmpW( guids[i], product_code )) + if (!strcmpW( guids[i], product_code )) ret = ERROR_SUCCESS; } msi_free( guids ); @@ -679,7 +759,27 @@ static UINT msi_apply_transforms( MSIPACKAGE *package ) if (xforms[i][0] == ':') r = msi_apply_substorage_transform( package, package->db, xforms[i] ); else - r = MSI_DatabaseApplyTransformW( package->db, xforms[i], 0 ); + { + WCHAR *transform; + + if (!PathIsRelativeW( xforms[i] )) transform = xforms[i]; + else + { + WCHAR *p = strrchrW( package->PackagePath, '\\' ); + DWORD len = p - package->PackagePath + 1; + + if (!(transform = msi_alloc( (len + strlenW( xforms[i] ) + 1) * sizeof(WCHAR)) )) + { + msi_free( xforms ); + msi_free( xform_list ); + return ERROR_OUTOFMEMORY; + } + memcpy( transform, package->PackagePath, len * sizeof(WCHAR) ); + memcpy( transform + len, xforms[i], (strlenW( xforms[i] ) + 1) * sizeof(WCHAR) ); + } + r = MSI_DatabaseApplyTransformW( package->db, transform, 0 ); + if (transform != xforms[i]) msi_free( transform ); + } } msi_free( xforms ); @@ -964,6 +1064,9 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) MSICOMPONENT *comp; component = MSI_RecordGetString(row, 2); + if (!component) + return ERROR_SUCCESS; + comp = get_loaded_component(package, component); if (!comp) return ERROR_SUCCESS; @@ -994,7 +1097,7 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) ui_actiondata(package, szCreateFolders, uirow); msiobj_release(&uirow->hdr); - full_path = resolve_folder(package,dir,FALSE,FALSE,TRUE,&folder); + full_path = resolve_target_folder( package, dir, FALSE, TRUE, &folder ); if (!full_path) { ERR("Unable to resolve folder id %s\n",debugstr_w(dir)); @@ -1014,16 +1117,14 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) static UINT ACTION_CreateFolders(MSIPACKAGE *package) { - static const WCHAR ExecSeqQuery[] = - {'S','E','L','E','C','T',' ', - '`','D','i','r','e','c','t','o','r','y','_','`', - ' ','F','R','O','M',' ', - '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0 }; + 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','`',0}; UINT rc; MSIQUERY *view; /* create all the empty folders specified in the CreateFolder table */ - rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view ); + rc = MSI_DatabaseOpenViewW(package->db, query, &view ); if (rc != ERROR_SUCCESS) return ERROR_SUCCESS; @@ -1043,6 +1144,9 @@ static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param ) MSICOMPONENT *comp; component = MSI_RecordGetString(row, 2); + if (!component) + return ERROR_SUCCESS; + comp = get_loaded_component(package, component); if (!comp) return ERROR_SUCCESS; @@ -1068,7 +1172,7 @@ static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param ) return ERROR_SUCCESS; } - full_path = resolve_folder( package, dir, FALSE, FALSE, TRUE, &folder ); + full_path = resolve_target_folder( package, dir, FALSE, TRUE, &folder ); if (!full_path) { ERR("Unable to resolve folder id %s\n", debugstr_w(dir)); @@ -1092,8 +1196,8 @@ static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param ) static UINT ACTION_RemoveFolders( MSIPACKAGE *package ) { static const WCHAR query[] = - {'S','E','L','E','C','T',' ', '`','D','i','r','e','c','t','o','r','y','_','`', - ' ','F','R','O','M',' ', '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0}; + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0}; MSIQUERY *view; UINT rc; @@ -1131,8 +1235,10 @@ static UINT load_component( MSIRECORD *row, LPVOID param ) comp->KeyPath = msi_dup_record_field( row, 6 ); comp->Installed = INSTALLSTATE_UNKNOWN; - msi_component_set_state(package, comp, INSTALLSTATE_UNKNOWN); + comp->Action = INSTALLSTATE_UNKNOWN; + comp->ActionRequest = INSTALLSTATE_UNKNOWN; + comp->assembly = load_assembly( package, comp ); return ERROR_SUCCESS; } @@ -1218,7 +1324,7 @@ static MSIFEATURE *find_feature_by_name( MSIPACKAGE *package, LPCWSTR name ) LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - if ( !lstrcmpW( feature->Feature, name ) ) + if ( !strcmpW( feature->Feature, name ) ) return feature; } @@ -1265,7 +1371,8 @@ static UINT load_feature(MSIRECORD * row, LPVOID param) feature->Attributes = MSI_RecordGetInteger(row,8); feature->Installed = INSTALLSTATE_UNKNOWN; - msi_feature_set_state(package, feature, INSTALLSTATE_UNKNOWN); + feature->Action = INSTALLSTATE_UNKNOWN; + feature->ActionRequest = INSTALLSTATE_UNKNOWN; list_add_tail( &package->features, &feature->entry ); @@ -1515,9 +1622,9 @@ static UINT load_folder( MSIRECORD *row, LPVOID param ) src_long = folder_split_path( src_short, '|' ); /* check for no-op dirs */ - if (!lstrcmpW(szDot, tgt_short)) + if (tgt_short && !strcmpW( szDot, tgt_short )) tgt_short = szEmpty; - if (!lstrcmpW(szDot, src_short)) + if (src_short && !strcmpW( szDot, src_short )) src_short = szEmpty; if (!tgt_long) @@ -1636,48 +1743,48 @@ static UINT ACTION_FileCost(MSIPACKAGE *package) static void ACTION_GetComponentInstallStates(MSIPACKAGE *package) { MSICOMPONENT *comp; - INSTALLSTATE state; UINT r; - state = MsiQueryProductStateW(package->ProductCode); - LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry) { - if (!comp->ComponentId) - continue; + if (!comp->ComponentId) continue; - if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT) + r = MsiQueryComponentStateW( package->ProductCode, NULL, + MSIINSTALLCONTEXT_USERMANAGED, comp->ComponentId, + &comp->Installed ); + if (r != ERROR_SUCCESS) + r = MsiQueryComponentStateW( package->ProductCode, NULL, + MSIINSTALLCONTEXT_USERUNMANAGED, comp->ComponentId, + &comp->Installed ); + if (r != ERROR_SUCCESS) + r = MsiQueryComponentStateW( package->ProductCode, NULL, + MSIINSTALLCONTEXT_MACHINE, comp->ComponentId, + &comp->Installed ); + if (r != ERROR_SUCCESS) comp->Installed = INSTALLSTATE_ABSENT; - else - { - r = MsiQueryComponentStateW(package->ProductCode, NULL, - package->Context, comp->ComponentId, - &comp->Installed); - if (r != ERROR_SUCCESS) - comp->Installed = INSTALLSTATE_ABSENT; - } } } static void ACTION_GetFeatureInstallStates(MSIPACKAGE *package) { MSIFEATURE *feature; - INSTALLSTATE state; - - state = MsiQueryProductStateW(package->ProductCode); LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - if (state != INSTALLSTATE_LOCAL && state != INSTALLSTATE_DEFAULT) + INSTALLSTATE state = MsiQueryFeatureStateW( package->ProductCode, feature->Feature ); + + if (state == INSTALLSTATE_UNKNOWN || state == INSTALLSTATE_INVALIDARG) feature->Installed = INSTALLSTATE_ABSENT; else - { - feature->Installed = MsiQueryFeatureStateW(package->ProductCode, - feature->Feature); - } + feature->Installed = state; } } +static inline BOOL is_feature_selected( MSIFEATURE *feature, INT level ) +{ + return (feature->Level > 0 && feature->Level <= level); +} + static BOOL process_state_property(MSIPACKAGE* package, int level, LPCWSTR property, INSTALLSTATE state) { @@ -1690,14 +1797,19 @@ static BOOL process_state_property(MSIPACKAGE* package, int level, LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - if (lstrcmpW(property, szRemove) && - (feature->Level <= 0 || feature->Level > level)) + if (strcmpW( property, szRemove ) && !is_feature_selected( feature, level )) continue; if (!strcmpW(property, szReinstall)) state = feature->Installed; - if (strcmpiW(override, szAll)==0) - msi_feature_set_state(package, feature, state); + if (!strcmpiW( override, szAll )) + { + if (feature->Installed != state) + { + feature->Action = state; + feature->ActionRequest = state; + } + } else { LPWSTR ptr = override; @@ -1710,7 +1822,11 @@ static BOOL process_state_property(MSIPACKAGE* package, int level, if ((ptr2 && strlenW(feature->Feature) == len && !strncmpW(ptr, feature->Feature, len)) || (!ptr2 && !strcmpW(ptr, feature->Feature))) { - msi_feature_set_state(package, feature, state); + if (feature->Installed != state) + { + feature->Action = state; + feature->ActionRequest = state; + } break; } if (ptr2) @@ -1724,7 +1840,6 @@ static BOOL process_state_property(MSIPACKAGE* package, int level, } } msi_free(override); - return TRUE; } @@ -1782,17 +1897,25 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) { LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - BOOL feature_state = ((feature->Level > 0) && - (feature->Level <= level)); + if (!is_feature_selected( feature, level )) continue; - if (feature_state && feature->ActionRequest == INSTALLSTATE_UNKNOWN) + if (feature->ActionRequest == INSTALLSTATE_UNKNOWN) { if (feature->Attributes & msidbFeatureAttributesFavorSource) - msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE); + { + feature->Action = INSTALLSTATE_SOURCE; + feature->ActionRequest = INSTALLSTATE_SOURCE; + } else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise) - msi_feature_set_state(package, feature, INSTALLSTATE_ADVERTISED); + { + feature->Action = INSTALLSTATE_ADVERTISED; + feature->ActionRequest = INSTALLSTATE_ADVERTISED; + } else - msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL); + { + feature->Action = INSTALLSTATE_LOCAL; + feature->ActionRequest = INSTALLSTATE_LOCAL; + } } } @@ -1801,29 +1924,38 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) { FeatureList *fl; - if (feature->Level > 0 && feature->Level <= level) - continue; + if (is_feature_selected( feature, level )) continue; LIST_FOR_EACH_ENTRY( fl, &feature->Children, FeatureList, entry ) - msi_feature_set_state(package, fl->feature, INSTALLSTATE_UNKNOWN); + { + fl->feature->Action = INSTALLSTATE_UNKNOWN; + fl->feature->ActionRequest = INSTALLSTATE_UNKNOWN; + } } } - else + else /* preselected */ { LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { - BOOL selected = feature->Level > 0 && feature->Level <= level; + if (!is_feature_selected( feature, level )) continue; - if (selected && feature->ActionRequest == INSTALLSTATE_UNKNOWN) + if (feature->ActionRequest == INSTALLSTATE_UNKNOWN) { - msi_feature_set_state(package, feature, feature->Installed); + if (feature->Installed == INSTALLSTATE_ABSENT) + { + feature->Action = INSTALLSTATE_UNKNOWN; + feature->ActionRequest = INSTALLSTATE_UNKNOWN; + } + else + { + feature->Action = feature->Installed; + feature->ActionRequest = feature->Installed; + } } } } - /* - * now we want to enable or disable components based on feature - */ + /* now we want to set component state based based on feature state */ LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { ComponentList *cl; @@ -1832,8 +1964,7 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) debugstr_w(feature->Feature), feature->Level, feature->Installed, feature->ActionRequest, feature->Action); - if (!feature->Level) - continue; + if (!is_feature_selected( feature, level )) continue; /* features with components that have compressed files are made local */ LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) @@ -1841,7 +1972,8 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) if (cl->component->ForceLocalState && feature->ActionRequest == INSTALLSTATE_SOURCE) { - msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL); + feature->Action = INSTALLSTATE_LOCAL; + feature->ActionRequest = INSTALLSTATE_LOCAL; break; } } @@ -1886,34 +2018,44 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) { if ((component->Attributes & msidbComponentAttributesSourceOnly) && !component->ForceLocalState) - 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; + } continue; } /* if any feature is local, the component must be local too */ if (component->hasLocalFeature) { - msi_component_set_state(package, component, INSTALLSTATE_LOCAL); + component->Action = INSTALLSTATE_LOCAL; + component->ActionRequest = INSTALLSTATE_LOCAL; continue; } - if (component->hasSourceFeature) { - msi_component_set_state(package, component, INSTALLSTATE_SOURCE); + component->Action = INSTALLSTATE_SOURCE; + component->ActionRequest = INSTALLSTATE_SOURCE; continue; } - if (component->hasAdvertiseFeature) { - msi_component_set_state(package, component, INSTALLSTATE_ADVERTISED); + component->Action = INSTALLSTATE_ADVERTISED; + component->ActionRequest = INSTALLSTATE_ADVERTISED; continue; } - TRACE("nobody wants component %s\n", debugstr_w(component->Component)); - if (component->anyAbsent) - msi_component_set_state(package, component, INSTALLSTATE_ABSENT); + if (component->anyAbsent && + (component->Installed == INSTALLSTATE_LOCAL || component->Installed == INSTALLSTATE_SOURCE)) + { + component->Action = INSTALLSTATE_ABSENT; + component->ActionRequest = INSTALLSTATE_ABSENT; + } } LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry ) @@ -1921,7 +2063,16 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) if (component->ActionRequest == INSTALLSTATE_DEFAULT) { TRACE("%s was default, setting to local\n", debugstr_w(component->Component)); - msi_component_set_state(package, component, INSTALLSTATE_LOCAL); + component->Action = INSTALLSTATE_LOCAL; + component->ActionRequest = INSTALLSTATE_LOCAL; + } + + if (component->ActionRequest == INSTALLSTATE_SOURCE && + component->Installed == INSTALLSTATE_SOURCE && + component->hasSourceFeature) + { + component->Action = INSTALLSTATE_UNKNOWN; + component->ActionRequest = INSTALLSTATE_UNKNOWN; } TRACE("Result: Component %s (Installed %d Request %d Action %d)\n", @@ -1947,10 +2098,9 @@ static UINT ITERATE_CostFinalizeDirectories(MSIRECORD *row, LPVOID param) msi_free(f->ResolvedTarget); f->ResolvedTarget = NULL; - /* This helper function now does ALL the work */ - TRACE("Dir %s ...\n",debugstr_w(name)); - path = resolve_folder(package,name,FALSE,TRUE,TRUE,NULL); - TRACE("resolves to %s\n",debugstr_w(path)); + TRACE("directory %s ...\n", debugstr_w(name)); + path = resolve_target_folder( package, name, TRUE, TRUE, NULL ); + TRACE("resolves to %s\n", debugstr_w(path)); msi_free(path); return ERROR_SUCCESS; @@ -2028,7 +2178,19 @@ int msi_compare_file_versions( VS_FIXEDFILEINFO *fi, const WCHAR *version ) return 0; } -static DWORD get_disk_file_size( LPCWSTR filename ) +int msi_compare_font_versions( const WCHAR *ver1, const WCHAR *ver2 ) +{ + DWORD ms1, ms2; + + msi_parse_version_string( ver1, &ms1, NULL ); + msi_parse_version_string( ver2, &ms2, NULL ); + + if (ms1 > ms2) return 1; + else if (ms1 < ms2) return -1; + return 0; +} + +DWORD msi_get_disk_file_size( LPCWSTR filename ) { HANDLE file; DWORD size; @@ -2044,7 +2206,7 @@ static DWORD get_disk_file_size( LPCWSTR filename ) return size; } -static BOOL hash_matches( MSIFILE *file ) +BOOL msi_file_hash_matches( MSIFILE *file ) { UINT r; MSIFILEHASHINFO hash; @@ -2057,77 +2219,95 @@ static BOOL hash_matches( MSIFILE *file ) return !memcmp( &hash, &file->hash, sizeof(MSIFILEHASHINFO) ); } -static UINT set_file_install_states( MSIPACKAGE *package ) +static WCHAR *get_temp_dir( void ) +{ + static UINT id; + WCHAR tmp[MAX_PATH], dir[MAX_PATH]; + + GetTempPathW( MAX_PATH, tmp ); + for (;;) + { + if (!GetTempFileNameW( tmp, szMsi, ++id, dir )) return NULL; + if (CreateDirectoryW( dir, NULL )) break; + } + return strdupW( dir ); +} + +static void set_target_path( MSIPACKAGE *package, MSIFILE *file ) +{ + MSIASSEMBLY *assembly = file->Component->assembly; + + TRACE("file %s is named %s\n", debugstr_w(file->File), debugstr_w(file->FileName)); + + msi_free( file->TargetPath ); + if (assembly && !assembly->application) + { + if (!assembly->tempdir) assembly->tempdir = get_temp_dir(); + file->TargetPath = build_directory_name( 2, assembly->tempdir, file->FileName ); + track_tempfile( package, file->TargetPath ); + } + else + { + WCHAR *dir = resolve_target_folder( package, file->Component->Directory, FALSE, TRUE, NULL ); + file->TargetPath = build_directory_name( 2, dir, file->FileName ); + msi_free( dir ); + } + + TRACE("resolves to %s\n", debugstr_w(file->TargetPath)); +} + +static UINT calculate_file_cost( MSIPACKAGE *package ) { VS_FIXEDFILEINFO *file_version; + WCHAR *font_version; MSIFILE *file; LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { - MSICOMPONENT* comp = file->Component; + MSICOMPONENT *comp = file->Component; DWORD file_size; - LPWSTR p; - if (!comp) - continue; + if (!comp->Enabled) continue; if (file->IsCompressed) comp->ForceLocalState = TRUE; - /* calculate target */ - p = resolve_folder(package, comp->Directory, FALSE, FALSE, TRUE, NULL); - msi_free(file->TargetPath); + set_target_path( package, file ); - TRACE("file %s is named %s\n", debugstr_w(file->File), debugstr_w(file->FileName)); - - file->TargetPath = build_directory_name(2, p, file->FileName); - msi_free(p); - - TRACE("file %s resolves to %s\n", debugstr_w(file->File), debugstr_w(file->TargetPath)); - - if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) + if ((comp->assembly && !comp->assembly->installed) || + GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) { - file->state = msifs_missing; comp->Cost += file->FileSize; continue; } - if (file->Version && (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)); + file_size = msi_get_disk_file_size( file->TargetPath ); - if (msi_compare_file_versions( file_version, file->Version ) < 0) - { - file->state = msifs_overwrite; - comp->Cost += file->FileSize; - } - else - { - TRACE("Destination file version equal or greater, not overwriting\n"); - file->state = msifs_present; - } - msi_free( file_version ); - continue; - } - if ((file_size = get_disk_file_size( file->TargetPath )) != file->FileSize) + if (file->Version) + { + if ((file_version = msi_get_disk_file_version( file->TargetPath ))) + { + if (msi_compare_file_versions( file_version, file->Version ) < 0) + { + comp->Cost += file->FileSize - file_size; + } + msi_free( file_version ); + continue; + } + else if ((font_version = font_version_from_file( file->TargetPath ))) + { + if (msi_compare_font_versions( font_version, file->Version ) < 0) + { + comp->Cost += file->FileSize - file_size; + } + msi_free( font_version ); + continue; + } + } + if (file_size != file->FileSize) { - file->state = msifs_overwrite; comp->Cost += file->FileSize - file_size; - continue; } - if (file->hash.dwFileHashInfoSize && hash_matches( file )) - { - TRACE("File hashes match, not overwriting\n"); - file->state = msifs_present; - continue; - } - file->state = msifs_overwrite; - comp->Cost += file->FileSize - file_size; } - return ERROR_SUCCESS; } @@ -2166,13 +2346,22 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) msiobj_release(&view->hdr); } + TRACE("Evaluating component conditions\n"); + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + { + if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE) + { + TRACE("Disabling component %s\n", debugstr_w(comp->Component)); + comp->Enabled = FALSE; + } + else + comp->Enabled = TRUE; + } + /* read components states from the registry */ ACTION_GetComponentInstallStates(package); ACTION_GetFeatureInstallStates(package); - TRACE("Calculating file install states\n"); - set_file_install_states( package ); - if (!process_overrides( package, msi_get_property_int( package->db, szlevel, 1 ) )) { TRACE("Evaluating feature conditions\n"); @@ -2184,18 +2373,9 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) msiobj_release( &view->hdr ); } } - TRACE("Evaluating component conditions\n"); - LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) - { - if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE) - { - TRACE("Disabling component %s\n", debugstr_w(comp->Component)); - comp->Enabled = FALSE; - } - else - comp->Enabled = TRUE; - } + TRACE("Calculating file cost\n"); + calculate_file_cost( package ); msi_set_property( package->db, szCosting, szOne ); /* set default run level if not set */ @@ -2313,7 +2493,7 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, else ptr=value; - if (strstrW(value,szMulti)) + if (strstrW(value, szMulti)) *type = REG_MULTI_SZ; /* remove initial delimiter */ @@ -2467,6 +2647,7 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) { ERR("Could not create key %s\n", debugstr_w(keypath)); msi_free(uikey); + msi_free(keypath); return ERROR_SUCCESS; } @@ -2518,6 +2699,7 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) msi_free(value_data); msi_free(deformated); msi_free(uikey); + msi_free(keypath); return ERROR_SUCCESS; } @@ -2553,7 +2735,7 @@ static void delete_reg_key_or_value( HKEY hkey_root, LPCWSTR key, LPCWSTR value, { if ((res = RegDeleteTreeW( hkey_root, key ))) { - WARN("Failed to delete key %s (%d)\n", debugstr_w(key), res); + TRACE("Failed to delete key %s (%d)\n", debugstr_w(key), res); } return; } @@ -2562,12 +2744,11 @@ static void delete_reg_key_or_value( HKEY hkey_root, LPCWSTR key, LPCWSTR value, { if ((res = RegDeleteValueW( hkey, value ))) { - WARN("Failed to delete value %s (%d)\n", debugstr_w(value), res); + TRACE("Failed to delete value %s (%d)\n", debugstr_w(value), res); } res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL, &num_values, NULL, NULL, NULL, NULL ); RegCloseKey( hkey ); - if (!res && !num_subkeys && !num_values) { TRACE("Removing empty key %s\n", debugstr_w(key)); @@ -2575,7 +2756,7 @@ static void delete_reg_key_or_value( HKEY hkey_root, LPCWSTR key, LPCWSTR value, } return; } - WARN("Failed to open key %s (%d)\n", debugstr_w(key), res); + TRACE("Failed to open key %s (%d)\n", debugstr_w(key), res); } @@ -2868,7 +3049,7 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp ) { if (!cmp->KeyPath) - return resolve_folder(package,cmp->Directory,FALSE,FALSE,TRUE,NULL); + return resolve_target_folder( package, cmp->Directory, FALSE, TRUE, NULL ); if (cmp->Attributes & msidbComponentAttributesRegistryKeyPath) { @@ -2970,9 +3151,6 @@ static UINT ACTION_WriteSharedDLLsCount(LPCWSTR path, UINT count) return count; } -/* - * Return TRUE if the count should be written out and FALSE if not - */ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp ) { MSIFEATURE *feature; @@ -2981,6 +3159,7 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp ) /* only refcount DLLs */ if (comp->KeyPath == NULL || + comp->assembly || comp->Attributes & msidbComponentAttributesRegistryKeyPath || comp->Attributes & msidbComponentAttributesODBCDataSource) write = FALSE; @@ -3071,7 +3250,19 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) squash_guid(comp->ComponentId,squished_cc); msi_free(comp->FullKeypath); - comp->FullKeypath = resolve_keypath( package, comp ); + if (comp->assembly) + { + const WCHAR prefixW[] = {'<','\\',0}; + DWORD len = strlenW( prefixW ) + strlenW( comp->assembly->display_name ); + + comp->FullKeypath = msi_alloc( (len + 1) * sizeof(WCHAR) ); + if (comp->FullKeypath) + { + strcpyW( comp->FullKeypath, prefixW ); + strcatW( comp->FullKeypath, comp->assembly->display_name ); + } + } + else comp->FullKeypath = resolve_keypath( package, comp ); ACTION_RefCountComponent( package, comp ); @@ -3085,15 +3276,10 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) if (comp->ActionRequest == INSTALLSTATE_LOCAL || comp->ActionRequest == INSTALLSTATE_SOURCE) { - if (!comp->FullKeypath) - continue; - if (package->Context == MSIINSTALLCONTEXT_MACHINE) - rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, szLocalSid, - &hkey, TRUE); + rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, szLocalSid, &hkey, TRUE); else - rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, NULL, - &hkey, TRUE); + rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, NULL, &hkey, TRUE); if (rc != ERROR_SUCCESS) continue; @@ -3127,8 +3313,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) '>','=',' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ', '`','D','i','s','k','I','d','`',0}; - file = get_loaded_file(package, comp->KeyPath); - if (!file) + if (!comp->KeyPath || !(file = get_loaded_file(package, comp->KeyPath))) continue; row = MSI_QueryGetRecord(package->db, query, file->Sequence); @@ -3260,10 +3445,11 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) } comp->Action = INSTALLSTATE_LOCAL; - file = get_loaded_file( package, comp->KeyPath ); - if (!file) + if (!comp->KeyPath || !(file = get_loaded_file( package, comp->KeyPath ))) + { + TRACE("component has no key path\n"); return ERROR_SUCCESS; - + } ui_actiondata( package, szRegisterTypeLibraries, row ); module = LoadLibraryExW( file->TargetPath, NULL, LOAD_LIBRARY_AS_DATAFILE ); @@ -3286,8 +3472,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) helpid = MSI_RecordGetString(row,6); - if (helpid) - help = resolve_folder(package,helpid,FALSE,FALSE,TRUE,NULL); + if (helpid) help = resolve_target_folder( package, helpid, FALSE, TRUE, NULL ); res = RegisterTypeLib(tl_struct.ptLib,tl_struct.path,help); msi_free(help); @@ -3421,7 +3606,7 @@ static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row ) LPWSTR link_folder, link_file, filename; directory = MSI_RecordGetString( row, 2 ); - link_folder = resolve_folder( package, directory, FALSE, FALSE, TRUE, NULL ); + link_folder = resolve_target_folder( package, directory, FALSE, TRUE, NULL ); /* may be needed because of a bug somewhere else */ create_full_pathW( link_folder ); @@ -3542,7 +3727,7 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) if (!MSI_RecordIsNull(row,12)) { LPCWSTR wkdir = MSI_RecordGetString(row, 12); - path = resolve_folder(package, wkdir, FALSE, FALSE, TRUE, NULL); + path = resolve_target_folder( package, wkdir, FALSE, TRUE, NULL ); if (path) IShellLinkW_SetWorkingDirectory(sl, path); msi_free(path); @@ -3752,7 +3937,7 @@ static UINT msi_publish_sourcelist(MSIPACKAGE *package, HKEY hkey) LIST_FOR_EACH_ENTRY(info, &package->sourcelist_info, MSISOURCELISTINFO, entry) { - if (!lstrcmpW(info->property, INSTALLPROPERTY_LASTUSEDSOURCEW)) + if (!strcmpW( info->property, INSTALLPROPERTY_LASTUSEDSOURCEW )) msi_set_last_used_source(package->ProductCode, NULL, info->context, info->options, info->value); else @@ -4075,7 +4260,7 @@ static WCHAR *get_ini_file_name( MSIPACKAGE *package, MSIRECORD *row ) dirprop = MSI_RecordGetString( row, 3 ); if (dirprop) { - folder = resolve_folder( package, dirprop, FALSE, FALSE, TRUE, NULL ); + folder = resolve_target_folder( package, dirprop, FALSE, TRUE, NULL ); if (!folder) folder = msi_dup_property( package->db, dirprop ); } @@ -4855,7 +5040,7 @@ static UINT msi_unpublish_product(MSIPACKAGE *package, WCHAR *remove) return ERROR_FUNCTION_FAILED; } - if (!lstrcmpW(features[0], szAll)) + if (!strcmpW( features[0], szAll )) full_uninstall = TRUE; else { @@ -4874,21 +5059,16 @@ static UINT msi_unpublish_product(MSIPACKAGE *package, WCHAR *remove) MSIREG_DeleteUserDataProductKey(package->ProductCode); MSIREG_DeleteUninstallKey(package); - if (package->Context == MSIINSTALLCONTEXT_MACHINE) - { - MSIREG_DeleteLocalClassesProductKey(package->ProductCode); - MSIREG_DeleteLocalClassesFeaturesKey(package->ProductCode); - } - else - { - MSIREG_DeleteUserProductKey(package->ProductCode); - MSIREG_DeleteUserFeaturesKey(package->ProductCode); - } + MSIREG_DeleteLocalClassesProductKey(package->ProductCode); + MSIREG_DeleteLocalClassesFeaturesKey(package->ProductCode); + MSIREG_DeleteUserProductKey(package->ProductCode); + MSIREG_DeleteUserFeaturesKey(package->ProductCode); upgrade = msi_dup_property(package->db, szUpgradeCode); if (upgrade) { MSIREG_DeleteUserUpgradeCodesKey(upgrade); + MSIREG_DeleteClassesUpgradeCodesKey(upgrade); msi_free(upgrade); } @@ -5100,13 +5280,14 @@ static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param) { MSIPACKAGE *package = param; LPCWSTR compgroupid, component, feature, qualifier, text; - LPWSTR advertise = NULL, output = NULL; + LPWSTR advertise = NULL, output = NULL, existing = NULL, p, q; HKEY hkey = NULL; UINT rc; MSICOMPONENT *comp; MSIFEATURE *feat; DWORD sz; MSIRECORD *uirow; + int len; feature = MSI_RecordGetString(rec, 5); feat = get_loaded_feature(package, feature); @@ -5133,30 +5314,56 @@ static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param) rc = MSIREG_OpenUserComponentsKey(compgroupid, &hkey, TRUE); if (rc != ERROR_SUCCESS) goto end; - - text = MSI_RecordGetString(rec,4); - advertise = create_component_advertise_string(package, comp, feature); - - sz = strlenW(advertise); + advertise = create_component_advertise_string( package, comp, feature ); + text = MSI_RecordGetString( rec, 4 ); if (text) - sz += lstrlenW(text); + { + p = msi_alloc( (strlenW( advertise ) + strlenW( text ) + 1) * sizeof(WCHAR) ); + strcpyW( p, advertise ); + strcatW( p, text ); + msi_free( advertise ); + advertise = p; + } + existing = msi_reg_get_val_str( hkey, qualifier ); - sz+=3; - sz *= sizeof(WCHAR); - - output = msi_alloc_zero(sz); - strcpyW(output,advertise); - msi_free(advertise); - - if (text) - strcatW(output,text); + sz = strlenW( advertise ) + 1; + if (existing) + { + for (p = existing; *p; p += len) + { + len = strlenW( p ) + 1; + if (strcmpW( advertise, p )) sz += len; + } + } + if (!(output = msi_alloc( (sz + 1) * sizeof(WCHAR) ))) + { + rc = ERROR_OUTOFMEMORY; + goto end; + } + q = output; + if (existing) + { + for (p = existing; *p; p += len) + { + len = strlenW( p ) + 1; + if (strcmpW( advertise, p )) + { + memcpy( q, p, len * sizeof(WCHAR) ); + q += len; + } + } + } + strcpyW( q, advertise ); + q[strlenW( q ) + 1] = 0; msi_reg_set_val_multi_str( hkey, qualifier, output ); end: RegCloseKey(hkey); - msi_free(output); + msi_free( output ); + msi_free( advertise ); + msi_free( existing ); /* the UI chunk */ uirow = MSI_CreateRecord( 2 ); @@ -5272,11 +5479,11 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) MSIRECORD *row; MSIFILE *file; SC_HANDLE hscm, service = NULL; - LPCWSTR comp, depends, pass; - LPWSTR name = NULL, disp = NULL; - LPCWSTR load_order, serv_name, key; - DWORD serv_type, start_type; - DWORD err_control; + LPCWSTR comp, key; + LPWSTR name = NULL, disp = NULL, load_order = NULL, serv_name = NULL; + LPWSTR depends = NULL, pass = NULL, args = NULL, image_path = NULL; + DWORD serv_type, start_type, err_control; + SERVICE_DESCRIPTIONW sd = {NULL}; static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ', @@ -5292,22 +5499,24 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) goto done; } + comp = MSI_RecordGetString( rec, 12 ); + if (!get_loaded_component( package, comp )) + goto done; + start_type = MSI_RecordGetInteger(rec, 5); if (start_type == SERVICE_BOOT_START || start_type == SERVICE_SYSTEM_START) goto done; - depends = MSI_RecordGetString(rec, 8); - if (depends && *depends) - FIXME("Dependency list unhandled!\n"); - deformat_string(package, MSI_RecordGetString(rec, 2), &name); deformat_string(package, MSI_RecordGetString(rec, 3), &disp); serv_type = MSI_RecordGetInteger(rec, 4); err_control = MSI_RecordGetInteger(rec, 6); - load_order = MSI_RecordGetString(rec, 7); - serv_name = MSI_RecordGetString(rec, 9); - pass = MSI_RecordGetString(rec, 10); - comp = MSI_RecordGetString(rec, 12); + deformat_string(package, MSI_RecordGetString(rec, 7), &load_order); + deformat_string(package, MSI_RecordGetString(rec, 8), &depends); + deformat_string(package, MSI_RecordGetString(rec, 9), &serv_name); + deformat_string(package, MSI_RecordGetString(rec, 10), &pass); + deformat_string(package, MSI_RecordGetString(rec, 11), &args); + deformat_string(package, MSI_RecordGetString(rec, 13), &sd.lpDescription); /* fetch the service path */ row = MSI_QueryGetRecord(package->db, query, comp); @@ -5316,7 +5525,6 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) ERR("Control query failed!\n"); goto done; } - key = MSI_RecordGetString(row, 6); file = get_loaded_file(package, key); @@ -5327,20 +5535,44 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) goto done; } + if (!args || !args[0]) image_path = file->TargetPath; + else + { + int len = strlenW(file->TargetPath) + strlenW(args) + 2; + if (!(image_path = msi_alloc(len * sizeof(WCHAR)))) + return ERROR_OUTOFMEMORY; + + strcpyW(image_path, file->TargetPath); + strcatW(image_path, szSpace); + strcatW(image_path, args); + } service = CreateServiceW(hscm, name, disp, GENERIC_ALL, serv_type, - start_type, err_control, file->TargetPath, - load_order, NULL, NULL, serv_name, pass); + start_type, err_control, image_path, load_order, + NULL, depends, serv_name, pass); + if (!service) { if (GetLastError() != ERROR_SERVICE_EXISTS) ERR("Failed to create service %s: %d\n", debugstr_w(name), GetLastError()); } + else if (sd.lpDescription) + { + if (!ChangeServiceConfig2W(service, SERVICE_CONFIG_DESCRIPTION, &sd)) + WARN("failed to set service description %u\n", GetLastError()); + } + if (image_path != file->TargetPath) msi_free(image_path); done: CloseServiceHandle(service); CloseServiceHandle(hscm); msi_free(name); msi_free(disp); + msi_free(sd.lpDescription); + msi_free(load_order); + msi_free(serv_name); + msi_free(pass); + msi_free(depends); + msi_free(args); return ERROR_SUCCESS; } @@ -5780,27 +6012,15 @@ static UINT ACTION_DeleteServices( MSIPACKAGE *package ) return rc; } -static MSIFILE *msi_find_file( MSIPACKAGE *package, LPCWSTR filename ) -{ - MSIFILE *file; - - LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry) - { - if (!lstrcmpW(file->File, filename)) - return file; - } - - return NULL; -} - static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; LPWSTR driver, driver_path, ptr; WCHAR outpath[MAX_PATH]; - MSIFILE *driver_file, *setup_file; + MSIFILE *driver_file = NULL, *setup_file = NULL; + MSICOMPONENT *comp; MSIRECORD *uirow; - LPCWSTR desc; + LPCWSTR desc, file_key, component; DWORD len, usage; UINT r = ERROR_SUCCESS; @@ -5811,10 +6031,24 @@ static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param ) static const WCHAR usage_fmt[] = { 'F','i','l','e','U','s','a','g','e','=','1',0}; + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } + desc = MSI_RecordGetString(rec, 3); - driver_file = msi_find_file(package, MSI_RecordGetString(rec, 4)); - setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5)); + file_key = MSI_RecordGetString( rec, 4 ); + if (file_key) driver_file = get_loaded_file( package, file_key ); + + file_key = MSI_RecordGetString( rec, 5 ); + if (file_key) setup_file = get_loaded_file( package, file_key ); if (!driver_file) { @@ -5877,9 +6111,10 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param ) MSIPACKAGE *package = param; LPWSTR translator, translator_path, ptr; WCHAR outpath[MAX_PATH]; - MSIFILE *translator_file, *setup_file; + MSIFILE *translator_file = NULL, *setup_file = NULL; + MSICOMPONENT *comp; MSIRECORD *uirow; - LPCWSTR desc; + LPCWSTR desc, file_key, component; DWORD len, usage; UINT r = ERROR_SUCCESS; @@ -5888,10 +6123,24 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param ) static const WCHAR setup_fmt[] = { 'S','e','t','u','p','=','%','s',0}; + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } + desc = MSI_RecordGetString(rec, 3); - translator_file = msi_find_file(package, MSI_RecordGetString(rec, 4)); - setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5)); + file_key = MSI_RecordGetString( rec, 4 ); + if (file_key) translator_file = get_loaded_file( package, file_key ); + + file_key = MSI_RecordGetString( rec, 5 ); + if (file_key) setup_file = get_loaded_file( package, file_key ); if (!translator_file) { @@ -5948,8 +6197,9 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param ) static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; + MSICOMPONENT *comp; LPWSTR attrs; - LPCWSTR desc, driver; + LPCWSTR desc, driver, component; WORD request = ODBC_ADD_SYS_DSN; INT registration; DWORD len; @@ -5959,6 +6209,17 @@ static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param ) static const WCHAR attrs_fmt[] = { 'D','S','N','=','%','s',0 }; + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } + desc = MSI_RecordGetString(rec, 3); driver = MSI_RecordGetString(rec, 4); registration = MSI_RecordGetInteger(rec, 5); @@ -6036,9 +6297,21 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package ) static UINT ITERATE_RemoveODBCDriver( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; + MSICOMPONENT *comp; MSIRECORD *uirow; DWORD usage; - LPCWSTR desc; + LPCWSTR desc, component; + + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } desc = MSI_RecordGetString( rec, 3 ); if (!SQLRemoveDriverW( desc, FALSE, &usage )) @@ -6062,9 +6335,21 @@ static UINT ITERATE_RemoveODBCDriver( MSIRECORD *rec, LPVOID param ) static UINT ITERATE_RemoveODBCTranslator( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; + MSICOMPONENT *comp; MSIRECORD *uirow; DWORD usage; - LPCWSTR desc; + LPCWSTR desc, component; + + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } desc = MSI_RecordGetString( rec, 3 ); if (!SQLRemoveTranslatorW( desc, &usage )) @@ -6088,9 +6373,10 @@ static UINT ITERATE_RemoveODBCTranslator( MSIRECORD *rec, LPVOID param ) static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; + MSICOMPONENT *comp; MSIRECORD *uirow; LPWSTR attrs; - LPCWSTR desc, driver; + LPCWSTR desc, driver, component; WORD request = ODBC_REMOVE_SYS_DSN; INT registration; DWORD len; @@ -6098,6 +6384,17 @@ static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param ) static const WCHAR attrs_fmt[] = { 'D','S','N','=','%','s',0 }; + component = MSI_RecordGetString( rec, 2 ); + comp = get_loaded_component( package, component ); + if (!comp) + return ERROR_SUCCESS; + + if (!comp->Enabled) + { + TRACE("component is disabled\n"); + return ERROR_SUCCESS; + } + desc = MSI_RecordGetString( rec, 3 ); driver = MSI_RecordGetString( rec, 4 ); registration = MSI_RecordGetInteger( rec, 5 ); @@ -6235,7 +6532,7 @@ static UINT env_parse_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags ) else if (lstrlenW(*value) >= prefix_len) { ptr += lstrlenW(ptr) - prefix_len; - if (!lstrcmpW(ptr, prefix)) + if (!strcmpW( ptr, prefix )) { if ((ptr-1) > *value && *(ptr-1) == szSemiColon[0]) { @@ -6406,7 +6703,7 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param ) if (res != ERROR_SUCCESS) goto done; - if (flags & ENV_ACT_REMOVEMATCH && (!value || !lstrcmpW(data, value))) + if (flags & ENV_ACT_REMOVEMATCH && (!value || !strcmpW( data, value ))) { action = 0x4; res = RegDeleteValueW(env, name); @@ -6590,481 +6887,6 @@ static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package ) return rc; } -typedef struct tagMSIASSEMBLY -{ - struct list entry; - MSICOMPONENT *component; - MSIFEATURE *feature; - MSIFILE *file; - LPWSTR manifest; - LPWSTR application; - LPWSTR display_name; - DWORD attributes; - BOOL installed; -} MSIASSEMBLY; - -static HRESULT (WINAPI *pCreateAssemblyCache)(IAssemblyCache **ppAsmCache, - DWORD dwReserved); -static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion, - LPVOID pvReserved, HMODULE *phModDll); - -static BOOL init_functionpointers(void) -{ - HRESULT hr; - HMODULE hfusion; - HMODULE hmscoree; - - static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0}; - - hmscoree = LoadLibraryA("mscoree.dll"); - if (!hmscoree) - { - WARN("mscoree.dll not available\n"); - return FALSE; - } - - pLoadLibraryShim = (void *)GetProcAddress(hmscoree, "LoadLibraryShim"); - if (!pLoadLibraryShim) - { - WARN("LoadLibraryShim not available\n"); - FreeLibrary(hmscoree); - return FALSE; - } - - hr = pLoadLibraryShim(szFusion, NULL, NULL, &hfusion); - if (FAILED(hr)) - { - WARN("fusion.dll not available\n"); - FreeLibrary(hmscoree); - return FALSE; - } - - pCreateAssemblyCache = (void *)GetProcAddress(hfusion, "CreateAssemblyCache"); - - FreeLibrary(hmscoree); - return TRUE; -} - -static UINT install_assembly(MSIPACKAGE *package, MSIASSEMBLY *assembly, - LPWSTR path) -{ - IAssemblyCache *cache; - MSIRECORD *uirow; - HRESULT hr; - UINT r = ERROR_FUNCTION_FAILED; - - TRACE("installing assembly: %s\n", debugstr_w(path)); - - uirow = MSI_CreateRecord( 2 ); - MSI_RecordSetStringW( uirow, 2, assembly->display_name ); - ui_actiondata( package, szMsiPublishAssemblies, uirow ); - msiobj_release( &uirow->hdr ); - - if (assembly->feature) - msi_feature_set_state(package, assembly->feature, INSTALLSTATE_LOCAL); - - if (assembly->manifest) - FIXME("Manifest unhandled\n"); - - if (assembly->application) - { - FIXME("Assembly should be privately installed\n"); - return ERROR_SUCCESS; - } - - if (assembly->attributes == msidbAssemblyAttributesWin32) - { - FIXME("Win32 assemblies not handled\n"); - return ERROR_SUCCESS; - } - - hr = pCreateAssemblyCache(&cache, 0); - if (FAILED(hr)) - goto done; - - hr = IAssemblyCache_InstallAssembly(cache, 0, path, NULL); - if (FAILED(hr)) - ERR("Failed to install assembly: %s %08x\n", debugstr_w(path), hr); - - r = ERROR_SUCCESS; - -done: - IAssemblyCache_Release(cache); - return r; -} - -typedef struct tagASSEMBLY_LIST -{ - MSIPACKAGE *package; - IAssemblyCache *cache; - struct list *assemblies; -} ASSEMBLY_LIST; - -typedef struct tagASSEMBLY_NAME -{ - LPWSTR name; - LPWSTR version; - LPWSTR culture; - LPWSTR pubkeytoken; -} ASSEMBLY_NAME; - -static UINT parse_assembly_name(MSIRECORD *rec, LPVOID param) -{ - ASSEMBLY_NAME *asmname = param; - LPCWSTR name = MSI_RecordGetString(rec, 2); - LPWSTR val = msi_dup_record_field(rec, 3); - - static const WCHAR Name[] = {'N','a','m','e',0}; - static const WCHAR Version[] = {'V','e','r','s','i','o','n',0}; - static const WCHAR Culture[] = {'C','u','l','t','u','r','e',0}; - static const WCHAR PublicKeyToken[] = { - 'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0}; - - if (!strcmpiW(name, Name)) - asmname->name = val; - else if (!strcmpiW(name, Version)) - asmname->version = val; - else if (!strcmpiW(name, Culture)) - asmname->culture = val; - else if (!strcmpiW(name, PublicKeyToken)) - asmname->pubkeytoken = val; - else - msi_free(val); - - return ERROR_SUCCESS; -} - -static void append_str(LPWSTR *str, DWORD *size, LPCWSTR append) -{ - if (!*str) - { - *size = lstrlenW(append) + 1; - *str = msi_alloc((*size) * sizeof(WCHAR)); - lstrcpyW(*str, append); - return; - } - - (*size) += lstrlenW(append); - *str = msi_realloc(*str, (*size) * sizeof(WCHAR)); - lstrcatW(*str, append); -} - -static WCHAR *get_assembly_display_name( MSIDATABASE *db, MSICOMPONENT *comp ) -{ - static const WCHAR separator[] = {',',' ',0}; - static const WCHAR Version[] = {'V','e','r','s','i','o','n','=',0}; - static const WCHAR Culture[] = {'C','u','l','t','u','r','e','=',0}; - static const WCHAR PublicKeyToken[] = {'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=',0}; - 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','N','a','m','e','`',' ', - 'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`', - '=','\'','%','s','\'',0}; - ASSEMBLY_NAME name; - MSIQUERY *view; - LPWSTR display_name; - DWORD size; - UINT r; - - display_name = NULL; - memset( &name, 0, sizeof(ASSEMBLY_NAME) ); - - r = MSI_OpenQuery( db, &view, query, comp->Component ); - if (r != ERROR_SUCCESS) - return NULL; - - MSI_IterateRecords( view, NULL, parse_assembly_name, &name ); - msiobj_release( &view->hdr ); - - if (!name.name) - { - ERR("No assembly name specified!\n"); - return NULL; - } - - append_str( &display_name, &size, name.name ); - - if (name.version) - { - append_str( &display_name, &size, separator ); - append_str( &display_name, &size, Version ); - append_str( &display_name, &size, name.version ); - } - if (name.culture) - { - append_str( &display_name, &size, separator ); - append_str( &display_name, &size, Culture ); - append_str( &display_name, &size, name.culture ); - } - if (name.pubkeytoken) - { - append_str( &display_name, &size, separator ); - append_str( &display_name, &size, PublicKeyToken ); - append_str( &display_name, &size, name.pubkeytoken ); - } - - msi_free( name.name ); - msi_free( name.version ); - msi_free( name.culture ); - msi_free( name.pubkeytoken ); - - return display_name; -} - -static BOOL check_assembly_installed( MSIDATABASE *db, IAssemblyCache *cache, MSICOMPONENT *comp ) -{ - ASSEMBLY_INFO asminfo; - LPWSTR disp; - BOOL found = FALSE; - HRESULT hr; - - disp = get_assembly_display_name( db, comp ); - if (!disp) - return FALSE; - - memset( &asminfo, 0, sizeof(ASSEMBLY_INFO) ); - asminfo.cbAssemblyInfo = sizeof(ASSEMBLY_INFO); - - hr = IAssemblyCache_QueryAssemblyInfo( cache, QUERYASMINFO_FLAG_VALIDATE, disp, &asminfo ); - if (SUCCEEDED(hr)) - found = (asminfo.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED); - - msi_free( disp ); - return found; -} - -static UINT load_assembly(MSIRECORD *rec, LPVOID param) -{ - ASSEMBLY_LIST *list = param; - MSIASSEMBLY *assembly; - LPCWSTR component; - - assembly = msi_alloc_zero(sizeof(MSIASSEMBLY)); - if (!assembly) - return ERROR_OUTOFMEMORY; - - component = MSI_RecordGetString(rec, 1); - assembly->component = get_loaded_component(list->package, component); - if (!assembly->component) - return ERROR_SUCCESS; - - if (assembly->component->ActionRequest != INSTALLSTATE_LOCAL && - assembly->component->ActionRequest != INSTALLSTATE_SOURCE) - { - TRACE("Component not scheduled for installation: %s\n", debugstr_w(component)); - assembly->component->Action = assembly->component->Installed; - return ERROR_SUCCESS; - } - assembly->component->Action = assembly->component->ActionRequest; - - assembly->feature = find_feature_by_name(list->package, MSI_RecordGetString(rec, 2)); - assembly->file = msi_find_file(list->package, assembly->component->KeyPath); - - if (!assembly->file) - { - ERR("File %s not found\n", debugstr_w(assembly->component->KeyPath)); - return ERROR_FUNCTION_FAILED; - } - - assembly->manifest = strdupW(MSI_RecordGetString(rec, 3)); - assembly->application = strdupW(MSI_RecordGetString(rec, 4)); - assembly->attributes = MSI_RecordGetInteger(rec, 5); - - if (assembly->application) - { - WCHAR version[24]; - DWORD size = sizeof(version)/sizeof(WCHAR); - - /* FIXME: we should probably check the manifest file here */ - - if (!MsiGetFileVersionW(assembly->file->TargetPath, version, &size, NULL, NULL) && - (!assembly->file->Version || strcmpW(version, assembly->file->Version) >= 0)) - { - assembly->installed = TRUE; - } - } - else - assembly->installed = check_assembly_installed(list->package->db, - list->cache, - assembly->component); - - list_add_head(list->assemblies, &assembly->entry); - return ERROR_SUCCESS; -} - -static UINT load_assemblies(MSIPACKAGE *package, struct list *assemblies) -{ - IAssemblyCache *cache = NULL; - ASSEMBLY_LIST list; - MSIQUERY *view; - HRESULT hr; - UINT r; - - 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','`',0}; - - r = MSI_DatabaseOpenViewW(package->db, query, &view); - if (r != ERROR_SUCCESS) - return ERROR_SUCCESS; - - hr = pCreateAssemblyCache(&cache, 0); - if (FAILED(hr)) - return ERROR_FUNCTION_FAILED; - - list.package = package; - list.cache = cache; - list.assemblies = assemblies; - - r = MSI_IterateRecords(view, NULL, load_assembly, &list); - msiobj_release(&view->hdr); - - IAssemblyCache_Release(cache); - - return r; -} - -static void free_assemblies(struct list *assemblies) -{ - struct list *item, *cursor; - - LIST_FOR_EACH_SAFE(item, cursor, assemblies) - { - MSIASSEMBLY *assembly = LIST_ENTRY(item, MSIASSEMBLY, entry); - - list_remove(&assembly->entry); - msi_free(assembly->application); - msi_free(assembly->manifest); - msi_free(assembly->display_name); - msi_free(assembly); - } -} - -static BOOL find_assembly(struct list *assemblies, LPCWSTR file, MSIASSEMBLY **out) -{ - MSIASSEMBLY *assembly; - - LIST_FOR_EACH_ENTRY(assembly, assemblies, MSIASSEMBLY, entry) - { - if (!lstrcmpW(assembly->file->File, file)) - { - *out = assembly; - return TRUE; - } - } - - return FALSE; -} - -static BOOL installassembly_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, - LPWSTR *path, DWORD *attrs, PVOID user) -{ - MSIASSEMBLY *assembly; - WCHAR temppath[MAX_PATH]; - struct list *assemblies = user; - UINT r; - - if (!find_assembly(assemblies, file, &assembly)) - return FALSE; - - GetTempPathW(MAX_PATH, temppath); - PathAddBackslashW(temppath); - lstrcatW(temppath, assembly->file->FileName); - - if (action == MSICABEXTRACT_BEGINEXTRACT) - { - if (assembly->installed) - return FALSE; - - *path = strdupW(temppath); - *attrs = assembly->file->Attributes; - } - else if (action == MSICABEXTRACT_FILEEXTRACTED) - { - assembly->installed = TRUE; - - r = install_assembly(package, assembly, temppath); - if (r != ERROR_SUCCESS) - ERR("Failed to install assembly\n"); - } - - return TRUE; -} - -static UINT ACTION_MsiPublishAssemblies( MSIPACKAGE *package ) -{ - UINT r; - struct list assemblies = LIST_INIT(assemblies); - MSIASSEMBLY *assembly; - MSIMEDIAINFO *mi; - - if (!init_functionpointers() || !pCreateAssemblyCache) - return ERROR_FUNCTION_FAILED; - - r = load_assemblies(package, &assemblies); - if (r != ERROR_SUCCESS) - goto done; - - if (list_empty(&assemblies)) - goto done; - - mi = msi_alloc_zero(sizeof(MSIMEDIAINFO)); - if (!mi) - { - r = ERROR_OUTOFMEMORY; - goto done; - } - - LIST_FOR_EACH_ENTRY(assembly, &assemblies, MSIASSEMBLY, entry) - { - if (assembly->installed && !mi->is_continuous) - continue; - - if (assembly->file->IsCompressed) - { - if (assembly->file->disk_id != mi->disk_id || mi->is_continuous) - { - MSICABDATA data; - - r = ready_media(package, assembly->file, mi); - if (r != ERROR_SUCCESS) - { - ERR("Failed to ready media\n"); - break; - } - - data.mi = mi; - data.package = package; - data.cb = installassembly_cb; - data.user = &assemblies; - - if (!msi_cabextract(package, mi, &data)) - { - ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet)); - r = ERROR_FUNCTION_FAILED; - break; - } - } - } - else - { - LPWSTR source = resolve_file_source(package, assembly->file); - - r = install_assembly(package, assembly, source); - if (r != ERROR_SUCCESS) - ERR("Failed to install assembly\n"); - - msi_free(source); - } - - /* FIXME: write Installer assembly reg values */ - } - -done: - free_assemblies(&assemblies); - return r; -} - static UINT ACTION_ValidateProductID( MSIPACKAGE *package ) { LPWSTR key, template, id; @@ -7159,6 +6981,101 @@ static UINT ACTION_SetODBCFolders( MSIPACKAGE *package ) return ERROR_SUCCESS; } +static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param ) +{ + MSIPACKAGE *package = param; + const WCHAR *property = MSI_RecordGetString( rec, 1 ); + WCHAR *value; + + if ((value = msi_dup_property( package->db, property ))) + { + FIXME("remove %s\n", debugstr_w(value)); + msi_free( value ); + } + return ERROR_SUCCESS; +} + +static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package ) +{ + UINT r; + MSIQUERY *view; + + static const WCHAR query[] = + {'S','E','L','E','C','T',' ','A','c','t','i','o','n','P','r','o','p','e','r','t','y', + ' ','F','R','O','M',' ','U','p','g','r','a','d','e',0}; + + r = MSI_DatabaseOpenViewW( package->db, query, &view ); + if (r == ERROR_SUCCESS) + { + r = MSI_IterateRecords( view, NULL, ITERATE_RemoveExistingProducts, package ); + msiobj_release( &view->hdr ); + } + return ERROR_SUCCESS; +} + +static UINT ITERATE_MigrateFeatureStates( MSIRECORD *rec, LPVOID param ) +{ + MSIPACKAGE *package = param; + int attributes = MSI_RecordGetInteger( rec, 5 ); + + if (attributes & msidbUpgradeAttributesMigrateFeatures) + { + const WCHAR *upgrade_code = MSI_RecordGetString( rec, 1 ); + const WCHAR *version_min = MSI_RecordGetString( rec, 2 ); + const WCHAR *version_max = MSI_RecordGetString( rec, 3 ); + const WCHAR *language = MSI_RecordGetString( rec, 4 ); + HKEY hkey; + UINT r; + + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + { + r = MSIREG_OpenClassesUpgradeCodesKey( upgrade_code, &hkey, FALSE ); + if (r != ERROR_SUCCESS) + return ERROR_SUCCESS; + } + else + { + r = MSIREG_OpenUserUpgradeCodesKey( upgrade_code, &hkey, FALSE ); + if (r != ERROR_SUCCESS) + return ERROR_SUCCESS; + } + RegCloseKey( hkey ); + + FIXME("migrate feature states from %s version min %s version max %s language %s\n", + debugstr_w(upgrade_code), debugstr_w(version_min), + debugstr_w(version_max), debugstr_w(language)); + } + return ERROR_SUCCESS; +} + +static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package ) +{ + UINT r; + MSIQUERY *view; + + static const WCHAR query[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','U','p','g','r','a','d','e',0}; + + if (msi_get_property_int( package->db, szInstalled, 0 )) + { + TRACE("product is installed, skipping action\n"); + return ERROR_SUCCESS; + } + if (msi_get_property_int( package->db, szPreselected, 0 )) + { + TRACE("Preselected property is set, not migrating feature states\n"); + return ERROR_SUCCESS; + } + + r = MSI_DatabaseOpenViewW( package->db, query, &view ); + if (r == ERROR_SUCCESS) + { + r = MSI_IterateRecords( view, NULL, ITERATE_MigrateFeatureStates, package ); + msiobj_release( &view->hdr ); + } + return ERROR_SUCCESS; +} + static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, LPCSTR action, LPCWSTR table ) { @@ -7202,19 +7119,6 @@ static UINT ACTION_IsolateComponents( MSIPACKAGE *package ) return msi_unimplemented_action_stub( package, "IsolateComponents", table ); } -static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'U','p','g','r','a','d','e',0 }; - return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table ); -} - -static UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { - 'M','s','i','A','s','s','e','m','b','l','y',0 }; - return msi_unimplemented_action_stub( package, "MsiUnpublishAssemblies", table ); -} - static UINT ACTION_RMCCPSearch( MSIPACKAGE *package ) { static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 }; @@ -7239,12 +7143,6 @@ static UINT ACTION_InstallSFPCatalogFile( MSIPACKAGE *package ) return msi_unimplemented_action_stub( package, "InstallSFPCatalogFile", table ); } -static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'U','p','g','r','a','d','e',0 }; - return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table ); -} - typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*); static const struct @@ -7516,7 +7414,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, msi_set_sourcedir_props(package, FALSE); } - msi_parse_command_line( package, szCommandLine, FALSE ); + rc = msi_parse_command_line( package, szCommandLine, FALSE ); + if (rc != ERROR_SUCCESS) + return rc; msi_apply_transforms( package ); msi_apply_patches( package ); diff --git a/dll/win32/msi/appsearch.c b/dll/win32/msi/appsearch.c index dfab3960b01..c8aea77fd35 100644 --- a/dll/win32/msi/appsearch.c +++ b/dll/win32/msi/appsearch.c @@ -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); diff --git a/dll/win32/msi/assembly.c b/dll/win32/msi/assembly.c new file mode 100644 index 00000000000..5199a31fc70 --- /dev/null +++ b/dll/win32/msi/assembly.c @@ -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 + +#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; +} diff --git a/dll/win32/msi/classes.c b/dll/win32/msi/classes.c index beaf1f0ff93..d11f48b4eab 100644 --- a/dll/win32/msi/classes.c +++ b/dll/win32/msi/classes.c @@ -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; diff --git a/dll/win32/msi/cond.tab.c b/dll/win32/msi/cond.tab.c index e68723db89b..eff848b5507 100644 --- a/dll/win32/msi/cond.tab.c +++ b/dll/win32/msi/cond.tab.c @@ -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; diff --git a/dll/win32/msi/cond.y b/dll/win32/msi/cond.y index 03ea4938ade..5bde044d8c2 100644 --- a/dll/win32/msi/cond.y +++ b/dll/win32/msi/cond.y @@ -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; diff --git a/dll/win32/msi/create.c b/dll/win32/msi/create.c index 2e13d592552..c55390c8f7a 100644 --- a/dll/win32/msi/create.c +++ b/dll/win32/msi/create.c @@ -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; diff --git a/dll/win32/msi/custom.c b/dll/win32/msi/custom.c index b56139fb665..83a750dd578 100644 --- a/dll/win32/msi/custom.c +++ b/dll/win32/msi/custom.c @@ -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; diff --git a/dll/win32/msi/database.c b/dll/win32/msi/database.c index 3007d485b2b..598d7a8a022 100644 --- a/dll/win32/msi/database.c +++ b/dll/win32/msi/database.c @@ -19,6 +19,7 @@ */ #include +#include #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; diff --git a/dll/win32/msi/dialog.c b/dll/win32/msi/dialog.c index e0e27d129f4..40aa7dff692 100644 --- a/dll/win32/msi/dialog.c +++ b/dll/win32/msi/dialog.c @@ -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: diff --git a/dll/win32/msi/events.c b/dll/win32/msi/events.c index 157d18575f4..b888c1cada9 100644 --- a/dll/win32/msi/events.c +++ b/dll/win32/msi/events.c @@ -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); diff --git a/dll/win32/msi/files.c b/dll/win32/msi/files.c index 0ed9582c179..1f6187356e1 100644 --- a/dll/win32/msi/files.c +++ b/dll/win32/msi/files.c @@ -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; diff --git a/dll/win32/msi/font.c b/dll/win32/msi/font.c index 2128e922a56..7a493867c6a 100644 --- a/dll/win32/msi/font.c +++ b/dll/win32/msi/font.c @@ -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 ); diff --git a/dll/win32/msi/format.c b/dll/win32/msi/format.c index c4ff30f4111..b970dc1479f 100644 --- a/dll/win32/msi/format.c +++ b/dll/win32/msi/format.c @@ -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); diff --git a/dll/win32/msi/helpers.c b/dll/win32/msi/helpers.c index d3f2d9074a5..ffbe58b40e0 100644 --- a/dll/win32/msi/helpers.c +++ b/dll/win32/msi/helpers.c @@ -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; diff --git a/dll/win32/msi/insert.c b/dll/win32/msi/insert.c index 61807e9534e..03e1bd99795 100644 --- a/dll/win32/msi/insert.c +++ b/dll/win32/msi/insert.c @@ -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) diff --git a/dll/win32/msi/install.c b/dll/win32/msi/install.c index fa3e4f9e382..30a63e6d8bb 100644 --- a/dll/win32/msi/install.c +++ b/dll/win32/msi/install.c @@ -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; } diff --git a/dll/win32/msi/media.c b/dll/win32/msi/media.c index 788528e9b37..37d353017e1 100644 --- a/dll/win32/msi/media.c +++ b/dll/win32/msi/media.c @@ -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; diff --git a/dll/win32/msi/msi.c b/dll/win32/msi/msi.c index 7d1b9a55095..325a5b04634 100644 --- a/dll/win32/msi/msi.c +++ b/dll/win32/msi/msi.c @@ -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.@] */ diff --git a/dll/win32/msi/msi.rc b/dll/win32/msi/msi.rc index d81484f66bb..985304c348d 100644 --- a/dll/win32/msi/msi.rc +++ b/dll/win32/msi/msi.rc @@ -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" diff --git a/dll/win32/msi/msi.spec b/dll/win32/msi/msi.spec index fd047f8a652..c1e35530782 100644 --- a/dll/win32/msi/msi.spec +++ b/dll/win32/msi/msi.spec @@ -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 diff --git a/dll/win32/msi/msi_main.c b/dll/win32/msi/msi_main.c index df29184ab92..93f65430545 100644 --- a/dll/win32/msi/msi_main.c +++ b/dll/win32/msi/msi_main.c @@ -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 )); } diff --git a/dll/win32/msi/msipriv.h b/dll/win32/msi/msipriv.h index 0361ff42c6e..56a8a93c807 100644 --- a/dll/win32/msi/msipriv.h +++ b/dll/win32/msi/msipriv.h @@ -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); diff --git a/dll/win32/msi/msiquery.c b/dll/win32/msi/msiquery.c index cf6959391d3..4ccf5f65f8f 100644 --- a/dll/win32/msi/msiquery.c +++ b/dll/win32/msi/msiquery.c @@ -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 ) diff --git a/dll/win32/msi/msiserver.idl b/dll/win32/msi/msiserver.idl index e74c22c0b19..58c5b3cf99f 100644 --- a/dll/win32/msi/msiserver.idl +++ b/dll/win32/msi/msiserver.idl @@ -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; } } diff --git a/dll/win32/msi/package.c b/dll/win32/msi/package.c index 32576a0362c..c84c28a7516 100644 --- a/dll/win32/msi/package.c +++ b/dll/win32/msi/package.c @@ -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; diff --git a/dll/win32/msi/record.c b/dll/win32/msi/record.c index 7bc82814b2e..fc30f793436 100644 --- a/dll/win32/msi/record.c +++ b/dll/win32/msi/record.c @@ -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; diff --git a/dll/win32/msi/registry.c b/dll/win32/msi/registry.c index e83490f5e36..017aa2405c9 100644 --- a/dll/win32/msi/registry.c +++ b/dll/win32/msi/registry.c @@ -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) diff --git a/dll/win32/msi/script.c b/dll/win32/msi/script.c index 4f223daa8b0..27bbee1afda 100644 --- a/dll/win32/msi/script.c +++ b/dll/win32/msi/script.c @@ -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); diff --git a/dll/win32/msi/source.c b/dll/win32/msi/source.c index 8e4323a4711..881f3d26bf2 100644 --- a/dll/win32/msi/source.c +++ b/dll/win32/msi/source.c @@ -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) diff --git a/dll/win32/msi/sql.tab.c b/dll/win32/msi/sql.tab.c index 72e230ca837..f70760278e5 100644 --- a/dll/win32/msi/sql.tab.c +++ b/dll/win32/msi/sql.tab.c @@ -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; diff --git a/dll/win32/msi/sql.y b/dll/win32/msi/sql.y index 548a8782444..01217378534 100644 --- a/dll/win32/msi/sql.y +++ b/dll/win32/msi/sql.y @@ -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; diff --git a/dll/win32/msi/string.c b/dll/win32/msi/string.c index 5644749392f..406803337f4 100644 --- a/dll/win32/msi/string.c +++ b/dll/win32/msi/string.c @@ -58,15 +58,22 @@ struct string_table UINT *sorted; /* index */ }; +static BOOL validate_codepage( UINT codepage ) +{ + if (codepage != CP_ACP && !IsValidCodePage( codepage )) + { + WARN("invalid codepage %u\n", codepage); + return FALSE; + } + return TRUE; +} + static string_table *init_stringtable( int entries, UINT codepage ) { string_table *st; - if (codepage != CP_ACP && !IsValidCodePage(codepage)) - { - ERR("invalid codepage %d\n", codepage); + if (!validate_codepage( codepage )) return NULL; - } st = msi_alloc( sizeof (string_table) ); if( !st ) @@ -162,7 +169,7 @@ static int find_insert_index( const string_table *st, UINT string_id ) while (low <= high) { i = (low + high) / 2; - c = lstrcmpW( st->strings[string_id].str, st->strings[st->sorted[i]].str ); + c = strcmpW( st->strings[string_id].str, st->strings[st->sorted[i]].str ); if (c < 0) high = i - 1; @@ -402,7 +409,7 @@ UINT msi_string2idW( const string_table *st, LPCWSTR str, UINT *id ) while (low <= high) { i = (low + high) / 2; - c = lstrcmpW( str, st->strings[st->sorted[i]].str ); + c = strcmpW( str, st->strings[st->sorted[i]].str ); if (c < 0) high = i - 1; @@ -671,3 +678,18 @@ err: return ret; } + +UINT msi_get_string_table_codepage( const string_table *st ) +{ + return st->codepage; +} + +UINT msi_set_string_table_codepage( string_table *st, UINT codepage ) +{ + if (validate_codepage( codepage )) + { + st->codepage = codepage; + return ERROR_SUCCESS; + } + return ERROR_FUNCTION_FAILED; +} diff --git a/dll/win32/msi/table.c b/dll/win32/msi/table.c index 3e456ed56c4..14f4d307ddd 100644 --- a/dll/win32/msi/table.c +++ b/dll/win32/msi/table.c @@ -156,7 +156,7 @@ LPWSTR encode_streamname(BOOL bTable, LPCWSTR in) if( !bTable ) count = lstrlenW( in )+2; - out = msi_alloc( count*sizeof(WCHAR) ); + if (!(out = msi_alloc( count*sizeof(WCHAR) ))) return NULL; p = out; if( bTable ) @@ -512,7 +512,7 @@ static MSITABLE *find_cached_table( MSIDATABASE *db, LPCWSTR name ) MSITABLE *t; LIST_FOR_EACH_ENTRY( t, &db->tables, MSITABLE, entry ) - if( !lstrcmpW( name, t->name ) ) + if( !strcmpW( name, t->name ) ) return t; return NULL; @@ -731,7 +731,7 @@ static UINT get_table( MSIDATABASE *db, LPCWSTR name, MSITABLE **table_ret ) table->persistent = MSICONDITION_TRUE; lstrcpyW( table->name, name ); - if ( !lstrcmpW(name, szTables) || !lstrcmpW(name, szColumns) ) + if ( !strcmpW( name, szTables ) || !strcmpW( name, szColumns ) ) table->persistent = MSICONDITION_NONE; r = table_get_column_info( db, name, &table->colinfo, &table->col_count); @@ -766,7 +766,8 @@ static UINT read_table_int(BYTE *const *data, UINT row, UINT col, UINT bytes) static UINT save_table( MSIDATABASE *db, const MSITABLE *t, UINT bytes_per_strref ) { BYTE *rawdata = NULL; - UINT rawsize, r, i, j, row_size, row_count; + UINT rawsize, i, j, row_size, row_count; + UINT r = ERROR_FUNCTION_FAILED; /* Nothing to do for non-persistent tables */ if( t->persistent == MSICONDITION_FALSE ) @@ -816,7 +817,6 @@ static UINT save_table( MSIDATABASE *db, const MSITABLE *t, UINT bytes_per_strre if (id > 1 << bytes_per_strref * 8) { ERR("string id %u out of range\n", id); - r = ERROR_FUNCTION_FAILED; goto err; } } @@ -864,12 +864,12 @@ static UINT get_defaulttablecolumns( MSIDATABASE *db, LPCWSTR name, TRACE("%s\n", debugstr_w(name)); - if (!lstrcmpW( name, szTables )) + if (!strcmpW( name, szTables )) { p = _Tables_cols; n = 1; } - else if (!lstrcmpW( name, szColumns )) + else if (!strcmpW( name, szColumns )) { p = _Columns_cols; n = 4; @@ -1037,11 +1037,8 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name ) UINT r, table_id, i; MSITABLE *table; - 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}; - - if( !lstrcmpW( name, szTables ) || !lstrcmpW( name, szColumns ) || - !lstrcmpW( name, szStreams ) || !lstrcmpW( name, szStorages ) ) + if( !strcmpW( name, szTables ) || !strcmpW( name, szColumns ) || + !strcmpW( name, szStreams ) || !strcmpW( name, szStorages ) ) return TRUE; r = msi_string2idW( db->strings, name, &table_id ); @@ -1146,6 +1143,8 @@ static UINT msi_stream_name( const MSITABLEVIEW *tv, UINT row, LPWSTR *pstname ) type = tv->columns[i].type; if ( type & MSITYPE_KEY ) { + WCHAR number[0x20]; + r = TABLE_fetch_int( view, row, i+1, &ival ); if ( r != ERROR_SUCCESS ) goto err; @@ -1162,7 +1161,6 @@ static UINT msi_stream_name( const MSITABLEVIEW *tv, UINT row, LPWSTR *pstname ) else { static const WCHAR fmt[] = { '%','d',0 }; - WCHAR number[0x20]; UINT n = bytes_per_column( tv->db, &tv->columns[i], LONG_STR_BYTES ); switch( n ) @@ -1346,10 +1344,13 @@ static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT else if ( columninfo.type & MSITYPE_STRING ) { LPCWSTR sval = MSI_RecordGetString( rec, iField ); - - r = msi_string2idW(tv->db->strings, sval, pvalue); - if (r != ERROR_SUCCESS) - return ERROR_NOT_FOUND; + if (sval) + { + r = msi_string2idW(tv->db->strings, sval, pvalue); + if (r != ERROR_SUCCESS) + return ERROR_NOT_FOUND; + } + else *pvalue = 0; } else if ( bytes_per_column( tv->db, &columninfo, LONG_STR_BYTES ) == 2 ) { @@ -1432,7 +1433,6 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI LPCWSTR sval = MSI_RecordGetString( rec, i + 1 ); val = msi_addstringW( tv->db->strings, sval, -1, 1, persistent ? StringPersistent : StringNonPersistent ); - } else { @@ -1630,6 +1630,8 @@ static int compare_record( MSITABLEVIEW *tv, UINT row, MSIRECORD *rec ) for (i = 0; i < tv->num_cols; i++ ) { + if (!(tv->columns[i].type & MSITYPE_KEY)) continue; + r = get_table_value_from_record( tv, rec, i + 1, &ivalue ); if (r != ERROR_SUCCESS) return 1; @@ -1774,6 +1776,9 @@ static UINT msi_table_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) if (row != new_row + 1) return ERROR_FUNCTION_FAILED; + if(tv->order) + new_row = tv->order->reorder[new_row]; + return TABLE_set_row(view, new_row, rec, (1 << tv->num_cols) - 1); } @@ -2099,7 +2104,7 @@ static UINT TABLE_add_column(struct tagMSIVIEW *view, LPCWSTR table, UINT number msitable = find_cached_table(tv->db, table); for (i = 0; i < msitable->col_count; i++) { - if (!lstrcmpW(msitable->colinfo[i].colname, column)) + if (!strcmpW( msitable->colinfo[i].colname, column )) { InterlockedIncrement(&msitable->colinfo[i].ref_count); break; @@ -2340,14 +2345,11 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view ) MSITABLEVIEW *tv ; UINT r, sz; - static const WCHAR Streams[] = {'_','S','t','r','e','a','m','s',0}; - static const WCHAR Storages[] = {'_','S','t','o','r','a','g','e','s',0}; - TRACE("%p %s %p\n", db, debugstr_w(name), view ); - if ( !lstrcmpW( name, Streams ) ) + if ( !strcmpW( name, szStreams ) ) return STREAMS_CreateView( db, view ); - else if ( !lstrcmpW( name, Storages ) ) + else if ( !strcmpW( name, szStorages ) ) return STORAGES_CreateView( db, view ); sz = sizeof *tv + lstrlenW(name)*sizeof name[0] ; @@ -2593,7 +2595,7 @@ static void dump_record( MSIRECORD *rec ) n = MSI_RecordGetFieldCount( rec ); for( i=1; i<=n; i++ ) { - LPCWSTR sval = MSI_RecordGetString( rec, i ); + LPCWSTR sval; if( MSI_RecordIsNull( rec, i ) ) TRACE("row -> []\n"); @@ -2634,15 +2636,19 @@ static UINT* msi_record_to_row( const MSITABLEVIEW *tv, MSIRECORD *rec ) ! MSITYPE_IS_BINARY(tv->columns[i].type) ) { str = MSI_RecordGetString( rec, i+1 ); - r = msi_string2idW( tv->db->strings, str, &data[i] ); - - /* if there's no matching string in the string table, - these keys can't match any record, so fail now. */ - if( ERROR_SUCCESS != r ) + if (str) { - msi_free( data ); - return NULL; + r = msi_string2idW( tv->db->strings, str, &data[i] ); + + /* if there's no matching string in the string table, + these keys can't match any record, so fail now. */ + if (r != ERROR_SUCCESS) + { + msi_free( data ); + return NULL; + } } + else data[i] = 0; } else { @@ -2818,7 +2824,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, UINT number = MSI_NULL_INTEGER; UINT row = 0; - if (!lstrcmpW( name, szColumns )) + if (!strcmpW( name, szColumns )) { MSI_RecordGetStringW( rec, 1, table, &sz ); number = MSI_RecordGetInteger( rec, 2 ); @@ -2830,7 +2836,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, if ( number == MSI_NULL_INTEGER ) { /* reset the column number on a new table */ - if (lstrcmpW( coltable, table )) + if (strcmpW( coltable, table )) { colcol = 0; lstrcpyW( coltable, table ); @@ -2876,7 +2882,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, WARN("failed to insert row %u\n", r); } - if (number != MSI_NULL_INTEGER && !lstrcmpW( name, szColumns )) + if (number != MSI_NULL_INTEGER && !strcmpW( name, szColumns )) msi_update_table_columns( db, table ); msiobj_release( &rec->hdr ); @@ -2938,8 +2944,8 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg ) if ( name[0] != 0x4840 ) continue; - if ( !lstrcmpW( name+1, szStringPool ) || - !lstrcmpW( name+1, szStringData ) ) + if ( !strcmpW( name+1, szStringPool ) || + !strcmpW( name+1, szStringData ) ) continue; transform = msi_alloc_zero( sizeof(TRANSFORMDATA) ); @@ -2950,9 +2956,9 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg ) transform->name = strdupW( name + 1 ); - if ( !lstrcmpW( transform->name, szTables ) ) + if ( !strcmpW( transform->name, szTables ) ) tables = transform; - else if (!lstrcmpW( transform->name, szColumns ) ) + else if (!strcmpW( transform->name, szColumns ) ) columns = transform; TRACE("transform contains stream %s\n", debugstr_w(name)); @@ -2990,8 +2996,8 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg ) { transform = LIST_ENTRY( list_head( &transforms ), TRANSFORMDATA, entry ); - if ( lstrcmpW( transform->name, szColumns ) && - lstrcmpW( transform->name, szTables ) && + if ( strcmpW( transform->name, szColumns ) && + strcmpW( transform->name, szTables ) && ret == ERROR_SUCCESS ) { ret = msi_table_load_transform( db, stg, strings, transform, bytes_per_strref ); diff --git a/dll/win32/msi/where.c b/dll/win32/msi/where.c index 4c4db491474..35a6074a650 100644 --- a/dll/win32/msi/where.c +++ b/dll/win32/msi/where.c @@ -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" @@ -306,7 +307,7 @@ static UINT STRCMP_Evaluate( MSIWHEREVIEW *wv, UINT row, const struct expr *cond else if( r_str && ! l_str ) sr = -1; else - sr = lstrcmpW( l_str, r_str ); + sr = strcmpW( l_str, r_str ); *val = ( cond->u.expr.op == OP_EQ && ( sr == 0 ) ) || ( cond->u.expr.op == OP_NE && ( sr != 0 ) ); @@ -327,11 +328,15 @@ static UINT WHERE_evaluate( MSIWHEREVIEW *wv, UINT row, { case EXPR_COL_NUMBER: r = wv->table->ops->fetch_int( wv->table, row, cond->u.col_number, &tval ); + if( r != ERROR_SUCCESS ) + return r; *val = tval - 0x8000; return ERROR_SUCCESS; case EXPR_COL_NUMBER32: r = wv->table->ops->fetch_int( wv->table, row, cond->u.col_number, &tval ); + if( r != ERROR_SUCCESS ) + return r; *val = tval - 0x80000000; return r; diff --git a/dll/win32/shell32/clipboard.c b/dll/win32/shell32/clipboard.c index 1bdae631878..24fd0d0f514 100644 --- a/dll/win32/shell32/clipboard.c +++ b/dll/win32/shell32/clipboard.c @@ -47,52 +47,56 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { UINT i; - int rootlen = 0,size = 0; - WCHAR wszRootPath[MAX_PATH]; + int size = 0; WCHAR wszFileName[MAX_PATH]; - HGLOBAL hGlobal; + HGLOBAL hGlobal = NULL; DROPFILES *pDropFiles; int offset; + LPITEMIDLIST *pidls; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); + pidls = HeapAlloc(GetProcessHeap(), 0, cidl * sizeof(*pidls)); + if (!pidls) + goto cleanup; + /* get the size needed */ size = sizeof(DROPFILES); - SHGetPathFromIDListW(pidlRoot, wszRootPath); - PathAddBackslashW(wszRootPath); - rootlen = wcslen(wszRootPath); - for (i=0; ipFiles = offset * sizeof(WCHAR); pDropFiles->fWide = TRUE; - wcscpy(wszFileName, wszRootPath); - for (i=0; ilpstrTitle) - SetWindowTextA (hwnd, prfdp->lpstrTitle) ; + SetWindowTextW(hwnd, prfdp->lpstrTitle); + if (prfdp->lpstrDescription) + SetWindowTextW(GetDlgItem(hwnd, IDC_RUNDLG_DESCRIPTION), prfdp->lpstrDescription); + if (prfdp->uFlags & RFF_NOBROWSE) + { + HWND browse = GetDlgItem(hwnd, IDC_RUNDLG_BROWSE); + ShowWindow(browse, SW_HIDE); + EnableWindow(browse, FALSE); + } + if (prfdp->uFlags & RFF_NOLABEL) + ShowWindow(GetDlgItem(hwnd, IDC_RUNDLG_LABEL), SW_HIDE); + if (prfdp->uFlags & RFF_CALCDIRECTORY) + FIXME("RFF_CALCDIRECTORY not supported\n"); - SetClassLongPtrW (hwnd, GCLP_HICON, (LPARAM)prfdp->hIcon) ; - SendMessageW (GetDlgItem (hwnd, 12297), STM_SETICON, - (WPARAM)LoadIconW (NULL, (LPCWSTR)IDI_WINLOGO), 0); - FillList (GetDlgItem (hwnd, 12298), NULL) ; - SetFocus (GetDlgItem (hwnd, 12298)) ; + if (prfdp->hIcon == NULL) + prfdp->hIcon = LoadIconW(NULL, (LPCWSTR)IDI_WINLOGO); + SendMessageW(hwnd, WM_SETICON, ICON_BIG, (LPARAM)prfdp->hIcon); + SendMessageW(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)prfdp->hIcon); + SendMessageW(GetDlgItem(hwnd, IDC_RUNDLG_ICON), STM_SETICON, (WPARAM)prfdp->hIcon, 0); + + FillList (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), NULL, (prfdp->uFlags & RFF_NODEFAULT) == 0) ; + SetFocus (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH)) ; return TRUE ; case WM_COMMAND : @@ -331,46 +392,45 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR { case IDOK : { - HWND htxt = NULL ; - if ((ic = GetWindowTextLengthA (htxt = GetDlgItem (hwnd, 12298)))) + int ic ; + HWND htxt = GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH); + if ((ic = GetWindowTextLengthW (htxt))) { - psz = HeapAlloc( GetProcessHeap(), 0, (ic + 2) ); - GetWindowTextA (htxt, psz, ic + 1) ; - pdir = HeapAlloc( GetProcessHeap(), 0, (ic + 2) ); - if (pdir) - { - char * ptr; - strcpy(pdir, psz); - ptr = strrchr(pdir + 4, '\\'); - if(ptr) - ptr[0] = '\0'; - else - pdir[3] = '\0'; - } - if (ShellExecuteA(NULL, NULL, psz, NULL, pdir, SW_SHOWNORMAL) < (HINSTANCE)33) - { - char *pszSysMsg = NULL ; - FormatMessageA ( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError (), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&pszSysMsg, 0, NULL - ) ; - sprintf (szMsg, "Error: %s", pszSysMsg) ; - LocalFree ((HLOCAL)pszSysMsg) ; - MessageBoxA (hwnd, szMsg, NULL, MB_OK | MB_ICONEXCLAMATION) ; + WCHAR *psz, *parent=NULL ; + SHELLEXECUTEINFOW sei ; + ZeroMemory (&sei, sizeof(sei)) ; + sei.cbSize = sizeof(sei) ; + psz = HeapAlloc( GetProcessHeap(), 0, (ic + 1)*sizeof(WCHAR) ); + GetWindowTextW (htxt, psz, ic + 1) ; + + /* according to http://www.codeproject.com/KB/shell/runfiledlg.aspx we should send a + * WM_NOTIFY before execution */ + + sei.hwnd = hwnd; + sei.nShow = SW_SHOWNORMAL; + sei.lpFile = psz; + + if (prfdp->lpstrDirectory) + sei.lpDirectory = prfdp->lpstrDirectory; + else + sei.lpDirectory = parent = RunDlg_GetParentDir(sei.lpFile); + + if (!ShellExecuteExW( &sei )) + { HeapFree(GetProcessHeap(), 0, psz); - HeapFree(GetProcessHeap(), 0, pdir); + HeapFree(GetProcessHeap(), 0, parent); SendMessageA (htxt, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; return TRUE ; - } - FillList (htxt, psz) ; + } + + /* FillList is still ANSI */ + GetWindowTextA (htxt, (LPSTR)psz, ic + 1) ; + FillList (htxt, (LPSTR)psz, FALSE) ; + HeapFree(GetProcessHeap(), 0, psz); - HeapFree(GetProcessHeap(), 0, pdir); - EndDialog (hwnd, 0) ; + HeapFree(GetProcessHeap(), 0, parent); + EndDialog (hwnd, 0); } } @@ -378,55 +438,43 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR EndDialog (hwnd, 0) ; return TRUE ; - case 12288 : + case IDC_RUNDLG_BROWSE : { HMODULE hComdlg = NULL ; LPFNOFN ofnProc = NULL ; - static char szFName[1024] = "", szFileTitle[256] = "", szInitDir[768] = "" ; - static OPENFILENAMEA ofn = - { - sizeof (OPENFILENAMEA), - NULL, - NULL, - "Executable Files\0*.exe\0All Files\0*.*\0\0\0\0", - NULL, - 0, - 0, - szFName, - 1023, - szFileTitle, - 255, - (LPCSTR)szInitDir, - "Browse", - OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, - 0, - 0, - NULL, - 0, - (LPOFNHOOKPROC)NULL, - NULL - } ; + static const WCHAR comdlg32W[] = {'c','o','m','d','l','g','3','2',0}; + WCHAR szFName[1024] = {0}; + WCHAR filter[MAX_PATH], szCaption[MAX_PATH]; + OPENFILENAMEW ofn; - ofn.hwndOwner = hwnd ; + LoadStringW(shell32_hInstance, IDS_RUNDLG_BROWSE_FILTER, filter, MAX_PATH); + LoadStringW(shell32_hInstance, IDS_RUNDLG_BROWSE_CAPTION, szCaption, MAX_PATH); - if (NULL == (hComdlg = LoadLibraryExA ("comdlg32", NULL, 0))) - { - MessageBoxA (hwnd, "Unable to display dialog box (LoadLibraryEx) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ; + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(OPENFILENAMEW); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = filter; + ofn.lpstrFile = szFName; + ofn.nMaxFile = 1023; + ofn.lpstrTitle = szCaption; + ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST; + ofn.lpstrInitialDir = prfdp->lpstrDirectory; + + if (NULL == (hComdlg = LoadLibraryExW (comdlg32W, NULL, 0)) || + NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameW"))) + { + ERR("Couldn't get GetOpenFileName function entry (lib=%p, proc=%p)\n", hComdlg, ofnProc); + ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_RUNDLG_BROWSE_ERROR), NULL, MB_OK | MB_ICONERROR); return TRUE ; - } + } - if ((LPFNOFN)NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameA"))) - { - MessageBoxA (hwnd, "Unable to display dialog box (GetProcAddress) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ; - return TRUE ; - } - - ofnProc (&ofn) ; - - SetFocus (GetDlgItem (hwnd, IDOK)) ; - SetWindowTextA (GetDlgItem (hwnd, 12298), szFName) ; - SendMessageA (GetDlgItem (hwnd, 12298), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; - SetFocus (GetDlgItem (hwnd, IDOK)) ; + if (ofnProc(&ofn)) + { + SetFocus (GetDlgItem (hwnd, IDOK)) ; + SetWindowTextW (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), szFName) ; + SendMessageW (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; + SetFocus (GetDlgItem (hwnd, IDOK)) ; + } FreeLibrary (hComdlg) ; @@ -439,7 +487,8 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR } /* This grabs the MRU list from the registry and fills the combo for the "Run" dialog above */ -static void FillList (HWND hCb, char *pszLatest) +/* fShowDefault ignored if pszLatest != NULL */ +static void FillList (HWND hCb, char *pszLatest, BOOL fShowDefault) { HKEY hkey ; /* char szDbgMsg[256] = "" ; */ @@ -511,7 +560,7 @@ static void FillList (HWND hCb, char *pszLatest) MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ; */ SendMessageA (hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd) ; - if (!Nix) + if (!Nix && fShowDefault) { SetWindowTextA (hCb, pszCmd) ; SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; @@ -609,6 +658,7 @@ int WINAPI RestartDialogEx(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, D return 0; } + /************************************************************************* * LogoffWindowsDialog [SHELL32.54] */ @@ -622,6 +672,7 @@ int WINAPI LogoffWindowsDialog(HWND hWndOwner) return 0; } + /************************************************************************* * RestartDialog [SHELL32.59] */ diff --git a/dll/win32/shell32/lang/bg-BG.rc b/dll/win32/shell32/lang/bg-BG.rc index 6e9b67ad41f..36a5cf5e23b 100644 --- a/dll/win32/shell32/lang/bg-BG.rc +++ b/dll/win32/shell32/lang/bg-BG.rc @@ -669,6 +669,12 @@ BEGIN IDS_LOGOFF_TITLE "" IDS_LOGOFF_PROMPT " ?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + // shell folder path default values IDS_PROGRAMS " \\" IDS_PERSONAL "" @@ -718,8 +724,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE " " IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE " " - IDS_PICK_ICON_FILTER " (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER " \0*.exe\0" + IDS_PICK_ICON_FILTER " (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER " (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "" IDS_VIRTUAL_DRIVER " " IDS_BAT_FILE " " diff --git a/dll/win32/shell32/lang/ca-ES.rc b/dll/win32/shell32/lang/ca-ES.rc index 214028e7d8e..80f7cb41b05 100644 --- a/dll/win32/shell32/lang/ca-ES.rc +++ b/dll/win32/shell32/lang/ca-ES.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/cs-CZ.rc b/dll/win32/shell32/lang/cs-CZ.rc index dff2e85bff0..728fce9fd08 100644 --- a/dll/win32/shell32/lang/cs-CZ.rc +++ b/dll/win32/shell32/lang/cs-CZ.rc @@ -655,6 +655,12 @@ BEGIN IDS_LOGOFF_TITLE "Odhlsit se" IDS_LOGOFF_PROMPT "Opravdu se chcete odhlsit?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Nabdka Start\\Programy" IDS_PERSONAL "Dokumenty" @@ -704,8 +710,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Dostupn msto" IDS_EMPTY_BITBUCKET "Vysypat ko" IDS_PICK_ICON_TITLE "Zvolit ikonu" - IDS_PICK_ICON_FILTER "Soubory ikon (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Spustiteln soubory\0*.exe\0" + IDS_PICK_ICON_FILTER "Soubory ikon (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Spustiteln soubory (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Sloka" IDS_VIRTUAL_DRIVER "Virtuln ovlada zazen" IDS_BAT_FILE "ReactOS dvkov soubor" diff --git a/dll/win32/shell32/lang/da-DK.rc b/dll/win32/shell32/lang/da-DK.rc index 9ad423c95e4..00472085917 100644 --- a/dll/win32/shell32/lang/da-DK.rc +++ b/dll/win32/shell32/lang/da-DK.rc @@ -657,6 +657,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programmer" IDS_PERSONAL "Mine Dokumenter" @@ -706,8 +712,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/de-DE.rc b/dll/win32/shell32/lang/de-DE.rc index 5610af6fa30..62921561703 100644 --- a/dll/win32/shell32/lang/de-DE.rc +++ b/dll/win32/shell32/lang/de-DE.rc @@ -672,6 +672,12 @@ BEGIN IDS_LOGOFF_TITLE "Ausloggen" IDS_LOGOFF_PROMPT "Mchten Sie sich ausloggen?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Startmen\\Programme" IDS_PERSONAL "Eigene Dateien" @@ -721,8 +727,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "freier Speicher" IDS_EMPTY_BITBUCKET "Papierkorb leeren" IDS_PICK_ICON_TITLE "Symbol auswhlen" - IDS_PICK_ICON_FILTER "Symboldateien(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Programme\0*.exe\0" + IDS_PICK_ICON_FILTER "Symboldateien (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Programme (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Dateiordner" IDS_VIRTUAL_DRIVER "Virtueller Gertetreiber" IDS_BAT_FILE "ReactOS-Stapelverarbeitungsdatei" diff --git a/dll/win32/shell32/lang/el-GR.rc b/dll/win32/shell32/lang/el-GR.rc index a269d68ed2f..80506a2cedf 100644 --- a/dll/win32/shell32/lang/el-GR.rc +++ b/dll/win32/shell32/lang/el-GR.rc @@ -669,6 +669,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL " " @@ -718,8 +724,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/en-GB.rc b/dll/win32/shell32/lang/en-GB.rc index 5d8f02c9a47..0b9ff3f713d 100644 --- a/dll/win32/shell32/lang/en-GB.rc +++ b/dll/win32/shell32/lang/en-GB.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/en-US.rc b/dll/win32/shell32/lang/en-US.rc index 04df98d1e60..6eaac708f7a 100644 --- a/dll/win32/shell32/lang/en-US.rc +++ b/dll/win32/shell32/lang/en-US.rc @@ -679,6 +679,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -728,8 +734,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/es-ES.rc b/dll/win32/shell32/lang/es-ES.rc index c619493d3f2..0bbfc4677c2 100644 --- a/dll/win32/shell32/lang/es-ES.rc +++ b/dll/win32/shell32/lang/es-ES.rc @@ -113,8 +113,8 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Mensaje" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Si", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Si &a todo", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&S", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "S &a todo", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&No", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Cancelar", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP ICON "", IDD_ICON, 10, 10, 16, 16 @@ -156,7 +156,7 @@ CAPTION "Ejecutar" FONT 8, "MS Shell Dlg" BEGIN ICON "", 12297, 7, 11, 18, 20, WS_VISIBLE - LTEXT "Introduzca el nombre de un programa, carpeta, documento o recurso de Internet, y ReactOS lo abrir para usted.", 12289, 36, 11, 182, 24 + LTEXT "Introduzca el nombre de un programa, carpeta, documento o recurso de Internet y ReactOS lo abrir para usted.", 12289, 36, 11, 182, 24 LTEXT "&Abrir:", 12305, 7, 39, 24, 10 CONTROL "", 12298, "COMBOBOX", WS_TABSTOP | WS_GROUP | WS_VSCROLL | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWN, 36, 37, 183, 100 DEFPUSHBUTTON "Aceptar", IDOK, 62, 63, 50, 14, WS_TABSTOP @@ -681,6 +681,12 @@ BEGIN IDS_LOGOFF_TITLE "Cerrar sesin" IDS_LOGOFF_PROMPT "Desea cerrar la sesin?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Imposible mostrar el dilogo Ejecutar (error interno)" + IDS_RUNDLG_BROWSE_ERROR "Imposible mostrar el dilogo Examinar (error interno)" + IDS_RUNDLG_BROWSE_CAPTION "Examinar" + IDS_RUNDLG_BROWSE_FILTER "Archivos ejecutables (*.exe)\0*.exe\0Todos los archivos (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Men Inicio\\Programas" IDS_PERSONAL "Mis documentos" @@ -730,8 +736,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Espacio disponible" IDS_EMPTY_BITBUCKET "Vaciar Papelera de reciclaje" IDS_PICK_ICON_TITLE "Seleccione un icono" - IDS_PICK_ICON_FILTER "Archivos de iconos(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Programas\0*.exe\0" + IDS_PICK_ICON_FILTER "Archivos de iconos (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Programas (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Directorio" IDS_VIRTUAL_DRIVER "Controlador de dispositivo virtual" IDS_BAT_FILE "Archivo por lotes ReactOS" diff --git a/dll/win32/shell32/lang/fi-FI.rc b/dll/win32/shell32/lang/fi-FI.rc index 6469ce1b7b5..125a07d9c50 100644 --- a/dll/win32/shell32/lang/fi-FI.rc +++ b/dll/win32/shell32/lang/fi-FI.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Kynnist\\Ohjelmat" IDS_PERSONAL "Omat tiedostot" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/fr-FR.rc b/dll/win32/shell32/lang/fr-FR.rc index 0ba3b4473f2..4083d654d9a 100644 --- a/dll/win32/shell32/lang/fr-FR.rc +++ b/dll/win32/shell32/lang/fr-FR.rc @@ -672,6 +672,12 @@ BEGIN IDS_LOGOFF_TITLE "Se dconnecter" IDS_LOGOFF_PROMPT "Voulez-vous vous dconnecter ?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Dmarrer\\Programmes" IDS_PERSONAL "Mes documents" @@ -721,8 +727,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Espace disponible" IDS_EMPTY_BITBUCKET "Vider la Corbeille" IDS_PICK_ICON_TITLE "Choisir une icne" - IDS_PICK_ICON_FILTER "Fichiers d'icnes (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Fichiers excutables\0*.exe\0" + IDS_PICK_ICON_FILTER "Fichiers d'icnes (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Fichiers excutables (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Dossier" IDS_VIRTUAL_DRIVER "Pilote de priphrique virtuel" IDS_BAT_FILE "Fichier Batch ReactOS" diff --git a/dll/win32/shell32/lang/hu-HU.rc b/dll/win32/shell32/lang/hu-HU.rc index e45819a2d47..7eb015d8ced 100644 --- a/dll/win32/shell32/lang/hu-HU.rc +++ b/dll/win32/shell32/lang/hu-HU.rc @@ -671,6 +671,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "Dokumentumok" @@ -720,8 +726,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/it-IT.rc b/dll/win32/shell32/lang/it-IT.rc index 824eb22a88e..59d76488d56 100644 --- a/dll/win32/shell32/lang/it-IT.rc +++ b/dll/win32/shell32/lang/it-IT.rc @@ -111,8 +111,8 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Messaggi" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Si", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Si a &tutti", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&S", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "S a &tutti", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&No", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Annulla", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP ICON "", IDD_ICON, 10, 10, 16, 16 @@ -154,7 +154,7 @@ CAPTION "" FONT 8, "MS Shell Dlg" BEGIN ICON "", 12297, 7, 11, 18, 20, WS_VISIBLE - LTEXT "Digitare il nome del programma, della cartella, del documento o della risorsa internet, e ReactOS la aprir.", 12289, 36, 11, 182, 18 + LTEXT "Digitare il nome del programma, della cartella, del documento o della risorsa Internet, e ReactOS la aprir.", 12289, 36, 11, 182, 18 LTEXT "&Apri:", 12305, 7, 39, 24, 10 CONTROL "", 12298, "COMBOBOX", WS_TABSTOP | WS_GROUP | WS_VSCROLL | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWN, 36, 37, 183, 100 DEFPUSHBUTTON "OK", IDOK, 62, 63, 50, 14, WS_TABSTOP @@ -297,7 +297,7 @@ BEGIN LTEXT "Disco %s", 14009, 100, 170, 40, 10 PUSHBUTTON "Pulitura disco", 14010, 180, 175, 50, 15, WS_TABSTOP CHECKBOX "Comprimere il disco per recuperare dello spazio", 14011, 15, 205, 180, 10, WS_DISABLED - CHECKBOX "Permettere di indicizzare questo disco al servizio di indicizzazione per avere ricerche dei file pi rapide", 14012, 15, 220, 200, 10, WS_DISABLED + CHECKBOX "Indicizza il disco per ricerche pi rapide dei file", 14012, 15, 220, 200, 10, WS_DISABLED END DRIVE_EXTRA_DLG DIALOGEX 0, 0, 240, 230 @@ -445,7 +445,7 @@ CAPTION "Conferma della sovrascrittura dei file" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "&S", IDYES, 20, 122, 60, 14 - PUSHBUTTON "S &tutti", 12807, 85, 122, 60, 14 + PUSHBUTTON "S a &tutti", 12807, 85, 122, 60, 14 PUSHBUTTON "&No", IDNO, 150, 122, 60, 14 PUSHBUTTON "Annulla", IDCANCEL, 215, 122, 60, 14 ICON 146, -1, 11, 10, 21, 20, SS_REALSIZECONTROL @@ -466,7 +466,7 @@ CAPTION "Chiudi sessione di ReactOS" FONT 8, "MS Shell Dlg" BEGIN ICON 45, 14344, 10, 10, 21, 20, SS_REALSIZECONTROL - LTEXT "Siete sicuro di voler Chiudere la sessione?", -1, 43, 11, 140, 22 + LTEXT "Siete sicuro di voler chiudere la sessione?", -1, 43, 11, 140, 22 DEFPUSHBUTTON "&Chiudi sessione", IDOK, 57, 40, 60, 14 PUSHBUTTON "Annulla", IDCANCEL, 122, 40, 60, 14 END @@ -583,7 +583,7 @@ BEGIN GROUPBOX "Opzioni per la verifica del disco", -1, 7, 6, 179, 50 PUSHBUTTON "Annulla", IDCANCEL, 118, 100, 60, 14 AUTOCHECKBOX "Correggi automaticamente gli errori", 14000, 16, 15, 155, 10 - AUTOCHECKBOX "&Ricerca dei settori difettosi e tentativo di correzione", 14001, 16, 30, 165, 10 + AUTOCHECKBOX "&Cerca i settori difettosi e tenta di correggerli", 14001, 16, 30, 165, 10 CONTROL "", 14002, "MSCTLS_PROGRESS32", 16, 7, 60, 170, 8 LTEXT "", 14003, 60, 80, 170, 10 END @@ -679,6 +679,12 @@ BEGIN IDS_LOGOFF_TITLE "Disconnetti" IDS_LOGOFF_PROMPT "Volete disconnettervi?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Impossibile mostrare il dialogo Eseguire (errore interno)" + IDS_RUNDLG_BROWSE_ERROR "Impossibile mostrare il dialogo sfoglia (errore interno)" + IDS_RUNDLG_BROWSE_CAPTION "Sfoglia" + IDS_RUNDLG_BROWSE_FILTER "File Eseguibili (*.exe)\0*.exe\0Tutti i file (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Avvio\\Programmi" IDS_PERSONAL "Documenti Personali" @@ -727,22 +733,22 @@ BEGIN IDS_RECYCLEBIN_LOCATION "Posizione del Cestino" IDS_RECYCLEBIN_DISKSPACE "Spazio disponibile" IDS_EMPTY_BITBUCKET "Svuota cestino" - IDS_PICK_ICON_TITLE "Scegliere un icona" - IDS_PICK_ICON_FILTER "Icone(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "File eseguibili\0*.exe\0" + IDS_PICK_ICON_TITLE "Scegliere un'icona" + IDS_PICK_ICON_FILTER "Icone (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0Tutti i file (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "File eseguibili (*.exe)\0*.exe\0Tutti i file (*.*)\0*.*\0" IDS_DIRECTORY "Cartella" - IDS_VIRTUAL_DRIVER "Virtual Device Driver" - IDS_BAT_FILE "ReactOS Batch File" - IDS_CMD_FILE "ReactOS Command Script" - IDS_COM_FILE "Applicazione Dos" + IDS_VIRTUAL_DRIVER "Driver di Periferica Virtuale" + IDS_BAT_FILE "File Batch ReactOS" + IDS_CMD_FILE "Script di comandi ReactOS" + IDS_COM_FILE "Applicazione DOS" IDS_CPL_FILE "Elemento del pannello di controllo" IDS_CUR_FILE "Cursore" IDS_DLL_FILE "Estensione di applicazione" - IDS_DRV_FILE "Device Driver" + IDS_DRV_FILE "Driver di periferica" IDS_EXE_FILE "Applicazione" IDS_FON_FILE "Font" IDS_TTF_FILE "TrueType Font" - IDS_HLP_FILE "Help File" + IDS_HLP_FILE "File della guida" IDS_INI_FILE "Impostazioni di configurazione" IDS_LNK_FILE "Collegamento" IDS_SYS_FILE "File di sistema" diff --git a/dll/win32/shell32/lang/ja-JP.rc b/dll/win32/shell32/lang/ja-JP.rc index c09ba106660..a671c6137a2 100644 --- a/dll/win32/shell32/lang/ja-JP.rc +++ b/dll/win32/shell32/lang/ja-JP.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "X^[g j[\\vO" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "pł̈" IDS_EMPTY_BITBUCKET "ݔɂ" IDS_PICK_ICON_TITLE "ACȒI" - IDS_PICK_ICON_FILTER "ACRt@C(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "s”\\ t@C\0*.exe\0" + IDS_PICK_ICON_FILTER "ACRt@C (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "s”\\ t@C (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "tH_" IDS_VIRTUAL_DRIVER "z foCX hCo" IDS_BAT_FILE "ReactOS ob` t@C" diff --git a/dll/win32/shell32/lang/ko-KR.rc b/dll/win32/shell32/lang/ko-KR.rc index 98981f74213..b5d0dfa5c91 100644 --- a/dll/win32/shell32/lang/ko-KR.rc +++ b/dll/win32/shell32/lang/ko-KR.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/nl-NL.rc b/dll/win32/shell32/lang/nl-NL.rc index 1689e2a3bae..fa176ce352d 100644 --- a/dll/win32/shell32/lang/nl-NL.rc +++ b/dll/win32/shell32/lang/nl-NL.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/no-NO.rc b/dll/win32/shell32/lang/no-NO.rc index f02aa64fecd..e576cb47d54 100644 --- a/dll/win32/shell32/lang/no-NO.rc +++ b/dll/win32/shell32/lang/no-NO.rc @@ -671,6 +671,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start-meny\\Programmer" IDS_PERSONAL "Mine dokumenter" @@ -720,8 +726,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Ledig plass" IDS_EMPTY_BITBUCKET "Tm papirkurven" IDS_PICK_ICON_TITLE "Velg Ikon" - IDS_PICK_ICON_FILTER "Ikon Fil(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Kjrbare filer\0*.exe\0" + IDS_PICK_ICON_FILTER "Ikon Fil (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Kjrbare filer (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Mappe" IDS_VIRTUAL_DRIVER "Virtuell enhetdriver" IDS_BAT_FILE "ReactOS Batch fil" diff --git a/dll/win32/shell32/lang/pl-PL.rc b/dll/win32/shell32/lang/pl-PL.rc index c9a4d40a48b..cb33116bd45 100644 --- a/dll/win32/shell32/lang/pl-PL.rc +++ b/dll/win32/shell32/lang/pl-PL.rc @@ -675,6 +675,12 @@ BEGIN IDS_LOGOFF_TITLE "Wyloguj" IDS_LOGOFF_PROMPT "Czy chcesz si wylogowa z systemu?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Nie mog wywietli okna Uruchom (bd wewntrzny)" + IDS_RUNDLG_BROWSE_ERROR "Nie mog wywietli okna Przegldaj (bd wewntrzny)" + IDS_RUNDLG_BROWSE_CAPTION "Przegldaj" + IDS_RUNDLG_BROWSE_FILTER "Programy (*.exe)\0*.exe\0Wszystkie pliki (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Start\\Programy" IDS_PERSONAL "Moje dokumenty" @@ -724,8 +730,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Pozostao wolnego miejsca" IDS_EMPTY_BITBUCKET "Oprnij Kosz" IDS_PICK_ICON_TITLE "Wybierz ikon" - IDS_PICK_ICON_FILTER "Pliki ikon(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Programy\0*.exe\0" + IDS_PICK_ICON_FILTER "Pliki ikon (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0Wszystkie pliki (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Programy (*.exe)\0*.exe\0Wszystkie pliki (*.*)\0*.*\0" IDS_DIRECTORY "Katalog" IDS_VIRTUAL_DRIVER "Sterownik urzdzenia wirtualnego" IDS_BAT_FILE "Plik wsadowy ReactOS" @@ -759,5 +765,5 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Domylny rozmiar jednostki alokacji" IDS_COPY_OF "Kopia" - IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." + IDS_SHLEXEC_NOASSOC "aden program nie jest skonfigurowane by otwiera pliki tego typu." END diff --git a/dll/win32/shell32/lang/pt-BR.rc b/dll/win32/shell32/lang/pt-BR.rc index 7679014ff37..ef97edbea18 100644 --- a/dll/win32/shell32/lang/pt-BR.rc +++ b/dll/win32/shell32/lang/pt-BR.rc @@ -670,6 +670,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Iniciar\\Programas" IDS_PERSONAL "Meus Documentos" @@ -719,8 +725,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/pt-PT.rc b/dll/win32/shell32/lang/pt-PT.rc index 2d99ca47e97..6daead85f4a 100644 --- a/dll/win32/shell32/lang/pt-PT.rc +++ b/dll/win32/shell32/lang/pt-PT.rc @@ -671,6 +671,12 @@ BEGIN IDS_LOGOFF_TITLE "Terminar a sesso" IDS_LOGOFF_PROMPT "Pretende terminar a sesso?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Menu Iniciar\\Programas" IDS_PERSONAL "OS Meus Documentos" @@ -720,8 +726,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Espao Disponvel" IDS_EMPTY_BITBUCKET "Esvaziar Reciclagem" IDS_PICK_ICON_TITLE "Escolha cone" - IDS_PICK_ICON_FILTER "Ficheiros de cones(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Ficheiros Executveis\0*.exe\0" + IDS_PICK_ICON_FILTER "Ficheiros de cones (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Ficheiros Executveis (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Pasta" IDS_VIRTUAL_DRIVER "Driver de Dispositivo Virtual" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/ro-RO.rc b/dll/win32/shell32/lang/ro-RO.rc index fb24c2ba437..47d05ffc62a 100644 --- a/dll/win32/shell32/lang/ro-RO.rc +++ b/dll/win32/shell32/lang/ro-RO.rc @@ -671,6 +671,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Meniu Start\\Programe" IDS_PERSONAL "Documentele mele" @@ -720,8 +726,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Spațiu disponibil" IDS_EMPTY_BITBUCKET "Golire Coș de gunoi" IDS_PICK_ICON_TITLE "Alegere pictogramă" - IDS_PICK_ICON_FILTER "Fișiere pictogramă (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Fișiere executabile\0*.exe\0" + IDS_PICK_ICON_FILTER "Fișiere pictogramă (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Fișiere executabile (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Dosar" IDS_VIRTUAL_DRIVER "Driver dispozitiv virtual" IDS_BAT_FILE "Fișier serie de comenzi ReactOS" diff --git a/dll/win32/shell32/lang/ru-RU.rc b/dll/win32/shell32/lang/ru-RU.rc index daf4f2ce16b..b3ecbdb4909 100644 --- a/dll/win32/shell32/lang/ru-RU.rc +++ b/dll/win32/shell32/lang/ru-RU.rc @@ -667,6 +667,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS " \\" IDS_PERSONAL " " @@ -716,8 +722,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE " " IDS_EMPTY_BITBUCKET " " IDS_PICK_ICON_TITLE " " - IDS_PICK_ICON_FILTER " (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER " \0*.exe\0" + IDS_PICK_ICON_FILTER " (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER " (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "" IDS_VIRTUAL_DRIVER " " IDS_BAT_FILE " ReactOS" diff --git a/dll/win32/shell32/lang/sk-SK.rc b/dll/win32/shell32/lang/sk-SK.rc index 848d343ecdd..7620ce08536 100644 --- a/dll/win32/shell32/lang/sk-SK.rc +++ b/dll/win32/shell32/lang/sk-SK.rc @@ -674,6 +674,12 @@ BEGIN IDS_LOGOFF_TITLE "Odhlsi" IDS_LOGOFF_PROMPT "Naozaj sa chcete odhlsi?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Ponuka tart\\Programy" IDS_PERSONAL "Moje dokumenty" @@ -723,8 +729,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Dostupn miesto" IDS_EMPTY_BITBUCKET "Vyprzdni K" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Sbory ikon(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Spustiten sbory\0*.exe\0" + IDS_PICK_ICON_FILTER "Sbory ikon (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Spustiten sbory (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Prieinok" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "Dvkov sbor systmu ReactOS" diff --git a/dll/win32/shell32/lang/sl-SI.rc b/dll/win32/shell32/lang/sl-SI.rc index 9789ec3841c..594cdf88181 100644 --- a/dll/win32/shell32/lang/sl-SI.rc +++ b/dll/win32/shell32/lang/sl-SI.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/sv-SE.rc b/dll/win32/shell32/lang/sv-SE.rc index 4ddd5c36520..0238edfae66 100644 --- a/dll/win32/shell32/lang/sv-SE.rc +++ b/dll/win32/shell32/lang/sv-SE.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/tr-TR.rc b/dll/win32/shell32/lang/tr-TR.rc index 633936f625a..d5ca8c1fb25 100644 --- a/dll/win32/shell32/lang/tr-TR.rc +++ b/dll/win32/shell32/lang/tr-TR.rc @@ -668,6 +668,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programlar" IDS_PERSONAL "Belgelerim" @@ -717,8 +723,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/uk-UA.rc b/dll/win32/shell32/lang/uk-UA.rc index b65aea75945..bd2cfda8c93 100644 --- a/dll/win32/shell32/lang/uk-UA.rc +++ b/dll/win32/shell32/lang/uk-UA.rc @@ -681,6 +681,12 @@ BEGIN IDS_LOGOFF_TITLE " " IDS_LOGOFF_PROMPT " ?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL " " @@ -730,8 +736,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE " " IDS_EMPTY_BITBUCKET " " IDS_PICK_ICON_TITLE " " - IDS_PICK_ICON_FILTER " (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER " \0*.exe\0" + IDS_PICK_ICON_FILTER " (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER " (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "" IDS_VIRTUAL_DRIVER " " IDS_BAT_FILE " ReactOS" diff --git a/dll/win32/shell32/lang/zh-CN.rc b/dll/win32/shell32/lang/zh-CN.rc index aa54e3eecb6..693a2890407 100644 --- a/dll/win32/shell32/lang/zh-CN.rc +++ b/dll/win32/shell32/lang/zh-CN.rc @@ -657,6 +657,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "ҵĵ" @@ -705,8 +711,8 @@ BEGIN IDS_RECYCLEBIN_LOCATION "Recycle Bin Location" IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/lang/zh-TW.rc b/dll/win32/shell32/lang/zh-TW.rc index fcf7abf9f7b..ea14a6d300c 100644 --- a/dll/win32/shell32/lang/zh-TW.rc +++ b/dll/win32/shell32/lang/zh-TW.rc @@ -669,6 +669,12 @@ BEGIN IDS_LOGOFF_TITLE "Log Off" IDS_LOGOFF_PROMPT "Do you want to log off?" + /* Run File dialog */ + IDS_RUNDLG_ERROR "Unable to display Run File dialog box (internal error)" + IDS_RUNDLG_BROWSE_ERROR "Unable to display Browse dialog box (internal error)" + IDS_RUNDLG_BROWSE_CAPTION "Browse" + IDS_RUNDLG_BROWSE_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" + /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" IDS_PERSONAL "My Documents" @@ -718,8 +724,8 @@ BEGIN IDS_RECYCLEBIN_DISKSPACE "Space Available" IDS_EMPTY_BITBUCKET "Empty Recycle Bin" IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" + IDS_PICK_ICON_FILTER "Icon Files (*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0All Files (*.*)\0*.*\0" + IDS_OPEN_WITH_FILTER "Executable Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0" IDS_DIRECTORY "Folder" IDS_VIRTUAL_DRIVER "Virtual Device Driver" IDS_BAT_FILE "ReactOS Batch File" diff --git a/dll/win32/shell32/she_ocmenu.c b/dll/win32/shell32/she_ocmenu.c index c2e9c05ede5..9aea9e1b48e 100644 --- a/dll/win32/shell32/she_ocmenu.c +++ b/dll/win32/shell32/she_ocmenu.c @@ -537,8 +537,8 @@ SetProgrammAsDefaultHandler(LPCWSTR szFileName, WCHAR * szAppName) void BrowseForApplication(HWND hwndDlg) { - WCHAR szBuffer[30] = {0}; - WCHAR szFilter[30] = {0}; + WCHAR szBuffer[64] = {0}; + WCHAR szFilter[256] = {0}; WCHAR szPath[MAX_PATH]; OPENFILENAMEW ofn; OPEN_WITH_CONTEXT Context; diff --git a/dll/win32/shell32/shell32.spec b/dll/win32/shell32/shell32.spec index c9d0956479b..923139fcfb1 100644 --- a/dll/win32/shell32/shell32.spec +++ b/dll/win32/shell32/shell32.spec @@ -58,9 +58,9 @@ 58 stdcall -noname ParseField(str long ptr long) ParseFieldAW # Fixme 59 stdcall RestartDialog(long wstr long) 60 stdcall -noname ExitWindowsDialog(long) # Fixme -61 stdcall -noname RunFileDlg(long long long str str long) RunFileDlg # Fixme +61 stdcall -noname RunFileDlg(long long long wstr wstr long) RunFileDlg # Fixme? 62 stdcall PickIconDlg(long long long long) -63 stdcall GetFileNameFromBrowse(long long long long str str str) +63 stdcall GetFileNameFromBrowse(long long long long wstr wstr wstr) 64 stdcall DriveType(long) 65 stdcall -noname InvalidateDriveType(long) 66 stdcall IsNetDrive(long) diff --git a/dll/win32/shell32/shresdef.h b/dll/win32/shell32/shresdef.h index 43e409cbf44..23ff1ecfd2c 100644 --- a/dll/win32/shell32/shresdef.h +++ b/dll/win32/shell32/shresdef.h @@ -142,6 +142,11 @@ #define IDS_FILE_TYPES 174 #define IDS_FILE_DETAILS 175 +#define IDS_RUNDLG_ERROR 180 +#define IDS_RUNDLG_BROWSE_ERROR 181 +#define IDS_RUNDLG_BROWSE_CAPTION 182 +#define IDS_RUNDLG_BROWSE_FILTER 183 + #define IDS_OPEN_VERB 300 #define IDS_RUNAS_VERB 301 #define IDS_EDIT_VERB 302 @@ -195,6 +200,13 @@ #define OPEN_WITH_PROGRAMM_DLG 0x4001 #define IDD_SH_FILE_COPY 0x4002 +/* run dialog */ +#define IDC_RUNDLG_DESCRIPTION 12289 +#define IDC_RUNDLG_BROWSE 12288 +#define IDC_RUNDLG_ICON 12297 +#define IDC_RUNDLG_EDITPATH 12298 +#define IDC_RUNDLG_LABEL 12305 + /* ID's of the ShellAbout controls */ // Part 1 - ID's identical to Windows Server 2003 SP1's shell32.dll #define IDD_SHELL_ABOUT 0x3810 diff --git a/dll/win32/shell32/undocshell.h b/dll/win32/shell32/undocshell.h index 8911967b694..f9ec7cdb5ce 100644 --- a/dll/win32/shell32/undocshell.h +++ b/dll/win32/shell32/undocshell.h @@ -70,6 +70,15 @@ HRESULT WINAPI SHILCreateFromPathW ( BOOL WINAPI StrRetToStrNA(LPSTR,DWORD,LPSTRRET,const ITEMIDLIST*); BOOL WINAPI StrRetToStrNW(LPWSTR,DWORD,LPSTRRET,const ITEMIDLIST*); + +/**************************************************************************** +* SHChangeNotifyRegister API +*/ +#define SHCNRF_InterruptLevel 0x0001 +#define SHCNRF_ShellLevel 0x0002 +#define SHCNRF_RecursiveInterrupt 0x1000 /* Must be combined with SHCNRF_InterruptLevel */ +#define SHCNRF_NewDelivery 0x8000 /* Messages use shared memory */ + /**************************************************************************** * Shell Common Dialogs */ @@ -100,9 +109,9 @@ typedef struct void WINAPI RunFileDlg( HWND hwndOwner, HICON hIcon, - LPCSTR lpstrDirectory, - LPCSTR lpstrTitle, - LPCSTR lpstrDescription, + LPCWSTR lpstrDirectory, + LPCWSTR lpstrTitle, + LPCWSTR lpstrDescription, UINT uFlags); void WINAPI ExitWindowsDialog(HWND hwndOwner); diff --git a/dll/win32/user32/controls/combo.c b/dll/win32/user32/controls/combo.c index 422953195c4..adeac610d78 100644 --- a/dll/win32/user32/controls/combo.c +++ b/dll/win32/user32/controls/combo.c @@ -2232,6 +2232,7 @@ LRESULT WINAPI ComboWndProc_common( HWND hwnd, UINT message, case CB_LIMITTEXT: if( lphc->wState & CBF_EDIT ) return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam); + break; // ReactOS!!! removed at revision 38715 case WM_UPDATEUISTATE: if (unicode) diff --git a/dll/win32/user32/controls/edit.c b/dll/win32/user32/controls/edit.c index 65f36797f63..b07830f3ce9 100644 --- a/dll/win32/user32/controls/edit.c +++ b/dll/win32/user32/controls/edit.c @@ -4477,8 +4477,8 @@ LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP { NtUserSetWindowFNID(hwnd, FNID_EDIT); } - } -#endif + } +#endif TRACE("hwnd=%p msg=%x (%s) wparam=%lx lparam=%lx\n", hwnd, msg, SPY_GetMsgName(msg, hwnd), wParam, lParam); diff --git a/dll/win32/user32/controls/icontitle.c b/dll/win32/user32/controls/icontitle.c index 467ca076c52..6daf27ec125 100644 --- a/dll/win32/user32/controls/icontitle.c +++ b/dll/win32/user32/controls/icontitle.c @@ -189,6 +189,18 @@ LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg, HWND owner = GetWindow( hWnd, GW_OWNER ); if (!IsWindow(hWnd)) return 0; +#ifdef __REACTOS__ // Do this now, remove after Server side is fixed. + PWND pWnd; + + pWnd = ValidateHwnd(hWnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(hWnd, FNID_ICONTITLE); + } + } +#endif switch( msg ) { @@ -201,6 +213,11 @@ LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg, hIconTitleFont = CreateFontIndirectA( &logFont ); } return (hIconTitleFont ? 0 : -1); +#ifdef __REACTOS__ + case WM_DESTROY: + NtUserSetWindowFNID(hWnd, FNID_DESTROY); + break; +#endif case WM_NCHITTEST: return HTCAPTION; case WM_NCMOUSEMOVE: diff --git a/dll/win32/user32/controls/regcontrol.c b/dll/win32/user32/controls/regcontrol.c index 47a45cebc7d..9980f06a6df 100644 --- a/dll/win32/user32/controls/regcontrol.c +++ b/dll/win32/user32/controls/regcontrol.c @@ -87,8 +87,23 @@ LRESULT WINAPI MsgWindowProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { + PWND pWnd; + + pWnd = ValidateHwnd(hwnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(hwnd, FNID_MESSAGEWND); + } + } + if (message == WM_NCCREATE) return TRUE; - return 0; + + if (message == WM_DESTROY) + NtUserSetWindowFNID(hwnd, FNID_DESTROY); + + return DefWindowProc(hwnd, message, wParam, lParam ); } LRESULT diff --git a/dll/win32/user32/controls/scrollbar.c b/dll/win32/user32/controls/scrollbar.c index ad0f4f25729..b238b64532a 100644 --- a/dll/win32/user32/controls/scrollbar.c +++ b/dll/win32/user32/controls/scrollbar.c @@ -1248,12 +1248,31 @@ ScrollBarWndProc(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARA return 0; } +#ifdef __REACTOS__ // Do this now, remove after Server side is fixed. + PWND pWnd; + + pWnd = ValidateHwnd(Wnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(Wnd, FNID_SCROLLBAR); + } + } +#endif + switch (Msg) { case WM_CREATE: IntScrollCreateScrollBar(Wnd, (LPCREATESTRUCTW) lParam); break; +#ifdef __REACTOS__ + case WM_DESTROY: + NtUserSetWindowFNID(Wnd, FNID_DESTROY); + return DefWindowProc(Wnd, Msg, wParam, lParam ); +#endif + //#if 0 /* FIXME */ case WM_ENABLE: { diff --git a/dll/win32/user32/controls/static.c b/dll/win32/user32/controls/static.c index bc0b92b361c..d421eae4671 100644 --- a/dll/win32/user32/controls/static.c +++ b/dll/win32/user32/controls/static.c @@ -813,6 +813,9 @@ static void STATIC_PaintRectfn( HWND hwnd, HDC hdc, DWORD style ) GetClientRect( hwnd, &rc); /* FIXME: send WM_CTLCOLORSTATIC */ +#ifdef __REACTOS__ + hBrush = STATIC_SendWmCtlColorStatic(hwnd, hdc); // Always sent.... +#endif switch (style & SS_TYPEMASK) { case SS_BLACKRECT: diff --git a/dll/win32/user32/misc/desktop.c b/dll/win32/user32/misc/desktop.c index e6ee527d274..1a317beb3f3 100644 --- a/dll/win32/user32/misc/desktop.c +++ b/dll/win32/user32/misc/desktop.c @@ -564,13 +564,22 @@ OpenDesktopW( ACCESS_MASK dwDesiredAccess) { UNICODE_STRING DesktopName; + OBJECT_ATTRIBUTES ObjectAttributes; RtlInitUnicodeString(&DesktopName, lpszDesktop); - return NtUserOpenDesktop( - &DesktopName, - dwFlags, - dwDesiredAccess); + InitializeObjectAttributes(&ObjectAttributes, + &DesktopName, + OBJ_CASE_INSENSITIVE, + GetProcessWindowStation(), + 0); + + if( fInherit == TRUE ) + { + ObjectAttributes.Attributes |= OBJ_INHERIT; + } + + return NtUserOpenDesktop(&ObjectAttributes, dwFlags, dwDesiredAccess); } diff --git a/dll/win32/user32/misc/display.c b/dll/win32/user32/misc/display.c index e9de23e4e4a..196ff76d369 100644 --- a/dll/win32/user32/misc/display.c +++ b/dll/win32/user32/misc/display.c @@ -1,29 +1,8 @@ /* - * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * * PROJECT: ReactOS user32.dll * FILE: lib/user32/misc/dde.c * PURPOSE: DDE * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) - * UPDATE HISTORY: - * 09-05-2001 CSH Created */ /* INCLUDES ******************************************************************/ @@ -47,53 +26,52 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32); */ BOOL WINAPI EnumDisplayDevicesA( - LPCSTR lpDevice, - DWORD iDevNum, - PDISPLAY_DEVICEA lpDisplayDevice, - DWORD dwFlags) + LPCSTR lpDevice, + DWORD iDevNum, + PDISPLAY_DEVICEA lpDisplayDevice, + DWORD dwFlags) { - BOOL rc; - UNICODE_STRING Device; - DISPLAY_DEVICEW DisplayDeviceW; + BOOL rc; + UNICODE_STRING Device; + DISPLAY_DEVICEW DisplayDeviceW; - if ( !RtlCreateUnicodeStringFromAsciiz ( &Device, (PCSZ)lpDevice ) ) + if (!RtlCreateUnicodeStringFromAsciiz(&Device, (PCSZ)lpDevice)) { - SetLastError ( ERROR_OUTOFMEMORY ); - return FALSE; + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; } - RtlZeroMemory(&DisplayDeviceW, sizeof(DISPLAY_DEVICEW)); - DisplayDeviceW.cb = sizeof(DISPLAY_DEVICEW); - rc = NtUserEnumDisplayDevices ( - &Device, - iDevNum, - &DisplayDeviceW, - dwFlags ); - if (rc) + RtlZeroMemory(&DisplayDeviceW, sizeof(DISPLAY_DEVICEW)); + DisplayDeviceW.cb = sizeof(DISPLAY_DEVICEW); + rc = NtUserEnumDisplayDevices(&Device, + iDevNum, + &DisplayDeviceW, + dwFlags); + if (rc) { - /* Copy result from DisplayDeviceW to lpDisplayDevice */ - lpDisplayDevice->StateFlags = DisplayDeviceW.StateFlags; - WideCharToMultiByte(CP_ACP,0, - DisplayDeviceW.DeviceName,wcslen(DisplayDeviceW.DeviceName), - lpDisplayDevice->DeviceName,sizeof(lpDisplayDevice->DeviceName) / sizeof(lpDisplayDevice->DeviceName[0]), - NULL,NULL); - WideCharToMultiByte(CP_ACP,0, - DisplayDeviceW.DeviceString,wcslen(DisplayDeviceW.DeviceString), - lpDisplayDevice->DeviceString,sizeof(lpDisplayDevice->DeviceString) / sizeof(lpDisplayDevice->DeviceString[0]), - NULL,NULL); - WideCharToMultiByte(CP_ACP,0, - DisplayDeviceW.DeviceID,wcslen(DisplayDeviceW.DeviceID), - lpDisplayDevice->DeviceID,sizeof(lpDisplayDevice->DeviceID) / sizeof(lpDisplayDevice->DeviceID[0]), - NULL,NULL); - WideCharToMultiByte(CP_ACP,0, - DisplayDeviceW.DeviceKey,wcslen(DisplayDeviceW.DeviceKey), - lpDisplayDevice->DeviceKey,sizeof(lpDisplayDevice->DeviceKey) / sizeof(lpDisplayDevice->DeviceKey[0]), - NULL,NULL); + /* Copy result from DisplayDeviceW to lpDisplayDevice. Buffers have the same size so result is always NULL terminated. */ + lpDisplayDevice->StateFlags = DisplayDeviceW.StateFlags; + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceName, -1, + lpDisplayDevice->DeviceName, + sizeof(lpDisplayDevice->DeviceName) / sizeof(lpDisplayDevice->DeviceName[0]), + NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceString, -1, + lpDisplayDevice->DeviceString, + sizeof(lpDisplayDevice->DeviceString) / sizeof(lpDisplayDevice->DeviceString[0]), + NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceID, -1, + lpDisplayDevice->DeviceID, + sizeof(lpDisplayDevice->DeviceID) / sizeof(lpDisplayDevice->DeviceID[0]), + NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, DisplayDeviceW.DeviceKey, -1, + lpDisplayDevice->DeviceKey, + sizeof(lpDisplayDevice->DeviceKey) / sizeof(lpDisplayDevice->DeviceKey[0]), + NULL, NULL); } - RtlFreeUnicodeString ( &Device ); + RtlFreeUnicodeString(&Device); - return rc; + return rc; } @@ -103,23 +81,23 @@ EnumDisplayDevicesA( BOOL WINAPI EnumDisplayDevicesW( - LPCWSTR lpDevice, - DWORD iDevNum, - PDISPLAY_DEVICE lpDisplayDevice, - DWORD dwFlags) + LPCWSTR lpDevice, + DWORD iDevNum, + PDISPLAY_DEVICE lpDisplayDevice, + DWORD dwFlags) { - UNICODE_STRING Device; - BOOL rc; + UNICODE_STRING Device; + BOOL rc; - RtlInitUnicodeString ( &Device, lpDevice ); + RtlInitUnicodeString(&Device, lpDevice); - rc = NtUserEnumDisplayDevices ( - &Device, - iDevNum, - lpDisplayDevice, - dwFlags ); + rc = NtUserEnumDisplayDevices( + &Device, + iDevNum, + lpDisplayDevice, + dwFlags); - return rc; + return rc; } @@ -129,71 +107,71 @@ EnumDisplayDevicesW( BOOL WINAPI EnumDisplayMonitors( - HDC hdc, - LPCRECT lprcClip, - MONITORENUMPROC lpfnEnum, - LPARAM dwData) + HDC hdc, + LPCRECT lprcClip, + MONITORENUMPROC lpfnEnum, + LPARAM dwData) { - INT iCount, i; - HMONITOR *hMonitorList; - LPRECT pRectList; - HANDLE hHeap; + INT iCount, i; + HMONITOR *hMonitorList; + LPRECT pRectList; + HANDLE hHeap; - /* get list of monitors/rects */ - iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, NULL, NULL, 0); - if (iCount < 0) + /* get list of monitors/rects */ + iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, NULL, NULL, 0); + if (iCount < 0) { - /* FIXME: SetLastError() */ - return FALSE; + /* FIXME: SetLastError() */ + return FALSE; } - if (iCount == 0) + if (iCount == 0) { - return TRUE; + return TRUE; } - hHeap = GetProcessHeap(); - hMonitorList = HeapAlloc(hHeap, 0, sizeof (HMONITOR) * iCount); - if (hMonitorList == NULL) + hHeap = GetProcessHeap(); + hMonitorList = HeapAlloc(hHeap, 0, sizeof (HMONITOR) * iCount); + if (hMonitorList == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; } - pRectList = HeapAlloc(hHeap, 0, sizeof (RECT) * iCount); - if (pRectList == NULL) + pRectList = HeapAlloc(hHeap, 0, sizeof (RECT) * iCount); + if (pRectList == NULL) { - HeapFree(hHeap, 0, hMonitorList); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + HeapFree(hHeap, 0, hMonitorList); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; } - iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, hMonitorList, pRectList, iCount); - if (iCount <= 0) + iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, hMonitorList, pRectList, iCount); + if (iCount <= 0) { - /* FIXME: SetLastError() */ - HeapFree(hHeap, 0, hMonitorList); - HeapFree(hHeap, 0, pRectList); - return FALSE; + /* FIXME: SetLastError() */ + HeapFree(hHeap, 0, hMonitorList); + HeapFree(hHeap, 0, pRectList); + return FALSE; } - /* enumerate list */ - for (i = 0; i < iCount; i++) + /* enumerate list */ + for (i = 0; i < iCount; i++) { - HMONITOR hMonitor = hMonitorList[i]; - LPRECT pMonitorRect = pRectList + i; - HDC hMonitorDC = NULL; + HMONITOR hMonitor = hMonitorList[i]; + LPRECT pMonitorRect = pRectList + i; + HDC hMonitorDC = NULL; - if (hdc != NULL) + if (hdc != NULL) { - /* make monitor DC */ - hMonitorDC = hdc; + /* make monitor DC */ + hMonitorDC = hdc; } - if (!lpfnEnum(hMonitor, hMonitorDC, pMonitorRect, dwData)) - break; + if (!lpfnEnum(hMonitor, hMonitorDC, pMonitorRect, dwData)) + break; } - HeapFree(hHeap, 0, hMonitorList); - HeapFree(hHeap, 0, pRectList); - return TRUE; + HeapFree(hHeap, 0, hMonitorList); + HeapFree(hHeap, 0, pRectList); + return TRUE; } @@ -244,13 +222,13 @@ EnumDisplaySettingsExA( COPYN(dmDriverVersion); switch (lpDevMode->dmSize) { - case SIZEOF_DEVMODEA_300: - case SIZEOF_DEVMODEA_400: - case SIZEOF_DEVMODEA_500: - break; - default: - lpDevMode->dmSize = SIZEOF_DEVMODEA_300; - break; + case SIZEOF_DEVMODEA_300: + case SIZEOF_DEVMODEA_400: + case SIZEOF_DEVMODEA_500: + break; + default: + lpDevMode->dmSize = SIZEOF_DEVMODEA_300; + break; } COPYN(dmDriverExtra); COPYN(dmFields); @@ -299,11 +277,11 @@ EnumDisplaySettingsExA( BOOL WINAPI EnumDisplaySettingsA( - LPCSTR lpszDeviceName, - DWORD iModeNum, - LPDEVMODEA lpDevMode) + LPCSTR lpszDeviceName, + DWORD iModeNum, + LPDEVMODEA lpDevMode) { - return EnumDisplaySettingsExA ( lpszDeviceName, iModeNum, lpDevMode, 0 ); + return EnumDisplaySettingsExA ( lpszDeviceName, iModeNum, lpDevMode, 0 ); } @@ -339,11 +317,11 @@ EnumDisplaySettingsExW( BOOL WINAPI EnumDisplaySettingsW( - LPCWSTR lpszDeviceName, - DWORD iModeNum, - LPDEVMODEW lpDevMode) + LPCWSTR lpszDeviceName, + DWORD iModeNum, + LPDEVMODEW lpDevMode) { - return EnumDisplaySettingsExW ( lpszDeviceName, iModeNum, lpDevMode, 0 ); + return EnumDisplaySettingsExW ( lpszDeviceName, iModeNum, lpDevMode, 0 ); } @@ -353,40 +331,40 @@ EnumDisplaySettingsW( BOOL WINAPI GetMonitorInfoA( - HMONITOR hMonitor, - LPMONITORINFO lpmi) + HMONITOR hMonitor, + LPMONITORINFO lpmi) { - if (lpmi->cbSize == sizeof (MONITORINFO)) + if (lpmi->cbSize == sizeof (MONITORINFO)) { - return NtUserGetMonitorInfo(hMonitor, lpmi); + return NtUserGetMonitorInfo(hMonitor, lpmi); } - else if (lpmi->cbSize != sizeof (MONITORINFOEXA)) + else if (lpmi->cbSize != sizeof (MONITORINFOEXA)) { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } - else + else { - MONITORINFOEXW miExW; - INT res; + MONITORINFOEXW miExW; + INT res; - miExW.cbSize = sizeof (MONITORINFOEXW); - if (!NtUserGetMonitorInfo(hMonitor, (LPMONITORINFO)&miExW)) + miExW.cbSize = sizeof (MONITORINFOEXW); + if (!NtUserGetMonitorInfo(hMonitor, (LPMONITORINFO)&miExW)) { - return FALSE; + return FALSE; } - memcpy(lpmi, &miExW, sizeof (MONITORINFO)); - res = WideCharToMultiByte(CP_THREAD_ACP, 0, miExW.szDevice, -1, - ((LPMONITORINFOEXA)lpmi)->szDevice, CCHDEVICENAME, - NULL, NULL); - if (res == 0) + memcpy(lpmi, &miExW, sizeof (MONITORINFO)); + res = WideCharToMultiByte(CP_THREAD_ACP, 0, miExW.szDevice, -1, + ((LPMONITORINFOEXA)lpmi)->szDevice, CCHDEVICENAME, + NULL, NULL); + if (res == 0) { - WARN("WideCharToMultiByte() failed!\n"); - return FALSE; + WARN("WideCharToMultiByte() failed!\n"); + return FALSE; } } - return TRUE; + return TRUE; } @@ -396,10 +374,10 @@ GetMonitorInfoA( BOOL WINAPI GetMonitorInfoW( - HMONITOR hMonitor, - LPMONITORINFO lpmi) + HMONITOR hMonitor, + LPMONITORINFO lpmi) { - return NtUserGetMonitorInfo(hMonitor, lpmi); + return NtUserGetMonitorInfo(hMonitor, lpmi); } @@ -409,10 +387,10 @@ GetMonitorInfoW( HMONITOR WINAPI MonitorFromPoint( - IN POINT ptPoint, - IN DWORD dwFlags ) + IN POINT ptPoint, + IN DWORD dwFlags ) { - return NtUserMonitorFromPoint(ptPoint, dwFlags); + return NtUserMonitorFromPoint(ptPoint, dwFlags); } @@ -422,10 +400,10 @@ MonitorFromPoint( HMONITOR WINAPI MonitorFromRect( - IN LPCRECT lpcRect, - IN DWORD dwFlags ) + IN LPCRECT lpcRect, + IN DWORD dwFlags ) { - return NtUserMonitorFromRect(lpcRect, dwFlags); + return NtUserMonitorFromRect(lpcRect, dwFlags); } @@ -435,10 +413,10 @@ MonitorFromRect( HMONITOR WINAPI MonitorFromWindow( - IN HWND hWnd, - IN DWORD dwFlags ) + IN HWND hWnd, + IN DWORD dwFlags ) { - return NtUserMonitorFromWindow(hWnd, dwFlags); + return NtUserMonitorFromWindow(hWnd, dwFlags); } @@ -448,46 +426,46 @@ MonitorFromWindow( LONG WINAPI ChangeDisplaySettingsExA( - LPCSTR lpszDeviceName, - LPDEVMODEA lpDevMode, - HWND hwnd, - DWORD dwflags, - LPVOID lParam) + LPCSTR lpszDeviceName, + LPDEVMODEA lpDevMode, + HWND hwnd, + DWORD dwflags, + LPVOID lParam) { - LONG rc; - UNICODE_STRING DeviceName; - PUNICODE_STRING pDeviceName = &DeviceName; + LONG rc; + UNICODE_STRING DeviceName; + PUNICODE_STRING pDeviceName = &DeviceName; - if (lpszDeviceName != NULL) + if (lpszDeviceName != NULL) { - if ( !RtlCreateUnicodeStringFromAsciiz ( pDeviceName, (PCSZ)lpszDeviceName ) ) + if (!RtlCreateUnicodeStringFromAsciiz(pDeviceName, (PCSZ)lpszDeviceName)) { - SetLastError ( ERROR_OUTOFMEMORY ); - return DISP_CHANGE_BADPARAM; /* FIXME what to return? */ + SetLastError(ERROR_OUTOFMEMORY); + return DISP_CHANGE_BADPARAM; /* FIXME what to return? */ } } - else - pDeviceName = NULL; + else + pDeviceName = NULL; - if (lpDevMode != NULL) - { - LPDEVMODEW pDevModeW; - pDevModeW = GdiConvertToDevmodeW(lpDevMode); - if(pDevModeW) + if (lpDevMode != NULL) { - rc = NtUserChangeDisplaySettings ( pDeviceName, pDevModeW, hwnd, dwflags, lParam ); - RtlFreeHeap(GetProcessHeap(), 0, pDevModeW); + LPDEVMODEW pDevModeW; + pDevModeW = GdiConvertToDevmodeW(lpDevMode); + if(pDevModeW) + { + rc = NtUserChangeDisplaySettings(pDeviceName, pDevModeW, hwnd, dwflags, lParam); + RtlFreeHeap(GetProcessHeap(), 0, pDevModeW); + } + else + rc = DISP_CHANGE_SUCCESSFUL; } else - rc = DISP_CHANGE_SUCCESSFUL; - } - else - rc = NtUserChangeDisplaySettings ( pDeviceName, NULL, hwnd, dwflags, lParam ); + rc = NtUserChangeDisplaySettings(pDeviceName, NULL, hwnd, dwflags, lParam); - if (lpszDeviceName != NULL) - RtlFreeUnicodeString ( &DeviceName ); + if (lpszDeviceName != NULL) + RtlFreeUnicodeString(&DeviceName); - return rc; + return rc; } @@ -497,12 +475,12 @@ ChangeDisplaySettingsExA( LONG WINAPI ChangeDisplaySettingsA( - LPDEVMODEA lpDevMode, - DWORD dwflags) + LPDEVMODEA lpDevMode, + DWORD dwflags) { - if(lpDevMode) - lpDevMode->dmDriverExtra = 0; - return ChangeDisplaySettingsExA ( NULL, lpDevMode, NULL, dwflags, 0 ); + if(lpDevMode) + lpDevMode->dmDriverExtra = 0; + return ChangeDisplaySettingsExA ( NULL, lpDevMode, NULL, dwflags, 0 ); } @@ -512,24 +490,24 @@ ChangeDisplaySettingsA( LONG WINAPI ChangeDisplaySettingsExW( - LPCWSTR lpszDeviceName, - LPDEVMODEW lpDevMode, - HWND hwnd, - DWORD dwflags, - LPVOID lParam) + LPCWSTR lpszDeviceName, + LPDEVMODEW lpDevMode, + HWND hwnd, + DWORD dwflags, + LPVOID lParam) { - LONG rc; - UNICODE_STRING DeviceName; - PUNICODE_STRING pDeviceName = &DeviceName; + LONG rc; + UNICODE_STRING DeviceName; + PUNICODE_STRING pDeviceName = &DeviceName; - if (lpszDeviceName != NULL) - RtlInitUnicodeString ( pDeviceName, lpszDeviceName ); - else - pDeviceName = NULL; + if (lpszDeviceName != NULL) + RtlInitUnicodeString(pDeviceName, lpszDeviceName); + else + pDeviceName = NULL; - rc = NtUserChangeDisplaySettings ( pDeviceName, lpDevMode, hwnd, dwflags, lParam ); + rc = NtUserChangeDisplaySettings(pDeviceName, lpDevMode, hwnd, dwflags, lParam); - return rc; + return rc; } @@ -539,10 +517,10 @@ ChangeDisplaySettingsExW( LONG WINAPI ChangeDisplaySettingsW( - LPDEVMODEW lpDevMode, - DWORD dwflags) + LPDEVMODEW lpDevMode, + DWORD dwflags) { - if(lpDevMode) - lpDevMode->dmDriverExtra = 0; - return ChangeDisplaySettingsExW ( NULL, lpDevMode, NULL, dwflags, 0 ); + if(lpDevMode) + lpDevMode->dmDriverExtra = 0; + return ChangeDisplaySettingsExW(NULL, lpDevMode, NULL, dwflags, 0); } diff --git a/dll/win32/user32/misc/winsta.c b/dll/win32/user32/misc/winsta.c index f6f237c2a74..b38732ddf07 100644 --- a/dll/win32/user32/misc/winsta.c +++ b/dll/win32/user32/misc/winsta.c @@ -12,6 +12,7 @@ #include #include +WINE_DEFAULT_DEBUG_CHANNEL(winsta); /* @@ -58,12 +59,50 @@ CreateWindowStationW(LPCWSTR lpwinsta, LPSECURITY_ATTRIBUTES lpsa) { UNICODE_STRING WindowStationName; + UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hWindowStationsDir; + NTSTATUS Status; + HWINSTA hwinsta; + + /* Open WindowStations directory */ + InitializeObjectAttributes(&ObjectAttributes, + &WindowStationsDir, + OBJ_CASE_INSENSITIVE, + 0, + 0); + + Status = NtOpenDirectoryObject(&hWindowStationsDir, + DIRECTORY_CREATE_OBJECT, + &ObjectAttributes); + if(!NT_SUCCESS(Status)) + { + ERR("Failed to open WindowStations directory\n"); + return NULL; + } RtlInitUnicodeString(&WindowStationName, lpwinsta); - return NtUserCreateWindowStation(&WindowStationName, - dwDesiredAccess, - lpsa, 0, 0, 0, 0); + /* Create the window station object */ + InitializeObjectAttributes(&ObjectAttributes, + &WindowStationName, + OBJ_CASE_INSENSITIVE, + hWindowStationsDir, + 0); + + /* Check if the handle should be inheritable */ + if (lpsa && lpsa->bInheritHandle) + { + ObjectAttributes.Attributes |= OBJ_INHERIT; + } + + hwinsta = NtUserCreateWindowStation(&ObjectAttributes, + dwDesiredAccess, + 0, 0, 0, 0, 0); + + NtClose(hWindowStationsDir); + + return hwinsta; } /* @@ -299,14 +338,51 @@ OpenWindowStationA(LPCSTR lpszWinSta, */ HWINSTA WINAPI OpenWindowStationW(LPCWSTR lpszWinSta, - BOOL fInherit, - ACCESS_MASK dwDesiredAccess) + BOOL fInherit, + ACCESS_MASK dwDesiredAccess) { UNICODE_STRING WindowStationName; + UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hWindowStationsDir; + NTSTATUS Status; + HWINSTA hwinsta; + /* Open WindowStations directory */ + InitializeObjectAttributes(&ObjectAttributes, + &WindowStationsDir, + OBJ_CASE_INSENSITIVE, + 0, + 0); + + Status = NtOpenDirectoryObject(&hWindowStationsDir, + DIRECTORY_TRAVERSE, + &ObjectAttributes); + if(!NT_SUCCESS(Status)) + { + ERR("Failed to open WindowStations directory\n"); + return NULL; + } + + /* Open the window station object */ RtlInitUnicodeString(&WindowStationName, lpszWinSta); - return NtUserOpenWindowStation(&WindowStationName, dwDesiredAccess); + InitializeObjectAttributes(&ObjectAttributes, + &WindowStationName, + OBJ_CASE_INSENSITIVE, + hWindowStationsDir, + 0); + + if( fInherit == TRUE ) + { + ObjectAttributes.Attributes |= OBJ_INHERIT; + } + + hwinsta = NtUserOpenWindowStation(&ObjectAttributes, dwDesiredAccess); + + NtClose(hWindowStationsDir); + + return hwinsta; } diff --git a/dll/win32/user32/windows/menu.c b/dll/win32/user32/windows/menu.c index bbc24c7db52..405e7809827 100644 --- a/dll/win32/user32/windows/menu.c +++ b/dll/win32/user32/windows/menu.c @@ -1792,9 +1792,24 @@ MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset) MenuCleanupRosMenuItemInfo(&ItemInfo); } +// +// This breaks some test results. Should handle A2U if called! +// LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) { TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam); +#ifdef __REACTOS__ + PWND pWnd; + + pWnd = ValidateHwnd(Wnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(Wnd, FNID_MENU); + } + } +#endif switch(Message) { @@ -1834,6 +1849,9 @@ LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM l top_popup = NULL; top_popup_hmenu = NULL; } +#ifdef __REACTOS__ + NtUserSetWindowFNID(Wnd, FNID_DESTROY); +#endif break; case WM_SHOWWINDOW: @@ -1868,6 +1886,18 @@ LRESULT WINAPI PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) { TRACE("hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam); +#ifdef __REACTOS__ // Do this now, remove after Server side is fixed. + PWND pWnd; + + pWnd = ValidateHwnd(Wnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(Wnd, FNID_MENU); + } + } +#endif switch(Message) { @@ -1907,6 +1937,9 @@ PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) top_popup = NULL; top_popup_hmenu = NULL; } +#ifdef __REACTOS__ + NtUserSetWindowFNID(Wnd, FNID_DESTROY); +#endif break; case WM_SHOWWINDOW: diff --git a/dll/win32/user32/windows/nonclient.c b/dll/win32/user32/windows/nonclient.c index 1d825b978df..19f18256f15 100644 --- a/dll/win32/user32/windows/nonclient.c +++ b/dll/win32/user32/windows/nonclient.c @@ -161,7 +161,7 @@ UserDrawSysMenuButton(HWND hWnd, HDC hDC, LPRECT Rect, BOOL Down) * - Center the buttons verticaly in the rect */ VOID -UserDrawCaptionButton(LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDown, ULONG Type) +UserDrawCaptionButton(HWND hWnd, LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDown, ULONG Type) { RECT TempRect; @@ -214,6 +214,9 @@ UserDrawCaptionButton(LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDo } case DFCS_CAPTIONCLOSE: { + HMENU hSysMenu = GetSystemMenu(hWnd, FALSE); + UINT MenuState = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* in case of error MenuState==0xFFFFFFFF */ + /* FIXME: A tool window has a smaller Close button */ if (ExStyle & WS_EX_TOOLWINDOW) @@ -231,7 +234,7 @@ UserDrawCaptionButton(LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDo DrawFrameControl(hDC, &TempRect, DFC_CAPTION, (DFCS_CAPTIONCLOSE | (bDown ? DFCS_PUSHED : 0) | - ((Style & WS_SYSMENU) ? 0 : DFCS_INACTIVE))); + ((!(MenuState & (MF_GRAYED|MF_DISABLED)) && !(GetClassLong(hWnd, GCL_STYLE) & CS_NOCLOSE)) ? 0 : DFCS_INACTIVE))); break; } } @@ -252,7 +255,7 @@ UserDrawCaptionButtonWnd(HWND hWnd, HDC hDC, BOOL bDown, ULONG Type) ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE); UserGetWindowBorders(Style, ExStyle, &WindowBorder, FALSE); InflateRect(&WindowRect, -WindowBorder.cx, -WindowBorder.cy); - UserDrawCaptionButton(&WindowRect, Style, ExStyle, hDC, bDown, Type); + UserDrawCaptionButton(hWnd, &WindowRect, Style, ExStyle, hDC, bDown, Type); } // Note from Wine: @@ -419,11 +422,11 @@ DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active) /* Draw buttons */ if (Style & WS_SYSMENU) { - UserDrawCaptionButton(&TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE); + UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE); if ((Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(ExStyle & WS_EX_TOOLWINDOW)) { - UserDrawCaptionButton(&TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMIN); - UserDrawCaptionButton(&TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMAX); + UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMIN); + UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMAX); } } if(!(Style & WS_MINIMIZE)) @@ -665,8 +668,8 @@ DefWndNCHitTest(HWND hWnd, POINT Point) RECT WindowRect, ClientRect, OrigWndRect; POINT ClientPoint; SIZE WindowBorders; - ULONG Style = GetWindowLongPtrW(hWnd, GWL_STYLE); - ULONG ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE); + DWORD Style = GetWindowLongPtrW(hWnd, GWL_STYLE); + DWORD ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE); GetWindowRect(hWnd, &WindowRect); if (!PtInRect(&WindowRect, Point)) @@ -787,8 +790,6 @@ DefWndNCHitTest(HWND hWnd, POINT Point) if(!(Style & WS_MINIMIZE)) { - HMENU menu; - ClientPoint = Point; ScreenToClient(hWnd, &ClientPoint); GetClientRect(hWnd, &ClientRect); @@ -798,7 +799,7 @@ DefWndNCHitTest(HWND hWnd, POINT Point) return HTCLIENT; } - if ((menu = GetMenu(hWnd)) && !(Style & WS_CHILD)) + if (GetMenu(hWnd) && !(Style & WS_CHILD)) { if (Point.x > 0 && Point.x < WindowRect.right && ClientPoint.y < 0) return HTMENU; @@ -878,13 +879,18 @@ DefWndDoButton(HWND hWnd, WPARAM wParam) HDC WindowDC; BOOL Pressed = TRUE, OldState; WPARAM SCMsg; - ULONG ButtonType, Style; + HMENU hSysMenu; + ULONG ButtonType; + DWORD Style; + UINT MenuState; Style = GetWindowLongPtrW(hWnd, GWL_STYLE); switch (wParam) { case HTCLOSE: - if (!(Style & WS_SYSMENU)) + hSysMenu = GetSystemMenu(hWnd, FALSE); + MenuState = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* in case of error MenuState==0xFFFFFFFF */ + if (!(Style & WS_SYSMENU) || (MenuState & (MF_GRAYED|MF_DISABLED)) || (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_NOCLOSE)) return; ButtonType = DFCS_CAPTIONCLOSE; SCMsg = SC_CLOSE; diff --git a/dll/win32/user32/windows/window.c b/dll/win32/user32/windows/window.c index 2025d815617..4cc757fcf5f 100644 --- a/dll/win32/user32/windows/window.c +++ b/dll/win32/user32/windows/window.c @@ -65,17 +65,7 @@ AllowSetForegroundWindow(DWORD dwProcessId) HDWP WINAPI BeginDeferWindowPos(int nNumWindows) { - if (nNumWindows < 0) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } -#if 0 - UNIMPLEMENTED; - return (HDWP)0; -#else - return (HDWP)1; -#endif + return (HDWP)NtUserCallOneParam((DWORD_PTR)nNumWindows, ONEPARAM_ROUTINE_BEGINDEFERWNDPOS); } @@ -567,12 +557,7 @@ DeferWindowPos(HDWP hWinPosInfo, int cy, UINT uFlags) { -#if 0 return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags); -#else - SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags); - return hWinPosInfo; -#endif } @@ -582,12 +567,7 @@ DeferWindowPos(HDWP hWinPosInfo, BOOL WINAPI EndDeferWindowPos(HDWP hWinPosInfo) { -#if 0 - UNIMPLEMENTED; - return FALSE; -#else - return TRUE; -#endif + return NtUserEndDeferWindowPosEx(hWinPosInfo, 0); } diff --git a/drivers/base/kddll/kddll.h b/drivers/base/kddll/kddll.h index b6119e39dcc..50964141b8f 100644 --- a/drivers/base/kddll/kddll.h +++ b/drivers/base/kddll/kddll.h @@ -70,7 +70,7 @@ KdpReceiveByte(OUT PBYTE OutByte); KDP_STATUS NTAPI -KdpPollBreakIn(); +KdpPollBreakIn(VOID); #if 0 diff --git a/drivers/filesystems/ext2/inc/protos.h b/drivers/filesystems/ext2/inc/protos.h index 20143c3c5bd..864dfc2b820 100644 --- a/drivers/filesystems/ext2/inc/protos.h +++ b/drivers/filesystems/ext2/inc/protos.h @@ -256,7 +256,7 @@ extern LONGLONG NTAPI Ext2Align64( LONGLONG NumberToBeAligned, LONGLONG Alignment); -extern ULONG NTAPI Ext2GetCurrentTime(); +extern ULONG NTAPI Ext2GetCurrentTime(VOID); /************************************************************************* * Prototypes for the file cleanup.c diff --git a/drivers/filesystems/fastfat_new/fastfat.h b/drivers/filesystems/fastfat_new/fastfat.h index fbbf272c413..f00bca4a832 100644 --- a/drivers/filesystems/fastfat_new/fastfat.h +++ b/drivers/filesystems/fastfat_new/fastfat.h @@ -368,7 +368,7 @@ FatRemoveNames(IN PFAT_IRP_CONTEXT IrpContext, IN PFCB Fcb); PCCB NTAPI -FatCreateCcb(); +FatCreateCcb(VOID); VOID NTAPI FatDeleteCcb(IN PFAT_IRP_CONTEXT IrpContext, diff --git a/drivers/network/lan/include/lan.h b/drivers/network/lan/include/lan.h index fb7e1e0a4e3..1e4be2f22e8 100644 --- a/drivers/network/lan/include/lan.h +++ b/drivers/network/lan/include/lan.h @@ -156,8 +156,8 @@ NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, VOID FreeNdisPacketX( PNDIS_PACKET Packet, PCHAR File, UINT Line ); -NDIS_STATUS InitNdisPools(); -VOID CloseNdisPools(); +NDIS_STATUS InitNdisPools(VOID); +VOID CloseNdisPools(VOID); PLAN_ADAPTER FindAdapterByIndex( PLAN_DEVICE_EXT DeviceExt, UINT Index ); diff --git a/drivers/network/ndis/include/miniport.h b/drivers/network/ndis/include/miniport.h index ad4de2a81e3..a5b8c8f206d 100644 --- a/drivers/network/ndis/include/miniport.h +++ b/drivers/network/ndis/include/miniport.h @@ -169,7 +169,7 @@ NdisFindDevice( PUINT SlotNumber); VOID -NdisStartDevices(); +NdisStartDevices(VOID); VOID NTAPI diff --git a/drivers/network/ndis/ndis/config.c b/drivers/network/ndis/ndis/config.c index b95f1e01060..f0227c71fd6 100644 --- a/drivers/network/ndis/ndis/config.c +++ b/drivers/network/ndis/ndis/config.c @@ -841,7 +841,7 @@ NdisOpenConfigurationKeyByIndex( /* should i fail instead if the passed-in string isn't long enough? */ wcsncpy(KeyName->Buffer, KeyInformation->Name, KeyName->MaximumLength/sizeof(WCHAR)); - KeyName->Length = (USHORT)KeyInformation->NameLength; + KeyName->Length = (USHORT)min(KeyInformation->NameLength, KeyName->MaximumLength); InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE, ConfigurationHandle, NULL); diff --git a/drivers/network/tcpip/include/icmp.h b/drivers/network/tcpip/include/icmp.h index aaaefa24b5f..e0902e02737 100644 --- a/drivers/network/tcpip/include/icmp.h +++ b/drivers/network/tcpip/include/icmp.h @@ -55,9 +55,9 @@ NTSTATUS ICMPSendDatagram( ULONG DataSize, PULONG DataUsed ); -NTSTATUS ICMPStartup(); +NTSTATUS ICMPStartup(VOID); -NTSTATUS ICMPShutdown(); +NTSTATUS ICMPShutdown(VOID); VOID ICMPReceive( PIP_INTERFACE Interface, diff --git a/drivers/network/tcpip/include/interface.h b/drivers/network/tcpip/include/interface.h index c79bcabce3f..72a69410669 100644 --- a/drivers/network/tcpip/include/interface.h +++ b/drivers/network/tcpip/include/interface.h @@ -7,7 +7,7 @@ NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface, ULONG Type, PULONG Address ); -UINT CountInterfaces(); +UINT CountInterfaces(VOID); UINT CountInterfaceAddresses( PIP_INTERFACE Interface ); NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed ); NTSTATUS GetInterfaceName( PIP_INTERFACE Interface, PCHAR NameBuffer, diff --git a/drivers/network/tcpip/include/lan.h b/drivers/network/tcpip/include/lan.h index 226d354e421..2792c25c6da 100644 --- a/drivers/network/tcpip/include/lan.h +++ b/drivers/network/tcpip/include/lan.h @@ -94,8 +94,8 @@ NTSTATUS LANRegisterProtocol( VOID NTAPI LANUnregisterProtocol(VOID); -VOID LANStartup(); -VOID LANShutdown(); +VOID LANStartup(VOID); +VOID LANShutdown(VOID); NTSTATUS TcpipLanGetDwordOid( PIP_INTERFACE Interface, NDIS_OID Oid, PULONG Result ); diff --git a/drivers/network/tcpip/include/lock.h b/drivers/network/tcpip/include/lock.h index cac01ebeb6e..be231520778 100644 --- a/drivers/network/tcpip/include/lock.h +++ b/drivers/network/tcpip/include/lock.h @@ -1,6 +1,6 @@ #pragma once -extern KIRQL TcpipGetCurrentIrql(); +extern KIRQL TcpipGetCurrentIrql(VOID); extern VOID TcpipInitializeSpinLock( PKSPIN_LOCK SpinLock ); extern VOID TcpipAcquireSpinLock( PKSPIN_LOCK SpinLock, PKIRQL Irql ); extern VOID TcpipReleaseSpinLock( PKSPIN_LOCK SpinLock, KIRQL Irql ); diff --git a/drivers/storage/classpnp/debug.h b/drivers/storage/classpnp/debug.h index 2fa64c41fe1..1bcbf6b7eeb 100644 --- a/drivers/storage/classpnp/debug.h +++ b/drivers/storage/classpnp/debug.h @@ -113,7 +113,7 @@ VOID ClassDebugPrint(CLASS_DEBUG_LEVEL DebugPrintLevel, PCCHAR DebugMessage, ... #define DBGCHECKRETURNEDPKT(_pkt) DbgCheckReturnedPkt(_pkt) #define DBGGETSRBSTATUSSTR(_pSrb) DbgGetSrbStatusStr(_pSrb) - VOID ClasspInitializeDebugGlobals(); + VOID ClasspInitializeDebugGlobals(VOID); char *DbgGetIoctlStr(ULONG ioctl); char *DbgGetScsiOpStr(PSCSI_REQUEST_BLOCK Srb); char *DbgGetSenseCodeStr(PSCSI_REQUEST_BLOCK Srb); diff --git a/drivers/storage/ide/uniata/inc/PostDbgMesg.h b/drivers/storage/ide/uniata/inc/PostDbgMesg.h index 964de7ea3f9..5c30d729c0e 100644 --- a/drivers/storage/ide/uniata/inc/PostDbgMesg.h +++ b/drivers/storage/ide/uniata/inc/PostDbgMesg.h @@ -27,11 +27,11 @@ DbgDump_Printn( BOOLEAN __stdcall -DbgDump_Reconnect(); +DbgDump_Reconnect(VOID); VOID __stdcall -DbgDump_Disconnect(); +DbgDump_Disconnect(VOID); VOID __stdcall diff --git a/drivers/usb/nt4compat/usbdriver/usb.h b/drivers/usb/nt4compat/usbdriver/usb.h index 9130c3ede79..29a8ce91d50 100644 --- a/drivers/usb/nt4compat/usbdriver/usb.h +++ b/drivers/usb/nt4compat/usbdriver/usb.h @@ -1049,7 +1049,7 @@ PLARGE_INTEGER clicks ); VOID -usb_cal_cpu_freq(); +usb_cal_cpu_freq(VOID); NTSTATUS usb_reset_pipe_ex( diff --git a/drivers/usb/usbehci/physmem.h b/drivers/usb/usbehci/physmem.h index ef1355da9df..a49f1bbda6d 100644 --- a/drivers/usb/usbehci/physmem.h +++ b/drivers/usb/usbehci/physmem.h @@ -16,7 +16,7 @@ typedef struct _MEM_HEADER } MEM_HEADER, *PMEM_HEADER; VOID -DumpPages(); +DumpPages(VOID); ULONG AllocateMemory(PEHCI_HOST_CONTROLLER hcd, ULONG Size, ULONG *PhysicalAddress); diff --git a/drivers/video/displays/vga/vgavideo/vgavideo.h b/drivers/video/displays/vga/vgavideo/vgavideo.h index dbd7259df6d..69015a5a3ad 100644 --- a/drivers/video/displays/vga/vgavideo/vgavideo.h +++ b/drivers/video/displays/vga/vgavideo/vgavideo.h @@ -41,7 +41,7 @@ typedef struct _VideoMode { unsigned char Attrib[21]; } VideoMode; -VOID vgaPreCalc(); +VOID vgaPreCalc(VOID); VOID vgaPutPixel(INT x, INT y, UCHAR c); VOID vgaPutByte(INT x, INT y, UCHAR c); VOID vgaGetByte(ULONG offset, diff --git a/drivers/video/miniport/vga/vgamp.h b/drivers/video/miniport/vga/vgamp.h index 2e018e4b116..acece1cfe24 100644 --- a/drivers/video/miniport/vga/vgamp.h +++ b/drivers/video/miniport/vga/vgamp.h @@ -34,8 +34,8 @@ #define UNIMPLEMENTED \ VideoPortDebugPrint(Error, "WARNING: %s at %s:%d is UNIMPLEMENTED!\n",__FUNCTION__,__FILE__,__LINE__); -void -InitVGAMode(); +VOID +InitVGAMode(VOID); VP_STATUS NTAPI VGAFindAdapter( diff --git a/drivers/video/videoprt/videoprt.c b/drivers/video/videoprt/videoprt.c index e2e8df2ca77..73976f8b39d 100644 --- a/drivers/video/videoprt/videoprt.c +++ b/drivers/video/videoprt/videoprt.c @@ -83,27 +83,43 @@ IntCreateRegistryPath( static WCHAR ControlSet[] = L"CONTROLSET"; static WCHAR Insert1[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\"; static WCHAR Insert2[] = L"\\Device0"; - LPWSTR ProfilePath = NULL; BOOLEAN Valid; - PWCHAR AfterControlSet; + UNICODE_STRING AfterControlSet; - Valid = (0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem, - wcslen(RegistryMachineSystem))); + AfterControlSet = *DriverRegistryPath; + /* Check if path begins with \\REGISTRY\\MACHINE\\SYSTEM\\ */ + Valid = (DriverRegistryPath->Length > sizeof(RegistryMachineSystem) && + 0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem, + wcslen(RegistryMachineSystem))); + if (Valid) { - AfterControlSet = DriverRegistryPath->Buffer + wcslen(RegistryMachineSystem); - if (0 == _wcsnicmp(AfterControlSet, CurrentControlSet, wcslen(CurrentControlSet))) + AfterControlSet.Buffer += wcslen(RegistryMachineSystem); + AfterControlSet.Length -= sizeof(RegistryMachineSystem) - sizeof(UNICODE_NULL); + + /* Check if path contains CURRENTCONTROLSET */ + if (AfterControlSet.Length > sizeof(CurrentControlSet) && + 0 == _wcsnicmp(AfterControlSet.Buffer, CurrentControlSet, wcslen(CurrentControlSet))) { - AfterControlSet += wcslen(CurrentControlSet); + AfterControlSet.Buffer += wcslen(CurrentControlSet); + AfterControlSet.Length -= sizeof(CurrentControlSet) - sizeof(UNICODE_NULL); } - else if (0 == _wcsnicmp(AfterControlSet, ControlSet, wcslen(ControlSet))) + /* Check if path contains CONTROLSETnum */ + else if (AfterControlSet.Length > sizeof(ControlSet) && + 0 == _wcsnicmp(AfterControlSet.Buffer, ControlSet, wcslen(ControlSet))) { - AfterControlSet += wcslen(ControlSet); - while (L'0' <= *AfterControlSet && L'9' <= *AfterControlSet) + AfterControlSet.Buffer += wcslen(ControlSet); + AfterControlSet.Length -= sizeof(ControlSet) - sizeof(UNICODE_NULL); + while (AfterControlSet.Length > 0 && + L'0' <= *AfterControlSet.Buffer && + L'9' <= *AfterControlSet.Buffer) { - AfterControlSet++; + AfterControlSet.Buffer++; + AfterControlSet.Length -= sizeof(WCHAR); } - Valid = (L'\\' == *AfterControlSet); - AfterControlSet++; + Valid = (AfterControlSet.Length > 0 && L'\\' == *AfterControlSet.Buffer); + AfterControlSet.Buffer++; + AfterControlSet.Length -= sizeof(WCHAR); + AfterControlSet.MaximumLength = AfterControlSet.Length; } else { @@ -113,18 +129,26 @@ IntCreateRegistryPath( if (Valid) { - ProfilePath = ExAllocatePoolWithTag(PagedPool, - (wcslen(DriverRegistryPath->Buffer) + - wcslen(Insert1) + wcslen(Insert2) + 1) * sizeof(WCHAR), - TAG_VIDEO_PORT); - if (NULL != ProfilePath) + DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert1) + sizeof(Insert2); + DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(PagedPool, + DeviceRegistryPath->MaximumLength, + TAG_VIDEO_PORT); + if (NULL != DeviceRegistryPath->Buffer) { - wcsncpy(ProfilePath, DriverRegistryPath->Buffer, AfterControlSet - DriverRegistryPath->Buffer); - wcscpy(ProfilePath + (AfterControlSet - DriverRegistryPath->Buffer), Insert1); - wcscat(ProfilePath, AfterControlSet); - wcscat(ProfilePath, Insert2); - - Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, ProfilePath)); + /* Build device path */ + wcsncpy(DeviceRegistryPath->Buffer, + DriverRegistryPath->Buffer, + AfterControlSet.Buffer - DriverRegistryPath->Buffer); + DeviceRegistryPath->Length = (AfterControlSet.Buffer - DriverRegistryPath->Buffer) * sizeof(WCHAR); + RtlAppendUnicodeToString(DeviceRegistryPath, Insert1); + RtlAppendUnicodeStringToString(DeviceRegistryPath, &AfterControlSet); + RtlAppendUnicodeToString(DeviceRegistryPath, Insert2); + + /* Check if registry key exists */ + Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DriverRegistryPath->Buffer)); + + if(!Valid) + ExFreePoolWithTag(DeviceRegistryPath->Buffer, TAG_VIDEO_PORT); } else { @@ -136,28 +160,22 @@ IntCreateRegistryPath( WARN_(VIDEOPRT, "Unparsable registry path %wZ", DriverRegistryPath); } - if (Valid) + /* If path doesn't point to *ControlSet*, use DriverRegistryPath directly */ + if (!Valid) { - RtlInitUnicodeString(DeviceRegistryPath, ProfilePath); - } - else - { - if (ProfilePath) - ExFreePoolWithTag(ProfilePath, TAG_VIDEO_PORT); - - DeviceRegistryPath->Length = - DeviceRegistryPath->MaximumLength = - DriverRegistryPath->Length + (9 * sizeof(WCHAR)); - DeviceRegistryPath->Length -= sizeof(WCHAR); + DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert2); DeviceRegistryPath->Buffer = ExAllocatePoolWithTag( NonPagedPool, DeviceRegistryPath->MaximumLength, TAG_VIDEO_PORT); + if (!DeviceRegistryPath->Buffer) return STATUS_NO_MEMORY; - swprintf(DeviceRegistryPath->Buffer, L"%s\\Device0", - DriverRegistryPath->Buffer); + + RtlCopyUnicodeString(DeviceRegistryPath, DriverRegistryPath); + RtlAppendUnicodeToString(DeviceRegistryPath, Insert2); } + return STATUS_SUCCESS; } diff --git a/drivers/wdm/audio/legacy/wdmaud/control.c b/drivers/wdm/audio/legacy/wdmaud/control.c index afc692c15ac..3343405de41 100644 --- a/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/drivers/wdm/audio/legacy/wdmaud/control.c @@ -402,28 +402,6 @@ IoCompletion ( /* sanity check */ ASSERT(Header); - /* iterate through all stream headers and collect size */ - do - { - if (Context->Function == IOCTL_KS_READ_STREAM) - { - /* length is stored in DataUsed */ - Length += Header->DataUsed; - } - else - { - /* length stored in frameextend */ - Length += Header->FrameExtent; - } - - /* subtract size */ - Context->Length -= Header->Size; - - /* move to next stream header */ - Header = (PKSSTREAM_HEADER)((ULONG_PTR)Header + Header->Size); - - }while(Context->Length); - /* time to free all allocated mdls */ Mdl = Irp->MdlAddress; @@ -454,12 +432,7 @@ IoCompletion ( DPRINT("IoCompletion Irp %p IoStatus %lx Information %lx Length %lu\n", Irp, Irp->IoStatus.Status, Irp->IoStatus.Information, Length); - if (Irp->IoStatus.Status == STATUS_SUCCESS) - { - /* store the length */ - Irp->IoStatus.Information = Length; - } - else + if (!NT_SUCCESS(Irp->IoStatus.Status)) { /* failed */ Irp->IoStatus.Information = 0; @@ -471,7 +444,6 @@ IoCompletion ( return STATUS_SUCCESS; } - NTSTATUS NTAPI WdmAudReadWrite( diff --git a/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 002cf8d0d0a..c322c3fc8a9 100644 --- a/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -280,19 +280,19 @@ OpenDevice( OUT PFILE_OBJECT * FileObject); ULONG -WdmAudGetMixerDeviceCount(); +WdmAudGetMixerDeviceCount(VOID); ULONG -WdmAudGetWaveInDeviceCount(); +WdmAudGetWaveInDeviceCount(VOID); ULONG -WdmAudGetWaveOutDeviceCount(); +WdmAudGetWaveOutDeviceCount(VOID); ULONG -WdmAudGetMidiInDeviceCount(); +WdmAudGetMidiInDeviceCount(VOID); ULONG -WdmAudGetMidiOutDeviceCount(); +WdmAudGetMidiOutDeviceCount(VOID); NTSTATUS WdmAudGetPnpNameByIndexAndType( diff --git a/include/crt/eh.h b/include/crt/eh.h index 3c7725a42c2..8d2264b1db1 100644 --- a/include/crt/eh.h +++ b/include/crt/eh.h @@ -16,10 +16,10 @@ #error eh.h is only for C++! #endif -typedef void (__cdecl *terminate_function)(); -typedef void (__cdecl *terminate_handler)(); -typedef void (__cdecl *unexpected_function)(); -typedef void (__cdecl *unexpected_handler)(); +typedef void (__cdecl *terminate_function)(void); +typedef void (__cdecl *terminate_handler)(void); +typedef void (__cdecl *unexpected_function)(void); +typedef void (__cdecl *unexpected_handler)(void); struct _EXCEPTION_POINTERS; typedef void (__cdecl *_se_translator_function)(unsigned int,struct _EXCEPTION_POINTERS *); @@ -32,7 +32,7 @@ extern "C" _CRTIMP terminate_function __cdecl _get_terminate(void); _CRTIMP unexpected_function __cdecl set_unexpected(unexpected_function _NewPtFunc); extern "C" _CRTIMP unexpected_function __cdecl _get_unexpected(void); _CRTIMP _se_translator_function __cdecl _set_se_translator(_se_translator_function _NewPtFunc); -_CRTIMP bool __cdecl __uncaught_exception(); +_CRTIMP bool __cdecl __uncaught_exception(void); #pragma pack(pop) #endif diff --git a/include/crt/rtcapi.h b/include/crt/rtcapi.h index 3816f2d25c8..44b7f873af9 100644 --- a/include/crt/rtcapi.h +++ b/include/crt/rtcapi.h @@ -76,7 +76,7 @@ extern "C" { __MINGW_EXTENSION int __fastcall _RTC_Check_8_to_4(__int64 _Src); #if (defined(_X86_) && !defined(__x86_64)) - void __cdecl _RTC_CheckEsp(); + void __cdecl _RTC_CheckEsp(void); #endif void __fastcall _RTC_CheckStackVars(void *_Esp,_RTC_framedesc *_Fd); void __fastcall _RTC_CheckStackVars2(void *_Esp,_RTC_framedesc *_Fd,_RTC_ALLOCA_NODE *_AllocaList); @@ -85,7 +85,7 @@ extern "C" { void __cdecl _RTC_Shutdown(void); void __cdecl _RTC_InitBase(void); #ifdef __cplusplus - void *_ReturnAddress(); + void *_ReturnAddress(void); } #endif diff --git a/include/crt/xlocinfo.h b/include/crt/xlocinfo.h index 514ae672e57..efa67fb85b4 100644 --- a/include/crt/xlocinfo.h +++ b/include/crt/xlocinfo.h @@ -62,10 +62,10 @@ typedef struct _Cvtvec { unsigned int _Page; } _Cvtvec; -_CRTIMP _Collvec __cdecl _Getcoll(); -_CRTIMP _Ctypevec __cdecl _Getctype(); -_CRTIMP _Cvtvec __cdecl _Getcvt(); -_CRTIMP int __cdecl _Getdateorder(); +_CRTIMP _Collvec __cdecl _Getcoll(void); +_CRTIMP _Ctypevec __cdecl _Getctype(void); +_CRTIMP _Cvtvec __cdecl _Getcvt(void); +_CRTIMP int __cdecl _Getdateorder(void); _CRTIMP int __cdecl _Mbrtowc(wchar_t *,const char *,size_t,mbstate_t *,const _Cvtvec *); _CRTIMP float __cdecl _Stof(const char *,char **,long); _CRTIMP double __cdecl _Stod(const char *,char **,long); @@ -85,9 +85,9 @@ _END_C_LIB_DECL _C_STD_END _C_LIB_DECL -_CRTIMP void *__cdecl _Gettnames(); -_CRTIMP char *__cdecl _Getdays(); -_CRTIMP char *__cdecl _Getmonths(); +_CRTIMP void *__cdecl _Gettnames(void); +_CRTIMP char *__cdecl _Getdays(void); +_CRTIMP char *__cdecl _Getmonths(void); _CRTIMP size_t __cdecl _Strftime(char *,size_t _Maxsize,const char *,const struct tm *,void *); _END_C_LIB_DECL diff --git a/include/ddk/ntstrsafe.h b/include/ddk/ntstrsafe.h index c107a0da425..d34b8896814 100644 --- a/include/ddk/ntstrsafe.h +++ b/include/ddk/ntstrsafe.h @@ -1,520 +1,2065 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: This file is in the public domain. - * FILE: include/ddk/ntstrsafe.h - * PURPOSE: Safe String Library for NT Code (Native/Kernel) - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ - -/* INCLUDES ******************************************************************/ - #ifndef _NTSTRSAFE_H_INCLUDED_ #define _NTSTRSAFE_H_INCLUDED_ -// -// Dependencies -// #include #include #include -// -// Maximum limits: allow overriding the maximum -// -#ifndef NTSTRSAFE_MAX_CCH -#define NTSTRSAFE_MAX_CCH 2147483647 +#ifndef C_ASSERT +#ifdef _MSC_VER +# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] +#else +# define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) #endif -#define NTSTRSAFE_MAX_LENGTH (NTSTRSAFE_MAX_CCH - 1) +#endif /* C_ASSERT */ -// -// Typedefs -// -typedef unsigned long DWORD; +#ifdef __cplusplus +#define _STRSAFE_EXTERN_C extern "C" +#else +#define _STRSAFE_EXTERN_C extern +#endif -/* PRIVATE FUNCTIONS *********************************************************/ +#define NTSTRSAFEAPI static __inline NTSTATUS NTAPI +#define NTSTRSAFE_INLINE_API static __inline NTSTATUS NTAPI -static __inline -NTSTATUS -NTAPI -RtlStringLengthWorkerA(IN LPCSTR String, - IN SIZE_T MaxLength, - OUT PSIZE_T ReturnLength OPTIONAL) +#ifndef NTSTRSAFE_MAX_CCH +#define NTSTRSAFE_MAX_CCH 2147483647 +#endif + +#ifndef _STRSAFE_H_INCLUDED_ +#define STRSAFE_IGNORE_NULLS 0x00000100 +#define STRSAFE_FILL_BEHIND_NULL 0x00000200 +#define STRSAFE_FILL_ON_FAILURE 0x00000400 +#define STRSAFE_NULL_ON_FAILURE 0x00000800 +#define STRSAFE_NO_TRUNCATION 0x00001000 +#define STRSAFE_IGNORE_NULL_UNICODE_STRINGS 0x00010000 +#define STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED 0x00020000 + +#define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION) +#define STRSAFE_UNICODE_STRING_VALID_FLAGS (STRSAFE_VALID_FLAGS | STRSAFE_IGNORE_NULL_UNICODE_STRINGS | STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED) + +#define STRSAFE_FILL_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL)) +#define STRSAFE_FAILURE_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_ON_FAILURE)) + +#define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)((dwFlags) & 0x000000FF)) +#endif + +typedef char *STRSAFE_LPSTR; +typedef const char *STRSAFE_LPCSTR; +typedef wchar_t *STRSAFE_LPWSTR; +typedef const wchar_t *STRSAFE_LPCWSTR; + +typedef ULONG STRSAFE_DWORD; + +NTSTRSAFEAPI RtlStringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); +NTSTRSAFEAPI RtlStringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy); +NTSTRSAFEAPI RtlStringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy); +NTSTRSAFEAPI RtlStringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); +NTSTRSAFEAPI RtlStringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend); +NTSTRSAFEAPI RtlStringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend); +NTSTRSAFEAPI RtlStringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength); +NTSTRSAFEAPI RtlStringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength); + +NTSTRSAFEAPI RtlStringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); + + +NTSTRSAFEAPI RtlStringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { - NTSTATUS Status = STATUS_SUCCESS; - SIZE_T LocalMax = MaxLength; + return (cchDest > NTSTRSAFE_MAX_CCH ? STATUS_INVALID_PARAMETER : RtlStringCopyWorkerA(pszDest,cchDest,pszSrc)); +} - while (MaxLength && (*String != ANSI_NULL)) +NTSTRSAFEAPI RtlStringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc); +} + + +NTSTRSAFEAPI RtlStringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc); + + +NTSTRSAFEAPI RtlStringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc) +{ + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyWorkerA(pszDest,cbDest,pszSrc); +} + +NTSTRSAFEAPI RtlStringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc); +} + + +NTSTRSAFEAPI RtlStringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + +NTSTRSAFEAPI RtlStringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + size_t cbDest; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + cbDest = cchDest * sizeof(wchar_t); + return RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + + +NTSTRSAFEAPI RtlStringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchRemaining = 0; + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + Status = RtlStringCopyExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) { - String++; - MaxLength--; + if (pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); } - - if (!MaxLength) Status = STATUS_INVALID_PARAMETER; - - if (ReturnLength) - { - if (NT_SUCCESS(Status)) - { - *ReturnLength = LocalMax - MaxLength; - } - else - { - *ReturnLength = 0; - } - } - return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringValidateDestA(IN LPSTR Destination, - IN SIZE_T Length, - OUT PSIZE_T ReturnLength OPTIONAL, - IN SIZE_T MaxLength) +NTSTRSAFEAPI RtlStringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchRemaining = 0; - if (!(Length) || (Length > MaxLength)) Status = STATUS_INVALID_PARAMETER; - - if (ReturnLength) + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + Status = RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) { - if (NT_SUCCESS(Status)) - { - Status = RtlStringLengthWorkerA(Destination, - Length, - ReturnLength); - } - else - { - *ReturnLength = 0; - } + if (pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); } - return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringExValidateDestA(IN OUT LPSTR *Destination, - IN OUT PSIZE_T DestinationLength, - OUT PSIZE_T ReturnLength OPTIONAL, - IN SIZE_T MaxLength, - IN DWORD Flags) + +NTSTRSAFEAPI RtlStringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy); +NTSTRSAFEAPI RtlStringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy); + + +NTSTRSAFEAPI RtlStringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy) { - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - return RtlStringValidateDestA(*Destination, - *DestinationLength, - ReturnLength, - MaxLength); + if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNWorkerA(pszDest,cchDest,pszSrc,cchToCopy); } -static __inline -NTSTATUS -NTAPI -RtlStringExValidateSrcA(IN OUT LPCSTR *Source OPTIONAL, - IN OUT PSIZE_T ReturnLength OPTIONAL, - IN SIZE_T MaxLength, - IN DWORD Flags) +NTSTRSAFEAPI RtlStringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy) { - NTSTATUS Status = STATUS_SUCCESS; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); + if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy); +} - if ((ReturnLength) && (*ReturnLength >= MaxLength)) - { + +NTSTRSAFEAPI RtlStringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy); +NTSTRSAFEAPI RtlStringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy); + + +NTSTRSAFEAPI RtlStringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy) +{ + if (cbDest > NTSTRSAFE_MAX_CCH || cbToCopy > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNWorkerA(pszDest,cbDest,pszSrc,cbToCopy); +} + +NTSTRSAFEAPI RtlStringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy); +} + + +NTSTRSAFEAPI RtlStringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags); +} + +NTSTRSAFEAPI RtlStringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCopyNExWorkerW(pszDest,cchDest,cchDest * sizeof(wchar_t),pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags); +} + + +NTSTRSAFEAPI RtlStringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchRemaining = 0; + if (cbDest > NTSTRSAFE_MAX_CCH) Status = STATUS_INVALID_PARAMETER; - } - + else + Status = RtlStringCopyNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToCopy,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = cchRemaining; return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringVPrintfWorkerA(OUT LPSTR Destination, - IN SIZE_T Length, - OUT PSIZE_T NewLength OPTIONAL, - IN LPCSTR Format, - IN va_list argList) +NTSTRSAFEAPI RtlStringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { - NTSTATUS Status = STATUS_SUCCESS; - LONG Return; - SIZE_T MaxLength, LocalNewLength = 0; + NTSTATUS Status; + size_t cchDest; + size_t cchToCopy; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + cchToCopy = cbToCopy / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCopyNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToCopy,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return Status; +} - MaxLength = Length - 1; - Return = _vsnprintf(Destination, MaxLength, Format, argList); - if ((Return < 0) || ((SIZE_T)Return > MaxLength)) - { - Destination += MaxLength; - *Destination = ANSI_NULL; +NTSTRSAFEAPI RtlStringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); - LocalNewLength = MaxLength; - Status = STATUS_BUFFER_OVERFLOW; - } - else if ((SIZE_T)Return == MaxLength) - { - Destination += MaxLength; - *Destination = ANSI_NULL; +NTSTRSAFEAPI RtlStringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatWorkerA(pszDest,cchDest,pszSrc); +} - LocalNewLength = MaxLength; - } +NTSTRSAFEAPI RtlStringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatWorkerW(pszDest,cchDest,pszSrc); +} + + +NTSTRSAFEAPI RtlStringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc); +NTSTRSAFEAPI RtlStringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc); + + +NTSTRSAFEAPI RtlStringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc) +{ + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatWorkerA(pszDest,cbDest,pszSrc); +} + +NTSTRSAFEAPI RtlStringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatWorkerW(pszDest,cchDest,pszSrc); +} + + +NTSTRSAFEAPI RtlStringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + +NTSTRSAFEAPI RtlStringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + size_t cbDest = cchDest*sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + + +NTSTRSAFEAPI RtlStringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchRemaining = 0; + if (cbDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCatExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + return Status; +} + +NTSTRSAFEAPI RtlStringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchRemaining = 0; + + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return Status; +} + + +NTSTRSAFEAPI RtlStringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend); +NTSTRSAFEAPI RtlStringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend); + + +NTSTRSAFEAPI RtlStringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNWorkerA(pszDest,cchDest,pszSrc,cchToAppend); +} + +NTSTRSAFEAPI RtlStringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend); +} + + +NTSTRSAFEAPI RtlStringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend); +NTSTRSAFEAPI RtlStringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend); + + +NTSTRSAFEAPI RtlStringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend) +{ + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNWorkerA(pszDest,cbDest,pszSrc,cbToAppend); +} + +NTSTRSAFEAPI RtlStringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend); +} + + +NTSTRSAFEAPI RtlStringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags); +} + +NTSTRSAFEAPI RtlStringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringCatNExWorkerW(pszDest,cchDest,(cchDest*sizeof(wchar_t)),pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags); +} + + +NTSTRSAFEAPI RtlStringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +NTSTRSAFEAPI RtlStringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + + +NTSTRSAFEAPI RtlStringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchRemaining = 0; + if (cbDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCatNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToAppend,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + return Status; +} + +NTSTRSAFEAPI RtlStringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + size_t cchRemaining = 0; + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringCatNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToAppend,ppszDestEnd,&cchRemaining,dwFlags); + if ((NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return Status; +} + + +NTSTRSAFEAPI RtlStringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList); + + +NTSTRSAFEAPI RtlStringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList); +} + +NTSTRSAFEAPI RtlStringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); +} + + +NTSTRSAFEAPI RtlStringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList); + + +NTSTRSAFEAPI RtlStringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList); +} + +NTSTRSAFEAPI RtlStringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); +} + + +NTSTRSAFEAPI RtlStringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...); +NTSTRSAFEAPI RtlStringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...); + + +NTSTRSAFEAPI RtlStringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return Status; +} + +NTSTRSAFEAPI RtlStringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return Status; +} + + +NTSTRSAFEAPI RtlStringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...); +NTSTRSAFEAPI RtlStringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...); + + +NTSTRSAFEAPI RtlStringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + if (cbDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList); + va_end(argList); + return Status; +} + +NTSTRSAFEAPI RtlStringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + size_t cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return Status; +} + + +NTSTRSAFEAPI RtlStringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...); +NTSTRSAFEAPI RtlStringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...); + + +NTSTRSAFEAPI RtlStringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...) +{ + NTSTATUS Status; + va_list argList; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cchDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + return Status; +} + +NTSTRSAFEAPI RtlStringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...) +{ + NTSTATUS Status; + size_t cbDest = cchDest * sizeof(wchar_t); + va_list argList; + if (cchDest > NTSTRSAFE_MAX_CCH) + return STATUS_INVALID_PARAMETER; + va_start(argList,pszFormat); + Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + return Status; +} + + +NTSTRSAFEAPI RtlStringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...); +NTSTRSAFEAPI RtlStringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...); + + +NTSTRSAFEAPI RtlStringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...) +{ + NTSTATUS Status; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; else { - LocalNewLength = Return; - } - - if (NewLength) *NewLength = LocalNewLength; - return Status; -} - -static __inline -NTSTATUS -NTAPI -RtlStringCopyWorkerA(OUT LPSTR Destination, - IN SIZE_T Length, - OUT PSIZE_T NewLength OPTIONAL, - IN LPCSTR Source, - IN SIZE_T CopyLength) -{ - NTSTATUS Status = STATUS_SUCCESS; - SIZE_T LocalNewLength = 0; - - while ((Length) && (CopyLength) && (*Source != ANSI_NULL)) - { - *Destination++ = *Source++; - Length--; - CopyLength--; - - LocalNewLength++; - } - - if (!Length) - { - Destination--; - LocalNewLength--; - - Status = STATUS_BUFFER_OVERFLOW; - } - - *Destination = ANSI_NULL; - - if (NewLength) *NewLength = LocalNewLength; - return Status; -} - -/* PUBLIC FUNCTIONS **********************************************************/ - -static __inline -NTSTATUS -NTAPI -RtlStringCchCopyA(IN LPSTR Destination, - IN SIZE_T cchDest, - IN LPCSTR pszSrc) -{ - ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE); - return STATUS_NOT_IMPLEMENTED; -} - -static __inline -NTSTATUS -RtlStringCbPrintfA(OUT LPSTR Destination, - IN SIZE_T Length, - IN LPCSTR Format, - ...) -{ - NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR); - va_list argList; - - Status = RtlStringValidateDestA(Destination, - CharLength, - NULL, - NTSTRSAFE_MAX_CCH); - if (NT_SUCCESS(Status)) - { - va_start(argList, Format); - Status = RtlStringVPrintfWorkerA(Destination, - CharLength, - NULL, - Format, - argList); + va_list argList; + va_start(argList,pszFormat); + Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); va_end(argList); } - + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (pcbRemaining) + { + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + } + } return Status; } -static __inline -NTSTATUS -RtlStringCbPrintfExA(OUT LPSTR Destination, - IN SIZE_T Length, - OUT LPSTR *DestinationEnd OPTIONAL, - OUT PSIZE_T RemainingSize OPTIONAL, - IN DWORD Flags, - IN LPCSTR Format, - ...) +NTSTRSAFEAPI RtlStringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...) { NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR), Remaining, LocalNewLength = 0; - PCHAR LocalDestinationEnd; - va_list argList; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - - Status = RtlStringExValidateDestA(&Destination, - &CharLength, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); - if (NT_SUCCESS(Status)) + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else { - LocalDestinationEnd = Destination; - Remaining = CharLength; + va_list argList; + va_start(argList,pszFormat); + Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (pcbRemaining) + { + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + return Status; +} - Status = RtlStringExValidateSrcA(&Format, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); + +NTSTRSAFEAPI RtlStringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); + + +NTSTRSAFEAPI RtlStringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + NTSTATUS Status; + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + size_t cbDest; + cbDest = cchDest*sizeof(char); + Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + } + return Status; +} + +NTSTRSAFEAPI RtlStringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + NTSTATUS Status; + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + size_t cbDest; + cbDest = cchDest*sizeof(wchar_t); + Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + } + return Status; +} + + +NTSTRSAFEAPI RtlStringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +NTSTRSAFEAPI RtlStringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); + + +NTSTRSAFEAPI RtlStringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + NTSTATUS Status; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (pcbRemaining) + { + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + } + } + return Status; +} + +NTSTRSAFEAPI RtlStringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + NTSTATUS Status; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if (cchDest > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (pcbRemaining) + { + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + return Status; +} + + +NTSTRSAFEAPI RtlStringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength); +NTSTRSAFEAPI RtlStringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength); + + +NTSTRSAFEAPI RtlStringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength) +{ + NTSTATUS Status; + if (!psz || (cchMax > NTSTRSAFE_MAX_CCH)) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringLengthWorkerA(psz,cchMax,pcchLength); + if (!NT_SUCCESS(Status) && pcchLength) + { + *pcchLength = 0; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength) +{ + NTSTATUS Status; + if (!psz || (cchMax > NTSTRSAFE_MAX_CCH)) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringLengthWorkerW(psz,cchMax,pcchLength); + if (!NT_SUCCESS(Status) && pcchLength) + { + *pcchLength = 0; + } + return Status; +} + + +NTSTRSAFEAPI RtlStringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength); +NTSTRSAFEAPI RtlStringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength); + + +NTSTRSAFEAPI RtlStringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength) +{ + NTSTATUS Status; + size_t cchMax; + size_t cchLength = 0; + cchMax = cbMax / sizeof(char); + if (!psz || (cchMax > NTSTRSAFE_MAX_CCH)) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringLengthWorkerA(psz,cchMax,&cchLength); + if (pcbLength) + { if (NT_SUCCESS(Status)) { - if (!Length) - { - if (*Format != ANSI_NULL) - { - if (!Destination) - { - Status = STATUS_INVALID_PARAMETER; - } - else - { - Status = STATUS_BUFFER_OVERFLOW; - } - } - } - else - { - va_start(argList, Format); - Status = RtlStringVPrintfWorkerA(Destination, - CharLength, - &LocalNewLength, - Format, - argList); - va_end(argList); - - LocalDestinationEnd = Destination + LocalNewLength; - Remaining = CharLength - LocalNewLength; - } + *pcbLength = cchLength*sizeof(char); } else { - if (Length) *Destination = ANSI_NULL; - } - - if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) - { - if (DestinationEnd) *DestinationEnd = LocalDestinationEnd; - - if (RemainingSize) - { - *RemainingSize = (Remaining * sizeof(CHAR)) + - (Length % sizeof(CHAR)); - } + *pcbLength = 0; } } - return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringCbCopyExA(OUT LPSTR Destination, - IN SIZE_T Length, - IN LPCSTR Source, - OUT LPSTR *DestinationEnd OPTIONAL, - OUT PSIZE_T RemainingSize OPTIONAL, - IN DWORD Flags) +NTSTRSAFEAPI RtlStringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength) { NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR), Copied = 0, Remaining; - PCHAR LocalDestinationEnd; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - - Status = RtlStringExValidateDestA(&Destination, - &Length, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); - if (NT_SUCCESS(Status)) + size_t cchMax; + size_t cchLength = 0; + cchMax = cbMax / sizeof(wchar_t); + if (!psz || (cchMax > NTSTRSAFE_MAX_CCH)) + Status = STATUS_INVALID_PARAMETER; + else + Status = RtlStringLengthWorkerW(psz,cchMax,&cchLength); + if (pcbLength) { - LocalDestinationEnd = Destination; - Remaining = CharLength; - - Status = RtlStringExValidateSrcA(&Source, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); if (NT_SUCCESS(Status)) { - if (!CharLength) - { - if (*Source != ANSI_NULL) - { - if (!Destination) - { - Status = STATUS_INVALID_PARAMETER; - } - else - { - Status = STATUS_BUFFER_OVERFLOW; - } - } - } - else - { - Status = RtlStringCopyWorkerA(Destination, - CharLength, - &Copied, - Source, - NTSTRSAFE_MAX_LENGTH); - - LocalDestinationEnd = Destination + Copied; - Remaining = CharLength - Copied; - } + *pcbLength = cchLength*sizeof(wchar_t); } else { - if (CharLength) *Destination = ANSI_NULL; - } - - if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) - { - if (DestinationEnd) *DestinationEnd = LocalDestinationEnd; - - if (RemainingSize) - { - *RemainingSize = (Remaining * sizeof(CHAR)) + - (Length % sizeof(CHAR)); - } + *pcbLength = 0; } } - return Status; } -static __inline -NTSTATUS -RtlStringCbPrintfW( - LPWSTR pszDest, - IN size_t cbDest, - IN LPCWSTR pszFormat, - ...) +NTSTRSAFEAPI RtlStringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { - ASSERTMSG("RtlStringCbPrintfW is UNIMPLEMENTED!\n", FALSE); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + while(cchDest && (*pszSrc!='\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + } + if (cchDest==0) + { + pszDest--; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDest= '\0'; + } + return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringCbCatExA(IN OUT LPSTR Destination, - IN SIZE_T Length, - IN LPCSTR Source, - OUT LPSTR *DestinationEnd OPTIONAL, - OUT PSIZE_T RemainingSize OPTIONAL, - IN DWORD Flags) +NTSTRSAFEAPI RtlStringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { - NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR); - SIZE_T DestinationLength, Remaining, Copied = 0; - PCHAR LocalDestinationEnd; - ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0); - - Status = RtlStringExValidateDestA(&Destination, - &CharLength, - &DestinationLength, - NTSTRSAFE_MAX_CCH, - Flags); - if (NT_SUCCESS(Status)) + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else { - LocalDestinationEnd = Destination + DestinationLength; - Remaining = CharLength - DestinationLength; + while(cchDest && (*pszSrc!=L'\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + } + if (cchDest==0) + { + pszDest--; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDest= L'\0'; + } + return Status; +} - Status = RtlStringExValidateSrcA(&Source, - NULL, - NTSTRSAFE_MAX_CCH, - Flags); +NTSTRSAFEAPI RtlStringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszSrc) + pszSrc = ""; + } if (NT_SUCCESS(Status)) { - if (Remaining <= 1) + if (cchDest==0) { - if (*Source != ANSI_NULL) + pszDestEnd = pszDest; + cchRemaining = 0; + if (*pszSrc!='\0') { - if (!Destination) - { + if (!pszDest) Status = STATUS_INVALID_PARAMETER; - } else - { Status = STATUS_BUFFER_OVERFLOW; - } } } else { - Status = RtlStringCopyWorkerA(LocalDestinationEnd, - Remaining, - &Copied, - Source, - NTSTRSAFE_MAX_LENGTH); - - LocalDestinationEnd = LocalDestinationEnd + Copied; - Remaining = Remaining - Copied; - } - } - - if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) - { - if (DestinationEnd) *DestinationEnd = LocalDestinationEnd; - - if (RemainingSize) - { - *RemainingSize = (Remaining * sizeof(CHAR)) + - (Length % sizeof(CHAR)); + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && (*pszSrc!='\0')) + { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + } + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + else + { + pszDestEnd--; + cchRemaining++; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDestEnd = '\0'; } } } - + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } return Status; } -static __inline -NTSTATUS -NTAPI -RtlStringCbCopyA(OUT LPSTR Destination, - IN SIZE_T Length, - IN LPCSTR Source) +NTSTRSAFEAPI RtlStringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszSrc) + pszSrc = L""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if (*pszSrc!=L'\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && (*pszSrc!=L'\0')) + { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + } + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + else + { + pszDestEnd--; + cchRemaining++; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDestEnd = L'\0'; + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchSrc) +{ + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + while(cchDest && cchSrc && (*pszSrc!='\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + cchSrc--; + } + if (cchDest==0) + { + pszDest--; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDest= '\0'; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy) +{ + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + while(cchDest && cchToCopy && (*pszSrc!=L'\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + cchToCopy--; + } + if (cchDest==0) + { + pszDest--; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDest= L'\0'; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + if (cchToCopy > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszSrc) + pszSrc = ""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if ((cchToCopy!=0) && (*pszSrc!='\0')) + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && cchToCopy && (*pszSrc!='\0')) + { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + cchToCopy--; + } + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + else + { + pszDestEnd--; + cchRemaining++; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDestEnd = '\0'; + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + if (cchToCopy > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszSrc) + pszSrc = L""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if ((cchToCopy!=0) && (*pszSrc!=L'\0')) + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && cchToCopy && (*pszSrc!=L'\0')) + { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + cchToCopy--; + } + if (cchRemaining > 0) + { + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + else + { + pszDestEnd--; + cchRemaining++; + Status = STATUS_BUFFER_OVERFLOW; + } + *pszDestEnd = L'\0'; + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { NTSTATUS Status; - SIZE_T CharLength = Length / sizeof(CHAR); - - Status = RtlStringValidateDestA(Destination, - CharLength, - NULL, - NTSTRSAFE_MAX_CCH); + size_t cchDestLength; + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); if (NT_SUCCESS(Status)) - { - Status = RtlStringCopyWorkerA(Destination, - CharLength, - NULL, - Source, - NTSTRSAFE_MAX_LENGTH); - } - + Status = RtlStringCopyWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc); return Status; } -#endif /* _NTSTRSAFE_H_INCLUDED_ */ +NTSTRSAFEAPI RtlStringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) +{ + NTSTATUS Status; + size_t cchDestLength; + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + Status = RtlStringCopyWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc); + return Status; +} + +NTSTRSAFEAPI RtlStringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + size_t cchDestLength; + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest==0) && (cbDest==0)) + cchDestLength = 0; + else + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (!pszSrc) + pszSrc = ""; + } + else + { + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + if (*pszSrc!='\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + Status = RtlStringCopyExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & STRSAFE_NULL_ON_FAILURE) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + size_t cchDestLength; + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest==0) && (cbDest==0)) + cchDestLength = 0; + else + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (!pszSrc) + pszSrc = L""; + } + else + { + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + if (*pszSrc!=L'\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + Status = RtlStringCopyExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & STRSAFE_NULL_ON_FAILURE) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend) +{ + NTSTATUS Status; + size_t cchDestLength; + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + Status = RtlStringCopyNWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend); + return Status; +} + +NTSTRSAFEAPI RtlStringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend) +{ + NTSTATUS Status; + size_t cchDestLength; + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + Status = RtlStringCopyNWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend); + return Status; +} + +NTSTRSAFEAPI RtlStringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestLength = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + if (cchToAppend > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest==0) && (cbDest==0)) + cchDestLength = 0; + else + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (!pszSrc) + pszSrc = ""; + } + else + { + Status = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + if ((cchToAppend!=0) && (*pszSrc!='\0')) + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + Status = RtlStringCopyNExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestLength = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + if (cchToAppend > NTSTRSAFE_MAX_CCH) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest==0) && (cbDest==0)) + cchDestLength = 0; + else + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (!pszSrc) + pszSrc = L""; + } + else + { + Status = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if (NT_SUCCESS(Status)) + { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + if ((cchToAppend!=0) && (*pszSrc!=L'\0')) + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + Status = RtlStringCopyNExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList); + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + pszDest += cchMax; + *pszDest = '\0'; + Status = STATUS_BUFFER_OVERFLOW; + } + else + if (((size_t)iRet)==cchMax) + { + pszDest += cchMax; + *pszDest = '\0'; + } + } + return Status; +} + +NTSTRSAFEAPI RtlStringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + NTSTATUS Status = STATUS_SUCCESS; + if (cchDest==0) + Status = STATUS_INVALID_PARAMETER; + else + { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList); + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + pszDest += cchMax; + *pszDest = L'\0'; + Status = STATUS_BUFFER_OVERFLOW; + } + else + if (((size_t)iRet)==cchMax) + { + pszDest += cchMax; + *pszDest = L'\0'; + } + } + return Status; +} + +NTSTRSAFEAPI RtlStringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszFormat) + pszFormat = ""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if (*pszFormat!='\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList); + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = '\0'; + Status = STATUS_BUFFER_OVERFLOW; + } + else + if (((size_t)iRet)==cchMax) + { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + else + if (((size_t)iRet) < cchMax) + { + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) +{ + NTSTATUS Status = STATUS_SUCCESS; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + Status = STATUS_INVALID_PARAMETER; + else + { + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (!pszDest) + { + if ((cchDest!=0) || (cbDest!=0)) + Status = STATUS_INVALID_PARAMETER; + } + if (!pszFormat) + pszFormat = L""; + } + if (NT_SUCCESS(Status)) + { + if (cchDest==0) + { + pszDestEnd = pszDest; + cchRemaining = 0; + if (*pszFormat!=L'\0') + { + if (!pszDest) + Status = STATUS_INVALID_PARAMETER; + else + Status = STATUS_BUFFER_OVERFLOW; + } + } + else + { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList); + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = L'\0'; + Status = STATUS_BUFFER_OVERFLOW; + } + else + if (((size_t)iRet)==cchMax) + { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + else + if (((size_t)iRet) < cchMax) + { + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + if (dwFlags & STRSAFE_FILL_BEHIND_NULL) + { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + } + } + } + if (!NT_SUCCESS(Status)) + { + if (pszDest) + { + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if (STRSAFE_GET_FILL_PATTERN(dwFlags)==0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } + else + if (cchDest > 0) + { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) + { + if (cchDest > 0) + { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if (NT_SUCCESS(Status) || (Status==STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + *ppszDestEnd = pszDestEnd; + if (pcchRemaining) + *pcchRemaining = cchRemaining; + } + return Status; +} + +NTSTRSAFEAPI RtlStringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength) +{ + NTSTATUS Status = STATUS_SUCCESS; + size_t cchMaxPrev = cchMax; + while(cchMax && (*psz!='\0')) + { + psz++; + cchMax--; + } + if (cchMax==0) + Status = STATUS_INVALID_PARAMETER; + if (pcchLength) + { + if (NT_SUCCESS(Status)) + *pcchLength = cchMaxPrev - cchMax; + else + *pcchLength = 0; + } + return Status; +} + +NTSTRSAFEAPI RtlStringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength) +{ + NTSTATUS Status = STATUS_SUCCESS; + size_t cchMaxPrev = cchMax; + while(cchMax && (*psz!=L'\0')) + { + psz++; + cchMax--; + } + if (cchMax==0) + Status = STATUS_INVALID_PARAMETER; + if (pcchLength) + { + if (NT_SUCCESS(Status)) + *pcchLength = cchMaxPrev - cchMax; + else + *pcchLength = 0; + } + return Status; +} + + + +#define RtlStringCopyWorkerA RtlStringCopyWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define RtlStringCopyWorkerW RtlStringCopyWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define RtlStringCopyExWorkerA RtlStringCopyExWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define RtlStringCopyExWorkerW RtlStringCopyExWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define RtlStringCatWorkerA RtlStringCatWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define RtlStringCatWorkerW RtlStringCatWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define RtlStringCatExWorkerA RtlStringCatExWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define RtlStringCatExWorkerW RtlStringCatExWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define RtlStringCatNWorkerA RtlStringCatNWorkerA_instead_use_StringCchCatNA_or_StrincCbCatNA; +#define RtlStringCatNWorkerW RtlStringCatNWorkerW_instead_use_StringCchCatNW_or_StringCbCatNW; +#define RtlStringCatNExWorkerA RtlStringCatNExWorkerA_instead_use_StringCchCatNExA_or_StringCbCatNExA; +#define RtlStringCatNExWorkerW RtlStringCatNExWorkerW_instead_use_StringCchCatNExW_or_StringCbCatNExW; +#define RtlStringVPrintfWorkerA RtlStringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define RtlStringVPrintfWorkerW RtlStringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define RtlStringVPrintfExWorkerA RtlStringVPrintfExWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define RtlStringVPrintfExWorkerW RtlStringVPrintfExWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define RtlStringLengthWorkerA RtlStringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA; +#define RtlStringLengthWorkerW RtlStringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW; + +#endif diff --git a/include/ndk/haltypes.h b/include/ndk/haltypes.h index 272a0d4fdc2..904a83146f1 100644 --- a/include/ndk/haltypes.h +++ b/include/ndk/haltypes.h @@ -270,6 +270,11 @@ extern NTSYSAPI HAL_PRIVATE_DISPATCH HalPrivateDispatchTable; // extern PUCHAR NTHALAPI KdComPortInUse; +// +// HAL Constants +// +#define HAL_IRQ_TRANSLATOR_VERSION 0x0 + #endif #endif diff --git a/include/psdk/commctrl.h b/include/psdk/commctrl.h index 2b2bfd38bd7..a6563982eaa 100644 --- a/include/psdk/commctrl.h +++ b/include/psdk/commctrl.h @@ -381,7 +381,7 @@ extern "C" { #define ILCF_SWAP 0x1 WINCOMMCTRLAPI WINBOOL WINAPI ImageList_Copy(HIMAGELIST himlDst,int iDst,HIMAGELIST himlSrc,int iSrc,UINT uFlags); WINCOMMCTRLAPI WINBOOL WINAPI ImageList_BeginDrag(HIMAGELIST himlTrack,int iTrack,int dxHotspot,int dyHotspot); - WINCOMMCTRLAPI void WINAPI ImageList_EndDrag(); + WINCOMMCTRLAPI void WINAPI ImageList_EndDrag(void); WINCOMMCTRLAPI WINBOOL WINAPI ImageList_DragEnter(HWND hwndLock,int x,int y); WINCOMMCTRLAPI WINBOOL WINAPI ImageList_DragLeave(HWND hwndLock); WINCOMMCTRLAPI WINBOOL WINAPI ImageList_DragMove(int x,int y); diff --git a/include/psdk/ntgdi.h b/include/psdk/ntgdi.h index e8050217a23..0ce2e6df05b 100644 --- a/include/psdk/ntgdi.h +++ b/include/psdk/ntgdi.h @@ -80,7 +80,7 @@ typedef struct tagDOWNLOADDESIGNVECTOR W32KAPI BOOL APIENTRY -NtGdiInit(); +NtGdiInit(VOID); W32KAPI INT @@ -1239,7 +1239,7 @@ NtGdiIcmBrushInfo( W32KAPI VOID APIENTRY -NtGdiFlush(); +NtGdiFlush(VOID); W32KAPI HDC @@ -3277,7 +3277,7 @@ NtGdiCLIPOBJ_ppoGetPath( W32KAPI CLIPOBJ* APIENTRY -NtGdiEngCreateClip(); +NtGdiEngCreateClip(VOID); W32KAPI VOID @@ -3660,7 +3660,7 @@ NtGdiMakeObjectUnXferable( W32KAPI BOOL APIENTRY -NtGdiInitSpool(); +NtGdiInitSpool(VOID); /* FIXME wrong prototypes fix the build */ W32KAPI diff --git a/include/psdk/shlwapi_undoc.h b/include/psdk/shlwapi_undoc.h index 11cb464cdc7..41f60a13e9e 100644 --- a/include/psdk/shlwapi_undoc.h +++ b/include/psdk/shlwapi_undoc.h @@ -47,7 +47,7 @@ struct IEThreadParamBlock void WINAPI InitOCHostClass(long param8); long WINAPI SHOpenFolderWindow(IEThreadParamBlock *param8); -void WINAPI SHCreateSavedWindows(); +void WINAPI SHCreateSavedWindows(void); long WINAPI SHCreateFromDesktop(long param8); long WINAPI SHExplorerParseCmdLine(LPCTSTR commandLine); void WINAPI UEMRegisterNotify(long param8, long paramC); @@ -59,11 +59,11 @@ IEThreadParamBlock *WINAPI SHCloneIETHREADPARAM(IEThreadParamBlock *param); long WINAPI SHParseIECommandLine(long param8, long paramC); void WINAPI SHDestroyIETHREADPARAM(IEThreadParamBlock *param); HRESULT WINAPI SHOnCWMCommandLine(long param8); -LPITEMIDLIST WINAPI Channel_GetFolderPidl(); +LPITEMIDLIST WINAPI Channel_GetFolderPidl(void); IUnknown *WINAPI ChannelBand_Create(LPITEMIDLIST pidl); HRESULT WINAPI Channels_SetBandInfoSFB(IUnknown *param8); HRESULT WINAPI IUnknown_SetBandInfoSFB(IUnknown *param8, long paramC); -HRESULT WINAPI Channel_QuickLaunch(); +HRESULT WINAPI Channel_QuickLaunch(void); HRESULT WINAPI SHGetNavigateTarget(long param8, long paramC, long param10, long param14); HRESULT WINAPI GetInfoTip(IUnknown *param8, long paramC, LPTSTR *param10, long cchMax); HRESULT WINAPI SHEnumClassesOfCategories(long param8, long paramC, long param10, long param14, long param18); diff --git a/include/psdk/strsafe.h b/include/psdk/strsafe.h index 0f84a20dd77..f3f7eac7f21 100644 --- a/include/psdk/strsafe.h +++ b/include/psdk/strsafe.h @@ -1,631 +1,2062 @@ -#ifndef __STRSAFE_H_ -#define __STRSAFE_H_ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#ifndef _STRSAFE_H_INCLUDED_ +#define _STRSAFE_H_INCLUDED_ +#include <_mingw_unicode.h> #include -#include +#include #include +#include -#if defined(STRSAFE_NO_CCH_FUNCTIONS) && defined(STRSAFE_NO_CB_FUNCTIONS) -#error Both STRSAFE_NO_CCH_FUNCTIONS and STRSAFE_NO_CB_FUNCTIONS are defined +#ifndef _SIZE_T_DEFINED +#define _SIZE_T_DEFINED +#undef size_t +#ifdef _WIN64 +__MINGW_EXTENSION typedef unsigned __int64 size_t; +#else +typedef unsigned int size_t; +#endif #endif -#ifndef SUCCEEDED -#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0) +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 +__MINGW_EXTENSION typedef __int64 ssize_t; +#else +typedef int ssize_t; #endif -#define STRSAFE_MAX_CCH 2147483647 -#define STRSAFE_E_INVALID_PARAMETER ((HRESULT)0x80070057L) -#define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) -#define STRSAFE_E_END_OF_FILE ((HRESULT)0x80070026L) - -#define STRSAFE_FILL_BEHIND_NULL 0x00000200 -#define STRSAFE_IGNORE_NULLS 0x00000200 -#define STRSAFE_FILL_ON_FAILURE 0x00000400 -#define STRSAFE_NULL_ON_FAILURE 0x00000800 -#define STRSAFE_NO_TRUNCATION 0x00001000 - -#ifndef S_OK -#define S_OK ((HRESULT)0x00000000L) #endif -#define STRSAFE_MIN(a,b) (((a) < (b))?(a):(b)) +#ifndef _WCHAR_T_DEFINED +#define _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +#endif #ifndef _HRESULT_DEFINED #define _HRESULT_DEFINED typedef long HRESULT; #endif -typedef char * STRSAFE_LPSTR; -typedef const char * STRSAFE_LPCSTR; -typedef wchar_t * STRSAFE_LPWSTR; -typedef const wchar_t * STRSAFE_LPCWSTR; -typedef unsigned long STRSAFE_DWORD; - -#define STRSAFE_PASS2 - -/* Implement Cb functions for ansi and unicode */ -#ifndef STRSAFE_NO_CB_FUNCTIONS -#define STRSAFE_CB -#define STRSAFE_UNICODE 0 -# include -#undef STRSAFE_UNICODE -#define STRSAFE_UNICODE 1 -# include -#undef STRSAFE_UNICODE -#undef STRSAFE_CB -#endif // !STRSAFE_NO_CB_FUNCTIONS - -/* Implement Cch functions for ansi and unicode */ -#ifndef STRSAFE_NO_CCH_FUNCTIONS -#define STRSAFE_UNICODE 0 -# include -#undef STRSAFE_UNICODE -#define STRSAFE_UNICODE 1 -# include -#undef STRSAFE_UNICODE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - -#undef STRSAFE_PASS2 - -/* Now define the functions depending on UNICODE */ -#if defined(UNICODE) -# define STRSAFE_UNICODE 1 -#else -# define STRSAFE_UNICODE 0 -#endif -#include -#undef STRSAFE_UNICODE - -#endif // !__STRSAFE_H_ - -/*****************************************************************************/ - -#if defined(STRSAFE_UNICODE) -#if (STRSAFE_UNICODE == 1) - -#define STRSAFE_LPTSTR STRSAFE_LPWSTR -#define STRSAFE_LPCTSTR STRSAFE_LPCWSTR -#define STRSAFE_TCHAR wchar_t - -#define StringCbCat StringCbCatW -#define StringCbCatEx StringCbCatExW -#define StringCbCatN StringCbCatNW -#define StringCbCatNEx StringCbCatNExW -#define StringCbCatWorker StringCxxCatWorkerW -#define StringCbCopy StringCbCopyW -#define StringCbCopyEx StringCbCopyExW -#define StringCbCopyN StringCbCopyNW -#define StringCbCopyNEx StringCbCopyNExW -#define StringCbGets StringCbGetsW -#define StringCbGetsEx StringCbGetsExW -#define StringCbLength StringCbLengthW -#define StringCbPrintf StringCbPrintfW -#define StringCbPrintfEx StringCbPrintfExW -#define StringCbVPrintf StringCbVPrintfW -#define StringCbVPrintfEx StringCbVPrintfExW -#define StringCchCat StringCchCatW -#define StringCchCatEx StringCchCatExW -#define StringCchCatN StringCchCatNW -#define StringCchCatNEx StringCchCatNExW -#define StringCchCatWorker StringCchCatWorkerW -#define StringCchCopy StringCchCopyW -#define StringCchCopyEx StringCchCopyExW -#define StringCchCopyN StringCchCopyNW -#define StringCchCopyNEx StringCchCopyNExW -#define StringCchGets StringCchGetsW -#define StringCchGetsEx StringCchGetsExW -#define StringCchLength StringCchLengthW -#define StringCchPrintf StringCchPrintfW -#define StringCchPrintfEx StringCchPrintfExW -#define StringCchVPrintf StringCchVPrintfW -#define StringCchVPrintfEx StringCchVPrintfExW -#define _vsnprintfAW _vsnwprintf - -#else // (STRSAFE_UNICODE != 1) - -#define STRSAFE_LPTSTR STRSAFE_LPSTR -#define STRSAFE_LPCTSTR STRSAFE_LPCSTR -#define STRSAFE_TCHAR char - -#define StringCbCat StringCbCatA -#define StringCbCatEx StringCbCatExA -#define StringCbCatN StringCbCatNA -#define StringCbCatNEx StringCbCatNExA -#define StringCbCatWorker StringCxxCatWorkerA -#define StringCbCopy StringCbCopyA -#define StringCbCopyEx StringCbCopyExA -#define StringCbCopyN StringCbCopyNA -#define StringCbCopyNEx StringCbCopyNExA -#define StringCbGets StringCbGetsA -#define StringCbGetsEx StringCbGetsExA -#define StringCbLength StringCbLengthA -#define StringCbPrintf StringCbPrintfA -#define StringCbPrintfEx StringCbPrintfExA -#define StringCbVPrintf StringCbVPrintfA -#define StringCbVPrintfEx StringCbVPrintfExA -#define StringCchCat StringCchCatA -#define StringCchCatEx StringCchCatExA -#define StringCchCatN StringCchCatNA -#define StringCchCatNEx StringCchCatNExA -#define StringCchCatWorker StringCchCatWorkerA -#define StringCchCopy StringCchCopyA -#define StringCchCopyEx StringCchCopyExA -#define StringCchCopyN StringCchCopyNA -#define StringCchCopyNEx StringCchCopyNExA -#define StringCchGets StringCchGetsA -#define StringCchGetsEx StringCchGetsExA -#define StringCchLength StringCchLengthA -#define StringCchPrintf StringCchPrintfA -#define StringCchPrintfEx StringCchPrintfExA -#define StringCchVPrintf StringCchVPrintfA -#define StringCchVPrintfEx StringCchVPrintfExA -#define _vsnprintfAW _vsnprintf - -#endif // (STRSAFE_UNICODE != 1) -#endif // defined(STRSAFE_UNICODE) - -/*****************************************************************************/ - -#if defined (STRSAFE_PASS2) - -#if defined(STRSAFE_CB) - -#define STRSAFE_CXXtoCB(x) (x) -#define STRSAFE_CBtoCXX(x) (x) -#define STRSAFE_CXXtoCCH(x) (x)/sizeof(STRSAFE_TCHAR) -#define STRSAFE_CCHtoCXX(x) (x)*sizeof(STRSAFE_TCHAR) -#define StringCxxCat StringCbCat -#define StringCxxCatEx StringCbCatEx -#define StringCxxCatN StringCbCatN -#define StringCxxCatNEx StringCbCatNEx -#define StringCxxCatWorker StringCbCatWorker -#define StringCxxCopy StringCbCopy -#define StringCxxCopyEx StringCbCopyEx -#define StringCxxCopyN StringCbCopyN -#define StringCxxCopyNEx StringCbCopyNEx -#define StringCxxGets StringCbGets -#define StringCxxGetsEx StringCbGetsEx -#define StringCxxLength StringCbLength -#define StringCxxPrintf StringCbPrintf -#define StringCxxPrintfEx StringCbPrintfEx -#define StringCxxVPrintf StringCbVPrintf -#define StringCxxVPrintfEx StringCbVPrintfEx - -#else // !STRSAFE_CB - -#define STRSAFE_CXXtoCB(x) (x)*sizeof(STRSAFE_TCHAR) -#define STRSAFE_CBtoCXX(x) (x)/sizeof(STRSAFE_TCHAR) -#define STRSAFE_CXXtoCCH(x) (x) -#define STRSAFE_CCHtoCXX(x) (x) -#define StringCxxCat StringCchCat -#define StringCxxCatEx StringCchCatEx -#define StringCxxCatN StringCchCatN -#define StringCxxCatNEx StringCchCatNEx -#define StringCxxCatWorker StringCchCatWorker -#define StringCxxCopy StringCchCopy -#define StringCxxCopyEx StringCchCopyEx -#define StringCxxCopyN StringCchCopyN -#define StringCxxCopyNEx StringCchCopyNEx -#define StringCxxGets StringCchGets -#define StringCxxGetsEx StringCchGetsEx -#define StringCxxLength StringCchLength -#define StringCxxPrintf StringCchPrintf -#define StringCxxPrintfEx StringCchPrintfEx -#define StringCxxVPrintf StringCchVPrintf -#define StringCxxVPrintfEx StringCchVPrintfEx - -#endif // !STRSAFE_CB - -#ifdef STRSAFE_LIB - -/* Normal function prototypes only */ -#define STRSAFEAPI HRESULT __stdcall - -STRSAFEAPI StringCxxCat(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc); -STRSAFEAPI StringCxxCatEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxCatN(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbMaxAppend); -STRSAFEAPI StringCxxCatNEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbMaxAppend, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxCopy(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc); -STRSAFEAPI StringCxxCopyEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxCopyN(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbSrc); -STRSAFEAPI StringCxxCopyNEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxGets(STRSAFE_LPTSTR pszDest, size_t cxDest); -STRSAFEAPI StringCxxGetsEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags); -STRSAFEAPI StringCxxLength(STRSAFE_LPCTSTR psz, size_t cxMax, size_t *pcb); -STRSAFEAPI StringCxxPrintf(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszFormat, ...); -STRSAFEAPI StringCxxPrintfEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags, STRSAFE_LPCTSTR pszFormat, ...); -STRSAFEAPI StringCxxVPrintf(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszFormat, va_list args); -STRSAFEAPI StringCxxVPrintfEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags, LPCTSTR pszFormat, va_list args); - -#else // !STRSAFE_LIB - -/* Create inlined versions */ -#ifdef __GNUC__ -#define STRSAFEAPI HRESULT static __inline__ -#else -#define STRSAFEAPI HRESULT __inline +#ifndef SUCCEEDED +#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) #endif -#define STRSAFE_MAX_CXX STRSAFE_CCHtoCXX(STRSAFE_MAX_CCH) - -STRSAFEAPI -StringCxxCatWorker( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc, - size_t cxMaxAppend, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags, - int UseN) -{ - HRESULT result; - STRSAFE_LPTSTR psz = pszDest; - size_t cch = STRSAFE_CXXtoCCH(cxDest); - - if (!pszDest || !pszSrc || cxDest > STRSAFE_MAX_CXX || cxDest == 0) - { - return STRSAFE_E_INVALID_PARAMETER; - } - - for (--psz; *(++psz) != 0 && --cch > 0;); - if (cch == 0) - { - return STRSAFE_E_INSUFFICIENT_BUFFER; - } - - if (UseN) - { - cch = STRSAFE_MIN(cxDest, STRSAFE_CXXtoCCH(cxMaxAppend)); - } - - for (--pszSrc, --psz; (*(++psz) = *(++pszSrc)) != 0 && --cch > 0;); - if (cch == 0) - { - result = STRSAFE_E_INSUFFICIENT_BUFFER; - } - else - result = S_OK; - - if (ppszDestEnd) - { - *ppszDestEnd = psz; - } - - if (pcbRemaining) - { - *pcbRemaining = STRSAFE_CCHtoCXX(cch); - } - - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - for (--psz, ++cch; --cch; *(++psz) = dwFlags & 0xff); - } - - if (!SUCCEEDED(result)) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - cch = STRSAFE_CXXtoCCH(cxDest); - for (--pszDest, ++cch; --cch; *(++pszDest) = dwFlags & 0xff); - } - - if (dwFlags & STRSAFE_NULL_ON_FAILURE) - { - *pszDest = 0; - } - } - - return result; -} - -STRSAFEAPI -StringCxxCatEx( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return StringCxxCatWorker(pszDest, cxDest, pszSrc, 0, ppszDestEnd, pcbRemaining, dwFlags, 0); -} - -STRSAFEAPI -StringCxxCat( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc) -{ - return StringCxxCatWorker(pszDest, cxDest, pszSrc, 0, NULL, NULL, 0, 0); -} - -STRSAFEAPI -StringCxxCatN( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc, - size_t cbMaxAppend) -{ - return StringCxxCatWorker(pszDest, cxDest, pszSrc, cbMaxAppend, NULL, NULL, 0, 1); -} - -STRSAFEAPI -StringCxxCatNEx( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszSrc, - size_t cbMaxAppend, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return StringCxxCatWorker(pszDest, cxDest, pszSrc, cbMaxAppend, ppszDestEnd, pcbRemaining, dwFlags, 1); -} - -STRSAFEAPI -StringCxxCopy( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPCTSTR pszSrc) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxCopyEx( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPCTSTR pszSrc, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxCopyN( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPCTSTR pszSrc, - size_t cbSrc) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxCopyNEx( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPCTSTR pszSrc, - size_t cbSrc, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxGets( - STRSAFE_LPTSTR pszDest, - size_t cbDest) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxGetsEx( - STRSAFE_LPTSTR pszDest, - size_t cbDest, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags) -{ - return 0; // FIXME -} - -STRSAFEAPI -StringCxxLength( - STRSAFE_LPCTSTR psz, - size_t cxMax, - size_t *pcx) -{ - size_t cch = STRSAFE_CXXtoCCH(cxMax); - - /* Default return on error */ - if (pcx) - *pcx = 0; - - if (!psz || cxMax > STRSAFE_MAX_CXX || cxMax == 0) - { - return STRSAFE_E_INVALID_PARAMETER; - } - - for (--psz; *(++psz) != 0 && --cch > 0;); - - if (cch == 0) - { - return STRSAFE_E_INVALID_PARAMETER; - } - - if (pcx) - *pcx = cxMax - STRSAFE_CCHtoCXX(cch); - - return S_OK; -} - -STRSAFEAPI -StringCxxVPrintfEx( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcxRemaining, - STRSAFE_DWORD dwFlags, - STRSAFE_LPCTSTR pszFormat, - va_list args) -{ - size_t cchDest = STRSAFE_CXXtoCCH(cxDest); - size_t cchMax = cchDest - 1; - int iResult; - HRESULT hr; - - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (!pszDest) pszDest = (STRSAFE_LPTSTR)L""; - if (!pszFormat) pszFormat = (STRSAFE_LPTSTR)L""; - } - - if (!pszDest || !pszFormat || cxDest > STRSAFE_MAX_CXX || cxDest == 0) - { - return STRSAFE_E_INVALID_PARAMETER; - } - -#if (STRSAFE_USE_SECURE_CRT == 1) - iResult = _vsnprintf_sAW(pszDest, cchDest, cchMax, pszFormat, args); -#else - iResult = _vsnprintfAW(pszDest, cchMax, pszFormat, args); +#ifndef FAILED +#define FAILED(hr) ((HRESULT)(hr) < 0) #endif - hr = (iResult == -1) ? STRSAFE_E_INSUFFICIENT_BUFFER : S_OK; +#ifndef S_OK +#define S_OK ((HRESULT)0x00000000L) +#endif - if ((size_t)iResult >= cchMax) - { - pszDest[cchMax] = 0; - iResult = cchMax; +#ifndef C_ASSERT +#ifdef _MSC_VER +# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] +#else +# define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) +#endif +#endif /* C_ASSERT */ + +#ifdef __cplusplus +#define _STRSAFE_EXTERN_C extern "C" +#else +#define _STRSAFE_EXTERN_C extern +#endif + +#ifndef WINAPI +#define WINAPI __stdcall +#endif + +#define STRSAFEAPI static __inline HRESULT WINAPI +#define STRSAFE_INLINE_API __CRT_INLINE HRESULT WINAPI + +#define STRSAFE_MAX_CCH 2147483647 + +#ifndef _NTSTRSAFE_H_INCLUDED_ +#define STRSAFE_IGNORE_NULLS 0x00000100 +#define STRSAFE_FILL_BEHIND_NULL 0x00000200 +#define STRSAFE_FILL_ON_FAILURE 0x00000400 +#define STRSAFE_NULL_ON_FAILURE 0x00000800 +#define STRSAFE_NO_TRUNCATION 0x00001000 +#define STRSAFE_IGNORE_NULL_UNICODE_STRINGS 0x00010000 +#define STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED 0x00020000 + +#define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION) +#define STRSAFE_UNICODE_STRING_VALID_FLAGS (STRSAFE_VALID_FLAGS | STRSAFE_IGNORE_NULL_UNICODE_STRINGS | STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED) + +#define STRSAFE_FILL_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL)) +#define STRSAFE_FAILURE_BYTE(x) ((STRSAFE_DWORD)(((x) & 0x000000FF) | STRSAFE_FILL_ON_FAILURE)) + +#define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)((dwFlags) & 0x000000FF)) +#endif + +#define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) +#define STRSAFE_E_INVALID_PARAMETER ((HRESULT)0x80070057L) +#define STRSAFE_E_END_OF_FILE ((HRESULT)0x80070026L) + +typedef char *STRSAFE_LPSTR; +typedef const char *STRSAFE_LPCSTR; +typedef wchar_t *STRSAFE_LPWSTR; +typedef const wchar_t *STRSAFE_LPCWSTR; + +typedef ULONG STRSAFE_DWORD; + +STRSAFEAPI StringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); +STRSAFEAPI StringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy); +STRSAFEAPI StringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy); +STRSAFEAPI StringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); +STRSAFEAPI StringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend); +STRSAFEAPI StringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend); +STRSAFEAPI StringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList); +STRSAFEAPI StringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); +STRSAFEAPI StringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength); +STRSAFEAPI StringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength); +STRSAFE_INLINE_API StringGetsExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFE_INLINE_API StringGetsExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchCopy __MINGW_NAME_AW(StringCchCopy) + +STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { + return (cchDest > STRSAFE_MAX_CCH ? STRSAFE_E_INVALID_PARAMETER : StringCopyWorkerA(pszDest,cchDest,pszSrc)); +} + +STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyWorkerW(pszDest,cchDest,pszSrc); +} +#endif /* !__CRT__NO_INLINE */ + +#define StringCbCopy __MINGW_NAME_AW(StringCbCopy) + +STRSAFEAPI StringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc); + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCopyA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc) { + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyWorkerA(pszDest,cbDest,pszSrc); +} + +STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc) { + size_t cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyWorkerW(pszDest,cchDest,pszSrc); +} +#endif /* !__CRT__NO_INLINE */ + +#define StringCchCopyEx __MINGW_NAME_AW(StringCchCopyEx) + +STRSAFEAPI StringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCopyExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + +STRSAFEAPI StringCchCopyExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + size_t cbDest; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + cbDest = cchDest * sizeof(wchar_t); + return StringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} +#endif /* !__CRT__NO_INLINE */ + +#define StringCbCopyEx __MINGW_NAME_AW(StringCbCopyEx) + +STRSAFEAPI StringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCopyExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchRemaining = 0; + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + hr = StringCopyExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if(SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) { + if(pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + } + return hr; +} + +STRSAFEAPI StringCbCopyExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchRemaining = 0; + + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + hr = StringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy); +STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy); +#define StringCchCopyN __MINGW_NAME_AW(StringCchCopyN) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCopyNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy) { + if(cchDest > STRSAFE_MAX_CCH || cchToCopy > STRSAFE_MAX_CCH) + return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNWorkerA(pszDest,cchDest,pszSrc,cchToCopy); +} + +STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy) { + if(cchDest > STRSAFE_MAX_CCH || cchToCopy > STRSAFE_MAX_CCH) + return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy); +STRSAFEAPI StringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy); + +#define StringCbCopyN __MINGW_NAME_AW(StringCbCopyN) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCopyNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy) { + if(cbDest > STRSAFE_MAX_CCH || cbToCopy > STRSAFE_MAX_CCH) + return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNWorkerA(pszDest,cbDest,pszSrc,cbToCopy); +} + +STRSAFEAPI StringCbCopyNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy) { + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH || cchToCopy > STRSAFE_MAX_CCH) + return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchCopyNEx __MINGW_NAME_AW(StringCchCopyNEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCopyNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags); +} + +STRSAFEAPI StringCchCopyNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCopyNExWorkerW(pszDest,cchDest,cchDest * sizeof(wchar_t),pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + +#define StringCbCopyNEx __MINGW_NAME_AW(StringCbCopyNEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCopyNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchRemaining = 0; + if(cbDest > STRSAFE_MAX_CCH) + hr = STRSAFE_E_INVALID_PARAMETER; + else + hr = StringCopyNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToCopy,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = cchRemaining; + return hr; +} + +STRSAFEAPI StringCbCopyNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest; + size_t cchToCopy; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + cchToCopy = cbToCopy / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCopyNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToCopy,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc); + +#define StringCchCat __MINGW_NAME_AW(StringCchCat) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatWorkerA(pszDest,cchDest,pszSrc); +} + +STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatWorkerW(pszDest,cchDest,pszSrc); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc); +STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc); + +#define StringCbCat __MINGW_NAME_AW(StringCbCat) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCatA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc) { + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatWorkerA(pszDest,cbDest,pszSrc); +} + +STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc) { + size_t cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatWorkerW(pszDest,cchDest,pszSrc); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchCatEx __MINGW_NAME_AW(StringCchCatEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCatExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} + +STRSAFEAPI StringCchCatExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + size_t cbDest = cchDest*sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + +#define StringCbCatEx __MINGW_NAME_AW(StringCbCatEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCatExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchRemaining = 0; + if(cbDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCatExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + return hr; +} + +STRSAFEAPI StringCbCatExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchRemaining = 0; + + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend); +STRSAFEAPI StringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend); + +#define StringCchCatN __MINGW_NAME_AW(StringCchCatN) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCatNA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNWorkerA(pszDest,cchDest,pszSrc,cchToAppend); +} + +STRSAFEAPI StringCchCatNW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend); +STRSAFEAPI StringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend); + +#define StringCbCatN __MINGW_NAME_AW(StringCbCatN) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCatNA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend) { + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNWorkerA(pszDest,cbDest,pszSrc,cbToAppend); +} + +STRSAFEAPI StringCbCatNW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend) { + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchCatNEx __MINGW_NAME_AW(StringCchCatNEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchCatNExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags); +} + +STRSAFEAPI StringCchCatNExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringCatNExWorkerW(pszDest,cchDest,(cchDest*sizeof(wchar_t)),pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags); +} +#endif + +STRSAFEAPI StringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFEAPI StringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); + +#define StringCbCatNEx __MINGW_NAME_AW(StringCbCatNEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbCatNExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cbToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchRemaining = 0; + if(cbDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCatNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToAppend,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + return hr; +} + +STRSAFEAPI StringCbCatNExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cbToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + size_t cchRemaining = 0; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringCatNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToAppend,ppszDestEnd,&cchRemaining,dwFlags); + if((SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER) && pcbRemaining) + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList); + +#define StringCchVPrintf __MINGW_NAME_AW(StringCchVPrintf) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchVPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList); +} + +STRSAFEAPI StringCchVPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList) { + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList); + +#define StringCbVPrintf __MINGW_NAME_AW(StringCbVPrintf) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbVPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,va_list argList) { + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList); +} + +STRSAFEAPI StringCbVPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,va_list argList) { + size_t cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + return StringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...); +STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...); + +#define StringCchPrintf __MINGW_NAME_AW(StringCchPrintf) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,...) { + HRESULT hr; + va_list argList; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return hr; +} + +STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,...) { + HRESULT hr; + va_list argList; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...); +STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...); + +#define StringCbPrintf __MINGW_NAME_AW(StringCbPrintf) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbPrintfA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPCSTR pszFormat,...) { + HRESULT hr; + va_list argList; + if(cbDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList); + va_end(argList); + return hr; +} + +STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPCWSTR pszFormat,...) { + HRESULT hr; + va_list argList; + size_t cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList); + va_end(argList); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...); +STRSAFEAPI StringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...); + +#define StringCchPrintfEx __MINGW_NAME_AW(StringCchPrintfEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...) { + HRESULT hr; + va_list argList; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfExWorkerA(pszDest,cchDest,cchDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + return hr; +} + +STRSAFEAPI StringCchPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...) { + HRESULT hr; + size_t cbDest = cchDest * sizeof(wchar_t); + va_list argList; + if(cchDest > STRSAFE_MAX_CCH) return STRSAFE_E_INVALID_PARAMETER; + va_start(argList,pszFormat); + hr = StringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...); +STRSAFEAPI StringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...); + +#define StringCbPrintfEx __MINGW_NAME_AW(StringCbPrintfEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,...) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + va_list argList; + va_start(argList,pszFormat); + hr = StringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) { + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); } + } + return hr; +} - if (ppszDestEnd) *ppszDestEnd = pszDest + iResult; - - if (pcxRemaining) *pcxRemaining = STRSAFE_CCHtoCXX(cchMax - iResult); - - if (SUCCEEDED(hr)) - { - if ((dwFlags & STRSAFE_FILL_BEHIND_NULL) && ((size_t)iResult + 1 < cchMax)) - { - memset(pszDest + iResult + 1, - dwFlags & 0xff, - (cchMax - iResult - 1) * sizeof(STRSAFE_TCHAR)); - } +STRSAFEAPI StringCbPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,...) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + va_list argList; + va_start(argList,pszFormat); + hr = StringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + va_end(argList); + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) { + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); } - else - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, dwFlags & 0xff, cchMax * sizeof(STRSAFE_TCHAR)); - } - else if (dwFlags & STRSAFE_NULL_ON_FAILURE) - { - *pszDest = 0; - } + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); + +#define StringCchVPrintfEx __MINGW_NAME_AW(StringCchVPrintfEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchVPrintfExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(char); + hr = StringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + } + return hr; +} + +STRSAFEAPI StringCchVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(wchar_t); + hr = StringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList); +STRSAFEAPI StringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList); + +#define StringCbVPrintfEx __MINGW_NAME_AW(StringCbVPrintfEx) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbVPrintfExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) { + *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); } - - return hr; + } + return hr; } -STRSAFEAPI -StringCxxVPrintf( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszFormat, - va_list args) -{ - return StringCxxVPrintfEx(pszDest, cxDest, NULL, NULL, 0, pszFormat, args); +STRSAFEAPI StringCbVPrintfExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(pcbRemaining) { + *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFE_INLINE_API StringCchGetsA(STRSAFE_LPSTR pszDest,size_t cchDest); +STRSAFE_INLINE_API StringCchGetsW(STRSAFE_LPWSTR pszDest,size_t cchDest); + +#define StringCchGets __MINGW_NAME_AW(StringCchGets) + +#ifndef __CRT__NO_INLINE +STRSAFE_INLINE_API StringCchGetsA(STRSAFE_LPSTR pszDest,size_t cchDest) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(char); + hr = StringGetsExWorkerA(pszDest,cchDest,cbDest,NULL,NULL,0); + } + return hr; } -STRSAFEAPI -StringCxxPrintf( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPCTSTR pszFormat, ...) -{ - HRESULT result; - va_list args; - va_start(args, pszFormat); - result = StringCxxVPrintf(pszDest, cxDest, pszFormat, args); - va_end(args); - return result; +STRSAFE_INLINE_API StringCchGetsW(STRSAFE_LPWSTR pszDest,size_t cchDest) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(wchar_t); + hr = StringGetsExWorkerW(pszDest,cchDest,cbDest,NULL,NULL,0); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFE_INLINE_API StringCbGetsA(STRSAFE_LPSTR pszDest,size_t cbDest); +STRSAFE_INLINE_API StringCbGetsW(STRSAFE_LPWSTR pszDest,size_t cbDest); + +#define StringCbGets __MINGW_NAME_AW(StringCbGets) + +#ifndef __CRT__NO_INLINE +STRSAFE_INLINE_API StringCbGetsA(STRSAFE_LPSTR pszDest,size_t cbDest) { + HRESULT hr; + size_t cchDest; + cchDest = cbDest / sizeof(char); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringGetsExWorkerA(pszDest,cchDest,cbDest,NULL,NULL,0); + return hr; } -STRSAFEAPI -StringCxxPrintfEx( - STRSAFE_LPTSTR pszDest, - size_t cxDest, - STRSAFE_LPTSTR *ppszDestEnd, - size_t *pcbRemaining, - STRSAFE_DWORD dwFlags, - STRSAFE_LPCTSTR pszFormat, ...) -{ - HRESULT result; - va_list args; - va_start(args, pszFormat); - result = StringCxxVPrintfEx(pszDest, cxDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, args); - va_end(args); - return result; +STRSAFE_INLINE_API StringCbGetsW(STRSAFE_LPWSTR pszDest,size_t cbDest) { + HRESULT hr; + size_t cchDest; + cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringGetsExWorkerW(pszDest,cchDest,cbDest,NULL,NULL,0); + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFE_INLINE_API StringCchGetsExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); +STRSAFE_INLINE_API StringCchGetsExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags); + +#define StringCchGetsEx __MINGW_NAME_AW(StringCchGetsEx) + +#ifndef __CRT__NO_INLINE +STRSAFE_INLINE_API StringCchGetsExA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(char); + hr = StringGetsExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags); + } + return hr; } -#endif // !STRSAFE_LIB +STRSAFE_INLINE_API StringCchGetsExW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cbDest; + cbDest = cchDest*sizeof(wchar_t); + hr = StringGetsExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ -/* Functions are implemented or defined, clear #defines for next pass */ -#undef StringCxxCat -#undef StringCxxCatEx -#undef StringCxxCatN -#undef StringCxxCatNEx -#undef StringCxxCatWorker -#undef StringCxxCopy -#undef StringCxxCopyEx -#undef StringCxxCopyN -#undef StringCxxCopyNEx -#undef StringCxxGets -#undef StringCxxGetsEx -#undef StringCxxLength -#undef StringCxxPrintf -#undef StringCxxPrintfEx -#undef StringCxxVPrintf -#undef StringCxxVPrintfEx +STRSAFE_INLINE_API StringCbGetsExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); +STRSAFE_INLINE_API StringCbGetsExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags); -#undef StringCbCat -#undef StringCbCatEx -#undef StringCbCatN -#undef StringCbCatNEx -#undef StringCbCatWorker -#undef StringCbCopy -#undef StringCbCopyEx -#undef StringCbCopyN -#undef StringCbCopyNEx -#undef StringCbGets -#undef StringCbGetsEx -#undef StringCbLength -#undef StringCbPrintf -#undef StringCbPrintfEx -#undef StringCbVPrintf -#undef StringCbVPrintfEx -#undef StringCchCat -#undef StringCchCatEx -#undef StringCchCatN -#undef StringCchCatNEx -#undef StringCchCatWorker -#undef StringCchCopy -#undef StringCchCopyEx -#undef StringCchCopyN -#undef StringCchCopyNEx -#undef StringCchGets -#undef StringCchGetsEx -#undef StringCchLength -#undef StringCchPrintf -#undef StringCchPrintfEx -#undef StringCchVPrintf -#undef StringCchVPrintfEx -#undef _vsnprintfAW +#define StringCbGetsEx __MINGW_NAME_AW(StringCbGetsEx) -#undef STRSAFE_LPTSTR -#undef STRSAFE_LPCTSTR -#undef STRSAFE_TCHAR +#ifndef __CRT__NO_INLINE +STRSAFE_INLINE_API StringCbGetsExA(STRSAFE_LPSTR pszDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(char); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringGetsExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER) || (hr==STRSAFE_E_END_OF_FILE)) { + if(pcbRemaining) *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char)); + } + return hr; +} -#undef STRSAFE_CXXtoCB -#undef STRSAFE_CBtoCXX -#undef STRSAFE_CXXtoCCH -#undef STRSAFE_CCHtoCXX +STRSAFE_INLINE_API StringCbGetsExW(STRSAFE_LPWSTR pszDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcbRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr; + size_t cchDest; + size_t cchRemaining = 0; + cchDest = cbDest / sizeof(wchar_t); + if(cchDest > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringGetsExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags); + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER) || (hr==STRSAFE_E_END_OF_FILE)) { + if(pcbRemaining) *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ -#endif // defined (STRSAFE_PASS2) +STRSAFEAPI StringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength); +STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength); +#define StringCchLength __MINGW_NAME_AW(StringCchLength) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCchLengthA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength) { + HRESULT hr; + if(!psz || (cchMax > STRSAFE_MAX_CCH)) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringLengthWorkerA(psz,cchMax,pcchLength); + if(FAILED(hr) && pcchLength) { + *pcchLength = 0; + } + return hr; +} + +STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength) { + HRESULT hr; + if(!psz || (cchMax > STRSAFE_MAX_CCH)) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringLengthWorkerW(psz,cchMax,pcchLength); + if(FAILED(hr) && pcchLength) { + *pcchLength = 0; + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +STRSAFEAPI StringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength); +STRSAFEAPI StringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength); + +#define StringCbLength __MINGW_NAME_AW(StringCbLength) + +#ifndef __CRT__NO_INLINE +STRSAFEAPI StringCbLengthA(STRSAFE_LPCSTR psz,size_t cbMax,size_t *pcbLength) { + HRESULT hr; + size_t cchMax; + size_t cchLength = 0; + cchMax = cbMax / sizeof(char); + if(!psz || (cchMax > STRSAFE_MAX_CCH)) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringLengthWorkerA(psz,cchMax,&cchLength); + if(pcbLength) { + if(SUCCEEDED(hr)) { + *pcbLength = cchLength*sizeof(char); + } else { + *pcbLength = 0; + } + } + return hr; +} + +STRSAFEAPI StringCbLengthW(STRSAFE_LPCWSTR psz,size_t cbMax,size_t *pcbLength) { + HRESULT hr; + size_t cchMax; + size_t cchLength = 0; + cchMax = cbMax / sizeof(wchar_t); + if(!psz || (cchMax > STRSAFE_MAX_CCH)) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = StringLengthWorkerW(psz,cchMax,&cchLength); + if(pcbLength) { + if(SUCCEEDED(hr)) { + *pcbLength = cchLength*sizeof(wchar_t); + } else { + *pcbLength = 0; + } + } + return hr; +} + +STRSAFEAPI StringCopyWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + while(cchDest && (*pszSrc!='\0')) { + *pszDest++ = *pszSrc++; + cchDest--; + } + if(cchDest==0) { + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDest= '\0'; + } + return hr; +} + +STRSAFEAPI StringCopyWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + while(cchDest && (*pszSrc!=L'\0')) { + *pszDest++ = *pszSrc++; + cchDest--; + } + if(cchDest==0) { + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDest= L'\0'; + } + return hr; +} + +STRSAFEAPI StringCopyExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszSrc) pszSrc = ""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if(*pszSrc!='\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && (*pszSrc!='\0')) { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } else { + pszDestEnd--; + cchRemaining++; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDestEnd = '\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCopyExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszSrc) pszSrc = L""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if(*pszSrc!=L'\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && (*pszSrc!=L'\0')) { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } else { + pszDestEnd--; + cchRemaining++; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDestEnd = L'\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCopyNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchSrc) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + while(cchDest && cchSrc && (*pszSrc!='\0')) { + *pszDest++ = *pszSrc++; + cchDest--; + cchSrc--; + } + if(cchDest==0) { + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDest= '\0'; + } + return hr; +} + +STRSAFEAPI StringCopyNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + while(cchDest && cchToCopy && (*pszSrc!=L'\0')) { + *pszDest++ = *pszSrc++; + cchDest--; + cchToCopy--; + } + if(cchDest==0) { + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDest= L'\0'; + } + return hr; +} + +STRSAFEAPI StringCopyNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToCopy,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else if(cchToCopy > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszSrc) pszSrc = ""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if((cchToCopy!=0) && (*pszSrc!='\0')) { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && cchToCopy && (*pszSrc!='\0')) { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + cchToCopy--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } else { + pszDestEnd--; + cchRemaining++; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDestEnd = '\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCopyNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToCopy,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else if(cchToCopy > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszSrc) pszSrc = L""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if((cchToCopy!=0) && (*pszSrc!=L'\0')) { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining && cchToCopy && (*pszSrc!=L'\0')) { + *pszDestEnd++ = *pszSrc++; + cchRemaining--; + cchToCopy--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } else { + pszDestEnd--; + cchRemaining++; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + *pszDestEnd = L'\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCatWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc) { + HRESULT hr; + size_t cchDestLength; + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) hr = StringCopyWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc); + return hr; +} + +STRSAFEAPI StringCatWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc) { + HRESULT hr; + size_t cchDestLength; + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) hr = StringCopyWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc); + return hr; +} + +STRSAFEAPI StringCatExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cchDestLength; + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest==0) && (cbDest==0)) cchDestLength = 0; + else hr = STRSAFE_E_INVALID_PARAMETER; + } else { + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(!pszSrc) pszSrc = ""; + } else { + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + if(*pszSrc!='\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else hr = StringCopyExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & STRSAFE_NULL_ON_FAILURE) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCatExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + size_t cchDestLength; + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest==0) && (cbDest==0)) cchDestLength = 0; + else hr = STRSAFE_E_INVALID_PARAMETER; + } else { + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(!pszSrc) pszSrc = L""; + } else { + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + if(*pszSrc!=L'\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else hr = StringCopyExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & STRSAFE_NULL_ON_FAILURE) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCatNWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend) { + HRESULT hr; + size_t cchDestLength; + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) hr = StringCopyNWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend); + return hr; +} + +STRSAFEAPI StringCatNWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend) { + HRESULT hr; + size_t cchDestLength; + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) hr = StringCopyNWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend); + return hr; +} + +STRSAFEAPI StringCatNExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCSTR pszSrc,size_t cchToAppend,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestLength = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else if(cchToAppend > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest==0) && (cbDest==0)) cchDestLength = 0; + else hr = STRSAFE_E_INVALID_PARAMETER; + } else { + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(!pszSrc) pszSrc = ""; + } else { + hr = StringLengthWorkerA(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + if((cchToAppend!=0) && (*pszSrc!='\0')) { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else hr = StringCopyNExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringCatNExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPCWSTR pszSrc,size_t cchToAppend,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + size_t cchDestLength = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else if(cchToAppend > STRSAFE_MAX_CCH) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest==0) && (cbDest==0)) cchDestLength = 0; + else hr = STRSAFE_E_INVALID_PARAMETER; + } else { + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(!pszSrc) pszSrc = L""; + } else { + hr = StringLengthWorkerW(pszDest,cchDest,&cchDestLength); + if(SUCCEEDED(hr)) { + pszDestEnd = pszDest + cchDestLength; + cchRemaining = cchDest - cchDestLength; + } + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + if((cchToAppend!=0) && (*pszSrc!=L'\0')) { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else hr = StringCopyNExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringVPrintfWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,STRSAFE_LPCSTR pszFormat,va_list argList) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList); + if((iRet < 0) || (((size_t)iRet) > cchMax)) { + pszDest += cchMax; + *pszDest = '\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else if(((size_t)iRet)==cchMax) { + pszDest += cchMax; + *pszDest = '\0'; + } + } + return hr; +} + +STRSAFEAPI StringVPrintfWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,STRSAFE_LPCWSTR pszFormat,va_list argList) { + HRESULT hr = S_OK; + if(cchDest==0) hr = STRSAFE_E_INVALID_PARAMETER; + else { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList); + if((iRet < 0) || (((size_t)iRet) > cchMax)) { + pszDest += cchMax; + *pszDest = L'\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else if(((size_t)iRet)==cchMax) { + pszDest += cchMax; + *pszDest = L'\0'; + } + } + return hr; +} + +STRSAFEAPI StringVPrintfExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCSTR pszFormat,va_list argList) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszFormat) pszFormat = ""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if(*pszFormat!='\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList); + if((iRet < 0) || (((size_t)iRet) > cchMax)) { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = '\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else if(((size_t)iRet)==cchMax) { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = '\0'; + } else if(((size_t)iRet) < cchMax) { + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags,STRSAFE_LPCWSTR pszFormat,va_list argList) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + if(!pszFormat) pszFormat = L""; + } + if(SUCCEEDED(hr)) { + if(cchDest==0) { + pszDestEnd = pszDest; + cchRemaining = 0; + if(*pszFormat!=L'\0') { + if(!pszDest) hr = STRSAFE_E_INVALID_PARAMETER; + else hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } + } else { + int iRet; + size_t cchMax; + cchMax = cchDest - 1; + iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList); + if((iRet < 0) || (((size_t)iRet) > cchMax)) { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = L'\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else if(((size_t)iRet)==cchMax) { + pszDestEnd = pszDest + cchMax; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } else if(((size_t)iRet) < cchMax) { + pszDestEnd = pszDest + iRet; + cchRemaining = cchDest - iRet; + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFEAPI StringLengthWorkerA(STRSAFE_LPCSTR psz,size_t cchMax,size_t *pcchLength) { + HRESULT hr = S_OK; + size_t cchMaxPrev = cchMax; + while(cchMax && (*psz!='\0')) { + psz++; + cchMax--; + } + if(cchMax==0) hr = STRSAFE_E_INVALID_PARAMETER; + if(pcchLength) { + if(SUCCEEDED(hr)) *pcchLength = cchMaxPrev - cchMax; + else *pcchLength = 0; + } + return hr; +} + +STRSAFEAPI StringLengthWorkerW(STRSAFE_LPCWSTR psz,size_t cchMax,size_t *pcchLength) { + HRESULT hr = S_OK; + size_t cchMaxPrev = cchMax; + while(cchMax && (*psz!=L'\0')) { + psz++; + cchMax--; + } + if(cchMax==0) hr = STRSAFE_E_INVALID_PARAMETER; + if(pcchLength) { + if(SUCCEEDED(hr)) *pcchLength = cchMaxPrev - cchMax; + else *pcchLength = 0; + } + return hr; +} + +STRSAFE_INLINE_API StringGetsExWorkerA(STRSAFE_LPSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + + if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STRSAFE_E_INVALID_PARAMETER; + else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + } + if(SUCCEEDED(hr)) { + if(cchDest <= 1) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + if(cchDest==1) *pszDestEnd = '\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining > 1) { + char ch; + int i = getc(stdin); + if(i==EOF) { + if(pszDestEnd==pszDest) hr = STRSAFE_E_END_OF_FILE; + break; + } + ch = (char)i; + if(ch=='\n') break; + *pszDestEnd = ch; + pszDestEnd++; + cchRemaining--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char))); + } + } + *pszDestEnd = '\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = '\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = '\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER) || (hr==STRSAFE_E_END_OF_FILE)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} + +STRSAFE_INLINE_API StringGetsExWorkerW(STRSAFE_LPWSTR pszDest,size_t cchDest,size_t cbDest,STRSAFE_LPWSTR *ppszDestEnd,size_t *pcchRemaining,STRSAFE_DWORD dwFlags) { + HRESULT hr = S_OK; + STRSAFE_LPWSTR pszDestEnd = pszDest; + size_t cchRemaining = 0; + if(dwFlags & (~STRSAFE_VALID_FLAGS)) { + hr = STRSAFE_E_INVALID_PARAMETER; + } else { + if(dwFlags & STRSAFE_IGNORE_NULLS) { + if(!pszDest) { + if((cchDest!=0) || (cbDest!=0)) hr = STRSAFE_E_INVALID_PARAMETER; + } + } + if(SUCCEEDED(hr)) { + if(cchDest <= 1) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + if(cchDest==1) *pszDestEnd = L'\0'; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; + } else { + pszDestEnd = pszDest; + cchRemaining = cchDest; + while(cchRemaining > 1) { + wchar_t ch = getwc(stdin); + if(ch==WEOF) { + if(pszDestEnd==pszDest) hr = STRSAFE_E_END_OF_FILE; + break; + } + if(ch==L'\n') break; + *pszDestEnd = ch; + pszDestEnd++; + cchRemaining--; + } + if(cchRemaining > 0) { + if(dwFlags & STRSAFE_FILL_BEHIND_NULL) { + memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); + } + } + *pszDestEnd = L'\0'; + } + } + } + if(FAILED(hr)) { + if(pszDest) { + if(dwFlags & STRSAFE_FILL_ON_FAILURE) { + memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest); + if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + } else if(cchDest > 0) { + pszDestEnd = pszDest + cchDest - 1; + cchRemaining = 1; + *pszDestEnd = L'\0'; + } + } + if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) { + if(cchDest > 0) { + pszDestEnd = pszDest; + cchRemaining = cchDest; + *pszDestEnd = L'\0'; + } + } + } + } + if(SUCCEEDED(hr) || (hr==STRSAFE_E_INSUFFICIENT_BUFFER) || (hr==STRSAFE_E_END_OF_FILE)) { + if(ppszDestEnd) *ppszDestEnd = pszDestEnd; + if(pcchRemaining) *pcchRemaining = cchRemaining; + } + return hr; +} +#endif /* !__CRT__NO_INLINE */ + +#define StringCopyWorkerA StringCopyWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define StringCopyWorkerW StringCopyWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define StringCopyExWorkerA StringCopyExWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; +#define StringCopyExWorkerW StringCopyExWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; +#define StringCatWorkerA StringCatWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define StringCatWorkerW StringCatWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define StringCatExWorkerA StringCatExWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; +#define StringCatExWorkerW StringCatExWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; +#define StringCatNWorkerA StringCatNWorkerA_instead_use_StringCchCatNA_or_StrincCbCatNA; +#define StringCatNWorkerW StringCatNWorkerW_instead_use_StringCchCatNW_or_StringCbCatNW; +#define StringCatNExWorkerA StringCatNExWorkerA_instead_use_StringCchCatNExA_or_StringCbCatNExA; +#define StringCatNExWorkerW StringCatNExWorkerW_instead_use_StringCchCatNExW_or_StringCbCatNExW; +#define StringVPrintfWorkerA StringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define StringVPrintfWorkerW StringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define StringVPrintfExWorkerA StringVPrintfExWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; +#define StringVPrintfExWorkerW StringVPrintfExWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; +#define StringLengthWorkerA StringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA; +#define StringLengthWorkerW StringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW; +#define StringGetsExWorkerA StringGetsExWorkerA_instead_use_StringCchGetsA_or_StringCbGetsA +#define StringGetsExWorkerW StringGetsExWorkerW_instead_use_StringCchGetsW_or_StringCbGetsW + +/* Some Wine modules include us, don't specify STRSAFE_NO_DEPRECATE, and use deprecated functions */ +#ifndef STRSAFE_NO_DEPRECATE +#define STRSAFE_NO_DEPRECATE +#endif + +#ifndef STRSAFE_NO_DEPRECATE + +#undef strcpy +#define strcpy strcpy_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef wcscpy +#define wcscpy wcscpy_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef strcat +#define strcat strcat_instead_use_StringCbCatA_or_StringCchCatA; + +#undef wcscat +#define wcscat wcscat_instead_use_StringCbCatW_or_StringCchCatW; + +#undef sprintf +#define sprintf sprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA; + +#undef swprintf +#define swprintf swprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW; + +#undef vsprintf +#define vsprintf vsprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; + +#undef vswprintf +#define vswprintf vswprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; + +#undef _snprintf +#define _snprintf _snprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA; + +#undef _snwprintf +#define _snwprintf _snwprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW; + +#undef _vsnprintf +#define _vsnprintf _vsnprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; + +#undef _vsnwprintf +#define _vsnwprintf _vsnwprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; + +#undef strcpyA +#define strcpyA strcpyA_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef strcpyW +#define strcpyW strcpyW_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef lstrcpy +#define lstrcpy lstrcpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef lstrcpyA +#define lstrcpyA lstrcpyA_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef lstrcpyW +#define lstrcpyW lstrcpyW_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef StrCpy +#define StrCpy StrCpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef StrCpyA +#define StrCpyA StrCpyA_instead_use_StringCbCopyA_or_StringCchCopyA; + +#undef StrCpyW +#define StrCpyW StrCpyW_instead_use_StringCbCopyW_or_StringCchCopyW; + +#undef _tcscpy +#define _tcscpy _tcscpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef _ftcscpy +#define _ftcscpy _ftcscpy_instead_use_StringCbCopy_or_StringCchCopy; + +#undef lstrcat +#define lstrcat lstrcat_instead_use_StringCbCat_or_StringCchCat; + +#undef lstrcatA +#define lstrcatA lstrcatA_instead_use_StringCbCatA_or_StringCchCatA; + +#undef lstrcatW +#define lstrcatW lstrcatW_instead_use_StringCbCatW_or_StringCchCatW; + +#undef StrCat +#define StrCat StrCat_instead_use_StringCbCat_or_StringCchCat; + +#undef StrCatA +#define StrCatA StrCatA_instead_use_StringCbCatA_or_StringCchCatA; + +#undef StrCatW +#define StrCatW StrCatW_instead_use_StringCbCatW_or_StringCchCatW; + +#undef StrNCat +#define StrNCat StrNCat_instead_use_StringCbCatN_or_StringCchCatN; + +#undef StrNCatA +#define StrNCatA StrNCatA_instead_use_StringCbCatNA_or_StringCchCatNA; + +#undef StrNCatW +#define StrNCatW StrNCatW_instead_use_StringCbCatNW_or_StringCchCatNW; + +#undef StrCatN +#define StrCatN StrCatN_instead_use_StringCbCatN_or_StringCchCatN; + +#undef StrCatNA +#define StrCatNA StrCatNA_instead_use_StringCbCatNA_or_StringCchCatNA; + +#undef StrCatNW +#define StrCatNW StrCatNW_instead_use_StringCbCatNW_or_StringCchCatNW; + +#undef _tcscat +#define _tcscat _tcscat_instead_use_StringCbCat_or_StringCchCat; + +#undef _ftcscat +#define _ftcscat _ftcscat_instead_use_StringCbCat_or_StringCchCat; + +#undef wsprintf +#define wsprintf wsprintf_instead_use_StringCbPrintf_or_StringCchPrintf; + +#undef wsprintfA +#define wsprintfA wsprintfA_instead_use_StringCbPrintfA_or_StringCchPrintfA; + +#undef wsprintfW +#define wsprintfW wsprintfW_instead_use_StringCbPrintfW_or_StringCchPrintfW; + +#undef wvsprintf +#define wvsprintf wvsprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; + +#undef wvsprintfA +#define wvsprintfA wvsprintfA_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; + +#undef wvsprintfW +#define wvsprintfW wvsprintfW_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; + +#undef _vstprintf +#define _vstprintf _vstprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; + +#undef _vsntprintf +#define _vsntprintf _vsntprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; + +#undef _stprintf +#define _stprintf _stprintf_instead_use_StringCbPrintf_or_StringCchPrintf; + +#undef _sntprintf +#define _sntprintf _sntprintf_instead_use_StringCbPrintf_or_StringCchPrintf; + +#undef _getts +#define _getts _getts_instead_use_StringCbGets_or_StringCchGets; + +#undef gets +#define gets _gets_instead_use_StringCbGetsA_or_StringCchGetsA; + +#undef _getws +#define _getws _getws_instead_use_StringCbGetsW_or_StringCchGetsW; +#endif +#endif diff --git a/include/psdk/uxtheme.h b/include/psdk/uxtheme.h index 5cda082bd8c..ad2b3694d7e 100644 --- a/include/psdk/uxtheme.h +++ b/include/psdk/uxtheme.h @@ -96,7 +96,7 @@ HRESULT WINAPI DrawThemeText(HTHEME,HDC,int,int,LPCWSTR,int,DWORD,DWORD,const RE HRESULT WINAPI EnableThemeDialogTexture(HWND,DWORD); HRESULT WINAPI EnableTheming(BOOL); HRESULT WINAPI GetCurrentThemeName(LPWSTR,int,LPWSTR,int,LPWSTR,int); -DWORD WINAPI GetThemeAppProperties(); +DWORD WINAPI GetThemeAppProperties(void); HRESULT WINAPI GetThemeBackgroundContentRect(HTHEME,HDC,int,int,const RECT*,RECT*); HRESULT WINAPI GetThemeBackgroundExtent(HTHEME,HDC,int,int,const RECT*,RECT*); HRESULT WINAPI GetThemeBackgroundRegion(HTHEME,HDC,int,int,const RECT*,HRGN*); @@ -126,8 +126,8 @@ HRESULT WINAPI GetThemeTextExtent(HTHEME,HDC,int,int,LPCWSTR,int,DWORD,const REC HRESULT WINAPI GetThemeTextMetrics(HTHEME,HDC,int,int,TEXTMETRICW*); HTHEME WINAPI GetWindowTheme(HWND); HRESULT WINAPI HitTestThemeBackground(HTHEME,HDC,int,int,DWORD,const RECT*,HRGN,POINT,WORD*); -BOOL WINAPI IsAppThemed(); -BOOL WINAPI IsThemeActive(); +BOOL WINAPI IsAppThemed(void); +BOOL WINAPI IsThemeActive(void); BOOL WINAPI IsThemeBackgroundPartiallyTransparent(HTHEME,int,int); BOOL WINAPI IsThemeDialogTextureEnabled(HWND); BOOL WINAPI IsThemePartDefined(HTHEME,int,int); diff --git a/include/psdk/ws2tcpip.h b/include/psdk/ws2tcpip.h index d6e8620b632..a3487f33007 100644 --- a/include/psdk/ws2tcpip.h +++ b/include/psdk/ws2tcpip.h @@ -835,7 +835,7 @@ WSAImpersonateSocketPeer( WINSOCK_API_LINKAGE INT WSAAPI -WSARevertImpersonation(); +WSARevertImpersonation(VOID); #endif /* _SECURE_SOCKET_TYPES_DEFINED_ */ #endif /* (_WIN32_WINNT >= 0x0600) */ diff --git a/include/reactos/drivers/directx/dxeng.h b/include/reactos/drivers/directx/dxeng.h index dcd5520c553..c4ddf18c0c5 100644 --- a/include/reactos/drivers/directx/dxeng.h +++ b/include/reactos/drivers/directx/dxeng.h @@ -73,7 +73,7 @@ typedef enum _DXEGSHDEVDATA /************************************************************************/ /* win32k.sys internal protypes for driver functions it exports */ /************************************************************************/ -BOOLEAN NTAPI DxEngNUIsTermSrv(); +BOOLEAN NTAPI DxEngNUIsTermSrv(VOID); PDC NTAPI DxEngLockDC(HDC hDC); BOOLEAN NTAPI DxEngUnlockDC(PDC pDC); DWORD_PTR NTAPI DxEngGetHdevData(HDEV, DXEGSHDEVDATA); @@ -82,20 +82,20 @@ BOOLEAN NTAPI DxEngLockHdev(HDEV hdev); BOOLEAN NTAPI DxEngUnlockHdev(HDEV hdev); DWORD_PTR NTAPI DxEngGetDCState(HDC hDC, DWORD type); BOOLEAN NTAPI DxEngReferenceHdev(HDEV hdev); -BOOLEAN NTAPI DxEngLockShareSem(); -BOOLEAN NTAPI DxEngUnlockShareSem(); -DWORD NTAPI DxEngScreenAccessCheck(); +BOOLEAN NTAPI DxEngLockShareSem(VOID); +BOOLEAN NTAPI DxEngUnlockShareSem(VOID); +DWORD NTAPI DxEngScreenAccessCheck(VOID); BOOL NTAPI DxEngSetDCOwner(HGDIOBJ hObject, DWORD OwnerMask); /* Prototypes for the following functions are not yet finished */ -BOOLEAN NTAPI DxEngRedrawDesktop(); -ULONG NTAPI DxEngDispUniq(); -ULONG NTAPI DxEngVisRgnUniq(); +BOOLEAN NTAPI DxEngRedrawDesktop(VOID); +ULONG NTAPI DxEngDispUniq(VOID); +ULONG NTAPI DxEngVisRgnUniq(VOID); HDEV* NTAPI DxEngEnumerateHdev(HDEV *hdev); BOOL NTAPI DxEngGetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp); BOOLEAN NTAPI DxEngSetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp, BOOL Unuse); BOOLEAN NTAPI DxEngCleanDC(HDC hdc); -BOOLEAN NTAPI DxEngIncDispUniq(); +BOOLEAN NTAPI DxEngIncDispUniq(VOID); HDC NTAPI DxEngCreateMemoryDC(HDEV hDev); diff --git a/include/reactos/libs/audiosrv/audiosrv.h b/include/reactos/libs/audiosrv/audiosrv.h index 0edc7d0abc2..ccaab5b0f23 100644 --- a/include/reactos/libs/audiosrv/audiosrv.h +++ b/include/reactos/libs/audiosrv/audiosrv.h @@ -46,15 +46,15 @@ typedef struct ( (lstrlenW(str) + 1) * sizeof(WCHAR) ) BOOL -InitializeAudioDeviceListLock(); +InitializeAudioDeviceListLock(VOID); VOID -KillAudioDeviceListLock(); +KillAudioDeviceListLock(VOID); VOID -LockAudioDeviceList(); +LockAudioDeviceList(VOID); VOID -UnlockAudioDeviceList(); +UnlockAudioDeviceList(VOID); #endif diff --git a/include/reactos/libs/ppcmmu/mmuutil.h b/include/reactos/libs/ppcmmu/mmuutil.h index 9528b571fc4..955028b33d6 100644 --- a/include/reactos/libs/ppcmmu/mmuutil.h +++ b/include/reactos/libs/ppcmmu/mmuutil.h @@ -1,8 +1,8 @@ #ifndef FREELDR_MMU_H #define FREELDR_MMU_H -int GetDEC(); -int GetMSR(); +int GetDEC(void); +int GetMSR(void); int GetPhys( paddr_t addr ); int GetPhysHalf( paddr_t addr ); int GetPhysByte( paddr_t addr ); @@ -13,7 +13,7 @@ int GetSR(int n); void SetSR(int n, int val); void GetBat( int bat, int inst, int *batHi, int *batLo ); void SetBat( int bat, int inst, int batHi, int batLo ); -int GetSDR1(); +int GetSDR1(void); void SetSDR1( int newsdr ); int BatHit( int bath, int batl, int virt ); int BatTranslate( int bath, int batl, int virt ); diff --git a/include/reactos/libs/sound/mmebuddy.h b/include/reactos/libs/sound/mmebuddy.h index d1139c7d867..aadbb3ae617 100644 --- a/include/reactos/libs/sound/mmebuddy.h +++ b/include/reactos/libs/sound/mmebuddy.h @@ -382,10 +382,10 @@ typedef struct _WAVEHDR_EXTENSION */ MMRESULT -InitEntrypointMutexes(); +InitEntrypointMutexes(VOID); VOID -CleanupEntrypointMutexes(); +CleanupEntrypointMutexes(VOID); VOID AcquireEntrypointMutex( @@ -502,7 +502,7 @@ UnlistSoundDevices( IN MMDEVICE_TYPE DeviceType); VOID -UnlistAllSoundDevices(); +UnlistAllSoundDevices(VOID); MMRESULT GetSoundDevice( @@ -608,7 +608,7 @@ FreeMemory( IN PVOID Pointer); UINT -GetMemoryAllocationCount(); +GetMemoryAllocationCount(VOID); UINT GetDigitCount( diff --git a/include/reactos/libs/sound/time.h b/include/reactos/libs/sound/time.h index 56378e8680c..7308253d84f 100644 --- a/include/reactos/libs/sound/time.h +++ b/include/reactos/libs/sound/time.h @@ -16,6 +16,6 @@ VOID SleepMs(ULONG Milliseconds); ULONG -QuerySystemTimeMs(); +QuerySystemTimeMs(VOID); #endif diff --git a/include/reactos/win32k/ntuser.h b/include/reactos/win32k/ntuser.h index b0e800bacdb..484a3a4b84c 100644 --- a/include/reactos/win32k/ntuser.h +++ b/include/reactos/win32k/ntuser.h @@ -1462,7 +1462,7 @@ NtUserCreateLocalMemHandle( HWND NTAPI NtUserCreateWindowEx( - DWORD dwExStyle, // |= 0x80000000 == Ansi used to set WNDS_ANSICREATOR + DWORD dwExStyle, PLARGE_STRING plstrClassName, PLARGE_STRING plstrClsVersion, PLARGE_STRING plstrWindowName, @@ -1481,9 +1481,9 @@ NtUserCreateWindowEx( HWINSTA NTAPI NtUserCreateWindowStation( - PUNICODE_STRING lpszWindowStationName, + POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpSecurity, + DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, @@ -1631,10 +1631,10 @@ NtUserEnableScrollBar( UINT wSBflags, UINT wArrows); -DWORD +BOOL NTAPI NtUserEndDeferWindowPosEx( - DWORD Unknown0, + HDWP WinPosInfo, DWORD Unknown1); BOOL NTAPI @@ -2301,9 +2301,9 @@ NtUserOpenClipboard( HDESK NTAPI NtUserOpenDesktop( - PUNICODE_STRING lpszDesktopName, - DWORD dwFlags, - ACCESS_MASK dwDesiredAccess); + POBJECT_ATTRIBUTES ObjectAttributes, + DWORD dwFlags, + ACCESS_MASK dwDesiredAccess); HDESK NTAPI @@ -2315,7 +2315,7 @@ NtUserOpenInputDesktop( HWINSTA NTAPI NtUserOpenWindowStation( - PUNICODE_STRING lpszWindowStationName, + POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess); BOOL diff --git a/lib/drivers/oskittcp/include/oskittcp.h b/lib/drivers/oskittcp/include/oskittcp.h index 64e587b7dad..c8f6066e65b 100644 --- a/lib/drivers/oskittcp/include/oskittcp.h +++ b/lib/drivers/oskittcp/include/oskittcp.h @@ -100,8 +100,8 @@ typedef struct _OSKITTCP_EVENT_HANDLERS { extern OSKITTCP_EVENT_HANDLERS OtcpEvent; -extern void InitOskitTCP(); -extern void DeinitOskitTCP(); +extern void InitOskitTCP( void ); +extern void DeinitOskitTCP( void ); extern void TimerOskitTCP( int FastTimer, int SlowTimer ); extern void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len ); extern int OskitTCPShutdown( void *socket, int disconn_type ); diff --git a/lib/fslib/vfatlib/check/io.h b/lib/fslib/vfatlib/check/io.h index 7b23462f515..518f00d49d3 100644 --- a/lib/fslib/vfatlib/check/io.h +++ b/lib/fslib/vfatlib/check/io.h @@ -21,7 +21,7 @@ void fs_open(PUNICODE_STRING DriveRoot,int rw); /* Opens the file system PATH. If RW is zero, the file system is opened read-only, otherwise, it is opened read-write. */ -BOOLEAN fs_isdirty(); +BOOLEAN fs_isdirty(void); /* Checks if filesystem is dirty */ @@ -55,7 +55,7 @@ NTSTATUS fs_lock(BOOLEAN LockVolume); /* Lock or unlocks the volume */ -void fs_dismount(); +void fs_dismount(void); /* Dismounts the volume */ diff --git a/lib/ppcmmu/mmuobject.h b/lib/ppcmmu/mmuobject.h index 024f757e38a..92e0486b186 100644 --- a/lib/ppcmmu/mmuobject.h +++ b/lib/ppcmmu/mmuobject.h @@ -1,6 +1,6 @@ #pragma once -void initme(); +void initme(void); void mmusetramsize(paddr_t size); int mmuaddpage(ppc_map_info_t *info, int count); void mmudelpage(ppc_map_info_t *info, int count); @@ -10,5 +10,5 @@ void *allocvsid(int); void mmuallocvsid(int vsid, int mask); void freevsid(int); void mmufreevsid(int vsid, int mask); -int mmunitest(); +int mmunitest(void); void callkernel(void *fun_ptr, void *arg); diff --git a/lib/rtl/actctx.c b/lib/rtl/actctx.c index a91e1e8a7b1..cd900e1b8de 100644 --- a/lib/rtl/actctx.c +++ b/lib/rtl/actctx.c @@ -2735,7 +2735,12 @@ NTAPI RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context) { - UNIMPLEMENTED; + static int i; + + if (i == 0) + UNIMPLEMENTED; + i++; + return STATUS_NOT_IMPLEMENTED; } @@ -2743,7 +2748,12 @@ NTSTATUS NTAPI RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame) { - UNIMPLEMENTED; + static int i; + + if (i == 0) + UNIMPLEMENTED; + i++; + return STATUS_NOT_IMPLEMENTED; } diff --git a/lib/rtl/heap.c b/lib/rtl/heap.c index 110e68b0993..59e1fa7d97f 100644 --- a/lib/rtl/heap.c +++ b/lib/rtl/heap.c @@ -341,18 +341,9 @@ RtlpRemoveFreeBlock(PHEAP Heap, BOOLEAN NoFill) { SIZE_T Result, RealSize; - PLIST_ENTRY OldBlink, OldFlink; - // FIXME: Maybe use RemoveEntryList? - - /* Remove the free block */ - OldFlink = FreeEntry->FreeList.Flink; - OldBlink = FreeEntry->FreeList.Blink; - OldBlink->Flink = OldFlink; - OldFlink->Blink = OldBlink; - - /* Update the freelists bitmap */ - if ((OldFlink == OldBlink) && + /* Remove the free block and update the freelists bitmap */ + if (RemoveEntryList(&FreeEntry->FreeList) && (Dedicated || (!Dedicated && FreeEntry->Size < HEAP_FREELISTS))) { RtlpClearFreeListsBit(Heap, FreeEntry); diff --git a/lib/rtl/image.c b/lib/rtl/image.c index 3886fb5ac5e..03c402fc20c 100644 --- a/lib/rtl/image.c +++ b/lib/rtl/image.c @@ -20,15 +20,104 @@ /* FUNCTIONS *****************************************************************/ +USHORT +FORCEINLINE +ChkSum(ULONG Sum, PUSHORT Src, ULONG Len) +{ + ULONG i; + + for (i=0; i> 16); + } + + /* Apply carry one more time and clamp to the USHORT */ + return (Sum + (Sum >> 16)) & 0xFFFF; +} + BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum( IN PVOID BaseAddress, - IN ULONG NumberOfBytes, + IN ULONG ImageSize, IN ULONG FileLength) { - /* FIXME: TODO */ - return TRUE; + PIMAGE_NT_HEADERS Header; + PUSHORT Ptr; + ULONG Sum; + ULONG CalcSum; + ULONG HeaderSum; + ULONG i; + + // HACK: Ignore calls with ImageSize=0. Should be fixed by new MM. + if (ImageSize == 0) return TRUE; + + /* Get NT header to check if it's an image at all */ + Header = RtlImageNtHeader(BaseAddress); + if (!Header) return FALSE; + + /* Get checksum to match */ + HeaderSum = Header->OptionalHeader.CheckSum; + + /* Zero checksum seems to be accepted */ + if (HeaderSum == 0) return TRUE; + + /* Calculate the checksum */ + 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; + + if (CalcSum != HeaderSum) + DPRINT1("Image %p checksum mismatches! 0x%x != 0x%x, ImageSize %x, FileLen %x\n", BaseAddress, CalcSum, HeaderSum, ImageSize, FileLength); + + return (BOOLEAN)(CalcSum == HeaderSum); } /* diff --git a/lib/sdk/crt/printf/streamout.c b/lib/sdk/crt/printf/streamout.c index 8e9ce4f667a..66aae271dd5 100644 --- a/lib/sdk/crt/printf/streamout.c +++ b/lib/sdk/crt/printf/streamout.c @@ -16,13 +16,6 @@ #ifdef _UNICODE # define streamout wstreamout # define format_float format_floatw -# define _flsbuf _flswbuf -int __cdecl _flswbuf(int ch, FILE *stream); -#endif - -#ifdef _LIBCNT_ -# undef _flsbuf -# define _flsbuf(chr, stream) _TEOF #endif #define MB_CUR_MAX 10 @@ -234,25 +227,19 @@ static int streamout_char(FILE *stream, int chr) { +#if defined(_USER32_WSPRINTF) || defined(_LIBCNT_) /* Check if the buffer is full */ if (stream->_cnt < sizeof(TCHAR)) - { -#ifdef _USER32_WSPRINTF - return _TEOF; -#else - /* Strings are done now */ - if (stream->_flag & _IOSTRG) return _TEOF; - - /* Flush buffer for files */ - return _flsbuf(chr, stream) != _TEOF; -#endif - } + return 0; *(TCHAR*)stream->_ptr = chr; stream->_ptr += sizeof(TCHAR); stream->_cnt -= sizeof(TCHAR); return 1; +#else + return _fputtc((TCHAR)chr, stream) != _TEOF; +#endif } static diff --git a/lib/sdk/crt/stdio/file.c b/lib/sdk/crt/stdio/file.c index a66da9de9d4..cb5f5ae3dd8 100644 --- a/lib/sdk/crt/stdio/file.c +++ b/lib/sdk/crt/stdio/file.c @@ -2175,12 +2175,33 @@ size_t CDECL fwrite(const void *ptr, size_t size, size_t nmemb, FILE* file) /********************************************************************* * fputwc (MSVCRT.@) */ -wint_t CDECL fputwc(wint_t wc, FILE* file) +wint_t CDECL fputwc(wchar_t c, FILE* stream) { - wchar_t mwc=wc; - if (fwrite( &mwc, sizeof(mwc), 1, file) != 1) - return WEOF; - return wc; + /* If this is a real file stream (and not some temporary one for + sprintf-like functions), check whether it is opened in text mode. + In this case, we have to perform an implicit conversion to ANSI. */ + if (!(stream->_flag & _IOSTRG) && fdesc[stream->_file].wxflag & WX_TEXT) + { + /* Convert to multibyte in text mode */ + char mbc[MB_LEN_MAX]; + int mb_return; + + mb_return = wctomb(mbc, c); + + if(mb_return == -1) + return WEOF; + + /* Output all characters */ + if (fwrite(mbc, mb_return, 1, stream) != 1) + return WEOF; + } + else + { + if (fwrite(&c, sizeof(c), 1, stream) != 1) + return WEOF; + } + + return c; } /********************************************************************* diff --git a/ntoskrnl/ex/exintrin.c b/ntoskrnl/ex/exintrin.c index 0d98379b99e..df80cae1064 100644 --- a/ntoskrnl/ex/exintrin.c +++ b/ntoskrnl/ex/exintrin.c @@ -103,6 +103,7 @@ ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment) { + ULONG_PTR Last, Current = (ULONG_PTR)Address; PAGED_CODE(); /* Only probe if we have a valid length */ @@ -115,18 +116,22 @@ ProbeForRead(IN CONST VOID *Address, (Alignment == 8) || (Alignment == 16)); - /* Check for correct alignment */ - if (((ULONG_PTR)Address & (Alignment - 1)) != 0) + /* Check the alignment */ + if ((Current & (Alignment - 1)) != 0) { /* Incorrect alignment */ ExRaiseDatatypeMisalignment(); } - else if (((ULONG_PTR)Address + Length) < (ULONG_PTR)Address || - ((ULONG_PTR)Address + Length) > (ULONG_PTR)MmUserProbeAddress) + + /* Get the end address */ + Last = Current + Length - 1; + if ((Last < Current) || (Last >= (ULONG_PTR)MmUserProbeAddress)) { - /* Attempt a read */ - *(volatile CHAR* const)MmUserProbeAddress = 0; + /* Raise an access violation */ + ExRaiseAccessViolation(); } + + /* ProbeForRead doesn't check if memory pages are readable! */ } } diff --git a/ntoskrnl/ex/init.c b/ntoskrnl/ex/init.c index 3e2066dc482..302d1fff48a 100644 --- a/ntoskrnl/ex/init.c +++ b/ntoskrnl/ex/init.c @@ -12,7 +12,6 @@ #include #define NDEBUG #include -#include "ntstrsafe.h" /* Temporary hack */ BOOLEAN @@ -44,7 +43,7 @@ ULONG NtBuildNumber = VER_PRODUCTBUILD; #endif /* NT System Info */ -ULONG NtGlobalFlag; +ULONG NtGlobalFlag = 0; ULONG ExSuiteMask; /* Cm Version Info */ @@ -894,7 +893,7 @@ ExpInitializeExecutive(IN ULONG Cpu, PLDR_DATA_TABLE_ENTRY NtosEntry; PMESSAGE_RESOURCE_ENTRY MsgEntry; ANSI_STRING CsdString; - SIZE_T Remaining = 0; + size_t Remaining = 0; PCHAR RcEnd = NULL; CHAR VersionBuffer [65]; @@ -1311,6 +1310,7 @@ Phase1InitializationDiscard(IN PVOID Context) ANSI_STRING TempString; ULONG LastTzBias, Length, YearHack = 0, Disposition, MessageCode = 0; SIZE_T Size; + size_t Remaining; PRTL_USER_PROCESS_INFORMATION ProcessInfo; KEY_VALUE_PARTIAL_INFORMATION KeyPartialInfo; UNICODE_STRING KeyName, DebugString; @@ -1390,14 +1390,14 @@ Phase1InitializationDiscard(IN PVOID Context) StringBuffer = InitBuffer->VersionBuffer; BeginBuffer = StringBuffer; EndBuffer = StringBuffer; - Size = 256; + Remaining = sizeof(InitBuffer->VersionBuffer); if (CmCSDVersionString.Length) { /* Print the version string */ Status = RtlStringCbPrintfExA(StringBuffer, - 255, + Remaining, &EndBuffer, - &Size, + &Remaining, 0, ": %wZ", &CmCSDVersionString); @@ -1410,16 +1410,17 @@ Phase1InitializationDiscard(IN PVOID Context) else { /* No version */ - Size = 255; + *EndBuffer = ANSI_NULL; /* Null-terminate the string */ } - /* Null-terminate the string */ - *EndBuffer++ = ANSI_NULL; + /* Skip over the null-terminator to start a new string */ + ++EndBuffer; + --Remaining; /* Build the version number */ StringBuffer = InitBuffer->VersionNumber; Status = RtlStringCbPrintfA(StringBuffer, - 24, + sizeof(InitBuffer->VersionNumber), "%u.%u", VER_PRODUCTMAJORVERSION, VER_PRODUCTMINORVERSION); @@ -1434,7 +1435,7 @@ Phase1InitializationDiscard(IN PVOID Context) { /* Create the banner message */ Status = RtlStringCbPrintfA(EndBuffer, - Size, + Remaining, (PCHAR)MsgEntry->Text, StringBuffer, NtBuildNumber & 0xFFFF, @@ -1448,7 +1449,7 @@ Phase1InitializationDiscard(IN PVOID Context) else { /* Use hard-coded banner message */ - Status = RtlStringCbCopyA(EndBuffer, Size, "REACTOS (R)\n"); + Status = RtlStringCbCopyA(EndBuffer, Remaining, "REACTOS (R)\n"); if (!NT_SUCCESS(Status)) { /* Bugcheck */ @@ -1548,7 +1549,7 @@ Phase1InitializationDiscard(IN PVOID Context) /* Create the string */ StringBuffer = InitBuffer->VersionBuffer; Status = RtlStringCbPrintfA(StringBuffer, - 256, + sizeof(InitBuffer->VersionBuffer), NT_SUCCESS(MsgStatus) ? (PCHAR)MsgEntry->Text : "%u System Processor [%u MB Memory] %Z\n", diff --git a/ntoskrnl/ex/win32k.c b/ntoskrnl/ex/win32k.c index ef914065e86..9cd929996c9 100644 --- a/ntoskrnl/ex/win32k.c +++ b/ntoskrnl/ex/win32k.c @@ -37,10 +37,46 @@ GENERIC_MAPPING ExpDesktopMapping = PKWIN32_PARSEMETHOD_CALLOUT ExpWindowStationObjectParse = NULL; PKWIN32_DELETEMETHOD_CALLOUT ExpWindowStationObjectDelete = NULL; +PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpWindowStationObjectOkToClose = NULL; +PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpDesktopObjectOkToClose = NULL; PKWIN32_DELETEMETHOD_CALLOUT ExpDesktopObjectDelete = NULL; /* FUNCTIONS ****************************************************************/ +NTSTATUS +NTAPI +ExpDesktopOkToClose( IN PEPROCESS Process OPTIONAL, + IN PVOID Object, + IN HANDLE Handle, + IN KPROCESSOR_MODE AccessMode) +{ + WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters; + + Parameters.Process = Process; + Parameters.Object = Object; + Parameters.Handle = Handle; + Parameters.PreviousMode = AccessMode; + + return ExpDesktopObjectOkToClose(&Parameters); +} + +NTSTATUS +NTAPI +ExpWindowStationOkToClose( IN PEPROCESS Process OPTIONAL, + IN PVOID Object, + IN HANDLE Handle, + IN KPROCESSOR_MODE AccessMode) +{ + WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters; + + Parameters.Process = Process; + Parameters.Object = Object; + Parameters.Handle = Handle; + Parameters.PreviousMode = AccessMode; + + return ExpWindowStationObjectOkToClose(&Parameters); +} + VOID NTAPI ExpWinStaObjectDelete(PVOID DeletedObject) @@ -114,6 +150,7 @@ ExpWin32kInit(VOID) ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.DeleteProcedure = ExpWinStaObjectDelete; ObjectTypeInitializer.ParseProcedure = ExpWinStaObjectParse; + ObjectTypeInitializer.OkayToCloseProcedure = ExpWindowStationOkToClose; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, @@ -124,6 +161,7 @@ ExpWin32kInit(VOID) ObjectTypeInitializer.GenericMapping = ExpDesktopMapping; ObjectTypeInitializer.DeleteProcedure = ExpDesktopDelete; ObjectTypeInitializer.ParseProcedure = NULL; + ObjectTypeInitializer.OkayToCloseProcedure = ExpDesktopOkToClose; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, diff --git a/ntoskrnl/fstub/translate.c b/ntoskrnl/fstub/translate.c index b9d37d266cd..839e6f01488 100644 --- a/ntoskrnl/fstub/translate.c +++ b/ntoskrnl/fstub/translate.c @@ -12,8 +12,6 @@ #define NDEBUG #include -#define HAL_IRQ_TRANSLATOR_VERSION 0x0 - /* PRIVATE FUNCTIONS *********************************************************/ /* diff --git a/ntoskrnl/inbv/logo/1.bmp b/ntoskrnl/inbv/logo/1.bmp index d13c48d16c0..05b139a2fe6 100644 Binary files a/ntoskrnl/inbv/logo/1.bmp and b/ntoskrnl/inbv/logo/1.bmp differ diff --git a/ntoskrnl/include/internal/amd64/ke.h b/ntoskrnl/include/internal/amd64/ke.h index ffb3f15c4b6..bbad6b89771 100644 --- a/ntoskrnl/include/internal/amd64/ke.h +++ b/ntoskrnl/include/internal/amd64/ke.h @@ -226,30 +226,30 @@ VOID FASTCALL KiInitializeTss(IN PKTSS Tss, IN UINT64 Stack); -VOID KiDivideErrorFault(); -VOID KiDebugTrapOrFault(); -VOID KiNmiInterrupt(); -VOID KiBreakpointTrap(); -VOID KiOverflowTrap(); -VOID KiBoundFault(); -VOID KiInvalidOpcodeFault(); -VOID KiNpxNotAvailableFault(); -VOID KiDoubleFaultAbort(); -VOID KiNpxSegmentOverrunAbort(); -VOID KiInvalidTssFault(); -VOID KiSegmentNotPresentFault(); -VOID KiStackFault(); -VOID KiGeneralProtectionFault(); -VOID KiPageFault(); -VOID KiFloatingErrorFault(); -VOID KiAlignmentFault(); -VOID KiMcheckAbort(); -VOID KiXmmException(); -VOID KiApcInterrupt(); -VOID KiRaiseAssertion(); -VOID KiDebugServiceTrap(); -VOID KiDpcInterrupt(); -VOID KiIpiInterrupt(); +VOID KiDivideErrorFault(VOID); +VOID KiDebugTrapOrFault(VOID); +VOID KiNmiInterrupt(VOID); +VOID KiBreakpointTrap(VOID); +VOID KiOverflowTrap(VOID); +VOID KiBoundFault(VOID); +VOID KiInvalidOpcodeFault(VOID); +VOID KiNpxNotAvailableFault(VOID); +VOID KiDoubleFaultAbort(VOID); +VOID KiNpxSegmentOverrunAbort(VOID); +VOID KiInvalidTssFault(VOID); +VOID KiSegmentNotPresentFault(VOID); +VOID KiStackFault(VOID); +VOID KiGeneralProtectionFault(VOID); +VOID KiPageFault(VOID); +VOID KiFloatingErrorFault(VOID); +VOID KiAlignmentFault(VOID); +VOID KiMcheckAbort(VOID); +VOID KiXmmException(VOID); +VOID KiApcInterrupt(VOID); +VOID KiRaiseAssertion(VOID); +VOID KiDebugServiceTrap(VOID); +VOID KiDpcInterrupt(VOID); +VOID KiIpiInterrupt(VOID); VOID KiGdtPrepareForApplicationProcessorInit(ULONG Id); @@ -284,7 +284,7 @@ KiGetFeatureBits(VOID); VOID NTAPI -KiInitializeCpuFeatures(); +KiInitializeCpuFeatures(VOID); ULONG KeAllocateGdtSelector(ULONG Desc[2]); VOID KeFreeGdtSelector(ULONG Entry); diff --git a/ntoskrnl/include/internal/kd.h b/ntoskrnl/include/internal/kd.h index 53ee9b0f4b2..5bb1060b548 100644 --- a/ntoskrnl/include/internal/kd.h +++ b/ntoskrnl/include/internal/kd.h @@ -245,7 +245,7 @@ KdpSafeWriteMemory( VOID NTAPI -KdpEnableSafeMem(); +KdpEnableSafeMem(VOID); /* KD GLOBALS ***************************************************************/ diff --git a/ntoskrnl/include/ntoskrnl.h b/ntoskrnl/include/ntoskrnl.h index 4261d020544..40c03b89d1d 100644 --- a/ntoskrnl/include/ntoskrnl.h +++ b/ntoskrnl/include/ntoskrnl.h @@ -36,6 +36,7 @@ #undef TEXT #define TEXT(s) L##s #include +#include /* FIXME: Temporary until Winldr is used */ #include diff --git a/ntoskrnl/kdbg/kdb.h b/ntoskrnl/kdbg/kdb.h index d77cdb0aa88..1872377e96a 100644 --- a/ntoskrnl/kdbg/kdb.h +++ b/ntoskrnl/kdbg/kdb.h @@ -96,7 +96,7 @@ KdbpStackSwitchAndCall( extern PCHAR KdbInitFileBuffer; VOID -KdbpCliInit(); +KdbpCliInit(VOID); VOID KdbpCliMainLoop( @@ -107,7 +107,7 @@ KdbpCliModuleLoaded( IN PUNICODE_STRING Name); VOID -KdbpCliInterpretInitFile(); +KdbpCliInterpretInitFile(VOID); VOID KdbpPrint( @@ -260,6 +260,6 @@ DbgEnableFile(PCH Filename); VOID DbgDisableFile(PCH Filename); VOID -KbdDisableMouse(); +KbdDisableMouse(VOID); VOID -KbdEnableMouse(); +KbdEnableMouse(VOID); diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c index a0d5135f929..a45009cf7c1 100644 --- a/ntoskrnl/kdbg/kdb_cli.c +++ b/ntoskrnl/kdbg/kdb_cli.c @@ -2490,14 +2490,12 @@ KdbpReadCommand( */ if (Buffer == Orig) { - strncpy(Buffer, LastCommand, Size); - Buffer[Size - 1] = '\0'; + RtlStringCbCopyA(Buffer, Size, LastCommand); } else { *Buffer = '\0'; - strncpy(LastCommand, Orig, sizeof (LastCommand)); - LastCommand[sizeof (LastCommand) - 1] = '\0'; + RtlStringCbCopyA(LastCommand, sizeof(LastCommand), Orig); } return; @@ -2614,8 +2612,7 @@ KdbpDoCommand( static PCH Argv[256]; static CHAR OrigCommand[1024]; - strncpy(OrigCommand, Command, sizeof(OrigCommand) - 1); - OrigCommand[sizeof(OrigCommand) - 1] = '\0'; + RtlStringCbCopyA(OrigCommand, sizeof(OrigCommand), Command); Argc = 0; p = Command; diff --git a/ntoskrnl/ke/freeldr.c b/ntoskrnl/ke/freeldr.c index 9dfc8eb9e07..2e0d17ce178 100644 --- a/ntoskrnl/ke/freeldr.c +++ b/ntoskrnl/ke/freeldr.c @@ -947,6 +947,8 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, WCHAR PathSetup[] = L"\\SystemRoot\\"; CHAR DriverNameLow[256]; ULONG Base; + size_t Remaining; + WCHAR *StringEnd; #if defined(_PPC_) ULONG KernelBase = RosLoaderBlock->ModsAddr[0].ModStart; #endif @@ -1123,7 +1125,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, /* Construct a correct full name */ BldrModuleStringsFull[i][0] = 0; - LdrEntry->FullDllName.MaximumLength = 260 * sizeof(WCHAR); + LdrEntry->FullDllName.MaximumLength = sizeof(BldrModuleStringsFull[i]); LdrEntry->FullDllName.Length = 0; LdrEntry->FullDllName.Buffer = BldrModuleStringsFull[i]; @@ -1256,25 +1258,26 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, /* Find the first \, separating the ARC path from NT path */ BootPath = strchr(CommandLine, '\\'); *BootPath = ANSI_NULL; - strncpy(BldrArcBootPath, CommandLine, 63); + RtlStringCbCopyA(BldrArcBootPath, sizeof(BldrArcBootPath), CommandLine); LoaderBlock->ArcBootDeviceName = BldrArcBootPath; /* The rest of the string is the NT path */ HalPath = strchr(BootPath + 1, ' '); *HalPath = ANSI_NULL; - BldrNtBootPath[0] = '\\'; - strncat(BldrNtBootPath, BootPath + 1, 61); - strcat(BldrNtBootPath,"\\"); + Remaining = sizeof(BldrNtBootPath); + RtlStringCbCopyExA(BldrNtBootPath, Remaining, "\\", &StringEnd, &Remaining, 0); + RtlStringCbCopyExA(StringEnd, Remaining, BootPath + 1, &StringEnd, &Remaining, 0); + RtlStringCbCopyA(StringEnd, Remaining, "\\"); LoaderBlock->NtBootPathName = BldrNtBootPath; /* Set the HAL paths */ - strncpy(BldrArcHalPath, BldrArcBootPath, 63); + RtlStringCbCopyA(BldrArcHalPath, sizeof(BldrArcHalPath), BldrArcBootPath); LoaderBlock->ArcHalDeviceName = BldrArcHalPath; strcpy(BldrNtHalPath, "\\"); LoaderBlock->NtHalPathName = BldrNtHalPath; /* Use this new command line */ - strncpy(LoaderBlock->LoadOptions, HalPath + 2, 255); + RtlStringCbCopyA(LoaderBlock->LoadOptions, 255, HalPath + 2); /* Parse it and change every slash to a space */ BootPath = LoaderBlock->LoadOptions; diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c index 38539b11e70..693701b13af 100644 --- a/ntoskrnl/ke/i386/cpu.c +++ b/ntoskrnl/ke/i386/cpu.c @@ -303,17 +303,10 @@ KiGetFeatureBits(VOID) /* Remove support for correct PTE support. */ FeatureBits &= ~KF_WORKING_PTE; } - - /* Virtualbox claims to have no SYSENTER support, - * which is false for processors >= Pentium Pro */ - if(Prcb->CpuType >= 6) - { - Reg[3] |= 0x800; - } - /* Check if the CPU is too old to support SYSENTER, - * See Intel CPUID instruction manual for details*/ - if ((Reg[0] & 0x0FFF3FFF) < 0x00000633) + /* Check if the CPU is too old to support SYSENTER */ + if ((Prcb->CpuType < 6) || + ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303))) { /* Disable it */ Reg[3] &= ~0x800; diff --git a/ntoskrnl/mm/ARM3/sysldr.c b/ntoskrnl/mm/ARM3/sysldr.c index 22d0792cc97..443a33d5e63 100644 --- a/ntoskrnl/mm/ARM3/sysldr.c +++ b/ntoskrnl/mm/ARM3/sysldr.c @@ -710,9 +710,9 @@ MiSnapThunk(IN PVOID DllBase, NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData; /* Copy the procedure name */ - strncpy(*MissingApi, - (PCHAR)&NameImport->Name[0], - MAXIMUM_FILENAME_LENGTH - 1); + RtlStringCbCopyA(*MissingApi, + MAXIMUM_FILENAME_LENGTH, + (PCHAR)&NameImport->Name[0]); /* Setup name tables */ DPRINT("Import name: %s\n", NameImport->Name); @@ -3000,8 +3000,8 @@ Quickie: /* If we have a file handle, close it */ if (FileHandle) ZwClose(FileHandle); - /* Check if we had a prefix */ - if (NamePrefix) ExFreePool(PrefixName.Buffer); + /* Check if we had a prefix (not supported yet - PrefixName == *FileName now) */ + /* if (NamePrefix) ExFreePool(PrefixName.Buffer); */ /* Free the name buffer and return status */ ExFreePoolWithTag(Buffer, TAG_LDR_WSTR); diff --git a/ntoskrnl/ob/obhandle.c b/ntoskrnl/ob/obhandle.c index 20d15651d4c..e19d020aa30 100644 --- a/ntoskrnl/ob/obhandle.c +++ b/ntoskrnl/ob/obhandle.c @@ -1752,7 +1752,6 @@ ObpCloseHandle(IN HANDLE Handle, /* Detach and return success */ if (AttachedToProcess) KeUnstackDetachProcess(&ApcState); - Status = STATUS_SUCCESS; } else { diff --git a/ntoskrnl/ps/win32.c b/ntoskrnl/ps/win32.c index 3a5c2c5b900..19dd4e9c43d 100644 --- a/ntoskrnl/ps/win32.c +++ b/ntoskrnl/ps/win32.c @@ -20,6 +20,8 @@ PKWIN32_THREAD_CALLOUT PspW32ThreadCallout = NULL; PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch = NULL; extern PKWIN32_PARSEMETHOD_CALLOUT ExpWindowStationObjectParse; extern PKWIN32_DELETEMETHOD_CALLOUT ExpWindowStationObjectDelete; +extern PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpWindowStationObjectOkToClose; +extern PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpDesktopObjectOkToClose; extern PKWIN32_DELETEMETHOD_CALLOUT ExpDesktopObjectDelete; extern PKWIN32_POWEREVENT_CALLOUT PopEventCallout; @@ -116,6 +118,8 @@ PsEstablishWin32Callouts(IN PWIN32_CALLOUTS_FPNS CalloutData) PspW32ThreadCallout = CalloutData->ThreadCallout; ExpWindowStationObjectParse = CalloutData->WindowStationParseProcedure; ExpWindowStationObjectDelete = CalloutData->WindowStationDeleteProcedure; + ExpWindowStationObjectOkToClose = CalloutData->WindowStationOkToCloseProcedure; + ExpDesktopObjectOkToClose = CalloutData->DesktopOkToCloseProcedure; ExpDesktopObjectDelete = CalloutData->DesktopDeleteProcedure; PopEventCallout = CalloutData->PowerEventCallout; KeGdiFlushUserBatch = CalloutData->BatchFlushRoutine; diff --git a/subsystems/win32/csrss/win32csr/desktopbg.c b/subsystems/win32/csrss/win32csr/desktopbg.c index 2c158c57e58..3482cd9dbd6 100644 --- a/subsystems/win32/csrss/win32csr/desktopbg.c +++ b/subsystems/win32/csrss/win32csr/desktopbg.c @@ -136,7 +136,7 @@ DtbgInit(VOID) * Create the desktop window class */ Class.cbSize = sizeof(WNDCLASSEXW); - Class.style = CS_GLOBALCLASS; + Class.style = 0; // Local Class Class.lpfnWndProc = DtbgWindowProc; Class.cbClsExtra = 0; Class.cbWndExtra = 0; diff --git a/subsystems/win32/win32k/eng/device.c b/subsystems/win32/win32k/eng/device.c index 3e6759499e0..802bcf50e4f 100644 --- a/subsystems/win32/win32k/eng/device.c +++ b/subsystems/win32/win32k/eng/device.c @@ -84,12 +84,13 @@ EngpRegisterGraphicsDevice( pGraphicsDevice->FileObject = pFileObject; /* Copy device name */ - wcsncpy(pGraphicsDevice->szNtDeviceName, - pustrDeviceName->Buffer, - sizeof(pGraphicsDevice->szNtDeviceName) / sizeof(WCHAR)); + RtlStringCbCopyNW(pGraphicsDevice->szNtDeviceName, + sizeof(pGraphicsDevice->szNtDeviceName), + pustrDeviceName->Buffer, + pustrDeviceName->Length); /* Create a win device name (FIXME: virtual devices!) */ - swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (CHAR)giDevNum); + swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (int)giDevNum); /* Allocate a buffer for the strings */ cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR); @@ -98,6 +99,8 @@ EngpRegisterGraphicsDevice( { DPRINT1("Could not allocate string buffer\n"); ASSERT(FALSE); // FIXME + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); + return NULL; } /* Copy display driver names */ @@ -160,7 +163,7 @@ EngpRegisterGraphicsDevice( if (!pGraphicsDevice->pdevmodeInfo || cModes == 0) { DPRINT1("No devmodes\n"); - ExFreePool(pGraphicsDevice); + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } @@ -172,7 +175,7 @@ EngpRegisterGraphicsDevice( if (!pGraphicsDevice->pDevModeList) { DPRINT1("No devmode list\n"); - ExFreePool(pGraphicsDevice); + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } diff --git a/subsystems/win32/win32k/eng/ldevobj.c b/subsystems/win32/win32k/eng/ldevobj.c index a1c75937333..9f7c1c989fd 100644 --- a/subsystems/win32/win32k/eng/ldevobj.c +++ b/subsystems/win32/win32k/eng/ldevobj.c @@ -103,7 +103,7 @@ LDEVOBJ_vFreeLDEV(PLDEVOBJ pldev) ASSERT(pldev && pldev->pGdiDriverInfo == NULL); /* Free the memory */ - ExFreePoolWithTag(pldev, TAG_LDEV); + ExFreePoolWithTag(pldev, GDITAG_LDEV); } PDEVMODEINFO @@ -145,7 +145,7 @@ LDEVOBJ_pdmiGetModes( { /* Could not get modes */ DPRINT1("returned size %ld(%ld)\n", cbSize, pdminfo->cbdevmode); - ExFreePool(pdminfo); + ExFreePoolWithTag(pdminfo, GDITAG_DEVMODE); pdminfo = NULL; } @@ -192,7 +192,7 @@ LDEVOBJ_bLoadImage( pstrPathName->Buffer, Status); /* Free the allocated memory */ - ExFreePoolWithTag(pDriverInfo, TAG_LDEV); + ExFreePoolWithTag(pDriverInfo, GDITAG_LDEV); return FALSE; } diff --git a/subsystems/win32/win32k/include/callback.h b/subsystems/win32/win32k/include/callback.h index 0b978a67e49..0494b99f36f 100644 --- a/subsystems/win32/win32k/include/callback.h +++ b/subsystems/win32/win32k/include/callback.h @@ -20,7 +20,7 @@ co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback, HMENU APIENTRY -co_IntLoadSysMenuTemplate(); +co_IntLoadSysMenuTemplate(VOID); BOOL APIENTRY co_IntLoadDefaultCursors(VOID); diff --git a/subsystems/win32/win32k/include/cursoricon.h b/subsystems/win32/win32k/include/cursoricon.h index 1a66dbc5408..0c0059a933d 100644 --- a/subsystems/win32/win32k/include/cursoricon.h +++ b/subsystems/win32/win32k/include/cursoricon.h @@ -61,8 +61,8 @@ typedef struct _SYSTEM_CURSORINFO BOOL ScreenSaverRunning; } SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO; -BOOL InitCursorImpl(); -PCURICON_OBJECT IntCreateCurIconHandle(); +BOOL InitCursorImpl(VOID); +PCURICON_OBJECT IntCreateCurIconHandle(VOID); VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process); BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, @@ -73,7 +73,7 @@ BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg); int UserShowCursor(BOOL bShow); -PSYSTEM_CURSORINFO IntGetSysCursorInfo(); +PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID); #define IntReleaseCurIconObject(CurIconObj) \ UserDereferenceObject(CurIconObj) diff --git a/subsystems/win32/win32k/include/dc.h b/subsystems/win32/win32k/include/dc.h index 1e85e364d35..caf112b827e 100644 --- a/subsystems/win32/win32k/include/dc.h +++ b/subsystems/win32/win32k/include/dc.h @@ -156,9 +156,9 @@ typedef struct _DC extern PDC defaultDCstate; -INIT_FUNCTION NTSTATUS NTAPI InitDcImpl(); +INIT_FUNCTION NTSTATUS NTAPI InitDcImpl(VOID); PPDEVOBJ FASTCALL IntEnumHDev(VOID); -PDC NTAPI DC_AllocDcWithHandle(); +PDC NTAPI DC_AllocDcWithHandle(VOID); VOID FASTCALL DC_InitDC(HDC DCToInit); VOID FASTCALL DC_AllocateDcAttr(HDC); VOID FASTCALL DC_FreeDcAttr(HDC); diff --git a/subsystems/win32/win32k/include/desktop.h b/subsystems/win32/win32k/include/desktop.h index 12911139223..82607df23dc 100644 --- a/subsystems/win32/win32k/include/desktop.h +++ b/subsystems/win32/win32k/include/desktop.h @@ -69,6 +69,9 @@ IntDesktopObjectParse(IN PVOID ParseObject, VOID APIENTRY IntDesktopObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters); +NTSTATUS NTAPI +IntDesktopOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters); + LRESULT CALLBACK IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); @@ -102,7 +105,7 @@ IntHideDesktop(PDESKTOP Desktop); HDESK FASTCALL IntGetDesktopObjectHandle(PDESKTOP DesktopObject); -BOOL IntSetThreadDesktop(IN PDESKTOP DesktopObject, +BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure); NTSTATUS FASTCALL diff --git a/subsystems/win32/win32k/include/device.h b/subsystems/win32/win32k/include/device.h index 2ad19b278a7..dedae46c427 100644 --- a/subsystems/win32/win32k/include/device.h +++ b/subsystems/win32/win32k/include/device.h @@ -33,7 +33,7 @@ EngpRegisterGraphicsDevice( INIT_FUNCTION NTSTATUS NTAPI -InitDeviceImpl(); +InitDeviceImpl(VOID); BOOL FASTCALL diff --git a/subsystems/win32/win32k/include/gdidebug.h b/subsystems/win32/win32k/include/gdidebug.h index 944e546c118..ffea26dcdc9 100644 --- a/subsystems/win32/win32k/include/gdidebug.h +++ b/subsystems/win32/win32k/include/gdidebug.h @@ -19,8 +19,8 @@ enum _DEBUGCHANNELS void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable); ULONG CaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture); -BOOL GdiDbgHTIntegrityCheck(); -void GdiDbgDumpLockedHandles(); +BOOL GdiDbgHTIntegrityCheck(VOID); +void GdiDbgDumpLockedHandles(VOID); #define DBGENABLE(ch) gulDebugChannels |= (ch); #define DBGDISABLE(ch) gulDebugChannels &= ~(ch); diff --git a/subsystems/win32/win32k/include/gdiobj.h b/subsystems/win32/win32k/include/gdiobj.h index 3f581bca22f..e29077c2f42 100644 --- a/subsystems/win32/win32k/include/gdiobj.h +++ b/subsystems/win32/win32k/include/gdiobj.h @@ -83,7 +83,7 @@ PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCES INIT_FUNCTION NTSTATUS NTAPI -InitGdiHandleTable(); +InitGdiHandleTable(VOID); #define GDIOBJ_GetObjectType(Handle) \ GDI_HANDLE_GET_TYPE(Handle) diff --git a/subsystems/win32/win32k/include/input.h b/subsystems/win32/win32k/include/input.h index 60056046d1a..167c2af5aad 100644 --- a/subsystems/win32/win32k/include/input.h +++ b/subsystems/win32/win32k/include/input.h @@ -45,7 +45,7 @@ BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt); BOOL FASTCALL IntMouseInput(MOUSEINPUT *mi); BOOL FASTCALL IntKeyboardInput(KEYBDINPUT *ki); -BOOL UserInitDefaultKeyboardLayout(); +BOOL UserInitDefaultKeyboardLayout(VOID); PKBL UserHklToKbl(HKL hKl); BOOL FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL); BOOL FASTCALL IntConnectThreadInput(PTHREADINFO,PTHREADINFO*,PUSER_MESSAGE_QUEUE*); diff --git a/subsystems/win32/win32k/include/intgdi.h b/subsystems/win32/win32k/include/intgdi.h index 5e7ca97d68f..c88545cfa4f 100644 --- a/subsystems/win32/win32k/include/intgdi.h +++ b/subsystems/win32/win32k/include/intgdi.h @@ -156,8 +156,8 @@ IntGdiCombineTransform(LPXFORM XFormResult, /* Stock objects */ -BOOL FASTCALL -IntSetSysColors(UINT nColors, INT *Elements, COLORREF *Colors); +VOID FASTCALL +IntSetSysColors(UINT nColors, CONST INT *Elements, CONST COLORREF *Colors); HGDIOBJ FASTCALL IntGetSysColorBrush(INT Object); diff --git a/subsystems/win32/win32k/include/ldevobj.h b/subsystems/win32/win32k/include/ldevobj.h index 6bae83ab8a0..633f5feed68 100644 --- a/subsystems/win32/win32k/include/ldevobj.h +++ b/subsystems/win32/win32k/include/ldevobj.h @@ -5,9 +5,6 @@ #endif extern IMAGE_DOS_HEADER __ImageBase; - -#define TAG_LDEV 'Gldv' - #define GDI_ENGINE_VERSION DDI_DRIVER_VERSION_NT5_01 typedef enum @@ -66,7 +63,7 @@ LDEVOBJ_pdmiGetModes( INIT_FUNCTION NTSTATUS NTAPI -InitLDEVImpl(); +InitLDEVImpl(VOID); PLDEVOBJ APIENTRY diff --git a/subsystems/win32/win32k/include/monitor.h b/subsystems/win32/win32k/include/monitor.h index 729f28d0a91..280864fb7cb 100644 --- a/subsystems/win32/win32k/include/monitor.h +++ b/subsystems/win32/win32k/include/monitor.h @@ -35,8 +35,8 @@ typedef struct _MONITOR INIT_FUNCTION NTSTATUS NTAPI -InitMonitorImpl(); -NTSTATUS CleanupMonitorImpl(); +InitMonitorImpl(VOID); +NTSTATUS CleanupMonitorImpl(VOID); NTSTATUS IntAttachMonitor(PDEVOBJ *pGdiDevice, ULONG DisplayNumber); NTSTATUS IntDetachMonitor(PDEVOBJ *pGdiDevice); diff --git a/subsystems/win32/win32k/include/msgqueue.h b/subsystems/win32/win32k/include/msgqueue.h index 84d803bb7fb..f078a16f23d 100644 --- a/subsystems/win32/win32k/include/msgqueue.h +++ b/subsystems/win32/win32k/include/msgqueue.h @@ -227,8 +227,8 @@ MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd); __inline BOOL MsqIsSignaled( PUSER_MESSAGE_QUEUE queue ); __inline VOID MsqSetQueueBits( PUSER_MESSAGE_QUEUE queue, WORD bits ); -BOOL APIENTRY IntInitMessagePumpHook(); -BOOL APIENTRY IntUninitMessagePumpHook(); +BOOL APIENTRY IntInitMessagePumpHook(VOID); +BOOL APIENTRY IntUninitMessagePumpHook(VOID); #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)) LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam); diff --git a/subsystems/win32/win32k/include/palette.h b/subsystems/win32/win32k/include/palette.h index d18edee49df..10d6dffbae6 100644 --- a/subsystems/win32/win32k/include/palette.h +++ b/subsystems/win32/win32k/include/palette.h @@ -74,7 +74,7 @@ HPALETTE FASTCALL PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, GDIOBJ_ShareUnlockObjByPtr(&ppal->BaseObject) BOOL INTERNAL_CALL PALETTE_Cleanup(PVOID ObjectBody); -INIT_FUNCTION NTSTATUS NTAPI InitPaletteImpl(); +INIT_FUNCTION NTSTATUS NTAPI InitPaletteImpl(VOID); VOID FASTCALL PALETTE_ValidateFlags (PALETTEENTRY* lpPalE, INT size); INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color); diff --git a/subsystems/win32/win32k/include/pdevobj.h b/subsystems/win32/win32k/include/pdevobj.h index bece851460a..34297add5f4 100644 --- a/subsystems/win32/win32k/include/pdevobj.h +++ b/subsystems/win32/win32k/include/pdevobj.h @@ -177,7 +177,7 @@ PDEVOBJ_vGetDeviceCaps( INIT_FUNCTION NTSTATUS NTAPI -InitPDEVImpl(); +InitPDEVImpl(VOID); PSIZEL FASTCALL diff --git a/subsystems/win32/win32k/include/region.h b/subsystems/win32/win32k/include/region.h index 5ad6e2cb52f..a7e531dff8b 100644 --- a/subsystems/win32/win32k/include/region.h +++ b/subsystems/win32/win32k/include/region.h @@ -44,6 +44,7 @@ INT APIENTRY IntGdiGetRgnBox(HRGN, RECTL*); BOOL FASTCALL IntGdiPaintRgn(PDC, HRGN ); HRGN FASTCALL IntCreatePolyPolygonRgn(PPOINT, PULONG, INT, INT); INT FASTCALL IntGdiOffsetRgn(PROSRGNDATA,INT,INT); +BOOL FASTCALL IntRectInRegion(HRGN,LPRECTL); INT FASTCALL IntGdiCombineRgn(PROSRGNDATA, PROSRGNDATA, PROSRGNDATA, INT); INT FASTCALL REGION_Complexity(PROSRGNDATA); diff --git a/subsystems/win32/win32k/include/win32.h b/subsystems/win32/win32k/include/win32.h index 521ef7a407c..2e43ec1517f 100644 --- a/subsystems/win32/win32k/include/win32.h +++ b/subsystems/win32/win32k/include/win32.h @@ -166,6 +166,7 @@ typedef struct _PROCESSINFO PCLS pclsPrivateList; PCLS pclsPublicList; INT cThreads; + HDESK hdeskStartup; DWORD dwhmodLibLoadedMask; HANDLE ahmodLibLoaded[CLIBS]; struct _WINSTATION_OBJECT *prpwinsta; diff --git a/subsystems/win32/win32k/include/winpos.h b/subsystems/win32/win32k/include/winpos.h index 7f1c52a4124..a230972ab5a 100644 --- a/subsystems/win32/win32k/include/winpos.h +++ b/subsystems/win32/win32k/include/winpos.h @@ -1,5 +1,32 @@ #pragma once +typedef struct _CVR // Tag Ussw +{ + WINDOWPOS pos; + LONG xClientNew; + LONG yClientNew; + LONG cxClientNew; + LONG cyClientNew; + RECT rcBlt; + LONG dxBlt; + LONG dyBlt; + UINT fsRE; + HRGN hrgnVisOld; + PTHREADINFO pti; + HRGN hrgnClip; + HRGN hrgnInterMonitor; +} CVR, *PCVR; + +typedef struct _SMWP +{ + HEAD head; + UINT bShellNotify:1; + UINT bHandle:1; + INT ccvr; + INT ccvrAlloc; + PCVR acvr; +} SMWP, *PSMWP; + #define IntPtInWindow(WndObject,x,y) \ ((x) >= (WndObject)->rcWindow.left && \ (x) < (WndObject)->rcWindow.right && \ @@ -36,3 +63,5 @@ VOID FASTCALL co_WinPosActivateOtherWindow(PWND Window); VOID FASTCALL WinPosInitInternalPos(PWND WindowObject, POINT *pt, RECTL *RestoreRect); +BOOL FASTCALL IntEndDeferWindowPosEx(HDWP); +HDWP FASTCALL IntDeferWindowPos(HDWP,HWND,HWND,INT,INT,INT,INT,UINT); diff --git a/subsystems/win32/win32k/include/winsta.h b/subsystems/win32/win32k/include/winsta.h index c40d14bf419..01a5fb77543 100644 --- a/subsystems/win32/win32k/include/winsta.h +++ b/subsystems/win32/win32k/include/winsta.h @@ -82,6 +82,9 @@ NTSTATUS APIENTRY IntWinStaObjectParse(PWIN32_PARSEMETHOD_PARAMETERS Parameters); +NTSTATUS NTAPI +IntWinstaOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters); + NTSTATUS FASTCALL IntValidateWindowStationHandle( HWINSTA WindowStation, @@ -106,4 +109,7 @@ IntGetFullWindowStationName( PWINSTATION_OBJECT FASTCALL IntGetWinStaObj(VOID); +BOOL FASTCALL +UserSetProcessWindowStation(HWINSTA hWindowStation); + /* EOF */ diff --git a/subsystems/win32/win32k/main/dllmain.c b/subsystems/win32/win32k/main/dllmain.c index f78bf1940b9..1bff6e3f3b9 100644 --- a/subsystems/win32/win32k/main/dllmain.c +++ b/subsystems/win32/win32k/main/dllmain.c @@ -119,6 +119,7 @@ Win32kProcessCallback(struct _EPROCESS *Process, { DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql()); Win32Process->W32PF_flags |= W32PF_TERMINATED; + if (Win32Process->InputIdleEvent) { EngFreeMem((PVOID)Win32Process->InputIdleEvent); @@ -144,6 +145,9 @@ Win32kProcessCallback(struct _EPROCESS *Process, { LogonProcess = NULL; } + + UserSetProcessWindowStation(NULL); + } RETURN( STATUS_SUCCESS); @@ -220,43 +224,17 @@ Win32kThreadCallback(struct _ETHREAD *Thread, { if(hWinSta != NULL) { - if(Process != CsrProcess) + if(!UserSetProcessWindowStation(hWinSta)) { - HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL); - if(hProcessWinSta != NULL) - { - /* our process is already assigned to a different window station, we don't need the handle anymore */ - NtClose(hWinSta); - } - } - else - { - NtClose(hWinSta); + DPRINT1("Failed to set process window station\n"); } } if (hDesk != NULL) { - PDESKTOP DesktopObject; - Win32Thread->rpdesk = NULL; - Status = ObReferenceObjectByHandle(hDesk, - 0, - ExDesktopObjectType, - KernelMode, - (PVOID*)&DesktopObject, - NULL); - NtClose(hDesk); - if(NT_SUCCESS(Status)) + if (!IntSetThreadDesktop(hDesk, FALSE)) { - if (!IntSetThreadDesktop(DesktopObject, - FALSE)) - { DPRINT1("Unable to set thread desktop\n"); - } - } - else - { - DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk); } } } @@ -456,6 +434,8 @@ DriverEntry( CalloutData.ProcessCallout = Win32kProcessCallback; CalloutData.ThreadCallout = Win32kThreadCallback; CalloutData.BatchFlushRoutine = NtGdiFlushUserBatch; + CalloutData.DesktopOkToCloseProcedure = IntDesktopOkToClose; + CalloutData.WindowStationOkToCloseProcedure = IntWinstaOkToClose; /* Register our per-process and per-thread structures. */ PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData); diff --git a/subsystems/win32/win32k/misc/registry.c b/subsystems/win32/win32k/misc/registry.c index 86bac347f2f..455aa3f8a36 100644 --- a/subsystems/win32/win32k/misc/registry.c +++ b/subsystems/win32/win32k/misc/registry.c @@ -58,7 +58,7 @@ RegQueryValue( ULONG cbInfoSize, cbDataSize; /* Check if the local buffer is sufficient */ - cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + *pcbValue; + cbInfoSize = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + *pcbValue; if (cbInfoSize <= sizeof(ajBuffer)) { pInfo = (PVOID)ajBuffer; @@ -89,8 +89,11 @@ RegQueryValue( /* Did we get the right type */ if (pInfo->Type == ulType) { - /* Copy the contents to the caller */ - RtlCopyMemory(pvData, pInfo->Data, min(*pcbValue, cbDataSize)); + /* Copy the contents to the caller. Make sure strings are null terminated */ + if (ulType == REG_SZ || ulType == REG_MULTI_SZ || ulType == REG_EXPAND_SZ) + RtlStringCbCopyNW((LPWSTR)pvData, *pcbValue, (LPWSTR)pInfo->Data, cbDataSize); + else + RtlCopyMemory(pvData, pInfo->Data, cbDataSize); } else Status = STATUS_OBJECT_TYPE_MISMATCH; diff --git a/subsystems/win32/win32k/ntuser/class.c b/subsystems/win32/win32k/ntuser/class.c index cc9da7f886b..81e0076be26 100644 --- a/subsystems/win32/win32k/ntuser/class.c +++ b/subsystems/win32/win32k/ntuser/class.c @@ -19,15 +19,15 @@ REGISTER_SYSCLASS DefaultServerClasses[] = { -/* { ((PWSTR)((ULONG_PTR)(WORD)(0x8001))), + { ((PWSTR)((ULONG_PTR)(WORD)(0x8001))), CS_GLOBALCLASS|CS_DBLCLKS, NULL, 0, IDC_ARROW, - (HBRUSH)(COLOR_BACKGROUND+1), + (HBRUSH)(COLOR_BACKGROUND + 1), FNID_DESKTOP, ICLS_DESKTOP - },*/ + }, { ((PWSTR)((ULONG_PTR)(WORD)(0x8003))), CS_VREDRAW|CS_HREDRAW|CS_SAVEBITS, NULL, // Use User32 procs diff --git a/subsystems/win32/win32k/ntuser/desktop.c b/subsystems/win32/win32k/ntuser/desktop.c index 1653bc21494..e414e7e55bf 100644 --- a/subsystems/win32/win32k/ntuser/desktop.c +++ b/subsystems/win32/win32k/ntuser/desktop.c @@ -168,6 +168,29 @@ IntDesktopObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters) IntFreeDesktopHeap(Desktop); } +NTSTATUS NTAPI +IntDesktopOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters) +{ + PTHREADINFO pti; + + pti = PsGetCurrentThreadWin32Thread(); + + if( pti == NULL) + { + /* This happens when we leak desktop handles */ + return TRUE; + } + + /* Do not allow the current desktop or the initial desktop to be closed */ + if( Parameters->Handle == pti->ppi->hdeskStartup || + Parameters->Handle == pti->hdesk) + { + return FALSE; + } + + return TRUE; +} + /* PRIVATE FUNCTIONS **********************************************************/ INIT_FUNCTION @@ -859,15 +882,12 @@ IntFreeDesktopHeap(IN OUT PDESKTOP Desktop) HDESK APIENTRY NtUserCreateDesktop( - POBJECT_ATTRIBUTES poa, + POBJECT_ATTRIBUTES ObjectAttributes, PUNICODE_STRING lpszDesktopDevice, LPDEVMODEW lpdmw, DWORD dwFlags, ACCESS_MASK dwDesiredAccess) { - OBJECT_ATTRIBUTES ObjectAttributes; - PTHREADINFO W32Thread; - PWINSTATION_OBJECT WinStaObject; PDESKTOP DesktopObject; UNICODE_STRING DesktopName; NTSTATUS Status = STATUS_SUCCESS; @@ -875,12 +895,9 @@ NtUserCreateDesktop( CSR_API_MESSAGE Request; PVOID DesktopHeapSystemBase = NULL; SIZE_T DesktopInfoSize; - UNICODE_STRING SafeDesktopName; ULONG DummyContext; ULONG_PTR HeapSize = 4 * 1024 * 1024; /* FIXME */ - HWINSTA hWindowStation = NULL ; - PUNICODE_STRING lpszDesktopName = NULL; - UNICODE_STRING ClassName, MenuName; + UNICODE_STRING ClassName; LARGE_STRING WindowName; BOOL NoHooks = FALSE; PWND pWnd = NULL; @@ -889,7 +906,7 @@ NtUserCreateDesktop( PTHREADINFO ptiCurrent; DECLARE_RETURN(HDESK); - DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName); + DPRINT("Enter NtUserCreateDesktop\n"); UserEnterExclusive(); ptiCurrent = PsGetCurrentThreadWin32Thread(); @@ -899,19 +916,38 @@ NtUserCreateDesktop( NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS); ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS; } + DesktopName.Buffer = NULL; + /* + * Try to open already existing desktop + */ + + DPRINT("Trying to open desktop (%wZ)\n", &DesktopName); + + Status = ObOpenObjectByName( + ObjectAttributes, + ExDesktopObjectType, + UserMode, + NULL, + dwDesiredAccess, + (PVOID)&DummyContext, + (HANDLE*)&Desktop); + if (!NT_SUCCESS(Status)) RETURN(NULL); + if (Status == STATUS_OBJECT_NAME_EXISTS) + { + RETURN( Desktop); + } + + /* Capture desktop name */ _SEH2_TRY { - ProbeForRead( poa, - sizeof(OBJECT_ATTRIBUTES), - 1); + ProbeForRead( ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1); - hWindowStation = poa->RootDirectory; - lpszDesktopName = poa->ObjectName; + Status = IntSafeCopyUnicodeString(&DesktopName, ObjectAttributes->ObjectName); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Status =_SEH2_GetExceptionCode(); + Status = _SEH2_GetExceptionCode(); } _SEH2_END @@ -922,75 +958,6 @@ NtUserCreateDesktop( RETURN( NULL); } - Status = IntValidateWindowStationHandle( - hWindowStation, - KernelMode, - 0, /* FIXME - WINSTA_CREATEDESKTOP */ - &WinStaObject); - - if (! NT_SUCCESS(Status)) - { - DPRINT1("Failed validation of window station handle (0x%X), cannot create desktop %wZ\n", - hWindowStation, lpszDesktopName); - SetLastNtError(Status); - RETURN( NULL); - } - if(lpszDesktopName != NULL) - { - Status = IntSafeCopyUnicodeString(&SafeDesktopName, lpszDesktopName); - if(!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( NULL); - } - } - else - { - RtlInitUnicodeString(&SafeDesktopName, NULL); - } - - if (! IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name, - &SafeDesktopName)) - { - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - ObDereferenceObject(WinStaObject); - if (lpszDesktopName) - ExFreePoolWithTag(SafeDesktopName.Buffer, TAG_STRING); - RETURN( NULL); - } - if (lpszDesktopName) - ExFreePoolWithTag(SafeDesktopName.Buffer, TAG_STRING); - ObDereferenceObject(WinStaObject); - - /* - * Try to open already existing desktop - */ - - DPRINT("Trying to open desktop (%wZ)\n", &DesktopName); - - /* Initialize ObjectAttributes for the desktop object */ - InitializeObjectAttributes( - &ObjectAttributes, - &DesktopName, - 0, - NULL, - NULL); - - Status = ObOpenObjectByName( - &ObjectAttributes, - ExDesktopObjectType, - KernelMode, - NULL, - dwDesiredAccess, - (PVOID)&DummyContext, - (HANDLE*)&Desktop); - if (!NT_SUCCESS(Status)) RETURN(NULL); - if (Status == STATUS_OBJECT_NAME_EXISTS) - { - ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING); - RETURN( Desktop); - } - /* Reference the desktop */ Status = ObReferenceObjectByHandle(Desktop, 0, @@ -1011,12 +978,11 @@ NtUserCreateDesktop( RETURN(NULL); } - DesktopInfoSize = FIELD_OFFSET(DESKTOPINFO, - szDesktopName[(lpszDesktopName->Length / sizeof(WCHAR)) + 1]); + DesktopInfoSize = sizeof(DESKTOPINFO) + DesktopName.Length; DesktopObject->pDeskInfo = RtlAllocateHeap(DesktopObject->pheapDesktop, - HEAP_NO_SERIALIZE, - DesktopInfoSize); + HEAP_NO_SERIALIZE, + DesktopInfoSize); if (DesktopObject->pDeskInfo == NULL) { @@ -1031,8 +997,8 @@ NtUserCreateDesktop( DesktopObject->pDeskInfo->pvDesktopBase = DesktopHeapSystemBase; DesktopObject->pDeskInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize); RtlCopyMemory(DesktopObject->pDeskInfo->szDesktopName, - lpszDesktopName->Buffer, - lpszDesktopName->Length); + DesktopName.Buffer, + DesktopName.Length); /* Initialize some local (to win32k) desktop state. */ InitializeListHead(&DesktopObject->PtiList); @@ -1042,7 +1008,6 @@ NtUserCreateDesktop( { InitializeListHead(&DesktopObject->pDeskInfo->aphkStart[i]); } - ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING); //// why is this here? #if 0 @@ -1090,7 +1055,6 @@ NtUserCreateDesktop( // ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_DESKTOP]))); ClassName.Length = 0; - RtlZeroMemory(&MenuName, sizeof(MenuName)); RtlZeroMemory(&WindowName, sizeof(WindowName)); RtlZeroMemory(&Cs, sizeof(Cs)); @@ -1113,9 +1077,8 @@ NtUserCreateDesktop( DesktopObject->pDeskInfo->spwnd = pWndDesktop; } #endif - W32Thread = PsGetCurrentThreadWin32Thread(); - if (!W32Thread->rpdesk) IntSetThreadDesktop(DesktopObject,FALSE); + if (!ptiCurrent->rpdesk) IntSetThreadDesktop(Desktop,FALSE); /* Based on wine/server/window.c in get_desktop_window. @@ -1123,7 +1086,6 @@ NtUserCreateDesktop( ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_HWNDMESSAGE]))); ClassName.Length = 0; - RtlZeroMemory(&MenuName, sizeof(MenuName)); RtlZeroMemory(&WindowName, sizeof(WindowName)); RtlZeroMemory(&Cs, sizeof(Cs)); @@ -1154,6 +1116,10 @@ NtUserCreateDesktop( RETURN( Desktop); CLEANUP: + if(DesktopName.Buffer != NULL) + { + ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING); + } if (!NoHooks && ptiCurrent) ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS; DPRINT("Leave NtUserCreateDesktop, ret=%i\n",_ret_); UserLeave(); @@ -1184,85 +1150,17 @@ CLEANUP: HDESK APIENTRY NtUserOpenDesktop( - PUNICODE_STRING lpszDesktopName, + POBJECT_ATTRIBUTES ObjectAttributes, DWORD dwFlags, ACCESS_MASK dwDesiredAccess) { - OBJECT_ATTRIBUTES ObjectAttributes; - HWINSTA WinSta; - PWINSTATION_OBJECT WinStaObject; - UNICODE_STRING DesktopName; - UNICODE_STRING SafeDesktopName; NTSTATUS Status; HDESK Desktop; - BOOL Result; - DECLARE_RETURN(HDESK); - - DPRINT("Enter NtUserOpenDesktop: %wZ\n", lpszDesktopName); - UserEnterExclusive(); - - /* - * Validate the window station handle and compose the fully - * qualified desktop name - */ - - WinSta = UserGetProcessWindowStation(); - Status = IntValidateWindowStationHandle( - WinSta, - KernelMode, - 0, - &WinStaObject); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed validation of window station handle (0x%X)\n", WinSta); - SetLastNtError(Status); - RETURN( 0); - } - - if(lpszDesktopName != NULL) - { - Status = IntSafeCopyUnicodeString(&SafeDesktopName, lpszDesktopName); - if(!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( NULL); - } - } - else - { - RtlInitUnicodeString(&SafeDesktopName, NULL); - } - - Result = IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name, - &SafeDesktopName); - - if (lpszDesktopName) - ExFreePoolWithTag(SafeDesktopName.Buffer, TAG_STRING); - ObDereferenceObject(WinStaObject); - - - if (!Result) - { - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - RETURN( 0); - } - - - DPRINT("Trying to open desktop (%wZ)\n", &DesktopName); - - /* Initialize ObjectAttributes for the desktop object */ - InitializeObjectAttributes( - &ObjectAttributes, - &DesktopName, - 0, - NULL, - NULL); Status = ObOpenObjectByName( - &ObjectAttributes, + ObjectAttributes, ExDesktopObjectType, - KernelMode, + UserMode, NULL, dwDesiredAccess, NULL, @@ -1271,19 +1169,10 @@ NtUserOpenDesktop( if (!NT_SUCCESS(Status)) { SetLastNtError(Status); - ExFreePool(DesktopName.Buffer); - RETURN( 0); + return 0; } - DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName); - ExFreePool(DesktopName.Buffer); - - RETURN( Desktop); - -CLEANUP: - DPRINT("Leave NtUserOpenDesktop, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; + return Desktop; } /* @@ -1929,105 +1818,135 @@ IntMapDesktopView(IN PDESKTOP DesktopObject) } BOOL -IntSetThreadDesktop(IN PDESKTOP DesktopObject, +IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure) { - PDESKTOP OldDesktop; + PDESKTOP DesktopObject = NULL, OldDesktop; + HDESK hOldDesktop; PTHREADINFO W32Thread; NTSTATUS Status; BOOL MapHeap; CLIENTTHREADINFO ctiSave; - DPRINT("IntSetThreadDesktop() DO=%p, FOF=%d\n", DesktopObject, FreeOnFailure); + DPRINT("IntSetThreadDesktop() , FOF=%d\n", FreeOnFailure); MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess); W32Thread = PsGetCurrentThreadWin32Thread(); - - if (W32Thread->rpdesk != DesktopObject) + + if(hDesktop != NULL) { - OldDesktop = W32Thread->rpdesk; + /* Validate the new desktop. */ + Status = IntValidateDesktopHandle( + hDesktop, + UserMode, + 0, + &DesktopObject); - if (!IsListEmpty(&W32Thread->WindowListHead)) + if (!NT_SUCCESS(Status)) { - DPRINT1("Attempted to change thread desktop although the thread has windows!\n"); - EngSetLastError(ERROR_BUSY); + DPRINT1("Validation of desktop handle (0x%X) failed\n", hDesktop); return FALSE; } - W32Thread->rpdesk = DesktopObject; + if (W32Thread->rpdesk == DesktopObject) + { + /* Nothing to do */ + ObDereferenceObject(DesktopObject); + return TRUE; + } + } + + if (!IsListEmpty(&W32Thread->WindowListHead)) + { + DPRINT1("Attempted to change thread desktop although the thread has windows!\n"); + EngSetLastError(ERROR_BUSY); + return FALSE; + } + + OldDesktop = W32Thread->rpdesk; + hOldDesktop = W32Thread->hdesk; + + W32Thread->rpdesk = DesktopObject; + W32Thread->hdesk = hDesktop; + + if (MapHeap && DesktopObject != NULL) + { + Status = IntMapDesktopView(DesktopObject); + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } + W32Thread->pDeskInfo = DesktopObject->pDeskInfo; + } + + RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO)); + + if (W32Thread->pcti && OldDesktop && NtCurrentTeb()) + { + RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO)); + DPRINT("Free ClientThreadInfo\n"); + DesktopHeapFree(OldDesktop, W32Thread->pcti); + W32Thread->pcti = NULL; + } + + if (!W32Thread->pcti && DesktopObject && NtCurrentTeb()) + { + DPRINT("Allocate ClientThreadInfo\n"); + W32Thread->pcti = DesktopHeapAlloc( DesktopObject, + sizeof(CLIENTTHREADINFO)); + RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO)); + } + + if (NtCurrentTeb()) + { + PCLIENTINFO pci = GetWin32ClientInfo(); + pci->ulClientDelta = DesktopHeapGetUserDelta(); + if (DesktopObject) + { + pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta); + if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta); + } + } + + if (OldDesktop != NULL && + !IntCheckProcessDesktopClasses(OldDesktop, + FreeOnFailure)) + { + DPRINT1("Failed to move process classes to shared heap!\n"); + + /* failed to move desktop classes to the shared heap, + unmap the view and return the error */ if (MapHeap && DesktopObject != NULL) + IntUnmapDesktopView(DesktopObject); + + return FALSE; + } + + /* Remove the thread from the old desktop's list */ + RemoveEntryList(&W32Thread->PtiLink); + + if (DesktopObject != NULL) + { + ObReferenceObject(DesktopObject); + /* Insert into new desktop's list */ + InsertTailList(&DesktopObject->PtiList, &W32Thread->PtiLink); + } + + /* Close the old desktop */ + if (OldDesktop != NULL) + { + if (MapHeap) { - Status = IntMapDesktopView(DesktopObject); - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return FALSE; - } - W32Thread->pDeskInfo = DesktopObject->pDeskInfo; + IntUnmapDesktopView(OldDesktop); } - RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO)); - - if (W32Thread->pcti && OldDesktop && NtCurrentTeb()) - { - RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO)); - DPRINT("Free ClientThreadInfo\n"); - DesktopHeapFree(OldDesktop, W32Thread->pcti); - W32Thread->pcti = NULL; - } - - if (!W32Thread->pcti && DesktopObject && NtCurrentTeb()) - { - DPRINT("Allocate ClientThreadInfo\n"); - W32Thread->pcti = DesktopHeapAlloc( DesktopObject, - sizeof(CLIENTTHREADINFO)); - RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO)); - } - - if (NtCurrentTeb()) - { - PCLIENTINFO pci = GetWin32ClientInfo(); - pci->ulClientDelta = DesktopHeapGetUserDelta(); - if (DesktopObject) - { - pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta); - if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta); - } - } - - if (OldDesktop != NULL && - !IntCheckProcessDesktopClasses(OldDesktop, - FreeOnFailure)) - { - DPRINT1("Failed to move process classes to shared heap!\n"); - - /* failed to move desktop classes to the shared heap, - unmap the view and return the error */ - if (MapHeap && DesktopObject != NULL) - IntUnmapDesktopView(DesktopObject); - - return FALSE; - } - - /* Remove the thread from the old desktop's list */ - RemoveEntryList(&W32Thread->PtiLink); - - if (DesktopObject != NULL) - { - ObReferenceObject(DesktopObject); - /* Insert into new desktop's list */ - InsertTailList(&DesktopObject->PtiList, &W32Thread->PtiLink); - } - - if (OldDesktop != NULL) - { - if (MapHeap) - { - IntUnmapDesktopView(OldDesktop); - } - - ObDereferenceObject(OldDesktop); - } + ObDereferenceObject(OldDesktop); + } + + if (hOldDesktop != NULL) + { + ZwClose(hOldDesktop); } return TRUE; @@ -2043,40 +1962,15 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject, BOOL APIENTRY NtUserSetThreadDesktop(HDESK hDesktop) { - PDESKTOP DesktopObject; - NTSTATUS Status; - DECLARE_RETURN(BOOL); + BOOL ret; UserEnterExclusive(); - DPRINT("Enter NtUserSetThreadDesktop\n"); - - /* Validate the new desktop. */ - Status = IntValidateDesktopHandle( - hDesktop, - UserMode, - 0, - &DesktopObject); - - if (!NT_SUCCESS(Status)) - { - DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop); - RETURN(FALSE); - } - - /* FIXME: Should check here to see if the thread has any windows. */ - - if (!IntSetThreadDesktop(DesktopObject, - FALSE)) - { - RETURN(FALSE); - } - - RETURN(TRUE); - -CLEANUP: - DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_); + + ret = IntSetThreadDesktop(hDesktop, FALSE); + UserLeave(); - END_CLEANUP; + + return ret; } /* EOF */ diff --git a/subsystems/win32/win32k/ntuser/display.c b/subsystems/win32/win32k/ntuser/display.c index 7e0f25cf22d..98b93d5ddf7 100644 --- a/subsystems/win32/win32k/ntuser/display.c +++ b/subsystems/win32/win32k/ntuser/display.c @@ -309,11 +309,11 @@ UserEnumDisplayDevices( ZwClose(hkey); /* Copy device name, device string and StateFlags */ - wcsncpy(pdispdev->DeviceName, pGraphicsDevice->szWinDeviceName, 32); - wcsncpy(pdispdev->DeviceString, pGraphicsDevice->pwszDescription, 128); + RtlStringCbCopyW(pdispdev->DeviceName, sizeof(pdispdev->DeviceName), pGraphicsDevice->szWinDeviceName); + RtlStringCbCopyW(pdispdev->DeviceString, sizeof(pdispdev->DeviceString), pGraphicsDevice->pwszDescription); pdispdev->StateFlags = pGraphicsDevice->StateFlags; - // FIXME: fill in DEVICE ID + pdispdev->DeviceID[0] = UNICODE_NULL; return STATUS_SUCCESS; } @@ -339,7 +339,7 @@ NtUserEnumDisplayDevices( if (pustrDevice && iDevNum != 0) return FALSE; - dispdev.cb = sizeof(DISPLAY_DEVICEW); + dispdev.cb = sizeof(dispdev); if (pustrDevice) { diff --git a/subsystems/win32/win32k/ntuser/ntstubs.c b/subsystems/win32/win32k/ntuser/ntstubs.c index 7d405821102..7cdc720cd0a 100644 --- a/subsystems/win32/win32k/ntuser/ntstubs.c +++ b/subsystems/win32/win32k/ntuser/ntstubs.c @@ -538,36 +538,40 @@ NtUserSetSysColors( IN CONST COLORREF *lpaRgbValues, FLONG Flags) { - DWORD Ret = FALSE; - NTSTATUS Status = STATUS_SUCCESS; - UserEnterExclusive(); - _SEH2_TRY - { - ProbeForRead(lpaElements, + DWORD Ret = TRUE; + NTSTATUS Status = STATUS_SUCCESS; + + if (cElements == 0) + return TRUE; + + UserEnterExclusive(); + _SEH2_TRY + { + ProbeForRead(lpaElements, sizeof(INT), 1); - ProbeForRead(lpaRgbValues, - sizeof(INT), + ProbeForRead(lpaRgbValues, + sizeof(COLORREF), 1); // Developers: We are thread locked and calling gdi. - Ret = IntSetSysColors(cElements, (INT*)lpaElements, (COLORREF*)lpaRgbValues); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { + IntSetSysColors(cElements, lpaElements, lpaRgbValues); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - if (!NT_SUCCESS(Status)) - { + } + _SEH2_END; + if (!NT_SUCCESS(Status)) + { SetLastNtError(Status); Ret = FALSE; - } - if (Ret) - { - UserSendNotifyMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); - } - UserLeave(); - return Ret; + } + if (Ret) + { + UserSendNotifyMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); + } + UserLeave(); + return Ret; } DWORD @@ -817,8 +821,45 @@ NtUserMinMaximize( UINT cmd, // Wine SW_ commands BOOL Hide) { - UNIMPLEMENTED; - return 0; + RECTL NewPos; + UINT SwFlags; + PWND pWnd; + + DPRINT("Enter NtUserMinMaximize\n"); + UserEnterExclusive(); + + pWnd = UserGetWindowObject(hWnd); + if ( !pWnd || // FIXME: + pWnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + pWnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + goto Exit; + } + + if ( cmd > SW_MAX || pWnd->state2 & WNDS2_INDESTROY) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + goto Exit; + } + + co_WinPosMinMaximize(pWnd, cmd, &NewPos); + + SwFlags = Hide ? SWP_NOACTIVATE|SWP_NOZORDER|SWP_FRAMECHANGED : SWP_NOZORDER|SWP_FRAMECHANGED; + + co_WinPosSetWindowPos( pWnd, + NULL, + NewPos.left, + NewPos.top, + NewPos.right, + NewPos.bottom, + SwFlags); + + co_WinPosShowWindow(pWnd, cmd); + +Exit: + DPRINT("Leave NtUserMinMaximize\n"); + UserLeave(); + return 0; // Always NULL? } DWORD @@ -1168,18 +1209,6 @@ NtUserDrawMenuBarTemp( return 0; } -/* - * @unimplemented - */ -DWORD APIENTRY -NtUserEndDeferWindowPosEx(DWORD Unknown0, - DWORD Unknown1) -{ - UNIMPLEMENTED - - return 0; -} - /* * FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND. */ @@ -1205,7 +1234,7 @@ NtUserFlashWindowEx(IN PFLASHWINFO pfwi) { UNIMPLEMENTED - return 0; + return 1; } /* @@ -1305,25 +1334,6 @@ NtUserWindowFromPhysicalPoint(POINT Point) return NULL; } -/* - * @unimplemented - */ -HDWP APIENTRY -NtUserDeferWindowPos(HDWP WinPosInfo, - HWND Wnd, - HWND WndInsertAfter, - int x, - int y, - int cx, - int cy, - UINT Flags) -{ - UNIMPLEMENTED - - return 0; -} - - /* * NtUserResolveDesktopForWOW * diff --git a/subsystems/win32/win32k/ntuser/object.c b/subsystems/win32/win32k/ntuser/object.c index 8376f0bfd84..4df5c8f8f6d 100644 --- a/subsystems/win32/win32k/ntuser/object.c +++ b/subsystems/win32/win32k/ntuser/object.c @@ -177,6 +177,7 @@ UserHandleOwnerByType(USER_OBJECT_TYPE type) case otHook: case otCallProc: case otAccel: + case otSMWP: pi = GetW32ProcessInfo(); break; diff --git a/subsystems/win32/win32k/ntuser/simplecall.c b/subsystems/win32/win32k/ntuser/simplecall.c index 2c4844f0e98..d4a1a14f403 100644 --- a/subsystems/win32/win32k/ntuser/simplecall.c +++ b/subsystems/win32/win32k/ntuser/simplecall.c @@ -157,6 +157,40 @@ NtUserCallOneParam( MsqPostQuitMessage(pti->MessageQueue, Param); RETURN(TRUE); } + + case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS: + { + PSMWP psmwp; + HDWP hDwp = NULL; + INT count = (INT)Param; + + if (count < 0) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + RETURN(0); + } + /* Windows allows zero count, in which case it allocates context for 8 moves */ + if (count == 0) count = 8; + + psmwp = (PSMWP) UserCreateObject( gHandleTable, + NULL, + (PHANDLE)&hDwp, + otSMWP, + sizeof(SMWP)); + if (!psmwp) RETURN(0); + psmwp->acvr = ExAllocatePoolWithTag(PagedPool, count * sizeof(CVR), USERTAG_SWP); + if (!psmwp->acvr) + { + UserDeleteObject(hDwp, otSMWP); + RETURN(0); + } + RtlZeroMemory(psmwp->acvr, count * sizeof(CVR)); + psmwp->bHandle = TRUE; + psmwp->ccvr = 0; // actualCount + psmwp->ccvrAlloc = count; // suggestedCount + RETURN((DWORD_PTR)hDwp); + } + case ONEPARAM_ROUTINE_SHOWCURSOR: RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) ); diff --git a/subsystems/win32/win32k/ntuser/window.c b/subsystems/win32/win32k/ntuser/window.c index 7be4ef57280..72d232b5393 100644 --- a/subsystems/win32/win32k/ntuser/window.c +++ b/subsystems/win32/win32k/ntuser/window.c @@ -1940,7 +1940,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, DWORD dwShowMode = SW_SHOW; CREATESTRUCTW *pCsw = NULL; PVOID pszClass = NULL, pszName = NULL; - DECLARE_RETURN(PWND); + PWND ret = NULL; /* Get the current window station and reference it */ pti = GetW32ThreadInfo(); @@ -1960,7 +1960,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if(!Class) { DPRINT1("Failed to find class %wZ\n", ClassName); - RETURN(NULL); + goto cleanup; } /* Now find the parent and the owner window */ @@ -1982,7 +1982,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, { DPRINT1("Cannot create a child window without a parrent!\n"); EngSetLastError(ERROR_TLW_WITH_WSCHILD); - RETURN(NULL); /* WS_CHILD needs a parent, but WS_POPUP doesn't */ + goto cleanup; /* WS_CHILD needs a parent, but WS_POPUP doesn't */ } ParentWindow = hWndParent ? UserGetWindowObject(hWndParent): NULL; @@ -2008,7 +2008,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if(!Window) { DPRINT1("IntCreateWindow failed!\n"); - RETURN(0); + goto cleanup; } hWnd = UserHMGetHandle(Window); @@ -2023,6 +2023,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, // Allocate the calling structures Justin Case this goes Global. pCsw = ExAllocatePoolWithTag(NonPagedPool, sizeof(CREATESTRUCTW), TAG_HOOK); pCbtCreate = ExAllocatePoolWithTag(NonPagedPool, sizeof(CBT_CREATEWNDW), TAG_HOOK); + if (!pCsw || !pCbtCreate) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } /* Fill the new CREATESTRUCTW */ RtlCopyMemory(pCsw, Cs, sizeof(CREATESTRUCTW)); @@ -2036,6 +2041,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, ANSI_STRING AnsiString; AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(ClassName)+sizeof(CHAR); pszClass = UserHeapAlloc(AnsiString.MaximumLength); + if (!pszClass) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } RtlZeroMemory(pszClass, AnsiString.MaximumLength); AnsiString.Buffer = (PCHAR)pszClass; RtlUnicodeStringToAnsiString(&AnsiString, ClassName, FALSE); @@ -2045,11 +2055,16 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, UNICODE_STRING UnicodeString; UnicodeString.MaximumLength = ClassName->Length + sizeof(UNICODE_NULL); pszClass = UserHeapAlloc(UnicodeString.MaximumLength); + if (!pszClass) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } RtlZeroMemory(pszClass, UnicodeString.MaximumLength); UnicodeString.Buffer = (PWSTR)pszClass; RtlCopyUnicodeString(&UnicodeString, ClassName); } - if (pszClass) pCsw->lpszClass = UserHeapAddressToUser(pszClass); + pCsw->lpszClass = UserHeapAddressToUser(pszClass); } if (WindowName->Length) { @@ -2061,8 +2076,13 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if (Window->state & WNDS_ANSICREATOR) { ANSI_STRING AnsiString; - AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name)+sizeof(CHAR); + AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name) + sizeof(CHAR); pszName = UserHeapAlloc(AnsiString.MaximumLength); + if (!pszName) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } RtlZeroMemory(pszName, AnsiString.MaximumLength); AnsiString.Buffer = (PCHAR)pszName; RtlUnicodeStringToAnsiString(&AnsiString, &Name, FALSE); @@ -2072,11 +2092,16 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, UNICODE_STRING UnicodeString; UnicodeString.MaximumLength = Name.Length + sizeof(UNICODE_NULL); pszName = UserHeapAlloc(UnicodeString.MaximumLength); + if (!pszName) + { + DPRINT1("UserHeapAlloc() failed!\n"); + goto cleanup; + } RtlZeroMemory(pszName, UnicodeString.MaximumLength); UnicodeString.Buffer = (PWSTR)pszName; RtlCopyUnicodeString(&UnicodeString, &Name); } - if (pszName) pCsw->lpszName = UserHeapAddressToUser(pszName); + pCsw->lpszName = UserHeapAddressToUser(pszName); } pCbtCreate->lpcs = pCsw; @@ -2087,7 +2112,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if (Result != 0) { DPRINT1("WH_CBT HCBT_CREATEWND hook failed! 0x%x\n", Result); - RETURN( (PWND) NULL); + goto cleanup; } // Write back changes. Cs->cx = pCsw->cx; @@ -2143,7 +2168,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if (!Result) { DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n"); - RETURN((PWND)0); + goto cleanup; } /* Send the WM_NCCALCSIZE message */ @@ -2161,7 +2186,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if (Result == (LRESULT)-1) { DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n"); - RETURN((PWND)0); + goto cleanup; } /* Send the EVENT_OBJECT_CREATE event*/ @@ -2234,10 +2259,10 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, } DPRINT("co_UserCreateWindowEx(): Created window %X\n", hWnd); - RETURN( Window); + ret = Window; -CLEANUP: - if (!_ret_) +cleanup: + if (!ret) { DPRINT("co_UserCreateWindowEx(): Error Created window!\n"); /* If the window was created, the class will be dereferenced by co_UserDestroyWindow */ @@ -2258,8 +2283,8 @@ CLEANUP: UserDereferenceObject(Window); } if (ParentWindow) UserDerefObjectCo(ParentWindow); - - END_CLEANUP; + + return ret; } NTSTATUS @@ -3684,23 +3709,6 @@ CLEANUP: END_CLEANUP; } -/* - * @implemented - */ -BOOL APIENTRY -NtUserMoveWindow( - HWND hWnd, - int X, - int Y, - int nWidth, - int nHeight, - BOOL bRepaint) -{ - return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, - (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE : - SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW)); -} - /* QueryWindow based on KJK::Hyperion and James Tabor. @@ -3901,234 +3909,6 @@ CLEANUP: END_CLEANUP; } - -/* - * @implemented - */ -BOOL APIENTRY -NtUserSetWindowPlacement(HWND hWnd, - WINDOWPLACEMENT *lpwndpl) -{ - PWND Wnd; - WINDOWPLACEMENT Safepl; - NTSTATUS Status; - DECLARE_RETURN(BOOL); - USER_REFERENCE_ENTRY Ref; - - DPRINT("Enter NtUserSetWindowPlacement\n"); - UserEnterExclusive(); - - if (!(Wnd = UserGetWindowObject(hWnd))) - { - RETURN( FALSE); - } - - Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT)); - if(!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( FALSE); - } - if(Safepl.length != sizeof(WINDOWPLACEMENT)) - { - RETURN( FALSE); - } - - UserRefObjectCo(Wnd, &Ref); - - if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0) - { - co_WinPosSetWindowPos(Wnd, NULL, - Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top, - Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left, - Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top, - SWP_NOZORDER | SWP_NOACTIVATE); - } - - /* FIXME - change window status */ - co_WinPosShowWindow(Wnd, Safepl.showCmd); - - Wnd->InternalPosInitialized = TRUE; - Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition; - Wnd->InternalPos.IconPos = Safepl.ptMinPosition; - Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition; - - UserDerefObjectCo(Wnd); - RETURN(TRUE); - -CLEANUP: - DPRINT("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - - -/* - * @implemented - */ -BOOL APIENTRY -NtUserSetWindowPos( - HWND hWnd, - HWND hWndInsertAfter, - int X, - int Y, - int cx, - int cy, - UINT uFlags) -{ - DECLARE_RETURN(BOOL); - PWND Window; - BOOL ret; - USER_REFERENCE_ENTRY Ref; - - DPRINT("Enter NtUserSetWindowPos\n"); - UserEnterExclusive(); - - if (!(Window = UserGetWindowObject(hWnd))) - { - RETURN(FALSE); - } - - /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */ - if (!(uFlags & SWP_NOMOVE)) - { - if (X < -32768) X = -32768; - else if (X > 32767) X = 32767; - if (Y < -32768) Y = -32768; - else if (Y > 32767) Y = 32767; - } - if (!(uFlags & SWP_NOSIZE)) - { - if (cx < 0) cx = 0; - else if (cx > 32767) cx = 32767; - if (cy < 0) cy = 0; - else if (cy > 32767) cy = 32767; - } - - UserRefObjectCo(Window, &Ref); - ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags); - UserDerefObjectCo(Window); - - RETURN(ret); - -CLEANUP: - DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - -/* - * @implemented - */ -INT APIENTRY -NtUserSetWindowRgn( - HWND hWnd, - HRGN hRgn, - BOOL bRedraw) -{ - HRGN hrgnCopy; - PWND Window; - INT flags = (SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE); - BOOLEAN Ret = FALSE; - DECLARE_RETURN(INT); - - DPRINT("Enter NtUserSetWindowRgn\n"); - UserEnterExclusive(); - - if (!(Window = UserGetWindowObject(hWnd))) - { - RETURN( 0); - } - - if (hRgn) // The region will be deleted in user32. - { - if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION)) - { - hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0); - - NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY); - } - else - RETURN( 0); - } - else - { - hrgnCopy = NULL; - } - - if (Window->hrgnClip) - { - /* Delete no longer needed region handle */ - GreDeleteObject(Window->hrgnClip); - } - - if (hrgnCopy) - { - if (Window->fnid != FNID_DESKTOP) - NtGdiOffsetRgn(hrgnCopy, Window->rcWindow.left, Window->rcWindow.top); - - /* Set public ownership */ - IntGdiSetRegionOwner(hrgnCopy, GDI_OBJ_HMGR_PUBLIC); - } - Window->hrgnClip = hrgnCopy; - - Ret = co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, bRedraw ? flags : (flags|SWP_NOREDRAW) ); - - RETURN( (INT)Ret); - -CLEANUP: - DPRINT("Leave NtUserSetWindowRgn, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - - -/* - * @implemented - */ -BOOL APIENTRY -NtUserShowWindow(HWND hWnd, LONG nCmdShow) -{ - PWND Window; - BOOL ret; - DECLARE_RETURN(BOOL); - USER_REFERENCE_ENTRY Ref; - - DPRINT("Enter NtUserShowWindow\n"); - UserEnterExclusive(); - - if (!(Window = UserGetWindowObject(hWnd))) - { - RETURN(FALSE); - } - - UserRefObjectCo(Window, &Ref); - ret = co_WinPosShowWindow(Window, nCmdShow); - UserDerefObjectCo(Window); - - RETURN(ret); - -CLEANUP: - DPRINT("Leave NtUserShowWindow, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - - -/* - * @unimplemented - */ -BOOL APIENTRY -NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow) -{ -#if 0 - UNIMPLEMENTED - return 0; -#else - return NtUserShowWindow(hWnd, nCmdShow); -#endif -} - /* * @implemented */ diff --git a/subsystems/win32/win32k/ntuser/winpos.c b/subsystems/win32/win32k/ntuser/winpos.c index 6a9dfd2b169..3934dcb21b6 100644 --- a/subsystems/win32/win32k/ntuser/winpos.c +++ b/subsystems/win32/win32k/ntuser/winpos.c @@ -20,7 +20,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: Windows - * FILE: subsys/win32k/ntuser/window.c + * FILE: subsystems/win32/win32k/ntuser/window.c * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * REVISION HISTORY: * 06-06-2001 CSH NtGdid @@ -199,8 +199,8 @@ co_WinPosArrangeIconicWindows(PWND parent) x = rectParent.left; y = rectParent.bottom; - xspacing = UserGetSystemMetrics(SM_CXMINSPACING); - yspacing = UserGetSystemMetrics(SM_CYMINSPACING); + xspacing = UserGetSystemMetrics(SM_CXICONSPACING); + yspacing = UserGetSystemMetrics(SM_CYICONSPACING); DPRINT("X:%d Y:%d XS:%d YS:%d\n",x,y,xspacing,yspacing); @@ -216,8 +216,8 @@ co_WinPosArrangeIconicWindows(PWND parent) USER_REFERENCE_ENTRY Ref; UserRefObjectCo(Child, &Ref); - co_WinPosSetWindowPos(Child, 0, x + UserGetSystemMetrics(SM_CXBORDER), - y - yspacing - UserGetSystemMetrics(SM_CYBORDER) + co_WinPosSetWindowPos(Child, 0, x + (xspacing - UserGetSystemMetrics(SM_CXICON)) / 2, + y - yspacing - UserGetSystemMetrics(SM_CYICON) / 2 , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); UserDerefObjectCo(Child); @@ -239,7 +239,7 @@ co_WinPosArrangeIconicWindows(PWND parent) static VOID FASTCALL WinPosFindIconPos(PWND Window, POINT *Pos) { - /* FIXME */ + DPRINT1("WinPosFindIconPos FIXME!\n"); } VOID FASTCALL @@ -1673,6 +1673,479 @@ co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest) return Window; } +HDWP +FASTCALL +IntDeferWindowPos( HDWP hdwp, + HWND hwnd, + HWND hwndAfter, + INT x, + INT y, + INT cx, + INT cy, + UINT flags ) +{ + PSMWP pDWP; + int i; + HDWP retvalue = hdwp; + + DPRINT("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n", + hdwp, hwnd, hwndAfter, x, y, cx, cy, flags); + + if (flags & ~(SWP_NOSIZE | SWP_NOMOVE | + SWP_NOZORDER | SWP_NOREDRAW | + SWP_NOACTIVATE | SWP_NOCOPYBITS | + SWP_NOOWNERZORDER|SWP_SHOWWINDOW | + SWP_HIDEWINDOW | SWP_FRAMECHANGED)) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP))) + { + EngSetLastError(ERROR_INVALID_DWP_HANDLE); + return NULL; + } + + for (i = 0; i < pDWP->ccvr; i++) + { + if (pDWP->acvr[i].pos.hwnd == hwnd) + { + /* Merge with the other changes */ + if (!(flags & SWP_NOZORDER)) + { + pDWP->acvr[i].pos.hwndInsertAfter = hwndAfter; + } + if (!(flags & SWP_NOMOVE)) + { + pDWP->acvr[i].pos.x = x; + pDWP->acvr[i].pos.y = y; + } + if (!(flags & SWP_NOSIZE)) + { + pDWP->acvr[i].pos.cx = cx; + pDWP->acvr[i].pos.cy = cy; + } + pDWP->acvr[i].pos.flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE | + SWP_NOZORDER | SWP_NOREDRAW | + SWP_NOACTIVATE | SWP_NOCOPYBITS| + SWP_NOOWNERZORDER); + pDWP->acvr[i].pos.flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | + SWP_FRAMECHANGED); + goto END; + } + } + if (pDWP->ccvr >= pDWP->ccvrAlloc) + { + PCVR newpos = ExAllocatePoolWithTag(PagedPool, pDWP->ccvrAlloc * 2 * sizeof(CVR), USERTAG_SWP); + if (!newpos) + { + retvalue = NULL; + goto END; + } + RtlZeroMemory(newpos, pDWP->ccvrAlloc * 2 * sizeof(CVR)); + RtlCopyMemory(newpos, pDWP->acvr, pDWP->ccvrAlloc * sizeof(CVR)); + ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP); + pDWP->ccvrAlloc *= 2; + pDWP->acvr = newpos; + } + pDWP->acvr[pDWP->ccvr].pos.hwnd = hwnd; + pDWP->acvr[pDWP->ccvr].pos.hwndInsertAfter = hwndAfter; + pDWP->acvr[pDWP->ccvr].pos.x = x; + pDWP->acvr[pDWP->ccvr].pos.y = y; + pDWP->acvr[pDWP->ccvr].pos.cx = cx; + pDWP->acvr[pDWP->ccvr].pos.cy = cy; + pDWP->acvr[pDWP->ccvr].pos.flags = flags; + pDWP->acvr[pDWP->ccvr].hrgnClip = NULL; + pDWP->acvr[pDWP->ccvr].hrgnInterMonitor = NULL; + pDWP->ccvr++; +END: + return retvalue; +} + +BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp ) +{ + PSMWP pDWP; + PCVR winpos; + BOOL res = TRUE; + int i; + + DPRINT("%p\n", hdwp); + + if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP))) + { + EngSetLastError(ERROR_INVALID_DWP_HANDLE); + return FALSE; + } + + for (i = 0, winpos = pDWP->acvr; res && i < pDWP->ccvr; i++, winpos++) + { + DPRINT("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n", + winpos->pos.hwnd, winpos->pos.hwndInsertAfter, winpos->pos.x, winpos->pos.y, + winpos->pos.cx, winpos->pos.cy, winpos->pos.flags); + + res = co_WinPosSetWindowPos( UserGetWindowObject(winpos->pos.hwnd), + winpos->pos.hwndInsertAfter, + winpos->pos.x, + winpos->pos.y, + winpos->pos.cx, + winpos->pos.cy, + winpos->pos.flags); + } + ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP); + UserDeleteObject(hdwp, otSMWP); + return res; +} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserEndDeferWindowPosEx(HDWP WinPosInfo, + DWORD Unknown1) +{ + BOOL Ret; + DPRINT("Enter NtUserEndDeferWindowPosEx\n"); + UserEnterExclusive(); + Ret = IntEndDeferWindowPosEx(WinPosInfo); + DPRINT("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret); + UserLeave(); + return Ret; +} + +/* + * @implemented + */ +HDWP APIENTRY +NtUserDeferWindowPos(HDWP WinPosInfo, + HWND Wnd, + HWND WndInsertAfter, + int x, + int y, + int cx, + int cy, + UINT Flags) +{ + PWND pWnd, pWndIA; + HDWP Ret = NULL; + UINT Tmp = ~(SWP_ASYNCWINDOWPOS|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_NOREPOSITION| + SWP_NOCOPYBITS|SWP_HIDEWINDOW|SWP_SHOWWINDOW|SWP_FRAMECHANGED| + SWP_NOACTIVATE|SWP_NOREDRAW|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE); + + DPRINT("Enter NtUserDeferWindowPos\n"); + UserEnterExclusive(); + + if ( Flags & Tmp ) + { + EngSetLastError(ERROR_INVALID_FLAGS); + goto Exit; + } + + pWnd = UserGetWindowObject(Wnd); + if ( !pWnd || // FIXME: + pWnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + pWnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + goto Exit; + } + + if ( WndInsertAfter && + WndInsertAfter != HWND_BOTTOM && + WndInsertAfter != HWND_TOPMOST && + WndInsertAfter != HWND_NOTOPMOST ) + { + pWndIA = UserGetWindowObject(WndInsertAfter); + if ( !pWndIA || + pWndIA == IntGetDesktopWindow() || + pWndIA == IntGetMessageWindow() ) + { + goto Exit; + } + } + + Ret = IntDeferWindowPos(WinPosInfo, Wnd, WndInsertAfter, x, y, cx, cy, Flags); + +Exit: + DPRINT("Leave NtUserDeferWindowPos, ret=%i\n", Ret); + UserLeave(); + return Ret; +} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserMoveWindow( + HWND hWnd, + int X, + int Y, + int nWidth, + int nHeight, + BOOL bRepaint) +{ + return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, + (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE : + SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW)); +} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserSetWindowPos( + HWND hWnd, + HWND hWndInsertAfter, + int X, + int Y, + int cx, + int cy, + UINT uFlags) +{ + DECLARE_RETURN(BOOL); + PWND Window, pWndIA; + BOOL ret; + USER_REFERENCE_ENTRY Ref; + + DPRINT("Enter NtUserSetWindowPos\n"); + UserEnterExclusive(); + + if (!(Window = UserGetWindowObject(hWnd)) || // FIXME: + Window == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + Window == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + RETURN(FALSE); + } + + if ( hWndInsertAfter && + hWndInsertAfter != HWND_BOTTOM && + hWndInsertAfter != HWND_TOPMOST && + hWndInsertAfter != HWND_NOTOPMOST ) + { + pWndIA = UserGetWindowObject(hWndInsertAfter); + if ( !pWndIA || + pWndIA == IntGetDesktopWindow() || + pWndIA == IntGetMessageWindow() ) + { + RETURN(FALSE); + } + } + + /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */ + if (!(uFlags & SWP_NOMOVE)) + { + if (X < -32768) X = -32768; + else if (X > 32767) X = 32767; + if (Y < -32768) Y = -32768; + else if (Y > 32767) Y = 32767; + } + if (!(uFlags & SWP_NOSIZE)) + { + if (cx < 0) cx = 0; + else if (cx > 32767) cx = 32767; + if (cy < 0) cy = 0; + else if (cy > 32767) cy = 32767; + } + + UserRefObjectCo(Window, &Ref); + ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags); + UserDerefObjectCo(Window); + + RETURN(ret); + +CLEANUP: + DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} + +/* + * @implemented + */ +INT APIENTRY +NtUserSetWindowRgn( + HWND hWnd, + HRGN hRgn, + BOOL bRedraw) +{ + HRGN hrgnCopy; + PWND Window; + INT flags = (SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE); + BOOLEAN Ret = FALSE; + DECLARE_RETURN(INT); + + DPRINT("Enter NtUserSetWindowRgn\n"); + UserEnterExclusive(); + + if (!(Window = UserGetWindowObject(hWnd)) || // FIXME: + Window == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + Window == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + RETURN( 0); + } + + if (hRgn) // The region will be deleted in user32. + { + if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION)) + { + hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0); + + NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY); + } + else + RETURN( 0); + } + else + { + hrgnCopy = NULL; + } + + if (Window->hrgnClip) + { + /* Delete no longer needed region handle */ + GreDeleteObject(Window->hrgnClip); + } + + if (hrgnCopy) + { + if (Window->fnid != FNID_DESKTOP) + NtGdiOffsetRgn(hrgnCopy, Window->rcWindow.left, Window->rcWindow.top); + + /* Set public ownership */ + IntGdiSetRegionOwner(hrgnCopy, GDI_OBJ_HMGR_PUBLIC); + } + Window->hrgnClip = hrgnCopy; + + Ret = co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, bRedraw ? flags : (flags|SWP_NOREDRAW) ); + + RETURN( (INT)Ret); + +CLEANUP: + DPRINT("Leave NtUserSetWindowRgn, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserSetWindowPlacement(HWND hWnd, + WINDOWPLACEMENT *lpwndpl) +{ + PWND Wnd; + WINDOWPLACEMENT Safepl; + DECLARE_RETURN(BOOL); + USER_REFERENCE_ENTRY Ref; + + DPRINT("Enter NtUserSetWindowPlacement\n"); + UserEnterExclusive(); + + if (!(Wnd = UserGetWindowObject(hWnd)) || // FIXME: + Wnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + Wnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + RETURN( FALSE); + } + + _SEH2_TRY + { + ProbeForRead(lpwndpl, sizeof(WINDOWPLACEMENT), 1); + RtlCopyMemory(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(RETURN( FALSE)); + } + _SEH2_END + + if(Safepl.length != sizeof(WINDOWPLACEMENT)) + { + RETURN( FALSE); + } + + UserRefObjectCo(Wnd, &Ref); + + if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0) + { + co_WinPosSetWindowPos(Wnd, NULL, + Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top, + Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left, + Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top, + SWP_NOZORDER | SWP_NOACTIVATE); + } + + /* FIXME - change window status */ + co_WinPosShowWindow(Wnd, Safepl.showCmd); + + Wnd->InternalPosInitialized = TRUE; + Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition; + Wnd->InternalPos.IconPos = Safepl.ptMinPosition; + Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition; + + UserDerefObjectCo(Wnd); + RETURN(TRUE); + +CLEANUP: + DPRINT("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} + +/* + * @unimplemented + */ +BOOL APIENTRY +NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow) +{ +#if 0 + UNIMPLEMENTED + return 0; +#else + return NtUserShowWindow(hWnd, nCmdShow); +#endif +} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserShowWindow(HWND hWnd, LONG nCmdShow) +{ + PWND Window; + BOOL ret; + DECLARE_RETURN(BOOL); + USER_REFERENCE_ENTRY Ref; + + DPRINT("Enter NtUserShowWindow\n"); + UserEnterExclusive(); + + if (!(Window = UserGetWindowObject(hWnd)) || // FIXME: + Window == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + Window == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + RETURN(FALSE); + } + + if ( nCmdShow > SW_MAX || Window->state2 & WNDS2_INDESTROY) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + RETURN(FALSE); + } + + UserRefObjectCo(Window, &Ref); + ret = co_WinPosShowWindow(Window, nCmdShow); + UserDerefObjectCo(Window); + + RETURN(ret); + +CLEANUP: + DPRINT("Leave NtUserShowWindow, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} + +//// Ugly NtUser API //// BOOL APIENTRY NtUserGetMinMaxInfo( diff --git a/subsystems/win32/win32k/ntuser/winsta.c b/subsystems/win32/win32k/ntuser/winsta.c index ff429a17524..2f44707b070 100644 --- a/subsystems/win32/win32k/ntuser/winsta.c +++ b/subsystems/win32/win32k/ntuser/winsta.c @@ -187,6 +187,21 @@ IntWinStaObjectParse(PWIN32_PARSEMETHOD_PARAMETERS Parameters) return STATUS_OBJECT_TYPE_MISMATCH; } +NTSTATUS NTAPI +IntWinstaOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters) +{ + PPROCESSINFO ppi; + + ppi = PsGetCurrentProcessWin32Process(); + + if(Parameters->Handle == ppi->hwinsta) + { + return FALSE; + } + + return TRUE; +} + /* PRIVATE FUNCTIONS **********************************************************/ /* @@ -392,61 +407,23 @@ IntGetScreenDC(VOID) HWINSTA APIENTRY NtUserCreateWindowStation( - PUNICODE_STRING lpszWindowStationName, + POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpSecurity, + DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6) { UNICODE_STRING WindowStationName; - UNICODE_STRING FullWindowStationName; PWINSTATION_OBJECT WindowStationObject; HWINSTA WindowStation; - OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; - /* - * Generate full window station name - */ - Status = ProbeAndCaptureUnicodeString(&WindowStationName, - UserMode, - lpszWindowStationName); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to capture window station name (status 0x%08x)\n", - Status); - SetLastNtError(Status); - return 0; - } - if (!IntGetFullWindowStationName(&FullWindowStationName, - &WindowStationName, - NULL)) - { - ReleaseCapturedUnicodeString(&WindowStationName, UserMode); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return 0; - } - - /* - * Try to open already existing window station - */ - - DPRINT("Trying to open window station (%wZ)\n", &FullWindowStationName); - - /* Initialize ObjectAttributes for the window station object */ - InitializeObjectAttributes( - &ObjectAttributes, - &FullWindowStationName, - 0, - NULL, - NULL); - Status = ObOpenObjectByName( - &ObjectAttributes, + ObjectAttributes, ExWindowStationObjectType, - KernelMode, + UserMode, NULL, dwDesiredAccess, NULL, @@ -454,24 +431,39 @@ NtUserCreateWindowStation( if (NT_SUCCESS(Status)) { - DPRINT("Successfully opened window station (%wZ)\n", - FullWindowStationName); - ExFreePool(FullWindowStationName.Buffer); - ReleaseCapturedUnicodeString(&WindowStationName, UserMode); return (HWINSTA)WindowStation; } + /* * No existing window station found, try to create new one */ + + /* Capture window station name */ + _SEH2_TRY + { + ProbeForRead( ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1); + Status = IntSafeCopyUnicodeString(&WindowStationName, ObjectAttributes->ObjectName); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status =_SEH2_GetExceptionCode(); + } + _SEH2_END - DPRINT("Creating window station (%wZ)\n", &FullWindowStationName); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Failed reading capturing window station name\n"); + SetLastNtError(Status); + return NULL; + } + /* Create the window station object */ Status = ObCreateObject( - KernelMode, + UserMode, ExWindowStationObjectType, - &ObjectAttributes, - ExGetPreviousMode(), + ObjectAttributes, + UserMode, NULL, sizeof(WINSTATION_OBJECT), 0, @@ -480,26 +472,11 @@ NtUserCreateWindowStation( if (!NT_SUCCESS(Status)) { - DPRINT1("Failed creating window station (%wZ)\n", &FullWindowStationName); - ExFreePool(FullWindowStationName.Buffer); - ReleaseCapturedUnicodeString(&WindowStationName, UserMode); + ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); return 0; } - /* Zero out the buffer */ - RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT)); - - KeInitializeSpinLock(&WindowStationObject->Lock); - - InitializeListHead(&WindowStationObject->DesktopListHead); - - WindowStationObject->AtomTable = NULL; - Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable); - WindowStationObject->SystemMenuTemplate = (HANDLE)0; - - WindowStationObject->Name = WindowStationName; - Status = ObInsertObject( (PVOID)WindowStationObject, NULL, @@ -510,20 +487,21 @@ NtUserCreateWindowStation( if (!NT_SUCCESS(Status)) { - DPRINT1("Failed creating window station (%wZ)\n", &FullWindowStationName); - ExFreePool(FullWindowStationName.Buffer); - ExFreePool(WindowStationName.Buffer); + ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); ObDereferenceObject(WindowStationObject); return 0; } - /* - * Initialize the new window station object - */ + /* Initialize the window station */ + RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT)); + KeInitializeSpinLock(&WindowStationObject->Lock); + InitializeListHead(&WindowStationObject->DesktopListHead); + Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable); + WindowStationObject->SystemMenuTemplate = (HANDLE)0; + WindowStationObject->Name = WindowStationName; WindowStationObject->ScreenSaverRunning = FALSE; - WindowStationObject->FlatMenu = FALSE; if (!IntSetupClipboard(WindowStationObject)) @@ -538,8 +516,6 @@ NtUserCreateWindowStation( InitCursorImpl(); } - DPRINT("Window station successfully created (%wZ)\n", &FullWindowStationName); - ExFreePool(FullWindowStationName.Buffer); return WindowStation; } @@ -569,39 +545,16 @@ NtUserCreateWindowStation( HWINSTA APIENTRY NtUserOpenWindowStation( - PUNICODE_STRING lpszWindowStationName, + POBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK dwDesiredAccess) { - UNICODE_STRING WindowStationName; HWINSTA WindowStation; - OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; - /* - * Generate full window station name - */ - - if (!IntGetFullWindowStationName(&WindowStationName, lpszWindowStationName, - NULL)) - { - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return 0; - } - - DPRINT("Trying to open window station (%wZ)\n", &WindowStationName); - - /* Initialize ObjectAttributes for the window station object */ - InitializeObjectAttributes( - &ObjectAttributes, - &WindowStationName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = ObOpenObjectByName( - &ObjectAttributes, + ObjectAttributes, ExWindowStationObjectType, - KernelMode, + UserMode, NULL, dwDesiredAccess, NULL, @@ -610,13 +563,9 @@ NtUserOpenWindowStation( if (!NT_SUCCESS(Status)) { SetLastNtError(Status); - ExFreePool(WindowStationName.Buffer); return 0; } - DPRINT("Successfully opened window station (%wZ)\n", &WindowStationName); - ExFreePool(WindowStationName.Buffer); - return WindowStation; } @@ -981,6 +930,57 @@ IntGetWinStaObj(VOID) return WinStaObj; } +BOOL FASTCALL +UserSetProcessWindowStation(HWINSTA hWindowStation) +{ + PPROCESSINFO ppi; + NTSTATUS Status; + HWINSTA hwinstaOld; + PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta; + + ppi = PsGetCurrentProcessWin32Process(); + + if(hWindowStation !=NULL) + { + Status = IntValidateWindowStationHandle( hWindowStation, + KernelMode, + 0, + &NewWinSta); + if (!NT_SUCCESS(Status)) + { + DPRINT("Validation of window station handle (0x%X) failed\n", + hWindowStation); + SetLastNtError(Status); + return FALSE; + } + } + + OldWinSta = ppi->prpwinsta; + hwinstaOld = ppi->hwinsta; + + /* + * FIXME - don't allow changing the window station if there are threads that are attached to desktops and own gui objects + */ + + InterlockedExchangePointer(&PsGetCurrentProcess()->Win32WindowStation, hWindowStation); + + ppi->prpwinsta = NewWinSta; + ppi->hwinsta = hWindowStation; + + + if(OldWinSta != NULL) + { + ObDereferenceObject(OldWinSta); + } + + if(hwinstaOld != NULL) + { + ZwClose(hwinstaOld); + } + + return TRUE; +} + /* * NtUserSetProcessWindowStation * @@ -1000,44 +1000,15 @@ IntGetWinStaObj(VOID) BOOL APIENTRY NtUserSetProcessWindowStation(HWINSTA hWindowStation) { - PWINSTATION_OBJECT NewWinSta; - NTSTATUS Status; + BOOL ret; - DPRINT("About to set process window station with handle (0x%X)\n", - hWindowStation); + UserEnterExclusive(); - if(PsGetCurrentProcess() == CsrProcess) - { - DPRINT1("CSRSS is not allowed to change it's window station!!!\n"); - EngSetLastError(ERROR_ACCESS_DENIED); - return FALSE; - } + ret = UserSetProcessWindowStation(hWindowStation); - Status = IntValidateWindowStationHandle( - hWindowStation, - KernelMode, - 0, - &NewWinSta); + UserLeave(); - if (!NT_SUCCESS(Status)) - { - DPRINT("Validation of window station handle (0x%X) failed\n", - hWindowStation); - SetLastNtError(Status); - return FALSE; - } - - /* - * FIXME - don't allow changing the window station if there are threads that are attached to desktops and own gui objects - */ - - /* FIXME - dereference the old window station, etc... */ - InterlockedExchangePointer(&PsGetCurrentProcess()->Win32WindowStation, hWindowStation); - - DPRINT("PsGetCurrentProcess()->Win32WindowStation 0x%X\n", - PsGetCurrentProcess()->Win32WindowStation); - - return TRUE; + return ret; } /* @@ -1139,21 +1110,13 @@ BuildWindowStationNameList( OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE DirectoryHandle; - UNICODE_STRING DirectoryName; + UNICODE_STRING DirectoryName = RTL_CONSTANT_STRING(WINSTA_ROOT_NAME); char InitialBuffer[256], *Buffer; ULONG Context, ReturnLength, BufferSize; DWORD EntryCount; POBJECT_DIRECTORY_INFORMATION DirEntry; WCHAR NullWchar; - /* - * Generate name of window station directory - */ - if (!IntGetFullWindowStationName(&DirectoryName, NULL, NULL)) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - /* * Try to open the directory. */ @@ -1169,8 +1132,6 @@ BuildWindowStationNameList( DIRECTORY_QUERY, &ObjectAttributes); - ExFreePool(DirectoryName.Buffer); - if (!NT_SUCCESS(Status)) { return Status; diff --git a/subsystems/win32/win32k/objects/cliprgn.c b/subsystems/win32/win32k/objects/cliprgn.c index 95e0e5cced9..7294f2b31fd 100644 --- a/subsystems/win32/win32k/objects/cliprgn.c +++ b/subsystems/win32/win32k/objects/cliprgn.c @@ -26,20 +26,13 @@ int FASTCALL CLIPPING_UpdateGCRegion(DC* Dc) { PROSRGNDATA CombinedRegion; - HRGN hRgnVis = Dc->prgnVis->BaseObject.hHmgr; + HRGN hRgnVis; // would prefer this, but the rest of the code sucks // ASSERT(Dc->rosdc.hGCClipRgn); // ASSERT(Dc->rosdc.hClipRgn); - if (!Dc->prgnVis) - { - DPRINT1("Warning, prgnVis is NULL!\n"); - } - else - { - hRgnVis = Dc->prgnVis->BaseObject.hHmgr ; - } - + ASSERT(Dc->prgnVis); + hRgnVis = Dc->prgnVis->BaseObject.hHmgr; if (Dc->rosdc.hGCClipRgn == NULL) Dc->rosdc.hGCClipRgn = IntSysCreateRectRgn(0, 0, 0, 0); diff --git a/subsystems/win32/win32k/objects/dcobjs.c b/subsystems/win32/win32k/objects/dcobjs.c index 7e6870be76f..6a7cf20661b 100644 --- a/subsystems/win32/win32k/objects/dcobjs.c +++ b/subsystems/win32/win32k/objects/dcobjs.c @@ -367,7 +367,7 @@ NtGdiSelectBitmap( REGION_FreeRgnByHandle(hVisRgn); } - /* Return the old bitmp handle */ + /* Return the old bitmap handle */ return hbmpOld; } @@ -522,7 +522,7 @@ NtGdiGetRandomRgn( pdc = DC_LockDc(hdc); if (!pdc) { - EngSetLastError(ERROR_INVALID_HANDLE); + EngSetLastError(ERROR_INVALID_PARAMETER); return -1; } diff --git a/subsystems/win32/win32k/objects/fillshap.c b/subsystems/win32/win32k/objects/fillshap.c index ae071d2cddf..0fb1695c1b6 100644 --- a/subsystems/win32/win32k/objects/fillshap.c +++ b/subsystems/win32/win32k/objects/fillshap.c @@ -545,10 +545,11 @@ IntRectangle(PDC dc, return PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect ); } - DestRect.left = LeftRect; - DestRect.right = RightRect; - DestRect.top = TopRect; - DestRect.bottom = BottomRect; + /* Make sure rectangle is not inverted */ + DestRect.left = min(LeftRect, RightRect); + DestRect.right = max(LeftRect, RightRect); + DestRect.top = min(TopRect, BottomRect); + DestRect.bottom = max(TopRect, BottomRect); IntLPtoDP(dc, (LPPOINT)&DestRect, 2); diff --git a/subsystems/win32/win32k/objects/freetype.c b/subsystems/win32/win32k/objects/freetype.c index 4e941ee2047..c7086fd39d4 100644 --- a/subsystems/win32/win32k/objects/freetype.c +++ b/subsystems/win32/win32k/objects/freetype.c @@ -1078,12 +1078,16 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, PCWSTR FaceName, PFONTGDI FontGDI) ExFreePoolWithTag(Otm, GDITAG_TEXT); - wcsncpy(Info->EnumLogFontEx.elfLogFont.lfFaceName, FaceName, LF_FACESIZE); - wcsncpy(Info->EnumLogFontEx.elfFullName, FaceName, LF_FULLFACESIZE); + RtlStringCbCopyW(Info->EnumLogFontEx.elfLogFont.lfFaceName, + sizeof(Info->EnumLogFontEx.elfLogFont.lfFaceName), + FaceName); + RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName, + sizeof(Info->EnumLogFontEx.elfFullName), + FaceName); RtlInitAnsiString(&StyleA, FontGDI->face->style_name); - RtlAnsiStringToUnicodeString(&StyleW, &StyleA, TRUE); - wcsncpy(Info->EnumLogFontEx.elfStyle, StyleW.Buffer, LF_FACESIZE); - RtlFreeUnicodeString(&StyleW); + StyleW.Buffer = Info->EnumLogFontEx.elfStyle; + StyleW.MaximumLength = sizeof(Info->EnumLogFontEx.elfStyle); + RtlAnsiStringToUnicodeString(&StyleW, &StyleA, FALSE); Info->EnumLogFontEx.elfLogFont.lfCharSet = DEFAULT_CHARSET; Info->EnumLogFontEx.elfScript[0] = L'\0'; @@ -1267,8 +1271,10 @@ FontFamilyInfoQueryRegistryCallback(IN PWSTR ValueName, IN ULONG ValueType, if (InfoContext->Count < InfoContext->Size) { InfoContext->Info[InfoContext->Count] = InfoContext->Info[Existing]; - wcsncpy(InfoContext->Info[InfoContext->Count].EnumLogFontEx.elfLogFont.lfFaceName, - RegistryName.Buffer, LF_FACESIZE); + RtlStringCbCopyNW(InfoContext->Info[InfoContext->Count].EnumLogFontEx.elfLogFont.lfFaceName, + sizeof(InfoContext->Info[InfoContext->Count].EnumLogFontEx.elfLogFont.lfFaceName), + RegistryName.Buffer, + RegistryName.Length); } InfoContext->Count++; return STATUS_SUCCESS; @@ -2643,7 +2649,7 @@ FindBestFontFromList(FONTOBJ **FontObj, UINT *MatchScore, LOGFONTW *LogFont, PFONT_ENTRY CurrentEntry; FONTGDI *FontGDI; UINT Score; - +ASSERT(FontObj && MatchScore && LogFont && FaceName && Head); Entry = Head->Flink; while (Entry != Head) { diff --git a/subsystems/win32/win32k/objects/rect.c b/subsystems/win32/win32k/objects/rect.c index e3012185ca7..9fd5cdaefc6 100644 --- a/subsystems/win32/win32k/objects/rect.c +++ b/subsystems/win32/win32k/objects/rect.c @@ -16,7 +16,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* $Id$ */ #include diff --git a/subsystems/win32/win32k/objects/region.c b/subsystems/win32/win32k/objects/region.c index d1b00441065..d0bd3bafc61 100644 --- a/subsystems/win32/win32k/objects/region.c +++ b/subsystems/win32/win32k/objects/region.c @@ -3204,6 +3204,27 @@ IntCreatePolyPolygonRgn( return hrgn; } +BOOL +FASTCALL +IntRectInRegion( + HRGN hRgn, + LPRECTL rc +) +{ + PROSRGNDATA Rgn; + BOOL Ret; + + if (!(Rgn = RGNOBJAPI_Lock(hRgn, NULL))) + { + return ERROR; + } + + Ret = REGION_RectInRegion(Rgn, rc); + RGNOBJAPI_Unlock(Rgn); + return Ret; +} + + // // NtGdi Exported Functions // @@ -3765,16 +3786,9 @@ NtGdiRectInRegion( LPRECTL unsaferc ) { - PROSRGNDATA Rgn; RECTL rc = {0}; - BOOL Ret; NTSTATUS Status = STATUS_SUCCESS; - if (!(Rgn = RGNOBJAPI_Lock(hRgn, NULL))) - { - return ERROR; - } - _SEH2_TRY { ProbeForRead(unsaferc, sizeof(RECT), 1); @@ -3788,15 +3802,12 @@ NtGdiRectInRegion( if (!NT_SUCCESS(Status)) { - RGNOBJAPI_Unlock(Rgn); SetLastNtError(Status); DPRINT1("NtGdiRectInRegion: bogus rc\n"); return ERROR; } - Ret = REGION_RectInRegion(Rgn, &rc); - RGNOBJAPI_Unlock(Rgn); - return Ret; + return IntRectInRegion(hRgn, &rc); } BOOL diff --git a/subsystems/win32/win32k/objects/stockobj.c b/subsystems/win32/win32k/objects/stockobj.c index 1ef2bc7d3bb..1a4a65e3b9f 100644 --- a/subsystems/win32/win32k/objects/stockobj.c +++ b/subsystems/win32/win32k/objects/stockobj.c @@ -216,8 +216,8 @@ NtGdiGetStockObject(INT Object) return ((Object < 0) || (NB_STOCK_OBJECTS <= Object)) ? NULL : StockObjects[Object]; } -BOOL FASTCALL -IntSetSysColors(UINT nColors, INT *Elements, COLORREF *Colors) +VOID FASTCALL +IntSetSysColors(UINT nColors, CONST INT *Elements, CONST COLORREF *Colors) { UINT i; @@ -231,7 +231,6 @@ IntSetSysColors(UINT nColors, INT *Elements, COLORREF *Colors) Elements++; Colors++; } - return nColors > 0; } HGDIOBJ FASTCALL diff --git a/subsystems/win32/win32k/pch.h b/subsystems/win32/win32k/pch.h index 479f00a195e..b703d6b868b 100644 --- a/subsystems/win32/win32k/pch.h +++ b/subsystems/win32/win32k/pch.h @@ -18,6 +18,7 @@ #include #include #include +#include /* Win32 Headers */ /* FIXME: Defines in winbase.h that we need... */