diff --git a/base/applications/games/spider/spigame.cpp b/base/applications/games/spider/spigame.cpp index bf7465bf685..f56f20616ab 100644 --- a/base/applications/games/spider/spigame.cpp +++ b/base/applications/games/spider/spigame.cpp @@ -249,7 +249,8 @@ bool CARDLIBPROC StackDropProc(CardRegion &stackobj, CardStack &dragcards) int i, max = NUM_ONECOLOR_CARDS - dragcards.NumCards() - 1; /* Dragged cards have been checked to be in order, check stack cards */ - if (stackLookingGood(mystack, max)) + if (mystack[0].Suit() == dragcard.Suit() && + stackLookingGood(mystack, max)) { CardStack s = stackobj.GetCardStack(); CardStack f; @@ -279,8 +280,8 @@ void CreateSpider() { int i, pos; - /* Compute the value for yRowStackCardOffset based on the height of the card, so the card number isn't hidden on larger cards */ - yRowStackCardOffset = (int)(__cardheight / 6.7); + /* Compute the value for yRowStackCardOffset based on the height of the card, so the card number and suite isn't hidden on larger cards except Ace */ + yRowStackCardOffset = (int)(__cardheight / 6.4); pDeck = SpiderWnd.CreateRegion(0, true, 0, 0, -15, 0); pDeck->SetFaceDirection(CS_FACE_DOWN, 0); diff --git a/base/setup/usetup/lang/fr-FR.h b/base/setup/usetup/lang/fr-FR.h index ba1844cf0f8..460411b6462 100644 --- a/base/setup/usetup/lang/fr-FR.h +++ b/base/setup/usetup/lang/fr-FR.h @@ -30,7 +30,7 @@ static MUI_ENTRY frFRLanguagePageEntries[] = { 8, 11, - " et appuyer sur ENTER.", + " et appuyer sur ENTRE.", TEXT_STYLE_NORMAL }, { @@ -42,7 +42,7 @@ static MUI_ENTRY frFRLanguagePageEntries[] = { 0, 0, - " ENTER = Continuer F3 = Quitter", + " ENTRE = Continuer F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -82,7 +82,7 @@ static MUI_ENTRY frFRWelcomePageEntries[] = { 8, 15, - "\x07 Appuyer sur ENTER pour installer ReactOS.", + "\x07 Appuyer sur ENTRE pour installer ReactOS.", TEXT_STYLE_NORMAL }, { @@ -118,7 +118,7 @@ static MUI_ENTRY frFRWelcomePageEntries[] = { 0, 0, - " ENTER = Continuer R = Rparer F3 = Quitter", + " ENTRE = Continuer R = Rparer F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -206,7 +206,7 @@ static MUI_ENTRY frFRIntroPageEntries[] = { 8, 23, - "\x07 Appuyer sur ENTER pour installer ReactOS.", + "\x07 Appuyer sur ENTRE pour installer ReactOS.", TEXT_STYLE_NORMAL }, { @@ -218,7 +218,7 @@ static MUI_ENTRY frFRIntroPageEntries[] = { 0, 0, - " ENTER = Continuer F3 = Quitter", + " ENTRE = Continuer F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -342,7 +342,7 @@ static MUI_ENTRY frFRLicensePageEntries[] = { 0, 0, - " ENTER = Retour", + " ENTRE = Retour", TEXT_TYPE_STATUS }, { @@ -417,7 +417,7 @@ static MUI_ENTRY frFRDevicePageEntries[] = { 6, 21, - "Appuyer sur ENTER pour choisir un autre rglage.", + "Appuyer sur ENTRE pour choisir un autre rglage.", TEXT_STYLE_NORMAL }, { @@ -429,13 +429,13 @@ static MUI_ENTRY frFRDevicePageEntries[] = { 6, 24, - "ces rglages matriels\" et appuyer sur ENTER.", + "ces rglages matriels\" et appuyer sur ENTRE.", TEXT_STYLE_NORMAL }, { 0, 0, - " ENTER = Continuer F3 = Quitter", + " ENTRE = Continuer F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -493,19 +493,19 @@ static MUI_ENTRY frFRRepairPageEntries[] = { 8, 19, - "\x07 Appuyer sur ESC pour retourner la page principale.", + "\x07 Appuyer sur CHAP pour retourner la page principale.", TEXT_STYLE_NORMAL }, { 8, 21, - "\x07 Appuyer sur ENTER pour redmarrer votre ordinateur.", + "\x07 Appuyer sur ENTRE pour redmarrer votre ordinateur.", TEXT_STYLE_NORMAL }, { 0, 0, - " ESC = Page principale ENTER = Redmarrer", + " CHAP = Page principale ENTRE = Redmarrer", TEXT_TYPE_STATUS }, { @@ -538,13 +538,13 @@ static MUI_ENTRY frFRComputerPageEntries[] = { 8, 11, - " Puis appuyer sur ENTER.", + " Puis appuyer sur ENTRE.", TEXT_STYLE_NORMAL }, { 8, 13, - "\x07 Appuyer sur ESC pour revenir la page prcdente sans changer", + "\x07 Appuyer sur CHAP pour revenir la page prcdente sans changer", TEXT_STYLE_NORMAL }, { @@ -556,7 +556,7 @@ static MUI_ENTRY frFRComputerPageEntries[] = { 0, 0, - " ENTER = Continuer ESC = Annuler F3 = Quitter", + " ENTRE = Continuer CHAP = Annuler F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -636,7 +636,7 @@ static MUI_ENTRY frFRQuitPageEntries[] = { 10, 11, - "Appuyer sur ENTER pour redmarrer votre ordinateur.", + "Appuyer sur ENTRE pour redmarrer votre ordinateur.", TEXT_STYLE_NORMAL }, { @@ -675,13 +675,13 @@ static MUI_ENTRY frFRDisplayPageEntries[] = { 8, 11, - " Appuyer sur ENTER.", + " Appuyer sur ENTRE.", TEXT_STYLE_NORMAL }, { 8, 13, - "\x07 Appuyer sur ESC pour revenir la page prcdente sans changer", + "\x07 Appuyer sur CHAP pour revenir la page prcdente sans changer", TEXT_STYLE_NORMAL }, { @@ -693,7 +693,7 @@ static MUI_ENTRY frFRDisplayPageEntries[] = { 0, 0, - " ENTER = Continuer ESC = Annuler F3 = Quitter", + " ENTRE = Continuer CHAP = Annuler F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -733,13 +733,13 @@ static MUI_ENTRY frFRSuccessPageEntries[] = { 10, 11, - "Appuyer sur ENTER pour redmarrer votre ordinateur.", + "Appuyer sur ENTRE pour redmarrer votre ordinateur.", TEXT_STYLE_NORMAL }, { 0, 0, - " ENTER = Redmarrer l'ordinateur", + " ENTRE = Redmarrer l'ordinateur", TEXT_TYPE_STATUS }, { @@ -779,13 +779,13 @@ static MUI_ENTRY frFRBootPageEntries[] = { 6, 14, - "appuyer sur ENTER.", + "appuyer sur ENTRE.", TEXT_STYLE_NORMAL, }, { 0, 0, - " ENTER = Continuer F3 = Quitter", + " ENTRE = Continuer F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -826,7 +826,7 @@ static MUI_ENTRY frFRSelectPartitionEntries[] = { 8, 13, - "\x07 Appuyer sur ENTER pour installer ReactOS sur la partition choisie.", + "\x07 Appuyer sur ENTRE pour installer ReactOS sur la partition choisie.", TEXT_STYLE_NORMAL }, { @@ -872,13 +872,13 @@ static MUI_ENTRY frFRFormatPartitionEntries[] = { 6, 10, - "Setup va formater la partition. Appuyer sur ENTER pour continuer.", + "Setup va formater la partition. Appuyer sur ENTRE pour continuer.", TEXT_STYLE_NORMAL }, { 0, 0, - " ENTER = Continuer F3 = Quitter", + " ENTRE = Continuer F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -930,7 +930,7 @@ static MUI_ENTRY frFRInstallDirectoryEntries[] = { 0, 0, - " ENTER = Continuer F3 = Quitter", + " ENTRE = Continuer F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -1022,7 +1022,7 @@ static MUI_ENTRY frFRBootLoaderEntries[] = { 0, 0, - " ENTER = Continuer F3 = Quitter", + " ENTRE = Continuer F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -1056,13 +1056,13 @@ static MUI_ENTRY frFRKeyboardSettingsEntries[] = { 8, 11, - " puis appuyez sur ENTER.", + " puis appuyez sur ENTRE.", TEXT_STYLE_NORMAL }, { 8, 13, - "\x07 Appuyez sur ESC pour revenir a la page prcdente sans changer", + "\x07 Appuyez sur CHAP pour revenir a la page prcdente sans changer", TEXT_STYLE_NORMAL }, { @@ -1074,7 +1074,7 @@ static MUI_ENTRY frFRKeyboardSettingsEntries[] = { 0, 0, - " ENTER = Continuer ESC = Annuler F3 = Quitter", + " ENTRE = Continuer CHAP = Annuler F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -1108,13 +1108,13 @@ static MUI_ENTRY frFRLayoutSettingsEntries[] = { 8, 11, - " choisie. Puis appuyez sur ENTER.", + " choisie. Puis appuyez sur ENTRE.", TEXT_STYLE_NORMAL }, { 8, 13, - "\x07 Appuyez sur ESC pour revenir a la page prcdente sans changer", + "\x07 Appuyez sur CHAP pour revenir a la page prcdente sans changer", TEXT_STYLE_NORMAL }, { @@ -1126,7 +1126,7 @@ static MUI_ENTRY frFRLayoutSettingsEntries[] = { 0, 0, - " ENTER = Continuer ESC = Annuler F3 = Quitter", + " ENTRE = Continuer CHAP = Annuler F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -1190,19 +1190,19 @@ static MUI_ENTRY frFRSelectFSEntries[] = { 8, 21, - "\x07 Appuyez sur ENTER pour formater la partition.", + "\x07 Appuyez sur ENTRE pour formater la partition.", 0 }, { 8, 23, - "\x07 Appuyez sur ESC pour slectionner une autre partition.", + "\x07 Appuyez sur CHAP pour slectionner une autre partition.", 0 }, { 0, 0, - " ENTER = Continuer ESC = Annuler F3 = Quitter", + " ENTRE = Continuer CHAP = Annuler F3 = Quitter", TEXT_TYPE_STATUS }, @@ -1243,13 +1243,13 @@ static MUI_ENTRY frFRDeletePartitionEntries[] = { 8, 21, - "\x07 Appuyez sur ESC pour annuler.", + "\x07 Appuyez sur CHAP pour annuler.", TEXT_STYLE_NORMAL }, { 0, 0, - " D = Supprimer la Partition ESC = Annuler F3 = Quitter", + " D = Supprimer la Partition CHAP = Annuler F3 = Quitter", TEXT_TYPE_STATUS }, { @@ -1265,7 +1265,7 @@ static MUI_ENTRY frFRRegistryEntries[] = { 4, 3, - " ReactOS " KERNEL_VERSION_STR " Setup ", + " Installation de ReactOS " KERNEL_VERSION_STR " ", TEXT_STYLE_UNDERLINE }, { @@ -1297,64 +1297,64 @@ MUI_ERROR frFRErrorEntries[] = "ordinateur. Si vous quittez Setup maintenant, vous devrez\n" "lancer Setup de nouveau pour installer ReactOS.\n" "\n" - " \x07 Appuyer sur ENTER pour continuer Setup.\n" + " \x07 Appuyer sur ENTRE pour continuer Setup.\n" " \x07 Appuyer sur F3 pour quitter Setup.", - "F3= Quitter ENTER = Continuer" + "F3= Quitter ENTRE = Continuer" }, { //ERROR_NO_HDD "Setup n'a pu trouver un disque dur.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_NO_SOURCE_DRIVE "Setup n'a pu trouver son lecteur source.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_LOAD_TXTSETUPSIF "Setup n'a pas russi charger le fichier TXTSETUP.SIF.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_CORRUPT_TXTSETUPSIF "Setup a trouv un fichier TXTSETUP.SIF corrompu.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_SIGNATURE_TXTSETUPSIF, "Setup a trouv une signature invalide dans TXTSETUP.SIF.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_DRIVE_INFORMATION "Setup n'a pu rcuprer les informations du disque systme.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_WRITE_BOOT, "Echec de l'installation du code de dmarrage FAT sur la partition systme.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_LOAD_COMPUTER, "Setup n'a pu charger la liste de type d'ordinateurs.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_LOAD_DISPLAY, "Setup n'a pu charger la liste de rglages des crans.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_LOAD_KEYBOARD, "Setup n'a pu charger la liste de types de claviers.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_LOAD_KBLAYOUT, "Setup n'a pu charger la liste de dispositions de claviers.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_WARN_PARTITION, @@ -1364,8 +1364,8 @@ MUI_ERROR frFRErrorEntries[] = "Crer ou effacer des partitions peut dtruire la table de partition.\n" "\n" " \x07 Appuyer sur F3 pour quitter Setup." - " \x07 Appuyer sur ENTER pour continuer Setup.", - "F3= Quitter ENTER = Continuer" + " \x07 Appuyer sur ENTRE pour continuer Setup.", + "F3= Quitter ENTRE = Continuer" }, { //ERROR_NEW_PARTITION, @@ -1385,115 +1385,115 @@ MUI_ERROR frFRErrorEntries[] = { //ERROR_INSTALL_BOOTCODE, "Echec de l'installation du code de dmarrage FAT sur la partition systme.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_NO_FLOPPY, "Pas de disque dans le lecteur A:.", - "ENTER = Continuer" + "ENTRE = Continuer" }, { //ERROR_UPDATE_KBSETTINGS, "Setup n'a pu mettre jour les rglages de disposition du clavier.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_UPDATE_DISPLAY_SETTINGS, "Setup n'a pu mettre jour les rglages de l'cran.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_IMPORT_HIVE, "Setup n'a pu importer un fichier ruche.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_FIND_REGISTRY "Setup n'a pu trouver les fichiers de la base de registres.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_CREATE_HIVE, "Setup n'a pu crer les ruches de la base de registres.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_INITIALIZE_REGISTRY, "Setup n'a pu initialiser la base de registres.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_INVALID_CABINET_INF, "Le Cabinet n'a pas de fichier inf valide.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_CABINET_MISSING, "Cabinet non trouv.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_CABINET_SCRIPT, "Cabinet n'a pas de script de setup.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_COPY_QUEUE, "Setup n'a pu ouvrir la file d'attente de copie de fichiers.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_CREATE_DIR, "Setup n'a pu crer les rpertoires d'installation.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_TXTSETUP_SECTION, "Setup n'a pu trouver la section 'Directories'\n" "dans TXTSETUP.SIF.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_CABINET_SECTION, "Setup n'a pu trouver la section 'Directories\n" "dans le cabinet.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_CREATE_INSTALL_DIR "Setup n'a pu crer le rpertoire d'installation.", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_FIND_SETUPDATA, "Setup n'a pu trouver la section 'SetupData'\n" "dans TXTSETUP.SIF.\n", - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_WRITE_PTABLE, "Setup n'a pu crire les tables de partition.\n" - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_ADDING_CODEPAGE, "Setup n'a pu ajouter la page de codes la base de registres.\n" - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_UPDATE_LOCALESETTINGS, "Setup n'a pu changer la langue systme.\n" - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_ADDING_KBLAYOUTS, "Setup n'a pas pu ajouter les dispositions de clavier au registre.\n" - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_UPDATE_GEOID, "Setup n'a pas pu dfinir la geo id.\n" - "ENTER = Redmarrer l'ordinateur" + "ENTRE = Redmarrer l'ordinateur" }, { //ERROR_INSUFFICIENT_DISKSPACE, @@ -1613,9 +1613,9 @@ MUI_STRING frFRStrings[] = {STRING_PLEASEWAIT, " Veuillez patienter..."}, {STRING_INSTALLCREATEPARTITION, - " ENTER = Installer C = Crer Partition F3 = Quitter"}, + " ENTRE = Installer C = Crer Partition F3 = Quitter"}, {STRING_INSTALLDELETEPARTITION, - " ENTER = Installer D = Supprimer Partition F3 = Quitter"}, + " ENTRE = Installer D = Supprimer Partition F3 = Quitter"}, {STRING_PARTITIONSIZE, "Taille de la nouvelle partition :"}, {STRING_CHOOSENEWPARTITION, @@ -1623,7 +1623,7 @@ MUI_STRING frFRStrings[] = {STRING_HDDSIZE, "Veuillez entrer la taille de la nouvelle partition en mgaoctets."}, {STRING_CREATEPARTITION, - " ENTER = Crer Partition ESC = Annuler F3 = Quitter"}, + " ENTRE = Crer Partition CHAP = Annuler F3 = Quitter"}, {STRING_PARTFORMAT, "Cette Partition sera ensuite formate."}, {STRING_NONFORMATTEDPART, @@ -1633,9 +1633,9 @@ MUI_STRING frFRStrings[] = {STRING_CHECKINGPART, "Setup vrifie la partition slectionne."}, {STRING_QUITCONTINUE, - "F3= Quitter ENTER = Continuer"}, + "F3= Quitter ENTRE = Continuer"}, {STRING_REBOOTCOMPUTER, - "ENTER = Redmarrer l'ordinateur"}, + "ENTRE = Redmarrer l'ordinateur"}, {STRING_TXTSETUPFAILED, "Setup n'a pu trouver la section '%S'\ndans TXTSETUP.SIF.\n"}, {STRING_COPYING, @@ -1657,7 +1657,7 @@ MUI_STRING frFRStrings[] = {STRING_DONE, " Termin..."}, {STRING_REBOOTCOMPUTER2, - " ENTER = Redmarrer l'ordinateur"}, + " ENTRE = Redmarrer l'ordinateur"}, {STRING_CONSOLEFAIL1, "Impossible d'ouvrir la console\n\n"}, {STRING_CONSOLEFAIL2, diff --git a/base/setup/usetup/lang/it-IT.h b/base/setup/usetup/lang/it-IT.h index 076de5efa41..7741e832f4c 100644 --- a/base/setup/usetup/lang/it-IT.h +++ b/base/setup/usetup/lang/it-IT.h @@ -1253,7 +1253,7 @@ static MUI_ENTRY itITRegistryEntries[] = { 4, 3, - " ReactOS " KERNEL_VERSION_STR " Setup ", + " Installazione di ReactOS " KERNEL_VERSION_STR " ", TEXT_STYLE_UNDERLINE }, { diff --git a/boot/bootdata/bootcd.ini b/boot/bootdata/bootcd.ini index cf8062e8656..2c04ff22441 100644 --- a/boot/bootdata/bootcd.ini +++ b/boot/bootdata/bootcd.ini @@ -13,16 +13,11 @@ TitleBoxTextColor=White TitleBoxColor=Red MessageBoxTextColor=White MessageBoxColor=Blue -MenuTextColor=Gray -MenuColor=Black -TextColor=Gray +MenuTextColor=White +MenuColor=Blue +TextColor=Yellow SelectedTextColor=Black SelectedColor=Gray -ShowTime=No -MenuBox=No -CenterMenu=No -MinimalUI=Yes -TimeText=Seconds until highlighted choice will be started automatically: [Operating Systems] Setup="Setup" diff --git a/boot/bootdata/livecd.ini b/boot/bootdata/livecd.ini index af4ec4fea83..6a208ce87e0 100644 --- a/boot/bootdata/livecd.ini +++ b/boot/bootdata/livecd.ini @@ -1,6 +1,6 @@ [FREELOADER] DefaultOS=LiveCD_Debug -TimeOut=3 +TimeOut=5 [Display] TitleText=ReactOS LiveCD diff --git a/boot/freeldr/freeldr/arch/i386/archmach.c b/boot/freeldr/freeldr/arch/i386/archmach.c index bc7952a8fd1..46915ab40c0 100644 --- a/boot/freeldr/freeldr/arch/i386/archmach.c +++ b/boot/freeldr/freeldr/arch/i386/archmach.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/custom.c b/boot/freeldr/freeldr/arch/i386/custom.c index a53d42301af..973c32674e1 100644 --- a/boot/freeldr/freeldr/arch/i386/custom.c +++ b/boot/freeldr/freeldr/arch/i386/custom.c @@ -43,7 +43,13 @@ VOID OptionMenuCustomBoot(VOID) ULONG CustomBootMenuCount = sizeof(CustomBootMenuList) / sizeof(CustomBootMenuList[0]); ULONG SelectedMenuItem; - if (!UiDisplayMenu(CustomBootMenuList, CustomBootMenuCount, 0, -1, &SelectedMenuItem, TRUE, NULL)) + if (!UiDisplayMenu("Please choose a boot method:", + CustomBootMenuList, + CustomBootMenuCount, + 0, -1, + &SelectedMenuItem, + TRUE, + NULL)) { // The user pressed ESC return; diff --git a/boot/freeldr/freeldr/arch/i386/machpc.c b/boot/freeldr/freeldr/arch/i386/machpc.c index 9cbd719c8b9..f9da6cfbb19 100644 --- a/boot/freeldr/freeldr/arch/i386/machpc.c +++ b/boot/freeldr/freeldr/arch/i386/machpc.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/machxbox.c b/boot/freeldr/freeldr/arch/i386/machxbox.c index dccd9a59b77..2930392d7b4 100644 --- a/boot/freeldr/freeldr/arch/i386/machxbox.c +++ b/boot/freeldr/freeldr/arch/i386/machxbox.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/pccons.c b/boot/freeldr/freeldr/arch/i386/pccons.c index b4cb5ce8a55..4d056d99290 100644 --- a/boot/freeldr/freeldr/arch/i386/pccons.c +++ b/boot/freeldr/freeldr/arch/i386/pccons.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/pcrtc.c b/boot/freeldr/freeldr/arch/i386/pcrtc.c index 6b53da8c066..58ac90b3c4d 100644 --- a/boot/freeldr/freeldr/arch/i386/pcrtc.c +++ b/boot/freeldr/freeldr/arch/i386/pcrtc.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/pcvideo.c b/boot/freeldr/freeldr/arch/i386/pcvideo.c index 098f558bb30..bb47c63e554 100644 --- a/boot/freeldr/freeldr/arch/i386/pcvideo.c +++ b/boot/freeldr/freeldr/arch/i386/pcvideo.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/xboxcons.c b/boot/freeldr/freeldr/arch/i386/xboxcons.c index 4bb9fb4eaaa..769a8f16b6d 100644 --- a/boot/freeldr/freeldr/arch/i386/xboxcons.c +++ b/boot/freeldr/freeldr/arch/i386/xboxcons.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/xboxdisk.c b/boot/freeldr/freeldr/arch/i386/xboxdisk.c index 99276bb4bb4..4e1c6dc553b 100644 --- a/boot/freeldr/freeldr/arch/i386/xboxdisk.c +++ b/boot/freeldr/freeldr/arch/i386/xboxdisk.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/xboxfont.c b/boot/freeldr/freeldr/arch/i386/xboxfont.c index 9a2daf69b53..0e67d1ff7ac 100644 --- a/boot/freeldr/freeldr/arch/i386/xboxfont.c +++ b/boot/freeldr/freeldr/arch/i386/xboxfont.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/xboxhw.c b/boot/freeldr/freeldr/arch/i386/xboxhw.c index 4b8597f30b9..0332439357d 100644 --- a/boot/freeldr/freeldr/arch/i386/xboxhw.c +++ b/boot/freeldr/freeldr/arch/i386/xboxhw.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/xboxi2c.c b/boot/freeldr/freeldr/arch/i386/xboxi2c.c index 4bb5145e726..3267b353cbe 100644 --- a/boot/freeldr/freeldr/arch/i386/xboxi2c.c +++ b/boot/freeldr/freeldr/arch/i386/xboxi2c.c @@ -1,5 +1,4 @@ -/* $Id: xboxhw.c 19190 2005-11-13 04:50:55Z fireball $ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/xboxmem.c b/boot/freeldr/freeldr/arch/i386/xboxmem.c index 05c760c673c..36c2f0bf108 100644 --- a/boot/freeldr/freeldr/arch/i386/xboxmem.c +++ b/boot/freeldr/freeldr/arch/i386/xboxmem.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/xboxrtc.c b/boot/freeldr/freeldr/arch/i386/xboxrtc.c index d8cc332bc97..946c2d816b4 100644 --- a/boot/freeldr/freeldr/arch/i386/xboxrtc.c +++ b/boot/freeldr/freeldr/arch/i386/xboxrtc.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/arch/i386/xboxvideo.c b/boot/freeldr/freeldr/arch/i386/xboxvideo.c index d1d3f86ebf6..866db6633f3 100644 --- a/boot/freeldr/freeldr/arch/i386/xboxvideo.c +++ b/boot/freeldr/freeldr/arch/i386/xboxvideo.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c index 6426eca0ec7..2295e50cd5b 100644 --- a/boot/freeldr/freeldr/bootmgr.c +++ b/boot/freeldr/freeldr/bootmgr.c @@ -191,7 +191,14 @@ VOID RunLoader(VOID) UiDrawBackdrop(); // Show the operating system list menu - if (!UiDisplayMenu(OperatingSystemDisplayNames, OperatingSystemCount, DefaultOperatingSystem, TimeOut, &SelectedOperatingSystem, FALSE, MainBootMenuKeyPressFilter)) + if (!UiDisplayMenu("Please select the operating system to start:", + OperatingSystemDisplayNames, + OperatingSystemCount, + DefaultOperatingSystem, + TimeOut, + &SelectedOperatingSystem, + FALSE, + MainBootMenuKeyPressFilter)) { UiMessageBox("Press ENTER to reboot."); goto reboot; diff --git a/boot/freeldr/freeldr/include/arch/i386/machxbox.h b/boot/freeldr/freeldr/include/arch/i386/machxbox.h index 26523efbe69..c2a20056976 100644 --- a/boot/freeldr/freeldr/include/arch/i386/machxbox.h +++ b/boot/freeldr/freeldr/include/arch/i386/machxbox.h @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/include/arch/pc/machpc.h b/boot/freeldr/freeldr/include/arch/pc/machpc.h index 01adfecf6a1..6cd31dd7a77 100644 --- a/boot/freeldr/freeldr/include/arch/pc/machpc.h +++ b/boot/freeldr/freeldr/include/arch/pc/machpc.h @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * Copyright (C) 2003 Eric Kohl diff --git a/boot/freeldr/freeldr/include/cmdline.h b/boot/freeldr/freeldr/include/cmdline.h index 05b92f1410c..6797b5610a0 100644 --- a/boot/freeldr/freeldr/include/cmdline.h +++ b/boot/freeldr/freeldr/include/cmdline.h @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLdr boot loader * Copyright (C) 2002, 2003 ReactOS Team * diff --git a/boot/freeldr/freeldr/include/inffile.h b/boot/freeldr/freeldr/include/inffile.h index 89afe6de322..5e36a83d875 100644 --- a/boot/freeldr/freeldr/include/inffile.h +++ b/boot/freeldr/freeldr/include/inffile.h @@ -16,7 +16,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* $Id$ +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS text-mode setup * FILE: subsys/system/usetup/infcache.h diff --git a/boot/freeldr/freeldr/include/ui.h b/boot/freeldr/freeldr/include/ui.h index 1b57fd9e069..9a87e21113f 100644 --- a/boot/freeldr/freeldr/include/ui.h +++ b/boot/freeldr/freeldr/include/ui.h @@ -19,8 +19,8 @@ #pragma once -extern ULONG UiScreenWidth; // Screen Width -extern ULONG UiScreenHeight; // Screen Height +extern ULONG UiScreenWidth; // Screen Width +extern ULONG UiScreenHeight; // Screen Height extern UCHAR UiStatusBarFgColor; // Status bar foreground color extern UCHAR UiStatusBarBgColor; // Status bar background color @@ -42,10 +42,10 @@ extern UCHAR UiEditBoxBgColor; // Edit box text background color extern CHAR UiTitleBoxTitleText[260]; // Title box's title text extern BOOLEAN UiUseSpecialEffects; // Tells us if we should use fade effects -extern BOOLEAN UiCenterMenu; -extern BOOLEAN UiMenuBox; -extern CHAR UiTimeText[]; -extern BOOLEAN UiDrawTime; +extern BOOLEAN UiCenterMenu; +extern BOOLEAN UiMenuBox; +extern CHAR UiTimeText[]; +extern BOOLEAN UiDrawTime; extern const CHAR UiMonthNames[12][15]; @@ -55,7 +55,7 @@ extern const CHAR UiMonthNames[12][15]; // /////////////////////////////////////////////////////////////////////////////////////// BOOLEAN UiInitialize(BOOLEAN ShowGui); // Initialize User-Interface -BOOLEAN SetupUiInitialize(VOID); // Initialize User-Interface +BOOLEAN SetupUiInitialize(VOID); // Initialize Setup User-Interface VOID UiUnInitialize(PCSTR BootText); // Un-initialize User-Interface VOID UiDrawBackdrop(VOID); // Fills the entire screen with a backdrop VOID UiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */); // Fills the area specified with FillChar and Attr @@ -93,7 +93,7 @@ typedef struct tagUI_MENU_INFO UI_MENU_INFO, *PUI_MENU_INFO; typedef BOOLEAN (*UiMenuKeyPressFilterCallback)(ULONG KeyPress); -BOOLEAN UiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); +BOOLEAN UiDisplayMenu(PCSTR MenuTitle, PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); /////////////////////////////////////////////////////////////////////////////////////// // @@ -123,7 +123,7 @@ typedef struct tagUIVTBL VOID (*FadeInBackdrop)(VOID); VOID (*FadeOut)(VOID); - BOOLEAN (*DisplayMenu)(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); + BOOLEAN (*DisplayMenu)(PCSTR MenuTitle, PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); VOID (*DrawMenu)(PUI_MENU_INFO MenuInfo); } UIVTBL, *PUIVTBL; diff --git a/boot/freeldr/freeldr/include/ui/noui.h b/boot/freeldr/freeldr/include/ui/noui.h index de027d7951b..f779db121c0 100644 --- a/boot/freeldr/freeldr/include/ui/noui.h +++ b/boot/freeldr/freeldr/include/ui/noui.h @@ -35,14 +35,11 @@ UCHAR NoUiTextToFillStyle(PCSTR FillStyleText); VOID NoUiFadeInBackdrop(VOID); VOID NoUiFadeOut(VOID); -BOOLEAN NoUiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); -VOID NoUiDrawMenu(PUI_MENU_INFO MenuInfo); - /////////////////////////////////////////////////////////////////////////////////////// // // Menu Functions // /////////////////////////////////////////////////////////////////////////////////////// -BOOLEAN NoUiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); +BOOLEAN NoUiDisplayMenu(PCSTR MenuTitle, PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); VOID NoUiDrawMenu(PUI_MENU_INFO MenuInfo); diff --git a/boot/freeldr/freeldr/include/ui/tui.h b/boot/freeldr/freeldr/include/ui/tui.h index ad7faa4cf8e..3262c1210cb 100644 --- a/boot/freeldr/freeldr/include/ui/tui.h +++ b/boot/freeldr/freeldr/include/ui/tui.h @@ -60,6 +60,8 @@ VOID TuiFadeOut(VOID); // Fades the screen out struct tagUI_MENU_INFO { + PCSTR MenuTitle; + PCSTR *MenuItemList; ULONG MenuItemCount; LONG MenuTimeRemaining; @@ -69,7 +71,6 @@ struct tagUI_MENU_INFO ULONG Top; ULONG Right; ULONG Bottom; - }; VOID NTAPI TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo); @@ -77,7 +78,7 @@ VOID TuiDrawMenu(PUI_MENU_INFO MenuInfo); VOID NTAPI TuiDrawMenuBox(PUI_MENU_INFO MenuInfo); VOID NTAPI TuiDrawMenuItem(PUI_MENU_INFO MenuInfo, ULONG MenuItemNumber); ULONG NTAPI TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo, UiMenuKeyPressFilterCallback KeyPressFilter); -BOOLEAN TuiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); +BOOLEAN TuiDisplayMenu(PCSTR MenuTitle, PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); /* Definitions for corners, depending on HORIZ and VERT */ #define UL (0xda) diff --git a/boot/freeldr/freeldr/inffile/inffile.c b/boot/freeldr/freeldr/inffile/inffile.c index 350261546ea..1b75ed863d7 100644 --- a/boot/freeldr/freeldr/inffile/inffile.c +++ b/boot/freeldr/freeldr/inffile/inffile.c @@ -16,7 +16,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* $Id$ +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS text-mode setup * FILE: subsys/system/usetup/infcache.c diff --git a/boot/freeldr/freeldr/machine.c b/boot/freeldr/freeldr/machine.c index 5dae495d960..9b68c5706a1 100644 --- a/boot/freeldr/freeldr/machine.c +++ b/boot/freeldr/freeldr/machine.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify diff --git a/boot/freeldr/freeldr/options.c b/boot/freeldr/freeldr/options.c index dc6e85c080d..23b9787dcbc 100644 --- a/boot/freeldr/freeldr/options.c +++ b/boot/freeldr/freeldr/options.c @@ -101,7 +101,13 @@ VOID DoOptionsMenu(VOID) ULONG SelectedMenuItem; CHAR DebugChannelString[100]; - if (!UiDisplayMenu(OptionsMenuList, OptionsMenuItemCount, 0, -1, &SelectedMenuItem, TRUE, NULL)) + if (!UiDisplayMenu("Select an option:", + OptionsMenuList, + OptionsMenuItemCount, + 0, -1, + &SelectedMenuItem, + TRUE, + NULL)) { // The user pressed ESC return; diff --git a/boot/freeldr/freeldr/ui/directui.c b/boot/freeldr/freeldr/ui/directui.c index 2a9db377bd6..18e2a821da9 100644 --- a/boot/freeldr/freeldr/ui/directui.c +++ b/boot/freeldr/freeldr/ui/directui.c @@ -52,11 +52,11 @@ BOOLEAN UiInitialize(IN BOOLEAN ShowGui) { ULONG Depth; - - /* Nothing to do */ - if (!ShowGui) return TRUE; - /* Set mode and query size */ + /* Nothing to do */ + if (!ShowGui) return TRUE; + + /* Set mode and query size */ MachVideoSetDisplayMode(NULL, TRUE); MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth); return TRUE; @@ -245,7 +245,7 @@ UiTruncateStringEllipsis(IN PCHAR StringText, IN ULONG MaxChars) { /* If it's too large, just add some ellipsis past the maximum */ - if (strlen(StringText) > MaxChars) strcpy(&StringText[MaxChars - 3], "..."); + if (strlen(StringText) > MaxChars) strcpy(&StringText[MaxChars - 3], "..."); } VOID @@ -273,7 +273,7 @@ UiDrawMenuBox(IN PUI_MENU_INFO MenuInfo) /* Display under the menu directly */ UiDrawText(0, - MenuInfo->Bottom + 3, + MenuInfo->Bottom + 4, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } @@ -288,7 +288,7 @@ UiDrawMenuBox(IN PUI_MENU_INFO MenuInfo) /* Draw this "empty" string to erase */ UiDrawText(0, - MenuInfo->Bottom + 3, + MenuInfo->Bottom + 4, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } @@ -356,14 +356,13 @@ UiDrawMenu(IN PUI_MENU_INFO MenuInfo) /* No GUI status bar text, just minimal text. first to tell the user to choose */ UiDrawText(0, MenuInfo->Top - 2, - "Please select the operating system to start:", + MenuInfo->MenuTitle, ATTR(UiMenuFgColor, UiMenuBgColor)); /* Now tell him how to choose */ UiDrawText(0, MenuInfo->Bottom + 1, - "Use the up and down arrow keys to move the highlight to " - "your choice.", + "Use \x18 and \x19 to move the highlight to your choice.", ATTR(UiMenuFgColor, UiMenuBgColor)); UiDrawText(0, MenuInfo->Bottom + 2, @@ -381,7 +380,10 @@ UiDrawMenu(IN PUI_MENU_INFO MenuInfo) UiDrawMenuBox(MenuInfo); /* Draw each line of the menu */ - for (i = 0; i < MenuInfo->MenuItemCount; i++) UiDrawMenuItem(MenuInfo, i); + for (i = 0; i < MenuInfo->MenuItemCount; i++) + { + UiDrawMenuItem(MenuInfo, i); + } } ULONG @@ -495,7 +497,8 @@ UiCalcMenuBoxSize(IN PUI_MENU_INFO MenuInfo) } BOOLEAN -UiDisplayMenu(IN PCSTR MenuItemList[], +UiDisplayMenu(IN PCSTR MenuTitle, + IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, IN LONG MenuTimeOut, @@ -517,6 +520,7 @@ UiDisplayMenu(IN PCSTR MenuItemList[], } /* Setup the MENU_INFO structure */ + MenuInformation.MenuTitle = MenuTitle; MenuInformation.MenuItemList = MenuItemList; MenuInformation.MenuItemCount = MenuItemCount; MenuInformation.MenuTimeRemaining = MenuTimeOut; @@ -571,4 +575,13 @@ UiDisplayMenu(IN PCSTR MenuItemList[], return TRUE; } + +/* SETUP MODE *****************************************************************/ + +BOOLEAN SetupUiInitialize(VOID) +{ + /* Nothing to do */ + return TRUE; +} + #endif diff --git a/boot/freeldr/freeldr/ui/minitui.c b/boot/freeldr/freeldr/ui/minitui.c index d38f7a5d5dd..e5103047948 100644 --- a/boot/freeldr/freeldr/ui/minitui.c +++ b/boot/freeldr/freeldr/ui/minitui.c @@ -14,13 +14,8 @@ VOID MiniTuiDrawBackdrop(VOID) // // Fill in a black background // - TuiFillArea(0, - 0, - UiScreenWidth - 1, - UiScreenHeight - 1, - 0, - 0); - + TuiFillArea(0, 0, UiScreenWidth - 1, UiScreenHeight - 1, 0, 0); + // // Update the screen buffer // @@ -93,7 +88,7 @@ MiniTuiDrawMenu(PUI_MENU_INFO MenuInfo) // UiVtbl.DrawText(0, MenuInfo->Top - 2, - "Please select the operating system to start:", + MenuInfo->MenuTitle, ATTR(UiMenuFgColor, UiMenuBgColor)); // @@ -101,8 +96,7 @@ MiniTuiDrawMenu(PUI_MENU_INFO MenuInfo) // UiVtbl.DrawText(0, MenuInfo->Bottom + 1, - "Use the up and down arrow keys to move the highlight to " - "your choice.", + "Use \x18 and \x19 to move the highlight to your choice.", ATTR(UiMenuFgColor, UiMenuBgColor)); UiVtbl.DrawText(0, MenuInfo->Bottom + 2, @@ -126,7 +120,11 @@ MiniTuiDrawMenu(PUI_MENU_INFO MenuInfo) // // Draw each line of the menu // - for (i = 0; i < MenuInfo->MenuItemCount; i++) TuiDrawMenuItem(MenuInfo, i); + for (i = 0; i < MenuInfo->MenuItemCount; i++) + { + TuiDrawMenuItem(MenuInfo, i); + } + VideoCopyOffScreenBufferToVRAM(); } diff --git a/boot/freeldr/freeldr/ui/noui.c b/boot/freeldr/freeldr/ui/noui.c index 433ddb73387..a8ee95268de 100644 --- a/boot/freeldr/freeldr/ui/noui.c +++ b/boot/freeldr/freeldr/ui/noui.c @@ -109,7 +109,7 @@ VOID NoUiFadeOut(VOID) // /////////////////////////////////////////////////////////////////////////////////////// -BOOLEAN NoUiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter) +BOOLEAN NoUiDisplayMenu(PCSTR MenuTitle, PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter) { *SelectedMenuItem = DefaultMenuItem; return TRUE; diff --git a/boot/freeldr/freeldr/ui/tui.c b/boot/freeldr/freeldr/ui/tui.c index bb4f9e3a8c3..9d458f44483 100644 --- a/boot/freeldr/freeldr/ui/tui.c +++ b/boot/freeldr/freeldr/ui/tui.c @@ -153,7 +153,7 @@ VOID TuiDrawBackdrop(VOID) VOID TuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */) { PUCHAR ScreenMemory = (PUCHAR)TextVideoBuffer; - ULONG i, j; + ULONG i, j; // Clip the area to the screen if ((Left >= UiScreenWidth) || (Top >= UiScreenHeight)) @@ -188,7 +188,7 @@ VOID TuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar VOID TuiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom) { PUCHAR ScreenMemory = (PUCHAR)TextVideoBuffer; - ULONG Idx; + ULONG Idx; // Shade the bottom of the area if (Bottom < (UiScreenHeight - 1)) @@ -320,7 +320,7 @@ VOID TuiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyl VOID TuiDrawText(ULONG X, ULONG Y, PCSTR Text, UCHAR Attr) { PUCHAR ScreenMemory = (PUCHAR)TextVideoBuffer; - ULONG i, j; + ULONG i, j; // Draw the text for (i=X, j=0; Text[j] && iMenuItemCount; i++) TuiDrawMenuItem(MenuInfo, i); + for (i = 0; i < MenuInfo->MenuItemCount; i++) + { + TuiDrawMenuItem(MenuInfo, i); + } + VideoCopyOffScreenBufferToVRAM(); } @@ -221,8 +227,7 @@ VOID NTAPI TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) { - CHAR MenuLineText[80]; - CHAR TempString[80]; + CHAR MenuLineText[80], TempString[80]; ULONG i; // @@ -237,7 +242,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) D_VERT, D_HORZ, FALSE, // Filled - TRUE, // Shadow + TRUE, // Shadow ATTR(UiMenuFgColor, UiMenuBgColor)); } @@ -284,7 +289,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) // Display under the menu directly // UiDrawText(0, - MenuInfo->Bottom + 3, + MenuInfo->Bottom + 4, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } @@ -313,7 +318,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) else { UiDrawText(0, - MenuInfo->Bottom + 3, + MenuInfo->Bottom + 4, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } diff --git a/boot/freeldr/freeldr/ui/ui.c b/boot/freeldr/freeldr/ui/ui.c index b0f0f12dcc9..cc1bf36bdf1 100644 --- a/boot/freeldr/freeldr/ui/ui.c +++ b/boot/freeldr/freeldr/ui/ui.c @@ -17,14 +17,17 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef _M_ARM + #include #include #include DBG_DEFAULT_CHANNEL(UI); -ULONG UiScreenWidth; // Screen Width -ULONG UiScreenHeight; // Screen Height +BOOLEAN UiMinimal = FALSE; // Tells us if we are using a minimal console-like UI + +ULONG UiScreenWidth; // Screen Width +ULONG UiScreenHeight; // Screen Height UCHAR UiStatusBarFgColor = COLOR_BLACK; // Status bar foreground color UCHAR UiStatusBarBgColor = COLOR_CYAN; // Status bar background color @@ -81,13 +84,13 @@ UIVTBL UiVtbl = BOOLEAN UiInitialize(BOOLEAN ShowGui) { VIDEODISPLAYMODE UiDisplayMode; // Tells us if we are in text or graphics mode - BOOLEAN UiMinimal = FALSE; // Tells us if we should use a minimal console-like UI ULONG_PTR SectionId; CHAR DisplayModeText[260]; CHAR SettingText[260]; ULONG Depth; - if (!ShowGui) { + if (!ShowGui) + { if (!UiVtbl.Initialize()) { MachVideoSetDisplayMode(NULL, FALSE); @@ -102,7 +105,7 @@ BOOLEAN UiInitialize(BOOLEAN ShowGui) DisplayModeText[0] = '\0'; if (IniOpenSection("Display", &SectionId)) { - if (! IniReadSettingByName(SectionId, "DisplayMode", DisplayModeText, sizeof(DisplayModeText))) + if (!IniReadSettingByName(SectionId, "DisplayMode", DisplayModeText, sizeof(DisplayModeText))) { DisplayModeText[0] = '\0'; } @@ -116,7 +119,7 @@ BOOLEAN UiInitialize(BOOLEAN ShowGui) MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth); if (VideoTextMode == UiDisplayMode) - UiVtbl = UiMinimal ? MiniTuiVtbl : TuiVtbl; + UiVtbl = (UiMinimal ? MiniTuiVtbl : TuiVtbl); else UiVtbl = GuiVtbl; @@ -225,44 +228,6 @@ BOOLEAN UiInitialize(BOOLEAN ShowGui) return TRUE; } -BOOLEAN SetupUiInitialize(VOID) -{ - CHAR DisplayModeText[260]; - ULONG Depth; - SIZE_T Length; - - - DisplayModeText[0] = '\0'; - - MachVideoSetDisplayMode(DisplayModeText, TRUE); - MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth); - - UiVtbl = TuiVtbl; - UiVtbl.Initialize(); - - // Draw the backdrop and fade it in if special effects are enabled - UiVtbl.FillArea(0, - 0, - UiScreenWidth - 1, - UiScreenHeight - 2, - 0, - ATTR(UiBackdropFgColor, UiBackdropBgColor)); - - UiDrawTime = FALSE; - UiStatusBarBgColor = 7; - - Length = strlen("ReactOS " KERNEL_VERSION_STR " Setup"); - memset(DisplayModeText, 0xcd, Length + 2); - DisplayModeText[Length + 2] = '\0'; - - UiVtbl.DrawText(4, 1, "ReactOS " KERNEL_VERSION_STR " Setup", ATTR(COLOR_GRAY, UiBackdropBgColor)); - UiVtbl.DrawText(3, 2, DisplayModeText, ATTR(COLOR_GRAY, UiBackdropBgColor)); - - TRACE("UiInitialize() returning TRUE.\n"); - - return TRUE; -} - VOID UiUnInitialize(PCSTR BootText) { UiDrawBackdrop(); @@ -405,7 +370,7 @@ VOID UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG P VOID UiShowMessageBoxesInSection(PCSTR SectionName) { - ULONG Idx; + ULONG Idx; CHAR SettingName[80]; CHAR SettingValue[80]; PCHAR MessageBoxText; @@ -455,7 +420,7 @@ VOID UiShowMessageBoxesInSection(PCSTR SectionName) VOID UiEscapeString(PCHAR String) { - ULONG Idx; + ULONG Idx; for (Idx=0; IdxBootDriverListHead, InfHandle, BootPath); - + /* Load ReactOS */ LoadAndBootWindowsCommon(_WIN32_WINNT_WS03, LoaderBlock, BootOptions, diff --git a/boot/freeldr/tools/rdel.c b/boot/freeldr/tools/rdel.c index 2bd312be2d2..5059e5bfc87 100644 --- a/boot/freeldr/tools/rdel.c +++ b/boot/freeldr/tools/rdel.c @@ -1,4 +1,4 @@ -/* $Id$ +/* * COPYRIGHT: See COPYING in the top level directory * PROGRAMMER: Rex Jolliff (rex@lvcablemodem.com) * PURPOSE: Platform independant delete command diff --git a/boot/freeldr/tools/rrmdir.c b/boot/freeldr/tools/rrmdir.c index f48a0fd9d22..a5620e94d24 100644 --- a/boot/freeldr/tools/rrmdir.c +++ b/boot/freeldr/tools/rrmdir.c @@ -1,4 +1,4 @@ -/* $Id$ +/* * COPYRIGHT: See COPYING in the top level directory * PROGRAMMER: Rex Jolliff (rex@lvcablemodem.com) * Casper S. Hornstrup (chorns@users.sourceforge.net) diff --git a/dll/cpl/main/CMakeLists.txt b/dll/cpl/main/CMakeLists.txt index b8c2c708409..d19842bffa6 100644 --- a/dll/cpl/main/CMakeLists.txt +++ b/dll/cpl/main/CMakeLists.txt @@ -1,6 +1,4 @@ -set_rc_compiler() - spec2def(main.cpl main.spec) add_library(main SHARED @@ -11,6 +9,7 @@ add_library(main SHARED ${CMAKE_CURRENT_BINARY_DIR}/main.def) set_module_type(main cpl UNICODE) +target_link_libraries(main uuid) add_importlibs(main msvcrt diff --git a/dll/cpl/main/main.h b/dll/cpl/main/main.h index 50f5206c766..3b8638202a6 100644 --- a/dll/cpl/main/main.h +++ b/dll/cpl/main/main.h @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/dll/win32/advpack/CMakeLists.txt b/dll/win32/advpack/CMakeLists.txt index a11becd6b65..9650fc6291d 100644 --- a/dll/win32/advpack/CMakeLists.txt +++ b/dll/win32/advpack/CMakeLists.txt @@ -3,7 +3,7 @@ add_definitions(-D__WINESRC__) include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) -spec2def(advpack.dll advpack.spec) +spec2def(advpack.dll advpack.spec ADD_IMPORTLIB) list(APPEND SOURCE advpack.c diff --git a/dll/win32/advpack/advpack_private.h b/dll/win32/advpack/advpack_private.h index cbbbf4819af..5d7489778d6 100644 --- a/dll/win32/advpack/advpack_private.h +++ b/dll/win32/advpack/advpack_private.h @@ -27,4 +27,28 @@ void set_ldids(HINF hInf, LPCWSTR pszInstallSection, LPCWSTR pszWorkingDir) DECL HRESULT launch_exe(LPCWSTR cmd, LPCWSTR dir, HANDLE *phEXE) DECLSPEC_HIDDEN; +static inline void *heap_alloc(size_t len) +{ + return HeapAlloc(GetProcessHeap(), 0, len); +} + +static inline BOOL heap_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +} + +static inline char *heap_strdupWtoA(const WCHAR *str) +{ + char *ret = NULL; + + if(str) { + size_t size = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); + ret = heap_alloc(size); + if(ret) + WideCharToMultiByte(CP_ACP, 0, str, -1, ret, size, NULL, NULL); + } + + return ret; +} + #endif /* __ADVPACK_PRIVATE_H */ diff --git a/dll/win32/advpack/files.c b/dll/win32/advpack/files.c index f6056f298fc..c34f6d566cc 100644 --- a/dll/win32/advpack/files.c +++ b/dll/win32/advpack/files.c @@ -779,11 +779,39 @@ done: HRESULT WINAPI ExtractFilesW(LPCWSTR CabName, LPCWSTR ExpandDir, DWORD Flags, LPCWSTR FileList, LPVOID LReserved, DWORD Reserved) { + char *cab_name = NULL, *expand_dir = NULL, *file_list = NULL; + HRESULT hres = S_OK; - FIXME("(%s, %s, %d, %s, %p, %d) stub!\n", debugstr_w(CabName), debugstr_w(ExpandDir), + TRACE("(%s, %s, %d, %s, %p, %d)\n", debugstr_w(CabName), debugstr_w(ExpandDir), Flags, debugstr_w(FileList), LReserved, Reserved); - return E_FAIL; + if(CabName) { + cab_name = heap_strdupWtoA(CabName); + if(!cab_name) + return E_OUTOFMEMORY; + } + + if(ExpandDir) { + expand_dir = heap_strdupWtoA(ExpandDir); + if(!expand_dir) + hres = E_OUTOFMEMORY; + } + + if(SUCCEEDED(hres) && FileList) { + file_list = heap_strdupWtoA(FileList); + if(!file_list) + hres = E_OUTOFMEMORY; + } + + /* cabinet.dll, which does the real job of extracting files, doesn't have UNICODE API, + so we need W->A conversion at some point anyway. */ + if(SUCCEEDED(hres)) + hres = ExtractFilesA(cab_name, expand_dir, Flags, file_list, LReserved, Reserved); + + heap_free(cab_name); + heap_free(expand_dir); + heap_free(file_list); + return hres; } /*********************************************************************** diff --git a/dll/win32/kernel32/client/file/copy.c b/dll/win32/kernel32/client/file/copy.c index aa1a0ce1187..b123cce38e6 100644 --- a/dll/win32/kernel32/client/file/copy.c +++ b/dll/win32/kernel32/client/file/copy.c @@ -25,171 +25,171 @@ DEBUG_CHANNEL(kernel32file); static NTSTATUS CopyLoop ( - HANDLE FileHandleSource, - HANDLE FileHandleDest, - LARGE_INTEGER SourceFileSize, - LPPROGRESS_ROUTINE lpProgressRoutine, - LPVOID lpData, - BOOL *pbCancel, - BOOL *KeepDest - ) + HANDLE FileHandleSource, + HANDLE FileHandleDest, + LARGE_INTEGER SourceFileSize, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + BOOL *pbCancel, + BOOL *KeepDest +) { - NTSTATUS errCode; - IO_STATUS_BLOCK IoStatusBlock; - UCHAR *lpBuffer = NULL; - SIZE_T RegionSize = 0x10000; - LARGE_INTEGER BytesCopied; - DWORD CallbackReason; - DWORD ProgressResult; - BOOL EndOfFileFound; + NTSTATUS errCode; + IO_STATUS_BLOCK IoStatusBlock; + UCHAR *lpBuffer = NULL; + SIZE_T RegionSize = 0x10000; + LARGE_INTEGER BytesCopied; + DWORD CallbackReason; + DWORD ProgressResult; + BOOL EndOfFileFound; - *KeepDest = FALSE; - errCode = NtAllocateVirtualMemory(NtCurrentProcess(), - (PVOID *)&lpBuffer, - 0, - &RegionSize, - MEM_RESERVE | MEM_COMMIT, - PAGE_READWRITE); + *KeepDest = FALSE; + errCode = NtAllocateVirtualMemory(NtCurrentProcess(), + (PVOID *)&lpBuffer, + 0, + &RegionSize, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE); - if (NT_SUCCESS(errCode)) - { - BytesCopied.QuadPart = 0; - EndOfFileFound = FALSE; - CallbackReason = CALLBACK_STREAM_SWITCH; - while (! EndOfFileFound && - NT_SUCCESS(errCode) && - (NULL == pbCancel || ! *pbCancel)) - { - if (NULL != lpProgressRoutine) - { - ProgressResult = (*lpProgressRoutine)(SourceFileSize, - BytesCopied, - SourceFileSize, - BytesCopied, - 0, - CallbackReason, - FileHandleSource, - FileHandleDest, - lpData); - switch (ProgressResult) - { - case PROGRESS_CANCEL: - TRACE("Progress callback requested cancel\n"); - errCode = STATUS_REQUEST_ABORTED; - break; - case PROGRESS_STOP: - TRACE("Progress callback requested stop\n"); - errCode = STATUS_REQUEST_ABORTED; - *KeepDest = TRUE; - break; - case PROGRESS_QUIET: - lpProgressRoutine = NULL; - break; - case PROGRESS_CONTINUE: - default: - break; - } - CallbackReason = CALLBACK_CHUNK_FINISHED; - } - if (NT_SUCCESS(errCode)) - { - errCode = NtReadFile(FileHandleSource, - NULL, - NULL, - NULL, - (PIO_STATUS_BLOCK)&IoStatusBlock, - lpBuffer, - RegionSize, - NULL, - NULL); - if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel)) - { - errCode = NtWriteFile(FileHandleDest, - NULL, - NULL, - NULL, - (PIO_STATUS_BLOCK)&IoStatusBlock, - lpBuffer, - IoStatusBlock.Information, - NULL, - NULL); - if (NT_SUCCESS(errCode)) - { - BytesCopied.QuadPart += IoStatusBlock.Information; - } - else - { - WARN("Error 0x%08x reading writing to dest\n", errCode); - } - } - else if (!NT_SUCCESS(errCode)) - { - if (STATUS_END_OF_FILE == errCode) - { - EndOfFileFound = TRUE; - errCode = STATUS_SUCCESS; - } - else - { - WARN("Error 0x%08x reading from source\n", errCode); - } - } - } - } + if (NT_SUCCESS(errCode)) + { + BytesCopied.QuadPart = 0; + EndOfFileFound = FALSE; + CallbackReason = CALLBACK_STREAM_SWITCH; + while (! EndOfFileFound && + NT_SUCCESS(errCode) && + (NULL == pbCancel || ! *pbCancel)) + { + if (NULL != lpProgressRoutine) + { + ProgressResult = (*lpProgressRoutine)(SourceFileSize, + BytesCopied, + SourceFileSize, + BytesCopied, + 0, + CallbackReason, + FileHandleSource, + FileHandleDest, + lpData); + switch (ProgressResult) + { + case PROGRESS_CANCEL: + TRACE("Progress callback requested cancel\n"); + errCode = STATUS_REQUEST_ABORTED; + break; + case PROGRESS_STOP: + TRACE("Progress callback requested stop\n"); + errCode = STATUS_REQUEST_ABORTED; + *KeepDest = TRUE; + break; + case PROGRESS_QUIET: + lpProgressRoutine = NULL; + break; + case PROGRESS_CONTINUE: + default: + break; + } + CallbackReason = CALLBACK_CHUNK_FINISHED; + } + if (NT_SUCCESS(errCode)) + { + errCode = NtReadFile(FileHandleSource, + NULL, + NULL, + NULL, + (PIO_STATUS_BLOCK)&IoStatusBlock, + lpBuffer, + RegionSize, + NULL, + NULL); + if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel)) + { + errCode = NtWriteFile(FileHandleDest, + NULL, + NULL, + NULL, + (PIO_STATUS_BLOCK)&IoStatusBlock, + lpBuffer, + IoStatusBlock.Information, + NULL, + NULL); + if (NT_SUCCESS(errCode)) + { + BytesCopied.QuadPart += IoStatusBlock.Information; + } + else + { + WARN("Error 0x%08x reading writing to dest\n", errCode); + } + } + else if (!NT_SUCCESS(errCode)) + { + if (STATUS_END_OF_FILE == errCode) + { + EndOfFileFound = TRUE; + errCode = STATUS_SUCCESS; + } + else + { + WARN("Error 0x%08x reading from source\n", errCode); + } + } + } + } - if (! EndOfFileFound && (NULL != pbCancel && *pbCancel)) - { - TRACE("User requested cancel\n"); - errCode = STATUS_REQUEST_ABORTED; - } + if (! EndOfFileFound && (NULL != pbCancel && *pbCancel)) + { + TRACE("User requested cancel\n"); + errCode = STATUS_REQUEST_ABORTED; + } - NtFreeVirtualMemory(NtCurrentProcess(), - (PVOID *)&lpBuffer, - &RegionSize, - MEM_RELEASE); - } - else - { - TRACE("Error 0x%08x allocating buffer of %d bytes\n", errCode, RegionSize); - } + NtFreeVirtualMemory(NtCurrentProcess(), + (PVOID *)&lpBuffer, + &RegionSize, + MEM_RELEASE); + } + else + { + TRACE("Error 0x%08x allocating buffer of %d bytes\n", errCode, RegionSize); + } - return errCode; + return errCode; } static NTSTATUS SetLastWriteTime( - HANDLE FileHandle, - LARGE_INTEGER LastWriteTime - ) + HANDLE FileHandle, + LARGE_INTEGER LastWriteTime +) { - NTSTATUS errCode = STATUS_SUCCESS; - IO_STATUS_BLOCK IoStatusBlock; - FILE_BASIC_INFORMATION FileBasic; + NTSTATUS errCode = STATUS_SUCCESS; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileBasic; - errCode = NtQueryInformationFile (FileHandle, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(errCode)) - { - WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode); - } - else - { - FileBasic.LastWriteTime.QuadPart = LastWriteTime.QuadPart; - errCode = NtSetInformationFile (FileHandle, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(errCode)) - { - WARN("Error 0x%0x setting LastWriteTime\n", errCode); - } - } + errCode = NtQueryInformationFile (FileHandle, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(errCode)) + { + WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode); + } + else + { + FileBasic.LastWriteTime.QuadPart = LastWriteTime.QuadPart; + errCode = NtSetInformationFile (FileHandle, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(errCode)) + { + WARN("Error 0x%0x setting LastWriteTime\n", errCode); + } + } - return errCode; + return errCode; } @@ -199,113 +199,113 @@ SetLastWriteTime( BOOL WINAPI CopyFileExW ( - LPCWSTR lpExistingFileName, - LPCWSTR lpNewFileName, - LPPROGRESS_ROUTINE lpProgressRoutine, - LPVOID lpData, - BOOL *pbCancel, - DWORD dwCopyFlags - ) + LPCWSTR lpExistingFileName, + LPCWSTR lpNewFileName, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + BOOL *pbCancel, + DWORD dwCopyFlags +) { - NTSTATUS errCode; - HANDLE FileHandleSource, FileHandleDest; - IO_STATUS_BLOCK IoStatusBlock; - FILE_STANDARD_INFORMATION FileStandard; - FILE_BASIC_INFORMATION FileBasic; - BOOL RC = FALSE; - BOOL KeepDestOnError = FALSE; - DWORD SystemError; + NTSTATUS errCode; + HANDLE FileHandleSource, FileHandleDest; + IO_STATUS_BLOCK IoStatusBlock; + FILE_STANDARD_INFORMATION FileStandard; + FILE_BASIC_INFORMATION FileBasic; + BOOL RC = FALSE; + BOOL KeepDestOnError = FALSE; + DWORD SystemError; - FileHandleSource = CreateFileW(lpExistingFileName, - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING, - NULL); - if (INVALID_HANDLE_VALUE != FileHandleSource) - { - errCode = NtQueryInformationFile(FileHandleSource, - &IoStatusBlock, - &FileStandard, - sizeof(FILE_STANDARD_INFORMATION), - FileStandardInformation); - if (!NT_SUCCESS(errCode)) - { - TRACE("Status 0x%08x obtaining FileStandardInformation for source\n", errCode); - BaseSetLastNTError(errCode); - } - else - { - errCode = NtQueryInformationFile(FileHandleSource, - &IoStatusBlock,&FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(errCode)) - { - TRACE("Status 0x%08x obtaining FileBasicInformation for source\n", errCode); - BaseSetLastNTError(errCode); - } - else - { - FileHandleDest = CreateFileW(lpNewFileName, - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS, - FileBasic.FileAttributes, - NULL); - if (INVALID_HANDLE_VALUE != FileHandleDest) - { - errCode = CopyLoop(FileHandleSource, - FileHandleDest, - FileStandard.EndOfFile, - lpProgressRoutine, - lpData, - pbCancel, - &KeepDestOnError); - if (!NT_SUCCESS(errCode)) - { - BaseSetLastNTError(errCode); - } - else - { - LARGE_INTEGER t; + FileHandleSource = CreateFileW(lpExistingFileName, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING, + NULL); + if (INVALID_HANDLE_VALUE != FileHandleSource) + { + errCode = NtQueryInformationFile(FileHandleSource, + &IoStatusBlock, + &FileStandard, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + if (!NT_SUCCESS(errCode)) + { + TRACE("Status 0x%08x obtaining FileStandardInformation for source\n", errCode); + BaseSetLastNTError(errCode); + } + else + { + errCode = NtQueryInformationFile(FileHandleSource, + &IoStatusBlock,&FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(errCode)) + { + TRACE("Status 0x%08x obtaining FileBasicInformation for source\n", errCode); + BaseSetLastNTError(errCode); + } + else + { + FileHandleDest = CreateFileW(lpNewFileName, + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS, + FileBasic.FileAttributes, + NULL); + if (INVALID_HANDLE_VALUE != FileHandleDest) + { + errCode = CopyLoop(FileHandleSource, + FileHandleDest, + FileStandard.EndOfFile, + lpProgressRoutine, + lpData, + pbCancel, + &KeepDestOnError); + if (!NT_SUCCESS(errCode)) + { + BaseSetLastNTError(errCode); + } + else + { + LARGE_INTEGER t; - t.QuadPart = FileBasic.LastWriteTime.QuadPart; - errCode = SetLastWriteTime(FileHandleDest, t); - if (!NT_SUCCESS(errCode)) - { - BaseSetLastNTError(errCode); - } - else - { - RC = TRUE; - } - } - NtClose(FileHandleDest); - if (! RC && ! KeepDestOnError) - { - SystemError = GetLastError(); - SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL); - DeleteFileW(lpNewFileName); - SetLastError(SystemError); - } - } - else - { - WARN("Error %d during opening of dest file\n", GetLastError()); - } - } - } - NtClose(FileHandleSource); - } - else - { - WARN("Error %d during opening of source file\n", GetLastError()); - } + t.QuadPart = FileBasic.LastWriteTime.QuadPart; + errCode = SetLastWriteTime(FileHandleDest, t); + if (!NT_SUCCESS(errCode)) + { + BaseSetLastNTError(errCode); + } + else + { + RC = TRUE; + } + } + NtClose(FileHandleDest); + if (! RC && ! KeepDestOnError) + { + SystemError = GetLastError(); + SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL); + DeleteFileW(lpNewFileName); + SetLastError(SystemError); + } + } + else + { + WARN("Error %d during opening of dest file\n", GetLastError()); + } + } + } + NtClose(FileHandleSource); + } + else + { + WARN("Error %d during opening of source file\n", GetLastError()); + } - return RC; + return RC; } @@ -353,17 +353,17 @@ CopyFileExA(IN LPCSTR lpExistingFileName, BOOL WINAPI CopyFileA ( - LPCSTR lpExistingFileName, - LPCSTR lpNewFileName, - BOOL bFailIfExists - ) + LPCSTR lpExistingFileName, + LPCSTR lpNewFileName, + BOOL bFailIfExists +) { - return CopyFileExA (lpExistingFileName, - lpNewFileName, - NULL, - NULL, - NULL, - bFailIfExists); + return CopyFileExA (lpExistingFileName, + lpNewFileName, + NULL, + NULL, + NULL, + bFailIfExists); } @@ -373,17 +373,17 @@ CopyFileA ( BOOL WINAPI CopyFileW ( - LPCWSTR lpExistingFileName, - LPCWSTR lpNewFileName, - BOOL bFailIfExists - ) + LPCWSTR lpExistingFileName, + LPCWSTR lpNewFileName, + BOOL bFailIfExists +) { - return CopyFileExW (lpExistingFileName, - lpNewFileName, - NULL, - NULL, - NULL, - bFailIfExists); + return CopyFileExW (lpExistingFileName, + lpNewFileName, + NULL, + NULL, + NULL, + bFailIfExists); } @@ -393,13 +393,13 @@ CopyFileW ( BOOL WINAPI PrivCopyFileExW ( - LPCWSTR lpExistingFileName, - LPCWSTR lpNewFileName, - LPPROGRESS_ROUTINE lpProgressRoutine, - LPVOID lpData, - BOOL *pbCancel, - DWORD dwCopyFlags - ) + LPCWSTR lpExistingFileName, + LPCWSTR lpNewFileName, + LPPROGRESS_ROUTINE lpProgressRoutine, + LPVOID lpData, + BOOL *pbCancel, + DWORD dwCopyFlags +) { UNIMPLEMENTED; return FALSE; diff --git a/dll/win32/lsasrv/database.c b/dll/win32/lsasrv/database.c index 1afa0a38d7b..aa04e13a801 100644 --- a/dll/win32/lsasrv/database.c +++ b/dll/win32/lsasrv/database.c @@ -304,6 +304,7 @@ LsapCreateDatabaseObjects(VOID) L"Policy", LsaDbPolicyObject, 0, + TRUE, &PolicyObject); if (!NT_SUCCESS(Status)) goto done; @@ -434,6 +435,7 @@ LsapGetDomainInfo(VOID) L"Policy", LsaDbPolicyObject, 0, + TRUE, &PolicyObject); if (!NT_SUCCESS(Status)) goto done; @@ -596,6 +598,7 @@ LsapCreateDbObject(IN PLSA_DB_OBJECT ParentObject, IN LPWSTR ObjectName, IN LSA_DB_OBJECT_TYPE ObjectType, IN ACCESS_MASK DesiredAccess, + IN BOOLEAN Trusted, OUT PLSA_DB_OBJECT *DbObject) { PLSA_DB_OBJECT NewObject; @@ -698,6 +701,7 @@ LsapCreateDbObject(IN PLSA_DB_OBJECT ParentObject, NewObject->Access = DesiredAccess; NewObject->KeyHandle = ObjectKeyHandle; NewObject->ParentObject = ParentObject; + NewObject->Trusted = Trusted; if (ParentObject != NULL) ParentObject->RefCount++; @@ -714,6 +718,7 @@ LsapOpenDbObject(IN PLSA_DB_OBJECT ParentObject, IN LPWSTR ObjectName, IN LSA_DB_OBJECT_TYPE ObjectType, IN ACCESS_MASK DesiredAccess, + IN BOOLEAN Trusted, OUT PLSA_DB_OBJECT *DbObject) { PLSA_DB_OBJECT NewObject; @@ -809,6 +814,7 @@ LsapOpenDbObject(IN PLSA_DB_OBJECT ParentObject, NewObject->Access = DesiredAccess; NewObject->KeyHandle = ObjectKeyHandle; NewObject->ParentObject = ParentObject; + NewObject->Trusted = Trusted; if (ParentObject != NULL) ParentObject->RefCount++; diff --git a/dll/win32/lsasrv/lsarpc.c b/dll/win32/lsasrv/lsarpc.c index db70223619a..a95ef980a03 100644 --- a/dll/win32/lsasrv/lsarpc.c +++ b/dll/win32/lsasrv/lsarpc.c @@ -258,6 +258,7 @@ NTSTATUS WINAPI LsarOpenPolicy( L"Policy", LsaDbPolicyObject, DesiredAccess, + FALSE, &PolicyObject); RtlLeaveCriticalSection(&PolicyHandleTableLock); @@ -592,6 +593,7 @@ NTSTATUS WINAPI LsarCreateAccount( SidString, LsaDbAccountObject, DesiredAccess, + PolicyObject->Trusted, &AccountObject); if (!NT_SUCCESS(Status)) { @@ -1036,6 +1038,7 @@ NTSTATUS WINAPI LsarCreateSecret( SecretName->Buffer, LsaDbSecretObject, DesiredAccess, + PolicyObject->Trusted, &SecretObject); if (!NT_SUCCESS(Status)) { @@ -1131,6 +1134,7 @@ NTSTATUS WINAPI LsarOpenAccount( SidString, LsaDbAccountObject, DesiredAccess, + PolicyObject->Trusted, &AccountObject); if (!NT_SUCCESS(Status)) { @@ -1241,6 +1245,7 @@ NTSTATUS WINAPI LsarAddPrivilegesToAccount( return Status; } + /* Get the size of the Privilgs attribute */ Status = LsapGetObjectAttribute(AccountObject, L"Privilgs", NULL, @@ -1348,7 +1353,7 @@ NTSTATUS WINAPI LsarAddPrivilegesToAccount( } } - /* Set the new priivliege set */ + /* Set the new privilege set */ Status = LsapSetObjectAttribute(AccountObject, L"Privilgs", NewPrivileges, @@ -1591,6 +1596,7 @@ NTSTATUS WINAPI LsarOpenSecret( SecretName->Buffer, LsaDbSecretObject, DesiredAccess, + PolicyObject->Trusted, &SecretObject); if (!NT_SUCCESS(Status)) { diff --git a/dll/win32/lsasrv/lsasrv.h b/dll/win32/lsasrv/lsasrv.h index 6488585c04e..10a9573daa4 100644 --- a/dll/win32/lsasrv/lsasrv.h +++ b/dll/win32/lsasrv/lsasrv.h @@ -47,6 +47,7 @@ typedef struct _LSA_DB_OBJECT ULONG RefCount; ACCESS_MASK Access; HANDLE KeyHandle; + BOOLEAN Trusted; struct _LSA_DB_OBJECT *ParentObject; } LSA_DB_OBJECT, *PLSA_DB_OBJECT; @@ -87,6 +88,7 @@ LsapCreateDbObject(IN PLSA_DB_OBJECT ParentObject, IN LPWSTR ObjectName, IN LSA_DB_OBJECT_TYPE HandleType, IN ACCESS_MASK DesiredAccess, + IN BOOLEAN Trusted, OUT PLSA_DB_OBJECT *DbObject); NTSTATUS @@ -95,6 +97,7 @@ LsapOpenDbObject(IN PLSA_DB_OBJECT ParentObject, IN LPWSTR ObjectName, IN LSA_DB_OBJECT_TYPE ObjectType, IN ACCESS_MASK DesiredAccess, + IN BOOLEAN Trusted, OUT PLSA_DB_OBJECT *DbObject); NTSTATUS diff --git a/dll/win32/lsasrv/policy.c b/dll/win32/lsasrv/policy.c index 8fe0735e19f..af8d1ce0b86 100644 --- a/dll/win32/lsasrv/policy.c +++ b/dll/win32/lsasrv/policy.c @@ -29,6 +29,7 @@ LsaIOpenPolicyTrusted(OUT LSAPR_HANDLE *PolicyHandle) L"Policy", LsaDbPolicyObject, POLICY_ALL_ACCESS, + TRUE, &PolicyObject); if (NT_SUCCESS(Status)) @@ -89,6 +90,7 @@ LsarQueryAuditEvents(PLSA_DB_OBJECT PolicyObject, if (!NT_SUCCESS(Status)) return Status; + TRACE("Attribute size: %lu\n", AttributeSize); if (AttributeSize > 0) { AuditData = MIDL_user_allocate(AttributeSize); @@ -101,14 +103,23 @@ LsarQueryAuditEvents(PLSA_DB_OBJECT PolicyObject, &AttributeSize); if (!NT_SUCCESS(Status)) goto done; + } - p = MIDL_user_allocate(sizeof(LSAPR_POLICY_AUDIT_EVENTS_INFO)); - if (p == NULL) - { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto done; - } + p = MIDL_user_allocate(sizeof(LSAPR_POLICY_AUDIT_EVENTS_INFO)); + if (p == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + if (AuditData == NULL) + { + p->AuditingMode = FALSE; + p->MaximumAuditEventCount = 0; + p->EventAuditingOptions = NULL; + } + else + { p->AuditingMode = AuditData->AuditingMode; p->MaximumAuditEventCount = AuditData->MaximumAuditEventCount; @@ -127,19 +138,23 @@ LsarQueryAuditEvents(PLSA_DB_OBJECT PolicyObject, *PolicyInformation = (PLSAPR_POLICY_INFORMATION)p; done: + TRACE("Status: 0x%lx\n", Status); + if (!NT_SUCCESS(Status)) { - if (p->EventAuditingOptions != NULL) - MIDL_user_free(p->EventAuditingOptions); - if (p != NULL) + { + if (p->EventAuditingOptions != NULL) + MIDL_user_free(p->EventAuditingOptions); + MIDL_user_free(p); + } } if (AuditData != NULL) MIDL_user_free(AuditData); - return STATUS_SUCCESS; + return Status; } @@ -237,7 +252,7 @@ LsarQueryPrimaryDomain(PLSA_DB_OBJECT PolicyObject, Done: if (!NT_SUCCESS(Status)) { - if (p) + if (p != NULL) { if (p->Name.Buffer) MIDL_user_free(p->Name.Buffer); @@ -782,8 +797,37 @@ NTSTATUS LsarSetAuditEvents(PLSA_DB_OBJECT PolicyObject, PLSAPR_POLICY_AUDIT_EVENTS_INFO Info) { - FIXME("\n"); - return STATUS_NOT_IMPLEMENTED; + PLSAP_POLICY_AUDIT_EVENTS_DATA AuditData = NULL; + ULONG AttributeSize; + NTSTATUS Status = STATUS_SUCCESS; + + TRACE("(%p %p)\n", PolicyObject, Info); + + AttributeSize = sizeof(LSAP_POLICY_AUDIT_EVENTS_DATA) + + Info->MaximumAuditEventCount * sizeof(DWORD); + + AuditData = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + AttributeSize); + if (AuditData == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + AuditData->AuditingMode = Info->AuditingMode; + AuditData->MaximumAuditEventCount = Info->MaximumAuditEventCount; + + memcpy(&(AuditData->AuditEvents[0]), + Info->EventAuditingOptions, + Info->MaximumAuditEventCount * sizeof(DWORD)); + + Status = LsapSetObjectAttribute(PolicyObject, + L"PolAdtEv", + AuditData, + AttributeSize); + + if (AuditData != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AuditData); + + return Status; } @@ -885,8 +929,12 @@ NTSTATUS LsarSetServerRole(PLSA_DB_OBJECT PolicyObject, PPOLICY_LSA_SERVER_ROLE_INFO Info) { - FIXME("\n"); - return STATUS_NOT_IMPLEMENTED; + TRACE("(%p %p)\n", PolicyObject, Info); + + return LsapSetObjectAttribute(PolicyObject, + L"PolSrvRo", + Info, + sizeof(POLICY_LSA_SERVER_ROLE_INFO)); } @@ -916,8 +964,12 @@ NTSTATUS LsarSetModification(PLSA_DB_OBJECT PolicyObject, PPOLICY_MODIFICATION_INFO Info) { - FIXME("\n"); - return STATUS_NOT_IMPLEMENTED; + TRACE("(%p %p)\n", PolicyObject, Info); + + return LsapSetObjectAttribute(PolicyObject, + L"PolMod", + Info, + sizeof(POLICY_MODIFICATION_INFO)); } @@ -925,8 +977,36 @@ NTSTATUS LsarSetAuditFull(PLSA_DB_OBJECT PolicyObject, PPOLICY_AUDIT_FULL_QUERY_INFO Info) { - FIXME("\n"); - return STATUS_NOT_IMPLEMENTED; + PPOLICY_AUDIT_FULL_QUERY_INFO AuditFullInfo = NULL; + ULONG AttributeSize; + NTSTATUS Status; + + TRACE("(%p %p)\n", PolicyObject, Info); + + AttributeSize = sizeof(POLICY_AUDIT_FULL_QUERY_INFO); + AuditFullInfo = MIDL_user_allocate(AttributeSize); + if (AuditFullInfo == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = LsapGetObjectAttribute(PolicyObject, + L"PolAdtFl", + AuditFullInfo, + &AttributeSize); + if (!NT_SUCCESS(Status)) + goto done; + + AuditFullInfo->ShutDownOnFull = Info->ShutDownOnFull; + + Status = LsapSetObjectAttribute(PolicyObject, + L"PolAdtFl", + AuditFullInfo, + AttributeSize); + +done: + if (AuditFullInfo != NULL) + MIDL_user_free(AuditFullInfo); + + return Status; } diff --git a/dll/win32/msi/action.c b/dll/win32/msi/action.c index 1ad3bc2b26e..076d1b3775d 100644 --- a/dll/win32/msi/action.c +++ b/dll/win32/msi/action.c @@ -353,7 +353,7 @@ UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine, remove_quotes( val ); TRACE("Found commandline property %s = %s\n", debugstr_w(prop), debugstr_w(val)); - r = msi_set_property( package->db, prop, val ); + r = msi_set_property( package->db, prop, val, -1 ); if (r == ERROR_SUCCESS && !strcmpW( prop, szSourceDir )) msi_reset_folders( package, TRUE ); @@ -462,7 +462,7 @@ UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace) check = msi_dup_property( package->db, szSourceDir ); if (!check || replace) { - UINT r = msi_set_property( package->db, szSourceDir, source ); + UINT r = msi_set_property( package->db, szSourceDir, source, -1 ); if (r == ERROR_SUCCESS) msi_reset_folders( package, TRUE ); } @@ -470,7 +470,7 @@ UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace) check = msi_dup_property( package->db, szSOURCEDIR ); if (!check || replace) - msi_set_property( package->db, szSOURCEDIR, source ); + msi_set_property( package->db, szSOURCEDIR, source, -1 ); msi_free( check ); msi_free( source ); @@ -605,7 +605,7 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran) { TRACE("Running the actions\n"); - msi_set_property(package->db, szSourceDir, NULL); + msi_set_property( package->db, szSourceDir, NULL, -1 ); rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, package); msiobj_release(&view->hdr); } @@ -809,6 +809,11 @@ INSTALLSTATE msi_get_component_action( MSIPACKAGE *package, MSICOMPONENT *comp ) return INSTALLSTATE_UNKNOWN; } if (package->need_rollback) return comp->Installed; + if (comp->num_clients > 0 && comp->ActionRequest == INSTALLSTATE_ABSENT) + { + TRACE("%s has %u clients left\n", debugstr_w(comp->Component), comp->num_clients); + return INSTALLSTATE_UNKNOWN; + } return comp->ActionRequest; } @@ -1563,8 +1568,8 @@ static UINT load_all_folders( MSIPACKAGE *package ) static UINT ACTION_CostInitialize(MSIPACKAGE *package) { - msi_set_property( package->db, szCostingComplete, szZero ); - msi_set_property( package->db, szRootDrive, szCRoot ); + msi_set_property( package->db, szCostingComplete, szZero, -1 ); + msi_set_property( package->db, szRootDrive, szCRoot, -1 ); load_all_folders( package ); msi_load_all_components( package ); @@ -1620,6 +1625,27 @@ static UINT ACTION_FileCost(MSIPACKAGE *package) return ERROR_SUCCESS; } +static void get_client_counts( MSIPACKAGE *package ) +{ + MSICOMPONENT *comp; + HKEY hkey; + + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + { + if (!comp->ComponentId) continue; + + if (MSIREG_OpenUserDataComponentKey( comp->ComponentId, szLocalSid, &hkey, FALSE ) && + MSIREG_OpenUserDataComponentKey( comp->ComponentId, NULL, &hkey, FALSE )) + { + comp->num_clients = 0; + continue; + } + RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, NULL, (DWORD *)&comp->num_clients, + NULL, NULL, NULL, NULL ); + RegCloseKey( hkey ); + } +} + static void ACTION_GetComponentInstallStates(MSIPACKAGE *package) { MSICOMPONENT *comp; @@ -1759,7 +1785,7 @@ static BOOL process_overrides( MSIPACKAGE *package, int level ) ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED ); if (ret) - msi_set_property( package->db, szPreselected, szOne ); + msi_set_property( package->db, szPreselected, szOne, -1 ); return ret; } @@ -1956,8 +1982,7 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) continue; } TRACE("nobody wants component %s\n", debugstr_w(component->Component)); - if (component->anyAbsent && - (component->Installed == INSTALLSTATE_LOCAL || component->Installed == INSTALLSTATE_SOURCE)) + if (component->anyAbsent && component->ComponentId) { component->Action = INSTALLSTATE_ABSENT; component->ActionRequest = INSTALLSTATE_ABSENT; @@ -1983,6 +2008,11 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) TRACE("component %s (installed %d request %d action %d)\n", debugstr_w(component->Component), component->Installed, component->ActionRequest, component->Action); + + if (component->Action == INSTALLSTATE_LOCAL || component->Action == INSTALLSTATE_SOURCE) + component->num_clients++; + else if (component->Action == INSTALLSTATE_ABSENT) + component->num_clients--; } return ERROR_SUCCESS; @@ -2154,7 +2184,7 @@ WCHAR *msi_build_directory_name( DWORD count, ... ) const WCHAR *str = va_arg( va, const WCHAR * ); if (!str) continue; strcatW( dir, str ); - if ( i + 1 != count && dir[strlenW( dir ) - 1] != '\\') strcatW( dir, szBackSlash ); + if ( i + 1 != count && dir[0] && dir[strlenW( dir ) - 1] != '\\') strcatW( dir, szBackSlash ); } va_end( va ); return dir; @@ -2281,6 +2311,19 @@ WCHAR *msi_normalize_path( const WCHAR *in ) return ret; } +static WCHAR *get_install_location( MSIPACKAGE *package ) +{ + HKEY hkey; + WCHAR *path; + + if (!package->ProductCode) return NULL; + if (MSIREG_OpenInstallProps( package->ProductCode, package->Context, NULL, &hkey, FALSE )) + return NULL; + path = msi_reg_get_val_str( hkey, szInstallLocation ); + RegCloseKey( hkey ); + return path; +} + void msi_resolve_target_folder( MSIPACKAGE *package, const WCHAR *name, BOOL load_prop ) { FolderList *fl; @@ -2293,7 +2336,8 @@ void msi_resolve_target_folder( MSIPACKAGE *package, const WCHAR *name, BOOL loa if (!strcmpW( folder->Directory, szTargetDir )) /* special resolving for target root dir */ { - if (!load_prop || !(path = msi_dup_property( package->db, szTargetDir ))) + if (!(path = get_install_location( package )) && + (!load_prop || !(path = msi_dup_property( package->db, szTargetDir )))) { path = msi_dup_property( package->db, szRootDrive ); } @@ -2316,7 +2360,7 @@ void msi_resolve_target_folder( MSIPACKAGE *package, const WCHAR *name, BOOL loa msi_free( normalized_path ); return; } - msi_set_property( package->db, folder->Directory, normalized_path ); + msi_set_property( package->db, folder->Directory, normalized_path, -1 ); msi_free( folder->ResolvedTarget ); folder->ResolvedTarget = normalized_path; @@ -2354,6 +2398,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) else comp->Enabled = TRUE; } + get_client_counts( package ); /* read components states from the registry */ ACTION_GetComponentInstallStates(package); @@ -2376,28 +2421,28 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) TRACE("Calculating file cost\n"); calculate_file_cost( package ); - msi_set_property( package->db, szCostingComplete, szOne ); + msi_set_property( package->db, szCostingComplete, szOne, -1 ); /* set default run level if not set */ level = msi_dup_property( package->db, szInstallLevel ); if (!level) - msi_set_property( package->db, szInstallLevel, szOne ); + msi_set_property( package->db, szInstallLevel, szOne, -1 ); msi_free(level); /* FIXME: check volume disk space */ - msi_set_property( package->db, szOutOfDiskSpace, szZero ); + msi_set_property( package->db, szOutOfDiskSpace, szZero, -1 ); return MSI_SetFeatureStates(package); } -static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, DWORD *size) +static BYTE *parse_value( MSIPACKAGE *package, const WCHAR *value, DWORD *type, DWORD *size ) { - LPSTR data = NULL; + BYTE *data = NULL; if (!value) { - data = (LPSTR)strdupW(szEmpty); - *size = sizeof(szEmpty); + *size = sizeof(WCHAR); *type = REG_SZ; + if ((data = msi_alloc( *size ))) *(WCHAR *)data = 0; return data; } if (value[0]=='#' && value[1]!='#' && value[1]!='%') @@ -2479,38 +2524,22 @@ static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, DWORD } else { - static const WCHAR szMulti[] = {'[','~',']',0}; - LPCWSTR ptr; - *type=REG_SZ; + const WCHAR *ptr = value; + DWORD len; - if (value[0]=='#') + *type = REG_SZ; + if (value[0] == '#') { - if (value[1]=='%') + ptr++; + if (value[1] == '%') { - ptr = &value[2]; - *type=REG_EXPAND_SZ; + ptr++; + *type = REG_EXPAND_SZ; } - else - ptr = &value[1]; - } - else - ptr=value; - - if (strstrW(value, szMulti)) - *type = REG_MULTI_SZ; - - /* remove initial delimiter */ - if (!strncmpW(value, szMulti, 3)) - ptr = value + 3; - - *size = deformat_string(package, ptr,(LPWSTR*)&data); - - /* add double NULL terminator */ - if (*type == REG_MULTI_SZ) - { - *size += 2 * sizeof(WCHAR); /* two NULL terminators */ - data = msi_realloc_zero(data, *size); } + len = deformat_string( package, ptr, (WCHAR **)&data ); + if (len > strlenW( (const WCHAR *)data )) *type = REG_MULTI_SZ; + *size = (len + 1) * sizeof(WCHAR); } return data; } @@ -2618,19 +2647,181 @@ static BOOL is_special_entry( const WCHAR *name ) return (name && (name[0] == '*' || name[0] == '+') && !name[1]); } +static WCHAR **split_multi_string_values( const WCHAR *str, DWORD len, DWORD *count ) +{ + const WCHAR *p = str; + WCHAR **ret; + int i = 0; + + *count = 0; + if (!str) return NULL; + while ((p - str) < len) + { + p += strlenW( p ) + 1; + (*count)++; + } + if (!(ret = msi_alloc( *count * sizeof(WCHAR *) ))) return NULL; + p = str; + while ((p - str) < len) + { + if (!(ret[i] = strdupW( p ))) + { + for (; i >= 0; i--) msi_free( ret[i] ); + msi_free( ret ); + return NULL; + } + p += strlenW( p ) + 1; + i++; + } + return ret; +} + +static WCHAR *flatten_multi_string_values( WCHAR **left, DWORD left_count, + WCHAR **right, DWORD right_count, DWORD *size ) +{ + WCHAR *ret, *p; + unsigned int i; + + *size = sizeof(WCHAR); + for (i = 0; i < left_count; i++) *size += (strlenW( left[i] ) + 1) * sizeof(WCHAR); + for (i = 0; i < right_count; i++) *size += (strlenW( right[i] ) + 1) * sizeof(WCHAR); + + if (!(ret = p = msi_alloc( *size ))) return NULL; + + for (i = 0; i < left_count; i++) + { + strcpyW( p, left[i] ); + p += strlenW( p ) + 1; + } + for (i = 0; i < right_count; i++) + { + strcpyW( p, right[i] ); + p += strlenW( p ) + 1; + } + *p = 0; + return ret; +} + +static DWORD remove_duplicate_values( WCHAR **old, DWORD old_count, + WCHAR **new, DWORD new_count ) +{ + DWORD ret = old_count; + unsigned int i, j, k; + + for (i = 0; i < new_count; i++) + { + for (j = 0; j < old_count; j++) + { + if (old[j] && !strcmpW( new[i], old[j] )) + { + msi_free( old[j] ); + for (k = j; k < old_count - 1; k++) { old[k] = old[k + 1]; } + old[k] = NULL; + ret--; + } + } + } + return ret; +} + +enum join_op +{ + JOIN_OP_APPEND, + JOIN_OP_PREPEND, + JOIN_OP_REPLACE +}; + +static WCHAR *join_multi_string_values( enum join_op op, WCHAR **old, DWORD old_count, + WCHAR **new, DWORD new_count, DWORD *size ) +{ + switch (op) + { + case JOIN_OP_APPEND: + old_count = remove_duplicate_values( old, old_count, new, new_count ); + return flatten_multi_string_values( old, old_count, new, new_count, size ); + + case JOIN_OP_PREPEND: + old_count = remove_duplicate_values( old, old_count, new, new_count ); + return flatten_multi_string_values( new, new_count, old, old_count, size ); + + case JOIN_OP_REPLACE: + return flatten_multi_string_values( new, new_count, NULL, 0, size ); + + default: + ERR("unhandled join op %u\n", op); + return NULL; + } +} + +static BYTE *build_multi_string_value( BYTE *old_value, DWORD old_size, + BYTE *new_value, DWORD new_size, DWORD *size ) +{ + DWORD i, old_len = 0, new_len = 0, old_count = 0, new_count = 0; + const WCHAR *new_ptr = NULL, *old_ptr = NULL; + enum join_op op = JOIN_OP_REPLACE; + WCHAR **old = NULL, **new = NULL; + BYTE *ret; + + if (new_size / sizeof(WCHAR) - 1 > 1) + { + new_ptr = (const WCHAR *)new_value; + new_len = new_size / sizeof(WCHAR) - 1; + + if (!new_ptr[0] && new_ptr[new_len - 1]) + { + op = JOIN_OP_APPEND; + new_len--; + new_ptr++; + } + else if (new_ptr[0] && !new_ptr[new_len - 1]) + { + op = JOIN_OP_PREPEND; + new_len--; + } + else if (new_len > 2 && !new_ptr[0] && !new_ptr[new_len - 1]) + { + op = JOIN_OP_REPLACE; + new_len -= 2; + new_ptr++; + } + new = split_multi_string_values( new_ptr, new_len, &new_count ); + } + if (old_size / sizeof(WCHAR) - 1 > 1) + { + old_ptr = (const WCHAR *)old_value; + old_len = old_size / sizeof(WCHAR) - 1; + old = split_multi_string_values( old_ptr, old_len, &old_count ); + } + ret = (BYTE *)join_multi_string_values( op, old, old_count, new, new_count, size ); + for (i = 0; i < old_count; i++) msi_free( old[i] ); + for (i = 0; i < new_count; i++) msi_free( new[i] ); + msi_free( old ); + msi_free( new ); + return ret; +} + +static BYTE *reg_get_value( HKEY hkey, const WCHAR *name, DWORD *type, DWORD *size ) +{ + BYTE *ret; + if (RegQueryValueExW( hkey, name, NULL, NULL, NULL, size )) return NULL; + if (!(ret = msi_alloc( *size ))) return NULL; + RegQueryValueExW( hkey, name, NULL, type, ret, size ); + return ret; +} + static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = param; - LPSTR value; + BYTE *new_value, *old_value = NULL; HKEY root_key, hkey; - DWORD type,size; + DWORD type, old_type, new_size, old_size = 0; LPWSTR deformated, uikey, keypath; - LPCWSTR szRoot, component, name, key; + const WCHAR *szRoot, *component, *name, *key, *str; MSICOMPONENT *comp; MSIRECORD * uirow; INT root; BOOL check_first = FALSE; - UINT rc; + int len; msi_ui_progress( package, 2, REG_PROGRESS_VALUE, 0, 0 ); @@ -2664,8 +2855,7 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) return ERROR_SUCCESS; deformat_string(package, key , &deformated); - size = strlenW(deformated) + strlenW(szRoot) + 1; - uikey = msi_alloc(size*sizeof(WCHAR)); + uikey = msi_alloc( (strlenW(deformated) + strlenW(szRoot) + 1) * sizeof(WCHAR) ); strcpyW(uikey,szRoot); strcatW(uikey,deformated); @@ -2678,34 +2868,46 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) msi_free(keypath); return ERROR_FUNCTION_FAILED; } - value = parse_value(package, MSI_RecordGetString(row, 5), &type, &size); + str = msi_record_get_string( row, 5, &len ); + if (str && len > strlenW( str )) + { + type = REG_MULTI_SZ; + new_size = (len + 1) * sizeof(WCHAR); + new_value = (BYTE *)msi_strdupW( str, len ); + } + else new_value = parse_value( package, str, &type, &new_size ); deformat_string(package, name, &deformated); if (!is_special_entry( name )) { + old_value = reg_get_value( hkey, deformated, &old_type, &old_size ); + if (type == REG_MULTI_SZ) + { + BYTE *new; + if (old_value && old_type != REG_MULTI_SZ) + { + msi_free( old_value ); + old_value = NULL; + old_size = 0; + } + new = build_multi_string_value( old_value, old_size, new_value, new_size, &new_size ); + msi_free( new_value ); + new_value = new; + } if (!check_first) { - TRACE("Setting value %s of %s\n", debugstr_w(deformated), - debugstr_w(uikey)); - RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value, size); + TRACE("setting value %s of %s type %u\n", debugstr_w(deformated), debugstr_w(uikey), type); + RegSetValueExW( hkey, deformated, 0, type, new_value, new_size ); } - else + else if (!old_value) { - DWORD sz = 0; - rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz); - if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA) + if (deformated || new_size) { - TRACE("value %s of %s checked already exists\n", debugstr_w(deformated), - debugstr_w(uikey)); - } - else - { - TRACE("Checked and setting value %s of %s\n", debugstr_w(deformated), - debugstr_w(uikey)); - if (deformated || size) - RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value, size); + TRACE("setting value %s of %s type %u\n", debugstr_w(deformated), debugstr_w(uikey), type); + RegSetValueExW( hkey, deformated, 0, type, new_value, new_size ); } } + else TRACE("not overwriting existing value %s of %s\n", debugstr_w(deformated), debugstr_w(uikey)); } RegCloseKey(hkey); @@ -2713,11 +2915,12 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) MSI_RecordSetStringW(uirow,2,deformated); MSI_RecordSetStringW(uirow,1,uikey); if (type == REG_SZ || type == REG_EXPAND_SZ) - MSI_RecordSetStringW(uirow, 3, (LPWSTR)value); + MSI_RecordSetStringW(uirow, 3, (LPWSTR)new_value); msi_ui_actiondata( package, szWriteRegistryValues, uirow ); msiobj_release( &uirow->hdr ); - msi_free(value); + msi_free(new_value); + msi_free(old_value); msi_free(deformated); msi_free(uikey); msi_free(keypath); @@ -3293,9 +3496,9 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) if (package->need_rollback) action = comp->Installed; else action = comp->ActionRequest; - TRACE("Component %s (%s), Keypath=%s, RefCount=%u Action=%u\n", + TRACE("Component %s (%s) Keypath=%s RefCount=%u Clients=%u Action=%u\n", debugstr_w(comp->Component), debugstr_w(squished_cc), - debugstr_w(comp->FullKeypath), comp->RefCount, action); + debugstr_w(comp->FullKeypath), comp->RefCount, comp->num_clients, action); if (action == INSTALLSTATE_LOCAL || action == INSTALLSTATE_SOURCE) { @@ -3358,10 +3561,13 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) } else if (action == INSTALLSTATE_ABSENT) { - if (package->Context == MSIINSTALLCONTEXT_MACHINE) - MSIREG_DeleteUserDataComponentKey(comp->ComponentId, szLocalSid); - else - MSIREG_DeleteUserDataComponentKey(comp->ComponentId, NULL); + if (comp->num_clients <= 0) + { + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + MSIREG_DeleteUserDataComponentKey( comp->ComponentId, szLocalSid ); + else + MSIREG_DeleteUserDataComponentKey( comp->ComponentId, NULL ); + } } /* UI stuff */ @@ -4514,27 +4720,27 @@ static UINT ACTION_RemoveIniValues( MSIPACKAGE *package ) static void register_dll( const WCHAR *dll, BOOL unregister ) { - HMODULE hmod; + static const WCHAR regW[] = + {'r','e','g','s','v','r','3','2','.','e','x','e',' ','\"','%','s','\"',0}; + static const WCHAR unregW[] = + {'r','e','g','s','v','r','3','2','.','e','x','e',' ','/','u',' ','\"','%','s','\"',0}; + PROCESS_INFORMATION pi; + STARTUPINFOW si; + WCHAR *cmd; - hmod = LoadLibraryExW( dll, 0, LOAD_WITH_ALTERED_SEARCH_PATH ); - if (hmod) + if (!(cmd = msi_alloc( strlenW(dll) * sizeof(WCHAR) + sizeof(unregW) ))) return; + + if (unregister) sprintfW( cmd, unregW, dll ); + else sprintfW( cmd, regW, dll ); + + memset( &si, 0, sizeof(STARTUPINFOW) ); + if (CreateProcessW( NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi )) { - HRESULT (WINAPI *func_ptr)( void ); - const char *func = unregister ? "DllUnregisterServer" : "DllRegisterServer"; - - func_ptr = (void *)GetProcAddress( hmod, func ); - if (func_ptr) - { - HRESULT hr = func_ptr(); - if (FAILED( hr )) - WARN("failed to register dll 0x%08x\n", hr); - } - else - WARN("entry point %s not found\n", func); - FreeLibrary( hmod ); - return; + CloseHandle( pi.hThread ); + msi_dialog_check_messages( pi.hProcess ); + CloseHandle( pi.hProcess ); } - WARN("failed to load library %u\n", GetLastError()); + msi_free( cmd ); } static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param) @@ -4837,8 +5043,6 @@ static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) {'H','e','l','p','T','e','l','e','p','h','o','n','e',0}; static const WCHAR szARPINSTALLLOCATION[] = {'A','R','P','I','N','S','T','A','L','L','L','O','C','A','T','I','O','N',0}; - static const WCHAR szInstallLocation[] = - {'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0}; static const WCHAR szManufacturer[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0}; static const WCHAR szPublisher[] = @@ -4896,7 +5100,7 @@ static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) { msi_reg_set_val_dword( hkey, szSystemComponent, 1 ); } - size = deformat_string(package, modpath_fmt, &buffer); + size = deformat_string(package, modpath_fmt, &buffer) * sizeof(WCHAR); RegSetValueExW(hkey, szModifyPath, 0, REG_EXPAND_SZ, (LPBYTE)buffer, size); RegSetValueExW(hkey, szUninstallString, 0, REG_EXPAND_SZ, (LPBYTE)buffer, size); msi_free(buffer); @@ -5548,6 +5752,7 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) LPWSTR depends = NULL, pass = NULL, args = NULL, image_path = NULL; DWORD serv_type, start_type, err_control; SERVICE_DESCRIPTIONW sd = {NULL}; + UINT ret = ERROR_SUCCESS; comp = MSI_RecordGetString( rec, 12 ); component = msi_get_loaded_component( package, comp ); @@ -5605,7 +5810,10 @@ static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param) { int len = strlenW(file->TargetPath) + strlenW(args) + 2; if (!(image_path = msi_alloc(len * sizeof(WCHAR)))) - return ERROR_OUTOFMEMORY; + { + ret = ERROR_OUTOFMEMORY; + goto done; + } strcpyW(image_path, file->TargetPath); strcatW(image_path, szSpace); @@ -5639,7 +5847,7 @@ done: msi_free(depends); msi_free(args); - return ERROR_SUCCESS; + return ret; } static UINT ACTION_InstallServices( MSIPACKAGE *package ) @@ -5839,6 +6047,7 @@ static BOOL stop_service_dependents(SC_HANDLE scm, SC_HANDLE service) ENUM_SERVICE_STATUSW *dependencies; SERVICE_STATUS ss; SC_HANDLE depserv; + BOOL stopped, ret = FALSE; if (EnumDependentServicesW(service, SERVICE_ACTIVE, NULL, 0, &needed, &count)) @@ -5853,24 +6062,26 @@ static BOOL stop_service_dependents(SC_HANDLE scm, SC_HANDLE service) if (!EnumDependentServicesW(service, SERVICE_ACTIVE, dependencies, needed, &needed, &count)) - goto error; + goto done; for (i = 0; i < count; i++) { depserv = OpenServiceW(scm, dependencies[i].lpServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS); if (!depserv) - goto error; + goto done; - if (!ControlService(depserv, SERVICE_CONTROL_STOP, &ss)) - goto error; + stopped = ControlService(depserv, SERVICE_CONTROL_STOP, &ss); + CloseServiceHandle(depserv); + if (!stopped) + goto done; } - return TRUE; + ret = TRUE; -error: +done: msi_free(dependencies); - return FALSE; + return ret; } static UINT stop_service( LPCWSTR name ) @@ -6959,7 +7170,7 @@ UINT msi_validate_product_id( MSIPACKAGE *package ) if (key && template) { FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) ); - r = msi_set_property( package->db, szProductID, key ); + r = msi_set_property( package->db, szProductID, key, -1 ); } msi_free( template ); msi_free( key ); @@ -6999,7 +7210,7 @@ static UINT ACTION_DisableRollback( MSIPACKAGE *package ) { TRACE("%p\n", package); - msi_set_property( package->db, szRollbackDisabled, szOne ); + msi_set_property( package->db, szRollbackDisabled, szOne, -1 ); return ERROR_SUCCESS; } @@ -7516,11 +7727,11 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, static const WCHAR szDisableRollback[] = {'D','I','S','A','B','L','E','R','O','L','L','B','A','C','K',0}; static const WCHAR szAction[] = {'A','C','T','I','O','N',0}; static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0}; - WCHAR *reinstall = NULL; + WCHAR *reinstall, *remove, *patch; BOOL ui_exists; UINT rc; - msi_set_property( package->db, szAction, szInstall ); + msi_set_property( package->db, szAction, szInstall, -1 ); package->script->InWhatSequence = SEQUENCE_INSTALL; @@ -7567,10 +7778,13 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, msi_apply_transforms( package ); msi_apply_patches( package ); - if (!szCommandLine && msi_get_property_int( package->db, szInstalled, 0 )) + patch = msi_dup_property( package->db, szPatch ); + remove = msi_dup_property( package->db, szRemove ); + reinstall = msi_dup_property( package->db, szReinstall ); + if (msi_get_property_int( package->db, szInstalled, 0 ) && !remove && !reinstall && !patch) { - TRACE("setting reinstall property\n"); - msi_set_property( package->db, szReinstall, szAll ); + TRACE("setting REINSTALL property to ALL\n"); + msi_set_property( package->db, szReinstall, szAll, -1 ); } /* properties may have been added by a transform */ @@ -7583,7 +7797,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, if (msi_get_property_int( package->db, szDisableRollback, 0 )) { TRACE("disabling rollback\n"); - msi_set_property( package->db, szRollbackDisabled, szOne ); + msi_set_property( package->db, szRollbackDisabled, szOne, -1 ); } if (needs_ui_sequence( package)) @@ -7621,12 +7835,14 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, /* finish up running custom actions */ ACTION_FinishCustomActions(package); - if (package->need_rollback && !(reinstall = msi_dup_property( package->db, szReinstall ))) + if (package->need_rollback && !reinstall) { WARN("installation failed, running rollback script\n"); execute_script( package, SCRIPT_ROLLBACK ); } msi_free( reinstall ); + msi_free( remove ); + msi_free( patch ); if (rc == ERROR_SUCCESS && package->need_reboot_at_end) return ERROR_SUCCESS_REBOOT_REQUIRED; diff --git a/dll/win32/msi/appsearch.c b/dll/win32/msi/appsearch.c index 21daf43f334..0d9c3022f09 100644 --- a/dll/win32/msi/appsearch.c +++ b/dll/win32/msi/appsearch.c @@ -1093,7 +1093,7 @@ static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) r = ACTION_AppSearchSigName(package, sigName, &sig, &value); if (value) { - r = msi_set_property( package->db, propName, value ); + r = msi_set_property( package->db, propName, value, -1 ); if (r == ERROR_SUCCESS && !strcmpW( propName, szSourceDir )) msi_reset_folders( package, TRUE ); @@ -1153,7 +1153,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param) if (value) { TRACE("Found signature %s\n", debugstr_w(signature)); - msi_set_property(package->db, success, szOne); + msi_set_property( package->db, success, szOne, -1 ); msi_free(value); r = ERROR_NO_MORE_ITEMS; } diff --git a/dll/win32/msi/automation.c b/dll/win32/msi/automation.c index e55717af7f1..8164463a581 100644 --- a/dll/win32/msi/automation.c +++ b/dll/win32/msi/automation.c @@ -42,36 +42,116 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); #define REG_INDEX_CLASSES_ROOT 0 #define REG_INDEX_DYN_DATA 6 +typedef struct AutomationObject AutomationObject; + +/* function that is called from AutomationObject::Invoke, specific to this type of object */ +typedef HRESULT (*auto_invoke_func)(AutomationObject* This, + DISPID dispIdMember, REFIID riid, LCID lcid, WORD flags, DISPPARAMS* pDispParams, + VARIANT* result, EXCEPINFO* ei, UINT* arg_err); +/* function that is called from AutomationObject::Release when the object is being freed + to free any private data structures (or NULL) */ +typedef void (*auto_free_func)(AutomationObject* This); + +typedef struct { + REFIID riid; + auto_invoke_func fn_invoke; + auto_free_func fn_free; +} tid_id_t; + + +static HRESULT database_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*); +static HRESULT installer_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*); +static HRESULT record_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*); +static HRESULT session_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*); +static HRESULT list_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*); +static void list_free(AutomationObject*); +static HRESULT summaryinfo_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*); +static HRESULT view_invoke(AutomationObject*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*); + +static tid_id_t tid_ids[] = { + { &DIID_Database, database_invoke }, + { &DIID_Installer, installer_invoke }, + { &DIID_Record, record_invoke }, + { &DIID_Session, session_invoke }, + { &DIID_StringList, list_invoke, list_free }, + { &DIID_SummaryInfo, summaryinfo_invoke }, + { &DIID_View, view_invoke } +}; + +static ITypeLib *typelib; +static ITypeInfo *typeinfos[LAST_tid]; + +static const IID *get_riid_from_tid(tid_t tid) +{ + return tid_ids[tid].riid; +} + +HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) +{ + HRESULT hr; + + if (!typelib) + { + ITypeLib *lib; + + hr = LoadRegTypeLib(&LIBID_WindowsInstaller, 1, 0, LOCALE_NEUTRAL, &lib); + if (FAILED(hr)) { + static const WCHAR msiserverW[] = {'m','s','i','s','e','r','v','e','r','.','t','l','b',0}; + hr = LoadTypeLib(msiserverW, &lib); + if (FAILED(hr)) { + ERR("Could not load msiserver.tlb\n"); + return hr; + } + } + + if (InterlockedCompareExchangePointer((void**)&typelib, lib, NULL)) + ITypeLib_Release(lib); + } + + if (!typeinfos[tid]) + { + ITypeInfo *ti; + + hr = ITypeLib_GetTypeInfoOfGuid(typelib, get_riid_from_tid(tid), &ti); + if (FAILED(hr)) { + ERR("Could not load ITypeInfo for %s\n", debugstr_guid(get_riid_from_tid(tid))); + return hr; + } + + if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) + ITypeInfo_Release(ti); + } + + *typeinfo = typeinfos[tid]; + return S_OK; +} + +void release_typelib(void) +{ + unsigned i; + + for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) + if (typeinfos[i]) + ITypeInfo_Release(typeinfos[i]); + + if (typelib) + ITypeLib_Release(typelib); +} + /* * AutomationObject - "base" class for all automation objects. For each interface, we implement Invoke function * called from AutomationObject::Invoke. */ - -typedef struct AutomationObject AutomationObject; - -typedef HRESULT (*autoInvokeFunc)(AutomationObject* This, - DISPID dispIdMember, REFIID riid, LCID lcid, WORD flags, DISPPARAMS* pDispParams, - VARIANT* result, EXCEPINFO* ei, UINT* arg_err); - -typedef void (*autoFreeFunc)(AutomationObject* This); - struct AutomationObject { IDispatch IDispatch_iface; IProvideMultipleClassInfo IProvideMultipleClassInfo_iface; LONG ref; - /* Clsid for this class and it's appropriate ITypeInfo object */ - LPCLSID clsid; - ITypeInfo *iTypeInfo; + /* type id for this class */ + tid_t tid; /* The MSI handle of the current object */ MSIHANDLE msiHandle; - - /* A function that is called from AutomationObject::Invoke, specific to this type of object. */ - autoInvokeFunc funcInvoke; - /* A function that is called from AutomationObject::Release when the object is being freed to free any private - * data structures (or NULL) */ - autoFreeFunc funcFree; }; typedef struct { @@ -110,37 +190,6 @@ static inline AutomationObject *impl_from_IDispatch( IDispatch *iface ) return CONTAINING_RECORD(iface, AutomationObject, IDispatch_iface); } -/* Load type info so we don't have to process GetIDsOfNames */ -HRESULT load_type_info(IDispatch *iface, ITypeInfo **pptinfo, REFIID clsid, LCID lcid) -{ - static const WCHAR msiserverW[] = {'m','s','i','s','e','r','v','e','r','.','t','l','b',0}; - ITypeInfo *ti = NULL; - ITypeLib *lib = NULL; - HRESULT hr; - - TRACE("(%p)->(%s, %d)\n", iface, debugstr_guid(clsid), lcid); - - /* Load registered type library */ - hr = LoadRegTypeLib(&LIBID_WindowsInstaller, 1, 0, lcid, &lib); - if (FAILED(hr)) { - hr = LoadTypeLib(msiserverW, &lib); - if (FAILED(hr)) { - ERR("Could not load msiserver.tlb\n"); - return hr; - } - } - - /* Get type information for object */ - hr = ITypeLib_GetTypeInfoOfGuid(lib, clsid, &ti); - ITypeLib_Release(lib); - if (FAILED(hr)) { - ERR("Could not load ITypeInfo for %s\n", debugstr_guid(clsid)); - return hr; - } - *pptinfo = ti; - return S_OK; -} - /* AutomationObject methods */ static HRESULT WINAPI AutomationObject_QueryInterface(IDispatch* iface, REFIID riid, void** ppvObject) { @@ -155,7 +204,7 @@ static HRESULT WINAPI AutomationObject_QueryInterface(IDispatch* iface, REFIID r if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch) || - IsEqualGUID(riid, This->clsid)) + IsEqualGUID(riid, get_riid_from_tid(This->tid))) *ppvObject = &This->IDispatch_iface; else if (IsEqualGUID(riid, &IID_IProvideClassInfo) || IsEqualGUID(riid, &IID_IProvideClassInfo2) || @@ -190,8 +239,7 @@ static ULONG WINAPI AutomationObject_Release(IDispatch* iface) if (!ref) { - if (This->funcFree) This->funcFree(This); - ITypeInfo_Release(This->iTypeInfo); + if (tid_ids[This->tid].fn_free) tid_ids[This->tid].fn_free(This); MsiCloseHandle(This->msiHandle); msi_free(This); } @@ -217,11 +265,16 @@ static HRESULT WINAPI AutomationObject_GetTypeInfo( ITypeInfo** ppTInfo) { AutomationObject *This = impl_from_IDispatch(iface); + HRESULT hr; + TRACE("(%p/%p)->(%d,%d,%p)\n", iface, This, iTInfo, lcid, ppTInfo); - ITypeInfo_AddRef(This->iTypeInfo); - *ppTInfo = This->iTypeInfo; - return S_OK; + hr = get_typeinfo(This->tid, ppTInfo); + if (FAILED(hr)) + return hr; + + ITypeInfo_AddRef(*ppTInfo); + return hr; } static HRESULT WINAPI AutomationObject_GetIDsOfNames( @@ -233,18 +286,25 @@ static HRESULT WINAPI AutomationObject_GetIDsOfNames( DISPID* rgDispId) { AutomationObject *This = impl_from_IDispatch(iface); + ITypeInfo *ti; HRESULT hr; + TRACE("(%p/%p)->(%p,%p,%d,%d,%p)\n", iface, This, riid, rgszNames, cNames, lcid, rgDispId); if (!IsEqualGUID(riid, &IID_NULL)) return E_INVALIDARG; - hr = ITypeInfo_GetIDsOfNames(This->iTypeInfo, rgszNames, cNames, rgDispId); + + hr = get_typeinfo(This->tid, &ti); + if (FAILED(hr)) + return hr; + + hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); if (hr == DISP_E_UNKNOWNNAME) { UINT idx; for (idx=0; idxclsid)); + FIXME("Unknown member %s, clsid %s\n", debugstr_w(rgszNames[idx]), debugstr_guid(get_riid_from_tid(This->tid))); } } return hr; @@ -270,6 +330,7 @@ static HRESULT WINAPI AutomationObject_Invoke( unsigned int uArgErr; VARIANT varResultDummy; BSTR bstrName = NULL; + ITypeInfo *ti; TRACE("(%p/%p)->(%d,%p,%d,%d,%p,%p,%p,%p)\n", iface, This, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); @@ -289,21 +350,26 @@ static HRESULT WINAPI AutomationObject_Invoke( if (puArgErr == NULL) puArgErr = &uArgErr; if (pVarResult == NULL) pVarResult = &varResultDummy; + hr = get_typeinfo(This->tid, &ti); + if (FAILED(hr)) + return hr; + /* Assume return type is void unless determined otherwise */ VariantInit(pVarResult); /* If we are tracing, we want to see the name of the member we are invoking */ if (TRACE_ON(msi)) { - ITypeInfo_GetDocumentation(This->iTypeInfo, dispIdMember, &bstrName, NULL, NULL, NULL); + ITypeInfo_GetDocumentation(ti, dispIdMember, &bstrName, NULL, NULL, NULL); TRACE("Method %d, %s\n", dispIdMember, debugstr_w(bstrName)); } - hr = This->funcInvoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr); + hr = tid_ids[This->tid].fn_invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr); if (hr == DISP_E_MEMBERNOTFOUND) { - if (bstrName == NULL) ITypeInfo_GetDocumentation(This->iTypeInfo, dispIdMember, &bstrName, NULL, NULL, NULL); - FIXME("Method %d, %s wflags %d not implemented, clsid %s\n", dispIdMember, debugstr_w(bstrName), wFlags, debugstr_guid(This->clsid)); + if (bstrName == NULL) ITypeInfo_GetDocumentation(ti, dispIdMember, &bstrName, NULL, NULL, NULL); + FIXME("Method %d, %s wflags %d not implemented, clsid %s\n", dispIdMember, debugstr_w(bstrName), wFlags, + debugstr_guid(get_riid_from_tid(This->tid))); } else if (pExcepInfo && (hr == DISP_E_PARAMNOTFOUND || @@ -315,7 +381,7 @@ static HRESULT WINAPI AutomationObject_Invoke( unsigned namesNo, i; BOOL bFirst = TRUE; - if (FAILED(ITypeInfo_GetNames(This->iTypeInfo, dispIdMember, bstrParamNames, + if (FAILED(ITypeInfo_GetNames(ti, dispIdMember, bstrParamNames, MAX_FUNC_PARAMS, &namesNo))) { TRACE("Failed to retrieve names for dispIdMember %d\n", dispIdMember); @@ -391,8 +457,15 @@ static ULONG WINAPI ProvideMultipleClassInfo_Release(IProvideMultipleClassInfo* static HRESULT WINAPI ProvideMultipleClassInfo_GetClassInfo(IProvideMultipleClassInfo* iface, ITypeInfo** ppTI) { AutomationObject *This = impl_from_IProvideMultipleClassInfo(iface); + HRESULT hr; + TRACE("(%p/%p)->(%p)\n", iface, This, ppTI); - return load_type_info(&This->IDispatch_iface, ppTI, This->clsid, 0); + + hr = get_typeinfo(This->tid, ppTI); + if (SUCCEEDED(hr)) + ITypeInfo_AddRef(*ppTI); + + return hr; } static HRESULT WINAPI ProvideMultipleClassInfo_GetGUID(IProvideMultipleClassInfo* iface, DWORD dwGuidKind, GUID* pGUID) @@ -403,7 +476,7 @@ static HRESULT WINAPI ProvideMultipleClassInfo_GetGUID(IProvideMultipleClassInfo if (dwGuidKind != GUIDKIND_DEFAULT_SOURCE_DISP_IID) return E_INVALIDARG; else { - *pGUID = *This->clsid; + *pGUID = *get_riid_from_tid(This->tid); return S_OK; } } @@ -420,7 +493,7 @@ static HRESULT WINAPI ProvideMultipleClassInfo_GetMultiTypeInfoCount(IProvideMul static HRESULT WINAPI ProvideMultipleClassInfo_GetInfoOfIndex(IProvideMultipleClassInfo* iface, ULONG iti, DWORD dwFlags, - ITypeInfo** pptiCoClass, + ITypeInfo** ti, DWORD* pdwTIFlags, ULONG* pcdispidReserved, IID* piidPrimary, @@ -428,13 +501,19 @@ static HRESULT WINAPI ProvideMultipleClassInfo_GetInfoOfIndex(IProvideMultipleCl { AutomationObject *This = impl_from_IProvideMultipleClassInfo(iface); - TRACE("(%p/%p)->(%d,%d,%p,%p,%p,%p,%p)\n", iface, This, iti, dwFlags, pptiCoClass, pdwTIFlags, pcdispidReserved, piidPrimary, piidSource); + TRACE("(%p/%p)->(%d,%d,%p,%p,%p,%p,%p)\n", iface, This, iti, dwFlags, ti, pdwTIFlags, pcdispidReserved, piidPrimary, piidSource); if (iti != 0) return E_INVALIDARG; if (dwFlags & MULTICLASSINFO_GETTYPEINFO) - load_type_info(&This->IDispatch_iface, pptiCoClass, This->clsid, 0); + { + HRESULT hr = get_typeinfo(This->tid, ti); + if (FAILED(hr)) + return hr; + + ITypeInfo_AddRef(*ti); + } if (dwFlags & MULTICLASSINFO_GETNUMRESERVEDDISPIDS) { @@ -442,13 +521,11 @@ static HRESULT WINAPI ProvideMultipleClassInfo_GetInfoOfIndex(IProvideMultipleCl *pcdispidReserved = 0; } - if (dwFlags & MULTICLASSINFO_GETIIDPRIMARY){ - *piidPrimary = *This->clsid; - } + if (dwFlags & MULTICLASSINFO_GETIIDPRIMARY) + *piidPrimary = *get_riid_from_tid(This->tid); - if (dwFlags & MULTICLASSINFO_GETIIDSOURCE){ - *piidSource = *This->clsid; - } + if (dwFlags & MULTICLASSINFO_GETIIDSOURCE) + *piidSource = *get_riid_from_tid(This->tid); return S_OK; } @@ -464,23 +541,18 @@ static const IProvideMultipleClassInfoVtbl ProvideMultipleClassInfoVtbl = ProvideMultipleClassInfo_GetInfoOfIndex }; -static HRESULT init_automation_object(AutomationObject *This, MSIHANDLE msiHandle, REFIID clsid, - autoInvokeFunc invokeFunc, autoFreeFunc freeFunc) +static HRESULT init_automation_object(AutomationObject *This, MSIHANDLE msiHandle, tid_t tid) { - TRACE("(%p, %d, %s, %p, %p)\n", This, msiHandle, debugstr_guid(clsid), invokeFunc, freeFunc); + TRACE("(%p, %d, %s)\n", This, msiHandle, debugstr_guid(get_riid_from_tid(tid))); This->IDispatch_iface.lpVtbl = &AutomationObjectVtbl; This->IProvideMultipleClassInfo_iface.lpVtbl = &ProvideMultipleClassInfoVtbl; This->ref = 1; This->msiHandle = msiHandle; - This->clsid = (LPCLSID)clsid; - This->funcInvoke = invokeFunc; - This->funcFree = freeFunc; + This->tid = tid; - /* Load our TypeInfo so we don't have to process GetIDsOfNames */ - This->iTypeInfo = NULL; - return load_type_info(&This->IDispatch_iface, &This->iTypeInfo, clsid, 0); + return S_OK; } /* @@ -682,7 +754,7 @@ static HRESULT DispGetParam_CopyOnly( &pdispparams->rgvarg[pos]); } -static HRESULT SummaryInfoImpl_Invoke( +static HRESULT summaryinfo_invoke( AutomationObject* This, DISPID dispIdMember, REFIID riid, @@ -834,7 +906,7 @@ static HRESULT SummaryInfoImpl_Invoke( return S_OK; } -static HRESULT RecordImpl_Invoke( +static HRESULT record_invoke( AutomationObject* This, DISPID dispIdMember, REFIID riid, @@ -846,7 +918,7 @@ static HRESULT RecordImpl_Invoke( UINT* puArgErr) { WCHAR *szString; - DWORD dwLen; + DWORD dwLen = 0; UINT ret; VARIANTARG varg0, varg1; HRESULT hr; @@ -933,7 +1005,7 @@ static HRESULT create_record(MSIHANDLE msiHandle, IDispatch **disp) record = msi_alloc(sizeof(*record)); if (!record) return E_OUTOFMEMORY; - hr = init_automation_object(record, msiHandle, &DIID_Record, RecordImpl_Invoke, NULL); + hr = init_automation_object(record, msiHandle, Record_tid); if (hr != S_OK) { msi_free(record); @@ -945,7 +1017,7 @@ static HRESULT create_record(MSIHANDLE msiHandle, IDispatch **disp) return hr; } -static HRESULT ListImpl_Invoke( +static HRESULT list_invoke( AutomationObject* This, DISPID dispIdMember, REFIID riid, @@ -1002,7 +1074,7 @@ static HRESULT ListImpl_Invoke( return S_OK; } -static void ListImpl_Free(AutomationObject *This) +static void list_free(AutomationObject *This) { ListObject *list = (ListObject*)This; int i; @@ -1049,7 +1121,7 @@ static HRESULT create_list(const WCHAR *product, IDispatch **dispatch) list = msi_alloc_zero(sizeof(ListObject)); if (!list) return E_OUTOFMEMORY; - hr = init_automation_object(&list->autoobj, 0, &DIID_StringList, ListImpl_Invoke, ListImpl_Free); + hr = init_automation_object(&list->autoobj, 0, StringList_tid); if (hr != S_OK) { msi_free(list); @@ -1092,7 +1164,7 @@ static HRESULT create_list(const WCHAR *product, IDispatch **dispatch) return S_OK; } -static HRESULT ViewImpl_Invoke( +static HRESULT view_invoke( AutomationObject* This, DISPID dispIdMember, REFIID riid, @@ -1200,7 +1272,7 @@ static HRESULT DatabaseImpl_LastErrorRecord(WORD wFlags, return S_OK; } -static HRESULT DatabaseImpl_Invoke( +HRESULT database_invoke( AutomationObject* This, DISPID dispIdMember, REFIID riid, @@ -1285,7 +1357,7 @@ static HRESULT DatabaseImpl_Invoke( return S_OK; } -static HRESULT SessionImpl_Invoke( +static HRESULT session_invoke( AutomationObject* This, DISPID dispIdMember, REFIID riid, @@ -2250,7 +2322,7 @@ static HRESULT InstallerImpl_RelatedProducts(WORD flags, return hr; } -static HRESULT InstallerImpl_Invoke( +static HRESULT installer_invoke( AutomationObject* This, DISPID dispIdMember, REFIID riid, @@ -2363,7 +2435,7 @@ HRESULT create_msiserver(IUnknown *outer, void **ppObj) installer = msi_alloc(sizeof(AutomationObject)); if (!installer) return E_OUTOFMEMORY; - hr = init_automation_object(installer, 0, &DIID_Installer, InstallerImpl_Invoke, NULL); + hr = init_automation_object(installer, 0, Installer_tid); if (hr != S_OK) { msi_free(installer); @@ -2383,7 +2455,7 @@ HRESULT create_session(MSIHANDLE msiHandle, IDispatch *installer, IDispatch **di session = msi_alloc(sizeof(SessionObject)); if (!session) return E_OUTOFMEMORY; - hr = init_automation_object(&session->autoobj, msiHandle, &DIID_Session, SessionImpl_Invoke, NULL); + hr = init_automation_object(&session->autoobj, msiHandle, Session_tid); if (hr != S_OK) { msi_free(session); @@ -2406,7 +2478,7 @@ static HRESULT create_database(MSIHANDLE msiHandle, IDispatch **dispatch) database = msi_alloc(sizeof(AutomationObject)); if (!database) return E_OUTOFMEMORY; - hr = init_automation_object(database, msiHandle, &DIID_Database, DatabaseImpl_Invoke, NULL); + hr = init_automation_object(database, msiHandle, Database_tid); if (hr != S_OK) { msi_free(database); @@ -2428,7 +2500,7 @@ static HRESULT create_view(MSIHANDLE msiHandle, IDispatch **dispatch) view = msi_alloc(sizeof(AutomationObject)); if (!view) return E_OUTOFMEMORY; - hr = init_automation_object(view, msiHandle, &DIID_View, ViewImpl_Invoke, NULL); + hr = init_automation_object(view, msiHandle, View_tid); if (hr != S_OK) { msi_free(view); @@ -2448,7 +2520,7 @@ static HRESULT create_summaryinfo(MSIHANDLE msiHandle, IDispatch **disp) info = msi_alloc(sizeof(*info)); if (!info) return E_OUTOFMEMORY; - hr = init_automation_object(info, msiHandle, &DIID_SummaryInfo, SummaryInfoImpl_Invoke, NULL); + hr = init_automation_object(info, msiHandle, SummaryInfo_tid); if (hr != S_OK) { msi_free(info); diff --git a/dll/win32/msi/custom.c b/dll/win32/msi/custom.c index 8f32e590300..a33f19d3512 100644 --- a/dll/win32/msi/custom.c +++ b/dll/win32/msi/custom.c @@ -184,25 +184,21 @@ static LPWSTR msi_get_deferred_action(LPCWSTR action, LPCWSTR actiondata, return deferred; } -static void set_deferred_action_props(MSIPACKAGE *package, LPWSTR deferred_data) +static void set_deferred_action_props( MSIPACKAGE *package, const WCHAR *deferred_data ) { - LPWSTR end, beg = deferred_data + 1; - static const WCHAR sep[] = {'<','=','>',0}; + const WCHAR *end, *beg = deferred_data + 1; end = strstrW(beg, sep); - *end = '\0'; - msi_set_property(package->db, szCustomActionData, beg); + msi_set_property( package->db, szCustomActionData, beg, end - beg ); beg = end + 3; end = strstrW(beg, sep); - *end = '\0'; - msi_set_property(package->db, szUserSID, beg); + msi_set_property( package->db, szUserSID, beg, end - beg ); beg = end + 3; end = strchrW(beg, ']'); - *end = '\0'; - msi_set_property(package->db, szProductCode, beg); + msi_set_property( package->db, szProductCode, beg, end - beg ); } static MSIBINARY *create_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll ) @@ -1229,23 +1225,20 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL UINT rc = ERROR_SUCCESS; MSIRECORD *row; UINT type; - LPCWSTR source, target; - LPWSTR ptr, deferred_data = NULL; - LPWSTR deformated = NULL, action_copy = strdupW(action); + const WCHAR *source, *target, *ptr, *deferred_data = NULL; + WCHAR *deformated = NULL; + int len; /* deferred action: [properties]Action */ - if ((ptr = strrchrW(action_copy, ']'))) + if ((ptr = strrchrW(action, ']'))) { - deferred_data = action_copy; + deferred_data = action; action = ptr + 1; } row = MSI_QueryGetRecord( package->db, query, action ); if (!row) - { - msi_free(action_copy); return ERROR_CALL_NOT_IMPLEMENTED; - } type = MSI_RecordGetInteger(row,2); source = MSI_RecordGetString(row,3); @@ -1284,9 +1277,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL if (deferred_data) set_deferred_action_props(package, deferred_data); else if (actiondata) - msi_set_property(package->db, szCustomActionData, actiondata); + msi_set_property( package->db, szCustomActionData, actiondata, -1 ); else - msi_set_property(package->db, szCustomActionData, szEmpty); + msi_set_property( package->db, szCustomActionData, szEmpty, -1 ); msi_free(actiondata); } @@ -1334,8 +1327,8 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL if (!source) break; - deformat_string(package,target,&deformated); - rc = msi_set_property( package->db, source, deformated ); + len = deformat_string( package, target, &deformated ); + rc = msi_set_property( package->db, source, deformated, len ); if (rc == ERROR_SUCCESS && !strcmpW( source, szSourceDir )) msi_reset_folders( package, TRUE ); msi_free(deformated); @@ -1365,7 +1358,6 @@ end: package->scheduled_action_running = FALSE; package->commit_action_running = FALSE; package->rollback_action_running = FALSE; - msi_free(action_copy); msiobj_release(&row->hdr); return rc; } diff --git a/dll/win32/msi/database.c b/dll/win32/msi/database.c index 944cf8f66e8..9c0d3466aba 100644 --- a/dll/win32/msi/database.c +++ b/dll/win32/msi/database.c @@ -130,7 +130,7 @@ UINT msi_clone_open_stream( MSIDATABASE *db, IStorage *stg, LPCWSTR name, IStrea UINT msi_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm ) { HRESULT r; - IStorage *stg = 0; + IStorage *stg; WCHAR decoded[MAX_STREAM_NAME_LEN]; decode_streamname( stname, decoded ); diff --git a/dll/win32/msi/dialog.c b/dll/win32/msi/dialog.c index 66d87864c52..c0ff2043a5e 100644 --- a/dll/win32/msi/dialog.c +++ b/dll/win32/msi/dialog.c @@ -309,7 +309,7 @@ static UINT msi_dialog_add_font( MSIRECORD *rec, LPVOID param ) /* create a font and add it to the list */ name = MSI_RecordGetString( rec, 1 ); - font = msi_alloc( sizeof *font + strlenW( name )*sizeof (WCHAR) ); + font = msi_alloc( FIELD_OFFSET( msi_font, name[strlenW( name ) + 1] )); strcpyW( font->name, name ); list_add_head( &dialog->fonts, &font->entry ); @@ -414,7 +414,7 @@ static msi_control *msi_dialog_create_window( msi_dialog *dialog, style |= WS_CHILD; - control = msi_alloc( sizeof *control + strlenW(name)*sizeof(WCHAR) ); + control = msi_alloc( FIELD_OFFSET( msi_control, name[strlenW( name ) + 1] )); if (!control) return NULL; @@ -583,7 +583,7 @@ static void msi_dialog_update_controls( msi_dialog *dialog, LPCWSTR property ) static void msi_dialog_set_property( MSIPACKAGE *package, LPCWSTR property, LPCWSTR value ) { - UINT r = msi_set_property( package->db, property, value ); + UINT r = msi_set_property( package->db, property, value, -1 ); if (r == ERROR_SUCCESS && !strcmpW( property, szSourceDir )) msi_reset_folders( package, TRUE ); } @@ -3939,7 +3939,7 @@ static UINT error_dialog_handler(MSIPACKAGE *package, LPCWSTR event, if ( !strcmpW( argument, error_abort ) || !strcmpW( argument, error_cancel ) || !strcmpW( argument, error_no ) ) { - msi_set_property( package->db, result_prop, error_abort ); + msi_set_property( package->db, result_prop, error_abort, -1 ); } ControlEvent_CleanupSubscriptions(package); diff --git a/dll/win32/msi/events.c b/dll/win32/msi/events.c index d42ac5b4e99..707a4a235fd 100644 --- a/dll/win32/msi/events.c +++ b/dll/win32/msi/events.c @@ -173,7 +173,7 @@ static UINT ControlEvent_AddLocal( MSIPACKAGE *package, LPCWSTR argument, msi_di if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll )) { if (feature->ActionRequest != INSTALLSTATE_LOCAL) - msi_set_property( package->db, szPreselected, szOne ); + msi_set_property( package->db, szPreselected, szOne, -1 ); MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_LOCAL ); } } @@ -189,7 +189,7 @@ static UINT ControlEvent_Remove( MSIPACKAGE *package, LPCWSTR argument, msi_dial if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll )) { if (feature->ActionRequest != INSTALLSTATE_ABSENT) - msi_set_property( package->db, szPreselected, szOne ); + msi_set_property( package->db, szPreselected, szOne, -1 ); MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_ABSENT ); } } @@ -205,7 +205,7 @@ static UINT ControlEvent_AddSource( MSIPACKAGE *package, LPCWSTR argument, msi_d if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll )) { if (feature->ActionRequest != INSTALLSTATE_SOURCE) - msi_set_property( package->db, szPreselected, szOne ); + msi_set_property( package->db, szPreselected, szOne, -1 ); MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_SOURCE ); } } @@ -377,13 +377,13 @@ static UINT ControlEvent_DirectoryListUp(MSIPACKAGE *package, LPCWSTR argument, static UINT ControlEvent_ReinstallMode(MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog) { - return msi_set_property( package->db, szReinstallMode, argument ); + return msi_set_property( package->db, szReinstallMode, argument, -1 ); } static UINT ControlEvent_Reinstall( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog ) { - return msi_set_property( package->db, szReinstall, argument ); + return msi_set_property( package->db, szReinstall, argument, -1 ); } static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument, diff --git a/dll/win32/msi/files.c b/dll/win32/msi/files.c index 11913efd618..7202fb637cd 100644 --- a/dll/win32/msi/files.c +++ b/dll/win32/msi/files.c @@ -69,7 +69,6 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil VS_FIXEDFILEINFO *file_version; WCHAR *font_version; msi_file_state state; - DWORD file_size; comp->Action = msi_get_component_action( package, comp ); if (comp->Action != INSTALLSTATE_LOCAL || (comp->assembly && comp->assembly->installed)) @@ -118,7 +117,7 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil return state; } } - if ((file_size = msi_get_disk_file_size( file->TargetPath )) != file->FileSize) + if (msi_get_disk_file_size( file->TargetPath ) != file->FileSize) { return msifs_overwrite; } @@ -336,7 +335,8 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) if (rc != ERROR_SUCCESS) { ERR("Unable to load media info for %s (%u)\n", debugstr_w(file->File), rc); - return ERROR_FUNCTION_FAILED; + rc = ERROR_FUNCTION_FAILED; + goto done; } if (!file->Component->Enabled) continue; @@ -513,7 +513,8 @@ UINT ACTION_PatchFiles( MSIPACKAGE *package ) if (rc != ERROR_SUCCESS) { ERR("Unable to load media info for %s (%u)\n", debugstr_w(file->File), rc); - return ERROR_FUNCTION_FAILED; + rc = ERROR_FUNCTION_FAILED; + goto done; } comp->Action = msi_get_component_action( package, comp ); if (!comp->Enabled || comp->Action != INSTALLSTATE_LOCAL) continue; @@ -779,7 +780,7 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) LPWSTR sourcedir, destname = NULL, destdir = NULL, source = NULL, dest = NULL; int options; DWORD size; - BOOL ret, wildcards; + BOOL wildcards; component = MSI_RecordGetString(rec, 2); comp = msi_get_loaded_component(package, component); @@ -861,7 +862,7 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) if (GetFileAttributesW(destdir) == INVALID_FILE_ATTRIBUTES) { - if (!(ret = msi_create_full_path(destdir))) + if (!msi_create_full_path(destdir)) { WARN("failed to create directory %u\n", GetLastError()); goto done; diff --git a/dll/win32/msi/format.c b/dll/win32/msi/format.c index 8188f132497..756c4d1bd4b 100644 --- a/dll/win32/msi/format.c +++ b/dll/win32/msi/format.c @@ -140,130 +140,146 @@ static LPCWSTR get_formstr_data(FORMAT *format, FORMSTR *str) return &format->deformatted[str->n]; } -static LPWSTR dup_formstr(FORMAT *format, FORMSTR *str) +static WCHAR *dup_formstr( FORMAT *format, FORMSTR *str, int *ret_len ) { - LPWSTR val; - LPCWSTR data; - - if (str->len == 0) - return NULL; - - val = msi_alloc((str->len + 1) * sizeof(WCHAR)); - data = get_formstr_data(format, str); - lstrcpynW(val, data, str->len + 1); + WCHAR *val; + if (!str->len) return NULL; + if ((val = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) + { + memcpy( val, get_formstr_data(format, str), str->len * sizeof(WCHAR) ); + val[str->len] = 0; + *ret_len = str->len; + } return val; } -static LPWSTR deformat_index(FORMAT *format, FORMSTR *str) +static WCHAR *deformat_index( FORMAT *format, FORMSTR *str, int *ret_len ) { - LPWSTR val, ret; + WCHAR *val, *ret; + DWORD len; + int field; - val = msi_alloc((str->len + 1) * sizeof(WCHAR)); + if (!(val = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL; lstrcpynW(val, get_formstr_data(format, str), str->len + 1); + field = atoiW( val ); + msi_free( val ); - ret = msi_dup_record_field(format->record, atoiW(val)); + if (MSI_RecordIsNull( format->record, field ) || + MSI_RecordGetStringW( format->record, field, NULL, &len )) return NULL; - msi_free(val); + len++; + if (!(ret = msi_alloc( len * sizeof(WCHAR) ))) return NULL; + ret[0] = 0; + if (MSI_RecordGetStringW( format->record, field, ret, &len )) + { + msi_free( ret ); + return NULL; + } + *ret_len = len; return ret; } -static LPWSTR deformat_property(FORMAT *format, FORMSTR *str) +static WCHAR *deformat_property( FORMAT *format, FORMSTR *str, int *ret_len ) { - LPWSTR val, ret; + WCHAR *prop, *ret; + DWORD len = 0; + UINT r; - val = msi_alloc((str->len + 1) * sizeof(WCHAR)); - lstrcpynW(val, get_formstr_data(format, str), str->len + 1); + if (!(prop = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL; + lstrcpynW( prop, get_formstr_data(format, str), str->len + 1 ); - ret = msi_dup_property(format->package->db, val); - - msi_free(val); + r = msi_get_property( format->package->db, prop, NULL, &len ); + if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA) + { + msi_free( prop ); + return NULL; + } + len++; + if ((ret = msi_alloc( len * sizeof(WCHAR) ))) + msi_get_property( format->package->db, prop, ret, &len ); + msi_free( prop ); + *ret_len = len; return ret; } -static LPWSTR deformat_component(FORMAT *format, FORMSTR *str) +static WCHAR *deformat_component( FORMAT *format, FORMSTR *str, int *ret_len ) { - LPWSTR key, ret = NULL; + WCHAR *key, *ret; MSICOMPONENT *comp; - key = msi_alloc((str->len + 1) * sizeof(WCHAR)); + if (!(key = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL; lstrcpynW(key, get_formstr_data(format, str), str->len + 1); - comp = msi_get_loaded_component(format->package, key); - if (!comp) - goto done; - + if (!(comp = msi_get_loaded_component( format->package, key ))) + { + msi_free( key ); + return NULL; + } if (comp->Action == INSTALLSTATE_SOURCE) ret = msi_resolve_source_folder( format->package, comp->Directory, NULL ); else ret = strdupW( msi_get_target_folder( format->package, comp->Directory ) ); -done: - msi_free(key); + if (ret) *ret_len = strlenW( ret ); + else *ret_len = 0; + msi_free( key ); return ret; } -static LPWSTR deformat_file(FORMAT *format, FORMSTR *str, BOOL shortname) +static WCHAR *deformat_file( FORMAT *format, FORMSTR *str, BOOL shortname, int *ret_len ) { - LPWSTR key, ret = NULL; - MSIFILE *file; - DWORD size; + WCHAR *key, *ret = NULL; + const MSIFILE *file; + DWORD len = 0; - key = msi_alloc((str->len + 1) * sizeof(WCHAR)); + if (!(key = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL; lstrcpynW(key, get_formstr_data(format, str), str->len + 1); - file = msi_get_loaded_file(format->package, key); - if (!file) - goto done; - + if (!(file = msi_get_loaded_file( format->package, key ))) goto done; if (!shortname) { - ret = strdupW(file->TargetPath); + if ((ret = strdupW( file->TargetPath ))) len = strlenW( ret ); goto done; } - - size = GetShortPathNameW(file->TargetPath, NULL, 0); - if (size <= 0) + if ((len = GetShortPathNameW(file->TargetPath, NULL, 0)) <= 0) { - ret = strdupW(file->TargetPath); + if ((ret = strdupW( file->TargetPath ))) len = strlenW( ret ); goto done; } - - size++; - ret = msi_alloc(size * sizeof(WCHAR)); - GetShortPathNameW(file->TargetPath, ret, size); + len++; + if ((ret = msi_alloc( len * sizeof(WCHAR) ))) + len = GetShortPathNameW( file->TargetPath, ret, len ); done: - msi_free(key); + msi_free( key ); + *ret_len = len; return ret; } -static LPWSTR deformat_environment(FORMAT *format, FORMSTR *str) +static WCHAR *deformat_environment( FORMAT *format, FORMSTR *str, int *ret_len ) { - LPWSTR key, ret = NULL; - DWORD sz; + WCHAR *key, *ret = NULL; + DWORD len; - key = msi_alloc((str->len + 1) * sizeof(WCHAR)); + if (!(key = msi_alloc((str->len + 1) * sizeof(WCHAR)))) return NULL; lstrcpynW(key, get_formstr_data(format, str), str->len + 1); - sz = GetEnvironmentVariableW(key, NULL ,0); - if (sz <= 0) - goto done; - - sz++; - ret = msi_alloc(sz * sizeof(WCHAR)); - GetEnvironmentVariableW(key, ret, sz); - -done: - msi_free(key); + if ((len = GetEnvironmentVariableW( key, NULL, 0 ))) + { + len++; + if ((ret = msi_alloc( len * sizeof(WCHAR) ))) + *ret_len = GetEnvironmentVariableW( key, ret, len ); + } + msi_free( key ); return ret; } -static LPWSTR deformat_literal(FORMAT *format, FORMSTR *str, BOOL *propfound, - BOOL *nonprop, int *type) +static WCHAR *deformat_literal( FORMAT *format, FORMSTR *str, BOOL *propfound, + BOOL *nonprop, int *type, int *len ) { LPCWSTR data = get_formstr_data(format, str); - LPWSTR replaced = NULL; + WCHAR *replaced = NULL; char ch = data[0]; if (ch == '\\') @@ -277,17 +293,17 @@ static LPWSTR deformat_literal(FORMAT *format, FORMSTR *str, BOOL *propfound, else { str->len = 1; - replaced = dup_formstr(format, str); + replaced = dup_formstr( format, str, len ); } } else if (ch == '~') { if (str->len != 1) replaced = NULL; - else + else if ((replaced = msi_alloc( sizeof(WCHAR) ))) { - replaced = msi_alloc(sizeof(WCHAR)); - *replaced = '\0'; + *replaced = 0; + *len = 0; } } else if (ch == '%' || ch == '#' || ch == '!' || ch == '$') @@ -298,20 +314,20 @@ static LPWSTR deformat_literal(FORMAT *format, FORMSTR *str, BOOL *propfound, switch (ch) { case '%': - replaced = deformat_environment(format, str); break; + replaced = deformat_environment( format, str, len ); break; case '#': - replaced = deformat_file(format, str, FALSE); break; + replaced = deformat_file( format, str, FALSE, len ); break; case '!': - replaced = deformat_file(format, str, TRUE); break; + replaced = deformat_file( format, str, TRUE, len ); break; case '$': - replaced = deformat_component(format, str); break; + replaced = deformat_component( format, str, len ); break; } *type = FORMAT_LITERAL; } else { - replaced = deformat_property(format, str); + replaced = deformat_property( format, str, len ); *type = FORMAT_LITERAL; if (replaced) @@ -489,8 +505,8 @@ static int format_lex(FORMAT *format, FORMSTR **out) return type; } -static FORMSTR *format_replace(FORMAT *format, BOOL propfound, BOOL nonprop, - int oldsize, int type, LPWSTR replace) +static FORMSTR *format_replace( FORMAT *format, BOOL propfound, BOOL nonprop, + int oldsize, int type, WCHAR *replace, int len ) { FORMSTR *ret; LPWSTR str, ptr; @@ -499,10 +515,10 @@ static FORMSTR *format_replace(FORMAT *format, BOOL propfound, BOOL nonprop, if (replace) { - if (!*replace) + if (!len) size = 1; else - size = lstrlenW(replace); + size = len; } size -= oldsize; @@ -526,15 +542,12 @@ static FORMSTR *format_replace(FORMAT *format, BOOL propfound, BOOL nonprop, if (replace) { - if (!*replace) - { - str[n] = '\0'; - n++; - } + if (!len) str[n++] = 0; else { - lstrcpyW(&str[n], replace); - n += lstrlenW(replace); + memcpy( str + n, replace, len * sizeof(WCHAR) ); + n += len; + str[n] = 0; } } @@ -546,7 +559,7 @@ static FORMSTR *format_replace(FORMAT *format, BOOL propfound, BOOL nonprop, format->len = size - 1; /* don't reformat the NULL */ - if (replace && !*replace) + if (replace && !len) format->n++; if (!replace) @@ -556,7 +569,7 @@ static FORMSTR *format_replace(FORMAT *format, BOOL propfound, BOOL nonprop, if (!ret) return NULL; - ret->len = lstrlenW(replace); + ret->len = len; ret->type = type; ret->n = format->n; ret->propfound = propfound; @@ -565,13 +578,12 @@ static FORMSTR *format_replace(FORMAT *format, BOOL propfound, BOOL nonprop, return ret; } -static LPWSTR replace_stack_group(FORMAT *format, STACK *values, - BOOL *propfound, BOOL *nonprop, - int *oldsize, int *type) +static WCHAR *replace_stack_group( FORMAT *format, STACK *values, + BOOL *propfound, BOOL *nonprop, + int *oldsize, int *type, int *len ) { - LPWSTR replaced = NULL; - FORMSTR *content; - FORMSTR *node; + WCHAR *replaced; + FORMSTR *content, *node; int n; *nonprop = FALSE; @@ -626,7 +638,7 @@ static LPWSTR replace_stack_group(FORMAT *format, STACK *values, *nonprop = TRUE; } - replaced = dup_formstr(format, content); + replaced = dup_formstr( format, content, len ); *type = content->type; msi_free(content); @@ -636,13 +648,12 @@ static LPWSTR replace_stack_group(FORMAT *format, STACK *values, return replaced; } -static LPWSTR replace_stack_prop(FORMAT *format, STACK *values, - BOOL *propfound, BOOL *nonprop, - int *oldsize, int *type) +static WCHAR *replace_stack_prop( FORMAT *format, STACK *values, + BOOL *propfound, BOOL *nonprop, + int *oldsize, int *type, int *len ) { - LPWSTR replaced = NULL; - FORMSTR *content; - FORMSTR *node; + WCHAR *replaced; + FORMSTR *content, *node; int n; *propfound = FALSE; @@ -672,7 +683,7 @@ static LPWSTR replace_stack_prop(FORMAT *format, STACK *values, if (*type == FORMAT_NUMBER) { - replaced = deformat_index(format, content); + replaced = deformat_index( format, content, len ); if (replaced) *propfound = TRUE; else @@ -684,48 +695,42 @@ static LPWSTR replace_stack_prop(FORMAT *format, STACK *values, } else if (format->package) { - replaced = deformat_literal(format, content, propfound, nonprop, type); + replaced = deformat_literal( format, content, propfound, nonprop, type, len ); } else { *nonprop = TRUE; content->n--; content->len += 2; - replaced = dup_formstr(format, content); + replaced = dup_formstr( format, content, len ); } - msi_free(content); return replaced; } static UINT replace_stack(FORMAT *format, STACK *stack, STACK *values) { - LPWSTR replaced = NULL; - FORMSTR *beg; - FORMSTR *top; - FORMSTR *node; - BOOL propfound = FALSE; - BOOL nonprop = FALSE; - BOOL group = FALSE; - int oldsize = 0; - int type, n; + WCHAR *replaced = NULL; + FORMSTR *beg, *top, *node; + BOOL propfound = FALSE, nonprop = FALSE, group = FALSE; + int type, n, len = 0, oldsize = 0; node = stack_peek(values); type = node->type; n = node->n; if (type == FORMAT_LBRACK) - replaced = replace_stack_prop(format, values, &propfound, - &nonprop, &oldsize, &type); + replaced = replace_stack_prop( format, values, &propfound, + &nonprop, &oldsize, &type, &len ); else if (type == FORMAT_LBRACE) { - replaced = replace_stack_group(format, values, &propfound, - &nonprop, &oldsize, &type); + replaced = replace_stack_group( format, values, &propfound, + &nonprop, &oldsize, &type, &len ); group = TRUE; } format->n = n; - beg = format_replace(format, propfound, nonprop, oldsize, type, replaced); + beg = format_replace( format, propfound, nonprop, oldsize, type, replaced, len ); if (!beg) return ERROR_SUCCESS; @@ -865,20 +870,18 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, UINT MSI_FormatRecordW( MSIPACKAGE* package, MSIRECORD* record, LPWSTR buffer, LPDWORD size ) { - LPWSTR deformated; - LPWSTR rec; - DWORD len; + WCHAR *format, *deformated; UINT rc = ERROR_INVALID_PARAMETER; + DWORD len; TRACE("%p %p %p %p\n", package, record, buffer, size); - rec = msi_dup_record_field(record,0); - if (!rec) - rec = build_default_format(record); + if (!(format = msi_dup_record_field( record, 0 ))) + format = build_default_format( record ); - TRACE("(%s)\n",debugstr_w(rec)); + TRACE("%s\n", debugstr_w(format)); - deformat_string_internal(package, rec, &deformated, &len, record, NULL); + deformat_string_internal( package, format, &deformated, &len, record, NULL ); if (buffer) { if (*size>len) @@ -897,13 +900,11 @@ UINT MSI_FormatRecordW( MSIPACKAGE* package, MSIRECORD* record, LPWSTR buffer, rc = ERROR_MORE_DATA; } } - else - rc = ERROR_SUCCESS; + else rc = ERROR_SUCCESS; *size = len; - - msi_free(rec); - msi_free(deformated); + msi_free( format ); + msi_free( deformated ); return rc; } @@ -934,7 +935,7 @@ UINT WINAPI MsiFormatRecordW( MSIHANDLE hInstall, MSIHANDLE hRecord, wstr.unicode = TRUE; wstr.str.w = szResult; - r = msi_strcpy_to_awstring( value, &wstr, sz ); + r = msi_strcpy_to_awstring( value, SysStringLen(value), &wstr, sz ); done: IWineMsiRemotePackage_Release( remote_package ); @@ -1022,24 +1023,23 @@ done: } /* wrapper to resist a need for a full rewrite right now */ -DWORD deformat_string( MSIPACKAGE *package, const WCHAR *ptr, WCHAR **data ) +DWORD deformat_string( MSIPACKAGE *package, const WCHAR *fmt, WCHAR **data ) { - if (ptr) - { - DWORD size = 0; - MSIRECORD *rec = MSI_CreateRecord( 1 ); + DWORD len; + MSIRECORD *rec; - MSI_RecordSetStringW( rec, 0, ptr ); - MSI_FormatRecordW( package, rec, NULL, &size ); - - size++; - *data = msi_alloc( size * sizeof(WCHAR) ); - if (size > 1) MSI_FormatRecordW( package, rec, *data, &size ); - else *data[0] = 0; - - msiobj_release( &rec->hdr ); - return size * sizeof(WCHAR); - } *data = NULL; - return 0; + if (!fmt) return 0; + if (!(rec = MSI_CreateRecord( 1 ))) return 0; + + MSI_RecordSetStringW( rec, 0, fmt ); + MSI_FormatRecordW( package, rec, NULL, &len ); + if (!(*data = msi_alloc( ++len * sizeof(WCHAR) ))) + { + msiobj_release( &rec->hdr ); + return 0; + } + MSI_FormatRecordW( package, rec, *data, &len ); + msiobj_release( &rec->hdr ); + return len; } diff --git a/dll/win32/msi/install.c b/dll/win32/msi/install.c index a6c832a94eb..5810a1ebfdb 100644 --- a/dll/win32/msi/install.c +++ b/dll/win32/msi/install.c @@ -178,32 +178,28 @@ UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode return ret; } -UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz ) +UINT msi_strcpy_to_awstring( const WCHAR *str, int len, awstring *awbuf, DWORD *sz ) { - UINT len, r = ERROR_SUCCESS; + UINT r = ERROR_SUCCESS; - if (awbuf->str.w && !sz ) + if (awbuf->str.w && !sz) return ERROR_INVALID_PARAMETER; - if (!sz) - return r; + return ERROR_SUCCESS; + + if (len < 0) len = strlenW( str ); - if (awbuf->unicode) - { - len = lstrlenW( str ); - if (awbuf->str.w) - lstrcpynW( awbuf->str.w, str, *sz ); - } + if (awbuf->unicode && awbuf->str.w) + memcpy( awbuf->str.w, str, min(len + 1, *sz) * sizeof(WCHAR) ); else { - len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL ); - if (len) - len--; - WideCharToMultiByte( CP_ACP, 0, str, -1, awbuf->str.a, *sz, NULL, NULL ); - if ( awbuf->str.a && *sz && (len >= *sz) ) + int lenA = WideCharToMultiByte( CP_ACP, 0, str, len + 1, NULL, 0, NULL, NULL ); + if (lenA) lenA--; + WideCharToMultiByte( CP_ACP, 0, str, len + 1, awbuf->str.a, *sz, NULL, NULL ); + if (awbuf->str.a && *sz && lenA >= *sz) awbuf->str.a[*sz - 1] = 0; + len = lenA; } - if (awbuf->str.w && len >= *sz) r = ERROR_MORE_DATA; *sz = len; @@ -277,7 +273,7 @@ static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder, if (FAILED(hr)) goto done; - r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf ); + r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf ); done: IWineMsiRemotePackage_Release( remote_package ); @@ -301,8 +297,7 @@ done: if (!path) return ERROR_DIRECTORY; - r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf ); - return r; + return msi_strcpy_to_awstring( path, -1, szPathBuf, pcchPathBuf ); } /*********************************************************************** @@ -447,7 +442,7 @@ static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder, if (FAILED(hr)) goto done; - r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf ); + r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf ); done: IWineMsiRemotePackage_Release( remote_package ); @@ -478,7 +473,7 @@ done: if (!path) return ERROR_DIRECTORY; - r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf ); + r = msi_strcpy_to_awstring( path, -1, szPathBuf, pcchPathBuf ); msi_free( path ); return r; } @@ -558,7 +553,7 @@ static void set_target_path( MSIPACKAGE *package, MSIFOLDER *folder, const WCHAR { msi_free( folder->ResolvedTarget ); folder->ResolvedTarget = target_path; - msi_set_property( package->db, folder->Directory, folder->ResolvedTarget ); + msi_set_property( package->db, folder->Directory, folder->ResolvedTarget, -1 ); LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry ) { @@ -1650,6 +1645,7 @@ UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ) { static const WCHAR fmt[] = { '%','d',0 }; WCHAR level[6]; + int len; UINT r; TRACE("%p %i\n", package, iInstallLevel); @@ -1660,8 +1656,8 @@ UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ) if (iInstallLevel < 1) return MSI_SetFeatureStates( package ); - sprintfW( level, fmt, iInstallLevel ); - r = msi_set_property( package->db, szInstallLevel, level ); + len = sprintfW( level, fmt, iInstallLevel ); + r = msi_set_property( package->db, szInstallLevel, level, len ); if ( r == ERROR_SUCCESS ) r = MSI_SetFeatureStates( package ); diff --git a/dll/win32/msi/msi.c b/dll/win32/msi/msi.c index 68e9f8154e7..92ef52cbc15 100644 --- a/dll/win32/msi/msi.c +++ b/dll/win32/msi/msi.c @@ -1101,6 +1101,11 @@ static LPWSTR msi_reg_get_value(HKEY hkey, LPCWSTR name, DWORD *type) static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, awstring *szValue, LPDWORD pcchValueBuf) { + static WCHAR empty[] = {0}; + static const WCHAR sourcelist[] = {'S','o','u','r','c','e','L','i','s','t',0}; + static const WCHAR display_name[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; + static const WCHAR display_version[] = {'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0}; + static const WCHAR assignment[] = {'A','s','s','i','g','n','m','e','n','t',0}; MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED; UINT r = ERROR_UNKNOWN_PROPERTY; HKEY prodkey, userdata, source; @@ -1111,16 +1116,6 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, LONG res; DWORD type = REG_NONE; - static WCHAR empty[] = {0}; - static const WCHAR sourcelist[] = { - 'S','o','u','r','c','e','L','i','s','t',0}; - static const WCHAR display_name[] = { - 'D','i','s','p','l','a','y','N','a','m','e',0}; - static const WCHAR display_version[] = { - 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0}; - static const WCHAR assignment[] = { - 'A','s','s','i','g','n','m','e','n','t',0}; - TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute), szValue, pcchValueBuf); @@ -1244,6 +1239,8 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, if (pcchValueBuf) { + int len = strlenW( val ); + /* If szBuffer (szValue->str) is NULL, there's no need to copy the value * out. Also, *pcchValueBuf may be uninitialized in this case, so we * can't rely on its value. @@ -1251,16 +1248,14 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, if (szValue->str.a || szValue->str.w) { DWORD size = *pcchValueBuf; - if (strlenW(val) < size) - r = msi_strcpy_to_awstring(val, szValue, &size); + if (len < size) + r = msi_strcpy_to_awstring( val, len, szValue, &size ); else - { r = ERROR_MORE_DATA; - } } if (!badconfig) - *pcchValueBuf = lstrlenW(val); + *pcchValueBuf = len; } if (badconfig) @@ -2220,7 +2215,10 @@ UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode, if (!(val = msi_alloc( sz ))) return ERROR_OUTOFMEMORY; if ((r = msi_comp_find_prodcode(squished_pc, dwContext, szComponent, val, &sz))) + { + msi_free(val); return r; + } if (lstrlenW(val) > 2 && val[0] >= '0' && val[0] <= '9' && val[1] >= '0' && val[1] <= '9' && val[2] != ':') @@ -2867,7 +2865,7 @@ static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent, if (state == INSTALLSTATE_LOCAL && !*path) state = INSTALLSTATE_NOTUSED; - msi_strcpy_to_awstring(path, lpPathBuf, pcchBuf); + msi_strcpy_to_awstring(path, -1, lpPathBuf, pcchBuf); msi_free(path); return state; } @@ -3521,7 +3519,7 @@ static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct, goto done; } - r = msi_strcpy_to_awstring(user, lpUserNameBuf, pcchUserNameBuf); + r = msi_strcpy_to_awstring(user, -1, lpUserNameBuf, pcchUserNameBuf); if (r == ERROR_MORE_DATA) { state = USERINFOSTATE_MOREDATA; @@ -3534,7 +3532,7 @@ static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct, orgptr = org; if (!orgptr) orgptr = szEmpty; - r = msi_strcpy_to_awstring(orgptr, lpOrgNameBuf, pcchOrgNameBuf); + r = msi_strcpy_to_awstring(orgptr, -1, lpOrgNameBuf, pcchOrgNameBuf); if (r == ERROR_MORE_DATA) { state = USERINFOSTATE_MOREDATA; @@ -3550,7 +3548,7 @@ static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct, goto done; } - r = msi_strcpy_to_awstring(serial, lpSerialBuf, pcchSerialBuf); + r = msi_strcpy_to_awstring(serial, -1, lpSerialBuf, pcchSerialBuf); if (r == ERROR_MORE_DATA) state = USERINFOSTATE_MOREDATA; } diff --git a/dll/win32/msi/msi_main.c b/dll/win32/msi/msi_main.c index de0534af131..46f9ed8db11 100644 --- a/dll/win32/msi/msi_main.c +++ b/dll/win32/msi/msi_main.c @@ -79,6 +79,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) msi_dialog_unregister_class(); msi_free_handle_table(); msi_free( gszLogFile ); + release_typelib(); break; } return TRUE; diff --git a/dll/win32/msi/msipriv.h b/dll/win32/msi/msipriv.h index a0657f4ce90..4110ec6166a 100644 --- a/dll/win32/msi/msipriv.h +++ b/dll/win32/msi/msipriv.h @@ -118,6 +118,7 @@ typedef struct tagMSIFIELD LPWSTR szwVal; IStream *stream; } u; + int len; } MSIFIELD; typedef struct tagMSIRECORD @@ -481,6 +482,7 @@ typedef struct tagMSICOMPONENT LPWSTR FullKeypath; LPWSTR AdvertiseString; MSIASSEMBLY *assembly; + int num_clients; unsigned int anyAbsent:1; unsigned int hasAdvertiseFeature:1; @@ -722,7 +724,7 @@ typedef struct { } str; } awcstring; -UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz ) DECLSPEC_HIDDEN; +UINT msi_strcpy_to_awstring(const WCHAR *, int, awstring *, DWORD *) DECLSPEC_HIDDEN; /* msi server interface */ extern HRESULT create_msi_custom_remote( IUnknown *pOuter, LPVOID *ppObj ) DECLSPEC_HIDDEN; @@ -753,14 +755,15 @@ enum StringPersistence }; extern BOOL msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcount, enum StringPersistence persistence ) DECLSPEC_HIDDEN; -extern UINT msi_string2idW( const string_table *st, LPCWSTR buffer, UINT *id ) DECLSPEC_HIDDEN; +extern UINT msi_string2id( const string_table *st, const WCHAR *data, int len, UINT *id ) DECLSPEC_HIDDEN; extern VOID msi_destroy_stringtable( string_table *st ) DECLSPEC_HIDDEN; -extern const WCHAR *msi_string_lookup_id( const string_table *st, UINT id ) DECLSPEC_HIDDEN; +extern const WCHAR *msi_string_lookup( const string_table *st, UINT id, int *len ) DECLSPEC_HIDDEN; extern HRESULT msi_init_string_table( IStorage *stg ) DECLSPEC_HIDDEN; extern string_table *msi_load_string_table( IStorage *stg, UINT *bytes_per_strref ) DECLSPEC_HIDDEN; extern UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *bytes_per_strref ) DECLSPEC_HIDDEN; extern UINT msi_get_string_table_codepage( const string_table *st ) DECLSPEC_HIDDEN; extern UINT msi_set_string_table_codepage( string_table *st, UINT codepage ) DECLSPEC_HIDDEN; +extern WCHAR *msi_strdupW( const WCHAR *value, int len ) DECLSPEC_HIDDEN; extern BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name ) DECLSPEC_HIDDEN; extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table ) DECLSPEC_HIDDEN; @@ -820,6 +823,8 @@ extern UINT MSI_RecordCopyField( MSIRECORD *, UINT, MSIRECORD *, UINT ) DECLSPEC extern MSIRECORD *MSI_CloneRecord( MSIRECORD * ) DECLSPEC_HIDDEN; extern BOOL MSI_RecordsAreEqual( MSIRECORD *, MSIRECORD * ) DECLSPEC_HIDDEN; extern BOOL MSI_RecordsAreFieldsEqual(MSIRECORD *a, MSIRECORD *b, UINT field) DECLSPEC_HIDDEN; +extern UINT msi_record_set_string(MSIRECORD *, UINT, const WCHAR *, int) DECLSPEC_HIDDEN; +extern const WCHAR *msi_record_get_string(const MSIRECORD *, UINT, int *) DECLSPEC_HIDDEN; /* stream internals */ extern void enum_stream_names( IStorage *stg ) DECLSPEC_HIDDEN; @@ -999,7 +1004,7 @@ extern UINT ACTION_MsiUnpublishAssemblies(MSIPACKAGE *package) DECLSPEC_HIDDEN; extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data ) DECLSPEC_HIDDEN; extern WCHAR *msi_dup_record_field(MSIRECORD *row, INT index) DECLSPEC_HIDDEN; extern LPWSTR msi_dup_property( MSIDATABASE *db, LPCWSTR prop ) DECLSPEC_HIDDEN; -extern UINT msi_set_property( MSIDATABASE *, LPCWSTR, LPCWSTR ) DECLSPEC_HIDDEN; +extern UINT msi_set_property( MSIDATABASE *, const WCHAR *, const WCHAR *, int ) DECLSPEC_HIDDEN; extern UINT msi_get_property( MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD ) DECLSPEC_HIDDEN; extern int msi_get_property_int( MSIDATABASE *package, LPCWSTR prop, int def ) DECLSPEC_HIDDEN; extern WCHAR *msi_resolve_source_folder(MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder) DECLSPEC_HIDDEN; @@ -1067,9 +1072,21 @@ extern VOID ControlEvent_SubscribeToEvent(MSIPACKAGE *package, msi_dialog *dialo LPCWSTR event, LPCWSTR control, LPCWSTR attribute) DECLSPEC_HIDDEN; /* OLE automation */ +typedef enum tid_t { + Database_tid, + Installer_tid, + Record_tid, + Session_tid, + StringList_tid, + SummaryInfo_tid, + View_tid, + LAST_tid +} tid_t; + extern HRESULT create_msiserver(IUnknown *pOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; extern HRESULT create_session(MSIHANDLE msiHandle, IDispatch *pInstaller, IDispatch **pDispatch) DECLSPEC_HIDDEN; -extern HRESULT load_type_info(IDispatch *iface, ITypeInfo **pptinfo, REFIID clsid, LCID lcid) DECLSPEC_HIDDEN; +extern HRESULT get_typeinfo(tid_t tid, ITypeInfo **ti) DECLSPEC_HIDDEN; +extern void release_typelib(void) DECLSPEC_HIDDEN; /* Scripting */ extern DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action) DECLSPEC_HIDDEN; @@ -1177,6 +1194,7 @@ static const WCHAR szRollbackDisabled[] = {'R','o','l','l','b','a','c','k','D',' static const WCHAR szName[] = {'N','a','m','e',0}; static const WCHAR szData[] = {'D','a','t','a',0}; static const WCHAR szLangResource[] = {'\\','V','a','r','F','i','l','e','I','n','f','o','\\','T','r','a','n','s','l','a','t','i','o','n',0}; +static const WCHAR szInstallLocation[] = {'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',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 433b3c772f6..451fdddbbb0 100644 --- a/dll/win32/msi/msiquery.c +++ b/dll/win32/msi/msiquery.c @@ -345,10 +345,9 @@ UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec) if (type & MSITYPE_STRING) { - LPCWSTR sval; - - sval = msi_string_lookup_id(db->strings, ival); - MSI_RecordSetStringW(*rec, i, sval); + int len; + const WCHAR *sval = msi_string_lookup( db->strings, ival, &len ); + msi_record_set_string( *rec, i, sval, len ); } else { diff --git a/dll/win32/msi/package.c b/dll/win32/msi/package.c index a050b2eb54b..3055175773b 100644 --- a/dll/win32/msi/package.c +++ b/dll/win32/msi/package.c @@ -483,7 +483,7 @@ static UINT set_installed_prop( MSIPACKAGE *package ) if (r == ERROR_SUCCESS) { RegCloseKey( hkey ); - msi_set_property( package->db, szInstalled, szOne ); + msi_set_property( package->db, szInstalled, szOne, -1 ); } return r; } @@ -525,7 +525,7 @@ static UINT set_user_sid_prop( MSIPACKAGE *package ) if (!ConvertSidToStringSidW( psid, &sid_str )) goto done; - r = msi_set_property( package->db, szUserSID, sid_str ); + r = msi_set_property( package->db, szUserSID, sid_str, -1 ); done: LocalFree( sid_str ); @@ -638,10 +638,12 @@ static void set_msi_assembly_prop(MSIPACKAGE *package) return; size = GetFileVersionInfoSizeW(fusion, &handle); - if (!size) return; + if (!size) + goto done; version = msi_alloc(size); - if (!version) return; + if (!version) + goto done; if (!GetFileVersionInfoW(fusion, handle, size, version)) goto done; @@ -657,7 +659,7 @@ static void set_msi_assembly_prop(MSIPACKAGE *package) if (!val_len || !verstr) goto done; - msi_set_property(package->db, netasm, verstr); + msi_set_property( package->db, netasm, verstr, -1 ); done: msi_free(fusion); @@ -757,182 +759,182 @@ static VOID set_installer_properties(MSIPACKAGE *package) SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szCommonAppDataFolder, pth); + msi_set_property( package->db, szCommonAppDataFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_FAVORITES, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szFavoritesFolder, pth); + msi_set_property( package->db, szFavoritesFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szFontsFolder, pth); + msi_set_property( package->db, szFontsFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_SENDTO, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szSendToFolder, pth); + msi_set_property( package->db, szSendToFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szStartMenuFolder, pth); + msi_set_property( package->db, szStartMenuFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_STARTUP, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szStartupFolder, pth); + msi_set_property( package->db, szStartupFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_TEMPLATES, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szTemplateFolder, pth); + msi_set_property( package->db, szTemplateFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szDesktopFolder, pth); + msi_set_property( package->db, szDesktopFolder, pth, -1 ); /* FIXME: set to AllUsers profile path if ALLUSERS is set */ SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szProgramMenuFolder, pth); + msi_set_property( package->db, szProgramMenuFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_ADMINTOOLS, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szAdminToolsFolder, pth); + msi_set_property( package->db, szAdminToolsFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szAppDataFolder, pth); + msi_set_property( package->db, szAppDataFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szSystemFolder, pth); - msi_set_property(package->db, szSystem16Folder, pth); + msi_set_property( package->db, szSystemFolder, pth, -1 ); + msi_set_property( package->db, szSystem16Folder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szLocalAppDataFolder, pth); + msi_set_property( package->db, szLocalAppDataFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_MYPICTURES, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szMyPicturesFolder, pth); + msi_set_property( package->db, szMyPicturesFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szPersonalFolder, pth); + msi_set_property( package->db, szPersonalFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szWindowsFolder, pth); + msi_set_property( package->db, szWindowsFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_PRINTHOOD, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szPrintHoodFolder, pth); + msi_set_property( package->db, szPrintHoodFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_NETHOOD, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szNetHoodFolder, pth); + msi_set_property( package->db, szNetHoodFolder, pth, -1 ); SHGetFolderPathW(NULL, CSIDL_RECENT, NULL, 0, pth); strcatW(pth, szBackSlash); - msi_set_property(package->db, szRecentFolder, pth); + msi_set_property( package->db, szRecentFolder, pth, -1 ); /* Physical Memory is specified in MB. Using total amount. */ msex.dwLength = sizeof(msex); GlobalMemoryStatusEx( &msex ); - sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys / 1024 / 1024) ); - msi_set_property(package->db, szPhysicalMemory, bufstr); + len = sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys / 1024 / 1024) ); + msi_set_property( package->db, szPhysicalMemory, bufstr, len ); SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth); ptr = strchrW(pth,'\\'); if (ptr) *(ptr + 1) = 0; - msi_set_property(package->db, szWindowsVolume, pth); + msi_set_property( package->db, szWindowsVolume, pth, -1 ); - GetTempPathW(MAX_PATH,pth); - msi_set_property(package->db, szTempFolder, pth); + len = GetTempPathW(MAX_PATH, pth); + msi_set_property( package->db, szTempFolder, pth, len ); /* in a wine environment the user is always admin and privileged */ - msi_set_property(package->db, szAdminUser, szOne); - msi_set_property(package->db, szPrivileged, szOne); + msi_set_property( package->db, szAdminUser, szOne, -1 ); + msi_set_property( package->db, szPrivileged, szOne, -1 ); /* set the os things */ OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); GetVersionExW((OSVERSIONINFOW *)&OSVersion); verval = OSVersion.dwMinorVersion + OSVersion.dwMajorVersion * 100; - sprintfW(verstr, szFormat, verval); + len = sprintfW( verstr, szFormat, verval ); switch (OSVersion.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: - msi_set_property(package->db, szVersion9x, verstr); + msi_set_property( package->db, szVersion9x, verstr, len ); break; case VER_PLATFORM_WIN32_NT: - msi_set_property(package->db, szVersionNT, verstr); - sprintfW(verstr, szFormat,OSVersion.wProductType); - msi_set_property(package->db, szMsiNTProductType, verstr); + msi_set_property( package->db, szVersionNT, verstr, len ); + len = sprintfW( verstr, szFormat,OSVersion.wProductType ); + msi_set_property( package->db, szMsiNTProductType, verstr, len ); break; } - sprintfW(verstr, szFormat, OSVersion.dwBuildNumber); - msi_set_property(package->db, szWindowsBuild, verstr); - sprintfW(verstr, szFormat, OSVersion.wServicePackMajor); - msi_set_property(package->db, szServicePackLevel, verstr); + len = sprintfW( verstr, szFormat, OSVersion.dwBuildNumber ); + msi_set_property( package->db, szWindowsBuild, verstr, len ); + len = sprintfW( verstr, szFormat, OSVersion.wServicePackMajor ); + msi_set_property( package->db, szServicePackLevel, verstr, len ); - sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION); - msi_set_property( package->db, szVersionMsi, bufstr ); - sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100); - msi_set_property( package->db, szVersionDatabase, bufstr ); + len = sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION ); + msi_set_property( package->db, szVersionMsi, bufstr, len ); + len = sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100 ); + msi_set_property( package->db, szVersionDatabase, bufstr, len ); GetNativeSystemInfo( &sys_info ); - sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel ); - msi_set_property( package->db, szIntel, bufstr ); + len = sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel ); + msi_set_property( package->db, szIntel, bufstr, len ); if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { GetSystemDirectoryW( pth, MAX_PATH ); PathAddBackslashW( pth ); - msi_set_property( package->db, szSystemFolder, pth ); + msi_set_property( package->db, szSystemFolder, pth, -1 ); SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth ); PathAddBackslashW( pth ); - msi_set_property( package->db, szProgramFilesFolder, pth ); + msi_set_property( package->db, szProgramFilesFolder, pth, -1 ); SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth ); PathAddBackslashW( pth ); - msi_set_property( package->db, szCommonFilesFolder, pth ); + msi_set_property( package->db, szCommonFilesFolder, pth, -1 ); } else if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { - msi_set_property( package->db, szMsiAMD64, bufstr ); - msi_set_property( package->db, szMsix64, bufstr ); - msi_set_property( package->db, szVersionNT64, verstr ); + msi_set_property( package->db, szMsiAMD64, bufstr, -1 ); + msi_set_property( package->db, szMsix64, bufstr, -1 ); + msi_set_property( package->db, szVersionNT64, verstr, -1 ); GetSystemDirectoryW( pth, MAX_PATH ); PathAddBackslashW( pth ); - msi_set_property( package->db, szSystem64Folder, pth ); + msi_set_property( package->db, szSystem64Folder, pth, -1 ); GetSystemWow64DirectoryW( pth, MAX_PATH ); PathAddBackslashW( pth ); - msi_set_property( package->db, szSystemFolder, pth ); + msi_set_property( package->db, szSystemFolder, pth, -1 ); SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth ); PathAddBackslashW( pth ); - msi_set_property( package->db, szProgramFiles64Folder, pth ); + msi_set_property( package->db, szProgramFiles64Folder, pth, -1 ); SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, pth ); PathAddBackslashW( pth ); - msi_set_property( package->db, szProgramFilesFolder, pth ); + msi_set_property( package->db, szProgramFilesFolder, pth, -1 ); SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth ); PathAddBackslashW( pth ); - msi_set_property( package->db, szCommonFiles64Folder, pth ); + msi_set_property( package->db, szCommonFiles64Folder, pth, -1 ); SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, pth ); PathAddBackslashW( pth ); - msi_set_property( package->db, szCommonFilesFolder, pth ); + msi_set_property( package->db, szCommonFilesFolder, pth, -1 ); } /* Screen properties. */ dc = GetDC(0); - sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, HORZRES ) ); - msi_set_property( package->db, szScreenX, bufstr ); - sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, VERTRES )); - msi_set_property( package->db, szScreenY, bufstr ); - sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, BITSPIXEL )); - msi_set_property( package->db, szColorBits, bufstr ); + len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, HORZRES) ); + msi_set_property( package->db, szScreenX, bufstr, len ); + len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, VERTRES) ); + msi_set_property( package->db, szScreenY, bufstr, len ); + len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, BITSPIXEL) ); + msi_set_property( package->db, szColorBits, bufstr, len ); ReleaseDC(0, dc); /* USERNAME and COMPANYNAME */ @@ -944,10 +946,10 @@ static VOID set_installer_properties(MSIPACKAGE *package) { if (!username && (username = msi_reg_get_val_str( hkey, szDefName ))) - msi_set_property( package->db, szUSERNAME, username ); + msi_set_property( package->db, szUSERNAME, username, -1 ); if (!companyname && (companyname = msi_reg_get_val_str( hkey, szDefCompany ))) - msi_set_property( package->db, szCOMPANYNAME, companyname ); + msi_set_property( package->db, szCOMPANYNAME, companyname, -1 ); CloseHandle( hkey ); } if ((!username || !companyname) && @@ -955,10 +957,10 @@ static VOID set_installer_properties(MSIPACKAGE *package) { if (!username && (username = msi_reg_get_val_str( hkey, szRegisteredUser ))) - msi_set_property( package->db, szUSERNAME, username ); + msi_set_property( package->db, szUSERNAME, username, -1 ); if (!companyname && (companyname = msi_reg_get_val_str( hkey, szRegisteredOrganization ))) - msi_set_property( package->db, szCOMPANYNAME, companyname ); + msi_set_property( package->db, szCOMPANYNAME, companyname, -1 ); CloseHandle( hkey ); } msi_free( username ); @@ -971,7 +973,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) GetSystemTime( &systemtime ); if (GetDateFormatW( LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemtime, NULL, bufstr, sizeof(bufstr)/sizeof(bufstr[0]) )) - msi_set_property( package->db, szDate, bufstr ); + msi_set_property( package->db, szDate, bufstr, -1 ); else ERR("Couldn't set Date property: GetDateFormat failed with error %d\n", GetLastError()); @@ -979,22 +981,22 @@ static VOID set_installer_properties(MSIPACKAGE *package) TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, &systemtime, NULL, bufstr, sizeof(bufstr)/sizeof(bufstr[0]) )) - msi_set_property( package->db, szTime, bufstr ); + msi_set_property( package->db, szTime, bufstr, -1 ); else ERR("Couldn't set Time property: GetTimeFormat failed with error %d\n", GetLastError()); set_msi_assembly_prop( package ); langid = GetUserDefaultLangID(); - sprintfW(bufstr, szIntFormat, langid); - msi_set_property( package->db, szUserLanguageID, bufstr ); + len = sprintfW( bufstr, szIntFormat, langid ); + msi_set_property( package->db, szUserLanguageID, bufstr, len ); langid = GetSystemDefaultLangID(); - sprintfW(bufstr, szIntFormat, langid); - msi_set_property( package->db, szSystemLangID, bufstr ); + len = sprintfW( bufstr, szIntFormat, langid ); + msi_set_property( package->db, szSystemLangID, bufstr, len ); - sprintfW(bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode)); - msi_set_property( package->db, szProductState, bufstr ); + len = sprintfW( bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode) ); + msi_set_property( package->db, szProductState, bufstr, len ); len = 0; if (!GetUserNameW( NULL, &len ) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) @@ -1003,7 +1005,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) if ((username = msi_alloc( len * sizeof(WCHAR) ))) { if (GetUserNameW( username, &len )) - msi_set_property( package->db, szLogonUser, username ); + msi_set_property( package->db, szLogonUser, username, len - 1 ); msi_free( username ); } } @@ -1014,7 +1016,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) if ((computername = msi_alloc( len * sizeof(WCHAR) ))) { if (GetComputerNameW( computername, &len )) - msi_set_property( package->db, szComputerName, computername ); + msi_set_property( package->db, szComputerName, computername, len - 1 ); msi_free( computername ); } } @@ -1073,7 +1075,7 @@ static UINT msi_load_summary_properties( MSIPACKAGE *package ) goto done; } - msi_set_property( package->db, szPackageCode, package_code ); + msi_set_property( package->db, szPackageCode, package_code, len ); msi_free( package_code ); /* load package attributes */ @@ -1141,9 +1143,9 @@ void msi_adjust_privilege_properties( MSIPACKAGE *package ) if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2) { TRACE("resetting ALLUSERS property from 2 to 1\n"); - msi_set_property( package->db, szAllUsers, szOne ); + msi_set_property( package->db, szAllUsers, szOne, -1 ); } - msi_set_property( package->db, szAdminUser, szOne ); + msi_set_property( package->db, szAdminUser, szOne, -1 ); } MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) @@ -1151,6 +1153,7 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) static const WCHAR fmtW[] = {'%','u',0}; MSIPACKAGE *package; WCHAR uilevel[11]; + int len; UINT r; TRACE("%p\n", db); @@ -1176,8 +1179,8 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) set_installer_properties( package ); package->ui_level = gUILevel; - sprintfW( uilevel, fmtW, gUILevel & INSTALLUILEVEL_MASK ); - msi_set_property(package->db, szUILevel, uilevel); + len = sprintfW( uilevel, fmtW, gUILevel & INSTALLUILEVEL_MASK ); + msi_set_property( package->db, szUILevel, uilevel, len ); r = msi_load_summary_properties( package ); if (r != ERROR_SUCCESS) @@ -1564,13 +1567,17 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) { r = msi_create_empty_local_file( localfile, dotmsi ); if (r != ERROR_SUCCESS) + { + msi_free ( base_url ); return r; + } if (!CopyFileW( file, localfile, FALSE )) { r = GetLastError(); WARN("unable to copy package %s to %s (%u)\n", debugstr_w(file), debugstr_w(localfile), r); DeleteFileW( localfile ); + msi_free ( base_url ); return r; } delete_on_close = TRUE; @@ -1578,7 +1585,10 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) TRACE("opening package %s\n", debugstr_w( localfile )); r = MSI_OpenDatabaseW( localfile, MSIDBOPEN_TRANSACT, &db ); if (r != ERROR_SUCCESS) + { + msi_free ( base_url ); return r; + } } package = MSI_CreatePackage( db, base_url ); msi_free( base_url ); @@ -1608,18 +1618,17 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) msiobj_release( &package->hdr ); return r; } - msi_set_property( package->db, szDatabase, db->path ); + msi_set_property( package->db, szDatabase, db->path, -1 ); if( UrlIsW( szPackage, URLIS_URL ) ) - msi_set_property( package->db, szOriginalDatabase, szPackage ); + msi_set_property( package->db, szOriginalDatabase, szPackage, -1 ); else if( szPackage[0] == '#' ) - msi_set_property( package->db, szOriginalDatabase, db->path ); + msi_set_property( package->db, szOriginalDatabase, db->path, -1 ); else { WCHAR fullpath[MAX_PATH]; - - GetFullPathNameW( szPackage, MAX_PATH, fullpath, NULL ); - msi_set_property( package->db, szOriginalDatabase, fullpath ); + DWORD len = GetFullPathNameW( szPackage, MAX_PATH, fullpath, NULL ); + msi_set_property( package->db, szOriginalDatabase, fullpath, len ); } msi_set_context( package ); @@ -2018,7 +2027,7 @@ void msi_reset_folders( MSIPACKAGE *package, BOOL source ) } } -UINT msi_set_property( MSIDATABASE *db, LPCWSTR szName, LPCWSTR szValue ) +UINT msi_set_property( MSIDATABASE *db, const WCHAR *name, const WCHAR *value, int len ) { static const WCHAR insert_query[] = { 'I','N','S','E','R','T',' ','I','N','T','O',' ', @@ -2039,34 +2048,34 @@ UINT msi_set_property( MSIDATABASE *db, LPCWSTR szName, LPCWSTR szValue ) WCHAR query[1024]; UINT rc; - TRACE("%p %s %s\n", db, debugstr_w(szName), debugstr_w(szValue)); + TRACE("%p %s %s %d\n", db, debugstr_w(name), debugstr_wn(value, len), len); - if (!szName) + if (!name) return ERROR_INVALID_PARAMETER; /* this one is weird... */ - if (!szName[0]) - return szValue ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS; + if (!name[0]) + return value ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS; - rc = msi_get_property(db, szName, 0, &sz); - if (!szValue || !*szValue) + if (value && len < 0) len = strlenW( value ); + + rc = msi_get_property( db, name, 0, &sz ); + if (!value || (!*value && !len)) { - sprintfW(query, delete_query, szName); + sprintfW( query, delete_query, name ); } else if (rc == ERROR_MORE_DATA || rc == ERROR_SUCCESS) { - sprintfW(query, update_query, szName); - + sprintfW( query, update_query, name ); row = MSI_CreateRecord(1); - MSI_RecordSetStringW(row, 1, szValue); + msi_record_set_string( row, 1, value, len ); } else { - strcpyW(query, insert_query); - + strcpyW( query, insert_query ); row = MSI_CreateRecord(2); - MSI_RecordSetStringW(row, 1, szName); - MSI_RecordSetStringW(row, 2, szValue); + msi_record_set_string( row, 1, name, -1 ); + msi_record_set_string( row, 2, value, len ); } rc = MSI_DatabaseOpenViewW(db, query, &view); @@ -2123,7 +2132,7 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue return ERROR_SUCCESS; } - ret = msi_set_property( package->db, szName, szValue ); + ret = msi_set_property( package->db, szName, szValue, -1 ); if (ret == ERROR_SUCCESS && !strcmpW( szName, szSourceDir )) msi_reset_folders( package, TRUE ); @@ -2181,7 +2190,7 @@ UINT msi_get_property( MSIDATABASE *db, LPCWSTR szName, } if (rc == ERROR_SUCCESS) - TRACE("returning %s for property %s\n", debugstr_w(szValueBuf), + TRACE("returning %s for property %s\n", debugstr_wn(szValueBuf, *pchValueBuf), debugstr_w(szName)); else if (rc == ERROR_MORE_DATA) TRACE("need %d sized buffer for %s\n", *pchValueBuf, @@ -2232,6 +2241,7 @@ static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name, MSIRECORD *row = NULL; UINT r = ERROR_FUNCTION_FAILED; LPCWSTR val = NULL; + DWORD len = 0; TRACE("%u %s %p %p\n", handle, debugstr_w(name), szValueBuf->str.w, pchValueBuf ); @@ -2246,7 +2256,6 @@ static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name, IWineMsiRemotePackage *remote_package; LPWSTR value = NULL; BSTR bname; - DWORD len; remote_package = (IWineMsiRemotePackage *)msi_get_remote( handle ); if (!remote_package) @@ -2259,7 +2268,6 @@ static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name, return ERROR_OUTOFMEMORY; } - len = 0; hr = IWineMsiRemotePackage_GetProperty( remote_package, bname, NULL, &len ); if (FAILED(hr)) goto done; @@ -2276,7 +2284,7 @@ static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name, if (FAILED(hr)) goto done; - r = msi_strcpy_to_awstring( value, szValueBuf, pchValueBuf ); + r = msi_strcpy_to_awstring( value, len, szValueBuf, pchValueBuf ); /* Bug required by Adobe installers */ if (!szValueBuf->unicode && !szValueBuf->str.a) @@ -2300,12 +2308,12 @@ done: row = msi_get_property_row( package->db, name ); if (row) - val = MSI_RecordGetString( row, 1 ); + val = msi_record_get_string( row, 1, (int *)&len ); if (!val) val = szEmpty; - r = msi_strcpy_to_awstring( val, szValueBuf, pchValueBuf ); + r = msi_strcpy_to_awstring( val, len, szValueBuf, pchValueBuf ); if (row) msiobj_release( &row->hdr ); diff --git a/dll/win32/msi/patch.c b/dll/win32/msi/patch.c index 4801872b32b..59785a690f2 100644 --- a/dll/win32/msi/patch.c +++ b/dll/win32/msi/patch.c @@ -225,7 +225,7 @@ static UINT patch_set_media_source_prop( MSIPACKAGE *package ) { property = MSI_RecordGetString( rec, 1 ); patch = msi_dup_property( package->db, szPatch ); - msi_set_property( package->db, property, patch ); + msi_set_property( package->db, property, patch, -1 ); msi_free( patch ); msiobj_release( &rec->hdr ); } diff --git a/dll/win32/msi/record.c b/dll/win32/msi/record.c index 1dace787906..dd097ea46e8 100644 --- a/dll/win32/msi/record.c +++ b/dll/win32/msi/record.c @@ -156,6 +156,17 @@ static BOOL string2intW( LPCWSTR str, int *out ) return TRUE; } +WCHAR *msi_strdupW( const WCHAR *value, int len ) +{ + WCHAR *ret; + + if (!value) return NULL; + if (!(ret = msi_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL; + memcpy( ret, value, len * sizeof(WCHAR) ); + ret[len] = 0; + return ret; +} + UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n, MSIRECORD *out_rec, UINT out_n ) { @@ -184,11 +195,12 @@ UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n, out->u.pVal = in->u.pVal; break; case MSIFIELD_WSTR: - str = strdupW( in->u.szwVal ); - if ( !str ) - r = ERROR_OUTOFMEMORY; - else + if ((str = msi_strdupW( in->u.szwVal, in->len ))) + { out->u.szwVal = str; + out->len = in->len; + } + else r = ERROR_OUTOFMEMORY; break; case MSIFIELD_STREAM: IStream_AddRef( in->u.stream ); @@ -202,7 +214,6 @@ UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n, } msiobj_unlock( &in_rec->hdr ); - return r; } @@ -380,7 +391,7 @@ BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, UINT iField ) UINT MSI_RecordGetStringA(MSIRECORD *rec, UINT iField, LPSTR szValue, LPDWORD pcchValue) { - UINT len=0, ret; + UINT len = 0, ret = ERROR_SUCCESS; CHAR buffer[16]; TRACE("%p %d %p %p\n", rec, iField, szValue, pcchValue); @@ -394,7 +405,6 @@ UINT MSI_RecordGetStringA(MSIRECORD *rec, UINT iField, return ERROR_SUCCESS; } - ret = ERROR_SUCCESS; switch( rec->fields[iField].type ) { case MSIFIELD_INT: @@ -404,11 +414,11 @@ UINT MSI_RecordGetStringA(MSIRECORD *rec, UINT iField, lstrcpynA(szValue, buffer, *pcchValue); break; case MSIFIELD_WSTR: - len = WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1, - NULL, 0 , NULL, NULL); + len = WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, + rec->fields[iField].len + 1, NULL, 0 , NULL, NULL ); if (szValue) - WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1, - szValue, *pcchValue, NULL, NULL); + WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, + rec->fields[iField].len + 1, szValue, *pcchValue, NULL, NULL ); if( szValue && *pcchValue && len>*pcchValue ) szValue[*pcchValue-1] = 0; if( len ) @@ -448,23 +458,30 @@ UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, UINT iField, return ret; } +const WCHAR *msi_record_get_string( const MSIRECORD *rec, UINT field, int *len ) +{ + if (field > rec->count) + return NULL; + + if (rec->fields[field].type != MSIFIELD_WSTR) + return NULL; + + if (len) *len = rec->fields[field].len; + + return rec->fields[field].u.szwVal; +} + const WCHAR *MSI_RecordGetString( const MSIRECORD *rec, UINT iField ) { - if( iField > rec->count ) - return NULL; - - if( rec->fields[iField].type != MSIFIELD_WSTR ) - return NULL; - - return rec->fields[iField].u.szwVal; + return msi_record_get_string( rec, iField, NULL ); } UINT MSI_RecordGetStringW(MSIRECORD *rec, UINT iField, LPWSTR szValue, LPDWORD pcchValue) { - UINT len=0, ret; + static const WCHAR szFormat[] = {'%','d',0}; + UINT len = 0, ret = ERROR_SUCCESS; WCHAR buffer[16]; - static const WCHAR szFormat[] = { '%','d',0 }; TRACE("%p %d %p %p\n", rec, iField, szValue, pcchValue); @@ -477,7 +494,6 @@ UINT MSI_RecordGetStringW(MSIRECORD *rec, UINT iField, return ERROR_SUCCESS; } - ret = ERROR_SUCCESS; switch( rec->fields[iField].type ) { case MSIFIELD_INT: @@ -487,9 +503,9 @@ UINT MSI_RecordGetStringW(MSIRECORD *rec, UINT iField, lstrcpynW(szValue, buffer, *pcchValue); break; case MSIFIELD_WSTR: - len = lstrlenW( rec->fields[iField].u.szwVal ); + len = rec->fields[iField].len; if (szValue) - lstrcpynW(szValue, rec->fields[iField].u.szwVal, *pcchValue); + memcpy( szValue, rec->fields[iField].u.szwVal, min(len + 1, *pcchValue) * sizeof(WCHAR) ); break; case MSIFIELD_NULL: if( szValue && *pcchValue > 0 ) @@ -548,7 +564,7 @@ static UINT MSI_RecordDataSize(MSIRECORD *rec, UINT iField) case MSIFIELD_INT: return sizeof (INT); case MSIFIELD_WSTR: - return lstrlenW( rec->fields[iField].u.szwVal ); + return rec->fields[iField].len; case MSIFIELD_NULL: break; case MSIFIELD_STREAM: @@ -574,72 +590,59 @@ UINT WINAPI MsiRecordDataSize(MSIHANDLE handle, UINT iField) return ret; } -static UINT MSI_RecordSetStringA( MSIRECORD *rec, UINT iField, LPCSTR szValue ) -{ - LPWSTR str; - - TRACE("%p %d %s\n", rec, iField, debugstr_a(szValue)); - - if( iField > rec->count ) - return ERROR_INVALID_FIELD; - - MSI_FreeField( &rec->fields[iField] ); - if( szValue && szValue[0] ) - { - str = strdupAtoW( szValue ); - rec->fields[iField].type = MSIFIELD_WSTR; - rec->fields[iField].u.szwVal = str; - } - else - { - rec->fields[iField].type = MSIFIELD_NULL; - rec->fields[iField].u.szwVal = NULL; - } - - return 0; -} - UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, UINT iField, LPCSTR szValue ) { + WCHAR *valueW = NULL; MSIRECORD *rec; UINT ret; TRACE("%d %d %s\n", handle, iField, debugstr_a(szValue)); + if (szValue && !(valueW = strdupAtoW( szValue ))) return ERROR_OUTOFMEMORY; + rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) + { + msi_free( valueW ); return ERROR_INVALID_HANDLE; + } msiobj_lock( &rec->hdr ); - ret = MSI_RecordSetStringA( rec, iField, szValue ); + ret = MSI_RecordSetStringW( rec, iField, valueW ); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); + msi_free( valueW ); return ret; } +UINT msi_record_set_string( MSIRECORD *rec, UINT field, const WCHAR *value, int len ) +{ + if (field > rec->count) + return ERROR_INVALID_FIELD; + + MSI_FreeField( &rec->fields[field] ); + + if (value && len < 0) len = strlenW( value ); + + if (value && len) + { + rec->fields[field].type = MSIFIELD_WSTR; + rec->fields[field].u.szwVal = msi_strdupW( value, len ); + rec->fields[field].len = len; + } + else + { + rec->fields[field].type = MSIFIELD_NULL; + rec->fields[field].u.szwVal = NULL; + rec->fields[field].len = 0; + } + return 0; +} + UINT MSI_RecordSetStringW( MSIRECORD *rec, UINT iField, LPCWSTR szValue ) { - LPWSTR str; - TRACE("%p %d %s\n", rec, iField, debugstr_w(szValue)); - if( iField > rec->count ) - return ERROR_INVALID_FIELD; - - MSI_FreeField( &rec->fields[iField] ); - - if( szValue && szValue[0] ) - { - str = strdupW( szValue ); - rec->fields[iField].type = MSIFIELD_WSTR; - rec->fields[iField].u.szwVal = str; - } - else - { - rec->fields[iField].type = MSIFIELD_NULL; - rec->fields[iField].u.szwVal = NULL; - } - - return 0; + return msi_record_set_string( rec, iField, szValue, -1 ); } UINT WINAPI MsiRecordSetStringW( MSIHANDLE handle, UINT iField, LPCWSTR szValue ) @@ -1011,8 +1014,9 @@ BOOL MSI_RecordsAreFieldsEqual(MSIRECORD *a, MSIRECORD *b, UINT field) break; case MSIFIELD_WSTR: - if (strcmpW(a->fields[field].u.szwVal, b->fields[field].u.szwVal)) - return FALSE; + if (a->fields[field].len != b->fields[field].len) return FALSE; + if (memcmp( a->fields[field].u.szwVal, b->fields[field].u.szwVal, + a->fields[field].len * sizeof(WCHAR) )) return FALSE; break; case MSIFIELD_STREAM: diff --git a/dll/win32/msi/registry.c b/dll/win32/msi/registry.c index 4143a791e84..388c0772808 100644 --- a/dll/win32/msi/registry.c +++ b/dll/win32/msi/registry.c @@ -1557,7 +1557,7 @@ static UINT MSI_EnumComponentQualifiers( LPCWSTR szComponent, DWORD iIndex, } r = ERROR_OUTOFMEMORY; - if ((name_sz+1) >= name_max) + if (name_sz + 1 >= name_max) { name_max *= 2; msi_free( name ); @@ -1586,8 +1586,8 @@ static UINT MSI_EnumComponentQualifiers( LPCWSTR szComponent, DWORD iIndex, TRACE("Providing %s and %s\n", debugstr_w(name), debugstr_w(val+ofs)); - r = msi_strcpy_to_awstring( name, lpQualBuf, pcchQual ); - r2 = msi_strcpy_to_awstring( val+ofs, lpAppBuf, pcchAppBuf ); + r = msi_strcpy_to_awstring( name, -1, lpQualBuf, pcchQual ); + r2 = msi_strcpy_to_awstring( val+ofs, -1, lpAppBuf, pcchAppBuf ); if (r2 != ERROR_SUCCESS) r = r2; @@ -1596,7 +1596,6 @@ end: msi_free(val); msi_free(name); RegCloseKey(key); - return r; } diff --git a/dll/win32/msi/script.c b/dll/win32/msi/script.c index 94577bae058..8d48a9411ae 100644 --- a/dll/win32/msi/script.c +++ b/dll/win32/msi/script.c @@ -36,6 +36,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); +#ifdef _WIN64 + +#define IActiveScriptParse_Release IActiveScriptParse64_Release +#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew +#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText + +#else + +#define IActiveScriptParse_Release IActiveScriptParse32_Release +#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew +#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText + +#endif + static const WCHAR szJScript[] = { 'J','S','c','r','i','p','t',0}; static const WCHAR szVBScript[] = { 'V','B','S','c','r','i','p','t',0}; static const WCHAR szSession[] = {'S','e','s','s','i','o','n',0}; @@ -43,207 +57,54 @@ static const WCHAR szSession[] = {'S','e','s','s','i','o','n',0}; /* * MsiActiveScriptSite - Our IActiveScriptSite implementation. */ - typedef struct { - IActiveScriptSite lpVtbl; - IDispatch *pInstaller; - IDispatch *pSession; + IActiveScriptSite IActiveScriptSite_iface; + IDispatch *installer; + IDispatch *session; LONG ref; } MsiActiveScriptSite; -static const struct IActiveScriptSiteVtbl ASS_Vtbl; - -static HRESULT create_ActiveScriptSite(IUnknown *pUnkOuter, LPVOID *ppObj) +static inline MsiActiveScriptSite *impl_from_IActiveScriptSite( IActiveScriptSite *iface ) { - MsiActiveScriptSite* object; - - TRACE("(%p,%p)\n", pUnkOuter, ppObj); - - if( pUnkOuter ) - return CLASS_E_NOAGGREGATION; - - object = msi_alloc_zero( sizeof(MsiActiveScriptSite) ); - - object->lpVtbl.lpVtbl = &ASS_Vtbl; - object->ref = 1; - object->pInstaller = NULL; - object->pSession = NULL; - - *ppObj = object; - - return S_OK; -} - -/* - * Call a script. - */ -DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action) -{ - HRESULT hr; - IActiveScript *pActiveScript = NULL; - IActiveScriptParse32 *pActiveScriptParse32 = NULL; - IActiveScriptParse64 *pActiveScriptParse64 = NULL; - MsiActiveScriptSite *pActiveScriptSite = NULL; - IDispatch *pDispatch = NULL; - DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0}; - DISPID dispid; - CLSID clsid; - VARIANT var; - DWORD ret = ERROR_INSTALL_FAILURE; - - CoInitialize(NULL); - - /* Create MsiActiveScriptSite object */ - hr = create_ActiveScriptSite(NULL, (void **)&pActiveScriptSite); - if (hr != S_OK) goto done; - - /* Create an installer object */ - hr = create_msiserver(NULL, (LPVOID *)&pActiveScriptSite->pInstaller); - if (hr != S_OK) goto done; - - /* Create a session object */ - hr = create_session(hPackage, pActiveScriptSite->pInstaller, &pActiveScriptSite->pSession); - if (hr != S_OK) goto done; - - /* Create the scripting engine */ - if ((type & 7) == msidbCustomActionTypeJScript) - hr = CLSIDFromProgID(szJScript, &clsid); - else if ((type & 7) == msidbCustomActionTypeVBScript) - hr = CLSIDFromProgID(szVBScript, &clsid); - else { - ERR("Unknown script type %d\n", type); - goto done; - } - if (FAILED(hr)) { - ERR("Could not find CLSID for Windows Script\n"); - goto done; - } - hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IActiveScript, (void **)&pActiveScript); - if (FAILED(hr)) { - ERR("Could not instantiate class for Windows Script\n"); - goto done; - } - - if (type & msidbCustomActionType64BitScript) - { - hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse64, (void **)&pActiveScriptParse64); - if (FAILED(hr)) goto done; - - hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite); - if (FAILED(hr)) goto done; - - hr = IActiveScriptParse64_InitNew(pActiveScriptParse64); - if (FAILED(hr)) goto done; - - hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS); - if (FAILED(hr)) goto done; - - hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse64, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL); - if (FAILED(hr)) goto done; - } - else - { - hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse32, (void **)&pActiveScriptParse32); - if (FAILED(hr)) goto done; - - hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite); - if (FAILED(hr)) goto done; - - hr = IActiveScriptParse32_InitNew(pActiveScriptParse32); - if (FAILED(hr)) goto done; - - hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS); - if (FAILED(hr)) goto done; - - hr = IActiveScriptParse32_ParseScriptText(pActiveScriptParse32, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL); - if (FAILED(hr)) goto done; - } - - hr = IActiveScript_SetScriptState(pActiveScript, SCRIPTSTATE_CONNECTED); - if (FAILED(hr)) goto done; - - /* Call a function if necessary through the IDispatch interface */ - if (function != NULL && strlenW(function) > 0) { - TRACE("Calling function %s\n", debugstr_w(function)); - - hr = IActiveScript_GetScriptDispatch(pActiveScript, NULL, &pDispatch); - if (FAILED(hr)) goto done; - - hr = IDispatch_GetIDsOfNames(pDispatch, &IID_NULL, (WCHAR **)&function, 1,LOCALE_USER_DEFAULT, &dispid); - if (FAILED(hr)) goto done; - - hr = IDispatch_Invoke(pDispatch, dispid, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparamsNoArgs, &var, NULL, NULL); - if (FAILED(hr)) goto done; - - /* Check return value, if it's not IDOK we failed */ - hr = VariantChangeType(&var, &var, 0, VT_I4); - if (FAILED(hr)) goto done; - - if (V_I4(&var) == IDOK) - ret = ERROR_SUCCESS; - else ret = ERROR_INSTALL_FAILURE; - - VariantClear(&var); - } else { - /* If no function to be called, MSI behavior is to succeed */ - ret = ERROR_SUCCESS; - } - -done: - - if (pDispatch) IDispatch_Release(pDispatch); - if (pActiveScript) IActiveScript_Release(pActiveScript); - if (pActiveScriptParse32) IActiveScriptParse32_Release(pActiveScriptParse32); - if (pActiveScriptParse64) IActiveScriptParse64_Release(pActiveScriptParse64); - if (pActiveScriptSite) - { - if (pActiveScriptSite->pSession) IDispatch_Release(pActiveScriptSite->pSession); - if (pActiveScriptSite->pInstaller) IDispatch_Release(pActiveScriptSite->pInstaller); - IActiveScriptSite_Release((IActiveScriptSite *)pActiveScriptSite); - } - CoUninitialize(); /* must call even if CoInitialize failed */ - return ret; + return CONTAINING_RECORD(iface, MsiActiveScriptSite, IActiveScriptSite_iface); } /* * MsiActiveScriptSite */ - -/*** IUnknown methods ***/ -static HRESULT WINAPI MsiActiveScriptSite_QueryInterface(IActiveScriptSite* iface, REFIID riid, void** ppvObject) +static HRESULT WINAPI MsiActiveScriptSite_QueryInterface(IActiveScriptSite* iface, REFIID riid, void** obj) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); - TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj); if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IActiveScriptSite)) { IActiveScriptSite_AddRef(iface); - *ppvObject = This; + *obj = iface; return S_OK; } - TRACE("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + *obj = NULL; return E_NOINTERFACE; } static ULONG WINAPI MsiActiveScriptSite_AddRef(IActiveScriptSite* iface) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; - - TRACE("(%p/%p)\n", iface, This); - - return InterlockedIncrement(&This->ref); + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p)->(%d)\n", This, ref); + return ref; } static ULONG WINAPI MsiActiveScriptSite_Release(IActiveScriptSite* iface) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p/%p)\n", iface, This); + TRACE("(%p)->(%d)\n", This, ref); if (!ref) msi_free(This); @@ -251,18 +112,18 @@ static ULONG WINAPI MsiActiveScriptSite_Release(IActiveScriptSite* iface) return ref; } -/*** IActiveScriptSite methods **/ static HRESULT WINAPI MsiActiveScriptSite_GetLCID(IActiveScriptSite* iface, LCID* plcid) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; - TRACE("(%p/%p)->(%p)\n", This, iface, plcid); + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); + TRACE("(%p)->(%p)\n", This, plcid); return E_NOTIMPL; /* Script will use system-defined locale */ } static HRESULT WINAPI MsiActiveScriptSite_GetItemInfo(IActiveScriptSite* iface, LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppiunkItem, ITypeInfo** ppti) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; - TRACE("(%p/%p)->(%p,%d,%p,%p)\n", This, iface, pstrName, dwReturnMask, ppiunkItem, ppti); + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); + + TRACE("(%p)->(%p, %d, %p, %p)\n", This, pstrName, dwReturnMask, ppiunkItem, ppti); /* Determine the kind of pointer that is requested, and make sure placeholder is valid */ if (dwReturnMask & SCRIPTINFO_ITYPEINFO) { @@ -276,10 +137,14 @@ static HRESULT WINAPI MsiActiveScriptSite_GetItemInfo(IActiveScriptSite* iface, /* Are we looking for the session object? */ if (!strcmpW(szSession, pstrName)) { - if (dwReturnMask & SCRIPTINFO_ITYPEINFO) - return load_type_info(This->pSession, ppti, &DIID_Session, 0); + if (dwReturnMask & SCRIPTINFO_ITYPEINFO) { + HRESULT hr = get_typeinfo(Session_tid, ppti); + if (SUCCEEDED(hr)) + ITypeInfo_AddRef(*ppti); + return hr; + } else if (dwReturnMask & SCRIPTINFO_IUNKNOWN) { - IDispatch_QueryInterface(This->pSession, &IID_IUnknown, (void **)ppiunkItem); + IDispatch_QueryInterface(This->session, &IID_IUnknown, (void **)ppiunkItem); return S_OK; } } @@ -289,15 +154,15 @@ static HRESULT WINAPI MsiActiveScriptSite_GetItemInfo(IActiveScriptSite* iface, static HRESULT WINAPI MsiActiveScriptSite_GetDocVersionString(IActiveScriptSite* iface, BSTR* pbstrVersion) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; - TRACE("(%p/%p)->(%p)\n", This, iface, pbstrVersion); + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); + TRACE("(%p)->(%p)\n", This, pbstrVersion); return E_NOTIMPL; } static HRESULT WINAPI MsiActiveScriptSite_OnScriptTerminate(IActiveScriptSite* iface, const VARIANT* pvarResult, const EXCEPINFO* pexcepinfo) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; - TRACE("(%p/%p)->(%p,%p)\n", This, iface, pvarResult, pexcepinfo); + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); + TRACE("(%p)->(%p, %p)\n", This, pvarResult, pexcepinfo); return S_OK; } @@ -338,11 +203,11 @@ static HRESULT WINAPI MsiActiveScriptSite_OnStateChange(IActiveScriptSite* iface static HRESULT WINAPI MsiActiveScriptSite_OnScriptError(IActiveScriptSite* iface, IActiveScriptError* pscripterror) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); EXCEPINFO exception; HRESULT hr; - TRACE("(%p/%p)->(%p)\n", This, iface, pscripterror); + TRACE("(%p)->(%p)\n", This, pscripterror); memset(&exception, 0, sizeof(EXCEPINFO)); hr = IActiveScriptError_GetExceptionInfo(pscripterror, &exception); @@ -359,19 +224,19 @@ static HRESULT WINAPI MsiActiveScriptSite_OnScriptError(IActiveScriptSite* iface static HRESULT WINAPI MsiActiveScriptSite_OnEnterScript(IActiveScriptSite* iface) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; - TRACE("(%p/%p)\n", This, iface); + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); + TRACE("(%p)\n", This); return S_OK; } static HRESULT WINAPI MsiActiveScriptSite_OnLeaveScript(IActiveScriptSite* iface) { - MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface; - TRACE("(%p/%p)\n", This, iface); + MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface); + TRACE("(%p)\n", This); return S_OK; } -static const struct IActiveScriptSiteVtbl ASS_Vtbl = +static const struct IActiveScriptSiteVtbl activescriptsitevtbl = { MsiActiveScriptSite_QueryInterface, MsiActiveScriptSite_AddRef, @@ -385,3 +250,135 @@ static const struct IActiveScriptSiteVtbl ASS_Vtbl = MsiActiveScriptSite_OnEnterScript, MsiActiveScriptSite_OnLeaveScript }; + +static HRESULT create_activescriptsite(MsiActiveScriptSite **obj) +{ + MsiActiveScriptSite* object; + + TRACE("(%p)\n", obj); + + *obj = NULL; + + object = msi_alloc( sizeof(MsiActiveScriptSite) ); + if (!object) + return E_OUTOFMEMORY; + + object->IActiveScriptSite_iface.lpVtbl = &activescriptsitevtbl; + object->ref = 1; + object->installer = NULL; + object->session = NULL; + + *obj = object; + + return S_OK; +} + +/* + * Call a script. + */ +DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action) +{ + HRESULT hr; + IActiveScript *pActiveScript = NULL; + IActiveScriptParse *pActiveScriptParse = NULL; + MsiActiveScriptSite *scriptsite; + IDispatch *pDispatch = NULL; + DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0}; + DISPID dispid; + CLSID clsid; + VARIANT var; + DWORD ret = ERROR_INSTALL_FAILURE; + + CoInitialize(NULL); + + /* Create MsiActiveScriptSite object */ + hr = create_activescriptsite(&scriptsite); + if (hr != S_OK) goto done; + + /* Create an installer object */ + hr = create_msiserver(NULL, (void**)&scriptsite->installer); + if (hr != S_OK) goto done; + + /* Create a session object */ + hr = create_session(hPackage, scriptsite->installer, &scriptsite->session); + if (hr != S_OK) goto done; + + /* Create the scripting engine */ + type &= msidbCustomActionTypeJScript|msidbCustomActionTypeVBScript; + if (type == msidbCustomActionTypeJScript) + hr = CLSIDFromProgID(szJScript, &clsid); + else if (type == msidbCustomActionTypeVBScript) + hr = CLSIDFromProgID(szVBScript, &clsid); + else { + ERR("Unknown script type %d\n", type); + goto done; + } + if (FAILED(hr)) { + ERR("Could not find CLSID for Windows Script\n"); + goto done; + } + hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IActiveScript, (void **)&pActiveScript); + if (FAILED(hr)) { + ERR("Could not instantiate class for Windows Script\n"); + goto done; + } + + hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse, (void **)&pActiveScriptParse); + if (FAILED(hr)) goto done; + + hr = IActiveScript_SetScriptSite(pActiveScript, &scriptsite->IActiveScriptSite_iface); + if (FAILED(hr)) goto done; + + hr = IActiveScriptParse_InitNew(pActiveScriptParse); + if (FAILED(hr)) goto done; + + hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS|SCRIPTITEM_ISVISIBLE); + if (FAILED(hr)) goto done; + + hr = IActiveScriptParse_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL); + if (FAILED(hr)) goto done; + + hr = IActiveScript_SetScriptState(pActiveScript, SCRIPTSTATE_CONNECTED); + if (FAILED(hr)) goto done; + + /* Call a function if necessary through the IDispatch interface */ + if (function != NULL && strlenW(function) > 0) { + TRACE("Calling function %s\n", debugstr_w(function)); + + hr = IActiveScript_GetScriptDispatch(pActiveScript, NULL, &pDispatch); + if (FAILED(hr)) goto done; + + hr = IDispatch_GetIDsOfNames(pDispatch, &IID_NULL, (WCHAR **)&function, 1,LOCALE_USER_DEFAULT, &dispid); + if (FAILED(hr)) goto done; + + hr = IDispatch_Invoke(pDispatch, dispid, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparamsNoArgs, &var, NULL, NULL); + if (FAILED(hr)) goto done; + + /* Check return value, if it's not IDOK we failed */ + hr = VariantChangeType(&var, &var, 0, VT_I4); + if (FAILED(hr)) goto done; + + if (V_I4(&var) == IDOK) + ret = ERROR_SUCCESS; + else ret = ERROR_INSTALL_FAILURE; + + VariantClear(&var); + } else { + /* If no function to be called, MSI behavior is to succeed */ + ret = ERROR_SUCCESS; + } + +done: + + if (pDispatch) IDispatch_Release(pDispatch); + if (pActiveScript) IActiveScript_Release(pActiveScript); + if (pActiveScriptParse) IActiveScriptParse_Release(pActiveScriptParse); + if (scriptsite) + { + if (scriptsite->session) IDispatch_Release(scriptsite->session); + if (scriptsite->installer) IDispatch_Release(scriptsite->installer); + IActiveScriptSite_Release(&scriptsite->IActiveScriptSite_iface); + } + CoUninitialize(); /* must call even if CoInitialize failed */ + return ret; +} diff --git a/dll/win32/msi/select.c b/dll/win32/msi/select.c index 982cf6a9369..e8f38855a86 100644 --- a/dll/win32/msi/select.c +++ b/dll/win32/msi/select.c @@ -276,8 +276,9 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) } else if (type & MSITYPE_STRING) { - str = MSI_RecordGetString(rec, i + 1); - r = MSI_RecordSetStringW(mod, col, str); + int len; + str = msi_record_get_string( rec, i + 1, &len ); + r = msi_record_set_string( mod, col, str, len ); } else { @@ -430,7 +431,7 @@ UINT SELECT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, count = select_count_columns( columns ); - sv = msi_alloc_zero( sizeof *sv + count*sizeof (UINT) ); + sv = msi_alloc_zero( FIELD_OFFSET( MSISELECTVIEW, cols[count] )); if( !sv ) return ERROR_FUNCTION_FAILED; diff --git a/dll/win32/msi/source.c b/dll/win32/msi/source.c index 881f3d26bf2..ab8541c170c 100644 --- a/dll/win32/msi/source.c +++ b/dll/win32/msi/source.c @@ -763,7 +763,10 @@ UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid, r = OpenSourceKey(product, &source, MSICODE_PRODUCT, context, FALSE); if (r != ERROR_SUCCESS) + { + msi_free(buffer); return r; + } sprintfW(buffer, format, typechar, index, value); diff --git a/dll/win32/msi/storages.c b/dll/win32/msi/storages.c index c980df8aa32..35c1de5903d 100644 --- a/dll/win32/msi/storages.c +++ b/dll/win32/msi/storages.c @@ -312,7 +312,7 @@ static UINT storages_find_row(MSISTORAGESVIEW *sv, MSIRECORD *rec, UINT *row) UINT r, i, id, data; str = MSI_RecordGetString(rec, 1); - r = msi_string2idW(sv->db->strings, str, &id); + r = msi_string2id(sv->db->strings, str, -1, &id); if (r != ERROR_SUCCESS) return r; diff --git a/dll/win32/msi/streams.c b/dll/win32/msi/streams.c index 71616e93eb0..d9d632fafbc 100644 --- a/dll/win32/msi/streams.c +++ b/dll/win32/msi/streams.c @@ -299,7 +299,7 @@ static UINT streams_find_row(MSISTREAMSVIEW *sv, MSIRECORD *rec, UINT *row) UINT r, i, id, data; str = MSI_RecordGetString(rec, 1); - r = msi_string2idW(sv->db->strings, str, &id); + r = msi_string2id(sv->db->strings, str, -1, &id); if (r != ERROR_SUCCESS) return r; diff --git a/dll/win32/msi/string.c b/dll/win32/msi/string.c index 065c04a3720..8e3e575f502 100644 --- a/dll/win32/msi/string.c +++ b/dll/win32/msi/string.c @@ -45,7 +45,8 @@ struct msistring { USHORT persistent_refcount; USHORT nonpersistent_refcount; - LPWSTR str; + WCHAR *data; + int len; }; struct string_table @@ -112,7 +113,7 @@ VOID msi_destroy_stringtable( string_table *st ) { if( st->strings[i].persistent_refcount || st->strings[i].nonpersistent_refcount ) - msi_free( st->strings[i].str ); + msi_free( st->strings[i].data ); } msi_free( st->strings ); msi_free( st->sorted ); @@ -162,6 +163,19 @@ static int st_find_free_entry( string_table *st ) return st->freeslot; } +static inline int cmp_string( const WCHAR *str1, int len1, const WCHAR *str2, int len2 ) +{ + if (len1 < len2) return -1; + else if (len1 > len2) return 1; + while (len1) + { + if (*str1 == *str2) { str1++; str2++; } + else return *str1 - *str2; + len1--; + } + return 0; +} + static int find_insert_index( const string_table *st, UINT string_id ) { int i, c, low = 0, high = st->sortcount - 1; @@ -169,8 +183,8 @@ static int find_insert_index( const string_table *st, UINT string_id ) while (low <= high) { i = (low + high) / 2; - c = strcmpW( st->strings[string_id].str, st->strings[st->sorted[i]].str ); - + c = cmp_string( st->strings[string_id].data, st->strings[string_id].len, + st->strings[st->sorted[i]].data, st->strings[st->sorted[i]].len ); if (c < 0) high = i - 1; else if (c > 0) @@ -194,7 +208,8 @@ static void insert_string_sorted( string_table *st, UINT string_id ) st->sortcount++; } -static void set_st_entry( string_table *st, UINT n, LPWSTR str, USHORT refcount, enum StringPersistence persistence ) +static void set_st_entry( string_table *st, UINT n, WCHAR *str, int len, USHORT refcount, + enum StringPersistence persistence ) { if (persistence == StringPersistent) { @@ -207,7 +222,8 @@ static void set_st_entry( string_table *st, UINT n, LPWSTR str, USHORT refcount, st->strings[n].nonpersistent_refcount = refcount; } - st->strings[n].str = str; + st->strings[n].data = str; + st->strings[n].len = len; insert_string_sorted( st, n ); @@ -237,20 +253,17 @@ static UINT msi_string2idA( const string_table *st, LPCSTR buffer, UINT *id ) return ERROR_NOT_ENOUGH_MEMORY; MultiByteToWideChar( st->codepage, 0, buffer, -1, str, sz ); - r = msi_string2idW( st, str, id ); + r = msi_string2id( st, str, sz - 1, id ); msi_free( str ); - return r; } -static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, USHORT refcount, enum StringPersistence persistence ) +static int msi_addstring( string_table *st, UINT n, const char *data, UINT len, USHORT refcount, enum StringPersistence persistence ) { LPWSTR str; int sz; - if( !data ) - return 0; - if( !data[0] ) + if( !data || !len ) return 0; if( n > 0 ) { @@ -280,8 +293,6 @@ static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, U } /* allocate a new string */ - if( len < 0 ) - len = strlen(data); sz = MultiByteToWideChar( st->codepage, 0, data, len, NULL, 0 ); str = msi_alloc( (sz+1)*sizeof(WCHAR) ); if( !str ) @@ -289,8 +300,7 @@ static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, U MultiByteToWideChar( st->codepage, 0, data, len, str, sz ); str[sz] = 0; - set_st_entry( st, n, str, refcount, persistence ); - + set_st_entry( st, n, str, sz, refcount, persistence ); return n; } @@ -301,10 +311,13 @@ int msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcoun if( !data ) return 0; - if( !data[0] ) + + if (len < 0) len = strlenW( data ); + + if( !data[0] && !len ) return 0; - if( msi_string2idW( st, data, &n ) == ERROR_SUCCESS ) + if (msi_string2id( st, data, len, &n) == ERROR_SUCCESS ) { if (persistence == StringPersistent) st->strings[n].persistent_refcount += refcount; @@ -318,9 +331,7 @@ int msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcoun return -1; /* allocate a new string */ - if(len<0) - len = strlenW(data); - TRACE("%s, n = %d len = %d\n", debugstr_w(data), n, len ); + TRACE( "%s, n = %d len = %d\n", debugstr_wn(data, len), n, len ); str = msi_alloc( (len+1)*sizeof(WCHAR) ); if( !str ) @@ -328,24 +339,27 @@ int msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcoun memcpy( str, data, len*sizeof(WCHAR) ); str[len] = 0; - set_st_entry( st, n, str, refcount, persistence ); - + set_st_entry( st, n, str, len, refcount, persistence ); return n; } /* find the string identified by an id - return null if there's none */ -const WCHAR *msi_string_lookup_id( const string_table *st, UINT id ) +const WCHAR *msi_string_lookup( const string_table *st, UINT id, int *len ) { if( id == 0 ) + { + if (len) *len = 0; return szEmpty; - + } if( id >= st->maxcount ) return NULL; if( id && !st->strings[id].persistent_refcount && !st->strings[id].nonpersistent_refcount) return NULL; - return st->strings[id].str; + if (len) *len = st->strings[id].len; + + return st->strings[id].data; } /* @@ -361,16 +375,15 @@ const WCHAR *msi_string_lookup_id( const string_table *st, UINT id ) */ static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT *sz ) { - UINT len, lenW; + int len, lenW; const WCHAR *str; TRACE("Finding string %d of %d\n", id, st->maxcount); - str = msi_string_lookup_id( st, id ); + str = msi_string_lookup( st, id, &lenW ); if( !str ) return ERROR_FUNCTION_FAILED; - lenW = strlenW( str ); len = WideCharToMultiByte( st->codepage, 0, str, lenW, NULL, 0, NULL, NULL ); if( *sz < len ) { @@ -382,20 +395,22 @@ static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT } /* - * msi_string2idW + * msi_string2id * * [in] st - pointer to the string table * [in] str - string to find in the string table * [out] id - id of the string, if found */ -UINT msi_string2idW( const string_table *st, LPCWSTR str, UINT *id ) +UINT msi_string2id( const string_table *st, const WCHAR *str, int len, UINT *id ) { int i, c, low = 0, high = st->sortcount - 1; + if (len < 0) len = strlenW( str ); + while (low <= high) { i = (low + high) / 2; - c = strcmpW( str, st->strings[st->sorted[i]].str ); + c = cmp_string( str, len, st->strings[st->sorted[i]].data, st->strings[st->sorted[i]].len ); if (c < 0) high = i - 1; @@ -407,7 +422,6 @@ UINT msi_string2idW( const string_table *st, LPCWSTR str, UINT *id ) return ERROR_SUCCESS; } } - return ERROR_INVALID_PARAMETER; } @@ -415,7 +429,7 @@ static void string_totalsize( const string_table *st, UINT *datasize, UINT *pool { UINT i, len, holesize; - if( st->strings[0].str || st->strings[0].persistent_refcount || st->strings[0].nonpersistent_refcount) + if( st->strings[0].data || st->strings[0].persistent_refcount || st->strings[0].nonpersistent_refcount) ERR("oops. element 0 has a string\n"); *poolsize = 4; @@ -425,14 +439,14 @@ static void string_totalsize( const string_table *st, UINT *datasize, UINT *pool { if( !st->strings[i].persistent_refcount ) { - TRACE("[%u] nonpersistent = %s\n", i, debugstr_w(st->strings[i].str)); + TRACE("[%u] nonpersistent = %s\n", i, debugstr_wn(st->strings[i].data, st->strings[i].len)); (*poolsize) += 4; } - else if( st->strings[i].str ) + else if( st->strings[i].data ) { - TRACE("[%u] = %s\n", i, debugstr_w(st->strings[i].str)); - len = WideCharToMultiByte( st->codepage, 0, - st->strings[i].str, -1, NULL, 0, NULL, NULL); + TRACE("[%u] = %s\n", i, debugstr_wn(st->strings[i].data, st->strings[i].len)); + len = WideCharToMultiByte( st->codepage, 0, st->strings[i].data, st->strings[i].len + 1, + NULL, 0, NULL, NULL); if( len ) len--; (*datasize) += len; diff --git a/dll/win32/msi/table.c b/dll/win32/msi/table.c index dd25fbb2cde..e2186fcb3cf 100644 --- a/dll/win32/msi/table.c +++ b/dll/win32/msi/table.c @@ -660,7 +660,7 @@ static UINT get_tablecolumns( MSIDATABASE *db, LPCWSTR szTableName, MSICOLUMNINF } /* convert table and column names to IDs from the string table */ - r = msi_string2idW( db->strings, szTableName, &table_id ); + r = msi_string2id( db->strings, szTableName, -1, &table_id ); if (r != ERROR_SUCCESS) { WARN("Couldn't find id for %s\n", debugstr_w(szTableName)); @@ -693,9 +693,9 @@ static UINT get_tablecolumns( MSIDATABASE *db, LPCWSTR szTableName, MSICOLUMNINF ERR("duplicate column %d\n", col); continue; } - colinfo[col - 1].tablename = msi_string_lookup_id( db->strings, table_id ); + colinfo[col - 1].tablename = msi_string_lookup( db->strings, table_id, NULL ); colinfo[col - 1].number = col; - colinfo[col - 1].colname = msi_string_lookup_id( db->strings, id ); + colinfo[col - 1].colname = msi_string_lookup( db->strings, id, NULL ); colinfo[col - 1].type = read_table_int( table->data, i, table->colinfo[3].offset, sizeof(USHORT) ) - (1 << 15); colinfo[col - 1].offset = 0; @@ -763,9 +763,9 @@ UINT msi_create_table( MSIDATABASE *db, LPCWSTR name, column_info *col_info, UINT table_id = msi_addstringW( db->strings, col->table, -1, 1, string_persistence ); UINT col_id = msi_addstringW( db->strings, col->column, -1, 1, string_persistence ); - table->colinfo[ i ].tablename = msi_string_lookup_id( db->strings, table_id ); + table->colinfo[ i ].tablename = msi_string_lookup( db->strings, table_id, NULL ); table->colinfo[ i ].number = i + 1; - table->colinfo[ i ].colname = msi_string_lookup_id( db->strings, col_id ); + table->colinfo[ i ].colname = msi_string_lookup( db->strings, col_id, NULL ); table->colinfo[ i ].type = col->type; table->colinfo[ i ].offset = 0; table->colinfo[ i ].ref_count = 0; @@ -981,7 +981,7 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name ) !strcmpW( name, szStreams ) || !strcmpW( name, szStorages ) ) return TRUE; - r = msi_string2idW( db->strings, name, &table_id ); + r = msi_string2id( db->strings, name, -1, &table_id ); if( r != ERROR_SUCCESS ) { TRACE("Couldn't find id for %s\n", debugstr_w(name)); @@ -1087,7 +1087,7 @@ static UINT msi_stream_name( const MSITABLEVIEW *tv, UINT row, LPWSTR *pstname ) if ( tv->columns[i].type & MSITYPE_STRING ) { - sval = msi_string_lookup_id( tv->db->strings, ival ); + sval = msi_string_lookup( tv->db->strings, ival, NULL ); if ( !sval ) { r = ERROR_INVALID_PARAMETER; @@ -1273,10 +1273,11 @@ static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT } else if ( columninfo.type & MSITYPE_STRING ) { - LPCWSTR sval = MSI_RecordGetString( rec, iField ); + int len; + const WCHAR *sval = msi_record_get_string( rec, iField, &len ); if (sval) { - r = msi_string2idW(tv->db->strings, sval, pvalue); + r = msi_string2id( tv->db->strings, sval, len, pvalue ); if (r != ERROR_SUCCESS) return ERROR_NOT_FOUND; } @@ -1360,8 +1361,9 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI if ( r != ERROR_SUCCESS ) { - LPCWSTR sval = MSI_RecordGetString( rec, i + 1 ); - val = msi_addstringW( tv->db->strings, sval, -1, 1, + int len; + const WCHAR *sval = msi_record_get_string( rec, i + 1, &len ); + val = msi_addstringW( tv->db->strings, sval, len, 1, persistent ? StringPersistent : StringNonPersistent ); } else @@ -1530,10 +1532,10 @@ static UINT table_validate_new( MSITABLEVIEW *tv, MSIRECORD *rec, UINT *column ) TRACE("skipping binary column\n"); else if ( tv->columns[i].type & MSITYPE_STRING ) { - LPCWSTR str; + int len; + const WCHAR *str = msi_record_get_string( rec, i+1, &len ); - str = MSI_RecordGetString( rec, i+1 ); - if (str == NULL || str[0] == 0) + if (!str || (!str[0] && !len)) { if (column) *column = i; return ERROR_INVALID_DATA; @@ -2139,7 +2141,7 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view ) else if ( !strcmpW( name, szStorages ) ) return STORAGES_CreateView( db, view ); - sz = sizeof *tv + lstrlenW(name)*sizeof name[0] ; + sz = FIELD_OFFSET( MSITABLEVIEW, name[lstrlenW( name ) + 1] ); tv = msi_alloc_zero( sz ); if( !tv ) return ERROR_FUNCTION_FAILED; @@ -2265,6 +2267,7 @@ static UINT msi_record_encoded_stream_name( const MSITABLEVIEW *tv, MSIRECORD *r if ( !p ) { r = ERROR_OUTOFMEMORY; + msi_free(sval); goto err; } stname = p; @@ -2328,21 +2331,25 @@ static MSIRECORD *msi_get_transform_record( const MSITABLEVIEW *tv, const string r = IStorage_OpenStream( stg, encname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm ); - msi_free( encname ); if ( r != ERROR_SUCCESS ) + { + msi_free( encname ); return NULL; + } MSI_RecordSetStream( rec, i+1, stm ); TRACE(" field %d [%s]\n", i+1, debugstr_w(encname)); + msi_free( encname ); } else if( columns[i].type & MSITYPE_STRING ) { - LPCWSTR sval; + int len; + const WCHAR *sval; val = read_raw_int(rawdata, ofs, bytes_per_strref); - sval = msi_string_lookup_id( st, val ); - MSI_RecordSetStringW( rec, i+1, sval ); - TRACE(" field %d [%s]\n", i+1, debugstr_w(sval)); + sval = msi_string_lookup( st, val, &len ); + msi_record_set_string( rec, i+1, sval, len ); + TRACE(" field %d [%s]\n", i+1, debugstr_wn(sval, len)); ofs += bytes_per_strref; } else @@ -2379,12 +2386,13 @@ static void dump_record( MSIRECORD *rec ) n = MSI_RecordGetFieldCount( rec ); for( i=1; i<=n; i++ ) { - LPCWSTR sval; + int len; + const WCHAR *sval; if( MSI_RecordIsNull( rec, i ) ) TRACE("row -> []\n"); - else if( (sval = MSI_RecordGetString( rec, i )) ) - TRACE("row -> [%s]\n", debugstr_w(sval)); + else if( (sval = msi_record_get_string( rec, i, &len )) ) + TRACE("row -> [%s]\n", debugstr_wn(sval, len)); else TRACE("row -> [0x%08x]\n", MSI_RecordGetInteger( rec, i ) ); } @@ -2392,19 +2400,17 @@ static void dump_record( MSIRECORD *rec ) static void dump_table( const string_table *st, const USHORT *rawdata, UINT rawsize ) { - LPCWSTR sval; UINT i; - - for( i=0; i<(rawsize/2); i++ ) + for (i = 0; i < rawsize / 2; i++) { - sval = msi_string_lookup_id( st, rawdata[i] ); - MESSAGE(" %04x %s\n", rawdata[i], debugstr_w(sval) ); + int len; + const WCHAR *sval = msi_string_lookup( st, rawdata[i], &len ); + MESSAGE(" %04x %s\n", rawdata[i], debugstr_wn(sval, len) ); } } static UINT* msi_record_to_row( const MSITABLEVIEW *tv, MSIRECORD *rec ) { - LPCWSTR str; UINT i, r, *data; data = msi_alloc( tv->num_cols *sizeof (UINT) ); @@ -2419,10 +2425,11 @@ static UINT* msi_record_to_row( const MSITABLEVIEW *tv, MSIRECORD *rec ) if ( ( tv->columns[i].type & MSITYPE_STRING ) && ! MSITYPE_IS_BINARY(tv->columns[i].type) ) { - str = MSI_RecordGetString( rec, i+1 ); + int len; + const WCHAR *str = msi_record_get_string( rec, i+1, &len ); if (str) { - r = msi_string2idW( tv->db->strings, str, &data[i] ); + r = msi_string2id( tv->db->strings, str, len, &data[i] ); /* if there's no matching string in the string table, these keys can't match any record, so fail now. */ diff --git a/dll/win32/msi/tokenize.c b/dll/win32/msi/tokenize.c index 47989175b08..441a54aff3d 100644 --- a/dll/win32/msi/tokenize.c +++ b/dll/win32/msi/tokenize.c @@ -32,103 +32,108 @@ */ typedef struct Keyword Keyword; struct Keyword { - const WCHAR *zName; /* The keyword name */ + const WCHAR *name; /* The keyword name */ + unsigned int len; int tokenType; /* The token value for this keyword */ }; #define MAX_TOKEN_LEN 11 -static const WCHAR ADD_W[] = { 'A','D','D',0 }; -static const WCHAR ALTER_W[] = { 'A','L','T','E','R',0 }; -static const WCHAR AND_W[] = { 'A','N','D',0 }; -static const WCHAR BY_W[] = { 'B','Y',0 }; -static const WCHAR CHAR_W[] = { 'C','H','A','R',0 }; -static const WCHAR CHARACTER_W[] = { 'C','H','A','R','A','C','T','E','R',0 }; -static const WCHAR CREATE_W[] = { 'C','R','E','A','T','E',0 }; -static const WCHAR DELETE_W[] = { 'D','E','L','E','T','E',0 }; -static const WCHAR DISTINCT_W[] = { 'D','I','S','T','I','N','C','T',0 }; -static const WCHAR DROP_W[] = { 'D','R','O','P',0 }; -static const WCHAR FREE_W[] = { 'F','R','E','E',0 }; -static const WCHAR FROM_W[] = { 'F','R','O','M',0 }; -static const WCHAR HOLD_W[] = { 'H','O','L','D',0 }; -static const WCHAR INSERT_W[] = { 'I','N','S','E','R','T',0 }; -static const WCHAR INT_W[] = { 'I','N','T',0 }; -static const WCHAR INTEGER_W[] = { 'I','N','T','E','G','E','R',0 }; -static const WCHAR INTO_W[] = { 'I','N','T','O',0 }; -static const WCHAR IS_W[] = { 'I','S',0 }; -static const WCHAR KEY_W[] = { 'K','E','Y',0 }; -static const WCHAR LIKE_W[] = { 'L','I','K','E',0 }; -static const WCHAR LOCALIZABLE_W[] = { 'L','O','C','A','L','I','Z','A','B','L','E',0 }; -static const WCHAR LONG_W[] = { 'L','O','N','G',0 }; -static const WCHAR LONGCHAR_W[] = { 'L','O','N','G','C','H','A','R',0 }; -static const WCHAR NOT_W[] = { 'N','O','T',0 }; -static const WCHAR NULL_W[] = { 'N','U','L','L',0 }; -static const WCHAR OBJECT_W[] = { 'O','B','J','E','C','T',0 }; -static const WCHAR OR_W[] = { 'O','R',0 }; -static const WCHAR ORDER_W[] = { 'O','R','D','E','R',0 }; -static const WCHAR PRIMARY_W[] = { 'P','R','I','M','A','R','Y',0 }; -static const WCHAR SELECT_W[] = { 'S','E','L','E','C','T',0 }; -static const WCHAR SET_W[] = { 'S','E','T',0 }; -static const WCHAR SHORT_W[] = { 'S','H','O','R','T',0 }; -static const WCHAR TABLE_W[] = { 'T','A','B','L','E',0 }; -static const WCHAR TEMPORARY_W[] = { 'T','E','M','P','O','R','A','R','Y',0 }; -static const WCHAR UPDATE_W[] = { 'U','P','D','A','T','E',0 }; -static const WCHAR VALUES_W[] = { 'V','A','L','U','E','S',0 }; -static const WCHAR WHERE_W[] = { 'W','H','E','R','E',0 }; +static const WCHAR addW[] = {'A','D','D'}; +static const WCHAR alterW[] = {'A','L','T','E','R'}; +static const WCHAR andW[] = {'A','N','D'}; +static const WCHAR byW[] = {'B','Y'}; +static const WCHAR charW[] = {'C','H','A','R'}; +static const WCHAR characterW[] = {'C','H','A','R','A','C','T','E','R'}; +static const WCHAR createW[] = {'C','R','E','A','T','E'}; +static const WCHAR deleteW[] = {'D','E','L','E','T','E'}; +static const WCHAR distinctW[] = {'D','I','S','T','I','N','C','T'}; +static const WCHAR dropW[] = {'D','R','O','P'}; +static const WCHAR freeW[] = {'F','R','E','E'}; +static const WCHAR fromW[] = {'F','R','O','M'}; +static const WCHAR holdW[] = {'H','O','L','D'}; +static const WCHAR insertW[] = {'I','N','S','E','R','T'}; +static const WCHAR intW[] = {'I','N','T'}; +static const WCHAR integerW[] = {'I','N','T','E','G','E','R'}; +static const WCHAR intoW[] = {'I','N','T','O'}; +static const WCHAR isW[] = {'I','S'}; +static const WCHAR keyW[] = {'K','E','Y'}; +static const WCHAR likeW[] = {'L','I','K','E'}; +static const WCHAR localizableW[] = {'L','O','C','A','L','I','Z','A','B','L','E'}; +static const WCHAR longW[] = {'L','O','N','G'}; +static const WCHAR longcharW[] = {'L','O','N','G','C','H','A','R'}; +static const WCHAR notW[] = {'N','O','T'}; +static const WCHAR nullW[] = {'N','U','L','L'}; +static const WCHAR objectW[] = {'O','B','J','E','C','T'}; +static const WCHAR orW[] = {'O','R'}; +static const WCHAR orderW[] = {'O','R','D','E','R'}; +static const WCHAR primaryW[] = {'P','R','I','M','A','R','Y'}; +static const WCHAR selectW[] = {'S','E','L','E','C','T'}; +static const WCHAR setW[] = {'S','E','T'}; +static const WCHAR shortW[] = {'S','H','O','R','T'}; +static const WCHAR tableW[] = {'T','A','B','L','E'}; +static const WCHAR temporaryW[] = {'T','E','M','P','O','R','A','R','Y'}; +static const WCHAR updateW[] = {'U','P','D','A','T','E'}; +static const WCHAR valuesW[] = {'V','A','L','U','E','S'}; +static const WCHAR whereW[] = {'W','H','E','R','E'}; + +#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0])) /* ** These are the keywords ** They MUST be in alphabetical order */ static const Keyword aKeywordTable[] = { - { ADD_W, TK_ADD }, - { ALTER_W, TK_ALTER }, - { AND_W, TK_AND }, - { BY_W, TK_BY }, - { CHAR_W, TK_CHAR }, - { CHARACTER_W, TK_CHAR }, - { CREATE_W, TK_CREATE }, - { DELETE_W, TK_DELETE }, - { DISTINCT_W, TK_DISTINCT }, - { DROP_W, TK_DROP }, - { FREE_W, TK_FREE }, - { FROM_W, TK_FROM }, - { HOLD_W, TK_HOLD }, - { INSERT_W, TK_INSERT }, - { INT_W, TK_INT }, - { INTEGER_W, TK_INT }, - { INTO_W, TK_INTO }, - { IS_W, TK_IS }, - { KEY_W, TK_KEY }, - { LIKE_W, TK_LIKE }, - { LOCALIZABLE_W, TK_LOCALIZABLE }, - { LONG_W, TK_LONG }, - { LONGCHAR_W, TK_LONGCHAR }, - { NOT_W, TK_NOT }, - { NULL_W, TK_NULL }, - { OBJECT_W, TK_OBJECT }, - { OR_W, TK_OR }, - { ORDER_W, TK_ORDER }, - { PRIMARY_W, TK_PRIMARY }, - { SELECT_W, TK_SELECT }, - { SET_W, TK_SET }, - { SHORT_W, TK_SHORT }, - { TABLE_W, TK_TABLE }, - { TEMPORARY_W, TK_TEMPORARY }, - { UPDATE_W, TK_UPDATE }, - { VALUES_W, TK_VALUES }, - { WHERE_W, TK_WHERE }, + { addW, ARRAY_SIZE(addW), TK_ADD }, + { alterW, ARRAY_SIZE(alterW), TK_ALTER }, + { andW, ARRAY_SIZE(andW), TK_AND }, + { byW, ARRAY_SIZE(byW), TK_BY }, + { charW, ARRAY_SIZE(charW), TK_CHAR }, + { characterW, ARRAY_SIZE(characterW), TK_CHAR }, + { createW, ARRAY_SIZE(createW), TK_CREATE }, + { deleteW, ARRAY_SIZE(deleteW), TK_DELETE }, + { distinctW, ARRAY_SIZE(distinctW), TK_DISTINCT }, + { dropW, ARRAY_SIZE(dropW), TK_DROP }, + { freeW, ARRAY_SIZE(freeW), TK_FREE }, + { fromW, ARRAY_SIZE(fromW), TK_FROM }, + { holdW, ARRAY_SIZE(holdW), TK_HOLD }, + { insertW, ARRAY_SIZE(insertW), TK_INSERT }, + { intW, ARRAY_SIZE(intW), TK_INT }, + { integerW, ARRAY_SIZE(integerW), TK_INT }, + { intoW, ARRAY_SIZE(intoW), TK_INTO }, + { isW, ARRAY_SIZE(isW), TK_IS }, + { keyW, ARRAY_SIZE(keyW), TK_KEY }, + { likeW, ARRAY_SIZE(likeW), TK_LIKE }, + { localizableW, ARRAY_SIZE(localizableW), TK_LOCALIZABLE }, + { longW, ARRAY_SIZE(longW), TK_LONG }, + { longcharW, ARRAY_SIZE(longcharW), TK_LONGCHAR }, + { notW, ARRAY_SIZE(notW), TK_NOT }, + { nullW, ARRAY_SIZE(nullW), TK_NULL }, + { objectW, ARRAY_SIZE(objectW), TK_OBJECT }, + { orW, ARRAY_SIZE(orW), TK_OR }, + { orderW, ARRAY_SIZE(orderW), TK_ORDER }, + { primaryW, ARRAY_SIZE(primaryW), TK_PRIMARY }, + { selectW, ARRAY_SIZE(selectW), TK_SELECT }, + { setW, ARRAY_SIZE(setW), TK_SET }, + { shortW, ARRAY_SIZE(shortW), TK_SHORT }, + { tableW, ARRAY_SIZE(tableW), TK_TABLE }, + { temporaryW, ARRAY_SIZE(temporaryW), TK_TEMPORARY }, + { updateW, ARRAY_SIZE(updateW), TK_UPDATE }, + { valuesW, ARRAY_SIZE(valuesW), TK_VALUES }, + { whereW, ARRAY_SIZE(whereW), TK_WHERE }, }; -#define KEYWORD_COUNT ( sizeof aKeywordTable/sizeof (Keyword) ) - /* ** Comparison function for binary search. */ static int compKeyword(const void *m1, const void *m2){ const Keyword *k1 = m1, *k2 = m2; + int ret, len = min( k1->len, k2->len ); - return strcmpiW( k1->zName, k2->zName ); + if ((ret = memicmpW( k1->name, k2->name, len ))) return ret; + if (k1->len < k2->len) return -1; + else if (k1->len > k2->len) return 1; + return 0; } /* @@ -137,17 +142,15 @@ static int compKeyword(const void *m1, const void *m2){ ** returned. If the input is not a keyword, TK_ID is returned. */ static int sqliteKeywordCode(const WCHAR *z, int n){ - WCHAR str[MAX_TOKEN_LEN+1]; Keyword key, *r; if( n>MAX_TOKEN_LEN ) return TK_ID; - memcpy( str, z, n*sizeof (WCHAR) ); - str[n] = 0; key.tokenType = 0; - key.zName = str; - r = bsearch( &key, aKeywordTable, KEYWORD_COUNT, sizeof (Keyword), compKeyword ); + key.name = z; + key.len = n; + r = bsearch( &key, aKeywordTable, ARRAY_SIZE(aKeywordTable), sizeof(Keyword), compKeyword ); if( r ) return r->tokenType; return TK_ID; diff --git a/dll/win32/msi/upgrade.c b/dll/win32/msi/upgrade.c index 94806610045..cd0ec06e6e2 100644 --- a/dll/win32/msi/upgrade.c +++ b/dll/win32/msi/upgrade.c @@ -88,7 +88,7 @@ static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, newprop[0] = 0; strcatW(newprop,productid); - r = msi_set_property( package->db, action_property, newprop ); + r = msi_set_property( package->db, action_property, newprop, -1 ); if (r == ERROR_SUCCESS && !strcmpW( action_property, szSourceDir )) msi_reset_folders( package, TRUE ); diff --git a/dll/win32/msi/where.c b/dll/win32/msi/where.c index 36c8ec83e01..1bf77889580 100644 --- a/dll/win32/msi/where.c +++ b/dll/win32/msi/where.c @@ -494,7 +494,7 @@ static UINT STRING_evaluate( MSIWHEREVIEW *wv, const UINT rows[], case EXPR_COL_NUMBER_STRING: r = expr_fetch_value(&expr->u.column, rows, &val); if (r == ERROR_SUCCESS) - *str = msi_string_lookup_id(wv->db->strings, val); + *str = msi_string_lookup(wv->db->strings, val, NULL); else *str = NULL; break; @@ -883,7 +883,7 @@ static UINT join_find_row( MSIWHEREVIEW *wv, MSIRECORD *rec, UINT *row ) UINT r, i, id, data; str = MSI_RecordGetString( rec, 1 ); - r = msi_string2idW( wv->db->strings, str, &id ); + r = msi_string2id( wv->db->strings, str, -1, &id ); if (r != ERROR_SUCCESS) return r; @@ -1253,6 +1253,8 @@ UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR tables, if (r != ERROR_SUCCESS) { ERR("can't get table dimensions\n"); + table->view->ops->delete(table->view); + msi_free(table); goto end; } diff --git a/dll/win32/msvcrt/dllmain.c b/dll/win32/msvcrt/dllmain.c index 9e904f30571..f7e972561e2 100644 --- a/dll/win32/msvcrt/dllmain.c +++ b/dll/win32/msvcrt/dllmain.c @@ -77,17 +77,11 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) /* Initialization of the WINE code */ msvcrt_init_mt_locks(); - //if(!msvcrt_init_locale()) { - // msvcrt_free_mt_locks(); - // msvcrt_free_tls_mem(); - // return FALSE; - //} //msvcrt_init_math(); msvcrt_init_io(); //msvcrt_init_console(); //msvcrt_init_args(); //msvcrt_init_signals(); - _setmbcp(_MB_CP_LOCALE); TRACE("Attach done\n"); break; @@ -110,7 +104,8 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) msvcrt_free_tls_mem(); if (!msvcrt_free_tls()) return FALSE; - //MSVCRT__free_locale(MSVCRT_locale); + if(global_locale) + MSVCRT__free_locale(global_locale); if (__winitenv && __winitenv != _wenviron) FreeEnvironment((char**)__winitenv); diff --git a/dll/win32/msvcrt/msvcrt.spec b/dll/win32/msvcrt/msvcrt.spec index 2e238c7c81a..b8451fadb4f 100644 --- a/dll/win32/msvcrt/msvcrt.spec +++ b/dll/win32/msvcrt/msvcrt.spec @@ -133,7 +133,7 @@ @ cdecl ___lc_codepage_func() # @ cdecl ___lc_collate_cp_func() @ cdecl ___lc_handle_func() -# @ cdecl ___mb_cur_max_func() MSVCRT___mb_cur_max_func +@ cdecl ___mb_cur_max_func() @ cdecl ___setlc_active_func() @ cdecl ___unguarded_readlc_active_add_func() @ extern __argc @@ -302,7 +302,7 @@ @ extern _commode @ cdecl _control87(long long) @ cdecl _controlfp(long long) -# @ cdecl _controlfp_s(ptr long long) +@ cdecl _controlfp_s(ptr long long) @ cdecl _copysign( double double ) @ varargs _cprintf(str) # stub _cprintf_l @@ -492,7 +492,7 @@ @ cdecl _isatty(long) # stub _iscntrl_l @ cdecl _isctype(long long) -# stub _isctype_l +@ cdecl _isctype_l(long long ptr) # stub _isdigit_l # stub _isgraph_l # stub _isleadbyte_l @@ -1042,7 +1042,7 @@ @ cdecl _wcstoi64(wstr ptr long) # @ cdecl _wcstoi64_l(wstr ptr long ptr) # stub _wcstol_l -# stub _wcstombs_l +@ cdecl _wcstombs_l(ptr ptr long ptr) # @ cdecl _wcstombs_s_l(ptr ptr long wstr long ptr) @ cdecl _wcstoui64(wstr ptr long) # @ cdecl _wcstoui64_l(wstr ptr long ptr) diff --git a/dll/win32/msvcrt/precomp.h b/dll/win32/msvcrt/precomp.h index 20371373b6f..7fb87800003 100644 --- a/dll/win32/msvcrt/precomp.h +++ b/dll/win32/msvcrt/precomp.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/dll/win32/msvcrt20/msvcrt20.c b/dll/win32/msvcrt20/msvcrt20.c index 841a74c7c04..e06a3902b7b 100644 --- a/dll/win32/msvcrt20/msvcrt20.c +++ b/dll/win32/msvcrt20/msvcrt20.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -93,17 +94,11 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) /* Initialization of the WINE code */ msvcrt_init_mt_locks(); - //if(!msvcrt_init_locale()) { - // msvcrt_free_mt_locks(); - // msvcrt_free_tls_mem(); - // return FALSE; - //} //msvcrt_init_math(); msvcrt_init_io(); //msvcrt_init_console(); //msvcrt_init_args(); //msvcrt_init_signals(); - _setmbcp(_MB_CP_LOCALE); TRACE("Attach done\n"); break; @@ -126,7 +121,8 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) msvcrt_free_tls_mem(); if (!msvcrt_free_tls()) return FALSE; - //MSVCRT__free_locale(MSVCRT_locale); + if(global_locale) + MSVCRT__free_locale(global_locale); if (__winitenv && __winitenv != _wenviron) FreeEnvironment((char**)__winitenv); @@ -169,4 +165,4 @@ void CDECL MSVCRT20__wgetmainargs( int *argc, WCHAR** *wargv, WCHAR** *wenvp, __wgetmainargs( argc, wargv, wenvp, expand_wildcards, &new_mode ); } -/* EOF */ \ No newline at end of file +/* EOF */ diff --git a/dll/win32/msvcrt40/msvcrt40.c b/dll/win32/msvcrt40/msvcrt40.c index 61ae6ad4e01..aa2201f52f4 100644 --- a/dll/win32/msvcrt40/msvcrt40.c +++ b/dll/win32/msvcrt40/msvcrt40.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -88,17 +89,11 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) /* Initialization of the WINE code */ msvcrt_init_mt_locks(); - //if(!msvcrt_init_locale()) { - // msvcrt_free_mt_locks(); - // msvcrt_free_tls_mem(); - // return FALSE; - //} //msvcrt_init_math(); msvcrt_init_io(); //msvcrt_init_console(); //msvcrt_init_args(); //msvcrt_init_signals(); - _setmbcp(_MB_CP_LOCALE); TRACE("Attach done\n"); break; @@ -121,7 +116,8 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) msvcrt_free_tls_mem(); if (!msvcrt_free_tls()) return FALSE; - //MSVCRT__free_locale(MSVCRT_locale); + if(global_locale) + MSVCRT__free_locale(global_locale); if (__winitenv && __winitenv != _wenviron) FreeEnvironment((char**)__winitenv); @@ -140,4 +136,4 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) return TRUE; } -/* EOF */ \ No newline at end of file +/* EOF */ diff --git a/dll/win32/shell32/control.cpp b/dll/win32/shell32/control.cpp index 8f8a688e4e9..09dcbd6a5a4 100644 --- a/dll/win32/shell32/control.cpp +++ b/dll/win32/shell32/control.cpp @@ -432,7 +432,7 @@ static void Control_DoLaunch(CPanel *pPanel, HWND hWnd, LPCWSTR pwszCmd) /* Start the applet */ TRACE("Starting applet %d\n", i); if (!pApplet->proc(pApplet->hWnd, CPL_DBLCLK, i, pApplet->info[i].lData)) - pApplet->proc(pApplet->hWnd, CPL_STARTWPARMSA, i, (LPARAM)pwszArg); + pApplet->proc(pApplet->hWnd, CPL_STARTWPARMSW, i, (LPARAM)pwszArg); } else ERR("Applet not found: %ls\n", pwszArg ? pwszArg : L"NULL"); diff --git a/dll/win32/userenv/directory.c b/dll/win32/userenv/directory.c index 52a60cb19bd..75bd23fe43a 100644 --- a/dll/win32/userenv/directory.c +++ b/dll/win32/userenv/directory.c @@ -35,301 +35,301 @@ BOOL WINAPI CopyProfileDirectoryA(LPCSTR lpSourcePath, - LPCSTR lpDestinationPath, - DWORD dwFlags) + LPCSTR lpDestinationPath, + DWORD dwFlags) { - UNICODE_STRING SrcPath; - UNICODE_STRING DstPath; - NTSTATUS Status; - BOOL bResult; + UNICODE_STRING SrcPath; + UNICODE_STRING DstPath; + NTSTATUS Status; + BOOL bResult; - Status = RtlCreateUnicodeStringFromAsciiz(&SrcPath, - (LPSTR)lpSourcePath); - if (!NT_SUCCESS(Status)) + Status = RtlCreateUnicodeStringFromAsciiz(&SrcPath, + (LPSTR)lpSourcePath); + if (!NT_SUCCESS(Status)) { - SetLastError (RtlNtStatusToDosError (Status)); - return FALSE; + SetLastError (RtlNtStatusToDosError (Status)); + return FALSE; } - Status = RtlCreateUnicodeStringFromAsciiz(&DstPath, - (LPSTR)lpDestinationPath); - if (!NT_SUCCESS(Status)) + Status = RtlCreateUnicodeStringFromAsciiz(&DstPath, + (LPSTR)lpDestinationPath); + if (!NT_SUCCESS(Status)) { - RtlFreeUnicodeString(&SrcPath); - SetLastError (RtlNtStatusToDosError (Status)); - return FALSE; + RtlFreeUnicodeString(&SrcPath); + SetLastError (RtlNtStatusToDosError (Status)); + return FALSE; } - bResult = CopyProfileDirectoryW(SrcPath.Buffer, - DstPath.Buffer, - dwFlags); + bResult = CopyProfileDirectoryW(SrcPath.Buffer, + DstPath.Buffer, + dwFlags); - RtlFreeUnicodeString(&DstPath); - RtlFreeUnicodeString(&SrcPath); + RtlFreeUnicodeString(&DstPath); + RtlFreeUnicodeString(&SrcPath); - return bResult; + return bResult; } BOOL WINAPI CopyProfileDirectoryW(LPCWSTR lpSourcePath, - LPCWSTR lpDestinationPath, - DWORD dwFlags) + LPCWSTR lpDestinationPath, + DWORD dwFlags) { - /* FIXME: dwFlags are ignored! */ - return CopyDirectory(lpDestinationPath, lpSourcePath); + /* FIXME: dwFlags are ignored! */ + return CopyDirectory(lpDestinationPath, lpSourcePath); } BOOL CopyDirectory (LPCWSTR lpDestinationPath, - LPCWSTR lpSourcePath) + LPCWSTR lpSourcePath) { - WCHAR szFileName[MAX_PATH]; - WCHAR szFullSrcName[MAX_PATH]; - WCHAR szFullDstName[MAX_PATH]; - WIN32_FIND_DATAW FindFileData; - LPWSTR lpSrcPtr; - LPWSTR lpDstPtr; - HANDLE hFind; + WCHAR szFileName[MAX_PATH]; + WCHAR szFullSrcName[MAX_PATH]; + WCHAR szFullDstName[MAX_PATH]; + WIN32_FIND_DATAW FindFileData; + LPWSTR lpSrcPtr; + LPWSTR lpDstPtr; + HANDLE hFind; - DPRINT ("CopyDirectory (%S, %S) called\n", - lpDestinationPath, lpSourcePath); + DPRINT ("CopyDirectory (%S, %S) called\n", + lpDestinationPath, lpSourcePath); - wcscpy (szFileName, lpSourcePath); - wcscat (szFileName, L"\\*.*"); + wcscpy (szFileName, lpSourcePath); + wcscat (szFileName, L"\\*.*"); - hFind = FindFirstFileW (szFileName, - &FindFileData); - if (hFind == INVALID_HANDLE_VALUE) + hFind = FindFirstFileW (szFileName, + &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) { - DPRINT1 ("Error: %lu\n", GetLastError()); - return FALSE; + DPRINT1 ("Error: %lu\n", GetLastError()); + return FALSE; } - wcscpy (szFullSrcName, lpSourcePath); - lpSrcPtr = AppendBackslash (szFullSrcName); + wcscpy (szFullSrcName, lpSourcePath); + lpSrcPtr = AppendBackslash (szFullSrcName); - wcscpy (szFullDstName, lpDestinationPath); - lpDstPtr = AppendBackslash (szFullDstName); + wcscpy (szFullDstName, lpDestinationPath); + lpDstPtr = AppendBackslash (szFullDstName); - for (;;) + for (;;) { - if (wcscmp (FindFileData.cFileName, L".") && - wcscmp (FindFileData.cFileName, L"..")) - { - wcscpy (lpSrcPtr, FindFileData.cFileName); - wcscpy (lpDstPtr, FindFileData.cFileName); + if (wcscmp (FindFileData.cFileName, L".") && + wcscmp (FindFileData.cFileName, L"..")) + { + wcscpy (lpSrcPtr, FindFileData.cFileName); + wcscpy (lpDstPtr, FindFileData.cFileName); - if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - DPRINT ("Create directory: %S\n", szFullDstName); - if (!CreateDirectoryExW (szFullSrcName, szFullDstName, NULL)) - { - if (GetLastError () != ERROR_ALREADY_EXISTS) - { - DPRINT1 ("Error: %lu\n", GetLastError()); + if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + DPRINT ("Create directory: %S\n", szFullDstName); + if (!CreateDirectoryExW (szFullSrcName, szFullDstName, NULL)) + { + if (GetLastError () != ERROR_ALREADY_EXISTS) + { + DPRINT1 ("Error: %lu\n", GetLastError()); - FindClose (hFind); - return FALSE; - } - } + FindClose (hFind); + return FALSE; + } + } - if (!CopyDirectory (szFullDstName, szFullSrcName)) - { - DPRINT1 ("Error: %lu\n", GetLastError()); + if (!CopyDirectory (szFullDstName, szFullSrcName)) + { + DPRINT1 ("Error: %lu\n", GetLastError()); - FindClose (hFind); - return FALSE; - } - } - else - { - DPRINT ("Copy file: %S -> %S\n", szFullSrcName, szFullDstName); - if (!CopyFileW (szFullSrcName, szFullDstName, FALSE)) - { - DPRINT1 ("Error: %lu\n", GetLastError()); + FindClose (hFind); + return FALSE; + } + } + else + { + DPRINT ("Copy file: %S -> %S\n", szFullSrcName, szFullDstName); + if (!CopyFileW (szFullSrcName, szFullDstName, FALSE)) + { + DPRINT1 ("Error: %lu\n", GetLastError()); - FindClose (hFind); - return FALSE; - } - } - } + FindClose (hFind); + return FALSE; + } + } + } - if (!FindNextFileW (hFind, &FindFileData)) - { - if (GetLastError () != ERROR_NO_MORE_FILES) - { - DPRINT1 ("Error: %lu\n", GetLastError()); - } + if (!FindNextFileW (hFind, &FindFileData)) + { + if (GetLastError () != ERROR_NO_MORE_FILES) + { + DPRINT1 ("Error: %lu\n", GetLastError()); + } - break; - } + break; + } } - FindClose (hFind); + FindClose (hFind); - DPRINT ("CopyDirectory() done\n"); + DPRINT ("CopyDirectory() done\n"); - return TRUE; + return TRUE; } BOOL CreateDirectoryPath (LPCWSTR lpPathName, - LPSECURITY_ATTRIBUTES lpSecurityAttributes) + LPSECURITY_ATTRIBUTES lpSecurityAttributes) { - WCHAR szPath[MAX_PATH]; - LPWSTR Ptr; - DWORD dwError; + WCHAR szPath[MAX_PATH]; + LPWSTR Ptr; + DWORD dwError; - DPRINT ("CreateDirectoryPath() called\n"); + DPRINT ("CreateDirectoryPath() called\n"); - if (lpPathName == NULL || *lpPathName == 0) - return TRUE; + if (lpPathName == NULL || *lpPathName == 0) + return TRUE; - if (CreateDirectoryW (lpPathName, - lpSecurityAttributes)) - return TRUE; + if (CreateDirectoryW (lpPathName, + lpSecurityAttributes)) + return TRUE; - dwError = GetLastError (); - if (dwError == ERROR_ALREADY_EXISTS) - return TRUE; + dwError = GetLastError (); + if (dwError == ERROR_ALREADY_EXISTS) + return TRUE; - wcscpy (szPath, lpPathName); + wcscpy (szPath, lpPathName); - if (wcslen(szPath) > 3 && szPath[1] == ':' && szPath[2] == '\\') + if (wcslen(szPath) > 3 && szPath[1] == ':' && szPath[2] == '\\') { - Ptr = &szPath[3]; + Ptr = &szPath[3]; } - else + else { - Ptr = szPath; + Ptr = szPath; } - while (Ptr != NULL) + while (Ptr != NULL) { - Ptr = wcschr (Ptr, L'\\'); - if (Ptr != NULL) - *Ptr = 0; + Ptr = wcschr (Ptr, L'\\'); + if (Ptr != NULL) + *Ptr = 0; - DPRINT ("CreateDirectory(%S)\n", szPath); - if (!CreateDirectoryW (szPath, - lpSecurityAttributes)) - { - dwError = GetLastError (); - if (dwError != ERROR_ALREADY_EXISTS) - return FALSE; - } + DPRINT ("CreateDirectory(%S)\n", szPath); + if (!CreateDirectoryW (szPath, + lpSecurityAttributes)) + { + dwError = GetLastError (); + if (dwError != ERROR_ALREADY_EXISTS) + return FALSE; + } - if (Ptr != NULL) - { - *Ptr = L'\\'; - Ptr++; - } + if (Ptr != NULL) + { + *Ptr = L'\\'; + Ptr++; + } } - DPRINT ("CreateDirectoryPath() done\n"); + DPRINT ("CreateDirectoryPath() done\n"); - return TRUE; + return TRUE; } static BOOL RecursiveRemoveDir (LPCWSTR lpPath) { - WCHAR szPath[MAX_PATH]; - WIN32_FIND_DATAW FindData; - HANDLE hFind; - BOOL bResult; + WCHAR szPath[MAX_PATH]; + WIN32_FIND_DATAW FindData; + HANDLE hFind; + BOOL bResult; - wcscpy (szPath, lpPath); - wcscat (szPath, L"\\*.*"); - DPRINT ("Search path: '%S'\n", szPath); + wcscpy (szPath, lpPath); + wcscat (szPath, L"\\*.*"); + DPRINT ("Search path: '%S'\n", szPath); - hFind = FindFirstFileW (szPath, - &FindData); - if (hFind == INVALID_HANDLE_VALUE) - return FALSE; + hFind = FindFirstFileW (szPath, + &FindData); + if (hFind == INVALID_HANDLE_VALUE) + return FALSE; - bResult = TRUE; - while (TRUE) + bResult = TRUE; + while (TRUE) { - if (wcscmp (FindData.cFileName, L".") && - wcscmp (FindData.cFileName, L"..")) - { - wcscpy (szPath, lpPath); - wcscat (szPath, L"\\"); - wcscat (szPath, FindData.cFileName); - DPRINT ("File name: '%S'\n", szPath); + if (wcscmp (FindData.cFileName, L".") && + wcscmp (FindData.cFileName, L"..")) + { + wcscpy (szPath, lpPath); + wcscat (szPath, L"\\"); + wcscat (szPath, FindData.cFileName); + DPRINT ("File name: '%S'\n", szPath); - if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - DPRINT ("Delete directory: '%S'\n", szPath); + if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + DPRINT ("Delete directory: '%S'\n", szPath); - if (!RecursiveRemoveDir (szPath)) - { - bResult = FALSE; - break; - } + if (!RecursiveRemoveDir (szPath)) + { + bResult = FALSE; + break; + } - if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) - { - SetFileAttributesW (szPath, - FindData.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY); - } + if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) + { + SetFileAttributesW (szPath, + FindData.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY); + } - if (!RemoveDirectoryW (szPath)) - { - bResult = FALSE; - break; - } - } - else - { - DPRINT ("Delete file: '%S'\n", szPath); + if (!RemoveDirectoryW (szPath)) + { + bResult = FALSE; + break; + } + } + else + { + DPRINT ("Delete file: '%S'\n", szPath); - if (FindData.dwFileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)) - { - SetFileAttributesW (szPath, - FILE_ATTRIBUTE_NORMAL); - } + if (FindData.dwFileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)) + { + SetFileAttributesW (szPath, + FILE_ATTRIBUTE_NORMAL); + } - if (!DeleteFileW (szPath)) - { - bResult = FALSE; - break; - } - } - } + if (!DeleteFileW (szPath)) + { + bResult = FALSE; + break; + } + } + } - if (!FindNextFileW (hFind, &FindData)) - { - if (GetLastError () != ERROR_NO_MORE_FILES) - { - DPRINT1 ("Error: %lu\n", GetLastError()); - bResult = FALSE; - break; - } + if (!FindNextFileW (hFind, &FindData)) + { + if (GetLastError () != ERROR_NO_MORE_FILES) + { + DPRINT1 ("Error: %lu\n", GetLastError()); + bResult = FALSE; + break; + } - break; - } + break; + } } - FindClose (hFind); + FindClose (hFind); - return bResult; + return bResult; } BOOL RemoveDirectoryPath (LPCWSTR lpPathName) { - if (!RecursiveRemoveDir (lpPathName)) - return FALSE; + if (!RecursiveRemoveDir (lpPathName)) + return FALSE; - DPRINT ("Delete directory: '%S'\n", lpPathName); - return RemoveDirectoryW (lpPathName); + DPRINT ("Delete directory: '%S'\n", lpPathName); + return RemoveDirectoryW (lpPathName); } /* EOF */ diff --git a/drivers/filesystems/cdfs/dirctl.c b/drivers/filesystems/cdfs/dirctl.c index 9174f698f65..3cb8ada2ba9 100644 --- a/drivers/filesystems/cdfs/dirctl.c +++ b/drivers/filesystems/cdfs/dirctl.c @@ -586,7 +586,15 @@ CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject, Buffer = Irp->UserBuffer; } - if (SearchPattern != NULL) + /* Allocate search pattern in case: + * -> We don't have one already in context + * -> We have been given an input pattern + * -> The pattern length is not null + * -> The pattern buffer is not null + * Otherwise, we'll fall later and allocate a match all (*) pattern + */ + if (SearchPattern != NULL && + SearchPattern->Length != 0 && SearchPattern->Buffer != NULL) { if (Ccb->DirectorySearchPattern.Buffer == NULL) { diff --git a/drivers/filesystems/fastfat/dir.c b/drivers/filesystems/fastfat/dir.c index 9195b3bb02b..9522cb1d88f 100644 --- a/drivers/filesystems/fastfat/dir.c +++ b/drivers/filesystems/fastfat/dir.c @@ -427,7 +427,15 @@ DoQuery(PVFAT_IRP_CONTEXT IrpContext) #endif FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass; - if (pSearchPattern) + /* Allocate search pattern in case: + * -> We don't have one already in context + * -> We have been given an input pattern + * -> The pattern length is not null + * -> The pattern buffer is not null + * Otherwise, we'll fall later and allocate a match all (*) pattern + */ + if (pSearchPattern && + pSearchPattern->Length != 0 && pSearchPattern->Buffer != NULL) { if (!pCcb->SearchPattern.Buffer) { @@ -606,4 +614,4 @@ VfatDirectoryControl(PVFAT_IRP_CONTEXT IrpContext) return Status; } -/* EOF */ \ No newline at end of file +/* EOF */ diff --git a/drivers/filesystems/fastfat/fcb.c b/drivers/filesystems/fastfat/fcb.c index 2b378e90116..573730cf1e2 100644 --- a/drivers/filesystems/fastfat/fcb.c +++ b/drivers/filesystems/fastfat/fcb.c @@ -147,7 +147,7 @@ vfatDestroyCCB(PVFATCCB pCcb) { if (pCcb->SearchPattern.Buffer) { - ExFreePool(pCcb->SearchPattern.Buffer); + ExFreePoolWithTag(pCcb->SearchPattern.Buffer, TAG_VFAT); } ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, pCcb); } diff --git a/drivers/hid/hidclass/fdo.c b/drivers/hid/hidclass/fdo.c index 898652692f7..18480b2d48a 100644 --- a/drivers/hid/hidclass/fdo.c +++ b/drivers/hid/hidclass/fdo.c @@ -350,26 +350,50 @@ HidClassFDO_StartDevice( // query capabilities // Status = HidClassFDO_QueryCapabilities(DeviceObject, &FDODeviceExtension->Capabilities); - ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + DPRINT1("[HIDCLASS] Failed to retrieve capabilities %x\n", Status); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } // // lets start the lower device too // IoSkipCurrentIrpStackLocation(Irp); Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp); - ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + DPRINT1("[HIDCLASS] Failed to start lower device with %x\n", Status); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } // // lets get the descriptors // Status = HidClassFDO_GetDescriptors(DeviceObject); - ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + DPRINT1("[HIDCLASS] Failed to retrieve the descriptors %x\n", Status); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } // // now get the the collection description // Status = HidP_GetCollectionDescription(FDODeviceExtension->ReportDescriptor, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength, NonPagedPool, &FDODeviceExtension->Common.DeviceDescription); - ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + DPRINT1("[HIDCLASS] Failed to retrieve the collection description %x\n", Status); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } // // complete request diff --git a/drivers/hid/hidusb/hidusb.c b/drivers/hid/hidusb/hidusb.c index a227d0911ad..7d5d2398384 100644 --- a/drivers/hid/hidusb/hidusb.c +++ b/drivers/hid/hidusb/hidusb.c @@ -651,10 +651,15 @@ HidUsb_GetReportDescriptor( { // // failed to get descriptor + // try with old hid version // - DPRINT("[HIDUSB] failed to get report descriptor with %x\n", Status); - ASSERT(FALSE); - return Status; + BufferLength = HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength; + Status = Hid_GetDescriptor(DeviceObject, URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), &Report, &BufferLength, HidDeviceExtension->HidDescriptor->DescriptorList[0].bReportType, 0, 0 /* FIXME*/); + if (!NT_SUCCESS(Status)) + { + DPRINT("[HIDUSB] failed to get report descriptor with %x\n", Status); + return Status; + } } // @@ -1168,6 +1173,13 @@ Hid_SelectConfiguration( USB_DEVICE_CLASS_HUMAN_INTERFACE, -1, -1); + if (!InterfaceDescriptor) + { + // + // bogus configuration descriptor + // + return STATUS_INVALID_PARAMETER; + } // // sanity check @@ -1291,7 +1303,7 @@ Hid_SetIdle( // // print status // - DPRINT("Status %x\n", Status); + DPRINT1("Status %x\n", Status); return Status; } @@ -1472,7 +1484,7 @@ Hid_PnpStart( // // no interface class // - DPRINT1("[HIDUSB] HID Class found\n"); + DPRINT1("[HIDUSB] HID Interface descriptor not found\n"); return STATUS_UNSUCCESSFUL; } @@ -1483,11 +1495,6 @@ Hid_PnpStart( ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE); ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR)); - // - // now set the device idle - // - Hid_SetIdle(DeviceObject); - // // move to next descriptor // @@ -1508,31 +1515,38 @@ Hid_PnpStart( // select configuration // Status = Hid_SelectConfiguration(DeviceObject); - ASSERT(Status == STATUS_SUCCESS); // // done // - DPRINT("[HIDUSB] SelectConfiguration %x\n", Status); + DPRINT1("[HIDUSB] SelectConfiguration %x\n", Status); - // - // get protocol - // - Hid_GetProtocol(DeviceObject); - return Status; + if (NT_SUCCESS(Status)) + { + // + // now set the device idle + // + Hid_SetIdle(DeviceObject); + + // + // get protocol + // + Hid_GetProtocol(DeviceObject); + return Status; + } } - - // - // FIXME parse hid descriptor - // - UNIMPLEMENTED - ASSERT(FALSE); - - // - // get protocol - // - Hid_GetProtocol(DeviceObject); - return STATUS_SUCCESS; + else + { + // + // FIXME parse hid descriptor + // select configuration + // set idle + // and get protocol + // + UNIMPLEMENTED + ASSERT(FALSE); + } + return Status; } @@ -1684,10 +1698,13 @@ HidPnp( Status = Irp->IoStatus.Status; } - // - // don't need to safely remove - // - IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE; + if (NT_SUCCESS(Status) && IoStack->Parameters.DeviceCapabilities.Capabilities != NULL) + { + // + // don't need to safely remove + // + IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE; + } // // done diff --git a/drivers/network/ndis/ndis/config.c b/drivers/network/ndis/ndis/config.c index 7b7c45cc0fc..addcd715086 100644 --- a/drivers/network/ndis/ndis/config.c +++ b/drivers/network/ndis/ndis/config.c @@ -432,7 +432,7 @@ NdisReadConfiguration( PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle; PVOID Buffer; - *ParameterValue = NULL; + //*ParameterValue = NULL; *Status = NDIS_STATUS_FAILURE; NDIS_DbgPrint(MAX_TRACE,("requested read of %wZ\n", Keyword)); diff --git a/drivers/network/ndis/ndis/misc.c b/drivers/network/ndis/ndis/misc.c index fda3c4bb4b1..be40c875e05 100644 --- a/drivers/network/ndis/ndis/misc.c +++ b/drivers/network/ndis/ndis/misc.c @@ -273,7 +273,7 @@ NdisOpenFile( InitializeObjectAttributes ( &ObjectAttributes, &FullFileName, - OBJ_CASE_INSENSITIVE, + OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL, NULL ); @@ -285,14 +285,14 @@ NdisOpenFile( NULL, // PLARGE_INTEGER AllocationSize 0, // ULONG FileAttributes FILE_SHARE_READ, // ULONG ShareAccess - FILE_CREATE, // ULONG CreateDisposition + FILE_OPEN, // ULONG CreateDisposition FILE_SYNCHRONOUS_IO_NONALERT, // ULONG CreateOptions 0, // PVOID EaBuffer 0 ); // ULONG EaLength if ( !NT_SUCCESS(*Status) ) { - NDIS_DbgPrint(MIN_TRACE, ("ZwCreateFile failed (%x)\n", *Status)); + NDIS_DbgPrint(MIN_TRACE, ("ZwCreateFile failed (%x) Name %wZ\n", *Status, FileName)); *Status = NDIS_STATUS_FAILURE; } diff --git a/drivers/usb/usbccgp/descriptor.c b/drivers/usb/usbccgp/descriptor.c index 5841dd31d92..fecb5f3b48e 100644 --- a/drivers/usb/usbccgp/descriptor.c +++ b/drivers/usb/usbccgp/descriptor.c @@ -268,6 +268,41 @@ AllocateInterfaceDescriptorsArray( return STATUS_SUCCESS; } +VOID +DumpFullConfigurationDescriptor( + IN PFDO_DEVICE_EXTENSION FDODeviceExtension, + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) +{ + PUSB_COMMON_DESCRIPTOR Descriptor; + + Descriptor = (PUSB_COMMON_DESCRIPTOR)ConfigurationDescriptor; + + DbgPrint("Bogus ConfigurationDescriptor Found\n"); + DbgPrint("InterfaceCount %x\n", ConfigurationDescriptor->bNumInterfaces); + + do + { + if (((ULONG_PTR)Descriptor) >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength)) + break; + + DbgPrint("Descriptor Type %x Length %lu Offset %lu\n", Descriptor->bDescriptorType, Descriptor->bLength, ((ULONG_PTR)Descriptor - (ULONG_PTR)ConfigurationDescriptor)); + + // check for invalid descriptors + if (!Descriptor->bLength) + { + DbgPrint("Bogus Descriptor!!!\n"); + break; + } + + // advance to next descriptor + Descriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)Descriptor + Descriptor->bLength); + + }while(TRUE); + + +} + + NTSTATUS NTAPI USBCCGP_ScanConfigurationDescriptor( @@ -309,7 +344,6 @@ USBCCGP_ScanConfigurationDescriptor( // parse configuration descriptor // InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, InterfaceIndex, -1, -1, -1, -1); - ASSERT(InterfaceDescriptor); if (InterfaceDescriptor) { // @@ -319,6 +353,18 @@ USBCCGP_ScanConfigurationDescriptor( FDODeviceExtension->InterfaceListCount++; CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); } + else + { + DumpConfigurationDescriptor(ConfigurationDescriptor); + DumpFullConfigurationDescriptor(FDODeviceExtension, ConfigurationDescriptor); + + // + // see issue + // CORE-6574 Test 3 (USB Web Cam) + // + if (FDODeviceExtension->DeviceDescriptor && FDODeviceExtension->DeviceDescriptor->idVendor == 0x0458 && FDODeviceExtension->DeviceDescriptor->idProduct == 0x705f) + ASSERT(FALSE); + } // // move to next interface @@ -341,15 +387,15 @@ USBCCGP_ScanConfigurationDescriptor( VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) { - DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor); - DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength); - DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType); - DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength); - DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces); - DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue); - DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration); - DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes); - DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower); + DbgPrint("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor); + DbgPrint("bLength %x\n", ConfigurationDescriptor->bLength); + DbgPrint("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType); + DbgPrint("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength); + DbgPrint("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces); + DbgPrint("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue); + DbgPrint("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration); + DbgPrint("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes); + DbgPrint("MaxPower %x\n", ConfigurationDescriptor->MaxPower); } NTSTATUS diff --git a/drivers/usb/usbccgp/usbccgp.h b/drivers/usb/usbccgp/usbccgp.h index 46e41ae14ea..385cbaecf85 100644 --- a/drivers/usb/usbccgp/usbccgp.h +++ b/drivers/usb/usbccgp/usbccgp.h @@ -62,6 +62,11 @@ typedef struct PFDO_DEVICE_EXTENSION FDODeviceExtension; // pointer to fdo's pdo list }PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION; +/* descriptor.c */ + +VOID +DumpConfigurationDescriptor( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor); NTSTATUS USBCCGP_GetDescriptors( diff --git a/drivers/usb/usbd/usbd.spec b/drivers/usb/usbd/usbd.spec index 229b91504d2..27f82d2a2c5 100644 --- a/drivers/usb/usbd/usbd.spec +++ b/drivers/usb/usbd/usbd.spec @@ -2,10 +2,12 @@ @ stdcall USBD_Debug_RetHeap(ptr long long) @ stdcall USBD_Debug_LogEntry(ptr ptr ptr ptr) @ stdcall USBD_CalculateUsbBandwidth(long long long) +@ stdcall _USBD_CreateConfigurationRequestEx@8(ptr ptr) USBD_CreateConfigurationRequestEx @ stdcall USBD_CreateConfigurationRequestEx(ptr ptr) @ stdcall USBD_CreateConfigurationRequest(ptr ptr) @ stdcall USBD_GetInterfaceLength(ptr ptr) @ stdcall USBD_ParseConfigurationDescriptor(ptr long long) +@ stdcall _USBD_ParseConfigurationDescriptorEx@28(ptr ptr long long long long long) USBD_ParseConfigurationDescriptorEx @ stdcall USBD_ParseConfigurationDescriptorEx(ptr ptr long long long long long) @ stdcall USBD_ParseDescriptors(ptr long ptr long) @ stdcall USBD_GetPdoRegistryParameter(ptr ptr long ptr long) diff --git a/drivers/usb/usbhub/fdo.c b/drivers/usb/usbhub/fdo.c index ff56169ebdd..0342b13bc17 100644 --- a/drivers/usb/usbhub/fdo.c +++ b/drivers/usb/usbhub/fdo.c @@ -1022,54 +1022,49 @@ CreateDeviceIds( 0, (PVOID*)&SerialBuffer, &UsbChildExtension->usInstanceId.Length); - if (!NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { - DPRINT1("USBHUB: GetUsbStringDescriptor failed with status %x\n", Status); + // construct instance id buffer + Index = swprintf(Buffer, L"%04d&%s", HubDeviceExtension->InstanceCount, SerialBuffer) + 1; + UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR)); + if (UsbChildExtension->usInstanceId.Buffer == NULL) + { + DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR)); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // copy instance id + // + RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR)); + UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR); + ExFreePool(SerialBuffer); + + DPRINT("Usb InstanceId %wZ InstanceCount %x\n", &UsbChildExtension->usInstanceId, HubDeviceExtension->InstanceCount); return Status; } - - // construct instance id buffer - Index = swprintf(Buffer, L"%04d&%s", HubDeviceExtension->InstanceCount, SerialBuffer) + 1; - UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR)); - if (UsbChildExtension->usInstanceId.Buffer == NULL) - { - DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR)); - Status = STATUS_INSUFFICIENT_RESOURCES; - return Status; - } - - // - // copy instance id - // - RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR)); - UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR); - ExFreePool(SerialBuffer); - - DPRINT("Usb InstanceId %wZ InstanceCount %x\n", &UsbChildExtension->usInstanceId, HubDeviceExtension->InstanceCount); } - else + + // + // the device did not provide a serial number, or failed to retrieve the serial number + // lets create a pseudo instance id + // + Index = swprintf(Buffer, L"%04d&%04d", HubDeviceExtension->InstanceCount, UsbChildExtension->PortNumber) + 1; + UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR)); + if (UsbChildExtension->usInstanceId.Buffer == NULL) { - // - // the device did not provide a serial number, lets create a pseudo instance id - // - Index = swprintf(Buffer, L"%04d&%04d", HubDeviceExtension->InstanceCount, UsbChildExtension->PortNumber) + 1; - UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR)); - if (UsbChildExtension->usInstanceId.Buffer == NULL) - { - DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR)); - Status = STATUS_INSUFFICIENT_RESOURCES; - return Status; - } - - // - // copy instance id - // - RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR)); - UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR); - - DPRINT("usDeviceId %wZ\n", &UsbChildExtension->usInstanceId); + DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR)); + Status = STATUS_INSUFFICIENT_RESOURCES; + return Status; } + // + // copy instance id + // + RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR)); + UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR); + + DPRINT("usDeviceId %wZ\n", &UsbChildExtension->usInstanceId); return STATUS_SUCCESS; } diff --git a/drivers/usb/usbuhci/usb_request.cpp b/drivers/usb/usbuhci/usb_request.cpp index 685d09c7dbe..0b4a074c7fd 100644 --- a/drivers/usb/usbuhci/usb_request.cpp +++ b/drivers/usb/usbuhci/usb_request.cpp @@ -1020,6 +1020,9 @@ CUSBRequest::BuildBulkInterruptTransferDescriptor( { // get buffer base m_Base = MmGetMdlVirtualAddress(m_TransferBufferMDL); + + // sanity check + ASSERT(m_Base != NULL); } // get new buffer offset diff --git a/include/crt/crtdefs.h b/include/crt/crtdefs.h index 03bbb9be4e4..76cc426c26f 100644 --- a/include/crt/crtdefs.h +++ b/include/crt/crtdefs.h @@ -343,6 +343,14 @@ extern "C" { #endif #endif +/* For wine code... */ +#if !defined(_MSVCRT_LONG_DEFINED) && defined(__ROS_LONG64__) +#define _MSVCRT_LONG_DEFINED +/* we need 32-bit longs even on 64-bit */ +typedef int __msvcrt_long; +typedef unsigned int __msvcrt_ulong; +#endif + #ifndef _TIME_T_DEFINED #define _TIME_T_DEFINED #ifdef _USE_32BIT_TIME_T diff --git a/include/crt/float.h b/include/crt/float.h index a542686948c..d80ae0ec295 100644 --- a/include/crt/float.h +++ b/include/crt/float.h @@ -41,6 +41,7 @@ #define _MCW_IC 0x00040000 /* Infinity */ #define _MCW_RC 0x00000300 /* Rounding */ #define _MCW_PC 0x00030000 /* Precision */ +#define _MCW_DN 0x03000000 /* Denormal */ /* Control word values for unNew (use with related unMask above) */ #define _EM_INVALID 0x00000010 diff --git a/include/psdk/shellapi.h b/include/psdk/shellapi.h index a9b4f2f32ae..8b269d08f94 100644 --- a/include/psdk/shellapi.h +++ b/include/psdk/shellapi.h @@ -391,6 +391,18 @@ HRESULT WINAPI SHEmptyRecycleBinA(HWND,LPCSTR,DWORD); HRESULT WINAPI SHEmptyRecycleBinW(HWND,LPCWSTR,DWORD); BOOL WINAPI SHCreateProcessAsUserW(PSHCREATEPROCESSINFOW); +DWORD +WINAPI +DoEnvironmentSubstA( + _Inout_updates_(cchSrc) LPSTR pszSrc, + UINT cchSrc); + +DWORD +WINAPI +DoEnvironmentSubstW( + _Inout_updates_(cchSrc) LPWSTR pszSrc, + UINT cchSrc); + #ifdef UNICODE #define NOTIFYICONDATA_V1_SIZE NOTIFYICONDATAW_V1_SIZE #define NOTIFYICONDATA_V2_SIZE NOTIFYICONDATAW_V2_SIZE @@ -417,6 +429,7 @@ typedef LPSHNAMEMAPPINGW LPSHNAMEMAPPING; #define SHQueryRecycleBin SHQueryRecycleBinW #define SHEmptyRecycleBin SHEmptyRecycleBinW #define SHGetNewLinkInfo SHGetNewLinkInfoW +#define DoEnvironmentSubst DoEnvironmentSubstW #else #define NOTIFYICONDATA_V1_SIZE NOTIFYICONDATAA_V1_SIZE @@ -444,6 +457,7 @@ typedef LPSHNAMEMAPPINGA LPSHNAMEMAPPING; #define SHQueryRecycleBin SHQueryRecycleBinA #define SHEmptyRecycleBin SHEmptyRecycleBinA #define SHGetNewLinkInfo SHGetNewLinkInfoA +#define DoEnvironmentSubst DoEnvironmentSubstA #endif #if !defined(_WIN64) diff --git a/include/psdk/shlguid.h b/include/psdk/shlguid.h index f81f604eee5..ccc6a532e93 100644 --- a/include/psdk/shlguid.h +++ b/include/psdk/shlguid.h @@ -19,63 +19,74 @@ #ifndef __WINE_SHLGUID_H #define __WINE_SHLGUID_H -DEFINE_OLEGUID(CLSID_ShellDesktop, 0x00021400L, 0, 0); +DEFINE_OLEGUID(CLSID_ShellDesktop, 0x00021400, 0, 0); -DEFINE_OLEGUID(CATID_BrowsableShellExt, 0x00021490L, 0, 0); -DEFINE_OLEGUID(CATID_BrowseInPlace, 0x00021491L, 0, 0); -DEFINE_OLEGUID(CATID_DeskBand, 0x00021492L, 0, 0); -DEFINE_OLEGUID(CATID_InfoBand, 0x00021493L, 0, 0); -DEFINE_OLEGUID(CATID_CommBand, 0x00021494L, 0, 0); +DEFINE_OLEGUID(CATID_BrowsableShellExt, 0x00021490, 0, 0); +DEFINE_OLEGUID(CATID_BrowseInPlace, 0x00021491, 0, 0); +DEFINE_OLEGUID(CATID_DeskBand, 0x00021492, 0, 0); +DEFINE_OLEGUID(CATID_InfoBand, 0x00021493, 0, 0); +DEFINE_OLEGUID(CATID_CommBand, 0x00021494, 0, 0); /* shell32 formatids */ -DEFINE_OLEGUID(FMTID_Intshcut, 0x000214A0L, 0, 0); -DEFINE_OLEGUID(FMTID_InternetSite, 0x000214A1L, 0, 0); +DEFINE_OLEGUID(FMTID_Intshcut, 0x000214A0, 0, 0); +DEFINE_OLEGUID(FMTID_InternetSite, 0x000214A1, 0, 0); /* command group ids */ -DEFINE_OLEGUID(CGID_Explorer, 0x000214D0L, 0, 0); -DEFINE_OLEGUID(CGID_ShellDocView, 0x000214D1L, 0, 0); -DEFINE_OLEGUID(CGID_ShellServiceObject, 0x000214D2L, 0, 0); -DEFINE_OLEGUID(CGID_ExplorerBarDoc, 0x000214D3L, 0, 0); +DEFINE_OLEGUID(CGID_Explorer, 0x000214D0, 0, 0); +DEFINE_OLEGUID(CGID_ShellDocView, 0x000214D1, 0, 0); +DEFINE_OLEGUID(CGID_ShellServiceObject, 0x000214D2, 0, 0); +DEFINE_OLEGUID(CGID_ExplorerBarDoc, 0x000214D3, 0, 0); /*DEFINE_OLEGUID(IID_IShellIcon, 0x000214E5L, 0, 0);*/ -DEFINE_OLEGUID(IID_IShellDetails, 0x000214ECL, 0, 0); -DEFINE_OLEGUID(IID_IDelayedRelease, 0x000214EDL, 0, 0); -DEFINE_OLEGUID(IID_IShellCopyHookA, 0x000214EFL, 0, 0); -DEFINE_OLEGUID(IID_IFileViewerA, 0x000214F0L, 0, 0); -DEFINE_OLEGUID(IID_IFileViewerSite, 0x000214F3L, 0, 0); -DEFINE_OLEGUID(IID_IPropSheetPage, 0x000214F6L, 0, 0); -DEFINE_OLEGUID(IID_IFileViewerW, 0x000214F8L, 0, 0); -DEFINE_OLEGUID(IID_IShellCopyHookW, 0x000214FCL, 0, 0); -DEFINE_OLEGUID(IID_IRemoteComputer, 0x000214FEL, 0, 0); -DEFINE_OLEGUID(IID_IQueryInfo, 0x00021500L, 0, 0); - -DEFINE_GUID(IID_IACList, 0x77A130B0L,0x94FD,0x11D0,0xA5,0x44,0x00,0xC0,0x4F,0xD7,0xD0,0x62); -DEFINE_GUID(IID_IACList2, 0x470141A0L,0x5186,0x11D2,0xBB,0xB6,0x00,0x60,0x97,0x7B,0x46,0x4C); -DEFINE_GUID(IID_IObjMgr, 0x00BB2761L,0x6A77,0x11D0,0xA5,0x35,0x00,0xC0,0x4F,0xD7,0xD0,0x62); - -DEFINE_GUID(IID_IProgressDialog, 0xEBBC7C04,0x315E,0x11D2,0xB6,0x2F,0x00,0x60,0x97,0xDF,0x5B,0xD4); +DEFINE_OLEGUID(IID_IShellDetails, 0x000214EC, 0, 0); +DEFINE_OLEGUID(IID_IDelayedRelease, 0x000214ED, 0, 0); +DEFINE_OLEGUID(IID_IShellCopyHookA, 0x000214EF, 0, 0); +DEFINE_OLEGUID(IID_IFileViewerA, 0x000214F0, 0, 0); +DEFINE_OLEGUID(IID_IFileViewerSite, 0x000214F3, 0, 0); +DEFINE_OLEGUID(IID_IPropSheetPage, 0x000214F6, 0, 0); +DEFINE_OLEGUID(IID_IFileViewerW, 0x000214F8, 0, 0); +DEFINE_OLEGUID(IID_IShellCopyHookW, 0x000214FC, 0, 0); +DEFINE_OLEGUID(IID_IRemoteComputer, 0x000214FE, 0, 0); +DEFINE_OLEGUID(IID_IQueryInfo, 0x00021500, 0, 0); /* avoid duplicate definitions with shobjidl.h (FIXME) */ /* DEFINE_GUID(IID_IDockingWindow, 0x012dd920L, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); */ -/* DEFINE_OLEGUID(IID_IShellPropSheetExt, 0x000214E9L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IExtractIconA, 0x000214EBL, 0, 0); */ -/* DEFINE_OLEGUID(IID_IExtractIconW, 0x000214FAL, 0, 0); */ -/* DEFINE_OLEGUID(IID_IContextMenu, 0x000214E4L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IContextMenu2, 0x000214F4L, 0, 0); */ -/* DEFINE_OLEGUID(IID_ICommDlgBrowser, 0x000214F1L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IShellBrowser, 0x000214E2L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IShellView, 0x000214E3L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IShellFolder, 0x000214E6L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IShellExtInit, 0x000214E8L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IPersistFolder, 0x000214EAL, 0, 0); */ -/* DEFINE_OLEGUID(IID_IShellLinkA, 0x000214EEL, 0, 0); */ -/* DEFINE_OLEGUID(IID_IEnumIDList, 0x000214F2L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IShellLinkW, 0x000214F9L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IShellExecuteHookA, 0x000214F5L, 0, 0); */ -/* DEFINE_OLEGUID(IID_IShellExecuteHookW, 0x000214FBL, 0, 0); */ -/* DEFINE_OLEGUID(IID_INewShortcutHookA, 0x000214E1L, 0, 0); */ -/* DEFINE_OLEGUID(IID_INewShortcutHookW, 0x000214F7L, 0, 0); */ +/* DEFINE_OLEGUID(IID_IShellPropSheetExt, 0x000214E9, 0, 0); */ +/* DEFINE_OLEGUID(IID_IExtractIconA, 0x000214EB, 0, 0); */ +/* DEFINE_OLEGUID(IID_IExtractIconW, 0x000214FA, 0, 0); */ +/* DEFINE_OLEGUID(IID_IContextMenu, 0x000214E4, 0, 0); */ +/* DEFINE_OLEGUID(IID_IContextMenu2, 0x000214F4, 0, 0); */ +/* DEFINE_OLEGUID(IID_ICommDlgBrowser, 0x000214F1, 0, 0); */ +/* DEFINE_OLEGUID(IID_IShellBrowser, 0x000214E2, 0, 0); */ +/* DEFINE_OLEGUID(IID_IShellView, 0x000214E3, 0, 0); */ +/* DEFINE_OLEGUID(IID_IShellFolder, 0x000214E6, 0, 0); */ +/* DEFINE_OLEGUID(IID_IShellExtInit, 0x000214E8, 0, 0); */ +/* DEFINE_OLEGUID(IID_IPersistFolder, 0x000214EA, 0, 0); */ +/* DEFINE_OLEGUID(IID_IShellLinkA, 0x000214EE, 0, 0); */ +/* DEFINE_OLEGUID(IID_IEnumIDList, 0x000214F2, 0, 0); */ +/* DEFINE_OLEGUID(IID_IShellLinkW, 0x000214F9, 0, 0); */ +/* DEFINE_OLEGUID(IID_IShellExecuteHookA, 0x000214F5, 0, 0); */ +/* DEFINE_OLEGUID(IID_IShellExecuteHookW, 0x000214FB, 0, 0); */ +/* DEFINE_OLEGUID(IID_INewShortcutHookA, 0x000214E1, 0, 0); */ +/* DEFINE_OLEGUID(IID_INewShortcutHookW, 0x000214F7, 0, 0); */ + +#ifndef NO_INTSHCUT_GUIDS +#include +#endif + +#ifndef NO_SHDOCVW_GUIDS +# ifndef GUID_DEFS_ONLY +# include +# include +# endif + +DEFINE_GUID(IID_IACList, 0x77A130B0,0x94FD,0x11D0,0xA5,0x44,0x00,0xC0,0x4F,0xD7,0xD0,0x62); +DEFINE_GUID(IID_IACList2, 0x470141A0,0x5186,0x11D2,0xBB,0xB6,0x00,0x60,0x97,0x7B,0x46,0x4C); +DEFINE_GUID(IID_IObjMgr, 0x00BB2761,0x6A77,0x11D0,0xA5,0x35,0x00,0xC0,0x4F,0xD7,0xD0,0x62); + +DEFINE_GUID(IID_IProgressDialog, 0xEBBC7C04,0x315E,0x11D2,0xB6,0x2F,0x00,0x60,0x97,0xDF,0x5B,0xD4); +#define SID_SProgressUI CLSID_ProgressDialog DEFINE_GUID(CLSID_CUrlHistory, 0x3c374a40, 0xbae4, 0x11cf, 0xbf, 0x7d, 0x00, 0xaa, 0x00, 0x69, 0x46, 0xee); #define SID_SUrlHistory CLSID_CUrlHistory @@ -83,16 +94,23 @@ DEFINE_GUID(CLSID_CUrlHistory, 0x3c374a40, 0xbae4, 0x11cf, 0xbf, 0x7d, 0x00, 0xa DEFINE_GUID(CLSID_CURLSearchHook, 0xcfbfae00, 0x17a6, 0x11d0, 0x99, 0xcb, 0x00, 0xc0, 0x4f, 0xd6, 0x44, 0x97); DEFINE_GUID(SID_STopLevelBrowser, 0x4C96BE40, 0x915C, 0x11CF, 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37); + +DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); +DEFINE_GUID(CLSID_ACLMulti, 0x00bb2765, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); +DEFINE_GUID(CLSID_ACListISF, 0x03c036f1, 0xa186, 0x11d0, 0x82, 0x4a, 0x00, 0xaa, 0x00, 0x5b, 0x043, 0x83); + +#define SID_SInternetExplorer IID_IWebBrowserApp +#define SID_SWebBrowserApp IID_IWebBrowserApp +#define SID_SWebBrowserEventsService IID_IWebBrowserEventsService + +#endif /* NO_SHDOCVW_GUIDS */ + DEFINE_GUID(SID_STopWindow, 0x49e1b500, 0x4636, 0x11d3, 0x97, 0xf7, 0x00, 0xc0, 0x4f, 0x45, 0xd0, 0xb3); DEFINE_GUID(SID_SCommDlgBrowser, 0x80f30233, 0xb7df, 0x11d2, 0xa3, 0x3b, 0x00, 0x60, 0x97, 0xdf, 0x5b, 0xd4); #define SID_LinkSite IID_IShellLinkW #define SID_SShellBrowser IID_IShellBrowser #define SID_SShellDesktop CLSID_ShellDesktop -#define SID_SInternetExplorer IID_IWebBrowserApp -#define SID_SWebBrowserApp IID_IWebBrowserApp -#define SID_SWebBrowserEventsService IID_IWebBrowserEventsService - #define IID_IFileViewer WINELIB_NAME_AW(IID_IFileViewer) #define IID_IShellLink WINELIB_NAME_AW(IID_IShellLink) #define IID_IExtractIcon WINELIB_NAME_AW(IID_IExtractIcon) @@ -100,9 +118,9 @@ DEFINE_GUID(SID_SCommDlgBrowser, 0x80f30233, 0xb7df, 0x11d2, 0xa3, 0x3b, 0x00, #define IID_IShellExecuteHook WINELIB_NAME_AW(IID_IShellExecuteHook) #define IID_INewShortcutHook WINELIB_NAME_AW(IID_INewShortcutHook) -DEFINE_GUID(IID_IDockingWindowSite, 0x2A342FC2L, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); -DEFINE_GUID(IID_IInputObject, 0x068284FAA, 0x6A48, 0x11D0, 0x8C, 0x78, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xB4); -DEFINE_GUID(IID_IInputObjectSite, 0x0F1DB8392, 0x7331, 0x11D0, 0x8C, 0x99, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); +DEFINE_GUID(IID_IDockingWindowSite, 0x2A342FC2, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); +DEFINE_GUID(IID_IInputObject, 0x68284FAA, 0x6A48, 0x11D0, 0x8C, 0x78, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xB4); +DEFINE_GUID(IID_IInputObjectSite, 0xF1DB8392, 0x7331, 0x11D0, 0x8C, 0x99, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); /**************************************************************************** * the next IID's are the namespace elements of the pidls @@ -126,12 +144,10 @@ DEFINE_GUID(CLSID_QueryAssociations, 0xa07034fd, 0x6caa, 0x4954, 0xac, 0x3f, 0x9 DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x00, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); -DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); -DEFINE_GUID(CLSID_ACLMulti, 0x00bb2765, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); -DEFINE_GUID(CLSID_ACListISF, 0x03c036f1, 0xa186, 0x11d0, 0x82, 0x4a, 0x00, 0xaa, 0x00, 0x5b, 0x043, 0x83); - DEFINE_GUID(CLSID_ProgressDialog, 0xf8383852, 0xfcd3, 0x11d1, 0xa6, 0xb9, 0x0, 0x60, 0x97, 0xdf, 0x5b, 0xd4); +DEFINE_GUID(CLSID_ShellItem, 0x2fe352ea, 0xfd1f, 0x11d2, 0xb1, 0xf4, 0x00, 0xc0, 0x4f, 0x8e, 0xeb, 0x3e); + #define PSGUID_SHELLDETAILS {0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0} DEFINE_GUID(FMTID_ShellDetails, 0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); #define PID_FINDDATA 0 @@ -162,6 +178,39 @@ DEFINE_GUID(VID_Thumbnails, 0x8bebb290, 0x52d0, 0x11d0, 0xb7, 0xf4, 0x00, 0xc0, DEFINE_GUID(VID_Tile, 0x65f125e5, 0x7be1, 0x4810, 0xba, 0x9d, 0xd2, 0x71, 0xc8, 0x43, 0x2c, 0xe3); DEFINE_GUID(VID_ThumbStrip, 0x8eefa624, 0xd1e9, 0x445b, 0x94, 0xb7, 0x74, 0xfb, 0xce, 0x2e, 0xa1, 0x1a); +#include + +/* FOLDERTYPEID */ +DEFINE_GUID(FOLDERTYPEID_Communications, 0x91475fe5, 0x586b, 0x4eba, 0x8d, 0x75, 0xd1, 0x74, 0x34, 0xb8, 0xcd, 0xf6); +DEFINE_GUID(FOLDERTYPEID_CompressedFolder, 0x80213e82, 0xbcfd, 0x4c4f, 0x88, 0x17, 0xbb, 0x27, 0x60, 0x12, 0x67, 0xa9); +DEFINE_GUID(FOLDERTYPEID_Contacts, 0xde2b70ec, 0x9bf7, 0x4a93, 0xbd, 0x3d, 0x24, 0x3f, 0x78, 0x81, 0xd4, 0x92); +DEFINE_GUID(FOLDERTYPEID_ControlPanelCategory, 0xde4f0660, 0xfa10, 0x4b8f, 0xa4, 0x94, 0x06, 0x8b, 0x20, 0xb2, 0x23, 0x07); +DEFINE_GUID(FOLDERTYPEID_ControlPanelClassic, 0x0c3794f3, 0xb545, 0x43aa, 0xa3, 0x29, 0xc3, 0x74, 0x30, 0xc5, 0x8d, 0x2a); +DEFINE_GUID(FOLDERTYPEID_Documents, 0x7d49d726, 0x3c21, 0x4f05, 0x99, 0xaa, 0xfd, 0xc2, 0xc9, 0x47, 0x46, 0x56); +DEFINE_GUID(FOLDERTYPEID_Games, 0xb689b0d0, 0x76d3, 0x4cbb, 0x87, 0xf7, 0x58, 0x5d, 0x0e, 0x0c, 0xe0, 0x70); +DEFINE_GUID(FOLDERTYPEID_Generic, 0x5c4f28b5, 0xf869, 0x4e84, 0x8e, 0x60, 0xf1, 0x1d, 0xb9, 0x7c, 0x5c, 0xc7); +DEFINE_GUID(FOLDERTYPEID_GenericLibrary, 0x5f4eab9a, 0x6833, 0x4f61, 0x89, 0x9d, 0x31, 0xcf, 0x46, 0x97, 0x9d, 0x49); +DEFINE_GUID(FOLDERTYPEID_GenericSearchResults, 0x7fde1a1e, 0x8b31, 0x49a5, 0x93, 0xb8, 0x6b, 0xe1, 0x4c, 0xfa, 0x49, 0x43); +DEFINE_GUID(FOLDERTYPEID_Invalid, 0x57807898, 0x8c4f, 0x4462, 0xbb, 0x63, 0x71, 0x04, 0x23, 0x80, 0xb1, 0x09); +DEFINE_GUID(FOLDERTYPEID_Music, 0x94d6ddcc, 0x4a68, 0x4175, 0xa3, 0x74, 0xbd, 0x58, 0x4a, 0x51, 0x0b, 0x78); +DEFINE_GUID(FOLDERTYPEID_NetworkExplorer, 0x25cc242b, 0x9a7c, 0x4f51, 0x80, 0xe0, 0x7a, 0x29, 0x28, 0xfe, 0xbe, 0x42); +DEFINE_GUID(FOLDERTYPEID_OpenSearch, 0x8faf9629, 0x1980, 0x46ff, 0x80, 0x23, 0x9d, 0xce, 0xab, 0x9c, 0x3e, 0xe3); +DEFINE_GUID(FOLDERTYPEID_OtherUsers, 0xb337fd00, 0x9dd5, 0x4635, 0xa6, 0xd4, 0xda, 0x33, 0xfd, 0x10, 0x2b, 0x7a); +DEFINE_GUID(FOLDERTYPEID_Pictures, 0xb3690e58, 0xe961, 0x423b, 0xb6, 0x87, 0x38, 0x6e, 0xbf, 0xd8, 0x32, 0x39); +DEFINE_GUID(FOLDERTYPEID_Printers, 0x2c7bbec6, 0xc844, 0x4a0a, 0x91, 0xfa, 0xce, 0xf6, 0xf5, 0x9c, 0xfd, 0xa1); +DEFINE_GUID(FOLDERTYPEID_PublishedItems, 0x7f2f5b96, 0xff74, 0x41da, 0xaf, 0xd8, 0x1c, 0x78, 0xa5, 0xf3, 0xae, 0xa2); +DEFINE_GUID(FOLDERTYPEID_RecordedTV, 0x5557a28f, 0x5da6, 0x4f83, 0x88, 0x09, 0xc2, 0xc9, 0x8a, 0x11, 0xa6, 0xfa); +DEFINE_GUID(FOLDERTYPEID_RecycleBin, 0xd6d9e004, 0xcd87, 0x442b, 0x9d, 0x57, 0x5e, 0x0a, 0xeb, 0x4f, 0x6f, 0x72); +DEFINE_GUID(FOLDERTYPEID_SavedGames, 0xd0363307, 0x28cb, 0x4106, 0x9f, 0x23, 0x29, 0x56, 0xe3, 0xe5, 0xe0, 0xe7); +DEFINE_GUID(FOLDERTYPEID_SearchConnector, 0x982725ee, 0x6f47, 0x479e, 0xb4, 0x47, 0x81, 0x2b, 0xfa, 0x7d, 0x2e, 0x8f); +DEFINE_GUID(FOLDERTYPEID_Searches, 0x0b0ba2e3, 0x405f, 0x415e, 0xa6, 0xee, 0xca, 0xd6, 0x25, 0x20, 0x78, 0x53); +DEFINE_GUID(FOLDERTYPEID_SearchHome, 0x834d8a44, 0x0974, 0x4ed6, 0x86, 0x6e, 0xf2, 0x03, 0xd8, 0x0b, 0x38, 0x10); +DEFINE_GUID(FOLDERTYPEID_SoftwareExplorer, 0xd674391b, 0x52d9, 0x4e07, 0x83, 0x4e, 0x67, 0xc9, 0x86, 0x10, 0xf3, 0x9d); +DEFINE_GUID(FOLDERTYPEID_StartMenu, 0xef87b4cb, 0xf2ce, 0x4785, 0x86, 0x58, 0x4c, 0xa6, 0xc6, 0x3e, 0x38, 0xc6); +DEFINE_GUID(FOLDERTYPEID_UserFiles, 0xcd0fc69b, 0x71e2, 0x46e5, 0x96, 0x90, 0x5b, 0xcd, 0x9f, 0x57, 0xaa, 0xb3); +DEFINE_GUID(FOLDERTYPEID_UsersLibraries, 0xc4d98f09, 0x6124, 0x4fe0, 0x99, 0x42, 0x82, 0x64, 0x16, 0x08, 0x2d, 0xa9); +DEFINE_GUID(FOLDERTYPEID_Videos, 0x5fa96407, 0x7e77, 0x483c, 0xac, 0x93, 0x69, 0x1d, 0x05, 0x85, 0x0d, 0xe8); + /* REACTOS ONLY */ DEFINE_GUID(CLSID_NewMenu, 0xd969A300, 0xe7FF, 0x11D0, 0xA9, 0x3B, 0x0, 0xA0, 0xC9, 0x0F, 0x27, 0x19); DEFINE_GUID(IID_IShellFolderViewCB, 0x2047E320, 0xF2A9, 0x11CE, 0xAE, 0x65, 0x8, 0x00, 0x2B, 0x2E, 0x12, 0x62); diff --git a/include/psdk/winbase.h b/include/psdk/winbase.h index 76fdf406d6d..c9eed376a4a 100644 --- a/include/psdk/winbase.h +++ b/include/psdk/winbase.h @@ -908,18 +908,66 @@ typedef struct _WIN32_STREAM_ID { } WIN32_STREAM_ID, *LPWIN32_STREAM_ID; #if (_WIN32_WINNT >= 0x0600) + typedef enum _FILE_ID_TYPE { - FileIdType, - MaximumFileIdType + FileIdType, + ObjectIdType, + ExtendedFileIdType, + MaximumFileIdType } FILE_ID_TYPE, *PFILE_ID_TYPE; typedef struct _FILE_ID_DESCRIPTOR { - DWORD dwSize; - FILE_ID_TYPE Type; - _ANONYMOUS_UNION union { - LARGE_INTEGER FileID; - } DUMMYUNIONNAME; + DWORD dwSize; + FILE_ID_TYPE Type; + union { + LARGE_INTEGER FileId; + GUID ObjectId; + } DUMMYUNIONNAME; } FILE_ID_DESCRIPTOR, *LPFILE_ID_DESCRIPTOR; + +typedef enum _FILE_INFO_BY_HANDLE_CLASS { + FileBasicInfo, + FileStandardInfo, + FileNameInfo, + FileRenameInfo, + FileDispositionInfo, + FileAllocationInfo, + FileEndOfFileInfo, + FileStreamInfo, + FileCompressionInfo, + FileAttributeTagInfo, + FileIdBothDirectoryInfo, + FileIdBothDirectoryRestartInfo, + FileIoPriorityHintInfo, + FileRemoteProtocolInfo, + FileFullDirectoryInfo, + FileFullDirectoryRestartInfo, + FileStorageInfo, + FileAlignmentInfo, + FileIdInfo, + FileIdExtdDirectoryInfo, + FileIdExtdDirectoryRestartInfo, + MaximumFileInfoByHandlesClass +} FILE_INFO_BY_HANDLE_CLASS, *PFILE_INFO_BY_HANDLE_CLASS; + +typedef struct _FILE_ID_BOTH_DIR_INFO { + DWORD NextEntryOffset; + DWORD FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + DWORD FileAttributes; + DWORD FileNameLength; + DWORD EaSize; + CCHAR ShortNameLength; + WCHAR ShortName[12]; + LARGE_INTEGER FileId; + WCHAR FileName[1]; +} FILE_ID_BOTH_DIR_INFO, *PFILE_ID_BOTH_DIR_INFO; + #endif typedef enum _FINDEX_INFO_LEVELS { @@ -3567,6 +3615,21 @@ typedef ENUMRESTYPEPROCA ENUMRESTYPEPROC; #endif #endif +/* one-time initialisation API */ +typedef RTL_RUN_ONCE INIT_ONCE; +typedef PRTL_RUN_ONCE PINIT_ONCE; +typedef PRTL_RUN_ONCE LPINIT_ONCE; + +#define INIT_ONCE_CHECK_ONLY RTL_RUN_ONCE_CHECK_ONLY +#define INIT_ONCE_ASYNC RTL_RUN_ONCE_ASYNC +#define INIT_ONCE_INIT_FAILED RTL_RUN_ONCE_INIT_FAILED + +typedef BOOL +(WINAPI *PINIT_ONCE_FN)( + _Inout_ PINIT_ONCE InitOnce, + _Inout_opt_ PVOID Parameter, + _Outptr_opt_result_maybenull_ PVOID *Context); + #ifdef _MSC_VER #pragma warning(pop) #endif diff --git a/include/psdk/wincred.h b/include/psdk/wincred.h index e263644d0fd..d0a75a72bfc 100644 --- a/include/psdk/wincred.h +++ b/include/psdk/wincred.h @@ -23,6 +23,12 @@ extern "C" { #endif +#ifdef _ADVAPI32_ +#define WINADVAPI +#else +#define WINADVAPI DECLSPEC_IMPORT +#endif + #ifndef __SECHANDLE_DEFINED__ #define __SECHANDLE_DEFINED__ typedef struct _SecHandle @@ -32,8 +38,11 @@ typedef struct _SecHandle } SecHandle, *PSecHandle; #endif +#ifndef __WINE_CTXTHANDLE_DEFINED__ +#define __WINE_CTXTHANDLE_DEFINED__ typedef SecHandle CtxtHandle; typedef PSecHandle PCtxtHandle; +#endif typedef struct _CREDENTIAL_ATTRIBUTEA { @@ -89,6 +98,37 @@ typedef struct _CREDENTIALW DECL_WINELIB_TYPE_AW(CREDENTIAL) DECL_WINELIB_TYPE_AW(PCREDENTIAL) +typedef struct _CREDENTIAL_TARGET_INFORMATIONA +{ + LPSTR TargetName; + LPSTR NetbiosServerName; + LPSTR DnsServerName; + LPSTR NetbiosDomainName; + LPSTR DnsDomainName; + LPSTR DnsTreeName; + LPSTR PackageName; + DWORD Flags; + DWORD CredTypeCount; + LPDWORD CredTypes; +} CREDENTIAL_TARGET_INFORMATIONA, *PCREDENTIAL_TARGET_INFORMATIONA; + +typedef struct _CREDENTIAL_TARGET_INFORMATIONW +{ + LPWSTR TargetName; + LPWSTR NetbiosServerName; + LPWSTR DnsServerName; + LPWSTR NetbiosDomainName; + LPWSTR DnsDomainName; + LPWSTR DnsTreeName; + LPWSTR PackageName; + DWORD Flags; + DWORD CredTypeCount; + LPDWORD CredTypes; +} CREDENTIAL_TARGET_INFORMATIONW, *PCREDENTIAL_TARGET_INFORMATIONW; + +DECL_WINELIB_TYPE_AW(CREDENTIAL_TARGET_INFORMATION) +DECL_WINELIB_TYPE_AW(PCREDENTIAL_TARGET_INFORMATION) + typedef struct _CREDUI_INFOA { DWORD cbSize; @@ -107,48 +147,35 @@ typedef struct _CREDUI_INFOW HBITMAP hbmBanner; } CREDUI_INFOW, *PCREDUI_INFOW; -typedef enum _CRED_MARSHAL_TYPE { - CertCredential = 1, - UsernameTargetCredential -} CRED_MARSHAL_TYPE, *PCRED_MARSHAL_TYPE; - -typedef struct _CREDENTIAL_TARGET_INFORMATIONA { - LPSTR TargetName; - LPSTR NetbiosServerName; - LPSTR DnsServerName; - LPSTR NetbiosDomainName; - LPSTR DnsDomainName; - LPSTR DnsTreeName; - LPSTR PackageName; - ULONG Flags; - DWORD CredTypeCount; - LPDWORD CredTypes; -} CREDENTIAL_TARGET_INFORMATIONA, *PCREDENTIAL_TARGET_INFORMATIONA; - -typedef struct _CREDENTIAL_TARGET_INFORMATIONW { - LPWSTR TargetName; - LPWSTR NetbiosServerName; - LPWSTR DnsServerName; - LPWSTR NetbiosDomainName; - LPWSTR DnsDomainName; - LPWSTR DnsTreeName; - LPWSTR PackageName; - ULONG Flags; - DWORD CredTypeCount; - LPDWORD CredTypes; -} CREDENTIAL_TARGET_INFORMATIONW, *PCREDENTIAL_TARGET_INFORMATIONW; - -#ifdef UNICODE -typedef CREDENTIAL_TARGET_INFORMATIONW CREDENTIAL_TARGET_INFORMATION; -typedef PCREDENTIAL_TARGET_INFORMATIONW PCREDENTIAL_TARGET_INFORMATION; -#else -typedef CREDENTIAL_TARGET_INFORMATIONA CREDENTIAL_TARGET_INFORMATION; -typedef PCREDENTIAL_TARGET_INFORMATIONA PCREDENTIAL_TARGET_INFORMATION; -#endif /* UNICODE */ - DECL_WINELIB_TYPE_AW(CREDUI_INFO) DECL_WINELIB_TYPE_AW(PCREDUI_INFO) +typedef enum _CRED_MARSHAL_TYPE +{ + CertCredential = 1, + UsernameTargetCredential, + BinaryBlobCredential +} CRED_MARSHAL_TYPE, *PCRED_MARSHAL_TYPE; + +#define CERT_HASH_LENGTH 20 + +typedef struct _CERT_CREDENTIAL_INFO +{ + ULONG cbSize; + UCHAR rgbHashOfCert[CERT_HASH_LENGTH]; +} CERT_CREDENTIAL_INFO, *PCERT_CREDENTIAL_INFO; + +typedef struct _USERNAME_TARGET_CREDENTIAL_INFO +{ + LPWSTR UserName; +} USERNAME_TARGET_CREDENTIAL_INFO; + +typedef struct _BINARY_BLOB_CREDENTIAL_INFO +{ + ULONG cbBlob; + LPBYTE pbBlob; +} BINARY_BLOB_CREDENTIAL_INFO, *PBINARY_BLOB_CREDENTIAL_INFO; + #define CRED_MAX_STRING_LENGTH 256 #define CRED_MAX_USERNAME_LENGTH 513 #define CRED_MAX_GENERIC_TARGET_NAME_LENGTH 32767 @@ -177,7 +204,9 @@ DECL_WINELIB_TYPE_AW(PCREDUI_INFO) #define CRED_TYPE_DOMAIN_PASSWORD 2 #define CRED_TYPE_DOMAIN_CERTIFICATE 3 #define CRED_TYPE_DOMAIN_VISIBLE_PASSWORD 4 -#define CRED_TYPE_MAXIMUM 5 +#define CRED_TYPE_GENERIC_CERTIFICATE 5 +#define CRED_TYPE_MAXIMUM 6 +#define CRED_TYPE_MAXIMUM_EX (CRED_TYPE_MAXIMUM+1000) /* values for CREDENTIAL::Persist */ #define CRED_PERSIST_NONE 0 @@ -185,6 +214,11 @@ DECL_WINELIB_TYPE_AW(PCREDUI_INFO) #define CRED_PERSIST_LOCAL_MACHINE 2 #define CRED_PERSIST_ENTERPRISE 3 +/* values for CREDENTIAL_TARGET_INFORMATION::Flags */ +#define CRED_TI_SERVER_FORMAT_UNKNOWN 1 +#define CRED_TI_DOMAIN_FORMAT_UNKNOWN 2 +#define CRED_TI_ONLY_PASSWORD_REQUIRED 4 + #define CREDUI_FLAGS_INCORRECT_PASSWORD 0x00000001 #define CREDUI_FLAGS_DO_NOT_PERSIST 0x00000002 #define CREDUI_FLAGS_REQUEST_ADMINISTRATOR 0x00000004 @@ -206,22 +240,35 @@ DECL_WINELIB_TYPE_AW(PCREDUI_INFO) /* flags for CredWrite and CredWriteDomainCredentials */ #define CRED_PRESERVE_CREDENTIAL_BLOB 0x00000001 -BOOL WINAPI CredDeleteA(LPCSTR,DWORD,DWORD); -BOOL WINAPI CredDeleteW(LPCWSTR,DWORD,DWORD); -#define CredDelete WINELIB_NAME_AW(CredDelete) -BOOL WINAPI CredEnumerateA(LPCSTR,DWORD,DWORD *,PCREDENTIALA **); -BOOL WINAPI CredEnumerateW(LPCWSTR,DWORD,DWORD *,PCREDENTIALW **); -#define CredEnumerate WINELIB_NAME_AW(CredEnumerate) -VOID WINAPI CredFree(PVOID); -BOOL WINAPI CredReadA(LPCSTR,DWORD,DWORD,PCREDENTIALA *); -BOOL WINAPI CredReadW(LPCWSTR,DWORD,DWORD,PCREDENTIALW *); -#define CredRead WINELIB_NAME_AW(CredRead) -BOOL WINAPI CredRenameA(LPCSTR,LPCSTR,DWORD,DWORD); -BOOL WINAPI CredRenameW(LPCWSTR,LPCWSTR,DWORD,DWORD); -#define CredRename WINELIB_NAME_AW(CredRename) -BOOL WINAPI CredWriteA(PCREDENTIALA,DWORD); -BOOL WINAPI CredWriteW(PCREDENTIALW,DWORD); -#define CredWrite WINELIB_NAME_AW(CredWrite) +WINADVAPI BOOL WINAPI CredDeleteA(LPCSTR,DWORD,DWORD); +WINADVAPI BOOL WINAPI CredDeleteW(LPCWSTR,DWORD,DWORD); +#define CredDelete WINELIB_NAME_AW(CredDelete) +WINADVAPI BOOL WINAPI CredEnumerateA(LPCSTR,DWORD,DWORD *,PCREDENTIALA **); +WINADVAPI BOOL WINAPI CredEnumerateW(LPCWSTR,DWORD,DWORD *,PCREDENTIALW **); +#define CredEnumerate WINELIB_NAME_AW(CredEnumerate) +WINADVAPI VOID WINAPI CredFree(PVOID); +WINADVAPI BOOL WINAPI CredGetSessionTypes(DWORD,LPDWORD); +WINADVAPI BOOL WINAPI CredIsMarshaledCredentialA(LPCSTR); +WINADVAPI BOOL WINAPI CredIsMarshaledCredentialW(LPCWSTR); +#define CredIsMarshaledCredential WINELIB_NAME_AW(CredIsMarshaledCredential) +WINADVAPI BOOL WINAPI CredMarshalCredentialA(CRED_MARSHAL_TYPE,PVOID,LPSTR *); +WINADVAPI BOOL WINAPI CredMarshalCredentialW(CRED_MARSHAL_TYPE,PVOID,LPWSTR *); +#define CredMarshalCredential WINELIB_NAME_AW(CredMarshalCredential) +WINADVAPI BOOL WINAPI CredReadA(LPCSTR,DWORD,DWORD,PCREDENTIALA *); +WINADVAPI BOOL WINAPI CredReadW(LPCWSTR,DWORD,DWORD,PCREDENTIALW *); +#define CredRead WINELIB_NAME_AW(CredRead) +WINADVAPI BOOL WINAPI CredReadDomainCredentialsA(PCREDENTIAL_TARGET_INFORMATIONA,DWORD,DWORD *,PCREDENTIALA **); +WINADVAPI BOOL WINAPI CredReadDomainCredentialsW(PCREDENTIAL_TARGET_INFORMATIONW,DWORD,DWORD *,PCREDENTIALW **); +#define CredReadDomainCredentials WINELIB_NAME_AW(CredReadDomainCredentials) +WINADVAPI BOOL WINAPI CredRenameA(LPCSTR,LPCSTR,DWORD,DWORD); +WINADVAPI BOOL WINAPI CredRenameW(LPCWSTR,LPCWSTR,DWORD,DWORD); +#define CredRename WINELIB_NAME_AW(CredRename) +WINADVAPI BOOL WINAPI CredUnmarshalCredentialA(LPCSTR,PCRED_MARSHAL_TYPE,PVOID *); +WINADVAPI BOOL WINAPI CredUnmarshalCredentialW(LPCWSTR,PCRED_MARSHAL_TYPE,PVOID *); +#define CredUnmarshalCredential WINELIB_NAME_AW(CredUnmarshalCredential) +WINADVAPI BOOL WINAPI CredWriteA(PCREDENTIALA,DWORD); +WINADVAPI BOOL WINAPI CredWriteW(PCREDENTIALW,DWORD); +#define CredWrite WINELIB_NAME_AW(CredWrite) DWORD WINAPI CredUICmdLinePromptForCredentialsW(PCWSTR,PCtxtHandle,DWORD,PWSTR,ULONG,PWSTR,ULONG,PBOOL,DWORD); DWORD WINAPI CredUICmdLinePromptForCredentialsA(PCSTR,PCtxtHandle,DWORD,PSTR,ULONG,PSTR,ULONG,PBOOL,DWORD); @@ -240,23 +287,6 @@ DWORD WINAPI CredUIStoreSSOCredW(PCWSTR,PCWSTR,PCWSTR,BOOL); DWORD WINAPI CredUIReadSSOCredW(PCWSTR,PWSTR*); /* Note: no CredUIReadSSOCredA in PSDK header */ -BOOL WINAPI CredReadDomainCredentialsW(PCREDENTIAL_TARGET_INFORMATIONW TargetInfo, DWORD Flags, DWORD *Count, PCREDENTIALW **Credential); -BOOL WINAPI CredReadDomainCredentialsA(PCREDENTIAL_TARGET_INFORMATIONA TargetInfo, DWORD Flags, DWORD *Count, PCREDENTIALA **Credential); -BOOL WINAPI CredWriteDomainCredentialsW(PCREDENTIAL_TARGET_INFORMATIONW TargetInfo, PCREDENTIALW Credential, DWORD Flags); -BOOL WINAPI CredWriteDomainCredentialsA(PCREDENTIAL_TARGET_INFORMATIONA TargetInfo, PCREDENTIALA Credential, DWORD Flags); -BOOL WINAPI CredUnmarshalCredentialW(LPCWSTR MarshaledCredential, PCRED_MARSHAL_TYPE CredType, PVOID *Credential); -BOOL WINAPI CredUnmarshalCredentialA(LPCSTR MarshaledCredential, PCRED_MARSHAL_TYPE CredType, PVOID *Credential); - -#ifdef UNICODE -#define CredReadDomainCredentials CredReadDomainCredentialsW -#define CredWriteDomainCredentials CredWriteDomainCredentialsW -#define CredUnmarshalCredential CredUnmarshalCredentialW -#else -#define CredReadDomainCredentials CredReadDomainCredentialsA -#define CredWriteDomainCredentials CredWriteDomainCredentialsA -#define CredUnmarshalCredential CredUnmarshalCredentialA -#endif /* UNICODE */ - #ifdef __cplusplus } #endif diff --git a/include/psdk/winnt.h b/include/psdk/winnt.h index c7e88715482..ae16f2337b0 100644 --- a/include/psdk/winnt.h +++ b/include/psdk/winnt.h @@ -931,13 +931,108 @@ typedef enum { #define SE_MANAGE_VOLUME_NAME TEXT("SeManageVolumePrivilege") #define SE_IMPERSONATE_NAME TEXT("SeImpersonatePrivilege") #define SE_CREATE_GLOBAL_NAME TEXT("SeCreateGlobalPrivilege") -#define SE_GROUP_MANDATORY 1 -#define SE_GROUP_ENABLED_BY_DEFAULT 2 -#define SE_GROUP_ENABLED 4 -#define SE_GROUP_OWNER 8 -#define SE_GROUP_USE_FOR_DENY_ONLY 16 -#define SE_GROUP_LOGON_ID 3221225472U -#define SE_GROUP_RESOURCE 536870912 + +#define SE_GROUP_MANDATORY 0x00000001 +#define SE_GROUP_ENABLED_BY_DEFAULT 0x00000002 +#define SE_GROUP_ENABLED 0x00000004 +#define SE_GROUP_OWNER 0x00000008 +#define SE_GROUP_USE_FOR_DENY_ONLY 0x00000010 +#define SE_GROUP_INTEGRITY 0x00000020 +#define SE_GROUP_INTEGRITY_ENABLED 0x00000040 +#define SE_GROUP_LOGON_ID 0xC0000000 +#define SE_GROUP_RESOURCE 0x20000000 +#define SE_GROUP_VALID_ATTRIBUTES 0xE000007F + +/* + * Product types + */ +#define PRODUCT_UNDEFINED 0x00000000 +#define PRODUCT_ULTIMATE 0x00000001 +#define PRODUCT_HOME_BASIC 0x00000002 +#define PRODUCT_HOME_PREMIUM 0x00000003 +#define PRODUCT_ENTERPRISE 0x00000004 +#define PRODUCT_HOME_BASIC_N 0x00000005 +#define PRODUCT_BUSINESS 0x00000006 +#define PRODUCT_STANDARD_SERVER 0x00000007 +#define PRODUCT_DATACENTER_SERVER 0x00000008 +#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 +#define PRODUCT_ENTERPRISE_SERVER 0x0000000A +#define PRODUCT_STARTER 0x0000000B +#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C +#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D +#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E +#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F +#define PRODUCT_BUSINESS_N 0x00000010 +#define PRODUCT_WEB_SERVER 0x00000011 +#define PRODUCT_CLUSTER_SERVER 0x00000012 +#define PRODUCT_HOME_SERVER 0x00000013 +#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 +#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 +#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 +#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 +#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 +#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019 +#define PRODUCT_HOME_PREMIUM_N 0x0000001A +#define PRODUCT_ENTERPRISE_N 0x0000001B +#define PRODUCT_ULTIMATE_N 0x0000001C +#define PRODUCT_WEB_SERVER_CORE 0x0000001D +#define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E +#define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F +#define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020 +#define PRODUCT_SERVER_FOUNDATION 0x00000021 +#define PRODUCT_HOME_PREMIUM_SERVER 0x00000022 +#define PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023 +#define PRODUCT_STANDARD_SERVER_V 0x00000024 +#define PRODUCT_DATACENTER_SERVER_V 0x00000025 +#define PRODUCT_SERVER_V 0x00000025 +#define PRODUCT_ENTERPRISE_SERVER_V 0x00000026 +#define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027 +#define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028 +#define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029 +#define PRODUCT_HYPERV 0x0000002A +#define PRODUCT_STORAGE_EXPRESS_SERVER_CORE 0x0000002B +#define PRODUCT_STORAGE_STANDARD_SERVER_CORE 0x0000002C +#define PRODUCT_STORAGE_WORKGROUP_SERVER_CORE 0x0000002D +#define PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE 0x0000002E +#define PRODUCT_STARTER_N 0x0000002F +#define PRODUCT_PROFESSIONAL 0x00000030 +#define PRODUCT_PROFESSIONAL_N 0x00000031 +#define PRODUCT_SB_SOLUTION_SERVER 0x00000032 +#define PRODUCT_SERVER_FOR_SB_SOLUTIONS 0x00000033 +#define PRODUCT_STANDARD_SERVER_SOLUTIONS 0x00000034 +#define PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE 0x00000035 +#define PRODUCT_SB_SOLUTION_SERVER_EM 0x00000036 +#define PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM 0x00000037 +#define PRODUCT_SOLUTION_EMBEDDEDSERVER 0x00000038 +#define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT 0x0000003B +#define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL 0x0000003C +#define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC 0x0000003D +#define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC 0x0000003E +#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE 0x0000003F +#define PRODUCT_CLUSTER_SERVER_V 0x00000040 +#define PRODUCT_EMBEDDED 0x00000041 +#define PRODUCT_STARTER_E 0x00000042 +#define PRODUCT_HOME_BASIC_E 0x00000043 +#define PRODUCT_HOME_PREMIUM_E 0x00000044 +#define PRODUCT_PROFESSIONAL_E 0x00000045 +#define PRODUCT_ENTERPRISE_E 0x00000046 +#define PRODUCT_ULTIMATE_E 0x00000047 +#define PRODUCT_ENTERPRISE_EVALUATION 0x00000048 +#define PRODUCT_MULTIPOINT_STANDARD_SERVER 0x0000004C +#define PRODUCT_MULTIPOINT_PREMIUM_SERVER 0x0000004D +#define PRODUCT_STANDARD_EVALUATION_SERVER 0x0000004F +#define PRODUCT_DATACENTER_EVALUATION_SERVER 0x00000050 +#define PRODUCT_ENTERPRISE_N_EVALUATION 0x00000054 +#define PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER 0x0000005F +#define PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER 0x00000060 +#define PRODUCT_CORE_ARM 0x00000061 +#define PRODUCT_CORE_N 0x00000062 +#define PRODUCT_CORE_COUNTRYSPECIFIC 0x00000063 +#define PRODUCT_CORE_LANGUAGESPECIFIC 0x00000064 +#define PRODUCT_CORE 0x00000065 +#define PRODUCT_PROFESSIONAL_WMC 0x00000067 +#define PRODUCT_UNLICENSED 0xABCDABCD + #define LANG_NEUTRAL 0x00 #define LANG_INVARIANT 0x7f #define LANG_AFRIKAANS 0x36 @@ -1245,6 +1340,7 @@ typedef enum { #define SUBLANG_SERBIAN_CROATIA 0x01 #define SUBLANG_SERBIAN_CYRILLIC 0x03 #define SUBLANG_SERBIAN_LATIN 0x02 +#define SUBLANG_SERBIAN_SERBIA_LATIN 0x09 #define SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA 0x01 #define SUBLANG_TSWANA_SOUTH_AFRICA 0x01 #define SUBLANG_SINDHI_AFGHANISTAN 0x02 @@ -3389,6 +3485,10 @@ typedef enum _TOKEN_ELEVATION_TYPE { TokenElevationTypeLimited, } TOKEN_ELEVATION_TYPE, *PTOKEN_ELEVATION_TYPE; +typedef struct _TOKEN_MANDATORY_LABEL { + SID_AND_ATTRIBUTES Label; +} TOKEN_MANDATORY_LABEL, * PTOKEN_MANDATORY_LABEL; + #include typedef struct _TOKEN_STATISTICS { LUID TokenId; @@ -3757,6 +3857,26 @@ RtlQueryDepthSList ( IN PSLIST_HEADER ListHead ); +#ifndef _RTL_RUN_ONCE_DEF +#define _RTL_RUN_ONCE_DEF + +#define RTL_RUN_ONCE_CHECK_ONLY 0x00000001UL +#define RTL_RUN_ONCE_ASYNC 0x00000002UL +#define RTL_RUN_ONCE_INIT_FAILED 0x00000004UL + +typedef union _RTL_RUN_ONCE { + PVOID Ptr; +} RTL_RUN_ONCE, *PRTL_RUN_ONCE; + +#endif + +#define RTL_CONDITION_VARIABLE_INIT {0} +#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 0x1 + +typedef struct _RTL_CONDITION_VARIABLE { + PVOID Ptr; +} RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE; + typedef struct _RTL_CRITICAL_SECTION_DEBUG { WORD Type; WORD CreatorBackTraceIndex; @@ -3821,13 +3941,6 @@ typedef struct _RTL_SRWLOCK { PVOID Ptr; } RTL_SRWLOCK, *PRTL_SRWLOCK; -#define RTL_CONDITION_VARIABLE_INIT {0} -#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 0x1 - -typedef struct _RTL_CONDITION_VARIABLE { - PVOID Ptr; -} RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE; - typedef LONG (NTAPI *PVECTORED_EXCEPTION_HANDLER)( struct _EXCEPTION_POINTERS *ExceptionInfo diff --git a/include/psdk/winsvc.h b/include/psdk/winsvc.h index 8a66503beee..a0a82bf4354 100644 --- a/include/psdk/winsvc.h +++ b/include/psdk/winsvc.h @@ -61,8 +61,24 @@ extern "C" { #define SERVICE_USER_DEFINED_CONTROL 256 #define SERVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SERVICE_QUERY_CONFIG|SERVICE_CHANGE_CONFIG|SERVICE_QUERY_STATUS|SERVICE_ENUMERATE_DEPENDENTS|SERVICE_START|SERVICE_STOP|SERVICE_PAUSE_CONTINUE|SERVICE_INTERROGATE|SERVICE_USER_DEFINED_CONTROL) #define SERVICE_RUNS_IN_SYSTEM_PROCESS 1 -#define SERVICE_CONFIG_DESCRIPTION 1 -#define SERVICE_CONFIG_FAILURE_ACTIONS 2 + +#define SERVICE_CONFIG_DESCRIPTION 1 +#define SERVICE_CONFIG_FAILURE_ACTIONS 2 +#define SERVICE_CONFIG_DELAYED_AUTO_START_INFO 3 +#define SERVICE_CONFIG_FAILURE_ACTIONS_FLAG 4 +#define SERVICE_CONFIG_SERVICE_SID_INFO 5 +#define SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO 6 +#define SERVICE_CONFIG_PRESHUTDOWN_INFO 7 +#define SERVICE_CONFIG_TRIGGER_INFO 8 +#define SERVICE_CONFIG_PREFERRED_NODE 9 +#define SERVICE_CONFIG_RUNLEVEL_INFO 10 + +#ifndef _SERVICE_PRESHUTDOWN_INFO_DEFINED_ +#define _SERVICE_PRESHUTDOWN_INFO_DEFINED_ +typedef struct _SERVICE_PRESHUTDOWN_INFO { + DWORD dwPreshutdownTimeout; +} SERVICE_PRESHUTDOWN_INFO, *LPSERVICE_PRESHUTDOWN_INFO; +#endif typedef struct _SERVICE_STATUS { DWORD dwServiceType; diff --git a/include/psdk/winternl.h b/include/psdk/winternl.h index e1dc06af0ce..0c67c8600ad 100644 --- a/include/psdk/winternl.h +++ b/include/psdk/winternl.h @@ -755,6 +755,26 @@ typedef enum _SYSTEM_INFORMATION_CLASS { SystemVerifierInformation = 51, SystemAddVerifier = 52, SystemSessionProcessesInformation = 53, + Unknown54, + Unknown55, + Unknown56, + Unknown57, + Unknown58, + Unknown59, + Unknown60, + Unknown61, + Unknown62, + Unknown63, + Unknown64, + Unknown65, + Unknown66, + Unknown67, + Unknown68, + Unknown69, + Unknown70, + Unknown71, + Unknown72, + SystemLogicalProcessorInformation = 73, SystemInformationClassMax } SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; diff --git a/include/reactos/idl/svcctl.idl b/include/reactos/idl/svcctl.idl index a678bdcda0c..11602930d5f 100644 --- a/include/reactos/idl/svcctl.idl +++ b/include/reactos/idl/svcctl.idl @@ -174,9 +174,12 @@ typedef struct _SERVICE_RPC_REQUIRED_PRIVILEGES_INFO { [size_is(cbRequiredPrivileges)] PBYTE pRequiredPrivileges; } SERVICE_RPC_REQUIRED_PRIVILEGES_INFO, *LPSERVICE_RPC_REQUIRED_PRIVILEGES_INFO; +cpp_quote("#ifndef _SERVICE_PRESHUTDOWN_INFO_DEFINED_") +cpp_quote("#define _SERVICE_PRESHUTDOWN_INFO_DEFINED_") typedef struct _SERVICE_PRESHUTDOWN_INFO { DWORD dwPreshutdownTimeout; } SERVICE_PRESHUTDOWN_INFO, *LPSERVICE_PRESHUTDOWN_INFO; +cpp_quote("#endif") typedef struct _SC_RPC_CONFIG_INFOA { DWORD dwInfoLevel; diff --git a/include/reactos/wine/ddk/ntddcdvd.h b/include/reactos/wine/ddk/ntddcdvd.h new file mode 100644 index 00000000000..f6ce77b1db7 --- /dev/null +++ b/include/reactos/wine/ddk/ntddcdvd.h @@ -0,0 +1,198 @@ +/* + * DDK information for DVD + * + * Copyright (C) 2004 Uwe Bonnes + * + * 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 + */ + +#ifndef __NTDDCDVD_H +#define __NTDDCDVD_H + +/* definitions taken from libdvdcss, modified to reflect Windows names and data types in places */ + +#define IOCTL_DVD_BASE FILE_DEVICE_DVD + +#define IOCTL_DVD_START_SESSION CTL_CODE(IOCTL_DVD_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_DVD_READ_KEY CTL_CODE(IOCTL_DVD_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_DVD_SEND_KEY CTL_CODE(IOCTL_DVD_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_DVD_END_SESSION CTL_CODE(IOCTL_DVD_BASE, 0x0403, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_DVD_SET_READ_AHEAD CTL_CODE(IOCTL_DVD_BASE, 0x0404, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_DVD_GET_REGION CTL_CODE(IOCTL_DVD_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_DVD_SEND_KEY2 CTL_CODE(IOCTL_DVD_BASE, 0x0406, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +#define IOCTL_DVD_READ_STRUCTURE CTL_CODE(IOCTL_DVD_BASE, 0x0450, METHOD_BUFFERED, FILE_READ_ACCESS) + +typedef enum { + DvdChallengeKey = 0x01, + DvdBusKey1, + DvdBusKey2, + DvdTitleKey, + DvdAsf, + DvdSetRpcKey = 0x6, + DvdGetRpcKey = 0x8, + DvdDiskKey = 0x80, + DvdInvalidateAGID = 0x3f +} DVD_KEY_TYPE; + +typedef ULONG DVD_SESSION_ID, *PDVD_SESSION_ID; + +#include + +typedef struct _DVD_COPY_PROTECT_KEY { + ULONG KeyLength; + DVD_SESSION_ID SessionId; + DVD_KEY_TYPE KeyType; + ULONG KeyFlags; + union { + struct { + ULONG FileHandle; + ULONG Reserved; /* used for NT alignment */ + } s; + LARGE_INTEGER TitleOffset; + } Parameters; + UCHAR KeyData[1]; +} DVD_COPY_PROTECT_KEY, *PDVD_COPY_PROTECT_KEY; + +typedef struct _DVD_RPC_KEY { + UCHAR UserResetsAvailable:3; + UCHAR ManufacturerResetsAvailable:3; + UCHAR TypeCode:2; + UCHAR RegionMask; + UCHAR RpcScheme; + UCHAR Reserved2[1]; +} DVD_RPC_KEY, * PDVD_RPC_KEY; + +typedef struct _DVD_ASF { + UCHAR Reserved0[3]; + UCHAR SuccessFlag:1; + UCHAR Reserved1:7; +} DVD_ASF, * PDVD_ASF; + +typedef struct _DVD_REGION +{ + UCHAR CopySystem; + UCHAR RegionData; /* current media region (not playable when set) */ + UCHAR SystemRegion; /* current drive region (playable when set) */ + UCHAR ResetCount; /* number of resets available */ +} DVD_REGION, * PDVD_REGION; + +typedef enum _DVD_STRUCTURE_FORMAT +{ + DvdPhysicalDescriptor, + DvdCopyrightDescriptor, + DvdDiskKeyDescriptor, + DvdBCADescriptor, + DvdManufacturerDescriptor, + DvdMaxDescriptor +} DVD_STRUCTURE_FORMAT, *PDVD_STRUCTURE_FORMAT; + +typedef struct DVD_READ_STRUCTURE { + /* Contains an offset to the logical block address of the descriptor to be retrieved. */ + LARGE_INTEGER BlockByteOffset; + + /* 0:Physical descriptor, 1:Copyright descriptor, 2:Disk key descriptor + 3:BCA descriptor, 4:Manufacturer descriptor, 5:Max descriptor + */ + DVD_STRUCTURE_FORMAT Format; + + /* Session ID, that is obtained by IOCTL_DVD_START_SESSION */ + DVD_SESSION_ID SessionId; + + /* From 0 to 4 */ + UCHAR LayerNumber; +} DVD_READ_STRUCTURE, *PDVD_READ_STRUCTURE; + +typedef struct _DVD_DESCRIPTOR_HEADER { + USHORT Length; + UCHAR Reserved[2]; +} DVD_DESCRIPTOR_HEADER, *PDVD_DESCRIPTOR_HEADER; +C_ASSERT(sizeof(DVD_DESCRIPTOR_HEADER) == 4); + +typedef struct _DVD_LAYER_DESCRIPTOR +{ + UCHAR BookVersion : 4; + + /* 0:DVD-ROM, 1:DVD-RAM, 2:DVD-R, 3:DVD-RW, 9:DVD-RW */ + UCHAR BookType : 4; + + UCHAR MinimumRate : 4; + + /* The physical size of the media. 0:120 mm, 1:80 mm. */ + UCHAR DiskSize : 4; + + /* 1:Read-only layer, 2:Recordable layer, 4:Rewritable layer */ + UCHAR LayerType : 4; + + /* 0:parallel track path, 1:opposite track path */ + UCHAR TrackPath : 1; + + /* 0:one layers, 1:two layers, and so on */ + UCHAR NumberOfLayers : 2; + + UCHAR Reserved1 : 1; + + /* 0:0.74 µm/track, 1:0.80 µm/track, 2:0.615 µm/track */ + UCHAR TrackDensity : 4; + + /* 0:0.267 µm/bit, 1:0.293 µm/bit, 2:0.409 to 0.435 µm/bit, 4:0.280 to 0.291 µm/bit, 8:0.353 µm/bit */ + UCHAR LinearDensity : 4; + + /* Must be either 0x30000:DVD-ROM or DVD-R/-RW or 0x31000:DVD-RAM or DVD+RW */ + ULONG StartingDataSector; + + ULONG EndDataSector; + ULONG EndLayerZeroSector; + UCHAR Reserved5 : 7; + + /* 0 indicates no BCA data */ + UCHAR BCAFlag : 1; +}DVD_LAYER_DESCRIPTOR, * PDVD_LAYER_DESCRIPTOR; +C_ASSERT(sizeof(DVD_LAYER_DESCRIPTOR) == 17); + +typedef struct _DVD_COPYRIGHT_DESCRIPTOR +{ + UCHAR CopyrightProtectionType; + UCHAR RegionManagementInformation; + USHORT Reserved; +}DVD_COPYRIGHT_DESCRIPTOR, * PDVD_COPYRIGHT_DESCRIPTOR; + +typedef struct _DVD_DISK_KEY_DESCRIPTOR +{ + UCHAR DiskKeyData[2048]; +}DVD_DISK_KEY_DESCRIPTOR, * PDVD_DISK_KEY_DESCRIPTOR; + +typedef struct _DVD_BCA_DESCRIPTOR +{ + UCHAR BCAInformation[1]; +}DVD_BCA_DESCRIPTOR, * PDVD_BCA_DESCRIPTOR; + +typedef struct _DVD_MANUFACTURER_DESCRIPTOR +{ + UCHAR ManufacturingInformation[2048]; +}DVD_MANUFACTURER_DESCRIPTOR, * PDVD_MANUFACTURER_DESCRIPTOR; + +#define DVD_CHALLENGE_KEY_LENGTH (12 + sizeof(DVD_COPY_PROTECT_KEY) - sizeof(UCHAR)) + +#define DVD_DISK_KEY_LENGTH (2048 + sizeof(DVD_COPY_PROTECT_KEY) - sizeof(UCHAR)) + +#define DVD_KEY_SIZE 5 +#define DVD_CHALLENGE_SIZE 10 +#define DVD_DISCKEY_SIZE 2048 +#define DVD_SECTOR_PROTECTED 0x00000020 + +#include + +#endif /* __NTDDCDVD_H */ diff --git a/lib/drivers/libusb/hub_controller.cpp b/lib/drivers/libusb/hub_controller.cpp index 90e6e9cfb8d..59f5245d4d4 100644 --- a/lib/drivers/libusb/hub_controller.cpp +++ b/lib/drivers/libusb/hub_controller.cpp @@ -740,6 +740,12 @@ CHubController::HandlePnp( Status = STATUS_SUCCESS; break; } + case IRP_MN_SURPRISE_REMOVAL: + { + DPRINT("[USBLIB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n"); + Status = STATUS_SUCCESS; + break; + } default: { // @@ -1038,6 +1044,7 @@ CHubController::HandleSelectConfiguration( { PUSBDEVICE UsbDevice; PUSBD_INTERFACE_INFORMATION InterfaceInfo; + NTSTATUS Status; // // is the request for the Root Hub @@ -1104,7 +1111,13 @@ CHubController::HandleSelectConfiguration( // // select configuration // - return UsbDevice->SelectConfiguration(Urb->UrbSelectConfiguration.ConfigurationDescriptor, &Urb->UrbSelectConfiguration.Interface, &Urb->UrbSelectConfiguration.ConfigurationHandle); + Status = UsbDevice->SelectConfiguration(Urb->UrbSelectConfiguration.ConfigurationDescriptor, &Urb->UrbSelectConfiguration.Interface, &Urb->UrbSelectConfiguration.ConfigurationHandle); + if (NT_SUCCESS(Status)) + { + // successfully configured device + Urb->UrbSelectConfiguration.Hdr.Status = USBD_STATUS_SUCCESS; + } + return Status; } } @@ -1479,7 +1492,10 @@ CHubController::HandleGetDescriptorFromInterface( // submit setup packet // Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer); - ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + DPRINT1("[USBLIB] HandleGetDescriptorFromInterface failed with %x\n", Status); + } // // done @@ -1499,7 +1515,7 @@ CHubController::HandleGetDescriptor( PUSBDEVICE UsbDevice; ULONG Length, BufferLength; - DPRINT("[USBLIB] HandleGetDescriptor\n"); + DPRINT("[USBLIB] HandleGetDescriptor Type %x\n", Urb->UrbControlDescriptorRequest.DescriptorType); // // check descriptor type @@ -1520,6 +1536,8 @@ CHubController::HandleGetDescriptor( // copy root hub device descriptor // RtlCopyMemory((PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); + Irp->IoStatus.Information = sizeof(USB_DEVICE_DESCRIPTOR); + Urb->UrbControlDescriptorRequest.Hdr.Status = USBD_STATUS_SUCCESS; Status = STATUS_SUCCESS; } else @@ -1546,6 +1564,8 @@ CHubController::HandleGetDescriptor( // retrieve device descriptor from device // UsbDevice->GetDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer); + Irp->IoStatus.Information = sizeof(USB_DEVICE_DESCRIPTOR); + Urb->UrbControlDescriptorRequest.Hdr.Status = USBD_STATUS_SUCCESS; Status = STATUS_SUCCESS; } break; @@ -1678,7 +1698,9 @@ CHubController::HandleGetDescriptor( // // store result size // + Irp->IoStatus.Information = Length; Urb->UrbControlDescriptorRequest.TransferBufferLength = Length; + Urb->UrbControlDescriptorRequest.Hdr.Status = USBD_STATUS_SUCCESS; Status = STATUS_SUCCESS; } break; @@ -1828,7 +1850,7 @@ CHubController::HandleVendorDevice( PUSBDEVICE UsbDevice; USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - DPRINT("CHubController::HandleVendorDevice Request %x\n", Urb->UrbControlVendorClassRequest.Request); + //DPRINT("CHubController::HandleVendorDevice Request %x\n", Urb->UrbControlVendorClassRequest.Request); // // sanity check @@ -1876,7 +1898,12 @@ CHubController::HandleVendorDevice( // issue request // Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer); - PC_ASSERT(NT_SUCCESS(Status)); + if (NT_SUCCESS(Status)) + { + // success + Urb->UrbControlVendorClassRequest.Hdr.Status = USBD_STATUS_SUCCESS; + Irp->IoStatus.Information = Urb->UrbControlVendorClassRequest.TransferBufferLength; + } return Status; } diff --git a/lib/drivers/libusb/usb_device.cpp b/lib/drivers/libusb/usb_device.cpp index 2050dd0fdee..e02cd03a652 100644 --- a/lib/drivers/libusb/usb_device.cpp +++ b/lib/drivers/libusb/usb_device.cpp @@ -387,7 +387,6 @@ CUSBDevice::SetDeviceAddress( if (!NT_SUCCESS(Status)) { DPRINT1("CUSBDevice::SetDeviceAddress> failed to retrieve configuration %lu\n", Index); - ASSERT(FALSE); break; } } @@ -1124,6 +1123,7 @@ CUSBDevice::SelectConfiguration( if (!NT_SUCCESS(Status)) { // failed + DPRINT1("[LIBUSB] Failed to copy interface descriptor Index %lu InterfaceDescriptor %p InterfaceInfo %p\n", ConfigurationIndex, InterfaceDescriptor, InterfaceInfo); break; } diff --git a/lib/sdk/crt/crt.cmake b/lib/sdk/crt/crt.cmake index c60a7cbe2fd..b1479770f13 100644 --- a/lib/sdk/crt/crt.cmake +++ b/lib/sdk/crt/crt.cmake @@ -61,6 +61,7 @@ list(APPEND CRT_SOURCE math/sinf.c math/sinh.c math/tanh.c + mbstring/_setmbcp.c mbstring/hanzen.c mbstring/ischira.c mbstring/iskana.c @@ -323,7 +324,6 @@ list(APPEND CRT_SOURCE time/utime64.c time/utime.c time/wasctime.c - time/wcsftime.c time/wctime32.c time/wctime64.c time/wctime.c diff --git a/lib/sdk/crt/float/i386/cntrlfp.c b/lib/sdk/crt/float/i386/cntrlfp.c index 18745eaaf6f..8ecd3fc046b 100644 --- a/lib/sdk/crt/float/i386/cntrlfp.c +++ b/lib/sdk/crt/float/i386/cntrlfp.c @@ -120,15 +120,15 @@ unsigned int CDECL _control87(unsigned int newval, unsigned int mask) int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask) { #ifdef __i386__ - unsigned int flags; - - FIXME("(%p %u %u) semi-stub\n", cur, newval, mask); - - flags = _control87( newval, mask & ~_EM_DENORMAL ); - - if(cur) - *cur = flags; + unsigned int val; + if (!MSVCRT_CHECK_PMT( !(newval & mask & ~(_MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC | _MCW_DN)))) + { + if (cur) *cur = _controlfp( 0, 0 ); /* retrieve it anyway */ + return EINVAL; + } + val = _controlfp( newval, mask ); + if (cur) *cur = val; return 0; #else FIXME(":Not Implemented!\n"); diff --git a/lib/sdk/crt/include/internal/locale.h b/lib/sdk/crt/include/internal/locale.h new file mode 100644 index 00000000000..107f08cfc32 --- /dev/null +++ b/lib/sdk/crt/include/internal/locale.h @@ -0,0 +1,111 @@ +#ifndef __CRT_INTERNAL_LOCALE_H +#define __CRT_INTERNAL_LOCALE_H + +typedef struct MSVCRT_threadlocaleinfostruct { + LONG refcount; + unsigned int lc_codepage; + unsigned int lc_collate_cp; + unsigned long lc_handle[6]; + LC_ID lc_id[6]; + struct { + char *locale; + wchar_t *wlocale; + int *refcount; + int *wrefcount; + } lc_category[6]; + int lc_clike; + int mb_cur_max; + int *lconv_intl_refcount; + int *lconv_num_refcount; + int *lconv_mon_refcount; + struct MSVCRT_lconv *lconv; + int *ctype1_refcount; + unsigned short *ctype1; + const unsigned short *pctype; + unsigned char *pclmap; + unsigned char *pcumap; + struct __lc_time_data *lc_time_curr; +} MSVCRT_threadlocinfo; + +typedef struct MSVCRT_threadmbcinfostruct { + LONG refcount; + int mbcodepage; + int ismbcodepage; + int mblcid; + unsigned short mbulinfo[6]; + unsigned char mbctype[257]; + char mbcasemap[256]; +} MSVCRT_threadmbcinfo; + +struct MSVCRT_lconv { + char* decimal_point; + char* thousands_sep; + char* grouping; + char* int_curr_symbol; + char* currency_symbol; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; +}; + +typedef struct MSVCRT_threadlocaleinfostruct *MSVCRT_pthreadlocinfo; +typedef struct MSVCRT_threadmbcinfostruct *MSVCRT_pthreadmbcinfo; + +typedef struct MSVCRT_localeinfo_struct +{ + MSVCRT_pthreadlocinfo locinfo; + MSVCRT_pthreadmbcinfo mbcinfo; +} MSVCRT__locale_tstruct, *MSVCRT__locale_t; + +typedef struct __lc_time_data { + union { + char *str[43]; + struct { + char *short_wday[7]; + char *wday[7]; + char *short_mon[12]; + char *mon[12]; + char *am; + char *pm; + char *short_date; + char *date; + char *time; + } names; + } str; + LCID lcid; + int unk[2]; + wchar_t *wstr[43]; + char data[1]; +} MSVCRT___lc_time_data; + +int _setmbcp_l(int, LCID, MSVCRT_pthreadmbcinfo) DECLSPEC_HIDDEN; +MSVCRT_pthreadmbcinfo get_mbcinfo(void) DECLSPEC_HIDDEN; +LCID MSVCRT_locale_to_LCID(const char *locale) DECLSPEC_HIDDEN; + +void __init_global_locale(); +extern MSVCRT__locale_t global_locale; +#define MSVCRT_locale __get_MSVCRT_locale() +FORCEINLINE MSVCRT__locale_t __get_MSVCRT_locale() +{ + if(!global_locale) + __init_global_locale(); + return global_locale; +} + +MSVCRT_pthreadlocinfo get_locinfo(void); +void __cdecl MSVCRT__free_locale(MSVCRT__locale_t); +void free_locinfo(MSVCRT_pthreadlocinfo); +void free_mbcinfo(MSVCRT_pthreadmbcinfo); + +#endif //__CRT_INTERNAL_LOCALE_H + diff --git a/lib/sdk/crt/include/internal/mbstring.h b/lib/sdk/crt/include/internal/mbstring.h index 703439b9bed..8ceb83fa921 100644 --- a/lib/sdk/crt/include/internal/mbstring.h +++ b/lib/sdk/crt/include/internal/mbstring.h @@ -39,7 +39,7 @@ #define MAX_LOCALE_LENGTH 256 extern unsigned char _mbctype[257]; -extern int MSVCRT___lc_codepage; +extern unsigned int MSVCRT___lc_codepage; extern char MSVCRT_current_lc_all[MAX_LOCALE_LENGTH]; #if defined (_MSC_VER) diff --git a/lib/sdk/crt/include/internal/tls.h b/lib/sdk/crt/include/internal/tls.h index b5850b74653..664e553ee39 100644 --- a/lib/sdk/crt/include/internal/tls.h +++ b/lib/sdk/crt/include/internal/tls.h @@ -16,108 +16,42 @@ #include -typedef struct MSVCRT_threadlocaleinfostruct { - int refcount; - unsigned int lc_codepage; - unsigned int lc_collate_cp; - unsigned long lc_handle[6]; - LC_ID lc_id[6]; - struct { - char *locale; - wchar_t *wlocale; - int *refcount; - int *wrefcount; - } lc_category[6]; - int lc_clike; - int mb_cur_max; - int *lconv_intl_refcount; - int *lconv_num_refcount; - int *lconv_mon_refcount; - struct MSVCRT_lconv *lconv; - int *ctype1_refcount; - unsigned short *ctype1; - unsigned short *pctype; - unsigned char *pclmap; - unsigned char *pcumap; - struct __lc_time_data *lc_time_curr; -} MSVCRT_threadlocinfo; - -typedef struct MSVCRT_threadmbcinfostruct { - int refcount; - int mbcodepage; - int ismbcodepage; - int mblcid; - unsigned short mbulinfo[6]; - char mbctype[257]; - char mbcasemap[256]; -} MSVCRT_threadmbcinfo; - -struct MSVCRT_lconv { - char* decimal_point; - char* thousands_sep; - char* grouping; - char* int_curr_symbol; - char* currency_symbol; - char* mon_decimal_point; - char* mon_thousands_sep; - char* mon_grouping; - char* positive_sign; - char* negative_sign; - char int_frac_digits; - char frac_digits; - char p_cs_precedes; - char p_sep_by_space; - char n_cs_precedes; - char n_sep_by_space; - char p_sign_posn; - char n_sign_posn; -}; - -typedef struct MSVCRT_threadlocaleinfostruct *MSVCRT_pthreadlocinfo; -typedef struct MSVCRT_threadmbcinfostruct *MSVCRT_pthreadmbcinfo; - -typedef struct MSVCRT_localeinfo_struct -{ - MSVCRT_pthreadlocinfo locinfo; - MSVCRT_pthreadmbcinfo mbcinfo; -} MSVCRT__locale_tstruct, *MSVCRT__locale_t; - /* TLS data */ extern DWORD tls_index; struct __thread_data { - DWORD tid; - HANDLE handle; - int thread_errno; - unsigned long thread_doserrno; - int unk1; - unsigned int random_seed; /* seed for rand() */ - char *strtok_next; /* next ptr for strtok() */ - wchar_t *wcstok_next; /* next ptr for wcstok() */ - unsigned char *mbstok_next; /* next ptr for mbstok() */ - char *strerror_buffer; /* buffer for strerror */ - wchar_t *wcserror_buffer; /* buffer for wcserror */ - char *tmpnam_buffer; /* buffer for tmpname() */ - wchar_t *wtmpnam_buffer; /* buffer for wtmpname() */ - void *unk2[2]; - char *asctime_buffer; /* buffer for asctime */ - wchar_t *wasctime_buffer; /* buffer for wasctime */ - struct tm *time_buffer; /* buffer for localtime/gmtime */ - char *efcvt_buffer; /* buffer for ecvt/fcvt */ - int unk3[2]; - void *unk4[4]; - int fpecode; - MSVCRT_pthreadmbcinfo mbcinfo; - MSVCRT_pthreadlocinfo locinfo; - BOOL have_locale; - int unk5[1]; - terminate_function terminate_handler; - unexpected_function unexpected_handler; - _se_translator_function se_translator; - void *unk6[3]; - int unk7; - EXCEPTION_RECORD *exc_record; - void *unk8[100]; + DWORD tid; + HANDLE handle; + int thread_errno; + unsigned long thread_doserrno; + int unk1; + unsigned int random_seed; /* seed for rand() */ + char *strtok_next; /* next ptr for strtok() */ + wchar_t *wcstok_next; /* next ptr for wcstok() */ + unsigned char *mbstok_next; /* next ptr for mbstok() */ + char *strerror_buffer; /* buffer for strerror */ + wchar_t *wcserror_buffer; /* buffer for wcserror */ + char *tmpnam_buffer; /* buffer for tmpname() */ + wchar_t *wtmpnam_buffer; /* buffer for wtmpname() */ + void *unk2[2]; + char *asctime_buffer; /* buffer for asctime */ + wchar_t *wasctime_buffer; /* buffer for wasctime */ + struct tm *time_buffer; /* buffer for localtime/gmtime */ + char *efcvt_buffer; /* buffer for ecvt/fcvt */ + int unk3[2]; + void *unk4[4]; + int fpecode; + struct MSVCRT_threadmbcinfostruct *mbcinfo; + struct MSVCRT_threadlocaleinfostruct *locinfo; + BOOL have_locale; + int unk5[1]; + terminate_function terminate_handler; + unexpected_function unexpected_handler; + _se_translator_function se_translator; + void *unk6[3]; + int unk7; + EXCEPTION_RECORD *exc_record; + void *unk8[100]; }; typedef struct __thread_data thread_data_t; @@ -130,12 +64,6 @@ extern inline void msvcrt_free_tls_mem(void); #define MSVCRT_ENABLE_PER_THREAD_LOCALE 1 #define MSVCRT_DISABLE_PER_THREAD_LOCALE 2 -extern MSVCRT__locale_t MSVCRT_locale; -MSVCRT_pthreadlocinfo get_locinfo(void); -void __cdecl MSVCRT__free_locale(MSVCRT__locale_t); -void free_locinfo(MSVCRT_pthreadlocinfo); -void free_mbcinfo(MSVCRT_pthreadmbcinfo); - #endif /* __MSVCRT_INTERNAL_TLS_H */ /* EOF */ diff --git a/lib/sdk/crt/locale/locale.c b/lib/sdk/crt/locale/locale.c index 5abee62e696..0aebb4b2dd4 100644 --- a/lib/sdk/crt/locale/locale.c +++ b/lib/sdk/crt/locale/locale.c @@ -1,182 +1,138 @@ /* - * Some stuff takem from wine msvcrt\locale.c + * msvcrt.dll locale functions * * Copyright 2000 Jon Griffiths + * + * 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 #include #include "mbctype.h" +#include -// mtdll.h -#define _SETLOCALE_LOCK 19 - -// msvcrt.h -#define MSVCRT_LC_ALL 0 -#define MSVCRT_LC_COLLATE 1 -#define MSVCRT_LC_CTYPE 2 -#define MSVCRT_LC_MONETARY 3 -#define MSVCRT_LC_NUMERIC 4 -#define MSVCRT_LC_TIME 5 -#define MSVCRT_LC_MIN MSVCRT_LC_ALL -#define MSVCRT_LC_MAX MSVCRT_LC_TIME - -/* FIXME: Need to hold locale for each LC_* type and aggregate - * string to produce lc_all. - */ #define MAX_ELEM_LEN 64 /* Max length of country/language/CP string */ +#define MAX_LOCALE_LENGTH 256 + +#ifdef _pctype +#error _pctype should not be defined +#endif + +unsigned int MSVCRT___lc_codepage = 0; +int MSVCRT___lc_collate_cp = 0; +LCID MSVCRT___lc_handle[LC_MAX - LC_MIN + 1] = { 0 }; +int __mb_cur_max = 1; +static unsigned char charmax = CHAR_MAX; unsigned char _mbctype[257] = { 0 }; -int g_mbcp_is_multibyte = 0; - -/* It seems that the data about valid trail bytes is not available from kernel32 - * so we have to store is here. The format is the same as for lead bytes in CPINFO */ -struct cp_extra_info_t -{ - int cp; - BYTE TrailBytes[MAX_LEADBYTES]; -}; - -static struct cp_extra_info_t g_cpextrainfo[] = -{ - {932, {0x40, 0x7e, 0x80, 0xfc, 0, 0}}, - {936, {0x40, 0xfe, 0, 0}}, - {949, {0x41, 0xfe, 0, 0}}, - {950, {0x40, 0x7e, 0xa1, 0xfe, 0, 0}}, - {1361, {0x31, 0x7e, 0x81, 0xfe, 0, 0}}, - {20932, {1, 255, 0, 0}}, /* seems to give different results on different systems */ - {0, {1, 255, 0, 0}} /* match all with FIXME */ -}; - - -char MSVCRT_current_lc_all[MAX_LOCALE_LENGTH] = { 0 }; -LCID MSVCRT_current_lc_all_lcid = 0; -int MSVCRT___lc_codepage = 0; -int MSVCRT___lc_collate_cp = 0; -HANDLE MSVCRT___lc_handle[MSVCRT_LC_MAX - MSVCRT_LC_MIN + 1] = { 0 }; -int __mb_cur_max = 1; /* MT */ #define LOCK_LOCALE _mlock(_SETLOCALE_LOCK); #define UNLOCK_LOCALE _munlock(_SETLOCALE_LOCK); #define MSVCRT_LEADBYTE 0x8000 +#define MSVCRT_C1_DEFINED 0x200 -typedef struct { - char search_language[MAX_ELEM_LEN]; - char search_country[MAX_ELEM_LEN]; - char search_codepage[MAX_ELEM_LEN]; - char found_language[MAX_ELEM_LEN]; - char found_country[MAX_ELEM_LEN]; - char found_codepage[MAX_ELEM_LEN]; - unsigned int match_flags; - LANGID found_lang_id; -} locale_search_t; - -extern unsigned int __setlc_active; -extern unsigned int __unguarded_readlc_active; -int _current_category; /* used by setlocale */ -const char *_current_locale; - - -int parse_locale(const char *locale, char *lang, char *country, char *code_page); - -#define _C_ _CONTROL -#define _S_ _SPACE -#define _P_ _PUNCT -#define _D_ _DIGIT -#define _H_ _HEX -#define _U_ _UPPER -#define _L_ _LOWER - -WORD MSVCRT__ctype [257] = { - 0, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_C_, _S_|_C_, - _S_|_C_, _S_|_C_, _S_|_C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, - _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_BLANK, - _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, - _P_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, - _D_|_H_, _D_|_H_, _D_|_H_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _U_|_H_, - _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_, _U_, _U_, _U_, _U_, - _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, - _U_, _P_, _P_, _P_, _P_, _P_, _P_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, - _L_|_H_, _L_|_H_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, - _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _P_, _P_, _P_, - _C_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* Internal: Current ctype table for locale */ -WORD MSVCRT_current_ctype[257]; - -/* pctype is used by macros in the Win32 headers. It must point - * To a table of flags exactly like ctype. To allow locale - * changes to affect ctypes (i.e. isleadbyte), we use a second table - * and update its flags whenever the current locale changes. - */ -WORD* MSVCRT__pctype = MSVCRT_current_ctype + 1; - -/* Friendly country strings & iso codes for synonym support. - * Based on MS documentation for setlocale(). - */ +/* Friendly country strings & language names abbreviations. */ static const char * const _country_synonyms[] = { - "Hong Kong","HK", - "Hong-Kong","HK", - "New Zealand","NZ", - "New-Zealand","NZ", - "PR China","CN", - "PR-China","CN", - "United Kingdom","GB", - "United-Kingdom","GB", - "Britain","GB", - "England","GB", - "Great Britain","GB", - "United States","US", - "United-States","US", - "America","US" + "american", "enu", + "american english", "enu", + "american-english", "enu", + "english-american", "enu", + "english-us", "enu", + "english-usa", "enu", + "us", "enu", + "usa", "enu", + "australian", "ena", + "english-aus", "ena", + "belgian", "nlb", + "french-belgian", "frb", + "canadian", "enc", + "english-can", "enc", + "french-canadian", "frc", + "chinese", "chs", + "chinese-simplified", "chs", + "chinese-traditional", "cht", + "dutch-belgian", "nlb", + "english-nz", "enz", + "uk", "eng", + "english-uk", "eng", + "french-swiss", "frs", + "swiss", "des", + "german-swiss", "des", + "italian-swiss", "its", + "german-austrian", "dea", + "portuguese", "ptb", + "portuguese-brazil", "ptb", + "spanish-mexican", "esm", + "norwegian-bokmal", "nor", + "norwegian-nynorsk", "non", + "spanish-modern", "esn" }; +/* INTERNAL: Map a synonym to an ISO code */ +static void remap_synonym(char *name) +{ + unsigned int i; + for (i = 0; i < sizeof(_country_synonyms)/sizeof(char*); i += 2 ) + { + if (!strcasecmp(_country_synonyms[i],name)) + { + TRACE(":Mapping synonym %s to %s\n",name,_country_synonyms[i+1]); + strcpy(name, _country_synonyms[i+1]); + return; + } + } +} + /* Note: Flags are weighted in order of matching importance */ #define FOUND_LANGUAGE 0x4 #define FOUND_COUNTRY 0x2 #define FOUND_CODEPAGE 0x1 -/* INTERNAL: Map a synonym to an ISO code */ -static void remap_synonym(char *name) -{ - size_t i; - for (i = 0; i < sizeof(_country_synonyms)/sizeof(char*); i += 2 ) - { - if (!_stricmp(_country_synonyms[i],name)) - { - TRACE(":Mapping synonym %s to %s\n",name,_country_synonyms[i+1]); - name[0] = _country_synonyms[i+1][0]; - name[1] = _country_synonyms[i+1][1]; - name[2] = '\0'; - return; - } - } -} +typedef struct { + char search_language[MAX_ELEM_LEN]; + char search_country[MAX_ELEM_LEN]; + char search_codepage[MAX_ELEM_LEN]; + char found_codepage[MAX_ELEM_LEN]; + unsigned int match_flags; + LANGID found_lang_id; +} locale_search_t; #define CONTINUE_LOOKING TRUE #define STOP_LOOKING FALSE /* INTERNAL: Get and compare locale info with a given string */ -static int compare_info(LCID lcid, DWORD flags, char* buff, const char* cmp) +static int compare_info(LCID lcid, DWORD flags, char* buff, const char* cmp, BOOL exact) { + int len; + buff[0] = 0; - GetLocaleInfoA(lcid, flags|LOCALE_NOUSEROVERRIDE,buff, MAX_ELEM_LEN); + GetLocaleInfoA(lcid, flags|LOCALE_NOUSEROVERRIDE, buff, MAX_ELEM_LEN); if (!buff[0] || !cmp[0]) return 0; - /* Partial matches are allowed, e.g. "Germ" matches "Germany" */ - return !_strnicmp(cmp, buff, strlen(cmp)); -} + /* Partial matches are only allowed on language/country names */ + len = strlen(cmp); + if(exact || len<=3) + return !strcasecmp(cmp, buff); + else + return !strncasecmp(cmp, buff, len); +} static BOOL CALLBACK find_best_locale_proc(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LONG_PTR lParam) @@ -190,13 +146,12 @@ find_best_locale_proc(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LO return CONTINUE_LOOKING; /* Check Language */ - if (compare_info(lcid,LOCALE_SISO639LANGNAME,buff,res->search_language) || - compare_info(lcid,LOCALE_SABBREVLANGNAME,buff,res->search_language) || - compare_info(lcid,LOCALE_SENGLANGUAGE,buff,res->search_language)) + if (compare_info(lcid,LOCALE_SISO639LANGNAME,buff,res->search_language, TRUE) || + compare_info(lcid,LOCALE_SABBREVLANGNAME,buff,res->search_language, TRUE) || + compare_info(lcid,LOCALE_SENGLANGUAGE,buff,res->search_language, FALSE)) { TRACE(":Found language: %s->%s\n", res->search_language, buff); flags |= FOUND_LANGUAGE; - memcpy(res->found_language,res->search_language,MAX_ELEM_LEN); } else if (res->match_flags & FOUND_LANGUAGE) { @@ -204,13 +159,12 @@ find_best_locale_proc(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LO } /* Check Country */ - if (compare_info(lcid,LOCALE_SISO3166CTRYNAME,buff,res->search_country) || - compare_info(lcid,LOCALE_SABBREVCTRYNAME,buff,res->search_country) || - compare_info(lcid,LOCALE_SENGCOUNTRY,buff,res->search_country)) + if (compare_info(lcid,LOCALE_SISO3166CTRYNAME,buff,res->search_country, TRUE) || + compare_info(lcid,LOCALE_SABBREVCTRYNAME,buff,res->search_country, TRUE) || + compare_info(lcid,LOCALE_SENGCOUNTRY,buff,res->search_country, FALSE)) { TRACE("Found country:%s->%s\n", res->search_country, buff); flags |= FOUND_COUNTRY; - memcpy(res->found_country,res->search_country,MAX_ELEM_LEN); } else if (res->match_flags & FOUND_COUNTRY) { @@ -218,8 +172,8 @@ find_best_locale_proc(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LO } /* Check codepage */ - if (compare_info(lcid,LOCALE_IDEFAULTCODEPAGE,buff,res->search_codepage) || - (compare_info(lcid,LOCALE_IDEFAULTANSICODEPAGE,buff,res->search_codepage))) + if (compare_info(lcid,LOCALE_IDEFAULTCODEPAGE,buff,res->search_codepage, TRUE) || + (compare_info(lcid,LOCALE_IDEFAULTANSICODEPAGE,buff,res->search_codepage, TRUE))) { TRACE("Found codepage:%s->%s\n", res->search_codepage, buff); flags |= FOUND_CODEPAGE; @@ -245,605 +199,315 @@ find_best_locale_proc(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LO return CONTINUE_LOOKING; } +extern int atoi(const char *); + /* Internal: Find the LCID for a locale specification */ -static LCID MSVCRT_locale_to_LCID(locale_search_t* locale) +LCID MSVCRT_locale_to_LCID(const char *locale) { - LCID lcid; - EnumResourceLanguagesA(GetModuleHandleA("KERNEL32"), (LPSTR)RT_STRING, - (LPCSTR)LOCALE_ILANGUAGE,find_best_locale_proc, - (LONG_PTR)locale); + LCID lcid; + locale_search_t search; + const char *cp, *region; - if (!locale->match_flags) - return 0; + memset(&search, 0, sizeof(locale_search_t)); - /* If we were given something that didn't match, fail */ - if (locale->search_country[0] && !(locale->match_flags & FOUND_COUNTRY)) - return 0; + cp = strchr(locale, '.'); + region = strchr(locale, '_'); - lcid = MAKELCID(locale->found_lang_id, SORT_DEFAULT); + lstrcpynA(search.search_language, locale, MAX_ELEM_LEN); + if(region) { + lstrcpynA(search.search_country, region+1, MAX_ELEM_LEN); + if(region-locale < MAX_ELEM_LEN) + search.search_language[region-locale] = '\0'; + } else + search.search_country[0] = '\0'; - /* Populate partial locale, translating LCID to locale string elements */ - if (!locale->found_codepage[0]) - { - /* Even if a codepage is not enumerated for a locale - * it can be set if valid */ - if (locale->search_codepage[0]) - { - if (IsValidCodePage(atoi(locale->search_codepage))) - memcpy(locale->found_codepage,locale->search_codepage,MAX_ELEM_LEN); - else - { - /* Special codepage values: OEM & ANSI */ - if (_stricmp(locale->search_codepage,"OCP")) - { - GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE, - locale->found_codepage, MAX_ELEM_LEN); + if(cp) { + lstrcpynA(search.search_codepage, cp+1, MAX_ELEM_LEN); + if(region && cp-region-1search_codepage,"ACP")) - { - GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, - locale->found_codepage, MAX_ELEM_LEN); - } - else - return 0; + } - if (!atoi(locale->found_codepage)) - return 0; - } - } - else - { - /* Prefer ANSI codepages if present */ - GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, - locale->found_codepage, MAX_ELEM_LEN); - if (!locale->found_codepage[0] || !atoi(locale->found_codepage)) - GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE, - locale->found_codepage, MAX_ELEM_LEN); - } - } - GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE|LOCALE_NOUSEROVERRIDE, - locale->found_language, MAX_ELEM_LEN); - GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY|LOCALE_NOUSEROVERRIDE, - locale->found_country, MAX_ELEM_LEN); - return lcid; + return lcid; } -/* INTERNAL: Set ctype behaviour for a codepage */ -static void msvcrt_set_ctype(unsigned int codepage, LCID lcid) +/* INTERNAL: Set lc_handle, lc_id and lc_category in threadlocinfo struct */ +static BOOL update_threadlocinfo_category(LCID lcid, MSVCRT__locale_t loc, int category) { - CPINFO cp; + char buf[256], *p; + int len; - memset(&cp, 0, sizeof(CPINFO)); + if(GetLocaleInfoA(lcid, LOCALE_ILANGUAGE|LOCALE_NOUSEROVERRIDE, buf, 256)) { + p = buf; + + loc->locinfo->lc_id[category].wLanguage = 0; + while(*p) { + loc->locinfo->lc_id[category].wLanguage *= 16; + + if(*p <= '9') + loc->locinfo->lc_id[category].wLanguage += *p-'0'; + else + loc->locinfo->lc_id[category].wLanguage += *p-'a'+10; + + p++; + } + + loc->locinfo->lc_id[category].wCountry = + loc->locinfo->lc_id[category].wLanguage; + } + + if(GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE + |LOCALE_NOUSEROVERRIDE, buf, 256)) + loc->locinfo->lc_id[category].wCodePage = atoi(buf); + + loc->locinfo->lc_handle[category] = lcid; + + len = 0; + len += GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE + |LOCALE_NOUSEROVERRIDE, buf, 256); + buf[len-1] = '_'; + len += GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY + |LOCALE_NOUSEROVERRIDE, &buf[len], 256-len); + buf[len-1] = '.'; + len += GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE + |LOCALE_NOUSEROVERRIDE, &buf[len], 256-len); + + loc->locinfo->lc_category[category].locale = malloc(len); + loc->locinfo->lc_category[category].refcount = malloc(sizeof(int)); + if(!loc->locinfo->lc_category[category].locale + || !loc->locinfo->lc_category[category].refcount) { + free(loc->locinfo->lc_category[category].locale); + free(loc->locinfo->lc_category[category].refcount); + loc->locinfo->lc_category[category].locale = NULL; + loc->locinfo->lc_category[category].refcount = NULL; + return TRUE; + } + memcpy(loc->locinfo->lc_category[category].locale, buf, len); + *loc->locinfo->lc_category[category].refcount = 1; + + return FALSE; +} + +/* INTERNAL: swap pointers values */ +static inline void swap_pointers(void **p1, void **p2) { + void *hlp; + + hlp = *p1; + *p1 = *p2; + *p2 = hlp; +} + +/* INTERNAL: returns pthreadlocinfo struct */ +MSVCRT_pthreadlocinfo get_locinfo(void) { + thread_data_t *data = msvcrt_get_thread_data(); + + if(!data || !data->have_locale) + return MSVCRT_locale->locinfo; + + return data->locinfo; +} + +/* INTERNAL: returns pthreadlocinfo struct */ +MSVCRT_pthreadmbcinfo get_mbcinfo(void) { + thread_data_t *data = msvcrt_get_thread_data(); + + if(!data || !data->have_locale) + return MSVCRT_locale->mbcinfo; + + return data->mbcinfo; +} + +/* INTERNAL: constructs string returned by setlocale */ +static inline char* construct_lc_all(MSVCRT_pthreadlocinfo locinfo) { + static char current_lc_all[MAX_LOCALE_LENGTH]; - if (GetCPInfo(codepage, &cp)) - { int i; - char str[3]; - unsigned char *traverse = cp.LeadByte; - memset(MSVCRT_current_ctype, 0, sizeof(MSVCRT__ctype)); - MSVCRT___lc_codepage = codepage; - MSVCRT___lc_collate_cp = codepage; - - /* Switch ctype macros to MBCS if needed */ - __mb_cur_max = cp.MaxCharSize; - - /* Set remaining ctype flags: FIXME: faster way to do this? */ - str[1] = str[2] = 0; - for (i = 0; i < 256; i++) - { - if (!(MSVCRT__pctype[i] & MSVCRT_LEADBYTE)) - { - str[0] = i; - GetStringTypeA(lcid, CT_CTYPE1, str, 1, MSVCRT__pctype + i); - } + for(i=LC_MIN+1; ilc_category[i].locale, + locinfo->lc_category[i+1].locale)) + break; } - /* Set leadbyte flags */ - while (traverse[0] || traverse[1]) - { - for( i = traverse[0]; i <= traverse[1]; i++ ) - MSVCRT_current_ctype[i+1] |= MSVCRT_LEADBYTE; - traverse += 2; - }; - } + if(i==LC_MAX) + return locinfo->lc_category[LC_COLLATE].locale; + + sprintf(current_lc_all, + "LC_COLLATE=%s;LC_CTYPE=%s;LC_MONETARY=%s;LC_NUMERIC=%s;LC_TIME=%s", + locinfo->lc_category[LC_COLLATE].locale, + locinfo->lc_category[LC_CTYPE].locale, + locinfo->lc_category[LC_MONETARY].locale, + locinfo->lc_category[LC_NUMERIC].locale, + locinfo->lc_category[LC_TIME].locale); + + return current_lc_all; } -/* - * @implemented +/********************************************************************* + * wsetlocale (MSVCRT.@) */ -char *setlocale(int category, const char *locale) -{ - LCID lcid = 0; - locale_search_t lc; - int haveLang, haveCountry, haveCP; - char* next; - int lc_all = 0; - - TRACE("(%d %s)\n",category,locale); - - if (category < MSVCRT_LC_MIN || category > MSVCRT_LC_MAX) - return NULL; - - if (locale == NULL) - { - /* Report the current Locale */ - return MSVCRT_current_lc_all; - } - - LOCK_LOCALE; - - if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_') - { - WARN(":restore previous locale not implemented!\n"); - /* FIXME: Easiest way to do this is parse the string and - * call this function recursively with its elements, - * Where they differ for each lc_ type. - */ - UNLOCK_LOCALE; - return MSVCRT_current_lc_all; - } - - /* Default Locale: Special case handling */ - if (!strlen(locale) || ((toupper(locale[0]) == 'C') && !locale[1])) - { - MSVCRT_current_lc_all[0] = 'C'; - MSVCRT_current_lc_all[1] = '\0'; - MSVCRT___lc_codepage = GetACP(); - MSVCRT___lc_collate_cp = GetACP(); - - switch (category) { - case MSVCRT_LC_ALL: - lc_all = 1; /* Fall through all cases ... */ - case MSVCRT_LC_COLLATE: - if (!lc_all) break; - case MSVCRT_LC_CTYPE: - /* Restore C locale ctype info */ - __mb_cur_max = 1; - memcpy(MSVCRT_current_ctype, MSVCRT__ctype, sizeof(MSVCRT__ctype)); - if (!lc_all) break; - case MSVCRT_LC_MONETARY: - if (!lc_all) break; - case MSVCRT_LC_NUMERIC: - if (!lc_all) break; - case MSVCRT_LC_TIME: - break; - } - UNLOCK_LOCALE; - return MSVCRT_current_lc_all; - } - - /* Get locale elements */ - haveLang = haveCountry = haveCP = 0; - memset(&lc,0,sizeof(lc)); - - next = strchr(locale,'_'); - if (next && next != locale) - { - haveLang = 1; - memcpy(lc.search_language,locale,next-locale); - locale += next-locale+1; - } - - next = strchr(locale,'.'); - if (next) - { - haveCP = 1; - if (next == locale) - { - locale++; - lstrcpynA(lc.search_codepage, locale, MAX_ELEM_LEN); - } - else - { - if (haveLang) - { - haveCountry = 1; - memcpy(lc.search_country,locale,next-locale); - locale += next-locale+1; - } - else - { - haveLang = 1; - memcpy(lc.search_language,locale,next-locale); - locale += next-locale+1; - } - lstrcpynA(lc.search_codepage, locale, MAX_ELEM_LEN); - } - } - else - { - if (haveLang) - { - haveCountry = 1; - lstrcpynA(lc.search_country, locale, MAX_ELEM_LEN); - } - else - { - haveLang = 1; - lstrcpynA(lc.search_language, locale, MAX_ELEM_LEN); - } - } - - if (haveCountry) - remap_synonym(lc.search_country); - - if (haveCP && !haveCountry && !haveLang) - { - ERR(":Codepage only locale not implemented\n"); - /* FIXME: Use default lang/country and skip locale_to_LCID() - * call below... - */ - UNLOCK_LOCALE; - return NULL; - } - - lcid = MSVCRT_locale_to_LCID(&lc); - - TRACE(":found LCID %d\n",lcid); - - if (lcid == 0) - { - UNLOCK_LOCALE; - return NULL; - } - - MSVCRT_current_lc_all_lcid = lcid; - - _snprintf(MSVCRT_current_lc_all,MAX_LOCALE_LENGTH,"%s_%s.%s", - lc.found_language,lc.found_country,lc.found_codepage); - - switch (category) { - case MSVCRT_LC_ALL: - lc_all = 1; /* Fall through all cases ... */ - case MSVCRT_LC_COLLATE: - if (!lc_all) break; - case MSVCRT_LC_CTYPE: - msvcrt_set_ctype(atoi(lc.found_codepage),lcid); - if (!lc_all) break; - case MSVCRT_LC_MONETARY: - if (!lc_all) break; - case MSVCRT_LC_NUMERIC: - if (!lc_all) break; - case MSVCRT_LC_TIME: - break; - } - UNLOCK_LOCALE; - return MSVCRT_current_lc_all; -} - -/* - * @unimplemented - */ -wchar_t* _wsetlocale(int category, const wchar_t* locale) +wchar_t* CDECL _wsetlocale(int category, const wchar_t* locale) { static wchar_t fake[] = { 'E','n','g','l','i','s','h','_','U','n','i','t','e','d',' ', 'S','t','a','t','e','s','.','1','2','5','2',0 }; - TRACE("%d %S\n", category, locale); + FIXME("%d %s\n", category, debugstr_w(locale)); return fake; } -/* - -locale "lang[_country[.code_page]]" - | ".code_page" - | "" - | NULL - -*/ -int parse_locale(const char *locale, char *lang, char *country, char *code_page) -{ - while ( *locale != 0 && *locale != '.' && *locale != '_' ) - { - *lang = *locale; - lang++; - locale++; - } - *lang = 0; - if ( *locale == '_' ) { - locale++; - while ( *locale != 0 && *locale != '.' ) - { - *country = *locale; - country++; - locale++; - } - } - *country = 0; - - - if ( *locale == '.' ) { - locale++; - while ( *locale != 0 && *locale != '.' ) - { - *code_page = *locale; - code_page++; - locale++; - } - } - - *code_page = 0; - return 0; -} - -const struct map_lcid2str { - short langid; - const char *langname; - const char *country; -} languages[]={ - {0x0409,"English", "United States"}, - {0x0809,"English", "United Kingdom"}, - {0x0000,"Unknown", "Unknown"} - -}; - -const struct map_cntr { - const char *abrev; - const char *country; -} abrev[] = { - {"britain", "united kingdom"}, - {"england", "united kingdom"}, - {"gbr", "united kingdom"}, - {"great britain", "united kingdom"}, - {"uk", "united kingdom"}, - {"united kingdom", "united kingdom"}, - {"united-kingdom", "united kingdom"}, - {"america", "united states" }, - {"united states", "united states"}, - {"united-states", "united states"}, - {"us", "united states"}, - {"usa", "united states"} -}; - - -struct lconv _lconv = { -".", // decimal_point -",", // thousands_sep -"", // grouping; -"DOL", // int_curr_symbol -"$", // currency_symbol -".", // mon_decimal_point -",", // mon_thousands_sep -"", // mon_grouping; -"+", // positive_sign -"-", // negative_sign -127, // int_frac_digits -127, // frac_digits -127, // p_cs_precedes -127, // p_sep_by_space -127, // n_cs_precedes -127, // n_sep_by_space -127, // p_sign_posn; -127 // n_sign_posn; -}; - -/* - * @implemented +/********************************************************************* + * _Getdays (MSVCRT.@) */ -struct lconv *localeconv(void) +char* CDECL _Getdays(void) { - return (struct lconv *) &_lconv; + MSVCRT___lc_time_data *cur = get_locinfo()->lc_time_curr; + int i, len, size; + char *out; + + TRACE("\n"); + + size = cur->str.names.short_mon[0]-cur->str.names.short_wday[0]; + out = malloc(size+1); + if(!out) + return NULL; + + size = 0; + for(i=0; i<7; i++) { + out[size++] = ':'; + len = strlen(cur->str.names.short_wday[i]); + memcpy(&out[size], cur->str.names.short_wday[i], len); + size += len; + + out[size++] = ':'; + len = strlen(cur->str.names.wday[i]); + memcpy(&out[size], cur->str.names.wday[i], len); + size += len; + } + out[size] = '\0'; + + return out; } /********************************************************************* - * _setmbcp (MSVCRT.@) - * @implemented + * _Getmonths (MSVCRT.@) */ -int CDECL _setmbcp(int cp) +char* CDECL _Getmonths(void) { - int newcp; - CPINFO cpi; - BYTE *bytes; - WORD chartypes[256]; - WORD *curr_type; - char bufA[256]; - WCHAR bufW[256]; - int charcount; - int ret; - int i; + MSVCRT___lc_time_data *cur = get_locinfo()->lc_time_curr; + int i, len, size; + char *out; - TRACE("_setmbcp %d\n",cp); - switch (cp) - { - case _MB_CP_ANSI: - newcp = GetACP(); - break; - case _MB_CP_OEM: - newcp = GetOEMCP(); - break; - case _MB_CP_LOCALE: - newcp = MSVCRT___lc_codepage; - break; - case _MB_CP_SBCS: - newcp = 20127; /* ASCII */ - break; - default: - newcp = cp; - break; - } + TRACE("\n"); - if (!GetCPInfo(newcp, &cpi)) - { - ERR("Codepage %d not found\n", newcp); - _set_errno(EINVAL); - return -1; - } + size = cur->str.names.am-cur->str.names.short_mon[0]; + out = malloc(size+1); + if(!out) + return NULL; - /* setup the _mbctype */ - memset(_mbctype, 0, sizeof(_mbctype)); + size = 0; + for(i=0; i<12; i++) { + out[size++] = ':'; + len = strlen(cur->str.names.short_mon[i]); + memcpy(&out[size], cur->str.names.short_mon[i], len); + size += len; - bytes = cpi.LeadByte; - while (bytes[0] || bytes[1]) - { - for (i = bytes[0]; i <= bytes[1]; i++) - _mbctype[i + 1] |= _M1; - bytes += 2; - } - - if (cpi.MaxCharSize > 1) - { - /* trail bytes not available through kernel32 but stored in a structure in msvcrt */ - struct cp_extra_info_t *cpextra = g_cpextrainfo; - - g_mbcp_is_multibyte = 1; - while (TRUE) - { - if (cpextra->cp == 0 || cpextra->cp == newcp) - { - if (cpextra->cp == 0) - ERR("trail bytes data not available for DBCS codepage %d - assuming all bytes\n", newcp); - - bytes = cpextra->TrailBytes; - while (bytes[0] || bytes[1]) - { - for (i = bytes[0]; i <= bytes[1]; i++) - _mbctype[i + 1] |= _M2; - bytes += 2; - } - break; - } - cpextra++; + out[size++] = ':'; + len = strlen(cur->str.names.mon[i]); + memcpy(&out[size], cur->str.names.mon[i], len); + size += len; } - } - else - g_mbcp_is_multibyte = 0; + out[size] = '\0'; - /* we can't use GetStringTypeA directly because we don't have a locale - only a code page - */ - charcount = 0; - for (i = 0; i < 256; i++) - if (!(_mbctype[i + 1] & _M1)) - bufA[charcount++] = i; + return out; +} - ret = MultiByteToWideChar(newcp, 0, bufA, charcount, bufW, charcount); - if (ret != charcount) - ERR("MultiByteToWideChar of chars failed for cp %d, ret=%d (exp %d), error=%d\n", newcp, ret, charcount, GetLastError()); +/********************************************************************* + * _Gettnames (MSVCRT.@) + */ +void* CDECL _Gettnames(void) +{ + MSVCRT___lc_time_data *ret, *cur = get_locinfo()->lc_time_curr; + int i, size = sizeof(MSVCRT___lc_time_data); - GetStringTypeW(CT_CTYPE1, bufW, charcount, chartypes); + TRACE("\n"); - curr_type = chartypes; - for (i = 0; i < 256; i++) - if (!(_mbctype[i + 1] & _M1)) - { - if ((*curr_type) & C1_UPPER) - _mbctype[i + 1] |= _SBUP; - if ((*curr_type) & C1_LOWER) - _mbctype[i + 1] |= _SBLOW; - curr_type++; + for(i=0; istr.str)/sizeof(cur->str.str[0]); i++) + size += strlen(cur->str.str[i])+1; + + ret = malloc(size); + if(!ret) + return NULL; + memcpy(ret, cur, size); + + size = 0; + for(i=0; istr.str)/sizeof(cur->str.str[0]); i++) { + ret->str.str[i] = &ret->data[size]; + size += strlen(&ret->data[size])+1; } - if (newcp == 932) /* CP932 only - set _MP and _MS */ - { - /* On Windows it's possible to calculate the _MP and _MS from CT_CTYPE1 - * and CT_CTYPE3. But as of Wine 0.9.43 we return wrong values what makes - * it hard. As this is set only for codepage 932 we hardcode it what gives - * also faster execution. - */ - for (i = 161; i <= 165; i++) - _mbctype[i + 1] |= _MP; - for (i = 166; i <= 223; i++) - _mbctype[i + 1] |= _MS; - } - - MSVCRT___lc_collate_cp = MSVCRT___lc_codepage = newcp; - TRACE("(%d) -> %d\n", cp, MSVCRT___lc_codepage); - return 0; -} - - -/********************************************************************* - * ___lc_handle_func (MSVCRT.@) - */ -HANDLE * CDECL ___lc_handle_func(void) -{ - return MSVCRT___lc_handle; -} - - -/********************************************************************* - * ___lc_codepage_func (MSVCRT.@) - */ -int CDECL ___lc_codepage_func(void) -{ - return MSVCRT___lc_codepage; -} - - -/********************************************************************* - * _Gettnames (MSVCRT.@) - */ -void *_Gettnames(void) -{ - FIXME("(void), stub!\n"); - return NULL; + return ret; } /********************************************************************* - * __lconv_init (MSVCRT.@) + * __crtLCMapStringA (MSVCRT.@) */ -void __lconv_init(void) -{ - char Char = (char) UCHAR_MAX; - - TRACE("__lconv_init()\n"); - - _lconv.int_frac_digits = Char; - _lconv.frac_digits = Char; - _lconv.p_sep_by_space = _lconv.n_sep_by_space = Char; - _lconv.p_cs_precedes = _lconv.n_cs_precedes = Char; - _lconv.p_sign_posn = _lconv.n_sign_posn = Char; -} - - -/********************************************************************* - * _Strftime (MSVCRT.@) - */ -const char* _Strftime(char *out, unsigned int len, const char *fmt, - const void *tm, void *foo) -{ - /* FIXME: */ - FIXME("(%p %d %s %p %p) stub\n", out, len, fmt, tm, foo); - return ""; -} - - -/********************************************************************* - * _Getdays (MSVCRT.@) - */ -const char* _Getdays(void) -{ - static const char *MSVCRT_days = ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:" - "Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday"; - /* FIXME: Use locale */ - FIXME("(void) semi-stub\n"); - return MSVCRT_days; -} - -/********************************************************************* - * _Getmonths (MSVCRT.@) - */ -const char* _Getmonths(void) -{ - static const char *MSVCRT_months = ":Jan:January:Feb:February:Mar:March:Apr:" - "April:May:May:Jun:June:Jul:July:Aug:August:Sep:September:Oct:" - "October:Nov:November:Dec:December"; - /* FIXME: Use locale */ - FIXME("(void) semi-stub\n"); - return MSVCRT_months; -} - -/********************************************************************* - * __crtLCMapStringA (MSVCRT.@) - */ -int __crtLCMapStringA( +int CDECL __crtLCMapStringA( LCID lcid, DWORD mapflags, const char* src, int srclen, char* dst, int dstlen, unsigned int codepage, int xflag ) { - TRACE("(lcid %lx, flags %lx, %s(%d), %p(%d), %x, %d), partial stub!\n", + FIXME("(lcid %x, flags %x, %s(%d), %p(%d), %x, %d), partial stub!\n", lcid,mapflags,src,srclen,dst,dstlen,codepage,xflag); /* FIXME: A bit incorrect. But msvcrt itself just converts its * arguments to wide strings and then calls LCMapStringW @@ -852,37 +516,64 @@ int __crtLCMapStringA( } /********************************************************************* - * __crtLCMapStringW (MSVCRT.@) + * __crtLCMapStringW (MSVCRT.@) */ -int __crtLCMapStringW( - LCID lcid, DWORD mapflags, LPCWSTR src, int srclen, LPWSTR dst, - int dstlen, unsigned int codepage, int xflag -) { - TRACE("(lcid %lx, flags %lx, %s(%d), %p(%d), %x, %d), partial stub!\n", - lcid,mapflags,src,srclen,dst,dstlen,codepage,xflag); - - return LCMapStringW(lcid,mapflags,src,srclen,dst,dstlen); -} - -int CDECL _getmbcp(void) +int CDECL __crtLCMapStringW(LCID lcid, DWORD mapflags, const wchar_t *src, + int srclen, wchar_t *dst, int dstlen, unsigned int codepage, int xflag) { - return MSVCRT___lc_codepage; + FIXME("(lcid %x, flags %x, %s(%d), %p(%d), %x, %d), partial stub!\n", + lcid, mapflags, debugstr_w(src), srclen, dst, dstlen, codepage, xflag); + + return LCMapStringW(lcid, mapflags, src, srclen, dst, dstlen); } /********************************************************************* - * ___unguarded_readlc_active_add_func (MSVCRT.@) + * __crtCompareStringA (MSVCRT.@) */ -unsigned int * CDECL ___unguarded_readlc_active_add_func(void) +int CDECL __crtCompareStringA( LCID lcid, DWORD flags, const char *src1, int len1, + const char *src2, int len2 ) { - return &__unguarded_readlc_active; + FIXME("(lcid %x, flags %x, %s(%d), %s(%d), partial stub\n", + lcid, flags, debugstr_a(src1), len1, debugstr_a(src2), len2 ); + /* FIXME: probably not entirely right */ + return CompareStringA( lcid, flags, src1, len1, src2, len2 ); } /********************************************************************* - * ___setlc_active_func (MSVCRT.@) + * __crtCompareStringW (MSVCRT.@) */ -unsigned int CDECL ___setlc_active_func(void) +int CDECL __crtCompareStringW( LCID lcid, DWORD flags, const wchar_t *src1, int len1, + const wchar_t *src2, int len2 ) { - return __setlc_active; + FIXME("(lcid %x, flags %x, %s(%d), %s(%d), partial stub\n", + lcid, flags, debugstr_w(src1), len1, debugstr_w(src2), len2 ); + /* FIXME: probably not entirely right */ + return CompareStringW( lcid, flags, src1, len1, src2, len2 ); +} + +/********************************************************************* + * __crtGetLocaleInfoW (MSVCRT.@) + */ +int CDECL __crtGetLocaleInfoW( LCID lcid, LCTYPE type, wchar_t *buffer, int len ) +{ + FIXME("(lcid %x, type %x, %p(%d), partial stub\n", lcid, type, buffer, len ); + /* FIXME: probably not entirely right */ + return GetLocaleInfoW( lcid, type, buffer, len ); +} + +/********************************************************************* + * btowc(MSVCRT.@) + */ +wint_t CDECL MSVCRT_btowc(int c) +{ + unsigned char letter = c; + wchar_t ret; + + if(!MultiByteToWideChar(get_locinfo()->lc_handle[LC_CTYPE], + 0, (LPCSTR)&letter, 1, &ret, 1)) + return 0; + + return ret; } /********************************************************************* @@ -899,3 +590,920 @@ BOOL CDECL __crtGetStringTypeW(DWORD unk, DWORD type, return GetStringTypeW(type, buffer, len, out); } + +/********************************************************************* + * localeconv (MSVCRT.@) + */ +struct lconv * CDECL localeconv(void) +{ + return (struct lconv*)get_locinfo()->lconv; +} + +/********************************************************************* + * __lconv_init (MSVCRT.@) + */ +int CDECL __lconv_init(void) +{ + /* this is used to make chars unsigned */ + charmax = 255; + return 0; +} + +/********************************************************************* + * ___lc_handle_func (MSVCRT.@) + */ +LCID* CDECL ___lc_handle_func(void) +{ + return MSVCRT___lc_handle; +} + +/********************************************************************* + * ___lc_codepage_func (MSVCRT.@) + */ +unsigned int CDECL ___lc_codepage_func(void) +{ + return MSVCRT___lc_codepage; +} + +/********************************************************************* + * ___lc_collate_cp_func (MSVCRT.@) + */ +int CDECL ___lc_collate_cp_func(void) +{ + return get_locinfo()->lc_collate_cp; +} + +/* INTERNAL: frees MSVCRT_pthreadlocinfo struct */ +void free_locinfo(MSVCRT_pthreadlocinfo locinfo) +{ + int i; + + if(!locinfo) + return; + + if(InterlockedDecrement(&locinfo->refcount)) + return; + + for(i=LC_MIN+1; i<=LC_MAX; i++) { + free(locinfo->lc_category[i].locale); + free(locinfo->lc_category[i].refcount); + } + + if(locinfo->lconv) { + free(locinfo->lconv->decimal_point); + free(locinfo->lconv->thousands_sep); + free(locinfo->lconv->grouping); + free(locinfo->lconv->int_curr_symbol); + free(locinfo->lconv->currency_symbol); + free(locinfo->lconv->mon_decimal_point); + free(locinfo->lconv->mon_thousands_sep); + free(locinfo->lconv->mon_grouping); + free(locinfo->lconv->positive_sign); + free(locinfo->lconv->negative_sign); + } + free(locinfo->lconv_intl_refcount); + free(locinfo->lconv_num_refcount); + free(locinfo->lconv_mon_refcount); + free(locinfo->lconv); + + free(locinfo->ctype1_refcount); + free(locinfo->ctype1); + + free(locinfo->pclmap); + free(locinfo->pcumap); + + free(locinfo->lc_time_curr); + + free(locinfo); +} + +/* INTERNAL: frees MSVCRT_pthreadmbcinfo struct */ +void free_mbcinfo(MSVCRT_pthreadmbcinfo mbcinfo) +{ + if(!mbcinfo) + return; + + if(InterlockedDecrement(&mbcinfo->refcount)) + return; + + free(mbcinfo); +} + +/* _get_current_locale - not exported in native msvcrt */ +MSVCRT__locale_t CDECL MSVCRT__get_current_locale(void) +{ + MSVCRT__locale_t loc = malloc(sizeof(MSVCRT__locale_tstruct)); + if(!loc) + return NULL; + + loc->locinfo = get_locinfo(); + loc->mbcinfo = get_mbcinfo(); + InterlockedIncrement(&loc->locinfo->refcount); + InterlockedIncrement(&loc->mbcinfo->refcount); + return loc; +} + +/* _free_locale - not exported in native msvcrt */ +void CDECL MSVCRT__free_locale(MSVCRT__locale_t locale) +{ + if (!locale) + return; + + free_locinfo(locale->locinfo); + free_mbcinfo(locale->mbcinfo); + free(locale); +} + +/* _create_locale - not exported in native msvcrt */ +MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale) +{ + static const DWORD time_data[] = { + LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, + LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, + LOCALE_SABBREVDAYNAME6, + LOCALE_SDAYNAME7, LOCALE_SDAYNAME1, LOCALE_SDAYNAME2, LOCALE_SDAYNAME3, + LOCALE_SDAYNAME4, LOCALE_SDAYNAME5, LOCALE_SDAYNAME6, + LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3, + LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, + LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9, + LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12, + LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3, LOCALE_SMONTHNAME4, + LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6, LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, + LOCALE_SMONTHNAME9, LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12, + LOCALE_S1159, LOCALE_S2359, + LOCALE_SSHORTDATE, LOCALE_SLONGDATE, + LOCALE_STIMEFORMAT + }; + static const char collate[] = "COLLATE="; + static const char ctype[] = "CTYPE="; + static const char monetary[] = "MONETARY="; + static const char numeric[] = "NUMERIC="; + static const char time[] = "TIME="; + static const char cloc_short_date[] = "MM/dd/yy"; + static const wchar_t cloc_short_dateW[] = {'M','M','/','d','d','/','y','y',0}; + static const char cloc_long_date[] = "dddd, MMMM dd, yyyy"; + static const wchar_t cloc_long_dateW[] = {'d','d','d','d',',',' ','M','M','M','M',' ','d','d',',',' ','y','y','y','y',0}; + static const char cloc_time[] = "HH:mm:ss"; + static const wchar_t cloc_timeW[] = {'H','H',':','m','m',':','s','s',0}; + + MSVCRT__locale_t loc; + LCID lcid[6] = { 0 }, lcid_tmp; + char buf[256]; + int i, ret, size; + + TRACE("(%d %s)\n", category, locale); + + if(categoryLC_MAX || !locale) + return NULL; + + if(locale[0]=='C' && !locale[1]) + lcid[0] = CP_ACP; + else if(!locale[0]) + lcid[0] = GetSystemDefaultLCID(); + else if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_') { + const char *p; + + while(1) { + locale += 3; /* LC_ */ + if(!memcmp(locale, collate, sizeof(collate)-1)) { + i = LC_COLLATE; + locale += sizeof(collate)-1; + } else if(!memcmp(locale, ctype, sizeof(ctype)-1)) { + i = LC_CTYPE; + locale += sizeof(ctype)-1; + } else if(!memcmp(locale, monetary, sizeof(monetary)-1)) { + i = LC_MONETARY; + locale += sizeof(monetary)-1; + } else if(!memcmp(locale, numeric, sizeof(numeric)-1)) { + i = LC_NUMERIC; + locale += sizeof(numeric)-1; + } else if(!memcmp(locale, time, sizeof(time)-1)) { + i = LC_TIME; + locale += sizeof(time)-1; + } else + return NULL; + + p = strchr(locale, ';'); + if(locale[0]=='C' && (locale[1]==';' || locale[1]=='\0')) + lcid[i] = 0; + else if(p) { + memcpy(buf, locale, p-locale); + buf[p-locale] = '\0'; + lcid[i] = MSVCRT_locale_to_LCID(buf); + } else + lcid[i] = MSVCRT_locale_to_LCID(locale); + + if(lcid[i] == -1) + return NULL; + + if(!p || *(p+1)!='L' || *(p+2)!='C' || *(p+3)!='_') + break; + + locale = p+1; + } + } else { + lcid[0] = MSVCRT_locale_to_LCID(locale); + if(lcid[0] == -1) + return NULL; + } + + for(i=1; i<6; i++) { + if(!lcid[i]) + lcid[i] = lcid[0]; + } + + loc = malloc(sizeof(MSVCRT__locale_tstruct)); + if(!loc) + return NULL; + + loc->locinfo = malloc(sizeof(MSVCRT_threadlocinfo)); + if(!loc->locinfo) { + free(loc); + return NULL; + } + + loc->mbcinfo = malloc(sizeof(MSVCRT_threadmbcinfo)); + if(!loc->mbcinfo) { + free(loc->locinfo); + free(loc); + return NULL; + } + + memset(loc->locinfo, 0, sizeof(MSVCRT_threadlocinfo)); + loc->locinfo->refcount = 1; + loc->mbcinfo->refcount = 1; + + loc->locinfo->lconv = malloc(sizeof(struct MSVCRT_lconv)); + if(!loc->locinfo->lconv) { + MSVCRT__free_locale(loc); + return NULL; + } + memset(loc->locinfo->lconv, 0, sizeof(struct MSVCRT_lconv)); + + loc->locinfo->pclmap = malloc(sizeof(char[256])); + loc->locinfo->pcumap = malloc(sizeof(char[256])); + if(!loc->locinfo->pclmap || !loc->locinfo->pcumap) { + MSVCRT__free_locale(loc); + return NULL; + } + + if(lcid[LC_COLLATE] && (category==LC_ALL || category==LC_COLLATE)) { + if(update_threadlocinfo_category(lcid[LC_COLLATE], loc, LC_COLLATE)) { + MSVCRT__free_locale(loc); + return NULL; + } + + loc->locinfo->lc_collate_cp = loc->locinfo->lc_id[LC_COLLATE].wCodePage; + } else + loc->locinfo->lc_category[LC_COLLATE].locale = _strdup("C"); + + if(lcid[LC_CTYPE] && (category==LC_ALL || category==LC_CTYPE)) { + CPINFO cp; + int j; + + if(update_threadlocinfo_category(lcid[LC_CTYPE], loc, LC_CTYPE)) { + MSVCRT__free_locale(loc); + return NULL; + } + + loc->locinfo->lc_codepage = loc->locinfo->lc_id[LC_CTYPE].wCodePage; + loc->locinfo->lc_clike = 1; + if(!GetCPInfo(loc->locinfo->lc_codepage, &cp)) { + MSVCRT__free_locale(loc); + return NULL; + } + loc->locinfo->mb_cur_max = cp.MaxCharSize; + + loc->locinfo->ctype1_refcount = malloc(sizeof(int)); + loc->locinfo->ctype1 = malloc(sizeof(short[257])); + if(!loc->locinfo->ctype1_refcount || !loc->locinfo->ctype1) { + MSVCRT__free_locale(loc); + return NULL; + } + + *loc->locinfo->ctype1_refcount = 1; + loc->locinfo->ctype1[0] = 0; + loc->locinfo->pctype = loc->locinfo->ctype1+1; + + buf[1] = buf[2] = '\0'; + for(i=1; i<257; i++) { + buf[0] = i-1; + + /* builtin GetStringTypeA doesn't set output to 0 on invalid input */ + loc->locinfo->ctype1[i] = 0; + + GetStringTypeA(lcid[LC_CTYPE], CT_CTYPE1, buf, + 1, loc->locinfo->ctype1+i); + } + + for(i=0; cp.LeadByte[i+1]!=0; i+=2) + for(j=cp.LeadByte[i]; j<=cp.LeadByte[i+1]; j++) + loc->locinfo->ctype1[j+1] |= _LEADBYTE; + } else { + loc->locinfo->lc_clike = 1; + loc->locinfo->mb_cur_max = 1; + loc->locinfo->pctype = _ctype+1; + loc->locinfo->lc_category[LC_CTYPE].locale = _strdup("C"); + } + + for(i=0; i<256; i++) { + if(loc->locinfo->pctype[i] & _LEADBYTE) + buf[i] = ' '; + else + buf[i] = i; + + } + + if(lcid[LC_CTYPE]) { + LCMapStringA(lcid[LC_CTYPE], LCMAP_LOWERCASE, buf, 256, + (char*)loc->locinfo->pclmap, 256); + LCMapStringA(lcid[LC_CTYPE], LCMAP_UPPERCASE, buf, 256, + (char*)loc->locinfo->pcumap, 256); + } else { + for(i=0; i<256; i++) { + loc->locinfo->pclmap[i] = (i>='A' && i<='Z' ? i-'A'+'a' : i); + loc->locinfo->pcumap[i] = (i>='a' && i<='z' ? i-'a'+'A' : i); + } + } + + _setmbcp_l(loc->locinfo->lc_id[LC_CTYPE].wCodePage, lcid[LC_CTYPE], loc->mbcinfo); + + if(lcid[LC_MONETARY] && (category==LC_ALL || category==LC_MONETARY)) { + if(update_threadlocinfo_category(lcid[LC_MONETARY], loc, LC_MONETARY)) { + MSVCRT__free_locale(loc); + return NULL; + } + + loc->locinfo->lconv_intl_refcount = malloc(sizeof(int)); + loc->locinfo->lconv_mon_refcount = malloc(sizeof(int)); + if(!loc->locinfo->lconv_intl_refcount || !loc->locinfo->lconv_mon_refcount) { + MSVCRT__free_locale(loc); + return NULL; + } + + *loc->locinfo->lconv_intl_refcount = 1; + *loc->locinfo->lconv_mon_refcount = 1; + + i = GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_SINTLSYMBOL + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i && (loc->locinfo->lconv->int_curr_symbol = malloc(i))) + memcpy(loc->locinfo->lconv->int_curr_symbol, buf, i); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + i = GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_SCURRENCY + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i && (loc->locinfo->lconv->currency_symbol = malloc(i))) + memcpy(loc->locinfo->lconv->currency_symbol, buf, i); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + i = GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_SMONDECIMALSEP + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i && (loc->locinfo->lconv->mon_decimal_point = malloc(i))) + memcpy(loc->locinfo->lconv->mon_decimal_point, buf, i); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + i = GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_SMONTHOUSANDSEP + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i && (loc->locinfo->lconv->mon_thousands_sep = malloc(i))) + memcpy(loc->locinfo->lconv->mon_thousands_sep, buf, i); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + i = GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_SMONGROUPING + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i>1) + i = i/2 + (buf[i-2]=='0'?0:1); + if(i && (loc->locinfo->lconv->mon_grouping = malloc(i))) { + for(i=0; buf[i+1]==';'; i+=2) + loc->locinfo->lconv->mon_grouping[i/2] = buf[i]-'0'; + loc->locinfo->lconv->mon_grouping[i/2] = buf[i]-'0'; + if(buf[i] != '0') + loc->locinfo->lconv->mon_grouping[i/2+1] = 127; + } else { + MSVCRT__free_locale(loc); + return NULL; + } + + i = GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_SPOSITIVESIGN + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i && (loc->locinfo->lconv->positive_sign = malloc(i))) + memcpy(loc->locinfo->lconv->positive_sign, buf, i); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + i = GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_SNEGATIVESIGN + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i && (loc->locinfo->lconv->negative_sign = malloc(i))) + memcpy(loc->locinfo->lconv->negative_sign, buf, i); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + if(GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_IINTLCURRDIGITS + |LOCALE_NOUSEROVERRIDE, buf, 256)) + loc->locinfo->lconv->int_frac_digits = atoi(buf); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + if(GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_ICURRDIGITS + |LOCALE_NOUSEROVERRIDE, buf, 256)) + loc->locinfo->lconv->frac_digits = atoi(buf); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + if(GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_IPOSSYMPRECEDES + |LOCALE_NOUSEROVERRIDE, buf, 256)) + loc->locinfo->lconv->p_cs_precedes = atoi(buf); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + if(GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_IPOSSEPBYSPACE + |LOCALE_NOUSEROVERRIDE, buf, 256)) + loc->locinfo->lconv->p_sep_by_space = atoi(buf); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + if(GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_INEGSYMPRECEDES + |LOCALE_NOUSEROVERRIDE, buf, 256)) + loc->locinfo->lconv->n_cs_precedes = atoi(buf); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + if(GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_INEGSEPBYSPACE + |LOCALE_NOUSEROVERRIDE, buf, 256)) + loc->locinfo->lconv->n_sep_by_space = atoi(buf); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + if(GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_IPOSSIGNPOSN + |LOCALE_NOUSEROVERRIDE, buf, 256)) + loc->locinfo->lconv->p_sign_posn = atoi(buf); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + if(GetLocaleInfoA(lcid[LC_MONETARY], LOCALE_INEGSIGNPOSN + |LOCALE_NOUSEROVERRIDE, buf, 256)) + loc->locinfo->lconv->n_sign_posn = atoi(buf); + else { + MSVCRT__free_locale(loc); + return NULL; + } + } else { + loc->locinfo->lconv->int_curr_symbol = malloc(sizeof(char)); + loc->locinfo->lconv->currency_symbol = malloc(sizeof(char)); + loc->locinfo->lconv->mon_decimal_point = malloc(sizeof(char)); + loc->locinfo->lconv->mon_thousands_sep = malloc(sizeof(char)); + loc->locinfo->lconv->mon_grouping = malloc(sizeof(char)); + loc->locinfo->lconv->positive_sign = malloc(sizeof(char)); + loc->locinfo->lconv->negative_sign = malloc(sizeof(char)); + + if(!loc->locinfo->lconv->int_curr_symbol || !loc->locinfo->lconv->currency_symbol + || !loc->locinfo->lconv->mon_decimal_point || !loc->locinfo->lconv->mon_thousands_sep + || !loc->locinfo->lconv->mon_grouping || !loc->locinfo->lconv->positive_sign + || !loc->locinfo->lconv->negative_sign) { + MSVCRT__free_locale(loc); + return NULL; + } + + loc->locinfo->lconv->int_curr_symbol[0] = '\0'; + loc->locinfo->lconv->currency_symbol[0] = '\0'; + loc->locinfo->lconv->mon_decimal_point[0] = '\0'; + loc->locinfo->lconv->mon_thousands_sep[0] = '\0'; + loc->locinfo->lconv->mon_grouping[0] = '\0'; + loc->locinfo->lconv->positive_sign[0] = '\0'; + loc->locinfo->lconv->negative_sign[0] = '\0'; + loc->locinfo->lconv->int_frac_digits = 127; + loc->locinfo->lconv->frac_digits = 127; + loc->locinfo->lconv->p_cs_precedes = 127; + loc->locinfo->lconv->p_sep_by_space = 127; + loc->locinfo->lconv->n_cs_precedes = 127; + loc->locinfo->lconv->n_sep_by_space = 127; + loc->locinfo->lconv->p_sign_posn = 127; + loc->locinfo->lconv->n_sign_posn = 127; + + loc->locinfo->lc_category[LC_MONETARY].locale = _strdup("C"); + } + + if(lcid[LC_NUMERIC] && (category==LC_ALL || category==LC_NUMERIC)) { + if(update_threadlocinfo_category(lcid[LC_NUMERIC], loc, LC_NUMERIC)) { + MSVCRT__free_locale(loc); + return NULL; + } + + if(!loc->locinfo->lconv_intl_refcount) + loc->locinfo->lconv_intl_refcount = malloc(sizeof(int)); + loc->locinfo->lconv_num_refcount = malloc(sizeof(int)); + if(!loc->locinfo->lconv_intl_refcount || !loc->locinfo->lconv_num_refcount) { + MSVCRT__free_locale(loc); + return NULL; + } + + *loc->locinfo->lconv_intl_refcount = 1; + *loc->locinfo->lconv_num_refcount = 1; + + i = GetLocaleInfoA(lcid[LC_NUMERIC], LOCALE_SDECIMAL + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i && (loc->locinfo->lconv->decimal_point = malloc(i))) + memcpy(loc->locinfo->lconv->decimal_point, buf, i); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + i = GetLocaleInfoA(lcid[LC_NUMERIC], LOCALE_STHOUSAND + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i && (loc->locinfo->lconv->thousands_sep = malloc(i))) + memcpy(loc->locinfo->lconv->thousands_sep, buf, i); + else { + MSVCRT__free_locale(loc); + return NULL; + } + + i = GetLocaleInfoA(lcid[LC_NUMERIC], LOCALE_SGROUPING + |LOCALE_NOUSEROVERRIDE, buf, 256); + if(i>1) + i = i/2 + (buf[i-2]=='0'?0:1); + if(i && (loc->locinfo->lconv->grouping = malloc(i))) { + for(i=0; buf[i+1]==';'; i+=2) + loc->locinfo->lconv->grouping[i/2] = buf[i]-'0'; + loc->locinfo->lconv->grouping[i/2] = buf[i]-'0'; + if(buf[i] != '0') + loc->locinfo->lconv->grouping[i/2+1] = 127; + } else { + MSVCRT__free_locale(loc); + return NULL; + } + } else { + loc->locinfo->lconv->decimal_point = malloc(sizeof(char[2])); + loc->locinfo->lconv->thousands_sep = malloc(sizeof(char)); + loc->locinfo->lconv->grouping = malloc(sizeof(char)); + if(!loc->locinfo->lconv->decimal_point || !loc->locinfo->lconv->thousands_sep + || !loc->locinfo->lconv->grouping) { + MSVCRT__free_locale(loc); + return NULL; + } + + loc->locinfo->lconv->decimal_point[0] = '.'; + loc->locinfo->lconv->decimal_point[1] = '\0'; + loc->locinfo->lconv->thousands_sep[0] = '\0'; + loc->locinfo->lconv->grouping[0] = '\0'; + + loc->locinfo->lc_category[LC_NUMERIC].locale = _strdup("C"); + } + + if(lcid[LC_TIME] && (category==LC_ALL || category==LC_TIME)) { + if(update_threadlocinfo_category(lcid[LC_TIME], loc, LC_TIME)) { + MSVCRT__free_locale(loc); + return NULL; + } + } else + loc->locinfo->lc_category[LC_TIME].locale = _strdup("C"); + + size = sizeof(MSVCRT___lc_time_data); + lcid_tmp = lcid[LC_TIME] ? lcid[LC_TIME] : MAKELCID(LANG_ENGLISH, SORT_DEFAULT); + for(i=0; ilocinfo->lc_time_curr = malloc(size); + if(!loc->locinfo->lc_time_curr) { + MSVCRT__free_locale(loc); + return NULL; + } + + ret = 0; + for(i=0; ilocinfo->lc_time_curr->str.str[i] = &loc->locinfo->lc_time_curr->data[ret]; + if(time_data[i]==LOCALE_SSHORTDATE && !lcid[LC_TIME]) { + memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_short_date, sizeof(cloc_short_date)); + ret += sizeof(cloc_short_date); + }else if(time_data[i]==LOCALE_SSHORTDATE && !lcid[LC_TIME]) { + memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_long_date, sizeof(cloc_long_date)); + ret += sizeof(cloc_long_date); + }else if(time_data[i]==LOCALE_STIMEFORMAT && !lcid[LC_TIME]) { + memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_time, sizeof(cloc_time)); + ret += sizeof(cloc_time); + }else { + ret += GetLocaleInfoA(lcid_tmp, time_data[i]|LOCALE_NOUSEROVERRIDE, + &loc->locinfo->lc_time_curr->data[ret], size-ret); + } + } + for(i=0; ilocinfo->lc_time_curr->wstr[i] = (wchar_t*)&loc->locinfo->lc_time_curr->data[ret]; + if(time_data[i]==LOCALE_SSHORTDATE && !lcid[LC_TIME]) { + memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_short_dateW, sizeof(cloc_short_dateW)); + ret += sizeof(cloc_short_dateW); + }else if(time_data[i]==LOCALE_SSHORTDATE && !lcid[LC_TIME]) { + memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_long_dateW, sizeof(cloc_long_dateW)); + ret += sizeof(cloc_long_dateW); + }else if(time_data[i]==LOCALE_STIMEFORMAT && !lcid[LC_TIME]) { + memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_timeW, sizeof(cloc_timeW)); + ret += sizeof(cloc_timeW); + }else { + ret += GetLocaleInfoW(lcid_tmp, time_data[i]|LOCALE_NOUSEROVERRIDE, + (wchar_t*)&loc->locinfo->lc_time_curr->data[ret], size-ret)*sizeof(wchar_t); + } + } + loc->locinfo->lc_time_curr->lcid = lcid[LC_TIME]; + + return loc; +} + +/********************************************************************* + * setlocale (MSVCRT.@) + */ +char* CDECL setlocale(int category, const char* locale) +{ + MSVCRT__locale_t loc; + MSVCRT_pthreadlocinfo locinfo = get_locinfo(); + + if(categoryLC_MAX) + return NULL; + + if(!locale) { + if(category == LC_ALL) + return construct_lc_all(locinfo); + + return locinfo->lc_category[category].locale; + } + + loc = MSVCRT__create_locale(category, locale); + if(!loc) { + WARN("%d %s failed\n", category, locale); + return NULL; + } + + LOCK_LOCALE; + + switch(category) { + case LC_ALL: + case LC_COLLATE: + locinfo->lc_collate_cp = loc->locinfo->lc_collate_cp; + locinfo->lc_handle[LC_COLLATE] = + loc->locinfo->lc_handle[LC_COLLATE]; + swap_pointers((void**)&locinfo->lc_category[LC_COLLATE].locale, + (void**)&loc->locinfo->lc_category[LC_COLLATE].locale); + swap_pointers((void**)&locinfo->lc_category[LC_COLLATE].refcount, + (void**)&loc->locinfo->lc_category[LC_COLLATE].refcount); + + if(category != LC_ALL) + break; + /* fall through */ + case LC_CTYPE: + locinfo->lc_handle[LC_CTYPE] = + loc->locinfo->lc_handle[LC_CTYPE]; + swap_pointers((void**)&locinfo->lc_category[LC_CTYPE].locale, + (void**)&loc->locinfo->lc_category[LC_CTYPE].locale); + swap_pointers((void**)&locinfo->lc_category[LC_CTYPE].refcount, + (void**)&loc->locinfo->lc_category[LC_CTYPE].refcount); + + locinfo->lc_codepage = loc->locinfo->lc_codepage; + locinfo->lc_clike = loc->locinfo->lc_clike; + locinfo->mb_cur_max = loc->locinfo->mb_cur_max; + + swap_pointers((void**)&locinfo->ctype1_refcount, + (void**)&loc->locinfo->ctype1_refcount); + swap_pointers((void**)&locinfo->ctype1, (void**)&loc->locinfo->ctype1); + swap_pointers((void**)&locinfo->pctype, (void**)&loc->locinfo->pctype); + swap_pointers((void**)&locinfo->pclmap, (void**)&loc->locinfo->pclmap); + swap_pointers((void**)&locinfo->pcumap, (void**)&loc->locinfo->pcumap); + + if(category != LC_ALL) + break; + /* fall through */ + case LC_MONETARY: + locinfo->lc_handle[LC_MONETARY] = + loc->locinfo->lc_handle[LC_MONETARY]; + swap_pointers((void**)&locinfo->lc_category[LC_MONETARY].locale, + (void**)&loc->locinfo->lc_category[LC_MONETARY].locale); + swap_pointers((void**)&locinfo->lc_category[LC_MONETARY].refcount, + (void**)&loc->locinfo->lc_category[LC_MONETARY].refcount); + + swap_pointers((void**)&locinfo->lconv->int_curr_symbol, + (void**)&loc->locinfo->lconv->int_curr_symbol); + swap_pointers((void**)&locinfo->lconv->currency_symbol, + (void**)&loc->locinfo->lconv->currency_symbol); + swap_pointers((void**)&locinfo->lconv->mon_decimal_point, + (void**)&loc->locinfo->lconv->mon_decimal_point); + swap_pointers((void**)&locinfo->lconv->mon_thousands_sep, + (void**)&loc->locinfo->lconv->mon_thousands_sep); + swap_pointers((void**)&locinfo->lconv->mon_grouping, + (void**)&loc->locinfo->lconv->mon_grouping); + swap_pointers((void**)&locinfo->lconv->positive_sign, + (void**)&loc->locinfo->lconv->positive_sign); + swap_pointers((void**)&locinfo->lconv->negative_sign, + (void**)&loc->locinfo->lconv->negative_sign); + locinfo->lconv->int_frac_digits = loc->locinfo->lconv->int_frac_digits; + locinfo->lconv->frac_digits = loc->locinfo->lconv->frac_digits; + locinfo->lconv->p_cs_precedes = loc->locinfo->lconv->p_cs_precedes; + locinfo->lconv->p_sep_by_space = loc->locinfo->lconv->p_sep_by_space; + locinfo->lconv->n_cs_precedes = loc->locinfo->lconv->n_cs_precedes; + locinfo->lconv->n_sep_by_space = loc->locinfo->lconv->n_sep_by_space; + locinfo->lconv->p_sign_posn = loc->locinfo->lconv->p_sign_posn; + locinfo->lconv->n_sign_posn = loc->locinfo->lconv->n_sign_posn; + + if(category != LC_ALL) + break; + /* fall through */ + case LC_NUMERIC: + locinfo->lc_handle[LC_NUMERIC] = + loc->locinfo->lc_handle[LC_NUMERIC]; + swap_pointers((void**)&locinfo->lc_category[LC_NUMERIC].locale, + (void**)&loc->locinfo->lc_category[LC_NUMERIC].locale); + swap_pointers((void**)&locinfo->lc_category[LC_NUMERIC].refcount, + (void**)&loc->locinfo->lc_category[LC_NUMERIC].refcount); + + swap_pointers((void**)&locinfo->lconv->decimal_point, + (void**)&loc->locinfo->lconv->decimal_point); + swap_pointers((void**)&locinfo->lconv->thousands_sep, + (void**)&loc->locinfo->lconv->thousands_sep); + swap_pointers((void**)&locinfo->lconv->grouping, + (void**)&loc->locinfo->lconv->grouping); + + if(category != LC_ALL) + break; + /* fall through */ + case LC_TIME: + locinfo->lc_handle[LC_TIME] = + loc->locinfo->lc_handle[LC_TIME]; + swap_pointers((void**)&locinfo->lc_category[LC_TIME].locale, + (void**)&loc->locinfo->lc_category[LC_TIME].locale); + swap_pointers((void**)&locinfo->lc_category[LC_TIME].refcount, + (void**)&loc->locinfo->lc_category[LC_TIME].refcount); + swap_pointers((void**)&locinfo->lc_time_curr, + (void**)&loc->locinfo->lc_time_curr); + + if(category != LC_ALL) + break; + } + + MSVCRT__free_locale(loc); + UNLOCK_LOCALE; + + if(locinfo == MSVCRT_locale->locinfo) { + int i; + + MSVCRT___lc_codepage = locinfo->lc_codepage; + MSVCRT___lc_collate_cp = locinfo->lc_collate_cp; + __mb_cur_max = locinfo->mb_cur_max; + _pctype = locinfo->pctype; + for(i=LC_MIN; i<=LC_MAX; i++) + MSVCRT___lc_handle[i] = MSVCRT_locale->locinfo->lc_handle[i]; + } + + if(category == LC_ALL) + return construct_lc_all(locinfo); + + return locinfo->lc_category[category].locale; +} + +/* _configthreadlocale - not exported in native msvcrt */ +int CDECL _configthreadlocale(int type) +{ + thread_data_t *data = msvcrt_get_thread_data(); + MSVCRT__locale_t locale; + int ret; + + if(!data) + return -1; + + ret = (data->have_locale ? _ENABLE_PER_THREAD_LOCALE : _DISABLE_PER_THREAD_LOCALE); + + if(type == _ENABLE_PER_THREAD_LOCALE) { + if(!data->have_locale) { + /* Copy current global locale */ + locale = MSVCRT__create_locale(LC_ALL, setlocale(LC_ALL, NULL)); + if(!locale) + return -1; + + data->locinfo = locale->locinfo; + data->mbcinfo = locale->mbcinfo; + data->have_locale = TRUE; + free(locale); + } + + return ret; + } + + if(type == _DISABLE_PER_THREAD_LOCALE) { + if(data->have_locale) { + free_locinfo(data->locinfo); + free_mbcinfo(data->mbcinfo); + data->locinfo = MSVCRT_locale->locinfo; + data->mbcinfo = MSVCRT_locale->mbcinfo; + data->have_locale = FALSE; + } + + return ret; + } + + if(!type) + return ret; + + return -1; +} + +/********************************************************************* + * _getmbcp (MSVCRT.@) + */ +int CDECL _getmbcp(void) +{ + return get_mbcinfo()->mbcodepage; +} + +extern unsigned int __setlc_active; +/********************************************************************* + * ___setlc_active_func (MSVCRT.@) + */ +unsigned int CDECL ___setlc_active_func(void) +{ + return __setlc_active; +} + +extern unsigned int __unguarded_readlc_active; +/********************************************************************* + * ___unguarded_readlc_active_add_func (MSVCRT.@) + */ +unsigned int * CDECL ___unguarded_readlc_active_add_func(void) +{ + return &__unguarded_readlc_active; +} + +MSVCRT__locale_t global_locale = NULL; +void __init_global_locale() +{ + unsigned i; + + LOCK_LOCALE; + global_locale = MSVCRT__create_locale(0, "C"); + + MSVCRT___lc_codepage = MSVCRT_locale->locinfo->lc_codepage; + MSVCRT___lc_collate_cp = MSVCRT_locale->locinfo->lc_collate_cp; + __mb_cur_max = MSVCRT_locale->locinfo->mb_cur_max; + for(i=LC_MIN; i<=LC_MAX; i++) + MSVCRT___lc_handle[i] = MSVCRT_locale->locinfo->lc_handle[i]; + _setmbcp(_MB_CP_ANSI); + UNLOCK_LOCALE; +} + +/* + * @implemented + */ +const unsigned short **__p__pctype(void) +{ + return &get_locinfo()->pctype; +} + +const unsigned short* __cdecl __pctype_func(void) +{ + return get_locinfo()->pctype; +} + diff --git a/lib/sdk/crt/mbstring/_setmbcp.c b/lib/sdk/crt/mbstring/_setmbcp.c new file mode 100644 index 00000000000..be23cc5899a --- /dev/null +++ b/lib/sdk/crt/mbstring/_setmbcp.c @@ -0,0 +1,222 @@ +/* + * msvcrt.dll mbcs functions + * + * Copyright 1999 Alexandre Julliard + * Copyright 2000 Jon Griffths + * + * 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 + * + * FIXME + * Not currently binary compatible with win32. MSVCRT_mbctype must be + * populated correctly and the ismb* functions should reference it. + */ + +#include + +#include + +/* It seems that the data about valid trail bytes is not available from kernel32 + * so we have to store is here. The format is the same as for lead bytes in CPINFO */ +struct cp_extra_info_t +{ + int cp; + BYTE TrailBytes[MAX_LEADBYTES]; +}; + +static struct cp_extra_info_t g_cpextrainfo[] = +{ + {932, {0x40, 0x7e, 0x80, 0xfc, 0, 0}}, + {936, {0x40, 0xfe, 0, 0}}, + {949, {0x41, 0xfe, 0, 0}}, + {950, {0x40, 0x7e, 0xa1, 0xfe, 0, 0}}, + {1361, {0x31, 0x7e, 0x81, 0xfe, 0, 0}}, + {20932, {1, 255, 0, 0}}, /* seems to give different results on different systems */ + {0, {1, 255, 0, 0}} /* match all with FIXME */ +}; + +/********************************************************************* + * INTERNAL: _setmbcp_l + */ +int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo) +{ + const char format[] = ".%d"; + + int newcp; + CPINFO cpi; + BYTE *bytes; + WORD chartypes[256]; + char bufA[256]; + WCHAR bufW[256]; + int charcount; + int ret; + int i; + + if(!mbcinfo) + mbcinfo = get_mbcinfo(); + + switch (cp) + { + case _MB_CP_ANSI: + newcp = GetACP(); + break; + case _MB_CP_OEM: + newcp = GetOEMCP(); + break; + case _MB_CP_LOCALE: + newcp = get_locinfo()->lc_codepage; + if(newcp) + break; + /* fall through (C locale) */ + case _MB_CP_SBCS: + newcp = 20127; /* ASCII */ + break; + default: + newcp = cp; + break; + } + + if(lcid == -1) { + sprintf(bufA, format, newcp); + mbcinfo->mblcid = MSVCRT_locale_to_LCID(bufA); + } else { + mbcinfo->mblcid = lcid; + } + + if(mbcinfo->mblcid == -1) + { + WARN("Can't assign LCID to codepage (%d)\n", mbcinfo->mblcid); + mbcinfo->mblcid = 0; + } + + if (!GetCPInfo(newcp, &cpi)) + { + WARN("Codepage %d not found\n", newcp); + *_errno() = EINVAL; + return -1; + } + + /* setup the _mbctype */ + memset(mbcinfo->mbctype, 0, sizeof(unsigned char[257])); + memset(mbcinfo->mbcasemap, 0, sizeof(unsigned char[256])); + + bytes = cpi.LeadByte; + while (bytes[0] || bytes[1]) + { + for (i = bytes[0]; i <= bytes[1]; i++) + mbcinfo->mbctype[i + 1] |= _M1; + bytes += 2; + } + + if (cpi.MaxCharSize > 1) + { + /* trail bytes not available through kernel32 but stored in a structure in msvcrt */ + struct cp_extra_info_t *cpextra = g_cpextrainfo; + + mbcinfo->ismbcodepage = 1; + while (TRUE) + { + if (cpextra->cp == 0 || cpextra->cp == newcp) + { + if (cpextra->cp == 0) + FIXME("trail bytes data not available for DBCS codepage %d - assuming all bytes\n", newcp); + + bytes = cpextra->TrailBytes; + while (bytes[0] || bytes[1]) + { + for (i = bytes[0]; i <= bytes[1]; i++) + mbcinfo->mbctype[i + 1] |= _M2; + bytes += 2; + } + break; + } + cpextra++; + } + } + else + mbcinfo->ismbcodepage = 0; + + /* we can't use GetStringTypeA directly because we don't have a locale - only a code page + */ + charcount = 0; + for (i = 0; i < 256; i++) + if (!(mbcinfo->mbctype[i + 1] & _M1)) + bufA[charcount++] = i; + + ret = MultiByteToWideChar(newcp, 0, bufA, charcount, bufW, charcount); + if (ret != charcount) + ERR("MultiByteToWideChar of chars failed for cp %d, ret=%d (exp %d), error=%d\n", newcp, ret, charcount, GetLastError()); + + GetStringTypeW(CT_CTYPE1, bufW, charcount, chartypes); + + charcount = 0; + for (i = 0; i < 256; i++) + if (!(mbcinfo->mbctype[i + 1] & _M1)) + { + if (chartypes[charcount] & C1_UPPER) + { + mbcinfo->mbctype[i + 1] |= _SBUP; + bufW[charcount] = tolowerW(bufW[charcount]); + } + else if (chartypes[charcount] & C1_LOWER) + { + mbcinfo->mbctype[i + 1] |= _SBLOW; + bufW[charcount] = toupperW(bufW[charcount]); + } + charcount++; + } + + ret = WideCharToMultiByte(newcp, 0, bufW, charcount, bufA, charcount, NULL, NULL); + if (ret != charcount) + ERR("WideCharToMultiByte failed for cp %d, ret=%d (exp %d), error=%d\n", newcp, ret, charcount, GetLastError()); + + charcount = 0; + for (i = 0; i < 256; i++) + { + if(!(mbcinfo->mbctype[i + 1] & _M1)) + { + if(mbcinfo->mbctype[i] & (C1_UPPER|C1_LOWER)) + mbcinfo->mbcasemap[i] = bufA[charcount]; + charcount++; + } + } + + if (newcp == 932) /* CP932 only - set _MP and _MS */ + { + /* On Windows it's possible to calculate the _MP and _MS from CT_CTYPE1 + * and CT_CTYPE3. But as of Wine 0.9.43 we return wrong values what makes + * it hard. As this is set only for codepage 932 we hardcode it what gives + * also faster execution. + */ + for (i = 161; i <= 165; i++) + mbcinfo->mbctype[i + 1] |= _MP; + for (i = 166; i <= 223; i++) + mbcinfo->mbctype[i + 1] |= _MS; + } + + mbcinfo->mbcodepage = newcp; + if(MSVCRT_locale && mbcinfo == MSVCRT_locale->mbcinfo) + memcpy(_mbctype, MSVCRT_locale->mbcinfo->mbctype, sizeof(_mbctype)); + + return 0; +} + +/********************************************************************* + * _setmbcp (MSVCRT.@) + */ +int CDECL _setmbcp(int cp) +{ + return _setmbcp_l(cp, -1, NULL); +} + diff --git a/lib/sdk/crt/mbstring/iskana.c b/lib/sdk/crt/mbstring/iskana.c index bb969c8ca9d..5be9d3d40a3 100644 --- a/lib/sdk/crt/mbstring/iskana.c +++ b/lib/sdk/crt/mbstring/iskana.c @@ -17,5 +17,5 @@ */ int _ismbbkana(unsigned int c) { - return (_mbctype[c & 0xff] & _MBKANA); + return (get_mbcinfo()->mbctype[c & 0xff] & _MBKANA); } diff --git a/lib/sdk/crt/mbstring/ismbkaln.c b/lib/sdk/crt/mbstring/ismbkaln.c index 084eb22c23e..fdad1367d67 100644 --- a/lib/sdk/crt/mbstring/ismbkaln.c +++ b/lib/sdk/crt/mbstring/ismbkaln.c @@ -16,5 +16,5 @@ */ int _ismbbkalnum( unsigned int c ) { - return (_mbctype[c & 0xff] & _MKMOJI); + return (get_mbcinfo()->mbctype[c & 0xff] & _MKMOJI); } diff --git a/lib/sdk/crt/mbstring/ismblead.c b/lib/sdk/crt/mbstring/ismblead.c index 30511b840b2..10f14daca32 100644 --- a/lib/sdk/crt/mbstring/ismblead.c +++ b/lib/sdk/crt/mbstring/ismblead.c @@ -19,7 +19,7 @@ */ int _ismbblead(unsigned int c) { - return (_mbctype[(c&0xff) + 1] & _M1) != 0; + return (get_mbcinfo()->mbctype[(c&0xff) + 1] & _M1) != 0; } /* @@ -47,7 +47,7 @@ int _ismbslead( const unsigned char *start, const unsigned char *str) */ unsigned char *__p__mbctype(void) { - return _mbctype; + return get_mbcinfo()->mbctype; } diff --git a/lib/sdk/crt/mbstring/ismbpun.c b/lib/sdk/crt/mbstring/ismbpun.c index 571ded523a1..e756aa24312 100644 --- a/lib/sdk/crt/mbstring/ismbpun.c +++ b/lib/sdk/crt/mbstring/ismbpun.c @@ -18,7 +18,7 @@ int _ismbbpunct(unsigned int c) { // (0xA1 <= c <= 0xA6) - return (_mbctype[c & 0xff] & _MBPUNCT); + return (get_mbcinfo()->mbctype[c & 0xff] & _MBPUNCT); } //iskana() :(0xA1 <= c <= 0xDF) diff --git a/lib/sdk/crt/mbstring/ismbtrl.c b/lib/sdk/crt/mbstring/ismbtrl.c index 7b5b630bab9..fe56d057afb 100644 --- a/lib/sdk/crt/mbstring/ismbtrl.c +++ b/lib/sdk/crt/mbstring/ismbtrl.c @@ -22,7 +22,7 @@ size_t _mbclen2(const unsigned int s); */ int _ismbbtrail(unsigned int c) { - return (_mbctype[(c&0xff) + 1] & _M2) != 0; + return (get_mbcinfo()->mbctype[(c&0xff) + 1] & _M2) != 0; } diff --git a/lib/sdk/crt/mbstring/mbsncpy.c b/lib/sdk/crt/mbstring/mbsncpy.c index 407a8204cda..4780e278dfc 100644 --- a/lib/sdk/crt/mbstring/mbsncpy.c +++ b/lib/sdk/crt/mbstring/mbsncpy.c @@ -13,17 +13,18 @@ #include #include -extern int g_mbcp_is_multibyte; - -/* - * @implemented +/********************************************************************* + * _mbsncpy(MSVCRT.@) + * REMARKS + * The parameter n is the number or characters to copy, not the size of + * the buffer. Use _mbsnbcpy for a function analogical to strncpy */ -unsigned char* _mbsncpy(unsigned char *dst, const unsigned char *src, size_t n) +unsigned char* CDECL _mbsncpy(unsigned char* dst, const unsigned char* src, size_t n) { unsigned char* ret = dst; if(!n) return dst; - if (g_mbcp_is_multibyte) + if (get_mbcinfo()->ismbcodepage) { while (*src && n) { @@ -55,48 +56,12 @@ unsigned char* _mbsncpy(unsigned char *dst, const unsigned char *src, size_t n) return ret; } - -/* - * The _mbsnbcpy function copies count bytes from src to dest. If src is shorter - * than dest, the string is padded with null characters. If dest is less than or - * equal to count it is not terminated with a null character. - * - * @implemented - */ -unsigned char * _mbsnbcpy(unsigned char *dst, const unsigned char *src, size_t n) -{ - unsigned char* ret = dst; - if(!n) - return dst; - if(g_mbcp_is_multibyte) - { - int is_lead = 0; - while (*src && n) - { - is_lead = (!is_lead && _ismbblead(*src)); - n--; - *dst++ = *src++; - } - - if (is_lead) /* if string ends with a lead, remove it */ - *(dst - 1) = 0; - } - else - { - while (n) - { - n--; - if (!(*dst++ = *src++)) break; - } - } - while (n--) *dst++ = 0; - return ret; -} - -/* +/********************************************************************* + * _mbsnbcpy_s(MSVCRT.@) + * REMARKS * Unlike _mbsnbcpy this function does not pad the rest of the dest * string with 0 -*/ + */ int CDECL _mbsnbcpy_s(unsigned char* dst, size_t size, const unsigned char* src, size_t n) { size_t pos = 0; @@ -111,7 +76,7 @@ int CDECL _mbsnbcpy_s(unsigned char* dst, size_t size, const unsigned char* src, if(!n) return 0; - if(g_mbcp_is_multibyte) + if(get_mbcinfo()->ismbcodepage) { int is_lead = 0; while (*src && n) @@ -155,3 +120,40 @@ int CDECL _mbsnbcpy_s(unsigned char* dst, size_t size, const unsigned char* src, return 0; } + +/********************************************************************* + * _mbsnbcpy(MSVCRT.@) + * REMARKS + * Like strncpy this function doesn't enforce the string to be + * NUL-terminated + */ +unsigned char* CDECL _mbsnbcpy(unsigned char* dst, const unsigned char* src, size_t n) +{ + unsigned char* ret = dst; + if(!n) + return dst; + if(get_mbcinfo()->ismbcodepage) + { + int is_lead = 0; + while (*src && n) + { + is_lead = (!is_lead && _ismbblead(*src)); + n--; + *dst++ = *src++; + } + + if (is_lead) /* if string ends with a lead, remove it */ + *(dst - 1) = 0; + } + else + { + while (n) + { + n--; + if (!(*dst++ = *src++)) break; + } + } + while (n--) *dst++ = 0; + return ret; +} + diff --git a/lib/sdk/crt/misc/environ.c b/lib/sdk/crt/misc/environ.c index ef3dda6563b..343d8a3d412 100644 --- a/lib/sdk/crt/misc/environ.c +++ b/lib/sdk/crt/misc/environ.c @@ -426,7 +426,15 @@ errno_t _get_osplatform(unsigned int *pValue) */ int *__p___mb_cur_max(void) { - return &__mb_cur_max; + return &get_locinfo()->mb_cur_max; +} + +/********************************************************************* + * ___mb_cur_max_func(MSVCRT.@) + */ +int CDECL ___mb_cur_max_func(void) +{ + return get_locinfo()->mb_cur_max; } /* diff --git a/lib/sdk/crt/misc/tls.c b/lib/sdk/crt/misc/tls.c index 37d37f598f0..0504fbfca95 100644 --- a/lib/sdk/crt/misc/tls.c +++ b/lib/sdk/crt/misc/tls.c @@ -41,8 +41,8 @@ thread_data_t *msvcrt_get_thread_data(void) ptr->tid = GetCurrentThreadId(); ptr->handle = INVALID_HANDLE_VALUE; ptr->random_seed = 1; - //ptr->locinfo = MSVCRT_locale->locinfo; - //ptr->mbcinfo = MSVCRT_locale->mbcinfo; + ptr->locinfo = MSVCRT_locale->locinfo; + ptr->mbcinfo = MSVCRT_locale->mbcinfo; } SetLastError( err ); return ptr; diff --git a/lib/sdk/crt/precomp.h b/lib/sdk/crt/precomp.h index 7fe14dd1e9e..4d01c7c7ce0 100644 --- a/lib/sdk/crt/precomp.h +++ b/lib/sdk/crt/precomp.h @@ -57,6 +57,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); #include #include #include +#include #include #include #include diff --git a/lib/sdk/crt/string/ctype.c b/lib/sdk/crt/string/ctype.c index a28fd2058f1..1dbbee453ac 100644 --- a/lib/sdk/crt/string/ctype.c +++ b/lib/sdk/crt/string/ctype.c @@ -3,6 +3,10 @@ #define __MINGW_IMPORT #include +#ifndef _LIBCNT_ +#include +#endif + #undef _pctype #undef _pwctype @@ -548,24 +552,12 @@ const unsigned short _wctype[] = { 0x0100 | _LOWER, /* 0xfe */ 0x0100 | _LOWER /* 0xff */ }; + const unsigned short *_pctype = _ctype + 1; const unsigned short *_pwctype = _wctype + 1; extern const unsigned short wine_wctype_table[]; -/* - * @implemented - */ -const unsigned short **__p__pctype(void) -{ - return &_pctype; -} - -const unsigned short* __cdecl __pctype_func(void) -{ - return _pctype; -} - /* * @implemented */ @@ -579,10 +571,50 @@ const unsigned short* __cdecl __pwctype_func(void) return _pwctype; } -int _isctype (int c, int ctypeFlags) +#ifdef _LIBCNT_ +int __cdecl _isctype (int c, int ctypeFlags) { return (_pctype[(unsigned char)(c & 0xFF)] & ctypeFlags); } +#else +/********************************************************************* + * _isctype_l (MSVCRT.@) + */ +int __cdecl _isctype_l(int c, int type, _locale_t locale) +{ + MSVCRT_pthreadlocinfo locinfo; + + if(!locale) + locinfo = get_locinfo(); + else + locinfo = ((MSVCRT__locale_t)locale)->locinfo; + + if (c >= -1 && c <= 255) + return locinfo->pctype[c] & type; + + if (locinfo->mb_cur_max != 1 && c > 0) + { + /* FIXME: Is there a faster way to do this? */ + WORD typeInfo; + char convert[3], *pconv = convert; + + if (locinfo->pctype[(UINT)c >> 8] & _LEADBYTE) + *pconv++ = (UINT)c >> 8; + *pconv++ = c & 0xff; + *pconv = 0; + + if (GetStringTypeExA(locinfo->lc_handle[LC_CTYPE], + CT_CTYPE1, convert, convert[1] ? 2 : 1, &typeInfo)) + return typeInfo & type; + } + return 0; +} + +int __cdecl _isctype (int c, int ctypeFlags) +{ + return _isctype_l(c, ctypeFlags, NULL); +} +#endif /* _LIBCNT_ */ /* * @implemented diff --git a/lib/sdk/crt/string/wcs.c b/lib/sdk/crt/string/wcs.c index 016745871d3..846179a0589 100644 --- a/lib/sdk/crt/string/wcs.c +++ b/lib/sdk/crt/string/wcs.c @@ -238,122 +238,81 @@ wchar_t* CDECL wcspbrk( const wchar_t* str, const wchar_t* accept ) /********************************************************************* * wctomb (MSVCRT.@) */ -INT CDECL wctomb(char *mbchar, wchar_t wchar) +/********************************************************************* + * wctomb (MSVCRT.@) + */ +INT CDECL wctomb( char *dst, wchar_t ch ) { - BOOL bUsedDefaultChar; - char chMultiByte[MB_LEN_MAX]; - int nBytes; + BOOL error; + INT size; - /* At least one parameter needs to be given, the length of a null character cannot be queried (verified by tests under WinXP SP2) */ - if(!mbchar && !wchar) - return 0; - - /* Use WideCharToMultiByte for doing the conversion using the codepage currently set with setlocale() */ - nBytes = WideCharToMultiByte(MSVCRT___lc_codepage, 0, &wchar, 1, chMultiByte, MB_LEN_MAX, NULL, &bUsedDefaultChar); - - /* Only copy the character if an 'mbchar' pointer was given. - - The "C" locale is emulated with codepage 1252 here. This codepage has a default character "?", but the "C" locale doesn't have one. - Therefore don't copy the character in this case. */ - if(mbchar && !(MSVCRT_current_lc_all[0] == 'C' && !MSVCRT_current_lc_all[1] && bUsedDefaultChar)) - memcpy(mbchar, chMultiByte, nBytes); - - /* If the default character was used, set errno to EILSEQ and return -1. */ - if(bUsedDefaultChar) - { - _set_errno(EILSEQ); - return -1; + size = WideCharToMultiByte(get_locinfo()->lc_codepage, 0, &ch, 1, dst, dst ? 6 : 0, NULL, &error); + if(!size || error) { + *_errno() = EINVAL; + return EOF; } - - /* Otherwise return the number of bytes this character occupies. */ - return nBytes; + return size; } +/********************************************************************* + * wcsrtombs_l (INTERNAL) + */ +static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count, _locale_t locale) +{ + MSVCRT_pthreadlocinfo locinfo; + size_t tmp = 0; + BOOL used_default; + + if(!locale) + locinfo = get_locinfo(); + else + locinfo = ((MSVCRT__locale_t)locale)->locinfo; + + if(!mbstr) { + tmp = WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS, + *wcstr, -1, NULL, 0, NULL, &used_default)-1; + if(used_default) + return -1; + return tmp; + } + + while(**wcstr) { + char buf[3]; + size_t i, size; + + size = WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS, + *wcstr, 1, buf, 3, NULL, &used_default); + if(used_default) + return -1; + if(tmp+size > count) + return tmp; + + for(i=0; i= 0 && *wcstr) - { - /* Get the length of this character */ - nResult = wctomb(NULL, *wcstr++); - - /* If this character is not convertible in the current locale, the end result will be -1 */ - if(nResult == -1) - return -1; - - nLength += nResult; - } - - /* Return the final length */ - return nLength; - } - - /* Convert the string then */ - bUsedDefaultChar = FALSE; - - for(;;) - { - char chMultiByte[MB_LEN_MAX]; - UINT uLength; - - /* Are we at the terminating null character? */ - if(!*wcstr) - { - /* Set the null character, but don't increment the pointer as the returned length never includes the terminating null character */ - *p = 0; - break; - } - - /* Convert this character into the temporary chMultiByte variable */ - ZeroMemory(chMultiByte, MB_LEN_MAX); - nResult = wctomb(chMultiByte, *wcstr++); - - /* Check if this was an invalid character */ - if(nResult == -1) - bUsedDefaultChar = TRUE; - - /* If we got no character, stop the conversion process here */ - if(!chMultiByte[0]) - break; - - /* Determine whether this is a double-byte or a single-byte character */ - if(chMultiByte[1]) - uLength = 2; - else - uLength = 1; - - /* Decrease 'count' by the character length and check if the buffer can still hold the full character */ - count -= uLength; - - if((int)count < 0) - break; - - /* It can, so copy it and move the pointer forward */ - memcpy(p, chMultiByte, uLength); - p += uLength; - } - - if(bUsedDefaultChar) - return -1; - - /* Return the length in bytes of the copied characters (without the terminating null character) */ - return p - mbstr; + return wcsrtombs_l(mbstr, &wcstr, count, NULL); } #endif diff --git a/lib/sdk/crt/time/strftime.c b/lib/sdk/crt/time/strftime.c index 797e4c3ece5..996b0fcda17 100644 --- a/lib/sdk/crt/time/strftime.c +++ b/lib/sdk/crt/time/strftime.c @@ -6,14 +6,320 @@ * PROGRAMER: */ #include -#include -size_t -_tcsftime(_TCHAR *strDest, - size_t maxsize, - const _TCHAR *format, - const struct tm *timeptr) +static inline BOOL strftime_date(char *str, size_t *pos, size_t max, + BOOL alternate, const struct tm *mstm, MSVCRT___lc_time_data *time_data) { + char *format; + SYSTEMTIME st; + size_t ret; + + st.wYear = mstm->tm_year + 1900; + st.wMonth = mstm->tm_mon + 1; + st.wDayOfWeek = mstm->tm_wday; + st.wDay = mstm->tm_mday; + st.wHour = mstm->tm_hour; + st.wMinute = mstm->tm_min; + st.wSecond = mstm->tm_sec; + st.wMilliseconds = 0; + + format = alternate ? time_data->str.names.date : time_data->str.names.short_date; + ret = GetDateFormatA(time_data->lcid, 0, &st, format, NULL, 0); + if(ret && retlcid, 0, &st, format, str+*pos, max-*pos); + if(!ret) { + *str = 0; + *_errno() = EINVAL; + return FALSE; + }else if(ret > max-*pos) { + *str = 0; + *_errno() = ERANGE; + return FALSE; + } + *pos += ret-1; + return TRUE; +} + +static inline BOOL strftime_time(char *str, size_t *pos, size_t max, + const struct tm *mstm, MSVCRT___lc_time_data *time_data) +{ + SYSTEMTIME st; + size_t ret; + + st.wYear = mstm->tm_year + 1900; + st.wMonth = mstm->tm_mon + 1; + st.wDayOfWeek = mstm->tm_wday; + st.wDay = mstm->tm_mday; + st.wHour = mstm->tm_hour; + st.wMinute = mstm->tm_min; + st.wSecond = mstm->tm_sec; + st.wMilliseconds = 0; + + ret = GetTimeFormatA(time_data->lcid, 0, &st, time_data->str.names.time, NULL, 0); + if(ret && retlcid, 0, &st, time_data->str.names.time, + str+*pos, max-*pos); + if(!ret) { + *str = 0; + *_errno() = EINVAL; + return FALSE; + }else if(ret > max-*pos) { + *str = 0; + *_errno() = ERANGE; + return FALSE; + } + *pos += ret-1; + return TRUE; +} + +static inline BOOL strftime_str(char *str, size_t *pos, size_t max, char *src) +{ + size_t len = strlen(src); + if(len > max-*pos) { + *str = 0; + *_errno() = ERANGE; + return FALSE; + } + + memcpy(str+*pos, src, len); + *pos += len; + return TRUE; +} + +static inline BOOL strftime_int(char *str, size_t *pos, size_t max, + int src, int prec, int l, int h) +{ + size_t len; + + if(srch) { + *str = 0; + *_errno() = EINVAL; + return FALSE; + } + + len = _snprintf(str+*pos, max-*pos, "%0*d", prec, src); + if(len == -1) { + *str = 0; + *_errno() = ERANGE; + return FALSE; + } + + *pos += len; + return TRUE; +} + +/********************************************************************* + * _Strftime (MSVCRT.@) + */ +size_t CDECL _Strftime(char *str, size_t max, const char *format, + const struct tm *mstm, MSVCRT___lc_time_data *time_data) +{ + size_t ret, tmp; + BOOL alternate; + + TRACE("(%p %ld %s %p %p)\n", str, max, format, mstm, time_data); + + if(!str || !format) { + if(str && max) + *str = 0; + *_errno() = EINVAL; + return 0; + } + + if(!time_data) + time_data = get_locinfo()->lc_time_curr; + + for(ret=0; *format && rettm_wday<0 || mstm->tm_wday>6) + goto einval_error; + if(!strftime_str(str, &ret, max, time_data->str.names.short_wday[mstm->tm_wday])) + return 0; + break; + case 'A': + if(mstm->tm_wday<0 || mstm->tm_wday>6) + goto einval_error; + if(!strftime_str(str, &ret, max, time_data->str.names.wday[mstm->tm_wday])) + return 0; + break; + case 'b': + if(mstm->tm_mon<0 || mstm->tm_mon>11) + goto einval_error; + if(!strftime_str(str, &ret, max, time_data->str.names.short_mon[mstm->tm_mon])) + return 0; + break; + case 'B': + if(mstm->tm_mon<0 || mstm->tm_mon>11) + goto einval_error; + if(!strftime_str(str, &ret, max, time_data->str.names.mon[mstm->tm_mon])) + return 0; + break; + case 'd': + if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 0, 31)) + return 0; + break; + case 'H': + if(!strftime_int(str, &ret, max, mstm->tm_hour, alternate ? 0 : 2, 0, 23)) + return 0; + break; + case 'I': + tmp = mstm->tm_hour; + if(tmp > 12) + tmp -= 12; + else if(!tmp) + tmp = 12; + if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 2, 1, 12)) + return 0; + break; + case 'j': + if(!strftime_int(str, &ret, max, mstm->tm_yday+1, alternate ? 0 : 3, 1, 366)) + return 0; + break; + case 'm': + if(!strftime_int(str, &ret, max, mstm->tm_mon+1, alternate ? 0 : 2, 1, 12)) + return 0; + break; + case 'M': + if(!strftime_int(str, &ret, max, mstm->tm_min, alternate ? 0 : 2, 0, 59)) + return 0; + break; + case 'p': + if(mstm->tm_hour<0 || mstm->tm_hour>23) + goto einval_error; + if(!strftime_str(str, &ret, max, mstm->tm_hour<12 ? + time_data->str.names.am : time_data->str.names.pm)) + return 0; + break; + case 'S': + if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, 59)) + return 0; + break; + case 'w': + if(!strftime_int(str, &ret, max, mstm->tm_wday, 0, 0, 6)) + return 0; + break; + case 'y': + if(!strftime_int(str, &ret, max, mstm->tm_year%100, alternate ? 0 : 2, 0, 99)) + return 0; + break; + case 'Y': + tmp = 1900+mstm->tm_year; + if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 4, 0, 9999)) + return 0; + break; + case 'z': + case 'Z': + _tzset(); + if(_get_tzname(&tmp, str+ret, max-ret, mstm->tm_isdst ? 1 : 0)) + return 0; + ret += tmp; + break; + case 'U': + case 'W': + if(mstm->tm_wday<0 || mstm->tm_wday>6 || mstm->tm_yday<0 || mstm->tm_yday>365) + goto einval_error; + if(*format == 'U') + tmp = mstm->tm_wday; + else if(!mstm->tm_wday) + tmp = 6; + else + tmp = mstm->tm_wday-1; + + tmp = mstm->tm_yday/7 + (tmp<=mstm->tm_yday%7); + if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 2, 0, 53)) + return 0; + break; + case '%': + str[ret++] = '%'; + break; + default: + WARN("unknown format %c\n", *format); + goto einval_error; + } + } + + if(ret == max) { + if(max) + *str = 0; + *_errno() = ERANGE; + return 0; + } + + str[ret] = 0; + return ret; + +einval_error: + *str = 0; + *_errno() = EINVAL; return 0; } +/********************************************************************* + * strftime (MSVCRT.@) + */ +size_t CDECL strftime( char *str, size_t max, const char *format, + const struct tm *mstm ) +{ + return _Strftime(str, max, format, mstm, NULL); +} + +/********************************************************************* + * wcsftime (MSVCRT.@) + */ +size_t CDECL wcsftime( wchar_t *str, size_t max, + const wchar_t *format, const struct tm *mstm ) +{ + char *s, *fmt; + size_t len; + + TRACE("%p %ld %s %p\n", str, max, debugstr_w(format), mstm ); + + len = WideCharToMultiByte( CP_ACP, 0, format, -1, NULL, 0, NULL, NULL ); + if (!(fmt = malloc( len ))) return 0; + WideCharToMultiByte( CP_ACP, 0, format, -1, fmt, len, NULL, NULL ); + + if ((s = malloc( max*4 ))) + { + if (!strftime( s, max*4, fmt, mstm )) s[0] = 0; + len = MultiByteToWideChar( CP_ACP, 0, s, -1, str, max ); + if (len) len--; + free( s ); + } + else len = 0; + + free( fmt ); + return len; +} diff --git a/lib/sdk/uuid/shguids.c b/lib/sdk/uuid/shguids.c index 626540218dc..bc20b16ce60 100644 --- a/lib/sdk/uuid/shguids.c +++ b/lib/sdk/uuid/shguids.c @@ -2,6 +2,7 @@ #include #include +#include #include //BHID_LinkTargetItem diff --git a/media/doc/README.WINE b/media/doc/README.WINE index f99e2ddc018..41b81b6b65a 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -39,7 +39,7 @@ reactos/dll/directx/qedit # Autosync reactos/dll/directx/quartz # Autosync reactos/dll/win32/activeds # Synced to Wine-1.1.43? reactos/dll/win32/actxprxy # Synced to Wine-1.3.29? -reactos/dll/win32/advpack # Synced to Wine-1.5.4 +reactos/dll/win32/advpack # Synced to Wine-1.5.19 reactos/dll/win32/atl # Synced to Wine-1.3.37 reactos/dll/win32/avifil32 # Synced to Wine-1.3.37 reactos/dll/win32/bcrypt # Synced to Wine-1.5.4 @@ -103,7 +103,7 @@ reactos/dll/win32/msg711.acm # Synced to Wine-1.5.4 reactos/dll/win32/msgsm32.acm # Synced to Wine-1.5.4 reactos/dll/win32/mshtml # Autosync reactos/dll/win32/mshtml.tlb # Autosync -reactos/dll/win32/msi # Synced to Wine-1.5.10 +reactos/dll/win32/msi # Synced to Wine-1.5.19 reactos/dll/win32/msimg32 # Synced to Wine-1.5.4 reactos/dll/win32/msimtf # Synced to Wine-1.5.4 reactos/dll/win32/msisip # Synced to Wine-1.5.4 diff --git a/ntoskrnl/fsrtl/dbcsname.c b/ntoskrnl/fsrtl/dbcsname.c index e2c564e2f0a..e7a31c6fb34 100644 --- a/ntoskrnl/fsrtl/dbcsname.c +++ b/ntoskrnl/fsrtl/dbcsname.c @@ -220,7 +220,7 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression, { if (Name->Buffer[MatchingChars] == '.') { - NamePosition = MatchingChars; + NamePosition = MatchingChars + 1; } MatchingChars++; } diff --git a/ntoskrnl/fsrtl/filelock.c b/ntoskrnl/fsrtl/filelock.c index 1e054212228..848e7467f42 100644 --- a/ntoskrnl/fsrtl/filelock.c +++ b/ntoskrnl/fsrtl/filelock.c @@ -51,6 +51,10 @@ typedef struct _LOCK_SHARED_RANGE } LOCK_SHARED_RANGE, *PLOCK_SHARED_RANGE; +#define TAG_TABLE 'LTAB' +#define TAG_RANGE 'FSRA' +#define TAG_FLOCK 'FLCK' + /* PRIVATE FUNCTIONS *********************************************************/ VOID @@ -67,7 +71,7 @@ FsRtlCompleteLockIrpReal(IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteRoutine, static PVOID NTAPI LockAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes) { PVOID Result; - Result = ExAllocatePoolWithTag(NonPagedPool, Bytes, 'LTAB'); + Result = ExAllocatePoolWithTag(NonPagedPool, Bytes, TAG_TABLE); DPRINT("LockAllocate(%d) => %p\n", Bytes, Result); return Result; } @@ -75,7 +79,7 @@ static PVOID NTAPI LockAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes) static VOID NTAPI LockFree(PRTL_GENERIC_TABLE Table, PVOID Buffer) { DPRINT("LockFree(%p)\n", Buffer); - ExFreePoolWithTag(Buffer, 'LTAB'); + ExFreePoolWithTag(Buffer, TAG_TABLE); } static RTL_GENERIC_COMPARE_RESULTS NTAPI LockCompare @@ -379,7 +383,7 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock, /* Initialize the lock, if necessary */ if (!FileLock->LockInformation) { - LockInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(LOCK_INFORMATION), 'FLCK'); + LockInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(LOCK_INFORMATION), TAG_FLOCK); if (!LockInfo) { IoStatus->Status = STATUS_NO_MEMORY; @@ -514,33 +518,30 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock, } return FALSE; } - else - { - DPRINT("Overlapping shared lock %wZ %08x%08x %08x%08x\n", - &FileObject->FileName, - Conflict->Exclusive.FileLock.StartingByte.HighPart, - Conflict->Exclusive.FileLock.StartingByte.LowPart, - Conflict->Exclusive.FileLock.EndingByte.HighPart, - Conflict->Exclusive.FileLock.EndingByte.LowPart); - Conflict = FsRtlpRebuildSharedLockRange(FileLock, - LockInfo, - &ToInsert); - if (!Conflict) - { - IoStatus->Status = STATUS_NO_MEMORY; - if (Irp) - { - FsRtlCompleteLockIrpReal - (FileLock->CompleteLockIrpRoutine, - Context, - Irp, - IoStatus->Status, - &Status, - FileObject); - } - break; - } - } + } + } + + DPRINT("Overlapping shared lock %wZ %08x%08x %08x%08x\n", + &FileObject->FileName, + Conflict->Exclusive.FileLock.StartingByte.HighPart, + Conflict->Exclusive.FileLock.StartingByte.LowPart, + Conflict->Exclusive.FileLock.EndingByte.HighPart, + Conflict->Exclusive.FileLock.EndingByte.LowPart); + Conflict = FsRtlpRebuildSharedLockRange(FileLock, + LockInfo, + &ToInsert); + if (!Conflict) + { + IoStatus->Status = STATUS_NO_MEMORY; + if (Irp) + { + FsRtlCompleteLockIrpReal + (FileLock->CompleteLockIrpRoutine, + Context, + Irp, + IoStatus->Status, + &Status, + FileObject); } } @@ -550,7 +551,7 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock, DPRINT("Adding shared lock %wZ\n", &FileObject->FileName); NewSharedRange = - ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), 'FSRA'); + ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), TAG_RANGE); if (!NewSharedRange) { IoStatus->Status = STATUS_NO_MEMORY; @@ -567,8 +568,8 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock, return FALSE; } DPRINT("Adding shared lock %wZ\n", &FileObject->FileName); - NewSharedRange->Start = ToInsert.Exclusive.FileLock.StartingByte; - NewSharedRange->End = ToInsert.Exclusive.FileLock.EndingByte; + NewSharedRange->Start = *FileOffset; + NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart; NewSharedRange->Key = Key; NewSharedRange->ProcessId = ToInsert.Exclusive.FileLock.ProcessId; InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry); @@ -622,7 +623,7 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock, if (!ExclusiveLock) { NewSharedRange = - ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), 'FSRA'); + ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), TAG_RANGE); if (!NewSharedRange) { IoStatus->Status = STATUS_NO_MEMORY; @@ -639,10 +640,10 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock, return FALSE; } DPRINT("Adding shared lock %wZ\n", &FileObject->FileName); - NewSharedRange->Start = ToInsert.Exclusive.FileLock.StartingByte; - NewSharedRange->End = ToInsert.Exclusive.FileLock.EndingByte; + NewSharedRange->Start = *FileOffset; + NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart; NewSharedRange->Key = Key; - NewSharedRange->ProcessId = ToInsert.Exclusive.FileLock.ProcessId; + NewSharedRange->ProcessId = Process->UniqueProcessId; InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry); } @@ -918,14 +919,9 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock, } if (FoundShared) { - PLIST_ENTRY SharedRangeEntry; - PLOCK_SHARED_RANGE WatchSharedRange; - COMBINED_LOCK_ELEMENT RemadeElement; - Find.Exclusive.FileLock.StartingByte = SharedRange->Start; - Find.Exclusive.FileLock.EndingByte = SharedRange->End; - SharedEntry = SharedRange->Entry.Flink; + /* Remove the found range from the shared range lists */ RemoveEntryList(&SharedRange->Entry); - ExFreePool(SharedRange); + ExFreePoolWithTag(SharedRange, TAG_RANGE); /* We need to rebuild the list of shared ranges. */ DPRINT("Removing the lock entry %wZ (%08x%08x:%08x%08x)\n", &FileObject->FileName, @@ -933,19 +929,25 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock, Entry->Exclusive.FileLock.StartingByte.LowPart, Entry->Exclusive.FileLock.EndingByte.HighPart, Entry->Exclusive.FileLock.EndingByte.LowPart); - /* Copy */ - RemadeElement = *Entry; - RtlDeleteElementGenericTable(&InternalInfo->RangeTable, Entry); + + /* Remember what was in there and remove it from the table */ + Find = *Entry; + RtlDeleteElementGenericTable(&InternalInfo->RangeTable, &Find); /* Put shared locks back in place */ - for (SharedRangeEntry = InternalInfo->SharedLocks.Flink; - SharedRangeEntry != &InternalInfo->SharedLocks; - SharedRangeEntry = SharedRangeEntry->Flink) + for (SharedEntry = InternalInfo->SharedLocks.Flink; + SharedEntry != &InternalInfo->SharedLocks; + SharedEntry = SharedEntry->Flink) { COMBINED_LOCK_ELEMENT LockElement; - WatchSharedRange = CONTAINING_RECORD(SharedRangeEntry, LOCK_SHARED_RANGE, Entry); - LockElement.Exclusive.FileLock.StartingByte = WatchSharedRange->Start; - LockElement.Exclusive.FileLock.EndingByte = WatchSharedRange->End; - if (LockCompare(&InternalInfo->RangeTable, &RemadeElement, &LockElement) != GenericEqual) + SharedRange = CONTAINING_RECORD(SharedEntry, LOCK_SHARED_RANGE, Entry); + LockElement.Exclusive.FileLock.FileObject = FileObject; + LockElement.Exclusive.FileLock.StartingByte = SharedRange->Start; + LockElement.Exclusive.FileLock.EndingByte = SharedRange->End; + LockElement.Exclusive.FileLock.ProcessId = SharedRange->ProcessId; + LockElement.Exclusive.FileLock.Key = SharedRange->Key; + LockElement.Exclusive.FileLock.ExclusiveLock = FALSE; + + if (LockCompare(&InternalInfo->RangeTable, &Find, &LockElement) != GenericEqual) { DPRINT("Skipping range %08x%08x:%08x%08x\n", LockElement.Exclusive.FileLock.StartingByte.HighPart, @@ -959,10 +961,7 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock, LockElement.Exclusive.FileLock.StartingByte.LowPart, LockElement.Exclusive.FileLock.EndingByte.HighPart, LockElement.Exclusive.FileLock.EndingByte.LowPart); - RtlZeroMemory(&RemadeElement, sizeof(RemadeElement)); - RemadeElement.Exclusive.FileLock.StartingByte = WatchSharedRange->Start; - RemadeElement.Exclusive.FileLock.EndingByte = WatchSharedRange->End; - FsRtlpRebuildSharedLockRange(FileLock, InternalInfo, &RemadeElement); + FsRtlpRebuildSharedLockRange(FileLock, InternalInfo, &LockElement); } } else @@ -970,7 +969,8 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock, return STATUS_RANGE_NOT_LOCKED; } } - + +#ifndef NDEBUG DPRINT("Lock still has:\n"); for (SharedEntry = InternalInfo->SharedLocks.Flink; SharedEntry != &InternalInfo->SharedLocks; @@ -985,6 +985,7 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock, SharedRange->End.LowPart, SharedRange->Key); } +#endif // this is definitely the thing we want InternalInfo->Generation++; @@ -1286,8 +1287,8 @@ FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock) { SharedRange = CONTAINING_RECORD(SharedEntry, LOCK_SHARED_RANGE, Entry); SharedEntry = SharedEntry->Flink; - RemoveEntryList(SharedEntry); - ExFreePool(SharedRange); + RemoveEntryList(&SharedRange->Entry); + ExFreePoolWithTag(SharedRange, TAG_RANGE); } while ((Entry = RtlGetElementGenericTable(&InternalInfo->RangeTable, 0)) != NULL) { @@ -1297,7 +1298,7 @@ FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock) { FsRtlProcessFileLock(FileLock, Irp, NULL); } - ExFreePoolWithTag(InternalInfo, 'FLCK'); + ExFreePoolWithTag(InternalInfo, TAG_FLOCK); FileLock->LockInformation = NULL; } } diff --git a/ntoskrnl/fsrtl/name.c b/ntoskrnl/fsrtl/name.c index f36b227f790..5b3b4f9fe9c 100644 --- a/ntoskrnl/fsrtl/name.c +++ b/ntoskrnl/fsrtl/name.c @@ -156,7 +156,7 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression, { if (Name->Buffer[MatchingChars] == L'.') { - NamePosition = MatchingChars; + NamePosition = MatchingChars + 1; } MatchingChars++; } diff --git a/ntoskrnl/inbv/inbv.c b/ntoskrnl/inbv/inbv.c index dc5f2419516..381ed77ed68 100644 --- a/ntoskrnl/inbv/inbv.c +++ b/ntoskrnl/inbv/inbv.c @@ -24,6 +24,108 @@ ROT_BAR_TYPE RotBarSelection; ULONG PltRotBarStatus; BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0}; +/* FADING FUNCTION ***********************************************************/ + +/** From include/psdk/wingdi.h **/ +typedef struct tagRGBQUAD +{ + UCHAR rgbBlue; + UCHAR rgbGreen; + UCHAR rgbRed; + UCHAR rgbReserved; +} RGBQUAD,*LPRGBQUAD; +/*******************************/ + +static RGBQUAD _MainPalette[16]; + +#define PALETTE_FADE_STEPS 15 +#define PALETTE_FADE_TIME 20 * 10000 /* 20ms */ + +/** From bootvid/precomp.h **/ +// +// Bitmap Header +// +typedef struct tagBITMAPINFOHEADER +{ + ULONG biSize; + LONG biWidth; + LONG biHeight; + USHORT biPlanes; + USHORT biBitCount; + ULONG biCompression; + ULONG biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + ULONG biClrUsed; + ULONG biClrImportant; +} BITMAPINFOHEADER, *PBITMAPINFOHEADER; +/****************************/ + +// +// Needed prototypes +// +VOID NTAPI InbvAcquireLock(VOID); +VOID NTAPI InbvReleaseLock(VOID); + +static VOID +NTAPI +BootImageFadeIn(VOID) +{ + UCHAR PaletteBitmapBuffer[sizeof(BITMAPINFOHEADER) + sizeof(_MainPalette)]; + PBITMAPINFOHEADER PaletteBitmap = (PBITMAPINFOHEADER)PaletteBitmapBuffer; + LPRGBQUAD Palette = (LPRGBQUAD)(PaletteBitmapBuffer + sizeof(BITMAPINFOHEADER)); + + ULONG Iteration, Index, ClrUsed; + LARGE_INTEGER Interval; + + Interval.QuadPart = -PALETTE_FADE_TIME; + + /* Check if we're installed and we own it */ + if ((InbvBootDriverInstalled) && + (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) + { + /* Acquire the lock */ + InbvAcquireLock(); + + /* + * Build a bitmap containing the fade in palette. The palette entries + * are then processed in a loop and set using VidBitBlt function. + */ + ClrUsed = sizeof(_MainPalette) / sizeof(_MainPalette[0]); + RtlZeroMemory(PaletteBitmap, sizeof(BITMAPINFOHEADER)); + PaletteBitmap->biSize = sizeof(BITMAPINFOHEADER); + PaletteBitmap->biBitCount = 4; + PaletteBitmap->biClrUsed = ClrUsed; + + /* + * Main animation loop. + */ + for (Iteration = 0; Iteration <= PALETTE_FADE_STEPS; ++Iteration) + { + for (Index = 0; Index < ClrUsed; Index++) + { + Palette[Index].rgbRed = + _MainPalette[Index].rgbRed * Iteration / PALETTE_FADE_STEPS; + Palette[Index].rgbGreen = + _MainPalette[Index].rgbGreen * Iteration / PALETTE_FADE_STEPS; + Palette[Index].rgbBlue = + _MainPalette[Index].rgbBlue * Iteration / PALETTE_FADE_STEPS; + } + + VidBitBlt(PaletteBitmapBuffer, 0, 0); + + /* Wait for a bit. */ + KeDelayExecutionThread(KernelMode, FALSE, &Interval); + } + + /* Release the lock */ + InbvReleaseLock(); + + /* Wait for a bit. */ + KeDelayExecutionThread(KernelMode, FALSE, &Interval); + } +} + /* FUNCTIONS *****************************************************************/ PVOID @@ -267,12 +369,11 @@ InbvDisplayString(IN PCHAR String) if (InbvBootDriverInstalled) VidDisplayString((PUCHAR) String); /* Print the string on the EMS port */ - HeadlessDispatch( - HeadlessCmdPutString, - String, - strlen(String) + sizeof(ANSI_NULL), - NULL, - NULL); + HeadlessDispatch(HeadlessCmdPutString, + String, + strlen(String) + sizeof(ANSI_NULL), + NULL, + NULL); /* Release the lock */ InbvReleaseLock(); @@ -578,10 +679,16 @@ NTAPI INIT_FUNCTION DisplayBootBitmap(IN BOOLEAN TextMode) { + PBITMAPINFOHEADER BitmapInfoHeader; + LPRGBQUAD Palette; + PVOID Header, Band, Text, Screen; ROT_BAR_TYPE TempRotBarSelection = RB_UNSPECIFIED; + +#ifdef CORE_6781_resolved UCHAR Buffer[64]; - +#endif + /* Check if the system thread has already been created */ if (SysThreadCreated) { @@ -665,19 +772,32 @@ DisplayBootBitmap(IN BOOLEAN TextMode) /* Server product, display appropriate status bar color */ InbvGetResourceAddress(IDB_BAR_SERVER); } - + /* Make sure we had a logo */ if (Screen) { /* Choose progress bar */ TempRotBarSelection = RB_SQUARE_CELLS; + /* + * Save the main image palette and replace it with black palette, so + * we can do fade in effect later. + */ + BitmapInfoHeader = (PBITMAPINFOHEADER)Screen; + Palette = (LPRGBQUAD)((PUCHAR)Screen + BitmapInfoHeader->biSize); + RtlCopyMemory(_MainPalette, Palette, sizeof(_MainPalette)); + RtlZeroMemory(Palette, sizeof(_MainPalette)); + /* Blit the background */ InbvBitBlt(Screen, 0, 0); /* Set progress bar coordinates and display it */ InbvSetProgressBarCoordinates(257, 352); - + + /* Display the boot logo and fade it in */ + BootImageFadeIn(); + +#ifdef CORE_6781_resolved /* Check for non-workstation products */ if (SharedUserData->NtProductType != NtProductWinNt) { @@ -689,16 +809,19 @@ DisplayBootBitmap(IN BOOLEAN TextMode) /* In setup mode, you haven't selected a SKU yet */ if (ExpInTextModeSetup) Text = NULL; } - } - - /* Draw the SKU text if it exits */ - if (Text) InbvBitBlt(Text, 180, 121); - - /* Draw the progress bar bit */ -// if (Bar) InbvBitBlt(Bar, 0, 0); +#endif + } - /* Set filter which will draw text display if needed */ - InbvInstallDisplayStringFilter(DisplayFilter); +#ifdef CORE_6781_resolved + /* Draw the SKU text if it exits */ + if (Text) InbvBitBlt(Text, 180, 121); +#endif + + /* Draw the progress bar bit */ +// if (Bar) InbvBitBlt(Bar, 0, 0); + + /* Set filter which will draw text display if needed */ + InbvInstallDisplayStringFilter(DisplayFilter); } /* Do we have a system thread? */ diff --git a/ntoskrnl/kdbg/kdb.c b/ntoskrnl/kdbg/kdb.c index b13384cd930..4b614d3863f 100644 --- a/ntoskrnl/kdbg/kdb.c +++ b/ntoskrnl/kdbg/kdb.c @@ -1705,30 +1705,29 @@ INIT_FUNCTION KdbpGetCommandLineSettings( PCHAR p1) { - PCHAR p2; +#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1) - while (p1 && (p2 = strchr(p1, ' '))) + while (p1 && (p1 = strchr(p1, ' '))) { - p2 += 2; + /* Skip other spaces */ + while (*p1 == ' ') ++p1; - if (!_strnicmp(p2, "KDSERIAL", 8)) + if (!_strnicmp(p1, "KDSERIAL", CONST_STR_LEN("KDSERIAL"))) { - p2 += 8; + p1 += CONST_STR_LEN("KDSERIAL"); KdbDebugState |= KD_DEBUG_KDSERIAL; KdpDebugMode.Serial = TRUE; } - else if (!_strnicmp(p2, "KDNOECHO", 8)) + else if (!_strnicmp(p1, "KDNOECHO", CONST_STR_LEN("KDNOECHO"))) { - p2 += 8; + p1 += CONST_STR_LEN("KDNOECHO"); KdbDebugState |= KD_DEBUG_KDNOECHO; } - else if (!_strnicmp(p2, "FIRSTCHANCE", 11)) + else if (!_strnicmp(p1, "FIRSTCHANCE", CONST_STR_LEN("FIRSTCHANCE"))) { - p2 += 11; + p1 += CONST_STR_LEN("FIRSTCHANCE"); KdbpSetEnterCondition(-1, TRUE, KdbEnterAlways); } - - p1 = p2; } } diff --git a/win32ss/drivers/miniport/vga/initvga.c b/win32ss/drivers/miniport/vga/initvga.c index 5e24286b617..3b523f5d38b 100644 --- a/win32ss/drivers/miniport/vga/initvga.c +++ b/win32ss/drivers/miniport/vga/initvga.c @@ -21,7 +21,7 @@ VGA_REGISTERS TextModeRegs; static VOID FASTCALL vgaSaveRegisters(PVGA_REGISTERS Registers) { - SIZE_T i; + UCHAR i; for (i = 0; i < sizeof(Registers->CRT); i++) { @@ -54,7 +54,7 @@ vgaSaveRegisters(PVGA_REGISTERS Registers) static VOID FASTCALL vgaSetRegisters(PVGA_REGISTERS Registers) { - SIZE_T i; + UCHAR i; /* Update misc output register */ VideoPortWritePortUchar(MISC, Registers->Misc); diff --git a/win32ss/drivers/miniport/vga_new/vbemodes.c b/win32ss/drivers/miniport/vga_new/vbemodes.c index 5e2fc4aef8b..e322ac003ab 100644 --- a/win32ss/drivers/miniport/vga_new/vbemodes.c +++ b/win32ss/drivers/miniport/vga_new/vbemodes.c @@ -168,7 +168,7 @@ InitializeModeTable(IN PHW_DEVICE_EXTENSION VgaExtension) ULONG Size, ScreenSize; PVIDEOMODE VgaMode; PVOID BaseAddress; - ULONG ScreenStride = 0; + ULONG ScreenStride; PHYSICAL_ADDRESS PhysicalAddress; /* Enable only default vga modes if no vesa */ @@ -345,7 +345,8 @@ InitializeModeTable(IN PHW_DEVICE_EXTENSION VgaExtension) { /* Read the screen stride (scanline size) */ ScreenStride = RaiseToPower2(VbeModeInfo->BytesPerScanLine); - VgaMode->wbytes = ScreenStride; + //ASSERT(ScreenStride <= MAX_USHORT); + VgaMode->wbytes = (USHORT)ScreenStride; //VideoPortDebugPrint(0, "ScanLines: %lx Stride: %lx\n", VbeModeInfo->BytesPerScanLine, VgaMode->Stride); /* Size of frame buffer is Height X ScanLine, align to bank/page size */ @@ -372,7 +373,8 @@ InitializeModeTable(IN PHW_DEVICE_EXTENSION VgaExtension) //VideoPortDebugPrint(0, "LINEAR MODE!!!\n"); ScreenStride = (VbeVersion >= 0x300) ? VbeModeInfo->LinBytesPerScanLine : 0; if (!ScreenStride) ScreenStride = VbeModeInfo->BytesPerScanLine; - VgaMode->wbytes = ScreenStride; + //ASSERT(ScreenStride <= MAX_USHORT); + VgaMode->wbytes = (USHORT)ScreenStride; //VideoPortDebugPrint(0, "ScanLines: %lx Stride: %lx\n", VbeModeInfo->BytesPerScanLine, VgaMode->Stride); /* Size of frame buffer is Height X ScanLine, align to page size */ diff --git a/win32ss/user/consrv/rsrc.rc b/win32ss/user/consrv/rsrc.rc index 13d5651466a..361b951a24b 100644 --- a/win32ss/user/consrv/rsrc.rc +++ b/win32ss/user/consrv/rsrc.rc @@ -5,27 +5,69 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 1 ICON DISCARDABLE res/terminal.ico -#include "lang/bg-BG.rc" -#include "lang/cs-CZ.rc" -#include "lang/de-DE.rc" -#include "lang/el-GR.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" -#include "lang/ja-JP.rc" -#include "lang/no-NO.rc" -#include "lang/sk-SK.rc" -#include "lang/sv-SE.rc" -#include "lang/zh-CN.rc" -#include "lang/zh-TW.rc" +#ifdef LANGUAGE_BG_BG + #include "lang/bg-BG.rc" +#endif +#ifdef LANGUAGE_CS_CZ + #include "lang/cs-CZ.rc" +#endif +#ifdef LANGUAGE_DE_DE + #include "lang/de-DE.rc" +#endif +#ifdef LANGUAGE_EL_GR + #include "lang/el-GR.rc" +#endif +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif +#ifdef LANGUAGE_ES_ES + #include "lang/es-ES.rc" +#endif +#ifdef LANGUAGE_FR_FR + #include "lang/fr-FR.rc" +#endif +#ifdef LANGUAGE_ID_ID + #include "lang/id-ID.rc" +#endif +#ifdef LANGUAGE_IT_IT + #include "lang/it-IT.rc" +#endif +#ifdef LANGUAGE_JA_JP + #include "lang/ja-JP.rc" +#endif +#ifdef LANGUAGE_NB_NO + #include "lang/no-NO.rc" +#endif +#ifdef LANGUAGE_SK_SK + #include "lang/sk-SK.rc" +#endif +#ifdef LANGUAGE_SV_SE + #include "lang/sv-SE.rc" +#endif +#ifdef LANGUAGE_ZH_CN + #include "lang/zh-CN.rc" +#endif +#ifdef LANGUAGE_ZH_TW + #include "lang/zh-TW.rc" +#endif // UTF-8 #pragma code_page(65001) -#include "lang/pl-PL.rc" -#include "lang/pt-BR.rc" -#include "lang/ro-RO.rc" -#include "lang/ru-RU.rc" -#include "lang/uk-UA.rc" -#include "lang/tr-TR.rc" +#ifdef LANGUAGE_PL_PL + #include "lang/pl-PL.rc" +#endif +#ifdef LANGUAGE_PT_BR + #include "lang/pt-BR.rc" +#endif +#ifdef LANGUAGE_RO_RO + #include "lang/ro-RO.rc" +#endif +#ifdef LANGUAGE_RU_RU + #include "lang/ru-RU.rc" +#endif +#ifdef LANGUAGE_UK_UA + #include "lang/uk-UA.rc" +#endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif diff --git a/win32ss/user/winsrv/rsrc.rc b/win32ss/user/winsrv/rsrc.rc index a0abb32fd99..648229241e9 100644 --- a/win32ss/user/winsrv/rsrc.rc +++ b/win32ss/user/winsrv/rsrc.rc @@ -3,27 +3,69 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#include "lang/bg-BG.rc" -#include "lang/cs-CZ.rc" -#include "lang/de-DE.rc" -#include "lang/el-GR.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" -#include "lang/ja-JP.rc" -#include "lang/no-NO.rc" -#include "lang/sk-SK.rc" -#include "lang/sv-SE.rc" -#include "lang/zh-CN.rc" -#include "lang/zh-TW.rc" +#ifdef LANGUAGE_BG_BG + #include "lang/bg-BG.rc" +#endif +#ifdef LANGUAGE_CS_CZ + #include "lang/cs-CZ.rc" +#endif +#ifdef LANGUAGE_DE_DE + #include "lang/de-DE.rc" +#endif +#ifdef LANGUAGE_EL_GR + #include "lang/el-GR.rc" +#endif +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif +#ifdef LANGUAGE_ES_ES + #include "lang/es-ES.rc" +#endif +#ifdef LANGUAGE_FR_FR + #include "lang/fr-FR.rc" +#endif +#ifdef LANGUAGE_ID_ID + #include "lang/id-ID.rc" +#endif +#ifdef LANGUAGE_IT_IT + #include "lang/it-IT.rc" +#endif +#ifdef LANGUAGE_JA_JP + #include "lang/ja-JP.rc" +#endif +#ifdef LANGUAGE_NB_NO + #include "lang/no-NO.rc" +#endif +#ifdef LANGUAGE_SK_SK + #include "lang/sk-SK.rc" +#endif +#ifdef LANGUAGE_SV_SE + #include "lang/sv-SE.rc" +#endif +#ifdef LANGUAGE_ZH_CN + #include "lang/zh-CN.rc" +#endif +#ifdef LANGUAGE_ZH_TW + #include "lang/zh-TW.rc" +#endif // UTF-8 #pragma code_page(65001) -#include "lang/pl-PL.rc" -#include "lang/pt-BR.rc" -#include "lang/ro-RO.rc" -#include "lang/ru-RU.rc" -#include "lang/uk-UA.rc" -#include "lang/tr-TR.rc" +#ifdef LANGUAGE_PL_PL + #include "lang/pl-PL.rc" +#endif +#ifdef LANGUAGE_PT_BR + #include "lang/pt-BR.rc" +#endif +#ifdef LANGUAGE_RO_RO + #include "lang/ro-RO.rc" +#endif +#ifdef LANGUAGE_RU_RU + #include "lang/ru-RU.rc" +#endif +#ifdef LANGUAGE_UK_UA + #include "lang/uk-UA.rc" +#endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif