diff --git a/base/applications/applications.rbuild b/base/applications/applications.rbuild
index 232b44c0868..0a1265ce571 100644
--- a/base/applications/applications.rbuild
+++ b/base/applications/applications.rbuild
@@ -22,6 +22,9 @@
+
+
+
diff --git a/base/applications/calc/lang/sk-SK.rc b/base/applications/calc/lang/sk-SK.rc
index 2bf46e61535..41f9ca78fe2 100644
--- a/base/applications/calc/lang/sk-SK.rc
+++ b/base/applications/calc/lang/sk-SK.rc
@@ -1,6 +1,6 @@
/* TRANSLATOR : Mrio Kamr /Mario Kacmar/ aka Kario (kario@szm.sk)
* DATE OF TR.: 30-01-2008
- * LAST CHANGE: 31-05-2010
+ * LAST CHANGE: 17-09-2010
* ---------------------------------------
* TODO:
* pridanie naviganch znaiek "&" ?
@@ -545,9 +545,9 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_ENERGY_15_C_CALORIES "15 C calories"
- IDS_ENERGY_BTUS "British Thermal Units"
+ IDS_ENERGY_BTUS "Britsk termlne jednotky"
IDS_ENERGY_ERGS "Ergs"
- IDS_ENERGY_EVS "Electron-Volts"
+ IDS_ENERGY_EVS "Elektron-Volty"
IDS_ENERGY_FOOT_POUNDS "Foot-Pounds"
IDS_ENERGY_IT_CALORIES "International Table calories"
IDS_ENERGY_IT_KILOCALORIES "International Table kilocalories"
@@ -593,7 +593,7 @@ BEGIN
IDS_LENGTH_MILLIMETERS "Milimetre"
IDS_LENGTH_NAUTICAL_MILES "Nmorn mle"
IDS_LENGTH_NIEU "Nieu"
- IDS_LENGTH_PARSECS "Parsecy"
+ IDS_LENGTH_PARSECS "Parseky"
IDS_LENGTH_PICAS "Picas"
IDS_LENGTH_RI_JAPAN "Ri (Japonsko)"
IDS_LENGTH_RI_KOREA "Ri (Krea)"
@@ -626,10 +626,10 @@ STRINGTABLE DISCARDABLE
BEGIN
IDS_PRESSURE_ATMOSPHERES "Atmosfry"
IDS_PRESSURE_BARS "Bary"
- IDS_PRESSURE_HECTOPASCALS "Hektopascals"
- IDS_PRESSURE_KILOPASCALS "Kilopascals"
- IDS_PRESSURE_MM_OF_MERCURY "Millimeters of mercury"
- IDS_PRESSURE_PASCALS "Pascals"
+ IDS_PRESSURE_HECTOPASCALS "Hektopascaly"
+ IDS_PRESSURE_KILOPASCALS "Kilopascaly"
+ IDS_PRESSURE_MM_OF_MERCURY "Milimetre ortuti"
+ IDS_PRESSURE_PASCALS "Pascaly"
IDS_PRESSURE_PSI "Libry na tvorcov palec"
END
diff --git a/base/applications/findstr/findstr.c b/base/applications/findstr/findstr.c
new file mode 100644
index 00000000000..681bff7ee53
--- /dev/null
+++ b/base/applications/findstr/findstr.c
@@ -0,0 +1,295 @@
+/* findstr.c */
+
+/* Copyright (C) 1994-2002, Jim Hall */
+
+/* Adapted for ReactOS -Edited for Findstr.exe K'Williams */
+
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+
+/* This program locates a string in a text file and prints those lines
+ * that contain the string. Multiple files are clearly separated.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "resource.h"
+
+
+/* Symbol definition */
+#define MAX_STR 1024
+
+
+/* This function prints out all lines containing a substring. There are some
+ * conditions that may be passed to the function.
+ *
+ * RETURN: If the string was found at least once, returns 1.
+ * If the string was not found at all, returns 0.
+ */
+int
+find_str (char *sz, FILE *p, int invert_search,
+ int count_lines, int number_output, int ignore_case, int at_start, int literal_search,
+ int at_end, int reg_express, int exact_match, int sub_dirs, int only_fname)
+{
+ int i, length;
+ long line_number = 0, total_lines = 0;
+ char *c, temp_str[MAX_STR], this_line[MAX_STR];
+
+ /* Convert to upper if needed */
+ if (ignore_case)
+ {
+ length = strlen (sz);
+ for (i = 0; i < length; i++)
+ sz[i] = toupper (sz[i]);
+ }
+
+ /* Scan the file until EOF */
+ while (fgets (temp_str, MAX_STR, p) != NULL)
+ {
+ /* Remove the trailing newline */
+ length = strlen (temp_str);
+ if (temp_str[length-1] == '\n')
+ {
+ temp_str[length-1] = '\0';
+ }
+
+ /* Increment number of lines */
+ line_number++;
+ strcpy (this_line, temp_str);
+
+ /* Convert to upper if needed */
+ if (ignore_case)
+ {
+ for (i = 0; i < length; i++)
+ {
+ temp_str[i] = toupper (temp_str[i]);
+ }
+ }
+
+ /* Locate the substring */
+
+ /* strstr() returns a pointer to the first occurrence in the
+ string of the substring */
+ c = strstr (temp_str, sz);
+
+ if ( ((invert_search) ? (c == NULL) : (c != NULL)) )
+ {
+ if (!count_lines)
+ {
+ if (number_output)
+ printf ("%ld:", line_number);
+
+ /* Print the line of text */
+ puts (this_line);
+ }
+
+ total_lines++;
+ } /* long if */
+ } /* while fgets */
+
+ if (count_lines)
+ {
+ /* Just show num. lines that contain the string */
+ printf ("%ld\n", total_lines);
+ }
+
+
+ /* RETURN: If the string was found at least once, returns 1.
+ * If the string was not found at all, returns 0.
+ */
+ return (total_lines > 0 ? 1 : 0);
+}
+
+/* Show usage */
+void
+usage (void)
+{
+ TCHAR lpUsage[4096];
+
+ LoadString( GetModuleHandle(NULL), IDS_USAGE, (LPTSTR)lpUsage, 4096);
+ CharToOem(lpUsage, lpUsage);
+ printf( lpUsage );
+}
+
+
+/* Main program */
+int
+main (int argc, char **argv)
+{
+ char *opt, *needle = NULL;
+ int ret = 0;
+ TCHAR lpMessage[4096];
+
+ int invert_search = 0; /* flag to invert the search */
+ int count_lines = 0; /* flag to whether/not count lines */
+ int number_output = 0; /* flag to print line numbers */
+ int ignore_case = 0; /* flag to be case insensitive */
+ int at_start = 0; /* flag to Match if at the beginning of a line. */
+ int at_end = 0; /* flag to Match if at the beginning of a line. */
+ int reg_express = 0; /* flag to use/not use regular expressions */
+ int exact_match = 0; /* flag to be exact match */
+ int sub_dirs= 0; /* this and all subdirectories */
+ int only_fname= 0; /* print only the name of the file*/
+ int literal_search=0;
+
+ FILE *pfile; /* file pointer */
+ int hfind; /* search handle */
+ struct _finddata_t finddata; /* _findfirst, filenext block */
+
+ /* Scan the command line */
+ while ((--argc) && (needle == NULL))
+ {
+ if (*(opt = *++argv) == '/')
+ {
+ switch (opt[1])
+ {
+ case 'b':
+ case 'B': /* Matches pattern if at the beginning of a line */
+ at_start = 1;
+ break;
+
+ //case 'c':
+ //case 'C': /* Literal? */
+ // literal_search = 1;
+ // break;
+
+ case 'e':
+ case 'E': /* matches pattern if at end of line */
+ at_end = 1;
+ break;
+
+ case 'i':
+ case 'I': /* Ignore */
+ ignore_case = 1;
+ break;
+
+ case 'm':
+ case 'M': /* only filename */
+ only_fname = 1;
+ break;
+
+ case 'n':
+ case 'N': /* Number */
+ number_output = 1;
+ break;
+
+ case 'r':
+ case 'R': /* search strings as regular expressions */
+ reg_express = 1;
+ break;
+
+ case 's':
+ case 'S': /* search files in child directory too*/
+ sub_dirs = 1;
+ break;
+
+ case 'v':
+ case 'V': /* Not with */
+ invert_search = 1;
+ break;
+
+ case 'x':
+ case 'X': /* exact match */
+ exact_match = 1;
+ break;
+
+ default:
+ usage ();
+ exit (2); /* syntax error .. return error 2 */
+ break;
+ }
+ }
+ else
+ {
+ /* Get the string */
+ if (needle == NULL)
+ {
+ /* Assign the string to find */
+ needle = *argv;
+ }
+ }
+ }
+
+ /* Check for search string */
+ if (needle == NULL)
+ {
+ /* No string? */
+ usage ();
+ exit (1);
+ }
+
+ /* Scan the files for the string */
+ if (argc == 0)
+ {
+ ret = find_str (needle, stdin, invert_search, count_lines,
+ number_output, ignore_case, at_start, literal_search, at_end, reg_express, exact_match,
+ sub_dirs, only_fname);
+ }
+
+ while (--argc >= 0)
+ {
+ hfind = _findfirst (*++argv, &finddata);
+ if (hfind < 0)
+ {
+ /* We were not able to find a file. Display a message and
+ set the exit status. */
+ LoadString( GetModuleHandle(NULL), IDS_NO_SUCH_FILE, (LPTSTR)lpMessage, 4096);
+ CharToOem(lpMessage, lpMessage);
+ fprintf (stderr, lpMessage, *argv);//
+ }
+ else
+ {
+ /* repeat find next file to match the filemask */
+ do
+ {
+ /* We have found a file, so try to open it */
+ if ((pfile = fopen (finddata.name, "r")) != NULL)
+ {
+ printf ("---------------- %s\n", finddata.name);
+ ret = find_str (needle, pfile, invert_search, count_lines,
+ number_output, ignore_case, at_start, literal_search, at_end, reg_express, exact_match,
+ sub_dirs, only_fname);
+ fclose (pfile);
+ }
+ else
+ {
+ LoadString(GetModuleHandle(NULL), IDS_CANNOT_OPEN, (LPTSTR)lpMessage, 4096);
+ CharToOem(lpMessage, lpMessage);
+ fprintf (stderr, lpMessage,
+ finddata.name);
+ }
+ }
+ while (_findnext(hfind, &finddata) > 0);
+ }
+ _findclose(hfind);
+ } /* for each argv */
+
+ /* RETURN: If the string was found at least once, returns 0.
+ * If the string was not found at all, returns 1.
+ * (Note that find_str.c returns the exact opposite values.)
+ */
+ exit ( (ret ? 0 : 1) );
+}
+
+
diff --git a/base/applications/findstr/findstr.rbuild b/base/applications/findstr/findstr.rbuild
new file mode 100644
index 00000000000..64306e39df8
--- /dev/null
+++ b/base/applications/findstr/findstr.rbuild
@@ -0,0 +1,8 @@
+
+
+
+ user32
+ findstr.c
+ findstr.rc
+ rsrc.rc
+
diff --git a/base/applications/findstr/findstr.rc b/base/applications/findstr/findstr.rc
new file mode 100644
index 00000000000..8d50fbaa345
--- /dev/null
+++ b/base/applications/findstr/findstr.rc
@@ -0,0 +1,6 @@
+#define REACTOS_STR_FILE_DESCRIPTION "W32 findstr command\0"
+#define REACTOS_STR_INTERNAL_NAME "findstr\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "findstr.exe\0"
+#include
+
+#include "rsrc.rc"
diff --git a/base/applications/findstr/lang/bg-BG.rc b/base/applications/findstr/lang/bg-BG.rc
new file mode 100644
index 00000000000..3f7cd7fde86
--- /dev/null
+++ b/base/applications/findstr/lang/bg-BG.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: , ..\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"\" [ ... ]\n\
+ /C \n\
+ /I \n\
+ /N , 1\n\
+ /V , ."
+
+IDS_NO_SUCH_FILE, "FIND: %s: \n"
+
+IDS_CANNOT_OPEN, "FIND: %s: \n"
+
+END
diff --git a/base/applications/findstr/lang/ca-ES.rc b/base/applications/findstr/lang/ca-ES.rc
new file mode 100644
index 00000000000..932d4bc06bc
--- /dev/null
+++ b/base/applications/findstr/lang/ca-ES.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_CATALAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Mostra totes les linies que continguin una determinada cadena de carcters.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"Cadena de carcters\" [ file... ]\n\
+ /C Conta el numero de linies que contenen la cadena de carcters\n\
+ /I Ignora majscules i minscules\n\
+ /N Numero de linies mostrades, comenant per la primera\n\
+ /V Mostra les linies que no contenen la cadena de carcters"
+
+IDS_NO_SUCH_FILE, "FIND: %s: No he trobat el fitxer\n"
+
+IDS_CANNOT_OPEN, "FIND: %s: No puc obrir el fitxer\n"
+
+END
diff --git a/base/applications/findstr/lang/cs-CZ.rc b/base/applications/findstr/lang/cs-CZ.rc
new file mode 100644
index 00000000000..8a41024c73b
--- /dev/null
+++ b/base/applications/findstr/lang/cs-CZ.rc
@@ -0,0 +1,23 @@
+/* FILE: applications/cmdutils/find/lang/cs-CZ.rc
+ * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com)
+ * THANKS TO: Mario Kacmar aka Kario (kario@szm.sk)
+ * UPDATED: 2008-02-29
+ */
+
+LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Zobraz vechny dky souboru obsahujc hledan etzec.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"etzec\" [ soubor... ]\n\
+ /C Zobraz poet dk obsahujc etzec.\n\
+ /I Ignoruje velikost psmen.\n\
+ /N sluje zobrazen dky, zan od 1.\n\
+ /V Zobraz vechny dky, kter NEobsahuj zadan etec."
+
+IDS_NO_SUCH_FILE, "FIND: Soubor %s nebyl nalezen.\n"
+
+IDS_CANNOT_OPEN, "FIND: Soubor %s nelze otevt!\n"
+
+END
diff --git a/base/applications/findstr/lang/de-DE.rc b/base/applications/findstr/lang/de-DE.rc
new file mode 100644
index 00000000000..1663cc7aff7
--- /dev/null
+++ b/base/applications/findstr/lang/de-DE.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "Sucht in einer Datei nach einer Zeichenfolge.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"string\" [ file... ]\n\
+ /C Zeigt nur die Anzahl der die Zeichenfolge enthaltenen Zeilen an.\n\
+ /I Ignoriert Gro-/Kleinbuchstaben bei der Suche.\n\
+ /N Zeigt die Zeilen mit ihren Zeilennummern an.\n\
+ /V Zeigt alle Zeilen an, die die Zeichenfolge NICHT enhalten."
+
+IDS_NO_SUCH_FILE, "Datei %s nicht gefunden\n"
+
+IDS_CANNOT_OPEN, "Datei %s kann nicht geffnet werden.\n"
+
+END
diff --git a/base/applications/findstr/lang/el-GR.rc b/base/applications/findstr/lang/el-GR.rc
new file mode 100644
index 00000000000..19e993dda46
--- /dev/null
+++ b/base/applications/findstr/lang/el-GR.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_GREEK, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: .\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"\" [ ... ]\n\
+ /C \n\
+ /I \n\
+ /N , 1\n\
+ /V "
+
+IDS_NO_SUCH_FILE, "FIND: %s: \n"
+
+IDS_CANNOT_OPEN, "FIND: %s: \n"
+
+END
diff --git a/base/applications/findstr/lang/en-US.rc b/base/applications/findstr/lang/en-US.rc
new file mode 100644
index 00000000000..d4ebfe38d53
--- /dev/null
+++ b/base/applications/findstr/lang/en-US.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FINDSTR: Prints all lines of a file that contain a string.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"string\" [ file... ]\n\
+ /C Count the number of lines that contain string\n\
+ /I Ignore case\n\
+ /N Number the displayed lines, starting at 1\n\
+ /V Print lines that do not contain the string"
+
+IDS_NO_SUCH_FILE, "FINDSTR: %s: No such file\n"
+
+IDS_CANNOT_OPEN, "FINDSTR: %s: Cannot open file\n"
+
+END
diff --git a/base/applications/findstr/lang/es-ES.rc b/base/applications/findstr/lang/es-ES.rc
new file mode 100644
index 00000000000..f2fee3f0a4b
--- /dev/null
+++ b/base/applications/findstr/lang/es-ES.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Imprime todas las lneas de un fichero que contiene una cadena.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"cadena\" [ fichero... ]\n\
+ /C Cuenta el nmero de lneas que contienen la cadena de caracteres\n\
+ /I Ignora maysculas y minsculas\n\
+ /N Numero de lneas a mostrar en pantalla, a partir de la primera\n\
+ /V Muestra las lneas que no contienen la cadena de caracteres."
+
+IDS_NO_SUCH_FILE, "FIND: %s: No se encontr el fichero\n"
+
+IDS_CANNOT_OPEN, "FIND: %s: No se pudo abrir el fichero\n"
+
+END
diff --git a/base/applications/findstr/lang/fr-FR.rc b/base/applications/findstr/lang/fr-FR.rc
new file mode 100644
index 00000000000..076f0930177
--- /dev/null
+++ b/base/applications/findstr/lang/fr-FR.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Affiche toutes les lignes d'un fichier qui contiennent un morceau de texte.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"texte\" [ fichier... ]\n\
+ /C Compte le nombre de lignes qui contiennent le texte\n\
+ /I Insensible la casse\n\
+ /N Numrote les lignes affiches en commenant 1\n\
+ /V Affiche les lignes qui ne contiennent pas le texte"
+
+IDS_NO_SUCH_FILE, "FIND: %s : fichier inexistant\n"
+
+IDS_CANNOT_OPEN, "FIND: %s : impossible d'ouvrir le fichier\n"
+
+END
diff --git a/base/applications/findstr/lang/it-IT.rc b/base/applications/findstr/lang/it-IT.rc
new file mode 100644
index 00000000000..d0dabd405f2
--- /dev/null
+++ b/base/applications/findstr/lang/it-IT.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Visualizza le linee di un file che contengono un stringa.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"stringa\" [ file... ]\n\
+ /C Conta il numero di linee che contengono la stringa\n\
+ /I Ignora maiuscole/minuscole\n\
+ /N Numera le linee visualizzate a partire da 1\n\
+ /V Visualizza le linee che non contengono la stringa"
+
+IDS_NO_SUCH_FILE, "FIND: %s: File non trovato\n"
+
+IDS_CANNOT_OPEN, "FIND: %s: Impossibile aprire il file\n"
+
+END
diff --git a/base/applications/findstr/lang/lt-LT.rc b/base/applications/findstr/lang/lt-LT.rc
new file mode 100644
index 00000000000..ce5b86af08a
--- /dev/null
+++ b/base/applications/findstr/lang/lt-LT.rc
@@ -0,0 +1,26 @@
+/*
+ * PROJECT: ReactOS find command
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: base/applications/cmdutils/find/lang/lt-LT.rc
+ * PURPOSE: Lithuanian Language File
+ * TRANSLATOR: Vytis "CMan" Girdijauskas (cman@cman.us)
+ * DATE: 2007-09-23
+ */
+
+LANGUAGE LANG_LITHUANIAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Spausdina visas bylos eilutes, kuriose yra iekomas tekstas.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"tekstas\" [ byla... ]\n\
+ /C Skaiiuoti eilutes, kuriose yra iekomas tekstas\n\
+ /I Ignoruoti raidi dyd\n\
+ /N Numeruoti vaizduojamas eilutes, pradedant nuo 1\n\
+ /V Spausdinti eilutes, kuriose nra iekomo teksto"
+
+IDS_NO_SUCH_FILE, "FIND: %s: Tokios bylos nra\n"
+
+IDS_CANNOT_OPEN, "FIND: %s: Nepavyko atverti bylos\n"
+
+END
diff --git a/base/applications/findstr/lang/no-NO.rc b/base/applications/findstr/lang/no-NO.rc
new file mode 100644
index 00000000000..d564684f86f
--- /dev/null
+++ b/base/applications/findstr/lang/no-NO.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FINN: Skriv alle linjene for filen som inneholder en streng.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"streng\" [ fil... ]\n\
+ /C Teller nummer av linjer som inneholder strenger\n\
+ /I Ignorere sak\n\
+ /N Nummer viste linjer, start med 1\n\
+ /V Skriv linjer som ikke inneholder en streng"
+
+IDS_NO_SUCH_FILE, "FINN: %s: Ingen filer\n"
+
+IDS_CANNOT_OPEN, "FINN: %s: Kan ikke pne filen\n"
+
+END
diff --git a/base/applications/findstr/lang/pl-PL.rc b/base/applications/findstr/lang/pl-PL.rc
new file mode 100644
index 00000000000..744623e2aa4
--- /dev/null
+++ b/base/applications/findstr/lang/pl-PL.rc
@@ -0,0 +1,24 @@
+/*
+ * translated by Caemyr - Olaf Siejka (Dec,2007)
+ * Use ReactOS forum PM or IRC to contact me
+ * http://www.reactos.org
+ * IRC: irc.freenode.net #reactos-pl
+ */
+
+LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Wywietla wszystkie linie danego pliku, zawierajce szukany cig znakw.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"cig znakw\" [ plik... ]\n\
+ /C Oblicza w ilu liniach pojawi si szukany cig znakw\n\
+ /I Ignoruje wielko liter\n\
+ /N Numeruje wywietlane linie, zaczynajc od 1\n\
+ /V Wywietla te linie ktre nie zawieraj szukanego cigu znakw"
+
+IDS_NO_SUCH_FILE, "FIND: %s: Plik nie zosta znaleziony\n"
+
+IDS_CANNOT_OPEN, "FIND: %s: Nie mona otworzy pliku\n"
+
+END
diff --git a/base/applications/findstr/lang/pt-BR.rc b/base/applications/findstr/lang/pt-BR.rc
new file mode 100644
index 00000000000..de6342b71b3
--- /dev/null
+++ b/base/applications/findstr/lang/pt-BR.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Localiza uma seqncia de texto em um ou mais arquivos.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"seqncia\" [ arquivo... ]\n\
+ /C Exibe apenas o nmero de linhas que contm a seqncia.\n\
+ /I Ignora maisculas/minsculas ao localizar uma seqncia.\n\
+ /N Exibe o nmero de cada linha, iniciando no 1.\n\
+ /V Exibe todas as linhas que NO contm a seqncia especificada."
+
+IDS_NO_SUCH_FILE, "FIND: %s: Arquivo no encontrado\n"
+
+IDS_CANNOT_OPEN, "FIND: %s: No foi possvel abrir o arquivo\n"
+
+END
diff --git a/base/applications/findstr/lang/ru-RU.rc b/base/applications/findstr/lang/ru-RU.rc
new file mode 100644
index 00000000000..94594f56770
--- /dev/null
+++ b/base/applications/findstr/lang/ru-RU.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: .\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"\" [ ... ]\n\
+ /C , .\n\
+ /I .\n\
+ /N ( 1).\n\
+ /V , ."
+
+IDS_NO_SUCH_FILE, "FIND: %s: .\n"
+
+IDS_CANNOT_OPEN, "FIND: %s: .\n"
+
+END
diff --git a/base/applications/findstr/lang/sk-SK.rc b/base/applications/findstr/lang/sk-SK.rc
new file mode 100644
index 00000000000..93037288a93
--- /dev/null
+++ b/base/applications/findstr/lang/sk-SK.rc
@@ -0,0 +1,21 @@
+/* TRANSLATOR: Mrio Kamr /Mario Kacmar/ aka Kario (kario@szm.sk)
+ * DATE OF TR: 12-02-2008
+ */
+
+LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Zobraz vetky riadky sboru obsahujce hadan reazec.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"reazec\" [ sbor... ]\n\
+ /C Zobraz poet riadkov, ktor obsahuj reazec.\n\
+ /I Ignoruje vekos psmen.\n\
+ /N sluje zobrazen riadky, zana od 1.\n\
+ /V Zobraz vetky riadky, ktor neobsahuj hadan reazec."
+
+IDS_NO_SUCH_FILE, "FIND: Sbor %s sa nenaiel.\n"
+
+IDS_CANNOT_OPEN, "FIND: Sbor %s sa ned otvori.\n"
+
+END
diff --git a/base/applications/findstr/lang/sv-SE.rc b/base/applications/findstr/lang/sv-SE.rc
new file mode 100644
index 00000000000..e8d0d6eefdc
--- /dev/null
+++ b/base/applications/findstr/lang/sv-SE.rc
@@ -0,0 +1,17 @@
+LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: Skriver ut alla rader i en fil som innehller en strng.\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"strng\" [ fil... ]\n\
+ /C Rkna nummren av linjer som innehller en strngen\n\
+ /I Ignorera skiftlge\n\
+ /N Antal visade rader, brjar p 1\n\
+ /V Skriver ut rader som inte innehller strngen"
+
+IDS_NO_SUCH_FILE, "FIND: %s: Ingen sorts fil\n"
+
+IDS_CANNOT_OPEN, "FIND: %s: Kan inte ppna filen\n"
+
+END
diff --git a/base/applications/findstr/lang/uk-UA.rc b/base/applications/findstr/lang/uk-UA.rc
new file mode 100644
index 00000000000..b7df8b4e635
--- /dev/null
+++ b/base/applications/findstr/lang/uk-UA.rc
@@ -0,0 +1,25 @@
+/*
+ * PROJECT: Find
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: base/applications/cmdutils/find/lang/uk-UA.rc
+ * PURPOSE: Ukraianian Language File for find
+ * TRANSLATOR: Artem Reznikov
+ */
+
+LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+BEGIN
+
+IDS_USAGE, "FIND: , .\n\n\
+ FIND [ /C ] [ /I ] [ /N ] [ /V ] \"\" [ ... ]\n\
+ /C , \n\
+ /I \n\
+ /N , ( 1)\n\
+ /V , "
+
+IDS_NO_SUCH_FILE, "FIND: %s: \n"
+
+IDS_CANNOT_OPEN, "FIND: %s: \n"
+
+END
diff --git a/base/applications/findstr/resource.h b/base/applications/findstr/resource.h
new file mode 100644
index 00000000000..444cd8cc457
--- /dev/null
+++ b/base/applications/findstr/resource.h
@@ -0,0 +1,3 @@
+#define IDS_USAGE 1000
+#define IDS_NO_SUCH_FILE 1001
+#define IDS_CANNOT_OPEN 1002
diff --git a/base/applications/findstr/rsrc.rc b/base/applications/findstr/rsrc.rc
new file mode 100644
index 00000000000..99baec73cbe
--- /dev/null
+++ b/base/applications/findstr/rsrc.rc
@@ -0,0 +1,20 @@
+#include
+#include "resource.h"
+
+#include "lang/bg-BG.rc"
+#include "lang/ca-ES.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/it-IT.rc"
+#include "lang/lt-LT.rc"
+#include "lang/no-NO.rc"
+#include "lang/pl-PL.rc"
+#include "lang/pt-BR.rc"
+#include "lang/ru-RU.rc"
+#include "lang/sk-SK.rc"
+#include "lang/sv-SE.rc"
+#include "lang/uk-UA.rc"
diff --git a/base/applications/network/ipconfig/ipconfig.c b/base/applications/network/ipconfig/ipconfig.c
index 3d9de7d8e19..26576144190 100644
--- a/base/applications/network/ipconfig/ipconfig.c
+++ b/base/applications/network/ipconfig/ipconfig.c
@@ -25,6 +25,17 @@
HINSTANCE hInstance;
HANDLE ProcessHeap;
+int LoadStringAndOem(HINSTANCE hInst,
+ UINT uID,
+ LPTSTR szNode,
+ int Siz
+)
+{
+ TCHAR szTmp[25];
+ int res = LoadString(hInst, uID, szTmp, sizeof(szTmp));
+ CharToOem(szTmp, szNode);
+ return(res);
+}
LPTSTR GetNodeTypeName(UINT NodeType)
{
@@ -33,27 +44,27 @@ LPTSTR GetNodeTypeName(UINT NodeType)
switch (NodeType)
{
case 1:
- if (!LoadString(hInstance, IDS_BCAST, szNode, sizeof(szNode)))
+ if (!LoadStringAndOem(hInstance, IDS_BCAST, szNode, sizeof(szNode)))
return NULL;
break;
case 2:
- if (!LoadString(hInstance, IDS_P2P, szNode, sizeof(szNode)))
+ if (!LoadStringAndOem(hInstance, IDS_P2P, szNode, sizeof(szNode)))
return NULL;
break;
case 4:
- if (!LoadString(hInstance, IDS_MIXED, szNode, sizeof(szNode)))
+ if (!LoadStringAndOem(hInstance, IDS_MIXED, szNode, sizeof(szNode)))
return NULL;
break;
case 8:
- if (!LoadString(hInstance, IDS_HYBRID, szNode, sizeof(szNode)))
+ if (!LoadStringAndOem(hInstance, IDS_HYBRID, szNode, sizeof(szNode)))
return NULL;
break;
default :
- if (!LoadString(hInstance, IDS_UNKNOWN, szNode, sizeof(szNode)))
+ if (!LoadStringAndOem(hInstance, IDS_UNKNOWN, szNode, sizeof(szNode)))
return NULL;
break;
}
@@ -69,42 +80,42 @@ LPTSTR GetInterfaceTypeName(UINT InterfaceType)
switch (InterfaceType)
{
case MIB_IF_TYPE_OTHER:
- if (!LoadString(hInstance, IDS_OTHER, szIntType, sizeof(szIntType)))
+ if (!LoadStringAndOem(hInstance, IDS_OTHER, szIntType, sizeof(szIntType)))
return NULL;
break;
case MIB_IF_TYPE_ETHERNET:
- if (!LoadString(hInstance, IDS_ETH, szIntType, sizeof(szIntType)))
+ if (!LoadStringAndOem(hInstance, IDS_ETH, szIntType, sizeof(szIntType)))
return NULL;
break;
case MIB_IF_TYPE_TOKENRING:
- if (!LoadString(hInstance, IDS_TOKEN, szIntType, sizeof(szIntType)))
+ if (!LoadStringAndOem(hInstance, IDS_TOKEN, szIntType, sizeof(szIntType)))
return NULL;
break;
case MIB_IF_TYPE_FDDI:
- if (!LoadString(hInstance, IDS_FDDI, szIntType, sizeof(szIntType)))
+ if (!LoadStringAndOem(hInstance, IDS_FDDI, szIntType, sizeof(szIntType)))
return NULL;
break;
case MIB_IF_TYPE_PPP:
- if (!LoadString(hInstance, IDS_PPP, szIntType, sizeof(szIntType)))
+ if (!LoadStringAndOem(hInstance, IDS_PPP, szIntType, sizeof(szIntType)))
return NULL;
break;
case MIB_IF_TYPE_LOOPBACK:
- if (!LoadString(hInstance, IDS_LOOP, szIntType, sizeof(szIntType)))
+ if (!LoadStringAndOem(hInstance, IDS_LOOP, szIntType, sizeof(szIntType)))
return NULL;
break;
case MIB_IF_TYPE_SLIP:
- if (!LoadString(hInstance, IDS_SLIP, szIntType, sizeof(szIntType)))
+ if (!LoadStringAndOem(hInstance, IDS_SLIP, szIntType, sizeof(szIntType)))
return NULL;
break;
default:
- if (!LoadString(hInstance, IDS_UNKNOWN, szIntType, sizeof(szIntType)))
+ if (!LoadStringAndOem(hInstance, IDS_UNKNOWN, szIntType, sizeof(szIntType)))
return NULL;
break;
}
@@ -153,6 +164,7 @@ LPTSTR GetConnectionType(LPTSTR lpClass)
{
HKEY hKey = NULL;
LPTSTR ConType = NULL;
+ LPTSTR ConTypeTmp = NULL;
TCHAR Path[256];
LPTSTR PrePath = _T("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
LPTSTR PostPath = _T("\\Connection");
@@ -180,24 +192,34 @@ LPTSTR GetConnectionType(LPTSTR lpClass)
NULL,
&dwDataSize) == ERROR_SUCCESS)
{
+ ConTypeTmp = (LPTSTR)HeapAlloc(ProcessHeap,
+ 0,
+ dwDataSize);
+
ConType = (LPTSTR)HeapAlloc(ProcessHeap,
0,
dwDataSize);
- if (ConType)
+ if (ConType && ConTypeTmp)
{
if(RegQueryValueEx(hKey,
_T("Name"),
NULL,
&dwType,
- (PBYTE)ConType,
+ (PBYTE)ConTypeTmp,
&dwDataSize) != ERROR_SUCCESS)
{
HeapFree(ProcessHeap,
0,
ConType);
+ HeapFree(ProcessHeap,
+ 0,
+ ConTypeTmp);
+
ConType = NULL;
}
+
+ if (ConType) CharToOem(ConTypeTmp, ConType);
}
}
}
@@ -674,7 +696,7 @@ VOID Usage(VOID)
if (lpUsage == NULL)
return;
- if (LoadString(hInstance,
+ if (LoadStringAndOem(hInstance,
IDS_USAGE,
lpUsage,
Size))
diff --git a/base/applications/network/tracert/tracert.c b/base/applications/network/tracert/tracert.c
index 4ec2508fa64..e3c1048f7be 100644
--- a/base/applications/network/tracert/tracert.c
+++ b/base/applications/network/tracert/tracert.c
@@ -422,7 +422,7 @@ AllocateBuffers(PAPPINFO pInfo)
pInfo->RecvPacket = (PIPv4_HEADER)HeapAlloc(GetProcessHeap(),
0,
- sizeof(IPv4_HEADER) + PACKET_SIZE);
+ MAX_PING_PACKET_SIZE);
if (!pInfo->RecvPacket)
{
HeapFree(GetProcessHeap(),
diff --git a/base/applications/rapps/rapps/7zip.txt b/base/applications/rapps/rapps/7zip.txt
index 93cdb8ad47e..e5e8df83ae6 100644
--- a/base/applications/rapps/rapps/7zip.txt
+++ b/base/applications/rapps/rapps/7zip.txt
@@ -2,13 +2,13 @@
[Section]
Name = 7-Zip
-Version = 4.65
+Version = 9.20
Licence = LGPL
Description = Utility to create and open 7zip, zip, tar, rar and other archive files.
-Size = 0.9M
+Size = 1.0M
Category = 12
URLSite = http://www.7-zip.org/
-URLDownload = http://ovh.dl.sourceforge.net/project/sevenzip/7-Zip/4.65/7z465.exe
+URLDownload = http://ovh.dl.sourceforge.net/project/sevenzip/7-Zip/9.20/7z920.exe
CDPath = none
[Section.0407]
@@ -17,5 +17,8 @@ Description = Tool zum Erstellen und Öffnen von 7zip, zip, tar, rar und andrern
[Section.040a]
Description = Utilidad para crear y abrir 7zip, zip, tar, rar y otros archivos comprimidos.
+[Section.0415]
+Description = Narzędzie do tworzenia i otwierania plików typu 7zip, zip, tar, i innych plików archiwizacyjnych.
+
[Section.0422]
Description = Утиліта для створення та відкриття 7zip, zip, tar, rar та інших архівних файлів.
diff --git a/base/applications/rapps/rapps/abyss.txt b/base/applications/rapps/rapps/abyss.txt
index 49d505cf414..8959327b617 100644
--- a/base/applications/rapps/rapps/abyss.txt
+++ b/base/applications/rapps/rapps/abyss.txt
@@ -14,5 +14,10 @@ CDPath = none
[Section.0407]
Description = Abyss Web Server ermöglicht es Webseiten auf Ihrem Computer zu hosten. Er unterstützt sichere SSL/TLS Verbindungen (HTTPS) sowie eine Vielfalt an Web Technologien. Er kann ebenfalls PHP, Perl, Python, ASP, ASP.NET, und Ruby on Rails Web Anwendungen ausführen, welche von Datenbanken, wie MySQL, SQLite, MS SQL Server, MS Access, oder Oracle unterstützt werden können.
+[Section.0415]
+Description = Abyss Web Server pozwala Ci na stworzenie serwera WWW na własnym komputerze. Ten program obsługuje zabezpieczone połączenia typu SSL/TLS (HTTPS) i wiele technologii Sieci.
+Może także uruchamiać zaawansowane aplikacje internetowe takie jak PHP, Perl, Python, ASP, ASP.NET, i Ruby on Rails.
+Mogą one zostać oparte o MySQL, SQLite, MS SQL Server, MS Access, lub Oracle.
+
[Section.0422]
Description = Abyss Web Server дозволить вам утримувати веб-сайти на вашому комп'ютері. Від підтримує безпечні SSL/TLS з'єднання (HTTPS) та великий ряд веб-технологій. Він також запускає PHP, Perl, Python, ASP, ASP.NET, та Ruby on Rails веб-додатки, які можуть підтримуватись такими базами даних, як MySQL, SQLite, MS SQL Server, MS Access, чи Oracle.
diff --git a/base/applications/rapps/rapps/comctl32ocx.txt b/base/applications/rapps/rapps/comctl32ocx.txt
index a678a338180..392e8faf26c 100644
--- a/base/applications/rapps/rapps/comctl32ocx.txt
+++ b/base/applications/rapps/rapps/comctl32ocx.txt
@@ -21,7 +21,7 @@ Description = X es necesario para varias aplicaciones.
[Section.0415]
Licence = Nieznana
-Description = X jest używana przez część aplikacji.
+Description = Microsoft Visual Basic 6.0 Common Controls jest używany przez część aplikacji.
[Section.0422]
Licence = Невідома
diff --git a/base/applications/rapps/rapps/dosblaster.txt b/base/applications/rapps/rapps/dosblaster.txt
index 3974dda66aa..a499b7a956c 100644
--- a/base/applications/rapps/rapps/dosblaster.txt
+++ b/base/applications/rapps/rapps/dosblaster.txt
@@ -17,5 +17,8 @@ Description = DosBlaster ist eine Shell Extension, die es ermöglicht jede DOS A
[Section.040a]
Description = DosBlaster en una extensión Shell que permite abrir cualquier ejecutable DOS en DOSBox desde el botón derecho del ratón. Esta versión contiene DOSBox 0.70, pero puede ser actualizado facilmente instalando una nueva versión de DOSBox en la carpeta de DosBlaster.
+[Section.0415]
+Description = DosBlaster to rozszerzenie powłoki, które umożliwia otwarcie każdego DOS-owego pliku wykonywalnego w DOSBox za pomocą prawego klawisza myszki. Ta wersja zawiera DosBox 0.70, ale można go łatwo zaktualizować, instalując nowszą wersje DOSBox do folderów DosBlaster.
+
[Section.0422]
Description = DosBlaster це розширення оболонки, яке дозволяє запустити будь-який виконавчий файл DOS в DOSBox через правий клік. Ця версія містить DOSBox 0.70, але може бути оновлена встановленням новішої версії DOSBox в теки DosBlaster.
diff --git a/base/applications/rapps/rapps/fap.txt b/base/applications/rapps/rapps/fap.txt
index 6bbac0edc57..56a42cb23f8 100644
--- a/base/applications/rapps/rapps/fap.txt
+++ b/base/applications/rapps/rapps/fap.txt
@@ -14,5 +14,8 @@ CDPath = none
[Section.0407]
Description = Kleiner und einfacher Mediaplayer.
+[Section.0415]
+Description = Prosty i lekki odtwarzacz audio.
+
[Section.0422]
Description = Простий та маленький програвач аудіо файлів.
diff --git a/base/applications/rapps/rapps/firefox36.txt b/base/applications/rapps/rapps/firefox36.txt
index cff4b21274c..31b72a5514f 100644
--- a/base/applications/rapps/rapps/firefox36.txt
+++ b/base/applications/rapps/rapps/firefox36.txt
@@ -2,47 +2,47 @@
[Section]
Name = Mozilla Firefox 3.6
-Version = 3.6.10
+Version = 3.6.12
Licence = MPL/GPL/LGPL
Description = The most popular and one of the best free Web Browsers out there.
Size = 8.1M
Category = 5
URLSite = http://www.mozilla.com/en-US/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/en-US/Firefox%20Setup%203.6.10.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.12/win32/en-US/Firefox%20Setup%203.6.12.exe
CDPath = none
[Section.0407]
Description = Der populärste und einer der besten freien Webbrowser.
Size = 8.0M
URLSite = http://www.mozilla-europe.org/de/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/de/Firefox%20Setup%203.6.10.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.12/win32/de/Firefox%20Setup%203.6.12.exe
[Section.040a]
Description = El más popular y uno de los mejores navegadores web gratuitos que hay.
Size = 8.0M
URLSite = http://www.mozilla-europe.org/es/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/es-ES/Firefox%20Setup%203.6.10.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.12/win32/es-ES/Firefox%20Setup%203.6.12.exe
[Section.0414]
Description = Mest populære og best også gratis nettleserene der ute.
Size = 8.0M
URLSite = http://www.mozilla-europe.org/no/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/nb-NO/Firefox%20Setup%203.6.10.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.12/win32/nb-NO/Firefox%20Setup%203.6.12.exe
[Section.0415]
Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych.
Size = 8.8M
URLSite = http://www.mozilla-europe.org/pl/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/pl/Firefox%20Setup%203.6.10.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.12/win32/pl/Firefox%20Setup%203.6.12.exe
[Section.0419]
Description = Один из самых популярных и лучших бесплатных браузеров.
Size = 8.4M
URLSite = http://www.mozilla-europe.org/ru/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/ru/Firefox%20Setup%203.6.10.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.12/win32/ru/Firefox%20Setup%203.6.12.exe
[Section.0422]
Description = Найпопулярніший та один з кращих безплатних веб-браузерів.
Size = 8.4M
URLSite = http://www.mozilla-europe.org/uk/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/uk/Firefox%20Setup%203.6.10.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.12/win32/uk/Firefox%20Setup%203.6.12.exe
diff --git a/base/applications/rapps/rapps/go-oo.txt b/base/applications/rapps/rapps/go-oo.txt
index e32599ed605..39dbe608ad5 100644
--- a/base/applications/rapps/rapps/go-oo.txt
+++ b/base/applications/rapps/rapps/go-oo.txt
@@ -18,7 +18,7 @@ Description = Open Source Office Suite, basierend auf Open Office, aber viel bes
Description = La suite de ofimática de código abierto.
[Section.0415]
-Description = Otwarty pakiet biurowy.
+Description = Otwarty pakiet biurowy, bazujący na Open Office, ale znacznie lepszy.
[Section.0422]
Description = Відкритий офісний пакет.
diff --git a/base/applications/rapps/rapps/kdewin.txt b/base/applications/rapps/rapps/kdewin.txt
index f0bd4ecd08c..4c47525940a 100644
--- a/base/applications/rapps/rapps/kdewin.txt
+++ b/base/applications/rapps/rapps/kdewin.txt
@@ -14,5 +14,8 @@ CDPath = none
[Section.0407]
Description = KDE für Windows.
+[Section.0415]
+Description = KDE dla Windows.
+
[Section.0422]
Description = KDE для Windows.
diff --git a/base/applications/rapps/rapps/libreoffice.txt b/base/applications/rapps/rapps/libreoffice.txt
index 8edeb91de0a..65ae3c3fa3a 100644
--- a/base/applications/rapps/rapps/libreoffice.txt
+++ b/base/applications/rapps/rapps/libreoffice.txt
@@ -2,13 +2,13 @@
[Section]
Name = LibreOffice
-Version = 3.3.0 Beta 1
+Version = 3.3.0 Beta 3
Licence = LGPL
Description = Former called OpenOffice. Open Source Office Suite.
-Size = 138.0MB
+Size = 300.0MB
Category = 6
URLSite = http://www.documentfoundation.org/
-URLDownload = http://download.documentfoundation.org/libreoffice/testing/LO_3.3.0-beta1_Win_x86_install_en-US.exe
+URLDownload = http://download.documentfoundation.org/libreoffice/testing/3.3.0-beta3/win/x86/LibO_3.3.0_Win_x86_install_multi.exe
CDPath = none
[Section.0407]
diff --git a/base/applications/rapps/rapps/mirandaim.txt b/base/applications/rapps/rapps/mirandaim.txt
index 5c9fc34a53a..d7a41806712 100644
--- a/base/applications/rapps/rapps/mirandaim.txt
+++ b/base/applications/rapps/rapps/mirandaim.txt
@@ -2,13 +2,13 @@
[Section]
Name = Miranda IM
-Version = 0.9.5
+Version = 0.9.11
Licence = GPL
Description = Open source multiprotocol instant messaging application - May not work completely.
-Size = 2.2MB
+Size = 3.0MB
Category = 5
URLSite = http://www.miranda-im.org/
-URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.9.5-unicode.exe
+URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.9.11-unicode.exe
CDPath = none
[Section.0407]
diff --git a/base/applications/rapps/rapps/mirc.txt b/base/applications/rapps/rapps/mirc.txt
index 695630a24e0..1f7220a9947 100644
--- a/base/applications/rapps/rapps/mirc.txt
+++ b/base/applications/rapps/rapps/mirc.txt
@@ -2,13 +2,13 @@
[Section]
Name = mIRC
-Version = 7.1
+Version = 7.15
Licence = Shareware
Description = The most popular client for the Internet Relay Chat (IRC).
-Size = 1.8M
+Size = 2.0M
Category = 5
URLSite = http://www.mirc.com/
-URLDownload = http://download.mirc.com/mirc71.exe
+URLDownload = http://download.mirc.com/mirc715.exe
CDPath = none
[Section.0407]
diff --git a/base/applications/rapps/rapps/mono2.txt b/base/applications/rapps/rapps/mono2.txt
index 6de2539031c..5911b62896b 100644
--- a/base/applications/rapps/rapps/mono2.txt
+++ b/base/applications/rapps/rapps/mono2.txt
@@ -2,14 +2,17 @@
[Section]
Name = Mono .net Development Framework
-Version = 2.6.7
+Version = 2.8.1
Licence = Unknown
Description = Open Source .net Framework.
-Size = 72MB
+Size = 77MB
Category = 14
URLSite = http://www.mono-project.com/Main_Page
-URLDownload = http://ftp.novell.com/pub/mono/archive/2.6.7/windows-installer/2/mono-2.6.7-gtksharp-2.12.10-win32-2.exe
+URLDownload = http://ftp.novell.com/pub/mono/archive/2.8.1/windows-installer/3/mono-2.8.1-gtksharp-2.12.10-win32-3.exe
CDPath = none
+[Section.0415]
+Description = Pakiet Mono .net Framework dla Programistów.
+
[Section.0422]
Description = Відкритий .net Фреймворк.
diff --git a/base/applications/rapps/rapps/mpc.txt b/base/applications/rapps/rapps/mpc.txt
index cf59628dcc3..d89fb38bb6a 100644
--- a/base/applications/rapps/rapps/mpc.txt
+++ b/base/applications/rapps/rapps/mpc.txt
@@ -20,5 +20,8 @@ Description = Reproductor multimedia.
[Section.0419]
Description = Мультимедийный проигрыватель.
+[Section.0415]
+Description = Odtwarzacz multimediów.
+
[Section.0422]
Description = Мультимедійний програвач.
diff --git a/base/applications/rapps/rapps/net11.txt b/base/applications/rapps/rapps/net11.txt
index f6d4ca63f27..15966d9b229 100644
--- a/base/applications/rapps/rapps/net11.txt
+++ b/base/applications/rapps/rapps/net11.txt
@@ -10,3 +10,6 @@ Category = 14
URLSite = http://www.microsoft.com/downloads/details.aspx?FamilyId=262D25E3-F589-4842-8157-034D1E7CF3A3
URLDownload = http://download.microsoft.com/download/a/a/c/aac39226-8825-44ce-90e3-bf8203e74006/dotnetfx.exe
CDPath = none
+
+[Section.0415]
+Description = Microsoft .NET Framework Wersja 1.1 - Pakiet Dystrybucyjny.
diff --git a/base/applications/rapps/rapps/net20.txt b/base/applications/rapps/rapps/net20.txt
index cb83683985c..a29ed102861 100644
--- a/base/applications/rapps/rapps/net20.txt
+++ b/base/applications/rapps/rapps/net20.txt
@@ -10,3 +10,6 @@ Category = 14
URLSite = http://www.microsoft.com/downloads/details.aspx?FamilyID=0856eacb-4362-4b0d-8edd-aab15c5e04f5
URLDownload = http://download.microsoft.com/download/5/6/7/567758a3-759e-473e-bf8f-52154438565a/dotnetfx.exe
CDPath = none
+
+[Section.0415]
+Description = Microsoft .NET Framework Wersja 2.0 - Pakiet Dystrybucyjny.
diff --git a/base/applications/rapps/rapps/net20sp2.txt b/base/applications/rapps/rapps/net20sp2.txt
index 65c98858d43..1901bfe937e 100644
--- a/base/applications/rapps/rapps/net20sp2.txt
+++ b/base/applications/rapps/rapps/net20sp2.txt
@@ -10,3 +10,6 @@ Category = 14
URLSite = http://www.microsoft.com/downloads/details.aspx?familyid=5B2C0358-915B-4EB5-9B1D-10E506DA9D0F
URLDownload = http://download.microsoft.com/download/c/6/e/c6e88215-0178-4c6c-b5f3-158ff77b1f38/NetFx20SP2_x86.exe
CDPath = none
+
+[Section.0415]
+Description = Microsoft .NET Framework Wersja 2.0 Service Pack 2.
\ No newline at end of file
diff --git a/base/applications/rapps/rapps/openttd.txt b/base/applications/rapps/rapps/openttd.txt
index 9f038ffe93f..43d57387674 100644
--- a/base/applications/rapps/rapps/openttd.txt
+++ b/base/applications/rapps/rapps/openttd.txt
@@ -2,13 +2,13 @@
[Section]
Name = OpenTTD
-Version = 1.0.4
+Version = 1.0.5
Licence = GPL v2
Description = Open Source clone of the "Transport Tycoon Deluxe" game engine. You need a copy of Transport Tycoon.
Size = 3.4MB
Category = 4
URLSite = http://www.openttd.org/
-URLDownload = http://cz.binaries.openttd.org/openttd/binaries/releases/1.0.4/openttd-1.0.4-windows-win32.exe
+URLDownload = http://cz.binaries.openttd.org/openttd/binaries/releases/1.0.5/openttd-1.0.5-windows-win32.exe
CDPath = none
[Section.0407]
diff --git a/base/applications/rapps/rapps/opera.txt b/base/applications/rapps/rapps/opera.txt
index 6852b4c8492..f16c517559b 100644
--- a/base/applications/rapps/rapps/opera.txt
+++ b/base/applications/rapps/rapps/opera.txt
@@ -2,13 +2,13 @@
[Section]
Name = Opera
-Version = 10.62
+Version = 10.63
Licence = Freeware
Description = The popular Opera Browser with many advanced features and including a Mail and BitTorrent client.
Size = 12.7M
Category = 5
URLSite = http://www.opera.com/
-URLDownload = http://get4.opera.com/pub/opera/win/1062/int/Opera_1062_int_Setup.exe
+URLDownload = http://get4.opera.com/pub/opera/win/1063/int/Opera_1063_int_Setup.exe
CDPath = none
[Section.0407]
diff --git a/base/applications/rapps/rapps/python.txt b/base/applications/rapps/rapps/python.txt
index 4664d47b104..4c77199eb62 100644
--- a/base/applications/rapps/rapps/python.txt
+++ b/base/applications/rapps/rapps/python.txt
@@ -14,5 +14,9 @@ CDPath = none
[Section.0407]
Description = Eine sehr mächtige, dynamische Programmiersprache.
+
+[Section.0415]
+Description = Potęży i dynamiczny język programowania.
+
[Section.0422]
Description = Дуже потужна динамічна мова програмування.
diff --git a/base/applications/rapps/rapps/remood.txt b/base/applications/rapps/rapps/remood.txt
index 7ee5f97ee55..dd58417f4fa 100644
--- a/base/applications/rapps/rapps/remood.txt
+++ b/base/applications/rapps/rapps/remood.txt
@@ -14,5 +14,8 @@ CDPath = none
[Section.0407]
Description = ReMooD ist ein Port des Doom Legacy Sources. Es versucht das klassische Legacy Erfahrung zusammen mit neuen Features und mehr Stabilitt zu bieten. Untersttzt werden Windows 98/98SE/ME/NT/2000/XP/2003/ Vista/2008/7/XP 64-bit/2003 64-bit/Vista 64-bit/2008 64-bit/7 64-bit; ReactOS 0.3.x und hher; und Linux (x86 und x86_64).
+[Section.0415]
+Description = rdowy port Doom. Jego celem jest zapewnienie rozrywki znanej z klasycznej wersji z nowymi funkcjami, i lepsz stabilnoci. Obsuguje Windows 98/98SE/ME/NT/2000/XP/2003/ Vista/2008/7/XP 64-bit/2003 64-bit/Vista 64-bit/2008 64-bit/7 64-bit; ReactOS 0.3.x i wysze; i Linux (x86 i x86_64).
+
[Section.0422]
Description = ReMooD э Портом вихідних кодів Doom Legacy. Його метою є додати нові можливості та стабільність до досвіду класичного Legacy. Він підтримує Windows 98/98SE/ME/NT/2000/XP/2003/ Vista/2008/7/XP 64-bit/2003 64-bit/Vista 64-bit/2008 64-bit/7 64-bit; ReactOS 0.3.x та новіші; а також Linux (x86 та x86_64).
diff --git a/base/applications/rapps/rapps/scite.txt b/base/applications/rapps/rapps/scite.txt
index 6fe68efa4d6..bdb56884200 100644
--- a/base/applications/rapps/rapps/scite.txt
+++ b/base/applications/rapps/rapps/scite.txt
@@ -2,13 +2,13 @@
[Section]
Name = SciTE
-Version = 2.21
+Version = 2.22
Licence = Freeware
Description = SciTE is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs.
Size = 0.6M
Category = 7
URLSite = http://www.scintilla.org/
-URLDownload = http://kent.dl.sourceforge.net/project/scintilla/SciTE/2.21/Sc221.exe
+URLDownload = http://kent.dl.sourceforge.net/project/scintilla/SciTE/2.22/Sc222.exe
CDPath = none
[Section.0407]
@@ -17,5 +17,8 @@ Description = SciTE ist ein SCIntilla basierter Text Editor. Ursprünglich wurde
[Section.040a]
Description = Editor de texto basado en SCIntilla. Originalmente creado para demostrar Scintilla, a crecido para ser un gran editor con capacidad para crear y ejecutar programas.
+[Section.0415]
+Description = SciTE to edytor tekstu bazowany na SCIntilla. Oryginalnie stworzony aby pokazać Scintille, stał sie ogólnie przydatnym edytorem z infrastrukturą potrzebną do tworzenia i uruchamiania programów.
+
[Section.0422]
Description = Текстовий редактор на основі SCIntilla. Був зібраний як презентація Scintilla, але виріс до редактора загального користування з засобами збирання та запуску програм.
diff --git a/base/applications/rapps/rapps/scummvm.txt b/base/applications/rapps/rapps/scummvm.txt
index 27747581a66..bc7286ea979 100644
--- a/base/applications/rapps/rapps/scummvm.txt
+++ b/base/applications/rapps/rapps/scummvm.txt
@@ -2,13 +2,13 @@
[Section]
Name = ScummVM
-Version = 1.1.1
+Version = 1.2.0
Licence = GPL
Description = Sam and Max, Day of the Tentacle, etc on ReactOS.
-Size = 3.3MB
+Size = 3.5MB
Category = 4
URLSite = http://scummvm.org/
-URLDownload = http://dfn.dl.sourceforge.net/project/scummvm/scummvm/1.1.1/scummvm-1.1.1-win32.exe
+URLDownload = http://dfn.dl.sourceforge.net/project/scummvm/scummvm/1.2.0/scummvm-1.2.0-win32.exe
CDPath = none
[Section.0407]
diff --git a/base/applications/rapps/rapps/seamonkey.txt b/base/applications/rapps/rapps/seamonkey.txt
index 3dd172cfb9e..ae5b9134110 100644
--- a/base/applications/rapps/rapps/seamonkey.txt
+++ b/base/applications/rapps/rapps/seamonkey.txt
@@ -2,31 +2,31 @@
[Section]
Name = Mozilla SeaMonkey
-Version = 2.0.8
+Version = 2.0.10
Licence = MPL/GPL/LGPL
Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Chat, and Composer bundle you will ever need.
Size = 10.1MB
Category = 5
URLSite = http://www.seamonkey-project.org/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/en-US/SeaMonkey%20Setup%202.0.8.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.10/win32/en-US/SeaMonkey%20Setup%202.0.10.exe
CDPath = none
[Section.0407]
Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen.
Size = 10.0MB
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/de/SeaMonkey%20Setup%202.0.8.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.10/win32/de/SeaMonkey%20Setup%202.0.10.exe
[Section.040a]
Description = La suite de Mozilla está viva. Es el primero y único navegador web, gestor de correo, lector de noticias, Chat y editor HTML que necesitarás.
Size = 10.0MB
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/es-ES/SeaMonkey%20Setup%202.0.8.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.10/win32/es-ES/SeaMonkey%20Setup%202.0.10.exe
[Section.0415]
Description = Pakiet Mozilla żyje. W zestawie: przeglądarka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz.
Size = 10.8MB
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/pl/SeaMonkey%20Setup%202.0.8.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.10/win32/pl/SeaMonkey%20Setup%202.0.10.exe
[Section.0419]
Description = Продолжение Mozilla Suite. Включает браузер, почтовый клиент, IRC-клиент и HTML-редактор.
Size = 10.4MB
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/ru/SeaMonkey%20Setup%202.0.8.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.10/win32/ru/SeaMonkey%20Setup%202.0.10.exe
diff --git a/base/applications/rapps/rapps/steam.txt b/base/applications/rapps/rapps/steam.txt
index 3caccc4e584..9d4a0af1012 100644
--- a/base/applications/rapps/rapps/steam.txt
+++ b/base/applications/rapps/rapps/steam.txt
@@ -14,5 +14,8 @@ CDPath = none
[Section.0407]
Description = Die STEAM Spieleplattform, die von viele Spielen verwendet wird.
+[Section.0415]
+Description = STEAM - platforma, którą używa obecnie wiele gier.
+
[Section.0422]
Description = Ігрова платформа, що використовується багатьма іграми.
diff --git a/base/applications/rapps/rapps/superfinder.txt b/base/applications/rapps/rapps/superfinder.txt
index 02b55605cc3..9098b11e8db 100644
--- a/base/applications/rapps/rapps/superfinder.txt
+++ b/base/applications/rapps/rapps/superfinder.txt
@@ -13,3 +13,6 @@ CDPath = none
[Section.0407]
Description = Eine schnelle und effektive Suchanwendung.
+
+[Section.0415]
+Description = Szybka i bogata w opcje aplikacja szukająca.
diff --git a/base/applications/rapps/rapps/tahoma.txt b/base/applications/rapps/rapps/tahoma.txt
index b5c87a0d3fe..c5e57fdf4b4 100644
--- a/base/applications/rapps/rapps/tahoma.txt
+++ b/base/applications/rapps/rapps/tahoma.txt
@@ -15,6 +15,9 @@ CDPath = none
Licence = Unbekannt
Description = Tahoma Font pack, der von einigen Anwendungen benötigt wird (Steam).
+[Section.0415]
+Description = Pakiet Czcionki Tahoma wymagany przez niektóre programy (np. Steam).
+
[Section.0422]
Licence = Невідома
Description = Пакет шрифтів Tahoma, що необхідні деяким програмам (Steam).
diff --git a/base/applications/rapps/rapps/thunderbird.txt b/base/applications/rapps/rapps/thunderbird.txt
index 71dce2f44bc..2e120b09a7c 100644
--- a/base/applications/rapps/rapps/thunderbird.txt
+++ b/base/applications/rapps/rapps/thunderbird.txt
@@ -2,41 +2,41 @@
[Section]
Name = Mozilla Thunderbird
-Version = 3.1.4
+Version = 3.1.6
Licence = MPL/GPL/LGPL
Description = The most popular and one of the best free Mail Clients out there.
Size = 9.0M
Category = 5
URLSite = http://www.mozilla-europe.org/en/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/en-US/Thunderbird%20Setup%203.1.4.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.6/win32/en-US/Thunderbird%20Setup%203.1.6.exe
CDPath = none
[Section.0407]
Description = Der populärste und einer der besten freien Mail-Clients.
Size = 8.8M
URLSite = http://www.mozilla-europe.org/de/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/de/Thunderbird%20Setup%203.1.4.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.6/win32/de/Thunderbird%20Setup%203.1.6.exe
[Section.040a]
Description = El más popular y uno de los mejores clientes mail que hay.
Size = 8.8M
URLSite = http://www.mozilla-europe.org/es/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/es-ES/Thunderbird%20Setup%203.1.4.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.6/win32/es-ES/Thunderbird%20Setup%203.1.6.exe
[Section.0415]
Description = Najpopularniejszy i jeden z najlepszych darmowych klientów poczty.
Size = 9.7M
URLSite = http://www.mozilla-europe.org/pl/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/pl/Thunderbird%20Setup%203.1.4.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.6/win32/pl/Thunderbird%20Setup%203.1.6.exe
[Section.0419]
Description = Один из самых популярных и лучших бесплатных почтовых клиентов.
Size = 9.2M
URLSite = http://www.mozilla-europe.org/ru/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/ru/Thunderbird%20Setup%203.1.4.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.6/win32/ru/Thunderbird%20Setup%203.1.6.exe
[Section.0422]
Description = Найпопулярніший та один з кращих поштових клієнтів.
Size = 9.2M
URLSite = http://www.mozillamessaging.com/uk/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/uk/Thunderbird%20Setup%203.1.4.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.6/win32/uk/Thunderbird%20Setup%203.1.6.exe
diff --git a/base/applications/rapps/rapps/ultravnc.txt b/base/applications/rapps/rapps/ultravnc.txt
index f00b1434902..89ab6740655 100644
--- a/base/applications/rapps/rapps/ultravnc.txt
+++ b/base/applications/rapps/rapps/ultravnc.txt
@@ -2,17 +2,20 @@
[Section]
Name = UltraVNC
-Version = 1.0.8.2
+Version = 1.0.9.1
Licence = GPL
Description = Open-source VNC client/server.
-Size = 1.9MB
+Size = 2.0MB
Category = 5
URLSite = http://www.uvnc.com/
-URLDownload = http://support1.uvnc.com/download/1082/UltraVNC_1.0.8.2_Setup.exe
+URLDownload = http://support1.uvnc.com/download/109/UltraVNC_1.0.9.1_Setup.exe
CDPath = none
[Section.040a]
Description = Cliente/Servidor VNC de código abierto.
+[Section.0415]
+Description = Otwarty klient/serwer VNC.
+
[Section.0422]
Description = Відкритий VNC клієнт/сервер.
diff --git a/base/applications/rapps/rapps/utorrent.txt b/base/applications/rapps/rapps/utorrent.txt
index cb05f9bd3e0..86fa5ae6884 100644
--- a/base/applications/rapps/rapps/utorrent.txt
+++ b/base/applications/rapps/rapps/utorrent.txt
@@ -2,13 +2,13 @@
[Section]
Name = µTorrent
-Version = 2.0.4
+Version = 2.2
Licence = Freeware for non-commercial uses
Description = Small and fast BitTorrent Client.
-Size = 320K
+Size = 385K
Category = 5
URLSite = http://www.utorrent.com/
-URLDownload = http://download.utorrent.com/2.0.4/utorrent.exe
+URLDownload = http://download.utorrent.com/2.2/utorrent.exe
CDPath = none
diff --git a/base/applications/rapps/rapps/vlc.txt b/base/applications/rapps/rapps/vlc.txt
index 8a362fa2428..76c8c74fe8b 100644
--- a/base/applications/rapps/rapps/vlc.txt
+++ b/base/applications/rapps/rapps/vlc.txt
@@ -2,13 +2,13 @@
[Section]
Name = VLC media player
-Version = 1.1.4
+Version = 1.1.5
Licence = GPL
Description = A media player.
-Size = 18.7MB
+Size = 19.1MB
Category = 1
URLSite = http://www.videolan.org/vlc/
-URLDownload = http://ignum.dl.sourceforge.net/project/vlc/1.1.4/win32/vlc-1.1.4-win32.exe
+URLDownload = http://ignum.dl.sourceforge.net/project/vlc/1.1.5/win32/vlc-1.1.5-win32.exe
CDPath = none
[Section.0407]
@@ -20,5 +20,8 @@ Description = Reproductor multimedia.
[Section.0419]
Description = Мультимедийный проигрыватель.
+[Section.0415]
+Description = Odtwarzacz multimediów.
+
[Section.0422]
Description = Мультимедійний програвач.
diff --git a/base/applications/regedit/childwnd.c b/base/applications/regedit/childwnd.c
index 6675e21d4ec..56ab005334e 100644
--- a/base/applications/regedit/childwnd.c
+++ b/base/applications/regedit/childwnd.c
@@ -67,19 +67,21 @@ static void draw_splitbar(HWND hWnd, int x)
static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy)
{
- HDWP hdwp = BeginDeferWindowPos(2);
- RECT rt, rs;
-
+ HDWP hdwp = BeginDeferWindowPos(3);
+ RECT rt, rs, rb;
+ const int tHeight = 18;
SetRect(&rt, 0, 0, cx, cy);
cy = 0;
if (hStatusBar != NULL) {
GetWindowRect(hStatusBar, &rs);
- cy = rs.bottom - rs.top + 8;
+ cy = rs.bottom - rs.top;
}
+ GetWindowRect(pChildWnd->hAddressBtnWnd, &rb);
cx = pChildWnd->nSplitPos + SPLIT_WIDTH/2;
- DeferWindowPos(hdwp, pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left, 23, SWP_NOZORDER|SWP_NOACTIVATE);
- DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + 25, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
- DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx , rt.top + 25, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
+ DeferWindowPos(hdwp, pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left - tHeight-2, tHeight, SWP_NOZORDER|SWP_NOACTIVATE);
+ DeferWindowPos(hdwp, pChildWnd->hAddressBtnWnd, 0, rt.right - tHeight, rt.top, tHeight, tHeight, SWP_NOZORDER|SWP_NOACTIVATE);
+ DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + tHeight+2, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
+ DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx, rt.top + tHeight+2, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
EndDeferWindowPos(hdwp);
}
@@ -259,7 +261,7 @@ static void SuggestKeys(HKEY hRootKey, LPCTSTR pszKeyPath, LPTSTR pszSuggestions
/* Check CLSID key */
if (RegOpenKey(hRootKey, pszKeyPath, &hSubKey) == ERROR_SUCCESS)
{
- if (QueryStringValue(hSubKey, TEXT("CLSID"), NULL, szBuffer,
+ if (QueryStringValue(hSubKey, TEXT("CLSID"), NULL, szBuffer,
COUNT_OF(szBuffer)) == ERROR_SUCCESS)
{
lstrcpyn(pszSuggestions, TEXT("HKCR\\CLSID\\"), (int) iSuggestionsLength);
@@ -324,29 +326,35 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
/* load "My Computer" string */
LoadString(hInst, IDS_MY_COMPUTER, buffer, sizeof(buffer)/sizeof(TCHAR));
- g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd));
+ g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd));
if (!pChildWnd) return 0;
_tcsncpy(pChildWnd->szPath, buffer, MAX_PATH);
pChildWnd->nSplitPos = 250;
pChildWnd->hWnd = hWnd;
- pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP,
+ pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hWnd, (HMENU)0, hInst, 0);
+ pChildWnd->hAddressBtnWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Button"), _T("»"), WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_DEFPUSHBUTTON,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ hWnd, (HMENU)0, hInst, 0);
pChildWnd->hTreeWnd = CreateTreeView(hWnd, pChildWnd->szPath, (HMENU) TREE_WINDOW);
pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, pChildWnd->szPath*/);
SetFocus(pChildWnd->hTreeWnd);
- /* set the address bar font */
- if (pChildWnd->hAddressBarWnd)
+ /* set the address bar and button font */
+ if ((pChildWnd->hAddressBarWnd) && (pChildWnd->hAddressBtnWnd))
{
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(pChildWnd->hAddressBarWnd,
WM_SETFONT,
(WPARAM)hFont,
0);
+ SendMessage(pChildWnd->hAddressBtnWnd,
+ WM_SETFONT,
+ (WPARAM)hFont,
+ 0);
}
-
/* Subclass the AddressBar */
oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_WNDPROC);
SetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_USERDATA, (DWORD_PTR)oldproc);
@@ -354,7 +362,10 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
break;
}
case WM_COMMAND:
- if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
+ if(HIWORD(wParam) == BN_CLICKED){
+ PostMessage(pChildWnd->hAddressBarWnd, WM_KEYUP, VK_RETURN, 0);
+ }
+ else if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
goto def;
}
break;
@@ -477,10 +488,28 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
rootName = get_root_key_name(hRootKey);
fullPath = HeapAlloc(GetProcessHeap(), 0, (_tcslen(rootName) + 1 + _tcslen(keyPath) + 1) * sizeof(TCHAR));
if (fullPath) {
- _stprintf(fullPath, _T("%s\\%s"), rootName, keyPath);
+ /* set (correct) the address bar text */
+ if(keyPath[0] != '\0')
+ _stprintf(fullPath, _T("%s\\%s"), rootName, keyPath);
+ else
+ fullPath = _tcscpy(fullPath, rootName);
SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath);
SendMessage(pChildWnd->hAddressBarWnd, WM_SETTEXT, 0, (LPARAM)fullPath);
- HeapFree(GetProcessHeap(), 0, fullPath);
+ HeapFree(GetProcessHeap(), 0, fullPath);
+ /* disable hive manipulation items temporarily (enable only if necessary) */
+ EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_GRAYED);
+ EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_UNLOADHIVE, MF_BYCOMMAND | MF_GRAYED);
+ /* compare the strings to see if we should enable/disable the "Load Hive" menus accordingly */
+ if (!(_tcsicmp(rootName, TEXT("HKEY_LOCAL_MACHINE")) &&
+ _tcsicmp(rootName, TEXT("HKEY_USERS"))))
+ {
+ // enable the unload menu item if at the root
+ // otherwise enable the load menu item if there is no slash in keyPath (ie. immediate child selected)
+ if(keyPath[0] == '\0')
+ EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_ENABLED);
+ else if(!_tcschr(keyPath, _T('\\')))
+ EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_UNLOADHIVE, MF_BYCOMMAND | MF_ENABLED);
+ }
{
HKEY hKey;
diff --git a/base/applications/regedit/edit.c b/base/applications/regedit/edit.c
index 9812b9bf625..85a5bd853e8 100644
--- a/base/applications/regedit/edit.c
+++ b/base/applications/regedit/edit.c
@@ -59,19 +59,10 @@ void error(HWND hwnd, INT resId, ...)
static void error_code_messagebox(HWND hwnd, DWORD error_code)
{
- LPTSTR lpMsgBuf;
- DWORD status;
TCHAR title[256];
- static const TCHAR fallback[] = TEXT("Error displaying error message.\n");
if (!LoadString(hInst, IDS_ERROR, title, COUNT_OF(title)))
lstrcpy(title, TEXT("Error"));
- status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, error_code, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
- if (!status)
- lpMsgBuf = (LPTSTR)fallback;
- MessageBox(hwnd, lpMsgBuf, title, MB_OK | MB_ICONERROR);
- if (lpMsgBuf != fallback)
- LocalFree(lpMsgBuf);
+ ErrorMessageBox(hwnd, title, error_code);
}
void warning(HWND hwnd, INT resId, ...)
diff --git a/base/applications/regedit/error.c b/base/applications/regedit/error.c
new file mode 100644
index 00000000000..aaadf1af600
--- /dev/null
+++ b/base/applications/regedit/error.c
@@ -0,0 +1,14 @@
+#include
+void ErrorMessageBox(HWND hWnd, LPCTSTR title, DWORD code)
+{
+ LPTSTR lpMsgBuf;
+ DWORD status;
+ static const TCHAR fallback[] = TEXT("Error displaying error message.\n");
+ status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, code, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
+ if (!status)
+ lpMsgBuf = (LPTSTR)fallback;
+ MessageBox(hWnd, lpMsgBuf, title, MB_OK | MB_ICONERROR);
+ if (lpMsgBuf != fallback)
+ LocalFree(lpMsgBuf);
+}
diff --git a/base/applications/regedit/framewnd.c b/base/applications/regedit/framewnd.c
index 4e465e6bb30..aa3a649f5da 100644
--- a/base/applications/regedit/framewnd.c
+++ b/base/applications/regedit/framewnd.c
@@ -282,6 +282,105 @@ static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
return TRUE;
}
+static INT_PTR CALLBACK LoadHive_KeyNameInHookProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static LPTSTR sKey = NULL;
+ static INT sLength = 0;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ sKey = (LPTSTR)lParam;
+ sLength = 128; /* FIXME: Ugly hack! */
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ if(GetDlgItemText(hWndDlg, IDC_EDIT_KEY, sKey, sLength))
+ return EndDialog(hWndDlg, -1);
+ else
+ return EndDialog(hWndDlg, 0);
+ case IDCANCEL:
+ return EndDialog(hWndDlg, 0);
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static BOOL LoadHive(HWND hWnd)
+{
+ OPENFILENAME ofn;
+ TCHAR Caption[128];
+ LPCTSTR pszKeyPath;
+ TCHAR xPath[128];
+ HKEY hRootKey;
+ TCHAR Filter[1024];
+ FILTERPAIR filter;
+ /* get the item key to load the hive in */
+ pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
+ /* initialize the "open file" dialog */
+ InitOpenFileName(hWnd, &ofn);
+ /* build the "All Files" filter up */
+ filter.DisplayID = IDS_FLT_ALLFILES;
+ filter.FilterID = IDS_FLT_ALLFILES_FLT;
+ BuildFilterStrings(Filter, &filter, sizeof(filter));
+ ofn.lpstrFilter = Filter;
+ /* load and set the caption and flags for dialog */
+ LoadString(hInst, IDS_LOAD_HIVE, Caption, COUNT_OF(Caption));
+ ofn.lpstrTitle = Caption;
+ ofn.Flags |= OFN_ENABLESIZING;
+ /* ofn.lCustData = ;*/
+ /* now load the hive */
+ if (GetOpenFileName(&ofn))
+ {
+ if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_LOADHIVE), hWnd, &LoadHive_KeyNameInHookProc, (LPARAM)xPath))
+ {
+ LONG regLoadResult = RegLoadKey(hRootKey, xPath, ofn.lpstrFile);
+ if(regLoadResult == ERROR_SUCCESS)
+ {
+ /* refresh tree and list views */
+ RefreshTreeView(g_pChildWnd->hTreeWnd);
+ pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
+ RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
+ }
+ else
+ {
+ ErrorMessageBox(hWnd, Caption, regLoadResult);
+ return FALSE;
+ }
+ }
+ } else {
+ CheckCommDlgError(hWnd);
+ }
+ return TRUE;
+}
+
+static BOOL UnloadHive(HWND hWnd)
+{
+ TCHAR Caption[128];
+ LPCTSTR pszKeyPath;
+ HKEY hRootKey;
+ /* get the item key to unload */
+ pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
+ /* load and set the caption and flags for dialog */
+ LoadString(hInst, IDS_UNLOAD_HIVE, Caption, COUNT_OF(Caption));
+ /* now unload the hive */
+ LONG regUnloadResult = RegUnLoadKey(hRootKey, pszKeyPath);
+ if(regUnloadResult == ERROR_SUCCESS)
+ {
+ /* refresh tree and list views */
+ RefreshTreeView(g_pChildWnd->hTreeWnd);
+ pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
+ RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
+ }
+ else
+ {
+ ErrorMessageBox(hWnd, Caption, regUnloadResult);
+ return FALSE;
+ }
+ return TRUE;
+}
+
static BOOL ImportRegistryFile(HWND hWnd)
{
OPENFILENAME ofn;
@@ -316,7 +415,6 @@ static BOOL ImportRegistryFile(HWND hWnd)
return TRUE;
}
-
static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
HWND hwndExportAll;
@@ -397,7 +495,7 @@ BOOL ExportRegistryFile(HWND hWnd)
if (GetSaveFileName(&ofn)) {
BOOL result;
DWORD format;
-
+
if (ofn.nFilterIndex == 1)
format = REG_FORMAT_5;
else
@@ -758,6 +856,12 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
UNREFERENCED_PARAMETER(message);
switch (LOWORD(wParam)) {
+ case ID_REGISTRY_LOADHIVE:
+ LoadHive(hWnd);
+ return TRUE;
+ case ID_REGISTRY_UNLOADHIVE:
+ UnloadHive(hWnd);
+ return TRUE;
case ID_REGISTRY_IMPORTREGISTRYFILE:
ImportRegistryFile(hWnd);
return TRUE;
diff --git a/base/applications/regedit/lang/bg-BG.rc b/base/applications/regedit/lang/bg-BG.rc
index 7ecabedf807..da8521bc924 100644
--- a/base/applications/regedit/lang/bg-BG.rc
+++ b/base/applications/regedit/lang/bg-BG.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -276,6 +286,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE " "
ID_REGISTRY_EXPORTREGISTRYFILE
" "
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
" "
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -332,6 +346,8 @@ BEGIN
IDS_MY_COMPUTER " "
IDS_IMPORT_REG_FILE " "
IDS_EXPORT_REG_FILE " "
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "( )"
END
diff --git a/base/applications/regedit/lang/cs-CZ.rc b/base/applications/regedit/lang/cs-CZ.rc
index c1d12dbfa95..9226c8eb36a 100644
--- a/base/applications/regedit/lang/cs-CZ.rc
+++ b/base/applications/regedit/lang/cs-CZ.rc
@@ -175,6 +175,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -274,6 +284,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importuje textov soubor do registru"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exportuje vechny sti registru do textovho souboru"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Pipoj se ke vzdlenmu registru jinho potae"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -330,6 +344,8 @@ BEGIN
IDS_MY_COMPUTER "Tento pota"
IDS_IMPORT_REG_FILE "Importovat soubor registru"
IDS_EXPORT_REG_FILE "Exportovat do souboru registru"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(Neplatn hodnota DWORD)"
END
diff --git a/base/applications/regedit/lang/de-DE.rc b/base/applications/regedit/lang/de-DE.rc
index 4cf8657a80f..8d6f251f962 100644
--- a/base/applications/regedit/lang/de-DE.rc
+++ b/base/applications/regedit/lang/de-DE.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -276,6 +286,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importiert eine Textddatei in die Registry"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exportiert Teile oder die ganze Registry in eine Textdatei"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Verbindet zu einer Registry eines Fremdcomputers"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -332,6 +346,8 @@ BEGIN
IDS_MY_COMPUTER "Arbeitsplatz"
IDS_IMPORT_REG_FILE "Registry importieren"
IDS_EXPORT_REG_FILE "Registry exportieren"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(ungltiger DWORD-Wert)"
END
diff --git a/base/applications/regedit/lang/el-GR.rc b/base/applications/regedit/lang/el-GR.rc
index 281ed2d299e..44ca2d9f33c 100644
--- a/base/applications/regedit/lang/el-GR.rc
+++ b/base/applications/regedit/lang/el-GR.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -276,6 +286,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE " registry"
ID_REGISTRY_EXPORTREGISTRYFILE
" registry "
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
" registry "
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -332,6 +346,8 @@ BEGIN
IDS_MY_COMPUTER " "
IDS_IMPORT_REG_FILE " Registry"
IDS_EXPORT_REG_FILE " Registry"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "( DWORD )"
END
diff --git a/base/applications/regedit/lang/en-US.rc b/base/applications/regedit/lang/en-US.rc
index e5a94cba8e7..fb81f164e87 100644
--- a/base/applications/regedit/lang/en-US.rc
+++ b/base/applications/regedit/lang/en-US.rc
@@ -274,6 +274,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Imports a text file into the registry"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exports all or part of the registry to a text file"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Connects to a remote computer's registry"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -330,6 +334,8 @@ BEGIN
IDS_MY_COMPUTER "My Computer"
IDS_IMPORT_REG_FILE "Import Registry File"
IDS_EXPORT_REG_FILE "Export Registry File"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(invalid DWORD value)"
END
@@ -392,6 +398,20 @@ BEGIN
EDITTEXT IDC_EXPORT_BRANCH_TEXT,30,34,335,12
END
+//
+// Dialog resources
+//
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
+
IDD_ADDFAVORITES DIALOGEX DISCARDABLE 0, 0, 186, 46
STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Add to Favorites"
diff --git a/base/applications/regedit/lang/es-ES.rc b/base/applications/regedit/lang/es-ES.rc
index b128846bca1..0e1dc4c5d86 100644
--- a/base/applications/regedit/lang/es-ES.rc
+++ b/base/applications/regedit/lang/es-ES.rc
@@ -180,6 +180,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -279,6 +289,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importa un archivo de texto al registro"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exporta todo o parte del registro a un archivo de texto"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Se conecta al registro de un ordenador remoto"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -335,6 +349,8 @@ BEGIN
IDS_MY_COMPUTER "Mi PC"
IDS_IMPORT_REG_FILE "Importa Fichero de Registro"
IDS_EXPORT_REG_FILE "Exporta Fichero de Registro"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(valor DWORD invalido)"
END
diff --git a/base/applications/regedit/lang/fr-FR.rc b/base/applications/regedit/lang/fr-FR.rc
index c5042da4c9a..56e31bcd755 100644
--- a/base/applications/regedit/lang/fr-FR.rc
+++ b/base/applications/regedit/lang/fr-FR.rc
@@ -180,6 +180,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -279,6 +289,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importe un fichier texte dans les registres"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exporte tout ou une partie des registres dans un fichier texte"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Connecte aux registres d'un ordinateur distant"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -335,6 +349,8 @@ BEGIN
IDS_MY_COMPUTER "Mon ordinateur"
IDS_IMPORT_REG_FILE "Importer un fichier registre"
IDS_EXPORT_REG_FILE "Exporter un fichier registre"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(valeur mot double invalide)"
END
diff --git a/base/applications/regedit/lang/hu-HU.rc b/base/applications/regedit/lang/hu-HU.rc
index 42faef3a4ea..7efa45d5221 100644
--- a/base/applications/regedit/lang/hu-HU.rc
+++ b/base/applications/regedit/lang/hu-HU.rc
@@ -178,6 +178,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -277,6 +287,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Imports a text file into the registry"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exports all or part of the registry to a text file"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Connects to a remote computer's registry"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -333,6 +347,8 @@ BEGIN
IDS_MY_COMPUTER "My Computer"
IDS_IMPORT_REG_FILE "Import Registry File"
IDS_EXPORT_REG_FILE "Export Registry File"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(invalid DWORD value)"
END
diff --git a/base/applications/regedit/lang/id-ID.rc b/base/applications/regedit/lang/id-ID.rc
index 059abec9576..4d8571470fe 100644
--- a/base/applications/regedit/lang/id-ID.rc
+++ b/base/applications/regedit/lang/id-ID.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -276,6 +286,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Mengimpor file teks ke dalam registri"
ID_REGISTRY_EXPORTREGISTRYFILE
"Mengekspor semua atau sebagian registri le file teks"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Menyambung ke registri komputer remote"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -332,6 +346,8 @@ BEGIN
IDS_MY_COMPUTER "My Computer"
IDS_IMPORT_REG_FILE "Impor File Registri"
IDS_EXPORT_REG_FILE "Ekspor File Registri"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(nilai DWORD tidak benar)"
END
diff --git a/base/applications/regedit/lang/it-IT.rc b/base/applications/regedit/lang/it-IT.rc
index 53c68565cb2..8f81f05ea36 100644
--- a/base/applications/regedit/lang/it-IT.rc
+++ b/base/applications/regedit/lang/it-IT.rc
@@ -180,6 +180,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -281,6 +291,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importa un file di testo nel Registro"
ID_REGISTRY_EXPORTREGISTRYFILE
"Esporta tutto o parte del Registro in un file di testo"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Si connette al Registro di un computer remoto"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -337,6 +351,8 @@ BEGIN
IDS_MY_COMPUTER "Il mio Computer"
IDS_IMPORT_REG_FILE "Importa file di Registro"
IDS_EXPORT_REG_FILE "Esporta file di Registro"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(valore DWORD non valido)"
END
diff --git a/base/applications/regedit/lang/ja-JP.rc b/base/applications/regedit/lang/ja-JP.rc
index 8b1816bf03f..66a0967fb17 100644
--- a/base/applications/regedit/lang/ja-JP.rc
+++ b/base/applications/regedit/lang/ja-JP.rc
@@ -175,6 +175,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -274,6 +284,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "eLXg t@CWXgɃC|[g܂B"
ID_REGISTRY_EXPORTREGISTRYFILE
"WXg̈ꕔ܂͑ŜeLXg t@CɃGNX|[g܂B"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"[g Rs[^̃WXgɐڑ܂B"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -330,6 +344,8 @@ BEGIN
IDS_MY_COMPUTER "}C Rs[^"
IDS_IMPORT_REG_FILE "WXg t@C̃C|[g"
IDS_EXPORT_REG_FILE "WXg t@C̃GNX|[g"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "( DWORD l)"
END
diff --git a/base/applications/regedit/lang/ko-KR.rc b/base/applications/regedit/lang/ko-KR.rc
index 01777d0344b..b2057978fca 100644
--- a/base/applications/regedit/lang/ko-KR.rc
+++ b/base/applications/regedit/lang/ko-KR.rc
@@ -162,6 +162,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -261,6 +271,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "ؽƮ Ʈ ҷ ɴϴ"
ID_REGISTRY_EXPORTREGISTRYFILE
"ؽƮ Ϸ Ʈ ü Ϻθ ϴ"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
" ǻ Ʈ մϴ"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -317,6 +331,8 @@ BEGIN
IDS_MY_COMPUTER " ǻ"
IDS_IMPORT_REG_FILE "Ʈ ҷ"
IDS_EXPORT_REG_FILE "Ʈ "
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(߸ DWORD)"
END
diff --git a/base/applications/regedit/lang/nl-NL.rc b/base/applications/regedit/lang/nl-NL.rc
index be86610e59c..2bc09796371 100644
--- a/base/applications/regedit/lang/nl-NL.rc
+++ b/base/applications/regedit/lang/nl-NL.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -276,6 +286,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Een tekstbestand in het register importeren"
ID_REGISTRY_EXPORTREGISTRYFILE
"Het register of een gedeelte ervan naar een tekstbestand exporteren"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Een verbinding maken met het register van een externe computer"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -332,6 +346,8 @@ BEGIN
IDS_MY_COMPUTER "My Computer"
IDS_IMPORT_REG_FILE "Import Registry File"
IDS_EXPORT_REG_FILE "Export Registry File"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(invalid DWORD value)"
END
diff --git a/base/applications/regedit/lang/no-NO.rc b/base/applications/regedit/lang/no-NO.rc
index b052432f8ec..60d0d1af091 100644
--- a/base/applications/regedit/lang/no-NO.rc
+++ b/base/applications/regedit/lang/no-NO.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -276,6 +286,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importerer en tekstfil inn i Registret"
ID_REGISTRY_EXPORTREGISTRYFILE
"Eksporterer hele eller deler av Registret til en tekstfil"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Kobler til Registret p en annen datamaskin"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -332,6 +346,8 @@ BEGIN
IDS_MY_COMPUTER "Min datamaskin"
IDS_IMPORT_REG_FILE "Importer registerfil"
IDS_EXPORT_REG_FILE "Eksporter registerfil"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(ugyldig DWORD-verdi)"
END
diff --git a/base/applications/regedit/lang/pl-PL.rc b/base/applications/regedit/lang/pl-PL.rc
index 198125c772c..4f864f3df01 100644
--- a/base/applications/regedit/lang/pl-PL.rc
+++ b/base/applications/regedit/lang/pl-PL.rc
@@ -182,6 +182,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -281,6 +291,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importuje plik do rejestru"
ID_REGISTRY_EXPORTREGISTRYFILE
"Eksportuje cao lub cz rejestru do pliku"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Poczenie z rejestrem zdalnego komputera"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -337,6 +351,8 @@ BEGIN
IDS_MY_COMPUTER "Mj komputer"
IDS_IMPORT_REG_FILE "Importuj plik rejestru"
IDS_EXPORT_REG_FILE "Eksportuj plik rejestru"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(niewaciwa warto DWORD)"
END
diff --git a/base/applications/regedit/lang/pt-BR.rc b/base/applications/regedit/lang/pt-BR.rc
index 4cd21990e30..7abc3c211ba 100644
--- a/base/applications/regedit/lang/pt-BR.rc
+++ b/base/applications/regedit/lang/pt-BR.rc
@@ -178,6 +178,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -277,6 +287,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importa um arquivo de texto para o registro"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exporta todo ou parte do Registro para um arquivo texto"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Conecta-se ao Registro de um computador remoto"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -333,6 +347,8 @@ BEGIN
IDS_MY_COMPUTER "Meu computador"
IDS_IMPORT_REG_FILE "Importar arquivo do Registro"
IDS_EXPORT_REG_FILE "Exportar arquivo do Registro"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(valor DWORD invlido)"
END
diff --git a/base/applications/regedit/lang/pt-PT.rc b/base/applications/regedit/lang/pt-PT.rc
index 15fee2f3166..52b15fd526c 100644
--- a/base/applications/regedit/lang/pt-PT.rc
+++ b/base/applications/regedit/lang/pt-PT.rc
@@ -277,6 +277,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importa um arquivo texto para o registro."
ID_REGISTRY_EXPORTREGISTRYFILE
"Exporta todo ou parte do registro para um arquivo texto."
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Conecta a um registro em um computador remoto."
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -333,6 +337,8 @@ BEGIN
IDS_MY_COMPUTER "My Computer"
IDS_IMPORT_REG_FILE "Import Registry File"
IDS_EXPORT_REG_FILE "Export Registry File"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(invalid DWORD value)"
END
@@ -384,6 +390,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EXPORTRANGE DIALOGEX DISCARDABLE 50, 50, 370, 50
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
diff --git a/base/applications/regedit/lang/ru-RU.rc b/base/applications/regedit/lang/ru-RU.rc
index 62892800f15..f8e74660ab9 100644
--- a/base/applications/regedit/lang/ru-RU.rc
+++ b/base/applications/regedit/lang/ru-RU.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
@@ -275,6 +285,8 @@ BEGIN
ID_EDIT_NEW_DWORDVALUE " DWORD-"
ID_REGISTRY_IMPORTREGISTRYFILE " "
ID_REGISTRY_EXPORTREGISTRYFILE " "
+ ID_REGISTRY_LOADHIVE "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY " "
@@ -332,6 +344,8 @@ BEGIN
IDS_MY_COMPUTER " "
IDS_IMPORT_REG_FILE " "
IDS_EXPORT_REG_FILE " "
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "( DWORD)"
END
diff --git a/base/applications/regedit/lang/sk-SK.rc b/base/applications/regedit/lang/sk-SK.rc
index f5437e9cb65..b6cb4754993 100644
--- a/base/applications/regedit/lang/sk-SK.rc
+++ b/base/applications/regedit/lang/sk-SK.rc
@@ -162,6 +162,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -261,6 +271,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Imports a text file into the registry"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exports all or part of the registry to a text file"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Connects to a remote computer's registry"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -317,6 +331,8 @@ BEGIN
IDS_MY_COMPUTER "Tento pota"
IDS_IMPORT_REG_FILE "Import Registry File"
IDS_EXPORT_REG_FILE "Export Registry File"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(neplatn DWORD hodnota)"
END
diff --git a/base/applications/regedit/lang/sl-SI.rc b/base/applications/regedit/lang/sl-SI.rc
index d5c5804c881..0be7a429a8a 100644
--- a/base/applications/regedit/lang/sl-SI.rc
+++ b/base/applications/regedit/lang/sl-SI.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -276,6 +286,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "V register uvozi datoteko z besedilom"
ID_REGISTRY_EXPORTREGISTRYFILE
"Registrsko datoteko ali njen del izvozi v besedilno datoteko"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Vzpostavi povezavo z registrom oddaljenega raunalnika"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -332,6 +346,8 @@ BEGIN
IDS_MY_COMPUTER "My Computer"
IDS_IMPORT_REG_FILE "Import Registry File"
IDS_EXPORT_REG_FILE "Export Registry File"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(invalid DWORD value)"
END
diff --git a/base/applications/regedit/lang/sv-SE.rc b/base/applications/regedit/lang/sv-SE.rc
index ee1515dd08b..70832d3e573 100644
--- a/base/applications/regedit/lang/sv-SE.rc
+++ b/base/applications/regedit/lang/sv-SE.rc
@@ -175,6 +175,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -274,6 +284,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Importerar en textfil till registret"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exporterar hela eller en del av registret till en textfil"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Ansluter till en annan dators register"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -330,6 +344,8 @@ BEGIN
IDS_MY_COMPUTER "Den hr datorn"
IDS_IMPORT_REG_FILE "Importera registerfil"
IDS_EXPORT_REG_FILE "Exportera registerfil"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(felaktigt DWORD-vrde)"
END
diff --git a/base/applications/regedit/lang/th-TH.rc b/base/applications/regedit/lang/th-TH.rc
index c7bb7fde7d9..51aa5da0a8f 100644
--- a/base/applications/regedit/lang/th-TH.rc
+++ b/base/applications/regedit/lang/th-TH.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -276,6 +286,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Imports a text file into the registry"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exports all or part of the registry to a text file"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Connects to a remote computer's registry"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -332,6 +346,8 @@ BEGIN
IDS_MY_COMPUTER "My Computer"
IDS_IMPORT_REG_FILE "Import Registry File"
IDS_EXPORT_REG_FILE "Export Registry File"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(invalid DWORD value)"
END
diff --git a/base/applications/regedit/lang/uk-UA.rc b/base/applications/regedit/lang/uk-UA.rc
index 5fd1fa5ec45..6f98e38c0eb 100644
--- a/base/applications/regedit/lang/uk-UA.rc
+++ b/base/applications/regedit/lang/uk-UA.rc
@@ -178,6 +178,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -277,6 +287,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE " "
ID_REGISTRY_EXPORTREGISTRYFILE
" "
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"ϳ '"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -333,6 +347,8 @@ BEGIN
IDS_MY_COMPUTER "̳ '"
IDS_IMPORT_REG_FILE " "
IDS_EXPORT_REG_FILE " "
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "( DWORD)"
END
diff --git a/base/applications/regedit/lang/zh-CN.rc b/base/applications/regedit/lang/zh-CN.rc
index 0d20667cdd3..8e098469ad3 100644
--- a/base/applications/regedit/lang/zh-CN.rc
+++ b/base/applications/regedit/lang/zh-CN.rc
@@ -177,6 +177,16 @@ END
/*
* Dialog
*/
+IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
+STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Load Hive"
+FONT 8, "Ms Shell Dlg"
+{
+ LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
+ EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
+ DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
+ PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
+}
IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP |
@@ -276,6 +286,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "ļ뵽עС"
ID_REGISTRY_EXPORTREGISTRYFILE
"עȫֵļС"
+ ID_REGISTRY_LOADHIVE
+ "Loads a hive file into the registry"
+ ID_REGISTRY_UNLOADHIVE
+ "Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"ӵԶ̼ע"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@@ -332,6 +346,8 @@ BEGIN
IDS_MY_COMPUTER "My Computer"
IDS_IMPORT_REG_FILE "עļ"
IDS_EXPORT_REG_FILE "עļ"
+ IDS_LOAD_HIVE "Load Hive"
+ IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(ȷ DWORD ֵ)"
END
diff --git a/base/applications/regedit/listview.c b/base/applications/regedit/listview.c
index d7eac5974d2..fcf9f52c8fe 100644
--- a/base/applications/regedit/listview.c
+++ b/base/applications/regedit/listview.c
@@ -556,18 +556,12 @@ BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath)
/* } */
/* dwValSize = max_val_size; */
while (RegEnumValue(hNewKey, dwIndex, ValName, &dwValNameLen, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) {
- /* Remove unwanted path from key name */
- TCHAR *pLastBl = _tcsrchr(ValName, TEXT('\\'));
- if (pLastBl != NULL)
- ++pLastBl;
- else
- pLastBl = ValName;
/* Add a terminating 0 character. Usually this is only necessary for strings. */
ValBuf[dwValSize] = 0;
#ifdef UNICODE
ValBuf[dwValSize + 1] = 0;
#endif
- AddEntryToList(hwndLV, pLastBl, dwValType, ValBuf, dwValSize, -1, TRUE);
+ AddEntryToList(hwndLV, ValName, dwValType, ValBuf, dwValSize, -1, TRUE);
dwValNameLen = max_val_name_len;
dwValSize = max_val_size;
dwValType = 0L;
diff --git a/base/applications/regedit/main.h b/base/applications/regedit/main.h
index 4b837d9f84c..c8220495852 100644
--- a/base/applications/regedit/main.h
+++ b/base/applications/regedit/main.h
@@ -58,6 +58,7 @@ typedef struct {
HWND hTreeWnd;
HWND hListWnd;
HWND hAddressBarWnd;
+ HWND hAddressBtnWnd;
int nFocusPanel; /* 0: left 1: right */
int nSplitPos;
WINDOWPLACEMENT pos;
@@ -88,6 +89,9 @@ extern void ShowAboutBox(HWND hWnd);
/* childwnd.c */
extern LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
+/* error.c */
+extern void ErrorMessageBox(HWND hWnd, LPCTSTR title, DWORD code);
+
/* find.c */
extern void FindDialog(HWND hWnd);
extern BOOL FindNext(HWND hWnd);
diff --git a/base/applications/regedit/regedit.rbuild b/base/applications/regedit/regedit.rbuild
index c29768c9b0c..786ee44d6cf 100644
--- a/base/applications/regedit/regedit.rbuild
+++ b/base/applications/regedit/regedit.rbuild
@@ -23,6 +23,7 @@
hexedit.c
listview.c
main.c
+ error.c
regedit.c
regproc.c
security.c
diff --git a/base/applications/regedit/resource.h b/base/applications/regedit/resource.h
index 2190e0e3ed6..771d743ab9f 100644
--- a/base/applications/regedit/resource.h
+++ b/base/applications/regedit/resource.h
@@ -137,9 +137,11 @@
#define IDS_ERR_RENVAL_CAPTION 32856
#define IDS_ERR_RENVAL_TOEMPTY 32857
#define IDS_BAD_KEY 32858
+#define IDS_LOAD_HIVE 32859
+#define IDS_UNLOAD_HIVE 32860
-#define ID_EDIT_NEW_MULTISTRINGVALUE 32860
-#define ID_EDIT_NEW_EXPANDABLESTRINGVALUE 32861
+#define ID_EDIT_NEW_MULTISTRINGVALUE 32861
+#define ID_EDIT_NEW_EXPANDABLESTRINGVALUE 32862
#define ID_SWITCH_PANELS 32871
#define ID_EDIT_PERMISSIONS 32872
@@ -199,6 +201,8 @@
#define IDC_EXPORT_BRANCH 2009
#define IDC_EXPORT_BRANCH_TEXT 2010
+#define IDD_LOADHIVE 2500
+#define IDC_EDIT_KEY 2501
#define IDC_FAVORITENAME 2011
#define IDC_FAVORITESLIST 2012
diff --git a/base/applications/regedit/treeview.c b/base/applications/regedit/treeview.c
index cd592036907..5e0727fdc61 100644
--- a/base/applications/regedit/treeview.c
+++ b/base/applications/regedit/treeview.c
@@ -633,7 +633,7 @@ BOOL SelectNode(HWND hwndTV, LPCTSTR keyPath)
TVITEM tvi;
/* Total no-good hack */
- if (!_tcsncmp(keyPath, _T("My Computer\\"), 12))
+ if (!_tcsnicmp(keyPath, _T("My Computer\\"), 12))
keyPath += 12;
hRoot = TreeView_GetRoot(hwndTV);
@@ -647,17 +647,17 @@ BOOL SelectNode(HWND hwndTV, LPCTSTR keyPath)
/* Special case for root to expand root key abbreviations */
if (hItem == hRoot)
{
- if (!_tcscmp(szPathPart, TEXT("HKCR")))
+ if (!_tcsicmp(szPathPart, TEXT("HKCR")))
_tcscpy(szPathPart, TEXT("HKEY_CLASSES_ROOT"));
- else if (!_tcscmp(szPathPart, TEXT("HKCU")))
+ else if (!_tcsicmp(szPathPart, TEXT("HKCU")))
_tcscpy(szPathPart, TEXT("HKEY_CURRENT_USER"));
- else if (!_tcscmp(szPathPart, TEXT("HKLM")))
+ else if (!_tcsicmp(szPathPart, TEXT("HKLM")))
_tcscpy(szPathPart, TEXT("HKEY_LOCAL_MACHINE"));
- else if (!_tcscmp(szPathPart, TEXT("HKU")))
+ else if (!_tcsicmp(szPathPart, TEXT("HKU")))
_tcscpy(szPathPart, TEXT("HKEY_USERS"));
- else if (!_tcscmp(szPathPart, TEXT("HKCC")))
+ else if (!_tcsicmp(szPathPart, TEXT("HKCC")))
_tcscpy(szPathPart, TEXT("HKEY_CURRENT_CONFIG"));
- else if (!_tcscmp(szPathPart, TEXT("HKDD")))
+ else if (!_tcsicmp(szPathPart, TEXT("HKDD")))
_tcscpy(szPathPart, TEXT("HKEY_DYN_DATA"));
}
@@ -672,7 +672,7 @@ BOOL SelectNode(HWND hwndTV, LPCTSTR keyPath)
(void)TreeView_GetItem(hwndTV, &tvi);
- if (!_tcscmp(szBuffer, szPathPart))
+ if (!_tcsicmp(szBuffer, szPathPart))
break;
}
diff --git a/base/applications/taskmgr/lang/ru-RU.rc b/base/applications/taskmgr/lang/ru-RU.rc
index b632ad53c6a..97d9215ac84 100644
--- a/base/applications/taskmgr/lang/ru-RU.rc
+++ b/base/applications/taskmgr/lang/ru-RU.rc
@@ -641,10 +641,10 @@ BEGIN
IDS_MSG_UNABLEDEBUGPROCESS " "
IDS_MSG_WARNINGDEBUG ": .\n , ?"
IDS_MSG_TASKMGRWARNING " "
- IDS_MSG_WARNINGTERMINATING ": \n .\n ?"
+ IDS_MSG_WARNINGTERMINATING ": \n .\n ?"
IDS_MSG_UNABLETERMINATEPRO " "
IDS_MSG_UNABLECHANGEPRIORITY " "
- IDS_MSG_WARNINGCHANGEPRIORITY ": .\n , ?"
+ IDS_MSG_WARNINGCHANGEPRIORITY ": .\n , ?"
IDS_MSG_TRAYICONCPUUSAGE " : %d%%"
IDS_STATUS_MEMUSAGE " : %dK / %dK"
IDS_STATUS_CPUUSAGE " : %3d%%"
diff --git a/base/setup/usetup/lang/sk-SK.h b/base/setup/usetup/lang/sk-SK.h
index 73117a45a46..6c35e8da169 100644
--- a/base/setup/usetup/lang/sk-SK.h
+++ b/base/setup/usetup/lang/sk-SK.h
@@ -1,7 +1,7 @@
/* TRANSLATOR: Mrio Kamr /Mario Kacmar/ aka Kario (kario@szm.sk)
* DATE OF TR: 22-01-2008
* Encoding : Latin II (852)
- * LastChange: 31-05-2010
+ * LastChange: 05-09-2010
*/
#pragma once
@@ -993,13 +993,13 @@ static MUI_ENTRY skSKBootLoaderEntries[] =
{
8,
12,
- "Install bootloader on the harddisk (MBR and VBR).",
+ "Naintalova zavdza systmu na pevn disk (MBR a VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Install bootloader on the harddisk (VBR only).",
+ "Naintalova zavdza systmu na pevn disk (iba VBR).",
TEXT_STYLE_NORMAL
},
{
diff --git a/base/shell/cmd/cmd.c b/base/shell/cmd/cmd.c
index 09f362d73af..1c63be6e5e1 100644
--- a/base/shell/cmd/cmd.c
+++ b/base/shell/cmd/cmd.c
@@ -180,7 +180,7 @@ WORD wDefColor; /* default color */
* insert commas into a number
*/
INT
-ConvertULargeInteger(ULONGLONG num, LPTSTR des, INT len, BOOL bPutSeperator)
+ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeperator)
{
TCHAR temp[39]; /* maximum length with nNumberGroups == 1 */
UINT n, iTarget;
diff --git a/base/shell/cmd/cmd.h b/base/shell/cmd/cmd.h
index c6605de480f..9344ac9372f 100644
--- a/base/shell/cmd/cmd.h
+++ b/base/shell/cmd/cmd.h
@@ -99,7 +99,7 @@ INT cmd_cls (LPTSTR);
/* Prototypes for CMD.C */
-INT ConvertULargeInteger(ULONGLONG num, LPTSTR des, INT len, BOOL bPutSeperator);
+INT ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeperator);
HANDLE RunFile(DWORD, LPTSTR, LPTSTR, LPTSTR, INT);
INT ParseCommandLine(LPTSTR);
struct _PARSED_COMMAND;
diff --git a/base/shell/cmd/console.c b/base/shell/cmd/console.c
index 8184af747ea..e5830586305 100644
--- a/base/shell/cmd/console.c
+++ b/base/shell/cmd/console.c
@@ -131,7 +131,7 @@ static VOID ConWrite(TCHAR *str, DWORD len, DWORD nStdHandle)
error_out_of_memory();
return;
}
- len = MultiByteToWideChar(OutputCodePage, 0, str, len, buffer, len, NULL, NULL);
+ len = MultiByteToWideChar(OutputCodePage, 0, str, len, buffer, len);
str = (PVOID)buffer;
#endif
WriteFile(hOutput, str, len * sizeof(WCHAR), &dwWritten, NULL);
diff --git a/base/shell/cmd/lang/sk-SK.rc b/base/shell/cmd/lang/sk-SK.rc
index f436e5c6990..cec75b04ef3 100644
--- a/base/shell/cmd/lang/sk-SK.rc
+++ b/base/shell/cmd/lang/sk-SK.rc
@@ -1,9 +1,9 @@
/* Slovak translation for CMD
* TRANSLATOR: Mrio Kamr /Mario Kacmar/ aka Kario (kario@szm.sk)
* DATE OF TR: 21-03-2009
- * LastChange: 21-06-2009
+ * LastChange: 10-08-2010
* _________________________________________________________________
- * NOTE : this file is not really translated (only scrap yet)
+ * NOTE : this file is not fully translated
*/
LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
@@ -118,7 +118,7 @@ dec hex name dec hex name\n\
6 6 Yellow 14 E Bright Yellow\n\
7 7 White 15 F Bright White\n"
-STRING_COPY_HELP1, "Overwrite %s (Yes/No/All)? "
+STRING_COPY_HELP1, "Prepsa %s (Yes/No/All)? "
STRING_COPY_HELP2, "Skopruje jeden alebo viac sborov na in umiestnenie.\n\n\
COPY [/V][/Y|/-Y][/A|/B] source [/A|/B]\n\
@@ -141,7 +141,7 @@ STRING_DATE_HELP2, "\nZadajte nov
STRING_DATE_HELP3, "\nZadajte nov dtum (rrrr%cmm%cdd): "
-STRING_DATE_HELP4, "Displays or sets the date.\n\n\
+STRING_DATE_HELP4, "Zobraz alebo nastav dtum.\n\n\
DATE [/T][date]\n\n\
/T display only\n\n\
Type DATE without parameters to display the current date setting and\n\
@@ -469,7 +469,7 @@ STRING_TITLE_HELP, "Sets the window title for the command prompt window.\n\n\
TITLE [string]\n\n\
string Specifies the title for the command prompt window.\n"
-STRING_TIME_HELP1, "Displays or sets the system time.\n\n\
+STRING_TIME_HELP1, "Zobraz alebo nastav systmov as.\n\n\
TIME [/T][time]\n\n\
/T display only\n\n\
Type TIME with no parameters to display the current time setting and a prompt\n\
@@ -547,18 +547,18 @@ STRING_WINDOW_HELP1, "change console window aspect\n\n\
WINDOW [/POS[=]left,top,width,heigth]\n\
[MIN|MAX|RESTORE] ['title']\n\n\
/POS specify window placement and dimensions\n\
-MIN minimize the window\n\
-MAX maximize the window\n\
-RESTORE restore the window"
+MIN minimalizova okno\n\
+MAX maximalizujte okno\n\
+RESTORE obnovi okno"
STRING_WINDOW_HELP2, "change console window aspect\n\n\
ACTIVATE 'window' [/POS[=]left,top,width,heigth]\n\
[MIN|MAX|RESTORE] ['title']\n\n\
window tile of window on which perform actions\n\
/POS specify window placement and dimensions\n\
-MIN minimize the window\n\
-MAX maximize the window\n\
-RESTORE restore the window\n\
+MIN minimalizova okno\n\
+MAX maximalizujte okno\n\
+RESTORE obnovi okno\n\
title new title\n"
@@ -576,7 +576,7 @@ CLS Vyma
CMD Starts a new instance of the ReactOS command interpreter.\n\
COLOR Sets the default console foreground and background colors.\n\
COPY Skopruje jeden alebo viac sborov na in umiestnenie.\n\
-DATE Displays or sets the date.\n\
+DATE Zobraz alebo nastav dtum.\n\
DELETE Deletes one or more files.\n\
DIR Displays a list of files and subdirectories in a directory.\n\
ECHO Displays messages, or turns command echoing on or off.\n\
@@ -590,8 +590,8 @@ HELP Provides Help information for ReactOS commands.\n\
HISTORY List all commands which has been used\n\
IF Performs conditional processing in batch programs.\n\
LABEL Creates, changes, or deletes the volume label of a disk.\n\
-MD Creates a directory.\n\
-MKDIR Creates a directory.\n\
+MD Vytvor adresr.\n\
+MKDIR Vytvor adresr.\n\
MKLINK Creates a filesystem link object.\n\
MOVE Moves one or more files from one directory to another\n\
directory.\n\
@@ -603,8 +603,8 @@ PROMPT Changes the command prompt.\n\
PUSHD Saves the current directory then changes it.\n\
RD Removes a directory.\n\
REM Records comments (remarks) in batch files.\n\
-REN Renames a file or files.\n\
-RENAME Renames a file or files.\n\
+REN Premenuje sbor alebo sbory.\n\
+RENAME Premenuje sbor alebo sbory.\n\
REPLACE Replaces files.\n\
RMDIR Removes a directory.\n\
SCREEN Move cursor and optionally print text.\n\
@@ -612,7 +612,7 @@ SET Displays, sets, or removes ReactOS environment variables.\n\
SHIFT Shifts the position of replaceable parameters in batch files.\n"
STRING_HELP2, "START Starts a separate window to run a specified program or command.\n\
Executes command.\n\
-TIME Displays or sets the system time.\n\
+TIME Zobraz alebo nastav systmov as.\n\
TIMER Allow the use of ten stopwatches.\n\
TITLE Sets the window title for a CMD.EXE session.\n\
TYPE Displays the contents of a text file.\n\
@@ -651,9 +651,9 @@ STRING_COPY_ERROR3, "Error writing destination!\n"
STRING_COPY_ERROR4, "Chyba: Zatia neimplementovan!\n" //Not implemented yet
STRING_DATE_ERROR, "Neplatn dtum."
STRING_DEL_ERROR5, "The file %s will be deleted! "
-STRING_DEL_ERROR6, "Are you sure (Y/N)?"
+STRING_DEL_ERROR6, "Ste si ist (Y/N)?"
STRING_DEL_ERROR7, "Deleting: %s\n"
-STRING_ERROR_ERROR1, "Unknown error! Error code: 0x%lx\n"
+STRING_ERROR_ERROR1, "Neznma chyba! Kd chyby: 0x%lx\n"
STRING_ERROR_ERROR2, "Syntax error"
STRING_FOR_ERROR1, "'in' missing in for statement."
STRING_FOR_ERROR2, "no brackets found."
@@ -675,47 +675,47 @@ STRING_TIME_ERROR1, "Neplatn
STRING_TYPE_ERROR1, "Invalid option '/%s'\n"
-STRING_WINDOW_ERROR1, "window not found"
+STRING_WINDOW_ERROR1, "okno sa nenalo"
STRING_ERROR_PARAMETERF_ERROR, "Parameter format not correct - %c\n"
-STRING_ERROR_INVALID_SWITCH, "Invalid switch - /%c\n"
+STRING_ERROR_INVALID_SWITCH, "Neplatn prepna - /%c\n"
STRING_ERROR_TOO_MANY_PARAMETERS, "Prli vea parametrov - %s\n"
-STRING_ERROR_PATH_NOT_FOUND, "Path not found\n"
-STRING_ERROR_FILE_NOT_FOUND, "File not found\n"
+STRING_ERROR_PATH_NOT_FOUND, "Cesta sa nenala\n"
+STRING_ERROR_FILE_NOT_FOUND, "Sbor sa nenaiel\n"
STRING_ERROR_REQ_PARAM_MISSING, "Required parameter missing\n"
STRING_ERROR_INVALID_DRIVE, "Invalid drive specification\n"
STRING_ERROR_INVALID_PARAM_FORMAT, "Invalid parameter format - %s\n"
-STRING_ERROR_BADCOMMAND, "Bad command or filename - %s\n"
+STRING_ERROR_BADCOMMAND, "Chybn prkaz alebo nzov sboru - %s\n"
STRING_ERROR_OUT_OF_MEMORY, "Chyba (z) nedostatku pamte.\n" //Out of memory error.
-STRING_ERROR_CANNOTPIPE, "Error! Cannot pipe! Cannot open temporary file!\n"
+STRING_ERROR_CANNOTPIPE, "Chyba! Cannot pipe! Cannot open temporary file!\n"
STRING_ERROR_D_PAUSEMSG, "Pokraujte stlaenm ubovonho klvesu ..."
-STRING_ERROR_DRIVER_NOT_READY, "Drive not ready"
+STRING_ERROR_DRIVER_NOT_READY, "Jednotka nie je pripraven"
STRING_PATH_ERROR, "CMD: Not in environment '%s'\n"
-STRING_REPLACE_ERROR1, "Invalid switch - %s\n"
-STRING_REPLACE_ERROR2, "Path not found - %s\n"
+STRING_REPLACE_ERROR1, "Neplatn prepna - %s\n"
+STRING_REPLACE_ERROR2, "Cesta sa nenala - %s\n"
STRING_REPLACE_ERROR3, "The filename, directory name, or volume label syntax is incorrect.\n"
STRING_REPLACE_ERROR4, "Invalid parameter combination\n"
-STRING_REPLACE_ERROR5, "Access denied - %s\n"
-STRING_REPLACE_ERROR6, "No files found - %s\n"
+STRING_REPLACE_ERROR5, "Prstup zamietnut - %s\n"
+STRING_REPLACE_ERROR6, "iadne sbory sa nenali - %s\n"
STRING_REPLACE_ERROR7, "Extended Error 32\n"
STRING_REACTOS_VERSION, "Operan systm ReactOS [Verzia %s-%s]\n"
-STRING_CMD_SHELLINFO, "\nReactOS Command Line Interpreter\nVerzia %s %s"
+STRING_CMD_SHELLINFO, "\nInterprter prkazovho riadku systmu ReactOS\nVerzia %s %s"
STRING_VERSION_RUNVER, " running on %s"
STRING_COPY_FILE , " %d sbor(ov) skoprovan(ch)\n"
STRING_DELETE_WIPE, "wiped"
STRING_FOR_ERROR, "bad variable specification."
-STRING_SCREEN_COL, "invalid value for col"
-STRING_SCREEN_ROW, "invalid value for row"
+STRING_SCREEN_COL, "neplatn hodnota pre stpec"
+STRING_SCREEN_ROW, "neplatn hodnota pre riadok"
STRING_TIMER_TIME "Timer %d is %s: "
STRING_MKLINK_CREATED_SYMBOLIC, "Symbolic link created for %s <<===>> %s\n"
STRING_MKLINK_CREATED_HARD, "Hard link created for %s <<===>> %s\n"
STRING_MKLINK_CREATED_JUNCTION, "Junction created for %s <<===>> %s\n"
STRING_MORE, "Viac? " //"More? "
-STRING_CANCEL_BATCH_FILE, "\r\nCtrl-Break pressed. Cancel batch file? (Yes/No/All) "
+STRING_CANCEL_BATCH_FILE, "\r\nStlaen Ctrl-Break. Cancel batch file? (Yes/No/All) "
STRING_INVALID_OPERAND, "Invalid operand."
STRING_EXPECTED_CLOSE_PAREN, "Oakvan ')'."
diff --git a/base/shell/cmd/precomp.h b/base/shell/cmd/precomp.h
index 915246cceb8..3eb404b69c4 100644
--- a/base/shell/cmd/precomp.h
+++ b/base/shell/cmd/precomp.h
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#define NTOS_MODE_USER
#include
diff --git a/base/shell/explorer/desktop/desktop.cpp b/base/shell/explorer/desktop/desktop.cpp
index aa63996e964..99b990bec39 100644
--- a/base/shell/explorer/desktop/desktop.cpp
+++ b/base/shell/explorer/desktop/desktop.cpp
@@ -435,6 +435,12 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
explorer_show_frame(SW_SHOWNORMAL);
break;
+ case WM_DISPLAYCHANGE:
+ MoveWindow(_hwnd, 0, 0, LOWORD(lparam), HIWORD(lparam), TRUE);
+ MoveWindow(g_Globals._hwndShellView, 0, 0, LOWORD(lparam), HIWORD(lparam), TRUE);
+ MoveWindow(_desktopBar, 0, HIWORD(lparam) - DESKTOPBARBAR_HEIGHT, LOWORD(lparam), DESKTOPBARBAR_HEIGHT, TRUE);
+ break;
+
case WM_GETISHELLBROWSER:
return (LRESULT)static_cast(this);
diff --git a/base/system/format/format.c b/base/system/format/format.c
index 4eae18bb614..8c356e63e5d 100755
--- a/base/system/format/format.c
+++ b/base/system/format/format.c
@@ -48,6 +48,19 @@ SIZEDEFINITION LegalSizes[] = {
};
+int LoadStringAndOem(HINSTANCE hInst,
+ UINT uID,
+ LPTSTR szStr,
+ int Siz
+)
+{
+ TCHAR szTmp[RC_STRING_MAX_SIZE];
+ int res = LoadString(hInst, uID, szTmp, sizeof(szTmp));
+ CharToOem(szTmp, szStr);
+ return(res);
+}
+
+
//----------------------------------------------------------------------
//
// PrintWin32Error
@@ -171,7 +184,7 @@ FormatExCallback (
case PROGRESS:
percent = (PDWORD) Argument;
- LoadString( GetModuleHandle(NULL), STRING_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf(szMsg, *percent);
break;
@@ -184,7 +197,7 @@ FormatExCallback (
status = (PBOOLEAN) Argument;
if( *status == FALSE ) {
- LoadString( GetModuleHandle(NULL), STRING_FORMAT_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_FORMAT_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf("%s", szMsg);
Error = TRUE;
}
@@ -203,7 +216,7 @@ FormatExCallback (
case UNKNOWND:
case STRUCTUREPROGRESS:
case CLUSTERSIZETOOSMALL:
- LoadString( GetModuleHandle(NULL), STRING_NO_SUPPORT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_SUPPORT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf("%s", szMsg);
return FALSE;
}
@@ -261,7 +274,7 @@ static VOID Usage( LPTSTR ProgramName )
BYTE dummy;
BOOLEAN lastestVersion;
- LoadString( GetModuleHandle(NULL), STRING_HELP, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_HELP, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
if (!LoadFMIFSEntryPoints())
{
_tprintf(szMsg, ProgramName, _T(""));
@@ -319,7 +332,7 @@ _tmain(int argc, TCHAR *argv[])
// Get function pointers
//
if( !LoadFMIFSEntryPoints()) {
- LoadString( GetModuleHandle(NULL), STRING_FMIFS_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_FMIFS_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf("%s", szMsg);
return -1;
}
@@ -329,7 +342,7 @@ _tmain(int argc, TCHAR *argv[])
//
if( (badArg = ParseCommandLine( argc, argv ))) {
- LoadString( GetModuleHandle(NULL), STRING_UNKNOW_ARG, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_UNKNOW_ARG, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf(szMsg, argv[badArg] );
Usage(argv[0]);
@@ -341,7 +354,7 @@ _tmain(int argc, TCHAR *argv[])
//
if( !Drive ) {
- LoadString( GetModuleHandle(NULL), STRING_DRIVE_PARM, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_DRIVE_PARM, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf(szMsg);
Usage( argv[0] );
return -1;
@@ -359,7 +372,7 @@ _tmain(int argc, TCHAR *argv[])
driveType = GetDriveType( RootDirectory );
if( driveType == 0 ) {
- LoadString( GetModuleHandle(NULL), STRING_ERROR_DRIVE_TYPE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_ERROR_DRIVE_TYPE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
PrintWin32Error( szMsg, GetLastError());
return -1;
}
@@ -371,7 +384,7 @@ _tmain(int argc, TCHAR *argv[])
}
if( driveType != DRIVE_FIXED ) {
- LoadString( GetModuleHandle(NULL), STRING_INSERT_DISK, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_INSERT_DISK, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf(szMsg, RootDirectory[0] );
_fgetts( input, sizeof(input)/2, stdin );
@@ -386,7 +399,7 @@ _tmain(int argc, TCHAR *argv[])
&serialNumber, &maxComponent, &flags,
fileSystem, sizeof(fileSystem)/2)) {
- LoadString( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
PrintWin32Error( szMsg, GetLastError());
return -1;
}
@@ -396,11 +409,11 @@ _tmain(int argc, TCHAR *argv[])
&totalNumberOfBytes,
&totalNumberOfFreeBytes )) {
- LoadString( GetModuleHandle(NULL), STRING_NO_VOLUME_SIZE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME_SIZE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
PrintWin32Error( szMsg, GetLastError());
return -1;
}
- LoadString( GetModuleHandle(NULL), STRING_FILESYSTEM, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_FILESYSTEM, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf(szMsg, fileSystem );
//
@@ -412,7 +425,7 @@ _tmain(int argc, TCHAR *argv[])
while(1 ) {
- LoadString( GetModuleHandle(NULL), STRING_LABEL_NAME_EDIT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_LABEL_NAME_EDIT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf(szMsg, RootDirectory[0] );
_fgetts( input, sizeof(input)/2, stdin );
input[ _tcslen( input ) - 1] = 0;
@@ -421,15 +434,15 @@ _tmain(int argc, TCHAR *argv[])
break;
}
- LoadString( GetModuleHandle(NULL), STRING_ERROR_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_ERROR_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf("%s", szMsg);
}
}
- LoadString( GetModuleHandle(NULL), STRING_YN_FORMAT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_YN_FORMAT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf(szMsg, RootDirectory[0] );
- LoadString( GetModuleHandle(NULL), STRING_YES_NO_FAQ, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_YES_NO_FAQ, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
while( 1 ) {
_fgetts( input, sizeof(input)/2, stdin );
@@ -460,7 +473,7 @@ _tmain(int argc, TCHAR *argv[])
}
} else {
- LoadString( GetModuleHandle(NULL), STRING_FAST_FMT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_FAST_FMT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
if( totalNumberOfBytes.QuadPart > 1024*1024*10 ) {
_tprintf(_T("%s %luM\n"),szMsg, (DWORD) (totalNumberOfBytes.QuadPart/(1024*1024)));
@@ -470,7 +483,7 @@ _tmain(int argc, TCHAR *argv[])
_tprintf(_T("%s %.2fM\n"),szMsg,
((float)(LONGLONG)totalNumberOfBytes.QuadPart)/(float)(1024.0*1024.0));
}
- LoadString( GetModuleHandle(NULL), STRING_CREATE_FSYS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_CREATE_FSYS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf("%s", szMsg);
}
@@ -488,7 +501,7 @@ _tmain(int argc, TCHAR *argv[])
ClusterSize, FormatExCallback );
#endif
if( Error ) return -1;
- LoadString( GetModuleHandle(NULL), STRING_FMT_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_FMT_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf("%s", szMsg);
//
@@ -503,7 +516,7 @@ _tmain(int argc, TCHAR *argv[])
if( !EnableVolumeCompression( RootDirectory, TRUE )) {
#endif
- LoadString( GetModuleHandle(NULL), STRING_VOL_COMPRESS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_VOL_COMPRESS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf("%s", szMsg);
}
}
@@ -520,7 +533,7 @@ _tmain(int argc, TCHAR *argv[])
input[ _tcslen(input)-1] = 0;
if( !SetVolumeLabel( RootDirectory, input )) {
- LoadString( GetModuleHandle(NULL), STRING_NO_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
PrintWin32Error(szMsg, GetLastError());
return -1;
}
@@ -531,7 +544,7 @@ _tmain(int argc, TCHAR *argv[])
&serialNumber, &maxComponent, &flags,
fileSystem, sizeof(fileSystem)/2)) {
- LoadString( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
PrintWin32Error( szMsg, GetLastError());
return -1;
}
@@ -544,12 +557,12 @@ _tmain(int argc, TCHAR *argv[])
&totalNumberOfBytes,
&totalNumberOfFreeBytes )) {
- LoadString( GetModuleHandle(NULL), STRING_NO_VOLUME_SIZE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME_SIZE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
PrintWin32Error(szMsg, GetLastError());
return -1;
}
- LoadString( GetModuleHandle(NULL), STRING_FREE_SPACE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_FREE_SPACE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf(szMsg, totalNumberOfBytes.QuadPart, totalNumberOfFreeBytes.QuadPart );
//
@@ -560,11 +573,11 @@ _tmain(int argc, TCHAR *argv[])
&serialNumber, &maxComponent, &flags,
fileSystem, sizeof(fileSystem)/2)) {
- LoadString( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
PrintWin32Error( szMsg, GetLastError());
return -1;
}
- LoadString( GetModuleHandle(NULL), STRING_SERIAL_NUMBER, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+ LoadStringAndOem( GetModuleHandle(NULL), STRING_SERIAL_NUMBER, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
_tprintf(szMsg, (unsigned int)(serialNumber >> 16),
(unsigned int)(serialNumber & 0xFFFF) );
diff --git a/base/system/format/lang/sk-SK.rc b/base/system/format/lang/sk-SK.rc
index deaee258367..c40b08fc2b6 100644
--- a/base/system/format/lang/sk-SK.rc
+++ b/base/system/format/lang/sk-SK.rc
@@ -1,6 +1,6 @@
/* TRANSLATOR : Mrio Kamr /Mario Kacmar/ aka Kario (kario@szm.sk)
* DATE OF TR.: 15-02-2008
- * LAST CHANGE: 08-08-2008
+ * LAST CHANGE: 10-08-2010
*/
#include "resource.h"
@@ -14,14 +14,14 @@ STRING_HELP, "Pou
-FS:systm sborov Uruje typ sborovho systmu (%s).\n\
-V:menovka Uruje menovku zvzku.\n\
-Q Vykonva rchle formtovanie.\n\
- -A:vekos Overrides the default allocation unit size. Default settings\n\
- are strongly recommended for general use\n\
- NTFS supports 512, 1024, 2048, 4096, 8192, 16K, 32K, 64K.\n\
- FAT supports 8192, 16K, 32K, 64K, 128K, 256K.\n\
- NTFS compression is not supported for allocation unit sizes\n\
- above 4096.\n\
- -C Files created on the new volume will be compressed by\n\
- default.\n\n"
+ -A:vekos Prepe predvolen vekos alokanej jednotky. Pre veobecn\n\
+ pouitie s drazne odporan predvolen nastavenia\n\
+ NTFS podporuje 512, 1024, 2048, 4096, 8192, 16K, 32K, 64K.\n\
+ FAT podporuje 8192, 16K, 32K, 64K, 128K, 256K.\n\
+ NTFS kompresia nie je podporovan pre vekosti alokanej\n\
+ jednotky nad 4096.\n\
+ -C Sbory vytvoren na novom zvzku bud automaticky\n\
+ komprimovan.\n\n"
STRING_COMPLETE "Dokonen na %lu percent.\r"
@@ -29,19 +29,19 @@ STRING_FORMAT_FAIL "FormatEx nebol schopn
STRING_NO_SUPPORT "Opercia nie je podporovan"
-STRING_FMIFS_FAIL "Could not located FMIFS entry points.\n\n"
+STRING_FMIFS_FAIL "Nepodarilo sa lokalizova vstupn body FMIFS.\n\n"
STRING_UNKNOW_ARG "Neznmy argument: %s\n"
STRING_DRIVE_PARM "Chba nevyhnutn parameter jednotky.\n\n"
-STRING_ERROR_DRIVE_TYPE "Could not get drive type"
+STRING_ERROR_DRIVE_TYPE "Nemono zska typ jednotky"
STRING_INSERT_DISK "Vlote nov disketu do jednotky %C:\na potom stlate ENTER..."
-STRING_NO_VOLUME "Could not query volume"
+STRING_NO_VOLUME "Nemono dotazova zvzok"
-STRING_NO_VOLUME_SIZE "Could not query volume size"
+STRING_NO_VOLUME_SIZE "Nemono dotazova vekos zvzku"
STRING_FILESYSTEM "Typ systmu sborov je %s.\n"
@@ -49,8 +49,8 @@ STRING_LABEL_NAME_EDIT "Vlo
STRING_ERROR_LABEL "Bola zadan nesprvna menovka zvzku pre tto jednotku.\n"
-STRING_YN_FORMAT "\nWARNING, ALL DATA ON NON_REMOVABLE DISK\n\
-DRIVE %C: WILL BE LOST!\nProceed with Format (A/N)? "
+STRING_YN_FORMAT "\nUPOZORNENIE: VETKY DAJE NA NIE_VYMENITENEJ DISKOVEJ\n\
+JEDNOTKE %C: BUD STRATEN!\nPokraova s formtovanm (A/N)? "
STRING_YES_NO_FAQ "AN"
diff --git a/base/system/services/rpcserver.c b/base/system/services/rpcserver.c
index 914e013327b..cc45ff5f1e4 100644
--- a/base/system/services/rpcserver.c
+++ b/base/system/services/rpcserver.c
@@ -24,7 +24,6 @@
typedef struct _SCMGR_HANDLE
{
DWORD Tag;
- DWORD RefCount;
DWORD DesiredAccess;
} SCMGR_HANDLE;
@@ -32,9 +31,6 @@ typedef struct _SCMGR_HANDLE
typedef struct _MANAGER_HANDLE
{
SCMGR_HANDLE Handle;
-
- /* FIXME: Insert more data here */
-
WCHAR DatabaseName[1];
} MANAGER_HANDLE, *PMANAGER_HANDLE;
@@ -42,12 +38,7 @@ typedef struct _MANAGER_HANDLE
typedef struct _SERVICE_HANDLE
{
SCMGR_HANDLE Handle;
-
- DWORD DesiredAccess;
PSERVICE ServiceEntry;
-
- /* FIXME: Insert more data here */
-
} SERVICE_HANDLE, *PSERVICE_HANDLE;
@@ -151,7 +142,7 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName,
if (lpDatabaseName == NULL)
lpDatabaseName = SERVICES_ACTIVE_DATABASEW;
- if (_wcsicmp(lpDatabaseName,SERVICES_FAILED_DATABASEW)==0)
+ if (_wcsicmp(lpDatabaseName, SERVICES_FAILED_DATABASEW) == 0)
{
DPRINT("Database %S, does not exist\n",lpDatabaseName);
return ERROR_DATABASE_DOES_NOT_EXIST;
@@ -169,9 +160,6 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName,
return ERROR_NOT_ENOUGH_MEMORY;
Ptr->Handle.Tag = MANAGER_TAG;
- Ptr->Handle.RefCount = 1;
-
- /* FIXME: initialize more data here */
wcscpy(Ptr->DatabaseName, lpDatabaseName);
@@ -194,9 +182,7 @@ ScmCreateServiceHandle(PSERVICE lpServiceEntry,
return ERROR_NOT_ENOUGH_MEMORY;
Ptr->Handle.Tag = SERVICE_TAG;
- Ptr->Handle.RefCount = 1;
- /* FIXME: initialize more data here */
Ptr->ServiceEntry = lpServiceEntry;
*Handle = (SC_HANDLE)Ptr;
@@ -205,6 +191,46 @@ ScmCreateServiceHandle(PSERVICE lpServiceEntry,
}
+static PMANAGER_HANDLE
+ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
+{
+ PMANAGER_HANDLE pManager = NULL;
+
+ _SEH2_TRY
+ {
+ if (((PMANAGER_HANDLE)Handle)->Handle.Tag == MANAGER_TAG)
+ pManager = (PMANAGER_HANDLE)Handle;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Exception: Invalid Service Manager handle!\n");
+ }
+ _SEH2_END;
+
+ return pManager;
+}
+
+
+static PSERVICE_HANDLE
+ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
+{
+ PSERVICE_HANDLE pService = NULL;
+
+ _SEH2_TRY
+ {
+ if (((PSERVICE_HANDLE)Handle)->Handle.Tag == SERVICE_TAG)
+ pService = (PSERVICE_HANDLE)Handle;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Exception: Invalid Service handle!\n");
+ }
+ _SEH2_END;
+
+ return pService;
+}
+
+
static DWORD
ScmCheckAccess(SC_HANDLE Handle,
DWORD dwDesiredAccess)
@@ -417,42 +443,33 @@ DWORD RCloseServiceHandle(
if (*hSCObject == 0)
return ERROR_INVALID_HANDLE;
- hManager = (PMANAGER_HANDLE)*hSCObject;
- hService = (PSERVICE_HANDLE)*hSCObject;
- if (hManager->Handle.Tag == MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(*hSCObject);
+ hService = ScmGetServiceFromHandle(*hSCObject);
+
+ if (hManager != NULL)
{
DPRINT("Found manager handle\n");
- hManager->Handle.RefCount--;
- if (hManager->Handle.RefCount == 0)
- {
- /* FIXME: add handle cleanup code */
+ /* FIXME: add handle cleanup code */
- HeapFree(GetProcessHeap(), 0, hManager);
- hManager = NULL;
- }
+ HeapFree(GetProcessHeap(), 0, hManager);
+ hManager = NULL;
DPRINT("RCloseServiceHandle() done\n");
return ERROR_SUCCESS;
}
- else if (hService->Handle.Tag == SERVICE_TAG)
+ else if (hService != NULL)
{
DPRINT("Found service handle\n");
/* Get the pointer to the service record */
lpService = hService->ServiceEntry;
- ASSERT(hService->Handle.RefCount > 0);
+ /* FIXME: add handle cleanup code */
- hService->Handle.RefCount--;
- if (hService->Handle.RefCount == 0)
- {
- /* FIXME: add handle cleanup code */
-
- /* Free the handle */
- HeapFree(GetProcessHeap(), 0, hService);
- hService = NULL;
- }
+ /* Free the handle */
+ HeapFree(GetProcessHeap(), 0, hService);
+ hService = NULL;
ASSERT(lpService->dwRefCount > 0);
@@ -535,6 +552,8 @@ DWORD RControlService(
DWORD dwError = ERROR_SUCCESS;
DWORD pcbBytesNeeded = 0;
DWORD dwServicesReturned = 0;
+ DWORD dwControlsAccepted;
+ DWORD dwCurrentState;
HKEY hServicesKey = NULL;
DPRINT("RControlService() called\n");
@@ -543,18 +562,19 @@ DWORD RControlService(
return ERROR_SHUTDOWN_IN_PROGRESS;
/* Check the service handle */
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
+
/* Check the service entry point */
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT("lpService == NULL!\n");
+ DPRINT1("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
@@ -635,6 +655,49 @@ DWORD RControlService(
}
else
{
+ dwControlsAccepted = lpService->Status.dwControlsAccepted;
+ dwCurrentState = lpService->Status.dwCurrentState;
+
+ /* Check the current state before sending a control request */
+ switch (dwCurrentState)
+ {
+ case SERVICE_STOP_PENDING:
+ case SERVICE_STOPPED:
+ return ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
+
+ case SERVICE_START_PENDING:
+ switch (dwControl)
+ {
+ case SERVICE_CONTROL_STOP:
+ break;
+
+ case SERVICE_CONTROL_INTERROGATE:
+ RtlCopyMemory(lpServiceStatus,
+ &lpService->Status,
+ sizeof(SERVICE_STATUS));
+ return ERROR_SUCCESS;
+
+ default:
+ return ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
+ }
+ break;
+ }
+
+ /* Check if the control code is acceptable to the service */
+ switch (dwControl)
+ {
+ case SERVICE_CONTROL_STOP:
+ if ((dwControlsAccepted & SERVICE_ACCEPT_STOP) == 0)
+ return ERROR_INVALID_SERVICE_CONTROL;
+ break;
+
+ case SERVICE_CONTROL_PAUSE:
+ case SERVICE_CONTROL_CONTINUE:
+ if ((dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) == 0)
+ return ERROR_INVALID_SERVICE_CONTROL;
+ break;
+ }
+
/* Send control code to the service */
dwError = ScmControlService(lpService,
dwControl);
@@ -674,9 +737,12 @@ DWORD RDeleteService(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
+ }
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
DELETE))
@@ -721,9 +787,12 @@ DWORD RLockServiceDatabase(
*lpLock = 0;
- hMgr = (PMANAGER_HANDLE)hSCManager;
- if (!hMgr || hMgr->Handle.Tag != MANAGER_TAG)
+ hMgr = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hMgr == NULL)
+ {
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
+ }
if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess,
SC_MANAGER_LOCK))
@@ -758,15 +827,15 @@ DWORD RQueryServiceObjectSecurity(
DPRINT("RQueryServiceObjectSecurity() called\n");
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
- if (dwSecurityInformation & (DACL_SECURITY_INFORMATION ||
- GROUP_SECURITY_INFORMATION ||
+ if (dwSecurityInformation & (DACL_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
OWNER_SECURITY_INFORMATION))
DesiredAccess |= READ_CONTROL;
@@ -840,10 +909,10 @@ DWORD RSetServiceObjectSecurity(
DPRINT("RSetServiceObjectSecurity() called\n");
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -957,10 +1026,10 @@ DWORD RQueryServiceStatus(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -1143,10 +1212,10 @@ DWORD RChangeServiceConfigW(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -1763,10 +1832,10 @@ DWORD RCreateServiceW(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -2073,7 +2142,6 @@ DWORD REnumDependentServicesW(
DWORD dwServicesReturned = 0;
DWORD dwServiceCount;
HKEY hServicesKey = NULL;
- LPSC_RPC_HANDLE hSCObject;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
PSERVICE *lpServicesArray = NULL;
@@ -2085,8 +2153,13 @@ DWORD REnumDependentServicesW(
DPRINT("REnumDependentServicesW() called\n");
- hSCObject = &hService;
- hSvc = (PSERVICE_HANDLE) *hSCObject;
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
lpService = hSvc->ServiceEntry;
/* Check access rights */
@@ -2218,13 +2291,14 @@ DWORD REnumServicesStatusW(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
+
*pcbBytesNeeded = 0;
*lpServicesReturned = 0;
@@ -2469,10 +2543,10 @@ DWORD ROpenServiceW(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -2549,10 +2623,10 @@ DWORD RQueryServiceConfigW(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -2757,10 +2831,10 @@ DWORD RStartServiceW(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -2983,10 +3057,10 @@ DWORD RChangeServiceConfigA(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -3401,7 +3475,6 @@ DWORD REnumDependentServicesA(
DWORD dwServicesReturned = 0;
DWORD dwServiceCount;
HKEY hServicesKey = NULL;
- LPSC_RPC_HANDLE hSCObject;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
PSERVICE *lpServicesArray = NULL;
@@ -3413,8 +3486,13 @@ DWORD REnumDependentServicesA(
DPRINT("REnumDependentServicesA() called\n");
- hSCObject = &hService;
- hSvc = (PSERVICE_HANDLE) *hSCObject;
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
lpService = hSvc->ServiceEntry;
/* Check access rights */
@@ -3723,10 +3801,10 @@ DWORD RQueryServiceConfigA(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -3964,10 +4042,10 @@ DWORD RStartServiceA(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -4345,10 +4423,10 @@ DWORD RChangeServiceConfig2W(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -4446,10 +4524,10 @@ DWORD RQueryServiceConfig2A(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -4566,10 +4644,10 @@ DWORD RQueryServiceConfig2W(
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -4719,10 +4797,10 @@ DWORD RQueryServiceStatusEx(
if (cbBufSize < sizeof(SERVICE_STATUS_PROCESS))
return ERROR_INSUFFICIENT_BUFFER;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
@@ -4912,10 +4990,10 @@ DWORD REnumServicesStatusExW(
if (InfoLevel != SC_ENUM_PROCESS_INFO)
return ERROR_INVALID_LEVEL;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
diff --git a/boot/armllb/armllb.rbuild b/boot/armllb/armllb.rbuild
index 2566c788011..4c4c0d9f9e3 100644
--- a/boot/armllb/armllb.rbuild
+++ b/boot/armllb/armllb.rbuild
@@ -1,17 +1,25 @@
-
+
libcntpr
rtl
./inc
-
+
+
-Wl,--image-base=0x401FEFF8
+
+
+
+
+ --image-base=0x80FFF000
+
+
@@ -25,17 +33,26 @@
fw.c
keyboard.c
+ matrix.c
serial.c
time.c
video.c
-
-
- hwdata.c
- hwdss.c
+
+
+ hwinfo.c
+ hwinit.c
+ hwlcd.c
+ hwsynkp.c
+ hwtwl40x.c
+ hwuart.c
+
+
+
+
hwuart.c
hwinfo.c
hwinit.c
-
+
@@ -59,8 +76,5 @@
-Os
-
- -lgcc
-
diff --git a/boot/armllb/boot.s b/boot/armllb/boot.s
index 505ae843cac..899013f4dc9 100644
--- a/boot/armllb/boot.s
+++ b/boot/armllb/boot.s
@@ -13,15 +13,47 @@
NESTED_ENTRY _start
PROLOG_END _start
-#ifdef _OMAP3_
+#ifdef _BEAGLE_ // This is only used for TI BootROM on Beagle/Emulator for now
/*
- * On OMAP3, the boot is directly from TI BootROM that reads NAND flash.
+ * On Beagle, the boot is directly from TI BootROM that reads NAND flash.
* First word is size of program to load.
* Second word is load address of program. Since DDR is not initialized,
* we load to SDRAM at 40200000h. Max 64K.
*/
.word 0x8000
.word 0x40200000
+#elif _ZOOM2_
+ /*
+ * On ZOOM2, we currently load from u-boot to make bring-up easier.
+ *
+ * In order to get ATAG and all that goodness, we have to fool u-boot into
+ * thinking we are a Linux ARM kernel.
+ *
+ * So this is a 'fake' uImage-format header, which will make u-boot grok our
+ * image and correctly execute it.
+ *
+ * Note that a data checksum is in the header, but thankfully we can disable
+ * the check.
+ *
+ * There's also a header checksum, but as long as there's no need to modify
+ * this header, we can leave it static.
+ *
+ * Finally, note that the "Image String" is sized as a 32-byte array in the
+ * uImage header format. The string chosen below is not only accurate, but
+ * also happens to fit exactly in 32 bytes, meaning we don't need to pad.
+ */
+ .word 0x56190527 // Header Magic
+ .word 0x5E4B8444 // Checksum
+ .word 0x483BE54C // Timestamp
+ .word 0x0CA10000 // Image size (64K)
+ .word 0x00000081 // Load address
+ .word 0x40000081 // Entrypoint
+ .word 0x90873DD8 // Data Checksum ('setenv verify n' must be set!)
+ .byte 5 // Linux OS
+ .byte 2 // ARM
+ .byte 2 // Kernel
+ .byte 0 // No compression
+ .ascii "ReactOS ARM Low-Level Bootloader"
#endif
/* Load C entrypoint and setup LLB stack */
@@ -31,8 +63,14 @@
ENTRY_END _start
L_BootStackEnd:
+#ifdef _BEAGLE_ // This is only used for TI BootROM on Beagle/Emulator for now
.long 0x00010000
-
+#elif _ZOOM2_ // On ZOOM2 RAM starts at 0x80000000, not 0
+ .long 0x81014000
+#else
+#error Stack Address Not Defined
+#endif
+
L_LlbStartup:
.long LlbStartup
diff --git a/boot/armllb/crtsupp.c b/boot/armllb/crtsupp.c
index ba2dde3937c..f535a1777c0 100644
--- a/boot/armllb/crtsupp.c
+++ b/boot/armllb/crtsupp.c
@@ -40,7 +40,7 @@ int printf(const char *fmt, ...)
return puts(printbuffer);
}
-VOID
+ULONG
DbgPrint(const char *fmt, ...)
{
va_list args;
@@ -52,6 +52,7 @@ DbgPrint(const char *fmt, ...)
va_end(args);
for (j = 0; j < i; j++) LlbSerialPutChar(Buffer[j]);
+ return 0;
}
/* EOF */
diff --git a/boot/armllb/envir.c b/boot/armllb/envir.c
index 31ec2a56f82..0b1c451c11b 100644
--- a/boot/armllb/envir.c
+++ b/boot/armllb/envir.c
@@ -9,10 +9,11 @@
#include "precomp.h"
ULONG LlbEnvHwPageSize;
-ULONG LlbEnvHwMemStart;
-ULONG LlbEnvHwMemSize;
-ULONG LlbEnvRamDiskStart;
-ULONG LlbEnvRamDiskSize;
+ULONG LlbEnvHwMemStart = 0;
+ULONG LlbEnvHwMemSize = 0;
+ULONG LlbEnvRamDiskStart = 0;
+ULONG LlbEnvRamDiskSize = 0;
+ULONG LlbEnvHwRevision;
CHAR LlbEnvCmdLine[256];
CHAR LlbValueData[32];
@@ -35,11 +36,17 @@ LlbEnvParseArguments(IN PATAG Arguments)
LlbEnvHwPageSize = Atag->u.Core.PageSize;
break;
+ case ATAG_REVISION:
+
+ /* Save page size */
+ LlbEnvHwRevision = Atag->u.Revision.Rev;
+ break;
+
case ATAG_MEM:
/* Save RAM start and size */
- LlbEnvHwMemStart = Atag->u.Mem.Start;
- LlbEnvHwMemSize = Atag->u.Mem.Size;
+ if (!LlbEnvHwMemStart) LlbEnvHwMemStart = Atag->u.Mem.Start;
+ LlbEnvHwMemSize += Atag->u.Mem.Size;
break;
case ATAG_INITRD2:
@@ -48,6 +55,7 @@ LlbEnvParseArguments(IN PATAG Arguments)
LlbEnvRamDiskStart = Atag->u.InitRd2.Start;
LlbEnvRamDiskSize = Atag->u.InitRd2.Size;
+#ifdef _BEAGLE_
/* Make sure it's 16MB-aligned */
LlbEnvRamDiskSize = (LlbEnvRamDiskSize + (16 * 1024 * 1024) - 1)
&~ ((16 * 1024 * 1024) - 1);
@@ -55,6 +63,7 @@ LlbEnvParseArguments(IN PATAG Arguments)
/* The RAMDISK actually starts 16MB later */
LlbEnvRamDiskStart += 16 * 1024 * 1024;
LlbEnvRamDiskSize -= 16 * 1024 * 1024;
+#endif
break;
case ATAG_CMDLINE:
@@ -68,7 +77,7 @@ LlbEnvParseArguments(IN PATAG Arguments)
/* Nothing left to handle */
case ATAG_NONE:
default:
- return;
+ break;
}
/* Next tag */
@@ -76,8 +85,11 @@ LlbEnvParseArguments(IN PATAG Arguments)
}
/* For debugging */
- DbgPrint("[BOOTROM] PageSize: %dKB RAM: %dMB CMDLINE: %s\n",
- LlbEnvHwPageSize / 1024, LlbEnvHwMemSize / 1024 / 1024, LlbEnvCmdLine);
+ DbgPrint("[BOOTROM] Board Revision: %lx PageSize: %dKB RAM: %dMB CMDLINE: %s\n"
+ "[RAMDISK] Base: %lx Size: %dMB\n",
+ LlbEnvHwRevision,
+ LlbEnvHwPageSize / 1024, LlbEnvHwMemSize / 1024 / 1024, LlbEnvCmdLine,
+ LlbEnvRamDiskStart, LlbEnvRamDiskSize / 1024 / 1024);
}
VOID
diff --git a/boot/armllb/fw.c b/boot/armllb/fw.c
index 4286b4ababa..8831d95a655 100644
--- a/boot/armllb/fw.c
+++ b/boot/armllb/fw.c
@@ -49,7 +49,11 @@ INT
LlbFwGetCh(VOID)
{
/* Return the key pressed */
+#ifdef _ZOOM2_
+ return LlbKeypadGetChar();
+#else
return LlbKeyboardGetChar();
+#endif
}
ULONG
diff --git a/boot/armllb/hw/matrix.c b/boot/armllb/hw/matrix.c
new file mode 100755
index 00000000000..c1275c2e719
--- /dev/null
+++ b/boot/armllb/hw/matrix.c
@@ -0,0 +1,42 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/hw/matrix.c
+ * PURPOSE: LLB Matrix Keypad Routines
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#include "precomp.h"
+
+/* SYNPATICS KEYPAD MATRIX ****************************************************/
+
+UCHAR KeyMatrix[8][8] =
+{
+ {'e', 'r', 't', KEY_HOME, 0, 0, 'i', KEY_LEFTSHIFT},
+ {'d', 'f', 'g', KEY_SEND, 0, 0, 'k', KEY_ENTER},
+ {'x', 'c', 'v', KEY_END, 0, 0, '.', KEY_CAPS_LOCK},
+ {'z', '+', 'b', KEY_F1, 0, 0, 'o', KEY_SPACE},
+ {'w', 'y', 'u', KEY_F2, 0, 0, 'l', KEY_LEFT},
+ {'s', 'h', 'j', KEY_F3, 0, 0, 'm', KEY_RIGHT},
+ {'q', 'a', 'n', KEY_BACKSPACE, 0, 0, 'p', KEY_UP},
+ {0, 0, 0, 0, 0, 0, KEY_ENTER, KEY_DOWN}
+};
+
+/* FUNCTIONS ******************************************************************/
+
+CHAR
+NTAPI
+LlbKeypadGetChar(VOID)
+{
+ UCHAR ScanCode;
+ UCHAR Col, Row;
+
+ ScanCode = LlbHwKbdRead();
+ Col = ScanCode >> 4;
+ Row = ScanCode & 0xF;
+
+ /* Return the ASCII character */
+ return KeyMatrix[Col][Row];
+}
+
+/* EOF */
diff --git a/boot/armllb/hw/omap3-beagle/hwinfo.c b/boot/armllb/hw/omap3-beagle/hwinfo.c
new file mode 100755
index 00000000000..8a7d5b54187
--- /dev/null
+++ b/boot/armllb/hw/omap3-beagle/hwinfo.c
@@ -0,0 +1,137 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/hw/omap3-beagle/hwinfo.c
+ * PURPOSE: LLB Hardware Info Routines for OMAP3 Beagle
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#include "precomp.h"
+
+ULONG
+NTAPI
+LlbHwGetBoardType(VOID)
+{
+ return MACH_TYPE_OMAP3_BEAGLE;
+}
+
+ULONG
+NTAPI
+LlbHwGetPClk(VOID)
+{
+ return 48000000;
+}
+
+ULONG
+NTAPI
+LlbHwGetTmr0Base(VOID)
+{
+ return 0x48318000;
+}
+
+ULONG
+NTAPI
+LlbHwGetSerialUart(VOID)
+{
+ return 3;
+}
+
+VOID
+NTAPI
+LlbHwKbdSend(IN ULONG Value)
+{
+
+}
+
+BOOLEAN
+NTAPI
+LlbHwKbdReady(VOID)
+{
+ return FALSE;
+}
+
+INT
+NTAPI
+LlbHwKbdRead(VOID)
+{
+ return 0;
+}
+
+ULONG
+NTAPI
+LlbHwGetScreenWidth(VOID)
+{
+ return 1280;
+}
+
+ULONG
+NTAPI
+LlbHwGetScreenHeight(VOID)
+{
+ return 720;
+}
+
+PVOID
+NTAPI
+LlbHwGetFrameBuffer(VOID)
+{
+ return (PVOID)0x80500000;
+}
+
+ULONG
+NTAPI
+LlbHwVideoCreateColor(IN ULONG Red,
+ IN ULONG Green,
+ IN ULONG Blue)
+{
+ return 0;
+}
+
+
+//
+// OMAP3 Memory Map
+//
+BIOS_MEMORY_MAP LlbHwOmap3MemoryMap[] =
+{
+ {0, 0, 0, 0}
+};
+
+VOID
+NTAPI
+LlbHwBuildMemoryMap(IN PBIOS_MEMORY_MAP MemoryMap)
+{
+ PBIOS_MEMORY_MAP MapEntry;
+ ULONG Base, Size, FsBase, FsSize;
+
+ /* Parse hardware memory map */
+ MapEntry = LlbHwOmap3MemoryMap;
+ while (MapEntry->Length)
+ {
+ /* Add this entry */
+ LlbAllocateMemoryEntry(MapEntry->Type, MapEntry->BaseAddress, MapEntry->Length);
+
+ /* Move to the next one */
+ MapEntry++;
+ }
+
+ /* Query memory and RAMDISK information */
+ LlbEnvGetMemoryInformation(&Base, &Size);
+ LlbEnvGetRamDiskInformation(&FsBase, &FsSize);
+
+ /* Add-in the size of the ramdisk */
+ Base = FsBase + FsSize;
+
+ /* Subtract size of ramdisk and anything else before it */
+ Size -= Base;
+
+ /* Allocate an entry for it */
+ LlbAllocateMemoryEntry(BiosMemoryUsable, Base, Size);
+}
+
+ULONG
+LlbHwRtcRead(VOID)
+{
+ return 0;
+}
+
+/* EOF */
diff --git a/boot/armllb/hw/omap3/hwinit.c b/boot/armllb/hw/omap3-beagle/hwinit.c
similarity index 78%
rename from boot/armllb/hw/omap3/hwinit.c
rename to boot/armllb/hw/omap3-beagle/hwinit.c
index 85ee0556096..4c7c0c9c66b 100755
--- a/boot/armllb/hw/omap3/hwinit.c
+++ b/boot/armllb/hw/omap3-beagle/hwinit.c
@@ -1,8 +1,8 @@
/*
* PROJECT: ReactOS Boot Loader
* LICENSE: BSD - See COPYING.ARM in the top level directory
- * FILE: boot/armllb/hw/omap3/hwinit.c
- * PURPOSE: LLB Hardware Initialization Routines for OMAP3
+ * FILE: boot/armllb/hw/omap3-beagle/hwinit.c
+ * PURPOSE: LLB Hardware Initialization Routines for OMAP3 Beagle
* PROGRAMMERS: ReactOS Portable Systems Group
*/
@@ -12,7 +12,7 @@ VOID
NTAPI
LlbHwInitialize(VOID)
{
-
+ while (TRUE);
}
/* EOF */
diff --git a/boot/armllb/hw/omap3-beagle/hwuart.c b/boot/armllb/hw/omap3-beagle/hwuart.c
new file mode 100755
index 00000000000..7f8669cf05a
--- /dev/null
+++ b/boot/armllb/hw/omap3-beagle/hwuart.c
@@ -0,0 +1,54 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/hw/omap3-beagle/hwuart.c
+ * PURPOSE: LLB UART Initialization Routines for OMAP3 Beagle
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#include "precomp.h"
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+LlbHwOmap3UartInitialize(VOID)
+{
+
+}
+
+VOID
+NTAPI
+LlbHwUartSendChar(IN CHAR Char)
+{
+
+}
+
+BOOLEAN
+NTAPI
+LlbHwUartTxReady(VOID)
+{
+ return FALSE;
+}
+
+ULONG
+NTAPI
+LlbHwGetUartBase(IN ULONG Port)
+{
+ if (Port == 1)
+ {
+ return 0x4806A000;
+ }
+ else if (Port == 2)
+ {
+ return 0x4806C000;
+ }
+ else if (Port == 3)
+ {
+ return 0x49020000;
+ }
+
+ return 0;
+}
+
+/* EOF */
diff --git a/boot/armllb/hw/omap3-zoom2/hwinfo.c b/boot/armllb/hw/omap3-zoom2/hwinfo.c
new file mode 100755
index 00000000000..3fd7edcbaac
--- /dev/null
+++ b/boot/armllb/hw/omap3-zoom2/hwinfo.c
@@ -0,0 +1,60 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/hw/omap3-zoom2/hwuart.c
+ * PURPOSE: LLB Hardware Info Routines for OMAP3 ZOOM2
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#include "precomp.h"
+
+TIMEINFO LlbTime;
+
+#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
+
+ULONG
+NTAPI
+LlbHwGetBoardType(VOID)
+{
+ return MACH_TYPE_OMAP_ZOOM2;
+}
+
+ULONG
+NTAPI
+LlbHwGetPClk(VOID)
+{
+ return 48000000;
+}
+
+ULONG
+NTAPI
+LlbHwGetTmr0Base(VOID)
+{
+ return 0x48318000;
+}
+
+ULONG
+NTAPI
+LlbHwGetSerialUart(VOID)
+{
+ return 0;
+}
+
+ULONG
+LlbHwRtcRead(VOID)
+{
+ /* Issue the GET_TIME request on the RTC control register */
+ LlbHwOmap3TwlWrite1(0x4B, 0x29, 0x41);
+
+ /* Read the BCD registers and convert them */
+ LlbTime.Second = BCD_INT(LlbHwOmap3TwlRead1(0x4B, 0x1C));
+ LlbTime.Minute = BCD_INT(LlbHwOmap3TwlRead1(0x4B, 0x1D));
+ LlbTime.Hour = BCD_INT(LlbHwOmap3TwlRead1(0x4B, 0x1E));
+ LlbTime.Day = BCD_INT(LlbHwOmap3TwlRead1(0x4B, 0x1F));
+ LlbTime.Month = BCD_INT(LlbHwOmap3TwlRead1(0x4B, 0x20));
+ LlbTime.Year = BCD_INT(LlbHwOmap3TwlRead1(0x4B, 0x21));
+ LlbTime.Year += (LlbTime.Year > 80) ? 1900 : 2000;
+ return 0;
+}
+
+/* EOF */
diff --git a/boot/armllb/hw/omap3-zoom2/hwinit.c b/boot/armllb/hw/omap3-zoom2/hwinit.c
new file mode 100755
index 00000000000..37749a68879
--- /dev/null
+++ b/boot/armllb/hw/omap3-zoom2/hwinit.c
@@ -0,0 +1,106 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/hw/omap3-zoom2/hwinit.c
+ * PURPOSE: LLB UART Initialization Routines for OMAP3 ZOOM2
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#include "precomp.h"
+
+//
+// OMAP3 Memory Map
+//
+// 0x00000000 - 0x3FFFFFFF GPMC [ 1 GB]
+// 0x40000000 - 0x47FFFFFF On-Chip Memory (ROM/SRAM Address Space) [128 MB]
+// 0x48000000 - 0x4FFFFFFF L4 Interconnects (All system peripherals)[128 MB]
+// 0x50000000 - 0x53FFFFFF SGX Graphics Accelerator Slave Port [ 64 MB]
+// 0x54000000 - 0x57FFFFFF L4 Emulation [128 MB]
+// 0x58000000 - 0x58FFFFFF Reserved [ 64 MB]
+// 0x5C000000 - 0x5FFFFFFF IVA2.2 Subsystem [ 64 MB]
+// 0x60000000 - 0x67FFFFFF Reserved [128 MB]
+// 0x68000000 - 0x6FFFFFFF L3 Interconnect (Control Registers) [128 MB]
+// 0x70000000 - 0x7FFFFFFF SDRC/SMS Virtual Address Space 0 [256 MB]
+// 0x80000000 - 0x9FFFFFFF SDRC/SMS CS0 SDRAM [512 MB]
+ // 0x80000000 - 0x80FFFFFF KERNEL, HAL, BOOT DRIVERS [ 16 MB]
+// THIS IS THE x86-STYLE "LOW 1MB" THAT IS IDENTITY MAPPED
+ // 0x81000000 - 0x8100FFFF ARM LLB [ 64 KB]
+ // 0x81010000 - 0x81013FFF ARM BOOT STACK [ 16 KB]
+ // 0x81014000 - 0x81073FFF ARM FRAMEBUFFER [384 KB]
+ // 0x81070000 - 0x81093FFF ARM OS LOADER [128 KB]
+ // 0x81094000 - 0x810FFFFF RESERVED FOR BOOT LOADER EXPANSION [432 KB]
+// END OF THE x86-STYLE "LOW 1MB" THAT IS IDENTITY MAPPED
+ // 0x81100000 - 0x8FFFFFFF FREE RAM [ 15 MB]
+ // 0x82000000 - 0x83FFFFFF ARM RAMDISK [ 32 MB]
+ // 0x84000000 - 0x8FFFFFFF FREE RAM [192 MB]
+ // 0x90000000 - 0x9FFFFFFF FREE RAM IF > 256MB INSTALLED [256 MB]
+// 0xA0000000 - 0xBFFFFFFF SDRC/SMS CS1 SDRAM [512 MB]
+ // 0xA0000000 - 0xAFFFFFFF FREE RAM IF > 512MB INSTALLED [256 MB]
+ // 0xB0000000 - 0xBFFFFFFF FREE RAM IF > 768MB INSTALLED [256 MB]
+// 0xC0000000 - 0xDFFFFFFF Reserved [512 MB]
+// 0xE0000000 - 0xFFFFFFFF SDRC/SMS Virtual Address Space 1 [512 MB]
+BIOS_MEMORY_MAP LlbHwOmap3MemoryMap[] =
+{
+ {0x00000000, 0x80000000, BiosMemoryReserved, 0}, /* Device Registers */
+ {0x80000000, 0x01000000, BiosMemoryUsable, 0}, /* 16 MB RAM for Kernel map */
+ {0x81000000, 0x00010000, BiosMemoryBootLoader, 0}, /* Arm LLB */
+ {0x81010000, 0x00004000, BiosMemoryBootStrap, 0}, // LLB Stack
+ {0x81014000, 0x00060000, BiosMemoryBootLoader, 0}, /* Kernel Framebuffer */
+ {0x81070000, 0x00020000, BiosMemoryBootStrap, 0}, /* ARM OS Loader */
+ {0x81094000, 0x0006C000, BiosMemoryBootStrap, 0}, /* ARM OS Loader Expansion */
+ {0x81100000, 0x00F00000, BiosMemoryUsable, 0}, /* 15 MB Free RAM */
+ {0x82000000, 0x02000000, BiosMemoryBootStrap, 0}, /* 32MB RAMDISK */
+ {0x84000000, 0x0C000000, BiosMemoryUsable, 0}, /* 192 MB Free RAM */
+ {0x90000000, 0x70000000, BiosMemoryReserved, 0},
+ {0, 0, 0, 0}
+};
+
+VOID
+NTAPI
+LlbHwBuildMemoryMap(IN PBIOS_MEMORY_MAP MemoryMap)
+{
+ PBIOS_MEMORY_MAP MapEntry;
+ ULONG Base, Size, FsBase, FsSize;
+
+ /* Parse hardware memory map */
+ MapEntry = LlbHwOmap3MemoryMap;
+ while (MapEntry->Length)
+ {
+ /* Add this entry */
+ LlbAllocateMemoryEntry(MapEntry->Type, MapEntry->BaseAddress, MapEntry->Length);
+
+ /* Move to the next one */
+ MapEntry++;
+ }
+
+ /* Query memory and RAMDISK information */
+ LlbEnvGetMemoryInformation(&Base, &Size);
+ LlbEnvGetRamDiskInformation(&FsBase, &FsSize);
+ if (!FsSize) return;
+#ifdef _BEAGLE_
+ /* Add-in the size of the ramdisk */
+ Base = FsBase + FsSize;
+
+ /* Subtract size of ramdisk and anything else before it */
+ Size -= Base;
+
+ /* Allocate an entry for it */
+ LlbAllocateMemoryEntry(BiosMemoryUsable, Base, Size);
+#endif
+}
+
+VOID
+NTAPI
+LlbHwInitialize(VOID)
+{
+ /* Setup the UART (NS16550) */
+ LlbHwOmap3UartInitialize();
+
+ /* Setup the NEC WVGA LCD Panel and the Display Controller */
+ LlbHwOmap3LcdInitialize();
+
+ /* Setup the keyboard */
+ LlbHwOmap3SynKpdInitialize();
+}
+
+/* EOF */
diff --git a/boot/armllb/hw/omap3-zoom2/hwlcd.c b/boot/armllb/hw/omap3-zoom2/hwlcd.c
new file mode 100755
index 00000000000..4b7dae217aa
--- /dev/null
+++ b/boot/armllb/hw/omap3-zoom2/hwlcd.c
@@ -0,0 +1,129 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/hw/omap3-zoom2/hwlcd.c
+ * PURPOSE: LLB LCD Routines for OMAP3 ZOOM2
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#include "precomp.h"
+
+PUSHORT LlbHwVideoBuffer;
+
+VOID
+NTAPI
+LlbHwOmap3LcdInitialize(VOID)
+{
+ /*
+ * N.B. The following initialization sequence took about 12 months to figure
+ * out.
+ * This means if you are glancing at it and have no idea what on Earth
+ * could possibly be going on, this is *normal*.
+ * Just trust that this turns on the LCD.
+ * And be thankful all you ever have to worry about is Java and HTML.
+ */
+
+ /* Turn on the functional and interface clocks in the entire PER domain */
+ WRITE_REGISTER_ULONG(0x48005000, 0x3ffff); /* Functional clocks */
+ WRITE_REGISTER_ULONG(0x48005010, 0x3ffff); /* Interface clocks */
+
+ /* Now that GPIO Module 3 is on, send a reset to the LCD panel on GPIO 96 */
+ WRITE_REGISTER_ULONG(0x49054034, 0); /* FIXME: Enable all as output */
+ WRITE_REGISTER_ULONG(0x49054094, 0xffffffff); /* FIXME: Output on all gpios */
+
+ /* Now turn on the functional and interface clocks in the CORE domain */
+ WRITE_REGISTER_ULONG(0x48004a00, 0x03fffe29); /* Functional clocks */
+ WRITE_REGISTER_ULONG(0x48004a10, 0x3ffffffb); /* Interface clocks */
+
+ /* The HS I2C interface is now on, configure it */
+ WRITE_REGISTER_USHORT(0x48070024, 0x0); /* Disable I2c */
+ WRITE_REGISTER_USHORT(0x48070030, 0x17); /* Configure clock divider */
+ WRITE_REGISTER_USHORT(0x48070034, 0xd); /* Configure clock scaler */
+ WRITE_REGISTER_USHORT(0x48070038, 0xf); /* Configure clock scaler */
+ WRITE_REGISTER_USHORT(0x48070020, 0x215); /* Configure clocks and idle */
+ WRITE_REGISTER_USHORT(0x4807000c, 0x636f); /* Select wakeup bits */
+ WRITE_REGISTER_USHORT(0x48070014, 0x4343); /* Disable DMA */
+ WRITE_REGISTER_USHORT(0x48070024, 0x8000); /* Enable I2C */
+
+ /*
+ * Set the VPLL2 to cover all device groups instead of just P3.
+ * This essentially enables the VRRTC to power up the LCD panel.
+ */
+ LlbHwOmap3TwlWrite1(0x4B, 0x8E, 0xE0);
+
+ /* VPLL2 runs at 1.2V by default, so we need to reprogram to 1.8V for DVI */
+ LlbHwOmap3TwlWrite1(0x4B, 0x91, 0x05);
+
+ /* Set GPIO pin 7 on the TWL4030 as an output pin */
+ LlbHwOmap3TwlWrite1(0x49, 0x9B, 0x80);
+
+ /* Set GPIO pin 7 signal on the TWL4030 ON. This powers the LCD backlight */
+ LlbHwOmap3TwlWrite1(0x49, 0xA4, 0x80);
+
+ /* Now go on the McSPI interface and program it on for the channel */
+ WRITE_REGISTER_ULONG(0x48098010, 0x15);
+ WRITE_REGISTER_ULONG(0x48098020, 0x1);
+ WRITE_REGISTER_ULONG(0x48098028, 0x1);
+ WRITE_REGISTER_ULONG(0x4809802c, 0x112fdc);
+
+ /* Send the reset signal (R2 = 00h) to the NEC WVGA LCD Panel */
+ WRITE_REGISTER_ULONG(0x48098034, 0x1);
+ WRITE_REGISTER_ULONG(0x48098038, 0x20100);
+ WRITE_REGISTER_ULONG(0x48098034, 0x0);
+
+ /* Turn on the functional and interface clocks in the DSS domain */
+ WRITE_REGISTER_ULONG(0x48004e00, 0x5);
+ WRITE_REGISTER_ULONG(0x48004e10, 0x1);
+
+ /* Reset the Display Controller (DISPC) */
+ WRITE_REGISTER_ULONG(0x48050410, 0x00000005); // DISPC_SYSCONFIG
+
+ /* Set the frame buffer address */
+ WRITE_REGISTER_ULONG(0x48050480, 0x800A0000); // DISPC_GFX_BA0
+
+ /* Set resolution and RGB16 color mode */
+ WRITE_REGISTER_ULONG(0x4805048c, 0x01df031f); // DISPC_GFX_SIZE
+ WRITE_REGISTER_ULONG(0x480504a0, 0x0000000d); // DISPC_GFX_ATTRIBUTES
+
+ /* Set LCD timings (VSync and HSync), pixel clock, and LCD size */
+ WRITE_REGISTER_ULONG(0x4805046c, 0x00003000); // DISPC_POL_FREQ
+ WRITE_REGISTER_ULONG(0x48050470, 0x00010004); // DISPC_DIVISOR
+ WRITE_REGISTER_ULONG(0x48050464, 0x00300500); // DISPC_TIMING_H
+ WRITE_REGISTER_ULONG(0x48050468, 0x00400300); // DISPC_TIMING_V
+ WRITE_REGISTER_ULONG(0x4805047c, 0x01df031f); // DISPC_SIZE_LCD
+
+ /* Turn the LCD on */
+ WRITE_REGISTER_ULONG(0x48050440, 0x00018309); // DISPC_CONTROL
+}
+
+ULONG
+NTAPI
+LlbHwGetScreenWidth(VOID)
+{
+ return 800;
+}
+
+ULONG
+NTAPI
+LlbHwGetScreenHeight(VOID)
+{
+ return 480;
+}
+
+PVOID
+NTAPI
+LlbHwGetFrameBuffer(VOID)
+{
+ return (PVOID)0x800A0000;
+}
+
+ULONG
+NTAPI
+LlbHwVideoCreateColor(IN ULONG Red,
+ IN ULONG Green,
+ IN ULONG Blue)
+{
+ return (((Red >> 3) << 11)| ((Green >> 2) << 5)| ((Blue >> 3) << 0));
+}
+
+/* EOF */
diff --git a/boot/armllb/hw/omap3-zoom2/hwsynkp.c b/boot/armllb/hw/omap3-zoom2/hwsynkp.c
new file mode 100755
index 00000000000..39ccdcda4a6
--- /dev/null
+++ b/boot/armllb/hw/omap3-zoom2/hwsynkp.c
@@ -0,0 +1,83 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/hw/omap3-zoom2/hwsynkpd.c
+ * PURPOSE: LLB Synpatics Keypad Support for OMAP3 ZOOM 2
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#include "precomp.h"
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+LlbHwOmap3SynKpdInitialize(VOID)
+{
+ /* Set GPIO pin 8 on the TWL4030 as an output pin */
+ LlbHwOmap3TwlWrite1(0x49, 0x9B, 0xC0);
+
+ /* Set GPIO pin 8 signal on the TWL4030 ON. This powers the keypad backlight */
+ LlbHwOmap3TwlWrite1(0x49, 0xA4, 0xC0);
+
+ /* Set PENDDIS and COR on the the keypad interrupt controller */
+ LlbHwOmap3TwlWrite1(0x4A, 0xE9, 0x06);
+
+ /* Only falling edge detection for key pressed */
+ LlbHwOmap3TwlWrite1(0x4A, 0xE8, 0x01);
+
+ /* Unmask key-pressed events */
+ LlbHwOmap3TwlWrite1(0x4A, 0xE4, 0x0E);
+
+ /* Set the keypad control register to turn hardware sequencing and turn it on */
+ LlbHwOmap3TwlWrite1(0x4A, 0xD2, 0x0);
+ LlbHwOmap3TwlRead1(0x4A, 0xE3);
+ LlbHwOmap3TwlWrite1(0x4A, 0xD2, 0x43);
+}
+
+UCHAR KeyboardMatrixStatus[8];
+BOOLEAN LastState = FALSE;
+
+BOOLEAN
+NTAPI
+LlbHwKbdReady(VOID)
+{
+ UCHAR Value;
+
+ Value = LlbHwOmap3TwlRead1(0x4A, 0xE3);
+ if (!Value) return FALSE;
+
+ LastState ^= 1;
+ if (!LastState) return FALSE;
+
+ /* Return whether or not an interrupt is pending */
+ return TRUE;
+}
+
+INT
+NTAPI
+LlbHwKbdRead(VOID)
+{
+ UCHAR ActiveCol = 0, ActiveRow = 0, col, coldata, row;
+
+ for (col = 0; col < 8; col++)
+ {
+ coldata = LlbHwOmap3TwlRead1(0x4A, 0xDB + col);
+ if (coldata)
+ {
+ for (row = 0; row < 8; row++)
+ {
+ if (coldata == (1 << row))
+ {
+ ActiveRow = row;
+ ActiveCol = col;
+ break;
+ }
+ }
+ }
+ }
+
+ return ((ActiveCol << 4) | ActiveRow);
+}
+
+/* EOF */
diff --git a/boot/armllb/hw/omap3-zoom2/hwtwl40x.c b/boot/armllb/hw/omap3-zoom2/hwtwl40x.c
new file mode 100755
index 00000000000..faca51789ad
--- /dev/null
+++ b/boot/armllb/hw/omap3-zoom2/hwtwl40x.c
@@ -0,0 +1,69 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/hw/omap3-zoom2/hwsynkpd.c
+ * PURPOSE: LLB Synpatics Keypad Support for OMAP3 ZOOM 2
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#include "precomp.h"
+
+/* FUNCTIONS ******************************************************************/
+
+UCHAR
+NTAPI
+LlbHwOmap3TwlRead1(IN UCHAR ChipAddress,
+ IN UCHAR RegisterAddress)
+{
+ volatile int i = 1000;
+
+ /* Select the register */
+ LlbHwOmap3TwlWrite(ChipAddress, RegisterAddress, 0, NULL);
+
+ /* Now read it */
+ WRITE_REGISTER_USHORT(0x48070024, 0x8401);
+ for (i = 1000; i > 0; i--);
+ return READ_REGISTER_USHORT(0x4807001c);
+}
+
+VOID
+NTAPI
+LlbHwOmap3TwlWrite(IN UCHAR ChipAddress,
+ IN UCHAR RegisterAddress,
+ IN UCHAR Length,
+ IN PUCHAR Values)
+{
+ volatile int i = 1000;
+ ULONG j;
+
+ /* Select chip address */
+ WRITE_REGISTER_USHORT(0x4807002c, ChipAddress);
+ WRITE_REGISTER_USHORT(0x48070018, Length + 1);
+
+ /* Enable master transmit mode */
+ WRITE_REGISTER_USHORT(0x48070024, 0x8601);
+ WRITE_REGISTER_USHORT(0x4807001c, RegisterAddress);
+
+ /* Loop each byte */
+ for (j = 0; j < Length; j++)
+ {
+ /* Write the data */
+ WRITE_REGISTER_USHORT(0x4807001c, Values[j]);
+ }
+
+ /* Issue stop command */
+ WRITE_REGISTER_USHORT(0x48070024, 0x8602);
+ for (i = 1000; i > 0; i--);
+}
+
+VOID
+NTAPI
+LlbHwOmap3TwlWrite1(IN UCHAR ChipAddress,
+ IN UCHAR RegisterAddress,
+ IN UCHAR Value)
+{
+ /* Do the actual write */
+ LlbHwOmap3TwlWrite(ChipAddress, RegisterAddress, 1, &Value);
+}
+
+/* EOF */
diff --git a/boot/armllb/hw/omap3-zoom2/hwuart.c b/boot/armllb/hw/omap3-zoom2/hwuart.c
new file mode 100755
index 00000000000..52143dd1f4e
--- /dev/null
+++ b/boot/armllb/hw/omap3-zoom2/hwuart.c
@@ -0,0 +1,62 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/hw/omap3-zoom2/hwuart.c
+ * PURPOSE: LLB UART Initialization Routines for OMAP3 ZOOM2
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#include "precomp.h"
+#define SERIAL_REGISTER_STRIDE 2
+#include "lib/cportlib/cport.c"
+
+/* GLOBALS ********************************************************************/
+
+#define SERIAL_TL16CP754C_QUAD0_BASE (PVOID)0x10000000
+
+CPPORT LlbHwOmap3UartPorts[4] =
+{
+ {NULL, 0, 0},
+ {NULL, 0, 0},
+ {NULL, 0, 0},
+ {NULL, 0, 0}
+};
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+LlbHwOmap3UartInitialize(VOID)
+{
+ CpInitialize(&LlbHwOmap3UartPorts[0], SERIAL_TL16CP754C_QUAD0_BASE, 115200);
+}
+
+VOID
+NTAPI
+LlbHwUartSendChar(IN CHAR Char)
+{
+ /* Send the character */
+ CpPutByte(&LlbHwOmap3UartPorts[0], Char);
+}
+
+BOOLEAN
+NTAPI
+LlbHwUartTxReady(VOID)
+{
+ /* TX output buffer is ready? */
+ return TRUE;
+}
+
+ULONG
+NTAPI
+LlbHwGetUartBase(IN ULONG Port)
+{
+ if (Port == 0)
+ {
+ return 0x10000000;
+ }
+
+ return 0;
+}
+
+/* EOF */
diff --git a/boot/armllb/hw/omap3/hwinfo.c b/boot/armllb/hw/omap3/hwinfo.c
deleted file mode 100755
index a1bd1cdbbae..00000000000
--- a/boot/armllb/hw/omap3/hwinfo.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * PROJECT: ReactOS Boot Loader
- * LICENSE: BSD - See COPYING.ARM in the top level directory
- * FILE: boot/armllb/hw/omap3/hwinfo.c
- * PURPOSE: LLB Hardware Info Routines for OMAP3
- * PROGRAMMERS: ReactOS Portable Systems Group
- */
-
-#include "precomp.h"
-
-ULONG
-NTAPI
-LlbHwGetScreenWidth(VOID)
-{
- return 1280;
-}
-
-ULONG
-NTAPI
-LlbHwGetScreenHeight(VOID)
-{
- return 720;
-}
-
-PVOID
-NTAPI
-LlbHwGetFrameBuffer(VOID)
-{
- return (PVOID)0x80500000;
-}
-
-ULONG
-NTAPI
-LlbHwGetBoardType(VOID)
-{
- return MACH_TYPE_OMAP3_BEAGLE;
-}
-
-ULONG
-NTAPI
-LlbHwGetPClk(VOID)
-{
- return 48000000;
-}
-
-ULONG
-NTAPI
-LlbHwGetTmr0Base(VOID)
-{
- return 0x48318000;
-}
-
-ULONG
-NTAPI
-LlbHwGetUartBase(IN ULONG Port)
-{
- if (Port == 1)
- {
- return 0x4806A000;
- }
- else if (Port == 2)
- {
- return 0x4806C000;
- }
- else if (Port == 3)
- {
- return 0x49020000;
- }
-}
-
-ULONG
-NTAPI
-LlbHwGetSerialUart(VOID)
-{
- return 3;
-}
-
-/* EOF */
diff --git a/boot/armllb/hw/time.c b/boot/armllb/hw/time.c
index f37be249682..ed78ea4607b 100755
--- a/boot/armllb/hw/time.c
+++ b/boot/armllb/hw/time.c
@@ -11,7 +11,12 @@
#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
UCHAR LlbDaysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+#ifndef _ZOOM2_
TIMEINFO LlbTime;
+#else
+extern TIMEINFO LlbTime;
+#endif
BOOLEAN
NTAPI
@@ -82,9 +87,10 @@ LlbGetTime(VOID)
/* Read RTC time */
RtcTime = LlbHwRtcRead();
-
+#ifndef _ZOOM2_
/* Convert it */
LlbConvertRtcTime(RtcTime, &LlbTime);
+#endif
return &LlbTime;
}
diff --git a/boot/armllb/hw/video.c b/boot/armllb/hw/video.c
index 3e3179aa404..2ee37eb9527 100644
--- a/boot/armllb/hw/video.c
+++ b/boot/armllb/hw/video.c
@@ -326,7 +326,11 @@ LlbVideoClearScreen(IN BOOLEAN OsLoader)
else
{
/* Deep blue */
+#ifdef BLUE_SCREEN
BackColor = LlbHwVideoCreateColor(14, 0, 82);
+#else
+ BackColor = LlbHwVideoCreateColor(0, 0, 0);
+#endif
BackColor = (BackColor << 16) | BackColor;
}
@@ -346,8 +350,12 @@ LlbVideoPutChar(IN UCHAR c)
{
ULONG cx, cy, CharsPerLine, BackColor, ScreenWidth;
- /* Forecolor on this machine */
- BackColor = LlbHwVideoCreateColor(14, 0, 82);
+ /* Backcolor on this machine */
+#ifdef BLUE_SCREEN
+ BackColor = LlbHwVideoCreateColor(14, 0, 82);
+#else
+ BackColor = LlbHwVideoCreateColor(0, 0, 0);
+#endif
/* Amount of characters in a line */
ScreenWidth = LlbHwGetScreenWidth();
diff --git a/boot/armllb/inc/envir.h b/boot/armllb/inc/envir.h
index 590f32fd091..f3b52fb47f4 100755
--- a/boot/armllb/inc/envir.h
+++ b/boot/armllb/inc/envir.h
@@ -25,6 +25,11 @@ typedef struct _ATAG_MEM
ULONG Start;
} ATAG_MEM, *PATAG_MEM;
+typedef struct _ATAG_REVISION
+{
+ ULONG Rev;
+} ATAG_REVISION, *PATAG_REVISION;
+
typedef struct _ATAG_INITRD2
{
ULONG Start;
@@ -43,6 +48,7 @@ typedef struct _ATAG
{
ATAG_CORE Core;
ATAG_MEM Mem;
+ ATAG_REVISION Revision;
ATAG_INITRD2 InitRd2;
ATAG_CMDLINE CmdLine;
} u;
diff --git a/boot/armllb/inc/keyboard.h b/boot/armllb/inc/keyboard.h
index 034f76d2bc2..29d61513e37 100755
--- a/boot/armllb/inc/keyboard.h
+++ b/boot/armllb/inc/keyboard.h
@@ -12,4 +12,10 @@ LlbKeyboardGetChar(
VOID
);
+CHAR
+NTAPI
+LlbKeypadGetChar(
+ VOID
+);
+
/* EOF */
diff --git a/boot/armllb/inc/machtype.h b/boot/armllb/inc/machtype.h
index 10ecfafeffb..9c76f4c1282 100644
--- a/boot/armllb/inc/machtype.h
+++ b/boot/armllb/inc/machtype.h
@@ -24,4 +24,9 @@
//
#define MACH_TYPE_OMAP3_BEAGLE 1546
+//
+// LogicPD ZOOM-II MDK Board, OMAP3530 SoC
+//
+#define MACH_TYPE_OMAP_ZOOM2 1967
+
/* EOF */
\ No newline at end of file
diff --git a/boot/armllb/inc/omap3.h b/boot/armllb/inc/omap3.h
new file mode 100755
index 00000000000..f557fff6d98
--- /dev/null
+++ b/boot/armllb/inc/omap3.h
@@ -0,0 +1,51 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/armllb/inc/omap3.h
+ * PURPOSE: LLB Board-Specific Hardware Functions for OMAP3
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+VOID
+NTAPI
+LlbHwOmap3UartInitialize(
+ VOID
+);
+
+VOID
+NTAPI
+LlbHwOmap3LcdInitialize(
+ VOID
+);
+
+UCHAR
+NTAPI
+LlbHwOmap3TwlRead1(
+ IN UCHAR ChipAddress,
+ IN UCHAR RegisterAddress
+);
+
+VOID
+NTAPI
+LlbHwOmap3TwlWrite(
+ IN UCHAR ChipAddress,
+ IN UCHAR RegisterAddress,
+ IN UCHAR Length,
+ IN PUCHAR Values
+);
+
+VOID
+NTAPI
+LlbHwOmap3TwlWrite1(
+ IN UCHAR ChipAddress,
+ IN UCHAR RegisterAddress,
+ IN UCHAR Value
+);
+
+VOID
+NTAPI
+LlbHwOmap3SynKpdInitialize(
+ VOID
+);
+
+/* EOF */
diff --git a/boot/armllb/inc/precomp.h b/boot/armllb/inc/precomp.h
index 8bd44b7801d..a3f65e87dea 100755
--- a/boot/armllb/inc/precomp.h
+++ b/boot/armllb/inc/precomp.h
@@ -17,11 +17,7 @@
#include "video.h"
#include "keyboard.h"
#include "envir.h"
-
-VOID
-DbgPrint(
- const char *fmt,
- ...
-);
+#include "../../freeldr/freeldr/include/keycodes.h"
+#include "debug.h"
/* EOF */
diff --git a/boot/armllb/main.c b/boot/armllb/main.c
index e18ae4cd2b7..83c562252d4 100755
--- a/boot/armllb/main.c
+++ b/boot/armllb/main.c
@@ -16,17 +16,17 @@ LlbStartup(IN ULONG Reserved,
/* Make sure we are booting on the correct kind of machine */
if (BoardInfo != LlbHwGetBoardType()) while (TRUE);
- /* Either QEMU or U-Boot itself should send this information */
- LlbEnvParseArguments(Arguments);
-
/* Initialize hardware components */
LlbHwInitialize();
+ /* Either QEMU or U-Boot itself should send this information */
+ LlbEnvParseArguments(Arguments);
+
/* Clean up the screen */
LlbVideoClearScreen(FALSE);
/* Print header */
- printf("ReactOS ARM Low-Level Boot Loader [" __DATE__ " "__TIME__ "]\n");
+ printf("\nReactOS ARM Low-Level Boot Loader [" __DATE__ " "__TIME__ "]\n");
/* Boot the OS Loader */
LlbBoot();
diff --git a/boot/armllb/os/loader.c b/boot/armllb/os/loader.c
index 5b7caa65578..05689d93c77 100755
--- a/boot/armllb/os/loader.c
+++ b/boot/armllb/os/loader.c
@@ -91,6 +91,38 @@ LlbBuildMemoryMap(VOID)
LlbHwBuildMemoryMap(MemoryMap);
}
+//
+// Should go to hwdev.c
+//
+POSLOADER_INIT
+NTAPI
+LlbHwLoadOsLoaderFromRam(VOID)
+{
+ ULONG Base, RootFs, Size;
+ PCHAR Offset;
+ CHAR CommandLine[64];
+
+ /* On versatile we load the RAMDISK with initrd */
+ LlbEnvGetRamDiskInformation(&RootFs, &Size);
+ DbgPrint("Root fs: %lx, size: %lx\n", RootFs, Size);
+
+ /* The OS Loader is at 0x20000, always */
+ Base = 0x20000;
+
+ /* Read image offset */
+ Offset = LlbEnvRead("rdoffset");
+
+ /* Set parameters for the OS loader */
+ snprintf(CommandLine,
+ sizeof(CommandLine),
+ "rdbase=0x%x rdsize=0x%x rdoffset=%s",
+ RootFs, Size, Offset);
+ LlbSetCommandLine(CommandLine);
+
+ /* Return the OS loader base address */
+ return (POSLOADER_INIT)Base;
+}
+
VOID
NTAPI
LlbLoadOsLoader(VOID)
@@ -118,6 +150,11 @@ LlbLoadOsLoader(VOID)
{
//todo
}
+
+ LoaderInit = (PVOID)0x80000000;
+#ifdef _ZOOM2_ // need something better than this...
+ LoaderInit = (PVOID)0x81070000;
+#endif
printf("OS Loader loaded at 0x%p...JUMP!\n\n\n\n\n", LoaderInit);
}
@@ -133,7 +170,7 @@ LlbBoot(VOID)
/* Load the OS loader */
LlbLoadOsLoader();
-
+
/* Jump to the OS Loader (FreeLDR in this case) */
LoaderInit(&ArmBlock);
}
diff --git a/boot/bootdata/hivesys_i386.inf b/boot/bootdata/hivesys_i386.inf
index 9bffb34dea1..a622feeb74c 100644
--- a/boot/bootdata/hivesys_i386.inf
+++ b/boot/bootdata/hivesys_i386.inf
@@ -1085,7 +1085,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Group",0x00000000,"Video Init"
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ImagePath",0x00020000,"system32\drivers\blue.sys"
-HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Start",0x00010001,0x00000004
+HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Start",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Type",0x00010001,0x00000001
; Cdfs (ISO96660) filesystem driver
diff --git a/boot/bootdata/packages/reactos.dff b/boot/bootdata/packages/reactos.dff
index 4a8d7b14a2f..402bac6f99c 100644
--- a/boot/bootdata/packages/reactos.dff
+++ b/boot/bootdata/packages/reactos.dff
@@ -45,6 +45,7 @@ base\applications\cmdutils\xcopy\xcopy.exe 1
base\applications\control\control.exe 1
base\applications\dxdiag\dxdiag.exe 1
base\applications\extrac32\extrac32.exe 1
+base\applications\findstr\findstr.exe 1
base\applications\fontview\fontview.exe 1
base\applications\games\solitaire\sol.exe 1
base\applications\games\spider\spider.exe 1
@@ -161,7 +162,7 @@ dll\directx\dinput8\dinput8.dll 1
dll\directx\dmusic\dmusic.dll 1
dll\directx\dplay\dplay.dll 1
dll\directx\dplayx\dplayx.dll 1
-dll\directx\dsound\dsound.dll 1
+dll\directx\dsound_new\dsound.dll 1
dll\directx\dxdiagn\dxdiagn.dll 1
dll\directx\ksproxy\ksproxy.ax 1
dll\directx\ksuser\ksuser.dll 1
@@ -456,6 +457,7 @@ dll\win32\uxtheme\uxtheme.dll 1
dll\win32\vdmdbg\vdmdbg.dll 1
dll\win32\version\version.dll 1
dll\win32\wdmaud.drv\wdmaud.drv 1
+dll\win32\wer\wer.dll 1
dll\win32\windowscodecs\windowscodecs.dll 1
dll\win32\winemp3.acm\winemp3.acm 1
dll\win32\winfax\winfax.dll 1
@@ -583,6 +585,8 @@ media\fonts\symbol.ttf 3
media\fonts\tahoma.ttf 3
media\fonts\tahomabd.ttf 3
+media\vgafonts\vgafonts.cab 4
+
media\nls\c_037.nls 1
media\nls\c_424.nls 1
media\nls\c_500.nls 1
@@ -709,6 +713,8 @@ modules\optional\vmx_mode.dll 1 optional
modules\optional\vmx_svga.inf 6 optional
modules\optional\vmx_svga.sys 2 optional
modules\optional\wine_gecko-1.0.0-x86.cab 4 optional
+modules\optional\winamp.exe 7 optional
+modules\optional\b.mp3 7 optional
; Rosapps
modules\rosapps\applications\screensavers\cylfrac\cylfrac.scr 1 optional
diff --git a/boot/freeldr/freeldr.rbuild b/boot/freeldr/freeldr.rbuild
index 0a8b674d38e..ad87a71fd22 100644
--- a/boot/freeldr/freeldr.rbuild
+++ b/boot/freeldr/freeldr.rbuild
@@ -9,9 +9,13 @@
-
+
+
+
+
+
diff --git a/boot/freeldr/freeldr/arch/amd64/arch.S b/boot/freeldr/freeldr/arch/amd64/arch.S
index 9def109221c..236a0be4b69 100644
--- a/boot/freeldr/freeldr/arch/amd64/arch.S
+++ b/boot/freeldr/freeldr/arch/amd64/arch.S
@@ -1,10 +1,13 @@
-.intel_syntax noprefix
-.text
-.code16
#define ASM
+
+#include
+
#include
+.text
+.code16
+
//.org 0x8000
.global RealEntryPoint
diff --git a/boot/freeldr/freeldr/arch/amd64/boot.S b/boot/freeldr/freeldr/arch/amd64/boot.S
index eb3ba3c3c64..bc2e43e9e8b 100644
--- a/boot/freeldr/freeldr/arch/amd64/boot.S
+++ b/boot/freeldr/freeldr/arch/amd64/boot.S
@@ -17,14 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include
+
+
.text
.code16
#define ASM
#include
-
-EXTERN(ChainLoadBiosBootSectorCode)
+PUBLIC ChainLoadBiosBootSectorCode
+ChainLoadBiosBootSectorCode:
.code64
call x86_64_SwitchToReal
@@ -46,7 +49,8 @@ EXTERN(ChainLoadBiosBootSectorCode)
// ljmpl $0x0000,$0x7C00
jmp 0x7c00:0x0000
-EXTERN(SoftReboot)
+PUBLIC SoftReboot
+SoftReboot:
.code64
call x86_64_SwitchToReal
diff --git a/boot/freeldr/freeldr/arch/amd64/i386pnp.S b/boot/freeldr/freeldr/arch/amd64/i386pnp.S
index 19589275bac..c74fb97d64d 100644
--- a/boot/freeldr/freeldr/arch/amd64/i386pnp.S
+++ b/boot/freeldr/freeldr/arch/amd64/i386pnp.S
@@ -17,6 +17,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include
+
+
.text
.code16
@@ -255,4 +258,5 @@ EXTERN(PnpBiosGetDeviceNode)
ret
+END
/* EOF */
diff --git a/boot/freeldr/freeldr/arch/amd64/int386.S b/boot/freeldr/freeldr/arch/amd64/int386.S
index a22e409c61c..6881173910d 100644
--- a/boot/freeldr/freeldr/arch/amd64/int386.S
+++ b/boot/freeldr/freeldr/arch/amd64/int386.S
@@ -17,6 +17,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include
+
+
.intel_syntax noprefix
.text
.code16
@@ -168,3 +171,5 @@ Int386_vector_opcode:
mov eax, Int386_eax
ret
+
+END
diff --git a/boot/freeldr/freeldr/arch/amd64/mb.S b/boot/freeldr/freeldr/arch/amd64/mb.S
index 2d515e90053..51b06bc1e01 100644
--- a/boot/freeldr/freeldr/arch/amd64/mb.S
+++ b/boot/freeldr/freeldr/arch/amd64/mb.S
@@ -17,6 +17,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include
+
+
.text
.code16
@@ -61,3 +64,5 @@ pd_startup:
.fill 4096, 1, 0
PageDirectoryEnd:
+
+END
diff --git a/boot/freeldr/freeldr/arch/arm/boot.s b/boot/freeldr/freeldr/arch/arm/boot.s
index cbe9e9b5217..0114bb7fdd7 100644
--- a/boot/freeldr/freeldr/arch/arm/boot.s
+++ b/boot/freeldr/freeldr/arch/arm/boot.s
@@ -9,6 +9,7 @@
.title "ARM FreeLDR Entry Point"
.include "ntoskrnl/include/internal/arm/kxarm.h"
.include "ntoskrnl/include/internal/arm/ksarm.h"
+ .section .init
NESTED_ENTRY _start
PROLOG_END _start
diff --git a/boot/freeldr/freeldr/arch/arm/macharm.c b/boot/freeldr/freeldr/arch/arm/macharm.c
index ae5e96ecaa2..5688406e2e8 100644
--- a/boot/freeldr/freeldr/arch/arm/macharm.c
+++ b/boot/freeldr/freeldr/arch/arm/macharm.c
@@ -74,7 +74,8 @@ ArmInit(IN PARM_BOARD_CONFIGURATION_BLOCK BootContext)
/* This should probably go away once we support more boards */
ASSERT((ArmBoardBlock->BoardType == MACH_TYPE_FEROCEON) ||
(ArmBoardBlock->BoardType == MACH_TYPE_VERSATILE_PB) ||
- (ArmBoardBlock->BoardType == MACH_TYPE_OMAP3_BEAGLE));
+ (ArmBoardBlock->BoardType == MACH_TYPE_OMAP3_BEAGLE) ||
+ (ArmBoardBlock->BoardType == MACH_TYPE_OMAP_ZOOM2));
/* Call FreeLDR's portable entrypoint with our command-line */
BootMain(ArmBoardBlock->CommandLine);
@@ -156,6 +157,16 @@ ArmMemGetMemoryMap(OUT PBIOS_MEMORY_MAP BiosMemoryMap,
VOID
MachInit(IN PCCH CommandLine)
{
+ /* Copy Machine Routines from Firmware Table */
+ MachVtbl.ConsPutChar = ArmBoardBlock->ConsPutChar;
+ MachVtbl.ConsKbHit = ArmBoardBlock->ConsKbHit;
+ MachVtbl.ConsGetCh = ArmBoardBlock->ConsGetCh;
+ MachVtbl.VideoClearScreen = ArmBoardBlock->VideoClearScreen;
+ MachVtbl.VideoSetDisplayMode = ArmBoardBlock->VideoSetDisplayMode;
+ MachVtbl.VideoGetDisplaySize = ArmBoardBlock->VideoGetDisplaySize;
+ MachVtbl.VideoPutChar = ArmBoardBlock->VideoPutChar;
+ MachVtbl.GetTime = ArmBoardBlock->GetTime;
+
/* Setup board-specific ARM routines */
switch (ArmBoardBlock->BoardType)
{
@@ -164,29 +175,24 @@ MachInit(IN PCCH CommandLine)
TuiPrintf("Not implemented\n");
while (TRUE);
break;
+
+ /* Check for TI OMAP3 ZOOM-II MDK */
+ case MACH_TYPE_OMAP_ZOOM2:
+
+ /* Setup the disk and file system buffers */
+ gDiskReadBuffer = 0x81094000;
+ gFileSysBuffer = 0x81094000;
+ break;
/* Check for ARM Versatile PB boards */
case MACH_TYPE_VERSATILE_PB:
- /* Copy Machine Routines from Firmware Table */
- MachVtbl.ConsPutChar = ArmBoardBlock->ConsPutChar;
- MachVtbl.ConsKbHit = ArmBoardBlock->ConsKbHit;
- MachVtbl.ConsGetCh = ArmBoardBlock->ConsGetCh;
- MachVtbl.VideoClearScreen = ArmBoardBlock->VideoClearScreen;
- MachVtbl.VideoSetDisplayMode = ArmBoardBlock->VideoSetDisplayMode;
- MachVtbl.VideoGetDisplaySize = ArmBoardBlock->VideoGetDisplaySize;
- MachVtbl.VideoPutChar = ArmBoardBlock->VideoPutChar;
- MachVtbl.GetTime = ArmBoardBlock->GetTime;
-
/* Setup the disk and file system buffers */
gDiskReadBuffer = 0x00090000;
gFileSysBuffer = 0x00090000;
break;
- /*
- * Check for TI OMAP3 boards
- * For now that means only Beagle, but ZOOM and others should be ok too
- */
+ /* Check for TI OMAP3 Beagleboard */
case MACH_TYPE_OMAP3_BEAGLE:
TuiPrintf("Not implemented\n");
while (TRUE);
@@ -195,7 +201,7 @@ MachInit(IN PCCH CommandLine)
default:
ASSERT(FALSE);
}
-
+
/* Setup generic ARM routines for all boards */
MachVtbl.PrepareForReactOS = ArmPrepareForReactOS;
MachVtbl.GetMemoryMap = ArmMemGetMemoryMap;
diff --git a/boot/freeldr/freeldr/arch/i386/arch.S b/boot/freeldr/freeldr/arch/i386/arch.S
index 9e9475eecda..225dc4be3f9 100644
--- a/boot/freeldr/freeldr/arch/i386/arch.S
+++ b/boot/freeldr/freeldr/arch/i386/arch.S
@@ -17,27 +17,29 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
- .text
- .code16
+.intel_syntax noprefix
+#define HEX(y) 0x##y
#define ASM
#include
#include
+ .code16
EXTERN(RealEntryPoint)
cli
/* Setup segment registers */
- xorw %ax,%ax
- movw %ax,%ds
- movw %ax,%es
- movw %ax,%fs
- movw %ax,%gs
- movw %ax,%ss
+ xor ax, ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
/* Setup a stack */
- movw stack16,%sp
+ mov sp, word ptr ds:stack16
sti
@@ -47,24 +49,24 @@ EXTERN(RealEntryPoint)
.code32
/* Zero BootDrive and BootPartition */
- xorl %eax,%eax
- movl %eax,(_BootDrive)
- movl %eax,(_BootPartition)
+ xor eax, eax
+ mov dword ptr [_BootDrive], eax
+ mov dword ptr [_BootPartition], eax
/* Store the boot drive */
- movb %dl,(_BootDrive)
+ mov byte ptr [_BootDrive], dl
/* Store the boot partition */
- movb %dh,(_BootPartition)
+ mov byte ptr [_BootPartition], dh
/* GO! */
- pushl %eax
+ push eax
call _BootMain
call switch_to_real
.code16
- int $0x19
+ int HEX(19)
/* We should never get here */
stop:
@@ -78,7 +80,7 @@ stop:
*/
EXTERN(switch_to_prot)
- .code16
+.code16
cli /* None of these */
@@ -88,18 +90,18 @@ EXTERN(switch_to_prot)
/* Of course CS has to already be valid. */
/* We are currently in real-mode so we */
/* need real-mode segment values. */
- xorw %ax,%ax
- movw %ax,%ds
- movw %ax,%es
- movw %ax,%fs
- movw %ax,%gs
- movw %ax,%ss
+ xor ax, ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
/* Get the return address off the stack */
- popw (code32ret)
+ pop word ptr ds:[code32ret]
/* Save 16-bit stack pointer */
- movw %sp,stack16
+ mov word ptr ds:[stack16], sp
/* Load the GDT */
lgdt gdtptr
@@ -107,28 +109,28 @@ EXTERN(switch_to_prot)
lidt i386idtptr
/* Enable Protected Mode */
- mov %cr0,%eax
- orl $CR0_PE_SET,%eax
- mov %eax,%cr0
+ mov eax, cr0
+ or eax, CR0_PE_SET
+ mov cr0, eax
/* Clear prefetch queue & correct CS */
- ljmp $PMODE_CS, $inpmode
+ //ljmp PMODE_CS, inpmode
+ jmp far ptr PMODE_CS:inpmode
-
- .code32
+.code32
inpmode:
/* Setup segment selectors */
- movw $PMODE_DS,%ax
- movw %ax,%ds
- movw %ax,%es
- movw %ax,%fs
- movw %ax,%gs
- movw %ax,%ss
- movl stack32,%esp
+ mov ax, PMODE_DS
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ mov esp, dword ptr [stack32]
/* Put the return address back onto the stack */
- pushl (code32ret)
+ push dword ptr [code32ret]
/* Now return in p-mode! */
ret
@@ -139,7 +141,7 @@ inpmode:
*/
EXTERN(switch_to_real)
- .code32
+.code32
/* We don't know what values are currently */
/* in the segment registers. So we are */
@@ -147,48 +149,49 @@ EXTERN(switch_to_real)
/* Of course CS has to already be valid. */
/* We are currently in protected-mode so we */
/* need protected-mode segment values. */
- movw $PMODE_DS,%ax
- movw %ax,%ds
- movw %ax,%es
- movw %ax,%fs
- movw %ax,%gs
- movw %ax,%ss
+ mov ax, PMODE_DS
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
/* Get the return address off the stack */
- popl (code16ret)
+ pop dword ptr [code16ret]
/* Save 32-bit stack pointer */
- movl %esp,stack32
+ mov dword ptr [stack32], esp
/* jmp to 16-bit segment to set the limit correctly */
- ljmp $RMODE_CS, $switch_to_real16
+ ljmp RMODE_CS, switch_to_real16
switch_to_real16:
- .code16
+.code16
/* Restore segment registers to correct limit */
- movw $RMODE_DS,%ax
- movw %ax,%ds
- movw %ax,%es
- movw %ax,%fs
- movw %ax,%gs
- movw %ax,%ss
+ mov ax, RMODE_DS
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
/* Disable Protected Mode */
- mov %cr0,%eax
- andl $CR0_PE_CLR,%eax
- mov %eax,%cr0
+ mov eax, cr0
+ and eax, CR0_PE_CLR
+ mov cr0, eax
/* Clear prefetch queue & correct CS */
- ljmp $0, $inrmode
+ //ljmp $0, $inrmode
+ jmp far ptr 0:inrmode
inrmode:
- movw %cs,%ax
- movw %ax,%ds
- movw %ax,%es
- movw %ax,%fs
- movw %ax,%gs
- movw %ax,%ss
+ mov ax, cs
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
/* Clear out the high 16-bits of ESP */
/* This is needed because I have one */
@@ -196,12 +199,12 @@ inrmode:
/* anything other than 0x0000 is in the high */
/* 16-bits of ESP. Even though real-mode */
/* code should only use SP and not ESP. */
- xorl %esp,%esp
+ xor esp, esp
- movw stack16,%sp
+ mov sp, word ptr ds:[stack16]
/* Put the return address back onto the stack */
- pushw (code16ret)
+ push word ptr ds:[code16ret]
/* Load IDTR with real mode value */
lidt rmode_idtptr
@@ -215,14 +218,14 @@ inrmode:
/*
* Needed for enabling the a20 address line
*/
- .code16
+.code16
empty_8042:
.word 0x00eb,0x00eb // jmp $+2, jmp $+2
- inb $0x64,%al
- cmp $0xff, %al // legacy-free machine without keyboard
- jz empty_8042_ret // controllers on Intel Macs read back 0xFF
- testb $0x02,%al
- jnz empty_8042
+ in al, HEX(64)
+ cmp al, HEX(ff) // legacy-free machine without keyboard
+ jz empty_8042_ret // controllers on Intel Macs read back 0xFF
+ test al, 2
+ jnz empty_8042
empty_8042_ret:
ret
@@ -230,24 +233,24 @@ empty_8042_ret:
* Enable the A20 address line (to allow access to over 1mb)
*/
EXTERN(_EnableA20)
+.code32
+
+ pusha
+
+ call switch_to_real
+.code16
+
+ call empty_8042
+ mov al, HEX(D1) // command write
+ out HEX(64), al
+ call empty_8042
+ mov al, HEX(DF) // A20 on
+ out HEX(60), al
+ call empty_8042
+ call switch_to_prot
.code32
- pushal
-
- call switch_to_real
- .code16
-
- call empty_8042
- movb $0xD1,%al // command write
- outb %al,$0x64
- call empty_8042
- mov $0xDF,%al // A20 on
- out %al,$0x60
- call empty_8042
- call switch_to_prot
- .code32
-
- popal
+ popa
ret
@@ -255,24 +258,24 @@ EXTERN(_EnableA20)
* Disable the A20 address line
*/
EXTERN(_DisableA20)
- .code32
+.code32
- pushal
+ pusha
- call switch_to_real
+ call switch_to_real
.code16
call empty_8042
- movb $0xD1,%al // command write
- outb %al,$0x64
- call empty_8042
- mov $0xDD,%al // A20 off
- out %al,$0x60
+ mov al, HEX(D1) // command write
+ out HEX(64), al
+ call empty_8042
+ mov al, HEX(DD) // A20 off
+ out HEX(60), al
call empty_8042
call switch_to_prot
.code32
- popal
+ popa
ret
@@ -294,11 +297,11 @@ EXTERN(_DisableA20)
* above 1MB. So we let Grub load us there and then relocate
* ourself to 0x8000
*/
-#define FREELDR_BASE 0x8000
-#define INITIAL_BASE 0x200000
+#define FREELDR_BASE HEX(8000)
+#define INITIAL_BASE HEX(200000)
/* Align 32 bits boundary */
- .align 4
+.align 4
/* Multiboot header */
MultibootHeader:
@@ -330,44 +333,45 @@ MultibootEntry:
* our own */
lgdt gdtptrhigh + INITIAL_BASE - FREELDR_BASE
/* Reload segment selectors */
- ljmp $PMODE_CS, $(mb1 + INITIAL_BASE - FREELDR_BASE)
+ //ljmp $PMODE_CS, $(mb1 + INITIAL_BASE - FREELDR_BASE)
+ jmp far ptr PMODE_CS: (mb1 + INITIAL_BASE - FREELDR_BASE)
mb1:
- movw $PMODE_DS,%dx
- movw %dx,%ds
- movw %dx,%es
+ mov dx, PMODE_DS
+ mov ds, dx
+ mov es, dx
/* Check for valid multiboot signature */
- cmpl $MULTIBOOT_BOOTLOADER_MAGIC,%eax
- jne mbfail
+ cmp eax, MULTIBOOT_BOOTLOADER_MAGIC
+ jne mbfail
/* Store multiboot info in a safe place */
- movl %ebx,%esi
- movl $(mb_info + INITIAL_BASE - FREELDR_BASE),%edi
- movl $MB_INFO_SIZE,%ecx
+ mov esi, ebx
+ mov edi, offset mb_info + INITIAL_BASE - FREELDR_BASE
+ mov ecx, MB_INFO_SIZE
rep movsb
/* Save commandline */
- movl MB_INFO_FLAGS_OFFSET(%ebx),%edx
- testl $MB_INFO_FLAG_COMMAND_LINE,MB_INFO_FLAGS_OFFSET(%ebx)
- jz mb3
- movl MB_INFO_COMMAND_LINE_OFFSET(%ebx),%esi
- movl $(cmdline + INITIAL_BASE - FREELDR_BASE),%edi
- movl $CMDLINE_SIZE,%ecx
+ mov edx, [ebx + MB_INFO_FLAGS_OFFSET]
+ test dword ptr [ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE
+ jz mb3
+ mov esi, [ebx + MB_INFO_COMMAND_LINE_OFFSET]
+ mov edi, offset cmdline + INITIAL_BASE - FREELDR_BASE
+ mov ecx, CMDLINE_SIZE
mb2: lodsb
stosb
- testb %al,%al
- jz mb3
- dec %ecx
- jnz mb2
+ test al, al
+ jz mb3
+ dec ecx
+ jnz mb2
mb3:
/* Copy to low mem */
- movl $INITIAL_BASE,%esi
- movl $FREELDR_BASE,%edi
- movl $(__bss_end__ - FREELDR_BASE),%ecx
- addl $3,%ecx
- shrl $2,%ecx
- rep movsl
+ mov esi, INITIAL_BASE
+ mov edi, FREELDR_BASE
+ mov ecx, (offset __bss_end__ - FREELDR_BASE)
+ add ecx, 3
+ shr ecx, 2
+ rep movsd
/* Load the GDT and IDT */
lgdt gdtptr
@@ -375,47 +379,49 @@ mb3:
/* Clear prefetch queue & correct CS,
* jump to low mem */
- ljmp $PMODE_CS, $mb4
+ //ljmp $PMODE_CS, $mb4
+ jmp far ptr PMODE_CS:mb4
mb4:
/* Reload segment selectors */
- movw $PMODE_DS,%dx
- movw %dx,%ds
- movw %dx,%es
- movw %dx,%fs
- movw %dx,%gs
- movw %dx,%ss
- movl $STACK32ADDR,%esp
+ mov dx, PMODE_DS
+ mov ds, dx
+ mov es, dx
+ mov fs, dx
+ mov gs, dx
+ mov ss, dx
+ mov esp, STACK32ADDR
- movl $mb_info,%ebx
+ mov ebx, offset mb_info
/* See if the boot device was passed in */
- movl MB_INFO_FLAGS_OFFSET(%ebx),%edx
- testl $MB_INFO_FLAG_BOOT_DEVICE,%edx
- jz mb5
+ mov edx, [ebx + MB_INFO_FLAGS_OFFSET]
+ test edx, MB_INFO_FLAG_BOOT_DEVICE
+ jz mb5
/* Retrieve boot device info */
- movl MB_INFO_BOOT_DEVICE_OFFSET(%ebx),%eax
- shrl $16,%eax
- incb %al
- movb %al,_BootPartition
- movb %ah,_BootDrive
- jmp mb6
+ mov eax, [ebx + MB_INFO_BOOT_DEVICE_OFFSET]
+ shr eax, 16
+ inc al
+ mov byte ptr _BootPartition, al
+ mov byte ptr _BootDrive, ah
+ jmp mb6
mb5: /* No boot device known, assume first partition of first harddisk */
- movb $0x80,_BootDrive
- movb $1,_BootPartition
+ mov byte ptr _BootDrive, HEX(80)
+ mov byte ptr _BootPartition, 1
mb6:
/* Check for command line */
- mov $cmdline,%eax
- testl $MB_INFO_FLAG_COMMAND_LINE,MB_INFO_FLAGS_OFFSET(%ebx)
- jnz mb7
- xorl %eax,%eax
+ mov eax, offset cmdline
+ test dword ptr [ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE
+ jnz mb7
+ xor eax, eax
mb7:
/* GO! */
- pushl %eax
+ push eax
call _BootMain
-mbfail: call switch_to_real
+mbfail:
+ call switch_to_real
.code16
- int $0x19
+ int 0x19
mbstop: jmp mbstop /* We should never get here */
.code32
@@ -437,52 +443,52 @@ code32ret:
.long 0
- .p2align 2 /* force 4-byte alignment */
+ .align 4 /* force 4-byte alignment */
gdt:
/* NULL Descriptor */
- .word 0x0000
- .word 0x0000
- .word 0x0000
- .word 0x0000
+ .word HEX(0000)
+ .word HEX(0000)
+ .word HEX(0000)
+ .word HEX(0000)
/* 32-bit flat CS */
- .word 0xFFFF
- .word 0x0000
- .word 0x9A00
- .word 0x00CF
+ .word HEX(FFFF)
+ .word HEX(0000)
+ .word HEX(9A00)
+ .word HEX(00CF)
/* 32-bit flat DS */
- .word 0xFFFF
- .word 0x0000
- .word 0x9200
- .word 0x00CF
+ .word HEX(FFFF)
+ .word HEX(0000)
+ .word HEX(9200)
+ .word HEX(00CF)
/* 16-bit real mode CS */
- .word 0xFFFF
- .word 0x0000
- .word 0x9E00
- .word 0x0000
+ .word HEX(FFFF)
+ .word HEX(0000)
+ .word HEX(9E00)
+ .word HEX(0000)
/* 16-bit real mode DS */
- .word 0xFFFF
- .word 0x0000
- .word 0x9200
- .word 0x0000
+ .word HEX(FFFF)
+ .word HEX(0000)
+ .word HEX(9200)
+ .word HEX(0000)
/* GDT table pointer */
gdtptr:
- .word 0x27 /* Limit */
- .long gdt /* Base Address */
+ .word HEX(27) /* Limit */
+ .long gdt /* Base Address */
/* Initial GDT table pointer for multiboot */
gdtptrhigh:
- .word 0x27 /* Limit */
- .long gdt + INITIAL_BASE - FREELDR_BASE /* Base Address */
+ .word HEX(27) /* Limit */
+ .long gdt + INITIAL_BASE - FREELDR_BASE /* Base Address */
/* Real-mode IDT pointer */
rmode_idtptr:
- .word 0x3ff /* Limit */
- .long 0 /* Base Address */
+ .word HEX(3ff) /* Limit */
+ .long 0 /* Base Address */
mb_info:
.fill MB_INFO_SIZE, 1, 0
diff --git a/boot/freeldr/freeldr/arch/i386/i386bug.c b/boot/freeldr/freeldr/arch/i386/i386bug.c
new file mode 100644
index 00000000000..989ce6ec9e1
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/i386/i386bug.c
@@ -0,0 +1,135 @@
+
+#include
+
+#define NDEBUG
+#include
+
+typedef struct _FRAME
+{
+ struct _FRAME *Next;
+ void *Address;
+} FRAME;
+
+char *i386ExceptionDescriptionText[] =
+{
+ "Exception 00: DIVIDE BY ZERO\n\n",
+ "Exception 01: DEBUG EXCEPTION\n\n",
+ "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n",
+ "Exception 03: BREAKPOINT (INT 3)\n\n",
+ "Exception 04: OVERFLOW\n\n",
+ "Exception 05: BOUND EXCEPTION\n\n",
+ "Exception 06: INVALID OPCODE\n\n",
+ "Exception 07: FPU NOT AVAILABLE\n\n",
+ "Exception 08: DOUBLE FAULT\n\n",
+ "Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n",
+ "Exception 0A: INVALID TSS\n\n",
+ "Exception 0B: SEGMENT NOT PRESENT\n\n",
+ "Exception 0C: STACK EXCEPTION\n\n",
+ "Exception 0D: GENERAL PROTECTION FAULT\n\n",
+ "Exception 0E: PAGE FAULT\n\n",
+ "Exception 0F: Reserved\n\n",
+ "Exception 10: COPROCESSOR ERROR\n\n",
+ "Exception 11: ALIGNMENT CHECK\n\n",
+ "Exception 12: MACHINE CHECK\n\n"
+};
+
+#define SCREEN_ATTR 0x1f
+void
+i386PrintChar(char chr, ULONG x, ULONG y)
+{
+ MachVideoPutChar(chr, SCREEN_ATTR, x, y);
+}
+
+/* Used to store the current X and Y position on the screen */
+ULONG i386_ScreenPosX = 0;
+ULONG i386_ScreenPosY = 0;
+
+void
+i386PrintText(char *pszText)
+{
+ char chr;
+ while (1)
+ {
+ chr = *pszText++;
+
+ if (chr == 0) break;
+ if (chr == '\n')
+ {
+ i386_ScreenPosY++;
+ i386_ScreenPosX = 0;
+ continue;
+ }
+
+ MachVideoPutChar(chr, SCREEN_ATTR, i386_ScreenPosX, i386_ScreenPosY);
+ i386_ScreenPosX++;
+ }
+}
+
+void
+PrintText(const char *format, ...)
+{
+ va_list argptr;
+ char buffer[256];
+
+ va_start(argptr, format);
+ _vsnprintf(buffer, sizeof(buffer), format, argptr);
+ buffer[sizeof(buffer) - 1] = 0;
+ va_end(argptr);
+ i386PrintText(buffer);
+}
+
+void
+i386PrintFrames(PKTRAP_FRAME TrapFrame)
+{
+ FRAME *Frame;
+
+ PrintText("Frames:\n");
+
+ for (Frame = (FRAME*)TrapFrame->Ebp;
+ Frame != 0 && (ULONG_PTR)Frame < STACK32ADDR;
+ Frame = Frame->Next)
+ {
+ PrintText("%p ", Frame->Address);
+ }
+}
+
+void
+NTAPI
+i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGISTERS Special)
+{
+ MachVideoClearScreen(SCREEN_ATTR);
+ i386_ScreenPosX = 0;
+ i386_ScreenPosY = 0;
+
+ PrintText("An error occured in FreeLoader\n"
+ VERSION"\n"
+ "Report this error to the ReactOS Development mailing list \n\n"
+ "%s\n", i386ExceptionDescriptionText[TrapIndex]);
+
+ PrintText("EAX: %.8lx ESP: %.8lx CR0: %.8lx DR0: %.8lx\n",
+ TrapFrame->Eax, TrapFrame->HardwareEsp, Special->Cr0, TrapFrame->Dr0);
+ PrintText("EBX: %.8lx EBP: %.8lx CR1: ???????? DR1: %.8lx\n",
+ TrapFrame->Ebx, TrapFrame->Ebp, TrapFrame->Dr1);
+ PrintText("ECX: %.8lx ESI: %.8lx CR2: %.8lx DR2: %.8lx\n",
+ TrapFrame->Ecx, TrapFrame->Esi, Special->Cr2, TrapFrame->Dr2);
+ PrintText("EDX: %.8lx EDI: %.8lx CR3: %.8lx DR3: %.8lx\n",
+ TrapFrame->Edx, TrapFrame->Edi, Special->Cr3, TrapFrame->Dr3);
+ PrintText(" DR6: %.8lx\n",
+ TrapFrame->Dr6);
+ PrintText(" DR7: %.8lx\n\n",
+ TrapFrame->Dr7);
+ PrintText("CS: %.4lx EIP: %.8lx\n",
+ TrapFrame->SegCs, TrapFrame->Eip);
+ PrintText("DS: %.4lx ERROR CODE: %.8lx\n",
+ TrapFrame->SegDs, TrapFrame->Eip);
+ PrintText("ES: %.4lx EFLAGS: %.8lx\n",
+ TrapFrame->SegEs, TrapFrame->EFlags);
+ PrintText("FS: %.4lx GDTR Base: %.8lx Limit: %.4x\n",
+ TrapFrame->SegFs, Special->Gdtr.Base, Special->Gdtr.Limit);
+ PrintText("GS: %.4lx IDTR Base: %.8lx Limit: %.4x\n",
+ TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit);
+ PrintText("SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n",
+ TrapFrame->HardwareSegSs, Special->Ldtr, Special->Idtr.Limit);
+
+ i386PrintFrames(TrapFrame); // Display frames
+}
diff --git a/boot/freeldr/freeldr/arch/i386/i386trap.S b/boot/freeldr/freeldr/arch/i386/i386trap.S
index 833fcc37104..be5c7de3ce9 100644
--- a/boot/freeldr/freeldr/arch/i386/i386trap.S
+++ b/boot/freeldr/freeldr/arch/i386/i386trap.S
@@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+.intel_syntax noprefix
.text
.code16
@@ -27,244 +28,67 @@
#define SCREEN_ATTR 0x1f /* Bright white on blue background */
.macro SAVE_CPU_REGS
- movl %eax,i386_EAX
- movl %ebx,i386_EBX
- movl %ecx,i386_ECX
- movl %edx,i386_EDX
- movl %esp,i386_ESP
- movl %ebp,i386_EBP
- movl %esi,i386_ESI
- movl %edi,i386_EDI
- movw %ds,%ax
- movw %ax,i386_DS
- movw %es,%ax
- movw %ax,i386_ES
- movw %fs,%ax
- movw %ax,i386_FS
- movw %gs,%ax
- movw %ax,i386_GS
- movw %ss,%ax
- movw %ax,i386_SS
- popl %eax
- movl %eax,i386_EIP
- popl %eax
- movw %ax,i386_CS
- popl %eax
- movl %eax,i386_EFLAGS
- movl %cr0,%eax
- movl %eax,i386_CR0
- //movl %cr1,%eax
- //movl %eax,i386_CR1
- movl %cr2,%eax
- movl %eax,i386_CR2
- movl %cr3,%eax
- movl %eax,i386_CR3
- movl %dr0,%eax
- movl %eax,i386_DR0
- movl %dr1,%eax
- movl %eax,i386_DR1
- movl %dr2,%eax
- movl %eax,i386_DR2
- movl %dr3,%eax
- movl %eax,i386_DR3
- movl %dr6,%eax
- movl %eax,i386_DR6
- movl %dr7,%eax
- movl %eax,i386_DR7
- sgdt i386_GDTR
- sidt i386_IDTR
- sldt i386_LDTR
- str i386_TR
+ /* push the rest of the KTRAP_FRAME */
+ push ebp
+ push ebx
+ push esi
+ push edi
+ push fs
+ push 0 // ExceptionList
+ push 0 // PreviousPreviousMode
+ push eax
+ push ecx
+ push edx
+ push ds
+ push es
+ push gs
+ mov eax, dr7
+ push eax
+ mov eax, dr6
+ push eax
+ mov eax, dr3
+ push eax
+ mov eax, dr2
+ push eax
+ mov eax, dr1
+ push eax
+ mov eax, dr0
+ push eax
+ sub esp, 6 * 4
+
+ /* push KSPECIAL_REGISTERS */
+ /* Gdtr, Idtr, Tr, Ldtr, Reserved */
+ sub esp, 44
+ sgdt [esp]
+ sidt [esp + 8]
+ str [esp + 16]
+ sldt [esp + 18]
+ mov eax, dr7;
+ push eax
+ mov eax, dr6;
+ push eax
+ mov eax, dr3;
+ push eax
+ mov eax, dr2;
+ push eax
+ mov eax, dr1;
+ push eax
+ mov eax, dr0;
+ push eax
+ mov eax, cr4;
+ push eax
+ mov eax, cr3;
+ push eax
+ mov eax, cr2;
+ push eax
+ mov eax, cr0;
+ push eax
.endm
-
-
-i386ExceptionHandlerText:
- .ascii "An error occured in FreeLoader\n"
- .ascii VERSION
- .ascii "\n"
- .asciz "Report this error to the ReactOS Development mailing list \n\n"
-
-i386DivideByZeroText:
- .asciz "Exception 00: DIVIDE BY ZERO\n\n"
-i386DebugExceptionText:
- .asciz "Exception 01: DEBUG EXCEPTION\n\n"
-i386NMIExceptionText:
- .asciz "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n"
-i386BreakpointText:
- .asciz "Exception 03: BREAKPOINT (INT 3)\n\n"
-i386OverflowText:
- .asciz "Exception 04: OVERFLOW\n\n"
-i386BoundExceptionText:
- .asciz "Exception 05: BOUND EXCEPTION\n\n"
-i386InvalidOpcodeText:
- .asciz "Exception 06: INVALID OPCODE\n\n"
-i386FPUNotAvailableText:
- .asciz "Exception 07: FPU NOT AVAILABLE\n\n"
-i386DoubleFaultText:
- .asciz "Exception 08: DOUBLE FAULT\n\n"
-i386CoprocessorSegmentText:
- .asciz "Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n"
-i386InvalidTSSText:
- .asciz "Exception 0A: INVALID TSS\n\n"
-i386SegmentNotPresentText:
- .asciz "Exception 0B: SEGMENT NOT PRESENT\n\n"
-i386StackExceptionText:
- .asciz "Exception 0C: STACK EXCEPTION\n\n"
-i386GeneralProtectionFaultText:
- .asciz "Exception 0D: GENERAL PROTECTION FAULT\n\n"
-i386PageFaultText:
- .asciz "Exception 0E: PAGE FAULT\n\n"
-i386CoprocessorErrorText:
- .asciz "Exception 10: COPROCESSOR ERROR\n\n"
-i386AlignmentCheckText:
- .asciz "Exception 11: ALIGNMENT CHECK\n\n"
-i386MachineCheckText:
- .asciz "Exception 12: MACHINE CHECK\n\n"
-
-i386_EAX_Text:
- .asciz "EAX: "
-i386_EBX_Text:
- .asciz "EBX: "
-i386_ECX_Text:
- .asciz "ECX: "
-i386_EDX_Text:
- .asciz "EDX: "
-i386_ESP_Text:
- .asciz " ESP: "
-i386_EBP_Text:
- .asciz " EBP: "
-i386_ESI_Text:
- .asciz " ESI: "
-i386_EDI_Text:
- .asciz " EDI: "
-i386_CS_Text:
- .asciz "CS: "
-i386_DS_Text:
- .asciz "DS: "
-i386_ES_Text:
- .asciz "ES: "
-i386_FS_Text:
- .asciz "FS: "
-i386_GS_Text:
- .asciz "GS: "
-i386_SS_Text:
- .asciz "SS: "
-i386_EFLAGS_Text:
- .asciz " EFLAGS: "
-i386_EIP_Text:
- .asciz " EIP: "
-i386_ERROR_CODE_Text:
- .asciz " ERROR CODE: "
-i386_CR0_Text:
- .asciz " CR0: "
-i386_CR1_Text:
- .asciz " CR1: "
-i386_CR2_Text:
- .asciz " CR2: "
-i386_CR3_Text:
- .asciz " CR3: "
-i386_DR0_Text:
- .asciz " DR0: "
-i386_DR1_Text:
- .asciz " DR1: "
-i386_DR2_Text:
- .asciz " DR2: "
-i386_DR3_Text:
- .asciz " DR3: "
-i386_DR6_Text:
- .asciz " DR6: "
-i386_DR7_Text:
- .asciz " DR7: "
-i386_GDTR_Text:
- .asciz " GDTR Base: "
-i386_IDTR_Text:
- .asciz " IDTR Base: "
-i386_Limit_Text:
- .asciz " Limit: "
-i386_LDTR_Text:
- .asciz " LDTR: "
-i386_TR_Text:
- .asciz " TR: "
-
-i386FramesText:
- .asciz "Frames:\n"
-
/* Set by each exception handler to the address of the description text */
-i386ExceptionDescriptionText:
+i386ExceptionIndex:
.long 0
-/* Used to store the contents of all the registers when an exception occurs */
-i386_EAX:
- .long 0
-i386_EBX:
- .long 0
-i386_ECX:
- .long 0
-i386_EDX:
- .long 0
-i386_ESP:
- .long 0
-i386_EBP:
- .long 0
-i386_ESI:
- .long 0
-i386_EDI:
- .long 0
-i386_CS:
- .word 0
-i386_DS:
- .word 0
-i386_ES:
- .word 0
-i386_FS:
- .word 0
-i386_GS:
- .word 0
-i386_SS:
- .word 0
-i386_EFLAGS:
- .long 0
-i386_EIP:
- .long 0
-i386_ERROR_CODE:
- .long 0
-i386_CR0:
- .long 0
-i386_CR1:
- .long 0
-i386_CR2:
- .long 0
-i386_CR3:
- .long 0
-i386_DR0:
- .long 0
-i386_DR1:
- .long 0
-i386_DR2:
- .long 0
-i386_DR3:
- .long 0
-i386_DR6:
- .long 0
-i386_DR7:
- .long 0
-i386_GDTR:
- .word 0
- .long 0
-i386_IDTR:
- .word 0
- .long 0
-i386_LDTR:
- .word 0
-i386_TR:
- .word 0
-
-/* Used to store the current X and Y position on the screen */
-i386_ScreenPosX:
- .long 0
-i386_ScreenPosY:
- .long 0
/************************************************************************/
i386CommonExceptionHandler:
@@ -272,177 +96,11 @@ i386CommonExceptionHandler:
SAVE_CPU_REGS
- pushl $SCREEN_ATTR
- call _MachVideoClearScreen
- add $4,%esp
-
- movl $i386ExceptionHandlerText,%esi
- call i386PrintText
-
- movl i386ExceptionDescriptionText,%esi
- call i386PrintText
-
- movl $i386_EAX_Text,%esi
- call i386PrintText
- movl i386_EAX,%eax
- call i386PrintHexDword // Display EAX
- movl $i386_ESP_Text,%esi
- call i386PrintText
- movl i386_ESP,%eax
- call i386PrintHexDword // Display ESP
- movl $i386_CR0_Text,%esi
- call i386PrintText
- movl i386_CR0,%eax
- call i386PrintHexDword // Display CR0
- movl $i386_DR0_Text,%esi
- call i386PrintText
- movl i386_DR0,%eax
- call i386PrintHexDword // Display DR0
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- movl $i386_EBX_Text,%esi
- call i386PrintText
- movl i386_EBX,%eax
- call i386PrintHexDword // Display EBX
- movl $i386_EBP_Text,%esi
- call i386PrintText
- movl i386_EBP,%eax
- call i386PrintHexDword // Display EBP
- movl $i386_CR1_Text,%esi
- call i386PrintText
- movl i386_CR1,%eax
- call i386PrintHexDword // Display CR1
- movl $i386_DR1_Text,%esi
- call i386PrintText
- movl i386_DR1,%eax
- call i386PrintHexDword // Display DR1
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- movl $i386_ECX_Text,%esi
- call i386PrintText
- movl i386_ECX,%eax
- call i386PrintHexDword // Display ECX
- movl $i386_ESI_Text,%esi
- call i386PrintText
- movl i386_ESI,%eax
- call i386PrintHexDword // Display ESI
- movl $i386_CR2_Text,%esi
- call i386PrintText
- movl i386_CR2,%eax
- call i386PrintHexDword // Display CR2
- movl $i386_DR2_Text,%esi
- call i386PrintText
- movl i386_DR2,%eax
- call i386PrintHexDword // Display DR2
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- movl $i386_EDX_Text,%esi
- call i386PrintText
- movl i386_EDX,%eax
- call i386PrintHexDword // Display EDX
- movl $i386_EDI_Text,%esi
- call i386PrintText
- movl i386_EDI,%eax
- call i386PrintHexDword // Display EDI
- movl $i386_CR3_Text,%esi
- call i386PrintText
- movl i386_CR3,%eax
- call i386PrintHexDword // Display CR3
- movl $i386_DR3_Text,%esi
- call i386PrintText
- movl i386_DR3,%eax
- call i386PrintHexDword // Display DR3
- incl i386_ScreenPosY
- movl $55,i386_ScreenPosX
- movl $i386_DR6_Text,%esi
- call i386PrintText
- movl i386_DR6,%eax
- call i386PrintHexDword // Display DR6
- incl i386_ScreenPosY
- movl $55,i386_ScreenPosX
- movl $i386_DR7_Text,%esi
- call i386PrintText
- movl i386_DR7,%eax
- call i386PrintHexDword // Display DR7
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- incl i386_ScreenPosY
- movl $i386_CS_Text,%esi
- call i386PrintText
- movw i386_CS,%ax
- call i386PrintHexWord // Display CS
- movl $i386_EIP_Text,%esi
- call i386PrintText
- movl i386_EIP,%eax
- call i386PrintHexDword // Display EIP
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- movl $i386_DS_Text,%esi
- call i386PrintText
- movw i386_DS,%ax
- call i386PrintHexWord // Display DS
- movl $i386_ERROR_CODE_Text,%esi
- call i386PrintText
- movl i386_ERROR_CODE,%eax
- call i386PrintHexDword // Display ERROR CODE
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- movl $i386_ES_Text,%esi
- call i386PrintText
- movw i386_ES,%ax
- call i386PrintHexWord // Display ES
- movl $i386_EFLAGS_Text,%esi
- call i386PrintText
- movl i386_EFLAGS,%eax
- call i386PrintHexDword // Display EFLAGS
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- movl $i386_FS_Text,%esi
- call i386PrintText
- movw i386_FS,%ax
- call i386PrintHexWord // Display FS
- movl $i386_GDTR_Text,%esi
- call i386PrintText
- movl i386_GDTR+2,%eax
- call i386PrintHexDword // Display GDTR Base
- movl $i386_Limit_Text,%esi
- call i386PrintText
- movw i386_GDTR,%ax
- call i386PrintHexWord // Display GDTR Limit
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- movl $i386_GS_Text,%esi
- call i386PrintText
- movw i386_GS,%ax
- call i386PrintHexWord // Display GS
- movl $i386_IDTR_Text,%esi
- call i386PrintText
- movl i386_IDTR+2,%eax
- call i386PrintHexDword // Display IDTR Base
- movl $i386_Limit_Text,%esi
- call i386PrintText
- movw i386_IDTR,%ax
- call i386PrintHexWord // Display IDTR Limit
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- movl $i386_SS_Text,%esi
- call i386PrintText
- movw i386_SS,%ax
- call i386PrintHexWord // Display SS
- movl $i386_LDTR_Text,%esi
- call i386PrintText
- movw i386_LDTR,%ax
- call i386PrintHexWord // Display LDTR
- movl $i386_TR_Text,%esi
- call i386PrintText
- movw i386_TR,%ax
- call i386PrintHexWord // Display TR
- movl $0,i386_ScreenPosX
- incl i386_ScreenPosY
- incl i386_ScreenPosY
- call i386PrintFrames // Display frames
- incl i386_ScreenPosY
- incl i386_ScreenPosY
+ lea eax, [esp + (21 * 4)] // KTRAP_FRAME
+ push esp // KSPECIAL_REGISTERS
+ push eax
+ push i386ExceptionIndex
+ call _i386PrintExceptionText@12
cli
i386ExceptionHandlerHang:
@@ -451,492 +109,69 @@ i386ExceptionHandlerHang:
iret
-i386PrintFrames:
- movl $0,i386_ScreenPosX
- movl $i386FramesText,%esi
- call i386PrintText
+.macro TRAP_STUB function, index
+ EXTERN(\function)
+ push 0 // Fake error code
+ mov dword ptr i386ExceptionIndex, \index
+ jmp i386CommonExceptionHandler
+.endm
- movl i386_EBP,%edi
-printnextframe:
- test %edi,%edi
- je nomoreframes
- movl $STACK32ADDR,%eax
- cmpl %edi,%eax
- jbe nomoreframes
- movl 4(%edi),%eax
- pushl %edi
- call i386PrintHexDword // Display frame
- popl %edi
- incl i386_ScreenPosX
- incl i386_ScreenPosX
- movl 0(%edi),%edi
- jmp printnextframe
-nomoreframes:
- ret
+.macro TRAP_STUB2 function, index
+ EXTERN(\function)
+ mov dword ptr i386ExceptionIndex, \index
+ jmp i386CommonExceptionHandler
+.endm
/************************************************************************/
-/* AL = Char to display */
-/************************************************************************/
-i386PrintChar:
- .code32
-
- pushl i386_ScreenPosY
- pushl i386_ScreenPosX
- pushl $SCREEN_ATTR
- andl $0xff,%eax
- pushl %eax
- call _MachVideoPutChar
- addl $16,%esp
-
- ret
-
-/************************************************************************/
-/* ESI = Address of text to display */
-/************************************************************************/
-i386PrintText:
- .code32
-
-i386PrintTextLoop:
- lodsb
-
- // Check for end of string char
- cmp $0,%al
- je i386PrintTextDone
-
- // Check for newline char
- cmp $0x0a,%al
- jne i386PrintTextLoop2
- incl i386_ScreenPosY
- movl $0,i386_ScreenPosX
- jmp i386PrintTextLoop
-
-i386PrintTextLoop2:
- call i386PrintChar
- incl i386_ScreenPosX
-
- jmp i386PrintTextLoop
-
-i386PrintTextDone:
-
- ret
-
-/************************************************************************/
-/* Prints the value in EAX on the screen in hex */
-/************************************************************************/
-i386PrintHexDword:
- .code32
-
- call i386PrintHex1
-
-i386PrintHex1:
- call i386PrintHex2
-i386PrintHex2:
- call i386PrintHex3
-i386PrintHex3:
- movb $4,%cl
- rol %cl,%eax
- push %eax
- andb $0x0f,%al
- movl $i386PrintHexTable,%ebx
- xlat /*$i386PrintHexTable*/
- call i386PrintChar
- incl i386_ScreenPosX
- pop %eax
-
- ret
-
-i386PrintHexTable:
- .ascii "0123456789ABCDEF"
-
-/************************************************************************/
-/* Prints the value in AX on the screen in hex */
-/************************************************************************/
-i386PrintHexWord:
- .code32
-
- call i386PrintHexWord1
-i386PrintHexWord1:
- call i386PrintHexWord2
-i386PrintHexWord2:
- movb $4,%cl
- rol %cl,%ax
- push %eax
- andb $0x0f,%al
- movl $i386PrintHexTable,%ebx
- xlat /*$i386PrintHexTable*/
- call i386PrintChar
- incl i386_ScreenPosX
- pop %eax
-
- ret
-
-/************************************************************************/
-/* Prints the value in AL on the screen in hex */
-/************************************************************************/
-i386PrintHexByte:
- .code32
-
- call i386PrintHexByte1
-i386PrintHexByte1:
- movb $4,%cl
- rol %cl,%al
- push %eax
- andb $0x0f,%al
- movl $i386PrintHexTable,%ebx
- xlat /*$i386PrintHexTable*/
- call i386PrintChar
- incl i386_ScreenPosX
- pop %eax
-
- ret
-
-/************************************************************************/
-EXTERN(i386DivideByZero)
- .code32
-
- movl $i386DivideByZeroText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386DebugException)
- .code32
-
- movl $i386DebugExceptionText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386NMIException)
- .code32
-
- movl $i386NMIExceptionText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386Breakpoint)
- .code32
-
- movl $i386BreakpointText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386Overflow)
- .code32
-
- movl $i386OverflowText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386BoundException)
- .code32
-
- movl $i386BoundExceptionText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386InvalidOpcode)
- .code32
-
- movl $i386InvalidOpcodeText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386FPUNotAvailable)
- .code32
-
- movl $i386FPUNotAvailableText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386DoubleFault)
- .code32
-
- popl %eax
- movl %eax,i386_ERROR_CODE
-
- movl $i386DoubleFaultText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386CoprocessorSegment)
- .code32
-
- movl $i386CoprocessorSegmentText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386InvalidTSS)
- .code32
-
- popl %eax
- movl %eax,i386_ERROR_CODE
-
- movl $i386InvalidTSSText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386SegmentNotPresent)
- .code32
-
- popl %eax
- movl %eax,i386_ERROR_CODE
-
- movl $i386SegmentNotPresentText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386StackException)
- .code32
-
- popl %eax
- movl %eax,i386_ERROR_CODE
-
- movl $i386StackExceptionText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386GeneralProtectionFault)
- .code32
-
- popl %eax
- movl %eax,i386_ERROR_CODE
-
- movl $i386GeneralProtectionFaultText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386PageFault)
- .code32
-
- popl %eax
- movl %eax,i386_ERROR_CODE
-
- movl $i386PageFaultText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386CoprocessorError)
- .code32
-
- movl $i386CoprocessorErrorText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386AlignmentCheck)
- .code32
-
- movl $i386AlignmentCheckText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
-
-/************************************************************************/
-EXTERN(i386MachineCheck)
- .code32
-
- movl $i386MachineCheckText,i386ExceptionDescriptionText
- jmp i386CommonExceptionHandler
+TRAP_STUB i386DivideByZero, 0
+TRAP_STUB i386DebugException, 1
+TRAP_STUB i386NMIException, 2
+TRAP_STUB i386Breakpoint, 3
+TRAP_STUB i386Overflow, 4
+TRAP_STUB i386BoundException, 5
+TRAP_STUB i386InvalidOpcode, 6
+TRAP_STUB i386FPUNotAvailable, 7
+TRAP_STUB2 i386DoubleFault, 8
+TRAP_STUB i386CoprocessorSegment, 9
+TRAP_STUB2 i386InvalidTSS, 10
+TRAP_STUB2 i386SegmentNotPresent, 11
+TRAP_STUB2 i386StackException, 12
+TRAP_STUB2 i386GeneralProtectionFault, 13
+TRAP_STUB2 i386PageFault, 14
+// 15 is reserved
+TRAP_STUB i386CoprocessorError, 16
+TRAP_STUB i386AlignmentCheck, 17
+TRAP_STUB i386MachineCheck, 18
+TRAP_STUB i386SimdFloatError, 19
/************************************************************************
* DEBUGGING SUPPORT FUNCTIONS
************************************************************************/
-EXTERN(_INSTRUCTION_BREAKPOINT1)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr0
- movl %dr7,%eax
- andl $0xfff0ffff,%eax
- orl $0x00000303,%eax
- movl %eax,%dr7
-
- popl %eax
+.macro BREAKPOINT_TEPLATE functionname, mask1, mask2
+ EXTERN(\functionname)
+ push eax
+ mov eax, [esp + 8]
+ mov dr3, eax
+ mov eax, dr7
+ and eax, \mask1
+ or eax, \mask2
+ mov dr7, eax
+ pop eax
ret
+.endm
+
+BREAKPOINT_TEPLATE _INSTRUCTION_BREAKPOINT1, 0xfff0ffff, 0x00000303
+BREAKPOINT_TEPLATE _MEMORY_READWRITE_BREAKPOINT1, 0xfff0ffff, 0x00030303
+BREAKPOINT_TEPLATE _MEMORY_WRITE_BREAKPOINT1, 0xfff0ffff, 0x00010303
+BREAKPOINT_TEPLATE _INSTRUCTION_BREAKPOINT2, 0xff0fffff, 0x0000030c
+BREAKPOINT_TEPLATE _MEMORY_READWRITE_BREAKPOINT2, 0xff0fffff, 0x0030030c
+BREAKPOINT_TEPLATE _MEMORY_WRITE_BREAKPOINT2, 0xff0fffff, 0x0010030c
+BREAKPOINT_TEPLATE _INSTRUCTION_BREAKPOINT3, 0xf0ffffff, 0x00000330
+BREAKPOINT_TEPLATE _MEMORY_READWRITE_BREAKPOINT3, 0xf0ffffff, 0x03000330
+BREAKPOINT_TEPLATE _MEMORY_WRITE_BREAKPOINT3, 0xf0ffffff, 0x01000330
+BREAKPOINT_TEPLATE _INSTRUCTION_BREAKPOINT4, 0x0fffffff, 0x000003c0
+BREAKPOINT_TEPLATE _MEMORY_READWRITE_BREAKPOINT4, 0x0fffffff, 0x300003c0
+BREAKPOINT_TEPLATE _MEMORY_WRITE_BREAKPOINT4, 0x0fffffff, 0x100003c0
-EXTERN(_MEMORY_READWRITE_BREAKPOINT1)
- .code32
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr0
- movl %dr7,%eax
- andl $0xfff0ffff,%eax
- orl $0x00030303,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_MEMORY_WRITE_BREAKPOINT1)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr0
- movl %dr7,%eax
- andl $0xfff0ffff,%eax
- orl $0x00010303,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_INSTRUCTION_BREAKPOINT2)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr1
- movl %dr7,%eax
- andl $0xff0fffff,%eax
- orl $0x0000030c,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_MEMORY_READWRITE_BREAKPOINT2)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr1
- movl %dr7,%eax
- andl $0xff0fffff,%eax
- orl $0x0030030c,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_MEMORY_WRITE_BREAKPOINT2)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr1
- movl %dr7,%eax
- andl $0xff0fffff,%eax
- orl $0x0010030c,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_INSTRUCTION_BREAKPOINT3)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr2
- movl %dr7,%eax
- andl $0xf0ffffff,%eax
- orl $0x00000330,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_MEMORY_READWRITE_BREAKPOINT3)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr2
- movl %dr7,%eax
- andl $0xf0ffffff,%eax
- orl $0x03000330,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_MEMORY_WRITE_BREAKPOINT3)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr2
- movl %dr7,%eax
- andl $0xf0ffffff,%eax
- orl $0x01000330,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_INSTRUCTION_BREAKPOINT4)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr3
- movl %dr7,%eax
- andl $0x0fffffff,%eax
- orl $0x000003c0,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_MEMORY_READWRITE_BREAKPOINT4)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr3
- movl %dr7,%eax
- andl $0x0fffffff,%eax
- orl $0x300003c0,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
-
-EXTERN(_MEMORY_WRITE_BREAKPOINT4)
- .code32
-
- pushl %eax
-
- movl 8(%esp),%eax
-
- movl %eax,%dr3
- movl %dr7,%eax
- andl $0x0fffffff,%eax
- orl $0x100003c0,%eax
- movl %eax,%dr7
-
- popl %eax
-
- ret
diff --git a/boot/freeldr/freeldr/debug.c b/boot/freeldr/freeldr/debug.c
index 4ab90966192..95a5a4f1b71 100644
--- a/boot/freeldr/freeldr/debug.c
+++ b/boot/freeldr/freeldr/debug.c
@@ -66,6 +66,19 @@ ULONG BaudRate = 115200;
BOOLEAN DebugStartOfLine = TRUE;
+// We need to emulate these, because the original ones don't work in freeldr
+int __cdecl wctomb(char *mbchar, wchar_t wchar)
+{
+ *mbchar = wchar;
+ return 1;
+}
+
+int __cdecl mbtowc (wchar_t *wchar, const char *mbchar, size_t count)
+{
+ *wchar = *mbchar;
+ return 1;
+}
+
VOID DebugInit(VOID)
{
if (DebugPort & RS232)
diff --git a/boot/freeldr/freeldr/freeldr.rbuild b/boot/freeldr/freeldr/freeldr.rbuild
index e8f4e6e0855..7ca1a75e734 100644
--- a/boot/freeldr/freeldr/freeldr.rbuild
+++ b/boot/freeldr/freeldr/freeldr.rbuild
@@ -16,6 +16,22 @@
+
+
+ freeldr_$(ARCH).lnk
+
+ freeldr_startup
+ freeldr_base64k
+ freeldr_base
+ freeldr_arch
+ freeldr_main
+ rossym
+ cmlib
+ rtl
+ libcntpr
+
+
+
freeldr_$(ARCH).lnk
diff --git a/boot/freeldr/freeldr/freeldr_arch.rbuild b/boot/freeldr/freeldr/freeldr_arch.rbuild
index 6aa231c258a..6d965bf36db 100644
--- a/boot/freeldr/freeldr/freeldr_arch.rbuild
+++ b/boot/freeldr/freeldr/freeldr_arch.rbuild
@@ -21,6 +21,7 @@
hwacpi.c
hwapm.c
hwpci.c
+ i386bug.c
i386disk.c
i386rtl.c
i386vid.c
@@ -63,7 +64,6 @@
- boot.s
macharm.c
diff --git a/boot/freeldr/freeldr/freeldr_arm.lnk b/boot/freeldr/freeldr/freeldr_arm.lnk
new file mode 100644
index 00000000000..82feba18f04
--- /dev/null
+++ b/boot/freeldr/freeldr/freeldr_arm.lnk
@@ -0,0 +1,54 @@
+OUTPUT_FORMAT(pei-arm-wince-little)
+SECTIONS
+{
+ .text __image_base__ + __section_alignment__ :
+ {
+ __text_start__ = .;
+ *(.init)
+ *(.text)
+ *(SORT(.text$*))
+ *(.glue_7t)
+ *(.glue_7)
+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+ LONG (-1); *(.ctors); *(.ctor); LONG (0);
+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+ LONG (-1); *(.dtors); *(.dtor); LONG (0);
+ *(.fini)
+ /* ??? Why is .gcc_exc here? */
+ *(.gcc_exc)
+ __text_end__ = .;
+ *(.gcc_except_table)
+ }
+ init BLOCK(__section_alignment__) :
+ {
+ __init_start__ = . ;
+ *(init)
+ __init_end__ = . ;
+ }
+ .data BLOCK(__section_alignment__) :
+ {
+ __data_start__ = . ;
+ *(.data)
+ *(.data2)
+ *(SORT(.data$*))
+ __data_end__ = . ;
+ __bss_start__ = . ;
+ *(.bss)
+ *(COMMON)
+ __bss_end__ = . ;
+ }
+ .rdata BLOCK(__section_alignment__) :
+ {
+ *(.rdata)
+ *(SORT(.rdata$*))
+ *(.eh_frame)
+ }
+ /DISCARD/ :
+ {
+ [ .stab ]
+ [ .stabstr ]
+ *(.reloc)
+ }
+
+}
+
diff --git a/boot/freeldr/freeldr/freeldr_base.rbuild b/boot/freeldr/freeldr/freeldr_base.rbuild
index db584d44e22..0288290b45c 100644
--- a/boot/freeldr/freeldr/freeldr_base.rbuild
+++ b/boot/freeldr/freeldr/freeldr_base.rbuild
@@ -75,7 +75,9 @@
winldr.c
wlmemory.c
wlregistry.c
- headless.c
+
+ headless.c
+
freeldr.c
debug.c
diff --git a/boot/freeldr/freeldr/freeldr_startup.rbuild b/boot/freeldr/freeldr/freeldr_startup.rbuild
index 836ecf628dd..53fd6a9d9eb 100644
--- a/boot/freeldr/freeldr/freeldr_startup.rbuild
+++ b/boot/freeldr/freeldr/freeldr_startup.rbuild
@@ -16,5 +16,10 @@
arch.S
+
+
+ boot.s
+
+
diff --git a/boot/freeldr/freeldr/include/keycodes.h b/boot/freeldr/freeldr/include/keycodes.h
index 5d781f92389..5435233e8f3 100644
--- a/boot/freeldr/freeldr/include/keycodes.h
+++ b/boot/freeldr/freeldr/include/keycodes.h
@@ -24,11 +24,14 @@
#define KEY_ENTER 0x0D
#define KEY_BACKSPACE 0x08
#define KEY_SPACE 0x20
+#define KEY_LEFTSHIFT 0x2A
+#define KEY_HOME 0x47
#define KEY_UP 0x48
#define KEY_DOWN 0x50
#define KEY_LEFT 0x4B
#define KEY_RIGHT 0x4D
#define KEY_ESC 0x1B
+#define KEY_CAPS_LOCK 0x3A
#define KEY_F1 0x3B
#define KEY_F2 0x3C
#define KEY_F3 0x3D
@@ -38,4 +41,7 @@
#define KEY_F7 0x41
#define KEY_F8 0x42
#define KEY_F9 0x43
-#define KEY_F10 0x44
+#define KEY_F10 0x44
+#define KEY_KEYPAD_PLUS 0x4e
+#define KEY_END 0x4f
+#define KEY_SEND 0xE7
diff --git a/boot/freeldr/freeldr/mm/mm.c b/boot/freeldr/freeldr/mm/mm.c
index f4a4c69b095..0066cb98d15 100644
--- a/boot/freeldr/freeldr/mm/mm.c
+++ b/boot/freeldr/freeldr/mm/mm.c
@@ -85,7 +85,6 @@ PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType)
PVOID MmHeapAlloc(ULONG MemorySize)
{
PVOID Result;
- LONG CurAlloc, TotalFree, MaxFree, NumberOfGets, NumberOfRels;
if (MemorySize > MM_PAGE_SIZE)
{
@@ -99,13 +98,17 @@ PVOID MmHeapAlloc(ULONG MemorySize)
{
DPRINTM(DPRINT_MEMORY, "Heap allocation for %d bytes failed\n", MemorySize);
}
+#if MM_DBG
+ {
+ LONG CurAlloc, TotalFree, MaxFree, NumberOfGets, NumberOfRels;
- // Gather some stats
- bstats(&CurAlloc, &TotalFree, &MaxFree, &NumberOfGets, &NumberOfRels);
-
- DPRINTM(DPRINT_MEMORY, "Current alloced %d bytes, free %d bytes, allocs %d, frees %d\n",
- CurAlloc, TotalFree, NumberOfGets, NumberOfRels);
+ // Gather some stats
+ bstats(&CurAlloc, &TotalFree, &MaxFree, &NumberOfGets, &NumberOfRels);
+ DPRINTM(DPRINT_MEMORY, "Current alloced %d bytes, free %d bytes, allocs %d, frees %d\n",
+ CurAlloc, TotalFree, NumberOfGets, NumberOfRels);
+ }
+#endif
return Result;
}
diff --git a/boot/freeldr/freeldr/rtl/bget.c b/boot/freeldr/freeldr/rtl/bget.c
index cff04fa7204..fb6c2d49d34 100644
--- a/boot/freeldr/freeldr/rtl/bget.c
+++ b/boot/freeldr/freeldr/rtl/bget.c
@@ -407,6 +407,7 @@
all buffers allocated are a
multiple of this size. This
MUST be a power of two. */
+#ifdef MM_DBG
#define BufDump 1 /* Define this symbol to enable the
bpoold() function which dumps the
@@ -442,6 +443,8 @@
#define BECtl 1 /* Define this symbol to enable the
bectl() function for automatic
pool space control. */
+#else
+#endif
#include
diff --git a/boot/freeldr/freeldr/windows/arm/wlmemory.c b/boot/freeldr/freeldr/windows/arm/wlmemory.c
index 660656a5722..37356a4107f 100644
--- a/boot/freeldr/freeldr/windows/arm/wlmemory.c
+++ b/boot/freeldr/freeldr/windows/arm/wlmemory.c
@@ -19,17 +19,32 @@
#define PTE_BASE 0xC0000000
#define PDE_BASE 0xC0400000
#define PDR_BASE 0xFFD00000
-#define MMIO_BASE 0x10000000
#define VECTOR_BASE 0xFFFF0000
-#define LowMemPageTableIndex 0
+#ifdef _ZOOM2_
+#define IDMAP_BASE 0x81000000
+#define MMIO_BASE 0x10000000
+#else
+#define IDMAP_BASE 0x00000000
+#define MMIO_BASE 0x10000000
+#endif
+
+#define LowMemPageTableIndex (IDMAP_BASE >> PDE_SHIFT)
+#define MmioPageTableIndex (MMIO_BASE >> PDE_SHIFT)
#define KernelPageTableIndex (KSEG0_BASE >> PDE_SHIFT)
#define StartupPtePageTableIndex (PTE_BASE >> PDE_SHIFT)
#define StartupPdePageTableIndex (PDE_BASE >> PDE_SHIFT)
-#define MmioPageTableIndex (MMIO_BASE >> PDE_SHIFT)
#define PdrPageTableIndex (PDR_BASE >> PDE_SHIFT)
#define VectorPageTableIndex (VECTOR_BASE >> PDE_SHIFT)
+#ifndef _ZOOM2_
+PVOID MempPdrBaseAddress = (PVOID)0x70000;
+PVOID MempKernelBaseAddress = (PVOID)0;
+#else
+PVOID MempPdrBaseAddress = (PVOID)0x81100000;
+PVOID MempKernelBaseAddress = (PVOID)0x80000000;
+#endif
+
/* Converts a Physical Address into a Page Frame Number */
#define PaToPfn(p) ((p) >> PFN_SHIFT)
#define PaToLargePfn(p) ((p) >> LARGE_PFN_SHIFT)
@@ -185,18 +200,21 @@ MempAllocatePageTables(VOID)
PFN_NUMBER Pfn;
/* Setup templates */
- TempPte.Accessed = TempPte.Valid = TempLargePte.LargePage = TempLargePte.Accessed = TempPde.Valid = 1;
+ TempPte.Sbo = TempPte.Valid = TempLargePte.LargePage = TempLargePte.Sbo = TempPde.Valid = 1;
/* Allocate the 1MB "PDR" (Processor Data Region). Must be 1MB aligned */
- PdrPage = MmAllocateMemoryAtAddress(sizeof(KPDR_PAGE), (PVOID)0x700000, LoaderMemoryData);
+ PdrPage = MmAllocateMemoryAtAddress(sizeof(KPDR_PAGE),
+ MempPdrBaseAddress,
+ LoaderMemoryData);
/* Setup the Low Memory PDE as an identity-mapped Large Page (1MB) */
LargePte = &PdrPage->PageDir.Pte[LowMemPageTableIndex];
+ TempLargePte.PageFrameNumber = PaToLargePfn(IDMAP_BASE);
*LargePte = TempLargePte;
/* Setup the MMIO PDE as two identity mapped large pages -- the kernel will blow these away later */
LargePte = &PdrPage->PageDir.Pte[MmioPageTableIndex];
- Pfn = PaToLargePfn(0x10000000);
+ Pfn = PaToLargePfn(MMIO_BASE);
for (i = 0; i < 2; i++)
{
TempLargePte.PageFrameNumber = Pfn++;
@@ -215,13 +233,13 @@ MempAllocatePageTables(VOID)
/* Setup the Kernel PTEs */
PointerPte = PdrPage->KernelPageTable[0].Pte;
- Pfn = 0;
+ Pfn = PaPtrToPfn(MempKernelBaseAddress);
for (i = 0; i < 3072; i++)
{
TempPte.PageFrameNumber = Pfn++;
*PointerPte++ = TempPte;
}
-
+
/* Done */
return TRUE;
}
diff --git a/boot/freeldr/freeldr/windows/conversion.c b/boot/freeldr/freeldr/windows/conversion.c
index 95c5bde5ee9..2f58a5f5466 100644
--- a/boot/freeldr/freeldr/windows/conversion.c
+++ b/boot/freeldr/freeldr/windows/conversion.c
@@ -15,6 +15,7 @@
/* FUNCTIONS **************************************************************/
+#ifndef _ZOOM2_
/* Arch-specific addresses translation implementation */
PVOID
VaToPa(PVOID Va)
@@ -27,6 +28,19 @@ PaToVa(PVOID Pa)
{
return (PVOID)((ULONG_PTR)Pa | KSEG0_BASE);
}
+#else
+PVOID
+VaToPa(PVOID Va)
+{
+ return Va;
+}
+
+PVOID
+PaToVa(PVOID Pa)
+{
+ return Pa;
+}
+#endif
VOID
List_PaToVa(LIST_ENTRY *ListEntry)
diff --git a/boot/freeldr/freeldr/windows/winldr.c b/boot/freeldr/freeldr/windows/winldr.c
index 3d5339083c0..95ac954005f 100644
--- a/boot/freeldr/freeldr/windows/winldr.c
+++ b/boot/freeldr/freeldr/windows/winldr.c
@@ -204,6 +204,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
Extension->AcpiTable = (PVOID)1;
}
+#ifndef _M_ARM
/* Set headless block pointer */
extern HEADLESS_LOADER_BLOCK LoaderRedirectionInformation;
extern BOOLEAN WinLdrTerminalConnected;
@@ -222,7 +223,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
sizeof(HEADLESS_LOADER_BLOCK));
Extension->HeadlessLoaderBlock = PaToVa(Extension->HeadlessLoaderBlock);
}
-
+#endif
/* Load drivers database */
strcpy(MiscFiles, BootPath);
strcat(MiscFiles, "AppPatch\\drvmain.sdb");
@@ -534,10 +535,11 @@ LoadAndBootWindows(PCSTR OperatingSystemName,
/* Allocate and minimalistic-initialize LPB */
AllocateAndInitLPB(&LoaderBlock);
+#ifndef _M_ARM
/* Setup redirection support */
extern void WinLdrSetupEms(IN PCHAR BootOptions);
WinLdrSetupEms(BootOptions);
-
+#endif
/* Detect hardware */
UseRealHeap = TRUE;
LoaderBlock->ConfigurationRoot = MachHwDetect();
diff --git a/boot/freeldr/freeldr/windows/wlregistry.c b/boot/freeldr/freeldr/windows/wlregistry.c
index 1080ee2cd06..b6c1fc956b4 100644
--- a/boot/freeldr/freeldr/windows/wlregistry.c
+++ b/boot/freeldr/freeldr/windows/wlregistry.c
@@ -88,7 +88,7 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
}
/* Convert address to virtual */
- HiveDataVirtual = (PVOID)(KSEG0_BASE | HiveDataPhysical);
+ HiveDataVirtual = PaToVa((PVOID)HiveDataPhysical);
/* Fill LoaderBlock's entries */
LoaderBlock->RegistryLength = HiveFileSize;
@@ -379,7 +379,7 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
if (NlsDataBase == 0)
goto Failure;
- NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase);
+ NlsVirtual = PaToVa((PVOID)NlsDataBase);
LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual +
(MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
diff --git a/config-arm.template.rbuild b/config-arm.template.rbuild
index dca25d53c0f..420c0f5cd9b 100644
--- a/config-arm.template.rbuild
+++ b/config-arm.template.rbuild
@@ -15,10 +15,10 @@
-
+
+
+
+
+
+
+
+
+
+
diff --git a/config.template.rbuild b/config.template.rbuild
index d8a130414d9..103c2e98e67 100644
--- a/config.template.rbuild
+++ b/config.template.rbuild
@@ -99,4 +99,14 @@
-->
+
+
+
+
+
+
diff --git a/dll/cpl/timedate/lang/fr-FR.rc b/dll/cpl/timedate/lang/fr-FR.rc
index c6cbb53fb15..b72be0231ce 100644
--- a/dll/cpl/timedate/lang/fr-FR.rc
+++ b/dll/cpl/timedate/lang/fr-FR.rc
@@ -33,7 +33,7 @@ BEGIN
COMBOBOX IDC_TIMEZONELIST, 5, 4, 241, 136,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP
CONTROL "", IDC_WORLD_BACKGROUND, "Static", SS_OWNERDRAW, 5, 20, 240, 110, WS_EX_STATICEDGE
- AUTOCHECKBOX "Ajuster automatiquement l'heure lors du &passage l'heure d't"
+ AUTOCHECKBOX "Ajuster automatiquement l'heure lors du &passage l'heure d't",
IDC_AUTODAYLIGHT, 6, 132, 242, 11, WS_VISIBLE | WS_GROUP | WS_TABSTOP
END
diff --git a/dll/directx/ddraw/Ddraw/callbacks_dd_hel.c b/dll/directx/ddraw/Ddraw/callbacks_dd_hel.c
index 8592543152c..57c30e346d8 100644
--- a/dll/directx/ddraw/Ddraw/callbacks_dd_hel.c
+++ b/dll/directx/ddraw/Ddraw/callbacks_dd_hel.c
@@ -75,9 +75,46 @@ DWORD CALLBACK HelDdCanCreateSurface(LPDDHAL_CANCREATESURFACEDATA lpCanCreateSu
DX_STUB;
}
-DWORD CALLBACK HelDdCreatePalette(LPDDHAL_CREATEPALETTEDATA lpCreatePalette)
+DWORD CALLBACK HelDdCreatePalette(LPDDHAL_CREATEPALETTEDATA lpCreatePalette)
{
- DX_STUB;
+ DDRAWI_DDRAWPALETTE_GBL* ddPalGbl = lpCreatePalette->lpDDPalette;
+ LOGPALETTE* logPal ;
+ WORD size=1;
+
+ if(ddPalGbl->dwFlags & DDRAWIPAL_2)
+ size = 2;
+ else if(ddPalGbl->dwFlags & DDRAWIPAL_4)
+ size = 4;
+ else if(ddPalGbl->dwFlags & DDRAWIPAL_16)
+ size = 16;
+ else if(ddPalGbl->dwFlags & DDRAWIPAL_256)
+ size = 256;
+
+ DxHeapMemAlloc(logPal, sizeof(LOGPALETTE) + size*sizeof(PALETTEENTRY));
+ if(logPal == NULL)
+ {
+ lpCreatePalette->ddRVal = DDERR_OUTOFMEMORY;
+ return DDHAL_DRIVER_HANDLED;
+ }
+
+ logPal->palVersion = 0x300;
+ logPal->palNumEntries = size;
+ CopyMemory(&logPal->palPalEntry[0], lpCreatePalette->lpColorTable, size*sizeof(PALETTEENTRY));
+
+ ddPalGbl->hHELGDIPalette = CreatePalette(logPal);
+
+ if (ddPalGbl->hHELGDIPalette == NULL)
+ {
+ DxHeapMemFree(logPal);
+ lpCreatePalette->ddRVal = DDERR_INVALIDOBJECT;
+ return DDHAL_DRIVER_HANDLED;
+ }
+
+ DxHeapMemFree(logPal);
+ ddPalGbl->lpColorTable = lpCreatePalette->lpColorTable;
+ ddPalGbl->dwFlags |= DDRAWIPAL_INHEL | DDRAWIPAL_GDI ;
+ lpCreatePalette->ddRVal = DD_OK;
+ return DDHAL_DRIVER_HANDLED;
}
DWORD CALLBACK HelDdGetScanLine(LPDDHAL_GETSCANLINEDATA lpGetScanLine)
diff --git a/dll/directx/ddraw/Ddraw/ddraw_main.c b/dll/directx/ddraw/Ddraw/ddraw_main.c
index a3b307c8a04..fe02d0a0d76 100644
--- a/dll/directx/ddraw/Ddraw/ddraw_main.c
+++ b/dll/directx/ddraw/Ddraw/ddraw_main.c
@@ -533,6 +533,9 @@ Main_DirectDraw_CreateSurface4(LPDDRAWI_DIRECTDRAW_INT This, LPDDSURFACEDESC2 pD
}
_SEH2_END;
+ if(*ppSurf != NULL)
+ Main_DirectDraw_AddRef(This);
+
LeaveCriticalSection(&ddcs);
return ret;
}
@@ -540,7 +543,32 @@ Main_DirectDraw_CreateSurface4(LPDDRAWI_DIRECTDRAW_INT This, LPDDSURFACEDESC2 pD
/* 5 of 31 DirectDraw7_Vtable api are working simluare to windows */
/* 8 of 31 DirectDraw7_Vtable api are under devloping / testing */
-
+HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDDRAWI_DIRECTDRAW_INT This, DWORD dwFlags,
+ LPPALETTEENTRY palent, LPDIRECTDRAWPALETTE* ppPalette, LPUNKNOWN pUnkOuter)
+{
+ HRESULT ret = DD_OK;
+ DX_WINDBG_trace();
+
+ EnterCriticalSection(&ddcs);
+ *ppPalette = NULL;
+
+ _SEH2_TRY
+ {
+ ret = Internal_CreatePalette(This, dwFlags, palent, ppPalette, pUnkOuter);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ret = DDERR_INVALIDPARAMS;
+ }
+ _SEH2_END;
+
+ //Versions 7 and 4 are addref'ed
+ if((This->lpVtbl == &DirectDraw7_Vtable || This->lpVtbl == &DirectDraw4_Vtable) && *ppPalette != NULL)
+ Main_DirectDraw_AddRef(This) ;
+
+ LeaveCriticalSection(&ddcs);
+ return ret;
+}
diff --git a/dll/directx/ddraw/Ddraw/ddraw_stubs.c b/dll/directx/ddraw/Ddraw/ddraw_stubs.c
index a2c60e74b33..4f11676ea86 100644
--- a/dll/directx/ddraw/Ddraw/ddraw_stubs.c
+++ b/dll/directx/ddraw/Ddraw/ddraw_stubs.c
@@ -24,13 +24,6 @@ Main_DirectDraw_CreateClipper(LPDDRAWI_DIRECTDRAW_INT This,
DX_STUB;
}
-HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDDRAWI_DIRECTDRAW_INT This, DWORD dwFlags,
- LPPALETTEENTRY palent, LPDIRECTDRAWPALETTE* ppPalette, LPUNKNOWN pUnkOuter)
-{
- DX_WINDBG_trace();
- DX_STUB;
-}
-
HRESULT WINAPI Main_DirectDraw_DuplicateSurface(LPDDRAWI_DIRECTDRAW_INT This, LPDIRECTDRAWSURFACE7 src,
LPDIRECTDRAWSURFACE7* dst)
{
diff --git a/dll/directx/ddraw/Palette/createpalette.c b/dll/directx/ddraw/Palette/createpalette.c
new file mode 100644
index 00000000000..87bb0a9f141
--- /dev/null
+++ b/dll/directx/ddraw/Palette/createpalette.c
@@ -0,0 +1,135 @@
+/* $Id$
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS DirectX
+ * FILE: ddraw/surface/createsurface.c
+ * PURPOSE: IDirectDrawPalette Creation
+ * PROGRAMMER: Jrme Gardou
+ *
+ */
+#include "rosdraw.h"
+
+DWORD ConvertPCapsFlags(DWORD dwFlags)
+{
+ DWORD ret = 0;
+ if(dwFlags & DDPCAPS_4BIT)
+ ret|=DDRAWIPAL_16;
+ if(dwFlags & DDPCAPS_8BIT)
+ ret|=DDRAWIPAL_256;
+ if(dwFlags & DDPCAPS_8BITENTRIES)
+ ret|=DDRAWIPAL_STORED_8INDEX;
+ if(dwFlags & DDPCAPS_ALLOW256)
+ ret|=DDRAWIPAL_ALLOW256;
+ if(dwFlags & DDPCAPS_ALPHA)
+ ret|=DDRAWIPAL_ALPHA;
+ if(dwFlags & DDPCAPS_1BIT)
+ ret|=DDRAWIPAL_2;
+ if(dwFlags & DDPCAPS_2BIT)
+ ret|=DDRAWIPAL_4;
+
+ return ret;
+}
+
+HRESULT
+Internal_CreatePalette( LPDDRAWI_DIRECTDRAW_INT pDDraw, DWORD dwFlags,
+ LPPALETTEENTRY palent, LPDIRECTDRAWPALETTE* ppPalette, LPUNKNOWN pUnkOuter)
+{
+ DDHAL_CREATEPALETTEDATA mDdCreatePalette = { 0 };
+
+ LPDDRAWI_DDRAWPALETTE_INT ThisPalInt = NULL;
+ LPDDRAWI_DDRAWPALETTE_LCL ThisPalLcl = NULL;
+ LPDDRAWI_DDRAWPALETTE_GBL ThisPalGbl = NULL;
+
+ HRESULT ret;
+
+ if(pUnkOuter)
+ {
+ return CLASS_E_NOAGGREGATION;
+ }
+
+ if(!(pDDraw->lpLcl->dwLocalFlags & DDRAWILCL_SETCOOPCALLED))
+ {
+ return DDERR_NOCOOPERATIVELEVELSET;
+ }
+
+
+ if (pDDraw->lpLcl->dwProcessId != GetCurrentProcessId() )
+ {
+ return DDERR_INVALIDOBJECT;
+ }
+
+ /* Allocate the palette interface and needed members */
+ DxHeapMemAlloc(ThisPalInt, sizeof( DDRAWI_DDRAWPALETTE_INT ) );
+ if( ThisPalInt == NULL )
+ {
+ ret = DDERR_OUTOFMEMORY;
+ goto cleanup;
+ }
+
+ DxHeapMemAlloc(ThisPalLcl, sizeof( DDRAWI_DDRAWPALETTE_LCL ) );
+ if( ThisPalLcl == NULL )
+ {
+ ret = DDERR_OUTOFMEMORY;
+ goto cleanup;
+ }
+
+ DxHeapMemAlloc(ThisPalGbl, sizeof( DDRAWI_DDRAWPALETTE_GBL ) );
+ if( ThisPalGbl == NULL )
+ {
+ ret = DDERR_OUTOFMEMORY;
+ goto cleanup;
+ }
+
+ /*Some initial setup*/
+
+ ThisPalInt->lpLcl = ThisPalLcl;
+ ThisPalLcl->lpGbl = ThisPalGbl;
+
+ ThisPalLcl->lpDD_lcl = ThisPalGbl->lpDD_lcl = pDDraw->lpLcl;
+ ThisPalGbl->dwFlags = ConvertPCapsFlags(dwFlags);
+
+ ThisPalInt->lpVtbl = (PVOID)&DirectDrawPalette_Vtable;
+ ThisPalGbl->dwProcessId = GetCurrentProcessId();
+
+ mDdCreatePalette.lpDD = pDDraw->lpLcl->lpGbl;
+ mDdCreatePalette.lpDDPalette = ThisPalGbl;
+ if(pDDraw->lpLcl->lpGbl->lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_CREATEPALETTE) {
+ mDdCreatePalette.CreatePalette = pDDraw->lpLcl->lpGbl->lpDDCBtmp->HALDD.CreatePalette;
+ DX_STUB_str("Using HAL CreatePalette\n");
+ }
+ else {
+ mDdCreatePalette.CreatePalette = pDDraw->lpLcl->lpGbl->lpDDCBtmp->HELDD.CreatePalette;
+ DX_STUB_str("Using HEL CreatePalette\n");
+ }
+ mDdCreatePalette.ddRVal = DDERR_GENERIC;
+ mDdCreatePalette.lpColorTable = palent;
+
+ if (mDdCreatePalette.CreatePalette(&mDdCreatePalette) == DDHAL_DRIVER_NOTHANDLED)
+ {
+ DX_STUB_str("mDdCreateSurface failed with DDHAL_DRIVER_NOTHANDLED.");
+ ret = DDERR_NOTINITIALIZED;
+ goto cleanup;
+ }
+
+ if (mDdCreatePalette.ddRVal != DD_OK)
+ {
+ DX_STUB_str("mDdCreateSurface failed.");
+ ret = mDdCreatePalette.ddRVal;
+ goto cleanup;
+ }
+
+ *ppPalette = (LPDIRECTDRAWPALETTE)ThisPalInt;
+ ThisPalInt->lpLink = pDDraw->lpLcl->lpGbl->palList;
+ pDDraw->lpLcl->lpGbl->palList = ThisPalInt;
+ ThisPalInt->lpLcl->dwReserved1 = (ULONG_PTR)pDDraw;
+ IDirectDrawPalette_AddRef(*ppPalette);
+
+ return DD_OK;
+
+cleanup:
+ if(ThisPalInt) DxHeapMemFree(ThisPalInt);
+ if(ThisPalLcl) DxHeapMemFree(ThisPalLcl);
+ if(ThisPalGbl) DxHeapMemFree(ThisPalGbl);
+
+ return ret;
+}
diff --git a/dll/directx/ddraw/Palette/palette.c b/dll/directx/ddraw/Palette/palette.c
new file mode 100644
index 00000000000..c366be9206c
--- /dev/null
+++ b/dll/directx/ddraw/Palette/palette.c
@@ -0,0 +1,157 @@
+/* $Id: palette.c $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS DirectX
+ * FILE: ddraw/Palette/palette.c
+ * PURPOSE: IDirectDrawPalette Implementation
+ * PROGRAMMER: Jrme Gardou
+ *
+ */
+
+#include "rosdraw.h"
+
+/*****************************************************************************
+ * IDirectDrawPalette::QueryInterface
+ *
+ * A usual QueryInterface implementation. Can only Query IUnknown and
+ * IDirectDrawPalette
+ *
+ * Params:
+ * refiid: The interface id queried for
+ * obj: Address to return the interface pointer at
+ *
+ * Returns:
+ * S_OK on success
+ * E_NOINTERFACE if the requested interface wasn't found
+ *****************************************************************************/
+static HRESULT WINAPI
+DirectDrawPalette_QueryInterface(IDirectDrawPalette *iface,
+ REFIID refiid,
+ void **obj)
+{
+ if (IsEqualGUID(refiid, &IID_IUnknown)
+ || IsEqualGUID(refiid, &IID_IDirectDrawPalette))
+ {
+ *obj = iface;
+ IDirectDrawPalette_AddRef(iface);
+ return S_OK;
+ }
+ else
+ {
+ *obj = NULL;
+ return E_NOINTERFACE;
+ }
+}
+
+/*****************************************************************************
+ * IDirectDrawPaletteImpl::AddRef
+ *
+ * Increases the refcount.
+ *
+ * Returns:
+ * The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+DirectDrawPalette_AddRef(IDirectDrawPalette *iface)
+{
+ LPDDRAWI_DDRAWPALETTE_INT This = (LPDDRAWI_DDRAWPALETTE_INT)iface;
+ ULONG ref = 0;
+
+ _SEH2_TRY
+ {
+ ref = ++This->dwIntRefCnt;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+ _SEH2_END
+
+ return ref;
+}
+
+/*****************************************************************************
+ * IDirectDrawPaletteImpl::Release
+ *
+ * Reduces the refcount. If the refcount falls to 0, the object is destroyed
+ *
+ * Returns:
+ * The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+DirectDrawPalette_Release(IDirectDrawPalette *iface)
+{
+ LPDDRAWI_DDRAWPALETTE_INT This = (LPDDRAWI_DDRAWPALETTE_INT)iface;
+ ULONG ref = 0;
+
+ _SEH2_TRY
+ {
+ ref = --This->dwIntRefCnt;
+ if(ref == 0)
+ {
+ AcquireDDThreadLock();
+ if(((LPDDRAWI_DIRECTDRAW_INT)This->lpLcl->dwReserved1)->lpVtbl == &DirectDraw7_Vtable
+ || ((LPDDRAWI_DIRECTDRAW_INT)This->lpLcl->dwReserved1)->lpVtbl == &DirectDraw4_Vtable)
+ Main_DirectDraw_Release((LPDDRAWI_DIRECTDRAW_INT)This->lpLcl->dwReserved1) ;
+ DxHeapMemFree(This); //HUGE FIXME!!!
+ ReleaseDDThreadLock();
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+ _SEH2_END
+
+ return ref;
+}
+
+static HRESULT WINAPI
+DirectDrawPalette_Initialize( LPDIRECTDRAWPALETTE iface,
+ LPDIRECTDRAW ddraw,
+ DWORD dwFlags,
+ LPPALETTEENTRY palent)
+{
+ DX_WINDBG_trace();
+ DX_STUB;
+}
+
+static HRESULT WINAPI
+DirectDrawPalette_GetEntries( LPDIRECTDRAWPALETTE iface,
+ DWORD dwFlags,
+ DWORD dwStart, DWORD dwCount,
+ LPPALETTEENTRY palent)
+{
+ DX_WINDBG_trace();
+ DX_STUB;
+}
+
+static HRESULT WINAPI
+DirectDrawPalette_SetEntries( LPDIRECTDRAWPALETTE iface,
+ DWORD dwFlags,
+ DWORD dwStart,
+ DWORD dwCount,
+ LPPALETTEENTRY palent)
+{
+ DX_WINDBG_trace();
+ DX_STUB;
+}
+
+static HRESULT WINAPI
+DirectDrawPalette_GetCaps( LPDIRECTDRAWPALETTE iface,
+ LPDWORD lpdwCaps)
+{
+ DX_WINDBG_trace();
+ DX_STUB;
+}
+
+const IDirectDrawPaletteVtbl DirectDrawPalette_Vtable =
+{
+ DirectDrawPalette_QueryInterface,
+ DirectDrawPalette_AddRef,
+ DirectDrawPalette_Release,
+ DirectDrawPalette_GetCaps,
+ DirectDrawPalette_GetEntries,
+ DirectDrawPalette_Initialize,
+ DirectDrawPalette_SetEntries
+};
diff --git a/dll/directx/ddraw/Surface/createsurface.c b/dll/directx/ddraw/Surface/createsurface.c
index c34396f309d..d6d95579a3d 100644
--- a/dll/directx/ddraw/Surface/createsurface.c
+++ b/dll/directx/ddraw/Surface/createsurface.c
@@ -182,7 +182,6 @@ Internal_CreateSurface( LPDDRAWI_DIRECTDRAW_INT pDDraw, LPDDSURFACEDESC2 pDDSD,
/* FIXME ThisSurfaceMore->dmiDDrawReserved7.wMonitorsAttachedToDesktop */
ThisSurfMore->dmiDDrawReserved7.wMonitorsAttachedToDesktop = 1;
pDDraw->lpLcl->lpPrimary = ThisSurfInt;
- Main_DirectDraw_AddRef(pDDraw);
}
else
{
diff --git a/dll/directx/ddraw/Surface/surface_main.c b/dll/directx/ddraw/Surface/surface_main.c
index 28bc2c34bb1..81abdf8f88d 100644
--- a/dll/directx/ddraw/Surface/surface_main.c
+++ b/dll/directx/ddraw/Surface/surface_main.c
@@ -264,14 +264,28 @@ Main_DDrawSurface_QueryInterface(LPDDRAWI_DDRAWSURFACE_INT This, REFIID riid, LP
ULONG WINAPI Main_DDrawSurface_Release(LPDDRAWI_DDRAWSURFACE_INT This)
{
-
/* FIXME
This is not right exiame how it should be done
*/
- DX_STUB_str("FIXME This is not right exiame how it should be done\n");
- return This->dwIntRefCnt;
+ ULONG ret = --This->dwIntRefCnt;
+ if(!ret)
+ {
+ DX_STUB_str("Release is a bit simplistic right now\n");
+ AcquireDDThreadLock();
+ DxHeapMemFree(This);
+ ReleaseDDThreadLock();
+ }
+ return ret;
}
+ULONG WINAPI Main_DDrawSurface_Release4(LPDDRAWI_DDRAWSURFACE_INT This)
+{
+ ULONG ref = Main_DDrawSurface_Release(This) ;
+
+ if(ref == 0) Main_DirectDraw_Release(This->lpLcl->lpSurfMore->lpDD_int);
+
+ return ref;
+}
HRESULT WINAPI Main_DDrawSurface_Blt(LPDDRAWI_DDRAWSURFACE_INT ThisDest, LPRECT rdst,
LPDDRAWI_DDRAWSURFACE_INT ThisSrc, LPRECT rsrc, DWORD dwFlags, LPDDBLTFX lpbltfx)
diff --git a/dll/directx/ddraw/Vtable/DirectDrawSurface4_Vtable.c b/dll/directx/ddraw/Vtable/DirectDrawSurface4_Vtable.c
index 3041906f21c..57fd0a4e3c5 100644
--- a/dll/directx/ddraw/Vtable/DirectDrawSurface4_Vtable.c
+++ b/dll/directx/ddraw/Vtable/DirectDrawSurface4_Vtable.c
@@ -16,7 +16,7 @@
#endif
ULONG WINAPI Main_DDrawSurface_AddRef(LPDIRECTDRAWSURFACE4);
-ULONG WINAPI Main_DDrawSurface_Release(LPDIRECTDRAWSURFACE4);
+ULONG WINAPI Main_DDrawSurface_Release4(LPDIRECTDRAWSURFACE4);
HRESULT WINAPI Main_DDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE4, REFIID, LPVOID*);
HRESULT WINAPI Main_DDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE4, HDC);
HRESULT WINAPI Main_DDrawSurface_Blt(LPDIRECTDRAWSURFACE4, LPRECT, LPDIRECTDRAWSURFACE4, LPRECT, DWORD, LPDDBLTFX);
@@ -68,7 +68,7 @@ IDirectDrawSurface4Vtbl DirectDrawSurface4_Vtable =
{
Main_DDrawSurface_QueryInterface,
Main_DDrawSurface_AddRef, /* (Compact done) */
- Main_DDrawSurface_Release,
+ Main_DDrawSurface_Release4,
Main_DDrawSurface_AddAttachedSurface,
Main_DDrawSurface_AddOverlayDirtyRect,
Main_DDrawSurface_Blt,
diff --git a/dll/directx/ddraw/Vtable/DirectDrawSurface7_Vtable.c b/dll/directx/ddraw/Vtable/DirectDrawSurface7_Vtable.c
index 97e92008ae9..07037c0ddb6 100644
--- a/dll/directx/ddraw/Vtable/DirectDrawSurface7_Vtable.c
+++ b/dll/directx/ddraw/Vtable/DirectDrawSurface7_Vtable.c
@@ -16,7 +16,7 @@
#endif
ULONG WINAPI Main_DDrawSurface_AddRef(LPDIRECTDRAWSURFACE7);
-ULONG WINAPI Main_DDrawSurface_Release(LPDIRECTDRAWSURFACE7);
+ULONG WINAPI Main_DDrawSurface_Release4(LPDIRECTDRAWSURFACE7);
HRESULT WINAPI Main_DDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7, REFIID, LPVOID*);
HRESULT WINAPI Main_DDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7, HDC);
HRESULT WINAPI Main_DDrawSurface_Blt(LPDIRECTDRAWSURFACE7, LPRECT, LPDIRECTDRAWSURFACE7, LPRECT, DWORD, LPDDBLTFX);
@@ -72,7 +72,7 @@ IDirectDrawSurface7Vtbl DirectDrawSurface7_Vtable =
{
Main_DDrawSurface_QueryInterface,
Main_DDrawSurface_AddRef, /* (Compact done) */
- Main_DDrawSurface_Release,
+ Main_DDrawSurface_Release4,
Main_DDrawSurface_AddAttachedSurface,
Main_DDrawSurface_AddOverlayDirtyRect,
Main_DDrawSurface_Blt,
diff --git a/dll/directx/ddraw/ddraw.rbuild b/dll/directx/ddraw/ddraw.rbuild
index a678e62164e..016afa6090a 100644
--- a/dll/directx/ddraw/ddraw.rbuild
+++ b/dll/directx/ddraw/ddraw.rbuild
@@ -8,7 +8,7 @@
d3d8thk
dxguid
ole32
- user32
+ uuid
advapi32
pseh
@@ -49,7 +49,8 @@
kernel_stubs.c
- palette_stubs.c
+ palette.c
+ createpalette.c
videoport_stubs.c
diff --git a/dll/directx/ddraw/rosdraw.h b/dll/directx/ddraw/rosdraw.h
index 6cb0f2088c8..9b50c1c7eda 100644
--- a/dll/directx/ddraw/rosdraw.h
+++ b/dll/directx/ddraw/rosdraw.h
@@ -34,7 +34,7 @@ extern IDirectDrawSurface4Vtbl DirectDrawSurface4_Vtable;
extern IDirectDrawSurface3Vtbl DirectDrawSurface3_Vtable;
extern IDirectDrawSurface2Vtbl DirectDrawSurface2_Vtable;
extern IDirectDrawSurfaceVtbl DirectDrawSurface_Vtable;
-extern IDirectDrawPaletteVtbl DirectDrawPalette_Vtable;
+extern const IDirectDrawPaletteVtbl DirectDrawPalette_Vtable;
extern IDirectDrawClipperVtbl DirectDrawClipper_Vtable;
extern IDirectDrawColorControlVtbl DirectDrawColorControl_Vtable;
extern IDirectDrawGammaControlVtbl DirectDrawGammaControl_Vtable;
@@ -93,6 +93,10 @@ Internal_CreateSurface(
LPDDRAWI_DDRAWSURFACE_INT *ppSurf,
IUnknown *pUnkOuter);
+HRESULT
+Internal_CreatePalette( LPDDRAWI_DIRECTDRAW_INT pDDraw, DWORD dwFlags,
+ LPPALETTEENTRY palent, LPDIRECTDRAWPALETTE* ppPalette, LPUNKNOWN pUnkOuter);
+
/* convert DDSURFACEDESC to DDSURFACEDESC2 */
void CopyDDSurfDescToDDSurfDesc2(LPDDSURFACEDESC2 dst_pDesc, LPDDSURFACEDESC src_pDesc);
diff --git a/dll/directx/ddraw/startup.c b/dll/directx/ddraw/startup.c
index e1158af974a..6a5c6ba9d33 100644
--- a/dll/directx/ddraw/startup.c
+++ b/dll/directx/ddraw/startup.c
@@ -24,17 +24,29 @@ Create_DirectDraw (LPGUID pGUID, LPDIRECTDRAW* pIface,
LPDDRAWI_DIRECTDRAW_INT This;
DX_WINDBG_trace();
+ BOOL linking = FALSE;
- if ((IsBadReadPtr(pIface,sizeof(LPDIRECTDRAW))) ||
- (IsBadWritePtr(pIface,sizeof(LPDIRECTDRAW))))
+ if (pIface == NULL)
{
return DDERR_INVALIDPARAMS;
}
This = (LPDDRAWI_DIRECTDRAW_INT)*pIface;
- if ( (IsBadWritePtr(This,sizeof(LPDDRAWI_DIRECTDRAW_INT)) != 0) ||
- (IsBadWritePtr(This->lpLcl,sizeof(LPDDRAWI_DIRECTDRAW_LCL)) != 0) )
+ DX_STUB_str("Linking?\n")
+
+ _SEH2_TRY
+ {
+ linking = This->lpLcl ? TRUE:FALSE;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ linking = FALSE;
+ }
+ _SEH2_END;
+
+ /* fixme linking too second link when we shall not doing it */
+ if (!linking)
{
/* We do not have a DirectDraw interface, we need alloc it*/
LPDDRAWI_DIRECTDRAW_INT memThis;
@@ -310,6 +322,7 @@ StartDirectDraw(LPDIRECTDRAW iface, LPGUID lpGuid, BOOL reenable)
return DDERR_NODIRECTDRAWSUPPORT;
}
dwFlags |= DDRAWI_NOHARDWARE;
+ DX_STUB_str("No hardware support\n");
}
if (hel_ret!=DD_OK)
diff --git a/dll/directx/directx.rbuild b/dll/directx/directx.rbuild
index f542c0398eb..f24af12c320 100644
--- a/dll/directx/directx.rbuild
+++ b/dll/directx/directx.rbuild
@@ -29,7 +29,7 @@
-
+
diff --git a/dll/ntdll/dispatch/i386/dispatch.S b/dll/ntdll/dispatch/i386/dispatch.S
index c17374e9ed1..25f7c34bcee 100644
--- a/dll/ntdll/dispatch/i386/dispatch.S
+++ b/dll/ntdll/dispatch/i386/dispatch.S
@@ -8,13 +8,22 @@
/* INCLUDES ******************************************************************/
-#include
-.intel_syntax noprefix
+#include
+#include
+
+EXTERN _LdrpInit@12:PROC
+EXTERN _NtTestAlert@0:PROC
+EXTERN _RtlDispatchException@8:PROC
+EXTERN _RtlRaiseException@4:PROC
+EXTERN _RtlRaiseStatus@4:PROC
+EXTERN _ZwCallbackReturn@12:PROC
+EXTERN _ZwContinue@8:PROC
+EXTERN _ZwRaiseException@12:PROC
/* FUNCTIONS ****************************************************************/
+.code
-.func LdrInitializeThunk@16
-.globl _LdrInitializeThunk@16
+PUBLIC _LdrInitializeThunk@16
_LdrInitializeThunk@16:
/* Get the APC Context */
@@ -28,9 +37,8 @@ _LdrInitializeThunk@16:
/* Jump into the C initialization routine */
jmp _LdrpInit@12
-.endfunc
-.func KiUserApcExceptionHandler
+
_KiUserApcExceptionHandler:
/* Put the exception record in ECX and check the Flags */
@@ -45,10 +53,9 @@ _KiUserApcExceptionHandler:
/* We'll execute handler */
mov eax, EXCEPTION_EXECUTE_HANDLER
ret 16
-.endfunc
-.func KiUserApcDispatcher@16
-.globl _KiUserApcDispatcher@16
+
+PUBLIC _KiUserApcDispatcher@16
_KiUserApcDispatcher@16:
/* Setup SEH stack */
@@ -86,9 +93,8 @@ StatusRaiseApc:
call _RtlRaiseStatus@4
jmp StatusRaiseApc
ret 16
-.endfunc
-.func KiUserCallbackExceptionHandler
+
_KiUserCallbackExceptionHandler:
/* Put the exception record in ECX and check the Flags */
@@ -106,10 +112,9 @@ return:
/* We'll execute the handler */
mov eax, EXCEPTION_EXECUTE_HANDLER
ret 16
-.endfunc
-.func KiUserCallbackDispatcher@12
-.globl _KiUserCallbackDispatcher@12
+
+PUBLIC _KiUserCallbackDispatcher@12
_KiUserCallbackDispatcher@12:
/* Setup SEH stack */
@@ -131,7 +136,7 @@ _KiUserCallbackDispatcher@12:
mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]
/* Call the routine */
- call [eax+edx*4]
+ call dword ptr [eax+edx*4]
/* Return from callback */
push eax
@@ -148,10 +153,9 @@ StatusRaise:
call _RtlRaiseStatus@4
jmp StatusRaise
ret 12
-.endfunc
-.func KiRaiseUserExceptionDispatcher@0
-.globl _KiRaiseUserExceptionDispatcher@0
+
+PUBLIC _KiRaiseUserExceptionDispatcher@0
_KiRaiseUserExceptionDispatcher@0:
/* Setup stack for EXCEPTION_RECORD */
@@ -177,10 +181,9 @@ _KiRaiseUserExceptionDispatcher@0:
mov esp, ebp
pop ebp
ret
-.endfunc
-.func KiUserExceptionDispatcher@8
-.globl _KiUserExceptionDispatcher@8
+
+PUBLIC _KiUserExceptionDispatcher@8
_KiUserExceptionDispatcher@8:
/* Clear direction flag */
@@ -236,39 +239,35 @@ Exit:
push esp
call _RtlRaiseException@4
ret 8
-.endfunc
-.func KiIntSystemCall@0
-.globl _KiIntSystemCall@0
+
+PUBLIC _KiIntSystemCall@0
_KiIntSystemCall@0:
/* Set stack in EDX and do the interrupt */
lea edx, [esp+8]
- int 0x2E
+ int HEX(2E)
/* Return to caller */
ret
-.endfunc
-.func KiFastSystemCall@0
-.globl _KiFastSystemCall@0
+
+PUBLIC _KiFastSystemCall@0
_KiFastSystemCall@0:
/* Put ESP in EDX and do the SYSENTER */
mov edx, esp
sysenter
-.endfunc
-.func KiFastSystemCallRet@0
-.globl _KiFastSystemCallRet@0
+
+PUBLIC _KiFastSystemCallRet@0
_KiFastSystemCallRet@0:
/* Just return to caller */
ret
-.endfunc
-.func RtlpGetStackLimits@8
-.globl _RtlpGetStackLimits@8
+
+PUBLIC _RtlpGetStackLimits@8
_RtlpGetStackLimits@8:
/* Get the stack limits */
@@ -283,4 +282,5 @@ _RtlpGetStackLimits@8:
/* return */
ret 8
-.endfunc
+
+END
diff --git a/dll/ntdll/ldr/utils.c b/dll/ntdll/ldr/utils.c
index 30373f35848..4b085391e92 100644
--- a/dll/ntdll/ldr/utils.c
+++ b/dll/ntdll/ldr/utils.c
@@ -256,7 +256,7 @@ LdrpQueryAppPaths(IN PCWSTR ImageName)
/* Copy it to the heap allocd memory */
Path = RtlAllocateHeap(RtlGetProcessHeap(),
0,
- wcslen(SearchPathBuffer) * sizeof(WCHAR));
+ (wcslen(SearchPathBuffer) + 1) * sizeof(WCHAR));
if (!Path)
{
@@ -3236,9 +3236,9 @@ LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders)
*/
NTSTATUS NTAPI
LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
- ULONG Unknown1,
- ULONG Unknown2,
- ULONG Unknown3)
+ IN PLDR_CALLBACK Callback,
+ IN PVOID CallbackContext,
+ OUT PUSHORT ImageCharacterstics)
{
FILE_STANDARD_INFORMATION FileInfo;
IO_STATUS_BLOCK IoStatusBlock;
diff --git a/dll/win32/atl/atl.rgs b/dll/win32/atl/atl.rgs
index 8b1d476b20d..ee432497f78 100644
--- a/dll/win32/atl/atl.rgs
+++ b/dll/win32/atl/atl.rgs
@@ -2,10 +2,10 @@ HKCR
{
ATL.Registrar = s 'Registrar Class'
{
- CLSID = s '%CLSID_ATLRegistrar%'
+ CLSID = s '%CLSID_Registrar%'
}
NoRemove CLSID {
- ForceRemove '%CLSID_ATLRegistrar%' = s 'Registrar Class'
+ ForceRemove '%CLSID_Registrar%' = s 'Registrar Class'
{
ProgID = s 'ATL.Registrar'
InprocServer32 = s '%MODULE%'
diff --git a/dll/win32/atl/atl_ax.c b/dll/win32/atl/atl_ax.c
index d9d60a56b9e..1293cb830ba 100644
--- a/dll/win32/atl/atl_ax.c
+++ b/dll/win32/atl/atl_ax.c
@@ -1053,6 +1053,9 @@ HRESULT WINAPI AtlAxAttachControl(IUnknown* pControl, HWND hWnd, IUnknown** ppUn
*ppUnkContainer = (IUnknown*) pUnkContainer;
}
+ if(!hWnd)
+ return S_FALSE;
+
return hr;
}
diff --git a/dll/win32/atl/atliface.idl b/dll/win32/atl/atliface.idl
index ef3e5e58165..887338fdb50 100644
--- a/dll/win32/atl/atliface.idl
+++ b/dll/win32/atl/atliface.idl
@@ -19,7 +19,7 @@
import "ocidl.idl";
cpp_quote("#ifdef ATL_INITGUID")
-cpp_quote("#include \"initguid.h\"")
+cpp_quote("#include ")
cpp_quote("#endif")
[
@@ -68,7 +68,7 @@ interface IRegistrar : IUnknown
[in] LPCOLESTR szType);
}
-cpp_quote("DEFINE_GUID(CLSID_ATLRegistrar,0x44ec053a,0x400f,0x11d0,0x9d,0xcd,0x00,0xa0,0xc9,0x03,0x91,0xd3);")
+cpp_quote("DEFINE_GUID(CLSID_Registrar,0x44ec053a,0x400f,0x11d0,0x9d,0xcd,0x00,0xa0,0xc9,0x03,0x91,0xd3);")
cpp_quote("HRESULT WINAPI AtlAxCreateControl(LPCOLESTR,HWND,IStream*,IUnknown**);")
cpp_quote("HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR,HWND,IStream*,IUnknown**,IUnknown**,REFIID,IUnknown*);")
diff --git a/dll/win32/atl/registrar.c b/dll/win32/atl/registrar.c
index 7076e35c17c..c9d7e6c7af7 100644
--- a/dll/win32/atl/registrar.c
+++ b/dll/win32/atl/registrar.c
@@ -687,8 +687,9 @@ static HRESULT WINAPI RegistrarCF_QueryInterface(IClassFactory *iface, REFIID ri
{
TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
- if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRegistrar, riid)) {
+ if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
*ppvObject = iface;
+ IClassFactory_AddRef( iface );
return S_OK;
}
@@ -743,10 +744,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, LPVOID *ppvObject)
{
TRACE("(%s %s %p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppvObject);
- if(IsEqualGUID(&CLSID_ATLRegistrar, clsid)) {
- *ppvObject = &RegistrarCF;
- return S_OK;
- }
+ if(IsEqualGUID(&CLSID_Registrar, clsid))
+ return IClassFactory_QueryInterface( &RegistrarCF, riid, ppvObject );
FIXME("Not supported class %s\n", debugstr_guid(clsid));
return CLASS_E_CLASSNOTAVAILABLE;
@@ -787,14 +786,14 @@ static HRESULT do_register_dll_server(IRegistrar *pRegistrar, LPCOLESTR wszDll,
static HRESULT do_register_server(BOOL do_register)
{
- static const WCHAR CLSID_ATLRegistrarW[] =
- {'C','L','S','I','D','_','A','T','L','R','e','g','i','s','t','r','a','r',0};
+ static const WCHAR CLSID_RegistrarW[] =
+ {'C','L','S','I','D','_','R','e','g','i','s','t','r','a','r',0};
static const WCHAR atl_dllW[] = {'a','t','l','.','d','l','l',0};
WCHAR clsid_str[40];
- const struct _ATL_REGMAP_ENTRY reg_map[] = {{CLSID_ATLRegistrarW, clsid_str}, {NULL,NULL}};
+ const struct _ATL_REGMAP_ENTRY reg_map[] = {{CLSID_RegistrarW, clsid_str}, {NULL,NULL}};
- StringFromGUID2(&CLSID_ATLRegistrar, clsid_str, sizeof(clsid_str)/sizeof(WCHAR));
+ StringFromGUID2(&CLSID_Registrar, clsid_str, sizeof(clsid_str)/sizeof(WCHAR));
return do_register_dll_server(NULL, atl_dllW, MAKEINTRESOURCEW(101), do_register, reg_map);
}
diff --git a/dll/win32/gdi32/include/gdi32p.h b/dll/win32/gdi32/include/gdi32p.h
index 5cc09870a94..e8b5e63952d 100644
--- a/dll/win32/gdi32/include/gdi32p.h
+++ b/dll/win32/gdi32/include/gdi32p.h
@@ -146,7 +146,7 @@ typedef BOOL (WINAPI *STARTPAGEPRINTER) (HANDLE);
typedef BOOL (WINAPI *SEEKPRINTER) (HANDLE,LARGE_INTEGER,PLARGE_INTEGER,DWORD,BOOL);
typedef BOOL (WINAPI *SPLREADPRINTER) (HANDLE,LPBYTE *,DWORD);
// Same as ddk/winsplp.h DriverUnloadComplete?
-typedef BOOL (WINAPI *SPLDRIVERUNLOADCOMPLETE) (LPWSTR);
+typedef BOOL (WINAPI *SPLDRIVERUNLOADCOMPLETE) (LPWSTR);
// Driver support:
// DrvDocumentEvent api/winddiui.h not W2k8 DocumentEventAW
typedef INT (WINAPI *DOCUMENTEVENT) (HANDLE,HDC,INT,ULONG,PVOID,ULONG,PVOID);
@@ -173,10 +173,10 @@ HEAP_strdupA2W(
VOID
HEAP_free(LPVOID memory);
-VOID
+VOID
FASTCALL
FONT_TextMetricWToA(
- const TEXTMETRICW *ptmW,
+ const TEXTMETRICW *ptmW,
LPTEXTMETRICA ptmA
);
@@ -279,7 +279,7 @@ WINAPI
GdiSetLastError( DWORD dwErrCode );
DWORD WINAPI GdiGetCodePage(HDC);
-UINT FASTCALL DIB_BitmapBitsSize( PBITMAPINFO );
+UINT FASTCALL DIB_BitmapBitsSize( CONST BITMAPINFO* );
int
WINAPI
diff --git a/dll/win32/gdi32/misc/wingl.c b/dll/win32/gdi32/misc/wingl.c
index 5373c6f4d2d..b20ac7ee9d2 100644
--- a/dll/win32/gdi32/misc/wingl.c
+++ b/dll/win32/gdi32/misc/wingl.c
@@ -166,6 +166,10 @@ SetPixelFormat(HDC hdc,
INT iPixelFormat,
CONST PIXELFORMATDESCRIPTOR * ppfd)
{
+ /* Can only be set once */
+ INT current = GetPixelFormat(hdc);
+ if(current) return current == iPixelFormat ;
+
if (glSetPixelFormat == NULL)
if (OpenGLEnable() == FALSE)
return(0);
diff --git a/dll/win32/gdi32/objects/bitmap.c b/dll/win32/gdi32/objects/bitmap.c
index 2c7d4cea90c..8d93036c7d9 100644
--- a/dll/win32/gdi32/objects/bitmap.c
+++ b/dll/win32/gdi32/objects/bitmap.c
@@ -34,7 +34,7 @@ DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines )
UINT
FASTCALL
-DIB_BitmapBitsSize( PBITMAPINFO Info )
+DIB_BitmapBitsSize( CONST BITMAPINFO* Info )
{
UINT Ret;
@@ -43,16 +43,16 @@ DIB_BitmapBitsSize( PBITMAPINFO Info )
if ( Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
- Ret = Core->bcHeight *
+ Ret = Core->bcHeight *
((Core->bcWidth * Core->bcPlanes * Core->bcBitCount + 31) & ~31 ) / 8;
}
else /* assume BITMAPINFOHEADER */
{
- if ((Info->bmiHeader.biCompression) &&
+ if ((Info->bmiHeader.biCompression) &&
(Info->bmiHeader.biCompression != BI_BITFIELDS))
return Info->bmiHeader.biSizeImage;
// Make Height positive always....
- Ret = abs(Info->bmiHeader.biHeight) *
+ Ret = abs(Info->bmiHeader.biHeight) *
((Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes * Info->bmiHeader.biBitCount + 31) & ~31 ) / 8;
}
return Ret;
@@ -132,12 +132,12 @@ WINAPI
GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
{
int retSize;
-
+
if (lpbmi->bmiHeader.biSize == FIELD_OFFSET(BITMAPINFOHEADER, biPlanes))
{
/* Calc the bits Size and align it*/
- retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) *
- LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31)
+ retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) *
+ LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31)
& -32) / 8;
}
else
@@ -148,13 +148,13 @@ GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
if (lpbmi->bmiHeader.biHeight >=0 )
{
/* Calc the bits Size and align it*/
- retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth *
+ retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth *
lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8;
}
else
{
/* Make height postiive if it negitve then calc the bits Size and align it*/
- retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth *
+ retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth *
lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8;
}
}
@@ -189,7 +189,7 @@ CreateDIBSection(
{ // Verify header due to converted may == info.
if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
{
- if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
pConvertedInfo->bmiHeader.biCompression == BI_PNG )
{
SetLastError(ERROR_INVALID_PARAMETER);
@@ -319,7 +319,7 @@ CreateBitmapIndirect(const BITMAP *pbm)
(!(pbm->bmWidthBytes & 1)) )
{
-
+
bitmap = CreateBitmap(pbm->bmWidth,
pbm->bmHeight,
pbm->bmPlanes,
@@ -409,7 +409,7 @@ GetDIBits(
{
if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
{
- if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
+ if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
lpbmi->bmiHeader.biCompression == BI_PNG )
{
SetLastError(ERROR_INVALID_PARAMETER);
@@ -461,78 +461,61 @@ CreateDIBitmap( HDC hDC,
LONG width, height, compr, dibsize;
WORD planes, bpp;
// PDC_ATTR pDc_Attr;
- PBITMAPINFO pConvertedInfo;
- UINT ConvertedInfoSize;
- UINT cjBmpScanSize;
- PVOID pvSafeBits = NULL;
+ UINT InfoSize = 0;
+ UINT cjBmpScanSize = 0;
HBITMAP hBmp;
+ NTSTATUS Status = STATUS_SUCCESS;
if (!Header) return 0;
- pConvertedInfo = ConvertBitmapInfo(Data, ColorUse,
- &ConvertedInfoSize, FALSE);
-
if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp, &compr, &dibsize) == -1)
{
GdiSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
- if ( pConvertedInfo )
- {
- if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
- {
- if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
- pConvertedInfo->bmiHeader.biCompression == BI_PNG )
- {
- hBmp = NULL;
- goto Exit;
- }
- }
- }
-
// For Icm support.
// GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
- cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo);
- DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", pConvertedInfo,bpp,dibsize,ConvertedInfoSize,cjBmpScanSize);
+ if(Data)
+ {
+ _SEH2_TRY
+ {
+ cjBmpScanSize = DIB_BitmapBitsSize(Data);
+ CalculateColorTableSize(&Data->bmiHeader, &ColorUse, &InfoSize);
+ InfoSize += Data->bmiHeader.biSize;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+ }
+
+ if(!NT_SUCCESS(Status))
+ {
+ GdiSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", Data,bpp,dibsize,InfoSize,cjBmpScanSize);
if ( !width || !height )
hBmp = GetStockObject(DEFAULT_BITMAP);
else
{
- if ( Bits && Init == CBM_INIT )
- {
- pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
- if (pvSafeBits == NULL)
- {
- hBmp = NULL;
- goto Exit;
- }
- else
- {
- RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize);
- }
- }
-
hBmp = NtGdiCreateDIBitmapInternal(hDC,
width,
height,
Init,
- (LPBYTE)pvSafeBits,
- (PBITMAPINFO)pConvertedInfo,
+ (LPBYTE)Bits,
+ (LPBITMAPINFO)Data,
ColorUse,
- ConvertedInfoSize,
+ InfoSize,
cjBmpScanSize,
0,
0);
-
- if ( Bits && Init == CBM_INIT )
- RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
}
-Exit:
- if (Data != pConvertedInfo)
- RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
return hBmp;
}
@@ -588,7 +571,7 @@ SetDIBits(HDC hDC,
if ( hOldBitmap )
{
- if ( hDC )
+ if ( hDC )
hPal = SelectPalette(SavehDC, (HPALETTE)GetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE), FALSE);
if ( lpbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
@@ -782,7 +765,7 @@ SetDIBitsToDevice(
/*
if ( !pDc_Attr ||
((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
- (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
{
LinesCopied = NtGdiSetDIBitsToDeviceInternal( hdc,
@@ -806,7 +789,7 @@ SetDIBitsToDevice(
RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
if (lpbmi != pConvertedInfo)
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
-
+
return LinesCopied;
}
@@ -886,17 +869,12 @@ StretchDIBits(HDC hdc,
}
}
#endif
- if ( iUsage ) // Save time, we only look at non RGB.
- {
- pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage,
- &ConvertedInfoSize, FALSE);
- if (!pConvertedInfo)
- {
+ pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage,
+ &ConvertedInfoSize, FALSE);
+ if (!pConvertedInfo)
+ {
return 0;
- }
- }
- else
- pConvertedInfo = (PBITMAPINFO)lpBitsInfo;
+ }
cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo);
@@ -933,7 +911,7 @@ StretchDIBits(HDC hdc,
/*
if ( !pDc_Attr ||
((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
- (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
{
LinesCopied = NtGdiStretchDIBitsInternal( hdc,
diff --git a/dll/win32/gdi32/objects/coord.c b/dll/win32/gdi32/objects/coord.c
index 93381e79ece..866108530b9 100644
--- a/dll/win32/gdi32/objects/coord.c
+++ b/dll/win32/gdi32/objects/coord.c
@@ -255,7 +255,7 @@ GetViewportExtEx(
if ((Dc_Attr->flXform & PAGE_EXTENTS_CHANGED) && (Dc_Attr->iMapMode == MM_ISOTROPIC))
// Something was updated, go to kernel.
- return NtGdiGetDCPoint( hdc, GdiGetViewPortExt, (LPPOINT) lpSize );
+ return NtGdiGetDCPoint( hdc, GdiGetViewPortExt, (PPOINTL) lpSize );
else
{
lpSize->cx = Dc_Attr->szlViewportExt.cx;
diff --git a/dll/win32/gdi32/objects/dc.c b/dll/win32/gdi32/objects/dc.c
index ddc33e501f1..7693dcc9592 100644
--- a/dll/win32/gdi32/objects/dc.c
+++ b/dll/win32/gdi32/objects/dc.c
@@ -15,7 +15,7 @@ IntCreateDICW ( LPCWSTR lpwszDriver,
{
UNICODE_STRING Device, Output;
HDC hDC = NULL;
- BOOL Display = FALSE, Default = TRUE;
+ BOOL Display = FALSE, Default = FALSE;
ULONG UMdhpdev = 0;
HANDLE hspool = NULL;
@@ -31,7 +31,7 @@ IntCreateDICW ( LPCWSTR lpwszDriver,
if ((!lpwszDevice) && (!lpwszDriver))
{
- Default = FALSE; // Ask Win32k to set Default device.
+ Default = TRUE; // Ask Win32k to set Default device.
Display = TRUE; // Most likely to be DISPLAY.
}
else
@@ -60,7 +60,7 @@ IntCreateDICW ( LPCWSTR lpwszDriver,
DPRINT1("Not a DISPLAY device! %wZ\n", &Device);
}
- hDC = NtGdiOpenDCW( (Default ? &Device : NULL),
+ hDC = NtGdiOpenDCW( (Default ? NULL : &Device),
(PDEVMODEW) lpInitData,
(lpwszOutput ? &Output : NULL),
iType, // DCW 0 and ICW 1.
@@ -318,7 +318,7 @@ WINAPI
DeleteObject(HGDIOBJ hObject)
{
UINT Type = 0;
-
+
/* From Wine: DeleteObject does not SetLastError() on a null object */
if(!hObject) return FALSE;
@@ -332,7 +332,7 @@ DeleteObject(HGDIOBJ hObject)
Type = GDI_HANDLE_GET_TYPE(hObject);
- if ((Type == GDI_OBJECT_TYPE_METAFILE) ||
+ if ((Type == GDI_OBJECT_TYPE_METAFILE) ||
(Type == GDI_OBJECT_TYPE_ENHMETAFILE))
return FALSE;
@@ -348,7 +348,7 @@ DeleteObject(HGDIOBJ hObject)
case GDI_OBJECT_TYPE_METADC:
return MFDRV_DeleteObject( hObject );
case GDI_OBJECT_TYPE_EMF:
- {
+ {
PLDC pLDC = GdiGetLDC(hObject);
if ( !pLDC ) return FALSE;
return EMFDRV_DeleteObject( hObject );
@@ -533,7 +533,7 @@ GetDeviceCaps(HDC hDC,
return NtGdiGetDeviceCaps(hDC,i);
}
DPRINT("Device CAPS2\n");
-
+
switch (i)
{
case DRIVERVERSION:
@@ -746,7 +746,7 @@ GetAspectRatioFilterEx(
LPSIZE lpAspectRatio
)
{
- return NtGdiGetDCPoint( hdc, GdiGetAspectRatioFilter, (LPPOINT) lpAspectRatio );
+ return NtGdiGetDCPoint( hdc, GdiGetAspectRatioFilter, (PPOINTL) lpAspectRatio );
}
@@ -760,7 +760,7 @@ GetDCOrgEx(
LPPOINT lpPoint
)
{
- return NtGdiGetDCPoint( hdc, GdiGetDCOrg, lpPoint );
+ return NtGdiGetDCPoint( hdc, GdiGetDCOrg, (PPOINTL)lpPoint );
}
@@ -1603,7 +1603,7 @@ SelectObject(HDC hDC,
#if 0
case GDI_OBJECT_TYPE_METADC:
- return MFDRV_SelectObject( hDC, hGdiObj);
+ return MFDRV_SelectObject( hDC, hGdiObj);
case GDI_OBJECT_TYPE_EMF:
PLDC pLDC = GdiGetLDC(hDC);
if ( !pLDC ) return NULL;
diff --git a/dll/win32/gdiplus/brush.c b/dll/win32/gdiplus/brush.c
index b46bdc559b8..74dc833d88d 100644
--- a/dll/win32/gdiplus/brush.c
+++ b/dll/win32/gdiplus/brush.c
@@ -352,6 +352,9 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
if(!line || !startpoint || !endpoint || wrap == WrapModeClamp)
return InvalidParameter;
+ if (startpoint->X == endpoint->X && startpoint->Y == endpoint->Y)
+ return OutOfMemory;
+
*line = GdipAlloc(sizeof(GpLineGradient));
if(!*line) return OutOfMemory;
@@ -428,7 +431,7 @@ GpStatus WINGDIPAPI GdipCreateLineBrushI(GDIPCONST GpPoint* startpoint,
stF.X = (REAL)startpoint->X;
stF.Y = (REAL)startpoint->Y;
endF.X = (REAL)endpoint->X;
- endF.X = (REAL)endpoint->Y;
+ endF.Y = (REAL)endpoint->Y;
return GdipCreateLineBrush(&stF, &endF, startcolor, endcolor, wrap, line);
}
@@ -1494,6 +1497,19 @@ GpStatus WINGDIPAPI GdipSetPathGradientBlend(GpPathGradient *brush, GDIPCONST RE
return NotImplemented;
}
+GpStatus WINGDIPAPI GdipSetPathGradientLinearBlend(GpPathGradient *brush,
+ REAL focus, REAL scale)
+{
+ static int calls;
+
+ TRACE("(%p,%0.2f,%0.2f)\n", brush, focus, scale);
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient *brush,
GDIPCONST ARGB *blend, GDIPCONST REAL *pos, INT count)
{
@@ -1501,6 +1517,20 @@ GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient *brush,
return NotImplemented;
}
+GpStatus WINGDIPAPI GdipGetPathGradientPresetBlend(GpPathGradient *brush,
+ ARGB *blend, REAL *pos, INT count)
+{
+ FIXME("(%p,%p,%p,%i): stub\n", brush, blend, pos, count);
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipGetPathGradientPresetBlendCount(GpPathGradient *brush,
+ INT *count)
+{
+ FIXME("(%p,%p): stub\n", brush, count);
+ return NotImplemented;
+}
+
GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad,
ARGB argb)
{
@@ -1621,6 +1651,84 @@ GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient *grad,
return Ok;
}
+GpStatus WINGDIPAPI GdipSetPathGradientTransform(GpPathGradient *grad,
+ GpMatrix *matrix)
+{
+ static int calls;
+
+ TRACE("(%p,%p)\n", grad, matrix);
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipGetPathGradientTransform(GpPathGradient *grad,
+ GpMatrix *matrix)
+{
+ static int calls;
+
+ TRACE("(%p,%p)\n", grad, matrix);
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipMultiplyPathGradientTransform(GpPathGradient *grad,
+ GDIPCONST GpMatrix *matrix, GpMatrixOrder order)
+{
+ static int calls;
+
+ TRACE("(%p,%p,%i)\n", grad, matrix, order);
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipRotatePathGradientTransform(GpPathGradient *grad,
+ REAL angle, GpMatrixOrder order)
+{
+ static int calls;
+
+ TRACE("(%p,%0.2f,%i)\n", grad, angle, order);
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipScalePathGradientTransform(GpPathGradient *grad,
+ REAL sx, REAL sy, GpMatrixOrder order)
+{
+ static int calls;
+
+ TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, sx, sy, order);
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipTranslatePathGradientTransform(GpPathGradient *grad,
+ REAL dx, REAL dy, GpMatrixOrder order)
+{
+ static int calls;
+
+ TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, dx, dy, order);
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill *sf, ARGB argb)
{
TRACE("(%p, %x)\n", sf, argb);
diff --git a/dll/win32/gdiplus/font.c b/dll/win32/gdiplus/font.c
index 2670e8175dc..843cfb52683 100644
--- a/dll/win32/gdiplus/font.c
+++ b/dll/win32/gdiplus/font.c
@@ -452,12 +452,16 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
GDIPCONST GpGraphics *graphics, REAL *height)
{
REAL dpi;
+ GpStatus stat;
TRACE("%p %p %p\n", font, graphics, height);
- dpi = GetDeviceCaps(graphics->hdc, LOGPIXELSY);
+ stat = GdipGetDpiY((GpGraphics*)graphics, &dpi);
- return GdipGetFontHeightGivenDPI(font, dpi, height);
+ if (stat == Ok)
+ stat = GdipGetFontHeightGivenDPI(font, dpi, height);
+
+ return stat;
}
/*******************************************************************************
diff --git a/dll/win32/gdiplus/gdiplus.c b/dll/win32/gdiplus/gdiplus.c
index 383f53621fb..fb159be55b2 100644
--- a/dll/win32/gdiplus/gdiplus.c
+++ b/dll/win32/gdiplus/gdiplus.c
@@ -121,6 +121,14 @@ void WINAPI GdiplusShutdown(ULONG_PTR token)
/* FIXME: no object tracking */
}
+/* "bricksntiles" expects a return value of 0, which native coincidentally gives */
+ULONG WINAPI GdiplusShutdown_wrapper(ULONG_PTR token)
+{
+ GdiplusShutdown(token);
+
+ return 0;
+}
+
/*****************************************************
* GdipAlloc [GDIPLUS.@]
*/
@@ -314,18 +322,18 @@ GpStatus hresult_to_status(HRESULT res)
}
/* converts a given unit to its value in pixels */
-REAL convert_unit(HDC hdc, GpUnit unit)
+REAL convert_unit(REAL logpixels, GpUnit unit)
{
switch(unit)
{
case UnitInch:
- return (REAL) GetDeviceCaps(hdc, LOGPIXELSX);
+ return logpixels;
case UnitPoint:
- return ((REAL)GetDeviceCaps(hdc, LOGPIXELSX)) / 72.0;
+ return logpixels / 72.0;
case UnitDocument:
- return ((REAL)GetDeviceCaps(hdc, LOGPIXELSX)) / 300.0;
+ return logpixels / 300.0;
case UnitMillimeter:
- return ((REAL)GetDeviceCaps(hdc, LOGPIXELSX)) / 25.4;
+ return logpixels / 25.4;
case UnitWorld:
ERR("cannot convert UnitWorld\n");
return 0.0;
diff --git a/dll/win32/gdiplus/gdiplus.spec b/dll/win32/gdiplus/gdiplus.spec
index bf0de649289..4cf15ab4d5e 100644
--- a/dll/win32/gdiplus/gdiplus.spec
+++ b/dll/win32/gdiplus/gdiplus.spec
@@ -67,7 +67,7 @@
@ stdcall GdipCombineRegionRegion(ptr ptr long)
@ stdcall GdipComment(ptr long ptr)
@ stdcall GdipConvertToEmfPlus(ptr ptr ptr long ptr ptr)
-@ stub GdipConvertToEmfPlusToFile
+@ stdcall GdipConvertToEmfPlusToFile(ptr ptr ptr ptr long ptr ptr)
@ stub GdipConvertToEmfPlusToStream
@ stdcall GdipCreateAdjustableArrowCap(long long long ptr)
@ stub GdipCreateBitmapFromDirectDrawSurface
@@ -215,8 +215,8 @@
@ stub GdipEnumerateMetafileSrcRectDestRectI
@ stdcall GdipFillClosedCurve2(ptr ptr ptr long long long)
@ stdcall GdipFillClosedCurve2I(ptr ptr ptr long long long)
-@ stub GdipFillClosedCurve
-@ stub GdipFillClosedCurveI
+@ stdcall GdipFillClosedCurve(ptr ptr ptr long)
+@ stdcall GdipFillClosedCurveI(ptr ptr ptr long)
@ stdcall GdipFillEllipse(ptr ptr long long long long)
@ stdcall GdipFillEllipseI(ptr ptr long long long long)
@ stdcall GdipFillPath(ptr ptr ptr)
@@ -315,10 +315,10 @@
@ stdcall GdipGetLogFontW(ptr ptr ptr)
@ stdcall GdipGetMatrixElements(ptr ptr)
@ stub GdipGetMetafileDownLevelRasterizationLimit
-@ stub GdipGetMetafileHeaderFromEmf
-@ stub GdipGetMetafileHeaderFromFile
+@ stdcall GdipGetMetafileHeaderFromEmf(ptr ptr)
+@ stdcall GdipGetMetafileHeaderFromFile(wstr ptr)
@ stdcall GdipGetMetafileHeaderFromMetafile(ptr ptr)
-@ stub GdipGetMetafileHeaderFromStream
+@ stdcall GdipGetMetafileHeaderFromStream(ptr ptr)
@ stub GdipGetMetafileHeaderFromWmf
@ stdcall GdipGetNearestColor(ptr ptr)
@ stdcall GdipGetPageScale(ptr ptr)
@@ -334,13 +334,13 @@
@ stdcall GdipGetPathGradientGammaCorrection(ptr ptr)
@ stub GdipGetPathGradientPath
@ stdcall GdipGetPathGradientPointCount(ptr ptr)
-@ stub GdipGetPathGradientPresetBlend
-@ stub GdipGetPathGradientPresetBlendCount
+@ stdcall GdipGetPathGradientPresetBlend(ptr ptr ptr long)
+@ stdcall GdipGetPathGradientPresetBlendCount(ptr ptr)
@ stdcall GdipGetPathGradientRect(ptr ptr)
@ stdcall GdipGetPathGradientRectI(ptr ptr)
@ stdcall GdipGetPathGradientSurroundColorCount(ptr ptr)
@ stdcall GdipGetPathGradientSurroundColorsWithCount(ptr ptr ptr)
-@ stub GdipGetPathGradientTransform
+@ stdcall GdipGetPathGradientTransform(ptr ptr)
@ stdcall GdipGetPathGradientWrapMode(ptr ptr)
@ stdcall GdipGetPathLastPoint(ptr ptr)
@ stdcall GdipGetPathPoints(ptr ptr long)
@@ -351,7 +351,7 @@
@ stdcall GdipGetPenBrushFill(ptr ptr)
@ stdcall GdipGetPenColor(ptr ptr)
@ stub GdipGetPenCompoundArray
-@ stub GdipGetPenCompoundCount
+@ stdcall GdipGetPenCompoundCount(ptr ptr)
@ stdcall GdipGetPenCustomEndCap(ptr ptr)
@ stdcall GdipGetPenCustomStartCap(ptr ptr)
@ stdcall GdipGetPenDashArray(ptr ptr long)
@@ -365,7 +365,7 @@
@ stdcall GdipGetPenMiterLimit(ptr ptr)
@ stdcall GdipGetPenMode(ptr ptr)
@ stdcall GdipGetPenStartCap(ptr ptr)
-@ stub GdipGetPenTransform
+@ stdcall GdipGetPenTransform(ptr ptr)
@ stdcall GdipGetPenUnit(ptr ptr)
@ stdcall GdipGetPenWidth(ptr ptr)
@ stdcall GdipGetPixelOffsetMode(ptr ptr)
@@ -380,9 +380,9 @@
@ stdcall GdipGetRegionData(ptr ptr long ptr)
@ stdcall GdipGetRegionDataSize(ptr ptr)
@ stdcall GdipGetRegionHRgn(ptr ptr ptr)
-@ stub GdipGetRegionScans
+@ stdcall GdipGetRegionScans(ptr ptr ptr ptr)
@ stdcall GdipGetRegionScansCount(ptr ptr ptr)
-@ stub GdipGetRegionScansI
+@ stdcall GdipGetRegionScansI(ptr ptr ptr ptr)
@ stdcall GdipGetRenderingOrigin(ptr ptr ptr)
@ stdcall GdipGetSmoothingMode(ptr ptr)
@ stdcall GdipGetSolidFillColor(ptr ptr)
@@ -444,8 +444,8 @@
@ stdcall GdipMeasureString(ptr wstr long ptr ptr ptr ptr ptr ptr)
@ stdcall GdipMultiplyLineTransform(ptr ptr long)
@ stdcall GdipMultiplyMatrix(ptr ptr long)
-@ stub GdipMultiplyPathGradientTransform
-@ stub GdipMultiplyPenTransform
+@ stdcall GdipMultiplyPathGradientTransform(ptr ptr long)
+@ stdcall GdipMultiplyPenTransform(ptr ptr long)
@ stdcall GdipMultiplyTextureTransform(ptr ptr long)
@ stdcall GdipMultiplyWorldTransform(ptr ptr long)
@ stdcall GdipNewInstalledFontCollection(ptr)
@@ -466,11 +466,11 @@
@ stub GdipPlayTSClientRecord
@ stdcall GdipPrivateAddFontFile(ptr wstr)
@ stdcall GdipPrivateAddMemoryFont(ptr ptr long)
-@ stub GdipRecordMetafile
+@ stdcall GdipRecordMetafile(long long ptr long wstr ptr)
@ stdcall GdipRecordMetafileFileName(wstr long long ptr long wstr ptr)
@ stdcall GdipRecordMetafileFileNameI(wstr long long ptr long wstr ptr)
@ stdcall GdipRecordMetafileI(long long ptr long wstr ptr)
-@ stub GdipRecordMetafileStream
+@ stdcall GdipRecordMetafileStream(ptr long long ptr long wstr ptr)
@ stub GdipRecordMetafileStreamI
@ stdcall GdipReleaseDC(ptr ptr)
@ stdcall GdipRemovePropertyItem(ptr long)
@@ -487,8 +487,8 @@
@ stdcall GdipReversePath(ptr)
@ stdcall GdipRotateLineTransform(ptr long long)
@ stdcall GdipRotateMatrix(ptr long long)
-@ stub GdipRotatePathGradientTransform
-@ stub GdipRotatePenTransform
+@ stdcall GdipRotatePathGradientTransform(ptr long long)
+@ stdcall GdipRotatePenTransform(ptr long long)
@ stdcall GdipRotateTextureTransform(ptr long long)
@ stdcall GdipRotateWorldTransform(ptr long long)
@ stub GdipSaveAdd
@@ -498,7 +498,7 @@
@ stdcall GdipSaveImageToStream(ptr ptr ptr ptr)
@ stdcall GdipScaleLineTransform(ptr long long long)
@ stdcall GdipScaleMatrix(ptr long long long)
-@ stub GdipScalePathGradientTransform
+@ stdcall GdipScalePathGradientTransform(ptr long long long)
@ stdcall GdipScalePenTransform(ptr long long long)
@ stdcall GdipScaleTextureTransform(ptr long long long)
@ stdcall GdipScaleWorldTransform(ptr long long long)
@@ -554,12 +554,12 @@
@ stdcall GdipSetPathGradientCenterPointI(ptr ptr)
@ stdcall GdipSetPathGradientFocusScales(ptr long long)
@ stdcall GdipSetPathGradientGammaCorrection(ptr long)
-@ stub GdipSetPathGradientLinearBlend
+@ stdcall GdipSetPathGradientLinearBlend(ptr long long)
@ stub GdipSetPathGradientPath
@ stdcall GdipSetPathGradientPresetBlend(ptr ptr ptr long)
@ stdcall GdipSetPathGradientSigmaBlend(ptr long long)
@ stdcall GdipSetPathGradientSurroundColorsWithCount(ptr ptr ptr)
-@ stub GdipSetPathGradientTransform
+@ stdcall GdipSetPathGradientTransform(ptr ptr)
@ stdcall GdipSetPathGradientWrapMode(ptr long)
@ stdcall GdipSetPathMarker(ptr)
@ stdcall GdipSetPenBrushFill(ptr ptr)
@@ -577,7 +577,7 @@
@ stdcall GdipSetPenMiterLimit(ptr long)
@ stdcall GdipSetPenMode(ptr long)
@ stdcall GdipSetPenStartCap(ptr long)
-@ stub GdipSetPenTransform
+@ stdcall GdipSetPenTransform(ptr ptr)
@ stub GdipSetPenUnit
@ stdcall GdipSetPenWidth(ptr long)
@ stdcall GdipSetPixelOffsetMode(ptr long)
@@ -613,8 +613,8 @@
@ stdcall GdipTranslateClipI(ptr long long)
@ stdcall GdipTranslateLineTransform(ptr long long long)
@ stdcall GdipTranslateMatrix(ptr long long long)
-@ stub GdipTranslatePathGradientTransform
-@ stub GdipTranslatePenTransform
+@ stdcall GdipTranslatePathGradientTransform(ptr long long long)
+@ stdcall GdipTranslatePenTransform(ptr long long long)
@ stdcall GdipTranslateRegion(ptr long long)
@ stdcall GdipTranslateRegionI(ptr long long)
@ stdcall GdipTranslateTextureTransform(ptr long long long)
@@ -623,8 +623,8 @@
@ stdcall GdipVectorTransformMatrixPointsI(ptr ptr long)
@ stdcall GdipWarpPath(ptr ptr ptr long long long long long long long)
@ stdcall GdipWidenPath(ptr ptr ptr long)
-@ stub GdipWindingModeOutline
+@ stdcall GdipWindingModeOutline(ptr ptr long)
@ stdcall GdiplusNotificationHook(ptr)
@ stdcall GdiplusNotificationUnhook(ptr)
-@ stdcall GdiplusShutdown(ptr)
+@ stdcall GdiplusShutdown(ptr) GdiplusShutdown_wrapper
@ stdcall GdiplusStartup(ptr ptr ptr)
diff --git a/dll/win32/gdiplus/gdiplus_private.h b/dll/win32/gdiplus/gdiplus_private.h
index eafed7c820e..b78e459a3ce 100644
--- a/dll/win32/gdiplus/gdiplus_private.h
+++ b/dll/win32/gdiplus/gdiplus_private.h
@@ -47,7 +47,9 @@ extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
REAL startAngle, REAL sweepAngle);
extern REAL gdiplus_atan2(REAL dy, REAL dx);
extern GpStatus hresult_to_status(HRESULT res);
-extern REAL convert_unit(HDC hdc, GpUnit unit);
+extern REAL convert_unit(REAL logpixels, GpUnit unit);
+
+extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics);
extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
REAL *y1, REAL *x2, REAL *y2);
@@ -150,6 +152,12 @@ struct GpGraphics{
UINT textcontrast; /* not used yet. get/set only */
struct list containers;
GraphicsContainer contid; /* last-issued container ID */
+ /* For giving the caller an HDC when we technically can't: */
+ HBITMAP temp_hbitmap;
+ int temp_hbitmap_width;
+ int temp_hbitmap_height;
+ BYTE *temp_bits;
+ HDC temp_hdc;
};
struct GpBrush{
@@ -269,6 +277,7 @@ struct GpBitmap{
HDC hdc;
BYTE *bits; /* actual image bits if this is a DIB */
INT stride; /* stride of bits if this is a DIB */
+ BYTE *own_bits; /* image bits that need to be freed with this object */
};
struct GpCachedBitmap{
diff --git a/dll/win32/gdiplus/graphics.c b/dll/win32/gdiplus/graphics.c
index 2d512abdc6c..e85a8ba3614 100644
--- a/dll/win32/gdiplus/graphics.c
+++ b/dll/win32/gdiplus/graphics.c
@@ -84,14 +84,22 @@ static BYTE convert_path_point_type(BYTE type)
return ret;
}
+static REAL graphics_res(GpGraphics *graphics)
+{
+ if (graphics->image) return graphics->image->xres;
+ else return (REAL)GetDeviceCaps(graphics->hdc, LOGPIXELSX);
+}
+
static INT prepare_dc(GpGraphics *graphics, GpPen *pen)
{
HPEN gdipen;
REAL width;
- INT save_state = SaveDC(graphics->hdc), i, numdashes;
+ INT save_state, i, numdashes;
GpPointF pt[2];
DWORD dash_array[MAX_DASHLEN];
+ save_state = SaveDC(graphics->hdc);
+
EndPath(graphics->hdc);
if(pen->unit == UnitPixel){
@@ -108,7 +116,7 @@ static INT prepare_dc(GpGraphics *graphics, GpPen *pen)
width = sqrt((pt[1].X - pt[0].X) * (pt[1].X - pt[0].X) +
(pt[1].Y - pt[0].Y) * (pt[1].Y - pt[0].Y)) / sqrt(2.0);
- width *= pen->width * convert_unit(graphics->hdc,
+ width *= pen->width * convert_unit(graphics_res(graphics),
pen->unit == UnitWorld ? graphics->unit : pen->unit);
}
@@ -156,7 +164,7 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
GpMatrix *matrix;
int i;
- unitscale = convert_unit(graphics->hdc, graphics->unit);
+ unitscale = convert_unit(graphics_res(graphics), graphics->unit);
/* apply page scale */
if(graphics->unit != UnitDisplay)
@@ -1131,6 +1139,8 @@ static GpStatus restore_container(GpGraphics* graphics,
static GpStatus get_graphics_bounds(GpGraphics* graphics, GpRectF* rect)
{
RECT wnd_rect;
+ GpStatus stat=Ok;
+ GpUnit unit;
if(graphics->hwnd) {
if(!GetClientRect(graphics->hwnd, &wnd_rect))
@@ -1140,6 +1150,10 @@ static GpStatus get_graphics_bounds(GpGraphics* graphics, GpRectF* rect)
rect->Y = wnd_rect.top;
rect->Width = wnd_rect.right - wnd_rect.left;
rect->Height = wnd_rect.bottom - wnd_rect.top;
+ }else if (graphics->image){
+ stat = GdipGetImageBounds(graphics->image, rect, &unit);
+ if (stat == Ok && unit != UnitPixel)
+ FIXME("need to convert from unit %i\n", unit);
}else{
rect->X = 0;
rect->Y = 0;
@@ -1147,7 +1161,7 @@ static GpStatus get_graphics_bounds(GpGraphics* graphics, GpRectF* rect)
rect->Height = GetDeviceCaps(graphics->hdc, VERTRES);
}
- return Ok;
+ return stat;
}
/* on success, rgn will contain the region of the graphics object which
@@ -1235,6 +1249,45 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra
return Ok;
}
+GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics)
+{
+ GpStatus retval;
+
+ *graphics = GdipAlloc(sizeof(GpGraphics));
+ if(!*graphics) return OutOfMemory;
+
+ if((retval = GdipCreateMatrix(&(*graphics)->worldtrans)) != Ok){
+ GdipFree(*graphics);
+ return retval;
+ }
+
+ if((retval = GdipCreateRegion(&(*graphics)->clip)) != Ok){
+ GdipFree((*graphics)->worldtrans);
+ GdipFree(*graphics);
+ return retval;
+ }
+
+ (*graphics)->hdc = NULL;
+ (*graphics)->hwnd = NULL;
+ (*graphics)->owndc = FALSE;
+ (*graphics)->image = image;
+ (*graphics)->smoothing = SmoothingModeDefault;
+ (*graphics)->compqual = CompositingQualityDefault;
+ (*graphics)->interpolation = InterpolationModeDefault;
+ (*graphics)->pixeloffset = PixelOffsetModeDefault;
+ (*graphics)->compmode = CompositingModeSourceOver;
+ (*graphics)->unit = UnitDisplay;
+ (*graphics)->scale = 1.0;
+ (*graphics)->busy = FALSE;
+ (*graphics)->textcontrast = 4;
+ list_init(&(*graphics)->containers);
+ (*graphics)->contid = 0;
+
+ TRACE("<-- %p\n", *graphics);
+
+ return Ok;
+}
+
GpStatus WINGDIPAPI GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics)
{
GpStatus ret;
@@ -1446,6 +1499,12 @@ GpStatus WINGDIPAPI GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x,
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
num_pts = arc2polybezier(points, x, y, width, height, startAngle, sweepAngle);
save_state = prepare_dc(graphics, pen);
@@ -1482,6 +1541,12 @@ GpStatus WINGDIPAPI GdipDrawBezier(GpGraphics *graphics, GpPen *pen, REAL x1,
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
pt[0].X = x1;
pt[0].Y = y1;
pt[1].X = x2;
@@ -1516,6 +1581,12 @@ GpStatus WINGDIPAPI GdipDrawBezierI(GpGraphics *graphics, GpPen *pen, INT x1,
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
pt[0].X = x1;
pt[0].Y = y1;
pt[1].X = x2;
@@ -1722,6 +1793,12 @@ GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics *graphics, GpPen *pen,
if(count < 2)
return InvalidParameter;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
pt = GdipAlloc(len_pt * sizeof(GpPointF));
if(!pt)
return OutOfMemory;
@@ -1837,6 +1914,12 @@ GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x,
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
ptf[0].X = x;
ptf[0].Y = y;
ptf[1].X = x + width;
@@ -1961,6 +2044,11 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
if (image->picture)
{
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ }
+
/* FIXME: partially implemented (only works for rectangular parallelograms) */
if(srcUnit == UnitInch)
dx = dy = (REAL) INCH_HIMETRIC;
@@ -1983,7 +2071,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
return GenericError;
}
}
- else if (image->type == ImageTypeBitmap && ((GpBitmap*)image)->hbitmap)
+ else if (image->type == ImageTypeBitmap)
{
GpBitmap* bitmap = (GpBitmap*)image;
int use_software=0;
@@ -1997,6 +2085,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
if (imageAttributes ||
(graphics->image && graphics->image->type == ImageTypeBitmap) ||
+ !((GpBitmap*)image)->hbitmap ||
ptf[1].Y != ptf[0].Y || ptf[2].X != ptf[0].X)
use_software = 1;
@@ -2383,6 +2472,12 @@ GpStatus WINGDIPAPI GdipDrawLine(GpGraphics *graphics, GpPen *pen, REAL x1,
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
pt[0].X = x1;
pt[0].Y = y1;
pt[1].X = x2;
@@ -2412,6 +2507,12 @@ GpStatus WINGDIPAPI GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1,
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
pt[0].X = (REAL)x1;
pt[0].Y = (REAL)y1;
pt[1].X = (REAL)x2;
@@ -2440,6 +2541,12 @@ GpStatus WINGDIPAPI GdipDrawLines(GpGraphics *graphics, GpPen *pen, GDIPCONST
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
save_state = prepare_dc(graphics, pen);
retval = draw_polyline(graphics, pen, points, count, TRUE);
@@ -2465,6 +2572,12 @@ GpStatus WINGDIPAPI GdipDrawLinesI(GpGraphics *graphics, GpPen *pen, GDIPCONST
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
ptf = GdipAlloc(count * sizeof(GpPointF));
if(!ptf) return OutOfMemory;
@@ -2496,6 +2609,12 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
save_state = prepare_dc(graphics, pen);
retval = draw_poly(graphics, pen, path->pathdata.Points,
@@ -2520,6 +2639,12 @@ GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x,
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
save_state = prepare_dc(graphics, pen);
SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH));
@@ -2554,6 +2679,12 @@ GpStatus WINGDIPAPI GdipDrawRectangle(GpGraphics *graphics, GpPen *pen, REAL x,
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
ptf[0].X = x;
ptf[0].Y = y;
ptf[1].X = x + width;
@@ -2597,6 +2728,12 @@ GpStatus WINGDIPAPI GdipDrawRectangles(GpGraphics *graphics, GpPen *pen,
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
ptf = GdipAlloc(4 * count * sizeof(GpPointF));
pti = GdipAlloc(4 * count * sizeof(POINT));
@@ -2673,6 +2810,9 @@ GpStatus WINGDIPAPI GdipFillClosedCurve2(GpGraphics *graphics, GpBrush *brush,
if(graphics->busy)
return ObjectBusy;
+ if(count == 1) /* Do nothing */
+ return Ok;
+
stat = GdipCreatePath(fill, &path);
if(stat != Ok)
return stat;
@@ -2704,9 +2844,12 @@ GpStatus WINGDIPAPI GdipFillClosedCurve2I(GpGraphics *graphics, GpBrush *brush,
TRACE("(%p, %p, %p, %d, %.2f, %d)\n", graphics, brush, points,
count, tension, fill);
- if(!points || count <= 0)
+ if(!points || count == 0)
return InvalidParameter;
+ if(count == 1) /* Do nothing */
+ return Ok;
+
ptf = GdipAlloc(sizeof(GpPointF)*count);
if(!ptf)
return OutOfMemory;
@@ -2723,6 +2866,22 @@ GpStatus WINGDIPAPI GdipFillClosedCurve2I(GpGraphics *graphics, GpBrush *brush,
return stat;
}
+GpStatus WINGDIPAPI GdipFillClosedCurve(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPointF *points, INT count)
+{
+ TRACE("(%p, %p, %p, %d)\n", graphics, brush, points, count);
+ return GdipFillClosedCurve2(graphics, brush, points, count,
+ 0.5f, FillModeAlternate);
+}
+
+GpStatus WINGDIPAPI GdipFillClosedCurveI(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPoint *points, INT count)
+{
+ TRACE("(%p, %p, %p, %d)\n", graphics, brush, points, count);
+ return GdipFillClosedCurve2I(graphics, brush, points, count,
+ 0.5f, FillModeAlternate);
+}
+
GpStatus WINGDIPAPI GdipFillEllipse(GpGraphics *graphics, GpBrush *brush, REAL x,
REAL y, REAL width, REAL height)
{
@@ -2738,6 +2897,12 @@ GpStatus WINGDIPAPI GdipFillEllipse(GpGraphics *graphics, GpBrush *brush, REAL x
if(graphics->busy)
return ObjectBusy;
+ if(!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
ptf[0].X = x;
ptf[0].Y = y;
ptf[1].X = x + width;
@@ -2780,6 +2945,12 @@ GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *p
if(graphics->busy)
return ObjectBusy;
+ if(!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
SetPolyFillMode(graphics->hdc, (path->fill == FillModeAlternate ? ALTERNATE
@@ -2817,6 +2988,12 @@ GpStatus WINGDIPAPI GdipFillPie(GpGraphics *graphics, GpBrush *brush, REAL x,
if(graphics->busy)
return ObjectBusy;
+ if(!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
@@ -2856,6 +3033,12 @@ GpStatus WINGDIPAPI GdipFillPolygon(GpGraphics *graphics, GpBrush *brush,
if(graphics->busy)
return ObjectBusy;
+ if(!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
ptf = GdipAlloc(count * sizeof(GpPointF));
pti = GdipAlloc(count * sizeof(POINT));
if(!ptf || !pti){
@@ -2903,6 +3086,12 @@ GpStatus WINGDIPAPI GdipFillPolygonI(GpGraphics *graphics, GpBrush *brush,
if(graphics->busy)
return ObjectBusy;
+ if(!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
ptf = GdipAlloc(count * sizeof(GpPointF));
pti = GdipAlloc(count * sizeof(POINT));
if(!ptf || !pti){
@@ -2968,6 +3157,12 @@ GpStatus WINGDIPAPI GdipFillRectangle(GpGraphics *graphics, GpBrush *brush,
if(graphics->busy)
return ObjectBusy;
+ if(!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
ptf[0].X = x;
ptf[0].Y = y;
ptf[1].X = x + width;
@@ -3008,6 +3203,12 @@ GpStatus WINGDIPAPI GdipFillRectangleI(GpGraphics *graphics, GpBrush *brush,
if(graphics->busy)
return ObjectBusy;
+ if(!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
ptf[0].X = x;
ptf[0].Y = y;
ptf[1].X = x + width;
@@ -3100,6 +3301,12 @@ GpStatus WINGDIPAPI GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
if(graphics->busy)
return ObjectBusy;
+ if(!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
status = GdipGetRegionHRgn(region, graphics, &hrgn);
if(status != Ok)
return status;
@@ -3700,6 +3907,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
int i;
HFONT oldfont;
struct measure_ranges_args args;
+ HDC temp_hdc=NULL;
TRACE("(%p %s %d %p %s %p %d %p)\n", graphics, debugstr_w(string),
length, font, debugstr_rectf(layoutRect), stringFormat, regionCount, regions);
@@ -3710,6 +3918,12 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
if (regionCount < stringFormat->range_count)
return InvalidParameter;
+ if(!graphics->hdc)
+ {
+ temp_hdc = graphics->hdc = CreateCompatibleDC(0);
+ if (!temp_hdc) return OutOfMemory;
+ }
+
if (stringFormat->attr)
TRACE("may be ignoring some format flags: attr %x\n", stringFormat->attr);
@@ -3729,6 +3943,12 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
DeleteObject(SelectObject(graphics->hdc, oldfont));
+ if (temp_hdc)
+ {
+ graphics->hdc = NULL;
+ DeleteDC(temp_hdc);
+ }
+
return stat;
}
@@ -3771,6 +3991,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
{
HFONT oldfont;
struct measure_string_args args;
+ HDC temp_hdc=NULL;
TRACE("(%p, %s, %i, %p, %s, %p, %p, %p, %p)\n", graphics,
debugstr_wn(string, length), length, font, debugstr_rectf(rect), format,
@@ -3779,6 +4000,12 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
if(!graphics || !string || !font || !rect || !bounds)
return InvalidParameter;
+ if(!graphics->hdc)
+ {
+ temp_hdc = graphics->hdc = CreateCompatibleDC(0);
+ if (!temp_hdc) return OutOfMemory;
+ }
+
if(linesfilled) *linesfilled = 0;
if(codepointsfitted) *codepointsfitted = 0;
@@ -3801,6 +4028,12 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
DeleteObject(SelectObject(graphics->hdc, oldfont));
+ if (temp_hdc)
+ {
+ graphics->hdc = NULL;
+ DeleteDC(temp_hdc);
+ }
+
return Ok;
}
@@ -3852,6 +4085,12 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
return NotImplemented;
}
+ if(!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
if(format){
TRACE("may be ignoring some format flags: attr %x\n", format->attr);
@@ -4415,6 +4654,12 @@ GpStatus WINGDIPAPI GdipDrawPolygon(GpGraphics *graphics,GpPen *pen,GDIPCONST Gp
if(graphics->busy)
return ObjectBusy;
+ if (!graphics->hdc)
+ {
+ FIXME("graphics object has no HDC\n");
+ return Ok;
+ }
+
pti = GdipAlloc(sizeof(POINT) * count);
save_state = prepare_dc(graphics, pen);
@@ -4462,7 +4707,10 @@ GpStatus WINGDIPAPI GdipGetDpiX(GpGraphics *graphics, REAL* dpi)
if(graphics->busy)
return ObjectBusy;
- *dpi = (REAL)GetDeviceCaps(graphics->hdc, LOGPIXELSX);
+ if (graphics->image)
+ *dpi = graphics->image->xres;
+ else
+ *dpi = (REAL)GetDeviceCaps(graphics->hdc, LOGPIXELSX);
return Ok;
}
@@ -4477,7 +4725,10 @@ GpStatus WINGDIPAPI GdipGetDpiY(GpGraphics *graphics, REAL* dpi)
if(graphics->busy)
return ObjectBusy;
- *dpi = (REAL)GetDeviceCaps(graphics->hdc, LOGPIXELSY);
+ if (graphics->image)
+ *dpi = graphics->image->yres;
+ else
+ *dpi = (REAL)GetDeviceCaps(graphics->hdc, LOGPIXELSY);
return Ok;
}
@@ -4505,6 +4756,9 @@ GpStatus WINGDIPAPI GdipMultiplyWorldTransform(GpGraphics *graphics, GDIPCONST G
return ret;
}
+/* Color used to fill bitmaps so we can tell which parts have been drawn over by gdi32. */
+static const COLORREF DC_BACKGROUND_KEY = 0x0c0b0d;
+
GpStatus WINGDIPAPI GdipGetDC(GpGraphics *graphics, HDC *hdc)
{
TRACE("(%p, %p)\n", graphics, hdc);
@@ -4515,7 +4769,61 @@ GpStatus WINGDIPAPI GdipGetDC(GpGraphics *graphics, HDC *hdc)
if(graphics->busy)
return ObjectBusy;
- *hdc = graphics->hdc;
+ if (!graphics->hdc ||
+ (graphics->image && graphics->image->type == ImageTypeBitmap && ((GpBitmap*)graphics->image)->format & PixelFormatAlpha))
+ {
+ /* Create a fake HDC and fill it with a constant color. */
+ HDC temp_hdc;
+ HBITMAP hbitmap;
+ GpStatus stat;
+ GpRectF bounds;
+ BITMAPINFOHEADER bmih;
+ int i;
+
+ stat = get_graphics_bounds(graphics, &bounds);
+ if (stat != Ok)
+ return stat;
+
+ graphics->temp_hbitmap_width = bounds.Width;
+ graphics->temp_hbitmap_height = bounds.Height;
+
+ bmih.biSize = sizeof(bmih);
+ bmih.biWidth = graphics->temp_hbitmap_width;
+ bmih.biHeight = -graphics->temp_hbitmap_height;
+ bmih.biPlanes = 1;
+ bmih.biBitCount = 32;
+ bmih.biCompression = BI_RGB;
+ bmih.biSizeImage = 0;
+ bmih.biXPelsPerMeter = 0;
+ bmih.biYPelsPerMeter = 0;
+ bmih.biClrUsed = 0;
+ bmih.biClrImportant = 0;
+
+ hbitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS,
+ (void**)&graphics->temp_bits, NULL, 0);
+ if (!hbitmap)
+ return GenericError;
+
+ temp_hdc = CreateCompatibleDC(0);
+ if (!temp_hdc)
+ {
+ DeleteObject(hbitmap);
+ return GenericError;
+ }
+
+ for (i=0; i<(graphics->temp_hbitmap_width * graphics->temp_hbitmap_height); i++)
+ ((DWORD*)graphics->temp_bits)[i] = DC_BACKGROUND_KEY;
+
+ SelectObject(temp_hdc, hbitmap);
+
+ graphics->temp_hbitmap = hbitmap;
+ *hdc = graphics->temp_hdc = temp_hdc;
+ }
+ else
+ {
+ *hdc = graphics->hdc;
+ }
+
graphics->busy = TRUE;
return Ok;
@@ -4525,12 +4833,40 @@ GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics *graphics, HDC hdc)
{
TRACE("(%p, %p)\n", graphics, hdc);
- if(!graphics)
+ if(!graphics || !hdc)
return InvalidParameter;
- if(graphics->hdc != hdc || !(graphics->busy))
+ if((graphics->hdc != hdc && graphics->temp_hdc != hdc) || !(graphics->busy))
return InvalidParameter;
+ if (graphics->temp_hdc == hdc)
+ {
+ DWORD* pos;
+ int i;
+
+ /* Find the pixels that have changed, and mark them as opaque. */
+ pos = (DWORD*)graphics->temp_bits;
+ for (i=0; i<(graphics->temp_hbitmap_width * graphics->temp_hbitmap_height); i++)
+ {
+ if (*pos != DC_BACKGROUND_KEY)
+ {
+ *pos |= 0xff000000;
+ }
+ pos++;
+ }
+
+ /* Write the changed pixels to the real target. */
+ alpha_blend_pixels(graphics, 0, 0, graphics->temp_bits,
+ graphics->temp_hbitmap_width, graphics->temp_hbitmap_height,
+ graphics->temp_hbitmap_width * 4);
+
+ /* Clean up. */
+ DeleteDC(graphics->temp_hdc);
+ DeleteObject(graphics->temp_hbitmap);
+ graphics->temp_hdc = NULL;
+ graphics->temp_hbitmap = NULL;
+ }
+
graphics->busy = FALSE;
return Ok;
@@ -4580,7 +4916,7 @@ GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace
stat = GdipCreateMatrix(&matrix);
if (stat == Ok)
{
- unitscale = convert_unit(graphics->hdc, graphics->unit);
+ unitscale = convert_unit(graphics_res(graphics), graphics->unit);
if(graphics->unit != UnitDisplay)
unitscale *= graphics->scale;
diff --git a/dll/win32/gdiplus/graphicspath.c b/dll/win32/gdiplus/graphicspath.c
index 60ddda1d7b5..983ead95008 100644
--- a/dll/win32/gdiplus/graphicspath.c
+++ b/dll/win32/gdiplus/graphicspath.c
@@ -364,7 +364,7 @@ GpStatus WINGDIPAPI GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *po
}
/* points [len_pt-2] and [0] are calculated
- separetely to connect splines properly */
+ separately to connect splines properly */
pts[0] = points[count-1];
pts[1] = points[0]; /* equals to start and end of a resulting path */
pts[2] = points[1];
@@ -1653,3 +1653,9 @@ GpStatus WINGDIPAPI GdipClearPathMarkers(GpPath* path)
return Ok;
}
+
+GpStatus WINGDIPAPI GdipWindingModeOutline(GpPath *path, GpMatrix *matrix, REAL flatness)
+{
+ FIXME("stub: %p, %p, %.2f\n", path, matrix, flatness);
+ return NotImplemented;
+}
diff --git a/dll/win32/gdiplus/image.c b/dll/win32/gdiplus/image.c
index d72ae8d3775..69f58659a28 100644
--- a/dll/win32/gdiplus/image.c
+++ b/dll/win32/gdiplus/image.c
@@ -1626,11 +1626,10 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
PixelFormat format, BYTE* scan0, GpBitmap** bitmap)
{
BITMAPINFO* pbmi;
- HBITMAP hbitmap;
+ HBITMAP hbitmap=NULL;
INT row_size, dib_stride;
HDC hdc;
- BYTE *bits;
- int i;
+ BYTE *bits=NULL, *own_bits=NULL;
REAL xres, yres;
GpStatus stat;
@@ -1655,46 +1654,62 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
if(stride == 0)
stride = dib_stride;
- pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
- if (!pbmi)
- return OutOfMemory;
+ if (format & PixelFormatGDI && !(format & (PixelFormatAlpha|PixelFormatIndexed)) && !scan0)
+ {
+ pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+ if (!pbmi)
+ return OutOfMemory;
- pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmi->bmiHeader.biWidth = width;
- pbmi->bmiHeader.biHeight = -height;
- pbmi->bmiHeader.biPlanes = 1;
- /* FIXME: use the rest of the data from format */
- pbmi->bmiHeader.biBitCount = PIXELFORMATBPP(format);
- pbmi->bmiHeader.biCompression = BI_RGB;
- pbmi->bmiHeader.biSizeImage = 0;
- pbmi->bmiHeader.biXPelsPerMeter = 0;
- pbmi->bmiHeader.biYPelsPerMeter = 0;
- pbmi->bmiHeader.biClrUsed = 0;
- pbmi->bmiHeader.biClrImportant = 0;
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biWidth = width;
+ pbmi->bmiHeader.biHeight = -height;
+ pbmi->bmiHeader.biPlanes = 1;
+ /* FIXME: use the rest of the data from format */
+ pbmi->bmiHeader.biBitCount = PIXELFORMATBPP(format);
+ pbmi->bmiHeader.biCompression = BI_RGB;
+ pbmi->bmiHeader.biSizeImage = 0;
+ pbmi->bmiHeader.biXPelsPerMeter = 0;
+ pbmi->bmiHeader.biYPelsPerMeter = 0;
+ pbmi->bmiHeader.biClrUsed = 0;
+ pbmi->bmiHeader.biClrImportant = 0;
- hdc = CreateCompatibleDC(NULL);
- if (!hdc) {
+ hdc = CreateCompatibleDC(NULL);
+ if (!hdc) {
+ GdipFree(pbmi);
+ return GenericError;
+ }
+
+ hbitmap = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+
+ DeleteDC(hdc);
GdipFree(pbmi);
- return GenericError;
+
+ if (!hbitmap) return GenericError;
+
+ stride = dib_stride;
}
+ else
+ {
+ /* Not a GDI format; don't try to make an HBITMAP. */
+ if (scan0)
+ bits = scan0;
+ else
+ {
+ INT size = abs(stride) * height;
- hbitmap = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+ own_bits = bits = GdipAlloc(size);
+ if (!own_bits) return OutOfMemory;
- DeleteDC(hdc);
- GdipFree(pbmi);
-
- if (!hbitmap) return GenericError;
-
- /* copy bits to the dib if necessary */
- /* FIXME: should reference the bits instead of copying them */
- if (scan0)
- for (i=0; ihbitmap = hbitmap;
(*bitmap)->hdc = NULL;
(*bitmap)->bits = bits;
- (*bitmap)->stride = dib_stride;
+ (*bitmap)->stride = stride;
+ (*bitmap)->own_bits = own_bits;
+
+ /* set format-related flags */
+ if (format & (PixelFormatAlpha|PixelFormatPAlpha|PixelFormatIndexed))
+ (*bitmap)->image.flags |= ImageFlagsHasAlpha;
if (format == PixelFormat1bppIndexed ||
format == PixelFormat4bppIndexed ||
@@ -1916,6 +1936,7 @@ static void move_bitmap(GpBitmap *dst, GpBitmap *src, BOOL clobber_palette)
dst->hdc = src->hdc;
dst->bits = src->bits;
dst->stride = src->stride;
+ dst->own_bits = src->own_bits;
GdipFree(src);
}
@@ -1927,15 +1948,22 @@ GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
if(!image)
return InvalidParameter;
- if (image->picture)
- IPicture_Release(image->picture);
if (image->type == ImageTypeBitmap)
{
GdipFree(((GpBitmap*)image)->bitmapbits);
+ GdipFree(((GpBitmap*)image)->own_bits);
DeleteDC(((GpBitmap*)image)->hdc);
DeleteObject(((GpBitmap*)image)->hbitmap);
}
+ else if (image->type != ImageTypeMetafile)
+ {
+ WARN("invalid image: %p\n", image);
+ return ObjectBusy;
+ }
+ if (image->picture)
+ IPicture_Release(image->picture);
GdipFree(image->palette_entries);
+ image->type = ~0;
GdipFree(image);
return Ok;
@@ -2008,14 +2036,15 @@ GpStatus WINGDIPAPI GdipGetImageDimension(GpImage *image, REAL *width,
if(image->type == ImageTypeMetafile){
HDC hdc = GetDC(0);
-
- *height = convert_unit(hdc, ((GpMetafile*)image)->unit) *
- ((GpMetafile*)image)->bounds.Height;
-
- *width = convert_unit(hdc, ((GpMetafile*)image)->unit) *
- ((GpMetafile*)image)->bounds.Width;
+ REAL res = (REAL)GetDeviceCaps(hdc, LOGPIXELSX);
ReleaseDC(0, hdc);
+
+ *height = convert_unit(res, ((GpMetafile*)image)->unit) *
+ ((GpMetafile*)image)->bounds.Height;
+
+ *width = convert_unit(res, ((GpMetafile*)image)->unit) *
+ ((GpMetafile*)image)->bounds.Width;
}
else if(image->type == ImageTypeBitmap){
@@ -2047,18 +2076,23 @@ GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
return NotImplemented;
}
- hdc = ((GpBitmap*)image)->hdc;
+ if (((GpBitmap*)image)->hbitmap)
+ {
+ hdc = ((GpBitmap*)image)->hdc;
- if(!hdc){
- hdc = CreateCompatibleDC(0);
- SelectObject(hdc, ((GpBitmap*)image)->hbitmap);
- ((GpBitmap*)image)->hdc = hdc;
+ if(!hdc){
+ hdc = CreateCompatibleDC(0);
+ SelectObject(hdc, ((GpBitmap*)image)->hbitmap);
+ ((GpBitmap*)image)->hdc = hdc;
+ }
+
+ stat = GdipCreateFromHDC(hdc, graphics);
+
+ if (stat == Ok)
+ (*graphics)->image = image;
}
-
- stat = GdipCreateFromHDC(hdc, graphics);
-
- if (stat == Ok)
- (*graphics)->image = image;
+ else
+ stat = graphics_from_image(image, graphics);
return stat;
}
@@ -2072,11 +2106,12 @@ GpStatus WINGDIPAPI GdipGetImageHeight(GpImage *image, UINT *height)
if(image->type == ImageTypeMetafile){
HDC hdc = GetDC(0);
-
- *height = roundr(convert_unit(hdc, ((GpMetafile*)image)->unit) *
- ((GpMetafile*)image)->bounds.Height);
+ REAL res = (REAL)GetDeviceCaps(hdc, LOGPIXELSX);
ReleaseDC(0, hdc);
+
+ *height = roundr(convert_unit(res, ((GpMetafile*)image)->unit) *
+ ((GpMetafile*)image)->bounds.Height);
}
else if(image->type == ImageTypeBitmap)
*height = ((GpBitmap*)image)->height;
@@ -2178,11 +2213,12 @@ GpStatus WINGDIPAPI GdipGetImageWidth(GpImage *image, UINT *width)
if(image->type == ImageTypeMetafile){
HDC hdc = GetDC(0);
-
- *width = roundr(convert_unit(hdc, ((GpMetafile*)image)->unit) *
- ((GpMetafile*)image)->bounds.Width);
+ REAL res = (REAL)GetDeviceCaps(hdc, LOGPIXELSX);
ReleaseDC(0, hdc);
+
+ *width = roundr(convert_unit(res, ((GpMetafile*)image)->unit) *
+ ((GpMetafile*)image)->bounds.Width);
}
else if(image->type == ImageTypeBitmap)
*width = ((GpBitmap*)image)->width;
@@ -2566,6 +2602,18 @@ static GpStatus decode_image_wic(IStream* stream, REFCLSID clsid, GpImage **imag
*image = NULL;
GdipDisposeImage((GpImage*)bitmap);
}
+
+ if (SUCCEEDED(hr) && status == Ok)
+ {
+ double dpix, dpiy;
+ hr = IWICBitmapSource_GetResolution(source, &dpix, &dpiy);
+ if (SUCCEEDED(hr))
+ {
+ bitmap->image.xres = dpix;
+ bitmap->image.yres = dpiy;
+ }
+ hr = S_OK;
+ }
}
IWICBitmapSource_Release(source);
@@ -2581,6 +2629,12 @@ end:
if (FAILED(hr) && status == Ok) status = hresult_to_status(hr);
+ if (status == Ok)
+ {
+ /* Native GDI+ used to be smarter, but since Win7 it just sets these flags. */
+ bitmap->image.flags |= ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI|ImageFlagsColorSpaceRGB;
+ }
+
return status;
}
@@ -3756,3 +3810,16 @@ GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
return stat;
}
+
+/*****************************************************************************
+ * GdipConvertToEmfPlusToFile [GDIPLUS.@]
+ */
+
+GpStatus WINGDIPAPI GdipConvertToEmfPlusToFile(const GpGraphics* refGraphics,
+ GpMetafile* metafile, BOOL* conversionSuccess,
+ const WCHAR* filename, EmfType emfType,
+ const WCHAR* description, GpMetafile** out_metafile)
+{
+ FIXME("stub: %p, %p, %p, %p, %u, %p, %p\n", refGraphics, metafile, conversionSuccess, filename, emfType, description, out_metafile);
+ return NotImplemented;
+}
diff --git a/dll/win32/gdiplus/pen.c b/dll/win32/gdiplus/pen.c
index 53e47f08f77..a022cfb64e0 100644
--- a/dll/win32/gdiplus/pen.c
+++ b/dll/win32/gdiplus/pen.c
@@ -404,6 +404,51 @@ GpStatus WINGDIPAPI GdipResetPenTransform(GpPen *pen)
return NotImplemented;
}
+GpStatus WINGDIPAPI GdipSetPenTransform(GpPen *pen, GpMatrix *matrix)
+{
+ static int calls;
+
+ TRACE("(%p,%p)\n", pen, matrix);
+
+ if(!pen || !matrix)
+ return InvalidParameter;
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipGetPenTransform(GpPen *pen, GpMatrix *matrix)
+{
+ static int calls;
+
+ TRACE("(%p,%p)\n", pen, matrix);
+
+ if(!pen || !matrix)
+ return InvalidParameter;
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipTranslatePenTransform(GpPen *pen, REAL dx, REAL dy, GpMatrixOrder order)
+{
+ static int calls;
+
+ TRACE("(%p,%0.2f,%0.2f,%u)\n", pen, dx, dy, order);
+
+ if(!pen)
+ return InvalidParameter;
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
GpStatus WINGDIPAPI GdipScalePenTransform(GpPen *pen, REAL sx, REAL sy, GpMatrixOrder order)
{
static int calls;
@@ -419,6 +464,21 @@ GpStatus WINGDIPAPI GdipScalePenTransform(GpPen *pen, REAL sx, REAL sy, GpMatrix
return NotImplemented;
}
+GpStatus WINGDIPAPI GdipRotatePenTransform(GpPen *pen, REAL angle, GpMatrixOrder order)
+{
+ static int calls;
+
+ TRACE("(%p,%0.2f,%u)\n", pen, angle, order);
+
+ if(!pen)
+ return InvalidParameter;
+
+ if(!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
GpStatus WINGDIPAPI GdipMultiplyPenTransform(GpPen *pen, GDIPCONST GpMatrix *matrix,
GpMatrixOrder order)
{
diff --git a/dll/win32/gdiplus/region.c b/dll/win32/gdiplus/region.c
index decaaf9e837..f11f3ca3669 100644
--- a/dll/win32/gdiplus/region.c
+++ b/dll/win32/gdiplus/region.c
@@ -884,6 +884,7 @@ GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
{
HDC new_hdc=NULL;
+ GpGraphics *new_graphics=NULL;
GpStatus stat;
INT save_state;
@@ -893,13 +894,20 @@ static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
if (!new_hdc)
return OutOfMemory;
- stat = GdipCreateFromHDC(new_hdc, &graphics);
+ stat = GdipCreateFromHDC(new_hdc, &new_graphics);
+ graphics = new_graphics;
if (stat != Ok)
{
ReleaseDC(0, new_hdc);
return stat;
}
}
+ else if (!graphics->hdc)
+ {
+ graphics->hdc = new_hdc = GetDC(0);
+ if (!new_hdc)
+ return OutOfMemory;
+ }
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
@@ -918,7 +926,10 @@ static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
if (new_hdc)
{
ReleaseDC(0, new_hdc);
- GdipDeleteGraphics(graphics);
+ if (new_graphics)
+ GdipDeleteGraphics(new_graphics);
+ else
+ graphics->hdc = NULL;
}
return stat;
@@ -1248,11 +1259,66 @@ GpStatus WINGDIPAPI GdipSetInfinite(GpRegion *region)
return stat;
}
+/* Transforms GpRegion elements with given matrix */
+static GpStatus transform_region_element(region_element* element, GpMatrix *matrix)
+{
+ GpStatus stat;
+
+ switch(element->type)
+ {
+ case RegionDataEmptyRect:
+ case RegionDataInfiniteRect:
+ return Ok;
+ case RegionDataRect:
+ {
+ /* We can't transform a rectangle, so convert it to a path. */
+ GpRegion *new_region;
+ GpPath *path;
+
+ stat = GdipCreatePath(FillModeAlternate, &path);
+ if (stat == Ok)
+ {
+ stat = GdipAddPathRectangle(path,
+ element->elementdata.rect.X, element->elementdata.rect.Y,
+ element->elementdata.rect.Width, element->elementdata.rect.Height);
+
+ if (stat == Ok)
+ stat = GdipCreateRegionPath(path, &new_region);
+
+ GdipDeletePath(path);
+ }
+
+ if (stat == Ok)
+ {
+ /* Steal the element from the created region. */
+ memcpy(element, &new_region->node, sizeof(region_element));
+ HeapFree(GetProcessHeap(), 0, new_region);
+ }
+ else
+ return stat;
+ }
+ /* Fall-through to do the actual conversion. */
+ case RegionDataPath:
+ stat = GdipTransformMatrixPoints(matrix,
+ element->elementdata.pathdata.path->pathdata.Points,
+ element->elementdata.pathdata.path->pathdata.Count);
+ return stat;
+ default:
+ stat = transform_region_element(element->elementdata.combine.left, matrix);
+ if (stat == Ok)
+ stat = transform_region_element(element->elementdata.combine.right, matrix);
+ return stat;
+ }
+}
+
GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *region, GpMatrix *matrix)
{
- FIXME("(%p, %p): stub\n", region, matrix);
+ TRACE("(%p, %p)\n", region, matrix);
- return NotImplemented;
+ if (!region || !matrix)
+ return InvalidParameter;
+
+ return transform_region_element(®ion->node, matrix);
}
/* Translates GpRegion elements with specified offsets */
@@ -1307,14 +1373,150 @@ GpStatus WINGDIPAPI GdipTranslateRegionI(GpRegion *region, INT dx, INT dy)
return GdipTranslateRegion(region, (REAL)dx, (REAL)dy);
}
+static GpStatus get_region_scans_data(GpRegion *region, GpMatrix *matrix, LPRGNDATA *data)
+{
+ GpRegion *region_copy;
+ GpStatus stat;
+ HRGN hrgn;
+ DWORD data_size;
+
+ stat = GdipCloneRegion(region, ®ion_copy);
+
+ if (stat == Ok)
+ {
+ stat = GdipTransformRegion(region_copy, matrix);
+
+ if (stat == Ok)
+ stat = GdipGetRegionHRgn(region_copy, NULL, &hrgn);
+
+ if (stat == Ok)
+ {
+ if (hrgn)
+ {
+ data_size = GetRegionData(hrgn, 0, NULL);
+
+ *data = GdipAlloc(data_size);
+
+ if (*data)
+ GetRegionData(hrgn, data_size, *data);
+ else
+ stat = OutOfMemory;
+
+ DeleteObject(hrgn);
+ }
+ else
+ {
+ data_size = sizeof(RGNDATAHEADER) + sizeof(RECT);
+
+ *data = GdipAlloc(data_size);
+
+ if (*data)
+ {
+ (*data)->rdh.dwSize = sizeof(RGNDATAHEADER);
+ (*data)->rdh.iType = RDH_RECTANGLES;
+ (*data)->rdh.nCount = 1;
+ (*data)->rdh.nRgnSize = sizeof(RECT);
+ (*data)->rdh.rcBound.left = (*data)->rdh.rcBound.top = -0x400000;
+ (*data)->rdh.rcBound.right = (*data)->rdh.rcBound.bottom = 0x400000;
+
+ memcpy(&(*data)->Buffer, &(*data)->rdh.rcBound, sizeof(RECT));
+ }
+ else
+ stat = OutOfMemory;
+ }
+ }
+
+ GdipDeleteRegion(region_copy);
+ }
+
+ return stat;
+}
+
GpStatus WINGDIPAPI GdipGetRegionScansCount(GpRegion *region, UINT *count, GpMatrix *matrix)
{
- static int calls;
+ GpStatus stat;
+ LPRGNDATA data;
TRACE("(%p, %p, %p)\n", region, count, matrix);
- if (!(calls++))
- FIXME("not implemented\n");
+ if (!region || !count || !matrix)
+ return InvalidParameter;
- return NotImplemented;
+ stat = get_region_scans_data(region, matrix, &data);
+
+ if (stat == Ok)
+ {
+ *count = data->rdh.nCount;
+ GdipFree(data);
+ }
+
+ return stat;
+}
+
+GpStatus WINGDIPAPI GdipGetRegionScansI(GpRegion *region, GpRect *scans, INT *count, GpMatrix *matrix)
+{
+ GpStatus stat;
+ INT i;
+ LPRGNDATA data;
+ RECT *rects;
+
+ if (!region || !count || !matrix)
+ return InvalidParameter;
+
+ stat = get_region_scans_data(region, matrix, &data);
+
+ if (stat == Ok)
+ {
+ *count = data->rdh.nCount;
+ rects = (RECT*)&data->Buffer;
+
+ if (scans)
+ {
+ for (i=0; irdh.nCount; i++)
+ {
+ scans[i].X = rects[i].left;
+ scans[i].Y = rects[i].top;
+ scans[i].Width = rects[i].right - rects[i].left;
+ scans[i].Height = rects[i].bottom - rects[i].top;
+ }
+ }
+
+ GdipFree(data);
+ }
+
+ return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetRegionScans(GpRegion *region, GpRectF *scans, INT *count, GpMatrix *matrix)
+{
+ GpStatus stat;
+ INT i;
+ LPRGNDATA data;
+ RECT *rects;
+
+ if (!region || !count || !matrix)
+ return InvalidParameter;
+
+ stat = get_region_scans_data(region, matrix, &data);
+
+ if (stat == Ok)
+ {
+ *count = data->rdh.nCount;
+ rects = (RECT*)&data->Buffer;
+
+ if (scans)
+ {
+ for (i=0; irdh.nCount; i++)
+ {
+ scans[i].X = rects[i].left;
+ scans[i].Y = rects[i].top;
+ scans[i].Width = rects[i].right - rects[i].left;
+ scans[i].Height = rects[i].bottom - rects[i].top;
+ }
+ }
+
+ GdipFree(data);
+ }
+
+ return Ok;
}
diff --git a/dll/win32/hlink/hlink.spec b/dll/win32/hlink/hlink.spec
index 0cc761fbcb6..ca8144e7d76 100644
--- a/dll/win32/hlink/hlink.spec
+++ b/dll/win32/hlink/hlink.spec
@@ -2,7 +2,7 @@
4 stdcall HlinkCreateFromString(wstr wstr wstr ptr long ptr ptr ptr)
5 stdcall HlinkCreateFromData(ptr ptr long ptr ptr ptr)
6 stdcall HlinkCreateBrowseContext(ptr ptr ptr)
-7 stub HlinkClone
+7 stdcall HlinkClone(ptr ptr ptr long ptr)
8 stdcall HlinkNavigateToStringReference(wstr wstr ptr long ptr long ptr ptr ptr)
9 stdcall HlinkOnNavigate(ptr ptr long ptr wstr wstr ptr)
10 stdcall HlinkNavigate(ptr ptr long ptr ptr ptr)
diff --git a/dll/win32/hlink/hlink_main.c b/dll/win32/hlink/hlink_main.c
index e96f206645f..cda96836484 100644
--- a/dll/win32/hlink/hlink_main.c
+++ b/dll/win32/hlink/hlink_main.c
@@ -428,6 +428,71 @@ HRESULT WINAPI HlinkResolveMonikerForData(LPMONIKER pimkReference, DWORD reserve
return IMoniker_BindToStorage(pimkReference, pibc, NULL, &IID_IUnknown, &obj);
}
+/***********************************************************************
+ * HlinkClone (HLINK.@)
+ */
+HRESULT WINAPI HlinkClone(IHlink *hlink, REFIID riid, IHlinkSite *hls,
+ DWORD site_data, void **obj)
+{
+ IMoniker *mk, *clone_mk = NULL;
+ WCHAR *loc, *name = NULL;
+ HRESULT hres;
+
+ if(!hlink || !riid || !obj)
+ return E_INVALIDARG;
+
+ *obj = NULL;
+
+ hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &mk, &loc);
+ if(FAILED(hres))
+ return hres;
+
+ if(mk) {
+ IStream *strm;
+ LARGE_INTEGER lgint;
+
+ hres = CreateStreamOnHGlobal(NULL, TRUE, &strm);
+ if(FAILED(hres)) {
+ IMoniker_Release(mk);
+ goto cleanup;
+ }
+
+ hres = OleSaveToStream((IPersistStream*)mk, strm);
+ if(FAILED(hres)) {
+ IStream_Release(strm);
+ IMoniker_Release(mk);
+ goto cleanup;
+ }
+ IMoniker_Release(mk);
+
+ lgint.QuadPart = 0;
+ hres = IStream_Seek(strm, lgint, STREAM_SEEK_SET, NULL);
+ if(FAILED(hres)) {
+ IStream_Release(strm);
+ goto cleanup;
+ }
+
+ hres = OleLoadFromStream(strm, &IID_IMoniker, (void**)&clone_mk);
+ IStream_Release(strm);
+ if(FAILED(hres))
+ goto cleanup;
+ }
+
+ hres = IHlink_GetFriendlyName(hlink, HLFNAMEF_DEFAULT, &name);
+ if(FAILED(hres))
+ goto cleanup;
+
+ hres = HlinkCreateFromMoniker(clone_mk, loc, name, hls, site_data, NULL,
+ &IID_IHlink, obj);
+
+cleanup:
+ if(clone_mk)
+ IMoniker_Release(clone_mk);
+ CoTaskMemFree(loc);
+ CoTaskMemFree(name);
+ return hres;
+}
+
static HRESULT WINAPI HLinkCF_fnQueryInterface ( LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppvObj)
{
diff --git a/dll/win32/hlink/link.c b/dll/win32/hlink/link.c
index ffd3cda854b..b0d99aaf4e9 100644
--- a/dll/win32/hlink/link.c
+++ b/dll/win32/hlink/link.c
@@ -69,20 +69,40 @@ static inline HlinkImpl* HlinkImpl_from_IDataObject( IDataObject* iface)
return (HlinkImpl*) ((CHAR*)iface - FIELD_OFFSET(HlinkImpl, lpDOVtbl));
}
-static inline void __GetMoniker(HlinkImpl* This, IMoniker** moniker)
+static HRESULT __GetMoniker(HlinkImpl* This, IMoniker** moniker,
+ DWORD ref_type)
{
- *moniker = NULL;
- if (This->Moniker)
+ HRESULT hres;
+
+ if (ref_type == HLINKGETREF_DEFAULT)
+ ref_type = HLINKGETREF_RELATIVE;
+
+ if (ref_type == HLINKGETREF_ABSOLUTE && This->Site)
{
- *moniker = This->Moniker;
- if (*moniker)
- IMoniker_AddRef(*moniker);
- }
- else if (This->Site)
- {
- IHlinkSite_GetMoniker(This->Site, This->SiteData,
- OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_CONTAINER, moniker);
+ IMoniker *hls_moniker;
+
+ hres = IHlinkSite_GetMoniker(This->Site, This->SiteData,
+ OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_CONTAINER, &hls_moniker);
+ if (FAILED(hres))
+ return hres;
+
+ if (This->Moniker)
+ {
+ hres = IMoniker_ComposeWith(hls_moniker, This->Moniker, FALSE,
+ moniker);
+ IMoniker_Release(hls_moniker);
+ return hres;
+ }
+
+ *moniker = hls_moniker;
+ return S_OK;
}
+
+ *moniker = This->Moniker;
+ if (*moniker)
+ IMoniker_AddRef(*moniker);
+
+ return S_OK;
}
HRESULT WINAPI HLink_Constructor(IUnknown *pUnkOuter, REFIID riid,
@@ -191,10 +211,11 @@ static HRESULT WINAPI IHlink_fnGetHlinkSite( IHlink* iface,
TRACE("(%p)->(%p %p)\n", This, ppihlSite, pdwSiteData);
*ppihlSite = This->Site;
- *pdwSiteData = This->SiteData;
- if (This->Site)
+ if (This->Site) {
IHlinkSite_AddRef(This->Site);
+ *pdwSiteData = This->SiteData;
+ }
return S_OK;
}
@@ -307,8 +328,16 @@ static HRESULT WINAPI IHlink_fnGetMonikerReference(IHlink* iface,
TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppimkTarget,
ppwzLocation);
- if(ppimkTarget)
- __GetMoniker(This, ppimkTarget);
+ if (ppimkTarget)
+ {
+ HRESULT hres = __GetMoniker(This, ppimkTarget, dwWhichRef);
+ if (FAILED(hres))
+ {
+ if (ppwzLocation)
+ *ppwzLocation = NULL;
+ return hres;
+ }
+ }
if (ppwzLocation)
IHlink_GetStringReference(iface, dwWhichRef, NULL, ppwzLocation);
@@ -323,7 +352,6 @@ static HRESULT WINAPI IHlink_fnGetStringReference (IHlink* iface,
TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppwzTarget, ppwzLocation);
- /* note: undocumented behavior with dwWhichRef == -1 */
if(dwWhichRef != -1 && dwWhichRef & ~(HLINKGETREF_DEFAULT | HLINKGETREF_ABSOLUTE | HLINKGETREF_RELATIVE))
{
if(ppwzTarget)
@@ -333,13 +361,16 @@ static HRESULT WINAPI IHlink_fnGetStringReference (IHlink* iface,
return E_INVALIDARG;
}
- if(dwWhichRef != HLINKGETREF_DEFAULT)
- FIXME("unhandled flags: 0x%x\n", dwWhichRef);
-
if (ppwzTarget)
{
IMoniker* mon;
- __GetMoniker(This, &mon);
+ HRESULT hres = __GetMoniker(This, &mon, dwWhichRef);
+ if (FAILED(hres))
+ {
+ if (ppwzLocation)
+ *ppwzLocation = NULL;
+ return hres;
+ }
if (mon)
{
IBindCtx *pbc;
@@ -389,7 +420,12 @@ static HRESULT WINAPI IHlink_fnGetFriendlyName (IHlink* iface,
else
{
IMoniker *moniker;
- __GetMoniker(This, &moniker);
+ HRESULT hres = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
+ if (FAILED(hres))
+ {
+ *ppwzFriendlyName = NULL;
+ return hres;
+ }
if (moniker)
{
IBindCtx *bcxt;
@@ -440,20 +476,17 @@ static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc,
{
HlinkImpl *This = (HlinkImpl*)iface;
IMoniker *mon = NULL;
+ HRESULT r;
FIXME("Semi-Stub:(%p)->(%i %p %p %p)\n", This, grfHLNF, pbc, pbsc, phbc);
- if (This->Site)
- IHlinkSite_ReadyToNavigate(This->Site, This->SiteData, 0);
-
- __GetMoniker(This, &mon);
+ r = __GetMoniker(This, &mon, HLINKGETREF_ABSOLUTE);
TRACE("Moniker %p\n", mon);
- if (mon)
+ if (SUCCEEDED(r))
{
IBindCtx *bcxt;
IHlinkTarget *target = NULL;
- HRESULT r = S_OK;
CreateBindCtx(0, &bcxt);
@@ -488,10 +521,10 @@ static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc,
}
if (This->Site)
- IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, 0, NULL);
+ IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, r, NULL);
TRACE("Finished Navigation\n");
- return S_OK;
+ return r;
}
static HRESULT WINAPI IHlink_fnSetAdditonalParams(IHlink* iface,
@@ -782,14 +815,17 @@ end:
static HRESULT WINAPI IPersistStream_fnSave(IPersistStream* iface,
IStream* pStm, BOOL fClearDirty)
{
- HRESULT r = E_FAIL;
+ HRESULT r;
HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
DWORD hdr[2];
IMoniker *moniker;
TRACE("(%p) Moniker(%p)\n", This, This->Moniker);
- __GetMoniker(This, &moniker);
+ r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
+ if (FAILED(r))
+ return r;
+ r = E_FAIL;
hdr[0] = HLINK_SAVE_MAGIC;
hdr[1] = 0;
@@ -850,7 +886,7 @@ end:
static HRESULT WINAPI IPersistStream_fnGetSizeMax(IPersistStream* iface,
ULARGE_INTEGER* pcbSize)
{
- HRESULT r = E_FAIL;
+ HRESULT r;
HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
IMoniker *moniker;
@@ -864,7 +900,11 @@ static HRESULT WINAPI IPersistStream_fnGetSizeMax(IPersistStream* iface,
if (This->FriendlyName)
pcbSize->QuadPart += size_hlink_string(This->FriendlyName);
- __GetMoniker(This, &moniker);
+ r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
+ if (FAILED(r))
+ return r;
+ r = E_FAIL;
+
if (moniker)
{
IPersistStream* monstream = NULL;
diff --git a/dll/win32/kernel32/except/except.c b/dll/win32/kernel32/except/except.c
index d46a51c4ed3..d57bd7a2e14 100644
--- a/dll/win32/kernel32/except/except.c
+++ b/dll/win32/kernel32/except/except.c
@@ -413,7 +413,7 @@ RaiseException(IN DWORD dwExceptionCode,
}
}
- if (dwExceptionCode == 0xeedface)
+ if (dwExceptionCode == 0xeedface || dwExceptionCode == 0xeedfade)
{
DPRINT1("Delphi Exception at address: %p\n", ExceptionRecord.ExceptionInformation[0]);
DPRINT1("Exception-Object: %p\n", ExceptionRecord.ExceptionInformation[1]);
diff --git a/dll/win32/kernel32/thread/amd64/fiber.S b/dll/win32/kernel32/thread/amd64/fiber.S
index 984447abe11..09ea635d23c 100644
--- a/dll/win32/kernel32/thread/amd64/fiber.S
+++ b/dll/win32/kernel32/thread/amd64/fiber.S
@@ -7,11 +7,13 @@
* KJK::Hyperion
*/
-#include
+#include
-.globl SwitchToFiber
-.intel_syntax noprefix
+
+PUBLIC SwitchToFiber
SwitchToFiber:
/* FIXME: TODO */
ret 4
+
+END
diff --git a/dll/win32/kernel32/thread/amd64/thread.S b/dll/win32/kernel32/thread/amd64/thread.S
index 2c0c2260cb8..71ed562f816 100644
--- a/dll/win32/kernel32/thread/amd64/thread.S
+++ b/dll/win32/kernel32/thread/amd64/thread.S
@@ -6,9 +6,11 @@
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
*/
-.globl BaseThreadStartupThunk
-.globl BaseProcessStartThunk
-.intel_syntax noprefix
+#include
+
+
+PUBLIC BaseThreadStartupThunk
+PUBLIC BaseProcessStartThunk
BaseThreadStartupThunk:
@@ -29,4 +31,5 @@ BaseProcessStartThunk:
push 0 /* Return RIP */
jmp BaseProcessStartup
+END
/* EOF */
diff --git a/dll/win32/kernel32/thread/i386/fiber.S b/dll/win32/kernel32/thread/i386/fiber.S
index 57358ffeed4..bf88c468487 100644
--- a/dll/win32/kernel32/thread/i386/fiber.S
+++ b/dll/win32/kernel32/thread/i386/fiber.S
@@ -7,11 +7,12 @@
* KJK::Hyperion
*/
-#include
+#include
+#include
-.globl _SwitchToFiber@4
-.intel_syntax noprefix
+.code
+PUBLIC _SwitchToFiber@4
_SwitchToFiber@4:
/* Get the TEB */
mov edx, fs:[TEB_SELF]
@@ -30,7 +31,7 @@ _SwitchToFiber@4:
mov [eax+FIBER_CONTEXT_EIP], ebx
/* Check if we're to save FPU State */
- cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL | CONTEXT_FLOATING_POINT
+ cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL OR CONTEXT_FLOATING_POINT
jnz NoFpuStateSave
/* Save the FPU State (Status and Control)*/
@@ -80,7 +81,7 @@ NoFpuStateSave:
mov [edx+TEB_ACTIVATION_CONTEXT_STACK_POINTER], esi
/* Restore FPU State */
- cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL | CONTEXT_FLOATING_POINT
+ cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL OR CONTEXT_FLOATING_POINT
jnz NoFpuStateRestore
/* Check if the Status Word Changed */
@@ -96,7 +97,7 @@ NoFpuStateSave:
StatusWordChanged:
/* Load the new one */
- mov word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD], 0xFFFF
+ mov word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD], HEX(0FFFF)
fldenv [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
ControlWordEqual:
@@ -120,6 +121,7 @@ NoFpuStateRestore:
mov [edx+TEB_FLS_DATA], eax
/* Jump to new fiber */
- jmp [ecx+FIBER_CONTEXT_EIP]
+ jmp dword ptr [ecx+FIBER_CONTEXT_EIP]
+END
/* EOF */
diff --git a/dll/win32/kernel32/thread/i386/thread.S b/dll/win32/kernel32/thread/i386/thread.S
index 5dea1ee7400..a07bcb2e60e 100644
--- a/dll/win32/kernel32/thread/i386/thread.S
+++ b/dll/win32/kernel32/thread/i386/thread.S
@@ -6,9 +6,15 @@
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
*/
-.globl _BaseThreadStartupThunk@0
-.globl _BaseProcessStartThunk@0
-.intel_syntax noprefix
+#include
+
+.code
+
+EXTERN _BaseThreadStartup@8:PROC
+EXTERN _BaseProcessStartup@4:PROC
+
+PUBLIC _BaseThreadStartupThunk@0
+PUBLIC _BaseProcessStartThunk@0
_BaseThreadStartupThunk@0:
@@ -29,4 +35,5 @@ _BaseProcessStartThunk@0:
push 0 /* Return EIP */
jmp _BaseProcessStartup@4
+END
/* EOF */
diff --git a/dll/win32/mprapi/mprapi.c b/dll/win32/mprapi/mprapi.c
index 90f47ae0c6b..715f1b8cada 100644
--- a/dll/win32/mprapi/mprapi.c
+++ b/dll/win32/mprapi/mprapi.c
@@ -44,6 +44,32 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
return TRUE;
}
+/***********************************************************************
+ * MprAdminGetErrorString (MPRAPI.@)
+ *
+ * Return a unicode string for the given mpr errorcode
+ *
+ * PARAMS
+ * mprerror [i] errorcode, for which a description is requested
+ * localstr [o] pointer, where a buffer with the error description is returned
+ *
+ * RETURNS
+ * Failure: ERROR_MR_MID_NOT_FOUND, when mprerror is not known
+ * Success: ERROR_SUCCESS, and in localstr a pointer to a buffer from LocalAlloc,
+ * which contains the error description.
+ *
+ * NOTES
+ * The caller must free the returned buffer with LocalFree
+ *
+ */
+DWORD APIENTRY MprAdminGetErrorString(DWORD mprerror, LPWSTR *localstr)
+{
+ FIXME("(0x%x/%u, %p): stub!\n", mprerror, mprerror, localstr);
+
+ *localstr = NULL;
+ return ERROR_MR_MID_NOT_FOUND;
+}
+
/***********************************************************************
* MprAdminIsServiceRunning (MPRAPI.@)
*/
diff --git a/dll/win32/mprapi/mprapi.spec b/dll/win32/mprapi/mprapi.spec
index 6fb84393f2d..4b5937b8806 100644
--- a/dll/win32/mprapi/mprapi.spec
+++ b/dll/win32/mprapi/mprapi.spec
@@ -6,7 +6,7 @@
@ stub MprAdminDeregisterConnectionNotification
@ stub MprAdminDeviceEnum
@ stub MprAdminEstablishDomainRasServer
-@ stub MprAdminGetErrorString
+@ stdcall MprAdminGetErrorString(long ptr)
@ stub MprAdminGetPDCServer
@ stub MprAdminInterfaceConnect
@ stub MprAdminInterfaceCreate
diff --git a/dll/win32/netcfgx/tcpipconf_notify.c b/dll/win32/netcfgx/tcpipconf_notify.c
index 14b9a4ab2f4..5238d60c72e 100644
--- a/dll/win32/netcfgx/tcpipconf_notify.c
+++ b/dll/win32/netcfgx/tcpipconf_notify.c
@@ -2860,7 +2860,7 @@ Initialize(TcpipConfNotifyImpl * This)
}
pCurSettings->AutoconfigActive = pPerInfo->AutoconfigActive;
}
- CoTaskMemFree(pInfo);
+ CoTaskMemFree(pPerInfo);
}
}
diff --git a/dll/win32/setupapi/cfgmgr.c b/dll/win32/setupapi/cfgmgr.c
index ccff5e652cd..e995e8fbf3e 100644
--- a/dll/win32/setupapi/cfgmgr.c
+++ b/dll/win32/setupapi/cfgmgr.c
@@ -1987,10 +1987,47 @@ CONFIGRET WINAPI CM_Get_Device_ID_List_ExW(
PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
HMACHINE hMachine)
{
- FIXME("%p %p %ld %ld %lx\n",
+ RPC_BINDING_HANDLE BindingHandle = NULL;
+ CONFIGRET ret;
+
+ TRACE("%p %p %ld %ld %lx\n",
pszFilter, Buffer, BufferLen, ulFlags, hMachine);
- memset(Buffer,0,2);
- return CR_SUCCESS;
+
+ if (Buffer == NULL || BufferLen == 0)
+ return CR_INVALID_POINTER;
+
+ if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
+ return CR_INVALID_FLAG;
+
+ if (hMachine != NULL)
+ {
+ BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
+ if (BindingHandle == NULL)
+ return CR_FAILURE;
+ }
+ else
+ {
+ if (!PnpGetLocalHandles(&BindingHandle, NULL))
+ return CR_FAILURE;
+ }
+
+ *Buffer = 0;
+
+ RpcTryExcept
+ {
+ ret = PNP_GetDeviceList(BindingHandle,
+ pszFilter,
+ Buffer,
+ &BufferLen,
+ ulFlags);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ret = RpcStatusToCmStatus(RpcExceptionCode());
+ }
+ RpcEndExcept;
+
+ return ret;
}
diff --git a/dll/win32/shdocvw/De.rc b/dll/win32/shdocvw/De.rc
new file mode 100644
index 00000000000..560d93deb1f
--- /dev/null
+++ b/dll/win32/shdocvw/De.rc
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010 André Hentschel
+ *
+ * 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 "resource.h"
+
+#pragma code_page(65001)
+
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "URL öffnen"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Geben Sie die Url ein, die Sie mit Internet Explorer öffnen möchten",-1,30, 5, 150,15
+ LTEXT "Öffnen:", -1, 2, 32, 25, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 30, 30, 160, 13
+ DEFPUSHBUTTON "&OK", IDOK, 30, 50, 50, 15
+ PUSHBUTTON "&Abbrechen", IDCANCEL, 90, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Datei"
+ {
+ POPUP "&Neu"
+ {
+ MENUITEM "&Fenster" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "Ö&ffnen...", ID_BROWSE_OPEN
+ MENUITEM "&Speichern", ID_BROWSE_SAVE
+ MENUITEM "Speichern &als...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "Seite &einrichten...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "Dr&ucken...", ID_BROWSE_PRINT
+ MENUITEM "Seiten&vorschau...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "Ei&genschaften...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Beenden", ID_BROWSE_QUIT
+ }
+ POPUP "&Ansicht"
+ {
+ POPUP "&Symbolleisten"
+ {
+ MENUITEM "&Standard" ID_BROWSE_BAR_STD
+ MENUITEM "&Adressleiste" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Favoriten"
+ {
+ MENUITEM "&Zu den Favoriten hinzufügen..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Hilfe"
+ {
+ MENUITEM "Über &Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Zurück"
+ IDS_TB_FORWARD "Vorwärts"
+ IDS_TB_STOP "Stopp"
+ IDS_TB_REFRESH "Neu laden"
+ IDS_TB_HOME "Start"
+ IDS_TB_PRINT "Drucken"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Adresse"
+}
diff --git a/dll/win32/shdocvw/En.rc b/dll/win32/shdocvw/En.rc
index 749c849aa3c..7a4fe78bf61 100644
--- a/dll/win32/shdocvw/En.rc
+++ b/dll/win32/shdocvw/En.rc
@@ -49,9 +49,38 @@ IDR_BROWSE_MAIN_MENU MENU
MENUITEM "Print previe&w...", ID_BROWSE_PRINT_PREVIEW
MENUITEM SEPARATOR
MENUITEM "&Properties...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Close", ID_BROWSE_QUIT
+ }
+ POPUP "&View"
+ {
+ POPUP "&Toolbars"
+ {
+ MENUITEM "&Standard bar" ID_BROWSE_BAR_STD
+ MENUITEM "&Address bar" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Favorites"
+ {
+ MENUITEM "&Add to Favorites..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
}
POPUP "&Help"
{
MENUITEM "&About Internet Explorer...", ID_BROWSE_ABOUT
}
}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Back"
+ IDS_TB_FORWARD "Forward"
+ IDS_TB_STOP "Stop"
+ IDS_TB_REFRESH "Refresh"
+ IDS_TB_HOME "Home"
+ IDS_TB_PRINT "Print"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Address"
+}
diff --git a/dll/win32/shdocvw/Es.rc b/dll/win32/shdocvw/Es.rc
new file mode 100644
index 00000000000..39715440998
--- /dev/null
+++ b/dll/win32/shdocvw/Es.rc
@@ -0,0 +1,89 @@
+/*
+ * Spanish resources for shdocvw
+ *
+ * Copyright 2010 José Rostagno
+ *
+ * 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 "resource.h"
+
+#pragma code_page(65001)
+
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Abrir URL"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Especifique la dirección que desea abrir en Internet Explorer",-1,25, 5, 150,15
+ LTEXT "Abrir:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&Aceptar", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&Cancelar", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Archivo"
+ {
+ POPUP "&Nuevo"
+ {
+ MENUITEM "&Ventana" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Abrir...", ID_BROWSE_OPEN
+ MENUITEM "&Guardar", ID_BROWSE_SAVE
+ MENUITEM "Guardar &como...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "&Formato de impresión...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "&Imprimir...", ID_BROWSE_PRINT
+ MENUITEM "&Vista previa de impresión...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Propiedades...", ID_BROWSE_PROPERTIES
+ }
+ POPUP "&Ver"
+ {
+ POPUP "&Barra de herramientas"
+ {
+ MENUITEM "Barra &estándar" ID_BROWSE_BAR_STD
+ MENUITEM "Barra de &direcciones" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Favoritos"
+ {
+ MENUITEM "&Añadir a Favoritos..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "A&yuda"
+ {
+ MENUITEM "Acerca &de Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Atrás"
+ IDS_TB_FORWARD "Adelante"
+ IDS_TB_STOP "Detener"
+ IDS_TB_REFRESH "Recargar"
+ IDS_TB_HOME "Inicio"
+ IDS_TB_PRINT "Imprimir"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Dirección"
+}
diff --git a/dll/win32/shdocvw/Fr.rc b/dll/win32/shdocvw/Fr.rc
new file mode 100644
index 00000000000..1e17409b7f9
--- /dev/null
+++ b/dll/win32/shdocvw/Fr.rc
@@ -0,0 +1,91 @@
+/*
+ * shdocvw French resources
+ *
+ * Copyright 2010 Frédéric Delanoy
+ *
+ * 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 "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Open URL"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Spécifiez l'URL que vous désirez ouvrir dans Internet Explorer :",-1,30, 6, 150, 17
+ LTEXT "Ouvrir :", -1, 2, 32, 27, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 30, 30, 155, 13
+ DEFPUSHBUTTON "&OK", IDOK, 54, 50, 50, 15
+ PUSHBUTTON "&Annuler", IDCANCEL, 114, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Fichier"
+ {
+ POPUP "&Nouvelle"
+ {
+ MENUITEM "&Fenêtre" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Ouvrir...", ID_BROWSE_OPEN
+ MENUITEM "&Enregistrer", ID_BROWSE_SAVE
+ MENUITEM "Enregistrer &sous...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "&Format d'impression...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "&Imprimer...", ID_BROWSE_PRINT
+ MENUITEM "&Aperçu avant impression...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Propriétés...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Quitter", ID_BROWSE_QUIT
+ }
+ POPUP "&Afficher"
+ {
+ POPUP "&Barres d'outils"
+ {
+ MENUITEM "Barre &standard" ID_BROWSE_BAR_STD
+ MENUITEM "Barre d'&adresse" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Favoris"
+ {
+ MENUITEM "&Ajouter aux favoris..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "A&ide"
+ {
+ MENUITEM "À &propos d'Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Précédent"
+ IDS_TB_FORWARD "Suivant"
+ IDS_TB_STOP "Arrêter"
+ IDS_TB_REFRESH "Recharger"
+ IDS_TB_HOME "Accueil"
+ IDS_TB_PRINT "Imprimer"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Adresse"
+}
diff --git a/dll/win32/shdocvw/He.rc b/dll/win32/shdocvw/He.rc
new file mode 100644
index 00000000000..a2789dfa90a
--- /dev/null
+++ b/dll/win32/shdocvw/He.rc
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 Alexander N. Sørnes
+ * Copyright 2010 Yaron Shahrabani
+ *
+ * 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 "resource.h"
+
+#pragma code_page(65001)
+
+LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+EXSTYLE WS_EX_LAYOUTRTL
+CAPTION "פתיחת כתובת"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "נא לציין את הכתובת אותה ברצונך לפתוח באמצעות Internet Explorer",-1,25, 5, 150,15
+ LTEXT "פתיחה:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&אישור", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&ביטול", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&קובץ"
+ {
+ POPUP "&חדש"
+ {
+ MENUITEM "&חלון" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&פתיחה...", ID_BROWSE_OPEN
+ MENUITEM "&שמירה", ID_BROWSE_SAVE
+ MENUITEM "שמירה &בשם...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "&תצורת ההדפסה...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "ה&דפסה...", ID_BROWSE_PRINT
+ MENUITEM "תצוגה מ&קדימה להדפסה...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "מ&אפיינים...", ID_BROWSE_PROPERTIES
+ MENUITEM "&סגירה", ID_BROWSE_QUIT
+ }
+ POPUP "&תצוגה"
+ {
+ POPUP "&סרגלי כלים"
+ {
+ MENUITEM "סרגל הכלים ה&רגיל" ID_BROWSE_BAR_STD
+ MENUITEM "סרגל ה&כתובות" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&מועדפים"
+ {
+ MENUITEM "הו&ספה למועדפים..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "ע&זרה"
+ {
+ MENUITEM "על &אודות Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "חזרה"
+ IDS_TB_FORWARD "קדימה"
+ IDS_TB_STOP "עצירה"
+ IDS_TB_REFRESH "רענון"
+ IDS_TB_HOME "דף הבית"
+ IDS_TB_PRINT "הדפסה"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "כתובת"
+}
diff --git a/dll/win32/shdocvw/It.rc b/dll/win32/shdocvw/It.rc
new file mode 100644
index 00000000000..7f39c2b08a2
--- /dev/null
+++ b/dll/win32/shdocvw/It.rc
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 Alexander N. Sørnes
+ * Copyright 2010 Luca Bennati
+ *
+ * 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 "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Apri URL"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Specifica l'URL che vuoi aprire in Internet Explorer",-1,25, 5, 150,15
+ LTEXT "Apri:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&OK", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&Annulla", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&File"
+ {
+ POPUP "&Nuova"
+ {
+ MENUITEM "Fin&estra" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Apri...", ID_BROWSE_OPEN
+ MENUITEM "&Salva", ID_BROWSE_SAVE
+ MENUITEM "Sa&lva come...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "&Imposta pagina...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "S&tampa...", ID_BROWSE_PRINT
+ MENUITEM "Antepri&ma di stampa...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Proprietà...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Chiudi", ID_BROWSE_QUIT
+ }
+ POPUP "&Visualizza"
+ {
+ POPUP "&Barre degli strumenti"
+ {
+ MENUITEM "Barra &predefinita" ID_BROWSE_BAR_STD
+ MENUITEM "Barra dell'&indirizzo" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Preferiti"
+ {
+ MENUITEM "&Aggiungi ai Preferiti..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Aiuto"
+ {
+ MENUITEM "&Informazioni su Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Indietro"
+ IDS_TB_FORWARD "Avanti"
+ IDS_TB_STOP "Ferma"
+ IDS_TB_REFRESH "Aggiorna"
+ IDS_TB_HOME "Inizio"
+ IDS_TB_PRINT "Stampa"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Indirizzo"
+}
diff --git a/dll/win32/shdocvw/Ko.rc b/dll/win32/shdocvw/Ko.rc
new file mode 100644
index 00000000000..613288d945b
--- /dev/null
+++ b/dll/win32/shdocvw/Ko.rc
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010 Alexander N. Sørnes
+ * Copyright 2010 YunSOng Hwang
+ *
+ * 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 "resource.h"
+
+#pragma code_page(65001)
+
+LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "URL 열기"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "인터넷 익스플로어로 열 URL 지정",-1,25, 5, 150,15
+ LTEXT "열기:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "확인(&O)", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "취소(&C)", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "파일(&F)"
+ {
+ POPUP "새 작업(&N)"
+ {
+ MENUITEM "창(&W)" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "열기(&O)...", ID_BROWSE_OPEN
+ MENUITEM "저장(&S)", ID_BROWSE_SAVE
+ MENUITEM "다른 이름으로 저장(&A)...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "인쇄 형식(&F)...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "인쇄(&I)...", ID_BROWSE_PRINT
+ MENUITEM "인쇄 미리보기(&W)...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "속성(&P)...", ID_BROWSE_PROPERTIES
+ }
+ POPUP "보기(&V)"
+ {
+ POPUP "도구바(&T)"
+ {
+ MENUITEM "표준 바(&S)" ID_BROWSE_BAR_STD
+ MENUITEM "주소 바(&A)" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "즐겨찾기(&F)"
+ {
+ MENUITEM "즐겨찾기 추가(&A)..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "도움말(&H)"
+ {
+ MENUITEM "인터넷 익스플로어 정보(&A)...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "뒤로"
+ IDS_TB_FORWARD "앞으로"
+ IDS_TB_STOP "멈추기"
+ IDS_TB_REFRESH "새로 고침"
+ IDS_TB_HOME "홈"
+ IDS_TB_PRINT "인쇄"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "주소"
+}
diff --git a/dll/win32/shdocvw/Lt.rc b/dll/win32/shdocvw/Lt.rc
new file mode 100644
index 00000000000..b9c0b04b2e3
--- /dev/null
+++ b/dll/win32/shdocvw/Lt.rc
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010 Aurimas Fišeras
+ *
+ * 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 "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Atverti URL"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Nurodykite URL, kurį norite atverti su interneto naršykle",-1 ,30, 5, 150, 16
+ LTEXT "Atverti:", -1, 2, 32, 25, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 30, 30, 160, 13
+ DEFPUSHBUTTON "&Gerai", IDOK, 30, 50, 50, 15
+ PUSHBUTTON "&Atsisakyti", IDCANCEL, 90, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Failas"
+ {
+ POPUP "&Naujas"
+ {
+ MENUITEM "&Langas" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Atverti...", ID_BROWSE_OPEN
+ MENUITEM "&Išsaugoti", ID_BROWSE_SAVE
+ MENUITEM "Išsaugoti &kaip...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "Spaudinio &formatas...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "S&pausdinti...", ID_BROWSE_PRINT
+ MENUITEM "Spaudinio pe&ržiūra...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Savybės...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Užverti", ID_BROWSE_QUIT
+ }
+ POPUP "&Rodymas"
+ {
+ POPUP "&Įrankių juosta"
+ {
+ MENUITEM "Į&prastinė juosta" ID_BROWSE_BAR_STD
+ MENUITEM "&Adreso juosta" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Adresynas"
+ {
+ MENUITEM "Į&rašyti į adresyną..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Žinynas"
+ {
+ MENUITEM "&Apie interneto naršyklę...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Atgal"
+ IDS_TB_FORWARD "Pirmyn"
+ IDS_TB_STOP "Stabdyti"
+ IDS_TB_REFRESH "Atnaujinti"
+ IDS_TB_HOME "Pradžia"
+ IDS_TB_PRINT "Spausdinti"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Adresas"
+}
diff --git a/dll/win32/shdocvw/Nl.rc b/dll/win32/shdocvw/Nl.rc
new file mode 100644
index 00000000000..fc5a1f397c0
--- /dev/null
+++ b/dll/win32/shdocvw/Nl.rc
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010 Sven Baars
+ *
+ * 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 "resource.h"
+
+LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Open URL"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Specificeer de URL die u wilt openen in Internet Explorer",-1,25, 5, 150,15
+ LTEXT "Open:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&OK", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&Annuleren", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Bestand"
+ {
+ POPUP "&Nieuw"
+ {
+ MENUITEM "&Venster" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Openen...", ID_BROWSE_OPEN
+ MENUITEM "Op&slaan", ID_BROWSE_SAVE
+ MENUITEM "Ops&laan als...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "Pa&gina-instellingen...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "Af&drukken...", ID_BROWSE_PRINT
+ MENUITEM "Afdruk&voorbeeld...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Eigenschappen...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Afsluiten", ID_BROWSE_QUIT
+ }
+ POPUP "Bee&ld"
+ {
+ POPUP "&Werkbalken"
+ {
+ MENUITEM "&Standaardbalk" ID_BROWSE_BAR_STD
+ MENUITEM "&Adresbalk" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Favorieten"
+ {
+ MENUITEM "&Toevoegen aan Favorieten..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Help"
+ {
+ MENUITEM "&Over Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Terug"
+ IDS_TB_FORWARD "Vooruit"
+ IDS_TB_STOP "Stoppen"
+ IDS_TB_REFRESH "Vernieuwen"
+ IDS_TB_HOME "Startpagina"
+ IDS_TB_PRINT "Printen"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Adres"
+}
diff --git a/dll/win32/shdocvw/Pl.rc b/dll/win32/shdocvw/Pl.rc
new file mode 100644
index 00000000000..5a6ada86e6e
--- /dev/null
+++ b/dll/win32/shdocvw/Pl.rc
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010 ukasz Wojniowicz
+ *
+ * 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 "resource.h"
+
+
+LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Otwrz URL"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Podaj adres URL, ktry chcesz otworzy w Internet Explorerze",-1,25, 5, 150,15
+ LTEXT "Otwrz:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&OK", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&Anuluj", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Plik"
+ {
+ POPUP "&Nowe"
+ {
+ MENUITEM "&Okno" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Otwrz...", ID_BROWSE_OPEN
+ MENUITEM "&Zapisz", ID_BROWSE_SAVE
+ MENUITEM "Zapisz &jako...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "Forma&t wydruku...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "&Drukuj...", ID_BROWSE_PRINT
+ MENUITEM "Podgl&d wydruku...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Waciwoci...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Zamknij...", ID_BROWSE_QUIT
+ }
+ POPUP "&Widok"
+ {
+ POPUP "&Paski narzdzi"
+ {
+ MENUITEM "Pasek &standardowy" ID_BROWSE_BAR_STD
+ MENUITEM "&Pasek adresu" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Ulubione"
+ {
+ MENUITEM "&Dodaj do ulubionych..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Pomoc"
+ {
+ MENUITEM "&O Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Wstecz"
+ IDS_TB_FORWARD "Dalej"
+ IDS_TB_STOP "Zatrzymaj"
+ IDS_TB_REFRESH "Odwierz"
+ IDS_TB_HOME "Strona gwna"
+ IDS_TB_PRINT "Drukuj"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Adres"
+}
diff --git a/dll/win32/shdocvw/Pt.rc b/dll/win32/shdocvw/Pt.rc
new file mode 100644
index 00000000000..9dff39c58c8
--- /dev/null
+++ b/dll/win32/shdocvw/Pt.rc
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2010 Gustavo Henrique Milaré
+ *
+ * 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 "resource.h"
+
+#pragma code_page(65001)
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Abrir URL"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Especifique a URL que você deseja abrir no Internet Explorer",-1,25, 5, 150,15
+ LTEXT "Abrir:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&OK", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&Cancelar", IDCANCEL, 85, 50, 50, 15
+}
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Arquivo"
+ {
+ POPUP "&Novo"
+ {
+ MENUITEM "&Janela" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Abrir...", ID_BROWSE_OPEN
+ MENUITEM "&Salvar", ID_BROWSE_SAVE
+ MENUITEM "Salvar &como...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "Imprimir &formato...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "&Imprimir...", ID_BROWSE_PRINT
+ MENUITEM "&Vizualizar impressão...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Propriedades...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Fechar", ID_BROWSE_QUIT
+ }
+ POPUP "&Ver"
+ {
+ POPUP "&Ferramentas"
+ {
+ MENUITEM "Barra &padrão" ID_BROWSE_BAR_STD
+ MENUITEM "Barra de &endereço" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Favoritos"
+ {
+ MENUITEM "&Adicionar aos Favoritos..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "A&juda"
+ {
+ MENUITEM "&Sobre o Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Voltar"
+ IDS_TB_FORWARD "Avançar"
+ IDS_TB_STOP "Parar"
+ IDS_TB_REFRESH "Atualizar"
+ IDS_TB_HOME "Início"
+ IDS_TB_PRINT "Imprimir"
+}
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Endereço"
+}
diff --git a/dll/win32/shdocvw/Ro.rc b/dll/win32/shdocvw/Ro.rc
new file mode 100644
index 00000000000..38c51caab8d
--- /dev/null
+++ b/dll/win32/shdocvw/Ro.rc
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010 Alexander N. Sørnes
+ * Copyright 2010 Michael Stefaniuc
+ *
+ * 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 "resource.h"
+
+LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
+
+#pragma code_page(65001)
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 210, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Deschide URL-ul"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Specificați URL-ul pe care doriți să îl deschideți în Internet Explorer",-1,35, 5, 160,15
+ LTEXT "Deschide:", -1, 2, 32, 30, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 35, 30, 170, 13
+ DEFPUSHBUTTON "&OK", IDOK, 35, 50, 50, 15
+ PUSHBUTTON "&Renunță", IDCANCEL, 95, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Fișier"
+ {
+ POPUP "&Nou"
+ {
+ MENUITEM "&Fereastră" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Deschidere...", ID_BROWSE_OPEN
+ MENUITEM "&Salvează", ID_BROWSE_SAVE
+ MENUITEM "S&alvare ca...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "&Format tipărire...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "T&ipărire...", ID_BROWSE_PRINT
+ MENUITEM "Pre&vizualizare imprimare...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Proprietăți...", ID_BROWSE_PROPERTIES
+ }
+ POPUP "&Ajutor"
+ {
+ MENUITEM "&Despre Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
diff --git a/dll/win32/shdocvw/Si.rc b/dll/win32/shdocvw/Si.rc
new file mode 100644
index 00000000000..35d501444c5
--- /dev/null
+++ b/dll/win32/shdocvw/Si.rc
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010 Matej Spindler
+ *
+ * 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 "resource.h"
+
+#pragma code_page(65001)
+
+LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Open URL"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Vnesite interneti naslov dokumenta, ki ga bo Internet Explorer odpru.",-1,25, 5, 150,15
+ LTEXT "Odpri:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&V redu", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&Prekliči", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Datoteka"
+ {
+ POPUP "&Nov"
+ {
+ MENUITEM "&Okno" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Odpri ...", ID_BROWSE_OPEN
+ MENUITEM "&Shrani", ID_BROWSE_SAVE
+ MENUITEM "Shrani &kot ...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "Nastavitve tiskanja ...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "Na&tisni ...", ID_BROWSE_PRINT
+ MENUITEM "Predo&gled tiskanja ...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Lastnosti ...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Zapri", ID_BROWSE_QUIT
+ }
+ POPUP "Pogl&ed"
+ {
+ POPUP "Oro&dne vrstice"
+ {
+ MENUITEM "&Statusna vrstica" ID_BROWSE_BAR_STD
+ MENUITEM "&Naslovna vrstica" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Priljubljene"
+ {
+ MENUITEM "&Dodaj med priljubljene ..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Pomoč"
+ {
+ MENUITEM "O programu Internet Explorer ...",ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Nazaj"
+ IDS_TB_FORWARD "Naprej"
+ IDS_TB_STOP "Stop"
+ IDS_TB_REFRESH "Osveži"
+ IDS_TB_HOME "Domov"
+ IDS_TB_PRINT "Natisni"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Naslov"
+}
diff --git a/dll/win32/shdocvw/Sr.rc b/dll/win32/shdocvw/Sr.rc
new file mode 100644
index 00000000000..5fd9e72b9b2
--- /dev/null
+++ b/dll/win32/shdocvw/Sr.rc
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2010 Alexander N. Sørnes
+ * Copyright 2010 Đorđe Vasiljević
+ *
+ * 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 "resource.h"
+
+#pragma code_page(65001)
+
+LANGUAGE LANG_SERBIAN, SUBLANG_SERBIAN_CYRILLIC
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Отварање адресе"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Унесите адресу коју желите да отворите у Internet Explorer-у",-1,25, 5, 150,15
+ LTEXT "Отвори:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&У реду", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&Откажи", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Датотека"
+ {
+ POPUP "&Ново"
+ {
+ MENUITEM "&Прозор" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Отвори...", ID_BROWSE_OPEN
+ MENUITEM "&Сачувај", ID_BROWSE_SAVE
+ MENUITEM "Сачувај &као...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "Формат &штампе...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "&Штампај...", ID_BROWSE_PRINT
+ MENUITEM "&Преглед штампе...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Својства...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Затвори", ID_BROWSE_QUIT
+ }
+ POPUP "&Приказ"
+ {
+ POPUP "&Алатнице"
+ {
+ MENUITEM "&Стандардна трака" ID_BROWSE_BAR_STD
+ MENUITEM "&Трака за навигацију" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Омиљено"
+ {
+ MENUITEM "&Додај у омиљене..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Помоћ"
+ {
+ MENUITEM "&О Internet Explorer-у...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Назад"
+ IDS_TB_FORWARD "Напред"
+ IDS_TB_STOP "Заустави"
+ IDS_TB_REFRESH "Освежи"
+ IDS_TB_HOME "Почетна"
+ IDS_TB_PRINT "Штампај"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Адреса"
+}
+
+LANGUAGE LANG_SERBIAN, SUBLANG_SERBIAN_LATIN
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Otvaranje adrese"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Unesite adresu koju želite da otvorite u Internet Explorer-u",-1,25, 5, 150,15
+ LTEXT "Otvori:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&U redu", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&Otkaži", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Datoteka"
+ {
+ POPUP "&Novo"
+ {
+ MENUITEM "&Prozor" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Otvori...", ID_BROWSE_OPEN
+ MENUITEM "&Sačuvaj", ID_BROWSE_SAVE
+ MENUITEM "Sačuvaj &kao...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "Format &štampe...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "&Štampaj...", ID_BROWSE_PRINT
+ MENUITEM "&Pregled štampe...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Svojstva...", ID_BROWSE_PROPERTIES
+ MENUITEM "&Zatvori", ID_BROWSE_QUIT
+ }
+ POPUP "&Prikaz"
+ {
+ POPUP "&Alatnice"
+ {
+ MENUITEM "&Standardna traka" ID_BROWSE_BAR_STD
+ MENUITEM "&Traka za navigaciju" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Omiljeno"
+ {
+ MENUITEM "&Dodaj u omiljene..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Pomoć"
+ {
+ MENUITEM "&O Internet Explorer-u...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Nazad"
+ IDS_TB_FORWARD "Napred"
+ IDS_TB_STOP "Zaustavi"
+ IDS_TB_REFRESH "Osveži"
+ IDS_TB_HOME "Početna"
+ IDS_TB_PRINT "Štampaj"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Adresa"
+}
diff --git a/dll/win32/shdocvw/Sv.rc b/dll/win32/shdocvw/Sv.rc
new file mode 100644
index 00000000000..f71d4edf311
--- /dev/null
+++ b/dll/win32/shdocvw/Sv.rc
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010 Anders Jonsson
+ *
+ * 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 "resource.h"
+
+#pragma code_page(65001)
+
+LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Öppna webbadress"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Ange webbadressen du vill öppna med Internet Explorer",-1,25, 5, 150,15
+ LTEXT "Öppna:", -1, 2, 32, 20, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 25, 30, 160, 13
+ DEFPUSHBUTTON "&OK", IDOK, 25, 50, 50, 15
+ PUSHBUTTON "&Avbryt", IDCANCEL, 85, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Arkiv"
+ {
+ POPUP "&Nytt"
+ {
+ MENUITEM "&Fönster" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Öppna...", ID_BROWSE_OPEN
+ MENUITEM "&Spara", ID_BROWSE_SAVE
+ MENUITEM "S¶ som...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "U&tskriftsformat...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "Skriv &ut...", ID_BROWSE_PRINT
+ MENUITEM "&Förhandsgranska...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "&Egenskaper...", ID_BROWSE_PROPERTIES
+ MENUITEM "Stä&ng", ID_BROWSE_QUIT
+ }
+ POPUP "&Visa"
+ {
+ POPUP "Verktygs&fält"
+ {
+ MENUITEM "&Standardfält" ID_BROWSE_BAR_STD
+ MENUITEM "&Adressfält" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Favoriter"
+ {
+ MENUITEM "&Lägg till favoriter..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Hjälp"
+ {
+ MENUITEM "&Om Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Bakåt"
+ IDS_TB_FORWARD "Framåt"
+ IDS_TB_STOP "Stopp"
+ IDS_TB_REFRESH "Uppdatera"
+ IDS_TB_HOME "Hem"
+ IDS_TB_PRINT "Skriv ut"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Adress"
+}
diff --git a/dll/win32/shdocvw/Uk.rc b/dll/win32/shdocvw/Uk.rc
new file mode 100644
index 00000000000..95e14849644
--- /dev/null
+++ b/dll/win32/shdocvw/Uk.rc
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 Alexander N. Sørnes
+ * Copyright 2010 Igor Paliychuk
+ *
+ * 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 "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
+
+IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70
+STYLE DS_MODALFRAME | WS_CAPTION
+CAPTION "Відкрити URL"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Вкажіть URL, що ви хочете відкрити в Internet Explorer",-1,25, 5, 150,15
+ LTEXT "Відкрити:", -1, 2, 32, 30, 15
+ EDITTEXT IDC_BROWSE_OPEN_URL, 35, 30, 160, 13
+ DEFPUSHBUTTON "&OK", IDOK, 45, 50, 50, 15
+ PUSHBUTTON "&Скасувати", IDCANCEL, 105, 50, 50, 15
+}
+
+IDR_BROWSE_MAIN_MENU MENU
+{
+ POPUP "&Файл"
+ {
+ POPUP "&Створити"
+ {
+ MENUITEM "&Вікно" ID_BROWSE_NEW_WINDOW
+ }
+ MENUITEM "&Відкрити...", ID_BROWSE_OPEN
+ MENUITEM "&Зберегти", ID_BROWSE_SAVE
+ MENUITEM "Зберегти &як...", ID_BROWSE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "&Формат друку...", ID_BROWSE_PRINT_FORMAT
+ MENUITEM "&Друк...", ID_BROWSE_PRINT
+ MENUITEM "Попередній пе&регляд...", ID_BROWSE_PRINT_PREVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "В&ластивості...", ID_BROWSE_PROPERTIES
+ MENUITEM "За&крити", ID_BROWSE_QUIT
+ }
+ POPUP "&Вигляд"
+ {
+ POPUP "&Панелі інструментів"
+ {
+ MENUITEM "&Стандартна панель" ID_BROWSE_BAR_STD
+ MENUITEM "Рядок &адреси" ID_BROWSE_BAR_ADDR
+ }
+ }
+ POPUP "&Обране"
+ {
+ MENUITEM "&Додати до Обраного..." ID_BROWSE_ADDFAV
+ MENUITEM SEPARATOR
+ }
+ POPUP "&Довідка"
+ {
+ MENUITEM "&Про Internet Explorer...", ID_BROWSE_ABOUT
+ }
+}
+
+STRINGTABLE
+{
+ IDS_TB_BACK "Назад"
+ IDS_TB_FORWARD "Вперед"
+ IDS_TB_STOP "Зупинити"
+ IDS_TB_REFRESH "Оновити"
+ IDS_TB_HOME "Додому"
+ IDS_TB_PRINT "Друк"
+}
+
+STRINGTABLE
+{
+ IDS_ADDRESS "Адреса"
+}
diff --git a/dll/win32/shdocvw/dochost.c b/dll/win32/shdocvw/dochost.c
index b3db0125700..f74d06413ac 100644
--- a/dll/win32/shdocvw/dochost.c
+++ b/dll/win32/shdocvw/dochost.c
@@ -311,7 +311,7 @@ void create_doc_view_hwnd(DocHost *This)
doc_view_atom = RegisterClassExW(&wndclass);
}
- GetClientRect(This->frame_hwnd, &rect); /* FIXME */
+ This->container_vtbl->GetDocObjRect(This, &rect);
This->hwnd = CreateWindowExW(0, wszShell_DocObject_View,
wszShell_DocObject_View,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TABSTOP,
@@ -447,8 +447,14 @@ static HRESULT WINAPI ClOleCommandTarget_Exec(IOleCommandTarget *iface,
nCmdexecopt, debugstr_variant(pvaIn), debugstr_variant(pvaOut));
if(!pguidCmdGroup) {
- FIXME("Unimplemented cmdid %d\n", nCmdID);
- return E_NOTIMPL;
+ switch(nCmdID) {
+ case OLECMDID_UPDATECOMMANDS:
+ return This->container_vtbl->exec(This, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
+ default:
+ FIXME("Unimplemented cmdid %d\n", nCmdID);
+ return E_NOTIMPL;
+ }
+ return S_OK;
}
if(IsEqualGUID(pguidCmdGroup, &CGID_DocHostCmdPriv)) {
@@ -783,7 +789,7 @@ static const IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
PropertyNotifySink_OnRequestEdit
};
-void DocHost_Init(DocHost *This, IDispatch *disp)
+void DocHost_Init(DocHost *This, IDispatch *disp, const IDocHostContainerVtbl* container)
{
This->lpDocHostUIHandlerVtbl = &DocHostUIHandler2Vtbl;
This->lpOleCommandTargetVtbl = &OleCommandTargetVtbl;
@@ -791,6 +797,8 @@ void DocHost_Init(DocHost *This, IDispatch *disp)
This->disp = disp;
+ This->container_vtbl = container;
+
This->client_disp = NULL;
This->document = NULL;
diff --git a/dll/win32/shdocvw/frame.c b/dll/win32/shdocvw/frame.c
index eeff20adcb3..2f089c12595 100644
--- a/dll/win32/shdocvw/frame.c
+++ b/dll/win32/shdocvw/frame.c
@@ -33,6 +33,9 @@ static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface,
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = INPLACEFRAME(This);
+ }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
+ TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
+ *ppv = INPLACEFRAME(This);
}else if(IsEqualGUID(&IID_IOleInPlaceUIWindow, riid)) {
TRACE("(%p)->(IID_IOleInPlaceUIWindow %p)\n", This, ppv);
*ppv = INPLACEFRAME(This);
@@ -135,8 +138,8 @@ static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface,
LPCOLESTR pszStatusText)
{
DocHost *This = INPLACEFRAME_THIS(iface);
- FIXME("(%p)->(%s)\n", This, debugstr_w(pszStatusText));
- return E_NOTIMPL;
+ TRACE("(%p)->(%s)\n", This, debugstr_w(pszStatusText));
+ return This->container_vtbl->SetStatusText(This, pszStatusText);
}
static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
diff --git a/dll/win32/shdocvw/ie.c b/dll/win32/shdocvw/ie.c
index 9d661ca7071..2a048e3ae8f 100644
--- a/dll/win32/shdocvw/ie.c
+++ b/dll/win32/shdocvw/ie.c
@@ -47,6 +47,8 @@ static HRESULT WINAPI InternetExplorer_QueryInterface(IWebBrowser2 *iface, REFII
}else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
*ppv = CONPTCONT(&This->doc_host.cps);
+ }else if(HlinkFrame_QI(&This->hlink_frame, riid, ppv)) {
+ return S_OK;
}
if(*ppv) {
@@ -394,8 +396,10 @@ static HRESULT WINAPI InternetExplorer_get_StatusText(IWebBrowser2 *iface, BSTR
static HRESULT WINAPI InternetExplorer_put_StatusText(IWebBrowser2 *iface, BSTR StatusText)
{
InternetExplorer *This = WEBBROWSER_THIS(iface);
- FIXME("(%p)->(%s)\n", This, debugstr_w(StatusText));
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%s)\n", This, debugstr_w(StatusText));
+
+ return update_ie_statustext(This, StatusText);
}
static HRESULT WINAPI InternetExplorer_get_ToolBar(IWebBrowser2 *iface, int *Value)
@@ -426,19 +430,11 @@ static HRESULT WINAPI InternetExplorer_put_MenuBar(IWebBrowser2 *iface, VARIANT_
TRACE("(%p)->(%x)\n", This, Value);
- if((menu = GetMenu(This->frame_hwnd)))
- DestroyMenu(menu);
-
- menu = NULL;
-
if(Value)
- menu = LoadMenuW(shdocvw_hinstance, MAKEINTRESOURCEW(IDR_BROWSE_MAIN_MENU));
+ menu = This->menu;
if(!SetMenu(This->frame_hwnd, menu))
- {
- DestroyMenu(menu);
return HRESULT_FROM_WIN32(GetLastError());
- }
return S_OK;
}
diff --git a/dll/win32/shdocvw/ietoolbar.bmp b/dll/win32/shdocvw/ietoolbar.bmp
new file mode 100644
index 00000000000..d4123627329
Binary files /dev/null and b/dll/win32/shdocvw/ietoolbar.bmp differ
diff --git a/dll/win32/shdocvw/ietoolbar.svg b/dll/win32/shdocvw/ietoolbar.svg
new file mode 100644
index 00000000000..24866a919c6
--- /dev/null
+++ b/dll/win32/shdocvw/ietoolbar.svg
@@ -0,0 +1,285 @@
+
+
+
diff --git a/dll/win32/shdocvw/iexplore.c b/dll/win32/shdocvw/iexplore.c
index fa643feecfa..a0d2684894f 100644
--- a/dll/win32/shdocvw/iexplore.c
+++ b/dll/win32/shdocvw/iexplore.c
@@ -34,6 +34,9 @@
#include "shdocvw.h"
#include "mshtmcid.h"
#include "shellapi.h"
+#include "winreg.h"
+#include "shlwapi.h"
+#include "intshcut.h"
#include "wine/debug.h"
@@ -41,12 +44,299 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
#define IDI_APPICON 1
+#define DOCHOST_THIS(iface) DEFINE_THIS2(InternetExplorer,doc_host,iface)
+
static const WCHAR szIEWinFrame[] = { 'I','E','F','r','a','m','e',0 };
/* Windows uses "Microsoft Internet Explorer" */
static const WCHAR wszWineInternetExplorer[] =
{'W','i','n','e',' ','I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',0};
+HRESULT update_ie_statustext(InternetExplorer* This, LPCWSTR text)
+{
+ if(!SendMessageW(This->status_hwnd, SB_SETTEXTW, MAKEWORD(SB_SIMPLEID, 0), (LPARAM)text))
+ return E_FAIL;
+
+ return S_OK;
+}
+
+static void adjust_ie_docobj_rect(HWND frame, RECT* rc)
+{
+ HWND hwndRebar = GetDlgItem(frame, IDC_BROWSE_REBAR);
+ HWND hwndStatus = GetDlgItem(frame, IDC_BROWSE_STATUSBAR);
+ INT barHeight = SendMessageW(hwndRebar, RB_GETBARHEIGHT, 0, 0);
+
+ rc->top += barHeight;
+ rc->bottom -= barHeight;
+
+ if(IsWindowVisible(hwndStatus))
+ {
+ RECT statusrc;
+
+ GetClientRect(hwndStatus, &statusrc);
+ rc->bottom -= statusrc.bottom - statusrc.top;
+ }
+}
+
+static HMENU get_tb_menu(HMENU menu)
+{
+ HMENU menu_view = GetSubMenu(menu, 1);
+
+ return GetSubMenu(menu_view, 0);
+}
+
+static HMENU get_fav_menu(HMENU menu)
+{
+ return GetSubMenu(menu, 2);
+}
+
+static LPWSTR get_fav_url_from_id(HMENU menu, UINT id)
+{
+ MENUITEMINFOW item;
+
+ item.cbSize = sizeof(item);
+ item.fMask = MIIM_DATA;
+
+ if(!GetMenuItemInfoW(menu, id, FALSE, &item))
+ return NULL;
+
+ return (LPWSTR)item.dwItemData;
+}
+
+static void free_fav_menu_data(HMENU menu)
+{
+ LPWSTR url;
+ int i;
+
+ for(i = 0; (url = get_fav_url_from_id(menu, ID_BROWSE_GOTOFAV_FIRST + i)); i++)
+ heap_free( url );
+}
+
+static int get_menu_item_count(HMENU menu)
+{
+ MENUITEMINFOW item;
+ int count = 0;
+ int i;
+
+ item.cbSize = sizeof(item);
+ item.fMask = MIIM_DATA | MIIM_SUBMENU;
+
+ for(i = 0; GetMenuItemInfoW(menu, i, TRUE, &item); i++)
+ {
+ if(item.hSubMenu)
+ count += get_menu_item_count(item.hSubMenu);
+ else
+ count++;
+ }
+
+ return count;
+}
+
+static void add_fav_to_menu(HMENU favmenu, HMENU menu, LPWSTR title, LPCWSTR url)
+{
+ MENUITEMINFOW item;
+ /* Subtract the number of standard elements in the Favorites menu */
+ int favcount = get_menu_item_count(favmenu) - 2;
+ LPWSTR urlbuf;
+
+ if(favcount > (ID_BROWSE_GOTOFAV_MAX - ID_BROWSE_GOTOFAV_FIRST))
+ {
+ FIXME("Add support for more than %d Favorites\n", favcount);
+ return;
+ }
+
+ urlbuf = heap_alloc((lstrlenW(url) + 1) * sizeof(WCHAR));
+
+ if(!urlbuf)
+ return;
+
+ lstrcpyW(urlbuf, url);
+
+ item.cbSize = sizeof(item);
+ item.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_DATA | MIIM_ID;
+ item.fType = MFT_STRING;
+ item.dwTypeData = title;
+ item.wID = ID_BROWSE_GOTOFAV_FIRST + favcount;
+ item.dwItemData = (ULONG_PTR)urlbuf;
+ InsertMenuItemW(menu, -1, TRUE, &item);
+}
+
+static void add_favs_to_menu(HMENU favmenu, HMENU menu, LPCWSTR dir)
+{
+ WCHAR path[MAX_PATH*2];
+ const WCHAR search[] = {'*',0};
+ WCHAR* filename;
+ HANDLE findhandle;
+ WIN32_FIND_DATAW finddata;
+ IUniformResourceLocatorW* urlobj;
+ IPersistFile* urlfile;
+ HRESULT res;
+
+ lstrcpyW(path, dir);
+ PathAppendW(path, search);
+
+ findhandle = FindFirstFileW(path, &finddata);
+
+ if(findhandle == INVALID_HANDLE_VALUE)
+ return;
+
+ res = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, &IID_IUniformResourceLocatorW, (PVOID*)&urlobj);
+
+ if(SUCCEEDED(res))
+ res = IUnknown_QueryInterface(urlobj, &IID_IPersistFile, (PVOID*)&urlfile);
+
+ if(SUCCEEDED(res))
+ {
+ filename = path + lstrlenW(path) - lstrlenW(search);
+
+ do
+ {
+ lstrcpyW(filename, finddata.cFileName);
+
+ if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ MENUITEMINFOW item;
+ const WCHAR ignore1[] = {'.','.',0};
+ const WCHAR ignore2[] = {'.',0};
+
+ if(!lstrcmpW(filename, ignore1) || !lstrcmpW(filename, ignore2))
+ continue;
+
+ item.cbSize = sizeof(item);
+ item.fMask = MIIM_STRING | MIIM_SUBMENU;
+ item.dwTypeData = filename;
+ item.hSubMenu = CreatePopupMenu();
+ InsertMenuItemW(menu, -1, TRUE, &item);
+ add_favs_to_menu(favmenu, item.hSubMenu, path);
+ } else
+ {
+ WCHAR* fileext;
+ WCHAR* url = NULL;
+ const WCHAR urlext[] = {'.','u','r','l',0};
+
+ if(lstrcmpiW(PathFindExtensionW(filename), urlext))
+ continue;
+
+ if(FAILED(IPersistFile_Load(urlfile, path, 0)))
+ continue;
+
+ urlobj->lpVtbl->GetURL(urlobj, &url);
+
+ if(!url)
+ continue;
+
+ fileext = filename + lstrlenW(filename) - lstrlenW(urlext);
+ *fileext = 0;
+ add_fav_to_menu(favmenu, menu, filename, url);
+ }
+ } while(FindNextFileW(findhandle, &finddata));
+ }
+
+ if(urlfile)
+ IPersistFile_Release(urlfile);
+
+ if(urlobj)
+ IUnknown_Release(urlobj);
+
+ FindClose(findhandle);
+}
+
+static void add_tbs_to_menu(HMENU menu)
+{
+ HUSKEY toolbar_handle;
+ WCHAR toolbar_key[] = {'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\',
+ 'I','n','t','e','r','n','e','t',' ',
+ 'E','x','p','l','o','r','e','r','\\',
+ 'T','o','o','l','b','a','r',0};
+
+ if(SHRegOpenUSKeyW(toolbar_key, KEY_READ, NULL, &toolbar_handle, TRUE) == ERROR_SUCCESS)
+ {
+ HUSKEY classes_handle;
+ WCHAR classes_key[] = {'S','o','f','t','w','a','r','e','\\',
+ 'C','l','a','s','s','e','s','\\','C','L','S','I','D',0};
+ WCHAR guid[39];
+ DWORD value_len = sizeof(guid)/sizeof(guid[0]);
+ int i;
+
+ if(SHRegOpenUSKeyW(classes_key, KEY_READ, NULL, &classes_handle, TRUE) != ERROR_SUCCESS)
+ {
+ SHRegCloseUSKey(toolbar_handle);
+ ERR("Failed to open key %s\n", debugstr_w(classes_key));
+ return;
+ }
+
+ for(i = 0; SHRegEnumUSValueW(toolbar_handle, i, guid, &value_len, NULL, NULL, NULL, SHREGENUM_HKLM) == ERROR_SUCCESS; i++)
+ {
+ WCHAR tb_name[100];
+ DWORD tb_name_len = sizeof(tb_name)/sizeof(tb_name[0]);
+ HUSKEY tb_class_handle;
+ MENUITEMINFOW item;
+ LSTATUS ret;
+ value_len = sizeof(guid)/sizeof(guid[0]);
+
+ if(lstrlenW(guid) != 38)
+ {
+ TRACE("Found invalid IE toolbar entry: %s\n", debugstr_w(guid));
+ continue;
+ }
+
+ if(SHRegOpenUSKeyW(guid, KEY_READ, classes_handle, &tb_class_handle, TRUE) != ERROR_SUCCESS)
+ {
+ ERR("Failed to get class info for %s\n", debugstr_w(guid));
+ continue;
+ }
+
+ ret = SHRegQueryUSValueW(tb_class_handle, NULL, NULL, tb_name, &tb_name_len, TRUE, NULL, 0);
+
+ SHRegCloseUSKey(tb_class_handle);
+
+ if(ret != ERROR_SUCCESS)
+ {
+ ERR("Failed to get toolbar name for %s\n", debugstr_w(guid));
+ continue;
+ }
+
+ item.cbSize = sizeof(item);
+ item.fMask = MIIM_STRING;
+ item.dwTypeData = tb_name;
+ InsertMenuItemW(menu, GetMenuItemCount(menu), TRUE, &item);
+ }
+
+ SHRegCloseUSKey(classes_handle);
+ SHRegCloseUSKey(toolbar_handle);
+ }
+}
+
+static HMENU create_ie_menu(void)
+{
+ HMENU menu = LoadMenuW(shdocvw_hinstance, MAKEINTRESOURCEW(IDR_BROWSE_MAIN_MENU));
+ HMENU favmenu = get_fav_menu(menu);
+ WCHAR path[MAX_PATH];
+
+ add_tbs_to_menu(get_tb_menu(menu));
+
+ if(SHGetFolderPathW(NULL, CSIDL_COMMON_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path) == S_OK)
+ add_favs_to_menu(favmenu, favmenu, path);
+
+ if(SHGetFolderPathW(NULL, CSIDL_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path) == S_OK)
+ add_favs_to_menu(favmenu, favmenu, path);
+
+ return menu;
+}
+
+static void ie_navigate(InternetExplorer* This, LPCWSTR url)
+{
+ VARIANT variant;
+
+ V_VT(&variant) = VT_BSTR;
+ V_BSTR(&variant) = SysAllocString(url);
+
+ IWebBrowser2_Navigate2(WEBBROWSER2(This), &variant, NULL, NULL, NULL, NULL);
+
+ SysFreeString(V_BSTR(&variant));
+}
+
static INT_PTR CALLBACK ie_dialog_open_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
static InternetExplorer* This;
@@ -81,7 +371,7 @@ static INT_PTR CALLBACK ie_dialog_open_proc(HWND hwnd, UINT msg, WPARAM wparam,
V_VT(&url) = VT_BSTR;
V_BSTR(&url) = SysAllocStringLen(NULL, len);
- GetWindowTextW(hwndurl, V_BSTR(&url), len);
+ GetWindowTextW(hwndurl, V_BSTR(&url), len + 1);
IWebBrowser2_Navigate2(WEBBROWSER2(This), &url, NULL, NULL, NULL, NULL);
SysFreeString(V_BSTR(&url));
@@ -105,32 +395,169 @@ static void ie_dialog_about(HWND hwnd)
DestroyIcon(icon);
}
+static void add_tb_separator(HWND hwnd)
+{
+ TBBUTTON btn;
+
+ ZeroMemory(&btn, sizeof(btn));
+
+ btn.iBitmap = 3;
+ btn.fsStyle = BTNS_SEP;
+ SendMessageW(hwnd, TB_ADDBUTTONSW, 1, (LPARAM)&btn);
+}
+
+static void add_tb_button(HWND hwnd, int bmp, int cmd, int strId)
+{
+ TBBUTTON btn;
+ WCHAR buf[30];
+
+ LoadStringW(shdocvw_hinstance, strId, buf, sizeof(buf)/sizeof(buf[0]));
+
+ btn.iBitmap = bmp;
+ btn.idCommand = cmd;
+ btn.fsState = TBSTATE_ENABLED;
+ btn.fsStyle = BTNS_SHOWTEXT;
+ btn.dwData = 0;
+ btn.iString = (INT_PTR)buf;
+
+ SendMessageW(hwnd, TB_ADDBUTTONSW, 1, (LPARAM)&btn);
+}
+
+static void create_rebar(HWND hwnd)
+{
+ HWND hwndRebar;
+ HWND hwndAddress;
+ HWND hwndToolbar;
+ REBARINFO rebarinf;
+ REBARBANDINFOW bandinf;
+ WCHAR addr[40];
+ HIMAGELIST imagelist;
+ WCHAR idb_ietoolbar[] = {'I','D','B','_','I','E','T','O','O','L','B','A','R',0};
+
+ LoadStringW(shdocvw_hinstance, IDS_ADDRESS, addr, sizeof(addr)/sizeof(addr[0]));
+
+ hwndRebar = CreateWindowExW(WS_EX_TOOLWINDOW, REBARCLASSNAMEW, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|RBS_VARHEIGHT|CCS_TOP|CCS_NODIVIDER, 0, 0, 0, 0, hwnd, (HMENU)IDC_BROWSE_REBAR, shdocvw_hinstance, NULL);
+
+ rebarinf.cbSize = sizeof(rebarinf);
+ rebarinf.fMask = 0;
+ rebarinf.himl = NULL;
+ rebarinf.cbSize = sizeof(rebarinf);
+
+ SendMessageW(hwndRebar, RB_SETBARINFO, 0, (LPARAM)&rebarinf);
+
+ hwndToolbar = CreateWindowExW(TBSTYLE_EX_MIXEDBUTTONS, TOOLBARCLASSNAMEW, NULL, TBSTYLE_FLAT | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwndRebar, (HMENU)IDC_BROWSE_TOOLBAR, shdocvw_hinstance, NULL);
+
+ imagelist = ImageList_LoadImageW(shdocvw_hinstance, idb_ietoolbar, 32, 0, CLR_NONE, IMAGE_BITMAP, LR_CREATEDIBSECTION);
+
+ SendMessageW(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)imagelist);
+ SendMessageW(hwndToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
+ add_tb_button(hwndToolbar, 0, 0, IDS_TB_BACK);
+ add_tb_button(hwndToolbar, 1, 0, IDS_TB_FORWARD);
+ add_tb_button(hwndToolbar, 2, 0, IDS_TB_STOP);
+ add_tb_button(hwndToolbar, 3, 0, IDS_TB_REFRESH);
+ add_tb_button(hwndToolbar, 4, ID_BROWSE_HOME, IDS_TB_HOME);
+ add_tb_separator(hwndToolbar);
+ add_tb_button(hwndToolbar, 5, ID_BROWSE_PRINT, IDS_TB_PRINT);
+ SendMessageW(hwndToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(55,50));
+ SendMessageW(hwndToolbar, TB_AUTOSIZE, 0, 0);
+
+ bandinf.cbSize = sizeof(bandinf);
+ bandinf.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;
+ bandinf.fStyle = RBBS_CHILDEDGE;
+ bandinf.cx = 100;
+ bandinf.cyMinChild = 52;
+ bandinf.hwndChild = hwndToolbar;
+
+ SendMessageW(hwndRebar, RB_INSERTBANDW, -1, (LPARAM)&bandinf);
+
+ hwndAddress = CreateWindowExW(0, WC_COMBOBOXEXW, NULL, WS_BORDER|WS_CHILD|WS_VISIBLE|CBS_DROPDOWN, 0, 0, 100,20,hwndRebar, (HMENU)IDC_BROWSE_ADDRESSBAR, shdocvw_hinstance, NULL);
+
+ bandinf.fMask |= RBBIM_TEXT;
+ bandinf.fStyle = RBBS_CHILDEDGE | RBBS_BREAK;
+ bandinf.lpText = addr;
+ bandinf.cyMinChild = 20;
+ bandinf.hwndChild = hwndAddress;
+
+ SendMessageW(hwndRebar, RB_INSERTBANDW, -1, (LPARAM)&bandinf);
+}
+
static LRESULT iewnd_OnCreate(HWND hwnd, LPCREATESTRUCTW lpcs)
{
+ InternetExplorer* This = (InternetExplorer*)lpcs->lpCreateParams;
SetWindowLongPtrW(hwnd, 0, (LONG_PTR) lpcs->lpCreateParams);
+
+ This->menu = create_ie_menu();
+
+ This->status_hwnd = CreateStatusWindowW(CCS_NODIVIDER|WS_CHILD|WS_VISIBLE, NULL, hwnd, IDC_BROWSE_STATUSBAR);
+ SendMessageW(This->status_hwnd, SB_SIMPLE, TRUE, 0);
+
+ create_rebar(hwnd);
+
return 0;
}
static LRESULT iewnd_OnSize(InternetExplorer *This, INT width, INT height)
{
+ HWND hwndRebar = GetDlgItem(This->frame_hwnd, IDC_BROWSE_REBAR);
+ INT barHeight = SendMessageW(hwndRebar, RB_GETBARHEIGHT, 0, 0);
+ RECT docarea = {0, 0, width, height};
+
+ SendMessageW(This->status_hwnd, WM_SIZE, 0, 0);
+
+ adjust_ie_docobj_rect(This->frame_hwnd, &docarea);
+
if(This->doc_host.hwnd)
- SetWindowPos(This->doc_host.hwnd, NULL, 0, 0, width, height,
+ SetWindowPos(This->doc_host.hwnd, NULL, docarea.left, docarea.top, docarea.right, docarea.bottom,
SWP_NOZORDER | SWP_NOACTIVATE);
+ SetWindowPos(hwndRebar, NULL, 0, 0, width, barHeight, SWP_NOZORDER | SWP_NOACTIVATE);
+
+ return 0;
+}
+
+static LRESULT iewnd_OnNotify(InternetExplorer *This, WPARAM wparam, LPARAM lparam)
+{
+ NMHDR* hdr = (NMHDR*)lparam;
+
+ if(hdr->idFrom == IDC_BROWSE_ADDRESSBAR && hdr->code == CBEN_ENDEDITW)
+ {
+ NMCBEENDEDITW* info = (NMCBEENDEDITW*)lparam;
+
+ if(info->fChanged && info->iWhy == CBENF_RETURN && info->szText)
+ {
+ VARIANT vt;
+
+ V_VT(&vt) = VT_BSTR;
+ V_BSTR(&vt) = SysAllocString(info->szText);
+
+ IWebBrowser2_Navigate2(WEBBROWSER2(This), &vt, NULL, NULL, NULL, NULL);
+
+ SysFreeString(V_BSTR(&vt));
+
+ return 0;
+ }
+ }
+
return 0;
}
static LRESULT iewnd_OnDestroy(InternetExplorer *This)
{
+ HWND hwndRebar = GetDlgItem(This->frame_hwnd, IDC_BROWSE_REBAR);
+ HWND hwndToolbar = GetDlgItem(hwndRebar, IDC_BROWSE_TOOLBAR);
+ HIMAGELIST list = (HIMAGELIST)SendMessageW(hwndToolbar, TB_GETIMAGELIST, 0, 0);
+
TRACE("%p\n", This);
+ free_fav_menu_data(get_fav_menu(This->menu));
+ ImageList_Destroy(list);
This->frame_hwnd = NULL;
PostQuitMessage(0); /* FIXME */
return 0;
}
-static LRESULT CALLBACK iewnd_OnCommand(InternetExplorer *This, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+static LRESULT iewnd_OnCommand(InternetExplorer *This, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(LOWORD(wparam))
{
@@ -152,16 +579,43 @@ static LRESULT CALLBACK iewnd_OnCommand(InternetExplorer *This, HWND hwnd, UINT
}
break;
+ case ID_BROWSE_HOME:
+ IWebBrowser2_GoHome(WEBBROWSER2(This));
+ break;
+
case ID_BROWSE_ABOUT:
ie_dialog_about(hwnd);
break;
+ case ID_BROWSE_QUIT:
+ iewnd_OnDestroy(This);
+ break;
+
default:
+ if(LOWORD(wparam) >= ID_BROWSE_GOTOFAV_FIRST && LOWORD(wparam) <= ID_BROWSE_GOTOFAV_MAX)
+ {
+ LPCWSTR url = get_fav_url_from_id(get_fav_menu(This->menu), LOWORD(wparam));
+
+ if(url)
+ ie_navigate(This, url);
+ }
return DefWindowProcW(hwnd, msg, wparam, lparam);
}
return 0;
}
+static LRESULT update_addrbar(InternetExplorer *This, LPARAM lparam)
+{
+ HWND hwndRebar = GetDlgItem(This->frame_hwnd, IDC_BROWSE_REBAR);
+ HWND hwndAddress = GetDlgItem(hwndRebar, IDC_BROWSE_ADDRESSBAR);
+ HWND hwndEdit = (HWND)SendMessageW(hwndAddress, CBEM_GETEDITCONTROL, 0, 0);
+ LPCWSTR url = (LPCWSTR)lparam;
+
+ SendMessageW(hwndEdit, WM_SETTEXT, 0, (LPARAM)url);
+
+ return 0;
+}
+
static LRESULT CALLBACK
ie_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
@@ -177,8 +631,12 @@ ie_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
return iewnd_OnSize(This, LOWORD(lparam), HIWORD(lparam));
case WM_COMMAND:
return iewnd_OnCommand(This, hwnd, msg, wparam, lparam);
+ case WM_NOTIFY:
+ return iewnd_OnNotify(This, wparam, lparam);
case WM_DOCHOSTTASK:
return process_dochost_task(&This->doc_host, lparam);
+ case WM_UPDATEADDRBAR:
+ return update_addrbar(This, lparam);
}
return DefWindowProcW(hwnd, msg, wparam, lparam);
}
@@ -264,6 +722,35 @@ static IWebBrowser2 *create_ie_window(LPCSTR cmdline)
return wb;
}
+static void WINAPI DocHostContainer_GetDocObjRect(DocHost* This, RECT* rc)
+{
+ GetClientRect(This->frame_hwnd, rc);
+ adjust_ie_docobj_rect(This->frame_hwnd, rc);
+}
+
+static HRESULT WINAPI DocHostContainer_SetStatusText(DocHost* This, LPCWSTR text)
+{
+ InternetExplorer* ie = DOCHOST_THIS(This);
+ return update_ie_statustext(ie, text);
+}
+
+static void WINAPI DocHostContainer_SetURL(DocHost* This, LPCWSTR url)
+{
+ SendMessageW(This->frame_hwnd, WM_UPDATEADDRBAR, 0, (LPARAM)url);
+}
+
+static HRESULT DocHostContainer_exec(DocHost* This, const GUID *cmd_group, DWORD cmdid, DWORD execopt, VARIANT *in,
+ VARIANT *out)
+{
+ return S_OK;
+}
+static const IDocHostContainerVtbl DocHostContainerVtbl = {
+ DocHostContainer_GetDocObjRect,
+ DocHostContainer_SetStatusText,
+ DocHostContainer_SetURL,
+ DocHostContainer_exec
+};
+
HRESULT InternetExplorer_Create(IUnknown *pOuter, REFIID riid, void **ppv)
{
InternetExplorer *ret;
@@ -275,10 +762,12 @@ HRESULT InternetExplorer_Create(IUnknown *pOuter, REFIID riid, void **ppv)
ret->ref = 0;
ret->doc_host.disp = (IDispatch*)WEBBROWSER2(ret);
- DocHost_Init(&ret->doc_host, (IDispatch*)WEBBROWSER2(ret));
+ DocHost_Init(&ret->doc_host, (IDispatch*)WEBBROWSER2(ret), &DocHostContainerVtbl);
InternetExplorer_WebBrowser_Init(ret);
+ HlinkFrame_Init(&ret->hlink_frame, (IUnknown*)WEBBROWSER2(ret), &ret->doc_host);
+
create_frame_hwnd(ret);
ret->doc_host.frame_hwnd = ret->frame_hwnd;
diff --git a/dll/win32/shdocvw/intshcut.c b/dll/win32/shdocvw/intshcut.c
index 8c17873453a..202a523d1f3 100644
--- a/dll/win32/shdocvw/intshcut.c
+++ b/dll/win32/shdocvw/intshcut.c
@@ -27,11 +27,17 @@
* The installer for the Zuma Deluxe Popcap game is good for testing.
*/
+#include
+#include
+
#include "wine/debug.h"
#include "shdocvw.h"
#include "objidl.h"
#include "shobjidl.h"
#include "intshcut.h"
+#include "shellapi.h"
+#include "winreg.h"
+#include "shlwapi.h"
WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
@@ -237,8 +243,47 @@ static HRESULT WINAPI UniformResourceLocatorW_GetUrl(IUniformResourceLocatorW *u
static HRESULT WINAPI UniformResourceLocatorW_InvokeCommand(IUniformResourceLocatorW *url, PURLINVOKECOMMANDINFOW pCommandInfo)
{
- FIXME("(%p, %p): stub\n", url, pCommandInfo);
- return E_NOTIMPL;
+ InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
+ WCHAR app[64];
+ HKEY hkey;
+ static const WCHAR wszURLProtocol[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};
+ SHELLEXECUTEINFOW sei;
+ DWORD res, type;
+ HRESULT hres;
+
+ TRACE("%p %p\n", This, pCommandInfo );
+
+ if (pCommandInfo->dwcbSize < sizeof (URLINVOKECOMMANDINFOW))
+ return E_INVALIDARG;
+
+ if (pCommandInfo->dwFlags != IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB)
+ {
+ FIXME("(%p, %p): non-default verbs not implemented\n", url, pCommandInfo);
+ return E_NOTIMPL;
+ }
+
+ hres = CoInternetParseUrl(This->url, PARSE_SCHEMA, 0, app, sizeof(app)/sizeof(WCHAR), NULL, 0);
+ if(FAILED(hres))
+ return E_FAIL;
+
+ res = RegOpenKeyW(HKEY_CLASSES_ROOT, app, &hkey);
+ if(res != ERROR_SUCCESS)
+ return E_FAIL;
+
+ res = RegQueryValueExW(hkey, wszURLProtocol, NULL, &type, NULL, NULL);
+ RegCloseKey(hkey);
+ if(res != ERROR_SUCCESS || type != REG_SZ)
+ return E_FAIL;
+
+ memset(&sei, 0, sizeof(sei));
+ sei.cbSize = sizeof(sei);
+ sei.lpFile = This->url;
+ sei.nShow = SW_SHOW;
+
+ if( ShellExecuteExW(&sei) )
+ return S_OK;
+ else
+ return E_FAIL;
}
static HRESULT WINAPI UniformResourceLocatorA_QueryInterface(IUniformResourceLocatorA *url, REFIID riid, PVOID *ppvObject)
@@ -299,8 +344,26 @@ static HRESULT WINAPI UniformResourceLocatorA_GetUrl(IUniformResourceLocatorA *u
static HRESULT WINAPI UniformResourceLocatorA_InvokeCommand(IUniformResourceLocatorA *url, PURLINVOKECOMMANDINFOA pCommandInfo)
{
- FIXME("(%p, %p): stub\n", url, pCommandInfo);
- return E_NOTIMPL;
+ URLINVOKECOMMANDINFOW wideCommandInfo;
+ int len;
+ WCHAR *wideVerb;
+ HRESULT res;
+ InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
+
+ wideCommandInfo.dwcbSize = sizeof wideCommandInfo;
+ wideCommandInfo.dwFlags = pCommandInfo->dwFlags;
+ wideCommandInfo.hwndParent = pCommandInfo->hwndParent;
+
+ len = MultiByteToWideChar(CP_ACP, 0, pCommandInfo->pcszVerb, -1, NULL, 0);
+ wideVerb = heap_alloc(len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, pCommandInfo->pcszVerb, -1, wideVerb, len);
+
+ wideCommandInfo.pcszVerb = wideVerb;
+
+ res = UniformResourceLocatorW_InvokeCommand(&This->uniformResourceLocatorW, &wideCommandInfo);
+ heap_free(wideVerb);
+
+ return res;
}
static HRESULT WINAPI PersistFile_QueryInterface(IPersistFile *pFile, REFIID riid, PVOID *ppvObject)
@@ -506,6 +569,22 @@ static const IPersistFileVtbl persistFileVtbl = {
PersistFile_GetCurFile
};
+static InternetShortcut *create_shortcut(void)
+{
+ InternetShortcut *newshortcut;
+
+ newshortcut = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(InternetShortcut));
+ if (newshortcut)
+ {
+ newshortcut->uniformResourceLocatorA.lpVtbl = &uniformResourceLocatorAVtbl;
+ newshortcut->uniformResourceLocatorW.lpVtbl = &uniformResourceLocatorWVtbl;
+ newshortcut->persistFile.lpVtbl = &persistFileVtbl;
+ newshortcut->refCount = 0;
+ }
+
+ return newshortcut;
+}
+
HRESULT InternetShortcut_Create(IUnknown *pOuter, REFIID riid, void **ppv)
{
InternetShortcut *This;
@@ -518,13 +597,9 @@ HRESULT InternetShortcut_Create(IUnknown *pOuter, REFIID riid, void **ppv)
if(pOuter)
return CLASS_E_NOAGGREGATION;
- This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(InternetShortcut));
+ This = create_shortcut();
if (This)
{
- This->uniformResourceLocatorA.lpVtbl = &uniformResourceLocatorAVtbl;
- This->uniformResourceLocatorW.lpVtbl = &uniformResourceLocatorWVtbl;
- This->persistFile.lpVtbl = &persistFileVtbl;
- This->refCount = 0;
hr = Unknown_QueryInterface(This, riid, ppv);
if (SUCCEEDED(hr))
SHDOCVW_LockModule();
@@ -535,3 +610,39 @@ HRESULT InternetShortcut_Create(IUnknown *pOuter, REFIID riid, void **ppv)
else
return E_OUTOFMEMORY;
}
+
+
+/**********************************************************************
+ * OpenURL (SHDOCVW.@)
+ */
+void WINAPI OpenURL(HWND hWnd, HINSTANCE hInst, LPCSTR lpcstrUrl, int nShowCmd)
+{
+ InternetShortcut *shortcut;
+ WCHAR* urlfilepath = NULL;
+ shortcut = create_shortcut();
+
+ if (shortcut)
+ {
+ int len;
+
+ len = MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, NULL, 0);
+ urlfilepath = heap_alloc(len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, urlfilepath, len);
+
+ if(SUCCEEDED(IPersistFile_Load(&shortcut->persistFile, urlfilepath, 0)))
+ {
+ URLINVOKECOMMANDINFOW ici;
+
+ memset( &ici, 0, sizeof ici );
+ ici.dwcbSize = sizeof ici;
+ ici.dwFlags = IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB;
+ ici.hwndParent = hWnd;
+
+ if FAILED(UniformResourceLocatorW_InvokeCommand(&shortcut->uniformResourceLocatorW, (PURLINVOKECOMMANDINFOW) &ici))
+ TRACE("failed to open URL: %s\n.",debugstr_a(lpcstrUrl));
+ }
+
+ heap_free(shortcut);
+ heap_free(urlfilepath);
+ }
+}
diff --git a/dll/win32/shdocvw/navigate.c b/dll/win32/shdocvw/navigate.c
index 6d73fd98b29..a160ee2b52e 100644
--- a/dll/win32/shdocvw/navigate.c
+++ b/dll/win32/shdocvw/navigate.c
@@ -125,6 +125,8 @@ static HRESULT set_dochost_url(DocHost *This, const WCHAR *url)
heap_free(This->url);
This->url = new_url;
+
+ This->container_vtbl->SetURL(This, This->url);
return S_OK;
}
@@ -759,7 +761,7 @@ HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags,
Flags, Flags ? V_VT(Flags) : -1, TargetFrameName,
TargetFrameName ? V_VT(TargetFrameName) : -1);
- if(PostData && V_VT(PostData) == (VT_ARRAY | VT_UI1)) {
+ if(PostData && V_VT(PostData) == (VT_ARRAY | VT_UI1) && V_ARRAY(PostData)) {
SafeArrayAccessData(V_ARRAY(PostData), (void**)&post_data);
post_data_len = V_ARRAY(PostData)->rgsabound[0].cElements;
}
@@ -781,7 +783,8 @@ HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags,
DWORD size;
size = sizeof(new_url)/sizeof(WCHAR);
- hres = UrlApplySchemeW(url, new_url, &size, URL_APPLY_GUESSSCHEME);
+ hres = UrlApplySchemeW(url, new_url, &size,
+ URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT);
if(FAILED(hres)) {
WARN("UrlApplyScheme failed: %08x\n", hres);
new_url[0] = 0;
@@ -881,30 +884,30 @@ HRESULT go_home(DocHost *This)
return navigate_url(This, wszPageName, NULL, NULL, NULL, NULL);
}
-#define HLINKFRAME_THIS(iface) DEFINE_THIS(WebBrowser, HlinkFrame, iface)
+#define HLINKFRAME_THIS(iface) DEFINE_THIS(HlinkFrame, IHlinkFrame, iface)
static HRESULT WINAPI HlinkFrame_QueryInterface(IHlinkFrame *iface, REFIID riid, void **ppv)
{
- WebBrowser *This = HLINKFRAME_THIS(iface);
- return IWebBrowser2_QueryInterface(WEBBROWSER2(This), riid, ppv);
+ HlinkFrame *This = HLINKFRAME_THIS(iface);
+ return IUnknown_QueryInterface(This->outer, riid, ppv);
}
static ULONG WINAPI HlinkFrame_AddRef(IHlinkFrame *iface)
{
- WebBrowser *This = HLINKFRAME_THIS(iface);
- return IWebBrowser2_AddRef(WEBBROWSER2(This));
+ HlinkFrame *This = HLINKFRAME_THIS(iface);
+ return IUnknown_AddRef(This->outer);
}
static ULONG WINAPI HlinkFrame_Release(IHlinkFrame *iface)
{
- WebBrowser *This = HLINKFRAME_THIS(iface);
- return IWebBrowser2_Release(WEBBROWSER2(This));
+ HlinkFrame *This = HLINKFRAME_THIS(iface);
+ return IUnknown_Release(This->outer);
}
static HRESULT WINAPI HlinkFrame_SetBrowseContext(IHlinkFrame *iface,
IHlinkBrowseContext *pihlbc)
{
- WebBrowser *This = HLINKFRAME_THIS(iface);
+ HlinkFrame *This = HLINKFRAME_THIS(iface);
FIXME("(%p)->(%p)\n", This, pihlbc);
return E_NOTIMPL;
}
@@ -912,7 +915,7 @@ static HRESULT WINAPI HlinkFrame_SetBrowseContext(IHlinkFrame *iface,
static HRESULT WINAPI HlinkFrame_GetBrowseContext(IHlinkFrame *iface,
IHlinkBrowseContext **ppihlbc)
{
- WebBrowser *This = HLINKFRAME_THIS(iface);
+ HlinkFrame *This = HLINKFRAME_THIS(iface);
FIXME("(%p)->(%p)\n", This, ppihlbc);
return E_NOTIMPL;
}
@@ -920,7 +923,7 @@ static HRESULT WINAPI HlinkFrame_GetBrowseContext(IHlinkFrame *iface,
static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc,
IBindStatusCallback *pibsc, IHlink *pihlNavigate)
{
- WebBrowser *This = HLINKFRAME_THIS(iface);
+ HlinkFrame *This = HLINKFRAME_THIS(iface);
IMoniker *mon;
LPWSTR location = NULL;
@@ -945,13 +948,13 @@ static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPB
return E_NOTIMPL;
}
- return navigate_hlink(&This->doc_host, mon, pbc, pibsc);
+ return navigate_hlink(This->doc_host, mon, pbc, pibsc);
}
static HRESULT WINAPI HlinkFrame_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF,
IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, DWORD dwreserved)
{
- WebBrowser *This = HLINKFRAME_THIS(iface);
+ HlinkFrame *This = HLINKFRAME_THIS(iface);
FIXME("(%p)->(%08x %p %s %s %d)\n", This, grfHLNF, pimkTarget, debugstr_w(pwzLocation),
debugstr_w(pwzFriendlyName), dwreserved);
return E_NOTIMPL;
@@ -960,7 +963,7 @@ static HRESULT WINAPI HlinkFrame_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF,
static HRESULT WINAPI HlinkFrame_UpdateHlink(IHlinkFrame *iface, ULONG uHLID,
IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
{
- WebBrowser *This = HLINKFRAME_THIS(iface);
+ HlinkFrame *This = HLINKFRAME_THIS(iface);
FIXME("(%p)->(%u %p %s %s)\n", This, uHLID, pimkTarget, debugstr_w(pwzLocation),
debugstr_w(pwzFriendlyName));
return E_NOTIMPL;
@@ -979,106 +982,106 @@ static const IHlinkFrameVtbl HlinkFrameVtbl = {
HlinkFrame_UpdateHlink
};
-#define TARGETFRAME2_THIS(iface) DEFINE_THIS(WebBrowser, ITargetFrame2, iface)
+#define TARGETFRAME2_THIS(iface) DEFINE_THIS(HlinkFrame, ITargetFrame2, iface)
static HRESULT WINAPI TargetFrame2_QueryInterface(ITargetFrame2 *iface, REFIID riid, void **ppv)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
- return IWebBrowser2_QueryInterface(WEBBROWSER2(This), riid, ppv);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
+ return IUnknown_QueryInterface(This->outer, riid, ppv);
}
static ULONG WINAPI TargetFrame2_AddRef(ITargetFrame2 *iface)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
- return IWebBrowser2_AddRef(WEBBROWSER2(This));
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
+ return IUnknown_AddRef(This->outer);
}
static ULONG WINAPI TargetFrame2_Release(ITargetFrame2 *iface)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
- return IWebBrowser2_Release(WEBBROWSER2(This));
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
+ return IUnknown_Release(This->outer);
}
static HRESULT WINAPI TargetFrame2_SetFrameName(ITargetFrame2 *iface, LPCWSTR pszFrameName)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameName));
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_GetFrameName(ITargetFrame2 *iface, LPWSTR *ppszFrameName)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%p)\n", This, ppszFrameName);
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_GetParentFrame(ITargetFrame2 *iface, IUnknown **ppunkParent)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%p)\n", This, ppunkParent);
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_SetFrameSrc(ITargetFrame2 *iface, LPCWSTR pszFrameSrc)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameSrc));
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_GetFrameSrc(ITargetFrame2 *iface, LPWSTR *ppszFrameSrc)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->()\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_GetFramesContainer(ITargetFrame2 *iface, IOleContainer **ppContainer)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%p)\n", This, ppContainer);
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_SetFrameOptions(ITargetFrame2 *iface, DWORD dwFlags)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%x)\n", This, dwFlags);
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_GetFrameOptions(ITargetFrame2 *iface, DWORD *pdwFlags)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%p)\n", This, pdwFlags);
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_SetFrameMargins(ITargetFrame2 *iface, DWORD dwWidth, DWORD dwHeight)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%d %d)\n", This, dwWidth, dwHeight);
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_GetFrameMargins(ITargetFrame2 *iface, DWORD *pdwWidth, DWORD *pdwHeight)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%p %p)\n", This, pdwWidth, pdwHeight);
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_FindFrame(ITargetFrame2 *iface, LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame);
return E_NOTIMPL;
}
static HRESULT WINAPI TargetFrame2_GetTargetAlias(ITargetFrame2 *iface, LPCWSTR pszTargetName, LPWSTR *ppszTargetAlias)
{
- WebBrowser *This = TARGETFRAME2_THIS(iface);
+ HlinkFrame *This = TARGETFRAME2_THIS(iface);
FIXME("(%p)->(%s %p)\n", This, debugstr_w(pszTargetName), ppszTargetAlias);
return E_NOTIMPL;
}
@@ -1103,8 +1106,27 @@ static const ITargetFrame2Vtbl TargetFrame2Vtbl = {
TargetFrame2_GetTargetAlias
};
-void WebBrowser_HlinkFrame_Init(WebBrowser *This)
+BOOL HlinkFrame_QI(HlinkFrame *This, REFIID riid, void **ppv)
{
- This->lpHlinkFrameVtbl = &HlinkFrameVtbl;
- This->lpITargetFrame2Vtbl = &TargetFrame2Vtbl;
+ if(IsEqualGUID(&IID_IHlinkFrame, riid)) {
+ TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv);
+ *ppv = HLINKFRAME(This);
+ }else if(IsEqualGUID(&IID_ITargetFrame2, riid)) {
+ TRACE("(%p)->(IID_ITargetFrame2 %p)\n", This, ppv);
+ *ppv = TARGETFRAME2(This);
+ }else {
+ return FALSE;
+ }
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return TRUE;
+}
+
+void HlinkFrame_Init(HlinkFrame *This, IUnknown *outer, DocHost *doc_host)
+{
+ This->lpIHlinkFrameVtbl = &HlinkFrameVtbl;
+ This->lpITargetFrame2Vtbl = &TargetFrame2Vtbl;
+
+ This->outer = outer;
+ This->doc_host = doc_host;
}
diff --git a/dll/win32/shdocvw/resource.h b/dll/win32/shdocvw/resource.h
index 31a700566fb..6f5c777061f 100644
--- a/dll/win32/shdocvw/resource.h
+++ b/dll/win32/shdocvw/resource.h
@@ -24,6 +24,11 @@
#define IDR_BROWSE_MAIN_MENU 1000
#define IDD_BROWSE_OPEN 1001
#define IDC_BROWSE_OPEN_URL 1002
+#define IDC_BROWSE_REBAR 1003
+#define IDC_BROWSE_ADDRESSBAR 1004
+#define IDC_BROWSE_STATUSBAR 1005
+#define IDC_BROWSE_TOOLBAR 1006
+#define IDB_IETOOLBAR 1007
#define ID_BROWSE_NEW_WINDOW 275
#define ID_BROWSE_OPEN 256
@@ -33,4 +38,23 @@
#define ID_BROWSE_PRINT 260
#define ID_BROWSE_PRINT_PREVIEW 277
#define ID_BROWSE_PROPERTIES 262
+#define ID_BROWSE_QUIT 278
#define ID_BROWSE_ABOUT 336
+
+#define ID_BROWSE_ADDFAV 1200
+#define ID_BROWSE_HOME 1201
+
+#define ID_BROWSE_BAR_STD 1300
+#define ID_BROWSE_BAR_ADDR 1301
+
+#define ID_BROWSE_GOTOFAV_FIRST 2000
+#define ID_BROWSE_GOTOFAV_MAX 65000
+
+#define IDS_TB_BACK 1100
+#define IDS_TB_FORWARD 1101
+#define IDS_TB_STOP 1102
+#define IDS_TB_REFRESH 1103
+#define IDS_TB_HOME 1104
+#define IDS_TB_PRINT 1105
+
+#define IDS_ADDRESS 1106
diff --git a/dll/win32/shdocvw/shdocvw.h b/dll/win32/shdocvw/shdocvw.h
index d1787cb85c4..61dc63fb0e0 100644
--- a/dll/win32/shdocvw/shdocvw.h
+++ b/dll/win32/shdocvw/shdocvw.h
@@ -43,6 +43,8 @@
#include "resource.h"
+#define WM_UPDATEADDRBAR (WM_APP+1)
+
/**********************************************************************
* Shell Instance Objects
*/
@@ -66,6 +68,14 @@ typedef struct {
IUnknown *impl;
} ConnectionPointContainer;
+typedef struct {
+ const IHlinkFrameVtbl *lpIHlinkFrameVtbl;
+ const ITargetFrame2Vtbl *lpITargetFrame2Vtbl;
+
+ IUnknown *outer;
+ DocHost *doc_host;
+} HlinkFrame;
+
struct _task_header_t;
typedef void (*task_proc_t)(DocHost*, struct _task_header_t*);
@@ -74,6 +84,14 @@ typedef struct _task_header_t {
task_proc_t proc;
} task_header_t;
+typedef struct _IDocHostContainerVtbl
+{
+ void (WINAPI* GetDocObjRect)(DocHost*,RECT*);
+ HRESULT (WINAPI* SetStatusText)(DocHost*,LPCWSTR);
+ void (WINAPI* SetURL)(DocHost*,LPCWSTR);
+ HRESULT (*exec)(DocHost*,const GUID*,DWORD,DWORD,VARIANT*,VARIANT*);
+} IDocHostContainerVtbl;
+
struct DocHost {
const IOleClientSiteVtbl *lpOleClientSiteVtbl;
const IOleInPlaceSiteVtbl *lpOleInPlaceSiteVtbl;
@@ -97,6 +115,8 @@ struct DocHost {
IOleDocumentView *view;
IUnknown *doc_navigate;
+ const IDocHostContainerVtbl *container_vtbl;
+
HWND hwnd;
HWND frame_hwnd;
@@ -128,10 +148,9 @@ struct WebBrowser {
const IViewObject2Vtbl *lpViewObjectVtbl;
const IOleInPlaceActiveObjectVtbl *lpOleInPlaceActiveObjectVtbl;
const IOleCommandTargetVtbl *lpOleCommandTargetVtbl;
- const IHlinkFrameVtbl *lpHlinkFrameVtbl;
- const ITargetFrame2Vtbl *lpITargetFrame2Vtbl;
const IServiceProviderVtbl *lpServiceProviderVtbl;
const IDataObjectVtbl *lpDataObjectVtbl;
+ HlinkFrame hlink_frame;
LONG ref;
@@ -166,10 +185,13 @@ struct WebBrowser {
struct InternetExplorer {
const IWebBrowser2Vtbl *lpWebBrowser2Vtbl;
+ HlinkFrame hlink_frame;
LONG ref;
HWND frame_hwnd;
+ HWND status_hwnd;
+ HMENU menu;
DocHost doc_host;
};
@@ -188,9 +210,7 @@ struct InternetExplorer {
#define VIEWOBJ2(x) ((IViewObject2*) &(x)->lpViewObjectVtbl);
#define ACTIVEOBJ(x) ((IOleInPlaceActiveObject*) &(x)->lpOleInPlaceActiveObjectVtbl)
#define OLECMD(x) ((IOleCommandTarget*) &(x)->lpOleCommandTargetVtbl)
-#define HLINKFRAME(x) ((IHlinkFrame*) &(x)->lpHlinkFrameVtbl)
#define DATAOBJECT(x) ((IDataObject*) &(x)->lpDataObjectVtbl)
-#define TARGETFRAME2(x) ((ITargetFrame2*) &(x)->lpITargetFrame2Vtbl)
#define CLIENTSITE(x) ((IOleClientSite*) &(x)->lpOleClientSiteVtbl)
#define INPLACESITE(x) ((IOleInPlaceSite*) &(x)->lpOleInPlaceSiteVtbl)
@@ -203,16 +223,18 @@ struct InternetExplorer {
#define INPLACEFRAME(x) ((IOleInPlaceFrame*) &(x)->lpOleInPlaceFrameVtbl)
+#define HLINKFRAME(x) ((IHlinkFrame*) &(x)->lpIHlinkFrameVtbl)
+#define TARGETFRAME2(x) ((ITargetFrame2*) &(x)->lpITargetFrame2Vtbl)
+
void WebBrowser_OleObject_Init(WebBrowser*);
void WebBrowser_ViewObject_Init(WebBrowser*);
void WebBrowser_DataObject_Init(WebBrowser*);
void WebBrowser_Persist_Init(WebBrowser*);
void WebBrowser_ClassInfo_Init(WebBrowser*);
-void WebBrowser_HlinkFrame_Init(WebBrowser*);
void WebBrowser_OleObject_Destroy(WebBrowser*);
-void DocHost_Init(DocHost*,IDispatch*);
+void DocHost_Init(DocHost*,IDispatch*,const IDocHostContainerVtbl*);
void DocHost_ClientSite_Init(DocHost*);
void DocHost_Frame_Init(DocHost*);
void release_dochost_client(DocHost*);
@@ -223,6 +245,9 @@ void DocHost_ClientSite_Release(DocHost*);
void ConnectionPointContainer_Init(ConnectionPointContainer*,IUnknown*);
void ConnectionPointContainer_Destroy(ConnectionPointContainer*);
+void HlinkFrame_Init(HlinkFrame*,IUnknown*,DocHost*);
+BOOL HlinkFrame_QI(HlinkFrame*,REFIID,void**);
+
HRESULT WebBrowserV1_Create(IUnknown*,REFIID,void**);
HRESULT WebBrowserV2_Create(IUnknown*,REFIID,void**);
@@ -247,7 +272,8 @@ HRESULT InternetShortcut_Create(IUnknown*,REFIID,void**);
HRESULT TaskbarList_Create(IUnknown*,REFIID,void**);
-#define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl)))
+#define DEFINE_THIS2(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,ifc)))
+#define DEFINE_THIS(cls,ifc,iface) DEFINE_THIS2(cls,lp ## ifc ## Vtbl,iface)
/**********************************************************************
* Dll lifetime tracking declaration for shdocvw.dll
@@ -259,6 +285,7 @@ static inline void SHDOCVW_UnlockModule(void) { InterlockedDecrement( &SHDOCVW_r
extern HINSTANCE shdocvw_hinstance;
extern void register_iewindow_class(void);
extern void unregister_iewindow_class(void);
+extern HRESULT update_ie_statustext(InternetExplorer*, LPCWSTR);
HRESULT register_class_object(BOOL);
HRESULT get_typeinfo(ITypeInfo**);
diff --git a/dll/win32/shdocvw/shdocvw.rbuild b/dll/win32/shdocvw/shdocvw.rbuild
index 47c57a97d25..c7b565269d2 100644
--- a/dll/win32/shdocvw/shdocvw.rbuild
+++ b/dll/win32/shdocvw/shdocvw.rbuild
@@ -12,6 +12,7 @@
uuid
ntdll
advapi32
+ comctl32
user32
ole32
oleaut32
diff --git a/dll/win32/shdocvw/shdocvw.rc b/dll/win32/shdocvw/shdocvw.rc
index e7276fff6c4..84549f24ac6 100644
--- a/dll/win32/shdocvw/shdocvw.rc
+++ b/dll/win32/shdocvw/shdocvw.rc
@@ -34,4 +34,22 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
/* @makedep: shdocvw.inf */
REGINST REGINST shdocvw.inf
+/* @makedep: ietoolbar.bmp */
+IDB_IETOOLBAR BITMAP ietoolbar.bmp
+
+#include "De.rc"
#include "En.rc"
+#include "Es.rc"
+#include "Fr.rc"
+#include "He.rc"
+#include "It.rc"
+#include "Ko.rc"
+#include "Lt.rc"
+#include "Nl.rc"
+//#include "Pl.rc"
+#include "Pt.rc"
+#include "Ro.rc"
+#include "Si.rc"
+#include "Sr.rc"
+#include "Sv.rc"
+#include "Uk.rc"
diff --git a/dll/win32/shdocvw/shdocvw.spec b/dll/win32/shdocvw/shdocvw.spec
index 4a0dd2c678a..be59d85c06b 100644
--- a/dll/win32/shdocvw/shdocvw.spec
+++ b/dll/win32/shdocvw/shdocvw.spec
@@ -120,7 +120,7 @@
@ stub HlinkFrameNavigateNHL
@ stub IEAboutBox
@ stub IEWriteErrorLog
-@ stub ImportPrivacySettings
+@ stdcall ImportPrivacySettings(wstr ptr ptr)
@ stub InstallReg_RunDLL
@ stdcall OpenURL(long long str long)
@ stub SHGetIDispatchForFolder
diff --git a/dll/win32/shdocvw/shdocvw_main.c b/dll/win32/shdocvw/shdocvw_main.c
index 5dfd2b99ddf..a0070b489d4 100644
--- a/dll/win32/shdocvw/shdocvw_main.c
+++ b/dll/win32/shdocvw/shdocvw_main.c
@@ -218,14 +218,6 @@ DWORD WINAPI SetQueryNetSessionCount(DWORD arg)
return 0;
}
-/**********************************************************************
- * OpenURL (SHDOCVW.@)
- */
-void WINAPI OpenURL(HWND hWnd, HINSTANCE hInst, LPCSTR lpcstrUrl, int nShowCmd)
-{
- FIXME("%p %p %s %d\n", hWnd, hInst, debugstr_a(lpcstrUrl), nShowCmd);
-}
-
/**********************************************************************
* Some forwards (by ordinal) to SHLWAPI
*/
@@ -461,3 +453,35 @@ DWORD WINAPI SHRestricted2A(DWORD restriction, LPCSTR url, DWORD reserved)
heap_free(urlW);
return res;
}
+
+/******************************************************************
+ * ImportPrivacySettings (SHDOCVW.@)
+ *
+ * Import global and/or per site privacy preferences from an xml file
+ *
+ * PARAMS
+ * filename [I] XML file to use
+ * pGlobalPrefs [IO] PTR to a usage flag for the global privacy preferences
+ * pPerSitePrefs [IO] PTR to a usage flag for the per site privacy preferences
+ *
+ * RETURNS
+ * Success: TRUE (the privacy preferences where updated)
+ * Failure: FALSE (the privacy preferences are unchanged)
+ *
+ * NOTES
+ * Set the flag to TRUE, when the related privacy preferences in the xml file
+ * should be used (parsed and overwrite the current settings).
+ * On return, the flag is TRUE, when the related privacy settings where used
+ *
+ */
+BOOL WINAPI ImportPrivacySettings(LPCWSTR filename, BOOL *pGlobalPrefs, BOOL * pPerSitePrefs)
+{
+ FIXME("(%s, %p->%d, %p->%d): stub\n", debugstr_w(filename),
+ pGlobalPrefs, pGlobalPrefs ? *pGlobalPrefs : 0,
+ pPerSitePrefs, pPerSitePrefs ? *pPerSitePrefs : 0);
+
+ if (pGlobalPrefs) *pGlobalPrefs = FALSE;
+ if (pPerSitePrefs) *pPerSitePrefs = FALSE;
+
+ return TRUE;
+}
diff --git a/dll/win32/shdocvw/webbrowser.c b/dll/win32/shdocvw/webbrowser.c
index 47996863785..ac45d858b45 100644
--- a/dll/win32/shdocvw/webbrowser.c
+++ b/dll/win32/shdocvw/webbrowser.c
@@ -100,12 +100,6 @@ static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid
}else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This, ppv);
*ppv = OLECMD(This);
- }else if(IsEqualGUID(&IID_IHlinkFrame, riid)) {
- TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv);
- *ppv = HLINKFRAME(This);
- }else if(IsEqualGUID(&IID_ITargetFrame2, riid)) {
- TRACE("(%p)->(IID_ITargetFrame2 %p)\n", This, ppv);
- *ppv = TARGETFRAME2(This);
}else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
*ppv = SERVPROV(This);
TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
@@ -133,6 +127,17 @@ static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid
}else if(IsEqualGUID(&IID_IViewObjectEx, riid)) {
TRACE("(%p)->(IID_IViewObjectEx %p) returning NULL\n", This, ppv);
return E_NOINTERFACE;
+ }else if(IsEqualGUID(&IID_IOleLink, riid)) {
+ TRACE("(%p)->(IID_IOleLink %p) returning NULL\n", This, ppv);
+ return E_NOINTERFACE;
+ }else if(IsEqualGUID(&IID_IMarshal, riid)) {
+ TRACE("(%p)->(IID_IMarshal %p) returning NULL\n", This, ppv);
+ return E_NOINTERFACE;
+ }else if(IsEqualGUID(&IID_IStdMarshalInfo, riid)) {
+ TRACE("(%p)->(IID_IStdMarshalInfo %p) returning NULL\n", This, ppv);
+ return E_NOINTERFACE;
+ }else if(HlinkFrame_QI(&This->hlink_frame, riid, ppv)) {
+ return S_OK;
}
if(*ppv) {
@@ -1130,6 +1135,62 @@ static const IServiceProviderVtbl ServiceProviderVtbl =
WebBrowser_IServiceProvider_QueryService
};
+#define DOCHOST_THIS(iface) DEFINE_THIS2(WebBrowser,doc_host,iface)
+
+static void WINAPI DocHostContainer_GetDocObjRect(DocHost* This, RECT* rc)
+{
+ GetClientRect(This->frame_hwnd, rc);
+}
+
+static HRESULT WINAPI DocHostContainer_SetStatusText(DocHost* This, LPCWSTR text)
+{
+ return E_NOTIMPL;
+}
+
+static void WINAPI DocHostContainer_SetURL(DocHost* This, LPCWSTR url)
+{
+
+}
+
+static HRESULT DocHostContainer_exec(DocHost *doc_host, const GUID *cmd_group, DWORD cmdid, DWORD execopt, VARIANT *in,
+ VARIANT *out)
+{
+ WebBrowser *This = DOCHOST_THIS(doc_host);
+ IOleCommandTarget *cmdtrg = NULL;
+ HRESULT hres;
+
+ if(This->client) {
+ hres = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
+ if(FAILED(hres))
+ cmdtrg = NULL;
+ }
+
+ if(!cmdtrg && This->container) {
+ hres = IOleContainer_QueryInterface(This->container, &IID_IOleCommandTarget, (void**)&cmdtrg);
+ if(FAILED(hres))
+ cmdtrg = NULL;
+ }
+
+ if(!cmdtrg)
+ return S_OK;
+
+ hres = IOleCommandTarget_Exec(cmdtrg, cmd_group, cmdid, execopt, in, out);
+ IOleCommandTarget_Release(cmdtrg);
+ if(FAILED(hres))
+ FIXME("Exec failed\n");
+
+ return hres;
+}
+
+#undef DOCHOST_THIS
+
+static const IDocHostContainerVtbl DocHostContainerVtbl = {
+ DocHostContainer_GetDocObjRect,
+ DocHostContainer_SetStatusText,
+ DocHostContainer_SetURL,
+ DocHostContainer_exec
+};
+
static HRESULT WebBrowser_Create(INT version, IUnknown *pOuter, REFIID riid, void **ppv)
{
WebBrowser *ret;
@@ -1144,7 +1205,7 @@ static HRESULT WebBrowser_Create(INT version, IUnknown *pOuter, REFIID riid, voi
ret->ref = 1;
ret->version = version;
- DocHost_Init(&ret->doc_host, (IDispatch*)WEBBROWSER2(ret));
+ DocHost_Init(&ret->doc_host, (IDispatch*)WEBBROWSER2(ret), &DocHostContainerVtbl);
ret->visible = VARIANT_TRUE;
ret->menu_bar = VARIANT_TRUE;
@@ -1157,7 +1218,8 @@ static HRESULT WebBrowser_Create(INT version, IUnknown *pOuter, REFIID riid, voi
WebBrowser_DataObject_Init(ret);
WebBrowser_Persist_Init(ret);
WebBrowser_ClassInfo_Init(ret);
- WebBrowser_HlinkFrame_Init(ret);
+
+ HlinkFrame_Init(&ret->hlink_frame, (IUnknown*)WEBBROWSER2(ret), &ret->doc_host);
SHDOCVW_LockModule();
diff --git a/dll/win32/shell32/drive.c b/dll/win32/shell32/drive.c
index 2e8cce57f75..8f70e74cc7f 100644
--- a/dll/win32/shell32/drive.c
+++ b/dll/win32/shell32/drive.c
@@ -395,7 +395,6 @@ InitializeGeneralDriveDialog(HWND hwndDlg, WCHAR * szDrive)
{
WCHAR szResult[128];
LONGLONG Result;
-#ifdef IOCTL_DISK_GET_LENGTH_INFO_IMPLEMENTED
HANDLE hVolume;
DWORD BytesReturned = 0;
@@ -404,16 +403,13 @@ InitializeGeneralDriveDialog(HWND hwndDlg, WCHAR * szDrive)
if (hVolume != INVALID_HANDLE_VALUE)
{
ret = DeviceIoControl(hVolume, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, (LPVOID)&TotalNumberOfBytes, sizeof(ULARGE_INTEGER), &BytesReturned, NULL);
- if (ret && StrFormatByteSizeW(LengthInformation.Length.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))
+ if (ret && StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))
SendDlgItemMessageW(hwndDlg, 14007, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);
CloseHandle(hVolume);
}
- TRACE("szResult %s hVOlume %p ret %d LengthInformation %ul Bytesreturned %d\n", debugstr_w(szResult), hVolume, ret, LengthInformation.Length.QuadPart, BytesReturned);
-#else
- if (ret && StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))
- SendDlgItemMessageW(hwndDlg, 14007, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);
-#endif
+
+ TRACE("szResult %s hVOlume %p ret %d LengthInformation %ul Bytesreturned %d\n", debugstr_w(szResult), hVolume, ret, TotalNumberOfBytes.QuadPart, BytesReturned);
if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart - FreeBytesAvailable.QuadPart, szResult, sizeof(szResult) / sizeof(WCHAR)))
SendDlgItemMessageW(hwndDlg, 14003, WM_SETTEXT, (WPARAM)NULL, (LPARAM)szResult);
diff --git a/dll/win32/shlwapi/shlwapi.rbuild b/dll/win32/shlwapi/shlwapi.rbuild
index 37fb2e8427f..24d2e5c0502 100644
--- a/dll/win32/shlwapi/shlwapi.rbuild
+++ b/dll/win32/shlwapi/shlwapi.rbuild
@@ -37,6 +37,7 @@
shell32
winmm
version
+ msvcrt
ntdll
diff --git a/dll/win32/user32/include/cursor.h b/dll/win32/user32/include/cursor.h
index 67d3053f3be..a8e966eae4e 100644
--- a/dll/win32/user32/include/cursor.h
+++ b/dll/win32/user32/include/cursor.h
@@ -1,2 +1,12 @@
HCURSOR
-CursorIconToCursor(HICON hIcon, BOOL SemiTransparent);
+CursorIconToCursor(HICON hIcon,
+ BOOL SemiTransparent);
+
+HICON CreateCursorIconFromData(PVOID ImageData,
+ ICONIMAGE* IconImage,
+ int cxDesired,
+ int cyDesired,
+ int xHotspot,
+ int yHotspot,
+ BOOL fIcon);
+
diff --git a/dll/win32/user32/include/user32.h b/dll/win32/user32/include/user32.h
index ba2a8364656..a0472b3ae62 100644
--- a/dll/win32/user32/include/user32.h
+++ b/dll/win32/user32/include/user32.h
@@ -43,7 +43,8 @@
#include
#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
-#define ISITHOOKED(HookId) (GetWin32ClientInfo()->fsHooks & HOOKID_TO_FLAG(HookId))
+#define ISITHOOKED(HookId) (GetWin32ClientInfo()->fsHooks & HOOKID_TO_FLAG(HookId) ||\
+ (GetWin32ClientInfo()->pDeskInfo && GetWin32ClientInfo()->pDeskInfo->fsHooks & HOOKID_TO_FLAG(HookId)))
/* Temporarily in here for now. */
typedef struct _USERAPIHOOKINFO
@@ -168,7 +169,7 @@ SharedPtrToKernel(PVOID Ptr)
static __inline BOOL
IsThreadHooked(PCLIENTINFO pci)
{
- return pci->fsHooks != 0;
+ return (pci->fsHooks|pci->pDeskInfo->fsHooks) != 0;
}
static __inline PDESKTOPINFO
@@ -194,3 +195,4 @@ VOID FASTCALL GetConnected(VOID);
BOOL FASTCALL DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi);
BOOL FASTCALL TestWindowProcess(PWND);
VOID UserGetWindowBorders(DWORD, DWORD, SIZE *, BOOL);
+VOID FASTCALL IntNotifyWinEvent(DWORD, HWND, LONG, LONG, DWORD);
diff --git a/dll/win32/user32/include/user32p.h b/dll/win32/user32/include/user32p.h
index 0227e8edce3..d000164a4d6 100644
--- a/dll/win32/user32/include/user32p.h
+++ b/dll/win32/user32/include/user32p.h
@@ -28,7 +28,7 @@
/* One/Two Param Functions */
#define NtUserMsqSetWakeMask(dwWaitMask) \
- (HANDLE)NtUserCallOneParam(dwWaitMask, ONEPARAM_ROUTINE_MSQSETWAKEMASK)
+ (HANDLE)NtUserCallOneParam(dwWaitMask, ONEPARAM_ROUTINE_GETINPUTEVENT)
#define NtUserMsqClearWakeMask() \
NtUserCallNoParam(NOPARAM_ROUTINE_MSQCLEARWAKEMASK)
@@ -83,9 +83,6 @@
#define NtUserGetCursorPos(lpPoint) \
(BOOL)NtUserCallOneParam((DWORD_PTR)lpPoint, ONEPARAM_ROUTINE_GETCURSORPOSITION)
-#define NtUserIsWindowInDestroy(hWnd) \
- (BOOL)NtUserCallOneParam((DWORD_PTR)hWnd, ONEPARAM_ROUTINE_ISWINDOWINDESTROY)
-
#define NtUserEnableProcessWindowGhosting(bEnable) \
NtUserCallOneParam((DWORD_PTR)bEnable, ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING)
diff --git a/dll/win32/user32/misc/display.c b/dll/win32/user32/misc/display.c
index 9090454c14b..e9de23e4e4a 100644
--- a/dll/win32/user32/misc/display.c
+++ b/dll/win32/user32/misc/display.c
@@ -457,7 +457,6 @@ ChangeDisplaySettingsExA(
LONG rc;
UNICODE_STRING DeviceName;
PUNICODE_STRING pDeviceName = &DeviceName;
- LPDEVMODEW pDevModeW;
if (lpszDeviceName != NULL)
{
@@ -471,14 +470,19 @@ ChangeDisplaySettingsExA(
pDeviceName = NULL;
if (lpDevMode != NULL)
+ {
+ LPDEVMODEW pDevModeW;
pDevModeW = GdiConvertToDevmodeW(lpDevMode);
+ if(pDevModeW)
+ {
+ rc = NtUserChangeDisplaySettings ( pDeviceName, pDevModeW, hwnd, dwflags, lParam );
+ RtlFreeHeap(GetProcessHeap(), 0, pDevModeW);
+ }
+ else
+ rc = DISP_CHANGE_SUCCESSFUL;
+ }
else
- pDevModeW = NULL;
-
- rc = NtUserChangeDisplaySettings ( pDeviceName, pDevModeW, hwnd, dwflags, lParam );
-
- if (pDevModeW != NULL)
- RtlFreeHeap(GetProcessHeap(), 0, pDevModeW);
+ rc = NtUserChangeDisplaySettings ( pDeviceName, NULL, hwnd, dwflags, lParam );
if (lpszDeviceName != NULL)
RtlFreeUnicodeString ( &DeviceName );
@@ -539,6 +543,6 @@ ChangeDisplaySettingsW(
DWORD dwflags)
{
if(lpDevMode)
- lpDevMode->dmDriverExtra = 0;
+ lpDevMode->dmDriverExtra = 0;
return ChangeDisplaySettingsExW ( NULL, lpDevMode, NULL, dwflags, 0 );
}
diff --git a/dll/win32/user32/misc/misc.c b/dll/win32/user32/misc/misc.c
index 76aaf462a31..e7b7672cfdc 100644
--- a/dll/win32/user32/misc/misc.c
+++ b/dll/win32/user32/misc/misc.c
@@ -304,13 +304,13 @@ GetUser32Handle(HANDLE handle)
static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_EVENT + 1] =
{
FALSE, /* VALIDATE_TYPE_FREE (not used) */
- FALSE, /* VALIDATE_TYPE_WIN FALSE */
+ FALSE, /* VALIDATE_TYPE_WIN */
TRUE, /* VALIDATE_TYPE_MENU FALSE */
TRUE, /* VALIDATE_TYPE_CURSOR */
TRUE, /* VALIDATE_TYPE_MWPOS */
- TRUE, /* VALIDATE_TYPE_HOOK FALSE */
+ FALSE, /* VALIDATE_TYPE_HOOK */
FALSE, /* (not used) */
- TRUE, /* VALIDATE_TYPE_CALLPROC FALSE */
+ FALSE, /* VALIDATE_TYPE_CALLPROC */
TRUE, /* VALIDATE_TYPE_ACCEL */
FALSE, /* (not used) */
FALSE, /* (not used) */
diff --git a/dll/win32/user32/misc/stubs.c b/dll/win32/user32/misc/stubs.c
index 354b5d3f31c..229c0a9bc7d 100644
--- a/dll/win32/user32/misc/stubs.c
+++ b/dll/win32/user32/misc/stubs.c
@@ -311,7 +311,7 @@ AlignRects(LPRECT rect, DWORD b, DWORD c, DWORD d)
}
/*
- * @unimplemented
+ * @implemented
*/
LRESULT
WINAPI
@@ -320,8 +320,9 @@ DefRawInputProc(
INT nInput,
UINT cbSizeHeader)
{
- UNIMPLEMENTED;
- return 0;
+ if (cbSizeHeader == sizeof(RAWINPUTHEADER))
+ return S_OK;
+ return 1;
}
/*
@@ -386,20 +387,6 @@ GetRegisteredRawInputDevices(
return 0;
}
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-PrintWindow(
- HWND hwnd,
- HDC hdcBlt,
- UINT nFlags)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
/*
* @unimplemented
*/
diff --git a/dll/win32/user32/user32.pspec b/dll/win32/user32/user32.pspec
index 603a025bf0d..3913a9a92df 100644
--- a/dll/win32/user32/user32.pspec
+++ b/dll/win32/user32/user32.pspec
@@ -526,7 +526,7 @@
@ stdcall PostQuitMessage(long)
@ stdcall PostThreadMessageA(long long long long)
@ stdcall PostThreadMessageW(long long long long)
-; @ stub PrintWindow
+@ stdcall PrintWindow(ptr ptr long) NtUserPrintWindow
@ stdcall PrivateExtractIconExA(str long ptr ptr long)
@ stdcall PrivateExtractIconExW(wstr long ptr ptr long)
@ stdcall PrivateExtractIconsA(str long long long ptr ptr long long)
diff --git a/dll/win32/user32/windows/class.c b/dll/win32/user32/windows/class.c
index d55d29c913a..70171c6d0eb 100644
--- a/dll/win32/user32/windows/class.c
+++ b/dll/win32/user32/windows/class.c
@@ -298,7 +298,7 @@ IntGetWndProc(PWND pWnd, BOOL Ansi)
}
return Ret;
}
- // Wine Class tests:
+ // Wine Class tests:
/* Edit controls are special - they return a wndproc handle when
GetWindowLongPtr is called with a different A/W.
On the other hand there is no W->A->W conversion so this control
@@ -831,7 +831,6 @@ CreateSmallIcon(HICON StdIcon)
int SmallIconWidth;
int SmallIconHeight;
BITMAP StdBitmapInfo;
- HDC hInfoDc = NULL;
HDC hSourceDc = NULL;
HDC hDestDc = NULL;
ICONINFO SmallInfo;
@@ -867,15 +866,6 @@ CreateSmallIcon(HICON StdIcon)
return StdIcon;
}
- /* Get a handle to a info DC and handles to DCs which can be used to
- select a bitmap into. This is done to avoid triggering a switch to
- graphics mode (if we're currently in text/blue screen mode) */
- hInfoDc = CreateICW(NULL, NULL, NULL, NULL);
- if (NULL == hInfoDc)
- {
- ERR("Failed to create info DC\n");
- goto cleanup;
- }
hSourceDc = CreateCompatibleDC(NULL);
if (NULL == hSourceDc)
{
@@ -895,7 +885,7 @@ CreateSmallIcon(HICON StdIcon)
ERR("Failed to select source color bitmap\n");
goto cleanup;
}
- SmallInfo.hbmColor = CreateCompatibleBitmap(hInfoDc, SmallIconWidth,
+ SmallInfo.hbmColor = CreateCompatibleBitmap(hSourceDc, SmallIconWidth,
SmallIconHeight);
if (NULL == SmallInfo.hbmColor)
{
@@ -921,8 +911,7 @@ CreateSmallIcon(HICON StdIcon)
ERR("Failed to select source mask bitmap\n");
goto cleanup;
}
- SmallInfo.hbmMask = CreateBitmap(SmallIconWidth, SmallIconHeight, 1, 1,
- NULL);
+ SmallInfo.hbmMask = CreateCompatibleBitmap(hSourceDc, SmallIconWidth, SmallIconHeight);
if (NULL == SmallInfo.hbmMask)
{
ERR("Failed to create mask bitmap\n");
@@ -976,10 +965,6 @@ cleanup:
{
DeleteDC(hSourceDc);
}
- if (NULL != hInfoDc)
- {
- DeleteDC(hInfoDc);
- }
return SmallIcon;
}
@@ -1070,9 +1055,9 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
clsMenuName.pusMenuName = &MenuName;
-
+
Atom = NtUserRegisterClassExWOW( &WndClass,
- &ClassName,
+ &ClassName,
NULL, //PUNICODE_STRING ClsNVersion,
&clsMenuName,
fnID,
diff --git a/dll/win32/user32/windows/cursoricon.c b/dll/win32/user32/windows/cursoricon.c
index 0c88734834c..f7ada0b80af 100644
--- a/dll/win32/user32/windows/cursoricon.c
+++ b/dll/win32/user32/windows/cursoricon.c
@@ -458,10 +458,16 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
void *color_bits, *mask_bits;
BOOL ret = FALSE;
HDC hdc = 0;
+ static HDC hScreenDC = 0;
if (!(info = HeapAlloc( GetProcessHeap(), 0, max( size, FIELD_OFFSET( BITMAPINFO, bmiColors[2] )))))
return FALSE;
- if (!(hdc = CreateCompatibleDC( 0 ))) goto done;
+ if(!hScreenDC)
+ {
+ hScreenDC = GetDC(0);
+ if(!hScreenDC) goto done;
+ }
+ if (!(hdc = CreateCompatibleDC(hScreenDC))) goto done;
memcpy( info, bmi, size );
info->bmiHeader.biHeight /= 2;
@@ -485,8 +491,8 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
else
{
if (!(*mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done;
- if (!(*color = CreateBitmap( width, height, bmi->bmiHeader.biPlanes,
- bmi->bmiHeader.biBitCount, NULL )))
+ if (!(*color = CreateBitmap( width, height, GetDeviceCaps(hScreenDC, PLANES),
+ GetDeviceCaps(hScreenDC, BITSPIXEL), NULL )))
{
DeleteObject( *mask );
goto done;
@@ -523,7 +529,7 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
ret = TRUE;
done:
- DeleteDC( hdc );
+ if(hdc) DeleteDC( hdc );
HeapFree( GetProcessHeap(), 0, info );
return ret;
}
diff --git a/dll/win32/user32/windows/defwnd.c b/dll/win32/user32/windows/defwnd.c
index 628940de1d6..76b34be0e9f 100644
--- a/dll/win32/user32/windows/defwnd.c
+++ b/dll/win32/user32/windows/defwnd.c
@@ -103,6 +103,7 @@ BOOL
FASTCALL
DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
{
+ BOOL Ret;
LARGE_STRING lsString;
if ( String )
@@ -112,7 +113,12 @@ DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
else
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0);
}
- return NtUserDefSetText(hWnd, (String ? &lsString : NULL));
+ Ret = NtUserDefSetText(hWnd, (String ? &lsString : NULL));
+
+ if (Ret)
+ IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
+
+ return Ret;
}
void
@@ -1969,7 +1975,6 @@ RealDefWindowProcA(HWND hWnd,
{
DefWndNCPaint(hWnd, (HRGN)1, -1);
}
-
Result = 1;
break;
}
diff --git a/dll/win32/user32/windows/draw.c b/dll/win32/user32/windows/draw.c
index c722dc7dbe8..dd50c75b1c3 100644
--- a/dll/win32/user32/windows/draw.c
+++ b/dll/win32/user32/windows/draw.c
@@ -1373,9 +1373,9 @@ IntDrawState(HDC hdc, HBRUSH hbr, DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
}
if (flags & DSS_DISABLED)
- hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
+ hbrtmp = GetSysColorBrush(COLOR_3DHILIGHT);
else if (flags & DSS_DEFAULT)
- hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
+ hbrtmp = GetSysColorBrush(COLOR_3DSHADOW);
/* Draw light or dark shadow */
if (flags & (DSS_DISABLED|DSS_DEFAULT))
@@ -1388,13 +1388,11 @@ IntDrawState(HDC hdc, HBRUSH hbr, DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
if(!BitBlt(hdc, x+1, y+1, cx, cy, memdc, 0, 0, 0x00B8074A))
goto cleanup;
SelectObject(hdc, hbsave);
- DeleteObject(hbrtmp);
- hbrtmp = 0;
}
if (flags & DSS_DISABLED)
{
- hbr = hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
+ hbr = hbrtmp = GetSysColorBrush(COLOR_3DSHADOW);
if(!hbrtmp)
goto cleanup;
}
@@ -1418,8 +1416,6 @@ cleanup:
SelectObject(hdc, hbsave);
if(hbmsave)
SelectObject(memdc, hbmsave);
- if(hbrtmp)
- DeleteObject(hbrtmp);
if(hbm)
DeleteObject(hbm);
if(memdc)
diff --git a/dll/win32/user32/windows/hook.c b/dll/win32/user32/windows/hook.c
index 304f9320a96..ff982eebcc6 100644
--- a/dll/win32/user32/windows/hook.c
+++ b/dll/win32/user32/windows/hook.c
@@ -19,8 +19,8 @@
/*
*
* PROJECT: ReactOS user32.dll
- * FILE: lib/user32/windows/input.c
- * PURPOSE: Input
+ * FILE: dll/win32/user32/windows/hook.c
+ * PURPOSE: Hooks
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* 09-05-2001 CSH Created
@@ -34,6 +34,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(user32);
+typedef struct _NOTIFYEVENT
+{
+ DWORD event;
+ LONG idObject;
+ LONG idChild;
+ DWORD flags;
+} NOTIFYEVENT, *PNOTIFYEVENT;
+
/* PRIVATE FUNCTIONS *********************************************************/
static
@@ -99,6 +107,29 @@ IntSetWindowsHook(
return NtUserSetWindowsHookEx(hMod, &USModuleName, dwThreadId, idHook, lpfn, bAnsi);
}
+/*
+ Since ReactOS uses User32 as the main message source this was needed.
+ Base on the funny rules from the wine tests it left it with this option.
+ 8^(
+ */
+VOID
+FASTCALL
+IntNotifyWinEvent(
+ DWORD event,
+ HWND hwnd,
+ LONG idObject,
+ LONG idChild,
+ DWORD flags
+ )
+{
+ NOTIFYEVENT ne;
+ ne.event = event;
+ ne.idObject = idObject;
+ ne.idChild = idChild;
+ ne.flags = flags;
+ if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(event))
+ NtUserCallHwndParam(hwnd, (DWORD)&ne, HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT);
+}
/* FUNCTIONS *****************************************************************/
@@ -123,49 +154,19 @@ CallMsgFilterA(
LPMSG lpMsg,
int nCode)
{
- BOOL ret = FALSE;
-
- if (nCode != HCBT_CREATEWND) ret = NtUserCallMsgFilter((LPMSG) lpMsg, nCode);
- else
+ MSG Msg;
+ if ( NtCurrentTeb()->Win32ThreadInfo &&
+ (ISITHOOKED(WH_MSGFILTER) || ISITHOOKED(WH_SYSMSGFILTER)) )
+ {
+ if ( lpMsg->message & ~WM_MAXIMUM )
{
- UNICODE_STRING usBuffer;
- CBT_CREATEWNDA *cbtcwA = (CBT_CREATEWNDA *)lpMsg->lParam;
- CBT_CREATEWNDW cbtcwW;
- CREATESTRUCTW csW;
- MSG Msg;
-
- Msg.hwnd = lpMsg->hwnd;
- Msg.message = lpMsg->message;
- Msg.time = lpMsg->time;
- Msg.pt = lpMsg->pt;
- Msg.wParam = lpMsg->wParam;
-
- cbtcwW.lpcs = &csW;
- cbtcwW.hwndInsertAfter = cbtcwA->hwndInsertAfter;
- csW = *(CREATESTRUCTW *)cbtcwA->lpcs;
-
- if (HIWORD(cbtcwA->lpcs->lpszName))
- {
- RtlCreateUnicodeStringFromAsciiz(&usBuffer,cbtcwA->lpcs->lpszName);
- csW.lpszName = usBuffer.Buffer;
- }
- if (HIWORD(cbtcwA->lpcs->lpszClass))
- {
- RtlCreateUnicodeStringFromAsciiz(&usBuffer,cbtcwA->lpcs->lpszClass);
- csW.lpszClass = usBuffer.Buffer;
- }
- Msg.lParam =(LPARAM) &cbtcwW;
-
- ret = NtUserCallMsgFilter((LPMSG)&Msg, nCode);
-
- lpMsg->time = Msg.time;
- lpMsg->pt = Msg.pt;
-
- cbtcwA->hwndInsertAfter = cbtcwW.hwndInsertAfter;
- if (HIWORD(csW.lpszName)) HeapFree( GetProcessHeap(), 0, (LPWSTR)csW.lpszName );
- if (HIWORD(csW.lpszClass)) HeapFree( GetProcessHeap(), 0, (LPWSTR)csW.lpszClass );
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
- return ret;
+ RtlCopyMemory(&Msg, lpMsg, sizeof(MSG));
+ return NtUserCallMsgFilter( &Msg, nCode);
+ }
+ return FALSE;
}
@@ -178,7 +179,19 @@ CallMsgFilterW(
LPMSG lpMsg,
int nCode)
{
- return NtUserCallMsgFilter((LPMSG) lpMsg, nCode);
+ MSG Msg;
+ if ( NtCurrentTeb()->Win32ThreadInfo &&
+ (ISITHOOKED(WH_MSGFILTER) || ISITHOOKED(WH_SYSMSGFILTER)) )
+ {
+ if ( lpMsg->message & ~WM_MAXIMUM )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ RtlCopyMemory(&Msg, lpMsg, sizeof(MSG));
+ return NtUserCallMsgFilter( &Msg, nCode);
+ }
+ return FALSE;
}
@@ -195,7 +208,7 @@ CallNextHookEx(
{
PCLIENTINFO ClientInfo;
DWORD Flags, Save;
- PHOOK pHook;
+ PHOOK pHook, phkNext;
LRESULT lResult = 0;
GetConnected();
@@ -204,9 +217,14 @@ CallNextHookEx(
if (!ClientInfo->phkCurrent) return 0;
- pHook = SharedPtrToUser(ClientInfo->phkCurrent);
+ pHook = DesktopPtrToUser(ClientInfo->phkCurrent);
- if (pHook->HookId == WH_CALLWNDPROC || pHook->HookId == WH_CALLWNDPROCRET)
+ if (!pHook->phkNext) return 0; // Nothing to do....
+
+ phkNext = DesktopPtrToUser(pHook->phkNext);
+
+ if ( phkNext->HookId == WH_CALLWNDPROC ||
+ phkNext->HookId == WH_CALLWNDPROCRET)
{
Save = ClientInfo->dwHookData;
Flags = ClientInfo->CI_flags & CI_CURTHPRHOOK;
@@ -215,7 +233,7 @@ CallNextHookEx(
if (wParam) ClientInfo->CI_flags |= CI_CURTHPRHOOK;
else ClientInfo->CI_flags &= ~CI_CURTHPRHOOK;
- if (pHook->HookId == WH_CALLWNDPROC)
+ if (phkNext->HookId == WH_CALLWNDPROC)
{
PCWPSTRUCT pCWP = (PCWPSTRUCT)lParam;
@@ -225,7 +243,7 @@ CallNextHookEx(
pCWP->lParam,
(ULONG_PTR)&lResult,
FNID_CALLWNDPROC,
- pHook->Ansi);
+ phkNext->Ansi);
}
else
{
@@ -239,7 +257,7 @@ CallNextHookEx(
pCWPR->lParam,
(ULONG_PTR)&lResult,
FNID_CALLWNDPROCRET,
- pHook->Ansi);
+ phkNext->Ansi);
}
ClientInfo->CI_flags ^= ((ClientInfo->CI_flags ^ Flags) & CI_CURTHPRHOOK);
ClientInfo->dwHookData = Save;
@@ -252,23 +270,27 @@ CallNextHookEx(
/*
- * @unimplemented
+ * @implemented
*/
HHOOK
WINAPI
SetWindowsHookW(int idHook, HOOKPROC lpfn)
{
- return IntSetWindowsHook(idHook, lpfn, NULL, 0, FALSE);
+ DWORD ThreadId = PtrToUint(NtCurrentTeb()->ClientId.UniqueThread);
+ return IntSetWindowsHook(idHook, lpfn, NULL, ThreadId, FALSE);
+// return NtUserSetWindowsHookAW(idHook, lpfn, FALSE);
}
/*
- * @unimplemented
+ * @implemented
*/
HHOOK
WINAPI
SetWindowsHookA(int idHook, HOOKPROC lpfn)
{
- return IntSetWindowsHook(idHook, lpfn, NULL, 0, TRUE);
+ DWORD ThreadId = PtrToUint(NtCurrentTeb()->ClientId.UniqueThread);
+ return IntSetWindowsHook(idHook, lpfn, NULL, ThreadId, TRUE);
+// return NtUserSetWindowsHookAW(idHook, lpfn, TRUE);
}
/*
@@ -377,7 +399,7 @@ IsWinEventHookInstalled(
}
/*
- * @unimplemented
+ * @implemented
*/
HHOOK
WINAPI
@@ -392,7 +414,7 @@ SetWindowsHookExA(
/*
- * @unimplemented
+ * @implemented
*/
HHOOK
WINAPI
@@ -409,22 +431,21 @@ NTSTATUS WINAPI
User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
{
PHOOKPROC_CALLBACK_ARGUMENTS Common;
- LRESULT Result;
CREATESTRUCTW Csw;
CBT_CREATEWNDW CbtCreatewndw;
- CREATESTRUCTA Csa;
- CBT_CREATEWNDA CbtCreatewnda;
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL;
- WPARAM wParam = 0;
- LPARAM lParam = 0;
- PKBDLLHOOKSTRUCT KeyboardLlData;
- PMSLLHOOKSTRUCT MouseLlData;
- PMSG Msg;
- PMOUSEHOOKSTRUCT MHook;
- PCWPSTRUCT CWP;
- PCWPRETSTRUCT CWPR;
+ KBDLLHOOKSTRUCT KeyboardLlData, *pKeyboardLlData;
+ MSLLHOOKSTRUCT MouseLlData, *pMouseLlData;
+ MSG *pcMsg, *pMsg;
+ PMOUSEHOOKSTRUCT pMHook;
+ CWPSTRUCT CWP, *pCWP;
+ CWPRETSTRUCT CWPR, *pCWPR;
PRECTL prl;
LPCBTACTIVATESTRUCT pcbtas;
+ WPARAM wParam = 0;
+ LPARAM lParam = 0;
+ LRESULT Result = 0;
+ BOOL Hit = FALSE;
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments;
@@ -432,40 +453,22 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
{
case WH_CBT:
{
+ //ERR("WH_CBT: Code %d\n", Common->Code);
switch(Common->Code)
{
case HCBT_CREATEWND:
CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS)
((PCHAR) Common + Common->lParam);
- Csw = CbtCreatewndExtra->Cs;
- if (NULL != CbtCreatewndExtra->Cs.lpszName)
- {
- Csw.lpszName = (LPCWSTR)((PCHAR) CbtCreatewndExtra
- + (ULONG_PTR) CbtCreatewndExtra->Cs.lpszName);
- }
- if (0 != HIWORD(CbtCreatewndExtra->Cs.lpszClass))
- {
- Csw.lpszClass = (LPCWSTR)((PCHAR) CbtCreatewndExtra
- + LOWORD((ULONG_PTR) CbtCreatewndExtra->Cs.lpszClass));
- }
+ RtlCopyMemory(&Csw, &CbtCreatewndExtra->Cs, sizeof(CREATESTRUCTW));
+ CbtCreatewndw.lpcs = &Csw;
+ CbtCreatewndw.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
wParam = Common->wParam;
- if (Common->Ansi)
- {
- memcpy(&Csa, &Csw, sizeof(CREATESTRUCTW));
- CbtCreatewnda.lpcs = &Csa;
- CbtCreatewnda.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
- lParam = (LPARAM) &CbtCreatewnda;
- }
- else
- {
- CbtCreatewndw.lpcs = &Csw;
- CbtCreatewndw.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
- lParam = (LPARAM) &CbtCreatewndw;
- }
+ lParam = (LPARAM) &CbtCreatewndw;
+ //ERR("HCBT_CREATEWND: hWnd 0x%x Name 0x%x Class 0x%x\n", Common->wParam, Csw.lpszName, Csw.lpszClass);
break;
case HCBT_CLICKSKIPPED:
- MHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
- lParam = (LPARAM) MHook;
+ pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
+ lParam = (LPARAM) pMHook;
break;
case HCBT_MOVESIZE:
prl = (PRECTL)((PCHAR) Common + Common->lParam);
@@ -475,7 +478,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
pcbtas = (LPCBTACTIVATESTRUCT)((PCHAR) Common + Common->lParam);
lParam = (LPARAM) pcbtas;
break;
- case HCBT_KEYSKIPPED:
+ case HCBT_KEYSKIPPED: /* The rest SEH support */
case HCBT_MINMAX:
case HCBT_SETFOCUS:
case HCBT_SYSCOMMAND:
@@ -490,55 +493,110 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
}
if (Common->Proc)
- Result = Common->Proc(Common->Code, wParam, lParam);
+ {
+ _SEH2_TRY
+ {
+ Result = Common->Proc(Common->Code, wParam, lParam);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Hit = TRUE;
+ }
+ _SEH2_END;
+ }
else
{
- ERR("Common = 0x%x, Proc = 0x%x\n",Common,Common->Proc);
+ ERR("Null Proc! Common = 0x%x, Proc = 0x%x\n",Common,Common->Proc);
}
switch(Common->Code)
{
case HCBT_CREATEWND:
CbtCreatewndExtra->WndInsertAfter = CbtCreatewndw.hwndInsertAfter;
+ CbtCreatewndExtra->Cs.x = CbtCreatewndw.lpcs->x;
+ CbtCreatewndExtra->Cs.y = CbtCreatewndw.lpcs->y;
+ CbtCreatewndExtra->Cs.cx = CbtCreatewndw.lpcs->cx;
+ CbtCreatewndExtra->Cs.cy = CbtCreatewndw.lpcs->cy;
break;
}
break;
}
case WH_KEYBOARD_LL:
- KeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
- Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) KeyboardLlData);
+ //ERR("WH_KEYBOARD_LL: Code %d, wParam %d\n",Common->Code,Common->wParam);
+ pKeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
+ RtlCopyMemory(&KeyboardLlData, pKeyboardLlData, sizeof(KBDLLHOOKSTRUCT));
+ Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &KeyboardLlData);
break;
case WH_MOUSE_LL:
- MouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
- Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MouseLlData);
+ //ERR("WH_MOUSE_LL: Code %d, wParam %d\n",Common->Code,Common->wParam);
+ pMouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
+ RtlCopyMemory(&MouseLlData, pMouseLlData, sizeof(MSLLHOOKSTRUCT));
+ Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &MouseLlData);
break;
- case WH_MOUSE:
- MHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
- Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MHook);
+ case WH_MOUSE: /* SEH support */
+ pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
+ _SEH2_TRY
+ {
+ Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pMHook);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Hit = TRUE;
+ }
+ _SEH2_END;
break;
case WH_CALLWNDPROC:
- CWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam);
- Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) CWP);
+// ERR("WH_CALLWNDPROC: Code %d, wParam %d\n",Common->Code,Common->wParam);
+ pCWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam);
+ RtlCopyMemory(&CWP, pCWP, sizeof(CWPSTRUCT));
+ Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWP);
break;
case WH_CALLWNDPROCRET:
- CWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam);
- Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) CWPR);
+ pCWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam);
+ RtlCopyMemory(&CWPR, pCWPR, sizeof(CWPRETSTRUCT));
+ Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWPR);
break;
- case WH_MSGFILTER:
+ case WH_MSGFILTER: /* All SEH support */
case WH_SYSMSGFILTER:
case WH_GETMESSAGE:
- Msg = (PMSG)((PCHAR) Common + Common->lParam);
-// FIXME("UHOOK Memory: %x: %x\n",Common, Msg);
- Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) Msg);
+ pMsg = (PMSG)((PCHAR) Common + Common->lParam);
+ pcMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSG));
+ RtlCopyMemory(pcMsg, pMsg, sizeof(MSG));
+// ERR("pMsg %d pcMsg %d\n",pMsg->message, pcMsg->message);
+ _SEH2_TRY
+ {
+ Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pcMsg);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Hit = TRUE;
+ }
+ _SEH2_END;
+ if (!Hit && Common->HookId == WH_GETMESSAGE)
+ RtlCopyMemory(pMsg, pcMsg, sizeof(MSG));
+ HeapFree( GetProcessHeap(), 0, pcMsg );
break;
- case WH_FOREGROUNDIDLE:
case WH_KEYBOARD:
case WH_SHELL:
Result = Common->Proc(Common->Code, Common->wParam, Common->lParam);
+ break;
+ case WH_FOREGROUNDIDLE: /* <-- SEH support */
+ _SEH2_TRY
+ {
+ Result = Common->Proc(Common->Code, Common->wParam, Common->lParam);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Hit = TRUE;
+ }
+ _SEH2_END;
break;
default:
return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED);
}
-
+ if (Hit)
+ {
+ ERR("Hook Exception! Id: %d, Code %d, Proc 0x%x\n",Common->HookId,Common->Code,Common->Proc);
+ }
return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
}
diff --git a/dll/win32/user32/windows/input.c b/dll/win32/user32/windows/input.c
index aa9a997f070..08e457bf5a1 100644
--- a/dll/win32/user32/windows/input.c
+++ b/dll/win32/user32/windows/input.c
@@ -138,6 +138,7 @@ EnableWindow(HWND hWnd,
if (Update)
{
+ IntNotifyWinEvent(EVENT_OBJECT_STATECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
SendMessageW(hWnd, WM_ENABLE, (LPARAM)bEnable, 0);
}
// Return nonzero if it was disabled, or zero if it wasn't:
diff --git a/dll/win32/user32/windows/menu.c b/dll/win32/user32/windows/menu.c
index dd8f1ff1780..8f8610d64b1 100644
--- a/dll/win32/user32/windows/menu.c
+++ b/dll/win32/user32/windows/menu.c
@@ -1636,6 +1636,8 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
top_popup_hmenu = hmenu;
}
+ IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
+
/* Display the window */
SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0,
@@ -3445,6 +3447,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
if (MenuInfo.Flags & MF_POPUP)
{
+ IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
DestroyWindow(MenuInfo.Wnd);
MenuInfo.Wnd = NULL;
@@ -3484,14 +3487,23 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
HideCaret(0);
+ MenuGetRosMenuInfo(&MenuInfo, hMenu);
+ /* This makes the menus of applications built with Delphi work.
+ * It also enables menus to be displayed in more than one window,
+ * but there are some bugs left that need to be fixed in this case.
+ */
+ if(MenuInfo.Self == hMenu)
+ {
+ MenuInfo.Wnd = hWnd;
+ MenuSetRosMenuInfo(&MenuInfo);
+ }
+
/* Send WM_ENTERMENULOOP and WM_INITMENU message only if TPM_NONOTIFY flag is not specified */
if (!(wFlags & TPM_NONOTIFY))
SendMessageW( hWnd, WM_ENTERMENULOOP, bPopup, 0 );
SendMessageW( hWnd, WM_SETCURSOR, (WPARAM)hWnd, HTCAPTION );
- MenuGetRosMenuInfo(&MenuInfo, hMenu);
-
if (!(wFlags & TPM_NONOTIFY))
{
SendMessageW( hWnd, WM_INITMENU, (WPARAM)hMenu, 0 );
@@ -3509,16 +3521,10 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
}
}
- /* This makes the menus of applications built with Delphi work.
- * It also enables menus to be displayed in more than one window,
- * but there are some bugs left that need to be fixed in this case.
- */
- if(MenuInfo.Self == hMenu)
- {
- MenuInfo.Wnd = hWnd;
- MenuSetRosMenuInfo(&MenuInfo);
- }
-
+ IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART,
+ hWnd,
+ MenuInfo.Flags & MF_SYSMENU ? OBJID_SYSMENU : OBJID_MENU,
+ CHILDID_SELF, 0);
return TRUE;
}
/***********************************************************************
@@ -3528,6 +3534,7 @@ static BOOL FASTCALL MenuExitTracking(HWND hWnd, BOOL bPopup)
{
TRACE("hwnd=%p\n", hWnd);
+ IntNotifyWinEvent( EVENT_SYSTEM_MENUEND, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 );
ShowCaret(0);
top_popup = 0;
@@ -3644,13 +3651,21 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
HWND Wnd, LPTPMPARAMS Tpm)
{
BOOL ret = FALSE;
+ ROSMENUINFO MenuInfo;
- if (!IsMenu(Menu))
+ if (!IsMenu(Menu))
{
SetLastError( ERROR_INVALID_MENU_HANDLE );
return FALSE;
}
+ MenuGetRosMenuInfo(&MenuInfo, Menu);
+ if (IsWindow(MenuInfo.Wnd))
+ {
+ SetLastError( ERROR_POPUP_ALREADY_ACTIVE );
+ return FALSE;
+ }
+
MenuInitTracking(Wnd, Menu, TRUE, Flags);
/* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
diff --git a/dll/win32/user32/windows/message.c b/dll/win32/user32/windows/message.c
index 2c89b7863df..300bfc796cf 100644
--- a/dll/win32/user32/windows/message.c
+++ b/dll/win32/user32/windows/message.c
@@ -2064,13 +2064,20 @@ SendMessageW(HWND Wnd,
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{
- if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo()))
+ if ( Window != NULL &&
+ Window->head.pti == ti &&
+// !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
+ !ISITHOOKED(WH_CALLWNDPROC) &&
+ !ISITHOOKED(WH_CALLWNDPROCRET) &&
+ !(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
{
/* NOTE: We can directly send messages to the window procedure
if *all* the following conditions are met:
* Window belongs to calling thread
- * The calling thread is not being hooked
+ * The calling thread is not being hooked for CallWndProc
+ * Not calling a server side proc:
+ Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage
*/
return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, FALSE);
@@ -2130,13 +2137,20 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{
- if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo()))
+ if ( Window != NULL &&
+ Window->head.pti == ti &&
+// !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
+ !ISITHOOKED(WH_CALLWNDPROC) &&
+ !ISITHOOKED(WH_CALLWNDPROCRET) &&
+ !(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
{
/* NOTE: We can directly send messages to the window procedure
if *all* the following conditions are met:
* Window belongs to calling thread
- * The calling thread is not being hooked
+ * The calling thread is not being hooked for CallWndProc
+ * Not calling a server side proc:
+ Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage
*/
return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, TRUE);
@@ -2684,9 +2698,8 @@ USER_MESSAGE_PUMP_ADDRESSES gmph = {sizeof(USER_MESSAGE_PUMP_ADDRESSES),
DWORD gfMessagePumpHook = 0;
BOOL WINAPI IsInsideMessagePumpHook()
-{ // Fixme: Need to fully implement this! FF uses this and polls it when Min/Max
+{ // FF uses this and polls it when Min/Max
PCLIENTTHREADINFO pcti = GetWin32ClientInfo()->pClientThreadInfo;
-// FIXME("IIMPH %x\n",pcti);
return (gfMessagePumpHook && pcti && (pcti->dwcPumpHook > 0));
}
diff --git a/dll/win32/user32/windows/window.c b/dll/win32/user32/windows/window.c
index 468536ee290..1b1a0894e15 100644
--- a/dll/win32/user32/windows/window.c
+++ b/dll/win32/user32/windows/window.c
@@ -2060,7 +2060,11 @@ AnyPopup(VOID)
BOOL WINAPI
IsWindowInDestroy(HWND hWnd)
{
- return NtUserIsWindowInDestroy(hWnd);
+ PWND pwnd;
+ pwnd = ValidateHwnd(hWnd);
+ if (!pwnd)
+ return FALSE;
+ return ((pwnd->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY);
}
/*
diff --git a/dll/win32/wdmaud.drv/wdmaud.c b/dll/win32/wdmaud.drv/wdmaud.c
index e1da68ac526..8cb69eacc2c 100644
--- a/dll/win32/wdmaud.drv/wdmaud.c
+++ b/dll/win32/wdmaud.drv/wdmaud.c
@@ -208,10 +208,10 @@ BOOL WINAPI DllMain(
SND_TRACE(L"WDMAUD.DRV - Process detached\n");
break;
case DLL_THREAD_ATTACH :
- SND_TRACE(L"WDMAUD.DRV - Thread attached\n");
+ //SND_TRACE(L"WDMAUD.DRV - Thread attached\n");
break;
case DLL_THREAD_DETACH :
- SND_TRACE(L"WDMAUD.DRV - Thread detached\n");
+ //SND_TRACE(L"WDMAUD.DRV - Thread detached\n");
break;
}
diff --git a/dll/win32/wer/main.c b/dll/win32/wer/main.c
new file mode 100644
index 00000000000..585ac91a30b
--- /dev/null
+++ b/dll/win32/wer/main.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2010 Louis Lenders
+ * Copyright 2010 Detlef Riekenberg
+ *
+ * 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 "config.h"
+
+#include
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "werapi.h"
+#include "wine/list.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wer);
+
+typedef struct {
+ struct list entry;
+ WER_REPORT_INFORMATION info;
+ WER_REPORT_TYPE reporttype;
+ WCHAR eventtype[1];
+} report_t;
+
+
+static CRITICAL_SECTION report_table_cs;
+static CRITICAL_SECTION_DEBUG report_table_cs_debug =
+{
+ 0, 0, &report_table_cs,
+ { &report_table_cs_debug.ProcessLocksList, &report_table_cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": report_table_cs") }
+};
+static CRITICAL_SECTION report_table_cs = { &report_table_cs_debug, -1, 0, 0, 0, 0 };
+
+static struct list report_table = LIST_INIT(report_table);
+
+static WCHAR regpath_exclude[] = {'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\',
+ 'W','i','n','d','o','w','s',' ','E','r','r','o','r',' ','R','e','p','o','r','t','i','n','g','\\',
+ 'E','x','c','l','u','d','e','d','A','p','p','l','i','c','a','t','i','o','n','s',0};
+
+/***********************************************************************
+ * Memory alloccation helper
+ */
+
+static inline void * __WINE_ALLOC_SIZE(1) heap_alloc_zero(size_t len)
+{
+ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+}
+
+static inline BOOL heap_free(void *mem)
+{
+ return HeapFree(GetProcessHeap(), 0, mem);
+}
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
+
+ switch (fdwReason)
+ {
+ case DLL_WINE_PREATTACH:
+ return FALSE; /* prefer native version */
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * WerAddExcludedApplication (wer.@)
+ *
+ * Add an application to the user specific or the system wide exclusion list
+ *
+ * PARAMS
+ * exeName [i] The application name
+ * allUsers [i] for all users (TRUE) or for the current user (FALSE)
+ *
+ * RETURNS
+ * Success: S_OK
+ * Faulure: A HRESULT error code
+ *
+ */
+HRESULT WINAPI WerAddExcludedApplication(PCWSTR exeName, BOOL allUsers)
+{
+ HKEY hkey;
+ DWORD value = 1;
+ LPWSTR bs;
+
+ TRACE("(%s, %d)\n",debugstr_w(exeName), allUsers);
+ if (!exeName || !exeName[0])
+ return E_INVALIDARG;
+
+ bs = strrchrW(exeName, '\\');
+ if (bs) {
+ bs++; /* skip the backslash */
+ if (!bs[0]) {
+ return E_INVALIDARG;
+ }
+ } else
+ bs = (LPWSTR) exeName;
+
+ if (!RegCreateKeyW(allUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, regpath_exclude, &hkey)) {
+ RegSetValueExW(hkey, bs, 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
+ RegCloseKey(hkey);
+ return S_OK;
+ }
+ return E_ACCESSDENIED;
+}
+
+/***********************************************************************
+ * WerRemoveExcludedApplication (wer.@)
+ *
+ * remove an application from the exclusion list
+ *
+ * PARAMS
+ * exeName [i] The application name
+ * allUsers [i] for all users (TRUE) or for the current user (FALSE)
+ *
+ * RETURNS
+ * Success: S_OK
+ * Faulure: A HRESULT error code
+ *
+ */
+HRESULT WINAPI WerRemoveExcludedApplication(PCWSTR exeName, BOOL allUsers)
+{
+ HKEY hkey;
+ LPWSTR bs;
+ LONG lres;
+
+ TRACE("(%s, %d)\n",debugstr_w(exeName), allUsers);
+ if (!exeName || !exeName[0])
+ return E_INVALIDARG;
+
+ bs = strrchrW(exeName, '\\');
+ if (bs) {
+ bs++; /* skip the backslash */
+ if (!bs[0]) {
+ return E_INVALIDARG;
+ }
+ } else
+ bs = (LPWSTR) exeName;
+
+ if (!RegCreateKeyW(allUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, regpath_exclude, &hkey)) {
+ lres = RegDeleteValueW(hkey, bs);
+ RegCloseKey(hkey);
+ return lres ? __HRESULT_FROM_WIN32(ERROR_ENVVAR_NOT_FOUND) : S_OK;
+ }
+ return E_ACCESSDENIED;
+}
+
+/***********************************************************************
+ * WerReportCloseHandle (wer.@)
+ *
+ * Close an error reporting handle and free associated resources
+ *
+ * PARAMS
+ * hreport [i] error reporting handle to close
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: A HRESULT error code
+ *
+ */
+HRESULT WINAPI WerReportCloseHandle(HREPORT hreport)
+{
+ report_t * report = (report_t *) hreport;
+ report_t * cursor;
+ BOOL found = FALSE;
+
+ TRACE("(%p)\n", hreport);
+ EnterCriticalSection(&report_table_cs);
+ if (report) {
+ LIST_FOR_EACH_ENTRY(cursor, &report_table, report_t, entry)
+ {
+ if (cursor == report) {
+ found = TRUE;
+ list_remove(&report->entry);
+ break;
+ }
+ }
+ }
+ LeaveCriticalSection(&report_table_cs);
+ if (!found)
+ return E_INVALIDARG;
+
+ heap_free(report);
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * WerReportCreate (wer.@)
+ *
+ * Create an error report in memory and return a related HANDLE
+ *
+ * PARAMS
+ * eventtype [i] a name for the event type
+ * reporttype [i] what type of report should be created
+ * reportinfo [i] NULL or a ptr to a struct with some detailed information
+ * phandle [o] ptr, where the resulting handle should be saved
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: A HRESULT error code
+ *
+ * NOTES
+ * The event type must be registered at microsoft. Predefined types are
+ * "APPCRASH" as the default on Windows, "Crash32" and "Crash64"
+ *
+ */
+HRESULT WINAPI WerReportCreate(PCWSTR eventtype, WER_REPORT_TYPE reporttype, PWER_REPORT_INFORMATION reportinfo, HREPORT *phandle)
+{
+ report_t *report;
+ DWORD len;
+
+ TRACE("(%s, %d, %p, %p)\n", debugstr_w(eventtype), reporttype, reportinfo, phandle);
+ if (reportinfo) {
+ TRACE(".wzFriendlyEventName: %s\n", debugstr_w(reportinfo->wzFriendlyEventName));
+ TRACE(".wzApplicationName: %s\n", debugstr_w(reportinfo->wzApplicationName));
+ }
+
+ if (phandle) *phandle = NULL;
+ if (!eventtype || !eventtype[0] || !phandle) {
+ return E_INVALIDARG;
+ }
+
+ len = lstrlenW(eventtype) + 1;
+
+ report = heap_alloc_zero(len * sizeof(WCHAR) + sizeof(report_t));
+ if (!report)
+ return __HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
+
+ lstrcpyW(report->eventtype, eventtype);
+ report->reporttype = reporttype;
+
+ if (reportinfo) {
+ report->info = *reportinfo;
+ } else {
+ FIXME("build report information from scratch for %p\n", report);
+ }
+
+ EnterCriticalSection(&report_table_cs);
+ list_add_head(&report_table, &report->entry);
+ LeaveCriticalSection(&report_table_cs);
+
+ *phandle = report;
+ TRACE("=> %p\n", report);
+ return S_OK;
+}
+
+/***********************************************************************
+ * WerReportSetParameter (wer.@)
+ *
+ * Set one of 10 parameter / value pairs for a report handle
+ *
+ * PARAMS
+ * hreport [i] error reporting handle to add the parameter
+ * id [i] parameter to set (WER_P0 upto WER_P9)
+ * name [i] optional name of the parameter
+ * value [i] value of the parameter
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: A HRESULT error code
+ *
+ */
+HRESULT WINAPI WerReportSetParameter(HREPORT hreport, DWORD id, PCWSTR name, PCWSTR value)
+{
+ FIXME("(%p, %d, %s, %s) :stub\n", hreport, id, debugstr_w(name), debugstr_w(value));
+
+ return E_NOTIMPL;
+}
+
+/***********************************************************************
+ * WerReportSubmit (wer.@)
+ *
+ * Ask the user for permission and send the error report
+ * then kill or restart the application, when requested
+ *
+ * PARAMS
+ * hreport [i] error reporting handle to send
+ * consent [i] current transmit permission
+ * flags [i] flag to select dialog, transmission snd restart options
+ * presult [o] ptr, where the transmission result should be saved
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: A HRESULT error code
+ *
+ */
+HRESULT WINAPI WerReportSubmit(HREPORT hreport, WER_CONSENT consent, DWORD flags, PWER_SUBMIT_RESULT presult)
+{
+ FIXME("(%p, %d, 0x%x, %p) :stub\n", hreport, consent, flags, presult);
+
+ if(!presult)
+ return E_INVALIDARG;
+
+ *presult = WerDisabled;
+ return E_NOTIMPL;
+}
diff --git a/dll/win32/wer/wer.rbuild b/dll/win32/wer/wer.rbuild
new file mode 100644
index 00000000000..852102966ba
--- /dev/null
+++ b/dll/win32/wer/wer.rbuild
@@ -0,0 +1,11 @@
+
+
+
+
+ .
+ include/reactos/wine
+
+ advapi32
+ wine
+ main.c
+
diff --git a/dll/win32/wer/wer.spec b/dll/win32/wer/wer.spec
new file mode 100644
index 00000000000..4303c204b7e
--- /dev/null
+++ b/dll/win32/wer/wer.spec
@@ -0,0 +1,77 @@
+@ stub WerSysprepCleanup
+@ stub WerSysprepGeneralize
+@ stub WerSysprepSpecialize
+@ stub WerUnattendedSetup
+@ stub WerpAddAppCompatData
+@ stub WerpAddFile
+@ stub WerpAddMemoryBlock
+@ stub WerpAddRegisteredDataToReport
+@ stub WerpAddSecondaryParameter
+@ stub WerpAddTextToReport
+@ stub WerpArchiveReport
+@ stub WerpCancelResponseDownload
+@ stub WerpCancelUpload
+@ stub WerpCloseStore
+@ stub WerpCreateMachineStore
+@ stub WerpDeleteReport
+@ stub WerpDestroyWerString
+@ stub WerpDownloadResponse
+@ stub WerpDownloadResponseTemplate
+@ stub WerpEnumerateStoreNext
+@ stub WerpEnumerateStoreStart
+@ stub WerpExtractReportFiles
+@ stub WerpGetBucketId
+@ stub WerpGetDynamicParameter
+@ stub WerpGetEventType
+@ stub WerpGetFileByIndex
+@ stub WerpGetFilePathByIndex
+@ stub WerpGetNumFiles
+@ stub WerpGetNumSecParams
+@ stub WerpGetNumSigParams
+@ stub WerpGetReportFinalConsent
+@ stub WerpGetReportFlags
+@ stub WerpGetReportInformation
+@ stub WerpGetReportTime
+@ stub WerpGetReportType
+@ stub WerpGetResponseId
+@ stub WerpGetResponseUrl
+@ stub WerpGetSecParamByIndex
+@ stub WerpGetSigParamByIndex
+@ stub WerpGetStoreLocation
+@ stub WerpGetStoreType
+@ stub WerpGetTextFromReport
+@ stub WerpGetUIParamByIndex
+@ stub WerpGetUploadTime
+@ stub WerpGetWerStringData
+@ stub WerpIsTransportAvailable
+@ stub WerpLoadReport
+@ stub WerpOpenMachineArchive
+@ stub WerpOpenMachineQueue
+@ stub WerpOpenUserArchive
+@ stub WerpReportCancel
+@ stub WerpRestartApplication
+@ stub WerpSetDynamicParameter
+@ stub WerpSetEventName
+@ stub WerpSetReportFlags
+@ stub WerpSetReportInformation
+@ stub WerpSetReportTime
+@ stub WerpSetReportUploadContextToken
+@ stub WerpShowNXNotification
+@ stub WerpShowSecondLevelConsent
+@ stub WerpShowUpsellUI
+@ stub WerpSubmitReportFromStore
+@ stub WerpSvcReportFromMachineQueue
+@ stdcall WerAddExcludedApplication(wstr long)
+@ stdcall WerRemoveExcludedApplication(wstr long)
+@ stub WerReportAddDump
+@ stub WerReportAddFile
+@ stdcall WerReportCloseHandle(ptr)
+@ stdcall WerReportCreate(wstr long ptr ptr)
+@ stdcall WerReportSetParameter(ptr long wstr wstr)
+@ stub WerReportSetUIOption
+@ stdcall WerReportSubmit(ptr long long ptr)
+@ stub WerpGetReportConsent
+@ stub WerpIsDisabled
+@ stub WerpOpenUserQueue
+@ stub WerpPromtUser
+@ stub WerpSetCallBack
diff --git a/dll/win32/win32.rbuild b/dll/win32/win32.rbuild
index 5cd3d741736..30dbf94704c 100644
--- a/dll/win32/win32.rbuild
+++ b/dll/win32/win32.rbuild
@@ -595,6 +595,9 @@
+
+
+
diff --git a/dll/win32/wtsapi32/wtsapi32.c b/dll/win32/wtsapi32/wtsapi32.c
index ab35de4f2ea..604752aa297 100644
--- a/dll/win32/wtsapi32/wtsapi32.c
+++ b/dll/win32/wtsapi32/wtsapi32.c
@@ -141,6 +141,16 @@ void WINAPI WTSFreeMemory(PVOID pMemory)
return;
}
+/************************************************************
+ * WTSLogoffSession (WTSAPI32.@)
+ */
+BOOL WINAPI WTSLogoffSession(HANDLE hserver, DWORD session_id, BOOL bwait)
+{
+ FIXME("(%p, 0x%x, %d): stub\n", hserver, session_id, bwait);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
/************************************************************
* WTSOpenServerA (WTSAPI32.@)
*/
diff --git a/dll/win32/wtsapi32/wtsapi32.spec b/dll/win32/wtsapi32/wtsapi32.spec
index 2be9df00c9d..f20bbe206b6 100644
--- a/dll/win32/wtsapi32/wtsapi32.spec
+++ b/dll/win32/wtsapi32/wtsapi32.spec
@@ -7,7 +7,7 @@
@ stdcall WTSEnumerateSessionsA(long long long ptr ptr)
@ stdcall WTSEnumerateSessionsW(long long long ptr ptr)
@ stdcall WTSFreeMemory(ptr)
-@ stub WTSLogoffSession
+@ stdcall WTSLogoffSession(ptr long long)
@ stdcall WTSOpenServerA(ptr)
@ stdcall WTSOpenServerW(ptr)
@ stdcall WTSQuerySessionInformationA(long long long ptr ptr)
diff --git a/drivers/filesystems/npfs/create.c b/drivers/filesystems/npfs/create.c
index bef462fb8d7..dc70991447e 100644
--- a/drivers/filesystems/npfs/create.c
+++ b/drivers/filesystems/npfs/create.c
@@ -13,17 +13,19 @@
#define NDEBUG
#include
+//#define USING_PROPER_NPFS_WAIT_SEMANTICS
+
/* FUNCTIONS *****************************************************************/
-static PNPFS_FCB
-NpfsFindPipe(PNPFS_DEVICE_EXTENSION DeviceExt,
+PNPFS_FCB
+NpfsFindPipe(PNPFS_VCB Vcb,
PUNICODE_STRING PipeName)
{
PLIST_ENTRY CurrentEntry;
PNPFS_FCB Fcb;
- CurrentEntry = DeviceExt->PipeListHead.Flink;
- while (CurrentEntry != &DeviceExt->PipeListHead)
+ CurrentEntry = Vcb->PipeListHead.Flink;
+ while (CurrentEntry != &Vcb->PipeListHead)
{
Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, PipeListEntry);
if (RtlCompareUnicodeString(PipeName,
@@ -103,53 +105,153 @@ NpfsSignalAndRemoveListeningServerInstance(PNPFS_FCB Fcb,
}
+static VOID
+NpfsOpenFileSystem(PNPFS_FCB Fcb,
+ PFILE_OBJECT FileObject,
+ PIO_STATUS_BLOCK IoStatus)
+{
+ PNPFS_CCB Ccb;
+
+ DPRINT("NpfsOpenFileSystem()\n");
+
+ Ccb = ExAllocatePool(NonPagedPool, sizeof(NPFS_CCB));
+ if (Ccb == NULL)
+ {
+ IoStatus->Status = STATUS_NO_MEMORY;
+ return;
+ }
+
+ Ccb->Type = CCB_DEVICE;
+ Ccb->Fcb = Fcb;
+
+ FileObject->FsContext = Fcb;
+ FileObject->FsContext2 = Ccb;
+
+ IoStatus->Information = FILE_OPENED;
+ IoStatus->Status = STATUS_SUCCESS;
+
+ return;
+}
+
+
+static VOID
+NpfsOpenRootDirectory(PNPFS_FCB Fcb,
+ PFILE_OBJECT FileObject,
+ PIO_STATUS_BLOCK IoStatus)
+{
+ PNPFS_CCB Ccb;
+
+ DPRINT("NpfsOpenRootDirectory()\n");
+
+ Ccb = ExAllocatePool(NonPagedPool, sizeof(NPFS_CCB));
+ if (Ccb == NULL)
+ {
+ IoStatus->Status = STATUS_NO_MEMORY;
+ return;
+ }
+
+ Ccb->Type = CCB_DIRECTORY;
+ Ccb->Fcb = Fcb;
+
+ FileObject->FsContext = Fcb;
+ FileObject->FsContext2 = Ccb;
+
+ IoStatus->Information = FILE_OPENED;
+ IoStatus->Status = STATUS_SUCCESS;
+
+ return;
+}
+
+
NTSTATUS NTAPI
NpfsCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PEXTENDED_IO_STACK_LOCATION IoStack;
+ PUNICODE_STRING FileName;
PFILE_OBJECT FileObject;
+ PFILE_OBJECT RelatedFileObject;
PNPFS_FCB Fcb;
PNPFS_CCB ClientCcb;
PNPFS_CCB ServerCcb = NULL;
- PNPFS_DEVICE_EXTENSION DeviceExt;
- BOOLEAN SpecialAccess;
+ PNPFS_VCB Vcb;
ACCESS_MASK DesiredAccess;
+ NTSTATUS Status;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
+ BOOLEAN SpecialAccess;
+#endif
DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
+ RelatedFileObject = FileObject->RelatedFileObject;
+ FileName = &FileObject->FileName;
DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess;
+
DPRINT("FileObject %p\n", FileObject);
DPRINT("FileName %wZ\n", &FileObject->FileName);
Irp->IoStatus.Information = 0;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
SpecialAccess = ((DesiredAccess & SPECIFIC_RIGHTS_ALL) == FILE_READ_ATTRIBUTES);
if (SpecialAccess)
{
DPRINT("NpfsCreate() open client end for special use!\n");
}
+#endif
+
+ DPRINT("FileName->Length: %hu RelatedFileObject: %p\n", FileName->Length, RelatedFileObject);
+
+ /* Open the file system */
+ if (FileName->Length == 0 &&
+ (RelatedFileObject == NULL || ((PNPFS_CCB)RelatedFileObject->FsContext2)->Type == CCB_DEVICE))
+ {
+ DPRINT("Open the file system\n");
+
+ NpfsOpenFileSystem(Vcb->DeviceFcb,
+ FileObject,
+ &Irp->IoStatus);
+
+ Status = Irp->IoStatus.Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+ }
+
+ /* Open the root directory */
+ if (FileName->Length == 2 && FileName->Buffer[0] == L'\\' && RelatedFileObject == NULL)
+ {
+ DPRINT("Open the root directory\n");
+
+ NpfsOpenRootDirectory(Vcb->RootFcb,
+ FileObject,
+ &Irp->IoStatus);
+
+ Status = Irp->IoStatus.Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+ }
+
/*
* Step 1. Find the pipe we're trying to open.
*/
- KeLockMutex(&DeviceExt->PipeListLock);
- Fcb = NpfsFindPipe(DeviceExt,
+ KeLockMutex(&Vcb->PipeListLock);
+ Fcb = NpfsFindPipe(Vcb,
&FileObject->FileName);
if (Fcb == NULL)
{
/* Not found, bail out with error. */
DPRINT("No pipe found!\n");
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
/*
* Acquire the lock for CCB lists. From now on no modifications to the
@@ -170,11 +272,16 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
return STATUS_NO_MEMORY;
}
+ ClientCcb->Type = CCB_PIPE;
ClientCcb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
ClientCcb->Fcb = Fcb;
ClientCcb->PipeEnd = FILE_PIPE_CLIENT_END;
ClientCcb->OtherSide = NULL;
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
ClientCcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
+#else
+ ClientCcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+#endif
InitializeListHead(&ClientCcb->ReadRequestListHead);
DPRINT("CCB: %p\n", ClientCcb);
@@ -212,9 +319,10 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
/*
* Step 3. Search for listening server CCB.
*/
-
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
if (!SpecialAccess)
{
+#endif
/*
* WARNING: Point of no return! Once we get the server CCB it's
* possible that we completed a wait request and so we have to
@@ -270,6 +378,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
/* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
NpfsSignalAndRemoveListeningServerInstance(Fcb, ServerCcb);
}
+#ifndef USING_PROPER_NPFS_WAIT_SEMANTICS
}
else if (IsListEmpty(&Fcb->ServerCcbListHead))
{
@@ -287,6 +396,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
+#endif
/*
* Step 4. Add the client CCB to a list and connect it if possible.
@@ -326,7 +436,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
{
PEXTENDED_IO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PNAMED_PIPE_CREATE_PARAMETERS Buffer;
@@ -334,7 +444,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
DPRINT("FileObject %p\n", FileObject);
@@ -360,13 +470,14 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
return STATUS_NO_MEMORY;
}
+ Ccb->Type = CCB_PIPE;
Ccb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
/*
* First search for existing Pipe with the same name.
*/
- Fcb = NpfsFindPipe(DeviceExt,
+ Fcb = NpfsFindPipe(Vcb,
&FileObject->FileName);
if (Fcb != NULL)
{
@@ -374,7 +485,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
* Found Pipe with the same name. Check if we are
* allowed to use it.
*/
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
{
@@ -402,7 +513,7 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
if (Fcb == NULL)
{
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
ExFreePool(Ccb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0;
@@ -410,12 +521,14 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
return STATUS_NO_MEMORY;
}
+ Fcb->Type = FCB_PIPE;
+ Fcb->Vcb = Vcb;
Fcb->PipeName.Length = FileObject->FileName.Length;
Fcb->PipeName.MaximumLength = Fcb->PipeName.Length + sizeof(UNICODE_NULL);
Fcb->PipeName.Buffer = ExAllocatePool(NonPagedPool, Fcb->PipeName.MaximumLength);
if (Fcb->PipeName.Buffer == NULL)
{
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
ExFreePool(Fcb);
ExFreePool(Ccb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
@@ -457,18 +570,18 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
{
if (Buffer->InboundQuota == 0)
{
- Fcb->InboundQuota = DeviceExt->DefaultQuota;
+ Fcb->InboundQuota = Vcb->DefaultQuota;
}
else
{
Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
- if (Fcb->InboundQuota < DeviceExt->MinQuota)
+ if (Fcb->InboundQuota < Vcb->MinQuota)
{
- Fcb->InboundQuota = DeviceExt->MinQuota;
+ Fcb->InboundQuota = Vcb->MinQuota;
}
- else if (Fcb->InboundQuota > DeviceExt->MaxQuota)
+ else if (Fcb->InboundQuota > Vcb->MaxQuota)
{
- Fcb->InboundQuota = DeviceExt->MaxQuota;
+ Fcb->InboundQuota = Vcb->MaxQuota;
}
}
}
@@ -481,18 +594,18 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
{
if (Buffer->OutboundQuota == 0)
{
- Fcb->OutboundQuota = DeviceExt->DefaultQuota;
+ Fcb->OutboundQuota = Vcb->DefaultQuota;
}
else
{
Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
- if (Fcb->OutboundQuota < DeviceExt->MinQuota)
+ if (Fcb->OutboundQuota < Vcb->MinQuota)
{
- Fcb->OutboundQuota = DeviceExt->MinQuota;
+ Fcb->OutboundQuota = Vcb->MinQuota;
}
- else if (Fcb->OutboundQuota > DeviceExt->MaxQuota)
+ else if (Fcb->OutboundQuota > Vcb->MaxQuota)
{
- Fcb->OutboundQuota = DeviceExt->MaxQuota;
+ Fcb->OutboundQuota = Vcb->MaxQuota;
}
}
}
@@ -501,8 +614,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
Fcb->OutboundQuota = 0;
}
- InsertTailList(&DeviceExt->PipeListHead, &Fcb->PipeListEntry);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ InsertTailList(&Vcb->PipeListHead, &Fcb->PipeListEntry);
+ KeUnlockMutex(&Vcb->PipeListLock);
}
if (Fcb->InboundQuota)
@@ -514,9 +627,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
if (NewPipe)
{
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
RemoveEntryList(&Fcb->PipeListEntry);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
RtlFreeUnicodeString(&Fcb->PipeName);
ExFreePool(Fcb);
}
@@ -573,7 +686,7 @@ NTSTATUS NTAPI
NpfsCleanup(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
PNPFS_CCB Ccb, OtherSide;
@@ -583,7 +696,7 @@ NpfsCleanup(PDEVICE_OBJECT DeviceObject,
DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = FileObject->FsContext2;
@@ -596,6 +709,24 @@ NpfsCleanup(PDEVICE_OBJECT DeviceObject,
return STATUS_SUCCESS;
}
+ if (Ccb->Type == CCB_DEVICE)
+ {
+ DPRINT("Cleanup the file system!\n");
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
+ if (Ccb->Type == CCB_DIRECTORY)
+ {
+ DPRINT("Cleanup the root directory!\n");
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
DPRINT("CCB %p\n", Ccb);
Fcb = Ccb->Fcb;
@@ -708,9 +839,9 @@ NTSTATUS NTAPI
NpfsClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PNPFS_DEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
BOOLEAN Server;
@@ -718,7 +849,7 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = FileObject->FsContext2;
@@ -731,6 +862,34 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
return STATUS_SUCCESS;
}
+ if (Ccb->Type == CCB_DEVICE)
+ {
+ DPRINT("Closing the file system!\n");
+
+ ExFreePool(Ccb);
+ FileObject->FsContext = NULL;
+ FileObject->FsContext2 = NULL;
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
+ if (Ccb->Type == CCB_DIRECTORY)
+ {
+ DPRINT("Closing the root directory!\n");
+
+ ExFreePool(Ccb);
+ FileObject->FsContext = NULL;
+ FileObject->FsContext2 = NULL;
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
DPRINT("CCB %p\n", Ccb);
Fcb = Ccb->Fcb;
@@ -771,9 +930,9 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
IsListEmpty(&Fcb->ClientCcbListHead))
{
RtlFreeUnicodeString(&Fcb->PipeName);
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
RemoveEntryList(&Fcb->PipeListEntry);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
ExFreePool(Fcb);
FileObject->FsContext = NULL;
}
diff --git a/drivers/filesystems/npfs/finfo.c b/drivers/filesystems/npfs/finfo.c
index fbb1d6090de..46c47c0acf1 100644
--- a/drivers/filesystems/npfs/finfo.c
+++ b/drivers/filesystems/npfs/finfo.c
@@ -214,7 +214,7 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
PIO_STACK_LOCATION IoStack;
FILE_INFORMATION_CLASS FileInformationClass;
PFILE_OBJECT FileObject;
- PNPFS_DEVICE_EXTENSION DeviceExtension;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PVOID SystemBuffer;
@@ -225,7 +225,7 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
IoStack = IoGetCurrentIrpStackLocation (Irp);
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
- DeviceExtension = DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = (PNPFS_CCB)FileObject->FsContext2;
Fcb = Ccb->Fcb;
diff --git a/drivers/filesystems/npfs/fsctrl.c b/drivers/filesystems/npfs/fsctrl.c
index 242102d0d75..9055bb1f902 100644
--- a/drivers/filesystems/npfs/fsctrl.c
+++ b/drivers/filesystems/npfs/fsctrl.c
@@ -15,6 +15,8 @@
#define NDEBUG
#include
+//#define USING_PROPER_NPFS_WAIT_SEMANTICS
+
/* FUNCTIONS *****************************************************************/
static DRIVER_CANCEL NpfsListeningCancelRoutine;
@@ -296,12 +298,66 @@ NpfsWaitPipe(PIRP Irp,
PNPFS_FCB Fcb;
PNPFS_CCB ServerCcb;
PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
- NTSTATUS Status;
LARGE_INTEGER TimeOut;
+ NTSTATUS Status;
+#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
+ PNPFS_VCB Vcb;
+ UNICODE_STRING PipeName;
+#endif
DPRINT("NpfsWaitPipe\n");
WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+
+#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
+ /* Fail, if the CCB does not represent the root directory */
+ if (Ccb->Type != CCB_DIRECTORY)
+ return STATUS_ILLEGAL_FUNCTION;
+
+ /* Calculate the pipe name length and allocate the buffer */
+ PipeName.Length = WaitPipe->NameLength + sizeof(WCHAR);
+ PipeName.MaximumLength = PipeName.Length + sizeof(WCHAR);
+ PipeName.Buffer = ExAllocatePool(NonPagedPool, PipeName.MaximumLength);
+ if (PipeName.Buffer == NULL)
+ {
+ DPRINT1("Could not allocate memory for the pipe name!\n");
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Copy the pipe name into the buffer, prepend a backslash and append a 0 character */
+ PipeName.Buffer[0] = L'\\';
+ RtlCopyMemory(&PipeName.Buffer[1],
+ &WaitPipe->Name[0],
+ WaitPipe->NameLength);
+ PipeName.Buffer[PipeName.Length / sizeof(WCHAR)] = 0;
+
+ DPRINT("Waiting for Pipe %wZ\n", &PipeName);
+
+ /* Get the VCB */
+ Vcb = Ccb->Fcb->Vcb;
+
+ /* Lock the pipe list */
+ KeLockMutex(&Vcb->PipeListLock);
+
+ /* File a pipe with the given name */
+ Fcb = NpfsFindPipe(Vcb,
+ &PipeName);
+
+ /* Unlock the pipe list */
+ KeUnlockMutex(&Vcb->PipeListLock);
+
+ /* Release the pipe name buffer */
+ ExFreePool(PipeName.Buffer);
+
+ /* Fail if not pipe was found */
+ if (Fcb == NULL)
+ {
+ DPRINT("No pipe found!\n", Fcb);
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ DPRINT("Fcb %p\n", Fcb);
+#else
Fcb = Ccb->Fcb;
if (Ccb->PipeState != 0)
@@ -309,6 +365,7 @@ NpfsWaitPipe(PIRP Irp,
DPRINT("Pipe is not in passive (waiting) state!\n");
return STATUS_UNSUCCESSFUL;
}
+#endif
/* search for listening server */
current_entry = Fcb->ServerCcbListHead.Flink;
@@ -484,13 +541,13 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("IoStack: %p\n", IoStack);
FileObject = IoStack->FileObject;
diff --git a/drivers/filesystems/npfs/npfs.c b/drivers/filesystems/npfs/npfs.c
index 147f4107b52..74fe99baeb6 100644
--- a/drivers/filesystems/npfs/npfs.c
+++ b/drivers/filesystems/npfs/npfs.c
@@ -19,9 +19,10 @@ NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
- PNPFS_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName;
+ PNPFS_VCB Vcb;
+ PNPFS_FCB Fcb;
NTSTATUS Status;
DPRINT("Named Pipe FSD 0.0.2\n");
@@ -56,7 +57,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");
Status = IoCreateDevice(DriverObject,
- sizeof(NPFS_DEVICE_EXTENSION),
+ sizeof(NPFS_VCB),
&DeviceName,
FILE_DEVICE_NAMED_PIPE,
0,
@@ -68,21 +69,33 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
return Status;
}
- /* initialize the device object */
+ /* Initialize the device object */
DeviceObject->Flags |= DO_DIRECT_IO;
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
- /* initialize the device extension */
- DeviceExtension = DeviceObject->DeviceExtension;
- InitializeListHead(&DeviceExtension->PipeListHead);
- InitializeListHead(&DeviceExtension->ThreadListHead);
- KeInitializeMutex(&DeviceExtension->PipeListLock, 0);
- DeviceExtension->EmptyWaiterCount = 0;
+ /* Initialize the Volume Control Block (VCB) */
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
+ InitializeListHead(&Vcb->PipeListHead);
+ InitializeListHead(&Vcb->ThreadListHead);
+ KeInitializeMutex(&Vcb->PipeListLock, 0);
+ Vcb->EmptyWaiterCount = 0;
/* set the size quotas */
- DeviceExtension->MinQuota = PAGE_SIZE;
- DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
- DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
+ Vcb->MinQuota = PAGE_SIZE;
+ Vcb->DefaultQuota = 8 * PAGE_SIZE;
+ Vcb->MaxQuota = 64 * PAGE_SIZE;
+
+ /* Create the device FCB */
+ Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
+ Fcb->Type = FCB_DEVICE;
+ Fcb->Vcb = Vcb;
+ Vcb->DeviceFcb = Fcb;
+
+ /* Create the root directory FCB */
+ Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
+ Fcb->Type = FCB_DIRECTORY;
+ Fcb->Vcb = Vcb;
+ Vcb->RootFcb = Fcb;
return STATUS_SUCCESS;
}
diff --git a/drivers/filesystems/npfs/npfs.h b/drivers/filesystems/npfs/npfs.h
index 373980ce6d5..2e47e6858c4 100644
--- a/drivers/filesystems/npfs/npfs.h
+++ b/drivers/filesystems/npfs/npfs.h
@@ -4,7 +4,22 @@
#include
#include
-typedef struct _NPFS_DEVICE_EXTENSION
+typedef enum _FCB_TYPE
+{
+ FCB_DEVICE,
+ FCB_DIRECTORY,
+ FCB_PIPE
+} FCB_TYPE;
+
+typedef enum _CCB_TYPE
+{
+ CCB_DEVICE,
+ CCB_DIRECTORY,
+ CCB_PIPE
+} CCB_TYPE;
+
+/* Volume Control Block (VCB) aka Device Extension */
+typedef struct _NPFS_VCB
{
LIST_ENTRY PipeListHead;
LIST_ENTRY ThreadListHead;
@@ -13,11 +28,14 @@ typedef struct _NPFS_DEVICE_EXTENSION
ULONG MinQuota;
ULONG DefaultQuota;
ULONG MaxQuota;
-} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
+ struct _NPFS_FCB *DeviceFcb;
+ struct _NPFS_FCB *RootFcb;
+} NPFS_VCB, *PNPFS_VCB;
typedef struct _NPFS_FCB
{
- FSRTL_COMMON_FCB_HEADER RFCB;
+ FCB_TYPE Type;
+ PNPFS_VCB Vcb;
UNICODE_STRING PipeName;
LIST_ENTRY PipeListEntry;
KMUTEX CcbListLock;
@@ -40,9 +58,11 @@ typedef struct _NPFS_FCB
typedef struct _NPFS_CCB
{
LIST_ENTRY CcbListEntry;
+ CCB_TYPE Type;
+ PNPFS_FCB Fcb;
+
struct _NPFS_CCB* OtherSide;
struct ETHREAD *Thread;
- PNPFS_FCB Fcb;
KEVENT ConnectEvent;
KEVENT ReadEvent;
KEVENT WriteEvent;
@@ -71,7 +91,7 @@ typedef struct _NPFS_THREAD_CONTEXT
{
ULONG Count;
KEVENT Event;
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
LIST_ENTRY ListEntry;
PVOID WaitObjectArray[MAXIMUM_WAIT_OBJECTS];
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
@@ -135,4 +155,9 @@ NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
+PNPFS_FCB
+NpfsFindPipe(PNPFS_VCB Vcb,
+ PUNICODE_STRING PipeName);
+
+
#endif /* __DRIVERS_FS_NP_NPFS_H */
diff --git a/drivers/filesystems/npfs/rw.c b/drivers/filesystems/npfs/rw.c
index e5ef963b9ad..3c54bd7df47 100644
--- a/drivers/filesystems/npfs/rw.c
+++ b/drivers/filesystems/npfs/rw.c
@@ -48,8 +48,8 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PNPFS_CONTEXT Context;
- PNPFS_DEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION IoStack;
+ PNPFS_VCB Vcb;
PNPFS_CCB Ccb;
PLIST_ENTRY ListEntry;
PNPFS_THREAD_CONTEXT ThreadContext;
@@ -60,17 +60,17 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
IoReleaseCancelSpinLock(Irp->CancelIrql);
Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Ccb = IoStack->FileObject->FsContext2;
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
ExAcquireFastMutex(&Ccb->DataListLock);
switch(IoStack->MajorFunction)
{
case IRP_MJ_READ:
- ListEntry = DeviceExt->ThreadListHead.Flink;
- while (ListEntry != &DeviceExt->ThreadListHead)
+ ListEntry = Vcb->ThreadListHead.Flink;
+ while (ListEntry != &Vcb->ThreadListHead)
{
ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry);
/* Real events start at index 1 */
@@ -92,7 +92,7 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE);
ExReleaseFastMutex(&Ccb->DataListLock);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
return;
}
@@ -103,7 +103,7 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
RemoveEntryList(&Context->ListEntry);
ExReleaseFastMutex(&Ccb->DataListLock);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
@@ -126,12 +126,12 @@ NpfsWaiterThread(PVOID InitContext)
PIO_STACK_LOCATION IoStack = NULL;
KIRQL OldIrql;
- KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+ KeLockMutex(&ThreadContext->Vcb->PipeListLock);
while (1)
{
CurrentCount = ThreadContext->Count;
- KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock);
+ KeUnlockMutex(&ThreadContext->Vcb->PipeListLock);
IoAcquireCancelSpinLock(&OldIrql);
if (Irp && IoSetCancelRoutine(Irp, NULL) != NULL)
{
@@ -162,14 +162,14 @@ NpfsWaiterThread(PVOID InitContext)
{
ASSERT(FALSE);
}
- KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+ KeLockMutex(&ThreadContext->Vcb->PipeListLock);
Count = Status - STATUS_WAIT_0;
ASSERT (Count < CurrentCount);
if (Count > 0)
{
Irp = ThreadContext->WaitIrpArray[Count];
ThreadContext->Count--;
- ThreadContext->DeviceExt->EmptyWaiterCount++;
+ ThreadContext->Vcb->EmptyWaiterCount++;
ThreadContext->WaitObjectArray[Count] = ThreadContext->WaitObjectArray[ThreadContext->Count];
ThreadContext->WaitIrpArray[Count] = ThreadContext->WaitIrpArray[ThreadContext->Count];
}
@@ -184,18 +184,18 @@ NpfsWaiterThread(PVOID InitContext)
if (ThreadContext->WaitIrpArray[i] == NULL)
{
ThreadContext->Count--;
- ThreadContext->DeviceExt->EmptyWaiterCount++;
+ ThreadContext->Vcb->EmptyWaiterCount++;
ThreadContext->WaitObjectArray[i] = ThreadContext->WaitObjectArray[ThreadContext->Count];
ThreadContext->WaitIrpArray[i] = ThreadContext->WaitIrpArray[ThreadContext->Count];
}
}
}
- if (ThreadContext->Count == 1 && ThreadContext->DeviceExt->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS)
+ if (ThreadContext->Count == 1 && ThreadContext->Vcb->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS)
{
/* it exist an other thread with empty wait slots, we can remove our thread from the list */
RemoveEntryList(&ThreadContext->ListEntry);
- ThreadContext->DeviceExt->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1;
- KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock);
+ ThreadContext->Vcb->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1;
+ KeUnlockMutex(&ThreadContext->Vcb->PipeListLock);
break;
}
}
@@ -208,19 +208,21 @@ NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
{
PLIST_ENTRY ListEntry;
PNPFS_THREAD_CONTEXT ThreadContext = NULL;
- NTSTATUS Status;
+ PNPFS_CONTEXT Context;
HANDLE hThread;
+ PNPFS_VCB Vcb;
KIRQL oldIrql;
+ NTSTATUS Status;
- PNPFS_CONTEXT Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
- PNPFS_DEVICE_EXTENSION DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
DPRINT("NpfsAddWaitingReadWriteRequest(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
- ListEntry = DeviceExt->ThreadListHead.Flink;
- while (ListEntry != &DeviceExt->ThreadListHead)
+ ListEntry = Vcb->ThreadListHead.Flink;
+ while (ListEntry != &Vcb->ThreadListHead)
{
ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry);
if (ThreadContext->Count < MAXIMUM_WAIT_OBJECTS)
@@ -229,20 +231,21 @@ NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
}
ListEntry = ListEntry->Flink;
}
- if (ListEntry == &DeviceExt->ThreadListHead)
+
+ if (ListEntry == &Vcb->ThreadListHead)
{
ThreadContext = ExAllocatePool(NonPagedPool, sizeof(NPFS_THREAD_CONTEXT));
if (ThreadContext == NULL)
{
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
return STATUS_NO_MEMORY;
}
- ThreadContext->DeviceExt = DeviceExt;
+
+ ThreadContext->Vcb = Vcb;
KeInitializeEvent(&ThreadContext->Event, SynchronizationEvent, FALSE);
ThreadContext->Count = 1;
ThreadContext->WaitObjectArray[0] = &ThreadContext->Event;
-
DPRINT("Creating a new system thread for waiting read/write requests\n");
Status = PsCreateSystemThread(&hThread,
@@ -255,11 +258,12 @@ NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
if (!NT_SUCCESS(Status))
{
ExFreePool(ThreadContext);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
return Status;
}
- InsertHeadList(&DeviceExt->ThreadListHead, &ThreadContext->ListEntry);
- DeviceExt->EmptyWaiterCount += MAXIMUM_WAIT_OBJECTS - 1;
+
+ InsertHeadList(&Vcb->ThreadListHead, &ThreadContext->ListEntry);
+ Vcb->EmptyWaiterCount += MAXIMUM_WAIT_OBJECTS - 1;
}
IoMarkIrpPending(Irp);
@@ -276,11 +280,11 @@ NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
ThreadContext->WaitObjectArray[ThreadContext->Count] = Context->WaitEvent;
ThreadContext->WaitIrpArray[ThreadContext->Count] = Irp;
ThreadContext->Count++;
- DeviceExt->EmptyWaiterCount--;
+ Vcb->EmptyWaiterCount--;
KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE);
Status = STATUS_SUCCESS;
}
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
return Status;
}
diff --git a/hal/halarm/directory.rbuild b/hal/halarm/directory.rbuild
index 62b91a39624..4e0dfcac6a6 100644
--- a/hal/halarm/directory.rbuild
+++ b/hal/halarm/directory.rbuild
@@ -8,4 +8,11 @@
+
+
+
+
+
+
+
diff --git a/hal/halarm/omap3/halinit_up.c b/hal/halarm/omap3/halinit_up.c
new file mode 100644
index 00000000000..2f3b06cb3b1
--- /dev/null
+++ b/hal/halarm/omap3/halinit_up.c
@@ -0,0 +1,31 @@
+/*
+ * PROJECT: ReactOS HAL
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: hal/halarm/omap3/halinit_up.c
+ * PURPOSE: OMAP3 Board-Specific HAL Initialization
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* GLOBALS ********************************************************************/
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+VOID
+HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+
+}
+
+VOID
+HalpInitPhase1(VOID)
+{
+
+}
+
+/* EOF */
diff --git a/hal/halarm/omap3/halup.rbuild b/hal/halarm/omap3/halup.rbuild
new file mode 100644
index 00000000000..7486fa96116
--- /dev/null
+++ b/hal/halarm/omap3/halup.rbuild
@@ -0,0 +1,16 @@
+
+
+
+
+
+ include
+ include
+
+ hal_generic
+ ntoskrnl
+ kdcom
+
+ halinit_up.c
+ halup.rc
+
+
diff --git a/hal/halarm/omap3/halup.rc b/hal/halarm/omap3/halup.rc
new file mode 100644
index 00000000000..90af6b929ff
--- /dev/null
+++ b/hal/halarm/omap3/halup.rc
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "X86 Uniprocessor Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME "halup\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "halup.dll\0"
+#include
diff --git a/hal/halx86/amd64/mps.S b/hal/halx86/amd64/mps.S
index 35436520ae6..7a3b8c55aa6 100644
--- a/hal/halx86/amd64/mps.S
+++ b/hal/halx86/amd64/mps.S
@@ -8,8 +8,9 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+
+#include
/* FUNCTIONS *****************************************************************/
@@ -92,5 +93,5 @@ MpsTimerInterrupt:
AFTER
iret
-
+END
/* EOF */
diff --git a/hal/halx86/amd64/systimer.S b/hal/halx86/amd64/systimer.S
index 1cb3b6e02a3..47d2a844b23 100644
--- a/hal/halx86/amd64/systimer.S
+++ b/hal/halx86/amd64/systimer.S
@@ -7,8 +7,9 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+
+#include
/* GLOBALS *******************************************************************/
@@ -90,3 +91,4 @@ HalpClockInterrupt:
UNIMPLEMENTED _HalpClockInterrupt
iret
+END
diff --git a/hal/halx86/generic/cmos.c b/hal/halx86/generic/cmos.c
index 71c4e67c13c..6a3a9ec47a3 100644
--- a/hal/halx86/generic/cmos.c
+++ b/hal/halx86/generic/cmos.c
@@ -152,6 +152,7 @@ HalpSetCmosData(IN ULONG BusNumber,
VOID
NTAPI
+INIT_FUNCTION
HalpInitializeCmos(VOID)
{
/* Set default century offset byte */
diff --git a/hal/halx86/generic/dma.c b/hal/halx86/generic/dma.c
index bdfae48bfc0..725e23f2690 100644
--- a/hal/halx86/generic/dma.c
+++ b/hal/halx86/generic/dma.c
@@ -126,6 +126,7 @@ static DMA_OPERATIONS HalpDmaOperations = {
#ifndef _MINIHAL_
VOID
+INIT_FUNCTION
HalpInitDma(VOID)
{
/*
diff --git a/hal/halx86/generic/halinit.c b/hal/halx86/generic/halinit.c
index 9615891c045..f0011d71429 100644
--- a/hal/halx86/generic/halinit.c
+++ b/hal/halx86/generic/halinit.c
@@ -20,6 +20,7 @@ BOOLEAN HalpPciLockSettings;
VOID
NTAPI
+INIT_FUNCTION
HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PCHAR CommandLine;
@@ -45,6 +46,7 @@ HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
*/
BOOLEAN
NTAPI
+INIT_FUNCTION
HalInitSystem(IN ULONG BootPhase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
diff --git a/hal/halx86/generic/i386/systimer.S b/hal/halx86/generic/i386/systimer.S
index 1a5bb45a1b8..8534f88a204 100644
--- a/hal/halx86/generic/i386/systimer.S
+++ b/hal/halx86/generic/i386/systimer.S
@@ -7,12 +7,42 @@
/* INCLUDES ******************************************************************/
-#include
-.intel_syntax noprefix
+#include
+
+#include
+
+EXTERN _HalpAcquireSystemHardwareSpinLock@0:PROC
+EXTERN _HalpReleaseCmosSpinLock@0:PROC
+EXTERN _DbgBreakPoint@0:PROC
+EXTERN _HalpCurrentRollOver:DWORD
+EXTERN _HalpPerfCounterCutoff:DWORD
+
+#define PIC1_BASE HEX(20) /* IO base address for master PIC */
+#define PIC2_BASE HEX(A0) /* IO base address for slave PIC */
+#define PIC1_COMMAND PIC1_BASE
+#define PIC1_DATA (PIC1_BASE+1)
+#define PIC2_COMMAND PIC2_BASE
+#define PIC2_DATA (PIC2_BASE+1)
+#define PIC_EOI HEX(20)
+#define PIC_SPECIFIC_EOI2 HEX(62)
+
+#define CMOS_ADDR HEX(70)
+#define CMOS_DATA HEX(71)
+#define CMOS_REGISTER_A HEX(0A)
+#define CMOS_REGISTER_B HEX(0B)
+#define CMOS_REGISTER_C HEX(0C)
+#define CMOS_REGISTER_D HEX(0D)
+
+#define PIT_CH0 HEX(40)
+#define PIT_MODE HEX(43)
+#define SYSTEM_CTRL_PORT_A HEX(92)
/* GLOBALS *******************************************************************/
-.globl _HalpPerfCounter
+.data
+ASSUME CS:NOTHING, DS:NOTHING, ES:NOTHING, FS:NOTHING, GS:NOTHING
+
+PUBLIC _HalpPerfCounter
_HalpLastPerfCounterLow: .long 0
_HalpLastPerfCounterHigh: .long 0
_HalpPerfCounter:
@@ -22,8 +52,8 @@ _HalpSystemHardwareFlags: .long 0
/* FUNCTIONS *****************************************************************/
-.global _HalpCalibrateStallExecution@0
-.func HalpCalibrateStallExecution@0
+.code
+PUBLIC _HalpCalibrateStallExecution@0
_HalpCalibrateStallExecution@0:
/* Setup the stack frame */
@@ -37,27 +67,27 @@ _HalpCalibrateStallExecution@0:
/* Get the current interrupt mask on the PICs */
xor eax, eax
- in al, 0xA1
+ in al, PIC2_DATA
shl eax, 8
- in al, 0x21
+ in al, PIC1_DATA
/* Save it */
push eax
/* Now mask everything except the RTC and PIC 2 chain-interrupt */
- mov eax, ~((1 << 2) | (1 << 8))
+ mov eax, NOT (HEX(04) OR HEX(100))
/* Program the PICs */
- out 0x21, al
+ out PIC1_DATA, al
shr eax, 8
- out 0xA1, al
+ out PIC2_DATA, al
/* Now get the IDT */
sidt [ebp-8]
mov ecx, [ebp-6]
/* Get the IDT entry for the RTC */
- mov eax, 0x38
+ mov eax, HEX(38)
shl eax, 3
add ecx, eax
@@ -70,7 +100,7 @@ _HalpCalibrateStallExecution@0:
mov eax, offset OnlyOnePersonCanWriteHalCode
mov [ecx], ax
mov word ptr [ecx+2], KGDT_R0_CODE
- mov word ptr [ecx+4], 0x8E00
+ mov word ptr [ecx+4], HEX(08E00)
shr eax, 16
mov [ecx+6], ax
@@ -81,18 +111,18 @@ _HalpCalibrateStallExecution@0:
call _HalpAcquireSystemHardwareSpinLock@0
/* Now initialize register A on the CMOS */
- mov ax, (0x2D << 8) | 0xA
- out 0x70, al
+ mov ax, HEX(2D00) OR CMOS_REGISTER_A
+ out CMOS_ADDR, al
jmp $+2
mov al, ah
- out 0x71, al
+ out CMOS_DATA, al
jmp $+2
/* Read register B */
- mov ax, 0xB
- out 0x70, al
+ mov ax, CMOS_REGISTER_B
+ out CMOS_ADDR, al
jmp $+2
- in al, 0x71
+ in al, CMOS_DATA
jmp $+2
/* Don't touch the LastKnownGoodConfig hack */
@@ -100,28 +130,28 @@ _HalpCalibrateStallExecution@0:
mov ah, al
/* Enable the interrupt */
- or ah, 0x42
+ or ah, HEX(42)
/* Now write the register B */
- mov al, 0xB
- out 0x70, al
+ mov al, CMOS_REGISTER_B
+ out CMOS_ADDR, al
jmp $+2
mov al, ah
- out 0x71, al
+ out CMOS_DATA, al
jmp $+2
/* Read register C */
- mov al, 0xC
- out 0x70, al
+ mov al, CMOS_REGISTER_C
+ out CMOS_ADDR, al
jmp $+2
- in al, 0x71
+ in al, CMOS_DATA
jmp $+2
/* Read register D */
- mov al, 0xD
- out 0x70, al
+ mov al, CMOS_REGISTER_D
+ out CMOS_ADDR, al
jmp $+2
- in al, 0x71
+ in al, CMOS_DATA
jmp $+2
/* Release CMOS lock */
@@ -169,18 +199,18 @@ OnlyOnePersonCanWriteHalCode:
call _HalpAcquireSystemHardwareSpinLock@0
/* Now initialize register A on the CMOS */
- mov ax, (0x2D << 8) | 0xA
- out 0x70, al
+ mov ax, HEX(2D00) OR CMOS_REGISTER_A
+ out CMOS_ADDR, al
jmp $+2
mov al, ah
- out 0x71, al
+ out CMOS_DATA, al
jmp $+2
/* Read register B */
- mov ax, 0xB
- out 0x70, al
+ mov ax, CMOS_REGISTER_B
+ out CMOS_ADDR, al
jmp $+2
- in al, 0x71
+ in al, CMOS_DATA
jmp $+2
/* Don't touch the LastKnownGoodConfig hack */
@@ -188,38 +218,38 @@ OnlyOnePersonCanWriteHalCode:
mov ah, al
/* Enable the interrupt */
- or ah, 0x42
+ or ah, HEX(42)
/* Now write the register B */
- mov al, 0xB
- out 0x70, al
+ mov al, CMOS_REGISTER_B
+ out CMOS_ADDR, al
jmp $+2
mov al, ah
- out 0x71, al
+ out CMOS_DATA, al
jmp $+2
/* Read register C */
- mov al, 0xC
- out 0x70, al
+ mov al, CMOS_REGISTER_C
+ out CMOS_ADDR, al
jmp $+2
- in al, 0x71
+ in al, CMOS_DATA
jmp $+2
/* Read register D */
- mov al, 0xD
- out 0x70, al
+ mov al, CMOS_REGISTER_D
+ out CMOS_ADDR, al
jmp $+2
- in al, 0x71
+ in al, CMOS_DATA
jmp $+2
/* Release CMOS lock */
call _HalpReleaseCmosSpinLock@0
/* Dismiss the interrupt */
- mov al, 0x20
- out 0xA0, al
- mov al, 0x62
- out 0x20, al
+ mov al, PIC_EOI
+ out PIC2_COMMAND, al
+ mov al, PIC_SPECIFIC_EOI2
+ out PIC1_COMMAND, al
/* Reset the counter and return back to the looper */
xor eax, eax
@@ -248,24 +278,24 @@ FoundFactor:
/* Prepare for interrupt return */
pop eax
push offset AndItsNotYou
- mov eax, 0x13
+ mov eax, HEX(13)
/* Acquire CMOS lock */
call _HalpAcquireSystemHardwareSpinLock@0
/* Now initialize register A on the CMOS */
- mov ax, (0x2D << 8) | 0xA
- out 0x70, al
+ mov ax, HEX(2D00) OR CMOS_REGISTER_A
+ out CMOS_ADDR, al
jmp $+2
mov al, ah
- out 0x71, al
+ out CMOS_DATA, al
jmp $+2
/* Read register B */
- mov ax, 0xB
- out 0x70, al
+ mov ax, CMOS_REGISTER_B
+ out CMOS_ADDR, al
jmp $+2
- in al, 0x71
+ in al, CMOS_DATA
jmp $+2
/* Don't touch the LastKnownGoodConfig hack */
@@ -273,34 +303,34 @@ FoundFactor:
mov ah, al
/* Disable the interrupt */
- or ah, 0x2
+ or ah, 2
/* Now write the register B */
- mov al, 0xB
- out 0x70, al
+ mov al, CMOS_REGISTER_B
+ out CMOS_ADDR, al
jmp $+2
mov al, ah
- out 0x71, al
+ out CMOS_DATA, al
jmp $+2
/* Read register C */
- mov al, 0xC
- out 0x70, al
+ mov al, CMOS_REGISTER_C
+ out CMOS_ADDR, al
jmp $+2
- in al, 0x71
+ in al, CMOS_DATA
jmp $+2
/* Release CMOS lock */
call _HalpReleaseCmosSpinLock@0
/* Dismiss the interrupt */
- mov al, 0x20
- out 0xA0, al
- mov al, 0x62
- out 0x20, al
+ mov al, PIC_EOI
+ out PIC2_COMMAND, al
+ mov al, PIC_SPECIFIC_EOI2
+ out PIC1_COMMAND, al
/* Disable interrupts on return */
- and word ptr [esp+8], ~EFLAGS_INTERRUPT_MASK
+ and word ptr [esp+8], NOT EFLAGS_INTERRUPT_MASK
iretd
/************************* WE ARE BACK FROM RTC ***************************/
@@ -313,9 +343,9 @@ AndItsNotYou:
/* Restore the mask */
pop eax
- out 0x21, al
+ out PIC1_DATA, al
shr eax, 8
- out 0xA1, al
+ out PIC2_DATA, al
/* Restore EFLAGS */
popf
@@ -324,11 +354,10 @@ AndItsNotYou:
mov esp, ebp
pop ebp
ret
-.endfunc
+
#ifndef _MINIHAL_
-.globl _KeStallExecutionProcessor@4
-.func KeStallExecutionProcessor@4
+PUBLIC _KeStallExecutionProcessor@4
_KeStallExecutionProcessor@4:
/* Get the number of microseconds required */
@@ -356,11 +385,9 @@ SubtractLoop:
Done:
/* Return */
ret 4
-.endfunc
#endif
-.global _KeQueryPerformanceCounter@4
-.func KeQueryPerformanceCounter@4
+PUBLIC _KeQueryPerformanceCounter@4
_KeQueryPerformanceCounter@4:
/* Check if we were called too early */
@@ -380,20 +407,20 @@ LoopPreInt:
LoopPostInt:
/* Get the current value */
- mov ebx, _HalpPerfCounterLow
- mov esi, _HalpPerfCounterHigh
+ mov ebx, dword ptr _HalpPerfCounterLow
+ mov esi, dword ptr _HalpPerfCounterHigh
/* Read 8254 timer */
- mov al, 0
- out 0x43, al
- in al, 0x92
- or al, _HalpPerfCounterCutoff
- out 0x92, al
+ mov al, 0 /* Interrupt on terminal count */
+ out PIT_MODE, al
+ in al, SYSTEM_CTRL_PORT_A
+ or al, byte ptr _HalpPerfCounterCutoff
+ out SYSTEM_CTRL_PORT_A, al
jmp $+2
- in al, 0x40
+ in al, PIT_CH0
jmp $+2
movzx ecx, al
- in al, 0x40
+ in al, PIT_CH0
mov ch, al
/* Enable interrupts and do a short wait */
@@ -406,8 +433,8 @@ LoopPostInt:
cli
/* Get the counter value again */
- mov eax, _HalpPerfCounterLow
- mov edx, _HalpPerfCounterHigh
+ mov eax, dword ptr _HalpPerfCounterLow
+ mov edx, dword ptr _HalpPerfCounterHigh
/* Check if someone updated the counter */
cmp eax, ebx
@@ -417,7 +444,7 @@ LoopPostInt:
/* Check if the current 8254 value causes rollover */
neg ecx
- add ecx, _HalpCurrentRollOver
+ add ecx, dword ptr _HalpCurrentRollOver
jnb DoRollOver
SetSum:
@@ -427,19 +454,19 @@ SetSum:
adc edx, 0
/* Check if we're above or below the last high value */
- cmp edx, _HalpLastPerfCounterHigh
+ cmp edx, dword ptr _HalpLastPerfCounterHigh
jb short BelowHigh
jnz short BelowLow
/* Check if we're above or below the last low value */
- cmp eax, _HalpLastPerfCounterLow
+ cmp eax, dword ptr _HalpLastPerfCounterLow
jb BelowHigh
BelowLow:
/* Update the last value and bring back interrupts */
- mov _HalpLastPerfCounterLow, eax
- mov _HalpLastPerfCounterHigh, edx
+ mov dword ptr _HalpLastPerfCounterLow, eax
+ mov dword ptr _HalpLastPerfCounterHigh, edx
popf
/* Check if caller wants frequency */
@@ -469,7 +496,7 @@ DoRollOver:
/* We might have an incoming interrupt, save EFLAGS and reset rollover */
mov esi, [esp]
- mov ecx, _HalpCurrentRollOver
+ mov ecx, dword ptr _HalpCurrentRollOver
popf
/* Check if interrupts were enabled and try again */
@@ -483,8 +510,8 @@ DoRollOver:
BelowHigh:
/* Get the last counter values */
- mov ebx, _HalpLastPerfCounterLow
- mov esi, _HalpLastPerfCounterHigh
+ mov ebx, dword ptr _HalpLastPerfCounterLow
+ mov esi, dword ptr _HalpLastPerfCounterHigh
/* Check if the previous value was 0 and go back if yes */
mov ecx, ebx
@@ -495,7 +522,7 @@ BelowHigh:
sub ebx, eax
sbb esi, edx
jnz InvalidCount
- cmp ebx, _HalpCurrentRollOver
+ cmp ebx, dword ptr _HalpCurrentRollOver
jg InvalidCount
/* Fixup the count with the last known value */
@@ -517,7 +544,8 @@ BelowHigh:
InvalidCount:
popf
xor eax, eax
- mov _HalpLastPerfCounterLow, eax
- mov _HalpLastPerfCounterHigh, eax
+ mov dword ptr _HalpLastPerfCounterLow, eax
+ mov dword ptr _HalpLastPerfCounterHigh, eax
jmp LoopPreInt
-.endfunc
+
+END
diff --git a/hal/halx86/generic/i386/trap.S b/hal/halx86/generic/i386/trap.S
index 2ad319bfb6e..8a4f4538144 100644
--- a/hal/halx86/generic/i386/trap.S
+++ b/hal/halx86/generic/i386/trap.S
@@ -8,12 +8,12 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+
+#include
#include
-.code32
-.text
+.code
TRAP_ENTRY HalpTrap0D, 0
TRAP_ENTRY HalpApcInterrupt, KI_SOFTWARE_TRAP
@@ -42,4 +42,6 @@ _HalpRealModeStart:
.space 2048
_HalpRealModeEnd:
PUBLIC _HalpRealModeEnd
+.endcode16
+END
diff --git a/hal/halx86/generic/legacy/bus/libpcidata.a b/hal/halx86/generic/legacy/bus/libpcidata.a
new file mode 100644
index 00000000000..a186d0fb299
Binary files /dev/null and b/hal/halx86/generic/legacy/bus/libpcidata.a differ
diff --git a/hal/halx86/generic/legacy/bus/pcibus.c b/hal/halx86/generic/legacy/bus/pcibus.c
index 8169fb19deb..ddb05cacf43 100644
--- a/hal/halx86/generic/legacy/bus/pcibus.c
+++ b/hal/halx86/generic/legacy/bus/pcibus.c
@@ -600,6 +600,7 @@ HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler,
NTSTATUS
NTAPI
+INIT_FUNCTION
HalpSetupPciDeviceForDebugging(IN PVOID LoaderBlock,
IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
{
@@ -609,6 +610,7 @@ HalpSetupPciDeviceForDebugging(IN PVOID LoaderBlock,
NTSTATUS
NTAPI
+INIT_FUNCTION
HalpReleasePciDeviceForDebugging(IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
{
DPRINT1("Unimplemented!\n");
@@ -617,6 +619,7 @@ HalpReleasePciDeviceForDebugging(IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
VOID
NTAPI
+INIT_FUNCTION
HalpRegisterPciDebuggingDeviceInfo(VOID)
{
BOOLEAN Found = FALSE;
@@ -853,6 +856,7 @@ HaliPciInterfaceReadConfig(IN PBUS_HANDLER RootBusHandler,
PPCI_REGISTRY_INFO_INTERNAL
NTAPI
+INIT_FUNCTION
HalpQueryPciRegistryInfo(VOID)
{
#ifndef _MINIHAL_
@@ -1085,6 +1089,7 @@ HalpQueryPciRegistryInfo(VOID)
VOID
NTAPI
+INIT_FUNCTION
HalpInitializePciStubs(VOID)
{
PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
diff --git a/hal/halx86/generic/legacy/bus/pcidata.c b/hal/halx86/generic/legacy/bus/pcidata.c
index 83ccecef7d6..f7ca914752f 100644
--- a/hal/halx86/generic/legacy/bus/pcidata.c
+++ b/hal/halx86/generic/legacy/bus/pcidata.c
@@ -15,7 +15,7 @@
/* GLOBALS *******************************************************************/
#ifndef _MINIHAL_
-CHAR ClassTable[3922] =
+INIT_FUNCTION CHAR ClassTable[3922] =
{
0x43, 0x20, 0x30, 0x30, 0x20, 0x20, 0x55, 0x6E, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69,
0x65, 0x64, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x0D, 0x0A, 0x09, 0x30, 0x30, 0x20, 0x20,
@@ -265,7 +265,7 @@ CHAR ClassTable[3922] =
0x72, 0x00,
};
-CHAR VendorTable[642355] =
+INIT_FUNCTION CHAR VendorTable[642355] =
{
0x30, 0x30, 0x30, 0x30, 0x20, 0x20, 0x47, 0x61, 0x6D, 0x6D, 0x61, 0x67, 0x72, 0x61, 0x70, 0x68,
0x78, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x28, 0x6F, 0x72, 0x20, 0x6D, 0x69, 0x73, 0x73,
diff --git a/hal/halx86/generic/legacy/bussupp.c b/hal/halx86/generic/legacy/bussupp.c
index 078a05980a7..013b8564d79 100644
--- a/hal/halx86/generic/legacy/bussupp.c
+++ b/hal/halx86/generic/legacy/bussupp.c
@@ -65,6 +65,7 @@ HalpAllocateBusHandler(IN INTERFACE_TYPE InterfaceType,
VOID
NTAPI
+INIT_FUNCTION
HalpRegisterInternalBusHandlers(VOID)
{
PBUS_HANDLER Bus;
@@ -139,6 +140,7 @@ HalpRegisterInternalBusHandlers(VOID)
#ifndef _MINIHAL_
NTSTATUS
NTAPI
+INIT_FUNCTION
HalpMarkChipsetDecode(BOOLEAN OverrideEnable)
{
NTSTATUS Status;
@@ -186,6 +188,7 @@ HalpMarkChipsetDecode(BOOLEAN OverrideEnable)
PBUS_HANDLER
NTAPI
+INIT_FUNCTION
HalpAllocateAndInitPciBusHandler(IN ULONG PciType,
IN ULONG BusNo,
IN BOOLEAN TestAllocation)
@@ -270,6 +273,7 @@ HalpAllocateAndInitPciBusHandler(IN ULONG PciType,
BOOLEAN
NTAPI
+INIT_FUNCTION
HalpIsValidPCIDevice(IN PBUS_HANDLER BusHandler,
IN PCI_SLOT_NUMBER Slot)
{
@@ -331,6 +335,7 @@ static BOOLEAN WarningsGiven[5];
NTSTATUS
NTAPI
+INIT_FUNCTION
HalpGetChipHacks(IN USHORT VendorId,
IN USHORT DeviceId,
IN UCHAR RevisionId,
@@ -394,6 +399,7 @@ HalpGetChipHacks(IN USHORT VendorId,
BOOLEAN
NTAPI
+INIT_FUNCTION
HalpIsRecognizedCard(IN PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo,
IN PPCI_COMMON_CONFIG PciData,
IN ULONG Flags)
@@ -474,6 +480,7 @@ HalpIsRecognizedCard(IN PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo,
BOOLEAN
NTAPI
+INIT_FUNCTION
HalpIsIdeDevice(IN PPCI_COMMON_CONFIG PciData)
{
/* Simple test first */
@@ -526,6 +533,7 @@ HalpIsIdeDevice(IN PPCI_COMMON_CONFIG PciData)
BOOLEAN
NTAPI
+INIT_FUNCTION
HalpIsBridgeDevice(IN PPCI_COMMON_CONFIG PciData)
{
/* Either this is a PCI-to-PCI Bridge, or a CardBUS Bridge */
@@ -539,6 +547,7 @@ HalpIsBridgeDevice(IN PPCI_COMMON_CONFIG PciData)
BOOLEAN
NTAPI
+INIT_FUNCTION
HalpGetPciBridgeConfig(IN ULONG PciType,
IN PUCHAR BusCount)
{
@@ -591,6 +600,7 @@ HalpGetPciBridgeConfig(IN ULONG PciType,
VOID
NTAPI
+INIT_FUNCTION
HalpFixupPciSupportedRanges(IN ULONG BusCount)
{
ULONG i;
@@ -653,6 +663,7 @@ HalpFixupPciSupportedRanges(IN ULONG BusCount)
VOID
NTAPI
+INIT_FUNCTION
ShowSize(ULONG x)
{
if (!x) return;
@@ -678,6 +689,7 @@ ShowSize(ULONG x)
VOID
NTAPI
+INIT_FUNCTION
HalpDebugPciDumpBus(IN ULONG i,
IN ULONG j,
IN ULONG k,
@@ -829,6 +841,7 @@ HalpDebugPciDumpBus(IN ULONG i,
VOID
NTAPI
+INIT_FUNCTION
HalpInitializePciBus(VOID)
{
#ifndef _MINIHAL_
@@ -1093,6 +1106,7 @@ HalpInitializePciBus(VOID)
VOID
NTAPI
+INIT_FUNCTION
HalpInitBusHandlers(VOID)
{
/* Register the HAL Bus Handler support */
@@ -1101,6 +1115,7 @@ HalpInitBusHandlers(VOID)
VOID
NTAPI
+INIT_FUNCTION
HalpRegisterKdSupportFunctions(VOID)
{
/* Register PCI Device Functions */
diff --git a/hal/halx86/generic/legacy/halpcat.c b/hal/halx86/generic/legacy/halpcat.c
index 28913f9fc16..c403b6ffd19 100644
--- a/hal/halx86/generic/legacy/halpcat.c
+++ b/hal/halx86/generic/legacy/halpcat.c
@@ -23,6 +23,7 @@ PWCHAR HalName = L"PC Compatible Eisa/Isa HAL";
NTSTATUS
NTAPI
+INIT_FUNCTION
HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
/* There is no ACPI on these HALs */
@@ -31,6 +32,7 @@ HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
HalpBuildAddressMap(VOID)
{
/* FIXME: Inherit ROM blocks from the registry */
@@ -42,6 +44,7 @@ HalpBuildAddressMap(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
HalpGetDebugPortTable(VOID)
{
/* No ACPI */
@@ -50,6 +53,7 @@ HalpGetDebugPortTable(VOID)
ULONG
NTAPI
+INIT_FUNCTION
HalpIs16BitPortDecodeSupported(VOID)
{
/* Only EISA systems support this */
@@ -58,9 +62,11 @@ HalpIs16BitPortDecodeSupported(VOID)
NTSTATUS
NTAPI
+INIT_FUNCTION
HaliInitPnpDriver(VOID)
{
/* On PC-AT, this will interface with the PCI driver */
+ //HalpDebugPciBus();
return STATUS_SUCCESS;
}
@@ -69,6 +75,7 @@ HaliInitPnpDriver(VOID)
*/
VOID
NTAPI
+INIT_FUNCTION
HalReportResourceUsage(VOID)
{
INTERFACE_TYPE InterfaceType;
diff --git a/hal/halx86/generic/memory.c b/hal/halx86/generic/memory.c
index 74f20cbc6ed..979cacf4f0d 100644
--- a/hal/halx86/generic/memory.c
+++ b/hal/halx86/generic/memory.c
@@ -25,7 +25,6 @@ PVOID HalpHeapStart = MM_HAL_HEAP_START;
/* PRIVATE FUNCTIONS *********************************************************/
-
ULONG
NTAPI
HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
diff --git a/hal/halx86/generic/misc.c b/hal/halx86/generic/misc.c
index 4b171a819a6..2ddd18599e1 100644
--- a/hal/halx86/generic/misc.c
+++ b/hal/halx86/generic/misc.c
@@ -24,6 +24,7 @@ CHAR HalpSerialNumber[31];
#ifndef _MINIHAL_
VOID
NTAPI
+INIT_FUNCTION
HalpReportSerialNumber(VOID)
{
NTSTATUS Status;
@@ -54,6 +55,7 @@ HalpReportSerialNumber(VOID)
NTSTATUS
NTAPI
+INIT_FUNCTION
HalpMarkAcpiHal(VOID)
{
NTSTATUS Status;
diff --git a/hal/halx86/generic/timer.c b/hal/halx86/generic/timer.c
index 2f78ac46cd8..89d66279574 100644
--- a/hal/halx86/generic/timer.c
+++ b/hal/halx86/generic/timer.c
@@ -44,6 +44,7 @@ LARGE_INTEGER HalpRolloverTable[15] =
VOID
NTAPI
+INIT_FUNCTION
HalpInitializeClock(VOID)
{
PKPRCB Prcb = KeGetCurrentPrcb();
diff --git a/hal/halx86/generic/usage.c b/hal/halx86/generic/usage.c
index c35df96c3e5..8339119c39a 100644
--- a/hal/halx86/generic/usage.c
+++ b/hal/halx86/generic/usage.c
@@ -63,6 +63,7 @@ ADDRESS_USAGE HalpDefaultIoSpace =
#ifndef _MINIHAL_
VOID
NTAPI
+INIT_FUNCTION
HalpGetResourceSortValue(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
OUT PULONG Scale,
OUT PLARGE_INTEGER Value)
@@ -102,6 +103,7 @@ HalpGetResourceSortValue(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
VOID
NTAPI
+INIT_FUNCTION
HalpBuildPartialFromIdt(IN ULONG Entry,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR RawDescriptor,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR TranslatedDescriptor)
@@ -139,6 +141,7 @@ HalpBuildPartialFromIdt(IN ULONG Entry,
VOID
NTAPI
+INIT_FUNCTION
HalpBuildPartialFromAddress(IN INTERFACE_TYPE Interface,
IN PADDRESS_USAGE CurrentAddress,
IN ULONG Element,
@@ -206,6 +209,7 @@ HalpBuildPartialFromAddress(IN INTERFACE_TYPE Interface,
VOID
NTAPI
+INIT_FUNCTION
HalpReportResourceUsage(IN PUNICODE_STRING HalName,
IN INTERFACE_TYPE InterfaceType)
{
@@ -235,8 +239,9 @@ HalpReportResourceUsage(IN PUNICODE_STRING HalName,
if (!HalpGetInfoFromACPI)
{
/* No, so use our local table */
- Port = HalpComPortIrqMapping[0][0];
- for (i = 0; Port; i++)
+ for (i = 0, Port = HalpComPortIrqMapping[i][0];
+ Port;
+ i++, Port = HalpComPortIrqMapping[i][0])
{
/* Is this the port we want? */
if (Port == (ULONG_PTR)KdComPortInUse)
@@ -248,9 +253,6 @@ HalpReportResourceUsage(IN PUNICODE_STRING HalName,
PRIMARY_VECTOR_BASE,
HIGH_LEVEL);
}
-
- /* Next port */
- Port = HalpComPortIrqMapping[i][0];
}
}
}
@@ -486,6 +488,7 @@ HalpReportResourceUsage(IN PUNICODE_STRING HalName,
VOID
NTAPI
+INIT_FUNCTION
HalpRegisterVector(IN UCHAR Flags,
IN ULONG BusVector,
IN ULONG SystemVector,
@@ -502,6 +505,7 @@ HalpRegisterVector(IN UCHAR Flags,
#ifndef _MINIHAL_
VOID
NTAPI
+INIT_FUNCTION
HalpEnableInterruptHandler(IN UCHAR Flags,
IN ULONG BusVector,
IN ULONG SystemVector,
@@ -509,6 +513,9 @@ HalpEnableInterruptHandler(IN UCHAR Flags,
IN PVOID Handler,
IN KINTERRUPT_MODE Mode)
{
+ /* Set the IDT_LATCHED flag for latched interrupts */
+ if (Mode == Latched) Flags |= IDT_LATCHED;
+
/* Register the vector */
HalpRegisterVector(Flags, BusVector, SystemVector, Irql);
@@ -521,6 +528,7 @@ HalpEnableInterruptHandler(IN UCHAR Flags,
VOID
NTAPI
+INIT_FUNCTION
HalpGetNMICrashFlag(VOID)
{
UNICODE_STRING ValueName;
diff --git a/hal/halx86/include/halp.h b/hal/halx86/include/halp.h
index 3ab0f7b253c..c7b921fb75c 100644
--- a/hal/halx86/include/halp.h
+++ b/hal/halx86/include/halp.h
@@ -4,6 +4,16 @@
#pragma once
+#define PLACE_IN_SECTION(s) __attribute__((section (s)))
+#ifdef __GNUC__
+#define INIT_FUNCTION
+#define PAGE_LOCKED_FUNCTION PLACE_IN_SECTION("pagelk")
+#define PAGE_UNLOCKED_FUNCTION PLACE_IN_SECTION("pagepo")
+#else
+#define INIT_FUNCTION
+#define PAGE_LOCKED_FUNCTION
+#define PAGE_UNLOCKED_FUNCTION
+#endif
#ifdef _MSC_VER
#define REGISTERCALL FASTCALL
diff --git a/include/crt/mingw32/intrin_arm.h b/include/crt/mingw32/intrin_arm.h
index 12ced3ebb4b..f5a07b381fb 100644
--- a/include/crt/mingw32/intrin_arm.h
+++ b/include/crt/mingw32/intrin_arm.h
@@ -67,12 +67,40 @@ __INTRIN_INLINE char _InterlockedCompareExchange8(volatile char * const Destinat
__INTRIN_INLINE short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
{
- return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
+ short a, b;
+
+ __asm__ __volatile__ ( "0:\n\t"
+ "ldr %1, [%2]\n\t"
+ "cmp %1, %4\n\t"
+ "bne 1f\n\t"
+ "swp %0, %3, [%2]\n\t"
+ "cmp %0, %1\n\t"
+ "swpne %3, %0, [%2]\n\t"
+ "bne 0b\n\t"
+ "1:"
+ : "=&r" (a), "=&r" (b)
+ : "r" (Destination), "r" (Exchange), "r" (Comperand)
+ : "cc", "memory");
+
+ return a;
}
-__INTRIN_INLINE long _InterlockedExchangeAdd16(volatile short * const Addend, const short Value)
+__INTRIN_INLINE short _InterlockedExchangeAdd16(volatile short * const Addend, const short Value)
{
- return __sync_fetch_and_add(Addend, Value);
+ short a, b, c;
+
+ __asm__ __volatile__ ( "0:\n\t"
+ "ldr %0, [%3]\n\t"
+ "add %1, %0, %4\n\t"
+ "swp %2, %1, [%3]\n\t"
+ "cmp %0, %2\n\t"
+ "swpne %1, %2, [%3]\n\t"
+ "bne 0b"
+ : "=&r" (a), "=&r" (b), "=&r" (c)
+ : "r" (Value), "r" (Addend)
+ : "cc", "memory");
+
+ return a;
}
__INTRIN_INLINE long _InterlockedCompareExchange(volatile long * const dest, const long exch, const long comp)
diff --git a/include/crt/setjmp.h b/include/crt/setjmp.h
index 2a64a9b7c17..002e525c050 100644
--- a/include/crt/setjmp.h
+++ b/include/crt/setjmp.h
@@ -129,6 +129,15 @@ extern "C" {
SETJMP_FLOAT128 Xmm15;
} _JUMP_BUFFER;
+#elif defined(_M_ARM)
+
+#define _JBLEN 11
+#define _JBTYPE int
+
+#else
+
+#error Define Setjmp for this architecture!
+
#endif
#ifndef _JMP_BUF_DEFINED
diff --git a/include/crt/stddef.h b/include/crt/stddef.h
index 9482677272d..0c366e977fd 100644
--- a/include/crt/stddef.h
+++ b/include/crt/stddef.h
@@ -372,20 +372,13 @@ typedef __WCHAR_TYPE__ wchar_t;
#endif /* __sys_stdtypes_h */
/* A null pointer constant. */
-
-#if defined (_STDDEF_H) || defined (__need_NULL)
-#undef NULL /* in case has defined it. */
-#ifdef __GNUG__
-#define NULL __null
-#else /* G++ */
-#ifndef __cplusplus
-#define NULL ((void *)0)
-#else /* C++ */
+#ifndef NULL
+#ifdef __cplusplus
#define NULL 0
-#endif /* C++ */
-#endif /* G++ */
-#endif /* NULL not defined and or need NULL. */
-#undef __need_NULL
+#else
+#define NULL ((void*)0)
+#endif
+#endif
#ifndef offsetof
diff --git a/include/ddk/ntifs.h b/include/ddk/ntifs.h
index 8c4f1a1bbad..a82cd79053a 100644
--- a/include/ddk/ntifs.h
+++ b/include/ddk/ntifs.h
@@ -7344,7 +7344,7 @@ FsRtlAddBaseMcbEntry(
IN LONGLONG SectorCount);
NTKERNELAPI
-BOOLEAN
+VOID
NTAPI
FsRtlRemoveBaseMcbEntry(
IN PBASE_MCB Mcb,
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 233a0c96a4b..05f57a0d23f 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -9726,7 +9726,7 @@ KeQuerySystemTime(
OUT PLARGE_INTEGER CurrentTime);
#endif /* !_M_AMD64 */
-#if !defined(_X86_)
+#if !defined(_X86_) && !defined(_M_ARM)
NTKERNELAPI
KIRQL
NTAPI
diff --git a/include/ndk/arm/ketypes.h b/include/ndk/arm/ketypes.h
index bbf85af50cb..feb0c16c6dc 100644
--- a/include/ndk/arm/ketypes.h
+++ b/include/ndk/arm/ketypes.h
@@ -473,8 +473,13 @@ typedef struct _KIPCR
ULONG StallScaleFactor;
UCHAR SpareUnused;
UCHAR Number;
+ UCHAR Spare0;
+ UCHAR SecondLevelCacheAssociativity;
+ ULONG VdmAlert;
+ ULONG KernelReserved[14];
+ ULONG SecondLevelCacheSize;
+ ULONG HalReserved[16];
// arm part
- UCHAR Spare0[2];
UCHAR IrqlMask[32];
ULONG IrqlTable[32];
PKINTERRUPT_ROUTINE InterruptRoutine[32];
diff --git a/include/ndk/arm/mmtypes.h b/include/ndk/arm/mmtypes.h
index febadda1cd5..371b1594368 100644
--- a/include/ndk/arm/mmtypes.h
+++ b/include/ndk/arm/mmtypes.h
@@ -68,7 +68,7 @@ typedef struct _HARDWARE_LARGE_PTE_ARMV6
ULONG NoExecute:1;
ULONG Domain:4;
ULONG Ecc:1;
- ULONG Accessed:1;
+ ULONG Sbo:1;
ULONG Owner:1;
ULONG CacheAttributes:3;
ULONG ReadOnly:1;
@@ -85,7 +85,7 @@ typedef struct _HARDWARE_PTE_ARMV6
ULONG Valid:1;
ULONG Buffered:1;
ULONG Cached:1;
- ULONG Accessed:1;
+ ULONG Sbo:1;
ULONG Owner:1;
ULONG CacheAttributes:3;
ULONG ReadOnly:1;
@@ -100,9 +100,9 @@ C_ASSERT(sizeof(HARDWARE_PTE_ARMV6) == sizeof(ULONG));
typedef struct _MMPTE_SOFTWARE
{
- ULONG Valid:1;
+ ULONG Valid:2;
ULONG PageFileLow:4;
- ULONG Protection:5;
+ ULONG Protection:4;
ULONG Prototype:1;
ULONG Transition:1;
ULONG PageFileHigh:20;
@@ -110,12 +110,12 @@ typedef struct _MMPTE_SOFTWARE
typedef struct _MMPTE_TRANSITION
{
- ULONG Valid:1;
- ULONG Write:1;
+ ULONG Valid:2;
+ ULONG Buffered:1;
+ ULONG Cached:1;
ULONG Owner:1;
- ULONG WriteThrough:1;
- ULONG CacheDisable:1;
- ULONG Protection:5;
+ ULONG Protection:4;
+ ULONG ReadOnly:1;
ULONG Prototype:1;
ULONG Transition:1;
ULONG PageFrameNumber:20;
@@ -123,19 +123,18 @@ typedef struct _MMPTE_TRANSITION
typedef struct _MMPTE_PROTOTYPE
{
- ULONG Valid:1;
+ ULONG Valid:2;
ULONG ProtoAddressLow:7;
ULONG ReadOnly:1;
- ULONG WhichPool:1;
ULONG Prototype:1;
ULONG ProtoAddressHigh:21;
} MMPTE_PROTOTYPE;
typedef struct _MMPTE_SUBSECTION
{
- ULONG Valid:1;
+ ULONG Valid:2;
ULONG SubsectionAddressLow:4;
- ULONG Protection:5;
+ ULONG Protection:4;
ULONG Prototype:1;
ULONG SubsectionAddressHigh:20;
ULONG WhichPool:1;
@@ -143,47 +142,38 @@ typedef struct _MMPTE_SUBSECTION
typedef struct _MMPTE_LIST
{
- ULONG Valid:1;
+ ULONG Valid:2;
ULONG OneEntry:1;
ULONG filler0:8;
ULONG NextEntry:20;
ULONG Prototype:1;
- ULONG filler1:1;
} MMPTE_LIST;
typedef union _MMPTE_HARDWARE
{
- struct
- {
- ULONG NoExecute:1;
- ULONG Valid:1;
- ULONG Buffered:1;
- ULONG Cached:1;
- ULONG Access:1;
- ULONG Owner:1;
- ULONG CacheAttributes:3;
- ULONG ReadOnly:1;
- ULONG Shared:1;
- ULONG NonGlobal:1;
- ULONG PageFrameNumber:20;
- };
- ULONG AsUlong;
+ ULONG NoExecute:1;
+ ULONG Valid:1;
+ ULONG Buffered:1;
+ ULONG Cached:1;
+ ULONG Sbo:1;
+ ULONG Owner:1;
+ ULONG CacheAttributes:3;
+ ULONG ReadOnly:1;
+ ULONG Prototype:1;
+ ULONG NonGlobal:1;
+ ULONG PageFrameNumber:20;
} MMPTE_HARDWARE, *PMMPTE_HARDWARE;
typedef union _MMPDE_HARDWARE
{
- struct
- {
- ULONG Valid:1;
- ULONG LargePage:1;
- ULONG Buffered:1;
- ULONG Cached:1;
- ULONG NoExecute:1;
- ULONG Domain:4;
- ULONG Ecc:1;
- ULONG PageFrameNumber:22;
- };
- ULONG AsUlong;
+ ULONG Valid:1;
+ ULONG LargePage:1;
+ ULONG Buffered:1;
+ ULONG Cached:1;
+ ULONG NoExecute:1;
+ ULONG Domain:4;
+ ULONG Ecc:1;
+ ULONG PageFrameNumber:22;
} MMPDE_HARDWARE, *PMMPDE_HARDWARE;
typedef struct _MMPDE
diff --git a/include/ndk/umfuncs.h b/include/ndk/umfuncs.h
index 4cbee159ca7..a3721733e3a 100644
--- a/include/ndk/umfuncs.h
+++ b/include/ndk/umfuncs.h
@@ -295,13 +295,14 @@ LdrUnloadDll(
IN PVOID BaseAddress
);
+typedef VOID NTAPI (*PLDR_CALLBACK)(PVOID CallbackContext, PVOID Name);
NTSTATUS
NTAPI
LdrVerifyImageMatchesChecksum(
IN HANDLE FileHandle,
- ULONG Unknown1,
- ULONG Unknown2,
- ULONG Unknown3
+ IN PLDR_CALLBACK Callback,
+ IN PVOID CallbackContext,
+ OUT PUSHORT ImageCharacterstics
);
#endif
diff --git a/include/psdk/specstrings.h b/include/psdk/specstrings.h
new file mode 100644
index 00000000000..de2c0bae219
--- /dev/null
+++ b/include/psdk/specstrings.h
@@ -0,0 +1,278 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+#define __specstrings
+
+#ifdef __cplusplus
+#ifndef __nothrow
+#define __nothrow __declspec(nothrow)
+#endif
+#else
+#ifndef __nothrow
+#define __nothrow
+#endif
+#endif
+
+#define __deref_in
+#define __deref_in_ecount(size)
+#define __deref_in_bcount(size)
+#define __deref_in_opt
+#define __deref_in_ecount_opt(size)
+#define __deref_in_bcount_opt(size)
+#define __deref_opt_in
+#define __deref_opt_in_ecount(size)
+#define __deref_opt_in_bcount(size)
+#define __deref_opt_in_opt
+#define __deref_opt_in_ecount_opt(size)
+#define __deref_opt_in_bcount_opt(size)
+#define __out_awcount(expr,size)
+#define __in_awcount(expr,size)
+#ifndef __cplusplus
+#define __null
+#endif
+#define __notnull
+#define __maybenull
+#define __readonly
+#define __notreadonly
+#define __maybereadonly
+#define __valid
+#define __notvalid
+#define __maybevalid
+#define __readableTo(extent)
+#define __elem_readableTo(size)
+#define __byte_readableTo(size)
+#define __writableTo(size)
+#define __elem_writableTo(size)
+#define __byte_writableTo(size)
+#define __deref
+#define __pre
+#define __post
+#define __precond(expr)
+#define __postcond(expr)
+#define __exceptthat
+#define __execeptthat
+#define __inner_success(expr)
+#define __inner_checkReturn
+#define __inner_typefix(ctype)
+#define __inner_override
+#define __inner_callback
+#define __inner_blocksOn(resource)
+#define __inner_fallthrough_dec
+#define __inner_fallthrough
+#define __refparam
+#define __inner_control_entrypoint(category)
+#define __inner_data_entrypoint(category)
+#define __ecount(size)
+#define __bcount(size)
+#ifndef __cplusplus
+#define __in
+#endif
+#define __in_opt
+#define __in_nz
+#define __in_nz_opt
+#define __in_z
+#define __in_z_opt
+#define __in_ecount(size)
+#define __in_ecount_nz(size)
+#define __in_ecount_z(size)
+#define __in_bcount(size)
+#define __in_bcount_z(size)
+#define __in_bcount_nz(size)
+#define __in_ecount_opt(size)
+#define __in_bcount_opt(size)
+#define __in_ecount_z_opt(size)
+#define __in_bcount_z_opt(size)
+#define __in_ecount_nz_opt(size)
+#define __in_bcount_nz_opt(size)
+#define __out
+#define __out_ecount(size)
+#define __out_z
+#define __out_nz
+#define __out_nz_opt
+#define __out_z_opt
+#define __out_ecount_part(size,length)
+#define __out_ecount_full(size)
+#define __out_ecount_nz(size)
+#define __out_ecount_z(size)
+#define __out_ecount_part_z(size,length)
+#define __out_ecount_full_z(size)
+#define __out_bcount(size)
+#define __out_bcount_part(size,length)
+#define __out_bcount_full(size)
+#define __out_bcount_z(size)
+#define __out_bcount_part_z(size,length)
+#define __out_bcount_full_z(size)
+#define __out_bcount_nz(size)
+#define __inout
+#define __inout_ecount(size)
+#define __inout_bcount(size)
+#define __inout_ecount_part(size,length)
+#define __inout_bcount_part(size,length)
+#define __inout_ecount_full(size)
+#define __inout_bcount_full(size)
+#define __inout_z
+#define __inout_ecount_z(size)
+#define __inout_bcount_z(size)
+#define __inout_nz
+#define __inout_ecount_nz(size)
+#define __inout_bcount_nz(size)
+#define __ecount_opt(size)
+#define __bcount_opt(size)
+#define __out_opt
+#define __out_ecount_opt(size)
+#define __out_bcount_opt(size)
+#define __out_ecount_part_opt(size,length)
+#define __out_bcount_part_opt(size,length)
+#define __out_ecount_full_opt(size)
+#define __out_bcount_full_opt(size)
+#define __out_ecount_z_opt(size)
+#define __out_bcount_z_opt(size)
+#define __out_ecount_part_z_opt(size,length)
+#define __out_bcount_part_z_opt(size,length)
+#define __out_ecount_full_z_opt(size)
+#define __out_bcount_full_z_opt(size)
+#define __out_ecount_nz_opt(size)
+#define __out_bcount_nz_opt(size)
+#define __inout_opt
+#define __inout_ecount_opt(size)
+#define __inout_bcount_opt(size)
+#define __inout_ecount_part_opt(size,length)
+#define __inout_bcount_part_opt(size,length)
+#define __inout_ecount_full_opt(size)
+#define __inout_bcount_full_opt(size)
+#define __inout_z_opt
+#define __inout_ecount_z_opt(size)
+#define __inout_bcount_z_opt(size)
+#define __inout_nz_opt
+#define __inout_ecount_nz_opt(size)
+#define __inout_bcount_nz_opt(size)
+#define __deref_ecount(size)
+#define __deref_bcount(size)
+#define __deref_out
+#define __deref_out_ecount(size)
+#define __deref_out_bcount(size)
+#define __deref_out_ecount_part(size,length)
+#define __deref_out_bcount_part(size,length)
+#define __deref_out_ecount_full(size)
+#define __deref_out_bcount_full(size)
+#define __deref_out_z
+#define __deref_out_ecount_z(size)
+#define __deref_out_bcount_z(size)
+#define __deref_out_nz
+#define __deref_out_ecount_nz(size)
+#define __deref_out_bcount_nz(size)
+#define __deref_inout
+#define __deref_inout_ecount(size)
+#define __deref_inout_bcount(size)
+#define __deref_inout_ecount_part(size,length)
+#define __deref_inout_bcount_part(size,length)
+#define __deref_inout_ecount_full(size)
+#define __deref_inout_bcount_full(size)
+#define __deref_inout_z
+#define __deref_inout_ecount_z(size)
+#define __deref_inout_bcount_z(size)
+#define __deref_inout_nz
+#define __deref_inout_ecount_nz(size)
+#define __deref_inout_bcount_nz(size)
+#define __deref_ecount_opt(size)
+#define __deref_bcount_opt(size)
+#define __deref_out_opt
+#define __deref_out_ecount_opt(size)
+#define __deref_out_bcount_opt(size)
+#define __deref_out_ecount_part_opt(size,length)
+#define __deref_out_bcount_part_opt(size,length)
+#define __deref_out_ecount_full_opt(size)
+#define __deref_out_bcount_full_opt(size)
+#define __deref_out_z_opt
+#define __deref_out_ecount_z_opt(size)
+#define __deref_out_bcount_z_opt(size)
+#define __deref_out_nz_opt
+#define __deref_out_ecount_nz_opt(size)
+#define __deref_out_bcount_nz_opt(size)
+#define __deref_inout_opt
+#define __deref_inout_ecount_opt(size)
+#define __deref_inout_bcount_opt(size)
+#define __deref_inout_ecount_part_opt(size,length)
+#define __deref_inout_bcount_part_opt(size,length)
+#define __deref_inout_ecount_full_opt(size)
+#define __deref_inout_bcount_full_opt(size)
+#define __deref_inout_z_opt
+#define __deref_inout_ecount_z_opt(size)
+#define __deref_inout_bcount_z_opt(size)
+#define __deref_inout_nz_opt
+#define __deref_inout_ecount_nz_opt(size)
+#define __deref_inout_bcount_nz_opt(size)
+#define __deref_opt_ecount(size)
+#define __deref_opt_bcount(size)
+#define __deref_opt_out
+#define __deref_opt_out_z
+#define __deref_opt_out_ecount(size)
+#define __deref_opt_out_bcount(size)
+#define __deref_opt_out_ecount_part(size,length)
+#define __deref_opt_out_bcount_part(size,length)
+#define __deref_opt_out_ecount_full(size)
+#define __deref_opt_out_bcount_full(size)
+#define __deref_opt_inout
+#define __deref_opt_inout_ecount(size)
+#define __deref_opt_inout_bcount(size)
+#define __deref_opt_inout_ecount_part(size,length)
+#define __deref_opt_inout_bcount_part(size,length)
+#define __deref_opt_inout_ecount_full(size)
+#define __deref_opt_inout_bcount_full(size)
+#define __deref_opt_inout_z
+#define __deref_opt_inout_ecount_z(size)
+#define __deref_opt_inout_bcount_z(size)
+#define __deref_opt_inout_nz
+#define __deref_opt_inout_ecount_nz(size)
+#define __deref_opt_inout_bcount_nz(size)
+#define __deref_opt_ecount_opt(size)
+#define __deref_opt_bcount_opt(size)
+#define __deref_opt_out_opt
+#define __deref_opt_out_ecount_opt(size)
+#define __deref_opt_out_bcount_opt(size)
+#define __deref_opt_out_ecount_part_opt(size,length)
+#define __deref_opt_out_bcount_part_opt(size,length)
+#define __deref_opt_out_ecount_full_opt(size)
+#define __deref_opt_out_bcount_full_opt(size)
+#define __deref_opt_out_z_opt
+#define __deref_opt_out_ecount_z_opt(size)
+#define __deref_opt_out_bcount_z_opt(size)
+#define __deref_opt_out_nz_opt
+#define __deref_opt_out_ecount_nz_opt(size)
+#define __deref_opt_out_bcount_nz_opt(size)
+#define __deref_opt_inout_opt
+#define __deref_opt_inout_ecount_opt(size)
+#define __deref_opt_inout_bcount_opt(size)
+#define __deref_opt_inout_ecount_part_opt(size,length)
+#define __deref_opt_inout_bcount_part_opt(size,length)
+#define __deref_opt_inout_ecount_full_opt(size)
+#define __deref_opt_inout_bcount_full_opt(size)
+#define __deref_opt_inout_z_opt
+#define __deref_opt_inout_ecount_z_opt(size)
+#define __deref_opt_inout_bcount_z_opt(size)
+#define __deref_opt_inout_nz_opt
+#define __deref_opt_inout_ecount_nz_opt(size)
+#define __deref_opt_inout_bcount_nz_opt(size)
+#define __success(expr)
+#define __nullterminated
+#define __nullnullterminated
+#define __reserved
+#define __checkReturn
+#define __typefix(ctype)
+#define __override
+#define __callback
+#define __format_string
+#define __blocksOn(resource)
+#define __control_entrypoint(category)
+#define __data_entrypoint(category)
+#ifndef __fallthrough
+#define __fallthrough
+#endif
+#ifndef __analysis_assume
+#define __analysis_assume(expr)
+#endif
+
+//#endif
+
diff --git a/include/psdk/werapi.h b/include/psdk/werapi.h
new file mode 100644
index 00000000000..4b79c041787
--- /dev/null
+++ b/include/psdk/werapi.h
@@ -0,0 +1,127 @@
+/*
+ * Windows Error Reporing definitions
+ *
+ * Copyright (C) 2010 Louis Lenders
+ *
+ * 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 __WINE_WERAPI_H
+#define __WINE_WERAPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Only 10 parameter are allowed in WerReportSetParameter */
+#define WER_MAX_PARAM_COUNT 10
+#define WER_P0 0
+#define WER_P1 1
+#define WER_P2 2
+#define WER_P3 3
+#define WER_P4 4
+#define WER_P5 5
+#define WER_P6 6
+#define WER_P7 7
+#define WER_P8 8
+#define WER_P9 9
+
+/* Flags for WerReportSubmit */
+#define WER_SUBMIT_HONOR_RECOVERY 0x0001
+#define WER_SUBMIT_HONOR_RESTART 0x0002
+#define WER_SUBMIT_QUEUE 0x0004
+#define WER_SUBMIT_SHOW_DEBUG 0x0008
+#define WER_SUBMIT_ADD_REGISTERED_DATA 0x0010
+#define WER_SUBMIT_OUTOFPROCESS 0x0020
+#define WER_SUBMIT_NO_CLOSE_UI 0x0040
+#define WER_SUBMIT_NO_QUEUE 0x0080
+#define WER_SUBMIT_NO_ARCHIVE 0x0100
+#define WER_SUBMIT_START_MINIMIZED 0x0200
+#define WER_SUBMIT_OUTOFPROCESS_ASYNC 0x0400
+#define WER_SUBMIT_BYPASS_DATA_THROTTLING 0x0800
+#define WER_SUBMIT_ARCHIVE_PARAMETERS_ONLY 0x1000
+#define WER_SUBMIT_REPORT_MACHINE_ID 0x2000
+
+/* #### */
+
+typedef HANDLE HREPORT;
+
+typedef enum _WER_CONSENT
+{
+ WerConsentNotAsked = 1,
+ WerConsentApproved,
+ WerConsentDenied,
+ WerConsentAlwaysPrompt,
+ WerConsentMax
+} WER_CONSENT;
+
+typedef enum _WER_REGISTER_FILE_TYPE
+{
+ WerRegFileTypeUserDocument = 1,
+ WerRegFileTypeOther = 2,
+ WerRegFileTypeMax
+} WER_REGISTER_FILE_TYPE;
+
+typedef struct _WER_REPORT_INFORMATION
+{
+ DWORD dwSize;
+ HANDLE hProcess;
+ WCHAR wzConsentKey[64];
+ WCHAR wzFriendlyEventName[128];
+ WCHAR wzApplicationName[128];
+ WCHAR wzApplicationPath[MAX_PATH];
+ WCHAR wzDescription[512];
+ HWND hwndParent;
+} WER_REPORT_INFORMATION, *PWER_REPORT_INFORMATION;
+
+
+typedef enum _WER_REPORT_TYPE
+{
+ WerReportNonCritical = 0,
+ WerReportCritical,
+ WerReportApplicationCrash,
+ WerReportApplicationHang,
+ WerReportKernel,
+ WerReportInvalid
+} WER_REPORT_TYPE;
+
+typedef enum _WER_SUBMIT_RESULT
+{
+ WerReportQueued = 1,
+ WerReportUploaded,
+ WerReportDebug,
+ WerReportFailed,
+ WerDisabled,
+ WerReportCancelled,
+ WerDisabledQueue,
+ WerReportAsync,
+ WerCustomAction
+} WER_SUBMIT_RESULT, *PWER_SUBMIT_RESULT;
+
+/* #### */
+
+HRESULT WINAPI WerAddExcludedApplication(PCWSTR, BOOL);
+HRESULT WINAPI WerRegisterFile(PCWSTR file, WER_REGISTER_FILE_TYPE regfiletype, DWORD flags);
+HRESULT WINAPI WerRemoveExcludedApplication(PCWSTR, BOOL);
+HRESULT WINAPI WerReportCloseHandle(HREPORT);
+HRESULT WINAPI WerReportCreate(PCWSTR, WER_REPORT_TYPE, PWER_REPORT_INFORMATION, HREPORT*);
+HRESULT WINAPI WerReportSetParameter(HREPORT, DWORD, PCWSTR, PCWSTR);
+HRESULT WINAPI WerReportSubmit(HREPORT, WER_CONSENT, DWORD, PWER_SUBMIT_RESULT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_WERAPI_H */
diff --git a/include/psdk/windef.h b/include/psdk/windef.h
index a29a959e747..1fa768b2ecd 100644
--- a/include/psdk/windef.h
+++ b/include/psdk/windef.h
@@ -1,5 +1,17 @@
-#ifndef _WINDEF_H
-#define _WINDEF_H
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+#ifndef _WINDEF_
+#define _WINDEF_
+
+#define _WINDEF_H // wine ...
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4255)
+#endif
#ifndef _M_AMD64
#if !defined(__ROS_LONG64__)
@@ -9,62 +21,68 @@
#endif
#endif
+#ifndef NO_STRICT
+#ifndef STRICT
+#define STRICT 1
+#endif
+#endif
+
+#ifndef WIN32
+#define WIN32
+#endif
+
+#if defined(_MAC) && !defined(_WIN32)
+#define _WIN32
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4255)
+#ifndef WINVER
+#define WINVER 0x0502
#endif
-#ifndef WINVER
-#define WINVER 0x0400
-/*
- * If you need Win32 API features newer the Win95 and WinNT then you must
- * define WINVER before including windows.h or any other method of including
- * the windef.h header.
- */
-#endif
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT WINVER
-/*
- * There may be the need to define _WIN32_WINNT to a value different from
- * the value of WINVER. I don't have any example of why you would do that.
- * However, if you must then define _WIN32_WINNT to the value required before
- * including windows.h or any other method of including the windef.h header.
- */
-#endif
-#ifndef WIN32
-#define WIN32
-#endif
-#ifndef _WIN32
-#define _WIN32
-#endif
-#define FAR
-#define far
-#define NEAR
-#define near
-#ifndef CONST
-#define CONST const
+#ifndef BASETYPES
+#define BASETYPES
+#ifndef __ROS_LONG64__
+typedef unsigned long ULONG;
+#else
+typedef unsigned int ULONG;
#endif
+typedef ULONG *PULONG;
+typedef unsigned short USHORT;
+typedef USHORT *PUSHORT;
+typedef unsigned char UCHAR;
+typedef UCHAR *PUCHAR;
+typedef char *PSZ;
+typedef int INT;
+#endif /* BASETYPES */
+
#undef MAX_PATH
#define MAX_PATH 260
#ifndef NULL
#ifdef __cplusplus
+#ifndef _WIN64
#define NULL 0
#else
-#define NULL ((void*)0)
+#define NULL 0LL
+#endif /* W64 */
+#else
+#define NULL ((void *)0)
#endif
#endif
+
#ifndef FALSE
#define FALSE 0
#endif
+
#ifndef TRUE
#define TRUE 1
#endif
+#ifndef _NO_W32_PSEUDO_MODIFIERS
#ifndef IN
#define IN
#endif
@@ -74,6 +92,307 @@ extern "C" {
#ifndef OPTIONAL
#define OPTIONAL
#endif
+#endif
+
+#ifdef __GNUC__
+#define PACKED __attribute__((packed))
+#ifndef __declspec
+#define __declspec(e) __attribute__((e))
+#endif
+#ifndef _declspec
+#define _declspec(e) __attribute__((e))
+#endif
+#elif defined(__WATCOMC__)
+#define PACKED
+#else
+#define PACKED
+#define _cdecl
+#define __cdecl
+#endif
+
+#ifdef __GNUC__
+#define DECLSPEC_NORETURN __declspec(noreturn)
+#define DECLARE_STDCALL_P( type ) __stdcall type
+#elif defined(__WATCOMC__)
+#define DECLSPEC_NORETURN
+#define DECLARE_STDCALL_P( type ) type __stdcall
+#elif defined(_MSC_VER)
+#define DECLSPEC_NORETURN __declspec(noreturn)
+#define DECLARE_STDCALL_P( type ) type __stdcall
+#endif /* __GNUC__/__WATCOMC__ */
+
+#define DECLSPEC_IMPORT __declspec(dllimport)
+#define DECLSPEC_EXPORT __declspec(dllexport)
+#ifndef DECLSPEC_NOINLINE
+#if (_MSC_VER >= 1300)
+#define DECLSPEC_NOINLINE __declspec(noinline)
+#elif defined(__GNUC__)
+#define DECLSPEC_NOINLINE __attribute__((noinline))
+#else
+#define DECLSPEC_NOINLINE
+#endif
+#endif
+
+#undef far
+#undef near
+#undef pascal
+
+#define far
+#define near
+#define pascal __stdcall
+
+//#define cdecl _cdecl
+#ifndef CDECL
+#define CDECL _cdecl
+#endif
+
+#if !defined(__x86_64__) //defined(_STDCALL_SUPPORTED)
+#ifndef CALLBACK
+#define CALLBACK __stdcall
+#endif
+#ifndef WINAPI
+#define WINAPI __stdcall
+#endif
+#define WINAPIV __cdecl
+#define APIENTRY WINAPI
+#define APIPRIVATE WINAPI
+#define PASCAL WINAPI
+#else
+#define CALLBACK
+#define WINAPI
+#define WINAPIV
+#define APIENTRY WINAPI
+#define APIPRIVATE
+#define PASCAL pascal
+#endif
+
+#undef FAR
+#undef NEAR
+#define FAR
+#define NEAR
+
+#ifndef CONST
+#define CONST const
+#endif
+
+#ifndef _DEF_WINBOOL_
+#define _DEF_WINBOOL_
+typedef int WINBOOL;
+#pragma push_macro("BOOL")
+#undef BOOL
+#if !defined(__OBJC__) && !defined(__OBJC_BOOL) && !defined(__objc_INCLUDE_GNU)
+typedef int BOOL;
+#endif
+#define BOOL WINBOOL
+typedef BOOL *PBOOL;
+typedef BOOL *LPBOOL;
+#pragma pop_macro("BOOL")
+#endif /* _DEF_WINBOOL_ */
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+#ifndef __ROS_LONG64__
+ typedef unsigned long DWORD;
+#else
+ typedef unsigned int DWORD;
+#endif
+typedef float FLOAT;
+typedef FLOAT *PFLOAT;
+typedef BYTE *PBYTE;
+typedef BYTE *LPBYTE;
+typedef int *PINT;
+typedef int *LPINT;
+typedef WORD *PWORD;
+typedef WORD *LPWORD;
+#ifndef __ROS_LONG64__
+typedef long *LPLONG;
+#else
+typedef int *LPLONG;
+#endif
+typedef DWORD *PDWORD;
+typedef DWORD *LPDWORD;
+typedef void *LPVOID;
+#ifndef _LPCVOID_DEFINED
+#define _LPCVOID_DEFINED
+typedef CONST void *LPCVOID;
+#endif
+//typedef int INT;
+typedef unsigned int UINT;
+typedef unsigned int *PUINT;
+typedef unsigned int *LPUINT;
+
+
+
+
+#ifndef NT_INCLUDED
+#include
+#endif
+
+//#include
+
+typedef UINT_PTR WPARAM;
+typedef LONG_PTR LPARAM;
+typedef LONG_PTR LRESULT;
+#ifndef _HRESULT_DEFINED
+typedef LONG HRESULT;
+#define _HRESULT_DEFINED
+#endif
+
+#ifndef NOMINMAX
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+#endif
+
+#define MAKEWORD(a,b) ((WORD)(((BYTE)((DWORD_PTR)(a) & 0xff)) | ((WORD)((BYTE)((DWORD_PTR)(b) & 0xff))) << 8))
+#define MAKELONG(a,b) ((LONG)(((WORD)((DWORD_PTR)(a) & 0xffff)) | ((DWORD)((WORD)((DWORD_PTR)(b) & 0xffff))) << 16))
+#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xffff))
+#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16))
+#define LOBYTE(w) ((BYTE)((DWORD_PTR)(w) & 0xff))
+#define HIBYTE(w) ((BYTE)((DWORD_PTR)(w) >> 8))
+
+#ifndef WIN_INTERNAL
+DECLARE_HANDLE (HWND);
+//DECLARE_HANDLE (HHOOK);
+#ifdef WINABLE
+DECLARE_HANDLE (HEVENT);
+#endif
+#endif
+
+typedef WORD ATOM;
+
+typedef HANDLE *SPHANDLE;
+typedef HANDLE *LPHANDLE;
+typedef HANDLE HGLOBAL;
+typedef HANDLE HLOCAL;
+typedef HANDLE GLOBALHANDLE;
+typedef HANDLE LOCALHANDLE;
+#ifdef _WIN64
+typedef INT_PTR (WINAPI *FARPROC)();
+typedef INT_PTR (WINAPI *NEARPROC)();
+typedef INT_PTR (WINAPI *PROC)();
+#else
+typedef int (WINAPI *FARPROC)();
+typedef int (WINAPI *NEARPROC)();
+typedef int (WINAPI *PROC)();
+#endif
+
+typedef void *HGDIOBJ;
+
+DECLARE_HANDLE(HKEY);
+typedef HKEY *PHKEY;
+
+DECLARE_HANDLE(HACCEL);
+DECLARE_HANDLE(HBITMAP);
+DECLARE_HANDLE(HBRUSH);
+DECLARE_HANDLE(HCOLORSPACE);
+DECLARE_HANDLE(HDC);
+DECLARE_HANDLE(HGLRC);
+DECLARE_HANDLE(HDESK);
+DECLARE_HANDLE(HENHMETAFILE);
+DECLARE_HANDLE(HFONT);
+DECLARE_HANDLE(HICON);
+DECLARE_HANDLE(HMENU);
+DECLARE_HANDLE(HMETAFILE);
+DECLARE_HANDLE(HINSTANCE);
+typedef HINSTANCE HMODULE;
+DECLARE_HANDLE(HPALETTE);
+DECLARE_HANDLE(HPEN);
+DECLARE_HANDLE(HRGN);
+DECLARE_HANDLE(HRSRC);
+DECLARE_HANDLE(HSTR);
+DECLARE_HANDLE(HTASK);
+DECLARE_HANDLE(HWINSTA);
+DECLARE_HANDLE(HKL);
+DECLARE_HANDLE(HMONITOR);
+DECLARE_HANDLE(HWINEVENTHOOK);
+DECLARE_HANDLE(HUMPD);
+
+typedef int HFILE;
+typedef HICON HCURSOR;
+typedef DWORD COLORREF;
+typedef DWORD *LPCOLORREF;
+
+#define HFILE_ERROR ((HFILE)-1)
+
+typedef struct tagRECT {
+ LONG left;
+ LONG top;
+ LONG right;
+ LONG bottom;
+} RECT,*PRECT,*NPRECT,*LPRECT;
+
+typedef const RECT *LPCRECT;
+
+typedef struct _RECTL {
+ LONG left;
+ LONG top;
+ LONG right;
+ LONG bottom;
+} RECTL,*PRECTL,*LPRECTL;
+
+typedef const RECTL *LPCRECTL;
+
+typedef struct tagPOINT {
+ LONG x;
+ LONG y;
+} POINT,*PPOINT,*NPPOINT,*LPPOINT;
+
+typedef struct _POINTL {
+ LONG x;
+ LONG y;
+} POINTL,*PPOINTL;
+
+typedef struct tagSIZE {
+ LONG cx;
+ LONG cy;
+} SIZE,*PSIZE,*LPSIZE;
+
+typedef SIZE SIZEL;
+typedef SIZE *PSIZEL,*LPSIZEL;
+
+typedef struct tagPOINTS {
+ SHORT x;
+ SHORT y;
+} POINTS,*PPOINTS,*LPPOINTS;
+
+typedef struct _FILETIME {
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+} FILETIME,*PFILETIME,*LPFILETIME;
+#define _FILETIME_
+
+#define DM_UPDATE 1
+#define DM_COPY 2
+#define DM_PROMPT 4
+#define DM_MODIFY 8
+
+#define DM_IN_BUFFER DM_MODIFY
+#define DM_IN_PROMPT DM_PROMPT
+#define DM_OUT_BUFFER DM_COPY
+#define DM_OUT_DEFAULT DM_UPDATE
+
+#define DC_FIELDS 1
+#define DC_PAPERS 2
+#define DC_PAPERSIZE 3
+#define DC_MINEXTENT 4
+#define DC_MAXEXTENT 5
+#define DC_BINS 6
+#define DC_DUPLEX 7
+#define DC_SIZE 8
+#define DC_EXTRA 9
+#define DC_VERSION 10
+#define DC_DRIVER 11
+#define DC_BINNAMES 12
+#define DC_ENUMRESOLUTIONS 13
+#define DC_FILEDEPENDENCIES 14
+#define DC_TRUETYPE 15
+#define DC_PAPERNAMES 16
+#define DC_ORIENTATION 17
+#define DC_COPIES 18
/* needed by header files generated by WIDL */
#ifdef __WINESRC__
@@ -98,26 +417,41 @@ extern "C" {
# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
#endif
+#define UNREFERENCED_PARAMETER(P) {(P)=(P);}
+#define UNREFERENCED_LOCAL_VARIABLE(L) {(L)=(L);}
+#define DBG_UNREFERENCED_PARAMETER(P)
+#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
+
+#ifndef __WATCOMC__
+#ifndef _export
+#define _export
+#endif
+#ifndef __export
+#define __export
+#endif
+#endif
+
+#if 0
#ifdef __GNUC__
#define PACKED __attribute__((packed))
-#ifndef _fastcall
-#define _fastcall __attribute__((fastcall))
-#endif
-#ifndef __fastcall
-#define __fastcall __attribute__((fastcall))
-#endif
-#ifndef _stdcall
-#define _stdcall __attribute__((stdcall))
-#endif
-#ifndef __stdcall
-#define __stdcall __attribute__((stdcall))
-#endif
-#ifndef _cdecl
-#define _cdecl __attribute__((cdecl))
-#endif
-#ifndef __cdecl
-#define __cdecl __attribute__((cdecl))
-#endif
+//#ifndef _fastcall
+//#define _fastcall __attribute__((fastcall))
+//#endif
+//#ifndef __fastcall
+//#define __fastcall __attribute__((fastcall))
+//#endif
+//#ifndef _stdcall
+//#define _stdcall __attribute__((stdcall))
+//#endif
+//#ifndef __stdcall
+//#define __stdcall __attribute__((stdcall))
+//#endif
+//#ifndef _cdecl
+//#define _cdecl __attribute__((cdecl))
+//#endif
+//#ifndef __cdecl
+//#define __cdecl __attribute__((cdecl))
+//#endif
#ifndef __declspec
#define __declspec(e) __attribute__((e))
#endif
@@ -131,186 +465,9 @@ extern "C" {
#define _cdecl
#define __cdecl
#endif
-
-#undef pascal
-#undef _pascal
-#undef __pascal
-#define pascal __stdcall
-#define _pascal __stdcall
-#define __pascal __stdcall
-
-#define CDECL _cdecl
-
-#if !defined(__x86_64__) //defined(_STDCALL_SUPPORTED)
-#define CALLBACK __stdcall
-#define WINAPI __stdcall
-#define WINAPIV __cdecl
-#define APIENTRY WINAPI
-#define APIPRIVATE __stdcall
-#define PASCAL __stdcall
-#else
-#define CALLBACK
-#define WINAPI
-#define WINAPIV
-#define APIENTRY WINAPI
-#define APIPRIVATE
-#define PASCAL pascal
#endif
-#define DECLSPEC_IMPORT __declspec(dllimport)
-#define DECLSPEC_EXPORT __declspec(dllexport)
-#ifndef DECLSPEC_NOINLINE
-#if (_MSC_VER >= 1300)
-#define DECLSPEC_NOINLINE __declspec(noinline)
-#elif defined(__GNUC__)
-#define DECLSPEC_NOINLINE __attribute__((noinline))
-#else
-#define DECLSPEC_NOINLINE
-#endif
-#endif
-#ifdef __GNUC__
-#define DECLSPEC_NORETURN __declspec(noreturn)
-#define DECLARE_STDCALL_P( type ) __stdcall type
-#elif defined(__WATCOMC__)
-#define DECLSPEC_NORETURN
-#define DECLARE_STDCALL_P( type ) type __stdcall
-#elif defined(_MSC_VER)
-#define DECLSPEC_NORETURN __declspec(noreturn)
-#define DECLARE_STDCALL_P( type ) type __stdcall
-#endif /* __GNUC__/__WATCOMC__ */
-#define MAKEWORD(a,b) ((WORD)(((BYTE)(a))|(((WORD)((BYTE)(b)))<<8)))
-#define MAKELONG(a,b) ((LONG)(((WORD)(a))|(((DWORD)((WORD)(b)))<<16)))
-#define LOWORD(l) ((WORD)((DWORD_PTR)(l)))
-#define HIWORD(l) ((WORD)(((DWORD_PTR)(l)>>16)&0xFFFF))
-#define LOBYTE(w) ((BYTE)(w))
-#define HIBYTE(w) ((BYTE)(((WORD)(w)>>8)&0xFF))
-
-#ifndef __WATCOMC__
-#ifndef _export
-#define _export
-#endif
-#ifndef __export
-#define __export
-#endif
-#endif
-
-#ifndef NOMINMAX
- #ifndef max
- #define max(a,b) ((a)>(b)?(a):(b))
- #endif
-
- #ifndef min
- #define min(a,b) ((a)<(b)?(a):(b))
- #endif
-#endif
-
-#define UNREFERENCED_PARAMETER(P) {(P)=(P);}
-#define UNREFERENCED_LOCAL_VARIABLE(L) {(L)=(L);}
-#define DBG_UNREFERENCED_PARAMETER(P)
-#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
-
-#ifndef __ANONYMOUS_DEFINED
-#define __ANONYMOUS_DEFINED
-
-#ifndef NONAMELESSUNION
-#ifdef __GNUC__
-#define _ANONYMOUS_UNION __extension__
-#define _ANONYMOUS_STRUCT __extension__
-#elif defined(__WATCOMC__) || defined(_MSC_VER)
-#define _ANONYMOUS_UNION
-#define _ANONYMOUS_STRUCT
-#endif /* __GNUC__/__WATCOMC__ */
-#endif /* NONAMELESSUNION */
-
-#ifndef _ANONYMOUS_UNION
-#define _ANONYMOUS_UNION
-#define _UNION_NAME(x) x
-#define DUMMYUNIONNAME u
-#define DUMMYUNIONNAME1 u1
-#define DUMMYUNIONNAME2 u2
-#define DUMMYUNIONNAME3 u3
-#define DUMMYUNIONNAME4 u4
-#define DUMMYUNIONNAME5 u5
-#define DUMMYUNIONNAME6 u6
-#define DUMMYUNIONNAME7 u7
-#define DUMMYUNIONNAME8 u8
-#else
-#define _UNION_NAME(x)
-#define DUMMYUNIONNAME
-#define DUMMYUNIONNAME1
-#define DUMMYUNIONNAME2
-#define DUMMYUNIONNAME3
-#define DUMMYUNIONNAME4
-#define DUMMYUNIONNAME5
-#define DUMMYUNIONNAME6
-#define DUMMYUNIONNAME7
-#define DUMMYUNIONNAME8
-#endif
-#ifndef _ANONYMOUS_STRUCT
-#define _ANONYMOUS_STRUCT
-#define _STRUCT_NAME(x) x
-#define DUMMYSTRUCTNAME s
-#define DUMMYSTRUCTNAME1 s1
-#define DUMMYSTRUCTNAME2 s2
-#define DUMMYSTRUCTNAME3 s3
-#define DUMMYSTRUCTNAME4 s4
-#define DUMMYSTRUCTNAME5 s5
-#else
-#define _STRUCT_NAME(x)
-#define DUMMYSTRUCTNAME
-#define DUMMYSTRUCTNAME1
-#define DUMMYSTRUCTNAME2
-#define DUMMYSTRUCTNAME3
-#define DUMMYSTRUCTNAME4
-#define DUMMYSTRUCTNAME5
-#endif
-
-#endif /* __ANONYMOUS_DEFINED */
-
-#ifndef NO_STRICT
-#ifndef STRICT
-#define STRICT 1
-#endif
-#endif
-
-#ifndef DWORD_DEFINED
-#define DWORD_DEFINED
-#ifndef __ROS_LONG64__
- typedef unsigned long DWORD;
-#else
- typedef unsigned int DWORD;
-#endif
-#endif//DWORD_DEFINED
-
-typedef int WINBOOL,*PWINBOOL,*LPWINBOOL;
-/* FIXME: Is there a good solution to this? */
-#ifndef XFree86Server
-#ifndef __OBJC__
-typedef WINBOOL BOOL;
-#else
-#define BOOL WINBOOL
-#endif
-typedef unsigned char BYTE;
-#endif /* ndef XFree86Server */
-typedef BOOL *PBOOL,*LPBOOL;
-typedef unsigned short WORD;
-typedef float FLOAT;
-typedef FLOAT *PFLOAT;
-typedef BYTE *PBYTE,*LPBYTE;
-typedef int *PINT,*LPINT;
-typedef WORD *PWORD,*LPWORD;
-#ifndef __ROS_LONG64__
-typedef long *LPLONG;
-#else
-typedef int *LPLONG;
-#endif
-typedef DWORD *PDWORD,*LPDWORD;
-typedef CONST void *LPCVOID;
-
-typedef unsigned int UINT,*PUINT,*LPUINT;
-
-typedef void *LPVOID;
-
+#if 1 // needed by shlwapi.h
#ifndef __ms_va_list
# if defined(__x86_64__) && defined (__GNUC__)
# define __ms_va_list __builtin_ms_va_list
@@ -322,115 +479,7 @@ typedef void *LPVOID;
# define __ms_va_end(list) va_end(list)
# endif
#endif
-
-//
-// Check if ntdef.h already defined these for us
-//
-#ifndef BASETYPES
-#define BASETYPES
-#ifndef __ROS_LONG64__
-typedef unsigned long ULONG, *PULONG;
-#else
-typedef unsigned int ULONG, *PULONG;
#endif
-typedef unsigned short USHORT, *PUSHORT;
-typedef unsigned char UCHAR, *PUCHAR;
-typedef char *PSZ;
-typedef int INT;
-#endif /* BASETYPES */
-
-#ifndef NT_INCLUDED
-#include
-#endif
-
-typedef HANDLE *LPHANDLE;
-typedef UINT_PTR WPARAM;
-typedef LONG_PTR LPARAM;
-typedef LONG_PTR LRESULT;
-#ifndef _HRESULT_DEFINED
-typedef LONG HRESULT;
-#define _HRESULT_DEFINED
-#endif
-#ifndef XFree86Server
-typedef WORD ATOM;
-#endif /* XFree86Server */
-typedef HANDLE HGLOBAL;
-typedef HANDLE HLOCAL;
-typedef HANDLE GLOBALHANDLE;
-typedef HANDLE LOCALHANDLE;
-typedef void *HGDIOBJ;
-DECLARE_HANDLE(HACCEL);
-DECLARE_HANDLE(HBITMAP);
-DECLARE_HANDLE(HBRUSH);
-DECLARE_HANDLE(HCOLORSPACE);
-DECLARE_HANDLE(HDC);
-DECLARE_HANDLE(HGLRC);
-DECLARE_HANDLE(HDESK);
-DECLARE_HANDLE(HENHMETAFILE);
-DECLARE_HANDLE(HFONT);
-DECLARE_HANDLE(HICON);
-DECLARE_HANDLE(HKEY);
-/* FIXME: How to handle these. SM_CMONITORS etc in winuser.h also. */
-/* #if (WINVER >= 0x0500) */
-DECLARE_HANDLE(HMONITOR);
-DECLARE_HANDLE(HUMPD);
-#define HMONITOR_DECLARED 1
-DECLARE_HANDLE(HTERMINAL);
-DECLARE_HANDLE(HWINEVENTHOOK);
-/* #endif */
-typedef HKEY *PHKEY;
-DECLARE_HANDLE(HMENU);
-DECLARE_HANDLE(HMETAFILE);
-DECLARE_HANDLE(HINSTANCE);
-typedef HINSTANCE HMODULE;
-DECLARE_HANDLE(HPALETTE);
-DECLARE_HANDLE(HPEN);
-DECLARE_HANDLE(HRGN);
-DECLARE_HANDLE(HRSRC);
-DECLARE_HANDLE(HSTR);
-DECLARE_HANDLE(HTASK);
-DECLARE_HANDLE(HWND);
-DECLARE_HANDLE(HWINSTA);
-DECLARE_HANDLE(HKL);
-typedef int HFILE;
-typedef HICON HCURSOR;
-typedef DWORD COLORREF;
-typedef DWORD* LPCOLORREF;
-#ifdef _WIN64
-typedef INT_PTR (FAR WINAPI *FARPROC)();
-typedef INT_PTR (NEAR WINAPI *NEARPROC)();
-typedef INT_PTR (WINAPI *PROC)();
-#else
-typedef int (FAR WINAPI *FARPROC)();
-typedef int (NEAR WINAPI *NEARPROC)();
-typedef int (WINAPI *PROC)();
-#endif
-typedef struct tagRECT {
- LONG left;
- LONG top;
- LONG right;
- LONG bottom;
-} RECT,*PRECT,*LPRECT;
-typedef const RECT *LPCRECT;
-typedef struct tagRECTL {
- LONG left;
- LONG top;
- LONG right;
- LONG bottom;
-} RECTL,*PRECTL,*LPRECTL;
-typedef const RECTL *LPCRECTL;
-typedef struct tagPOINT {
- LONG x;
- LONG y;
-} POINT,POINTL,*PPOINT,*LPPOINT,*PPOINTL,*LPPOINTL;
-typedef struct tagSIZE {
- LONG cx;
- LONG cy;
-} SIZE,SIZEL,*PSIZE,*LPSIZE,*PSIZEL,*LPSIZEL;
-typedef struct tagPOINTS {
- SHORT x;
- SHORT y;
-} POINTS,*PPOINTS,*LPPOINTS;
#ifdef _MSC_VER
#pragma warning(pop)
@@ -439,4 +488,6 @@ typedef struct tagPOINTS {
#ifdef __cplusplus
}
#endif
-#endif
+
+#endif /* _WINDEF_ */
+
diff --git a/include/psdk/winnt.h b/include/psdk/winnt.h
index 441660a894f..83adae6ec08 100644
--- a/include/psdk/winnt.h
+++ b/include/psdk/winnt.h
@@ -11,6 +11,62 @@
#include
#endif
+#ifndef __ANONYMOUS_DEFINED
+#define __ANONYMOUS_DEFINED
+#ifndef NONAMELESSUNION
+#ifdef __GNUC__
+#define _ANONYMOUS_UNION __extension__
+#define _ANONYMOUS_STRUCT __extension__
+#elif defined(__WATCOMC__) || defined(_MSC_VER)
+#define _ANONYMOUS_UNION
+#define _ANONYMOUS_STRUCT
+#endif /* __GNUC__/__WATCOMC__ */
+#endif /* NONAMELESSUNION */
+#ifndef _ANONYMOUS_UNION
+#define _ANONYMOUS_UNION
+#define _UNION_NAME(x) x
+#define DUMMYUNIONNAME u
+#define DUMMYUNIONNAME1 u1
+#define DUMMYUNIONNAME2 u2
+#define DUMMYUNIONNAME3 u3
+#define DUMMYUNIONNAME4 u4
+#define DUMMYUNIONNAME5 u5
+#define DUMMYUNIONNAME6 u6
+#define DUMMYUNIONNAME7 u7
+#define DUMMYUNIONNAME8 u8
+#else
+#define _UNION_NAME(x)
+#define DUMMYUNIONNAME
+#define DUMMYUNIONNAME1
+#define DUMMYUNIONNAME2
+#define DUMMYUNIONNAME3
+#define DUMMYUNIONNAME4
+#define DUMMYUNIONNAME5
+#define DUMMYUNIONNAME6
+#define DUMMYUNIONNAME7
+#define DUMMYUNIONNAME8
+#endif
+#ifndef _ANONYMOUS_STRUCT
+#define _ANONYMOUS_STRUCT
+#define _STRUCT_NAME(x) x
+#define DUMMYSTRUCTNAME s
+#define DUMMYSTRUCTNAME1 s1
+#define DUMMYSTRUCTNAME2 s2
+#define DUMMYSTRUCTNAME3 s3
+#define DUMMYSTRUCTNAME4 s4
+#define DUMMYSTRUCTNAME5 s5
+#else
+#define _STRUCT_NAME(x)
+#define DUMMYSTRUCTNAME
+#define DUMMYSTRUCTNAME1
+#define DUMMYSTRUCTNAME2
+#define DUMMYSTRUCTNAME3
+#define DUMMYSTRUCTNAME4
+#define DUMMYSTRUCTNAME5
+#endif
+#endif /* __ANONYMOUS_DEFINED */
+
+
#ifndef DECLSPEC_ALIGN
# if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(MIDL_PASS)
# define DECLSPEC_ALIGN(x) __declspec(align(x))
@@ -5259,12 +5315,24 @@ MemoryBarrier(VOID)
#endif
#if defined(_M_IX86)
+
#ifdef _MSC_VER
+#pragma intrinsic(__int2c)
#pragma intrinsic(_mm_pause)
#define YieldProcessor _mm_pause
#else
#define YieldProcessor() __asm__ __volatile__("pause");
+#define __int2c() __asm__ __volatile__("int $0x2c");
#endif
+
+
+FORCEINLINE
+VOID
+DbgRaiseAssertionFailure(VOID)
+{
+ __int2c();
+}
+
#elif defined (_M_AMD64)
#ifdef _MSC_VER
#pragma intrinsic(_mm_pause)
diff --git a/include/reactos/arm/armddk.h b/include/reactos/arm/armddk.h
index ad235b0b56b..97d7298b717 100644
--- a/include/reactos/arm/armddk.h
+++ b/include/reactos/arm/armddk.h
@@ -173,6 +173,12 @@ typedef struct _KPCR
ULONG StallScaleFactor;
UCHAR SpareUnused;
UCHAR Number;
+ UCHAR Spare0;
+ UCHAR SecondLevelCacheAssociativity;
+ ULONG VdmAlert;
+ ULONG KernelReserved[14];
+ ULONG SecondLevelCacheSize;
+ ULONG HalReserved[16];
} KPCR, *PKPCR;
//
@@ -246,6 +252,35 @@ KeRaiseIrqlToDpcLevel(
#define KeLowerIrql(NewIrql) KfLowerIrql(NewIrql)
#define KeRaiseIrql(NewIrql, OldIrql) *(OldIrql) = KfRaiseIrql(NewIrql)
+NTHALAPI
+KIRQL
+FASTCALL
+KfAcquireSpinLock(
+ IN OUT PKSPIN_LOCK SpinLock);
+#define KeAcquireSpinLock(a,b) *(b) = KfAcquireSpinLock(a)
+
+NTHALAPI
+VOID
+FASTCALL
+KfReleaseSpinLock(
+ IN OUT PKSPIN_LOCK SpinLock,
+ IN KIRQL NewIrql);
+#define KeReleaseSpinLock(a,b) KfReleaseSpinLock(a,b)
+
+NTKERNELAPI
+VOID
+FASTCALL
+KefAcquireSpinLockAtDpcLevel(
+ IN OUT PKSPIN_LOCK SpinLock);
+#define KeAcquireSpinLockAtDpcLevel(SpinLock) KefAcquireSpinLockAtDpcLevel(SpinLock)
+
+NTKERNELAPI
+VOID
+FASTCALL
+KefReleaseSpinLockFromDpcLevel(
+ IN OUT PKSPIN_LOCK SpinLock);
+#define KeReleaseSpinLockFromDpcLevel(SpinLock) KefReleaseSpinLockFromDpcLevel(SpinLock)
+
//
// Cache clean and flush
//
@@ -258,6 +293,26 @@ VOID
HalSweepIcache(
VOID
);
+
+FORCEINLINE
+VOID
+_KeQueryTickCount(
+ OUT PLARGE_INTEGER CurrentCount)
+{
+ for (;;) {
+#ifdef NONAMELESSUNION
+ CurrentCount->s.HighPart = KeTickCount.High1Time;
+ CurrentCount->s.LowPart = KeTickCount.LowPart;
+ if (CurrentCount->s.HighPart == KeTickCount.High2Time) break;
+#else
+ CurrentCount->HighPart = KeTickCount.High1Time;
+ CurrentCount->LowPart = KeTickCount.LowPart;
+ if (CurrentCount->HighPart == KeTickCount.High2Time) break;
+#endif
+ YieldProcessor();
+ }
+}
+#define KeQueryTickCount(CurrentCount) _KeQueryTickCount(CurrentCount)
#endif
//
diff --git a/include/reactos/asm.inc b/include/reactos/asm.inc
new file mode 100644
index 00000000000..4274221fc19
--- /dev/null
+++ b/include/reactos/asm.inc
@@ -0,0 +1,262 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/include/amd64/asmmacro.S
+ * PURPOSE: ASM macros for for GAS and MASM/ML64
+ * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#ifdef _USE_ML
+
+/* Allow ".name" identifiers */
+OPTION DOTNAME
+
+.686P
+.XMM
+.MODEL FLAT
+ASSUME CS:NOTHING, DS:NOTHING, ES:NOTHING, FS:NOTHING, GS:NOTHING
+
+/* Hex numbers need to be in 01ABh format */
+#define HEX(x) 0##x##h
+
+/* Macro values need to be marked */
+#define VAL(x) x
+
+/* MASM/ML doesn't want explicit [rip] addressing */
+rip = 0
+
+/* Due to MASM's reverse syntax, we are forced to use a precompiler macro */
+#define MACRO(name, ...) name MACRO __VA_ARGS__
+
+/* To avoid reverse syntax we provide a new macro .PROC, replacing PROC... */
+.PROC MACRO name
+ name PROC FRAME
+ _name:
+ENDM
+
+/* ... and .ENDP, replacing ENDP */
+.ENDP MACRO name
+ name ENDP
+ENDM
+
+/* MASM doesn't have an ASCII macro */
+.ASCII MACRO text
+ DB text
+ENDM
+
+/* MASM doesn't have an ASCIZ macro */
+.ASCIZ MACRO text
+ DB text, 0
+ENDM
+
+#define lgdt lgdt fword ptr ds:
+
+#define lidt lidt fword ptr ds:
+
+ljmp MACRO segment, offset
+ DB 0
+ENDM
+
+.code64 MACRO
+ .code
+ENDM
+
+.code32 MACRO
+ .code
+ .586P
+ENDM
+
+.code16 MACRO
+ ASSUME nothing
+ .text SEGMENT use16
+ENDM
+
+.endcode16 MACRO
+ .text ENDS
+ENDM
+
+.bss MACRO
+ .DATA?
+ ASSUME nothing
+ENDM
+
+//.text MACRO
+//ENDM
+
+.align MACRO alignment
+ ALIGN alignment
+ENDM
+
+.byte MACRO args:VARARG
+ db args
+ENDM
+
+.short MACRO args:VARARG
+ dw args
+ENDM
+
+.word MACRO args:VARARG
+ dw args
+ENDM
+
+.long MACRO args:VARARG
+ dd args
+ENDM
+
+.double MACRO args:VARARG
+ dq args
+ENDM
+
+.org MACRO value
+ ORG value
+ENDM
+
+.fill MACRO repeat, size, value
+// FIXME
+ENDM
+
+ljmp MACRO segment, offset
+// FIXME
+ENDM
+
+UNIMPLEMENTED MACRO name
+ENDM
+
+/* We need this to distinguish repeat from macros */
+#define ENDR ENDM
+
+#else /***********************************************************************/
+
+/* Force intel syntax */
+.intel_syntax noprefix
+
+.altmacro
+
+/* Hex numbers need to be in 0x1AB format */
+#define HEX(y) 0x##y
+
+/* Macro values need to be marked */
+#define VAL(x) \x
+
+/* Due to MASM's reverse syntax, we are forced to use a precompiler macro */
+#define MACRO(...) .macro __VA_ARGS__
+#define ENDM .endm
+
+/* To avoid reverse syntax we provide a new macro .PROC, replacing PROC... */
+.macro .PROC name
+ .func \name
+ \name:
+ .cfi_startproc
+ .equ cfa_current_offset, -8
+.endm
+
+/* ... and .ENDP, replacing ENDP */
+.macro .ENDP name
+ .cfi_endproc
+ .endfunc
+.endm
+
+/* MASM compatible PUBLIC */
+.macro PUBLIC symbol
+ .global \symbol
+.endm
+
+/* Dummy ASSUME */
+.macro ASSUME p1 p2 p3 p4 p5 p6 p7 p8
+.endm
+
+/* MASM needs an end tag for segments */
+.macro .endcode16
+.endm
+
+/* MASM compatible ALIGN */
+#define ALIGN .align
+
+/* MASM compatible REPEAT, additional ENDR */
+#define REPEAT .rept
+#define ENDR .endr
+
+.macro ljmp segment, offset
+ jmp far ptr \segment:\offset
+.endm
+
+/* MASM compatible EXTERN */
+.macro EXTERN name
+.endm
+
+/* MASM needs an END tag */
+#define END
+
+.macro .MODEL model
+.endm
+
+.macro .code
+ .text
+.endm
+
+/* Macros for x64 stack unwind OPs */
+
+.macro .allocstack size
+ .cfi_adjust_cfa_offset \size
+ .set cfa_current_offset, cfa_current_offset - \size
+.endm
+
+code = 1
+.macro .pushframe param=0
+ .if (\param)
+ .cfi_adjust_cfa_offset 0x30
+ .set cfa_current_offset, cfa_current_offset - 0x30
+ .else
+ .cfi_adjust_cfa_offset 0x28
+ .set cfa_current_offset, cfa_current_offset - 0x28
+ .endif
+.endm
+
+.macro .pushreg reg
+ .cfi_adjust_cfa_offset 8
+ .equ cfa_current_offset, cfa_current_offset - 8
+ .cfi_offset \reg, cfa_current_offset
+.endm
+
+.macro .savereg reg, offset
+ // checkme!!!
+ .cfi_offset \reg, \offset
+.endm
+
+.macro .savexmm128 reg, offset
+ // checkme!!!
+ .cfi_offset \reg, \offset
+.endm
+
+.macro .setframe reg, offset
+ .cfi_def_cfa reg, \offset
+ .equ cfa_current_offset, \offset
+.endm
+
+.macro .endprolog
+.endm
+
+.macro UNIMPLEMENTED2 file, line, func
+
+ jmp 3f
+1: .asciz "\func"
+2: .asciz \file
+3:
+ sub rsp, 0x20
+ lea rcx, MsgUnimplemented[rip]
+ lea rdx, 1b[rip]
+ lea r8, 2b[rip]
+ mov r9, \line
+ call DbgPrint
+ add rsp, 0x20
+.endm
+#define UNIMPLEMENTED UNIMPLEMENTED2 __FILE__, __LINE__,
+
+/* MASM/ML uses ".if" for runtime conditionals, and "if" for compile time
+ conditionals. We therefore use "if", too. .if shouldn't be used at all */
+#define if .if
+#define endif .endif
+#define else .else
+#define elseif .elseif
+
+#endif
diff --git a/include/reactos/ks386.inc b/include/reactos/ks386.inc
new file mode 100644
index 00000000000..a4272847a9f
--- /dev/null
+++ b/include/reactos/ks386.inc
@@ -0,0 +1,946 @@
+
+/* Pointer size */
+SizeofPointer = 0x4
+
+/* Breakpoints */
+BREAKPOINT_BREAK = 0x0
+BREAKPOINT_PRINT = 0x1
+BREAKPOINT_PROMPT = 0x2
+BREAKPOINT_LOAD_SYMBOLS = 0x3
+BREAKPOINT_UNLOAD_SYMBOLS = 0x4
+BREAKPOINT_COMMAND_STRING = 0x5
+
+/* Context Frame Flags */
+CONTEXT_FULL = 0x10007
+CONTEXT_CONTROL = 0x10001
+CONTEXT_INTEGER = 0x10002
+CONTEXT_SEGMENTS = 0x10004
+CONTEXT_FLOATING_POINT = 0x10008
+CONTEXT_DEBUG_REGISTERS = 0x10010
+
+/* Exception flags */
+EXCEPTION_NONCONTINUABLE = 0x1
+EXCEPTION_UNWINDING = 0x2
+EXCEPTION_EXIT_UNWIND = 0x4
+EXCEPTION_STACK_INVALID = 0x8
+EXCEPTION_NESTED_CALL = 0x10
+EXCEPTION_TARGET_UNWIND = 0x20
+EXCEPTION_COLLIDED_UNWIND = 0x20
+EXCEPTION_UNWIND = 0x6
+EXCEPTION_EXECUTE_HANDLER = 0x1
+EXCEPTION_CONTINUE_SEARCH = 0x0
+EXCEPTION_CONTINUE_EXECUTION = 0xffffffff
+EXCEPTION_CHAIN_END = 0xffffffff
+
+/* Exception types */
+ExceptionContinueExecution = 0x0
+ExceptionContinueSearch = 0x1
+ExceptionNestedException = 0x2
+ExceptionCollidedUnwind = 0x3
+
+/* Lock Queue */
+LOCK_QUEUE_WAIT = 0x1
+LOCK_QUEUE_OWNER = 0x2
+LockQueueDispatcherLock = 0x0
+
+/* Process states */
+ProcessInMemory = 0x0
+ProcessOutOfMemory = 0x1
+ProcessInTransition = 0x2
+
+/* Processor mode */
+KernelMode = 0x0
+UserMode = 0x1
+
+/* Status codes */
+STATUS_ACCESS_VIOLATION = 0xc0000005
+STATUS_ASSERTION_FAILURE = 0xc0000420
+STATUS_ARRAY_BOUNDS_EXCEEDED = 0xc000008c
+STATUS_BAD_COMPRESSION_BUFFER = 0xc0000242
+STATUS_BREAKPOINT = 0x80000003
+STATUS_CALLBACK_POP_STACK = 0xc0000423
+STATUS_DATATYPE_MISALIGNMENT = 0x80000002
+STATUS_FLOAT_DENORMAL_OPERAND = 0xc000008d
+STATUS_FLOAT_DIVIDE_BY_ZERO = 0xc000008e
+STATUS_FLOAT_INEXACT_RESULT = 0xc000008f
+STATUS_FLOAT_INVALID_OPERATION = 0xc0000090
+STATUS_FLOAT_OVERFLOW = 0xc0000091
+STATUS_FLOAT_STACK_CHECK = 0xc0000092
+STATUS_FLOAT_UNDERFLOW = 0xc0000093
+STATUS_FLOAT_MULTIPLE_FAULTS = 0xc00002b4
+STATUS_FLOAT_MULTIPLE_TRAPS = 0xc00002b5
+STATUS_GUARD_PAGE_VIOLATION = 0x80000001
+STATUS_ILLEGAL_FLOAT_CONTEXT = 0xc000014a
+STATUS_ILLEGAL_INSTRUCTION = 0xc000001d
+STATUS_INSTRUCTION_MISALIGNMENT = 0xc00000aa
+STATUS_INVALID_HANDLE = 0xc0000008
+STATUS_INVALID_LOCK_SEQUENCE = 0xc000001e
+STATUS_INVALID_OWNER = 0xc000005a
+STATUS_INVALID_PARAMETER = 0xc000000d
+STATUS_INVALID_PARAMETER_1 = 0xc00000ef
+STATUS_INVALID_SYSTEM_SERVICE = 0xc000001c
+STATUS_INTEGER_DIVIDE_BY_ZERO = 0xc0000094
+STATUS_INTEGER_OVERFLOW = 0xc0000095
+STATUS_IN_PAGE_ERROR = 0xc0000006
+STATUS_KERNEL_APC = 0x100
+STATUS_LONGJUMP = 0x80000026
+STATUS_NO_CALLBACK_ACTIVE = 0xc0000258
+STATUS_NO_EVENT_PAIR = 0xc000014e
+STATUS_PRIVILEGED_INSTRUCTION = 0xc0000096
+STATUS_SINGLE_STEP = 0x80000004
+STATUS_STACK_BUFFER_OVERRUN = 0xc0000409
+STATUS_STACK_OVERFLOW = 0xc00000fd
+STATUS_SUCCESS = 0x0
+STATUS_THREAD_IS_TERMINATING = 0xc000004b
+STATUS_TIMEOUT = 0x102
+STATUS_UNWIND = 0xc0000027
+STATUS_UNWIND_CONSOLIDATE = 0x80000029
+STATUS_USER_APC = 0xc0
+STATUS_WAKE_SYSTEM_DEBUGGER = 0x80000007
+
+/* TLS defines */
+TLS_MINIMUM_AVAILABLE = 0x40
+TLS_EXPANSION_SLOTS = 0x400
+
+/* Thread states */
+Initialized = 0x0
+Ready = 0x1
+Running = 0x2
+Standby = 0x3
+Terminated = 0x4
+Waiting = 0x5
+
+/* Wait type / reason */
+WrExecutive = 0x7
+WrMutex = 0x1d
+WrDispatchInt = 0x1f
+WrQuantumEnd = 0x1e
+WrEventPair = 0xe
+WaitAny = 0x1
+WaitAll = 0x0
+
+/* Interrupt object types */
+InLevelSensitive = 0x0
+InLatched = 0x1
+
+/* Bug Check Codes */
+APC_INDEX_MISMATCH = 0x1
+INVALID_AFFINITY_SET = 0x3
+INVALID_DATA_ACCESS_TRAP = 0x4
+IRQL_NOT_GREATER_OR_EQUAL = 0x9
+IRQL_NOT_LESS_OR_EQUAL = 0xa
+NO_USER_MODE_CONTEXT = 0xe
+SPIN_LOCK_ALREADY_OWNED = 0xf
+SPIN_LOCK_NOT_OWNED = 0x10
+THREAD_NOT_MUTEX_OWNER = 0x11
+TRAP_CAUSE_UNKNOWN = 0x12
+KMODE_EXCEPTION_NOT_HANDLED = 0x1e
+KERNEL_APC_PENDING_DURING_EXIT = 0x20
+PANIC_STACK_SWITCH = 0x2b
+DATA_BUS_ERROR = 0x2e
+INSTRUCTION_BUS_ERROR = 0x2f
+SYSTEM_EXIT_OWNED_MUTEX = 0x39
+PAGE_FAULT_WITH_INTERRUPTS_OFF = 0x49
+IRQL_GT_ZERO_AT_SYSTEM_SERVICE = 0x4a
+DATA_COHERENCY_EXCEPTION = 0x55
+INSTRUCTION_COHERENCY_EXCEPTION = 0x56
+HAL1_INITIALIZATION_FAILED = 0x61
+UNEXPECTED_KERNEL_MODE_TRAP = 0x7f
+NMI_HARDWARE_FAILURE = 0x80
+SPIN_LOCK_INIT_FAILURE = 0x81
+ATTEMPTED_SWITCH_FROM_DPC = 0xb8
+
+/* IRQL */
+PASSIVE_LEVEL = 0x0
+APC_LEVEL = 0x1
+DISPATCH_LEVEL = 0x2
+CLOCK1_LEVEL = 0x1c
+CLOCK2_LEVEL = 0x1c
+IPI_LEVEL = 0x1d
+POWER_LEVEL = 0x1e
+PROFILE_LEVEL = 0x1b
+HIGH_LEVEL = 0x1f
+#ifdef NT_UP
+SYNCH_LEVEL = 0x2
+#else
+SYNCH_LEVEL = 0x1b
+#endif
+
+/* Stack sizes */
+KERNEL_STACK_SIZE = 0x3000
+KERNEL_LARGE_STACK_SIZE = 0xf000
+KERNEL_LARGE_STACK_COMMIT = 0x3000
+
+/* Miscellaneous Definitions */
+LOW_REALTIME_PRIORITY = 0x10
+CLOCK_QUANTUM_DECREMENT = 0x3
+WAIT_QUANTUM_DECREMENT = 0x1
+MAXIMUM_PROCESSORS = 0x20
+INITIAL_STALL_COUNT = 0x64
+KI_EXCEPTION_ACCESS_VIOLATION = 0x10000004
+Executive = 0x0
+FALSE = 0x0
+TRUE = 0x1
+DBG_STATUS_CONTROL_C = 0x1
+USER_SHARED_DATA = 0x7ffe0000
+PAGE_SIZE = 0x1000
+MAXIMUM_IDTVECTOR = 0xff
+PRIMARY_VECTOR_BASE = 0x30
+RPL_MASK = 0x3
+MODE_MASK = 0x1
+NUMBER_SERVICE_TABLES = 0x2
+SERVICE_NUMBER_MASK = 0xfff
+SERVICE_TABLE_SHIFT = 0x8
+SERVICE_TABLE_MASK = 0x10
+SERVICE_TABLE_TEST = 0x10
+
+/* KAPC */
+ApType = 0x0
+ApSize = 0x2
+ApThread = 0x8
+ApApcListEntry = 0xc
+ApKernelRoutine = 0x14
+ApRundownRoutine = 0x18
+ApNormalRoutine = 0x1c
+ApNormalContext = 0x20
+ApSystemArgument1 = 0x24
+ApSystemArgument2 = 0x28
+ApApcStateIndex = 0x2c
+ApApcMode = 0x2d
+ApInserted = 0x2e
+ApcObjectLength = 0x30
+
+/* KAPC_STATE */
+AsApcListHead = 0x0
+AsProcess = 0x10
+AsKernelApcInProgress = 0x14
+AsKernelApcPending = 0x15
+AsUserApcPending = 0x16
+
+/* CLIENT_ID */
+CidUniqueProcess = 0x0
+CidUniqueThread = 0x4
+
+/* RTL_CRITICAL_SECTION */
+CsDebugInfo = 0x0
+CsLockCount = 0x4
+CsRecursionCount = 0x8
+CsOwningThread = 0xc
+CsLockSemaphore = 0x10
+CsSpinCount = 0x14
+
+/* RTL_CRITICAL_SECTION_DEBUG */
+CsType = 0x0
+CsCreatorBackTraceIndex = 0x2
+CsCriticalSection = 0x4
+CsProcessLocksList = 0x8
+CsEntryCount = 0x10
+CsContentionCount = 0x14
+
+/* KDEVICE_QUEUE_ENTRY */
+DeDeviceListEntry = 0x0
+DeSortKey = 0x8
+DeInserted = 0xc
+DeviceQueueEntryLength = 0x10
+
+/* KDPC */
+DpType = 0x0
+DpImportance = 0x1
+DpNumber = 0x2
+DpDpcListEntry = 0x4
+DpDeferredRoutine = 0xc
+DpDeferredContext = 0x10
+DpSystemArgument1 = 0x14
+DpSystemArgument2 = 0x18
+DpDpcData = 0x1c
+DpcObjectLength = 0x20
+
+/* KDEVICE_QUEUE */
+DvType = 0x0
+DvSize = 0x2
+DvDeviceListHead = 0x4
+DvSpinLock = 0xc
+DvBusy = 0x10
+DeviceQueueObjectLength = 0x14
+
+/* EXCEPTION_RECORD */
+ErExceptionCode = 0x0
+ErExceptionFlags = 0x4
+ErExceptionRecord = 0x8
+ErExceptionAddress = 0xc
+ErNumberParameters = 0x10
+ErExceptionInformation = 0x14
+ExceptionRecordLength = 0x50
+EXCEPTION_RECORD_LENGTH = 0x50
+
+/* EPROCESS */
+EpDebugPort = 0xcc
+EpVdmObjects = 0x144
+ExecutiveProcessObjectLength = 0x278
+
+/* KEVENT */
+EvType = 0x0
+EvSize = 0x2
+EvSignalState = 0x4
+EvWaitListHead = 0x8
+EventObjectLength = 0x10
+
+/* FAST_MUTEX */
+FmCount = 0x0
+FmOwner = 0x4
+FmContention = 0x8
+FmOldIrql = 0x1c
+
+/* KINTERRUPT */
+InType = 0x0
+InSize = 0x2
+InInterruptListEntry = 0x4
+InServiceRoutine = 0xc
+InServiceContext = 0x10
+InSpinLock = 0x14
+InTickCount = 0x18
+InActualLock = 0x1c
+InDispatchAddress = 0x20
+InVector = 0x24
+InIrql = 0x28
+InSynchronizeIrql = 0x29
+InFloatingSave = 0x2a
+InConnected = 0x2b
+InNumber = 0x2c
+InShareVector = 0x2d
+InMode = 0x30
+InServiceCount = 0x34
+InDispatchCount = 0x38
+InDispatchCode = 0x3c
+InterruptObjectLength = 0x1e4
+
+/* IO_STATUS_BLOCK */
+IoStatus = 0x0
+IoPointer = 0x0
+IoInformation = 0x4
+
+/* KNODE */
+KnPfnDereferenceSListHead = 0x8
+KnProcessorMask = 0x10
+KnColor = 0x14
+KnSeed = 0x18
+KnNodeNumber = 0x19
+KnFlags = 0x1a
+knMmShiftedColor = 0x1e
+KnFreeCount = 0x22
+KnPfnDeferredList = 0x2a
+KNODE_SIZE = 0x2e
+
+/* KSPIN_LOCK_QUEUE */
+LqNext = 0x0
+LqLock = 0x4
+
+/* KLOCK_QUEUE_HANDLE */
+LqhNext = 0x0
+LqhLock = 0x4
+LqhOldIrql = 0x8
+LOCK_QUEUE_HEADER_SIZE = 0xc
+
+/* LARGE_INTEGER */
+LiLowPart = 0x0
+LiHighPart = 0x4
+
+/* LIST_ENTRY */
+LsFlink = 0x0
+LsBlink = 0x4
+
+/* PEB */
+PeKernelCallbackTable = 0x2c
+ProcessEnvironmentBlockLength = 0x230
+
+/* KPROFILE */
+PfType = 0x0
+PfSize = 0x2
+PfProfileListEntry = 0x4
+PfProcess = 0xc
+PfRangeBase = 0x10
+PfRangeLimit = 0x14
+PfBucketShift = 0x18
+PfBuffer = 0x1c
+PfSegment = 0x20
+PfAffinity = 0x24
+PfSource = 0x28
+PfStarted = 0x2c
+ProfileObjectLength = 0x30
+
+/* PORT_MESSAGE */
+PmLength = 0x0
+PmZeroInit = 0x4
+PmClientId = 0x8
+PmProcess = 0x8
+PmThread = 0xc
+PmMessageId = 0x10
+PmClientViewSize = 0x14
+PortMessageLength = 0x18
+
+/* KPROCESS */
+PrType = 0x0
+PrSize = 0x2
+PrSignalState = 0x4
+PrProfileListHead = 0x10
+PrDirectoryTableBase = 0x18
+PrLdtDescriptor = 0x20
+PrIopmOffset = 0x30
+PrInt21Descriptor = 0x28
+PrVdmTrapcHandler = 0x4c
+PrFlags = 0x6b
+PrActiveProcessors = 0x34
+PrKernelTime = 0x38
+PrUserTime = 0x3c
+PrReadyListHead = 0x40
+PrSwapListEntry = 0x48
+PrThreadListHead = 0x50
+PrProcessLock = 0x58
+PrAffinity = 0x5c
+PrProcessFlags = 0x60
+PrBasePriority = 0x64
+PrQuantumReset = 0x65
+PrState = 0x66
+PrStackCount = 0x6c
+KernelProcessObjectLength = 0x78
+
+/* KQUEUE */
+QuType = 0x0
+QuSize = 0x2
+QuSignalState = 0x4
+QuEntryListHead = 0x10
+QuCurrentCount = 0x18
+QuMaximumCount = 0x1c
+QuThreadListHead = 0x20
+QueueObjectLength = 0x28
+
+/* STRING */
+StrLength = 0x0
+StrMaximumLength = 0x2
+StrBuffer = 0x4
+
+/* TEB */
+TeCmTeb = 0x0
+TeExceptionList = 0x0
+TeStackBase = 0x4
+TeStackLimit = 0x8
+TeFiberData = 0x10
+TeSelf = 0x18
+TeEnvironmentPointer = 0x1c
+TeClientId = 0x20
+TeActiveRpcHandle = 0x28
+TeThreadLocalStoragePointer = 0x2c
+TeCountOfOwnedCriticalSections = 0x38
+TePeb = 0x30
+TeCsrClientThread = 0x3c
+TeWOW32Reserved = 0xc0
+TeExceptionCode = 0x1a4
+TeActivationContextStackPointer = 0x1a8
+TeGdiClientPID = 0x6c0
+TeGdiClientTID = 0x6c4
+TeGdiThreadLocalInfo = 0x6c8
+TeglDispatchTable = 0x7c4
+TeglReserved1 = 0xb68
+TeglReserved2 = 0xbdc
+TeglSectionInfo = 0xbe0
+TeglSection = 0xbe4
+TeglTable = 0xbe8
+TeglCurrentRC = 0xbec
+TeglContext = 0xbf0
+TeDeallocationStack = 0xe0c
+TeTlsSlots = 0xe10
+TeTlsExpansionSlots = 0xf94
+TeLastErrorValue = 0x34
+TeVdm = 0xf18
+TeInstrumentation = 0xf2c
+TeGdiBatchCount = 0xf70
+TeGuaranteedStackBytes = 0xf78
+TeFlsData = 0xfb4
+ThreadEnvironmentBlockLength = 0xfbc
+
+/* TIME_FIELDS */
+TfSecond = 0xa
+TfMinute = 0x8
+TfHour = 0x6
+TfWeekday = 0xe
+TfDay = 0x4
+TfMonth = 0x2
+TfYear = 0x0
+TfMilliseconds = 0xc
+
+/* KTHREAD */
+ThType = 0x0
+ThSize = 0x2
+ThLock = 0x0
+ThDebugActive = 0x3
+ThSignalState = 0x4
+ThInitialStack = 0x18
+ThStackLimit = 0x1c
+ThKernelStack = 0x20
+ThThreadLock = 0x24
+ThAlerted = 0x5e
+ThApcState = 0x28
+ThPriority = 0x5b
+ThSwapBusy = 0x5d
+ThNextProcessor = 0x40
+ThDeferredProcessor = 0x41
+ThApcQueueLock = 0x44
+ThContextSwitches = 0x48
+ThState = 0x4c
+ThNpxState = 0x4d
+ThWaitIrql = 0x4e
+ThWaitMode = 0x4f
+ThWaitStatus = 0x50
+ThWaitBlockList = 0x54
+ThGateObject = 0x54
+ThWaitListEntry = 0x60
+ThSwapListEntry = 0x60
+ThQueue = 0x68
+ThWaitTime = 0x6c
+ThCombinedApcDisable = 0x70
+ThKernelApcDisable = 0x70
+ThSpecialApcDisable = 0x72
+ThTeb = 0x74
+ThTimer = 0x78
+ThThreadFlags = 0xa0
+ThServiceTable = 0x118
+ThWaitBlock = 0xa8
+ThResourceIndex = 0xef
+ThQueueListEntry = 0x108
+ThTrapFrame = 0x110
+ThCallbackStack = 0x114
+ThApcStateIndex = 0x11c
+ThIdealProcessor = 0x11d
+ThBasePriority = 0x121
+ThPriorityDecrement = 0x122
+ThAdjustReason = 0x42
+ThAdjustIncrement = 0x43
+ThPreviousMode = 0xd7
+ThSaturation = 0x123
+ThFreezeCount = 0x14f
+ThUserAffinity = 0x124
+ThProcess = 0x128
+ThAffinity = 0x12c
+ThUserIdealProcessor = 0x151
+ThApcStatePointer = 0x130
+ThSavedApcState = 0x138
+ThWaitReason = 0x5a
+ThSuspendCount = 0x150
+ThWin32Thread = 0x154
+ThStackBase = 0x158
+ThSuspendApc = 0x15c
+ThPowerState = 0x18b
+ThKernelTime = 0x160
+ThLegoData = 0x184
+ThLargeStack = 0x107
+ThUserTime = 0x18c
+ThSuspendSemaphore = 0x190
+ThSListFaultCount = 0x1a4
+ThThreadListEntry = 0x1a8
+ThMutantListHead = 0x10
+ThSListFaultAddress = 0x1b0
+KernelThreadObjectLength = 0x1b8
+ExecutiveThreadObjectLength = 0x250
+
+/* KTIMER */
+TiType = 0x0
+TiSize = 0x2
+TiInserted = 0x3
+TiSignalState = 0x4
+TiDueTime = 0x10
+TiTimerListEntry = 0x18
+TiDpc = 0x20
+TiPeriod = 0x24
+TimerObjectLength = 0x28
+
+/* TIME */
+
+/* KUSER_SHARED_DATA */
+UsTickCountMultiplier = 0x4
+UsInterruptTime = 0x8
+UsSystemTime = 0x14
+UsTimeZoneBias = 0x20
+UsImageNumberLow = 0x2c
+UsImageNumberHigh = 0x2e
+UsNtSystemRoot = 0x30
+UsMaxStackTraceDepth = 0x238
+UsCryptoExponent = 0x23c
+UsTimeZoneId = 0x240
+UsLargePageMinimum = 0x244
+UsReserved2 = 0x248
+UsNtProductType = 0x264
+UsProductTypeIsValid = 0x268
+UsNtMajorVersion = 0x26c
+UsNtMinorVersion = 0x270
+UsProcessorFeatures = 0x274
+UsReserved1 = 0x2b4
+UsReserved3 = 0x2b8
+UsTimeSlip = 0x2bc
+UsAlternativeArchitecture = 0x2c0
+UsSystemExpirationDate = 0x2c8
+UsSuiteMask = 0x2d0
+UsKdDebuggerEnabled = 0x2d4
+UsActiveConsoleId = 0x2d8
+UsDismountCount = 0x2dc
+UsComPlusPackage = 0x2e0
+UsLastSystemRITEventTickCount = 0x2e4
+UsNumberOfPhysicalPages = 0x2e8
+UsSafeBootMode = 0x2ec
+UsTestRetInstruction = 0x2f8
+UsSystemCall = 0x300
+UsSystemCallReturn = 0x304
+UsSystemCallPad = 0x308
+UsTickCount = 0x320
+UsTickCountQuad = 0x320
+UsWow64SharedInformation = 0x340
+
+/* KWAIT_BLOCK */
+WbWaitListEntry = 0x0
+WbThread = 0x8
+WbObject = 0xc
+WbNextWaitBlock = 0x10
+WbWaitKey = 0x14
+WbWaitType = 0x16
+
+/* CR0 flags */
+CR0_PE = 0x1
+CR0_MP = 0x2
+CR0_EM = 0x4
+CR0_TS = 0x8
+CR0_ET = 0x10
+CR0_NE = 0x20
+CR0_WP = 0x10000
+CR0_AM = 0x40000
+CR0_NW = 0x20000000
+CR0_CD = 0x40000000
+CR0_PG = 0x80000000
+
+/* CR4 flags */
+CR4_VME = 0x1
+CR4_PVI = 0x2
+CR4_TSD = 0x4
+CR4_DE = 0x8
+CR4_PSE = 0x10
+CR4_PAE = 0x20
+CR4_MCE = 0x40
+CR4_PGE = 0x80
+CR4_FXSR = 0x200
+CR4_XMMEXCPT = 0x400
+
+/* KeFeatureBits flags */
+KF_RDTSC = 0x2
+KF_CR4 = 0x4
+KF_GLOBAL_PAGE = 0x10
+KF_LARGE_PAGE = 0x20
+KF_CMPXCHG8B = 0x80
+KF_FAST_SYSCALL = 0x1000
+KF_V86_VIS = 0x1
+
+/* Machine type definitions */
+MACHINE_TYPE_ISA = 0x0
+MACHINE_TYPE_EISA = 0x1
+MACHINE_TYPE_MCA = 0x2
+
+/* EFLAGS */
+EFLAGS_TF = 0x100
+EFLAGS_INTERRUPT_MASK = 0x200
+EFLAGS_V86_MASK = 0x20000
+EFLAGS_ALIGN_CHECK = 0x40000
+EFLAGS_VIF = 0x80000
+EFLAGS_VIP = 0x100000
+EFLAGS_USER_SANITIZE = 0x3f4dd7
+
+/* KDGT selectors */
+KGDT_R3_DATA = 0x20
+KGDT_R3_CODE = 0x18
+KGDT_R0_CODE = 0x8
+KGDT_R0_DATA = 0x10
+KGDT_R0_PCR = 0x30
+KGDT_TSS = 0x28
+KGDT_R3_TEB = 0x38
+KGDT_DF_TSS = 0x50
+KGDT_NMI_TSS = 0x58
+KGDT_LDT = 0x48
+NPX_STATE_NOT_LOADED = 0xa
+NPX_STATE_LOADED = 0x0
+PF_XMMI_INSTRUCTIONS_AVAILABLE = 0x6
+EFLAG_SELECT = 0xc000
+
+/* CONTEXT */
+CsContextFlags = 0x0
+CsDr0 = 0x4
+CsDr1 = 0x8
+CsDr2 = 0xc
+CsDr3 = 0x10
+CsDr6 = 0x14
+CsDr7 = 0x18
+CsFloatSave = 0x1c
+CsSegGs = 0x8c
+CsSegFs = 0x90
+CsSegEs = 0x94
+CsSegDs = 0x98
+CsEdi = 0x9c
+CsEsi = 0xa0
+CsEbx = 0xa4
+CsEdx = 0xa8
+CsEcx = 0xac
+CsEax = 0xb0
+CsEbp = 0xb4
+CsEip = 0xb8
+CsSegCs = 0xbc
+CsEflags = 0xc0
+CsEsp = 0xc4
+CsSegSs = 0xc8
+CsExtendedRegisters = 0xcc
+ContextFrameLength = 0x2cc
+CONTEXT_LENGTH = 0x2cc
+
+/* KGDTENTRY */
+KgdtBaseLow = 0x2
+KgdtBaseMid = 0x4
+KgdtBaseHi = 0x7
+KgdtLimitHi = 0x6
+KgdtLimitLow = 0x0
+
+/* KTRAP_FRAME */
+TsExceptionList = 0x4c
+TsPreviousPreviousMode = 0x48
+TsSegGs = 0x30
+TsSegFs = 0x50
+TsSegEs = 0x34
+TsSegDs = 0x38
+TsEdi = 0x54
+TsEsi = 0x58
+TsEbp = 0x60
+TsEbx = 0x5c
+TsEdx = 0x3c
+TsEcx = 0x40
+TsEax = 0x44
+TsErrCode = 0x64
+TsEip = 0x68
+TsSegCs = 0x6c
+TsEflags = 0x70
+TsHardwareEsp = 0x74
+TsHardwareSegSs = 0x78
+TsTempSegCs = 0x10
+TsTempEsp = 0x14
+TsDbgEbp = 0x0
+TsDbgEip = 0x4
+TsDbgArgMark = 0x8
+TsDbgArgPointer = 0xc
+TsDr0 = 0x18
+TsDr1 = 0x1c
+TsDr2 = 0x20
+TsDr3 = 0x24
+TsDr6 = 0x28
+TsDr7 = 0x2c
+TsV86Es = 0x7c
+TsV86Ds = 0x80
+TsV86Fs = 0x84
+TsV86Gs = 0x88
+KTRAP_FRAME_LENGTH = 0x8c
+KTRAP_FRAME_ALIGN = 0x4
+FRAME_EDITED = 0xfff8
+
+/* KTSS */
+TssEsp0 = 0x4
+TssCR3 = 0x1c
+TssEip = 0x20
+TssEFlags = 0x24
+TssEax = 0x28
+TssEbx = 0x34
+TssEcx = 0x2c
+TssEdx = 0x30
+TssEsp = 0x38
+TssEbp = 0x3c
+TssEsi = 0x40
+TssEdi = 0x44
+TssEs = 0x48
+TssCs = 0x4c
+TssSs = 0x50
+TssDs = 0x54
+TssFs = 0x58
+TssGs = 0x5c
+TssLDT = 0x60
+TssIoMapBase = 0x66
+TssIoMaps = 0x68
+TssLength = 0x20ac
+
+/* KPCR */
+KPCR_EXCEPTION_LIST = 0x0
+KPCR_PERF_GLOBAL_GROUP_MASK = 0x8
+KPCR_CONTEXT_SWITCHES = 0x10
+KPCR_TEB = 0x18
+KPCR_SELF = 0x1c
+KPCR_PRCB = 0x20
+KPCR_IDT = 0x38
+KPCR_GDT = 0x3c
+KPCR_TSS = 0x40
+KPCR_STALL_SCALE_FACTOR = 0x4c
+KPCR_PRCB_DATA = 0x120
+KPCR_CURRENT_THREAD = 0x124
+KPCR_PRCB_NEXT_THREAD = 0x128
+KPCR_PRCB_DPC_QUEUE_DEPTH = 0xa4c
+KPCR_PRCB_DPC_STACK = 0xa68
+KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH = 0xa6c
+KPCR_PRCB_DPC_ROUTINE_ACTIVE = 0xa7a
+KPCR_PRCB_TIMER_REQUEST = 0xa88
+KPCR_PRCB_QUANTUM_END = 0xaa1
+KPCR_PRCB_DEFERRED_READY_LIST_HEAD = 0xc10
+KPCR_PRCB_POWER_STATE_IDLE_FUNCTION = 0xec0
+
+/* KTRAP_FRAME */
+KTRAP_FRAME_DEBUGEBP = 0x0
+KTRAP_FRAME_DEBUGEIP = 0x4
+KTRAP_FRAME_TEMPESP = 0x14
+KTRAP_FRAME_DR0 = 0x18
+KTRAP_FRAME_DR1 = 0x1c
+KTRAP_FRAME_DR2 = 0x20
+KTRAP_FRAME_DR3 = 0x24
+KTRAP_FRAME_DR6 = 0x28
+KTRAP_FRAME_DR7 = 0x2c
+KTRAP_FRAME_GS = 0x30
+KTRAP_FRAME_ES = 0x34
+KTRAP_FRAME_DS = 0x38
+KTRAP_FRAME_EDX = 0x3c
+KTRAP_FRAME_ECX = 0x40
+KTRAP_FRAME_EAX = 0x44
+KTRAP_FRAME_PREVIOUS_MODE = 0x48
+KTRAP_FRAME_EXCEPTION_LIST = 0x4c
+KTRAP_FRAME_FS = 0x50
+KTRAP_FRAME_EDI = 0x54
+KTRAP_FRAME_ESI = 0x58
+KTRAP_FRAME_EBX = 0x5c
+KTRAP_FRAME_EBP = 0x60
+KTRAP_FRAME_ERROR_CODE = 0x64
+KTRAP_FRAME_EIP = 0x68
+KTRAP_FRAME_EFLAGS = 0x70
+KTRAP_FRAME_ESP = 0x74
+KTRAP_FRAME_SS = 0x78
+KTRAP_FRAME_V86_ES = 0x7c
+KTRAP_FRAME_V86_DS = 0x80
+KTRAP_FRAME_V86_FS = 0x84
+KTRAP_FRAME_V86_GS = 0x88
+KTRAP_FRAME_SIZE = 0x8c
+FRAME_EDITED = 0xfff8
+
+/* CONTEXT */
+CONTEXT_FLAGS = 0x0
+CONTEXT_SEGGS = 0x8c
+CONTEXT_SEGFS = 0x90
+CONTEXT_SEGES = 0x94
+CONTEXT_SEGDS = 0x98
+CONTEXT_EDI = 0x9c
+CONTEXT_ESI = 0xa0
+CONTEXT_EBX = 0xa4
+CONTEXT_EDX = 0xa8
+CONTEXT_ECX = 0xac
+CONTEXT_EAX = 0xb0
+CONTEXT_EBP = 0xb4
+CONTEXT_EIP = 0xb8
+CONTEXT_SEGCS = 0xbc
+CONTEXT_EFLAGS = 0xc0
+CONTEXT_ESP = 0xc4
+CONTEXT_SEGSS = 0xc8
+CONTEXT_FRAME_LENGTH = 0x2cc
+
+/* FIBER */
+FIBER_PARAMETER = 0x0
+FIBER_EXCEPTION_LIST = 0x4
+FIBER_STACK_BASE = 0x8
+FIBER_STACK_LIMIT = 0xc
+FIBER_DEALLOCATION_STACK = 0x10
+FIBER_CONTEXT = 0x14
+FIBER_CONTEXT_FLAGS = 0x14
+FIBER_CONTEXT_EAX = 0xc4
+FIBER_CONTEXT_EBX = 0xb8
+FIBER_CONTEXT_ECX = 0xc0
+FIBER_CONTEXT_EDX = 0xbc
+FIBER_CONTEXT_ESI = 0xb4
+FIBER_CONTEXT_EDI = 0xb0
+FIBER_CONTEXT_EBP = 0xc8
+FIBER_CONTEXT_EIP = 0xcc
+FIBER_CONTEXT_ESP = 0xd8
+FIBER_CONTEXT_DR6 = 0x28
+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD = 0x30
+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD = 0x34
+FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD = 0x38
+FIBER_GUARANTEED_STACK_BYTES = 0x2e0
+FIBER_FLS_DATA = 0x2e4
+FIBER_ACTIVATION_CONTEXT_STACK = 0x2e8
+
+/* KTSS */
+KTSS_IOMAPBASE = 0x66
+KTSS_ESP0 = 0x4
+
+/* EXCEPTION_RECORD */
+EXCEPTION_RECORD_EXCEPTION_CODE = 0x0
+EXCEPTION_RECORD_EXCEPTION_FLAGS = 0x4
+EXCEPTION_RECORD_EXCEPTION_RECORD = 0x8
+EXCEPTION_RECORD_EXCEPTION_ADDRESS = 0xc
+EXCEPTION_RECORD_NUMBER_PARAMETERS = 0x10
+EXCEPTION_RECORD_EXCEPTION_ADDRESS = 0xc
+SIZEOF_EXCEPTION_RECORD = 0x50
+EXCEPTION_RECORD_LENGTH = 0x50
+
+/* KTHREAD */
+KTHREAD_DEBUG_ACTIVE = 0x3
+KTHREAD_INITIAL_STACK = 0x18
+KTHREAD_STACK_LIMIT = 0x1c
+KTHREAD_TEB = 0x74
+KTHREAD_KERNEL_STACK = 0x20
+KTHREAD_APCSTATE_PROCESS = 0x38
+KTHREAD_PENDING_KERNEL_APC = 0x3d
+KTHREAD_CONTEXT_SWITCHES = 0x48
+KTHREAD_STATE_ = 0x4c
+KTHREAD_NPX_STATE = 0x4d
+KTHREAD_WAIT_IRQL = 0x4e
+KTHREAD_WAIT_REASON = 0x5a
+KTHREAD_COMBINED_APC_DISABLE = 0x70
+KTHREAD_SPECIAL_APC_DISABLE = 0x72
+KTHREAD_LARGE_STACK = 0x107
+KTHREAD_TRAP_FRAME = 0x110
+KTHREAD_CALLBACK_STACK = 0x114
+KTHREAD_APC_STATE_INDEX = 0x11c
+KTHREAD_STACK_BASE = 0x158
+
+/* KPROCESS */
+KPROCESS_DIRECTORY_TABLE_BASE = 0x18
+KPROCESS_LDT_DESCRIPTOR0 = 0x20
+KPROCESS_LDT_DESCRIPTOR1 = 0x24
+KPROCESS_INT21_DESCRIPTOR0 = 0x28
+KPROCESS_INT21_DESCRIPTOR1 = 0x2c
+KPROCESS_IOPM_OFFSET = 0x30
+
+/* Teb */
+TEB_EXCEPTION_LIST = 0x0
+TEB_STACK_LIMIT = 0x8
+TEB_STACK_BASE = 0x4
+TEB_SELF = 0x18
+TEB_FIBER_DATA = 0x10
+TEB_PEB = 0x30
+TEB_EXCEPTION_CODE = 0x1a4
+PEB_KERNEL_CALLBACK_TABLE = 0x2c
+TEB_FLS_DATA = 0xfb4
+TEB_ACTIVATION_CONTEXT_STACK_POINTER = 0x1a8
+TEB_GUARANTEED_STACK_BYTES = 0xf78
+TEB_DEALLOCATION_STACK = 0xe0c
+
+/* Misc */
+NPX_FRAME_LENGTH = 0x210
+FN_CR0_NPX_STATE = 0x20c
+DR7_RESERVED_MASK = 0xdc00
+FP_CONTROL_WORD = 0x0
+FP_STATUS_WORD = 0x4
+FP_TAG_WORD = 0x8
+FP_DATA_SELECTOR = 0x18
+CBSTACK_RESULT = 0x20
+CBSTACK_RESULT_LENGTH = 0x24
+CBSTACK_TRAP_FRAME = 0x4
+CBSTACK_CALLBACK_STACK = 0x8
+SIZEOF_FX_SAVE_AREA = 0x210
+KUSER_SHARED_SYSCALL = 0x7ffe0300
+EXCEPTION_EXECUTE_HANDLER = 0x1
+STATUS_CALLBACK_POP_STACK = 0xc0000423
+CONTEXT_ALIGNED_SIZE = 0x2cc
+PROCESSOR_FEATURE_FXSR = 0x7ffe0278
diff --git a/include/reactos/win32k/ntuser.h b/include/reactos/win32k/ntuser.h
index 920e4e1abff..5c4a335ec9f 100644
--- a/include/reactos/win32k/ntuser.h
+++ b/include/reactos/win32k/ntuser.h
@@ -51,13 +51,15 @@ VOID NTAPI RtlInitLargeAnsiString(IN OUT PLARGE_ANSI_STRING,IN PCSZ,IN INT);
VOID NTAPI RtlInitLargeUnicodeString(IN OUT PLARGE_UNICODE_STRING,IN PCWSTR,IN INT);
BOOL NTAPI RtlLargeStringToUnicodeString( PUNICODE_STRING, PLARGE_STRING);
+#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
+
typedef struct _DESKTOPINFO
{
PVOID pvDesktopBase;
PVOID pvDesktopLimit;
struct _WND *spwnd;
DWORD fsHooks;
- struct tagHOOK * aphkStart[16];
+ LIST_ENTRY aphkStart[NB_HOOKS];
HWND hTaskManWindow;
HWND hProgmanWindow;
@@ -127,15 +129,23 @@ typedef struct _PROCMARKHEAD
/* Window Client Information structure */
struct _ETHREAD;
+#define WEF_SETBYWNDPTI 0x0001
+
typedef struct tagHOOK
{
THRDESKHEAD head;
+ struct tagHOOK *phkNext; /* This is for user space. */
+ int HookId; /* Hook table index */
+ ULONG_PTR offPfn;
+ ULONG flags; /* Some internal flags */
+ INT ihmod;
+ PTHREADINFO ptiHooked;
+ struct _DESKTOP *rpdesk;
+ /* ReactOS */
LIST_ENTRY Chain; /* Hook chain entry */
struct _ETHREAD* Thread; /* Thread owning the hook */
- int HookId; /* Hook table index */
HOOKPROC Proc; /* Hook function */
BOOLEAN Ansi; /* Is it an Ansi hook? */
- ULONG Flags; /* Some internal flags */
UNICODE_STRING ModuleName; /* Module name for global hooks */
} HOOK, *PHOOK;
@@ -3149,10 +3159,8 @@ typedef struct tagKMDDELPARAM
#define NOPARAM_ROUTINE_ANYPOPUP 0xffff0006
#define ONEPARAM_ROUTINE_CSRSS_GUICHECK 0xffff0008
#define ONEPARAM_ROUTINE_SWITCHCARETSHOWING 0xfffe0008
-#define ONEPARAM_ROUTINE_ISWINDOWINDESTROY 0xfffe000c
#define ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING 0xfffe000d
#define ONEPARAM_ROUTINE_GETDESKTOPMAPPING 0xfffe000e
-#define ONEPARAM_ROUTINE_MSQSETWAKEMASK 0xfffe0027
#define ONEPARAM_ROUTINE_GETCURSORPOSITION 0xfffe0048 // use ONEPARAM_ or TWOPARAM routine ?
#define TWOPARAM_ROUTINE_GETWINDOWRGNBOX 0xfffd0048 // user mode
#define TWOPARAM_ROUTINE_GETWINDOWRGN 0xfffd0049 // user mode
@@ -3167,6 +3175,7 @@ typedef struct tagKMDDELPARAM
#define TWOPARAM_ROUTINE_SETCARETPOS 0xfffd0060
#define TWOPARAM_ROUTINE_REGISTERLOGONPROC 0xfffd0062
#define TWOPARAM_ROUTINE_ROS_UPDATEUISTATE 0x1004
+#define HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT 0x1005
DWORD
NTAPI
diff --git a/include/reactos/wine/exception.h b/include/reactos/wine/exception.h
index 17ba84c0909..c2f23fb9d2b 100644
--- a/include/reactos/wine/exception.h
+++ b/include/reactos/wine/exception.h
@@ -83,7 +83,7 @@ static inline EXCEPTION_REGISTRATION_RECORD *__wine_push_frame( EXCEPTION_REGIST
#else
NT_TIB *teb = (NT_TIB *)NtCurrentTeb();
frame->Prev = teb->ExceptionList;
- teb->ExceptionList = frame;
+ teb->ExceptionList = (PVOID)frame;
return frame->Prev;
#endif
}
@@ -96,7 +96,7 @@ static inline EXCEPTION_REGISTRATION_RECORD *__wine_pop_frame( EXCEPTION_REGISTR
#else
NT_TIB *teb = (NT_TIB *)NtCurrentTeb();
frame->Prev = teb->ExceptionList;
- teb->ExceptionList = frame;
+ teb->ExceptionList = (PVOID)frame;
return frame->Prev;
#endif
}
diff --git a/lib/atl/atlcore.h b/lib/atl/atlcore.h
index c2f22eacfdf..08e19d41382 100644
--- a/lib/atl/atlcore.h
+++ b/lib/atl/atlcore.h
@@ -43,7 +43,7 @@ public:
memset(&m_sec, 0, sizeof(CRITICAL_SECTION));
}
- ~CComCriticalSection()
+ virtual ~CComCriticalSection()
{
}
diff --git a/lib/drivers/sound/mmixer/mixer.c b/lib/drivers/sound/mmixer/mixer.c
index b04b50c702f..b4b7dcfad2c 100644
--- a/lib/drivers/sound/mmixer/mixer.c
+++ b/lib/drivers/sound/mmixer/mixer.c
@@ -89,6 +89,7 @@ MMixerOpen(
if (Status != MM_STATUS_SUCCESS)
{
/* invalid context passed */
+ DPRINT1("invalid context\n");
return Status;
}
@@ -97,6 +98,7 @@ MMixerOpen(
if (!MixerInfo)
{
/* invalid mixer id */
+ DPRINT1("invalid mixer id %lu\n", MixerId);
return MM_STATUS_INVALID_PARAMETER;
}
diff --git a/lib/rtl/amd64/debug_asm.S b/lib/rtl/amd64/debug_asm.S
index c115feb12fc..ca09236c566 100644
--- a/lib/rtl/amd64/debug_asm.S
+++ b/lib/rtl/amd64/debug_asm.S
@@ -6,7 +6,7 @@
* PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
-#include
+#include
/* GLOBALS ****************************************************************/
diff --git a/lib/rtl/amd64/except_asm.S b/lib/rtl/amd64/except_asm.S
index a4b35079fcd..54f44ce445a 100644
--- a/lib/rtl/amd64/except_asm.S
+++ b/lib/rtl/amd64/except_asm.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* FUNCTIONS *****************************************************************/
diff --git a/lib/rtl/amd64/rtlmem.S b/lib/rtl/amd64/rtlmem.S
index d0a82068251..e75161061ee 100644
--- a/lib/rtl/amd64/rtlmem.S
+++ b/lib/rtl/amd64/rtlmem.S
@@ -8,8 +8,7 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
/* FUNCTIONS *****************************************************************/
diff --git a/lib/rtl/amd64/slist.S b/lib/rtl/amd64/slist.S
index ca1ed3905d5..efdada51999 100644
--- a/lib/rtl/amd64/slist.S
+++ b/lib/rtl/amd64/slist.S
@@ -6,8 +6,8 @@
* PROGRAMMERS: Timo Kreuzer
*/
-#include
-#include
+#include
+#include
#define SLIST8A_DEPTH_MASK HEX(000000000000FFFF)
#define SLIST8A_DEPTH_INC HEX(0000000000000001)
diff --git a/lib/rtl/i386/debug_asm.S b/lib/rtl/i386/debug_asm.S
index c79545f53c0..39b6fa84236 100644
--- a/lib/rtl/i386/debug_asm.S
+++ b/lib/rtl/i386/debug_asm.S
@@ -6,43 +6,39 @@
* PROGRAMER: Alex Ionescu (alex@relsoft.net)
*/
-.intel_syntax noprefix
+#include
/* GLOBALS ****************************************************************/
-.globl _DbgBreakPoint@0
-.globl _DbgBreakPointWithStatus@4
-.globl _DbgUserBreakPoint@0
-.globl _DebugService@20
-.globl _DebugService2@12
-.globl _DbgBreakPointNoBugCheck@0
-.globl _RtlpBreakWithStatusInstruction@0
+PUBLIC _DbgBreakPoint@0
+PUBLIC _DbgBreakPointWithStatus@4
+PUBLIC _DbgUserBreakPoint@0
+PUBLIC _DebugService@20
+PUBLIC _DebugService2@12
+PUBLIC _DbgBreakPointNoBugCheck@0
+PUBLIC _RtlpBreakWithStatusInstruction@0
/* FUNCTIONS ***************************************************************/
-.func DbgBreakPointNoBugCheck@0
+.code
+
_DbgBreakPointNoBugCheck@0:
int 3
ret
-.endfunc
-.func DbgBreakPoint@0
_DbgBreakPoint@0:
_DbgUserBreakPoint@0:
int 3
ret
-.endfunc
-.func DbgBreakPointWithStatus@4
_DbgBreakPointWithStatus@4:
mov eax, [esp+4]
_RtlpBreakWithStatusInstruction@0:
int 3
ret 4
-.endfunc
-.func DebugService2@12
+
_DebugService2@12:
/* Setup the stack */
@@ -53,15 +49,14 @@ _DebugService2@12:
mov eax, [ebp+16]
mov ecx, [ebp+8]
mov edx, [ebp+12]
- int 0x2D
+ int HEX(2D)
int 3
/* Restore stack */
pop ebp
ret 12
-.endfunc
-.func DebugService@20
+
_DebugService@20:
/* Setup the stack */
@@ -78,7 +73,7 @@ _DebugService@20:
mov edx, [ebp+16]
mov ebx, [ebp+20]
mov edi, [ebp+24]
- int 0x2D
+ int HEX(2D)
int 3
/* Restore registers */
@@ -88,4 +83,5 @@ _DebugService@20:
/* Return */
pop ebp
ret 20
-.endfunc
+
+END
diff --git a/lib/rtl/i386/except_asm.s b/lib/rtl/i386/except_asm.s
index 9b2f856c724..53b07c69711 100644
--- a/lib/rtl/i386/except_asm.s
+++ b/lib/rtl/i386/except_asm.s
@@ -9,8 +9,13 @@
/* INCLUDES ******************************************************************/
-#include
-.intel_syntax noprefix
+#include
+#include
+
+EXTERN _RtlpCheckForActiveDebugger@0:PROC
+EXTERN _RtlDispatchException@8:PROC
+EXTERN _ZwContinue@8:PROC
+EXTERN _ZwRaiseException@12:PROC
#define ExceptionContinueSearch 1
#define ExceptionNestedException 2
@@ -18,17 +23,17 @@
/* FUNCTIONS *****************************************************************/
-.func RtlpGetExceptionList@0
-.globl _RtlpGetExceptionList@0
+.code
+
+PUBLIC _RtlpGetExceptionList@0
_RtlpGetExceptionList@0:
/* Return the exception list */
mov eax, fs:[TEB_EXCEPTION_LIST]
ret
-.endfunc
-.func RtlpSetExceptionList@4
-.globl _RtlpSetExceptionList@4
+
+PUBLIC _RtlpSetExceptionList@4
_RtlpSetExceptionList@4:
/* Get the new list */
@@ -40,10 +45,9 @@ _RtlpSetExceptionList@4:
/* Return */
ret 4
-.endfunc
-.func RtlCaptureContext@4
-.globl _RtlCaptureContext@4
+
+PUBLIC _RtlCaptureContext@4
_RtlCaptureContext@4:
/* Preserve EBX and put the context in it */
@@ -61,10 +65,9 @@ _RtlCaptureContext@4:
/* Capture the other regs */
jmp CaptureRest
-.endfunc
-.func RtlpCaptureContext@4
-.globl _RtlpCaptureContext@4
+
+PUBLIC _RtlpCaptureContext@4
_RtlpCaptureContext@4:
/* Preserve EBX and put the context in it */
@@ -107,10 +110,9 @@ CaptureRest:
/* Return to the caller */
pop ebx
ret 4
-.endfunc
-.func RtlpExecuteHandlerForException@20
-.globl _RtlpExecuteHandlerForException@20
+
+PUBLIC _RtlpExecuteHandlerForException@20
_RtlpExecuteHandlerForException@20:
/* Copy the routine in EDX */
@@ -118,16 +120,14 @@ _RtlpExecuteHandlerForException@20:
/* Jump to common routine */
jmp _RtlpExecuteHandler@20
-.endfunc
-.func RtlpExecuteHandlerForUnwind@20
-.globl _RtlpExecuteHandlerForUnwind@20
+
+PUBLIC _RtlpExecuteHandlerForUnwind@20
_RtlpExecuteHandlerForUnwind@20:
/* Copy the routine in EDX */
mov edx, offset _RtlpUnwindProtector
-.endfunc
-.func RtlpExecuteHandler@20
+
_RtlpExecuteHandler@20:
/* Save non-volatile */
@@ -142,22 +142,21 @@ _RtlpExecuteHandler@20:
xor edi, edi
/* Call the 2nd-stage executer */
- push [esp+0x20]
- push [esp+0x20]
- push [esp+0x20]
- push [esp+0x20]
- push [esp+0x20]
+ push [esp+32]
+ push [esp+32]
+ push [esp+32]
+ push [esp+32]
+ push [esp+32]
call _RtlpExecuteHandler2@20
/* Restore non-volatile */
pop edi
pop esi
pop ebx
- ret 0x14
-.endfunc
+ ret 20
-.func RtlpExecuteHandler2@20
-.globl _RtlpExecuteHandler2@20
+
+PUBLIC _RtlpExecuteHandler2@20
_RtlpExecuteHandler2@20:
/* Set up stack frame */
@@ -165,7 +164,7 @@ _RtlpExecuteHandler2@20:
mov ebp, esp
/* Save the Frame */
- push [ebp+0xC]
+ push [ebp+12]
/* Push handler address */
push edx
@@ -177,11 +176,11 @@ _RtlpExecuteHandler2@20:
mov [fs:TEB_EXCEPTION_LIST], esp
/* Call the handler */
- push [ebp+0x14]
- push [ebp+0x10]
- push [ebp+0xC]
+ push [ebp+20]
+ push [ebp+16]
+ push [ebp+12]
push [ebp+8]
- mov ecx, [ebp+0x18]
+ mov ecx, [ebp+24]
call ecx
/* Unlink us */
@@ -193,10 +192,9 @@ _RtlpExecuteHandler2@20:
/* Undo stack frame and return */
mov esp, ebp
pop ebp
- ret 0x14
-.endfunc
+ ret 20
+
-.func RtlpExceptionProtector
_RtlpExceptionProtector:
/* Assume we'll continue */
@@ -222,9 +220,8 @@ _RtlpExceptionProtector:
return:
ret 16
-.endfunc
-.func RtlpUnwindProtector
+
_RtlpUnwindProtector:
/* Assume we'll continue */
@@ -250,10 +247,9 @@ _RtlpUnwindProtector:
.return:
ret 16
-.endfunc
-.func RtlRaiseException@4
-.globl _RtlRaiseException@4
+
+PUBLIC _RtlRaiseException@4
_RtlRaiseException@4:
/* Set up stack frame */
@@ -325,10 +321,9 @@ RaiseStatus1:
/* If we returned, raise a status */
push eax
call _RtlRaiseStatus@4
-.endfunc
-.func RtlRaiseStatus@4
-.globl _RtlRaiseStatus@4
+
+PUBLIC _RtlRaiseStatus@4
_RtlRaiseStatus@4:
/* Set up stack frame */
@@ -398,4 +393,5 @@ RaiseStatus2:
/* If we returned, raise a status */
push eax
call _RtlRaiseStatus@4
-.endfunc
+
+END
diff --git a/lib/rtl/i386/interlck.S b/lib/rtl/i386/interlck.S
index 5b95e4c5429..7ad7a085216 100644
--- a/lib/rtl/i386/interlck.S
+++ b/lib/rtl/i386/interlck.S
@@ -6,20 +6,20 @@
* PROGRAMMERS: Timo Kreuzer
*/
-.intel_syntax noprefix
+#include
/* FUNCTIONS ****************************************************************/
-
+.code
/* PSLIST_ENTRY
* NTAPI
* RtlInterlockedPopEntrySList(
* IN PSLIST_HEADER ListHead);
*/
-.global _ExpInterlockedPopEntrySListResume@0
-.global _ExpInterlockedPopEntrySListEnd@0
-.global _ExpInterlockedPopEntrySListFault@0
-.global _RtlInterlockedPopEntrySList@4
+PUBLIC _ExpInterlockedPopEntrySListResume@0
+PUBLIC _ExpInterlockedPopEntrySListEnd@0
+PUBLIC _ExpInterlockedPopEntrySListFault@0
+PUBLIC _RtlInterlockedPopEntrySList@4
_RtlInterlockedPopEntrySList@4:
/* Save registers */
@@ -35,10 +35,9 @@ _ExpInterlockedPopEntrySListResume@0:
/* Load ListHead->Depth and ListHead->Sequence into edx */
mov edx, [ebp + 4]
-1:
/* Check if ListHead->Next is NULL */
or eax, eax
- jz 2f
+ jz _ExpInterlockedPopEntrySList2
/* Copy Depth and Sequence number and adjust Depth */
lea ecx, [edx - 1]
@@ -54,7 +53,7 @@ _ExpInterlockedPopEntrySListEnd@0:
jnz _ExpInterlockedPopEntrySListResume@0
/* Restore registers and return */
-2:
+_ExpInterlockedPopEntrySList2:
pop ebp
pop ebx
ret 4
@@ -66,7 +65,7 @@ _ExpInterlockedPopEntrySListEnd@0:
* IN PSLIST_HEADER ListHead,
* IN PSLIST_ENTRY ListEntry);
*/
-.global _RtlInterlockedPushEntrySList@8
+PUBLIC _RtlInterlockedPushEntrySList@8
_RtlInterlockedPushEntrySList@8:
/* Save registers */
@@ -85,18 +84,18 @@ _RtlInterlockedPushEntrySList@8:
/* Load ListHead->Depth and ListHead->Sequence into edx */
mov edx, [ebp + 4]
-1:
+_RtlpInterlockedPushEntrySListResume:
/* Set ListEntry->Next to ListHead->Next */
mov [ebx], eax
/* Copy ListHead->Depth and ListHead->Sequence and adjust them */
- lea ecx, [edx + 0x10001]
+ lea ecx, [edx + HEX(10001)]
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
- jnz 1b
+ jnz _RtlpInterlockedPushEntrySListResume
/* Restore registers and return */
pop ebp
@@ -109,7 +108,7 @@ _RtlInterlockedPushEntrySList@8:
* RtlInterlockedFlushSList(
* IN PSINGLE_LIST_ENTRY ListHead);
*/
-.global _RtlInterlockedFlushSList@4
+PUBLIC _RtlInterlockedFlushSList@4
_RtlInterlockedFlushSList@4:
/* Save registers */
@@ -128,10 +127,10 @@ _RtlInterlockedFlushSList@4:
/* Load ListHead->Depth and ListHead->Sequence into edx */
mov edx, [ebp + 4]
-1:
+_RtlpInterlockedFlushSListResume:
/* Check if ListHead->Next is NULL */
or eax, eax
- jz 2f
+ jz _RtlpInterlockedFlushSListEnd
/* Copy Depth and Sequence number to ecx */
mov ecx, edx
@@ -143,10 +142,12 @@ _RtlInterlockedFlushSList@4:
LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
- jnz 1b
+ jnz _RtlpInterlockedFlushSListResume
/* Restore registers and return */
-2:
+_RtlpInterlockedFlushSListEnd:
pop ebp
pop ebx
ret 4
+
+END
diff --git a/lib/rtl/i386/res_asm.s b/lib/rtl/i386/res_asm.s
index 46c61e08d42..5af744c2308 100644
--- a/lib/rtl/i386/res_asm.s
+++ b/lib/rtl/i386/res_asm.s
@@ -1,11 +1,22 @@
-#include
-.intel_syntax noprefix
+/*
+ * COPYRIGHT: GNU GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Run-Time Library
+ * PURPOSE:
+ * FILE: lib/rtl/i386/res_asm.S
+ * PROGRAMER:
+ */
+
+#include
+#include
+
+EXTERN _LdrpAccessResource@16:PROC
/*
* On x86, Shrinker, an executable compressor, depends on the
* "call access_resource" instruction being there.
*/
-.globl _LdrAccessResource@16
+.code
+PUBLIC _LdrAccessResource@16
_LdrAccessResource@16:
push ebp
mov ebp, esp
@@ -18,3 +29,5 @@ _LdrAccessResource@16:
call _LdrpAccessResource@16
leave
ret 16
+
+END
diff --git a/lib/rtl/i386/rtlmem.s b/lib/rtl/i386/rtlmem.s
index dea3b6d920d..d26f5b4ec52 100644
--- a/lib/rtl/i386/rtlmem.s
+++ b/lib/rtl/i386/rtlmem.s
@@ -1,26 +1,26 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
+ * COPYRIGHT: GNU GPL - See COPYING in the top level directory
* PROJECT: ReactOS Run-Time Library
* PURPOSE: Memory functions
* FILE: lib/rtl/i386/rtlswap.S
* PROGRAMER: Alex Ionescu (alex.ionescu@reactos.org)
*/
-.intel_syntax noprefix
+#include
/* GLOBALS *******************************************************************/
-.globl _RtlCompareMemory@12
-.globl _RtlCompareMemoryUlong@12
-.globl _RtlFillMemory@12
-.globl _RtlFillMemoryUlong@12
-.globl _RtlMoveMemory@12
-.globl _RtlZeroMemory@8
-.globl @RtlPrefetchMemoryNonTemporal@8
+PUBLIC _RtlCompareMemory@12
+PUBLIC _RtlCompareMemoryUlong@12
+PUBLIC _RtlFillMemory@12
+PUBLIC _RtlFillMemoryUlong@12
+PUBLIC _RtlMoveMemory@12
+PUBLIC _RtlZeroMemory@8
+PUBLIC @RtlPrefetchMemoryNonTemporal@8
/* FUNCTIONS *****************************************************************/
+.code
-.func RtlCompareMemory@12
_RtlCompareMemory@12:
/* Save volatiles */
@@ -74,9 +74,8 @@ NotEqual2:
pop edi
pop esi
ret 12
-.endfunc
-.func RtlCompareMemoryUlong@12
+
_RtlCompareMemoryUlong@12:
/* Get pointers and size in ULONGs */
@@ -97,9 +96,8 @@ Done:
mov eax, edi
pop edi
ret 12
-.endfunc
-.func RtlFillMemory@12
+
_RtlFillMemory@12:
/* Get pointers and size */
@@ -134,9 +132,8 @@ ByteFill:
rep stosb
pop edi
ret 12
-.endfunc
-.func RtlFillMemoryUlong@12
+
_RtlFillMemoryUlong@12:
/* Get pointer, size and pattern */
@@ -150,9 +147,8 @@ _RtlFillMemoryUlong@12:
rep stosd
pop edi
ret 12
-.endfunc
-.func RtlFillMemoryUlonglong@16
+
_RtlFillMemoryUlonglong@16:
/* Save volatiles */
@@ -179,9 +175,8 @@ _RtlFillMemoryUlonglong@16:
pop esi
pop edi
ret 16
-.endfunc
-.func RtlZeroMemory@8
+
_RtlZeroMemory@8:
/* Get pointers and size */
@@ -212,9 +207,8 @@ ByteZero:
rep stosb
pop edi
ret 8
-.endfunc
-.func RtlMoveMemory@12
+
_RtlMoveMemory@12:
/* Save volatiles */
@@ -280,9 +274,8 @@ Overlap:
rep movsb
cld
jmp DoneMove
-.endfunc
-.func @RtlPrefetchMemoryNonTemporal@8, @RtlPrefetchMemoryNonTemporal@8
+
@RtlPrefetchMemoryNonTemporal@8:
/*
@@ -306,8 +299,10 @@ FetchLine:
/* Keep looping for the next line, or return if done */
ja FetchLine
ret
-.endfunc
+
/* FIXME: HACK */
_Ke386CacheAlignment:
- .long 0x40
+ .long 64
+
+END
diff --git a/lib/rtl/rtl.rbuild b/lib/rtl/rtl.rbuild
index eac455e626d..0bce2979a22 100644
--- a/lib/rtl/rtl.rbuild
+++ b/lib/rtl/rtl.rbuild
@@ -6,6 +6,11 @@
.
+
+
+
+
+
debug_asm.S
diff --git a/lib/rtl/sprintf.c b/lib/rtl/sprintf.c
index 52f46f8a3d3..51461147d0a 100644
--- a/lib/rtl/sprintf.c
+++ b/lib/rtl/sprintf.c
@@ -1,3 +1,5 @@
+
+#ifndef USE_NEW_SPRINTF
/*
* PROGRAMMERS: David Welch
* Eric Kohl
@@ -741,3 +743,5 @@ int __cdecl vsprintf(char *buf, const char *fmt, va_list args)
}
/* EOF */
+#endif
+
diff --git a/lib/rtl/swprintf.c b/lib/rtl/swprintf.c
index 64d7d65397a..20d975ff757 100644
--- a/lib/rtl/swprintf.c
+++ b/lib/rtl/swprintf.c
@@ -1,3 +1,4 @@
+#ifndef USE_NEW_SPRINTF
/*
* PROGRAMMERS: David Welch
* Eric Kohl
@@ -740,3 +741,4 @@ int __cdecl vswprintf(wchar_t *buf, const wchar_t *fmt, va_list args)
}
/* EOF */
+#endif
diff --git a/lib/sdk/crt/conio/cprintf.c b/lib/sdk/crt/conio/cprintf.c
index 5c6295c15a1..100e6ae63cf 100644
--- a/lib/sdk/crt/conio/cprintf.c
+++ b/lib/sdk/crt/conio/cprintf.c
@@ -5,6 +5,7 @@
* PURPOSE: C Runtime
* PROGRAMMER: Magnus Olsen (Imported from wine cvs 2006-05-23)
*/
+#ifndef USE_NEW_SPRINTF
#include
@@ -38,3 +39,5 @@ _cprintf(const char *fmt, ...)
free (mem);
return retval;
}
+
+#endif
diff --git a/lib/sdk/crt/crt.rbuild b/lib/sdk/crt/crt.rbuild
index ba76d8cc0bb..c6f60a7d997 100644
--- a/lib/sdk/crt/crt.rbuild
+++ b/lib/sdk/crt/crt.rbuild
@@ -26,6 +26,33 @@
+
+
+
+
+ _cprintf.c
+ _snprintf.c
+ _snwprintf.c
+ _vcprintf.c
+ _vsnprintf.c
+ _vsnwprintf.c
+ fprintf.c
+ fwprintf.c
+ printf.c
+ sprintf.c
+ streamout.c
+ swprintf.c
+ vfprintf.c
+ vfwprintf.c
+ vprintf.c
+ vsprintf.c
+ vswprintf.c
+ vwprintf.c
+ wprintf.c
+ wstreamout.c
+
+
+
cgets.c
cprintf.c
@@ -123,6 +150,7 @@
ldiv.c
logf.c
modf.c
+ powf.c
rand.c
s_modf.c
sinf.c
@@ -284,7 +312,6 @@
amsg.c
assert.c
- crtmain.c
environ.c
getargs.c
initterm.c
@@ -344,6 +371,7 @@
wpopen.c
wstat.c
wstat64.c
+ lock_file.c
_exit.c
diff --git a/lib/sdk/crt/except/amd64/chkstk_asm.s b/lib/sdk/crt/except/amd64/chkstk_asm.s
index 4008d4f5eab..b1486dea898 100644
--- a/lib/sdk/crt/except/amd64/chkstk_asm.s
+++ b/lib/sdk/crt/except/amd64/chkstk_asm.s
@@ -8,11 +8,10 @@
/* INCLUDES ******************************************************************/
-#include
+#include
-.intel_syntax noprefix
-.global MsgUnimplemented
+PUBLIC MsgUnimplemented
MsgUnimplemented:
.asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
@@ -27,4 +26,5 @@ MsgUnimplemented:
ret
.endp
+END
/* EOF */
diff --git a/lib/sdk/crt/except/amd64/seh.s b/lib/sdk/crt/except/amd64/seh.s
index e784457e9f8..9d44d3ffd4d 100644
--- a/lib/sdk/crt/except/amd64/seh.s
+++ b/lib/sdk/crt/except/amd64/seh.s
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-.intel_syntax noprefix
+#include
+#include
#define DISPOSITION_DISMISS 0
#define DISPOSITION_CONTINUE_SEARCH 1
@@ -54,3 +54,5 @@ _except_handler2:
_except_handler3:
ret
.endfunc
+
+END
diff --git a/lib/sdk/crt/except/i386/chkstk_asm.s b/lib/sdk/crt/except/i386/chkstk_asm.s
index 5104a35b1c4..58879f18d0f 100644
--- a/lib/sdk/crt/except/i386/chkstk_asm.s
+++ b/lib/sdk/crt/except/i386/chkstk_asm.s
@@ -7,8 +7,43 @@
* PROGRAMER: KJK::Hyperion
*/
-.globl __chkstk
-.globl __alloca_probe
+#include
+#include
+
+#define PAGE_SIZE 4096
+
+PUBLIC __chkstk
+PUBLIC __alloca_probe
+PUBLIC __alloca_probe_16
+.code
+
+ /* 16 byte aligned alloca probe
+ * EAX = size to be allocated */
+__alloca_probe_16:
+ /* save the ECX register */
+ push ecx
+
+ /* ecx = top of the previous stack frame */
+ lea ecx, [esp + 8]
+
+ /* Calculate end of allocation */
+ sub ecx, eax
+
+ /* Get the misalignment */
+ and ecx, 15
+
+ /* Add the misalignment to the original alloc size */
+ add eax, ecx
+
+ /* Check for overflow */
+ jnc l1
+
+ /* Set maximum value */
+ mov eax, HEX(0ffffffff)
+l1:
+ /* Restore ecx */
+ pop ecx
+ /* Fall through to __chkstk */
/*
_chkstk() is called by all stack allocations of more than 4 KB. It grows the
@@ -18,49 +53,49 @@
__chkstk:
__alloca_probe:
-/* EAX = size to be allocated */
-/* save the ECX register */
- pushl %ecx
+ /* EAX = size to be allocated */
+ /* save the ECX register */
+ push ecx
-/* ECX = top of the previous stack frame */
- leal 8(%esp), %ecx
+ /* ECX = top of the previous stack frame */
+ lea ecx, [esp + 8]
-/* probe the desired memory, page by page */
- cmpl $0x1000, %eax
- jge .l_MoreThanAPage
- jmp .l_LessThanAPage
+ /* probe the desired memory, page by page */
+ cmp eax, PAGE_SIZE
+ jl .l_LessThanAPage
.l_MoreThanAPage:
-/* raise the top of the stack by a page and probe */
- subl $0x1000, %ecx
- testl %eax, 0(%ecx)
+ /* raise the top of the stack by a page and probe */
+ sub ecx, PAGE_SIZE
+ test [ecx], eax
-/* loop if still more than a page must be probed */
- subl $0x1000, %eax
- cmpl $0x1000, %eax
- jge .l_MoreThanAPage
+ /* loop if still more than a page must be probed */
+ sub eax, PAGE_SIZE
+ cmp eax, PAGE_SIZE
+ jge .l_MoreThanAPage
.l_LessThanAPage:
-/* raise the top of the stack by EAX bytes (size % 4096) and probe */
- subl %eax, %ecx
- testl %eax, 0(%ecx)
+ /* raise the top of the stack by EAX bytes (size % 4096) and probe */
+ sub ecx, eax
+ test [ecx], eax
-/* EAX = top of the stack */
- movl %esp, %eax
+ /* EAX = top of the stack */
+ mov eax, esp
-/* allocate the memory */
- movl %ecx, %esp
+ /* allocate the memory */
+ mov esp, ecx
-/* restore ECX */
- movl 0(%eax), %ecx
+ /* restore ECX */
+ mov ecx, [eax]
-/* restore the return address */
- movl 4(%eax), %eax
- pushl %eax
+ /* restore the return address */
+ mov eax, [eax + 4]
+ push eax
-/* return */
- ret
+ /* return */
+ ret
/* EOF */
+END
diff --git a/lib/sdk/crt/except/i386/prolog.s b/lib/sdk/crt/except/i386/prolog.s
index 5ff588d6746..ebbf4ee412d 100644
--- a/lib/sdk/crt/except/i386/prolog.s
+++ b/lib/sdk/crt/except/i386/prolog.s
@@ -8,20 +8,23 @@
/* INCLUDES ******************************************************************/
-#include
+#include
+#include
-/* GLOBALS *******************************************************************/
-
-.globl __EH_prolog
+/* FUNCTIONS *****************************************************************/
+.code
+PUBLIC __EH_prolog
// Copied from Wine.
__EH_prolog:
- pushl $-1
- pushl %eax
- pushl %fs:0
- movl %esp, %fs:0
- movl 12(%esp), %eax
- movl %ebp, 12(%esp)
- leal 12(%esp), %ebp
- pushl %eax
+ push -1
+ push eax
+ push fs:0
+ mov fs:0, esp
+ mov eax, [esp + 12]
+ mov [esp + 12], ebp
+ lea ebp, [esp + 12]
+ push eax
ret
+
+END
diff --git a/lib/sdk/crt/except/i386/seh.s b/lib/sdk/crt/except/i386/seh.s
index 15a8cc5777a..6fde1e181f7 100644
--- a/lib/sdk/crt/except/i386/seh.s
+++ b/lib/sdk/crt/except/i386/seh.s
@@ -8,24 +8,29 @@
/* INCLUDES ******************************************************************/
-#include
-.intel_syntax noprefix
+#include
#define DISPOSITION_DISMISS 0
#define DISPOSITION_CONTINUE_SEARCH 1
#define DISPOSITION_COLLIDED_UNWIND 3
+#define EXCEPTION_EXIT_UNWIND 4
+#define EXCEPTION_UNWINDING 2
+
+
+EXTERN _RtlUnwind@16:PROC
+
/* GLOBALS *******************************************************************/
-.globl __global_unwind2
-.globl __local_unwind2
-.globl __abnormal_termination
-.globl __except_handler2
-.globl __except_handler3
+PUBLIC __global_unwind2
+PUBLIC __local_unwind2
+PUBLIC __abnormal_termination
+PUBLIC __except_handler2
+PUBLIC __except_handler3
/* FUNCTIONS *****************************************************************/
-.func unwind_handler
+.code
_unwind_handler:
/* Check if we were unwinding and continue search if not */
@@ -56,9 +61,8 @@ _unwind_handler:
unwind_handler_return:
ret
-.endfunc
-.func _global_unwind2
+
__global_unwind2:
/* Create stack and save all registers */
@@ -85,9 +89,8 @@ glu_return:
mov esp, ebp
pop ebp
ret
-.endfunc
-.func _abnormal_termination
+
__abnormal_termination:
/* Assume false */
@@ -112,9 +115,8 @@ __abnormal_termination:
/* Return */
ab_return:
ret
-.endfunc
-.func _local_unwind2
+
__local_unwind2:
/* Save volatiles */
@@ -175,9 +177,8 @@ unwind_return:
pop esi
pop ebx
ret
-.endfunc
-.func _except_handler2
+
__except_handler2:
/* Setup stack and save volatiles */
@@ -256,7 +257,7 @@ except_loop2:
mov [ebx+12], eax
/* Call except handler */
- call [edi+ecx*4+8]
+ call dword ptr [edi+ecx*4+8]
except_continue2:
/* Reload try level and except again */
@@ -297,9 +298,8 @@ except_return2:
mov esp, ebp
pop ebp
ret
-.endfunc
-.func _except_handler3
+
__except_handler3:
/* Setup stack and save volatiles */
@@ -437,4 +437,5 @@ except_return3:
mov esp, ebp
pop ebp
ret
-.endfunc
+
+END
diff --git a/lib/sdk/crt/float/i386/logb.c b/lib/sdk/crt/float/i386/logb.c
index 0c02c0e0f11..e4b61949fc4 100644
--- a/lib/sdk/crt/float/i386/logb.c
+++ b/lib/sdk/crt/float/i386/logb.c
@@ -30,7 +30,7 @@ double _logb (double __x)
("fxtract\n\t"
: "=t" (__junk), "=u" (__val) : "0" (__x));
#else
-#error REVIEW ME
+#pragma message ("REVIEW ME")
__asm fld [__x];
__asm fxtract;
__asm fstp st(0);
diff --git a/lib/sdk/crt/libcntpr.rbuild b/lib/sdk/crt/libcntpr.rbuild
index e27ac1d265c..5bb60df8b9c 100644
--- a/lib/sdk/crt/libcntpr.rbuild
+++ b/lib/sdk/crt/libcntpr.rbuild
@@ -9,6 +9,25 @@
+
+
+
+
+ _snprintf.c
+ _snwprintf.c
+ _vcprintf.c
+ _vsnprintf.c
+ _vsnwprintf.c
+ sprintf.c
+ streamout.c
+ swprintf.c
+ vprintf.c
+ vsprintf.c
+ vswprintf.c
+ wstreamout.c
+
+
+
"extern __attribute__ ((dllexport))"
@@ -33,6 +52,9 @@
+
+ isnan.c
+
@@ -54,6 +76,7 @@
floor_asm.s
ftol_asm.s
log_asm.s
+ log10_asm.s
pow_asm.s
sin_asm.s
sqrt_asm.s
@@ -207,6 +230,10 @@
wtol.c
+
+ mbstrlen.c
+
+
wcsicmp.c
wcslwr.c
diff --git a/lib/sdk/crt/math/amd64/alldiv.S b/lib/sdk/crt/math/amd64/alldiv.S
index 831ef50981b..b4018cc4739 100644
--- a/lib/sdk/crt/math/amd64/alldiv.S
+++ b/lib/sdk/crt/math/amd64/alldiv.S
@@ -8,8 +8,7 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
/* DATA *********************************************************************/
diff --git a/lib/sdk/crt/math/amd64/atan.S b/lib/sdk/crt/math/amd64/atan.S
index 3ba194931f4..889f10e2825 100644
--- a/lib/sdk/crt/math/amd64/atan.S
+++ b/lib/sdk/crt/math/amd64/atan.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* FUNCTIONS ****************************************************************/
diff --git a/lib/sdk/crt/math/amd64/atan2.S b/lib/sdk/crt/math/amd64/atan2.S
index 7cd29b93269..fd611101f0a 100644
--- a/lib/sdk/crt/math/amd64/atan2.S
+++ b/lib/sdk/crt/math/amd64/atan2.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* FUNCTIONS ****************************************************************/
diff --git a/lib/sdk/crt/math/amd64/ceil.S b/lib/sdk/crt/math/amd64/ceil.S
index dbee413f491..17ae0150717 100644
--- a/lib/sdk/crt/math/amd64/ceil.S
+++ b/lib/sdk/crt/math/amd64/ceil.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* FUNCTIONS ****************************************************************/
diff --git a/lib/sdk/crt/math/amd64/ceilf.S b/lib/sdk/crt/math/amd64/ceilf.S
index e3a948fff8a..2b2d14b03f0 100644
--- a/lib/sdk/crt/math/amd64/ceilf.S
+++ b/lib/sdk/crt/math/amd64/ceilf.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* FUNCTIONS ****************************************************************/
@@ -17,24 +17,30 @@
PUBLIC ceilf
ceilf:
+ sub rsp, 16
+
/* Put parameter on the stack */
- movss [rsp - 0x10], xmm0
- fld dword ptr [rsp]
+ movss [rsp], xmm0
+ fld dword ptr [rsp]
/* Change fpu control word to round up */
- fstcw [rsp - 0x10]
- mov eax, [rsp - 0x10]
- or eax, 0x00800
- and eax, 0x0fbff
- mov [rsp - 0x08], eax
- fldcw [rsp - 0x08]
+ fstcw [rsp + 8]
+ mov eax, [rsp + 8]
+ or eax, HEX(00800)
+ and eax, HEX(0fbff)
+ mov [rsp + 12], eax
+ fldcw [rsp + 12]
/* Round to integer */
frndint
/* Restore fpu control word */
- fldcw [rsp - 0x10]
+ fldcw [rsp + 8]
- fstp dword ptr [rsp - 0x10]
- movss xmm0, [rsp - 0x10]
+ fstp dword ptr [rsp]
+ movss xmm0, [rsp]
+
+ add rsp, 16
ret
+
+END
diff --git a/lib/sdk/crt/math/amd64/exp.S b/lib/sdk/crt/math/amd64/exp.S
index ca3dc993182..44b324e4267 100644
--- a/lib/sdk/crt/math/amd64/exp.S
+++ b/lib/sdk/crt/math/amd64/exp.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* FUNCTIONS ****************************************************************/
@@ -20,3 +20,4 @@ exp:
UNIMPLEMENTED exp
ret
+END
diff --git a/lib/sdk/crt/math/amd64/fabs.S b/lib/sdk/crt/math/amd64/fabs.S
index e58b960ecab..3c1e8f2dcf1 100644
--- a/lib/sdk/crt/math/amd64/fabs.S
+++ b/lib/sdk/crt/math/amd64/fabs.S
@@ -8,8 +8,7 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
/* FUNCTIONS ****************************************************************/
diff --git a/lib/sdk/crt/math/amd64/floor.S b/lib/sdk/crt/math/amd64/floor.S
index f1c3b9305af..c0fba3dd066 100644
--- a/lib/sdk/crt/math/amd64/floor.S
+++ b/lib/sdk/crt/math/amd64/floor.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* FUNCTIONS ****************************************************************/
@@ -19,3 +19,5 @@ PUBLIC floor
floor:
UNIMPLEMENTED floor
ret
+
+END
diff --git a/lib/sdk/crt/math/amd64/floorf.S b/lib/sdk/crt/math/amd64/floorf.S
index e2d02202df7..0ac9098b9a3 100644
--- a/lib/sdk/crt/math/amd64/floorf.S
+++ b/lib/sdk/crt/math/amd64/floorf.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* FUNCTIONS ****************************************************************/
@@ -17,24 +17,29 @@
PUBLIC floorf
floorf:
+ sub rsp, 16
+
/* Put parameter on the stack */
- movss [rsp - 0x10], xmm0
+ movss [rsp], xmm0
fld dword ptr [rsp]
/* Change fpu control word to round down */
- fstcw [rsp - 0x10]
- mov eax, [rsp - 0x10]
+ fstcw [rsp]
+ mov eax, [rsp]
or eax, 0x00400
and eax, 0x0f7ff
- mov [rsp - 0x08], eax
- fldcw [rsp - 0x08]
+ mov [rsp + 8], eax
+ fldcw [rsp + 8]
/* Round to integer */
frndint
/* Restore fpu control word */
- fldcw [rsp - 0x10]
+ fldcw [rsp]
- fstp dword ptr [rsp - 0x10]
- movss xmm0, [rsp - 0x10]
+ fstp dword ptr [rsp]
+ movss xmm0, [rsp]
+ add rsp, 16
ret
+
+END
diff --git a/lib/sdk/crt/math/amd64/fmod.S b/lib/sdk/crt/math/amd64/fmod.S
index 4ca67f55bfb..697257ab368 100644
--- a/lib/sdk/crt/math/amd64/fmod.S
+++ b/lib/sdk/crt/math/amd64/fmod.S
@@ -8,8 +8,7 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
/* DATA *********************************************************************/
@@ -17,3 +16,5 @@ PUBLIC fmod
fmod:
UNIMPLEMENTED fmod
ret
+
+END
diff --git a/lib/sdk/crt/math/amd64/fmodf.S b/lib/sdk/crt/math/amd64/fmodf.S
index e109c387cc8..d0e24ef9529 100644
--- a/lib/sdk/crt/math/amd64/fmodf.S
+++ b/lib/sdk/crt/math/amd64/fmodf.S
@@ -8,8 +8,7 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
/* DATA *********************************************************************/
@@ -17,3 +16,5 @@ PUBLIC fmodf
fmodf:
UNIMPLEMENTED fmodf
ret
+
+END
diff --git a/lib/sdk/crt/math/amd64/ldexp.S b/lib/sdk/crt/math/amd64/ldexp.S
index d0265629bf6..a83660ae7a3 100644
--- a/lib/sdk/crt/math/amd64/ldexp.S
+++ b/lib/sdk/crt/math/amd64/ldexp.S
@@ -8,8 +8,7 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
/* DATA *********************************************************************/
@@ -17,3 +16,5 @@ PUBLIC ldexp
ldexp:
UNIMPLEMENTED ldexp
ret
+
+END
diff --git a/lib/sdk/crt/math/amd64/log.S b/lib/sdk/crt/math/amd64/log.S
index 9fa02763b9e..1289a745cba 100644
--- a/lib/sdk/crt/math/amd64/log.S
+++ b/lib/sdk/crt/math/amd64/log.S
@@ -8,8 +8,7 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
/* DATA *********************************************************************/
diff --git a/lib/sdk/crt/math/amd64/log10.S b/lib/sdk/crt/math/amd64/log10.S
index 007f0d80e98..f8014aa5bc6 100644
--- a/lib/sdk/crt/math/amd64/log10.S
+++ b/lib/sdk/crt/math/amd64/log10.S
@@ -8,8 +8,7 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
/* DATA *********************************************************************/
diff --git a/lib/sdk/crt/math/amd64/pow.S b/lib/sdk/crt/math/amd64/pow.S
index 37988801b11..48adf3961f3 100644
--- a/lib/sdk/crt/math/amd64/pow.S
+++ b/lib/sdk/crt/math/amd64/pow.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* DATA *********************************************************************/
diff --git a/lib/sdk/crt/math/amd64/sqrt.S b/lib/sdk/crt/math/amd64/sqrt.S
index 758d8768d4f..282419e78a5 100644
--- a/lib/sdk/crt/math/amd64/sqrt.S
+++ b/lib/sdk/crt/math/amd64/sqrt.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* DATA *********************************************************************/
@@ -17,3 +17,5 @@ PUBLIC sqrt
sqrt:
UNIMPLEMENTED sqrt
ret
+
+END
diff --git a/lib/sdk/crt/math/amd64/sqrtf.S b/lib/sdk/crt/math/amd64/sqrtf.S
index a4ee3fa6cc5..da75fcf42f5 100644
--- a/lib/sdk/crt/math/amd64/sqrtf.S
+++ b/lib/sdk/crt/math/amd64/sqrtf.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* DATA *********************************************************************/
@@ -17,3 +17,5 @@ PUBLIC sqrtf
sqrtf:
sqrtss xmm0, xmm0
ret
+
+END
diff --git a/lib/sdk/crt/math/amd64/tan.S b/lib/sdk/crt/math/amd64/tan.S
index a7c66d0ccd7..93e5d01d762 100644
--- a/lib/sdk/crt/math/amd64/tan.S
+++ b/lib/sdk/crt/math/amd64/tan.S
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
/* DATA *********************************************************************/
@@ -17,3 +17,5 @@ PUBLIC tan
tan:
UNIMPLEMENTED tan
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/alldiv_asm.s b/lib/sdk/crt/math/i386/alldiv_asm.s
index 043a8af95c3..5061fb7c21f 100644
--- a/lib/sdk/crt/math/i386/alldiv_asm.s
+++ b/lib/sdk/crt/math/i386/alldiv_asm.s
@@ -33,18 +33,22 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
- .globl __alldiv
- .globl __fltused
-
+
+#include
+
+PUBLIC __alldiv
+PUBLIC __fltused
+
/* DATA ********************************************************************/
+.data
+ASSUME CS:NOTHING, DS:NOTHING, ES:NOTHING, FS:NOTHING, GS:NOTHING
__fltused:
- .long 0x9875
+ .long HEX(9875)
-.intel_syntax noprefix
/* FUNCTIONS ***************************************************************/
+.code
//
// lldiv - signed long divide
@@ -222,3 +226,5 @@ L8:
pop edi
ret 16
+
+END
diff --git a/lib/sdk/crt/math/i386/alldvrm_asm.s b/lib/sdk/crt/math/i386/alldvrm_asm.s
index 8f775d6dac3..a055d55d62e 100644
--- a/lib/sdk/crt/math/i386/alldvrm_asm.s
+++ b/lib/sdk/crt/math/i386/alldvrm_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl __alldvrm
-
-.intel_syntax noprefix
+#include
+
+PUBLIC __alldvrm
+
/* FUNCTIONS ***************************************************************/
+.code
__alldvrm:
push edi
@@ -88,7 +89,7 @@ __alldvrm:
mov eax,DVNDHI // hi word of a
or eax,eax // test to see if signed
- jge short ....L1 // skip rest if a is already positive
+ jge short .L1 // skip rest if a is already positive
inc edi // complement result sign flag
inc ebp // complement result sign flag
mov edx,DVNDLO // lo word of a
@@ -97,10 +98,10 @@ __alldvrm:
sbb eax,0
mov DVNDHI,eax // save positive value
mov DVNDLO,edx
-....L1:
+.L1:
mov eax,DVSRHI // hi word of b
or eax,eax // test to see if signed
- jge short ....L2 // skip rest if b is already positive
+ jge short .L2 // skip rest if b is already positive
inc edi // complement the result sign flag
mov edx,DVSRLO // lo word of a
neg eax // make b positive
@@ -108,7 +109,7 @@ __alldvrm:
sbb eax,0
mov DVSRHI,eax // save positive value
mov DVSRLO,edx
-....L2:
+.L2:
//
// Now do the divide. First look to see if the divisor is less than 4194304K.
@@ -119,7 +120,7 @@ __alldvrm:
//
or eax,eax // check to see if divisor < 4194304K
- jnz short ....L3 // nope, gotta do this the hard way
+ jnz short .L3 // nope, gotta do this the hard way
mov ecx,DVSRLO // load divisor
mov eax,DVNDHI // load high word of dividend
xor edx,edx
@@ -137,24 +138,24 @@ __alldvrm:
mov eax,esi // set up low word of quotient
mul dword ptr DVSRLO // LOWORD(QUOT) * DVSR
add edx,ecx // EDX:EAX = QUOT * DVSR
- jmp short ....L4 // complete remainder calculation
+ jmp short .L4 // complete remainder calculation
//
// Here we do it the hard way. Remember, eax contains the high word of DVSR
//
-....L3:
+.L3:
mov ebx,eax // ebx:ecx <- divisor
mov ecx,DVSRLO
mov edx,DVNDHI // edx:eax <- dividend
mov eax,DVNDLO
-....L5:
+.L5:
shr ebx,1 // shift divisor right one bit
rcr ecx,1
shr edx,1 // shift dividend right one bit
rcr eax,1
or ebx,ebx
- jnz short ....L5 // loop until divisor < 4194304K
+ jnz short .L5 // loop until divisor < 4194304K
div ecx // now divide, ignore remainder
mov esi,eax // save quotient
@@ -170,7 +171,7 @@ __alldvrm:
mov eax,DVSRLO
mul esi // QUOT * DVSRLO
add edx,ecx // EDX:EAX = QUOT * DVSR
- jc short ....L6 // carry means Quotient is off by 1
+ jc short .L6 // carry means Quotient is off by 1
//
// do long compare here between original dividend and the result of the
@@ -179,18 +180,18 @@ __alldvrm:
//
cmp edx,DVNDHI // compare hi words of result and original
- ja short ....L6 // if result > original, do subtract
- jb short ....L7 // if result < original, we are ok
+ ja short .L6 // if result > original, do subtract
+ jb short .L7 // if result < original, we are ok
cmp eax,DVNDLO // hi words are equal, compare lo words
- jbe short ....L7 // if less or equal we are ok, else subtract
-....L6:
+ jbe short .L7 // if less or equal we are ok, else subtract
+.L6:
dec esi // subtract 1 from quotient
sub eax,DVSRLO // subtract divisor from result
sbb edx,DVSRHI
-....L7:
+.L7:
xor ebx,ebx // ebx:esi <- quotient
-....L4:
+.L4:
//
// Calculate remainder by subtracting the result from the original dividend.
// Since the result is already in a register, we will do the subtract in the
@@ -208,7 +209,7 @@ __alldvrm:
//
dec ebp // check result sign flag
- jns short ....L9 // result is ok, set up the quotient
+ jns short .L9 // result is ok, set up the quotient
neg edx // otherwise, negate the result
neg eax
sbb edx,0
@@ -216,7 +217,7 @@ __alldvrm:
//
// Now we need to get the quotient into edx:eax and the remainder into ebx:ecx.
//
-....L9:
+.L9:
mov ecx,edx
mov edx,ebx
mov ebx,ecx
@@ -229,7 +230,7 @@ __alldvrm:
//
dec edi // check to see if result is negative
- jnz short ....L8 // if EDI == 0, result should be negative
+ jnz short .L8 // if EDI == 0, result should be negative
neg edx // otherwise, negate the result
neg eax
sbb edx,0
@@ -238,9 +239,11 @@ __alldvrm:
// Restore the saved registers and return.
//
-....L8:
+.L8:
pop ebp
pop esi
pop edi
ret 16
+
+END
diff --git a/lib/sdk/crt/math/i386/allmul_asm.s b/lib/sdk/crt/math/i386/allmul_asm.s
index ddfa7cf7b46..b9a47baafcc 100644
--- a/lib/sdk/crt/math/i386/allmul_asm.s
+++ b/lib/sdk/crt/math/i386/allmul_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl __allmul
-.intel_syntax noprefix
+#include
+
+PUBLIC __allmul
/* FUNCTIONS ***************************************************************/
+.code
//
// llmul - long multiply routine
@@ -113,3 +114,4 @@ hard:
ret 16 // callee restores the stack
+END
diff --git a/lib/sdk/crt/math/i386/allrem_asm.s b/lib/sdk/crt/math/i386/allrem_asm.s
index a8e222e25bf..2c3e68c5578 100644
--- a/lib/sdk/crt/math/i386/allrem_asm.s
+++ b/lib/sdk/crt/math/i386/allrem_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl __allrem
-
-.intel_syntax noprefix
+#include
+
+PUBLIC __allrem
+
/* FUNCTIONS ***************************************************************/
+.code
//
// llrem - signed long remainder
@@ -227,3 +228,5 @@ __allrem :
pop ebx
ret 16
+
+END
diff --git a/lib/sdk/crt/math/i386/allshl_asm.s b/lib/sdk/crt/math/i386/allshl_asm.s
index b5d574aff01..48d06b7dd5a 100644
--- a/lib/sdk/crt/math/i386/allshl_asm.s
+++ b/lib/sdk/crt/math/i386/allshl_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl __allshl
-.intel_syntax noprefix
+#include
+
+PUBLIC __allshl
/* FUNCTIONS ***************************************************************/
+.code
//
// llshl - long shift left
@@ -92,3 +93,5 @@ RETZERO:
xor eax,eax
xor edx,edx
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/allshr_asm.s b/lib/sdk/crt/math/i386/allshr_asm.s
index 575fc92db9a..e2b60bd97aa 100644
--- a/lib/sdk/crt/math/i386/allshr_asm.s
+++ b/lib/sdk/crt/math/i386/allshr_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl __allshr
-
-.intel_syntax noprefix
+#include
+
+PUBLIC __allshr
+
/* FUNCTIONS ***************************************************************/
+.code
//
// llshr - long shift right
@@ -93,3 +94,5 @@ __allshr:
sar edx,31
mov eax,edx
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/atan2_asm.s b/lib/sdk/crt/math/i386/atan2_asm.s
new file mode 100644
index 00000000000..699b02d3530
--- /dev/null
+++ b/lib/sdk/crt/math/i386/atan2_asm.s
@@ -0,0 +1,18 @@
+
+#include
+
+PUBLIC _atan2
+
+.code
+_atan2:
+ push ebp
+ mov ebp, esp
+
+ fld qword ptr [ebp + 8]
+ fld qword ptr [ebp + 16]
+ fpatan
+
+ pop ebp
+ ret
+
+END
diff --git a/lib/sdk/crt/math/i386/atan_asm.s b/lib/sdk/crt/math/i386/atan_asm.s
index 37554c940ae..9cd08752369 100644
--- a/lib/sdk/crt/math/i386/atan_asm.s
+++ b/lib/sdk/crt/math/i386/atan_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _atan
-
-.intel_syntax noprefix
+#include
+
+PUBLIC _atan
+
/* FUNCTIONS ***************************************************************/
+.code
_atan:
push ebp
@@ -48,3 +49,5 @@ _atan:
fpatan // Take the arctangent
pop ebp
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/aulldiv_asm.s b/lib/sdk/crt/math/i386/aulldiv_asm.s
index 565914eb87b..b3a08787c1c 100644
--- a/lib/sdk/crt/math/i386/aulldiv_asm.s
+++ b/lib/sdk/crt/math/i386/aulldiv_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
- .globl __aulldiv
-.intel_syntax noprefix
+#include
+
+PUBLIC __aulldiv
/* FUNCTIONS ***************************************************************/
+.code
//
// ulldiv - unsigned long divide
@@ -105,7 +106,7 @@ __aulldiv:
mov eax,DVSRHI // check to see if divisor < 4194304K
or eax,eax
- jnz short ..L1 // nope, gotta do this the hard way
+ jnz short .L1 // nope, gotta do this the hard way
mov ecx,DVSRLO // load divisor
mov eax,DVNDHI // load high word of dividend
xor edx,edx
@@ -114,24 +115,24 @@ __aulldiv:
mov eax,DVNDLO // edx:eax <- remainder:lo word of dividend
div ecx // get low order bits of quotient
mov edx,ebx // edx:eax <- quotient hi:quotient lo
- jmp short ..L2 // restore stack and return
+ jmp short .L2 // restore stack and return
//
// Here we do it the hard way. Remember, eax contains DVSRHI
//
-..L1:
+.L1:
mov ecx,eax // ecx:ebx <- divisor
mov ebx,DVSRLO
mov edx,DVNDHI // edx:eax <- dividend
mov eax,DVNDLO
-..L3:
+.L3:
shr ecx,1 // shift divisor right one bit// hi bit <- 0
rcr ebx,1
shr edx,1 // shift dividend right one bit// hi bit <- 0
rcr eax,1
or ecx,ecx
- jnz short ..L3 // loop until divisor < 4194304K
+ jnz short .L3 // loop until divisor < 4194304K
div ebx // now divide, ignore remainder
mov esi,eax // save quotient
@@ -147,7 +148,7 @@ __aulldiv:
mov eax,DVSRLO
mul esi // QUOT * DVSRLO
add edx,ecx // EDX:EAX = QUOT * DVSR
- jc short ..L4 // carry means Quotient is off by 1
+ jc short .L4 // carry means Quotient is off by 1
//
// do long compare here between original dividend and the result of the
@@ -156,13 +157,13 @@ __aulldiv:
//
cmp edx,DVNDHI // compare hi words of result and original
- ja short ..L4 // if result > original, do subtract
- jb short ..L5 // if result < original, we are ok
+ ja short .L4 // if result > original, do subtract
+ jb short .L5 // if result < original, we are ok
cmp eax,DVNDLO // hi words are equal, compare lo words
- jbe short ..L5 // if less or equal we are ok, else subtract
-..L4:
+ jbe short .L5 // if less or equal we are ok, else subtract
+.L4:
dec esi // subtract 1 from quotient
-..L5:
+.L5:
xor edx,edx // edx:eax <- quotient
mov eax,esi
@@ -171,9 +172,11 @@ __aulldiv:
// Restore the saved registers and return.
//
-..L2:
+.L2:
pop esi
pop ebx
ret 16
+
+END
diff --git a/lib/sdk/crt/math/i386/aulldvrm_asm.s b/lib/sdk/crt/math/i386/aulldvrm_asm.s
index 6f7de08f2b2..ed1d4a10832 100644
--- a/lib/sdk/crt/math/i386/aulldvrm_asm.s
+++ b/lib/sdk/crt/math/i386/aulldvrm_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl __aulldvrm
-
-.intel_syntax noprefix
+#include
+
+PUBLIC __aulldvrm
+
/* FUNCTIONS ***************************************************************/
+.code
__aulldvrm:
@@ -101,7 +102,7 @@ __aulldvrm:
mov eax,DVSRHI // check to see if divisor < 4194304K
or eax,eax
- jnz short .....L1 // nope, gotta do this the hard way
+ jnz short .L1 // nope, gotta do this the hard way
mov ecx,DVSRLO // load divisor
mov eax,DVNDHI // load high word of dividend
xor edx,edx
@@ -120,24 +121,24 @@ __aulldvrm:
mov eax,esi // set up low word of quotient
mul dword ptr DVSRLO // LOWORD(QUOT) * DVSR
add edx,ecx // EDX:EAX = QUOT * DVSR
- jmp short .....L2 // complete remainder calculation
+ jmp short .L2 // complete remainder calculation
//
// Here we do it the hard way. Remember, eax contains DVSRHI
//
-.....L1:
+.L1:
mov ecx,eax // ecx:ebx <- divisor
mov ebx,DVSRLO
mov edx,DVNDHI // edx:eax <- dividend
mov eax,DVNDLO
-.....L3:
+.L3:
shr ecx,1 // shift divisor right one bit// hi bit <- 0
rcr ebx,1
shr edx,1 // shift dividend right one bit// hi bit <- 0
rcr eax,1
or ecx,ecx
- jnz short .....L3 // loop until divisor < 4194304K
+ jnz short .L3 // loop until divisor < 4194304K
div ebx // now divide, ignore remainder
mov esi,eax // save quotient
@@ -153,7 +154,7 @@ __aulldvrm:
mov eax,DVSRLO
mul esi // QUOT * DVSRLO
add edx,ecx // EDX:EAX = QUOT * DVSR
- jc short .....L4 // carry means Quotient is off by 1
+ jc short .L4 // carry means Quotient is off by 1
//
// do long compare here between original dividend and the result of the
@@ -162,18 +163,18 @@ __aulldvrm:
//
cmp edx,DVNDHI // compare hi words of result and original
- ja short .....L4 // if result > original, do subtract
- jb short .....L5 // if result < original, we are ok
+ ja short .L4 // if result > original, do subtract
+ jb short .L5 // if result < original, we are ok
cmp eax,DVNDLO // hi words are equal, compare lo words
- jbe short .....L5 // if less or equal we are ok, else subtract
-.....L4:
+ jbe short .L5 // if less or equal we are ok, else subtract
+.L4:
dec esi // subtract 1 from quotient
sub eax,DVSRLO // subtract divisor from result
sbb edx,DVSRHI
-.....L5:
+.L5:
xor ebx,ebx // ebx:esi <- quotient
-.....L2:
+.L2:
//
// Calculate remainder by subtracting the result from the original dividend.
// Since the result is already in a register, we will do the subtract in the
@@ -202,3 +203,5 @@ __aulldvrm:
pop esi
ret 16
+
+END
diff --git a/lib/sdk/crt/math/i386/aullrem_asm.s b/lib/sdk/crt/math/i386/aullrem_asm.s
index bfcb0efb2a0..4fde84a01ba 100644
--- a/lib/sdk/crt/math/i386/aullrem_asm.s
+++ b/lib/sdk/crt/math/i386/aullrem_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl __aullrem
-
-.intel_syntax noprefix
+#include
+
+PUBLIC __aullrem
+
/* FUNCTIONS ***************************************************************/
+.code
//
// ullrem - unsigned long remainder
@@ -101,7 +102,7 @@ __aullrem:
mov eax,DVSRHI // check to see if divisor < 4194304K
or eax,eax
- jnz short ...L1 // nope, gotta do this the hard way
+ jnz short .L1 // nope, gotta do this the hard way
mov ecx,DVSRLO // load divisor
mov eax,DVNDHI // load high word of dividend
xor edx,edx
@@ -110,24 +111,24 @@ __aullrem:
div ecx // edx <- final remainder
mov eax,edx // edx:eax <- remainder
xor edx,edx
- jmp short ...L2 // restore stack and return
+ jmp short .L2 // restore stack and return
//
// Here we do it the hard way. Remember, eax contains DVSRHI
//
-...L1:
+.L1:
mov ecx,eax // ecx:ebx <- divisor
mov ebx,DVSRLO
mov edx,DVNDHI // edx:eax <- dividend
mov eax,DVNDLO
-...L3:
+.L3:
shr ecx,1 // shift divisor right one bit// hi bit <- 0
rcr ebx,1
shr edx,1 // shift dividend right one bit// hi bit <- 0
rcr eax,1
or ecx,ecx
- jnz short ...L3 // loop until divisor < 4194304K
+ jnz short .L3 // loop until divisor < 4194304K
div ebx // now divide, ignore remainder
//
@@ -142,7 +143,7 @@ __aullrem:
xchg ecx,eax // put partial product in ECX, get quotient in EAX
mul dword ptr DVSRLO
add edx,ecx // EDX:EAX = QUOT * DVSR
- jc short ...L4 // carry means Quotient is off by 1
+ jc short .L4 // carry means Quotient is off by 1
//
// do long compare here between original dividend and the result of the
@@ -151,14 +152,14 @@ __aullrem:
//
cmp edx,DVNDHI // compare hi words of result and original
- ja short ...L4 // if result > original, do subtract
- jb short ...L5 // if result < original, we're ok
+ ja short .L4 // if result > original, do subtract
+ jb short .L5 // if result < original, we're ok
cmp eax,DVNDLO // hi words are equal, compare lo words
- jbe short ...L5 // if less or equal we're ok, else subtract
-...L4:
+ jbe short .L5 // if less or equal we're ok, else subtract
+.L4:
sub eax,DVSRLO // subtract divisor from result
sbb edx,DVSRHI
-...L5:
+.L5:
//
// Calculate remainder by subtracting the result from the original dividend.
@@ -177,8 +178,10 @@ __aullrem:
// Restore the saved registers and return.
//
-...L2:
+.L2:
pop ebx
ret 16
+
+END
diff --git a/lib/sdk/crt/math/i386/aullshr_asm.s b/lib/sdk/crt/math/i386/aullshr_asm.s
index 1b9f2af9f2e..5d65f4b2eea 100644
--- a/lib/sdk/crt/math/i386/aullshr_asm.s
+++ b/lib/sdk/crt/math/i386/aullshr_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl __aullshr
-
-.intel_syntax noprefix
+#include
+
+PUBLIC __aullshr
+
/* FUNCTIONS ***************************************************************/
+.code
//
// ullshr - long shift right
@@ -65,13 +66,13 @@ __aullshr:
// depends only on the high order bit of edx).
//
cmp cl,64
- jae short ..RETZERO
+ jae short .RETZERO
//
// Handle shifts of between 0 and 31 bits
//
cmp cl, 32
- jae short ..MORE32
+ jae short .MORE32
shrd eax,edx,cl
shr edx,cl
ret
@@ -79,7 +80,7 @@ __aullshr:
//
// Handle shifts of between 32 and 63 bits
//
-..MORE32:
+.MORE32:
mov eax,edx
xor edx,edx
and cl,31
@@ -89,7 +90,9 @@ __aullshr:
//
// return 0 in edx:eax
//
-..RETZERO:
+.RETZERO:
xor eax,eax
xor edx,edx
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/ceil_asm.s b/lib/sdk/crt/math/i386/ceil_asm.s
index aad69114f5a..0b6d2ffb7b3 100644
--- a/lib/sdk/crt/math/i386/ceil_asm.s
+++ b/lib/sdk/crt/math/i386/ceil_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _ceil
-.intel_syntax noprefix
+#include
+
+PUBLIC _ceil
/* FUNCTIONS ***************************************************************/
+.code
_ceil:
push ebp
@@ -47,7 +48,7 @@ _ceil:
fld qword ptr [ebp+8] // Load real from stack
fstcw [ebp-2] // Save control word
fclex // Clear exceptions
- mov word ptr [ebp-4],0xb63 // Rounding control word
+ mov word ptr [ebp-4], HEX(0b63) // Rounding control word
fldcw [ebp-4] // Set new rounding control
frndint // Round to integer
fclex // Clear exceptions
@@ -55,3 +56,5 @@ _ceil:
mov esp,ebp // Deallocate temporary space
pop ebp
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/ceilf.S b/lib/sdk/crt/math/i386/ceilf.S
index 9eee272ecb3..79d66ce1cf2 100644
--- a/lib/sdk/crt/math/i386/ceilf.S
+++ b/lib/sdk/crt/math/i386/ceilf.S
@@ -3,53 +3,34 @@
* This file is part of the w64 mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
-#include <_mingw_mac.h>
- .file "ceilf.S"
- .text
- .align 4
-.globl __MINGW_USYMBOL(ceilf)
- .def __MINGW_USYMBOL(ceilf); .scl 2; .type 32; .endef
-__MINGW_USYMBOL(ceilf):
-#ifdef _WIN64
- subq $24,%rsp
- movss %xmm0,8(%rsp)
- flds 8(%rsp)
+#include
- fstcw 4(%rsp) /* store fpu control word */
+.code
+.align 4
- movl $0x0800,%edx /* round towards +oo */
- orl 4(%rsp),%edx
- andl $0xfbff,%edx
- movl %edx,(%rsp)
- fldcw (%rsp) /* load modified control word */
+PUBLIC _ceilf
+_ceilf:
- frndint /* round */
+ fld dword ptr [esp + 4]
+ sub esp, 8
- fldcw 4(%rsp) /* restore original control word */
- fstps 8(%rsp)
- movss 8(%rsp),%xmm0
- addq $24,%rsp
- ret
-#else
- flds 4(%esp)
- subl $8,%esp
-
- fstcw 4(%esp) /* store fpu control word */
+ fstcw [esp + 4] /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
- movl $0x0800,%edx /* round towards +oo */
- orl 4(%esp),%edx
- andl $0xfbff,%edx
- movl %edx,(%esp)
- fldcw (%esp) /* load modified control word */
+ mov edx, [esp + 4]
+ or edx, HEX(0800) /* round towards +oo */
+ and edx, HEX(fbff)
+ mov [esp], edx
+ fldcw [esp] /* load modified control word */
frndint /* round */
- fldcw 4(%esp) /* restore original control word */
+ fldcw [esp + 4] /* restore original control word */
- addl $8,%esp
+ add esp, 8
ret
-#endif
+
+END
diff --git a/lib/sdk/crt/math/i386/cos_asm.s b/lib/sdk/crt/math/i386/cos_asm.s
index b1c6ada49b2..7732fe78734 100644
--- a/lib/sdk/crt/math/i386/cos_asm.s
+++ b/lib/sdk/crt/math/i386/cos_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _cos
-.intel_syntax noprefix
+#include
+
+PUBLIC _cos
/* FUNCTIONS ***************************************************************/
+.code
_cos:
push ebp
@@ -47,3 +48,5 @@ _cos:
fcos // Take the cosine
pop ebp
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/exp_asm.s b/lib/sdk/crt/math/i386/exp_asm.s
new file mode 100644
index 00000000000..3dd5be060b9
--- /dev/null
+++ b/lib/sdk/crt/math/i386/exp_asm.s
@@ -0,0 +1,29 @@
+
+#include
+
+PUBLIC _exp
+
+/* FUNCTIONS ***************************************************************/
+.code
+
+_exp:
+ push ebp
+ mov ebp, esp
+
+ fld qword ptr [ebp + 8]
+ fldl2e
+ fmul st, st(1)
+ fst st(1)
+ frndint
+ fxch st(1)
+ fsub st, st(1)
+ f2xm1
+ fld1
+ faddp st(1), st
+ fscale
+ fstp st(1)
+
+ pop ebp
+ ret
+
+END
diff --git a/lib/sdk/crt/math/i386/fabs_asm.s b/lib/sdk/crt/math/i386/fabs_asm.s
index 5c6ce9214ef..c121f5205db 100644
--- a/lib/sdk/crt/math/i386/fabs_asm.s
+++ b/lib/sdk/crt/math/i386/fabs_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _fabs
-
-.intel_syntax noprefix
+#include
+
+PUBLIC _fabs
+
/* FUNCTIONS ***************************************************************/
+.code
_fabs:
push ebp
@@ -47,3 +48,5 @@ _fabs:
fabs // Take the absolute value
pop ebp
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/floor_asm.s b/lib/sdk/crt/math/i386/floor_asm.s
index f03c85cb4e8..7a2ed174eb3 100644
--- a/lib/sdk/crt/math/i386/floor_asm.s
+++ b/lib/sdk/crt/math/i386/floor_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _floor
-
-.intel_syntax noprefix
+#include
+
+PUBLIC _floor
+
/* FUNCTIONS ***************************************************************/
+.code
_floor:
push ebp
@@ -47,7 +48,7 @@ _floor:
fld qword ptr [ebp+8] // Load real from stack
fstcw [ebp-2] // Save control word
fclex // Clear exceptions
- mov word ptr [ebp-4],0x763 // Rounding control word
+ mov word ptr [ebp-4], HEX(0763) // Rounding control word
fldcw [ebp-4] // Set new rounding control
frndint // Round to integer
fclex // Clear exceptions
@@ -55,3 +56,5 @@ _floor:
mov esp,ebp
pop ebp
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/floorf.S b/lib/sdk/crt/math/i386/floorf.S
index eec073b2376..99ef5522038 100644
--- a/lib/sdk/crt/math/i386/floorf.S
+++ b/lib/sdk/crt/math/i386/floorf.S
@@ -7,57 +7,34 @@
* Removed header file dependency for use in libmingwex.a by
* Danny Smith
*/
-#include <_mingw_mac.h>
- .file "floorf.S"
- .text
-#ifdef _WIN64
- .align 8
-#else
- .align 4
-#endif
-.globl __MINGW_USYMBOL(floorf)
- .def __MINGW_USYMBOL(floorf); .scl 2; .type 32; .endef
-__MINGW_USYMBOL(floorf):
-#ifdef _WIN64
- subq $24,%rsp
- movss %xmm0,8(%rsp)
- flds 8(%rsp)
+#include
- fstcw 4(%rsp) /* store fpu control word */
- movl $0x400,%edx /* round towards -oo */
- orl 4(%rsp),%edx
- andl $0xf7ff,%edx
- movl %edx,(%rsp)
- fldcw (%rsp) /* load modified control word */
+.code
+.align 4
- frndint /* round */
+PUBLIC _floorf
+_floorf:
- fldcw 4(%rsp) /* restore original control word */
+ fld dword ptr [esp + 4]
+ sub esp, 8
- fstps 8(%rsp)
- movss 8(%rsp),%xmm0
- addq $24,%rsp
- ret
-#else
- flds 4(%esp)
- subl $8,%esp
-
- fstcw 4(%esp) /* store fpu control word */
+ fstcw [esp + 4] /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
- movl $0x400,%edx /* round towards -oo */
- orl 4(%esp),%edx
- andl $0xf7ff,%edx
- movl %edx,(%esp)
- fldcw (%esp) /* load modified control word */
+ mov edx, [esp + 4]
+ or edx, HEX(0400) /* round towards -oo */
+ and edx, HEX(0f7ff)
+ mov [esp], edx
+ fldcw [esp] /* load modified control word */
frndint /* round */
- fldcw 4(%esp) /* restore original control word */
+ fldcw [esp + 4] /* restore original control word */
- addl $8,%esp
+ add esp, 8
ret
-#endif
+
+END
diff --git a/lib/sdk/crt/math/i386/fmod_asm.s b/lib/sdk/crt/math/i386/fmod_asm.s
new file mode 100644
index 00000000000..44be4c0b24a
--- /dev/null
+++ b/lib/sdk/crt/math/i386/fmod_asm.s
@@ -0,0 +1,26 @@
+
+#include
+
+PUBLIC _fmod
+
+/* FUNCTIONS ***************************************************************/
+.code
+
+_fmod:
+ push ebp
+ mov ebp, esp
+
+ fld qword ptr [ebp + 8]
+ fld qword ptr [ebp + 16]
+ fxch st(1)
+l1:
+ fprem
+ fstsw ax
+ sahf
+ jp l1
+ fstp st(1)
+
+ pop ebp
+ ret
+
+END
diff --git a/lib/sdk/crt/math/i386/fmodf_asm.s b/lib/sdk/crt/math/i386/fmodf_asm.s
new file mode 100644
index 00000000000..1a06ef98671
--- /dev/null
+++ b/lib/sdk/crt/math/i386/fmodf_asm.s
@@ -0,0 +1,26 @@
+
+#include
+
+PUBLIC _fmodf
+
+/* FUNCTIONS ***************************************************************/
+.code
+
+_fmodf:
+ push ebp
+ mov ebp, esp
+
+ fld dword ptr [esp + 4]
+ fld dword ptr [esp + 8]
+ fxch st(1)
+l1:
+ fprem
+ fstsw ax
+ sahf
+ jp l1
+ fstp st(1)
+
+ pop ebp
+ ret
+
+END
diff --git a/lib/sdk/crt/math/i386/ftol2_asm.s b/lib/sdk/crt/math/i386/ftol2_asm.s
new file mode 100644
index 00000000000..12f55010312
--- /dev/null
+++ b/lib/sdk/crt/math/i386/ftol2_asm.s
@@ -0,0 +1,28 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Run-Time Library
+ * FILE: lib/rtl/i386/ftol2.S
+ * PROGRAMER:
+ *
+ */
+
+#include
+
+EXTERN __ftol:PROC
+PUBLIC __ftol2
+PUBLIC __ftol2_sse
+
+/* FUNCTIONS ***************************************************************/
+.code
+
+/*
+ * This routine is called by MSVC-generated code to convert from floating point
+ * to integer representation. The floating point number to be converted is
+ * on the top of the floating point stack.
+ */
+__ftol2:
+__ftol2_sse:
+ jmp __ftol
+
+END
diff --git a/lib/sdk/crt/math/i386/ftol_asm.s b/lib/sdk/crt/math/i386/ftol_asm.s
index 4e1445a9988..9942f389f88 100644
--- a/lib/sdk/crt/math/i386/ftol_asm.s
+++ b/lib/sdk/crt/math/i386/ftol_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl __ftol
-
-.intel_syntax noprefix
+#include
+
+PUBLIC __ftol
+
/* FUNCTIONS ***************************************************************/
+.code
/*
* This routine is called by MSVC-generated code to convert from floating point
@@ -54,7 +55,7 @@ __ftol:
fstcw [ebp-2]
wait
mov ax, [ebp-2]
- or ah, 0xC
+ or ah, 12
mov [ebp-4], ax
fldcw [ebp-4]
@@ -71,3 +72,5 @@ __ftol:
/* Remove stack frame and return*/
leave
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/log10_asm.s b/lib/sdk/crt/math/i386/log10_asm.s
index 71731816429..a627ace1090 100644
--- a/lib/sdk/crt/math/i386/log10_asm.s
+++ b/lib/sdk/crt/math/i386/log10_asm.s
@@ -7,12 +7,13 @@
* PROGRAMER: Magnus Olsen (magnus@greatlord.com)
*
*/
-
-.globl _log10
-.intel_syntax noprefix
+#include
+
+PUBLIC _log10
/* FUNCTIONS ***************************************************************/
+.code
_log10:
@@ -25,3 +26,4 @@ _log10:
pop ebp
ret
+END
diff --git a/lib/sdk/crt/math/i386/log_asm.s b/lib/sdk/crt/math/i386/log_asm.s
index 0d98279ed41..472202fee92 100644
--- a/lib/sdk/crt/math/i386/log_asm.s
+++ b/lib/sdk/crt/math/i386/log_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _log
-
-.intel_syntax noprefix
+#include
+
+PUBLIC _log
+
/* FUNCTIONS ***************************************************************/
+.code
_log:
push ebp
@@ -49,3 +50,5 @@ _log:
fyl2x // Compute the natural log(x)
pop ebp
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/pow_asm.s b/lib/sdk/crt/math/i386/pow_asm.s
index 0b79aa5883e..f418cd38c6e 100644
--- a/lib/sdk/crt/math/i386/pow_asm.s
+++ b/lib/sdk/crt/math/i386/pow_asm.s
@@ -19,41 +19,53 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-/* Reacros modifications */
+/* Reactos modifications */
+#include
+
#define ALIGNARG(log2) log2
#define ASM_TYPE_DIRECTIVE(name,typearg)
#define ASM_SIZE_DIRECTIVE(name)
#define cfi_adjust_cfa_offset(x)
-#define ENTRY(x)
-#define END(x)
-.global _pow
- .text
+PUBLIC _pow
+
+.data
+ASSUME nothing
.align ALIGNARG(4)
ASM_TYPE_DIRECTIVE(infinity,@object)
+
inf_zero:
infinity:
- .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+ .byte 0, 0, 0, 0, 0, 0, HEX(f0), HEX(7f)
ASM_SIZE_DIRECTIVE(infinity)
ASM_TYPE_DIRECTIVE(zero,@object)
-zero: .double 0.0
+zero:
+ .double 0.0
ASM_SIZE_DIRECTIVE(zero)
ASM_TYPE_DIRECTIVE(minf_mzero,@object)
+
minf_mzero:
minfinity:
- .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
+ .byte 0, 0, 0, 0, 0, 0, HEX(f0), HEX(ff)
+
mzero:
- .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ .byte 0, 0, 0, 0, 0, 0, 0, HEX(80)
ASM_SIZE_DIRECTIVE(minf_mzero)
ASM_TYPE_DIRECTIVE(one,@object)
-one: .double 1.0
+
+one:
+ .double 1.0
ASM_SIZE_DIRECTIVE(one)
ASM_TYPE_DIRECTIVE(limit,@object)
-limit: .double 0.29
+
+limit:
+ .double 0.29
ASM_SIZE_DIRECTIVE(limit)
ASM_TYPE_DIRECTIVE(p63,@object)
-p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
+
+p63:
+ .byte 0, 0, 0, 0, 0, 0, HEX(e0), HEX(43)
ASM_SIZE_DIRECTIVE(p63)
#ifdef PIC
@@ -61,308 +73,309 @@ p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
#else
#define MO(op) op
-#define MOX(op,x,f) op(,x,f)
+#define MOX(op,x,f) op[x*f]
#endif
- .text
+.code
_pow:
-ENTRY(__ieee754_pow)
- fldl 12(%esp) // y
+ fld qword ptr [esp + 12] // y
fxam
#ifdef PIC
LOAD_PIC_REG (cx)
#endif
- fnstsw
- movb %ah, %dl
- andb $0x45, %ah
- cmpb $0x40, %ah // is y == 0 ?
- je 11f
+ fnstsw ax
+ mov dl, ah
+ and ah, HEX(045)
+ cmp ah, HEX(040) // is y == 0 ?
+ je L11
- cmpb $0x05, %ah // is y == inf ?
- je 12f
+ cmp ah, 5 // is y == inf ?
+ je L12
- cmpb $0x01, %ah // is y == NaN ?
- je 30f
+ cmp ah, 1 // is y == NaN ?
+ je L30
- fldl 4(%esp) // x : y
+ fld qword ptr [esp + 4] // x : y
- subl $8,%esp
+ sub esp, 8
cfi_adjust_cfa_offset (8)
fxam
- fnstsw
- movb %ah, %dh
- andb $0x45, %ah
- cmpb $0x40, %ah
- je 20f // x is 0
+ fnstsw ax
+ mov dh, ah
+ and ah, HEX(45)
+ cmp ah, HEX(040)
+ je L20 // x is 0
- cmpb $0x05, %ah
- je 15f // x is inf
+ cmp ah, 5
+ je L15 // x is inf
- fxch // y : x
+ fxch st(1) // y : x
/* fistpll raises invalid exception for |y| >= 1L<<63. */
- fld %st // y : y : x
+ fld st // y : y : x
fabs // |y| : y : x
- fcompl MO(p63) // y : x
- fnstsw
+ fcomp qword ptr MO(p63) // y : x
+ fnstsw ax
sahf
- jnc 2f
+ jnc L2
/* First see whether `y' is a natural number. In this case we
can use a more precise algorithm. */
- fld %st // y : y : x
- fistpll (%esp) // y : x
- fildll (%esp) // int(y) : y : x
- fucomp %st(1) // y : x
- fnstsw
+ fld st // y : y : x
+ fistp qword ptr [esp] // y : x
+ fild qword ptr [esp] // int(y) : y : x
+ fucomp st(1) // y : x
+ fnstsw ax
sahf
- jne 2f
+ jne L2
/* OK, we have an integer value for y. */
- popl %eax
+ pop eax
cfi_adjust_cfa_offset (-4)
- popl %edx
+ pop edx
cfi_adjust_cfa_offset (-4)
- orl $0, %edx
- fstp %st(0) // x
- jns 4f // y >= 0, jump
- fdivrl MO(one) // 1/x (now referred to as x)
- negl %eax
- adcl $0, %edx
- negl %edx
-4: fldl MO(one) // 1 : x
- fxch
+ or edx, 0
+ fstp st // x
+ jns L4 // y >= 0, jump
+ fdivr qword ptr MO(one) // 1/x (now referred to as x)
+ neg eax
+ adc edx, 0
+ neg edx
+L4: fld qword ptr MO(one) // 1 : x
+ fxch st(1)
-6: shrdl $1, %edx, %eax
- jnc 5f
- fxch
- fmul %st(1) // x : ST*x
- fxch
-5: fmul %st(0), %st // x*x : ST*x
- shrl $1, %edx
- movl %eax, %ecx
- orl %edx, %ecx
- jnz 6b
- fstp %st(0) // ST*x
+L6: shrd eax, edx, 1
+ jnc L5
+ fxch st(1)
+ fmul st, st(1) // x : ST*x
+ fxch st(1)
+L5: fmul st, st // x*x : ST*x
+ shr edx, 1
+ mov ecx, eax
+ or ecx, edx
+ jnz L6
+ fstp st // ST*x
ret
/* y is NAN */
-30: fldl 4(%esp) // x : y
- fldl MO(one) // 1.0 : x : y
- fucomp %st(1) // x : y
- fnstsw
+L30:
+ fld qword ptr [esp + 4] // x : y
+ fld qword ptr MO(one) // 1.0 : x : y
+ fucomp st(1) // x : y
+ fnstsw ax
sahf
- je 31f
- fxch // y : x
-31: fstp %st(1)
+ je L31
+ fxch st(1) // y : x
+L31:fstp st(1)
ret
cfi_adjust_cfa_offset (8)
.align ALIGNARG(4)
-2: /* y is a real number. */
- fxch // x : y
- fldl MO(one) // 1.0 : x : y
- fldl MO(limit) // 0.29 : 1.0 : x : y
- fld %st(2) // x : 0.29 : 1.0 : x : y
- fsub %st(2) // x-1 : 0.29 : 1.0 : x : y
+L2: /* y is a real number. */
+ fxch st(1) // x : y
+ fld qword ptr MO(one) // 1.0 : x : y
+ fld qword ptr MO(limit) // 0.29 : 1.0 : x : y
+ fld st(2) // x : 0.29 : 1.0 : x : y
+ fsub st, st(2) // x-1 : 0.29 : 1.0 : x : y
fabs // |x-1| : 0.29 : 1.0 : x : y
fucompp // 1.0 : x : y
- fnstsw
- fxch // x : 1.0 : y
+ fnstsw ax
+ fxch st(1) // x : 1.0 : y
sahf
- ja 7f
- fsub %st(1) // x-1 : 1.0 : y
+ ja L7
+ fsub st, st(1) // x-1 : 1.0 : y
fyl2xp1 // log2(x) : y
- jmp 8f
+ jmp L8
-7: fyl2x // log2(x) : y
-8: fmul %st(1) // y*log2(x) : y
- fst %st(1) // y*log2(x) : y*log2(x)
+L7: fyl2x // log2(x) : y
+L8: fmul st, st(1) // y*log2(x) : y
+ fst st(1) // y*log2(x) : y*log2(x)
frndint // int(y*log2(x)) : y*log2(x)
- fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
+ fsubr st(1), st // int(y*log2(x)) : fract(y*log2(x))
fxch // fract(y*log2(x)) : int(y*log2(x))
f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x))
- faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x))
+ fadd qword ptr MO(one) // 2^fract(y*log2(x)) : int(y*log2(x))
fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
- addl $8, %esp
+ add esp, 8
cfi_adjust_cfa_offset (-8)
- fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
+ fstp st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
ret
// pow(x,0) = 1
.align ALIGNARG(4)
-11: fstp %st(0) // pop y
- fldl MO(one)
+L11:fstp st(0) // pop y
+ fld qword ptr MO(one)
ret
// y == inf
.align ALIGNARG(4)
-12: fstp %st(0) // pop y
- fldl MO(one) // 1
- fldl 4(%esp) // x : 1
+L12: fstp st(0) // pop y
+ fld qword ptr MO(one) // 1
+ fld qword ptr [esp + 4] // x : 1
fabs // abs(x) : 1
fucompp // < 1, == 1, or > 1
- fnstsw
- andb $0x45, %ah
- cmpb $0x45, %ah
- je 13f // jump if x is NaN
+ fnstsw ax
+ and ah, HEX(45)
+ cmp ah, HEX(45)
+ je L13 // jump if x is NaN
- cmpb $0x40, %ah
- je 14f // jump if |x| == 1
+ cmp ah, HEX(40)
+ je L14 // jump if |x| == 1
- shlb $1, %ah
- xorb %ah, %dl
- andl $2, %edx
- fldl MOX(inf_zero, %edx, 4)
+ shl ah, 1
+ xor dl, ah
+ and edx, 2
+ fld qword ptr MOX(inf_zero, edx, 4)
ret
.align ALIGNARG(4)
-14: fldl MO(one)
+L14:fld qword ptr MO(one)
ret
.align ALIGNARG(4)
-13: fldl 4(%esp) // load x == NaN
+L13:fld qword ptr [esp + 4] // load x == NaN
ret
cfi_adjust_cfa_offset (8)
.align ALIGNARG(4)
// x is inf
-15: fstp %st(0) // y
- testb $2, %dh
- jz 16f // jump if x == +inf
+L15: fstp st(0) // y
+ test dh, 2
+ jz L16 // jump if x == +inf
// We must find out whether y is an odd integer.
- fld %st // y : y
- fistpll (%esp) // y
- fildll (%esp) // int(y) : y
+ fld st // y : y
+ fistp qword ptr [esp] // y
+ fild qword ptr [esp] // int(y) : y
fucompp //
- fnstsw
+ fnstsw ax
sahf
- jne 17f
+ jne L17
// OK, the value is an integer, but is the number of bits small
// enough so that all are coming from the mantissa?
- popl %eax
+ pop eax
cfi_adjust_cfa_offset (-4)
- popl %edx
+ pop edx
cfi_adjust_cfa_offset (-4)
- andb $1, %al
- jz 18f // jump if not odd
- movl %edx, %eax
- orl %edx, %edx
- jns 155f
- negl %eax
-155: cmpl $0x00200000, %eax
- ja 18f // does not fit in mantissa bits
+ and al, 1
+ jz L18 // jump if not odd
+ mov eax, edx
+ or edx, edx
+ jns L155
+ neg eax
+L155:
+ cmp eax, HEX(000200000)
+ ja L18 // does not fit in mantissa bits
// It's an odd integer.
- shrl $31, %edx
- fldl MOX(minf_mzero, %edx, 8)
+ shr edx, 31
+ fld qword ptr MOX(minf_mzero, edx, 8)
ret
cfi_adjust_cfa_offset (8)
.align ALIGNARG(4)
-16: fcompl MO(zero)
- addl $8, %esp
+L16:fcomp qword ptr MO(zero)
+ add esp, 8
cfi_adjust_cfa_offset (-8)
- fnstsw
- shrl $5, %eax
- andl $8, %eax
- fldl MOX(inf_zero, %eax, 1)
+ fnstsw ax
+ shr eax, 5
+ and eax, 8
+ fld qword ptr MOX(inf_zero, eax, 1)
ret
cfi_adjust_cfa_offset (8)
.align ALIGNARG(4)
-17: shll $30, %edx // sign bit for y in right position
- addl $8, %esp
+L17: shl ecx, 30 // sign bit for y in right position
+ add esp, 8
cfi_adjust_cfa_offset (-8)
-18: shrl $31, %edx
- fldl MOX(inf_zero, %edx, 8)
+L18: shr edx, 31
+ fld qword ptr MOX(inf_zero, edx, 8)
ret
cfi_adjust_cfa_offset (8)
.align ALIGNARG(4)
// x is 0
-20: fstp %st(0) // y
- testb $2, %dl
- jz 21f // y > 0
+L20: fstp st(0) // y
+ test dl, 2
+ jz L21 // y > 0
// x is 0 and y is < 0. We must find out whether y is an odd integer.
- testb $2, %dh
- jz 25f
+ test dh, 2
+ jz L25
- fld %st // y : y
- fistpll (%esp) // y
- fildll (%esp) // int(y) : y
+ fld st // y : y
+ fistp qword ptr [esp] // y
+ fild qword ptr [esp] // int(y) : y
fucompp //
- fnstsw
+ fnstsw ax
sahf
- jne 26f
+ jne L26
// OK, the value is an integer, but is the number of bits small
// enough so that all are coming from the mantissa?
- popl %eax
+ pop eax
cfi_adjust_cfa_offset (-4)
- popl %edx
+ pop edx
cfi_adjust_cfa_offset (-4)
- andb $1, %al
- jz 27f // jump if not odd
- cmpl $0xffe00000, %edx
- jbe 27f // does not fit in mantissa bits
+ and al, 1
+ jz L27 // jump if not odd
+ cmp edx, HEX(0ffe00000)
+ jbe L27 // does not fit in mantissa bits
// It's an odd integer.
// Raise divide-by-zero exception and get minus infinity value.
- fldl MO(one)
- fdivl MO(zero)
+ fld qword ptr MO(one)
+ fdiv qword ptr MO(zero)
fchs
ret
cfi_adjust_cfa_offset (8)
-25: fstp %st(0)
-26: addl $8, %esp
+L25: fstp st(0)
+L26: add esp, 8
cfi_adjust_cfa_offset (-8)
-27: // Raise divide-by-zero exception and get infinity value.
- fldl MO(one)
- fdivl MO(zero)
+L27: // Raise divide-by-zero exception and get infinity value.
+ fld qword ptr MO(one)
+ fdiv qword ptr MO(zero)
ret
cfi_adjust_cfa_offset (8)
.align ALIGNARG(4)
// x is 0 and y is > 0. We must find out whether y is an odd integer.
-21: testb $2, %dh
- jz 22f
+L21:test dh, 2
+ jz L22
- fld %st // y : y
- fistpll (%esp) // y
- fildll (%esp) // int(y) : y
+ fld st // y : y
+ fistp qword ptr [esp] // y
+ fild qword ptr [esp] // int(y) : y
fucompp //
- fnstsw
+ fnstsw ax
sahf
- jne 23f
+ jne L23
// OK, the value is an integer, but is the number of bits small
// enough so that all are coming from the mantissa?
- popl %eax
+ pop eax
cfi_adjust_cfa_offset (-4)
- popl %edx
+ pop edx
cfi_adjust_cfa_offset (-4)
- andb $1, %al
- jz 24f // jump if not odd
- cmpl $0xffe00000, %edx
- jae 24f // does not fit in mantissa bits
+ and al, 1
+ jz L24 // jump if not odd
+ cmp edx, HEX(0ffe00000)
+ jae L24 // does not fit in mantissa bits
// It's an odd integer.
- fldl MO(mzero)
+ fld qword ptr MO(mzero)
ret
cfi_adjust_cfa_offset (8)
-22: fstp %st(0)
-23: addl $8, %esp // Don't use 2 x pop
+L22: fstp st(0)
+L23: add esp, 8 // Don't use 2 x pop
cfi_adjust_cfa_offset (-8)
-24: fldl MO(zero)
+L24: fld qword ptr MO(zero)
ret
-END(__ieee754_pow)
+END
diff --git a/lib/sdk/crt/math/i386/sin_asm.s b/lib/sdk/crt/math/i386/sin_asm.s
index 39791a3e989..4a27af804b2 100644
--- a/lib/sdk/crt/math/i386/sin_asm.s
+++ b/lib/sdk/crt/math/i386/sin_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _sin
-.intel_syntax noprefix
+#include
+
+PUBLIC _sin
/* FUNCTIONS ***************************************************************/
+.code
_sin:
push ebp // Save register bp
@@ -47,3 +48,5 @@ _sin:
fsin // Take the sine
pop ebp // Restore register bp
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/sqrt_asm.s b/lib/sdk/crt/math/i386/sqrt_asm.s
index c953a0350e9..3385204d572 100644
--- a/lib/sdk/crt/math/i386/sqrt_asm.s
+++ b/lib/sdk/crt/math/i386/sqrt_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _sqrt
-
-.intel_syntax noprefix
+#include
+
+PUBLIC _sqrt
+
/* FUNCTIONS ***************************************************************/
+.code
_sqrt:
push ebp
@@ -47,3 +48,5 @@ _sqrt:
fsqrt // Take the square root
pop ebp
ret
+
+END
diff --git a/lib/sdk/crt/math/i386/tan_asm.s b/lib/sdk/crt/math/i386/tan_asm.s
index 34af2614f89..3b64b360f17 100644
--- a/lib/sdk/crt/math/i386/tan_asm.s
+++ b/lib/sdk/crt/math/i386/tan_asm.s
@@ -33,12 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _tan
-
-.intel_syntax noprefix
+#include
+
+PUBLIC _tan
+
/* FUNCTIONS ***************************************************************/
+.code
_tan:
push ebp
@@ -50,3 +51,5 @@ _tan:
mov esp,ebp // Deallocate temporary space
pop ebp
ret
+
+END
diff --git a/lib/sdk/crt/mbstring/mbstrlen.c b/lib/sdk/crt/mbstring/mbstrlen.c
index c600bd1029b..9b324668458 100644
--- a/lib/sdk/crt/mbstring/mbstrlen.c
+++ b/lib/sdk/crt/mbstring/mbstrlen.c
@@ -12,7 +12,12 @@
#include
#include
+#ifdef _LIBCNT_
+unsigned short *NlsLeadByteInfo;
+#define isleadbyte(c) NlsLeadByteInfo[c]
+#else
int isleadbyte(int byte);
+#endif
/*
* @implemented
diff --git a/lib/sdk/crt/mem/i386/memchr_asm.s b/lib/sdk/crt/mem/i386/memchr_asm.s
index f6e8037fc31..40cd3dc8cef 100644
--- a/lib/sdk/crt/mem/i386/memchr_asm.s
+++ b/lib/sdk/crt/mem/i386/memchr_asm.s
@@ -5,28 +5,34 @@
* FILE: lib/sdk/crt/mem/i386/memchr.s
*/
+#include
+#include
+
/*
* void* memchr(const void* s, int c, size_t n)
*/
-.globl _memchr
+PUBLIC _memchr
+.code
_memchr:
- push %ebp
- mov %esp,%ebp
- push %edi
- mov 0x8(%ebp),%edi
- mov 0xc(%ebp),%eax
- mov 0x10(%ebp),%ecx
+ push ebp
+ mov ebp, esp
+ push edi
+ mov edi, [ebp + 8]
+ mov eax, [ebp + 12]
+ mov ecx, [ebp + 16]
cld
- jecxz .Lnotfound
- repne scasb
- je .Lfound
+ jecxz .Lnotfound
+ repne scasb
+ je .Lfound
.Lnotfound:
- mov $1,%edi
+ mov edi, 1
.Lfound:
- mov %edi,%eax
- dec %eax
- pop %edi
+ mov eax, edi
+ dec eax
+ pop edi
leave
ret
+
+END
diff --git a/lib/sdk/crt/mem/i386/memcpy_asm.s b/lib/sdk/crt/mem/i386/memcpy_asm.s
index 36a1a079513..e69de29bb2d 100644
--- a/lib/sdk/crt/mem/i386/memcpy_asm.s
+++ b/lib/sdk/crt/mem/i386/memcpy_asm.s
@@ -1,114 +0,0 @@
-/*
- * void *memcpy (void *to, const void *from, size_t count)
- *
- * NOTE: This code is a duplicate of memmove function from memmove_asm.s
- */
-
-.globl _memcpy
-
-_memcpy:
- push %ebp
- mov %esp,%ebp
-
- push %esi
- push %edi
-
- mov 8(%ebp),%edi
- mov 12(%ebp),%esi
- mov 16(%ebp),%ecx
-
- cmp %esi,%edi
- jbe .CopyUp
- mov %ecx,%eax
- add %esi,%eax
- cmp %eax,%edi
- jb .CopyDown
-
-.CopyUp:
- cld
-
- cmp $16,%ecx
- jb .L1
- mov %ecx,%edx
- test $3,%edi
- je .L2
-/*
- * Make the destination dword aligned
- */
- mov %edi,%ecx
- and $3,%ecx
- sub $5,%ecx
- not %ecx
- sub %ecx,%edx
- rep movsb
- mov %edx,%ecx
-.L2:
- shr $2,%ecx
- rep movsl
- mov %edx,%ecx
- and $3,%ecx
-.L1:
- test %ecx,%ecx
- je .L3
- rep movsb
-.L3:
- mov 8(%ebp),%eax
- pop %edi
- pop %esi
- leave
- ret
-
-.CopyDown:
- std
-
- add %ecx,%edi
- add %ecx,%esi
-
- cmp $16,%ecx
- jb .L4
- mov %ecx,%edx
- test $3,%edi
- je .L5
-
-/*
- * Make the destination dword aligned
- */
- mov %edi,%ecx
- and $3,%ecx
- sub %ecx,%edx
- dec %esi
- dec %edi
- rep movsb
- mov %edx,%ecx
-
- sub $3,%esi
- sub $3,%edi
-.L6:
- shr $2,%ecx
- rep movsl
- mov %edx,%ecx
- and $3,%ecx
- je .L7
- add $3,%esi
- add $3,%edi
-.L8:
- rep movsb
-.L7:
- cld
- mov 8(%ebp),%eax
- pop %edi
- pop %esi
- leave
- ret
-.L5:
- sub $4,%edi
- sub $4,%esi
- jmp .L6
-
-.L4:
- test %ecx,%ecx
- je .L7
- dec %esi
- dec %edi
- jmp .L8
-
diff --git a/lib/sdk/crt/mem/i386/memmove_asm.s b/lib/sdk/crt/mem/i386/memmove_asm.s
index e27006e3bed..476f843befe 100644
--- a/lib/sdk/crt/mem/i386/memmove_asm.s
+++ b/lib/sdk/crt/mem/i386/memmove_asm.s
@@ -1,114 +1,120 @@
/*
- * void *memmove (void *to, const void *from, size_t count)
+ * void *memcpy (void *to, const void *from, size_t count)
*
- * NOTE: This code is duplicated in memcpy_asm.s
*/
-.globl _memmove
+#include
+#include
+PUBLIC _memcpy
+PUBLIC _memmove
+.code
+
+_memcpy:
_memmove:
- push %ebp
- mov %esp,%ebp
+ push ebp
+ mov ebp, esp
- push %esi
- push %edi
+ push esi
+ push edi
- mov 8(%ebp),%edi
- mov 12(%ebp),%esi
- mov 16(%ebp),%ecx
+ mov edi, [ebp + 8]
+ mov esi, [ebp + 12]
+ mov ecx, [ebp + 16]
- cmp %esi,%edi
+ cmp edi, esi
jbe .CopyUp
- mov %ecx,%eax
- add %esi,%eax
- cmp %eax,%edi
- jb .CopyDown
-
+ mov eax, ecx
+ add eax, esi
+ cmp edi, eax
+ jb .CopyDown
+
.CopyUp:
cld
- cmp $16,%ecx
- jb .L1
- mov %ecx,%edx
- test $3,%edi
- je .L2
+ cmp ecx, 16
+ jb .L1
+ mov edx, ecx
+ test edi, 3
+ je .L2
/*
* Make the destination dword aligned
*/
- mov %edi,%ecx
- and $3,%ecx
- sub $5,%ecx
- not %ecx
- sub %ecx,%edx
- rep movsb
- mov %edx,%ecx
+ mov ecx, edi
+ and ecx, 3
+ sub ecx, 5
+ not ecx
+ sub edx, ecx
+ rep movsb
+ mov ecx, edx
.L2:
- shr $2,%ecx
- rep movsl
- mov %edx,%ecx
- and $3,%ecx
+ shr ecx, 2
+ rep movsd
+ mov ecx, edx
+ and ecx, 3
.L1:
- test %ecx,%ecx
- je .L3
- rep movsb
+ test ecx, ecx
+ je .L3
+ rep movsb
.L3:
- mov 8(%ebp),%eax
- pop %edi
- pop %esi
+ mov eax, [ebp + 8]
+ pop edi
+ pop esi
leave
ret
.CopyDown:
- std
+ std
- add %ecx,%edi
- add %ecx,%esi
+ add edi, ecx
+ add esi, ecx
- cmp $16,%ecx
- jb .L4
- mov %ecx,%edx
- test $3,%edi
- je .L5
+ cmp ecx, 16
+ jb .L4
+ mov edx, ecx
+ test edi, 3
+ je .L5
/*
* Make the destination dword aligned
*/
- mov %edi,%ecx
- and $3,%ecx
- sub %ecx,%edx
- dec %esi
- dec %edi
- rep movsb
- mov %edx,%ecx
+ mov ecx, edi
+ and ecx, 3
+ sub edx, ecx
+ dec esi
+ dec edi
+ rep movsb
+ mov ecx, edx
- sub $3,%esi
- sub $3,%edi
+ sub esi, 3
+ sub edi, 3
.L6:
- shr $2,%ecx
- rep movsl
- mov %edx,%ecx
- and $3,%ecx
- je .L7
- add $3,%esi
- add $3,%edi
+ shr ecx, 2
+ rep movsd
+ mov ecx, edx
+ and ecx, 3
+ je .L7
+ add esi, 3
+ add edi, 3
.L8:
- rep movsb
+ rep movsb
.L7:
cld
- mov 8(%ebp),%eax
- pop %edi
- pop %esi
+ mov eax, [ebp + 8]
+ pop edi
+ pop esi
leave
ret
.L5:
- sub $4,%edi
- sub $4,%esi
- jmp .L6
-
-.L4:
- test %ecx,%ecx
- je .L7
- dec %esi
- dec %edi
- jmp .L8
+ sub edi, 4
+ sub esi, 4
+ jmp .L6
+.L4:
+ test ecx, ecx
+ je .L7
+ dec esi
+ dec edi
+ jmp .L8
+
+END
diff --git a/lib/sdk/crt/mem/i386/memset_asm.s b/lib/sdk/crt/mem/i386/memset_asm.s
index 4f7c9436e71..81430472f4a 100644
--- a/lib/sdk/crt/mem/i386/memset_asm.s
+++ b/lib/sdk/crt/mem/i386/memset_asm.s
@@ -2,46 +2,51 @@
* $Id$
*/
+#include
+#include
+
/*
* void *memset (void *src, int val, size_t count)
*/
-.globl _memset
+PUBLIC _memset
+.code
_memset:
- push %ebp
- mov %esp,%ebp
- push %edi
- mov 0x8(%ebp),%edi
- movzb 0xc(%ebp),%eax
- mov 0x10(%ebp),%ecx
+ push ebp
+ mov ebp, esp
+ push edi
+ mov edi, [ebp + 8]
+ movzx eax, byte ptr [ebp + 12]
+ mov ecx, [ebp + 16]
cld
- cmp $16,%ecx
- jb .L1
- mov $0x01010101,%edx
- mul %edx
- mov %ecx,%edx
- test $3,%edi
- je .L2
- mov %edi,%ecx
- and $3,%ecx
- sub $5,%ecx
- not %ecx
- sub %ecx,%edx
- rep stosb
- mov %edx,%ecx
+ cmp ecx, 16
+ jb .L1
+ mov edx, HEX(01010101)
+ mul edx
+ mov edx, ecx
+ test edi, 3
+ je .L2
+ mov ecx, edi
+ and ecx, 3
+ sub ecx, 5
+ not ecx
+ sub edx, ecx
+ rep stosb
+ mov ecx, edx
.L2:
- shr $2,%ecx
- rep stosl
- mov %edx,%ecx
- and $3,%ecx
+ shr ecx, 2
+ rep stosd
+ mov ecx, edx
+ and ecx, 3
.L1:
- test %ecx,%ecx
- je .L3
- rep stosb
+ test ecx, ecx
+ je .L3
+ rep stosb
.L3:
- pop %edi
- mov 0x8(%ebp),%eax
+ pop edi
+ mov eax, [ebp + 8]
leave
ret
+END
diff --git a/lib/sdk/crt/misc/assert.c b/lib/sdk/crt/misc/assert.c
index 38c6940e7e4..bc196fd8417 100644
--- a/lib/sdk/crt/misc/assert.c
+++ b/lib/sdk/crt/misc/assert.c
@@ -67,6 +67,6 @@ void _assert(const char *exp, const char *file, unsigned line)
/* Does the user want to debug? */
if (iResult == IDRETRY)
{
- __debugbreak();
+ DbgRaiseAssertionFailure();
}
}
diff --git a/lib/sdk/crt/misc/crtmain.c b/lib/sdk/crt/misc/crtmain.c
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/lib/sdk/crt/printf/_cprintf.c b/lib/sdk/crt/printf/_cprintf.c
new file mode 100644
index 00000000000..4ce0494bbd6
--- /dev/null
+++ b/lib/sdk/crt/printf/_cprintf.c
@@ -0,0 +1,25 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/_vcprintf.c
+ * PURPOSE: Implementation of _vcprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+
+int _vcprintf(const char* format, va_list argptr);
+
+int
+_cdecl
+_cprintf(const char * format, ...)
+{
+ va_list argptr;
+ int result;
+
+ va_start(argptr, format);
+ result = _vcprintf(format, argptr);
+ va_end(argptr);
+ return result;
+}
+
diff --git a/lib/sdk/crt/printf/_snprintf.c b/lib/sdk/crt/printf/_snprintf.c
new file mode 100644
index 00000000000..b8bd5370c56
--- /dev/null
+++ b/lib/sdk/crt/printf/_snprintf.c
@@ -0,0 +1,39 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/_snprintf.c
+ * PURPOSE: Implementation of _snprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+#include
+
+int _cdecl streamout(FILE *stream, const char *format, va_list argptr);
+
+int
+_cdecl
+_snprintf(char *buffer, size_t count, const char *format, ...)
+{
+ va_list argptr;
+ int result;
+ FILE stream;
+
+ stream._base = buffer;
+ stream._ptr = stream._base;
+ stream._charbuf = 0;
+ stream._bufsiz = (unsigned long)-1;
+ stream._cnt = stream._bufsiz;
+ stream._flag = 0;
+ stream._tmpfname = 0;
+
+ va_start(argptr, format);
+ result = streamout(&stream, format, argptr);
+ va_end(argptr);
+
+ *stream._ptr = '\0';
+ return result;
+}
+
+
diff --git a/lib/sdk/crt/printf/_snwprintf.c b/lib/sdk/crt/printf/_snwprintf.c
new file mode 100644
index 00000000000..5a4a951d2eb
--- /dev/null
+++ b/lib/sdk/crt/printf/_snwprintf.c
@@ -0,0 +1,42 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/_snwprintf.c
+ * PURPOSE: Implementation of _snwprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+int _cdecl wstreamout(FILE *stream, const wchar_t *format, va_list argptr);
+
+int
+__cdecl
+_snwprintf(
+ wchar_t *buffer,
+ size_t count,
+ const wchar_t *format,
+ ...)
+{
+ va_list argptr;
+ int result;
+ FILE stream;
+
+ stream._base = (char*)buffer;
+ stream._ptr = stream._base;
+ stream._bufsiz = count * sizeof(wchar_t);
+ stream._cnt = stream._bufsiz;
+ stream._flag = _IOSTRG | _IOWRT;
+ stream._tmpfname = 0;
+ stream._charbuf = 0;
+
+ va_start(argptr, format);
+ result = wstreamout(&stream, format, argptr);
+ va_end(argptr);
+
+ /* Only zero terminate if there is enough space left */
+ if (stream._cnt >= sizeof(wchar_t)) *(wchar_t*)stream._ptr = L'\0';
+
+ return result;
+}
diff --git a/lib/sdk/crt/printf/_vcprintf.c b/lib/sdk/crt/printf/_vcprintf.c
new file mode 100644
index 00000000000..345a4421e91
--- /dev/null
+++ b/lib/sdk/crt/printf/_vcprintf.c
@@ -0,0 +1,18 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/_vcprintf.c
+ * PURPOSE: Implementation of _vcprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+
+int
+_cdecl
+_vcprintf(const char* format, va_list va)
+{
+ return 0;
+}
+
+
diff --git a/lib/sdk/crt/printf/_vsnprintf.c b/lib/sdk/crt/printf/_vsnprintf.c
new file mode 100644
index 00000000000..c94ffc60a8b
--- /dev/null
+++ b/lib/sdk/crt/printf/_vsnprintf.c
@@ -0,0 +1,37 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/_vsnprintf.c
+ * PURPOSE: Implementation of _vsnprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+int _cdecl streamout(FILE *stream, const char *format, va_list argptr);
+
+int
+__cdecl
+_vsnprintf(
+ char *buffer,
+ size_t count,
+ const char *format,
+ va_list argptr)
+{
+ int result;
+ FILE stream;
+
+ stream._base = buffer;
+ stream._ptr = stream._base;
+ stream._bufsiz = count;
+ stream._cnt = stream._bufsiz;
+ stream._flag = _IOSTRG | _IOWRT;
+ stream._tmpfname = 0;
+ stream._charbuf = 0;
+
+ result = streamout(&stream, format, argptr);
+ *stream._ptr = '\0';
+
+ return result;
+}
diff --git a/lib/sdk/crt/printf/_vsnwprintf.c b/lib/sdk/crt/printf/_vsnwprintf.c
new file mode 100644
index 00000000000..77e12303136
--- /dev/null
+++ b/lib/sdk/crt/printf/_vsnwprintf.c
@@ -0,0 +1,37 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/_vsnwprintf.c
+ * PURPOSE: Implementation of _vsnwprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+int _cdecl wstreamout(FILE *stream, const wchar_t *format, va_list argptr);
+
+int
+__cdecl
+_vsnwprintf(
+ wchar_t *buffer,
+ size_t count,
+ const wchar_t *format,
+ va_list argptr)
+{
+ int result;
+ FILE stream;
+
+ stream._base = (char*)buffer;
+ stream._ptr = stream._base;
+ stream._bufsiz = count * sizeof(wchar_t);
+ stream._cnt = stream._bufsiz;
+ stream._flag = _IOSTRG | _IOWRT;
+ stream._tmpfname = 0;
+ stream._charbuf = 0;
+
+ result = wstreamout(&stream, format, argptr);
+ *(wchar_t*)stream._ptr = L'\0';
+
+ return result;
+}
diff --git a/lib/sdk/crt/printf/fprintf.c b/lib/sdk/crt/printf/fprintf.c
new file mode 100644
index 00000000000..9d0b9540995
--- /dev/null
+++ b/lib/sdk/crt/printf/fprintf.c
@@ -0,0 +1,24 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/fprintf.c
+ * PURPOSE: Implementation of fprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+int
+_cdecl
+fprintf(FILE *stream, const char *format, ...)
+{
+ va_list argptr;
+ int result;
+
+ va_start(argptr, format);
+ result = vfprintf(stream, format, argptr);
+ va_end(argptr);
+ return result;
+}
+
diff --git a/lib/sdk/crt/printf/fwprintf.c b/lib/sdk/crt/printf/fwprintf.c
new file mode 100644
index 00000000000..f4b32b13488
--- /dev/null
+++ b/lib/sdk/crt/printf/fwprintf.c
@@ -0,0 +1,23 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/fwprintf.c
+ * PURPOSE: Implementation of fwprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+int
+__cdecl
+fwprintf(FILE* file, const wchar_t *format, ...)
+{
+ va_list argptr;
+ int result;
+
+ va_start(argptr, format);
+ result = vfwprintf(file, format, argptr);
+ va_end(argptr);
+ return result;
+}
diff --git a/lib/sdk/crt/printf/printf.c b/lib/sdk/crt/printf/printf.c
new file mode 100644
index 00000000000..a9f83f1046c
--- /dev/null
+++ b/lib/sdk/crt/printf/printf.c
@@ -0,0 +1,27 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/printf.c
+ * PURPOSE: Implementation of printf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+#include
+
+int _cdecl streamout(FILE *stream, const char *format, va_list argptr);
+
+int
+_cdecl
+printf(const char *format, ...)
+{
+ va_list argptr;
+ int result;
+
+ va_start(argptr, format);
+ result = streamout(stdout, format, argptr);
+ va_end(argptr);
+ return result;
+}
+
diff --git a/lib/sdk/crt/printf/sprintf.c b/lib/sdk/crt/printf/sprintf.c
new file mode 100644
index 00000000000..33c60926c72
--- /dev/null
+++ b/lib/sdk/crt/printf/sprintf.c
@@ -0,0 +1,38 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/sprintf.c
+ * PURPOSE: Implementation of sprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+#include
+
+int _cdecl streamout(FILE *stream, const char *format, va_list argptr);
+
+int
+_cdecl
+sprintf(char *buffer, const char *format, ...)
+{
+ va_list argptr;
+ int result;
+ FILE stream;
+
+ stream._base = buffer;
+ stream._ptr = stream._base;
+ stream._charbuf = 0;
+ stream._bufsiz = INT_MAX;
+ stream._cnt = stream._bufsiz;
+ stream._flag = 0;
+ stream._tmpfname = 0;
+
+ va_start(argptr, format);
+ result = streamout(&stream, format, argptr);
+ va_end(argptr);
+
+ *stream._ptr = '\0';
+ return result;
+}
+
diff --git a/lib/sdk/crt/printf/streamout.c b/lib/sdk/crt/printf/streamout.c
new file mode 100644
index 00000000000..53bfebafc42
--- /dev/null
+++ b/lib/sdk/crt/printf/streamout.c
@@ -0,0 +1,636 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/streamout.c
+ * PURPOSE: Implementation of streamout
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef _UNICODE
+#define streamout wstreamout
+#define format_float format_floatw
+#endif
+
+#define MB_CUR_MAX 10
+#define BUFFER_SIZE (32 + 17)
+
+int mbtowc(wchar_t *wchar, const char *mbchar, size_t count);
+int wctomb(char *mbchar, wchar_t wchar);
+
+typedef struct _STRING
+{
+ unsigned short Length;
+ unsigned short MaximumLength;
+ void *Buffer;
+} STRING;
+
+enum
+{
+ /* Formatting flags */
+ FLAG_ALIGN_LEFT = 0x01,
+ FLAG_FORCE_SIGN = 0x02,
+ FLAG_FORCE_SIGNSP = 0x04,
+ FLAG_PAD_ZERO = 0x08,
+ FLAG_SPECIAL = 0x10,
+
+ /* Data format flags */
+ FLAG_SHORT = 0x100,
+ FLAG_LONG = 0x200,
+ FLAG_WIDECHAR = FLAG_LONG,
+ FLAG_INT64 = 0x400,
+#ifdef _WIN64
+ FLAG_INTPTR = FLAG_INT64,
+#else
+ FLAG_INTPTR = 0,
+#endif
+ FLAG_LONGDOUBLE = 0x800,
+};
+
+#define va_arg_f(argptr, flags) \
+ (flags & FLAG_INT64) ? va_arg(argptr, __int64) : \
+ (flags & FLAG_SHORT) ? (short)va_arg(argptr, int) : \
+ va_arg(argptr, int)
+
+#define va_arg_fu(argptr, flags) \
+ (flags & FLAG_INT64) ? va_arg(argptr, unsigned __int64) : \
+ (flags & FLAG_SHORT) ? (unsigned short)va_arg(argptr, int) : \
+ va_arg(argptr, unsigned int)
+
+#define va_arg_ffp(argptr, flags) \
+ (flags & FLAG_LONGDOUBLE) ? va_arg(argptr, long double) : \
+ va_arg(argptr, double)
+
+#ifdef _LIBCNT_
+# define _flsbuf(chr, stream) 0
+#endif
+
+#define get_exp(f) floor(f > 0 ? log10(f) : log10(-f))
+
+void
+#ifdef _LIBCNT
+/* Due to restrictions in kernel mode regarding the use of floating point,
+ we prevent it from being inlined */
+__declspec(noinline)
+#endif
+format_float(
+ TCHAR chr,
+ unsigned int flags,
+ int precision,
+ TCHAR **string,
+ const TCHAR **prefix,
+ va_list *argptr)
+{
+ static const TCHAR digits_l[] = _T("0123456789abcdef0x");
+ static const TCHAR digits_u[] = _T("0123456789ABCDEF0X");
+ static const TCHAR _nan[] = _T("#QNAN");
+ static const TCHAR _infinity[] = _T("#INF");
+ const TCHAR *digits = digits_l;
+ int exponent = 0;
+ long double fpval;
+ int num_digits, val32, base = 10;
+ __int64 val64;
+
+ if (precision < 0) precision = 6;
+ else if (precision > 512) precision = 512;
+
+ fpval = va_arg_ffp(*argptr, flags);
+ exponent = get_exp(fpval);
+
+ switch (chr)
+ {
+ case _T('G'):
+ digits = digits_u;
+ case _T('g'):
+ if (exponent < -4 || exponent >= precision) goto case_e;
+ break;
+
+ case _T('E'):
+ digits = digits_u;
+ case _T('e'):
+ case_e:
+ fpval /= pow(10., exponent);
+ val32 = exponent >= 0 ? exponent : -exponent;
+
+ // FIXME: handle length of exponent field:
+ // http://msdn.microsoft.com/de-de/library/0fatw238%28VS.80%29.aspx
+ num_digits = 3;
+ while (num_digits--)
+ {
+ *--(*string) = digits[val32 % 10];
+ val32 /= 10;
+ }
+
+ /* Sign for the exponent */
+ *--(*string) = exponent > 0 ? _T('+') : _T('-');
+
+ /* Add 'e' or 'E' separator */
+ *--(*string) = digits[0xe];
+ break;
+
+ case _T('A'):
+ digits = digits_u;
+ case _T('a'):
+// base = 16;
+ // FIXME: TODO
+
+ case _T('f'):
+ break;
+ }
+
+ /* CHECKME: Windows seems to handle a max of 17 digits(?) */
+ num_digits = precision <= 17 ? precision: 17;
+
+ /* Handle sign */
+ if (fpval < 0)
+ {
+ fpval = -fpval;
+ *prefix = _T("-");
+ }
+ else if (flags & FLAG_FORCE_SIGN)
+ *prefix = _T("+");
+ else if (flags & FLAG_FORCE_SIGNSP)
+ *prefix = _T(" ");
+
+ /* Handle special cases first */
+ if (_isnan(fpval))
+ {
+ (*string) -= sizeof(_nan) / sizeof(TCHAR) - 1;
+ _tcscpy((*string), _nan);
+ val64 = 1;
+ }
+ else if (!_finite(fpval))
+ {
+ (*string) -= sizeof(_infinity) / sizeof(TCHAR) - 1;
+ _tcscpy((*string), _infinity);
+ val64 = 1;
+ }
+ else
+ {
+ fpval *= pow(10., precision);
+ val64 = (__int64)(fpval + 0.5);
+
+ while (num_digits-- > 0)
+ {
+ *--(*string) = digits[val64 % 10];
+ val64 /= 10;
+ }
+ }
+
+ *--(*string) = _T('.');
+
+ /* Digits before the decimal point */
+ do
+ {
+ *--(*string) = digits[val64 % base];
+ val64 /= base;
+ }
+ while (val64);
+
+}
+
+static
+int
+streamout_char(FILE *stream, int chr)
+{
+ /* Flush the buffer if neccessary */
+ if (stream->_cnt < sizeof(TCHAR))
+ {
+ return _flsbuf(chr, stream) != EOF;
+ }
+
+ *(TCHAR*)stream->_ptr = chr;
+ stream->_ptr += sizeof(TCHAR);
+ stream->_cnt -= sizeof(TCHAR);
+
+ return 1;
+}
+
+static
+int
+streamout_astring(FILE *stream, const char *string, int count)
+{
+ TCHAR chr;
+ int written = 0;
+
+ while (count--)
+ {
+#ifdef _UNICODE
+ int len;
+ if ((len = mbtowc(&chr, string, MB_CUR_MAX)) < 1) break;
+ string += len;
+#else
+ chr = *string++;
+#endif
+ if (streamout_char(stream, chr) == 0) return -1;
+ written++;
+ }
+
+ return written;
+}
+
+static
+int
+streamout_wstring(FILE *stream, const wchar_t *string, int count)
+{
+ wchar_t chr;
+ int written = 0;
+
+ while (count--)
+ {
+#ifndef _UNICODE
+ char mbchar[MB_CUR_MAX], *ptr = mbchar;
+ int mblen;
+
+ mblen = wctomb(mbchar, *string++);
+ if (mblen <= 0) return written;
+
+ while (chr = *ptr++, mblen--)
+#else
+ chr = *string++;
+#endif
+ {
+ if (streamout_char(stream, chr) == 0) return -1;
+ written++;
+ }
+ }
+
+ return written;
+}
+
+#ifdef _UNICODE
+#define streamout_string streamout_wstring
+#else
+#define streamout_string streamout_astring
+#endif
+
+
+int
+_cdecl
+streamout(FILE *stream, const TCHAR *format, va_list argptr)
+{
+ static const TCHAR digits_l[] = _T("0123456789abcdef0x");
+ static const TCHAR digits_u[] = _T("0123456789ABCDEF0X");
+ static const char *_nullstring = "(null)";
+ TCHAR buffer[BUFFER_SIZE + 1];
+ TCHAR chr, *string;
+ STRING *nt_string;
+ const TCHAR *digits, *prefix;
+ int base, len, prefixlen, fieldwidth, precision, padding;
+ int written = 1, written_all = 0;
+ unsigned int flags;
+ unsigned __int64 val64;
+
+ buffer[BUFFER_SIZE] = '\0';
+
+ while (written >= 0)
+ {
+ chr = *format++;
+
+ /* Check for end of format string */
+ if (chr == _T('\0')) break;
+
+ /* Check for 'normal' character or double % */
+ if ((chr != _T('%')) ||
+ (chr = *format++) == _T('%'))
+ {
+ /* Write the character to the stream */
+ if ((written = streamout_char(stream, chr)) == -1) return -1;
+ written_all += written;
+ continue;
+ }
+
+ /* Handle flags */
+ flags = 0;
+ while (1)
+ {
+ if (chr == _T('-')) flags |= FLAG_ALIGN_LEFT;
+ else if (chr == _T('+')) flags |= FLAG_FORCE_SIGN;
+ else if (chr == _T(' ')) flags |= FLAG_FORCE_SIGNSP;
+ else if (chr == _T('0')) flags |= FLAG_PAD_ZERO;
+ else if (chr == _T('#')) flags |= FLAG_SPECIAL;
+ else break;
+ chr = *format++;
+ }
+
+ /* Handle field width modifier */
+ if (chr == _T('*'))
+ {
+ fieldwidth = va_arg(argptr, int);
+ if (fieldwidth < 0)
+ {
+ flags |= FLAG_ALIGN_LEFT;
+ fieldwidth = -fieldwidth;
+ }
+ chr = *format++;
+ }
+ else
+ {
+ fieldwidth = 0;
+ while (chr >= _T('0') && chr <= _T('9'))
+ {
+ fieldwidth = fieldwidth * 10 + (chr - _T('0'));
+ chr = *format++;
+ }
+ }
+
+ /* Handle precision modifier */
+ if (chr == '.')
+ {
+ chr = *format++;
+
+ if (chr == _T('*'))
+ {
+ precision = va_arg(argptr, int);
+ chr = *format++;
+ }
+ else
+ {
+ precision = 0;
+ while (chr >= _T('0') && chr <= _T('9'))
+ {
+ precision = precision * 10 + (chr - _T('0'));
+ chr = *format++;
+ }
+ }
+ }
+ else precision = -1;
+
+ /* Handle argument size prefix */
+ while (1)
+ {
+ if (chr == _T('h')) flags |= FLAG_SHORT;
+ else if (chr == _T('w')) flags |= FLAG_WIDECHAR;
+ else if (chr == _T('L')) flags |= 0; // FIXME: long double
+ else if (chr == _T('l'))
+ {
+ flags |= FLAG_LONG;
+#if SUPPORT_LL
+ if (format[0] == _T('l'))
+ {
+ format++;
+ flags |= FLAG_INT64;
+ }
+#endif
+ }
+ else if (chr == _T('I'))
+ {
+ if (format[0] == _T('3') && format[1] == _T('2'))
+ {
+ format += 2;
+ }
+ else if (format[0] == _T('6') && format[1] == _T('4'))
+ {
+ format += 2;
+ flags |= FLAG_INT64;
+ }
+ else if (format[0] == _T('x') || format[0] == _T('X') ||
+ format[0] == _T('d') || format[0] == _T('i') ||
+ format[0] == _T('u') || format[0] == _T('o'))
+ {
+ flags |= FLAG_INTPTR;
+ }
+ else break;
+ }
+ else break;
+ chr = *format++;
+ }
+
+ /* Handle the format specifier */
+ digits = digits_l;
+ string = &buffer[BUFFER_SIZE];
+ base = 10;
+ prefix = 0;
+ switch (chr)
+ {
+ case _T('n'):
+ if (flags & FLAG_INT64)
+ *va_arg(argptr, __int64*) = written_all;
+ else if (flags & FLAG_SHORT)
+ *va_arg(argptr, short*) = written_all;
+ else
+ *va_arg(argptr, int*) = written_all;
+ continue;
+
+ case _T('C'):
+#ifndef _UNICODE
+ if (!(flags & FLAG_SHORT)) flags |= FLAG_WIDECHAR;
+#endif
+ goto case_char;
+
+ case _T('c'):
+#ifdef _UNICODE
+ if (!(flags & FLAG_SHORT)) flags |= FLAG_WIDECHAR;
+#endif
+ case_char:
+ string = buffer;
+ len = 1;
+ if (flags & FLAG_WIDECHAR)
+ {
+ ((wchar_t*)string)[0] = va_arg(argptr, int);
+ ((wchar_t*)string)[1] = _T('\0');
+ }
+ else
+ {
+ ((char*)string)[0] = va_arg(argptr, int);
+ ((char*)string)[1] = _T('\0');
+ }
+ break;
+
+ case _T('Z'):
+ nt_string = va_arg(argptr, void*);
+ if (nt_string && (string = nt_string->Buffer))
+ {
+ len = nt_string->Length;
+ if (flags & FLAG_WIDECHAR) len /= sizeof(wchar_t);
+ break;
+ }
+ string = 0;
+ goto case_string;
+
+ case _T('S'):
+ string = va_arg(argptr, void*);
+#ifndef _UNICODE
+ if (!(flags & FLAG_SHORT)) flags |= FLAG_WIDECHAR;
+#endif
+ goto case_string;
+
+ case _T('s'):
+ string = va_arg(argptr, void*);
+#ifdef _UNICODE
+ if (!(flags & FLAG_SHORT)) flags |= FLAG_WIDECHAR;
+#endif
+
+ case_string:
+ if (!string)
+ {
+ string = (TCHAR*)_nullstring;
+ flags &= ~FLAG_WIDECHAR;
+ }
+
+ if (flags & FLAG_WIDECHAR)
+ len = wcslen((wchar_t*)string);
+ else
+ len = strlen((char*)string);
+ if (precision >= 0 && len > precision) len = precision;
+ break;
+
+ case _T('G'):
+ case _T('E'):
+ case _T('A'):
+ case _T('g'):
+ case _T('e'):
+ case _T('a'):
+ case _T('f'):
+#ifdef _UNICODE
+ flags |= FLAG_WIDECHAR;
+#else
+ flags &= ~FLAG_WIDECHAR;
+#endif
+ /* Use external function, one for kernel one for user mode */
+ format_float(chr, flags, precision, &string, &prefix, &argptr);
+ len = _tcslen(string);
+ precision = 0;
+ break;
+
+ case _T('d'):
+ case _T('i'):
+ val64 = (__int64)va_arg_f(argptr, flags);
+
+ if ((__int64)val64 < 0)
+ {
+ val64 = -val64;
+ prefix = _T("-");
+ }
+ else if (flags & FLAG_FORCE_SIGN)
+ prefix = _T("+");
+ else if (flags & FLAG_FORCE_SIGNSP)
+ prefix = _T(" ");
+
+ goto case_number;
+
+ case _T('o'):
+ base = 8;
+ if (flags & FLAG_SPECIAL) prefix = _T("0");
+ goto case_unsigned;
+ /* Fall through */
+
+ case _T('p'):
+ precision = 2 * sizeof(void*);
+ flags &= ~FLAG_PAD_ZERO;
+ flags |= FLAG_INTPTR;
+ /* Fall through */
+
+ case _T('X'):
+ digits = digits_u;
+ /* Fall through */
+
+ case _T('x'):
+ base = 16;
+ if (flags & FLAG_SPECIAL)
+ {
+ prefix = &digits[16];
+ }
+
+ case _T('u'):
+ case_unsigned:
+ val64 = va_arg_fu(argptr, flags);
+
+ case_number:
+#ifdef _UNICODE
+ flags |= FLAG_WIDECHAR;
+#else
+ flags &= ~FLAG_WIDECHAR;
+#endif
+ if (precision < 0) precision = 1;
+
+ /* Gather digits in reverse order */
+ while (val64)
+ {
+ *--string = digits[val64 % base];
+ val64 /= base;
+ precision--;
+ }
+
+ len = _tcslen(string);
+ break;
+
+ default:
+ /* Treat anything else as a new character */
+ format--;
+ continue;
+ }
+
+ /* Calculate padding */
+ prefixlen = prefix ? _tcslen(prefix) : 0;
+ if (precision < 0) precision = 0;
+ padding = fieldwidth - len - prefixlen - precision;
+ if (padding < 0) padding = 0;
+
+ /* Optional left space padding */
+ if ((flags & (FLAG_ALIGN_LEFT | FLAG_PAD_ZERO)) == 0)
+ {
+ for (; padding > 0; padding--)
+ {
+ if ((written = streamout_char(stream, _T(' '))) == -1) return -2;
+ written_all += written;
+ }
+ }
+
+ /* Optional prefix */
+ if (prefix)
+ {
+ written = streamout_string(stream, prefix, prefixlen);
+ if (written == -1) return -3;
+ written_all += written;
+ }
+
+ /* Optional left '0' padding */
+ if ((flags & FLAG_ALIGN_LEFT) == 0) precision += padding;
+ while (precision-- > 0)
+ {
+ if ((written = streamout_char(stream, _T('0'))) == -1) return -4;
+ written_all += written;
+ }
+
+ /* Output the string */
+ if (flags & FLAG_WIDECHAR)
+ written = streamout_wstring(stream, (wchar_t*)string, len);
+ else
+ written = streamout_astring(stream, (char*)string, len);
+ if (written == -1) return -5;
+ written_all += written;
+
+#if 0 && SUPPORT_FLOAT
+ /* Optional right '0' padding */
+ while (precision-- > 0)
+ {
+ if ((written = streamout_char(stream, _T('0'))) == -1) return -6;
+ written_all += written;
+ len++;
+ }
+#endif
+
+ /* Optional right padding */
+ if (flags & FLAG_ALIGN_LEFT)
+ {
+ while (padding-- > 0)
+ {
+ if ((written = streamout_char(stream, _T(' '))) == -1) return -7;
+ written_all += written;
+ }
+ }
+
+ }
+
+ if (written == -1) return -8;
+
+ return written_all;
+}
+
diff --git a/lib/sdk/crt/printf/swprintf.c b/lib/sdk/crt/printf/swprintf.c
new file mode 100644
index 00000000000..115c1e6da56
--- /dev/null
+++ b/lib/sdk/crt/printf/swprintf.c
@@ -0,0 +1,39 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/swprintf.c
+ * PURPOSE: Implementation of swprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+#include
+
+int _cdecl wstreamout(FILE *stream, const wchar_t *format, va_list argptr);
+
+int
+_cdecl
+swprintf(wchar_t *buffer, const wchar_t *format, ...)
+{
+ va_list argptr;
+ int result;
+ FILE stream;
+
+ stream._base = (char*)buffer;
+ stream._ptr = stream._base;
+ stream._charbuf = 0;
+ stream._bufsiz = INT_MAX;
+ stream._cnt = stream._bufsiz;
+ stream._flag = 0;
+ stream._tmpfname = 0;
+
+ va_start(argptr, format);
+ result = wstreamout(&stream, format, argptr);
+ va_end(argptr);
+
+ *(wchar_t*)stream._ptr = '\0';
+ return result;
+}
+
+
diff --git a/lib/sdk/crt/printf/vfprintf.c b/lib/sdk/crt/printf/vfprintf.c
new file mode 100644
index 00000000000..5a28be59dac
--- /dev/null
+++ b/lib/sdk/crt/printf/vfprintf.c
@@ -0,0 +1,29 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/vfprintf.c
+ * PURPOSE: Implementation of vfprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+void _cdecl _lock_file(FILE* file);
+void _cdecl _unlock_file(FILE* file);
+int _cdecl streamout(FILE *stream, const char *format, va_list argptr);
+
+int
+_cdecl
+vfprintf(FILE *stream, const char *format, va_list argptr)
+{
+ int result;
+
+ _lock_file(stream);
+
+ result = streamout(stream, format, argptr);
+
+ _unlock_file(stream);
+
+ return result;
+}
diff --git a/lib/sdk/crt/printf/vfwprintf.c b/lib/sdk/crt/printf/vfwprintf.c
new file mode 100644
index 00000000000..fef618845c2
--- /dev/null
+++ b/lib/sdk/crt/printf/vfwprintf.c
@@ -0,0 +1,20 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/vfwprintf.c
+ * PURPOSE: Implementation of vfwprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+int _cdecl wstreamout(FILE *stream, const wchar_t *format, va_list argptr);
+
+int
+__cdecl
+vfwprintf(FILE* file, const wchar_t *format, va_list argptr)
+{
+ return wstreamout(file, format, argptr);
+}
+
diff --git a/lib/sdk/crt/printf/vprintf.c b/lib/sdk/crt/printf/vprintf.c
new file mode 100644
index 00000000000..e126c8ddf8f
--- /dev/null
+++ b/lib/sdk/crt/printf/vprintf.c
@@ -0,0 +1,19 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/vprintf.c
+ * PURPOSE: Implementation of vprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+int _cdecl streamout(FILE *stream, const char *format, va_list argptr);
+
+int
+__cdecl
+vprintf(const char *format, va_list argptr)
+{
+ return streamout(stdout, format, argptr);
+}
diff --git a/lib/sdk/crt/printf/vsprintf.c b/lib/sdk/crt/printf/vsprintf.c
new file mode 100644
index 00000000000..12a3d535835
--- /dev/null
+++ b/lib/sdk/crt/printf/vsprintf.c
@@ -0,0 +1,37 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/vsprintf.c
+ * PURPOSE: Implementation of vsprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+#include
+
+int _cdecl streamout(FILE *stream, const char *format, va_list argptr);
+
+int
+__cdecl
+vsprintf(
+ char *buffer,
+ const char *format,
+ va_list argptr)
+{
+ int result;
+ FILE stream;
+
+ stream._base = buffer;
+ stream._ptr = stream._base;
+ stream._charbuf = 0;
+ stream._bufsiz = INT_MAX;
+ stream._cnt = stream._bufsiz;
+ stream._flag = _IOSTRG|_IOWRT|_IOMYBUF;
+ stream._tmpfname = 0;
+
+ result = streamout(&stream, format, argptr);
+ *stream._ptr = '\0';
+
+ return result;
+}
diff --git a/lib/sdk/crt/printf/vswprintf.c b/lib/sdk/crt/printf/vswprintf.c
new file mode 100644
index 00000000000..4bba6ba3b2c
--- /dev/null
+++ b/lib/sdk/crt/printf/vswprintf.c
@@ -0,0 +1,18 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/vswprintf.c
+ * PURPOSE: Implementation of vswprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+#include
+
+int
+__cdecl
+vswprintf(wchar_t *buffer, const wchar_t *format, va_list argptr)
+{
+ return _vsnwprintf(buffer, INT_MAX, format, argptr);
+}
diff --git a/lib/sdk/crt/printf/vwprintf.c b/lib/sdk/crt/printf/vwprintf.c
new file mode 100644
index 00000000000..b9ee541613d
--- /dev/null
+++ b/lib/sdk/crt/printf/vwprintf.c
@@ -0,0 +1,19 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/vwprintf.c
+ * PURPOSE: Implementation of vwprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+int _cdecl wstreamout(FILE *stream, const wchar_t *format, va_list argptr);
+
+int
+__cdecl
+vwprintf(const wchar_t *format, va_list argptr)
+{
+ return wstreamout(stdout, format, argptr);
+}
diff --git a/lib/sdk/crt/printf/wprintf.c b/lib/sdk/crt/printf/wprintf.c
new file mode 100644
index 00000000000..1c5e9011132
--- /dev/null
+++ b/lib/sdk/crt/printf/wprintf.c
@@ -0,0 +1,25 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/wprintf.c
+ * PURPOSE: Implementation of wprintf
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#include
+#include
+
+int _cdecl wstreamout(FILE *stream, const wchar_t *format, va_list argptr);
+
+int
+__cdecl
+wprintf(const wchar_t *format, ...)
+{
+ va_list argptr;
+ int result;
+
+ va_start(argptr, format);
+ result = wstreamout(stdout, format, argptr);
+ va_end(argptr);
+ return result;
+}
diff --git a/lib/sdk/crt/printf/wstreamout.c b/lib/sdk/crt/printf/wstreamout.c
new file mode 100644
index 00000000000..bc078737db6
--- /dev/null
+++ b/lib/sdk/crt/printf/wstreamout.c
@@ -0,0 +1,12 @@
+/*
+ * COPYRIGHT: GNU GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS crt library
+ * FILE: lib/sdk/crt/printf/wstreamout.c
+ * PURPOSE: Implementation of wstreamout
+ * PROGRAMMER: Timo Kreuzer
+ */
+
+#define _UNICODE
+#define UNICODE
+
+#include "streamout.c"
diff --git a/lib/sdk/crt/setjmp/amd64/setjmp.s b/lib/sdk/crt/setjmp/amd64/setjmp.s
index 56459ae7665..a969bc43db5 100644
--- a/lib/sdk/crt/setjmp/amd64/setjmp.s
+++ b/lib/sdk/crt/setjmp/amd64/setjmp.s
@@ -8,8 +8,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
#define JUMP_BUFFER_Frame 0x00
#define JUMP_BUFFER_Rbx 0x08
@@ -156,3 +156,5 @@ PUBLIC longjmp
inc rax
2: jmp r8
.endp longjmp
+
+END
diff --git a/lib/sdk/crt/setjmp/i386/setjmp.s b/lib/sdk/crt/setjmp/i386/setjmp.s
index 7cf257cca24..95c4aac27a3 100644
--- a/lib/sdk/crt/setjmp/i386/setjmp.s
+++ b/lib/sdk/crt/setjmp/i386/setjmp.s
@@ -9,6 +9,8 @@
* complete implementation
*/
+#include
+
#define JB_BP 0
#define JB_BX 1
#define JB_DI 2
@@ -20,6 +22,7 @@
#define JMPBUF 4
+.code
/*
* int
* _setjmp(jmp_buf env);
@@ -33,20 +36,20 @@
* Notes:
* Sets up the jmp_buf
*/
-.globl __setjmp
+PUBLIC __setjmp
__setjmp:
- xorl %eax, %eax
- movl JMPBUF(%esp), %edx
+ xor eax, eax
+ mov edx, JMPBUF[esp]
/* Save registers. */
- movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */
- movl %ebx, (JB_BX*4)(%edx)
- movl %edi, (JB_DI*4)(%edx)
- movl %esi, (JB_SI*4)(%edx)
- leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
- movl %ecx, (JB_SP*4)(%edx)
- movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
- movl %ecx, (JB_IP*4)(%edx)
+ mov [edx + JB_BP*4], ebp /* Save caller's frame pointer. */
+ mov [edx + JB_BX*4], ebx
+ mov [edx + JB_DI*4], edi
+ mov [edx + JB_SI*4], esi
+ lea ecx, JMPBUF[esp] /* Save SP as it will be after we return. */
+ mov [edx + JB_SP*4], ecx
+ mov ecx, PCOFF[esp] /* Save PC we are returning to now. */
+ mov [edx + JB_IP*4], ecx
ret
/*
@@ -62,24 +65,22 @@ __setjmp:
* Notes:
* Sets up the jmp_buf
*/
-.globl __setjmp3
+PUBLIC __setjmp3
__setjmp3:
- xorl %eax, %eax
- movl JMPBUF(%esp), %edx
+ xor eax, eax
+ mov edx, JMPBUF[esp]
/* Save registers. */
- movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */
- movl %ebx, (JB_BX*4)(%edx)
- movl %edi, (JB_DI*4)(%edx)
- movl %esi, (JB_SI*4)(%edx)
- leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
- movl %ecx, (JB_SP*4)(%edx)
- movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
- movl %ecx, (JB_IP*4)(%edx)
+ mov [edx + JB_BP*4], ebp /* Save caller's frame pointer. */
+ mov [edx + JB_BX*4], ebx
+ mov [edx + JB_DI*4], edi
+ mov [edx + JB_SI*4], esi
+ lea ecx, JMPBUF[esp] /* Save SP as it will be after we return. */
+ mov [edx + JB_SP*4], ecx
+ mov ecx, PCOFF[esp] /* Save PC we are returning to now. */
+ mov [edx + JB_IP*4], ecx
ret
-#define VAL 8
-
/*
* void
* longjmp(jmp_buf env, int value);
@@ -94,18 +95,20 @@ __setjmp3:
* Notes:
* Non-local goto
*/
-.globl _longjmp
+PUBLIC _longjmp
_longjmp:
- movl JMPBUF(%esp), %ecx /* User's jmp_buf in %ecx. */
+ mov ecx, JMPBUF[esp] /* User's jmp_buf in %ecx. */
- movl VAL(%esp), %eax /* Second argument is return value. */
+ mov eax, [esp + 8] /* Second argument is return value. */
/* Save the return address now. */
- movl (JB_IP*4)(%ecx), %edx
+ mov edx, [ecx + JB_IP*4]
/* Restore registers. */
- movl (JB_BP*4)(%ecx), %ebp
- movl (JB_BX*4)(%ecx), %ebx
- movl (JB_DI*4)(%ecx), %edi
- movl (JB_SI*4)(%ecx), %esi
- movl (JB_SP*4)(%ecx), %esp
+ mov ebp, [ecx + JB_BP*4]
+ mov ebx, [ecx + JB_BX*4]
+ mov edi, [ecx + JB_DI*4]
+ mov esi, [ecx + JB_SI*4]
+ mov esp, [ecx + JB_SP*4]
/* Jump to saved PC. */
- jmp *%edx
+ jmp edx
+
+END
diff --git a/lib/sdk/crt/stdio/file.c b/lib/sdk/crt/stdio/file.c
index a3540ce28bd..eb20be7cf3f 100644
--- a/lib/sdk/crt/stdio/file.c
+++ b/lib/sdk/crt/stdio/file.c
@@ -2814,6 +2814,7 @@ FILE* CDECL tmpfile(void)
return file;
}
+#ifndef USE_NEW_SPRINTF
/*********************************************************************
* vfprintf (MSVCRT.@)
*/
@@ -2947,6 +2948,7 @@ int CDECL printf(const char *format, ...)
va_end(valist);
return res;
}
+#endif
/*********************************************************************
* ungetc (MSVCRT.@)
@@ -2984,6 +2986,7 @@ wint_t CDECL ungetwc(wint_t wc, FILE * file)
return mwc;
}
+#ifndef USE_NEW_SPRINTF
/*********************************************************************
* wprintf (MSVCRT.@)
*/
@@ -2996,6 +2999,7 @@ int CDECL wprintf(const wchar_t *format, ...)
va_end(valist);
return res;
}
+#endif
/*********************************************************************
* _getmaxstdio (MSVCRT.@)
diff --git a/lib/sdk/crt/stdio/lnx_sprintf.c b/lib/sdk/crt/stdio/lnx_sprintf.c
index f42a4e37662..29d150d68e5 100644
--- a/lib/sdk/crt/stdio/lnx_sprintf.c
+++ b/lib/sdk/crt/stdio/lnx_sprintf.c
@@ -14,7 +14,7 @@
* Lars Wirzenius & Linus Torvalds
* Wirzenius wrote this portably, Torvalds fucked it up :-)
*/
-
+#ifndef USE_NEW_SPRINTF
#include
#include
@@ -879,3 +879,4 @@ int __cdecl vsprintf(char *buf, const char *fmt, va_list args)
}
#endif
/* EOF */
+#endif
diff --git a/lib/sdk/crt/stdio/lock_file.c b/lib/sdk/crt/stdio/lock_file.c
new file mode 100644
index 00000000000..28c0265c36e
--- /dev/null
+++ b/lib/sdk/crt/stdio/lock_file.c
@@ -0,0 +1,15 @@
+
+#include
+
+void
+_cdecl
+_lock_file(FILE* file)
+{
+}
+
+void
+_cdecl
+_unlock_file(FILE* file)
+{
+}
+
diff --git a/lib/sdk/crt/string/i386/strcat_asm.s b/lib/sdk/crt/string/i386/strcat_asm.s
index 1241e78f7bb..6f7b8052d23 100644
--- a/lib/sdk/crt/string/i386/strcat_asm.s
+++ b/lib/sdk/crt/string/i386/strcat_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcscat.h"
+#include "tcscat.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/strchr_asm.s b/lib/sdk/crt/string/i386/strchr_asm.s
index b90e86d3303..f8085f25485 100644
--- a/lib/sdk/crt/string/i386/strchr_asm.s
+++ b/lib/sdk/crt/string/i386/strchr_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcschr.h"
+#include "tcschr.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/strcmp_asm.s b/lib/sdk/crt/string/i386/strcmp_asm.s
index 3ee6573f700..8618f17c076 100644
--- a/lib/sdk/crt/string/i386/strcmp_asm.s
+++ b/lib/sdk/crt/string/i386/strcmp_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcscmp.h"
+#include "tcscmp.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/strcpy_asm.s b/lib/sdk/crt/string/i386/strcpy_asm.s
index 1b77403847c..168d2921ba8 100644
--- a/lib/sdk/crt/string/i386/strcpy_asm.s
+++ b/lib/sdk/crt/string/i386/strcpy_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcscpy.h"
+#include "tcscpy.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/strlen_asm.s b/lib/sdk/crt/string/i386/strlen_asm.s
index 9bb10b6d91b..66a8ba27299 100644
--- a/lib/sdk/crt/string/i386/strlen_asm.s
+++ b/lib/sdk/crt/string/i386/strlen_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcslen.h"
+#include "tcslen.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/strncat_asm.s b/lib/sdk/crt/string/i386/strncat_asm.s
index 52b20671625..d7fefe417a7 100644
--- a/lib/sdk/crt/string/i386/strncat_asm.s
+++ b/lib/sdk/crt/string/i386/strncat_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcsncat.h"
+#include "tcsncat.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/strncmp_asm.s b/lib/sdk/crt/string/i386/strncmp_asm.s
index 30c64e6b664..d4db767c207 100644
--- a/lib/sdk/crt/string/i386/strncmp_asm.s
+++ b/lib/sdk/crt/string/i386/strncmp_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcsncmp.h"
+#include "tcsncmp.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/strncpy_asm.s b/lib/sdk/crt/string/i386/strncpy_asm.s
index 7409b4ed6c7..584dbb8cce5 100644
--- a/lib/sdk/crt/string/i386/strncpy_asm.s
+++ b/lib/sdk/crt/string/i386/strncpy_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcsncpy.h"
+#include "tcsncpy.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/strnlen_asm.s b/lib/sdk/crt/string/i386/strnlen_asm.s
index be35b3ca2c2..5c1f8dfccf7 100644
--- a/lib/sdk/crt/string/i386/strnlen_asm.s
+++ b/lib/sdk/crt/string/i386/strnlen_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcsnlen.h"
+#include "tcsnlen.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/strrchr_asm.s b/lib/sdk/crt/string/i386/strrchr_asm.s
index a8a9d5e79ac..c94f29ec0d7 100644
--- a/lib/sdk/crt/string/i386/strrchr_asm.s
+++ b/lib/sdk/crt/string/i386/strrchr_asm.s
@@ -1,6 +1,6 @@
/* $Id$
*/
-#include "tcsrchr.h"
+#include "tcsrchr.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/tchar.h b/lib/sdk/crt/string/i386/tchar.h
index ce2f1b9666d..a313e86111e 100644
--- a/lib/sdk/crt/string/i386/tchar.h
+++ b/lib/sdk/crt/string/i386/tchar.h
@@ -21,12 +21,12 @@
#define _tlods lodsw
#define _tstos stosw
-#define _tsize $2
+#define _tsize 2
#define _treg(_O_) _O_ ## x
-#define _tdec(_O_) sub $2, _O_
-#define _tinc(_O_) add $2, _O_
+#define _tdec(_O_) sub _O_, 2
+#define _tinc(_O_) add _O_, 2
#else
@@ -45,7 +45,7 @@
#define _tlods lodsb
#define _tstos stosb
-#define _tsize $1
+#define _tsize 1
#define _treg(_O_) _O_ ## l
diff --git a/lib/sdk/crt/string/i386/tcscat.h b/lib/sdk/crt/string/i386/tcscat.h
deleted file mode 100644
index e50676528d8..00000000000
--- a/lib/sdk/crt/string/i386/tcscat.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* $Id$
- */
-
-#include "tchar.h"
-
-.globl _tcscat
-
-_tcscat:
- push %esi
- push %edi
- mov 0x0C(%esp), %edi
- mov 0x10(%esp), %esi
-
- xor %eax, %eax
- mov $-1, %ecx
- cld
-
- repne _tscas
- _tdec(%edi)
-
-.L1:
- _tlods
- _tstos
- test %_treg(a), %_treg(a)
- jnz .L1
-
- mov 0x0C(%esp), %eax
- pop %edi
- pop %esi
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcscat.inc b/lib/sdk/crt/string/i386/tcscat.inc
new file mode 100644
index 00000000000..d587128f447
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcscat.inc
@@ -0,0 +1,35 @@
+/* $Id: tcscat.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+ */
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcscat
+.code
+
+_tcscat:
+ push esi
+ push edi
+ mov edi, [esp + 12]
+ mov esi, [esp + 16]
+
+ xor eax, eax
+ mov ecx, -1
+ cld
+
+ repne _tscas
+ _tdec(edi)
+
+.L1:
+ _tlods
+ _tstos
+ test _treg(a), _treg(a)
+ jnz .L1
+
+ mov eax, [esp + 12]
+ pop edi
+ pop esi
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcschr.h b/lib/sdk/crt/string/i386/tcschr.h
deleted file mode 100644
index ea08bb8d22e..00000000000
--- a/lib/sdk/crt/string/i386/tcschr.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $Id$
- */
-
-#include "tchar.h"
-
-.globl _tcschr
-
-_tcschr:
- push %esi
- mov 0x8(%esp), %esi
- mov 0xC(%esp), %edx
-
- cld
-
-.L1:
- _tlods
- cmp %_treg(a), %_treg(d)
- je .L2
- test %_treg(a), %_treg(a)
- jnz .L1
- mov _tsize, %esi
-
-.L2:
- mov %esi, %eax
- _tdec(%eax)
-
- pop %esi
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcschr.inc b/lib/sdk/crt/string/i386/tcschr.inc
new file mode 100644
index 00000000000..9554ac3cbcd
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcschr.inc
@@ -0,0 +1,32 @@
+/* $Id: tcschr.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+ */
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcschr
+.code
+
+_tcschr:
+ push esi
+ mov esi, [esp + 8]
+ mov edx, [esp + 12]
+ cld
+
+.L1:
+ _tlods
+ cmp _treg(d), _treg(a)
+ je .L2
+ test _treg(a), _treg(a)
+ jnz .L1
+ mov esi, _tsize
+
+.L2:
+ mov eax, esi
+ _tdec(eax)
+
+ pop esi
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcscmp.h b/lib/sdk/crt/string/i386/tcscmp.h
deleted file mode 100644
index 6830a0ba0dc..00000000000
--- a/lib/sdk/crt/string/i386/tcscmp.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* $Id$
- */
-
-#include "tchar.h"
-
-.globl _tcscmp
-
-_tcscmp:
- push %esi
- push %edi
- mov 0x0C(%esp), %esi
- mov 0x10(%esp), %edi
- xor %eax, %eax
- cld
-
-.L1:
- _tlods
- _tscas
- jne .L2
- test %eax, %eax
- jne .L1
- xor %eax, %eax
- jmp .L3
-
-.L2:
- sbb %eax, %eax
- or $1, %al
-
-.L3:
- pop %edi
- pop %esi
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcscmp.inc b/lib/sdk/crt/string/i386/tcscmp.inc
new file mode 100644
index 00000000000..3bcf453e7b7
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcscmp.inc
@@ -0,0 +1,37 @@
+/* $Id: tcscmp.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+ */
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcscmp
+.code
+
+_tcscmp:
+ push esi
+ push edi
+ mov esi, [esp + 12]
+ mov edi, [esp + 16]
+ xor eax, eax
+ cld
+
+.L1:
+ _tlods
+ _tscas
+ jne .L2
+ test eax, eax
+ jne .L1
+ xor eax, eax
+ jmp .L3
+
+.L2:
+ sbb eax, eax
+ or al, 1
+
+.L3:
+ pop edi
+ pop esi
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcscpy.h b/lib/sdk/crt/string/i386/tcscpy.h
deleted file mode 100644
index cb89a43a4a8..00000000000
--- a/lib/sdk/crt/string/i386/tcscpy.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* $Id$
- */
-
-#include "tchar.h"
-
-.globl _tcscpy
-
-_tcscpy:
- push %esi
- push %edi
- mov 0x0C(%esp), %edi
- mov 0x10(%esp), %esi
- cld
-
-.L1:
- _tlods
- _tstos
- test %_treg(a), %_treg(a)
- jnz .L1
-
- mov 0x0C(%esp), %eax
-
- pop %edi
- pop %esi
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcscpy.inc b/lib/sdk/crt/string/i386/tcscpy.inc
new file mode 100644
index 00000000000..b16b4ccea32
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcscpy.inc
@@ -0,0 +1,30 @@
+/* $Id: tcscpy.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+ */
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcscpy
+.code
+
+_tcscpy:
+ push esi
+ push edi
+ mov edi, [esp + 12]
+ mov esi, [esp + 16]
+ cld
+
+.L1:
+ _tlods
+ _tstos
+ test _treg(a), _treg(a)
+ jnz .L1
+
+ mov eax, [esp + 12]
+
+ pop edi
+ pop esi
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcslen.h b/lib/sdk/crt/string/i386/tcslen.h
deleted file mode 100644
index 8c9586da70d..00000000000
--- a/lib/sdk/crt/string/i386/tcslen.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* $Id$
-*/
-
-#include "tchar.h"
-
-.globl _tcslen
-
-_tcslen:
- push %edi
- mov 0x8(%esp), %edi
- xor %eax, %eax
- test %edi,%edi
- jz _tcslen_end
-
- mov $-1, %ecx
- cld
-
- repne _tscas
-
- not %ecx
- dec %ecx
-
- mov %ecx, %eax
-
-_tcslen_end:
- pop %edi
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcslen.inc b/lib/sdk/crt/string/i386/tcslen.inc
new file mode 100644
index 00000000000..f749b9d88c4
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcslen.inc
@@ -0,0 +1,32 @@
+/* $Id: tcslen.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+*/
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcslen
+.code
+
+_tcslen:
+ push edi
+ mov edi, [esp + 8]
+ xor eax, eax
+ test edi, edi
+ jz _tcslen_end
+
+ mov ecx, -1
+ cld
+
+ repne _tscas
+
+ not ecx
+ dec ecx
+
+ mov eax, ecx
+
+_tcslen_end:
+ pop edi
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsncat.h b/lib/sdk/crt/string/i386/tcsncat.h
deleted file mode 100644
index f7a3b616396..00000000000
--- a/lib/sdk/crt/string/i386/tcsncat.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* $Id$
- */
-
-#include "tchar.h"
-
-.globl _tcsncat
-
-_tcsncat:
- push %esi
- push %edi
- mov 0x0C(%esp), %edi
- mov 0x10(%esp), %esi
- cld
-
- xor %eax, %eax
- mov $-1, %ecx
- repne _tscas
- _tdec(%edi)
-
- mov 0x14(%esp),%ecx
-
-.L1:
- dec %ecx
- js .L2
- _tlods
- _tstos
- test %_treg(a), %_treg(a)
- jne .L1
- jmp .L3
-
-.L2:
- xor %eax, %eax
- _tstos
-
-.L3:
- mov 0x0C(%esp), %eax
- pop %edi
- pop %esi
-
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsncat.inc b/lib/sdk/crt/string/i386/tcsncat.inc
new file mode 100644
index 00000000000..b03bb87785f
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcsncat.inc
@@ -0,0 +1,45 @@
+/* $Id: tcsncat.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+ */
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcsncat
+.code
+
+_tcsncat:
+ push esi
+ push edi
+ mov edi, [esp + 12]
+ mov esi, [esp + 16]
+ cld
+
+ xor eax, eax
+ mov ecx, -1
+ repne _tscas
+ _tdec(edi)
+
+ mov ecx, [esp + 20]
+
+.L1:
+ dec ecx
+ js .L2
+ _tlods
+ _tstos
+ test _treg(a), _treg(a)
+ jne .L1
+ jmp .L3
+
+.L2:
+ xor eax, eax
+ _tstos
+
+.L3:
+ mov eax, [esp + 12]
+ pop edi
+ pop esi
+
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsncmp.h b/lib/sdk/crt/string/i386/tcsncmp.h
deleted file mode 100644
index 58a30859e73..00000000000
--- a/lib/sdk/crt/string/i386/tcsncmp.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* $Id$
- */
-
-#include "tchar.h"
-
-.globl _tcsncmp
-
-_tcsncmp:
- push %esi
- push %edi
- mov 0x0C(%esp), %esi /* s1 */
- mov 0x10(%esp), %edi /* s2 */
- mov 0x14(%esp), %ecx /* n */
-
- xor %eax,%eax
- cld
-
-.L1:
- dec %ecx
- js .L2
- _tlods
- _tscas
- jne .L3
- test %eax, %eax
- jne .L1
-
-.L2:
- xor %eax, %eax
- jmp .L4
-
-.L3:
- sbb %eax, %eax
- or $1, %al
-
-.L4:
- pop %edi
- pop %esi
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsncmp.inc b/lib/sdk/crt/string/i386/tcsncmp.inc
new file mode 100644
index 00000000000..9545e583bec
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcsncmp.inc
@@ -0,0 +1,43 @@
+/* $Id: tcsncmp.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+ */
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcsncmp
+.code
+
+_tcsncmp:
+ push esi
+ push edi
+ mov esi, [esp + 12] /* s1 */
+ mov edi, [esp + 16] /* s2 */
+ mov ecx, [esp + 20] /* n */
+
+ xor eax, eax
+ cld
+
+.L1:
+ dec ecx
+ js .L2
+ _tlods
+ _tscas
+ jne .L3
+ test eax, eax
+ jne .L1
+
+.L2:
+ xor eax, eax
+ jmp .L4
+
+.L3:
+ sbb eax, eax
+ or al, 1
+
+.L4:
+ pop edi
+ pop esi
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsncpy.h b/lib/sdk/crt/string/i386/tcsncpy.h
deleted file mode 100644
index ed15334d036..00000000000
--- a/lib/sdk/crt/string/i386/tcsncpy.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* $Id$
- */
-
-#include "tchar.h"
-
-.globl _tcsncpy
-
-_tcsncpy:
- push %esi
- push %edi
- mov 0x0C(%esp), %edi /* s1 */
- mov 0x10(%esp), %esi /* s2 */
- mov 0x14(%esp), %ecx /* n */
-
- xor %eax, %eax
- cld
-
-.L1:
- dec %ecx
- js .L2
- _tlods
- _tstos
- test %_treg(a), %_treg(a)
- jnz .L1
- rep _tstos
-
-.L2:
- mov 0x0C(%esp), %eax
-
- pop %edi
- pop %esi
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsncpy.inc b/lib/sdk/crt/string/i386/tcsncpy.inc
new file mode 100644
index 00000000000..248c5ce9a20
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcsncpy.inc
@@ -0,0 +1,37 @@
+/* $Id: tcsncpy.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+ */
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcsncpy
+.code
+
+_tcsncpy:
+ push esi
+ push edi
+ mov edi, [esp + 12] /* s1 */
+ mov esi, [esp + 16] /* s2 */
+ mov ecx, [esp + 20] /* n */
+
+ xor eax, eax
+ cld
+
+.L1:
+ dec ecx
+ js .L2
+ _tlods
+ _tstos
+ test _treg(a), _treg(a)
+ jnz .L1
+ rep _tstos
+
+.L2:
+ mov eax, [esp + 12]
+
+ pop edi
+ pop esi
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsnlen.h b/lib/sdk/crt/string/i386/tcsnlen.h
deleted file mode 100644
index 90a4ec6c88c..00000000000
--- a/lib/sdk/crt/string/i386/tcsnlen.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $Id$
-*/
-
-#include "tchar.h"
-
-.globl _tcsnlen
-
-_tcsnlen:
- push %edi
- mov 0x8(%esp), %edi
- mov 0xC(%esp), %ecx
- xor %eax, %eax
- test %ecx, %ecx
- jz .L1
- mov %ecx, %edx
-
- cld
-
- repne _tscas
-
- sete %al
- sub %ecx, %edx
- sub %eax, %edx
- mov %edx, %eax
-
-.L1:
- pop %edi
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsnlen.inc b/lib/sdk/crt/string/i386/tcsnlen.inc
new file mode 100644
index 00000000000..fc72607adb2
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcsnlen.inc
@@ -0,0 +1,33 @@
+/* $Id: tcsnlen.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+*/
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcsnlen
+.code
+
+_tcsnlen:
+ push edi
+ mov edi, [esp + 8]
+ mov ecx, [esp + 12]
+ xor eax, eax
+ test ecx, ecx
+ jz .L1
+ mov edx, ecx
+
+ cld
+
+ repne _tscas
+
+ sete al
+ sub edx, ecx
+ sub edx, eax
+ mov eax, edx
+
+.L1:
+ pop edi
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsrchr.h b/lib/sdk/crt/string/i386/tcsrchr.h
deleted file mode 100644
index 61d3a4dd863..00000000000
--- a/lib/sdk/crt/string/i386/tcsrchr.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $Id$
- */
-
-#include "tchar.h"
-
-.globl _tcsrchr
-
-_tcsrchr:
- push %esi
- mov 0x8(%esp), %esi
- mov 0xC(%esp), %edx
-
- cld
- mov _tsize, %ecx
-
-.L1:
- _tlods
- cmp %_treg(a), %_treg(d)
- jne .L2
- mov %esi, %ecx
-
-.L2:
- test %_treg(a), %_treg(a)
- jnz .L1
-
- mov %ecx, %eax
- _tdec(%eax)
- pop %esi
- ret
-
-/* EOF */
diff --git a/lib/sdk/crt/string/i386/tcsrchr.inc b/lib/sdk/crt/string/i386/tcsrchr.inc
new file mode 100644
index 00000000000..9527853122a
--- /dev/null
+++ b/lib/sdk/crt/string/i386/tcsrchr.inc
@@ -0,0 +1,34 @@
+/* $Id: tcsrchr.inc 49591 2010-11-15 01:29:12Z tkreuzer $
+ */
+
+#include "tchar.h"
+#include
+
+PUBLIC _tcsrchr
+.code
+
+_tcsrchr:
+ push esi
+ mov esi, [esp + 8]
+ mov edx, [esp + 12]
+
+ cld
+ mov ecx, _tsize
+
+.L1:
+ _tlods
+ cmp _treg(d), _treg(a)
+ jne .L2
+ mov ecx, esi
+
+.L2:
+ test _treg(a), _treg(a)
+ jnz .L1
+
+ mov eax, ecx
+ _tdec(eax)
+ pop esi
+ ret
+
+END
+/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcscat_asm.s b/lib/sdk/crt/string/i386/wcscat_asm.s
index 56beb026aa3..b833d0ddab3 100644
--- a/lib/sdk/crt/string/i386/wcscat_asm.s
+++ b/lib/sdk/crt/string/i386/wcscat_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcscat.h"
+#include "tcscat.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcschr_asm.s b/lib/sdk/crt/string/i386/wcschr_asm.s
index a493a48d237..8fc6c360baf 100644
--- a/lib/sdk/crt/string/i386/wcschr_asm.s
+++ b/lib/sdk/crt/string/i386/wcschr_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcschr.h"
+#include "tcschr.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcscmp_asm.s b/lib/sdk/crt/string/i386/wcscmp_asm.s
index 2377a026b78..b4f5425beba 100644
--- a/lib/sdk/crt/string/i386/wcscmp_asm.s
+++ b/lib/sdk/crt/string/i386/wcscmp_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcscmp.h"
+#include "tcscmp.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcscpy_asm.s b/lib/sdk/crt/string/i386/wcscpy_asm.s
index 7e76864972d..78b6fe2a6d2 100644
--- a/lib/sdk/crt/string/i386/wcscpy_asm.s
+++ b/lib/sdk/crt/string/i386/wcscpy_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcscpy.h"
+#include "tcscpy.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcslen_asm.s b/lib/sdk/crt/string/i386/wcslen_asm.s
index f70390048ad..5d4bfe054aa 100644
--- a/lib/sdk/crt/string/i386/wcslen_asm.s
+++ b/lib/sdk/crt/string/i386/wcslen_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcslen.h"
+#include "tcslen.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcsncat_asm.s b/lib/sdk/crt/string/i386/wcsncat_asm.s
index 36e2cf15dc6..d28bbc3e3a4 100644
--- a/lib/sdk/crt/string/i386/wcsncat_asm.s
+++ b/lib/sdk/crt/string/i386/wcsncat_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcsncat.h"
+#include "tcsncat.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcsncmp_asm.s b/lib/sdk/crt/string/i386/wcsncmp_asm.s
index 594e2c49340..5ae53efa7c9 100644
--- a/lib/sdk/crt/string/i386/wcsncmp_asm.s
+++ b/lib/sdk/crt/string/i386/wcsncmp_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcsncmp.h"
+#include "tcsncmp.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcsncpy_asm.s b/lib/sdk/crt/string/i386/wcsncpy_asm.s
index 601e70cdafe..b4591cfdb10 100644
--- a/lib/sdk/crt/string/i386/wcsncpy_asm.s
+++ b/lib/sdk/crt/string/i386/wcsncpy_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcsncpy.h"
+#include "tcsncpy.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcsnlen_asm.s b/lib/sdk/crt/string/i386/wcsnlen_asm.s
index 65bd605231c..39349927757 100644
--- a/lib/sdk/crt/string/i386/wcsnlen_asm.s
+++ b/lib/sdk/crt/string/i386/wcsnlen_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcsnlen.h"
+#include "tcsnlen.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/i386/wcsrchr_asm.s b/lib/sdk/crt/string/i386/wcsrchr_asm.s
index 872403a8956..a845ee53203 100644
--- a/lib/sdk/crt/string/i386/wcsrchr_asm.s
+++ b/lib/sdk/crt/string/i386/wcsrchr_asm.s
@@ -2,6 +2,6 @@
*/
#define _UNICODE
-#include "tcsrchr.h"
+#include "tcsrchr.inc"
/* EOF */
diff --git a/lib/sdk/crt/string/wcs.c b/lib/sdk/crt/string/wcs.c
index 00941292911..52446dcb82a 100644
--- a/lib/sdk/crt/string/wcs.c
+++ b/lib/sdk/crt/string/wcs.c
@@ -388,6 +388,7 @@ static inline int pf_output_format_A( pf_output *out, LPCSTR str,
return r;
}
+#ifndef USE_NEW_SPRINTF
static int pf_handle_string_format( pf_output *out, const void* str, int len,
pf_flags *flags, BOOL capital_letter)
{
@@ -879,6 +880,7 @@ int CDECL vswprintf( wchar_t* str, const wchar_t* format, va_list args )
return _vsnwprintf( str, INT_MAX, format, args );
}
#endif
+#endif
/*********************************************************************
* wcscoll (MSVCRT.@)
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index d03bb636129..adaff2f0e71 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -90,6 +90,7 @@ reactos/dll/win32/mciseq # Autosync
reactos/dll/win32/mciwave # Autosync
reactos/dll/win32/mlang # Autosync
reactos/dll/win32/mpr # Autosync
+reactos/dll/win32/mprapi # Autosync
reactos/dll/win32/msacm32 # Autosync
reactos/dll/win32/msadp32.acm # Autosync
reactos/dll/win32/mscat32 # Autosync
@@ -167,6 +168,7 @@ reactos/dll/win32/urlmon # Autosync
reactos/dll/win32/usp10 # Autosync
reactos/dll/win32/uxtheme # Autosync
reactos/dll/win32/version # Autosync
+reactos/dll/win32/wer # Autosync
reactos/dll/win32/windowscodecs # Autosync
reactos/dll/win32/winemp3.acm # Autosync
reactos/dll/win32/wininet # Autosync
diff --git a/modules/directory.rbuild b/modules/directory.rbuild
index 7c33c54cb7c..a4424fd98e1 100644
--- a/modules/directory.rbuild
+++ b/modules/directory.rbuild
@@ -22,4 +22,11 @@
+
diff --git a/ntoskrnl/cache/cachesub.c b/ntoskrnl/cache/cachesub.c
new file mode 100644
index 00000000000..fb9d9e31eb9
--- /dev/null
+++ b/ntoskrnl/cache/cachesub.c
@@ -0,0 +1,347 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/cachesup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ * Art Yerkes
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include
+#include "newcc.h"
+#include "section/newmm.h"
+#define NDEBUG
+#include
+
+/* STRUCTURES *****************************************************************/
+
+typedef struct _WORK_QUEUE_WITH_READ_AHEAD
+{
+ WORK_QUEUE_ITEM WorkItem;
+ PFILE_OBJECT FileObject;
+ LARGE_INTEGER FileOffset;
+ ULONG Length;
+} WORK_QUEUE_WITH_READ_AHEAD, *PWORK_QUEUE_WITH_READ_AHEAD;
+
+/* FUNCTIONS ******************************************************************/
+
+PDEVICE_OBJECT
+NTAPI
+MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject);
+
+VOID
+NTAPI
+CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject,
+ IN ULONG Granularity)
+{
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+ if (Map)
+ {
+ Map->ReadAheadGranularity = Granularity;
+ }
+}
+
+VOID
+NTAPI
+CcpReadAhead(PVOID Context)
+{
+ LARGE_INTEGER Offset;
+ PWORK_QUEUE_WITH_READ_AHEAD WorkItem = (PWORK_QUEUE_WITH_READ_AHEAD)Context;
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)WorkItem->FileObject->SectionObjectPointer->SharedCacheMap;
+ DPRINT("Reading ahead %08x%08x:%x %wZ\n",
+ WorkItem->FileOffset.HighPart,
+ WorkItem->FileOffset.LowPart,
+ WorkItem->Length,
+ &WorkItem->FileObject->FileName);
+ Offset.HighPart = WorkItem->FileOffset.HighPart;
+ Offset.LowPart = PAGE_ROUND_DOWN(WorkItem->FileOffset.LowPart);
+ if (Map)
+ {
+ PLIST_ENTRY ListEntry;
+ volatile char *chptr;
+ PNOCC_BCB Bcb;
+ for (ListEntry = Map->AssociatedBcb.Flink;
+ ListEntry != &Map->AssociatedBcb;
+ ListEntry = ListEntry->Flink)
+ {
+ Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
+ if ((Offset.QuadPart + WorkItem->Length < Bcb->FileOffset.QuadPart) ||
+ (Bcb->FileOffset.QuadPart + Bcb->Length < Offset.QuadPart))
+ continue;
+ for (chptr = Bcb->BaseAddress, Offset = Bcb->FileOffset;
+ chptr < ((PCHAR)Bcb->BaseAddress) + Bcb->Length &&
+ Offset.QuadPart <
+ WorkItem->FileOffset.QuadPart + WorkItem->Length;
+ chptr += PAGE_SIZE, Offset.QuadPart += PAGE_SIZE)
+ {
+ *chptr ^= 0;
+ }
+ }
+ }
+ ObDereferenceObject(WorkItem->FileObject);
+ ExFreePool(WorkItem);
+ DPRINT("Done\n");
+}
+
+VOID
+NTAPI
+CcScheduleReadAhead(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length)
+{
+ PWORK_QUEUE_WITH_READ_AHEAD WorkItem;
+ DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
+ FileOffset->HighPart,
+ FileOffset->LowPart,
+ Length,
+ &FileObject->FileName);
+ WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem));
+ if (!WorkItem) KeBugCheck(0);
+ ObReferenceObject(FileObject);
+ WorkItem->FileObject = FileObject;
+ WorkItem->FileOffset = *FileOffset;
+ WorkItem->Length = Length;
+ ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpReadAhead, WorkItem);
+ ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
+ DPRINT("Done\n");
+}
+
+VOID
+NTAPI
+CcSetDirtyPinnedData(IN PVOID BcbVoid,
+ IN OPTIONAL PLARGE_INTEGER Lsn)
+{
+ PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid;
+ Bcb->Dirty = TRUE;
+}
+
+LARGE_INTEGER
+NTAPI
+CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
+ IN BOOLEAN CcInternalCaller)
+{
+ LARGE_INTEGER Result = {{0}};
+ UNIMPLEMENTED;
+ while (TRUE);
+ return Result;
+}
+
+
+
+VOID
+NTAPI
+_CcpFlushCache(IN PNOCC_CACHE_MAP Map,
+ IN OPTIONAL PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
+ BOOLEAN Delete,
+ const char *File,
+ int Line)
+{
+ PNOCC_BCB Bcb = NULL;
+ LARGE_INTEGER LowerBound, UpperBound;
+ PLIST_ENTRY ListEntry;
+ IO_STATUS_BLOCK IOSB = { };
+
+ DPRINT1("CcFlushCache (while file) (%s:%d)\n", File, Line);
+
+ if (FileOffset && Length)
+ {
+ LowerBound.QuadPart = FileOffset->QuadPart;
+ UpperBound.QuadPart = LowerBound.QuadPart + Length;
+ }
+ else
+ {
+ LowerBound.QuadPart = 0;
+ UpperBound.QuadPart = 0x7fffffffffffffffull;
+ }
+
+ CcpLock();
+ ListEntry = Map->AssociatedBcb.Flink;
+
+ while (ListEntry != &Map->AssociatedBcb)
+ {
+ Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
+ CcpReferenceCache(Bcb - CcCacheSections);
+
+ if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
+ Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
+ {
+ DPRINT
+ ("Bcb #%x (@%08x%08x)\n",
+ Bcb - CcCacheSections,
+ Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
+
+ Bcb->RefCount++;
+ CcpUnlock();
+ MiFlushMappedSection(Bcb->BaseAddress, &Bcb->FileOffset, &Map->FileSizes.FileSize, Bcb->Dirty);
+ CcpLock();
+ Bcb->RefCount--;
+
+ Bcb->Dirty = FALSE;
+
+ ListEntry = ListEntry->Flink;
+ if (Delete && Bcb->RefCount < 2)
+ {
+ Bcb->RefCount = 1;
+ CcpDereferenceCache(Bcb - CcCacheSections, FALSE);
+ }
+ else
+ CcpUnpinData(Bcb);
+ }
+ else
+ {
+ ListEntry = ListEntry->Flink;
+ CcpUnpinData(Bcb);
+ }
+
+ DPRINT("End loop\n");
+ }
+ CcpUnlock();
+
+ if (IoStatus) *IoStatus = IOSB;
+}
+
+VOID
+NTAPI
+CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
+ IN OPTIONAL PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
+{
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
+
+ // Not cached
+ if (!Map)
+ {
+ if (IoStatus)
+ {
+ IoStatus->Status = STATUS_SUCCESS;
+ IoStatus->Information = 0;
+ }
+ return;
+ }
+
+ CcpFlushCache(Map, FileOffset, Length, IoStatus, TRUE);
+}
+
+BOOLEAN
+NTAPI
+CcFlushImageSection
+(PSECTION_OBJECT_POINTERS SectionObjectPointer,
+ MMFLUSH_TYPE FlushType)
+{
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
+ PNOCC_BCB Bcb;
+ PLIST_ENTRY Entry;
+ IO_STATUS_BLOCK IOSB;
+ BOOLEAN Result = TRUE;
+
+ if (!Map) return TRUE;
+
+ for (Entry = Map->AssociatedBcb.Flink;
+ Entry != &Map->AssociatedBcb;
+ Entry = Entry->Flink)
+ {
+ Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
+
+ if (!Bcb->Dirty) continue;
+
+ switch (FlushType)
+ {
+ case MmFlushForDelete:
+ CcPurgeCacheSection
+ (SectionObjectPointer,
+ &Bcb->FileOffset,
+ Bcb->Length,
+ FALSE);
+ break;
+ case MmFlushForWrite:
+ CcFlushCache
+ (SectionObjectPointer,
+ &Bcb->FileOffset,
+ Bcb->Length,
+ &IOSB);
+ break;
+ }
+ }
+
+ return Result;
+}
+
+// Always succeeds for us
+PVOID
+NTAPI
+CcRemapBcb(IN PVOID Bcb)
+{
+ CcpLock();
+ ASSERT(RtlTestBit(CcCacheBitmap, ((PNOCC_BCB)Bcb) - CcCacheSections));
+ CcpReferenceCache(((PNOCC_BCB)Bcb) - CcCacheSections);
+ CcpUnlock();
+ return Bcb;
+}
+
+VOID
+NTAPI
+CcShutdownSystem()
+{
+ ULONG i;
+
+ DPRINT1("CC: Shutdown\n");
+
+ for (i = 0; i < CACHE_NUM_SECTIONS; i++)
+ {
+ PNOCC_BCB Bcb = &CcCacheSections[i];
+ if (Bcb->SectionObject)
+ {
+ DPRINT1
+ ("Evicting #%02x %08x%08x %wZ\n",
+ i,
+ Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart,
+ &MmGetFileObjectForSection
+ ((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName);
+ CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE);
+ Bcb->Dirty = FALSE;
+ }
+ }
+
+ DPRINT1("Done\n");
+}
+
+
+VOID
+NTAPI
+CcRepinBcb(IN PVOID Bcb)
+{
+ CcpLock();
+ ASSERT(RtlTestBit(CcCacheBitmap, ((PNOCC_BCB)Bcb) - CcCacheSections));
+ DPRINT("CcRepinBcb(#%x)\n", ((PNOCC_BCB)Bcb) - CcCacheSections);
+ CcpReferenceCache(((PNOCC_BCB)Bcb) - CcCacheSections);
+ CcpUnlock();
+}
+
+VOID
+NTAPI
+CcUnpinRepinnedBcb(IN PVOID Bcb,
+ IN BOOLEAN WriteThrough,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
+
+ if (WriteThrough)
+ {
+ DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
+
+ CcpFlushCache
+ (RealBcb->Map,
+ &RealBcb->FileOffset,
+ RealBcb->Length,
+ IoStatus, RealBcb->Dirty);
+ }
+
+ CcUnpinData(Bcb);
+}
+
+/* EOF */
diff --git a/ntoskrnl/cache/copysup.c b/ntoskrnl/cache/copysup.c
new file mode 100644
index 00000000000..2f8a954e846
--- /dev/null
+++ b/ntoskrnl/cache/copysup.c
@@ -0,0 +1,214 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/copysup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include
+#include "newcc.h"
+#include "section/newmm.h"
+#define NDEBUG
+#include
+
+/* GLOBALS ********************************************************************/
+
+ULONG CcFastMdlReadWait;
+ULONG CcFastMdlReadNotPossible;
+ULONG CcFastReadNotPossible;
+ULONG CcFastReadWait;
+ULONG CcFastReadNoWait;
+ULONG CcFastReadResourceMiss;
+
+#define TAG_COPY_READ TAG('C', 'o', 'p', 'y')
+#define TAG_COPY_WRITE TAG('R', 'i', 't', 'e')
+
+/* FUNCTIONS ******************************************************************/
+
+BOOLEAN
+NTAPI
+CcCopyRead(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ OUT PVOID Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ PCHAR ReadBuffer;
+ ULONG ReadLen;
+ PVOID Bcb;
+ PCHAR BufferTarget = (PCHAR)Buffer;
+ LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
+
+ DPRINT
+ ("CcCopyRead(%x,%x,%d,%d,%x)\n",
+ FileObject,
+ FileOffset->LowPart,
+ Length,
+ Wait,
+ Buffer);
+
+ CacheOffset.QuadPart = FileOffset->QuadPart;
+ EndOfExtent.QuadPart = FileOffset->QuadPart + Length;
+
+ while (CacheOffset.QuadPart < EndOfExtent.QuadPart)
+ {
+ NextOffset.QuadPart = CacheOffset.QuadPart;
+ NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
+ ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
+ if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
+ {
+ ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
+ }
+
+ DPRINT("Reading %d bytes in this go (at %08x%08x)\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
+
+ if (!CcPinRead
+ (FileObject,
+ &CacheOffset,
+ ReadLen,
+ Wait ? PIN_WAIT : PIN_IF_BCB,
+ &Bcb,
+ (PVOID*)&ReadBuffer))
+ {
+ IoStatus->Status = STATUS_UNSUCCESSFUL;
+ IoStatus->Information = 0;
+ DPRINT("Failed CcCopyRead\n");
+ return FALSE;
+ }
+
+ DPRINT1("Copying %d bytes at %08x%08x\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
+ RtlCopyMemory
+ (BufferTarget,
+ ReadBuffer,
+ ReadLen);
+
+ BufferTarget += ReadLen;
+
+ CacheOffset = NextOffset;
+ CcUnpinData(Bcb);
+ }
+
+ IoStatus->Status = STATUS_SUCCESS;
+ IoStatus->Information = Length;
+
+ DPRINT("Done with CcCopyRead\n");
+
+ return TRUE;
+}
+
+VOID
+NTAPI
+CcFastCopyRead(IN PFILE_OBJECT FileObject,
+ IN ULONG FileOffset,
+ IN ULONG Length,
+ IN ULONG PageCount,
+ OUT PVOID Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+BOOLEAN
+NTAPI
+CcCopyWrite(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ IN PVOID Buffer)
+{
+ INT Count = 0;
+ BOOLEAN Result;
+ PNOCC_BCB Bcb;
+ PVOID WriteBuf;
+ ULONG WriteLen;
+ LARGE_INTEGER CurrentOffset = *FileOffset;
+ LARGE_INTEGER EndOffset;
+ LARGE_INTEGER NextOffset;
+
+ EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
+
+ DPRINT
+ ("CcCopyWrite(%x,%x,%d,%d,%x)\n",
+ FileObject,
+ FileOffset->LowPart,
+ Length,
+ Wait,
+ Buffer);
+
+ while (CurrentOffset.QuadPart < EndOffset.QuadPart)
+ {
+ NextOffset.HighPart = CurrentOffset.HighPart;
+ NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
+ DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
+ WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
+ DPRINT("Copying %x bytes from %08x%08x\n",
+ WriteLen,
+ CurrentOffset.u.HighPart, CurrentOffset.u.LowPart);
+ DPRINT("CcPreparePinWrite\n");
+ Result = CcPreparePinWrite
+ (FileObject, &CurrentOffset, WriteLen, FALSE, Wait ? PIN_WAIT : PIN_IF_BCB,
+ (PVOID *)&Bcb, &WriteBuf);
+ DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
+ if (!Result)
+ {
+ DPRINT1("CcPreparePinWrite Failed?\n");
+ if (Wait) RtlRaiseStatus(STATUS_NOT_MAPPED_DATA); else return FALSE;
+ }
+ DPRINT1("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n", Bcb - CcCacheSections, WriteBuf, Bcb->BaseAddress);
+
+ //MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
+ RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
+ Count += WriteLen;
+ Length -= WriteLen;
+ CurrentOffset = NextOffset;
+ Bcb->Dirty = TRUE;
+ CcUnpinData(Bcb);
+ }
+
+ DPRINT("Done with CcCopyWrite\n");
+
+ return TRUE;
+}
+
+VOID
+NTAPI
+CcFastCopyWrite(IN PFILE_OBJECT FileObject,
+ IN ULONG FileOffset,
+ IN ULONG Length,
+ IN PVOID Buffer)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+BOOLEAN
+NTAPI
+CcCanIWrite(IN PFILE_OBJECT FileObject,
+ IN ULONG BytesToWrite,
+ IN BOOLEAN Wait,
+ IN UCHAR Retrying)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return FALSE;
+}
+
+VOID
+NTAPI
+CcDeferWrite(IN PFILE_OBJECT FileObject,
+ IN PCC_POST_DEFERRED_WRITE PostRoutine,
+ IN PVOID Context1,
+ IN PVOID Context2,
+ IN ULONG BytesToWrite,
+ IN BOOLEAN Retrying)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+/* EOF */
diff --git a/ntoskrnl/cache/fssup.c b/ntoskrnl/cache/fssup.c
new file mode 100644
index 00000000000..8646513e3b0
--- /dev/null
+++ b/ntoskrnl/cache/fssup.c
@@ -0,0 +1,513 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/fssup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ * Art Yerkes
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include
+#include "newcc.h"
+#include "section/newmm.h"
+#define NDEBUG
+#include
+
+/* GLOBALS ********************************************************************/
+
+PFSN_PREFETCHER_GLOBALS CcPfGlobals;
+extern LONG CcOutstandingDeletes;
+extern KEVENT CcpLazyWriteEvent;
+extern KEVENT CcFinalizeEvent;
+extern VOID NTAPI CcpUnmapThread(PVOID Unused);
+extern VOID NTAPI CcpLazyWriteThread(PVOID Unused);
+HANDLE CcUnmapThreadHandle, CcLazyWriteThreadHandle;
+CLIENT_ID CcUnmapThreadId, CcLazyWriteThreadId;
+
+typedef struct _NOCC_PRIVATE_CACHE_MAP
+{
+ LIST_ENTRY ListEntry;
+ PFILE_OBJECT FileObject;
+ PNOCC_CACHE_MAP Map;
+} NOCC_PRIVATE_CACHE_MAP, *PNOCC_PRIVATE_CACHE_MAP;
+
+LIST_ENTRY CcpAllSharedCacheMaps;
+
+/* FUNCTIONS ******************************************************************/
+
+// Interact with legacy balance manager for now
+// This can fall away when our section implementation supports
+// demand paging properly
+NTSTATUS
+CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
+{
+ ULONG i, Freed, BcbHead;
+
+ *NrFreed = 0;
+
+ for (i = 0; i < CACHE_NUM_SECTIONS; i++) {
+ BcbHead = (i+CcCacheClockHand) % CACHE_NUM_SECTIONS;
+
+ // Reference a cache stripe so it won't go away
+ CcpLock();
+ if (CcCacheSections[BcbHead].BaseAddress) {
+ CcpReferenceCache(i);
+ CcpUnlock();
+ } else {
+ CcpUnlock();
+ continue;
+ }
+
+ // Defer to MM to try recovering pages from it
+ Freed = MiCacheEvictPages
+ (CcCacheSections[BcbHead].BaseAddress, Target);
+
+ Target -= Freed;
+ *NrFreed += Freed;
+
+ CcpLock();
+ CcpDereferenceCache(BcbHead, FALSE);
+ CcpUnlock();
+ }
+
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN
+NTAPI
+CcInitializeCacheManager(VOID)
+{
+ int i;
+
+ DPRINT("Initialize\n");
+ for (i = 0; i < CACHE_NUM_SECTIONS; i++)
+ {
+ KeInitializeEvent(&CcCacheSections[i].ExclusiveWait, SynchronizationEvent, FALSE);
+ InitializeListHead(&CcCacheSections[i].ThisFileList);
+ }
+
+ InitializeListHead(&CcpAllSharedCacheMaps);
+
+ KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
+ KeInitializeEvent(&CcFinalizeEvent, SynchronizationEvent, FALSE);
+ KeInitializeEvent(&CcpLazyWriteEvent, SynchronizationEvent, FALSE);
+
+ CcCacheBitmap->Buffer = ((PULONG)&CcCacheBitmap[1]);
+ CcCacheBitmap->SizeOfBitMap = ROUND_UP(CACHE_NUM_SECTIONS, 32);
+ DPRINT("Cache has %d entries\n", CcCacheBitmap->SizeOfBitMap);
+ ExInitializeFastMutex(&CcMutex);
+
+ // MM stub
+ KeInitializeEvent(&MmWaitPageEvent, SynchronizationEvent, FALSE);
+
+ // Until we're fully demand paged, we can do things the old way through
+ // the balance manager
+ MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache);
+
+ return TRUE;
+}
+
+VOID
+NTAPI
+CcPfInitializePrefetcher(VOID)
+{
+ /* Notify debugger */
+ DbgPrintEx(DPFLTR_PREFETCHER_ID,
+ DPFLTR_TRACE_LEVEL,
+ "CCPF: InitializePrefetecher()\n");
+
+ /* Setup the Prefetcher Data */
+ InitializeListHead(&CcPfGlobals.ActiveTraces);
+ InitializeListHead(&CcPfGlobals.CompletedTraces);
+ ExInitializeFastMutex(&CcPfGlobals.CompletedTracesLock);
+
+ /* FIXME: Setup the rest of the prefetecher */
+}
+
+BOOLEAN
+NTAPI
+CcpAcquireFileLock(PNOCC_CACHE_MAP Map)
+{
+ DPRINT("Calling AcquireForLazyWrite: %x\n", Map->LazyContext);
+ return Map->Callbacks.AcquireForLazyWrite(Map->LazyContext, TRUE);
+}
+
+VOID
+NTAPI
+CcpReleaseFileLock(PNOCC_CACHE_MAP Map)
+{
+ DPRINT("Releasing Lazy Write %x\n", Map->LazyContext);
+ Map->Callbacks.ReleaseFromLazyWrite(Map->LazyContext);
+}
+
+// Must have CcpLock()
+PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject)
+{
+ PLIST_ENTRY Entry, Private;
+ for (Entry = CcpAllSharedCacheMaps.Flink;
+ Entry != &CcpAllSharedCacheMaps;
+ Entry = Entry->Flink)
+ {
+ // 'Identical' test for other stream file object
+ PNOCC_CACHE_MAP Map = CONTAINING_RECORD(Entry, NOCC_CACHE_MAP, Entry);
+ for (Private = Map->PrivateCacheMaps.Flink;
+ Private != &Map->PrivateCacheMaps;
+ Private = Private->Flink)
+ {
+ PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private, NOCC_PRIVATE_CACHE_MAP, ListEntry);
+ if (PrivateMap->FileObject->Flags & FO_STREAM_FILE &&
+ PrivateMap->FileObject->DeviceObject == FileObject->DeviceObject &&
+ PrivateMap->FileObject->Vpb == FileObject->Vpb &&
+ PrivateMap->FileObject->FsContext == FileObject->FsContext &&
+ PrivateMap->FileObject->FsContext2 == FileObject->FsContext2 &&
+ 1)
+ {
+ return PrivateMap->FileObject;
+ }
+ }
+ }
+ return 0;
+}
+
+// Thanks: http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html
+
+VOID
+NTAPI
+CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
+ IN PCC_FILE_SIZES FileSizes,
+ IN BOOLEAN PinAccess,
+ IN PCACHE_MANAGER_CALLBACKS Callbacks,
+ IN PVOID LazyWriteContext)
+{
+ PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
+ PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
+
+ CcpLock();
+ if (!Map && FileObject->Flags & FO_STREAM_FILE)
+ {
+ PFILE_OBJECT IdenticalStreamFileObject =
+ CcpFindOtherStreamFileObject(FileObject);
+ if (IdenticalStreamFileObject)
+ Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
+ if (Map)
+ {
+ DPRINT1
+ ("Linking SFO %x to previous SFO %x through cache map %x #\n",
+ FileObject, IdenticalStreamFileObject, Map);
+ }
+ }
+ if (!Map)
+ {
+ DPRINT("Initializing file object for (%p) %wZ\n", FileObject, &FileObject->FileName);
+ Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
+ FileObject->SectionObjectPointer->SharedCacheMap = Map;
+ Map->FileSizes = *FileSizes;
+ Map->LazyContext = LazyWriteContext;
+ Map->ReadAheadGranularity = PAGE_SIZE;
+ RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));
+ // For now ...
+ DPRINT("FileSizes->ValidDataLength %08x%08x\n", FileSizes->ValidDataLength.HighPart, FileSizes->ValidDataLength.LowPart);
+ InitializeListHead(&Map->AssociatedBcb);
+ InitializeListHead(&Map->PrivateCacheMaps);
+ InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry);
+ DPRINT("New Map %x\n", Map);
+ }
+ if (!PrivateCacheMap)
+ {
+ PrivateCacheMap = ExAllocatePool(NonPagedPool, sizeof(*PrivateCacheMap));
+ FileObject->PrivateCacheMap = PrivateCacheMap;
+ PrivateCacheMap->FileObject = FileObject;
+ ObReferenceObject(PrivateCacheMap->FileObject);
+ }
+
+ PrivateCacheMap->Map = Map;
+ InsertTailList(&Map->PrivateCacheMaps, &PrivateCacheMap->ListEntry);
+
+ CcpUnlock();
+}
+
+ULONG
+NTAPI
+CcpCountCacheSections(IN PNOCC_CACHE_MAP Map)
+{
+ PLIST_ENTRY Entry;
+ ULONG Count;
+
+ for (Count = 0, Entry = Map->AssociatedBcb.Flink; Entry != &Map->AssociatedBcb; Entry = Entry->Flink, Count++);
+
+ return Count;
+}
+
+BOOLEAN
+NTAPI
+CcUninitializeCacheMap(IN PFILE_OBJECT FileObject,
+ IN OPTIONAL PLARGE_INTEGER TruncateSize,
+ IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
+{
+ BOOLEAN LastMap = FALSE;
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+ PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
+
+ DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n", &FileObject->FileName, FileObject->SectionObjectPointer);
+
+ ASSERT(UninitializeEvent == NULL);
+
+ if (Map)
+ CcpFlushCache(Map, NULL, 0, NULL, FALSE);
+
+ CcpLock();
+ if (PrivateCacheMap)
+ {
+ ASSERT(!Map || Map == PrivateCacheMap->Map);
+ ASSERT(PrivateCacheMap->FileObject == FileObject);
+
+ RemoveEntryList(&PrivateCacheMap->ListEntry);
+ if (IsListEmpty(&PrivateCacheMap->Map->PrivateCacheMaps))
+ {
+ while (!IsListEmpty(&Map->AssociatedBcb))
+ {
+ PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
+ DPRINT("Evicting cache stripe #%x\n", Bcb - CcCacheSections);
+ Bcb->RefCount = 1;
+ CcpDereferenceCache(Bcb - CcCacheSections, TRUE);
+ }
+ RemoveEntryList(&PrivateCacheMap->Map->Entry);
+ ExFreePool(PrivateCacheMap->Map);
+ FileObject->SectionObjectPointer->SharedCacheMap = NULL;
+ LastMap = TRUE;
+ }
+ ObDereferenceObject(PrivateCacheMap->FileObject);
+ FileObject->PrivateCacheMap = NULL;
+ ExFreePool(PrivateCacheMap);
+ }
+ CcpUnlock();
+
+ DPRINT("Uninit complete\n");
+
+ return LastMap;
+}
+
+VOID
+NTAPI
+CcSetFileSizes(IN PFILE_OBJECT FileObject,
+ IN PCC_FILE_SIZES FileSizes)
+{
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+ if (!Map) return;
+ Map->FileSizes = *FileSizes;
+ PNOCC_BCB Bcb = Map->AssociatedBcb.Flink == &Map->AssociatedBcb ?
+ NULL : CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
+ if (!Bcb) return;
+ MmExtendCacheSection(Bcb->SectionObject, &FileSizes->FileSize, FALSE);
+ DPRINT("FileSizes->FileSize %x\n", FileSizes->FileSize.LowPart);
+ DPRINT("FileSizes->AllocationSize %x\n", FileSizes->AllocationSize.LowPart);
+ DPRINT("FileSizes->ValidDataLength %x\n", FileSizes->ValidDataLength.LowPart);
+}
+
+BOOLEAN
+NTAPI
+CcGetFileSizes
+(IN PFILE_OBJECT FileObject,
+ IN PCC_FILE_SIZES FileSizes)
+{
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+ if (!Map) return FALSE;
+ *FileSizes = Map->FileSizes;
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
+ IN OPTIONAL PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN UninitializeCacheMaps)
+{
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
+ if (!Map) return TRUE;
+ CcpFlushCache(Map, NULL, 0, NULL, TRUE);
+ return TRUE;
+}
+
+VOID
+NTAPI
+CcSetDirtyPageThreshold(IN PFILE_OBJECT FileObject,
+ IN ULONG DirtyPageThreshold)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+BOOLEAN
+NTAPI
+CcZeroData(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER StartOffset,
+ IN PLARGE_INTEGER EndOffset,
+ IN BOOLEAN Wait)
+{
+ PNOCC_BCB Bcb = NULL;
+ PLIST_ENTRY ListEntry = NULL;
+ LARGE_INTEGER LowerBound = *StartOffset;
+ LARGE_INTEGER UpperBound = *EndOffset;
+ LARGE_INTEGER Target, End;
+ PVOID PinnedBcb, PinnedBuffer;
+ PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
+
+ DPRINT
+ ("S %08x%08x E %08x%08x\n",
+ StartOffset->u.HighPart, StartOffset->u.LowPart,
+ EndOffset->u.HighPart, EndOffset->u.LowPart);
+
+ if (!Map)
+ {
+ NTSTATUS Status;
+ IO_STATUS_BLOCK IOSB;
+ PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
+ ULONG ToWrite;
+
+ if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
+ RtlZeroMemory(ZeroBuf, PAGE_SIZE);
+
+ Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
+ End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);
+
+ // Handle leading page
+ if (LowerBound.QuadPart != Target.QuadPart)
+ {
+ ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart, (PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
+ DPRINT("Zero last half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
+ Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, &IOSB);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(ZeroBuf);
+ RtlRaiseStatus(Status);
+ }
+ DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite);
+ RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite);
+ Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE,UpperBound.QuadPart-Target.QuadPart), &IOSB);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(ZeroBuf);
+ RtlRaiseStatus(Status);
+ }
+ Target.QuadPart += PAGE_SIZE;
+ }
+
+ DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
+ RtlZeroMemory(ZeroBuf, PAGE_SIZE);
+
+ while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
+ {
+ DPRINT("Zero full page %08x%08x\n", Target.u.HighPart, Target.u.LowPart);
+ Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, PAGE_SIZE, &IOSB);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(ZeroBuf);
+ RtlRaiseStatus(Status);
+ }
+ Target.QuadPart += PAGE_SIZE;
+ }
+
+ if (UpperBound.QuadPart > Target.QuadPart)
+ {
+ ToWrite = UpperBound.QuadPart - Target.QuadPart;
+ DPRINT("Zero first half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
+ Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, &IOSB);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(ZeroBuf);
+ RtlRaiseStatus(Status);
+ }
+ DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite);
+ RtlZeroMemory(ZeroBuf, ToWrite);
+ Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE, UpperBound.QuadPart-Target.QuadPart), &IOSB);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(ZeroBuf);
+ RtlRaiseStatus(Status);
+ }
+ Target.QuadPart += PAGE_SIZE;
+ }
+
+ ExFreePool(ZeroBuf);
+ return TRUE;
+ }
+
+ CcpLock();
+ ListEntry = Map->AssociatedBcb.Flink;
+
+ while (ListEntry != &Map->AssociatedBcb)
+ {
+ Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
+ CcpReferenceCache(Bcb - CcCacheSections);
+
+ if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
+ Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
+ {
+ DPRINT
+ ("Bcb #%x (@%08x%08x)\n",
+ Bcb - CcCacheSections,
+ Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
+
+ Target.QuadPart = MAX(Bcb->FileOffset.QuadPart, LowerBound.QuadPart);
+ End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart, UpperBound.QuadPart);
+ End.QuadPart = MIN(End.QuadPart, Bcb->FileOffset.QuadPart + Bcb->Length);
+ CcpUnlock();
+
+ if (!CcPreparePinWrite
+ (FileObject,
+ &Target,
+ End.QuadPart - Target.QuadPart,
+ TRUE,
+ Wait,
+ &PinnedBcb,
+ &PinnedBuffer))
+ {
+ return FALSE;
+ }
+
+ ASSERT(PinnedBcb == Bcb);
+
+ CcpLock();
+ ListEntry = ListEntry->Flink;
+ // Return from pin state
+ CcpUnpinData(PinnedBcb);
+ }
+
+ CcpUnpinData(Bcb);
+ }
+
+ CcpUnlock();
+
+ return TRUE;
+}
+
+PFILE_OBJECT
+NTAPI
+CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
+{
+ PFILE_OBJECT Result = NULL;
+ PNOCC_CACHE_MAP Map = SectionObjectPointer->SharedCacheMap;
+ CcpLock();
+ if (!IsListEmpty(&Map->AssociatedBcb))
+ {
+ PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
+ Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject);
+ }
+ CcpUnlock();
+ return Result;
+}
+
+PFILE_OBJECT
+NTAPI
+CcGetFileObjectFromBcb(PVOID Bcb)
+{
+ PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
+ DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
+ return MmGetFileObjectForSection((PROS_SECTION_OBJECT)RealBcb->SectionObject);
+}
+
+/* EOF */
diff --git a/ntoskrnl/cache/lazyrite.c b/ntoskrnl/cache/lazyrite.c
new file mode 100644
index 00000000000..4dcbb5d8a36
--- /dev/null
+++ b/ntoskrnl/cache/lazyrite.c
@@ -0,0 +1,36 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/lazyrite.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include
+#include "newcc.h"
+#define NDEBUG
+#include
+
+/* GLOBALS ********************************************************************/
+
+KEVENT CcpLazyWriteEvent;
+
+/* FUNCTIONS ******************************************************************/
+
+VOID NTAPI
+CcpLazyWriteThread(PVOID Unused)
+{
+ /* Not implemented */
+}
+
+NTSTATUS
+NTAPI
+CcWaitForCurrentLazyWriterActivity(VOID)
+{
+ //KeWaitForSingleObject(&CcpLazyWriteEvent, Executive, KernelMode, FALSE, NULL);
+ return STATUS_SUCCESS;
+}
+
+/* EOF */
diff --git a/ntoskrnl/cache/logsup.c b/ntoskrnl/cache/logsup.c
new file mode 100644
index 00000000000..b06432fc394
--- /dev/null
+++ b/ntoskrnl/cache/logsup.c
@@ -0,0 +1,75 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/logsup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include
+#include "newcc.h"
+#define NDEBUG
+#include
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+CcSetAdditionalCacheAttributes(IN PFILE_OBJECT FileObject,
+ IN BOOLEAN DisableReadAhead,
+ IN BOOLEAN DisableWriteBehind)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+VOID
+NTAPI
+CcSetLogHandleForFile(IN PFILE_OBJECT FileObject,
+ IN PVOID LogHandle,
+ IN PFLUSH_TO_LSN FlushToLsnRoutine)
+{
+ PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
+ if (!Map) return;
+ Map->LogHandle = LogHandle;
+ Map->FlushToLsn = FlushToLsnRoutine;
+}
+
+LARGE_INTEGER
+NTAPI
+CcGetDirtyPages(IN PVOID LogHandle,
+ IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine,
+ IN PVOID Context1,
+ IN PVOID Context2)
+{
+ LARGE_INTEGER Result = {{0}};
+ UNIMPLEMENTED;
+ while (TRUE);
+ return Result;
+}
+
+BOOLEAN
+NTAPI
+CcIsThereDirtyData(IN PVPB Vpb)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return FALSE;
+}
+
+LARGE_INTEGER
+NTAPI
+CcGetLsnForFileObject(IN PFILE_OBJECT FileObject,
+ OUT OPTIONAL PLARGE_INTEGER OldestLsn)
+{
+ LARGE_INTEGER Result = {{0}};
+ UNIMPLEMENTED;
+ while (TRUE);
+ return Result;
+}
+
+/* EOF */
diff --git a/ntoskrnl/cache/mdlsup.c b/ntoskrnl/cache/mdlsup.c
new file mode 100644
index 00000000000..6e558d5aa4c
--- /dev/null
+++ b/ntoskrnl/cache/mdlsup.c
@@ -0,0 +1,143 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/logsup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include
+#include "newcc.h"
+#define NDEBUG
+#include
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+
+PMDL
+NTAPI
+CcpBuildCacheMdl
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ ULONG Length,
+ PIO_STATUS_BLOCK IOSB)
+{
+ PMDL Mdl;
+ PVOID Bcb, Buffer;
+
+ BOOLEAN Result = CcMapData
+ (FileObject,
+ FileOffset,
+ Length,
+ PIN_WAIT,
+ &Bcb,
+ &Buffer);
+
+ if (!Result)
+ {
+ IOSB->Information = 0;
+ IOSB->Status = STATUS_UNSUCCESSFUL;
+ return NULL;
+ }
+
+ IOSB->Information = Length;
+ IOSB->Status = STATUS_SUCCESS;
+
+ Mdl = IoAllocateMdl
+ (Buffer,
+ Length,
+ FALSE,
+ FALSE,
+ NULL);
+
+ if (!Mdl)
+ {
+ IOSB->Information = 0;
+ IOSB->Status = STATUS_NO_MEMORY;
+ return NULL;
+ }
+
+ IOSB->Information = Length;
+ IOSB->Status = STATUS_SUCCESS;
+
+ return Mdl;
+}
+
+VOID
+NTAPI
+CcMdlRead(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ OUT PMDL *MdlChain,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ *MdlChain = CcpBuildCacheMdl
+ (FileObject,
+ FileOffset,
+ Length,
+ IoStatus);
+}
+
+VOID
+NTAPI
+CcMdlReadComplete(IN PFILE_OBJECT FileObject,
+ IN PMDL MdlChain)
+{
+ IoFreeMdl(MdlChain);
+}
+
+VOID
+NTAPI
+CcMdlReadComplete2(IN PMDL MdlChain,
+ IN PFILE_OBJECT FileObject)
+{
+ DPRINT("Not sure\n");
+}
+
+VOID
+NTAPI
+CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ OUT PMDL *MdlChain,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ *MdlChain = CcpBuildCacheMdl
+ (FileObject,
+ FileOffset,
+ Length,
+ IoStatus);
+}
+
+VOID
+NTAPI
+CcMdlWriteComplete(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PMDL MdlChain)
+{
+ IoFreeMdl(MdlChain);
+}
+
+VOID
+NTAPI
+CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PMDL MdlChain)
+{
+ DPRINT("Not sure\n");
+}
+
+VOID
+NTAPI
+CcMdlWriteAbort(IN PFILE_OBJECT FileObject,
+ IN PMDL MdlChain)
+{
+ ASSERT(FALSE);
+ IoFreeMdl(MdlChain);
+}
+
+/* EOF */
diff --git a/ntoskrnl/cache/newcc.h b/ntoskrnl/cache/newcc.h
new file mode 100644
index 00000000000..5e0bd2608eb
--- /dev/null
+++ b/ntoskrnl/cache/newcc.h
@@ -0,0 +1,170 @@
+#pragma once
+
+struct _MM_CACHE_SECTION_SEGMENT;
+
+typedef struct _NOCC_BCB
+{
+ /* Public part */
+ PUBLIC_BCB Bcb;
+
+ struct _NOCC_CACHE_MAP *Map;
+ struct _MM_CACHE_SECTION_SEGMENT *SectionObject;
+ LARGE_INTEGER FileOffset;
+ ULONG Length;
+ PVOID BaseAddress;
+ BOOLEAN Dirty;
+ PVOID OwnerPointer;
+
+ /* Reference counts */
+ ULONG RefCount;
+
+ LIST_ENTRY ThisFileList;
+
+ KEVENT ExclusiveWait;
+ ULONG ExclusiveWaiter;
+ BOOLEAN Exclusive;
+} NOCC_BCB, *PNOCC_BCB;
+
+typedef struct _NOCC_CACHE_MAP
+{
+ LIST_ENTRY Entry;
+ LIST_ENTRY AssociatedBcb;
+ LIST_ENTRY PrivateCacheMaps;
+ ULONG NumberOfMaps;
+ ULONG RefCount;
+ CC_FILE_SIZES FileSizes;
+ CACHE_MANAGER_CALLBACKS Callbacks;
+ PVOID LazyContext;
+ PVOID LogHandle;
+ PFLUSH_TO_LSN FlushToLsn;
+ ULONG ReadAheadGranularity;
+} NOCC_CACHE_MAP, *PNOCC_CACHE_MAP;
+
+VOID
+NTAPI
+CcPfInitializePrefetcher(
+ VOID
+);
+
+VOID
+NTAPI
+CcMdlReadComplete2(
+ IN PMDL MemoryDescriptorList,
+ IN PFILE_OBJECT FileObject
+);
+
+VOID
+NTAPI
+CcMdlWriteComplete2(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PMDL MdlChain
+);
+
+VOID
+NTAPI
+CcInitView(VOID);
+
+VOID
+NTAPI
+CcpUnpinData(PNOCC_BCB Bcb);
+
+BOOLEAN
+NTAPI
+CcInitializeCacheManager(VOID);
+
+VOID
+NTAPI
+CcShutdownSystem();
+
+VOID
+NTAPI
+CcInitCacheZeroPage(VOID);
+
+/* Called by section.c */
+BOOLEAN
+NTAPI
+CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer, MMFLUSH_TYPE FlushType);
+
+VOID
+NTAPI
+_CcpFlushCache
+(IN PNOCC_CACHE_MAP Map,
+ IN OPTIONAL PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
+ BOOLEAN Delete,
+ const char *File,
+ int Line);
+
+#define CcpFlushCache(M,F,L,I,D) _CcpFlushCache(M,F,L,I,D,__FILE__,__LINE__)
+
+BOOLEAN
+NTAPI
+CcGetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
+
+ULONG
+NTAPI
+CcpCountCacheSections(PNOCC_CACHE_MAP Map);
+
+BOOLEAN
+NTAPI
+CcpAcquireFileLock(PNOCC_CACHE_MAP Map);
+
+VOID
+NTAPI
+CcpReleaseFileLock(PNOCC_CACHE_MAP Map);
+
+/*
+ * Macro for generic cache manage bugchecking. Note that this macro assumes
+ * that the file name including extension is always longer than 4 characters.
+ */
+#define KEBUGCHECKCC \
+ KEBUGCHECKEX(CACHE_MANAGER, \
+ (*(ULONG*)(__FILE__ + sizeof(__FILE__) - 4) << 16) | \
+ (__LINE__ & 0xFFFF), 0, 0, 0)
+
+/* Private data */
+
+#define CACHE_SINGLE_FILE_MAX (16)
+#define CACHE_OVERALL_SIZE (32 * 1024 * 1024)
+#define CACHE_STRIPE VACB_MAPPING_GRANULARITY
+#define CACHE_SHIFT 18
+#define CACHE_NUM_SECTIONS (CACHE_OVERALL_SIZE / CACHE_STRIPE)
+#define CACHE_ROUND_UP(x) (((x) + (CACHE_STRIPE-1)) & ~(CACHE_STRIPE-1))
+#define CACHE_ROUND_DOWN(x) ((x) & ~(CACHE_STRIPE-1))
+#define INVALID_CACHE ((ULONG)~0)
+
+extern NOCC_BCB CcCacheSections[CACHE_NUM_SECTIONS];
+extern PRTL_BITMAP CcCacheBitmap;
+extern FAST_MUTEX CcMutex;
+extern KEVENT CcDeleteEvent;
+extern ULONG CcCacheClockHand;
+extern LIST_ENTRY CcPendingUnmap;
+extern KEVENT CcpLazyWriteEvent;
+
+#define CcpLock() _CcpLock(__FILE__,__LINE__)
+#define CcpUnlock() _CcpUnlock(__FILE__,__LINE__)
+
+extern VOID _CcpLock(const char *file, int line);
+extern VOID _CcpUnlock(const char *file, int line);
+
+extern VOID CcpReferenceCache(ULONG Sector);
+extern VOID CcpDereferenceCache(ULONG Sector, BOOLEAN Immediate);
+BOOLEAN
+NTAPI
+CcpMapData
+(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ OUT PVOID *BcbResult,
+ OUT PVOID *Buffer);
+
+BOOLEAN
+NTAPI
+CcpPinMappedData(IN PNOCC_CACHE_MAP Map,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ IN OUT PVOID *Bcb);
diff --git a/ntoskrnl/cache/pinsup.c b/ntoskrnl/cache/pinsup.c
new file mode 100644
index 00000000000..5531bbb9720
--- /dev/null
+++ b/ntoskrnl/cache/pinsup.c
@@ -0,0 +1,785 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/pinsup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ * Art Yerkes
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include
+#include "newcc.h"
+#include "section/newmm.h"
+#define NDEBUG
+#include
+
+/* The following is a test mode that only works with modified filesystems.
+ * it maps the cache sections read only until they're pinned writable, and then
+ * turns them readonly again when they're unpinned.
+ * This helped me determine that a certain bug was not a memory overwrite. */
+//#define PIN_WRITE_ONLY
+
+/* GLOBALS ********************************************************************/
+
+#define TAG_MAP_SEC TAG('C', 'c', 'S', 'x')
+#define TAG_MAP_READ TAG('M', 'c', 'p', 'y')
+#define TAG_MAP_BCB TAG('B', 'c', 'b', ' ')
+
+NOCC_BCB CcCacheSections[CACHE_NUM_SECTIONS];
+CHAR CcpBitmapBuffer[sizeof(RTL_BITMAP) + ROUND_UP((CACHE_NUM_SECTIONS), 32) / 8];
+PRTL_BITMAP CcCacheBitmap = (PRTL_BITMAP)&CcpBitmapBuffer;
+FAST_MUTEX CcMutex;
+KEVENT CcDeleteEvent;
+KEVENT CcFinalizeEvent;
+ULONG CcCacheClockHand;
+LONG CcOutstandingDeletes;
+
+/* FUNCTIONS ******************************************************************/
+
+PETHREAD LastThread;
+VOID _CcpLock(const char *file, int line)
+{
+ //DPRINT("<<<---<<< CC In Mutex(%s:%d %x)!\n", file, line, PsGetCurrentThread());
+ ExAcquireFastMutex(&CcMutex);
+}
+
+VOID _CcpUnlock(const char *file, int line)
+{
+ ExReleaseFastMutex(&CcMutex);
+ //DPRINT(">>>--->>> CC Exit Mutex!\n", file, line);
+}
+
+PDEVICE_OBJECT
+NTAPI
+MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject);
+
+NTSTATUS CcpAllocateSection
+(PFILE_OBJECT FileObject,
+ ULONG Length,
+ ULONG Protect,
+ PMM_CACHE_SECTION_SEGMENT *Result)
+{
+ NTSTATUS Status;
+ LARGE_INTEGER MaxSize;
+
+ MaxSize.QuadPart = Length;
+
+ DPRINT("Making Section for File %x\n", FileObject);
+ DPRINT("File name %wZ\n", &FileObject->FileName);
+ Status = MmCreateCacheSection
+ (Result,
+ STANDARD_RIGHTS_REQUIRED,
+ NULL,
+ &MaxSize,
+ Protect,
+ SEC_RESERVE | SEC_CACHE,
+ FileObject);
+
+ return Status;
+}
+
+typedef struct _WORK_QUEUE_WITH_CONTEXT
+{
+ WORK_QUEUE_ITEM WorkItem;
+ PVOID ToUnmap;
+ LARGE_INTEGER FileOffset;
+ LARGE_INTEGER MapSize;
+ PMM_CACHE_SECTION_SEGMENT ToDeref;
+ PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite;
+ PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite;
+ PVOID LazyContext;
+ BOOLEAN Dirty;
+} WORK_QUEUE_WITH_CONTEXT, *PWORK_QUEUE_WITH_CONTEXT;
+
+VOID
+CcpUnmapCache(PVOID Context)
+{
+ PWORK_QUEUE_WITH_CONTEXT WorkItem = (PWORK_QUEUE_WITH_CONTEXT)Context;
+ DPRINT("Unmapping (finally) %x\n", WorkItem->ToUnmap);
+ WorkItem->AcquireForLazyWrite(WorkItem->LazyContext, TRUE);
+ MiFlushMappedSection(WorkItem->ToUnmap, &WorkItem->FileOffset, &WorkItem->MapSize, WorkItem->Dirty);
+ WorkItem->ReleaseFromLazyWrite(WorkItem->LazyContext);
+ MmUnmapCacheViewInSystemSpace(WorkItem->ToUnmap);
+ MmFinalizeSegment(WorkItem->ToDeref);
+ ExFreePool(WorkItem);
+ DPRINT("Done\n");
+}
+
+/* Must have acquired the mutex */
+VOID CcpDereferenceCache(ULONG Start, BOOLEAN Immediate)
+{
+ PVOID ToUnmap;
+ PNOCC_BCB Bcb;
+ BOOLEAN Dirty;
+ LARGE_INTEGER MappedSize;
+ LARGE_INTEGER BaseOffset;
+ PWORK_QUEUE_WITH_CONTEXT WorkItem;
+
+ DPRINT("CcpDereferenceCache(#%x)\n", Start);
+
+ Bcb = &CcCacheSections[Start];
+
+ Dirty = Bcb->Dirty;
+ ToUnmap = Bcb->BaseAddress;
+ BaseOffset = Bcb->FileOffset;
+ MappedSize = Bcb->Map->FileSizes.ValidDataLength;
+
+ DPRINT("Dereference #%x (count %d)\n", Start, Bcb->RefCount);
+ ASSERT(Bcb->SectionObject);
+ ASSERT(Bcb->RefCount == 1);
+
+ DPRINT("Firing work item for %x\n", Bcb->BaseAddress);
+
+ if (Immediate)
+ {
+ PMM_CACHE_SECTION_SEGMENT ToDeref = Bcb->SectionObject;
+ BOOLEAN Dirty = Bcb->Dirty;
+
+ Bcb->Map = NULL;
+ Bcb->SectionObject = NULL;
+ Bcb->BaseAddress = NULL;
+ Bcb->FileOffset.QuadPart = 0;
+ Bcb->Length = 0;
+ Bcb->RefCount = 0;
+ Bcb->Dirty = FALSE;
+ RemoveEntryList(&Bcb->ThisFileList);
+
+ CcpUnlock();
+ MiFlushMappedSection(ToUnmap, &BaseOffset, &MappedSize, Dirty);
+ MmUnmapCacheViewInSystemSpace(ToUnmap);
+ MmFinalizeSegment(ToDeref);
+ CcpLock();
+ }
+ else
+ {
+ WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem));
+ if (!WorkItem) KeBugCheck(0);
+ WorkItem->ToUnmap = Bcb->BaseAddress;
+ WorkItem->FileOffset = Bcb->FileOffset;
+ WorkItem->Dirty = Bcb->Dirty;
+ WorkItem->MapSize = MappedSize;
+ WorkItem->ToDeref = Bcb->SectionObject;
+ WorkItem->AcquireForLazyWrite = Bcb->Map->Callbacks.AcquireForLazyWrite;
+ WorkItem->ReleaseFromLazyWrite = Bcb->Map->Callbacks.ReleaseFromLazyWrite;
+ WorkItem->LazyContext = Bcb->Map->LazyContext;
+
+ ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpUnmapCache, WorkItem);
+
+ Bcb->Map = NULL;
+ Bcb->SectionObject = NULL;
+ Bcb->BaseAddress = NULL;
+ Bcb->FileOffset.QuadPart = 0;
+ Bcb->Length = 0;
+ Bcb->RefCount = 0;
+ Bcb->Dirty = FALSE;
+ RemoveEntryList(&Bcb->ThisFileList);
+
+ CcpUnlock();
+ ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
+ CcpLock();
+ }
+ DPRINT("Done\n");
+}
+
+/* Needs mutex */
+ULONG CcpAllocateCacheSections
+(PFILE_OBJECT FileObject,
+ PMM_CACHE_SECTION_SEGMENT SectionObject)
+{
+ ULONG i = INVALID_CACHE;
+ PNOCC_CACHE_MAP Map;
+ PNOCC_BCB Bcb;
+
+ DPRINT("AllocateCacheSections: FileObject %x\n", FileObject);
+
+ if (!FileObject->SectionObjectPointer)
+ return INVALID_CACHE;
+
+ Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+
+ if (!Map)
+ return INVALID_CACHE;
+
+ DPRINT("Allocating Cache Section\n");
+
+ i = RtlFindClearBitsAndSet(CcCacheBitmap, 1, CcCacheClockHand);
+ CcCacheClockHand = (i + 1) % CACHE_NUM_SECTIONS;
+
+ if (i != INVALID_CACHE)
+ {
+ DPRINT("Setting up Bcb #%x\n", i);
+
+ Bcb = &CcCacheSections[i];
+
+ ASSERT(Bcb->RefCount < 2);
+
+ if (Bcb->RefCount > 0)
+ {
+ CcpDereferenceCache(i, FALSE);
+ }
+
+ ASSERT(!Bcb->RefCount);
+ Bcb->RefCount = 1;
+
+ DPRINT("Bcb #%x RefCount %d\n", Bcb - CcCacheSections, Bcb->RefCount);
+
+ if (!RtlTestBit(CcCacheBitmap, i))
+ {
+ DPRINT("Somebody stoeled BCB #%x\n", i);
+ }
+ ASSERT(RtlTestBit(CcCacheBitmap, i));
+
+ DPRINT("Allocated #%x\n", i);
+ ASSERT(CcCacheSections[i].RefCount);
+ }
+ else
+ {
+ DPRINT("Failed to allocate cache segment\n");
+ }
+ return i;
+}
+
+/* Must have acquired the mutex */
+VOID CcpReferenceCache(ULONG Start)
+{
+ PNOCC_BCB Bcb;
+ Bcb = &CcCacheSections[Start];
+ ASSERT(Bcb->SectionObject);
+ Bcb->RefCount++;
+ RtlSetBit(CcCacheBitmap, Start);
+
+}
+
+VOID CcpMarkForExclusive(ULONG Start)
+{
+ PNOCC_BCB Bcb;
+ Bcb = &CcCacheSections[Start];
+ Bcb->ExclusiveWaiter++;
+}
+
+/* Must not have the mutex */
+VOID CcpReferenceCacheExclusive(ULONG Start)
+{
+ PNOCC_BCB Bcb = &CcCacheSections[Start];
+
+ KeWaitForSingleObject(&Bcb->ExclusiveWait, Executive, KernelMode, FALSE, NULL);
+ CcpLock();
+ ASSERT(Bcb->ExclusiveWaiter);
+ ASSERT(Bcb->SectionObject);
+ Bcb->Exclusive = TRUE;
+ Bcb->ExclusiveWaiter--;
+ RtlSetBit(CcCacheBitmap, Start);
+ CcpUnlock();
+}
+
+/* Find a map that encompasses the target range */
+/* Must have the mutex */
+ULONG CcpFindMatchingMap(PLIST_ENTRY Head, PLARGE_INTEGER FileOffset, ULONG Length)
+{
+ PLIST_ENTRY Entry;
+ //DPRINT("Find Matching Map: (%x) %x:%x\n", FileOffset->LowPart, Length);
+ for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
+ {
+ //DPRINT("Link @%x\n", Entry);
+ PNOCC_BCB Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
+ //DPRINT("Selected BCB %x #%x\n", Bcb, Bcb - CcCacheSections);
+ //DPRINT("This File: %x:%x\n", Bcb->FileOffset.LowPart, Bcb->Length);
+ if (FileOffset->QuadPart >= Bcb->FileOffset.QuadPart &&
+ FileOffset->QuadPart < Bcb->FileOffset.QuadPart + CACHE_STRIPE)
+ {
+ //DPRINT("Found match at #%x\n", Bcb - CcCacheSections);
+ return Bcb - CcCacheSections;
+ }
+ }
+
+ //DPRINT("This region isn't mapped\n");
+
+ return INVALID_CACHE;
+}
+
+BOOLEAN
+NTAPI
+CcpMapData
+(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ OUT PVOID *BcbResult,
+ OUT PVOID *Buffer)
+{
+ BOOLEAN Success = FALSE, FaultIn = FALSE;
+ /* Note: windows 2000 drivers treat this as a bool */
+ //BOOLEAN Wait = (Flags & MAP_WAIT) || (Flags == TRUE);
+ LARGE_INTEGER Target, EndInterval;
+ ULONG BcbHead;
+ PNOCC_BCB Bcb = NULL;
+ PMM_CACHE_SECTION_SEGMENT SectionObject = NULL;
+ NTSTATUS Status;
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+
+ if (!Map)
+ {
+ DPRINT1("File object was not mapped\n");
+ return FALSE;
+ }
+
+ DPRINT("CcMapData(F->%x,%08x%08x:%d)\n", FileObject, FileOffset->HighPart, FileOffset->LowPart, Length);
+
+ ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
+
+ Target.HighPart = FileOffset->HighPart;
+ Target.LowPart = CACHE_ROUND_DOWN(FileOffset->LowPart);
+
+ CcpLock();
+
+ /* Find out if any range is a superset of what we want */
+ /* Find an accomodating section */
+ BcbHead = CcpFindMatchingMap(&Map->AssociatedBcb, FileOffset, Length);
+
+ if (BcbHead != INVALID_CACHE)
+ {
+ Bcb = &CcCacheSections[BcbHead];
+ Success = TRUE;
+ *BcbResult = Bcb;
+ *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart);
+ DPRINT
+ ("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n",
+ Bcb - CcCacheSections,
+ Bcb->FileOffset.HighPart,
+ Bcb->FileOffset.LowPart,
+ Bcb->BaseAddress,
+ Bcb->Length,
+ *Buffer,
+ Length,
+ &FileObject->FileName);
+ DPRINT("w1n\n");
+ goto cleanup;
+ }
+
+ ULONG SectionSize;
+
+ DPRINT("File size %08x%08x\n", Map->FileSizes.ValidDataLength.HighPart, Map->FileSizes.ValidDataLength.LowPart);
+
+ if (Map->FileSizes.ValidDataLength.QuadPart)
+ {
+ SectionSize = min(CACHE_STRIPE, Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart);
+ }
+ else
+ {
+ SectionSize = CACHE_STRIPE;
+ }
+
+ DPRINT("Allocating a cache stripe at %x:%d\n",
+ Target.LowPart, SectionSize);
+ //ASSERT(SectionSize <= CACHE_STRIPE);
+
+ CcpUnlock();
+ Status = CcpAllocateSection
+ (FileObject,
+ SectionSize,
+#ifdef PIN_WRITE_ONLY
+ PAGE_READONLY,
+#else
+ PAGE_READWRITE,
+#endif
+ &SectionObject);
+ CcpLock();
+
+ if (!NT_SUCCESS(Status))
+ {
+ *BcbResult = NULL;
+ *Buffer = NULL;
+ DPRINT1("End %08x\n", Status);
+ goto cleanup;
+ }
+
+retry:
+ /* Returns a reference */
+ DPRINT("Allocating cache sections: %wZ\n", &FileObject->FileName);
+ BcbHead = CcpAllocateCacheSections(FileObject, SectionObject);
+ if (BcbHead == INVALID_CACHE)
+ {
+ ULONG i;
+ DbgPrint("Cache Map:");
+ for (i = 0; i < CACHE_NUM_SECTIONS; i++)
+ {
+ if (!(i % 64)) DbgPrint("\n");
+ DbgPrint("%c", CcCacheSections[i].RefCount + (RtlTestBit(CcCacheBitmap, i) ? '@' : '`'));
+ }
+ DbgPrint("\n");
+ KeWaitForSingleObject(&CcDeleteEvent, Executive, KernelMode, FALSE, NULL);
+ goto retry;
+ }
+
+ DPRINT("BcbHead #%x (final)\n", BcbHead);
+
+ if (BcbHead == INVALID_CACHE)
+ {
+ *BcbResult = NULL;
+ *Buffer = NULL;
+ DPRINT1("End\n");
+ goto cleanup;
+ }
+
+ DPRINT("Selected BCB #%x\n", BcbHead);
+ ULONG ViewSize = CACHE_STRIPE;
+
+ Bcb = &CcCacheSections[BcbHead];
+ Status = MmMapCacheViewInSystemSpaceAtOffset
+ (SectionObject,
+ &Bcb->BaseAddress,
+ &Target,
+ &ViewSize);
+
+ if (!NT_SUCCESS(Status))
+ {
+ *BcbResult = NULL;
+ *Buffer = NULL;
+ MmFinalizeSegment(SectionObject);
+ RemoveEntryList(&Bcb->ThisFileList);
+ RtlZeroMemory(Bcb, sizeof(*Bcb));
+ RtlClearBit(CcCacheBitmap, BcbHead);
+ DPRINT1("Failed to map\n");
+ goto cleanup;
+ }
+
+ Success = TRUE;
+ //DPRINT("w1n\n");
+
+ Bcb->Length = MIN(Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart, CACHE_STRIPE);
+ Bcb->SectionObject = SectionObject;
+ Bcb->Map = Map;
+ Bcb->FileOffset = Target;
+ InsertTailList(&Map->AssociatedBcb, &Bcb->ThisFileList);
+
+ *BcbResult = &CcCacheSections[BcbHead];
+ *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart);
+ FaultIn = TRUE;
+
+ DPRINT
+ ("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n",
+ Bcb - CcCacheSections,
+ Bcb->FileOffset.HighPart,
+ Bcb->FileOffset.LowPart,
+ Bcb->BaseAddress,
+ Bcb->Length,
+ *Buffer,
+ Length,
+ &FileObject->FileName);
+
+ EndInterval.QuadPart = Bcb->FileOffset.QuadPart + Bcb->Length - 1;
+ ASSERT((EndInterval.QuadPart & ~(CACHE_STRIPE - 1)) == (Bcb->FileOffset.QuadPart & ~(CACHE_STRIPE - 1)));
+
+ //DPRINT("TERM!\n");
+
+cleanup:
+ CcpUnlock();
+ if (Success)
+ {
+ if (FaultIn)
+ {
+ // Fault in the pages. This forces reads to happen now.
+ ULONG i;
+ CHAR Dummy;
+ PCHAR FaultIn = Bcb->BaseAddress;
+ DPRINT1
+ ("Faulting in pages at this point: file %wZ %08x%08x:%x\n",
+ &FileObject->FileName,
+ Bcb->FileOffset.HighPart,
+ Bcb->FileOffset.LowPart,
+ Bcb->Length);
+ for (i = 0; i < Bcb->Length; i++)
+ {
+ Dummy = FaultIn[i];
+ }
+ }
+ ASSERT(Bcb >= CcCacheSections && Bcb < (CcCacheSections + CACHE_NUM_SECTIONS));
+ }
+ else
+ {
+ ASSERT(FALSE);
+ }
+
+ return Success;
+}
+
+BOOLEAN
+NTAPI
+CcMapData
+(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ OUT PVOID *BcbResult,
+ OUT PVOID *Buffer)
+{
+ BOOLEAN Result;
+
+ Result = CcpMapData
+ (FileObject,
+ FileOffset,
+ Length,
+ Flags,
+ BcbResult,
+ Buffer);
+
+ if (Result)
+ {
+ PNOCC_BCB Bcb = (PNOCC_BCB)*BcbResult;
+ ASSERT(Bcb >= CcCacheSections && Bcb < CcCacheSections + CACHE_NUM_SECTIONS);
+ ASSERT(Bcb->BaseAddress);
+ CcpLock();
+ CcpReferenceCache(Bcb - CcCacheSections);
+ CcpUnlock();
+ }
+
+ return Result;
+}
+
+BOOLEAN
+NTAPI
+CcpPinMappedData(IN PNOCC_CACHE_MAP Map,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ IN OUT PVOID *Bcb)
+{
+ BOOLEAN Exclusive = Flags & PIN_EXCLUSIVE;
+ ULONG BcbHead;
+ PNOCC_BCB TheBcb;
+
+ CcpLock();
+
+ ASSERT(Map->AssociatedBcb.Flink == &Map->AssociatedBcb || (CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList) >= CcCacheSections && CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList) < CcCacheSections + CACHE_NUM_SECTIONS));
+ BcbHead = CcpFindMatchingMap(&Map->AssociatedBcb, FileOffset, Length);
+ if (BcbHead == INVALID_CACHE)
+ {
+ CcpUnlock();
+ return FALSE;
+ }
+
+ TheBcb = &CcCacheSections[BcbHead];
+
+ if (Exclusive)
+ {
+ DPRINT("Requesting #%x Exclusive\n", BcbHead);
+ CcpMarkForExclusive(BcbHead);
+ }
+ else
+ {
+ DPRINT("Reference #%x\n", BcbHead);
+ CcpReferenceCache(BcbHead);
+ }
+
+ if (Exclusive)
+ CcpReferenceCacheExclusive(BcbHead);
+
+ CcpUnlock();
+
+ *Bcb = TheBcb;
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CcPinMappedData(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ IN OUT PVOID *Bcb)
+{
+ PVOID Buffer;
+ PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+
+ if (!Map)
+ {
+ DPRINT1("Not cached\n");
+ return FALSE;
+ }
+
+ if (CcpMapData(FileObject, FileOffset, Length, Flags, Bcb, &Buffer))
+ {
+ return CcpPinMappedData(Map, FileOffset, Length, Flags, Bcb);
+ }
+ else
+ {
+ DPRINT1("could not map\n");
+ return FALSE;
+ }
+}
+
+BOOLEAN
+NTAPI
+CcPinRead(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ OUT PVOID *Bcb,
+ OUT PVOID *Buffer)
+{
+ PNOCC_BCB RealBcb;
+ BOOLEAN Result;
+
+ Result = CcPinMappedData
+ (FileObject,
+ FileOffset,
+ Length,
+ Flags,
+ Bcb);
+
+ if (Result)
+ {
+ CcpLock();
+ RealBcb = *Bcb;
+ *Buffer = ((PCHAR)RealBcb->BaseAddress) + (int)(FileOffset->QuadPart - RealBcb->FileOffset.QuadPart);
+ CcpUnlock();
+ }
+
+ return Result;
+}
+
+BOOLEAN
+NTAPI
+CcPreparePinWrite(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Zero,
+ IN ULONG Flags,
+ OUT PVOID *Bcb,
+ OUT PVOID *Buffer)
+{
+ BOOLEAN Result;
+ PNOCC_BCB RealBcb;
+#ifdef PIN_WRITE_ONLY
+ PVOID BaseAddress;
+ SIZE_T NumberOfBytes;
+ ULONG OldProtect;
+#endif
+
+ DPRINT1("CcPreparePinWrite(%x:%x)\n", Buffer, Length);
+
+ Result = CcPinRead
+ (FileObject,
+ FileOffset,
+ Length,
+ Flags,
+ Bcb,
+ Buffer);
+
+ if (Result)
+ {
+ CcpLock();
+ RealBcb = *Bcb;
+
+#ifdef PIN_WRITE_ONLY
+ BaseAddress = RealBcb->BaseAddress;
+ NumberOfBytes = RealBcb->Length;
+
+ MiProtectVirtualMemory
+ (NULL,
+ &BaseAddress,
+ &NumberOfBytes,
+ PAGE_READWRITE,
+ &OldProtect);
+#endif
+
+ CcpUnlock();
+ RealBcb->Dirty = TRUE;
+
+ if (Zero)
+ {
+ DPRINT
+ ("Zero fill #%x %08x%08x:%x Buffer %x %wZ\n",
+ RealBcb - CcCacheSections,
+ FileOffset->u.HighPart,
+ FileOffset->u.LowPart,
+ Length,
+ *Buffer,
+ &FileObject->FileName);
+
+ DPRINT1("RtlZeroMemory(%x,%x)\n", *Buffer, Length);
+ RtlZeroMemory(*Buffer, Length);
+ }
+ }
+
+ return Result;
+}
+
+VOID
+NTAPI
+CcpUnpinData(IN PNOCC_BCB RealBcb)
+{
+ if (RealBcb->RefCount <= 2)
+ {
+ RealBcb->Exclusive = FALSE;
+ if (RealBcb->ExclusiveWaiter)
+ {
+ DPRINT("Triggering exclusive waiter\n");
+ KeSetEvent(&RealBcb->ExclusiveWait, IO_NO_INCREMENT, FALSE);
+ return;
+ }
+ }
+ if (RealBcb->RefCount > 1)
+ {
+ DPRINT("Removing one reference #%x\n", RealBcb - CcCacheSections);
+ RealBcb->RefCount--;
+ KeSetEvent(&CcDeleteEvent, IO_DISK_INCREMENT, FALSE);
+ }
+ if (RealBcb->RefCount == 1)
+ {
+ DPRINT("Clearing allocation bit #%x\n", RealBcb - CcCacheSections);
+ RtlClearBit(CcCacheBitmap, RealBcb - CcCacheSections);
+
+#ifdef PIN_WRITE_ONLY
+ PVOID BaseAddress = RealBcb->BaseAddress;
+ SIZE_T NumberOfBytes = RealBcb->Length;
+ ULONG OldProtect;
+
+ MiProtectVirtualMemory
+ (NULL,
+ &BaseAddress,
+ &NumberOfBytes,
+ PAGE_READONLY,
+ &OldProtect);
+#endif
+ }
+}
+
+VOID
+NTAPI
+CcUnpinData(IN PVOID Bcb)
+{
+ PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
+ ULONG Selected = RealBcb - CcCacheSections;
+
+ ASSERT(RealBcb >= CcCacheSections && RealBcb - CcCacheSections < CACHE_NUM_SECTIONS);
+ DPRINT("CcUnpinData Bcb #%x (RefCount %d)\n", Selected, RealBcb->RefCount);
+
+ CcpLock();
+ CcpUnpinData(RealBcb);
+ CcpUnlock();
+}
+
+VOID
+NTAPI
+CcSetBcbOwnerPointer(IN PVOID Bcb,
+ IN PVOID OwnerPointer)
+{
+ PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
+ CcpLock();
+ CcpReferenceCache(RealBcb - CcCacheSections);
+ RealBcb->OwnerPointer = OwnerPointer;
+ CcpUnlock();
+}
+
+VOID
+NTAPI
+CcUnpinDataForThread(IN PVOID Bcb,
+ IN ERESOURCE_THREAD ResourceThreadId)
+{
+ CcUnpinData(Bcb);
+}
+
+/* EOF */
diff --git a/ntoskrnl/cache/section/data.c b/ntoskrnl/cache/section/data.c
new file mode 100644
index 00000000000..4e2d81bcc32
--- /dev/null
+++ b/ntoskrnl/cache/section/data.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/section.c
+ * PURPOSE: Implements section objects
+ *
+ * PROGRAMMERS: Rex Jolliff
+ * David Welch
+ * Eric Kohl
+ * Emanuele Aliberti
+ * Eugene Ingerman
+ * Casper Hornstrup
+ * KJK::Hyperion
+ * Guido de Jong
+ * Ge van Geldorp
+ * Royce Mitchell III
+ * Filip Navara
+ * Aleksey Bragin
+ * Jason Filby
+ * Thomas Weidenmueller
+ * Gunnar Andre' Dalsnes
+ * Mike Nordell
+ * Alex Ionescu
+ * Gregor Anich
+ * Steven Edwards
+ * Herve Poussineau
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#include "newmm.h"
+#include "../newcc.h"
+#define NDEBUG
+#include
+
+#define DPRINTC DPRINT
+
+extern KEVENT MpwThreadEvent;
+extern KSPIN_LOCK MiSectionPageTableLock;
+
+/* GLOBALS *******************************************************************/
+
+ULONG_PTR MmSubsectionBase;
+BOOLEAN MmAllocationFragment;
+
+NTSTATUS
+NTAPI
+MiSimpleRead
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ ULONG Length,
+ PIO_STATUS_BLOCK ReadStatus);
+
+static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
+{
+ ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionBasicInformation */
+ ICI_SQ_SAME( sizeof(SECTION_IMAGE_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionImageInformation */
+};
+
+/* FUNCTIONS *****************************************************************/
+
+/* Note: Mmsp prefix denotes "Memory Manager Section Private". */
+
+VOID
+NTAPI
+_MmLockCacheSectionSegment(PMM_CACHE_SECTION_SEGMENT Segment, const char *file, int line)
+{
+ DPRINT("MmLockSectionSegment(%p,%s:%d)\n", Segment, file, line);
+ ExAcquireFastMutex(&Segment->Lock);
+}
+
+VOID
+NTAPI
+_MmUnlockCacheSectionSegment(PMM_CACHE_SECTION_SEGMENT Segment, const char *file, int line)
+{
+ ExReleaseFastMutex(&Segment->Lock);
+ DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment, file, line);
+}
+
+NTSTATUS
+NTAPI
+MiZeroFillSection
+(PVOID Address,
+ PLARGE_INTEGER FileOffsetPtr,
+ ULONG Length)
+{
+ PFN_NUMBER Page;
+ PMMSUPPORT AddressSpace;
+ PMEMORY_AREA MemoryArea;
+ PMM_CACHE_SECTION_SEGMENT Segment;
+ LARGE_INTEGER FileOffset = *FileOffsetPtr, End, FirstMapped;
+ DPRINT("MiZeroFillSection(Address %x,Offset %x,Length %x)\n", Address, FileOffset.LowPart, Length);
+ AddressSpace = MmGetKernelAddressSpace();
+ MmLockAddressSpace(AddressSpace);
+ MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
+ MmUnlockAddressSpace(AddressSpace);
+ if (!MemoryArea || MemoryArea->Type != MEMORY_AREA_SECTION_VIEW)
+ {
+ return STATUS_NOT_MAPPED_DATA;
+ }
+
+ Segment = MemoryArea->Data.CacheData.Segment;
+ End.QuadPart = FileOffset.QuadPart + Length;
+ End.LowPart = PAGE_ROUND_DOWN(End.LowPart);
+ FileOffset.LowPart = PAGE_ROUND_UP(FileOffset.LowPart);
+ FirstMapped.QuadPart = MemoryArea->Data.CacheData.ViewOffset.QuadPart;
+ DPRINT
+ ("Pulling zero pages for %08x%08x-%08x%08x\n",
+ FileOffset.u.HighPart, FileOffset.u.LowPart,
+ End.u.HighPart, End.u.LowPart);
+ while (FileOffset.QuadPart < End.QuadPart)
+ {
+ PVOID Address;
+ ULONG Entry;
+
+ if (!NT_SUCCESS(MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page)))
+ break;
+
+ MmLockAddressSpace(AddressSpace);
+ MmLockCacheSectionSegment(Segment);
+
+ Entry = MiGetPageEntryCacheSectionSegment(Segment, &FileOffset);
+ if (Entry == 0)
+ {
+ MiSetPageEntryCacheSectionSegment(Segment, &FileOffset, MAKE_PFN_SSE(Page));
+ Address = ((PCHAR)MemoryArea->StartingAddress) + FileOffset.QuadPart - FirstMapped.QuadPart;
+ MmReferencePage(Page);
+ MmCreateVirtualMapping(NULL, Address, PAGE_READWRITE, &Page, 1);
+ MmInsertRmap(Page, NULL, Address);
+ }
+ else
+ MmReleasePageMemoryConsumer(MC_CACHE, Page);
+
+ MmUnlockCacheSectionSegment(Segment);
+ MmUnlockAddressSpace(AddressSpace);
+
+ FileOffset.QuadPart += PAGE_SIZE;
+ }
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+_MiFlushMappedSection
+(PVOID BaseAddress,
+ PLARGE_INTEGER BaseOffset,
+ PLARGE_INTEGER FileSize,
+ BOOLEAN WriteData,
+ const char *File,
+ int Line)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG_PTR PageAddress;
+ PMMSUPPORT AddressSpace = MmGetKernelAddressSpace();
+ PMEMORY_AREA MemoryArea;
+ PMM_CACHE_SECTION_SEGMENT Segment;
+ ULONG_PTR BeginningAddress, EndingAddress;
+ LARGE_INTEGER ViewOffset;
+ LARGE_INTEGER FileOffset;
+ PFN_NUMBER Page;
+ PPFN_NUMBER Pages;
+
+ DPRINT("MiFlushMappedSection(%x,%08x,%x,%d,%s:%d)\n", BaseAddress, BaseOffset->LowPart, FileSize, WriteData, File, Line);
+
+ MmLockAddressSpace(AddressSpace);
+ MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+ if (!MemoryArea || MemoryArea->Type != MEMORY_AREA_CACHE)
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ DPRINT("STATUS_NOT_MAPPED_DATA\n");
+ return STATUS_NOT_MAPPED_DATA;
+ }
+ BeginningAddress = PAGE_ROUND_DOWN((ULONG_PTR)MemoryArea->StartingAddress);
+ EndingAddress = PAGE_ROUND_UP((ULONG_PTR)MemoryArea->EndingAddress);
+ Segment = MemoryArea->Data.CacheData.Segment;
+ ViewOffset.QuadPart = MemoryArea->Data.CacheData.ViewOffset.QuadPart;
+
+ ASSERT(ViewOffset.QuadPart == BaseOffset->QuadPart);
+
+ MmLockCacheSectionSegment(Segment);
+
+ Pages = ExAllocatePool
+ (NonPagedPool,
+ sizeof(PFN_NUMBER) *
+ ((EndingAddress - BeginningAddress) >> PAGE_SHIFT));
+
+ if (!Pages)
+ {
+ ASSERT(FALSE);
+ }
+
+ DPRINT("Getting pages in range %08x-%08x\n", BeginningAddress, EndingAddress);
+
+ for (PageAddress = BeginningAddress;
+ PageAddress < EndingAddress;
+ PageAddress += PAGE_SIZE)
+ {
+ ULONG Entry;
+ FileOffset.QuadPart = ViewOffset.QuadPart + PageAddress - BeginningAddress;
+ Entry =
+ MiGetPageEntryCacheSectionSegment
+ (MemoryArea->Data.CacheData.Segment,
+ &FileOffset);
+ Page = PFN_FROM_SSE(Entry);
+ if (Entry != 0 && !IS_SWAP_FROM_SSE(Entry) &&
+ (MmIsDirtyPageRmap(Page) || IS_DIRTY_SSE(Entry)) &&
+ FileOffset.QuadPart < FileSize->QuadPart)
+ {
+ Pages[(PageAddress - BeginningAddress) >> PAGE_SHIFT] = Page;
+ }
+ else
+ Pages[(PageAddress - BeginningAddress) >> PAGE_SHIFT] = 0;
+ }
+
+ MmUnlockCacheSectionSegment(Segment);
+ MmUnlockAddressSpace(AddressSpace);
+
+ for (PageAddress = BeginningAddress;
+ PageAddress < EndingAddress;
+ PageAddress += PAGE_SIZE)
+ {
+ FileOffset.QuadPart = ViewOffset.QuadPart + PageAddress - BeginningAddress;
+ Page = Pages[(PageAddress - BeginningAddress) >> PAGE_SHIFT];
+ if (Page)
+ {
+ ULONG Entry;
+ if (WriteData) {
+ DPRINT("MiWriteBackPage(%wZ,addr %x,%08x%08x)\n", &Segment->FileObject->FileName, PageAddress, FileOffset.u.HighPart, FileOffset.u.LowPart);
+ Status = MiWriteBackPage(Segment->FileObject, &FileOffset, PAGE_SIZE, Page);
+ } else
+ Status = STATUS_SUCCESS;
+
+ if (NT_SUCCESS(Status)) {
+ MmLockAddressSpace(AddressSpace);
+ MmSetCleanAllRmaps(Page);
+ MmLockCacheSectionSegment(Segment);
+ Entry = MiGetPageEntryCacheSectionSegment(Segment, &FileOffset);
+ if (Entry && !IS_SWAP_FROM_SSE(Entry) && PFN_FROM_SSE(Entry) == Page)
+ MiSetPageEntryCacheSectionSegment(Segment, &FileOffset, CLEAN_SSE(Entry));
+ MmUnlockCacheSectionSegment(Segment);
+ MmUnlockAddressSpace(AddressSpace);
+ } else {
+ DPRINT
+ ("Writeback from section flush %08x%08x (%x) %x@%x (%08x%08x:%wZ) failed %x\n",
+ FileOffset.u.HighPart, FileOffset.u.LowPart,
+ (ULONG)(FileSize->QuadPart - FileOffset.QuadPart),
+ PageAddress,
+ Page,
+ FileSize->u.HighPart,
+ FileSize->u.LowPart,
+ &Segment->FileObject->FileName,
+ Status);
+ }
+ }
+ }
+
+ ExFreePool(Pages);
+
+ return Status;
+}
+
+VOID
+NTAPI
+MmFinalizeSegment(PMM_CACHE_SECTION_SEGMENT Segment)
+{
+ KIRQL OldIrql = 0;
+
+ MmLockCacheSectionSegment(Segment);
+ if (Segment->Flags & MM_DATAFILE_SEGMENT) {
+ KeAcquireSpinLock(&Segment->FileObject->IrpListLock, &OldIrql);
+ if (Segment->Flags & MM_SEGMENT_FINALIZE) {
+ KeReleaseSpinLock(&Segment->FileObject->IrpListLock, OldIrql);
+ MmUnlockCacheSectionSegment(Segment);
+ return;
+ } else {
+ Segment->Flags |= MM_SEGMENT_FINALIZE;
+ }
+ }
+ DPRINTC("Finalizing segment %x\n", Segment);
+ if (Segment->Flags & MM_DATAFILE_SEGMENT)
+ {
+ //Segment->FileObject->SectionObjectPointer->DataSectionObject = NULL;
+ KeReleaseSpinLock(&Segment->FileObject->IrpListLock, OldIrql);
+ MiFreePageTablesSectionSegment(Segment, MiFreeSegmentPage);
+ MmUnlockCacheSectionSegment(Segment);
+ ObDereferenceObject(Segment->FileObject);
+ } else {
+ MiFreePageTablesSectionSegment(Segment, MiFreeSegmentPage);
+ MmUnlockCacheSectionSegment(Segment);
+ }
+ DPRINTC("Segment %x destroy\n", Segment);
+ ExFreePool(Segment);
+}
+
+NTSTATUS
+NTAPI
+MmCreateCacheSection
+(PMM_CACHE_SECTION_SEGMENT *SegmentObject,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PLARGE_INTEGER UMaximumSize,
+ ULONG SectionPageProtection,
+ ULONG AllocationAttributes,
+ PFILE_OBJECT FileObject)
+/*
+ * Create a section backed by a data file
+ */
+{
+ NTSTATUS Status;
+ ULARGE_INTEGER MaximumSize;
+ PMM_CACHE_SECTION_SEGMENT Segment;
+ ULONG FileAccess;
+ IO_STATUS_BLOCK Iosb;
+ CC_FILE_SIZES FileSizes;
+ FILE_STANDARD_INFORMATION FileInfo;
+
+ /*
+ * Check file access required
+ */
+ if (SectionPageProtection & PAGE_READWRITE ||
+ SectionPageProtection & PAGE_EXECUTE_READWRITE)
+ {
+ FileAccess = FILE_READ_DATA | FILE_WRITE_DATA;
+ }
+ else
+ {
+ FileAccess = FILE_READ_DATA;
+ }
+
+ /*
+ * Reference the file handle
+ */
+ ObReferenceObject(FileObject);
+
+ DPRINT("Getting original file size\n");
+ /* A hack: If we're cached, we can overcome deadlocking with the upper
+ * layer filesystem call by retriving the object sizes from the cache
+ * which is made to keep track. If I had to guess, they were figuring
+ * out a similar problem.
+ */
+ if (!CcGetFileSizes(FileObject, &FileSizes))
+ {
+ /*
+ * FIXME: This is propably not entirely correct. We can't look into
+ * the standard FCB header because it might not be initialized yet
+ * (as in case of the EXT2FS driver by Manoj Paul Joseph where the
+ * standard file information is filled on first request).
+ */
+ Status = IoQueryFileInformation
+ (FileObject,
+ FileStandardInformation,
+ sizeof(FILE_STANDARD_INFORMATION),
+ &FileInfo,
+ &Iosb.Information);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ ASSERT(Status != STATUS_PENDING);
+
+ FileSizes.ValidDataLength = FileInfo.EndOfFile;
+ FileSizes.FileSize = FileInfo.EndOfFile;
+ }
+ DPRINT("Got %08x\n", FileSizes.ValidDataLength.u.LowPart);
+
+ /*
+ * FIXME: Revise this once a locking order for file size changes is
+ * decided
+ */
+ if (UMaximumSize != NULL)
+ {
+ MaximumSize.QuadPart = UMaximumSize->QuadPart;
+ }
+ else
+ {
+ DPRINT("Got file size %08x%08x\n", FileSizes.FileSize.u.HighPart, FileSizes.FileSize.u.LowPart);
+ MaximumSize.QuadPart = FileSizes.FileSize.QuadPart;
+ }
+
+ Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_CACHE_SECTION_SEGMENT),
+ TAG_MM_SECTION_SEGMENT);
+ if (Segment == NULL)
+ {
+ return(STATUS_NO_MEMORY);
+ }
+
+ ExInitializeFastMutex(&Segment->Lock);
+
+ Segment->ReferenceCount = 1;
+
+ /*
+ * Set the lock before assigning the segment to the file object
+ */
+ ExAcquireFastMutex(&Segment->Lock);
+
+ DPRINT("Filling out Segment info (No previous data section)\n");
+ ObReferenceObject(FileObject);
+ Segment->FileObject = FileObject;
+ Segment->Protection = SectionPageProtection;
+ Segment->Flags = MM_DATAFILE_SEGMENT;
+ memset(&Segment->Image, 0, sizeof(Segment->Image));
+ Segment->WriteCopy = FALSE;
+ if (AllocationAttributes & SEC_RESERVE)
+ {
+ Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0;
+ }
+ else
+ {
+ Segment->RawLength = MaximumSize;
+ Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart);
+ }
+
+ MiInitializeSectionPageTable(Segment);
+ MmUnlockCacheSectionSegment(Segment);
+
+ /* Extend file if section is longer */
+ DPRINT("MaximumSize %08x%08x ValidDataLength %08x%08x\n",
+ MaximumSize.u.HighPart, MaximumSize.u.LowPart,
+ FileSizes.ValidDataLength.u.HighPart, FileSizes.ValidDataLength.u.LowPart);
+ if (MaximumSize.QuadPart > FileSizes.ValidDataLength.QuadPart)
+ {
+ DPRINT("Changing file size to %08x%08x, segment %x\n", MaximumSize.u.HighPart, MaximumSize.u.LowPart, Segment);
+ Status = IoSetInformation(FileObject, FileEndOfFileInformation, sizeof(LARGE_INTEGER), &MaximumSize);
+ DPRINT("Change: Status %x\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Could not expand section\n");
+ return Status;
+ }
+ }
+
+ DPRINTC("Segment %x created (%x)\n", Segment, Segment->Flags);
+
+ *SegmentObject = Segment;
+
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS
+NTAPI
+_MiMapViewOfSegment
+(PMMSUPPORT AddressSpace,
+ PMM_CACHE_SECTION_SEGMENT Segment,
+ PVOID* BaseAddress,
+ SIZE_T ViewSize,
+ ULONG Protect,
+ PLARGE_INTEGER ViewOffset,
+ ULONG AllocationType,
+ const char *file,
+ int line)
+{
+ PMEMORY_AREA MArea;
+ NTSTATUS Status;
+ PHYSICAL_ADDRESS BoundaryAddressMultiple;
+
+ BoundaryAddressMultiple.QuadPart = 0;
+
+ Status = MmCreateMemoryArea
+ (AddressSpace,
+ MEMORY_AREA_CACHE,
+ BaseAddress,
+ ViewSize,
+ Protect,
+ &MArea,
+ FALSE,
+ AllocationType,
+ BoundaryAddressMultiple);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Mapping between 0x%.8X and 0x%.8X failed (%X).\n",
+ (*BaseAddress), (char*)(*BaseAddress) + ViewSize, Status);
+ return(Status);
+ }
+
+ DPRINTC("MiMapViewOfSegment %x %x %x %x %x %wZ %s:%d\n", MmGetAddressSpaceOwner(AddressSpace), *BaseAddress, Segment, ViewOffset ? ViewOffset->LowPart : 0, ViewSize, Segment->FileObject ? &Segment->FileObject->FileName : NULL, file, line);
+
+ MArea->Data.CacheData.Segment = Segment;
+ if (ViewOffset)
+ MArea->Data.CacheData.ViewOffset = *ViewOffset;
+ else
+ MArea->Data.CacheData.ViewOffset.QuadPart = 0;
+
+#if 0
+ MArea->NotPresent = MmNotPresentFaultPageFile;
+ MArea->AccessFault = MiCowSectionPage;
+ MArea->PageOut = MmPageOutPageFileView;
+#endif
+
+ DPRINTC
+ ("MiMapViewOfSegment(P %x, A %x, T %x)\n",
+ MmGetAddressSpaceOwner(AddressSpace), *BaseAddress, MArea->Type);
+
+ return(STATUS_SUCCESS);
+}
+
+VOID
+NTAPI
+MiFreeSegmentPage
+(PMM_CACHE_SECTION_SEGMENT Segment,
+ PLARGE_INTEGER FileOffset)
+{
+ ULONG Entry;
+ PFILE_OBJECT FileObject = Segment->FileObject;
+
+ Entry = MiGetPageEntryCacheSectionSegment(Segment, FileOffset);
+ DPRINTC("MiFreeSegmentPage(%x:%08x%08x -> Entry %x\n",
+ Segment, FileOffset->HighPart, FileOffset->LowPart, Entry);
+
+ if (Entry && !IS_SWAP_FROM_SSE(Entry))
+ {
+ // The segment is carrying a dirty page.
+ PFN_NUMBER OldPage = PFN_FROM_SSE(Entry);
+ if (IS_DIRTY_SSE(Entry) && FileObject)
+ {
+ DPRINT("MiWriteBackPage(%x,%wZ,%08x%08x)\n", Segment, &FileObject->FileName, FileOffset->u.HighPart, FileOffset->u.LowPart);
+ MiWriteBackPage(FileObject, FileOffset, PAGE_SIZE, OldPage);
+ }
+ DPRINTC("Free page %x (off %x from %x) (ref ct %d, ent %x, dirty? %s)\n", OldPage, FileOffset->LowPart, Segment, MmGetReferenceCountPage(OldPage), Entry, IS_DIRTY_SSE(Entry) ? "true" : "false");
+
+ MiSetPageEntryCacheSectionSegment(Segment, FileOffset, 0);
+ MmReleasePageMemoryConsumer(MC_CACHE, OldPage);
+ }
+ else if (IS_SWAP_FROM_SSE(Entry))
+ {
+ DPRINT("Free swap\n");
+ MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry));
+ }
+
+ DPRINT("Done\n");
+}
+
+VOID
+MmFreeCacheSectionPage
+(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
+ PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
+{
+ ULONG Entry;
+ PVOID *ContextData = Context;
+ PMMSUPPORT AddressSpace;
+ PEPROCESS Process;
+ PMM_CACHE_SECTION_SEGMENT Segment;
+ LARGE_INTEGER Offset;
+
+ DPRINT("MmFreeSectionPage(%x,%x,%x,%x,%d)\n", MmGetAddressSpaceOwner(ContextData[0]), Address, Page, SwapEntry, Dirty);
+
+ AddressSpace = ContextData[0];
+ Process = MmGetAddressSpaceOwner(AddressSpace);
+ Address = (PVOID)PAGE_ROUND_DOWN(Address);
+ Segment = ContextData[1];
+ Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress +
+ MemoryArea->Data.CacheData.ViewOffset.QuadPart;
+
+ Entry = MiGetPageEntryCacheSectionSegment(Segment, &Offset);
+
+ if (Page)
+ {
+ DPRINT("Removing page %x:%x -> %x\n", Segment, Offset.LowPart, Entry);
+ MmSetSavedSwapEntryPage(Page, 0);
+ MmDeleteRmap(Page, Process, Address);
+ MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
+ MmReleasePageMemoryConsumer(MC_CACHE, Page);
+ }
+ if (Page != 0 && PFN_FROM_SSE(Entry) == Page && Dirty)
+ {
+ DPRINT("Freeing section page %x:%x -> %x\n", Segment, Offset.LowPart, Entry);
+ MiSetPageEntryCacheSectionSegment(Segment, &Offset, DIRTY_SSE(Entry));
+ }
+ else if (SwapEntry != 0)
+ {
+ MmFreeSwapPage(SwapEntry);
+ }
+}
+
+NTSTATUS
+NTAPI
+MmUnmapViewOfCacheSegment
+(PMMSUPPORT AddressSpace,
+ PVOID BaseAddress)
+{
+ PVOID Context[2];
+ PMEMORY_AREA MemoryArea;
+ PMM_CACHE_SECTION_SEGMENT Segment;
+
+ MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+ if (MemoryArea == NULL)
+ {
+ ASSERT(MemoryArea);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ MemoryArea->DeleteInProgress = TRUE;
+ Segment = MemoryArea->Data.CacheData.Segment;
+ MemoryArea->Data.CacheData.Segment = NULL;
+
+ MmLockCacheSectionSegment(Segment);
+
+ Context[0] = AddressSpace;
+ Context[1] = Segment;
+ DPRINT("MmFreeMemoryArea(%x,%x)\n", MmGetAddressSpaceOwner(AddressSpace), MemoryArea->StartingAddress);
+ MmFreeMemoryArea(AddressSpace, MemoryArea, MmFreeCacheSectionPage, Context);
+
+ MmUnlockCacheSectionSegment(Segment);
+
+ DPRINTC("MiUnmapViewOfSegment %x %x %x\n", MmGetAddressSpaceOwner(AddressSpace), BaseAddress, Segment);
+
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS
+NTAPI
+MmExtendCacheSection
+(PMM_CACHE_SECTION_SEGMENT Segment,
+ PLARGE_INTEGER NewSize,
+ BOOLEAN ExtendFile)
+{
+ LARGE_INTEGER OldSize;
+ DPRINT("Extend Segment %x\n", Segment);
+
+ MmLockCacheSectionSegment(Segment);
+ OldSize.QuadPart = Segment->RawLength.QuadPart;
+ MmUnlockCacheSectionSegment(Segment);
+
+ DPRINT("OldSize %08x%08x NewSize %08x%08x\n",
+ OldSize.u.HighPart, OldSize.u.LowPart,
+ NewSize->u.HighPart, NewSize->u.LowPart);
+
+ if (ExtendFile && OldSize.QuadPart < NewSize->QuadPart)
+ {
+ NTSTATUS Status;
+ Status = IoSetInformation(Segment->FileObject, FileEndOfFileInformation, sizeof(LARGE_INTEGER), NewSize);
+ if (!NT_SUCCESS(Status)) return Status;
+ }
+
+ MmLockCacheSectionSegment(Segment);
+ Segment->RawLength.QuadPart = NewSize->QuadPart;
+ Segment->Length.QuadPart = MAX(Segment->Length.QuadPart, PAGE_ROUND_UP(Segment->RawLength.LowPart));
+ MmUnlockCacheSectionSegment(Segment);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+MmMapCacheViewInSystemSpaceAtOffset
+(IN PMM_CACHE_SECTION_SEGMENT Segment,
+ OUT PVOID *MappedBase,
+ PLARGE_INTEGER FileOffset,
+ IN OUT PULONG ViewSize)
+{
+ PMMSUPPORT AddressSpace;
+ NTSTATUS Status;
+
+ DPRINT("MmMapViewInSystemSpaceAtOffset() called offset %08x%08x\n", FileOffset->HighPart, FileOffset->LowPart);
+
+ AddressSpace = MmGetKernelAddressSpace();
+
+ MmLockAddressSpace(AddressSpace);
+ MmLockCacheSectionSegment(Segment);
+
+ Status = MiMapViewOfSegment
+ (AddressSpace,
+ Segment,
+ MappedBase,
+ *ViewSize,
+ PAGE_READWRITE,
+ FileOffset,
+ 0);
+
+ MmUnlockCacheSectionSegment(Segment);
+ MmUnlockAddressSpace(AddressSpace);
+
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+MmUnmapCacheViewInSystemSpace (IN PVOID MappedBase)
+{
+ PMMSUPPORT AddressSpace;
+ NTSTATUS Status;
+
+ DPRINT("MmUnmapViewInSystemSpace() called\n");
+
+ AddressSpace = MmGetKernelAddressSpace();
+
+ Status = MmUnmapViewOfCacheSegment(AddressSpace, MappedBase);
+
+ return Status;
+}
+
+/* EOF */
diff --git a/ntoskrnl/cache/section/fault.c b/ntoskrnl/cache/section/fault.c
new file mode 100644
index 00000000000..204c264b579
--- /dev/null
+++ b/ntoskrnl/cache/section/fault.c
@@ -0,0 +1,766 @@
+/*
+ * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/section/fault.c
+ * PURPOSE: Consolidate fault handlers for sections
+ *
+ * PROGRAMMERS: Arty
+ * Rex Jolliff
+ * David Welch
+ * Eric Kohl
+ * Emanuele Aliberti
+ * Eugene Ingerman
+ * Casper Hornstrup
+ * KJK::Hyperion
+ * Guido de Jong
+ * Ge van Geldorp
+ * Royce Mitchell III
+ * Filip Navara
+ * Aleksey Bragin
+ * Jason Filby
+ * Thomas Weidenmueller
+ * Gunnar Andre' Dalsnes
+ * Mike Nordell
+ * Alex Ionescu
+ * Gregor Anich
+ * Steven Edwards
+ * Herve Poussineau
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#include "newmm.h"
+#define NDEBUG
+#include
+
+#define DPRINTC DPRINT
+
+extern KEVENT MmWaitPageEvent;
+
+NTSTATUS
+NTAPI
+MmNotPresentFaultCachePage
+(PMMSUPPORT AddressSpace,
+ MEMORY_AREA* MemoryArea,
+ PVOID Address,
+ BOOLEAN Locked,
+ PMM_REQUIRED_RESOURCES Required)
+{
+ NTSTATUS Status;
+ PVOID PAddress;
+ ULONG Consumer;
+ PMM_CACHE_SECTION_SEGMENT Segment;
+ LARGE_INTEGER FileOffset, TotalOffset;
+ ULONG Entry;
+ ULONG Attributes;
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
+ DPRINT("Not Present: %p %p (%p-%p)\n", AddressSpace, Address, MemoryArea->StartingAddress, MemoryArea->EndingAddress);
+
+ /*
+ * There is a window between taking the page fault and locking the
+ * address space when another thread could load the page so we check
+ * that.
+ */
+ if (MmIsPagePresent(Process, Address))
+ {
+ DPRINT("Done\n");
+ return(STATUS_SUCCESS);
+ }
+
+ PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
+ TotalOffset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress;
+
+ Segment = MemoryArea->Data.CacheData.Segment;
+
+ TotalOffset.QuadPart += MemoryArea->Data.CacheData.ViewOffset.QuadPart;
+ FileOffset = TotalOffset;
+
+ //Consumer = (Segment->Flags & MM_DATAFILE_SEGMENT) ? MC_CACHE : MC_USER;
+ Consumer = MC_CACHE;
+
+ if (Segment->FileObject)
+ {
+ DPRINT("FileName %wZ\n", &Segment->FileObject->FileName);
+ }
+
+ DPRINT("Total Offset %08x%08x\n", TotalOffset.HighPart, TotalOffset.LowPart);
+
+ /*
+ * Lock the segment
+ */
+ MmLockCacheSectionSegment(Segment);
+
+ /*
+ * Get the entry corresponding to the offset within the section
+ */
+ Entry = MiGetPageEntryCacheSectionSegment(Segment, &TotalOffset);
+
+ Attributes = PAGE_READONLY;
+
+ if (Required->State && Required->Page[0])
+ {
+ DPRINT("Have file and page, set page %x in section @ %x #\n", Required->Page[0], TotalOffset.LowPart);
+
+ if (Required->SwapEntry)
+ MmSetSavedSwapEntryPage(Required->Page[0], Required->SwapEntry);
+
+ if (Required->State & 2)
+ {
+ DPRINT("Set in section @ %x\n", TotalOffset.LowPart);
+ Status = MiSetPageEntryCacheSectionSegment
+ (Segment, &TotalOffset, Entry = MAKE_PFN_SSE(Required->Page[0]));
+ if (!NT_SUCCESS(Status))
+ {
+ MmReleasePageMemoryConsumer(MC_CACHE, Required->Page[0]);
+ }
+ MmUnlockCacheSectionSegment(Segment);
+ MiSetPageEvent(Process, Address);
+ DPRINT("Status %x\n", Status);
+ return STATUS_MM_RESTART_OPERATION;
+ }
+ else
+ {
+ DPRINT("Set %x in address space @ %x\n", Required->Page[0], Address);
+ Status = MmCreateVirtualMapping(Process, Address, Attributes, Required->Page, 1);
+ if (NT_SUCCESS(Status))
+ {
+ MmInsertRmap(Required->Page[0], Process, Address);
+ }
+ else
+ {
+ // Drop the reference for our address space ...
+ MmReleasePageMemoryConsumer(MC_CACHE, Required->Page[0]);
+ }
+ MmUnlockCacheSectionSegment(Segment);
+ DPRINTC("XXX Set Event %x\n", Status);
+ MiSetPageEvent(Process, Address);
+ DPRINT("Status %x\n", Status);
+ return Status;
+ }
+ }
+ else if (Entry)
+ {
+ PFN_NUMBER Page = PFN_FROM_SSE(Entry);
+ DPRINT("Take reference to page %x #\n", Page);
+
+ MmReferencePage(Page);
+
+ Status = MmCreateVirtualMapping(Process, Address, Attributes, &Page, 1);
+ if (NT_SUCCESS(Status))
+ {
+ MmInsertRmap(Page, Process, Address);
+ }
+ DPRINT("XXX Set Event %x\n", Status);
+ MiSetPageEvent(Process, Address);
+ MmUnlockCacheSectionSegment(Segment);
+ DPRINT("Status %x\n", Status);
+ return Status;
+ }
+ else
+ {
+ DPRINT("Get page into section\n");
+ /*
+ * If the entry is zero (and it can't change because we have
+ * locked the segment) then we need to load the page.
+ */
+ //DPRINT1("Read from file %08x %wZ\n", FileOffset.LowPart, &Section->FileObject->FileName);
+ Required->State = 2;
+ Required->Context = Segment->FileObject;
+ Required->Consumer = Consumer;
+ Required->FileOffset = FileOffset;
+ Required->Amount = PAGE_SIZE;
+ Required->DoAcquisition = MiReadFilePage;
+ MiSetPageEntryCacheSectionSegment(Segment, &TotalOffset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
+ MmUnlockCacheSectionSegment(Segment);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+ }
+ ASSERT(FALSE);
+ return STATUS_ACCESS_VIOLATION;
+}
+
+NTSTATUS
+NTAPI
+MiCopyPageToPage(PFN_NUMBER DestPage, PFN_NUMBER SrcPage)
+{
+ PEPROCESS Process;
+ KIRQL Irql, Irql2;
+ PVOID TempAddress, TempSource;
+
+ Process = PsGetCurrentProcess();
+ TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
+ if (TempAddress == NULL)
+ {
+ return(STATUS_NO_MEMORY);
+ }
+ TempSource = MiMapPageInHyperSpace(Process, SrcPage, &Irql2);
+ if (!TempSource) {
+ MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
+ return(STATUS_NO_MEMORY);
+ }
+
+ memcpy(TempAddress, TempSource, PAGE_SIZE);
+
+ MiUnmapPageInHyperSpace(Process, TempSource, Irql2);
+ MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS
+NTAPI
+MiCowCacheSectionPage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PVOID Address,
+ BOOLEAN Locked,
+ PMM_REQUIRED_RESOURCES Required)
+{
+ PMM_CACHE_SECTION_SEGMENT Segment;
+ PFN_NUMBER NewPage, OldPage;
+ NTSTATUS Status;
+ PVOID PAddress;
+ LARGE_INTEGER Offset;
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
+ DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address, Locked);
+
+ Segment = MemoryArea->Data.CacheData.Segment;
+
+ /*
+ * Lock the segment
+ */
+ MmLockCacheSectionSegment(Segment);
+
+ /*
+ * Find the offset of the page
+ */
+ PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
+ Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress +
+ MemoryArea->Data.CacheData.ViewOffset.QuadPart;
+
+#if 0 // XXX Cache sections are not CoW. For now, treat all access violations this way.
+ if ((!Segment->WriteCopy &&
+ !MemoryArea->Data.CacheData.WriteCopyView) ||
+ Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
+#endif
+ {
+#if 0 // XXX Cache sections don't have regions at present, which streamlines things
+ if (Region->Protect == PAGE_READWRITE ||
+ Region->Protect == PAGE_EXECUTE_READWRITE)
+#endif
+ {
+ DPRINTC("setting non-cow page %x %x:%x offset %x (%x) to writable\n", Segment, Process, PAddress, Offset.u.LowPart, MmGetPfnForProcess(Process, Address));
+ if (Segment->FileObject)
+ {
+ DPRINTC("file %wZ\n", &Segment->FileObject->FileName);
+ }
+ ULONG Entry = MiGetPageEntryCacheSectionSegment(Segment, &Offset);
+ DPRINT("Entry %x\n", Entry);
+ if (Entry &&
+ !IS_SWAP_FROM_SSE(Entry) &&
+ PFN_FROM_SSE(Entry) == MmGetPfnForProcess(Process, Address)) {
+ MiSetPageEntryCacheSectionSegment(Segment, &Offset, DIRTY_SSE(Entry));
+ }
+ MmSetPageProtect(Process, PAddress, PAGE_READWRITE);
+ MmUnlockCacheSectionSegment(Segment);
+ DPRINT("Done\n");
+ return STATUS_SUCCESS;
+ }
+#if 0
+ else
+ {
+ DPRINT("Not supposed to be writable\n");
+ MmUnlockCacheSectionSegment(Segment);
+ return STATUS_ACCESS_VIOLATION;
+ }
+#endif
+ }
+
+ if (!Required->Page[0])
+ {
+ SWAPENTRY SwapEntry;
+ if (MmIsPageSwapEntry(Process, Address))
+ {
+ MmGetPageFileMapping(Process, Address, &SwapEntry);
+ MmUnlockCacheSectionSegment(Segment);
+ if (SwapEntry == MM_WAIT_ENTRY)
+ return STATUS_SUCCESS + 1; // Wait ... somebody else is getting it right now
+ else
+ return STATUS_SUCCESS; // Nonwait swap entry ... handle elsewhere
+ }
+ Required->Page[1] = MmGetPfnForProcess(Process, Address);
+ Required->Consumer = MC_CACHE;
+ Required->Amount = 1;
+ Required->File = __FILE__;
+ Required->Line = __LINE__;
+ Required->DoAcquisition = MiGetOnePage;
+ MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
+ MmUnlockCacheSectionSegment(Segment);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+ }
+
+ NewPage = Required->Page[0];
+ OldPage = Required->Page[1];
+
+ DPRINT("Allocated page %x\n", NewPage);
+
+ /*
+ * Unshare the old page.
+ */
+ MmDeleteRmap(OldPage, Process, PAddress);
+
+ /*
+ * Copy the old page
+ */
+ DPRINT("Copying\n");
+ MiCopyPageToPage(NewPage, OldPage);
+
+ /*
+ * Set the PTE to point to the new page
+ */
+ Status = MmCreateVirtualMapping
+ (Process, Address, PAGE_READWRITE, &NewPage, 1);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
+ ASSERT(FALSE);
+ MmUnlockCacheSectionSegment(Segment);
+ return(Status);
+ }
+
+ MmInsertRmap(NewPage, Process, PAddress);
+ MmReleasePageMemoryConsumer(MC_CACHE, OldPage);
+ MmUnlockCacheSectionSegment(Segment);
+
+ DPRINT("Address 0x%.8X\n", Address);
+ return(STATUS_SUCCESS);
+}
+
+KEVENT MmWaitPageEvent;
+
+typedef struct _WORK_QUEUE_WITH_CONTEXT
+{
+ WORK_QUEUE_ITEM WorkItem;
+ PMMSUPPORT AddressSpace;
+ PMEMORY_AREA MemoryArea;
+ PMM_REQUIRED_RESOURCES Required;
+ NTSTATUS Status;
+ KEVENT Wait;
+ AcquireResource DoAcquisition;
+} WORK_QUEUE_WITH_CONTEXT, *PWORK_QUEUE_WITH_CONTEXT;
+
+VOID
+NTAPI
+MmpFaultWorker
+(PWORK_QUEUE_WITH_CONTEXT WorkItem)
+{
+ DPRINT("Calling work\n");
+ WorkItem->Status =
+ WorkItem->Required->DoAcquisition
+ (WorkItem->AddressSpace,
+ WorkItem->MemoryArea,
+ WorkItem->Required);
+ DPRINT("Status %x\n", WorkItem->Status);
+ KeSetEvent(&WorkItem->Wait, IO_NO_INCREMENT, FALSE);
+}
+
+NTSTATUS
+NTAPI
+MmpSectionAccessFaultInner
+(KPROCESSOR_MODE Mode,
+ PMMSUPPORT AddressSpace,
+ ULONG_PTR Address,
+ BOOLEAN FromMdl,
+ PETHREAD Thread)
+{
+ MEMORY_AREA* MemoryArea;
+ NTSTATUS Status;
+ BOOLEAN Locked = FromMdl;
+ MM_REQUIRED_RESOURCES Resources = { 0 };
+
+ DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
+
+ if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
+ {
+ DPRINT1("Page fault at high IRQL was %d\n", KeGetCurrentIrql());
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ /*
+ * Find the memory area for the faulting address
+ */
+ if (Address >= (ULONG_PTR)MmSystemRangeStart)
+ {
+ /*
+ * Check permissions
+ */
+ if (Mode != KernelMode)
+ {
+ DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
+ return(STATUS_ACCESS_VIOLATION);
+ }
+ AddressSpace = MmGetKernelAddressSpace();
+ }
+ else
+ {
+ AddressSpace = &PsGetCurrentProcess()->Vm;
+ }
+
+ if (!FromMdl)
+ {
+ MmLockAddressSpace(AddressSpace);
+ }
+
+ do
+ {
+ MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
+ if (MemoryArea == NULL ||
+ MemoryArea->DeleteInProgress)
+ {
+ if (!FromMdl)
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ }
+ DPRINT("Address: %x\n", Address);
+ return (STATUS_ACCESS_VIOLATION);
+ }
+
+ DPRINT
+ ("Type %x (%x -> %x)\n",
+ MemoryArea->Type,
+ MemoryArea->StartingAddress,
+ MemoryArea->EndingAddress);
+
+ Resources.DoAcquisition = NULL;
+
+ // Note: fault handlers are called with address space locked
+ // We return STATUS_MORE_PROCESSING_REQUIRED if anything is needed
+ Status = MiCowCacheSectionPage
+ (AddressSpace, MemoryArea, (PVOID)Address, Locked, &Resources);
+
+ if (!FromMdl)
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ }
+
+ if (Status == STATUS_SUCCESS + 1)
+ {
+ // Wait page ...
+ DPRINT("Waiting for %x\n", Address);
+ MiWaitForPageEvent(MmGetAddressSpaceOwner(AddressSpace), Address);
+ DPRINT("Restarting fault %x\n", Address);
+ Status = STATUS_MM_RESTART_OPERATION;
+ }
+ else if (Status == STATUS_MM_RESTART_OPERATION)
+ {
+ // Clean slate
+ RtlZeroMemory(&Resources, sizeof(Resources));
+ }
+ else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
+ {
+ if (Thread->ActiveFaultCount > 0)
+ {
+ WORK_QUEUE_WITH_CONTEXT Context = { };
+ DPRINT("Already fault handling ... going to work item (%x)\n", Address);
+ Context.AddressSpace = AddressSpace;
+ Context.MemoryArea = MemoryArea;
+ Context.Required = &Resources;
+ KeInitializeEvent(&Context.Wait, NotificationEvent, FALSE);
+ ExInitializeWorkItem(&Context.WorkItem, (PWORKER_THREAD_ROUTINE)MmpFaultWorker, &Context);
+ DPRINT("Queue work item\n");
+ ExQueueWorkItem(&Context.WorkItem, DelayedWorkQueue);
+ DPRINT("Wait\n");
+ KeWaitForSingleObject(&Context.Wait, 0, KernelMode, FALSE, NULL);
+ Status = Context.Status;
+ DPRINT("Status %x\n", Status);
+ }
+ else
+ {
+ Status = Resources.DoAcquisition(AddressSpace, MemoryArea, &Resources);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ Status = STATUS_MM_RESTART_OPERATION;
+ }
+ }
+
+ if (!FromMdl)
+ {
+ MmLockAddressSpace(AddressSpace);
+ }
+ }
+ while (Status == STATUS_MM_RESTART_OPERATION);
+
+ if (!NT_SUCCESS(Status) && MemoryArea->Type == 1)
+ {
+ DPRINT1("Completed page fault handling %x %x\n", Address, Status);
+ DPRINT1
+ ("Type %x (%x -> %x)\n",
+ MemoryArea->Type,
+ MemoryArea->StartingAddress,
+ MemoryArea->EndingAddress);
+ }
+
+ if (!FromMdl)
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ }
+
+ return(Status);
+}
+
+NTSTATUS
+NTAPI
+MmAccessFaultCacheSection
+(KPROCESSOR_MODE Mode,
+ ULONG_PTR Address,
+ BOOLEAN FromMdl)
+{
+ PETHREAD Thread;
+ PMMSUPPORT AddressSpace;
+ NTSTATUS Status;
+
+ DPRINT("MmpAccessFault(Mode %d, Address %x)\n", Mode, Address);
+
+ Thread = PsGetCurrentThread();
+
+ if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
+ {
+ DPRINT1("Page fault at high IRQL %d, address %x\n", KeGetCurrentIrql(), Address);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ /*
+ * Find the memory area for the faulting address
+ */
+ if (Address >= (ULONG_PTR)MmSystemRangeStart)
+ {
+ /*
+ * Check permissions
+ */
+ if (Mode != KernelMode)
+ {
+ DPRINT1("Address: %x:%x\n", PsGetCurrentProcess(), Address);
+ return(STATUS_ACCESS_VIOLATION);
+ }
+ AddressSpace = MmGetKernelAddressSpace();
+ }
+ else
+ {
+ AddressSpace = &PsGetCurrentProcess()->Vm;
+ }
+
+ Thread->ActiveFaultCount++;
+ Status = MmpSectionAccessFaultInner(Mode, AddressSpace, Address, FromMdl, Thread);
+ Thread->ActiveFaultCount--;
+
+ return(Status);
+}
+
+NTSTATUS
+NTAPI
+MmNotPresentFaultCacheSectionInner
+(KPROCESSOR_MODE Mode,
+ PMMSUPPORT AddressSpace,
+ ULONG_PTR Address,
+ BOOLEAN FromMdl,
+ PETHREAD Thread)
+{
+ BOOLEAN Locked = FromMdl;
+ PMEMORY_AREA MemoryArea;
+ MM_REQUIRED_RESOURCES Resources = { 0 };
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (!FromMdl)
+ {
+ MmLockAddressSpace(AddressSpace);
+ }
+
+ /*
+ * Call the memory area specific fault handler
+ */
+ do
+ {
+ MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
+ if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
+ {
+ Status = STATUS_ACCESS_VIOLATION;
+ if (MemoryArea)
+ {
+ DPRINT1("Type %x DIP %x\n", MemoryArea->Type, MemoryArea->DeleteInProgress);
+ }
+ else
+ {
+ DPRINT1("No memory area\n");
+ }
+ DPRINT1("Process %x, Address %x\n", MmGetAddressSpaceOwner(AddressSpace), Address);
+ break;
+ }
+
+ DPRINTC
+ ("Type %x (%x -> %x -> %x) in %x\n",
+ MemoryArea->Type,
+ MemoryArea->StartingAddress,
+ Address,
+ MemoryArea->EndingAddress,
+ PsGetCurrentThread());
+
+ Resources.DoAcquisition = NULL;
+
+ // Note: fault handlers are called with address space locked
+ // We return STATUS_MORE_PROCESSING_REQUIRED if anything is needed
+
+ Status = MmNotPresentFaultCachePage
+ (AddressSpace, MemoryArea, (PVOID)Address, Locked, &Resources);
+
+ if (!FromMdl)
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ }
+
+ if (Status == STATUS_SUCCESS)
+ {
+ ; // Nothing
+ }
+ else if (Status == STATUS_SUCCESS + 1)
+ {
+ // Wait page ...
+ DPRINT("Waiting for %x\n", Address);
+ MiWaitForPageEvent(MmGetAddressSpaceOwner(AddressSpace), Address);
+ DPRINT("Done waiting for %x\n", Address);
+ Status = STATUS_MM_RESTART_OPERATION;
+ }
+ else if (Status == STATUS_MM_RESTART_OPERATION)
+ {
+ // Clean slate
+ DPRINT("Clear resource\n");
+ RtlZeroMemory(&Resources, sizeof(Resources));
+ }
+ else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
+ {
+ if (Thread->ActiveFaultCount > 1)
+ {
+ WORK_QUEUE_WITH_CONTEXT Context = { };
+ DPRINTC("Already fault handling ... going to work item (%x)\n", Address);
+ Context.AddressSpace = AddressSpace;
+ Context.MemoryArea = MemoryArea;
+ Context.Required = &Resources;
+ KeInitializeEvent(&Context.Wait, NotificationEvent, FALSE);
+ ExInitializeWorkItem(&Context.WorkItem, (PWORKER_THREAD_ROUTINE)MmpFaultWorker, &Context);
+ DPRINT("Queue work item\n");
+ ExQueueWorkItem(&Context.WorkItem, DelayedWorkQueue);
+ DPRINT("Wait\n");
+ KeWaitForSingleObject(&Context.Wait, 0, KernelMode, FALSE, NULL);
+ Status = Context.Status;
+ DPRINTC("Status %x\n", Status);
+ }
+ else
+ {
+ DPRINT("DoAcquisition %x\n", Resources.DoAcquisition);
+ Status = Resources.DoAcquisition
+ (AddressSpace, MemoryArea, &Resources);
+ DPRINT("DoAcquisition %x -> %x\n", Resources.DoAcquisition, Status);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ Status = STATUS_MM_RESTART_OPERATION;
+ }
+ }
+ else if (NT_SUCCESS(Status))
+ {
+ ASSERT(FALSE);
+ }
+
+ if (!FromMdl)
+ {
+ MmLockAddressSpace(AddressSpace);
+ }
+ }
+ while (Status == STATUS_MM_RESTART_OPERATION);
+
+ DPRINTC("Completed page fault handling: %x:%x %x\n", MmGetAddressSpaceOwner(AddressSpace), Address, Status);
+ if (!FromMdl)
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ }
+
+ MiSetPageEvent(MmGetAddressSpaceOwner(AddressSpace), Address);
+ DPRINT("Done %x\n", Status);
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+MmNotPresentFaultCacheSection
+(KPROCESSOR_MODE Mode,
+ ULONG_PTR Address,
+ BOOLEAN FromMdl)
+{
+ PETHREAD Thread;
+ PMMSUPPORT AddressSpace;
+ NTSTATUS Status;
+
+ Address &= ~(PAGE_SIZE - 1);
+ DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address);
+
+ Thread = PsGetCurrentThread();
+
+ if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
+ {
+ DPRINT1("Page fault at high IRQL %d, address %x\n", KeGetCurrentIrql(), Address);
+ ASSERT(FALSE);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ /*
+ * Find the memory area for the faulting address
+ */
+ if (Address >= (ULONG_PTR)MmSystemRangeStart)
+ {
+ /*
+ * Check permissions
+ */
+ if (Mode != KernelMode)
+ {
+ DPRINTC("Address: %x\n", Address);
+ return(STATUS_ACCESS_VIOLATION);
+ }
+ AddressSpace = MmGetKernelAddressSpace();
+ }
+ else
+ {
+ AddressSpace = &PsGetCurrentProcess()->Vm;
+ }
+
+ Thread->ActiveFaultCount++;
+ Status = MmNotPresentFaultCacheSectionInner
+ (Mode, AddressSpace, Address, FromMdl, Thread);
+ Thread->ActiveFaultCount--;
+
+ ASSERT(Status != STATUS_UNSUCCESSFUL);
+ ASSERT(Status != STATUS_INVALID_PARAMETER);
+ DPRINT("MmAccessFault %x:%x -> %x\n", MmGetAddressSpaceOwner(AddressSpace), Address, Status);
+
+ return(Status);
+}
diff --git a/ntoskrnl/cache/section/io.c b/ntoskrnl/cache/section/io.c
new file mode 100644
index 00000000000..254c25c38a6
--- /dev/null
+++ b/ntoskrnl/cache/section/io.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/section.c
+ * PURPOSE: Implements section objects
+ *
+ * PROGRAMMERS: Rex Jolliff
+ * David Welch
+ * Eric Kohl
+ * Emanuele Aliberti
+ * Eugene Ingerman
+ * Casper Hornstrup
+ * KJK::Hyperion
+ * Guido de Jong
+ * Ge van Geldorp
+ * Royce Mitchell III
+ * Filip Navara
+ * Aleksey Bragin
+ * Jason Filby
+ * Thomas Weidenmueller
+ * Gunnar Andre' Dalsnes
+ * Mike Nordell
+ * Alex Ionescu
+ * Gregor Anich
+ * Steven Edwards
+ * Herve Poussineau
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#include "newmm.h"
+#define NDEBUG
+#include
+#include
+
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, MmCreatePhysicalMemorySection)
+#pragma alloc_text(INIT, MmInitSectionImplementation)
+#endif
+
+KEVENT CcpLazyWriteEvent;
+
+PDEVICE_OBJECT
+NTAPI
+MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject)
+{
+ return IoGetRelatedDeviceObject(FileObject);
+}
+
+NTSTATUS
+NTAPI
+MiSimpleReadComplete
+(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID Context)
+{
+ /* Unlock MDL Pages, page 167. */
+ DPRINT("MiSimpleReadComplete %x\n", Irp);
+ PMDL Mdl = Irp->MdlAddress;
+ while (Mdl)
+ {
+ DPRINT("MDL Unlock %x\n", Mdl);
+ MmUnlockPages(Mdl);
+ Mdl = Mdl->Next;
+ }
+
+ /* Check if there's an MDL */
+ while ((Mdl = Irp->MdlAddress))
+ {
+ /* Clear all of them */
+ Irp->MdlAddress = Mdl->Next;
+ IoFreeMdl(Mdl);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+MiSimpleRead
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ ULONG Length,
+ PIO_STATUS_BLOCK ReadStatus)
+{
+ NTSTATUS Status;
+ PIRP Irp = NULL;
+ KEVENT ReadWait;
+ PDEVICE_OBJECT DeviceObject;
+ PIO_STACK_LOCATION IrpSp;
+
+ ASSERT(FileObject);
+ ASSERT(FileOffset);
+ ASSERT(Buffer);
+ ASSERT(ReadStatus);
+
+ DeviceObject = MmGetDeviceObjectForFile(FileObject);
+ ReadStatus->Status = STATUS_INTERNAL_ERROR;
+ ReadStatus->Information = 0;
+
+ ASSERT(DeviceObject);
+
+ DPRINT
+ ("PAGING READ: FileObject %x <%wZ> Offset %08x%08x Length %d\n",
+ &FileObject,
+ &FileObject->FileName,
+ FileOffset->HighPart,
+ FileOffset->LowPart,
+ Length);
+
+ KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
+
+ Irp = IoBuildAsynchronousFsdRequest
+ (IRP_MJ_READ,
+ DeviceObject,
+ Buffer,
+ Length,
+ FileOffset,
+ ReadStatus);
+
+ if (!Irp)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ Irp->Flags |= IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE | IRP_SYNCHRONOUS_API;
+
+ Irp->UserEvent = &ReadWait;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ IrpSp = IoGetNextIrpStackLocation(Irp);
+ IrpSp->Control |= SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR;
+ IrpSp->FileObject = FileObject;
+ IrpSp->CompletionRoutine = MiSimpleReadComplete;
+
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ DPRINT1("KeWaitForSingleObject(&ReadWait)\n");
+ if (!NT_SUCCESS
+ (KeWaitForSingleObject
+ (&ReadWait,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL)))
+ {
+ DPRINT1("Warning: Failed to wait for synchronous IRP\n");
+ ASSERT(FALSE);
+ return Status;
+ }
+ }
+
+ DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
+ Status =
+ ReadStatus->Status == STATUS_END_OF_FILE ?
+ STATUS_SUCCESS : ReadStatus->Status;
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+_MiSimpleWrite
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ ULONG Length,
+ PIO_STATUS_BLOCK ReadStatus,
+ const char *File,
+ int Line)
+{
+ NTSTATUS Status;
+ PIRP Irp = NULL;
+ KEVENT ReadWait;
+ PDEVICE_OBJECT DeviceObject;
+ PIO_STACK_LOCATION IrpSp;
+
+ ASSERT(FileObject);
+ ASSERT(FileOffset);
+ ASSERT(Buffer);
+ ASSERT(ReadStatus);
+
+ ObReferenceObject(FileObject);
+ DeviceObject = MmGetDeviceObjectForFile(FileObject);
+ ASSERT(DeviceObject);
+
+ DPRINT
+ ("PAGING WRITE: FileObject %x Offset %x Length %d (%s:%d)\n",
+ &FileObject,
+ FileOffset->LowPart,
+ Length,
+ File,
+ Line);
+
+ KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
+
+ Irp = IoBuildAsynchronousFsdRequest
+ (IRP_MJ_WRITE,
+ DeviceObject,
+ Buffer,
+ Length,
+ FileOffset,
+ ReadStatus);
+
+ if (!Irp)
+ {
+ ObDereferenceObject(FileObject);
+ return STATUS_NO_MEMORY;
+ }
+
+ Irp->Flags = IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE | IRP_SYNCHRONOUS_API;
+
+ Irp->UserEvent = &ReadWait;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ IrpSp = IoGetNextIrpStackLocation(Irp);
+ IrpSp->Control |= SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR;
+ IrpSp->FileObject = FileObject;
+ IrpSp->CompletionRoutine = MiSimpleReadComplete;
+
+ DPRINT("Call Driver\n");
+ Status = IoCallDriver(DeviceObject, Irp);
+ DPRINT("Status %x\n", Status);
+
+ ObDereferenceObject(FileObject);
+
+ if (Status == STATUS_PENDING)
+ {
+ DPRINT1("KeWaitForSingleObject(&ReadWait)\n");
+ if (!NT_SUCCESS
+ (KeWaitForSingleObject
+ (&ReadWait,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL)))
+ {
+ DPRINT1("Warning: Failed to wait for synchronous IRP\n");
+ ASSERT(FALSE);
+ return Status;
+ }
+ }
+
+ DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
+ return ReadStatus->Status;
+}
+
+extern KEVENT MpwThreadEvent;
+FAST_MUTEX MiWriteMutex;
+
+NTSTATUS
+NTAPI
+_MiWriteBackPage
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ ULONG Length,
+ PFN_NUMBER Page,
+ const char *File,
+ int Line)
+{
+ NTSTATUS Status;
+ PVOID Hyperspace;
+ IO_STATUS_BLOCK Iosb;
+ KIRQL OldIrql;
+ PVOID PageBuffer = ExAllocatePool(NonPagedPool, PAGE_SIZE);
+
+ if (!PageBuffer) return STATUS_NO_MEMORY;
+
+ OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
+ Hyperspace = MmCreateHyperspaceMapping(Page);
+ RtlCopyMemory(PageBuffer, Hyperspace, PAGE_SIZE);
+ MmDeleteHyperspaceMapping(Hyperspace);
+ KfLowerIrql(OldIrql);
+
+ DPRINT1("MiWriteBackPage(%wZ,%08x%08x,%s:%d)\n", &FileObject->FileName, FileOffset->u.HighPart, FileOffset->u.LowPart, File, Line);
+ Status = MiSimpleWrite
+ (FileObject,
+ FileOffset,
+ PageBuffer,
+ Length,
+ &Iosb);
+
+ ExFreePool(PageBuffer);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MiSimpleWrite failed (%x)\n", Status);
+ }
+
+ return Status;
+}
diff --git a/ntoskrnl/cache/section/newmm.h b/ntoskrnl/cache/section/newmm.h
new file mode 100644
index 00000000000..43fd3fe7cef
--- /dev/null
+++ b/ntoskrnl/cache/section/newmm.h
@@ -0,0 +1,454 @@
+#pragma once
+
+#include
+
+/* TYPES *********************************************************************/
+
+#define MM_WAIT_ENTRY 0x7ffff800
+#define PFN_FROM_SSE(E) ((E) >> PAGE_SHIFT)
+#define IS_SWAP_FROM_SSE(E) ((E) & 0x00000001)
+#define MM_IS_WAIT_PTE(E) \
+ (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY)
+#define MAKE_PFN_SSE(P) ((P) << PAGE_SHIFT)
+#define SWAPENTRY_FROM_SSE(E) ((E) >> 1)
+#define MAKE_SWAP_SSE(S) (((S) << 1) | 0x1)
+#define DIRTY_SSE(E) ((E) | 2)
+#define CLEAN_SSE(E) ((E) & ~2)
+#define IS_DIRTY_SSE(E) ((E) & 2)
+
+#define MEMORY_AREA_CACHE (2)
+#define MM_SEGMENT_FINALIZE (0x40000000)
+
+#define RMAP_SEGMENT_MASK ~0xff
+#define RMAP_IS_SEGMENT(x) (((ULONG_PTR)(x) & RMAP_SEGMENT_MASK) == RMAP_SEGMENT_MASK)
+
+#define MIN(x,y) (((x)<(y))?(x):(y))
+#define MAX(x,y) (((x)>(y))?(x):(y))
+
+/* Determine what's needed to make paged pool fit in this category.
+ * it seems that something more is required to satisfy arm3. */
+#define BALANCER_CAN_EVICT(Consumer) \
+ (((Consumer) == MC_USER) || \
+ ((Consumer) == MC_CACHE))
+
+#define SEC_CACHE (0x40000000)
+
+#define MiWaitForPageEvent(Process,Address) do { \
+ DPRINT("MiWaitForPageEvent %x:%x #\n", Process, Address); \
+ KeWaitForSingleObject(&MmWaitPageEvent, 0, KernelMode, FALSE, NULL); \
+} while(0)
+
+#define MiSetPageEvent(Process,Address) do { \
+ DPRINT("MiSetPageEvent %x:%x #\n",Process, Address); \
+ KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE); \
+} while(0)
+
+/* We store 8 bits of location with a page association */
+#define ENTRIES_PER_ELEMENT 256
+
+extern KEVENT MmWaitPageEvent;
+
+typedef struct _MM_CACHE_SECTION_SEGMENT
+{
+ FAST_MUTEX Lock; /* lock which protects the page directory */
+ PFILE_OBJECT FileObject;
+ ULARGE_INTEGER RawLength; /* length of the segment which is part of the mapped file */
+ ULARGE_INTEGER Length; /* absolute length of the segment */
+ ULONG ReferenceCount;
+ ULONG Protection;
+ ULONG Flags;
+ BOOLEAN WriteCopy;
+
+ struct
+ {
+ LONG FileOffset; /* start offset into the file for image sections */
+ ULONG_PTR VirtualAddress; /* dtart offset into the address range for image sections */
+ ULONG Characteristics;
+ } Image;
+
+ RTL_GENERIC_TABLE PageTable;
+} MM_CACHE_SECTION_SEGMENT, *PMM_CACHE_SECTION_SEGMENT;
+
+typedef struct _CACHE_SECTION_PAGE_TABLE
+{
+ LARGE_INTEGER FileOffset;
+ PMM_CACHE_SECTION_SEGMENT Segment;
+ ULONG Refcount;
+ ULONG PageEntries[ENTRIES_PER_ELEMENT];
+} CACHE_SECTION_PAGE_TABLE, *PCACHE_SECTION_PAGE_TABLE;
+
+struct _MM_REQUIRED_RESOURCES;
+
+typedef NTSTATUS (NTAPI * AcquireResource)
+ (PMMSUPPORT AddressSpace,
+ struct _MEMORY_AREA *MemoryArea,
+ struct _MM_REQUIRED_RESOURCES *Required);
+typedef NTSTATUS (NTAPI * NotPresentFaultHandler)
+ (PMMSUPPORT AddressSpace,
+ struct _MEMORY_AREA *MemoryArea,
+ PVOID Address,
+ BOOLEAN Locked,
+ struct _MM_REQUIRED_RESOURCES *Required);
+typedef NTSTATUS (NTAPI * FaultHandler)
+ (PMMSUPPORT AddressSpace,
+ struct _MEMORY_AREA *MemoryArea,
+ PVOID Address,
+ struct _MM_REQUIRED_RESOURCES *Required);
+
+typedef struct _MM_REQUIRED_RESOURCES
+{
+ ULONG Consumer;
+ ULONG Amount;
+ ULONG Offset;
+ ULONG State;
+ PVOID Context;
+ LARGE_INTEGER FileOffset;
+ AcquireResource DoAcquisition;
+ PFN_NUMBER Page[2];
+ PVOID Buffer[2];
+ SWAPENTRY SwapEntry;
+ const char *File;
+ int Line;
+} MM_REQUIRED_RESOURCES, *PMM_REQUIRED_RESOURCES;
+
+PFN_NUMBER
+NTAPI
+MmWithdrawSectionPage
+(PMM_CACHE_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, BOOLEAN *Dirty);
+
+NTSTATUS
+NTAPI
+MmFinalizeSectionPageOut
+(PMM_CACHE_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, PFN_NUMBER Page,
+ BOOLEAN Dirty);
+
+/* sptab.c *******************************************************************/
+
+VOID
+NTAPI
+MiInitializeSectionPageTable(PMM_CACHE_SECTION_SEGMENT Segment);
+
+NTSTATUS
+NTAPI
+_MiSetPageEntryCacheSectionSegment
+(PMM_CACHE_SECTION_SEGMENT Segment,
+ PLARGE_INTEGER Offset,
+ ULONG Entry, const char *file, int line);
+
+ULONG
+NTAPI
+_MiGetPageEntryCacheSectionSegment
+(PMM_CACHE_SECTION_SEGMENT Segment,
+ PLARGE_INTEGER Offset, const char *file, int line);
+
+#define MiSetPageEntryCacheSectionSegment(S,O,E) _MiSetPageEntryCacheSectionSegment(S,O,E,__FILE__,__LINE__)
+#define MiGetPageEntryCacheSectionSegment(S,O) _MiGetPageEntryCacheSectionSegment(S,O,__FILE__,__LINE__)
+
+typedef VOID (NTAPI *FREE_SECTION_PAGE_FUN)
+ (PMM_CACHE_SECTION_SEGMENT Segment,
+ PLARGE_INTEGER Offset);
+
+VOID
+NTAPI
+MiFreePageTablesSectionSegment(PMM_CACHE_SECTION_SEGMENT Segment, FREE_SECTION_PAGE_FUN FreePage);
+
+/* Yields a lock */
+PMM_CACHE_SECTION_SEGMENT
+NTAPI
+MmGetSectionAssociation(PFN_NUMBER Page, PLARGE_INTEGER Offset);
+
+NTSTATUS
+NTAPI
+MmSetSectionAssociation(PFN_NUMBER Page, PMM_CACHE_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset);
+
+VOID
+NTAPI
+MmDeleteSectionAssociation(PFN_NUMBER Page);
+
+NTSTATUS
+NTAPI
+MmpPageOutPhysicalAddress(PFN_NUMBER Page);
+
+/* io.c **********************************************************************/
+
+NTSTATUS
+MmspWaitForFileLock(PFILE_OBJECT File);
+
+NTSTATUS
+NTAPI
+MiSimpleRead
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ ULONG Length,
+ PIO_STATUS_BLOCK ReadStatus);
+
+NTSTATUS
+NTAPI
+_MiSimpleWrite
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ ULONG Length,
+ PIO_STATUS_BLOCK ReadStatus,
+ const char *file,
+ int line);
+
+#define MiSimpleWrite(F,O,B,L,R) _MiSimpleWrite(F,O,B,L,R,__FILE__,__LINE__)
+
+NTSTATUS
+NTAPI
+_MiWriteBackPage
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER Offset,
+ ULONG Length,
+ PFN_NUMBER Page,
+ const char *File,
+ int Line);
+
+#define MiWriteBackPage(F,O,L,P) _MiWriteBackPage(F,O,L,P,__FILE__,__LINE__)
+
+/* section.c *****************************************************************/
+
+NTSTATUS
+NTAPI
+MmAccessFaultCacheSection
+(KPROCESSOR_MODE Mode,
+ ULONG_PTR Address,
+ BOOLEAN FromMdl);
+
+NTSTATUS
+NTAPI
+MiReadFilePage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES RequiredResources);
+
+ULONG
+NTAPI
+MiChecksumPage(PFN_NUMBER Page, BOOLEAN Lock);
+
+NTSTATUS
+NTAPI
+MiGetOnePage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES RequiredResources);
+
+NTSTATUS
+NTAPI
+MiSwapInPage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES RequiredResources);
+
+NTSTATUS
+NTAPI
+MiWriteSwapPage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES Resources);
+
+NTSTATUS
+NTAPI
+MiWriteFilePage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES Resources);
+
+VOID
+NTAPI
+MiFreeSegmentPage
+(PMM_CACHE_SECTION_SEGMENT Segment,
+ PLARGE_INTEGER FileOffset);
+
+NTSTATUS
+NTAPI
+MiCowCacheSectionPage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PVOID Address,
+ BOOLEAN Locked,
+ PMM_REQUIRED_RESOURCES Required);
+
+NTSTATUS
+NTAPI
+MiZeroFillSection(PVOID Address, PLARGE_INTEGER FileOffsetPtr, ULONG Length);
+
+VOID
+MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address);
+
+VOID
+NTAPI
+_MmLockCacheSectionSegment(PMM_CACHE_SECTION_SEGMENT Segment, const char *file, int line);
+
+#define MmLockCacheSectionSegment(x) _MmLockCacheSectionSegment(x,__FILE__,__LINE__)
+
+VOID
+NTAPI
+_MmUnlockCacheSectionSegment(PMM_CACHE_SECTION_SEGMENT Segment, const char *file, int line);
+
+#define MmUnlockCacheSectionSegment(x) _MmUnlockCacheSectionSegment(x,__FILE__,__LINE__)
+
+VOID
+MmFreeCacheSectionPage
+(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
+ PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty);
+
+NTSTATUS
+NTAPI
+_MiFlushMappedSection(PVOID BaseAddress, PLARGE_INTEGER BaseOffset, PLARGE_INTEGER FileSize, BOOLEAN Dirty, const char *File, int Line);
+
+#define MiFlushMappedSection(A,O,S,D) _MiFlushMappedSection(A,O,S,D,__FILE__,__LINE__)
+
+VOID
+NTAPI
+MmFinalizeSegment(PMM_CACHE_SECTION_SEGMENT Segment);
+
+VOID
+NTAPI
+MmFreeSectionSegments(PFILE_OBJECT FileObject);
+
+NTSTATUS NTAPI
+MmMapCacheViewInSystemSpaceAtOffset
+(IN PMM_CACHE_SECTION_SEGMENT Segment,
+ OUT PVOID * MappedBase,
+ IN PLARGE_INTEGER ViewOffset,
+ IN OUT PULONG ViewSize);
+
+NTSTATUS
+NTAPI
+_MiMapViewOfSegment
+(PMMSUPPORT AddressSpace,
+ PMM_CACHE_SECTION_SEGMENT Segment,
+ PVOID* BaseAddress,
+ SIZE_T ViewSize,
+ ULONG Protect,
+ PLARGE_INTEGER ViewOffset,
+ ULONG AllocationType,
+ const char *file,
+ int line);
+
+#define MiMapViewOfSegment(AddressSpace,Segment,BaseAddress,ViewSize,Protect,ViewOffset,AllocationType) _MiMapViewOfSegment(AddressSpace,Segment,BaseAddress,ViewSize,Protect,ViewOffset,AllocationType,__FILE__,__LINE__)
+
+NTSTATUS
+NTAPI
+MmUnmapViewOfCacheSegment
+(PMMSUPPORT AddressSpace,
+ PVOID BaseAddress);
+
+NTSTATUS
+NTAPI
+MmUnmapCacheViewInSystemSpace(PVOID Address);
+
+NTSTATUS
+NTAPI
+MmNotPresentFaultCachePage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PVOID Address,
+ BOOLEAN Locked,
+ PMM_REQUIRED_RESOURCES Required);
+
+NTSTATUS
+NTAPI
+MmPageOutPageFileView
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PVOID Address,
+ PMM_REQUIRED_RESOURCES Required);
+
+FORCEINLINE
+BOOLEAN
+_MmTryToLockAddressSpace(IN PMMSUPPORT AddressSpace, const char *file, int line)
+{
+ BOOLEAN Result = KeTryToAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock);
+ //DbgPrint("(%s:%d) Try Lock Address Space %x -> %s\n", file, line, AddressSpace, Result ? "true" : "false");
+ return Result;
+}
+
+#define MmTryToLockAddressSpace(x) _MmTryToLockAddressSpace(x,__FILE__,__LINE__)
+
+NTSTATUS
+NTAPI
+MiWidenSegment
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES RequiredResources);
+
+NTSTATUS
+NTAPI
+MiSwapInSectionPage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES RequiredResources);
+
+NTSTATUS
+NTAPI
+MmExtendCacheSection(PMM_CACHE_SECTION_SEGMENT Section, PLARGE_INTEGER NewSize, BOOLEAN ExtendFile);
+
+NTSTATUS
+NTAPI
+_MiFlushMappedSection(PVOID BaseAddress, PLARGE_INTEGER BaseOffset, PLARGE_INTEGER FileSize, BOOLEAN Dirty, const char *File, int Line);
+
+#define MiFlushMappedSection(A,O,S,D) _MiFlushMappedSection(A,O,S,D,__FILE__,__LINE__)
+
+NTSTATUS
+NTAPI
+MmCreateCacheSection
+(PMM_CACHE_SECTION_SEGMENT *SegmentObject,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PLARGE_INTEGER UMaximumSize,
+ ULONG SectionPageProtection,
+ ULONG AllocationAttributes,
+ PFILE_OBJECT FileObject);
+
+NTSTATUS
+NTAPI
+MiSimpleRead
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ ULONG Length,
+ PIO_STATUS_BLOCK ReadStatus);
+
+NTSTATUS
+NTAPI
+_MiSimpleWrite
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ ULONG Length,
+ PIO_STATUS_BLOCK ReadStatus,
+ const char *file,
+ int line);
+
+#define MiSimpleWrite(F,O,B,L,R) _MiSimpleWrite(F,O,B,L,R,__FILE__,__LINE__)
+
+NTSTATUS
+NTAPI
+_MiWriteBackPage
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER Offset,
+ ULONG Length,
+ PFN_NUMBER Page,
+ const char *File,
+ int Line);
+
+#define MiWriteBackPage(F,O,L,P) _MiWriteBackPage(F,O,L,P,__FILE__,__LINE__)
+
+PVOID
+NTAPI
+MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset);
+
+NTSTATUS
+NTAPI
+MmNotPresentFaultCacheSection
+(KPROCESSOR_MODE Mode,
+ ULONG_PTR Address,
+ BOOLEAN FromMdl);
+
+ULONG
+NTAPI
+MiCacheEvictPages(PVOID BaseAddress, ULONG Target);
diff --git a/ntoskrnl/cache/section/reqtools.c b/ntoskrnl/cache/section/reqtools.c
new file mode 100644
index 00000000000..68056d49ec9
--- /dev/null
+++ b/ntoskrnl/cache/section/reqtools.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/section.c
+ * PURPOSE: Implements section objects
+ *
+ * PROGRAMMERS: Rex Jolliff
+ * David Welch
+ * Eric Kohl
+ * Emanuele Aliberti
+ * Eugene Ingerman
+ * Casper Hornstrup
+ * KJK::Hyperion
+ * Guido de Jong
+ * Ge van Geldorp
+ * Royce Mitchell III
+ * Filip Navara
+ * Aleksey Bragin
+ * Jason Filby
+ * Thomas Weidenmueller
+ * Gunnar Andre' Dalsnes
+ * Mike Nordell
+ * Alex Ionescu
+ * Gregor Anich
+ * Steven Edwards
+ * Herve Poussineau
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#include "newmm.h"
+#define NDEBUG
+#include
+
+#define DPRINTC DPRINT
+
+NTSTATUS
+NTAPI
+MiGetOnePage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES Required)
+{
+ int i;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ for (i = 0; i < Required->Amount; i++)
+ {
+ DPRINTC("MiGetOnePage(%s:%d)\n", Required->File, Required->Line);
+ Status = MmRequestPageMemoryConsumer(Required->Consumer, TRUE, &Required->Page[i]);
+ if (!NT_SUCCESS(Status))
+ {
+ while (i > 0)
+ {
+ MmReleasePageMemoryConsumer(MC_CACHE, Required->Page[i-1]);
+ i--;
+ }
+ return Status;
+ }
+ }
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+MiReadFilePage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES RequiredResources)
+{
+ PFILE_OBJECT FileObject = RequiredResources->Context;
+ PPFN_NUMBER Page = &RequiredResources->Page[RequiredResources->Offset];
+ PLARGE_INTEGER FileOffset = &RequiredResources->FileOffset;
+ NTSTATUS Status;
+ PVOID PageBuf = NULL;
+ PMEMORY_AREA TmpArea;
+ IO_STATUS_BLOCK IOSB;
+ PHYSICAL_ADDRESS BoundaryAddressMultiple;
+
+ BoundaryAddressMultiple.QuadPart = 0;
+
+ DPRINTC
+ ("Pulling page %08x%08x from %wZ to %x\n",
+ FileOffset->u.HighPart, FileOffset->u.LowPart,
+ &FileObject->FileName,
+ Page);
+
+ Status = MmRequestPageMemoryConsumer(RequiredResources->Consumer, TRUE, Page);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Status: %x\n", Status);
+ return Status;
+ }
+
+ MmLockAddressSpace(MmGetKernelAddressSpace());
+ Status = MmCreateMemoryArea
+ (MmGetKernelAddressSpace(),
+ MEMORY_AREA_VIRTUAL_MEMORY,
+ &PageBuf,
+ PAGE_SIZE,
+ PAGE_READWRITE,
+ &TmpArea,
+ FALSE,
+ MEM_TOP_DOWN,
+ BoundaryAddressMultiple);
+
+ DPRINT("Status %x, PageBuf %x\n", Status, PageBuf);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("STATUS_NO_MEMORY: %x\n", Status);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ MmReleasePageMemoryConsumer(MC_CACHE, *Page);
+ return STATUS_NO_MEMORY;
+ }
+
+ Status = MmCreateVirtualMapping(NULL, PageBuf, PAGE_READWRITE, Page, 1);
+ if (!NT_SUCCESS(Status))
+ {
+ MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ MmReleasePageMemoryConsumer(MC_CACHE, *Page);
+ DPRINT1("Status: %x\n", Status);
+ return Status;
+ }
+
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
+
+ Status = MiSimpleRead
+ (FileObject,
+ FileOffset,
+ PageBuf,
+ RequiredResources->Amount,
+ &IOSB);
+ RtlZeroMemory
+ ((PCHAR)PageBuf+RequiredResources->Amount,
+ PAGE_SIZE-RequiredResources->Amount);
+
+ DPRINT("Read Status %x (Page %x)\n", Status, *Page);
+
+ MmLockAddressSpace(MmGetKernelAddressSpace());
+ MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
+
+ if (!NT_SUCCESS(Status))
+ {
+ MmReleasePageMemoryConsumer(MC_CACHE, *Page);
+ DPRINT("Status: %x\n", Status);
+ return Status;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+ULONG
+NTAPI
+MiChecksumPage(PFN_NUMBER Page, BOOLEAN Lock)
+{
+ int i;
+ NTSTATUS Status;
+ ULONG Total = 0;
+ PULONG PageBuf = NULL;
+ PMEMORY_AREA TmpArea;
+ PHYSICAL_ADDRESS BoundaryAddressMultiple;
+
+ BoundaryAddressMultiple.QuadPart = 0;
+
+ if (Lock) MmLockAddressSpace(MmGetKernelAddressSpace());
+
+ Status = MmCreateMemoryArea
+ (MmGetKernelAddressSpace(),
+ MEMORY_AREA_VIRTUAL_MEMORY,
+ (PVOID*)&PageBuf,
+ PAGE_SIZE,
+ PAGE_READWRITE,
+ &TmpArea,
+ FALSE,
+ MEM_TOP_DOWN,
+ BoundaryAddressMultiple);
+
+ DPRINT("Status %x, PageBuf %x\n", Status, PageBuf);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("STATUS_NO_MEMORY: %x\n", Status);
+ if (Lock) MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ return 0;
+ }
+
+ Status = MmCreateVirtualMapping(NULL, PageBuf, PAGE_READWRITE, &Page, 1);
+ if (!NT_SUCCESS(Status))
+ {
+ MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
+ if (Lock) MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ DPRINT1("Status: %x\n", Status);
+ return Status;
+ }
+
+ for (i = 0; i < 1024; i++) {
+ Total += PageBuf[i];
+ }
+
+ MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
+ if (Lock) MmUnlockAddressSpace(MmGetKernelAddressSpace());
+
+ return Total;
+}
+
+NTSTATUS
+NTAPI
+MiSwapInPage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES Resources)
+{
+ NTSTATUS Status;
+
+ Status = MmRequestPageMemoryConsumer(Resources->Consumer, TRUE, &Resources->Page[Resources->Offset]);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status);
+ return Status;
+ }
+
+ Status = MmReadFromSwapPage(Resources->SwapEntry, Resources->Page[Resources->Offset]);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
+ return Status;
+ }
+
+ MmSetSavedSwapEntryPage(Resources->Page[Resources->Offset], Resources->SwapEntry);
+
+ DPRINT1("MiSwapInPage(%x,%x)\n", Resources->Page[Resources->Offset], Resources->SwapEntry);
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+MiWriteFilePage
+(PMMSUPPORT AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_REQUIRED_RESOURCES Required)
+{
+ DPRINT1("MiWriteFilePage(%x,%x)\n", Required->Page[Required->Offset], Required->FileOffset.LowPart);
+
+ return MiWriteBackPage
+ (Required->Context,
+ &Required->FileOffset,
+ PAGE_SIZE,
+ Required->Page[Required->Offset]);
+}
diff --git a/ntoskrnl/cache/section/sptab.c b/ntoskrnl/cache/section/sptab.c
new file mode 100644
index 00000000000..0b71764b865
--- /dev/null
+++ b/ntoskrnl/cache/section/sptab.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/section.c
+ * PURPOSE: Section object page tables
+ *
+ * PROGRAMMERS: arty
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#include "newmm.h"
+#define NDEBUG
+#include
+
+#define DPRINTC DPRINT
+
+/* TYPES *********************************************************************/
+
+extern KSPIN_LOCK MiSectionPageTableLock;
+
+static
+PVOID
+NTAPI
+MiSectionPageTableAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes)
+{
+ PVOID Result;
+ Result = ExAllocatePoolWithTag(NonPagedPool, Bytes, 'MmPt');
+ DPRINT("MiSectionPageTableAllocate(%d) => %p\n", Bytes, Result);
+ return Result;
+}
+
+static
+VOID
+NTAPI
+MiSectionPageTableFree(PRTL_GENERIC_TABLE Table, PVOID Data)
+{
+ DPRINT("MiSectionPageTableFree(%p)\n", Data);
+ ExFreePoolWithTag(Data, 'MmPt');
+}
+
+static
+RTL_GENERIC_COMPARE_RESULTS
+NTAPI
+MiSectionPageTableCompare(PRTL_GENERIC_TABLE Table, PVOID PtrA, PVOID PtrB)
+{
+ PLARGE_INTEGER A = PtrA, B = PtrB;
+ BOOLEAN Result = (A->QuadPart < B->QuadPart) ? GenericLessThan :
+ (A->QuadPart == B->QuadPart) ? GenericEqual : GenericGreaterThan;
+
+ DPRINT
+ ("Compare: %08x%08x vs %08x%08x => %s\n",
+ A->u.HighPart, A->u.LowPart,
+ B->u.HighPart, B->u.LowPart,
+ Result == GenericLessThan ? "GenericLessThan" :
+ Result == GenericGreaterThan ? "GenericGreaterThan" :
+ "GenericEqual");
+
+ return Result;
+}
+
+static
+PCACHE_SECTION_PAGE_TABLE
+NTAPI
+MiSectionPageTableGet
+(PRTL_GENERIC_TABLE Table,
+ PLARGE_INTEGER FileOffset)
+{
+ LARGE_INTEGER SearchFileOffset;
+ PCACHE_SECTION_PAGE_TABLE PageTable;
+ SearchFileOffset.QuadPart = ROUND_DOWN(FileOffset->QuadPart, ENTRIES_PER_ELEMENT * PAGE_SIZE);
+ PageTable = RtlLookupElementGenericTable(Table, &SearchFileOffset);
+ DPRINT
+ ("MiSectionPageTableGet(%08x,%08x%08x)\n",
+ Table,
+ FileOffset->HighPart,
+ FileOffset->LowPart);
+ return PageTable;
+}
+
+static
+PCACHE_SECTION_PAGE_TABLE
+NTAPI
+MiSectionPageTableGetOrAllocate
+(PRTL_GENERIC_TABLE Table,
+ PLARGE_INTEGER FileOffset)
+{
+ LARGE_INTEGER SearchFileOffset;
+ PCACHE_SECTION_PAGE_TABLE PageTableSlice =
+ MiSectionPageTableGet(Table, FileOffset);
+ if (!PageTableSlice)
+ {
+ CACHE_SECTION_PAGE_TABLE SectionZeroPageTable = { };
+ SearchFileOffset.QuadPart = ROUND_DOWN(FileOffset->QuadPart, ENTRIES_PER_ELEMENT * PAGE_SIZE);
+ SectionZeroPageTable.FileOffset = SearchFileOffset;
+ SectionZeroPageTable.Refcount = 1;
+ PageTableSlice = RtlInsertElementGenericTable
+ (Table, &SectionZeroPageTable, sizeof(SectionZeroPageTable), NULL);
+ DPRINT
+ ("Allocate page table %x (%08x%08x)\n",
+ PageTableSlice,
+ PageTableSlice->FileOffset.u.HighPart,
+ PageTableSlice->FileOffset.u.LowPart);
+ if (!PageTableSlice) return NULL;
+ }
+ return PageTableSlice;
+}
+
+VOID
+NTAPI
+MiInitializeSectionPageTable(PMM_CACHE_SECTION_SEGMENT Segment)
+{
+ RtlInitializeGenericTable
+ (&Segment->PageTable,
+ MiSectionPageTableCompare,
+ MiSectionPageTableAllocate,
+ MiSectionPageTableFree,
+ NULL);
+ DPRINT("MiInitializeSectionPageTable(%p)\n", &Segment->PageTable);
+}
+
+NTSTATUS
+NTAPI
+_MiSetPageEntryCacheSectionSegment
+(PMM_CACHE_SECTION_SEGMENT Segment,
+ PLARGE_INTEGER Offset,
+ ULONG Entry,
+ const char *file,
+ int line)
+{
+ ULONG PageIndex, OldEntry;
+ PCACHE_SECTION_PAGE_TABLE PageTable;
+ PageTable =
+ MiSectionPageTableGetOrAllocate(&Segment->PageTable, Offset);
+ if (!PageTable) return STATUS_NO_MEMORY;
+ ASSERT(MiSectionPageTableGet(&Segment->PageTable, Offset));
+ PageTable->Segment = Segment;
+ PageIndex =
+ (Offset->QuadPart - PageTable->FileOffset.QuadPart) / PAGE_SIZE;
+ OldEntry = PageTable->PageEntries[PageIndex];
+ if (OldEntry && !IS_SWAP_FROM_SSE(OldEntry)) {
+ MmDeleteSectionAssociation(PFN_FROM_SSE(OldEntry));
+ }
+ if (Entry && !IS_SWAP_FROM_SSE(Entry)) {
+ MmSetSectionAssociation(PFN_FROM_SSE(Entry), Segment, Offset);
+ }
+ PageTable->PageEntries[PageIndex] = Entry;
+ DPRINT
+ ("MiSetPageEntrySectionSegment(%p,%08x%08x,%x) %s:%d\n",
+ Segment, Offset->u.HighPart, Offset->u.LowPart, Entry, file, line);
+ return STATUS_SUCCESS;
+}
+
+ULONG
+NTAPI
+_MiGetPageEntryCacheSectionSegment
+(PMM_CACHE_SECTION_SEGMENT Segment,
+ PLARGE_INTEGER Offset,
+ const char *file,
+ int line)
+{
+ LARGE_INTEGER FileOffset;
+ ULONG PageIndex, Result;
+ PCACHE_SECTION_PAGE_TABLE PageTable;
+
+ FileOffset.QuadPart =
+ ROUND_DOWN(Offset->QuadPart, ENTRIES_PER_ELEMENT * PAGE_SIZE);
+ PageTable = MiSectionPageTableGet(&Segment->PageTable, &FileOffset);
+ if (!PageTable) return 0;
+ PageIndex =
+ (Offset->QuadPart - PageTable->FileOffset.QuadPart) / PAGE_SIZE;
+ Result = PageTable->PageEntries[PageIndex];
+#if 0
+ DPRINTC
+ ("MiGetPageEntrySectionSegment(%p,%08x%08x) => %x %s:%d\n",
+ Segment,
+ FileOffset.u.HighPart,
+ FileOffset.u.LowPart + PageIndex * PAGE_SIZE,
+ Result,
+ file, line);
+#endif
+ return Result;
+}
+
+VOID
+NTAPI
+MiFreePageTablesSectionSegment
+(PMM_CACHE_SECTION_SEGMENT Segment, FREE_SECTION_PAGE_FUN FreePage)
+{
+ PCACHE_SECTION_PAGE_TABLE Element;
+ DPRINT("MiFreePageTablesSectionSegment(%p)\n", &Segment->PageTable);
+ while ((Element = RtlGetElementGenericTable(&Segment->PageTable, 0))) {
+ DPRINT
+ ("Delete table for %x -> %08x%08x\n",
+ Segment,
+ Element->FileOffset.u.HighPart,
+ Element->FileOffset.u.LowPart);
+ if (FreePage)
+ {
+ int i;
+ for (i = 0; i < ENTRIES_PER_ELEMENT; i++)
+ {
+ ULONG Entry;
+ LARGE_INTEGER Offset;
+ Offset.QuadPart = Element->FileOffset.QuadPart + i * PAGE_SIZE;
+ Entry = Element->PageEntries[i];
+ if (Entry && !IS_SWAP_FROM_SSE(Entry))
+ {
+ DPRINTC("Freeing page %x:%x @ %x\n", Segment, Entry, Offset.LowPart);
+ FreePage(Segment, &Offset);
+ }
+ }
+ }
+ DPRINT("Remove memory\n");
+ RtlDeleteElementGenericTable(&Segment->PageTable, Element);
+ }
+ DPRINT("Done\n");
+}
+
+PMM_CACHE_SECTION_SEGMENT
+NTAPI
+MmGetSectionAssociation(PFN_NUMBER Page, PLARGE_INTEGER Offset)
+{
+ ULONG RawOffset;
+ PMM_CACHE_SECTION_SEGMENT Segment = NULL;
+ PCACHE_SECTION_PAGE_TABLE PageTable;
+
+ PageTable = (PCACHE_SECTION_PAGE_TABLE)MmGetSegmentRmap(Page, &RawOffset);
+ if (PageTable)
+ {
+ Segment = PageTable->Segment;
+ Offset->QuadPart = PageTable->FileOffset.QuadPart + (RawOffset << PAGE_SHIFT);
+ }
+
+ return(Segment);
+}
+
+NTSTATUS
+NTAPI
+MmSetSectionAssociation(PFN_NUMBER Page, PMM_CACHE_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
+{
+ PCACHE_SECTION_PAGE_TABLE PageTable;
+ ULONG ActualOffset;
+ PageTable = MiSectionPageTableGet(&Segment->PageTable, Offset);
+ ASSERT(PageTable);
+ ActualOffset = (ULONG)(Offset->QuadPart - PageTable->FileOffset.QuadPart);
+ MmInsertRmap(Page, (PEPROCESS)PageTable, (PVOID)(RMAP_SEGMENT_MASK | (ActualOffset >> PAGE_SHIFT)));
+ return STATUS_SUCCESS;
+}
diff --git a/ntoskrnl/cache/section/swapout.c b/ntoskrnl/cache/section/swapout.c
new file mode 100644
index 00000000000..685104e3d64
--- /dev/null
+++ b/ntoskrnl/cache/section/swapout.c
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/section/fault.c
+ * PURPOSE: Consolidate fault handlers for sections
+ *
+ * PROGRAMMERS: Arty
+ * Rex Jolliff
+ * David Welch
+ * Eric Kohl
+ * Emanuele Aliberti
+ * Eugene Ingerman
+ * Casper Hornstrup
+ * KJK::Hyperion
+ * Guido de Jong
+ * Ge van Geldorp
+ * Royce Mitchell III
+ * Filip Navara
+ * Aleksey Bragin
+ * Jason Filby
+ * Thomas Weidenmueller
+ * Gunnar Andre' Dalsnes
+ * Mike Nordell
+ * Alex Ionescu
+ * Gregor Anich
+ * Steven Edwards
+ * Herve Poussineau
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include
+#include "newmm.h"
+#define NDEBUG
+#include
+
+#define DPRINTC DPRINT
+
+extern KEVENT MmWaitPageEvent;
+extern FAST_MUTEX RmapListLock;
+
+FAST_MUTEX GlobalPageOperation;
+
+PFN_NUMBER
+NTAPI
+MmWithdrawSectionPage
+(PMM_CACHE_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, BOOLEAN *Dirty)
+{
+ ULONG Entry;
+
+ DPRINT("MmWithdrawSectionPage(%x,%08x%08x,%x)\n", Segment, FileOffset->HighPart, FileOffset->LowPart, Dirty);
+
+ MmLockCacheSectionSegment(Segment);
+ Entry = MiGetPageEntryCacheSectionSegment(Segment, FileOffset);
+
+ *Dirty = !!IS_DIRTY_SSE(Entry);
+
+ DPRINT("Withdraw %x (%x) of %wZ\n", FileOffset->LowPart, Entry, Segment->FileObject ? &Segment->FileObject->FileName : NULL);
+
+ if (!Entry)
+ {
+ DPRINT("Stoeled!\n");
+ MmUnlockCacheSectionSegment(Segment);
+ return 0;
+ }
+ else if (MM_IS_WAIT_PTE(Entry))
+ {
+ DPRINT("WAIT\n");
+ MmUnlockCacheSectionSegment(Segment);
+ return MM_WAIT_ENTRY;
+ }
+ else if (Entry && !IS_SWAP_FROM_SSE(Entry))
+ {
+ DPRINT("Page %x\n", PFN_FROM_SSE(Entry));
+ *Dirty |= (Entry & 2);
+ MiSetPageEntryCacheSectionSegment(Segment, FileOffset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
+ MmUnlockCacheSectionSegment(Segment);
+ return PFN_FROM_SSE(Entry);
+ }
+ else
+ {
+ DPRINT1("SWAP ENTRY?! (%x:%08x%08x)\n", Segment, FileOffset->HighPart, FileOffset->LowPart);
+ ASSERT(FALSE);
+ MmUnlockCacheSectionSegment(Segment);
+ return 0;
+ }
+}
+
+NTSTATUS
+NTAPI
+MmFinalizeSectionPageOut
+(PMM_CACHE_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, PFN_NUMBER Page,
+ BOOLEAN Dirty)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ BOOLEAN WriteZero = FALSE, WritePage = FALSE;
+ SWAPENTRY Swap = MmGetSavedSwapEntryPage(Page);
+
+ MmLockCacheSectionSegment(Segment);
+ (void)InterlockedIncrementUL(&Segment->ReferenceCount);
+
+ if (Dirty)
+ {
+ DPRINT("Finalize (dirty) Segment %x Page %x\n", Segment, Page);
+ DPRINT("Segment->FileObject %x\n", Segment->FileObject);
+ DPRINT("Segment->Flags %x\n", Segment->Flags);
+
+ WriteZero = TRUE;
+ WritePage = TRUE;
+ }
+ else
+ {
+ WriteZero = TRUE;
+ }
+
+ DPRINT("Status %x\n", Status);
+
+ MmUnlockCacheSectionSegment(Segment);
+
+ if (WritePage)
+ {
+ DPRINT("MiWriteBackPage(Segment %x FileObject %x Offset %x)\n", Segment, Segment->FileObject, FileOffset->LowPart);
+ Status = MiWriteBackPage(Segment->FileObject, FileOffset, PAGE_SIZE, Page);
+ }
+
+ MmLockCacheSectionSegment(Segment);
+
+ if (WriteZero && NT_SUCCESS(Status))
+ {
+ DPRINT("Setting page entry in segment %x:%x to swap %x\n", Segment, FileOffset->LowPart, Swap);
+ MiSetPageEntryCacheSectionSegment(Segment, FileOffset, Swap ? MAKE_SWAP_SSE(Swap) : 0);
+ }
+ else
+ {
+ DPRINT("Setting page entry in segment %x:%x to page %x\n", Segment, FileOffset->LowPart, Page);
+ MiSetPageEntryCacheSectionSegment
+ (Segment, FileOffset, Page ? (Dirty ? DIRTY_SSE(MAKE_PFN_SSE(Page)) : MAKE_PFN_SSE(Page)) : 0);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT("Removing page %x for real\n", Page);
+ MmSetSavedSwapEntryPage(Page, 0);
+ // Note: the other one is held by MmTrimUserMemory
+ if (MmGetReferenceCountPage(Page) != 2) {
+ DPRINT1("ALERT: Page %x about to be evicted with ref count %d\n", Page, MmGetReferenceCountPage(Page));
+ }
+ MmDereferencePage(Page);
+ }
+
+ MmUnlockCacheSectionSegment(Segment);
+
+ if (InterlockedDecrementUL(&Segment->ReferenceCount) == 0)
+ {
+ MmFinalizeSegment(Segment);
+ }
+
+ /* Note: Writing may evict the segment... Nothing is guaranteed from here down */
+ MiSetPageEvent(Segment, FileOffset->LowPart);
+
+ DPRINT("Status %x\n", Status);
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+MmPageOutCacheSection
+(PMMSUPPORT AddressSpace,
+ MEMORY_AREA* MemoryArea,
+ PVOID Address,
+ PMM_REQUIRED_RESOURCES Required)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG Entry;
+ BOOLEAN Dirty = FALSE;
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+ LARGE_INTEGER TotalOffset;
+ PMM_CACHE_SECTION_SEGMENT Segment;
+ PVOID PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
+
+ TotalOffset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress +
+ MemoryArea->Data.CacheData.ViewOffset.QuadPart;
+
+ Segment = MemoryArea->Data.CacheData.Segment;
+
+ MmLockCacheSectionSegment(Segment);
+ ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
+
+ Dirty = MmIsDirtyPageRmap(Required->Page[0]);
+ Entry = MiGetPageEntryCacheSectionSegment(Segment, &TotalOffset);
+
+ if (Dirty)
+ {
+ PFN_NUMBER OurPage;
+ MiSetPageEntryCacheSectionSegment(Segment, &TotalOffset, DIRTY_SSE(Entry));
+ MmDeleteRmap(Required->Page[0], Process, Address);
+ MmDeleteVirtualMapping(Process, Address, FALSE, &Dirty, &OurPage);
+ ASSERT(OurPage == Required->Page[0]);
+ } else {
+ /* Just unmap if the page wasn't dirty */
+ PFN_NUMBER OurPage;
+ MmDeleteRmap(Required->Page[0], Process, Address);
+ MmDeleteVirtualMapping(Process, Address, FALSE, &Dirty, &OurPage);
+ DPRINT("OurPage %x ThePage %x\n", OurPage, Required->Page[0]);
+ ASSERT(OurPage == Required->Page[0]);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ MmDereferencePage(Required->Page[0]);
+ }
+
+ MmUnlockCacheSectionSegment(Segment);
+ MiSetPageEvent(Process, Address);
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+MmpPageOutPhysicalAddress(PFN_NUMBER Page)
+{
+ BOOLEAN ProcRef = FALSE;
+ PFN_NUMBER SectionPage = 0;
+ PMM_RMAP_ENTRY entry;
+ PMM_CACHE_SECTION_SEGMENT Segment = NULL;
+ LARGE_INTEGER FileOffset;
+ PMEMORY_AREA MemoryArea;
+ PMMSUPPORT AddressSpace = MmGetKernelAddressSpace();
+ BOOLEAN Dirty = FALSE;
+ PVOID Address = NULL;
+ PEPROCESS Process = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+ MM_REQUIRED_RESOURCES Resources = { 0 };
+
+ DPRINTC("Page out %x (ref ct %x)\n", Page, MmGetReferenceCountPage(Page));
+
+ ExAcquireFastMutex(&GlobalPageOperation);
+ if ((Segment = MmGetSectionAssociation(Page, &FileOffset)))
+ {
+ DPRINT1("Withdrawing page (%x) %x:%x\n", Page, Segment, FileOffset.LowPart);
+ SectionPage = MmWithdrawSectionPage(Segment, &FileOffset, &Dirty);
+ DPRINTC("SectionPage %x\n", SectionPage);
+
+ if (SectionPage == MM_WAIT_ENTRY || SectionPage == 0)
+ {
+ DPRINT1("In progress page out %x\n", SectionPage);
+ ExReleaseFastMutex(&GlobalPageOperation);
+ return STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ ASSERT(SectionPage == Page);
+ }
+ Resources.State = Dirty ? 1 : 0;
+ }
+ else
+ {
+ DPRINT("No segment association for %x\n", Page);
+ }
+
+
+ Dirty = MmIsDirtyPageRmap(Page);
+
+ DPRINTC("Trying to unmap all instances of %x\n", Page);
+ ExAcquireFastMutex(&RmapListLock);
+ entry = MmGetRmapListHeadPage(Page);
+
+ // Entry and Segment might be null here in the case that the page
+ // is new and is in the process of being swapped in
+ if (!entry && !Segment)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ DPRINT1("Page %x is in transit\n", Page);
+ ExReleaseFastMutex(&RmapListLock);
+ goto bail;
+ }
+
+ while (entry != NULL && NT_SUCCESS(Status))
+ {
+ Process = entry->Process;
+ Address = entry->Address;
+
+ DPRINTC("Process %x Address %x Page %x\n", Process, Address, Page);
+
+ if (RMAP_IS_SEGMENT(Address)) {
+ entry = entry->Next;
+ continue;
+ }
+
+ if (Process && Address < MmSystemRangeStart)
+ {
+ // Make sure we don't try to page out part of an exiting process
+ if (PspIsProcessExiting(Process))
+ {
+ DPRINT("bail\n");
+ ExReleaseFastMutex(&RmapListLock);
+ goto bail;
+ }
+ Status = ObReferenceObject(Process);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("bail\n");
+ ExReleaseFastMutex(&RmapListLock);
+ goto bail;
+ }
+ ProcRef = TRUE;
+ AddressSpace = &Process->Vm;
+ }
+ else
+ {
+ AddressSpace = MmGetKernelAddressSpace();
+ }
+ ExReleaseFastMutex(&RmapListLock);
+
+ RtlZeroMemory(&Resources, sizeof(Resources));
+
+ if ((((ULONG_PTR)Address) & 0xFFF) != 0)
+ {
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+
+ if (!MmTryToLockAddressSpace(AddressSpace))
+ {
+ DPRINT1("Could not lock address space for process %x\n", MmGetAddressSpaceOwner(AddressSpace));
+ Status = STATUS_UNSUCCESSFUL;
+ goto bail;
+ }
+
+ do
+ {
+ MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
+ if (MemoryArea == NULL ||
+ MemoryArea->DeleteInProgress)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ MmUnlockAddressSpace(AddressSpace);
+ DPRINTC("bail\n");
+ goto bail;
+ }
+
+ DPRINTC
+ ("Type %x (%x -> %x)\n",
+ MemoryArea->Type,
+ MemoryArea->StartingAddress,
+ MemoryArea->EndingAddress);
+
+ Resources.DoAcquisition = NULL;
+
+ Resources.Page[0] = Page;
+
+ ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
+
+ DPRINT("%x:%x, page %x %x\n", Process, Address, Page, Resources.Page[0]);
+ Status = MmPageOutCacheSection
+ (AddressSpace, MemoryArea, Address, &Resources);
+ DPRINT("%x\n", Status);
+
+ ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
+
+ MmUnlockAddressSpace(AddressSpace);
+
+ if (Status == STATUS_SUCCESS + 1)
+ {
+ // Wait page ... the other guy has it, so we'll just fail for now
+ DPRINTC("Wait entry ... can't continue\n");
+ Status = STATUS_UNSUCCESSFUL;
+ goto bail;
+ }
+ else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
+ {
+ DPRINTC("DoAcquisition %x\n", Resources.DoAcquisition);
+ Status = Resources.DoAcquisition(AddressSpace, MemoryArea, &Resources);
+ DPRINTC("Status %x\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("bail\n");
+ goto bail;
+ }
+ else Status = STATUS_MM_RESTART_OPERATION;
+ }
+
+ MmLockAddressSpace(AddressSpace);
+ }
+ while (Status == STATUS_MM_RESTART_OPERATION);
+ Dirty |= Resources.State & 1; // Accumulate dirty
+
+ MmUnlockAddressSpace(AddressSpace);
+
+ if (ProcRef)
+ {
+ ObDereferenceObject(Process);
+ ProcRef = FALSE;
+ }
+
+ ExAcquireFastMutex(&RmapListLock);
+ ASSERT(!MM_IS_WAIT_PTE(MmGetPfnForProcess(Process, Address)));
+ entry = MmGetRmapListHeadPage(Page);
+
+ DPRINTC("Entry %x\n", entry);
+ }
+
+ ExReleaseFastMutex(&RmapListLock);
+
+bail:
+ DPRINTC("BAIL %x\n", Status);
+
+ if (Segment)
+ {
+ DPRINTC("About to finalize section page %x (%x:%x) Status %x %s\n", Page, Segment, FileOffset.LowPart, Status, Dirty ? "dirty" : "clean");
+
+ if (!NT_SUCCESS(Status) ||
+ !NT_SUCCESS
+ (Status = MmFinalizeSectionPageOut
+ (Segment, &FileOffset, Page, Dirty)))
+ {
+ DPRINTC
+ ("Failed to page out %x, replacing %x at %x in segment %x\n",
+ SectionPage, FileOffset.LowPart, Segment);
+ MmLockCacheSectionSegment(Segment);
+ MiSetPageEntryCacheSectionSegment(Segment, &FileOffset, Dirty ? MAKE_PFN_SSE(Page) : DIRTY_SSE(MAKE_PFN_SSE(Page)));
+ MmUnlockCacheSectionSegment(Segment);
+ }
+
+ // Alas, we had the last reference
+ ULONG RefCount;
+ if ((RefCount = InterlockedDecrementUL(&Segment->ReferenceCount)) == 0)
+ MmFinalizeSegment(Segment);
+ }
+
+ if (ProcRef)
+ {
+ DPRINTC("Dereferencing process...\n");
+ ObDereferenceObject(Process);
+ }
+
+ ExReleaseFastMutex(&GlobalPageOperation);
+ DPRINTC("%s %x %x\n", NT_SUCCESS(Status) ? "Evicted" : "Spared", Page, Status);
+ return NT_SUCCESS(Status) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+}
+
+ULONG
+NTAPI
+MiCacheEvictPages(PVOID BaseAddress, ULONG Target)
+{
+ ULONG i, Entry, Result = 0;
+ NTSTATUS Status;
+ PFN_NUMBER Page;
+ PMEMORY_AREA MemoryArea;
+ LARGE_INTEGER Offset;
+ PMM_CACHE_SECTION_SEGMENT Segment;
+
+ MmLockAddressSpace(MmGetKernelAddressSpace());
+ MemoryArea = MmLocateMemoryAreaByAddress
+ (MmGetKernelAddressSpace(),
+ BaseAddress);
+
+ ASSERT(MemoryArea);
+ ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
+
+ Segment = MemoryArea->Data.CacheData.Segment;
+
+ ASSERT(Segment);
+
+ MmLockCacheSectionSegment(Segment);
+
+ for (i = 0;
+ i < Segment->Length.QuadPart -
+ MemoryArea->Data.CacheData.ViewOffset.QuadPart &&
+ Result < Target;
+ i += PAGE_SIZE) {
+ Offset.QuadPart = MemoryArea->Data.CacheData.ViewOffset.QuadPart + i;
+ Entry = MiGetPageEntryCacheSectionSegment(Segment, &Offset);
+ if (Entry && !IS_SWAP_FROM_SSE(Entry)) {
+ Page = PFN_FROM_SSE(Entry);
+ MmReferencePage(Page);
+ MmUnlockCacheSectionSegment(Segment);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ Status = MmpPageOutPhysicalAddress(Page);
+ if (NT_SUCCESS(Status))
+ Result++;
+ MmLockCacheSectionSegment(Segment);
+ MmLockAddressSpace(MmGetKernelAddressSpace());
+ MmReleasePageMemoryConsumer(MC_CACHE, Page);
+ }
+ }
+
+ MmUnlockCacheSectionSegment(Segment);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
+
+ return Result;
+}
+
diff --git a/ntoskrnl/cc/cacheman.c b/ntoskrnl/cc/cacheman.c
index a9459d7988d..78d23e737cd 100644
--- a/ntoskrnl/cc/cacheman.c
+++ b/ntoskrnl/cc/cacheman.c
@@ -19,6 +19,7 @@ PFSN_PREFETCHER_GLOBALS CcPfGlobals;
VOID
NTAPI
+INIT_FUNCTION
CcPfInitializePrefetcher(VOID)
{
/* Notify debugger */
@@ -36,6 +37,7 @@ CcPfInitializePrefetcher(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
CcInitializeCacheManager(VOID)
{
CcInitView();
diff --git a/ntoskrnl/cc/copy.c b/ntoskrnl/cc/copy.c
index 628f1dcbed8..17702665945 100644
--- a/ntoskrnl/cc/copy.c
+++ b/ntoskrnl/cc/copy.c
@@ -41,7 +41,9 @@ CcInitCacheZeroPage(VOID)
{
NTSTATUS Status;
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &CcZeroPage);
+ MI_SET_USAGE(MI_USAGE_CACHE);
+ //MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
+ Status = MmRequestPageMemoryConsumer(MC_SYSTEM, TRUE, &CcZeroPage);
if (!NT_SUCCESS(Status))
{
DbgPrint("Can't allocate CcZeroPage.\n");
diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c
index fcdefc4d032..a17e2c942fe 100644
--- a/ntoskrnl/cc/view.c
+++ b/ntoskrnl/cc/view.c
@@ -703,6 +703,18 @@ CcRosCreateCacheSegment(PBCB Bcb,
#endif
/* Create a virtual mapping for this memory area */
+ MI_SET_USAGE(MI_USAGE_CACHE);
+#if MI_TRACE_PFNS
+ PWCHAR pos = NULL;
+ ULONG len = 0;
+ if ((Bcb->FileObject) && (Bcb->FileObject->FileName.Buffer))
+ {
+ pos = wcsrchr(Bcb->FileObject->FileName.Buffer, '\\');
+ len = wcslen(pos) * sizeof(WCHAR);
+ if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos);
+ }
+#endif
+
MmMapMemoryArea(current->BaseAddress, Bcb->CacheSegmentSize,
MC_CACHE, PAGE_READWRITE);
diff --git a/ntoskrnl/config/cmalloc.c b/ntoskrnl/config/cmalloc.c
index 97dfc1a6e26..65028838e13 100644
--- a/ntoskrnl/config/cmalloc.c
+++ b/ntoskrnl/config/cmalloc.c
@@ -25,6 +25,7 @@ LIST_ENTRY CmpFreeDelayItemsListHead;
VOID
NTAPI
+INIT_FUNCTION
CmpInitCmPrivateAlloc(VOID)
{
/* Make sure we didn't already do this */
@@ -39,6 +40,7 @@ CmpInitCmPrivateAlloc(VOID)
VOID
NTAPI
+INIT_FUNCTION
CmpInitCmPrivateDelayAlloc(VOID)
{
/* Initialize the delay allocation list and lock */
diff --git a/ntoskrnl/config/cmboot.c b/ntoskrnl/config/cmboot.c
index 50c6815866f..1416c4dfe01 100644
--- a/ntoskrnl/config/cmboot.c
+++ b/ntoskrnl/config/cmboot.c
@@ -17,6 +17,7 @@
HCELL_INDEX
NTAPI
+INIT_FUNCTION
CmpFindControlSet(IN PHHIVE SystemHive,
IN HCELL_INDEX RootCell,
IN PUNICODE_STRING SelectKeyName,
@@ -126,6 +127,7 @@ CmpFindControlSet(IN PHHIVE SystemHive,
ULONG
NTAPI
+INIT_FUNCTION
CmpFindTagIndex(IN PHHIVE Hive,
IN HCELL_INDEX TagCell,
IN HCELL_INDEX GroupOrderCell,
@@ -175,6 +177,7 @@ CmpFindTagIndex(IN PHHIVE Hive,
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpAddDriverToList(IN PHHIVE Hive,
IN HCELL_INDEX DriverCell,
IN HCELL_INDEX GroupOrderCell,
@@ -341,6 +344,7 @@ CmpAddDriverToList(IN PHHIVE Hive,
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpIsLoadType(IN PHHIVE Hive,
IN HCELL_INDEX Cell,
IN SERVICE_LOAD_TYPE LoadType)
@@ -371,6 +375,7 @@ CmpIsLoadType(IN PHHIVE Hive,
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpFindDrivers(IN PHHIVE Hive,
IN HCELL_INDEX ControlSet,
IN SERVICE_LOAD_TYPE LoadType,
@@ -465,6 +470,7 @@ CmpFindDrivers(IN PHHIVE Hive,
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpDoSort(IN PLIST_ENTRY DriverListHead,
IN PUNICODE_STRING OrderList)
{
@@ -521,6 +527,7 @@ CmpDoSort(IN PLIST_ENTRY DriverListHead,
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpSortDriverList(IN PHHIVE Hive,
IN HCELL_INDEX ControlSet,
IN PLIST_ENTRY DriverListHead)
@@ -569,6 +576,7 @@ CmpSortDriverList(IN PHHIVE Hive,
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpOrderGroup(IN PBOOT_DRIVER_NODE StartNode,
IN PBOOT_DRIVER_NODE EndNode)
{
@@ -631,6 +639,7 @@ CmpOrderGroup(IN PBOOT_DRIVER_NODE StartNode,
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpResolveDriverDependencies(IN PLIST_ENTRY DriverListHead)
{
PLIST_ENTRY NextEntry;
diff --git a/ntoskrnl/config/cmconfig.c b/ntoskrnl/config/cmconfig.c
index 7aae14da7a6..f483d700983 100644
--- a/ntoskrnl/config/cmconfig.c
+++ b/ntoskrnl/config/cmconfig.c
@@ -16,6 +16,7 @@
NTSTATUS
NTAPI
+INIT_FUNCTION
CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
IN HANDLE NodeHandle,
OUT PHANDLE NewHandle,
@@ -195,6 +196,7 @@ CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
NTSTATUS
NTAPI
+INIT_FUNCTION
CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
IN HANDLE ParentHandle,
IN INTERFACE_TYPE InterfaceType,
@@ -311,6 +313,7 @@ CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
NTSTATUS
NTAPI
+INIT_FUNCTION
CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
NTSTATUS Status;
@@ -390,8 +393,3 @@ CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
NtClose(KeyHandle);
return Status;
}
-
-
-
-
-
diff --git a/ntoskrnl/config/cmcontrl.c b/ntoskrnl/config/cmcontrl.c
index 8d3459ba72e..1e481e455c0 100644
--- a/ntoskrnl/config/cmcontrl.c
+++ b/ntoskrnl/config/cmcontrl.c
@@ -18,6 +18,7 @@
LANGID
NTAPI
+INIT_FUNCTION
CmpConvertLangId(IN LPWSTR Name,
IN ULONG NameLength)
{
@@ -68,6 +69,7 @@ CmpConvertLangId(IN LPWSTR Name,
HCELL_INDEX
NTAPI
+INIT_FUNCTION
CmpWalkPath(IN PHHIVE SystemHive,
IN HCELL_INDEX ParentCell,
IN LPWSTR Path)
@@ -98,6 +100,7 @@ CmpWalkPath(IN PHHIVE SystemHive,
VOID
NTAPI
+INIT_FUNCTION
CmGetSystemControlValues(IN PVOID SystemHiveData,
IN PCM_SYSTEM_CONTROL_VECTOR ControlVector)
{
diff --git a/ntoskrnl/config/cmdata.c b/ntoskrnl/config/cmdata.c
index 6dbf2a0380d..a4e7acb6590 100644
--- a/ntoskrnl/config/cmdata.c
+++ b/ntoskrnl/config/cmdata.c
@@ -65,7 +65,7 @@ ULONG CmpTypeCount[MaximumType + 1];
HANDLE CmpRegistryRootHandle;
-UNICODE_STRING CmClassName[MaximumClass + 1] =
+INIT_FUNCTION UNICODE_STRING CmClassName[MaximumClass + 1] =
{
RTL_CONSTANT_STRING(L"System"),
RTL_CONSTANT_STRING(L"Processor"),
@@ -77,7 +77,7 @@ UNICODE_STRING CmClassName[MaximumClass + 1] =
RTL_CONSTANT_STRING(L"Undefined")
};
-UNICODE_STRING CmTypeName[MaximumType + 1] =
+INIT_FUNCTION UNICODE_STRING CmTypeName[MaximumType + 1] =
{
RTL_CONSTANT_STRING(L"System"),
RTL_CONSTANT_STRING(L"CentralProcessor"),
@@ -123,7 +123,7 @@ UNICODE_STRING CmTypeName[MaximumType + 1] =
RTL_CONSTANT_STRING(L"Undefined")
};
-CMP_MF_TYPE CmpMultifunctionTypes[] =
+INIT_FUNCTION CMP_MF_TYPE CmpMultifunctionTypes[] =
{
{"ISA", Isa, 0},
{"MCA", MicroChannel, 0},
@@ -136,7 +136,7 @@ CMP_MF_TYPE CmpMultifunctionTypes[] =
{NULL, Internal, 0}
};
-CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
+INIT_FUNCTION CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
{
{
L"Session Manager",
diff --git a/ntoskrnl/config/cmdelay.c b/ntoskrnl/config/cmdelay.c
index 015aa2f991f..58ac9a67ce8 100644
--- a/ntoskrnl/config/cmdelay.c
+++ b/ntoskrnl/config/cmdelay.c
@@ -185,6 +185,7 @@ CmpDelayCloseWorker(IN PVOID Context)
VOID
NTAPI
+INIT_FUNCTION
CmpInitializeDelayedCloseTable(VOID)
{
@@ -259,6 +260,7 @@ CmpDelayDerefKCBWorker(IN PVOID Context)
VOID
NTAPI
+INIT_FUNCTION
CmpInitDelayDerefKCBEngine(VOID)
{
/* Initialize lock and list */
diff --git a/ntoskrnl/config/cmhook.c b/ntoskrnl/config/cmhook.c
index 6ccd751f3ed..cf12c26404a 100644
--- a/ntoskrnl/config/cmhook.c
+++ b/ntoskrnl/config/cmhook.c
@@ -34,6 +34,7 @@ typedef struct _REGISTRY_CALLBACK
VOID
NTAPI
+INIT_FUNCTION
CmpInitCallback(VOID)
{
ULONG i;
diff --git a/ntoskrnl/config/cmkcbncb.c b/ntoskrnl/config/cmkcbncb.c
index a123a3cee56..1c093403c48 100644
--- a/ntoskrnl/config/cmkcbncb.c
+++ b/ntoskrnl/config/cmkcbncb.c
@@ -22,6 +22,7 @@ PCM_NAME_HASH_TABLE_ENTRY CmpNameCacheTable;
VOID
NTAPI
+INIT_FUNCTION
CmpInitializeCache(VOID)
{
ULONG Length, i;
diff --git a/ntoskrnl/config/cmse.c b/ntoskrnl/config/cmse.c
index 4ee2335c064..019a14c8868 100644
--- a/ntoskrnl/config/cmse.c
+++ b/ntoskrnl/config/cmse.c
@@ -18,6 +18,7 @@
PSECURITY_DESCRIPTOR
NTAPI
+INIT_FUNCTION
CmpHiveRootSecurityDescriptor(VOID)
{
NTSTATUS Status;
diff --git a/ntoskrnl/config/cmsysini.c b/ntoskrnl/config/cmsysini.c
index 779d902b650..f144e84a0fa 100644
--- a/ntoskrnl/config/cmsysini.c
+++ b/ntoskrnl/config/cmsysini.c
@@ -308,6 +308,7 @@ CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName,
NTSTATUS
NTAPI
+INIT_FUNCTION
CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
OBJECT_ATTRIBUTES ObjectAttributes;
@@ -361,6 +362,7 @@ Quickie:
NTSTATUS
NTAPI
+INIT_FUNCTION
CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
UNICODE_STRING ConfigName = RTL_CONSTANT_STRING(L"Control\\IDConfigDB");
@@ -689,6 +691,7 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName,
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PVOID HiveBase;
@@ -817,6 +820,7 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS
NTAPI
+INIT_FUNCTION
CmpCreateObjectTypes(VOID)
{
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
@@ -849,6 +853,7 @@ CmpCreateObjectTypes(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpCreateRootNode(IN PHHIVE Hive,
IN PCWSTR Name,
OUT PHCELL_INDEX Index)
@@ -909,6 +914,7 @@ CmpCreateRootNode(IN PHHIVE Hive,
BOOLEAN
NTAPI
+INIT_FUNCTION
CmpCreateRegistryRoot(VOID)
{
UNICODE_STRING KeyName;
@@ -1366,6 +1372,7 @@ CmpInitializeHiveList(IN USHORT Flag)
BOOLEAN
NTAPI
+INIT_FUNCTION
CmInitSystem1(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
@@ -1577,6 +1584,7 @@ CmInitSystem1(VOID)
VOID
NTAPI
+INIT_FUNCTION
CmpFreeDriverList(IN PHHIVE Hive,
IN PLIST_ENTRY DriverList)
{
@@ -1625,6 +1633,7 @@ CmpFreeDriverList(IN PHHIVE Hive,
PUNICODE_STRING*
NTAPI
+INIT_FUNCTION
CmGetSystemDriverList(VOID)
{
LIST_ENTRY DriverList;
diff --git a/ntoskrnl/config/powerpc/cmhardwr.c b/ntoskrnl/config/powerpc/cmhardwr.c
index a14d90a26e0..f620f736109 100644
--- a/ntoskrnl/config/powerpc/cmhardwr.c
+++ b/ntoskrnl/config/powerpc/cmhardwr.c
@@ -446,7 +446,7 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
}
/* Null-terminate it */
- CpuString[48] = ANSI_NULL;
+ CpuString[47] = ANSI_NULL;
}
}
diff --git a/ntoskrnl/ex/handle.c b/ntoskrnl/ex/handle.c
index 548163d0099..17ae2814550 100644
--- a/ntoskrnl/ex/handle.c
+++ b/ntoskrnl/ex/handle.c
@@ -23,6 +23,7 @@ EX_PUSH_LOCK HandleTableListLock;
VOID
NTAPI
+INIT_FUNCTION
ExpInitializeHandleTables(VOID)
{
/* Initialize the list of handle tables and the lock */
diff --git a/ntoskrnl/ex/hdlsterm.c b/ntoskrnl/ex/hdlsterm.c
index a47cd006152..ce34699fcb2 100644
--- a/ntoskrnl/ex/hdlsterm.c
+++ b/ntoskrnl/ex/hdlsterm.c
@@ -69,6 +69,7 @@ HdlspEnableTerminal(
VOID
NTAPI
+INIT_FUNCTION
HeadlessInit(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
diff --git a/ntoskrnl/ex/i386/fastinterlck_asm.S b/ntoskrnl/ex/i386/fastinterlck_asm.S
index f09edfd3b9c..566f37f5a0c 100644
--- a/ntoskrnl/ex/i386/fastinterlck_asm.S
+++ b/ntoskrnl/ex/i386/fastinterlck_asm.S
@@ -8,14 +8,13 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
#include
/* FUNCTIONS ****************************************************************/
.code32
-.text
/*
* NOTE: These functions must obey the following rules:
@@ -30,7 +29,7 @@
*ExInterlockedAddLargeStatistic(IN PLARGE_INTEGER Addend,
* IN ULONG Increment)
*/
-.global @ExInterlockedAddLargeStatistic@8
+PUBLIC @ExInterlockedAddLargeStatistic@8
@ExInterlockedAddLargeStatistic@8:
#ifdef CONFIG_SMP
@@ -38,10 +37,10 @@
lock add [ecx], edx
/* Check for carry bit and return */
- jb 1f
+ jb .l1
ret
-1:
+.l1:
/* Add carry */
lock adc dword ptr [ecx+4], 0
#else
@@ -58,7 +57,7 @@
* IN ULONG Increment,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExfInterlockedAddUlong@12
+PUBLIC @ExfInterlockedAddUlong@12
@ExfInterlockedAddUlong@12:
/* Save flags */
@@ -103,7 +102,7 @@
* IN PLIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExfInterlockedInsertHeadList@12
+PUBLIC @ExfInterlockedInsertHeadList@12
@ExfInterlockedInsertHeadList@12:
#ifdef CONFIG_SMP
@@ -139,11 +138,11 @@
/* Check if list was empty */
xor eax, ecx
- jz 2f
+ jz .l2
/* Return list pointer */
xor eax, ecx
-2:
+.l2:
ret 4
#ifdef CONFIG_SMP
@@ -159,7 +158,7 @@
* IN PLIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExfInterlockedInsertTailList@12
+PUBLIC @ExfInterlockedInsertTailList@12
@ExfInterlockedInsertTailList@12:
#ifdef CONFIG_SMP
@@ -195,11 +194,11 @@
/* Check if list was empty */
xor eax, ecx
- jz 2f
+ jz .l3
/* Return list pointer */
xor eax, ecx
-2:
+.l3:
ret 4
#ifdef CONFIG_SMP
@@ -214,7 +213,7 @@
*ExfInterlockedRemoveHeadList(IN PLIST_ENTRY ListHead,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExfInterlockedRemoveHeadList@8
+PUBLIC @ExfInterlockedRemoveHeadList@8
@ExfInterlockedRemoveHeadList@8:
/* Save flags and disable interrupts */
@@ -228,7 +227,7 @@
/* Check if it's empty */
cmp eax, ecx
- je 2f
+ je .l4
/* Get the next entry and do the deletion */
#ifdef CONFIG_SMP
@@ -254,7 +253,7 @@
/* Return */
ret
-2:
+.l4:
/* Release lock */
RELEASE_SPINLOCK(edx)
@@ -276,7 +275,7 @@
*ExfInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExfInterlockedPopEntryList@8
+PUBLIC @ExfInterlockedPopEntryList@8
@ExfInterlockedPopEntryList@8:
/* Save flags and disable interrupts */
@@ -290,7 +289,7 @@
/* Check if it's empty */
or eax, eax
- je 3f
+ je .l6
/* Get next entry and do deletion */
#ifdef CONFIG_SMP
@@ -302,7 +301,7 @@
pop edx
#endif
-2:
+.l5:
/* Release lock */
RELEASE_SPINLOCK(edx)
@@ -312,10 +311,10 @@
/* Return */
ret
-3:
+.l6:
/* Return empty list */
xor eax, eax
- jmp 2b
+ jmp .l5
#ifdef CONFIG_SMP
.spin5:
@@ -329,7 +328,7 @@
* IN PSINGLE_LIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExfInterlockedPushEntryList@12
+PUBLIC @ExfInterlockedPushEntryList@12
@ExfInterlockedPushEntryList@12:
/* Save flags */
@@ -383,11 +382,11 @@
*ExInterlockedPopEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExInterlockedPopEntrySList@8
-.global @InterlockedPopEntrySList@4
-.global _ExpInterlockedPopEntrySListResume@0
-.global _ExpInterlockedPopEntrySListFault@0
-.global _ExpInterlockedPopEntrySListEnd@0
+PUBLIC @ExInterlockedPopEntrySList@8
+PUBLIC @InterlockedPopEntrySList@4
+PUBLIC _ExpInterlockedPopEntrySListResume@0
+PUBLIC _ExpInterlockedPopEntrySListFault@0
+PUBLIC _ExpInterlockedPopEntrySListEnd@0
@ExInterlockedPopEntrySList@8:
@InterlockedPopEntrySList@4:
@@ -405,7 +404,7 @@ _ExpInterlockedPopEntrySListResume@0:
/* Check if the list is empty */
or eax, eax
- jz 2f
+ jz .l7
/* Copy sequence number and adjust it */
lea ecx, [edx-1]
@@ -418,7 +417,7 @@ _ExpInterlockedPopEntrySListEnd@0:
jnz _ExpInterlockedPopEntrySListResume@0
/* Restore registers and return */
-2:
+.l7:
pop ebp
pop ebx
ret
@@ -429,13 +428,13 @@ _ExpInterlockedPopEntrySListEnd@0:
* IN PSINGLE_LIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExInterlockedPushEntrySList@12
+PUBLIC @ExInterlockedPushEntrySList@12
@ExInterlockedPushEntrySList@12:
/* So we can fall through below */
pop [esp]
-.global @InterlockedPushEntrySList@8
+PUBLIC @InterlockedPushEntrySList@8
@InterlockedPushEntrySList@8:
/* Save registers */
@@ -450,19 +449,18 @@ _ExpInterlockedPopEntrySListEnd@0:
mov edx, [ebp+4]
mov eax, [ebp]
-1:
+.l8:
/* Set link pointer */
mov [ebx], eax
/* Copy sequence number and adjust it */
- lea ecx, [edx+0x10001]
+ lea ecx, [edx + HEX(10001)]
/* Do the exchange */
LOCK cmpxchg8b qword ptr [ebp]
- jnz 1b
+ jnz .l8
/* Restore registers and return */
-2:
pop ebp
pop ebx
ret
@@ -471,7 +469,7 @@ _ExpInterlockedPopEntrySListEnd@0:
*FASTCALL
*ExInterlockedFlushSList(IN PSINGLE_LIST_ENTRY ListHead)
*/
-.global @ExInterlockedFlushSList@4
+PUBLIC @ExInterlockedFlushSList@4
@ExInterlockedFlushSList@4:
/* Save registers */
@@ -488,10 +486,10 @@ _ExpInterlockedPopEntrySListEnd@0:
mov edx, [ebp+4]
mov eax, [ebp]
-1:
+.l9:
/* Check if the list is empty */
or eax, eax
- jz 2f
+ jz .l10
/* Clear sequence and pointer */
mov ecx, edx
@@ -499,10 +497,10 @@ _ExpInterlockedPopEntrySListEnd@0:
/* Do the exchange */
LOCK cmpxchg8b qword ptr [ebp]
- jnz 1b
+ jnz .l9
/* Restore registers and return */
-2:
+.l10:
pop ebp
pop ebx
ret
@@ -511,7 +509,7 @@ _ExpInterlockedPopEntrySListEnd@0:
*FASTCALL
*Exfi386InterlockedIncrementLong(IN PLONG Addend)
*/
-.global @Exfi386InterlockedIncrementLong@4
+PUBLIC @Exfi386InterlockedIncrementLong@4
@Exfi386InterlockedIncrementLong@4:
/* Do the op */
@@ -526,7 +524,7 @@ _ExpInterlockedPopEntrySListEnd@0:
*FASTCALL
*Exfi386InterlockedDecrementLong(IN PLONG Addend)
*/
-.global @Exfi386InterlockedDecrementLong@4
+PUBLIC @Exfi386InterlockedDecrementLong@4
@Exfi386InterlockedDecrementLong@4:
/* Do the op */
@@ -542,7 +540,7 @@ _ExpInterlockedPopEntrySListEnd@0:
*Exfi386InterlockedExchangeUlong(IN PULONG Taget,
* IN ULONG Value)
*/
-.global @Exfi386InterlockedExchangeUlong@8
+PUBLIC @Exfi386InterlockedExchangeUlong@8
@Exfi386InterlockedExchangeUlong@8:
#ifdef CONFIG_SMP
@@ -552,9 +550,9 @@ _ExpInterlockedPopEntrySListEnd@0:
#else
/* On UP, use cmpxchg */
mov eax, [ecx]
-1:
+.l11:
cmpxchg [ecx], edx
- jnz 1b
+ jnz .l11
#endif
/* Return */
@@ -566,7 +564,7 @@ _ExpInterlockedPopEntrySListEnd@0:
* IN PLONGLONG Exchange,
* IN PLONGLONG Comperand)
*/
-.global @ExfInterlockedCompareExchange64@12
+PUBLIC @ExfInterlockedCompareExchange64@12
@ExfInterlockedCompareExchange64@12:
/* Save registers */
@@ -598,7 +596,7 @@ _ExpInterlockedPopEntrySListEnd@0:
* IN PLONGLONG Comperand,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExInterlockedCompareExchange64@16
+PUBLIC @ExInterlockedCompareExchange64@16
@ExInterlockedCompareExchange64@16:
/* Save registers */
@@ -630,7 +628,7 @@ _ExpInterlockedPopEntrySListEnd@0:
*ExfInterlockedPopEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExfInterlockedPopEntrySList@8
+PUBLIC @ExfInterlockedPopEntrySList@8
@ExfInterlockedPopEntrySList@8:
/* Save flags */
@@ -646,7 +644,7 @@ _ExpInterlockedPopEntrySListEnd@0:
/* Get the next link and check if it's empty */
mov eax, [ecx]
or eax, eax
- jz 1f
+ jz .l12
/* Get address of the next link and store it */
push [eax]
@@ -655,7 +653,7 @@ _ExpInterlockedPopEntrySListEnd@0:
/* Decrement list depth */
dec dword ptr [ecx+4]
-1:
+.l12:
#ifdef CONFIG_SMP
/* Release spinlock */
RELEASE_SPINLOCK(edx)
@@ -678,7 +676,7 @@ _ExpInterlockedPopEntrySListEnd@0:
* IN PSINGLE_LIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExfInterlockedPushEntrySList@12
+PUBLIC @ExfInterlockedPushEntrySList@12
@ExfInterlockedPushEntrySList@12:
/* Save flags */
@@ -727,7 +725,7 @@ _ExpInterlockedPopEntrySListEnd@0:
* IN PLONGLONG Comperand,
* IN PKSPIN_LOCK Lock)
*/
-.global @ExpInterlockedCompareExchange64@16
+PUBLIC @ExpInterlockedCompareExchange64@16
@ExpInterlockedCompareExchange64@16:
/* Save registers */
@@ -802,4 +800,6 @@ NoMatch:
pushfd
SPIN_ON_LOCK(esi, .startc)
#endif
+
+END
/* EOF */
diff --git a/ntoskrnl/ex/i386/interlck_asm.S b/ntoskrnl/ex/i386/interlck_asm.S
index 954091cee85..755813e80d8 100644
--- a/ntoskrnl/ex/i386/interlck_asm.S
+++ b/ntoskrnl/ex/i386/interlck_asm.S
@@ -8,14 +8,13 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
#include
/* FUNCTIONS ****************************************************************/
.code32
-.text
/*
* NOTE: These functions must obey the following rules:
@@ -31,7 +30,7 @@
* IN PLIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedAddLargeInteger@16
+PUBLIC _ExInterlockedAddLargeInteger@16
_ExInterlockedAddLargeInteger@16:
/* Prepare stack frame */
@@ -97,7 +96,7 @@ _ExInterlockedAddLargeInteger@16:
* IN PLIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedAddUlong@12
+PUBLIC _ExInterlockedAddUlong@12
_ExInterlockedAddUlong@12:
/* Save flags and disable interrupts */
@@ -153,7 +152,7 @@ _ExInterlockedAddUlong@12:
* IN PLIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedInsertHeadList@12
+PUBLIC _ExInterlockedInsertHeadList@12
_ExInterlockedInsertHeadList@12:
/* Save lock pointer */
@@ -189,12 +188,12 @@ _ExInterlockedInsertHeadList@12:
/* check if the list was empty and return NULL */
xor eax, edx
- jz 2f
+ jz .l2
/* Return pointer */
mov eax, edx
-2:
+.l2:
ret 12
#ifdef CONFIG_SMP
@@ -209,7 +208,7 @@ _ExInterlockedInsertHeadList@12:
* IN PLIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedInsertTailList@12
+PUBLIC _ExInterlockedInsertTailList@12
_ExInterlockedInsertTailList@12:
/* Save lock pointer */
@@ -245,12 +244,12 @@ _ExInterlockedInsertTailList@12:
/* Check if the list was empty and return NULL */
xor eax, edx
- jz 2f
+ jz .l3
/* Return pointer */
mov eax, edx
-2:
+.l3:
ret 12
#ifdef CONFIG_SMP
@@ -264,7 +263,7 @@ _ExInterlockedInsertTailList@12:
*ExInterlockedRemoveHeadList(IN PLIST_ENTRY ListHead,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedRemoveHeadList@8
+PUBLIC _ExInterlockedRemoveHeadList@8
_ExInterlockedRemoveHeadList@8:
/* Save lock pointer */
@@ -284,7 +283,7 @@ _ExInterlockedRemoveHeadList@8:
/* Check if it's empty */
cmp eax, edx
- je 2f
+ je .l4
/* Get next entry and do deletion */
mov ecx, [eax]
@@ -303,7 +302,7 @@ _ExInterlockedRemoveHeadList@8:
/* Return */
ret 8
-2:
+.l4:
/* Release lock */
#ifdef CONFIG_SMP
mov edx, [esp+12]
@@ -328,7 +327,7 @@ _ExInterlockedRemoveHeadList@8:
*ExInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedPopEntryList@8
+PUBLIC _ExInterlockedPopEntryList@8
_ExInterlockedPopEntryList@8:
/* Save lock pointer */
@@ -348,13 +347,13 @@ _ExInterlockedPopEntryList@8:
/* Check if it's empty */
or eax, eax
- je 3f
+ je .l6
/* Get next entry and do deletion */
mov edx, [eax]
mov [ecx], edx
-2:
+.l5:
/* Release lock */
#ifdef CONFIG_SMP
mov ecx, [esp+12]
@@ -367,10 +366,10 @@ _ExInterlockedPopEntryList@8:
/* Return */
ret 8
-3:
+.l6:
/* Return empty list */
xor eax, eax
- jmp 2b
+ jmp .l5
#ifdef CONFIG_SMP
.spin6:
@@ -384,7 +383,7 @@ _ExInterlockedPopEntryList@8:
* IN PSINGLE_LIST_ENTRY ListEntry,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedPushEntryList@12
+PUBLIC _ExInterlockedPushEntryList@12
_ExInterlockedPushEntryList@12:
/* Save lock pointer */
@@ -430,7 +429,7 @@ _ExInterlockedPushEntryList@12:
*ExInterlockedIncrementLong(IN PLONG Addend,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedIncrementLong@8
+PUBLIC _ExInterlockedIncrementLong@8
_ExInterlockedIncrementLong@8:
/* Get addend */
@@ -449,7 +448,7 @@ _ExInterlockedIncrementLong@8:
*ExInterlockedDecrementLong(IN PLONG Addend,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedDecrementLong@8
+PUBLIC _ExInterlockedDecrementLong@8
_ExInterlockedDecrementLong@8:
/* Get addend */
@@ -469,7 +468,7 @@ _ExInterlockedDecrementLong@8:
* IN ULONG Value,
* IN PKSPIN_LOCK Lock)
*/
-.global _ExInterlockedExchangeUlong@12
+PUBLIC _ExInterlockedExchangeUlong@12
_ExInterlockedExchangeUlong@12:
/* Get pointers */
@@ -498,7 +497,7 @@ _ExInterlockedExchangeUlong@12:
*Exi386InterlockedIncrementLong(IN PLONG Addend,
* IN PKSPIN_LOCK Lock)
*/
-.global _Exi386InterlockedIncrementLong@4
+PUBLIC _Exi386InterlockedIncrementLong@4
_Exi386InterlockedIncrementLong@4:
/* Get addend */
@@ -517,7 +516,7 @@ _Exi386InterlockedIncrementLong@4:
*Exi386InterlockedDecrementLong(IN PLONG Addend,
* IN PKSPIN_LOCK Lock)
*/
-.global _Exi386InterlockedDecrementLong@4
+PUBLIC _Exi386InterlockedDecrementLong@4
_Exi386InterlockedDecrementLong@4:
/* Get addend */
@@ -537,7 +536,7 @@ _Exi386InterlockedDecrementLong@4:
* IN ULONG Value,
* IN PKSPIN_LOCK Lock)
*/
-.global _Exi386InterlockedExchangeUlong@12
+PUBLIC _Exi386InterlockedExchangeUlong@12
_Exi386InterlockedExchangeUlong@12:
/* Get pointers */
@@ -560,5 +559,6 @@ _Exi386InterlockedExchangeUlong@12:
/* Return */
ret 8
-
+
+END
/* EOF */
diff --git a/ntoskrnl/ex/i386/ioport.S b/ntoskrnl/ex/i386/ioport.S
index c9c55a160f4..ba456c799f8 100644
--- a/ntoskrnl/ex/i386/ioport.S
+++ b/ntoskrnl/ex/i386/ioport.S
@@ -8,54 +8,52 @@
/* INCLUDES ******************************************************************/
-#include
-.intel_syntax noprefix
+#include
+#include
/* GLOBALS *******************************************************************/
-.globl _READ_REGISTER_UCHAR@4
-.globl _READ_REGISTER_USHORT@4
-.globl _READ_REGISTER_ULONG@4
-.globl _READ_REGISTER_BUFFER_UCHAR@12
-.globl _READ_REGISTER_BUFFER_USHORT@12
-.globl _READ_REGISTER_BUFFER_ULONG@12
-.globl _WRITE_REGISTER_UCHAR@8
-.globl _WRITE_REGISTER_USHORT@8
-.globl _WRITE_REGISTER_ULONG@8
-.globl _WRITE_REGISTER_BUFFER_UCHAR@12
-.globl _WRITE_REGISTER_BUFFER_USHORT@12
-.globl _WRITE_REGISTER_BUFFER_ULONG@12
+PUBLIC _READ_REGISTER_UCHAR@4
+PUBLIC _READ_REGISTER_USHORT@4
+PUBLIC _READ_REGISTER_ULONG@4
+PUBLIC _READ_REGISTER_BUFFER_UCHAR@12
+PUBLIC _READ_REGISTER_BUFFER_USHORT@12
+PUBLIC _READ_REGISTER_BUFFER_ULONG@12
+PUBLIC _WRITE_REGISTER_UCHAR@8
+PUBLIC _WRITE_REGISTER_USHORT@8
+PUBLIC _WRITE_REGISTER_ULONG@8
+PUBLIC _WRITE_REGISTER_BUFFER_UCHAR@12
+PUBLIC _WRITE_REGISTER_BUFFER_USHORT@12
+PUBLIC _WRITE_REGISTER_BUFFER_ULONG@12
/* FUNCTIONS *****************************************************************/
-.func READ_REGISTER_UCHAR@4
+.code
+
_READ_REGISTER_UCHAR@4:
/* Return the requested memory location */
mov edx, [esp+4]
mov al, [edx]
ret 4
-.endfunc
-.func READ_REGISTER_USHORT@4
+
_READ_REGISTER_USHORT@4:
/* Return the requested memory location */
mov edx, [esp+4]
mov ax, [edx]
ret 4
-.endfunc
-.func READ_REGISTER_ULONG@4
+
_READ_REGISTER_ULONG@4:
/* Return the requested memory location */
mov edx, [esp+4]
mov eax, [edx]
ret 4
-.endfunc
-.func READ_REGISTER_BUFFER_UCHAR@12
+
_READ_REGISTER_BUFFER_UCHAR@12:
/* Save volatiles */
@@ -72,9 +70,8 @@ _READ_REGISTER_BUFFER_UCHAR@12:
mov edi, edx
mov esi, eax
ret 12
-.endfunc
-.func READ_REGISTER_BUFFER_USHORT@12
+
_READ_REGISTER_BUFFER_USHORT@12:
/* Save volatiles */
@@ -91,9 +88,8 @@ _READ_REGISTER_BUFFER_USHORT@12:
mov edi, edx
mov esi, eax
ret 12
-.endfunc
-.func READ_REGISTER_BUFFER_ULONG@12
+
_READ_REGISTER_BUFFER_ULONG@12:
/* Save volatiles */
@@ -110,9 +106,8 @@ _READ_REGISTER_BUFFER_ULONG@12:
mov edi, edx
mov esi, eax
ret 12
-.endfunc
-.func WRITE_REGISTER_UCHAR@8
+
_WRITE_REGISTER_UCHAR@8:
/* Write to memory */
@@ -123,9 +118,8 @@ _WRITE_REGISTER_UCHAR@8:
/* Flush posted write buffers and return */
lock or [esp+4], edx
ret 8
-.endfunc
-.func WRITE_REGISTER_USHORT@8
+
_WRITE_REGISTER_USHORT@8:
/* Write to memory */
@@ -136,9 +130,8 @@ _WRITE_REGISTER_USHORT@8:
/* Flush posted write buffers and return */
lock or [esp+4], edx
ret 8
-.endfunc
-.func WRITE_REGISTER_ULONG@8
+
_WRITE_REGISTER_ULONG@8:
/* Write to memory */
@@ -149,9 +142,8 @@ _WRITE_REGISTER_ULONG@8:
/* Flush posted write buffers and return */
lock or [esp+4], edx
ret 8
-.endfunc
-.func WRITE_REGISTER_BUFFER_UCHAR@12
+
_WRITE_REGISTER_BUFFER_UCHAR@12:
/* Save volatiles */
@@ -171,9 +163,8 @@ _WRITE_REGISTER_BUFFER_UCHAR@12:
mov edi, edx
mov esi, eax
ret 12
-.endfunc
-.func WRITE_REGISTER_BUFFER_USHORT@12
+
_WRITE_REGISTER_BUFFER_USHORT@12:
/* Save volatiles */
@@ -193,9 +184,8 @@ _WRITE_REGISTER_BUFFER_USHORT@12:
mov edi, edx
mov esi, eax
ret 12
-.endfunc
-.func WRITE_REGISTER_BUFFER_ULONG@12
+
_WRITE_REGISTER_BUFFER_ULONG@12:
/* Save volatiles */
@@ -215,6 +205,6 @@ _WRITE_REGISTER_BUFFER_ULONG@12:
mov edi, edx
mov esi, eax
ret 12
-.endfunc
+END
/* EOF */
diff --git a/ntoskrnl/ex/init.c b/ntoskrnl/ex/init.c
index 650de252895..ee7cc3c2f55 100644
--- a/ntoskrnl/ex/init.c
+++ b/ntoskrnl/ex/init.c
@@ -14,6 +14,14 @@
#include
#include "ntstrsafe.h"
+/* Temporary hack */
+BOOLEAN
+NTAPI
+MmArmInitSystem(
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
typedef struct _INIT_BUFFER
{
WCHAR DebugBuffer[256];
@@ -79,6 +87,7 @@ BOOLEAN ExpRealTimeIsUniversal;
NTSTATUS
NTAPI
+INIT_FUNCTION
ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
UNICODE_STRING LinkName;
@@ -190,6 +199,7 @@ ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
LARGE_INTEGER SectionSize;
@@ -321,6 +331,7 @@ ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
}
/* Copy the codepage data in its new location. */
+ ASSERT(SectionBase > MmSystemRangeStart);
RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
/* Free the previously allocated buffer and set the new location */
@@ -364,6 +375,7 @@ ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
OUT PCHAR *ProcessEnvironment)
@@ -584,6 +596,7 @@ ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
ULONG
NTAPI
+INIT_FUNCTION
ExComputeTickCountMultiplier(IN ULONG ClockIncrement)
{
ULONG MsRemainder = 0, MsIncrement;
@@ -616,6 +629,7 @@ ExComputeTickCountMultiplier(IN ULONG ClockIncrement)
BOOLEAN
NTAPI
+INIT_FUNCTION
ExpInitSystemPhase0(VOID)
{
/* Initialize EXRESOURCE Support */
@@ -638,6 +652,7 @@ ExpInitSystemPhase0(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
ExpInitSystemPhase1(VOID)
{
/* Initialize worker threads */
@@ -675,6 +690,7 @@ ExpInitSystemPhase1(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
ExInitSystem(VOID)
{
/* Check the initialization phase */
@@ -700,6 +716,7 @@ ExInitSystem(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PLOADER_PARAMETER_EXTENSION Extension;
@@ -725,6 +742,7 @@ ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
ULONG i = 0;
@@ -817,6 +835,7 @@ ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
ExBurnMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN ULONG PagesToDestroy,
IN TYPE_OF_MEMORY MemoryType)
@@ -862,6 +881,7 @@ ExBurnMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
VOID
NTAPI
+INIT_FUNCTION
ExpInitializeExecutive(IN ULONG Cpu,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
@@ -1045,7 +1065,7 @@ ExpInitializeExecutive(IN ULONG Cpu,
if (!ExInitSystem()) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
/* Initialize the memory manager at phase 0 */
- if (!MmInitSystem(0, LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
+ if (!MmArmInitSystem(0, LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
/* Load boot symbols */
ExpLoadBootSymbols(LoaderBlock);
@@ -1272,6 +1292,7 @@ ExpInitializeExecutive(IN ULONG Cpu,
VOID
NTAPI
+INIT_FUNCTION
Phase1InitializationDiscard(IN PVOID Context)
{
PLOADER_PARAMETER_BLOCK LoaderBlock = Context;
@@ -1577,7 +1598,7 @@ Phase1InitializationDiscard(IN PVOID Context)
if (!MmInitSystem(1, LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED);
/* Create NLS section */
- ExpInitNls(KeLoaderBlock);
+ ExpInitNls(LoaderBlock);
/* Initialize Cache Views */
if (!CcInitializeCacheManager()) KeBugCheck(CACHE_INITIALIZATION_FAILED);
@@ -1862,8 +1883,8 @@ Phase1InitializationDiscard(IN PVOID Context)
NtClose(OptionHandle);
}
- /* Unmap Low memory, and initialize the MPW and Balancer Thread */
- MmInitSystem(2, LoaderBlock);
+ /* FIXME: This doesn't do anything for now */
+ MmArmInitSystem(2, LoaderBlock);
/* Update progress bar */
InbvUpdateProgressBar(80);
@@ -1890,6 +1911,7 @@ Phase1InitializationDiscard(IN PVOID Context)
InbvUpdateProgressBar(90);
/* Launch initial process */
+ DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
ProcessInfo = &InitBuffer->ProcessInfo;
ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment);
@@ -1936,6 +1958,7 @@ Phase1InitializationDiscard(IN PVOID Context)
/* Free the boot buffer */
ExFreePool(InitBuffer);
+ DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
}
VOID
diff --git a/ntoskrnl/ex/lookas.c b/ntoskrnl/ex/lookas.c
index 7979e739e06..a82ececef68 100644
--- a/ntoskrnl/ex/lookas.c
+++ b/ntoskrnl/ex/lookas.c
@@ -31,6 +31,7 @@ GENERAL_LOOKASIDE ExpSmallPagedPoolLookasideLists[MAXIMUM_PROCESSORS];
VOID
NTAPI
+INIT_FUNCTION
ExInitializeSystemLookasideList(IN PGENERAL_LOOKASIDE List,
IN POOL_TYPE Type,
IN ULONG Size,
@@ -58,6 +59,7 @@ ExInitializeSystemLookasideList(IN PGENERAL_LOOKASIDE List,
VOID
NTAPI
+INIT_FUNCTION
ExInitPoolLookasidePointers(VOID)
{
ULONG i;
@@ -87,6 +89,7 @@ ExInitPoolLookasidePointers(VOID)
VOID
NTAPI
+INIT_FUNCTION
ExpInitLookasideLists()
{
ULONG i;
diff --git a/ntoskrnl/ex/pushlock.c b/ntoskrnl/ex/pushlock.c
index f426d3d6c52..18ef8d66574 100644
--- a/ntoskrnl/ex/pushlock.c
+++ b/ntoskrnl/ex/pushlock.c
@@ -41,6 +41,7 @@ ULONG ExPushLockSpinCount = 0;
*--*/
VOID
NTAPI
+INIT_FUNCTION
ExpInitializePushLocks(VOID)
{
#ifdef CONFIG_SMP
diff --git a/ntoskrnl/ex/sysinfo.c b/ntoskrnl/ex/sysinfo.c
index ee585576967..483c92057ea 100644
--- a/ntoskrnl/ex/sysinfo.c
+++ b/ntoskrnl/ex/sysinfo.c
@@ -547,8 +547,7 @@ QSI_DEF(SystemPerformanceInformation)
* Add up all the used "Committed" memory + pagefile.
* Not sure this is right. 8^\
*/
- Spi->CommittedPages = MiMemoryConsumers[MC_PPOOL].PagesUsed +
- MiMemoryConsumers[MC_NPPOOL].PagesUsed +
+ Spi->CommittedPages = MiMemoryConsumers[MC_SYSTEM].PagesUsed +
MiMemoryConsumers[MC_CACHE].PagesUsed +
MiMemoryConsumers[MC_USER].PagesUsed +
MiUsedSwapPages;
@@ -574,10 +573,10 @@ QSI_DEF(SystemPerformanceInformation)
Spi->MappedPagesWriteCount = 0; /* FIXME */
Spi->MappedWriteIoCount = 0; /* FIXME */
- Spi->PagedPoolPages = MiMemoryConsumers[MC_PPOOL].PagesUsed;
+ Spi->PagedPoolPages = 0; /* FIXME */
Spi->PagedPoolAllocs = 0; /* FIXME */
Spi->PagedPoolFrees = 0; /* FIXME */
- Spi->NonPagedPoolPages = MiMemoryConsumers[MC_NPPOOL].PagesUsed;
+ Spi->NonPagedPoolPages = 0; /* FIXME */
Spi->NonPagedPoolAllocs = 0; /* FIXME */
Spi->NonPagedPoolFrees = 0; /* FIXME */
@@ -592,7 +591,7 @@ QSI_DEF(SystemPerformanceInformation)
Spi->Spare3Count = 0; /* FIXME */
Spi->ResidentSystemCachePage = MiMemoryConsumers[MC_CACHE].PagesUsed;
- Spi->ResidentPagedPoolPage = MiMemoryConsumers[MC_PPOOL].PagesUsed; /* FIXME */
+ Spi->ResidentPagedPoolPage = 0; /* FIXME */
Spi->ResidentSystemDriverPage = 0; /* FIXME */
Spi->CcFastReadNoWait = 0; /* FIXME */
diff --git a/ntoskrnl/ex/xipdisp.c b/ntoskrnl/ex/xipdisp.c
index aa739c2dfa8..c3249f43383 100644
--- a/ntoskrnl/ex/xipdisp.c
+++ b/ntoskrnl/ex/xipdisp.c
@@ -17,6 +17,7 @@
PMEMORY_ALLOCATION_DESCRIPTOR
NTAPI
+INIT_FUNCTION
XIPpFindMemoryDescriptor(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PLIST_ENTRY NextEntry;
@@ -40,6 +41,7 @@ XIPpFindMemoryDescriptor(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
XIPInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PCHAR CommandLine, XipBoot, XipRom, XipMegs, XipVerbose, XipRam;
diff --git a/ntoskrnl/fsrtl/dbcsname.c b/ntoskrnl/fsrtl/dbcsname.c
index 64359a50c01..903da2eeab3 100644
--- a/ntoskrnl/fsrtl/dbcsname.c
+++ b/ntoskrnl/fsrtl/dbcsname.c
@@ -48,6 +48,7 @@ FsRtlDissectDbcs(IN ANSI_STRING Name,
{
ULONG FirstPosition, i;
ULONG SkipFirstSlash = 0;
+ PAGED_CODE();
/* Zero the strings before continuing */
RtlZeroMemory(FirstPart, sizeof(ANSI_STRING));
@@ -116,6 +117,7 @@ NTAPI
FsRtlDoesDbcsContainWildCards(IN PANSI_STRING Name)
{
ULONG i;
+ PAGED_CODE();
/* Check every character */
for (i = 0; i < Name->Length; i++)
@@ -150,7 +152,7 @@ FsRtlDoesDbcsContainWildCards(IN PANSI_STRING Name)
*
* @return TRUE if Name is found in Expression, FALSE otherwise
*
- * @remarks None
+ * @remarks
*
*--*/
BOOLEAN
@@ -159,7 +161,10 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
IN PANSI_STRING Name)
{
ULONG ExpressionPosition, NamePosition, MatchingChars = 0;
+ PAGED_CODE();
+ ASSERT(Name->Length);
+ ASSERT(Expression->Length);
ASSERT(!FsRtlDoesDbcsContainWildCards(Name));
/* One can't be null, both can be */
@@ -242,6 +247,7 @@ FsRtlIsFatDbcsLegal(IN ANSI_STRING DbcsName,
ANSI_STRING FirstPart, RemainingPart, Name;
BOOLEAN LastDot;
ULONG i;
+ PAGED_CODE();
/* Just quit if the string is empty */
if (!DbcsName.Length)
@@ -378,6 +384,7 @@ FsRtlIsHpfsDbcsLegal(IN ANSI_STRING DbcsName,
{
ANSI_STRING FirstPart, RemainingPart, Name;
ULONG i;
+ PAGED_CODE();
/* Just quit if the string is empty */
if (!DbcsName.Length)
diff --git a/ntoskrnl/fsrtl/faulttol.c b/ntoskrnl/fsrtl/faulttol.c
index ca66fab20f4..ea868adbb3e 100644
--- a/ntoskrnl/fsrtl/faulttol.c
+++ b/ntoskrnl/fsrtl/faulttol.c
@@ -17,7 +17,7 @@
/*++
* @name FsRtlBalanceReads
- * @implemented NT 4.0
+ * @implemented NT 5.2
*
* The FsRtlBalanceReads routine sends an IRP to an FTDISK Driver
* requesting the driver to balance read requests across a mirror set.
@@ -65,6 +65,8 @@ FsRtlBalanceReads(PDEVICE_OBJECT TargetDevice)
KernelMode,
FALSE,
NULL);
+ ASSERT(Status == STATUS_SUCCESS);
+
/* Return Status */
Status = IoStatusBlock.Status;
}
@@ -75,7 +77,7 @@ FsRtlBalanceReads(PDEVICE_OBJECT TargetDevice)
/*++
* @name FsRtlSyncVolumes
- * @implemented NT 4.0
+ * @implemented NT 5.2
*
* The FsRtlSyncVolumes routine is deprecated.
*
diff --git a/ntoskrnl/fsrtl/filtrctx.c b/ntoskrnl/fsrtl/filtrctx.c
index 24d88c45c4e..89c670739b8 100644
--- a/ntoskrnl/fsrtl/filtrctx.c
+++ b/ntoskrnl/fsrtl/filtrctx.c
@@ -3,7 +3,7 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/fsrtl/filtrctx.c
* PURPOSE: File Stream Filter Context support for File System Drivers
- * PROGRAMMERS: None.
+ * PROGRAMMERS: Pierre Schweitzer (pierre.schweitzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
@@ -12,11 +12,42 @@
#define NDEBUG
#include
+/* PRIVATE FUNCTIONS *********************************************************/
+
+typedef struct _FILE_OBJECT_FILTER_CONTEXTS
+{
+ FAST_MUTEX FilterContextsMutex;
+ LIST_ENTRY FilterContexts;
+} FILE_OBJECT_FILTER_CONTEXTS, *PFILE_OBJECT_FILTER_CONTEXTS;
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+FsRtlPTeardownPerFileObjectContexts(IN PFILE_OBJECT FileObject)
+{
+ PFILE_OBJECT_FILTER_CONTEXTS FOContext = NULL;
+
+ ASSERT(FileObject);
+
+ if (!(FOContext = IoGetFileObjectFilterContext(FileObject)))
+ {
+ return;
+ }
+
+ ASSERT(IoChangeFileObjectFilterContext(FileObject, FOContext, FALSE) == STATUS_SUCCESS);
+ ASSERT(IsListEmpty(&(FOContext->FilterContexts)));
+
+ ExFreePoolWithTag(FOContext, 'FOCX');
+}
+
+
/* PUBLIC FUNCTIONS **********************************************************/
/*++
* @name FsRtlIsPagingFile
- * @implemented NT 4.0
+ * @implemented NT 5.2
*
* The FsRtlIsPagingFile routine checks if the FileObject is a Paging File.
*
@@ -32,25 +63,11 @@ LOGICAL
NTAPI
FsRtlIsPagingFile(IN PFILE_OBJECT FileObject)
{
- KeBugCheck(FILE_SYSTEM);
- return FALSE;
+ return MmIsFileObjectAPagingFile(FileObject);
}
/*
- * @unimplemented
- */
-PFSRTL_PER_STREAM_CONTEXT
-NTAPI
-FsRtlLookupPerStreamContextInternal(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext,
- IN PVOID OwnerId OPTIONAL,
- IN PVOID InstanceId OPTIONAL)
-{
- KeBugCheck(FILE_SYSTEM);
- return FALSE;
-}
-
-/*
- * @unimplemented
+ * @implemented
*/
PFSRTL_PER_FILEOBJECT_CONTEXT
NTAPI
@@ -58,67 +75,335 @@ FsRtlLookupPerFileObjectContext(IN PFILE_OBJECT FileObject,
IN PVOID OwnerId OPTIONAL,
IN PVOID InstanceId OPTIONAL)
{
- KeBugCheck(FILE_SYSTEM);
- return FALSE;
+ PLIST_ENTRY NextEntry;
+ PFILE_OBJECT_FILTER_CONTEXTS FOContext = NULL;
+ PFSRTL_PER_FILEOBJECT_CONTEXT TmpPerFOContext, PerFOContext = NULL;
+
+ if (!FileObject || !(FOContext = IoGetFileObjectFilterContext(FileObject)))
+ {
+ return NULL;
+ }
+
+ ExAcquireFastMutex(&(FOContext->FilterContextsMutex));
+
+ /* If list is empty, no need to browse it */
+ if (!IsListEmpty(&(FOContext->FilterContexts)))
+ {
+ for (NextEntry = FOContext->FilterContexts.Flink;
+ NextEntry != &(FOContext->FilterContexts);
+ NextEntry = NextEntry->Flink)
+ {
+ /* If we don't have any criteria for search, first entry will be enough */
+ if (!OwnerId && !InstanceId)
+ {
+ PerFOContext = (PFSRTL_PER_FILEOBJECT_CONTEXT)NextEntry;
+ break;
+ }
+ /* Else, we've to find something that matches with the parameters. */
+ else
+ {
+ TmpPerFOContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_FILEOBJECT_CONTEXT, Links);
+ if ((InstanceId && TmpPerFOContext->InstanceId == InstanceId && TmpPerFOContext->OwnerId == OwnerId) ||
+ (OwnerId && TmpPerFOContext->OwnerId == OwnerId))
+ {
+ PerFOContext = TmpPerFOContext;
+ break;
+ }
+ }
+ }
+ }
+
+ ExReleaseFastMutex(&(FOContext->FilterContextsMutex));
+
+ return PerFOContext;
}
/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-FsRtlInsertPerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER PerStreamContext,
- IN PFSRTL_PER_STREAM_CONTEXT Ptr)
-{
- KeBugCheck(FILE_SYSTEM);
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
+ * @implemented
*/
PFSRTL_PER_STREAM_CONTEXT
NTAPI
-FsRtlRemovePerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext,
- IN PVOID OwnerId OPTIONAL,
- IN PVOID InstanceId OPTIONAL)
+FsRtlLookupPerStreamContextInternal(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader,
+ IN PVOID OwnerId OPTIONAL,
+ IN PVOID InstanceId OPTIONAL)
{
- KeBugCheck(FILE_SYSTEM);
- return NULL;
+ PLIST_ENTRY NextEntry;
+ PFSRTL_PER_STREAM_CONTEXT TmpPerStreamContext, PerStreamContext = NULL;
+
+ ASSERT(AdvFcbHeader);
+ ASSERT(FlagOn(AdvFcbHeader->Flags2, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS));
+
+ ExAcquireFastMutex(AdvFcbHeader->FastMutex);
+
+ /* If list is empty, no need to browse it */
+ if (!IsListEmpty(&(AdvFcbHeader->FilterContexts)))
+ {
+ for (NextEntry = AdvFcbHeader->FilterContexts.Flink;
+ NextEntry != &(AdvFcbHeader->FilterContexts);
+ NextEntry = NextEntry->Flink)
+ {
+ /* If we don't have any criteria for search, first entry will be enough */
+ if (!OwnerId && !InstanceId)
+ {
+ PerStreamContext = (PFSRTL_PER_STREAM_CONTEXT)NextEntry;
+ break;
+ }
+ /* Else, we've to find something that matches with the parameters. */
+ else
+ {
+ TmpPerStreamContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_STREAM_CONTEXT, Links);
+ if ((InstanceId && TmpPerStreamContext->InstanceId == InstanceId && TmpPerStreamContext->OwnerId == OwnerId) ||
+ (OwnerId && TmpPerStreamContext->OwnerId == OwnerId))
+ {
+ PerStreamContext = TmpPerStreamContext;
+ break;
+ }
+ }
+ }
+ }
+
+ ExReleaseFastMutex(AdvFcbHeader->FastMutex);
+
+ return PerStreamContext;
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
FsRtlInsertPerFileObjectContext(IN PFILE_OBJECT FileObject,
IN PFSRTL_PER_FILEOBJECT_CONTEXT Ptr)
{
- KeBugCheck(FILE_SYSTEM);
- return STATUS_NOT_IMPLEMENTED;
+ PFILE_OBJECT_FILTER_CONTEXTS FOContext = NULL;
+
+ if (!FileObject)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (!(FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION))
+ {
+ return STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ /* Get filter contexts */
+ FOContext = IoGetFileObjectFilterContext(FileObject);
+ if (!FOContext)
+ {
+ /* If there's none, allocate new structure */
+ FOContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(FILE_OBJECT_FILTER_CONTEXTS), 'FOCX');
+ if (!FOContext)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Initialize it */
+ ExInitializeFastMutex(&(FOContext->FilterContextsMutex));
+ InitializeListHead(&(FOContext->FilterContexts));
+
+ /* Set it */
+ if (!IoChangeFileObjectFilterContext(FileObject, FOContext, TRUE))
+ {
+ /* If it fails, it means that someone else has set it in the meanwhile */
+ ExFreePoolWithTag(FOContext, 'FOCX');
+
+ /* So, we can get it */
+ FOContext = IoGetFileObjectFilterContext(FileObject);
+ if (!FOContext)
+ {
+ /* If we fall down here, something went very bad. This shouldn't happen */
+ ASSERT(FALSE);
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+ }
+
+ /* Finally, insert */
+ ExAcquireFastMutex(&(FOContext->FilterContextsMutex));
+ InsertHeadList(&(FOContext->FilterContexts), &(Ptr->Links));
+ ExReleaseFastMutex(&(FOContext->FilterContextsMutex));
+
+ return STATUS_SUCCESS;
}
/*
- * @unimplemented
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+FsRtlInsertPerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader,
+ IN PFSRTL_PER_STREAM_CONTEXT PerStreamContext)
+{
+ if (!(AdvFcbHeader) || !(AdvFcbHeader->Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS))
+ {
+ return STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ ExAcquireFastMutex(AdvFcbHeader->FastMutex);
+ InsertHeadList(&(AdvFcbHeader->FilterContexts), &(PerStreamContext->Links));
+ ExReleaseFastMutex(AdvFcbHeader->FastMutex);
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
*/
PFSRTL_PER_FILEOBJECT_CONTEXT
NTAPI
-FsRtlRemovePerFileObjectContext(IN PFILE_OBJECT PerFileObjectContext,
+FsRtlRemovePerFileObjectContext(IN PFILE_OBJECT FileObject,
IN PVOID OwnerId OPTIONAL,
IN PVOID InstanceId OPTIONAL)
{
- KeBugCheck(FILE_SYSTEM);
- return NULL;
+ PLIST_ENTRY NextEntry;
+ PFILE_OBJECT_FILTER_CONTEXTS FOContext = NULL;
+ PFSRTL_PER_FILEOBJECT_CONTEXT TmpPerFOContext, PerFOContext = NULL;
+
+ if (!FileObject || !(FOContext = IoGetFileObjectFilterContext(FileObject)))
+ {
+ return NULL;
+ }
+
+ ExAcquireFastMutex(&(FOContext->FilterContextsMutex));
+
+ /* If list is empty, no need to browse it */
+ if (!IsListEmpty(&(FOContext->FilterContexts)))
+ {
+ for (NextEntry = FOContext->FilterContexts.Flink;
+ NextEntry != &(FOContext->FilterContexts);
+ NextEntry = NextEntry->Flink)
+ {
+ /* If we don't have any criteria for search, first entry will be enough */
+ if (!OwnerId && !InstanceId)
+ {
+ PerFOContext = (PFSRTL_PER_FILEOBJECT_CONTEXT)NextEntry;
+ break;
+ }
+ /* Else, we've to find something that matches with the parameters. */
+ else
+ {
+ TmpPerFOContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_FILEOBJECT_CONTEXT, Links);
+ if ((InstanceId && TmpPerFOContext->InstanceId == InstanceId && TmpPerFOContext->OwnerId == OwnerId) ||
+ (OwnerId && TmpPerFOContext->OwnerId == OwnerId))
+ {
+ PerFOContext = TmpPerFOContext;
+ break;
+ }
+ }
+ }
+
+ /* Finally remove entry from list */
+ if (PerFOContext)
+ {
+ RemoveEntryList(&(PerFOContext->Links));
+ }
+ }
+
+ ExReleaseFastMutex(&(FOContext->FilterContextsMutex));
+
+ return PerFOContext;
}
/*
- * @unimplemented
+ * @implemented
+ */
+PFSRTL_PER_STREAM_CONTEXT
+NTAPI
+FsRtlRemovePerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader,
+ IN PVOID OwnerId OPTIONAL,
+ IN PVOID InstanceId OPTIONAL)
+{
+ PLIST_ENTRY NextEntry;
+ PFSRTL_PER_STREAM_CONTEXT TmpPerStreamContext, PerStreamContext = NULL;
+
+ if (!(AdvFcbHeader) || !(AdvFcbHeader->Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS))
+ {
+ return NULL;
+ }
+
+ ExAcquireFastMutex(AdvFcbHeader->FastMutex);
+ /* If list is empty, no need to browse it */
+ if (!IsListEmpty(&(AdvFcbHeader->FilterContexts)))
+ {
+ for (NextEntry = AdvFcbHeader->FilterContexts.Flink;
+ NextEntry != &(AdvFcbHeader->FilterContexts);
+ NextEntry = NextEntry->Flink)
+ {
+ /* If we don't have any criteria for search, first entry will be enough */
+ if (!OwnerId && !InstanceId)
+ {
+ PerStreamContext = (PFSRTL_PER_STREAM_CONTEXT)NextEntry;
+ break;
+ }
+ /* Else, we've to find something that matches with the parameters. */
+ else
+ {
+ TmpPerStreamContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_STREAM_CONTEXT, Links);
+ if ((InstanceId && TmpPerStreamContext->InstanceId == InstanceId && TmpPerStreamContext->OwnerId == OwnerId) ||
+ (OwnerId && TmpPerStreamContext->OwnerId == OwnerId))
+ {
+ PerStreamContext = TmpPerStreamContext;
+ break;
+ }
+ }
+ }
+
+ /* Finally remove entry from list */
+ if (PerStreamContext)
+ {
+ RemoveEntryList(&(PerStreamContext->Links));
+ }
+ }
+ ExReleaseFastMutex(AdvFcbHeader->FastMutex);
+
+ return PerStreamContext;
+
+}
+
+/*
+ * @implemented
*/
VOID
NTAPI
-FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvancedHeader)
+FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader)
{
- KeBugCheck(FILE_SYSTEM);
-}
+ PLIST_ENTRY NextEntry;
+ BOOLEAN IsMutexLocked = FALSE;
+ PFSRTL_PER_STREAM_CONTEXT PerStreamContext;
+ _SEH2_TRY
+ {
+ /* Acquire mutex to deal with the list */
+ ExAcquireFastMutex(AdvFcbHeader->FastMutex);
+ IsMutexLocked = TRUE;
+
+ /* While there are items... */
+ while (!IsListEmpty(&(AdvFcbHeader->FilterContexts)))
+ {
+ /* ...remove one */
+ NextEntry = RemoveHeadList(&(AdvFcbHeader->FilterContexts));
+ PerStreamContext = CONTAINING_RECORD(NextEntry, FSRTL_PER_STREAM_CONTEXT, Links);
+
+ /* Release mutex before calling callback */
+ ExReleaseFastMutex(AdvFcbHeader->FastMutex);
+ IsMutexLocked = FALSE;
+
+ /* Call the callback */
+ ASSERT(PerStreamContext->FreeCallback);
+ (*PerStreamContext->FreeCallback)(PerStreamContext);
+
+ /* Relock the list to continue */
+ ExAcquireFastMutex(AdvFcbHeader->FastMutex);
+ IsMutexLocked = TRUE;
+ }
+ }
+ _SEH2_FINALLY
+ {
+ /* If mutex was locked, release */
+ if (IsMutexLocked)
+ {
+ ExReleaseFastMutex(AdvFcbHeader->FastMutex);
+ }
+ }
+ _SEH2_END;
+}
diff --git a/ntoskrnl/fsrtl/fsrtlpc.c b/ntoskrnl/fsrtl/fsrtlpc.c
index 9e018e44e20..6c59f4f691f 100644
--- a/ntoskrnl/fsrtl/fsrtlpc.c
+++ b/ntoskrnl/fsrtl/fsrtlpc.c
@@ -155,6 +155,7 @@ PUCHAR FsRtlLegalAnsiCharacterArray = LegalAnsiCharacterArray;
BOOLEAN
NTAPI
+INIT_FUNCTION
FsRtlInitSystem(VOID)
{
ULONG i;
diff --git a/ntoskrnl/fsrtl/name.c b/ntoskrnl/fsrtl/name.c
index 1405b9f99c4..291ecf7f12a 100644
--- a/ntoskrnl/fsrtl/name.c
+++ b/ntoskrnl/fsrtl/name.c
@@ -23,8 +23,9 @@ FsRtlIsNameInExpressionPrivate(IN PUNICODE_STRING Expression,
IN PWCHAR UpcaseTable OPTIONAL)
{
ULONG i = 0, j, k = 0;
+ PAGED_CODE();
- ASSERT(!FsRtlDoesNameContainWildCards(Name));
+ ASSERT(!IgnoreCase || UpcaseTable);
while (i < Name->Length / sizeof(WCHAR) && k < Expression->Length / sizeof(WCHAR))
{
@@ -119,6 +120,7 @@ FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1,
BOOLEAN StringsAreEqual, MemoryAllocated = FALSE;
ULONG i;
NTSTATUS Status;
+ PAGED_CODE();
/* Well, first check their size */
if (Name1->Length != Name2->Length) return FALSE;
@@ -210,6 +212,7 @@ FsRtlDissectName(IN UNICODE_STRING Name,
{
ULONG FirstPosition, i;
ULONG SkipFirstSlash = 0;
+ PAGED_CODE();
/* Zero the strings before continuing */
RtlZeroMemory(FirstPart, sizeof(UNICODE_STRING));
@@ -272,6 +275,7 @@ NTAPI
FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
{
PWCHAR Ptr;
+ PAGED_CODE();
/* Loop through every character */
if (Name->Length)
diff --git a/ntoskrnl/fstub/fstubex.c b/ntoskrnl/fstub/fstubex.c
index d04c29923e6..51b8ea48b52 100644
--- a/ntoskrnl/fstub/fstubex.c
+++ b/ntoskrnl/fstub/fstubex.c
@@ -14,9 +14,6 @@
/* PRIVATE FUNCTIONS *********************************************************/
-#define PARTITION_ENTRY_SIZE 128
-#define TAG_FSTUB 'BtsF'
-
typedef struct _DISK_INFORMATION
{
PDEVICE_OBJECT DeviceObject;
@@ -26,6 +23,88 @@ typedef struct _DISK_INFORMATION
ULONGLONG SectorCount;
} DISK_INFORMATION, *PDISK_INFORMATION;
+#include
+typedef struct _EFI_PARTITION_HEADER
+{
+ ULONGLONG Signature; // 0
+ ULONG Revision; // 8
+ ULONG HeaderSize; // 12
+ ULONG HeaderCRC32; // 16
+ ULONG Reserved; // 20
+ ULONGLONG MyLBA; // 24
+ ULONGLONG AlternateLBA; // 32
+ ULONGLONG FirstUsableLBA; // 40
+ ULONGLONG LastUsableLBA; // 48
+ GUID DiskGUID; // 56
+ ULONGLONG PartitionEntryLBA; // 72
+ ULONG NumberOfEntries; // 80
+ ULONG SizeOfPartitionEntry; // 84
+ ULONG PartitionEntryCRC32; // 88
+} EFI_PARTITION_HEADER, *PEFI_PARTITION_HEADER;
+#include
+
+typedef struct _EFI_PARTITION_ENTRY
+{
+ GUID PartitionType; // 0
+ GUID UniquePartition; // 16
+ ULONGLONG StartingLBA; // 32
+ ULONGLONG EndingLBA; // 40
+ ULONGLONG Attributes; // 48
+ WCHAR Name[0x24]; // 56
+} EFI_PARTITION_ENTRY, *PEFI_PARTITION_ENTRY;
+
+typedef struct _CREATE_DISK_MBR
+{
+ ULONG Signature;
+} CREATE_DISK_MBR, *PCREATE_DISK_MBR;
+
+typedef struct _CREATE_DISK_GPT
+{
+ GUID DiskId;
+ ULONG MaxPartitionCount;
+} CREATE_DISK_GPT, *PCREATE_DISK_GPT;
+
+typedef struct _CREATE_DISK
+{
+ PARTITION_STYLE PartitionStyle;
+ union
+ {
+ CREATE_DISK_MBR Mbr;
+ CREATE_DISK_GPT Gpt;
+ };
+} CREATE_DISK, *PCREATE_DISK;
+
+typedef struct _PARTITION_TABLE_ENTRY
+{
+ UCHAR BootIndicator;
+ UCHAR StartHead;
+ UCHAR StartSector;
+ UCHAR StartCylinder;
+ UCHAR SystemIndicator;
+ UCHAR EndHead;
+ UCHAR EndSector;
+ UCHAR EndCylinder;
+ ULONG SectorCountBeforePartition;
+ ULONG PartitionSectorCount;
+} PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
+
+typedef struct _MASTER_BOOT_RECORD
+{
+ UCHAR MasterBootRecordCodeAndData[0x1B8]; // 0
+ ULONG Signature; // 440
+ USHORT Reserved; // 444
+ PARTITION_TABLE_ENTRY PartitionTable[4]; // 446
+ USHORT MasterBootRecordMagic; // 510
+} MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
+
+/* Tag for Fstub allocations */
+#define TAG_FSTUB 'BtsF'
+/* Partition entry size (bytes) - FIXME: It's hardcoded as Microsoft does, but according to specs, it shouldn't be */
+#define PARTITION_ENTRY_SIZE 128
+/* Defines "EFI PART" */
+#define EFI_HEADER_SIGNATURE 0x5452415020494645ULL
+/* Defines version 1.0 */
+#define EFI_HEADER_REVISION_1 0x00010000
/* Defines system type for MBR showing that a GPT is following */
#define EFI_PMBR_OSTYPE_EFI 0xEE
@@ -42,6 +121,17 @@ FstubDbgPrintPartitionEx(IN PPARTITION_INFORMATION_EX PartitionEntry,
IN ULONG PartitionNumber
);
+NTSTATUS
+NTAPI
+FstubDetectPartitionStyle(IN PDISK_INFORMATION Disk,
+ IN PARTITION_STYLE * PartitionStyle
+);
+
+VOID
+NTAPI
+FstubFreeDiskInformation(IN PDISK_INFORMATION DiskBuffer
+);
+
NTSTATUS
NTAPI
FstubGetDiskGeometry(IN PDEVICE_OBJECT DeviceObject,
@@ -56,6 +146,67 @@ FstubReadSector(IN PDEVICE_OBJECT DeviceObject,
OUT PUSHORT Buffer
);
+NTSTATUS
+NTAPI
+FstubWriteBootSectorEFI(IN PDISK_INFORMATION Disk
+);
+
+NTSTATUS
+NTAPI
+FstubWritePartitionTableEFI(IN PDISK_INFORMATION Disk,
+ IN GUID DiskGUID,
+ IN ULONG MaxPartitionCount,
+ IN ULONGLONG FirstUsableLBA,
+ IN ULONGLONG LastUsableLBA,
+ IN BOOLEAN WriteBackupTable,
+ IN ULONG PartitionCount,
+ IN PPARTITION_INFORMATION_EX PartitionEntries OPTIONAL
+);
+
+NTSTATUS
+NTAPI
+FstubWriteSector(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN ULONGLONG StartingSector OPTIONAL,
+ IN PUSHORT Buffer
+);
+
+VOID
+NTAPI
+FstubAdjustPartitionCount(IN ULONG SectorSize,
+ IN OUT PULONG PartitionCount)
+{
+ ULONG Count;
+ PAGED_CODE();
+
+ ASSERT(SectorSize);
+ ASSERT(PartitionCount);
+
+ /* Get partition count */
+ Count = *PartitionCount;
+ /* We need at least 128 entries */
+ if (Count < 128)
+ {
+ Count = 128;
+ }
+
+ /* Then, ensure that we will have a round value,
+ * ie, all sectors will be full of entries
+ * There won't be lonely entries
+ */
+ Count = (Count * PARTITION_ENTRY_SIZE) / SectorSize;
+ Count = (Count * SectorSize) / PARTITION_ENTRY_SIZE;
+ ASSERT(*PartitionCount <= Count);
+ /* Return result */
+ *PartitionCount = Count;
+
+ /* One more sanity check */
+ if (SectorSize == 512)
+ {
+ ASSERT(Count % 4 == 0);
+ }
+}
+
NTSTATUS
NTAPI
FstubAllocateDiskInformation(IN PDEVICE_OBJECT DeviceObject,
@@ -118,6 +269,265 @@ FstubAllocateDiskInformation(IN PDEVICE_OBJECT DeviceObject,
return STATUS_SUCCESS;
}
+PDRIVE_LAYOUT_INFORMATION
+NTAPI
+FstubConvertExtendedToLayout(IN PDRIVE_LAYOUT_INFORMATION_EX LayoutEx)
+{
+ ULONG i;
+ PDRIVE_LAYOUT_INFORMATION DriveLayout;
+ PAGED_CODE();
+
+ ASSERT(LayoutEx);
+
+ /* Check whether we're dealing with MBR partition table */
+ if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR)
+ {
+ ASSERT(FALSE);
+ return NULL;
+ }
+
+ /* Allocate needed buffer */
+ DriveLayout = ExAllocatePoolWithTag(NonPagedPool,
+ FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry) +
+ LayoutEx->PartitionCount * sizeof(PARTITION_INFORMATION),
+ 'BtsF');
+ if (!DriveLayout)
+ {
+ return NULL;
+ }
+
+ /* Convert information about partition table */
+ DriveLayout->PartitionCount = LayoutEx->PartitionCount;
+ DriveLayout->Signature = LayoutEx->Mbr.Signature;
+
+ /* Convert each partition */
+ for (i = 0; i < LayoutEx->PartitionCount; i++)
+ {
+ DriveLayout->PartitionEntry[i].StartingOffset = LayoutEx->PartitionEntry[i].StartingOffset;
+ DriveLayout->PartitionEntry[i].PartitionLength = LayoutEx->PartitionEntry[i].PartitionLength;
+ DriveLayout->PartitionEntry[i].HiddenSectors = LayoutEx->PartitionEntry[i].Mbr.HiddenSectors;
+ DriveLayout->PartitionEntry[i].PartitionNumber = LayoutEx->PartitionEntry[i].PartitionNumber;
+ DriveLayout->PartitionEntry[i].PartitionType = LayoutEx->PartitionEntry[i].Mbr.PartitionType;
+ DriveLayout->PartitionEntry[i].BootIndicator = LayoutEx->PartitionEntry[i].Mbr.BootIndicator;
+ DriveLayout->PartitionEntry[i].RecognizedPartition = LayoutEx->PartitionEntry[i].Mbr.RecognizedPartition;
+ DriveLayout->PartitionEntry[i].RewritePartition = LayoutEx->PartitionEntry[i].RewritePartition;
+ }
+
+ return DriveLayout;
+}
+
+VOID
+NTAPI
+FstubCopyEntryEFI(OUT PEFI_PARTITION_ENTRY Entry,
+ IN PPARTITION_INFORMATION_EX Partition,
+ ULONG SectorSize)
+{
+ PAGED_CODE();
+
+ ASSERT(Entry);
+ ASSERT(Partition);
+ ASSERT(SectorSize);
+
+ /* Just convert data to EFI partition entry type */
+ Entry->PartitionType = Partition->Gpt.PartitionType;
+ Entry->UniquePartition = Partition->Gpt.PartitionId;
+ Entry->StartingLBA = Partition->StartingOffset.QuadPart / SectorSize;
+ Entry->EndingLBA = (Partition->StartingOffset.QuadPart + Partition->PartitionLength.QuadPart - 1) / SectorSize;
+ Entry->Attributes = Partition->Gpt.Attributes;
+ RtlCopyMemory(Entry->Name, Partition->Gpt.Name, sizeof(Entry->Name));
+}
+
+NTSTATUS
+NTAPI
+FstubCreateDiskMBR(IN PDEVICE_OBJECT DeviceObject,
+ IN PCREATE_DISK_MBR DiskInfo)
+{
+ NTSTATUS Status;
+ PDISK_INFORMATION Disk = NULL;
+ PMASTER_BOOT_RECORD MasterBootRecord;
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+
+ /* Allocate internal structure */
+ Status = FstubAllocateDiskInformation(DeviceObject, &Disk, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Read previous MBR, if any */
+ Status = FstubReadSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ 0ULL,
+ Disk->Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ FstubFreeDiskInformation(Disk);
+ return Status;
+ }
+ /* Fill the buffer with needed information, we won't overwrite boot code */
+ MasterBootRecord = (PMASTER_BOOT_RECORD)Disk->Buffer;
+ MasterBootRecord->Signature = DiskInfo->Signature;
+ RtlZeroMemory(MasterBootRecord->PartitionTable, sizeof(PARTITION_TABLE_ENTRY) * 4);
+ MasterBootRecord->MasterBootRecordMagic = BOOT_RECORD_SIGNATURE;
+
+ /* Finally, write MBR */
+ Status = FstubWriteSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ 0ULL,
+ Disk->Buffer);
+
+ /* Release internal structure and return */
+ FstubFreeDiskInformation(Disk);
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+FstubCreateDiskEFI(IN PDEVICE_OBJECT DeviceObject,
+ IN PCREATE_DISK_GPT DiskInfo)
+{
+ NTSTATUS Status;
+ PDISK_INFORMATION Disk = NULL;
+ ULONGLONG FirstUsableLBA, LastUsableLBA;
+ ULONG MaxPartitionCount, SectorsForPartitions;
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+ ASSERT(DiskInfo);
+
+ /* Allocate internal structure */
+ Status = FstubAllocateDiskInformation(DeviceObject, &Disk, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ ASSERT(Disk);
+
+ /* Write legacy MBR */
+ Status = FstubWriteBootSectorEFI(Disk);
+ if (!NT_SUCCESS(Status))
+ {
+ FstubFreeDiskInformation(Disk);
+ return Status;
+ }
+
+ /* Get max entries and adjust its number */
+ MaxPartitionCount = DiskInfo->MaxPartitionCount;
+ FstubAdjustPartitionCount(Disk->SectorSize, &MaxPartitionCount);
+
+ /* Count number of sectors needed to store partitions */
+ SectorsForPartitions = (MaxPartitionCount * PARTITION_ENTRY_SIZE) / Disk->SectorSize;
+ /* Set first usable LBA: Legacy MBR + GPT header + Partitions entries */
+ FirstUsableLBA = SectorsForPartitions + 2;
+ /* Set last usable LBA: Last sector - GPT header - Partitions entries */
+ LastUsableLBA = Disk->SectorCount - SectorsForPartitions - 1;
+
+ /* First, write primary table */
+ Status = FstubWritePartitionTableEFI(Disk,
+ DiskInfo->DiskId,
+ MaxPartitionCount,
+ FirstUsableLBA,
+ LastUsableLBA,
+ FALSE,
+ 0,
+ NULL);
+ /* Then, write backup table */
+ if (NT_SUCCESS(Status))
+ {
+ Status = FstubWritePartitionTableEFI(Disk,
+ DiskInfo->DiskId,
+ MaxPartitionCount,
+ FirstUsableLBA,
+ LastUsableLBA,
+ TRUE,
+ 0,
+ NULL);
+ }
+
+ /* Release internal structure and return */
+ FstubFreeDiskInformation(Disk);
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+FstubCreateDiskRaw(IN PDEVICE_OBJECT DeviceObject)
+{
+ NTSTATUS Status;
+ PDISK_INFORMATION Disk = NULL;
+ PARTITION_STYLE PartitionStyle;
+ PMASTER_BOOT_RECORD MasterBootRecord;
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+
+ /* Allocate internal structure */
+ Status = FstubAllocateDiskInformation(DeviceObject, &Disk, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Detect current disk partition style */
+ Status = FstubDetectPartitionStyle(Disk, &PartitionStyle);
+ if (!NT_SUCCESS(Status))
+ {
+ FstubFreeDiskInformation(Disk);
+ return Status;
+ }
+
+ /* Read MBR, if any */
+ Status = FstubReadSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ 0ULL,
+ Disk->Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ FstubFreeDiskInformation(Disk);
+ return Status;
+ }
+
+ /* Only zero useful stuff */
+ MasterBootRecord = (PMASTER_BOOT_RECORD)Disk->Buffer;
+ MasterBootRecord->Signature = 0;
+ RtlZeroMemory(MasterBootRecord->PartitionTable, sizeof(PARTITION_TABLE_ENTRY));
+ MasterBootRecord->MasterBootRecordMagic = 0;
+
+ /* Write back that destroyed MBR */
+ Status = FstubWriteSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ 0ULL,
+ Disk->Buffer);
+ /* If previous style wasn't GPT, we're done here */
+ if (PartitionStyle != PARTITION_STYLE_GPT)
+ {
+ FstubFreeDiskInformation(Disk);
+ return Status;
+ }
+
+ /* Otherwise, we've to zero the two GPT headers */
+ RtlZeroMemory(Disk->Buffer, Disk->SectorSize);
+ /* Erase primary header */
+ Status = FstubWriteSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ 1ULL,
+ Disk->Buffer);
+ /* In case of success, erase backup header */
+ if (NT_SUCCESS(Status))
+ {
+ Status = FstubWriteSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ Disk->SectorCount - 1ULL,
+ Disk->Buffer);
+ }
+
+ /* Release internal structure and return */
+ FstubFreeDiskInformation(Disk);
+ return Status;
+}
+
PCHAR
NTAPI
FstubDbgGuidToString(IN PGUID Guid,
@@ -220,6 +630,36 @@ FstubDbgPrintPartitionEx(IN PPARTITION_INFORMATION_EX PartitionEntry,
}
}
+VOID
+NTAPI
+FstubDbgPrintSetPartitionEx(IN PSET_PARTITION_INFORMATION_EX PartitionEntry,
+ IN ULONG PartitionNumber)
+{
+ CHAR Guid[38];
+ PAGED_CODE();
+
+ DPRINT1("FSTUB: SET_PARTITION_INFORMATION_EX: %p\n", PartitionEntry);
+ DPRINT1("Modifying partition %ld\n", PartitionNumber);
+ switch (PartitionEntry->PartitionStyle)
+ {
+ case PARTITION_STYLE_MBR:
+ DPRINT1(" PartitionType: %02x\n", PartitionEntry->Mbr.PartitionType);
+
+ break;
+ case PARTITION_STYLE_GPT:
+ FstubDbgGuidToString(&(PartitionEntry->Gpt.PartitionType), Guid);
+ DPRINT1(" PartitionType: %s\n", Guid);
+ FstubDbgGuidToString(&(PartitionEntry->Gpt.PartitionId), Guid);
+ DPRINT1(" PartitionId: %s\n", Guid);
+ DPRINT1(" Attributes: %16x\n", PartitionEntry->Gpt.Attributes);
+ DPRINT1(" Name: %ws\n", PartitionEntry->Gpt.Name);
+
+ break;
+ default:
+ DPRINT1(" Unsupported partition style: %ld\n", PartitionEntry[PartitionNumber].PartitionStyle);
+ }
+}
+
NTSTATUS
NTAPI
FstubDetectPartitionStyle(IN PDISK_INFORMATION Disk,
@@ -374,14 +814,281 @@ Cleanup:
return Status;
}
+NTSTATUS
+NTAPI
+FstubReadHeaderEFI(IN PDISK_INFORMATION Disk,
+ IN BOOLEAN ReadBackupTable,
+ PEFI_PARTITION_HEADER HeaderBuffer)
+{
+ NTSTATUS Status;
+ PUCHAR Sector = NULL;
+ ULONGLONG StartingSector;
+ PEFI_PARTITION_HEADER EFIHeader;
+ ULONG i, HeaderCRC32, PreviousCRC32, SectoredPartitionEntriesSize, LonelyPartitions;
+ PAGED_CODE();
+
+ ASSERT(Disk);
+ ASSERT(IS_VALID_DISK_INFO(Disk));
+ ASSERT(HeaderBuffer);
+
+ /* In case we want to read backup table, we read last disk sector */
+ if (ReadBackupTable)
+ {
+ StartingSector = Disk->SectorCount - 1ULL;
+ }
+ else
+ {
+ /* Otherwise we start at first sector (as sector 0 is the MBR) */
+ StartingSector = 1ULL;
+ }
+
+ Status = FstubReadSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ StartingSector,
+ Disk->Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("EFI::Failed reading header!\n");
+ return Status;
+ }
+ /* Let's use read buffer as EFI_PARTITION_HEADER */
+ EFIHeader = (PEFI_PARTITION_HEADER)Disk->Buffer;
+
+
+ /* First check signature
+ * Then, check version (we only support v1)
+ * Finally check header size
+ */
+ if (EFIHeader->Signature != EFI_HEADER_SIGNATURE ||
+ EFIHeader->Revision != EFI_HEADER_REVISION_1 ||
+ EFIHeader->HeaderSize != sizeof(EFI_PARTITION_HEADER))
+ {
+ DPRINT("EFI::Wrong signature/version/header size!\n");
+ DPRINT("%I64x (expected: %I64x)\n", EFIHeader->Signature, EFI_HEADER_SIGNATURE);
+ DPRINT("%03x (expected: %03x)\n", EFIHeader->Revision, EFI_HEADER_REVISION_1);
+ DPRINT("%02x (expected: %02x)\n", EFIHeader->HeaderSize, sizeof(EFI_PARTITION_HEADER));
+ return STATUS_DISK_CORRUPT_ERROR;
+ }
+
+ /* Save current checksum */
+ HeaderCRC32 = EFIHeader->HeaderCRC32;
+ /* Then zero the one in EFI header. This is needed to compute header checksum */
+ EFIHeader->HeaderCRC32 = 0;
+ /* Compute header checksum and compare with the one present in partition table */
+ if (RtlComputeCrc32(0, (PUCHAR)Disk->Buffer, sizeof(EFI_PARTITION_HEADER)) != HeaderCRC32)
+ {
+ DPRINT("EFI::Not matching header checksum!\n");
+ return STATUS_DISK_CORRUPT_ERROR;
+ }
+ /* Put back removed checksum in header */
+ EFIHeader->HeaderCRC32 = HeaderCRC32;
+
+ /* Check if current LBA is matching with ours */
+ if (EFIHeader->MyLBA != StartingSector)
+ {
+ DPRINT("EFI::Not matching starting sector!\n");
+ return STATUS_DISK_CORRUPT_ERROR;
+ }
+
+ /* Allocate a buffer to read a sector on the disk */
+ Sector = ExAllocatePoolWithTag(NonPagedPool,
+ Disk->SectorSize,
+ 'BtsF');
+ if (!Sector)
+ {
+ DPRINT("EFI::Lacking resources!\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Count how much sectors we'll have to read to read the whole partition table */
+ SectoredPartitionEntriesSize = (EFIHeader->NumberOfEntries * PARTITION_ENTRY_SIZE) / Disk->SectorSize;
+ /* Compute partition table checksum */
+ for (i = 0, PreviousCRC32 = 0; i < SectoredPartitionEntriesSize; i++)
+ {
+ Status = FstubReadSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ EFIHeader->PartitionEntryLBA + i,
+ (PUSHORT)Sector);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Sector, 'BtsF');
+ DPRINT("EFI::Failed reading sector for partition entry!\n");
+ return Status;
+ }
+
+ PreviousCRC32 = RtlComputeCrc32(PreviousCRC32, Sector, Disk->SectorSize);
+ }
+
+ /* Check whether we have a last sector not full of partitions */
+ LonelyPartitions = (EFIHeader->NumberOfEntries * PARTITION_ENTRY_SIZE) % Disk->SectorSize;
+ /* In such case, we have to complete checksum computation */
+ if (LonelyPartitions != 0)
+ {
+ /* Read the sector that contains those partitions */
+ Status = FstubReadSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ EFIHeader->PartitionEntryLBA + i,
+ (PUSHORT)Sector);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Sector, 'BtsF');
+ DPRINT("EFI::Failed reading sector for partition entry!\n");
+ return Status;
+ }
+
+ /* Then complete checksum by computing on each partition */
+ for (i = 0; i < LonelyPartitions; i++)
+ {
+ PreviousCRC32 = RtlComputeCrc32(PreviousCRC32, Sector + i * PARTITION_ENTRY_SIZE, PARTITION_ENTRY_SIZE);
+ }
+ }
+
+ /* Finally, release memory */
+ ExFreePoolWithTag(Sector, 'BtsF');
+
+ /* Compare checksums */
+ if (PreviousCRC32 == EFIHeader->PartitionEntryCRC32)
+ {
+ /* In case of a success, return read header */
+ *HeaderBuffer = *EFIHeader;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ DPRINT("EFI::Not matching partition table checksum!\n");
+ DPRINT("EFI::Expected: %x, received: %x\n", EFIHeader->PartitionEntryCRC32, PreviousCRC32);
+ return STATUS_DISK_CORRUPT_ERROR;
+ }
+}
+
NTSTATUS
NTAPI
FstubReadPartitionTableEFI(IN PDISK_INFORMATION Disk,
IN BOOLEAN ReadBackupTable,
OUT struct _DRIVE_LAYOUT_INFORMATION_EX** DriveLayout)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ EFI_PARTITION_HEADER EfiHeader;
+ ULONGLONG SectorsForPartitions;
+ EFI_PARTITION_ENTRY PartitionEntry;
+ BOOLEAN UpdatedPartitionTable = FALSE;
+ PDRIVE_LAYOUT_INFORMATION_EX DriveLayoutEx = NULL;
+ ULONG i, PartitionCount, PartitionIndex, PartitionsPerSector;
+ PAGED_CODE();
+
+ ASSERT(Disk);
+
+ /* Zero output */
+ *DriveLayout = NULL;
+
+ /* Read EFI header */
+ Status = FstubReadHeaderEFI(Disk,
+ ReadBackupTable,
+ &EfiHeader);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Allocate a DRIVE_LAYOUT_INFORMATION_EX struct big enough */
+ DriveLayoutEx = ExAllocatePoolWithTag(NonPagedPool,
+ FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry) +
+ EfiHeader.NumberOfEntries * sizeof(PARTITION_INFORMATION_EX),
+ TAG_FSTUB);
+ if (!DriveLayoutEx)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (ReadBackupTable)
+ {
+ /* If we read backup but if it doesn't match with current geometry */
+ if ((Disk->SectorCount - 1ULL) != EfiHeader.AlternateLBA)
+ {
+ /* We'll update it. First, count number of sectors needed to store partitions */
+ SectorsForPartitions = (EfiHeader.NumberOfEntries * PARTITION_ENTRY_SIZE) / Disk->SectorSize;
+ /* Then set first usable LBA: Legacy MBR + GPT header + Partitions entries */
+ EfiHeader.FirstUsableLBA = SectorsForPartitions + 2;
+ /* Then set last usable LBA: Last sector - GPT header - Partitions entries */
+ EfiHeader.LastUsableLBA = Disk->SectorCount - SectorsForPartitions - 1;
+ /* Inform that we'll rewrite partition table */
+ UpdatedPartitionTable = TRUE;
+ }
+ }
+
+ DriveLayoutEx->PartitionStyle = PARTITION_STYLE_GPT;
+ /* Translate LBA -> Offset */
+ DriveLayoutEx->Gpt.StartingUsableOffset.QuadPart = EfiHeader.FirstUsableLBA * Disk->SectorSize;
+ DriveLayoutEx->Gpt.UsableLength.QuadPart = EfiHeader.LastUsableLBA - EfiHeader.FirstUsableLBA * Disk->SectorSize;
+ DriveLayoutEx->Gpt.MaxPartitionCount = EfiHeader.NumberOfEntries;
+ DriveLayoutEx->Gpt.DiskId = EfiHeader.DiskGUID;
+
+ /* Count number of partitions per sector */
+ PartitionsPerSector = (Disk->SectorSize / PARTITION_ENTRY_SIZE);
+ /* Read all partitions and fill in structure */
+ for (i = 0, PartitionCount = 0, PartitionIndex = PartitionsPerSector;
+ i < EfiHeader.NumberOfEntries;
+ i++)
+ {
+ /* Only read following sector if we finished with previous sector */
+ if (PartitionIndex == PartitionsPerSector)
+ {
+ Status = FstubReadSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ EfiHeader.PartitionEntryLBA + (i / PartitionsPerSector),
+ Disk->Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(DriveLayoutEx, TAG_FSTUB);
+ return Status;
+ }
+
+ PartitionIndex = 0;
+ }
+ /* Read following partition */
+ PartitionEntry = ((PEFI_PARTITION_ENTRY)Disk->Buffer)[PartitionIndex];
+ PartitionIndex++;
+
+ /* If partition GUID is 00000000-0000-0000-0000-000000000000, then it's unused, skip it */
+ if (PartitionEntry.PartitionType.Data1 == 0 &&
+ PartitionEntry.PartitionType.Data2 == 0 &&
+ PartitionEntry.PartitionType.Data3 == 0 &&
+ ((PULONGLONG)PartitionEntry.PartitionType.Data4)[0] == 0)
+ {
+ continue;
+ }
+
+ /* Write data to structure. Don't forget GPT is using sectors, Windows offsets */
+ DriveLayoutEx->PartitionEntry[PartitionCount].StartingOffset.QuadPart = PartitionEntry.StartingLBA * Disk->SectorSize;
+ DriveLayoutEx->PartitionEntry[PartitionCount].PartitionLength.QuadPart = (PartitionEntry.EndingLBA -
+ PartitionEntry.StartingLBA + 1) *
+ Disk->SectorSize;
+ /* This number starts from 1 */
+ DriveLayoutEx->PartitionEntry[PartitionCount].PartitionNumber = PartitionCount + 1;
+ DriveLayoutEx->PartitionEntry[PartitionCount].RewritePartition = FALSE;
+ DriveLayoutEx->PartitionEntry[PartitionCount].PartitionStyle = PARTITION_STYLE_GPT;
+ DriveLayoutEx->PartitionEntry[PartitionCount].Gpt.PartitionType = PartitionEntry.PartitionType;
+ DriveLayoutEx->PartitionEntry[PartitionCount].Gpt.PartitionId = PartitionEntry.UniquePartition;
+ DriveLayoutEx->PartitionEntry[PartitionCount].Gpt.Attributes = PartitionEntry.Attributes;
+ RtlCopyMemory(DriveLayoutEx->PartitionEntry[PartitionCount].Gpt.Name,
+ PartitionEntry.Name, sizeof(PartitionEntry.Name));
+
+ /* Update partition count */
+ PartitionCount++;
+ }
+ DriveLayoutEx->PartitionCount = PartitionCount;
+
+ /* If we updated partition table using backup table, rewrite partition table */
+ if (UpdatedPartitionTable)
+ {
+ IoWritePartitionTableEx(Disk->DeviceObject,
+ DriveLayoutEx);
+ }
+
+ /* Finally, return read data */
+ *DriveLayout = DriveLayoutEx;
+
+ return Status;
}
NTSTATUS
@@ -503,34 +1210,843 @@ FstubReadSector(IN PDEVICE_OBJECT DeviceObject,
return Status;
}
+NTSTATUS
+NTAPI
+FstubSetPartitionInformationEFI(IN PDISK_INFORMATION Disk,
+ IN ULONG PartitionNumber,
+ IN SET_PARTITION_INFORMATION_GPT * PartitionInfo)
+{
+ NTSTATUS Status;
+ PDRIVE_LAYOUT_INFORMATION_EX Layout = NULL;
+ PAGED_CODE();
+
+ ASSERT(Disk);
+ ASSERT(PartitionInfo);
+
+ /* Partition 0 isn't correct (should start at 1) */
+ if (PartitionNumber == 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Read partition table */
+ Status = IoReadPartitionTableEx(Disk->DeviceObject, &Layout);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ ASSERT(Layout);
+
+ /* If our partition (started at 0 now) is higher than partition count, then, there's an issue */
+ if (Layout->PartitionCount <= --PartitionNumber)
+ {
+ ExFreePool(Layout);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Erase actual partition entry data with provided ones */
+ Layout->PartitionEntry[PartitionNumber].Gpt.PartitionType = PartitionInfo->PartitionType;
+ Layout->PartitionEntry[PartitionNumber].Gpt.PartitionId = PartitionInfo->PartitionId;
+ Layout->PartitionEntry[PartitionNumber].Gpt.Attributes = PartitionInfo->Attributes;
+ RtlCopyMemory(Layout->PartitionEntry[PartitionNumber].Gpt.Name, PartitionInfo->Name, sizeof(PartitionInfo->Name));
+
+ /* Rewrite the whole partition table to update the modified entry */
+ Status = IoWritePartitionTableEx(Disk->DeviceObject, Layout);
+
+ /* Free partition table and return */
+ ExFreePool(Layout);
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+FstubVerifyPartitionTableEFI(IN PDISK_INFORMATION Disk,
+ IN BOOLEAN FixErrors)
+{
+ NTSTATUS Status;
+ PEFI_PARTITION_HEADER EFIHeader;
+ EFI_PARTITION_HEADER ReadEFIHeader;
+ BOOLEAN PrimaryValid = FALSE, BackupValid = FALSE;
+ PAGED_CODE();
+
+ EFIHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(EFI_PARTITION_HEADER), TAG_FSTUB);
+ if (!EFIHeader)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = FstubReadHeaderEFI(Disk, FALSE, &ReadEFIHeader);
+ if (NT_SUCCESS(Status))
+ {
+ PrimaryValid = TRUE;
+ }
+
+ Status = FstubReadHeaderEFI(Disk, TRUE, &ReadEFIHeader);
+ if (NT_SUCCESS(Status))
+ {
+ BackupValid = TRUE;
+ }
+
+ if (!PrimaryValid)
+ {
+ if (!BackupValid || !FixErrors)
+ {
+ ExFreePoolWithTag(EFIHeader, TAG_FSTUB);
+ return STATUS_DISK_CORRUPT_ERROR;
+ }
+
+ DPRINT1("EFI::Partition table fixing not yet supported!\n");
+ ExFreePoolWithTag(EFIHeader, TAG_FSTUB);
+ return STATUS_NOT_IMPLEMENTED;
+ }
+ else if (!BackupValid)
+ {
+ if (!PrimaryValid || !FixErrors)
+ {
+ ExFreePoolWithTag(EFIHeader, TAG_FSTUB);
+ return STATUS_DISK_CORRUPT_ERROR;
+ }
+
+ DPRINT1("EFI::Partition table fixing not yet supported!\n");
+ ExFreePoolWithTag(EFIHeader, TAG_FSTUB);
+ return STATUS_NOT_IMPLEMENTED;
+ }
+ else
+ {
+ ExFreePoolWithTag(EFIHeader, TAG_FSTUB);
+ return STATUS_SUCCESS;
+ }
+}
+
+NTSTATUS
+NTAPI
+FstubWriteBootSectorEFI(IN PDISK_INFORMATION Disk)
+{
+ NTSTATUS Status;
+ ULONG Signature = 0;
+ PMASTER_BOOT_RECORD MasterBootRecord;
+ PAGED_CODE();
+
+ ASSERT(Disk);
+ ASSERT(IS_VALID_DISK_INFO(Disk));
+
+ /* Read if a MBR is already present */
+ Status = FstubReadSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ 0ULL,
+ Disk->Buffer);
+ MasterBootRecord = (PMASTER_BOOT_RECORD)Disk->Buffer;
+ /* If one has been found */
+ if (NT_SUCCESS(Status) && MasterBootRecord->MasterBootRecordMagic == BOOT_RECORD_SIGNATURE)
+ {
+ /* Save its signature */
+ Signature = MasterBootRecord->Signature;
+ }
+
+ /* Reset the MBR */
+ RtlZeroMemory(MasterBootRecord, Disk->SectorSize);
+ /* Then create a fake MBR matching those purposes:
+ * It must have only partition. Type of this partition
+ * has to be 0xEE to signal a GPT is following.
+ * This partition has to cover the whole disk. To prevent
+ * any disk modification by a program that wouldn't
+ * understand anything to GPT.
+ */
+ MasterBootRecord->Signature = Signature;
+ MasterBootRecord->PartitionTable[0].StartSector = 2;
+ MasterBootRecord->PartitionTable[0].SystemIndicator = EFI_PMBR_OSTYPE_EFI;
+ MasterBootRecord->PartitionTable[0].EndHead = 0xFF;
+ MasterBootRecord->PartitionTable[0].EndSector = 0xFF;
+ MasterBootRecord->PartitionTable[0].EndCylinder = 0xFF;
+ MasterBootRecord->PartitionTable[0].SectorCountBeforePartition = 1;
+ MasterBootRecord->PartitionTable[0].PartitionSectorCount = 0xFFFFFFFF;
+ MasterBootRecord->MasterBootRecordMagic = BOOT_RECORD_SIGNATURE;
+
+ /* Finally, write that MBR */
+ return FstubWriteSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ 0,
+ Disk->Buffer);
+}
+
+NTSTATUS
+NTAPI
+FstubWriteEntryEFI(IN PDISK_INFORMATION Disk,
+ IN ULONG PartitionsSizeSector,
+ IN ULONG PartitionEntryNumber,
+ IN PEFI_PARTITION_ENTRY PartitionEntry,
+ IN BOOLEAN WriteBackupTable,
+ IN BOOLEAN ForceWrite,
+ OUT PULONG PartitionEntryCRC32 OPTIONAL)
+{
+ ULONG Offset;
+ ULONGLONG FirstEntryLBA;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PAGED_CODE();
+
+ ASSERT(Disk);
+ ASSERT(IS_VALID_DISK_INFO(Disk));
+
+ /* Get the first LBA where the partition table is:
+ * On primary table, it's sector 2 (skip MBR & Header)
+ * On backup table, it's ante last sector (Header) minus partition table size
+ */
+ if (!WriteBackupTable)
+ {
+ FirstEntryLBA = 2ULL;
+ }
+ else
+ {
+ FirstEntryLBA = Disk->SectorCount - PartitionsSizeSector - 1;
+ }
+
+ /* Copy the entry at the proper place into the buffer
+ * That way, we don't erase previous entries
+ */
+ RtlCopyMemory(Disk->Buffer + (((PartitionEntryNumber * PARTITION_ENTRY_SIZE) % Disk->SectorSize) / sizeof(PUSHORT)),
+ PartitionEntry,
+ sizeof(EFI_PARTITION_ENTRY));
+ /* Compute size of buffer */
+ Offset = (PartitionEntryNumber * PARTITION_ENTRY_SIZE) % Disk->SectorSize + PARTITION_ENTRY_SIZE;
+ ASSERT(Offset <= Disk->SectorSize);
+
+ /* If it's full of partition entries, or if call ask for it, write down the data */
+ if (Offset == Disk->SectorSize || ForceWrite)
+ {
+ /* We will write at first entry LBA + a shift made by already present/written entries */
+ Status = FstubWriteSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ FirstEntryLBA + ((PartitionEntryNumber * PARTITION_ENTRY_SIZE) / Disk->SectorSize),
+ Disk->Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ /* We clean buffer */
+ RtlZeroMemory(Disk->Buffer, Disk->SectorSize);
+ }
+
+ /* If we have a buffer for CRC32, then compute it */
+ if (PartitionEntryCRC32)
+ {
+ *PartitionEntryCRC32 = RtlComputeCrc32(*PartitionEntryCRC32, (PUCHAR)PartitionEntry, PARTITION_ENTRY_SIZE);
+ }
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+FstubWriteHeaderEFI(IN PDISK_INFORMATION Disk,
+ IN ULONG PartitionsSizeSector,
+ IN GUID DiskGUID,
+ IN ULONG NumberOfEntries,
+ IN ULONGLONG FirstUsableLBA,
+ IN ULONGLONG LastUsableLBA,
+ IN ULONG PartitionEntryCRC32,
+ IN BOOLEAN WriteBackupTable)
+{
+ PEFI_PARTITION_HEADER EFIHeader;
+ PAGED_CODE();
+
+ ASSERT(Disk);
+ ASSERT(IS_VALID_DISK_INFO(Disk));
+
+ /* Let's use read buffer as EFI_PARTITION_HEADER */
+ EFIHeader = (PEFI_PARTITION_HEADER)Disk->Buffer;
+
+ /* Complete standard header information */
+ EFIHeader->Signature = EFI_HEADER_SIGNATURE;
+ EFIHeader->Revision = EFI_HEADER_REVISION_1;
+ EFIHeader->HeaderSize = sizeof(EFI_PARTITION_HEADER);
+ /* Set no CRC32 checksum at the moment */
+ EFIHeader->HeaderCRC32 = 0;
+ EFIHeader->Reserved = 0;
+ /* Check whether we're writing primary or backup
+ * That way, we can ajust LBA setting:
+ * Primary is on first sector
+ * Backup is on last sector
+ */
+ if (!WriteBackupTable)
+ {
+ EFIHeader->MyLBA = 1ULL;
+ EFIHeader->AlternateLBA = Disk->SectorCount - 1ULL;
+ }
+ else
+ {
+ EFIHeader->MyLBA = Disk->SectorCount - 1ULL;
+ EFIHeader->AlternateLBA = 1ULL;
+ }
+ /* Fill in with received data */
+ EFIHeader->FirstUsableLBA = FirstUsableLBA;
+ EFIHeader->LastUsableLBA = LastUsableLBA;
+ EFIHeader->DiskGUID = DiskGUID;
+ /* Check whether we're writing primary or backup
+ * That way, we can ajust LBA setting:
+ * On primary, partition entries are just after header, so sector 2
+ * On backup, partition entries are just before header, so, last sector minus partition table size
+ */
+ if (!WriteBackupTable)
+ {
+ EFIHeader->PartitionEntryLBA = EFIHeader->MyLBA + 1ULL;
+ }
+ else
+ {
+ EFIHeader->PartitionEntryLBA = EFIHeader->MyLBA - PartitionsSizeSector;
+ }
+ /* Complete filling in */
+ EFIHeader->NumberOfEntries = NumberOfEntries;
+ EFIHeader->SizeOfPartitionEntry = PARTITION_ENTRY_SIZE;
+ EFIHeader->PartitionEntryCRC32 = PartitionEntryCRC32;
+ /* Finally, compute header checksum */
+ EFIHeader->HeaderCRC32 = RtlComputeCrc32(0, (PUCHAR)EFIHeader, sizeof(EFI_PARTITION_HEADER));
+
+ /* Debug the way we'll break disk, to let user pray */
+ DPRINT("FSTUB: About to write the following header for %s table\n", (WriteBackupTable ? "backup" : "primary"));
+ DPRINT(" Signature: %I64x\n Revision: %x\n HeaderSize: %x\n HeaderCRC32: %x\n",
+ EFIHeader->Signature, EFIHeader->Revision, EFIHeader->HeaderSize, EFIHeader->HeaderCRC32);
+ DPRINT(" MyLBA: %I64x\n AlternateLBA: %I64x\n FirstUsableLBA: %I64x\n LastUsableLBA: %I64x\n",
+ EFIHeader->MyLBA, EFIHeader->AlternateLBA, EFIHeader->FirstUsableLBA, EFIHeader->LastUsableLBA);
+ DPRINT(" PartitionEntryLBA: %I64x\n NumberOfEntries: %x\n SizeOfPartitionEntry: %x\n PartitionEntryCRC32: %x\n",
+ EFIHeader->PartitionEntryLBA, EFIHeader->NumberOfEntries,
+ EFIHeader->SizeOfPartitionEntry, EFIHeader->PartitionEntryCRC32);
+
+ /* Write header to disk */
+ return FstubWriteSector(Disk->DeviceObject,
+ Disk->SectorSize,
+ EFIHeader->MyLBA,
+ Disk->Buffer);
+}
+
+NTSTATUS
+NTAPI
+FstubWritePartitionTableEFI(IN PDISK_INFORMATION Disk,
+ IN GUID DiskGUID,
+ IN ULONG MaxPartitionCount,
+ IN ULONGLONG FirstUsableLBA,
+ IN ULONGLONG LastUsableLBA,
+ IN BOOLEAN WriteBackupTable,
+ IN ULONG PartitionCount,
+ IN PPARTITION_INFORMATION_EX PartitionEntries OPTIONAL)
+{
+ NTSTATUS Status;
+ EFI_PARTITION_ENTRY Entry;
+ ULONG i, WrittenPartitions, SectoredPartitionEntriesSize, PartitionEntryCRC32;
+ PAGED_CODE();
+
+ ASSERT(Disk);
+ ASSERT(MaxPartitionCount >= 128);
+ ASSERT(PartitionCount <= MaxPartitionCount);
+
+ PartitionEntryCRC32 = 0;
+ /* Count how much sectors we'll have to read to read the whole partition table */
+ SectoredPartitionEntriesSize = (MaxPartitionCount * PARTITION_ENTRY_SIZE) / Disk->SectorSize;
+
+ for (i = 0, WrittenPartitions = 0; i < PartitionCount; i++)
+ {
+ /* If partition GUID is 00000000-0000-0000-0000-000000000000, then it's unused, skip it */
+ if (PartitionEntries[i].Gpt.PartitionType.Data1 == 0 &&
+ PartitionEntries[i].Gpt.PartitionType.Data2 == 0 &&
+ PartitionEntries[i].Gpt.PartitionType.Data3 == 0 &&
+ ((PULONGLONG)PartitionEntries[i].Gpt.PartitionType.Data4)[0] == 0)
+ {
+ continue;
+ }
+
+ /* Copy the entry in the partition entry format */
+ FstubCopyEntryEFI(&Entry, &PartitionEntries[i], Disk->SectorSize);
+ /* Then write the entry to the disk */
+ Status = FstubWriteEntryEFI(Disk,
+ SectoredPartitionEntriesSize,
+ WrittenPartitions,
+ &Entry,
+ WriteBackupTable,
+ FALSE,
+ &PartitionEntryCRC32);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ WrittenPartitions++;
+ }
+
+ /* Zero the buffer to write zeros to the disk */
+ RtlZeroMemory(&Entry, sizeof(EFI_PARTITION_ENTRY));
+ /* Write the disks with zeros for every unused remaining partition entry */
+ for (i = WrittenPartitions; i < MaxPartitionCount; i++)
+ {
+ Status = FstubWriteEntryEFI(Disk,
+ SectoredPartitionEntriesSize,
+ i,
+ &Entry,
+ WriteBackupTable,
+ FALSE,
+ &PartitionEntryCRC32);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ /* Once we're done, write the GPT header */
+ return FstubWriteHeaderEFI(Disk,
+ SectoredPartitionEntriesSize,
+ DiskGUID,
+ MaxPartitionCount,
+ FirstUsableLBA,
+ LastUsableLBA,
+ PartitionEntryCRC32,
+ WriteBackupTable);
+}
+
+NTSTATUS
+NTAPI
+FstubWritePartitionTableMBR(IN PDISK_INFORMATION Disk,
+ IN PDRIVE_LAYOUT_INFORMATION_EX LayoutEx)
+{
+ NTSTATUS Status;
+ PDRIVE_LAYOUT_INFORMATION DriveLayout;
+ PAGED_CODE();
+
+ ASSERT(IS_VALID_DISK_INFO(Disk));
+ ASSERT(LayoutEx);
+
+ /* Convert data to the correct format */
+ DriveLayout = FstubConvertExtendedToLayout(LayoutEx);
+ if (!DriveLayout)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Really write information */
+ Status = IoWritePartitionTable(Disk->DeviceObject,
+ Disk->SectorSize,
+ Disk->DiskGeometry.Geometry.SectorsPerTrack,
+ Disk->DiskGeometry.Geometry.TracksPerCylinder,
+ DriveLayout);
+
+ /* Free allocated structure and return */
+ ExFreePool(DriveLayout);
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+FstubWriteSector(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN ULONGLONG StartingSector OPTIONAL,
+ IN PUSHORT Buffer)
+{
+ PIRP Irp;
+ KEVENT Event;
+ NTSTATUS Status;
+ LARGE_INTEGER StartingOffset;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PIO_STACK_LOCATION IoStackLocation;
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+ ASSERT(Buffer);
+ ASSERT(SectorSize);
+
+ /* Compute starting offset */
+ StartingOffset.QuadPart = StartingSector * SectorSize;
+
+ /* Initialize waiting event */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ /* Prepare IRP */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
+ DeviceObject,
+ Buffer,
+ SectorSize,
+ &StartingOffset,
+ &Event,
+ &IoStatusBlock);
+ if (!Irp)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Override volume verify */
+ IoStackLocation = IoGetNextIrpStackLocation(Irp);
+ IoStackLocation->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
+
+ /* Then call driver, and wait for completion if needed */
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ return Status;
+}
+
/* FUNCTIONS *****************************************************************/
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
IoCreateDisk(IN PDEVICE_OBJECT DeviceObject,
IN struct _CREATE_DISK* Disk)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PARTITION_STYLE PartitionStyle;
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+
+ /* Get partition style. If caller didn't provided data, assume it's raw */
+ PartitionStyle = ((Disk) ? Disk->PartitionStyle : PARTITION_STYLE_RAW);
+ /* Then, call appropriate internal function */
+ switch (PartitionStyle)
+ {
+ case PARTITION_STYLE_MBR:
+ return FstubCreateDiskMBR(DeviceObject, &(Disk->Mbr));
+ case PARTITION_STYLE_GPT:
+ return FstubCreateDiskEFI(DeviceObject, &(Disk->Gpt));
+ case PARTITION_STYLE_RAW:
+ return FstubCreateDiskRaw(DeviceObject);
+ default:
+ return STATUS_NOT_SUPPORTED;
+ }
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
IoGetBootDiskInformation(IN OUT PBOOTDISK_INFORMATION BootDiskInformation,
IN ULONG Size)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PIRP Irp;
+ KEVENT Event;
+ PLIST_ENTRY NextEntry;
+ PFILE_OBJECT FileObject;
+ DISK_GEOMETRY DiskGeometry;
+ PDEVICE_OBJECT DeviceObject;
+ UNICODE_STRING DeviceStringW;
+ IO_STATUS_BLOCK IoStatusBlock;
+ CHAR Buffer[128], ArcBuffer[128];
+ NTSTATUS Status = STATUS_SUCCESS;
+ BOOLEAN SingleDisk, IsBootDiskInfoEx;
+ PARC_DISK_SIGNATURE ArcDiskSignature;
+ PARC_DISK_INFORMATION ArcDiskInformation;
+ PARTITION_INFORMATION_EX PartitionInformation;
+ PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = NULL;
+ ULONG DiskCount, DiskNumber, Signature, PartitionNumber;
+ ANSI_STRING ArcBootString, ArcSystemString, DeviceStringA, ArcNameStringA;
+ extern PLOADER_PARAMETER_BLOCK IopLoaderBlock;
+ PAGED_CODE();
+
+ /* Get loader block. If it's null, we come to late */
+ if (!IopLoaderBlock)
+ {
+ return STATUS_TOO_LATE;
+ }
+
+ /* Check buffer size */
+ if (Size < sizeof(BOOTDISK_INFORMATION))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Init some useful stuff:
+ * Get arc disks information
+ * Check whether we have a single disk
+ * Check received structure size (extended or not?)
+ * Init boot strings (system/boot)
+ * Finaly, get disk count
+ */
+ ArcDiskInformation = IopLoaderBlock->ArcDiskInformation;
+ SingleDisk = IsListEmpty(&(ArcDiskInformation->DiskSignatureListHead));
+ IsBootDiskInfoEx = (Size >= sizeof(BOOTDISK_INFORMATION_EX));
+ RtlInitAnsiString(&ArcBootString, IopLoaderBlock->ArcBootDeviceName);
+ RtlInitAnsiString(&ArcSystemString, IopLoaderBlock->ArcHalDeviceName);
+ DiskCount = IoGetConfigurationInformation()->DiskCount;
+
+ /* If no disk, return success */
+ if (DiskCount == 0)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ /* Now, browse all disks */
+ for (DiskNumber = 0; DiskNumber < DiskCount; DiskNumber++)
+ {
+ /* Create the device name */
+ sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", DiskNumber);
+ RtlInitAnsiString(&DeviceStringA, Buffer);
+ Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ continue;
+ }
+
+ /* Get its device object */
+ Status = IoGetDeviceObjectPointer(&DeviceStringW,
+ FILE_READ_ATTRIBUTES,
+ &FileObject,
+ &DeviceObject);
+ RtlFreeUnicodeString(&DeviceStringW);
+ if (!NT_SUCCESS(Status))
+ {
+ continue;
+ }
+
+ /* Prepare for getting disk geometry */
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ DeviceObject,
+ NULL,
+ 0,
+ &DiskGeometry,
+ sizeof(DISK_GEOMETRY),
+ FALSE,
+ &Event,
+ &IoStatusBlock);
+ if (!Irp)
+ {
+ ObDereferenceObject(FileObject);
+ continue;
+ }
+
+ /* Then, call the drive, and wait for it if needed */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatusBlock.Status;
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(FileObject);
+ continue;
+ }
+
+ /* Read partition table */
+ Status = IoReadPartitionTableEx(DeviceObject,
+ &DriveLayout);
+
+ /* FileObject, you can go! */
+ ObDereferenceObject(FileObject);
+
+ if (!NT_SUCCESS(Status))
+ {
+ continue;
+ }
+
+ /* Ensure we have at least 512 bytes per sector */
+ if (DiskGeometry.BytesPerSector < 512)
+ {
+ DiskGeometry.BytesPerSector = 512;
+ }
+
+ /* Now, for each arc disk, try to find the matching */
+ for (NextEntry = ArcDiskInformation->DiskSignatureListHead.Flink;
+ NextEntry != &ArcDiskInformation->DiskSignatureListHead;
+ NextEntry = NextEntry->Flink)
+ {
+ ArcDiskSignature = CONTAINING_RECORD(NextEntry,
+ ARC_DISK_SIGNATURE,
+ ListEntry);
+ /* If they matches, ie
+ * - There's only one disk for both BIOS and detected
+ * - Signatures are matching
+ * - This is MBR
+ * (We don't check checksums here)
+ */
+ if (((SingleDisk && DiskCount == 1) ||
+ (IopVerifyDiskSignature(DriveLayout, ArcDiskSignature, &Signature))) &&
+ (DriveLayout->PartitionStyle == PARTITION_STYLE_MBR))
+ {
+ /* Create arc name */
+ sprintf(ArcBuffer, "\\ArcName\\%s", ArcDiskSignature->ArcName);
+ RtlInitAnsiString(&ArcNameStringA, ArcBuffer);
+
+ /* Browse all partitions */
+ for (PartitionNumber = 1; PartitionNumber <= DriveLayout->PartitionCount; PartitionNumber++)
+ {
+ /* Create its device name */
+ sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition%lu", DiskNumber, PartitionNumber);
+ RtlInitAnsiString(&DeviceStringA, Buffer);
+ Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ continue;
+ }
+
+ /* If IopVerifyDiskSignature returned no signature, take the one from DriveLayout */
+ if (!Signature)
+ {
+ Signature = DriveLayout->Mbr.Signature;
+ }
+
+ /* Create partial arc name */
+ sprintf(ArcBuffer, "%spartition(%lu)", ArcDiskSignature->ArcName, PartitionNumber);
+ RtlInitAnsiString(&ArcNameStringA, ArcBuffer);
+
+ /* If it's matching boot string */
+ if (RtlEqualString(&ArcNameStringA, &ArcBootString, TRUE))
+ {
+ /* Then, fill in information about boot device */
+ BootDiskInformation->BootDeviceSignature = Signature;
+
+ /* Get its device object */
+ Status = IoGetDeviceObjectPointer(&DeviceStringW,
+ FILE_READ_ATTRIBUTES,
+ &FileObject,
+ &DeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&DeviceStringW);
+ continue;
+ }
+
+ /* And call the drive to get information about partition */
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO_EX,
+ DeviceObject,
+ NULL,
+ 0,
+ &PartitionInformation,
+ sizeof(PARTITION_INFORMATION_EX),
+ FALSE,
+ &Event,
+ &IoStatusBlock);
+ if (!Irp)
+ {
+ ObDereferenceObject(FileObject);
+ RtlFreeUnicodeString(&DeviceStringW);
+ continue;
+ }
+
+ /* Call & wait if needed */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatusBlock.Status;
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(FileObject);
+ RtlFreeUnicodeString(&DeviceStringW);
+ continue;
+ }
+
+ /* We get partition offset as demanded and return it */
+ BootDiskInformation->BootPartitionOffset = PartitionInformation.StartingOffset.QuadPart;
+
+ /* If called passed a BOOTDISK_INFORMATION_EX structure, give more intel */
+ if (IsBootDiskInfoEx)
+ {
+ /* Is PT MBR or GPT? */
+ if (DriveLayout->PartitionStyle == PARTITION_STYLE_GPT)
+ {
+ ((PBOOTDISK_INFORMATION_EX)BootDiskInformation)->BootDeviceGuid = DriveLayout->Gpt.DiskId;
+ ((PBOOTDISK_INFORMATION_EX)BootDiskInformation)->BootDeviceIsGpt = TRUE;
+ }
+ else
+ {
+ ((PBOOTDISK_INFORMATION_EX)BootDiskInformation)->BootDeviceIsGpt = FALSE;
+ }
+ }
+
+ /* Dereference FileObject */
+ ObDereferenceObject(FileObject);
+ }
+
+ /* If it's matching system string */
+ if (RtlEqualString(&ArcNameStringA, &ArcSystemString, TRUE))
+ {
+ /* Then, fill in information about the system device */
+ BootDiskInformation->SystemDeviceSignature = Signature;
+
+ /* Get its device object */
+ Status = IoGetDeviceObjectPointer(&DeviceStringW,
+ FILE_READ_ATTRIBUTES,
+ &FileObject,
+ &DeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&DeviceStringW);
+ continue;
+ }
+
+ /* And call the drive to get information about partition */
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO_EX,
+ DeviceObject,
+ NULL,
+ 0,
+ &PartitionInformation,
+ sizeof(PARTITION_INFORMATION_EX),
+ FALSE,
+ &Event,
+ &IoStatusBlock);
+ if (!Irp)
+ {
+ ObDereferenceObject(FileObject);
+ RtlFreeUnicodeString(&DeviceStringW);
+ continue;
+ }
+
+ /* Call & wait if needed */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatusBlock.Status;
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(FileObject);
+ RtlFreeUnicodeString(&DeviceStringW);
+ continue;
+ }
+
+ /* We get partition offset as demanded and return it */
+ BootDiskInformation->SystemPartitionOffset = PartitionInformation.StartingOffset.QuadPart;
+
+ /* If called passed a BOOTDISK_INFORMATION_EX structure, give more intel */
+ if (IsBootDiskInfoEx)
+ {
+ /* Is PT MBR or GPT? */
+ if (DriveLayout->PartitionStyle == PARTITION_STYLE_GPT)
+ {
+ ((PBOOTDISK_INFORMATION_EX)BootDiskInformation)->SystemDeviceGuid = DriveLayout->Gpt.DiskId;
+ ((PBOOTDISK_INFORMATION_EX)BootDiskInformation)->SystemDeviceIsGpt = TRUE;
+ }
+ else
+ {
+ ((PBOOTDISK_INFORMATION_EX)BootDiskInformation)->SystemDeviceIsGpt = FALSE;
+ }
+ }
+
+ /* Dereference FileObject */
+ ObDereferenceObject(FileObject);
+ }
+
+ /* Release device string */
+ RtlFreeUnicodeString(&DeviceStringW);
+ }
+ }
+ }
+
+ /* Finally, release drive layout structure */
+ ExFreePool(DriveLayout);
+ }
+
+ /* And return */
+ return Status;
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -538,8 +2054,101 @@ IoReadDiskSignature(IN PDEVICE_OBJECT DeviceObject,
IN ULONG BytesPerSector,
OUT PDISK_SIGNATURE Signature)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PULONG Buffer;
+ NTSTATUS Status;
+ ULONG HeaderCRC32, i, CheckSum;
+ PEFI_PARTITION_HEADER EFIHeader;
+ PPARTITION_DESCRIPTOR PartitionDescriptor;
+ PAGED_CODE();
+
+ /* Ensure we'll read at least 512 bytes */
+ if (BytesPerSector < 512)
+ {
+ BytesPerSector = 512;
+ }
+
+ /* Allocate a buffer for reading operations */
+ Buffer = ExAllocatePoolWithTag(NonPagedPoolCacheAligned, BytesPerSector, TAG_FSTUB);
+ if (!Buffer)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Read first sector (sector 0) for MBR */
+ Status = FstubReadSector(DeviceObject,
+ BytesPerSector,
+ 0ULL,
+ (PUSHORT)Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Get the partition descriptor array */
+ PartitionDescriptor = (PPARTITION_DESCRIPTOR)
+ &(Buffer[PARTITION_TABLE_OFFSET]);
+ /* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
+ if (PartitionDescriptor[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
+ PartitionDescriptor[1].PartitionType == 0 &&
+ PartitionDescriptor[2].PartitionType == 0 &&
+ PartitionDescriptor[3].PartitionType == 0)
+ {
+ /* If we have GPT, read second sector (sector 1) for GPT header */
+ Status = FstubReadSector(DeviceObject,
+ BytesPerSector,
+ 1ULL,
+ (PUSHORT)Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
+ EFIHeader = (PEFI_PARTITION_HEADER)Buffer;
+
+ /* First check signature
+ * Then, check version (we only support v1
+ * Finally check header size
+ */
+ if (EFIHeader->Signature != EFI_HEADER_SIGNATURE ||
+ EFIHeader->Revision != EFI_HEADER_REVISION_1 ||
+ EFIHeader->HeaderSize != sizeof(EFI_PARTITION_HEADER))
+ {
+ Status = STATUS_DISK_CORRUPT_ERROR;
+ goto Cleanup;
+ }
+
+ /* Save current checksum */
+ HeaderCRC32 = EFIHeader->HeaderCRC32;
+ /* Then zero the one in EFI header. This is needed to compute header checksum */
+ EFIHeader->HeaderCRC32 = 0;
+ /* Compute header checksum and compare with the one present in partition table */
+ if (RtlComputeCrc32(0, (PUCHAR)Buffer, sizeof(EFI_PARTITION_HEADER)) != HeaderCRC32)
+ {
+ Status = STATUS_DISK_CORRUPT_ERROR;
+ goto Cleanup;
+ }
+
+ /* Set partition table style to GPT and return disk GUID */
+ Signature->PartitionStyle = PARTITION_STYLE_GPT;
+ Signature->Gpt.DiskId = EFIHeader->DiskGUID;
+ }
+ else
+ {
+ /* Compute MBR checksum */
+ for (i = 0, CheckSum = 0; i < 512 / sizeof(ULONG) ; i++)
+ {
+ CheckSum += Buffer[i];
+ }
+
+ /* Set partition table style to MBR and return signature (offset 440) and checksum */
+ Signature->PartitionStyle = PARTITION_STYLE_MBR;
+ Signature->Mbr.Signature = Buffer[PARTITION_TABLE_OFFSET / 2 - 1];
+ Signature->Mbr.CheckSum = CheckSum;
+ }
+
+Cleanup:
+ /* Free buffer and return */
+ ExFreePoolWithTag(Buffer, TAG_FSTUB);
+ return Status;
}
/*
@@ -610,7 +2219,7 @@ IoReadPartitionTableEx(IN PDEVICE_OBJECT DeviceObject,
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -618,32 +2227,207 @@ IoSetPartitionInformationEx(IN PDEVICE_OBJECT DeviceObject,
IN ULONG PartitionNumber,
IN struct _SET_PARTITION_INFORMATION_EX* PartitionInfo)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PDISK_INFORMATION Disk;
+ PARTITION_STYLE PartitionStyle;
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+ ASSERT(PartitionInfo);
+
+ /* Debug given modifications */
+ FstubDbgPrintSetPartitionEx(PartitionInfo, PartitionNumber);
+
+ /* Allocate internal structure */
+ Status = FstubAllocateDiskInformation(DeviceObject, &Disk, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Get partition table style on disk */
+ Status = FstubDetectPartitionStyle(Disk, &PartitionStyle);
+ if (!NT_SUCCESS(Status))
+ {
+ FstubFreeDiskInformation(Disk);
+ return Status;
+ }
+
+ /* If it's not matching partition style given in modifications, give up */
+ if (PartitionInfo->PartitionStyle != PartitionStyle)
+ {
+ FstubFreeDiskInformation(Disk);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Finally, handle modifications using proper function */
+ switch (PartitionStyle)
+ {
+ case PARTITION_STYLE_MBR:
+ Status = IoSetPartitionInformation(DeviceObject,
+ Disk->SectorSize,
+ PartitionNumber,
+ PartitionInfo->Mbr.PartitionType);
+ break;
+ case PARTITION_STYLE_GPT:
+ Status = FstubSetPartitionInformationEFI(Disk,
+ PartitionNumber,
+ &(PartitionInfo->Gpt));
+ break;
+ default:
+ Status = STATUS_NOT_SUPPORTED;
+ }
+
+ /* Release internal structure and return */
+ FstubFreeDiskInformation(Disk);
+ return Status;
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
IoVerifyPartitionTable(IN PDEVICE_OBJECT DeviceObject,
IN BOOLEAN FixErrors)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PDISK_INFORMATION Disk;
+ PARTITION_STYLE PartitionStyle;
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+
+ /* Allocate internal structure */
+ Status = FstubAllocateDiskInformation(DeviceObject, &Disk, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ ASSERT(Disk);
+
+ /* Get partition table style on disk */
+ Status = FstubDetectPartitionStyle(Disk, &PartitionStyle);
+ if (!NT_SUCCESS(Status))
+ {
+ FstubFreeDiskInformation(Disk);
+ return Status;
+ }
+
+ /* Action will depend on partition style */
+ switch (PartitionStyle)
+ {
+ /* For MBR, assume it's always OK */
+ case PARTITION_STYLE_MBR:
+ Status = STATUS_SUCCESS;
+ break;
+ /* For GPT, call internal function */
+ case PARTITION_STYLE_GPT:
+ Status = FstubVerifyPartitionTableEFI(Disk, FixErrors);
+ break;
+ /* Otherwise, signal we can't work */
+ default:
+ Status = STATUS_NOT_SUPPORTED;
+ }
+
+ /* Release internal structure and return */
+ FstubFreeDiskInformation(Disk);
+ return Status;
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
IoWritePartitionTableEx(IN PDEVICE_OBJECT DeviceObject,
- IN struct _DRIVE_LAYOUT_INFORMATION_EX* DriveLayfout)
+ IN struct _DRIVE_LAYOUT_INFORMATION_EX* DriveLayout)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PDISK_INFORMATION Disk;
+ ULONGLONG SectorsForPartitions;
+ EFI_PARTITION_HEADER EfiHeader;
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+ ASSERT(DriveLayout);
+
+ /* Debug partition table that must be written */
+ FstubDbgPrintDriveLayoutEx(DriveLayout);
+
+ /* Allocate internal structure */
+ Status = FstubAllocateDiskInformation(DeviceObject, &Disk, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ ASSERT(Disk);
+
+ switch (DriveLayout->PartitionStyle)
+ {
+ case PARTITION_STYLE_MBR:
+ Status = FstubWritePartitionTableMBR(Disk, DriveLayout);
+ break;
+
+ case PARTITION_STYLE_GPT:
+ /* Read primary table header */
+ Status = FstubReadHeaderEFI(Disk,
+ FALSE,
+ &EfiHeader);
+ /* If it failed, try reading back table header */
+ if (!NT_SUCCESS(Status))
+ {
+ Status = FstubReadHeaderEFI(Disk,
+ TRUE,
+ &EfiHeader);
+ }
+
+ /* We have a header! */
+ if (NT_SUCCESS(Status))
+ {
+ /* Check if there are enough places for the partitions to be written */
+ if (DriveLayout->PartitionCount <= EfiHeader.NumberOfEntries)
+ {
+ /* Count number of sectors needed to store partitions */
+ SectorsForPartitions = (EfiHeader.NumberOfEntries * PARTITION_ENTRY_SIZE) / Disk->SectorSize;
+ /* Set first usable LBA: Legacy MBR + GPT header + Partitions entries */
+ EfiHeader.FirstUsableLBA = SectorsForPartitions + 2;
+ /* Set last usable LBA: Last sector - GPT header - Partitions entries */
+ EfiHeader.LastUsableLBA = Disk->SectorCount - SectorsForPartitions - 1;
+ /* Write primary table */
+ Status = FstubWritePartitionTableEFI(Disk,
+ EfiHeader.DiskGUID,
+ EfiHeader.NumberOfEntries,
+ EfiHeader.FirstUsableLBA,
+ EfiHeader.LastUsableLBA,
+ FALSE,
+ DriveLayout->PartitionCount,
+ DriveLayout->PartitionEntry);
+ /* If it succeed, also update backup table */
+ if (NT_SUCCESS(Status))
+ {
+ Status = FstubWritePartitionTableEFI(Disk,
+ EfiHeader.DiskGUID,
+ EfiHeader.NumberOfEntries,
+ EfiHeader.FirstUsableLBA,
+ EfiHeader.LastUsableLBA,
+ TRUE,
+ DriveLayout->PartitionCount,
+ DriveLayout->PartitionEntry);
+ }
+ }
+ }
+ break;
+
+ default:
+ DPRINT("Unsupported partition style: %ld\n", DriveLayout->PartitionStyle);
+ Status = STATUS_NOT_SUPPORTED;
+ }
+
+ /* It's over, internal structure not needed anymore */
+ FstubFreeDiskInformation(Disk);
+
+ return Status;
}
/* EOF */
diff --git a/ntoskrnl/inbv/inbv.c b/ntoskrnl/inbv/inbv.c
index 280e918bd83..98aff194e3f 100644
--- a/ntoskrnl/inbv/inbv.c
+++ b/ntoskrnl/inbv/inbv.c
@@ -28,6 +28,7 @@ BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0};
PVOID
NTAPI
+INIT_FUNCTION
FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN ULONG ResourceId)
{
@@ -92,6 +93,7 @@ FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
BOOLEAN
NTAPI
+INIT_FUNCTION
InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN ULONG Count)
{
@@ -174,6 +176,7 @@ InbvReleaseLock(VOID)
VOID
NTAPI
+INIT_FUNCTION
InbvEnableBootDriver(IN BOOLEAN Enable)
{
/* Check if we're installed */
@@ -408,6 +411,7 @@ InbvSolidColorFill(IN ULONG Left,
VOID
NTAPI
+INIT_FUNCTION
InbvUpdateProgressBar(IN ULONG Progress)
{
ULONG FillCount, BoundedProgress;
@@ -523,6 +527,7 @@ InbvSetProgressBarSubset(IN ULONG Floor,
VOID
NTAPI
+INIT_FUNCTION
InbvIndicateProgress(VOID)
{
ULONG Percentage;
@@ -570,6 +575,7 @@ NtDisplayString(IN PUNICODE_STRING DisplayString)
VOID
NTAPI
+INIT_FUNCTION
DisplayBootBitmap(IN BOOLEAN SosMode)
{
PVOID Header, Band, Text, Screen;
@@ -705,6 +711,7 @@ DisplayBootBitmap(IN BOOLEAN SosMode)
VOID
NTAPI
+INIT_FUNCTION
FinalizeBootLogo(VOID)
{
/* Acquire lock and check the display state */
diff --git a/ntoskrnl/include/internal/arm/kxarm.h b/ntoskrnl/include/internal/arm/kxarm.h
index 3ac4d762346..cede87c6763 100644
--- a/ntoskrnl/include/internal/arm/kxarm.h
+++ b/ntoskrnl/include/internal/arm/kxarm.h
@@ -1,6 +1,6 @@
.macro TEXTAREA
- .section text, "rx"
+ .section .text, "rx"
.align 2
.endm
diff --git a/ntoskrnl/include/internal/arm/mm.h b/ntoskrnl/include/internal/arm/mm.h
index 03bb7bf1372..b73179c6359 100644
--- a/ntoskrnl/include/internal/arm/mm.h
+++ b/ntoskrnl/include/internal/arm/mm.h
@@ -1,5 +1,7 @@
#pragma once
+#define _MI_PAGING_LEVELS 2
+
#define PDE_SHIFT 20
//
@@ -20,6 +22,7 @@
#define PTE_BASE 0xC0000000
#define PTE_TOP 0xC03FFFFF
#define PDE_BASE 0xC0400000
+#define PDE_TOP 0xC04FFFFF
#define HYPER_SPACE 0xC0500000
#if 0
@@ -106,6 +109,7 @@ PULONG MmGetPageDirectory(VOID);
#define MI_MAKE_LOCAL_PAGE(x) ((x)->u.Hard.NonGlobal = 1)
#define MI_MAKE_DIRTY_PAGE(x)
+#define MI_MAKE_ACCESSED_PAGE(x)
#define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1)
#define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.ReadOnly = 0)
#define MI_PAGE_DISABLE_CACHE(x) ((x)->u.Hard.Cached = 0)
@@ -114,6 +118,7 @@ PULONG MmGetPageDirectory(VOID);
#define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.ReadOnly == 0)
#define MI_IS_PAGE_COPY_ON_WRITE(x)FALSE
#define MI_IS_PAGE_DIRTY(x) TRUE
+#define MI_IS_PAGE_LARGE(x) FALSE
/* Easy accessing PFN in PTE */
#define PFN_FROM_PTE(v) ((v)->u.Hard.PageFrameNumber)
@@ -129,6 +134,12 @@ PULONG MmGetPageDirectory(VOID);
MI_HYPERSPACE_PTES * PAGE_SIZE)
#define MI_ZERO_PTE (PMMPTE)(MI_MAPPING_RANGE_END + \
PAGE_SIZE)
+#define MI_DUMMY_PTE (PMMPTE)(MI_MAPPING_RANGE_END + \
+ PAGE_SIZE)
+#define MI_VAD_BITMAP (PMMPTE)(MI_DUMMY_PTE + \
+ PAGE_SIZE)
+#define MI_WORKING_SET_LIST (PMMPTE)(MI_VAD_BITMAP + \
+ PAGE_SIZE)
/* Retrives the PDE entry for the given VA */
#define MiGetPdeAddress(x) ((PMMPDE)(PDE_BASE + (((ULONG)(x) >> 20) << 2)))
@@ -139,8 +150,10 @@ PULONG MmGetPageDirectory(VOID);
#define MiAddressToPte(x) MiGetPteAddress(x)
/* Retrives the PDE offset for the given VA */
-#define MiGetPdeOffset(x) (((ULONG)(x)) >> 20)
-
+#define MiGetPdeOffset(x) (((ULONG)(x)) >> 20)
+#define MiGetPteOffset(x) ((((ULONG)(x)) << 12) >> 24)
+#define MiAddressToPteOffset(x) MiGetPteOffset(x)
+
/* Convert a PTE into a corresponding address */
#define MiPteToAddress(x) ((PVOID)((ULONG)(x) << 10))
#define MiPdeToAddress(x) ((PVOID)((ULONG)(x) << 18))
diff --git a/ntoskrnl/include/internal/fsrtl.h b/ntoskrnl/include/internal/fsrtl.h
index 7997abd41c3..b0777de94cc 100644
--- a/ntoskrnl/include/internal/fsrtl.h
+++ b/ntoskrnl/include/internal/fsrtl.h
@@ -53,6 +53,15 @@ FsRtlInitSystem(
VOID
);
+//
+// File contexts Routines
+//
+VOID
+NTAPI
+FsRtlPTeardownPerFileObjectContexts(
+ IN PFILE_OBJECT FileObject
+);
+
//
// Global data inside the File System Runtime Library
//
diff --git a/ntoskrnl/include/internal/i386/asmmacro.S b/ntoskrnl/include/internal/i386/asmmacro.S
index 6ddb9d015ad..2a64a938320 100644
--- a/ntoskrnl/include/internal/i386/asmmacro.S
+++ b/ntoskrnl/include/internal/i386/asmmacro.S
@@ -60,8 +60,8 @@
// @remark None.
//
MACRO(idt, Handler, Bits)
- .long \Handler
- .short \Bits
+ .long VAL(Handler)
+ .short VAL(Bits)
.short KGDT_R0_CODE
ENDM
@@ -128,17 +128,17 @@ MACRO(KiEnterTrap, Flags)
mov [esp + KTRAP_FRAME_EAX], eax
/* Does the caller want nonvolatiles only? */
- if ((Flags AND KI_NONVOLATILES_ONLY) == 0)
+ if (NOT (Flags AND KI_NONVOLATILES_ONLY))
/* Otherwise, save the volatiles as well */
mov [esp + KTRAP_FRAME_ECX], ecx
mov [esp + KTRAP_FRAME_EDX], edx
endif
/* Save segment registers? */
- if ((Flags AND KI_DONT_SAVE_SEGS) == 0)
+ if (NOT (Flags AND KI_DONT_SAVE_SEGS))
/* Check for V86 mode */
- test byte ptr [esp + KTRAP_FRAME_EFLAGS + 2], (EFLAGS_V86_MASK >> 16)
+ test byte ptr [esp + KTRAP_FRAME_EFLAGS + 2], (EFLAGS_V86_MASK / HEX(10000))
jz not_v86_trap
/* Restore V8086 segments into Protected Mode segments */
@@ -173,7 +173,7 @@ set_sane_segs:
mov es, ax
/* Fast system calls have fs already fixed */
- if ((Flags AND KI_FAST_SYSTEM_CALL) == 0)
+ if (NOT (Flags AND KI_FAST_SYSTEM_CALL))
/* Otherwise fix fs now */
mov ax, KGDT_R0_PCR
mov fs, ax
@@ -296,7 +296,7 @@ PUBLIC @&Name&@4
mov ecx, [esp - OffsetEsp + KTRAP_FRAME_ESP]
/* Keep interrupts disabled until the sti / sysexit */
- and byte ptr [esp - OffsetEsp + KTRAP_FRAME_EFLAGS + 1], ~(EFLAGS_INTERRUPT_MASK >> 8)
+ and byte ptr [esp - OffsetEsp + KTRAP_FRAME_EFLAGS + 1], NOT (EFLAGS_INTERRUPT_MASK / HEX(100))
endif
diff --git a/ntoskrnl/include/internal/i386/mm.h b/ntoskrnl/include/internal/i386/mm.h
index 1014884b099..83b48efef56 100644
--- a/ntoskrnl/include/internal/i386/mm.h
+++ b/ntoskrnl/include/internal/i386/mm.h
@@ -39,6 +39,7 @@ PULONG MmGetPageDirectory(VOID);
// Convert a PTE into a corresponding address
//
#define MiPteToAddress(PTE) ((PVOID)((ULONG)(PTE) << 10))
+#define MiPdeToAddress(PDE) ((PVOID)((ULONG)(PDE) << 10))
#define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (1024 * PAGE_SIZE))
#define ADDR_TO_PDE_OFFSET(v) ((((ULONG)(v)) / (1024 * PAGE_SIZE)))
@@ -51,9 +52,11 @@ PULONG MmGetPageDirectory(VOID);
#define MI_MAKE_LOCAL_PAGE(x) ((x)->u.Hard.Global = 0)
#define MI_MAKE_DIRTY_PAGE(x) ((x)->u.Hard.Dirty = 1)
+#define MI_MAKE_ACCESSED_PAGE(x) ((x)->u.Hard.Accessed = 1)
#define MI_PAGE_DISABLE_CACHE(x) ((x)->u.Hard.CacheDisable = 1)
#define MI_PAGE_WRITE_THROUGH(x) ((x)->u.Hard.WriteThrough = 1)
#define MI_PAGE_WRITE_COMBINED(x) ((x)->u.Hard.WriteThrough = 0)
+#define MI_IS_PAGE_LARGE(x) ((x)->u.Hard.LargePage == 1)
#if !defined(CONFIG_SMP)
#define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Write == 1)
#else
@@ -83,9 +86,13 @@ PULONG MmGetPageDirectory(VOID);
#define MI_ZERO_PTES (32)
#define MI_MAPPING_RANGE_START (ULONG)HYPER_SPACE
#define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + \
- MI_HYPERSPACE_PTES * PAGE_SIZE)
-#define MI_ZERO_PTE (PMMPTE)(MI_MAPPING_RANGE_END + \
- PAGE_SIZE)
+ MI_HYPERSPACE_PTES * PAGE_SIZE)
+#define MI_DUMMY_PTE (PMMPTE)(MI_MAPPING_RANGE_END + \
+ PAGE_SIZE)
+#define MI_VAD_BITMAP (PMMPTE)(MI_DUMMY_PTE + \
+ PAGE_SIZE)
+#define MI_WORKING_SET_LIST (PMMPTE)(MI_VAD_BITMAP + \
+ PAGE_SIZE)
/* On x86, these two are the same */
#define MMPDE MMPTE
diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h
index 28bc779111c..8edb68e75be 100644
--- a/ntoskrnl/include/internal/io.h
+++ b/ntoskrnl/include/internal/io.h
@@ -514,6 +514,21 @@ IopAssignDeviceResources(
IN PDEVICE_NODE DeviceNode
);
+NTSTATUS
+NTAPI
+IopCreateResourceListFromRequirements(
+ IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
+ OUT PCM_RESOURCE_LIST *ResourceList
+);
+
+NTSTATUS
+NTAPI
+IopDetectResourceConflict(
+ IN PCM_RESOURCE_LIST ResourceList,
+ IN BOOLEAN Silent,
+ OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor
+);
+
//
// PNP Routines
//
@@ -1140,6 +1155,20 @@ IopCloseFile(
IN ULONG SystemHandleCount
);
+PVOID
+NTAPI
+IoGetFileObjectFilterContext(
+ IN PFILE_OBJECT FileObject
+);
+
+NTSTATUS
+NTAPI
+IoChangeFileObjectFilterContext(
+ IN PFILE_OBJECT FileObject,
+ IN PVOID FilterContext,
+ IN BOOLEAN Define
+);
+
//
// I/O Timer Routines
//
diff --git a/ntoskrnl/include/internal/ke.h b/ntoskrnl/include/internal/ke.h
index 45d47d1612a..56f3ee013c2 100644
--- a/ntoskrnl/include/internal/ke.h
+++ b/ntoskrnl/include/internal/ke.h
@@ -298,8 +298,8 @@ KeReadStateThread(IN PKTHREAD Thread);
BOOLEAN
FASTCALL
KiSwapContext(
- IN PKTHREAD CurrentThread,
- IN PKTHREAD NewThread
+ IN KIRQL WaitIrql,
+ IN PKTHREAD CurrentThread
);
VOID
diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h
index c11fe04d6cc..02fa7e9d6d6 100644
--- a/ntoskrnl/include/internal/mm.h
+++ b/ntoskrnl/include/internal/mm.h
@@ -114,10 +114,8 @@ typedef ULONG SWAPENTRY;
#define MC_CACHE (0)
#define MC_USER (1)
-#define MC_PPOOL (2)
-#define MC_NPPOOL (3)
-#define MC_SYSTEM (4)
-#define MC_MAXIMUM (5)
+#define MC_SYSTEM (2)
+#define MC_MAXIMUM (3)
#define PAGED_POOL_MASK 1
#define MUST_SUCCEED_POOL_MASK 2
@@ -250,6 +248,8 @@ typedef struct _ROS_SECTION_OBJECT
};
} ROS_SECTION_OBJECT, *PROS_SECTION_OBJECT;
+struct _MM_CACHE_SECTION_SEGMENT;
+
typedef struct _MEMORY_AREA
{
PVOID StartingAddress;
@@ -272,6 +272,11 @@ typedef struct _MEMORY_AREA
PMM_SECTION_SEGMENT Segment;
LIST_ENTRY RegionListHead;
} SectionData;
+ struct
+ {
+ LARGE_INTEGER ViewOffset;
+ struct _MM_CACHE_SECTION_SEGMENT *Segment;
+ } CacheData;
struct
{
LIST_ENTRY RegionListHead;
@@ -279,6 +284,54 @@ typedef struct _MEMORY_AREA
} Data;
} MEMORY_AREA, *PMEMORY_AREA;
+typedef struct _MM_RMAP_ENTRY
+{
+ struct _MM_RMAP_ENTRY* Next;
+ PEPROCESS Process;
+ PVOID Address;
+#if DBG
+ PVOID Caller;
+#endif
+}
+MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
+
+#if MI_TRACE_PFNS
+extern ULONG MI_PFN_CURRENT_USAGE;
+extern CHAR MI_PFN_CURRENT_PROCESS_NAME[16];
+#define MI_SET_USAGE(x) MI_PFN_CURRENT_USAGE = x
+#define MI_SET_PROCESS2(x) memcpy(MI_PFN_CURRENT_PROCESS_NAME, x, 16)
+#else
+#define MI_SET_USAGE(x)
+#define MI_SET_PROCESS2(x)
+#endif
+
+typedef enum _MI_PFN_USAGES
+{
+ MI_USAGE_NOT_SET = 0,
+ MI_USAGE_PAGED_POOL,
+ MI_USAGE_NONPAGED_POOL,
+ MI_USAGE_NONPAGED_POOL_EXPANSION,
+ MI_USAGE_KERNEL_STACK,
+ MI_USAGE_KERNEL_STACK_EXPANSION,
+ MI_USAGE_SYSTEM_PTE,
+ MI_USAGE_VAD,
+ MI_USAGE_PEB_TEB,
+ MI_USAGE_SECTION,
+ MI_USAGE_PAGE_TABLE,
+ MI_USAGE_PAGE_DIRECTORY,
+ MI_USAGE_LEGACY_PAGE_DIRECTORY,
+ MI_USAGE_DRIVER_PAGE,
+ MI_USAGE_CONTINOUS_ALLOCATION,
+ MI_USAGE_MDL,
+ MI_USAGE_DEMAND_ZERO,
+ MI_USAGE_ZERO_LOOP,
+ MI_USAGE_CACHE,
+ MI_USAGE_PFN_DATABASE,
+ MI_USAGE_BOOT_DRIVER,
+ MI_USAGE_INIT_MEMORY,
+ MI_USAGE_FREE_PAGE
+} MI_PFN_USAGES;
+
//
// These two mappings are actually used by Windows itself, based on the ASSERTS
//
@@ -346,6 +399,10 @@ typedef struct _MMPFN
ULONG_PTR MustBeCached:1;
};
} u4;
+#if MI_TRACE_PFNS
+ MI_PFN_USAGES PfnUsage;
+ CHAR ProcessName[16];
+#endif
} MMPFN, *PMMPFN;
extern PMMPFN MmPfnDatabase;
@@ -429,7 +486,7 @@ typedef struct _MM_PAGED_POOL_INFO
PRTL_BITMAP EndOfPagedPoolBitmap;
PMMPTE FirstPteForPagedPool;
PMMPTE LastPteForPagedPool;
- PMMPTE NextPdeForPagedPoolExpansion;
+ PMMPDE NextPdeForPagedPoolExpansion;
ULONG PagedPoolHint;
SIZE_T PagedPoolCommit;
SIZE_T AllocatedPagedPool;
@@ -721,6 +778,10 @@ VOID
NTAPI
MmInitPagingFile(VOID);
+BOOLEAN
+NTAPI
+MmIsFileObjectAPagingFile(PFILE_OBJECT FileObject);
+
NTSTATUS
NTAPI
MmReadFromSwapPage(
@@ -1134,8 +1195,8 @@ MmInitializePageList(
VOID
NTAPI
-MmDumpPfnDatabase(
- VOID
+MmDumpArmPfnDatabase(
+ IN BOOLEAN StatusOnly
);
PFN_NUMBER
@@ -1277,6 +1338,14 @@ VOID
NTAPI
MmRawDeleteVirtualMapping(PVOID Address);
+
+VOID
+NTAPI
+MmGetPageFileMapping(
+ struct _EPROCESS *Process,
+ PVOID Address,
+ SWAPENTRY* SwapEntry);
+
VOID
NTAPI
MmDeletePageFileMapping(
@@ -1670,20 +1739,6 @@ MmCallDllInitialize(
IN PLIST_ENTRY ListHead
);
-/* ReactOS Mm Hacks */
-VOID
-FASTCALL
-MiSyncForProcessAttach(
- IN PKTHREAD NextThread,
- IN PEPROCESS Process
-);
-
-VOID
-FASTCALL
-MiSyncForContextSwitch(
- IN PKTHREAD Thread
-);
-
extern PMMSUPPORT MmKernelAddressSpace;
FORCEINLINE
diff --git a/ntoskrnl/include/internal/ntoskrnl.h b/ntoskrnl/include/internal/ntoskrnl.h
index f5354eea293..ceb4800423f 100644
--- a/ntoskrnl/include/internal/ntoskrnl.h
+++ b/ntoskrnl/include/internal/ntoskrnl.h
@@ -5,7 +5,7 @@
*/
#define PLACE_IN_SECTION(s) __attribute__((section (s)))
#ifdef __GNUC__
-#define INIT_FUNCTION PLACE_IN_SECTION("INIT")
+#define INIT_FUNCTION
#define PAGE_LOCKED_FUNCTION PLACE_IN_SECTION("pagelk")
#define PAGE_UNLOCKED_FUNCTION PLACE_IN_SECTION("pagepo")
#else
diff --git a/ntoskrnl/include/internal/po.h b/ntoskrnl/include/internal/po.h
index ef4ee1a5ff1..86e25595164 100644
--- a/ntoskrnl/include/internal/po.h
+++ b/ntoskrnl/include/internal/po.h
@@ -6,7 +6,7 @@
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
-#include "initguid.h"
+#include
#include
//
diff --git a/ntoskrnl/include/internal/ps.h b/ntoskrnl/include/internal/ps.h
index 1d55e3068ff..bf18cf818b3 100644
--- a/ntoskrnl/include/internal/ps.h
+++ b/ntoskrnl/include/internal/ps.h
@@ -399,6 +399,10 @@ PsChargeProcessPageFileQuota(
IN SIZE_T Amount
);
+BOOLEAN
+NTAPI
+PspIsProcessExiting(IN PEPROCESS Process);
+
//
// Global data inside the Process Manager
//
diff --git a/ntoskrnl/io/iomgr/arcname.c b/ntoskrnl/io/iomgr/arcname.c
index 17d242ef5c5..a49fdfc20ab 100644
--- a/ntoskrnl/io/iomgr/arcname.c
+++ b/ntoskrnl/io/iomgr/arcname.c
@@ -785,6 +785,7 @@ Cleanup:
NTSTATUS
NTAPI
+INIT_FUNCTION
IopReassignSystemRoot(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
OUT PANSI_STRING NtBootPath)
{
diff --git a/ntoskrnl/io/iomgr/controller.c b/ntoskrnl/io/iomgr/controller.c
index 5f738a593af..0ab410553cc 100644
--- a/ntoskrnl/io/iomgr/controller.c
+++ b/ntoskrnl/io/iomgr/controller.c
@@ -63,7 +63,11 @@ IoCreateController(IN ULONG Size)
PAGED_CODE();
/* Initialize an empty OBA */
- InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
/* Create the Object */
Status = ObCreateObject(KernelMode,
@@ -87,7 +91,7 @@ IoCreateController(IN ULONG Size)
if (!NT_SUCCESS(Status)) return NULL;
/* Close the dummy handle */
- NtClose(Handle);
+ ObCloseHandle(Handle, KernelMode);
/* Zero the Object and set its data */
RtlZeroMemory(Controller, sizeof(CONTROLLER_OBJECT) + Size);
diff --git a/ntoskrnl/io/iomgr/device.c b/ntoskrnl/io/iomgr/device.c
index 88e5ba4fa67..738ec9744b3 100644
--- a/ntoskrnl/io/iomgr/device.c
+++ b/ntoskrnl/io/iomgr/device.c
@@ -1731,4 +1731,15 @@ IoStartPacket(IN PDEVICE_OBJECT DeviceObject,
KeLowerIrql(OldIrql);
}
+#if defined (_WIN64)
+ULONG
+NTAPI
+IoWMIDeviceObjectToProviderId(
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ UNIMPLEMENTED;
+ return 0;
+}
+#endif
+
/* EOF */
diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c
index 1f5832c65ce..b0d35fa8fdd 100644
--- a/ntoskrnl/io/iomgr/driver.c
+++ b/ntoskrnl/io/iomgr/driver.c
@@ -709,6 +709,7 @@ MiResolveImageReferences(IN PVOID ImageBase,
//
NTSTATUS
NTAPI
+INIT_FUNCTION
LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry,
PUNICODE_STRING FileName,
PLDR_DATA_TABLE_ENTRY *ModuleObject)
@@ -784,6 +785,7 @@ LdrProcessDriverModule(PLDR_DATA_TABLE_ENTRY LdrEntry,
NTSTATUS
NTAPI
+INIT_FUNCTION
IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
{
PDEVICE_NODE DeviceNode;
@@ -870,6 +872,7 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
*/
VOID
FASTCALL
+INIT_FUNCTION
IopInitializeBootDrivers(VOID)
{
PLIST_ENTRY ListHead, NextEntry, NextEntry2;
@@ -1061,6 +1064,7 @@ IopInitializeBootDrivers(VOID)
VOID
FASTCALL
+INIT_FUNCTION
IopInitializeSystemDrivers(VOID)
{
PUNICODE_STRING *DriverList, *SavedList;
diff --git a/ntoskrnl/io/iomgr/file.c b/ntoskrnl/io/iomgr/file.c
index 46060f470b2..43686de19d6 100644
--- a/ntoskrnl/io/iomgr/file.c
+++ b/ntoskrnl/io/iomgr/file.c
@@ -1049,6 +1049,13 @@ IopDeleteFile(IN PVOID ObjectBody)
ExFreePool(FileObject->CompletionContext);
}
+ /* Check if the FO had extension */
+ if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
+ {
+ /* Release filter context structure if any */
+ FsRtlPTeardownPerFileObjectContexts(FileObject);
+ }
+
/* Check if dereference has been done yet */
if (!DereferenceDone)
{
@@ -1610,6 +1617,36 @@ IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
return Status;
}
+PVOID
+NTAPI
+IoGetFileObjectFilterContext(IN PFILE_OBJECT FileObject)
+{
+ if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION)
+ {
+ UNIMPLEMENTED;
+ /* FIXME: return NULL for the moment ~ */
+ return NULL;
+ }
+
+ return NULL;
+}
+
+NTSTATUS
+NTAPI
+IoChangeFileObjectFilterContext(IN PFILE_OBJECT FileObject,
+ IN PVOID FilterContext,
+ IN BOOLEAN Define)
+{
+ if (!(FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ UNIMPLEMENTED;
+
+ return STATUS_NOT_IMPLEMENTED;
+}
+
/* FUNCTIONS *****************************************************************/
/*
diff --git a/ntoskrnl/io/iomgr/iorsrce.c b/ntoskrnl/io/iomgr/iorsrce.c
index af5913146c6..9d52881ce12 100644
--- a/ntoskrnl/io/iomgr/iorsrce.c
+++ b/ntoskrnl/io/iomgr/iorsrce.c
@@ -841,7 +841,7 @@ IoGetConfigurationInformation(VOID)
}
/*
- * @unimplemented
+ * @halfplemented
*/
NTSTATUS NTAPI
IoReportResourceUsage(PUNICODE_STRING DriverClassName,
@@ -876,13 +876,48 @@ IoReportResourceUsage(PUNICODE_STRING DriverClassName,
* a conflict is detected with another driver.
*/
{
- UNIMPLEMENTED;
- *ConflictDetected = FALSE;
- return STATUS_SUCCESS;
+ NTSTATUS Status;
+ PCM_RESOURCE_LIST ResourceList;
+
+ DPRINT1("IoReportResourceUsage is halfplemented!\n");
+
+ if (!DriverList && !DeviceList)
+ return STATUS_INVALID_PARAMETER;
+
+ if (DeviceList)
+ ResourceList = DeviceList;
+ else
+ ResourceList = DriverList;
+
+ Status = IopDetectResourceConflict(ResourceList, FALSE, NULL);
+ if (Status == STATUS_CONFLICTING_ADDRESSES)
+ {
+ *ConflictDetected = TRUE;
+
+ if (!OverrideConflict)
+ {
+ DPRINT1("Denying an attempt to claim resources currently in use by another device!\n");
+ return STATUS_CONFLICTING_ADDRESSES;
+ }
+ else
+ {
+ DPRINT1("Proceeding with conflicting resources\n");
+ }
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* TODO: Claim resources in registry */
+
+ *ConflictDetected = FALSE;
+
+ return STATUS_SUCCESS;
}
/*
- * @unimplemented
+ * @halfplemented
*/
NTSTATUS NTAPI
IoAssignResources(PUNICODE_STRING RegistryPath,
@@ -892,8 +927,23 @@ IoAssignResources(PUNICODE_STRING RegistryPath,
PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
PCM_RESOURCE_LIST* AllocatedResources)
{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
+ NTSTATUS Status;
+
+ DPRINT1("IoAssignResources is halfplemented!\n");
+
+ Status = IopCreateResourceListFromRequirements(RequestedResources,
+ AllocatedResources);
+ if (!NT_SUCCESS(Status))
+ {
+ if (Status == STATUS_CONFLICTING_ADDRESSES)
+ DPRINT1("Denying an attempt to claim resources currently in use by another device!\n");
+
+ return Status;
+ }
+
+ /* TODO: Claim resources in registry */
+
+ return STATUS_SUCCESS;
}
/*
diff --git a/ntoskrnl/io/iomgr/irp.c b/ntoskrnl/io/iomgr/irp.c
index 55d316adf55..54179a6d317 100644
--- a/ntoskrnl/io/iomgr/irp.c
+++ b/ntoskrnl/io/iomgr/irp.c
@@ -1816,3 +1816,14 @@ IoSetTopLevelIrp(IN PIRP Irp)
/* Set the IRP */
PsGetCurrentThread()->TopLevelIrp = (ULONG_PTR)Irp;
}
+
+#if defined (_WIN64)
+BOOLEAN
+NTAPI
+IoIs32bitProcess(
+ IN PIRP Irp OPTIONAL)
+{
+#pragma message IoIs32bitProcess is hardcoded to FALSE
+ return FALSE;
+}
+#endif
diff --git a/ntoskrnl/io/iomgr/ramdisk.c b/ntoskrnl/io/iomgr/ramdisk.c
index eec4f8d801a..3ca2d0351d8 100644
--- a/ntoskrnl/io/iomgr/ramdisk.c
+++ b/ntoskrnl/io/iomgr/ramdisk.c
@@ -24,6 +24,7 @@
NTSTATUS
NTAPI
+INIT_FUNCTION
IopStartRamdisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
diff --git a/ntoskrnl/io/iomgr/rawfs.c b/ntoskrnl/io/iomgr/rawfs.c
index 32c396f712e..143f486977c 100755
--- a/ntoskrnl/io/iomgr/rawfs.c
+++ b/ntoskrnl/io/iomgr/rawfs.c
@@ -1076,6 +1076,7 @@ RawUnload(IN PDRIVER_OBJECT DriverObject)
NTSTATUS
NTAPI
+INIT_FUNCTION
RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
diff --git a/ntoskrnl/io/pnpmgr/pnpinit.c b/ntoskrnl/io/pnpmgr/pnpinit.c
index deced326832..7811632dd5c 100644
--- a/ntoskrnl/io/pnpmgr/pnpinit.c
+++ b/ntoskrnl/io/pnpmgr/pnpinit.c
@@ -44,6 +44,7 @@ IopInitializeArbiters(VOID)
NTSTATUS
NTAPI
+INIT_FUNCTION
PiInitCacheGroupInformation(VOID)
{
HANDLE KeyHandle;
@@ -355,6 +356,7 @@ PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
NTSTATUS
NTAPI
+INIT_FUNCTION
IopInitializePlugPlayServices(VOID)
{
NTSTATUS Status;
diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c
index 69e013caefc..cfdad1d741a 100644
--- a/ntoskrnl/io/pnpmgr/pnpmgr.c
+++ b/ntoskrnl/io/pnpmgr/pnpmgr.c
@@ -2606,6 +2606,7 @@ cleanup:
NTSTATUS
NTAPI
+INIT_FUNCTION
IopUpdateRootKey(VOID)
{
UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c
index 165b0b06f59..94a20dc18ce 100644
--- a/ntoskrnl/io/pnpmgr/pnpreport.c
+++ b/ntoskrnl/io/pnpmgr/pnpreport.c
@@ -38,9 +38,6 @@ NTSTATUS
IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
PVOID Context);
-NTSTATUS
-IopDetectResourceConflict(IN PCM_RESOURCE_LIST ResourceList);
-
NTSTATUS
PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject,
IN OUT PKEVENT SyncEvent OPTIONAL,
@@ -379,7 +376,7 @@ IoReportResourceForDetection(IN PDRIVER_OBJECT DriverObject,
ResourceList = DriverList;
/* Look for a resource conflict */
- Status = IopDetectResourceConflict(ResourceList);
+ Status = IopDetectResourceConflict(ResourceList, FALSE, NULL);
if (Status == STATUS_CONFLICTING_ADDRESSES)
{
/* Oh noes */
diff --git a/ntoskrnl/io/pnpmgr/pnpres.c b/ntoskrnl/io/pnpmgr/pnpres.c
index 71319f8abd1..733440dd5fb 100644
--- a/ntoskrnl/io/pnpmgr/pnpres.c
+++ b/ntoskrnl/io/pnpmgr/pnpres.c
@@ -12,12 +12,6 @@
#define NDEBUG
#include
-NTSTATUS
-IopDetectResourceConflict(
- IN PCM_RESOURCE_LIST ResourceList,
- IN BOOLEAN Silent,
- OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor);
-
static
BOOLEAN
IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
@@ -187,8 +181,8 @@ IopFindInterruptResource(
return FALSE;
}
-static
-NTSTATUS
+
+NTSTATUS NTAPI
IopCreateResourceListFromRequirements(
IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
OUT PCM_RESOURCE_LIST *ResourceList)
@@ -336,9 +330,6 @@ IopCheckResourceDescriptor(
ULONG i, ii;
BOOLEAN Result = FALSE;
- if (ResDesc->ShareDisposition == CmResourceShareShared)
- return FALSE;
-
for (i = 0; i < ResourceList->Count; i++)
{
PCM_PARTIAL_RESOURCE_LIST ResList = &ResourceList->List[i].PartialResourceList;
@@ -615,40 +606,61 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2
if (DeviceNode->ResourceList)
{
- PWCHAR DeviceName = NULL;
UNICODE_STRING NameU;
- UNICODE_STRING Suffix;
+ UNICODE_STRING RawSuffix, TranslatedSuffix;
ULONG OldLength = 0;
ASSERT(DeviceNode->ResourceListTranslated);
+
+ RtlInitUnicodeString(&TranslatedSuffix, L".Translated");
+ RtlInitUnicodeString(&RawSuffix, L".Raw");
Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
DevicePropertyPhysicalDeviceObjectName,
0,
NULL,
&OldLength);
- if ((OldLength != 0) && (Status == STATUS_BUFFER_TOO_SMALL))
- {
- DeviceName = ExAllocatePool(NonPagedPool, OldLength);
- ASSERT(DeviceName);
+ if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ ASSERT(OldLength);
+
+ NameU.Buffer = ExAllocatePool(PagedPool, OldLength + TranslatedSuffix.Length);
+ if (!NameU.Buffer)
+ {
+ ZwClose(PnpMgrLevel2);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ NameU.Length = 0;
+ NameU.MaximumLength = OldLength + TranslatedSuffix.Length;
+
+ Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
+ DevicePropertyPhysicalDeviceObjectName,
+ NameU.MaximumLength,
+ NameU.Buffer,
+ &OldLength);
+ if (!NT_SUCCESS(Status))
+ {
+ ZwClose(PnpMgrLevel2);
+ ExFreePool(NameU.Buffer);
+ return Status;
+ }
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ /* Some failure */
+ ZwClose(PnpMgrLevel2);
+ return Status;
+ }
+ else
+ {
+ /* This should never happen */
+ ASSERT(FALSE);
+ }
+
+ NameU.Length = OldLength;
- IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
- DevicePropertyPhysicalDeviceObjectName,
- OldLength,
- DeviceName,
- &OldLength);
-
- RtlInitUnicodeString(&NameU, DeviceName);
- }
- else
- {
- /* Some failure */
- ASSERT(!NT_SUCCESS(Status));
- return Status;
- }
-
- RtlInitUnicodeString(&Suffix, L".Raw");
- RtlAppendUnicodeStringToString(&NameU, &Suffix);
+ RtlAppendUnicodeStringToString(&NameU, &RawSuffix);
Status = ZwSetValueKey(PnpMgrLevel2,
&NameU,
@@ -659,14 +671,14 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2
if (!NT_SUCCESS(Status))
{
ZwClose(PnpMgrLevel2);
+ ExFreePool(NameU.Buffer);
return Status;
}
/* "Remove" the suffix by setting the length back to what it used to be */
- NameU.Length = (USHORT)OldLength;
+ NameU.Length = OldLength;
- RtlInitUnicodeString(&Suffix, L".Translated");
- RtlAppendUnicodeStringToString(&NameU, &Suffix);
+ RtlAppendUnicodeStringToString(&NameU, &TranslatedSuffix);
Status = ZwSetValueKey(PnpMgrLevel2,
&NameU,
@@ -675,8 +687,8 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2
DeviceNode->ResourceListTranslated,
PnpDetermineResourceListSize(DeviceNode->ResourceListTranslated));
ZwClose(PnpMgrLevel2);
- ASSERT(DeviceName);
- ExFreePool(DeviceName);
+ ExFreePool(NameU.Buffer);
+
if (!NT_SUCCESS(Status))
return Status;
}
@@ -718,7 +730,7 @@ IopTranslateDeviceResources(
DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize);
if (!DeviceNode->ResourceListTranslated)
{
- Status =STATUS_NO_MEMORY;
+ Status = STATUS_NO_MEMORY;
goto cleanup;
}
RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, ListSize);
@@ -743,6 +755,7 @@ IopTranslateDeviceResources(
&DescriptorTranslated->u.Port.Start))
{
Status = STATUS_UNSUCCESSFUL;
+ DPRINT1("Failed to translate port resource (Start: 0xI64x)\n", DescriptorRaw->u.Port.Start.QuadPart);
goto cleanup;
}
break;
@@ -756,6 +769,14 @@ IopTranslateDeviceResources(
DescriptorRaw->u.Interrupt.Vector,
(PKIRQL)&DescriptorTranslated->u.Interrupt.Level,
&DescriptorTranslated->u.Interrupt.Affinity);
+
+ if (!DescriptorTranslated->u.Interrupt.Vector)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ DPRINT1("Failed to translate interrupt resource (Vector: 0x%x | Level: 0x%x)\n", DescriptorRaw->u.Interrupt.Vector,
+ DescriptorRaw->u.Interrupt.Level);
+ goto cleanup;
+ }
break;
}
case CmResourceTypeMemory:
@@ -769,6 +790,7 @@ IopTranslateDeviceResources(
&DescriptorTranslated->u.Memory.Start))
{
Status = STATUS_UNSUCCESSFUL;
+ DPRINT1("Failed to translate memory resource (Start: 0xI64x)\n", DescriptorRaw->u.Memory.Start.QuadPart);
goto cleanup;
}
}
@@ -864,16 +886,21 @@ IopAssignDeviceResources(
Status = IopCreateResourceListFromRequirements(DeviceNode->ResourceRequirements,
&DeviceNode->ResourceList);
if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create a resource list from supplied resources for %wZ\n", &DeviceNode->InstancePath);
goto ByeBye;
+ }
- Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL);
- if (!NT_SUCCESS(Status))
- goto ByeBye;
+ /* IopCreateResourceListFromRequirements should NEVER succeed with a conflicting list */
+ ASSERT(IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL) != STATUS_CONFLICTING_ADDRESSES);
Finish:
Status = IopTranslateDeviceResources(DeviceNode);
if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to translate resources for %wZ\n", &DeviceNode->InstancePath);
goto ByeBye;
+ }
Status = IopUpdateResourceMapForPnPDevice(DeviceNode);
if (!NT_SUCCESS(Status))
@@ -935,7 +962,7 @@ ByeBye:
return Result;
}
-NTSTATUS
+NTSTATUS NTAPI
IopDetectResourceConflict(
IN PCM_RESOURCE_LIST ResourceList,
IN BOOLEAN Silent,
diff --git a/ntoskrnl/kd/kdinit.c b/ntoskrnl/kd/kdinit.c
index 5fcc0ee8cd2..3e7b53e4057 100644
--- a/ntoskrnl/kd/kdinit.c
+++ b/ntoskrnl/kd/kdinit.c
@@ -44,6 +44,7 @@ PKDP_INIT_ROUTINE InitRoutines[KdMax] = {KdpScreenInit,
PCHAR
NTAPI
+INIT_FUNCTION
KdpGetDebugMode(PCHAR Currentp2)
{
PCHAR p2 = Currentp2;
@@ -118,6 +119,7 @@ KdpGetDebugMode(PCHAR Currentp2)
VOID
NTAPI
+INIT_FUNCTION
KdpCallInitRoutine(ULONG BootPhase)
{
PLIST_ENTRY CurrentEntry;
diff --git a/ntoskrnl/kd/kdio.c b/ntoskrnl/kd/kdio.c
index db48c31e227..4c18d4c721d 100644
--- a/ntoskrnl/kd/kdio.c
+++ b/ntoskrnl/kd/kdio.c
@@ -134,6 +134,7 @@ KdpPrintToLogFile(PCH String,
VOID
NTAPI
+INIT_FUNCTION
KdpInitDebugLog(PKD_DISPATCH_TABLE DispatchTable,
ULONG BootPhase)
{
diff --git a/ntoskrnl/kd/kdmain.c b/ntoskrnl/kd/kdmain.c
index 0d649112016..6b16582735a 100644
--- a/ntoskrnl/kd/kdmain.c
+++ b/ntoskrnl/kd/kdmain.c
@@ -72,8 +72,8 @@ KdpServiceDispatcher(ULONG Service,
DbgBreakPoint();
break;
- case ThatsWhatSheSaid:
- MmDumpPfnDatabase();
+ case KdSpare3:
+ MmDumpArmPfnDatabase(FALSE);
break;
default:
diff --git a/ntoskrnl/kd64/kdinit.c b/ntoskrnl/kd64/kdinit.c
index 542b8ded5d8..9fb10a86878 100644
--- a/ntoskrnl/kd64/kdinit.c
+++ b/ntoskrnl/kd64/kdinit.c
@@ -70,6 +70,7 @@ KdRegisterDebuggerDataBlock(IN ULONG Tag,
BOOLEAN
NTAPI
+INIT_FUNCTION
KdInitSystem(IN ULONG BootPhase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
diff --git a/ntoskrnl/kdbg/amd64/kdb_help.S b/ntoskrnl/kdbg/amd64/kdb_help.S
index eb777010513..eca6dcfbdac 100644
--- a/ntoskrnl/kdbg/amd64/kdb_help.S
+++ b/ntoskrnl/kdbg/amd64/kdb_help.S
@@ -1,7 +1,9 @@
-#include
-#include
-.globl KdbEnter
+#include
+
+#include
+
+PUBLIC KdbEnter
KdbEnter:
/* save flags */
@@ -149,4 +151,6 @@ KdbpStackSwitchAndCall:
mov rsp, rax
/* Return */
- ret
\ No newline at end of file
+ ret
+
+END
\ No newline at end of file
diff --git a/ntoskrnl/kdbg/i386/kdb_help.S b/ntoskrnl/kdbg/i386/kdb_help.S
index 00cb522c17c..e586f14c5e7 100644
--- a/ntoskrnl/kdbg/i386/kdb_help.S
+++ b/ntoskrnl/kdbg/i386/kdb_help.S
@@ -1,68 +1,72 @@
-#include
-.text
+#include
+#include
-.globl _KdbEnter
+EXTERN _KdbEnterDebuggerException:PROC
+
+.code
+
+PUBLIC _KdbEnter
_KdbEnter:
/*
* Set up a trap frame
*/
- pushfl /* Eflags */
- pushl %cs /* Cs */
- pushl $0 /* ErrorCode */
- pushl %ebp /* Ebp */
- pushl %ebx /* Ebx */
- movl 20(%esp), %ebp /* Eip */
- movl 16(%esp), %ebx /* Eflags */
- movl %ebx, 20(%esp)
- movl 12(%esp), %ebx /* Cs */
- movl %ebx, 16(%esp)
- movl %ebp, 12(%esp)
- pushl %esi /* Esi */
- pushl %edi /* Edi */
- pushl %fs /* Fs */
- pushl $0 /* ExceptionList */
- pushl $0 /* PreviousMode */
- pushl %eax /* Eax */
- pushl %ecx /* Ecx */
- pushl %edx /* Edx */
- pushl %ds /* Ds */
- pushl %es /* Es */
- pushl %gs /* Gs */
- movl %dr7, %eax
- pushl %eax /* Dr7 */
+ pushf /* Eflags */
+ push cs /* Cs */
+ push 0 /* ErrorCode */
+ push ebp /* Ebp */
+ push ebx /* Ebx */
+ mov ebp, [esp + 20] /* Eip */
+ mov ebx, [esp + 16] /* Eflags */
+ mov [esp + 20], ebx
+ mov ebx, [esp + 12] /* Cs */
+ mov [esp + 16], ebx
+ mov [esp + 12], ebp
+ push esi /* Esi */
+ push edi /* Edi */
+ push fs /* Fs */
+ push 0 /* ExceptionList */
+ push 0 /* PreviousMode */
+ push eax /* Eax */
+ push ecx /* Ecx */
+ push edx /* Edx */
+ push ds /* Ds */
+ push es /* Es */
+ push gs /* Gs */
+ mov eax, dr7
+ push eax /* Dr7 */
/* Clear all breakpoint enables in dr7. */
- andl $0xFFFF0000, %eax
- movl %eax, %dr7
- movl %dr6, %eax
- pushl %eax /* Dr6 */
- movl %dr3, %eax
- pushl %eax /* Dr3 */
- movl %dr2, %eax
- pushl %eax /* Dr2 */
- movl %dr1, %eax
- pushl %eax /* Dr1 */
- movl %dr0, %eax
- pushl %eax /* Dr0 */
- leal 0x58(%esp), %eax
- pushl %eax /* TempEsp */
- pushl %ss /* TempSegSs */
- pushl $0 /* DebugPointer */
- pushl $3 /* DebugArgMark (Exception number) */
- pushl 0x60(%esp) /* DebugEip */
- pushl %ebp /* DebugEbp */
+ and eax, HEX(0FFFF0000)
+ mov dr7, eax
+ mov eax, dr6
+ push eax /* Dr6 */
+ mov eax, dr3
+ push eax /* Dr3 */
+ mov eax, dr2
+ push eax /* Dr2 */
+ mov eax, dr1
+ push eax /* Dr1 */
+ mov eax, dr0
+ push eax /* Dr0 */
+ lea eax, [esp + HEX(58)]
+ push eax /* TempEsp */
+ push ss /* TempSegSs */
+ push 0 /* DebugPointer */
+ push 3 /* DebugArgMark (Exception number) */
+ push [esp + HEX(60)] /* DebugEip */
+ push ebp /* DebugEbp */
/*
* Call KDB
*/
- movl %esp, %eax
- pushl $1 /* FirstChance */
- pushl %eax /* Push a pointer to the trap frame */
- pushl $0 /* Context */
- pushl $0 /* PreviousMode (KernelMode) */
- pushl $0 /* ExceptionRecord */
- call _KdbEnterDebuggerException
+ mov eax, esp
+ push 1 /* FirstChance */
+ push eax /* Push a pointer to the trap frame */
+ push 0 /* Context */
+ push 0 /* PreviousMode (KernelMode) */
+ push 0 /* ExceptionRecord */
+ call _KdbEnterDebuggerException
/*
* Pop the arguments and unused portions of the trap frame:
@@ -73,41 +77,41 @@ _KdbEnter:
* TempSegSs
* TempEsp
*/
- addl $(11*4), %esp
+ add esp, 11*4
/*
* Restore/update debugging registers.
*/
- popl %eax /* Dr0 */
- movl %eax, %dr0
- popl %eax /* Dr1 */
- movl %eax, %dr1
- popl %eax /* Dr2 */
- movl %eax, %dr2
- popl %eax /* Dr3 */
- movl %eax, %dr3
- popl %eax /* Dr6 */
- movl %eax, %dr6
- popl %eax /* Dr7 */
- movl %eax, %dr7
+ pop eax /* Dr0 */
+ mov dr0, eax
+ pop eax /* Dr1 */
+ mov dr1, eax
+ pop eax /* Dr2 */
+ mov dr2, eax
+ pop eax /* Dr3 */
+ mov dr3, eax
+ pop eax /* Dr6 */
+ mov dr6, eax
+ pop eax /* Dr7 */
+ mov dr7, eax
/*
* Restore registers including any that might have been changed
* inside the debugger.
*/
- popl %gs /* Gs */
- popl %es /* Es */
- popl %ds /* Ds */
- popl %edx /* Edx */
- popl %ecx /* Ecx */
- popl %eax /* Eax */
- addl $8, %esp /* PreviousMode, ExceptionList */
- popl %fs /* Fs */
- popl %edi /* Edi */
- popl %esi /* Esi */
- popl %ebx /* Ebx */
- popl %ebp /* Ebp */
- addl $4, %esp /* ErrorCode */
+ pop gs /* Gs */
+ pop es /* Es */
+ pop ds /* Ds */
+ pop edx /* Edx */
+ pop ecx /* Ecx */
+ pop eax /* Eax */
+ add esp, 8 /* PreviousMode, ExceptionList */
+ pop fs /* Fs */
+ pop edi /* Edi */
+ pop esi /* Esi */
+ pop ebx /* Ebx */
+ pop ebp /* Ebp */
+ add esp, 4 /* ErrorCode */
/*
* Return to the caller.
@@ -115,26 +119,27 @@ _KdbEnter:
iret
-.globl _KdbpStackSwitchAndCall@8
+PUBLIC _KdbpStackSwitchAndCall@8
_KdbpStackSwitchAndCall@8:
- pushl %ebp
- movl %esp, %ebp
+ push ebp
+ mov ebp, esp
- movl 0x8(%esp), %eax /* New stack */
- movl 0xC(%esp), %ecx /* Function to call */
- movl %esp, %edx /* Old stack */
+ mov eax, [esp + 8] /* New stack */
+ mov ecx, [esp + 12] /* Function to call */
+ mov edx, esp /* Old stack */
/* Switch stack */
- movl %eax, %esp
- pushl %edx
+ mov esp, eax
+ push edx
/* Call function */
- call *%ecx
+ call ecx
/* Switch back to old stack */
- popl %esp
+ pop esp
/* Return */
- popl %ebp
- ret $8
+ pop ebp
+ ret 8
+END
diff --git a/ntoskrnl/kdbg/kdb.c b/ntoskrnl/kdbg/kdb.c
index bc7e01864b0..67037f6829d 100644
--- a/ntoskrnl/kdbg/kdb.c
+++ b/ntoskrnl/kdbg/kdb.c
@@ -1695,6 +1695,7 @@ continue_execution:
VOID
NTAPI
+INIT_FUNCTION
KdbpGetCommandLineSettings(
PCHAR p1)
{
diff --git a/ntoskrnl/ke/amd64/boot.S b/ntoskrnl/ke/amd64/boot.S
index f1715c6663e..4efbef3f94a 100644
--- a/ntoskrnl/ke/amd64/boot.S
+++ b/ntoskrnl/ke/amd64/boot.S
@@ -2,14 +2,14 @@
* FILE: ntoskrnl/ke/i386/boot.S
* COPYRIGHT: See COPYING in the top level directory
* PURPOSE: FreeLDR Wrapper Bootstrap Code and Bootstrap Trampoline
- * PROGRAMMERs: Alex Ionescu (alex@relsoft.net)
- * Thomas Weidenmueller
+ * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+
+#include
EXTERN KiInitializeKernelAndGotoIdleLoop:PROC
diff --git a/ntoskrnl/ke/amd64/ctxswitch.S b/ntoskrnl/ke/amd64/ctxswitch.S
index 61ce1473e53..1c9b13e5737 100644
--- a/ntoskrnl/ke/amd64/ctxswitch.S
+++ b/ntoskrnl/ke/amd64/ctxswitch.S
@@ -9,8 +9,9 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+
+#include
/* FUNCTIONS ****************************************************************/
diff --git a/ntoskrnl/ke/amd64/trap.S b/ntoskrnl/ke/amd64/trap.S
index 532f6bbdb91..2b95b42894d 100644
--- a/ntoskrnl/ke/amd64/trap.S
+++ b/ntoskrnl/ke/amd64/trap.S
@@ -7,8 +7,9 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+
+#include
EXTERN KiDispatchException:PROC
EXTERN FrLdrDbgPrint:DWORD
diff --git a/ntoskrnl/ke/arm/boot.s b/ntoskrnl/ke/arm/boot.s
index eff065cacbc..5bce7356a16 100644
--- a/ntoskrnl/ke/arm/boot.s
+++ b/ntoskrnl/ke/arm/boot.s
@@ -15,7 +15,10 @@
PROLOG_END KiSystemStartup
/* Put us in FIQ mode, set IRQ stack */
- msr cpsr_c, #CPSR_FIQ_MODE
+ b .
+ mrs r3, cpsr
+ orr r3, r1, #CPSR_FIQ_MODE
+ msr cpsr, r3
ldr sp, [a1, #LpbInterruptStack]
/* Repeat for IRQ mode */
diff --git a/ntoskrnl/ke/arm/cpu.c b/ntoskrnl/ke/arm/cpu.c
index 275df6c3854..37d8a1569fd 100644
--- a/ntoskrnl/ke/arm/cpu.c
+++ b/ntoskrnl/ke/arm/cpu.c
@@ -57,6 +57,15 @@ KeFlushCurrentTb(VOID)
KeFlushTb();
}
+VOID
+FASTCALL
+KeZeroPages(IN PVOID Address,
+ IN ULONG Size)
+{
+ /* Not using XMMI in this routine */
+ RtlZeroMemory(Address, Size);
+}
+
VOID
NTAPI
KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
diff --git a/ntoskrnl/ke/arm/ctxswtch.s b/ntoskrnl/ke/arm/ctxswtch.s
index a8f391f8ec3..0d6bb54f27c 100644
--- a/ntoskrnl/ke/arm/ctxswtch.s
+++ b/ntoskrnl/ke/arm/ctxswtch.s
@@ -13,6 +13,10 @@
TEXTAREA
NESTED_ENTRY KiSwapContext
PROLOG_END KiSwapContext
+
+ // BUSTEDDDD
+ b .
+
//
// a1 = Old Thread
// a2 = New Thread
@@ -104,3 +108,19 @@
b .
ENTRY_END KiThreadStartup
+
+ NESTED_ENTRY KiSwitchThreads
+ PROLOG_END KiSwitchThreads
+
+ // BUSTEDDDD
+ b .
+
+ ENTRY_END KiSwitchThreads
+
+ NESTED_ENTRY KiSwapContextInternal
+ PROLOG_END KiSwapContextInternal
+
+ // BUSTEDDDD
+ b .
+
+ ENTRY_END KiSwapContextInternal
diff --git a/ntoskrnl/ke/arm/thrdini.c b/ntoskrnl/ke/arm/thrdini.c
index 16700f54470..cae9b75deb1 100644
--- a/ntoskrnl/ke/arm/thrdini.c
+++ b/ntoskrnl/ke/arm/thrdini.c
@@ -14,6 +14,13 @@
/* GLOBALS ********************************************************************/
+typedef struct _KSWITCHFRAME
+{
+ PVOID ExceptionList;
+ BOOLEAN ApcBypassDisable;
+ PVOID RetAddr;
+} KSWITCHFRAME, *PKSWITCHFRAME;
+
typedef struct _KUINIT_FRAME
{
KEXCEPTION_FRAME CtxSwitchFrame;
@@ -32,6 +39,15 @@ VOID
NTAPI
KiThreadStartup(VOID);
+VOID
+FASTCALL
+KiSwitchThreads(
+ IN PKTHREAD OldThread,
+ IN PKTHREAD NewThread
+);
+
+
+/* FIXME: THIS IS TOTALLY BUSTED NOW */
VOID
NTAPI
KiInitializeContextThread(IN PKTHREAD Thread,
@@ -131,3 +147,217 @@ KiInitializeContextThread(IN PKTHREAD Thread,
//
Thread->KernelStack = (PVOID)CtxSwitchFrame;
}
+
+VOID
+FASTCALL
+KiIdleLoop(VOID)
+{
+ PKPRCB Prcb = KeGetCurrentPrcb();
+ PKTHREAD OldThread, NewThread;
+
+ /* Initialize the idle loop: disable interrupts */
+ _enable();
+ YieldProcessor();
+ YieldProcessor();
+ _disable();
+
+ /* Now loop forever */
+ while (TRUE)
+ {
+ /* Check for pending timers, pending DPCs, or pending ready threads */
+ if ((Prcb->DpcData[0].DpcQueueDepth) ||
+ (Prcb->TimerRequest) ||
+ (Prcb->DeferredReadyListHead.Next))
+ {
+ /* Quiesce the DPC software interrupt */
+ HalClearSoftwareInterrupt(DISPATCH_LEVEL);
+
+ /* Handle it */
+ KiRetireDpcList(Prcb);
+ }
+
+ /* Check if a new thread is scheduled for execution */
+ if (Prcb->NextThread)
+ {
+ /* Enable interupts */
+ _enable();
+
+ /* Capture current thread data */
+ OldThread = Prcb->CurrentThread;
+ NewThread = Prcb->NextThread;
+
+ /* Set new thread data */
+ Prcb->NextThread = NULL;
+ Prcb->CurrentThread = NewThread;
+
+ /* The thread is now running */
+ NewThread->State = Running;
+
+ /* Switch away from the idle thread */
+ KiSwapContext(APC_LEVEL, OldThread);
+
+ /* We are back in the idle thread -- disable interrupts again */
+ _enable();
+ YieldProcessor();
+ YieldProcessor();
+ _disable();
+ }
+ else
+ {
+ /* Continue staying idle. Note the HAL returns with interrupts on */
+ Prcb->PowerState.IdleFunction(&Prcb->PowerState);
+ }
+ }
+}
+
+BOOLEAN
+FASTCALL
+KiSwapContextExit(IN PKTHREAD OldThread,
+ IN PKSWITCHFRAME SwitchFrame)
+{
+ PKIPCR Pcr = (PKIPCR)KeGetPcr();
+ PKPROCESS OldProcess, NewProcess;
+ PKTHREAD NewThread;
+ ARM_TTB_REGISTER TtbRegister;
+
+ /* We are on the new thread stack now */
+ NewThread = Pcr->PrcbData.CurrentThread;
+
+ /* Now we are the new thread. Check if it's in a new process */
+ OldProcess = OldThread->ApcState.Process;
+ NewProcess = NewThread->ApcState.Process;
+ if (OldProcess != NewProcess)
+ {
+ TtbRegister.AsUlong = NewProcess->DirectoryTableBase[0];
+ ASSERT(TtbRegister.Reserved == 0);
+ KeArmTranslationTableRegisterSet(TtbRegister);
+ }
+
+ /* Increase thread context switches */
+ NewThread->ContextSwitches++;
+
+ /* Load data from switch frame */
+ Pcr->NtTib.ExceptionList = SwitchFrame->ExceptionList;
+
+ /* DPCs shouldn't be active */
+ if (Pcr->PrcbData.DpcRoutineActive)
+ {
+ /* Crash the machine */
+ KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC,
+ (ULONG_PTR)OldThread,
+ (ULONG_PTR)NewThread,
+ (ULONG_PTR)OldThread->InitialStack,
+ 0);
+ }
+
+ /* Kernel APCs may be pending */
+ if (NewThread->ApcState.KernelApcPending)
+ {
+ /* Are APCs enabled? */
+ if (!NewThread->SpecialApcDisable)
+ {
+ /* Request APC delivery */
+ if (SwitchFrame->ApcBypassDisable) HalRequestSoftwareInterrupt(APC_LEVEL);
+ return TRUE;
+ }
+ }
+
+ /* Return */
+ return FALSE;
+}
+
+VOID
+FASTCALL
+KiSwapContextEntry(IN PKSWITCHFRAME SwitchFrame,
+ IN ULONG_PTR OldThreadAndApcFlag)
+{
+ PKIPCR Pcr = (PKIPCR)KeGetPcr();
+ PKTHREAD OldThread, NewThread;
+
+ /* Save APC bypass disable */
+ SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3;
+ SwitchFrame->ExceptionList = Pcr->NtTib.ExceptionList;
+
+ /* Increase context switch count and check if tracing is enabled */
+ Pcr->ContextSwitches++;
+ if (Pcr->PerfGlobalGroupMask)
+ {
+ /* We don't support this yet on x86 either */
+ DPRINT1("WMI Tracing not supported\n");
+ ASSERT(FALSE);
+ }
+
+ /* Get thread pointers */
+ OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3);
+ NewThread = Pcr->PrcbData.CurrentThread;
+
+ /* Get the old thread and set its kernel stack */
+ OldThread->KernelStack = SwitchFrame;
+
+ /* Do the switch */
+ KiSwitchThreads(OldThread, NewThread->KernelStack);
+}
+
+VOID
+NTAPI
+KiDispatchInterrupt(VOID)
+{
+ PKIPCR Pcr = (PKIPCR)KeGetPcr();
+ PKPRCB Prcb = &Pcr->PrcbData;
+ PVOID OldHandler;
+ PKTHREAD NewThread, OldThread;
+
+ /* Disable interrupts */
+ _disable();
+
+ /* Check for pending timers, pending DPCs, or pending ready threads */
+ if ((Prcb->DpcData[0].DpcQueueDepth) ||
+ (Prcb->TimerRequest) ||
+ (Prcb->DeferredReadyListHead.Next))
+ {
+ /* Switch to safe execution context */
+ OldHandler = Pcr->NtTib.ExceptionList;
+ Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
+
+ /* Retire DPCs while under the DPC stack */
+ //KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack);
+ // FIXME!!! //
+ KiRetireDpcList(Prcb);
+
+ /* Restore context */
+ Pcr->NtTib.ExceptionList = OldHandler;
+ }
+
+ /* Re-enable interrupts */
+ _enable();
+
+ /* Check for quantum end */
+ if (Prcb->QuantumEnd)
+ {
+ /* Handle quantum end */
+ Prcb->QuantumEnd = FALSE;
+ KiQuantumEnd();
+ }
+ else if (Prcb->NextThread)
+ {
+ /* Capture current thread data */
+ OldThread = Prcb->CurrentThread;
+ NewThread = Prcb->NextThread;
+
+ /* Set new thread data */
+ Prcb->NextThread = NULL;
+ Prcb->CurrentThread = NewThread;
+
+ /* The thread is now running */
+ NewThread->State = Running;
+ OldThread->WaitReason = WrDispatchInt;
+
+ /* Make the old thread ready */
+ KxQueueReadyThread(OldThread, Prcb);
+
+ /* Swap to the new thread */
+ KiSwapContext(APC_LEVEL, OldThread);
+ }
+}
+
+/* EOF */
diff --git a/ntoskrnl/ke/arm/trapc.c b/ntoskrnl/ke/arm/trapc.c
index edfedf42820..9f731bb578b 100644
--- a/ntoskrnl/ke/arm/trapc.c
+++ b/ntoskrnl/ke/arm/trapc.c
@@ -15,6 +15,7 @@
/* FUNCTIONS ******************************************************************/
+#if 0
VOID
KiIdleLoop(VOID)
{
@@ -89,6 +90,7 @@ KiIdleLoop(VOID)
}
}
}
+#endif
VOID
NTAPI
@@ -116,6 +118,7 @@ KiSwapProcess(IN PKPROCESS NewProcess,
while (TRUE);
}
+#if 0
BOOLEAN
KiSwapContextInternal(IN PKTHREAD OldThread,
IN PKTHREAD NewThread)
@@ -220,6 +223,7 @@ KiSwapContextInternal(IN PKTHREAD OldThread,
//
return FALSE;
}
+#endif
VOID
KiApcInterrupt(VOID)
@@ -262,6 +266,7 @@ KiApcInterrupt(VOID)
KiDeliverApc(PreviousMode, &ExceptionFrame, TrapFrame);
}
+#if 0
VOID
KiDispatchInterrupt(VOID)
{
@@ -343,6 +348,7 @@ KiDispatchInterrupt(VOID)
KiSwapContext(OldThread, NewThread);
}
}
+#endif
VOID
KiInterruptHandler(IN PKTRAP_FRAME TrapFrame,
@@ -523,7 +529,7 @@ KiDataAbortHandler(IN PKTRAP_FRAME TrapFrame)
Address,
KiGetPreviousMode(TrapFrame),
TrapFrame);
- if (Status == STATUS_SUCCESS) return Status;
+ if (NT_SUCCESS(Status)) return Status;
}
//
diff --git a/ntoskrnl/ke/config.c b/ntoskrnl/ke/config.c
index 5f9a196d032..ae01ca87368 100644
--- a/ntoskrnl/ke/config.c
+++ b/ntoskrnl/ke/config.c
@@ -19,6 +19,7 @@
*/
PCONFIGURATION_COMPONENT_DATA
NTAPI
+INIT_FUNCTION
KeFindConfigurationEntry(IN PCONFIGURATION_COMPONENT_DATA Child,
IN CONFIGURATION_CLASS Class,
IN CONFIGURATION_TYPE Type,
@@ -39,6 +40,7 @@ KeFindConfigurationEntry(IN PCONFIGURATION_COMPONENT_DATA Child,
*/
PCONFIGURATION_COMPONENT_DATA
NTAPI
+INIT_FUNCTION
KeFindConfigurationNextEntry(IN PCONFIGURATION_COMPONENT_DATA Child,
IN CONFIGURATION_CLASS Class,
IN CONFIGURATION_TYPE Type,
diff --git a/ntoskrnl/ke/dpc.c b/ntoskrnl/ke/dpc.c
index 7b4446a543b..9895cae3f27 100644
--- a/ntoskrnl/ke/dpc.c
+++ b/ntoskrnl/ke/dpc.c
@@ -534,7 +534,7 @@ KiQuantumEnd(VOID)
Thread->WaitIrql = APC_LEVEL;
/* Swap threads */
- KiSwapContext(Thread, NextThread);
+ KiSwapContext(APC_LEVEL, Thread);
/* Lower IRQL back to DISPATCH_LEVEL */
KeLowerIrql(DISPATCH_LEVEL);
diff --git a/ntoskrnl/ke/freeldr.c b/ntoskrnl/ke/freeldr.c
index 7e67916a7ff..9dfc8eb9e07 100644
--- a/ntoskrnl/ke/freeldr.c
+++ b/ntoskrnl/ke/freeldr.c
@@ -8,6 +8,8 @@
/* INCLUDES *****************************************************************/
+#if !defined(_X86_)
+
#include
#define NDEBUG
#include
@@ -1204,14 +1206,10 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
0,
&Base);
- //
- // Check if we have a ramdisk
- //
+ /* Check if we have a ramdisk */
if ((RosLoaderBlock->RdAddr) && (RosLoaderBlock->RdLength))
{
- //
- // Build a descriptor for it
- //
+ /* Build a descriptor for it */
KiRosAllocateNtDescriptor(LoaderXIPRom,
KERNEL_DESCRIPTOR_PAGE(RosLoaderBlock->RdAddr),
(RosLoaderBlock->RdLength + PAGE_SIZE - 1) >> PAGE_SHIFT,
@@ -1265,7 +1263,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
HalPath = strchr(BootPath + 1, ' ');
*HalPath = ANSI_NULL;
BldrNtBootPath[0] = '\\';
- strncat(BldrNtBootPath, BootPath + 1, 63);
+ strncat(BldrNtBootPath, BootPath + 1, 61);
strcat(BldrNtBootPath,"\\");
LoaderBlock->NtBootPathName = BldrNtBootPath;
@@ -1412,3 +1410,4 @@ KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
/* Do general System Startup */
KiSystemStartup(NtLoaderBlock);
}
+#endif
diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c
index 5e4f51dfd65..a8db4d5b5dd 100644
--- a/ntoskrnl/ke/i386/cpu.c
+++ b/ntoskrnl/ke/i386/cpu.c
@@ -120,6 +120,7 @@ RDMSR(IN ULONG Register)
VOID
NTAPI
+INIT_FUNCTION
KiSetProcessorType(VOID)
{
ULONG EFlags, NewEFlags;
@@ -186,6 +187,7 @@ KiSetProcessorType(VOID)
ULONG
NTAPI
+INIT_FUNCTION
KiGetCpuVendor(VOID)
{
PKPRCB Prcb = KeGetCurrentPrcb();
@@ -247,6 +249,7 @@ KiGetCpuVendor(VOID)
ULONG
NTAPI
+INIT_FUNCTION
KiGetFeatureBits(VOID)
{
PKPRCB Prcb = KeGetCurrentPrcb();
@@ -472,6 +475,7 @@ KiGetFeatureBits(VOID)
VOID
NTAPI
+INIT_FUNCTION
KiGetCacheInformation(VOID)
{
PKIPCR Pcr = (PKIPCR)KeGetPcr();
@@ -774,6 +778,7 @@ KiGetCacheInformation(VOID)
VOID
NTAPI
+INIT_FUNCTION
KiSetCR0Bits(VOID)
{
ULONG Cr0;
@@ -790,6 +795,7 @@ KiSetCR0Bits(VOID)
VOID
NTAPI
+INIT_FUNCTION
KiInitializeTSS2(IN PKTSS Tss,
IN PKGDTENTRY TssEntry OPTIONAL)
{
@@ -843,6 +849,7 @@ KiInitializeTSS(IN PKTSS Tss)
VOID
FASTCALL
+INIT_FUNCTION
Ki386InitializeTss(IN PKTSS Tss,
IN PKIDTENTRY Idt,
IN PKGDTENTRY Gdt)
@@ -1002,6 +1009,7 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
VOID
NTAPI
+INIT_FUNCTION
KiInitializeMachineType(VOID)
{
/* Set the Machine Type we got from NTLDR */
@@ -1010,6 +1018,7 @@ KiInitializeMachineType(VOID)
ULONG_PTR
NTAPI
+INIT_FUNCTION
KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
{
/* Set CS and ESP */
@@ -1023,6 +1032,7 @@ KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
VOID
NTAPI
+INIT_FUNCTION
KiRestoreFastSyscallReturnState(VOID)
{
/* Check if the CPU Supports fast system call */
@@ -1056,6 +1066,7 @@ KiRestoreFastSyscallReturnState(VOID)
ULONG_PTR
NTAPI
+INIT_FUNCTION
Ki386EnableDE(IN ULONG_PTR Context)
{
/* Enable DE */
@@ -1065,6 +1076,7 @@ Ki386EnableDE(IN ULONG_PTR Context)
ULONG_PTR
NTAPI
+INIT_FUNCTION
Ki386EnableFxsr(IN ULONG_PTR Context)
{
/* Enable FXSR */
@@ -1074,6 +1086,7 @@ Ki386EnableFxsr(IN ULONG_PTR Context)
ULONG_PTR
NTAPI
+INIT_FUNCTION
Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
{
PKIDTENTRY IdtEntry;
@@ -1096,6 +1109,7 @@ Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
VOID
NTAPI
+INIT_FUNCTION
KiI386PentiumLockErrataFixup(VOID)
{
KDESCRIPTOR IdtDescriptor;
@@ -1187,6 +1201,7 @@ KiSaveProcessorState(IN PKTRAP_FRAME TrapFrame,
BOOLEAN
NTAPI
+INIT_FUNCTION
KiIsNpxPresent(VOID)
{
ULONG Cr0;
@@ -1227,6 +1242,7 @@ KiIsNpxPresent(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
KiIsNpxErrataPresent(VOID)
{
BOOLEAN ErrataPresent;
diff --git a/ntoskrnl/ke/i386/ctxswitch.S b/ntoskrnl/ke/i386/ctxswitch.S
index 4af3f9b504d..8fba093426f 100644
--- a/ntoskrnl/ke/i386/ctxswitch.S
+++ b/ntoskrnl/ke/i386/ctxswitch.S
@@ -10,341 +10,28 @@
/* INCLUDES ******************************************************************/
-#include
-.intel_syntax noprefix
+#include
+#include
-#define Ready 1
-#define Running 2
-#define WrDispatchInt 0x1F
+EXTERN @KiSwapContextEntry@8:PROC
+EXTERN @KiSwapContextExit@8:PROC
+EXTERN @KiRetireDpcList@4:PROC
+EXTERN @KiEnterV86Mode@4:PROC
+EXTERN @KiExitV86Mode@4:PROC
/* FUNCTIONS ****************************************************************/
+.code
-/*++
- * KiSwapContextInternal
- *
- * The KiSwapContextInternal routine switches context to another thread.
- *
- * Params:
- * ESI - Pointer to the KTHREAD to which the caller wishes to
- * switch to.
- * EDI - Pointer to the KTHREAD to which the caller wishes to
- * switch from.
- *
- * Returns:
- * None.
- *
- * Remarks:
- * Absolutely all registers except ESP can be trampled here for maximum code flexibility.
- *
- *--*/
-.globl @KiSwapContextInternal@0
-.func @KiSwapContextInternal@0, @KiSwapContextInternal@0
+PUBLIC @KiSwapContextInternal@0
@KiSwapContextInternal@0:
+ /* Build switch frame */
+ sub esp, 2 * 4
+ mov ecx, esp
+ jmp @KiSwapContextEntry@8
- /* Save the IRQL */
- push ecx
-#ifdef CONFIG_SMP
-GetSwapLock:
- /* Acquire the swap lock */
- cmp byte ptr [esi+KTHREAD_SWAP_BUSY], 0
- jz NotBusy
- pause
- jmp GetSwapLock
-NotBusy:
-#endif
- /* Increase context switches (use ES for lazy load) */
- inc dword ptr es:[ebx+KPCR_CONTEXT_SWITCHES]
-
- /* Save the Exception list */
- push [ebx+KPCR_EXCEPTION_LIST]
-
- /* Check for WMI */
- cmp dword ptr [ebx+KPCR_PERF_GLOBAL_GROUP_MASK], 0
- jnz WmiTrace
-
-AfterTrace:
-#ifdef CONFIG_SMP
-#if DBG
- /* Assert that we're on the right CPU */
- mov cl, [esi+KTHREAD_NEXT_PROCESSOR]
- cmp cl, [ebx+KPCR_PROCESSOR_NUMBER]
- jnz WrongCpu
-#endif
-#endif
-
- /* Get CR0 and save it */
- mov ebp, cr0
- mov edx, ebp
-
-#ifdef CONFIG_SMP
- /* Check NPX State */
- cmp byte ptr [edi+KTHREAD_NPX_STATE], NPX_STATE_LOADED
- jz NpxLoaded
-SetStack:
-#endif
-
- /* Set new stack */
- mov [edi+KTHREAD_KERNEL_STACK], esp
-
- /* Checking NPX, disable interrupts now */
- mov eax, [esi+KTHREAD_INITIAL_STACK]
- cli
-
- /* Get the NPX State */
- movzx ecx, byte ptr [esi+KTHREAD_NPX_STATE]
-
- /* Clear the other bits, merge in CR0, merge in FPU CR0 bits and compare */
- and edx, ~(CR0_MP + CR0_EM + CR0_TS)
- or ecx, edx
- or ecx, [eax - (NPX_FRAME_LENGTH - FN_CR0_NPX_STATE)]
- cmp ebp, ecx
- jnz NewCr0
-
-StackOk:
- /* Enable interrupts and set the current stack */
- sti
- mov esp, [esi+KTHREAD_KERNEL_STACK]
-
- /* Check if address space switch is needed */
- mov ebp, [esi+KTHREAD_APCSTATE_PROCESS]
- mov eax, [edi+KTHREAD_APCSTATE_PROCESS]
- cmp ebp, eax
- jz SameProcess
-
-#ifdef CONFIG_SMP
- /* Get the active processors and XOR with the process' */
- mov ecx, [ebx+KPCR_SET_MEMBER_COPY]
- lock xor [ebp+KPROCESS_ACTIVE_PROCESSORS], ecx
- lock xor [eax+KPROCESS_ACTIVE_PROCESSORS], ecx
-
- /* Assert change went ok */
-#if DBG
- test [ebp+KPROCESS_ACTIVE_PROCESSORS], ecx
- jz WrongActiveCpu
- test [eax+KPROCESS_ACTIVE_PROCESSORS], ecx
- jnz WrongActiveCpu
-#endif
-#endif
-
- /* Check if we need an LDT */
- mov ecx, [ebp+KPROCESS_LDT_DESCRIPTOR0]
- or ecx, [eax+KPROCESS_LDT_DESCRIPTOR0]
- jnz LdtReload
-
-UpdateCr3:
- /* Switch address space */
- mov eax, [ebp+KPROCESS_DIRECTORY_TABLE_BASE]
- mov cr3, eax
-
-SameProcess:
-
-#ifdef CONFIG_SMP
- /* Release swap lock */
- and byte ptr [edi+KTHREAD_SWAP_BUSY], 0
-#endif
-
- /* Clear gs */
- xor eax, eax
- mov gs, ax
-
- /* Set the TEB */
- mov eax, [esi+KTHREAD_TEB]
- mov [ebx+KPCR_TEB], eax
- mov ecx, [ebx+KPCR_GDT]
- mov [ecx+0x3A], ax
- shr eax, 16
- mov [ecx+0x3C], al
- mov [ecx+0x3F], ah
-
- /* Get stack pointer */
- mov eax, [esi+KTHREAD_INITIAL_STACK]
-
- /* Make space for the NPX Frame */
- sub eax, NPX_FRAME_LENGTH
-
- /* Check if this isn't V86 Mode, so we can bias the Esp0 */
- test dword ptr [eax - KTRAP_FRAME_SIZE + KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
- jnz NoAdjust
-
- /* Bias esp */
- sub eax, KTRAP_FRAME_V86_GS - KTRAP_FRAME_SS
-
-NoAdjust:
-
- /* Set new ESP0 */
- mov ecx, [ebx+KPCR_TSS]
- mov [ecx+KTSS_ESP0], eax
-
- /* Set current IOPM offset in the TSS */
- mov ax, [ebp+KPROCESS_IOPM_OFFSET]
- mov [ecx+KTSS_IOMAPBASE], ax
-
- /* Increase context switches */
- inc dword ptr [esi+KTHREAD_CONTEXT_SWITCHES]
-
- /* Restore exception list */
- pop [ebx+KPCR_EXCEPTION_LIST]
-
- /* Restore IRQL */
- pop ecx
-
- /* DPC shouldn't be active */
- cmp byte ptr [ebx+KPCR_PRCB_DPC_ROUTINE_ACTIVE], 0
- jnz BugCheckDpc
-
- /* Check if kernel APCs are pending */
- cmp byte ptr [esi+KTHREAD_PENDING_KERNEL_APC], 0
- jnz CheckApc
-
- /* No APCs, return */
- xor eax, eax
- ret
-
-CheckApc:
-
- /* Check if they're disabled */
- cmp word ptr [esi+KTHREAD_SPECIAL_APC_DISABLE], 0
- jnz ApcReturn
- test cl, cl
- jz ApcReturn
-
- /* Request APC Delivery */
- mov cl, APC_LEVEL
- call @HalRequestSoftwareInterrupt@4
- or eax, esp
-
-ApcReturn:
-
- /* Return with APC pending */
- setz al
- ret
-
-LdtReload:
- /* Check if it's empty */
- mov eax, [ebp+KPROCESS_LDT_DESCRIPTOR0]
- test eax, eax
- jz LoadLdt
-
- /* Write the LDT Selector */
- mov ecx, [ebx+KPCR_GDT]
- mov [ecx+KGDT_LDT], eax
- mov eax, [ebp+KPROCESS_LDT_DESCRIPTOR1]
- mov [ecx+KGDT_LDT+4], eax
-
- /* Write the INT21 handler */
- mov ecx, [ebx+KPCR_IDT]
- mov eax, [ebp+KPROCESS_INT21_DESCRIPTOR0]
- mov [ecx+0x108], eax
- mov eax, [ebp+KPROCESS_INT21_DESCRIPTOR1]
- mov [ecx+0x10C], eax
-
- /* Save LDT Selector */
- mov eax, KGDT_LDT
-
-LoadLdt:
- lldt ax
- jmp UpdateCr3
-
-NewCr0:
-
-#if DBG
- /* Assert NPX State */
- test byte ptr [esi+KTHREAD_NPX_STATE], ~(NPX_STATE_NOT_LOADED)
- jnz InvalidNpx
- test dword ptr [eax - (NPX_FRAME_LENGTH - FN_CR0_NPX_STATE)], ~(CR0_PE + CR0_MP + CR0_EM + CR0_TS)
- jnz InvalidNpx
-#endif
-
- /* Update CR0 */
- mov cr0, ecx
- jmp StackOk
-
-#ifdef CONFIG_SMP
-NpxLoaded:
-
- /* Mask out FPU flags */
- and edx, ~(CR0_MP + CR0_EM + CR0_TS)
-
- /* Get the NPX Frame */
- mov ecx, [edi+KTHREAD_INITIAL_STACK]
- sub ecx, NPX_FRAME_LENGTH
-
- /* Check if we have a new CR0 */
- cmp ebp, edx
- jz Cr0Equal
-
- /* We do, update it */
- mov cr0, edx
- mov ebp, edx
-
-Cr0Equal:
-
- /* Save the NPX State */
- fxsave [ecx]
- mov byte ptr [edi+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
-
- /* Clear the NPX Thread */
- mov dword ptr [ebx+KPCR_NPX_THREAD], 0
-
- /* Jump back */
- jmp SetStack
-#endif
-
-WmiTrace:
-
- /* No WMI support yet */
- int 3
-
- /* Jump back */
- jmp AfterTrace
-
-BugCheckDpc:
-
- /* Bugcheck the machine, printing out the threads being switched */
- mov eax, [edi+KTHREAD_INITIAL_STACK]
- push 0
- push eax
- push esi
- push edi
- push ATTEMPTED_SWITCH_FROM_DPC
- call _KeBugCheckEx@20
-
-#if DBG
-InvalidNpx:
- int 3
-WrongActiveCpu:
- int 3
-WrongCpu:
- int 3
-#endif
-.endfunc
-
-/*++
- * KiSwapContext
- *
- * The KiSwapContext routine switches context to another thread.
- *
- * Params:
- * TargetThread - Pointer to the KTHREAD to which the caller wishes to
- * switch to.
- *
- * Returns:
- * The WaitStatus of the Target Thread.
- *
- * Remarks:
- * This is a wrapper around KiSwapContextInternal which will save all the
- * non-volatile registers so that the Internal function can use all of
- * them. It will also save the old current thread and set the new one.
- *
- * The calling thread does not return after KiSwapContextInternal until
- * another thread switches to IT.
- *
- *--*/
-.globl @KiSwapContext@8
-.func @KiSwapContext@8, @KiSwapContext@8
+PUBLIC @KiSwapContext@8
@KiSwapContext@8:
-
/* Save 4 registers */
sub esp, 4 * 4
@@ -354,17 +41,8 @@ WrongCpu:
mov [esp+4], edi
mov [esp+0], ebp
- /* Get the current KPCR */
- mov ebx, fs:[KPCR_SELF]
-
- /* Get the Current Thread */
- mov edi, ecx
-
- /* Get the New Thread */
- mov esi, edx
-
/* Get the wait IRQL */
- movzx ecx, byte ptr [edi+KTHREAD_WAIT_IRQL]
+ or dl, cl
/* Do the swap with the registers correctly setup */
call @KiSwapContextInternal@0
@@ -378,256 +56,34 @@ WrongCpu:
/* Clean stack */
add esp, 4 * 4
ret
-.endfunc
-/* DPC INTERRUPT HANDLER ******************************************************/
-.globl _KiDispatchInterrupt@0
-.func KiDispatchInterrupt@0
-_KiDispatchInterrupt@0:
-
- /* Preserve EBX */
- push ebx
-
- /* Get the PCR and disable interrupts */
- mov ebx, PCR[KPCR_SELF]
- cli
-
- /* Check if we have to deliver DPCs, timers, or deferred threads */
- mov eax, [ebx+KPCR_PRCB_DPC_QUEUE_DEPTH]
- or eax, [ebx+KPCR_PRCB_TIMER_REQUEST]
- or eax, [ebx+KPCR_PRCB_DEFERRED_READY_LIST_HEAD]
- jz CheckQuantum
-
- /* Save stack pointer and exception list, then clear it */
- push ebp
- push dword ptr [ebx+KPCR_EXCEPTION_LIST]
- mov dword ptr [ebx+KPCR_EXCEPTION_LIST], -1
-
- /* Save the stack and switch to the DPC Stack */
- mov edx, esp
- mov esp, [ebx+KPCR_PRCB_DPC_STACK]
- push edx
-
- /* Deliver DPCs */
- mov ecx, [ebx+KPCR_PRCB]
- call @KiRetireDpcList@4
-
- /* Restore stack and exception list */
- pop esp
- pop dword ptr [ebx+KPCR_EXCEPTION_LIST]
- pop ebp
-
-CheckQuantum:
-
- /* Re-enable interrupts */
- sti
-
- /* Check if we have quantum end */
- cmp byte ptr [ebx+KPCR_PRCB_QUANTUM_END], 0
- jnz QuantumEnd
-
- /* Check if we have a thread to swap to */
- cmp byte ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
- je Return
-
- /* Make space on the stack to save registers */
- sub esp, 3 * 4
- mov [esp+8], esi
- mov [esp+4], edi
- mov [esp+0], ebp
-
- /* Get the current thread */
- mov edi, [ebx+KPCR_CURRENT_THREAD]
-
-#ifdef CONFIG_SMP
- /* Raise to synch level */
- call _KeRaiseIrqlToSynchLevel@0
-
- /* Set context swap busy */
- mov byte ptr [edi+KTHREAD_SWAP_BUSY], 1
-
- /* Acquire the PRCB Lock */
- lock bts dword ptr [ebx+KPCR_PRCB_PRCB_LOCK], 0
- jnb GetNext
- lea ecx, [ebx+KPCR_PRCB_PRCB_LOCK]
- call @KefAcquireSpinLockAtDpcLevel@4
-#endif
-
-GetNext:
- /* Get the next thread and clear it */
- mov esi, [ebx+KPCR_PRCB_NEXT_THREAD]
- and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
-
- /* Set us as the current running thread */
- mov [ebx+KPCR_CURRENT_THREAD], esi
- mov byte ptr [esi+KTHREAD_STATE_], Running
- mov byte ptr [edi+KTHREAD_WAIT_REASON], WrDispatchInt
-
- /* Put thread in ECX and get the PRCB in EDX */
- mov ecx, edi
- lea edx, [ebx+KPCR_PRCB_DATA]
- call @KiQueueReadyThread@8
-
- /* Set APC_LEVEL and do the swap */
- mov cl, APC_LEVEL
- call @KiSwapContextInternal@0
-
-#ifdef CONFIG_SMP
- /* Lower IRQL back to dispatch */
- mov cl, DISPATCH_LEVEL
- call @KfLowerIrql@4
-#endif
-
- /* Restore registers */
- mov ebp, [esp+0]
- mov edi, [esp+4]
- mov esi, [esp+8]
- add esp, 3*4
-
-Return:
- /* All done */
- pop ebx
- ret
-
-QuantumEnd:
- /* Disable quantum end and process it */
- mov byte ptr [ebx+KPCR_PRCB_QUANTUM_END], 0
- call _KiQuantumEnd@0
- pop ebx
- ret
-.endfunc
-
-.globl @KiIdleLoop@0
-.func @KiIdleLoop@0, @KiIdleLoop@0
-@KiIdleLoop@0:
-
- /* Set EBX */
- mov ebx, fs:[KPCR_SELF]
-
- /* Jump into mainline code */
- jmp MainLoop
-
-CpuIdle:
- /* Call the CPU's idle function */
- lea ecx, [ebx+KPCR_PRCB_POWER_STATE_IDLE_FUNCTION]
- call [ecx]
-
-MainLoop:
- /* Cycle interrupts for 1 cycle */
- sti
- nop
- nop
- cli
-
- /* Check if we have to deliver DPCs, timers, or deferred threads */
- mov eax, [ebx+KPCR_PRCB_DPC_QUEUE_DEPTH]
- or eax, [ebx+KPCR_PRCB_TIMER_REQUEST]
-#ifdef CONFIG_SMP
- or eax, [ebx+KPCR_PRCB_DEFERRED_READY_LIST_HEAD]
-#endif
- jz CheckSchedule
-
- mov cl, DISPATCH_LEVEL
- call @HalClearSoftwareInterrupt@4
+PUBLIC @KiSwitchThreads@8
+@KiSwitchThreads@8:
+ /* Load the new kernel stack and switch OS to new thread */
+ mov esp, edx
+ call @KiSwapContextExit@8
- /* Handle the above */
- lea ecx, [ebx+KPCR_PRCB_DATA]
+ /* Now we're on the new thread. Return to the caller to restore registers */
+ add esp, 2 * 4
+ ret
+
+
+PUBLIC @KiRetireDpcListInDpcStack@8
+@KiRetireDpcListInDpcStack@8:
+ /* Switch stacks and retire DPCs */
+ mov eax, esp
+ mov esp, edx
+ push eax
call @KiRetireDpcList@4
-CheckSchedule:
- /* Check if a next thread is queued */
- cmp dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
-#ifdef CONFIG_SMP
- jz NoNextThread
-#else
- jz CpuIdle
-#endif
+ /* Return on original stack */
+ pop esp
+ ret
-#ifdef CONFIG_SMP
- /* There is, raise IRQL to synch level */
- call _KeRaiseIrqlToSynchLevel@0
-#endif
- sti
-
- /* Set the current thread to ready */
- mov edi, [ebx+KPCR_CURRENT_THREAD]
-#ifdef CONFIG_SMP
- mov byte ptr [edi+KTHREAD_SWAP_BUSY], 1
-
- /* Acquire the PRCB Lock */
- lock bts dword ptr [ebx+KPCR_PRCB_PRCB_LOCK], 0
- jnb CheckNext
- lea ecx, [ebx+KPCR_PRCB_PRCB_LOCK]
- call @KefAcquireSpinLockAtDpcLevel@4
-#endif
-
-CheckNext:
- /* Check if the next thread is the current */
- mov esi, [ebx+KPCR_PRCB_NEXT_THREAD]
-#ifdef CONFIG_SMP
- cmp esi, edi
- jz SameThread
-#endif
-
- /* Clear the next thread and set this one instead */
- and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
- mov [ebx+KPCR_CURRENT_THREAD], esi
-
- /* Set the thread as running */
- mov byte ptr [esi+KTHREAD_STATE_], Running
-
-#ifdef CONFIG_SMP
- /* Disable the idle scheduler and release the PRCB lock */
- and byte ptr [ebx+KPCR_PRCB_IDLE_SCHEDULE], 0
- and dword ptr [ebx+KPCR_PRCB_PRCB_LOCK], 0
-#endif
-
-SwapContext:
- /* ReactOS Mm Hack */
- mov ecx, esi
- call @MiSyncForContextSwitch@4
-
- /* Swap context at APC_LEVEL */
- mov ecx, APC_LEVEL
- call @KiSwapContextInternal@0
-
-#ifdef CONFIG_SMP
- /* Lower to DPC level */
- mov ecx, DISPATCH_LEVEL
- call @KfLowerIrql@4
-#endif
- jmp MainLoop
-
-#ifdef CONFIG_SMP
-SameThread:
- /* Clear the next thread, and put the thread as ready after lock release */
- and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
- and dword ptr [ebx+KPCR_PRCB_PRCB_LOCK], 0
- and byte ptr [edi+KTHREAD_STATE_], Ready
- jmp MainLoop
-
-NoNextThread:
- /* Check if the idle scheduler is enabled */
- cmp byte ptr [ebx+KPCR_PRCB_IDLE_SCHEDULE], 0
- jz CpuIdle
-
- /* It is, so call the scheduler */
- lea ecx, [ebx+KPCR_PRCB_DATA]
- call @KiIdleSchedule@4
- test eax, eax
-
- /* Get new thread pointers and either swap or idle loop again */
- mov esi, eax
- mov edi, [ebx+KPCR_PRCB_IDLE_THREAD]
- jnz SwapContext
- jmp MainLoop
-#endif
-.endfunc
/* FIXFIX: Move to C code ****/
-.globl _Ki386SetupAndExitToV86Mode@4
-.func Ki386SetupAndExitToV86Mode@4
+PUBLIC _Ki386SetupAndExitToV86Mode@4
_Ki386SetupAndExitToV86Mode@4:
/* Enter V8086 mode */
@@ -636,9 +92,9 @@ _Ki386SetupAndExitToV86Mode@4:
mov ecx, esp
call @KiEnterV86Mode@4
jmp $
-.endfunc
-.globl @Ki386BiosCallReturnAddress@4
+
+PUBLIC @Ki386BiosCallReturnAddress@4
@Ki386BiosCallReturnAddress@4:
/* Exit V8086 mode */
@@ -648,3 +104,4 @@ _Ki386SetupAndExitToV86Mode@4:
popad
ret 4
+END
diff --git a/ntoskrnl/ke/i386/kiinit.c b/ntoskrnl/ke/i386/kiinit.c
index b9ad8c65fea..45b25ed7ec6 100644
--- a/ntoskrnl/ke/i386/kiinit.c
+++ b/ntoskrnl/ke/i386/kiinit.c
@@ -33,6 +33,7 @@ ULONGLONG BootCycles, BootCyclesEnd;
VOID
NTAPI
+INIT_FUNCTION
KiInitMachineDependent(VOID)
{
ULONG CpuCount;
@@ -263,19 +264,14 @@ KiInitMachineDependent(VOID)
if (KeFeatureBits & KF_FXSR)
{
/* Get the current thread NPX state */
- FxSaveArea = (PVOID)
- ((ULONG_PTR)KeGetCurrentThread()->InitialStack -
- NPX_FRAME_LENGTH);
+ FxSaveArea = KiGetThreadNpxArea(KeGetCurrentThread());
/* Clear initial MXCsr mask */
FxSaveArea->U.FxArea.MXCsrMask = 0;
/* Save the current NPX State */
-#ifdef __GNUC__
- asm volatile("fxsave %0\n\t" : "=m" (*FxSaveArea));
-#else
- __asm fxsave [FxSaveArea]
-#endif
+ Ke386SaveFpuState(FxSaveArea);
+
/* Check if the current mask doesn't match the reserved bits */
if (FxSaveArea->U.FxArea.MXCsrMask != 0)
{
@@ -325,6 +321,7 @@ KiInitMachineDependent(VOID)
VOID
NTAPI
+INIT_FUNCTION
KiInitializePcr(IN ULONG ProcessorNumber,
IN PKIPCR Pcr,
IN PKIDTENTRY Idt,
@@ -386,6 +383,7 @@ KiInitializePcr(IN ULONG ProcessorNumber,
VOID
NTAPI
+INIT_FUNCTION
KiInitializeKernel(IN PKPROCESS InitProcess,
IN PKTHREAD InitThread,
IN PVOID IdleStack,
@@ -607,6 +605,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
VOID
FASTCALL
+INIT_FUNCTION
KiGetMachineBootPointers(IN PKGDTENTRY *Gdt,
IN PKIDTENTRY *Idt,
IN PKIPCR *Pcr,
@@ -647,6 +646,7 @@ KiGetMachineBootPointers(IN PKGDTENTRY *Gdt,
VOID
NTAPI
+INIT_FUNCTION
KiSystemStartupBootStack(VOID)
{
PKTHREAD Thread;
@@ -676,6 +676,7 @@ KiSystemStartupBootStack(VOID)
VOID
NTAPI
+INIT_FUNCTION
KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
ULONG Cpu;
@@ -689,10 +690,10 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
/* Boot cycles timestamp */
BootCycles = __rdtsc();
-
+#if !defined(_X86_)
/* Check if we are being booted from FreeLDR */
if (!((ULONG_PTR)LoaderBlock & 0x80000000)) KiRosPrepareForSystemStartup((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock);
-
+#endif
/* Save the loader block and get the current CPU */
KeLoaderBlock = LoaderBlock;
Cpu = KeNumberProcessors;
diff --git a/ntoskrnl/ke/i386/mtrr.c b/ntoskrnl/ke/i386/mtrr.c
index 72ceed70f31..d2f83038f66 100644
--- a/ntoskrnl/ke/i386/mtrr.c
+++ b/ntoskrnl/ke/i386/mtrr.c
@@ -18,6 +18,7 @@
VOID
NTAPI
+INIT_FUNCTION
KiInitializeMTRR(IN BOOLEAN FinalCpu)
{
/* FIXME: Support this */
@@ -26,6 +27,7 @@ KiInitializeMTRR(IN BOOLEAN FinalCpu)
VOID
NTAPI
+INIT_FUNCTION
KiAmdK6InitializeMTRR(VOID)
{
/* FIXME: Support this */
diff --git a/ntoskrnl/ke/i386/patpge.c b/ntoskrnl/ke/i386/patpge.c
index 9b6ef4b67c6..5e8e232727a 100644
--- a/ntoskrnl/ke/i386/patpge.c
+++ b/ntoskrnl/ke/i386/patpge.c
@@ -16,6 +16,7 @@
ULONG_PTR
NTAPI
+INIT_FUNCTION
Ki386EnableGlobalPage(IN volatile ULONG_PTR Context)
{
volatile PLONG Count = (PLONG)Context;
@@ -52,6 +53,7 @@ Ki386EnableGlobalPage(IN volatile ULONG_PTR Context)
VOID
NTAPI
+INIT_FUNCTION
KiInitializePAT(VOID)
{
/* FIXME: Support this */
diff --git a/ntoskrnl/ke/i386/thrdini.c b/ntoskrnl/ke/i386/thrdini.c
index 219e2883922..07da5ab1fa3 100644
--- a/ntoskrnl/ke/i386/thrdini.c
+++ b/ntoskrnl/ke/i386/thrdini.c
@@ -42,6 +42,20 @@ typedef struct _KKINIT_FRAME
FX_SAVE_AREA FxSaveArea;
} KKINIT_FRAME, *PKKINIT_FRAME;
+VOID
+FASTCALL
+KiSwitchThreads(
+ IN PKTHREAD OldThread,
+ IN PKTHREAD NewThread
+);
+
+VOID
+FASTCALL
+KiRetireDpcListInDpcStack(
+ IN PKPRCB Prcb,
+ IN PVOID DpcStack
+);
+
/* FUNCTIONS *****************************************************************/
VOID
@@ -51,7 +65,7 @@ KiThreadStartup(VOID)
PKTRAP_FRAME TrapFrame;
PKSTART_FRAME StartFrame;
PKUINIT_FRAME InitFrame;
-
+
/* Get the start and trap frames */
InitFrame = KeGetCurrentThread()->KernelStack;
StartFrame = &InitFrame->StartFrame;
@@ -59,13 +73,13 @@ KiThreadStartup(VOID)
/* Lower to APC level */
KfLowerIrql(APC_LEVEL);
-
+
/* Call the system routine */
StartFrame->SystemRoutine(StartFrame->StartRoutine, StartFrame->StartContext);
-
+
/* If we returned, we better be a user thread */
if (!StartFrame->UserThread) DbgBreakPoint();
-
+
/* Exit to user-mode */
KiServiceExit2(TrapFrame);
}
@@ -249,6 +263,252 @@ KiInitializeContextThread(IN PKTHREAD Thread,
Thread->KernelStack = (PVOID)CtxSwitchFrame;
}
+VOID
+FASTCALL
+KiIdleLoop(VOID)
+{
+ PKPRCB Prcb = KeGetCurrentPrcb();
+ PKTHREAD OldThread, NewThread;
+
+ /* Initialize the idle loop: disable interrupts */
+ _enable();
+ YieldProcessor();
+ YieldProcessor();
+ _disable();
+
+ /* Now loop forever */
+ while (TRUE)
+ {
+ /* Check for pending timers, pending DPCs, or pending ready threads */
+ if ((Prcb->DpcData[0].DpcQueueDepth) ||
+ (Prcb->TimerRequest) ||
+ (Prcb->DeferredReadyListHead.Next))
+ {
+ /* Quiesce the DPC software interrupt */
+ HalClearSoftwareInterrupt(DISPATCH_LEVEL);
+
+ /* Handle it */
+ KiRetireDpcList(Prcb);
+ }
+
+ /* Check if a new thread is scheduled for execution */
+ if (Prcb->NextThread)
+ {
+ /* Enable interupts */
+ _enable();
+
+ /* Capture current thread data */
+ OldThread = Prcb->CurrentThread;
+ NewThread = Prcb->NextThread;
+
+ /* Set new thread data */
+ Prcb->NextThread = NULL;
+ Prcb->CurrentThread = NewThread;
+
+ /* The thread is now running */
+ NewThread->State = Running;
+
+ /* Switch away from the idle thread */
+ KiSwapContext(APC_LEVEL, OldThread);
+
+ /* We are back in the idle thread -- disable interrupts again */
+ _enable();
+ YieldProcessor();
+ YieldProcessor();
+ _disable();
+ }
+ else
+ {
+ /* Continue staying idle. Note the HAL returns with interrupts on */
+ Prcb->PowerState.IdleFunction(&Prcb->PowerState);
+ }
+ }
+}
+
+BOOLEAN
+FASTCALL
+KiSwapContextExit(IN PKTHREAD OldThread,
+ IN PKSWITCHFRAME SwitchFrame)
+{
+ PKIPCR Pcr = (PKIPCR)KeGetPcr();
+ PKPROCESS OldProcess, NewProcess;
+ PKGDTENTRY GdtEntry;
+ PKTHREAD NewThread;
+
+ /* We are on the new thread stack now */
+ NewThread = Pcr->PrcbData.CurrentThread;
+
+ /* Now we are the new thread. Check if it's in a new process */
+ OldProcess = OldThread->ApcState.Process;
+ NewProcess = NewThread->ApcState.Process;
+ if (OldProcess != NewProcess)
+ {
+ /* Check if there is a different LDT */
+ if (*(PULONGLONG)&OldProcess->LdtDescriptor != *(PULONGLONG)&NewProcess->LdtDescriptor)
+ {
+ DPRINT1("LDT switch not implemented\n");
+ ASSERT(FALSE);
+ }
+
+ /* Switch address space and flush TLB */
+ __writecr3(NewProcess->DirectoryTableBase[0]);
+ }
+
+ /* Clear GS */
+ Ke386SetGs(0);
+
+ /* Set the TEB */
+ Pcr->NtTib.Self = (PVOID)NewThread->Teb;
+ GdtEntry = &Pcr->GDT[KGDT_R3_TEB / sizeof(KGDTENTRY)];
+ GdtEntry->BaseLow = (USHORT)((ULONG_PTR)NewThread->Teb & 0xFFFF);
+ GdtEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)NewThread->Teb >> 16);
+ GdtEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)NewThread->Teb >> 24);
+
+ /* Set new TSS fields */
+ Pcr->TSS->Esp0 = (ULONG_PTR)NewThread->InitialStack;
+ if (!((KeGetTrapFrame(NewThread))->EFlags & EFLAGS_V86_MASK))
+ {
+ Pcr->TSS->Esp0 -= (FIELD_OFFSET(KTRAP_FRAME, V86Gs) - FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs));
+ }
+ Pcr->TSS->Esp0 -= NPX_FRAME_LENGTH;
+ Pcr->TSS->IoMapBase = NewProcess->IopmOffset;
+
+ /* Increase thread context switches */
+ NewThread->ContextSwitches++;
+
+ /* Load data from switch frame */
+ Pcr->NtTib.ExceptionList = SwitchFrame->ExceptionList;
+
+ /* DPCs shouldn't be active */
+ if (Pcr->PrcbData.DpcRoutineActive)
+ {
+ /* Crash the machine */
+ KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC,
+ (ULONG_PTR)OldThread,
+ (ULONG_PTR)NewThread,
+ (ULONG_PTR)OldThread->InitialStack,
+ 0);
+ }
+
+ /* Kernel APCs may be pending */
+ if (NewThread->ApcState.KernelApcPending)
+ {
+ /* Are APCs enabled? */
+ if (!NewThread->SpecialApcDisable)
+ {
+ /* Request APC delivery */
+ if (SwitchFrame->ApcBypassDisable) HalRequestSoftwareInterrupt(APC_LEVEL);
+ return TRUE;
+ }
+ }
+
+ /* Return */
+ return FALSE;
+}
+
+VOID
+FASTCALL
+KiSwapContextEntry(IN PKSWITCHFRAME SwitchFrame,
+ IN ULONG_PTR OldThreadAndApcFlag)
+{
+ PKIPCR Pcr = (PKIPCR)KeGetPcr();
+ PKTHREAD OldThread, NewThread;
+ ULONG Cr0, NewCr0;
+
+ /* Save APC bypass disable */
+ SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3;
+ SwitchFrame->ExceptionList = Pcr->NtTib.ExceptionList;
+
+ /* Increase context switch count and check if tracing is enabled */
+ Pcr->ContextSwitches++;
+ if (Pcr->PerfGlobalGroupMask)
+ {
+ /* We don't support this yet on x86 either */
+ DPRINT1("WMI Tracing not supported\n");
+ ASSERT(FALSE);
+ }
+
+ /* Get thread pointers */
+ OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3);
+ NewThread = Pcr->PrcbData.CurrentThread;
+
+ /* Get the old thread and set its kernel stack */
+ OldThread->KernelStack = SwitchFrame;
+
+ /* ISRs can change FPU state, so disable interrupts while checking */
+ _disable();
+
+ /* Get current and new CR0 and check if they've changed */
+ Cr0 = __readcr0();
+ NewCr0 = NewThread->NpxState |
+ (Cr0 & ~(CR0_MP | CR0_EM | CR0_TS)) |
+ KiGetThreadNpxArea(NewThread)->Cr0NpxState;
+ if (Cr0 != NewCr0) __writecr0(NewCr0);
+
+ /* Now enable interrupts and do the switch */
+ _enable();
+ KiSwitchThreads(OldThread, NewThread->KernelStack);
+}
+
+VOID
+NTAPI
+KiDispatchInterrupt(VOID)
+{
+ PKIPCR Pcr = (PKIPCR)KeGetPcr();
+ PKPRCB Prcb = &Pcr->PrcbData;
+ PVOID OldHandler;
+ PKTHREAD NewThread, OldThread;
+
+ /* Disable interrupts */
+ _disable();
+
+ /* Check for pending timers, pending DPCs, or pending ready threads */
+ if ((Prcb->DpcData[0].DpcQueueDepth) ||
+ (Prcb->TimerRequest) ||
+ (Prcb->DeferredReadyListHead.Next))
+ {
+ /* Switch to safe execution context */
+ OldHandler = Pcr->NtTib.ExceptionList;
+ Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
+
+ /* Retire DPCs while under the DPC stack */
+ KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack);
+
+ /* Restore context */
+ Pcr->NtTib.ExceptionList = OldHandler;
+ }
+
+ /* Re-enable interrupts */
+ _enable();
+
+ /* Check for quantum end */
+ if (Prcb->QuantumEnd)
+ {
+ /* Handle quantum end */
+ Prcb->QuantumEnd = FALSE;
+ KiQuantumEnd();
+ }
+ else if (Prcb->NextThread)
+ {
+ /* Capture current thread data */
+ OldThread = Prcb->CurrentThread;
+ NewThread = Prcb->NextThread;
+
+ /* Set new thread data */
+ Prcb->NextThread = NULL;
+ Prcb->CurrentThread = NewThread;
+
+ /* The thread is now running */
+ NewThread->State = Running;
+ OldThread->WaitReason = WrDispatchInt;
+
+ /* Make the old thread ready */
+ KxQueueReadyThread(OldThread, Prcb);
+
+ /* Swap to the new thread */
+ KiSwapContext(APC_LEVEL, OldThread);
+ }
+}
+
+
/* EOF */
-
-
diff --git a/ntoskrnl/ke/i386/trap.s b/ntoskrnl/ke/i386/trap.s
index adfcd322dd9..f3c99c48c77 100644
--- a/ntoskrnl/ke/i386/trap.s
+++ b/ntoskrnl/ke/i386/trap.s
@@ -9,8 +9,8 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
#include
MACRO(GENERATE_IDT_STUB, Number)
@@ -18,16 +18,19 @@ idt _KiUnexpectedInterrupt&Number, INT_32_DPL0
ENDM
MACRO(GENERATE_INT_HANDLER, Number)
-.func KiUnexpectedInterrupt&Number
+//.func KiUnexpectedInterrupt&Number
_KiUnexpectedInterrupt&Number:
push PRIMARY_VECTOR_BASE + Number
jmp _KiEndUnexpectedRange@0
-.endfunc
+//.endfunc
ENDM
+EXTERN _KiTrap02:PROC
+
/* GLOBALS *******************************************************************/
.data
+ASSUME nothing
PUBLIC _KiIdt
_KiIdt:
@@ -52,9 +55,9 @@ idt _KiTrap10, INT_32_DPL0 /* INT 10: x87 FPU Error (#MF) */
idt _KiTrap11, INT_32_DPL0 /* INT 11: Align Check Exception (#AC) */
idt _KiTrap0F, INT_32_DPL0 /* INT 12: Machine Check Exception (#MC)*/
idt _KiTrap0F, INT_32_DPL0 /* INT 13: SIMD FPU Exception (#XF) */
-.rept 22
+REPEAT 22
idt _KiTrap0F, INT_32_DPL0 /* INT 14-29: UNDEFINED INTERRUPTS */
-.endr
+ENDR
idt _KiGetTickCount, INT_32_DPL3 /* INT 2A: Get Tick Count Handler */
idt _KiCallbackReturn, INT_32_DPL3 /* INT 2B: User-Mode Callback Return */
idt _KiRaiseAssertion, INT_32_DPL3 /* INT 2C: Debug Assertion Handler */
@@ -62,15 +65,15 @@ idt _KiDebugService, INT_32_DPL3 /* INT 2D: Debug Service Handler */
idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call Service Handler */
idt _KiTrap0F, INT_32_DPL0 /* INT 2F: RESERVED */
i = 0
-.rept 208
+REPEAT 208
GENERATE_IDT_STUB %i
i = i + 1
-.endr
+ENDR
PUBLIC _KiIdtDescriptor
_KiIdtDescriptor:
.short 0
- .short 0x7FF
+ .short HEX(7FF)
.long _KiIdt
PUBLIC _KiUnexpectedEntrySize
@@ -78,8 +81,7 @@ _KiUnexpectedEntrySize:
.long _KiUnexpectedInterrupt1 - _KiUnexpectedInterrupt0
/******************************************************************************/
-.code32
-.text
+.code
TRAP_ENTRY KiTrap00, KI_PUSH_FAKE_ERROR_CODE
TRAP_ENTRY KiTrap01, KI_PUSH_FAKE_ERROR_CODE
@@ -106,7 +108,7 @@ TRAP_ENTRY KiDebugService, KI_PUSH_FAKE_ERROR_CODE
TRAP_ENTRY KiUnexpectedInterruptTail, 0
ALIGN 4
-EXTERN @KiInterruptTemplateHandler@8
+EXTERN @KiInterruptTemplateHandler@8:PROC
PUBLIC _KiInterruptTemplate
_KiInterruptTemplate:
KiEnterTrap KI_PUSH_FAKE_ERROR_CODE
@@ -135,10 +137,10 @@ _KiFastCallEntry:
PUBLIC _KiStartUnexpectedRange@0
_KiStartUnexpectedRange@0:
i = 0
-.rept 208
+REPEAT 208
GENERATE_INT_HANDLER %i
i = i + 1
-.endr
+ENDR
PUBLIC _KiEndUnexpectedRange@0
_KiEndUnexpectedRange@0:
jmp _KiUnexpectedInterruptTail
diff --git a/ntoskrnl/ke/i386/usercall_asm.S b/ntoskrnl/ke/i386/usercall_asm.S
index 2da726882eb..dcdc7ba9e88 100644
--- a/ntoskrnl/ke/i386/usercall_asm.S
+++ b/ntoskrnl/ke/i386/usercall_asm.S
@@ -8,17 +8,18 @@
/* INCLUDES ******************************************************************/
-#include
-#include
+#include
+#include
#include
+EXTERN _MmGrowKernelStack@4:PROC
+EXTERN _KeUserCallbackDispatcher:PROC
+EXTERN @KiServiceExit@8:PROC
+
/* FUNCTIONS ****************************************************************/
+.code
-.code32
-.text
-
-.globl _KiGetUserModeStackAddress@0
-.func KiGetUserModeStackAddress@0
+PUBLIC _KiGetUserModeStackAddress@0
_KiGetUserModeStackAddress@0:
/* Get the current thread's trapframe and return the esp */
@@ -27,7 +28,6 @@ _KiGetUserModeStackAddress@0:
lea eax, [eax+KTRAP_FRAME_ESP]
ret
-.endfunc
/*++
* @name KiCallUserMode
@@ -53,8 +53,7 @@ _KiGetUserModeStackAddress@0:
* This call MUST be paired by interrupt 0x2B or NtCallbackReturn.
*
*--*/
-.globl _KiCallUserMode@8
-.func KiCallUserMode@8
+PUBLIC _KiCallUserMode@8
_KiCallUserMode@8:
/* Save volatile registers */
@@ -102,7 +101,7 @@ ApcsEnabled:
#endif
/* Get the lowest stack limit and check if we can handle it */
- lea eax, [esp-0x3000]
+ lea eax, [esp-HEX(3000)]
cmp eax, [ebx+KTHREAD_STACK_LIMIT]
jnb StackOk
@@ -130,7 +129,7 @@ StackOk:
mov [ebx+KTHREAD_CALLBACK_STACK], esp
/* Align stack on 16-byte boundary */
- and esp, ~15
+ and esp, NOT 15
mov edi, esp
/* Set destination and origin NPX Areas */
@@ -181,7 +180,7 @@ DontBias:
/* Copy DR7 */
mov edi, [edx+KTRAP_FRAME_DR7]
- test edi, ~DR7_RESERVED_MASK
+ test edi, NOT DR7_RESERVED_MASK
mov [esp+KTRAP_FRAME_DR7], edi
/* Check if we need to save debug registers */
@@ -226,7 +225,6 @@ GrowFailed:
/* Return */
ret 8
-.endfunc
/*++
* @name NtCallbackReturn
@@ -251,8 +249,7 @@ GrowFailed:
* @remark This call MUST be paired with KeUserModeCallback.
*
*--*/
-.globl _NtCallbackReturn@12
-.func NtCallbackReturn@12
+PUBLIC _NtCallbackReturn@12
_NtCallbackReturn@12:
/* Get the current thread and make sure we have a callback stack */
@@ -316,7 +313,7 @@ CheckDebug:
and dword ptr [edi+KTRAP_FRAME_DR7], 0
/* Check if debugging was active */
- test byte ptr [eax+KTHREAD_DEBUG_ACTIVE], 0xFF
+ test byte ptr [eax+KTHREAD_DEBUG_ACTIVE], HEX(0FF)
jnz RestoreDebug
RestoreStack:
@@ -407,7 +404,6 @@ NoStack:
/* Return failure */
mov eax, STATUS_NO_CALLBACK_ACTIVE
ret 12
-.endfunc
/*++
* @name KeSwitchKernelStack
@@ -429,8 +425,7 @@ NoStack:
* this routine.
*
*--*/
-.globl _KeSwitchKernelStack@8
-.func KeSwitchKernelStack@8
+PUBLIC _KeSwitchKernelStack@8
_KeSwitchKernelStack@8:
/* Save volatiles */
@@ -515,4 +510,5 @@ V86Switch:
pop edi
pop esi
ret 8
-.endfunc
+
+END
diff --git a/ntoskrnl/ke/krnlinit.c b/ntoskrnl/ke/krnlinit.c
index 55ec779251d..d22fe7e2fd8 100644
--- a/ntoskrnl/ke/krnlinit.c
+++ b/ntoskrnl/ke/krnlinit.c
@@ -57,6 +57,7 @@ KSPIN_LOCK KiReverseStallIpiLock;
VOID
NTAPI
+INIT_FUNCTION
KiInitSystem(VOID)
{
ULONG i;
@@ -108,6 +109,7 @@ KiInitSystem(VOID)
LARGE_INTEGER
NTAPI
+INIT_FUNCTION
KiComputeReciprocal(IN LONG Divisor,
OUT PUCHAR Shift)
{
@@ -171,6 +173,7 @@ KiComputeReciprocal(IN LONG Divisor,
VOID
NTAPI
+INIT_FUNCTION
KiInitSpinLocks(IN PKPRCB Prcb,
IN CCHAR Number)
{
@@ -276,6 +279,7 @@ KiInitSpinLocks(IN PKPRCB Prcb,
BOOLEAN
NTAPI
+INIT_FUNCTION
KeInitSystem(VOID)
{
/* Check if Threaded DPCs are enabled */
diff --git a/ntoskrnl/ke/procobj.c b/ntoskrnl/ke/procobj.c
index f187ec1dd71..ce337feab2a 100644
--- a/ntoskrnl/ke/procobj.c
+++ b/ntoskrnl/ke/procobj.c
@@ -96,9 +96,6 @@ KiAttachProcess(IN PKTHREAD Thread,
/* Release lock */
KiReleaseApcLockFromDpcLevel(ApcLock);
-
- /* Make sure that we are in the right page directory (ReactOS Mm Hack) */
- MiSyncForProcessAttach(Thread, (PEPROCESS)Process);
/* Swap Processes */
KiSwapProcess(Process, SavedApcState->Process);
@@ -450,9 +447,6 @@ KeAttachProcess(IN PKPROCESS Process)
ASSERT_PROCESS(Process);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
- /* Make sure that we are in the right page directory (ReactOS Mm Hack) */
- MiSyncForProcessAttach(Thread, (PEPROCESS)Process);
-
/* Check if we're already in that process */
if (Thread->ApcState.Process == Process) return;
diff --git a/ntoskrnl/ke/thrdobj.c b/ntoskrnl/ke/thrdobj.c
index e73f4ff9d29..b23741f6a28 100644
--- a/ntoskrnl/ke/thrdobj.c
+++ b/ntoskrnl/ke/thrdobj.c
@@ -810,9 +810,6 @@ KeInitThread(IN OUT PKTHREAD Thread,
Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE;
Thread->KernelStackResident = TRUE;
- /* Make sure that we are in the right page directory (ReactOS Mm Hack) */
- MiSyncForProcessAttach(Thread, (PEPROCESS)Process);
-
/* Enter SEH to avoid crashes due to user mode */
Status = STATUS_SUCCESS;
_SEH2_TRY
diff --git a/ntoskrnl/ke/thrdschd.c b/ntoskrnl/ke/thrdschd.c
index 87246f0b778..d100c3b8900 100644
--- a/ntoskrnl/ke/thrdschd.c
+++ b/ntoskrnl/ke/thrdschd.c
@@ -386,11 +386,8 @@ KiSwapThread(IN PKTHREAD CurrentThread,
/* Save the wait IRQL */
WaitIrql = CurrentThread->WaitIrql;
- /* REACTOS Mm Hack of Doom */
- MiSyncForContextSwitch(NextThread);
-
/* Swap contexts */
- ApcState = KiSwapContext(CurrentThread, NextThread);
+ ApcState = KiSwapContext(WaitIrql, CurrentThread);
/* Get the wait status */
WaitStatus = CurrentThread->WaitStatus;
@@ -756,11 +753,8 @@ NtYieldExecution(VOID)
/* Sanity check */
ASSERT(OldIrql <= DISPATCH_LEVEL);
- /* REACTOS Mm Hack of Doom */
- MiSyncForContextSwitch(NextThread);
-
/* Swap to new thread */
- KiSwapContext(Thread, NextThread);
+ KiSwapContext(APC_LEVEL, Thread);
Status = STATUS_SUCCESS;
}
else
diff --git a/ntoskrnl/ke/wait.c b/ntoskrnl/ke/wait.c
index a4737b0b7fa..3fc51062ba4 100644
--- a/ntoskrnl/ke/wait.c
+++ b/ntoskrnl/ke/wait.c
@@ -249,7 +249,7 @@ KiExitDispatcher(IN KIRQL OldIrql)
Thread->WaitIrql = OldIrql;
/* Swap threads and check if APCs were pending */
- PendingApc = KiSwapContext(Thread, NextThread);
+ PendingApc = KiSwapContext(OldIrql, Thread);
if (PendingApc)
{
/* Lower only to APC */
diff --git a/ntoskrnl/lpc/port.c b/ntoskrnl/lpc/port.c
index b179fd30b48..77517ded394 100644
--- a/ntoskrnl/lpc/port.c
+++ b/ntoskrnl/lpc/port.c
@@ -33,6 +33,7 @@ static GENERIC_MAPPING LpcpPortMapping =
BOOLEAN
NTAPI
+INIT_FUNCTION
LpcInitSystem(VOID)
{
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
diff --git a/ntoskrnl/mm/ARM3/arm/init.c b/ntoskrnl/mm/ARM3/arm/init.c
index 091d0cb7b5e..1e44b767d35 100644
--- a/ntoskrnl/mm/ARM3/arm/init.c
+++ b/ntoskrnl/mm/ARM3/arm/init.c
@@ -24,10 +24,7 @@ ULONG MmMaximumNonPagedPoolInBytes;
PVOID MmNonPagedSystemStart;
PVOID MmNonPagedPoolStart;
PVOID MmNonPagedPoolExpansionStart;
-PVOID MmNonPagedPoolEnd = MI_NONPAGED_POOL_END;
-PVOID MmPagedPoolStart = MI_PAGED_POOL_START;
PVOID MmPagedPoolEnd;
-ULONG MmSizeOfPagedPoolInBytes = MI_MIN_INIT_PAGED_POOLSIZE;
PVOID MiSessionSpaceEnd;
PVOID MiSessionImageEnd;
PVOID MiSessionImageStart;
@@ -42,14 +39,14 @@ ULONG MmSessionImageSize;
PVOID MiSystemViewStart;
ULONG MmSystemViewSize;
PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
-PMMPTE MmSystemPagePtes;
+PMMPDE MmSystemPagePtes;
ULONG MmNumberOfSystemPtes;
ULONG MxPfnAllocation;
RTL_BITMAP MiPfnBitMap;
PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
-ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage = -1;
+ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage;
ULONG MmBootImageSize;
ULONG MmUserProbeAddress;
PVOID MmHighestUserAddress;
@@ -63,8 +60,8 @@ PVOID MmHyperSpaceEnd;
NTSTATUS
NTAPI
-MmArmInitSystem(IN ULONG Phase,
- IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+INIT_FUNCTION
+MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
//
// Always return success for now
diff --git a/ntoskrnl/mm/ARM3/contmem.c b/ntoskrnl/mm/ARM3/contmem.c
index da277565861..79eacda42a0 100644
--- a/ntoskrnl/mm/ARM3/contmem.c
+++ b/ntoskrnl/mm/ARM3/contmem.c
@@ -30,13 +30,16 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn,
ULONG i = 0;
PMMPFN Pfn1, EndPfn;
KIRQL OldIrql;
- PAGED_CODE ();
+ PAGED_CODE();
ASSERT(SizeInPages != 0);
//
// Convert the boundary PFN into an alignment mask
//
BoundaryMask = ~(BoundaryPfn - 1);
+
+ /* Disable APCs */
+ KeEnterGuardedRegion();
//
// Loop all the physical memory blocks
@@ -69,12 +72,16 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn,
// Now scan all the relevant PFNs in this run
//
Length = 0;
- for (Pfn1 = MiGetPfnEntry(Page); Page < LastPage; Page++, Pfn1++)
+ for (Pfn1 = MI_PFN_ELEMENT(Page); Page < LastPage; Page++, Pfn1++)
{
//
// If this PFN is in use, ignore it
//
- if (MiIsPfnInUse(Pfn1)) continue;
+ if (MiIsPfnInUse(Pfn1))
+ {
+ Length = 0;
+ continue;
+ }
//
// If we haven't chosen a start PFN yet and the caller specified an
@@ -130,6 +137,8 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn,
//
// This PFN is now a used page, set it up
//
+ MI_SET_USAGE(MI_USAGE_CONTINOUS_ALLOCATION);
+ MI_SET_PROCESS2("Kernel Driver");
MiUnlinkFreeOrZeroedPage(Pfn1);
Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->u2.ShareCount = 1;
@@ -162,14 +171,17 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn,
// Quick sanity check that the last PFN is consistent
//
EndPfn = Pfn1 + SizeInPages;
- ASSERT(EndPfn == MiGetPfnEntry(Page + 1));
+ ASSERT(EndPfn == MI_PFN_ELEMENT(Page + 1));
//
// Compute the first page, and make sure it's consistent
//
- Page -= SizeInPages - 1;
- ASSERT(Pfn1 == MiGetPfnEntry(Page));
+ Page = Page - SizeInPages + 1;
+ ASSERT(Pfn1 == MI_PFN_ELEMENT(Page));
ASSERT(Page != 0);
+
+ /* Enable APCs and return the page */
+ KeLeaveGuardedRegion();
return Page;
}
@@ -354,7 +366,7 @@ MiFindContiguousMemory(IN PFN_NUMBER LowestPfn,
/* Write the PTE address */
Pfn1->PteAddress = PointerPte;
Pfn1->u4.PteFrame = PFN_FROM_PTE(MiAddressToPte(PointerPte++));
- } while (Pfn1++ < EndPfn);
+ } while (++Pfn1 < EndPfn);
/* Return the address */
return BaseAddress;
diff --git a/ntoskrnl/mm/ARM3/expool.c b/ntoskrnl/mm/ARM3/expool.c
index 4a93c072a86..120050e6aca 100644
--- a/ntoskrnl/mm/ARM3/expool.c
+++ b/ntoskrnl/mm/ARM3/expool.c
@@ -248,7 +248,7 @@ VOID
NTAPI
ExpCheckPoolBlocks(IN PVOID Block)
{
- BOOLEAN FoundBlock;
+ BOOLEAN FoundBlock = FALSE;
SIZE_T Size = 0;
PPOOL_HEADER Entry;
@@ -288,6 +288,7 @@ ExpCheckPoolBlocks(IN PVOID Block)
VOID
NTAPI
+INIT_FUNCTION
ExInitializePoolDescriptor(IN PPOOL_DESCRIPTOR PoolDescriptor,
IN POOL_TYPE PoolType,
IN ULONG PoolIndex,
@@ -333,6 +334,7 @@ ExInitializePoolDescriptor(IN PPOOL_DESCRIPTOR PoolDescriptor,
VOID
NTAPI
+INIT_FUNCTION
InitializePool(IN POOL_TYPE PoolType,
IN ULONG Threshold)
{
diff --git a/ntoskrnl/mm/ARM3/i386/init.c b/ntoskrnl/mm/ARM3/i386/init.c
index cfb77c6e33c..70707a6e98a 100644
--- a/ntoskrnl/mm/ARM3/i386/init.c
+++ b/ntoskrnl/mm/ARM3/i386/init.c
@@ -24,6 +24,7 @@ MMPTE ValidKernelPte = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1,
/* Template PDE for a demand-zero page */
MMPDE DemandZeroPde = {.u.Long = (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS)};
+MMPTE DemandZeroPte = {.u.Long = (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS)};
/* Template PTE for prototype page */
MMPTE PrototypePte = {.u.Long = (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS) | PTE_PROTOTYPE | (MI_PTE_LOOKUP_NEEDED << PAGE_SHIFT)};
@@ -32,6 +33,7 @@ MMPTE PrototypePte = {.u.Long = (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS
VOID
NTAPI
+INIT_FUNCTION
MiComputeNonPagedPoolVa(IN ULONG FreePages)
{
IN PFN_NUMBER PoolPages;
@@ -147,6 +149,7 @@ MiComputeNonPagedPoolVa(IN ULONG FreePages)
NTSTATUS
NTAPI
+INIT_FUNCTION
MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PLIST_ENTRY NextEntry;
@@ -157,7 +160,9 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
MMPTE TempPde, TempPte;
PVOID NonPagedPoolExpansionVa;
KIRQL OldIrql;
-
+ PMMPFN Pfn1;
+ ULONG Flags;
+
/* Check for kernel stack size that's too big */
if (MmLargeStackSize > (KERNEL_LARGE_STACK_SIZE / _1KB))
{
@@ -196,7 +201,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
//
// Set CR3 for the system process
//
- PointerPte = MiAddressToPde(PTE_BASE);
+ PointerPte = MiAddressToPde(PDE_BASE);
PageFrameIndex = PFN_FROM_PTE(PointerPte) << PAGE_SHIFT;
PsGetCurrentProcess()->Pcb.DirectoryTableBase[0] = PageFrameIndex;
@@ -307,11 +312,10 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
MiComputeColorInformation();
//
- // Calculate the number of bytes for the PFN database, double it for ARM3,
+ // Calculate the number of bytes for the PFN database
// then add the color tables and convert to pages
//
MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN);
- //MxPfnAllocation <<= 1;
MxPfnAllocation += (MmSecondaryColors * sizeof(MMCOLOR_TABLES) * 2);
MxPfnAllocation >>= PAGE_SHIFT;
@@ -531,6 +535,8 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Allocate a page for hyperspace and create it */
+ MI_SET_USAGE(MI_USAGE_PAGE_TABLE);
+ MI_SET_PROCESS2("Kernel");
PageFrameIndex = MiRemoveAnyPage(0);
TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
TempPde.u.Hard.Global = FALSE; // Hyperspace is local!
@@ -554,6 +560,9 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
MmFirstReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_START);
MmLastReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_END);
MmFirstReservedMappingPte->u.Hard.PageFrameNumber = MI_HYPERSPACE_PTES;
+
+ /* Set the working set address */
+ MmWorkingSetList = (PVOID)MI_WORKING_SET_LIST;
//
// Reserve system PTEs for zeroing PTEs and clear them
@@ -567,16 +576,75 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
//
MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES - 1;
+ /* Lock PFN database */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Reset the ref/share count so that MmInitializeProcessAddressSpace works */
+ Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(MiAddressToPde(PDE_BASE)));
+ Pfn1->u2.ShareCount = 0;
+ Pfn1->u3.e2.ReferenceCount = 0;
+
+ /* Get a page for the working set list */
+ MI_SET_USAGE(MI_USAGE_PAGE_TABLE);
+ MI_SET_PROCESS2("Kernel WS List");
+ PageFrameIndex = MiRemoveAnyPage(0);
+ TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
+
+ /* Map the working set list */
+ PointerPte = MiAddressToPte(MmWorkingSetList);
+ MI_WRITE_VALID_PTE(PointerPte, TempPte);
+
+ /* Zero it out, and save the frame index */
+ RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE);
+ PsGetCurrentProcess()->WorkingSetPage = PageFrameIndex;
+
/* Check for Pentium LOCK errata */
if (KiI386PentiumLockErrataPresent)
{
/* Mark the 1st IDT page as Write-Through to prevent a lockup
- on a FOOF instruction.
+ on a F00F instruction.
See http://www.rcollins.org/Errata/Dec97/F00FBug.html */
PointerPte = MiAddressToPte(KeGetPcr()->IDT);
PointerPte->u.Hard.WriteThrough = 1;
}
+ /* Release the lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* Initialize the bogus address space */
+ Flags = 0;
+ MmInitializeProcessAddressSpace(PsGetCurrentProcess(), NULL, NULL, &Flags, NULL);
+
+ /* Make sure the color lists are valid */
+ ASSERT(MmFreePagesByColor[0] < (PMMCOLOR_TABLES)PTE_BASE);
+ StartPde = MiAddressToPde(MmFreePagesByColor[0]);
+ ASSERT(StartPde->u.Hard.Valid == 1);
+ PointerPte = MiAddressToPte(MmFreePagesByColor[0]);
+ ASSERT(PointerPte->u.Hard.Valid == 1);
+ LastPte = MiAddressToPte((ULONG_PTR)&MmFreePagesByColor[1][MmSecondaryColors] - 1);
+ ASSERT(LastPte->u.Hard.Valid == 1);
+
+ /* Loop the color list PTEs */
+ while (PointerPte <= LastPte)
+ {
+ /* Get the PFN entry */
+ Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
+ if (!Pfn1->u3.e2.ReferenceCount)
+ {
+ /* Fill it out */
+ Pfn1->u4.PteFrame = PFN_FROM_PTE(StartPde);
+ Pfn1->PteAddress = PointerPte;
+ Pfn1->u2.ShareCount++;
+ Pfn1->u3.e2.ReferenceCount = 1;
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
+ Pfn1->u3.e1.CacheAttribute = MiCached;
+ }
+
+ /* Keep going */
+ PointerPte++;
+ }
+
+ /* All done */
return STATUS_SUCCESS;
}
diff --git a/ntoskrnl/mm/ARM3/largepag.c b/ntoskrnl/mm/ARM3/largepag.c
index 01917b89876..601542b4005 100644
--- a/ntoskrnl/mm/ARM3/largepag.c
+++ b/ntoskrnl/mm/ARM3/largepag.c
@@ -31,6 +31,7 @@ BOOLEAN MiLargePageAllDrivers;
VOID
NTAPI
+INIT_FUNCTION
MiInitializeLargePageSupport(VOID)
{
#if _MI_PAGING_LEVELS > 2
@@ -50,6 +51,7 @@ MiInitializeLargePageSupport(VOID)
VOID
NTAPI
+INIT_FUNCTION
MiSyncCachedRanges(VOID)
{
ULONG i;
@@ -64,6 +66,7 @@ MiSyncCachedRanges(VOID)
VOID
NTAPI
+INIT_FUNCTION
MiInitializeDriverLargePageList(VOID)
{
PWCHAR p, pp;
diff --git a/ntoskrnl/mm/ARM3/mdlsup.c b/ntoskrnl/mm/ARM3/mdlsup.c
index c7dd00db38e..f956bb7725d 100644
--- a/ntoskrnl/mm/ARM3/mdlsup.c
+++ b/ntoskrnl/mm/ARM3/mdlsup.c
@@ -16,8 +16,11 @@
#define MODULE_INVOLVED_IN_ARM3
#include "../ARM3/miarm.h"
+/* GLOBALS ********************************************************************/
+
BOOLEAN MmTrackPtes;
BOOLEAN MmTrackLockedPages;
+SIZE_T MmSystemLockPagesCount;
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -248,34 +251,47 @@ MmFreePagesFromMdl(IN PMDL Mdl)
//
// Reached the last page
//
- if (*Pages == -1) break;
-
- //
- // Sanity check
- //
- ASSERT(*Pages <= MmHighestPhysicalPage);
-
+ if (*Pages == LIST_HEAD) break;
+
//
// Get the page entry
//
Pfn1 = MiGetPfnEntry(*Pages);
- ASSERT(Pfn1->u3.ReferenceCount == 1);
+ ASSERT(Pfn1);
+ ASSERT(Pfn1->u2.ShareCount == 1);
+ ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
+ if (Pfn1->u4.PteFrame != 0x1FFEDCB)
+ {
+ /* Corrupted PFN entry or invalid free */
+ KeBugCheckEx(MEMORY_MANAGEMENT, 0x1236, (ULONG_PTR)Mdl, (ULONG_PTR)Pages, *Pages);
+ }
//
// Clear it
//
Pfn1->u3.e1.StartOfAllocation = 0;
Pfn1->u3.e1.EndOfAllocation = 0;
+ Pfn1->u2.ShareCount = 0;
//
// Dereference it
//
- MmDereferencePage(*Pages);
+ ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
+ if (Pfn1->u3.e2.ReferenceCount != 1)
+ {
+ /* Just take off one reference */
+ InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
+ }
+ else
+ {
+ /* We'll be nuking the whole page */
+ MiDecrementReferenceCount(Pfn1, *Pages);
+ }
//
// Clear this page and move on
//
- *Pages++ = -1;
+ *Pages++ = LIST_HEAD;
} while (--NumberOfPages != 0);
//
@@ -411,7 +427,7 @@ MmMapLockedPagesSpecifyCache(IN PMDL Mdl,
//
// We're done here
//
- if (*MdlPages == -1) break;
+ if (*MdlPages == LIST_HEAD) break;
//
// Write the PTE
@@ -573,13 +589,14 @@ MmProbeAndLockPages(IN PMDL Mdl,
ULONG LockPages, TotalPages;
NTSTATUS Status = STATUS_SUCCESS;
PEPROCESS CurrentProcess;
- PMMSUPPORT AddressSpace;
NTSTATUS ProbeStatus;
PMMPTE PointerPte, LastPte;
PMMPDE PointerPde;
PFN_NUMBER PageFrameIndex;
BOOLEAN UsePfnLock;
KIRQL OldIrql;
+ USHORT OldRefCount, RefCount;
+ PMMPFN Pfn1;
DPRINT("Probing MDL: %p\n", Mdl);
//
@@ -608,8 +625,17 @@ MmProbeAndLockPages(IN PMDL Mdl,
LockPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Address, Mdl->ByteCount);
ASSERT(LockPages != 0);
+ /* Block invalid access */
+ if ((AccessMode != KernelMode) &&
+ ((LastAddress > (PVOID)MM_USER_PROBE_ADDRESS) || (Address >= LastAddress)))
+ {
+ /* Caller should be in SEH, raise the error */
+ *MdlPages = LIST_HEAD;
+ ExRaiseStatus(STATUS_ACCESS_VIOLATION);
+ }
+
//
- // Get theprocess
+ // Get the process
//
if (Address <= MM_HIGHEST_USER_ADDRESS)
{
@@ -632,6 +658,9 @@ MmProbeAndLockPages(IN PMDL Mdl,
TotalPages = LockPages;
StartAddress = Address;
+ /* Large pages not supported */
+ ASSERT(!MI_IS_PHYSICAL_ADDRESS(Address));
+
//
// Now probe them
//
@@ -646,7 +675,7 @@ MmProbeAndLockPages(IN PMDL Mdl,
//
// Assume failure
//
- *MdlPages = -1;
+ *MdlPages = LIST_HEAD;
//
// Read
@@ -668,8 +697,7 @@ MmProbeAndLockPages(IN PMDL Mdl,
//
// Next address...
//
- Address = (PVOID)((ULONG_PTR)Address + PAGE_SIZE);
- Address = PAGE_ALIGN(Address);
+ Address = PAGE_ALIGN((ULONG_PTR)Address + PAGE_SIZE);
//
// Next page...
@@ -711,6 +739,10 @@ MmProbeAndLockPages(IN PMDL Mdl,
//
PointerPte = MiAddressToPte(StartAddress);
PointerPde = MiAddressToPde(StartAddress);
+#if (_MI_PAGING_LEVELS >= 3)
+ DPRINT1("PAE/x64 Not Implemented\n");
+ ASSERT(FALSE);
+#endif
//
// Sanity check
@@ -761,7 +793,6 @@ MmProbeAndLockPages(IN PMDL Mdl,
//
UsePfnLock = TRUE;
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- AddressSpace = NULL; // Keep compiler happy
}
else
{
@@ -782,13 +813,10 @@ MmProbeAndLockPages(IN PMDL Mdl,
//
Mdl->Process = CurrentProcess;
- //
- // Use the process lock
- //
+ /* Lock the process working set */
+ MiLockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
UsePfnLock = FALSE;
- AddressSpace = &CurrentProcess->Vm;
- MmLockAddressSpace(AddressSpace);
- OldIrql = DISPATCH_LEVEL; // Keep compiler happy
+ OldIrql = MM_NOIRQL;
}
//
@@ -804,7 +832,7 @@ MmProbeAndLockPages(IN PMDL Mdl,
//
// Assume failure and check for non-mapped pages
//
- *MdlPages = -1;
+ *MdlPages = LIST_HEAD;
#if (_MI_PAGING_LEVELS >= 3)
/* Should be checking the PPE and PXE */
ASSERT(FALSE);
@@ -824,10 +852,8 @@ MmProbeAndLockPages(IN PMDL Mdl,
}
else
{
- //
- // Release process address space lock
- //
- MmUnlockAddressSpace(AddressSpace);
+ /* Release process working set */
+ MiUnlockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
}
//
@@ -856,10 +882,8 @@ MmProbeAndLockPages(IN PMDL Mdl,
}
else
{
- //
- // Use the address space lock
- //
- MmLockAddressSpace(AddressSpace);
+ /* Lock the process working set */
+ MiLockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
}
}
@@ -896,10 +920,8 @@ MmProbeAndLockPages(IN PMDL Mdl,
}
else
{
- //
- // Release process address space lock
- //
- MmUnlockAddressSpace(AddressSpace);
+ /* Release process working set */
+ MiUnlockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
}
//
@@ -927,10 +949,8 @@ MmProbeAndLockPages(IN PMDL Mdl,
}
else
{
- //
- // Use the address space lock
- //
- MmLockAddressSpace(AddressSpace);
+ /* Lock the process working set */
+ MiLockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
}
//
@@ -952,14 +972,55 @@ MmProbeAndLockPages(IN PMDL Mdl,
// Grab the PFN
//
PageFrameIndex = PFN_FROM_PTE(PointerPte);
- if (PageFrameIndex <= MmHighestPhysicalPage)
+ Pfn1 = MiGetPfnEntry(PageFrameIndex);
+ if (Pfn1)
{
+ /* Either this is for kernel-mode, or the working set is held */
ASSERT((CurrentProcess == NULL) || (UsePfnLock == FALSE));
- //
- // Now lock the page
- //
- MmReferencePage(PageFrameIndex);
+ /* No Physical VADs supported yet */
+ if (CurrentProcess) ASSERT(CurrentProcess->PhysicalVadRoot == NULL);
+
+ /* This address should already exist and be fully valid */
+ ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
+ if (MI_IS_ROS_PFN(Pfn1))
+ {
+ /* ReactOS Mm doesn't track share count */
+ ASSERT(Pfn1->u3.e1.PageLocation == ActiveAndValid);
+ }
+ else
+ {
+ /* On ARM3 pages, we should see a valid share count */
+ ASSERT((Pfn1->u2.ShareCount != 0) && (Pfn1->u3.e1.PageLocation == ActiveAndValid));
+
+ /* We don't support mapping a prototype page yet */
+ ASSERT((Pfn1->u3.e1.PrototypePte == 0) && (Pfn1->OriginalPte.u.Soft.Prototype == 0));
+ }
+
+ /* More locked pages! */
+ InterlockedExchangeAddSizeT(&MmSystemLockPagesCount, 1);
+
+ /* Loop trying to update the reference count */
+ do
+ {
+ /* Get the current reference count, make sure it's valid */
+ OldRefCount = Pfn1->u3.e2.ReferenceCount;
+ ASSERT(OldRefCount != 0);
+ ASSERT(OldRefCount < 2500);
+
+ /* Bump it up by one */
+ RefCount = InterlockedCompareExchange16((PSHORT)&Pfn1->u3.e2.ReferenceCount,
+ OldRefCount + 1,
+ OldRefCount);
+ ASSERT(RefCount != 0);
+ } while (OldRefCount != RefCount);
+
+ /* Was this the first lock attempt? */
+ if (OldRefCount != 1)
+ {
+ /* Someone else came through */
+ InterlockedExchangeAddSizeT(&MmSystemLockPagesCount, -1);
+ }
}
else
{
@@ -973,7 +1034,10 @@ MmProbeAndLockPages(IN PMDL Mdl,
// Write the page and move on
//
*MdlPages++ = PageFrameIndex;
- if (!((ULONG_PTR)(++PointerPte) & (PAGE_SIZE - 1))) PointerPde++;
+ PointerPte++;
+
+ /* Check if we're on a PDE boundary */
+ if (!((ULONG_PTR)PointerPte & (PD_SIZE - 1))) PointerPde++;
} while (PointerPte <= LastPte);
//
@@ -988,10 +1052,8 @@ MmProbeAndLockPages(IN PMDL Mdl,
}
else
{
- //
- // Release process address space lock
- //
- MmUnlockAddressSpace(AddressSpace);
+ /* Release process working set */
+ MiUnlockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
}
//
@@ -1018,10 +1080,8 @@ CleanupWithLock:
}
else
{
- //
- // Release process address space lock
- //
- MmUnlockAddressSpace(AddressSpace);
+ /* Release process working set */
+ MiUnlockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
}
Cleanup:
//
@@ -1048,6 +1108,8 @@ MmUnlockPages(IN PMDL Mdl)
PVOID Base;
ULONG Flags, PageCount;
KIRQL OldIrql;
+ USHORT RefCount, OldRefCount;
+ PMMPFN Pfn1;
DPRINT("Unlocking MDL: %p\n", Mdl);
//
@@ -1107,17 +1169,71 @@ MmUnlockPages(IN PMDL Mdl)
//
// Last page, break out
//
- if (*MdlPages == -1) break;
+ if (*MdlPages == LIST_HEAD) break;
//
// Check if this page is in the PFN database
//
- if (*MdlPages <= MmHighestPhysicalPage)
+ Pfn1 = MiGetPfnEntry(*MdlPages);
+ if (Pfn1);
{
- //
- // Unlock and dereference
- //
- MmDereferencePage(*MdlPages);
+ /* Get the current entry and reference count */
+ OldRefCount = Pfn1->u3.e2.ReferenceCount;
+ ASSERT(OldRefCount != 0);
+
+ /* Is this already the last dereference */
+ if (OldRefCount == 1)
+ {
+ /* It should be on a free list waiting for us */
+ ASSERT(Pfn1->u3.e2.ReferenceCount == 1);
+ ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
+ ASSERT(Pfn1->u2.ShareCount == 0);
+
+ /* Not supported yet */
+ ASSERT(((Pfn1->u3.e1.PrototypePte == 0) &&
+ (Pfn1->OriginalPte.u.Soft.Prototype == 0)));
+
+ /* One less page */
+ InterlockedExchangeAddSizeT(&MmSystemLockPagesCount, -1);
+
+ /* Do the last dereference, we're done here */
+ MiDecrementReferenceCount(Pfn1, *MdlPages);
+ }
+ else
+ {
+ /* Loop decrementing one reference */
+ do
+ {
+ /* Make sure it's still valid */
+ OldRefCount = Pfn1->u3.e2.ReferenceCount;
+ ASSERT(OldRefCount != 0);
+
+ /* Take off one reference */
+ RefCount = InterlockedCompareExchange16((PSHORT)&Pfn1->u3.e2.ReferenceCount,
+ OldRefCount - 1,
+ OldRefCount);
+ ASSERT(RefCount != 0);
+ } while (OldRefCount != RefCount);
+ ASSERT(RefCount > 1);
+
+ /* Are there only lock references left? */
+ if (RefCount == 2)
+ {
+ /* And does the page still have users? */
+ if (Pfn1->u2.ShareCount >= 1)
+ {
+ /* Then it should still be valid */
+ ASSERT(Pfn1->u3.e1.PageLocation == ActiveAndValid);
+
+ /* Not supported yet */
+ ASSERT(((Pfn1->u3.e1.PrototypePte == 0) &&
+ (Pfn1->OriginalPte.u.Soft.Prototype == 0)));
+
+ /* But there is one less "locked" page though */
+ InterlockedExchangeAddSizeT(&MmSystemLockPagesCount, -1);
+ }
+ }
+ }
}
} while (++MdlPages < LastPage);
@@ -1169,7 +1285,7 @@ MmUnlockPages(IN PMDL Mdl)
//
// Last page reached
//
- if (*MdlPages == -1)
+ if (*MdlPages == LIST_HEAD)
{
//
// Were there no pages at all?
@@ -1190,10 +1306,9 @@ MmUnlockPages(IN PMDL Mdl)
break;
}
- //
- // Sanity check
- //
- ASSERT(*MdlPages <= MmHighestPhysicalPage);
+ /* Save the PFN entry instead for the secondary loop */
+ *MdlPages = (PFN_NUMBER)MiGetPfnEntry(*MdlPages);
+ ASSERT((*MdlPages) != 0);
} while (++MdlPages < LastPage);
//
@@ -1207,10 +1322,64 @@ MmUnlockPages(IN PMDL Mdl)
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
do
{
- //
- // Unlock and dereference
- //
- MmDereferencePage(*MdlPages);
+ /* Get the current entry and reference count */
+ Pfn1 = (PMMPFN)(*MdlPages);
+ OldRefCount = Pfn1->u3.e2.ReferenceCount;
+ ASSERT(OldRefCount != 0);
+
+ /* Is this already the last dereference */
+ if (OldRefCount == 1)
+ {
+ /* It should be on a free list waiting for us */
+ ASSERT(Pfn1->u3.e2.ReferenceCount == 1);
+ ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
+ ASSERT(Pfn1->u2.ShareCount == 0);
+
+ /* Not supported yet */
+ ASSERT(((Pfn1->u3.e1.PrototypePte == 0) &&
+ (Pfn1->OriginalPte.u.Soft.Prototype == 0)));
+
+ /* One less page */
+ InterlockedExchangeAddSizeT(&MmSystemLockPagesCount, -1);
+
+ /* Do the last dereference, we're done here */
+ MiDecrementReferenceCount(Pfn1, MiGetPfnEntryIndex(Pfn1));
+ }
+ else
+ {
+ /* Loop decrementing one reference */
+ do
+ {
+ /* Make sure it's still valid */
+ OldRefCount = Pfn1->u3.e2.ReferenceCount;
+ ASSERT(OldRefCount != 0);
+
+ /* Take off one reference */
+ RefCount = InterlockedCompareExchange16((PSHORT)&Pfn1->u3.e2.ReferenceCount,
+ OldRefCount - 1,
+ OldRefCount);
+ ASSERT(RefCount != 0);
+ } while (OldRefCount != RefCount);
+ ASSERT(RefCount > 1);
+
+ /* Are there only lock references left? */
+ if (RefCount == 2)
+ {
+ /* And does the page still have users? */
+ if (Pfn1->u2.ShareCount >= 1)
+ {
+ /* Then it should still be valid */
+ ASSERT(Pfn1->u3.e1.PageLocation == ActiveAndValid);
+
+ /* Not supported yet */
+ ASSERT(((Pfn1->u3.e1.PrototypePte == 0) &&
+ (Pfn1->OriginalPte.u.Soft.Prototype == 0)));
+
+ /* But there is one less "locked" page though */
+ InterlockedExchangeAddSizeT(&MmSystemLockPagesCount, -1);
+ }
+ }
+ }
} while (++MdlPages < LastPage);
//
diff --git a/ntoskrnl/mm/ARM3/miarm.h b/ntoskrnl/mm/ARM3/miarm.h
index 8338173ce16..cfa99d77330 100644
--- a/ntoskrnl/mm/ARM3/miarm.h
+++ b/ntoskrnl/mm/ARM3/miarm.h
@@ -130,12 +130,12 @@ C_ASSERT(SYSTEM_PD_SIZE == PAGE_SIZE);
//
// Access Flags
//
-#define PTE_READONLY 0
+#define PTE_READONLY 0 // Doesn't exist on x86
#define PTE_EXECUTE 0 // Not worrying about NX yet
#define PTE_EXECUTE_READ 0 // Not worrying about NX yet
#define PTE_READWRITE 0x2
#define PTE_WRITECOPY 0x200
-#define PTE_EXECUTE_READWRITE 0x0
+#define PTE_EXECUTE_READWRITE 0x2 // Not worrying about NX yet
#define PTE_EXECUTE_WRITECOPY 0x200
#define PTE_PROTOTYPE 0x400
//
@@ -145,6 +145,20 @@ C_ASSERT(SYSTEM_PD_SIZE == PAGE_SIZE);
#define PTE_DISABLE_CACHE 0x10
#define PTE_WRITECOMBINED_CACHE 0x10
#elif defined(_M_ARM)
+#define PTE_READONLY 0x200
+#define PTE_EXECUTE 0 // Not worrying about NX yet
+#define PTE_EXECUTE_READ 0 // Not worrying about NX yet
+#define PTE_READWRITE 0 // Doesn't exist on ARM
+#define PTE_WRITECOPY 0 // Doesn't exist on ARM
+#define PTE_EXECUTE_READWRITE 0 // Not worrying about NX yet
+#define PTE_EXECUTE_WRITECOPY 0 // Not worrying about NX yet
+#define PTE_PROTOTYPE 0x400 // Using the Shared bit
+//
+// Cache flags
+//
+#define PTE_ENABLE_CACHE 0
+#define PTE_DISABLE_CACHE 0x10
+#define PTE_WRITECOMBINED_CACHE 0x10
#else
#error Define these please!
#endif
@@ -179,7 +193,7 @@ extern const ULONG MmProtectToValue[32];
#ifdef _M_IX86
#define MM_PTE_SOFTWARE_PROTECTION_BITS 5
#elif _M_ARM
-#define MM_PTE_SOFTWARE_PROTECTION_BITS 5
+#define MM_PTE_SOFTWARE_PROTECTION_BITS 6
#elif _M_AMD64
#define MM_PTE_SOFTWARE_PROTECTION_BITS 5
#else
@@ -235,13 +249,13 @@ extern const ULONG MmProtectToValue[32];
#define MI_GET_NEXT_COLOR(x) (MI_GET_PAGE_COLOR(++MmSystemPageColor))
#define MI_GET_NEXT_PROCESS_COLOR(x) (MI_GET_PAGE_COLOR(++(x)->NextPageColor))
-#ifdef _M_IX86
+#ifndef _M_AMD64
//
// Decodes a Prototype PTE into the underlying PTE
//
#define MiProtoPteToPte(x) \
(PMMPTE)((ULONG_PTR)MmPagedPoolStart + \
- ((x)->u.Proto.ProtoAddressHigh | (x)->u.Proto.ProtoAddressLow))
+ (((x)->u.Proto.ProtoAddressHigh << 7) | (x)->u.Proto.ProtoAddressLow))
#endif
//
@@ -403,6 +417,7 @@ extern MMPTE HyperTemplatePte;
extern MMPDE ValidKernelPde;
extern MMPTE ValidKernelPte;
extern MMPDE DemandZeroPde;
+extern MMPTE DemandZeroPte;
extern MMPTE PrototypePte;
extern BOOLEAN MmLargeSystemCache;
extern BOOLEAN MmZeroPageFile;
@@ -461,7 +476,7 @@ extern PMMPTE MiSessionImagePteEnd;
extern PMMPTE MiSessionBasePte;
extern PMMPTE MiSessionLastPte;
extern SIZE_T MmSizeOfPagedPoolInBytes;
-extern PMMPTE MmSystemPagePtes;
+extern PMMPDE MmSystemPagePtes;
extern PVOID MmSystemCacheStart;
extern PVOID MmSystemCacheEnd;
extern MMSUPPORT MmSystemCacheWs;
@@ -512,13 +527,14 @@ extern BOOLEAN MmZeroingPageThreadActive;
extern KEVENT MmZeroingPageEvent;
extern ULONG MmSystemPageColor;
extern ULONG MmProcessColorSeed;
+extern PMMWSL MmWorkingSetList;
//
// Figures out the hardware bits for a PTE
//
ULONG
FORCEINLINE
-MiDetermineUserGlobalPteMask(IN PMMPTE PointerPte)
+MiDetermineUserGlobalPteMask(IN PVOID PointerPte)
{
MMPTE TempPte;
@@ -527,14 +543,15 @@ MiDetermineUserGlobalPteMask(IN PMMPTE PointerPte)
/* Make it valid and accessed */
TempPte.u.Hard.Valid = TRUE;
- TempPte.u.Hard.Accessed = TRUE;
+ MI_MAKE_ACCESSED_PAGE(&TempPte);
/* Is this for user-mode? */
- if ((PointerPte <= MiHighestUserPte) ||
- ((PointerPte >= MiAddressToPde(NULL)) && (PointerPte <= MiHighestUserPde)))
+ if ((PointerPte <= (PVOID)MiHighestUserPte) ||
+ ((PointerPte >= (PVOID)MiAddressToPde(NULL)) &&
+ (PointerPte <= (PVOID)MiHighestUserPde)))
{
/* Set the owner bit */
- TempPte.u.Hard.Owner = TRUE;
+ MI_MAKE_OWNER_PAGE(&TempPte);
}
/* FIXME: We should also set the global bit */
@@ -604,7 +621,7 @@ MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte,
NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
}
-#ifdef _M_IX86
+#ifndef _M_AMD64
//
// Builds a Prototype PTE for the address of the PTE
//
@@ -624,10 +641,11 @@ MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte,
* lets us only use 28 bits for the adress of the PTE
*/
Offset = (ULONG_PTR)PointerPte - (ULONG_PTR)MmPagedPoolStart;
-
+
/* 7 bits go in the "low", and the other 21 bits go in the "high" */
NewPte->u.Proto.ProtoAddressLow = Offset & 0x7F;
- NewPte->u.Proto.ProtoAddressHigh = Offset & 0xFFFFF80;
+ NewPte->u.Proto.ProtoAddressHigh = (Offset & 0xFFFFFF80) >> 7;
+ ASSERT(MiProtoPteToPte(NewPte) == PointerPte);
}
#endif
@@ -673,6 +691,33 @@ MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte,
*PointerPte = InvalidPte;
}
+//
+// Writes a valid PDE
+//
+VOID
+FORCEINLINE
+MI_WRITE_VALID_PDE(IN PMMPDE PointerPde,
+ IN MMPDE TempPde)
+{
+ /* Write the valid PDE */
+ ASSERT(PointerPde->u.Hard.Valid == 0);
+ ASSERT(TempPde.u.Hard.Valid == 1);
+ *PointerPde = TempPde;
+}
+
+//
+// Writes an invalid PDE
+//
+VOID
+FORCEINLINE
+MI_WRITE_INVALID_PDE(IN PMMPDE PointerPde,
+ IN MMPDE InvalidPde)
+{
+ /* Write the invalid PDE */
+ ASSERT(InvalidPde.u.Hard.Valid == 0);
+ *PointerPde = InvalidPde;
+}
+
//
// Checks if the thread already owns a working set
//
@@ -832,7 +877,35 @@ MiUnlockWorkingSet(IN PETHREAD Thread,
KeLeaveGuardedRegion();
}
-NTSTATUS
+//
+// Returns the ProtoPTE inside a VAD for the given VPN
+//
+FORCEINLINE
+PMMPTE
+MI_GET_PROTOTYPE_PTE_FOR_VPN(IN PMMVAD Vad,
+ IN ULONG_PTR Vpn)
+{
+ PMMPTE ProtoPte;
+
+ /* Find the offset within the VAD's prototype PTEs */
+ ProtoPte = Vad->FirstPrototypePte + (Vpn - Vad->StartingVpn);
+ ASSERT(ProtoPte <= Vad->LastContiguousPte);
+ return ProtoPte;
+}
+
+//
+// Returns the PFN Database entry for the given page number
+// Warning: This is not necessarily a valid PFN database entry!
+//
+FORCEINLINE
+PMMPFN
+MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
+{
+ /* Get the entry */
+ return &MmPfnDatabase[Pfn];
+};
+
+BOOLEAN
NTAPI
MmArmInitSystem(
IN ULONG Phase,
@@ -1058,6 +1131,13 @@ MiDecrementShareCount(
IN PFN_NUMBER PageFrameIndex
);
+VOID
+NTAPI
+MiDecrementReferenceCount(
+ IN PMMPFN Pfn1,
+ IN PFN_NUMBER PageFrameIndex
+);
+
PFN_NUMBER
NTAPI
MiRemoveAnyPage(
@@ -1217,6 +1297,27 @@ MiMakeSystemAddressValid(
IN PVOID PageTableVirtualAddress,
IN PEPROCESS CurrentProcess
);
+
+ULONG
+NTAPI
+MiMakeSystemAddressValidPfn(
+ IN PVOID VirtualAddress,
+ IN KIRQL OldIrql
+);
+
+VOID
+NTAPI
+MiRemoveMappedView(
+ IN PEPROCESS CurrentProcess,
+ IN PMMVAD Vad
+);
+
+PSUBSECTION
+NTAPI
+MiLocateSubsection(
+ IN PMMVAD Vad,
+ IN ULONG_PTR Vpn
+);
//
// MiRemoveZeroPage will use inline code to zero out the page manually if only
@@ -1233,4 +1334,18 @@ MiRemoveZeroPageSafe(IN ULONG Color)
return 0;
}
+//
+// New ARM3<->RosMM PAGE Architecture
+//
+#define MI_GET_ROS_DATA(x) ((PMMROSPFN)(x->RosMmData))
+#define MI_IS_ROS_PFN(x) (((x)->u4.AweAllocation == TRUE) && (MI_GET_ROS_DATA(x) != NULL))
+#define ASSERT_IS_ROS_PFN(x) ASSERT(MI_IS_ROS_PFN(x) == TRUE);
+typedef struct _MMROSPFN
+{
+ PMM_RMAP_ENTRY RmapListHead;
+ SWAPENTRY SwapEntry;
+} MMROSPFN, *PMMROSPFN;
+
+#define RosMmData AweReferenceCount
+
/* EOF */
diff --git a/ntoskrnl/mm/ARM3/mminit.c b/ntoskrnl/mm/ARM3/mminit.c
index 76df1586996..b977a65152a 100644
--- a/ntoskrnl/mm/ARM3/mminit.c
+++ b/ntoskrnl/mm/ARM3/mminit.c
@@ -161,7 +161,7 @@ SIZE_T MmSystemViewSize;
// address.
//
PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
-PMMPTE MmSystemPagePtes;
+PMMPDE MmSystemPagePtes;
#endif
//
@@ -353,35 +353,19 @@ SIZE_T MmAllocationFragment;
SIZE_T MmTotalCommitLimit;
SIZE_T MmTotalCommitLimitMaximum;
-/* PRIVATE FUNCTIONS **********************************************************/
-
-#ifndef _M_AMD64
-//
-// In Bavaria, this is probably a hate crime
-//
-VOID
-FASTCALL
-MiSyncARM3WithROS(IN PVOID AddressStart,
- IN PVOID AddressEnd)
-{
- //
- // Puerile piece of junk-grade carbonized horseshit puss sold to the lowest bidder
- //
- ULONG Pde = ADDR_TO_PDE_OFFSET(AddressStart);
- while (Pde <= ADDR_TO_PDE_OFFSET(AddressEnd))
- {
- //
- // This both odious and heinous
- //
- extern ULONG MmGlobalKernelPageDirectory[1024];
- MmGlobalKernelPageDirectory[Pde] = ((PULONG)PDE_BASE)[Pde];
- Pde++;
- }
-}
+/* Internal setting used for debugging memory descriptors */
+BOOLEAN MiDbgEnableMdDump =
+#ifdef _ARM_
+TRUE;
+#else
+FALSE;
#endif
+/* PRIVATE FUNCTIONS **********************************************************/
+
PFN_NUMBER
NTAPI
+INIT_FUNCTION
MxGetNextPage(IN PFN_NUMBER PageCount)
{
PFN_NUMBER Pfn;
@@ -406,6 +390,7 @@ MxGetNextPage(IN PFN_NUMBER PageCount)
VOID
NTAPI
+INIT_FUNCTION
MiComputeColorInformation(VOID)
{
ULONG L2Associativity;
@@ -459,6 +444,7 @@ MiComputeColorInformation(VOID)
VOID
NTAPI
+INIT_FUNCTION
MiInitializeColorTables(VOID)
{
ULONG i;
@@ -508,6 +494,7 @@ MiInitializeColorTables(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
MiIsRegularMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PFN_NUMBER Pfn)
{
@@ -566,6 +553,7 @@ MiIsRegularMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
VOID
NTAPI
+INIT_FUNCTION
MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
ULONG FreePage, FreePageCount, PagesLeft, BasePage, PageCount;
@@ -661,6 +649,7 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PMMPDE PointerPde;
@@ -690,11 +679,15 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
/* Yes we do, set it up */
Pfn1 = MiGetPfnEntry(PageFrameIndex);
Pfn1->u4.PteFrame = StartupPdIndex;
- Pfn1->PteAddress = PointerPde;
+ Pfn1->PteAddress = (PMMPTE)PointerPde;
Pfn1->u2.ShareCount++;
Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->u3.e1.PageLocation = ActiveAndValid;
Pfn1->u3.e1.CacheAttribute = MiNonCached;
+#if MI_TRACE_PFNS
+ Pfn1->PfnUsage = MI_USAGE_INIT_MEMORY;
+ memcpy(Pfn1->ProcessName, "Initial PDE", 16);
+#endif
}
else
{
@@ -738,6 +731,10 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Pfn2->u3.e2.ReferenceCount = 1;
Pfn2->u3.e1.PageLocation = ActiveAndValid;
Pfn2->u3.e1.CacheAttribute = MiNonCached;
+#if MI_TRACE_PFNS
+ Pfn2->PfnUsage = MI_USAGE_INIT_MEMORY;
+ memcpy(Pfn1->ProcessName, "Initial PTE", 16);
+#endif
}
}
}
@@ -761,6 +758,7 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
MiBuildPfnDatabaseZeroPage(VOID)
{
PMMPFN Pfn1;
@@ -773,7 +771,7 @@ MiBuildPfnDatabaseZeroPage(VOID)
/* Make it a bogus page to catch errors */
PointerPde = MiAddressToPde(0xFFFFFFFF);
Pfn1->u4.PteFrame = PFN_FROM_PTE(PointerPde);
- Pfn1->PteAddress = PointerPde;
+ Pfn1->PteAddress = (PMMPTE)PointerPde;
Pfn1->u2.ShareCount++;
Pfn1->u3.e2.ReferenceCount = 0xFFF0;
Pfn1->u3.e1.PageLocation = ActiveAndValid;
@@ -783,6 +781,7 @@ MiBuildPfnDatabaseZeroPage(VOID)
VOID
NTAPI
+INIT_FUNCTION
MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PLIST_ENTRY NextEntry;
@@ -893,6 +892,9 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->u3.e1.PageLocation = ActiveAndValid;
Pfn1->u3.e1.CacheAttribute = MiNonCached;
+#if MI_TRACE_PFNS
+ Pfn1->PfnUsage = MI_USAGE_BOOT_DRIVER;
+#endif
/* Check for RAM disk page */
if (MdBlock->MemoryType == LoaderXIPRom)
@@ -923,6 +925,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
MiBuildPfnDatabaseSelf(VOID)
{
PMMPTE PointerPte, LastPte;
@@ -940,6 +943,9 @@ MiBuildPfnDatabaseSelf(VOID)
Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
Pfn1->u2.ShareCount = 1;
Pfn1->u3.e2.ReferenceCount = 1;
+#if MI_TRACE_PFNS
+ Pfn1->PfnUsage = MI_USAGE_PFN_DATABASE;
+#endif
}
/* Next */
@@ -949,6 +955,7 @@ MiBuildPfnDatabaseSelf(VOID)
VOID
NTAPI
+INIT_FUNCTION
MiInitializePfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
/* Scan memory and start setting up PFN entries */
@@ -966,6 +973,7 @@ MiInitializePfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID
NTAPI
+INIT_FUNCTION
MiAdjustWorkingSetManagerParameters(IN BOOLEAN Client)
{
/* This function needs to do more work, for now, we tune page minimums */
@@ -980,6 +988,7 @@ MiAdjustWorkingSetManagerParameters(IN BOOLEAN Client)
VOID
NTAPI
+INIT_FUNCTION
MiNotifyMemoryEvents(VOID)
{
/* Are we in a low-memory situation? */
@@ -1005,6 +1014,7 @@ MiNotifyMemoryEvents(VOID)
NTSTATUS
NTAPI
+INIT_FUNCTION
MiCreateMemoryEvent(IN PUNICODE_STRING Name,
OUT PKEVENT *Event)
{
@@ -1099,6 +1109,7 @@ CleanUp:
BOOLEAN
NTAPI
+INIT_FUNCTION
MiInitializeMemoryEvents(VOID)
{
UNICODE_STRING LowString = RTL_CONSTANT_STRING(L"\\KernelObjects\\LowMemoryCondition");
@@ -1177,10 +1188,11 @@ MiInitializeMemoryEvents(VOID)
VOID
NTAPI
+INIT_FUNCTION
MiAddHalIoMappings(VOID)
{
PVOID BaseAddress;
- PMMPTE PointerPde;
+ PMMPDE PointerPde;
PMMPTE PointerPte;
ULONG i, j, PdeCount;
PFN_NUMBER PageFrameIndex;
@@ -1191,12 +1203,12 @@ MiAddHalIoMappings(VOID)
/* Check how many PDEs the heap has */
PointerPde = MiAddressToPde(BaseAddress);
- PdeCount = PDE_COUNT - ADDR_TO_PDE_OFFSET(BaseAddress);
+ PdeCount = PDE_COUNT - MiGetPdeOffset(BaseAddress);
for (i = 0; i < PdeCount; i++)
{
/* Does the HAL own this mapping? */
if ((PointerPde->u.Hard.Valid == 1) &&
- (PointerPde->u.Hard.LargePage == 0))
+ (MI_IS_PAGE_LARGE(PointerPde) == FALSE))
{
/* Get the PTE for it and scan each page */
PointerPte = MiAddressToPte(BaseAddress);
@@ -1232,24 +1244,53 @@ MiAddHalIoMappings(VOID)
VOID
NTAPI
-MmDumpArmPfnDatabase(VOID)
+MmDumpArmPfnDatabase(IN BOOLEAN StatusOnly)
{
ULONG i;
PMMPFN Pfn1;
PCHAR Consumer = "Unknown";
KIRQL OldIrql;
ULONG ActivePages = 0, FreePages = 0, OtherPages = 0;
-
- KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
+#if MI_TRACE_PFNS
+ ULONG UsageBucket[MI_USAGE_FREE_PAGE + 1] = {0};
+ PCHAR MI_USAGE_TEXT[MI_USAGE_FREE_PAGE + 1] =
+ {
+ "Not set",
+ "Paged Pool",
+ "Nonpaged Pool",
+ "Nonpaged Pool Ex",
+ "Kernel Stack",
+ "Kernel Stack Ex",
+ "System PTE",
+ "VAD",
+ "PEB/TEB",
+ "Section",
+ "Page Table",
+ "Page Directory",
+ "Old Page Table",
+ "Driver Page",
+ "Contiguous Alloc",
+ "MDL",
+ "Demand Zero",
+ "Zero Loop",
+ "Cache",
+ "PFN Database",
+ "Boot Driver",
+ "Initial Memory",
+ "Free Page"
+ };
+#endif
//
// Loop the PFN database
//
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
for (i = 0; i <= MmHighestPhysicalPage; i++)
{
Pfn1 = MiGetPfnEntry(i);
if (!Pfn1) continue;
-
+#if MI_TRACE_PFNS
+ ASSERT(Pfn1->PfnUsage <= MI_USAGE_FREE_PAGE);
+#endif
//
// Get the page location
//
@@ -1260,12 +1301,18 @@ MmDumpArmPfnDatabase(VOID)
Consumer = "Active and Valid";
ActivePages++;
break;
-
+
+ case ZeroedPageList:
+
+ Consumer = "Zero Page List";
+ FreePages++;
+ break;//continue;
+
case FreePageList:
Consumer = "Free Page List";
FreePages++;
- break;
+ break;//continue;
default:
@@ -1273,23 +1320,55 @@ MmDumpArmPfnDatabase(VOID)
OtherPages++;
break;
}
-
+
+#if MI_TRACE_PFNS
+ /* Add into bucket */
+ UsageBucket[Pfn1->PfnUsage]++;
+#endif
+
//
// Pretty-print the page
//
- DbgPrint("0x%08p:\t%20s\t(%02d.%02d) [%08p-%08p])\n",
+ if (!StatusOnly)
+ DbgPrint("0x%08p:\t%20s\t(%04d.%04d)\t[%16s - %16s])\n",
i << PAGE_SHIFT,
Consumer,
Pfn1->u3.e2.ReferenceCount,
- Pfn1->u2.ShareCount,
- Pfn1->PteAddress,
- Pfn1->u4.PteFrame);
+ Pfn1->u2.ShareCount == LIST_HEAD ? 0xFFFF : Pfn1->u2.ShareCount,
+#if MI_TRACE_PFNS
+ MI_USAGE_TEXT[Pfn1->PfnUsage],
+ Pfn1->ProcessName);
+#else
+ "Page tracking",
+ "is disabled");
+#endif
}
- DbgPrint("Active: %d pages\t[%d KB]\n", ActivePages, (ActivePages << PAGE_SHIFT) / 1024);
- DbgPrint("Free: %d pages\t[%d KB]\n", FreePages, (FreePages << PAGE_SHIFT) / 1024);
- DbgPrint("Other: %d pages\t[%d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
-
+ DbgPrint("Active: %5d pages\t[%6d KB]\n", ActivePages, (ActivePages << PAGE_SHIFT) / 1024);
+ DbgPrint("Free: %5d pages\t[%6d KB]\n", FreePages, (FreePages << PAGE_SHIFT) / 1024);
+ DbgPrint("-----------------------------------------\n");
+#if MI_TRACE_PFNS
+ OtherPages = UsageBucket[MI_USAGE_BOOT_DRIVER];
+ DbgPrint("Boot Images: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+ OtherPages = UsageBucket[MI_USAGE_DRIVER_PAGE];
+ DbgPrint("System Drivers: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+ OtherPages = UsageBucket[MI_USAGE_PFN_DATABASE];
+ DbgPrint("PFN Database: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+ OtherPages = UsageBucket[MI_USAGE_PAGE_TABLE] + UsageBucket[MI_USAGE_LEGACY_PAGE_DIRECTORY];
+ DbgPrint("Page Tables: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+ OtherPages = UsageBucket[MI_USAGE_NONPAGED_POOL] + UsageBucket[MI_USAGE_NONPAGED_POOL_EXPANSION];
+ DbgPrint("NonPaged Pool: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+ OtherPages = UsageBucket[MI_USAGE_PAGED_POOL];
+ DbgPrint("Paged Pool: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+ OtherPages = UsageBucket[MI_USAGE_KERNEL_STACK] + UsageBucket[MI_USAGE_KERNEL_STACK_EXPANSION];
+ DbgPrint("Kernel Stack: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+ OtherPages = UsageBucket[MI_USAGE_INIT_MEMORY];
+ DbgPrint("Init Memory: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+ OtherPages = UsageBucket[MI_USAGE_SECTION];
+ DbgPrint("Sections: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+ OtherPages = UsageBucket[MI_USAGE_CACHE];
+ DbgPrint("Cache: %5d pages\t[%6d KB]\n", OtherPages, (OtherPages << PAGE_SHIFT) / 1024);
+#endif
KeLowerIrql(OldIrql);
}
@@ -1337,6 +1416,7 @@ MiPagesInLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
PPHYSICAL_MEMORY_DESCRIPTOR
NTAPI
+INIT_FUNCTION
MmInitializeMemoryLimits(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PBOOLEAN IncludeType)
{
@@ -1473,10 +1553,13 @@ MmInitializeMemoryLimits(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
VOID
NTAPI
+INIT_FUNCTION
MiBuildPagedPool(VOID)
{
- PMMPTE PointerPte, PointerPde;
+ PMMPTE PointerPte;
+ PMMPDE PointerPde;
MMPTE TempPte = ValidKernelPte;
+ MMPDE TempPde = ValidKernelPde;
PFN_NUMBER PageFrameIndex;
KIRQL OldIrql;
ULONG Size, BitMapSize;
@@ -1567,7 +1650,7 @@ MiBuildPagedPool(VOID)
#endif
RtlZeroMemory(PointerPde,
- (1 + MiAddressToPde(MmPagedPoolEnd) - PointerPde) * sizeof(MMPTE));
+ (1 + MiAddressToPde(MmPagedPoolEnd) - PointerPde) * sizeof(MMPDE));
//
// Next, get the first and last PTE
@@ -1582,9 +1665,11 @@ MiBuildPagedPool(VOID)
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Allocate a page and map the first paged pool PDE */
+ MI_SET_USAGE(MI_USAGE_PAGED_POOL);
+ MI_SET_PROCESS2("Kernel");
PageFrameIndex = MiRemoveZeroPage(0);
- TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
- MI_WRITE_VALID_PTE(PointerPde, TempPte);
+ TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
+ MI_WRITE_VALID_PDE(PointerPde, TempPde);
#if (_MI_PAGING_LEVELS >= 3)
/* Use the PPE of MmPagedPoolStart that was setup above */
// Bla = PFN_FROM_PTE(PpeAddress(MmPagedPool...));
@@ -1595,8 +1680,8 @@ MiBuildPagedPool(VOID)
/* Initialize the PFN entry for it */
MiInitializePfnForOtherProcess(PageFrameIndex,
- PointerPde,
- MmSystemPageDirectory[(PointerPde - (PMMPTE)PDE_BASE) / PDE_COUNT]);
+ (PMMPTE)PointerPde,
+ MmSystemPageDirectory[(PointerPde - (PMMPDE)PDE_BASE) / PDE_COUNT]);
#endif
//
@@ -1679,8 +1764,61 @@ MiBuildPagedPool(VOID)
MiInitializeSystemSpaceMap(NULL);
}
-NTSTATUS
+VOID
NTAPI
+INIT_FUNCTION
+MiDbgDumpMemoryDescriptors(VOID)
+{
+ PLIST_ENTRY NextEntry;
+ PMEMORY_ALLOCATION_DESCRIPTOR Md;
+ ULONG TotalPages = 0;
+ PCHAR
+ MemType[] =
+ {
+ "ExceptionBlock ",
+ "SystemBlock ",
+ "Free ",
+ "Bad ",
+ "LoadedProgram ",
+ "FirmwareTemporary ",
+ "FirmwarePermanent ",
+ "OsloaderHeap ",
+ "OsloaderStack ",
+ "SystemCode ",
+ "HalCode ",
+ "BootDriver ",
+ "ConsoleInDriver ",
+ "ConsoleOutDriver ",
+ "StartupDpcStack ",
+ "StartupKernelStack",
+ "StartupPanicStack ",
+ "StartupPcrPage ",
+ "StartupPdrPage ",
+ "RegistryData ",
+ "MemoryData ",
+ "NlsData ",
+ "SpecialMemory ",
+ "BBTMemory ",
+ "LoaderReserve ",
+ "LoaderXIPRom "
+ };
+
+ DPRINT1("Base\t\tLength\t\tType\n");
+ for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
+ NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
+ NextEntry = NextEntry->Flink)
+ {
+ Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
+ DPRINT1("%08lX\t%08lX\t%s\n", Md->BasePage, Md->PageCount, MemType[Md->MemoryType]);
+ TotalPages += Md->PageCount;
+ }
+
+ DPRINT1("Total: %08lX (%d MB)\n", TotalPages, (TotalPages * PAGE_SIZE) / 1024 / 1024);
+}
+
+BOOLEAN
+NTAPI
+INIT_FUNCTION
MmArmInitSystem(IN ULONG Phase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
@@ -1690,6 +1828,9 @@ MmArmInitSystem(IN ULONG Phase,
PPHYSICAL_MEMORY_RUN Run;
PFN_NUMBER PageCount;
+ /* Dump memory descriptors */
+ if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors();
+
//
// Instantiate memory that we don't consider RAM/usable
// We use the same exclusions that Windows does, in order to try to be
@@ -1892,14 +2033,7 @@ MmArmInitSystem(IN ULONG Phase,
/* Initialize the platform-specific parts */
MiInitMachineDependent(LoaderBlock);
-
- //
- // Sync us up with ReactOS Mm
- //
- MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1));
- MiSyncARM3WithROS(MmPfnDatabase, (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1));
- MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1));
-
+
//
// Build the physical memory block
//
@@ -2097,7 +2231,7 @@ MmArmInitSystem(IN ULONG Phase,
//
// Always return success for now
//
- return STATUS_SUCCESS;
+ return TRUE;
}
/* EOF */
diff --git a/ntoskrnl/mm/ARM3/pagfault.c b/ntoskrnl/mm/ARM3/pagfault.c
index 953a539d045..20264a1faf0 100644
--- a/ntoskrnl/mm/ARM3/pagfault.c
+++ b/ntoskrnl/mm/ARM3/pagfault.c
@@ -18,6 +18,10 @@
/* GLOBALS ********************************************************************/
+#if MI_TRACE_PFNS
+BOOLEAN UserPdeFault = FALSE;
+#endif
+
/* PRIVATE FUNCTIONS **********************************************************/
PMMPTE
@@ -256,6 +260,12 @@ MiResolveDemandZeroFault(IN PVOID Address,
/* Do we need a zero page? */
ASSERT(PointerPte->u.Hard.Valid == 0);
+#if MI_TRACE_PFNS
+ if (UserPdeFault) MI_SET_USAGE(MI_USAGE_PAGE_TABLE);
+ if (!UserPdeFault) MI_SET_USAGE(MI_USAGE_DEMAND_ZERO);
+#endif
+ if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+ if (!Process) MI_SET_PROCESS2("Kernel Demand 0");
if ((NeedZero) && (Process))
{
/* Try to get one, if we couldn't grab a free page and zero it */
@@ -315,7 +325,7 @@ MiResolveDemandZeroFault(IN PVOID Address,
}
/* Set it dirty if it's a writable page */
- if (TempPte.u.Hard.Write) TempPte.u.Hard.Dirty = TRUE;
+ if (MI_IS_PAGE_WRITEABLE(&TempPte)) MI_MAKE_DIRTY_PAGE(&TempPte);
/* Write it */
MI_WRITE_VALID_PTE(PointerPte, TempPte);
@@ -594,13 +604,13 @@ MiDispatchFault(IN BOOLEAN StoreInstruction,
PointerPte,
Process,
MM_NOIRQL);
- ASSERT(KeAreAllApcsDisabled () == TRUE);
+ ASSERT(KeAreAllApcsDisabled() == TRUE);
if (NT_SUCCESS(Status))
{
//
// Make sure we're returning in a sane state and pass the status down
//
- ASSERT(OldIrql == KeGetCurrentIrql ());
+ ASSERT(OldIrql == KeGetCurrentIrql());
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
return Status;
}
@@ -805,21 +815,23 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
/* Get the prototype PTE! */
ProtoPte = MiProtoPteToPte(&TempPte);
}
+ else
+ {
+ //
+ // We don't implement transition PTEs
+ //
+ ASSERT(TempPte.u.Soft.Transition == 0);
- //
- // We don't implement transition PTEs
- //
- ASSERT(TempPte.u.Soft.Transition == 0);
-
- /* Check for no-access PTE */
- if (TempPte.u.Soft.Protection == MM_NOACCESS)
- {
- /* Bad boy, bad boy, whatcha gonna do, whatcha gonna do when ARM3 comes for you! */
- KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
- (ULONG_PTR)Address,
- StoreInstruction,
- (ULONG_PTR)TrapInformation,
- 1);
+ /* Check for no-access PTE */
+ if (TempPte.u.Soft.Protection == MM_NOACCESS)
+ {
+ /* Bad boy, bad boy, whatcha gonna do, whatcha gonna do when ARM3 comes for you! */
+ KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
+ (ULONG_PTR)Address,
+ StoreInstruction,
+ (ULONG_PTR)TrapInformation,
+ 1);
+ }
}
/* Check for demand page */
@@ -874,8 +886,6 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
#endif
/* First things first, is the PDE valid? */
-// DPRINT1("The PDE we faulted on: %lx %lx\n", PointerPde, MiAddressToPde(PTE_BASE));
- //ASSERT(PointerPde != MiAddressToPde(PTE_BASE));
ASSERT(PointerPde->u.Hard.LargePage == 0);
if (PointerPde->u.Hard.Valid == 0)
{
@@ -889,18 +899,23 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
ASSERT(ProtectionCode != MM_NOACCESS);
/* Make the PDE demand-zero */
- MI_WRITE_INVALID_PTE(PointerPde, DemandZeroPde);
+ MI_WRITE_INVALID_PDE(PointerPde, DemandZeroPde);
/* And go dispatch the fault on the PDE. This should handle the demand-zero */
+#if MI_TRACE_PFNS
+ UserPdeFault = TRUE;
+#endif
Status = MiDispatchFault(TRUE,
PointerPte,
- PointerPde,
+ (PMMPTE)PointerPde,
NULL,
FALSE,
PsGetCurrentProcess(),
TrapInformation,
NULL);
-
+#if MI_TRACE_PFNS
+ UserPdeFault = FALSE;
+#endif
/* We should come back with APCs enabled, and with a valid PDE */
ASSERT(KeAreAllApcsDisabled() == TRUE);
#if (_MI_PAGING_LEVELS >= 3)
@@ -918,7 +933,6 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
if (TempPte.u.Long == (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS))
{
/* Resolve the fault */
- //DPRINT1("VAD demand-zero fault: %p\n", Address);
MiResolveDemandZeroFault(Address,
PointerPte,
CurrentProcess,
@@ -977,6 +991,14 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);
return Status;
}
+
+ /* Is this a user address? */
+ if (Address <= MM_HIGHEST_USER_ADDRESS)
+ {
+ /* Add an additional page table reference */
+ MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
+ ASSERT(MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] <= PTE_COUNT);
+ }
/* Did we get a prototype PTE back? */
if (!ProtoPte)
@@ -988,6 +1010,8 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Try to get a zero page */
+ MI_SET_USAGE(MI_USAGE_PEB_TEB);
+ MI_SET_PROCESS2(CurrentProcess->ImageFileName);
Color = MI_GET_NEXT_PROCESS_COLOR(CurrentProcess);
PageFrameIndex = MiRemoveZeroPageSafe(Color);
if (!PageFrameIndex)
@@ -1034,7 +1058,7 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
}
/* Write the dirty bit for writeable pages */
- if (TempPte.u.Hard.Write) TempPte.u.Hard.Dirty = TRUE;
+ if (MI_IS_PAGE_WRITEABLE(&TempPte)) MI_MAKE_DIRTY_PAGE(&TempPte);
/* And now write down the PTE, making the address valid */
MI_WRITE_VALID_PTE(PointerPte, TempPte);
diff --git a/ntoskrnl/mm/ARM3/pfnlist.c b/ntoskrnl/mm/ARM3/pfnlist.c
index ae2813b4d8a..575c179a33d 100644
--- a/ntoskrnl/mm/ARM3/pfnlist.c
+++ b/ntoskrnl/mm/ARM3/pfnlist.c
@@ -55,6 +55,10 @@ PMMPFNLIST MmPageLocationList[] =
NULL,
NULL
};
+
+ULONG MI_PFN_CURRENT_USAGE;
+CHAR MI_PFN_CURRENT_PROCESS_NAME[16] = "None yet";
+
/* FUNCTIONS ******************************************************************/
VOID
@@ -109,7 +113,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
if (OldFlink != LIST_HEAD)
{
/* It is not, so set the backlink of the actual entry, to our backlink */
- MiGetPfnEntry(OldFlink)->u2.Blink = OldBlink;
+ MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
}
else
{
@@ -121,7 +125,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
if (OldBlink != LIST_HEAD)
{
/* It is not, so set the backlink of the actual entry, to our backlink */
- MiGetPfnEntry(OldBlink)->u1.Flink = OldFlink;
+ MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
}
else
{
@@ -145,7 +149,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
if (ColorTable->Flink != LIST_HEAD)
{
/* And make the previous link point to the head now */
- MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
+ MI_PFN_ELEMENT(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
}
else
{
@@ -159,14 +163,14 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
ASSERT(Entry->u4.PteFrame != COLORED_LIST_HEAD);
/* Make the back link point to whoever the next page is */
- Pfn1 = MiGetPfnEntry(Entry->u4.PteFrame);
+ Pfn1 = MI_PFN_ELEMENT(Entry->u4.PteFrame);
Pfn1->OriginalPte.u.Long = Entry->OriginalPte.u.Long;
/* Check if this page was pointing to the head */
if (Entry->OriginalPte.u.Long != LIST_HEAD)
{
/* Make the back link point to the head */
- Pfn1 = MiGetPfnEntry(Entry->OriginalPte.u.Long);
+ Pfn1 = MI_PFN_ELEMENT(Entry->OriginalPte.u.Long);
Pfn1->u4.PteFrame = Entry->u4.PteFrame;
}
else
@@ -204,6 +208,14 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
{
/* FIXME: Should wake up the MPW and working set manager, if we had one */
}
+
+#if MI_TRACE_PFNS
+ ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET);
+ Entry->PfnUsage = MI_PFN_CURRENT_USAGE;
+ memcpy(Entry->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16);
+// MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
+// memcpy(MI_PFN_CURRENT_PROCESS_NAME, "Not Set", 16);
+#endif
}
PFN_NUMBER
@@ -223,7 +235,7 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
ASSERT(Color < MmSecondaryColors);
/* Get the PFN entry */
- Pfn1 = MiGetPfnEntry(PageIndex);
+ Pfn1 = MI_PFN_ELEMENT(PageIndex);
ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
ASSERT(Pfn1->u3.e1.Rom == 0);
@@ -248,19 +260,19 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
if (OldFlink != LIST_HEAD)
{
/* It is not, so set the backlink of the actual entry, to our backlink */
- MiGetPfnEntry(OldFlink)->u2.Blink = OldBlink;
+ MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
}
else
{
/* Set the list head's backlink instead */
- ListHead->Blink = OldFlink;
+ ListHead->Blink = OldBlink;
}
/* Check if the back entry is the list head */
if (OldBlink != LIST_HEAD)
{
/* It is not, so set the backlink of the actual entry, to our backlink */
- MiGetPfnEntry(OldBlink)->u1.Flink = OldFlink;
+ MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
}
else
{
@@ -294,7 +306,7 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
else
{
/* The list is empty, so we are the first page */
- MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
+ MI_PFN_ELEMENT(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
}
/* One less page */
@@ -321,6 +333,14 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
/* FIXME: Should wake up the MPW and working set manager, if we had one */
}
+#if MI_TRACE_PFNS
+ //ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET);
+ Pfn1->PfnUsage = MI_PFN_CURRENT_USAGE;
+ memcpy(Pfn1->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16);
+ //MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
+ //memcpy(MI_PFN_CURRENT_PROCESS_NAME, "Not Set", 16);
+#endif
+
/* Return the page */
return PageIndex;
}
@@ -336,18 +356,15 @@ MiRemoveAnyPage(IN ULONG Color)
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(MmAvailablePages != 0);
ASSERT(Color < MmSecondaryColors);
-#if 0
+
/* Check the colored free list */
PageIndex = MmFreePagesByColor[FreePageList][Color].Flink;
- DPRINT1("Found free page: %lx\n", PageIndex);
if (PageIndex == LIST_HEAD)
{
/* Check the colored zero list */
PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink;
- DPRINT1("Found zero page: %lx\n", PageIndex);
if (PageIndex == LIST_HEAD)
{
-#endif
/* Check the free list */
ASSERT_LIST_INVARIANT(&MmFreePageListHead);
PageIndex = MmFreePageListHead.Flink;
@@ -365,15 +382,14 @@ MiRemoveAnyPage(IN ULONG Color)
ASSERT(MmZeroedPageListHead.Total == 0);
}
}
-#if 0
}
}
-#endif
+
/* Remove the page from its list */
PageIndex = MiRemovePageByColor(PageIndex, Color);
/* Sanity checks */
- Pfn1 = MiGetPfnEntry(PageIndex);
+ Pfn1 = MI_PFN_ELEMENT(PageIndex);
ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
(Pfn1->u3.e1.PageLocation == ZeroedPageList));
ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
@@ -391,7 +407,7 @@ MiRemoveZeroPage(IN ULONG Color)
{
PFN_NUMBER PageIndex;
PMMPFN Pfn1;
- BOOLEAN Zero;
+ BOOLEAN Zero = FALSE;
/* Make sure PFN lock is held and we have pages */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
@@ -399,26 +415,22 @@ MiRemoveZeroPage(IN ULONG Color)
ASSERT(Color < MmSecondaryColors);
/* Check the colored zero list */
-#if 0
PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink;
if (PageIndex == LIST_HEAD)
{
-#endif
/* Check the zero list */
ASSERT_LIST_INVARIANT(&MmZeroedPageListHead);
PageIndex = MmZeroedPageListHead.Flink;
- Color = PageIndex & MmSecondaryColorMask;
if (PageIndex == LIST_HEAD)
{
/* This means there's no zero pages, we have to look for free ones */
ASSERT(MmZeroedPageListHead.Total == 0);
Zero = TRUE;
-#if 0
+
/* Check the colored free list */
PageIndex = MmFreePagesByColor[FreePageList][Color].Flink;
if (PageIndex == LIST_HEAD)
{
-#endif
/* Check the free list */
ASSERT_LIST_INVARIANT(&MmFreePageListHead);
PageIndex = MmFreePageListHead.Flink;
@@ -429,22 +441,22 @@ MiRemoveZeroPage(IN ULONG Color)
/* FIXME: Should check the standby list */
ASSERT(MmZeroedPageListHead.Total == 0);
}
-#if 0
}
-#endif
}
-#if 0
+ else
+ {
+ Color = PageIndex & MmSecondaryColorMask;
+ }
}
-#endif
/* Sanity checks */
- Pfn1 = MiGetPfnEntry(PageIndex);
+ Pfn1 = MI_PFN_ELEMENT(PageIndex);
ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
(Pfn1->u3.e1.PageLocation == ZeroedPageList));
/* Remove the page from its list */
PageIndex = MiRemovePageByColor(PageIndex, Color);
- ASSERT(Pfn1 == MiGetPfnEntry(PageIndex));
+ ASSERT(Pfn1 == MI_PFN_ELEMENT(PageIndex));
/* Zero it, if needed */
if (Zero) MiZeroPhysicalPage(PageIndex);
@@ -477,7 +489,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
(PageFrameIndex >= MmLowestPhysicalPage));
/* Get the PFN entry */
- Pfn1 = MiGetPfnEntry(PageFrameIndex);
+ Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
/* Sanity checks that a right kind of page is being inserted here */
ASSERT(Pfn1->u4.MustBeCached == 0);
@@ -496,7 +508,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
if (LastPage != LIST_HEAD)
{
/* Link us with the previous page, so we're at the end now */
- MiGetPfnEntry(LastPage)->u1.Flink = PageFrameIndex;
+ MI_PFN_ELEMENT(LastPage)->u1.Flink = PageFrameIndex;
}
else
{
@@ -551,19 +563,15 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
/* Get the previous page */
Blink = (PMMPFN)ColorTable->Blink;
- /* Make it link to us */
- Pfn1->u4.PteFrame = MiGetPfnEntryIndex(Blink);
-
- /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
- ASSERT(Blink->u3.e1.ParityError == FALSE);
+ /* Make it link to us, and link back to it */
Blink->OriginalPte.u.Long = PageFrameIndex;
+ Pfn1->u4.PteFrame = MiGetPfnEntryIndex(Blink);
}
/* Now initialize our own list pointers */
ColorTable->Blink = Pfn1;
- /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
- ASSERT(Pfn1->u3.e1.ParityError == FALSE);
+ /* This page is now the last */
Pfn1->OriginalPte.u.Long = LIST_HEAD;
/* And increase the count in the colored list */
@@ -576,6 +584,11 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
MmZeroingPageThreadActive = TRUE;
KeSetEvent(&MmZeroingPageEvent, IO_NO_INCREMENT, FALSE);
}
+
+#if MI_TRACE_PFNS
+ Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
+ RtlZeroMemory(Pfn1->ProcessName, 16);
+#endif
}
/* Note: This function is hardcoded only for the zeroed page list, for now */
@@ -602,7 +615,7 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
(PageFrameIndex >= MmLowestPhysicalPage));
/* Page should be unused */
- Pfn1 = MiGetPfnEntry(PageFrameIndex);
+ Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
ASSERT(Pfn1->u3.e1.Rom != 1);
@@ -626,7 +639,7 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
if (Flink != LIST_HEAD)
{
/* It wasn't, so update the backlink of the previous head page */
- Pfn2 = MiGetPfnEntry(Flink);
+ Pfn2 = MI_PFN_ELEMENT(Flink);
Pfn2->u2.Blink = PageFrameIndex;
}
else
@@ -666,9 +679,6 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
/* Get the old head */
Flink = ColorHead->Flink;
- /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
- ASSERT(Pfn1->u3.e1.ParityError == FALSE);
-
/* Make this page point back to the list, and point forwards to the old head */
Pfn1->OriginalPte.u.Long = Flink;
Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
@@ -680,7 +690,7 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
if (Flink != LIST_HEAD)
{
/* No, so make the old head point to this page */
- Pfn2 = MiGetPfnEntry(Flink);
+ Pfn2 = MI_PFN_ELEMENT(Flink);
Pfn2->u4.PteFrame = PageFrameIndex;
}
else
@@ -691,6 +701,13 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
/* One more paged on the colored list */
ColorHead->Count++;
+
+#if MI_TRACE_PFNS
+ //ASSERT(MI_PFN_CURRENT_USAGE == MI_USAGE_NOT_SET);
+ Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
+ MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
+ RtlZeroMemory(Pfn1->ProcessName, 16);
+#endif
}
VOID
@@ -705,7 +722,7 @@ MiInitializePfn(IN PFN_NUMBER PageFrameIndex,
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
/* Setup the PTE */
- Pfn1 = MiGetPfnEntry(PageFrameIndex);
+ Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
Pfn1->PteAddress = PointerPte;
/* Check if this PFN is part of a valid address space */
@@ -756,7 +773,7 @@ MiInitializePfn(IN PFN_NUMBER PageFrameIndex,
Pfn1->u4.PteFrame = PageFrameIndex;
/* Increase its share count so we don't get rid of it */
- Pfn1 = MiGetPfnEntry(PageFrameIndex);
+ Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
Pfn1->u2.ShareCount++;
}
@@ -810,8 +827,9 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
IN PFN_NUMBER PageFrameIndex)
{
ASSERT(PageFrameIndex > 0);
- ASSERT(MiGetPfnEntry(PageFrameIndex) != NULL);
- ASSERT(Pfn1 == MiGetPfnEntry(PageFrameIndex));
+ ASSERT(MI_PFN_ELEMENT(PageFrameIndex) != NULL);
+ ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
+ ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE);
/* Page must be in-use */
if ((Pfn1->u3.e1.PageLocation != ActiveAndValid) &&
@@ -847,13 +865,7 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
/* Clear the last reference */
Pfn1->u3.e2.ReferenceCount = 0;
-
- /*
- * OriginalPte is used by AweReferenceCount in ReactOS, but either
- * ways we shouldn't be seeing RMAP entries at this point
- */
ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
- ASSERT(Pfn1->u3.e1.ParityError == FALSE);
/* Mark the page temporarily as valid, we're going to make it free soon */
Pfn1->u3.e1.PageLocation = ActiveAndValid;
@@ -869,6 +881,49 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
}
}
+VOID
+NTAPI
+MiDecrementReferenceCount(IN PMMPFN Pfn1,
+ IN PFN_NUMBER PageFrameIndex)
+{
+ /* PFN lock must be held */
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /* Sanity checks on the page */
+ ASSERT(PageFrameIndex < MmHighestPhysicalPage);
+ ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
+ ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
+
+ /* Dereference the page, bail out if it's still alive */
+ InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
+ if (Pfn1->u3.e2.ReferenceCount) return;
+
+ /* Nobody should still have reference to this page */
+ if (Pfn1->u2.ShareCount != 0)
+ {
+ /* Otherwise something's really wrong */
+ KeBugCheckEx(PFN_LIST_CORRUPT, 7, PageFrameIndex, Pfn1->u2.ShareCount, 0);
+ }
+
+ /* And it should be lying on some page list */
+ ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
+
+ /* Did someone set the delete flag? */
+ if (MI_IS_PFN_DELETED(Pfn1))
+ {
+ /* Insert it into the free list, there's nothing left to do */
+ MiInsertPageInFreeList(PageFrameIndex);
+ return;
+ }
+
+ /* We don't have a modified list yet */
+ ASSERT(Pfn1->u3.e1.Modified == 0);
+ ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
+
+ /* FIXME: Normally it would go on the standby list, but we're pushing it on the free list */
+ MiInsertPageInFreeList(PageFrameIndex);
+}
+
VOID
NTAPI
MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex,
@@ -878,7 +933,7 @@ MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex,
PMMPFN Pfn1;
/* Setup the PTE */
- Pfn1 = MiGetPfnEntry(PageFrameIndex);
+ Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
Pfn1->PteAddress = PointerPte;
/* Make this a software PTE */
@@ -899,7 +954,7 @@ MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex,
Pfn1->u4.PteFrame = PteFrame;
/* Increase its share count so we don't get rid of it */
- Pfn1 = MiGetPfnEntry(PteFrame);
+ Pfn1 = MI_PFN_ELEMENT(PteFrame);
Pfn1->u2.ShareCount++;
}
}
diff --git a/ntoskrnl/mm/ARM3/pool.c b/ntoskrnl/mm/ARM3/pool.c
index 8156f6748f7..1efdbc513a1 100644
--- a/ntoskrnl/mm/ARM3/pool.c
+++ b/ntoskrnl/mm/ARM3/pool.c
@@ -177,6 +177,7 @@ MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry)
VOID
NTAPI
+INIT_FUNCTION
MiInitializeNonPagedPoolThresholds(VOID)
{
PFN_NUMBER Size = MmMaximumNonPagedPoolInPages;
@@ -193,6 +194,7 @@ MiInitializeNonPagedPoolThresholds(VOID)
VOID
NTAPI
+INIT_FUNCTION
MiInitializePoolEvents(VOID)
{
KIRQL OldIrql;
@@ -267,6 +269,7 @@ MiInitializePoolEvents(VOID)
VOID
NTAPI
+INIT_FUNCTION
MiInitializeNonPagedPool(VOID)
{
ULONG i;
@@ -372,7 +375,7 @@ NTAPI
MiAllocatePoolPages(IN POOL_TYPE PoolType,
IN SIZE_T SizeInBytes)
{
- PFN_NUMBER SizeInPages, PageFrameNumber;
+ PFN_NUMBER SizeInPages, PageFrameNumber, PageTableCount;
ULONG i;
KIRQL OldIrql;
PLIST_ENTRY NextEntry, NextHead, LastHead;
@@ -419,7 +422,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
// Check if there is enougn paged pool expansion space left
//
if (MmPagedPoolInfo.NextPdeForPagedPoolExpansion >
- MiAddressToPte(MmPagedPoolInfo.LastPteForPagedPool))
+ (PMMPDE)MiAddressToPte(MmPagedPoolInfo.LastPteForPagedPool))
{
//
// Out of memory!
@@ -433,23 +436,23 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
// Check if we'll have to expand past the last PTE we have available
//
if (((i - 1) + MmPagedPoolInfo.NextPdeForPagedPoolExpansion) >
- MiAddressToPte(MmPagedPoolInfo.LastPteForPagedPool))
+ (PMMPDE)MiAddressToPte(MmPagedPoolInfo.LastPteForPagedPool))
{
//
// We can only support this much then
//
- SizeInPages = MiAddressToPte(MmPagedPoolInfo.LastPteForPagedPool) -
- MmPagedPoolInfo.NextPdeForPagedPoolExpansion +
- 1;
- ASSERT(SizeInPages < i);
- i = SizeInPages;
+ PageTableCount = (PMMPDE)MiAddressToPte(MmPagedPoolInfo.LastPteForPagedPool) -
+ MmPagedPoolInfo.NextPdeForPagedPoolExpansion +
+ 1;
+ ASSERT(PageTableCount < i);
+ i = PageTableCount;
}
else
{
//
// Otherwise, there is plenty of space left for this expansion
//
- SizeInPages = i;
+ PageTableCount = i;
}
//
@@ -461,7 +464,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
// Get the first PTE in expansion space
//
PointerPde = MmPagedPoolInfo.NextPdeForPagedPoolExpansion;
- BaseVa = MiPteToAddress(PointerPde);
+ BaseVa = MiPdeToAddress(PointerPde);
BaseVaStart = BaseVa;
//
@@ -476,11 +479,10 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
ASSERT(PointerPde->u.Hard.Valid == 0);
/* Request a page */
- DPRINT1("Requesting %d PDEs\n", i);
+ MI_SET_USAGE(MI_USAGE_PAGED_POOL);
+ MI_SET_PROCESS2("Kernel");
PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
- DPRINT1("We have a PDE: %lx\n", PageFrameNumber);
-
#if (_MI_PAGING_LEVELS >= 3)
/* On PAE/x64 systems, there's no double-buffering */
ASSERT(FALSE);
@@ -492,11 +494,11 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
/* Initialize the PFN */
MiInitializePfnForOtherProcess(PageFrameNumber,
- PointerPde,
+ (PMMPTE)PointerPde,
MmSystemPageDirectory[(PointerPde - MiAddressToPde(NULL)) / PDE_COUNT]);
/* Write the actual PDE now */
- MI_WRITE_VALID_PTE(PointerPde, TempPde);
+ MI_WRITE_VALID_PDE(PointerPde, TempPde);
#endif
//
// Move on to the next expansion address
@@ -515,26 +517,25 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
// These pages are now available, clear their availablity bits
//
EndAllocation = (MmPagedPoolInfo.NextPdeForPagedPoolExpansion -
- MiAddressToPte(MmPagedPoolInfo.FirstPteForPagedPool)) *
+ (PMMPDE)MiAddressToPte(MmPagedPoolInfo.FirstPteForPagedPool)) *
PTE_COUNT;
RtlClearBits(MmPagedPoolInfo.PagedPoolAllocationMap,
EndAllocation,
- SizeInPages * PTE_COUNT);
+ PageTableCount * PTE_COUNT);
//
// Update the next expansion location
//
- MmPagedPoolInfo.NextPdeForPagedPoolExpansion += SizeInPages;
+ MmPagedPoolInfo.NextPdeForPagedPoolExpansion += PageTableCount;
//
// Zero out the newly available memory
//
- RtlZeroMemory(BaseVaStart, SizeInPages * PAGE_SIZE);
+ RtlZeroMemory(BaseVaStart, PageTableCount * PAGE_SIZE);
//
// Now try consuming the pages again
//
- SizeInPages = BYTES_TO_PAGES(SizeInBytes);
i = RtlFindClearBitsAndSet(MmPagedPoolInfo.PagedPoolAllocationMap,
SizeInPages,
0);
@@ -773,6 +774,8 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
do
{
/* Allocate a page */
+ MI_SET_USAGE(MI_USAGE_PAGED_POOL);
+ MI_SET_PROCESS2("Kernel");
PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
/* Get the PFN entry for it and fill it out */
diff --git a/ntoskrnl/mm/ARM3/procsup.c b/ntoskrnl/mm/ARM3/procsup.c
index c63058341db..afedcc21859 100644
--- a/ntoskrnl/mm/ARM3/procsup.c
+++ b/ntoskrnl/mm/ARM3/procsup.c
@@ -19,6 +19,7 @@
/* GLOBALS ********************************************************************/
ULONG MmProcessColorSeed = 0x12345678;
+PMMWSL MmWorkingSetList;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -190,6 +191,7 @@ MmDeleteTeb(IN PEPROCESS Process,
ASSERT((Vad->StartingVpn == ((ULONG_PTR)Teb >> PAGE_SHIFT) &&
(Vad->EndingVpn == (TebEnd >> PAGE_SHIFT))));
ASSERT(Vad->u.VadFlags.NoChange == TRUE);
+ ASSERT(Vad->u2.VadFlags2.OneSecured == TRUE);
ASSERT(Vad->u2.VadFlags2.MultipleSecured == FALSE);
/* Lock the working set */
@@ -362,6 +364,8 @@ MmCreateKernelStack(IN BOOLEAN GuiStack,
PointerPte++;
/* Get a page and write the current invalid PTE */
+ MI_SET_USAGE(MI_USAGE_KERNEL_STACK);
+ MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
MI_WRITE_INVALID_PTE(PointerPte, InvalidPte);
@@ -373,9 +377,6 @@ MmCreateKernelStack(IN BOOLEAN GuiStack,
MI_WRITE_VALID_PTE(PointerPte, TempPte);
}
- // Bug #4835
- (VOID)InterlockedExchangeAddUL(&MiMemoryConsumers[MC_NPPOOL].PagesUsed, StackPages);
-
//
// Release the PFN lock
//
@@ -449,6 +450,8 @@ MmGrowKernelStackEx(IN PVOID StackPointer,
while (LimitPte >= NewLimitPte)
{
/* Get a page and write the current invalid PTE */
+ MI_SET_USAGE(MI_USAGE_KERNEL_STACK_EXPANSION);
+ MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
MI_WRITE_INVALID_PTE(LimitPte, InvalidPte);
@@ -890,6 +893,32 @@ MmCreateTeb(IN PEPROCESS Process,
return Status;
}
+VOID
+NTAPI
+MiInitializeWorkingSetList(IN PEPROCESS CurrentProcess)
+{
+ PMMPFN Pfn1;
+
+ /* Setup some bogus list data */
+ MmWorkingSetList->LastEntry = CurrentProcess->Vm.MinimumWorkingSetSize;
+ MmWorkingSetList->HashTable = NULL;
+ MmWorkingSetList->HashTableSize = 0;
+ MmWorkingSetList->NumberOfImageWaiters = 0;
+ MmWorkingSetList->Wsle = (PVOID)0xDEADBABE;
+ MmWorkingSetList->VadBitMapHint = 1;
+ MmWorkingSetList->HashTableStart = (PVOID)0xBADAB00B;
+ MmWorkingSetList->HighestPermittedHashAddress = (PVOID)0xCAFEBABE;
+ MmWorkingSetList->FirstFree = 1;
+ MmWorkingSetList->FirstDynamic = 2;
+ MmWorkingSetList->NextSlot = 3;
+ MmWorkingSetList->LastInitializedWsle = 4;
+
+ /* The rule is that the owner process is always in the FLINK of the PDE's PFN entry */
+ Pfn1 = MiGetPfnEntry(MiAddressToPte(PDE_BASE)->u.Hard.PageFrameNumber);
+ ASSERT(Pfn1->u4.PteFrame == MiGetPfnEntryIndex(Pfn1));
+ Pfn1->u1.Event = (PKEVENT)CurrentProcess;
+}
+
NTSTATUS
NTAPI
MmInitializeProcessAddressSpace(IN PEPROCESS Process,
@@ -910,6 +939,7 @@ MmInitializeProcessAddressSpace(IN PEPROCESS Process,
PWCHAR Source;
PCHAR Destination;
USHORT Length = 0;
+ MMPTE TempPte;
/* We should have a PDE */
ASSERT(Process->Pcb.DirectoryTableBase[0] != 0);
@@ -941,7 +971,23 @@ MmInitializeProcessAddressSpace(IN PEPROCESS Process,
/* Do the same for hyperspace */
PointerPde = MiAddressToPde(HYPER_SPACE);
PageFrameNumber = PFN_FROM_PTE(PointerPde);
- MiInitializePfn(PageFrameNumber, PointerPde, TRUE);
+ MiInitializePfn(PageFrameNumber, (PMMPTE)PointerPde, TRUE);
+
+ /* Setup the PFN for the PTE for the working set */
+ PointerPte = MiAddressToPte(MI_WORKING_SET_LIST);
+ MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, MM_READWRITE, 0);
+ ASSERT(PointerPte->u.Long != 0);
+ PageFrameNumber = PFN_FROM_PTE(PointerPte);
+ MI_WRITE_INVALID_PTE(PointerPte, DemandZeroPte);
+ MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
+ TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
+ MI_WRITE_VALID_PTE(PointerPte, TempPte);
+
+ /* Now initialize the working set list */
+ MiInitializeWorkingSetList(Process);
+
+ /* Sanity check */
+ ASSERT(Process->PhysicalVadRoot == NULL);
/* Release PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
@@ -1021,6 +1067,7 @@ MmInitializeProcessAddressSpace(IN PEPROCESS Process,
NTSTATUS
NTAPI
+INIT_FUNCTION
MmInitializeHandBuiltProcess(IN PEPROCESS Process,
IN PULONG_PTR DirectoryTableBase)
{
@@ -1042,6 +1089,7 @@ MmInitializeHandBuiltProcess(IN PEPROCESS Process,
NTSTATUS
NTAPI
+INIT_FUNCTION
MmInitializeHandBuiltProcess2(IN PEPROCESS Process)
{
/* Lock the VAD, ARM3-owned ranges away */
@@ -1058,12 +1106,13 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
OUT PULONG_PTR DirectoryTableBase)
{
KIRQL OldIrql;
- PFN_NUMBER PdeIndex, HyperIndex;
+ PFN_NUMBER PdeIndex, HyperIndex, WsListIndex;
PMMPTE PointerPte;
MMPTE TempPte, PdePte;
ULONG PdeOffset;
- PMMPTE SystemTable;
+ PMMPTE SystemTable, HyperTable;
ULONG Color;
+ PMMPFN Pfn1;
/* Choose a process color */
Process->NextPageColor = RtlRandom(&MmProcessColorSeed);
@@ -1076,6 +1125,7 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
/* Get a zero page for the PDE, if possible */
Color = MI_GET_NEXT_PROCESS_COLOR(Process);
+ MI_SET_USAGE(MI_USAGE_PAGE_DIRECTORY);
PdeIndex = MiRemoveZeroPageSafe(Color);
if (!PdeIndex)
{
@@ -1089,6 +1139,7 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
}
/* Get a zero page for hyperspace, if possible */
+ MI_SET_USAGE(MI_USAGE_PAGE_DIRECTORY);
Color = MI_GET_NEXT_PROCESS_COLOR(Process);
HyperIndex = MiRemoveZeroPageSafe(Color);
if (!HyperIndex)
@@ -1099,6 +1150,21 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
/* Zero it outside the PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
MiZeroPhysicalPage(HyperIndex);
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ }
+
+ /* Get a zero page for the woring set list, if possible */
+ MI_SET_USAGE(MI_USAGE_PAGE_TABLE);
+ Color = MI_GET_NEXT_PROCESS_COLOR(Process);
+ WsListIndex = MiRemoveZeroPageSafe(Color);
+ if (!WsListIndex)
+ {
+ /* No zero pages, grab a free one */
+ WsListIndex = MiRemoveAnyPage(Color);
+
+ /* Zero it outside the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(WsListIndex);
}
else
{
@@ -1111,11 +1177,42 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
Process->AddressSpaceInitialized = 1;
/* Set the base directory pointers */
+ Process->WorkingSetPage = WsListIndex;
DirectoryTableBase[0] = PdeIndex << PAGE_SHIFT;
DirectoryTableBase[1] = HyperIndex << PAGE_SHIFT;
/* Make sure we don't already have a page directory setup */
ASSERT(Process->Pcb.DirectoryTableBase[0] == 0);
+
+ /* Get a PTE to map hyperspace */
+ PointerPte = MiReserveSystemPtes(1, SystemPteSpace);
+ ASSERT(PointerPte != NULL);
+
+ /* Build it */
+ MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte,
+ PointerPte,
+ MM_READWRITE,
+ HyperIndex);
+
+ /* Set it dirty and map it */
+ MI_MAKE_DIRTY_PAGE(&PdePte);
+ MI_WRITE_VALID_PTE(PointerPte, PdePte);
+
+ /* Now get hyperspace's page table */
+ HyperTable = MiPteToAddress(PointerPte);
+
+ /* Now write the PTE/PDE entry for the working set list index itself */
+ TempPte = ValidKernelPte;
+ TempPte.u.Hard.PageFrameNumber = WsListIndex;
+ PdeOffset = MiAddressToPteOffset(MmWorkingSetList);
+ HyperTable[PdeOffset] = TempPte;
+
+ /* Let go of the system PTE */
+ MiReleaseSystemPtes(PointerPte, 1, SystemPteSpace);
+
+ /* Save the PTE address of the page directory itself */
+ Pfn1 = MiGetPfnEntry(PdeIndex);
+ Pfn1->PteAddress = (PMMPTE)PDE_BASE;
/* Insert us into the Mm process list */
InsertTailList(&MmProcessList, &Process->MmProcessLinks);
@@ -1131,7 +1228,7 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
PdeIndex);
/* Set it dirty and map it */
- PdePte.u.Hard.Dirty = TRUE;
+ MI_MAKE_DIRTY_PAGE(&PdePte);
MI_WRITE_VALID_PTE(PointerPte, PdePte);
/* Now get the page directory (which we'll double map, so call it a page table */
@@ -1172,9 +1269,15 @@ MmCleanProcessAddressSpace(IN PEPROCESS Process)
PMM_AVL_TABLE VadTree;
PETHREAD Thread = PsGetCurrentThread();
+ /* Only support this */
+ ASSERT(Process->AddressSpaceInitialized == 2);
+
/* Lock the process address space from changes */
MmLockAddressSpace(&Process->Vm);
+ /* VM is deleted now */
+ Process->VmDeleted = TRUE;
+
/* Enumerate the VADs */
VadTree = &Process->VadRoot;
while (VadTree->NumberGenericTableElements)
@@ -1189,17 +1292,25 @@ MmCleanProcessAddressSpace(IN PEPROCESS Process)
ASSERT(VadTree->NumberGenericTableElements >= 1);
MiRemoveNode((PMMADDRESS_NODE)Vad, VadTree);
- /* Only PEB/TEB VADs supported for now */
- ASSERT(Vad->u.VadFlags.PrivateMemory == 1);
+ /* Only regular VADs supported for now */
ASSERT(Vad->u.VadFlags.VadType == VadNone);
- /* Delete the addresses */
- MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
- (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
- Vad);
+ /* Check if this is a section VAD */
+ if (!(Vad->u.VadFlags.PrivateMemory) && (Vad->ControlArea))
+ {
+ /* Remove the view */
+ MiRemoveMappedView(Process, Vad);
+ }
+ else
+ {
+ /* Delete the addresses */
+ MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
+ (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
+ Vad);
- /* Release the working set */
- MiUnlockProcessWorkingSet(Process, Thread);
+ /* Release the working set */
+ MiUnlockProcessWorkingSet(Process, Thread);
+ }
/* Skip ARM3 fake VADs, they'll be freed by MmDeleteProcessAddresSpace */
if (Vad->u.VadFlags.Spare == 1)
diff --git a/ntoskrnl/mm/ARM3/section.c b/ntoskrnl/mm/ARM3/section.c
index 822c5c524d1..a51bdabba70 100644
--- a/ntoskrnl/mm/ARM3/section.c
+++ b/ntoskrnl/mm/ARM3/section.c
@@ -339,23 +339,25 @@ MiFillSystemPageDirectory(IN PVOID Base,
if (SystemMapPde->u.Hard.Valid == 0)
{
/* Grab a page for it */
+ MI_SET_USAGE(MI_USAGE_PAGE_TABLE);
+ MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
ASSERT(PageFrameIndex);
TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
/* Initialize its PFN entry, with the parent system page directory page table */
MiInitializePfnForOtherProcess(PageFrameIndex,
- PointerPde,
+ (PMMPTE)PointerPde,
MmSystemPageDirectory[(PointerPde - MiAddressToPde(NULL)) / PDE_COUNT]);
/* Make the system PDE entry valid */
- MI_WRITE_VALID_PTE(SystemMapPde, TempPde);
+ MI_WRITE_VALID_PDE(SystemMapPde, TempPde);
/* The system PDE entry might be the PDE itself, so check for this */
if (PointerPde->u.Hard.Valid == 0)
{
/* It's different, so make the real PDE valid too */
- MI_WRITE_VALID_PTE(PointerPde, TempPde);
+ MI_WRITE_VALID_PDE(PointerPde, TempPde);
}
}
@@ -393,6 +395,188 @@ MiCheckPurgeAndUpMapCount(IN PCONTROL_AREA ControlArea,
return STATUS_SUCCESS;
}
+PSUBSECTION
+NTAPI
+MiLocateSubsection(IN PMMVAD Vad,
+ IN ULONG_PTR Vpn)
+{
+ PSUBSECTION Subsection;
+ PCONTROL_AREA ControlArea;
+ ULONG PteOffset;
+
+ /* Get the control area */
+ ControlArea = Vad->ControlArea;
+ ASSERT(ControlArea->u.Flags.Rom == 0);
+ ASSERT(ControlArea->u.Flags.Image == 0);
+ ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
+
+ /* Get the subsection */
+ Subsection = (PSUBSECTION)(ControlArea + 1);
+
+ /* We only support single-subsection segments */
+ ASSERT(Subsection->SubsectionBase != NULL);
+ ASSERT(Vad->FirstPrototypePte >= Subsection->SubsectionBase);
+ ASSERT(Vad->FirstPrototypePte < &Subsection->SubsectionBase[Subsection->PtesInSubsection]);
+
+ /* Compute the PTE offset */
+ PteOffset = (ULONG_PTR)Vpn - Vad->StartingVpn;
+ PteOffset += Vad->FirstPrototypePte - Subsection->SubsectionBase;
+
+ /* Again, we only support single-subsection segments */
+ ASSERT(PteOffset < 0xF0000000);
+ ASSERT(PteOffset < Subsection->PtesInSubsection);
+
+ /* Return the subsection */
+ return Subsection;
+}
+
+VOID
+NTAPI
+MiSegmentDelete(IN PSEGMENT Segment)
+{
+ PCONTROL_AREA ControlArea;
+ SEGMENT_FLAGS SegmentFlags;
+ PSUBSECTION Subsection;
+ PMMPTE PointerPte, LastPte, PteForProto;
+ MMPTE TempPte;
+ KIRQL OldIrql;
+
+ /* Capture data */
+ SegmentFlags = Segment->SegmentFlags;
+ ControlArea = Segment->ControlArea;
+
+ /* Make sure control area is on the right delete path */
+ ASSERT(ControlArea->u.Flags.BeingDeleted == 1);
+ ASSERT(ControlArea->WritableUserReferences == 0);
+
+ /* These things are not supported yet */
+ ASSERT(ControlArea->DereferenceList.Flink == NULL);
+ ASSERT(!(ControlArea->u.Flags.Image) & !(ControlArea->u.Flags.File));
+ ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
+ ASSERT(ControlArea->u.Flags.Rom == 0);
+
+ /* Get the subsection and PTEs for this segment */
+ Subsection = (PSUBSECTION)(ControlArea + 1);
+ PointerPte = Subsection->SubsectionBase;
+ LastPte = PointerPte + Segment->NonExtendedPtes;
+
+ /* Lock the PFN database */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Check if the master PTE is invalid */
+ PteForProto = MiAddressToPte(PointerPte);
+ if (!PteForProto->u.Hard.Valid)
+ {
+ /* Fault it in */
+ MiMakeSystemAddressValidPfn(PointerPte, OldIrql);
+ }
+
+ /* Loop all the segment PTEs */
+ while (PointerPte < LastPte)
+ {
+ /* Check if it's time to switch master PTEs if we passed a PDE boundary */
+ if (!((ULONG_PTR)PointerPte & (PD_SIZE - 1)) &&
+ (PointerPte != Subsection->SubsectionBase))
+ {
+ /* Check if the master PTE is invalid */
+ PteForProto = MiAddressToPte(PointerPte);
+ if (!PteForProto->u.Hard.Valid)
+ {
+ /* Fault it in */
+ MiMakeSystemAddressValidPfn(PointerPte, OldIrql);
+ }
+ }
+
+ /* This should be a prototype PTE */
+ TempPte = *PointerPte;
+ ASSERT(SegmentFlags.LargePages == 0);
+ ASSERT(TempPte.u.Hard.Valid == 0);
+ ASSERT(TempPte.u.Soft.Prototype == 1);
+
+ /* Zero the PTE and keep going */
+ PointerPte->u.Long = 0;
+ PointerPte++;
+ }
+
+ /* Release the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* Free the structures */
+ ExFreePool(ControlArea);
+ ExFreePool(Segment);
+}
+
+VOID
+NTAPI
+MiCheckControlArea(IN PCONTROL_AREA ControlArea,
+ IN KIRQL OldIrql)
+{
+ BOOLEAN DeleteSegment = FALSE;
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /* Check if this is the last reference or view */
+ if (!(ControlArea->NumberOfMappedViews) &&
+ !(ControlArea->NumberOfSectionReferences))
+ {
+ /* There should be no more user references either */
+ ASSERT(ControlArea->NumberOfUserReferences == 0);
+
+ /* Not yet supported */
+ ASSERT(ControlArea->FilePointer == NULL);
+
+ /* The control area is being destroyed */
+ ControlArea->u.Flags.BeingDeleted = TRUE;
+ DeleteSegment = TRUE;
+ }
+
+ /* Release the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* Delete the segment if needed */
+ if (DeleteSegment)
+ {
+ /* No more user write references at all */
+ ASSERT(ControlArea->WritableUserReferences == 0);
+ MiSegmentDelete(ControlArea->Segment);
+ }
+}
+
+VOID
+NTAPI
+MiRemoveMappedView(IN PEPROCESS CurrentProcess,
+ IN PMMVAD Vad)
+{
+ KIRQL OldIrql;
+ PCONTROL_AREA ControlArea;
+
+ /* Get the control area */
+ ControlArea = Vad->ControlArea;
+
+ /* We only support non-extendable, non-image, pagefile-backed regular sections */
+ ASSERT(Vad->u.VadFlags.VadType == VadNone);
+ ASSERT(Vad->u2.VadFlags2.ExtendableFile == FALSE);
+ ASSERT(ControlArea);
+ ASSERT(ControlArea->FilePointer == NULL);
+
+ /* Delete the actual virtual memory pages */
+ MiDeleteVirtualAddresses(Vad->StartingVpn << PAGE_SHIFT,
+ (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
+ Vad);
+
+ /* Release the working set */
+ MiUnlockProcessWorkingSet(CurrentProcess, PsGetCurrentThread());
+
+ /* Lock the PFN database */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Remove references */
+ ControlArea->NumberOfMappedViews--;
+ ControlArea->NumberOfUserReferences--;
+
+ /* Check if it should be destroyed */
+ MiCheckControlArea(ControlArea, OldIrql);
+}
+
NTSTATUS
NTAPI
MiMapViewInSystemSpace(IN PVOID Section,
@@ -505,7 +689,6 @@ MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea,
/* These flags/parameters are not supported */
ASSERT((AllocationType & MEM_DOS_LIM) == 0);
ASSERT((AllocationType & MEM_RESERVE) == 0);
- ASSERT((AllocationType & MEM_TOP_DOWN) == 0);
ASSERT(Process->VmTopDown == 0);
ASSERT(Section->u.Flags.CopyOnWrite == FALSE);
ASSERT(ZeroBits == 0);
@@ -553,13 +736,28 @@ MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea,
/* Did the caller specify an address? */
if (!(*BaseAddress))
{
- /* No, find an address bottom-up */
- Status = MiFindEmptyAddressRangeInTree(*ViewSize,
- _64K,
- &Process->VadRoot,
- (PMMADDRESS_NODE*)&Process->VadFreeHint,
- &StartAddress);
- ASSERT(NT_SUCCESS(Status));
+ /* Which way should we search? */
+ if (AllocationType & MEM_TOP_DOWN)
+ {
+ /* No, find an address top-down */
+ Status = MiFindEmptyAddressRangeDownTree(*ViewSize,
+ (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS,
+ _64K,
+ &Process->VadRoot,
+ &StartAddress,
+ (PMMADDRESS_NODE*)&Process->VadFreeHint);
+ ASSERT(NT_SUCCESS(Status));
+ }
+ else
+ {
+ /* No, find an address bottom-up */
+ Status = MiFindEmptyAddressRangeInTree(*ViewSize,
+ _64K,
+ &Process->VadRoot,
+ (PMMADDRESS_NODE*)&Process->VadFreeHint,
+ &StartAddress);
+ ASSERT(NT_SUCCESS(Status));
+ }
}
else
{
@@ -1179,8 +1377,11 @@ NtCreateSection(OUT PHANDLE SectionHandle,
SEC_LARGE_PAGES | SEC_IMAGE | SEC_NOCACHE |
SEC_NO_CHANGE)))
{
- DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes);
- return STATUS_INVALID_PARAMETER_6;
+ if (!(AllocationAttributes & 1))
+ {
+ DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes);
+ return STATUS_INVALID_PARAMETER_6;
+ }
}
/* Check for no allocation type */
diff --git a/ntoskrnl/mm/ARM3/sysldr.c b/ntoskrnl/mm/ARM3/sysldr.c
index 7990b82d2e6..673ef30afa1 100644
--- a/ntoskrnl/mm/ARM3/sysldr.c
+++ b/ntoskrnl/mm/ARM3/sysldr.c
@@ -166,12 +166,24 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr,
/* The driver is here */
*ImageBase = DriverBase;
+ DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
/* Loop the new driver PTEs */
TempPte = ValidKernelPte;
while (PointerPte < LastPte)
{
/* Allocate a page */
+ MI_SET_USAGE(MI_USAGE_DRIVER_PAGE);
+#if MI_TRACE_PFNS
+ PWCHAR pos = NULL;
+ ULONG len = 0;
+ if (FileName->Buffer)
+ {
+ pos = wcsrchr(FileName->Buffer, '\\');
+ len = wcslen(pos) * sizeof(WCHAR);
+ if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos);
+ }
+#endif
TempPte.u.Hard.PageFrameNumber = MiAllocatePfn(PointerPte, MM_EXECUTE);
/* Write it */
@@ -551,6 +563,7 @@ MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
VOID
NTAPI
+INIT_FUNCTION
MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PVOID OldBase,
IN PVOID NewBase,
@@ -1286,7 +1299,7 @@ CheckDllState:
/* Check if we have an import list */
if (LoadedImports)
{
- /* Reset the count again, and loop entries*/
+ /* Reset the count again, and loop entries */
ImportCount = 0;
for (i = 0; i < LoadedImports->Count; i++)
{
@@ -1352,6 +1365,7 @@ CheckDllState:
VOID
NTAPI
+INIT_FUNCTION
MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PLIST_ENTRY NextEntry;
@@ -1385,6 +1399,23 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
(ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
&LdrEntry->FullDllName);
+ /* Get the first PTE and the number of PTEs we'll need */
+ PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
+ PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
+ LastPte = StartPte + PteCount;
+
+#if MI_TRACE_PFNS
+ /* Loop the PTEs */
+ while (PointerPte < LastPte)
+ {
+ ULONG len;
+ ASSERT(PointerPte->u.Hard.Valid == 1);
+ Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
+ len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
+ snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
+ PointerPte++;
+ }
+#endif
/* Skip kernel and HAL */
/* ROS HACK: Skip BOOTVID/KDCOM too */
i++;
@@ -1424,12 +1455,8 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
/* Remember the original address */
DllBase = LdrEntry->DllBase;
- /* Get the first PTE and the number of PTEs we'll need */
- PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
- PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
- LastPte = StartPte + PteCount;
-
/* Loop the PTEs */
+ PointerPte = StartPte;
while (PointerPte < LastPte)
{
/* Mark the page modified in the PFN database */
@@ -1527,6 +1554,7 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS
NTAPI
+INIT_FUNCTION
MiBuildImportsForBootDrivers(VOID)
{
PLIST_ENTRY NextEntry, NextEntry2;
@@ -1792,6 +1820,7 @@ MiBuildImportsForBootDrivers(VOID)
VOID
NTAPI
+INIT_FUNCTION
MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
{
ULONG_PTR DllBase;
@@ -1852,6 +1881,7 @@ MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
BOOLEAN
NTAPI
+INIT_FUNCTION
MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
diff --git a/ntoskrnl/mm/ARM3/syspte.c b/ntoskrnl/mm/ARM3/syspte.c
index a70ebda3c07..401550d8edf 100644
--- a/ntoskrnl/mm/ARM3/syspte.c
+++ b/ntoskrnl/mm/ARM3/syspte.c
@@ -366,6 +366,7 @@ MiReleaseSystemPtes(IN PMMPTE StartingPte,
VOID
NTAPI
+INIT_FUNCTION
MiInitializeSystemPtes(IN PMMPTE StartingPte,
IN ULONG NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE PoolType)
diff --git a/ntoskrnl/mm/ARM3/vadnode.c b/ntoskrnl/mm/ARM3/vadnode.c
index d725907e66e..d62a02c8a73 100644
--- a/ntoskrnl/mm/ARM3/vadnode.c
+++ b/ntoskrnl/mm/ARM3/vadnode.c
@@ -133,8 +133,9 @@ MiInsertNode(IN PMM_AVL_TABLE Table,
}
else
{
- /* This is a section VAD, this code doesn't happen yet */
- ASSERT(FALSE);
+ /* This is a section VAD. Store the MAREA here for now */
+ DPRINT("Storing %p in %p\n", MemoryArea, Vad);
+ Vad->ControlArea->WaitingForDeletion = (PVOID)MemoryArea;
}
}
}
@@ -191,23 +192,25 @@ MiRemoveNode(IN PMMADDRESS_NODE Node,
{
/* We store the ReactOS MEMORY_AREA here */
MemoryArea = (PMEMORY_AREA)Vad->FirstPrototypePte;
- if (MemoryArea)
- {
- /* Get the process */
- Process = CONTAINING_RECORD(Table, EPROCESS, VadRoot);
-
- /* We only create fake memory-areas for ARM3 VADs */
- ASSERT(MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3);
- ASSERT(MemoryArea->Vad == NULL);
-
- /* Free it */
- MmFreeMemoryArea(&Process->Vm, MemoryArea, NULL, NULL);
- }
}
else
{
- /* This is a section VAD, this code doesn't happen yet */
- ASSERT(FALSE);
+ /* This is a section VAD. We store the ReactOS MEMORY_AREA here */
+ MemoryArea = (PMEMORY_AREA)Vad->ControlArea->WaitingForDeletion;
+ }
+
+ /* Make sure one actually still exists */
+ if (MemoryArea)
+ {
+ /* Get the process */
+ Process = CONTAINING_RECORD(Table, EPROCESS, VadRoot);
+
+ /* We only create fake memory-areas for ARM3 VADs */
+ ASSERT(MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3);
+ ASSERT(MemoryArea->Vad == NULL);
+
+ /* Free it */
+ MmFreeMemoryArea(&Process->Vm, MemoryArea, NULL, NULL);
}
}
}
diff --git a/ntoskrnl/mm/ARM3/virtual.c b/ntoskrnl/mm/ARM3/virtual.c
index 1c5be836978..508db86b1e2 100644
--- a/ntoskrnl/mm/ARM3/virtual.c
+++ b/ntoskrnl/mm/ARM3/virtual.c
@@ -68,6 +68,46 @@ MiMakeSystemAddressValid(IN PVOID PageTableVirtualAddress,
return LockChange;
}
+ULONG
+NTAPI
+MiMakeSystemAddressValidPfn(IN PVOID VirtualAddress,
+ IN KIRQL OldIrql)
+{
+ NTSTATUS Status;
+ BOOLEAN LockChange = FALSE;
+
+ /* Must be e kernel address */
+ ASSERT(VirtualAddress > MM_HIGHEST_USER_ADDRESS);
+
+ /* Check if the page is valid */
+ while (!MmIsAddressValid(VirtualAddress))
+ {
+ /* Release the PFN database */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* Fault it in */
+ Status = MmAccessFault(FALSE, VirtualAddress, KernelMode, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* This should not fail */
+ KeBugCheckEx(KERNEL_DATA_INPAGE_ERROR,
+ 3,
+ Status,
+ 0,
+ (ULONG_PTR)VirtualAddress);
+ }
+
+ /* This flag will be useful later when we do better locking */
+ LockChange = TRUE;
+
+ /* Lock the PFN database */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ }
+
+ /* Let caller know what the lock state is */
+ return LockChange;
+}
+
PFN_NUMBER
NTAPI
MiDeleteSystemPageableVm(IN PMMPTE PointerPte,
@@ -106,7 +146,7 @@ MiDeleteSystemPageableVm(IN PMMPTE PointerPte,
ASSERT(Pfn1->u1.WsIndex == 0);
/* Actual valid, legitimate, pages */
- if (ValidPages) *ValidPages++;
+ if (ValidPages) (*ValidPages)++;
/* Get the page table entry */
PageTableIndex = Pfn1->u4.PteFrame;
@@ -120,7 +160,7 @@ MiDeleteSystemPageableVm(IN PMMPTE PointerPte,
MiDecrementShareCount(Pfn1, PageFrameIndex);
/* Decrement the page table too */
- DPRINT("FIXME: ARM3 should decrement the PT refcount for: %p\n", Pfn2);
+ DPRINT("FIXME: ARM3 should decrement the pool PDE refcount for: %p\n", PageTableIndex);
#if 0 // ARM3: Dont't trust this yet
MiDecrementShareCount(Pfn2, PageTableIndex);
#endif
@@ -144,7 +184,7 @@ MiDeleteSystemPageableVm(IN PMMPTE PointerPte,
*
* Right now, we shouldn't expect any page file information in the PTE
*/
- ASSERT(PointerPte->u.Soft.PageFileHigh == 0);
+ ASSERT(PointerPte->u.Soft.PageFileHigh == 0);
/* Destroy the PTE */
PointerPte->u.Long = 0;
@@ -169,53 +209,90 @@ VOID
NTAPI
MiDeletePte(IN PMMPTE PointerPte,
IN PVOID VirtualAddress,
- IN PEPROCESS CurrentProcess)
+ IN PEPROCESS CurrentProcess,
+ IN PMMPTE PrototypePte)
{
PMMPFN Pfn1;
- MMPTE PteContents;
+ MMPTE TempPte;
PFN_NUMBER PageFrameIndex;
+ PMMPDE PointerPde;
/* PFN lock must be held */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
/* Capture the PTE */
- PteContents = *PointerPte;
+ TempPte = *PointerPte;
/* We only support valid PTEs for now */
- ASSERT(PteContents.u.Hard.Valid == 1);
- ASSERT(PteContents.u.Soft.Prototype == 0);
- ASSERT(PteContents.u.Soft.Transition == 0);
-
- /* Get the PFN entry */
- PageFrameIndex = PFN_FROM_PTE(&PteContents);
- Pfn1 = MiGetPfnEntry(PageFrameIndex);
-
- /* We don't support deleting prototype PTEs for now */
- ASSERT(Pfn1->u3.e1.PrototypePte == 0);
-
- /* Make sure the saved PTE address is valid */
- if ((PMMPTE)((ULONG_PTR)Pfn1->PteAddress & ~0x1) != PointerPte)
+ ASSERT(TempPte.u.Hard.Valid == 1);
+ if (TempPte.u.Hard.Valid == 0)
{
- /* The PFN entry is illegal, or invalid */
- KeBugCheckEx(MEMORY_MANAGEMENT,
- 0x401,
- (ULONG_PTR)PointerPte,
- PointerPte->u.Long,
- (ULONG_PTR)Pfn1->PteAddress);
+ /* Invalid PTEs not supported yet */
+ ASSERT(TempPte.u.Soft.Prototype == 0);
+ ASSERT(TempPte.u.Soft.Transition == 0);
}
- /* There should only be 1 shared reference count */
- ASSERT(Pfn1->u2.ShareCount == 1);
-
- /* FIXME: Drop the reference on the page table. For now, leak it until RosMM is gone */
- //MiDecrementShareCount(MiGetPfnEntry(Pfn1->u4.PteFrame), Pfn1->u4.PteFrame);
+ /* Get the PFN entry */
+ PageFrameIndex = PFN_FROM_PTE(&TempPte);
+ Pfn1 = MiGetPfnEntry(PageFrameIndex);
- /* Mark the PFN for deletion and dereference what should be the last ref */
- MI_SET_PFN_DELETED(Pfn1);
- MiDecrementShareCount(Pfn1, PageFrameIndex);
+ /* Check if this is a valid, prototype PTE */
+ if (Pfn1->u3.e1.PrototypePte == 1)
+ {
+ /* Get the PDE and make sure it's faulted in */
+ PointerPde = MiAddressToPde(PointerPte);
+ if (PointerPde->u.Hard.Valid == 0)
+ {
+#if (_MI_PAGING_LEVELS == 2)
+ /* Could be paged pool access from a new process -- synchronize the page directories */
+ if (!NT_SUCCESS(MiCheckPdeForPagedPool(VirtualAddress)))
+ {
+#endif
+ /* The PDE must be valid at this point */
+ KeBugCheckEx(MEMORY_MANAGEMENT,
+ 0x61940,
+ (ULONG_PTR)PointerPte,
+ PointerPte->u.Long,
+ (ULONG_PTR)VirtualAddress);
+ }
+#if (_MI_PAGING_LEVELS == 2)
+ }
+#endif
+ /* FIXME: Drop the reference on the page table. For now, leak it until RosMM is gone */
+ //MiDecrementShareCount(MiGetPfnEntry(PFN_FROM_PTE(PointerPde)), PFN_FROM_PTE(PointerPde));
+
+ /* Drop the share count */
+ MiDecrementShareCount(Pfn1, PageFrameIndex);
+
+ /* No fork yet */
+ if (PointerPte <= MiHighestUserPte) ASSERT(PrototypePte == Pfn1->PteAddress);
+ }
+ else
+ {
+ /* Make sure the saved PTE address is valid */
+ if ((PMMPTE)((ULONG_PTR)Pfn1->PteAddress & ~0x1) != PointerPte)
+ {
+ /* The PFN entry is illegal, or invalid */
+ KeBugCheckEx(MEMORY_MANAGEMENT,
+ 0x401,
+ (ULONG_PTR)PointerPte,
+ PointerPte->u.Long,
+ (ULONG_PTR)Pfn1->PteAddress);
+ }
+
+ /* There should only be 1 shared reference count */
+ ASSERT(Pfn1->u2.ShareCount == 1);
- /* We should eventually do this */
- //CurrentProcess->NumberOfPrivatePages--;
+ /* FIXME: Drop the reference on the page table. For now, leak it until RosMM is gone */
+ //MiDecrementShareCount(MiGetPfnEntry(Pfn1->u4.PteFrame), Pfn1->u4.PteFrame);
+
+ /* Mark the PFN for deletion and dereference what should be the last ref */
+ MI_SET_PFN_DELETED(Pfn1);
+ MiDecrementShareCount(Pfn1, PageFrameIndex);
+
+ /* We should eventually do this */
+ //CurrentProcess->NumberOfPrivatePages--;
+ }
/* Destroy the PTE and flush the TLB */
PointerPte->u.Long = 0;
@@ -228,27 +305,35 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
IN ULONG_PTR EndingAddress,
IN PMMVAD Vad)
{
- PMMPTE PointerPte, PointerPde;
+ PMMPTE PointerPte, PrototypePte, LastPrototypePte;
+ PMMPDE PointerPde;
MMPTE TempPte;
PEPROCESS CurrentProcess;
KIRQL OldIrql;
+ BOOLEAN AddressGap = FALSE;
+ PSUBSECTION Subsection;
+
+ /* Get out if this is a fake VAD, RosMm will free the marea pages */
+ if ((Vad) && (Vad->u.VadFlags.Spare == 1)) return;
/* Grab the process and PTE/PDE for the address being deleted */
CurrentProcess = PsGetCurrentProcess();
PointerPde = MiAddressToPde(Va);
PointerPte = MiAddressToPte(Va);
- /* We usually only get a VAD when it's not a VM address */
- if (Vad)
+ /* Check if this is a section VAD or a VM VAD */
+ if (!(Vad) || (Vad->u.VadFlags.PrivateMemory) || !(Vad->FirstPrototypePte))
{
- /* Get out if this is a fake VAD, RosMm will free the marea pages */
- if (Vad->u.VadFlags.Spare == 1) return;
-
- /* At process deletion, we may get a VAD, but it should be a VM VAD */
- ASSERT(Vad->u.VadFlags.PrivateMemory);
- //ASSERT(Vad->FirstPrototypePte == NULL); memory_area fuckers
+ /* Don't worry about prototypes */
+ PrototypePte = LastPrototypePte = NULL;
}
-
+ else
+ {
+ /* Get the prototype PTE */
+ PrototypePte = Vad->FirstPrototypePte;
+ LastPrototypePte = Vad->FirstPrototypePte + 1;
+ }
+
/* In all cases, we don't support fork() yet */
ASSERT(CurrentProcess->CloneRoot == NULL);
@@ -256,8 +341,11 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
while (TRUE)
{
/* First keep going until we find a valid PDE */
- while (PointerPde->u.Long == 0)
+ while (!PointerPde->u.Long)
{
+ /* There are gaps in the address space */
+ AddressGap = TRUE;
+
/* Still no valid PDE, try the next 4MB (or whatever) */
PointerPde++;
@@ -270,7 +358,7 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
}
/* Now check if the PDE is mapped in */
- if (PointerPde->u.Hard.Valid == 0)
+ if (!PointerPde->u.Hard.Valid)
{
/* It isn't, so map it in */
PointerPte = MiPteToAddress(PointerPde);
@@ -281,6 +369,26 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
ASSERT(PointerPde->u.Hard.Valid == 1);
ASSERT(Va <= EndingAddress);
+ /* Check if this is a section VAD with gaps in it */
+ if ((AddressGap) && (LastPrototypePte))
+ {
+ /* We need to skip to the next correct prototype PTE */
+ PrototypePte = MI_GET_PROTOTYPE_PTE_FOR_VPN(Vad, Va >> PAGE_SHIFT);
+
+ /* And we need the subsection to skip to the next last prototype PTE */
+ Subsection = MiLocateSubsection(Vad, Va >> PAGE_SHIFT);
+ if (Subsection)
+ {
+ /* Found it! */
+ LastPrototypePte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
+ }
+ else
+ {
+ /* No more subsections, we are done with prototype PTEs */
+ PrototypePte = NULL;
+ }
+ }
+
/* Lock the PFN Database while we delete the PTEs */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
do
@@ -292,11 +400,41 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
/* Check if the PTE is actually mapped in */
if (TempPte.u.Long & 0xFFFFFC01)
{
- /* It is, we don't support prototype PTEs for now though */
- ASSERT(TempPte.u.Soft.Prototype == 0);
+ /* Are we dealing with section VAD? */
+ if ((LastPrototypePte) && (PrototypePte > LastPrototypePte))
+ {
+ /* We need to skip to the next correct prototype PTE */
+ PrototypePte = MI_GET_PROTOTYPE_PTE_FOR_VPN(Vad, Va >> PAGE_SHIFT);
+
+ /* And we need the subsection to skip to the next last prototype PTE */
+ Subsection = MiLocateSubsection(Vad, Va >> PAGE_SHIFT);
+ if (Subsection)
+ {
+ /* Found it! */
+ LastPrototypePte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
+ }
+ else
+ {
+ /* No more subsections, we are done with prototype PTEs */
+ PrototypePte = NULL;
+ }
+ }
- /* Delete the PTE proper */
- MiDeletePte(PointerPte, (PVOID)Va, CurrentProcess);
+ /* Check for prototype PTE */
+ if ((TempPte.u.Hard.Valid == 0) &&
+ (TempPte.u.Soft.Prototype == 1))
+ {
+ /* Just nuke it */
+ PointerPte->u.Long = 0;
+ }
+ else
+ {
+ /* Delete the PTE proper */
+ MiDeletePte(PointerPte,
+ (PVOID)Va,
+ CurrentProcess,
+ PrototypePte);
+ }
}
else
{
@@ -308,6 +446,7 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
/* Update the address and PTE for it */
Va += PAGE_SIZE;
PointerPte++;
+ PrototypePte++;
/* Making sure the PDE is still valid */
ASSERT(PointerPde->u.Hard.Valid == 1);
@@ -323,6 +462,7 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
/* Otherwise, we exited because we hit a new PDE boundary, so start over */
PointerPde = MiAddressToPde(Va);
+ AddressGap = FALSE;
}
}
@@ -909,6 +1049,152 @@ MmFlushVirtualMemory(IN PEPROCESS Process,
return STATUS_SUCCESS;
}
+ULONG
+NTAPI
+MiGetPageProtection(IN PMMPTE PointerPte)
+{
+ MMPTE TempPte;
+ PMMPFN Pfn;
+ PAGED_CODE();
+
+ /* Copy this PTE's contents */
+ TempPte = *PointerPte;
+
+ /* Assure it's not totally zero */
+ ASSERT(TempPte.u.Long);
+
+ /* Check for a special prototype format */
+ if (TempPte.u.Soft.Valid == 0 &&
+ TempPte.u.Soft.Prototype == 1)
+ {
+ /* Unsupported now */
+ UNIMPLEMENTED;
+ ASSERT(FALSE);
+ }
+
+ /* In the easy case of transition or demand zero PTE just return its protection */
+ if (!TempPte.u.Hard.Valid) return MmProtectToValue[TempPte.u.Soft.Protection];
+
+ /* If we get here, the PTE is valid, so look up the page in PFN database */
+ Pfn = MiGetPfnEntry(TempPte.u.Hard.PageFrameNumber);
+
+ if (!Pfn->u3.e1.PrototypePte)
+ {
+ /* Return protection of the original pte */
+ return MmProtectToValue[Pfn->OriginalPte.u.Soft.Protection];
+ }
+
+ /* This is hardware PTE */
+ UNIMPLEMENTED;
+ ASSERT(FALSE);
+
+ return PAGE_NOACCESS;
+}
+
+ULONG
+NTAPI
+MiQueryAddressState(IN PVOID Va,
+ IN PMMVAD Vad,
+ IN PEPROCESS TargetProcess,
+ OUT PULONG ReturnedProtect,
+ OUT PVOID *NextVa)
+{
+
+ PMMPTE PointerPte;
+ PMMPDE PointerPde;
+ MMPTE TempPte;
+ BOOLEAN DemandZeroPte = TRUE, ValidPte = FALSE;
+ ULONG State = MEM_RESERVE, Protect = 0, LockChange;
+ ASSERT((Vad->StartingVpn <= ((ULONG_PTR)Va >> PAGE_SHIFT)) &&
+ (Vad->EndingVpn >= ((ULONG_PTR)Va >> PAGE_SHIFT)));
+
+ /* Only normal VADs supported */
+ ASSERT(Vad->u.VadFlags.VadType == VadNone);
+
+ /* Get the PDE and PTE for the address */
+ PointerPde = MiAddressToPde(Va);
+ PointerPte = MiAddressToPte(Va);
+
+ /* Return the next range */
+ *NextVa = (PVOID)((ULONG_PTR)Va + PAGE_SIZE);
+
+ /* Loop to make sure the PDE is valid */
+ do
+ {
+ /* Try again */
+ LockChange = 0;
+
+ /* Is the PDE empty? */
+ if (!PointerPde->u.Long)
+ {
+ /* No address in this range used yet, move to the next PDE range */
+ *NextVa = MiPteToAddress(MiPteToAddress(PointerPde + 1));
+ break;
+ }
+
+ /* The PDE is empty, but is it faulted in? */
+ if (!PointerPde->u.Hard.Valid)
+ {
+ /* It isn't, go ahead and do the fault */
+ LockChange = MiMakeSystemAddressValid(MiPteToAddress(PointerPde),
+ TargetProcess);
+ }
+
+ /* Check if the PDE was faulted in, making the PTE readable */
+ if (!LockChange) ValidPte = TRUE;
+ } while (LockChange);
+
+ /* Is it safe to try reading the PTE? */
+ if (ValidPte)
+ {
+ /* FIXME: watch out for large pages */
+
+ /* Capture the PTE */
+ TempPte = *PointerPte;
+ if (TempPte.u.Long)
+ {
+ /* The PTE is valid, so it's not zeroed out */
+ DemandZeroPte = FALSE;
+
+ /* Check if it's valid or has a valid protection mask */
+ ASSERT(TempPte.u.Soft.Prototype == 0);
+ if ((TempPte.u.Soft.Protection != MM_DECOMMIT) ||
+ (TempPte.u.Hard.Valid == 1))
+ {
+ /* This means it's committed */
+ State = MEM_COMMIT;
+
+ /* Get protection state of this page */
+ Protect = MiGetPageProtection(PointerPte);
+ }
+ else
+ {
+ /* Otherwise our defaults should hold */
+ ASSERT(Protect == 0);
+ ASSERT(State == MEM_RESERVE);
+ }
+ }
+ }
+
+ /* Check if this was a demand-zero PTE, since we need to find the state */
+ if (DemandZeroPte)
+ {
+ /* Check if the VAD is for committed memory */
+ if (Vad->u.VadFlags.MemCommit)
+ {
+ /* This is committed memory */
+ State = MEM_COMMIT;
+
+ /* Convert the protection */
+ Protect = MmProtectToValue[Vad->u.VadFlags.Protection];
+ }
+ }
+
+ /* Return the protection code */
+ *ReturnedProtect = Protect;
+ return State;
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
/*
@@ -2051,4 +2337,410 @@ NtResetWriteWatch(IN HANDLE ProcessHandle,
return STATUS_SUCCESS;
}
+NTSTATUS
+NTAPI
+MiQueryMemoryBasicInformation(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ OUT PVOID MemoryInformation,
+ IN SIZE_T MemoryInformationLength,
+ OUT PSIZE_T ReturnLength)
+{
+ PEPROCESS TargetProcess;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PMMVAD Vad = NULL;
+ PVOID Address, NextAddress;
+ BOOLEAN Found = FALSE;
+ ULONG NewProtect, NewState, BaseVpn;
+ MEMORY_BASIC_INFORMATION MemoryInfo;
+ KAPC_STATE ApcState;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+
+ /* Check for illegal addresses in user-space, or the shared memory area */
+ if ((BaseAddress > MM_HIGHEST_VAD_ADDRESS) ||
+ (PAGE_ALIGN(BaseAddress) == (PVOID)USER_SHARED_DATA))
+ {
+ Address = PAGE_ALIGN(BaseAddress);
+
+ /* Make up an info structure describing this range */
+ MemoryInfo.BaseAddress = Address;
+ MemoryInfo.AllocationProtect = PAGE_READONLY;
+ MemoryInfo.Type = MEM_PRIVATE;
+
+ /* Special case for shared data */
+ if (Address == (PVOID)USER_SHARED_DATA)
+ {
+ MemoryInfo.AllocationBase = (PVOID)USER_SHARED_DATA;
+ MemoryInfo.State = MEM_COMMIT;
+ MemoryInfo.Protect = PAGE_READONLY;
+ MemoryInfo.RegionSize = PAGE_SIZE;
+ }
+ else
+ {
+ MemoryInfo.AllocationBase = (PCHAR)MM_HIGHEST_VAD_ADDRESS + 1;
+ MemoryInfo.State = MEM_RESERVE;
+ MemoryInfo.Protect = PAGE_NOACCESS;
+ MemoryInfo.RegionSize = (ULONG_PTR)MemoryInfo.AllocationBase - (ULONG_PTR)Address;
+ }
+
+ /* Return the data, NtQueryInformation already probed it*/
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ *(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
+ if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ *(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
+ if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
+ }
+
+ return Status;
+ }
+
+ /* Check if this is for a local or remote process */
+ if (ProcessHandle == NtCurrentProcess())
+ {
+ TargetProcess = PsGetCurrentProcess();
+ }
+ else
+ {
+ /* Reference the target process */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_QUERY_INFORMATION,
+ PsProcessType,
+ ExGetPreviousMode(),
+ (PVOID*)&TargetProcess,
+ NULL);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Attach to it now */
+ KeStackAttachProcess(&TargetProcess->Pcb, &ApcState);
+ }
+
+ /* Loop the VADs */
+ ASSERT(TargetProcess->VadRoot.NumberGenericTableElements);
+ if (TargetProcess->VadRoot.NumberGenericTableElements)
+ {
+ /* Scan on the right */
+ Vad = (PMMVAD)TargetProcess->VadRoot.BalancedRoot.RightChild;
+ BaseVpn = (ULONG_PTR)BaseAddress >> PAGE_SHIFT;
+ while (Vad)
+ {
+ /* Check if this VAD covers the allocation range */
+ if ((BaseVpn >= Vad->StartingVpn) &&
+ (BaseVpn <= Vad->EndingVpn))
+ {
+ /* We're done */
+ Found = TRUE;
+ break;
+ }
+
+ /* Check if this VAD is too high */
+ if (BaseVpn < Vad->StartingVpn)
+ {
+ /* Search on the left next */
+ Vad = Vad->LeftChild;
+ }
+ else
+ {
+ /* Then this VAD is too low, keep searching on the right */
+ ASSERT(BaseVpn > Vad->EndingVpn);
+ Vad = Vad->RightChild;
+ }
+ }
+ }
+
+ /* Was a VAD found? */
+ if (!Found)
+ {
+ Address = PAGE_ALIGN(BaseAddress);
+
+ /* Calculate region size */
+ if (Vad)
+ {
+ if (Vad->StartingVpn >= BaseVpn)
+ {
+ /* Region size is the free space till the start of that VAD */
+ MemoryInfo.RegionSize = (ULONG_PTR)(Vad->StartingVpn << PAGE_SHIFT) - (ULONG_PTR)Address;
+ }
+ else
+ {
+ /* Get the next VAD */
+ Vad = (PMMVAD)MiGetNextNode((PMMADDRESS_NODE)Vad);
+ if (Vad)
+ {
+ /* Region size is the free space till the start of that VAD */
+ MemoryInfo.RegionSize = (ULONG_PTR)(Vad->StartingVpn << PAGE_SHIFT) - (ULONG_PTR)Address;
+ }
+ else
+ {
+ /* Maximum possible region size with that base address */
+ MemoryInfo.RegionSize = (PCHAR)MM_HIGHEST_VAD_ADDRESS + 1 - (PCHAR)Address;
+ }
+ }
+ }
+ else
+ {
+ /* Maximum possible region size with that base address */
+ MemoryInfo.RegionSize = (PCHAR)MM_HIGHEST_VAD_ADDRESS + 1 - (PCHAR)Address;
+ }
+
+ /* Check if we were attached */
+ if (ProcessHandle != NtCurrentProcess())
+ {
+ /* Detach and derefernece the process */
+ KeUnstackDetachProcess(&ApcState);
+ ObDereferenceObject(TargetProcess);
+ }
+
+ /* Build the rest of the initial information block */
+ MemoryInfo.BaseAddress = Address;
+ MemoryInfo.AllocationBase = NULL;
+ MemoryInfo.AllocationProtect = 0;
+ MemoryInfo.State = MEM_FREE;
+ MemoryInfo.Protect = PAGE_NOACCESS;
+ MemoryInfo.Type = 0;
+
+ /* Return the data, NtQueryInformation already probed it*/
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ *(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
+ if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ *(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
+ if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
+ }
+
+ return Status;
+ }
+
+ /* This must be a VM VAD */
+ ASSERT(Vad->u.VadFlags.PrivateMemory);
+
+ /* Build the initial information block */
+ Address = PAGE_ALIGN(BaseAddress);
+ MemoryInfo.BaseAddress = Address;
+ MemoryInfo.AllocationBase = (PVOID)(Vad->StartingVpn << PAGE_SHIFT);
+ MemoryInfo.AllocationProtect = MmProtectToValue[Vad->u.VadFlags.Protection];
+ MemoryInfo.Type = MEM_PRIVATE;
+
+ /* Find the largest chunk of memory which has the same state and protection mask */
+ MemoryInfo.State = MiQueryAddressState(Address,
+ Vad,
+ TargetProcess,
+ &MemoryInfo.Protect,
+ &NextAddress);
+ Address = NextAddress;
+ while (((ULONG_PTR)Address >> PAGE_SHIFT) <= Vad->EndingVpn)
+ {
+ /* Keep going unless the state or protection mask changed */
+ NewState = MiQueryAddressState(Address, Vad, TargetProcess, &NewProtect, &NextAddress);
+ if ((NewState != MemoryInfo.State) || (NewProtect != MemoryInfo.Protect)) break;
+ Address = NextAddress;
+ }
+
+ /* Now that we know the last VA address, calculate the region size */
+ MemoryInfo.RegionSize = ((ULONG_PTR)Address - (ULONG_PTR)MemoryInfo.BaseAddress);
+
+ /* Check if we were attached */
+ if (ProcessHandle != NtCurrentProcess())
+ {
+ /* Detach and derefernece the process */
+ KeUnstackDetachProcess(&ApcState);
+ ObDereferenceObject(TargetProcess);
+ }
+
+ /* Return the data, NtQueryInformation already probed it*/
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ *(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
+ if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ *(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
+ if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
+ }
+
+ /* All went well */
+ DPRINT("Base: %p AllocBase: %p Protect: %lx AllocProtect: %lx "
+ "State: %lx Type: %lx Size: %lx\n",
+ MemoryInfo.BaseAddress, MemoryInfo.AllocationBase,
+ MemoryInfo.AllocationProtect, MemoryInfo.Protect,
+ MemoryInfo.State, MemoryInfo.Type, MemoryInfo.RegionSize);
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+MiQueryMemorySectionName(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ OUT PVOID MemoryInformation,
+ IN SIZE_T MemoryInformationLength,
+ OUT PSIZE_T ReturnLength)
+{
+ PEPROCESS Process;
+ NTSTATUS Status;
+ WCHAR ModuleFileNameBuffer[MAX_PATH] = {0};
+ UNICODE_STRING ModuleFileName;
+ PMEMORY_SECTION_NAME SectionName = NULL;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_QUERY_INFORMATION,
+ NULL,
+ PreviousMode,
+ (PVOID*)(&Process),
+ NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
+ return Status;
+ }
+
+ RtlInitEmptyUnicodeString(&ModuleFileName, ModuleFileNameBuffer, sizeof(ModuleFileNameBuffer));
+ Status = MmGetFileNameForAddress(BaseAddress, &ModuleFileName);
+
+ if (NT_SUCCESS(Status))
+ {
+ SectionName = MemoryInformation;
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
+ SectionName->SectionFileName.MaximumLength = MemoryInformationLength;
+ RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
+
+ if (ReturnLength) *ReturnLength = ModuleFileName.Length;
+
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
+ SectionName->SectionFileName.MaximumLength = MemoryInformationLength;
+ RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
+
+ if (ReturnLength) *ReturnLength = ModuleFileName.Length;
+
+ }
+ }
+ ObDereferenceObject(Process);
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+NtQueryVirtualMemory(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
+ OUT PVOID MemoryInformation,
+ IN SIZE_T MemoryInformationLength,
+ OUT PSIZE_T ReturnLength)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ KPROCESSOR_MODE PreviousMode;
+
+ DPRINT("Querying class %d about address: %p\n", MemoryInformationClass, BaseAddress);
+
+ /* Bail out if the address is invalid */
+ if (BaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER;
+
+ /* Probe return buffer */
+ PreviousMode = ExGetPreviousMode();
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(MemoryInformation,
+ MemoryInformationLength,
+ sizeof(ULONG_PTR));
+
+ if (ReturnLength) ProbeForWriteSize_t(ReturnLength);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ switch(MemoryInformationClass)
+ {
+ case MemoryBasicInformation:
+ /* Validate the size information of the class */
+ if (MemoryInformationLength < sizeof(MEMORY_BASIC_INFORMATION))
+ {
+ /* The size is invalid */
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+ Status = MiQueryMemoryBasicInformation(ProcessHandle,
+ BaseAddress,
+ MemoryInformation,
+ MemoryInformationLength,
+ ReturnLength);
+ break;
+
+ case MemorySectionName:
+ /* Validate the size information of the class */
+ if (MemoryInformationLength < sizeof(MEMORY_SECTION_NAME))
+ {
+ /* The size is invalid */
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+ Status = MiQueryMemorySectionName(ProcessHandle,
+ BaseAddress,
+ MemoryInformation,
+ MemoryInformationLength,
+ ReturnLength);
+ break;
+ case MemoryWorkingSetList:
+ case MemoryBasicVlmInformation:
+ default:
+ DPRINT1("Unhandled memory information class %d\n", MemoryInformationClass);
+ break;
+ }
+
+ return Status;
+}
+
/* EOF */
diff --git a/ntoskrnl/mm/ARM3/zeropage.c b/ntoskrnl/mm/ARM3/zeropage.c
index 4735cfbadf4..5a7aee0d3a6 100644
--- a/ntoskrnl/mm/ARM3/zeropage.c
+++ b/ntoskrnl/mm/ARM3/zeropage.c
@@ -39,6 +39,7 @@ MmZeroPageThread(VOID)
/* FIXME: Get the discardable sections to free them */
// MiFindInitializationCode(&StartAddress, &EndAddress);
// if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress);
+ DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
/* Set our priority to 0 */
Thread->BasePriority = 0;
@@ -71,6 +72,8 @@ MmZeroPageThread(VOID)
PageIndex = MmFreePageListHead.Flink;
ASSERT(PageIndex != LIST_HEAD);
Pfn1 = MiGetPfnEntry(PageIndex);
+ MI_SET_USAGE(MI_USAGE_ZERO_LOOP);
+ MI_SET_PROCESS2("Kernel 0 Loop");
FreePage = MiRemoveAnyPage(MI_GET_PAGE_COLOR(PageIndex));
/* The first global free page should also be the first on its own list */
diff --git a/ntoskrnl/mm/amd64/init.c b/ntoskrnl/mm/amd64/init.c
index a7aed95b36d..3211b99440d 100644
--- a/ntoskrnl/mm/amd64/init.c
+++ b/ntoskrnl/mm/amd64/init.c
@@ -752,9 +752,7 @@ MiBuildPagedPool_x(VOID)
/* Save the first and last paged pool PTE */
MmPagedPoolInfo.FirstPteForPagedPool = MiAddressToPte(MmPagedPoolStart);
MmPagedPoolInfo.LastPteForPagedPool = MiAddressToPte(MmPagedPoolEnd);
-
- MmPagedPoolInfo.NextPdeForPagedPoolExpansion =
- MiAddressToPde(MmPagedPoolStart) + 1;
+ MmPagedPoolInfo.NextPdeForPagedPoolExpansion = MiAddressToPde(MmPagedPoolStart) + 1;
// We keep track of each page via a bit, so check how big the bitmap will
// have to be (make sure to align our page count such that it fits nicely
diff --git a/ntoskrnl/mm/amd64/page.c b/ntoskrnl/mm/amd64/page.c
index b91e5e6a223..3201412e4f4 100644
--- a/ntoskrnl/mm/amd64/page.c
+++ b/ntoskrnl/mm/amd64/page.c
@@ -77,6 +77,43 @@ MmProtectToPteMask[32] =
PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
};
+const
+ULONG MmProtectToValue[32] =
+{
+ PAGE_NOACCESS,
+ PAGE_READONLY,
+ PAGE_EXECUTE,
+ PAGE_EXECUTE_READ,
+ PAGE_READWRITE,
+ PAGE_WRITECOPY,
+ PAGE_EXECUTE_READWRITE,
+ PAGE_EXECUTE_WRITECOPY,
+ PAGE_NOACCESS,
+ PAGE_NOCACHE | PAGE_READONLY,
+ PAGE_NOCACHE | PAGE_EXECUTE,
+ PAGE_NOCACHE | PAGE_EXECUTE_READ,
+ PAGE_NOCACHE | PAGE_READWRITE,
+ PAGE_NOCACHE | PAGE_WRITECOPY,
+ PAGE_NOCACHE | PAGE_EXECUTE_READWRITE,
+ PAGE_NOCACHE | PAGE_EXECUTE_WRITECOPY,
+ PAGE_NOACCESS,
+ PAGE_GUARD | PAGE_READONLY,
+ PAGE_GUARD | PAGE_EXECUTE,
+ PAGE_GUARD | PAGE_EXECUTE_READ,
+ PAGE_GUARD | PAGE_READWRITE,
+ PAGE_GUARD | PAGE_WRITECOPY,
+ PAGE_GUARD | PAGE_EXECUTE_READWRITE,
+ PAGE_GUARD | PAGE_EXECUTE_WRITECOPY,
+ PAGE_NOACCESS,
+ PAGE_WRITECOMBINE | PAGE_READONLY,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE_READ,
+ PAGE_WRITECOMBINE | PAGE_READWRITE,
+ PAGE_WRITECOMBINE | PAGE_WRITECOPY,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE_READWRITE,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE_WRITECOPY
+};
+
/* PRIVATE FUNCTIONS *******************************************************/
BOOLEAN
@@ -418,8 +455,8 @@ MmDeleteVirtualMapping(
{
Pfn = OldPte.u.Hard.PageFrameNumber;
- if (FreePage)
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ //if (FreePage)
+ //MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
}
else
Pfn = 0;
diff --git a/ntoskrnl/mm/anonmem.c b/ntoskrnl/mm/anonmem.c
index 0564c7ac71c..766a8fc17c2 100644
--- a/ntoskrnl/mm/anonmem.c
+++ b/ntoskrnl/mm/anonmem.c
@@ -367,6 +367,8 @@ MmNotPresentFaultVirtualMemory(PMMSUPPORT AddressSpace,
/*
* Try to allocate a page
*/
+ MI_SET_USAGE(MI_USAGE_VAD);
+ MI_SET_PROCESS2(Process->ImageFileName);
Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
if (Status == STATUS_NO_MEMORY)
{
@@ -516,99 +518,6 @@ MmModifyAttributes(PMMSUPPORT AddressSpace,
}
}
-NTSTATUS FASTCALL
-MiQueryVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID Address,
- IN MEMORY_INFORMATION_CLASS VirtualMemoryInformationClass,
- OUT PVOID VirtualMemoryInformation,
- IN SIZE_T Length,
- OUT PSIZE_T ResultLength)
-{
- NTSTATUS Status;
- PEPROCESS Process;
- MEMORY_AREA* MemoryArea;
- PMMSUPPORT AddressSpace;
-
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_QUERY_INFORMATION,
- NULL,
- UserMode,
- (PVOID*)(&Process),
- NULL);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtQueryVirtualMemory() = %x\n",Status);
- return(Status);
- }
-
- AddressSpace = &Process->Vm;
-
- MmLockAddressSpace(AddressSpace);
- MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
- switch(VirtualMemoryInformationClass)
- {
- case MemoryBasicInformation:
- {
- PMEMORY_BASIC_INFORMATION Info =
- (PMEMORY_BASIC_INFORMATION)VirtualMemoryInformation;
- if (Length != sizeof(MEMORY_BASIC_INFORMATION))
- {
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
- return(STATUS_INFO_LENGTH_MISMATCH);
- }
-
- if (MemoryArea == NULL)
- {
- Info->Type = 0;
- Info->State = MEM_FREE;
- Info->Protect = PAGE_NOACCESS;
- Info->AllocationProtect = 0;
- Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
- Info->AllocationBase = NULL;
- Info->RegionSize = MmFindGapAtAddress(AddressSpace, Info->BaseAddress);
- Status = STATUS_SUCCESS;
- *ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
- }
- else
- {
- switch(MemoryArea->Type)
- {
- case MEMORY_AREA_VIRTUAL_MEMORY:
- Status = MmQueryAnonMem(MemoryArea, Address, Info,
- ResultLength);
- break;
-
- case MEMORY_AREA_SECTION_VIEW:
- Status = MmQuerySectionView(MemoryArea, Address, Info,
- ResultLength);
- break;
-
- default:
- DPRINT1("unhandled memory area type: 0x%x\n", MemoryArea->Type);
- Status = STATUS_UNSUCCESSFUL;
- *ResultLength = 0;
- }
- }
- break;
- }
-
- default:
- {
- DPRINT1("Unsupported or unimplemented class: %lx\n", VirtualMemoryInformationClass);
- Status = STATUS_INVALID_INFO_CLASS;
- *ResultLength = 0;
- break;
- }
- }
-
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
-
- return Status;
-}
-
NTSTATUS NTAPI
MiProtectVirtualMemory(IN PEPROCESS Process,
IN OUT PVOID *BaseAddress,
@@ -1032,171 +941,6 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
return(STATUS_SUCCESS);
}
-
-NTSTATUS NTAPI
-NtQueryVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID Address,
- IN MEMORY_INFORMATION_CLASS VirtualMemoryInformationClass,
- OUT PVOID VirtualMemoryInformation,
- IN SIZE_T Length,
- OUT PSIZE_T UnsafeResultLength)
-{
- NTSTATUS Status;
- SIZE_T ResultLength = 0;
- KPROCESSOR_MODE PreviousMode;
- WCHAR ModuleFileNameBuffer[MAX_PATH] = {0};
- UNICODE_STRING ModuleFileName;
- PMEMORY_SECTION_NAME SectionName = NULL;
- PEPROCESS Process;
- union
- {
- MEMORY_BASIC_INFORMATION BasicInfo;
- }
- VirtualMemoryInfo;
-
- DPRINT("NtQueryVirtualMemory(ProcessHandle %x, Address %x, "
- "VirtualMemoryInformationClass %d, VirtualMemoryInformation %x, "
- "Length %lu ResultLength %x)\n",ProcessHandle,Address,
- VirtualMemoryInformationClass,VirtualMemoryInformation,
- Length,ResultLength);
-
- PreviousMode = ExGetPreviousMode();
-
- if (PreviousMode != KernelMode)
- {
- _SEH2_TRY
- {
- ProbeForWrite(VirtualMemoryInformation,
- Length,
- sizeof(ULONG_PTR));
-
- if (UnsafeResultLength) ProbeForWriteSize_t(UnsafeResultLength);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Return the exception code */
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
- }
- _SEH2_END;
- }
-
- if (Address >= MmSystemRangeStart)
- {
- DPRINT1("Invalid parameter\n");
- return STATUS_INVALID_PARAMETER;
- }
-
- /* FIXME: Move this inside MiQueryVirtualMemory */
- if (VirtualMemoryInformationClass == MemorySectionName)
- {
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_QUERY_INFORMATION,
- NULL,
- PreviousMode,
- (PVOID*)(&Process),
- NULL);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtQueryVirtualMemory() = %x\n",Status);
- return(Status);
- }
-
- RtlInitEmptyUnicodeString(&ModuleFileName, ModuleFileNameBuffer, sizeof(ModuleFileNameBuffer));
- Status = MmGetFileNameForAddress(Address, &ModuleFileName);
-
- if (NT_SUCCESS(Status))
- {
- SectionName = VirtualMemoryInformation;
- if (PreviousMode != KernelMode)
- {
- _SEH2_TRY
- {
- RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
- SectionName->SectionFileName.MaximumLength = Length;
- RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
-
- if (UnsafeResultLength != NULL)
- {
- *UnsafeResultLength = ModuleFileName.Length;
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
- }
- else
- {
- RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
- SectionName->SectionFileName.MaximumLength = Length;
- RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
-
- if (UnsafeResultLength != NULL)
- {
- *UnsafeResultLength = ModuleFileName.Length;
- }
- }
- }
- ObDereferenceObject(Process);
- return Status;
- }
- else
- {
- Status = MiQueryVirtualMemory(ProcessHandle,
- Address,
- VirtualMemoryInformationClass,
- &VirtualMemoryInfo,
- Length,
- &ResultLength);
- }
-
- if (NT_SUCCESS(Status))
- {
- if (PreviousMode != KernelMode)
- {
- _SEH2_TRY
- {
- if (ResultLength > 0)
- {
- ProbeForWrite(VirtualMemoryInformation,
- ResultLength,
- 1);
- RtlCopyMemory(VirtualMemoryInformation,
- &VirtualMemoryInfo,
- ResultLength);
- }
- if (UnsafeResultLength != NULL)
- {
- *UnsafeResultLength = ResultLength;
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
- }
- else
- {
- if (ResultLength > 0)
- {
- RtlCopyMemory(VirtualMemoryInformation,
- &VirtualMemoryInfo,
- ResultLength);
- }
-
- if (UnsafeResultLength != NULL)
- {
- *UnsafeResultLength = ResultLength;
- }
- }
- }
-
- return(Status);
-}
-
static VOID
MmFreeVirtualMemoryPage(PVOID Context,
MEMORY_AREA* MemoryArea,
diff --git a/ntoskrnl/mm/arm/page.c b/ntoskrnl/mm/arm/page.c
index c24115a049d..549b65a9613 100644
--- a/ntoskrnl/mm/arm/page.c
+++ b/ntoskrnl/mm/arm/page.c
@@ -12,10 +12,111 @@
#define NDEBUG
#include
+#line 15 "ARM³::ARMPAGE"
+#define MODULE_INVOLVED_IN_ARM3
+#include "../ARM3/miarm.h"
+
/* GLOBALS ********************************************************************/
+const
+ULONG
+MmProtectToPteMask[32] =
+{
+ //
+ // These are the base MM_ protection flags
+ //
+ 0,
+ PTE_READONLY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
+ PTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_WRITECOPY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
+ //
+ // These OR in the MM_NOCACHE flag
+ //
+ 0,
+ PTE_READONLY | PTE_DISABLE_CACHE,
+ PTE_EXECUTE | PTE_DISABLE_CACHE,
+ PTE_EXECUTE_READ | PTE_DISABLE_CACHE,
+ PTE_READWRITE | PTE_DISABLE_CACHE,
+ PTE_WRITECOPY | PTE_DISABLE_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE,
+ //
+ // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
+ //
+ 0,
+ PTE_READONLY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
+ PTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_WRITECOPY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
+ //
+ // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
+ //
+ 0,
+ PTE_READONLY | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE,
+ PTE_READWRITE | PTE_WRITECOMBINED_CACHE,
+ PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
+};
+
+const
+ULONG MmProtectToValue[32] =
+{
+ PAGE_NOACCESS,
+ PAGE_READONLY,
+ PAGE_EXECUTE,
+ PAGE_EXECUTE_READ,
+ PAGE_READWRITE,
+ PAGE_WRITECOPY,
+ PAGE_EXECUTE_READWRITE,
+ PAGE_EXECUTE_WRITECOPY,
+ PAGE_NOACCESS,
+ PAGE_NOCACHE | PAGE_READONLY,
+ PAGE_NOCACHE | PAGE_EXECUTE,
+ PAGE_NOCACHE | PAGE_EXECUTE_READ,
+ PAGE_NOCACHE | PAGE_READWRITE,
+ PAGE_NOCACHE | PAGE_WRITECOPY,
+ PAGE_NOCACHE | PAGE_EXECUTE_READWRITE,
+ PAGE_NOCACHE | PAGE_EXECUTE_WRITECOPY,
+ PAGE_NOACCESS,
+ PAGE_GUARD | PAGE_READONLY,
+ PAGE_GUARD | PAGE_EXECUTE,
+ PAGE_GUARD | PAGE_EXECUTE_READ,
+ PAGE_GUARD | PAGE_READWRITE,
+ PAGE_GUARD | PAGE_WRITECOPY,
+ PAGE_GUARD | PAGE_EXECUTE_READWRITE,
+ PAGE_GUARD | PAGE_EXECUTE_WRITECOPY,
+ PAGE_NOACCESS,
+ PAGE_WRITECOMBINE | PAGE_READONLY,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE_READ,
+ PAGE_WRITECOMBINE | PAGE_READWRITE,
+ PAGE_WRITECOMBINE | PAGE_WRITECOPY,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE_READWRITE,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE_WRITECOPY
+};
+
ULONG MmGlobalKernelPageDirectory[4096];
-MMPDE HyperTemplatePde;
+
+/* Template PTE and PDE for a kernel page */
+MMPDE ValidKernelPde = {.u.Hard.Valid = 1};
+MMPTE ValidKernelPte = {.u.Hard.Valid = 1, .u.Hard.Sbo = 1};
+
+/* Template PDE for a demand-zero page */
+MMPDE DemandZeroPde = {.u.Long = (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS)};
+MMPTE DemandZeroPte = {.u.Long = (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS)};
+
+/* Template PTE for prototype page */
+MMPTE PrototypePte = {.u.Long = (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS) | PTE_PROTOTYPE | (MI_PTE_LOOKUP_NEEDED << PAGE_SHIFT)};
/* PRIVATE FUNCTIONS **********************************************************/
@@ -49,25 +150,6 @@ MmUpdatePageDir(IN PEPROCESS Process,
return;
}
-NTSTATUS
-NTAPI
-Mmi386ReleaseMmInfo(IN PEPROCESS Process)
-{
- UNIMPLEMENTED;
- while (TRUE);
- return 0;
-}
-
-NTSTATUS
-NTAPI
-MmInitializeHandBuiltProcess(IN PEPROCESS Process,
- IN PULONG DirectoryTableBase)
-{
- UNIMPLEMENTED;
- while (TRUE);
- return STATUS_SUCCESS;
-}
-
PULONG
NTAPI
MmGetPageDirectory(VOID)
@@ -246,16 +328,7 @@ MmInitGlobalKernelPageDirectory(VOID)
{
ULONG i;
PULONG CurrentPageDirectory = (PULONG)PDE_BASE;
- extern MMPTE HyperTemplatePte;
-
- /* Setup PTE template */
- HyperTemplatePte.u.Long = 0;
- HyperTemplatePte.u.Hard.Valid = 1;
- HyperTemplatePte.u.Hard.Access = 1;
- /* Setup PDE template */
- HyperTemplatePde.u.Long = 0;
- HyperTemplatePde.u.Hard.Valid = 1;
/* Loop the 2GB of address space which belong to the kernel */
for (i = MiGetPdeOffset(MmSystemRangeStart); i < 2048; i++)
diff --git a/ntoskrnl/mm/arm/stubs.c b/ntoskrnl/mm/arm/stubs.c
index 55178c747aa..781ea284e05 100644
--- a/ntoskrnl/mm/arm/stubs.c
+++ b/ntoskrnl/mm/arm/stubs.c
@@ -367,18 +367,6 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
return TRUE;
}
-VOID
-NTAPI
-MmUpdatePageDir(IN PEPROCESS Process,
- IN PVOID Address,
- IN ULONG Size)
-{
- //
- // Nothing to do
- //
- return;
-}
-
NTSTATUS
NTAPI
Mmi386ReleaseMmInfo(IN PEPROCESS Process)
@@ -391,30 +379,6 @@ Mmi386ReleaseMmInfo(IN PEPROCESS Process)
return 0;
}
-NTSTATUS
-NTAPI
-MmInitializeHandBuiltProcess(IN PEPROCESS Process,
- IN PULONG DirectoryTableBase)
-{
- //
- // Share the directory base with the idle process
- //
- DirectoryTableBase[0] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[0];
- DirectoryTableBase[1] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[1];
-
- //
- // Initialize the Addresss Space
- //
- KeInitializeGuardedMutex(&Process->AddressCreationLock);
- Process->VadRoot.BalancedRoot.u1.Parent = NULL;
-
- //
- // The process now has an address space
- //
- Process->HasAddressSpace = TRUE;
- return STATUS_SUCCESS;
-}
-
PULONG
NTAPI
MmGetPageDirectory(VOID)
diff --git a/ntoskrnl/mm/balance.c b/ntoskrnl/mm/balance.c
index 1303c013f70..17edb8e97c3 100644
--- a/ntoskrnl/mm/balance.c
+++ b/ntoskrnl/mm/balance.c
@@ -47,14 +47,6 @@ static LONG MiBalancerWork = 0;
/* FUNCTIONS ****************************************************************/
-VOID MmPrintMemoryStatistic(VOID)
-{
- DbgPrint("MC_CACHE %d, MC_USER %d, MC_PPOOL %d, MC_NPPOOL %d, MmAvailablePages %d\n",
- MiMemoryConsumers[MC_CACHE].PagesUsed, MiMemoryConsumers[MC_USER].PagesUsed,
- MiMemoryConsumers[MC_PPOOL].PagesUsed, MiMemoryConsumers[MC_NPPOOL].PagesUsed,
- MmAvailablePages);
-}
-
VOID
INIT_FUNCTION
NTAPI
@@ -80,13 +72,7 @@ MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages)
{
MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 8;
}
- MiMemoryConsumers[MC_USER].PagesTarget =
- NrAvailablePages - MiMinimumAvailablePages;
- MiMemoryConsumers[MC_PPOOL].PagesTarget = NrAvailablePages / 2;
- MiMemoryConsumers[MC_NPPOOL].PagesTarget = 0xFFFFFFFF;
- MiMemoryConsumers[MC_NPPOOL].PagesUsed = NrSystemPages;
- MiMemoryConsumers[MC_SYSTEM].PagesTarget = 0xFFFFFFFF;
- MiMemoryConsumers[MC_SYSTEM].PagesUsed = 0;
+ MiMemoryConsumers[MC_USER].PagesTarget = NrAvailablePages - MiMinimumAvailablePages;
}
VOID
@@ -261,7 +247,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
/*
* Allocate always memory for the non paged pool and for the pager thread.
*/
- if ((Consumer == MC_NPPOOL) || (Consumer == MC_SYSTEM) || MiIsBalancerThread())
+ if ((Consumer == MC_SYSTEM) || MiIsBalancerThread())
{
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MmAllocPage(Consumer);
diff --git a/ntoskrnl/mm/freelist.c b/ntoskrnl/mm/freelist.c
index d2a36d06a50..7eef9593f95 100644
--- a/ntoskrnl/mm/freelist.c
+++ b/ntoskrnl/mm/freelist.c
@@ -23,13 +23,7 @@
/* GLOBALS ****************************************************************/
-//
-//
// ReactOS to NT Physical Page Descriptor Entry Legacy Mapping Definitions
-//
-// REACTOS NT
-//
-#define RmapListHead AweReferenceCount
#define PHYSICAL_PAGE MMPFN
#define PPHYSICAL_PAGE PMMPFN
@@ -85,6 +79,8 @@ MmGetLRUFirstUserPage(VOID)
if (Position == 0xFFFFFFFF) return 0;
/* Return it */
+ ASSERT(Position != 0);
+ ASSERT_IS_ROS_PFN(MiGetPfnEntry(Position));
return Position;
}
@@ -95,6 +91,8 @@ MmInsertLRULastUserPage(PFN_NUMBER Pfn)
KIRQL OldIrql;
/* Set the page as a user page */
+ ASSERT(Pfn != 0);
+ ASSERT_IS_ROS_PFN(MiGetPfnEntry(Pfn));
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
RtlSetBit(&MiUserPfnBitMap, Pfn);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
@@ -114,6 +112,8 @@ MmGetLRUNextUserPage(PFN_NUMBER PreviousPfn)
if (Position == 0xFFFFFFFF) return 0;
/* Return it */
+ ASSERT(Position != 0);
+ ASSERT_IS_ROS_PFN(MiGetPfnEntry(Position));
return Position;
}
@@ -122,6 +122,8 @@ NTAPI
MmRemoveLRUUserPage(PFN_NUMBER Page)
{
/* Unset the page as a user page */
+ ASSERT(Page != 0);
+ ASSERT_IS_ROS_PFN(MiGetPfnEntry(Page));
RtlClearBit(&MiUserPfnBitMap, Page);
}
@@ -159,7 +161,7 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
KIRQL OldIrql;
PPHYSICAL_PAGE Pfn1;
INT LookForZeroedPages;
- ASSERT (KeGetCurrentIrql() <= APC_LEVEL);
+ ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
//
// Convert the low address into a PFN
@@ -228,6 +230,8 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
while (PagesFound < PageCount)
{
/* Grab a page */
+ MI_SET_USAGE(MI_USAGE_MDL);
+ MI_SET_PROCESS2("Kernel");
Page = MiRemoveAnyPage(0);
if (Page == 0)
{
@@ -244,12 +248,14 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
//
ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
- //
- // Allocate it and mark it
- //
+ /* Now setup the page and mark it */
+ Pfn1->u3.e2.ReferenceCount = 1;
+ Pfn1->u2.ShareCount = 1;
+ MI_SET_PFN_DELETED(Pfn1);
+ Pfn1->u4.PteFrame = 0x1FFEDCB;
Pfn1->u3.e1.StartOfAllocation = 1;
Pfn1->u3.e1.EndOfAllocation = 1;
- Pfn1->u3.e2.ReferenceCount = 1;
+ Pfn1->u4.VerifierAllocation = 0;
//
// Save it into the MDL
@@ -283,6 +289,9 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
if ((Pfn1->u3.e1.PageLocation == ZeroedPageList) != LookForZeroedPages) continue;
/* Remove the page from the free or zero list */
+ ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
+ MI_SET_USAGE(MI_USAGE_MDL);
+ MI_SET_PROCESS2("Kernel");
MiUnlinkFreeOrZeroedPage(Pfn1);
//
@@ -294,9 +303,13 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
// Now setup the page and mark it
//
Pfn1->u3.e2.ReferenceCount = 1;
+ Pfn1->u2.ShareCount = 1;
+ MI_SET_PFN_DELETED(Pfn1);
+ Pfn1->u4.PteFrame = 0x1FFEDCB;
Pfn1->u3.e1.StartOfAllocation = 1;
Pfn1->u3.e1.EndOfAllocation = 1;
-
+ Pfn1->u4.VerifierAllocation = 0;
+
//
// Save this page into the MDL
//
@@ -338,7 +351,7 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
//
// Terminate the MDL array if there's certain missing pages
//
- if (PagesFound != PageCount) *MdlPage = -1;
+ if (PagesFound != PageCount) *MdlPage = LIST_HEAD;
//
// Now go back and loop over all the MDL pages
@@ -351,7 +364,7 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
// Check if we've reached the end
//
Page = *MdlPage++;
- if (Page == (PFN_NUMBER)-1) break;
+ if (Page == LIST_HEAD) break;
//
// Get the PFN entry for the page and check if we should zero it out
@@ -363,7 +376,7 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
}
//
- // We're done, mark the pages as locked (should we lock them, though???)
+ // We're done, mark the pages as locked
//
Mdl->Process = NULL;
Mdl->MdlFlags |= MDL_PAGES_LOCKED;
@@ -372,79 +385,23 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
VOID
NTAPI
-MmDumpPfnDatabase(VOID)
-{
- ULONG i;
- PPHYSICAL_PAGE Pfn1;
- PCHAR State = "????", Type = "Unknown";
- KIRQL OldIrql;
- ULONG Totals[5] = {0}, FreePages = 0;
-
- KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
- //
- // Loop the PFN database
- //
- for (i = 0; i <= MmHighestPhysicalPage; i++)
- {
- Pfn1 = MiGetPfnEntry(i);
- if (!Pfn1) continue;
-
- //
- // Get the type
- //
- if (MiIsPfnInUse(Pfn1))
- {
- State = "Used";
- }
- else
- {
- State = "Free";
- Type = "Free";
- FreePages++;
- break;
- }
-
- //
- // Pretty-print the page
- //
- DbgPrint("0x%08p:\t%04s\t%20s\t(%02d) [%08p])\n",
- i << PAGE_SHIFT,
- State,
- Type,
- Pfn1->u3.e2.ReferenceCount,
- Pfn1->RmapListHead);
- }
-
- DbgPrint("Nonpaged Pool: %d pages\t[%d KB]\n", Totals[MC_NPPOOL], (Totals[MC_NPPOOL] << PAGE_SHIFT) / 1024);
- DbgPrint("Paged Pool: %d pages\t[%d KB]\n", Totals[MC_PPOOL], (Totals[MC_PPOOL] << PAGE_SHIFT) / 1024);
- DbgPrint("File System Cache: %d pages\t[%d KB]\n", Totals[MC_CACHE], (Totals[MC_CACHE] << PAGE_SHIFT) / 1024);
- DbgPrint("Process Working Set: %d pages\t[%d KB]\n", Totals[MC_USER], (Totals[MC_USER] << PAGE_SHIFT) / 1024);
- DbgPrint("System: %d pages\t[%d KB]\n", Totals[MC_SYSTEM], (Totals[MC_SYSTEM] << PAGE_SHIFT) / 1024);
- DbgPrint("Free: %d pages\t[%d KB]\n", FreePages, (FreePages << PAGE_SHIFT) / 1024);
-
- KeLowerIrql(OldIrql);
-}
-
-VOID
-NTAPI
-MmSetRmapListHeadPage(PFN_NUMBER Pfn, struct _MM_RMAP_ENTRY* ListHead)
+MmSetRmapListHeadPage(PFN_NUMBER Pfn, PMM_RMAP_ENTRY ListHead)
{
KIRQL oldIrql;
PMMPFN Pfn1;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Pfn1 = MiGetPfnEntry(Pfn);
+ ASSERT(Pfn1);
+ ASSERT_IS_ROS_PFN(Pfn1);
+
if (ListHead)
{
/* Should not be trying to insert an RMAP for a non-active page */
ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
/* Set the list head address */
- Pfn1->RmapListHead = (LONG)ListHead;
-
- /* Mark that the page has an actual RMAP, not a residual color link */
- Pfn1->u3.e1.ParityError = TRUE;
+ MI_GET_ROS_DATA(Pfn1)->RmapListHead = ListHead;
}
else
{
@@ -452,23 +409,20 @@ MmSetRmapListHeadPage(PFN_NUMBER Pfn, struct _MM_RMAP_ENTRY* ListHead)
ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
/* In this case, the RMAP is actually being removed, so clear field */
- Pfn1->RmapListHead = 0;
-
- /* Mark that the page has no RMAP, not a residual color link */
- Pfn1->u3.e1.ParityError = FALSE;
-
+ MI_GET_ROS_DATA(Pfn1)->RmapListHead = NULL;
+
/* ReactOS semantics will now release the page, which will make it free and enter a colored list */
}
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
-struct _MM_RMAP_ENTRY*
+PMM_RMAP_ENTRY
NTAPI
MmGetRmapListHeadPage(PFN_NUMBER Pfn)
{
KIRQL oldIrql;
- struct _MM_RMAP_ENTRY* ListHead;
+ PMM_RMAP_ENTRY ListHead;
PMMPFN Pfn1;
/* Lock PFN database */
@@ -476,15 +430,11 @@ MmGetRmapListHeadPage(PFN_NUMBER Pfn)
/* Get the entry */
Pfn1 = MiGetPfnEntry(Pfn);
-
- /* Check if the page doesn't really have an RMAP */
- if (Pfn1->u3.e1.ParityError == FALSE)
- {
- KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
- return NULL;
- }
-
- ListHead = (struct _MM_RMAP_ENTRY*)Pfn1->RmapListHead;
+ ASSERT(Pfn1);
+ ASSERT_IS_ROS_PFN(Pfn1);
+
+ /* Get the list head */
+ ListHead = MI_GET_ROS_DATA(Pfn1)->RmapListHead;
/* Should not have an RMAP for a non-active page */
ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
@@ -499,9 +449,14 @@ NTAPI
MmSetSavedSwapEntryPage(PFN_NUMBER Pfn, SWAPENTRY SwapEntry)
{
KIRQL oldIrql;
-
+ PPHYSICAL_PAGE Page;
+
+ Page = MiGetPfnEntry(Pfn);
+ ASSERT(Page);
+ ASSERT_IS_ROS_PFN(Page);
+
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- MiGetPfnEntry(Pfn)->u1.WsIndex = SwapEntry;
+ MI_GET_ROS_DATA(Page)->SwapEntry = SwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
@@ -511,9 +466,14 @@ MmGetSavedSwapEntryPage(PFN_NUMBER Pfn)
{
SWAPENTRY SwapEntry;
KIRQL oldIrql;
+ PPHYSICAL_PAGE Page;
+
+ Page = MiGetPfnEntry(Pfn);
+ ASSERT(Page);
+ ASSERT_IS_ROS_PFN(Page);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- SwapEntry = MiGetPfnEntry(Pfn)->u1.WsIndex;
+ SwapEntry = MI_GET_ROS_DATA(Page)->SwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(SwapEntry);
@@ -534,7 +494,8 @@ MmReferencePage(PFN_NUMBER Pfn)
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
-
+ ASSERT_IS_ROS_PFN(Page);
+
Page->u3.e2.ReferenceCount++;
}
@@ -551,6 +512,7 @@ MmGetReferenceCountPage(PFN_NUMBER Pfn)
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
+ ASSERT_IS_ROS_PFN(Page);
RCount = Page->u3.e2.ReferenceCount;
@@ -570,17 +532,22 @@ NTAPI
MmDereferencePage(PFN_NUMBER Pfn)
{
PPHYSICAL_PAGE Page;
-
DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
-
+ ASSERT_IS_ROS_PFN(Page);
+
Page->u3.e2.ReferenceCount--;
if (Page->u3.e2.ReferenceCount == 0)
{
/* Mark the page temporarily as valid, we're going to make it free soon */
Page->u3.e1.PageLocation = ActiveAndValid;
+
+ /* It's not a ROS PFN anymore */
+ Page->u4.AweAllocation = FALSE;
+ ExFreePool(MI_GET_ROS_DATA(Page));
+ Page->RosMmData = 0;
/* Bring it back into the free list */
DPRINT("Legacy free: %lx\n", Pfn);
@@ -595,14 +562,7 @@ MmAllocPage(ULONG Type)
PFN_NUMBER PfnOffset;
PMMPFN Pfn1;
- if (Type != MC_SYSTEM)
- {
- PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
- }
- else
- {
- PfnOffset = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
- }
+ PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
if (!PfnOffset)
{
@@ -614,6 +574,17 @@ MmAllocPage(ULONG Type)
Pfn1 = MiGetPfnEntry(PfnOffset);
Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->u3.e1.PageLocation = ActiveAndValid;
+
+ /* This marks the PFN as a ReactOS PFN */
+ Pfn1->u4.AweAllocation = TRUE;
+
+ /* Allocate the extra ReactOS Data and zero it out */
+ Pfn1->RosMmData = (LONG)ExAllocatePoolWithTag(NonPagedPool, sizeof(MMROSPFN), 'RsPf');
+ ASSERT(MI_GET_ROS_DATA(Pfn1) != NULL);
+ ASSERT_IS_ROS_PFN(Pfn1);
+ MI_GET_ROS_DATA(Pfn1)->SwapEntry = 0;
+ MI_GET_ROS_DATA(Pfn1)->RmapListHead = NULL;
+
return PfnOffset;
}
diff --git a/ntoskrnl/mm/i386/page.c b/ntoskrnl/mm/i386/page.c
index 9ce0ef5163c..a7dbce4127e 100644
--- a/ntoskrnl/mm/i386/page.c
+++ b/ntoskrnl/mm/i386/page.c
@@ -223,7 +223,10 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
MmDeleteHyperspaceMapping(PageDir);
return NULL;
}
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
+ MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY);
+ if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+ if (!Process) MI_SET_PROCESS2("Kernel Legacy");
+ Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn);
if (!NT_SUCCESS(Status) || Pfn == 0)
{
KeBugCheck(MEMORY_MANAGEMENT);
@@ -231,7 +234,7 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Entry = InterlockedCompareExchangePte(&PageDir[PdeOffset], PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
if (Entry != 0)
{
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
Pfn = PTE_TO_PFN(Entry);
}
}
@@ -258,6 +261,9 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
{
return NULL;
}
+ MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY);
+ if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+ if (!Process) MI_SET_PROCESS2("Kernel Legacy");
Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn);
if (!NT_SUCCESS(Status) || Pfn == 0)
{
@@ -280,7 +286,10 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
{
return NULL;
}
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
+ MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY);
+ if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+ if (!Process) MI_SET_PROCESS2("Kernel Legacy");
+ Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn);
if (!NT_SUCCESS(Status) || Pfn == 0)
{
KeBugCheck(MEMORY_MANAGEMENT);
@@ -288,7 +297,7 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Entry = InterlockedCompareExchangePte(PageDir, PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
if (Entry != 0)
{
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
}
}
}
@@ -449,7 +458,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN FreePage,
if (FreePage && WasValid)
{
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
}
/*
@@ -465,6 +474,18 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN FreePage,
}
}
+VOID
+NTAPI
+MmGetPageFileMapping(PEPROCESS Process, PVOID Address,
+ SWAPENTRY* SwapEntry)
+/*
+ * FUNCTION: Get a page file mapping
+ */
+{
+ ULONG Entry = MmGetPageEntryForProcess(Process, Address);
+ *SwapEntry = Entry >> 1;
+}
+
VOID
NTAPI
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
@@ -909,54 +930,6 @@ MmGetPhysicalAddress(PVOID vaddr)
return p;
}
-VOID
-NTAPI
-MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size)
-{
- ULONG StartOffset, EndOffset, Offset;
- PULONG Pde;
-
- //
- // Check if the process isn't there anymore
- // This is probably a bad sign, since it means the caller is setting cr3 to
- // 0 or something...
- //
- if ((PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]) == 0) && (Process != PsGetCurrentProcess()))
- {
- DPRINT1("Process: %16s is dead: %p\n", Process->ImageFileName, Process->Pcb.DirectoryTableBase[0]);
- ASSERT(FALSE);
- return;
- }
-
- if (Address < MmSystemRangeStart)
- {
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- StartOffset = ADDR_TO_PDE_OFFSET(Address);
- EndOffset = ADDR_TO_PDE_OFFSET((PVOID)((ULONG_PTR)Address + Size));
-
- if (Process != NULL && Process != PsGetCurrentProcess())
- {
- Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
- }
- else
- {
- Pde = (PULONG)PAGEDIRECTORY_MAP;
- }
- for (Offset = StartOffset; Offset <= EndOffset; Offset++)
- {
- if (Offset != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP))
- {
- InterlockedCompareExchangePte(&Pde[Offset], MmGlobalKernelPageDirectory[Offset], 0);
- }
- }
- if (Pde != (PULONG)PAGEDIRECTORY_MAP)
- {
- MmDeleteHyperspaceMapping(Pde);
- }
-}
-
VOID
INIT_FUNCTION
NTAPI
diff --git a/ntoskrnl/mm/marea.c b/ntoskrnl/mm/marea.c
index 92aacb8b822..a621abfdc69 100644
--- a/ntoskrnl/mm/marea.c
+++ b/ntoskrnl/mm/marea.c
@@ -356,6 +356,12 @@ NTAPI
MiInsertVad(IN PMMVAD Vad,
IN PEPROCESS Process);
+ULONG
+NTAPI
+MiMakeProtectionMask(
+ IN ULONG Protect
+);
+
static VOID
MmInsertMemoryArea(
PMMSUPPORT AddressSpace,
@@ -389,6 +395,7 @@ MmInsertMemoryArea(
}
Vad->u.VadFlags.Spare = 1;
Vad->u.VadFlags.PrivateMemory = 1;
+ Vad->u.VadFlags.Protection = MiMakeProtectionMask(marea->Protect);
MiInsertVad(Vad, MmGetAddressSpaceOwner(AddressSpace));
marea->Vad = Vad;
}
@@ -485,13 +492,16 @@ MmFindGapBottomUp(
break;
AlignedAddress = MM_ROUND_UP(PreviousNode->EndingAddress, Granularity);
- if (Node->StartingAddress > AlignedAddress &&
- (ULONG_PTR)Node->StartingAddress - (ULONG_PTR)AlignedAddress >= Length)
+ if (AlignedAddress >= LowestAddress)
{
- DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
- return AlignedAddress;
+ if (Node->StartingAddress > AlignedAddress &&
+ (ULONG_PTR)Node->StartingAddress - (ULONG_PTR)AlignedAddress >= Length)
+ {
+ DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
+ ASSERT(AlignedAddress >= LowestAddress);
+ return AlignedAddress;
+ }
}
-
PreviousNode = Node;
}
@@ -501,6 +511,7 @@ MmFindGapBottomUp(
(ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length)
{
DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
+ ASSERT(AlignedAddress >= LowestAddress);
return AlignedAddress;
}
@@ -510,6 +521,7 @@ MmFindGapBottomUp(
(ULONG_PTR)FirstNode->StartingAddress - (ULONG_PTR)AlignedAddress >= Length)
{
DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
+ ASSERT(AlignedAddress >= LowestAddress);
return AlignedAddress;
}
diff --git a/ntoskrnl/mm/mmfault.c b/ntoskrnl/mm/mmfault.c
index 269a1659fe6..9a3ecf9f0ef 100644
--- a/ntoskrnl/mm/mmfault.c
+++ b/ntoskrnl/mm/mmfault.c
@@ -9,6 +9,9 @@
/* INCLUDES *******************************************************************/
#include
+#ifdef NEWCC
+#include "../cache/section/newmm.h"
+#endif
#define NDEBUG
#include
@@ -17,37 +20,6 @@
/* PRIVATE FUNCTIONS **********************************************************/
-VOID
-FASTCALL
-MiSyncForProcessAttach(IN PKTHREAD Thread,
- IN PEPROCESS Process)
-{
- PETHREAD Ethread = CONTAINING_RECORD(Thread, ETHREAD, Tcb);
-
- /* Hack Sync because Mm is broken */
- MmUpdatePageDir(Process, Ethread, sizeof(ETHREAD));
- MmUpdatePageDir(Process, Ethread->ThreadsProcess, sizeof(EPROCESS));
- MmUpdatePageDir(Process,
- (PVOID)Thread->StackLimit,
- Thread->LargeStack ?
- KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE);
-}
-
-VOID
-FASTCALL
-MiSyncForContextSwitch(IN PKTHREAD Thread)
-{
- PVOID Process = PsGetCurrentProcess();
- PETHREAD Ethread = CONTAINING_RECORD(Thread, ETHREAD, Tcb);
-
- /* Hack Sync because Mm is broken */
- MmUpdatePageDir(Process, Ethread->ThreadsProcess, sizeof(EPROCESS));
- MmUpdatePageDir(Process,
- (PVOID)Thread->StackLimit,
- Thread->LargeStack ?
- KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE);
-}
-
NTSTATUS
NTAPI
MmpAccessFault(KPROCESSOR_MODE Mode,
@@ -116,6 +88,18 @@ MmpAccessFault(KPROCESSOR_MODE Mode,
Status = STATUS_ACCESS_VIOLATION;
break;
+#ifdef NEWCC
+ case MEMORY_AREA_CACHE:
+ // This code locks for itself to keep from having to break a lock
+ // passed in.
+ if (!FromMdl)
+ MmUnlockAddressSpace(AddressSpace);
+ Status = MmAccessFaultCacheSection(Mode, Address, Locked);
+ if (!FromMdl)
+ MmLockAddressSpace(AddressSpace);
+ break;
+#endif
+
default:
Status = STATUS_ACCESS_VIOLATION;
break;
@@ -206,6 +190,18 @@ MmNotPresentFault(KPROCESSOR_MODE Mode,
Locked);
break;
+#ifdef NEWCC
+ case MEMORY_AREA_CACHE:
+ // This code locks for itself to keep from having to break a lock
+ // passed in.
+ if (!FromMdl)
+ MmUnlockAddressSpace(AddressSpace);
+ Status = MmNotPresentFaultCacheSection(Mode, Address, Locked);
+ if (!FromMdl)
+ MmLockAddressSpace(AddressSpace);
+ break;
+#endif
+
default:
Status = STATUS_ACCESS_VIOLATION;
break;
@@ -230,7 +226,7 @@ MmAccessFault(IN BOOLEAN StoreInstruction,
IN KPROCESSOR_MODE Mode,
IN PVOID TrapInformation)
{
- PMEMORY_AREA MemoryArea;
+ PMEMORY_AREA MemoryArea = NULL;
/* Cute little hack for ROS */
if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)
@@ -245,27 +241,24 @@ MmAccessFault(IN BOOLEAN StoreInstruction,
#endif
}
- /*
- * Check if this is an ARM3 memory area or if there's no memory area at all.
- * The latter can happen early in the boot cycle when ARM3 paged pool is in
- * use before having defined the memory areas proper.
- * A proper fix would be to define memory areas in the ARM3 code, but we want
- * to avoid adding this ReactOS-specific construct to ARM3 code.
- * Either way, in the future, as ReactOS-paged pool is eliminated, this hack
- * can go away.
- */
- MemoryArea = MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address);
- if (!(MemoryArea) && (Address <= MM_HIGHEST_USER_ADDRESS))
+ /* Is there a ReactOS address space yet? */
+ if (MmGetKernelAddressSpace())
{
- /* Could this be a VAD fault from user-mode? */
- MemoryArea = MmLocateMemoryAreaByAddress(MmGetCurrentAddressSpace(), Address);
+ /* Check if this is an ARM3 memory area */
+ MemoryArea = MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address);
+ if (!(MemoryArea) && (Address <= MM_HIGHEST_USER_ADDRESS))
+ {
+ /* Could this be a VAD fault from user-mode? */
+ MemoryArea = MmLocateMemoryAreaByAddress(MmGetCurrentAddressSpace(), Address);
+ }
}
- if ((!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) ||
- ((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)))
+
+ /* Is this an ARM3 memory area, or is there no address space yet? */
+ if (((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)) ||
+ (!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) ||
+ (!MmGetKernelAddressSpace()))
{
- //
- // Hand it off to more competent hands...
- //
+ /* This is an ARM3 fault */
DPRINT("ARM3 fault %p\n", MemoryArea);
return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation);
}
diff --git a/ntoskrnl/mm/mminit.c b/ntoskrnl/mm/mminit.c
index 60ea7f70cc6..1ad5b5cc0d4 100644
--- a/ntoskrnl/mm/mminit.c
+++ b/ntoskrnl/mm/mminit.c
@@ -19,37 +19,6 @@
VOID NTAPI MiInitializeUserPfnBitmap(VOID);
-PCHAR
-MemType[] =
-{
- "ExceptionBlock ",
- "SystemBlock ",
- "Free ",
- "Bad ",
- "LoadedProgram ",
- "FirmwareTemporary ",
- "FirmwarePermanent ",
- "OsloaderHeap ",
- "OsloaderStack ",
- "SystemCode ",
- "HalCode ",
- "BootDriver ",
- "ConsoleInDriver ",
- "ConsoleOutDriver ",
- "StartupDpcStack ",
- "StartupKernelStack",
- "StartupPanicStack ",
- "StartupPcrPage ",
- "StartupPdrPage ",
- "RegistryData ",
- "MemoryData ",
- "NlsData ",
- "SpecialMemory ",
- "BBTMemory ",
- "LoaderReserve ",
- "LoaderXIPRom "
-};
-
HANDLE MpwThreadHandle;
KEVENT MpwThreadEvent;
@@ -61,12 +30,6 @@ ULONG MmReadClusterSize;
UCHAR MmDisablePagingExecutive = 1; // Forced to off
PMMPTE MmSharedUserDataPte;
PMMSUPPORT MmKernelAddressSpace;
-BOOLEAN MiDbgEnableMdDump =
-#ifdef _ARM_
-TRUE;
-#else
-FALSE;
-#endif
/* PRIVATE FUNCTIONS *********************************************************/
@@ -268,6 +231,7 @@ MiInitSystemMemoryAreas()
VOID
NTAPI
+INIT_FUNCTION
MiDbgDumpAddressSpace(VOID)
{
//
@@ -314,27 +278,6 @@ MiDbgDumpAddressSpace(VOID)
"Non Paged Pool Expansion PTE Space");
}
-VOID
-NTAPI
-MiDbgDumpMemoryDescriptors(VOID)
-{
- PLIST_ENTRY NextEntry;
- PMEMORY_ALLOCATION_DESCRIPTOR Md;
- ULONG TotalPages = 0;
-
- DPRINT1("Base\t\tLength\t\tType\n");
- for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
- NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
- NextEntry = NextEntry->Flink)
- {
- Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
- DPRINT1("%08lX\t%08lX\t%s\n", Md->BasePage, Md->PageCount, MemType[Md->MemoryType]);
- TotalPages += Md->PageCount;
- }
-
- DPRINT1("Total: %08lX (%d MB)\n", TotalPages, (TotalPages * PAGE_SIZE) / 1024 / 1024);
-}
-
NTSTATUS NTAPI
MmMpwThreadMain(PVOID Ignored)
{
@@ -360,12 +303,17 @@ MmMpwThreadMain(PVOID Ignored)
PagesWritten = 0;
+#ifndef NEWCC
+ // XXX arty -- we flush when evicting pages or destorying cache
+ // sections.
CcRosFlushDirtyPages(128, &PagesWritten);
+#endif
}
}
NTSTATUS
NTAPI
+INIT_FUNCTION
MmInitMpwThread(VOID)
{
KPRIORITY Priority;
@@ -397,6 +345,7 @@ MmInitMpwThread(VOID)
NTSTATUS
NTAPI
+INIT_FUNCTION
MmInitBsmThread(VOID)
{
NTSTATUS Status;
@@ -420,6 +369,7 @@ MmInitBsmThread(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
MmInitSystem(IN ULONG Phase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
@@ -428,75 +378,65 @@ MmInitSystem(IN ULONG Phase,
MMPTE TempPte = ValidKernelPte;
PFN_NUMBER PageFrameNumber;
- if (Phase == 0)
- {
- /* Initialize the kernel address space */
- KeInitializeGuardedMutex(&PsGetCurrentProcess()->AddressCreationLock);
- MmKernelAddressSpace = MmGetCurrentAddressSpace();
- MmInitGlobalKernelPageDirectory();
-
- /* Dump memory descriptors */
- if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors();
-
- /* Initialize ARM³ in phase 0 */
- MmArmInitSystem(0, KeLoaderBlock);
+ /* Initialize the kernel address space */
+ ASSERT(Phase == 1);
+ KeInitializeGuardedMutex(&PsIdleProcess->AddressCreationLock);
+ MmKernelAddressSpace = &PsIdleProcess->Vm;
- /* Intialize system memory areas */
- MiInitSystemMemoryAreas();
+ /* Intialize system memory areas */
+ MiInitSystemMemoryAreas();
- /* Dump the address space */
- MiDbgDumpAddressSpace();
- }
- else if (Phase == 1)
- {
- MiInitializeUserPfnBitmap();
- MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
- MmInitializeRmapList();
- MmInitializePageOp();
- MmInitSectionImplementation();
- MmInitPagingFile();
-
- //
- // Create a PTE to double-map the shared data section. We allocate it
- // from paged pool so that we can't fault when trying to touch the PTE
- // itself (to map it), since paged pool addresses will already be mapped
- // by the fault handler.
- //
- MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool,
- sizeof(MMPTE),
- ' mM');
- if (!MmSharedUserDataPte) return FALSE;
-
- //
- // Now get the PTE for shared data, and read the PFN that holds it
- //
- PointerPte = MiAddressToPte((PVOID)KI_USER_SHARED_DATA);
- ASSERT(PointerPte->u.Hard.Valid == 1);
- PageFrameNumber = PFN_FROM_PTE(PointerPte);
-
- /* Build the PTE and write it */
- MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte,
- PointerPte,
- MM_READONLY,
- PageFrameNumber);
- *MmSharedUserDataPte = TempPte;
-
- /* Setup the memory threshold events */
- if (!MiInitializeMemoryEvents()) return FALSE;
-
- /*
- * Unmap low memory
- */
- MiInitBalancerThread();
-
- /*
- * Initialise the modified page writer.
- */
- MmInitMpwThread();
-
- /* Initialize the balance set manager */
- MmInitBsmThread();
- }
+ /* Dump the address space */
+ MiDbgDumpAddressSpace();
+
+ MmInitGlobalKernelPageDirectory();
+ MiInitializeUserPfnBitmap();
+ MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
+ MmInitializeRmapList();
+ MmInitializePageOp();
+ MmInitSectionImplementation();
+ MmInitPagingFile();
+
+ //
+ // Create a PTE to double-map the shared data section. We allocate it
+ // from paged pool so that we can't fault when trying to touch the PTE
+ // itself (to map it), since paged pool addresses will already be mapped
+ // by the fault handler.
+ //
+ MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool,
+ sizeof(MMPTE),
+ ' mM');
+ if (!MmSharedUserDataPte) return FALSE;
+
+ //
+ // Now get the PTE for shared data, and read the PFN that holds it
+ //
+ PointerPte = MiAddressToPte((PVOID)KI_USER_SHARED_DATA);
+ ASSERT(PointerPte->u.Hard.Valid == 1);
+ PageFrameNumber = PFN_FROM_PTE(PointerPte);
+
+ /* Build the PTE and write it */
+ MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte,
+ PointerPte,
+ MM_READONLY,
+ PageFrameNumber);
+ *MmSharedUserDataPte = TempPte;
+
+ /* Setup the memory threshold events */
+ if (!MiInitializeMemoryEvents()) return FALSE;
+
+ /*
+ * Unmap low memory
+ */
+ MiInitBalancerThread();
+
+ /*
+ * Initialise the modified page writer.
+ */
+ MmInitMpwThread();
+
+ /* Initialize the balance set manager */
+ MmInitBsmThread();
return TRUE;
}
diff --git a/ntoskrnl/mm/pagefile.c b/ntoskrnl/mm/pagefile.c
index a9c1c6ab0f9..cfa5d9cc6c5 100644
--- a/ntoskrnl/mm/pagefile.c
+++ b/ntoskrnl/mm/pagefile.c
@@ -132,7 +132,7 @@ MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
BOOLEAN
NTAPI
-MmIsFileAPagingFile(PFILE_OBJECT FileObject)
+MmIsFileObjectAPagingFile(PFILE_OBJECT FileObject)
{
ULONG i;
@@ -252,6 +252,7 @@ MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
MmBuildMdlFromPages(Mdl, &Page);
+ MmReferencePage(Page);
Mdl->MdlFlags |= MDL_PAGES_LOCKED;
file_offset.QuadPart = offset * PAGE_SIZE;
@@ -313,6 +314,7 @@ MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
MmBuildMdlFromPages(Mdl, &Page);
+ MmReferencePage(Page);
Mdl->MdlFlags |= MDL_PAGES_LOCKED;
file_offset.QuadPart = offset * PAGE_SIZE;
diff --git a/ntoskrnl/mm/rmap.c b/ntoskrnl/mm/rmap.c
index 8d6b7a6aab4..8d6867e50cc 100644
--- a/ntoskrnl/mm/rmap.c
+++ b/ntoskrnl/mm/rmap.c
@@ -10,6 +10,9 @@
/* INCLUDES *****************************************************************/
#include
+#ifdef NEWCC
+#include "../cache/section/newmm.h"
+#endif
#define NDEBUG
#include
@@ -19,21 +22,10 @@
/* TYPES ********************************************************************/
-typedef struct _MM_RMAP_ENTRY
-{
- struct _MM_RMAP_ENTRY* Next;
- PEPROCESS Process;
- PVOID Address;
-#if DBG
- PVOID Caller;
-#endif
-}
-MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
-
/* GLOBALS ******************************************************************/
-static FAST_MUTEX RmapListLock;
static NPAGED_LOOKASIDE_LIST RmapLookasideList;
+FAST_MUTEX RmapListLock;
/* FUNCTIONS ****************************************************************/
@@ -76,6 +68,7 @@ MmPageOutPhysicalAddress(PFN_NUMBER Page)
Process = entry->Process;
Address = entry->Address;
+
if ((((ULONG_PTR)Address) & 0xFFF) != 0)
{
KeBugCheck(MEMORY_MANAGEMENT);
@@ -204,8 +197,11 @@ MmSetCleanAllRmaps(PFN_NUMBER Page)
}
while (current_entry != NULL)
{
- MmSetCleanPage(current_entry->Process, current_entry->Address);
- current_entry = current_entry->Next;
+#ifdef NEWCC
+ if (!RMAP_IS_SEGMENT(current_entry->Address))
+#endif
+ MmSetCleanPage(current_entry->Process, current_entry->Address);
+ current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
}
@@ -225,7 +221,10 @@ MmSetDirtyAllRmaps(PFN_NUMBER Page)
}
while (current_entry != NULL)
{
- MmSetDirtyPage(current_entry->Process, current_entry->Address);
+#ifdef NEWCC
+ if (!RMAP_IS_SEGMENT(current_entry->Address))
+#endif
+ MmSetDirtyPage(current_entry->Process, current_entry->Address);
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
@@ -246,7 +245,11 @@ MmIsDirtyPageRmap(PFN_NUMBER Page)
}
while (current_entry != NULL)
{
- if (MmIsDirtyPage(current_entry->Process, current_entry->Address))
+ if (
+#ifdef NEWCC
+ !RMAP_IS_SEGMENT(current_entry->Address) &&
+#endif
+ MmIsDirtyPage(current_entry->Process, current_entry->Address))
{
ExReleaseFastMutex(&RmapListLock);
return(TRUE);
@@ -265,8 +268,10 @@ MmInsertRmap(PFN_NUMBER Page, PEPROCESS Process,
PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY new_entry;
ULONG PrevSize;
-
- Address = (PVOID)PAGE_ROUND_DOWN(Address);
+#ifdef NEWCC
+ if (!RMAP_IS_SEGMENT(Address))
+#endif
+ Address = (PVOID)PAGE_ROUND_DOWN(Address);
new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList);
if (new_entry == NULL)
@@ -283,7 +288,11 @@ MmInsertRmap(PFN_NUMBER Page, PEPROCESS Process,
#endif
#endif
- if (MmGetPfnForProcess(Process, Address) != Page)
+ if (
+#ifdef NEWCC
+ !RMAP_IS_SEGMENT(Address) &&
+#endif
+ MmGetPfnForProcess(Process, Address) != Page)
{
DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
"address 0x%.8X\n", Process->UniqueProcessId, Address,
@@ -313,17 +322,22 @@ MmInsertRmap(PFN_NUMBER Page, PEPROCESS Process,
#endif
MmSetRmapListHeadPage(Page, new_entry);
ExReleaseFastMutex(&RmapListLock);
- if (Process == NULL)
+#ifdef NEWCC
+ if (!RMAP_IS_SEGMENT(Address))
+#endif
{
- Process = PsInitialSystemProcess;
- }
- if (Process)
- {
- PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE);
- if (PrevSize >= Process->Vm.PeakWorkingSetSize)
- {
- Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE;
- }
+ if (Process == NULL)
+ {
+ Process = PsInitialSystemProcess;
+ }
+ if (Process)
+ {
+ PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE);
+ if (PrevSize >= Process->Vm.PeakWorkingSetSize)
+ {
+ Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE;
+ }
+ }
}
}
@@ -350,21 +364,32 @@ MmDeleteAllRmaps(PFN_NUMBER Page, PVOID Context,
{
previous_entry = current_entry;
current_entry = current_entry->Next;
- if (DeleteMapping)
- {
- DeleteMapping(Context, previous_entry->Process,
- previous_entry->Address);
- }
- Process = previous_entry->Process;
- ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
- if (Process == NULL)
- {
- Process = PsInitialSystemProcess;
- }
- if (Process)
- {
- (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
- }
+#ifdef NEWCC
+ if (!RMAP_IS_SEGMENT(current_entry->Address))
+#endif
+ {
+ if (DeleteMapping)
+ {
+ DeleteMapping(Context, previous_entry->Process,
+ previous_entry->Address);
+ }
+ Process = previous_entry->Process;
+ ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
+ if (Process == NULL)
+ {
+ Process = PsInitialSystemProcess;
+ }
+ if (Process)
+ {
+ (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
+ }
+ }
+#ifdef NEWCC
+ else
+ {
+ ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
+ }
+#endif
}
}
@@ -394,14 +419,19 @@ MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process,
}
ExReleaseFastMutex(&RmapListLock);
ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
- if (Process == NULL)
- {
- Process = PsInitialSystemProcess;
- }
- if (Process)
- {
- (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
- }
+#ifdef NEWCC
+ if (!RMAP_IS_SEGMENT(Address))
+#endif
+ {
+ if (Process == NULL)
+ {
+ Process = PsInitialSystemProcess;
+ }
+ if (Process)
+ {
+ (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
+ }
+ }
return;
}
previous_entry = current_entry;
@@ -409,3 +439,63 @@ MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process,
}
KeBugCheck(MEMORY_MANAGEMENT);
}
+
+#ifdef NEWCC
+PVOID
+NTAPI
+MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset)
+{
+ PCACHE_SECTION_PAGE_TABLE Result = NULL;
+ PMM_RMAP_ENTRY current_entry, previous_entry;
+
+ ExAcquireFastMutex(&RmapListLock);
+ previous_entry = NULL;
+ current_entry = MmGetRmapListHeadPage(Page);
+ while (current_entry != NULL)
+ {
+ if (RMAP_IS_SEGMENT(current_entry->Address))
+ {
+ Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process;
+ *RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK;
+ InterlockedIncrementUL(&Result->Segment->ReferenceCount);
+ ExReleaseFastMutex(&RmapListLock);
+ return Result;
+ }
+ previous_entry = current_entry;
+ current_entry = current_entry->Next;
+ }
+ ExReleaseFastMutex(&RmapListLock);
+ return NULL;
+}
+
+VOID
+NTAPI
+MmDeleteSectionAssociation(PFN_NUMBER Page)
+{
+ PMM_RMAP_ENTRY current_entry, previous_entry;
+
+ ExAcquireFastMutex(&RmapListLock);
+ previous_entry = NULL;
+ current_entry = MmGetRmapListHeadPage(Page);
+ while (current_entry != NULL)
+ {
+ if (RMAP_IS_SEGMENT(current_entry->Address))
+ {
+ if (previous_entry == NULL)
+ {
+ MmSetRmapListHeadPage(Page, current_entry->Next);
+ }
+ else
+ {
+ previous_entry->Next = current_entry->Next;
+ }
+ ExReleaseFastMutex(&RmapListLock);
+ ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
+ return;
+ }
+ previous_entry = current_entry;
+ current_entry = current_entry->Next;
+ }
+ ExReleaseFastMutex(&RmapListLock);
+}
+#endif
diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c
index 3b00025d6d1..bef77f4cad5 100644
--- a/ntoskrnl/mm/section.c
+++ b/ntoskrnl/mm/section.c
@@ -45,6 +45,9 @@
/* INCLUDES *****************************************************************/
#include
+#ifdef NEWCC
+#include "../cache/section/newmm.h"
+#endif
#define NDEBUG
#include
#include
@@ -745,7 +748,7 @@ MmspCompleteAndReleasePageOp(PMM_PAGEOP PageOp)
* ARGUMENTS: PFILE_OBJECT to wait for.
* RETURNS: Status of the wait.
*/
-static NTSTATUS
+NTSTATUS
MmspWaitForFileLock(PFILE_OBJECT File)
{
return STATUS_SUCCESS;
@@ -979,7 +982,11 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
NTSTATUS Status;
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
IsDirectMapped = TRUE;
+#ifndef NEWCC
Status = CcRosUnmapCacheSegment(Bcb, FileOffset, Dirty);
+#else
+ Status = STATUS_SUCCESS;
+#endif
if (!NT_SUCCESS(Status))
{
DPRINT1("CcRosUnmapCacheSegment failed, status = %x\n", Status);
@@ -1057,6 +1064,7 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
ULONG SegOffset)
{
+#ifndef NEWCC
if (!(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
{
PBCB Bcb;
@@ -1069,6 +1077,7 @@ BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
return TRUE;
}
}
+#endif
return FALSE;
}
@@ -1091,6 +1100,7 @@ MiCopyFromUserPage(PFN_NUMBER DestPage, PVOID SourceAddress)
return(STATUS_SUCCESS);
}
+#ifndef NEWCC
NTSTATUS
NTAPI
MiReadPage(PMEMORY_AREA MemoryArea,
@@ -1183,6 +1193,8 @@ MiReadPage(PMEMORY_AREA MemoryArea,
* Allocate a page, this is rather complicated by the possibility
* we might have to move other things out of memory
*/
+ MI_SET_USAGE(MI_USAGE_SECTION);
+ MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, Page);
if (!NT_SUCCESS(Status))
{
@@ -1267,6 +1279,35 @@ MiReadPage(PMEMORY_AREA MemoryArea,
}
return(STATUS_SUCCESS);
}
+#else
+NTSTATUS
+NTAPI
+MiReadPage(PMEMORY_AREA MemoryArea,
+ ULONG SegOffset,
+ PPFN_NUMBER Page)
+/*
+ * FUNCTION: Read a page for a section backed memory area.
+ * PARAMETERS:
+ * MemoryArea - Memory area to read the page for.
+ * Offset - Offset of the page to read.
+ * Page - Variable that receives a page contains the read data.
+ */
+{
+ MM_REQUIRED_RESOURCES Resources = { };
+
+ Resources.Context = MemoryArea->Data.SectionData.Section->FileObject;
+ Resources.FileOffset.QuadPart = SegOffset +
+ MemoryArea->Data.SectionData.Segment->FileOffset;
+ Resources.Consumer = MC_USER;
+ Resources.Amount = PAGE_SIZE;
+
+ DPRINT1("%S, offset %x, len %d, page %x\n", ((PFILE_OBJECT)Resources.Context)->FileName.Buffer, Resources.FileOffset.LowPart, Resources.Amount, Resources.Page[0]);
+
+ NTSTATUS Status = MiReadFilePage(NULL, NULL, &Resources);
+ *Page = Resources.Page[0];
+ return Status;
+}
+#endif
NTSTATUS
NTAPI
@@ -1447,6 +1488,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
MmUnlockAddressSpace(AddressSpace);
+ MI_SET_USAGE(MI_USAGE_SECTION);
+ if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+ if (!Process) MI_SET_PROCESS2("Kernel Section");
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
if (!NT_SUCCESS(Status))
{
@@ -1528,6 +1572,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
if (Segment->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
{
MmUnlockSectionSegment(Segment);
+ MI_SET_USAGE(MI_USAGE_SECTION);
+ if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+ if (!Process) MI_SET_PROCESS2("Kernel Section");
Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
if (!NT_SUCCESS(Status))
{
@@ -1582,11 +1629,15 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
(Offset >= PAGE_ROUND_UP(Segment->RawLength) && Section->AllocationAttributes & SEC_IMAGE))
{
+ MI_SET_USAGE(MI_USAGE_SECTION);
+ if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+ if (!Process) MI_SET_PROCESS2("Kernel Section");
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
if (!NT_SUCCESS(Status))
{
DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status);
}
+
}
else
{
@@ -1624,7 +1675,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
if (Entry != Entry1)
{
DPRINT1("Someone changed ppte entry while we slept\n");
- KeBugCheck(MEMORY_MANAGEMENT);
+ KeBugCheck(MEMORY_MANAGEMENT);
}
/*
@@ -1664,7 +1715,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
MmUnlockSectionSegment(Segment);
MmUnlockAddressSpace(AddressSpace);
-
+ MI_SET_USAGE(MI_USAGE_SECTION);
+ if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+ if (!Process) MI_SET_PROCESS2("Kernel Section");
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
if (!NT_SUCCESS(Status))
{
@@ -1872,6 +1925,9 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
/*
* Allocate a page
*/
+ MI_SET_USAGE(MI_USAGE_SECTION);
+ if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+ if (!Process) MI_SET_PROCESS2("Kernel Section");
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage);
if (!NT_SUCCESS(Status))
{
@@ -2151,7 +2207,11 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
Address);
KeBugCheck(MEMORY_MANAGEMENT);
}
+#ifndef NEWCC
Status = CcRosUnmapCacheSegment(Bcb, FileOffset, FALSE);
+#else
+ Status = STATUS_SUCCESS;
+#endif
if (!NT_SUCCESS(Status))
{
DPRINT1("CCRosUnmapCacheSegment failed, status = %x\n", Status);
@@ -2429,7 +2489,9 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
if (DirectMapped && !Private)
{
ASSERT(SwapEntry == 0);
+#ifndef NEWCC
CcRosMarkDirtyCacheSegment(Bcb, Offset + Segment->FileOffset);
+#endif
PageOp->Status = STATUS_SUCCESS;
MmspCompleteAndReleasePageOp(PageOp);
return(STATUS_SUCCESS);
@@ -2717,7 +2779,9 @@ MmpDeleteSection(PVOID ObjectBody)
}
if (Section->FileObject != NULL)
{
+#ifndef NEWCC
CcRosDereferenceCache(Section->FileObject);
+#endif
ObDereferenceObject(Section->FileObject);
Section->FileObject = NULL;
}
@@ -3122,7 +3186,9 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
MmUnlockSectionSegment(Segment);
Section->FileObject = FileObject;
Section->MaximumSize = MaximumSize;
+#ifndef NEWCC
CcRosReferenceCache(FileObject);
+#endif
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
*SectionObject = Section;
return(STATUS_SUCCESS);
@@ -3853,11 +3919,15 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
Section->SectionPageProtection = SectionPageProtection;
Section->AllocationAttributes = AllocationAttributes;
+#ifndef NEWCC
/*
* Initialized caching for this file object if previously caching
* was initialized for the same on disk file
*/
Status = CcTryToInitializeFileCache(FileObject);
+#else
+ Status = STATUS_SUCCESS;
+#endif
if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL)
{
@@ -3950,7 +4020,9 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
Status = STATUS_SUCCESS;
}
Section->FileObject = FileObject;
+#ifndef NEWCC
CcRosReferenceCache(FileObject);
+#endif
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
*SectionObject = Section;
return(Status);
@@ -4062,7 +4134,9 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
{
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+#ifndef NEWCC
CcRosMarkDirtyCacheSegment(Bcb, Offset + Segment->FileOffset);
+#endif
ASSERT(SwapEntry == 0);
}
}
@@ -4749,7 +4823,9 @@ MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
{
return FALSE;
}
+#ifndef NEWCC
CcRosSetRemoveOnClose(SectionObjectPointer);
+#endif
return TRUE;
case MmFlushForWrite:
break;
@@ -4902,7 +4978,7 @@ MmCreateSection (OUT PVOID * Section,
PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
/* Check if an ARM3 section is being created instead */
- if (AllocationAttributes & 0xC0000000)
+ if (AllocationAttributes & 1)
{
DPRINT1("arm 3 path\n");
return MmCreateArm3Section(Section,
@@ -4910,7 +4986,7 @@ MmCreateSection (OUT PVOID * Section,
ObjectAttributes,
MaximumSize,
SectionPageProtection,
- AllocationAttributes &~ 0xC0000000,
+ AllocationAttributes &~ 1,
FileHandle,
File);
}
diff --git a/ntoskrnl/ntoskrnl-generic.rbuild b/ntoskrnl/ntoskrnl-generic.rbuild
index 74fdf0b4531..6056698c2b2 100644
--- a/ntoskrnl/ntoskrnl-generic.rbuild
+++ b/ntoskrnl/ntoskrnl-generic.rbuild
@@ -14,6 +14,9 @@
+
+
+
.
include
@@ -130,14 +133,35 @@
timerobj.c
wait.c
-
+
+
cacheman.c
copy.c
fs.c
mdl.c
pin.c
view.c
-
+
+
+
+
+ cachesub.c
+ copysup.c
+ fssup.c
+ lazyrite.c
+ logsup.c
+ mdlsup.c
+ pinsup.c
+
+ data.c
+ fault.c
+ io.c
+ reqtools.c
+ sptab.c
+ swapout.c
+
+
+
diff --git a/ntoskrnl/ntoskrnl.pspec b/ntoskrnl/ntoskrnl.pspec
index cc7415b4439..1c65cc24145 100644
--- a/ntoskrnl/ntoskrnl.pspec
+++ b/ntoskrnl/ntoskrnl.pspec
@@ -112,7 +112,7 @@
@ FASTCALL ExInterlockedAddLargeStatistic(ptr long)
#endif
@ stdcall ExInterlockedAddUlong(ptr long ptr)
-#ifndef __x86_64__
+#ifdef __x86__
@ FASTCALL ExInterlockedCompareExchange64(ptr ptr ptr ptr)
@ stdcall ExInterlockedDecrementLong(ptr ptr)
@ stdcall ExInterlockedExchangeUlong(ptr long ptr)
@@ -454,6 +454,7 @@
@ stdcall IoInitializeTimer(ptr ptr ptr)
@ stdcall IoInvalidateDeviceRelations(ptr long)
@ stdcall IoInvalidateDeviceState(ptr)
+@ stdcall -arch=x86_64 IoIs32bitProcess(ptr)
@ stdcall IoIsFileOriginRemote(ptr)
@ stdcall IoIsOperationSynchronous(ptr)
@ stdcall IoIsSystemThread(ptr)
@@ -533,6 +534,7 @@
@ stdcall IoVolumeDeviceToDosName(ptr ptr)
@ stdcall IoWMIAllocateInstanceIds(ptr long ptr)
@ stdcall IoWMIDeviceObjectToInstanceName(ptr ptr ptr)
+@ stdcall -arch=x86_64 IoWMIDeviceObjectToProviderId(ptr)
@ stdcall IoWMIExecuteMethod(ptr ptr long long ptr ptr)
@ stdcall IoWMIHandleToInstanceName(ptr ptr ptr)
@ stdcall IoWMIOpenBlock(ptr long ptr)
diff --git a/ntoskrnl/ntoskrnl_i386.lnk b/ntoskrnl/ntoskrnl_i386.lnk
index c759babe6b9..788cda743c1 100644
--- a/ntoskrnl/ntoskrnl_i386.lnk
+++ b/ntoskrnl/ntoskrnl_i386.lnk
@@ -19,12 +19,6 @@ SECTIONS
*(.gcc_exc)
__text_end__ = .;
*(.gcc_except_table)
- }
- init BLOCK(__section_alignment__) :
- {
- __init_start__ = . ;
- *(init)
- __init_end__ = . ;
}
/* The Cygwin32 library uses a section to avoid copying certain data
on fork. This used to be named ".data". The linker used
@@ -101,5 +95,11 @@ SECTIONS
{
[ .stabstr ]
}
+ INIT BLOCK(__section_alignment__) :
+ {
+ __init_start__ = . ;
+ *(INIT)
+ __init_end__ = . ;
+ }
}
diff --git a/ntoskrnl/ob/obname.c b/ntoskrnl/ob/obname.c
index c97d4cea5be..a514af7b195 100644
--- a/ntoskrnl/ob/obname.c
+++ b/ntoskrnl/ob/obname.c
@@ -33,6 +33,7 @@ UNICODE_STRING ObpDosDevicesShortName =
NTSTATUS
NTAPI
+INIT_FUNCTION
ObpCreateDosDevicesDirectory(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
diff --git a/ntoskrnl/ob/obsdcach.c b/ntoskrnl/ob/obsdcach.c
index 8e51d967622..1e8f9dad198 100644
--- a/ntoskrnl/ob/obsdcach.c
+++ b/ntoskrnl/ob/obsdcach.c
@@ -57,6 +57,7 @@ ObpSdReleaseLockShared(IN POB_SD_CACHE_LIST CacheEntry)
NTSTATUS
NTAPI
+INIT_FUNCTION
ObpInitSdCache(VOID)
{
ULONG i;
diff --git a/ntoskrnl/po/poshtdwn.c b/ntoskrnl/po/poshtdwn.c
index dd5113e1bb3..919ffd4eefb 100644
--- a/ntoskrnl/po/poshtdwn.c
+++ b/ntoskrnl/po/poshtdwn.c
@@ -9,6 +9,9 @@
/* INCLUDES ******************************************************************/
#include
+#ifdef NEWCC
+#include "../cache/newcc.h"
+#endif
#define NDEBUG
#include
@@ -154,6 +157,10 @@ PopGracefulShutdown(IN PVOID Context)
IoShutdownSystem(1);
CcWaitForCurrentLazyWriterActivity();
+#ifdef NEWCC
+ CcShutdownSystem();
+#endif
+
/* Note that here, we should broadcast the power IRP to devices */
/* In this step, the HAL disables any wake timers */
diff --git a/ntoskrnl/po/power.c b/ntoskrnl/po/power.c
index a163b98bc48..a4f45c0f38c 100644
--- a/ntoskrnl/po/power.c
+++ b/ntoskrnl/po/power.c
@@ -9,6 +9,7 @@
/* INCLUDES ******************************************************************/
+#include "initguid.h"
#include
#define NDEBUG
#include
@@ -127,6 +128,7 @@ PopSetSystemPowerState(SYSTEM_POWER_STATE PowerState)
BOOLEAN
NTAPI
+INIT_FUNCTION
PoInitSystem(IN ULONG BootPhase)
{
PVOID NotificationEntry;
@@ -216,6 +218,7 @@ PopIdle0(IN PPROCESSOR_POWER_STATE PowerState)
VOID
NTAPI
+INIT_FUNCTION
PoInitializePrcb(IN PKPRCB Prcb)
{
/* Initialize the Power State */
@@ -744,8 +747,12 @@ NtSetSystemPowerState(IN POWER_ACTION SystemAction,
/* Check if we're still in an invalid status */
if (!NT_SUCCESS(Status)) break;
+#ifndef NEWCC
/* Flush dirty cache pages */
CcRosFlushDirtyPages(-1, &Dummy);
+#else
+ Dummy = 0;
+#endif
/* Flush all volumes and the registry */
DPRINT1("Flushing volumes, cache flushed %d pages\n", Dummy);
diff --git a/ntoskrnl/ps/job.c b/ntoskrnl/ps/job.c
index 52f4f2715be..7bded05b5ef 100644
--- a/ntoskrnl/ps/job.c
+++ b/ntoskrnl/ps/job.c
@@ -72,6 +72,7 @@ PspDeleteJob ( PVOID ObjectBody )
VOID
NTAPI
+INIT_FUNCTION
PspInitializeJobStructures(VOID)
{
InitializeListHead(&PsJobListHead);
diff --git a/ntoskrnl/ps/kill.c b/ntoskrnl/ps/kill.c
index b1ea95fb361..7efbc761ad7 100644
--- a/ntoskrnl/ps/kill.c
+++ b/ntoskrnl/ps/kill.c
@@ -1012,6 +1012,13 @@ PspTerminateThreadByPointer(IN PETHREAD Thread,
return Status;
}
+BOOLEAN
+NTAPI
+PspIsProcessExiting(IN PEPROCESS Process)
+{
+ return Process->Flags & PSF_PROCESS_EXITING_BIT;
+}
+
VOID
NTAPI
PspExitProcess(IN BOOLEAN LastThread,
diff --git a/ntoskrnl/ps/process.c b/ntoskrnl/ps/process.c
index 0c557c3699e..01f9a77b17a 100644
--- a/ntoskrnl/ps/process.c
+++ b/ntoskrnl/ps/process.c
@@ -669,6 +669,13 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
}
}
+#if MI_TRACE_PFNS
+ /* Copy the process name now that we have it */
+ memcpy(MiGetPfnEntry(Process->Pcb.DirectoryTableBase[0] >> PAGE_SHIFT)->ProcessName, Process->ImageFileName, 16);
+ if (Process->Pcb.DirectoryTableBase[1]) memcpy(MiGetPfnEntry(Process->Pcb.DirectoryTableBase[1] >> PAGE_SHIFT)->ProcessName, Process->ImageFileName, 16);
+ if (Process->WorkingSetPage) memcpy(MiGetPfnEntry(Process->WorkingSetPage)->ProcessName, Process->ImageFileName, 16);
+#endif
+
/* Check if we have a section object and map the system DLL */
if (SectionObject) PspMapSystemDll(Process, NULL, FALSE);
diff --git a/ntoskrnl/ps/psmgr.c b/ntoskrnl/ps/psmgr.c
index dbc9a660cfc..156982ed565 100644
--- a/ntoskrnl/ps/psmgr.c
+++ b/ntoskrnl/ps/psmgr.c
@@ -65,6 +65,7 @@ BOOLEAN PspDoingGiveBacks;
USHORT
NTAPI
+INIT_FUNCTION
NameToOrdinal(IN PCHAR Name,
IN PVOID DllBase,
IN ULONG NumberOfNames,
@@ -107,6 +108,7 @@ NameToOrdinal(IN PCHAR Name,
NTSTATUS
NTAPI
+INIT_FUNCTION
LookupEntryPoint(IN PVOID DllBase,
IN PCHAR Name,
OUT PVOID *EntryPoint)
@@ -158,6 +160,7 @@ LookupEntryPoint(IN PVOID DllBase,
NTSTATUS
NTAPI
+INIT_FUNCTION
PspLookupSystemDllEntryPoint(IN PCHAR Name,
IN PVOID *EntryPoint)
{
@@ -167,6 +170,7 @@ PspLookupSystemDllEntryPoint(IN PCHAR Name,
NTSTATUS
NTAPI
+INIT_FUNCTION
PspLookupKernelUserEntryPoints(VOID)
{
NTSTATUS Status;
@@ -239,6 +243,7 @@ PspLookupKernelUserEntryPoints(VOID)
NTSTATUS
NTAPI
+INIT_FUNCTION
PspMapSystemDll(IN PEPROCESS Process,
IN PVOID *DllBase,
IN BOOLEAN UseLargePages)
@@ -272,6 +277,7 @@ PspMapSystemDll(IN PEPROCESS Process,
NTSTATUS
NTAPI
+INIT_FUNCTION
PsLocateSystemDll(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
@@ -357,6 +363,7 @@ PsLocateSystemDll(VOID)
NTSTATUS
NTAPI
+INIT_FUNCTION
PspInitializeSystemDll(VOID)
{
NTSTATUS Status;
@@ -389,6 +396,7 @@ PspInitializeSystemDll(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
PspInitPhase1()
{
/* Initialize the System DLL and return status of operation */
@@ -398,6 +406,7 @@ PspInitPhase1()
BOOLEAN
NTAPI
+INIT_FUNCTION
PspInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
NTSTATUS Status;
@@ -616,6 +625,7 @@ PspInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
BOOLEAN
NTAPI
+INIT_FUNCTION
PsInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
/* Check the initialization phase */
diff --git a/ntoskrnl/ps/quota.c b/ntoskrnl/ps/quota.c
index 772ae7e6bcf..8814104c147 100644
--- a/ntoskrnl/ps/quota.c
+++ b/ntoskrnl/ps/quota.c
@@ -98,6 +98,7 @@ PspReturnProcessQuotaSpecifiedPool(IN PEPROCESS Process,
VOID
NTAPI
+INIT_FUNCTION
PsInitializeQuotaSystem(VOID)
{
RtlZeroMemory(&PspDefaultQuotaBlock, sizeof(PspDefaultQuotaBlock));
diff --git a/ntoskrnl/rtl/i386/stack.S b/ntoskrnl/rtl/i386/stack.S
index d71cc4f0c3e..7fbb6e0106a 100644
--- a/ntoskrnl/rtl/i386/stack.S
+++ b/ntoskrnl/rtl/i386/stack.S
@@ -8,13 +8,13 @@
/* INCLUDES ******************************************************************/
-#include
-.intel_syntax noprefix
+#include
+#include
/* FUNCTIONS *****************************************************************/
+.code
-.func RtlpGetStackLimits@8
-.globl _RtlpGetStackLimits@8
+PUBLIC _RtlpGetStackLimits@8
_RtlpGetStackLimits@8:
/* Get the current thread */
@@ -34,4 +34,5 @@ _RtlpGetStackLimits@8:
/* return */
ret 8
-.endfunc
+
+END
diff --git a/ntoskrnl/se/semgr.c b/ntoskrnl/se/semgr.c
index 406003b0af9..2795f01e0c8 100644
--- a/ntoskrnl/se/semgr.c
+++ b/ntoskrnl/se/semgr.c
@@ -86,6 +86,7 @@ SepInitExports(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
SepInitializationPhase0(VOID)
{
PAGED_CODE();
@@ -117,6 +118,7 @@ SepInitializationPhase0(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
SepInitializationPhase1(VOID)
{
NTSTATUS Status;
@@ -139,6 +141,7 @@ SepInitializationPhase1(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
SeInitSystem(VOID)
{
/* Check the initialization phase */
@@ -168,6 +171,7 @@ SeInitSystem(VOID)
BOOLEAN
NTAPI
+INIT_FUNCTION
SeInitSRM(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
diff --git a/ntoskrnl/vdm/vdmmain.c b/ntoskrnl/vdm/vdmmain.c
index c7aa0a2500d..e9136599791 100644
--- a/ntoskrnl/vdm/vdmmain.c
+++ b/ntoskrnl/vdm/vdmmain.c
@@ -15,11 +15,11 @@
/* GLOBALS *******************************************************************/
-
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
+INIT_FUNCTION
Ki386VdmEnablePentiumExtentions(IN BOOLEAN Enable)
{
ULONG EFlags, Cr4;
@@ -38,6 +38,7 @@ Ki386VdmEnablePentiumExtentions(IN BOOLEAN Enable)
VOID
NTAPI
+INIT_FUNCTION
KeI386VdmInitialize(VOID)
{
NTSTATUS Status;
@@ -84,6 +85,7 @@ KeI386VdmInitialize(VOID)
NTSTATUS
NTAPI
+INIT_FUNCTION
VdmpInitialize(PVOID ControlData)
{
OBJECT_ATTRIBUTES ObjectAttributes;
diff --git a/subsystems/win32/csrss/win32csr/desktopbg.c b/subsystems/win32/csrss/win32csr/desktopbg.c
index 1853ab6cc21..14a6155fb00 100644
--- a/subsystems/win32/csrss/win32csr/desktopbg.c
+++ b/subsystems/win32/csrss/win32csr/desktopbg.c
@@ -68,6 +68,10 @@ DtbgWindowProc(HWND Wnd,
case WM_CLOSE:
return 0;
+ case WM_DISPLAYCHANGE:
+ MoveWindow(Wnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
+ break;
+
case WM_NOTIFY:
{
PPRIVATE_NOTIFY_DESKTOP nmh = (PPRIVATE_NOTIFY_DESKTOP)lParam;
diff --git a/subsystems/win32/csrss/win32csr/win32csr.rbuild b/subsystems/win32/csrss/win32csr/win32csr.rbuild
index c6d4843abea..0764763980c 100644
--- a/subsystems/win32/csrss/win32csr/win32csr.rbuild
+++ b/subsystems/win32/csrss/win32csr/win32csr.rbuild
@@ -9,9 +9,10 @@
.
-fms-extensions
ntdll
- user32
- gdi32
- advapi32
+ user32
+ gdi32
+ advapi32
+ delayimp
win32ksys
psapi
pseh
diff --git a/subsystems/win32/win32k/dib/alphablend.c b/subsystems/win32/win32k/dib/alphablend.c
new file mode 100644
index 00000000000..be269cf5c37
--- /dev/null
+++ b/subsystems/win32/win32k/dib/alphablend.c
@@ -0,0 +1,123 @@
+/*
+ * PROJECT: Win32 subsystem
+ * LICENSE: See COPYING in the top level directory
+ * FILE: subsystems/win32/win32k/dib/stretchblt.c
+ * PURPOSE: AlphaBlend implementation suitable for all bit depths
+ * PROGRAMMERS: Jérôme Gardou
+ */
+
+#include
+
+#define NDEBUG
+#include
+
+typedef union
+{
+ ULONG ul;
+ struct
+ {
+ UCHAR red;
+ UCHAR green;
+ UCHAR blue;
+ UCHAR alpha;
+ } col;
+} NICEPIXEL32;
+
+static __inline UCHAR
+Clamp8(ULONG val)
+{
+ return (val > 255) ? 255 : val;
+}
+
+BOOLEAN
+DIB_XXBPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+ RECTL* SourceRect, CLIPOBJ* ClipRegion,
+ XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+ INT DstX, DstY, SrcX, SrcY;
+ BLENDFUNCTION BlendFunc;
+ register NICEPIXEL32 DstPixel32;
+ register NICEPIXEL32 SrcPixel32;
+ UCHAR Alpha, SrcBpp = BitsPerFormat(Source->iBitmapFormat);
+ EXLATEOBJ* pexlo;
+ EXLATEOBJ exloSrcRGB, exloDstRGB, exloRGBSrc;
+ PFN_DIB_PutPixel pfnDibPutPixel = DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel;
+
+ DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
+ SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
+ DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
+
+ BlendFunc = BlendObj->BlendFunction;
+ if (BlendFunc.BlendOp != AC_SRC_OVER)
+ {
+ DPRINT1("BlendOp != AC_SRC_OVER\n");
+ return FALSE;
+ }
+ if (BlendFunc.BlendFlags != 0)
+ {
+ DPRINT1("BlendFlags != 0\n");
+ return FALSE;
+ }
+ if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
+ {
+ DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
+ return FALSE;
+ }
+ if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
+ SrcBpp != 32)
+ {
+ DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
+ return FALSE;
+ }
+
+ if (!ColorTranslation)
+ {
+ DPRINT1("ColorTranslation must not be NULL!\n");
+ return FALSE;
+ }
+
+ pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo);
+ EXLATEOBJ_vInitialize(&exloSrcRGB, pexlo->ppalSrc, &gpalRGB, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exloDstRGB, pexlo->ppalDst, &gpalRGB, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exloRGBSrc, &gpalRGB, pexlo->ppalSrc, 0, 0, 0);
+
+ SrcY = SourceRect->top;
+ DstY = DestRect->top;
+ while ( DstY < DestRect->bottom )
+ {
+ SrcX = SourceRect->left;
+ DstX = DestRect->left;
+ while(DstX < DestRect->right)
+ {
+ SrcPixel32.ul = DIB_GetSource(Source, SrcX, SrcY, &exloSrcRGB.xlo);
+ SrcPixel32.col.red = (SrcPixel32.col.red * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel32.col.green = (SrcPixel32.col.green * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel32.col.blue = (SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha) / 255;
+
+ Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
+ (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha) / 255 :
+ BlendFunc.SourceConstantAlpha ;
+
+ DstPixel32.ul = DIB_GetSource(Dest, DstX, DstY, &exloDstRGB.xlo);
+ DstPixel32.col.red = Clamp8((DstPixel32.col.red * (255 - Alpha)) / 255 + SrcPixel32.col.red) ;
+ DstPixel32.col.green = Clamp8((DstPixel32.col.green * (255 - Alpha)) / 255 + SrcPixel32.col.green) ;
+ DstPixel32.col.blue = Clamp8((DstPixel32.col.blue * (255 - Alpha)) / 255 + SrcPixel32.col.blue) ;
+ DstPixel32.ul = XLATEOBJ_iXlate(&exloRGBSrc.xlo, DstPixel32.ul);
+ pfnDibPutPixel(Dest, DstX, DstY, XLATEOBJ_iXlate(ColorTranslation, DstPixel32.ul));
+
+ DstX++;
+ SrcX = SourceRect->left + ((DstX-DestRect->left)*(SourceRect->right - SourceRect->left))
+ /(DestRect->right-DestRect->left);
+ }
+ DstY++;
+ SrcY = SourceRect->top + ((DstY-DestRect->top)*(SourceRect->bottom - SourceRect->top))
+ /(DestRect->bottom-DestRect->top);
+ }
+
+ EXLATEOBJ_vCleanup(&exloDstRGB);
+ EXLATEOBJ_vCleanup(&exloRGBSrc);
+ EXLATEOBJ_vCleanup(&exloSrcRGB);
+
+ return TRUE;
+}
+
diff --git a/subsystems/win32/win32k/dib/dib.c b/subsystems/win32/win32k/dib/dib.c
index 30591d3d27d..2066c9e0b72 100644
--- a/subsystems/win32/win32k/dib/dib.c
+++ b/subsystems/win32/win32k/dib/dib.c
@@ -29,25 +29,25 @@ DIB_FUNCTIONS DibFunctionsForBitmapFormat[] =
{
DIB_1BPP_PutPixel, DIB_1BPP_GetPixel, DIB_1BPP_HLine, DIB_1BPP_VLine,
DIB_1BPP_BitBlt, DIB_1BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
- DIB_1BPP_TransparentBlt, DIB_1BPP_ColorFill, DIB_1BPP_AlphaBlend
+ DIB_1BPP_TransparentBlt, DIB_1BPP_ColorFill, DIB_XXBPP_AlphaBlend
},
/* BMF_4BPP */
{
DIB_4BPP_PutPixel, DIB_4BPP_GetPixel, DIB_4BPP_HLine, DIB_4BPP_VLine,
DIB_4BPP_BitBlt, DIB_4BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
- DIB_4BPP_TransparentBlt, DIB_4BPP_ColorFill, DIB_4BPP_AlphaBlend
+ DIB_4BPP_TransparentBlt, DIB_4BPP_ColorFill, DIB_XXBPP_AlphaBlend
},
/* BMF_8BPP */
{
DIB_8BPP_PutPixel, DIB_8BPP_GetPixel, DIB_8BPP_HLine, DIB_8BPP_VLine,
DIB_8BPP_BitBlt, DIB_8BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
- DIB_8BPP_TransparentBlt, DIB_8BPP_ColorFill, DIB_8BPP_AlphaBlend
+ DIB_8BPP_TransparentBlt, DIB_8BPP_ColorFill, DIB_XXBPP_AlphaBlend
},
/* BMF_16BPP */
{
DIB_16BPP_PutPixel, DIB_16BPP_GetPixel, DIB_16BPP_HLine, DIB_16BPP_VLine,
DIB_16BPP_BitBlt, DIB_16BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
- DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_16BPP_AlphaBlend
+ DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_XXBPP_AlphaBlend
},
/* BMF_24BPP */
{
diff --git a/subsystems/win32/win32k/dib/dib.h b/subsystems/win32/win32k/dib/dib.h
index bae2199fe59..4ae455bc92b 100644
--- a/subsystems/win32/win32k/dib/dib.h
+++ b/subsystems/win32/win32k/dib/dib.h
@@ -78,7 +78,6 @@ BOOLEAN DIB_1BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_1BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_1BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
-BOOLEAN DIB_1BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
VOID DIB_4BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
ULONG DIB_4BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -88,7 +87,6 @@ BOOLEAN DIB_4BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_4BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_4BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
-BOOLEAN DIB_4BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
VOID DIB_8BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
ULONG DIB_8BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -98,7 +96,6 @@ BOOLEAN DIB_8BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_8BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_8BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
-BOOLEAN DIB_8BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
VOID DIB_16BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
ULONG DIB_16BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -108,7 +105,6 @@ BOOLEAN DIB_16BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_16BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_16BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
-BOOLEAN DIB_16BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
VOID DIB_24BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
ULONG DIB_24BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -132,6 +128,7 @@ BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATE
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,ROP4);
BOOLEAN DIB_XXBPP_FloodFillSolid(SURFOBJ*, BRUSHOBJ*, RECTL*, POINTL*, ULONG, UINT);
+BOOLEAN DIB_XXBPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
extern unsigned char notmask[2];
extern unsigned char altnotmask[2];
diff --git a/subsystems/win32/win32k/dib/dib16bpp.c b/subsystems/win32/win32k/dib/dib16bpp.c
index de569716586..a1d72ae7251 100644
--- a/subsystems/win32/win32k/dib/dib16bpp.c
+++ b/subsystems/win32/win32k/dib/dib16bpp.c
@@ -525,174 +525,4 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
return TRUE;
}
-typedef union
-{
- ULONG ul;
- struct
- {
- UCHAR red;
- UCHAR green;
- UCHAR blue;
- UCHAR alpha;
- } col;
-} NICEPIXEL32;
-
-typedef union
-{
- USHORT us;
- struct
- {
- USHORT red:5,
- green:6,
- blue:5;
- } col;
-} NICEPIXEL16;
-
-static __inline UCHAR
-Clamp5(ULONG val)
-{
- return (val > 31) ? 31 : val;
-}
-
-static __inline UCHAR
-Clamp8(ULONG val)
-{
- return (val > 255) ? 255 : val;
-}
-
-static __inline UCHAR
-Clamp6(ULONG val)
-{
- return (val > 63) ? 63 : val;
-}
-
-BOOLEAN
-DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
- RECTL* SourceRect, CLIPOBJ* ClipRegion,
- XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
-{
- INT Rows, Cols, SrcX, SrcY;
- register PUSHORT Dst;
- ULONG DstDelta;
- BLENDFUNCTION BlendFunc;
- register NICEPIXEL16 SrcPixel16;
- register NICEPIXEL16 DstPixel16;
- register NICEPIXEL32 SrcPixel32;
- register NICEPIXEL32 DstPixel32;
- UCHAR Alpha, SrcBpp;
- EXLATEOBJ *pexlo;
- EXLATEOBJ exloDst2Src;
-
- DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
- SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
- DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
-
- ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
- DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
-
- BlendFunc = BlendObj->BlendFunction;
- if (BlendFunc.BlendOp != AC_SRC_OVER)
- {
- DPRINT1("BlendOp != AC_SRC_OVER\n");
- return FALSE;
- }
- if (BlendFunc.BlendFlags != 0)
- {
- DPRINT1("BlendFlags != 0\n");
- return FALSE;
- }
- if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
- {
- DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
- return FALSE;
- }
- if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
- BitsPerFormat(Source->iBitmapFormat) != 32)
- {
- DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
- return FALSE;
- }
-
- if (!ColorTranslation)
- {
- DPRINT1("ColorTranslation must not be NULL!\n");
- return FALSE;
- }
-
- pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo);
- EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0);
-
- Dst = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
- (DestRect->left << 1));
- DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 1);
- SrcBpp = BitsPerFormat(Source->iBitmapFormat);
-
- Rows = DestRect->bottom - DestRect->top;
- SrcY = SourceRect->top;
- while (--Rows >= 0)
- {
- Cols = DestRect->right - DestRect->left;
- SrcX = SourceRect->left;
- while (--Cols >= 0)
- {
- if (SrcBpp <= 16)
- {
- SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
- SrcPixel32.col.red = (SrcPixel16.col.red << 3);
- SrcPixel32.col.green = (SrcPixel16.col.green << 2);
- SrcPixel32.col.blue = (SrcPixel16.col.blue << 3);
-
- SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.alpha = (SrcBpp == 32) ?
- (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) :
- BlendFunc.SourceConstantAlpha;
-
- Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
-
- DstPixel16.us = *Dst;
- DstPixel16.col.red = Clamp5(DstPixel16.col.red * (255 - Alpha) / 255 +
- (SrcPixel32.col.red >> 3));
-
- DstPixel16.col.green = Clamp6(DstPixel16.col.green * (255 - Alpha) / 255 +
- (SrcPixel32.col.green >> 2));
-
- DstPixel16.col.blue = Clamp5(DstPixel16.col.blue * (255 - Alpha) / 255 +
- (SrcPixel32.col.blue >> 3));
-
- *Dst++ = DstPixel16.us;
- }
- else
- {
- SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
-
- SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.alpha = (SrcBpp == 32) ?
- (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) :
- BlendFunc.SourceConstantAlpha;
-
- Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
-
- DstPixel32.ul = XLATEOBJ_iXlate(&exloDst2Src.xlo, *Dst);
- SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red);
- SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green);
- SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue);
- *Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul);
- }
- }
-
- Dst = (PUSHORT)((ULONG_PTR)Dst + DstDelta);
- SrcY++;
- }
-
- EXLATEOBJ_vCleanup(&exloDst2Src);
-
- return TRUE;
-}
-
/* EOF */
diff --git a/subsystems/win32/win32k/dib/dib1bpp.c b/subsystems/win32/win32k/dib/dib1bpp.c
index 3686754e5dd..b924112351c 100644
--- a/subsystems/win32/win32k/dib/dib1bpp.c
+++ b/subsystems/win32/win32k/dib/dib1bpp.c
@@ -33,7 +33,7 @@ DIB_1BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
VOID
DIB_1BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
{
- while(x1 < x2)
+ while(x1 < x2)
{
DIB_1BPP_PutPixel(SurfObj, x1, y, c);
x1++;
@@ -43,7 +43,7 @@ DIB_1BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
VOID
DIB_1BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
{
- while(y1 < y2)
+ while(y1 < y2)
{
DIB_1BPP_PutPixel(SurfObj, x, y1, c);
y1++;
@@ -474,13 +474,4 @@ DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
return FALSE;
}
-BOOLEAN
-DIB_1BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
- RECTL* SourceRect, CLIPOBJ* ClipRegion,
- XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
/* EOF */
diff --git a/subsystems/win32/win32k/dib/dib24bpp.c b/subsystems/win32/win32k/dib/dib24bpp.c
index 3810024a6f8..0642862b0b1 100644
--- a/subsystems/win32/win32k/dib/dib24bpp.c
+++ b/subsystems/win32/win32k/dib/dib24bpp.c
@@ -37,7 +37,7 @@ DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
LONG lDelta = SurfObj->lDelta;
c &= 0xFFFFFF;
- while(y1++ < y2)
+ while(y1++ < y2)
{
*(PUSHORT)(addr) = c & 0xFFFF;
*(addr + 2) = c >> 16;
@@ -466,7 +466,6 @@ DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
{
INT Rows, Cols, SrcX, SrcY;
register PUCHAR Dst;
- ULONG DstDelta;
BLENDFUNCTION BlendFunc;
register NICEPIXEL32 DstPixel, SrcPixel;
UCHAR Alpha, SrcBpp;
@@ -475,9 +474,6 @@ DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
- ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
- DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
-
BlendFunc = BlendObj->BlendFunction;
if (BlendFunc.BlendOp != AC_SRC_OVER)
{
@@ -503,39 +499,41 @@ DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
(DestRect->left * 3));
- DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) * 3);
SrcBpp = BitsPerFormat(Source->iBitmapFormat);
- Rows = DestRect->bottom - DestRect->top;
+ Rows = 0;
SrcY = SourceRect->top;
- while (--Rows >= 0)
- {
- Cols = DestRect->right - DestRect->left;
- SrcX = SourceRect->left;
- while (--Cols >= 0)
+ while (++Rows <= DestRect->bottom - DestRect->top)
+ {
+ Cols = 0;
+ SrcX = SourceRect->left;
+ while (++Cols <= DestRect->right - DestRect->left)
+ {
+ SrcPixel.ul = DIB_GetSource(Source, SrcX, SrcY, ColorTranslation);
+ SrcPixel.col.red = (SrcPixel.col.red * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.green = (SrcPixel.col.green * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.blue = (SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255;
+ if (!(BlendFunc.AlphaFormat & AC_SRC_ALPHA))
{
- SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
- SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
-
- Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
-
- /* copy only 24bits of dst */
- DstPixel.ul = *(PUSHORT)(Dst) + (*(Dst+2) << 16);
- DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
- DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
- DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
- /* copy back 24bits of result */
- *(PUSHORT)(Dst) = (USHORT)(DstPixel.ul & 0xFFFF);
- *(Dst + 2) = (UCHAR)((DstPixel.ul >> 16) & 0xFF);
- Dst = (PUCHAR)((ULONG_PTR)Dst + 3);
+ Alpha = BlendFunc.SourceConstantAlpha ;
}
- Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
- SrcY++;
- }
+ else
+ {
+ Alpha = (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha) / 255;
+ }
+
+ DstPixel.col.red = Clamp8((*Dst * (255 - Alpha)) / 255 + SrcPixel.col.red) ;
+ DstPixel.col.green = Clamp8((*(Dst+1) * (255 - Alpha) / 255 + SrcPixel.col.green)) ;
+ DstPixel.col.blue = Clamp8((*(Dst+2) * (255 - Alpha)) / 255 + SrcPixel.col.blue) ;
+ *Dst++ = DstPixel.col.red;
+ *Dst++ = DstPixel.col.green;
+ *Dst++ = DstPixel.col.blue;
+ SrcX = SourceRect->left + (Cols*(SourceRect->right - SourceRect->left))/(DestRect->right - DestRect->left);
+ }
+ Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + ((DestRect->top + Rows) * Dest->lDelta) +
+ (DestRect->left*3));
+ SrcY = SourceRect->top + (Rows*(SourceRect->bottom - SourceRect->top))/(DestRect->bottom - DestRect->top);
+ }
return TRUE;
}
diff --git a/subsystems/win32/win32k/dib/dib32bpp.c b/subsystems/win32/win32k/dib/dib32bpp.c
index 6c4704b1c96..50c819380ce 100644
--- a/subsystems/win32/win32k/dib/dib32bpp.c
+++ b/subsystems/win32/win32k/dib/dib32bpp.c
@@ -54,8 +54,8 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
PBYTE SourceBits_4BPP, SourceLine_4BPP;
PDWORD Source32, Dest32;
- DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
- + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta)
+ DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
+ + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta)
+ 4 * BltInfo->DestRect.left;
switch (BltInfo->SourceSurface->iBitmapFormat)
@@ -83,8 +83,8 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
break;
case BMF_4BPP:
- SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0
- + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
+ SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0
+ + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
+ (BltInfo->SourcePoint.x >> 1);
for (j=BltInfo->DestRect.top; jDestRect.bottom; j++)
@@ -156,8 +156,8 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
break;
case BMF_24BPP:
- SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0
- + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
+ SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0
+ + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
+ 3 * BltInfo->SourcePoint.x;
DestLine = DestBits;
@@ -182,7 +182,7 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
break;
case BMF_32BPP:
- if (NULL == BltInfo->XlateSourceToDest ||
+ if (NULL == BltInfo->XlateSourceToDest ||
0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
{
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
@@ -197,10 +197,10 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
}
else
{
- SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
- + ((BltInfo->SourcePoint.y
- + BltInfo->DestRect.bottom
- - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta)
+ SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
+ + ((BltInfo->SourcePoint.y
+ + BltInfo->DestRect.bottom
+ - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta)
+ 4 * BltInfo->SourcePoint.x;
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
@@ -348,7 +348,6 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
{
INT Rows, Cols, SrcX, SrcY;
register PULONG Dst;
- ULONG DstDelta;
BLENDFUNCTION BlendFunc;
register NICEPIXEL32 DstPixel, SrcPixel;
UCHAR Alpha, SrcBpp;
@@ -357,9 +356,6 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
- ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
- DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
-
BlendFunc = BlendObj->BlendFunction;
if (BlendFunc.BlendOp != AC_SRC_OVER)
{
@@ -385,35 +381,38 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
Dst = (PULONG)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
(DestRect->left << 2));
- DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 2);
SrcBpp = BitsPerFormat(Source->iBitmapFormat);
- Rows = DestRect->bottom - DestRect->top;
- SrcY = SourceRect->top;
- while (--Rows >= 0)
+ Rows = 0;
+ SrcY = SourceRect->top;
+ while (++Rows <= DestRect->bottom - DestRect->top)
{
- Cols = DestRect->right - DestRect->left;
+ Cols = 0;
SrcX = SourceRect->left;
- while (--Cols >= 0)
+ while (++Cols <= DestRect->right - DestRect->left)
{
- SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
- SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
+ SrcPixel.ul = DIB_GetSource(Source, SrcX, SrcY, ColorTranslation);
+ SrcPixel.col.red = (SrcPixel.col.red * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.green = (SrcPixel.col.green * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.blue = (SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.alpha = (32 == SrcBpp) ?
+ (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha) / 255 :
+ BlendFunc.SourceConstantAlpha ;
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
+ SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha ;
DstPixel.ul = *Dst;
- DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
- DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
- DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
- DstPixel.col.alpha = Clamp8(DstPixel.col.alpha * (255 - Alpha) / 255 + SrcPixel.col.alpha);
+ DstPixel.col.red = Clamp8((DstPixel.col.red * (255 - Alpha)) / 255 + SrcPixel.col.red) ;
+ DstPixel.col.green = Clamp8((DstPixel.col.green * (255 - Alpha)) / 255 + SrcPixel.col.green) ;
+ DstPixel.col.blue = Clamp8((DstPixel.col.blue * (255 - Alpha)) / 255 + SrcPixel.col.blue) ;
+ DstPixel.col.alpha = Clamp8((DstPixel.col.alpha * (255 - Alpha)) / 255 + SrcPixel.col.alpha) ;
*Dst++ = DstPixel.ul;
+ SrcX = SourceRect->left + (Cols*(SourceRect->right - SourceRect->left))/(DestRect->right - DestRect->left);
}
- Dst = (PULONG)((ULONG_PTR)Dst + DstDelta);
- SrcY++;
+ Dst = (PULONG)((ULONG_PTR)Dest->pvScan0 + ((DestRect->top + Rows) * Dest->lDelta) +
+ (DestRect->left << 2));
+ SrcY = SourceRect->top + (Rows*(SourceRect->bottom - SourceRect->top))/(DestRect->bottom - DestRect->top);
}
return TRUE;
diff --git a/subsystems/win32/win32k/dib/dib4bpp.c b/subsystems/win32/win32k/dib/dib4bpp.c
index 1626b8e8397..e27c2264b70 100644
--- a/subsystems/win32/win32k/dib/dib4bpp.c
+++ b/subsystems/win32/win32k/dib/dib4bpp.c
@@ -32,7 +32,7 @@ DIB_4BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
PBYTE addr = (PBYTE)SurfObj->pvScan0 + (x1>>1) + y * SurfObj->lDelta;
LONG cx = x1;
- while(cx < x2)
+ while(cx < x2)
{
*addr = (*addr & notmask[x1&1]) | (c << ((1-(x1&1))<<2));
if((++x1 & 1) == 0)
@@ -48,7 +48,7 @@ DIB_4BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
int lDelta = SurfObj->lDelta;
addr += (x>>1) + y1 * lDelta;
- while(y1++ < y2)
+ while(y1++ < y2)
{
*addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2));
addr += lDelta;
@@ -81,8 +81,8 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
{
DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
- }
- else
+ }
+ else
{
DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
}
@@ -375,13 +375,4 @@ DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
return FALSE;
}
-BOOLEAN
-DIB_4BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
- RECTL* SourceRect, CLIPOBJ* ClipRegion,
- XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
/* EOF */
diff --git a/subsystems/win32/win32k/dib/dib8bpp.c b/subsystems/win32/win32k/dib/dib8bpp.c
index 3fac604f5c4..e13331c8042 100644
--- a/subsystems/win32/win32k/dib/dib8bpp.c
+++ b/subsystems/win32/win32k/dib/dib8bpp.c
@@ -43,7 +43,7 @@ DIB_8BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
LONG lDelta = SurfObj->lDelta;
byteaddr = addr;
- while(y1++ < y2)
+ while(y1++ < y2)
{
*addr = c;
@@ -74,8 +74,8 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
{
DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
- }
- else
+ }
+ else
{
DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
}
@@ -362,130 +362,4 @@ DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
return TRUE;
}
-typedef union {
- ULONG ul;
- struct {
- UCHAR red;
- UCHAR green;
- UCHAR blue;
- UCHAR alpha;
- } col;
-} NICEPIXEL32;
-
-typedef union {
- USHORT us;
- struct {
- USHORT red:5,
- green:6,
- blue:5;
- } col;
-} NICEPIXEL16;
-
-static __inline UCHAR
-Clamp8(ULONG val)
-{
- return (val > 255) ? 255 : val;
-}
-
-BOOLEAN
-DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
- RECTL* SourceRect, CLIPOBJ* ClipRegion,
- XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
-{
- INT Rows, Cols, SrcX, SrcY;
- register PUCHAR Dst;
- ULONG DstDelta;
- BLENDFUNCTION BlendFunc;
- register NICEPIXEL32 DstPixel32;
- register NICEPIXEL32 SrcPixel32;
- register NICEPIXEL16 SrcPixel16;
- UCHAR Alpha, SrcBpp;
- EXLATEOBJ exloDst2Src;
- EXLATEOBJ* pexlo;
-
- DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
- SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
- DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
-
- ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
- DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
-
- BlendFunc = BlendObj->BlendFunction;
- if (BlendFunc.BlendOp != AC_SRC_OVER)
- {
- DPRINT1("BlendOp != AC_SRC_OVER\n");
- return FALSE;
- }
- if (BlendFunc.BlendFlags != 0)
- {
- DPRINT1("BlendFlags != 0\n");
- return FALSE;
- }
- if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
- {
- DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
- return FALSE;
- }
- if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
- BitsPerFormat(Source->iBitmapFormat) != 32)
- {
- DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
- return FALSE;
- }
- if (!ColorTranslation)
- {
- DPRINT1("ColorTranslation must not be NULL!\n");
- return FALSE;
- }
-
- pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo);
- EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0);
-
- Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
- DestRect->left);
- DstDelta = Dest->lDelta - (DestRect->right - DestRect->left);
- SrcBpp = BitsPerFormat(Source->iBitmapFormat);
-
- Rows = DestRect->bottom - DestRect->top;
- SrcY = SourceRect->top;
- while (--Rows >= 0)
- {
- Cols = DestRect->right - DestRect->left;
- SrcX = SourceRect->left;
- while (--Cols >= 0)
- {
- if (SrcBpp <= 16)
- {
- SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
- SrcPixel32.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2);
- SrcPixel32.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4);
- SrcPixel32.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2);
- }
- else
- {
- SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
- }
- SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.alpha = (SrcBpp == 32) ? (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
-
- Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
-
- DstPixel32.ul = XLATEOBJ_iXlate(&exloDst2Src.xlo, *Dst);
- SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red);
- SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green);
- SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue);
- *Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul);
- }
- Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
- SrcY++;
- }
-
- EXLATEOBJ_vCleanup(&exloDst2Src);
-
- return TRUE;
-}
-
/* EOF */
diff --git a/subsystems/win32/win32k/dib/i386/dib24bpp_hline.s b/subsystems/win32/win32k/dib/i386/dib24bpp_hline.s
index 24451140f7c..1d36aa4bb9c 100644
--- a/subsystems/win32/win32k/dib/i386/dib24bpp_hline.s
+++ b/subsystems/win32/win32k/dib/i386/dib24bpp_hline.s
@@ -6,13 +6,12 @@
* PROGRAMMERS: Magnus Olsen
*/
-.globl _DIB_24BPP_HLine
-.intel_syntax noprefix
+#include
+
+.code
+
+PUBLIC _DIB_24BPP_HLine
-.def _DIB_24BPP_HLine;
-.scl 2;
-.type 32;
-.endef
_DIB_24BPP_HLine:
push edi
push esi
@@ -151,3 +150,5 @@
pop esi
pop edi
ret
+
+END
diff --git a/subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.s b/subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.s
index fce9f7f84c0..00a83804a73 100644
--- a/subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.s
+++ b/subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.s
@@ -7,15 +7,16 @@
* Timo Kreuzer (timo.kreuzer@reactos.org)
*/
-.intel_syntax noprefix
+#include
+.code
/*
* BOOLEAN
* _cdecl
* DIB_32BPP_ColorFill(SURFOBJ* pso, RECTL* prcl, ULONG iColor);
*/
-.globl _DIB_32BPP_ColorFill
+PUBLIC _DIB_32BPP_ColorFill
_DIB_32BPP_ColorFill:
push ebp
mov ebp, esp
@@ -27,22 +28,22 @@ _DIB_32BPP_ColorFill:
mov edx, [ebp+12] /* edx = prcl */
mov ecx, [ebp+8] /* ecx = pso */
- mov ebx, [ecx+0x24] /* ebx = pso->lDelta; */
+ mov ebx, [ecx+36] /* ebx = pso->lDelta; */
mov [esp], ebx /* lDelta = pso->lDelta; */
mov edi, [edx+4] /* edi = prcl->top; */
mov eax, edi /* eax = prcl->top; */
imul eax, ebx /* eax = prcl->top * pso->lDelta; */
- add eax, [ecx+0x20] /* eax += pso->pvScan0; */
+ add eax, [ecx+32] /* eax += pso->pvScan0; */
mov ebx, [edx] /* ebx = prcl->left; */
lea esi, [eax+ebx*4] /* esi = pvLine0 = eax + 4 * prcl->left; */
mov ebx, [edx+8] /* ebx = prcl->right; */
sub ebx, [edx] /* ebx = prcl->right - prcl->left; */
- jbe end /* if (ebx <= 0) goto end; */
+ jbe .end /* if (ebx <= 0) goto end; */
mov edx, [edx+12] /* edx = prcl->bottom; */
sub edx, edi /* edx -= prcl->top; */
- jbe end /* if (eax <= 0) goto end; */
+ jbe .end /* if (eax <= 0) goto end; */
mov eax, [ebp+16] /* eax = iColor; */
cld
@@ -55,7 +56,7 @@ for_loop: /* do { */
dec edx /* cy--; */
jnz for_loop /* } while (cy > 0); */
-end:
+.end:
mov eax, 1
add esp, 4
pop edi
@@ -63,3 +64,5 @@ end:
pop ebx
pop ebp
ret
+
+END
diff --git a/subsystems/win32/win32k/dib/i386/dib32bpp_hline.s b/subsystems/win32/win32k/dib/i386/dib32bpp_hline.s
index f976b8741bf..c60d43d6343 100644
--- a/subsystems/win32/win32k/dib/i386/dib32bpp_hline.s
+++ b/subsystems/win32/win32k/dib/i386/dib32bpp_hline.s
@@ -6,13 +6,11 @@
* PROGRAMMERS: Magnus Olsen
*/
-.globl _DIB_32BPP_HLine
-.intel_syntax noprefix
+#include
-.def _DIB_32BPP_HLine;
-.scl 2;
-.type 32;
-.endef
+.code
+
+PUBLIC _DIB_32BPP_HLine
_DIB_32BPP_HLine:
sub esp, 12 // rember the base is not hex it is dec
@@ -55,3 +53,4 @@ _save_rest:
add esp, 12
ret
+END
diff --git a/subsystems/win32/win32k/eng/alphablend.c b/subsystems/win32/win32k/eng/alphablend.c
index 34b2930cd68..afd1b5e5f54 100644
--- a/subsystems/win32/win32k/eng/alphablend.c
+++ b/subsystems/win32/win32k/eng/alphablend.c
@@ -1,4 +1,4 @@
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI alpha blending functions
@@ -25,10 +25,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
IN PRECTL SourceRect,
IN BLENDOBJ *BlendObj)
{
- RECTL SourceStretchedRect;
- SIZEL SourceStretchedSize;
- HBITMAP SourceStretchedBitmap = 0;
- SURFOBJ* SourceStretchedObj = NULL;
RECTL InputRect;
RECTL OutputRect;
RECTL ClipRect;
@@ -39,7 +35,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
INTENG_ENTER_LEAVE EnterLeaveDest;
SURFOBJ* InputObj;
SURFOBJ* OutputObj;
- LONG Width;
LONG ClippingType;
RECT_ENUM RectEnum;
BOOL EnumMore;
@@ -71,7 +66,7 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
InputRect = *SourceRect;
if ( (InputRect.top < 0) || (InputRect.bottom < 0) ||
(InputRect.left < 0) || (InputRect.right < 0) ||
- InputRect.right > psoSource->sizlBitmap.cx ||
+ InputRect.right > psoSource->sizlBitmap.cx ||
InputRect.bottom > psoSource->sizlBitmap.cy )
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
@@ -111,68 +106,9 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
return TRUE;
}
- /* Stretch source if needed */
- if (OutputRect.right - OutputRect.left != InputRect.right - InputRect.left ||
- OutputRect.bottom - OutputRect.top != InputRect.bottom - InputRect.top)
- {
- SourceStretchedSize.cx = OutputRect.right - OutputRect.left;
- SourceStretchedSize.cy = OutputRect.bottom - OutputRect.top;
- Width = DIB_GetDIBWidthBytes(SourceStretchedSize.cx, BitsPerFormat(psoSource->iBitmapFormat));
- /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and IntEngStretchBlt
- if possible to get a HW accelerated stretch. */
- SourceStretchedBitmap = EngCreateBitmap(SourceStretchedSize, Width, psoSource->iBitmapFormat,
- BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
- if (SourceStretchedBitmap == 0)
- {
- DPRINT1("EngCreateBitmap failed!\n");
- return FALSE;
- }
- SourceStretchedObj = EngLockSurface((HSURF)SourceStretchedBitmap);
- if (SourceStretchedObj == NULL)
- {
- DPRINT1("EngLockSurface failed!\n");
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- return FALSE;
- }
-
- SourceStretchedRect.left = 0;
- SourceStretchedRect.right = SourceStretchedSize.cx;
- SourceStretchedRect.top = 0;
- SourceStretchedRect.bottom = SourceStretchedSize.cy;
- /* FIXME: IntEngStretchBlt isn't used here atm because it results in a
- try to acquire an already acquired mutex (lock the already locked source surface) */
- /*if (!IntEngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL,
- NULL, &SourceStretchedRect, SourceRect, NULL,
- NULL, NULL, COLORONCOLOR))*/
- if (!EngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL, NULL,
- NULL, NULL, &SourceStretchedRect, &InputRect,
- NULL, COLORONCOLOR))
- {
- DPRINT1("EngStretchBlt failed!\n");
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- return FALSE;
- }
- InputRect.top = SourceStretchedRect.top;
- InputRect.bottom = SourceStretchedRect.bottom;
- InputRect.left = SourceStretchedRect.left;
- InputRect.right = SourceStretchedRect.right;
- psoSource = SourceStretchedObj;
- }
-
/* Now call the DIB function */
if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj))
{
- if (SourceStretchedObj != NULL)
- {
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- }
- if (SourceStretchedBitmap != 0)
- {
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- }
return FALSE;
}
InputRect.left += Translate.x;
@@ -182,16 +118,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj))
{
- IntEngLeave(&EnterLeaveSource);
- if (SourceStretchedObj != NULL)
- {
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- }
- if (SourceStretchedBitmap != 0)
- {
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- }
return FALSE;
}
OutputRect.left += Translate.x;
@@ -261,16 +187,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
- if (SourceStretchedObj != NULL)
- {
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- }
- if (SourceStretchedBitmap != 0)
- {
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- }
-
return Ret;
}
@@ -305,17 +221,8 @@ IntEngAlphaBlend(IN SURFOBJ *psoDest,
return TRUE;
}
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, DestRect->left, DestRect->top,
- DestRect->right, DestRect->bottom);
-
- if (psoSource != psoDest)
- SURFACE_LockBitmapBits(psurfSource);
- MouseSafetyOnDrawStart(psoSource, SourceRect->left, SourceRect->top,
- SourceRect->right, SourceRect->bottom);
-
/* Call the driver's DrvAlphaBlend if available */
- if (psurfDest->flHooks & HOOK_ALPHABLEND)
+ if (psurfDest->flags & HOOK_ALPHABLEND)
{
ret = GDIDEVFUNCS(psoDest).AlphaBlend(
psoDest, psoSource, ClipRegion, ColorTranslation,
@@ -328,12 +235,6 @@ IntEngAlphaBlend(IN SURFOBJ *psoDest,
DestRect, SourceRect, BlendObj);
}
- MouseSafetyOnDrawEnd(psoSource);
- if (psoSource != psoDest)
- SURFACE_UnlockBitmapBits(psurfSource);
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
-
return ret;
}
diff --git a/subsystems/win32/win32k/eng/bitblt.c b/subsystems/win32/win32k/eng/bitblt.c
index b74e890cfd0..3525a2caf2a 100644
--- a/subsystems/win32/win32k/eng/bitblt.c
+++ b/subsystems/win32/win32k/eng/bitblt.c
@@ -370,6 +370,7 @@ EngBitBlt(SURFOBJ *DestObj,
}
else
{
+ InputPoint.x = InputPoint.y = 0;
InputRect.left = 0;
InputRect.right = DestRect->right - DestRect->left;
InputRect.top = 0;
@@ -522,7 +523,7 @@ EngBitBlt(SURFOBJ *DestObj,
}
BOOL APIENTRY
-IntEngBitBltEx(
+IntEngBitBlt(
SURFOBJ *psoTrg,
SURFOBJ *psoSrc,
SURFOBJ *psoMask,
@@ -533,8 +534,7 @@ IntEngBitBltEx(
POINTL *pptlMask,
BRUSHOBJ *pbo,
POINTL *pptlBrush,
- ROP4 rop4,
- BOOL bRemoveMouse)
+ ROP4 rop4)
{
SURFACE *psurfTrg;
SURFACE *psurfSrc = NULL;
@@ -583,28 +583,11 @@ IntEngBitBltEx(
psurfSrc = NULL;
}
- if (bRemoveMouse)
- {
- SURFACE_LockBitmapBits(psurfTrg);
-
- if (psoSrc)
- {
- if (psoSrc != psoTrg)
- {
- SURFACE_LockBitmapBits(psurfSrc);
- }
- MouseSafetyOnDrawStart(psoSrc, rclSrc.left, rclSrc.top,
- rclSrc.right, rclSrc.bottom);
- }
- MouseSafetyOnDrawStart(psoTrg, rclClipped.left, rclClipped.top,
- rclClipped.right, rclClipped.bottom);
- }
-
/* Is the target surface device managed? */
- if (psurfTrg->flHooks & HOOK_BITBLT)
+ if (psurfTrg->flags & HOOK_BITBLT)
{
/* Is the source a different device managed surface? */
- if (psoSrc && psoSrc->hdev != psoTrg->hdev && psurfSrc->flHooks & HOOK_BITBLT)
+ if (psoSrc && psoSrc->hdev != psoTrg->hdev && psurfSrc->flags & HOOK_BITBLT)
{
DPRINT1("Need to copy to standard bitmap format!\n");
ASSERT(FALSE);
@@ -614,7 +597,7 @@ IntEngBitBltEx(
}
/* Is the source surface device managed? */
- else if (psoSrc && psurfSrc->flHooks & HOOK_BITBLT)
+ else if (psoSrc && psurfSrc->flags & HOOK_BITBLT)
{
pfnBitBlt = GDIDEVFUNCS(psoSrc).BitBlt;
}
@@ -637,21 +620,6 @@ IntEngBitBltEx(
// FIXME: cleanup temp surface!
- if (bRemoveMouse)
- {
- MouseSafetyOnDrawEnd(psoTrg);
- if (psoSrc)
- {
- MouseSafetyOnDrawEnd(psoSrc);
- if (psoSrc != psoTrg)
- {
- SURFACE_UnlockBitmapBits(psurfSrc);
- }
- }
-
- SURFACE_UnlockBitmapBits(psurfTrg);
- }
-
return bResult;
}
@@ -983,27 +951,20 @@ IntEngMaskBlt(SURFOBJ *psoDest,
ASSERT(psoDest);
psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
-
/* Dummy BitBlt to let driver know that it should flush its changes.
This should really be done using a call to DrvSynchronizeSurface,
but the VMware driver doesn't hook that call. */
- IntEngBitBltEx(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
+ IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
- R4_NOOP, FALSE);
+ R4_NOOP);
ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation, SourceColorTranslation,
&OutputRect, &InputPoint, pbo, BrushOrigin);
/* Dummy BitBlt to let driver know that something has changed. */
- IntEngBitBltEx(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
+ IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
- R4_NOOP, FALSE);
-
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
+ R4_NOOP);
return ret;
}
diff --git a/subsystems/win32/win32k/eng/copybits.c b/subsystems/win32/win32k/eng/copybits.c
index 73a477dd13d..afb2f16cc99 100644
--- a/subsystems/win32/win32k/eng/copybits.c
+++ b/subsystems/win32/win32k/eng/copybits.c
@@ -53,13 +53,7 @@ EngCopyBits(SURFOBJ *psoDest,
ASSERT(psoDest != NULL && psoSource != NULL && DestRect != NULL && SourcePoint != NULL);
psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
- SURFACE_LockBitmapBits(psurfSource);
-
psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
- if (psoDest != psoSource)
- {
- SURFACE_LockBitmapBits(psurfDest);
- }
// FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
// mark the copy block function to be DrvCopyBits instead of the
@@ -73,7 +67,7 @@ EngCopyBits(SURFOBJ *psoDest,
if (psoDest->iType!=STYPE_BITMAP)
{
/* FIXME: Eng* functions shouldn't call Drv* functions. ? */
- if (psurfDest->flHooks & HOOK_COPYBITS)
+ if (psurfDest->flags & HOOK_COPYBITS)
{
ret = GDIDEVFUNCS(psoDest).CopyBits(
psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
@@ -86,7 +80,7 @@ EngCopyBits(SURFOBJ *psoDest,
if (psoSource->iType!=STYPE_BITMAP)
{
/* FIXME: Eng* functions shouldn't call Drv* functions. ? */
- if (psurfSource->flHooks & HOOK_COPYBITS)
+ if (psurfSource->flags & HOOK_COPYBITS)
{
ret = GDIDEVFUNCS(psoSource).CopyBits(
psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
@@ -180,12 +174,6 @@ EngCopyBits(SURFOBJ *psoDest,
}
cleanup:
- if (psoDest != psoSource)
- {
- SURFACE_UnlockBitmapBits(psurfDest);
- }
- SURFACE_UnlockBitmapBits(psurfSource);
-
return ret;
}
@@ -198,20 +186,7 @@ IntEngCopyBits(
RECTL *prclDest,
POINTL *ptlSource)
{
- BOOL bResult;
-
- MouseSafetyOnDrawStart(psoSource, ptlSource->x, ptlSource->y,
- (ptlSource->x + abs(prclDest->right - prclDest->left)),
- (ptlSource->y + abs(prclDest->bottom - prclDest->top)));
-
- MouseSafetyOnDrawStart(psoDest, prclDest->left, prclDest->top, prclDest->right, prclDest->bottom);
-
- bResult = EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
-
- MouseSafetyOnDrawEnd(psoDest);
- MouseSafetyOnDrawEnd(psoSource);
-
- return bResult;
+ return EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
}
diff --git a/subsystems/win32/win32k/eng/device.c b/subsystems/win32/win32k/eng/device.c
index 0e51ea05eef..730b2ffaa3a 100644
--- a/subsystems/win32/win32k/eng/device.c
+++ b/subsystems/win32/win32k/eng/device.c
@@ -12,6 +12,265 @@
#define NDEBUG
#include
+PGRAPHICS_DEVICE gpPrimaryGraphicsDevice;
+PGRAPHICS_DEVICE gpVgaGraphicsDevice;
+
+static PGRAPHICS_DEVICE gpGraphicsDeviceFirst = NULL;
+static PGRAPHICS_DEVICE gpGraphicsDeviceLast = NULL;
+static HSEMAPHORE ghsemGraphicsDeviceList;
+static ULONG giDevNum = 1;
+
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitDeviceImpl()
+{
+ ghsemGraphicsDeviceList = EngCreateSemaphore();
+ if (!ghsemGraphicsDeviceList)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ return STATUS_SUCCESS;
+}
+
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpRegisterGraphicsDevice(
+ PUNICODE_STRING pustrDeviceName,
+ PUNICODE_STRING pustrDiplayDrivers,
+ PUNICODE_STRING pustrDescription,
+ PDEVMODEW pdmDefault)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PDEVICE_OBJECT pDeviceObject;
+ PFILE_OBJECT pFileObject;
+ NTSTATUS Status;
+ PWSTR pwsz;
+ ULONG i, cj, cModes = 0;
+ BOOL bEnable = TRUE;
+ PDEVMODEINFO pdminfo;
+ PDEVMODEW pdm, pdmEnd;
+ PLDEVOBJ pldev;
+
+ DPRINT("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName);
+
+ /* Allocate a GRAPHICS_DEVICE structure */
+ pGraphicsDevice = ExAllocatePoolWithTag(PagedPool,
+ sizeof(GRAPHICS_DEVICE),
+ GDITAG_GDEVICE);
+ if (!pGraphicsDevice)
+ {
+ DPRINT1("ExAllocatePoolWithTag failed\n");
+ return NULL;
+ }
+
+ /* Try to open the driver */
+ Status = IoGetDeviceObjectPointer(pustrDeviceName,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ &pFileObject,
+ &pDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not open driver %wZ, 0x%lx\n", pustrDeviceName, Status);
+ ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
+ return NULL;
+ }
+
+ /* Enable the device */
+ EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cj);
+
+ /* Copy the device and file object pointers */
+ pGraphicsDevice->DeviceObject = pDeviceObject;
+ pGraphicsDevice->FileObject = pFileObject;
+
+ /* Copy device name */
+ wcsncpy(pGraphicsDevice->szNtDeviceName,
+ pustrDeviceName->Buffer,
+ sizeof(pGraphicsDevice->szNtDeviceName) / sizeof(WCHAR));
+
+ /* Create a win device name (FIXME: virtual devices!) */
+ swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (CHAR)giDevNum);
+
+ /* Allocate a buffer for the strings */
+ cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR);
+ pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP);
+ if (!pwsz)
+ {
+ DPRINT1("Could not allocate string buffer\n");
+ ASSERT(FALSE); // FIXME
+ }
+
+ /* Copy display driver names */
+ pGraphicsDevice->pDiplayDrivers = pwsz;
+ RtlCopyMemory(pGraphicsDevice->pDiplayDrivers,
+ pustrDiplayDrivers->Buffer,
+ pustrDiplayDrivers->Length);
+
+ /* Copy description */
+ pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR);
+ RtlCopyMemory(pGraphicsDevice->pwszDescription,
+ pustrDescription->Buffer,
+ pustrDescription->Length + sizeof(WCHAR));
+
+ /* Initialize the pdevmodeInfo list and default index */
+ pGraphicsDevice->pdevmodeInfo = NULL;
+ pGraphicsDevice->iDefaultMode = 0;
+ pGraphicsDevice->iCurrentMode = 0;
+
+ // FIXME: initialize state flags
+ pGraphicsDevice->StateFlags = 0;
+
+ /* Loop through the driver names
+ * This is a REG_MULTI_SZ string */
+ for (; *pwsz; pwsz += wcslen(pwsz) + 1)
+ {
+ DPRINT1("trying driver: %ls\n", pwsz);
+ /* Try to load the display driver */
+ pldev = EngLoadImageEx(pwsz, LDEV_DEVICE_DISPLAY);
+ if (!pldev)
+ {
+ DPRINT1("Could not load driver: '%ls'\n", pwsz);
+ continue;
+ }
+
+ /* Get the mode list from the driver */
+ pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject);
+ if (!pdminfo)
+ {
+ DPRINT1("Could not get mode list for '%ls'\n", pwsz);
+ continue;
+ }
+
+ /* Attach the mode info to the device */
+ pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
+ pGraphicsDevice->pdevmodeInfo = pdminfo;
+
+ /* Count DEVMODEs */
+ pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
+ for (pdm = pdminfo->adevmode;
+ pdm + 1 <= pdmEnd;
+ pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
+ {
+ cModes++;
+ }
+
+ // FIXME: release the driver again until it's used?
+ }
+
+ if (!pGraphicsDevice->pdevmodeInfo || cModes == 0)
+ {
+ DPRINT1("No devmodes\n");
+ ExFreePool(pGraphicsDevice);
+ return NULL;
+ }
+
+ /* Allocate an index buffer */
+ pGraphicsDevice->cDevModes = cModes;
+ pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool,
+ cModes * sizeof(DEVMODEENTRY),
+ GDITAG_GDEVICE);
+ if (!pGraphicsDevice->pDevModeList)
+ {
+ DPRINT1("No devmode list\n");
+ ExFreePool(pGraphicsDevice);
+ return NULL;
+ }
+
+ /* Loop through all DEVMODEINFOs */
+ for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0;
+ pdminfo;
+ pdminfo = pdminfo->pdmiNext)
+ {
+ /* Calculate End of the DEVMODEs */
+ pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
+
+ /* Loop through the DEVMODEs */
+ for (pdm = pdminfo->adevmode;
+ pdm + 1 <= pdmEnd;
+ pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
+ {
+ /* Compare with the default entry */
+ if (pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel &&
+ pdm->dmPelsWidth == pdmDefault->dmPelsWidth &&
+ pdm->dmPelsHeight == pdmDefault->dmPelsHeight &&
+ pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency)
+ {
+ pGraphicsDevice->iDefaultMode = i;
+ pGraphicsDevice->iCurrentMode = i;
+ DPRINT1("Found default entry: %ld '%ls'\n", i, pdm->dmDeviceName);
+ }
+
+ /* Initialize the entry */
+ pGraphicsDevice->pDevModeList[i].dwFlags = 0;
+ pGraphicsDevice->pDevModeList[i].pdm = pdm;
+ i++;
+ }
+ }
+
+ /* Lock loader */
+ EngAcquireSemaphore(ghsemGraphicsDeviceList);
+
+ /* Insert the device into the global list */
+ pGraphicsDevice->pNextGraphicsDevice = gpGraphicsDeviceLast;
+ gpGraphicsDeviceLast = pGraphicsDevice;
+ if (!gpGraphicsDeviceFirst)
+ gpGraphicsDeviceFirst = pGraphicsDevice;
+
+ /* Increment device number */
+ giDevNum++;
+
+ /* Unlock loader */
+ EngReleaseSemaphore(ghsemGraphicsDeviceList);
+ DPRINT1("Prepared %ld modes for %ls\n", cModes, pGraphicsDevice->pwszDescription);
+
+ return pGraphicsDevice;
+}
+
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpFindGraphicsDevice(
+ PUNICODE_STRING pustrDevice,
+ ULONG iDevNum,
+ DWORD dwFlags)
+{
+ UNICODE_STRING ustrCurrent;
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ ULONG i;
+
+ /* Lock list */
+ EngAcquireSemaphore(ghsemGraphicsDeviceList);
+
+ if (pustrDevice)
+ {
+ /* Loop through the list of devices */
+ for (pGraphicsDevice = gpGraphicsDeviceFirst;
+ pGraphicsDevice;
+ pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice)
+ {
+ /* Compare the device name */
+ RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
+ if (RtlEqualUnicodeString(&ustrCurrent, pustrDevice, FALSE))
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* Loop through the list of devices */
+ for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
+ pGraphicsDevice && i < iDevNum;
+ pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++);
+ }
+
+ /* Unlock list */
+ EngReleaseSemaphore(ghsemGraphicsDeviceList);
+
+ return pGraphicsDevice;
+}
+
+
static
NTSTATUS
EngpFileIoRequest(
@@ -39,7 +298,7 @@ EngpFileIoRequest(
/* Initialize an event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
- /* Build IPR */
+ /* Build IRP */
liStartOffset.QuadPart = ullStartOffset;
pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction,
pDeviceObject,
@@ -113,7 +372,7 @@ EngFileIoControl(
/* Initialize an event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
- /* Build IO control IPR */
+ /* Build IO control IRP */
pIrp = IoBuildDeviceIoControlRequest(dwIoControlCode,
pDeviceObject,
lpInBuffer,
diff --git a/subsystems/win32/win32k/eng/engbrush.c b/subsystems/win32/win32k/eng/engbrush.c
index a13d11b5385..c61e0e47f9f 100644
--- a/subsystems/win32/win32k/eng/engbrush.c
+++ b/subsystems/win32/win32k/eng/engbrush.c
@@ -18,8 +18,6 @@ VOID
NTAPI
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
{
- HPALETTE hpal = NULL;
-
ASSERT(pebo);
ASSERT(pbrush);
ASSERT(pdc);
@@ -35,14 +33,11 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
pebo->crCurrentText = pdc->pdcattr->crForegroundClr;
pebo->psurfTrg = pdc->dclevel.pSurface;
-// ASSERT(pebo->psurfTrg); // FIXME: some dcs don't have a surface
+ ASSERT(pebo->psurfTrg);
+ ASSERT(pebo->psurfTrg->ppal);
- if (pebo->psurfTrg)
- hpal = pebo->psurfTrg->hDIBPalette;
- if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault;
- pebo->ppalSurf = PALETTE_ShareLockPalette(hpal);
- if (!pebo->ppalSurf)
- pebo->ppalSurf = &gpalRGB;
+ pebo->ppalSurf = pebo->psurfTrg->ppal;
+ GDIOBJ_IncrementShareCount(&pebo->ppalSurf->BaseObject);
if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
{
@@ -80,7 +75,12 @@ EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor)
pebo->ulRGBColor = crColor;
/* Initialize an XLATEOBJ RGB -> surface */
- EXLATEOBJ_vInitialize(&exlo, &gpalRGB, pebo->ppalSurf, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo,
+ &gpalRGB,
+ pebo->ppalSurf,
+ pebo->crCurrentBack,
+ 0,
+ 0);
/* Translate the brush color to the target format */
iSolidColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
@@ -109,8 +109,7 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
pebo->BrushObject.pvRbrush = NULL;
}
- if (pebo->ppalSurf != &gpalRGB)
- PALETTE_ShareUnlockPalette(pebo->ppalSurf);
+ PALETTE_ShareUnlockPalette(pebo->ppalSurf);
}
VOID
@@ -145,7 +144,7 @@ EngRealizeBrush(
ULONG lWidth;
/* Calculate width in bytes of the realized brush */
- lWidth = DIB_GetDIBWidthBytes(psoPattern->sizlBitmap.cx,
+ lWidth = WIDTH_BYTES_ALIGN32(psoPattern->sizlBitmap.cx,
BitsPerFormat(psoDst->iBitmapFormat));
/* Allocate a bitmap */
@@ -192,12 +191,8 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
PPDEVOBJ ppdev = NULL;
EXLATEOBJ exlo;
- // FIXME: all EBRUSHOBJs need a surface, see EBRUSHOBJ_vInit
- if (!pebo->psurfTrg)
- {
- DPRINT1("Pattern brush has no target surface!\n");
- return FALSE;
- }
+ /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */
+ ASSERT(pebo->psurfTrg);
ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev;
@@ -210,16 +205,18 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
psurfPattern = SURFACE_ShareLockSurface(pebo->pbrush->hbmPattern);
ASSERT(psurfPattern);
+ ASSERT(psurfPattern->ppal);
/* FIXME: implement mask */
psurfMask = NULL;
/* Initialize XLATEOBJ for the brush */
- EXLATEOBJ_vInitBrushXlate(&exlo,
- pebo->pbrush,
- pebo->psurfTrg,
- pebo->crCurrentText,
- pebo->crCurrentBack);
+ EXLATEOBJ_vInitialize(&exlo,
+ psurfPattern->ppal,
+ pebo->psurfTrg->ppal,
+ 0,
+ pebo->crCurrentBack,
+ pebo->crCurrentText);
/* Create the realization */
bResult = pfnRealzizeBrush(&pebo->BrushObject,
diff --git a/subsystems/win32/win32k/eng/engmisc.c b/subsystems/win32/win32k/eng/engmisc.c
index af544c95d55..31ea864dc9d 100644
--- a/subsystems/win32/win32k/eng/engmisc.c
+++ b/subsystems/win32/win32k/eng/engmisc.c
@@ -56,7 +56,7 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
{
/* Driver needs to support DrvCopyBits, else we can't do anything */
SURFACE *psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
- if (!(psurfDest->flHooks & HOOK_COPYBITS))
+ if (!(psurfDest->flags & HOOK_COPYBITS))
{
return FALSE;
}
@@ -64,7 +64,7 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
/* Allocate a temporary bitmap */
BitmapSize.cx = DestRect->right - DestRect->left;
BitmapSize.cy = DestRect->bottom - DestRect->top;
- Width = DIB_GetDIBWidthBytes(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat));
+ Width = WIDTH_BYTES_ALIGN32(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat));
EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width,
psoDest->iBitmapFormat,
BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
@@ -127,7 +127,6 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
&ClippedDestRect, &SrcPoint))
{
EngDeleteClip(EnterLeave->TrivialClipObj);
- EngFreeMem((*ppsoOutput)->pvBits);
EngUnlockSurface(*ppsoOutput);
EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
return FALSE;
@@ -149,7 +148,7 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
if (NULL != *ppsoOutput)
{
SURFACE* psurfOutput = CONTAINING_RECORD(*ppsoOutput, SURFACE, SurfObj);
- if (0 != (psurfOutput->flHooks & HOOK_SYNCHRONIZE))
+ if (0 != (psurfOutput->flags & HOOK_SYNCHRONIZE))
{
if (NULL != GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface)
{
@@ -219,7 +218,6 @@ IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave)
Result = TRUE;
}
}
- EngFreeMem(EnterLeave->OutputObj->pvBits);
EngUnlockSurface(EnterLeave->OutputObj);
EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
EngDeleteClip(EnterLeave->TrivialClipObj);
diff --git a/subsystems/win32/win32k/eng/gradient.c b/subsystems/win32/win32k/eng/gradient.c
index c3ef6535c04..75faeae5c33 100644
--- a/subsystems/win32/win32k/eng/gradient.c
+++ b/subsystems/win32/win32k/eng/gradient.c
@@ -548,14 +548,7 @@ IntEngGradientFill(
psurf = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
ASSERT(psurf);
- SURFACE_LockBitmapBits(psurf);
- MouseSafetyOnDrawStart(
- psoDest,
- pco->rclBounds.left,
- pco->rclBounds.top,
- pco->rclBounds.right,
- pco->rclBounds.bottom);
- if(psurf->flHooks & HOOK_GRADIENTFILL)
+ if(psurf->flags & HOOK_GRADIENTFILL)
{
Ret = GDIDEVFUNCS(psoDest).GradientFill(
psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh,
@@ -566,8 +559,6 @@ IntEngGradientFill(
Ret = EngGradientFill(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents,
pptlDitherOrg, ulMode);
}
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurf);
return Ret;
}
diff --git a/subsystems/win32/win32k/eng/i386/floatobj.S b/subsystems/win32/win32k/eng/i386/floatobj.S
index 6a9a3324729..c046bcfbeec 100644
--- a/subsystems/win32/win32k/eng/i386/floatobj.S
+++ b/subsystems/win32/win32k/eng/i386/floatobj.S
@@ -6,6 +6,9 @@
* PROGRAMMER: Timo Kreuzer
*/
+#include
+
+.code
/*******************************************************************************
* IEEE 754-1985 single precision floating point
@@ -72,9 +75,6 @@
* FLOATOBJ_SubLong - wrapper
*/
-.intel_syntax noprefix
-.text
-
#define lMant 0
#define lExp 4
@@ -87,24 +87,24 @@
* FLOATOBJ_SetFloat(IN OUT PFLOATOBJ pf, IN FLOATL f);
*/
_FLOATOBJ_SetFloat@8:
-.global _FLOATOBJ_SetFloat@8
+PUBLIC _FLOATOBJ_SetFloat@8
push ebp
mov ebp, esp
mov ecx, [esp + PARAM2] /* Load the float into ecx */
mov eax, ecx /* Copy float to eax for later */
- test ecx, 0x7f800000 /* Check for zero exponent - 0 or denormal */
+ test ecx, HEX(7f800000) /* Check for zero exponent - 0 or denormal */
jz SetFloat0 /* If it's all zero, ... */
shl ecx, 7 /* Put the bits for the mantissa in place */
cdq /* Fill edx with the sign from the FLOATL in eax */
- and ecx, 0x7fffffff /* Mask out invalid field in the mantissa */
+ and ecx, HEX(7fffffff) /* Mask out invalid field in the mantissa */
shr eax, 23 /* Shift the exponent in eax in place */
- or ecx, 0x40000000 /* Set bit for 1 in the mantissa */
- and eax, 0xff /* Mask out invalid fields in the exponent in eax */
+ or ecx, HEX(40000000) /* Set bit for 1 in the mantissa */
+ and eax, HEX(0ff) /* Mask out invalid fields in the exponent in eax */
xor ecx, edx /* Make use of the sign bit expanded to full edx */
@@ -136,7 +136,7 @@ SetFloat0:
*
*/
_FLOATOBJ_GetFloat@4:
-.global _FLOATOBJ_GetFloat@4
+PUBLIC _FLOATOBJ_GetFloat@4
push ebp
mov ebp, esp
@@ -152,13 +152,13 @@ _FLOATOBJ_GetFloat@4:
sub eax, edx
jz GetFloatRet
- and ecx, 0xff /* Mask out invalid fields in the exponent */
- and eax, 0x3fffffff /* Mask out invalid fields in mantissa */
+ and ecx, HEX(0ff) /* Mask out invalid fields in the exponent */
+ and eax, HEX(3fffffff) /* Mask out invalid fields in mantissa */
shl ecx, 23 /* Shift exponent in place */
shr eax, 7 /* Shift mantissa in place */
- and edx, 0x80000000 /* Reduce edx to sign bit only */
+ and edx, HEX(80000000) /* Reduce edx to sign bit only */
or eax, ecx /* Set exponent in result */
or eax, edx /* Set sign bit in result */
@@ -178,7 +178,7 @@ GetFloatRet:
* Instead of using abs(l), which is 3 + 2 instructions, use a branch.
*/
_FLOATOBJ_SetLong@8:
-.global _FLOATOBJ_SetLong@8
+PUBLIC _FLOATOBJ_SetLong@8
push ebp
mov ebp, esp
@@ -236,7 +236,7 @@ SetLong0:
*
*/
_FLOATOBJ_GetLong@4:
-.global _FLOATOBJ_GetLong@4
+PUBLIC _FLOATOBJ_GetLong@4
push ebp
mov ebp, esp
@@ -263,7 +263,7 @@ GetLong2:
* FLOATOBJ_Equal(IN PFLOATOBJ pf1, IN PFLOATOBJ pf2);
*/
_FLOATOBJ_Equal@8:
-.global _FLOATOBJ_Equal@8
+PUBLIC _FLOATOBJ_Equal@8
push ebp
mov ebp, esp
@@ -291,7 +291,7 @@ _FLOATOBJ_Equal@8:
* FLOATOBJ_EqualLong(IN PFLOATOBJ pf, IN LONG l);
*/
_FLOATOBJ_EqualLong@8:
-.global _FLOATOBJ_EqualLong@8
+PUBLIC _FLOATOBJ_EqualLong@8
push ebp
mov ebp, esp
@@ -325,7 +325,7 @@ EqualLongFalse:
*
*/
_FLOATOBJ_GreaterThan@8:
-.global _FLOATOBJ_GreaterThan@8
+PUBLIC _FLOATOBJ_GreaterThan@8
push ebp
mov ebp, esp
@@ -415,7 +415,7 @@ GreaterThan_neg2:
* LOATOBJ_GreaterThan
*/
_FLOATOBJ_GreaterThanLong@8:
-.global _FLOATOBJ_GreaterThanLong@8
+PUBLIC _FLOATOBJ_GreaterThanLong@8
push ebp
mov ebp, esp
@@ -445,7 +445,7 @@ _FLOATOBJ_GreaterThanLong@8:
*
*/
_FLOATOBJ_LessThan@8:
-.global _FLOATOBJ_LessThan@8
+PUBLIC _FLOATOBJ_LessThan@8
push ebp
mov ebp, esp
@@ -536,7 +536,7 @@ LessThan_neg2:
* Currently implemented as a wrapper around FLOATOBJ_SetLong and FLOATOBJ_LessThan
*/
_FLOATOBJ_LessThanLong@8:
-.global _FLOATOBJ_LessThanLong@8
+PUBLIC _FLOATOBJ_LessThanLong@8
push ebp
mov ebp, esp
@@ -569,7 +569,7 @@ _FLOATOBJ_LessThanLong@8:
* No special handling for 0, where mantissa is 0
*/
_FLOATOBJ_Mul@8:
-.global _FLOATOBJ_Mul@8
+PUBLIC _FLOATOBJ_Mul@8
push ebp
mov ebp, esp
@@ -620,7 +620,7 @@ MulNeg:
lea edx, [edx + ecx -2] /* Normalize exponent in edx */
- or eax, 0x80000000 /* Set sign bit */
+ or eax, HEX(80000000) /* Set sign bit */
mov ecx, [esp + PARAM1] /* Load pf1 into ecx */
mov [ecx + lMant], eax /* Save back mantissa */
@@ -646,7 +646,7 @@ Mul0:
* Currently implemented as a wrapper around FLOATOBJ_SetFloat and FLOATOBJ_Mul
*/
_FLOATOBJ_MulFloat@8:
-.global _FLOATOBJ_MulFloat@8
+PUBLIC _FLOATOBJ_MulFloat@8
push ebp
mov ebp, esp
@@ -675,7 +675,7 @@ _FLOATOBJ_MulFloat@8:
* Currently implemented as a wrapper around FLOATOBJ_SetLong and FLOATOBJ_Mul
*/
_FLOATOBJ_MulLong@8:
-.global _FLOATOBJ_MulLong@8
+PUBLIC _FLOATOBJ_MulLong@8
push ebp
mov ebp, esp
@@ -703,7 +703,7 @@ _FLOATOBJ_MulLong@8:
*
*/
_FLOATOBJ_Div@8:
-.global _FLOATOBJ_Div@8
+PUBLIC _FLOATOBJ_Div@8
push ebp
mov ebp, esp
push ebx
@@ -736,7 +736,7 @@ _FLOATOBJ_Div@8:
div ecx /* Do an unsigned divide */
xor ecx, ecx /* Adjust result */
- test eax, 0x80000000
+ test eax, HEX(80000000)
setnz cl
shr eax, cl
@@ -773,7 +773,7 @@ Div0:
* Currently implemented as a wrapper around FLOATOBJ_SetFloat and FLOATOBJ_Div
*/
_FLOATOBJ_DivFloat@8:
-.global _FLOATOBJ_DivFloat@8
+PUBLIC _FLOATOBJ_DivFloat@8
push ebp
mov ebp, esp
sub esp, 8 /* Make room for a FLOATOBJ on the stack */
@@ -802,7 +802,7 @@ _FLOATOBJ_DivFloat@8:
* Currently implemented as a wrapper around FLOATOBJ_SetLong and FLOATOBJ_Div
*/
_FLOATOBJ_DivLong@8:
-.global _FLOATOBJ_DivLong@8
+PUBLIC _FLOATOBJ_DivLong@8
push ebp
mov ebp, esp
sub esp, 8 /* Make room for a FLOATOBJ on the stack */
@@ -829,7 +829,7 @@ _FLOATOBJ_DivLong@8:
*
*/
_FLOATOBJ_Add@8:
-.global _FLOATOBJ_Add@8
+PUBLIC _FLOATOBJ_Add@8
push ebp
mov ebp, esp
push ebx
@@ -928,7 +928,7 @@ AddIs0:
* Currently implemented as a wrapper around FLOATOBJ_SetFloat and FLOATOBJ_Add
*/
_FLOATOBJ_AddFloat@8:
-.global _FLOATOBJ_AddFloat@8
+PUBLIC _FLOATOBJ_AddFloat@8
push ebp
mov ebp, esp
sub esp, 8 /* Make room for a FLOATOBJ on the stack */
@@ -957,7 +957,7 @@ _FLOATOBJ_AddFloat@8:
* Currently implemented as a wrapper around FLOATOBJ_SetLong and FLOATOBJ_Add
*/
_FLOATOBJ_AddLong@8:
-.global _FLOATOBJ_AddLong@8
+PUBLIC _FLOATOBJ_AddLong@8
push ebp
mov ebp, esp
sub esp, 8 /* Make room for a FLOATOBJ on the stack */
@@ -985,7 +985,7 @@ _FLOATOBJ_AddLong@8:
*
*/
_FLOATOBJ_Sub@8:
-.global _FLOATOBJ_Sub@8
+PUBLIC _FLOATOBJ_Sub@8
push ebp
mov ebp, esp
push ebx
@@ -1083,7 +1083,7 @@ SubIs0:
* Currently implemented as a wrapper around FLOATOBJ_SetFloat and FLOATOBJ_Sub
*/
_FLOATOBJ_SubFloat@8:
-.global _FLOATOBJ_SubFloat@8
+PUBLIC _FLOATOBJ_SubFloat@8
push ebp
mov ebp, esp
sub esp, 8 /* Make room for a FLOATOBJ on the stack */
@@ -1112,7 +1112,7 @@ _FLOATOBJ_SubFloat@8:
* Currently implemented as a wrapper around FLOATOBJ_SetLong and FLOATOBJ_Sub
*/
_FLOATOBJ_SubLong@8:
-.global _FLOATOBJ_SubLong@8
+PUBLIC _FLOATOBJ_SubLong@8
push ebp
mov ebp, esp
sub esp, 8 /* Make room for a FLOATOBJ on the stack */
@@ -1140,7 +1140,7 @@ _FLOATOBJ_SubLong@8:
*
*/
_FLOATOBJ_Neg@4:
-.global _FLOATOBJ_Neg@4
+PUBLIC _FLOATOBJ_Neg@4
push ebp
mov ebp, esp
@@ -1150,5 +1150,5 @@ _FLOATOBJ_Neg@4:
pop ebp /* Return */
ret 4
-
+END
/* EOF */
diff --git a/subsystems/win32/win32k/eng/ldevobj.c b/subsystems/win32/win32k/eng/ldevobj.c
new file mode 100644
index 00000000000..0e6c0eea540
--- /dev/null
+++ b/subsystems/win32/win32k/eng/ldevobj.c
@@ -0,0 +1,505 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Support for logical devices
+ * FILE: subsystems/win32/win32k/eng/ldevobj.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#include
+
+#include
+
+#define NDEBUG
+#include
+
+#ifndef RVA_TO_ADDR
+#define RVA_TO_ADDR(Base,Rva) ((PVOID)(((ULONG_PTR)(Base)) + (Rva)))
+#endif
+
+/** Globals *******************************************************************/
+
+HSEMAPHORE ghsemLDEVList;
+LDEVOBJ *gpldevHead = NULL;
+LDEVOBJ *gpldevWin32k = NULL;
+
+
+/** Private functions *********************************************************/
+
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitLDEVImpl()
+{
+ /* Initialize the loader lock */
+ ghsemLDEVList = EngCreateSemaphore();
+ if (!ghsemLDEVList)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Allocate a LDEVOBJ for win32k */
+ gpldevWin32k = ExAllocatePoolWithTag(PagedPool,
+ sizeof(LDEVOBJ) +
+ sizeof(SYSTEM_GDI_DRIVER_INFORMATION),
+ GDITAG_LDEV);
+ if (!gpldevWin32k)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Initialize the LDEVOBJ for win32k */
+ gpldevWin32k->pldevNext = NULL;
+ gpldevWin32k->pldevPrev = NULL;
+ gpldevWin32k->ldevtype = LDEV_DEVICE_DISPLAY;
+ gpldevWin32k->cRefs = 1;
+ gpldevWin32k->ulDriverVersion = GDI_ENGINE_VERSION;
+ gpldevWin32k->pGdiDriverInfo = (PVOID)(gpldevWin32k + 1);
+ RtlInitUnicodeString(&gpldevWin32k->pGdiDriverInfo->DriverName,
+ L"\\SystemRoot\\System32\\win32k.sys");
+ gpldevWin32k->pGdiDriverInfo->ImageAddress = &__ImageBase;
+ gpldevWin32k->pGdiDriverInfo->SectionPointer = NULL;
+ gpldevWin32k->pGdiDriverInfo->EntryPoint = (PVOID)DriverEntry;
+ gpldevWin32k->pGdiDriverInfo->ExportSectionPointer = NULL;
+ gpldevWin32k->pGdiDriverInfo->ImageLength = 0; // FIXME;
+
+ return STATUS_SUCCESS;
+}
+
+PLDEVOBJ
+NTAPI
+LDEVOBJ_AllocLDEV(LDEVTYPE ldevtype)
+{
+ PLDEVOBJ pldev;
+
+ /* Allocate the structure from paged pool */
+ pldev = ExAllocatePoolWithTag(PagedPool, sizeof(LDEVOBJ), GDITAG_LDEV);
+ if (!pldev)
+ {
+ DPRINT1("Failed to allocate LDEVOBJ.\n");
+ return NULL;
+ }
+
+ /* Zero out the structure */
+ RtlZeroMemory(pldev, sizeof(LDEVOBJ));
+
+ /* Set the ldevtype */
+ pldev->ldevtype = ldevtype;
+
+ return pldev;
+}
+
+VOID
+NTAPI
+LDEVOBJ_vFreeLDEV(PLDEVOBJ pldev)
+{
+ /* Make sure we don't have a driver loaded */
+ ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
+
+ /* Free the memory */
+ ExFreePoolWithTag(pldev, TAG_LDEV);
+}
+
+PDEVMODEINFO
+NTAPI
+LDEVOBJ_pdmiGetModes(
+ PLDEVOBJ pldev,
+ HANDLE hDriver)
+{
+ ULONG cbSize, cbFull;
+ PDEVMODEINFO pdminfo;
+
+ DPRINT("LDEVOBJ_pdmiGetModes(%p, %p)\n", pldev, hDriver);
+
+ /* Call the driver to get the required size */
+ cbSize = pldev->pfn.GetModes(hDriver, 0, NULL);
+ if (!cbSize)
+ {
+ DPRINT1("DrvGetModes returned 0\n");
+ return NULL;
+ }
+
+ /* Add space for the header */
+ cbFull = cbSize + FIELD_OFFSET(DEVMODEINFO, adevmode);
+
+ /* Allocate a buffer for the DEVMODE array */
+ pdminfo = ExAllocatePoolWithTag(PagedPool, cbFull, GDITAG_DEVMODE);
+ if (!pdminfo)
+ {
+ DPRINT1("Could not allocate devmodeinfo\n");
+ return NULL;
+ }
+
+ pdminfo->pldev = pldev;
+ pdminfo->cbdevmode = cbSize;
+
+ /* Call the driver again to fill the buffer */
+ cbSize = pldev->pfn.GetModes(hDriver, cbSize, pdminfo->adevmode);
+ if (!cbSize)
+ {
+ /* Could not get modes */
+ DPRINT1("returned size %ld(%ld)\n", cbSize, pdminfo->cbdevmode);
+ ExFreePool(pdminfo);
+ pdminfo = NULL;
+ }
+
+ return pdminfo;
+}
+
+
+BOOL
+NTAPI
+LDEVOBJ_bLoadImage(
+ IN PLDEVOBJ pldev,
+ PUNICODE_STRING pstrPathName)
+{
+ PSYSTEM_GDI_DRIVER_INFORMATION pDriverInfo;
+ NTSTATUS Status;
+ ULONG cbSize;
+
+ /* Make sure no image is loaded yet */
+ ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
+
+ /* Allocate a SYSTEM_GDI_DRIVER_INFORMATION structure */
+ cbSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION) + pstrPathName->Length;
+ pDriverInfo = ExAllocatePoolWithTag(PagedPool, cbSize, GDITAG_LDEV);
+ if (!pDriverInfo)
+ {
+ DPRINT1("Failed to allocate SYSTEM_GDI_DRIVER_INFORMATION\n");
+ return FALSE;
+ }
+
+ /* Initialize the UNICODE_STRING and copy the driver name */
+ RtlInitEmptyUnicodeString(&pDriverInfo->DriverName,
+ (PWSTR)(pDriverInfo + 1),
+ pstrPathName->Length);
+ RtlCopyUnicodeString(&pDriverInfo->DriverName, pstrPathName);
+
+ /* Try to load the driver */
+ Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation,
+ pDriverInfo,
+ sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to load a GDI driver: '%S', Status = 0x%lx\n",
+ pstrPathName->Buffer, Status);
+
+ /* Free the allocated memory */
+ ExFreePoolWithTag(pDriverInfo, TAG_LDEV);
+ return FALSE;
+ }
+
+ /* Set the driver info */
+ pldev->pGdiDriverInfo = pDriverInfo;
+
+ /* Return success. */
+ return TRUE;
+}
+
+VOID
+NTAPI
+LDEVOBJ_vUnloadImage(
+ IN PLDEVOBJ pldev)
+{
+ NTSTATUS Status;
+
+ /* Make sure we have a driver info */
+ ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
+
+ /* Check if we have loaded a driver */
+ if (pldev->pfn.DisableDriver)
+ {
+ /* Call the unload function */
+ pldev->pfn.DisableDriver();
+ }
+
+ /* Unload the driver */
+ Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
+ &pldev->pGdiDriverInfo->ImageAddress,
+ sizeof(HANDLE));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to unload the driver, this is bad.\n");
+ }
+
+ /* Free the driver info structure */
+ ExFreePoolWithTag(pldev->pGdiDriverInfo, GDITAG_LDEV);
+ pldev->pGdiDriverInfo = NULL;
+}
+
+BOOL
+NTAPI
+LDEVOBJ_bLoadDriver(
+ IN PLDEVOBJ pldev)
+{
+ PFN_DrvEnableDriver pfnEnableDriver;
+ DRVENABLEDATA ded;
+ ULONG i;
+
+ /* Make sure we have a driver info */
+ ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
+
+ /* Call the drivers DrvEnableDriver function */
+ RtlZeroMemory(&ded, sizeof(ded));
+ pfnEnableDriver = pldev->pGdiDriverInfo->EntryPoint;
+ if (!pfnEnableDriver(GDI_ENGINE_VERSION, sizeof(ded), &ded))
+ {
+ DPRINT1("DrvEnableDriver failed\n");
+
+ /* Unload the image. */
+ LDEVOBJ_vUnloadImage(pldev);
+ return FALSE;
+ }
+
+ /* Copy the returned driver version */
+ pldev->ulDriverVersion = ded.iDriverVersion;
+
+ /* Fill the driver function array */
+ for (i = 0; i < ded.c; i++)
+ {
+ pldev->apfn[ded.pdrvfn[i].iFunc] = ded.pdrvfn[i].pfn;
+ }
+
+ /* Return success. */
+ return TRUE;
+}
+
+
+PVOID
+NTAPI
+LDEVOBJ_pvFindImageProcAddress(
+ IN PLDEVOBJ pldev,
+ IN LPSTR pszProcName)
+{
+ PVOID pvImageBase;
+ PIMAGE_EXPORT_DIRECTORY pExportDir;
+ PVOID pvProcAdress = NULL;
+ PUSHORT pOrdinals;
+ PULONG pNames, pAddresses;
+ ULONG i, cbSize;
+
+ /* Make sure we have a driver info */
+ ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
+
+ /* Get the pointer to the export directory */
+ pvImageBase = pldev->pGdiDriverInfo->ImageAddress;
+ pExportDir = RtlImageDirectoryEntryToData(pvImageBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &cbSize);
+ if (!pExportDir)
+ {
+ return NULL;
+ }
+
+ /* Get pointers to some tables */
+ pNames = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNames);
+ pOrdinals = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNameOrdinals);
+ pAddresses = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfFunctions);
+
+ /* Loop the export table */
+ for (i = 0; i < pExportDir->NumberOfNames; i++)
+ {
+ /* Compare the name */
+ if (_stricmp(pszProcName, RVA_TO_ADDR(pvImageBase, pNames[i])) == 0)
+ {
+ /* Found! Calculate the procedure address */
+ pvProcAdress = RVA_TO_ADDR(pvImageBase, pAddresses[pOrdinals[i]]);
+ break;
+ }
+ }
+
+ /* Return the address */
+ return pvProcAdress;
+}
+
+PLDEVOBJ
+NTAPI
+EngLoadImageEx(
+ LPWSTR pwszDriverName,
+ ULONG ldevtype)
+{
+ WCHAR acwBuffer[MAX_PATH];
+ PLDEVOBJ pldev;
+ UNICODE_STRING strDriverName;
+ ULONG cwcLength;
+ LPWSTR pwsz;
+
+ DPRINT("EngLoadImageEx(%ls, %ld)\n", pwszDriverName, ldevtype);
+ ASSERT(pwszDriverName);
+
+ /* Initialize buffer for the the driver name */
+ RtlInitEmptyUnicodeString(&strDriverName, acwBuffer, sizeof(acwBuffer));
+
+ /* Start path with systemroot */
+ RtlAppendUnicodeToString(&strDriverName, L"\\SystemRoot\\System32\\");
+
+ /* Get Length of given string */
+ cwcLength = wcslen(pwszDriverName);
+
+ /* Check if we have a system32 path given */
+ pwsz = pwszDriverName + cwcLength;
+ while (pwsz > pwszDriverName)
+ {
+ if (_wcsnicmp(pwsz, L"\\system32\\", 10) == 0)
+ {
+ /* Driver name starts after system32 */
+ pwsz += 10;
+ break;
+ }
+ pwsz--;
+ }
+
+ /* Append the driver name */
+ RtlAppendUnicodeToString(&strDriverName, pwsz);
+
+ /* MSDN says "The driver must include this suffix in the pwszDriver string."
+ But in fact it's optional. */
+ if (_wcsnicmp(pwszDriverName + cwcLength - 4, L".dll", 4) != 0)
+ {
+ /* Append the .dll suffix */
+ RtlAppendUnicodeToString(&strDriverName, L".dll");
+ }
+
+ /* Lock loader */
+ EngAcquireSemaphore(ghsemLDEVList);
+
+ /* Search the List of LDEVS for the driver name */
+ for (pldev = gpldevHead; pldev != NULL; pldev = pldev->pldevNext)
+ {
+ /* Check if the ldev is associated with a file */
+ if (pldev->pGdiDriverInfo)
+ {
+ /* Check for match (case insensative) */
+ if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, 1))
+ {
+ /* Image found in LDEV list */
+ break;
+ }
+ }
+ }
+
+ /* Did we find one? */
+ if (!pldev)
+ {
+ /* No, allocate a new LDEVOBJ */
+ pldev = LDEVOBJ_AllocLDEV(ldevtype);
+ if (!pldev)
+ {
+ DPRINT1("Could not allocate LDEV\n");
+ goto leave;
+ }
+
+ /* Load the image */
+ if (!LDEVOBJ_bLoadImage(pldev, &strDriverName))
+ {
+ LDEVOBJ_vFreeLDEV(pldev);
+ pldev = NULL;
+ DPRINT1("LDEVOBJ_bLoadImage failed\n");
+ goto leave;
+ }
+
+ /* Shall we load a driver? */
+ if (ldevtype != LDEV_IMAGE)
+ {
+ /* Load the driver */
+ if (!LDEVOBJ_bLoadDriver(pldev))
+ {
+ DPRINT1("LDEVOBJ_bLoadDriver failed\n");
+ LDEVOBJ_vFreeLDEV(pldev);
+ pldev = NULL;
+ goto leave;
+ }
+ }
+
+ /* Insert the LDEV into the global list */
+ pldev->pldevPrev = NULL;
+ pldev->pldevNext = gpldevHead;
+ gpldevHead = pldev;
+ }
+
+ /* Increase ref count */
+ pldev->cRefs++;
+
+leave:
+ /* Unlock loader */
+ EngReleaseSemaphore(ghsemLDEVList);
+
+ DPRINT("EngLoadImageEx returning %p\n", pldev);
+
+ return pldev;
+}
+
+
+/** Exported functions ********************************************************/
+
+HANDLE
+APIENTRY
+EngLoadImage(
+ LPWSTR pwszDriverName)
+{
+ return (HANDLE)EngLoadImageEx(pwszDriverName, LDEV_IMAGE);
+}
+
+
+VOID
+APIENTRY
+EngUnloadImage(
+ IN HANDLE hModule)
+{
+ PLDEVOBJ pldev = (PLDEVOBJ)hModule;
+
+ /* Make sure the LDEV is in the list */
+ ASSERT(pldev->pldevPrev || pldev->pldevNext);
+
+ /* Lock loader */
+ EngAcquireSemaphore(ghsemLDEVList);
+
+ /* Decrement reference count */
+ pldev->cRefs--;
+
+ /* No more references left? */
+ if (pldev->cRefs == 0)
+ {
+ /* Remove ldev from the list */
+ if (pldev->pldevPrev)
+ pldev->pldevPrev->pldevNext = pldev->pldevNext;
+ if (pldev->pldevNext)
+ pldev->pldevNext->pldevPrev = pldev->pldevPrev;
+
+ /* Unload the image */
+ LDEVOBJ_vUnloadImage(pldev);
+ }
+
+ /* Unlock loader */
+ EngReleaseSemaphore(ghsemLDEVList);
+}
+
+
+PVOID
+APIENTRY
+EngFindImageProcAddress(
+ IN HANDLE hModule,
+ IN LPSTR lpProcName)
+{
+ PLDEVOBJ pldev = (PLDEVOBJ)hModule;
+
+ ASSERT(gpldevWin32k != NULL);
+
+ /* Check if win32k is requested */
+ if (!pldev)
+ {
+ pldev = gpldevWin32k;
+ }
+
+ /* Check if the drivers entry point is requested */
+ if (_strnicmp(lpProcName, "DrvEnableDriver", 15) == 0)
+ {
+ return pldev->pGdiDriverInfo->EntryPoint;
+ }
+
+ /* Try to find the address */
+ return LDEVOBJ_pvFindImageProcAddress(pldev, lpProcName);
+}
+
diff --git a/subsystems/win32/win32k/eng/lineto.c b/subsystems/win32/win32k/eng/lineto.c
index a67b47af5b1..d5db687be0e 100644
--- a/subsystems/win32/win32k/eng/lineto.c
+++ b/subsystems/win32/win32k/eng/lineto.c
@@ -565,10 +565,7 @@ IntEngLineTo(SURFOBJ *psoDest,
if (b.left == b.right) b.right++;
if (b.top == b.bottom) b.bottom++;
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, x1, y1, x2, y2);
-
- if (psurfDest->flHooks & HOOK_LINETO)
+ if (psurfDest->flags & HOOK_LINETO)
{
/* Call the driver's DrvLineTo */
ret = GDIDEVFUNCS(psoDest).LineTo(
@@ -576,7 +573,7 @@ IntEngLineTo(SURFOBJ *psoDest,
}
#if 0
- if (! ret && (psurfDest->flHooks & HOOK_STROKEPATH))
+ if (! ret && (psurfDest->flags & HOOK_STROKEPATH))
{
/* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
}
@@ -587,9 +584,6 @@ IntEngLineTo(SURFOBJ *psoDest,
ret = EngLineTo(psoDest, ClipObj, pbo, x1, y1, x2, y2, RectBounds, Mix);
}
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
-
return ret;
}
diff --git a/subsystems/win32/win32k/eng/mapping.c b/subsystems/win32/win32k/eng/mapping.c
index 7e445d7c631..0da46dfca29 100644
--- a/subsystems/win32/win32k/eng/mapping.c
+++ b/subsystems/win32/win32k/eng/mapping.c
@@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel
* PURPOSE: Functions for mapping files and sections
* FILE: subsys/win32k/eng/device.c
- * PROGRAMER:
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include
@@ -11,12 +11,348 @@
#define NDEBUG
#include
+// HACK!!!
+#define MmMapViewInSessionSpace MmMapViewInSystemSpace
+#define MmUnmapViewInSessionSpace MmUnmapViewInSystemSpace
+
+typedef struct _ENGSECTION
+{
+ PVOID pvSectionObject;
+ PVOID pvMappedBase;
+ SIZE_T cjViewSize;
+ ULONG ulTag;
+} ENGSECTION, *PENGSECTION;
+
+typedef struct _FILEVIEW
+{
+ LARGE_INTEGER LastWriteTime;
+ PVOID pvKView;
+ PVOID pvViewFD;
+ SIZE_T cjView;
+ PVOID pSection;
+} FILEVIEW, *PFILEVIEW;
+
+typedef struct _FONTFILEVIEW
+{
+ FILEVIEW;
+ DWORD reserved[2];
+ PWSTR pwszPath;
+ SIZE_T ulRegionSize;
+ ULONG cKRefCount;
+ ULONG cRefCountFD;
+ PVOID pvSpoolerBase;
+ DWORD dwSpoolerPid;
+} FONTFILEVIEW, *PFONTFILEVIEW;
+
+enum
+{
+ FVF_SYSTEMROOT = 1,
+ FVF_READONLY = 2,
+ FVF_FONTFILE = 4,
+};
+
+HANDLE ghSystem32Directory;
+HANDLE ghRootDirectory;
+
+
+PVOID
+NTAPI
+EngCreateSection(
+ IN ULONG fl,
+ IN SIZE_T cjSize,
+ IN ULONG ulTag)
+{
+ NTSTATUS Status;
+ PENGSECTION pSection;
+ PVOID pvSectionObject;
+ LARGE_INTEGER liSize;
+
+ /* Allocate a section object */
+ pSection = EngAllocMem(0, sizeof(ENGSECTION), 'stsU');
+ if (!pSection) return NULL;
+
+ liSize.QuadPart = cjSize;
+ Status = MmCreateSection(&pvSectionObject,
+ SECTION_ALL_ACCESS,
+ NULL,
+ &liSize,
+ PAGE_READWRITE,
+ SEC_COMMIT,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create a section Status=0x%x\n", Status);
+ EngFreeMem(pSection);
+ return NULL;
+ }
+
+ /* Set the fields of the section */
+ pSection->ulTag = ulTag;
+ pSection->pvSectionObject = pvSectionObject;
+ pSection->pvMappedBase = NULL;
+ pSection->cjViewSize = cjSize;
+
+ return pSection;
+}
+
+
+BOOL
+APIENTRY
+EngMapSection(
+ IN PVOID pvSection,
+ IN BOOL bMap,
+ IN HANDLE hProcess,
+ OUT PVOID* pvBaseAddress)
+{
+ NTSTATUS Status;
+ PENGSECTION pSection = pvSection;
+ PEPROCESS pepProcess;
+
+ /* Get a pointer to the process */
+ Status = ObReferenceObjectByHandle(hProcess,
+ PROCESS_VM_OPERATION,
+ NULL,
+ KernelMode,
+ (PVOID*)&pepProcess,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not access process %p, Status=0x%lx\n", hProcess, Status);
+ return FALSE;
+ }
+
+ if (bMap)
+ {
+ /* Make sure the section isn't already mapped */
+ ASSERT(pSection->pvMappedBase == NULL);
+
+ /* Map the section into the process address space */
+ Status = MmMapViewOfSection(pSection->pvSectionObject,
+ pepProcess,
+ &pSection->pvMappedBase,
+ 0,
+ pSection->cjViewSize,
+ NULL,
+ &pSection->cjViewSize,
+ 0,
+ 0,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map a section Status=0x%x\n", Status);
+ }
+ }
+ else
+ {
+ /* Make sure the section is mapped */
+ ASSERT(pSection->pvMappedBase);
+
+ /* Unmap the section from the process address space */
+ Status = MmUnmapViewOfSection(pepProcess, pSection->pvMappedBase);
+ if (NT_SUCCESS(Status))
+ {
+ pSection->pvMappedBase = NULL;
+ }
+ else
+ {
+ DPRINT1("Failed to unmap a section @ &p Status=0x%x\n",
+ pSection->pvMappedBase, Status);
+ }
+ }
+
+ /* Dereference the process */
+ ObDereferenceObject(pepProcess);
+
+ /* Set the new mapping base and return bool status */
+ *pvBaseAddress = pSection->pvMappedBase;
+ return NT_SUCCESS(Status);
+}
+
+BOOL
+APIENTRY
+EngFreeSectionMem(
+ IN PVOID pvSection OPTIONAL,
+ IN PVOID pvMappedBase OPTIONAL)
+{
+ NTSTATUS Status;
+ PENGSECTION pSection = pvSection;
+ BOOL bResult = TRUE;
+
+ /* Did the caller give us a mapping base? */
+ if (pvMappedBase)
+ {
+ Status = MmUnmapViewInSessionSpace(pvMappedBase);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status);
+ bResult = FALSE;
+ }
+ }
+
+ /* Check if we should free the section as well */
+ if (pSection)
+ {
+ /* Dereference the kernel section */
+ ObDereferenceObject(pSection->pvSectionObject);
+
+ /* Finally free the section memory itself */
+ EngFreeMem(pSection);
+ }
+
+ return bResult;
+}
+
+PVOID
+APIENTRY
+EngAllocSectionMem(
+ OUT PVOID *ppvSection,
+ IN ULONG fl,
+ IN SIZE_T cjSize,
+ IN ULONG ulTag)
+{
+ NTSTATUS Status;
+ PENGSECTION pSection;
+
+ /* Check parameter */
+ if (cjSize == 0) return NULL;
+
+ /* Allocate a section object */
+ pSection = EngCreateSection(fl, cjSize, ulTag);
+ if (!pSection)
+ {
+ *ppvSection = NULL;
+ return NULL;
+ }
+
+ /* Map the section in session space */
+ Status = MmMapViewInSessionSpace(pSection->pvSectionObject,
+ &pSection->pvMappedBase,
+ &pSection->cjViewSize);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map a section Status=0x%x\n", Status);
+ *ppvSection = NULL;
+ EngFreeSectionMem(pSection, NULL);
+ return NULL;
+ }
+
+ if (fl & FL_ZERO_MEMORY)
+ {
+ RtlZeroMemory(pSection->pvMappedBase, cjSize);
+ }
+
+ /* Set section pointer and return base address */
+ *ppvSection = pSection;
+ return pSection->pvMappedBase;
+}
+
+
+PFILEVIEW
+NTAPI
+EngLoadModuleEx(
+ LPWSTR pwsz,
+ ULONG cjSizeOfModule,
+ FLONG fl)
+{
+ PFILEVIEW pFileView = NULL;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hRootDir;
+ UNICODE_STRING ustrFileName;
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_BASIC_INFORMATION FileInformation;
+ HANDLE hFile;
+ NTSTATUS Status;
+ LARGE_INTEGER liSize;
+
+ if (fl & FVF_FONTFILE)
+ {
+ pFileView = EngAllocMem(0, sizeof(FONTFILEVIEW), 'vffG');
+ }
+ else
+ {
+ pFileView = EngAllocMem(0, sizeof(FILEVIEW), 'liFg');
+ }
+
+ /* Check for success */
+ if (!pFileView) return NULL;
+
+ /* Check if the file is relative to system32 */
+ if (fl & FVF_SYSTEMROOT)
+ {
+ hRootDir = ghSystem32Directory;
+ }
+ else
+ {
+ hRootDir = ghRootDirectory;
+ }
+
+ /* Initialize unicode string and object attributes */
+ RtlInitUnicodeString(&ustrFileName, pwsz);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ustrFileName,
+ OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
+ hRootDir,
+ NULL);
+
+ /* Now open the file */
+ Status = ZwCreateFile(&hFile,
+ FILE_READ_DATA,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OPEN,
+ FILE_NON_DIRECTORY_FILE,
+ NULL,
+ 0);
+
+ Status = ZwQueryInformationFile(hFile,
+ &IoStatusBlock,
+ &FileInformation,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
+ if (NT_SUCCESS(Status))
+ {
+ pFileView->LastWriteTime = FileInformation.LastWriteTime;
+ }
+
+ /* Create a section from the file */
+ liSize.QuadPart = cjSizeOfModule;
+ Status = MmCreateSection(&pFileView->pSection,
+ SECTION_ALL_ACCESS,
+ NULL,
+ cjSizeOfModule ? &liSize : NULL,
+ fl & FVF_READONLY ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE,
+ SEC_COMMIT,
+ hFile,
+ NULL);
+
+ /* Close the file handle */
+ ZwClose(hFile);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create a section Status=0x%x\n", Status);
+ EngFreeMem(pFileView);
+ return NULL;
+ }
+
+
+ pFileView->pvKView = NULL;
+ pFileView->pvViewFD = NULL;
+ pFileView->cjView = 0;
+
+ return pFileView;
+}
+
HANDLE
APIENTRY
EngLoadModule(LPWSTR pwsz)
{
- UNIMPLEMENTED;
- return NULL;
+ /* Forward to EngLoadModuleEx */
+ return (HANDLE)EngLoadModuleEx(pwsz, 0, FVF_READONLY | FVF_SYSTEMROOT);
}
HANDLE
@@ -25,9 +361,8 @@ EngLoadModuleForWrite(
IN LPWSTR pwsz,
IN ULONG cjSizeOfModule)
{
- // www.osr.com/ddk/graphics/gdifncs_98rr.htm
- UNIMPLEMENTED;
- return NULL;
+ /* Forward to EngLoadModuleEx */
+ return (HANDLE)EngLoadModuleEx(pwsz, cjSizeOfModule, FVF_SYSTEMROOT);
}
PVOID
@@ -36,17 +371,46 @@ EngMapModule(
IN HANDLE h,
OUT PULONG pulSize)
{
- // www.osr.com/ddk/graphics/gdifncs_9b1j.htm
- UNIMPLEMENTED;
- return NULL;
+ PFILEVIEW pFileView = (PFILEVIEW)h;
+ NTSTATUS Status;
+
+ pFileView->cjView = 0;
+
+ /* Map the section in session space */
+ Status = MmMapViewInSessionSpace(pFileView->pSection,
+ &pFileView->pvKView,
+ &pFileView->cjView);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map a section Status=0x%x\n", Status);
+ *pulSize = 0;
+ return NULL;
+ }
+
+ *pulSize = pFileView->cjView;
+ return pFileView->pvKView;
}
VOID
APIENTRY
-EngFreeModule (IN HANDLE h)
+EngFreeModule(IN HANDLE h)
{
- // www.osr.com/ddk/graphics/gdifncs_9fzb.htm
- UNIMPLEMENTED;
+ PFILEVIEW pFileView = (PFILEVIEW)h;
+ NTSTATUS Status;
+
+ /* Unmap the section */
+ Status = MmUnmapViewInSessionSpace(pFileView->pvKView);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status);
+ ASSERT(FALSE);
+ }
+
+ /* Dereference the section */
+ ObDereferenceObject(pFileView->pSection);
+
+ /* Free the file view memory */
+ EngFreeMem(pFileView);
}
PVOID
@@ -56,8 +420,28 @@ EngMapFile(
IN ULONG cjSize,
OUT ULONG_PTR *piFile)
{
- UNIMPLEMENTED;
- return NULL;
+ HANDLE hModule;
+ PVOID pvBase;
+
+ /* Load the file */
+ hModule = EngLoadModuleEx(pwsz, 0, 0);
+ if (!hModule)
+ {
+ *piFile = 0;
+ return NULL;
+ }
+
+ /* Map the file */
+ pvBase = EngMapModule(hModule, &cjSize);
+ if (!pvBase)
+ {
+ EngFreeModule(hModule);
+ hModule = NULL;
+ }
+
+ /* Set iFile and return mapped base */
+ *piFile = (ULONG_PTR)hModule;
+ return pvBase;
}
BOOL
@@ -65,8 +449,11 @@ APIENTRY
EngUnmapFile(
IN ULONG_PTR iFile)
{
- UNIMPLEMENTED;
- return FALSE;
+ HANDLE hModule = (HANDLE)iFile;
+
+ EngFreeModule(hModule);
+
+ return TRUE;
}
@@ -110,36 +497,3 @@ EngUnmapFontFile(
// www.osr.com/ddk/graphics/gdifncs_09wn.htm
EngUnmapFontFileFD(iFile);
}
-
-
-BOOLEAN
-APIENTRY
-EngMapSection(IN PVOID Section,
- IN BOOLEAN Map,
- IN HANDLE Process,
- IN PVOID* BaseAddress)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-PVOID
-APIENTRY
-EngAllocSectionMem(IN PVOID SectionObject,
- IN ULONG Flags,
- IN SIZE_T MemSize,
- IN ULONG Tag)
-{
- UNIMPLEMENTED;
- return NULL;
-}
-
-
-BOOLEAN
-APIENTRY
-EngFreeSectionMem(IN PVOID SectionObject OPTIONAL,
- IN PVOID MappedBase)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
diff --git a/subsystems/win32/win32k/eng/mem.c b/subsystems/win32/win32k/eng/mem.c
index a49e4fe5cab..1fb81b339bc 100644
--- a/subsystems/win32/win32k/eng/mem.c
+++ b/subsystems/win32/win32k/eng/mem.c
@@ -79,6 +79,7 @@ EngAllocUserMem(SIZE_T cj, ULONG Tag)
}
/* TODO: Add allocation info to AVL tree (stored inside W32PROCESS structure) */
+ //hSecure = EngSecureMem(NewMem, cj);
return NewMem;
}
@@ -166,6 +167,7 @@ HackUnsecureVirtualMemory(
HANDLE APIENTRY
EngSecureMem(PVOID Address, ULONG Length)
{
+ return (HANDLE)-1; // HACK!!!
return MmSecureVirtualMemory(Address, Length, PAGE_READWRITE);
}
@@ -175,6 +177,7 @@ EngSecureMem(PVOID Address, ULONG Length)
VOID APIENTRY
EngUnsecureMem(HANDLE Mem)
{
+ if (Mem == (HANDLE)-1) return; // HACK!!!
MmUnsecureVirtualMemory((PVOID) Mem);
}
diff --git a/subsystems/win32/win32k/eng/mouse.c b/subsystems/win32/win32k/eng/mouse.c
index 93ab14d4f6d..b2db0e61af7 100644
--- a/subsystems/win32/win32k/eng/mouse.c
+++ b/subsystems/win32/win32k/eng/mouse.c
@@ -37,23 +37,17 @@ EngSetPointerTag(
*/
INT INTERNAL_CALL
MouseSafetyOnDrawStart(
- SURFOBJ *pso,
+ PPDEVOBJ ppdev,
LONG HazardX1,
LONG HazardY1,
LONG HazardX2,
LONG HazardY2)
{
LONG tmp;
- PDEVOBJ *ppdev;
GDIPOINTER *pgp;
- ASSERT(pso != NULL);
-
- ppdev = GDIDEV(pso);
- if (ppdev == NULL)
- {
- return FALSE;
- }
+ ASSERT(ppdev != NULL);
+ ASSERT(ppdev->pSurface != NULL);
pgp = &ppdev->Pointer;
@@ -83,12 +77,12 @@ MouseSafetyOnDrawStart(
}
if (pgp->Exclude.right >= HazardX1
- && pgp->Exclude.left <= HazardX2
- && pgp->Exclude.bottom >= HazardY1
- && pgp->Exclude.top <= HazardY2)
+ && pgp->Exclude.left <= HazardX2
+ && pgp->Exclude.bottom >= HazardY1
+ && pgp->Exclude.top <= HazardY2)
{
ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount;
- ppdev->pfnMovePointer(pso, -1, -1, NULL);
+ ppdev->pfnMovePointer(&ppdev->pSurface->SurfObj, -1, -1, NULL);
}
return(TRUE);
@@ -99,19 +93,12 @@ MouseSafetyOnDrawStart(
*/
INT INTERNAL_CALL
MouseSafetyOnDrawEnd(
- SURFOBJ *pso)
+ PPDEVOBJ ppdev)
{
- PDEVOBJ *ppdev;
GDIPOINTER *pgp;
- ASSERT(pso != NULL);
-
- ppdev = (PDEVOBJ*)pso->hdev;
-
- if (ppdev == NULL)
- {
- return(FALSE);
- }
+ ASSERT(ppdev != NULL);
+ ASSERT(ppdev->pSurface != NULL);
pgp = &ppdev->Pointer;
@@ -125,7 +112,10 @@ MouseSafetyOnDrawEnd(
return FALSE;
}
- ppdev->pfnMovePointer(pso, gpsi->ptCursor.x, gpsi->ptCursor.y, &pgp->Exclude);
+ ppdev->pfnMovePointer(&ppdev->pSurface->SurfObj,
+ gpsi->ptCursor.x,
+ gpsi->ptCursor.y,
+ &pgp->Exclude);
ppdev->SafetyRemoveLevel = 0;
@@ -175,18 +165,17 @@ IntHideMousePointer(
ptlSave.x = rclDest.left - pt.x;
ptlSave.y = rclDest.top - pt.y;
- IntEngBitBltEx(psoDest,
- &pgp->psurfSave->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclDest,
- &ptlSave,
- &ptlSave,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCCOPY),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfSave->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclDest,
+ &ptlSave,
+ &ptlSave,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCCOPY));
}
VOID
@@ -229,77 +218,72 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
rclPointer.bottom = min(pgp->Size.cy, psoDest->sizlBitmap.cy - pt.y);
/* Copy the pixels under the cursor to temporary surface. */
- IntEngBitBltEx(&pgp->psurfSave->SurfObj,
- psoDest,
- NULL,
- NULL,
- NULL,
- &rclPointer,
- (POINTL*)&rclSurf,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCCOPY),
- FALSE);
+ IntEngBitBlt(&pgp->psurfSave->SurfObj,
+ psoDest,
+ NULL,
+ NULL,
+ NULL,
+ &rclPointer,
+ (POINTL*)&rclSurf,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCCOPY));
/* Blt the pointer on the screen. */
if (pgp->psurfColor)
{
- IntEngBitBltEx(psoDest,
- &pgp->psurfMask->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCAND),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfMask->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCAND));
- IntEngBitBltEx(psoDest,
- &pgp->psurfColor->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCINVERT),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfColor->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCINVERT));
}
else
{
- IntEngBitBltEx(psoDest,
- &pgp->psurfMask->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCAND),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfMask->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCAND));
rclPointer.top += pgp->Size.cy;
- IntEngBitBltEx(psoDest,
- &pgp->psurfMask->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCINVERT),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfMask->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCINVERT));
}
}
@@ -353,7 +337,7 @@ EngSetPointerShape(
rectl.bottom = sizel.cy;
/* Calculate lDelta for our surfaces. */
- lDelta = DIB_GetDIBWidthBytes(sizel.cx,
+ lDelta = WIDTH_BYTES_ALIGN32(sizel.cx,
BitsPerFormat(pso->iBitmapFormat));
/* Create a bitmap for saving the pixels under the cursor. */
@@ -373,10 +357,10 @@ EngSetPointerShape(
/* Create a bitmap to copy the color bitmap to */
hbmColor = EngCreateBitmap(psoColor->sizlBitmap,
- lDelta,
- pso->iBitmapFormat,
- BMF_TOPDOWN | BMF_NOZEROINIT,
- NULL);
+ lDelta,
+ pso->iBitmapFormat,
+ BMF_TOPDOWN | BMF_NOZEROINIT,
+ NULL);
psurfColor = SURFACE_ShareLockSurface(hbmColor);
if (!psurfColor) goto failure;
@@ -540,28 +524,13 @@ EngMovePointer(
prcl->right = prcl->left + pgp->Size.cx;
prcl->bottom = prcl->top + pgp->Size.cy;
}
- }
+ }
else if (prcl != NULL)
{
prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
}
}
-VOID APIENTRY
-IntEngMovePointer(
- IN SURFOBJ *pso,
- IN LONG x,
- IN LONG y,
- IN RECTL *prcl)
-{
- SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
- PPDEVOBJ ppdev = (PPDEVOBJ)pso->hdev;
-
- SURFACE_LockBitmapBits(psurf);
- ppdev->pfnMovePointer(pso, x, y, prcl);
- SURFACE_UnlockBitmapBits(psurf);
-}
-
ULONG APIENTRY
IntEngSetPointerShape(
IN SURFOBJ *pso,
@@ -576,13 +545,11 @@ IntEngSetPointerShape(
IN FLONG fl)
{
ULONG ulResult = SPS_DECLINE;
- SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
PFN_DrvSetPointerShape pfnSetPointerShape;
PPDEVOBJ ppdev = GDIDEV(pso);
pfnSetPointerShape = GDIDEVFUNCS(pso).SetPointerShape;
- SURFACE_LockBitmapBits(psurf);
if (pfnSetPointerShape)
{
ulResult = pfnSetPointerShape(pso,
@@ -620,8 +587,6 @@ IntEngSetPointerShape(
ppdev->pfnMovePointer = EngMovePointer;
}
- SURFACE_UnlockBitmapBits(psurf);
-
return ulResult;
}
@@ -649,10 +614,14 @@ GreSetPointerShape(
return 0;
}
- psurf = pdc->dclevel.pSurface;
+ ASSERT(pdc->dctype == DCTYPE_DIRECT);
+ EngAcquireSemaphore(pdc->ppdev->hsemDevLock);
+ /* We're not sure DC surface is the good one */
+ psurf = pdc->ppdev->pSurface;
if (!psurf)
{
DPRINT1("DC has no surface.\n");
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
DC_UnlockDc(pdc);
return 0;
}
@@ -668,7 +637,7 @@ GreSetPointerShape(
{
/* We have one, lock it */
psurfColor = SURFACE_ShareLockSurface(hbmColor);
-
+
if (psurfColor)
{
/* Create an XLATEOBJ, no mono support */
@@ -700,6 +669,8 @@ GreSetPointerShape(
if (psurfMask)
SURFACE_ShareUnlockSurface(psurfMask);
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+
/* Unlock the DC */
DC_UnlockDc(pdc);
@@ -724,12 +695,23 @@ GreMovePointer(
DPRINT1("Failed to lock the DC.\n");
return;
}
+ ASSERT(pdc->dctype == DCTYPE_DIRECT);
- /* Store the cursor exclude position in the PDEV */
- prcl = &pdc->ppdev->Pointer.Exclude;
+ /* Acquire PDEV lock */
+ EngAcquireSemaphore(pdc->ppdev->hsemDevLock);
- /* Call Eng/Drv function */
- IntEngMovePointer(&pdc->dclevel.pSurface->SurfObj, x, y, prcl);
+ /* Check if we need to move it */
+ if(pdc->ppdev->SafetyRemoveLevel == 0)
+ {
+ /* Store the cursor exclude position in the PDEV */
+ prcl = &pdc->ppdev->Pointer.Exclude;
+
+ /* Call Eng/Drv function */
+ pdc->ppdev->pfnMovePointer(&pdc->ppdev->pSurface->SurfObj, x, y, prcl);
+ }
+
+ /* Release PDEV lock */
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
/* Unlock the DC */
DC_UnlockDc(pdc);
diff --git a/subsystems/win32/win32k/eng/paint.c b/subsystems/win32/win32k/eng/paint.c
index d1290b3e9e9..d59c4f217aa 100644
--- a/subsystems/win32/win32k/eng/paint.c
+++ b/subsystems/win32/win32k/eng/paint.c
@@ -32,14 +32,13 @@
#define NDEBUG
#include
-static BOOL APIENTRY FillSolidUnlocked(SURFOBJ *pso, PRECTL pRect, ULONG iColor)
+BOOL APIENTRY FillSolid(SURFOBJ *pso, PRECTL pRect, ULONG iColor)
{
LONG y;
ULONG LineWidth;
ASSERT(pso);
ASSERT(pRect);
- MouseSafetyOnDrawStart(pso, pRect->left, pRect->top, pRect->right, pRect->bottom);
LineWidth = pRect->right - pRect->left;
DPRINT(" LineWidth: %d, top: %d, bottom: %d\n", LineWidth, pRect->top, pRect->bottom);
for (y = pRect->top; y < pRect->bottom; y++)
@@ -47,22 +46,9 @@ static BOOL APIENTRY FillSolidUnlocked(SURFOBJ *pso, PRECTL pRect, ULONG iColor)
DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_HLine(
pso, pRect->left, pRect->right, y, iColor);
}
- MouseSafetyOnDrawEnd(pso);
-
return TRUE;
}
-BOOL APIENTRY FillSolid(SURFOBJ *pso, PRECTL pRect, ULONG iColor)
-{
- SURFACE *psurf;
- BOOL Result;
- psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
- SURFACE_LockBitmapBits(psurf);
- Result = FillSolidUnlocked(pso, pRect, iColor);
- SURFACE_UnlockBitmapBits(psurf);
- return Result;
-}
-
BOOL APIENTRY
EngPaintRgn(SURFOBJ *pso, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
BRUSHOBJ *BrushObj, POINTL *BrushPoint)
@@ -85,7 +71,7 @@ EngPaintRgn(SURFOBJ *pso, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
if (ClipRegion->iDComplexity == DC_RECT)
{
- FillSolidUnlocked(pso, &(ClipRegion->rclBounds), iColor);
+ FillSolid(pso, &(ClipRegion->rclBounds), iColor);
} else {
/* Enumerate all the rectangles and draw them */
@@ -94,7 +80,7 @@ EngPaintRgn(SURFOBJ *pso, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
do {
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c; i++) {
- FillSolidUnlocked(pso, RectEnum.arcl + i, iColor);
+ FillSolid(pso, RectEnum.arcl + i, iColor);
}
} while (EnumMore);
}
@@ -136,18 +122,11 @@ IntEngPaint(IN SURFOBJ *pso,
DPRINT("pso->iType == %d\n", pso->iType);
/* Is the surface's Paint function hooked? */
- if((pso->iType!=STYPE_BITMAP) && (psurf->flHooks & HOOK_PAINT))
+ if((pso->iType!=STYPE_BITMAP) && (psurf->flags & HOOK_PAINT))
{
// Call the driver's DrvPaint
- SURFACE_LockBitmapBits(psurf);
- MouseSafetyOnDrawStart(pso, ClipRegion->rclBounds.left,
- ClipRegion->rclBounds.top, ClipRegion->rclBounds.right,
- ClipRegion->rclBounds.bottom);
-
ret = GDIDEVFUNCS(pso).Paint(
pso, ClipRegion, Brush, BrushOrigin, Mix);
- MouseSafetyOnDrawEnd(pso);
- SURFACE_UnlockBitmapBits(psurf);
return ret;
}
return EngPaint(pso, ClipRegion, Brush, BrushOrigin, Mix );
diff --git a/subsystems/win32/win32k/eng/pdevobj.c b/subsystems/win32/win32k/eng/pdevobj.c
new file mode 100644
index 00000000000..2da468ee3fb
--- /dev/null
+++ b/subsystems/win32/win32k/eng/pdevobj.c
@@ -0,0 +1,846 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Support for physical devices
+ * FILE: subsystems/win32/win32k/eng/pdevobj.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#include
+
+#include
+
+#define NDEBUG
+#include
+
+PPDEVOBJ gppdevPrimary = NULL;
+
+static PPDEVOBJ gppdevList = NULL;
+static HSEMAPHORE ghsemPDEV;
+
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitPDEVImpl()
+{
+ ghsemPDEV = EngCreateSemaphore();
+ if (!ghsemPDEV) return STATUS_INSUFFICIENT_RESOURCES;
+ return STATUS_SUCCESS;
+}
+
+
+PPDEVOBJ
+PDEVOBJ_AllocPDEV()
+{
+ PPDEVOBJ ppdev;
+
+ ppdev = ExAllocatePoolWithTag(PagedPool, sizeof(PDEVOBJ), GDITAG_PDEV);
+ if (!ppdev)
+ return NULL;
+
+ RtlZeroMemory(ppdev, sizeof(PDEVOBJ));
+
+ ppdev->cPdevRefs = 1;
+
+ return ppdev;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vRelease(PPDEVOBJ ppdev)
+{
+ /* Lock loader */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ /* Decrease reference count */
+ --ppdev->cPdevRefs;
+
+ ASSERT(ppdev->cPdevRefs >= 0) ;
+
+ /* Check if references are left */
+ if (ppdev->cPdevRefs == 0)
+ {
+ /* Do we have a surface? */
+ if(ppdev->pSurface)
+ {
+ /* Release the surface and let the driver free it */
+ SURFACE_ShareUnlockSurface(ppdev->pSurface);
+ ppdev->pfn.DisableSurface(ppdev->dhpdev);
+ }
+
+ /* Do we have a palette? */
+ if(ppdev->ppalSurf)
+ {
+ PALETTE_ShareUnlockPalette(ppdev->ppalSurf);
+ }
+
+ /* Disable PDEV */
+ ppdev->pfn.DisablePDEV(ppdev->dhpdev);
+
+ /* Remove it from list */
+ if( ppdev == gppdevList )
+ gppdevList = ppdev->ppdevNext ;
+ else
+ {
+ PPDEVOBJ ppdevCurrent = gppdevList;
+ BOOL found = FALSE ;
+ while (!found && ppdevCurrent->ppdevNext)
+ {
+ if (ppdevCurrent->ppdevNext == ppdev)
+ found = TRUE;
+ else
+ ppdevCurrent = ppdevCurrent->ppdevNext ;
+ }
+ if(found)
+ ppdevCurrent->ppdevNext = ppdev->ppdevNext;
+ }
+
+ /* Is this the primary one ? */
+ if (ppdev == gppdevPrimary)
+ gppdevPrimary = NULL;
+
+ /* Free it */
+ ExFreePoolWithTag(ppdev, GDITAG_PDEV );
+ }
+
+ /* Unlock loader */
+ EngReleaseSemaphore(ghsemPDEV);
+
+}
+
+BOOL
+NTAPI
+PDEVOBJ_bEnablePDEV(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdevmode,
+ PWSTR pwszLogAddress)
+{
+ PFN_DrvEnablePDEV pfnEnablePDEV;
+
+ DPRINT1("PDEVOBJ_bEnablePDEV()\n");
+
+ /* Get the DrvEnablePDEV function */
+ pfnEnablePDEV = ppdev->pldev->pfn.EnablePDEV;
+
+ /* Call the drivers DrvEnablePDEV function */
+ ppdev->dhpdev = pfnEnablePDEV(pdevmode,
+ pwszLogAddress,
+ HS_DDI_MAX,
+ ppdev->ahsurf,
+ sizeof(GDIINFO),
+ &ppdev->gdiinfo,
+ sizeof(DEVINFO),
+ &ppdev->devinfo,
+ (HDEV)ppdev,
+ ppdev->pGraphicsDevice->pwszDescription,
+ ppdev->pGraphicsDevice->DeviceObject);
+
+ /* Fix up some values */
+ if (ppdev->gdiinfo.ulLogPixelsX == 0)
+ ppdev->gdiinfo.ulLogPixelsX = 96;
+
+ if (ppdev->gdiinfo.ulLogPixelsY == 0)
+ ppdev->gdiinfo.ulLogPixelsY = 96;
+
+ /* Setup Palette */
+ GDIOBJ_SetOwnership(ppdev->devinfo.hpalDefault, NULL);
+ ppdev->ppalSurf = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
+
+ DPRINT1("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev);
+
+ return TRUE;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vCompletePDEV(
+ PPDEVOBJ ppdev)
+{
+ /* Call the drivers DrvCompletePDEV function */
+ ppdev->pldev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
+}
+
+PSURFACE
+NTAPI
+PDEVOBJ_pSurface(
+ PPDEVOBJ ppdev)
+{
+ HSURF hsurf;
+
+ /* Check if we already have a surface */
+ if (ppdev->pSurface)
+ {
+ /* Increment reference count */
+ GDIOBJ_IncrementShareCount(&ppdev->pSurface->BaseObject);
+ }
+ else
+ {
+ /* Call the drivers DrvEnableSurface */
+ hsurf = ppdev->pldev->pfn.EnableSurface(ppdev->dhpdev);
+
+ /* Lock the surface */
+ ppdev->pSurface = SURFACE_ShareLockSurface(hsurf);
+ }
+
+ DPRINT("PDEVOBJ_pSurface() returning %p\n", ppdev->pSurface);
+ return ppdev->pSurface;
+}
+
+PDEVMODEW
+NTAPI
+PDEVOBJ_pdmMatchDevMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PDEVMODEW pdmCurrent;
+ INT i;
+ DWORD dwFields;
+
+ pGraphicsDevice = ppdev->pGraphicsDevice;
+
+ for (i = 0; i < pGraphicsDevice->cDevModes; i++)
+ {
+ pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
+
+ /* Compare asked DEVMODE fields
+ * Only compare those that are valid in both DEVMODE structs */
+ dwFields = pdmCurrent->dmFields & pdm->dmFields ;
+ /* For now, we only need those */
+ if ((dwFields & DM_BITSPERPEL) &&
+ (pdmCurrent->dmBitsPerPel != pdm->dmBitsPerPel))
+ continue;
+ if ((dwFields & DM_PELSWIDTH) &&
+ (pdmCurrent->dmPelsWidth != pdm->dmPelsWidth))
+ continue;
+ if ((dwFields & DM_PELSHEIGHT) &&
+ (pdmCurrent->dmPelsHeight != pdm->dmPelsHeight))
+ continue;
+ if ((dwFields & DM_DISPLAYFREQUENCY) &&
+ (pdmCurrent->dmDisplayFrequency != pdm->dmDisplayFrequency))
+ continue;
+
+ /* Match! Return the DEVMODE */
+ return pdmCurrent;
+ }
+
+ /* Nothing found */
+ return NULL;
+}
+
+static
+PPDEVOBJ
+EngpCreatePDEV(
+ PUNICODE_STRING pustrDeviceName,
+ PDEVMODEW pdm)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PPDEVOBJ ppdev;
+
+ /* Try to find the GRAPHICS_DEVICE */
+ if (pustrDeviceName)
+ {
+ pGraphicsDevice = EngpFindGraphicsDevice(pustrDeviceName, 0, 0);
+ if (!pGraphicsDevice)
+ {
+ DPRINT1("No GRAPHICS_DEVICE found for %ls!\n",
+ pustrDeviceName ? pustrDeviceName->Buffer : 0);
+ return NULL;
+ }
+ }
+ else
+ {
+ pGraphicsDevice = gpPrimaryGraphicsDevice;
+ }
+
+ /* Allocate a new PDEVOBJ */
+ ppdev = PDEVOBJ_AllocPDEV();
+ if (!ppdev)
+ {
+ DPRINT1("failed to allocate a PDEV\n");
+ return NULL;
+ }
+
+ /* If no DEVMODEW is given, ... */
+ if (!pdm)
+ {
+ /* ... use the device's default one */
+ pdm = pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm;
+ DPRINT1("Using iDefaultMode = %ld\n", pGraphicsDevice->iDefaultMode);
+ }
+
+ /* Try to get a diplay driver */
+ ppdev->pldev = EngLoadImageEx(pdm->dmDeviceName, LDEV_DEVICE_DISPLAY);
+ if (!ppdev->pldev)
+ {
+ DPRINT1("Could not load display driver '%ls'\n",
+ pGraphicsDevice->pDiplayDrivers);
+ ExFreePoolWithTag(ppdev, GDITAG_PDEV);
+ return NULL;
+ }
+
+ /* Copy the function table */
+ ppdev->pfn = ppdev->pldev->pfn;
+
+ /* Set MovePointer function */
+ ppdev->pfnMovePointer = ppdev->pfn.MovePointer;
+ if (!ppdev->pfnMovePointer)
+ ppdev->pfnMovePointer = EngMovePointer;
+
+ ppdev->pGraphicsDevice = pGraphicsDevice;
+ ppdev->hsemDevLock = EngCreateSemaphore();
+ // Should we change the ative mode of pGraphicsDevice ?
+ ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, pdm) ;
+
+ /* FIXME! */
+ ppdev->flFlags = PDEV_DISPLAY;
+
+ /* HACK: Don't use the pointer */
+ ppdev->Pointer.Exclude.right = -1;
+
+ /* Call the driver to enable the PDEV */
+ if (!PDEVOBJ_bEnablePDEV(ppdev, pdm, NULL))
+ {
+ DPRINT1("Failed to enable PDEV!\n");
+ ASSERT(FALSE);
+ }
+
+ /* FIXME: this must be done in a better way */
+ pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
+
+ /* Tell the driver that the PDEV is ready */
+ PDEVOBJ_vCompletePDEV(ppdev);
+
+ /* Return the PDEV */
+ return ppdev;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vSwitchPdev(
+ PPDEVOBJ ppdev,
+ PPDEVOBJ ppdev2)
+{
+ PDEVOBJ pdevTmp;
+ DWORD tmpStateFlags;
+
+ /* Exchange data */
+ pdevTmp = *ppdev;
+
+ /* Exchange driver functions */
+ ppdev->pfn = ppdev2->pfn;
+ ppdev2->pfn = pdevTmp.pfn;
+
+ /* Exchange LDEVs */
+ ppdev->pldev = ppdev2->pldev;
+ ppdev2->pldev = pdevTmp.pldev;
+
+ /* Exchange DHPDEV */
+ ppdev->dhpdev = ppdev2->dhpdev;
+ ppdev2->dhpdev = pdevTmp.dhpdev;
+
+ /* Exchange surfaces and associate them with their new PDEV */
+ ppdev->pSurface = ppdev2->pSurface;
+ ppdev2->pSurface = pdevTmp.pSurface;
+ ppdev->pSurface->SurfObj.hdev = (HDEV)ppdev;
+ ppdev2->pSurface->SurfObj.hdev = (HDEV)ppdev2;
+
+ /* Exchange devinfo */
+ ppdev->devinfo = ppdev2->devinfo;
+ ppdev2->devinfo = pdevTmp.devinfo;
+
+ /* Exchange gdiinfo */
+ ppdev->gdiinfo = ppdev2->gdiinfo;
+ ppdev2->gdiinfo = pdevTmp.gdiinfo;
+
+ /* Exchange DEVMODE */
+ ppdev->pdmwDev = ppdev2->pdmwDev;
+ ppdev2->pdmwDev = pdevTmp.pdmwDev;
+
+ /* Exchange state flags */
+ tmpStateFlags = ppdev->pGraphicsDevice->StateFlags;
+ ppdev->pGraphicsDevice->StateFlags = ppdev2->pGraphicsDevice->StateFlags;
+ ppdev2->pGraphicsDevice->StateFlags = tmpStateFlags;
+
+ /* Notify each driver instance of its new HDEV association */
+ ppdev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
+ ppdev2->pfn.CompletePDEV(ppdev2->dhpdev, (HDEV)ppdev2);
+}
+
+
+BOOL
+NTAPI
+PDEVOBJ_bSwitchMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm)
+{
+ UNICODE_STRING ustrDevice;
+ PPDEVOBJ ppdevTmp;
+ PSURFACE pSurface;
+ BOOL retval = FALSE;
+
+ /* Lock the PDEV */
+ EngAcquireSemaphore(ppdev->hsemDevLock);
+ /* And everything else */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
+
+ // Lookup the GraphicsDevice + select DEVMODE
+ // pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
+
+ /* 1. Temporarily disable the current PDEV */
+ if (!ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE))
+ {
+ DPRINT1("DrvAssertMode failed\n");
+ goto leave;
+ }
+
+ /* 2. Create new PDEV */
+ RtlInitUnicodeString(&ustrDevice, ppdev->pGraphicsDevice->szWinDeviceName);
+ ppdevTmp = EngpCreatePDEV(&ustrDevice, pdm);
+ if (!ppdevTmp)
+ {
+ DPRINT1("Failed to create a new PDEV\n");
+ goto leave;
+ }
+
+ /* 3. Create a new surface */
+ pSurface = PDEVOBJ_pSurface(ppdevTmp);
+ if (!pSurface)
+ {
+ DPRINT1("DrvEnableSurface failed\n");
+ goto leave;
+ }
+
+ /* 4. Get DirectDraw information */
+ /* 5. Enable DirectDraw Not traced */
+ /* 6. Copy old PDEV state to new PDEV instance */
+
+ /* 7. Switch the PDEVs */
+ PDEVOBJ_vSwitchPdev(ppdev, ppdevTmp);
+
+ /* 8. Disable DirectDraw */
+
+ PDEVOBJ_vRelease(ppdevTmp);
+
+ /* Update primary display capabilities */
+ if(ppdev == gppdevPrimary)
+ {
+ PDEVOBJ_vGetDeviceCaps(ppdev, &GdiHandleTable->DevCaps);
+ }
+
+ /* Success! */
+ retval = TRUE;
+leave:
+ /* Unlock PDEV */
+ EngReleaseSemaphore(ppdev->hsemDevLock);
+ EngReleaseSemaphore(ghsemPDEV);
+
+ DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
+
+ return retval;
+}
+
+
+PPDEVOBJ
+NTAPI
+EngpGetPDEV(
+ PUNICODE_STRING pustrDeviceName)
+{
+ UNICODE_STRING ustrCurrent;
+ PPDEVOBJ ppdev;
+ PGRAPHICS_DEVICE pGraphicsDevice;
+
+ /* Acquire PDEV lock */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ /* If no device name is given, ... */
+ if (!pustrDeviceName && gppdevPrimary)
+ {
+ /* ... use the primary PDEV */
+ ppdev = gppdevPrimary;
+
+ /* Reference the pdev */
+ InterlockedIncrement(&ppdev->cPdevRefs);
+ goto leave;
+ }
+
+ /* Loop all present PDEVs */
+ for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
+ {
+ /* Get a pointer to the GRAPHICS_DEVICE */
+ pGraphicsDevice = ppdev->pGraphicsDevice;
+
+ /* Compare the name */
+ RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
+ if (RtlEqualUnicodeString(pustrDeviceName, &ustrCurrent, FALSE))
+ {
+ /* Found! Reference the PDEV */
+ InterlockedIncrement(&ppdev->cPdevRefs);
+ break;
+ }
+ }
+
+ /* Did we find one? */
+ if (!ppdev)
+ {
+ /* No, create a new PDEV */
+ ppdev = EngpCreatePDEV(pustrDeviceName, NULL);
+ if (ppdev)
+ {
+ /* Insert the PDEV into the list */
+ ppdev->ppdevNext = gppdevList;
+ gppdevList = ppdev;
+
+ /* Set as primary PDEV, if we don't have one yet */
+ if (!gppdevPrimary)
+ {
+ gppdevPrimary = ppdev;
+ ppdev->pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE;
+ }
+ }
+ }
+
+leave:
+ /* Release PDEV lock */
+ EngReleaseSemaphore(ghsemPDEV);
+
+ return ppdev;
+}
+
+INT
+NTAPI
+PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev)
+{
+ INT ret = CM_NONE;
+
+ if (ppdev->flFlags & PDEV_DISPLAY)
+ {
+ if (ppdev->devinfo.iDitherFormat == BMF_8BPP ||
+ ppdev->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP)
+ ret = CM_GAMMA_RAMP;
+ }
+
+ if (ppdev->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR)
+ ret |= CM_CMYK_COLOR;
+ if (ppdev->devinfo.flGraphicsCaps & GCAPS_ICM)
+ ret |= CM_DEVICE_ICM;
+
+ return ret;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vGetDeviceCaps(
+ IN PPDEVOBJ ppdev,
+ OUT PDEVCAPS pDevCaps)
+{
+ PGDIINFO pGdiInfo = &ppdev->gdiinfo;
+
+ pDevCaps->ulVersion = pGdiInfo->ulVersion;
+ pDevCaps->ulTechnology = pGdiInfo->ulTechnology;
+ pDevCaps->ulHorzSizeM = (pGdiInfo->ulHorzSize + 500) / 1000;
+ pDevCaps->ulVertSizeM = (pGdiInfo->ulVertSize + 500) / 1000;
+ pDevCaps->ulHorzSize = pGdiInfo->ulHorzSize;
+ pDevCaps->ulVertSize = pGdiInfo->ulVertSize;
+ pDevCaps->ulHorzRes = pGdiInfo->ulHorzRes;
+ pDevCaps->ulVertRes = pGdiInfo->ulVertRes;
+ pDevCaps->ulBitsPixel = pGdiInfo->cBitsPixel;
+ if (pDevCaps->ulBitsPixel == 15) pDevCaps->ulBitsPixel = 16;
+ pDevCaps->ulPlanes = pGdiInfo->cPlanes;
+ pDevCaps->ulNumPens = pGdiInfo->ulNumColors;
+ if (pDevCaps->ulNumPens != -1) pDevCaps->ulNumPens *= 5;
+ pDevCaps->ulNumFonts = 0; // PDEVOBJ_cFonts(ppdev);
+ pDevCaps->ulNumColors = pGdiInfo->ulNumColors;
+ pDevCaps->ulRasterCaps = pGdiInfo->flRaster;
+ pDevCaps->ulAspectX = pGdiInfo->ulAspectX;
+ pDevCaps->ulAspectY = pGdiInfo->ulAspectY;
+ pDevCaps->ulAspectXY = pGdiInfo->ulAspectXY;
+ pDevCaps->ulLogPixelsX = pGdiInfo->ulLogPixelsX;
+ pDevCaps->ulLogPixelsY = pGdiInfo->ulLogPixelsY;
+ pDevCaps->ulSizePalette = pGdiInfo->ulNumPalReg;
+ pDevCaps->ulColorRes = pGdiInfo->ulDACRed +
+ pGdiInfo->ulDACGreen +
+ pGdiInfo->ulDACBlue;
+ pDevCaps->ulPhysicalWidth = pGdiInfo->szlPhysSize.cx;
+ pDevCaps->ulPhysicalHeight = pGdiInfo->szlPhysSize.cy;
+ pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x;
+ pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y;
+ pDevCaps->ulTextCaps = pGdiInfo->flTextCaps;
+ pDevCaps->ulTextCaps |= (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
+ if (pGdiInfo->ulTechnology != DT_PLOTTER)
+ pDevCaps->ulTextCaps |= TC_VA_ABLE;
+ pDevCaps->ulVRefresh = pGdiInfo->ulVRefresh;
+ pDevCaps->ulDesktopHorzRes = pGdiInfo->ulHorzRes;
+ pDevCaps->ulDesktopVertRes = pGdiInfo->ulVertRes;
+ pDevCaps->ulBltAlignment = pGdiInfo->ulBltAlignment;
+ pDevCaps->ulPanningHorzRes = pGdiInfo->ulPanningHorzRes;
+ pDevCaps->ulPanningVertRes = pGdiInfo->ulPanningVertRes;
+ pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment;
+ pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment;
+ pDevCaps->ulShadeBlend = pGdiInfo->flShadeBlend;
+ pDevCaps->ulColorMgmtCaps = PDEVOBJ_iGetColorManagementCaps(ppdev);
+}
+
+
+/** Exported functions ********************************************************/
+
+LPWSTR
+APIENTRY
+EngGetDriverName(IN HDEV hdev)
+{
+ PPDEVOBJ ppdev = (PPDEVOBJ)hdev;
+ PLDEVOBJ pldev;
+
+ if (!hdev)
+ return NULL;
+
+ pldev = ppdev->pldev;
+ ASSERT(pldev);
+
+ if (!pldev->pGdiDriverInfo)
+ return NULL;
+
+ return pldev->pGdiDriverInfo->DriverName.Buffer;
+}
+
+
+INT
+APIENTRY
+NtGdiGetDeviceCaps(
+ HDC hdc,
+ INT Index)
+{
+ PDC pdc;
+ DEVCAPS devcaps;
+
+ /* Lock the given DC */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ /* Get the data */
+ PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+
+ /* Return capability */
+ switch (Index)
+ {
+ case DRIVERVERSION:
+ return devcaps.ulVersion;
+
+ case TECHNOLOGY:
+ return devcaps.ulTechnology;
+
+ case HORZSIZE:
+ return devcaps.ulHorzSize;
+
+ case VERTSIZE:
+ return devcaps.ulVertSize;
+
+ case HORZRES:
+ return devcaps.ulHorzRes;
+
+ case VERTRES:
+ return devcaps.ulVertRes;
+
+ case LOGPIXELSX:
+ return devcaps.ulLogPixelsX;
+
+ case LOGPIXELSY:
+ return devcaps.ulLogPixelsY;
+
+ case BITSPIXEL:
+ return devcaps.ulBitsPixel;
+
+ case PLANES:
+ return devcaps.ulPlanes;
+
+ case NUMBRUSHES:
+ return -1;
+
+ case NUMPENS:
+ return devcaps.ulNumPens;
+
+ case NUMFONTS:
+ return devcaps.ulNumFonts;
+
+ case NUMCOLORS:
+ return devcaps.ulNumColors;
+
+ case ASPECTX:
+ return devcaps.ulAspectX;
+
+ case ASPECTY:
+ return devcaps.ulAspectY;
+
+ case ASPECTXY:
+ return devcaps.ulAspectXY;
+
+ case CLIPCAPS:
+ return CP_RECTANGLE;
+
+ case SIZEPALETTE:
+ return devcaps.ulSizePalette;
+
+ case NUMRESERVED:
+ return 20;
+
+ case COLORRES:
+ return devcaps.ulColorRes;
+
+ case DESKTOPVERTRES:
+ return devcaps.ulVertRes;
+
+ case DESKTOPHORZRES:
+ return devcaps.ulHorzRes;
+
+ case BLTALIGNMENT:
+ return devcaps.ulBltAlignment;
+
+ case SHADEBLENDCAPS:
+ return devcaps.ulShadeBlend;
+
+ case COLORMGMTCAPS:
+ return devcaps.ulColorMgmtCaps;
+
+ case PHYSICALWIDTH:
+ return devcaps.ulPhysicalWidth;
+
+ case PHYSICALHEIGHT:
+ return devcaps.ulPhysicalHeight;
+
+ case PHYSICALOFFSETX:
+ return devcaps.ulPhysicalOffsetX;
+
+ case PHYSICALOFFSETY:
+ return devcaps.ulPhysicalOffsetY;
+
+ case VREFRESH:
+ return devcaps.ulVRefresh;
+
+ case RASTERCAPS:
+ return devcaps.ulRasterCaps;
+
+ case CURVECAPS:
+ return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
+ CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
+
+ case LINECAPS:
+ return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+ LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
+
+ case POLYGONALCAPS:
+ return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
+ PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
+
+ case TEXTCAPS:
+ return devcaps.ulTextCaps;
+
+ case CAPS1:
+ case PDEVICESIZE:
+ case SCALINGFACTORX:
+ case SCALINGFACTORY:
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+
+BOOL
+APIENTRY
+NtGdiGetDeviceCapsAll(
+ IN HDC hDC,
+ OUT PDEVCAPS pDevCaps)
+{
+ PDC pdc;
+ DEVCAPS devcaps;
+ BOOL bResult = TRUE;
+
+ /* Lock the given DC */
+ pdc = DC_LockDc(hDC);
+ if (!pdc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ /* Get the data */
+ PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+
+ /* Copy data to caller */
+ _SEH2_TRY
+ {
+ ProbeForWrite(pDevCaps, sizeof(DEVCAPS), 1);
+ RtlCopyMemory(pDevCaps, &devcaps, sizeof(DEVCAPS));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ bResult = FALSE;
+ }
+ _SEH2_END;
+
+ return bResult;
+}
+
+DHPDEV
+APIENTRY
+NtGdiGetDhpdev(
+ IN HDEV hdev)
+{
+ PPDEVOBJ ppdev;
+ DHPDEV dhpdev = NULL;
+
+ /* Check parameter */
+ if (!hdev || (PCHAR)hdev < (PCHAR)MmSystemRangeStart)
+ return NULL;
+
+ /* Lock PDEV list */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ /* Walk through the list of PDEVs */
+ for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
+ {
+ /* Compare with the given HDEV */
+ if (ppdev == hdev)
+ {
+ /* Found the PDEV! Get it's dhpdev and break */
+ dhpdev = ppdev->dhpdev;
+ break;
+ }
+ }
+
+ /* Unlock PDEV list */
+ EngReleaseSemaphore(ghsemPDEV);
+
+ return dhpdev;
+}
+
+PSIZEL
+FASTCALL
+PDEVOBJ_sizl(PPDEVOBJ ppdev, PSIZEL psizl)
+{
+ if (ppdev->flFlags & PDEV_META_DEVICE)
+ {
+ psizl->cx = ppdev->ulHorzRes;
+ psizl->cy = ppdev->ulVertRes;
+ }
+ else
+ {
+ psizl->cx = ppdev->gdiinfo.ulHorzRes;
+ psizl->cy = ppdev->gdiinfo.ulVertRes;
+ }
+ return psizl;
+}
diff --git a/subsystems/win32/win32k/eng/rlecomp.c b/subsystems/win32/win32k/eng/rlecomp.c
new file mode 100644
index 00000000000..dc8a0712f44
--- /dev/null
+++ b/subsystems/win32/win32k/eng/rlecomp.c
@@ -0,0 +1,99 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: RLE compression
+ * FILE: subsystems/win32k/eng/rlecomp.c
+ * PROGRAMER: Jason Filby
+ */
+
+#include
+
+#define NDEBUG
+#include
+
+enum Rle_EscapeCodes
+{
+ RLE_EOL = 0, /* End of line */
+ RLE_END = 1, /* End of bitmap */
+ RLE_DELTA = 2 /* Delta */
+};
+
+VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format)
+{
+ INT x = 0;
+ INT y = Size.cy - 1;
+ INT c;
+ INT length;
+ INT width;
+ INT height = Size.cy - 1;
+ BYTE *begin = CompressedBits;
+ BYTE *bits = CompressedBits;
+ BYTE *temp;
+ INT shift = 0;
+
+ if (Format == BMF_4RLE)
+ shift = 1;
+ else if(Format != BMF_8RLE)
+ return;
+
+ width = ((Size.cx + shift) >> shift);
+
+ _SEH2_TRY
+ {
+ while (y >= 0)
+ {
+ length = (*bits++) >> shift;
+ if (length)
+ {
+ c = *bits++;
+ while (length--)
+ {
+ if (x >= width) break;
+ temp = UncompressedBits + (((height - y) * Delta) + x);
+ x++;
+ *temp = c;
+ }
+ }
+ else
+ {
+ length = *bits++;
+ switch (length)
+ {
+ case RLE_EOL:
+ x = 0;
+ y--;
+ break;
+ case RLE_END:
+ _SEH2_YIELD(return);
+ case RLE_DELTA:
+ x += (*bits++) >> shift;
+ y -= (*bits++) >> shift;
+ break;
+ default:
+ length = length >> shift;
+ while (length--)
+ {
+ c = *bits++;
+ if (x < width)
+ {
+ temp = UncompressedBits + (((height - y) * Delta) + x);
+ x++;
+ *temp = c;
+ }
+ }
+ if ((bits - begin) & 1)
+ {
+ bits++;
+ }
+ }
+ }
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Decoding error\n");
+ }
+ _SEH2_END;
+
+ return;
+}
diff --git a/subsystems/win32/win32k/eng/semaphor.c b/subsystems/win32/win32k/eng/semaphor.c
index d09d4c9022b..ce9780fc0bf 100644
--- a/subsystems/win32/win32k/eng/semaphor.c
+++ b/subsystems/win32/win32k/eng/semaphor.c
@@ -69,6 +69,19 @@ EngReleaseSemaphore ( IN HSEMAPHORE hsem )
IntGdiReleaseSemaphore ( hsem );
}
+VOID
+NTAPI
+EngAcquireSemaphoreShared(
+ IN HSEMAPHORE hsem)
+{
+ PTHREADINFO pti;
+
+ ASSERT(hsem);
+ ExEnterCriticalRegionAndAcquireResourceShared((PERESOURCE)hsem);
+ pti = PsGetThreadWin32Thread(PsGetCurrentThread());
+ if (pti) ++pti->dwEngAcquireCount;
+}
+
/*
* @implemented
*/
diff --git a/subsystems/win32/win32k/eng/stretchblt.c b/subsystems/win32/win32k/eng/stretchblt.c
index 932d93d5cb4..a6f3d4f4572 100644
--- a/subsystems/win32/win32k/eng/stretchblt.c
+++ b/subsystems/win32/win32k/eng/stretchblt.c
@@ -462,25 +462,16 @@ IntEngStretchBlt(SURFOBJ *psoDest,
/* No success yet */
ret = FALSE;
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
if (UsesSource)
{
psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
- if (psoSource != psoDest)
- {
- SURFACE_LockBitmapBits(psurfSource);
- }
- MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top,
- InputRect.right, InputRect.bottom);
}
/* Prepare color adjustment */
/* Call the driver's DrvStretchBlt if available */
- if (psurfDest->flHooks & HOOK_STRETCHBLTROP)
+ if (psurfDest->flags & HOOK_STRETCHBLTROP)
{
/* Drv->StretchBltROP (look at http://www.osronline.com/ddkx/graphics/ddifncs_0z3b.htm ) */
ret = GDIDEVFUNCS(psoDest).StretchBltROP(psoDest,
@@ -514,17 +505,6 @@ IntEngStretchBlt(SURFOBJ *psoDest,
ROP);
}
- if (UsesSource)
- {
- MouseSafetyOnDrawEnd(psoSource);
- if (psoSource != psoDest)
- {
- SURFACE_UnlockBitmapBits(psurfSource);
- }
- }
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
-
return ret;
}
diff --git a/subsystems/win32/win32k/eng/surface.c b/subsystems/win32/win32k/eng/surface.c
index 126ae9542ce..622b99da2d5 100644
--- a/subsystems/win32/win32k/eng/surface.c
+++ b/subsystems/win32/win32k/eng/surface.c
@@ -3,7 +3,8 @@
* PROJECT: ReactOS kernel
* PURPOSE: GDI Driver Surace Functions
* FILE: subsys/win32k/eng/surface.c
- * PROGRAMER: Jason Filby
+ * PROGRAMERS: Jason Filby
+ * Timo Kreuzer
* REVISION HISTORY:
* 3/7/1999: Created
* 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
@@ -17,43 +18,24 @@
#define NDEBUG
#include
-enum Rle_EscapeCodes
+ULONG giUniqueSurface = 0;
+
+UCHAR
+gajBitsPerFormat[11] =
{
- RLE_EOL = 0, /* End of line */
- RLE_END = 1, /* End of bitmap */
- RLE_DELTA = 2 /* Delta */
+ 0, /* 0: unused */
+ 1, /* 1: BMF_1BPP */
+ 4, /* 2: BMF_4BPP */
+ 8, /* 3: BMF_8BPP */
+ 16, /* 4: BMF_16BPP */
+ 24, /* 5: BMF_24BPP */
+ 32, /* 6: BMF_32BPP */
+ 4, /* 7: BMF_4RLE */
+ 8, /* 8: BMF_8RLE */
+ 0, /* 9: BMF_JPEG */
+ 0, /* 10: BMF_PNG */
};
-INT FASTCALL BitsPerFormat(ULONG Format)
-{
- switch (Format)
- {
- case BMF_1BPP:
- return 1;
-
- case BMF_4BPP:
- /* Fall through */
- case BMF_4RLE:
- return 4;
-
- case BMF_8BPP:
- /* Fall through */
- case BMF_8RLE:
- return 8;
-
- case BMF_16BPP:
- return 16;
-
- case BMF_24BPP:
- return 24;
-
- case BMF_32BPP:
- return 32;
-
- default:
- return 0;
- }
-}
ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
{
@@ -90,534 +72,238 @@ ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
}
}
-BOOL INTERNAL_CALL
+BOOL
+INTERNAL_CALL
SURFACE_Cleanup(PVOID ObjectBody)
{
PSURFACE psurf = (PSURFACE)ObjectBody;
PVOID pvBits = psurf->SurfObj.pvBits;
+ NTSTATUS Status;
- /* If this is an API bitmap, free the bits */
- if (pvBits != NULL &&
- (psurf->flFlags & BITMAPOBJ_IS_APIBITMAP))
+ /* Check if the surface has bits */
+ if (pvBits)
{
- /* Check if we have a DIB section */
- if (psurf->hSecure)
- {
- // FIXME: IMPLEMENT ME!
- // MmUnsecureVirtualMemory(psurf->hSecure);
- if (psurf->hDIBSection)
- {
- /* DIB was created from a section */
- NTSTATUS Status;
+ /* Only bitmaps can have bits */
+ ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
- pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
- Status = ZwUnmapViewOfSection(NtCurrentProcess(), pvBits);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Could not unmap section view!\n");
- // Should we BugCheck here?
- }
- }
- else
+ /* Check if it is a DIB section */
+ if (psurf->hDIBSection)
+ {
+ /* Unsecure the memory */
+ EngUnsecureMem(psurf->hSecure);
+
+ /* Calculate the real start of the section */
+ pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
+
+ /* Unmap the section */
+ Status = MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits);
+ if (!NT_SUCCESS(Status))
{
- /* DIB was allocated */
- EngFreeUserMem(pvBits);
+ DPRINT1("Could not unmap section view!\n");
+ // Should we BugCheck here?
+ ASSERT(FALSE);
}
}
+ else if (psurf->SurfObj.fjBitmap & BMF_USERMEM)
+ {
+ /* Bitmap was allocated from usermode memory */
+ EngFreeUserMem(pvBits);
+ }
+ else if (psurf->SurfObj.fjBitmap & BMF_KMSECTION)
+ {
+ /* Bitmap was allocated from a kernel section */
+ if (!EngFreeSectionMem(NULL, pvBits))
+ {
+ DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits);
+ // Should we BugCheck here?
+ ASSERT(FALSE);
+ }
+ }
+ else if (psurf->SurfObj.fjBitmap & BMF_RLE_HACK)
+ {
+ /* HACK: Free RLE decompressed bits */
+ EngFreeMem(pvBits);
+ }
else
{
- // FIXME: use TAG
- ExFreePool(psurf->SurfObj.pvBits);
- }
-
- if (psurf->hDIBPalette != NULL)
- {
- GreDeleteObject(psurf->hDIBPalette);
+ /* There should be nothing to free */
+ ASSERT(psurf->SurfObj.fjBitmap & BMF_DONT_FREE);
}
}
- if (NULL != psurf->BitsLock)
+ /* Free palette */
+ if(psurf->ppal)
{
- ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
- psurf->BitsLock = NULL;
+ PALETTE_ShareUnlockPalette(psurf->ppal);
}
return TRUE;
}
-BOOL INTERNAL_CALL
-SURFACE_InitBitsLock(PSURFACE psurf)
+
+PSURFACE
+NTAPI
+SURFACE_AllocSurface(
+ IN ULONG iType,
+ IN ULONG cx,
+ IN ULONG cy,
+ IN ULONG iFormat)
{
- psurf->BitsLock = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(FAST_MUTEX),
- TAG_SURFACE);
- if (NULL == psurf->BitsLock)
- {
- return FALSE;
- }
-
- ExInitializeFastMutex(psurf->BitsLock);
-
- return TRUE;
-}
-
-void INTERNAL_CALL
-SURFACE_CleanupBitsLock(PSURFACE psurf)
-{
- if (NULL != psurf->BitsLock)
- {
- ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
- psurf->BitsLock = NULL;
- }
-}
-
-
-/*
- * @implemented
- */
-HBITMAP APIENTRY
-EngCreateDeviceBitmap(IN DHSURF dhsurf,
- IN SIZEL Size,
- IN ULONG Format)
-{
- HBITMAP NewBitmap;
+ PSURFACE psurf;
SURFOBJ *pso;
- NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
- if (!NewBitmap)
+ /* Verify format */
+ if (iFormat < BMF_1BPP || iFormat > BMF_PNG)
{
- DPRINT1("EngCreateBitmap failed\n");
- return 0;
- }
-
- pso = EngLockSurface((HSURF)NewBitmap);
- if (!pso)
- {
- DPRINT1("EngLockSurface failed on newly created bitmap!\n");
- GreDeleteObject(NewBitmap);
+ DPRINT1("Invalid bitmap format: %ld\n", iFormat);
return NULL;
}
- pso->dhsurf = dhsurf;
- EngUnlockSurface(pso);
+ /* Allocate a SURFACE object */
+ psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP);
- return NewBitmap;
+ if (psurf)
+ {
+ /* Initialize the basic fields */
+ pso = &psurf->SurfObj;
+ pso->hsurf = psurf->BaseObject.hHmgr;
+ pso->sizlBitmap.cx = cx;
+ pso->sizlBitmap.cy = cy;
+ pso->iBitmapFormat = iFormat;
+ pso->iType = iType;
+ pso->iUniq = InterlockedIncrement((PLONG)&giUniqueSurface);
+
+ /* Assign a default palette and increment its reference count */
+ psurf->ppal = appalSurfaceDefault[iFormat];
+ GDIOBJ_IncrementShareCount(&psurf->ppal->BaseObject);
+ }
+
+ return psurf;
}
-BOOL DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format)
+BOOL
+NTAPI
+SURFACE_bSetBitmapBits(
+ IN PSURFACE psurf,
+ IN USHORT fjBitmap,
+ IN ULONG ulWidth,
+ IN PVOID pvBits OPTIONAL)
{
- INT x = 0;
- INT y = Size.cy - 1;
- INT c;
- INT length;
- INT width;
- INT height = Size.cy - 1;
- BYTE *begin = CompressedBits;
- BYTE *bits = CompressedBits;
- BYTE *temp;
- INT shift = 0;
+ SURFOBJ *pso = &psurf->SurfObj;
+ PVOID pvSection;
+ UCHAR cBitsPixel;
- if (Format == BMF_4RLE)
- shift = 1;
- else if(Format != BMF_8RLE)
- return FALSE;
+ /* Only bitmaps can have bits */
+ ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
- width = ((Size.cx + shift) >> shift);
+ /* Get bits per pixel from the format */
+ cBitsPixel = gajBitsPerFormat[pso->iBitmapFormat];
- _SEH2_TRY
+ /* Is a width in bytes given? */
+ if (ulWidth)
{
- while (y >= 0)
+ /* Align the width (Windows compatibility, drivers expect that) */
+ ulWidth = WIDTH_BYTES_ALIGN32((ulWidth << 3) / cBitsPixel, cBitsPixel);
+ }
+ else
+ {
+ /* Calculate width from the bitmap width in pixels */
+ ulWidth = WIDTH_BYTES_ALIGN32(pso->sizlBitmap.cx, cBitsPixel);
+ }
+
+ /* Calculate the bitmap size in bytes */
+ pso->cjBits = ulWidth * pso->sizlBitmap.cy;
+
+ /* Did the caller provide bits? */
+ if (pvBits)
+ {
+ /* Yes, so let him free it */
+ fjBitmap |= BMF_DONT_FREE;
+ }
+ else if (pso->cjBits)
+ {
+ /* We must allocate memory, check what kind */
+ if (fjBitmap & BMF_USERMEM)
{
- length = (*bits++) >> shift;
- if (length)
- {
- c = *bits++;
- while (length--)
- {
- if (x >= width) break;
- temp = UncompressedBits + (((height - y) * Delta) + x);
- x++;
- *temp = c;
- }
- }
- else
- {
- length = *bits++;
- switch (length)
- {
- case RLE_EOL:
- x = 0;
- y--;
- break;
- case RLE_END:
- _SEH2_YIELD(return TRUE);
- case RLE_DELTA:
- x += (*bits++) >> shift;
- y -= (*bits++) >> shift;
- break;
- default:
- length = length >> shift;
- while (length--)
- {
- c = *bits++;
- if (x < width)
- {
- temp = UncompressedBits + (((height - y) * Delta) + x);
- x++;
- *temp = c;
- }
- }
- if ((bits - begin) & 1)
- {
- bits++;
- }
- }
- }
+ /* User mode memory was requested */
+ pvBits = EngAllocUserMem(pso->cjBits, 0);
}
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- DPRINT1("Decoding error\n");
- _SEH2_YIELD(return FALSE);
- }
- _SEH2_END;
+ else
+ {
+ /* Use a kernel mode section */
+ fjBitmap |= BMF_KMSECTION;
+ pvBits = EngAllocSectionMem(&pvSection,
+ (fjBitmap & BMF_NOZEROINIT) ?
+ 0 : FL_ZERO_MEMORY,
+ pso->cjBits, TAG_DIB);
+ /* Free the section already, but keep the mapping */
+ if (pvBits) EngFreeSectionMem(pvSection, NULL);
+ }
+
+ /* Check for failure */
+ if (!pvBits) return FALSE;
+ }
+
+ /* Set pvBits, pvScan0 and lDelta */
+ pso->pvBits = pvBits;
+ if (fjBitmap & BMF_TOPDOWN)
+ {
+ /* Topdown is the normal way */
+ pso->pvScan0 = pso->pvBits;
+ pso->lDelta = ulWidth;
+ }
+ else
+ {
+ /* Inversed bitmap (bottom up) */
+ pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ulWidth);
+ pso->lDelta = -ulWidth;
+ }
+
+ pso->fjBitmap = fjBitmap;
+
+ /* Success */
return TRUE;
}
-HBITMAP FASTCALL
-IntCreateBitmap(IN SIZEL Size,
- IN LONG Width,
- IN ULONG Format,
- IN ULONG Flags,
- IN PVOID Bits)
+HBITMAP
+APIENTRY
+EngCreateBitmap(
+ IN SIZEL sizl,
+ IN LONG lWidth,
+ IN ULONG iFormat,
+ IN ULONG fl,
+ IN PVOID pvBits)
{
+ PSURFACE psurf;
HBITMAP hbmp;
- SURFOBJ *pso;
- PSURFACE psurf;
- PVOID UncompressedBits;
- ULONG UncompressedFormat;
- if (Format == 0)
- return 0;
-
- psurf = SURFACE_AllocSurfaceWithHandle();
- if (psurf == NULL)
- {
- return 0;
- }
- hbmp = psurf->BaseObject.hHmgr;
-
- if (! SURFACE_InitBitsLock(psurf))
- {
- SURFACE_UnlockSurface(psurf);
- SURFACE_FreeSurfaceByHandle(hbmp);
- return 0;
- }
- pso = &psurf->SurfObj;
-
- if (Format == BMF_4RLE)
- {
- pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP));
- pso->cjBits = pso->lDelta * Size.cy;
- UncompressedFormat = BMF_4BPP;
- UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
- DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format);
- }
- else if (Format == BMF_8RLE)
- {
- pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP));
- pso->cjBits = pso->lDelta * Size.cy;
- UncompressedFormat = BMF_8BPP;
- UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
- DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format);
- }
- else
- {
- pso->lDelta = abs(Width);
- pso->cjBits = pso->lDelta * Size.cy;
- UncompressedBits = Bits;
- UncompressedFormat = Format;
- }
-
- if (UncompressedBits != NULL)
- {
- pso->pvBits = UncompressedBits;
- }
- else
- {
- if (pso->cjBits == 0)
- {
- pso->pvBits = NULL;
- }
- else
- {
- if (0 != (Flags & BMF_USERMEM))
- {
- pso->pvBits = EngAllocUserMem(pso->cjBits, 0);
- }
- else
- {
- pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ?
- 0 : FL_ZERO_MEMORY,
- pso->cjBits, TAG_DIB);
- }
- if (pso->pvBits == NULL)
- {
- SURFACE_UnlockSurface(psurf);
- SURFACE_FreeSurfaceByHandle(hbmp);
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
- }
- }
-
- if (0 == (Flags & BMF_TOPDOWN))
- {
- pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta);
- pso->lDelta = - pso->lDelta;
- }
- else
- {
- pso->pvScan0 = pso->pvBits;
- }
-
- pso->dhsurf = 0; /* device managed surface */
- pso->hsurf = (HSURF)hbmp;
- pso->dhpdev = NULL;
- pso->hdev = NULL;
- pso->sizlBitmap = Size;
- pso->iBitmapFormat = UncompressedFormat;
- pso->iType = STYPE_BITMAP;
- pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
- pso->iUniq = 0;
-
- psurf->flHooks = 0;
- psurf->flFlags = 0;
- psurf->dimension.cx = 0;
- psurf->dimension.cy = 0;
-
- psurf->hSecure = NULL;
- psurf->hDIBSection = NULL;
-
- SURFACE_UnlockSurface(psurf);
-
- return hbmp;
-}
-
-/* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */
-typedef struct _DEVBITMAPINFO
-{
- ULONG Format;
- ULONG Width;
- ULONG Height;
- ULONG Flags;
- ULONG Size;
-} DEVBITMAPINFO, *PDEVBITMAPINFO;
-
-SURFOBJ*
-FASTCALL
-SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
- IN PVOID Bits)
-{
- BOOLEAN Compressed = FALSE;
- ULONG ScanLine = 0; // Compiler is dumb
- ULONG Size;
- SURFOBJ *pso;
- PSURFACE psurf;
- SIZEL LocalSize;
- BOOLEAN AllocatedLocally = FALSE;
- PVOID DecompressedBits = NULL;
-
- /*
- * First, check the format so we can get the aligned scanline width.
- * RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines
- * since they are compressed surfaces!
- */
- switch (BitmapInfo->Format)
- {
- case BMF_1BPP:
- ScanLine = ((BitmapInfo->Width + 31) & ~31) >> 3;
- break;
-
- case BMF_4BPP:
- ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
- break;
-
- case BMF_8BPP:
- ScanLine = (BitmapInfo->Width + 3) & ~3;
- break;
-
- case BMF_16BPP:
- ScanLine = ((BitmapInfo->Width + 1) & ~1) << 1;
- break;
-
- case BMF_24BPP:
- ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3;
- break;
-
- case BMF_32BPP:
- ScanLine = BitmapInfo->Width << 2;
- break;
-
- case BMF_8RLE:
- ScanLine = (BitmapInfo->Width + 3) & ~3;
- Compressed = TRUE;
- break;
- case BMF_4RLE:
- ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
- Compressed = TRUE;
- break;
-
- case BMF_JPEG:
- case BMF_PNG:
- ASSERT(FALSE); // ENGDDI shouldn't be creating PNGs for drivers ;-)
- DPRINT1("No support for JPEG and PNG formats\n");
- return NULL;
-
- default:
- DPRINT1("Invalid bitmap format\n");
- return NULL;
- }
-
- /* Save local bitmap size */
- LocalSize.cy = BitmapInfo->Height;
- LocalSize.cx = BitmapInfo->Width;
-
- /* Does the device manage its own surface? */
- if (!Bits)
- {
- /* We need to allocate bits for the caller, figure out the size */
- if (Compressed)
- {
- /* Note: we should not be seeing this scenario from ENGDDI */
- ASSERT(FALSE);
- DPRINT1("RLE compressed bitmap requested with no valid bitmap bits\n");
- return NULL;
- }
- else
- {
- /* The height times the bytes for each scanline */
- Size = BitmapInfo->Height * ScanLine;
- }
-
- if (Size)
- {
- /* Check for allocation flag */
- if (BitmapInfo->Flags & BMF_USERMEM)
- {
- /* Get the bits from user-mode memory */
- Bits = EngAllocUserMem(Size, 'mbuG');
- }
- else
- {
- /* Get kernel bits (zeroed out if requested) */
- Bits = EngAllocMem((BitmapInfo->Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY,
- Size,
- TAG_DIB);
- }
- AllocatedLocally = TRUE;
- /* Bail out if that failed */
- if (!Bits) return NULL;
- }
- }
- else
- {
- /* Should not have asked for user memory */
- ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
-
- if (Compressed)
- {
- DecompressedBits = EngAllocMem(FL_ZERO_MEMORY, BitmapInfo->Height * ScanLine, TAG_DIB);
-
- if(!DecompressedBits)
- return NULL;
-
- if(!DecompressBitmap(LocalSize, (BYTE *)Bits, (BYTE *)DecompressedBits, ScanLine, BitmapInfo->Format))
- {
- EngFreeMem(DecompressedBits);
- return NULL;
- }
-
- BitmapInfo->Format = (BitmapInfo->Format == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
- }
- }
-
- /* Allocate the actual surface object structure */
- psurf = SURFACE_AllocSurfaceWithHandle();
+ /* Allocate a surface */
+ psurf = SURFACE_AllocSurface(STYPE_BITMAP, sizl.cx, sizl.cy, iFormat);
if (!psurf)
{
- if(Bits && AllocatedLocally)
- {
- if(BitmapInfo->Flags & BMF_USERMEM)
- EngFreeUserMem(Bits);
- else
- EngFreeMem(Bits);
- }
- if (DecompressedBits)
- EngFreeMem(DecompressedBits);
+ DPRINT1("SURFACE_AllocSurface failed.\n");
return NULL;
}
- /* Lock down the surface */
- if (!SURFACE_InitBitsLock(psurf))
+ /* Get the handle for the bitmap */
+ hbmp = (HBITMAP)psurf->SurfObj.hsurf;
+
+ /* Set the bitmap bits */
+ if (!SURFACE_bSetBitmapBits(psurf, fl, lWidth, pvBits))
{
/* Bail out if that failed */
- SURFACE_UnlockSurface(psurf);
- SURFACE_FreeSurfaceByHandle(psurf->BaseObject.hHmgr);
+ DPRINT1("SURFACE_bSetBitmapBits failed.\n");
+ SURFACE_FreeSurfaceByHandle(hbmp);
return NULL;
}
- /* We should now have our surface object */
- pso = &psurf->SurfObj;
+ /* Set public ownership */
+ GDIOBJ_SetOwnership(hbmp, NULL);
- /* Save format and flags */
- pso->iBitmapFormat = BitmapInfo->Format;
- pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM);
-
- /* Save size and type */
- pso->sizlBitmap = LocalSize;
- pso->iType = STYPE_BITMAP;
-
- /* Device-managed surface, no flags or dimension */
- pso->dhsurf = 0;
- pso->dhpdev = NULL;
- pso->hdev = NULL;
- psurf->flFlags = 0;
- psurf->dimension.cx = 0;
- psurf->dimension.cy = 0;
- psurf->hSecure = NULL;
- psurf->hDIBSection = NULL;
- psurf->flHooks = 0;
-
- /* Set bits */
- if(Compressed)
- pso->pvBits = DecompressedBits;
- else
- pso->pvBits = Bits;
-
- /* Number of bits is based on the height times the scanline */
- pso->cjBits = BitmapInfo->Height * ScanLine;
- if (BitmapInfo->Flags & BMF_TOPDOWN)
- {
- /* For topdown, the base address starts with the bits */
- pso->pvScan0 = pso->pvBits;
- pso->lDelta = ScanLine;
- }
- else
- {
- /* Otherwise we start with the end and go up */
- pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine);
- pso->lDelta = -ScanLine;
- }
-
- /* Finally set the handle and uniq */
- pso->hsurf = (HSURF)psurf->BaseObject.hHmgr;
- pso->iUniq = 0;
-
- /* Unlock and return the surface */
+ /* Unlock the surface and return */
SURFACE_UnlockSurface(psurf);
- return pso;
+ return hbmp;
}
/*
@@ -625,108 +311,66 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
*/
HBITMAP
APIENTRY
-EngCreateBitmap(IN SIZEL Size,
- IN LONG Width,
- IN ULONG Format,
- IN ULONG Flags,
- IN PVOID Bits)
+EngCreateDeviceBitmap(
+ IN DHSURF dhsurf,
+ IN SIZEL sizl,
+ IN ULONG iFormat)
{
- SURFOBJ* Surface;
- DEVBITMAPINFO BitmapInfo;
-
- /* Capture the parameters */
- BitmapInfo.Format = Format;
- BitmapInfo.Width = Size.cx;
- BitmapInfo.Height = Size.cy;
- BitmapInfo.Flags = Flags;
-
- /*
- * If the display driver supports framebuffer access, use the scanline width
- * to determine the actual width of the bitmap, and convert it to pels instead
- * of bytes.
- */
- if ((Bits) && (Width))
- {
- switch (BitmapInfo.Format)
- {
- /* Do the conversion for each bit depth we support */
- case BMF_1BPP:
- BitmapInfo.Width = Width * 8;
- break;
- case BMF_4BPP:
- BitmapInfo.Width = Width * 2;
- break;
- case BMF_8BPP:
- BitmapInfo.Width = Width;
- break;
- case BMF_16BPP:
- BitmapInfo.Width = Width / 2;
- break;
- case BMF_24BPP:
- BitmapInfo.Width = Width / 3;
- break;
- case BMF_32BPP:
- BitmapInfo.Width = Width / 4;
- break;
- }
- }
-
- /* Now create the surface */
- Surface = SURFMEM_bCreateDib(&BitmapInfo, Bits);
- if (!Surface) return 0;
-
- /* Set public ownership and reutrn the handle */
- GDIOBJ_SetOwnership(Surface->hsurf, NULL);
- return Surface->hsurf;
-}
-
-/*
- * @unimplemented
- */
-HSURF APIENTRY
-EngCreateDeviceSurface(IN DHSURF dhsurf,
- IN SIZEL Size,
- IN ULONG Format)
-{
- HSURF hsurf;
- SURFOBJ *pso;
PSURFACE psurf;
+ HBITMAP hbmp;
- psurf = SURFACE_AllocSurfaceWithHandle();
+ /* Allocate a surface */
+ psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP, sizl.cx, sizl.cy, iFormat);
if (!psurf)
{
return 0;
}
- hsurf = psurf->BaseObject.hHmgr;
- GDIOBJ_SetOwnership(hsurf, NULL);
+ /* Set the device handle */
+ psurf->SurfObj.dhsurf = dhsurf;
- if (!SURFACE_InitBitsLock(psurf))
+ /* Get the handle for the bitmap */
+ hbmp = (HBITMAP)psurf->SurfObj.hsurf;
+
+ /* Set public ownership */
+ GDIOBJ_SetOwnership(hbmp, NULL);
+
+ /* Unlock the surface and return */
+ SURFACE_UnlockSurface(psurf);
+ return hbmp;
+}
+
+HSURF
+APIENTRY
+EngCreateDeviceSurface(
+ IN DHSURF dhsurf,
+ IN SIZEL sizl,
+ IN ULONG iFormat)
+{
+ PSURFACE psurf;
+ HSURF hsurf;
+
+ /* Allocate a surface */
+ psurf = SURFACE_AllocSurface(STYPE_DEVICE, sizl.cx, sizl.cy, iFormat);
+ if (!psurf)
{
- SURFACE_UnlockSurface(psurf);
- SURFACE_FreeSurfaceByHandle(hsurf);
return 0;
}
- pso = &psurf->SurfObj;
- pso->dhsurf = dhsurf;
- pso->hsurf = hsurf;
- pso->sizlBitmap = Size;
- pso->iBitmapFormat = Format;
- pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
- pso->iType = STYPE_DEVICE;
- pso->iUniq = 0;
+ /* Set the device handle */
+ psurf->SurfObj.dhsurf = dhsurf;
- psurf->flHooks = 0;
+ /* Get the handle for the surface */
+ hsurf = psurf->SurfObj.hsurf;
+ /* Set public ownership */
+ GDIOBJ_SetOwnership(hsurf, NULL);
+
+ /* Unlock the surface and return */
SURFACE_UnlockSurface(psurf);
-
return hsurf;
}
-/*
- * @implemented
- */
BOOL
APIENTRY
EngAssociateSurface(
@@ -753,17 +397,19 @@ EngAssociateSurface(
pso->dhpdev = ppdev->dhpdev;
/* Hook up specified functions */
- psurf->flHooks = flHooks;
+ psurf->flags &= ~HOOK_FLAGS;
+ psurf->flags |= (flHooks & HOOK_FLAGS);
+
+ /* Get palette */
+ psurf->ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
SURFACE_UnlockSurface(psurf);
return TRUE;
}
-/*
- * @implemented
- */
-BOOL APIENTRY
+BOOL
+APIENTRY
EngModifySurface(
IN HSURF hsurf,
IN HDEV hdev,
@@ -795,17 +441,20 @@ EngModifySurface(
pso->dhpdev = ppdev->dhpdev;
/* Hook up specified functions */
- psurf->flHooks = flHooks;
+ psurf->flags &= ~HOOK_FLAGS;
+ psurf->flags |= (flHooks & HOOK_FLAGS);
+
+ /* Get palette */
+ psurf->ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
SURFACE_UnlockSurface(psurf);
return TRUE;
}
-/*
- * @implemented
- */
-BOOL APIENTRY
+
+BOOL
+APIENTRY
EngDeleteSurface(IN HSURF hsurf)
{
GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
@@ -813,17 +462,16 @@ EngDeleteSurface(IN HSURF hsurf)
return TRUE;
}
-/*
- * @implemented
- */
-BOOL APIENTRY
-EngEraseSurface(SURFOBJ *pso,
- RECTL *Rect,
- ULONG iColor)
+BOOL
+APIENTRY
+EngEraseSurface(
+ SURFOBJ *pso,
+ RECTL *prcl,
+ ULONG iColor)
{
ASSERT(pso);
- ASSERT(Rect);
- return FillSolid(pso, Rect, iColor);
+ ASSERT(prcl);
+ return FillSolid(pso, prcl, iColor);
}
/*
@@ -836,10 +484,8 @@ NtGdiEngLockSurface(IN HSURF hsurf)
}
-/*
- * @implemented
- */
-SURFOBJ * APIENTRY
+SURFOBJ *
+APIENTRY
EngLockSurface(IN HSURF hsurf)
{
SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP);
@@ -850,20 +496,15 @@ EngLockSurface(IN HSURF hsurf)
return NULL;
}
-
-/*
- * @implemented
- */
-VOID APIENTRY
+VOID
+APIENTRY
NtGdiEngUnlockSurface(IN SURFOBJ *pso)
{
EngUnlockSurface(pso);
}
-/*
- * @implemented
- */
-VOID APIENTRY
+VOID
+APIENTRY
EngUnlockSurface(IN SURFOBJ *pso)
{
if (pso != NULL)
@@ -873,5 +514,4 @@ EngUnlockSurface(IN SURFOBJ *pso)
}
}
-
/* EOF */
diff --git a/subsystems/win32/win32k/eng/transblt.c b/subsystems/win32/win32k/eng/transblt.c
index bca22440edd..0bfc145eb94 100644
--- a/subsystems/win32/win32k/eng/transblt.c
+++ b/subsystems/win32/win32k/eng/transblt.c
@@ -76,7 +76,7 @@ EngTransparentBlt(SURFOBJ *psoDest,
OutputRect.top = DestRect->bottom;
OutputRect.bottom = DestRect->top;
}
-
+
if(Clip)
{
if(OutputRect.left < Clip->rclBounds.left)
@@ -284,17 +284,7 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
OutputRect = InputClippedRect;
}
- if(psoSource != psoDest)
- {
- SURFACE_LockBitmapBits(psurfSource);
- MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top,
- InputRect.right, InputRect.bottom);
- }
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
-
- if(psurfDest->flHooks & HOOK_TRANSPARENTBLT)
+ if(psurfDest->flags & HOOK_TRANSPARENTBLT)
{
Ret = GDIDEVFUNCS(psoDest).TransparentBlt(
psoDest, psoSource, Clip, ColorTranslation, &OutputRect,
@@ -309,14 +299,6 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
&OutputRect, &InputRect, iTransColor, Reserved);
}
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
- if(psoSource != psoDest)
- {
- MouseSafetyOnDrawEnd(psoSource);
- SURFACE_UnlockBitmapBits(psurfSource);
- }
-
return Ret;
}
diff --git a/subsystems/win32/win32k/eng/xlate.c b/subsystems/win32/win32k/eng/xlate.c
index 77f2a213ae1..f15d757cb3d 100644
--- a/subsystems/win32/win32k/eng/xlate.c
+++ b/subsystems/win32/win32k/eng/xlate.c
@@ -64,7 +64,7 @@ EXLATEOBJ_iXlateRGBtoBGR(PEXLATEOBJ pxlo, ULONG iColor)
{
ULONG iNewColor;
- /* Copy green and alpha */
+ /* Copy green */
iNewColor = iColor & 0xff00ff00;
/* Mask red and blue */
@@ -362,19 +362,19 @@ EXLATEOBJ_vInitialize(
EXLATEOBJ_vInitTrivial(pexlo);
if (ppalDst == ppalSrc || !ppalSrc || !ppalDst ||
- ((ppalDst->Mode == PAL_RGB || ppalDst->Mode == PAL_BGR) &&
- ppalDst->Mode == ppalSrc->Mode))
+ ((ppalDst->flFlags == PAL_RGB || ppalDst->flFlags == PAL_BGR) &&
+ ppalDst->flFlags == ppalSrc->flFlags))
{
return;
}
pexlo->ppalSrc = ppalSrc;
pexlo->ppalDst = ppalDst;
- pexlo->xlo.iSrcType = ppalSrc->Mode;
- pexlo->xlo.iDstType = ppalDst->Mode;
+ pexlo->xlo.iSrcType = ppalSrc->flFlags;
+ pexlo->xlo.iDstType = ppalDst->flFlags;
/* Chack if both of the pallettes are indexed */
- if (!(ppalSrc->Mode & PAL_INDEXED) || !(ppalDst->Mode & PAL_INDEXED))
+ if (!(ppalSrc->flFlags & PAL_INDEXED) || !(ppalDst->flFlags & PAL_INDEXED))
{
/* At least one palette is not indexed, calculate shifts/masks */
ULONG aulMasksSrc[3], aulMasksDst[3];
@@ -391,10 +391,10 @@ EXLATEOBJ_vInitialize(
pexlo->ulBlueShift = CalculateShift(aulMasksSrc[2], aulMasksDst[2]);
}
- if (ppalSrc->Mode & PAL_MONOCHROME)
+ if (ppalSrc->flFlags & PAL_MONOCHROME)
{
/* This is a monochrome palette */
- if (!(ppalDst->Mode & PAL_MONOCHROME))
+ if (!(ppalDst->flFlags & PAL_MONOCHROME))
{
/* Mono to color, use the dest DC's fore and back color */
pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
@@ -406,28 +406,28 @@ EXLATEOBJ_vInitialize(
PALETTE_ulGetNearestIndex(ppalDst, crDstBackColor);
}
}
- else if (ppalDst->Mode & PAL_MONOCHROME)
+ else if (ppalDst->flFlags & PAL_MONOCHROME)
{
pexlo->pfnXlate = EXLATEOBJ_iXlateToMono;
pexlo->xlo.flXlate |= XO_TO_MONO;
pexlo->xlo.cEntries = 1;
- if (ppalSrc->Mode & PAL_INDEXED)
+ if (ppalSrc->flFlags & PAL_INDEXED)
{
pexlo->aulXlate[0] =
PALETTE_ulGetNearestPaletteIndex(ppalSrc, crSrcBackColor);
}
- else if (ppalSrc->Mode & PAL_BGR)
+ else if (ppalSrc->flFlags & PAL_BGR)
{
pexlo->aulXlate[0] = crSrcBackColor;
}
- else if (ppalSrc->Mode & PAL_RGB)
+ else if (ppalSrc->flFlags & PAL_RGB)
{
pexlo->aulXlate[0] = RGB(GetBValue(crSrcBackColor),
GetGValue(crSrcBackColor),
GetRValue(crSrcBackColor));
}
- else if (ppalSrc->Mode & PAL_BITFIELDS)
+ else if (ppalSrc->flFlags & PAL_BITFIELDS)
{
PALETTE_vGetBitMasks(ppalSrc, &pexlo->ulRedMask);
pexlo->ulRedShift = CalculateShift(0xFF, pexlo->ulRedMask);
@@ -437,7 +437,7 @@ EXLATEOBJ_vInitialize(
pexlo->aulXlate[0] = EXLATEOBJ_iXlateShiftAndMask(pexlo, crSrcBackColor);
}
}
- else if (ppalSrc->Mode & PAL_INDEXED)
+ else if (ppalSrc->flFlags & PAL_INDEXED)
{
cEntries = ppalSrc->NumColors;
@@ -458,7 +458,7 @@ EXLATEOBJ_vInitialize(
pexlo->xlo.cEntries = cEntries;
pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
{
pexlo->xlo.flXlate |= XO_TABLE;
@@ -504,78 +504,78 @@ EXLATEOBJ_vInitialize(
}
}
}
- else if (ppalSrc->Mode & PAL_RGB)
+ else if (ppalSrc->flFlags & PAL_RGB)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoPal;
- else if (ppalDst->Mode & PAL_BGR)
+ else if (ppalDst->flFlags & PAL_BGR)
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
- else if (ppalDst->Mode & PAL_RGB16_555)
+ else if (ppalDst->flFlags & PAL_RGB16_555)
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto555;
- else if (ppalDst->Mode & PAL_RGB16_565)
+ else if (ppalDst->flFlags & PAL_RGB16_565)
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto565;
- else if (ppalDst->Mode & PAL_BITFIELDS)
+ else if (ppalDst->flFlags & PAL_BITFIELDS)
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
}
- else if (ppalSrc->Mode & PAL_BGR)
+ else if (ppalSrc->flFlags & PAL_BGR)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
- else if (ppalDst->Mode & PAL_RGB)
+ else if (ppalDst->flFlags & PAL_RGB)
/* The inverse function works the same */
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
- else if (ppalDst->Mode & PAL_RGB16_555)
+ else if (ppalDst->flFlags & PAL_RGB16_555)
pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto555;
- else if (ppalDst->Mode & PAL_RGB16_565)
+ else if (ppalDst->flFlags & PAL_RGB16_565)
pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto565;
- else if (ppalDst->Mode & PAL_BITFIELDS)
+ else if (ppalDst->flFlags & PAL_BITFIELDS)
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
}
- else if (ppalSrc->Mode & PAL_RGB16_555)
+ else if (ppalSrc->flFlags & PAL_RGB16_555)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlate555toPal;
- else if (ppalDst->Mode & PAL_RGB)
+ else if (ppalDst->flFlags & PAL_RGB)
pexlo->pfnXlate = EXLATEOBJ_iXlate555toRGB;
- else if (ppalDst->Mode & PAL_BGR)
+ else if (ppalDst->flFlags & PAL_BGR)
pexlo->pfnXlate = EXLATEOBJ_iXlate555toBGR;
- else if (ppalDst->Mode & PAL_RGB16_565)
+ else if (ppalDst->flFlags & PAL_RGB16_565)
pexlo->pfnXlate = EXLATEOBJ_iXlate555to565;
- else if (ppalDst->Mode & PAL_BITFIELDS)
+ else if (ppalDst->flFlags & PAL_BITFIELDS)
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
}
- else if (ppalSrc->Mode & PAL_RGB16_565)
+ else if (ppalSrc->flFlags & PAL_RGB16_565)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlate565toPal;
- else if (ppalDst->Mode & PAL_RGB)
+ else if (ppalDst->flFlags & PAL_RGB)
pexlo->pfnXlate = EXLATEOBJ_iXlate565toRGB;
- else if (ppalDst->Mode & PAL_BGR)
+ else if (ppalDst->flFlags & PAL_BGR)
pexlo->pfnXlate = EXLATEOBJ_iXlate565toBGR;
- else if (ppalDst->Mode & PAL_RGB16_555)
+ else if (ppalDst->flFlags & PAL_RGB16_555)
pexlo->pfnXlate = EXLATEOBJ_iXlate565to555;
- else if (ppalDst->Mode & PAL_BITFIELDS)
+ else if (ppalDst->flFlags & PAL_BITFIELDS)
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
}
- else if (ppalSrc->Mode & PAL_BITFIELDS)
+ else if (ppalSrc->flFlags & PAL_BITFIELDS)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
else
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
@@ -603,157 +603,24 @@ EXLATEOBJ_vInitXlateFromDCs(
PDC pdcDst)
{
PSURFACE psurfDst, psurfSrc;
- HPALETTE hpalSrc, hpalDst;
- PPALETTE ppalSrc, ppalDst, ppalDstDc;
-
- DPRINT("Enter EXLATEOBJ_vInitXlateFromDCs\n");
-
- /* Do basic init */
- EXLATEOBJ_vInitTrivial(pexlo);
psurfDst = pdcDst->dclevel.pSurface;
psurfSrc = pdcSrc->dclevel.pSurface;
+ /* Check for trivial color translation */
if (psurfDst == psurfSrc)
{
+ EXLATEOBJ_vInitTrivial(pexlo);
return;
}
- hpalSrc = psurfSrc->hDIBPalette;
- if (!hpalSrc)
- hpalSrc = pPrimarySurface->devinfo.hpalDefault;
-
- ppalSrc = PALETTE_ShareLockPalette(hpalSrc);
- if (!ppalSrc)
- return;
-
- hpalDst = psurfDst->hDIBPalette;
- if (!hpalDst) hpalDst = pPrimarySurface->devinfo.hpalDefault;
-
- ppalDst = PALETTE_ShareLockPalette(hpalDst);
- if (!ppalDst)
- {
- PALETTE_ShareUnlockPalette(ppalSrc);
- return;
- }
-
- ppalDstDc = pdcDst->dclevel.ppal;
- ASSERT(ppalDstDc);
-
- /* KB41464 details how to convert between mono and color */
- if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP)
- {
- if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP)
- {
- // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
- EXLATEOBJ_vInitialize(pexlo,
- ppalSrc,
- &gpalMono,
- pdcSrc->pdcattr->crBackgroundClr,
- pdcDst->pdcattr->crBackgroundClr,
- pdcDst->pdcattr->crForegroundClr);
- }
- }
- else if (psurfSrc->SurfObj.iBitmapFormat == BMF_1BPP && !psurfSrc->hSecure)
- {
- // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
- EXLATEOBJ_vInitialize(pexlo,
- &gpalMono,
- ppalDst,
- 0,
- pdcDst->pdcattr->crBackgroundClr,
- pdcDst->pdcattr->crForegroundClr);
- }
- else
- {
- EXLATEOBJ_vInitialize(pexlo, ppalSrc, ppalDst, 0, 0, 0);
- }
-
- PALETTE_ShareUnlockPalette(ppalDst);
- PALETTE_ShareUnlockPalette(ppalSrc);
-}
-
-
-VOID
-NTAPI
-EXLATEOBJ_vInitBrushXlate(
- PEXLATEOBJ pexlo,
- BRUSH *pbrush,
- SURFACE *psurfDst,
- COLORREF crForegroundClr,
- COLORREF crBackgroundClr)
-{
- HPALETTE hpalDst = NULL;
- PPALETTE ppalDst, ppalPattern;
- SURFACE *psurfPattern;
-
- ASSERT(pexlo);
- ASSERT(pbrush);
- ASSERT(psurfDst);
- ASSERT(!(pbrush->flAttrs & (GDIBRUSH_IS_SOLID | GDIBRUSH_IS_NULL)));
-
- EXLATEOBJ_vInitTrivial(pexlo);
-
- hpalDst = psurfDst->hDIBPalette;
- if (!hpalDst) hpalDst = pPrimarySurface->devinfo.hpalDefault;
- ppalDst = PALETTE_ShareLockPalette(hpalDst);
- if (!ppalDst)
- {
- DPRINT1("No ppalDst!\n");
- return;
- }
-
- psurfPattern = SURFACE_ShareLockSurface(pbrush->hbmPattern);
- if (!psurfPattern)
- {
- PALETTE_ShareUnlockPalette(ppalDst);
- return;
- }
-
-#if 0
- if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP)
- {
- if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP)
- {
- // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
- EXLATEOBJ_vInitialize(pexlo,
- ppalSrc,
- &gpalMono,
- 0,
- crBackgroundClr,
- crForegroundClr);
- }
- }
- else
-#endif
- if (psurfPattern->SurfObj.iBitmapFormat == BMF_1BPP &&
- !(pbrush->flAttrs & GDIBRUSH_IS_DIB))
- {
- /* Special case: 1 bpp pattern, not a DIB brush. */
- if (psurfDst->SurfObj.iBitmapFormat != BMF_1BPP)
- {
- // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
- EXLATEOBJ_vInitialize(pexlo,
- &gpalMono,
- ppalDst,
- 0,
- crBackgroundClr,
- crForegroundClr);
- }
- }
- else
- {
- /* Default: use the patterns' palette */
- ppalPattern = PALETTE_LockPalette(psurfPattern->hDIBPalette);
- if (ppalPattern)
- {
- EXLATEOBJ_vInitialize(pexlo, &gpalRGB, ppalDst, 0, 0, 0);
- PALETTE_UnlockPalette(ppalPattern);
- }
- }
-
- PALETTE_ShareUnlockPalette(ppalDst);
- SURFACE_ShareUnlockSurface(psurfPattern);
+ /* Normal initialisation. No surface means DEFAULT_BITMAP */
+ EXLATEOBJ_vInitialize(pexlo,
+ psurfSrc ? psurfSrc->ppal : &gpalMono,
+ psurfDst ? psurfDst->ppal : &gpalMono,
+ pdcSrc->pdcattr->crBackgroundClr,
+ pdcDst->pdcattr->crBackgroundClr,
+ pdcDst->pdcattr->crForegroundClr);
}
VOID
@@ -767,11 +634,13 @@ EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo)
pexlo->xlo.pulXlate = pexlo->aulXlate;
}
-VOID
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitXlateImpl(VOID)
{
-
EXLATEOBJ_vInitTrivial(&gexloTrivial);
+ return STATUS_SUCCESS;
}
@@ -827,9 +696,9 @@ XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut)
/* Verify palette type match */
if (!ppal ||
((iPal == XO_SRCPALETTE || iPal == XO_DESTPALETTE)
- && !(ppal->Mode & PAL_INDEXED)) ||
+ && !(ppal->flFlags & PAL_INDEXED)) ||
((iPal == XO_SRCBITFIELDS || iPal == XO_DESTBITFIELDS)
- && !(ppal->Mode & PAL_BITFIELDS)))
+ && !(ppal->flFlags & PAL_BITFIELDS)))
{
return 0;
}
@@ -840,7 +709,7 @@ XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut)
}
/* Copy the values into the buffer */
- if (ppal->Mode & PAL_INDEXED)
+ if (ppal->flFlags & PAL_INDEXED)
{
cPal = min(cPal, ppal->NumColors);
for (i = 0; i < cPal; i++)
diff --git a/subsystems/win32/win32k/include/accelerator.h b/subsystems/win32/win32k/include/accelerator.h
index f9aea474215..48de41329da 100644
--- a/subsystems/win32/win32k/include/accelerator.h
+++ b/subsystems/win32/win32k/include/accelerator.h
@@ -11,7 +11,9 @@ typedef struct _ACCELERATOR_TABLE
LPACCEL Table;
} ACCELERATOR_TABLE, *PACCELERATOR_TABLE;
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitAcceleratorImpl(VOID);
NTSTATUS FASTCALL
diff --git a/subsystems/win32/win32k/include/bitmaps.h b/subsystems/win32/win32k/include/bitmaps.h
index 6a5e731c375..802028d4afa 100644
--- a/subsystems/win32/win32k/include/bitmaps.h
+++ b/subsystems/win32/win32k/include/bitmaps.h
@@ -2,11 +2,47 @@
#include "surface.h"
-INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth);
-int APIENTRY DIB_GetDIBImageBytes (INT width, INT height, INT depth);
-INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse);
+typedef struct tagBITMAPV5INFO
+{
+ BITMAPV5HEADER bmiHeader;
+ RGBQUAD bmiColors[256];
+} BITMAPV5INFO, *PBITMAPV5INFO;
+
INT APIENTRY BITMAP_GetObject(SURFACE * bmp, INT count, LPVOID buffer);
HBITMAP FASTCALL IntCreateBitmap(IN SIZEL Size, IN LONG Width, IN ULONG Format, IN ULONG Flags, IN PVOID Bits);
HBITMAP FASTCALL BITMAP_CopyBitmap (HBITMAP hBitmap);
UINT FASTCALL BITMAP_GetRealBitsPixel(UINT nBitsPixel);
-INT FASTCALL BITMAP_GetWidthBytes (INT bmWidth, INT bpp);
+
+HBITMAP
+APIENTRY
+GreCreateBitmap(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN UINT cPlanes,
+ IN UINT cBitsPixel,
+ IN OPTIONAL PVOID pvBits);
+
+HBITMAP
+APIENTRY
+GreCreateBitmapEx(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN ULONG cjWidthBytes,
+ IN ULONG iFormat,
+ IN USHORT fjBitmap,
+ IN ULONG cjBits,
+ IN OPTIONAL PVOID pvBits,
+ IN FLONG flags);
+
+HBITMAP
+FASTCALL
+GreCreateDIBitmapInternal(
+ IN HDC hDc,
+ IN INT cx,
+ IN INT cy,
+ IN DWORD fInit,
+ IN OPTIONAL LPBYTE pjInit,
+ IN OPTIONAL PBITMAPINFO pbmi,
+ IN DWORD iUsage,
+ IN FLONG fl,
+ IN HANDLE hcmXform);
diff --git a/subsystems/win32/win32k/include/dc.h b/subsystems/win32/win32k/include/dc.h
index 41621f973c1..b1f8cd1838a 100644
--- a/subsystems/win32/win32k/include/dc.h
+++ b/subsystems/win32/win32k/include/dc.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef __WIN32K_DC_H
+#define __WIN32K_DC_H
typedef struct _DC *PDC;
@@ -22,6 +23,30 @@ typedef struct _DC *PDC;
/* fl */
#define DC_FL_PAL_BACK 1
+#define DC_DISPLAY 1
+#define DC_DIRECT 2
+#define DC_CANCELED 4
+#define DC_PERMANANT 0x08
+#define DC_DIRTY_RAO 0x10
+#define DC_ACCUM_WMGR 0x20
+#define DC_ACCUM_APP 0x40
+#define DC_RESET 0x80
+#define DC_SYNCHRONIZEACCESS 0x100
+#define DC_EPSPRINTINGESCAPE 0x200
+#define DC_TEMPINFODC 0x400
+#define DC_FULLSCREEN 0x800
+#define DC_IN_CLONEPDEV 0x1000
+#define DC_REDIRECTION 0x2000
+#define DC_SHAREACCESS 0x4000
+
+typedef enum
+{
+ DCTYPE_DIRECT = 0,
+ DCTYPE_MEMORY = 1,
+ DCTYPE_INFO = 2,
+} DCTYPE;
+
+
/* Type definitions ***********************************************************/
typedef struct _ROS_DC_INFO
@@ -29,7 +54,7 @@ typedef struct _ROS_DC_INFO
HRGN hClipRgn; /* Clip region (may be 0) */
HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */
- CLIPOBJ *CombinedClip; /* Use XCLIPOBJ in DC. */
+ CLIPOBJ *CombinedClip;
UNICODE_STRING DriverName;
@@ -134,15 +159,14 @@ typedef struct _DC
extern PDC defaultDCstate;
-NTSTATUS FASTCALL InitDcImpl(VOID);
+INIT_FUNCTION NTSTATUS NTAPI InitDcImpl();
PPDEVOBJ FASTCALL IntEnumHDev(VOID);
-HDC FASTCALL DC_AllocDC(PUNICODE_STRING Driver);
+PDC NTAPI DC_AllocDcWithHandle();
VOID FASTCALL DC_InitDC(HDC DCToInit);
-HDC FASTCALL DC_FindOpenDC(PUNICODE_STRING Driver);
VOID FASTCALL DC_AllocateDcAttr(HDC);
VOID FASTCALL DC_FreeDcAttr(HDC);
BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody);
-BOOL FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner);
+BOOL FASTCALL DC_SetOwnership(HDC hDC, PEPROCESS Owner);
VOID FASTCALL DC_LockDisplay(HDC);
VOID FASTCALL DC_UnlockDisplay(HDC);
BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
@@ -155,10 +179,16 @@ VOID FASTCALL DC_vUpdateFillBrush(PDC pdc);
VOID FASTCALL DC_vUpdateLineBrush(PDC pdc);
VOID FASTCALL DC_vUpdateTextBrush(PDC pdc);
VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc);
+VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2);
+VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdc1, RECT rc1, PDC pdc2, RECT rc2);
+
+VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel);
BOOL FASTCALL DCU_SyncDcAttrtoUser(PDC);
BOOL FASTCALL DCU_SynchDcAttrtoUser(HDC);
VOID FASTCALL DCU_SetDcUndeletable(HDC);
+VOID NTAPI DC_vFreeDcAttr(PDC pdc);
+VOID NTAPI DC_vInitDc(PDC pdc, DCTYPE dctype, PPDEVOBJ ppdev);
COLORREF FASTCALL IntGdiSetBkColor (HDC hDC, COLORREF Color);
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode);
@@ -174,12 +204,9 @@ VOID FASTCALL IntGdiUnreferencePdev(PPDEVOBJ pPDev, DWORD CleanUpType);
HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC);
BOOL FASTCALL IntGdiCleanDC(HDC hDC);
VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS);
-INT FASTCALL IntGdiGetDeviceCaps(PDC,INT);
BOOL FASTCALL MakeInfoDC(PDC,BOOL);
BOOL FASTCALL IntSetDefaultRegion(PDC);
-extern PPDEVOBJ pPrimarySurface;
-
VOID
FORCEINLINE
DC_vSelectSurface(PDC pdc, PSURFACE psurfNew)
@@ -228,5 +255,6 @@ DC_vSelectPalette(PDC pdc, PPALETTE ppal)
pdc->dclevel.ppal = ppal;
}
-BOOL FASTCALL IntPrepareDriverIfNeeded(VOID);
-extern PDEVOBJ PrimarySurface;
+extern PBRUSH pbrDefaultBrush ;
+
+#endif /* not __WIN32K_DC_H */
diff --git a/subsystems/win32/win32k/include/desktop.h b/subsystems/win32/win32k/include/desktop.h
index 83ec40ceaf8..12911139223 100644
--- a/subsystems/win32/win32k/include/desktop.h
+++ b/subsystems/win32/win32k/include/desktop.h
@@ -45,7 +45,9 @@ typedef struct _SHELL_HOOK_WINDOW
HWND hWnd;
} SHELL_HOOK_WINDOW, *PSHELL_HOOK_WINDOW;
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitDesktopImpl(VOID);
NTSTATUS FASTCALL
diff --git a/subsystems/win32/win32k/include/device.h b/subsystems/win32/win32k/include/device.h
new file mode 100644
index 00000000000..2ad19b278a7
--- /dev/null
+++ b/subsystems/win32/win32k/include/device.h
@@ -0,0 +1,58 @@
+
+//#define _PDEVOBJ _PDEVOBJ2
+//#define PDEVOBJ PDEVOBJ2
+//#define PPDEVOBJ PPDEVOBJ2
+
+//typedef struct _PDEVOBJ *PPDEVOBJ;
+
+#define TAG_GDEV 'gdev'
+
+VOID
+APIENTRY
+EngFileWrite(
+ IN PFILE_OBJECT pFileObject,
+ IN PVOID lpBuffer,
+ IN SIZE_T nLength,
+ IN PSIZE_T lpBytesWritten);
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpFindGraphicsDevice(
+ PUNICODE_STRING pustrDevice,
+ DWORD iDevNum,
+ DWORD dwFlags);
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpRegisterGraphicsDevice(
+ PUNICODE_STRING pustrDeviceName,
+ PUNICODE_STRING pustrDiplayDrivers,
+ PUNICODE_STRING pustrDescription,
+ PDEVMODEW pdmDefault);
+
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitDeviceImpl();
+
+BOOL
+FASTCALL
+DC_AllocDcAttr(PDC pdc);
+
+//#define KeRosDumpStackFrames(Frames, Count) KdSystemDebugControl(TAG('R', 'o', 's', 'D'), (PVOID)Frames, Count, NULL, 0, NULL, KernelMode)
+NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags);
+
+BOOL
+NTAPI
+PDEVOBJ_bSwitchMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm);
+
+PDEVMODEW
+NTAPI
+PDEVOBJ_pdmMatchDevMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm);
+
+extern PGRAPHICS_DEVICE gpPrimaryGraphicsDevice;
+extern PGRAPHICS_DEVICE gpVgaGraphicsDevice;
diff --git a/subsystems/win32/win32k/include/dib.h b/subsystems/win32/win32k/include/dib.h
index 479476d3850..9d5b2b18462 100644
--- a/subsystems/win32/win32k/include/dib.h
+++ b/subsystems/win32/win32k/include/dib.h
@@ -5,15 +5,17 @@
INT FASTCALL
DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse);
HBITMAP APIENTRY
-DIB_CreateDIBSection (PDC dc, PBITMAPINFO bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch);
-INT APIENTRY
-DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, PLONG width, PLONG height, PWORD planes, PWORD bpp, PLONG compr, PLONG size );
+DIB_CreateDIBSection (PDC dc, CONST BITMAPINFO *bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch);
+int FASTCALL
+DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+ LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size );
INT APIENTRY
DIB_GetDIBImageBytes (INT width, INT height, INT depth);
-INT FASTCALL
-DIB_GetDIBWidthBytes (INT width, INT depth);
-RGBQUAD * FASTCALL
-DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi);
+HPALETTE FASTCALL
+DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi);
HPALETTE FASTCALL
-BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType);
+BuildDIBPalette (CONST BITMAPINFO *bmi);
+
+BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage);
+VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
\ No newline at end of file
diff --git a/subsystems/win32/win32k/include/eng.h b/subsystems/win32/win32k/include/eng.h
index 5d95070c03c..3ed830acad8 100644
--- a/subsystems/win32/win32k/include/eng.h
+++ b/subsystems/win32/win32k/include/eng.h
@@ -21,3 +21,19 @@ IntEngWindowChanged(
VOID FASTCALL IntGdiAcquireSemaphore ( HSEMAPHORE hsem );
VOID FASTCALL IntGdiReleaseSemaphore ( HSEMAPHORE hsem );
ULONGLONG APIENTRY EngGetTickCount(VOID);
+
+BOOL
+APIENTRY
+EngFreeSectionMem(
+ IN PVOID pvSection OPTIONAL,
+ IN PVOID pvMappedBase OPTIONAL);
+
+PVOID
+APIENTRY
+EngAllocSectionMem(
+ OUT PVOID *ppvSection,
+ IN ULONG fl,
+ IN SIZE_T cjSize,
+ IN ULONG ulTag);
+
+VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG iFormat);
diff --git a/subsystems/win32/win32k/include/gdiobj.h b/subsystems/win32/win32k/include/gdiobj.h
index 9ce98f0d830..e736391322e 100644
--- a/subsystems/win32/win32k/include/gdiobj.h
+++ b/subsystems/win32/win32k/include/gdiobj.h
@@ -59,6 +59,8 @@ enum BASEFLAGS
BASEFLAG_READY_TO_DIE = 0x1000
};
+extern PSECTION_OBJECT GdiTableSection;
+
BOOL INTERNAL_CALL GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle);
BOOL INTERNAL_CALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS Owner);
BOOL INTERNAL_CALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo);
@@ -71,9 +73,15 @@ VOID INTERNAL_CALL GDIOBJ_FreeObj (POBJ pObj, UCHAR ObjectType);
BOOL INTERNAL_CALL GDIOBJ_FreeObjByHandle (HGDIOBJ hObj, DWORD ObjectType);
PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType);
PGDIOBJ INTERNAL_CALL GDIOBJ_ShareLockObj (HGDIOBJ hObj, DWORD ObjectType);
+VOID INTERNAL_CALL GDIOBJ_LockMultipleObjs(ULONG ulCount, IN HGDIOBJ* ahObj, OUT PGDIOBJ* apObj);
PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process);
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitGdiHandleTable();
+
#define GDIOBJ_GetObjectType(Handle) \
GDI_HANDLE_GET_TYPE(Handle)
diff --git a/subsystems/win32/win32k/include/guicheck.h b/subsystems/win32/win32k/include/guicheck.h
index 5e1c5c9c385..8548ab6732c 100644
--- a/subsystems/win32/win32k/include/guicheck.h
+++ b/subsystems/win32/win32k/include/guicheck.h
@@ -4,6 +4,9 @@ BOOL FASTCALL co_IntGraphicsCheck(BOOL Create);
BOOL FASTCALL IntCreatePrimarySurface(VOID);
VOID FASTCALL IntDestroyPrimarySurface(VOID);
-NTSTATUS FASTCALL InitGuiCheckImpl (VOID);
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitGuiCheckImpl (VOID);
/* EOF */
diff --git a/subsystems/win32/win32k/include/hook.h b/subsystems/win32/win32k/include/hook.h
index d09304b4895..ce6d64e1b9f 100644
--- a/subsystems/win32/win32k/include/hook.h
+++ b/subsystems/win32/win32k/include/hook.h
@@ -1,17 +1,10 @@
#pragma once
#define HOOK_THREAD_REFERENCED (0x1)
-#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
#define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK)
#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
#define ISITHOOKED(HookId) (((PTHREADINFO)PsGetCurrentThreadWin32Thread())->fsHooks & HOOKID_TO_FLAG(HookId))
-typedef struct tagHOOKTABLE
-{
- LIST_ENTRY Hooks[NB_HOOKS]; /* array of hook chains */
- UINT Counts[NB_HOOKS]; /* use counts for each hook chain */
-} HOOKTABLE, *PHOOKTABLE;
-
typedef struct tagEVENTHOOK
{
THROBJHEAD head;
@@ -32,11 +25,22 @@ typedef struct tagEVENTTABLE
UINT Counts;
} EVENTTABLE, *PEVENTTABLE;
+typedef struct _NOTIFYEVENT
+{
+ DWORD event;
+ LONG idObject;
+ LONG idChild;
+ DWORD flags;
+} NOTIFYEVENT, *PNOTIFYEVENT;
+
+LRESULT FASTCALL co_CallHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam);
LRESULT FASTCALL co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam);
LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, UINT_PTR, LONG_PTR);
VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread);
+VOID FASTCALL EVENT_DestroyThreadEvents(PETHREAD Thread);
PHOOK FASTCALL IntGetHookObject(HHOOK);
PHOOK FASTCALL IntGetNextHook(PHOOK Hook);
LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi);
+BOOL FASTCALL IntUnhookWindowsHook(int,HOOKPROC);
/* EOF */
diff --git a/subsystems/win32/win32k/include/hotkey.h b/subsystems/win32/win32k/include/hotkey.h
index c03e6ebc010..74f19a2b2a7 100644
--- a/subsystems/win32/win32k/include/hotkey.h
+++ b/subsystems/win32/win32k/include/hotkey.h
@@ -13,7 +13,9 @@ typedef struct _HOT_KEY_ITEM
UINT vk;
} HOT_KEY_ITEM, *PHOT_KEY_ITEM;
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitHotkeyImpl(VOID);
//NTSTATUS FASTCALL
diff --git a/subsystems/win32/win32k/include/input.h b/subsystems/win32/win32k/include/input.h
index 2a00fe20e9e..60056046d1a 100644
--- a/subsystems/win32/win32k/include/input.h
+++ b/subsystems/win32/win32k/include/input.h
@@ -27,10 +27,16 @@ extern PATTACHINFO gpai;
#define KBL_PRELOAD 2
#define KBL_RESET 4
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitInputImpl(VOID);
-NTSTATUS FASTCALL
+
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitKeyboardImpl(VOID);
+
PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue(VOID);
VOID W32kUnregisterPrimitiveMessageQueue(VOID);
PKBL W32kGetDefaultKeyLayout(VOID);
diff --git a/subsystems/win32/win32k/include/inteng.h b/subsystems/win32/win32k/include/inteng.h
index dc0bc98a845..1d8610d2dac 100644
--- a/subsystems/win32/win32k/include/inteng.h
+++ b/subsystems/win32/win32k/include/inteng.h
@@ -45,7 +45,7 @@ IntEngLineTo(SURFOBJ *Surface,
MIX mix);
BOOL APIENTRY
-IntEngBitBltEx(SURFOBJ *DestObj,
+IntEngBitBlt(SURFOBJ *DestObj,
SURFOBJ *SourceObj,
SURFOBJ *Mask,
CLIPOBJ *ClipRegion,
@@ -55,14 +55,7 @@ IntEngBitBltEx(SURFOBJ *DestObj,
POINTL *MaskOrigin,
BRUSHOBJ *Brush,
POINTL *BrushOrigin,
- ROP4 Rop4,
- BOOL RemoveMouse);
-#define IntEngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, \
- DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, \
- Rop4) \
- IntEngBitBltEx((DestObj), (SourceObj), (Mask), (ClipRegion), \
- (ColorTranslation), (DestRect), (SourcePoint), \
- (MaskOrigin), (Brush), (BrushOrigin), (Rop4), TRUE)
+ ROP4 Rop4);
BOOL APIENTRY
IntEngStretchBlt(SURFOBJ *DestObj,
@@ -89,32 +82,6 @@ IntEngGradientFill(SURFOBJ *psoDest,
POINTL *pptlDitherOrg,
ULONG ulMode);
-VOID InitXlateImpl(VOID);
-
-XLATEOBJ* FASTCALL
-IntEngCreateXlate(USHORT DestPalType,
- USHORT SourcePalType,
- HPALETTE PaletteDest,
- HPALETTE PaletteSource);
-
-XLATEOBJ* FASTCALL
-IntEngCreateMonoXlate(USHORT SourcePalType,
- HPALETTE PaletteDest,
- HPALETTE PaletteSource,
- ULONG BackgroundColor);
-
-XLATEOBJ* FASTCALL
-IntEngCreateSrcMonoXlate(HPALETTE PaletteDest,
- ULONG Color0,
- ULONG Color1);
-
-XLATEOBJ*
-IntCreateBrushXlate(BRUSH *pbrush, SURFACE * psurf, COLORREF crBackgroundClr);
-
-HPALETTE FASTCALL
-IntEngGetXlatePalette(XLATEOBJ *XlateObj,
- ULONG Palette);
-
BOOL APIENTRY
IntEngPolyline(SURFOBJ *DestSurf,
CLIPOBJ *Clip,
diff --git a/subsystems/win32/win32k/include/intgdi.h b/subsystems/win32/win32k/include/intgdi.h
index d547ba460d6..fcbb7a08e10 100644
--- a/subsystems/win32/win32k/include/intgdi.h
+++ b/subsystems/win32/win32k/include/intgdi.h
@@ -167,9 +167,6 @@ IntGetSysColor(INT nIndex);
/* Other Stuff */
-INT FASTCALL
-IntGdiGetDeviceCaps(PDC dc, INT Index);
-
INT
FASTCALL
IntGdiEscape(PDC dc,
@@ -186,14 +183,6 @@ IntEnumDisplaySettings(
IN OUT LPDEVMODEW pDevMode,
IN DWORD dwFlags);
-LONG
-FASTCALL
-IntChangeDisplaySettings(
- IN PUNICODE_STRING pDeviceName OPTIONAL,
- IN LPDEVMODEW pDevMode,
- IN DWORD dwflags,
- IN PVOID lParam OPTIONAL);
-
HBITMAP
FASTCALL
IntCreateCompatibleBitmap(PDC Dc,
diff --git a/subsystems/win32/win32k/include/ldevobj.h b/subsystems/win32/win32k/include/ldevobj.h
new file mode 100644
index 00000000000..6bae83ab8a0
--- /dev/null
+++ b/subsystems/win32/win32k/include/ldevobj.h
@@ -0,0 +1,87 @@
+
+#ifdef __GNUC__
+/* Hack, for bug in ld. Will be removed soon. */
+#define __ImageBase _image_base__
+#endif
+extern IMAGE_DOS_HEADER __ImageBase;
+
+
+#define TAG_LDEV 'Gldv'
+
+#define GDI_ENGINE_VERSION DDI_DRIVER_VERSION_NT5_01
+
+typedef enum
+{
+ LDEV_DEVICE_DISPLAY = 1,
+ LDEV_DEVICE_PRINTER = 2,
+ LDEV_DEVICE_META = 3,
+ LDEV_DEVICE_MIRROR = 4,
+ LDEV_IMAGE = 5,
+ LDEV_FONT = 6,
+} LDEVTYPE;
+
+typedef struct _LDEVOBJ
+{
+ struct _LDEVOBJ *pldevNext;
+ struct _LDEVOBJ *pldevPrev;
+ SYSTEM_GDI_DRIVER_INFORMATION *pGdiDriverInfo;
+ LDEVTYPE ldevtype;
+ ULONG cRefs;
+ ULONG ulDriverVersion;
+
+ union
+ {
+ PVOID apfn[INDEX_LAST];
+ DRIVER_FUNCTIONS pfn;
+ };
+
+} LDEVOBJ, *PLDEVOBJ;
+
+extern PLDEVOBJ gpldevHead;
+extern HSEMAPHORE ghsemDriverMgmt;
+
+PLDEVOBJ
+NTAPI
+LDEVOBJ_pldevLoadImage(
+ PUNICODE_STRING pusPathName,
+ LDEVTYPE ldevtype);
+
+BOOL
+NTAPI
+LDEVOBJ_bLoadDriver(
+ IN PLDEVOBJ pldev);
+
+PVOID
+NTAPI
+LDEVOBJ_pvFindImageProcAddress(
+ IN PLDEVOBJ pldev,
+ IN LPSTR lpProcName);
+
+PDEVMODEINFO
+NTAPI
+LDEVOBJ_pdmiGetModes(
+ PLDEVOBJ pldev,
+ HANDLE hDriver);
+
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitLDEVImpl();
+
+PLDEVOBJ
+APIENTRY
+EngLoadImageEx(
+ LPWSTR pwszDriverName,
+ ULONG ldevtype);
+
+PLDEVOBJ
+NTAPI
+EngGetLDEV(
+ PDEVMODEW pdm);
+
+NTSTATUS
+APIENTRY
+DriverEntry (
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath);
+
diff --git a/subsystems/win32/win32k/include/menu.h b/subsystems/win32/win32k/include/menu.h
index 6b86b62e8ad..10fe2294fba 100644
--- a/subsystems/win32/win32k/include/menu.h
+++ b/subsystems/win32/win32k/include/menu.h
@@ -104,7 +104,9 @@ IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
PROSMENUITEMINFO ItemInfo);
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitMenuImpl(VOID);
NTSTATUS FASTCALL
diff --git a/subsystems/win32/win32k/include/misc.h b/subsystems/win32/win32k/include/misc.h
index 366c44b4b7c..340e9ef252d 100644
--- a/subsystems/win32/win32k/include/misc.h
+++ b/subsystems/win32/win32k/include/misc.h
@@ -24,11 +24,38 @@ extern HGDIOBJ StockObjects[];
extern SHORT gusLanguageID;
SHORT FASTCALL IntGdiGetLanguageID(VOID);
-DWORD APIENTRY IntGetQueueStatus(BOOL ClearChanges);
+DWORD APIENTRY IntGetQueueStatus(DWORD);
VOID FASTCALL IntUserManualGuiCheck(LONG Check);
PVOID APIENTRY HackSecureVirtualMemory(IN PVOID,IN SIZE_T,IN ULONG,OUT PVOID *);
VOID APIENTRY HackUnsecureVirtualMemory(IN PVOID);
+NTSTATUS
+NTAPI
+RegOpenKey(
+ LPCWSTR pwszKeyName,
+ PHKEY phkey);
+
+NTSTATUS
+NTAPI
+RegQueryValue(
+ IN HKEY hkey,
+ IN PCWSTR pwszValueName,
+ IN ULONG ulType,
+ OUT PVOID pvData,
+ IN OUT PULONG pcbValue);
+
+VOID
+NTAPI
+RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData);
+
+VOID
+NTAPI
+RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData);
+
+BOOL
+NTAPI
+RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData);
+
BOOL
NTAPI
RegReadUserSetting(
diff --git a/subsystems/win32/win32k/include/monitor.h b/subsystems/win32/win32k/include/monitor.h
index 6c4282885ca..04a9a3ffc36 100644
--- a/subsystems/win32/win32k/include/monitor.h
+++ b/subsystems/win32/win32k/include/monitor.h
@@ -32,7 +32,10 @@ typedef struct _MONITOR
} MONITOR, *PMONITOR;
/* functions */
-NTSTATUS InitMonitorImpl();
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitMonitorImpl();
NTSTATUS CleanupMonitorImpl();
NTSTATUS IntAttachMonitor(PDEVOBJ *pGdiDevice, ULONG DisplayNumber);
diff --git a/subsystems/win32/win32k/include/mouse.h b/subsystems/win32/win32k/include/mouse.h
index 0e5f68b9626..306148bef30 100644
--- a/subsystems/win32/win32k/include/mouse.h
+++ b/subsystems/win32/win32k/include/mouse.h
@@ -2,8 +2,8 @@
#include
-INT INTERNAL_CALL MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2);
-INT INTERNAL_CALL MouseSafetyOnDrawEnd(SURFOBJ *SurfObj);
+INT INTERNAL_CALL MouseSafetyOnDrawStart(PPDEVOBJ ppdev, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2);
+INT INTERNAL_CALL MouseSafetyOnDrawEnd(PPDEVOBJ ppdev);
#ifndef XBUTTON1
#define XBUTTON1 (0x01)
diff --git a/subsystems/win32/win32k/include/msgqueue.h b/subsystems/win32/win32k/include/msgqueue.h
index e35ab0f5a15..8a8bac87a24 100644
--- a/subsystems/win32/win32k/include/msgqueue.h
+++ b/subsystems/win32/win32k/include/msgqueue.h
@@ -58,8 +58,12 @@ typedef struct _USER_MESSAGE_QUEUE
LIST_ENTRY HardwareMessagesListHead;
/* Lock for the hardware message list. */
KMUTEX HardwareLock;
- /* Pointer to the current WM_MOUSEMOVE message */
- PUSER_MESSAGE MouseMoveMsg;
+ /* True if a WM_MOUSEMOVE is pending */
+ BOOLEAN MouseMoved;
+ /* Current WM_MOUSEMOVE message */
+ MSG MouseMoveMsg;
+ /* Last click message for translating double clicks */
+ MSG msgDblClk;
/* True if a WM_QUIT message is pending. */
BOOLEAN QuitPosted;
/* The quit exit code. */
@@ -87,9 +91,6 @@ typedef struct _USER_MESSAGE_QUEUE
/* Caret information for this queue */
PTHRDCARETINFO CaretInfo;
- /* Window hooks */
- PHOOKTABLE Hooks;
-
/* queue state tracking */
WORD WakeMask;
WORD QueueBits;
@@ -124,13 +125,26 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue,
VOID FASTCALL
MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode);
BOOLEAN APIENTRY
-co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
- IN BOOLEAN Hardware,
- IN BOOLEAN Remove,
- IN PWND Window,
- IN UINT MsgFilterLow,
- IN UINT MsgFilterHigh,
- OUT PUSER_MESSAGE* Message);
+MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
+ IN BOOLEAN Remove,
+ IN PWND Window,
+ IN UINT MsgFilterLow,
+ IN UINT MsgFilterHigh,
+ OUT PMSG Message);
+BOOL APIENTRY
+co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
+ IN BOOL Remove,
+ IN PWND Window,
+ IN UINT MsgFilterLow,
+ IN UINT MsgFilterHigh,
+ OUT MSG* pMsg);
+BOOL APIENTRY
+co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
+ IN BOOL Remove,
+ IN PWND Window,
+ IN UINT MsgFilterLow,
+ IN UINT MsgFilterHigh,
+ OUT MSG* pMsg);
BOOLEAN FASTCALL
MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQueue);
VOID FASTCALL
@@ -141,7 +155,9 @@ VOID FASTCALL
MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue);
PUSER_MESSAGE_QUEUE FASTCALL
MsqGetHardwareMessageQueue(VOID);
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
MsqInitializeImpl(VOID);
BOOLEAN FASTCALL
co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue);
@@ -149,9 +165,6 @@ NTSTATUS FASTCALL
co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
UINT MsgFilterMin, UINT MsgFilterMax);
VOID FASTCALL
-MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue,
- PUSER_SENT_MESSAGE_NOTIFY NotifyMessage);
-VOID FASTCALL
MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue);
VOID FASTCALL
MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue);
@@ -197,7 +210,7 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
VOID FASTCALL
MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam);
VOID FASTCALL
-MsqInsertSystemMessage(MSG* Msg);
+co_MsqInsertMouseMessage(MSG* Msg);
BOOL FASTCALL
MsqIsClkLck(LPMSG Msg, BOOL Remove);
BOOL FASTCALL
@@ -212,9 +225,6 @@ BOOL APIENTRY IntInitMessagePumpHook();
BOOL APIENTRY IntUninitMessagePumpHook();
#define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))
-PHOOKTABLE FASTCALL MsqGetHooks(PUSER_MESSAGE_QUEUE Queue);
-VOID FASTCALL MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks);
-
LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam);
LPARAM FASTCALL MsqGetMessageExtraInfo(VOID);
VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, will be gone in the rewrite! */
@@ -273,4 +283,7 @@ MsqCalculateMessageTime(IN PLARGE_INTEGER TickCount)
return (LONG)(TickCount->QuadPart * (KeQueryTimeIncrement() / 10000));
}
+VOID FASTCALL IdlePing(VOID);
+VOID FASTCALL IdlePong(VOID);
+
/* EOF */
diff --git a/subsystems/win32/win32k/include/ntuser.h b/subsystems/win32/win32k/include/ntuser.h
index 58a911d6f82..83b21556862 100644
--- a/subsystems/win32/win32k/include/ntuser.h
+++ b/subsystems/win32/win32k/include/ntuser.h
@@ -11,7 +11,7 @@
extern PSERVERINFO gpsi;
-NTSTATUS FASTCALL InitUserImpl(VOID);
+INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
VOID FASTCALL CleanupUserImpl(VOID);
VOID FASTCALL UserEnterShared(VOID);
VOID FASTCALL UserEnterExclusive(VOID);
diff --git a/subsystems/win32/win32k/include/palette.h b/subsystems/win32/win32k/include/palette.h
index 76839b075f5..3fad906ff45 100644
--- a/subsystems/win32/win32k/include/palette.h
+++ b/subsystems/win32/win32k/include/palette.h
@@ -40,7 +40,7 @@ typedef struct _PALETTE
PALOBJ PalObj;
XLATEOBJ *logicalToSystem;
HPALETTE Self;
- ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
+ FLONG flFlags; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
ULONG NumColors;
PALETTEENTRY *IndexedColors;
ULONG RedMask;
@@ -52,8 +52,8 @@ typedef struct _PALETTE
HDEV hPDev;
} PALETTE, *PPALETTE;
-extern PALETTE gpalRGB, gpalBGR, gpalMono;
-
+extern PALETTE gpalRGB, gpalBGR, gpalMono, gpalRGB555, gpalRGB565, *gppalDefault;
+extern PPALETTE appalSurfaceDefault[];
HPALETTE FASTCALL PALETTE_AllocPalette(ULONG Mode,
ULONG NumColors,
@@ -74,8 +74,7 @@ HPALETTE FASTCALL PALETTE_AllocPaletteIndexedRGB(ULONG NumColors,
GDIOBJ_ShareUnlockObjByPtr(&ppal->BaseObject)
BOOL INTERNAL_CALL PALETTE_Cleanup(PVOID ObjectBody);
-
-HPALETTE FASTCALL PALETTE_Init (VOID);
+INIT_FUNCTION NTSTATUS NTAPI InitPaletteImpl();
VOID FASTCALL PALETTE_ValidateFlags (PALETTEENTRY* lpPalE, INT size);
INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color);
diff --git a/subsystems/win32/win32k/include/pdevobj.h b/subsystems/win32/win32k/include/pdevobj.h
index ca0c3fa0821..bece851460a 100644
--- a/subsystems/win32/win32k/include/pdevobj.h
+++ b/subsystems/win32/win32k/include/pdevobj.h
@@ -1,6 +1,5 @@
-#pragma once
-
-#include
+#ifndef __WIN32K_PDEVOBJ_H
+#define __WIN32K_PDEVOBJ_H
/* PDEVOBJ flags */
#define PDEV_DISPLAY 0x00000001 /* Display device */
@@ -37,6 +36,21 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak
RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */
} GDIPOINTER, *PGDIPOINTER;
+typedef struct _DEVMODEINFO
+{
+ struct _DEVMODEINFO *pdmiNext;
+ struct _LDEVOBJ *pldev;
+ ULONG cbdevmode;
+ DEVMODEW adevmode[1];
+} DEVMODEINFO, *PDEVMODEINFO;
+
+typedef struct
+{
+ DWORD dwFlags;
+ PDEVMODEW pdm;
+
+} DEVMODEENTRY, *PDEVMODEENTRY;
+
typedef struct _GRAPHICS_DEVICE
{
WCHAR szNtDeviceName[CCHDEVICENAME/2];
@@ -48,15 +62,17 @@ typedef struct _GRAPHICS_DEVICE
DWORD hkClassDriverConfig;
DWORD StateFlags; /* See DISPLAY_DEVICE_* */
ULONG cbdevmodeInfo;
- PVOID devmodeInfo;
- DWORD cbdevmodeInfo1;
- PVOID devmodeInfo1;
- LPWSTR pwszDeviceNames;
+ PDEVMODEINFO pdevmodeInfo;
+ ULONG cDevModes;
+ PDEVMODEENTRY pDevModeList;
+ LPWSTR pDiplayDrivers;
LPWSTR pwszDescription;
DWORD dwUnknown;
PVOID pUnknown;
PFILE_OBJECT FileObject;
DWORD ProtocolType;
+ ULONG iDefaultMode;
+ ULONG iCurrentMode;
} GRAPHICS_DEVICE, *PGRAPHICS_DEVICE;
typedef struct _PDEVOBJ
@@ -64,8 +80,8 @@ typedef struct _PDEVOBJ
BASEOBJECT BaseObject;
struct _PDEVOBJ * ppdevNext;
- INT cPdevRefs;
- INT cPdevOpenRefs;
+ LONG cPdevRefs;
+ LONG cPdevOpenRefs;
struct _PDEVOBJ * ppdevParent;
FLONG flFlags; // flags
// FLONG flAccelerated;
@@ -98,17 +114,17 @@ typedef struct _PDEVOBJ
// PFN_DrvSetPalette pfnDrvSetPalette;
// PFN_DrvNotify pfnDrvNotify;
// ULONG TagSig;
-// PLDEVOBJ pldev;
+ struct _LDEVOBJ * pldev;
DHPDEV dhpdev; /* DHPDEV for device. */
- PVOID ppalSurf; /* PEPALOBJ/PPALETTE for this device. */
+ struct _PALETTE* ppalSurf; /* PEPALOBJ/PPALETTE for this device. */
DEVINFO devinfo;
GDIINFO gdiinfo;
- HSURF pSurface; /* SURFACE for this device., FIXME: PSURFACE */
+ PSURFACE pSurface; /* SURFACE for this device. */
// HANDLE hSpooler; /* Handle to spooler, if spooler dev driver. */
// PVOID pDesktopId;
PGRAPHICS_DEVICE pGraphicsDevice;
POINTL ptlOrigion;
- PVOID pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
+ PDEVMODEW pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
// DWORD Unknown3;
FLONG DxDd_Flags; /* DxDD active status flags. */
// LONG devAttr;
@@ -117,15 +133,12 @@ typedef struct _PDEVOBJ
union
{
DRIVER_FUNCTIONS DriverFunctions;
+ DRIVER_FUNCTIONS pfn;
PVOID apfn[INDEX_LAST]; // B8C 0x0598
};
/* ros specific */
ULONG DxDd_nCount;
- ULONG DisplayNumber;
- DEVMODEW DMW;
- PFILE_OBJECT VideoFileObject;
- BOOLEAN PreparedDriver;
GDIPOINTER Pointer;
/* Stuff to keep track of software cursors; win32k gdi part */
UINT SafetyRemoveLevel; /* at what level was the cursor removed?
@@ -134,13 +147,40 @@ typedef struct _PDEVOBJ
struct _EDD_DIRECTDRAW_GLOBAL * pEDDgpl;
} PDEVOBJ, *PPDEVOBJ;
-/* PDEV and EDDX extra data container.*/
-typedef struct _PDEVEDD
-{
- PDEVOBJ pdevobj;
- EDD_DIRECTDRAW_GLOBAL EDDgpl;
-} PDEVEDD, *PPDEVEDD;
+/* Globals ********************************************************************/
-PSIZEL FASTCALL PDEV_sizl(PPDEVOBJ, PSIZEL);
+extern PPDEVOBJ gppdevPrimary;
+#define pPrimarySurface gppdevPrimary
-extern ULONG gdwDirectDrawContext;
+
+/* Function prototypes ********************************************************/
+
+PPDEVOBJ
+NTAPI
+EngpGetPDEV(PUNICODE_STRING pustrDevice);
+
+VOID
+NTAPI
+PDEVOBJ_vRelease(PPDEVOBJ ppdev);
+
+PSURFACE
+NTAPI
+PDEVOBJ_pSurface(
+ PPDEVOBJ ppdev);
+
+VOID
+NTAPI
+PDEVOBJ_vGetDeviceCaps(
+ PPDEVOBJ ppdev,
+ PDEVCAPS pDevCaps);
+
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitPDEVImpl();
+
+PSIZEL
+FASTCALL
+PDEVOBJ_sizl(PPDEVOBJ, PSIZEL);
+
+#endif /* !__WIN32K_PDEVOBJ_H */
diff --git a/subsystems/win32/win32k/include/region.h b/subsystems/win32/win32k/include/region.h
index d29b1b04fdf..5ad6e2cb52f 100644
--- a/subsystems/win32/win32k/include/region.h
+++ b/subsystems/win32/win32k/include/region.h
@@ -14,7 +14,7 @@ typedef struct _ROSRGNDATA
RGNDATAHEADER rdh;
RECTL *Buffer;
-} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA;
+} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA, REGION, *PREGION;
/* Functions ******************************************************************/
diff --git a/subsystems/win32/win32k/include/surface.h b/subsystems/win32/win32k/include/surface.h
index 3fe90540467..485f3dc72b3 100644
--- a/subsystems/win32/win32k/include/surface.h
+++ b/subsystems/win32/win32k/include/surface.h
@@ -8,48 +8,88 @@
/* GDI surface object */
typedef struct _SURFACE
{
- BASEOBJECT BaseObject;
+ BASEOBJECT BaseObject;
- SURFOBJ SurfObj;
- FLONG flHooks;
- FLONG flFlags;
- struct _PALETTE *ppal;
+ SURFOBJ SurfObj;
+ //XDCOBJ * pdcoAA;
+ FLONG flags;
+ struct _PALETTE *ppal;
+ //UINT unk_050;
- union
- {
- HANDLE hSecureUMPD; // if UMPD_SURFACE set
- HANDLE hMirrorParent;// if MIRROR_SURFACE set
- HANDLE hDDSurface; // if DIRECTDRAW_SURFACE set
- };
+ union
+ {
+ HANDLE hSecureUMPD; // if UMPD_SURFACE set
+ HANDLE hMirrorParent;// if MIRROR_SURFACE set
+ HANDLE hDDSurface; // if DIRECTDRAW_SURFACE set
+ };
- SIZEL dimension; /* For SetBitmapDimension(), do NOT use
+ SIZEL sizlDim; /* For SetBitmapDimension(), do NOT use
to get width/height of bitmap, use
bitmap.bmWidth/bitmap.bmHeight for
that */
-
- HDC hDC; // Doc in "Undocumented Windows", page 546, seems to be supported with XP.
- ULONG cRef; // 0x064
- HPALETTE hpalHint;
- /* For device-independent bitmaps: */
- HANDLE hDIBSection;
- HANDLE hSecure;
- DWORD dwOffset;
+ HDC hdc; // Doc in "Undocumented Windows", page 546, seems to be supported with XP.
+ ULONG cRef;
+ HPALETTE hpalHint;
+
+ /* For device-independent bitmaps: */
+ HANDLE hDIBSection;
+ HANDLE hSecure;
+ DWORD dwOffset;
+ //UINT unk_078;
/* reactos specific */
- PFAST_MUTEX BitsLock; /* You need to hold this lock before you touch
- the actual bits in the bitmap */
- HPALETTE hDIBPalette;
- DWORD dsBitfields[3]; // hack, should probably use palette instead
- DWORD biClrUsed;
- DWORD biClrImportant;
+ DWORD biClrImportant;
} SURFACE, *PSURFACE;
-#define BITMAPOBJ_IS_APIBITMAP 0x1
+// flags field:
+//#define HOOK_BITBLT 0x00000001
+//#define HOOK_STRETCHBLT 0x00000002
+//#define HOOK_PLGBLT 0x00000004
+//#define HOOK_TEXTOUT 0x00000008
+//#define HOOK_PAINT 0x00000010
+//#define HOOK_STROKEPATH 0x00000020
+//#define HOOK_FILLPATH 0x00000040
+//#define HOOK_STROKEANDFILLPATH 0x00000080
+//#define HOOK_LINETO 0x00000100
+//#define SHAREACCESS_SURFACE 0x00000200
+//#define HOOK_COPYBITS 0x00000400
+//#define REDIRECTION_SURFACE 0x00000800 // ?
+//#define HOOK_MOVEPANNING 0x00000800
+//#define HOOK_SYNCHRONIZE 0x00001000
+//#define HOOK_STRETCHBLTROP 0x00002000
+//#define HOOK_SYNCHRONIZEACCESS 0x00004000
+//#define USE_DEVLOCK_SURFACE 0x00004000
+//#define HOOK_TRANSPARENTBLT 0x00008000
+//#define HOOK_ALPHABLEND 0x00010000
+//#define HOOK_GRADIENTFILL 0x00020000
+//#if (NTDDI_VERSION < 0x06000000)
+// #define HOOK_FLAGS 0x0003B5FF
+//#else
+// #define HOOK_FLAGS 0x0003B5EF
+//#endif
+#define UMPD_SURFACE 0x00040000
+#define MIRROR_SURFACE 0x00080000
+#define DIRECTDRAW_SURFACE 0x00100000
+#define DRIVER_CREATED_SURFACE 0x00200000
+#define ENG_CREATE_DEVICE_SURFACE 0x00400000
+#define DDB_SURFACE 0x00800000
+#define LAZY_DELETE_SURFACE 0x01000000
+#define BANDING_SURFACE 0x02000000
+#define API_BITMAP 0x04000000
+#define PALETTE_SELECT_SET 0x08000000
+#define UNREADABLE_SURFACE 0x10000000
+#define DYNAMIC_MODE_PALETTE 0x20000000
+#define ABORT_SURFACE 0x40000000
+#define PDEV_SURFACE 0x80000000
+
+
+#define BMF_DONT_FREE 0x100
+#define BMF_RLE_HACK 0x200
+
/* Internal interface */
-#define SURFACE_AllocSurface() ((PSURFACE) GDIOBJ_AllocObj(GDIObjType_SURF_TYPE))
#define SURFACE_AllocSurfaceWithHandle() ((PSURFACE) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP))
#define SURFACE_FreeSurface(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_SURF_TYPE)
#define SURFACE_FreeSurfaceByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP)
@@ -64,15 +104,31 @@ typedef struct _SURFACE
#define SURFACE_ShareUnlockSurface(pBMObj) \
GDIOBJ_ShareUnlockObjByPtr ((POBJ)pBMObj)
-#define SURFACE_LockBitmapBits(pBMObj) ExEnterCriticalRegionAndAcquireFastMutexUnsafe((pBMObj)->BitsLock)
-#define SURFACE_UnlockBitmapBits(pBMObj) ExReleaseFastMutexUnsafeAndLeaveCriticalRegion((pBMObj)->BitsLock)
-
BOOL INTERNAL_CALL SURFACE_Cleanup(PVOID ObjectBody);
-BOOL INTERNAL_CALL SURFACE_InitBitsLock(SURFACE *pBMObj);
-void INTERNAL_CALL SURFACE_CleanupBitsLock(SURFACE *pBMObj);
+
+PSURFACE
+NTAPI
+SURFACE_AllocSurface(
+ IN ULONG iType,
+ IN ULONG cx,
+ IN ULONG cy,
+ IN ULONG iFormat);
+
+BOOL
+NTAPI
+SURFACE_bSetBitmapBits(
+ IN PSURFACE psurf,
+ IN USHORT fjBitmap,
+ IN ULONG ulWidth,
+ IN PVOID pvBits OPTIONAL);
#define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))
#define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions
-INT FASTCALL BitsPerFormat (ULONG Format);
ULONG FASTCALL BitmapFormat (WORD Bits, DWORD Compression);
+extern UCHAR gajBitsPerFormat[];
+#define BitsPerFormat(Format) gajBitsPerFormat[Format]
+
+#define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
+#define WIDTH_BYTES_ALIGN16(cx, bpp) ((((cx) * (bpp) + 15) & ~15) >> 3)
+
diff --git a/subsystems/win32/win32k/include/timer.h b/subsystems/win32/win32k/include/timer.h
index 20faa683526..c88da4a987d 100644
--- a/subsystems/win32/win32k/include/timer.h
+++ b/subsystems/win32/win32k/include/timer.h
@@ -26,7 +26,10 @@ typedef struct _TIMER
extern PKTIMER MasterTimer;
-NTSTATUS FASTCALL InitTimerImpl(VOID);
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitTimerImpl(VOID);
BOOL FASTCALL DestroyTimersForThread(PTHREADINFO pti);
BOOL FASTCALL DestroyTimersForWindow(PTHREADINFO pti, PWND Window);
BOOL FASTCALL IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer);
diff --git a/subsystems/win32/win32k/include/win32.h b/subsystems/win32/win32k/include/win32.h
index 63dfba76fe2..ed1e645a0a6 100644
--- a/subsystems/win32/win32k/include/win32.h
+++ b/subsystems/win32/win32k/include/win32.h
@@ -96,6 +96,7 @@ typedef struct _THREADINFO
LIST_ENTRY PtiLink;
POINT ptLast;
+ LIST_ENTRY aphkStart[NB_HOOKS];
CLIENTTHREADINFO cti; // Used only when no Desktop or pcti NULL.
/* ReactOS */
LIST_ENTRY WindowListHead;
@@ -150,6 +151,8 @@ typedef struct _W32PROCESS
LIST_ENTRY GDIBrushAttrFreeList;
} W32PROCESS, *PW32PROCESS;
+#define CLIBS 32
+
typedef struct _PROCESSINFO
{
W32PROCESS;
@@ -158,11 +161,15 @@ typedef struct _PROCESSINFO
struct _DESKTOP* rpdeskStartup;
PCLS pclsPrivateList;
PCLS pclsPublicList;
-
+ DWORD dwhmodLibLoadedMask;
+ HANDLE ahmodLibLoaded[CLIBS];
+ struct _WINSTATION_OBJECT *prpwinsta;
+ HWINSTA hwinsta;
+ ACCESS_MASK amwinsta;
+ DWORD dwHotkey;
HMONITOR hMonitor;
-
+ LUID luidSession;
USERSTARTUPINFO usi;
- ULONG Flags;
DWORD dwLayout;
DWORD dwRegisteredClasses;
/* ReactOS */
diff --git a/subsystems/win32/win32k/include/win32kp.h b/subsystems/win32/win32k/include/win32kp.h
index ea3bd61497a..b84a319947f 100644
--- a/subsystems/win32/win32k/include/win32kp.h
+++ b/subsystems/win32/win32k/include/win32kp.h
@@ -11,6 +11,13 @@
#pragma once
#define INTERNAL_CALL APIENTRY
+#ifndef _MSC_VER
+#define PLACE_IN_SECTION(s) __attribute__((section(s)))
+#define INIT_FUNCTION PLACE_IN_SECTION("INIT")
+#else
+#define INIT_FUNCTION
+#endif
+
/* Internal Win32k Headers */
#include
#include
@@ -78,4 +85,6 @@
#include
#include
#include
+#include
+#include
#include
diff --git a/subsystems/win32/win32k/include/window.h b/subsystems/win32/win32k/include/window.h
index a91183a0153..0e2073d3df1 100644
--- a/subsystems/win32/win32k/include/window.h
+++ b/subsystems/win32/win32k/include/window.h
@@ -50,7 +50,9 @@ IntIsWindow(HWND hWnd);
HWND* FASTCALL
IntWinListChildren(PWND Window);
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitWindowImpl (VOID);
NTSTATUS FASTCALL
@@ -104,7 +106,7 @@ IntShowOwnedPopups( PWND owner, BOOL fShow );
LRESULT FASTCALL
IntDefWindowProc( PWND Window, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi);
-VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG);
+VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG, DWORD);
PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW*, PUNICODE_STRING, PLARGE_STRING);
WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL);
diff --git a/subsystems/win32/win32k/include/winpos.h b/subsystems/win32/win32k/include/winpos.h
index cee93ab0465..b21b9107616 100644
--- a/subsystems/win32/win32k/include/winpos.h
+++ b/subsystems/win32/win32k/include/winpos.h
@@ -27,9 +27,8 @@ BOOLEAN FASTCALL
co_WinPosShowWindow(PWND Window, INT Cmd);
void FASTCALL
co_WinPosSendSizeMove(PWND Window);
-USHORT FASTCALL
-co_WinPosWindowFromPoint(PWND ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *WinPoint,
- PWND* Window);
+PWND FASTCALL
+co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest);
VOID FASTCALL co_WinPosActivateOtherWindow(PWND Window);
VOID FASTCALL WinPosInitInternalPos(PWND WindowObject,
diff --git a/subsystems/win32/win32k/include/winsta.h b/subsystems/win32/win32k/include/winsta.h
index da944af3a46..a50a23ed6b7 100644
--- a/subsystems/win32/win32k/include/winsta.h
+++ b/subsystems/win32/win32k/include/winsta.h
@@ -62,7 +62,9 @@ typedef struct _WINSTATION_OBJECT
extern WINSTATION_OBJECT *InputWindowStation;
extern PPROCESSINFO LogonProcess;
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitWindowStationImpl(VOID);
NTSTATUS FASTCALL
diff --git a/subsystems/win32/win32k/include/xlateobj.h b/subsystems/win32/win32k/include/xlateobj.h
index a2ffedb7615..ea7d32035eb 100644
--- a/subsystems/win32/win32k/include/xlateobj.h
+++ b/subsystems/win32/win32k/include/xlateobj.h
@@ -45,8 +45,11 @@ DbgCmpXlate(XLATEOBJ *pxlo1, XLATEOBJ *pxlo2);
VOID NTAPI EXLATEOBJ_vInitialize(PEXLATEOBJ pexlo, PALETTE *ppalSrc, PALETTE *ppalDst, ULONG, ULONG, ULONG);
VOID NTAPI EXLATEOBJ_vInitXlateFromDCs(PEXLATEOBJ pexlo, PDC pdcSrc, PDC pdcDst);
-VOID NTAPI EXLATEOBJ_vInitBrushXlate(PEXLATEOBJ pexlo, BRUSH *pbrush, SURFACE *psurf, COLORREF crForegroundClr, COLORREF crBackgroundClr);
VOID NTAPI EXLATEOBJ_vInitSrcMonoXlate(PEXLATEOBJ pexlo, PPALETTE ppalDst, ULONG Color0, ULONG Color1);
VOID NTAPI EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo);
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitXlateImpl(VOID);
//#define XLATEOBJ_iXlate(pxo, Color) ((EXLATEOBJ*)pxo)->pfnXlate(pxo, Color)
diff --git a/subsystems/win32/win32k/ldr/loader.c b/subsystems/win32/win32k/ldr/loader.c
deleted file mode 100644
index bc867c2c4ac..00000000000
--- a/subsystems/win32/win32k/ldr/loader.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/* $Id$
- *
- */
-
-#include
-
-#define NDEBUG
-#include
-
-
-extern LIST_ENTRY GlobalDriverListHead;
-
-
-/*
- * Blatantly stolen from ldr/utils.c in ntdll. I can't link ntdll from
- * here, though.
- */
-NTSTATUS APIENTRY
-LdrGetProcedureAddress (IN PVOID BaseAddress,
- IN PANSI_STRING Name,
- IN ULONG Ordinal,
- OUT PVOID *ProcedureAddress)
-{
- PIMAGE_EXPORT_DIRECTORY ExportDir;
- PUSHORT OrdinalPtr;
- PULONG NamePtr;
- PULONG AddressPtr;
- ULONG i = 0;
-
- DPRINT("LdrGetProcedureAddress (BaseAddress %x Name %Z Ordinal %lu ProcedureAddress %x)\n",
- BaseAddress, Name, Ordinal, ProcedureAddress);
-
- /* Get the pointer to the export directory */
- ExportDir = (PIMAGE_EXPORT_DIRECTORY)
- RtlImageDirectoryEntryToData (BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &i);
-
- DPRINT("ExportDir %x i %lu\n", ExportDir, i);
-
- if (!ExportDir || !i || !ProcedureAddress)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- AddressPtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfFunctions);
- if (Name && Name->Length)
- {
- /* by name */
- OrdinalPtr = (PUSHORT)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNameOrdinals);
- NamePtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNames);
- for( i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
- {
- if (!strcmp(Name->Buffer, (char*)((ULONG_PTR)BaseAddress + *NamePtr)))
- {
- *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG)AddressPtr[*OrdinalPtr]);
- return STATUS_SUCCESS;
- }
- }
- DPRINT1("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
- }
- else
- {
- /* by ordinal */
- Ordinal &= 0x0000FFFF;
- if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions)
- {
- *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG_PTR)AddressPtr[Ordinal - ExportDir->Base]);
- return STATUS_SUCCESS;
- }
- DPRINT1("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal);
- }
-
- return STATUS_PROCEDURE_NOT_FOUND;
-}
-
-PVOID APIENTRY
-EngFindImageProcAddress(IN HANDLE Module,
- IN LPSTR ProcName)
-{
- PVOID Function;
- NTSTATUS Status;
- ANSI_STRING ProcNameString;
- unsigned i;
- static struct
- {
- PCSTR ProcName;
- PVOID ProcAddress;
- }
- Win32kExports[] =
- {
- { "BRUSHOBJ_hGetColorTransform", BRUSHOBJ_hGetColorTransform },
- { "EngAlphaBlend", EngAlphaBlend },
- { "EngClearEvent", EngClearEvent },
- { "EngControlSprites", EngControlSprites },
- { "EngCreateEvent", EngCreateEvent },
- { "EngDeleteEvent", EngDeleteEvent },
- { "EngDeleteFile", EngDeleteFile },
- { "EngDeleteSafeSemaphore", EngDeleteSafeSemaphore },
- { "EngDeleteWnd", EngDeleteWnd },
- { "EngDitherColor", EngDitherColor },
- { "EngGetPrinterDriver", EngGetPrinterDriver },
- { "EngGradientFill", EngGradientFill },
- { "EngHangNotification", EngHangNotification },
- { "EngInitializeSafeSemaphore", EngInitializeSafeSemaphore },
- { "EngLockDirectDrawSurface", EngLockDirectDrawSurface },
- { "EngLpkInstalled", EngLpkInstalled },
- { "EngMapEvent", EngMapEvent },
- { "EngMapFile", EngMapFile },
- { "EngMapFontFileFD", EngMapFontFileFD },
- { "EngModifySurface", EngModifySurface },
- { "EngMovePointer", EngMovePointer },
- { "EngPlgBlt", EngPlgBlt },
- { "EngQueryDeviceAttribute", EngQueryDeviceAttribute },
- { "EngQueryPalette", EngQueryPalette },
- { "EngQuerySystemAttribute", EngQuerySystemAttribute },
- { "EngReadStateEvent", EngReadStateEvent },
- { "EngRestoreFloatingPointState", EngRestoreFloatingPointState },
- { "EngSaveFloatingPointState", EngSaveFloatingPointState },
- { "EngSetEvent", EngSetEvent },
- { "EngSetPointerShape", EngSetPointerShape },
- { "EngSetPointerTag", EngSetPointerTag },
- { "EngStretchBltROP", EngStretchBltROP },
- { "EngTransparentBlt", EngTransparentBlt },
- { "EngUnlockDirectDrawSurface", EngUnlockDirectDrawSurface },
- { "EngUnmapEvent", EngUnmapEvent },
- { "EngUnmapFile", EngUnmapFile },
- { "EngUnmapFontFileFD", EngUnmapFontFileFD },
- { "EngWaitForSingleObject", EngWaitForSingleObject },
- { "FONTOBJ_pfdg", FONTOBJ_pfdg },
- { "FONTOBJ_pjOpenTypeTablePointer", FONTOBJ_pjOpenTypeTablePointer },
- { "FONTOBJ_pQueryGlyphAttrs", FONTOBJ_pQueryGlyphAttrs },
- { "FONTOBJ_pwszFontFilePaths", FONTOBJ_pwszFontFilePaths },
- { "HeapVidMemAllocAligned", HeapVidMemAllocAligned },
- { "HT_Get8BPPMaskPalette", HT_Get8BPPMaskPalette },
- { "STROBJ_bEnumPositionsOnly", STROBJ_bEnumPositionsOnly },
- { "STROBJ_bGetAdvanceWidths", STROBJ_bGetAdvanceWidths },
- { "STROBJ_fxBreakExtra", STROBJ_fxBreakExtra },
- { "STROBJ_fxCharacterExtra", STROBJ_fxCharacterExtra },
- { "VidMemFree", VidMemFree },
- { "XLATEOBJ_hGetColorTransform", XLATEOBJ_hGetColorTransform }
- };
-
- if (NULL == Module)
- {
- DPRINT("Looking for win32k export %s\n", ProcName);
- for (i = 0; i < sizeof(Win32kExports) / sizeof(Win32kExports[0]); i++)
- {
- if (0 == strcmp(ProcName, Win32kExports[i].ProcName))
- {
- DPRINT("Found it index %u address %p\n", i, Win32kExports[i].ProcName);
- return Win32kExports[i].ProcAddress;
- }
- }
- return NULL;
- }
- RtlInitAnsiString(&ProcNameString, ProcName);
- Status = LdrGetProcedureAddress(((PDRIVERS)Module)->BaseAddress,
- &ProcNameString,
- 0,
- &Function);
- if (!NT_SUCCESS(Status))
- {
- return(NULL);
- }
- return(Function);
-}
-
-
-/*
- * @implemented
- */
-HANDLE
-APIENTRY
-EngLoadImage (LPWSTR DriverName)
-{
- SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
- PDRIVERS DriverInfo = NULL;
- NTSTATUS Status;
-
- RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
- if( !IsListEmpty(&GlobalDriverListHead) )
- {
- PLIST_ENTRY CurrentEntry = GlobalDriverListHead.Flink;
- PDRIVERS Current;
- /* probably the driver was already loaded, let's try to find it out */
- while( CurrentEntry != &GlobalDriverListHead )
- {
- Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry);
- if( Current && (0 == RtlCompareUnicodeString(&GdiDriverInfo.DriverName, &Current->DriverName, FALSE)) ) {
- DriverInfo = Current;
- break;
- }
- CurrentEntry = CurrentEntry->Flink;
- };
- }
-
- if( !DriverInfo )
- {
- /* the driver was not loaded before, so let's do that */
- Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
- if (!NT_SUCCESS(Status)) {
- DPRINT1("ZwSetSystemInformation failed with Status 0x%lx\n", Status);
- }
- else {
- DriverInfo = ExAllocatePoolWithTag(PagedPool, sizeof(DRIVERS), TAG_DRIVER);
- DriverInfo->DriverName.MaximumLength = GdiDriverInfo.DriverName.MaximumLength;
- DriverInfo->DriverName.Length = GdiDriverInfo.DriverName.Length;
- DriverInfo->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool, GdiDriverInfo.DriverName.MaximumLength, TAG_DRIVER);
- RtlCopyUnicodeString(&DriverInfo->DriverName, &GdiDriverInfo.DriverName);
- DriverInfo->SectionPointer = GdiDriverInfo.SectionPointer;
- DriverInfo->BaseAddress = GdiDriverInfo.ImageAddress;
- InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry);
- }
- }
-
- return DriverInfo;
-}
-
-VOID
-APIENTRY
-EngUnloadImage ( IN HANDLE hModule )
-{
- NTSTATUS Status;
- PDRIVERS DriverInfo = (PDRIVERS)hModule;
-
- DPRINT("hModule 0x%x\n", hModule);
-
- Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
- DriverInfo->SectionPointer, sizeof(PVOID));
-
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("ZwSetSystemInformation failed with status 0x%08X\n",
- Status);
- }
- else
- {
- ExFreePool(DriverInfo->DriverName.Buffer);
- RemoveEntryList(&DriverInfo->ListEntry);
- ExFreePool(DriverInfo);
- }
-}
-
-/* EOF */
diff --git a/subsystems/win32/win32k/main/dllmain.c b/subsystems/win32/win32k/main/dllmain.c
index 0c992c0e72f..d0bbae1b025 100644
--- a/subsystems/win32/win32k/main/dllmain.c
+++ b/subsystems/win32/win32k/main/dllmain.c
@@ -1,23 +1,9 @@
/*
- * ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/*
- * Entry Point for win32k.sys
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Driver entry and initialization of win32k
+ * FILE: subsystems/win32/win32k/main/main.c
+ * PROGRAMER:
*/
#include
@@ -30,19 +16,12 @@ HANDLE hModuleWin;
PGDI_HANDLE_TABLE INTERNAL_CALL GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject);
BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
-/* FIXME */
-PGDI_HANDLE_TABLE GdiHandleTable = NULL;
-PSECTION_OBJECT GdiTableSection = NULL;
-
-LIST_ENTRY GlobalDriverListHead;
HANDLE GlobalUserHeap = NULL;
PSECTION_OBJECT GlobalUserHeapSection = NULL;
PSERVERINFO gpsi = NULL; // Global User Server Information.
-HSEMAPHORE hsemDriverMgmt = NULL;
-
SHORT gusLanguageID;
extern ULONG_PTR Win32kSSDT[];
@@ -79,92 +58,101 @@ Win32kProcessCallback(struct _EPROCESS *Process,
/* FIXME - unlock the process */
}
- if (Create)
+ if (Create)
{
- SIZE_T ViewSize = 0;
- LARGE_INTEGER Offset;
- PVOID UserBase = NULL;
- NTSTATUS Status;
- extern PSECTION_OBJECT GlobalUserHeapSection;
- DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
+ SIZE_T ViewSize = 0;
+ LARGE_INTEGER Offset;
+ PVOID UserBase = NULL;
+ NTSTATUS Status;
+ extern PSECTION_OBJECT GlobalUserHeapSection;
+ DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
- /* map the global heap into the process */
- Offset.QuadPart = 0;
- Status = MmMapViewOfSection(GlobalUserHeapSection,
- PsGetCurrentProcess(),
- &UserBase,
- 0,
- 0,
- &Offset,
- &ViewSize,
- ViewUnmap,
- SEC_NO_CHANGE,
- PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to map the global heap! 0x%x\n", Status);
- RETURN(Status);
- }
- Win32Process->HeapMappings.Next = NULL;
- Win32Process->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
- Win32Process->HeapMappings.UserMapping = UserBase;
- Win32Process->HeapMappings.Count = 1;
+ /* map the global heap into the process */
+ Offset.QuadPart = 0;
+ Status = MmMapViewOfSection(GlobalUserHeapSection,
+ PsGetCurrentProcess(),
+ &UserBase,
+ 0,
+ 0,
+ &Offset,
+ &ViewSize,
+ ViewUnmap,
+ SEC_NO_CHANGE,
+ PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map the global heap! 0x%x\n", Status);
+ RETURN(Status);
+ }
+ Win32Process->HeapMappings.Next = NULL;
+ Win32Process->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
+ Win32Process->HeapMappings.UserMapping = UserBase;
+ Win32Process->HeapMappings.Count = 1;
- InitializeListHead(&Win32Process->ClassList);
+ InitializeListHead(&Win32Process->ClassList);
- InitializeListHead(&Win32Process->MenuListHead);
+ InitializeListHead(&Win32Process->MenuListHead);
- InitializeListHead(&Win32Process->GDIBrushAttrFreeList);
- InitializeListHead(&Win32Process->GDIDcAttrFreeList);
+ InitializeListHead(&Win32Process->GDIBrushAttrFreeList);
+ InitializeListHead(&Win32Process->GDIDcAttrFreeList);
- InitializeListHead(&Win32Process->PrivateFontListHead);
- ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
+ InitializeListHead(&Win32Process->PrivateFontListHead);
+ ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
- InitializeListHead(&Win32Process->DriverObjListHead);
- ExInitializeFastMutex(&Win32Process->DriverObjListLock);
+ InitializeListHead(&Win32Process->DriverObjListHead);
+ ExInitializeFastMutex(&Win32Process->DriverObjListLock);
- Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
+ Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
+ EngCreateEvent((PEVENT *)&Win32Process->InputIdleEvent);
+ KeInitializeEvent(Win32Process->InputIdleEvent, NotificationEvent, FALSE);
- if(Process->Peb != NULL)
- {
- /* map the gdi handle table to user land */
- Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(GdiTableSection, Process);
- Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT;
- }
+ if(Process->Peb != NULL)
+ {
+ /* map the gdi handle table to user land */
+ Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(GdiTableSection, Process);
+ Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT;
+ }
- Win32Process->peProcess = Process;
- /* setup process flags */
- Win32Process->W32PF_flags = 0;
+ Win32Process->peProcess = Process;
+ /* setup process flags */
+ Win32Process->W32PF_flags = 0;
}
- else
+ else
{
- DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
- IntCleanupMenus(Process, Win32Process);
- IntCleanupCurIcons(Process, Win32Process);
- CleanupMonitorImpl();
+ DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
+ Win32Process->W32PF_flags |= W32PF_TERMINATED;
+ if (Win32Process->InputIdleEvent)
+ {
+ EngFreeMem((PVOID)Win32Process->InputIdleEvent);
+ Win32Process->InputIdleEvent = NULL;
+ }
- /* no process windows should exist at this point, or the function will assert! */
- DestroyProcessClasses(Win32Process);
+ IntCleanupMenus(Process, Win32Process);
+ IntCleanupCurIcons(Process, Win32Process);
+ CleanupMonitorImpl();
- GDI_CleanupForProcess(Process);
+ /* no process windows should exist at this point, or the function will assert! */
+ DestroyProcessClasses(Win32Process);
- co_IntGraphicsCheck(FALSE);
+ GDI_CleanupForProcess(Process);
- /*
- * Deregister logon application automatically
- */
- if(LogonProcess == Win32Process)
- {
- LogonProcess = NULL;
- }
+ co_IntGraphicsCheck(FALSE);
+
+ /*
+ * Deregister logon application automatically
+ */
+ if(LogonProcess == Win32Process)
+ {
+ LogonProcess = NULL;
+ }
}
- RETURN( STATUS_SUCCESS);
+ RETURN( STATUS_SUCCESS);
CLEANUP:
- UserLeave();
- DPRINT("Leave Win32kProcessCallback, ret=%i\n",_ret_);
- END_CLEANUP;
+ UserLeave();
+ DPRINT("Leave Win32kProcessCallback, ret=%i\n",_ret_);
+ END_CLEANUP;
}
@@ -175,6 +163,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
{
struct _EPROCESS *Process;
PTHREADINFO Win32Thread;
+ int i;
DECLARE_RETURN(NTSTATUS);
DPRINT("Enter Win32kThreadCallback\n");
@@ -200,202 +189,244 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
PsSetThreadWin32Thread(Thread, Win32Thread);
/* FIXME - unlock the process */
}
- if (Type == PsW32ThreadCalloutInitialize)
+ if (Type == PsW32ThreadCalloutInitialize)
{
- HWINSTA hWinSta = NULL;
- PTEB pTeb;
- HDESK hDesk = NULL;
- NTSTATUS Status;
- PUNICODE_STRING DesktopPath;
- PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
+ HWINSTA hWinSta = NULL;
+ PTEB pTeb;
+ HDESK hDesk = NULL;
+ NTSTATUS Status;
+ PUNICODE_STRING DesktopPath;
+ PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
- DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
+ DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
- InitializeListHead(&Win32Thread->WindowListHead);
- InitializeListHead(&Win32Thread->W32CallbackListHead);
- InitializeListHead(&Win32Thread->PtiLink);
-
- /*
- * inherit the thread desktop and process window station (if not yet inherited) from the process startup
- * info structure. See documentation of CreateProcess()
- */
- DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
- Status = IntParseDesktopPath(Process,
- DesktopPath,
- &hWinSta,
- &hDesk);
- if(NT_SUCCESS(Status))
- {
- if(hWinSta != NULL)
+ InitializeListHead(&Win32Thread->WindowListHead);
+ InitializeListHead(&Win32Thread->W32CallbackListHead);
+ InitializeListHead(&Win32Thread->PtiLink);
+ for (i = 0; i < NB_HOOKS; i++)
{
- if(Process != CsrProcess)
- {
- HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL);
- if(hProcessWinSta != NULL)
- {
- /* our process is already assigned to a different window station, we don't need the handle anymore */
- NtClose(hWinSta);
- }
- }
- else
- {
- NtClose(hWinSta);
- }
+ InitializeListHead(&Win32Thread->aphkStart[i]);
}
- if (hDesk != NULL)
+ /*
+ * inherit the thread desktop and process window station (if not yet inherited) from the process startup
+ * info structure. See documentation of CreateProcess()
+ */
+ DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
+ Status = IntParseDesktopPath(Process,
+ DesktopPath,
+ &hWinSta,
+ &hDesk);
+ if(NT_SUCCESS(Status))
{
- PDESKTOP DesktopObject;
- Win32Thread->rpdesk = NULL;
- Status = ObReferenceObjectByHandle(hDesk,
- 0,
- ExDesktopObjectType,
- KernelMode,
- (PVOID*)&DesktopObject,
- NULL);
- NtClose(hDesk);
- if(NT_SUCCESS(Status))
- {
- if (!IntSetThreadDesktop(DesktopObject,
- FALSE))
+ if(hWinSta != NULL)
{
- DPRINT1("Unable to set thread desktop\n");
+ if(Process != CsrProcess)
+ {
+ HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL);
+ if(hProcessWinSta != NULL)
+ {
+ /* our process is already assigned to a different window station, we don't need the handle anymore */
+ NtClose(hWinSta);
+ }
+ }
+ else
+ {
+ NtClose(hWinSta);
+ }
+ }
+
+ if (hDesk != NULL)
+ {
+ PDESKTOP DesktopObject;
+ Win32Thread->rpdesk = NULL;
+ Status = ObReferenceObjectByHandle(hDesk,
+ 0,
+ ExDesktopObjectType,
+ KernelMode,
+ (PVOID*)&DesktopObject,
+ NULL);
+ NtClose(hDesk);
+ if(NT_SUCCESS(Status))
+ {
+ if (!IntSetThreadDesktop(DesktopObject,
+ FALSE))
+ {
+ DPRINT1("Unable to set thread desktop\n");
+ }
+ }
+ else
+ {
+ DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
+ }
}
- }
- else
- {
- DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
- }
}
- }
- Win32Thread->TIF_flags &= ~TIF_INCLEANUP;
- co_IntDestroyCaret(Win32Thread);
- Win32Thread->ppi = PsGetCurrentProcessWin32Process();
- pTeb = NtCurrentTeb();
- if (pTeb)
- {
- Win32Thread->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
- Win32Thread->pClientInfo->pClientThreadInfo = NULL;
- }
- Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
- Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
- Win32Thread->pEThread = Thread;
+ else
+ {
+ DPRINT1("No Desktop handle for this Thread!\n");
+ }
+ Win32Thread->TIF_flags &= ~TIF_INCLEANUP;
+ co_IntDestroyCaret(Win32Thread);
+ Win32Thread->ppi = PsGetCurrentProcessWin32Process();
+ if (Win32Thread->rpdesk && !Win32Thread->pDeskInfo)
+ {
+ Win32Thread->pDeskInfo = Win32Thread->rpdesk->pDeskInfo;
+ }
+ Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
+ Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
+ pTeb = NtCurrentTeb();
+ if (pTeb)
+ { /* Attempt to startup client support which should have been initialized in IntSetThreadDesktop. */
+ PCLIENTINFO pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
+ Win32Thread->pClientInfo = pci;
+ pci->ppi = Win32Thread->ppi;
+ pci->fsHooks = Win32Thread->fsHooks;
+ if (Win32Thread->KeyboardLayout) pci->hKL = Win32Thread->KeyboardLayout->hkl;
+ pci->dwTIFlags = Win32Thread->TIF_flags;
+ /* CI may not have been initialized. */
+ if (!pci->pDeskInfo && Win32Thread->pDeskInfo)
+ {
+ if (!pci->ulClientDelta) pci->ulClientDelta = DesktopHeapGetUserDelta();
+
+ pci->pDeskInfo = (PVOID)((ULONG_PTR)Win32Thread->pDeskInfo - pci->ulClientDelta);
+ }
+ if (Win32Thread->pcti && pci->pDeskInfo)
+ pci->pClientThreadInfo = (PVOID)((ULONG_PTR)Win32Thread->pcti - pci->ulClientDelta);
+ else
+ pci->pClientThreadInfo = NULL;
+ }
+ else
+ {
+ DPRINT1("No TEB for this Thread!\n");
+ }
+ Win32Thread->pEThread = Thread;
}
- else
+ else
{
- PSINGLE_LIST_ENTRY e;
+ PSINGLE_LIST_ENTRY e;
- DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
+ DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
- Win32Thread->TIF_flags |= TIF_INCLEANUP;
- DceFreeThreadDCE(Win32Thread);
- HOOK_DestroyThreadHooks(Thread);
- /* Cleanup timers */
- DestroyTimersForThread(Win32Thread);
- KeSetEvent(Win32Thread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
- UnregisterThreadHotKeys(Thread);
- /* what if this co_ func crash in umode? what will clean us up then? */
- co_DestroyThreadWindows(Thread);
- IntBlockInput(Win32Thread, FALSE);
- MsqDestroyMessageQueue(Win32Thread->MessageQueue);
- IntCleanupThreadCallbacks(Win32Thread);
+ Win32Thread->TIF_flags |= TIF_INCLEANUP;
+ DceFreeThreadDCE(Win32Thread);
+ HOOK_DestroyThreadHooks(Thread);
+ EVENT_DestroyThreadEvents(Thread);
+ /* Cleanup timers */
+ DestroyTimersForThread(Win32Thread);
+ KeSetEvent(Win32Thread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+ UnregisterThreadHotKeys(Thread);
+ /* what if this co_ func crash in umode? what will clean us up then? */
+ co_DestroyThreadWindows(Thread);
+ IntBlockInput(Win32Thread, FALSE);
+ MsqDestroyMessageQueue(Win32Thread->MessageQueue);
+ IntCleanupThreadCallbacks(Win32Thread);
- /* cleanup user object references stack */
- e = PopEntryList(&Win32Thread->ReferencesList);
- while (e)
- {
- PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry);
- DPRINT("thread clean: remove reference obj 0x%x\n",ref->obj);
- UserDereferenceObject(ref->obj);
+ /* cleanup user object references stack */
+ e = PopEntryList(&Win32Thread->ReferencesList);
+ while (e)
+ {
+ PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry);
+ DPRINT("thread clean: remove reference obj 0x%x\n",ref->obj);
+ UserDereferenceObject(ref->obj);
- e = PopEntryList(&Win32Thread->ReferencesList);
- }
+ e = PopEntryList(&Win32Thread->ReferencesList);
+ }
- IntSetThreadDesktop(NULL,
- TRUE);
+ IntSetThreadDesktop(NULL,
+ TRUE);
- PsSetThreadWin32Thread(Thread, NULL);
+
+ PsSetThreadWin32Thread(Thread, NULL);
}
- RETURN( STATUS_SUCCESS);
+ RETURN( STATUS_SUCCESS);
CLEANUP:
- UserLeave();
- DPRINT("Leave Win32kThreadCallback, ret=%i\n",_ret_);
- END_CLEANUP;
+ UserLeave();
+ DPRINT("Leave Win32kThreadCallback, ret=%i\n",_ret_);
+ END_CLEANUP;
}
-/* Only used in ntuser/input.c KeyboardThreadMain(). If it's
- not called there anymore, please delete */
NTSTATUS
Win32kInitWin32Thread(PETHREAD Thread)
{
- PEPROCESS Process;
+ PEPROCESS Process;
- Process = Thread->ThreadsProcess;
+ Process = Thread->ThreadsProcess;
- if (Process->Win32Process == NULL)
+ if (Process->Win32Process == NULL)
{
- /* FIXME - lock the process */
- Process->Win32Process = ExAllocatePoolWithTag(NonPagedPool, sizeof(PROCESSINFO), USERTAG_PROCESSINFO);
+ /* FIXME - lock the process */
+ Process->Win32Process = ExAllocatePoolWithTag(NonPagedPool, sizeof(PROCESSINFO), USERTAG_PROCESSINFO);
- if (Process->Win32Process == NULL)
- return STATUS_NO_MEMORY;
+ if (Process->Win32Process == NULL)
+ return STATUS_NO_MEMORY;
- RtlZeroMemory(Process->Win32Process, sizeof(PROCESSINFO));
- /* FIXME - unlock the process */
+ RtlZeroMemory(Process->Win32Process, sizeof(PROCESSINFO));
+ /* FIXME - unlock the process */
- Win32kProcessCallback(Process, TRUE);
+ Win32kProcessCallback(Process, TRUE);
}
- if (Thread->Tcb.Win32Thread == NULL)
+ if (Thread->Tcb.Win32Thread == NULL)
{
- Thread->Tcb.Win32Thread = ExAllocatePoolWithTag(NonPagedPool, sizeof(THREADINFO), USERTAG_THREADINFO);
- if (Thread->Tcb.Win32Thread == NULL)
- return STATUS_NO_MEMORY;
+ Thread->Tcb.Win32Thread = ExAllocatePoolWithTag(NonPagedPool, sizeof(THREADINFO), USERTAG_THREADINFO);
+ if (Thread->Tcb.Win32Thread == NULL)
+ return STATUS_NO_MEMORY;
- RtlZeroMemory(Thread->Tcb.Win32Thread, sizeof(THREADINFO));
+ RtlZeroMemory(Thread->Tcb.Win32Thread, sizeof(THREADINFO));
- Win32kThreadCallback(Thread, PsW32ThreadCalloutInitialize);
+ Win32kThreadCallback(Thread, PsW32ThreadCalloutInitialize);
}
- return(STATUS_SUCCESS);
+ return(STATUS_SUCCESS);
}
+C_ASSERT(sizeof(SERVERINFO) <= PAGE_SIZE);
+
+// Return on failure
+#define NT_ROF(x) \
+ Status = (x); \
+ if (!NT_SUCCESS(Status)) \
+ { \
+ DPRINT1("Failed '%s' (0x%lx)\n", #x, Status); \
+ return Status; \
+ }
/*
* This definition doesn't work
*/
-NTSTATUS APIENTRY
-DriverEntry (
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath)
+INIT_FUNCTION
+NTSTATUS
+APIENTRY
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
{
- NTSTATUS Status;
- BOOLEAN Result;
- WIN32_CALLOUTS_FPNS CalloutData = {0};
- PVOID GlobalUserHeapBase = NULL;
+ NTSTATUS Status;
+ BOOLEAN Result;
+ WIN32_CALLOUTS_FPNS CalloutData = {0};
+ PVOID GlobalUserHeapBase = NULL;
- /*
- * Register user mode call interface
- * (system service table index = 1)
- */
- Result = KeAddSystemServiceTable (Win32kSSDT,
- NULL,
- Win32kNumberOfSysCalls,
- Win32kSSPT,
- 1);
- if (Result == FALSE)
+ /*
+ * Register user mode call interface
+ * (system service table index = 1)
+ */
+ Result = KeAddSystemServiceTable(Win32kSSDT,
+ NULL,
+ Win32kNumberOfSysCalls,
+ Win32kSSPT,
+ 1);
+ if (Result == FALSE)
{
- DPRINT1("Adding system services failed!\n");
- return STATUS_UNSUCCESSFUL;
+ DPRINT1("Adding system services failed!\n");
+ return STATUS_UNSUCCESSFUL;
}
- hModuleWin = MmPageEntireDriver(DriverEntry);
- DPRINT("Win32k hInstance 0x%x!\n",hModuleWin);
- /*
- * Register Object Manager Callbacks
- */
+ hModuleWin = MmPageEntireDriver(DriverEntry);
+ DPRINT("Win32k hInstance 0x%x!\n",hModuleWin);
+
+ /* Register Object Manager Callbacks */
CalloutData.WindowStationParseProcedure = IntWinStaObjectParse;
CalloutData.WindowStationDeleteProcedure = IntWinStaObjectDelete;
CalloutData.DesktopDeleteProcedure = IntDesktopObjectDelete;
@@ -403,11 +434,10 @@ DriverEntry (
CalloutData.ThreadCallout = Win32kThreadCallback;
CalloutData.BatchFlushRoutine = NtGdiFlushUserBatch;
- /*
- * Register our per-process and per-thread structures.
- */
+ /* Register our per-process and per-thread structures. */
PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData);
+ /* Create the global USER heap */
GlobalUserHeap = UserCreateHeap(&GlobalUserHeapSection,
&GlobalUserHeapBase,
1 * 1024 * 1024); /* FIXME - 1 MB for now... */
@@ -417,133 +447,54 @@ DriverEntry (
return STATUS_UNSUCCESSFUL;
}
- /* Initialize a list of loaded drivers in Win32 subsystem */
- InitializeListHead(&GlobalDriverListHead);
-
- if(!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore();
-
- GdiHandleTable = GDIOBJ_iAllocHandleTable(&GdiTableSection);
- if (GdiHandleTable == NULL)
- {
- DPRINT1("Failed to initialize the GDI handle table.\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = InitUserImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize user implementation!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = InitHotkeyImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize hotkey implementation!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = InitWindowStationImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize window station implementation!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = InitDesktopImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize desktop implementation!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = InitWindowImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize window implementation!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = InitMenuImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize menu implementation!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = InitInputImpl();
- if (!NT_SUCCESS(Status))
+ /* Allocate global server info structure */
+ gpsi = UserHeapAlloc(sizeof(SERVERINFO));
+ if (!gpsi)
{
- DPRINT1("Failed to initialize input implementation.\n");
- return(Status);
+ DPRINT1("Failed allocate server info structure!\n");
+ return STATUS_UNSUCCESSFUL;
}
- Status = InitKeyboardImpl();
- if (!NT_SUCCESS(Status))
+ RtlZeroMemory(gpsi, sizeof(SERVERINFO));
+ DPRINT("Global Server Data -> %x\n", gpsi);
+
+ NT_ROF(InitGdiHandleTable());
+ NT_ROF(InitPaletteImpl());
+
+ /* Create stock objects, ie. precreated objects commonly
+ used by win32 applications */
+ CreateStockObjects();
+ CreateSysColorObjects();
+
+ NT_ROF(InitXlateImpl());
+ NT_ROF(InitPDEVImpl());
+ NT_ROF(InitLDEVImpl());
+ NT_ROF(InitDeviceImpl());
+ NT_ROF(InitDcImpl());
+ NT_ROF(InitUserImpl());
+ NT_ROF(InitHotkeyImpl());
+ NT_ROF(InitWindowStationImpl());
+ NT_ROF(InitDesktopImpl());
+ NT_ROF(InitWindowImpl());
+ NT_ROF(InitMenuImpl());
+ NT_ROF(InitInputImpl());
+ NT_ROF(InitKeyboardImpl());
+ NT_ROF(InitMonitorImpl());
+ NT_ROF(MsqInitializeImpl());
+ NT_ROF(InitTimerImpl());
+ NT_ROF(InitAcceleratorImpl());
+ NT_ROF(InitGuiCheckImpl());
+
+ /* Initialize FreeType library */
+ if (!InitFontSupport())
{
- DPRINT1("Failed to initialize keyboard implementation.\n");
- return(Status);
+ DPRINT1("Unable to initialize font support\n");
+ return Status;
}
- Status = InitMonitorImpl();
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("Failed to initialize monitor implementation!\n");
- return STATUS_UNSUCCESSFUL;
- }
+ gusLanguageID = IntGdiGetLanguageID();
- Status = MsqInitializeImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize message queue implementation.\n");
- return(Status);
- }
-
- Status = InitTimerImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize timer implementation.\n");
- return(Status);
- }
-
- Status = InitAcceleratorImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize accelerator implementation.\n");
- return(Status);
- }
-
- Status = InitGuiCheckImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize GUI check implementation.\n");
- return(Status);
- }
-
- Status = InitDcImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize Device context implementation!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Initialize FreeType library */
- if (! InitFontSupport())
- {
- DPRINT1("Unable to initialize font support\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- InitXlateImpl();
-
- /* Create stock objects, ie. precreated objects commonly
- used by win32 applications */
- CreateStockObjects();
- CreateSysColorObjects();
-
- gusLanguageID = IntGdiGetLanguageID();
-
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
/* EOF */
diff --git a/subsystems/win32/win32k/misc/copy.c b/subsystems/win32/win32k/misc/copy.c
index a40a5be6ffb..6a50d5562dd 100644
--- a/subsystems/win32/win32k/misc/copy.c
+++ b/subsystems/win32/win32k/misc/copy.c
@@ -5,7 +5,7 @@ NTSTATUS _MmCopyFromCaller( PVOID Target, PVOID Source, UINT Bytes ) {
_SEH2_TRY
{
- /* ProbeForRead(Source,Bytes,1); */
+ ProbeForRead(Source,Bytes,1);
RtlCopyMemory(Target,Source,Bytes);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
diff --git a/subsystems/win32/win32k/misc/driver.c b/subsystems/win32/win32k/misc/driver.c
index 8b25b137b33..8b137891791 100644
--- a/subsystems/win32/win32k/misc/driver.c
+++ b/subsystems/win32/win32k/misc/driver.c
@@ -1,621 +1 @@
-/*
- * ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/* $Id$
- *
- * GDI Driver support routines
- * (mostly swiped from Wine)
- *
- */
-#include
-
-#define NDEBUG
-#include
-
-/* #define TRACE_DRV_CALLS to get a log of all calls into the display driver. */
-#undef TRACE_DRV_CALLS
-
-
-typedef struct _GRAPHICS_DRIVER
-{
- PWSTR Name;
- PFN_DrvEnableDriver EnableDriver;
- int ReferenceCount;
- struct _GRAPHICS_DRIVER *Next;
-} GRAPHICS_DRIVER, *PGRAPHICS_DRIVER;
-
-static PGRAPHICS_DRIVER DriverList;
-static PGRAPHICS_DRIVER GenericDriver = NULL;
-
-BOOL DRIVER_RegisterDriver(LPCWSTR Name, PFN_DrvEnableDriver EnableDriver)
-{
- PGRAPHICS_DRIVER Driver;
-
- DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
-
- if (GenericDriver != NULL)
- {
- return FALSE;
- }
- Driver = ExAllocatePoolWithTag(PagedPool, sizeof(*Driver), TAG_DRIVER);
- if (!Driver) return FALSE;
- Driver->ReferenceCount = 0;
- Driver->EnableDriver = EnableDriver;
- if (Name)
- {
- Driver->Name = ExAllocatePoolWithTag(PagedPool,
- (wcslen(Name) + 1) * sizeof(WCHAR),
- TAG_DRIVER);
- if (Driver->Name == NULL)
- {
- DPRINT1("Out of memory\n");
- ExFreePoolWithTag(Driver, TAG_DRIVER);
- return FALSE;
- }
-
- wcscpy(Driver->Name, Name);
- Driver->Next = DriverList;
- DriverList = Driver;
- return TRUE;
- }
-
- GenericDriver = Driver;
- return TRUE;
-}
-
-PFN_DrvEnableDriver DRIVER_FindExistingDDIDriver(LPCWSTR Name)
-{
- GRAPHICS_DRIVER *Driver = DriverList;
- while (Driver && Name)
- {
- if (!_wcsicmp(Driver->Name, Name))
- {
- return Driver->EnableDriver;
- }
- Driver = Driver->Next;
- }
-
- return NULL;
-}
-
-PFN_DrvEnableDriver DRIVER_FindDDIDriver(LPCWSTR Name)
-{
- static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\";
- static WCHAR DefaultExtension[] = L".DLL";
- PFN_DrvEnableDriver ExistingDriver;
- SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
- NTSTATUS Status;
- LPWSTR FullName;
- LPCWSTR p;
- BOOL PathSeparatorFound;
- BOOL DotFound;
- UINT Size;
-
- DotFound = FALSE;
- PathSeparatorFound = FALSE;
- p = Name;
- while (L'\0' != *p)
- {
- if (L'\\' == *p || L'/' == *p)
- {
- PathSeparatorFound = TRUE;
- DotFound = FALSE;
- }
- else if (L'.' == *p)
- {
- DotFound = TRUE;
- }
- p++;
- }
-
- Size = (wcslen(Name) + 1) * sizeof(WCHAR);
- if (! PathSeparatorFound)
- {
- Size += sizeof(DefaultPath) - sizeof(WCHAR);
- }
- if (! DotFound)
- {
- Size += sizeof(DefaultExtension) - sizeof(WCHAR);
- }
- FullName = ExAllocatePoolWithTag(PagedPool, Size, TAG_DRIVER);
- if (NULL == FullName)
- {
- DPRINT1("Out of memory\n");
- return NULL;
- }
- if (PathSeparatorFound)
- {
- FullName[0] = L'\0';
- }
- else
- {
- wcscpy(FullName, DefaultPath);
- }
- wcscat(FullName, Name);
- if (! DotFound)
- {
- wcscat(FullName, DefaultExtension);
- }
-
- /* First see if the driver hasn't already been loaded */
- ExistingDriver = DRIVER_FindExistingDDIDriver(FullName);
- if (ExistingDriver)
- {
- ExFreePoolWithTag(FullName, TAG_DRIVER);
- return ExistingDriver;
- }
-
- /* If not, then load it */
- RtlInitUnicodeString (&GdiDriverInfo.DriverName, FullName);
- Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
-
- if (!NT_SUCCESS(Status))
- {
- ExFreePoolWithTag(FullName, TAG_DRIVER);
- return NULL;
- }
-
- DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
- DRIVER_RegisterDriver( FullName, GdiDriverInfo.EntryPoint);
- ExFreePoolWithTag(FullName, TAG_DRIVER);
- return (PFN_DrvEnableDriver)GdiDriverInfo.EntryPoint;
-}
-
-#define BEGIN_FUNCTION_MAP() \
- ULONG i; \
- for (i = 0; i < DED->c; i++) \
- { \
- switch(DED->pdrvfn[i].iFunc) \
- {
-
-#define END_FUNCTION_MAP() \
- default: \
- DPRINT1("Unsupported DDI function 0x%x\n", DED->pdrvfn[i].iFunc); \
- break; \
- } \
- }
-
-#ifdef TRACE_DRV_CALLS
-
-typedef struct _TRACEDRVINFO
- {
- unsigned Index;
- char *Name;
- PVOID DrvRoutine;
- }
-TRACEDRVINFO, *PTRACEDRVINFO;
-
-__asm__(
-" .text\n"
-"TraceDrv:\n"
-" pushl %eax\n"
-" call _FindTraceInfo\n"
-" add $4,%esp\n"
-" pushl %eax\n"
-" pushl 4(%eax)\n"
-" call _DbgPrint\n"
-" addl $4,%esp\n"
-" popl %eax\n"
-" mov 8(%eax),%eax\n"
-" jmp *%eax\n"
-);
-
-#define TRACEDRV_ROUTINE(function) \
-unsigned TraceDrvIndex##function = INDEX_Drv##function; \
-__asm__ ( \
-" .text\n" \
-"_Trace" #function ":\n" \
-" movl _TraceDrvIndex" #function ",%eax\n" \
-" jmp TraceDrv\n" \
-); \
-extern PVOID Trace##function;
-
-TRACEDRV_ROUTINE(EnablePDEV)
-TRACEDRV_ROUTINE(CompletePDEV)
-TRACEDRV_ROUTINE(DisablePDEV)
-TRACEDRV_ROUTINE(EnableSurface)
-TRACEDRV_ROUTINE(DisableSurface)
-TRACEDRV_ROUTINE(AssertMode)
-TRACEDRV_ROUTINE(Offset)
-TRACEDRV_ROUTINE(ResetPDEV)
-TRACEDRV_ROUTINE(DisableDriver)
-TRACEDRV_ROUTINE(CreateDeviceBitmap)
-TRACEDRV_ROUTINE(DeleteDeviceBitmap)
-TRACEDRV_ROUTINE(RealizeBrush)
-TRACEDRV_ROUTINE(DitherColor)
-TRACEDRV_ROUTINE(StrokePath)
-TRACEDRV_ROUTINE(FillPath)
-TRACEDRV_ROUTINE(StrokeAndFillPath)
-TRACEDRV_ROUTINE(Paint)
-TRACEDRV_ROUTINE(BitBlt)
-TRACEDRV_ROUTINE(TransparentBlt)
-TRACEDRV_ROUTINE(CopyBits)
-TRACEDRV_ROUTINE(StretchBlt)
-TRACEDRV_ROUTINE(StretchBltROP)
-TRACEDRV_ROUTINE(SetPalette)
-TRACEDRV_ROUTINE(TextOut)
-TRACEDRV_ROUTINE(Escape)
-TRACEDRV_ROUTINE(DrawEscape)
-TRACEDRV_ROUTINE(QueryFont)
-TRACEDRV_ROUTINE(QueryFontTree)
-TRACEDRV_ROUTINE(QueryFontData)
-TRACEDRV_ROUTINE(SetPointerShape)
-TRACEDRV_ROUTINE(MovePointer)
-TRACEDRV_ROUTINE(LineTo)
-TRACEDRV_ROUTINE(SendPage)
-TRACEDRV_ROUTINE(StartPage)
-TRACEDRV_ROUTINE(EndDoc)
-TRACEDRV_ROUTINE(StartDoc)
-TRACEDRV_ROUTINE(GetGlyphMode)
-TRACEDRV_ROUTINE(Synchronize)
-TRACEDRV_ROUTINE(SaveScreenBits)
-TRACEDRV_ROUTINE(GetModes)
-TRACEDRV_ROUTINE(Free)
-TRACEDRV_ROUTINE(DestroyFont)
-TRACEDRV_ROUTINE(QueryFontCaps)
-TRACEDRV_ROUTINE(LoadFontFile)
-TRACEDRV_ROUTINE(UnloadFontFile)
-TRACEDRV_ROUTINE(FontManagement)
-TRACEDRV_ROUTINE(QueryTrueTypeTable)
-TRACEDRV_ROUTINE(QueryTrueTypeOutline)
-TRACEDRV_ROUTINE(GetTrueTypeFile)
-TRACEDRV_ROUTINE(QueryFontFile)
-TRACEDRV_ROUTINE(QueryAdvanceWidths)
-TRACEDRV_ROUTINE(SetPixelFormat)
-TRACEDRV_ROUTINE(DescribePixelFormat)
-TRACEDRV_ROUTINE(SwapBuffers)
-TRACEDRV_ROUTINE(StartBanding)
-TRACEDRV_ROUTINE(NextBand)
-TRACEDRV_ROUTINE(GetDirectDrawInfo)
-TRACEDRV_ROUTINE(EnableDirectDraw)
-TRACEDRV_ROUTINE(DisableDirectDraw)
-TRACEDRV_ROUTINE(QuerySpoolType)
-TRACEDRV_ROUTINE(IcmSetDeviceGammaRamp)
-TRACEDRV_ROUTINE(GradientFill)
-TRACEDRV_ROUTINE(SynchronizeSurface)
-TRACEDRV_ROUTINE(AlphaBlend)
-
-#define TRACEDRVINFO_ENTRY(function) \
- { INDEX_Drv##function, "Drv" #function "\n", NULL }
-static TRACEDRVINFO TraceDrvInfo[] =
- {
- TRACEDRVINFO_ENTRY(EnablePDEV),
- TRACEDRVINFO_ENTRY(CompletePDEV),
- TRACEDRVINFO_ENTRY(DisablePDEV),
- TRACEDRVINFO_ENTRY(EnableSurface),
- TRACEDRVINFO_ENTRY(DisableSurface),
- TRACEDRVINFO_ENTRY(AssertMode),
- TRACEDRVINFO_ENTRY(Offset),
- TRACEDRVINFO_ENTRY(ResetPDEV),
- TRACEDRVINFO_ENTRY(DisableDriver),
- TRACEDRVINFO_ENTRY(CreateDeviceBitmap),
- TRACEDRVINFO_ENTRY(DeleteDeviceBitmap),
- TRACEDRVINFO_ENTRY(RealizeBrush),
- TRACEDRVINFO_ENTRY(DitherColor),
- TRACEDRVINFO_ENTRY(StrokePath),
- TRACEDRVINFO_ENTRY(FillPath),
- TRACEDRVINFO_ENTRY(StrokeAndFillPath),
- TRACEDRVINFO_ENTRY(Paint),
- TRACEDRVINFO_ENTRY(BitBlt),
- TRACEDRVINFO_ENTRY(TransparentBlt),
- TRACEDRVINFO_ENTRY(CopyBits),
- TRACEDRVINFO_ENTRY(StretchBlt),
- TRACEDRVINFO_ENTRY(StretchBltROP),
- TRACEDRVINFO_ENTRY(SetPalette),
- TRACEDRVINFO_ENTRY(TextOut),
- TRACEDRVINFO_ENTRY(Escape),
- TRACEDRVINFO_ENTRY(DrawEscape),
- TRACEDRVINFO_ENTRY(QueryFont),
- TRACEDRVINFO_ENTRY(QueryFontTree),
- TRACEDRVINFO_ENTRY(QueryFontData),
- TRACEDRVINFO_ENTRY(SetPointerShape),
- TRACEDRVINFO_ENTRY(MovePointer),
- TRACEDRVINFO_ENTRY(LineTo),
- TRACEDRVINFO_ENTRY(SendPage),
- TRACEDRVINFO_ENTRY(StartPage),
- TRACEDRVINFO_ENTRY(EndDoc),
- TRACEDRVINFO_ENTRY(StartDoc),
- TRACEDRVINFO_ENTRY(GetGlyphMode),
- TRACEDRVINFO_ENTRY(Synchronize),
- TRACEDRVINFO_ENTRY(SaveScreenBits),
- TRACEDRVINFO_ENTRY(GetModes),
- TRACEDRVINFO_ENTRY(Free),
- TRACEDRVINFO_ENTRY(DestroyFont),
- TRACEDRVINFO_ENTRY(QueryFontCaps),
- TRACEDRVINFO_ENTRY(LoadFontFile),
- TRACEDRVINFO_ENTRY(UnloadFontFile),
- TRACEDRVINFO_ENTRY(FontManagement),
- TRACEDRVINFO_ENTRY(QueryTrueTypeTable),
- TRACEDRVINFO_ENTRY(QueryTrueTypeOutline),
- TRACEDRVINFO_ENTRY(GetTrueTypeFile),
- TRACEDRVINFO_ENTRY(QueryFontFile),
- TRACEDRVINFO_ENTRY(QueryAdvanceWidths),
- TRACEDRVINFO_ENTRY(SetPixelFormat),
- TRACEDRVINFO_ENTRY(DescribePixelFormat),
- TRACEDRVINFO_ENTRY(SwapBuffers),
- TRACEDRVINFO_ENTRY(StartBanding),
- TRACEDRVINFO_ENTRY(NextBand),
- TRACEDRVINFO_ENTRY(GetDirectDrawInfo),
- TRACEDRVINFO_ENTRY(EnableDirectDraw),
- TRACEDRVINFO_ENTRY(DisableDirectDraw),
- TRACEDRVINFO_ENTRY(QuerySpoolType),
- TRACEDRVINFO_ENTRY(IcmSetDeviceGammaRamp),
- TRACEDRVINFO_ENTRY(GradientFill),
- TRACEDRVINFO_ENTRY(SynchronizeSurface),
- TRACEDRVINFO_ENTRY(AlphaBlend)
- };
-
-PTRACEDRVINFO
-FindTraceInfo(unsigned Index)
-{
- unsigned i;
-
- for (i = 0; i < sizeof(TraceDrvInfo) / sizeof(TRACEDRVINFO); i++)
- {
- if (TraceDrvInfo[i].Index == Index)
- {
- return TraceDrvInfo + i;
- }
- }
-
- return NULL;
-}
-
-#define DRIVER_FUNCTION(function) \
- case INDEX_Drv##function: \
- FindTraceInfo(INDEX_Drv##function)->DrvRoutine = DED->pdrvfn[i].pfn; \
- *(PVOID*)&DF->function = &Trace##function; \
- break
-#else
-#define DRIVER_FUNCTION(function) \
- case INDEX_Drv##function: \
- *(PVOID*)&DF->function = DED->pdrvfn[i].pfn; \
- break
-#endif
-
-BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
- PDRIVER_FUNCTIONS DF)
-{
- BEGIN_FUNCTION_MAP();
- DRIVER_FUNCTION(EnablePDEV);
- DRIVER_FUNCTION(CompletePDEV);
- DRIVER_FUNCTION(DisablePDEV);
- DRIVER_FUNCTION(EnableSurface);
- DRIVER_FUNCTION(DisableSurface);
- DRIVER_FUNCTION(AssertMode);
- DRIVER_FUNCTION(Offset);
- DRIVER_FUNCTION(ResetPDEV);
- DRIVER_FUNCTION(DisableDriver);
- DRIVER_FUNCTION(Unknown1);
- DRIVER_FUNCTION(CreateDeviceBitmap);
- DRIVER_FUNCTION(DeleteDeviceBitmap);
- DRIVER_FUNCTION(RealizeBrush);
- DRIVER_FUNCTION(DitherColor);
- DRIVER_FUNCTION(StrokePath);
- DRIVER_FUNCTION(FillPath);
- DRIVER_FUNCTION(StrokeAndFillPath);
- DRIVER_FUNCTION(Paint);
- DRIVER_FUNCTION(BitBlt);
- DRIVER_FUNCTION(CopyBits);
- DRIVER_FUNCTION(StretchBlt);
- DRIVER_FUNCTION(Unknown2);
- DRIVER_FUNCTION(SetPalette);
- DRIVER_FUNCTION(TextOut);
- DRIVER_FUNCTION(Escape);
- DRIVER_FUNCTION(DrawEscape);
- DRIVER_FUNCTION(QueryFont);
- DRIVER_FUNCTION(QueryFontTree);
- DRIVER_FUNCTION(QueryFontData);
- DRIVER_FUNCTION(SetPointerShape);
- DRIVER_FUNCTION(MovePointer);
- DRIVER_FUNCTION(LineTo);
- DRIVER_FUNCTION(SendPage);
- DRIVER_FUNCTION(StartPage);
- DRIVER_FUNCTION(EndDoc);
- DRIVER_FUNCTION(StartDoc);
- DRIVER_FUNCTION(Unknown3);
- DRIVER_FUNCTION(GetGlyphMode);
- DRIVER_FUNCTION(Synchronize);
- DRIVER_FUNCTION(Unknown4);
- DRIVER_FUNCTION(SaveScreenBits);
- DRIVER_FUNCTION(GetModes);
- DRIVER_FUNCTION(Free);
- DRIVER_FUNCTION(DestroyFont);
- DRIVER_FUNCTION(QueryFontCaps);
- DRIVER_FUNCTION(LoadFontFile);
- DRIVER_FUNCTION(UnloadFontFile);
- DRIVER_FUNCTION(FontManagement);
- DRIVER_FUNCTION(QueryTrueTypeTable);
- DRIVER_FUNCTION(QueryTrueTypeOutline);
- DRIVER_FUNCTION(GetTrueTypeFile);
- DRIVER_FUNCTION(QueryFontFile);
- DRIVER_FUNCTION(QueryAdvanceWidths);
- DRIVER_FUNCTION(SetPixelFormat);
- DRIVER_FUNCTION(DescribePixelFormat);
- DRIVER_FUNCTION(SwapBuffers);
- DRIVER_FUNCTION(StartBanding);
- DRIVER_FUNCTION(NextBand);
- DRIVER_FUNCTION(GetDirectDrawInfo);
- DRIVER_FUNCTION(EnableDirectDraw);
- DRIVER_FUNCTION(DisableDirectDraw);
- DRIVER_FUNCTION(QuerySpoolType);
- DRIVER_FUNCTION(Unknown5);
- DRIVER_FUNCTION(IcmCreateColorTransform);
- DRIVER_FUNCTION(IcmDeleteColorTransform);
- DRIVER_FUNCTION(IcmCheckBitmapBits);
- DRIVER_FUNCTION(IcmSetDeviceGammaRamp);
- DRIVER_FUNCTION(GradientFill);
- DRIVER_FUNCTION(StretchBltROP);
- DRIVER_FUNCTION(PlgBlt);
- DRIVER_FUNCTION(AlphaBlend);
- DRIVER_FUNCTION(SynthesizeFont);
- DRIVER_FUNCTION(GetSynthesizedFontFiles);
- DRIVER_FUNCTION(TransparentBlt);
- DRIVER_FUNCTION(QueryPerBandInfo);
- DRIVER_FUNCTION(QueryDeviceSupport);
- DRIVER_FUNCTION(Reserved1);
- DRIVER_FUNCTION(Reserved2);
- DRIVER_FUNCTION(Reserved3);
- DRIVER_FUNCTION(Reserved4);
- DRIVER_FUNCTION(Reserved5);
- DRIVER_FUNCTION(Reserved6);
- DRIVER_FUNCTION(Reserved7);
- DRIVER_FUNCTION(Reserved8);
- DRIVER_FUNCTION(DeriveSurface);
- DRIVER_FUNCTION(QueryGlyphAttrs);
- DRIVER_FUNCTION(Notify);
- DRIVER_FUNCTION(SynchronizeSurface);
- DRIVER_FUNCTION(ResetDevice);
- DRIVER_FUNCTION(Reserved9);
- DRIVER_FUNCTION(Reserved10);
- DRIVER_FUNCTION(Reserved11);
- END_FUNCTION_MAP();
-
- return TRUE;
-}
-
-typedef LONG VP_STATUS;
-typedef VP_STATUS (APIENTRY *PMP_DRIVERENTRY)(PVOID, PVOID);
-
-PFILE_OBJECT DRIVER_FindMPDriver(ULONG DisplayNumber)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- WCHAR DeviceNameBuffer[20];
- UNICODE_STRING DeviceName;
- IO_STATUS_BLOCK Iosb;
- HANDLE DisplayHandle;
- NTSTATUS Status;
- PFILE_OBJECT VideoFileObject;
-
- swprintf(DeviceNameBuffer, L"\\??\\DISPLAY%d", DisplayNumber + 1);
- RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
- InitializeObjectAttributes(&ObjectAttributes,
- &DeviceName,
- 0,
- NULL,
- NULL);
- Status = ZwOpenFile(&DisplayHandle,
- FILE_ALL_ACCESS,
- &ObjectAttributes,
- &Iosb,
- 0,
- FILE_SYNCHRONOUS_IO_ALERT);
- if (NT_SUCCESS(Status))
- {
- Status = ObReferenceObjectByHandle(DisplayHandle,
- FILE_READ_DATA | FILE_WRITE_DATA,
- IoFileObjectType,
- KernelMode,
- (PVOID *)&VideoFileObject,
- NULL);
- ZwClose(DisplayHandle);
- }
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to connect to miniport (Status %lx)\n", Status);
- DPRINT1("Perhaps the miniport wasn't loaded?\n");
- return(NULL);
- }
-
- return VideoFileObject;
-}
-
-
-BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
-{
- PGRAPHICS_DRIVER Driver = NULL;
-
- if (Name)
- {
- if (DriverList != NULL)
- {
- if (!_wcsicmp(DriverList->Name, Name))
- {
- Driver = DriverList;
- DriverList = DriverList->Next;
- }
- else
- {
- Driver = DriverList;
- while (Driver->Next && _wcsicmp(Driver->Name, Name))
- {
- Driver = Driver->Next;
- }
- }
- }
- }
- else
- {
- if (GenericDriver != NULL)
- {
- Driver = GenericDriver;
- GenericDriver = NULL;
- }
- }
-
- if (Driver != NULL)
- {
- ExFreePoolWithTag(Driver->Name, TAG_DRIVER);
- ExFreePoolWithTag(Driver, TAG_DRIVER);
-
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-INT DRIVER_ReferenceDriver (LPCWSTR Name)
-{
- GRAPHICS_DRIVER *Driver = DriverList;
-
- while (Driver && Name)
- {
- DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
- if (!_wcsicmp( Driver->Name, Name))
- {
- return ++Driver->ReferenceCount;
- }
- Driver = Driver->Next;
- }
- DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
- ASSERT( GenericDriver != 0 );
- return ++GenericDriver->ReferenceCount;
-}
-
-INT DRIVER_UnreferenceDriver (LPCWSTR Name)
-{
- GRAPHICS_DRIVER *Driver = DriverList;
-
- while (Driver && Name)
- {
- DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
- if (!_wcsicmp( Driver->Name, Name))
- {
- return --Driver->ReferenceCount;
- }
- Driver = Driver->Next;
- }
- DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
- ASSERT( GenericDriver != 0 );
- return --GenericDriver->ReferenceCount;
-}
-/* EOF */
diff --git a/subsystems/win32/win32k/misc/file.c b/subsystems/win32/win32k/misc/file.c
index 1e2281aa517..856de99015d 100644
--- a/subsystems/win32/win32k/misc/file.c
+++ b/subsystems/win32/win32k/misc/file.c
@@ -149,213 +149,98 @@ W32kMapViewOfSection(
return pvBase;
}
-typedef struct tagBITMAPV5INFO
-{
- BITMAPV5HEADER bmiHeader;
- RGBQUAD bmiColors[256];
-} BITMAPV5INFO, *PBITMAPV5INFO;
-
-// FIXME: this should go to dibobj.c
-NTSTATUS
-ProbeAndConvertBitmapInfo(
- OUT BITMAPV5HEADER *pbmhDst,
- OUT RGBQUAD *pbmiColorsDst,
- ULONG cColors,
- IN PBITMAPINFO pbmiUnsafe)
-{
- DWORD dwSize;
- RGBQUAD *pbmiColors;
- ULONG ulWidthBytes;
-
- /* Get the size and probe */
- ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
- dwSize = pbmiUnsafe->bmiHeader.biSize;
- ProbeForRead(pbmiUnsafe, dwSize, 1);
-
- /* Check the size */
- // FIXME: are intermediate sizes allowed? As what are they interpreted?
- // make sure we don't use a too big dwSize later
- if (dwSize != sizeof(BITMAPCOREHEADER) &&
- dwSize != sizeof(BITMAPINFOHEADER) &&
- dwSize != sizeof(BITMAPV4HEADER) &&
- dwSize != sizeof(BITMAPV5HEADER))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- pbmiColors = (RGBQUAD*)((PCHAR)pbmiUnsafe + dwSize);
-
- pbmhDst->bV5Size = sizeof(BITMAPV5HEADER);
-
- if (dwSize == sizeof(BITMAPCOREHEADER))
- {
- PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmiUnsafe;
-
- /* Manually copy the fields that are present */
- pbmhDst->bV5Width = pbch->bcWidth;
- pbmhDst->bV5Height = pbch->bcHeight;
- pbmhDst->bV5Planes = pbch->bcPlanes;
- pbmhDst->bV5BitCount = pbch->bcBitCount;
-
- /* Set some default values */
- pbmhDst->bV5Compression = BI_RGB;
- pbmhDst->bV5SizeImage = 0;
- pbmhDst->bV5XPelsPerMeter = 72;
- pbmhDst->bV5YPelsPerMeter = 72;
- pbmhDst->bV5ClrUsed = 0;
- pbmhDst->bV5ClrImportant = 0;
- }
- else
- {
- /* Copy valid fields */
- memcpy(pbmhDst, pbmiUnsafe, dwSize);
-
- /* Zero out the rest of the V5 header */
- memset((char*)pbmhDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize);
- }
-
-
- if (dwSize < sizeof(BITMAPV4HEADER))
- {
- if (pbmhDst->bV5Compression == BI_BITFIELDS)
- {
- DWORD *pMasks = (DWORD*)pbmiColors;
- pbmhDst->bV5RedMask = pMasks[0];
- pbmhDst->bV5GreenMask = pMasks[1];
- pbmhDst->bV5BlueMask = pMasks[2];
- pbmhDst->bV5AlphaMask = 0;
- pbmhDst->bV5ClrUsed = 0;
- }
-
-// pbmhDst->bV5CSType;
-// pbmhDst->bV5Endpoints;
-// pbmhDst->bV5GammaRed;
-// pbmhDst->bV5GammaGreen;
-// pbmhDst->bV5GammaBlue;
- }
-
- if (dwSize < sizeof(BITMAPV5HEADER))
- {
-// pbmhDst->bV5Intent;
-// pbmhDst->bV5ProfileData;
-// pbmhDst->bV5ProfileSize;
-// pbmhDst->bV5Reserved;
- }
-
- ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes *
- pbmhDst->bV5BitCount + 31) & ~31) / 8;
-
- if (pbmhDst->bV5SizeImage == 0)
- pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height);
-
- if (pbmhDst->bV5ClrUsed == 0)
- pbmhDst->bV5ClrUsed = pbmhDst->bV5BitCount == 1 ? 2 :
- (pbmhDst->bV5BitCount == 4 ? 16 :
- (pbmhDst->bV5BitCount == 8 ? 256 : 0));
-
- if (pbmhDst->bV5Planes != 1)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- if (pbmhDst->bV5BitCount != 0 && pbmhDst->bV5BitCount != 1 &&
- pbmhDst->bV5BitCount != 4 && pbmhDst->bV5BitCount != 8 &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 24 &&
- pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Invalid bit count: %d\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
-
- if ((pbmhDst->bV5BitCount == 0 &&
- pbmhDst->bV5Compression != BI_JPEG && pbmhDst->bV5Compression != BI_PNG))
- {
- DPRINT("Bit count 0 is invalid for compression %d.\n", pbmhDst->bV5Compression);
- return STATUS_INVALID_PARAMETER;
- }
-
- if (pbmhDst->bV5Compression == BI_BITFIELDS &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Copy Colors */
- cColors = min(cColors, pbmhDst->bV5ClrUsed);
- memcpy(pbmiColorsDst, pbmiColors, cColors * sizeof(RGBQUAD));
-
- return STATUS_SUCCESS;
-}
-
-
HBITMAP
NTAPI
UserLoadImage(PCWSTR pwszName)
{
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
HANDLE hFile, hSection;
BITMAPFILEHEADER *pbmfh;
LPBITMAPINFO pbmi;
- ULONG cjInfoSize;
PVOID pvBits;
HBITMAP hbmp = 0;
- BITMAPV5INFO bmiLocal;
+
+ DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
/* Open the file */
hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
- if (hFile == INVALID_HANDLE_VALUE)
- return NULL;
+ if (!hFile)
+ {
+ return NULL;
+ }
/* Create a section */
hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
ZwClose(hFile);
if (!hSection)
- return NULL;
+ {
+ return NULL;
+ }
/* Map the section */
pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
ZwClose(hSection);
if (!pbmfh)
- return NULL;
+ {
+ return NULL;
+ }
/* Get a pointer to the BITMAPINFO */
pbmi = (LPBITMAPINFO)(pbmfh + 1);
- /* Create a normalized local BITMAPINFO */
- _SEH2_TRY
- {
- Status = ProbeAndConvertBitmapInfo(&bmiLocal.bmiHeader,
- bmiLocal.bmiColors,
- 256,
- pbmi);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
+ _SEH2_TRY
+ {
+ ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1);
+ ProbeForRead(pbmfh, pbmfh->bfSize, 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
- if (NT_SUCCESS(Status))
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Bad File?\n");
+ goto leave;
+ }
+
+ if (pbmfh->bfType == 0x4D42 /* 'BM' */)
{
- cjInfoSize = bmiLocal.bmiHeader.bV5Size +
- bmiLocal.bmiHeader.bV5ClrUsed * sizeof(RGBQUAD);
- pvBits = (PVOID)((PCHAR)pbmi + cjInfoSize);
+ /* Could be BITMAPCOREINFO */
+ BITMAPINFO* pConvertedInfo;
+ HDC hdc;
- // FIXME: use Gre... so that the BITMAPINFO doesn't get probed
- hbmp = NtGdiCreateDIBitmapInternal(NULL,
- bmiLocal.bmiHeader.bV5Width,
- bmiLocal.bmiHeader.bV5Height,
- CBM_INIT,
- pvBits,
- pbmi,
- DIB_RGB_COLORS,
- bmiLocal.bmiHeader.bV5Size,
- bmiLocal.bmiHeader.bV5SizeImage,
- 0,
- 0);
+ pvBits = (PVOID)((PCHAR)pbmfh + pbmfh->bfOffBits);
+
+ pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS);
+ if(!pConvertedInfo)
+ {
+ DPRINT1("Unable to convert the bitmap Info\n");
+ goto leave;
+ }
+
+ hdc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
+
+ hbmp = GreCreateDIBitmapInternal(hdc,
+ pConvertedInfo->bmiHeader.biWidth,
+ pConvertedInfo->bmiHeader.biHeight,
+ CBM_INIT,
+ pvBits,
+ pConvertedInfo,
+ DIB_RGB_COLORS,
+ 0,
+ 0);
+
+ NtGdiDeleteObjectApp(hdc);
+ DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi);
}
+ else
+ {
+ DPRINT1("Unknown file type!\n");
+ }
+leave:
/* Unmap our section, we don't need it anymore */
ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
diff --git a/subsystems/win32/win32k/misc/i386/atan2_asm.s b/subsystems/win32/win32k/misc/i386/atan2_asm.s
index 1ce05320559..75aca5f7b30 100644
--- a/subsystems/win32/win32k/misc/i386/atan2_asm.s
+++ b/subsystems/win32/win32k/misc/i386/atan2_asm.s
@@ -33,13 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _atan2
-
-.intel_syntax noprefix
+#include
+
/* FUNCTIONS ***************************************************************/
+.code
+PUBLIC _atan2
_atan2:
push ebp
mov ebp,esp
@@ -49,3 +49,5 @@ _atan2:
mov esp,ebp
pop ebp
ret
+
+END
diff --git a/subsystems/win32/win32k/misc/i386/ceil_asm.s b/subsystems/win32/win32k/misc/i386/ceil_asm.s
index aad69114f5a..1256fa1cf00 100644
--- a/subsystems/win32/win32k/misc/i386/ceil_asm.s
+++ b/subsystems/win32/win32k/misc/i386/ceil_asm.s
@@ -33,13 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _ceil
-.intel_syntax noprefix
+#include
/* FUNCTIONS ***************************************************************/
+.code
+PUBLIC _ceil
_ceil:
push ebp
mov ebp,esp
@@ -47,7 +47,7 @@ _ceil:
fld qword ptr [ebp+8] // Load real from stack
fstcw [ebp-2] // Save control word
fclex // Clear exceptions
- mov word ptr [ebp-4],0xb63 // Rounding control word
+ mov word ptr [ebp-4],HEX(b63) // Rounding control word
fldcw [ebp-4] // Set new rounding control
frndint // Round to integer
fclex // Clear exceptions
@@ -55,3 +55,5 @@ _ceil:
mov esp,ebp // Deallocate temporary space
pop ebp
ret
+
+END
diff --git a/subsystems/win32/win32k/misc/i386/cos_asm.s b/subsystems/win32/win32k/misc/i386/cos_asm.s
index b1c6ada49b2..8b525755b17 100644
--- a/subsystems/win32/win32k/misc/i386/cos_asm.s
+++ b/subsystems/win32/win32k/misc/i386/cos_asm.s
@@ -33,13 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _cos
-.intel_syntax noprefix
+#include
/* FUNCTIONS ***************************************************************/
+.code
+PUBLIC _cos
_cos:
push ebp
mov ebp,esp // Point to the stack frame
@@ -47,3 +47,5 @@ _cos:
fcos // Take the cosine
pop ebp
ret
+
+END
diff --git a/subsystems/win32/win32k/misc/i386/floor_asm.s b/subsystems/win32/win32k/misc/i386/floor_asm.s
index f03c85cb4e8..1f5f2b107df 100644
--- a/subsystems/win32/win32k/misc/i386/floor_asm.s
+++ b/subsystems/win32/win32k/misc/i386/floor_asm.s
@@ -33,13 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _floor
-
-.intel_syntax noprefix
+
+#include
/* FUNCTIONS ***************************************************************/
+.code
+PUBLIC _floor
_floor:
push ebp
mov ebp,esp
@@ -47,7 +47,7 @@ _floor:
fld qword ptr [ebp+8] // Load real from stack
fstcw [ebp-2] // Save control word
fclex // Clear exceptions
- mov word ptr [ebp-4],0x763 // Rounding control word
+ mov word ptr [ebp-4],HEX(763) // Rounding control word
fldcw [ebp-4] // Set new rounding control
frndint // Round to integer
fclex // Clear exceptions
@@ -55,3 +55,5 @@ _floor:
mov esp,ebp
pop ebp
ret
+
+END
diff --git a/subsystems/win32/win32k/misc/i386/sin_asm.s b/subsystems/win32/win32k/misc/i386/sin_asm.s
index 39791a3e989..7ec0fa69c23 100644
--- a/subsystems/win32/win32k/misc/i386/sin_asm.s
+++ b/subsystems/win32/win32k/misc/i386/sin_asm.s
@@ -33,13 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-.globl _sin
-.intel_syntax noprefix
+#include
/* FUNCTIONS ***************************************************************/
+.code
+PUBLIC _sin
_sin:
push ebp // Save register bp
mov ebp,esp // Point to the stack frame
@@ -47,3 +47,5 @@ _sin:
fsin // Take the sine
pop ebp // Restore register bp
ret
+
+END
diff --git a/subsystems/win32/win32k/misc/registry.c b/subsystems/win32/win32k/misc/registry.c
index fcaefabb62f..86bac347f2f 100644
--- a/subsystems/win32/win32k/misc/registry.c
+++ b/subsystems/win32/win32k/misc/registry.c
@@ -11,6 +11,134 @@
#define NDEBUG
#include
+NTSTATUS
+NTAPI
+RegOpenKey(
+ LPCWSTR pwszKeyName,
+ PHKEY phkey)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING ustrKeyName;
+ HKEY hkey;
+
+ /* Initialize the key name */
+ RtlInitUnicodeString(&ustrKeyName, pwszKeyName);
+
+ /* Initialize object attributes */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ustrKeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ /* Open the key */
+ Status = ZwOpenKey(&hkey, KEY_READ, &ObjectAttributes);
+ if (NT_SUCCESS(Status))
+ {
+ *phkey = hkey;
+ }
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+RegQueryValue(
+ IN HKEY hkey,
+ IN PCWSTR pwszValueName,
+ IN ULONG ulType,
+ OUT PVOID pvData,
+ IN OUT PULONG pcbValue)
+{
+ NTSTATUS Status;
+ UNICODE_STRING ustrValueName;
+ BYTE ajBuffer[100];
+ PKEY_VALUE_PARTIAL_INFORMATION pInfo;
+ ULONG cbInfoSize, cbDataSize;
+
+ /* Check if the local buffer is sufficient */
+ cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + *pcbValue;
+ if (cbInfoSize <= sizeof(ajBuffer))
+ {
+ pInfo = (PVOID)ajBuffer;
+ }
+ else
+ {
+ /* It's not, allocate a sufficient buffer */
+ pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP);
+ if (!pInfo)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ /* Query the value */
+ RtlInitUnicodeString(&ustrValueName, pwszValueName);
+ Status = ZwQueryValueKey(hkey,
+ &ustrValueName,
+ KeyValuePartialInformation,
+ (PVOID)pInfo,
+ cbInfoSize,
+ &cbInfoSize);
+
+ cbDataSize = cbInfoSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* Did we get the right type */
+ if (pInfo->Type == ulType)
+ {
+ /* Copy the contents to the caller */
+ RtlCopyMemory(pvData, pInfo->Data, min(*pcbValue, cbDataSize));
+ }
+ else
+ Status = STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ /* Return the data size to the caller */
+ *pcbValue = cbDataSize;
+
+ /* Cleanup */
+ if (pInfo != (PVOID)ajBuffer)
+ ExFreePoolWithTag(pInfo, TAG_TEMP);
+
+ return Status;
+
+}
+
+VOID
+NTAPI
+RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData)
+{
+ UNICODE_STRING ustrValue;
+ UNICODE_STRING ustrData;
+
+ RtlInitUnicodeString(&ustrValue, pwszValue);
+ RtlInitUnicodeString(&ustrData, pwszData);
+ ZwSetValueKey(hkey, &ustrValue, 0, REG_SZ, &ustrData, ustrData.Length + sizeof(WCHAR));
+}
+
+VOID
+NTAPI
+RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData)
+{
+ UNICODE_STRING ustrValue;
+
+ RtlInitUnicodeString(&ustrValue, pwszValue);
+ ZwSetValueKey(hkey, &ustrValue, 0, REG_DWORD, &dwData, sizeof(DWORD));
+}
+
+BOOL
+NTAPI
+RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData)
+{
+ NTSTATUS Status;
+ ULONG cbSize = sizeof(DWORD);
+ Status = RegQueryValue(hkey, pwszValue, REG_DWORD, pdwData, &cbSize);
+ return NT_SUCCESS(Status);
+}
+
BOOL
NTAPI
RegReadUserSetting(
@@ -163,7 +291,8 @@ RegWriteUserSetting(
Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
if (!NT_SUCCESS(Status))
{
- DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n", Status, usKeyName.Length, usKeyName.MaximumLength);
+ DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n",
+ Status, usKeyName.Length, usKeyName.MaximumLength);
return FALSE;
}
diff --git a/subsystems/win32/win32k/ntddraw/dxeng.c b/subsystems/win32/win32k/ntddraw/dxeng.c
index 58413a584ff..135c048b07b 100644
--- a/subsystems/win32/win32k/ntddraw/dxeng.c
+++ b/subsystems/win32/win32k/ntddraw/dxeng.c
@@ -1,4 +1,4 @@
- /*
+/*
* PROJECT: ReactOS Win32 Subsystem
* LICENSE: GPL - See COPYING in the top level directory
* FILE: subsystems/win32/win32k/ntddraw/dxeng.c
@@ -297,8 +297,7 @@ DxEngGetHdevData(HDEV hDev,
break;
case DxEGShDevData_hSpooler:
DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_hSpooler\n");
- // retVal = (DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver.
- retVal = (DWORD_PTR) PDev->VideoFileObject->DeviceObject;
+ retVal = 0;//(DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver.
break;
case DxEGShDevData_DitherFmt:
DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_DitherFmt\n");
diff --git a/subsystems/win32/win32k/ntuser/accelerator.c b/subsystems/win32/win32k/ntuser/accelerator.c
index a913de1ebfa..cb0eca60d00 100644
--- a/subsystems/win32/win32k/ntuser/accelerator.c
+++ b/subsystems/win32/win32k/ntuser/accelerator.c
@@ -56,7 +56,9 @@
/* FUNCTIONS *****************************************************************/
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitAcceleratorImpl(VOID)
{
return(STATUS_SUCCESS);
diff --git a/subsystems/win32/win32k/ntuser/callback.c b/subsystems/win32/win32k/ntuser/callback.c
index e536d4ca7e1..bb087f074f5 100644
--- a/subsystems/win32/win32k/ntuser/callback.c
+++ b/subsystems/win32/win32k/ntuser/callback.c
@@ -324,20 +324,19 @@ co_IntCallHookProc(INT HookId,
PUNICODE_STRING ModuleName)
{
ULONG ArgumentLength;
- PVOID Argument;
+ PVOID Argument = NULL;
LRESULT Result = 0;
NTSTATUS Status;
PVOID ResultPointer;
ULONG ResultLength;
PHOOKPROC_CALLBACK_ARGUMENTS Common;
- CBT_CREATEWNDW *CbtCreateWnd =NULL;
+ CBT_CREATEWNDW *CbtCreateWnd = NULL;
PCHAR Extra;
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL;
- UNICODE_STRING WindowName;
- UNICODE_STRING ClassName;
- PANSI_STRING asWindowName;
- PANSI_STRING asClassName;
PTHREADINFO pti;
+ PWND pWnd;
+ PMSG pMsg = NULL;
+ BOOL Hit = FALSE;
ASSERT(Proc);
@@ -348,44 +347,27 @@ co_IntCallHookProc(INT HookId,
return 0;
}
- ArgumentLength = sizeof(HOOKPROC_CALLBACK_ARGUMENTS) - sizeof(WCHAR)
- + ModuleName->Length;
+ ArgumentLength = sizeof(HOOKPROC_CALLBACK_ARGUMENTS);
+
switch(HookId)
{
case WH_CBT:
+ DPRINT("WH_CBT: Code %d\n", Code);
switch(Code)
{
case HCBT_CREATEWND:
+ pWnd = UserGetWindowObject((HWND) wParam);
+ if (!pWnd)
+ {
+ DPRINT1("WH_CBT HCBT_CREATEWND wParam bad hWnd!\n");
+ goto Fault_Exit;
+ }
+ DPRINT("HCBT_CREATEWND AnsiCreator %s, AnsiHook %s\n", pWnd->state & WNDS_ANSICREATOR ? "True" : "False", Ansi ? "True" : "False");
+ // Due to KsStudio.exe, just pass the callers original pointers
+ // except class which point to kernel space if not an atom.
+ // Found by, Olaf Siejka
CbtCreateWnd = (CBT_CREATEWNDW *) lParam;
ArgumentLength += sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS);
-
- asWindowName = (PANSI_STRING)&WindowName;
- asClassName = (PANSI_STRING)&ClassName;
-
- if (Ansi)
- {
- RtlInitAnsiString(asWindowName, (PCSZ)CbtCreateWnd->lpcs->lpszName);
- ArgumentLength += WindowName.Length + sizeof(CHAR);
- }
- else
- {
- RtlInitUnicodeString(&WindowName, CbtCreateWnd->lpcs->lpszName);
- ArgumentLength += WindowName.Length + sizeof(WCHAR);
- }
-
- if (! IS_ATOM(CbtCreateWnd->lpcs->lpszClass))
- {
- if (Ansi)
- {
- RtlInitAnsiString(asClassName, (PCSZ)CbtCreateWnd->lpcs->lpszClass);
- ArgumentLength += ClassName.Length + sizeof(CHAR);
- }
- else
- {
- RtlInitUnicodeString(&ClassName, CbtCreateWnd->lpcs->lpszClass);
- ArgumentLength += ClassName.Length + sizeof(WCHAR);
- }
- }
break;
case HCBT_MOVESIZE:
@@ -408,7 +390,7 @@ co_IntCallHookProc(INT HookId,
break;
default:
DPRINT1("Trying to call unsupported CBT hook %d\n", Code);
- return 0;
+ goto Fault_Exit;
}
break;
case WH_KEYBOARD_LL:
@@ -437,14 +419,14 @@ co_IntCallHookProc(INT HookId,
break;
default:
DPRINT1("Trying to call unsupported window hook %d\n", HookId);
- return 0;
+ goto Fault_Exit;
}
Argument = IntCbAllocateMemory(ArgumentLength);
if (NULL == Argument)
{
DPRINT1("HookProc callback failed: out of memory\n");
- return 0;
+ goto Fault_Exit;
}
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Argument;
Common->HookId = HookId;
@@ -453,48 +435,20 @@ co_IntCallHookProc(INT HookId,
Common->lParam = lParam;
Common->Proc = Proc;
Common->Ansi = Ansi;
- Common->ModuleNameLength = ModuleName->Length;
- memcpy(Common->ModuleName, ModuleName->Buffer, ModuleName->Length);
- Extra = (PCHAR) Common->ModuleName + Common->ModuleNameLength;
+ Extra = (PCHAR) Common + sizeof(HOOKPROC_CALLBACK_ARGUMENTS);
switch(HookId)
{
case WH_CBT:
switch(Code)
- {
+ { // Need to remember this is not the first time through! Call Next Hook?
case HCBT_CREATEWND:
- Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS) Extra;
RtlCopyMemory( &CbtCreatewndExtra->Cs, CbtCreateWnd->lpcs, sizeof(CREATESTRUCTW) );
CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter;
- Extra = (PCHAR) (CbtCreatewndExtra + 1);
- RtlCopyMemory(Extra, WindowName.Buffer, WindowName.Length);
- CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra);
- CbtCreatewndExtra->Cs.lpszClass = ClassName.Buffer;
- Extra += WindowName.Length;
- if (Ansi)
- {
- *((CHAR *) Extra) = '\0';
- Extra += sizeof(CHAR);
- }
- else
- {
- *((WCHAR *) Extra) = L'\0';
- Extra += sizeof(WCHAR);
- }
-
- if (! IS_ATOM(ClassName.Buffer))
- {
- RtlCopyMemory(Extra, ClassName.Buffer, ClassName.Length);
- CbtCreatewndExtra->Cs.lpszClass =
- (LPCWSTR)(ULONG_PTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1);
- Extra += ClassName.Length;
-
- if (Ansi)
- *((CHAR *) Extra) = '\0';
- else
- *((WCHAR *) Extra) = L'\0';
- }
+ CbtCreatewndExtra->Cs.lpszClass = CbtCreateWnd->lpcs->lpszClass;
+ CbtCreatewndExtra->Cs.lpszName = CbtCreateWnd->lpcs->lpszName;
+ Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
break;
case HCBT_CLICKSKIPPED:
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MOUSEHOOKSTRUCT));
@@ -533,9 +487,9 @@ co_IntCallHookProc(INT HookId,
case WH_MSGFILTER:
case WH_SYSMSGFILTER:
case WH_GETMESSAGE:
- RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSG));
+ pMsg = (PMSG)lParam;
+ RtlCopyMemory(Extra, (PVOID) pMsg, sizeof(MSG));
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
-// DPRINT1("KHOOK Memory: %x\n",Common);
break;
case WH_FOREGROUNDIDLE:
case WH_KEYBOARD:
@@ -565,37 +519,48 @@ co_IntCallHookProc(INT HookId,
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Result = 0;
+ Hit = TRUE;
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
- return 0;
+ DPRINT1("Failure to make Callback! Status 0x%x",Status);
+ goto Fault_Exit;
}
-
- if (HookId == WH_CBT && Code == HCBT_CREATEWND)
+ /* Support write backs... SEH is in UserCallNextHookEx. */
+ switch (HookId)
{
- if (CbtCreatewndExtra)
- {
- _SEH2_TRY
- { /*
- The parameters could have been changed, include the coordinates
- and dimensions of the window. We copy it back.
- */
- CbtCreateWnd->hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
- CbtCreateWnd->lpcs->x = CbtCreatewndExtra->Cs.x;
- CbtCreateWnd->lpcs->y = CbtCreatewndExtra->Cs.y;
- CbtCreateWnd->lpcs->cx = CbtCreatewndExtra->Cs.cx;
- CbtCreateWnd->lpcs->cy = CbtCreatewndExtra->Cs.cy;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ case WH_CBT:
+ if (Code == HCBT_CREATEWND)
{
- Result = 0;
+ if (CbtCreatewndExtra)
+ {/*
+ The parameters could have been changed, include the coordinates
+ and dimensions of the window. We copy it back.
+ */
+ CbtCreateWnd->hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
+ CbtCreateWnd->lpcs->x = CbtCreatewndExtra->Cs.x;
+ CbtCreateWnd->lpcs->y = CbtCreatewndExtra->Cs.y;
+ CbtCreateWnd->lpcs->cx = CbtCreatewndExtra->Cs.cx;
+ CbtCreateWnd->lpcs->cy = CbtCreatewndExtra->Cs.cy;
+ }
}
- _SEH2_END;
- }
+ break;
+ // "The GetMsgProc hook procedure can examine or modify the message."
+ case WH_GETMESSAGE:
+ if (pMsg)
+ {
+ RtlCopyMemory((PVOID) pMsg, Extra, sizeof(MSG));
+ }
+ break;
}
+Fault_Exit:
+ if (Hit)
+ {
+ DPRINT1("Exception CallHookProc HookId %d Code %d\n",HookId,Code);
+ }
if (Argument) IntCbFreeMemory(Argument);
return Result;
diff --git a/subsystems/win32/win32k/ntuser/caret.c b/subsystems/win32/win32k/ntuser/caret.c
index 3ebae7ae11b..76d58a7120b 100644
--- a/subsystems/win32/win32k/ntuser/caret.c
+++ b/subsystems/win32/win32k/ntuser/caret.c
@@ -30,10 +30,13 @@ static
BOOL FASTCALL
co_IntHideCaret(PTHRDCARETINFO CaretInfo)
{
+ PWND pWnd;
if(CaretInfo->hWnd && CaretInfo->Visible && CaretInfo->Showing)
{
+ pWnd = UserGetWindowObject(CaretInfo->hWnd);
co_IntSendMessage(CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
CaretInfo->Showing = 0;
+ IntNotifyWinEvent(EVENT_OBJECT_HIDE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
return TRUE;
}
return FALSE;
@@ -43,17 +46,20 @@ BOOL FASTCALL
co_IntDestroyCaret(PTHREADINFO Win32Thread)
{
PUSER_MESSAGE_QUEUE ThreadQueue;
+ PWND pWnd;
ThreadQueue = (PUSER_MESSAGE_QUEUE)Win32Thread->MessageQueue;
if(!ThreadQueue || !ThreadQueue->CaretInfo)
return FALSE;
+ pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd);
co_IntHideCaret(ThreadQueue->CaretInfo);
ThreadQueue->CaretInfo->Bitmap = (HBITMAP)0;
ThreadQueue->CaretInfo->hWnd = (HWND)0;
ThreadQueue->CaretInfo->Size.cx = ThreadQueue->CaretInfo->Size.cy = 0;
ThreadQueue->CaretInfo->Showing = 0;
ThreadQueue->CaretInfo->Visible = 0;
+ IntNotifyWinEvent(EVENT_OBJECT_DESTROY, pWnd, OBJID_CARET, CHILDID_SELF, 0);
return TRUE;
}
@@ -176,6 +182,7 @@ BOOL FASTCALL
co_IntSetCaretPos(int X, int Y)
{
PTHREADINFO pti;
+ PWND pWnd;
PUSER_MESSAGE_QUEUE ThreadQueue;
pti = PsGetCurrentThreadWin32Thread();
@@ -183,6 +190,7 @@ co_IntSetCaretPos(int X, int Y)
if(ThreadQueue->CaretInfo->hWnd)
{
+ pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd);
if(ThreadQueue->CaretInfo->Pos.x != X || ThreadQueue->CaretInfo->Pos.y != Y)
{
co_IntHideCaret(ThreadQueue->CaretInfo);
@@ -191,6 +199,7 @@ co_IntSetCaretPos(int X, int Y)
ThreadQueue->CaretInfo->Pos.y = Y;
co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM);
+ IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
}
return TRUE;
}
@@ -277,6 +286,7 @@ BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL)
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
{
PTHREADINFO pti;
+ PWND pWnd;
PUSER_MESSAGE_QUEUE ThreadQueue;
if (Window) ASSERT_REFS_CO(Window);
@@ -301,11 +311,12 @@ BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
ThreadQueue->CaretInfo->Visible = 1;
if(!ThreadQueue->CaretInfo->Showing)
{
+ pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd);
co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
+ IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
}
IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM);
}
-
return TRUE;
}
@@ -370,7 +381,7 @@ NtUserCreateCaret(
}
ThreadQueue->CaretInfo->Visible = 0;
ThreadQueue->CaretInfo->Showing = 0;
-
+ IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);
RETURN(TRUE);
CLEANUP:
diff --git a/subsystems/win32/win32k/ntuser/clipboard.c b/subsystems/win32/win32k/ntuser/clipboard.c
index 538cf25707e..eca0d4d9f8c 100644
--- a/subsystems/win32/win32k/ntuser/clipboard.c
+++ b/subsystems/win32/win32k/ntuser/clipboard.c
@@ -243,34 +243,62 @@ IntEmptyClipboardData(VOID)
/*==============================================================*/
HANDLE FASTCALL
-renderBITMAPfromDIB(LPBYTE hDIB)
+renderBITMAPfromDIB(LPBYTE pDIB)
{
HDC hdc;
HBITMAP hbitmap;
- unsigned int offset;
- BITMAPINFOHEADER *ih;
+ PBITMAPINFO pBmi, pConvertedBmi = NULL;
+ NTSTATUS Status ;
+ UINT offset = 0; /* Stupid compiler */
+
+ pBmi = (BITMAPINFO*)pDIB;
//hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE);
hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE);
- ih = (BITMAPINFOHEADER *)hDIB;
+ /* Probe it */
+ _SEH2_TRY
+ {
+ ProbeForRead(&pBmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(pBmi, pBmi->bmiHeader.biSize, 1);
+ ProbeForRead(pBmi, DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS), 1);
+ pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS);
+ if(!pConvertedBmi)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ offset = DIB_BitmapInfoSize((BITMAPINFO*)pBmi, DIB_RGB_COLORS);
+ ProbeForRead(pDIB + offset, pConvertedBmi->bmiHeader.biSizeImage, 1);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
- offset = sizeof(BITMAPINFOHEADER) + ((ih->biBitCount <= 8) ? (sizeof(RGBQUAD) * (1 << ih->biBitCount)) : 0);
+ if(!NT_SUCCESS(Status))
+ {
+ UserReleaseDC(ClipboardWindow, hdc, FALSE);
+ return NULL;
+ }
- hbitmap = NtGdiCreateDIBitmapInternal(hdc,
- ih->biWidth,
- ih->biHeight,
- CBM_INIT,
- (LPBYTE)ih+offset,
- (LPBITMAPINFO)ih,
- DIB_RGB_COLORS,
- ih->biBitCount,
- ih->biSizeImage,
- 0,
- 0);
+ hbitmap = GreCreateDIBitmapInternal(hdc,
+ pConvertedBmi->bmiHeader.biWidth,
+ pConvertedBmi->bmiHeader.biHeight,
+ CBM_INIT,
+ pDIB+offset,
+ pConvertedBmi,
+ DIB_RGB_COLORS,
+ 0,
+ 0);
//UserReleaseDC(NULL, hdc, FALSE);
UserReleaseDC(ClipboardWindow, hdc, FALSE);
+ DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi);
+
return hbitmap;
}
@@ -1170,33 +1198,4 @@ NtUserGetClipboardSequenceNumber(VOID)
return sn;
}
-
-/**************** VISTA FUNCTIONS******************/
-
-BOOL APIENTRY NtUserAddClipboardFormatListener(
- HWND hwnd
-)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-BOOL APIENTRY NtUserRemoveClipboardFormatListener(
- HWND hwnd
-)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-BOOL APIENTRY NtUserGetUpdatedClipboardFormats(
- PUINT lpuiFormats,
- UINT cFormats,
- PUINT pcFormatsOut
-)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
/* EOF */
diff --git a/subsystems/win32/win32k/ntuser/cursoricon.c b/subsystems/win32/win32k/ntuser/cursoricon.c
index 427632e3ba7..ce738a7093b 100644
--- a/subsystems/win32/win32k/ntuser/cursoricon.c
+++ b/subsystems/win32/win32k/ntuser/cursoricon.c
@@ -109,7 +109,7 @@ UserSetCursor(
PCURICON_OBJECT OldCursor;
HCURSOR hOldCursor = (HCURSOR)0;
HDC hdcScreen;
-
+
CurInfo = IntGetSysCursorInfo();
OldCursor = CurInfo->CurrentCursorObject;
@@ -217,7 +217,7 @@ BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg)
Msg.wParam = CurInfo->ButtonsDown;
Msg.lParam = MAKELPARAM(x, y);
Msg.pt = pt;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
/* Store the new cursor position */
@@ -483,6 +483,7 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
}
+
/*
* @implemented
*/
@@ -617,23 +618,6 @@ cleanup:
}
-/*
- * @unimplemented
- */
-DWORD
-APIENTRY
-NtUserGetCursorFrameInfo(
- DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
/*
* @implemented
*/
@@ -692,6 +676,35 @@ CLEANUP:
END_CLEANUP;
}
+BOOL
+APIENTRY
+UserClipCursor(
+ RECTL *prcl)
+{
+ /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
+ PSYSTEM_CURSORINFO CurInfo;
+ PWND DesktopWindow = NULL;
+
+ CurInfo = IntGetSysCursorInfo();
+
+ DesktopWindow = UserGetDesktopWindow();
+
+ if (prcl != NULL &&
+ (prcl->right > prcl->left) &&
+ (prcl->bottom > prcl->top) &&
+ DesktopWindow != NULL)
+ {
+ CurInfo->bClipped = TRUE;
+ RECTL_bIntersectRect(&CurInfo->rcClip, prcl, &DesktopWindow->rcWindow);
+ UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
+ }
+ else
+ {
+ CurInfo->bClipped = FALSE;
+ }
+
+ return TRUE;
+}
/*
* @implemented
@@ -699,45 +712,37 @@ CLEANUP:
BOOL
APIENTRY
NtUserClipCursor(
- RECTL *UnsafeRect)
+ RECTL *prcl)
{
- /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
- PSYSTEM_CURSORINFO CurInfo;
- RECTL Rect;
- PWND DesktopWindow = NULL;
- DECLARE_RETURN(BOOL);
+ RECTL rclLocal;
+ BOOL bResult;
- DPRINT("Enter NtUserClipCursor\n");
- UserEnterExclusive();
-
- if (NULL != UnsafeRect && ! NT_SUCCESS(MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT))))
+ if (prcl)
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN(FALSE);
+ _SEH2_TRY
+ {
+ /* Probe and copy rect */
+ ProbeForRead(prcl, sizeof(RECTL), 1);
+ rclLocal = *prcl;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ _SEH2_YIELD(return FALSE;)
+ }
+ _SEH2_END
+
+ prcl = &rclLocal;
}
+
+ UserEnterExclusive();
- CurInfo = IntGetSysCursorInfo();
+ /* Call the internal function */
+ bResult = UserClipCursor(prcl);
- DesktopWindow = UserGetDesktopWindow();
-
- if ((Rect.right > Rect.left) && (Rect.bottom > Rect.top)
- && DesktopWindow && UnsafeRect != NULL)
- {
-
- CurInfo->bClipped = TRUE;
- RECTL_bIntersectRect(&CurInfo->rcClip, &Rect, &DesktopWindow->rcWindow);
- UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
-
- RETURN(TRUE);
- }
-
- CurInfo->bClipped = FALSE;
- RETURN(TRUE);
-
-CLEANUP:
- DPRINT("Leave NtUserClipCursor, ret=%i\n",_ret_);
UserLeave();
- END_CLEANUP;
+
+ return bResult;
}
@@ -937,12 +942,12 @@ NtUserSetCursorContents(
/* Delete old bitmaps */
if ((CurIcon->IconInfo.hbmColor)
- && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
+ && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
{
GreDeleteObject(CurIcon->IconInfo.hbmColor);
}
if ((CurIcon->IconInfo.hbmMask)
- && (CurIcon->IconInfo.hbmMask != IconInfo.hbmMask))
+ && CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)
{
GreDeleteObject(CurIcon->IconInfo.hbmMask);
}
@@ -968,8 +973,8 @@ NtUserSetCursorContents(
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy / 2;
SURFACE_UnlockSurface(psurfBmp);
- GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
}
+ GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
Ret = TRUE;
@@ -1154,18 +1159,6 @@ CLEANUP:
}
#endif
-/*
- * @unimplemented
- */
-BOOL
-APIENTRY
-NtUserSetSystemCursor(
- HCURSOR hcur,
- DWORD id)
-{
- return FALSE;
-}
-
/* Mostly inspired from wine code */
BOOL
UserDrawIconEx(
@@ -1287,23 +1280,12 @@ UserDrawIconEx(
if(bAlpha && (diFlags & DI_IMAGE))
{
BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
- DWORD Pixel;
- BYTE Red, Green, Blue, Alpha;
- DWORD Count = 0;
+ BYTE Alpha;
INT i, j;
PSURFACE psurf;
- PBYTE pBits ;
+ PBYTE ptr ;
HBITMAP hMemBmp = NULL;
- pBits = ExAllocatePoolWithTag(PagedPool,
- bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
- TAG_BITMAP);
- if (pBits == NULL)
- {
- Ret = FALSE;
- goto CleanupAlpha;
- }
-
hMemBmp = BITMAP_CopyBitmap(hbmColor);
if(!hMemBmp)
{
@@ -1317,35 +1299,22 @@ UserDrawIconEx(
DPRINT1("SURFACE_LockSurface failed!\n");
goto CleanupAlpha;
}
- /* get color bits */
- IntGetBitmapBits(psurf,
- bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
- pBits);
/* premultiply with the alpha channel value */
- for (i = 0; i < abs(bmpColor.bmHeight); i++)
+ for (i = 0; i < psurf->SurfObj.sizlBitmap.cy; i++)
{
- Count = i*bmpColor.bmWidthBytes;
- for (j = 0; j < bmpColor.bmWidth; j++)
+ ptr = (PBYTE)psurf->SurfObj.pvScan0 + i*psurf->SurfObj.lDelta;
+ for (j = 0; j < psurf->SurfObj.sizlBitmap.cx; j++)
{
- Pixel = *(DWORD *)(pBits + Count);
+ Alpha = ptr[3];
+ ptr[0] = (ptr[0] * Alpha) / 0xff;
+ ptr[1] = (ptr[1] * Alpha) / 0xff;
+ ptr[2] = (ptr[2] * Alpha) / 0xff;
- Alpha = ((BYTE)(Pixel >> 24) & 0xff);
-
- Red = (((BYTE)(Pixel >> 0)) * Alpha) / 0xff;
- Green = (((BYTE)(Pixel >> 8)) * Alpha) / 0xff;
- Blue = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff;
-
- *(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24));
-
- Count += sizeof(DWORD);
+ ptr += 4;
}
}
- /* set mem bits */
- IntSetBitmapBits(psurf,
- bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
- pBits);
SURFACE_UnlockSurface(psurf);
hTmpBmp = NtGdiSelectBitmap(hMemDC, hMemBmp);
@@ -1364,12 +1333,10 @@ UserDrawIconEx(
NULL);
NtGdiSelectBitmap(hMemDC, hTmpBmp);
CleanupAlpha:
- if(pBits) ExFreePoolWithTag(pBits, TAG_BITMAP);
if(hMemBmp) NtGdiDeleteObjectApp(hMemBmp);
if(Ret) goto done;
}
-
if (diFlags & DI_MASK)
{
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
diff --git a/subsystems/win32/win32k/ntuser/desktop.c b/subsystems/win32/win32k/ntuser/desktop.c
index 3a054f2f08d..c4af4525c8c 100644
--- a/subsystems/win32/win32k/ntuser/desktop.c
+++ b/subsystems/win32/win32k/ntuser/desktop.c
@@ -170,8 +170,9 @@ IntDesktopObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters)
/* PRIVATE FUNCTIONS **********************************************************/
+INIT_FUNCTION
NTSTATUS
-FASTCALL
+NTAPI
InitDesktopImpl(VOID)
{
/* Set Desktop Object Attributes */
@@ -616,8 +617,6 @@ UserRedrawDesktop()
{
PWND Window = NULL;
- UserEnterExclusive();
-
Window = UserGetDesktopWindow();
IntInvalidateWindows( Window,
@@ -626,7 +625,6 @@ UserRedrawDesktop()
RDW_ERASE |
RDW_INVALIDATE |
RDW_ALLCHILDREN);
- UserLeave();
}
@@ -882,13 +880,24 @@ NtUserCreateDesktop(
PUNICODE_STRING lpszDesktopName = NULL;
UNICODE_STRING ClassName, MenuName;
LARGE_STRING WindowName;
+ BOOL NoHooks = FALSE;
PWND pWnd = NULL;
CREATESTRUCTW Cs;
+ INT i;
+ PTHREADINFO ptiCurrent;
DECLARE_RETURN(HDESK);
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
UserEnterExclusive();
+ ptiCurrent = PsGetCurrentThreadWin32Thread();
+ if (ptiCurrent)
+ {
+ /* Turn off hooks when calling any CreateWindowEx from inside win32k. */
+ NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
+ ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
+ }
+
_SEH2_TRY
{
ProbeForRead( poa,
@@ -1026,6 +1035,11 @@ NtUserCreateDesktop(
/* Initialize some local (to win32k) desktop state. */
InitializeListHead(&DesktopObject->PtiList);
DesktopObject->ActiveMessageQueue = NULL;
+ /* Setup Global Hooks. */
+ for (i = 0; i < NB_HOOKS; i++)
+ {
+ InitializeListHead(&DesktopObject->pDeskInfo->aphkStart[i]);
+ }
ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING);
if (! NT_SUCCESS(Status))
@@ -1098,6 +1112,7 @@ NtUserCreateDesktop(
RETURN( Desktop);
CLEANUP:
+ if (!NoHooks && ptiCurrent) ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS;
DPRINT("Leave NtUserCreateDesktop, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
@@ -1670,20 +1685,6 @@ CLEANUP:
END_CLEANUP;
}
-/*
- * NtUserResolveDesktopForWOW
- *
- * Status
- * @unimplemented
- */
-
-DWORD APIENTRY
-NtUserResolveDesktopForWOW(DWORD Unknown0)
-{
- UNIMPLEMENTED
- return 0;
-}
-
/*
* NtUserGetThreadDesktop
*
@@ -1820,7 +1821,6 @@ IntUnmapDesktopView(IN PDESKTOP DesktopObject)
static NTSTATUS
IntMapDesktopView(IN PDESKTOP DesktopObject)
{
- PTHREADINFO ti;
PPROCESSINFO CurrentWin32Process;
PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
PVOID UserBase = NULL;
@@ -1883,19 +1883,6 @@ IntMapDesktopView(IN PDESKTOP DesktopObject)
ObReferenceObject(DesktopObject);
- /* create a W32THREADINFO structure if not already done, or update it */
- ti = GetW32ThreadInfo();
- GetWin32ClientInfo()->ulClientDelta = DesktopHeapGetUserDelta();
- if (ti != NULL)
- {
- if (GetWin32ClientInfo()->pDeskInfo == NULL)
- {
- GetWin32ClientInfo()->pDeskInfo =
- (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo -
- GetWin32ClientInfo()->ulClientDelta);
- }
- }
-
return STATUS_SUCCESS;
}
@@ -1907,6 +1894,7 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
PTHREADINFO W32Thread;
NTSTATUS Status;
BOOL MapHeap;
+ CLIENTTHREADINFO ctiSave;
DPRINT("IntSetThreadDesktop() DO=%p, FOF=%d\n", DesktopObject, FreeOnFailure);
MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess);
@@ -1933,9 +1921,27 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
SetLastNtError(Status);
return FALSE;
}
+ W32Thread->pDeskInfo = DesktopObject->pDeskInfo;
+ }
+
+ RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO));
+
+ if (W32Thread->pcti && OldDesktop)
+ {
+ RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO));
+ DPRINT("Free ClientThreadInfo\n");
+ DesktopHeapFree(OldDesktop, W32Thread->pcti);
+ W32Thread->pcti = NULL;
+ }
+
+ if (!W32Thread->pcti && DesktopObject)
+ {
+ DPRINT("Allocate ClientThreadInfo\n");
+ W32Thread->pcti = DesktopHeapAlloc( DesktopObject,
+ sizeof(CLIENTTHREADINFO));
+ RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO));
}
- /* Hack for system threads */
if (NtCurrentTeb())
{
PCLIENTINFO pci = GetWin32ClientInfo();
@@ -1943,6 +1949,7 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
if (DesktopObject)
{
pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta);
+ if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta);
}
}
diff --git a/subsystems/win32/win32k/ntuser/display.c b/subsystems/win32/win32k/ntuser/display.c
index b5986a58df2..f5770a7ce2c 100644
--- a/subsystems/win32/win32k/ntuser/display.c
+++ b/subsystems/win32/win32k/ntuser/display.c
@@ -1,199 +1,896 @@
/*
- * PROJECT: ReactOS Kernel
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: subsystems/win32/win32k/ntuser/display.c
- * PURPOSE: display settings
- * COPYRIGHT: Copyright 2007 ReactOS
- *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Video initialization and display settings
+ * FILE: subsystems/win32/win32k/ntuser/display.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
-/* INCLUDES ******************************************************************/
-
#include
+#include
+
#define NDEBUG
#include
-#define SIZEOF_DEVMODEW_300 188
-#define SIZEOF_DEVMODEW_400 212
-#define SIZEOF_DEVMODEW_500 220
+BOOL InitSysParams();
-/* PUBLIC FUNCTIONS ***********************************************************/
+BOOL gbBaseVideo = 0;
-NTSTATUS
-APIENTRY
-NtUserEnumDisplaySettings(
- PUNICODE_STRING pusDeviceName,
- DWORD iModeNum,
- LPDEVMODEW lpDevMode, /* FIXME is this correct? */
- DWORD dwFlags )
+static const PWCHAR KEY_ROOT = L"";
+static const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
+
+VOID
+RegWriteDisplaySettings(HKEY hkey, PDEVMODEW pdm)
{
+ RegWriteDWORD(hkey, L"DefaultSettings.BitsPerPel", pdm->dmBitsPerPel);
+ RegWriteDWORD(hkey, L"DefaultSettings.XResolution", pdm->dmPelsWidth);
+ RegWriteDWORD(hkey, L"DefaultSettings.YResolution", pdm->dmPelsHeight);
+ RegWriteDWORD(hkey, L"DefaultSettings.Flags", pdm->dmDisplayFlags);
+ RegWriteDWORD(hkey, L"DefaultSettings.VRefresh", pdm->dmDisplayFrequency);
+ RegWriteDWORD(hkey, L"DefaultSettings.XPanning", pdm->dmPanningWidth);
+ RegWriteDWORD(hkey, L"DefaultSettings.YPanning", pdm->dmPanningHeight);
+ RegWriteDWORD(hkey, L"DefaultSettings.Orientation", pdm->dmDisplayOrientation);
+ RegWriteDWORD(hkey, L"DefaultSettings.FixedOutput", pdm->dmDisplayFixedOutput);
+ RegWriteDWORD(hkey, L"Attach.RelativeX", pdm->dmPosition.x);
+ RegWriteDWORD(hkey, L"Attach.RelativeY", pdm->dmPosition.y);
+// RegWriteDWORD(hkey, L"Attach.ToDesktop, pdm->dmBitsPerPel", pdm->);
+}
+
+VOID
+RegReadDisplaySettings(HKEY hkey, PDEVMODEW pdm)
+{
+ DWORD dwValue;
+
+ /* Zero out the structure */
+ RtlZeroMemory(pdm, sizeof(DEVMODEW));
+
+/* Helper macro */
+#define READ(field, str, flag) \
+ if (RegReadDWORD(hkey, L##str, &dwValue)) \
+ { \
+ pdm->field = dwValue; \
+ pdm->dmFields |= flag; \
+ }
+
+ /* Read all present settings */
+ READ(dmBitsPerPel, "DefaultSettings.BitsPerPel", DM_BITSPERPEL);
+ READ(dmPelsWidth, "DefaultSettings.XResolution", DM_PELSWIDTH);
+ READ(dmPelsHeight, "DefaultSettings.YResolution", DM_PELSHEIGHT);
+ READ(dmDisplayFlags, "DefaultSettings.Flags", DM_DISPLAYFLAGS);
+ READ(dmDisplayFrequency, "DefaultSettings.VRefresh", DM_DISPLAYFREQUENCY);
+ READ(dmPanningWidth, "DefaultSettings.XPanning", DM_PANNINGWIDTH);
+ READ(dmPanningHeight, "DefaultSettings.YPanning", DM_PANNINGHEIGHT);
+ READ(dmDisplayOrientation, "DefaultSettings.Orientation", DM_DISPLAYORIENTATION);
+ READ(dmDisplayFixedOutput, "DefaultSettings.FixedOutput", DM_DISPLAYFIXEDOUTPUT);
+ READ(dmPosition.x, "Attach.RelativeX", DM_POSITION);
+ READ(dmPosition.y, "Attach.RelativeY", DM_POSITION);
+}
+
+PGRAPHICS_DEVICE
+NTAPI
+InitDisplayDriver(
+ IN PWSTR pwszDeviceName,
+ IN PWSTR pwszRegKey)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ UNICODE_STRING ustrDeviceName, ustrDisplayDrivers, ustrDescription;
NTSTATUS Status;
- LPDEVMODEW pSafeDevMode;
- PUNICODE_STRING pusSafeDeviceName = NULL;
- UNICODE_STRING usSafeDeviceName;
- USHORT Size = 0, ExtraSize = 0;
+ WCHAR awcBuffer[128];
+ ULONG cbSize;
+ HKEY hkey;
+ DEVMODEW dmDefault;
- /* Copy the devmode */
- _SEH2_TRY
- {
- ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
- Size = lpDevMode->dmSize;
- ExtraSize = lpDevMode->dmDriverExtra;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- DPRINT("FIXME ? : Out of range of DEVMODEW size \n");
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
- }
- _SEH2_END;
-
- if (Size != sizeof(DEVMODEW))
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- pSafeDevMode = ExAllocatePoolWithTag(PagedPool, Size + ExtraSize, GDITAG_DEVMODE);
- if (pSafeDevMode == NULL)
- {
- return STATUS_NO_MEMORY;
- }
- pSafeDevMode->dmSize = Size;
- pSafeDevMode->dmDriverExtra = ExtraSize;
-
- /* Copy the device name */
- if (pusDeviceName != NULL)
- {
- Status = IntSafeCopyUnicodeString(&usSafeDeviceName, pusDeviceName);
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(pSafeDevMode);
- return Status;
- }
- pusSafeDeviceName = &usSafeDeviceName;
- }
-
- /* Call internal function */
- Status = IntEnumDisplaySettings(pusSafeDeviceName, iModeNum, pSafeDevMode, dwFlags);
-
- if (pusSafeDeviceName != NULL)
- RtlFreeUnicodeString(pusSafeDeviceName);
+ DPRINT1("InitDisplayDriver(%S, %S);\n",
+ pwszDeviceName, pwszRegKey);
+ /* Open the driver's registry key */
+ Status = RegOpenKey(pwszRegKey, &hkey);
if (!NT_SUCCESS(Status))
{
- ExFreePool(pSafeDevMode);
+ DPRINT1("Failed to open registry key: %ls\n", pwszRegKey);
+ return NULL;
+ }
+
+ /* Query the diplay drivers */
+ cbSize = sizeof(awcBuffer) - 10;
+ Status = RegQueryValue(hkey,
+ L"InstalledDisplayDrivers",
+ REG_MULTI_SZ,
+ awcBuffer,
+ &cbSize);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Didn't find 'InstalledDisplayDrivers', status = 0x%lx\n", Status);
+ ZwClose(hkey);
+ return NULL;
+ }
+
+ /* Initialize the UNICODE_STRING */
+ ustrDisplayDrivers.Buffer = awcBuffer;
+ ustrDisplayDrivers.MaximumLength = cbSize;
+ ustrDisplayDrivers.Length = cbSize;
+
+ /* Set Buffer for description and size of remaining buffer */
+ ustrDescription.Buffer = awcBuffer + (cbSize / sizeof(WCHAR));
+ cbSize = sizeof(awcBuffer) - cbSize;
+
+ /* Query the device string */
+ Status = RegQueryValue(hkey,
+ L"Device Description",
+ REG_SZ,
+ ustrDescription.Buffer,
+ &cbSize);
+ if (NT_SUCCESS(Status))
+ {
+ ustrDescription.MaximumLength = cbSize;
+ ustrDescription.Length = cbSize;
+ }
+ else
+ {
+ RtlInitUnicodeString(&ustrDescription, L"");
+ }
+
+ /* Query the default settings */
+ RegReadDisplaySettings(hkey, &dmDefault);
+
+ /* Close the registry key */
+ ZwClose(hkey);
+
+ /* Register the device with GDI */
+ RtlInitUnicodeString(&ustrDeviceName, pwszDeviceName);
+ pGraphicsDevice = EngpRegisterGraphicsDevice(&ustrDeviceName,
+ &ustrDisplayDrivers,
+ &ustrDescription,
+ &dmDefault);
+
+ return pGraphicsDevice;
+}
+
+NTSTATUS
+NTAPI
+InitVideo()
+{
+ ULONG iDevNum, iVGACompatible = -1, ulMaxObjectNumber = 0;
+ WCHAR awcDeviceName[20];
+ WCHAR awcBuffer[256];
+ NTSTATUS Status;
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ ULONG cbValue;
+ HKEY hkey;
+
+ DPRINT("----------------------------- InitVideo() -------------------------------\n");
+
+ /* Open the key for the boot command line */
+ Status = RegOpenKey(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control", &hkey);
+ if (NT_SUCCESS(Status))
+ {
+ cbValue = 256;
+ Status = RegQueryValue(hkey, L"SystemStartOptions", REG_SZ, awcBuffer, &cbValue);
+ if (NT_SUCCESS(Status))
+ {
+ /* Check if VGA mode is requested. */
+ if (wcsstr(awcBuffer, L"/BASEVIDEO") != 0)
+ {
+ DPRINT1("VGA mode requested.\n");
+ gbBaseVideo = TRUE;
+ }
+ }
+
+ ZwClose(hkey);
+ }
+
+ /* Open the key for the adapters */
+ Status = RegOpenKey(KEY_VIDEO, &hkey);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not open device registry key!\n");
return Status;
}
- /* Copy some information back */
- _SEH2_TRY
+ /* Read the name of the VGA adapter */
+ cbValue = 20;
+ Status = RegQueryValue(hkey, L"VgaCompatible", REG_SZ, awcDeviceName, &cbValue);
+ if (NT_SUCCESS(Status))
{
- ProbeForWrite(lpDevMode,Size + ExtraSize, 1);
- lpDevMode->dmPelsWidth = pSafeDevMode->dmPelsWidth;
- lpDevMode->dmPelsHeight = pSafeDevMode->dmPelsHeight;
- lpDevMode->dmBitsPerPel = pSafeDevMode->dmBitsPerPel;
- lpDevMode->dmDisplayFrequency = pSafeDevMode->dmDisplayFrequency;
- lpDevMode->dmDisplayFlags = pSafeDevMode->dmDisplayFlags;
+ iVGACompatible = _wtoi(&awcDeviceName[13]);
+ DPRINT1("VGA adapter = %ld\n", iVGACompatible);
+ }
- /* output private/extra driver data */
- if (ExtraSize > 0)
+ /* Get the maximum mumber of adapters */
+ if (!RegReadDWORD(hkey, L"MaxObjectNumber", &ulMaxObjectNumber))
+ {
+ DPRINT1("Could not read MaxObjectNumber, defaulting to 0.\n");
+ }
+
+ DPRINT("Found %ld devices\n", ulMaxObjectNumber);
+
+ /* Loop through all adapters */
+ for (iDevNum = 0; iDevNum <= ulMaxObjectNumber; iDevNum++)
+ {
+ /* Create the adapter's key name */
+ swprintf(awcDeviceName, L"\\Device\\Video%lu", iDevNum);
+
+ /* Read the reg key name */
+ cbValue = sizeof(awcBuffer);
+ Status = RegQueryValue(hkey, awcDeviceName, REG_SZ, awcBuffer, &cbValue);
+ if (!NT_SUCCESS(Status))
{
- memcpy((PCHAR)lpDevMode + Size, (PCHAR)pSafeDevMode + Size, ExtraSize);
+ DPRINT1("failed to query the registry path:0x%lx\n", Status);
+ continue;
+ }
+
+ /* Initialize the driver for this device */
+ pGraphicsDevice = InitDisplayDriver(awcDeviceName, awcBuffer);
+ if (!pGraphicsDevice) continue;
+
+ /* Check if this is the VGA adapter */
+ if (iDevNum == iVGACompatible)
+ {
+ /* Set the VGA device as primary */
+ gpVgaGraphicsDevice = pGraphicsDevice;
+ DPRINT1("gpVgaGraphicsDevice = %p\n", gpVgaGraphicsDevice);
+ }
+
+ /* Set the first one as primary device */
+ if (!gpPrimaryGraphicsDevice)
+ gpPrimaryGraphicsDevice = pGraphicsDevice;
+ }
+
+ /* Close the device map registry key */
+ ZwClose(hkey);
+
+ /* Check if we had any success */
+ if (!gpPrimaryGraphicsDevice)
+ {
+ DPRINT1("No usable display driver was found.\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (gbBaseVideo)
+ {
+ if (gpVgaGraphicsDevice)
+ {
+ /* Set the VgaAdapter as primary */
+ gpPrimaryGraphicsDevice = gpVgaGraphicsDevice;
+ // FIXME: DEVMODE
+ }
+ else
+ {
+ DPRINT1("Could not find VGA compatible driver. Trying normal.\n");
}
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
- ExFreePool(pSafeDevMode);
- return Status;
+ InitSysParams();
+
+ return 1;
}
-
-LONG
-APIENTRY
-NtUserChangeDisplaySettings(
- PUNICODE_STRING lpszDeviceName,
- LPDEVMODEW lpDevMode,
- HWND hwnd,
- DWORD dwflags,
- LPVOID lParam)
+NTSTATUS
+NTAPI
+UserEnumDisplayDevices(
+ PUNICODE_STRING pustrDevice,
+ DWORD iDevNum,
+ PDISPLAY_DEVICEW pdispdev,
+ DWORD dwFlags)
{
- NTSTATUS Status = STATUS_SUCCESS;
- LPDEVMODEW lpSafeDevMode = NULL;
- DEVMODEW DevMode;
- PUNICODE_STRING pSafeDeviceName = NULL;
- UNICODE_STRING SafeDeviceName;
- LONG Ret;
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ ULONG cbSize;
+ HKEY hkey;
+ NTSTATUS Status;
- /* Check arguments */
-#ifdef CDS_VIDEOPARAMETERS
- if (dwflags != CDS_VIDEOPARAMETERS && lParam != NULL)
-#else
- if (lParam != NULL)
-#endif
+ /* Ask gdi for the GRAPHICS_DEVICE */
+ pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, iDevNum, 0);
+ if (!pGraphicsDevice)
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return DISP_CHANGE_BADPARAM;
+ /* No device found */
+ DPRINT1("No GRAPHICS_DEVICE found\n");
+ return STATUS_UNSUCCESSFUL;
}
- if (hwnd != NULL)
+ /* Open thhe device map registry key */
+ Status = RegOpenKey(KEY_VIDEO, &hkey);
+ if (!NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return DISP_CHANGE_BADPARAM;
+ /* No device found */
+ DPRINT1("Could not open reg key\n");
+ return STATUS_UNSUCCESSFUL;
}
- /* Copy devmode */
- if (lpDevMode != NULL)
+ /* Query the registry path */
+ cbSize = sizeof(pdispdev->DeviceKey);
+ RegQueryValue(hkey,
+ pGraphicsDevice->szNtDeviceName,
+ REG_SZ,
+ pdispdev->DeviceKey,
+ &cbSize);
+
+ /* Close registry key */
+ ZwClose(hkey);
+
+ /* Copy device name, device string and StateFlags */
+ wcsncpy(pdispdev->DeviceName, pGraphicsDevice->szWinDeviceName, 32);
+ wcsncpy(pdispdev->DeviceString, pGraphicsDevice->pwszDescription, 128);
+ pdispdev->StateFlags = pGraphicsDevice->StateFlags;
+
+ // FIXME: fill in DEVICE ID
+
+ return STATUS_SUCCESS;
+}
+
+//NTSTATUS
+BOOL
+NTAPI
+NtUserEnumDisplayDevices(
+ PUNICODE_STRING pustrDevice,
+ DWORD iDevNum,
+ PDISPLAY_DEVICEW pDisplayDevice,
+ DWORD dwFlags)
+{
+ UNICODE_STRING ustrDevice;
+ WCHAR awcDevice[CCHDEVICENAME];
+ DISPLAY_DEVICEW dispdev;
+ NTSTATUS Status;
+
+ DPRINT("Enter NtUserEnumDisplayDevices(%wZ, %ld)\n",
+ pustrDevice, iDevNum);
+
+ // FIXME: HACK, desk.cpl passes broken crap
+ if (pustrDevice && iDevNum != 0)
+ return FALSE;
+
+ dispdev.cb = sizeof(DISPLAY_DEVICEW);
+
+ if (pustrDevice)
{
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
_SEH2_TRY
{
- ProbeForRead(lpDevMode, sizeof(DevMode.dmSize), 1);
- DevMode.dmSize = lpDevMode->dmSize;
- DevMode.dmSize = min(sizeof(DevMode), DevMode.dmSize);
- ProbeForRead(lpDevMode, DevMode.dmSize, 1);
- RtlCopyMemory(&DevMode, lpDevMode, DevMode.dmSize);
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+// _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ _SEH2_YIELD(return NT_SUCCESS(_SEH2_GetExceptionCode()));
+ }
+ _SEH2_END
+
+ if (ustrDevice.Length > 0)
+ pustrDevice = &ustrDevice;
+ else
+ pustrDevice = NULL;
+ }
+
+ /* Acquire global USER lock */
+ UserEnterExclusive();
+
+ /* Call the internal function */
+ Status = UserEnumDisplayDevices(pustrDevice, iDevNum, &dispdev, dwFlags);
+
+ /* Release lock */
+ UserLeave();
+
+ /* On success copy data to caller */
+ if (NT_SUCCESS(Status))
+ {
+ /* Enter SEH */
+ _SEH2_TRY
+ {
+ /* First probe the cb field */
+ ProbeForWrite(&pDisplayDevice->cb, sizeof(DWORD), 1);
+
+ /* Check the buffer size */
+ if (pDisplayDevice->cb)
+ {
+ /* Probe the output buffer */
+ pDisplayDevice->cb = min(pDisplayDevice->cb, sizeof(dispdev));
+ ProbeForWrite(pDisplayDevice, pDisplayDevice->cb, 1);
+
+ /* Copy as much as the given buffer allows */
+ RtlCopyMemory(pDisplayDevice, &dispdev, pDisplayDevice->cb);
+ }
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END
+ }
+ DPRINT1("Leave NtUserEnumDisplayDevices, Status = 0x%lx\n", Status);
+ /* Return the result */
+// return Status;
+ return NT_SUCCESS(Status); // FIXME
+}
+
+NTSTATUS
+NTAPI
+UserEnumCurrentDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ PDEVMODEW *ppdm)
+{
+ PPDEVOBJ ppdev;
+
+ /* Get the PDEV for the device */
+ ppdev = EngpGetPDEV(pustrDevice);
+ if (!ppdev)
+ {
+ /* No device found */
+ DPRINT1("No PDEV found!\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ *ppdm = ppdev->pdmwDev;
+ PDEVOBJ_vRelease(ppdev);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+UserEnumDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ DWORD iModeNum,
+ LPDEVMODEW *ppdm,
+ DWORD dwFlags)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PDEVMODEENTRY pdmentry;
+ ULONG i, iFoundMode;
+
+ DPRINT("Enter UserEnumDisplaySettings('%ls', %ld)\n",
+ pustrDevice ? pustrDevice->Buffer : NULL, iModeNum);
+
+ /* Ask gdi for the GRAPHICS_DEVICE */
+ pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, 0, 0);
+
+ if (!pGraphicsDevice)
+ {
+ /* No device found */
+ DPRINT1("No device found!\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (iModeNum >= pGraphicsDevice->cDevModes)
+ return STATUS_NO_MORE_ENTRIES;
+
+ iFoundMode = 0;
+ for (i = 0; i < pGraphicsDevice->cDevModes; i++)
+ {
+ pdmentry = &pGraphicsDevice->pDevModeList[i];
+
+ /* FIXME: consider EDS_RAWMODE */
+#if 0
+ if ((!(dwFlags & EDS_RAWMODE) && (pdmentry->dwFlags & 1)) ||!
+ (dwFlags & EDS_RAWMODE))
+#endif
+ {
+ /* Is this the one we want? */
+ if (iFoundMode == iModeNum)
+ {
+ *ppdm = pdmentry->pdm;
+ return STATUS_SUCCESS;
+ }
+
+ /* Increment number of found modes */
+ iFoundMode++;
+ }
+ }
+
+ /* Nothing was found */
+ return STATUS_INVALID_PARAMETER;
+}
+
+NTSTATUS
+NTAPI
+UserOpenDisplaySettingsKey(
+ OUT PHKEY phkey,
+ IN PUNICODE_STRING pustrDevice,
+ IN BOOL bGlobal)
+{
+ HKEY hkey;
+ DISPLAY_DEVICEW dispdev;
+ NTSTATUS Status;
+
+ /* Get device info */
+ Status = UserEnumDisplayDevices(pustrDevice, 0, &dispdev, 0);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ if (bGlobal)
+ {
+ // FIXME: need to fix the registry key somehow
+ }
+
+ /* Open the registry key */
+ Status = RegOpenKey(dispdev.DeviceKey, &hkey);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ *phkey = hkey;
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+UserEnumRegistryDisplaySettings(
+ IN PUNICODE_STRING pustrDevice,
+ OUT LPDEVMODEW pdm)
+{
+ HKEY hkey;
+ NTSTATUS Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, 0);
+ if(NT_SUCCESS(Status))
+ {
+ RegReadDisplaySettings(hkey, pdm);
+ ZwClose(hkey);
+ return STATUS_SUCCESS;
+ }
+ return Status ;
+}
+
+
+NTSTATUS
+APIENTRY
+NtUserEnumDisplaySettings(
+ IN PUNICODE_STRING pustrDevice,
+ IN DWORD iModeNum,
+ OUT LPDEVMODEW lpDevMode,
+ IN DWORD dwFlags)
+{
+ UNICODE_STRING ustrDevice;
+ WCHAR awcDevice[CCHDEVICENAME];
+ NTSTATUS Status;
+ ULONG cbSize, cbExtra;
+ DEVMODEW dmReg, *pdm;
+
+ DPRINT1("Enter NtUserEnumDisplaySettings(%ls, %ld)\n",
+ pustrDevice ? pustrDevice->Buffer : 0, iModeNum);
+
+ if (pustrDevice)
+ {
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
+ _SEH2_TRY
+ {
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END
+
+ pustrDevice = &ustrDevice;
+ }
+
+ /* Acquire global USER lock */
+ UserEnterExclusive();
+
+ if (iModeNum == ENUM_REGISTRY_SETTINGS)
+ {
+ /* Get the registry settings */
+ Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg);
+ pdm = &dmReg;
+ }
+ else if (iModeNum == ENUM_CURRENT_SETTINGS)
+ {
+ /* Get the current settings */
+ Status = UserEnumCurrentDisplaySettings(pustrDevice, &pdm);
+ }
+ else
+ {
+ /* Get specified settings */
+ Status = UserEnumDisplaySettings(pustrDevice, iModeNum, &pdm, dwFlags);
+ }
+
+ /* Release lock */
+ UserLeave();
+
+ /* Did we succeed? */
+ if (NT_SUCCESS(Status))
+ {
+ /* Copy some information back */
+ _SEH2_TRY
+ {
+ ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
+ cbSize = lpDevMode->dmSize;
+ cbExtra = lpDevMode->dmDriverExtra;
+
+ ProbeForWrite(lpDevMode, cbSize + cbExtra, 1);
+ /* Output what we got */
+ RtlCopyMemory(lpDevMode, pdm, min(cbSize, pdm->dmSize));
+
+ /* output private/extra driver data */
+ if (cbExtra > 0 && pdm->dmDriverExtra > 0)
+ {
+ RtlCopyMemory((PCHAR)lpDevMode + cbSize,
+ (PCHAR)pdm + pdm->dmSize,
+ min(cbExtra, pdm->dmDriverExtra));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+
+ return Status;
+}
+
+BOOL APIENTRY UserClipCursor(RECTL *prcl);
+VOID APIENTRY UserRedrawDesktop();
+HCURSOR FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange);
+
+LONG
+APIENTRY
+UserChangeDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ LPDEVMODEW pdm,
+ HWND hwnd,
+ DWORD flags,
+ LPVOID lParam)
+{
+ DEVMODEW dm;
+ LONG lResult = DISP_CHANGE_SUCCESSFUL;
+ HKEY hkey;
+ NTSTATUS Status;
+ PPDEVOBJ ppdev;
+ PDESKTOP pdesk;
+
+ /* If no DEVMODE is given, use registry settings */
+ if (!pdm)
+ {
+ /* Get the registry settings */
+ Status = UserEnumRegistryDisplaySettings(pustrDevice, &dm);
if (!NT_SUCCESS(Status))
{
- SetLastNtError(Status);
+ DPRINT1("Could not load registry settings\n");
return DISP_CHANGE_BADPARAM;
}
+ }
+ else if (pdm->dmSize < FIELD_OFFSET(DEVMODEW, dmFields))
+ return DISP_CHANGE_BADMODE; /* This is what winXP SP3 returns */
+ else
+ dm = *pdm;
- if (DevMode.dmDriverExtra > 0)
+ /* Check params */
+ if ((dm.dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT))
+ {
+ DPRINT1("devmode doesn't specify the resolution.\n");
+ return DISP_CHANGE_BADMODE;
+ }
+
+ /* Get the PDEV */
+ ppdev = EngpGetPDEV(pustrDevice);
+ if (!ppdev)
+ {
+ DPRINT1("failed to get PDEV\n");
+ return DISP_CHANGE_BADPARAM;
+ }
+
+ /* Fixup values */
+ if(dm.dmBitsPerPel == 0 || !(dm.dmFields & DM_BITSPERPEL))
+ {
+ dm.dmBitsPerPel = ppdev->pdmwDev->dmBitsPerPel;
+ dm.dmFields |= DM_BITSPERPEL;
+ }
+
+ if((dm.dmFields & DM_DISPLAYFREQUENCY) && (dm.dmDisplayFrequency == 0))
+ dm.dmDisplayFrequency = ppdev->pdmwDev->dmDisplayFrequency;
+
+ /* Look for the requested DEVMODE */
+ pdm = PDEVOBJ_pdmMatchDevMode(ppdev, &dm);
+ if (!pdm)
+ {
+ DPRINT1("Could not find a matching DEVMODE\n");
+ lResult = DISP_CHANGE_BADMODE;
+ goto leave;
+ }
+ else if (flags & CDS_TEST)
+ {
+ /* It's possible, go ahead! */
+ lResult = DISP_CHANGE_SUCCESSFUL;
+ goto leave;
+ }
+
+ /* Shall we update the registry? */
+ if (flags & CDS_UPDATEREGISTRY)
+ {
+ /* Open the local or global settings key */
+ Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, flags & CDS_GLOBAL);
+ if (NT_SUCCESS(Status))
{
- DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n");
- DevMode.dmDriverExtra = 0;
+ /* Store the settings */
+ RegWriteDisplaySettings(hkey, pdm);
+
+ /* Close the registry key */
+ ZwClose(hkey);
}
- lpSafeDevMode = &DevMode;
+ else
+ {
+ DPRINT1("Could not open registry key\n");
+ lResult = DISP_CHANGE_NOTUPDATED;
+ }
+ }
+
+ /* Check if DEVMODE matches the current mode */
+ if (pdm == ppdev->pdmwDev && !(flags & CDS_RESET))
+ {
+ DPRINT1("DEVMODE matches, nothing to do\n");
+ goto leave;
+ }
+
+ /* Shall we apply the settings? */
+ if (!(flags & CDS_NORESET))
+ {
+ ULONG ulResult;
+
+ /* Remove mouse pointer */
+ UserSetCursor(NULL, TRUE);
+
+ /* Do the mode switch */
+ ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm);
+
+ /* Restore mouse pointer, no hooks called */
+ UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
+
+ /* Check for failure */
+ if (!ulResult)
+ {
+ DPRINT1("failed to set mode\n");
+ lResult = (lResult == DISP_CHANGE_NOTUPDATED) ?
+ DISP_CHANGE_FAILED : DISP_CHANGE_RESTART;
+
+ goto leave;
+ }
+
+ /* Update the system metrics */
+ InitMetrics();
+
+ //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps);
+
+ /* Remove all cursor clipping */
+ UserClipCursor(NULL);
+
+ pdesk = IntGetActiveDesktop();
+ //IntHideDesktop(pdesk);
+
+ /* Send WM_DISPLAYCHANGE to all toplevel windows */
+ co_IntSendMessageTimeout(HWND_BROADCAST,
+ WM_DISPLAYCHANGE,
+ (WPARAM)ppdev->gdiinfo.cBitsPixel,
+ (LPARAM)(ppdev->gdiinfo.ulHorzRes + (ppdev->gdiinfo.ulVertRes << 16)),
+ SMTO_NORMAL,
+ 100,
+ &ulResult);
+
+ //co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes);
+
+ UserRedrawDesktop();
+ }
+
+leave:
+ /* Release the PDEV */
+ PDEVOBJ_vRelease(ppdev);
+
+ return lResult;
+}
+
+LONG
+APIENTRY
+NtUserChangeDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ LPDEVMODEW lpDevMode,
+ HWND hwnd,
+ DWORD dwflags,
+ LPVOID lParam)
+{
+ WCHAR awcDevice[CCHDEVICENAME];
+ UNICODE_STRING ustrDevice;
+ DEVMODEW dmLocal;
+ LONG lRet;
+
+ /* Check arguments */
+ if ((dwflags != CDS_VIDEOPARAMETERS && lParam != NULL) ||
+ (hwnd != NULL))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return DISP_CHANGE_BADPARAM;
+ }
+
+ /* Check flags */
+ if ((dwflags & (CDS_GLOBAL|CDS_NORESET)) && !(dwflags & CDS_UPDATEREGISTRY))
+ {
+ return DISP_CHANGE_BADFLAGS;
}
/* Copy the device name */
- if (lpszDeviceName != NULL)
+ if (pustrDevice)
{
- Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
- if (!NT_SUCCESS(Status))
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
+ _SEH2_TRY
{
- SetLastNtError(Status);
- return DISP_CHANGE_BADPARAM;
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
}
- pSafeDeviceName = &SafeDeviceName;
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Set and return error */
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
+ }
+ _SEH2_END
+
+ pustrDevice = &ustrDevice;
+ }
+
+ /* Copy devmode */
+ if (lpDevMode)
+ {
+ _SEH2_TRY
+ {
+ /* Probe the size field of the structure */
+ ProbeForRead(lpDevMode, sizeof(dmLocal.dmSize), 1);
+
+ /* Calculate usable size */
+ dmLocal.dmSize = min(sizeof(dmLocal), lpDevMode->dmSize);
+
+ /* Probe and copy the full DEVMODE */
+ ProbeForRead(lpDevMode, dmLocal.dmSize, 1);
+ RtlCopyMemory(&dmLocal, lpDevMode, dmLocal.dmSize);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Set and return error */
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
+ }
+ _SEH2_END
+
+ /* Check for extra parameters */
+ if (dmLocal.dmDriverExtra > 0)
+ {
+ /* FIXME: TODO */
+ DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n");
+ dmLocal.dmDriverExtra = 0;
+ }
+
+ /* Use the local structure */
+ lpDevMode = &dmLocal;
}
+ // FIXME: Copy videoparameters
+
+ /* Acquire global USER lock */
+ UserEnterExclusive();
+
/* Call internal function */
- Ret = IntChangeDisplaySettings(pSafeDeviceName, lpSafeDevMode, dwflags, lParam);
+ lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, hwnd, dwflags, NULL);
- if (pSafeDeviceName != NULL)
- RtlFreeUnicodeString(pSafeDeviceName);
+ /* Release lock */
+ UserLeave();
- return Ret;
+ return lRet;
}
diff --git a/subsystems/win32/win32k/ntuser/event.c b/subsystems/win32/win32k/ntuser/event.c
index 02d2ffeb2a2..cdc2092439a 100644
--- a/subsystems/win32/win32k/ntuser/event.c
+++ b/subsystems/win32/win32k/ntuser/event.c
@@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Window event handlers
- * FILE: subsystem/win32/win32k/ntuser/event.c
+ * FILE: subsystems/win32/win32k/ntuser/event.c
* PROGRAMER: James Tabor (james.tabor@rectos.org)
*/
@@ -103,12 +103,15 @@ IntCallLowLevelEvent( PEVENTHOOK pEH,
LONG idChild)
{
NTSTATUS Status;
- ULONG_PTR uResult;
- EVENTPACK EP;
+ PEVENTPACK pEP;
+ ULONG_PTR uResult = 0;
- EP.pEH = pEH;
- EP.idObject = idObject;
- EP.idChild = idChild;
+ pEP = ExAllocatePoolWithTag(NonPagedPool, sizeof(EVENTPACK), TAG_HOOK);
+ if (!pEP) return 0;
+
+ pEP->pEH = pEH;
+ pEP->idObject = idObject;
+ pEP->idChild = idChild;
/* FIXME should get timeout from
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
@@ -116,16 +119,18 @@ IntCallLowLevelEvent( PEVENTHOOK pEH,
hwnd,
event,
0,
- (LPARAM)&EP,
- 5000,
+ (LPARAM)pEP,
+ 300,
TRUE,
MSQ_ISEVENT,
&uResult);
-
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(pEP, TAG_HOOK);
+ }
return NT_SUCCESS(Status) ? uResult : 0;
}
-
static
BOOL
FASTCALL
@@ -145,14 +150,49 @@ IntRemoveEvent(PEVENTHOOK pEH)
return FALSE;
}
+VOID
+FASTCALL
+EVENT_DestroyThreadEvents(PETHREAD Thread)
+{
+ PTHREADINFO pti;
+ PEVENTHOOK pEH;
+ PLIST_ENTRY pLE;
+
+ pti = Thread->Tcb.Win32Thread;
+ if (!pti) return;
+
+ if (!GlobalEvents || !GlobalEvents->Counts) return;
+
+ pLE = GlobalEvents->Events.Flink;
+ if (IsListEmpty(pLE)) return;
+
+ pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
+ do
+ {
+ if (IsListEmpty(pLE)) break;
+ if (!pEH) break;
+ pLE = pEH->Chain.Flink;
+ if (pEH->head.pti == pti)
+ {
+ IntRemoveEvent(pEH);
+ }
+ pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
+ } while (pLE != &GlobalEvents->Events);
+
+ return;
+}
+
/* FUNCTIONS *****************************************************************/
+//
+// Dispatch MsgQueue Event Call processor!
+//
LRESULT
FASTCALL
co_EVENT_CallEvents( DWORD event,
- HWND hwnd,
- UINT_PTR idObject,
- LONG_PTR idChild)
+ HWND hwnd,
+ UINT_PTR idObject,
+ LONG_PTR idChild)
{
PEVENTHOOK pEH;
LRESULT Result;
@@ -165,9 +205,11 @@ co_EVENT_CallEvents( DWORD event,
hwnd,
pEP->idObject,
pEP->idChild,
- (DWORD_PTR)(NtCurrentTeb()->ClientId).UniqueThread,
+ PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
(DWORD)EngGetTickCount(),
pEH->Proc);
+
+ ExFreePoolWithTag(pEP, TAG_HOOK);
return Result;
}
@@ -177,55 +219,66 @@ IntNotifyWinEvent(
DWORD Event,
PWND pWnd,
LONG idObject,
- LONG idChild)
+ LONG idChild,
+ DWORD flags)
{
PEVENTHOOK pEH;
PLIST_ENTRY pLE;
+ PTHREADINFO pti, ptiCurrent;
DPRINT("IntNotifyWinEvent GlobalEvents = 0x%x pWnd 0x%x\n",GlobalEvents, pWnd);
- if (!pWnd) return;
+ if (!GlobalEvents || !GlobalEvents->Counts) return;
if (pWnd && pWnd->state & WNDS_DESTROYED) return;
- if (!GlobalEvents || !GlobalEvents->Counts) return;
+ ptiCurrent = PsGetCurrentThreadWin32Thread();
+
+ if (pWnd && flags & WEF_SETBYWNDPTI)
+ pti = pWnd->head.pti;
+ else
+ pti = ptiCurrent;
pLE = GlobalEvents->Events.Flink;
pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
do
- {
+ {
+ if (!pEH) break;
UserReferenceObject(pEH);
// Must be inside the event window.
if ( (pEH->eventMin <= Event) && (pEH->eventMax >= Event))
{
- if (pEH->head.pti->pEThread != PsGetCurrentThread())
- { // if all process || all thread || other thread same process
- if (!(pEH->idProcess) || !(pEH->idThread) ||
- (NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)(DWORD_PTR)pEH->idProcess))
+// if all process || all thread || other thread same process
+// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process)
+ if ( (!pEH->idProcess || pEH->idProcess == PtrToUint(pti->pEThread->Cid.UniqueProcess)) &&
+ (!(pEH->Flags & WINEVENT_SKIPOWNPROCESS) || pEH->head.pti->ppi != pti->ppi) &&
+ (!pEH->idThread || pEH->idThread == PtrToUint(pti->pEThread->Cid.UniqueThread)) &&
+ (!(pEH->Flags & WINEVENT_SKIPOWNTHREAD) || pEH->head.pti != pti) &&
+ pEH->head.pti->rpdesk == ptiCurrent->rpdesk ) // Same as hooks.
+ {
+ // Send message to the thread if pEH is not current.
+ if (pEH->head.pti != ptiCurrent)
{
+ DPRINT1("Global Event 0x%x, idObject %d\n", Event, idObject);
IntCallLowLevelEvent( pEH,
Event,
UserHMGetHandle(pWnd),
idObject,
idChild);
}
- }// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process)
- else if ( !(pEH->Flags & WINEVENT_SKIPOWNTHREAD) &&
- ( ((pEH->idProcess &&
- NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)(DWORD_PTR)pEH->idProcess) &&
- !(pEH->Flags & WINEVENT_SKIPOWNPROCESS)) ||
- !pEH->idProcess ) )
- {
- // What in the deuce is this right-aligned formatting?
- co_IntCallEventProc( UserHMGetHandle(pEH),
- Event,
- UserHMGetHandle(pWnd),
- idObject,
- idChild,
- PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
- (DWORD)EngGetTickCount(),
- pEH->Proc);
- }
+ else
+ {
+ DPRINT1("Local Event 0x%x, idObject %d\n", Event, idObject);
+ co_IntCallEventProc( UserHMGetHandle(pEH),
+ Event,
+ UserHMGetHandle(pWnd),
+ idObject,
+ idChild,
+ PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
+ (DWORD)EngGetTickCount(),
+ pEH->Proc);
+ }
+ }
}
UserDereferenceObject(pEH);
pLE = pEH->Chain.Flink;
@@ -246,17 +299,21 @@ NtUserNotifyWinEvent(
UserEnterExclusive();
/* Validate input */
- if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd)))
+ if (hWnd && (hWnd != INVALID_HANDLE_VALUE))
{
- UserLeave();
- return;
+ Window = UserGetWindowObject(hWnd);
+ if (!Window)
+ {
+ UserLeave();
+ return;
+ }
}
if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(Event))
{
- UserRefObjectCo(Window, &Ref);
- IntNotifyWinEvent( Event, Window, idObject, idChild);
- UserDerefObjectCo(Window);
+ if (Window) UserRefObjectCo(Window, &Ref);
+ IntNotifyWinEvent( Event, Window, idObject, idChild, WEF_SETBYWNDPTI);
+ if (Window) UserDerefObjectCo(Window);
}
UserLeave();
}
@@ -322,7 +379,7 @@ NtUserSetWinEventHook(
goto SetEventExit;
}
}
-
+ // Creator, pti is set here.
pEH = UserCreateObject(gHandleTable, NULL, &Handle, otEvent, sizeof(EVENTHOOK));
if (pEH)
{
@@ -330,16 +387,18 @@ NtUserSetWinEventHook(
GlobalEvents->Counts++;
UserHMGetHandle(pEH) = Handle;
- if (Thread)
- pEH->head.pti = Thread->Tcb.Win32Thread;
- else
- pEH->head.pti = GetW32ThreadInfo();
pEH->eventMin = eventMin;
pEH->eventMax = eventMax;
- pEH->idProcess = idProcess;
- pEH->idThread = idThread;
+ pEH->idProcess = idProcess; // These are cmp'ed
+ pEH->idThread = idThread; // "
pEH->Flags = dwflags;
-
+ /*
+ If WINEVENT_INCONTEXT, set offset from hmod and proc. Save ihmod from
+ the atom index table where the hmod data is saved to be recalled later
+ if fSync set by WINEVENT_INCONTEXT.
+ If WINEVENT_OUTOFCONTEXT just use proc..
+ Do this instead....
+ */
if (NULL != hmodWinEventProc)
{
pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc);
diff --git a/subsystems/win32/win32k/ntuser/focus.c b/subsystems/win32/win32k/ntuser/focus.c
index 5832eaf41ad..414b1523bf7 100644
--- a/subsystems/win32/win32k/ntuser/focus.c
+++ b/subsystems/win32/win32k/ntuser/focus.c
@@ -165,6 +165,7 @@ co_IntSendKillFocusMessages(HWND hWndPrev, HWND hWnd)
{
if (hWndPrev)
{
+ IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(hWndPrev, WM_KILLFOCUS, (WPARAM)hWnd, 0);
}
}
@@ -174,6 +175,8 @@ co_IntSendSetFocusMessages(HWND hWndPrev, HWND hWnd)
{
if (hWnd)
{
+ PWND pWnd = UserGetWindowObject(hWnd);
+ IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(hWnd, WM_SETFOCUS, (WPARAM)hWndPrev, 0);
}
}
@@ -356,8 +359,10 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL)
cbt.fMouse = FALSE;
cbt.hWndActive = hWndPrev;
if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt))
+ {
+ DPRINT1("SetActiveWindow WH_CBT Call Hook return!\n");
return 0;
-
+ }
ThreadQueue->ActiveWindow = hWnd;
co_IntSendDeactivateMessages(hWndPrev, hWnd);
@@ -392,9 +397,11 @@ co_IntSetFocusWindow(PWND Window OPTIONAL)
return hWndPrev;
}
- if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
- return 0;
-
+ if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
+ {
+ DPRINT1("SetFocusWindow 1 WH_CBT Call Hook return!\n");
+ return 0;
+ }
ThreadQueue->FocusWindow = Window->head.h;
co_IntSendKillFocusMessages(hWndPrev, Window->head.h);
@@ -403,9 +410,11 @@ co_IntSetFocusWindow(PWND Window OPTIONAL)
else
{
ThreadQueue->FocusWindow = 0;
-
- if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
- return 0;
+ if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
+ {
+ DPRINT1("SetFocusWindow 2 WH_CBT Call Hook return!\n");
+ return 0;
+ }
co_IntSendKillFocusMessages(hWndPrev, 0);
}
@@ -533,7 +542,7 @@ NtUserSetCapture(HWND hWnd)
{
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE ThreadQueue;
- PWND Window;
+ PWND Window, pWnd;
HWND hWndPrev;
DECLARE_RETURN(HWND);
@@ -553,13 +562,23 @@ NtUserSetCapture(HWND hWnd)
hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd);
+ if (hWndPrev)
+ {
+ pWnd = UserGetWindowObject(hWndPrev);
+ if (pWnd)
+ IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
+ }
+
/* also remove other windows if not capturing anymore */
- if(hWnd == NULL)
+ if (hWnd == NULL)
{
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL);
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL);
}
+ if (Window)
+ IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
+
co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
ThreadQueue->CaptureWindow = hWnd;
diff --git a/subsystems/win32/win32k/ntuser/guicheck.c b/subsystems/win32/win32k/ntuser/guicheck.c
index e3766d8c4b2..50421737fb9 100644
--- a/subsystems/win32/win32k/ntuser/guicheck.c
+++ b/subsystems/win32/win32k/ntuser/guicheck.c
@@ -130,7 +130,9 @@ IntUserManualGuiCheck(LONG Check)
}
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitGuiCheckImpl (VOID)
{
return STATUS_SUCCESS;
diff --git a/subsystems/win32/win32k/ntuser/hook.c b/subsystems/win32/win32k/ntuser/hook.c
index 6b6df548973..f41d7bad0ce 100644
--- a/subsystems/win32/win32k/ntuser/hook.c
+++ b/subsystems/win32/win32k/ntuser/hook.c
@@ -2,8 +2,10 @@
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Window hooks
- * FILE: subsystem/win32/win32k/ntuser/hook.c
+ * FILE: subsystems/win32/win32k/ntuser/hook.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * James Tabor (james.tabor@rectos.org)
+ *
* REVISION HISTORY:
* 06-06-2001 CSH Created
* NOTE: Most of this code was adapted from Wine,
@@ -15,474 +17,167 @@
#define NDEBUG
#include
-static PHOOKTABLE GlobalHooks;
-
+typedef struct _HOOKPACK
+{
+ PHOOK pHk;
+ LPARAM lParam;
+ PVOID pHookStructs;
+} HOOKPACK, *PHOOKPACK;
/* PRIVATE FUNCTIONS *********************************************************/
-
-/* create a new hook table */
-static
-PHOOKTABLE
-IntAllocHookTable(void)
-{
- PHOOKTABLE Table;
- UINT i;
-
- Table = ExAllocatePoolWithTag(PagedPool, sizeof(HOOKTABLE), TAG_HOOK);
- if (NULL != Table)
- {
- for (i = 0; i < NB_HOOKS; i++)
- {
- InitializeListHead(&Table->Hooks[i]);
- Table->Counts[i] = 0;
- }
- }
-
- return Table;
-}
-
-
-PHOOK
-FASTCALL
-IntGetHookObject(HHOOK hHook)
-{
- PHOOK Hook;
-
- if (!hHook)
- {
- SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE);
- return NULL;
- }
-
- Hook = (PHOOK)UserGetObject(gHandleTable, hHook, otHook);
- if (!Hook)
- {
- SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE);
- return NULL;
- }
-
- ASSERT(Hook->head.cLockObj >= 0);
-
- Hook->head.cLockObj++;
-
- return Hook;
-}
-
-
-
-/* create a new hook and add it to the specified table */
-static
-PHOOK
-IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinStaObj)
-{
- PTHREADINFO W32Thread;
- PHOOK Hook;
- PHOOKTABLE Table = Global ? GlobalHooks : MsqGetHooks(((PTHREADINFO)Thread->Tcb.Win32Thread)->MessageQueue);
- HANDLE Handle;
-
- if (NULL == Table)
- {
- Table = IntAllocHookTable();
- if (NULL == Table)
- {
- return NULL;
- }
- if (Global)
- {
- GlobalHooks = Table;
- }
- else
- {
- MsqSetHooks(((PTHREADINFO)Thread->Tcb.Win32Thread)->MessageQueue, Table);
- }
- }
-
- Hook = UserCreateObject(gHandleTable, NULL, &Handle, otHook, sizeof(HOOK));
- if (NULL == Hook)
- {
- return NULL;
- }
-
- Hook->Thread = Thread;
- Hook->HookId = HookId;
-
- if (Thread)
- {
- W32Thread = ((PTHREADINFO)Thread->Tcb.Win32Thread);
- ASSERT(W32Thread != NULL);
- W32Thread->fsHooks |= HOOKID_TO_FLAG(HookId);
-
- if (W32Thread->pClientInfo)
- W32Thread->pClientInfo->fsHooks = W32Thread->fsHooks;
-
- if (W32Thread->pDeskInfo) // Do this for now.
- W32Thread->pDeskInfo->fsHooks= W32Thread->fsHooks;
-
- Hook->head.pti = W32Thread;
- Hook->head.rpdesk = W32Thread->rpdesk;
- }
-
- RtlInitUnicodeString(&Hook->ModuleName, NULL);
-
- InsertHeadList(&Table->Hooks[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
-
- return Hook;
-}
-
-/* get the hook table that a given hook belongs to */
-static
-PHOOKTABLE
-FASTCALL
-IntGetTable(PHOOK Hook)
-{
- if (NULL == Hook->Thread || WH_KEYBOARD_LL == Hook->HookId ||
- WH_MOUSE_LL == Hook->HookId)
- {
- return GlobalHooks;
- }
-
- return MsqGetHooks(((PTHREADINFO)Hook->Thread->Tcb.Win32Thread)->MessageQueue);
-}
-
-/* get the first hook in the chain */
-static
-PHOOK
-FASTCALL
-IntGetFirstHook(PHOOKTABLE Table, int HookId)
-{
- PLIST_ENTRY Elem = Table->Hooks[HOOKID_TO_INDEX(HookId)].Flink;
-
- return Elem == &Table->Hooks[HOOKID_TO_INDEX(HookId)]
- ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain);
-}
-
-/* find the first non-deleted hook in the chain */
-static
-PHOOK
-FASTCALL
-IntGetFirstValidHook(PHOOKTABLE Table, int HookId)
-{
- PHOOK Hook;
- PLIST_ENTRY Elem;
-
- Hook = IntGetFirstHook(Table, HookId);
-
- while (NULL != Hook && NULL == Hook->Proc)
- {
- Elem = Hook->Chain.Flink;
- Hook = (Elem == &Table->Hooks[HOOKID_TO_INDEX(HookId)]
- ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain));
- }
-
- return Hook;
-}
-
-/* find the next hook in the chain, skipping the deleted ones */
-PHOOK
-FASTCALL
-IntGetNextHook(PHOOK Hook)
-{
- PHOOKTABLE Table = IntGetTable(Hook);
- int HookId = Hook->HookId;
- PLIST_ENTRY Elem;
-
- Elem = Hook->Chain.Flink;
- while (Elem != &Table->Hooks[HOOKID_TO_INDEX(HookId)])
- {
- Hook = CONTAINING_RECORD(Elem, HOOK, Chain);
- if (NULL != Hook->Proc)
- {
- return Hook;
- }
- }
-
- if (NULL != GlobalHooks && Table != GlobalHooks) /* now search through the global table */
- {
- return IntGetFirstValidHook(GlobalHooks, HookId);
- }
-
- return NULL;
-}
-
-/* free a hook, removing it from its chain */
-static
-VOID
-FASTCALL
-IntFreeHook(PHOOKTABLE Table, PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
-{
- RemoveEntryList(&Hook->Chain);
- RtlFreeUnicodeString(&Hook->ModuleName);
-
- /* Dereference thread if required */
- if (Hook->Flags & HOOK_THREAD_REFERENCED)
- {
- ObDereferenceObject(Hook->Thread);
- }
-
- /* Close handle */
- UserDeleteObject(UserHMGetHandle(Hook), otHook);
-}
-
-/* remove a hook, freeing it if the chain is not in use */
-static
-VOID
-IntRemoveHook(PHOOK Hook, PWINSTATION_OBJECT WinStaObj, BOOL TableAlreadyLocked)
-{
- PTHREADINFO W32Thread;
- PHOOKTABLE Table = IntGetTable(Hook);
-
- ASSERT(NULL != Table); // At this point this should not be null!
-
- W32Thread = ((PTHREADINFO)Hook->Thread->Tcb.Win32Thread);
- ASSERT(W32Thread != NULL);
- W32Thread->fsHooks &= ~HOOKID_TO_FLAG(Hook->HookId);
-
- GetWin32ClientInfo()->fsHooks = W32Thread->fsHooks;
-
- if (W32Thread->pDeskInfo) // Do this for now.
- W32Thread->pDeskInfo->fsHooks= W32Thread->fsHooks;
-
- if (0 != Table->Counts[HOOKID_TO_INDEX(Hook->HookId)])
- {
- Hook->Proc = NULL; /* chain is in use, just mark it and return */
- }
- else
- {
- IntFreeHook(Table, Hook, WinStaObj);
- }
-}
-
-/* release a hook chain, removing deleted hooks if the use count drops to 0 */
-static
-VOID
-FASTCALL
-IntReleaseHookChain(PHOOKTABLE Table, int HookId, PWINSTATION_OBJECT WinStaObj)
-{
- PLIST_ENTRY Elem;
- PHOOK HookObj;
-
- if (NULL == Table)
- {
- return;
- }
-
- /* use count shouldn't already be 0 */
- ASSERT(0 != Table->Counts[HOOKID_TO_INDEX(HookId)]);
-
- if (0 == Table->Counts[HOOKID_TO_INDEX(HookId)])
- {
- return;
- }
-
- if (0 == --Table->Counts[HOOKID_TO_INDEX(HookId)])
- {
- Elem = Table->Hooks[HOOKID_TO_INDEX(HookId)].Flink;
-
- while (Elem != &Table->Hooks[HOOKID_TO_INDEX(HookId)])
- {
- HookObj = CONTAINING_RECORD(Elem, HOOK, Chain);
- Elem = Elem->Flink;
-
- if (NULL == HookObj->Proc)
- {
- IntFreeHook(Table, HookObj, WinStaObj);
- }
- }
- }
-}
-
static
LRESULT
FASTCALL
-IntCallLowLevelHook(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam)
+IntCallLowLevelHook( PHOOK Hook,
+ INT Code,
+ WPARAM wParam,
+ LPARAM lParam)
{
NTSTATUS Status;
- ULONG_PTR uResult;
+ PTHREADINFO pti;
+ PHOOKPACK pHP;
+ INT Size;
+ UINT uTimeout = 300;
+ BOOL Block = FALSE;
+ ULONG_PTR uResult = 0;
+
+ if (Hook->Thread)
+ pti = Hook->Thread->Tcb.Win32Thread;
+ else
+ pti = Hook->head.pti;
+
+ pHP = ExAllocatePoolWithTag(NonPagedPool, sizeof(HOOKPACK), TAG_HOOK);
+ if (!pHP) return 0;
+
+ pHP->pHk = Hook;
+ pHP->lParam = lParam;
+ pHP->pHookStructs = NULL;
+ Size = 0;
+
+// This prevents stack corruption from the caller.
+ switch(Hook->HookId)
+ {
+ case WH_JOURNALPLAYBACK:
+ case WH_JOURNALRECORD:
+ uTimeout = 0;
+ Size = sizeof(EVENTMSG);
+ break;
+ case WH_KEYBOARD_LL:
+ Size = sizeof(KBDLLHOOKSTRUCT);
+ break;
+ case WH_MOUSE_LL:
+ Size = sizeof(MSLLHOOKSTRUCT);
+ break;
+ case WH_MOUSE:
+ uTimeout = 200;
+ Block = TRUE;
+ Size = sizeof(MOUSEHOOKSTRUCT);
+ break;
+ case WH_KEYBOARD:
+ uTimeout = 200;
+ Block = TRUE;
+ Size = sizeof(KBDLLHOOKSTRUCT);
+ break;
+ }
+
+ if (Size)
+ {
+ pHP->pHookStructs = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_HOOK);
+ if (pHP->pHookStructs) RtlCopyMemory(pHP->pHookStructs, (PVOID)lParam, Size);
+ }
/* FIXME should get timeout from
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
- Status = co_MsqSendMessage(((PTHREADINFO)Hook->Thread->Tcb.Win32Thread)->MessageQueue,
- IntToPtr(Code),
- Hook->HookId,
+ Status = co_MsqSendMessage( pti->MessageQueue,
+ IntToPtr(Code), // hWnd
+ Hook->HookId, // Msg
wParam,
- lParam,
- 5000,
- TRUE,
+ (LPARAM)pHP,
+ uTimeout,
+ Block,
MSQ_ISHOOK,
- &uResult);
-
+ &uResult);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error Hook Call SendMsg. %d Status: 0x%x\n", Hook->HookId, Status);
+ if (pHP->pHookStructs) ExFreePoolWithTag(pHP->pHookStructs, TAG_HOOK);
+ ExFreePoolWithTag(pHP, TAG_HOOK);
+ }
return NT_SUCCESS(Status) ? uResult : 0;
}
-/*
- Called from inside kernel space.
- */
+
+//
+// Dispatch MsgQueue Hook Call processor!
+//
LRESULT
FASTCALL
-co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
+co_CallHook( INT HookId,
+ INT Code,
+ WPARAM wParam,
+ LPARAM lParam)
{
- PHOOK Hook, SaveHook;
- PTHREADINFO pti;
- PCLIENTINFO ClientInfo;
- PHOOKTABLE Table;
LRESULT Result;
- PWINSTATION_OBJECT WinStaObj;
- NTSTATUS Status;
+ PHOOK phk;
+ PHOOKPACK pHP = (PHOOKPACK)lParam;
- ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK);
+ phk = pHP->pHk;
+ lParam = pHP->lParam;
-#if 0
- /* FIXME! Check pDeskInfo->fsHooks for global hooks! */
- if (!ISITHOOKED(HookId))
+ switch(HookId)
{
- return 0;
- }
-#endif
-
- pti = PsGetCurrentThreadWin32Thread();
- if (!pti)
- {
- Table = NULL;
- }
- else
- {
- Table = MsqGetHooks(pti->MessageQueue);
+ case WH_JOURNALPLAYBACK:
+ case WH_JOURNALRECORD:
+ case WH_KEYBOARD:
+ case WH_KEYBOARD_LL:
+ case WH_MOUSE_LL:
+ case WH_MOUSE:
+ lParam = (LPARAM)pHP->pHookStructs;
+ break;
}
- if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId)))
- {
- /* try global table */
- Table = GlobalHooks;
- if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId)))
- {
- return 0; /* no hook set */
- }
- }
-
- if ((Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL))
- {
- DPRINT1("\nHook found by Id and posted to Thread! %d\n",HookId );
- /* Post it in message queue. */
- return IntCallLowLevelHook(Hook, Code, wParam, lParam);
- }
-
- Table->Counts[HOOKID_TO_INDEX(HookId)]++;
- if (Table != GlobalHooks && GlobalHooks != NULL)
- {
- GlobalHooks->Counts[HOOKID_TO_INDEX(HookId)]++;
- }
-
- ClientInfo = GetWin32ClientInfo();
- SaveHook = ClientInfo->phkCurrent;
- ClientInfo->phkCurrent = Hook; /* Load the call. */
-
- Result = co_IntCallHookProc(HookId,
- Code,
- wParam,
- lParam,
- Hook->Proc,
- Hook->Ansi,
- &Hook->ModuleName);
-
- ClientInfo->phkCurrent = SaveHook;
-
- Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
- KernelMode,
- 0,
- &WinStaObj);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid window station????\n");
- }
- else
- {
- IntReleaseHookChain(MsqGetHooks(pti->MessageQueue), HookId, WinStaObj);
- IntReleaseHookChain(GlobalHooks, HookId, WinStaObj);
- ObDereferenceObject(WinStaObj);
- }
+ /* The odds are high for this to be a Global call. */
+ Result = co_IntCallHookProc( HookId,
+ Code,
+ wParam,
+ lParam,
+ phk->Proc,
+ phk->Ansi,
+ &phk->ModuleName);
+ /* The odds so high, no one is waiting for the results. */
+ if (pHP->pHookStructs) ExFreePoolWithTag(pHP->pHookStructs, TAG_HOOK);
+ ExFreePoolWithTag(pHP, TAG_HOOK);
return Result;
}
-VOID
-FASTCALL
-HOOK_DestroyThreadHooks(PETHREAD Thread)
-{
- int HookId;
- PLIST_ENTRY Elem;
- PHOOK HookObj;
- PWINSTATION_OBJECT WinStaObj;
- NTSTATUS Status;
-
- if (NULL != GlobalHooks)
- {
- Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
- KernelMode,
- 0,
- &WinStaObj);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid window station????\n");
- return;
- }
-
- for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++)
- {
- /* only low-level keyboard/mouse global hooks can be owned by a thread */
- switch(HookId)
- {
- case WH_KEYBOARD_LL:
- case WH_MOUSE_LL:
- Elem = GlobalHooks->Hooks[HOOKID_TO_INDEX(HookId)].Flink;
-
- while (Elem != &GlobalHooks->Hooks[HOOKID_TO_INDEX(HookId)])
- {
- HookObj = CONTAINING_RECORD(Elem, HOOK, Chain);
- Elem = Elem->Flink;
-
- if (HookObj->Thread == Thread)
- {
- IntRemoveHook(HookObj, WinStaObj, TRUE);
- }
- }
- break;
- }
- }
- }
-}
-
static
LRESULT
FASTCALL
-co_HOOK_CallHookNext(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam)
+co_HOOK_CallHookNext( PHOOK Hook,
+ INT Code,
+ WPARAM wParam,
+ LPARAM lParam)
{
- if ((Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL))
- {
- DPRINT1("CALLING HOOK from another Thread. %d\n", Hook->HookId);
- return IntCallLowLevelHook(Hook, Code, wParam, lParam);
- }
+ DPRINT("Calling Next HOOK %d\n", Hook->HookId);
- DPRINT("CALLING HOOK %d\n", Hook->HookId);
-
- return co_IntCallHookProc(Hook->HookId,
- Code,
- wParam,
- lParam,
- Hook->Proc,
- Hook->Ansi,
+ return co_IntCallHookProc( Hook->HookId,
+ Code,
+ wParam,
+ lParam,
+ Hook->Proc,
+ Hook->Ansi,
&Hook->ModuleName);
}
-
LRESULT
FASTCALL
-IntCallDebugHook(PHOOK Hook,
- int Code,
- WPARAM wParam,
- LPARAM lParam)
+IntCallDebugHook( PHOOK Hook,
+ int Code,
+ WPARAM wParam,
+ LPARAM lParam,
+ BOOL Ansi)
{
LRESULT lResult = 0;
ULONG Size;
@@ -608,16 +303,13 @@ IntCallDebugHook(PHOOK Hook,
return lResult;
}
-/*
- Called from user space via CallNextHook.
- */
LRESULT
FASTCALL
-UserCallNextHookEx(PHOOK Hook,
- int Code,
- WPARAM wParam,
- LPARAM lParam,
- BOOL Ansi)
+UserCallNextHookEx( PHOOK Hook,
+ int Code,
+ WPARAM wParam,
+ LPARAM lParam,
+ BOOL Ansi)
{
LRESULT lResult = 0;
BOOL BadChk = FALSE;
@@ -940,7 +632,11 @@ UserCallNextHookEx(PHOOK Hook,
break;
}
break;
-
+/*
+ Note WH_JOURNALPLAYBACK,
+ "To have the system wait before processing the message, the return value
+ must be the amount of time, in clock ticks, that the system should wait."
+ */
case WH_JOURNALPLAYBACK:
case WH_JOURNALRECORD:
{
@@ -1002,7 +698,7 @@ UserCallNextHookEx(PHOOK Hook,
}
case WH_DEBUG:
- lResult = IntCallDebugHook(Hook, Code, wParam, lParam);
+ lResult = IntCallDebugHook(Hook, Code, wParam, lParam, Ansi);
break;
/*
@@ -1018,70 +714,499 @@ UserCallNextHookEx(PHOOK Hook,
DPRINT1("Unsupported HOOK Id -> %d\n",Hook->HookId);
break;
}
-
return lResult;
}
+PHOOK
+FASTCALL
+IntGetHookObject(HHOOK hHook)
+{
+ PHOOK Hook;
+
+ if (!hHook)
+ {
+ SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE);
+ return NULL;
+ }
+
+ Hook = (PHOOK)UserGetObject(gHandleTable, hHook, otHook);
+ if (!Hook)
+ {
+ SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE);
+ return NULL;
+ }
+
+ UserReferenceObject(Hook);
+
+ return Hook;
+}
+
+/* get the first hook in the chain */
+static
+PHOOK
+FASTCALL
+IntGetFirstHook(PLIST_ENTRY Table)
+{
+ PLIST_ENTRY Elem = Table->Flink;
+
+ if (IsListEmpty(Table)) return NULL;
+
+ return Elem == Table ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain);
+}
+
+static
+PHOOK
+FASTCALL
+IntGetNextGlobalHook(PHOOK Hook, PDESKTOP pdo)
+{
+ int HookId = Hook->HookId;
+ PLIST_ENTRY Elem;
+
+ Elem = Hook->Chain.Flink;
+ if (Elem != &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)])
+ return CONTAINING_RECORD(Elem, HOOK, Chain);
+ return NULL;
+}
+
+/* find the next hook in the chain */
+PHOOK
+FASTCALL
+IntGetNextHook(PHOOK Hook)
+{
+ int HookId = Hook->HookId;
+ PLIST_ENTRY Elem;
+ PTHREADINFO pti;
+
+ if (Hook->Thread)
+ {
+ pti = ((PTHREADINFO)Hook->Thread->Tcb.Win32Thread);
+
+ Elem = Hook->Chain.Flink;
+ if (Elem != &pti->aphkStart[HOOKID_TO_INDEX(HookId)])
+ return CONTAINING_RECORD(Elem, HOOK, Chain);
+ }
+ else
+ {
+ pti = PsGetCurrentThreadWin32Thread();
+ return IntGetNextGlobalHook(Hook, pti->rpdesk);
+ }
+ return NULL;
+}
+
+/* free a hook, removing it from its chain */
+static
+VOID
+FASTCALL
+IntFreeHook(PHOOK Hook)
+{
+ RemoveEntryList(&Hook->Chain);
+ if (Hook->ModuleName.Buffer)
+ {
+ ExFreePoolWithTag(Hook->ModuleName.Buffer, TAG_HOOK);
+ Hook->ModuleName.Buffer = NULL;
+ }
+ /* Close handle */
+ UserDeleteObject(UserHMGetHandle(Hook), otHook);
+}
+
+/* remove a hook, freeing it from the chain */
+static
+BOOL
+FASTCALL
+IntRemoveHook(PHOOK Hook)
+{
+ INT HookId;
+ PTHREADINFO pti;
+ PDESKTOP pdo;
+
+ HookId = Hook->HookId;
+
+ if (Hook->Thread) // Local
+ {
+ pti = ((PTHREADINFO)Hook->Thread->Tcb.Win32Thread);
+
+ IntFreeHook( Hook);
+
+ if ( IsListEmpty(&pti->aphkStart[HOOKID_TO_INDEX(HookId)]) )
+ {
+ pti->fsHooks &= ~HOOKID_TO_FLAG(HookId);
+ _SEH2_TRY
+ {
+ GetWin32ClientInfo()->fsHooks = pti->fsHooks;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+ _SEH2_END;
+ return TRUE;
+ }
+ }
+ else // Global
+ {
+ IntFreeHook( Hook);
+
+ pdo = IntGetActiveDesktop();
+
+ if ( pdo &&
+ pdo->pDeskInfo &&
+ IsListEmpty(&pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]) )
+ {
+ pdo->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+VOID
+FASTCALL
+HOOK_DestroyThreadHooks(PETHREAD Thread)
+{
+ PTHREADINFO pti;
+ PDESKTOP pdo;
+ int HookId;
+ PHOOK HookObj;
+ PLIST_ENTRY pElem;
+
+ pti = Thread->Tcb.Win32Thread;
+ pdo = IntGetActiveDesktop();
+
+ if (!pti || !pdo)
+ {
+ DPRINT1("Kill Thread Hooks pti 0x%x pdo 0x%x\n",pti,pdo);
+ return;
+ }
+ ObReferenceObject(Thread);
+
+// Local Thread cleanup.
+ if (pti->fsHooks)
+ {
+ for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++)
+ {
+ PLIST_ENTRY pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
+
+ if (IsListEmpty(pLLE)) continue;
+
+ pElem = pLLE->Flink;
+ HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
+ do
+ {
+ if (!HookObj) break;
+ if (IntRemoveHook(HookObj)) break;
+ pElem = HookObj->Chain.Flink;
+ HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
+ }
+ while (pElem != pLLE);
+ }
+ pti->fsHooks = 0;
+ }
+// Global search based on Thread and cleanup.
+ if (pdo->pDeskInfo->fsHooks)
+ {
+ for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++)
+ {
+ PLIST_ENTRY pGLE = &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
+
+ if (IsListEmpty(pGLE)) continue;
+
+ pElem = pGLE->Flink;
+ HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
+ do
+ {
+ if (!HookObj) break;
+ if (HookObj->head.pti == pti)
+ {
+ if (IntRemoveHook(HookObj)) break;
+ }
+ pElem = HookObj->Chain.Flink;
+ HookObj = CONTAINING_RECORD(pElem, HOOK, Chain);
+ }
+ while (pElem != pGLE);
+ }
+ }
+ ObDereferenceObject(Thread);
+ return;
+}
+
+/*
+ Win32k Kernel Space Hook Caller.
+ */
+LRESULT
+FASTCALL
+co_HOOK_CallHooks( INT HookId,
+ INT Code,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ PHOOK Hook, SaveHook;
+ PTHREADINFO pti;
+ PCLIENTINFO ClientInfo;
+ PLIST_ENTRY pLLE, pGLE;
+ PDESKTOP pdo;
+ BOOL Local = FALSE, Global = FALSE;
+ LRESULT Result = 0;
+
+ ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK);
+
+ pti = PsGetCurrentThreadWin32Thread();
+ if (!pti || !pti->rpdesk || !pti->rpdesk->pDeskInfo)
+ {
+ pdo = IntGetActiveDesktop();
+ /* If KeyboardThread|MouseThread|(RawInputThread or RIT) aka system threads,
+ pti->fsHooks most likely, is zero. So process KbT & MsT to "send" the message.
+ */
+ if ( !pti || !pdo || (!(HookId == WH_KEYBOARD_LL) && !(HookId == WH_MOUSE_LL)) )
+ {
+ DPRINT("No PDO %d\n", HookId);
+ goto Exit;
+ }
+ }
+ else
+ {
+ pdo = pti->rpdesk;
+ }
+
+ if ( pti->TIF_flags & (TIF_INCLEANUP|TIF_DISABLEHOOKS))
+ {
+ DPRINT("Hook Thread dead %d\n", HookId);
+ goto Exit;
+ }
+
+ if ( ISITHOOKED(HookId) )
+ {
+ DPRINT("Local Hooker %d\n", HookId);
+ Local = TRUE;
+ }
+
+ if ( pdo->pDeskInfo->fsHooks & HOOKID_TO_FLAG(HookId) )
+ {
+ DPRINT("Global Hooker %d\n", HookId);
+ Global = TRUE;
+ }
+
+ if ( !Local && !Global ) goto Exit; // No work!
+
+ Hook = NULL;
+
+ /* SetWindowHookEx sorts out the Thread issue by placing the Hook to
+ the correct Thread if not NULL.
+ */
+ if ( Local )
+ {
+ pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
+ Hook = IntGetFirstHook(pLLE);
+ if (!Hook)
+ {
+ DPRINT1("No Local Hook Found!\n");
+ goto Exit;
+ }
+ ObReferenceObject(Hook->Thread);
+
+ ClientInfo = pti->pClientInfo;
+ SaveHook = pti->sphkCurrent;
+
+ /* Load it for the next call. */
+ pti->sphkCurrent = Hook;
+ Hook->phkNext = IntGetNextHook(Hook);
+ if (ClientInfo)
+ {
+ _SEH2_TRY
+ {
+ ClientInfo->phkCurrent = Hook;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ClientInfo = NULL; // Don't bother next run.
+ }
+ _SEH2_END;
+ }
+ Result = co_IntCallHookProc( HookId,
+ Code,
+ wParam,
+ lParam,
+ Hook->Proc,
+ Hook->Ansi,
+ &Hook->ModuleName);
+ if (ClientInfo)
+ {
+ _SEH2_TRY
+ {
+ ClientInfo->phkCurrent = SaveHook;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+ _SEH2_END;
+ }
+ pti->sphkCurrent = SaveHook;
+ Hook->phkNext = NULL;
+ ObDereferenceObject(Hook->Thread);
+ }
+
+ if ( Global )
+ {
+ PTHREADINFO ptiHook;
+
+ pGLE = &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
+ Hook = IntGetFirstHook(pGLE);
+ if (!Hook)
+ {
+ DPRINT1("No Global Hook Found!\n");
+ goto Exit;
+ }
+ /* Performance goes down the drain. If more hooks are associated to this
+ * hook ID, this will have to post to each of the thread message queues
+ * or make a direct call.
+ */
+ do
+ {
+ /* Hook->Thread is null, we hax around this with Hook->head.pti. */
+ ptiHook = Hook->head.pti;
+
+ /* "Global hook monitors messages for all threads in the same desktop
+ * as the calling thread."
+ */
+ if ( ptiHook->TIF_flags & (TIF_INCLEANUP|TIF_DISABLEHOOKS) ||
+ ptiHook->rpdesk != pdo)
+ {
+ DPRINT("Next Hook 0x%x, 0x%x\n",ptiHook->rpdesk,pdo);
+ Hook = IntGetNextGlobalHook(Hook, pdo);
+ if (!Hook) break;
+ continue;
+ }
+ // Lockup the thread while this links through user world.
+ ObReferenceObject(ptiHook->pEThread);
+ if (ptiHook != pti )
+ { // Block | TimeOut
+ if ( HookId == WH_JOURNALPLAYBACK || // 1 | 0
+ HookId == WH_JOURNALRECORD || // 1 | 0
+ HookId == WH_KEYBOARD || // 1 | 200
+ HookId == WH_MOUSE || // 1 | 200
+ HookId == WH_KEYBOARD_LL || // 0 | 300
+ HookId == WH_MOUSE_LL ) // 0 | 300
+ {
+ DPRINT("\nGlobal Hook posting to another Thread! %d\n",HookId );
+ Result = IntCallLowLevelHook(Hook, Code, wParam, lParam);
+ }
+ }
+ else
+ { /* Make the direct call. */
+ DPRINT("\nLocal Hook calling to Thread! %d\n",HookId );
+ Result = co_IntCallHookProc( HookId,
+ Code,
+ wParam,
+ lParam,
+ Hook->Proc,
+ Hook->Ansi,
+ &Hook->ModuleName);
+ }
+ ObDereferenceObject(ptiHook->pEThread);
+ Hook = IntGetNextGlobalHook(Hook, pdo);
+ }
+ while ( Hook );
+ DPRINT("Ret: Global HookId %d Result 0x%x\n", HookId,Result);
+ }
+Exit:
+ return Result;
+}
+
+BOOL
+FASTCALL
+IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc)
+{
+ PHOOK Hook;
+ PLIST_ENTRY pLLE, pLE;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+
+ if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId )
+ {
+ SetLastWin32Error(ERROR_INVALID_HOOK_FILTER);
+ return FALSE;
+ }
+
+ if (pti->fsHooks)
+ {
+ pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
+
+ if (IsListEmpty(pLLE)) return FALSE;
+
+ pLE = pLLE->Flink;
+ Hook = CONTAINING_RECORD(pLE, HOOK, Chain);
+ do
+ {
+ if (!Hook) break;
+ if (Hook->Proc == pfnFilterProc)
+ {
+ if (Hook->head.pti == pti)
+ {
+ IntRemoveHook(Hook);
+ UserDereferenceObject(Hook);
+ return TRUE;
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+ }
+ pLE = Hook->Chain.Flink;
+ Hook = CONTAINING_RECORD(pLE, HOOK, Chain);
+ }
+ while (pLE != pLLE);
+ }
+ return FALSE;
+}
+
+/*
+ * Support for compatibility only? Global hooks are processed in kernel space.
+ * This is very thread specific! Never seeing applications with more than one
+ * hook per thread installed. Most of the applications are Global hookers and
+ * associated with just one hook Id. Maybe it's for diagnostic testing or a
+ * throw back to 3.11?
+ */
LRESULT
APIENTRY
-NtUserCallNextHookEx(int Code,
- WPARAM wParam,
- LPARAM lParam,
- BOOL Ansi)
+NtUserCallNextHookEx( int Code,
+ WPARAM wParam,
+ LPARAM lParam,
+ BOOL Ansi)
{
+ PTHREADINFO pti;
PHOOK HookObj, NextObj;
PCLIENTINFO ClientInfo;
- PWINSTATION_OBJECT WinStaObj;
- NTSTATUS Status;
+ LRESULT lResult = 0;
DECLARE_RETURN(LRESULT);
DPRINT("Enter NtUserCallNextHookEx\n");
UserEnterExclusive();
- Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
- KernelMode,
- 0,
- &WinStaObj);
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( 0);
- }
+ pti = GetW32ThreadInfo();
- ObDereferenceObject(WinStaObj);
-
- ClientInfo = GetWin32ClientInfo();
-
- if (!ClientInfo) RETURN( 0);
-
- HookObj = ClientInfo->phkCurrent;
+ HookObj = pti->sphkCurrent;
if (!HookObj) RETURN( 0);
- /* Check that the first hook in the chain is not this hook */
- NextObj = IntGetFirstHook(IntGetTable(HookObj), HookObj->HookId);
+ NextObj = HookObj->phkNext;
- /* Its the same so it has already been called */
- if (HookObj == NextObj) RETURN(0);
-
- UserReferenceObject(HookObj);
-
- Ansi = HookObj->Ansi;
-
- if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread()))
+ pti->sphkCurrent = NextObj;
+ ClientInfo = pti->pClientInfo;
+ _SEH2_TRY
{
- DPRINT1("Thread mismatch\n");
- UserDereferenceObject(HookObj);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- RETURN( 0);
+ ClientInfo->phkCurrent = NextObj;
}
-
- NextObj = IntGetNextHook(HookObj);
- ClientInfo->phkCurrent = NextObj; /* Preset next hook from list. */
- UserCallNextHookEx( HookObj, Code, wParam, lParam, Ansi);
- UserDereferenceObject(HookObj);
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ClientInfo = NULL;
+ }
+ _SEH2_END;
- RETURN( (LRESULT)NextObj);
+ /* Now in List run down. */
+ if (ClientInfo && NextObj)
+ {
+ NextObj->phkNext = IntGetNextHook(NextObj);
+ lResult = UserCallNextHookEx( NextObj, Code, wParam, lParam, NextObj->Ansi);
+ }
+ RETURN( lResult);
CLEANUP:
DPRINT("Leave NtUserCallNextHookEx, ret=%i\n",_ret_);
@@ -1091,43 +1216,51 @@ CLEANUP:
HHOOK
APIENTRY
-NtUserSetWindowsHookAW(int idHook,
- HOOKPROC lpfn,
- BOOL Ansi)
+NtUserSetWindowsHookAW( int idHook,
+ HOOKPROC lpfn,
+ BOOL Ansi)
{
+ DWORD ThreadId;
UNICODE_STRING USModuleName;
RtlInitUnicodeString(&USModuleName, NULL);
+ ThreadId = PtrToUint(NtCurrentTeb()->ClientId.UniqueThread);
- return NtUserSetWindowsHookEx(NULL, &USModuleName, 0, idHook, lpfn, Ansi);
+ return NtUserSetWindowsHookEx( NULL,
+ &USModuleName,
+ ThreadId,
+ idHook,
+ lpfn,
+ Ansi);
}
HHOOK
APIENTRY
-NtUserSetWindowsHookEx(HINSTANCE Mod,
- PUNICODE_STRING UnsafeModuleName,
- DWORD ThreadId,
- int HookId,
- HOOKPROC HookProc,
- BOOL Ansi)
+NtUserSetWindowsHookEx( HINSTANCE Mod,
+ PUNICODE_STRING UnsafeModuleName,
+ DWORD ThreadId,
+ int HookId,
+ HOOKPROC HookProc,
+ BOOL Ansi)
{
PWINSTATION_OBJECT WinStaObj;
- PCLIENTINFO ClientInfo;
- BOOLEAN Global;
- PETHREAD Thread;
PHOOK Hook;
UNICODE_STRING ModuleName;
NTSTATUS Status;
HHOOK Handle;
- BOOLEAN ThreadReferenced = FALSE;
+ PETHREAD Thread = NULL;
+ PTHREADINFO ptiCurrent, pti = NULL;
+ BOOL Hit = FALSE;
DECLARE_RETURN(HHOOK);
DPRINT("Enter NtUserSetWindowsHookEx\n");
UserEnterExclusive();
+ ptiCurrent = PsGetCurrentThreadWin32Thread();
+
if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId )
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ SetLastWin32Error(ERROR_INVALID_HOOK_FILTER);
RETURN( NULL);
}
@@ -1137,174 +1270,221 @@ NtUserSetWindowsHookEx(HINSTANCE Mod,
RETURN( NULL);
}
- ClientInfo = GetWin32ClientInfo();
-
if (ThreadId) /* thread-local hook */
{
- if (HookId == WH_JOURNALRECORD ||
+ if ( HookId == WH_JOURNALRECORD ||
HookId == WH_JOURNALPLAYBACK ||
HookId == WH_KEYBOARD_LL ||
HookId == WH_MOUSE_LL ||
HookId == WH_SYSMSGFILTER)
- {
- /* these can only be global */
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( NULL);
- }
+ {
+ DPRINT1("Local hook installing Global HookId: %d\n",HookId);
+ /* these can only be global */
+ SetLastWin32Error(ERROR_GLOBAL_ONLY_HOOK);
+ RETURN( NULL);
+ }
- Mod = NULL;
- Global = FALSE;
+ if (!NT_SUCCESS(PsLookupThreadByThreadId((HANDLE)(DWORD_PTR) ThreadId, &Thread)))
+ {
+ DPRINT1("Invalid thread id 0x%x\n", ThreadId);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ RETURN( NULL);
+ }
- if (!NT_SUCCESS(PsLookupThreadByThreadId((HANDLE)(DWORD_PTR) ThreadId, &Thread)))
- {
- DPRINT1("Invalid thread id 0x%x\n", ThreadId);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( NULL);
- }
+ pti = Thread->Tcb.Win32Thread;
- /* Thread was referenced */
- ThreadReferenced = TRUE;
- if (Thread->ThreadsProcess != PsGetCurrentProcess())
- {
- ObDereferenceObject(Thread);
- DPRINT1("Can't specify thread belonging to another process\n");
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( NULL);
- }
+ ObDereferenceObject(Thread);
+
+ if ( pti->rpdesk != ptiCurrent->rpdesk) // gptiCurrent->rpdesk)
+ {
+ DPRINT1("Local hook wrong desktop HookId: %d\n",HookId);
+ SetLastWin32Error(ERROR_ACCESS_DENIED);
+ RETURN( NULL);
+ }
+
+ if (Thread->ThreadsProcess != PsGetCurrentProcess())
+ {
+ if ( !Mod &&
+ (HookId == WH_GETMESSAGE ||
+ HookId == WH_CALLWNDPROC ||
+ HookId == WH_CBT ||
+ HookId == WH_HARDWARE ||
+ HookId == WH_DEBUG ||
+ HookId == WH_SHELL ||
+ HookId == WH_FOREGROUNDIDLE ||
+ HookId == WH_CALLWNDPROCRET) )
+ {
+ DPRINT1("Local hook needs hMod HookId: %d\n",HookId);
+ SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD);
+ RETURN( NULL);
+ }
+
+ if ( (pti->TIF_flags & (TIF_CSRSSTHREAD|TIF_SYSTEMTHREAD)) &&
+ (HookId == WH_GETMESSAGE ||
+ HookId == WH_CALLWNDPROC ||
+ HookId == WH_CBT ||
+ HookId == WH_HARDWARE ||
+ HookId == WH_DEBUG ||
+ HookId == WH_SHELL ||
+ HookId == WH_FOREGROUNDIDLE ||
+ HookId == WH_CALLWNDPROCRET) )
+ {
+ SetLastWin32Error(ERROR_HOOK_TYPE_NOT_ALLOWED);
+ RETURN( NULL);
+ }
+ }
}
else /* system-global hook */
- {
- if (HookId == WH_KEYBOARD_LL || HookId == WH_MOUSE_LL)
- {
- Mod = NULL;
- Thread = PsGetCurrentThread();
-
- Status = ObReferenceObjectByPointer(Thread,
- THREAD_ALL_ACCESS,
- PsThreadType,
- KernelMode);
-
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( (HANDLE) NULL);
- }
-
- /* Thread was referenced */
- ThreadReferenced = TRUE;
- }
- else if (NULL == Mod)
- {
- SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD);
- RETURN( NULL);
- }
- else
- {
- Thread = NULL;
- }
- Global = TRUE;
+ {
+ pti = ptiCurrent; // gptiCurrent;
+ if ( !Mod &&
+ (HookId == WH_GETMESSAGE ||
+ HookId == WH_CALLWNDPROC ||
+ HookId == WH_CBT ||
+ HookId == WH_SYSMSGFILTER ||
+ HookId == WH_HARDWARE ||
+ HookId == WH_DEBUG ||
+ HookId == WH_SHELL ||
+ HookId == WH_FOREGROUNDIDLE ||
+ HookId == WH_CALLWNDPROCRET) )
+ {
+ DPRINT1("Global hook needs hMod HookId: %d\n",HookId);
+ SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD);
+ RETURN( NULL);
+ }
}
- if ((Global && (HookId != WH_KEYBOARD_LL && HookId != WH_MOUSE_LL)) ||
- WH_DEBUG == HookId ||
- WH_JOURNALPLAYBACK == HookId ||
- WH_JOURNALRECORD == HookId)
- {
-#if 0 /* Removed to get winEmbed working again */
- UNIMPLEMENTED
-#else
- DPRINT1("Not implemented: HookId %d Global %s\n", HookId, Global ? "TRUE" : "FALSE");
-#endif
-
- /* Dereference thread if needed */
- if (ThreadReferenced) ObDereferenceObject(Thread);
- SetLastWin32Error(ERROR_NOT_SUPPORTED);
- RETURN( NULL);
- }
-
- Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
- KernelMode,
- 0,
+ Status = IntValidateWindowStationHandle( PsGetCurrentProcess()->Win32WindowStation,
+ KernelMode,
+ 0,
&WinStaObj);
if (!NT_SUCCESS(Status))
{
- /* Dereference thread if needed */
- if (ThreadReferenced) ObDereferenceObject(Thread);
- SetLastNtError(Status);
- RETURN( (HANDLE) NULL);
+ SetLastNtError(Status);
+ RETURN( NULL);
}
-
- Hook = IntAddHook(Thread, HookId, Global, WinStaObj);
- if (NULL == Hook)
- {
- /* Dereference thread if needed */
- if (ThreadReferenced) ObDereferenceObject(Thread);
- ObDereferenceObject(WinStaObj);
- RETURN( NULL);
- }
-
- /* Let IntFreeHook now that this thread needs a dereference */
- if (ThreadReferenced)
- {
- Hook->Flags |= HOOK_THREAD_REFERENCED;
- }
-
- if (NULL != Mod)
- {
- Status = MmCopyFromCaller(&ModuleName, UnsafeModuleName, sizeof(UNICODE_STRING));
- if (!NT_SUCCESS(Status))
- {
- UserDereferenceObject(Hook);
- IntRemoveHook(Hook, WinStaObj, FALSE);
- ObDereferenceObject(WinStaObj);
- SetLastNtError(Status);
- RETURN( NULL);
- }
-
- Hook->ModuleName.Buffer = ExAllocatePoolWithTag(PagedPool,
- ModuleName.MaximumLength,
- TAG_HOOK);
- if (NULL == Hook->ModuleName.Buffer)
- {
- UserDereferenceObject(Hook);
- IntRemoveHook(Hook, WinStaObj, FALSE);
- ObDereferenceObject(WinStaObj);
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- RETURN( NULL);
- }
-
- Hook->ModuleName.MaximumLength = ModuleName.MaximumLength;
- Status = MmCopyFromCaller(Hook->ModuleName.Buffer,
- ModuleName.Buffer,
- ModuleName.MaximumLength);
- if (!NT_SUCCESS(Status))
- {
- ExFreePoolWithTag(Hook->ModuleName.Buffer, TAG_HOOK);
- UserDereferenceObject(Hook);
- IntRemoveHook(Hook, WinStaObj, FALSE);
- ObDereferenceObject(WinStaObj);
- SetLastNtError(Status);
- RETURN( NULL);
- }
-
- Hook->ModuleName.Length = ModuleName.Length;
- /* make proc relative to the module base */
- Hook->Proc = (void *)((char *)HookProc - (char *)Mod);
- }
- else
- Hook->Proc = HookProc;
-
- Hook->Ansi = Ansi;
- Handle = UserHMGetHandle(Hook);
-
- /* Clear the client threads next hook. */
- ClientInfo->phkCurrent = 0;
-
- UserDereferenceObject(Hook);
-
ObDereferenceObject(WinStaObj);
+ Hook = UserCreateObject(gHandleTable, NULL, &Handle, otHook, sizeof(HOOK));
+
+ if (!Hook)
+ {
+ RETURN( NULL);
+ }
+
+ Hook->ihmod = (INT)Mod; // Module Index from atom table, Do this for now.
+ Hook->Thread = Thread; /* Set Thread, Null is Global. */
+ Hook->HookId = HookId;
+ Hook->rpdesk = pti->rpdesk;
+ Hook->phkNext = NULL; /* Dont use as a chain! Use link lists for chaining. */
+ Hook->Proc = HookProc;
+ Hook->Ansi = Ansi;
+
+ DPRINT("Set Hook Desk 0x%x DeskInfo 0x%x Handle Desk 0x%x\n",pti->rpdesk, pti->pDeskInfo,Hook->head.rpdesk);
+
+ if (ThreadId) /* thread-local hook */
+ {
+ InsertHeadList(&pti->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
+ pti->sphkCurrent = NULL;
+ Hook->ptiHooked = pti;
+ pti->fsHooks |= HOOKID_TO_FLAG(HookId);
+
+ if (pti->pClientInfo)
+ {
+ if ( pti->ppi == ptiCurrent->ppi) /* gptiCurrent->ppi) */
+ {
+ _SEH2_TRY
+ {
+ pti->pClientInfo->fsHooks = pti->fsHooks;
+ pti->pClientInfo->phkCurrent = NULL;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Hit = TRUE;
+ }
+ _SEH2_END;
+ if (Hit)
+ {
+ DPRINT1("Problem writing to Local ClientInfo!\n");
+ }
+ }
+ else
+ {
+ KeAttachProcess(&pti->ppi->peProcess->Pcb);
+ _SEH2_TRY
+ {
+ pti->pClientInfo->fsHooks = pti->fsHooks;
+ pti->pClientInfo->phkCurrent = NULL;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Hit = TRUE;
+ }
+ _SEH2_END;
+ KeDetachProcess();
+ if (Hit)
+ {
+ DPRINT1("Problem writing to Remote ClientInfo!\n");
+ }
+ }
+ }
+ }
+ else
+ {
+ InsertHeadList(&pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
+ Hook->ptiHooked = NULL;
+ //gptiCurrent->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
+ pti->rpdesk->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
+ pti->sphkCurrent = NULL;
+ pti->pClientInfo->phkCurrent = NULL;
+ }
+
+ RtlInitUnicodeString(&Hook->ModuleName, NULL);
+
+ if (Mod)
+ {
+ Status = MmCopyFromCaller(&ModuleName,
+ UnsafeModuleName,
+ sizeof(UNICODE_STRING));
+ if (!NT_SUCCESS(Status))
+ {
+ IntRemoveHook(Hook);
+ SetLastNtError(Status);
+ RETURN( NULL);
+ }
+
+ Hook->ModuleName.Buffer = ExAllocatePoolWithTag( PagedPool,
+ ModuleName.MaximumLength,
+ TAG_HOOK);
+ if (NULL == Hook->ModuleName.Buffer)
+ {
+ IntRemoveHook(Hook);
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ RETURN( NULL);
+ }
+
+ Hook->ModuleName.MaximumLength = ModuleName.MaximumLength;
+ Status = MmCopyFromCaller( Hook->ModuleName.Buffer,
+ ModuleName.Buffer,
+ ModuleName.MaximumLength);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Hook->ModuleName.Buffer, TAG_HOOK);
+ Hook->ModuleName.Buffer = NULL;
+ IntRemoveHook(Hook);
+ SetLastNtError(Status);
+ RETURN( NULL);
+ }
+
+ Hook->ModuleName.Length = ModuleName.Length;
+ /* make proc relative to the module base */
+ Hook->offPfn = (ULONG_PTR)((char *)HookProc - (char *)Mod);
+ }
+ else
+ Hook->offPfn = 0;
+
+ DPRINT("Installing: HookId %d Global %s\n", HookId, !ThreadId ? "TRUE" : "FALSE");
RETURN( Handle);
CLEANUP:
@@ -1313,46 +1493,28 @@ CLEANUP:
END_CLEANUP;
}
-
BOOL
APIENTRY
NtUserUnhookWindowsHookEx(HHOOK Hook)
{
- PWINSTATION_OBJECT WinStaObj;
PHOOK HookObj;
- NTSTATUS Status;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserUnhookWindowsHookEx\n");
UserEnterExclusive();
- Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
- KernelMode,
- 0,
- &WinStaObj);
-
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
-
- /* Status = UserReferenceObjectByHandle(gHandleTable, Hook,
- otHookProc, (PVOID *) &HookObj); */
if (!(HookObj = IntGetHookObject(Hook)))
{
DPRINT1("Invalid handle passed to NtUserUnhookWindowsHookEx\n");
- ObDereferenceObject(WinStaObj);
/* SetLastNtError(Status); */
RETURN( FALSE);
}
ASSERT(Hook == UserHMGetHandle(HookObj));
- IntRemoveHook(HookObj, WinStaObj, FALSE);
+ IntRemoveHook(HookObj);
UserDereferenceObject(HookObj);
- ObDereferenceObject(WinStaObj);
RETURN( TRUE);
diff --git a/subsystems/win32/win32k/ntuser/hotkey.c b/subsystems/win32/win32k/ntuser/hotkey.c
index adfc6a5c3e1..0b8a68efc84 100644
--- a/subsystems/win32/win32k/ntuser/hotkey.c
+++ b/subsystems/win32/win32k/ntuser/hotkey.c
@@ -51,7 +51,9 @@ LIST_ENTRY gHotkeyList;
/* FUNCTIONS *****************************************************************/
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitHotkeyImpl(VOID)
{
InitializeListHead(&gHotkeyList);
diff --git a/subsystems/win32/win32k/ntuser/input.c b/subsystems/win32/win32k/ntuser/input.c
index 316b9308b31..717e8c4be1c 100644
--- a/subsystems/win32/win32k/ntuser/input.c
+++ b/subsystems/win32/win32k/ntuser/input.c
@@ -22,6 +22,8 @@ extern NTSTATUS Win32kInitWin32Thread(PETHREAD Thread);
/* GLOBALS *******************************************************************/
PTHREADINFO ptiRawInput;
+PTHREADINFO ptiKeyboard;
+PTHREADINFO ptiMouse;
PKTIMER MasterTimer = NULL;
PATTACHINFO gpai = NULL;
@@ -234,6 +236,18 @@ MouseThreadMain(PVOID StartContext)
FILE_SYNCHRONOUS_IO_ALERT);
} while (!NT_SUCCESS(Status));
+ /* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
+ Status = Win32kInitWin32Thread(PsGetCurrentThread());
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Win32K: Failed making mouse thread a win32 thread.\n");
+ return; //(Status);
+ }
+
+ ptiMouse = PsGetCurrentThreadWin32Thread();
+ ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
+ DPRINT1("\nMouse Thread 0x%x \n", ptiMouse);
+
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
@@ -530,6 +544,10 @@ KeyboardThreadMain(PVOID StartContext)
return; //(Status);
}
+ ptiKeyboard = PsGetCurrentThreadWin32Thread();
+ ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
+ DPRINT1("\nKeyboard Thread 0x%x \n", ptiKeyboard);
+
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
@@ -890,8 +908,8 @@ RawInputThreadMain(PVOID StartContext)
}
ptiRawInput = PsGetCurrentThreadWin32Thread();
- DPRINT("\nRaw Input Thread 0x%x \n", ptiRawInput);
-
+ ptiRawInput->TIF_flags |= TIF_SYSTEMTHREAD;
+ DPRINT1("\nRaw Input Thread 0x%x \n", ptiRawInput);
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
@@ -922,7 +940,9 @@ RawInputThreadMain(PVOID StartContext)
DPRINT1("Raw Input Thread Exit!\n");
}
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitInputImpl(VOID)
{
NTSTATUS Status;
@@ -992,16 +1012,6 @@ CleanupInputImp(VOID)
return(STATUS_SUCCESS);
}
-BOOL
-APIENTRY
-NtUserDragDetect(
- HWND hWnd,
- POINT pt) // Just like the User call.
-{
- UNIMPLEMENTED
- return 0;
-}
-
BOOL FASTCALL
IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt)
{
@@ -1136,7 +1146,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[0][SwapButtons];
CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
{
@@ -1144,7 +1154,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[1][SwapButtons];
CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
{
@@ -1152,7 +1162,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = WM_MBUTTONDOWN;
CurInfo->ButtonsDown |= MK_MBUTTON;
Msg.wParam |= CurInfo->ButtonsDown;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
{
@@ -1160,7 +1170,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = WM_MBUTTONUP;
CurInfo->ButtonsDown &= ~MK_MBUTTON;
Msg.wParam |= CurInfo->ButtonsDown;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
{
@@ -1168,7 +1178,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[0][!SwapButtons];
CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
{
@@ -1176,7 +1186,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[1][!SwapButtons];
CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) &&
@@ -1194,14 +1204,14 @@ IntMouseInput(MOUSEINPUT *mi)
gQueueKeyStateTable[VK_XBUTTON1] |= 0xc0;
CurInfo->ButtonsDown |= MK_XBUTTON1;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
if(mi->mouseData & XBUTTON2)
{
gQueueKeyStateTable[VK_XBUTTON2] |= 0xc0;
CurInfo->ButtonsDown |= MK_XBUTTON2;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
}
else if(mi->dwFlags & MOUSEEVENTF_XUP)
@@ -1212,21 +1222,21 @@ IntMouseInput(MOUSEINPUT *mi)
gQueueKeyStateTable[VK_XBUTTON1] &= ~0x80;
CurInfo->ButtonsDown &= ~MK_XBUTTON1;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
if(mi->mouseData & XBUTTON2)
{
gQueueKeyStateTable[VK_XBUTTON2] &= ~0x80;
CurInfo->ButtonsDown &= ~MK_XBUTTON2;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
}
if(mi->dwFlags & MOUSEEVENTF_WHEEL)
{
Msg.message = WM_MOUSEWHEEL;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData);
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
return TRUE;
@@ -1347,7 +1357,7 @@ IntKeyboardInput(KEYBDINPUT *ki)
KbdHookData.dwExtraInfo = ki->dwExtraInfo;
if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
{
- DPRINT("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
+ DPRINT1("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
Msg.message, vk_hook, Msg.lParam);
if (Entered) UserLeave();
return FALSE;
diff --git a/subsystems/win32/win32k/ntuser/kbdlayout.c b/subsystems/win32/win32k/ntuser/kbdlayout.c
index 5d04cd81902..a6ac6e68bfb 100644
--- a/subsystems/win32/win32k/ntuser/kbdlayout.c
+++ b/subsystems/win32/win32k/ntuser/kbdlayout.c
@@ -163,10 +163,7 @@ static BOOL UserLoadKbdDll(WCHAR *wsKLID,
DPRINT("Loaded %wZ\n", &FullLayoutPath);
RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
- LdrGetProcedureAddress((*(PDRIVERS*)phModule)->BaseAddress,
- &kbdProcedureName,
- 0,
- (PVOID*)&layerDescGetFn);
+ layerDescGetFn = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor");
if(layerDescGetFn)
{
diff --git a/subsystems/win32/win32k/ntuser/keyboard.c b/subsystems/win32/win32k/ntuser/keyboard.c
index 62b2d7d9042..49a65450be5 100644
--- a/subsystems/win32/win32k/ntuser/keyboard.c
+++ b/subsystems/win32/win32k/ntuser/keyboard.c
@@ -58,7 +58,10 @@ BYTE gQueueKeyStateTable[256];
/* FUNCTIONS *****************************************************************/
/* Initialization -- Right now, just zero the key state and init the lock */
-NTSTATUS FASTCALL InitKeyboardImpl(VOID)
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitKeyboardImpl(VOID)
{
RtlZeroMemory(&gQueueKeyStateTable,0x100);
return STATUS_SUCCESS;
@@ -941,6 +944,12 @@ W32kKeyProcessMessage(LPMSG Msg,
VscVkTable = KeyboardLayout->pVSCtoVK_E1;
}
+ if (!VscVkTable)
+ {
+ DPRINT1("somethings wrong, Prefix=0x%x", Prefix);
+ return;
+ }
+
RawVk = 0xff;
while (VscVkTable->Vsc)
{
diff --git a/subsystems/win32/win32k/ntuser/menu.c b/subsystems/win32/win32k/ntuser/menu.c
index 06618296b49..08700461f6f 100644
--- a/subsystems/win32/win32k/ntuser/menu.c
+++ b/subsystems/win32/win32k/ntuser/menu.c
@@ -86,7 +86,9 @@ UserMenuInfo(
( ((r).bottom >= y)) && \
( ((r).top <= y)) )
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitMenuImpl(VOID)
{
return(STATUS_SUCCESS);
@@ -1711,17 +1713,6 @@ CLEANUP:
END_CLEANUP;
}
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserEndMenu(VOID)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
/*
* @implemented
*/
@@ -2453,25 +2444,6 @@ CLEANUP:
END_CLEANUP;
}
-/*
- * @implemented
- */
-/* NOTE: unused function */
-BOOL APIENTRY
-NtUserTrackPopupMenuEx(
- HMENU hMenu,
- UINT fuFlags,
- int x,
- int y,
- HWND hWnd,
- LPTPMPARAMS lptpm)
-{
- UNIMPLEMENTED
-
- return FALSE;
-}
-
-
////// ReactOS NtUserBad
/*
* @implemented
diff --git a/subsystems/win32/win32k/ntuser/message.c b/subsystems/win32/win32k/ntuser/message.c
index 403e02b84ce..01dcb73a982 100644
--- a/subsystems/win32/win32k/ntuser/message.c
+++ b/subsystems/win32/win32k/ntuser/message.c
@@ -1,12 +1,12 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * PURPOSE: Messages
- * FILE: subsys/win32k/ntuser/message.c
- * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISION HISTORY:
- * 06-06-2001 CSH Created
- */
+* COPYRIGHT: See COPYING in the top level directory
+* PROJECT: ReactOS kernel
+* PURPOSE: Messages
+* FILE: subsys/win32k/ntuser/message.c
+* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+* REVISION HISTORY:
+* 06-06-2001 CSH Created
+*/
/* INCLUDES ******************************************************************/
@@ -15,13 +15,15 @@
#define NDEBUG
#include
+BOOLEAN NTAPI PsGetProcessExitProcessCalled(PEPROCESS Process);
+
#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
typedef struct
{
- UINT uFlags;
- UINT uTimeout;
- ULONG_PTR Result;
+ UINT uFlags;
+ UINT uTimeout;
+ ULONG_PTR Result;
}
DOSENDMESSAGE, *PDOSENDMESSAGE;
@@ -30,13 +32,13 @@ DOSENDMESSAGE, *PDOSENDMESSAGE;
NTSTATUS FASTCALL
IntInitMessageImpl(VOID)
{
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
NTSTATUS FASTCALL
IntCleanupMessageImpl(VOID)
{
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
#define MMS_SIZE_WPARAM -1
@@ -48,1003 +50,657 @@ IntCleanupMessageImpl(VOID)
#define MMS_FLAG_READWRITE (MMS_FLAG_READ | MMS_FLAG_WRITE)
typedef struct tagMSGMEMORY
{
- UINT Message;
- UINT Size;
- INT Flags;
+ UINT Message;
+ UINT Size;
+ INT Flags;
}
MSGMEMORY, *PMSGMEMORY;
static MSGMEMORY MsgMemory[] =
- {
- { WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
- { WM_DDE_ACK, sizeof(KMDDELPARAM), MMS_FLAG_READ },
- { WM_DDE_EXECUTE, MMS_SIZE_WPARAM, MMS_FLAG_READ },
- { WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
- { WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
- { WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
- { WM_NCCREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
- { WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
- { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
- { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
- { WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
- { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
- { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
- };
+{
+ { WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
+ { WM_DDE_ACK, sizeof(KMDDELPARAM), MMS_FLAG_READ },
+ { WM_DDE_EXECUTE, MMS_SIZE_WPARAM, MMS_FLAG_READ },
+ { WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
+ { WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
+ { WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
+ { WM_NCCREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
+ { WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
+ { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
+ { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
+ { WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
+ { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
+ { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
+};
static PMSGMEMORY FASTCALL
FindMsgMemory(UINT Msg)
{
- PMSGMEMORY MsgMemoryEntry;
+ PMSGMEMORY MsgMemoryEntry;
- /* See if this message type is present in the table */
- for (MsgMemoryEntry = MsgMemory;
- MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
- MsgMemoryEntry++)
- {
- if (Msg == MsgMemoryEntry->Message)
- {
- return MsgMemoryEntry;
- }
- }
+ /* See if this message type is present in the table */
+ for (MsgMemoryEntry = MsgMemory;
+ MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
+ MsgMemoryEntry++)
+ {
+ if (Msg == MsgMemoryEntry->Message)
+ {
+ return MsgMemoryEntry;
+ }
+ }
- return NULL;
+ return NULL;
}
static UINT FASTCALL
MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
{
- CREATESTRUCTW *Cs;
- PUNICODE_STRING WindowName;
- PUNICODE_STRING ClassName;
- UINT Size = 0;
+ CREATESTRUCTW *Cs;
+ PUNICODE_STRING WindowName;
+ PUNICODE_STRING ClassName;
+ UINT Size = 0;
- _SEH2_TRY
- {
- if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
- {
- Size = (UINT)wParam;
- }
- else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
- {
- Size = (UINT) (wParam * sizeof(WCHAR));
- }
- else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
- {
- Size = (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
- }
- else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
- {
- switch(MsgMemoryEntry->Message)
- {
+ _SEH2_TRY
+ {
+ if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
+ {
+ Size = (UINT)wParam;
+ }
+ else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
+ {
+ Size = (UINT) (wParam * sizeof(WCHAR));
+ }
+ else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
+ {
+ Size = (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
+ }
+ else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
+ {
+ switch(MsgMemoryEntry->Message)
+ {
case WM_CREATE:
case WM_NCCREATE:
- Cs = (CREATESTRUCTW *) lParam;
- WindowName = (PUNICODE_STRING) Cs->lpszName;
- ClassName = (PUNICODE_STRING) Cs->lpszClass;
- Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
- if (IS_ATOM(ClassName->Buffer))
- {
- Size += sizeof(WCHAR) + sizeof(ATOM);
- }
- else
- {
- Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
- }
- break;
+ Cs = (CREATESTRUCTW *) lParam;
+ WindowName = (PUNICODE_STRING) Cs->lpszName;
+ ClassName = (PUNICODE_STRING) Cs->lpszClass;
+ Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
+ if (IS_ATOM(ClassName->Buffer))
+ {
+ Size += sizeof(WCHAR) + sizeof(ATOM);
+ }
+ else
+ {
+ Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
+ }
+ break;
case WM_NCCALCSIZE:
- Size = wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
- break;
+ Size = wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
+ break;
case WM_COPYDATA:
- Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
- break;
+ Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
+ break;
case WM_COPYGLOBALDATA:
- Size = wParam;
- break;
+ Size = wParam;
+ break;
default:
- ASSERT(FALSE);
- Size = 0;
- break;
- }
- }
- else
- {
- Size = MsgMemoryEntry->Size;
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH2_GetExceptionCode());
- Size = 0;
- }
- _SEH2_END;
- return Size;
+ ASSERT(FALSE);
+ Size = 0;
+ break;
+ }
+ }
+ else
+ {
+ Size = MsgMemoryEntry->Size;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH2_GetExceptionCode());
+ Size = 0;
+ }
+ _SEH2_END;
+ return Size;
}
static NTSTATUS
PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolNeeded)
{
- NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
- NCCALCSIZE_PARAMS *PackedNcCalcsize;
- CREATESTRUCTW *UnpackedCs;
- CREATESTRUCTW *PackedCs;
- PLARGE_STRING WindowName;
- PUNICODE_STRING ClassName;
- POOL_TYPE PoolType;
- UINT Size;
- PCHAR CsData;
+ NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
+ NCCALCSIZE_PARAMS *PackedNcCalcsize;
+ CREATESTRUCTW *UnpackedCs;
+ CREATESTRUCTW *PackedCs;
+ PLARGE_STRING WindowName;
+ PUNICODE_STRING ClassName;
+ POOL_TYPE PoolType;
+ UINT Size;
+ PCHAR CsData;
- *lParamPacked = lParam;
+ *lParamPacked = lParam;
if (NonPagedPoolNeeded)
- PoolType = NonPagedPool;
+ PoolType = NonPagedPool;
else
- PoolType = PagedPool;
+ PoolType = PagedPool;
- if (WM_NCCALCSIZE == Msg && wParam)
- {
+ if (WM_NCCALCSIZE == Msg && wParam)
+ {
- UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
- PackedNcCalcsize = ExAllocatePoolWithTag(PoolType,
- sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
- TAG_MSG);
+ UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
+ PackedNcCalcsize = ExAllocatePoolWithTag(PoolType,
+ sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
+ TAG_MSG);
- if (NULL == PackedNcCalcsize)
- {
- DPRINT1("Not enough memory to pack lParam\n");
- return STATUS_NO_MEMORY;
- }
- RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
- PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
- RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
- *lParamPacked = (LPARAM) PackedNcCalcsize;
- }
- else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
- {
- UnpackedCs = (CREATESTRUCTW *) lParam;
- WindowName = (PLARGE_STRING) UnpackedCs->lpszName;
- ClassName = (PUNICODE_STRING) UnpackedCs->lpszClass;
- Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
- if (IS_ATOM(ClassName->Buffer))
- {
- Size += sizeof(WCHAR) + sizeof(ATOM);
- }
- else
- {
- Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
- }
- PackedCs = ExAllocatePoolWithTag(PoolType, Size, TAG_MSG);
- if (NULL == PackedCs)
- {
- DPRINT1("Not enough memory to pack lParam\n");
- return STATUS_NO_MEMORY;
- }
- RtlCopyMemory(PackedCs, UnpackedCs, sizeof(CREATESTRUCTW));
- CsData = (PCHAR) (PackedCs + 1);
- PackedCs->lpszName = (LPCWSTR) (CsData - (PCHAR) PackedCs);
- RtlCopyMemory(CsData, WindowName->Buffer, WindowName->Length);
- CsData += WindowName->Length;
- *((WCHAR *) CsData) = L'\0';
- CsData += sizeof(WCHAR);
- PackedCs->lpszClass = (LPCWSTR) (CsData - (PCHAR) PackedCs);
- if (IS_ATOM(ClassName->Buffer))
- {
- *((WCHAR *) CsData) = L'A';
- CsData += sizeof(WCHAR);
- *((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer;
- CsData += sizeof(ATOM);
- }
- else
- {
- *((WCHAR *) CsData) = L'S';
- CsData += sizeof(WCHAR);
- RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length);
- CsData += ClassName->Length;
- *((WCHAR *) CsData) = L'\0';
- CsData += sizeof(WCHAR);
- }
- ASSERT(CsData == (PCHAR) PackedCs + Size);
- *lParamPacked = (LPARAM) PackedCs;
- }
+ if (NULL == PackedNcCalcsize)
+ {
+ DPRINT1("Not enough memory to pack lParam\n");
+ return STATUS_NO_MEMORY;
+ }
+ RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
+ PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
+ RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
+ *lParamPacked = (LPARAM) PackedNcCalcsize;
+ }
+ else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
+ {
+ UnpackedCs = (CREATESTRUCTW *) lParam;
+ WindowName = (PLARGE_STRING) UnpackedCs->lpszName;
+ ClassName = (PUNICODE_STRING) UnpackedCs->lpszClass;
+ Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
+ if (IS_ATOM(ClassName->Buffer))
+ {
+ Size += sizeof(WCHAR) + sizeof(ATOM);
+ }
+ else
+ {
+ Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
+ }
+ PackedCs = ExAllocatePoolWithTag(PoolType, Size, TAG_MSG);
+ if (NULL == PackedCs)
+ {
+ DPRINT1("Not enough memory to pack lParam\n");
+ return STATUS_NO_MEMORY;
+ }
+ RtlCopyMemory(PackedCs, UnpackedCs, sizeof(CREATESTRUCTW));
+ CsData = (PCHAR) (PackedCs + 1);
+ PackedCs->lpszName = (LPCWSTR) (CsData - (PCHAR) PackedCs);
+ RtlCopyMemory(CsData, WindowName->Buffer, WindowName->Length);
+ CsData += WindowName->Length;
+ *((WCHAR *) CsData) = L'\0';
+ CsData += sizeof(WCHAR);
+ PackedCs->lpszClass = (LPCWSTR) (CsData - (PCHAR) PackedCs);
+ if (IS_ATOM(ClassName->Buffer))
+ {
+ *((WCHAR *) CsData) = L'A';
+ CsData += sizeof(WCHAR);
+ *((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer;
+ CsData += sizeof(ATOM);
+ }
+ else
+ {
+ *((WCHAR *) CsData) = L'S';
+ CsData += sizeof(WCHAR);
+ RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length);
+ CsData += ClassName->Length;
+ *((WCHAR *) CsData) = L'\0';
+ CsData += sizeof(WCHAR);
+ }
+ ASSERT(CsData == (PCHAR) PackedCs + Size);
+ *lParamPacked = (LPARAM) PackedCs;
+ }
- else if (PoolType == NonPagedPool)
- {
- PMSGMEMORY MsgMemoryEntry;
- PVOID PackedData;
+ else if (PoolType == NonPagedPool)
+ {
+ PMSGMEMORY MsgMemoryEntry;
+ PVOID PackedData;
- MsgMemoryEntry = FindMsgMemory(Msg);
+ MsgMemoryEntry = FindMsgMemory(Msg);
- if ((!MsgMemoryEntry) || (MsgMemoryEntry->Size < 0))
- {
- /* Keep previous behavior */
- return STATUS_SUCCESS;
- }
- PackedData = ExAllocatePoolWithTag(NonPagedPool, MsgMemorySize(MsgMemoryEntry, wParam, lParam), TAG_MSG);
- RtlCopyMemory(PackedData, (PVOID)lParam, MsgMemorySize(MsgMemoryEntry, wParam, lParam));
- *lParamPacked = (LPARAM)PackedData;
- }
+ if ((!MsgMemoryEntry) || (MsgMemoryEntry->Size < 0))
+ {
+ /* Keep previous behavior */
+ return STATUS_SUCCESS;
+ }
+ PackedData = ExAllocatePoolWithTag(NonPagedPool, MsgMemorySize(MsgMemoryEntry, wParam, lParam), TAG_MSG);
+ RtlCopyMemory(PackedData, (PVOID)lParam, MsgMemorySize(MsgMemoryEntry, wParam, lParam));
+ *lParamPacked = (LPARAM)PackedData;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
static NTSTATUS
UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolUsed)
{
- NCCALCSIZE_PARAMS *UnpackedParams;
- NCCALCSIZE_PARAMS *PackedParams;
- PWINDOWPOS UnpackedWindowPos;
+ NCCALCSIZE_PARAMS *UnpackedParams;
+ NCCALCSIZE_PARAMS *PackedParams;
+ PWINDOWPOS UnpackedWindowPos;
- if (lParamPacked == lParam)
- {
- return STATUS_SUCCESS;
- }
+ if (lParamPacked == lParam)
+ {
+ return STATUS_SUCCESS;
+ }
- if (WM_NCCALCSIZE == Msg && wParam)
- {
- PackedParams = (NCCALCSIZE_PARAMS *) lParamPacked;
- UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
- UnpackedWindowPos = UnpackedParams->lppos;
- RtlCopyMemory(UnpackedParams, PackedParams, sizeof(NCCALCSIZE_PARAMS));
- UnpackedParams->lppos = UnpackedWindowPos;
- RtlCopyMemory(UnpackedWindowPos, PackedParams + 1, sizeof(WINDOWPOS));
- ExFreePool((PVOID) lParamPacked);
+ if (WM_NCCALCSIZE == Msg && wParam)
+ {
+ PackedParams = (NCCALCSIZE_PARAMS *) lParamPacked;
+ UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
+ UnpackedWindowPos = UnpackedParams->lppos;
+ RtlCopyMemory(UnpackedParams, PackedParams, sizeof(NCCALCSIZE_PARAMS));
+ UnpackedParams->lppos = UnpackedWindowPos;
+ RtlCopyMemory(UnpackedWindowPos, PackedParams + 1, sizeof(WINDOWPOS));
+ ExFreePool((PVOID) lParamPacked);
- return STATUS_SUCCESS;
- }
- else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
- {
- ExFreePool((PVOID) lParamPacked);
+ return STATUS_SUCCESS;
+ }
+ else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
+ {
+ ExFreePool((PVOID) lParamPacked);
- return STATUS_SUCCESS;
- }
- else if (NonPagedPoolUsed)
- {
- PMSGMEMORY MsgMemoryEntry;
- MsgMemoryEntry = FindMsgMemory(Msg);
- if (MsgMemoryEntry->Size < 0)
- {
- /* Keep previous behavior */
- return STATUS_INVALID_PARAMETER;
- }
-
- if (MsgMemory->Flags == MMS_FLAG_READWRITE)
- {
- //RtlCopyMemory((PVOID)lParam, (PVOID)lParamPacked, MsgMemory->Size);
- }
- ExFreePool((PVOID) lParamPacked);
- return STATUS_SUCCESS;
- }
-
- ASSERT(FALSE);
-
- return STATUS_INVALID_PARAMETER;
-}
-
-static
-VOID
-FASTCALL
-IntCallWndProc
-( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
- BOOL SameThread = FALSE;
- CWPSTRUCT CWP;
-
- if (Window->head.pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
- SameThread = TRUE;
-
- CWP.hwnd = hWnd;
- CWP.message = Msg;
- CWP.wParam = wParam;
- CWP.lParam = lParam;
- co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
-}
-
-static
-VOID
-FASTCALL
-IntCallWndProcRet
-( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *uResult)
-{
- BOOL SameThread = FALSE;
- CWPRETSTRUCT CWPR;
-
- if (Window->head.pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
- SameThread = TRUE;
-
- CWPR.hwnd = hWnd;
- CWPR.message = Msg;
- CWPR.wParam = wParam;
- CWPR.lParam = lParam;
- CWPR.lResult = *uResult;
- co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
-}
-
-LRESULT
-FASTCALL
-IntDispatchMessage(PMSG pMsg)
-{
- LARGE_INTEGER TickCount;
- LONG Time;
- LRESULT retval;
- PMSGMEMORY MsgMemoryEntry;
- INT lParamBufferSize;
- LPARAM lParamPacked;
- PWND Window = NULL;
-
- if (pMsg->hwnd)
- {
- Window = UserGetWindowObject(pMsg->hwnd);
- if (!Window) return 0;
- }
-
- if (((pMsg->message == WM_SYSTIMER) ||
- (pMsg->message == WM_TIMER)) &&
- (pMsg->lParam) )
- {
- if (pMsg->message == WM_TIMER)
- {
- if (ValidateTimerCallback(PsGetCurrentThreadWin32Thread(),pMsg->lParam))
+ return STATUS_SUCCESS;
+ }
+ else if (NonPagedPoolUsed)
+ {
+ PMSGMEMORY MsgMemoryEntry;
+ MsgMemoryEntry = FindMsgMemory(Msg);
+ if (MsgMemoryEntry->Size < 0)
{
- KeQueryTickCount(&TickCount);
- Time = MsqCalculateMessageTime(&TickCount);
- return co_IntCallWindowProc((WNDPROC)pMsg->lParam,
- TRUE,
- pMsg->hwnd,
- WM_TIMER,
- pMsg->wParam,
- (LPARAM)Time,
- sizeof(LPARAM));
+ /* Keep previous behavior */
+ return STATUS_INVALID_PARAMETER;
}
- return 0;
- }
- else
- {
- PTIMER pTimer = FindSystemTimer(pMsg);
- if (pTimer && pTimer->pfn)
+
+ if (MsgMemory->Flags == MMS_FLAG_READWRITE)
{
- KeQueryTickCount(&TickCount);
- Time = MsqCalculateMessageTime(&TickCount);
- pTimer->pfn(pMsg->hwnd, WM_SYSTIMER, (UINT)pMsg->wParam, Time);
+ //RtlCopyMemory((PVOID)lParam, (PVOID)lParamPacked, MsgMemory->Size);
}
- return 0;
- }
- }
- // Need a window!
- if ( !Window ) return 0;
+ ExFreePool((PVOID) lParamPacked);
+ return STATUS_SUCCESS;
+ }
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(pMsg->message);
- if ( !MsgMemoryEntry )
- {
- lParamBufferSize = -1;
- }
- else
- {
- lParamBufferSize = MsgMemorySize(MsgMemoryEntry, pMsg->wParam, pMsg->lParam);
- }
+ ASSERT(FALSE);
- if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
- {
- DPRINT1("Failed to pack message parameters\n");
- return 0;
- }
+ return STATUS_INVALID_PARAMETER;
+}
- retval = co_IntCallWindowProc( Window->lpfnWndProc,
- !Window->Unicode,
- pMsg->hwnd,
- pMsg->message,
- pMsg->wParam,
- lParamPacked,
- lParamBufferSize);
+//
+// Wakeup any thread/process waiting on idle input.
+//
+VOID FASTCALL
+IdlePing(VOID)
+{
+ PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+ PUSER_MESSAGE_QUEUE ForegroundQueue;
+ PTHREADINFO pti, ptiForeground = NULL;
- if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
- {
- DPRINT1("Failed to unpack message parameters\n");
- }
+ ForegroundQueue = IntGetFocusMessageQueue();
- if (pMsg->message == WM_PAINT)
- {
- /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
- HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
- co_UserGetUpdateRgn( Window, hrgn, TRUE );
- REGION_FreeRgnByHandle( hrgn );
- }
- return retval;
+ if (ForegroundQueue)
+ ptiForeground = ForegroundQueue->Thread->Tcb.Win32Thread;
+
+ pti = PsGetCurrentThreadWin32Thread();
+
+ if ( pti && pti->pDeskInfo && pti == ptiForeground )
+ {
+ if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ||
+ pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) )
+ {
+ co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
+ }
+ }
+
+ DPRINT("IdlePing ppi 0x%x\n",ppi);
+ if ( ppi && ppi->InputIdleEvent )
+ {
+ DPRINT("InputIdleEvent\n");
+ KeSetEvent( ppi->InputIdleEvent, IO_NO_INCREMENT, FALSE);
+ }
}
VOID FASTCALL
-co_IntSendHitTestMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
+IdlePong(VOID)
{
- if(!Msg->hwnd || ThreadQueue->CaptureWindow)
+ PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+
+ DPRINT("IdlePong ppi 0x%x\n",ppi);
+ if ( ppi && ppi->InputIdleEvent )
{
- return;
- }
-
- switch(Msg->message)
- {
- case WM_MOUSEMOVE:
- {
- co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
- break;
- }
- case WM_NCMOUSEMOVE:
- {
- co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
- break;
- }
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_XBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- case WM_MBUTTONDBLCLK:
- case WM_RBUTTONDBLCLK:
- case WM_XBUTTONDBLCLK:
- {
- WPARAM wParam;
- PSYSTEM_CURSORINFO CurInfo;
- CurInfo = IntGetSysCursorInfo();
-
- wParam = (WPARAM)(CurInfo->ButtonsDown);
-
- co_IntSendMessage(Msg->hwnd, WM_MOUSEMOVE, wParam, Msg->lParam);
- co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
- break;
- }
- case WM_NCLBUTTONDOWN:
- case WM_NCMBUTTONDOWN:
- case WM_NCRBUTTONDOWN:
- case WM_NCXBUTTONDOWN:
- case WM_NCLBUTTONDBLCLK:
- case WM_NCMBUTTONDBLCLK:
- case WM_NCRBUTTONDBLCLK:
- case WM_NCXBUTTONDBLCLK:
- {
- co_IntSendMessage(Msg->hwnd, WM_NCMOUSEMOVE, (WPARAM)Msg->wParam, Msg->lParam);
- co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
- break;
- }
+ KeClearEvent(ppi->InputIdleEvent);
}
}
-BOOL FASTCALL
-co_IntActivateWindowMouse(
- PUSER_MESSAGE_QUEUE ThreadQueue,
- LPMSG Msg,
- PWND MsgWindow,
- USHORT *HitTest)
+static VOID FASTCALL
+IntCallWndProc( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
- ULONG Result;
- PWND Parent;
+ BOOL SameThread = FALSE;
+ CWPSTRUCT CWP;
- ASSERT_REFS_CO(MsgWindow);
+ if (Window->head.pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
+ SameThread = TRUE;
- if(*HitTest == (USHORT)HTTRANSPARENT)
- {
- /* eat the message, search again! */
- return TRUE;
- }
-
- Parent = IntGetParent(MsgWindow);//fixme: deref retval?
-
- /* If no parent window, pass MsgWindows HWND as wParam. Fixes bug #3111 */
- Result = co_IntSendMessage(MsgWindow->head.h,
- WM_MOUSEACTIVATE,
- (WPARAM) (Parent ? Parent->head.h : MsgWindow->head.h),
- (LPARAM)MAKELONG(*HitTest, Msg->message)
- );
-
- switch (Result)
- {
- case MA_NOACTIVATEANDEAT:
- return TRUE;
- case MA_NOACTIVATE:
- break;
- case MA_ACTIVATEANDEAT:
- co_IntMouseActivateWindow(MsgWindow);
- return TRUE;
- default:
- /* MA_ACTIVATE */
- co_IntMouseActivateWindow(MsgWindow);
- break;
- }
-
- return FALSE;
+ CWP.hwnd = hWnd;
+ CWP.message = Msg;
+ CWP.wParam = wParam;
+ CWP.lParam = lParam;
+ co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
}
-BOOL FASTCALL
-co_IntTranslateMouseMessage(
- PUSER_MESSAGE_QUEUE ThreadQueue,
- LPMSG Msg,
- USHORT *HitTest,
- BOOL Remove)
+static VOID FASTCALL
+IntCallWndProcRet ( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *uResult)
{
- PWND Window;
- USER_REFERENCE_ENTRY Ref, DesktopRef;
+ BOOL SameThread = FALSE;
+ CWPRETSTRUCT CWPR;
- if(!(Window = UserGetWindowObject(Msg->hwnd)))
- {
- /* let's just eat the message?! */
- return TRUE;
- }
+ if (Window->head.pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
+ SameThread = TRUE;
- *HitTest = HTCLIENT;
-
- UserRefObjectCo(Window, &Ref);
-
- if ( ThreadQueue == Window->head.pti->MessageQueue &&
- ThreadQueue->CaptureWindow != Window->head.h)
- {
- /* only send WM_NCHITTEST messages if we're not capturing the window! */
- if (Remove )
- {
- *HitTest = co_IntSendMessage(Window->head.h, WM_NCHITTEST, 0,
- MAKELONG(Msg->pt.x, Msg->pt.y));
- }
- /* else we are going to see this message again, but then with Remove == TRUE */
-
- if (*HitTest == (USHORT)HTTRANSPARENT)
- {
- PWND DesktopWindow;
- HWND hDesktop = IntGetDesktopWindow();
-
- if ((DesktopWindow = UserGetWindowObject(hDesktop)))
- {
- PWND Wnd;
-
- UserRefObjectCo(DesktopWindow, &DesktopRef);
-
- co_WinPosWindowFromPoint(DesktopWindow, Window->head.pti->MessageQueue, &Msg->pt, &Wnd);
- if (Wnd)
- {
- if (Wnd != Window)
- {
- /* post the message to the other window */
- Msg->hwnd = Wnd->head.h;
- if(!(Wnd->state & WNDS_DESTROYED))
- {
- MsqPostMessage(Wnd->head.pti->MessageQueue, Msg, FALSE,
- Msg->message == WM_MOUSEMOVE ? QS_MOUSEMOVE :
- QS_MOUSEBUTTON);
- }
-
- /* eat the message */
- UserDereferenceObject(Wnd);
- UserDerefObjectCo(DesktopWindow);
- UserDerefObjectCo(Window);
- return TRUE;
- }
- UserDereferenceObject(Wnd);
- }
-
- UserDerefObjectCo(DesktopWindow);
- }
- }
- }
-
- if ( gspv.bMouseClickLock &&
- ( (Msg->message == WM_LBUTTONUP) ||
- (Msg->message == WM_LBUTTONDOWN) ) )
- {
- if (MsqIsClkLck(Msg, Remove))
- {
- // FIXME: drop the message, hack: use WM_NULL
- Msg->message = WM_NULL;
- }
- }
-
- if (IS_BTN_MESSAGE(Msg->message, DOWN))
- {
- /* generate double click messages, if necessary */
- if ((((*HitTest) != HTCLIENT) ||
- (Window->pcls->style & CS_DBLCLKS)) &&
- MsqIsDblClk(Msg, Remove))
- {
- Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
- }
- }
-
- if(Msg->message != WM_MOUSEWHEEL)
- {
-
- if ((*HitTest) != HTCLIENT)
- {
- Msg->message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
- if ( (Msg->message == WM_NCRBUTTONUP) &&
- (((*HitTest) == HTCAPTION) || ((*HitTest) == HTSYSMENU)) )
- {
- Msg->message = WM_CONTEXTMENU;
- Msg->wParam = (WPARAM)Window->head.h;
- }
- else
- {
- Msg->wParam = *HitTest;
- }
- Msg->lParam = MAKELONG(Msg->pt.x, Msg->pt.y);
- }
- else if ( ThreadQueue->MoveSize == NULL &&
- ThreadQueue->MenuOwner == NULL )
- {
- /* NOTE: Msg->pt should remain in screen coordinates. -- FiN */
- Msg->lParam = MAKELONG(
- Msg->pt.x - (WORD)Window->rcClient.left,
- Msg->pt.y - (WORD)Window->rcClient.top);
- }
- }
-
- UserDerefObjectCo(Window);
- return FALSE;
+ CWPR.hwnd = hWnd;
+ CWPR.message = Msg;
+ CWPR.wParam = wParam;
+ CWPR.lParam = lParam;
+ CWPR.lResult = *uResult;
+ co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
}
-BOOL ProcessMouseMessage(MSG* Msg, BOOLEAN RemoveMessages)
+LRESULT FASTCALL
+IntDispatchMessage(PMSG pMsg)
{
- MOUSEHOOKSTRUCT MHook;
- EVENTMSG Event;
+ LARGE_INTEGER TickCount;
+ LONG Time;
+ LRESULT retval = 0;
+ PMSGMEMORY MsgMemoryEntry;
+ INT lParamBufferSize;
PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE ThreadQueue;
- USER_REFERENCE_ENTRY Ref;
- USHORT HitTest = HTNOWHERE;
+ LPARAM lParamPacked;
+ PWND Window = NULL;
+
+ if (pMsg->hwnd)
+ {
+ Window = UserGetWindowObject(pMsg->hwnd);
+ if (!Window) return 0;
+ }
pti = PsGetCurrentThreadWin32Thread();
- ThreadQueue = pti->MessageQueue;
- if(RemoveMessages)
- {
- PWND MsgWindow = NULL;
-
- /* Mouse message process */
-
- if( Msg->hwnd &&
- ( MsgWindow = UserGetWindowObject(Msg->hwnd) ) &&
- Msg->message >= WM_MOUSEFIRST &&
- Msg->message <= WM_MOUSELAST )
- {
- USHORT HitTest;
-
- UserRefObjectCo(MsgWindow, &Ref);
-
- if ( co_IntTranslateMouseMessage( ThreadQueue,
- Msg,
- &HitTest,
- TRUE))
- /* FIXME - check message filter again, if the message doesn't match anymore,
- search again */
- {
- UserDerefObjectCo(MsgWindow);
- /* eat the message, search again */
- return FALSE;
- }
-
- if(ThreadQueue->CaptureWindow == NULL)
- {
- co_IntSendHitTestMessages(ThreadQueue, Msg);
-
- if ( ( Msg->message != WM_MOUSEMOVE &&
- Msg->message != WM_NCMOUSEMOVE ) &&
- IS_BTN_MESSAGE(Msg->message, DOWN) &&
- co_IntActivateWindowMouse(ThreadQueue, Msg, MsgWindow, &HitTest) )
- {
- UserDerefObjectCo(MsgWindow);
- /* eat the message, search again */
- return FALSE;
- }
- }
-
- UserDerefObjectCo(MsgWindow);
- }
- else
- {
- co_IntSendHitTestMessages(ThreadQueue, Msg);
- }
-
- return TRUE;
- }
-
- if ( ( Msg->hwnd &&
- Msg->message >= WM_MOUSEFIRST &&
- Msg->message <= WM_MOUSELAST ) &&
- co_IntTranslateMouseMessage( ThreadQueue,
- Msg,
- &HitTest,
- FALSE) )
- /* FIXME - check message filter again, if the message doesn't match anymore,
- search again */
- {
- /* eat the message, search again */
- return FALSE;
- }
-
- pti->rpdesk->htEx = HitTest; /* Now set the capture hit. */
-
- Event.message = Msg->message;
- Event.time = Msg->time;
- Event.hwnd = Msg->hwnd;
- Event.paramL = Msg->pt.x;
- Event.paramH = Msg->pt.y;
- co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
-
-
- MHook.pt = Msg->pt;
- MHook.hwnd = Msg->hwnd;
- MHook.wHitTestCode = HitTest;
- MHook.dwExtraInfo = 0;
- if (co_HOOK_CallHooks( WH_MOUSE,
- RemoveMessages ? HC_ACTION : HC_NOREMOVE,
- Msg->message,
- (LPARAM)&MHook ))
+ if (((pMsg->message == WM_SYSTIMER) ||
+ (pMsg->message == WM_TIMER)) &&
+ (pMsg->lParam) )
{
- MHook.pt = Msg->pt;
- MHook.hwnd = Msg->hwnd;
- MHook.wHitTestCode = HitTest;
- MHook.dwExtraInfo = 0;
- co_HOOK_CallHooks( WH_CBT,
- HCBT_CLICKSKIPPED,
- Msg->message,
- (LPARAM)&MHook);
- return FALSE;
- }
-
- return TRUE;
-}
-
-BOOL ProcessKeyboardMessage(MSG* Msg, BOOLEAN RemoveMessages)
-{
- EVENTMSG Event;
-
- Event.message = Msg->message;
- Event.hwnd = Msg->hwnd;
- Event.time = Msg->time;
- Event.paramL = (Msg->wParam & 0xFF) | (HIWORD(Msg->lParam) << 8);
- Event.paramH = Msg->lParam & 0x7FFF;
- if (HIWORD(Msg->lParam) & 0x0100) Event.paramH |= 0x8000;
- co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
-
- if (co_HOOK_CallHooks( WH_KEYBOARD,
- RemoveMessages ? HC_ACTION : HC_NOREMOVE,
- LOWORD(Msg->wParam),
- Msg->lParam))
- {
- /* skip this message */
- co_HOOK_CallHooks( WH_CBT,
- HCBT_KEYSKIPPED,
- LOWORD(Msg->wParam),
- Msg->lParam );
- return FALSE;
- }
- return TRUE;
-}
-
-BOOL ProcessHardwareMessage(MSG* Msg, BOOLEAN RemoveMessages)
-{
- if ( IS_MOUSE_MESSAGE(Msg->message))
- {
- if (!ProcessMouseMessage(Msg, RemoveMessages))
+ if (pMsg->message == WM_TIMER)
{
- return FALSE;
+ ObReferenceObject(pti->pEThread);
+ if (ValidateTimerCallback(pti,pMsg->lParam))
+ {
+ KeQueryTickCount(&TickCount);
+ Time = MsqCalculateMessageTime(&TickCount);
+ retval = co_IntCallWindowProc((WNDPROC)pMsg->lParam,
+ TRUE,
+ pMsg->hwnd,
+ WM_TIMER,
+ pMsg->wParam,
+ (LPARAM)Time,
+ sizeof(LPARAM));
+ }
+ ObDereferenceObject(pti->pEThread);
+ return retval;
+ }
+ else
+ {
+ PTIMER pTimer = FindSystemTimer(pMsg);
+ if (pTimer && pTimer->pfn)
+ {
+ KeQueryTickCount(&TickCount);
+ Time = MsqCalculateMessageTime(&TickCount);
+ pTimer->pfn(pMsg->hwnd, WM_SYSTIMER, (UINT)pMsg->wParam, Time);
+ }
+ return 0;
}
}
- else if ( IS_KBD_MESSAGE(Msg->message))
+ // Need a window!
+ if ( !Window ) return 0;
+
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(pMsg->message);
+ if ( !MsgMemoryEntry )
{
- if(!ProcessKeyboardMessage(Msg, RemoveMessages))
- {
- return FALSE;
- }
+ lParamBufferSize = -1;
+ }
+ else
+ {
+ lParamBufferSize = MsgMemorySize(MsgMemoryEntry, pMsg->wParam, pMsg->lParam);
}
- return TRUE;
+ if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
+ {
+ DPRINT1("Failed to pack message parameters\n");
+ return 0;
+ }
+ ObReferenceObject(pti->pEThread);
+ retval = co_IntCallWindowProc( Window->lpfnWndProc,
+ !Window->Unicode,
+ pMsg->hwnd,
+ pMsg->message,
+ pMsg->wParam,
+ lParamPacked,
+ lParamBufferSize);
+
+ if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
+ {
+ DPRINT1("Failed to unpack message parameters\n");
+ }
+
+ if (pMsg->message == WM_PAINT)
+ {
+ /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
+ HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
+ co_UserGetUpdateRgn( Window, hrgn, TRUE );
+ REGION_FreeRgnByHandle( hrgn );
+ }
+ ObDereferenceObject(pti->pEThread);
+ return retval;
}
+
/*
- * Internal version of PeekMessage() doing all the work
- */
+* Internal version of PeekMessage() doing all the work
+*/
BOOL FASTCALL
-co_IntPeekMessage( PUSER_MESSAGE Msg,
+co_IntPeekMessage( PMSG Msg,
PWND Window,
UINT MsgFilterMin,
UINT MsgFilterMax,
UINT RemoveMsg )
{
- PTHREADINFO pti;
- LARGE_INTEGER LargeTickCount;
- PUSER_MESSAGE_QUEUE ThreadQueue;
- PUSER_MESSAGE Message;
- BOOL RemoveMessages;
+ PTHREADINFO pti;
+ LARGE_INTEGER LargeTickCount;
+ PUSER_MESSAGE_QUEUE ThreadQueue;
+ BOOL RemoveMessages;
- pti = PsGetCurrentThreadWin32Thread();
- ThreadQueue = pti->MessageQueue;
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
- RemoveMessages = RemoveMsg & PM_REMOVE;
+ RemoveMessages = RemoveMsg & PM_REMOVE;
- do
- {
- KeQueryTickCount(&LargeTickCount);
- ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
+ IdlePong();
- /* Dispatch sent messages here. */
- while (co_MsqDispatchOneSentMessage(ThreadQueue))
- ;
+ do
+ {
+ KeQueryTickCount(&LargeTickCount);
+ ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
- /* Now look for a quit message. */
+ /* Dispatch sent messages here. */
+ while (co_MsqDispatchOneSentMessage(ThreadQueue)) ;
- if (ThreadQueue->QuitPosted)
- {
- /* According to the PSDK, WM_QUIT messages are always returned, regardless
- of the filter specified */
- Msg->Msg.hwnd = NULL;
- Msg->Msg.message = WM_QUIT;
- Msg->Msg.wParam = ThreadQueue->QuitExitCode;
- Msg->Msg.lParam = 0;
- if (RemoveMessages)
- {
- ThreadQueue->QuitPosted = FALSE;
- }
+ /* Now look for a quit message. */
- return TRUE;
- }
+ if (ThreadQueue->QuitPosted)
+ {
+ /* According to the PSDK, WM_QUIT messages are always returned, regardless
+ of the filter specified */
+ Msg->hwnd = NULL;
+ Msg->message = WM_QUIT;
+ Msg->wParam = ThreadQueue->QuitExitCode;
+ Msg->lParam = 0;
+ if (RemoveMessages)
+ {
+ ThreadQueue->QuitPosted = FALSE;
+ }
- /* Now check for normal messages. */
- if (co_MsqFindMessage( ThreadQueue,
- FALSE,
+ return TRUE;
+ }
+
+ /* Now check for normal messages. */
+ if (MsqPeekMessage( ThreadQueue,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ Msg ))
+ {
+ return TRUE;
+ }
+
+ /* Check for hardware events. */
+ if(co_MsqPeekMouseMove(ThreadQueue,
RemoveMessages,
Window,
MsgFilterMin,
MsgFilterMax,
- &Message ))
- {
- RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
- if (RemoveMessages)
- {
- MsqDestroyMessage(Message);
- }
- break;
- }
+ Msg ))
+ {
+ return TRUE;
+ }
- /* Check for hardware events. */
- if(co_MsqFindMessage( ThreadQueue,
- TRUE,
- RemoveMessages,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- &Message ))
- {
- RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
- if (RemoveMessages)
- {
- MsqDestroyMessage(Message);
- }
+ if(co_MsqPeekHardwareMessage(ThreadQueue,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ Msg))
+ {
+ return TRUE;
+ }
- if(!ProcessHardwareMessage(&Msg->Msg, RemoveMessages))
- continue;
+ /* Check for sent messages again. */
+ while (co_MsqDispatchOneSentMessage(ThreadQueue))
+ ;
- break;
- }
+ /* Check for paint messages. */
+ if( IntGetPaintMessage( Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ pti,
+ Msg,
+ RemoveMessages))
+ {
+ return TRUE;
+ }
- /* Check for sent messages again. */
- while (co_MsqDispatchOneSentMessage(ThreadQueue))
- ;
+ if (PostTimerMessages(Window))
+ {
+ continue;
+ }
- /* Check for paint messages. */
- if( IntGetPaintMessage( Window,
- MsgFilterMin,
- MsgFilterMax,
- pti,
- &Msg->Msg,
- RemoveMessages))
- {
- break;
- }
+ return FALSE;
+ }
+ while (TRUE);
- if (PostTimerMessages(Window))
- {
- continue;
- }
-
- return FALSE;
- }
- while (TRUE);
-
- // The WH_GETMESSAGE hook enables an application to monitor messages about to
- // be returned by the GetMessage or PeekMessage function.
-
- co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg);
- return TRUE;
+ return TRUE;
}
static NTSTATUS FASTCALL
CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
{
- NTSTATUS Status;
+ NTSTATUS Status;
- PVOID KernelMem;
- UINT Size;
+ PVOID KernelMem;
+ UINT Size;
- *KernelModeMsg = *UserModeMsg;
+ *KernelModeMsg = *UserModeMsg;
- /* See if this message type is present in the table */
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- return STATUS_SUCCESS;
- }
+ /* See if this message type is present in the table */
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ return STATUS_SUCCESS;
+ }
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
- if (0 != Size)
- {
- /* Allocate kernel mem */
- KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
- if (NULL == KernelMem)
- {
- DPRINT1("Not enough memory to copy message to kernel mem\n");
- return STATUS_NO_MEMORY;
- }
- KernelModeMsg->lParam = (LPARAM) KernelMem;
+ if (0 != Size)
+ {
+ /* Allocate kernel mem */
+ KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
+ if (NULL == KernelMem)
+ {
+ DPRINT1("Not enough memory to copy message to kernel mem\n");
+ return STATUS_NO_MEMORY;
+ }
+ KernelModeMsg->lParam = (LPARAM) KernelMem;
- /* Copy data if required */
- if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
- {
- Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
- ExFreePoolWithTag(KernelMem, TAG_MSG);
- return Status;
- }
- }
- else
- {
- /* Make sure we don't pass any secrets to usermode */
- RtlZeroMemory(KernelMem, Size);
- }
- }
- else
- {
- KernelModeMsg->lParam = 0;
- }
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
+ {
+ Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
+ ExFreePoolWithTag(KernelMem, TAG_MSG);
+ return Status;
+ }
+ }
+ else
+ {
+ /* Make sure we don't pass any secrets to usermode */
+ RtlZeroMemory(KernelMem, Size);
+ }
+ }
+ else
+ {
+ KernelModeMsg->lParam = 0;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
static NTSTATUS FASTCALL
CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
{
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
- UINT Size;
+ NTSTATUS Status;
+ PMSGMEMORY MsgMemoryEntry;
+ UINT Size;
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- return STATUS_SUCCESS;
- }
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ return STATUS_SUCCESS;
+ }
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
- if (0 != Size)
- {
- /* Copy data if required */
- if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
- {
- Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Failed to copy message from kernel: invalid usermode buffer\n");
- ExFreePool((PVOID) KernelModeMsg->lParam);
- return Status;
- }
- }
+ if (0 != Size)
+ {
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
+ {
+ Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to copy message from kernel: invalid usermode buffer\n");
+ ExFreePool((PVOID) KernelModeMsg->lParam);
+ return Status;
+ }
+ }
- ExFreePool((PVOID) KernelModeMsg->lParam);
- }
+ ExFreePool((PVOID) KernelModeMsg->lParam);
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
static BOOL FASTCALL
@@ -1052,40 +708,41 @@ co_IntWaitMessage( PWND Window,
UINT MsgFilterMin,
UINT MsgFilterMax )
{
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE ThreadQueue;
- NTSTATUS Status = STATUS_SUCCESS;
- USER_MESSAGE Msg;
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE ThreadQueue;
+ NTSTATUS Status = STATUS_SUCCESS;
+ MSG Msg;
- pti = PsGetCurrentThreadWin32Thread();
- ThreadQueue = pti->MessageQueue;
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
- do
- {
- if ( co_IntPeekMessage( &Msg,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- PM_NOREMOVE))
- {
- return TRUE;
- }
- /* Nothing found. Wait for new messages. */
- Status = co_MsqWaitForNewMessages( ThreadQueue,
- Window,
- MsgFilterMin,
- MsgFilterMax);
- }
- while ( (STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) ||
- STATUS_TIMEOUT == Status );
+ do
+ {
+ if ( co_IntPeekMessage( &Msg,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ PM_NOREMOVE))
+ {
+ return TRUE;
+ }
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- DPRINT1("Exit co_IntWaitMessage on error!\n");
- }
+ /* Nothing found. Wait for new messages. */
+ Status = co_MsqWaitForNewMessages( ThreadQueue,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax);
+ }
+ while ( (STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) ||
+ STATUS_TIMEOUT == Status );
- return FALSE;
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ DPRINT1("Exit co_IntWaitMessage on error!\n");
+ }
+
+ return FALSE;
}
BOOL FASTCALL
@@ -1096,72 +753,75 @@ co_IntGetPeekMessage( PMSG pMsg,
UINT RemoveMsg,
BOOL bGMSG )
{
- BOOL Present;
- PWND Window;
- USER_MESSAGE Msg;
+ PWND Window;
+ BOOL Present = FALSE;
- if ( hWnd == HWND_TOPMOST ||
- hWnd == HWND_BROADCAST )
- hWnd = HWND_BOTTOM;
+ if ( hWnd == HWND_TOPMOST || hWnd == HWND_BROADCAST )
+ hWnd = HWND_BOTTOM;
- /* Validate input */
- if (hWnd && hWnd != HWND_BOTTOM)
- {
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- if (bGMSG)
- return -1;
- else
- return FALSE;
- }
- }
- else
- {
- Window = (PWND)hWnd;
- }
+ /* Validate input */
+ if (hWnd && hWnd != HWND_BOTTOM)
+ {
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ if (bGMSG)
+ return -1;
+ else
+ return FALSE;
+ }
+ }
+ else
+ {
+ Window = (PWND)hWnd;
+ }
- if (MsgFilterMax < MsgFilterMin)
- {
- MsgFilterMin = 0;
- MsgFilterMax = 0;
- }
+ if (MsgFilterMax < MsgFilterMin)
+ {
+ MsgFilterMin = 0;
+ MsgFilterMax = 0;
+ }
- do
- {
- Present = co_IntPeekMessage( &Msg,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- RemoveMsg );
- if (Present)
- {
- RtlCopyMemory( pMsg, &Msg.Msg, sizeof(MSG));
+ do
+ {
+ Present = co_IntPeekMessage( pMsg,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ RemoveMsg );
+ if (Present)
+ {
+ // The WH_GETMESSAGE hook enables an application to monitor messages about to
+ // be returned by the GetMessage or PeekMessage function.
- if (bGMSG)
- return (WM_QUIT != pMsg->message);
- else
- return TRUE;
- }
+ co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)pMsg);
- if ( bGMSG && !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax) )
- {
- return -1;
- }
- else
- {
- if (!(RemoveMsg & PM_NOYIELD))
- {
- // Yield this thread!
- UserLeave();
- ZwYieldExecution();
- UserEnterExclusive();
- // Fall through to fail.
- }
- }
- }
- while( bGMSG && !Present );
+ if ( bGMSG )
+ return (WM_QUIT != pMsg->message);
+ }
- return FALSE;
+ if ( bGMSG )
+ {
+ if ( !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax) )
+ return -1;
+ }
+ else
+ {
+ if (!(RemoveMsg & PM_NOYIELD))
+ {
+ IdlePing();
+ // Yield this thread!
+ UserLeave();
+ ZwYieldExecution();
+ UserEnterExclusive();
+ // Fall through to exit.
+ IdlePong();
+ }
+ break;
+ }
+ }
+ while( bGMSG && !Present );
+
+ return Present;
}
BOOL FASTCALL
@@ -1170,50 +830,50 @@ UserPostThreadMessage( DWORD idThread,
WPARAM wParam,
LPARAM lParam )
{
- MSG Message;
- PETHREAD peThread;
- PTHREADINFO pThread;
- LARGE_INTEGER LargeTickCount;
- NTSTATUS Status;
+ MSG Message;
+ PETHREAD peThread;
+ PTHREADINFO pThread;
+ LARGE_INTEGER LargeTickCount;
+ NTSTATUS Status;
- DPRINT1("UserPostThreadMessage wParam 0x%x lParam 0x%x\n", wParam,lParam);
+ DPRINT1("UserPostThreadMessage wParam 0x%x lParam 0x%x\n", wParam,lParam);
- if (FindMsgMemory(Msg) != 0)
- {
- SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
- return FALSE;
- }
+ if (FindMsgMemory(Msg) != 0)
+ {
+ SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
+ }
- Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
+ Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
- if( Status == STATUS_SUCCESS )
- {
- pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
- if( !pThread ||
- !pThread->MessageQueue ||
- (pThread->TIF_flags & TIF_INCLEANUP))
- {
- ObDereferenceObject( peThread );
- return FALSE;
- }
+ if( Status == STATUS_SUCCESS )
+ {
+ pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
+ if( !pThread ||
+ !pThread->MessageQueue ||
+ (pThread->TIF_flags & TIF_INCLEANUP))
+ {
+ ObDereferenceObject( peThread );
+ return FALSE;
+ }
- Message.hwnd = NULL;
- Message.message = Msg;
- Message.wParam = wParam;
- Message.lParam = lParam;
- Message.pt = gpsi->ptCursor;
+ Message.hwnd = NULL;
+ Message.message = Msg;
+ Message.wParam = wParam;
+ Message.lParam = lParam;
+ Message.pt = gpsi->ptCursor;
- KeQueryTickCount(&LargeTickCount);
- pThread->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
- ObDereferenceObject( peThread );
- return TRUE;
- }
- else
- {
- SetLastNtError( Status );
- }
- return FALSE;
+ KeQueryTickCount(&LargeTickCount);
+ pThread->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
+ MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
+ ObDereferenceObject( peThread );
+ return TRUE;
+ }
+ else
+ {
+ SetLastNtError( Status );
+ }
+ return FALSE;
}
BOOL FASTCALL
@@ -1222,79 +882,83 @@ UserPostMessage( HWND Wnd,
WPARAM wParam,
LPARAM lParam )
{
- PTHREADINFO pti;
- MSG Message;
- LARGE_INTEGER LargeTickCount;
+ PTHREADINFO pti;
+ MSG Message;
+ LARGE_INTEGER LargeTickCount;
- if (FindMsgMemory(Msg) != 0)
- {
- SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
- return FALSE;
- }
+ if (FindMsgMemory(Msg) != 0)
+ {
+ SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
+ }
- if (!Wnd)
- return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
- Msg,
- wParam,
- lParam);
+ if (!Wnd)
+ {
+ return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
+ Msg,
+ wParam,
+ lParam);
+ }
+ if (Wnd == HWND_BROADCAST)
+ {
+ HWND *List;
+ PWND DesktopWindow;
+ ULONG i;
- if (Wnd == HWND_BROADCAST)
- {
- HWND *List;
- PWND DesktopWindow;
- ULONG i;
+ DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ List = IntWinListChildren(DesktopWindow);
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
- List = IntWinListChildren(DesktopWindow);
+ if (List != NULL)
+ {
+ UserPostMessage(DesktopWindow->head.h, Msg, wParam, lParam);
+ for (i = 0; List[i]; i++)
+ {
+ UserPostMessage(List[i], Msg, wParam, lParam);
+ }
+ ExFreePool(List);
+ }
+ }
+ else
+ {
+ PWND Window;
- if (List != NULL)
- {
- for (i = 0; List[i]; i++)
- UserPostMessage(List[i], Msg, wParam, lParam);
- ExFreePool(List);
- }
- }
- else
- {
- PWND Window;
+ Window = UserGetWindowObject(Wnd);
+ if ( !Window )
+ {
+ return FALSE;
+ }
- Window = UserGetWindowObject(Wnd);
- if ( !Window )
- {
- return FALSE;
- }
+ pti = Window->head.pti;
+ if ( pti->TIF_flags & TIF_INCLEANUP )
+ {
+ DPRINT1("Attempted to post message to window 0x%x when the thread is in cleanup!\n", Wnd);
+ return FALSE;
+ }
- pti = Window->head.pti;
- if ( pti->TIF_flags & TIF_INCLEANUP )
- {
- DPRINT1("Attempted to post message to window 0x%x when the thread is in cleanup!\n", Wnd);
- return FALSE;
- }
+ if ( Window->state & WNDS_DESTROYED )
+ {
+ DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
+ /* FIXME - last error code? */
+ return FALSE;
+ }
- if ( Window->state & WNDS_DESTROYED )
- {
- DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
- /* FIXME - last error code? */
- return FALSE;
- }
-
- if (WM_QUIT == Msg)
- {
- MsqPostQuitMessage(Window->head.pti->MessageQueue, wParam);
- }
- else
- {
- Message.hwnd = Wnd;
- Message.message = Msg;
- Message.wParam = wParam;
- Message.lParam = lParam;
- Message.pt = gpsi->ptCursor;
- KeQueryTickCount(&LargeTickCount);
- pti->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
- }
- }
- return TRUE;
+ if (WM_QUIT == Msg)
+ {
+ MsqPostQuitMessage(Window->head.pti->MessageQueue, wParam);
+ }
+ else
+ {
+ Message.hwnd = Wnd;
+ Message.message = Msg;
+ Message.wParam = wParam;
+ Message.lParam = lParam;
+ Message.pt = gpsi->ptCursor;
+ KeQueryTickCount(&LargeTickCount);
+ pti->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
+ MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
+ }
+ }
+ return TRUE;
}
@@ -1304,16 +968,15 @@ co_IntSendMessage( HWND hWnd,
WPARAM wParam,
LPARAM lParam )
{
- ULONG_PTR Result = 0;
- if(co_IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
- {
- return (LRESULT)Result;
- }
- return 0;
+ ULONG_PTR Result = 0;
+ if(co_IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
+ {
+ return (LRESULT)Result;
+ }
+ return 0;
}
-static
-LRESULT FASTCALL
+static LRESULT FASTCALL
co_IntSendMessageTimeoutSingle( HWND hWnd,
UINT Msg,
WPARAM wParam,
@@ -1322,131 +985,134 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
UINT uTimeout,
ULONG_PTR *uResult )
{
- ULONG_PTR Result;
- NTSTATUS Status;
- PWND Window = NULL;
- PMSGMEMORY MsgMemoryEntry;
- INT lParamBufferSize;
- LPARAM lParamPacked;
- PTHREADINFO Win32Thread;
- DECLARE_RETURN(LRESULT);
- USER_REFERENCE_ENTRY Ref;
+ NTSTATUS Status;
+ PWND Window = NULL;
+ PMSGMEMORY MsgMemoryEntry;
+ INT lParamBufferSize;
+ LPARAM lParamPacked;
+ PTHREADINFO Win32Thread;
+ ULONG_PTR Result = 0;
+ DECLARE_RETURN(LRESULT);
+ USER_REFERENCE_ENTRY Ref;
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN( FALSE);
- }
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ RETURN( FALSE);
+ }
- UserRefObjectCo(Window, &Ref);
+ UserRefObjectCo(Window, &Ref);
- Win32Thread = PsGetCurrentThreadWin32Thread();
+ Win32Thread = PsGetCurrentThreadWin32Thread();
- IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+ IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
- if ( NULL != Win32Thread &&
- Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
- {
- if (Win32Thread->TIF_flags & TIF_INCLEANUP)
- {
- /* Never send messages to exiting threads */
- RETURN( FALSE);
- }
+ if ( NULL != Win32Thread &&
+ Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
+ {
+ if (Win32Thread->TIF_flags & TIF_INCLEANUP)
+ {
+ /* Never send messages to exiting threads */
+ RETURN( FALSE);
+ }
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(Msg);
- if (NULL == MsgMemoryEntry)
- {
- lParamBufferSize = -1;
- }
- else
- {
- lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
- }
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(Msg);
+ if (NULL == MsgMemoryEntry)
+ {
+ lParamBufferSize = -1;
+ }
+ else
+ {
+ lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+ }
- if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, FALSE)))
- {
- DPRINT1("Failed to pack message parameters\n");
- RETURN( FALSE);
- }
+ if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, FALSE)))
+ {
+ DPRINT1("Failed to pack message parameters\n");
+ RETURN( FALSE);
+ }
- Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
- !Window->Unicode,
- hWnd,
- Msg,
- wParam,
- lParamPacked,
- lParamBufferSize );
- if(uResult)
- {
- *uResult = Result;
- }
+ ObReferenceObject(Win32Thread->pEThread);
+ Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
+ !Window->Unicode,
+ hWnd,
+ Msg,
+ wParam,
+ lParamPacked,
+ lParamBufferSize );
+ if(uResult)
+ {
+ *uResult = Result;
+ }
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
+ ObDereferenceObject(Win32Thread->pEThread);
- if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
- {
- DPRINT1("Failed to unpack message parameters\n");
- RETURN( TRUE);
- }
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
- RETURN( TRUE);
- }
+ if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
+ {
+ DPRINT1("Failed to unpack message parameters\n");
+ RETURN( TRUE);
+ }
- if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti->MessageQueue))
- {
- /* FIXME - Set a LastError? */
- RETURN( FALSE);
- }
+ RETURN( TRUE);
+ }
- if (Window->state & WNDS_DESTROYED)
- {
- /* FIXME - last error? */
- DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
- RETURN( FALSE);
- }
+ if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti->MessageQueue))
+ {
+ /* FIXME - Set a LastError? */
+ RETURN( FALSE);
+ }
- do
- {
- Status = co_MsqSendMessage( Window->head.pti->MessageQueue,
- hWnd,
- Msg,
- wParam,
- lParam,
- uTimeout,
- (uFlags & SMTO_BLOCK),
- MSQ_NORMAL,
- uResult );
- }
- while ((STATUS_TIMEOUT == Status) &&
- (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
- !MsqIsHung(Window->head.pti->MessageQueue));
+ if (Window->state & WNDS_DESTROYED)
+ {
+ /* FIXME - last error? */
+ DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
+ RETURN( FALSE);
+ }
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
+ do
+ {
+ Status = co_MsqSendMessage( Window->head.pti->MessageQueue,
+ hWnd,
+ Msg,
+ wParam,
+ lParam,
+ uTimeout,
+ (uFlags & SMTO_BLOCK),
+ MSQ_NORMAL,
+ uResult );
+ }
+ while ((STATUS_TIMEOUT == Status) &&
+ (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
+ !MsqIsHung(Window->head.pti->MessageQueue));
- if (STATUS_TIMEOUT == Status)
- {
-/*
- MSDN says:
- Microsoft Windows 2000: If GetLastError returns zero, then the function
- timed out.
- XP+ : If the function fails or times out, the return value is zero.
- To get extended error information, call GetLastError. If GetLastError
- returns ERROR_TIMEOUT, then the function timed out.
- */
- SetLastWin32Error(ERROR_TIMEOUT);
- RETURN( FALSE);
- }
- else if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
- RETURN( TRUE);
+ if (STATUS_TIMEOUT == Status)
+ {
+ /*
+MSDN says:
+ Microsoft Windows 2000: If GetLastError returns zero, then the function
+ timed out.
+ XP+ : If the function fails or times out, the return value is zero.
+ To get extended error information, call GetLastError. If GetLastError
+ returns ERROR_TIMEOUT, then the function timed out.
+*/
+ SetLastWin32Error(ERROR_TIMEOUT);
+ RETURN( FALSE);
+ }
+ else if (! NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN( FALSE);
+ }
+
+ RETURN( TRUE);
CLEANUP:
- if (Window) UserDerefObjectCo(Window);
- END_CLEANUP;
+ if (Window) UserDerefObjectCo(Window);
+ END_CLEANUP;
}
LRESULT FASTCALL
@@ -1458,217 +1124,222 @@ co_IntSendMessageTimeout( HWND hWnd,
UINT uTimeout,
ULONG_PTR *uResult )
{
- PWND DesktopWindow;
- HWND *Children;
- HWND *Child;
+ PWND DesktopWindow;
+ HWND *Children;
+ HWND *Child;
- if (HWND_BROADCAST != hWnd)
- {
- return co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags, uTimeout, uResult);
- }
+ if (HWND_BROADCAST != hWnd)
+ {
+ return co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+ }
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
- if (NULL == DesktopWindow)
- {
- SetLastWin32Error(ERROR_INTERNAL_ERROR);
- return 0;
- }
+ DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ if (NULL == DesktopWindow)
+ {
+ SetLastWin32Error(ERROR_INTERNAL_ERROR);
+ return 0;
+ }
- Children = IntWinListChildren(DesktopWindow);
- if (NULL == Children)
- {
- return 0;
- }
+ /* Send message to the desktop window too! */
+ co_IntSendMessageTimeoutSingle(DesktopWindow->head.h, Msg, wParam, lParam, uFlags, uTimeout, uResult);
- for (Child = Children; NULL != *Child; Child++)
- {
- co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
- }
+ Children = IntWinListChildren(DesktopWindow);
+ if (NULL == Children)
+ {
+ return 0;
+ }
- ExFreePool(Children);
+ for (Child = Children; NULL != *Child; Child++)
+ {
+ co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+ }
- return (LRESULT) TRUE;
+ ExFreePool(Children);
+
+ return (LRESULT) TRUE;
}
-LRESULT FASTCALL co_IntSendMessageNoWait(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
+LRESULT FASTCALL
+co_IntSendMessageNoWait(HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam)
{
- ULONG_PTR Result = 0;
- co_IntSendMessageWithCallBack(hWnd,
- Msg,
- wParam,
- lParam,
- NULL,
- 0,
- &Result);
- return Result;
+ ULONG_PTR Result = 0;
+ co_IntSendMessageWithCallBack(hWnd,
+ Msg,
+ wParam,
+ lParam,
+ NULL,
+ 0,
+ &Result);
+ return Result;
}
LRESULT FASTCALL
co_IntSendMessageWithCallBack( HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- SENDASYNCPROC CompletionCallback,
- ULONG_PTR CompletionCallbackContext,
- ULONG_PTR *uResult)
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ SENDASYNCPROC CompletionCallback,
+ ULONG_PTR CompletionCallbackContext,
+ ULONG_PTR *uResult)
{
- ULONG_PTR Result;
- PWND Window = NULL;
- PMSGMEMORY MsgMemoryEntry;
- INT lParamBufferSize;
- LPARAM lParamPacked;
- PTHREADINFO Win32Thread;
- DECLARE_RETURN(LRESULT);
- USER_REFERENCE_ENTRY Ref;
- PUSER_SENT_MESSAGE Message;
+ ULONG_PTR Result;
+ PWND Window = NULL;
+ PMSGMEMORY MsgMemoryEntry;
+ INT lParamBufferSize;
+ LPARAM lParamPacked;
+ PTHREADINFO Win32Thread;
+ DECLARE_RETURN(LRESULT);
+ USER_REFERENCE_ENTRY Ref;
+ PUSER_SENT_MESSAGE Message;
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(FALSE);
- }
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ RETURN(FALSE);
+ }
- UserRefObjectCo(Window, &Ref);
+ UserRefObjectCo(Window, &Ref);
- if (Window->state & WNDS_DESTROYED)
- {
- /* FIXME - last error? */
- DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
- RETURN(FALSE);
- }
+ if (Window->state & WNDS_DESTROYED)
+ {
+ /* FIXME - last error? */
+ DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
+ RETURN(FALSE);
+ }
- Win32Thread = PsGetCurrentThreadWin32Thread();
+ Win32Thread = PsGetCurrentThreadWin32Thread();
- IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+ IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
- if (Win32Thread == NULL)
- {
- ASSERT(FALSE);
- RETURN(FALSE);
- }
+ if (Win32Thread == NULL)
+ {
+ ASSERT(FALSE);
+ RETURN(FALSE);
+ }
- if (Win32Thread->TIF_flags & TIF_INCLEANUP)
- {
- /* Never send messages to exiting threads */
- RETURN(FALSE);
- }
+ if (Win32Thread->TIF_flags & TIF_INCLEANUP)
+ {
+ /* Never send messages to exiting threads */
+ RETURN(FALSE);
+ }
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(Msg);
- if (NULL == MsgMemoryEntry)
- {
- lParamBufferSize = -1;
- }
- else
- {
- lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
- }
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(Msg);
+ if (NULL == MsgMemoryEntry)
+ {
+ lParamBufferSize = -1;
+ }
+ else
+ {
+ lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+ }
- if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti->MessageQueue != Win32Thread->MessageQueue)))
- {
- DPRINT1("Failed to pack message parameters\n");
- RETURN( FALSE);
- }
+ if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti->MessageQueue != Win32Thread->MessageQueue)))
+ {
+ DPRINT1("Failed to pack message parameters\n");
+ RETURN( FALSE);
+ }
- /* If this is not a callback and it can be sent now, then send it. */
- if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
- {
+ /* If this is not a callback and it can be sent now, then send it. */
+ if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+ {
+ ObReferenceObject(Win32Thread->pEThread);
+ Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
+ !Window->Unicode,
+ hWnd,
+ Msg,
+ wParam,
+ lParamPacked,
+ lParamBufferSize );
+ if(uResult)
+ {
+ *uResult = Result;
+ }
+ ObDereferenceObject(Win32Thread->pEThread);
+ }
- Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
- !Window->Unicode,
- hWnd,
- Msg,
- wParam,
- lParamPacked,
- lParamBufferSize );
- if(uResult)
- {
- *uResult = Result;
- }
- }
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
+ if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+ {
+ if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
+ {
+ DPRINT1("Failed to unpack message parameters\n");
+ }
+ RETURN(TRUE);
+ }
- if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
- {
- if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
- {
- DPRINT1("Failed to unpack message parameters\n");
- }
- RETURN(TRUE);
- }
+ if(!(Message = ExAllocatePoolWithTag(NonPagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
+ {
+ DPRINT1("MsqSendMessage(): Not enough memory to allocate a message");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- if(!(Message = ExAllocatePoolWithTag(NonPagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
- {
- DPRINT1("MsqSendMessage(): Not enough memory to allocate a message");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ Message->Msg.hwnd = hWnd;
+ Message->Msg.message = Msg;
+ Message->Msg.wParam = wParam;
+ Message->Msg.lParam = lParamPacked;
+ Message->CompletionEvent = NULL;
+ Message->Result = 0;
+ Message->SenderQueue = NULL; //Win32Thread->MessageQueue;
- Message->Msg.hwnd = hWnd;
- Message->Msg.message = Msg;
- Message->Msg.wParam = wParam;
- Message->Msg.lParam = lParamPacked;
- Message->CompletionEvent = NULL;
- Message->Result = 0;
- Message->SenderQueue = NULL; //Win32Thread->MessageQueue;
+ IntReferenceMessageQueue(Window->head.pti->MessageQueue);
+ Message->CompletionCallback = CompletionCallback;
+ Message->CompletionCallbackContext = CompletionCallbackContext;
+ Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
+ Message->HasPackedLParam = (lParamBufferSize > 0);
- IntReferenceMessageQueue(Window->head.pti->MessageQueue);
- Message->CompletionCallback = CompletionCallback;
- Message->CompletionCallbackContext = CompletionCallbackContext;
- Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
- Message->HasPackedLParam = (lParamBufferSize > 0);
+ InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
+ IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
- InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
- IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
-
- RETURN(TRUE);
+ RETURN(TRUE);
CLEANUP:
- if (Window) UserDerefObjectCo(Window);
- END_CLEANUP;
+ if (Window) UserDerefObjectCo(Window);
+ END_CLEANUP;
}
/* This function posts a message if the destination's message queue belongs to
- another thread, otherwise it sends the message. It does not support broadcast
- messages! */
+another thread, otherwise it sends the message. It does not support broadcast
+messages! */
LRESULT FASTCALL
co_IntPostOrSendMessage( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam )
{
- ULONG_PTR Result;
- PTHREADINFO pti;
- PWND Window;
+ ULONG_PTR Result;
+ PTHREADINFO pti;
+ PWND Window;
- if ( hWnd == HWND_BROADCAST )
- {
- return 0;
- }
+ if ( hWnd == HWND_BROADCAST )
+ {
+ return 0;
+ }
- if(!(Window = UserGetWindowObject(hWnd)))
- {
- return 0;
- }
+ if(!(Window = UserGetWindowObject(hWnd)))
+ {
+ return 0;
+ }
- pti = PsGetCurrentThreadWin32Thread();
+ pti = PsGetCurrentThreadWin32Thread();
- if ( Window->head.pti->MessageQueue != pti->MessageQueue &&
- FindMsgMemory(Msg) == 0 )
- {
- Result = UserPostMessage(hWnd, Msg, wParam, lParam);
- }
- else
- {
- if ( !co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result) )
- {
- Result = 0;
- }
- }
+ if ( Window->head.pti->MessageQueue != pti->MessageQueue &&
+ FindMsgMemory(Msg) == 0 )
+ {
+ Result = UserPostMessage(hWnd, Msg, wParam, lParam);
+ }
+ else
+ {
+ if ( !co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result) )
+ {
+ Result = 0;
+ }
+ }
- return (LRESULT)Result;
+ return (LRESULT)Result;
}
LRESULT FASTCALL
@@ -1679,116 +1350,115 @@ co_IntDoSendMessage( HWND hWnd,
PDOSENDMESSAGE dsm,
PNTUSERSENDMESSAGEINFO UnsafeInfo )
{
- PTHREADINFO pti;
- LRESULT Result = TRUE;
- NTSTATUS Status;
- PWND Window = NULL;
- NTUSERSENDMESSAGEINFO Info;
- MSG UserModeMsg;
- MSG KernelModeMsg;
- PMSGMEMORY MsgMemoryEntry;
+ PTHREADINFO pti;
+ LRESULT Result = TRUE;
+ NTSTATUS Status;
+ PWND Window = NULL;
+ NTUSERSENDMESSAGEINFO Info;
+ MSG UserModeMsg;
+ MSG KernelModeMsg;
+ PMSGMEMORY MsgMemoryEntry;
- RtlZeroMemory(&Info, sizeof(NTUSERSENDMESSAGEINFO));
+ RtlZeroMemory(&Info, sizeof(NTUSERSENDMESSAGEINFO));
- /* FIXME: Call hooks. */
- if (HWND_BROADCAST != hWnd)
- {
- Window = UserGetWindowObject(hWnd);
- if ( !Window )
- {
- /* Tell usermode to not touch this one */
- Info.HandledByKernel = TRUE;
- MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
- return 0;
- }
- }
+ /* FIXME: Call hooks. */
+ if (HWND_BROADCAST != hWnd)
+ {
+ Window = UserGetWindowObject(hWnd);
+ if ( !Window )
+ {
+ /* Tell usermode to not touch this one */
+ Info.HandledByKernel = TRUE;
+ MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
+ return 0;
+ }
+ }
- /* Check for an exiting window. */
- if (Window && Window->state & WNDS_DESTROYED)
- {
- DPRINT1("co_IntDoSendMessage Window Exiting!\n");
- }
+ /* Check for an exiting window. */
+ if (Window && Window->state & WNDS_DESTROYED)
+ {
+ DPRINT1("co_IntDoSendMessage Window Exiting!\n");
+ }
- /* See if the current thread can handle the message */
- pti = PsGetCurrentThreadWin32Thread();
+ /* See if the current thread can handle the message */
+ pti = PsGetCurrentThreadWin32Thread();
- // This is checked in user mode!!!!!!!
- if ( HWND_BROADCAST != hWnd &&
- NULL != pti &&
- Window->head.pti->MessageQueue == pti->MessageQueue &&
- !ISITHOOKED(WH_CALLWNDPROC) &&
- !ISITHOOKED(WH_CALLWNDPROCRET) &&
- ( Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST ) )
- {
- /* Gather the information usermode needs to call the window proc directly */
- Info.HandledByKernel = FALSE;
+ // This is checked in user mode!!!!!!!
+ if ( HWND_BROADCAST != hWnd &&
+ NULL != pti &&
+ Window->head.pti->MessageQueue == pti->MessageQueue &&
+ !ISITHOOKED(WH_CALLWNDPROC) &&
+ !ISITHOOKED(WH_CALLWNDPROCRET) &&
+ ( Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST ) )
+ {
+ /* Gather the information usermode needs to call the window proc directly */
+ Info.HandledByKernel = FALSE;
- Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
- sizeof(BOOL));
- if (! NT_SUCCESS(Status))
- {
- Info.Ansi = ! Window->Unicode;
- }
+ Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi), sizeof(BOOL));
+ if (! NT_SUCCESS(Status))
+ {
+ Info.Ansi = ! Window->Unicode;
+ }
- Info.Ansi = !Window->Unicode;
- Info.Proc = Window->lpfnWndProc;
- }
- else
- {
- /* Must be handled by other thread */
-// if (HWND_BROADCAST != hWnd)
-// {
-// UserDereferenceObject(Window);
-// }
- Info.HandledByKernel = TRUE;
- UserModeMsg.hwnd = hWnd;
- UserModeMsg.message = Msg;
- UserModeMsg.wParam = wParam;
- UserModeMsg.lParam = lParam;
- MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
+ Info.Ansi = !Window->Unicode;
+ Info.Proc = Window->lpfnWndProc;
+ }
+ else
+ {
+ /* Must be handled by other thread */
+ // if (HWND_BROADCAST != hWnd)
+ // {
+ // UserDereferenceObject(Window);
+ // }
+ Info.HandledByKernel = TRUE;
+ UserModeMsg.hwnd = hWnd;
+ UserModeMsg.message = Msg;
+ UserModeMsg.wParam = wParam;
+ UserModeMsg.lParam = lParam;
+ MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
- Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
- if (! NT_SUCCESS(Status))
- {
- MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return (dsm ? 0 : -1);
- }
+ Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
+ if (! NT_SUCCESS(Status))
+ {
+ MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return (dsm ? 0 : -1);
+ }
- if(!dsm)
- {
- Result = co_IntSendMessage( KernelModeMsg.hwnd,
- KernelModeMsg.message,
- KernelModeMsg.wParam,
- KernelModeMsg.lParam );
- }
- else
- {
- Result = co_IntSendMessageTimeout( KernelModeMsg.hwnd,
- KernelModeMsg.message,
- KernelModeMsg.wParam,
- KernelModeMsg.lParam,
- dsm->uFlags,
- dsm->uTimeout,
- &dsm->Result );
- }
+ if(!dsm)
+ {
+ Result = co_IntSendMessage( KernelModeMsg.hwnd,
+ KernelModeMsg.message,
+ KernelModeMsg.wParam,
+ KernelModeMsg.lParam );
+ }
+ else
+ {
+ Result = co_IntSendMessageTimeout( KernelModeMsg.hwnd,
+ KernelModeMsg.message,
+ KernelModeMsg.wParam,
+ KernelModeMsg.lParam,
+ dsm->uFlags,
+ dsm->uTimeout,
+ &dsm->Result );
+ }
- Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
- if (! NT_SUCCESS(Status))
- {
- MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return(dsm ? 0 : -1);
- }
- }
+ Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
+ if (! NT_SUCCESS(Status))
+ {
+ MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return(dsm ? 0 : -1);
+ }
+ }
- Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
- if (! NT_SUCCESS(Status))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- }
+ Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ }
- return (LRESULT)Result;
+ return (LRESULT)Result;
}
@@ -1798,112 +1468,116 @@ UserSendNotifyMessage( HWND hWnd,
WPARAM wParam,
LPARAM lParam )
{
- BOOL Result = TRUE;
+ BOOL Result = TRUE;
- if (FindMsgMemory(Msg) != 0)
- {
- SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
- return FALSE;
- }
+ if (FindMsgMemory(Msg) != 0)
+ {
+ SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
+ }
- // Basicly the same as IntPostOrSendMessage
- if (hWnd == HWND_BROADCAST) //Handle Broadcast
- {
- HWND *List;
- PWND DesktopWindow;
- ULONG i;
+ // Basicly the same as IntPostOrSendMessage
+ if (hWnd == HWND_BROADCAST) //Handle Broadcast
+ {
+ HWND *List;
+ PWND DesktopWindow;
+ ULONG i;
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
- List = IntWinListChildren(DesktopWindow);
+ DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ List = IntWinListChildren(DesktopWindow);
- if (List != NULL)
- {
- for (i = 0; List[i]; i++)
- {
- UserSendNotifyMessage(List[i], Msg, wParam, lParam);
- }
- ExFreePool(List);
- }
- }
- else
- {
- ULONG_PTR PResult;
- PTHREADINFO pti;
- PWND Window;
+ if (List != NULL)
+ {
+ UserSendNotifyMessage(DesktopWindow->head.h, Msg, wParam, lParam);
+ for (i = 0; List[i]; i++)
+ {
+ UserSendNotifyMessage(List[i], Msg, wParam, lParam);
+ }
+ ExFreePool(List);
+ }
+ }
+ else
+ {
+ ULONG_PTR PResult;
+ PTHREADINFO pti;
+ PWND Window;
- if ( !(Window = UserGetWindowObject(hWnd)) ) return FALSE;
+ if ( !(Window = UserGetWindowObject(hWnd)) ) return FALSE;
- pti = PsGetCurrentThreadWin32Thread();
+ pti = PsGetCurrentThreadWin32Thread();
- if (Window->head.pti->MessageQueue != pti->MessageQueue)
- { // Send message w/o waiting for it.
- Result = UserPostMessage(hWnd, Msg, wParam, lParam);
- }
- else
- { // Handle message and callback.
- Result = co_IntSendMessageTimeoutSingle( hWnd,
- Msg,
- wParam,
- lParam,
- SMTO_NORMAL,
- 0,
- &PResult );
- }
- }
- return Result;
+ if (Window->head.pti->MessageQueue != pti->MessageQueue)
+ { // Send message w/o waiting for it.
+ Result = UserPostMessage(hWnd, Msg, wParam, lParam);
+ }
+ else
+ { // Handle message and callback.
+ Result = co_IntSendMessageTimeoutSingle( hWnd,
+ Msg,
+ wParam,
+ lParam,
+ SMTO_NORMAL,
+ 0,
+ &PResult );
+ }
+ }
+ return Result;
}
DWORD APIENTRY
-IntGetQueueStatus(BOOL ClearChanges)
+IntGetQueueStatus(DWORD Changes)
{
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE Queue;
- DWORD Result;
- DECLARE_RETURN(DWORD);
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE Queue;
+ DWORD Result;
- DPRINT("Enter IntGetQueueStatus\n");
+ pti = PsGetCurrentThreadWin32Thread();
+ Queue = pti->MessageQueue;
+// wine:
+ Changes &= (QS_ALLINPUT|QS_ALLPOSTMESSAGE|QS_SMRESULT);
- pti = PsGetCurrentThreadWin32Thread();
- Queue = pti->MessageQueue;
+ Result = MAKELONG(Queue->ChangedBits & Changes, Queue->QueueBits & Changes);
- Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
- if (ClearChanges)
- {
- Queue->ChangedBits = 0;
- }
+ if (pti->pcti)
+ {
+ pti->pcti->fsChangeBits = Queue->ChangedBits;
+ pti->pcti->fsChangeBits &= ~Changes;
+ }
- RETURN(Result);
+ Queue->ChangedBits &= ~Changes;
-CLEANUP:
- DPRINT("Leave IntGetQueueStatus, ret=%i\n",_ret_);
- END_CLEANUP;
+ return Result;
}
BOOL APIENTRY
IntInitMessagePumpHook()
{
- if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
- {
- ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook++;
- return TRUE;
- }
- return FALSE;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+
+ if (pti->pcti)
+ {
+ pti->pcti->dwcPumpHook++;
+ return TRUE;
+ }
+ return FALSE;
}
BOOL APIENTRY
IntUninitMessagePumpHook()
{
- if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
- {
- if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook <= 0)
- {
- return FALSE;
- }
- ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook--;
- return TRUE;
- }
- return FALSE;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+
+ if (pti->pcti)
+ {
+ if (pti->pcti->dwcPumpHook <= 0)
+ {
+ return FALSE;
+ }
+ pti->pcti->dwcPumpHook--;
+ return TRUE;
+ }
+ return FALSE;
}
/** Functions ******************************************************************/
@@ -1914,17 +1588,15 @@ NtUserPostMessage(HWND hWnd,
WPARAM wParam,
LPARAM lParam)
{
- DECLARE_RETURN(BOOL);
+ BOOL ret;
- DPRINT("Enter NtUserPostMessage\n");
- UserEnterExclusive();
+ UserEnterExclusive();
- RETURN( UserPostMessage(hWnd, Msg, wParam, lParam));
+ ret = UserPostMessage(hWnd, Msg, wParam, lParam);
-CLEANUP:
- DPRINT("Leave NtUserPostMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+
+ return ret;
}
BOOL APIENTRY
@@ -1933,31 +1605,17 @@ NtUserPostThreadMessage(DWORD idThread,
WPARAM wParam,
LPARAM lParam)
{
- DECLARE_RETURN(BOOL);
+ BOOL ret;
- DPRINT("Enter NtUserPostThreadMessage\n");
- UserEnterExclusive();
+ UserEnterExclusive();
- RETURN( UserPostThreadMessage( idThread,
- Msg,
- wParam,
- lParam));
+ ret = UserPostThreadMessage( idThread, Msg, wParam, lParam);
-CLEANUP:
- DPRINT("Leave NtUserPostThreadMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+
+ return ret;
}
-DWORD APIENTRY
-NtUserQuerySendMessage(DWORD Unknown0)
-{
- UNIMPLEMENTED;
-
- return 0;
-}
-
-
////////// API on the way out!
LRESULT APIENTRY
NtUserSendMessageTimeout( HWND hWnd,
@@ -1969,33 +1627,36 @@ NtUserSendMessageTimeout( HWND hWnd,
ULONG_PTR *uResult,
PNTUSERSENDMESSAGEINFO UnsafeInfo )
{
- DOSENDMESSAGE dsm;
- LRESULT Result;
- DECLARE_RETURN(BOOL);
+ DOSENDMESSAGE dsm;
+ LRESULT Result;
- DPRINT("Enter NtUserSendMessageTimeout\n");
- UserEnterExclusive();
+ DPRINT("Enter NtUserSendMessageTimeout\n");
- dsm.uFlags = uFlags;
- dsm.uTimeout = uTimeout;
- Result = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
- if(uResult != NULL && Result != 0)
- {
- NTSTATUS Status;
+ dsm.uFlags = uFlags;
+ dsm.uTimeout = uTimeout;
- Status = MmCopyToCaller(uResult, &dsm.Result, sizeof(ULONG_PTR));
- if(!NT_SUCCESS(Status))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( FALSE);
- }
- }
- RETURN( Result);
+ UserEnterExclusive();
-CLEANUP:
- DPRINT("Leave NtUserSendMessageTimeout, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ Result = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
+
+ UserLeave();
+
+ if(uResult != NULL && Result != 0)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(uResult, sizeof(ULONG_PTR), 1);
+ RtlCopyMemory(uResult, &dsm.Result, sizeof(ULONG_PTR));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);;
+ Result = FALSE;
+ }
+ _SEH2_END;
+ }
+
+ return Result;
}
LRESULT APIENTRY
@@ -2005,34 +1666,30 @@ NtUserSendMessage( HWND Wnd,
LPARAM lParam,
PNTUSERSENDMESSAGEINFO UnsafeInfo )
{
- DECLARE_RETURN(BOOL);
+ BOOL ret;
- DPRINT("Enter NtUserSendMessage\n");
- UserEnterExclusive();
+ UserEnterExclusive();
- RETURN(co_IntDoSendMessage(Wnd, Msg, wParam, lParam, NULL, UnsafeInfo));
+ ret = co_IntDoSendMessage(Wnd, Msg, wParam, lParam, NULL, UnsafeInfo);
-CLEANUP:
- DPRINT("Leave NtUserSendMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+
+ return ret;
}
//////////
BOOL APIENTRY
NtUserWaitMessage(VOID)
{
- DECLARE_RETURN(BOOL);
+ BOOL ret;
- DPRINT("EnterNtUserWaitMessage\n");
- UserEnterExclusive();
+ UserEnterExclusive();
- RETURN(co_IntWaitMessage(NULL, 0, 0));
+ ret = co_IntWaitMessage(NULL, 0, 0);
-CLEANUP:
- DPRINT("Leave NtUserWaitMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+
+ return ret;
}
@@ -2042,155 +1699,134 @@ NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
UINT MsgFilterMin,
UINT MsgFilterMax )
/*
- * FUNCTION: Get a message from the calling thread's message queue.
- * ARGUMENTS:
- * UnsafeMsg - Pointer to the structure which receives the returned message.
- * Wnd - Window whose messages are to be retrieved.
- * MsgFilterMin - Integer value of the lowest message value to be
- * retrieved.
- * MsgFilterMax - Integer value of the highest message value to be
- * retrieved.
- */
+* FUNCTION: Get a message from the calling thread's message queue.
+* ARGUMENTS:
+* UnsafeMsg - Pointer to the structure which receives the returned message.
+* Wnd - Window whose messages are to be retrieved.
+* MsgFilterMin - Integer value of the lowest message value to be
+* retrieved.
+* MsgFilterMax - Integer value of the highest message value to be
+* retrieved.
+*/
{
- BOOL GotMessage;
- NTUSERGETMESSAGEINFO Info;
- NTSTATUS Status;
- /* FIXME: if initialization is removed, gcc complains that this may be used before initialization. Please review */
- PWND Window = NULL;
- PMSGMEMORY MsgMemoryEntry;
- PVOID UserMem;
- UINT Size;
- USER_MESSAGE Msg;
- DECLARE_RETURN(BOOL);
-// USER_REFERENCE_ENTRY Ref;
+ NTUSERGETMESSAGEINFO Info;
+ NTSTATUS Status;
+ PMSGMEMORY MsgMemoryEntry;
+ PVOID UserMem;
+ ULONG Size;
+ MSG Msg;
+ BOOL GotMessage;
- DPRINT("Enter NtUserGetMessage\n");
- UserEnterExclusive();
+ if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
- /* Validate input */
- if (hWnd && !(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(-1);
- }
+ UserEnterExclusive();
-// if (Window) UserRefObjectCo(Window, &Ref);
+ RtlZeroMemory(&Msg, sizeof(MSG));
- if (MsgFilterMax < MsgFilterMin)
- {
- MsgFilterMin = 0;
- MsgFilterMax = 0;
- }
+ GotMessage = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
- do
- {
- GotMessage = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, PM_REMOVE);
- if (GotMessage)
- {
- Info.Msg = Msg.Msg;
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
- if (NULL == MsgMemoryEntry)
- {
+ UserLeave();
+
+ Info.Msg = Msg;
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(UnsafeInfo, sizeof(NTUSERGETMESSAGEINFO), 1);
+ RtlCopyMemory(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
+
+ if (NULL == MsgMemoryEntry)
+ {
/* Not present, no copying needed */
- Info.LParamSize = 0;
- }
- else
- {
+ UnsafeInfo->LParamSize = 0;
+ }
+ else
+ {
/* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
- Info.Msg.lParam);
+ Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam, Info.Msg.lParam);
+
/* Allocate required amount of user-mode memory */
- Info.LParamSize = Size;
- UserMem = NULL;
- Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
- &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
-
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ &UserMem,
+ 0,
+ &Size,
+ MEM_COMMIT,
+ PAGE_READWRITE);
if (! NT_SUCCESS(Status))
{
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
+ SetLastNtError(Status);
+ _SEH2_YIELD(return (BOOL) -1);
}
+
/* Transfer lParam data to user-mode mem */
- Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
- if (! NT_SUCCESS(Status))
- {
- ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
- &Info.LParamSize, MEM_DECOMMIT);
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
- }
- Info.Msg.lParam = (LPARAM) UserMem;
- }
- Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
- if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
- }
- }
- else if (! co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax))
- {
- RETURN( (BOOL) -1);
- }
- }
- while (! GotMessage);
+ ProbeForWrite(UserMem, Size, 1);
+ RtlCopyMemory(UserMem, (PVOID)Info.Msg.lParam, Size);
- RETURN( WM_QUIT != Info.Msg.message);
+ UnsafeInfo->LParamSize = Size;
+ UnsafeInfo->Msg.lParam = (LPARAM) UserMem;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
-CLEANUP:
-// if (Window) UserDerefObjectCo(Window);
+ if(UserMem != NULL)
+ {
+ ZwFreeVirtualMemory(NtCurrentProcess(), &UserMem, &Size, MEM_RELEASE);
+ }
- DPRINT("Leave NtUserGetMessage\n");
- UserLeave();
- END_CLEANUP;
+ _SEH2_YIELD(return (BOOL) -1);
+ }
+ _SEH2_END;
+
+ return GotMessage;
}
-BOOL
-APIENTRY
-NtUserGetMessageX(
- PMSG pMsg,
- HWND hWnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax)
+BOOL APIENTRY
+NtUserGetMessageX(PMSG pMsg,
+ HWND hWnd,
+ UINT MsgFilterMin,
+ UINT MsgFilterMax)
{
- MSG Msg;
- BOOL Ret = FALSE;
- DECLARE_RETURN(BOOL);
+ MSG Msg;
+ BOOL Ret;
- DPRINT("Enter NtUserGetMessage\n");
- UserEnterExclusive();
+ if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
- if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( Ret);
- }
+ UserEnterExclusive();
- RtlZeroMemory(&Msg, sizeof(MSG));
+ RtlZeroMemory(&Msg, sizeof(MSG));
- Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
+ Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
- if (Ret)
- {
- _SEH2_TRY
- {
- ProbeForWrite(pMsg, sizeof(MSG), 1);
- RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Ret = FALSE;
- }
- _SEH2_END;
- }
- RETURN( Ret);
+ UserLeave();
-CLEANUP:
- DPRINT("Leave NtUserGetMessage\n");
- UserLeave();
- END_CLEANUP;
+ if (Ret)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(pMsg, sizeof(MSG), 1);
+ RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = FALSE;
+ }
+ _SEH2_END;
+ }
+
+ return Ret;
}
BOOL APIENTRY
@@ -2200,453 +1836,427 @@ NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
UINT MsgFilterMax,
UINT RemoveMsg)
{
- NTSTATUS Status;
- BOOL Present;
- NTUSERGETMESSAGEINFO Info;
- PWND Window;
- PMSGMEMORY MsgMemoryEntry;
- PVOID UserMem;
- UINT Size;
- USER_MESSAGE Msg;
- DECLARE_RETURN(BOOL);
+ NTSTATUS Status;
+ NTUSERGETMESSAGEINFO Info;
+ PMSGMEMORY MsgMemoryEntry;
+ PVOID UserMem = NULL;
+ ULONG Size;
+ MSG Msg;
+ BOOL Ret;
- DPRINT("Enter NtUserPeekMessage\n");
- UserEnterExclusive();
+ if ( RemoveMsg & PM_BADMSGFLAGS )
+ {
+ SetLastWin32Error(ERROR_INVALID_FLAGS);
+ return FALSE;
+ }
- if (hWnd == (HWND)-1 || hWnd == (HWND)0x0000FFFF || hWnd == (HWND)0xFFFFFFFF)
- hWnd = (HWND)1;
+ UserEnterExclusive();
- /* Validate input */
- if (hWnd && hWnd != (HWND)1)
- {
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(-1);
- }
- }
- else
- {
- Window = (PWND)hWnd;
- }
+ RtlZeroMemory(&Msg, sizeof(MSG));
- if (MsgFilterMax < MsgFilterMin)
- {
- MsgFilterMin = 0;
- MsgFilterMax = 0;
- }
+ Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
- Present = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, RemoveMsg);
- if (Present)
- {
+ UserLeave();
- Info.Msg = Msg.Msg;
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- Info.LParamSize = 0;
- }
- else
- {
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
- Info.Msg.lParam);
- /* Allocate required amount of user-mode memory */
- Info.LParamSize = Size;
- UserMem = NULL;
- Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
- &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
- if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
- }
- /* Transfer lParam data to user-mode mem */
- Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
- if (! NT_SUCCESS(Status))
- {
- ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
- &Info.LParamSize, MEM_RELEASE);
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
- }
- Info.Msg.lParam = (LPARAM) UserMem;
- }
- Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
- if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
- }
- }
+ if (Ret)
+ {
+ Info.Msg = Msg;
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
- RETURN( Present);
+ _SEH2_TRY
+ {
+ ProbeForWrite(UnsafeInfo, sizeof(NTUSERGETMESSAGEINFO), 1);
+ RtlCopyMemory(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
-CLEANUP:
- DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ UnsafeInfo->LParamSize = 0;
+ }
+ else
+ {
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam, Info.Msg.lParam);
+
+ /* Allocate required amount of user-mode memory */
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ &UserMem,
+ 0,
+ &Size,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ _SEH2_YIELD(return (BOOL) -1);
+ }
+
+ /* Transfer lParam data to user-mode mem */
+ ProbeForWrite(UserMem, Size, 1);
+ RtlCopyMemory(UserMem, (PVOID)Info.Msg.lParam, Size);
+
+ UnsafeInfo->LParamSize = Size;
+ UnsafeInfo->Msg.lParam = (LPARAM) UserMem;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = (BOOL) -1;
+
+ if(UserMem != NULL)
+ {
+ ZwFreeVirtualMemory(NtCurrentProcess(), &UserMem, &Size, MEM_RELEASE);
+ }
+ }
+ _SEH2_END;
+ }
+
+ return Ret;
}
-BOOL
-APIENTRY
-NtUserPeekMessageX(
- PMSG pMsg,
- HWND hWnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax,
- UINT RemoveMsg)
+BOOL APIENTRY
+NtUserPeekMessageX( PMSG pMsg,
+ HWND hWnd,
+ UINT MsgFilterMin,
+ UINT MsgFilterMax,
+ UINT RemoveMsg)
{
- MSG Msg;
- BOOL Ret = FALSE;
- DECLARE_RETURN(BOOL);
+ MSG Msg;
+ BOOL Ret;
- DPRINT("Enter NtUserPeekMessage\n");
- UserEnterExclusive();
+ if ( RemoveMsg & PM_BADMSGFLAGS )
+ {
+ SetLastWin32Error(ERROR_INVALID_FLAGS);
+ return FALSE;
+ }
- if ( RemoveMsg & PM_BADMSGFLAGS )
- {
- SetLastWin32Error(ERROR_INVALID_FLAGS);
- RETURN( Ret);
- }
+ UserEnterExclusive();
- RtlZeroMemory(&Msg, sizeof(MSG));
+ RtlZeroMemory(&Msg, sizeof(MSG));
- Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
+ Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
- if (Ret)
- {
- _SEH2_TRY
- {
- ProbeForWrite(pMsg, sizeof(MSG), 1);
- RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Ret = FALSE;
- }
- _SEH2_END;
- }
- RETURN( Ret);
+ UserLeave();
-CLEANUP:
- DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ if (Ret)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(pMsg, sizeof(MSG), 1);
+ RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = FALSE;
+ }
+ _SEH2_END;
+ }
+
+ return Ret;
}
-BOOL
-APIENTRY
-NtUserCallMsgFilter(
- LPMSG lpmsg,
- INT code)
+BOOL APIENTRY
+NtUserCallMsgFilter( LPMSG lpmsg, INT code)
{
- BOOL BadChk = FALSE, Ret = FALSE;
- MSG Msg;
- DECLARE_RETURN(BOOL);
+ BOOL Ret = FALSE;
+ MSG Msg;
- DPRINT("Enter NtUserCallMsgFilter\n");
- UserEnterExclusive();
- if (lpmsg)
- {
- _SEH2_TRY
- {
- ProbeForRead((PVOID)lpmsg,
- sizeof(MSG),
- 1);
- RtlCopyMemory( &Msg,
- (PVOID)lpmsg,
- sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- BadChk = TRUE;
- }
- _SEH2_END;
- }
- else
- RETURN( FALSE);
+ _SEH2_TRY
+ {
+ ProbeForRead(lpmsg, sizeof(MSG), 1);
+ RtlCopyMemory( &Msg, lpmsg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
- if (BadChk) RETURN( FALSE);
+ UserEnterExclusive();
- if ( co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)&Msg))
- {
- Ret = TRUE;
- }
- else
- {
- Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
- }
+ if ( co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)&Msg))
+ {
+ Ret = TRUE;
+ }
+ else
+ {
+ Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
+ }
- _SEH2_TRY
- {
- ProbeForWrite((PVOID)lpmsg,
- sizeof(MSG),
- 1);
- RtlCopyMemory((PVOID)lpmsg,
- &Msg,
- sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- BadChk = TRUE;
- }
- _SEH2_END;
- if (BadChk) RETURN( FALSE);
- RETURN( Ret)
+ UserLeave();
-CLEANUP:
- DPRINT("Leave NtUserCallMsgFilter. ret=%i\n", _ret_);
- UserLeave();
- END_CLEANUP;
+ _SEH2_TRY
+ {
+ ProbeForWrite(lpmsg, sizeof(MSG), 1);
+ RtlCopyMemory(lpmsg, &Msg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ }
+ _SEH2_END;
+
+ return Ret;
}
LRESULT APIENTRY
NtUserDispatchMessage(PMSG UnsafeMsgInfo)
{
- LRESULT Res = 0;
- BOOL Hit = FALSE;
- MSG SafeMsg;
+ LRESULT Res = 0;
+ MSG SafeMsg;
- UserEnterExclusive();
- _SEH2_TRY
- {
- ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
- RtlCopyMemory(&SafeMsg, UnsafeMsgInfo, sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Hit = TRUE;
- }
- _SEH2_END;
-
- if (!Hit) Res = IntDispatchMessage(&SafeMsg);
+ _SEH2_TRY
+ {
+ ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
+ RtlCopyMemory(&SafeMsg, UnsafeMsgInfo, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
- UserLeave();
- return Res;
+ UserEnterExclusive();
+
+ Res = IntDispatchMessage(&SafeMsg);
+
+ UserLeave();
+ return Res;
}
BOOL APIENTRY
-NtUserTranslateMessage(LPMSG lpMsg,
- UINT flags)
+NtUserTranslateMessage(LPMSG lpMsg, UINT flags)
{
- NTSTATUS Status;
- MSG SafeMsg;
- DECLARE_RETURN(BOOL);
+ MSG SafeMsg;
+ BOOL Ret;
- DPRINT("Enter NtUserTranslateMessage\n");
- UserEnterExclusive();
+ _SEH2_TRY
+ {
+ ProbeForRead(lpMsg, sizeof(MSG), 1);
+ RtlCopyMemory(&SafeMsg, lpMsg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
- Status = MmCopyFromCaller(&SafeMsg, lpMsg, sizeof(MSG));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
+ UserEnterExclusive();
- RETURN( IntTranslateKbdMessage(&SafeMsg, flags));
+ Ret = IntTranslateKbdMessage(&SafeMsg, flags);
-CLEANUP:
- DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+
+ return Ret;
}
BOOL APIENTRY
-NtUserMessageCall(
- HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- ULONG_PTR ResultInfo,
- DWORD dwType, // fnID?
- BOOL Ansi)
+NtUserMessageCall( HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ ULONG_PTR ResultInfo,
+ DWORD dwType, // fnID?
+ BOOL Ansi)
{
- LRESULT lResult = 0;
- BOOL Ret = FALSE;
- BOOL BadChk = FALSE;
- PWND Window = NULL;
- USER_REFERENCE_ENTRY Ref;
+ LRESULT lResult = 0;
+ BOOL Ret = FALSE;
+ PWND Window = NULL;
+ USER_REFERENCE_ENTRY Ref;
- UserEnterExclusive();
+ UserEnterExclusive();
- /* Validate input */
- if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd)))
- {
- UserLeave();
- return FALSE;
- }
- switch(dwType)
- {
- case FNID_DEFWINDOWPROC:
- UserRefObjectCo(Window, &Ref);
- lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
- Ret = TRUE;
- UserDerefObjectCo(Window);
- break;
- case FNID_SENDNOTIFYMESSAGE:
- Ret = UserSendNotifyMessage(hWnd, Msg, wParam, lParam);
- break;
- case FNID_BROADCASTSYSTEMMESSAGE:
- {
- BROADCASTPARM parm;
- DWORD_PTR RetVal = 0;
+ /* Validate input */
+ if (hWnd && (hWnd != INVALID_HANDLE_VALUE))
+ {
+ Window = UserGetWindowObject(hWnd);
+ if (!Window)
+ {
+ UserLeave();
+ return FALSE;
+ }
+ }
- if (ResultInfo)
- {
+ switch(dwType)
+ {
+ case FNID_DEFWINDOWPROC:
+ if (Window) UserRefObjectCo(Window, &Ref);
+ lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
+ Ret = TRUE;
+ if (Window) UserDerefObjectCo(Window);
+ break;
+ case FNID_SENDNOTIFYMESSAGE:
+ Ret = UserSendNotifyMessage(hWnd, Msg, wParam, lParam);
+ break;
+ case FNID_BROADCASTSYSTEMMESSAGE:
+ {
+ BROADCASTPARM parm;
+ DWORD_PTR RetVal = 0;
+
+ if (ResultInfo)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite((PVOID)ResultInfo, sizeof(BROADCASTPARM), 1);
+ RtlCopyMemory(&parm, (PVOID)ResultInfo, sizeof(BROADCASTPARM));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ _SEH2_YIELD(break);
+ }
+ _SEH2_END;
+ }
+ else
+ break;
+
+ if ( parm.recipients & BSM_ALLDESKTOPS ||
+ parm.recipients == BSM_ALLCOMPONENTS )
+ {
+ }
+ else if (parm.recipients & BSM_APPLICATIONS)
+ {
+ if (parm.flags & BSF_QUERY)
+ {
+ if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG)
+ {
+ co_IntSendMessageTimeout( HWND_BROADCAST,
+ Msg,
+ wParam,
+ lParam,
+ SMTO_ABORTIFHUNG,
+ 2000,
+ &RetVal);
+ }
+ else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG)
+ {
+ co_IntSendMessageTimeout( HWND_BROADCAST,
+ Msg,
+ wParam,
+ lParam,
+ SMTO_NOTIMEOUTIFNOTHUNG,
+ 2000,
+ &RetVal);
+ }
+ else
+ {
+ co_IntSendMessageTimeout( HWND_BROADCAST,
+ Msg,
+ wParam,
+ lParam,
+ SMTO_NORMAL,
+ 2000,
+ &RetVal);
+ }
+ Ret = RetVal;
+ }
+ else if (parm.flags & BSF_POSTMESSAGE)
+ {
+ Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ }
+ else //Everything else,,,, if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
+ {
+ Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ }
+ }
+ }
+ break;
+ case FNID_SENDMESSAGECALLBACK:
+ {
+ PCALL_BACK_INFO CallBackInfo = (PCALL_BACK_INFO)ResultInfo;
+ ULONG_PTR uResult;
+
+ if (!CallBackInfo)
+ break;
+
+ if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam,
+ CallBackInfo->CallBack, CallBackInfo->Context, &uResult))
+ {
+ DPRINT1("Callback failure!\n");
+ }
+ }
+ break;
+ // CallNextHook bypass.
+ case FNID_CALLWNDPROC:
+ case FNID_CALLWNDPROCRET:
+ {
+ PTHREADINFO pti;
+ PCLIENTINFO ClientInfo;
+ PHOOK NextObj, Hook;
+
+ pti = GetW32ThreadInfo();
+
+ Hook = pti->sphkCurrent;
+
+ if (!Hook) break;
+
+ NextObj = Hook->phkNext;
+ ClientInfo = pti->pClientInfo;
_SEH2_TRY
{
- ProbeForWrite((PVOID)ResultInfo,
- sizeof(BROADCASTPARM),
- 1);
- RtlCopyMemory(&parm, (PVOID)ResultInfo, sizeof(BROADCASTPARM));
+ ClientInfo->phkCurrent = NextObj;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- BadChk = TRUE;
+ ClientInfo = NULL;
}
_SEH2_END;
- if (BadChk) break;
- }
- else
- break;
- if ( parm.recipients & BSM_ALLDESKTOPS ||
- parm.recipients == BSM_ALLCOMPONENTS )
- {
- }
- else if (parm.recipients & BSM_APPLICATIONS)
- {
- if (parm.flags & BSF_QUERY)
+ if (!ClientInfo || !NextObj) break;
+
+ NextObj->phkNext = IntGetNextHook(NextObj);
+
+ if ( Hook->HookId == WH_CALLWNDPROC)
{
- if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG)
- {
- co_IntSendMessageTimeout( HWND_BROADCAST,
- Msg,
- wParam,
- lParam,
- SMTO_ABORTIFHUNG,
- 2000,
- &RetVal);
- }
- else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG)
- {
- co_IntSendMessageTimeout( HWND_BROADCAST,
- Msg,
- wParam,
- lParam,
- SMTO_NOTIMEOUTIFNOTHUNG,
- 2000,
- &RetVal);
- }
- else
- {
- co_IntSendMessageTimeout( HWND_BROADCAST,
- Msg,
- wParam,
- lParam,
- SMTO_NORMAL,
- 2000,
- &RetVal);
- }
+ CWPSTRUCT CWP;
+ CWP.hwnd = hWnd;
+ CWP.message = Msg;
+ CWP.wParam = wParam;
+ CWP.lParam = lParam;
+ DPRINT("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
+
+ lResult = co_IntCallHookProc( Hook->HookId,
+ HC_ACTION,
+ ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
+ (LPARAM)&CWP,
+ Hook->Proc,
+ Hook->Ansi,
+ &Hook->ModuleName);
}
- else if (parm.flags & BSF_POSTMESSAGE)
+ else
{
- Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ CWPRETSTRUCT CWPR;
+ CWPR.hwnd = hWnd;
+ CWPR.message = Msg;
+ CWPR.wParam = wParam;
+ CWPR.lParam = lParam;
+ CWPR.lResult = ClientInfo->dwHookData;
+
+ lResult = co_IntCallHookProc( Hook->HookId,
+ HC_ACTION,
+ ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
+ (LPARAM)&CWPR,
+ Hook->Proc,
+ Hook->Ansi,
+ &Hook->ModuleName);
}
- else if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
- {
- Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
- }
- }
- }
- break;
- case FNID_SENDMESSAGECALLBACK:
- {
- PCALL_BACK_INFO CallBackInfo = (PCALL_BACK_INFO)ResultInfo;
- ULONG_PTR uResult;
+ }
+ break;
+ }
- if (!CallBackInfo)
- break;
-
- if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam,
- CallBackInfo->CallBack, CallBackInfo->Context, &uResult))
- {
- DPRINT1("Callback failure!\n");
- }
- }
- break;
- // CallNextHook bypass.
- case FNID_CALLWNDPROC:
- case FNID_CALLWNDPROCRET:
- {
- PCLIENTINFO ClientInfo = GetWin32ClientInfo();
- PHOOK NextObj, Hook = ClientInfo->phkCurrent;
-
- if (!ClientInfo || !Hook) break;
-
- UserReferenceObject(Hook);
-
- if (Hook->Thread && (Hook->Thread != PsGetCurrentThread()))
- {
- UserDereferenceObject(Hook);
- break;
- }
-
- NextObj = IntGetNextHook(Hook);
- ClientInfo->phkCurrent = NextObj;
-
- if ( Hook->HookId == WH_CALLWNDPROC)
- {
- CWPSTRUCT CWP;
- CWP.hwnd = hWnd;
- CWP.message = Msg;
- CWP.wParam = wParam;
- CWP.lParam = lParam;
- DPRINT("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
-
- lResult = co_IntCallHookProc( Hook->HookId,
- HC_ACTION,
- ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
- (LPARAM)&CWP,
- Hook->Proc,
- Hook->Ansi,
- &Hook->ModuleName);
- }
- else
- {
- CWPRETSTRUCT CWPR;
- CWPR.hwnd = hWnd;
- CWPR.message = Msg;
- CWPR.wParam = wParam;
- CWPR.lParam = lParam;
- CWPR.lResult = ClientInfo->dwHookData;
-
- lResult = co_IntCallHookProc( Hook->HookId,
- HC_ACTION,
- ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
- (LPARAM)&CWPR,
- Hook->Proc,
- Hook->Ansi,
- &Hook->ModuleName);
- }
- UserDereferenceObject(Hook);
- lResult = (LRESULT) NextObj;
- }
- break;
- }
-
- switch(dwType)
- {
- case FNID_DEFWINDOWPROC:
- case FNID_CALLWNDPROC:
- case FNID_CALLWNDPROCRET:
- if (ResultInfo)
- {
+ switch(dwType)
+ {
+ case FNID_DEFWINDOWPROC:
+ case FNID_CALLWNDPROC:
+ case FNID_CALLWNDPROCRET:
+ if (ResultInfo)
+ {
_SEH2_TRY
{
ProbeForWrite((PVOID)ResultInfo, sizeof(LRESULT), 1);
@@ -2654,18 +2264,18 @@ NtUserMessageCall(
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- BadChk = TRUE;
+ Ret = FALSE;
}
- _SEH2_END;
- }
- break;
- default:
- break;
- }
+ _SEH2_END;
+ }
+ break;
+ default:
+ break;
+ }
- UserLeave();
+ UserLeave();
- return BadChk ? FALSE : Ret;
+ return Ret;
}
#define INFINITE 0xFFFFFFFF
@@ -2673,127 +2283,113 @@ NtUserMessageCall(
DWORD
APIENTRY
-NtUserWaitForInputIdle(
- IN HANDLE hProcess,
- IN DWORD dwMilliseconds,
- IN BOOL Unknown2)
+NtUserWaitForInputIdle( IN HANDLE hProcess,
+ IN DWORD dwMilliseconds,
+ IN BOOL Unknown2)
{
- PEPROCESS Process;
- PPROCESSINFO W32Process;
- NTSTATUS Status;
- HANDLE Handles[2];
- LARGE_INTEGER Timeout;
- ULONGLONG StartTime, Run, Elapsed = 0;
+ PEPROCESS Process;
+ PPROCESSINFO W32Process;
+ PTHREADINFO pti;
+ NTSTATUS Status;
+ HANDLE Handles[3];
+ LARGE_INTEGER Timeout;
- UserEnterExclusive();
+ UserEnterExclusive();
- Status = ObReferenceObjectByHandle(hProcess,
- PROCESS_QUERY_INFORMATION,
- PsProcessType,
- UserMode,
- (PVOID*)&Process,
- NULL);
+ Status = ObReferenceObjectByHandle(hProcess,
+ PROCESS_QUERY_INFORMATION,
+ PsProcessType,
+ UserMode,
+ (PVOID*)&Process,
+ NULL);
- if (!NT_SUCCESS(Status))
- {
- UserLeave();
- SetLastNtError(Status);
- return WAIT_FAILED;
- }
-
- W32Process = (PPROCESSINFO)Process->Win32Process;
- if (!W32Process)
- {
- ObDereferenceObject(Process);
- UserLeave();
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return WAIT_FAILED;
- }
-
- EngCreateEvent((PEVENT *)&W32Process->InputIdleEvent);
-
- Handles[0] = Process;
- Handles[1] = W32Process->InputIdleEvent;
-
- if (!Handles[1])
- {
- ObDereferenceObject(Process);
- UserLeave();
- return STATUS_SUCCESS; /* no event to wait on */
- }
-
- StartTime = EngGetTickCount();
-
- Run = dwMilliseconds;
-
- DPRINT("WFII: waiting for %p\n", Handles[1] );
- do
- {
- Timeout.QuadPart = Run - Elapsed;
- UserLeave();
- Status = KeWaitForMultipleObjects( 2,
- Handles,
- WaitAny,
- UserRequest,
- UserMode,
- FALSE,
- dwMilliseconds == INFINITE ? NULL : &Timeout,
- NULL);
- UserEnterExclusive();
-
- if (!NT_SUCCESS(Status))
- {
+ if (!NT_SUCCESS(Status))
+ {
+ UserLeave();
SetLastNtError(Status);
- Status = WAIT_FAILED;
- goto WaitExit;
- }
+ return WAIT_FAILED;
+ }
- switch (Status)
- {
- case STATUS_WAIT_0:
- Status = WAIT_FAILED;
- goto WaitExit;
+ pti = PsGetCurrentThreadWin32Thread();
- case STATUS_WAIT_2:
+ W32Process = (PPROCESSINFO)Process->Win32Process;
+
+ if ( PsGetProcessExitProcessCalled(Process) ||
+ !W32Process ||
+ pti->ppi == W32Process)
+ {
+ ObDereferenceObject(Process);
+ UserLeave();
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return WAIT_FAILED;
+ }
+
+ Handles[0] = Process;
+ Handles[1] = W32Process->InputIdleEvent;
+ Handles[2] = pti->MessageQueue->NewMessages; // pEventQueueServer; IntMsqSetWakeMask returns hEventQueueClient
+
+ if (!Handles[1])
+ {
+ ObDereferenceObject(Process);
+ UserLeave();
+ return STATUS_SUCCESS; /* no event to wait on */
+ }
+
+ if (dwMilliseconds != INFINITE)
+ Timeout.QuadPart = (LONGLONG) dwMilliseconds * (LONGLONG) -10000;
+
+ DPRINT("WFII: ppi 0x%x\n",W32Process);
+ DPRINT("WFII: waiting for %p\n", Handles[1] );
+ do
+ {
+ UserLeave();
+ Status = KeWaitForMultipleObjects( 3,
+ Handles,
+ WaitAny,
+ UserRequest,
+ UserMode,
+ FALSE,
+ dwMilliseconds == INFINITE ? NULL : &Timeout,
+ NULL);
+ UserEnterExclusive();
+
+ if (!NT_SUCCESS(Status))
{
- USER_MESSAGE Msg;
- co_IntPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
- break;
+ SetLastNtError(Status);
+ Status = WAIT_FAILED;
+ goto WaitExit;
}
- case STATUS_USER_APC:
- case STATUS_ALERTED:
+ switch (Status)
+ {
+ case STATUS_WAIT_0:
+ goto WaitExit;
+
+ case STATUS_WAIT_2:
+ {
+ MSG Msg;
+ co_IntPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
+ DPRINT1("WFII: WAIT 2\n");
+ }
+ break;
+
case STATUS_TIMEOUT:
- DPRINT1("WFII: timeout\n");
- Status = STATUS_TIMEOUT;
- goto WaitExit;
+ DPRINT1("WFII: timeout\n");
+ case WAIT_FAILED:
+ goto WaitExit;
default:
- DPRINT1("WFII: finished\n");
- Status = STATUS_SUCCESS;
- goto WaitExit;
- }
-
- if (dwMilliseconds != INFINITE)
- {
- Elapsed = EngGetTickCount() - StartTime;
-
- if (Elapsed > Run)
- Status = STATUS_TIMEOUT;
- break;
- }
- }
- while (1);
+ DPRINT1("WFII: finished\n");
+ Status = STATUS_SUCCESS;
+ goto WaitExit;
+ }
+ }
+ while (TRUE);
WaitExit:
- if (W32Process->InputIdleEvent)
- {
- EngFreeMem((PVOID)W32Process->InputIdleEvent);
- W32Process->InputIdleEvent = NULL;
- }
- ObDereferenceObject(Process);
- UserLeave();
- return Status;
+ ObDereferenceObject(Process);
+ UserLeave();
+ return Status;
}
/* EOF */
diff --git a/subsystems/win32/win32k/ntuser/metric.c b/subsystems/win32/win32k/ntuser/metric.c
index be2b1a10367..e8829570a16 100644
--- a/subsystems/win32/win32k/ntuser/metric.c
+++ b/subsystems/win32/win32k/ntuser/metric.c
@@ -24,9 +24,19 @@ FASTCALL
InitMetrics(VOID)
{
INT *piSysMet;
+ ULONG Width, Height;
- ULONG Width = pPrimarySurface->gdiinfo.ulHorzRes;
- ULONG Height = pPrimarySurface->gdiinfo.ulVertRes;
+ /* FIXME: HACK, due to missing PDEV on first init */
+ if (!pPrimarySurface)
+ {
+ Width = 640;
+ Height = 480;
+ }
+ else
+ {
+ Width = pPrimarySurface->gdiinfo.ulHorzRes;
+ Height = pPrimarySurface->gdiinfo.ulVertRes;
+ }
piSysMet = gpsi->aiSysMet;
diff --git a/subsystems/win32/win32k/ntuser/misc.c b/subsystems/win32/win32k/ntuser/misc.c
index 48ef50b7ae6..d884d0c145f 100644
--- a/subsystems/win32/win32k/ntuser/misc.c
+++ b/subsystems/win32/win32k/ntuser/misc.c
@@ -125,7 +125,7 @@ NtUserGetThreadState(
break;
case THREADSTATE_GETINPUTSTATE:
- ret = HIWORD(IntGetQueueStatus(FALSE)) & (QS_KEY | QS_MOUSEBUTTON);
+ ret = LOWORD(IntGetQueueStatus(QS_POSTMESSAGE|QS_TIMER|QS_PAINT|QS_SENDMESSAGE|QS_INPUT)) & (QS_KEY | QS_MOUSEBUTTON);
break;
}
@@ -472,8 +472,6 @@ GetW32ThreadInfo(VOID)
/* initialize it */
pti->ppi = ppi = GetW32ProcessInfo();
- pti->pcti = &pti->cti; // FIXME Need to set it in desktop.c!
-
if (pti->rpdesk != NULL)
{
pti->pDeskInfo = pti->rpdesk->pDeskInfo;
@@ -494,7 +492,6 @@ GetW32ThreadInfo(VOID)
Teb->Win32ThreadInfo = (PW32THREAD) pti;
- pci->pClientThreadInfo = NULL; // FIXME Need to set it in desktop.c!
pci->ppi = ppi;
pci->fsHooks = pti->fsHooks;
if (pti->KeyboardLayout) pci->hKL = pti->KeyboardLayout->hkl;
@@ -506,6 +503,11 @@ GetW32ThreadInfo(VOID)
pci->pDeskInfo = (PVOID)((ULONG_PTR)pti->pDeskInfo - pci->ulClientDelta);
}
+ if (pti->pcti && pci->pDeskInfo)
+ pci->pClientThreadInfo = (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta);
+ else
+ pci->pClientThreadInfo = NULL;
+
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
diff --git a/subsystems/win32/win32k/ntuser/monitor.c b/subsystems/win32/win32k/ntuser/monitor.c
index 2f587bfd492..b766e951da9 100644
--- a/subsystems/win32/win32k/ntuser/monitor.c
+++ b/subsystems/win32/win32k/ntuser/monitor.c
@@ -1,21 +1,4 @@
/*
- * ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Monitor support
@@ -45,35 +28,27 @@ static PMONITOR gMonitorList = NULL;
/* INITALIZATION FUNCTIONS ****************************************************/
+INIT_FUNCTION
NTSTATUS
+NTAPI
InitMonitorImpl()
{
- DPRINT("Initializing monitor implementation...\n");
+ DPRINT("Initializing monitor implementation...\n");
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
NTSTATUS
CleanupMonitorImpl()
{
- DPRINT("Cleaning up monitor implementation...\n");
- /* FIXME: Destroy monitor objects? */
+ DPRINT("Cleaning up monitor implementation...\n");
+ /* FIXME: Destroy monitor objects? */
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
/* PRIVATE FUNCTIONS **********************************************************/
-#ifndef MIN
-# define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef MAX
-# define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef ABS
-# define ABS(a) ((a) < (0) ? (-(a)) : (a))
-#endif
-
/* IntCreateMonitorObject
*
* Creates a MONITOR
@@ -86,18 +61,18 @@ static
PMONITOR
IntCreateMonitorObject()
{
- HANDLE Handle;
- PMONITOR Monitor;
+ HANDLE Handle;
+ PMONITOR Monitor;
- Monitor = UserCreateObject(gHandleTable, NULL, &Handle, otMonitor, sizeof (MONITOR));
- if (Monitor == NULL)
- {
- return NULL;
- }
+ Monitor = UserCreateObject(gHandleTable, NULL, &Handle, otMonitor, sizeof (MONITOR));
+ if (Monitor == NULL)
+ {
+ return NULL;
+ }
- ExInitializeFastMutex(&Monitor->Lock);
+ ExInitializeFastMutex(&Monitor->Lock);
- return Monitor;
+ return Monitor;
}
/* IntDestroyMonitorObject
@@ -114,33 +89,32 @@ static
void
IntDestroyMonitorObject(IN PMONITOR pMonitor)
{
- RtlFreeUnicodeString(&pMonitor->DeviceName);
- UserDereferenceObject(pMonitor);
+ RtlFreeUnicodeString(&pMonitor->DeviceName);
+ UserDereferenceObject(pMonitor);
}
PMONITOR FASTCALL
UserGetMonitorObject(IN HMONITOR hMonitor)
{
- PMONITOR Monitor;
+ PMONITOR Monitor;
- if (!hMonitor)
- {
- SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
- return NULL;
- }
+ if (!hMonitor)
+ {
+ SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
+ return NULL;
+ }
+ Monitor = (PMONITOR)UserGetObject(gHandleTable, hMonitor, otMonitor);
+ if (!Monitor)
+ {
+ SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
+ return NULL;
+ }
- Monitor = (PMONITOR)UserGetObject(gHandleTable, hMonitor, otMonitor);
- if (!Monitor)
- {
- SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
- return NULL;
- }
+ ASSERT(Monitor->head.cLockObj >= 0);
- ASSERT(Monitor->head.cLockObj >= 0);
-
- return Monitor;
+ return Monitor;
}
@@ -160,58 +134,58 @@ NTSTATUS
IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
IN ULONG DisplayNumber)
{
- PMONITOR Monitor;
- WCHAR Buffer[CCHDEVICENAME];
+ PMONITOR Monitor;
+ WCHAR Buffer[CCHDEVICENAME];
- DPRINT("Attaching monitor...\n");
+ DPRINT("Attaching monitor...\n");
- /* create new monitor object */
- Monitor = IntCreateMonitorObject();
- if (Monitor == NULL)
- {
- DPRINT("Couldnt create monitor object\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ /* create new monitor object */
+ Monitor = IntCreateMonitorObject();
+ if (Monitor == NULL)
+ {
+ DPRINT("Couldnt create monitor object\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- _snwprintf(Buffer, CCHDEVICENAME, L"\\\\.\\DISPLAY%d", DisplayNumber + 1);
- if (!RtlCreateUnicodeString(&Monitor->DeviceName, Buffer))
- {
- DPRINT("Couldn't duplicate monitor name!\n");
- UserDereferenceObject(Monitor);
- UserDeleteObject(UserHMGetHandle(Monitor), otMonitor);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ _snwprintf(Buffer, CCHDEVICENAME, L"\\\\.\\DISPLAY%d", DisplayNumber + 1);
+ if (!RtlCreateUnicodeString(&Monitor->DeviceName, Buffer))
+ {
+ DPRINT("Couldn't duplicate monitor name!\n");
+ UserDereferenceObject(Monitor);
+ UserDeleteObject(UserHMGetHandle(Monitor), otMonitor);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- Monitor->GdiDevice = pGdiDevice;
- Monitor->rcMonitor.left = 0;
- Monitor->rcMonitor.top = 0;
- Monitor->rcMonitor.right = Monitor->rcMonitor.left + pGdiDevice->gdiinfo.ulHorzRes;
- Monitor->rcMonitor.bottom = Monitor->rcMonitor.top + pGdiDevice->gdiinfo.ulVertRes;
- Monitor->rcWork = Monitor->rcMonitor;
- Monitor->cWndStack = 0;
+ Monitor->GdiDevice = pGdiDevice;
+ Monitor->rcMonitor.left = 0;
+ Monitor->rcMonitor.top = 0;
+ Monitor->rcMonitor.right = Monitor->rcMonitor.left + pGdiDevice->gdiinfo.ulHorzRes;
+ Monitor->rcMonitor.bottom = Monitor->rcMonitor.top + pGdiDevice->gdiinfo.ulVertRes;
+ Monitor->rcWork = Monitor->rcMonitor;
+ Monitor->cWndStack = 0;
- Monitor->hrgnMonitor = IntSysCreateRectRgnIndirect( &Monitor->rcMonitor );
+ Monitor->hrgnMonitor = IntSysCreateRectRgnIndirect( &Monitor->rcMonitor );
- IntGdiSetRegionOwner(Monitor->hrgnMonitor, GDI_OBJ_HMGR_PUBLIC);
+ IntGdiSetRegionOwner(Monitor->hrgnMonitor, GDI_OBJ_HMGR_PUBLIC);
- if (gMonitorList == NULL)
- {
- DPRINT("Primary monitor is beeing attached\n");
- Monitor->IsPrimary = TRUE;
- gMonitorList = Monitor;
- }
- else
- {
- PMONITOR p;
- DPRINT("Additional monitor is beeing attached\n");
- for (p = gMonitorList; p->Next != NULL; p = p->Next)
- {
- p->Next = Monitor;
- }
- Monitor->Prev = p;
- }
+ if (gMonitorList == NULL)
+ {
+ DPRINT("Primary monitor is beeing attached\n");
+ Monitor->IsPrimary = TRUE;
+ gMonitorList = Monitor;
+ }
+ else
+ {
+ PMONITOR p;
+ DPRINT("Additional monitor is beeing attached\n");
+ for (p = gMonitorList; p->Next != NULL; p = p->Next)
+ {
+ p->Next = Monitor;
+ }
+ Monitor->Prev = p;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
/* IntDetachMonitor
@@ -228,48 +202,48 @@ IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
NTSTATUS
IntDetachMonitor(IN PDEVOBJ *pGdiDevice)
{
- PMONITOR Monitor;
+ PMONITOR Monitor;
- for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
- {
- if (Monitor->GdiDevice == pGdiDevice)
- break;
- }
+ for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
+ {
+ if (Monitor->GdiDevice == pGdiDevice)
+ break;
+ }
- if (Monitor == NULL)
- {
- /* no monitor for given device found */
- return STATUS_INVALID_PARAMETER;
- }
+ if (Monitor == NULL)
+ {
+ /* no monitor for given device found */
+ return STATUS_INVALID_PARAMETER;
+ }
- if (Monitor->IsPrimary && (Monitor->Next != NULL || Monitor->Prev != NULL))
- {
- PMONITOR NewPrimaryMonitor = (Monitor->Prev != NULL) ? (Monitor->Prev) : (Monitor->Next);
+ if (Monitor->IsPrimary && (Monitor->Next != NULL || Monitor->Prev != NULL))
+ {
+ PMONITOR NewPrimaryMonitor = (Monitor->Prev != NULL) ? (Monitor->Prev) : (Monitor->Next);
- ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&NewPrimaryMonitor->Lock);
- NewPrimaryMonitor->IsPrimary = TRUE;
- ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&NewPrimaryMonitor->Lock);
- }
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&NewPrimaryMonitor->Lock);
+ NewPrimaryMonitor->IsPrimary = TRUE;
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&NewPrimaryMonitor->Lock);
+ }
- if (gMonitorList == Monitor)
- {
- gMonitorList = Monitor->Next;
- if (Monitor->Next != NULL)
- Monitor->Next->Prev = NULL;
- }
- else
- {
- Monitor->Prev->Next = Monitor->Next;
- if (Monitor->Next != NULL)
- Monitor->Next->Prev = Monitor->Prev;
- }
+ if (gMonitorList == Monitor)
+ {
+ gMonitorList = Monitor->Next;
+ if (Monitor->Next != NULL)
+ Monitor->Next->Prev = NULL;
+ }
+ else
+ {
+ Monitor->Prev->Next = Monitor->Next;
+ if (Monitor->Next != NULL)
+ Monitor->Next->Prev = Monitor->Prev;
+ }
- if (Monitor->hrgnMonitor)
- REGION_FreeRgnByHandle(Monitor->hrgnMonitor);
+ if (Monitor->hrgnMonitor)
+ REGION_FreeRgnByHandle(Monitor->hrgnMonitor);
- IntDestroyMonitorObject(Monitor);
+ IntDestroyMonitorObject(Monitor);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
/* IntGetPrimaryMonitor
@@ -283,16 +257,16 @@ PMONITOR
FASTCALL
IntGetPrimaryMonitor()
{
- PMONITOR Monitor;
+ PMONITOR Monitor;
- for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
- {
- /* FIXME: I guess locking the monitor is not neccessary to read 1 int */
- if (Monitor->IsPrimary)
- break;
- }
+ for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
+ {
+ /* FIXME: I guess locking the monitor is not neccessary to read 1 int */
+ if (Monitor->IsPrimary)
+ break;
+ }
- return Monitor;
+ return Monitor;
}
/* IntGetMonitorsFromRect
@@ -334,99 +308,95 @@ IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
OPTIONAL IN DWORD listSize,
OPTIONAL IN DWORD flags)
{
- PMONITOR Monitor, NearestMonitor = NULL, PrimaryMonitor = NULL;
- UINT iCount = 0;
- LONG iNearestDistanceX = 0x7fffffff, iNearestDistanceY = 0x7fffffff;
+ PMONITOR Monitor, NearestMonitor = NULL, PrimaryMonitor = NULL;
+ UINT iCount = 0;
+ ULONG iNearestDistance = 0xffffffff;
- /* find monitors which intersect the rectangle */
- for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
- {
- RECTL MonitorRect, IntersectionRect;
+ /* Find monitors which intersect the rectangle */
+ for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
+ {
+ RECTL MonitorRect, IntersectionRect;
- ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Monitor->Lock);
- MonitorRect = Monitor->rcMonitor;
- ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Monitor->Lock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Monitor->Lock);
+ MonitorRect = Monitor->rcMonitor;
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Monitor->Lock);
- DPRINT("MonitorRect: left = %d, top = %d, right = %d, bottom = %d\n",
- MonitorRect.left, MonitorRect.top, MonitorRect.right, MonitorRect.bottom);
+ DPRINT("MonitorRect: left = %d, top = %d, right = %d, bottom = %d\n",
+ MonitorRect.left, MonitorRect.top, MonitorRect.right, MonitorRect.bottom);
- if (flags == MONITOR_DEFAULTTOPRIMARY && Monitor->IsPrimary)
- {
- PrimaryMonitor = Monitor;
- }
+ if (flags == MONITOR_DEFAULTTOPRIMARY && Monitor->IsPrimary)
+ {
+ PrimaryMonitor = Monitor;
+ }
- if (pRect != NULL)
- {
- BOOL intersects = TRUE;
+ /* Check if a rect is given */
+ if (pRect == NULL)
+ {
+ /* No rect given, so use the full monitor rect */
+ IntersectionRect = MonitorRect;
+ }
- /* check if the rect intersects the monitor */
- if ((pRect->right < MonitorRect.left) || (pRect->left > MonitorRect.right) ||
- (pRect->bottom < MonitorRect.top) || (pRect->top > MonitorRect.bottom))
- {
- intersects = FALSE;
- }
-
- if (flags == MONITOR_DEFAULTTONEAREST && !intersects)
- {
- INT distanceX, distanceY;
-
- distanceX = MIN(ABS(MonitorRect.left - pRect->right),
- ABS(pRect->left - MonitorRect.right));
- distanceY = MIN(ABS(MonitorRect.top - pRect->bottom),
- ABS(pRect->top - MonitorRect.bottom));
-
- if (((distanceX < iNearestDistanceX) && (distanceY <= iNearestDistanceY)) ||
- ((distanceX <= iNearestDistanceX) && (distanceY < iNearestDistanceY)))
+ /* We have a rect, calculate intersection */
+ else if (!RECTL_bIntersectRect(&IntersectionRect, &MonitorRect, pRect))
+ {
+ /* Rects did not intersect */
+ if (flags == MONITOR_DEFAULTTONEAREST)
{
- iNearestDistanceX = distanceX;
- iNearestDistanceY = distanceY;
- NearestMonitor = Monitor;
+ ULONG cx, cy, iDistance;
+
+ /* Get x and y distance */
+ cx = min(abs(MonitorRect.left - pRect->right),
+ abs(pRect->left - MonitorRect.right));
+ cy = min(abs(MonitorRect.top - pRect->bottom),
+ abs(pRect->top - MonitorRect.bottom));
+
+ /* Calculate distance square */
+ iDistance = cx * cx + cy * cy;
+
+ /* Check if this is the new nearest monitor */
+ if (iDistance < iNearestDistance)
+ {
+ iNearestDistance = iDistance;
+ NearestMonitor = Monitor;
+ }
}
- }
- if (!intersects)
continue;
+ }
- /* calculate intersection */
- IntersectionRect.left = MAX(MonitorRect.left, pRect->left);
- IntersectionRect.top = MAX(MonitorRect.top, pRect->top);
- IntersectionRect.right = MIN(MonitorRect.right, pRect->right);
- IntersectionRect.bottom = MIN(MonitorRect.bottom, pRect->bottom);
- }
- else
- {
- IntersectionRect = MonitorRect;
- }
+ /* Check if there's space in the buffer */
+ if (iCount < listSize)
+ {
+ if (hMonitorList != NULL)
+ hMonitorList[iCount] = UserHMGetHandle(Monitor);
+ if (monitorRectList != NULL)
+ monitorRectList[iCount] = IntersectionRect;
+ }
+
+ /* Increase count of found monitors */
+ iCount++;
+ }
- if (iCount < listSize)
- {
- if (hMonitorList != NULL)
- hMonitorList[iCount] = UserHMGetHandle(Monitor);
- if (monitorRectList != NULL)
- monitorRectList[iCount] = IntersectionRect;
- }
- iCount++;
- }
+ /* Found nothing intersecting? */
+ if (iCount == 0)
+ {
+ /* Check if we shall default to the nearest monitor */
+ if (flags == MONITOR_DEFAULTTONEAREST && NearestMonitor)
+ {
+ if (hMonitorList && listSize > 0)
+ hMonitorList[iCount] = UserHMGetHandle(NearestMonitor);
+ iCount++;
+ }
+ /* Check if we shall default to the primary monitor */
+ else if (flags == MONITOR_DEFAULTTOPRIMARY && PrimaryMonitor)
+ {
+ if (hMonitorList != NULL && listSize > 0)
+ hMonitorList[iCount] = UserHMGetHandle(PrimaryMonitor);
+ iCount++;
+ }
+ }
- if (iCount == 0 && flags == MONITOR_DEFAULTTONEAREST)
- {
- if (iCount < listSize)
- {
- if (hMonitorList != NULL)
- hMonitorList[iCount] = UserHMGetHandle(NearestMonitor);
- }
- iCount++;
- }
- else if (iCount == 0 && flags == MONITOR_DEFAULTTOPRIMARY)
- {
- if (iCount < listSize)
- {
- if (hMonitorList != NULL)
- hMonitorList[iCount] = UserHMGetHandle(PrimaryMonitor);
- }
- iCount++;
- }
- return iCount;
+ return iCount;
}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -464,146 +434,147 @@ IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
INT
APIENTRY
NtUserEnumDisplayMonitors(
- OPTIONAL IN HDC hDC,
- OPTIONAL IN LPCRECTL pRect,
- OPTIONAL OUT HMONITOR *hMonitorList,
- OPTIONAL OUT PRECTL monitorRectList,
- OPTIONAL IN DWORD listSize)
+ OPTIONAL IN HDC hDC,
+ OPTIONAL IN LPCRECTL pRect,
+ OPTIONAL OUT HMONITOR *hMonitorList,
+ OPTIONAL OUT PRECTL monitorRectList,
+ OPTIONAL IN DWORD listSize)
{
- INT numMonitors, i;
- HMONITOR *safeHMonitorList = NULL;
- PRECTL safeRectList = NULL;
- RECTL rect, *myRect;
- RECTL dcRect;
- NTSTATUS status;
+ INT numMonitors, i;
+ HMONITOR *safeHMonitorList = NULL;
+ PRECTL safeRectList = NULL;
+ RECTL rect, *myRect;
+ RECTL dcRect;
+ NTSTATUS status;
- /* get rect */
- if (pRect != NULL)
- {
- status = MmCopyFromCaller(&rect, pRect, sizeof (RECT));
- if (!NT_SUCCESS(status))
- {
- DPRINT("MmCopyFromCaller() failed!\n");
- SetLastNtError(status);
- return -1;
- }
- }
+ /* get rect */
+ if (pRect != NULL)
+ {
+ status = MmCopyFromCaller(&rect, pRect, sizeof (RECT));
+ if (!NT_SUCCESS(status))
+ {
+ DPRINT("MmCopyFromCaller() failed!\n");
+ SetLastNtError(status);
+ return -1;
+ }
+ }
- if (hDC != NULL)
- {
- PDC dc;
- INT regionType;
+ if (hDC != NULL)
+ {
+ PDC dc;
+ INT regionType;
- /* get visible region bounding rect */
- dc = DC_LockDc(hDC);
- if (dc == NULL)
- {
- DPRINT("DC_LockDc() failed!\n");
- /* FIXME: setlasterror? */
- return -1;
- }
- regionType = REGION_GetRgnBox(dc->prgnVis, &dcRect);
- DC_UnlockDc(dc);
+ /* get visible region bounding rect */
+ dc = DC_LockDc(hDC);
+ if (dc == NULL)
+ {
+ DPRINT("DC_LockDc() failed!\n");
+ /* FIXME: setlasterror? */
+ return -1;
+ }
+ regionType = REGION_GetRgnBox(dc->prgnVis, &dcRect);
+ DC_UnlockDc(dc);
- if (regionType == 0)
- {
- DPRINT("NtGdiGetRgnBox() failed!\n");
- return -1;
- }
- if (regionType == NULLREGION)
- return 0;
- if (regionType == COMPLEXREGION)
- { /* TODO: warning */
- }
+ if (regionType == 0)
+ {
+ DPRINT("NtGdiGetRgnBox() failed!\n");
+ return -1;
+ }
+ if (regionType == NULLREGION)
+ return 0;
+ if (regionType == COMPLEXREGION)
+ {
+ /* TODO: warning */
+ }
- /* if hDC and pRect are given the area of interest is pRect with
- coordinate origin at the DC position */
- if (pRect != NULL)
- {
- rect.left += dcRect.left;
- rect.right += dcRect.left;
- rect.top += dcRect.top;
- rect.bottom += dcRect.top;
- }
- /* if hDC is given and pRect is not the area of interest is the
- bounding rect of hDC */
- else
- {
- rect = dcRect;
- }
- }
+ /* if hDC and pRect are given the area of interest is pRect with
+ coordinate origin at the DC position */
+ if (pRect != NULL)
+ {
+ rect.left += dcRect.left;
+ rect.right += dcRect.left;
+ rect.top += dcRect.top;
+ rect.bottom += dcRect.top;
+ }
+ /* if hDC is given and pRect is not the area of interest is the
+ bounding rect of hDC */
+ else
+ {
+ rect = dcRect;
+ }
+ }
- if (hDC == NULL && pRect == NULL)
- myRect = NULL;
- else
- myRect = ▭
+ if (hDC == NULL && pRect == NULL)
+ myRect = NULL;
+ else
+ myRect = ▭
- /* find intersecting monitors */
- numMonitors = IntGetMonitorsFromRect(myRect, NULL, NULL, 0, 0);
- if (numMonitors == 0 || listSize == 0 ||
- (hMonitorList == NULL && monitorRectList == NULL))
- {
- DPRINT("numMonitors = %d\n", numMonitors);
- return numMonitors;
- }
+ /* find intersecting monitors */
+ numMonitors = IntGetMonitorsFromRect(myRect, NULL, NULL, 0, 0);
+ if (numMonitors == 0 || listSize == 0 ||
+ (hMonitorList == NULL && monitorRectList == NULL))
+ {
+ DPRINT("numMonitors = %d\n", numMonitors);
+ return numMonitors;
+ }
- if (hMonitorList != NULL && listSize != 0)
- {
- safeHMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * listSize, USERTAG_MONITORRECTS);
- if (safeHMonitorList == NULL)
- {
- /* FIXME: SetLastWin32Error? */
- return -1;
- }
- }
- if (monitorRectList != NULL && listSize != 0)
- {
- safeRectList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * listSize, USERTAG_MONITORRECTS);
- if (safeRectList == NULL)
- {
- ExFreePoolWithTag(safeHMonitorList, USERTAG_MONITORRECTS);
- /* FIXME: SetLastWin32Error? */
- return -1;
- }
- }
+ if (hMonitorList != NULL && listSize != 0)
+ {
+ safeHMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * listSize, USERTAG_MONITORRECTS);
+ if (safeHMonitorList == NULL)
+ {
+ /* FIXME: SetLastWin32Error? */
+ return -1;
+ }
+ }
+ if (monitorRectList != NULL && listSize != 0)
+ {
+ safeRectList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * listSize, USERTAG_MONITORRECTS);
+ if (safeRectList == NULL)
+ {
+ ExFreePoolWithTag(safeHMonitorList, USERTAG_MONITORRECTS);
+ /* FIXME: SetLastWin32Error? */
+ return -1;
+ }
+ }
- /* get intersecting monitors */
- numMonitors = IntGetMonitorsFromRect(myRect, safeHMonitorList, safeRectList,
- listSize, 0 );
+ /* get intersecting monitors */
+ numMonitors = IntGetMonitorsFromRect(myRect, safeHMonitorList, safeRectList,
+ listSize, 0 );
- if (hDC != NULL && pRect != NULL && safeRectList != NULL)
- for (i = 0; i < numMonitors; i++)
- {
- safeRectList[i].left -= dcRect.left;
- safeRectList[i].right -= dcRect.left;
- safeRectList[i].top -= dcRect.top;
- safeRectList[i].bottom -= dcRect.top;
- }
+ if (hDC != NULL && pRect != NULL && safeRectList != NULL)
+ for (i = 0; i < numMonitors; i++)
+ {
+ safeRectList[i].left -= dcRect.left;
+ safeRectList[i].right -= dcRect.left;
+ safeRectList[i].top -= dcRect.top;
+ safeRectList[i].bottom -= dcRect.top;
+ }
- /* output result */
- if (hMonitorList != NULL && listSize != 0)
- {
- status = MmCopyToCaller(hMonitorList, safeHMonitorList, sizeof (HMONITOR) * listSize);
- ExFreePool(safeHMonitorList);
- if (!NT_SUCCESS(status))
- {
- ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
- SetLastNtError(status);
- return -1;
- }
- }
- if (monitorRectList != NULL && listSize != 0)
- {
- status = MmCopyToCaller(monitorRectList, safeRectList, sizeof (RECT) * listSize);
- ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
- if (!NT_SUCCESS(status))
- {
- SetLastNtError(status);
- return -1;
- }
- }
+ /* output result */
+ if (hMonitorList != NULL && listSize != 0)
+ {
+ status = MmCopyToCaller(hMonitorList, safeHMonitorList, sizeof (HMONITOR) * listSize);
+ ExFreePool(safeHMonitorList);
+ if (!NT_SUCCESS(status))
+ {
+ ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
+ SetLastNtError(status);
+ return -1;
+ }
+ }
+ if (monitorRectList != NULL && listSize != 0)
+ {
+ status = MmCopyToCaller(monitorRectList, safeRectList, sizeof (RECT) * listSize);
+ ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
+ if (!NT_SUCCESS(status))
+ {
+ SetLastNtError(status);
+ return -1;
+ }
+ }
- return numMonitors;
+ return numMonitors;
}
/* NtUserGetMonitorInfo
@@ -633,81 +604,81 @@ NtUserEnumDisplayMonitors(
BOOL
APIENTRY
NtUserGetMonitorInfo(
- IN HMONITOR hMonitor,
- OUT LPMONITORINFO pMonitorInfo)
+ IN HMONITOR hMonitor,
+ OUT LPMONITORINFO pMonitorInfo)
{
- PMONITOR Monitor;
- MONITORINFOEXW MonitorInfo;
- NTSTATUS Status;
- DECLARE_RETURN(BOOL);
+ PMONITOR Monitor;
+ MONITORINFOEXW MonitorInfo;
+ NTSTATUS Status;
+ DECLARE_RETURN(BOOL);
- DPRINT("Enter NtUserGetMonitorInfo\n");
- UserEnterShared();
+ DPRINT("Enter NtUserGetMonitorInfo\n");
+ UserEnterShared();
- /* get monitor object */
- if (!(Monitor = UserGetMonitorObject(hMonitor)))
- {
- DPRINT("Couldnt find monitor 0x%lx\n", hMonitor);
- RETURN(FALSE);
- }
+ /* get monitor object */
+ if (!(Monitor = UserGetMonitorObject(hMonitor)))
+ {
+ DPRINT("Couldnt find monitor 0x%lx\n", hMonitor);
+ RETURN(FALSE);
+ }
- if(pMonitorInfo == NULL)
- {
- SetLastNtError(STATUS_INVALID_PARAMETER);
- RETURN(FALSE);
- }
+ if(pMonitorInfo == NULL)
+ {
+ SetLastNtError(STATUS_INVALID_PARAMETER);
+ RETURN(FALSE);
+ }
- /* get size of pMonitorInfo */
- Status = MmCopyFromCaller(&MonitorInfo.cbSize, &pMonitorInfo->cbSize, sizeof (MonitorInfo.cbSize));
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN(FALSE);
- }
- if ((MonitorInfo.cbSize != sizeof (MONITORINFO)) &&
- (MonitorInfo.cbSize != sizeof (MONITORINFOEXW)))
- {
- SetLastNtError(STATUS_INVALID_PARAMETER);
- RETURN(FALSE);
- }
+ /* get size of pMonitorInfo */
+ Status = MmCopyFromCaller(&MonitorInfo.cbSize, &pMonitorInfo->cbSize, sizeof (MonitorInfo.cbSize));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN(FALSE);
+ }
+ if ((MonitorInfo.cbSize != sizeof (MONITORINFO)) &&
+ (MonitorInfo.cbSize != sizeof (MONITORINFOEXW)))
+ {
+ SetLastNtError(STATUS_INVALID_PARAMETER);
+ RETURN(FALSE);
+ }
- /* fill monitor info */
- MonitorInfo.rcMonitor = Monitor->rcMonitor;
- MonitorInfo.rcWork = Monitor->rcWork;
- MonitorInfo.dwFlags = 0;
+ /* fill monitor info */
+ MonitorInfo.rcMonitor = Monitor->rcMonitor;
+ MonitorInfo.rcWork = Monitor->rcWork;
+ MonitorInfo.dwFlags = 0;
- if (Monitor->IsPrimary)
- MonitorInfo.dwFlags |= MONITORINFOF_PRIMARY;
+ if (Monitor->IsPrimary)
+ MonitorInfo.dwFlags |= MONITORINFOF_PRIMARY;
- /* fill device name */
- if (MonitorInfo.cbSize == sizeof (MONITORINFOEXW))
- {
- WCHAR nul = L'\0';
- INT len = Monitor->DeviceName.Length;
- if (len >= CCHDEVICENAME * sizeof (WCHAR))
- len = (CCHDEVICENAME - 1) * sizeof (WCHAR);
+ /* fill device name */
+ if (MonitorInfo.cbSize == sizeof (MONITORINFOEXW))
+ {
+ WCHAR nul = L'\0';
+ INT len = Monitor->DeviceName.Length;
+ if (len >= CCHDEVICENAME * sizeof (WCHAR))
+ len = (CCHDEVICENAME - 1) * sizeof (WCHAR);
- memcpy(MonitorInfo.szDevice, Monitor->DeviceName.Buffer, len);
- memcpy(MonitorInfo.szDevice + (len / sizeof (WCHAR)), &nul, sizeof (WCHAR));
- }
+ memcpy(MonitorInfo.szDevice, Monitor->DeviceName.Buffer, len);
+ memcpy(MonitorInfo.szDevice + (len / sizeof (WCHAR)), &nul, sizeof (WCHAR));
+ }
- /* output data */
- Status = MmCopyToCaller(pMonitorInfo, &MonitorInfo, MonitorInfo.cbSize);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("GetMonitorInfo: MmCopyToCaller failed\n");
- SetLastNtError(Status);
- RETURN(FALSE);
- }
+ /* output data */
+ Status = MmCopyToCaller(pMonitorInfo, &MonitorInfo, MonitorInfo.cbSize);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("GetMonitorInfo: MmCopyToCaller failed\n");
+ SetLastNtError(Status);
+ RETURN(FALSE);
+ }
- DPRINT("GetMonitorInfo: success\n");
+ DPRINT("GetMonitorInfo: success\n");
- RETURN(TRUE);
+ RETURN(TRUE);
CLEANUP:
- DPRINT("Leave NtUserGetMonitorInfo, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ DPRINT("Leave NtUserGetMonitorInfo, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
/* NtUserMonitorFromPoint
@@ -729,42 +700,27 @@ CLEANUP:
HMONITOR
APIENTRY
NtUserMonitorFromPoint(
- IN POINT point,
- IN DWORD dwFlags)
+ IN POINT point,
+ IN DWORD dwFlags)
{
- INT NumMonitors;
- RECTL InRect;
- HMONITOR hMonitor = NULL;
+ INT NumMonitors;
+ RECTL InRect;
+ HMONITOR hMonitor = NULL;
- /* fill inRect */
- InRect.left = InRect.right = point.x;
- InRect.top = InRect.bottom = point.y;
+ /* fill inRect (bottom-right exclusive) */
+ InRect.left = point.x;
+ InRect.right = point.x + 1;
+ InRect.top = point.y;
+ InRect.bottom = point.y + 1;
- /* find intersecting monitor */
- NumMonitors = IntGetMonitorsFromRect(&InRect, &hMonitor, NULL, 1, 0);
- if (NumMonitors < 0)
- {
- return (HMONITOR)NULL;
- }
+ /* find intersecting monitor */
+ NumMonitors = IntGetMonitorsFromRect(&InRect, &hMonitor, NULL, 1, dwFlags);
+ if (NumMonitors < 0)
+ {
+ return (HMONITOR)NULL;
+ }
- if (hMonitor == NULL)
- {
- if (dwFlags == MONITOR_DEFAULTTOPRIMARY)
- {
- PMONITOR MonitorObj = IntGetPrimaryMonitor();
- if (MonitorObj)
- hMonitor = UserHMGetHandle(MonitorObj);
- }
- else if (dwFlags == MONITOR_DEFAULTTONEAREST)
- {
- NumMonitors = IntGetMonitorsFromRect(&InRect, &hMonitor, NULL,
- 1, MONITOR_DEFAULTTONEAREST);
- /*ASSERT( (numMonitors > 0) && (hMonitor != NULL) );*/
- }
- /* else flag is DEFAULTTONULL */
- }
-
- return hMonitor;
+ return hMonitor;
}
/* NtUserMonitorFromRect
@@ -787,131 +743,111 @@ NtUserMonitorFromPoint(
HMONITOR
APIENTRY
NtUserMonitorFromRect(
- IN LPCRECTL pRect,
- IN DWORD dwFlags)
+ IN LPCRECTL pRect,
+ IN DWORD dwFlags)
{
- INT numMonitors, iLargestArea = -1, i;
- PRECTL rectList;
- HMONITOR *hMonitorList;
- HMONITOR hMonitor = NULL;
- RECTL rect;
- NTSTATUS status;
+ ULONG numMonitors, iLargestArea = 0, i;
+ PRECTL rectList;
+ HMONITOR *hMonitorList;
+ HMONITOR hMonitor = NULL;
+ RECTL rect;
+ NTSTATUS status;
- /* get rect */
- status = MmCopyFromCaller(&rect, pRect, sizeof (RECT));
- if (!NT_SUCCESS(status))
- {
- SetLastNtError(status);
- return (HMONITOR)NULL;
- }
+ /* get rect */
+ status = MmCopyFromCaller(&rect, pRect, sizeof (RECT));
+ if (!NT_SUCCESS(status))
+ {
+ SetLastNtError(status);
+ return (HMONITOR)NULL;
+ }
- /* find intersecting monitors */
- numMonitors = IntGetMonitorsFromRect(&rect, NULL, NULL, 0, 0);
- if (numMonitors < 0)
- {
- return (HMONITOR)NULL;
- }
+ /* find intersecting monitors */
+ numMonitors = IntGetMonitorsFromRect(&rect, &hMonitor, NULL, 1, dwFlags);
+ if (numMonitors <= 1)
+ {
+ return hMonitor;
+ }
- if (numMonitors == 0)
- {
- if (dwFlags == MONITOR_DEFAULTTOPRIMARY)
- {
- PMONITOR monitorObj = IntGetPrimaryMonitor();
- if (monitorObj)
- return UserHMGetHandle(monitorObj);
- }
- else if (dwFlags == MONITOR_DEFAULTTONEAREST)
- {
- numMonitors = IntGetMonitorsFromRect(&rect, &hMonitor, NULL,
- 1, MONITOR_DEFAULTTONEAREST);
- if (numMonitors <= 0)
- {
- /* error? */
- return (HMONITOR)NULL;
- }
+ hMonitorList = ExAllocatePoolWithTag(PagedPool,
+ sizeof(HMONITOR) * numMonitors,
+ USERTAG_MONITORRECTS);
+ if (hMonitorList == NULL)
+ {
+ /* FIXME: SetLastWin32Error? */
+ return (HMONITOR)NULL;
+ }
- if (numMonitors > 0)
- return hMonitor;
- }
- /* else flag is DEFAULTTONULL */
- return (HMONITOR)NULL;
- }
+ rectList = ExAllocatePoolWithTag(PagedPool,
+ sizeof(RECT) * numMonitors,
+ USERTAG_MONITORRECTS);
+ if (rectList == NULL)
+ {
+ ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
+ /* FIXME: SetLastWin32Error? */
+ return (HMONITOR)NULL;
+ }
- hMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * numMonitors, USERTAG_MONITORRECTS);
- if (hMonitorList == NULL)
- {
- /* FIXME: SetLastWin32Error? */
- return (HMONITOR)NULL;
- }
- rectList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * numMonitors, USERTAG_MONITORRECTS);
- if (rectList == NULL)
- {
- ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
- /* FIXME: SetLastWin32Error? */
- return (HMONITOR)NULL;
- }
+ /* get intersecting monitors */
+ numMonitors = IntGetMonitorsFromRect(&rect, hMonitorList, rectList,
+ numMonitors, 0);
+ if (numMonitors == 0)
+ {
+ ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
+ ExFreePoolWithTag(rectList, USERTAG_MONITORRECTS);
+ return (HMONITOR)NULL;
+ }
- /* get intersecting monitors */
- numMonitors = IntGetMonitorsFromRect(&rect, hMonitorList, rectList,
- numMonitors, 0);
- if (numMonitors <= 0)
- {
- ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
- ExFreePoolWithTag(rectList, USERTAG_MONITORRECTS);
- return (HMONITOR)NULL;
- }
+ /* find largest intersection */
+ for (i = 0; i < numMonitors; i++)
+ {
+ ULONG area = (rectList[i].right - rectList[i].left) *
+ (rectList[i].bottom - rectList[i].top);
+ if (area >= iLargestArea)
+ {
+ hMonitor = hMonitorList[i];
+ }
+ }
- /* find largest intersection */
- for (i = 0; i < numMonitors; i++)
- {
- INT area = (rectList[i].right - rectList[i].left) *
- (rectList[i].bottom - rectList[i].top);
- if (area > iLargestArea)
- {
- hMonitor = hMonitorList[i];
- }
- }
+ ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
+ ExFreePoolWithTag(rectList, USERTAG_MONITORRECTS);
- ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
- ExFreePoolWithTag(rectList, USERTAG_MONITORRECTS);
-
- return hMonitor;
+ return hMonitor;
}
HMONITOR
APIENTRY
NtUserMonitorFromWindow(
- IN HWND hWnd,
- IN DWORD dwFlags)
+ IN HWND hWnd,
+ IN DWORD dwFlags)
{
- PWND Window;
- HMONITOR hMonitor = NULL;
- RECTL Rect;
- DECLARE_RETURN(HMONITOR);
+ PWND Window;
+ HMONITOR hMonitor = NULL;
+ RECTL Rect;
+ DECLARE_RETURN(HMONITOR);
- DPRINT("Enter NtUserMonitorFromWindow\n");
- UserEnterShared();
+ DPRINT("Enter NtUserMonitorFromWindow\n");
+ UserEnterShared();
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- if (dwFlags == MONITOR_DEFAULTTONULL)
- {
- RETURN(hMonitor);
- }
- IntGetMonitorsFromRect(NULL, &hMonitor, NULL, 1, dwFlags);
- RETURN(hMonitor);
- }
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ if (dwFlags == MONITOR_DEFAULTTONULL)
+ {
+ RETURN(hMonitor);
+ }
+ IntGetMonitorsFromRect(NULL, &hMonitor, NULL, 1, dwFlags);
+ RETURN(hMonitor);
+ }
- Rect.left = Rect.right = Window->rcWindow.left;
- Rect.top = Rect.bottom = Window->rcWindow.bottom;
+ Rect.left = Rect.right = Window->rcWindow.left;
+ Rect.top = Rect.bottom = Window->rcWindow.bottom;
- IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags);
+ IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags);
- RETURN(hMonitor);
+ RETURN(hMonitor);
CLEANUP:
- DPRINT("Leave NtUserMonitorFromWindow, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ DPRINT("Leave NtUserMonitorFromWindow, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
diff --git a/subsystems/win32/win32k/ntuser/msgqueue.c b/subsystems/win32/win32k/ntuser/msgqueue.c
index 5d0bee88eba..b03ba84365b 100644
--- a/subsystems/win32/win32k/ntuser/msgqueue.c
+++ b/subsystems/win32/win32k/ntuser/msgqueue.c
@@ -22,6 +22,8 @@
* PURPOSE: Message queues
* FILE: subsystems/win32/win32k/ntuser/msgqueue.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ Alexandre Julliard
+ Maarten Lankhorst
* REVISION HISTORY:
* 06-06-2001 CSH Created
*/
@@ -35,59 +37,10 @@
/* GLOBALS *******************************************************************/
-#define SYSTEM_MESSAGE_QUEUE_SIZE (256)
-
-static MSG SystemMessageQueue[SYSTEM_MESSAGE_QUEUE_SIZE];
-static ULONG SystemMessageQueueHead = 0;
-static ULONG SystemMessageQueueTail = 0;
-static ULONG SystemMessageQueueCount = 0;
-static KSPIN_LOCK SystemMessageQueueLock;
-
-static ULONG volatile HardwareMessageQueueStamp = 0;
-static LIST_ENTRY HardwareMessageQueueHead;
-static KMUTANT HardwareMessageQueueLock;
-
-static KEVENT HardwareMessageEvent;
-
static PAGED_LOOKASIDE_LIST MessageLookasideList;
-#define IntLockSystemMessageQueue(OldIrql) \
- KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql)
-
-#define IntUnLockSystemMessageQueue(OldIrql) \
- KeReleaseSpinLock(&SystemMessageQueueLock, OldIrql)
-
-#define IntUnLockSystemHardwareMessageQueueLock(Wait) \
- KeReleaseMutant(&HardwareMessageQueueLock, IO_NO_INCREMENT, FALSE, Wait)
-
/* FUNCTIONS *****************************************************************/
-//
-// Wakeup any thread/process waiting on idle input.
-//
-static VOID FASTCALL
-IdlePing(VOID)
-{
- HWND hWnd;
- PWND Window;
- PPROCESSINFO W32d = PsGetCurrentProcessWin32Process();
-
- hWnd = UserGetForegroundWindow();
-
- Window = UserGetWindowObject(hWnd);
-
- if (Window && Window->head.pti)
- {
- if (Window->head.pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE))
- {
- co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
- }
- }
-
- if (W32d && W32d->InputIdleEvent)
- KePulseEvent( W32d->InputIdleEvent, EVENT_INCREMENT, TRUE);
-}
-
HANDLE FASTCALL
IntMsqSetWakeMask(DWORD WakeMask)
{
@@ -103,6 +56,11 @@ IntMsqSetWakeMask(DWORD WakeMask)
MessageQueue->WakeMask = WakeMask;
MessageEventHandle = MessageQueue->NewMessagesHandle;
+ if (Win32Thread->pcti)
+ Win32Thread->pcti->fsWakeMask = WakeMask;
+
+ IdlePing();
+
return MessageEventHandle;
}
@@ -120,17 +78,28 @@ IntMsqClearWakeMask(VOID)
// HACK!!!!!!! Newbies that wrote this should hold your head down in shame! (jt)
MessageQueue->WakeMask = ~0;
+ if (Win32Thread->pcti)
+ Win32Thread->pcti->fsWakeMask = 0;
+
+ IdlePong();
+
return TRUE;
}
+VOID FASTCALL
+MsqWakeQueue(PUSER_MESSAGE_QUEUE Queue, DWORD MessageBits)
+{
+ Queue->QueueBits |= MessageBits;
+ Queue->ChangedBits |= MessageBits;
+ if (Queue->WakeMask & MessageBits)
+ KeSetEvent(Queue->NewMessages, IO_NO_INCREMENT, FALSE);
+}
+
VOID FASTCALL
MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
{
Queue->PaintCount++;
- Queue->QueueBits |= QS_PAINT;
- Queue->ChangedBits |= QS_PAINT;
- if (Queue->WakeMask & QS_PAINT)
- KeSetEvent(Queue->NewMessages, IO_NO_INCREMENT, FALSE);
+ MsqWakeQueue(Queue, QS_PAINT);
}
VOID FASTCALL
@@ -140,15 +109,11 @@ MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
}
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
MsqInitializeImpl(VOID)
{
- /*CurrentFocusMessageQueue = NULL;*/
- InitializeListHead(&HardwareMessageQueueHead);
- KeInitializeEvent(&HardwareMessageEvent, NotificationEvent, 0);
- KeInitializeSpinLock(&SystemMessageQueueLock);
- KeInitializeMutant(&HardwareMessageQueueLock, 0);
-
ExInitializePagedLookasideList(&MessageLookasideList,
NULL,
NULL,
@@ -161,12 +126,19 @@ MsqInitializeImpl(VOID)
}
VOID FASTCALL
-MsqInsertSystemMessage(MSG* Msg)
+MsqPostMouseMove(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg)
+{
+ MessageQueue->MouseMoveMsg = *Msg;
+ MessageQueue->MouseMoved = TRUE;
+ MsqWakeQueue(MessageQueue, QS_MOUSEMOVE);
+}
+
+VOID FASTCALL
+co_MsqInsertMouseMessage(MSG* Msg)
{
LARGE_INTEGER LargeTickCount;
- KIRQL OldIrql;
- ULONG Prev;
MSLLHOOKSTRUCT MouseHookData;
+ PWND pwnd, pwndDesktop;
KeQueryTickCount(&LargeTickCount);
Msg->time = MsqCalculateMessageTime(&LargeTickCount);
@@ -199,554 +171,47 @@ MsqInsertSystemMessage(MSG* Msg)
if (co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData))
return;
- /*
- * If we got WM_MOUSEMOVE and there are already messages in the
- * system message queue, check if the last message is mouse move
- * and if it is then just overwrite it.
- */
- IntLockSystemMessageQueue(OldIrql);
+ /* Get the desktop window */
+ pwndDesktop = UserGetDesktopWindow();
+ if(!pwndDesktop)
+ return;
- /*
- * Bail out if the queue is full. FIXME: We should handle this case
- * more gracefully.
- */
-
- if (SystemMessageQueueCount == SYSTEM_MESSAGE_QUEUE_SIZE)
+ /* Check if the mouse is captured */
+ Msg->hwnd = IntGetCaptureWindow();
+ if(Msg->hwnd != NULL)
{
- IntUnLockSystemMessageQueue(OldIrql);
- return;
- }
-
- if (Msg->message == WM_MOUSEMOVE && SystemMessageQueueCount)
- {
- if (SystemMessageQueueTail == 0)
- Prev = SYSTEM_MESSAGE_QUEUE_SIZE - 1;
- else
- Prev = SystemMessageQueueTail - 1;
- if (SystemMessageQueue[Prev].message == WM_MOUSEMOVE)
- {
- SystemMessageQueueTail = Prev;
- SystemMessageQueueCount--;
- }
- }
-
- /*
- * Actually insert the message into the system message queue.
- */
-
- SystemMessageQueue[SystemMessageQueueTail] = *Msg;
- SystemMessageQueueTail =
- (SystemMessageQueueTail + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
- SystemMessageQueueCount++;
-
- IntUnLockSystemMessageQueue(OldIrql);
-
- KeSetEvent(&HardwareMessageEvent, IO_NO_INCREMENT, FALSE);
-}
-
-BOOL FASTCALL
-MsqIsClkLck(LPMSG Msg, BOOL Remove)
-{
- PTHREADINFO pti;
- PSYSTEM_CURSORINFO CurInfo;
- BOOL Res = FALSE;
-
- pti = PsGetCurrentThreadWin32Thread();
- if (pti->rpdesk == NULL)
- {
- return FALSE;
- }
-
- CurInfo = IntGetSysCursorInfo();
-
- switch (Msg->message)
- {
- case WM_LBUTTONUP:
- Res = ((Msg->time - CurInfo->ClickLockTime) >= gspv.dwMouseClickLockTime);
- if (Res && (!CurInfo->ClickLockActive))
- {
- CurInfo->ClickLockActive = TRUE;
- }
- break;
- case WM_LBUTTONDOWN:
- if (CurInfo->ClickLockActive)
- {
- Res = TRUE;
- CurInfo->ClickLockActive = FALSE;
- CurInfo->ClickLockTime = 0;
- }
- else
- {
- CurInfo->ClickLockTime = Msg->time;
- }
- break;
- }
- return Res;
-}
-
-BOOL FASTCALL
-MsqIsDblClk(LPMSG Msg, BOOL Remove)
-{
- PTHREADINFO pti;
- PSYSTEM_CURSORINFO CurInfo;
- LONG dX, dY;
- BOOL Res;
-
- pti = PsGetCurrentThreadWin32Thread();
- if (pti->rpdesk == NULL)
- {
- return FALSE;
- }
-
- CurInfo = IntGetSysCursorInfo();
- Res = (Msg->hwnd == (HWND)CurInfo->LastClkWnd) &&
- ((Msg->time - CurInfo->LastBtnDown) < gspv.iDblClickTime);
- if(Res)
- {
-
- dX = CurInfo->LastBtnDownX - Msg->pt.x;
- dY = CurInfo->LastBtnDownY - Msg->pt.y;
- if(dX < 0)
- dX = -dX;
- if(dY < 0)
- dY = -dY;
-
- Res = (dX <= gspv.iDblClickWidth) &&
- (dY <= gspv.iDblClickHeight);
-
- if(Res)
- {
- if(CurInfo->ButtonsDown)
- Res = (CurInfo->ButtonsDown == Msg->message);
- }
- }
-
- if(Remove)
- {
- CurInfo->LastBtnDownX = Msg->pt.x;
- CurInfo->LastBtnDownY = Msg->pt.y;
- CurInfo->ButtonsDown = Msg->message;
- if (Res)
- {
- CurInfo->LastBtnDown = 0;
- CurInfo->LastClkWnd = NULL;
- }
- else
- {
- CurInfo->LastClkWnd = (HANDLE)Msg->hwnd;
- CurInfo->LastBtnDown = Msg->time;
- }
- }
-
- return Res;
-}
-
-static BOOL APIENTRY
-co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWND Window, UINT FilterLow, UINT FilterHigh,
- PUSER_MESSAGE Message, BOOL Remove, PBOOL Freed,
- PWND ScopeWin, PPOINT ScreenPoint, BOOL FromGlobalQueue, PLIST_ENTRY *Next)
-{
- USHORT Msg = Message->Msg.message;
- PWND CaptureWindow = NULL;
- HWND hCaptureWin;
-
- /* FIXME: Mouse message can be sent before the Desktop is up and running in which case ScopeWin (Desktop) is 0.
- Is this the best fix? */
- if (ScopeWin == 0) return FALSE;
-
- ASSERT_REFS_CO(ScopeWin);
-
- /*
- co_WinPosWindowFromPoint can return a Window, and in that case
- that window has a ref that we need to deref. Thats why we add "dummy"
- refs in all other cases.
- */
-
- hCaptureWin = IntGetCaptureWindow();
- if (hCaptureWin == NULL)
- {
- if (Msg == WM_MOUSEWHEEL)
- {
- CaptureWindow = UserGetWindowObject(IntGetFocusWindow());
- if (CaptureWindow) UserReferenceObject(CaptureWindow);
- }
- else
- {
- co_WinPosWindowFromPoint(ScopeWin, NULL, &Message->Msg.pt, &CaptureWindow);
- if(CaptureWindow == NULL)
- {
- CaptureWindow = ScopeWin;
- if (CaptureWindow) UserReferenceObject(CaptureWindow);
- }
- else
- {
- /* this is the one case where we dont add a ref, since the returned
- window is already referenced */
- }
- }
+ pwnd = UserGetWindowObject(Msg->hwnd);
}
else
{
- /* FIXME - window messages should go to the right window if no buttons are
- pressed */
- CaptureWindow = UserGetWindowObject(hCaptureWin);
- if (CaptureWindow) UserReferenceObject(CaptureWindow);
+ /* Loop all top level windows to find which one should receive input */
+ for( pwnd = pwndDesktop->spwndChild;
+ pwnd != NULL;
+ pwnd = pwnd->spwndNext )
+ {
+ if((pwnd->style & WS_VISIBLE) &&
+ IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y))
+ {
+ Msg->hwnd = pwnd->head.h;
+ break;
+ }
+ }
}
-
-
- if (CaptureWindow == NULL)
+ /* Check if we found a window */
+ if(Msg->hwnd != NULL && pwnd != NULL)
{
- if(!FromGlobalQueue)
- {
- RemoveEntryList(&Message->ListEntry);
- if(MessageQueue->MouseMoveMsg == Message)
- {
- MessageQueue->MouseMoveMsg = NULL;
- }
- }
- // when FromGlobalQueue is true, the caller has already removed the Message
- ExFreePool(Message);
- *Freed = TRUE;
- return(FALSE);
+ if(Msg->message == WM_MOUSEMOVE)
+ {
+ /* Mouse move is a special case*/
+ MsqPostMouseMove(pwnd->head.pti->MessageQueue, Msg);
+ }
+ else
+ {
+ DPRINT("Posting mouse message to hwnd=0x%x!\n", UserHMGetHandle(pwnd));
+ MsqPostMessage(pwnd->head.pti->MessageQueue, Msg, TRUE, QS_MOUSEBUTTON);
+ }
}
-
- if (CaptureWindow->head.pti->MessageQueue != MessageQueue)
- {
- if (! FromGlobalQueue)
- {
- DPRINT("Moving msg between private queues\n");
- /* This message is already queued in a private queue, but we need
- * to move it to a different queue, perhaps because a new window
- * was created which now covers the screen area previously taken
- * by another window. To move it, we need to take it out of the
- * old queue. Note that we're already holding the lock mutexes of the
- * old queue */
- RemoveEntryList(&Message->ListEntry);
-
- /* remove the pointer for the current WM_MOUSEMOVE message in case we
- just removed it */
- if(MessageQueue->MouseMoveMsg == Message)
- {
- MessageQueue->MouseMoveMsg = NULL;
- }
- }
-
- /* lock the destination message queue, so we don't get in trouble with other
- threads, messing with it at the same time */
- IntLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
- InsertTailList(&CaptureWindow->head.pti->MessageQueue->HardwareMessagesListHead,
- &Message->ListEntry);
- if(Message->Msg.message == WM_MOUSEMOVE)
- {
- if(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg)
- {
- /* remove the old WM_MOUSEMOVE message, we're processing a more recent
- one */
- RemoveEntryList(&CaptureWindow->head.pti->MessageQueue->MouseMoveMsg->ListEntry);
- ExFreePool(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg);
- }
- /* save the pointer to the WM_MOUSEMOVE message in the new queue */
- CaptureWindow->head.pti->MessageQueue->MouseMoveMsg = Message;
-
- CaptureWindow->head.pti->MessageQueue->QueueBits |= QS_MOUSEMOVE;
- CaptureWindow->head.pti->MessageQueue->ChangedBits |= QS_MOUSEMOVE;
- if (CaptureWindow->head.pti->MessageQueue->WakeMask & QS_MOUSEMOVE)
- KeSetEvent(CaptureWindow->head.pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
- }
- else
- {
- CaptureWindow->head.pti->MessageQueue->QueueBits |= QS_MOUSEBUTTON;
- CaptureWindow->head.pti->MessageQueue->ChangedBits |= QS_MOUSEBUTTON;
- if (CaptureWindow->head.pti->MessageQueue->WakeMask & QS_MOUSEBUTTON)
- KeSetEvent(CaptureWindow->head.pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
- }
- IntUnLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
-
- *Freed = FALSE;
- UserDereferenceObject(CaptureWindow);
- return(FALSE);
- }
-
- /* From here on, we're in the same message queue as the caller! */
-
- *ScreenPoint = Message->Msg.pt;
-
- if((Window != NULL && PtrToInt(Window) != 1 && CaptureWindow->head.h != Window->head.h) ||
- ((FilterLow != 0 || FilterHigh != 0) && (Msg < FilterLow || Msg > FilterHigh)))
- {
- /* Reject the message because it doesn't match the filter */
-
- if(FromGlobalQueue)
- {
- /* Lock the message queue so no other thread can mess with it.
- Our own message queue is not locked while fetching from the global
- queue, so we have to make sure nothing interferes! */
- IntLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
- /* if we're from the global queue, we need to add our message to our
- private queue so we don't loose it! */
- InsertTailList(&CaptureWindow->head.pti->MessageQueue->HardwareMessagesListHead,
- &Message->ListEntry);
- }
-
- if (Message->Msg.message == WM_MOUSEMOVE)
- {
- if(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg &&
- (CaptureWindow->head.pti->MessageQueue->MouseMoveMsg != Message))
- {
- /* delete the old message */
- RemoveEntryList(&CaptureWindow->head.pti->MessageQueue->MouseMoveMsg->ListEntry);
- ExFreePool(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg);
- if (!FromGlobalQueue)
- {
- // We might have deleted the next one in our queue, so fix next
- *Next = Message->ListEntry.Flink;
- }
- }
- /* always save a pointer to this WM_MOUSEMOVE message here because we're
- sure that the message is in the private queue */
- CaptureWindow->head.pti->MessageQueue->MouseMoveMsg = Message;
- }
- if(FromGlobalQueue)
- {
- IntUnLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
- }
-
- UserDereferenceObject(CaptureWindow);
- *Freed = FALSE;
- return(FALSE);
- }
-
- /* FIXME - only assign if removing? */
- Message->Msg.hwnd = CaptureWindow->head.h;
- Message->Msg.message = Msg;
- Message->Msg.lParam = MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y);
-
- /* remove the reference to the current WM_(NC)MOUSEMOVE message, if this message
- is it */
- if (Message->Msg.message == WM_MOUSEMOVE ||
- Message->Msg.message == WM_NCMOUSEMOVE)
- {
- if(FromGlobalQueue)
- {
- /* Lock the message queue so no other thread can mess with it.
- Our own message queue is not locked while fetching from the global
- queue, so we have to make sure nothing interferes! */
- IntLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
- if(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg)
- {
- /* delete the WM_(NC)MOUSEMOVE message in the private queue, we're dealing
- with one that's been sent later */
- RemoveEntryList(&CaptureWindow->head.pti->MessageQueue->MouseMoveMsg->ListEntry);
- ExFreePool(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg);
- /* our message is not in the private queue so we can remove the pointer
- instead of setting it to the current message we're processing */
- CaptureWindow->head.pti->MessageQueue->MouseMoveMsg = NULL;
- }
- IntUnLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
- }
- else if (CaptureWindow->head.pti->MessageQueue->MouseMoveMsg == Message)
- {
- CaptureWindow->head.pti->MessageQueue->MouseMoveMsg = NULL;
- }
- }
-
- UserDereferenceObject(CaptureWindow);
- *Freed = FALSE;
- return(TRUE);
-}
-
-BOOL APIENTRY
-co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWND Window,
- UINT FilterLow, UINT FilterHigh, BOOL Remove,
- PUSER_MESSAGE* Message)
-{
- KIRQL OldIrql;
- POINT ScreenPoint;
- BOOL Accept, Freed;
- PLIST_ENTRY CurrentEntry;
- PWND DesktopWindow = NULL;
- PVOID WaitObjects[2];
- NTSTATUS WaitStatus;
- DECLARE_RETURN(BOOL);
- USER_REFERENCE_ENTRY Ref;
- PDESKTOPINFO Desk = NULL;
-
- WaitObjects[1] = MessageQueue->NewMessages;
- WaitObjects[0] = &HardwareMessageQueueLock;
- do
- {
- IdlePing();
-
- UserLeaveCo();
-
- WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
- UserMode, FALSE, NULL, NULL);
-
- UserEnterCo();
- }
- while (NT_SUCCESS(WaitStatus) && STATUS_WAIT_0 != WaitStatus);
-
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
-
- if (DesktopWindow)
- {
- UserRefObjectCo(DesktopWindow, &Ref);
- Desk = DesktopWindow->head.pti->pDeskInfo;
- }
-
- /* Process messages in the message queue itself. */
- IntLockHardwareMessageQueue(MessageQueue);
- CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;
- while (CurrentEntry != &MessageQueue->HardwareMessagesListHead)
- {
- PUSER_MESSAGE Current =
- CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
- CurrentEntry = CurrentEntry->Flink;
- if (Current->Msg.message >= WM_MOUSEFIRST &&
- Current->Msg.message <= WM_MOUSELAST)
- {
-
-
- Accept = co_MsqTranslateMouseMessage(MessageQueue, Window, FilterLow, FilterHigh,
- Current, Remove, &Freed,
- DesktopWindow, &ScreenPoint, FALSE, &CurrentEntry);
- if (Accept)
- {
- if (Remove)
- {
- RemoveEntryList(&Current->ListEntry);
- }
- IntUnLockHardwareMessageQueue(MessageQueue);
- IntUnLockSystemHardwareMessageQueueLock(FALSE);
- *Message = Current;
-
- if (Desk)
- Desk->LastInputWasKbd = FALSE;
-
- RETURN(TRUE);
- }
-
- }
- else
- {
- if (Remove)
- {
- RemoveEntryList(&Current->ListEntry);
- }
- IntUnLockHardwareMessageQueue(MessageQueue);
- IntUnLockSystemHardwareMessageQueueLock(FALSE);
- *Message = Current;
-
- RETURN(TRUE);
- }
- }
- IntUnLockHardwareMessageQueue(MessageQueue);
-
- /* Now try the global queue. */
-
- /* Transfer all messages from the DPC accessible queue to the main queue. */
- IntLockSystemMessageQueue(OldIrql);
- while (SystemMessageQueueCount > 0)
- {
- PUSER_MESSAGE UserMsg;
- MSG Msg;
-
- ASSERT(SystemMessageQueueHead < SYSTEM_MESSAGE_QUEUE_SIZE);
- Msg = SystemMessageQueue[SystemMessageQueueHead];
- SystemMessageQueueHead =
- (SystemMessageQueueHead + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
- SystemMessageQueueCount--;
- IntUnLockSystemMessageQueue(OldIrql);
-
- UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
- /* What to do if out of memory? For now we just panic a bit in debug */
- ASSERT(UserMsg);
- UserMsg->Msg = Msg;
- InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
-
- IntLockSystemMessageQueue(OldIrql);
- }
- HardwareMessageQueueStamp++;
- IntUnLockSystemMessageQueue(OldIrql);
-
- /* Process messages in the queue until we find one to return. */
- CurrentEntry = HardwareMessageQueueHead.Flink;
- while (CurrentEntry != &HardwareMessageQueueHead)
- {
- PUSER_MESSAGE Current =
- CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
- CurrentEntry = CurrentEntry->Flink;
- RemoveEntryList(&Current->ListEntry);
- HardwareMessageQueueStamp++;
- if (Current->Msg.message >= WM_MOUSEFIRST &&
- Current->Msg.message <= WM_MOUSELAST)
- {
- const ULONG ActiveStamp = HardwareMessageQueueStamp;
- /* Translate the message. */
- Accept = co_MsqTranslateMouseMessage(MessageQueue, Window, FilterLow, FilterHigh,
- Current, Remove, &Freed,
- DesktopWindow, &ScreenPoint, TRUE, NULL);
- if (Accept)
- {
- /* Check for no more messages in the system queue. */
- IntLockSystemMessageQueue(OldIrql);
- if (SystemMessageQueueCount == 0 &&
- IsListEmpty(&HardwareMessageQueueHead))
- {
- KeClearEvent(&HardwareMessageEvent);
- }
- IntUnLockSystemMessageQueue(OldIrql);
-
- /*
- If we aren't removing the message then add it to the private
- queue.
- */
- if (!Remove)
- {
- IntLockHardwareMessageQueue(MessageQueue);
- if(Current->Msg.message == WM_MOUSEMOVE)
- {
- if(MessageQueue->MouseMoveMsg)
- {
- RemoveEntryList(&MessageQueue->MouseMoveMsg->ListEntry);
- ExFreePool(MessageQueue->MouseMoveMsg);
- }
- MessageQueue->MouseMoveMsg = Current;
- }
- InsertTailList(&MessageQueue->HardwareMessagesListHead,
- &Current->ListEntry);
- IntUnLockHardwareMessageQueue(MessageQueue);
- }
- IntUnLockSystemHardwareMessageQueueLock(FALSE);
- *Message = Current;
-
- RETURN(TRUE);
- }
- /* If the contents of the queue changed then restart processing. */
- if (HardwareMessageQueueStamp != ActiveStamp)
- {
- CurrentEntry = HardwareMessageQueueHead.Flink;
- continue;
- }
- }
- }
-
- /* Check if the system message queue is now empty. */
- IntLockSystemMessageQueue(OldIrql);
- if (SystemMessageQueueCount == 0 && IsListEmpty(&HardwareMessageQueueHead))
- {
- KeClearEvent(&HardwareMessageEvent);
- }
- IntUnLockSystemMessageQueue(OldIrql);
- IntUnLockSystemHardwareMessageQueueLock(FALSE);
-
- RETURN(FALSE);
-
-CLEANUP:
- if (DesktopWindow) UserDerefObjectCo(DesktopWindow);
-
- END_CLEANUP;
}
//
@@ -798,7 +263,7 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
KbdHookData.dwExtraInfo = 0;
if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
{
- DPRINT("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
+ DPRINT1("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
Msg.message, Msg.wParam, Msg.lParam);
if (Entered) UserLeave();
return;
@@ -871,9 +336,6 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
UserDereferenceObject(Window);
ObDereferenceObject (Thread);
- // InsertHeadList(&pThread->MessageQueue->PostedMessagesListHead,
- // &Message->ListEntry);
- // KeSetEvent(pThread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
}
PUSER_MESSAGE FASTCALL
@@ -898,34 +360,6 @@ MsqDestroyMessage(PUSER_MESSAGE Message)
ExFreeToPagedLookasideList(&MessageLookasideList, Message);
}
-VOID FASTCALL
-co_MsqDispatchSentNotifyMessages(PUSER_MESSAGE_QUEUE MessageQueue)
-{
- PLIST_ENTRY ListEntry;
- PUSER_SENT_MESSAGE_NOTIFY Message;
-
- while (!IsListEmpty(&MessageQueue->SentMessagesListHead))
- {
- ListEntry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
- Message = CONTAINING_RECORD(ListEntry, USER_SENT_MESSAGE_NOTIFY,
- ListEntry);
-
- co_IntCallSentMessageCallback(Message->CompletionCallback,
- Message->hWnd,
- Message->Msg,
- Message->CompletionCallbackContext,
- Message->Result);
-
- }
-
-}
-
-BOOLEAN FASTCALL
-MsqPeekSentMessages(PUSER_MESSAGE_QUEUE MessageQueue)
-{
- return(!IsListEmpty(&MessageQueue->SentMessagesListHead));
-}
-
BOOLEAN FASTCALL
co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
{
@@ -948,26 +382,25 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
&Message->ListEntry);
if (Message->HookMessage == MSQ_ISHOOK)
- {
- Result = co_HOOK_CallHooks(Message->Msg.message,
- (INT)(INT_PTR)Message->Msg.hwnd,
- Message->Msg.wParam,
- Message->Msg.lParam);
+ { // Direct Hook Call processor
+ Result = co_CallHook( Message->Msg.message, // HookId
+ (INT)(INT_PTR)Message->Msg.hwnd, // Code
+ Message->Msg.wParam,
+ Message->Msg.lParam);
}
else if (Message->HookMessage == MSQ_ISEVENT)
- {
+ { // Direct Event Call processor
Result = co_EVENT_CallEvents( Message->Msg.message,
Message->Msg.hwnd,
Message->Msg.wParam,
Message->Msg.lParam);
}
else
- {
- /* Call the window procedure. */
- Result = co_IntSendMessage(Message->Msg.hwnd,
- Message->Msg.message,
- Message->Msg.wParam,
- Message->Msg.lParam);
+ { /* Call the window procedure. */
+ Result = co_IntSendMessage( Message->Msg.hwnd,
+ Message->Msg.message,
+ Message->Msg.wParam,
+ Message->Msg.lParam);
}
/* remove the message from the local dispatching list, because it doesn't need
@@ -1111,18 +544,6 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
}
}
-VOID FASTCALL
-MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue,
- PUSER_SENT_MESSAGE_NOTIFY NotifyMessage)
-{
- InsertTailList(&MessageQueue->NotifyMessagesListHead,
- &NotifyMessage->ListEntry);
- MessageQueue->QueueBits |= QS_SENDMESSAGE;
- MessageQueue->ChangedBits |= QS_SENDMESSAGE;
- if (MessageQueue->WakeMask & QS_SENDMESSAGE)
- KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
-}
-
NTSTATUS FASTCALL
co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
@@ -1133,10 +554,10 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent;
NTSTATUS WaitStatus;
- LRESULT Result;
PUSER_MESSAGE_QUEUE ThreadQueue;
LARGE_INTEGER Timeout;
PLIST_ENTRY Entry;
+ LRESULT Result = 0; //// Result could be trashed. ////
if(!(Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
{
@@ -1154,7 +575,6 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
/* FIXME - increase reference counter of sender's message queue here */
- Result = 0;
Message->Msg.hwnd = Wnd;
Message->Msg.message = Msg;
Message->Msg.wParam = wParam;
@@ -1164,6 +584,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
Message->SenderQueue = ThreadQueue;
IntReferenceMessageQueue(ThreadQueue);
Message->CompletionCallback = NULL;
+ Message->CompletionCallbackContext = 0;
Message->HookMessage = HookMessage;
Message->HasPackedLParam = FALSE;
@@ -1175,17 +596,12 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
/* queue it in the destination's message queue */
InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
- MessageQueue->QueueBits |= QS_SENDMESSAGE;
- MessageQueue->ChangedBits |= QS_SENDMESSAGE;
- if (MessageQueue->WakeMask & QS_SENDMESSAGE)
- KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+ MsqWakeQueue(MessageQueue, QS_SENDMESSAGE);
/* we can't access the Message anymore since it could have already been deleted! */
if(Block)
{
- IdlePing();
-
UserLeaveCo();
/* don't process messages sent to the thread */
@@ -1247,8 +663,6 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
WaitObjects[1] = ThreadQueue->NewMessages;
do
{
- IdlePing();
-
UserLeaveCo();
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
@@ -1332,10 +746,7 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessa
InsertTailList(&MessageQueue->HardwareMessagesListHead,
&Message->ListEntry);
}
- MessageQueue->QueueBits |= MessageBits;
- MessageQueue->ChangedBits |= MessageBits;
- if (MessageQueue->WakeMask & MessageBits)
- KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+ MsqWakeQueue(MessageQueue, MessageBits);
}
VOID FASTCALL
@@ -1343,35 +754,436 @@ MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode)
{
MessageQueue->QuitPosted = TRUE;
MessageQueue->QuitExitCode = ExitCode;
- MessageQueue->QueueBits |= QS_POSTMESSAGE;
- MessageQueue->ChangedBits |= QS_POSTMESSAGE;
- if (MessageQueue->WakeMask & QS_POSTMESSAGE)
- KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+ MsqWakeQueue(MessageQueue, QS_POSTMESSAGE);
+}
+
+/***********************************************************************
+ * MsqSendParentNotify
+ *
+ * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
+ * the window has the WS_EX_NOPARENTNOTIFY style.
+ */
+static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt )
+{
+ PWND pwndDesktop = UserGetWindowObject(IntGetDesktopWindow());
+
+ /* pt has to be in the client coordinates of the parent window */
+ pt.x += pwndDesktop->rcClient.left - pwnd->rcClient.left;
+ pt.y += pwndDesktop->rcClient.top - pwnd->rcClient.top;
+
+ for (;;)
+ {
+ PWND pwndParent;
+
+ if (!(pwnd->style & WS_CHILD)) break;
+ if (pwnd->ExStyle & WS_EX_NOPARENTNOTIFY) break;
+ if (!(pwndParent = IntGetParent(pwnd))) break;
+ if (pwndParent == pwndDesktop) break;
+ pt.x += pwnd->rcClient.left - pwndParent->rcClient.left;
+ pt.y += pwnd->rcClient.top - pwndParent->rcClient.top;
+
+ pwnd = pwndParent;
+ co_IntSendMessage( UserHMGetHandle(pwnd), WM_PARENTNOTIFY,
+ MAKEWPARAM( event, idChild ), MAKELPARAM( pt.x, pt.y ) );
+ }
+}
+
+BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT last)
+{
+ MSG clk_msg;
+ POINT pt;
+ UINT message;
+ USHORT hittest;
+ EVENTMSG event;
+ MOUSEHOOKSTRUCT hook;
+ BOOL eatMsg;
+
+ PWND pwndMsg, pwndDesktop;
+ PUSER_MESSAGE_QUEUE MessageQueue;
+ PTHREADINFO pti;
+ PSYSTEM_CURSORINFO CurInfo;
+ DECLARE_RETURN(BOOL);
+
+ pti = PsGetCurrentThreadWin32Thread();
+ pwndDesktop = UserGetDesktopWindow();
+ MessageQueue = pti->MessageQueue;
+ CurInfo = IntGetSysCursorInfo();
+ pwndMsg = UserGetWindowObject(msg->hwnd);
+ clk_msg = MessageQueue->msgDblClk;
+
+ /* find the window to dispatch this mouse message to */
+ if (MessageQueue->CaptureWindow)
+ {
+ hittest = HTCLIENT;
+ pwndMsg = IntGetWindowObject(MessageQueue->CaptureWindow);
+ }
+ else
+ {
+ pwndMsg = co_WinPosWindowFromPoint(pwndMsg, &msg->pt, &hittest);
+ }
+
+ DPRINT("Got mouse message for 0x%x, hittest: 0x%x\n", msg->hwnd, hittest );
+
+ if (pwndMsg == NULL || pwndMsg->head.pti != pti)
+ {
+ /* Remove and ignore the message */
+ *RemoveMessages = TRUE;
+ RETURN(FALSE);
+ }
+
+ msg->hwnd = UserHMGetHandle(pwndMsg);
+
+#if 0
+ if (!check_hwnd_filter( msg, hwnd_filter )) RETURN(FALSE);
+#endif
+
+ pt = msg->pt;
+ message = msg->message;
+ /* Note: windows has no concept of a non-client wheel message */
+ if (message != WM_MOUSEWHEEL)
+ {
+ if (hittest != HTCLIENT)
+ {
+ message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
+ msg->wParam = hittest;
+ }
+ else
+ {
+ /* coordinates don't get translated while tracking a menu */
+ /* FIXME: should differentiate popups and top-level menus */
+ if (!(MessageQueue->MenuOwner))
+ {
+ pt.x += pwndDesktop->rcClient.left - pwndMsg->rcClient.left;
+ pt.y += pwndDesktop->rcClient.top - pwndMsg->rcClient.top;
+ }
+ }
+ }
+ msg->lParam = MAKELONG( pt.x, pt.y );
+
+ /* translate double clicks */
+
+ if ((msg->message == WM_LBUTTONDOWN) ||
+ (msg->message == WM_RBUTTONDOWN) ||
+ (msg->message == WM_MBUTTONDOWN) ||
+ (msg->message == WM_XBUTTONDOWN))
+ {
+ BOOL update = *RemoveMessages;
+
+ /* translate double clicks -
+ * note that ...MOUSEMOVEs can slip in between
+ * ...BUTTONDOWN and ...BUTTONDBLCLK messages */
+
+ if ((MessageQueue->MenuOwner || MessageQueue->MoveSize) ||
+ hittest != HTCLIENT ||
+ (pwndMsg->pcls->style & CS_DBLCLKS))
+ {
+ if ((msg->message == clk_msg.message) &&
+ (msg->hwnd == clk_msg.hwnd) &&
+ (msg->wParam == clk_msg.wParam) &&
+ (msg->time - clk_msg.time < gspv.iDblClickTime) &&
+ (abs(msg->pt.x - clk_msg.pt.x) < UserGetSystemMetrics(SM_CXDOUBLECLK)/2) &&
+ (abs(msg->pt.y - clk_msg.pt.y) < UserGetSystemMetrics(SM_CYDOUBLECLK)/2))
+ {
+ message += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
+ if (update)
+ {
+ MessageQueue->msgDblClk.message = 0; /* clear the double click conditions */
+ update = FALSE;
+ }
+ }
+ }
+
+ if (!((first == 0 && last == 0) || (message >= first || message <= last)))
+ {
+ DPRINT("Message out of range!!!\n");
+ RETURN(FALSE);
+ }
+
+ /* update static double click conditions */
+ if (update) MessageQueue->msgDblClk = *msg;
+ }
+ else
+ {
+ if (!((first == 0 && last == 0) || (message >= first || message <= last)))
+ {
+ DPRINT("Message out of range!!!\n");
+ RETURN(FALSE);
+ }
+ }
+
+ if(gspv.bMouseClickLock)
+ {
+ BOOL IsClkLck = FALSE;
+
+ if(msg->message == WM_LBUTTONUP)
+ {
+ IsClkLck = ((msg->time - CurInfo->ClickLockTime) >= gspv.dwMouseClickLockTime);
+ if (IsClkLck && (!CurInfo->ClickLockActive))
+ {
+ CurInfo->ClickLockActive = TRUE;
+ }
+ }
+ else if (msg->message == WM_LBUTTONDOWN)
+ {
+ if (CurInfo->ClickLockActive)
+ {
+ IsClkLck = TRUE;
+ CurInfo->ClickLockActive = FALSE;
+ }
+
+ CurInfo->ClickLockTime = msg->time;
+ }
+
+ if(IsClkLck)
+ {
+ /* Remove and ignore the message */
+ *RemoveMessages = TRUE;
+ RETURN(FALSE);
+ }
+ }
+
+ /* message is accepted now (but may still get dropped) */
+
+ pti->rpdesk->htEx = hittest; /* Now set the capture hit. */
+
+ event.message = msg->message;
+ event.time = msg->time;
+ event.hwnd = msg->hwnd;
+ event.paramL = msg->pt.x;
+ event.paramH = msg->pt.y;
+ co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event );
+
+ hook.pt = msg->pt;
+ hook.hwnd = msg->hwnd;
+ hook.wHitTestCode = hittest;
+ hook.dwExtraInfo = 0/*extra_info*/;
+ if (co_HOOK_CallHooks( WH_MOUSE, *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
+ message, (LPARAM)&hook ))
+ {
+ hook.pt = msg->pt;
+ hook.hwnd = msg->hwnd;
+ hook.wHitTestCode = hittest;
+ hook.dwExtraInfo = 0/*extra_info*/;
+ co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook );
+
+ DPRINT1("WH_MOUSE dorpped mouse message!\n");
+
+ /* Remove and skip message */
+ *RemoveMessages = TRUE;
+ RETURN(FALSE);
+ }
+
+ if ((hittest == HTERROR) || (hittest == HTNOWHERE))
+ {
+ co_IntSendMessage( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
+ MAKELONG( hittest, msg->message ));
+
+ /* Remove and skip message */
+ *RemoveMessages = TRUE;
+ RETURN(FALSE);
+ }
+
+ if ((*RemoveMessages == FALSE) || MessageQueue->CaptureWindow)
+ {
+ /* Accept the message */
+ msg->message = message;
+ RETURN(TRUE);
+ }
+
+ eatMsg = FALSE;
+
+ if ((msg->message == WM_LBUTTONDOWN) ||
+ (msg->message == WM_RBUTTONDOWN) ||
+ (msg->message == WM_MBUTTONDOWN) ||
+ (msg->message == WM_XBUTTONDOWN))
+ {
+ /* Send the WM_PARENTNOTIFY,
+ * note that even for double/nonclient clicks
+ * notification message is still WM_L/M/RBUTTONDOWN.
+ */
+ MsqSendParentNotify(pwndMsg, msg->message, 0, msg->pt );
+
+ /* Activate the window if needed */
+
+ if (msg->hwnd != MessageQueue->ActiveWindow)
+ {
+ PWND pwndTop = pwndMsg;
+ while (pwndTop)
+ {
+ if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
+ pwndTop = IntGetParent( pwndTop );
+ }
+
+ if (pwndTop && pwndTop != pwndDesktop)
+ {
+ LONG ret = co_IntSendMessage( msg->hwnd,
+ WM_MOUSEACTIVATE,
+ (WPARAM)UserHMGetHandle(pwndTop),
+ MAKELONG( hittest, msg->message));
+ switch(ret)
+ {
+ case MA_NOACTIVATEANDEAT:
+ eatMsg = TRUE;
+ /* fall through */
+ case MA_NOACTIVATE:
+ break;
+ case MA_ACTIVATEANDEAT:
+ eatMsg = TRUE;
+ /* fall through */
+ case MA_ACTIVATE:
+ case 0:
+ if(!co_IntMouseActivateWindow(pwndMsg)) eatMsg = TRUE;
+ break;
+ default:
+ DPRINT1( "unknown WM_MOUSEACTIVATE code %d\n", ret );
+ break;
+ }
+ }
+ }
+ }
+
+ /* send the WM_SETCURSOR message */
+
+ /* Windows sends the normal mouse message as the message parameter
+ in the WM_SETCURSOR message even if it's non-client mouse message */
+ co_IntSendMessage( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd, MAKELONG( hittest, msg->message ));
+
+ msg->message = message;
+ RETURN(!eatMsg);
+
+CLEANUP:
+ if(pwndMsg)
+ UserDereferenceObject(pwndMsg);
+
+ END_CLEANUP;
+}
+
+BOOL co_IntProcessKeyboardMessage(MSG* Msg, BOOL* RemoveMessages)
+{
+ EVENTMSG Event;
+
+ Event.message = Msg->message;
+ Event.hwnd = Msg->hwnd;
+ Event.time = Msg->time;
+ Event.paramL = (Msg->wParam & 0xFF) | (HIWORD(Msg->lParam) << 8);
+ Event.paramH = Msg->lParam & 0x7FFF;
+ if (HIWORD(Msg->lParam) & 0x0100) Event.paramH |= 0x8000;
+ co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
+
+ if (co_HOOK_CallHooks( WH_KEYBOARD,
+ *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
+ LOWORD(Msg->wParam),
+ Msg->lParam))
+ {
+ /* skip this message */
+ co_HOOK_CallHooks( WH_CBT,
+ HCBT_KEYSKIPPED,
+ LOWORD(Msg->wParam),
+ Msg->lParam );
+ DPRINT1("KeyboardMessage WH_CBT Call Hook return!\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, UINT first, UINT last)
+{
+ if ( IS_MOUSE_MESSAGE(Msg->message))
+ {
+ return co_IntProcessMouseMessage(Msg, RemoveMessages, first, last);
+ }
+ else if ( IS_KBD_MESSAGE(Msg->message))
+ {
+ return co_IntProcessKeyboardMessage(Msg, RemoveMessages);
+ }
+
+ return TRUE;
+}
+
+BOOL APIENTRY
+co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
+ IN BOOL Remove,
+ IN PWND Window,
+ IN UINT MsgFilterLow,
+ IN UINT MsgFilterHigh,
+ OUT MSG* pMsg)
+{
+ BOOL AcceptMessage;
+ MSG msg;
+
+ if(!(MessageQueue->MouseMoved))
+ return FALSE;
+
+ msg = MessageQueue->MouseMoveMsg;
+
+ AcceptMessage = co_IntProcessMouseMessage(&msg, &Remove, MsgFilterLow, MsgFilterHigh);
+
+ if(AcceptMessage)
+ *pMsg = msg;
+
+ if(Remove)
+ MessageQueue->MouseMoved = FALSE;
+
+ return AcceptMessage;
+}
+
+BOOL APIENTRY
+co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
+ IN BOOL Remove,
+ IN PWND Window,
+ IN UINT MsgFilterLow,
+ IN UINT MsgFilterHigh,
+ OUT MSG* pMsg)
+{
+
+ BOOL AcceptMessage;
+ PUSER_MESSAGE CurrentMessage;
+ PLIST_ENTRY ListHead, CurrentEntry = NULL;
+ MSG msg;
+
+ ListHead = &MessageQueue->HardwareMessagesListHead;
+ CurrentEntry = ListHead->Flink;
+
+ while(CurrentEntry != ListHead)
+ {
+ CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
+ ListEntry);
+
+ msg = CurrentMessage->Msg;
+
+ AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, MsgFilterLow, MsgFilterHigh);
+
+ CurrentEntry = CurrentMessage->ListEntry.Flink;
+
+ if (Remove)
+ {
+ RemoveEntryList(&CurrentMessage->ListEntry);
+ MsqDestroyMessage(CurrentMessage);
+ }
+
+ if(AcceptMessage)
+ {
+ *pMsg = msg;
+ return TRUE;
+ }
+
+ }
+
+ return FALSE;
}
BOOLEAN APIENTRY
-co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
- IN BOOLEAN Hardware,
+MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
IN BOOLEAN Remove,
IN PWND Window,
IN UINT MsgFilterLow,
IN UINT MsgFilterHigh,
- OUT PUSER_MESSAGE* Message)
+ OUT PMSG Message)
{
PLIST_ENTRY CurrentEntry;
PUSER_MESSAGE CurrentMessage;
PLIST_ENTRY ListHead;
-
- if (Hardware)
- {
- return(co_MsqPeekHardwareMessage( MessageQueue,
- Window,
- MsgFilterLow,
- MsgFilterHigh,
- Remove,
- Message));
- }
-
+
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
ListHead = &MessageQueue->PostedMessagesListHead;
while (CurrentEntry != ListHead)
@@ -1385,12 +1197,14 @@ co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
( MsgFilterLow <= CurrentMessage->Msg.message &&
MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
{
+ *Message= CurrentMessage->Msg;
+
if (Remove)
{
- RemoveEntryList(&CurrentMessage->ListEntry);
+ RemoveEntryList(&CurrentMessage->ListEntry);
+ MsqDestroyMessage(CurrentMessage);
}
- *Message = CurrentMessage;
return(TRUE);
}
CurrentEntry = CurrentEntry->Flink;
@@ -1403,21 +1217,14 @@ NTSTATUS FASTCALL
co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
UINT MsgFilterMin, UINT MsgFilterMax)
{
- PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent};
NTSTATUS ret;
- IdlePing(); // Going to wait so send Idle ping.
-
UserLeaveCo();
-
- ret = KeWaitForMultipleObjects(2,
- WaitObjects,
- WaitAny,
- Executive,
- UserMode,
- FALSE,
- NULL,
- NULL);
+ ret = KeWaitForSingleObject(MessageQueue->NewMessages,
+ Executive,
+ UserMode,
+ FALSE,
+ NULL);
UserEnterCo();
return ret;
}
@@ -1632,18 +1439,6 @@ MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
IntDereferenceMessageQueue(MessageQueue);
}
-PHOOKTABLE FASTCALL
-MsqGetHooks(PUSER_MESSAGE_QUEUE Queue)
-{
- return Queue->Hooks;
-}
-
-VOID FASTCALL
-MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks)
-{
- Queue->Hooks = Hooks;
-}
-
LPARAM FASTCALL
MsqSetMessageExtraInfo(LPARAM lParam)
{
diff --git a/subsystems/win32/win32k/ntuser/ntstubs.c b/subsystems/win32/win32k/ntuser/ntstubs.c
index 3219a953411..401af3de778 100644
--- a/subsystems/win32/win32k/ntuser/ntstubs.c
+++ b/subsystems/win32/win32k/ntuser/ntstubs.c
@@ -199,39 +199,6 @@ NtUserDrawAnimatedRects(
return 0;
}
-BOOL
-APIENTRY
-NtUserEnumDisplayDevices (
- PUNICODE_STRING lpDevice, /* device name */
- DWORD iDevNum, /* display device */
- PDISPLAY_DEVICEW lpDisplayDevice, /* device information */
- DWORD dwFlags ) /* reserved */
-{
- DPRINT1("NtUserEnumDisplayDevices() is UNIMPLEMENTED!\n");
- if (lpDevice->Length == 0 && iDevNum > 0)
- {
- /* Only one display device present */
- return FALSE;
- }
- else if (lpDevice->Length != 0)
- {
- /* Can't enumerate monitors :( */
- return FALSE;
- }
- if (lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
- return FALSE;
-
- wcscpy(lpDisplayDevice->DeviceName, L"\\\\.\\DISPLAY1");
- wcscpy(lpDisplayDevice->DeviceString, L"");
- lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
- | DISPLAY_DEVICE_MODESPRUNED
- | DISPLAY_DEVICE_PRIMARY_DEVICE
- | DISPLAY_DEVICE_VGA_COMPATIBLE;
- lpDisplayDevice->DeviceID[0] = L'0';
- lpDisplayDevice->DeviceKey[0] = L'0';
- return TRUE;
-}
-
DWORD
APIENTRY
NtUserEvent(
@@ -1184,5 +1151,335 @@ NtUserCtxDisplayIOCtl(
return 0;
}
+/*
+ * @unimplemented
+ */
+DWORD
+APIENTRY
+NtUserDrawMenuBarTemp(
+ HWND hWnd,
+ HDC hDC,
+ PRECT hRect,
+ HMENU hMenu,
+ HFONT hFont)
+{
+ /* we'll use this function just for caching the menu bar */
+ UNIMPLEMENTED
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+DWORD APIENTRY
+NtUserEndDeferWindowPosEx(DWORD Unknown0,
+ DWORD Unknown1)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
+ */
+/*
+ * @unimplemented
+ */
+BOOL APIENTRY
+NtUserFillWindow(HWND hWndPaint,
+ HWND hWndPaint1,
+ HDC hDC,
+ HBRUSH hBrush)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL APIENTRY
+NtUserFlashWindowEx(IN PFLASHWINFO pfwi)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL APIENTRY
+NtUserLockWindowUpdate(HWND hWnd)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+DWORD APIENTRY
+NtUserRealChildWindowFromPoint(DWORD Unknown0,
+ DWORD Unknown1,
+ DWORD Unknown2)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+DWORD APIENTRY
+NtUserSetImeOwnerWindow(DWORD Unknown0,
+ DWORD Unknown1)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+DWORD APIENTRY
+NtUserSetInternalWindowPos(
+ HWND hwnd,
+ UINT showCmd,
+ LPRECT rect,
+ LPPOINT pt)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL APIENTRY
+NtUserSetLayeredWindowAttributes(HWND hwnd,
+ COLORREF crKey,
+ BYTE bAlpha,
+ DWORD dwFlags)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL APIENTRY
+NtUserSetLogonNotifyWindow(HWND hWnd)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL
+APIENTRY
+NtUserUpdateLayeredWindow(
+ HWND hwnd,
+ HDC hdcDst,
+ POINT *pptDst,
+ SIZE *psize,
+ HDC hdcSrc,
+ POINT *pptSrc,
+ COLORREF crKey,
+ BLENDFUNCTION *pblend,
+ DWORD dwFlags,
+ RECT *prcDirty)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+HWND APIENTRY
+NtUserWindowFromPhysicalPoint(POINT Point)
+{
+ UNIMPLEMENTED
+
+ return NULL;
+}
+
+/*
+ * @unimplemented
+ */
+HDWP APIENTRY
+NtUserDeferWindowPos(HDWP WinPosInfo,
+ HWND Wnd,
+ HWND WndInsertAfter,
+ int x,
+ int y,
+ int cx,
+ int cy,
+ UINT Flags)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+
+/*
+ * NtUserResolveDesktopForWOW
+ *
+ * Status
+ * @unimplemented
+ */
+
+DWORD APIENTRY
+NtUserResolveDesktopForWOW(DWORD Unknown0)
+{
+ UNIMPLEMENTED
+ return 0;
+}
+
+BOOL
+APIENTRY
+NtUserDragDetect(
+ HWND hWnd,
+ POINT pt) // Just like the User call.
+{
+ UNIMPLEMENTED
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL APIENTRY
+NtUserEndMenu(VOID)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @implemented
+ */
+/* NOTE: unused function */
+BOOL APIENTRY
+NtUserTrackPopupMenuEx(
+ HMENU hMenu,
+ UINT fuFlags,
+ int x,
+ int y,
+ HWND hWnd,
+ LPTPMPARAMS lptpm)
+{
+ UNIMPLEMENTED
+
+ return FALSE;
+}
+
+DWORD APIENTRY
+NtUserQuerySendMessage(DWORD Unknown0)
+{
+ UNIMPLEMENTED;
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+DWORD APIENTRY
+NtUserAlterWindowStyle(DWORD Unknown0,
+ DWORD Unknown1,
+ DWORD Unknown2)
+{
+ UNIMPLEMENTED
+
+ return(0);
+}
+
+/*
+ * NtUserSetWindowStationUser
+ *
+ * Status
+ * @unimplemented
+ */
+
+DWORD APIENTRY
+NtUserSetWindowStationUser(
+ DWORD Unknown0,
+ DWORD Unknown1,
+ DWORD Unknown2,
+ DWORD Unknown3)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+BOOL APIENTRY NtUserAddClipboardFormatListener(
+ HWND hwnd
+)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+BOOL APIENTRY NtUserRemoveClipboardFormatListener(
+ HWND hwnd
+)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+BOOL APIENTRY NtUserGetUpdatedClipboardFormats(
+ PUINT lpuiFormats,
+ UINT cFormats,
+ PUINT pcFormatsOut
+)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+/*
+ * @unimplemented
+ */
+DWORD
+APIENTRY
+NtUserGetCursorFrameInfo(
+ DWORD Unknown0,
+ DWORD Unknown1,
+ DWORD Unknown2,
+ DWORD Unknown3)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL
+APIENTRY
+NtUserSetSystemCursor(
+ HCURSOR hcur,
+ DWORD id)
+{
+ return FALSE;
+}
/* EOF */
diff --git a/subsystems/win32/win32k/ntuser/ntuser.c b/subsystems/win32/win32k/ntuser/ntuser.c
index 14857b09f25..d28aa33e2e6 100644
--- a/subsystems/win32/win32k/ntuser/ntuser.c
+++ b/subsystems/win32/win32k/ntuser/ntuser.c
@@ -53,8 +53,10 @@ InitUserAtoms(VOID)
/* FUNCTIONS *****************************************************************/
-
-NTSTATUS FASTCALL InitUserImpl(VOID)
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitUserImpl(VOID)
{
NTSTATUS Status;
@@ -73,16 +75,6 @@ NTSTATUS FASTCALL InitUserImpl(VOID)
return Status;
}
- if (!gpsi)
- {
- gpsi = UserHeapAlloc(sizeof(SERVERINFO));
- if (gpsi)
- {
- RtlZeroMemory(gpsi, sizeof(SERVERINFO));
- DPRINT("Global Server Data -> %x\n", gpsi);
- }
- }
-
InitUserAtoms();
InitSysParams();
@@ -90,6 +82,9 @@ NTSTATUS FASTCALL InitUserImpl(VOID)
return STATUS_SUCCESS;
}
+NTSTATUS
+NTAPI
+InitVideo();
NTSTATUS
NTAPI
@@ -97,10 +92,16 @@ UserInitialize(
HANDLE hPowerRequestEvent,
HANDLE hMediaRequestEvent)
{
+ NTSTATUS Status;
+
// Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA)
// Create Object Directory,,, Looks like create workstation. "\\Windows\\WindowStations"
// Create Event for Diconnect Desktop.
-// Initialize Video.
+
+ /* Initialize Video. */
+ Status = InitVideo();
+ if (!NT_SUCCESS(Status)) return Status;
+
// {
// DrvInitConsole.
// DrvChangeDisplaySettings.
@@ -139,8 +140,8 @@ NtUserInitialize(
{
NTSTATUS Status;
- DPRINT("Enter NtUserInitialize(%lx, %p, %p)\n",
- dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
+ DPRINT1("Enter NtUserInitialize(%lx, %p, %p)\n",
+ dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
/* Check the Windows version */
if (dwWinVersion != 0)
diff --git a/subsystems/win32/win32k/ntuser/object.c b/subsystems/win32/win32k/ntuser/object.c
index 0c3fb075d7e..222b36cb6b8 100644
--- a/subsystems/win32/win32k/ntuser/object.c
+++ b/subsystems/win32/win32k/ntuser/object.c
@@ -330,8 +330,8 @@ UserCreateObject( PUSER_HANDLE_TABLE ht,
{
case otWindow:
// case otMenu:
-// case otHook:
-// case otCallProc:
+ case otHook:
+ case otCallProc:
case otInputContext:
Object = DesktopHeapAlloc(rpdesk, size);
dt = TRUE;
@@ -420,8 +420,8 @@ UserDereferenceObject(PVOID object)
{
case otWindow:
// case otMenu:
-// case otHook:
-// case otCallProc:
+ case otHook:
+ case otCallProc:
case otInputContext:
return DesktopHeapFree(((PTHRDESKHEAD)object)->rpdesk, object);
diff --git a/subsystems/win32/win32k/ntuser/simplecall.c b/subsystems/win32/win32k/ntuser/simplecall.c
index af977096c8a..953f936574a 100644
--- a/subsystems/win32/win32k/ntuser/simplecall.c
+++ b/subsystems/win32/win32k/ntuser/simplecall.c
@@ -228,21 +228,6 @@ NtUserCallOneParam(
RETURN (ret);
}
- case ONEPARAM_ROUTINE_ISWINDOWINDESTROY:
- {
- PWND Window;
- DWORD_PTR Result;
-
- if(!(Window = UserGetWindowObject((HWND)Param)))
- {
- RETURN( FALSE);
- }
-
- Result = (DWORD_PTR)IntIsWindowInDestroy(Window);
-
- RETURN( Result);
- }
-
case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
{
BOOL Enable;
@@ -267,7 +252,7 @@ NtUserCallOneParam(
RETURN( FALSE);
}
- case ONEPARAM_ROUTINE_MSQSETWAKEMASK:
+ case ONEPARAM_ROUTINE_GETINPUTEVENT:
RETURN( (DWORD_PTR)IntMsqSetWakeMask(Param));
case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
@@ -284,12 +269,7 @@ NtUserCallOneParam(
case ONEPARAM_ROUTINE_GETQUEUESTATUS:
{
- DWORD Ret;
- WORD changed_bits, wake_bits;
- Ret = IntGetQueueStatus(FALSE);
- changed_bits = LOWORD(Ret);
- wake_bits = HIWORD(Ret);
- RETURN( MAKELONG(changed_bits & Param, wake_bits & Param));
+ RETURN (IntGetQueueStatus((DWORD)Param));
}
case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
/* FIXME: Should use UserEnterShared */
@@ -473,6 +453,8 @@ NtUserCallTwoParam(
case TWOPARAM_ROUTINE_SETCURSORPOS:
RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, FALSE));
+ case TWOPARAM_ROUTINE_UNHOOKWINDOWSHOOK:
+ RETURN( IntUnhookWindowsHook((int)Param1, (HOOKPROC)Param2));
}
DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
Routine, Param1, Param2);
@@ -713,6 +695,21 @@ NtUserCallHwndParam(
UserLeave();
return 0;
}
+
+ case HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT:
+ {
+ PWND pWnd;
+ PNOTIFYEVENT pne;
+ UserEnterExclusive();
+ pne = (PNOTIFYEVENT)Param;
+ if (hWnd)
+ pWnd = UserGetWindowObject(hWnd);
+ else
+ pWnd = NULL;
+ IntNotifyWinEvent(pne->event, pWnd, pne->idObject, pne->idChild, pne->flags);
+ UserLeave();
+ return 0;
+ }
}
UNIMPLEMENTED;
diff --git a/subsystems/win32/win32k/ntuser/timer.c b/subsystems/win32/win32k/ntuser/timer.c
index f9d83d6f27f..b3a7fbde3bc 100644
--- a/subsystems/win32/win32k/ntuser/timer.c
+++ b/subsystems/win32/win32k/ntuser/timer.c
@@ -527,7 +527,9 @@ IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer)
return pTmr ? TRUE : FALSE;
}
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitTimerImpl(VOID)
{
ULONG BitmapBytes;
diff --git a/subsystems/win32/win32k/ntuser/windc.c b/subsystems/win32/win32k/ntuser/windc.c
index e6b3cfa5ad9..e5534172c6b 100644
--- a/subsystems/win32/win32k/ntuser/windc.c
+++ b/subsystems/win32/win32k/ntuser/windc.c
@@ -41,6 +41,9 @@ DceCreateDisplayDC(VOID)
UNICODE_STRING DriverName;
RtlInitUnicodeString(&DriverName, L"DISPLAY");
hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
+
+ co_IntGraphicsCheck(TRUE);
+
//
// If NULL, first time through! Build the default window dc!
//
diff --git a/subsystems/win32/win32k/ntuser/window.c b/subsystems/win32/win32k/ntuser/window.c
index 0b270cf8c0b..73b6d9af7cf 100644
--- a/subsystems/win32/win32k/ntuser/window.c
+++ b/subsystems/win32/win32k/ntuser/window.c
@@ -15,7 +15,6 @@
#define NDEBUG
#include
-
/* dialog resources appear to pass this in 16 bits, handle them properly */
#define CW_USEDEFAULT16 (0x8000)
@@ -29,7 +28,9 @@
* Initialize windowing implementation.
*/
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitWindowImpl(VOID)
{
return STATUS_SUCCESS;
@@ -163,7 +164,6 @@ IntIsWindow(HWND hWnd)
}
-
PWND FASTCALL
IntGetParent(PWND Wnd)
{
@@ -179,7 +179,6 @@ IntGetParent(PWND Wnd)
return NULL;
}
-
/*
* IntWinListChildren
*
@@ -348,7 +347,7 @@ static LRESULT co_UserFreeWindow(PWND Window,
Window->state2 |= WNDS2_INDESTROY;
Window->style &= ~WS_VISIBLE;
- IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, 0);
+ IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
/* remove the window already at this point from the thread window list so we
don't get into trouble when destroying the thread windows while we're still
@@ -399,8 +398,11 @@ static LRESULT co_UserFreeWindow(PWND Window,
if(BelongsToThreadData)
co_IntSendMessage(Window->head.h, WM_NCDESTROY, 0, 0);
}
+
DestroyTimersForWindow(ThreadData, Window);
- HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too!
+
+ /* Unregister hot keys */
+ UnregisterWindowHotKeys (Window);
/* flush the message queue */
MsqRemoveWindowMessagesFromQueue(Window);
@@ -421,9 +423,6 @@ static LRESULT co_UserFreeWindow(PWND Window,
ThreadData->rpdesk->rpwinstaParent->ShellListView = NULL;
}
- /* Unregister hot keys */
- UnregisterWindowHotKeys (Window);
-
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
#if 0 /* FIXME */
@@ -657,22 +656,6 @@ IntSetWindowProc(PWND pWnd,
return Ret;
}
-// Move this to user space!
-BOOL FASTCALL
-IntGetWindowInfo(PWND Wnd, PWINDOWINFO pwi)
-{
- pwi->cbSize = sizeof(WINDOWINFO);
- pwi->rcWindow = Wnd->rcWindow;
- pwi->rcClient = Wnd->rcClient;
- pwi->dwStyle = Wnd->style;
- pwi->dwExStyle = Wnd->ExStyle;
- pwi->dwWindowStatus = (UserGetForegroundWindow() == Wnd->head.h); /* WS_ACTIVECAPTION */
- IntGetWindowBorderMeasures(Wnd, &pwi->cxWindowBorders, &pwi->cyWindowBorders);
- pwi->atomWindowType = (Wnd->pcls ? Wnd->pcls->atomClassName : 0);
- pwi->wCreatorVersion = 0x400; /* FIXME - return a real version number */
- return TRUE;
-}
-
static BOOL FASTCALL
IntSetMenu(
PWND Wnd,
@@ -801,25 +784,6 @@ IntGetClientRect(PWND Window, RECTL *Rect)
}
-#if 0
-HWND FASTCALL
-IntGetFocusWindow(VOID)
-{
- PUSER_MESSAGE_QUEUE Queue;
- PDESKTOP pdo = IntGetActiveDesktop();
-
- if( !pdo )
- return NULL;
-
- Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
-
- if (Queue == NULL)
- return(NULL);
- else
- return(Queue->FocusWindow);
-}
-#endif
-
PMENU_OBJECT FASTCALL
IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
{
@@ -1168,6 +1132,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
}
+ IntNotifyWinEvent(EVENT_OBJECT_PARENTCHANGE, Wnd ,OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
/*
* SetParent additionally needs to make hwnd the top window
* in the z-order and send the expected WM_WINDOWPOSCHANGING and
@@ -1227,13 +1192,6 @@ IntUnlinkWindow(PWND Wnd)
Wnd->spwndPrev = Wnd->spwndNext = NULL;
}
-BOOL FASTCALL
-IntIsWindowInDestroy(PWND Window)
-{
- return ((Window->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY);
-}
-
-
BOOL
FASTCALL
IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
@@ -1281,19 +1239,6 @@ IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
/* FUNCTIONS *****************************************************************/
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserAlterWindowStyle(DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2)
-{
- UNIMPLEMENTED
-
- return(0);
-}
-
/*
* As best as I can figure, this function is used by EnumWindows,
* EnumChildWindows, EnumDesktopWindows, & EnumThreadWindows.
@@ -1635,6 +1580,33 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
pti = PsGetCurrentThreadWin32Thread();
+ if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL))
+ {
+ if (ParentWindow)
+ {
+ if ( (Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD &&
+ ParentWindow->ExStyle & WS_EX_LAYOUTRTL &&
+ !(ParentWindow->ExStyle & WS_EX_NOINHERITLAYOUT) )
+ Cs->dwExStyle |= WS_EX_LAYOUTRTL;
+ }
+ else
+ {/*
+ Note from MSDN http://msdn.microsoft.com/en-us/library/aa913269.aspx :
+
+ Dialog boxes and message boxes do not inherit layout, so you must
+ set the layout explicitly.
+ */
+ if ( Class && Class->fnid != FNID_DIALOG)
+ {
+ PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+ if (ppi->dwLayout & LAYOUT_RTL)
+ {
+ Cs->dwExStyle |= WS_EX_LAYOUTRTL;
+ }
+ }
+ }
+ }
+
/* Automatically add WS_EX_WINDOWEDGE */
if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
((!(Cs->dwExStyle & WS_EX_STATICEDGE)) &&
@@ -1877,17 +1849,18 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
PLARGE_STRING WindowName)
{
PWND Window = NULL, ParentWindow = NULL, OwnerWindow;
- HWND hWnd, hWndParent, hWndOwner;
- DWORD dwStyle;
+ HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter;
PWINSTATION_OBJECT WinSta;
PCLS Class = NULL;
SIZE Size;
POINT MaxPos;
- CBT_CREATEWNDW CbtCreate;
+ CBT_CREATEWNDW * pCbtCreate;
LRESULT Result;
USER_REFERENCE_ENTRY ParentRef, Ref;
PTHREADINFO pti;
DWORD dwShowMode = SW_SHOW;
+ CREATESTRUCTW *pCsw = NULL;
+ PVOID pszClass = NULL, pszName = NULL;
DECLARE_RETURN(PWND);
/* Get the current window station and reference it */
@@ -1900,6 +1873,9 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
WinSta = pti->rpdesk->rpwinstaParent;
ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
+ pCsw = NULL;
+ pCbtCreate = NULL;
+
/* Get the class and reference it*/
Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
if(!Class)
@@ -1956,30 +1932,101 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
RETURN(0);
}
- hWnd = Window->head.h;
+ hWnd = UserHMGetHandle(Window);
+ hwndInsertAfter = HWND_TOP;
UserRefObjectCo(Window, &Ref);
ObDereferenceObject(WinSta);
- /* Call the WH_CBT hook */
- dwStyle = Cs->style;
- Cs->style = Window->style; /* HCBT_CREATEWND needs the real window style */
- CbtCreate.lpcs = Cs;
- CbtCreate.hwndInsertAfter = HWND_TOP;
-
- if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
+ //// Check for a hook to eliminate overhead. ////
+ if ( ISITHOOKED(WH_CBT) || (pti->rpdesk->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_CBT)) )
{
- DPRINT1("HCBT_CREATEWND hook failed!\n");
- RETURN( (PWND) NULL);
+ // Allocate the calling structures Justin Case this goes Global.
+ pCsw = ExAllocatePoolWithTag(NonPagedPool, sizeof(CREATESTRUCTW), TAG_HOOK);
+ pCbtCreate = ExAllocatePoolWithTag(NonPagedPool, sizeof(CBT_CREATEWNDW), TAG_HOOK);
+
+ /* Fill the new CREATESTRUCTW */
+ RtlCopyMemory(pCsw, Cs, sizeof(CREATESTRUCTW));
+ pCsw->style = Window->style; /* HCBT_CREATEWND needs the real window style */
+
+ // Based on the assumption this is from "unicode source" user32, ReactOS, answer is yes.
+ if (!IS_ATOM(ClassName->Buffer))
+ {
+ if (Window->state & WNDS_ANSICREATOR)
+ {
+ ANSI_STRING AnsiString;
+ AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(ClassName)+sizeof(CHAR);
+ pszClass = UserHeapAlloc(AnsiString.MaximumLength);
+ RtlZeroMemory(pszClass, AnsiString.MaximumLength);
+ AnsiString.Buffer = (PCHAR)pszClass;
+ RtlUnicodeStringToAnsiString(&AnsiString, ClassName, FALSE);
+ }
+ else
+ {
+ UNICODE_STRING UnicodeString;
+ UnicodeString.MaximumLength = ClassName->Length + sizeof(UNICODE_NULL);
+ pszClass = UserHeapAlloc(UnicodeString.MaximumLength);
+ RtlZeroMemory(pszClass, UnicodeString.MaximumLength);
+ UnicodeString.Buffer = (PWSTR)pszClass;
+ RtlCopyUnicodeString(&UnicodeString, ClassName);
+ }
+ if (pszClass) pCsw->lpszClass = UserHeapAddressToUser(pszClass);
+ }
+ if (WindowName->Length)
+ {
+ UNICODE_STRING Name;
+ Name.Buffer = WindowName->Buffer;
+ Name.Length = WindowName->Length;
+ Name.MaximumLength = WindowName->MaximumLength;
+
+ if (Window->state & WNDS_ANSICREATOR)
+ {
+ ANSI_STRING AnsiString;
+ AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name)+sizeof(CHAR);
+ pszName = UserHeapAlloc(AnsiString.MaximumLength);
+ RtlZeroMemory(pszName, AnsiString.MaximumLength);
+ AnsiString.Buffer = (PCHAR)pszName;
+ RtlUnicodeStringToAnsiString(&AnsiString, &Name, FALSE);
+ }
+ else
+ {
+ UNICODE_STRING UnicodeString;
+ UnicodeString.MaximumLength = Name.Length + sizeof(UNICODE_NULL);
+ pszName = UserHeapAlloc(UnicodeString.MaximumLength);
+ RtlZeroMemory(pszName, UnicodeString.MaximumLength);
+ UnicodeString.Buffer = (PWSTR)pszName;
+ RtlCopyUnicodeString(&UnicodeString, &Name);
+ }
+ if (pszName) pCsw->lpszName = UserHeapAddressToUser(pszName);
+ }
+
+ pCbtCreate->lpcs = pCsw;
+ pCbtCreate->hwndInsertAfter = hwndInsertAfter;
+
+ //// Call the WH_CBT hook ////
+ Result = co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) pCbtCreate);
+ if (Result != 0)
+ {
+ DPRINT1("WH_CBT HCBT_CREATEWND hook failed! 0x%x\n", Result);
+ RETURN( (PWND) NULL);
+ }
+ // Write back changes.
+ Cs->cx = pCsw->cx;
+ Cs->cy = pCsw->cy;
+ Cs->x = pCsw->x;
+ Cs->y = pCsw->y;
+ hwndInsertAfter = pCbtCreate->hwndInsertAfter;
}
- Cs->style = dwStyle; /* NCCREATE and WM_NCCALCSIZE need the original values*/
+ /* NCCREATE and WM_NCCALCSIZE need the original values */
+ Cs->lpszName = (LPCWSTR) WindowName;
+ Cs->lpszClass = (LPCWSTR) ClassName;
/* Send the WM_GETMINMAXINFO message*/
Size.cx = Cs->cx;
Size.cy = Cs->cy;
- if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
+ if ((Cs->style & WS_THICKFRAME) || !(Cs->style & (WS_POPUP | WS_CHILD)))
{
POINT MaxSize, MaxPos, MinTrack, MaxTrack;
@@ -2007,14 +2054,14 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
if (NULL != ParentWindow)
{
/* link the window into the siblings list */
- if ((dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
+ if ((Cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
IntLinkHwnd(Window, HWND_BOTTOM);
else
- IntLinkHwnd(Window, HWND_TOP);
+ IntLinkHwnd(Window, hwndInsertAfter);
}
/* Send the NCCREATE message */
- Result = co_IntSendMessage(Window->head.h, WM_NCCREATE, 0, (LPARAM) Cs);
+ Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs);
if (!Result)
{
DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n");
@@ -2032,7 +2079,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
/* Send the WM_CREATE message. */
- Result = co_IntSendMessage(Window->head.h, WM_CREATE, 0, (LPARAM) Cs);
+ Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs);
if (Result == (LRESULT)-1)
{
DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n");
@@ -2040,7 +2087,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
}
/* Send the EVENT_OBJECT_CREATE event*/
- IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, 0);
+ IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, CHILDID_SELF, 0);
/* By setting the flag below it can be examined to determine if the window
was created successfully and a valid pwnd was passed back to caller since
@@ -2102,7 +2149,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
if (Window->ExStyle & WS_EX_MDICHILD)
{
- co_IntSendMessage(ParentWindow->head.h, WM_MDIREFRESHMENU, 0, 0);
+ co_IntSendMessage(UserHMGetHandle(ParentWindow), WM_MDIREFRESHMENU, 0, 0);
/* ShowWindow won't activate child windows */
co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
}
@@ -2114,6 +2161,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
CLEANUP:
if (!_ret_)
{
+ DPRINT("co_UserCreateWindowEx(): Error Created window!\n");
/* If the window was created, the class will be dereferenced by co_UserDestroyWindow */
if (Window)
co_UserDestroyWindow(Window);
@@ -2121,6 +2169,11 @@ CLEANUP:
IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi);
}
+ if (pCsw) ExFreePoolWithTag(pCsw, TAG_HOOK);
+ if (pCbtCreate) ExFreePoolWithTag(pCbtCreate, TAG_HOOK);
+ if (pszName) UserHeapFree(pszName);
+ if (pszClass) UserHeapFree(pszClass);
+
if (Window)
{
UserDerefObjectCo(Window);
@@ -2269,10 +2322,11 @@ NtUserCreateWindowEx(
Cs.cy = nHeight;
Cs.x = x;
Cs.y = y;
-// Cs.lpszName = (LPCWSTR) WindowName->Buffer;
-// Cs.lpszClass = (LPCWSTR) ClassName->Buffer;
- Cs.lpszName = (LPCWSTR) plstrWindowName;
- Cs.lpszClass = (LPCWSTR) &ustrClassName;
+ Cs.lpszName = (LPCWSTR) plstrWindowName->Buffer;
+ if (IS_ATOM(plstrClassName))
+ Cs.lpszClass = (LPCWSTR) plstrClassName;
+ else
+ Cs.lpszClass = (LPCWSTR) plstrClassName->Buffer;
Cs.dwExStyle = dwExStyle;
UserEnterExclusive();
@@ -2280,7 +2334,7 @@ NtUserCreateWindowEx(
/* Call the internal function */
pwnd = co_UserCreateWindowEx(&Cs, &ustrClassName, plstrWindowName);
- if(!pwnd)
+ if(!pwnd)
{
DPRINT1("co_UserCreateWindowEx failed!\n");
}
@@ -2300,25 +2354,7 @@ cleanup:
return hwnd;
}
-
-/*
- * @unimplemented
- */
-HDWP APIENTRY
-NtUserDeferWindowPos(HDWP WinPosInfo,
- HWND Wnd,
- HWND WndInsertAfter,
- int x,
- int y,
- int cx,
- int cy,
- UINT Flags)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
+
BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
{
@@ -2343,7 +2379,11 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
/* If window was created successfully and it is hooked */
if ((Window->state2 & WNDS2_WMCREATEMSGPROCESSED))
{
- if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE;
+ if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0))
+ {
+ DPRINT1("Destroy Window WH_CBT Call Hook return!\n");
+ return FALSE;
+ }
}
/* Inform the parent */
@@ -2452,7 +2492,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
msg.wParam = IntGetSysCursorInfo()->ButtonsDown;
msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
msg.pt = gpsi->ptCursor;
- MsqInsertSystemMessage(&msg);
+ co_MsqInsertMouseMessage(&msg);
if (!IntIsWindow(Window->head.h))
{
@@ -2498,56 +2538,6 @@ CLEANUP:
}
-
-/*
- * @unimplemented
- */
-DWORD
-APIENTRY
-NtUserDrawMenuBarTemp(
- HWND hWnd,
- HDC hDC,
- PRECT hRect,
- HMENU hMenu,
- HFONT hFont)
-{
- /* we'll use this function just for caching the menu bar */
- UNIMPLEMENTED
- return 0;
-}
-
-
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserEndDeferWindowPosEx(DWORD Unknown0,
- DWORD Unknown1)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
-/*
- * FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
- */
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserFillWindow(HWND hWndPaint,
- HWND hWndPaint1,
- HDC hDC,
- HBRUSH hBrush)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
static HWND FASTCALL
IntFindWindow(PWND Parent,
PWND ChildAfter,
@@ -2827,18 +2817,6 @@ CLEANUP:
}
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserFlashWindowEx(IN PFLASHWINFO pfwi)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
/*
* @implemented
*/
@@ -3685,19 +3663,6 @@ CLEANUP:
END_CLEANUP;
}
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserLockWindowUpdate(HWND hWnd)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
/*
* @implemented
*/
@@ -3786,20 +3751,6 @@ CLEANUP:
}
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserRealChildWindowFromPoint(DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
/*
* @implemented
*/
@@ -3839,62 +3790,6 @@ CLEANUP:
}
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserSetImeOwnerWindow(DWORD Unknown0,
- DWORD Unknown1)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserSetInternalWindowPos(
- HWND hwnd,
- UINT showCmd,
- LPRECT rect,
- LPPOINT pt)
-{
- UNIMPLEMENTED
-
- return 0;
-
-}
-
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserSetLayeredWindowAttributes(HWND hwnd,
- COLORREF crKey,
- BYTE bAlpha,
- DWORD dwFlags)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserSetLogonNotifyWindow(HWND hWnd)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
/*
* @implemented
*/
@@ -4275,40 +4170,6 @@ NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow)
#endif
}
-
-/*
- * @unimplemented
- */
-BOOL
-APIENTRY
-NtUserUpdateLayeredWindow(
- HWND hwnd,
- HDC hdcDst,
- POINT *pptDst,
- SIZE *psize,
- HDC hdcSrc,
- POINT *pptSrc,
- COLORREF crKey,
- BLENDFUNCTION *pblend,
- DWORD dwFlags,
- RECT *prcDirty)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-/*
- * @unimplemented
- */
-HWND APIENTRY
-NtUserWindowFromPhysicalPoint(POINT Point)
-{
- UNIMPLEMENTED
-
- return NULL;
-}
-
/*
* @implemented
*/
@@ -4318,6 +4179,7 @@ NtUserWindowFromPoint(LONG X, LONG Y)
POINT pt;
HWND Ret;
PWND DesktopWindow = NULL, Window = NULL;
+ USHORT hittest;
DECLARE_RETURN(HWND);
USER_REFERENCE_ENTRY Ref;
@@ -4336,7 +4198,7 @@ NtUserWindowFromPoint(LONG X, LONG Y)
UserRefObjectCo(DesktopWindow, &Ref);
pti = PsGetCurrentThreadWin32Thread();
- co_WinPosWindowFromPoint(DesktopWindow, pti->MessageQueue, &pt, &Window);
+ Window = co_WinPosWindowFromPoint(DesktopWindow, &pt, &hittest);
if(Window)
{
diff --git a/subsystems/win32/win32k/ntuser/winpos.c b/subsystems/win32/win32k/ntuser/winpos.c
index 7a9562613c4..b80c9db2e18 100644
--- a/subsystems/win32/win32k/ntuser/winpos.c
+++ b/subsystems/win32/win32k/ntuser/winpos.c
@@ -299,8 +299,10 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
WinPosInitInternalPos(Wnd, &Size, &Wnd->rcWindow);
if (co_HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)Wnd->head.h, ShowFlag))
+ {
+ DPRINT1("WinPosMinMaximize WH_CBT Call Hook return!\n");
return SWP_NOSIZE | SWP_NOMOVE;
-
+ }
if (Wnd->style & WS_MINIMIZE)
{
if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0))
@@ -385,7 +387,6 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
}
}
}
-
return(SwpFlags);
}
@@ -1358,6 +1359,14 @@ co_WinPosSetWindowPos(
co_IntSendMessageNoWait(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
}
+ if ( WinPos.flags & SWP_FRAMECHANGED || WinPos.flags & SWP_STATECHANGED ||
+ !(WinPos.flags & SWP_NOCLIENTSIZE) || !(WinPos.flags & SWP_NOCLIENTMOVE) )
+ {
+ PWND pWnd = UserGetWindowObject(WinPos.hwnd);
+ if (pWnd)
+ IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
+ }
+
return TRUE;
}
@@ -1569,162 +1578,99 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
return(WasVisible);
}
-
-#if 0
-
-/* find child of 'parent' that contains the given point (in parent-relative coords) */
-PWND child_window_from_point(PWND parent, int x, int y )
-{
- PWND Wnd;// = parent->spwndChild;
-
-// LIST_FOR_EACH_ENTRY( Wnd, &parent->children, struct window, entry )
- for (Wnd = parent->spwndChild; Wnd; Wnd = Wnd->spwndNext)
- {
- if (!IntPtInWindow( Wnd, x, y )) continue; /* skip it */
-
- /* if window is minimized or disabled, return at once */
- if (Wnd->style & (WS_MINIMIZE|WS_DISABLED)) return Wnd;
-
- /* if point is not in client area, return at once */
- if (x < Wnd->rcClient.left || x >= Wnd->rcClient.right ||
- y < Wnd->rcClient.top || y >= Wnd->rcClient.bottom)
- return Wnd;
-
- return child_window_from_point( Wnd, x - Wnd->rcClient.left, y - Wnd->rcClient.top );
- }
- return parent; /* not found any child */
-}
-#endif
-
-/* wine server: child_window_from_point
-
-Caller must dereference the "returned" Window
-*/
static
-VOID FASTCALL
+PWND FASTCALL
co_WinPosSearchChildren(
PWND ScopeWin,
- PUSER_MESSAGE_QUEUE OnlyHitTests,
POINT *Point,
- PWND* Window,
USHORT *HitTest
)
{
- PWND Current;
- HWND *List, *phWnd;
- USER_REFERENCE_ENTRY Ref;
+ PWND pwndChild;
+ HWND *List, *phWnd;
- ASSERT_REFS_CO(ScopeWin);
+ if (!(ScopeWin->style & WS_VISIBLE))
+ {
+ return NULL;
+ }
- if ((List = IntWinListChildren(ScopeWin)))
- {
- for (phWnd = List; *phWnd; ++phWnd)
- {
- if (!(Current = UserGetWindowObject(*phWnd)))
- continue;
+ if ((ScopeWin->style & WS_DISABLED))
+ {
+ return NULL;
+ }
- if (!(Current->style & WS_VISIBLE))
- {
- continue;
- }
+ if (!IntPtInWindow(ScopeWin, Point->x, Point->y))
+ {
+ return NULL;
+ }
- if ((Current->style & (WS_POPUP | WS_CHILD | WS_DISABLED)) ==
- (WS_CHILD | WS_DISABLED))
- {
- continue;
- }
+ UserReferenceObject(ScopeWin);
- if (!IntPtInWindow(Current, Point->x, Point->y))
- {
- continue;
- }
-
- if (*Window) UserDereferenceObject(*Window);
- *Window = Current;
- UserReferenceObject(*Window);
-
- if (Current->style & WS_MINIMIZE)
- {
- *HitTest = HTCAPTION;
- break;
- }
-
- if (Current->style & WS_DISABLED)
- {
- *HitTest = HTERROR;
- break;
- }
-
- UserRefObjectCo(Current, &Ref);
-
- if (OnlyHitTests && (Current->head.pti->MessageQueue == OnlyHitTests))
- {
- *HitTest = co_IntSendMessage(Current->head.h, WM_NCHITTEST, 0,
- MAKELONG(Point->x, Point->y));
- if ((*HitTest) == (USHORT)HTTRANSPARENT)
+ if (Point->x - ScopeWin->rcClient.left < ScopeWin->rcClient.right &&
+ Point->y - ScopeWin->rcClient.top < ScopeWin->rcClient.bottom )
+ {
+ List = IntWinListChildren(ScopeWin);
+ if(List)
+ {
+ for (phWnd = List; *phWnd; ++phWnd)
{
- UserDerefObjectCo(Current);
- continue;
+ if (!(pwndChild = UserGetWindowObject(*phWnd)))
+ {
+ continue;
+ }
+
+ pwndChild = co_WinPosSearchChildren(pwndChild, Point, HitTest);
+
+ if(pwndChild != NULL)
+ {
+ /* We found a window. Don't send any more WM_NCHITTEST messages */
+ UserDereferenceObject(ScopeWin);
+ return pwndChild;
+ }
}
- }
- else
- *HitTest = HTCLIENT;
+ }
- if (Point->x >= Current->rcClient.left &&
- Point->x < Current->rcClient.right &&
- Point->y >= Current->rcClient.top &&
- Point->y < Current->rcClient.bottom)
- {
- co_WinPosSearchChildren(Current, OnlyHitTests, Point, Window, HitTest);
- }
+ ExFreePool(List);
+ }
- UserDerefObjectCo(Current);
-
- break;
- }
- ExFreePool(List);
- }
+ *HitTest = co_IntSendMessage(ScopeWin->head.h, WM_NCHITTEST, 0,
+ MAKELONG(Point->x, Point->y));
+ if ((*HitTest) == (USHORT)HTTRANSPARENT)
+ {
+ UserDereferenceObject(ScopeWin);
+ return NULL;
+ }
+
+ return ScopeWin;
}
-/* wine: WINPOS_WindowFromPoint */
-USHORT FASTCALL
-co_WinPosWindowFromPoint(PWND ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *WinPoint,
- PWND* Window)
+PWND FASTCALL
+co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest)
{
- HWND DesktopWindowHandle;
- PWND DesktopWindow;
+ PWND Window;
POINT Point = *WinPoint;
- USHORT HitTest;
+ USER_REFERENCE_ENTRY Ref;
+
+ if( ScopeWin == NULL )
+ {
+ ScopeWin = UserGetDesktopWindow();
+ if(ScopeWin == NULL)
+ return NULL;
+ }
+
+ *HitTest = HTNOWHERE;
ASSERT_REFS_CO(ScopeWin);
+ UserRefObjectCo(ScopeWin, &Ref);
- *Window = NULL;
+ Window = co_WinPosSearchChildren(ScopeWin, &Point, HitTest);
- if(!ScopeWin)
- {
- DPRINT1("WinPosWindowFromPoint(): ScopeWin == NULL!\n");
- return(HTERROR);
- }
+ UserDerefObjectCo(ScopeWin);
+ if(Window)
+ ASSERT_REFS_CO(Window);
+ ASSERT_REFS_CO(ScopeWin);
- if (ScopeWin->style & WS_DISABLED)
- {
- return(HTERROR);
- }
-
- /* Translate the point to the space of the scope window. */
- DesktopWindowHandle = IntGetDesktopWindow();
- if((DesktopWindowHandle != ScopeWin->head.h) &&
- (DesktopWindow = UserGetWindowObject(DesktopWindowHandle)))
- {
- Point.x += ScopeWin->rcClient.left - DesktopWindow->rcClient.left;
- Point.y += ScopeWin->rcClient.top - DesktopWindow->rcClient.top;
- }
-
- HitTest = HTNOWHERE;
-
- co_WinPosSearchChildren(ScopeWin, OnlyHitTests, &Point, Window, &HitTest);
-
- return ((*Window) ? HitTest : HTNOWHERE);
+ return Window;
}
BOOL
diff --git a/subsystems/win32/win32k/ntuser/winsta.c b/subsystems/win32/win32k/ntuser/winsta.c
index 09810d2c82a..855ce9a26c3 100644
--- a/subsystems/win32/win32k/ntuser/winsta.c
+++ b/subsystems/win32/win32k/ntuser/winsta.c
@@ -56,7 +56,9 @@ static GENERIC_MAPPING IntWindowStationMapping =
};
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitWindowStationImpl(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
@@ -1125,25 +1127,6 @@ NtUserUnlockWindowStation(HWINSTA hWindowStation)
return Ret;
}
-/*
- * NtUserSetWindowStationUser
- *
- * Status
- * @unimplemented
- */
-
-DWORD APIENTRY
-NtUserSetWindowStationUser(
- DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
static NTSTATUS FASTCALL
BuildWindowStationNameList(
ULONG dwSize,
diff --git a/subsystems/win32/win32k/objects/arc.c b/subsystems/win32/win32k/objects/arc.c
index 58393036608..e2ffeb50fdc 100644
--- a/subsystems/win32/win32k/objects/arc.c
+++ b/subsystems/win32/win32k/objects/arc.c
@@ -31,7 +31,7 @@ BOOL FASTCALL IntDrawArc( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, d
static
BOOL
FASTCALL
-IntArc( DC *dc,
+IntArc( DC *dc,
int Left,
int Top,
int Right,
@@ -91,7 +91,7 @@ IntArc( DC *dc,
}
if (!PenWidth) PenWidth = 1;
- pbrushPen->ptPenWidth.x = PenWidth;
+ pbrushPen->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.right = Right;
@@ -105,7 +105,7 @@ IntArc( DC *dc,
IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
IntLPtoDP(dc, (LPPOINT)&RectSEpts, 2);
-
+
RectBounds.left += dc->ptlDCOrig.x;
RectBounds.right += dc->ptlDCOrig.x;
RectBounds.top += dc->ptlDCOrig.y;
@@ -172,7 +172,7 @@ IntArc( DC *dc,
}
if (arctype == GdiTypeChord)
PUTLINE(EfCx + CenterX, EfCy + CenterY, SfCx + CenterX, SfCy + CenterY, dc->eboLine);
-
+
pbrushPen->ptPenWidth.x = PenOrigWidth;
PEN_UnlockPen(pbrushPen);
DPRINT("IntArc Exit.\n");
@@ -219,12 +219,6 @@ IntGdiArcInternal(
pdcattr = dc->pdcattr;
- if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(dc);
-
- if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
- DC_vUpdateLineBrush(dc);
-
if (arctype == GdiTypeArcTo)
{
if (dc->dclevel.flPath & DCPATH_CLOCKWISE)
@@ -329,7 +323,14 @@ NtGdiAngleArc(
}
worker.l = dwStartAngle;
worker1.l = dwSweepAngle;
+ DC_vPrepareDCsForBlit(pDC, pDC->rosdc.CombinedClip->rclBounds,
+ NULL, pDC->rosdc.CombinedClip->rclBounds);
+ if (pDC->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(pDC);
+ if (pDC->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(pDC);
Ret = IntGdiAngleArc( pDC, x, y, dwRadius, worker.f, worker1.f);
+ DC_vFinishBlit(pDC, NULL);
DC_UnlockDc( pDC );
return Ret;
}
@@ -364,6 +365,15 @@ NtGdiArcInternal(
return TRUE;
}
+ DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+ NULL, dc->rosdc.CombinedClip->rclBounds);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
Ret = IntGdiArcInternal(
arctype,
dc,
@@ -376,6 +386,7 @@ NtGdiArcInternal(
XEndArc,
YEndArc);
+ DC_vFinishBlit(dc, NULL);
DC_UnlockDc( dc );
return Ret;
}
diff --git a/subsystems/win32/win32k/objects/bitblt.c b/subsystems/win32/win32k/objects/bitblt.c
index f685b1163e5..5854743cdc6 100644
--- a/subsystems/win32/win32k/objects/bitblt.c
+++ b/subsystems/win32/win32k/objects/bitblt.c
@@ -42,6 +42,8 @@ NtGdiAlphaBlend(
{
PDC DCDest;
PDC DCSrc;
+ HDC ahDC[2];
+ PGDIOBJ apObj[2];
SURFACE *BitmapDest, *BitmapSrc;
RECTL DestRect, SourceRect;
BOOL bResult;
@@ -55,45 +57,30 @@ NtGdiAlphaBlend(
return FALSE;
}
- DCDest = DC_LockDc(hDCDest);
- if (NULL == DCDest)
+ DPRINT("Locking DCs\n");
+ ahDC[0] = hDCDest;
+ ahDC[1] = hDCSrc ;
+ GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
+ DCDest = apObj[0];
+ DCSrc = apObj[1];
+
+ if ((NULL == DCDest) || (NULL == DCSrc))
{
- DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCDest);
+ DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return FALSE;
}
- if (DCDest->dctype == DC_TYPE_INFO)
+ if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
{
- DC_UnlockDc(DCDest);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
- if (hDCSrc != hDCDest)
- {
- DCSrc = DC_LockDc(hDCSrc);
- if (NULL == DCSrc)
- {
- DC_UnlockDc(DCDest);
- DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCSrc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if (DCSrc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
- }
- else
- {
- DCSrc = DCDest;
- }
-
DestRect.left = XOriginDest;
DestRect.top = YOriginDest;
DestRect.right = XOriginDest + WidthDest;
@@ -121,35 +108,35 @@ NtGdiAlphaBlend(
!SourceRect.right ||
!SourceRect.bottom)
{
- if (hDCSrc != hDCDest)
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return TRUE;
}
+ /* Prepare DCs for blit */
+ DPRINT("Preparing DCs for blit\n");
+ DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+
/* Determine surfaces to be used in the bitblt */
BitmapDest = DCDest->dclevel.pSurface;
if (!BitmapDest)
{
- if (hDCSrc != hDCDest)
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- return FALSE;
+ bResult = FALSE ;
+ goto leave ;
}
BitmapSrc = DCSrc->dclevel.pSurface;
if (!BitmapSrc)
{
- if (hDCSrc != hDCDest)
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- return FALSE;
+ bResult = FALSE;
+ goto leave;
}
/* Create the XLATEOBJ. */
EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
/* Perform the alpha blend operation */
+ DPRINT("Performing the alpha Blend\n");
bResult = IntEngAlphaBlend(&BitmapDest->SurfObj,
&BitmapSrc->SurfObj,
DCDest->rosdc.CombinedClip,
@@ -159,9 +146,11 @@ NtGdiAlphaBlend(
&BlendObj);
EXLATEOBJ_vCleanup(&exlo);
- DC_UnlockDc(DCDest);
- if (hDCSrc != hDCDest)
- DC_UnlockDc(DCSrc);
+leave :
+ DPRINT("Finishing blit\n");
+ DC_vFinishBlit(DCDest, DCSrc);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return bResult;
}
@@ -182,59 +171,64 @@ NtGdiBitBlt(
{
PDC DCDest;
PDC DCSrc = NULL;
+ HDC ahDC[2];
+ PGDIOBJ apObj[2];
PDC_ATTR pdcattr = NULL;
SURFACE *BitmapDest, *BitmapSrc = NULL;
- RECTL DestRect;
+ RECTL DestRect, SourceRect;
POINTL SourcePoint;
BOOL Status = FALSE;
EXLATEOBJ exlo;
XLATEOBJ *XlateObj = NULL;
BOOL UsesSource = ROP3_USES_SOURCE(ROP);
- DCDest = DC_LockDc(hDCDest);
+ DPRINT("Locking DCs\n");
+ ahDC[0] = hDCDest;
+ ahDC[1] = hDCSrc ;
+ GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
+ DCDest = apObj[0];
+ DCSrc = apObj[1];
+
if (NULL == DCDest)
{
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest);
return FALSE;
}
if (DCDest->dctype == DC_TYPE_INFO)
{
- DC_UnlockDc(DCDest);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if (UsesSource)
{
- if (hDCSrc != hDCDest)
+ if (NULL == DCSrc)
{
- DCSrc = DC_LockDc(hDCSrc);
- if (NULL == DCSrc)
- {
- DC_UnlockDc(DCDest);
- DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
- return FALSE;
- }
- if (DCSrc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
+ return FALSE;
}
- else
+ if (DCSrc->dctype == DC_TYPE_INFO)
{
- DCSrc = DCDest;
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ /* Yes, Windows really returns TRUE in this case */
+ return TRUE;
}
}
+ else if(DCSrc)
+ {
+ DPRINT1("Getting a valid Source handle without using source!!!\n");
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ DCSrc = NULL ;
+ }
pdcattr = DCDest->pdcattr;
- if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(DCDest);
-
DestRect.left = XDest;
DestRect.top = YDest;
DestRect.right = XDest+Width;
@@ -255,8 +249,19 @@ NtGdiBitBlt(
SourcePoint.x += DCSrc->ptlDCOrig.x;
SourcePoint.y += DCSrc->ptlDCOrig.y;
+ /* Calculate Source Rect */
+ SourceRect.left = SourcePoint.x;
+ SourceRect.top = SourcePoint.y;
+ SourceRect.right = SourcePoint.x + DestRect.right - DestRect.left;
+ SourceRect.bottom = SourcePoint.y + DestRect.bottom - DestRect.top ;
}
+ /* Prepare blit */
+ DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(DCDest);
+
/* Determine surfaces to be used in the bitblt */
BitmapDest = DCDest->dclevel.pSurface;
if (!BitmapDest)
@@ -291,14 +296,15 @@ NtGdiBitBlt(
&DCDest->dclevel.pbrFill->ptOrigin,
ROP3_TO_ROP4(ROP));
- if (UsesSource)
+ if (UsesSource)
EXLATEOBJ_vCleanup(&exlo);
cleanup:
- if (UsesSource && hDCSrc != hDCDest)
+ DC_vFinishBlit(DCDest, DCSrc);
+ if (UsesSource)
{
- DC_UnlockDc(DCSrc);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
}
- DC_UnlockDc(DCDest);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return Status;
}
@@ -318,97 +324,38 @@ NtGdiTransparentBlt(
COLORREF TransColor)
{
PDC DCDest, DCSrc;
+ HDC ahDC[2];
+ PGDIOBJ apObj[2];
RECTL rcDest, rcSrc;
SURFACE *BitmapDest, *BitmapSrc = NULL;
- HPALETTE SourcePalette = 0, DestPalette = 0;
- PPALETTE PalDestGDI, PalSourceGDI;
ULONG TransparentColor = 0;
BOOL Ret = FALSE;
EXLATEOBJ exlo;
- if(!(DCDest = DC_LockDc(hdcDst)))
- {
- DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcDst);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (DCDest->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(DCDest);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
+ DPRINT("Locking DCs\n");
+ ahDC[0] = hdcDst;
+ ahDC[1] = hdcSrc ;
+ GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
+ DCDest = apObj[0];
+ DCSrc = apObj[1];
- if((hdcDst != hdcSrc) && !(DCSrc = DC_LockDc(hdcSrc)))
+ if ((NULL == DCDest) || (NULL == DCSrc))
{
- DC_UnlockDc(DCDest);
- DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcSrc);
+ DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hdcDst, hdcSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return FALSE;
}
- if(hdcDst == hdcSrc)
+ if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
{
- DCSrc = DCDest;
- }
-
- if (DCSrc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(DCSrc);
- if(hdcDst != hdcSrc)
- {
- DC_UnlockDc(DCDest);
- }
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
- BitmapDest = DCDest->dclevel.pSurface;
- if (!BitmapDest)
- {
- goto done;
- }
-
- BitmapSrc = DCSrc->dclevel.pSurface;
- if (!BitmapSrc)
- {
- goto done;
- }
-
- DestPalette = BitmapDest->hDIBPalette;
- if (!DestPalette) DestPalette = pPrimarySurface->devinfo.hpalDefault;
-
- SourcePalette = BitmapSrc->hDIBPalette;
- if (!SourcePalette) SourcePalette = pPrimarySurface->devinfo.hpalDefault;
-
- if(!(PalSourceGDI = PALETTE_LockPalette(SourcePalette)))
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- goto done;
- }
- PALETTE_UnlockPalette(PalSourceGDI);
-
- if(DestPalette != SourcePalette)
- {
- if (!(PalDestGDI = PALETTE_LockPalette(DestPalette)))
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- goto done;
- }
- PALETTE_UnlockPalette(PalDestGDI);
- }
- else
- {
- PalDestGDI = PalSourceGDI;
- }
-
- /* Translate Transparent (RGB) Color to the source palette */
- EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalSourceGDI, 0, 0, 0);
- TransparentColor = XLATEOBJ_iXlate(&exlo.xlo, (ULONG)TransColor);
- EXLATEOBJ_vCleanup(&exlo);
-
- EXLATEOBJ_vInitialize(&exlo, PalSourceGDI, PalDestGDI, 0, 0, 0);
-
rcDest.left = xDst;
rcDest.top = yDst;
rcDest.right = rcDest.left + cxDst;
@@ -431,17 +378,39 @@ NtGdiTransparentBlt(
rcSrc.right += DCSrc->ptlDCOrig.x;
rcSrc.bottom += DCSrc->ptlDCOrig.y;
+ /* Prepare for blit */
+ DC_vPrepareDCsForBlit(DCDest, rcDest, DCSrc, rcSrc);
+
+ BitmapDest = DCDest->dclevel.pSurface;
+ if (!BitmapDest)
+ {
+ goto done;
+ }
+
+ BitmapSrc = DCSrc->dclevel.pSurface;
+ if (!BitmapSrc)
+ {
+ goto done;
+ }
+
+ /* Translate Transparent (RGB) Color to the source palette */
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, BitmapSrc->ppal, 0, 0, 0);
+ TransparentColor = XLATEOBJ_iXlate(&exlo.xlo, (ULONG)TransColor);
+ EXLATEOBJ_vCleanup(&exlo);
+
+ EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
+
Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
DCDest->rosdc.CombinedClip, &exlo.xlo, &rcDest, &rcSrc,
TransparentColor, 0);
-done:
- DC_UnlockDc(DCSrc);
- if(hdcDst != hdcSrc)
- {
- DC_UnlockDc(DCDest);
- }
EXLATEOBJ_vCleanup(&exlo);
+
+done:
+ DC_vFinishBlit(DCDest, DCSrc);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+
return Ret;
}
@@ -674,6 +643,8 @@ GreStretchBltMask(
PDC DCDest;
PDC DCSrc = NULL;
PDC DCMask = NULL;
+ HDC ahDC[3];
+ PGDIOBJ apObj[3];
PDC_ATTR pdcattr;
SURFACE *BitmapDest, *BitmapSrc = NULL;
SURFACE *BitmapMask = NULL;
@@ -692,52 +663,59 @@ GreStretchBltMask(
return FALSE;
}
- DCDest = DC_LockDc(hDCDest);
+ DPRINT("Locking DCs\n");
+ ahDC[0] = hDCDest;
+ ahDC[1] = hDCSrc ;
+ ahDC[2] = hDCMask ;
+ GDIOBJ_LockMultipleObjs(3, ahDC, apObj);
+ DCDest = apObj[0];
+ DCSrc = apObj[1];
+ DCMask = apObj[2];
+
if (NULL == DCDest)
{
- DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCDest);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
+ DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest);
return FALSE;
}
if (DCDest->dctype == DC_TYPE_INFO)
{
- DC_UnlockDc(DCDest);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if (UsesSource)
{
- if (hDCSrc != hDCDest)
+ if (NULL == DCSrc)
{
- DCSrc = DC_LockDc(hDCSrc);
- if (NULL == DCSrc)
- {
- DC_UnlockDc(DCDest);
- DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCSrc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (DCSrc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
+ DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
+ return FALSE;
}
- else
+ if (DCSrc->dctype == DC_TYPE_INFO)
{
- DCSrc = DCDest;
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
+ /* Yes, Windows really returns TRUE in this case */
+ return TRUE;
}
}
+ else if(DCSrc)
+ {
+ DPRINT1("Getting a valid Source handle without using source!!!\n");
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ DCSrc = NULL ;
+ }
pdcattr = DCDest->pdcattr;
- if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(DCDest);
-
DestRect.left = XOriginDest;
DestRect.top = YOriginDest;
DestRect.right = XOriginDest+WidthDest;
@@ -767,6 +745,12 @@ GreStretchBltMask(
BrushOrigin.x = 0;
BrushOrigin.y = 0;
+ /* Only prepare Source and Dest, hdcMask represents a DIB */
+ DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(DCDest);
+
/* Determine surfaces to be used in the bitblt */
BitmapDest = DCDest->dclevel.pSurface;
if (BitmapDest == NULL)
@@ -787,28 +771,25 @@ GreStretchBltMask(
BrushOrigin.y += DCDest->ptlDCOrig.y;
/* Make mask surface for source surface */
- if (BitmapSrc && hDCMask)
+ if (BitmapSrc && DCMask)
{
- DCMask = DC_LockDc(hDCMask);
- if (DCMask)
+ BitmapMask = DCMask->dclevel.pSurface;
+ if (BitmapMask &&
+ (BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc ||
+ BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc))
{
- BitmapMask = DCMask->dclevel.pSurface;
- if (BitmapMask &&
- (BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc ||
- BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc))
- {
- DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
- BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
- WidthSrc, HeightSrc);
- goto failed;
- }
- /* Create mask offset point */
- MaskPoint.x = XOriginMask;
- MaskPoint.y = YOriginMask;
- IntLPtoDP(DCMask, &MaskPoint, 1);
- MaskPoint.x += DCMask->ptlDCOrig.x;
- MaskPoint.y += DCMask->ptlDCOrig.x;
+ DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
+ BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
+ WidthSrc, HeightSrc);
+ EXLATEOBJ_vCleanup(&exlo);
+ goto failed;
}
+ /* Create mask offset point */
+ MaskPoint.x = XOriginMask;
+ MaskPoint.y = YOriginMask;
+ IntLPtoDP(DCMask, &MaskPoint, 1);
+ MaskPoint.x += DCMask->ptlDCOrig.x;
+ MaskPoint.y += DCMask->ptlDCOrig.x;
}
/* Perform the bitblt operation */
@@ -823,13 +804,14 @@ GreStretchBltMask(
&DCDest->eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(ROP));
-
-failed:
if (UsesSource)
{
EXLATEOBJ_vCleanup(&exlo);
}
- if (UsesSource && hDCSrc != hDCDest)
+
+failed:
+ DC_vFinishBlit(DCDest, DCSrc);
+ if (UsesSource)
{
DC_UnlockDc(DCSrc);
}
@@ -889,19 +871,12 @@ IntPatBlt(
{
RECTL DestRect;
SURFACE *psurf;
- EBRUSHOBJ eboFill;
+ EBRUSHOBJ eboFill ;
POINTL BrushOrigin;
BOOL ret;
ASSERT(pbrush);
- psurf = pdc->dclevel.pSurface;
- if (psurf == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
{
return TRUE;
@@ -939,6 +914,13 @@ IntPatBlt(
BrushOrigin.x = pbrush->ptOrigin.x + pdc->ptlDCOrig.x;
BrushOrigin.y = pbrush->ptOrigin.y + pdc->ptlDCOrig.y;
+ DC_vPrepareDCsForBlit(pdc, DestRect, NULL, DestRect);
+
+ psurf = pdc->dclevel.pSurface;
+
+ if (pdc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(pdc);
+
EBRUSHOBJ_vInit(&eboFill, pbrush, pdc);
ret = IntEngBitBlt(
@@ -950,10 +932,12 @@ IntPatBlt(
&DestRect,
NULL,
NULL,
- &eboFill.BrushObject, // use pDC->eboFill
+ &eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(dwRop));
+ DC_vFinishBlit(pdc, NULL);
+
EBRUSHOBJ_vCleanup(&eboFill);
return ret;
diff --git a/subsystems/win32/win32k/objects/bitmaps.c b/subsystems/win32/win32k/objects/bitmaps.c
index f471a67e502..c3b7e8f148b 100644
--- a/subsystems/win32/win32k/objects/bitmaps.c
+++ b/subsystems/win32/win32k/objects/bitmaps.c
@@ -22,110 +22,198 @@
#define NDEBUG
#include
-HBITMAP APIENTRY
-IntGdiCreateBitmap(
- INT Width,
- INT Height,
- UINT Planes,
- UINT BitsPixel,
- IN OPTIONAL LPBYTE pBits)
+LONG APIENTRY
+IntSetBitmapBits(
+ PSURFACE psurf,
+ DWORD Bytes,
+ IN PBYTE Bits)
{
- HBITMAP hBitmap;
- SIZEL Size;
- LONG WidthBytes;
- PSURFACE psurfBmp;
+ /* Don't copy more bytes than the buffer has */
+ Bytes = min(Bytes, psurf->SurfObj.cjBits);
- /* NOTE: Windows also doesn't store nr. of planes separately! */
- BitsPixel = BITMAP_GetRealBitsPixel(BitsPixel * Planes);
+ RtlCopyMemory(psurf->SurfObj.pvBits, Bits, Bytes);
- /* Check parameters */
- if (BitsPixel == 0 || Width <= 0 || Width >= 0x8000000 || Height == 0)
+ return Bytes;
+}
+
+void
+NTAPI
+UnsafeSetBitmapBits(
+ PSURFACE psurf,
+ IN ULONG cjBits,
+ IN PVOID pvBits)
+{
+ PUCHAR pjDst, pjSrc;
+ LONG lDeltaDst, lDeltaSrc;
+ ULONG nWidth, nHeight, cBitsPixel;
+
+ nWidth = psurf->SurfObj.sizlBitmap.cx;
+ nHeight = psurf->SurfObj.sizlBitmap.cy;
+ cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+
+ /* Get pointers */
+ pjDst = psurf->SurfObj.pvScan0;
+ pjSrc = pvBits;
+ lDeltaDst = psurf->SurfObj.lDelta;
+ lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
+
+ while (nHeight--)
{
- DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
- Width, Height, BitsPixel);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
+ /* Copy one line */
+ memcpy(pjDst, pjSrc, lDeltaSrc);
+ pjSrc += lDeltaSrc;
+ pjDst += lDeltaDst;
}
- WidthBytes = BITMAP_GetWidthBytes(Width, BitsPixel);
+}
- Size.cx = Width;
- Size.cy = abs(Height);
+HBITMAP
+APIENTRY
+GreCreateBitmapEx(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN ULONG cjWidthBytes,
+ IN ULONG iFormat,
+ IN USHORT fjBitmap,
+ IN ULONG cjSizeImage,
+ IN OPTIONAL PVOID pvBits,
+ IN FLONG flags)
+{
+ PSURFACE psurf;
+ SURFOBJ *pso;
+ HBITMAP hbmp;
+ PVOID pvCompressedBits;
+ SIZEL sizl;
- /* Make sure that cjBits will not overflow */
- if ((ULONGLONG)WidthBytes * Size.cy >= 0x100000000ULL)
+ /* Verify format */
+ if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
+
+ /* Allocate a surface */
+ psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat);
+ if (!psurf)
{
- DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
- Width, Height, BitsPixel);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- /* Create the bitmap object. */
- hBitmap = IntCreateBitmap(Size, WidthBytes,
- BitmapFormat(BitsPixel, BI_RGB),
- (Height < 0 ? BMF_TOPDOWN : 0) |
- (NULL == pBits ? 0 : BMF_NOZEROINIT), NULL);
- if (!hBitmap)
- {
- DPRINT("IntGdiCreateBitmap: returned 0\n");
- return 0;
- }
-
- psurfBmp = SURFACE_LockSurface(hBitmap);
- if (psurfBmp == NULL)
- {
- GreDeleteObject(hBitmap);
+ DPRINT1("SURFACE_AllocSurface failed.\n");
return NULL;
}
- psurfBmp->flFlags = BITMAPOBJ_IS_APIBITMAP;
- psurfBmp->hDC = NULL; // Fixme
+ /* Get the handle for the bitmap and the surfobj */
+ hbmp = (HBITMAP)psurf->SurfObj.hsurf;
+ pso = &psurf->SurfObj;
- if (NULL != pBits)
+ /* The infamous RLE hack */
+ if (iFormat == BMF_4RLE || iFormat == BMF_8RLE)
{
- IntSetBitmapBits(psurfBmp, psurfBmp->SurfObj.cjBits, pBits);
+ sizl.cx = nWidth;
+ sizl.cy = nHeight;
+ pvCompressedBits = pvBits;
+ pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
+ DecompressBitmap(sizl, pvCompressedBits, pvBits, pso->lDelta, iFormat);
+ fjBitmap |= BMF_RLE_HACK;
}
- SURFACE_UnlockSurface(psurfBmp);
+ /* Mark as API bitmap */
+ psurf->flags |= (flags | API_BITMAP);
- DPRINT("IntGdiCreateBitmap : %dx%d, %d BPP colors, topdown %d, returning %08x\n",
- Size.cx, Size.cy, BitsPixel, (Height < 0 ? 1 : 0), hBitmap);
+ /* Set the bitmap bits */
+ if (!SURFACE_bSetBitmapBits(psurf, fjBitmap, cjWidthBytes, pvBits))
+ {
+ /* Bail out if that failed */
+ DPRINT1("SURFACE_bSetBitmapBits failed.\n");
+ SURFACE_FreeSurfaceByHandle(hbmp);
+ return NULL;
+ }
- return hBitmap;
+ /* Unlock the surface and return */
+ SURFACE_UnlockSurface(psurf);
+ return hbmp;
}
+/* Creates a DDB surface,
+ * as in CreateCompatibleBitmap or CreateBitmap.
+ */
+HBITMAP
+APIENTRY
+GreCreateBitmap(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN UINT cPlanes,
+ IN UINT cBitsPixel,
+ IN OPTIONAL PVOID pvBits)
+{
+ /* Call the extended function */
+ return GreCreateBitmapEx(nWidth,
+ nHeight,
+ 0, /* auto width */
+ BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
+ 0, /* no bitmap flags */
+ 0, /* auto size */
+ pvBits,
+ DDB_SURFACE /* DDB */);
+}
-HBITMAP APIENTRY
+HBITMAP
+APIENTRY
NtGdiCreateBitmap(
- INT Width,
- INT Height,
- UINT Planes,
- UINT BitsPixel,
+ IN INT nWidth,
+ IN INT nHeight,
+ IN UINT cPlanes,
+ IN UINT cBitsPixel,
IN OPTIONAL LPBYTE pUnsafeBits)
{
+ HBITMAP hbmp;
+ ULONG cjWidthBytes, iFormat;
+
+ /* NOTE: Windows also doesn't store nr. of planes separately! */
+ cBitsPixel = BITMAP_GetRealBitsPixel(cBitsPixel * cPlanes);
+
+ /* Calculate bitmap format */
+ iFormat = BitmapFormat(cBitsPixel, BI_RGB);
+
+ /* Check parameters */
+ if (iFormat == 0 || nWidth <= 0 || nWidth >= 0x8000000 || nHeight <= 0)
+ {
+ DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
+ nWidth, nHeight, cBitsPixel);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ /* Make sure that cjBits will not overflow */
+ cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
+ if ((ULONGLONG)cjWidthBytes * nHeight >= 0x100000000ULL)
+ {
+ DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
+ nWidth, nHeight, cBitsPixel);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ /* cBitsPixel = cBitsPixel * cPlanes now! */
+ hbmp = GreCreateBitmap(nWidth, nHeight, 1, cBitsPixel, NULL);
+
if (pUnsafeBits)
{
- BOOL Hit = FALSE;
- UINT cjBits = BITMAP_GetWidthBytes(Width, BitsPixel) * abs(Height);
-
- // FIXME: Use MmSecureVirtualMemory
+ PSURFACE psurf = SURFACE_LockSurface(hbmp);
_SEH2_TRY
{
- ProbeForRead(pUnsafeBits, cjBits, 1);
+ ProbeForRead(pUnsafeBits, cjWidthBytes * nHeight, 1);
+ UnsafeSetBitmapBits(psurf, 0, pUnsafeBits);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Hit = TRUE;
+ SURFACE_UnlockSurface(psurf);
+ SURFACE_FreeSurfaceByHandle(hbmp);
+ _SEH2_YIELD(return NULL;)
}
_SEH2_END
- if (Hit) return 0;
+ SURFACE_UnlockSurface(psurf);
}
- return IntGdiCreateBitmap(Width, Height, Planes, BitsPixel, pUnsafeBits);
+ return hbmp;
}
+
HBITMAP FASTCALL
IntCreateCompatibleBitmap(
PDC Dc,
@@ -143,11 +231,21 @@ IntCreateCompatibleBitmap(
{
if (Dc->dctype != DC_TYPE_MEMORY)
{
- Bmp = IntGdiCreateBitmap(abs(Width),
- abs(Height),
- IntGdiGetDeviceCaps(Dc,PLANES),
- IntGdiGetDeviceCaps(Dc,BITSPIXEL),
- NULL);
+ PSURFACE psurf;
+
+ Bmp = GreCreateBitmap(abs(Width),
+ abs(Height),
+ 1,
+ Dc->ppdev->gdiinfo.cBitsPixel,
+ NULL);
+ psurf = SURFACE_LockSurface(Bmp);
+ ASSERT(psurf);
+ /* Set palette */
+ psurf->ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
+ /* Set flags */
+ psurf->flags = API_BITMAP;
+ psurf->hdc = NULL; // Fixme
+ SURFACE_UnlockSurface(psurf);
}
else
{
@@ -160,83 +258,71 @@ IntCreateCompatibleBitmap(
{
if (Count == sizeof(BITMAP))
{
- /* We have a bitmap bug!!! W/O the HACK, we have white icons.
+ PSURFACE psurfBmp;
- MSDN Note: When a memory device context is created, it initially
- has a 1-by-1 monochrome bitmap selected into it. If this memory
- device context is used in CreateCompatibleBitmap, the bitmap that
- is created is a monochrome bitmap. To create a color bitmap, use
- the hDC that was used to create the memory device context, as
- shown in the following code:
-
- HDC memDC = CreateCompatibleDC(hDC);
- HBITMAP memBM = CreateCompatibleBitmap(hDC, nWidth, nHeight);
- SelectObject(memDC, memBM);
- */
- Bmp = IntGdiCreateBitmap(abs(Width),
- abs(Height),
- dibs.dsBm.bmPlanes,
- IntGdiGetDeviceCaps(Dc,BITSPIXEL),//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct!
- NULL);
+ Bmp = GreCreateBitmap(abs(Width),
+ abs(Height),
+ 1,
+ dibs.dsBm.bmBitsPixel,
+ NULL);
+ psurfBmp = SURFACE_LockSurface(Bmp);
+ ASSERT(psurfBmp);
+ /* Assign palette */
+ psurfBmp->ppal = psurf->ppal;
+ GDIOBJ_IncrementShareCount((POBJ)psurf->ppal);
+ /* Set flags */
+ psurfBmp->flags = API_BITMAP;
+ psurfBmp->hdc = NULL; // Fixme
+ SURFACE_UnlockSurface(psurfBmp);
}
else
{
/* A DIB section is selected in the DC */
- BITMAPINFO *bi;
+ BYTE buf[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)] = {0};
PVOID Bits;
+ BITMAPINFO* bi = (BITMAPINFO*)buf;
- /* Allocate memory for a BITMAPINFOHEADER structure and a
- color table. The maximum number of colors in a color table
- is 256 which corresponds to a bitmap with depth 8.
- Bitmaps with higher depths don't have color tables. */
- bi = ExAllocatePoolWithTag(PagedPool,
- sizeof(BITMAPINFOHEADER) +
- 256 * sizeof(RGBQUAD),
- TAG_TEMP);
+ bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
+ bi->bmiHeader.biWidth = Width;
+ bi->bmiHeader.biHeight = Height;
+ bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
+ bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
+ bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
+ bi->bmiHeader.biSizeImage = 0;
+ bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
+ bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
+ bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
+ bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
- if (bi)
+ if (bi->bmiHeader.biCompression == BI_BITFIELDS)
{
- bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
- bi->bmiHeader.biWidth = Width;
- bi->bmiHeader.biHeight = Height;
- bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
- bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
- bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
- bi->bmiHeader.biSizeImage = 0;
- bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
- bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
- bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
- bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
+ /* Copy the color masks */
+ RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD));
+ }
+ else if (bi->bmiHeader.biBitCount <= 8)
+ {
+ /* Copy the color table */
+ UINT Index;
+ PPALETTE PalGDI;
- if (bi->bmiHeader.biCompression == BI_BITFIELDS)
+ if (!psurf->ppal)
{
- /* Copy the color masks */
- RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3 * sizeof(DWORD));
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
}
- else if (bi->bmiHeader.biBitCount <= 8)
+
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
+ for (Index = 0;
+ Index < 256 && Index < PalGDI->NumColors;
+ Index++)
{
- /* Copy the color table */
- UINT Index;
- PPALETTE PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
-
- if (!PalGDI)
- {
- ExFreePoolWithTag(bi, TAG_TEMP);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- for (Index = 0;
- Index < 256 && Index < PalGDI->NumColors;
- Index++)
- {
- bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
- bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
- bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
- bi->bmiColors[Index].rgbReserved = 0;
- }
- PALETTE_UnlockPalette(PalGDI);
+ bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
+ bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
+ bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
+ bi->bmiColors[Index].rgbReserved = 0;
}
+ PALETTE_UnlockPalette(PalGDI);
Bmp = DIB_CreateDIBSection(Dc,
bi,
@@ -245,8 +331,6 @@ IntCreateCompatibleBitmap(
NULL,
0,
0);
-
- ExFreePoolWithTag(bi, TAG_TEMP);
return Bmp;
}
}
@@ -272,7 +356,7 @@ NtGdiCreateCompatibleBitmap(
}
if (!hDC)
- return IntGdiCreateBitmap(Width, Height, 1, 1, 0);
+ return GreCreateBitmap(Width, Height, 1, 1, 0);
Dc = DC_LockDc(hDC);
@@ -313,7 +397,7 @@ NtGdiGetBitmapDimension(
_SEH2_TRY
{
ProbeForWrite(Dimension, sizeof(SIZE), 1);
- *Dimension = psurfBmp->dimension;
+ *Dimension = psurfBmp->sizlDim;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -334,8 +418,6 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
BOOL bInRect = FALSE;
SURFACE *psurf;
SURFOBJ *pso;
- HPALETTE hpal = 0;
- PPALETTE ppal;
EXLATEOBJ exlo;
HBITMAP hBmpTmp;
@@ -361,21 +443,8 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
psurf = dc->dclevel.pSurface;
if (psurf)
{
- pso = &psurf->SurfObj;
- hpal = psurf->hDIBPalette;
- if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault;
- ppal = PALETTE_ShareLockPalette(hpal);
-
- if (psurf->SurfObj.iBitmapFormat == BMF_1BPP && !psurf->hSecure)
- {
- /* FIXME: palette should be gpalMono already ! */
- EXLATEOBJ_vInitialize(&exlo, &gpalMono, &gpalRGB, 0, 0xffffff, 0);
- }
- else
- {
- EXLATEOBJ_vInitialize(&exlo, ppal, &gpalRGB, 0, 0xffffff, 0);
- }
-
+ pso = &psurf->SurfObj;
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, &gpalRGB, 0, 0xffffff, 0);
// check if this DC has a DIB behind it...
if (pso->pvScan0) // STYPE_BITMAP == pso->iType
{
@@ -385,7 +454,6 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
}
EXLATEOBJ_vCleanup(&exlo);
- PALETTE_ShareUnlockPalette(ppal);
}
}
DC_UnlockDc(dc);
@@ -412,7 +480,7 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
0,
0);
- //HBITMAP hBmpTmp = IntGdiCreateBitmap(1, 1, 1, 32, NULL);
+ //HBITMAP hBmpTmp = GreCreateBitmap(1, 1, 1, 32, NULL);
if (hBmpTmp)
{
HBITMAP hBmpOld = (HBITMAP)NtGdiSelectBitmap(hDCTmp, hBmpTmp);
@@ -482,6 +550,36 @@ IntGetBitmapBits(
return ret;
}
+VOID
+FASTCALL
+UnsafeGetBitmapBits(
+ PSURFACE psurf,
+ DWORD Bytes,
+ OUT PBYTE pvBits)
+{
+ PUCHAR pjDst, pjSrc;
+ LONG lDeltaDst, lDeltaSrc;
+ ULONG nWidth, nHeight, cBitsPixel;
+
+ nWidth = psurf->SurfObj.sizlBitmap.cx;
+ nHeight = psurf->SurfObj.sizlBitmap.cy;
+ cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+
+ /* Get pointers */
+ pjSrc = psurf->SurfObj.pvScan0;
+ pjDst = pvBits;
+ lDeltaSrc = psurf->SurfObj.lDelta;
+ lDeltaDst = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
+
+ while (nHeight--)
+ {
+ /* Copy one line */
+ RtlCopyMemory(pjDst, pjSrc, lDeltaDst);
+ pjSrc += lDeltaSrc;
+ pjDst += lDeltaDst;
+ }
+}
+
LONG APIENTRY
NtGdiGetBitmapBits(
HBITMAP hBitmap,
@@ -503,7 +601,7 @@ NtGdiGetBitmapBits(
return 0;
}
- bmSize = BITMAP_GetWidthBytes(psurf->SurfObj.sizlBitmap.cx,
+ bmSize = WIDTH_BYTES_ALIGN16(psurf->SurfObj.sizlBitmap.cx,
BitsPerFormat(psurf->SurfObj.iBitmapFormat)) *
abs(psurf->SurfObj.sizlBitmap.cy);
@@ -521,7 +619,8 @@ NtGdiGetBitmapBits(
_SEH2_TRY
{
ProbeForWrite(pUnsafeBits, Bytes, 1);
- ret = IntGetBitmapBits(psurf, Bytes, pUnsafeBits);
+ UnsafeGetBitmapBits(psurf, Bytes, pUnsafeBits);
+ ret = Bytes;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -535,46 +634,6 @@ NtGdiGetBitmapBits(
}
-LONG APIENTRY
-IntSetBitmapBits(
- PSURFACE psurf,
- DWORD Bytes,
- IN PBYTE Bits)
-{
- LONG ret;
-
- /* Don't copy more bytes than the buffer has */
- Bytes = min(Bytes, psurf->SurfObj.cjBits);
-
-#if 0
- /* FIXME: call DDI specific function here if available */
- if (psurf->DDBitmap)
- {
- DPRINT("Calling device specific BitmapBits\n");
- if (psurf->DDBitmap->funcs->pBitmapBits)
- {
- ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap,
- (void *)Bits,
- Bytes,
- DDB_SET);
- }
- else
- {
- DPRINT("BitmapBits == NULL??\n");
- ret = 0;
- }
- }
- else
-#endif
- {
- RtlCopyMemory(psurf->SurfObj.pvBits, Bits, Bytes);
- ret = Bytes;
- }
-
- return ret;
-}
-
-
LONG APIENTRY
NtGdiSetBitmapBits(
HBITMAP hBitmap,
@@ -599,7 +658,8 @@ NtGdiSetBitmapBits(
_SEH2_TRY
{
ProbeForRead(pUnsafeBits, Bytes, 1);
- ret = IntSetBitmapBits(psurf, Bytes, pUnsafeBits);
+ UnsafeSetBitmapBits(psurf, Bytes, pUnsafeBits);
+ ret = 1;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -637,7 +697,7 @@ NtGdiSetBitmapDimension(
_SEH2_TRY
{
ProbeForWrite(Size, sizeof(SIZE), 1);
- *Size = psurf->dimension;
+ *Size = psurf->sizlDim;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -647,8 +707,8 @@ NtGdiSetBitmapDimension(
}
/* The dimension is changed even if writing the old value failed */
- psurf->dimension.cx = Width;
- psurf->dimension.cy = Height;
+ psurf->sizlDim.cx = Width;
+ psurf->sizlDim.cy = Height;
SURFACE_UnlockSurface(psurf);
@@ -665,7 +725,7 @@ VOID IntHandleSpecialColorType(HDC hDC, COLORREF* Color)
switch (*Color >> 24)
{
case 0x10: /* DIBINDEX */
- if (IntGetDIBColorTable(hDC, LOWORD(*Color), 1, &quad) == 1)
+ if (IntGetDIBColorTable(hDC, LOWORD(*Color), 1, &quad) == 1)
{
*Color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
}
@@ -707,7 +767,7 @@ VOID IntHandleSpecialColorType(HDC hDC, COLORREF* Color)
default:
DPRINT("Unsupported color type %d passed\n", *Color >> 24);
break;
- }
+ }
}
BOOL APIENTRY
@@ -786,40 +846,6 @@ BITMAP_GetRealBitsPixel(UINT nBitsPixel)
return 0;
}
-INT FASTCALL
-BITMAP_GetWidthBytes(INT bmWidth, INT bpp)
-{
-#if 0
- switch (bpp)
- {
- case 1:
- return 2 * ((bmWidth+15) >> 4);
-
- case 24:
- bmWidth *= 3; /* fall through */
- case 8:
- return bmWidth + (bmWidth & 1);
-
- case 32:
- return bmWidth * 4;
-
- case 16:
- case 15:
- return bmWidth * 2;
-
- case 4:
- return 2 * ((bmWidth+3) >> 2);
-
- default:
- DPRINT ("stub");
- }
-
- return -1;
-#endif
-
- return ((bmWidth * bpp + 15) & ~15) >> 3;
-}
-
HBITMAP FASTCALL
BITMAP_CopyBitmap(HBITMAP hBitmap)
{
@@ -833,7 +859,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
return 0;
}
- Bitmap = GDIOBJ_LockObj(hBitmap, GDI_OBJECT_TYPE_BITMAP);
+ Bitmap = SURFACE_LockSurface(hBitmap);
if (Bitmap == NULL)
{
return 0;
@@ -846,34 +872,23 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
Size.cx = abs(bm.bmWidth);
Size.cy = abs(bm.bmHeight);
- res = IntCreateBitmap(Size,
- bm.bmWidthBytes,
- BitmapFormat(bm.bmBitsPixel * bm.bmPlanes, BI_RGB),
- (bm.bmHeight < 0 ? BMF_TOPDOWN : 0) | BMF_NOZEROINIT,
- NULL);
+ res = GreCreateBitmapEx(Size.cx,
+ Size.cy,
+ bm.bmWidthBytes,
+ Bitmap->SurfObj.iBitmapFormat,
+ Bitmap->SurfObj.fjBitmap,
+ Bitmap->SurfObj.cjBits,
+ NULL,
+ Bitmap->flags);
+
if (res)
{
- PBYTE buf;
-
- resBitmap = GDIOBJ_LockObj(res, GDI_OBJECT_TYPE_BITMAP);
+ resBitmap = SURFACE_LockSurface(res);
if (resBitmap)
{
- buf = ExAllocatePoolWithTag(PagedPool,
- bm.bmWidthBytes * abs(bm.bmHeight),
- TAG_BITMAP);
- if (buf == NULL)
- {
- GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
- GreDeleteObject(res);
- return 0;
- }
- IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
- IntSetBitmapBits(resBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
- ExFreePoolWithTag(buf,TAG_BITMAP);
- resBitmap->flFlags = Bitmap->flFlags;
- GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
+ IntSetBitmapBits(resBitmap, Bitmap->SurfObj.cjBits, Bitmap->SurfObj.pvBits);
+ SURFACE_UnlockSurface(resBitmap);
}
else
{
@@ -882,7 +897,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
}
}
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
+ SURFACE_UnlockSurface(Bitmap);
return res;
}
@@ -900,15 +915,17 @@ BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
pBitmap->bmType = 0;
pBitmap->bmWidth = psurf->SurfObj.sizlBitmap.cx;
pBitmap->bmHeight = psurf->SurfObj.sizlBitmap.cy;
- pBitmap->bmWidthBytes = abs(psurf->SurfObj.lDelta);
pBitmap->bmPlanes = 1;
pBitmap->bmBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN16(pBitmap->bmWidth, pBitmap->bmBitsPixel);
/* Check for DIB section */
if (psurf->hSecure)
{
/* Set bmBits in this case */
pBitmap->bmBits = psurf->SurfObj.pvBits;
+ /* DIBs data are 32 bits aligned */
+ pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN32(pBitmap->bmWidth, pBitmap->bmBitsPixel);
if (Count >= sizeof(DIBSECTION))
{
@@ -920,38 +937,44 @@ BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
pds->dsBmih.biHeight = pds->dsBm.bmHeight;
pds->dsBmih.biPlanes = pds->dsBm.bmPlanes;
pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel;
- switch (psurf->SurfObj.iBitmapFormat)
- {
- /* FIXME: What about BI_BITFIELDS? */
- case BMF_1BPP:
- case BMF_4BPP:
- case BMF_8BPP:
- case BMF_16BPP:
- case BMF_24BPP:
- case BMF_32BPP:
- pds->dsBmih.biCompression = BI_RGB;
- break;
- case BMF_4RLE:
- pds->dsBmih.biCompression = BI_RLE4;
- break;
- case BMF_8RLE:
- pds->dsBmih.biCompression = BI_RLE8;
- break;
- case BMF_JPEG:
- pds->dsBmih.biCompression = BI_JPEG;
- break;
- case BMF_PNG:
- pds->dsBmih.biCompression = BI_PNG;
- break;
- }
+ if(psurf->ppal->flFlags & PAL_BITFIELDS)
+ {
+ pds->dsBmih.biCompression = BI_BITFIELDS;
+ }
+ else
+ {
+ switch (psurf->SurfObj.iBitmapFormat)
+ {
+ case BMF_1BPP:
+ case BMF_4BPP:
+ case BMF_8BPP:
+ case BMF_16BPP:
+ case BMF_24BPP:
+ case BMF_32BPP:
+ pds->dsBmih.biCompression = BI_RGB;
+ break;
+ case BMF_4RLE:
+ pds->dsBmih.biCompression = BI_RLE4;
+ break;
+ case BMF_8RLE:
+ pds->dsBmih.biCompression = BI_RLE8;
+ break;
+ case BMF_JPEG:
+ pds->dsBmih.biCompression = BI_JPEG;
+ break;
+ case BMF_PNG:
+ pds->dsBmih.biCompression = BI_PNG;
+ break;
+ }
+ }
pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits;
pds->dsBmih.biXPelsPerMeter = 0;
pds->dsBmih.biYPelsPerMeter = 0;
- pds->dsBmih.biClrUsed = psurf->biClrUsed;
+ pds->dsBmih.biClrUsed = psurf->ppal->NumColors;
pds->dsBmih.biClrImportant = psurf->biClrImportant;
- pds->dsBitfields[0] = psurf->dsBitfields[0];
- pds->dsBitfields[1] = psurf->dsBitfields[1];
- pds->dsBitfields[2] = psurf->dsBitfields[2];
+ pds->dsBitfields[0] = psurf->ppal->RedMask;
+ pds->dsBitfields[1] = psurf->ppal->GreenMask;
+ pds->dsBitfields[2] = psurf->ppal->BlueMask;
pds->dshSection = psurf->hDIBSection;
pds->dsOffset = psurf->dwOffset;
@@ -975,14 +998,15 @@ APIENTRY
NtGdiGetDCforBitmap(
IN HBITMAP hsurf)
{
- HDC hDC = NULL;
+ HDC hdc = NULL;
PSURFACE psurf = SURFACE_LockSurface(hsurf);
if (psurf)
{
- hDC = psurf->hDC;
+ hdc = psurf->hdc;
SURFACE_UnlockSurface(psurf);
}
- return hDC;
+ return hdc;
}
+
/* EOF */
diff --git a/subsystems/win32/win32k/objects/brush.c b/subsystems/win32/win32k/objects/brush.c
index c8682f6a849..d1f8175d62a 100644
--- a/subsystems/win32/win32k/objects/brush.c
+++ b/subsystems/win32/win32k/objects/brush.c
@@ -1,9 +1,9 @@
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS win32 subsystem
* PURPOSE: Functions for brushes
* FILE: subsystem/win32/win32k/objects/brush.c
- * PROGRAMER:
+ * PROGRAMER:
*/
#include
@@ -19,13 +19,13 @@ typedef struct _GDI_OBJ_ATTR_FREELIST
DWORD nEntries;
PVOID AttrList[GDIOBJATTRFREE];
} GDI_OBJ_ATTR_FREELIST, *PGDI_OBJ_ATTR_FREELIST;
-
+
typedef struct _GDI_OBJ_ATTR_ENTRY
{
RGN_ATTR Attr[GDIOBJATTRFREE];
} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY;
-static const USHORT HatchBrushes[NB_HATCH_STYLES][8] =
+static const ULONG HatchBrushes[NB_HATCH_STYLES][8] =
{
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
{0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
@@ -46,7 +46,7 @@ AllocateObjectAttr(VOID)
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
PGDI_OBJ_ATTR_ENTRY pGdiObjAttrEntry;
int i;
-
+
pti = PsGetCurrentThreadWin32Thread();
if (pti->pgdiBrushAttr)
{
@@ -127,9 +127,9 @@ FreeObjectAttr(PVOID pAttr)
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
pti = PsGetCurrentThreadWin32Thread();
-
+
if (!pti) return;
-
+
if (!pti->pgdiBrushAttr)
{ // If it is null, just cache it for the next time.
pti->pgdiBrushAttr = pAttr;
@@ -244,129 +244,6 @@ BRUSH_GetObject(PBRUSH pbrush, INT Count, LPLOGBRUSH Buffer)
return sizeof(LOGBRUSH);
}
-/**
- * @name CalculateColorTableSize
- *
- * Internal routine to calculate the number of color table entries.
- *
- * @param BitmapInfoHeader
- * Input bitmap information header, can be any version of
- * BITMAPINFOHEADER or BITMAPCOREHEADER.
- *
- * @param ColorSpec
- * Pointer to variable which specifiing the color mode (DIB_RGB_COLORS
- * or DIB_RGB_COLORS). On successful return this value is normalized
- * according to the bitmap info.
- *
- * @param ColorTableSize
- * On successful return this variable is filled with number of
- * entries in color table for the image with specified parameters.
- *
- * @return
- * TRUE if the input values together form a valid image, FALSE otherwise.
- */
-BOOL
-APIENTRY
-CalculateColorTableSize(
- CONST BITMAPINFOHEADER *BitmapInfoHeader,
- UINT *ColorSpec,
- UINT *ColorTableSize)
-{
- WORD BitCount;
- DWORD ClrUsed;
- DWORD Compression;
-
- /*
- * At first get some basic parameters from the passed BitmapInfoHeader
- * structure. It can have one of the following formats:
- * - BITMAPCOREHEADER (the oldest one with totally different layout
- * from the others)
- * - BITMAPINFOHEADER (the standard and most common header)
- * - BITMAPV4HEADER (extension of BITMAPINFOHEADER)
- * - BITMAPV5HEADER (extension of BITMAPV4HEADER)
- */
- if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
- {
- BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount;
- ClrUsed = 0;
- Compression = BI_RGB;
- }
- else
- {
- BitCount = BitmapInfoHeader->biBitCount;
- ClrUsed = BitmapInfoHeader->biClrUsed;
- Compression = BitmapInfoHeader->biCompression;
- }
-
- switch (Compression)
- {
- case BI_BITFIELDS:
- if (*ColorSpec == DIB_PAL_COLORS)
- *ColorSpec = DIB_RGB_COLORS;
-
- if (BitCount != 16 && BitCount != 32)
- return FALSE;
-
- /* For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in
- * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask).
- * For BITMAPINFOHEADER the color masks are stored in the palette. */
- if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER))
- *ColorTableSize = 0;
- else
- *ColorTableSize = 3;
-
- return TRUE;
-
- case BI_RGB:
- switch (BitCount)
- {
- case 1:
- *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2;
- return TRUE;
-
- case 4:
- *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
- return TRUE;
-
- case 8:
- *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
- return TRUE;
-
- default:
- if (*ColorSpec == DIB_PAL_COLORS)
- *ColorSpec = DIB_RGB_COLORS;
- if (BitCount != 16 && BitCount != 24 && BitCount != 32)
- return FALSE;
- *ColorTableSize = ClrUsed;
- return TRUE;
- }
-
- case BI_RLE4:
- if (BitCount == 4)
- {
- *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
- return TRUE;
- }
- return FALSE;
-
- case BI_RLE8:
- if (BitCount == 8)
- {
- *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
- return TRUE;
- }
- return FALSE;
-
- case BI_JPEG:
- case BI_PNG:
- *ColorTableSize = ClrUsed;
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
HBRUSH
APIENTRY
IntGdiCreateDIBBrush(
@@ -379,9 +256,7 @@ IntGdiCreateDIBBrush(
PBRUSH pbrush;
HBITMAP hPattern;
ULONG_PTR DataPtr;
- UINT PaletteEntryCount;
- PSURFACE psurfPattern;
- INT PaletteType;
+ PVOID pvDIBits;
if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
{
@@ -389,36 +264,19 @@ IntGdiCreateDIBBrush(
return NULL;
}
- if (!CalculateColorTableSize(&BitmapInfo->bmiHeader,
- &ColorSpec,
- &PaletteEntryCount))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return NULL;
- }
+ DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
- // FIXME: What about BI_BITFIELDS
- DataPtr = (ULONG_PTR)BitmapInfo + BitmapInfo->bmiHeader.biSize;
- if (ColorSpec == DIB_RGB_COLORS)
- DataPtr += PaletteEntryCount * sizeof(RGBQUAD);
- else
- DataPtr += PaletteEntryCount * sizeof(USHORT);
-
- hPattern = IntGdiCreateBitmap(BitmapInfo->bmiHeader.biWidth,
- BitmapInfo->bmiHeader.biHeight,
- BitmapInfo->bmiHeader.biPlanes,
- BitmapInfo->bmiHeader.biBitCount,
- (PVOID)DataPtr);
+ hPattern = DIB_CreateDIBSection(NULL, BitmapInfo, ColorSpec, &pvDIBits, NULL, 0, 0);
if (hPattern == NULL)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
-
- psurfPattern = SURFACE_LockSurface(hPattern);
- ASSERT(psurfPattern != NULL);
- psurfPattern->hDIBPalette = BuildDIBPalette(BitmapInfo, &PaletteType);
- SURFACE_UnlockSurface(psurfPattern);
+ RtlCopyMemory(pvDIBits,
+ (PVOID)DataPtr,
+ DIB_GetDIBImageBytes(BitmapInfo->bmiHeader.biWidth,
+ BitmapInfo->bmiHeader.biHeight,
+ BitmapInfo->bmiHeader.biBitCount * BitmapInfo->bmiHeader.biPlanes));
pbrush = BRUSH_AllocBrushWithHandle();
if (pbrush == NULL)
@@ -455,7 +313,7 @@ IntGdiCreateHatchBrush(
return 0;
}
- hPattern = IntGdiCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
+ hPattern = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
if (hPattern == NULL)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
diff --git a/subsystems/win32/win32k/objects/cliprgn.c b/subsystems/win32/win32k/objects/cliprgn.c
index 63b629add84..8698bb3ee98 100644
--- a/subsystems/win32/win32k/objects/cliprgn.c
+++ b/subsystems/win32/win32k/objects/cliprgn.c
@@ -28,27 +28,16 @@ CLIPPING_UpdateGCRegion(DC* Dc)
PROSRGNDATA CombinedRegion;
HRGN hRgnVis = Dc->prgnVis->BaseObject.hHmgr;
- /* Experiment with API region based on wine.. */
- if (Dc->rosdc.hClipRgn && Dc->dclevel.prgnMeta)
+ // would prefer this, but the rest of the code sucks
+// ASSERT(Dc->rosdc.hGCClipRgn);
+// ASSERT(Dc->rosdc.hClipRgn);
+ if (!Dc->prgnVis)
{
- PROSRGNDATA pClipRgn;
-
- if ((pClipRgn = RGNOBJAPI_Lock(Dc->rosdc.hClipRgn, NULL)))
- {
- if (!Dc->prgnAPI) Dc->prgnAPI = IntSysCreateRectpRgn( 0, 0, 0, 0 );
-
- IntGdiCombineRgn( Dc->prgnAPI,
- pClipRgn,
- Dc->dclevel.prgnMeta,
- RGN_AND );
- RGNOBJAPI_Unlock(pClipRgn);
- }
+ DPRINT1("Warning, prgnVis is NULL!\n");
}
else
{
- if (Dc->prgnAPI)
- GreDeleteObject(((PROSRGNDATA)Dc->prgnAPI)->BaseObject.hHmgr);
- Dc->prgnAPI = NULL;
+ hRgnVis = Dc->prgnVis->BaseObject.hHmgr ;
}
@@ -62,28 +51,27 @@ CLIPPING_UpdateGCRegion(DC* Dc)
NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y);
- if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL)))
- {
- CLIPOBJ *CombinedClip;
-
- CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount,
- CombinedRegion->Buffer,
- &CombinedRegion->rdh.rcBound);
+ if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL)))
+ {
+ CLIPOBJ *CombinedClip;
- RGNOBJAPI_Unlock(CombinedRegion);
+ CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount,
+ CombinedRegion->Buffer,
+ &CombinedRegion->rdh.rcBound);
- if (!CombinedClip)
- {
- DPRINT1("IntEngCreateClipRegion() failed\n");
- return ERROR;
- }
+ RGNOBJAPI_Unlock(CombinedRegion);
- if (Dc->rosdc.CombinedClip != NULL)
- IntEngDeleteClipRegion(Dc->rosdc.CombinedClip);
+ if ( !CombinedClip )
+ {
+ DPRINT1("IntEngCreateClipRegion() failed\n");
+ return ERROR;
+ }
- Dc->rosdc.CombinedClip = CombinedClip;
- }
+ if(Dc->rosdc.CombinedClip != NULL)
+ IntEngDeleteClipRegion(Dc->rosdc.CombinedClip);
+ Dc->rosdc.CombinedClip = CombinedClip ;
+ }
return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y);
}
@@ -115,7 +103,6 @@ GdiSelectVisRgn(HDC hdc, HRGN hrgn)
NtGdiOffsetRgn(dc->prgnVis->BaseObject.hHmgr, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
CLIPPING_UpdateGCRegion(dc);
}
-
DC_UnlockDc(dc);
return retval;
@@ -166,6 +153,7 @@ int FASTCALL GdiExtSelectClipRgn(PDC dc,
else
NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode);
}
+
return CLIPPING_UpdateGCRegion(dc);
}
@@ -233,6 +221,7 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
retval = REGION_GetRgnBox(pRgnNew, rc);
REGION_FreeRgnByHandle(pRgnNew->BaseObject.hHmgr);
+
DC_UnlockDc(dc);
if(Unlock) REGION_UnlockRgn(pRgn);
return retval;
@@ -529,6 +518,7 @@ IntGdiSetMetaRgn(PDC pDC)
return Ret;
}
+
int APIENTRY NtGdiSetMetaRgn(HDC hDC)
{
INT Ret;
@@ -570,7 +560,7 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC)
IntGdiCombineRgn( pDC->prgnAPI,
pDC->dclevel.prgnClip,
pDC->dclevel.prgnMeta,
- RGN_AND );
+ RGN_AND);
}
else
{
@@ -579,43 +569,42 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC)
IntGdiCombineRgn( pDC->prgnAPI,
pDC->dclevel.prgnClip,
NULL,
- RGN_COPY );
+ RGN_COPY);
}
else if (pDC->dclevel.prgnMeta)
{
IntGdiCombineRgn( pDC->prgnAPI,
pDC->dclevel.prgnMeta,
NULL,
- RGN_COPY );
+ RGN_COPY);
}
}
IntGdiCombineRgn( pDC->prgnRao,
pDC->prgnVis,
pDC->prgnAPI,
- RGN_AND );
+ RGN_AND);
- RtlCopyMemory( &pDC->erclClip,
- &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound,
- sizeof(RECTL));
+ RtlCopyMemory(&pDC->erclClip,
+ &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound,
+ sizeof(RECTL));
pDC->fs &= ~DC_FLAG_DIRTY_RAO;
IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
// pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
- // the rects from region objects rects in pClipRgn->Buffer.
+ // the rects from region objects rects in pClipRgn->Buffer.
// With pDC->co.pClipRgn->Buffer,
// pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount,
((PROSRGNDATA)pDC->prgnRao)->Buffer,
- &pDC->erclClip);
-
+ &pDC->erclClip);
if (co)
{
if (pDC->rosdc.CombinedClip != NULL)
- IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
+ IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
pDC->rosdc.CombinedClip = co;
}
diff --git a/subsystems/win32/win32k/objects/dcattr.c b/subsystems/win32/win32k/objects/dcattr.c
index 1fa8535d9cc..93673c77717 100644
--- a/subsystems/win32/win32k/objects/dcattr.c
+++ b/subsystems/win32/win32k/objects/dcattr.c
@@ -152,35 +152,49 @@ FreeDcAttr(PDC_ATTR pDc_Attr)
return;
}
+BOOL
+FASTCALL
+DC_AllocDcAttr(PDC pdc)
+{
+ DC_AllocateDcAttr(pdc->BaseObject.hHmgr);
+ *pdc->pdcattr = pdc->dcattr;
+ return TRUE;
+}
+
+// CHECK against current head
VOID
FASTCALL
DC_AllocateDcAttr(HDC hDC)
{
PVOID NewMem = NULL;
PDC pDC;
+ HANDLE Pid = NtCurrentProcess();
+ ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size
+ NTSTATUS Status = ZwAllocateVirtualMemory(Pid,
+ &NewMem,
+ 0,
+ &MemSize,
+ MEM_COMMIT|MEM_RESERVE,
+ PAGE_READWRITE);
{
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
-
- NewMem = AllocateDcAttr();
-
// FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
-
- if (NewMem)
+ if (NT_SUCCESS(Status))
{
- RtlZeroMemory(NewMem, sizeof(DC_ATTR));
- Entry->UserData = NewMem;
- DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
+ RtlZeroMemory(NewMem, MemSize);
+ Entry->UserData = NewMem;
+ DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
}
else
{
- DPRINT1("DC_ATTR not allocated!\n");
+ DPRINT("DC_ATTR not allocated!\n");
}
}
pDC = DC_LockDc(hDC);
ASSERT(pDC->pdcattr == &pDC->dcattr);
- if (NewMem)
+ if(NewMem)
{
pDC->pdcattr = NewMem; // Store pointer
}
@@ -188,23 +202,37 @@ DC_AllocateDcAttr(HDC hDC)
}
VOID
-FASTCALL
-DC_FreeDcAttr(HDC DCToFree )
+NTAPI
+DC_vFreeDcAttr(PDC pdc)
{
- PDC pDC = DC_LockDc(DCToFree);
- if (pDC->pdcattr == &pDC->dcattr) return; // Internal DC object!
- pDC->pdcattr = &pDC->dcattr;
- DC_UnlockDc(pDC);
+ HANDLE Pid = NtCurrentProcess();
+ INT Index;
+ PGDI_TABLE_ENTRY pent;
- {
- INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree);
- PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData)
+ if (pdc->pdcattr == &pdc->dcattr)
{
- FreeDcAttr(Entry->UserData);
- Entry->UserData = NULL;
+ // Internal DC object!
+ return;
+ }
+
+ pdc->pdcattr = &pdc->dcattr;
+
+ Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr);
+ pent = &GdiHandleTable->Entries[Index];
+ if(pent->UserData)
+ {
+ ULONG MemSize = sizeof(DC_ATTR);
+ NTSTATUS Status = ZwFreeVirtualMemory(Pid,
+ &pent->UserData,
+ &MemSize,
+ MEM_RELEASE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("DC_FreeDC failed to free DC_ATTR 0x%p\n", pent->UserData);
+ ASSERT(FALSE);
+ }
+ pent->UserData = NULL;
}
- }
}
@@ -218,12 +246,8 @@ CopytoUserDcAttr(PDC dc, PDC_ATTR pdcattr)
_SEH2_TRY
{
- ProbeForWrite( pdcattr,
- sizeof(DC_ATTR),
- 1);
- RtlCopyMemory( pdcattr,
- &dc->dcattr,
- sizeof(DC_ATTR));
+ ProbeForWrite(pdcattr, sizeof(DC_ATTR), 1);
+ RtlCopyMemory(pdcattr, &dc->dcattr, sizeof(DC_ATTR));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
diff --git a/subsystems/win32/win32k/objects/dclife.c b/subsystems/win32/win32k/objects/dclife.c
index 0dffdd41193..589e92c594f 100644
--- a/subsystems/win32/win32k/objects/dclife.c
+++ b/subsystems/win32/win32k/objects/dclife.c
@@ -12,169 +12,363 @@
#define NDEBUG
#include
+//FIXME: windows uses 0x0012009f
+#define DIRTY_DEFAULT DIRTY_CHARSET|DIRTY_BACKGROUND|DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL
+
+PSURFACE psurfDefaultBitmap = NULL;
+PBRUSH pbrDefaultBrush = NULL;
+
+// FIXME: these should go to floatobj.h or something
+#define FLOATOBJ_0 {0x00000000, 0x00000000}
+#define FLOATOBJ_1 {0x40000000, 0x00000002}
+#define FLOATOBJ_16 {0x40000000, 0x00000006}
+#define FLOATOBJ_1_16 {0x40000000, 0xfffffffe}
+
+static const FLOATOBJ gef0 = FLOATOBJ_0;
+static const FLOATOBJ gef1 = FLOATOBJ_1;
+static const FLOATOBJ gef16 = FLOATOBJ_16;
+
+static const MATRIX gmxWorldToDeviceDefault =
+{
+ FLOATOBJ_16, FLOATOBJ_0,
+ FLOATOBJ_0, FLOATOBJ_16,
+ FLOATOBJ_0, FLOATOBJ_0,
+ 0, 0, 0x4b
+};
+
+static const MATRIX gmxDeviceToWorldDefault =
+{
+ FLOATOBJ_1_16, FLOATOBJ_0,
+ FLOATOBJ_0, FLOATOBJ_1_16,
+ FLOATOBJ_0, FLOATOBJ_0,
+ 0, 0, 0x53
+};
+
+static const MATRIX gmxWorldToPageDefault =
+{
+ FLOATOBJ_1, FLOATOBJ_0,
+ FLOATOBJ_0, FLOATOBJ_1,
+ FLOATOBJ_0, FLOATOBJ_0,
+ 0, 0, 0x63
+};
+
+// HACK!! Fix XFORMOBJ then use 1:16 / 16:1
+#define gmxWorldToDeviceDefault gmxWorldToPageDefault
+#define gmxDeviceToWorldDefault gmxWorldToPageDefault
+
/** Internal functions ********************************************************/
-HDC FASTCALL
-DC_AllocDC(PUNICODE_STRING Driver)
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitDcImpl()
{
- PDC NewDC;
- PDC_ATTR pdcattr;
- HDC hDC;
- PWSTR Buf = NULL;
- XFORM xformTemplate;
- PBRUSH pbrush;
- HSURF hsurf;
+ psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
+ if (!psurfDefaultBitmap)
+ return STATUS_UNSUCCESSFUL;
- if (Driver != NULL)
- {
- Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
- if (!Buf)
- {
- DPRINT1("ExAllocatePoolWithTag failed\n");
- return NULL;
- }
- RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength);
- }
+ pbrDefaultBrush = BRUSH_ShareLockBrush(StockObjects[BLACK_BRUSH]);
+ if (!pbrDefaultBrush)
+ return STATUS_UNSUCCESSFUL;
- NewDC = (PDC)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DC);
- if (!NewDC)
- {
- if (Buf)
- {
- ExFreePoolWithTag(Buf, TAG_DC);
- }
- DPRINT1("GDIOBJ_AllocObjWithHandle failed\n");
- return NULL;
- }
-
- hDC = NewDC->BaseObject.hHmgr;
-
- NewDC->pdcattr = &NewDC->dcattr;
- DC_AllocateDcAttr(hDC);
-
- if (Driver != NULL)
- {
- RtlCopyMemory(&NewDC->rosdc.DriverName, Driver, sizeof(UNICODE_STRING));
- NewDC->rosdc.DriverName.Buffer = Buf;
- }
- pdcattr = NewDC->pdcattr;
-
- // FIXME: no floating point in the kernel!
- xformTemplate.eM11 = 1.0f;
- xformTemplate.eM12 = 0.0f;
- xformTemplate.eM21 = 0.0f;
- xformTemplate.eM22 = 1.0f;
- xformTemplate.eDx = 0.0f;
- xformTemplate.eDy = 0.0f;
- XForm2MatrixS(&NewDC->dclevel.mxWorldToDevice, &xformTemplate);
- XForm2MatrixS(&NewDC->dclevel.mxDeviceToWorld, &xformTemplate);
- XForm2MatrixS(&NewDC->dclevel.mxWorldToPage, &xformTemplate);
-
- // Setup syncing bits for the dcattr data packets.
- pdcattr->flXform = DEVICE_TO_PAGE_INVALID;
-
- pdcattr->ulDirty_ = 0; // Server side
-
- pdcattr->iMapMode = MM_TEXT;
- pdcattr->iGraphicsMode = GM_COMPATIBLE;
- pdcattr->jFillMode = ALTERNATE;
-
- pdcattr->szlWindowExt.cx = 1; // Float to Int,,, WRONG!
- pdcattr->szlWindowExt.cy = 1;
- pdcattr->szlViewportExt.cx = 1;
- pdcattr->szlViewportExt.cy = 1;
-
- pdcattr->crForegroundClr = 0;
- pdcattr->ulForegroundClr = 0;
-
- pdcattr->ulBackgroundClr = 0xffffff;
- pdcattr->crBackgroundClr = 0xffffff;
-
- pdcattr->ulPenClr = RGB(0, 0, 0);
- pdcattr->crPenClr = RGB(0, 0, 0);
-
- pdcattr->ulBrushClr = RGB(255, 255, 255); // Do this way too.
- pdcattr->crBrushClr = RGB(255, 255, 255);
-
-//// This fixes the default brush and pen settings. See DC_InitDC.
-
- /* Create the default fill brush */
- pdcattr->hbrush = NtGdiGetStockObject(WHITE_BRUSH);
- NewDC->dclevel.pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
- EBRUSHOBJ_vInit(&NewDC->eboFill, NewDC->dclevel.pbrFill, NewDC);
-
- /* Create the default pen / line brush */
- pdcattr->hpen = NtGdiGetStockObject(BLACK_PEN);
- NewDC->dclevel.pbrLine = PEN_ShareLockPen(pdcattr->hpen);
- EBRUSHOBJ_vInit(&NewDC->eboLine, NewDC->dclevel.pbrLine, NewDC);
-
- /* Create the default text brush */
- pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(BLACK_BRUSH));
- EBRUSHOBJ_vInit(&NewDC->eboText, pbrush, NewDC);
- pdcattr->ulDirty_ |= DIRTY_TEXT;
-
- /* Create the default background brush */
- pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(WHITE_BRUSH));
- EBRUSHOBJ_vInit(&NewDC->eboBackground, pbrush, NewDC);
-
- pdcattr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
- TextIntRealizeFont(pdcattr->hlfntNew,NULL);
- NewDC->hlfntCur = pdcattr->hlfntNew;
- NewDC->dclevel.plfnt = GDIOBJ_GetKernelObj(pdcattr->hlfntNew);
-
- NewDC->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
- NewDC->dclevel.ppal = PALETTE_ShareLockPalette(NewDC->dclevel.hpal);
- /* This should never fail */
- ASSERT(NewDC->dclevel.ppal);
-
- NewDC->dclevel.laPath.eMiterLimit = 10.0; // FIXME: use FLOATL or FLOATOBJ!
-
- NewDC->dclevel.lSaveDepth = 1;
-
- hsurf = (HBITMAP)PrimarySurface.pSurface; // <- what kind of haxx0ry is that?
- NewDC->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
-
- /* Allocate a Vis region */
- NewDC->prgnVis = IntSysCreateRectpRgn(0, 0, 1, 1);
- if (!NewDC->prgnVis)
- {
- DPRINT1("IntSysCreateRectpRgn failed\n");
- if (!GDIOBJ_FreeObjByHandle(hDC, GDI_OBJECT_TYPE_DC))
- {
- ASSERT(FALSE);
- }
- return NULL;
- }
-
- return NewDC;
+ return STATUS_SUCCESS;
}
-BOOL INTERNAL_CALL
+
+PDC
+NTAPI
+DC_AllocDcWithHandle()
+{
+ PDC pdc;
+ pdc = (PDC)GDIOBJ_AllocObjWithHandle(GDILoObjType_LO_DC_TYPE);
+
+ pdc->pdcattr = &pdc->dcattr;
+
+ return pdc;
+}
+
+
+void
+DC_InitHack(PDC pdc)
+{
+ TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
+ pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
+
+ /* This should never fail */
+ ASSERT(pdc->dclevel.ppal);
+
+ /* Select regions */
+ pdc->rosdc.hClipRgn = NULL;
+ pdc->rosdc.hGCClipRgn = NULL;
+}
+
+VOID
+NTAPI
+DC_vInitDc(
+ PDC pdc,
+ DCTYPE dctype,
+ PPDEVOBJ ppdev)
+{
+ /* Setup some basic fields */
+ pdc->dctype = dctype;
+ pdc->ppdev = ppdev;
+ pdc->dhpdev = ppdev->dhpdev;
+ pdc->hsem = ppdev->hsemDevLock;
+ pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
+ pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
+ pdc->fs = DC_DIRTY_RAO;
+
+ /* Setup dc attribute */
+ pdc->pdcattr = &pdc->dcattr;
+ pdc->dcattr.pvLDC = NULL;
+ pdc->dcattr.ulDirty_ = DIRTY_DEFAULT;
+ if (ppdev == gppdevPrimary)
+ pdc->dcattr.ulDirty_ |= DC_PRIMARY_DISPLAY;
+
+ /* Setup the DC size */
+ if (dctype == DCTYPE_MEMORY)
+ {
+ /* Memory DCs have a 1 x 1 bitmap by default */
+ pdc->dclevel.sizl.cx = 1;
+ pdc->dclevel.sizl.cy = 1;
+ }
+ else
+ {
+ /* Other DC's are as big as the related PDEV */
+ pdc->dclevel.sizl.cx = ppdev->gdiinfo.ulHorzRes;
+ pdc->dclevel.sizl.cy = ppdev->gdiinfo.ulVertRes;
+ }
+
+ /* Setup Window rect based on DC size */
+ pdc->erclWindow.left = 0;
+ pdc->erclWindow.top = 0;
+ pdc->erclWindow.right = pdc->dclevel.sizl.cx;
+ pdc->erclWindow.bottom = pdc->dclevel.sizl.cy;
+
+ if (dctype == DCTYPE_DIRECT)
+ {
+ /* Direct DCs get the surface from the PDEV */
+ pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
+
+ pdc->erclBounds.left = 0x7fffffff;
+ pdc->erclBounds.top = 0x7fffffff;
+ pdc->erclBounds.right = 0x80000000;
+ pdc->erclBounds.bottom = 0x80000000;
+ pdc->erclBoundsApp.left = 0xffffffff;
+ pdc->erclBoundsApp.top = 0xfffffffc;
+ pdc->erclBoundsApp.right = 0x00007ffc; // FIXME
+ pdc->erclBoundsApp.bottom = 0x00000333; // FIXME
+ pdc->erclClip = pdc->erclBounds;
+// pdc->co
+
+ pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY;
+ }
+ else
+ {
+ /* Non-direct DCs don't have a surface by default */
+ pdc->dclevel.pSurface = NULL;
+
+ // FIXME: HACK, because our code expects a surface
+ pdc->dclevel.pSurface = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
+
+ pdc->erclBounds.left = 0;
+ pdc->erclBounds.top = 0;
+ pdc->erclBounds.right = 0;
+ pdc->erclBounds.bottom = 0;
+ pdc->erclBoundsApp = pdc->erclBounds;
+ pdc->erclClip = pdc->erclWindow;
+// pdc->co = NULL
+ }
+
+// pdc->dcattr.VisRectRegion:
+
+ /* Setup coordinate transformation data */
+ pdc->dclevel.mxWorldToDevice = gmxWorldToDeviceDefault;
+ pdc->dclevel.mxDeviceToWorld = gmxDeviceToWorldDefault;
+ pdc->dclevel.mxWorldToPage = gmxWorldToPageDefault;
+ pdc->dclevel.efM11PtoD = gef16;
+ pdc->dclevel.efM22PtoD = gef16;
+ pdc->dclevel.efDxPtoD = gef0;
+ pdc->dclevel.efDyPtoD = gef0;
+ pdc->dclevel.efM11_TWIPS = gef0;
+ pdc->dclevel.efM22_TWIPS = gef0;
+ pdc->dclevel.efPr11 = gef0;
+ pdc->dclevel.efPr22 = gef0;
+ pdc->dcattr.mxWorldToDevice = pdc->dclevel.mxWorldToDevice;
+ pdc->dcattr.mxDeviceToWorld = pdc->dclevel.mxDeviceToWorld;
+ pdc->dcattr.mxWorldToPage = pdc->dclevel.mxWorldToPage;
+ pdc->dcattr.efM11PtoD = pdc->dclevel.efM11PtoD;
+ pdc->dcattr.efM22PtoD = pdc->dclevel.efM22PtoD;
+ pdc->dcattr.efDxPtoD = pdc->dclevel.efDxPtoD;
+ pdc->dcattr.efDyPtoD = pdc->dclevel.efDyPtoD;
+ pdc->dcattr.iMapMode = MM_TEXT;
+ pdc->dcattr.dwLayout = 0;
+ pdc->dcattr.flXform = PAGE_TO_DEVICE_SCALE_IDENTITY |
+ PAGE_TO_DEVICE_IDENTITY |
+ WORLD_TO_PAGE_IDENTITY;
+
+ /* Setup more coordinates */
+ pdc->ptlDCOrig.x = 0;
+ pdc->ptlDCOrig.y = 0;
+ pdc->dcattr.lWindowOrgx = 0;
+ pdc->dcattr.ptlWindowOrg.x = 0;
+ pdc->dcattr.ptlWindowOrg.y = 0;
+ pdc->dcattr.szlWindowExt.cx = 1;
+ pdc->dcattr.szlWindowExt.cy = 1;
+ pdc->dcattr.ptlViewportOrg.x = 0;
+ pdc->dcattr.ptlViewportOrg.y = 0;
+ pdc->dcattr.szlViewportExt.cx = 1;
+ pdc->dcattr.szlViewportExt.cy = 1;
+ pdc->dcattr.szlVirtualDevicePixel.cx = ppdev->gdiinfo.ulHorzRes;
+ pdc->dcattr.szlVirtualDevicePixel.cy = ppdev->gdiinfo.ulVertRes;
+ pdc->dcattr.szlVirtualDeviceMm.cx = ppdev->gdiinfo.ulHorzSize;
+ pdc->dcattr.szlVirtualDeviceMm.cy = ppdev->gdiinfo.ulVertSize;
+ pdc->dcattr.szlVirtualDeviceSize.cx = 0;
+ pdc->dcattr.szlVirtualDeviceSize.cy = 0;
+
+ /* Setup regions */
+ pdc->prgnAPI = NULL;
+ pdc->prgnRao = NULL;
+ /* Allocate a Vis region */
+ pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
+ ASSERT(pdc->prgnVis);
+ GDIOBJ_CopyOwnership(pdc->BaseObject.hHmgr, pdc->prgnVis->BaseObject.hHmgr);
+
+ /* Setup palette */
+ pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE];
+ pdc->dclevel.ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal);
+
+ /* Setup path */
+ pdc->dclevel.hPath = NULL;
+ pdc->dclevel.flPath = 0;
+// pdc->dclevel.lapath:
+
+ /* Setup colors */
+ pdc->dcattr.crBackgroundClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.ulBackgroundClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.crForegroundClr = RGB(0, 0, 0);
+ pdc->dcattr.ulForegroundClr = RGB(0, 0, 0);
+ pdc->dcattr.crBrushClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.ulBrushClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.crPenClr = RGB(0, 0, 0);
+ pdc->dcattr.ulPenClr = RGB(0, 0, 0);
+
+ /* Select the default fill and line brush */
+ pdc->dcattr.hbrush = StockObjects[WHITE_BRUSH];
+ pdc->dcattr.hpen = StockObjects[BLACK_PEN];
+ pdc->dclevel.pbrFill = BRUSH_ShareLockBrush(pdc->pdcattr->hbrush);
+ pdc->dclevel.pbrLine = PEN_ShareLockPen(pdc->pdcattr->hpen);
+ pdc->dclevel.ptlBrushOrigin.x = 0;
+ pdc->dclevel.ptlBrushOrigin.y = 0;
+ pdc->dcattr.ptlBrushOrigin = pdc->dclevel.ptlBrushOrigin;
+
+ /* Initialize EBRUSHOBJs */
+ EBRUSHOBJ_vInit(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
+ EBRUSHOBJ_vInit(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
+ EBRUSHOBJ_vInit(&pdc->eboText, pbrDefaultBrush, pdc);
+ EBRUSHOBJ_vInit(&pdc->eboBackground, pbrDefaultBrush, pdc);
+
+ /* Setup fill data */
+ pdc->dcattr.jROP2 = R2_COPYPEN;
+ pdc->dcattr.jBkMode = 2;
+ pdc->dcattr.lBkMode = 2;
+ pdc->dcattr.jFillMode = ALTERNATE;
+ pdc->dcattr.lFillMode = 1;
+ pdc->dcattr.jStretchBltMode = 1;
+ pdc->dcattr.lStretchBltMode = 1;
+ pdc->ptlFillOrigin.x = 0;
+ pdc->ptlFillOrigin.y = 0;
+
+ /* Setup drawing position */
+ pdc->dcattr.ptlCurrent.x = 0;
+ pdc->dcattr.ptlCurrent.y = 0;
+ pdc->dcattr.ptfxCurrent.x = 0;
+ pdc->dcattr.ptfxCurrent.y = 0;
+
+ /* Setup ICM data */
+ pdc->dclevel.lIcmMode = 0;
+ pdc->dcattr.lIcmMode = 0;
+ pdc->dcattr.hcmXform = NULL;
+ pdc->dcattr.flIcmFlags = 0;
+ pdc->dcattr.IcmBrushColor = CLR_INVALID;
+ pdc->dcattr.IcmPenColor = CLR_INVALID;
+ pdc->dcattr.pvLIcm = NULL;
+ pdc->dcattr.hColorSpace = NULL; // FIXME: 0189001f
+ pdc->dclevel.pColorSpace = NULL; // FIXME
+ pdc->pClrxFormLnk = NULL;
+// pdc->dclevel.ca =
+
+ /* Setup font data */
+ pdc->hlfntCur = NULL; // FIXME: 2f0a0cf8
+ pdc->pPFFList = NULL;
+ pdc->flSimulationFlags = 0;
+ pdc->lEscapement = 0;
+ pdc->prfnt = NULL;
+ pdc->dcattr.flFontMapper = 0;
+ pdc->dcattr.flTextAlign = 0;
+ pdc->dcattr.lTextAlign = 0;
+ pdc->dcattr.lTextExtra = 0;
+ pdc->dcattr.lRelAbs = 1;
+ pdc->dcattr.lBreakExtra = 0;
+ pdc->dcattr.cBreak = 0;
+ pdc->dcattr.hlfntNew = StockObjects[SYSTEM_FONT];
+// pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew);
+
+ /* Other stuff */
+ pdc->hdcNext = NULL;
+ pdc->hdcPrev = NULL;
+ pdc->ipfdDevMax = 0x0000ffff;
+ pdc->ulCopyCount = -1;
+ pdc->ptlDoBanding.x = 0;
+ pdc->ptlDoBanding.y = 0;
+ pdc->dclevel.lSaveDepth = 1;
+ pdc->dclevel.hdcSave = NULL;
+ pdc->dcattr.iGraphicsMode = GM_COMPATIBLE;
+ pdc->dcattr.iCS_CP = 0;
+ pdc->pSurfInfo = NULL;
+
+}
+
+BOOL
+INTERNAL_CALL
DC_Cleanup(PVOID ObjectBody)
{
- PDC pDC = (PDC)ObjectBody;
+ PDC pdc = (PDC)ObjectBody;
- /* Free driver name (HACK) */
- if (pDC->rosdc.DriverName.Buffer)
- ExFreePoolWithTag(pDC->rosdc.DriverName.Buffer, TAG_DC);
+ /* Free DC_ATTR */
+ DC_vFreeDcAttr(pdc);
+
+ /* Delete saved DCs */
+ DC_vRestoreDC(pdc, 1);
/* Deselect dc objects */
- DC_vSelectSurface(pDC, NULL);
- DC_vSelectFillBrush(pDC, NULL);
- DC_vSelectLineBrush(pDC, NULL);
- DC_vSelectPalette(pDC, NULL);
-
- /* Dereference default brushes */
- if (pDC->eboText.pbrush)
- BRUSH_ShareUnlockBrush(pDC->eboText.pbrush);
- if (pDC->eboBackground.pbrush)
- BRUSH_ShareUnlockBrush(pDC->eboBackground.pbrush);
+ DC_vSelectSurface(pdc, NULL);
+ DC_vSelectFillBrush(pdc, NULL);
+ DC_vSelectLineBrush(pdc, NULL);
+ DC_vSelectPalette(pdc, NULL);
/* Cleanup the dc brushes */
- EBRUSHOBJ_vCleanup(&pDC->eboFill);
- EBRUSHOBJ_vCleanup(&pDC->eboLine);
- EBRUSHOBJ_vCleanup(&pDC->eboText);
- EBRUSHOBJ_vCleanup(&pDC->eboBackground);
+ EBRUSHOBJ_vCleanup(&pdc->eboFill);
+ EBRUSHOBJ_vCleanup(&pdc->eboLine);
+ EBRUSHOBJ_vCleanup(&pdc->eboText);
+ EBRUSHOBJ_vCleanup(&pdc->eboBackground);
+
+ /* Free regions */
+ if (pdc->rosdc.hClipRgn)
+ GreDeleteObject(pdc->rosdc.hClipRgn);
+ if (pdc->prgnVis)
+ REGION_FreeRgnByHandle(pdc->prgnVis->BaseObject.hHmgr);
+ if (pdc->rosdc.hGCClipRgn)
+ GreDeleteObject(pdc->rosdc.hGCClipRgn);
+ if (NULL != pdc->rosdc.CombinedClip)
+ IntEngDeleteClipRegion(pdc->rosdc.CombinedClip);
+
+ PATH_Delete(pdc->dclevel.hPath);
+
+ if(pdc->dclevel.pSurface)
+ SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
+
+ PDEVOBJ_vRelease(pdc->ppdev) ;
return TRUE;
}
@@ -186,205 +380,187 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner)
INT Index;
PGDI_TABLE_ENTRY Entry;
PDC pDC;
+ BOOL ret = FALSE;
- if (!GDIOBJ_SetOwnership(hDC, Owner)) return FALSE;
- pDC = DC_LockDc(hDC);
- if (pDC)
+ if (!GDIOBJ_SetOwnership(hDC, Owner))
{
+ DPRINT1("GDIOBJ_SetOwnership failed\n");
+ return FALSE;
+ }
+
+ pDC = DC_LockDc(hDC);
+ if (!pDC)
+ {
+ DPRINT1("Could not lock DC\n");
+ return FALSE;
+ }
+
/*
System Regions:
These regions do not use attribute sections and when allocated, use
gdiobj level functions.
*/
- if (pDC->rosdc.hClipRgn)
- { // FIXME! HAX!!!
- Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn);
- Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData) FreeObjectAttr(Entry->UserData);
- Entry->UserData = NULL;
- //
- if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) return FALSE;
- }
- if (pDC->prgnVis)
- { // FIXME! HAX!!!
- Index = GDI_HANDLE_GET_INDEX(pDC->prgnVis->BaseObject.hHmgr);
- Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData) FreeObjectAttr(Entry->UserData);
- Entry->UserData = NULL;
- //
- if (!GDIOBJ_SetOwnership(pDC->prgnVis->BaseObject.hHmgr, Owner)) return FALSE;
- }
- if (pDC->rosdc.hGCClipRgn)
- { // FIXME! HAX!!!
- Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn);
- Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData) FreeObjectAttr(Entry->UserData);
- Entry->UserData = NULL;
- //
- if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) return FALSE;
- }
- if (pDC->dclevel.hPath)
- {
- if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) return FALSE;
- }
- DC_UnlockDc(pDC);
+ if (pDC->rosdc.hClipRgn)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) goto leave;
}
+ if (pDC->prgnVis)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->prgnVis->BaseObject.hHmgr);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->prgnVis->BaseObject.hHmgr, Owner)) goto leave;
+ }
+ if (pDC->rosdc.hGCClipRgn)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) goto leave;
+ }
+ if (pDC->dclevel.hPath)
+ {
+ if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) goto leave;
+ }
+ ret = TRUE;
- return TRUE;
+leave:
+ DC_UnlockDc(pDC);
+
+ return ret;
}
-HDC FASTCALL
-IntGdiCreateDC(
- PUNICODE_STRING Driver,
- PUNICODE_STRING Device,
- PVOID pUMdhpdev,
- CONST PDEVMODEW InitData,
- BOOL CreateAsIC)
+int FASTCALL
+CLIPPING_UpdateGCRegion(DC* Dc);
+
+static
+void
+DC_vUpdateDC(PDC pdc)
{
- HDC hdc;
- PDC pdc;
- PDC_ATTR pdcattr;
- HRGN hVisRgn;
- UNICODE_STRING StdDriver;
- BOOL calledFromUser;
+ HRGN hVisRgn ;
+ PPDEVOBJ ppdev = pdc->ppdev ;
- RtlInitUnicodeString(&StdDriver, L"DISPLAY");
+ pdc->dhpdev = ppdev->dhpdev;
- DPRINT("DriverName: %wZ, DeviceName: %wZ\n", Driver, Device);
+ SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
+ pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
- if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
+ PDEVOBJ_sizl(pdc->ppdev, &pdc->dclevel.sizl);
+ hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
+ ASSERT(hVisRgn);
+ GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
+ GreDeleteObject(hVisRgn);
+
+ pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
+ pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
+
+ /* Mark EBRUSHOBJs as dirty */
+ pdc->pdcattr->ulDirty_ |= DIRTY_DEFAULT ;
+}
+
+/* Prepare a blit for up to 2 DCs */
+/* rc1 and rc2 are the rectangles where we want to draw or
+ * from where we take pixels. */
+VOID
+FASTCALL
+DC_vPrepareDCsForBlit(PDC pdc1,
+ RECT rc1,
+ PDC pdc2,
+ RECT rc2)
+{
+ PDC pdcFirst, pdcSecond;
+ PRECT prcFirst, prcSecond;
+ /* Lock them in good order */
+ if(pdc2)
{
- if (CreateAsIC)
+ if((ULONG_PTR)pdc1->ppdev->hsemDevLock >= (ULONG_PTR)pdc2->ppdev->hsemDevLock)
{
- if (! IntPrepareDriverIfNeeded())
- {
- /* Here, we have two possibilities:
- * a) return NULL, and hope that the caller
- * won't call us in a loop
- * b) bugcheck, but caller is unable to
- * react on the problem
- */
- /*DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
- return NULL;*/
- KeBugCheck(VIDEO_DRIVER_INIT_FAILURE);
- }
+ pdcFirst = pdc1;
+ prcFirst = &rc1;
+ pdcSecond = pdc2;
+ prcSecond = &rc2;
}
else
{
- calledFromUser = UserIsEntered();
- if (!calledFromUser)
- {
- UserEnterExclusive();
- }
-
- if (! co_IntGraphicsCheck(TRUE))
- {
- if (!calledFromUser)
- {
- UserLeave();
- }
- DPRINT1("Unable to initialize graphics, returning NULL dc\n");
- return NULL;
- }
-
- if (!calledFromUser)
- {
- UserLeave();
- }
-
+ pdcFirst = pdc2;
+ prcFirst = &rc2;
+ pdcSecond = pdc1;
+ prcSecond = &rc1;
}
}
-
- /* Check for existing DC object */
- if ((hdc = DC_FindOpenDC(Driver)) != NULL)
- {
- hdc = NtGdiCreateCompatibleDC(hdc);
- if (!hdc)
- DPRINT1("NtGdiCreateCompatibleDC() failed\n");
- return hdc;
- }
-
- /* Allocate a DC object */
- pdc = DC_AllocDC(Driver);
- if (pdc == NULL)
- {
- DPRINT1("DC_AllocDC() failed\n");
- return NULL;
- }
- hdc = pdc->BaseObject.hHmgr;
- pdcattr = pdc->pdcattr;
-
- pdc->dctype = DC_TYPE_DIRECT;
-
- pdc->dhpdev = PrimarySurface.dhpdev;
- if (pUMdhpdev) pUMdhpdev = pdc->dhpdev; // set DHPDEV for device.
- pdc->ppdev = (PVOID)&PrimarySurface;
-
- // ATM we only have one display.
- pdcattr->ulDirty_ |= DC_PRIMARY_DISPLAY;
-
- pdc->flGraphicsCaps = PrimarySurface.devinfo.flGraphicsCaps;
- pdc->flGraphicsCaps2 = PrimarySurface.devinfo.flGraphicsCaps2;
-
- pdc->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
-
- pdcattr->jROP2 = R2_COPYPEN;
-
- pdc->erclWindow.top = pdc->erclWindow.left = 0;
- pdc->erclWindow.right = pdc->ppdev->gdiinfo.ulHorzRes;
- pdc->erclWindow.bottom = pdc->ppdev->gdiinfo.ulVertRes;
- pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; // Default is CCW.
-
- pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
-
- hVisRgn = IntSysCreateRectRgn(0, 0, pdc->ppdev->gdiinfo.ulHorzRes,
- pdc->ppdev->gdiinfo.ulVertRes);
-
- if (!CreateAsIC)
- {
- pdc->pSurfInfo = NULL;
-// pdc->dclevel.pSurface =
- DC_UnlockDc(pdc);
-
- /* Initialize the DC state */
- IntGdiSetTextColor(hdc, RGB(0, 0, 0));
- IntGdiSetBkColor(hdc, RGB(255, 255, 255));
- }
else
{
- /* From MSDN2:
- The CreateIC function creates an information context for the specified device.
- The information context provides a fast way to get information about the
- device without creating a device context (DC). However, GDI drawing functions
- cannot accept a handle to an information context.
- */
- pdc->dctype = DC_TYPE_INFO;
-// pdc->pSurfInfo =
-// DC_vSelectSurface(pdc, NULL);
- pdcattr->crBackgroundClr = pdcattr->ulBackgroundClr = RGB(255, 255, 255);
- pdcattr->crForegroundClr = RGB(0, 0, 0);
- DC_UnlockDc(pdc);
+ pdcFirst = pdc1 ;
+ prcFirst = &rc1;
+ pdcSecond = NULL ;
}
- DC_InitDC(hdc);
- if (hVisRgn)
+ if(pdcFirst && pdcFirst->dctype == DCTYPE_DIRECT)
{
- GdiSelectVisRgn(hdc, hVisRgn);
- REGION_FreeRgnByHandle(hVisRgn);
+ EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock);
+ MouseSafetyOnDrawStart(pdcFirst->ppdev,
+ prcFirst->left,
+ prcFirst->top,
+ prcFirst->right,
+ prcFirst->bottom) ;
+ /* Update surface if needed */
+ if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
+ {
+ DC_vUpdateDC(pdcFirst);
+ }
+ }
+ if(pdcSecond && pdcSecond->dctype == DCTYPE_DIRECT)
+ {
+ EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock);
+ MouseSafetyOnDrawStart(pdcSecond->ppdev,
+ prcSecond->left,
+ prcSecond->top,
+ prcSecond->right,
+ prcSecond->bottom) ;
+ /* Update surface if needed */
+ if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
+ {
+ DC_vUpdateDC(pdcSecond);
+ }
}
-
- IntGdiSetTextAlign(hdc, TA_TOP);
- IntGdiSetBkMode(hdc, OPAQUE);
-
- return hdc;
}
+/* Finishes a blit for one or two DCs */
+VOID
+FASTCALL
+DC_vFinishBlit(PDC pdc1, PDC pdc2)
+{
+ if(pdc1->dctype == DCTYPE_DIRECT)
+ {
+ MouseSafetyOnDrawEnd(pdc1->ppdev);
+ EngReleaseSemaphore(pdc1->ppdev->hsemDevLock);
+ }
-HDC APIENTRY
-NtGdiOpenDCW(
- PUNICODE_STRING Device,
- DEVMODEW *InitData,
+ if(pdc2)
+ {
+ if(pdc2->dctype == DCTYPE_DIRECT)
+ {
+ MouseSafetyOnDrawEnd(pdc2->ppdev);
+ EngReleaseSemaphore(pdc2->ppdev->hsemDevLock);
+ }
+ }
+}
+
+HDC
+NTAPI
+GreOpenDCW(
+ PUNICODE_STRING pustrDevice,
+ DEVMODEW *pdmInit,
PUNICODE_STRING pustrLogAddr,
ULONG iType,
BOOL bDisplay,
@@ -392,98 +568,210 @@ NtGdiOpenDCW(
VOID *pDriverInfo2,
VOID *pUMdhpdev)
{
- UNICODE_STRING SafeDevice;
- DEVMODEW SafeInitData;
- PVOID Dhpdev;
- HDC Ret;
- NTSTATUS Status = STATUS_SUCCESS;
+ PPDEVOBJ ppdev;
+ PDC pdc;
+ HDC hdc;
- if (!Device) return UserGetDesktopDC(iType,FALSE,TRUE);
+ DPRINT("GreOpenDCW(%S, iType=%ld)\n",
+ pustrDevice ? pustrDevice->Buffer : NULL, iType);
- if (InitData)
+ /* Get a PDEVOBJ for the device */
+ ppdev = EngpGetPDEV(pustrDevice);
+ if (!ppdev)
{
+ DPRINT1("Didn't find a suitable PDEV\n");
+ return NULL;
+ }
+
+ DPRINT("GreOpenDCW - ppdev = %p\n", ppdev);
+
+ pdc = DC_AllocDcWithHandle();
+ if (!pdc)
+ {
+ DPRINT1("Could not Allocate a DC\n");
+ PDEVOBJ_vRelease(ppdev);
+ return NULL;
+ }
+ hdc = pdc->BaseObject.hHmgr;
+
+ /* Lock ppdev and initialize the new DC */
+ DC_vInitDc(pdc, iType, ppdev);
+ /* FIXME: HACK! */
+ DC_InitHack(pdc);
+
+ DC_AllocDcAttr(pdc);
+
+ DC_UnlockDc(pdc);
+
+ DPRINT("returning hdc = %p\n", hdc);
+
+ return hdc;
+}
+
+HDC
+APIENTRY
+NtGdiOpenDCW(
+ PUNICODE_STRING pustrDevice,
+ DEVMODEW *pdmInit,
+ PUNICODE_STRING pustrLogAddr,
+ ULONG iType,
+ BOOL bDisplay,
+ HANDLE hspool,
+ VOID *pDriverInfo2,
+ VOID *pUMdhpdev)
+{
+ UNICODE_STRING ustrDevice;
+ WCHAR awcDevice[CCHDEVICENAME];
+ DEVMODEW dmInit;
+ PVOID dhpdev;
+ HDC hdc;
+
+ /* Only if a devicename is given, we need any data */
+ if (pustrDevice)
+ {
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
_SEH2_TRY
{
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+
+ if (pdmInit)
+ {
+ /* FIXME: could be larger */
+ ProbeForRead(pdmInit, sizeof(DEVMODEW), 1);
+ RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW));
+ }
+
if (pUMdhpdev)
{
- ProbeForWrite(pUMdhpdev, sizeof(PVOID), 1);
+ ProbeForWrite(pUMdhpdev, sizeof(HANDLE), 1);
}
- ProbeForRead(InitData, sizeof(DEVMODEW), 1);
- RtlCopyMemory(&SafeInitData, InitData, sizeof(DEVMODEW));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH2_GetExceptionCode();
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return NULL);
}
- _SEH2_END;
-
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- return NULL;
- }
- /* FIXME - InitData can have some more bytes! */
+ _SEH2_END
}
-
- if (Device)
+ else
{
- Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
- if (!NT_SUCCESS(Status))
+ pdmInit = NULL;
+ pUMdhpdev = NULL;
+ }
+
+ /* FIXME: HACK! */
+ if (pustrDevice)
+ {
+ UNICODE_STRING ustrDISPLAY = RTL_CONSTANT_STRING(L"DISPLAY");
+ if (RtlEqualUnicodeString(&ustrDevice, &ustrDISPLAY, TRUE))
{
- SetLastNtError(Status);
- return NULL;
+ pustrDevice = NULL;
}
}
- Ret = IntGdiCreateDC(Device ? &SafeDevice : NULL,
- NULL,
- pUMdhpdev ? &Dhpdev : NULL,
- InitData ? &SafeInitData : NULL,
- (BOOL) iType); // FALSE 0 DCW, TRUE 1 ICW
+ /* Call the internal function */
+ hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL,
+ pdmInit ? &dmInit : NULL,
+ NULL, // fixme pwszLogAddress
+ iType,
+ bDisplay,
+ hspool,
+ NULL, //FIXME: pDriverInfo2
+ pUMdhpdev ? &dhpdev : NULL);
- // FIXME!!!!
- if (pUMdhpdev) pUMdhpdev = Dhpdev;
+ /* If we got a HDC and a UM dhpdev is requested,... */
+ if (hdc && pUMdhpdev)
+ {
+ /* Copy dhpdev to caller (FIXME: use dhpdev?? */
+ _SEH2_TRY
+ {
+ /* Pointer was already probed */
+ *(HANDLE*)pUMdhpdev = dhpdev;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Ignore error */
+ }
+ _SEH2_END
+ }
- return Ret;
+ return hdc;
}
-HDC FASTCALL
-IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
+
+HDC
+APIENTRY
+NtGdiCreateCompatibleDC(HDC hdc)
{
- HDC hDC;
- UNICODE_STRING DriverName;
- RtlInitUnicodeString(&DriverName, L"DISPLAY");
+ HDC hdcNew;
+ PPDEVOBJ ppdev;
+ PDC pdc, pdcNew;
- if (DcType != DC_TYPE_MEMORY)
- hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, (DcType == DC_TYPE_INFO));
- else
- hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth!
-//
-// There is room to grow here~
-//
+ DPRINT("NtGdiCreateCompatibleDC(0x%p)\n", hdc);
-//
-// If NULL, first time through! Build the default (was window) dc!
-// Setup clean DC state for the system.
-//
- if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG!
- { // This is a cheesy way to do this.
- PDC dc = DC_LockDc(hDC);
- HSURF hsurf;
- defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
- if (!defaultDCstate)
+ /* Did the caller provide a DC? */
+ if (hdc)
+ {
+ /* Yes, try to lock it */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
{
- DC_UnlockDc(dc);
+ DPRINT1("Could not lock source DC %p\n", hdc);
return NULL;
}
- RtlZeroMemory(defaultDCstate, sizeof(DC));
- defaultDCstate->pdcattr = &defaultDCstate->dcattr;
- hsurf = (HSURF)PrimarySurface.pSurface; // HAX
- defaultDCstate->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
- DC_vCopyState(dc, defaultDCstate, TRUE);
- DC_UnlockDc(dc);
+
+ /* Get the pdev from the DC */
+ ppdev = pdc->ppdev;
+ InterlockedIncrement(&ppdev->cPdevRefs);
+
+ /* Unlock the source DC */
+ DC_UnlockDc(pdc);
}
- return hDC;
+ else
+ {
+ /* No DC given, get default device */
+ ppdev = EngpGetPDEV(NULL);
+ }
+
+ if (!ppdev)
+ {
+ DPRINT1("Didn't find a suitable PDEV\n");
+ return NULL;
+ }
+
+ /* Allocate a new DC */
+ pdcNew = DC_AllocDcWithHandle();
+ if (!pdcNew)
+ {
+ DPRINT1("Could not allocate a new DC\n");
+ PDEVOBJ_vRelease(ppdev);
+ return NULL;
+ }
+ hdcNew = pdcNew->BaseObject.hHmgr;
+
+ /* Lock ppdev and initialize the new DC */
+ DC_vInitDc(pdcNew, DCTYPE_MEMORY, ppdev);
+ /* FIXME: HACK! */
+ DC_InitHack(pdcNew);
+
+ /* Allocate a dc attribute */
+ DC_AllocDcAttr(pdcNew);
+
+ // HACK!
+ DC_vSelectSurface(pdcNew, psurfDefaultBitmap);
+
+ DC_UnlockDc(pdcNew);
+
+ DPRINT("Leave NtGdiCreateCompatibleDC hdcNew = %p\n", hdcNew);
+
+ return hdcNew;
}
BOOL
@@ -500,102 +788,69 @@ IntGdiDeleteDC(HDC hDC, BOOL Force)
if (!Force)
{
+ /* Windows permits NtGdiDeleteObjectApp to delete a permanent DC
+ * For some reason, it's still a valid handle, pointing to some kernel data.
+ * Not sure if this is a bug, a feature, some cache stuff... Who knows?
+ * See NtGdiDeleteObjectApp test for details */
if (DCToDelete->fs & DC_FLAG_PERMANENT)
{
- DPRINT1("No! You Naughty Application!\n");
DC_UnlockDc(DCToDelete);
- return UserReleaseDC(NULL, hDC, FALSE);
+ if(UserReleaseDC(NULL, hDC, FALSE))
+ {
+ /* ReactOs feature : call UserReleaseDC
+ * I don't think windows does it.
+ * Still, complain, no one should ever call DeleteDC
+ * on a window DC */
+ DPRINT1("No, you naughty application!\n");
+ return TRUE;
+ }
+ else
+ {
+ /* This is not a window owned DC.
+ * Force its deletion */
+ return IntGdiDeleteDC(hDC, TRUE);
+ }
}
}
- /* First delete all saved DCs */
- while (DCToDelete->dclevel.lSaveDepth > 1)
- {
- PDC savedDC;
- HDC savedHDC;
-
- savedHDC = DCToDelete->hdcNext;
- savedDC = DC_LockDc(savedHDC);
- if (savedDC == NULL)
- {
- break;
- }
- DCToDelete->hdcNext = savedDC->hdcNext;
- DCToDelete->dclevel.lSaveDepth--;
- DC_UnlockDc(savedDC);
- IntGdiDeleteDC(savedHDC, Force);
- }
-
- /* Free GDI resources allocated to this DC */
- if (!(DCToDelete->dclevel.flPath & DCPATH_SAVESTATE))
- {
- /*
- NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN);
- NtGdiSelectBrush (DCHandle, STOCK_WHITE_BRUSH);
- NtGdiSelectFont (DCHandle, STOCK_SYSTEM_FONT);
- DC_LockDC (DCHandle); NtGdiSelectXxx does not recognize stock objects yet */
- }
- if (DCToDelete->rosdc.hClipRgn)
- {
- GreDeleteObject(DCToDelete->rosdc.hClipRgn);
- }
- if (DCToDelete->prgnVis)
- {
- GreDeleteObject(DCToDelete->prgnVis->BaseObject.hHmgr);
- }
- if (NULL != DCToDelete->rosdc.CombinedClip)
- {
- IntEngDeleteClipRegion(DCToDelete->rosdc.CombinedClip);
- }
- if (DCToDelete->rosdc.hGCClipRgn)
- {
- GreDeleteObject(DCToDelete->rosdc.hGCClipRgn);
- }
- if (DCToDelete->dclevel.prgnMeta)
- {
- GreDeleteObject(((PROSRGNDATA)DCToDelete->dclevel.prgnMeta)->BaseObject.hHmgr);
- }
- if (DCToDelete->prgnAPI)
- {
- GreDeleteObject(((PROSRGNDATA)DCToDelete->prgnAPI)->BaseObject.hHmgr);
- }
- PATH_Delete(DCToDelete->dclevel.hPath);
-
DC_UnlockDc(DCToDelete);
- GreDeleteObject(hDC);
+
+ if (!IsObjectDead(hDC))
+ {
+ if (!GDIOBJ_FreeObjByHandle(hDC, GDI_OBJECT_TYPE_DC))
+ {
+ DPRINT1("DC_FreeDC failed\n");
+ }
+ }
+ else
+ {
+ DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC);
+ }
+
return TRUE;
}
-HDC FASTCALL
-DC_FindOpenDC(PUNICODE_STRING Driver)
+BOOL
+APIENTRY
+NtGdiDeleteObjectApp(HANDLE DCHandle)
{
- return NULL;
-}
+ /* Complete all pending operations */
+ NtGdiFlushUserBatch();
-/*!
- * Initialize some common fields in the Device Context structure.
-*/
-VOID FASTCALL
-DC_InitDC(HDC DCHandle)
-{
-// NtGdiRealizeDefaultPalette(DCHandle);
+ if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
-//// Removed for now.. See above brush and pen.
-// NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
-// NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
-////
- //NtGdiSelectFont(DCHandle, hFont);
+ if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC)
+ return GreDeleteObject((HGDIOBJ) DCHandle);
- /*
- {
- int res;
- res = CLIPPING_UpdateGCRegion(DCToInit);
- ASSERT ( res != ERROR );
- }
- */
+ if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
- /* Set virtual resolution */
- NtGdiSetVirtualResolution(DCHandle, 0, 0, 0, 0);
+ if (!GDIOBJ_OwnedByCurrentProcess(DCHandle))
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ return IntGdiDeleteDC(DCHandle, FALSE);
}
BOOL
@@ -618,7 +873,7 @@ MakeInfoDC(PDC pdc, BOOL bSet)
pdc->dctype = DC_TYPE_INFO;
pdc->dclevel.pSurface = NULL;
- PDEV_sizl(pdc->ppdev, &sizl);
+ PDEVOBJ_sizl(pdc->ppdev, &sizl);
if ( sizl.cx == pdc->dclevel.sizl.cx &&
sizl.cy == pdc->dclevel.sizl.cy )
@@ -669,132 +924,42 @@ NtGdiMakeInfoDC(
return FALSE;
}
-HDC APIENTRY
-NtGdiCreateCompatibleDC(HDC hDC)
+
+HDC FASTCALL
+IntGdiCreateDC(
+ PUNICODE_STRING Driver,
+ PUNICODE_STRING pustrDevice,
+ PVOID pUMdhpdev,
+ CONST PDEVMODEW pdmInit,
+ BOOL CreateAsIC)
{
- PDC pdcNew, pdcOld;
- PDC_ATTR pdcattrNew, pdcattrOld;
- HDC hdcNew, DisplayDC = NULL;
- UNICODE_STRING DriverName;
- DWORD Layout = 0;
- HSURF hsurf;
+ HDC hdc;
- if (hDC == NULL)
- {
- RtlInitUnicodeString(&DriverName, L"DISPLAY");
- DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE);
- if (NULL == DisplayDC)
- {
- DPRINT1("Failed to create DisplayDC\n");
- return NULL;
- }
- hDC = DisplayDC;
- }
+ hdc = GreOpenDCW(pustrDevice,
+ pdmInit,
+ NULL,
+ CreateAsIC ? DCTYPE_INFO :
+ (Driver ? DC_TYPE_DIRECT : DC_TYPE_DIRECT),
+ TRUE,
+ NULL,
+ NULL,
+ pUMdhpdev);
- /* Allocate a new DC based on the original DC's device */
- pdcOld = DC_LockDc(hDC);
- if (NULL == pdcOld)
- {
- if (NULL != DisplayDC)
- {
- NtGdiDeleteObjectApp(DisplayDC);
- }
- DPRINT1("Failed to lock hDC\n");
- return NULL;
- }
- pdcNew = DC_AllocDC(&pdcOld->rosdc.DriverName);
- if (!pdcNew)
- {
- DPRINT1("Failed to create pdcNew\n");
- DC_UnlockDc(pdcOld);
- if (DisplayDC)
- {
- NtGdiDeleteObjectApp(DisplayDC);
- }
- return NULL;
- }
- hdcNew = pdcNew->BaseObject.hHmgr;
-
- pdcattrOld = pdcOld->pdcattr;
- pdcattrNew = pdcNew->pdcattr;
-
- /* Copy information from original DC to new DC */
- pdcNew->dclevel.hdcSave = hdcNew;
-
- pdcNew->dhpdev = pdcOld->dhpdev;
-
- /* DriverName is copied in the AllocDC routine */
- pdcattrNew->ptlWindowOrg = pdcattrOld->ptlWindowOrg;
- pdcattrNew->szlWindowExt = pdcattrOld->szlWindowExt;
- pdcattrNew->ptlViewportOrg = pdcattrOld->ptlViewportOrg;
- pdcattrNew->szlViewportExt = pdcattrOld->szlViewportExt;
-
- pdcNew->dctype = DC_TYPE_MEMORY; // Always!
- hsurf = NtGdiGetStockObject(DEFAULT_BITMAP);
- pdcNew->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
- pdcNew->ppdev = pdcOld->ppdev;
- pdcNew->dclevel.hpal = pdcOld->dclevel.hpal;
-
- pdcattrNew->lTextAlign = pdcattrOld->lTextAlign;
- pdcattrNew->lBkMode = pdcattrOld->lBkMode;
- pdcattrNew->jBkMode = pdcattrOld->jBkMode;
- pdcattrNew->jROP2 = pdcattrOld->jROP2;
- pdcattrNew->dwLayout = pdcattrOld->dwLayout;
- if (pdcattrOld->dwLayout & LAYOUT_ORIENTATIONMASK) Layout = pdcattrOld->dwLayout;
- pdcNew->dclevel.flPath = pdcOld->dclevel.flPath;
- pdcattrNew->ulDirty_ = pdcattrOld->ulDirty_;
- pdcattrNew->iCS_CP = pdcattrOld->iCS_CP;
-
- pdcNew->erclWindow.left = pdcNew->erclWindow.top = 0;
- pdcNew->erclWindow.right = pdcNew->erclWindow.bottom = 1;
-
- DC_UnlockDc(pdcNew);
- DC_UnlockDc(pdcOld);
- if (NULL != DisplayDC)
- {
- NtGdiDeleteObjectApp(DisplayDC);
- }
-
- if (Layout) NtGdiSetLayout(hdcNew, -1, Layout);
-
- DC_InitDC(hdcNew);
- return hdcNew;
+ return hdc;
}
-
-BOOL
-APIENTRY
-NtGdiDeleteObjectApp(HANDLE DCHandle)
+HDC FASTCALL
+IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
{
- GDIOBJTYPE ObjType;
+ HDC hDC;
+ UNIMPLEMENTED;
+ ASSERT(FALSE);
- /* Complete all pending operations */
- NtGdiFlushUserBatch();
+ if (DcType == DC_TYPE_MEMORY)
+ hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth!
+ else
+ hDC = IntGdiCreateDC(NULL, NULL, NULL, NULL, (DcType == DC_TYPE_INFO));
- if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
-
- if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
-
- ObjType = GDI_OBJECT_GET_TYPE_INDEX((ULONG_PTR)DCHandle);
-
- if (GreGetObjectOwner( DCHandle, ObjType))
- {
- switch(ObjType)
- {
- case GDIObjType_DC_TYPE:
- return IntGdiDeleteDC(DCHandle, FALSE);
-
- case GDIObjType_RGN_TYPE:
- case GDIObjType_SURF_TYPE:
- case GDIObjType_PAL_TYPE:
- case GDIObjType_LFONT_TYPE:
- case GDIObjType_BRUSH_TYPE:
- return GreDeleteObject((HGDIOBJ) DCHandle);
-
- default:
- return FALSE;
- }
- }
- return (DCHandle != NULL);
+ return hDC;
}
diff --git a/subsystems/win32/win32k/objects/dcobjs.c b/subsystems/win32/win32k/objects/dcobjs.c
index 3a093a01401..bba8441435d 100644
--- a/subsystems/win32/win32k/objects/dcobjs.c
+++ b/subsystems/win32/win32k/objects/dcobjs.c
@@ -110,8 +110,10 @@ DC_vUpdateTextBrush(PDC pdc)
{
PDC_ATTR pdcattr = pdc->pdcattr;
+ /* Timo : The text brush should never be changed.
+ * Jérôme : Yeah, but its palette must be updated anyway! */
if(pdcattr->ulDirty_ & DIRTY_TEXT)
- EBRUSHOBJ_vUpdate(&pdc->eboText, pdc->eboText.pbrush, pdc);
+ EBRUSHOBJ_vUpdate(&pdc->eboText, pbrDefaultBrush, pdc);
/* Update the eboText's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr);
@@ -127,7 +129,7 @@ DC_vUpdateBackgroundBrush(PDC pdc)
PDC_ATTR pdcattr = pdc->pdcattr;
if(pdcattr->ulDirty_ & DIRTY_BACKGROUND)
- EBRUSHOBJ_vUpdate(&pdc->eboBackground, pdc->eboBackground.pbrush, pdc);
+ EBRUSHOBJ_vUpdate(&pdc->eboBackground, pbrDefaultBrush, pdc);
/* Update the eboBackground's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr);
@@ -164,7 +166,7 @@ GdiSelectPalette(
/* Is this a valid palette for this depth? */
if ((BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) <= 8
- && ppal->Mode == PAL_INDEXED) ||
+ && (ppal->flFlags & PAL_INDEXED)) ||
(BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) > 8))
{
/* Get old palette, set new one */
@@ -282,14 +284,24 @@ NtGdiSelectBitmap(
}
/* Get the handle for the old bitmap */
- psurfOld = pDC->dclevel.pSurface;
- hOrgBmp = psurfOld ? psurfOld->BaseObject.hHmgr : NULL;
+ ASSERT(pDC->dclevel.pSurface);
+ hOrgBmp = pDC->dclevel.pSurface->BaseObject.hHmgr;
+
+ /* Lock it, to be sure while we mess with it*/
+ psurfOld = SURFACE_LockSurface(hOrgBmp);
+
+ /* Reset hdc, this surface isn't selected anymore */
+ psurfOld->hdc = NULL;
/* Release the old bitmap, reference the new */
DC_vSelectSurface(pDC, psurfBmp);
+ /* And unlock it, now we're done */
+ SURFACE_UnlockSurface(psurfOld);
+
// If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
- psurfBmp->hDC = hDC;
+ psurfBmp->hdc = hDC;
+
/* FIXME; improve by using a region without a handle and selecting it */
hVisRgn = IntSysCreateRectRgn( 0,
@@ -356,6 +368,7 @@ NtGdiSelectClipPath(
if (pPath->state != PATH_Closed)
{
SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+ DC_UnlockDc(pdc);
return FALSE;
}
diff --git a/subsystems/win32/win32k/objects/dcstate.c b/subsystems/win32/win32k/objects/dcstate.c
index f7942f33d02..889a8733087 100644
--- a/subsystems/win32/win32k/objects/dcstate.c
+++ b/subsystems/win32/win32k/objects/dcstate.c
@@ -15,9 +15,14 @@ VOID
FASTCALL
DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
{
+ DPRINT("DC_vCopyState(%p, %p)\n", pdcSrc->BaseObject.hHmgr, pdcDst->BaseObject.hHmgr);
+
/* Copy full DC attribute */
*pdcDst->pdcattr = *pdcSrc->pdcattr;
-
+
+ /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
+ /* The VisRectRegion field needs to be set to a valid state */
+
/* Mark some fields as dirty */
pdcDst->pdcattr->ulDirty_ |= 0x0012001f; // Note: Use if, To is FALSE....
@@ -36,7 +41,6 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
pdcDst->dclevel.hpal = pdcSrc->dclevel.hpal;
/* Handle references here correctly */
- DC_vSelectSurface(pdcDst, pdcSrc->dclevel.pSurface);
DC_vSelectFillBrush(pdcDst, pdcSrc->dclevel.pbrFill);
DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine);
DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal);
@@ -91,16 +95,96 @@ NtGdiResetDC(
}
+VOID
+NTAPI
+DC_vRestoreDC(
+ IN PDC pdc,
+ INT iSaveLevel)
+{
+ PEPROCESS pepCurrentProcess;
+ HDC hdcSave;
+ PDC pdcSave;
+
+ ASSERT(iSaveLevel > 0);
+ DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel);
+
+ /* Get current process */
+ pepCurrentProcess = PsGetCurrentProcess();
+
+ /* Loop the save levels */
+ while (pdc->dclevel.lSaveDepth > iSaveLevel)
+ {
+ hdcSave = pdc->dclevel.hdcSave;
+ DPRINT("RestoreDC = %p\n", hdcSave);
+
+ /* Set us as the owner */
+ if (!GDIOBJ_SetOwnership(hdcSave, pepCurrentProcess))
+ {
+ /* Could not get ownership. That's bad! */
+ DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n",
+ hdcSave, pdc->BaseObject.hHmgr);
+ return;// FALSE;
+ }
+
+ /* Lock the saved dc */
+ pdcSave = DC_LockDc(hdcSave);
+ if (!pdcSave)
+ {
+ /* WTF? Internal error! */
+ DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
+ hdcSave, pdc->BaseObject.hHmgr);
+ return;// FALSE;
+ }
+
+ /* Remove the saved dc from the queue */
+ pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave;
+
+ /* Decrement save level */
+ pdc->dclevel.lSaveDepth--;
+
+ /* Is this the state we want? */
+ if (pdc->dclevel.lSaveDepth == iSaveLevel)
+ {
+ /* Copy the state back */
+ DC_vCopyState(pdcSave, pdc, FALSE);
+
+ /* Only memory DC's change their surface */
+ if (pdc->dctype == DCTYPE_MEMORY)
+ DC_vSelectSurface(pdc, pdcSave->dclevel.pSurface);
+
+ // Restore Path by removing it, if the Save flag is set.
+ // BeginPath will takecare of the rest.
+ if (pdc->dclevel.hPath && pdc->dclevel.flPath & DCPATH_SAVE)
+ {
+ PATH_Delete(pdc->dclevel.hPath);
+ pdc->dclevel.hPath = 0;
+ pdc->dclevel.flPath &= ~DCPATH_SAVE;
+ }
+ }
+
+ /* Prevent save dc from being restored */
+ pdcSave->dclevel.lSaveDepth = 1;
+
+ /* Unlock it */
+ DC_UnlockDc(pdcSave);
+ /* Delete the saved dc */
+ GreDeleteObject(hdcSave);
+ }
+
+ DPRINT("Leave DC_vRestoreDC()\n");
+}
+
+
+
BOOL
APIENTRY
NtGdiRestoreDC(
HDC hdc,
INT iSaveLevel)
{
- PDC pdc, pdcSave;
- HDC hdcSave;
+ PDC pdc;
- DPRINT("NtGdiRestoreDC(%lx, %d)\n", hdc, iSaveLevel);
+ DPRINT("NtGdiRestoreDC(%p, %d)\n", hdc, iSaveLevel);
/* Lock the original DC */
pdc = DC_LockDc(hdc);
@@ -126,67 +210,12 @@ NtGdiRestoreDC(
return FALSE;
}
- /* Loop the save levels */
- while (pdc->dclevel.lSaveDepth > iSaveLevel)
- {
- hdcSave = pdc->dclevel.hdcSave;
-
- /* Set us as the owner */
- if (!IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_POWNED, FALSE ))
- {
- /* Could not get ownership. That's bad! */
- DPRINT1("Could not get ownership of saved DC (%p) for dc %p!\n",
- hdcSave, hdc);
- return FALSE;
- }
-
- /* Lock the saved dc */
- pdcSave = DC_LockDc(hdcSave);
- if (!pdcSave)
- {
- /* WTF? Internal error! */
- DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
- hdcSave, hdc);
- DC_UnlockDc(pdc);
- return FALSE;
- }
-
- /* Remove the saved dc from the queue */
- pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave;
-
- /* Decrement save level */
- pdc->dclevel.lSaveDepth--;
-
- /* Is this the state we want? */
- if (pdc->dclevel.lSaveDepth == iSaveLevel)
- {
- /* Copy the state back */
- DC_vCopyState(pdcSave, pdc, FALSE);
-
- // Restore Path by removing it, if the Save flag is set.
- // BeginPath will takecare of the rest.
- if (pdc->dclevel.hPath && pdc->dclevel.flPath & DCPATH_SAVE)
- {
- PATH_Delete(pdc->dclevel.hPath);
- pdc->dclevel.hPath = 0;
- pdc->dclevel.flPath &= ~DCPATH_SAVE;
- }
- // Attempt to plug the leak!
- if (pdcSave->rosdc.hClipRgn)
- {
- DPRINT("Have hClipRgn!\n");
- REGION_FreeRgnByHandle(pdcSave->rosdc.hClipRgn);
- }
- // FIXME! Handle prgnMeta!
- }
-
- /* Delete the saved dc */
- GreDeleteObject(hdcSave);
- }
+ /* Call the internal function */
+ DC_vRestoreDC(pdc, iSaveLevel);
DC_UnlockDc(pdc);
- DPRINT("Leaving NtGdiRestoreDC\n");
+ DPRINT("Leave NtGdiRestoreDC\n");
return TRUE;
}
@@ -200,7 +229,7 @@ NtGdiSaveDC(
PDC pdc, pdcSave;
INT lSaveDepth;
- DPRINT("NtGdiSaveDC(%lx)\n", hDC);
+ DPRINT("NtGdiSaveDC(%p)\n", hDC);
/* Lock the original dc */
pdc = DC_LockDc(hDC);
@@ -212,7 +241,7 @@ NtGdiSaveDC(
}
/* Allocate a new dc */
- pdcSave = DC_AllocDC(NULL);
+ pdcSave = DC_AllocDcWithHandle();
if (pdcSave == NULL)
{
DPRINT("Could not allocate a new DC\n");
@@ -221,12 +250,25 @@ NtGdiSaveDC(
}
hdcSave = pdcSave->BaseObject.hHmgr;
- /* Copy the current state */
- DC_vCopyState(pdc, pdcSave, TRUE);
+ InterlockedIncrement(&pdc->ppdev->cPdevRefs);
+ DC_vInitDc(pdcSave, DCTYPE_MEMORY, pdc->ppdev);
+
+ /* Handle references here correctly */
+// pdcSrc->dclevel.pSurface = NULL;
+// pdcSrc->dclevel.pbrFill = NULL;
+// pdcSrc->dclevel.pbrLine = NULL;
+// pdcSrc->dclevel.ppal = NULL;
/* Make it a kernel handle
(FIXME: windows handles this different, see wiki)*/
- IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_NONE, FALSE);
+ GDIOBJ_SetOwnership(hdcSave, NULL);
+
+ /* Copy the current state */
+ DC_vCopyState(pdc, pdcSave, TRUE);
+
+ /* Only memory DC's change their surface */
+ if (pdc->dctype == DCTYPE_MEMORY)
+ DC_vSelectSurface(pdcSave, pdc->dclevel.pSurface);
/* Copy path. FIXME: why this way? */
pdcSave->dclevel.hPath = pdc->dclevel.hPath;
@@ -243,7 +285,7 @@ NtGdiSaveDC(
DC_UnlockDc(pdcSave);
DC_UnlockDc(pdc);
- DPRINT("Leave NtGdiSaveDC: %ld\n", lSaveDepth);
+ DPRINT("Leave NtGdiSaveDC: %ld, hdcSave = %p\n", lSaveDepth, hdcSave);
return lSaveDepth;
}
diff --git a/subsystems/win32/win32k/objects/dcutil.c b/subsystems/win32/win32k/objects/dcutil.c
index f856ea19bda..0471c7dc9d2 100644
--- a/subsystems/win32/win32k/objects/dcutil.c
+++ b/subsystems/win32/win32k/objects/dcutil.c
@@ -145,7 +145,7 @@ IntSetDefaultRegion(PDC pdc)
if (pdc->ppdev->flFlags & PDEV_META_DEVICE)
{
pSurface = pdc->dclevel.pSurface;
- if (pSurface && pSurface->flFlags & PDEV_SURFACE)
+ if (pSurface && pSurface->flags & PDEV_SURFACE)
{
rclClip.left += pdc->ppdev->ptlOrigion.x;
rclClip.top += pdc->ppdev->ptlOrigion.y;
diff --git a/subsystems/win32/win32k/objects/device.c b/subsystems/win32/win32k/objects/device.c
index b6fb6a24708..c9b930331fa 100644
--- a/subsystems/win32/win32k/objects/device.c
+++ b/subsystems/win32/win32k/objects/device.c
@@ -11,584 +11,27 @@
#define NDEBUG
#include
-// TODO: proper implementation of LDEVOBJ and PDEVOBJ interface
-
-/*static*/ PDEVOBJ PrimarySurface;
-PPDEVOBJ pPrimarySurface = &PrimarySurface;
-static KEVENT VideoDriverNeedsPreparation;
-static KEVENT VideoDriverPrepared;
PDC defaultDCstate = NULL;
-PSIZEL
-FASTCALL
-PDEV_sizl(PPDEVOBJ ppdev, PSIZEL psizl)
+VOID FASTCALL
+IntGdiReferencePdev(PPDEVOBJ ppdev)
{
- if (ppdev->flFlags & PDEV_META_DEVICE)
- {
- psizl->cx = ppdev->ulHorzRes;
- psizl->cy = ppdev->ulVertRes;
- }
- else
- {
- psizl->cx = ppdev->gdiinfo.ulHorzRes;
- psizl->cy = ppdev->gdiinfo.ulVertRes;
- }
- return psizl;
+ UNIMPLEMENTED;
}
-NTSTATUS FASTCALL
-InitDcImpl(VOID)
+VOID FASTCALL
+IntGdiUnreferencePdev(PPDEVOBJ ppdev, DWORD CleanUpType)
{
- KeInitializeEvent(&VideoDriverNeedsPreparation, SynchronizationEvent, TRUE);
- KeInitializeEvent(&VideoDriverPrepared, NotificationEvent, FALSE);
- return STATUS_SUCCESS;
-}
-
-
-static BOOLEAN FASTCALL
-GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- WCHAR DeviceNameBuffer[20];
- NTSTATUS Status;
-
- swprintf(DeviceNameBuffer, L"\\Device\\Video%lu", DisplayNumber);
- RtlInitUnicodeString(RegistryPath, NULL);
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].Name = DeviceNameBuffer;
- QueryTable[0].EntryContext = RegistryPath;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
- L"VIDEO",
- QueryTable,
- NULL,
- NULL);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("No \\Device\\Video%lu value in DEVICEMAP\\VIDEO found\n", DisplayNumber);
- return FALSE;
- }
-
- DPRINT("RegistryPath %wZ\n", RegistryPath);
-
- return TRUE;
-}
-
-
-NTSTATUS
-NTAPI
-EnumDisplayQueryRoutine(IN PWSTR ValueName,
- IN ULONG ValueType,
- IN PVOID ValueData,
- IN ULONG ValueLength,
- IN PVOID Context,
- IN PVOID EntryContext)
-{
- if ((Context == NULL) && ((ValueType == REG_SZ) || (ValueType == REG_MULTI_SZ)))
- {
- *(PULONG)EntryContext = ValueLength;
- }
- else
- {
- DPRINT1("Value data: %S %d\n", ValueData, ValueLength);
- RtlCopyMemory(Context, ValueData, ValueLength);
- }
-
- return STATUS_SUCCESS;
-}
-
-static BOOL FASTCALL
-FindDriverFileNames(PUNICODE_STRING DriverFileNames, ULONG DisplayNumber)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- UNICODE_STRING RegistryPath;
- NTSTATUS Status;
- PWCHAR DriverNames = NULL;
- ULONG Length = 0;
-
- if (! GetRegistryPath(&RegistryPath, DisplayNumber))
- {
- DPRINT("GetRegistryPath failed\n");
- return FALSE;
- }
-
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND;
- QueryTable[0].Name = L"InstalledDisplayDrivers";
- QueryTable[0].EntryContext = &Length;
- QueryTable[0].QueryRoutine = EnumDisplayQueryRoutine;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- RegistryPath.Buffer,
- QueryTable,
- NULL,
- NULL);
- // DPRINT1("Status: %lx\n", Status);
- if (Length)
- {
- DriverNames = ExAllocatePoolWithTag(PagedPool, Length, TAG_DRIVER);
- // DPRINT1("Length allocated: %d\n", Length);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- RegistryPath.Buffer,
- QueryTable,
- DriverNames,
- NULL);
- if (!NT_SUCCESS(Status)) DriverNames = NULL;
- }
-
- ExFreePoolWithTag(RegistryPath.Buffer, TAG_RTLREGISTRY);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("No InstalledDisplayDrivers value in service entry found\n");
- return FALSE;
- }
-
- RtlInitUnicodeString(DriverFileNames, DriverNames);
- DriverFileNames->Length = Length;
- DriverFileNames->MaximumLength = Length;
- //DPRINT1("DriverFileNames %wZ\n", DriverFileNames);
-
- return TRUE;
-}
-
-
-static NTSTATUS APIENTRY
-DevModeCallback(IN PWSTR ValueName,
- IN ULONG ValueType,
- IN PVOID ValueData,
- IN ULONG ValueLength,
- IN PVOID Context,
- IN PVOID EntryContext)
-{
- PDEVMODEW DevMode = (PDEVMODEW) Context;
-
- DPRINT("Found registry value for name %S: type %d, length %d\n",
- ValueName, ValueType, ValueLength);
-
- if (REG_DWORD == ValueType && sizeof(DWORD) == ValueLength)
- {
- if (0 == _wcsicmp(ValueName, L"DefaultSettings.BitsPerPel"))
- {
- DevMode->dmBitsPerPel = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.Flags"))
- {
- DevMode->dmDisplayFlags = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.VRefresh"))
- {
- DevMode->dmDisplayFrequency = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XPanning"))
- {
- DevMode->dmPanningWidth = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XResolution"))
- {
- DevMode->dmPelsWidth = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YPanning"))
- {
- DevMode->dmPanningHeight = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YResolution"))
- {
- DevMode->dmPelsHeight = *((DWORD *) ValueData);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static BOOL FASTCALL
-SetupDevMode(PDEVMODEW DevMode, ULONG DisplayNumber)
-{
- UNICODE_STRING RegistryPath;
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- NTSTATUS Status;
- BOOLEAN Valid = TRUE;
-
- if (!GetRegistryPath(&RegistryPath, DisplayNumber))
- {
- DPRINT("GetRegistryPath failed\n");
- return FALSE;
- }
-
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
- QueryTable[0].QueryRoutine = DevModeCallback;
- QueryTable[0].Flags = 0;
- QueryTable[0].Name = NULL;
- QueryTable[0].EntryContext = NULL;
- QueryTable[0].DefaultType = REG_NONE;
- QueryTable[0].DefaultData = NULL;
- QueryTable[0].DefaultLength = 0;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- RegistryPath.Buffer,
- QueryTable,
- DevMode,
- NULL);
- if (! NT_SUCCESS(Status))
- {
- DPRINT("RtlQueryRegistryValues for %wZ failed with status 0x%08x\n",
- &RegistryPath, Status);
- Valid = FALSE;
- }
- else
- {
- DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n",
- DevMode->dmBitsPerPel, DevMode->dmDisplayFrequency,
- DevMode->dmPelsWidth, DevMode->dmPelsHeight);
- if (0 == DevMode->dmBitsPerPel || 0 == DevMode->dmDisplayFrequency
- || 0 == DevMode->dmPelsWidth || 0 == DevMode->dmPelsHeight)
- {
- DPRINT("Not all required devmode members are set\n");
- Valid = FALSE;
- }
- }
-
- ExFreePoolWithTag(RegistryPath.Buffer, TAG_RTLREGISTRY);
-
- if (! Valid)
- {
- RtlZeroMemory(DevMode, sizeof(DEVMODEW));
- }
-
- return Valid;
-}
-
-static BOOL FASTCALL
-IntPrepareDriver(VOID)
-{
- PFN_DrvEnableDriver GDEnableDriver;
- DRVENABLEDATA DED;
- UNICODE_STRING DriverFileNames;
- PWSTR CurrentName;
- BOOL GotDriver;
- BOOL DoDefault;
- ULONG DisplayNumber;
- LARGE_INTEGER Zero;
- BOOLEAN ret = FALSE;
-
- Zero.QuadPart = 0;
- if (STATUS_SUCCESS != KeWaitForSingleObject(&VideoDriverNeedsPreparation, Executive, KernelMode, TRUE, &Zero))
- {
- /* Concurrent access. Wait for VideoDriverPrepared event */
- if (STATUS_SUCCESS == KeWaitForSingleObject(&VideoDriverPrepared, Executive, KernelMode, TRUE, NULL))
- ret = PrimarySurface.PreparedDriver;
- goto cleanup;
- }
- // HAX! Fixme so I can support more than one! So how many?
- for (DisplayNumber = 0; ; DisplayNumber++)
- {
- DPRINT("Trying to load display driver no. %d\n", DisplayNumber);
-
- RtlZeroMemory(&PrimarySurface, sizeof(PrimarySurface));
-
-// if (!pPrimarySurface) pPrimarySurface = ExAllocatePoolWithTag(PagedPool, gdwDirectDrawContext + sizeof(PDEVOBJ), TAG_GDIPDEV);
-
- PrimarySurface.VideoFileObject = DRIVER_FindMPDriver(DisplayNumber);
-
- /* Open the miniport driver */
- if (PrimarySurface.VideoFileObject == NULL)
- {
- DPRINT1("FindMPDriver failed\n");
- goto cleanup;
- }
-
- /* Retrieve DDI driver names from registry */
- RtlInitUnicodeString(&DriverFileNames, NULL);
- if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
- {
- DPRINT1("FindDriverFileNames failed\n");
- continue;
- }
-
- /*
- * DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
- * scan all of them until a good one found.
- */
- CurrentName = DriverFileNames.Buffer;
- GotDriver = FALSE;
- while (!GotDriver &&
- CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
- {
- /* Get the DDI driver's entry point */
- GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
- if (NULL == GDEnableDriver)
- {
- DPRINT("FindDDIDriver failed for %S\n", CurrentName);
- }
- else
- {
- /* Call DDI driver's EnableDriver function */
- RtlZeroMemory(&DED, sizeof(DED));
-
- if (! GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof(DED), &DED))
- {
- DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
- }
- else
- {
- GotDriver = TRUE;
- }
- }
-
- if (! GotDriver)
- {
- /* Skip to the next name but never get past the Unicode string */
- while (L'\0' != *CurrentName &&
- CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
- {
- CurrentName++;
- }
- if (CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
- {
- CurrentName++;
- }
- }
- }
-
- if (!GotDriver)
- {
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY);
- DPRINT1("No suitable DDI driver found\n");
- continue;
- }
-
- DPRINT1("Display driver %S loaded\n", CurrentName);
-
- ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY);
-
- DPRINT("Building DDI Functions\n");
-
- /* Construct DDI driver function dispatch table */
- if (!DRIVER_BuildDDIFunctions(&DED, &PrimarySurface.DriverFunctions))
- {
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("BuildDDIFunctions failed\n");
- goto cleanup;
- }
-
- /* Allocate a phyical device handle from the driver */
- // Support DMW.dmSize + DMW.dmDriverExtra & Alloc DMW then set prt pdmwDev.
- PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
- if (SetupDevMode(&PrimarySurface.DMW, DisplayNumber))
- {
- PrimarySurface.dhpdev = PrimarySurface.DriverFunctions.EnablePDEV(
- &PrimarySurface.DMW,
- L"",
- HS_DDI_MAX,
- PrimarySurface.ahsurf,
- sizeof(PrimarySurface.gdiinfo),
- &PrimarySurface.gdiinfo,
- sizeof(PrimarySurface.devinfo),
- &PrimarySurface.devinfo,
- NULL,
- L"",
- (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
- DoDefault = (NULL == PrimarySurface.dhpdev);
- if (DoDefault)
- {
- DPRINT1("DrvEnablePDev with registry parameters failed\n");
- }
- }
- else
- {
- DoDefault = TRUE;
- }
-
- if (DoDefault)
- {
- RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
- PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
- PrimarySurface.dhpdev = PrimarySurface.DriverFunctions.EnablePDEV(
- &PrimarySurface.DMW,
- L"",
- HS_DDI_MAX,
- PrimarySurface.ahsurf,
- sizeof(PrimarySurface.gdiinfo),
- &PrimarySurface.gdiinfo,
- sizeof(PrimarySurface.devinfo),
- &PrimarySurface.devinfo,
- NULL,
- L"",
- (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
-
- if (NULL == PrimarySurface.dhpdev)
- {
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("DrvEnablePDEV with default parameters failed\n");
- DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
- continue;
- }
-
- // Update the primary surface with what we really got
- PrimarySurface.DMW.dmPelsWidth = PrimarySurface.gdiinfo.ulHorzRes;
- PrimarySurface.DMW.dmPelsHeight = PrimarySurface.gdiinfo.ulVertRes;
- PrimarySurface.DMW.dmBitsPerPel = PrimarySurface.gdiinfo.cBitsPixel;
- PrimarySurface.DMW.dmDisplayFrequency = PrimarySurface.gdiinfo.ulVRefresh;
- }
-
- if (!PrimarySurface.DMW.dmDriverExtra)
- {
- PrimarySurface.pdmwDev = &PrimarySurface.DMW; // HAX!
- }
- else
- {
- DPRINT1("WARNING!!! Need to Alloc DMW !!!!!!\n");
- }
- // Dont remove until we finish testing other drivers.
- if (PrimarySurface.DMW.dmDriverExtra != 0)
- {
- DPRINT1("**** DMW extra = %u bytes. Please report to ros-dev@reactos.org ****\n", PrimarySurface.DMW.dmDriverExtra);
- }
-
- if (0 == PrimarySurface.gdiinfo.ulLogPixelsX)
- {
- DPRINT("Adjusting gdiinfo.ulLogPixelsX\n");
- PrimarySurface.gdiinfo.ulLogPixelsX = 96;
- }
- if (0 == PrimarySurface.gdiinfo.ulLogPixelsY)
- {
- DPRINT("Adjusting gdiinfo.ulLogPixelsY\n");
- PrimarySurface.gdiinfo.ulLogPixelsY = 96;
- }
-
- PrimarySurface.Pointer.Exclude.right = -1;
-
- DPRINT("calling completePDev\n");
-
- /* Complete initialization of the physical device */
- PrimarySurface.DriverFunctions.CompletePDEV(
- PrimarySurface.dhpdev,
- (HDEV)&PrimarySurface);
-
- DPRINT("calling DRIVER_ReferenceDriver\n");
-
- DRIVER_ReferenceDriver(L"DISPLAY");
-
- PrimarySurface.PreparedDriver = TRUE;
- PrimarySurface.DisplayNumber = DisplayNumber;
- PrimarySurface.flFlags = PDEV_DISPLAY; // Hard set,, add more flags.
- PrimarySurface.hsemDevLock = (PERESOURCE)EngCreateSemaphore();
- // Should be null,, but make sure for now.
- PrimarySurface.pvGammaRamp = NULL;
- PrimarySurface.ppdevNext = NULL; // Fixme! We need to support more than display drvs.
- PrimarySurface.ppdevParent = NULL; // Always NULL if primary.
- PrimarySurface.pGraphicsDevice = NULL; // Fixme!
- PrimarySurface.pEDDgpl = ExAllocatePoolWithTag(PagedPool, sizeof(EDD_DIRECTDRAW_GLOBAL), TAG_EDDGBL);
- if (PrimarySurface.pEDDgpl)
- {
- RtlZeroMemory( PrimarySurface.pEDDgpl ,sizeof(EDD_DIRECTDRAW_GLOBAL));
- ret = TRUE;
- }
- goto cleanup;
- }
-
-cleanup:
- KeSetEvent(&VideoDriverPrepared, 1, FALSE);
- return ret;
+ UNIMPLEMENTED;
}
BOOL FASTCALL
-IntPrepareDriverIfNeeded(VOID)
-{
- return (PrimarySurface.PreparedDriver ? TRUE : IntPrepareDriver());
-}
-
-static BOOL FASTCALL
-PrepareVideoPrt(VOID)
-{
- PIRP Irp;
- NTSTATUS Status;
- IO_STATUS_BLOCK Iosb;
- BOOL Prepare = TRUE;
- ULONG Length = sizeof(BOOL);
- PIO_STACK_LOCATION StackPtr;
- LARGE_INTEGER StartOffset;
- PFILE_OBJECT FileObject = PrimarySurface.VideoFileObject;
- PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject;
-
- DPRINT("PrepareVideoPrt() called\n");
-
- KeClearEvent(&PrimarySurface.VideoFileObject->Event);
-
- ObReferenceObjectByPointer(FileObject, 0, IoFileObjectType, KernelMode);
-
- StartOffset.QuadPart = 0;
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
- DeviceObject,
- (PVOID) &Prepare,
- Length,
- &StartOffset,
- NULL,
- &Iosb);
- if (NULL == Irp)
- {
- return FALSE;
- }
-
- /* Set up IRP Data */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = KernelMode;
- Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
- Irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
- Irp->Flags |= IRP_WRITE_OPERATION;
-
- /* Setup Stack Data */
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = PrimarySurface.VideoFileObject;
- StackPtr->Parameters.Write.Key = 0;
-
- Status = IoCallDriver(DeviceObject, Irp);
-
- if (STATUS_PENDING == Status)
- {
- KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, TRUE, 0);
- Status = Iosb.Status;
- }
-
- return NT_SUCCESS(Status);
-}
-
-
-BOOL FASTCALL
-IntCreatePrimarySurface(VOID)
+IntCreatePrimarySurface()
{
SIZEL SurfSize;
- RECTL SurfaceRect;
- SURFOBJ *SurfObj;
+ SURFOBJ *pso;
BOOL calledFromUser;
- if (! IntPrepareDriverIfNeeded())
- {
- return FALSE;
- }
-
- if (! PrepareVideoPrt())
- {
- return FALSE;
- }
-
- DPRINT("calling EnableSurface\n");
- /* Enable the drawing surface */
- PrimarySurface.pSurface =
- PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.dhpdev);
- if (NULL == PrimarySurface.pSurface)
- {
- /* PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, FALSE);*/
- PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.dhpdev);
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("DrvEnableSurface failed\n");
- return FALSE;
- }
-
- PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, TRUE);
-
calledFromUser = UserIsEntered(); //fixme: possibly upgrade a shared lock
if (!calledFromUser)
{
@@ -596,31 +39,23 @@ IntCreatePrimarySurface(VOID)
}
/* attach monitor */
- IntAttachMonitor(&PrimarySurface, PrimarySurface.DisplayNumber);
+ IntAttachMonitor(gppdevPrimary, 0);
- SurfObj = EngLockSurface(PrimarySurface.pSurface);
- SurfObj->dhpdev = PrimarySurface.dhpdev;
- SurfSize = SurfObj->sizlBitmap;
- SurfaceRect.left = SurfaceRect.top = 0;
- SurfaceRect.right = SurfObj->sizlBitmap.cx;
- SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
- /* FIXME - why does EngEraseSurface() sometimes crash?
- EngEraseSurface(SurfObj, &SurfaceRect, 0); */
+ DPRINT1("IntCreatePrimarySurface, pPrimarySurface=%p, pPrimarySurface->pSurface = %p\n",
+ pPrimarySurface, pPrimarySurface->pSurface);
+
+ /* Create surface */
+ pso = &PDEVOBJ_pSurface(pPrimarySurface)->SurfObj;
+ SurfSize = pso->sizlBitmap;
/* Put the pointer in the center of the screen */
- gpsi->ptCursor.x = (SurfaceRect.right - SurfaceRect.left) / 2;
- gpsi->ptCursor.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
+ gpsi->ptCursor.x = pso->sizlBitmap.cx / 2;
+ gpsi->ptCursor.y = pso->sizlBitmap.cy / 2;
- /* Give the PDEV a MovePointer function */
- PrimarySurface.pfnMovePointer = PrimarySurface.DriverFunctions.MovePointer;
- if (!PrimarySurface.pfnMovePointer)
- PrimarySurface.pfnMovePointer = EngMovePointer;
-
- EngUnlockSurface(SurfObj);
co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
// Init Primary Displays Device Capabilities.
- IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps);
+ PDEVOBJ_vGetDeviceCaps(pPrimarySurface, &GdiHandleTable->DevCaps);
if (!calledFromUser)
{
@@ -631,1139 +66,20 @@ IntCreatePrimarySurface(VOID)
}
VOID FASTCALL
-IntDestroyPrimarySurface(VOID)
+IntDestroyPrimarySurface()
{
- BOOL calledFromUser;
-
- DRIVER_UnreferenceDriver(L"DISPLAY");
-
- calledFromUser = UserIsEntered();
- if (!calledFromUser)
- {
- UserEnterExclusive();
- }
-
- /* detach monitor */
- IntDetachMonitor(&PrimarySurface);
-
- if (!calledFromUser)
- {
- UserLeave();
- }
-
- /*
- * FIXME: Hide a mouse pointer there. Also because we have to prevent
- * memory leaks with the Eng* mouse routines.
- */
-
- DPRINT("Reseting display\n" );
- PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, FALSE);
- PrimarySurface.DriverFunctions.DisableSurface(PrimarySurface.dhpdev);
- PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.dhpdev);
- PrimarySurface.PreparedDriver = FALSE;
- KeSetEvent(&VideoDriverNeedsPreparation, 1, FALSE);
- KeResetEvent(&VideoDriverPrepared);
-
- DceEmptyCache();
-
- ObDereferenceObject(PrimarySurface.VideoFileObject);
+ UNIMPLEMENTED;
}
-INT
-FASTCALL
-IntcFonts(PPDEVOBJ pDevObj)
-{
- ULONG_PTR Junk;
-// Msdn DrvQueryFont:
-// If the number of fonts in DEVINFO is -1 and iFace is zero, the driver
-// should return the number of fonts it supports.
- if ( pDevObj->devinfo.cFonts == -1)
- {
- if (pDevObj->DriverFunctions.QueryFont)
- pDevObj->devinfo.cFonts =
- (ULONG)pDevObj->DriverFunctions.QueryFont(pDevObj->dhpdev, 0, 0, &Junk);
- else
- pDevObj->devinfo.cFonts = 0;
- }
- return pDevObj->devinfo.cFonts;
-}
-
-//
-// Support multi display/device locks.
-//
-VOID
-FASTCALL
-DC_LockDisplay(HDC hDC)
-{
- PERESOURCE Resource;
- PDC dc = DC_LockDc(hDC);
- if (!dc) return;
- Resource = dc->ppdev->hsemDevLock;
- DC_UnlockDc(dc);
- if (!Resource) return;
- KeEnterCriticalRegion();
- ExAcquireResourceExclusiveLite( Resource , TRUE);
-}
-
-VOID
-FASTCALL
-DC_UnlockDisplay(HDC hDC)
-{
- PERESOURCE Resource;
- PDC dc = DC_LockDc(hDC);
- if (!dc) return;
- Resource = dc->ppdev->hsemDevLock;
- DC_UnlockDc(dc);
- if (!Resource) return;
- ExReleaseResourceLite( Resource );
- KeLeaveCriticalRegion();
-}
-
-//
-// Enumerate HDev
-//
PPDEVOBJ FASTCALL
IntEnumHDev(VOID)
{
// I guess we will soon have more than one primary surface.
// This will do for now.
- return &PrimarySurface;
+ return pPrimarySurface;
}
-VOID FASTCALL
-IntGdiReferencePdev(PPDEVOBJ ppdev)
-{
- if (!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore(); // Hax, should be in dllmain.c
- IntGdiAcquireSemaphore(hsemDriverMgmt);
- ppdev->cPdevRefs++;
- IntGdiReleaseSemaphore(hsemDriverMgmt);
-}
-
-VOID FASTCALL
-IntGdiUnreferencePdev(PPDEVOBJ ppdev, DWORD CleanUpType)
-{
- IntGdiAcquireSemaphore(hsemDriverMgmt);
- ppdev->cPdevRefs--;
- if (!ppdev->cPdevRefs)
- {
- // Handle the destruction of ppdev or PDEVOBJ or PDEVOBJ or PDEV etc.
- }
- IntGdiReleaseSemaphore(hsemDriverMgmt);
-}
-
-
-
-INT
-FASTCALL
-IntGetColorManagementCaps(PPDEVOBJ pDevObj)
-{
- INT ret = CM_NONE;
-
- if ( pDevObj->flFlags & PDEV_DISPLAY)
- {
- if (pDevObj->devinfo.iDitherFormat == BMF_8BPP ||
- pDevObj->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP)
- ret = CM_GAMMA_RAMP;
- }
- if (pDevObj->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR)
- ret |= CM_CMYK_COLOR;
- if (pDevObj->devinfo.flGraphicsCaps & GCAPS_ICM)
- ret |= CM_DEVICE_ICM;
- return ret;
-}
-
-INT FASTCALL
-IntGdiGetDeviceCaps(PDC dc, INT Index)
-{
- INT ret = 0;
- PPDEVOBJ ppdev = dc->ppdev;
- /* Retrieve capability */
- switch (Index)
- {
- case DRIVERVERSION:
- ret = ppdev->gdiinfo.ulVersion;
- break;
-
- case TECHNOLOGY:
- ret = ppdev->gdiinfo.ulTechnology;
- break;
-
- case HORZSIZE:
- ret = ppdev->gdiinfo.ulHorzSize;
- break;
-
- case VERTSIZE:
- ret = ppdev->gdiinfo.ulVertSize;
- break;
-
- case HORZRES:
- ret = ppdev->gdiinfo.ulHorzRes;
- break;
-
- case VERTRES:
- ret = ppdev->gdiinfo.ulVertRes;
- break;
-
- case LOGPIXELSX:
- ret = ppdev->gdiinfo.ulLogPixelsX;
- break;
-
- case LOGPIXELSY:
- ret = ppdev->gdiinfo.ulLogPixelsY;
- break;
-
- case CAPS1:
- if ( ppdev->pGraphicsDevice &&
- (((PGRAPHICS_DEVICE)ppdev->pGraphicsDevice)->StateFlags &
- DISPLAY_DEVICE_MIRRORING_DRIVER))
- ret = C1_MIRRORING;
- break;
-
- case BITSPIXEL:
- ret = ppdev->gdiinfo.cBitsPixel;
- break;
-
- case PLANES:
- ret = ppdev->gdiinfo.cPlanes;
- break;
-
- case NUMBRUSHES:
- ret = -1;
- break;
-
- case NUMPENS:
- ret = ppdev->gdiinfo.ulNumColors;
- if ( ret != -1 ) ret *= 5;
- break;
-
- case NUMFONTS:
- ret = IntcFonts(ppdev);
- break;
-
- case NUMCOLORS:
- ret = ppdev->gdiinfo.ulNumColors;
- break;
-
- case ASPECTX:
- ret = ppdev->gdiinfo.ulAspectX;
- break;
-
- case ASPECTY:
- ret = ppdev->gdiinfo.ulAspectY;
- break;
-
- case ASPECTXY:
- ret = ppdev->gdiinfo.ulAspectXY;
- break;
-
- case CLIPCAPS:
- ret = CP_RECTANGLE;
- break;
-
- case SIZEPALETTE:
- ret = ppdev->gdiinfo.ulNumPalReg;
- break;
-
- case NUMRESERVED:
- ret = 20;
- break;
-
- case COLORRES:
- ret = ppdev->gdiinfo.ulDACRed +
- ppdev->gdiinfo.ulDACGreen +
- ppdev->gdiinfo.ulDACBlue;
- break;
-
- case DESKTOPVERTRES:
- ret = ppdev->gdiinfo.ulVertRes;
- break;
-
- case DESKTOPHORZRES:
- ret = ppdev->gdiinfo.ulHorzRes;
- break;
-
- case BLTALIGNMENT:
- ret = ppdev->gdiinfo.ulBltAlignment;
- break;
-
- case SHADEBLENDCAPS:
- ret = ppdev->gdiinfo.flShadeBlend;
- break;
-
- case COLORMGMTCAPS:
- ret = IntGetColorManagementCaps(ppdev);
- break;
-
- case PHYSICALWIDTH:
- ret = ppdev->gdiinfo.szlPhysSize.cx;
- break;
-
- case PHYSICALHEIGHT:
- ret = ppdev->gdiinfo.szlPhysSize.cy;
- break;
-
- case PHYSICALOFFSETX:
- ret = ppdev->gdiinfo.ptlPhysOffset.x;
- break;
-
- case PHYSICALOFFSETY:
- ret = ppdev->gdiinfo.ptlPhysOffset.y;
- break;
-
- case VREFRESH:
- ret = ppdev->gdiinfo.ulVRefresh;
- break;
-
- case RASTERCAPS:
- ret = ppdev->gdiinfo.flRaster;
- break;
-
- case CURVECAPS:
- ret = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
- CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
- break;
-
- case LINECAPS:
- ret = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
- LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
- break;
-
- case POLYGONALCAPS:
- ret = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
- PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
- break;
-
- case TEXTCAPS:
- ret = ppdev->gdiinfo.flTextCaps;
- if (ppdev->gdiinfo.ulTechnology) ret |= TC_VA_ABLE;
- ret |= (TC_SO_ABLE|TC_UA_ABLE);
- break;
-
- case PDEVICESIZE:
- case SCALINGFACTORX:
- case SCALINGFACTORY:
- default:
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-INT APIENTRY
-NtGdiGetDeviceCaps(HDC hDC,
- INT Index)
-{
- PDC dc;
- INT ret;
-
- dc = DC_LockDc(hDC);
- if (dc == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- ret = IntGdiGetDeviceCaps(dc, Index);
-
- DPRINT("(%04x,%d): returning %d\n", hDC, Index, ret);
-
- DC_UnlockDc( dc );
- return ret;
-}
-
-VOID
-FASTCALL
-IntvGetDeviceCaps(
- PPDEVOBJ pDevObj,
- PDEVCAPS pDevCaps)
-{
- ULONG Tmp = 0;
- PGDIINFO pGdiInfo = &pDevObj->gdiinfo;
-
- pDevCaps->ulVersion = pGdiInfo->ulVersion;
- pDevCaps->ulTechnology = pGdiInfo->ulTechnology;
- pDevCaps->ulHorzSizeM = (pGdiInfo->ulHorzSize + 500) / 1000;
- pDevCaps->ulVertSizeM = (pGdiInfo->ulVertSize + 500) / 1000;
- pDevCaps->ulHorzSize = pGdiInfo->ulHorzSize;
- pDevCaps->ulVertSize = pGdiInfo->ulVertSize;
- pDevCaps->ulHorzRes = pGdiInfo->ulHorzRes;
- pDevCaps->ulVertRes = pGdiInfo->ulVertRes;
- pDevCaps->ulVRefresh = pGdiInfo->ulVRefresh;
- pDevCaps->ulDesktopHorzRes = pGdiInfo->ulHorzRes;
- pDevCaps->ulDesktopVertRes = pGdiInfo->ulVertRes;
- pDevCaps->ulBltAlignment = pGdiInfo->ulBltAlignment;
- pDevCaps->ulPlanes = pGdiInfo->cPlanes;
-
- pDevCaps->ulBitsPixel = pGdiInfo->cBitsPixel;
- if (pGdiInfo->cBitsPixel == 15) pDevCaps->ulBitsPixel = 16;
-
- Tmp = pGdiInfo->ulNumColors;
- if ( Tmp != -1 ) Tmp *= 5;
- pDevCaps->ulNumPens = Tmp;
- pDevCaps->ulNumColors = pGdiInfo->ulNumColors;
-
- pDevCaps->ulNumFonts = IntcFonts(pDevObj);
-
- pDevCaps->ulRasterCaps = pGdiInfo->flRaster;
- pDevCaps->ulShadeBlend = pGdiInfo->flShadeBlend;
- pDevCaps->ulAspectX = pGdiInfo->ulAspectX;
- pDevCaps->ulAspectY = pGdiInfo->ulAspectY;
- pDevCaps->ulAspectXY = pGdiInfo->ulAspectXY;
- pDevCaps->ulLogPixelsX = pGdiInfo->ulLogPixelsX;
- pDevCaps->ulLogPixelsY = pGdiInfo->ulLogPixelsY;
- pDevCaps->ulSizePalette = pGdiInfo->ulNumPalReg;
- pDevCaps->ulColorRes = pGdiInfo->ulDACRed + pGdiInfo->ulDACGreen + pGdiInfo->ulDACBlue;
- pDevCaps->ulPhysicalWidth = pGdiInfo->szlPhysSize.cx;
- pDevCaps->ulPhysicalHeight = pGdiInfo->szlPhysSize.cy;
- pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x;
- pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y;
- pDevCaps->ulPanningHorzRes = pGdiInfo->ulPanningHorzRes;
- pDevCaps->ulPanningVertRes = pGdiInfo->ulPanningVertRes;
- pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment;
- pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment;
-
- Tmp = 0;
- Tmp = pGdiInfo->flTextCaps | (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
-
- pDevCaps->ulTextCaps = pGdiInfo->flTextCaps | (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
-
- if (pGdiInfo->ulTechnology)
- pDevCaps->ulTextCaps = Tmp | TC_VA_ABLE;
-
- pDevCaps->ulColorMgmtCaps = IntGetColorManagementCaps(pDevObj);
-
- return;
-}
-
-/*
-* @implemented
-*/
-BOOL
-APIENTRY
-NtGdiGetDeviceCapsAll (
- IN HDC hDC,
- OUT PDEVCAPS pDevCaps)
-{
- PDC dc;
- PDEVCAPS pSafeDevCaps;
- NTSTATUS Status = STATUS_SUCCESS;
-
- dc = DC_LockDc(hDC);
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- pSafeDevCaps = ExAllocatePoolWithTag(PagedPool, sizeof(DEVCAPS), TAG_TEMP);
-
- if (!pSafeDevCaps)
- {
- DC_UnlockDc(dc);
- return FALSE;
- }
-
- IntvGetDeviceCaps(dc->ppdev, pSafeDevCaps);
-
- _SEH2_TRY
- {
- ProbeForWrite(pDevCaps,
- sizeof(DEVCAPS),
- 1);
- RtlCopyMemory(pDevCaps, pSafeDevCaps, sizeof(DEVCAPS));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
-
- ExFreePoolWithTag(pSafeDevCaps, TAG_TEMP);
- DC_UnlockDc(dc);
-
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- return FALSE;
- }
- return TRUE;
-}
-
-
-/*
- * @implemented
- */
-DHPDEV
-APIENTRY
-NtGdiGetDhpdev(
- IN HDEV hdev)
-{
- PPDEVOBJ ppdev, pGdiDevice = (PPDEVOBJ) hdev;
- if (!pGdiDevice) return NULL;
- if ( pGdiDevice < (PPDEVOBJ)MmSystemRangeStart) return NULL;
- ppdev = pPrimarySurface;
- IntGdiAcquireSemaphore(hsemDriverMgmt);
- do
- {
- if (pGdiDevice == ppdev) break;
- else
- ppdev = ppdev->ppdevNext;
- }
- while (ppdev != NULL);
- IntGdiReleaseSemaphore(hsemDriverMgmt);
- if (!ppdev) return NULL;
- return pGdiDevice->dhpdev;
-}
-
-static NTSTATUS FASTCALL
-GetVideoRegistryKey(
- OUT PUNICODE_STRING RegistryPath,
- IN PCUNICODE_STRING DeviceName) /* ex: "\Device\Video0" */
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- NTSTATUS Status;
-
- RtlInitUnicodeString(RegistryPath, NULL);
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].Name = DeviceName->Buffer;
- QueryTable[0].EntryContext = RegistryPath;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
- L"VIDEO",
- QueryTable,
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("No %wZ value in DEVICEMAP\\VIDEO found (Status 0x%08lx)\n", DeviceName, Status);
- return STATUS_NO_SUCH_DEVICE;
- }
-
- DPRINT("RegistryPath %wZ\n", RegistryPath);
- return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS FASTCALL
-GetVideoDeviceName(
- OUT PUNICODE_STRING VideoDeviceName,
- IN PCUNICODE_STRING DisplayDevice) /* ex: "\.\DISPLAY1" or "\??\DISPLAY1" */
-{
- UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\??\\");
- UNICODE_STRING ObjectName;
- UNICODE_STRING KernelModeName = { 0, };
- OBJECT_ATTRIBUTES ObjectAttributes;
- USHORT LastSlash;
- ULONG Length;
- HANDLE LinkHandle = NULL;
- NTSTATUS Status;
-
- RtlInitUnicodeString(VideoDeviceName, NULL);
-
- /* Get device name (DisplayDevice is "\.\xxx") */
- for (LastSlash = DisplayDevice->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
- {
- if (DisplayDevice->Buffer[LastSlash - 1] == L'\\')
- break;
- }
-
- if (LastSlash == 0)
- {
- DPRINT1("Invalid device name '%wZ'\n", DisplayDevice);
- Status = STATUS_OBJECT_NAME_INVALID;
- goto cleanup;
- }
- ObjectName = *DisplayDevice;
- ObjectName.Length -= LastSlash * sizeof(WCHAR);
- ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
- ObjectName.Buffer += LastSlash;
-
- /* Create "\??\xxx" (ex: "\??\DISPLAY1") */
- KernelModeName.MaximumLength = Prefix.Length + ObjectName.Length + sizeof(UNICODE_NULL);
- KernelModeName.Buffer = ExAllocatePoolWithTag(PagedPool,
- KernelModeName.MaximumLength,
- TAG_DC);
- if (!KernelModeName.Buffer)
- {
- Status = STATUS_NO_MEMORY;
- goto cleanup;
- }
- RtlCopyUnicodeString(&KernelModeName, &Prefix);
- Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
- if (!NT_SUCCESS(Status))
- goto cleanup;
-
- /* Open \??\xxx (ex: "\??\DISPLAY1") */
- InitializeObjectAttributes(&ObjectAttributes,
- &KernelModeName,
- OBJ_KERNEL_HANDLE,
- NULL,
- NULL);
- Status = ZwOpenSymbolicLinkObject(&LinkHandle,
- GENERIC_READ,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to open symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
- Status = STATUS_NO_SUCH_DEVICE;
- goto cleanup;
- }
-
- Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, &Length);
- if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
- {
- DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
- Status = STATUS_NO_SUCH_DEVICE;
- goto cleanup;
- }
- VideoDeviceName->MaximumLength = Length;
- VideoDeviceName->Buffer = ExAllocatePoolWithTag(PagedPool,
- VideoDeviceName->MaximumLength + sizeof(UNICODE_NULL),
- TAG_DC);
- if (!VideoDeviceName->Buffer)
- {
- Status = STATUS_NO_MEMORY;
- goto cleanup;
- }
- Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, NULL);
- VideoDeviceName->Buffer[VideoDeviceName->MaximumLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
- Status = STATUS_NO_SUCH_DEVICE;
- goto cleanup;
- }
- Status = STATUS_SUCCESS;
-
-cleanup:
- if (!NT_SUCCESS(Status) && VideoDeviceName->Buffer)
- ExFreePoolWithTag(VideoDeviceName->Buffer, TAG_DC);
- if (KernelModeName.Buffer)
- ExFreePoolWithTag(KernelModeName.Buffer, TAG_DC);
- if (LinkHandle)
- ZwClose(LinkHandle);
- return Status;
-}
-
-LONG
-FASTCALL
-IntChangeDisplaySettings(
- IN PUNICODE_STRING pDeviceName OPTIONAL,
- IN LPDEVMODEW DevMode,
- IN DWORD dwflags,
- IN PVOID lParam OPTIONAL)
-{
- BOOLEAN NoReset = FALSE;
- BOOLEAN Reset = FALSE;
- LONG Ret = DISP_CHANGE_SUCCESSFUL;
- NTSTATUS Status ;
-
- DPRINT1("display flags : %x\n",dwflags);
-
- if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
- {
- /* Check global, reset and noreset flags */
- if ((dwflags & CDS_GLOBAL) == CDS_GLOBAL)
- DPRINT1("CDS_GLOBAL unhandled");
- if ((dwflags & CDS_NORESET) == CDS_NORESET)
- NoReset = TRUE;
- dwflags &= ~(CDS_GLOBAL | CDS_NORESET);
- }
- if ((dwflags & CDS_RESET) == CDS_RESET)
- Reset = TRUE;
- if ((dwflags & CDS_SET_PRIMARY) == CDS_SET_PRIMARY)
- DPRINT1("CDS_SET_PRIMARY unhandled");
- dwflags &= ~(CDS_RESET | CDS_SET_PRIMARY);
-
- if (Reset && NoReset)
- return DISP_CHANGE_BADFLAGS;
-
- if (dwflags == 0)
- {
- /* Dynamically change graphics mode */
- DPRINT1("flag 0 UNIMPLEMENTED\n");
- SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED);
- return DISP_CHANGE_FAILED;
- }
-
- if ((dwflags & CDS_TEST) == CDS_TEST)
- {
- /* Test resolution */
- dwflags &= ~CDS_TEST;
- Status = IntEnumDisplaySettings(pDeviceName, ENUM_REGISTRY_SETTINGS, DevMode, 0);
- if (!NT_SUCCESS(Status))
- Ret = DISP_CHANGE_BADMODE;
- return Ret;
- }
-
- if ((dwflags & CDS_FULLSCREEN) == CDS_FULLSCREEN)
- {
- DEVMODEW lpDevMode;
- /* Full Screen */
- dwflags &= ~CDS_FULLSCREEN;
- DPRINT1("flag CDS_FULLSCREEN partially implemented\n");
- Ret = DISP_CHANGE_FAILED;
-
- RtlZeroMemory(&lpDevMode, sizeof(DEVMODEW));
- lpDevMode.dmSize = sizeof(DEVMODEW);
-
- Status = IntEnumDisplaySettings(pDeviceName, ENUM_CURRENT_SETTINGS, &lpDevMode, 0);
- if (!NT_SUCCESS(Status))
- return DISP_CHANGE_FAILED;
-
- DPRINT1("Req Mode : %d x %d x %d\n", DevMode->dmPelsWidth,DevMode->dmPelsHeight,DevMode->dmBitsPerPel);
- DPRINT1("Current Mode : %d x %d x %d\n", lpDevMode.dmPelsWidth,lpDevMode.dmPelsHeight, lpDevMode.dmBitsPerPel);
-
-
- if ((lpDevMode.dmBitsPerPel == DevMode->dmBitsPerPel) &&
- (lpDevMode.dmPelsWidth == DevMode->dmPelsWidth) &&
- (lpDevMode.dmPelsHeight == DevMode->dmPelsHeight))
- Ret = DISP_CHANGE_SUCCESSFUL;
- }
-
- if ((dwflags & CDS_VIDEOPARAMETERS) == CDS_VIDEOPARAMETERS)
- {
- dwflags &= ~CDS_VIDEOPARAMETERS;
- if (lParam == NULL)
- Ret=DISP_CHANGE_BADPARAM;
- else
- {
- DPRINT1("flag CDS_VIDEOPARAMETERS UNIMPLEMENTED\n");
- Ret = DISP_CHANGE_FAILED;
- SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED);
- }
-
- }
-
- if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
- {
-
- UNICODE_STRING DeviceName;
- UNICODE_STRING RegistryKey;
- UNICODE_STRING InDeviceName;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE DevInstRegKey;
- ULONG NewValue;
-
- DPRINT1("set CDS_UPDATEREGISTRY\n");
-
- dwflags &= ~CDS_UPDATEREGISTRY;
-
- /* Check if pDeviceName is NULL, we need to retrieve it */
- if (pDeviceName == NULL)
- {
- WCHAR szBuffer[MAX_DRIVER_NAME];
- PDC DC;
- PWND Wnd=NULL;
- HWND hWnd;
- HDC hDC;
-
- hWnd = IntGetDesktopWindow();
- if (!(Wnd = UserGetWindowObject(hWnd)))
- {
- return FALSE;
- }
-
- hDC = UserGetWindowDC(Wnd);
-
- DC = DC_LockDc(hDC);
- if (NULL == DC)
- {
- return FALSE;
- }
- swprintf (szBuffer, L"\\\\.\\DISPLAY%lu", DC->ppdev->DisplayNumber);
- DC_UnlockDc(DC);
-
- RtlInitUnicodeString(&InDeviceName, szBuffer);
- pDeviceName = &InDeviceName;
- }
-
- Status = GetVideoDeviceName(&DeviceName, pDeviceName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to get destination of '%wZ' (Status 0x%08lx)\n", pDeviceName, Status);
- return DISP_CHANGE_FAILED;
- }
- Status = GetVideoRegistryKey(&RegistryKey, &DeviceName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to get registry key for '%wZ' (Status 0x%08lx)\n", &DeviceName, Status);
- ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
- return DISP_CHANGE_FAILED;
- }
- ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
-
- InitializeObjectAttributes(&ObjectAttributes, &RegistryKey,
- OBJ_CASE_INSENSITIVE, NULL, NULL);
- Status = ZwOpenKey(&DevInstRegKey, KEY_SET_VALUE, &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to open registry key %wZ (Status 0x%08lx)\n", &RegistryKey, Status);
- ExFreePoolWithTag(RegistryKey.Buffer, TAG_RTLREGISTRY);
- return DISP_CHANGE_FAILED;
- }
- ExFreePoolWithTag(RegistryKey.Buffer, TAG_RTLREGISTRY);
-
- /* Update needed fields */
- if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL)
- {
- RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.BitsPerPel");
- NewValue = DevMode->dmBitsPerPel;
- Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
- }
-
- if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSWIDTH)
- {
- RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.XResolution");
- NewValue = DevMode->dmPelsWidth;
- Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
- }
-
- if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSHEIGHT)
- {
- RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.YResolution");
- NewValue = DevMode->dmPelsHeight;
- Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
- }
-
- if (NT_SUCCESS(Status) && DevMode->dmFields & DM_DISPLAYFREQUENCY)
- {
- RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.VRefresh");
- NewValue = DevMode->dmDisplayFrequency;
- Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
- }
-
- ZwClose(DevInstRegKey);
- if (NT_SUCCESS(Status))
- Ret = DISP_CHANGE_RESTART;
- else
- /* return DISP_CHANGE_NOTUPDATED when we can save to reg only valid for NT */
- Ret = DISP_CHANGE_NOTUPDATED;
- }
-
- if (dwflags != 0)
- Ret = DISP_CHANGE_BADFLAGS;
-
- DPRINT("IntChangeDisplaySettings returning %x\n", Ret);
- return Ret;
-}
-
-
-
-#define SIZEOF_DEVMODEW_300 188
-#define SIZEOF_DEVMODEW_400 212
-#define SIZEOF_DEVMODEW_500 220
-
-static NTSTATUS FASTCALL
-GetDisplayNumberFromDeviceName(
- IN PUNICODE_STRING pDeviceName OPTIONAL,
- OUT ULONG *DisplayNumber)
-{
- UNICODE_STRING DisplayString = RTL_CONSTANT_STRING(L"\\\\.\\DISPLAY");
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Length;
- ULONG Number;
- ULONG i;
-
- if (DisplayNumber == NULL)
- return STATUS_INVALID_PARAMETER_2;
-
- /* Check if DeviceName is valid */
- if (pDeviceName &&
- pDeviceName->Length > 0 && pDeviceName->Length <= DisplayString.Length)
- return STATUS_OBJECT_NAME_INVALID;
-
- if (pDeviceName == NULL || pDeviceName->Length == 0)
- {
- PWND DesktopObject;
- HDC DesktopHDC;
- PDC pDC;
-
- DesktopObject = UserGetDesktopWindow();
- DesktopHDC = UserGetWindowDC(DesktopObject);
- pDC = DC_LockDc(DesktopHDC);
-
- *DisplayNumber = pDC->ppdev->DisplayNumber;
-
- DC_UnlockDc(pDC);
- UserReleaseDC(DesktopObject, DesktopHDC, FALSE);
-
- return STATUS_SUCCESS;
- }
-
- /* Hack to check if the first parts are equal, by faking the device name length */
- Length = pDeviceName->Length;
- pDeviceName->Length = DisplayString.Length;
- if (RtlEqualUnicodeString(&DisplayString, pDeviceName, FALSE) == FALSE)
- Status = STATUS_OBJECT_NAME_INVALID;
- pDeviceName->Length = Length;
-
- if (NT_SUCCESS(Status))
- {
- /* Convert the last part of pDeviceName to a number */
- Number = 0;
- Length = pDeviceName->Length / sizeof(WCHAR);
- for (i = DisplayString.Length / sizeof(WCHAR); i < Length; i++)
- {
- WCHAR Char = pDeviceName->Buffer[i];
- if (Char >= L'0' && Char <= L'9')
- Number = Number * 10 + Char - L'0';
- else if (Char != L'\0')
- return STATUS_OBJECT_NAME_INVALID;
- }
-
- *DisplayNumber = Number - 1;
- }
-
- return Status;
-}
-
-/*! \brief Enumerate possible display settings for the given display...
- *
- * \todo Make thread safe!?
- * \todo Don't ignore pDeviceName
- * \todo Implement non-raw mode (only return settings valid for driver and monitor)
- */
-NTSTATUS
-FASTCALL
-IntEnumDisplaySettings(
- IN PUNICODE_STRING pDeviceName OPTIONAL,
- IN DWORD iModeNum,
- IN OUT LPDEVMODEW pDevMode,
- IN DWORD dwFlags)
-{
- static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
- static DWORD SizeOfCachedDevModes = 0;
- static UNICODE_STRING CachedDeviceName;
- PDEVMODEW CachedMode = NULL;
- DEVMODEW DevMode;
- ULONG DisplayNumber;
- NTSTATUS Status;
-
- Status = GetDisplayNumberFromDeviceName(pDeviceName, &DisplayNumber);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if (pDevMode != NULL)
- {
- DPRINT("DevMode->dmSize = %d\n", pDevMode->dmSize);
- DPRINT("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra);
- if (pDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
- pDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
- pDevMode->dmSize != SIZEOF_DEVMODEW_500)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
- }
-
- if (iModeNum == ENUM_CURRENT_SETTINGS)
- {
- CachedMode = &PrimarySurface.DMW;
- ASSERT(CachedMode->dmSize > 0);
- }
- else if (iModeNum == ENUM_REGISTRY_SETTINGS)
- {
- RtlZeroMemory(&DevMode, sizeof (DevMode));
- DevMode.dmSize = sizeof (DevMode);
- DevMode.dmDriverExtra = 0;
- if (SetupDevMode(&DevMode, DisplayNumber))
- CachedMode = &DevMode;
- else
- {
- return STATUS_UNSUCCESSFUL; // FIXME: what status?
- }
- /* FIXME: Maybe look for the matching devmode supplied by the
- * driver so we can provide driver private/extra data?
- */
- }
- else
- {
- BOOL IsCachedDevice = (CachedDevModes != NULL);
-
- if (CachedDevModes &&
- ((pDeviceName == NULL && CachedDeviceName.Length > 0) ||
- (pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length == 0) ||
- (pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length > 0 && RtlEqualUnicodeString(pDeviceName, &CachedDeviceName, TRUE) == FALSE)))
- {
- IsCachedDevice = FALSE;
- }
-
- if (iModeNum == 0 || IsCachedDevice == FALSE) /* query modes from drivers */
- {
- UNICODE_STRING DriverFileNames;
- LPWSTR CurrentName;
- DRVENABLEDATA DrvEnableData;
-
- /* Free resources from last driver cache */
- if (IsCachedDevice == FALSE && CachedDeviceName.Buffer != NULL)
- {
- RtlFreeUnicodeString(&CachedDeviceName);
- }
-
- /* Retrieve DDI driver names from registry */
- RtlInitUnicodeString(&DriverFileNames, NULL);
- if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
- {
- DPRINT1("FindDriverFileNames failed\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- if (!IntPrepareDriverIfNeeded())
- {
- DPRINT1("IntPrepareDriverIfNeeded failed\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- /*
- * DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
- * scan all of them until a good one found.
- */
- CurrentName = DriverFileNames.Buffer;
- for (;CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR));
- CurrentName += wcslen(CurrentName) + 1)
- {
- INT i;
- PFN_DrvEnableDriver GDEnableDriver;
- PFN_DrvGetModes GetModes = NULL;
- INT SizeNeeded, SizeUsed;
-
- /* Get the DDI driver's entry point */
- //GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
- GDEnableDriver = DRIVER_FindExistingDDIDriver(L"DISPLAY");
- if (NULL == GDEnableDriver)
- {
- DPRINT("FindDDIDriver failed for %S\n", CurrentName);
- continue;
- }
-
- /* Call DDI driver's EnableDriver function */
- RtlZeroMemory(&DrvEnableData, sizeof(DrvEnableData));
-
- if (!GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof (DrvEnableData), &DrvEnableData))
- {
- DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
- continue;
- }
-
- CachedDevModesEnd = CachedDevModes;
-
- /* find DrvGetModes function */
- for (i = 0; i < DrvEnableData.c; i++)
- {
- PDRVFN DrvFn = DrvEnableData.pdrvfn + i;
-
- if (DrvFn->iFunc == INDEX_DrvGetModes)
- {
- GetModes = (PFN_DrvGetModes)DrvFn->pfn;
- break;
- }
- }
-
- if (GetModes == NULL)
- {
- DPRINT("DrvGetModes doesn't exist for %S\n", CurrentName);
- continue;
- }
-
- /* make sure we have enough memory to hold the modes */
- SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject), 0, NULL);
- if (SizeNeeded <= 0)
- {
- DPRINT("DrvGetModes failed for %S\n", CurrentName);
- break;
- }
-
- SizeUsed = (PCHAR)CachedDevModesEnd - (PCHAR)CachedDevModes;
- if (SizeOfCachedDevModes < SizeUsed + SizeNeeded)
- {
- PVOID NewBuffer;
-
- SizeOfCachedDevModes += SizeNeeded;
- NewBuffer = ExAllocatePoolWithTag(PagedPool, SizeOfCachedDevModes, GDITAG_DEVMODE);
- if (NewBuffer == NULL)
- {
- /* clean up */
- ExFreePool(CachedDevModes);
- CachedDevModes = NULL;
- CachedDevModesEnd = NULL;
- SizeOfCachedDevModes = 0;
-
- if (CachedDeviceName.Buffer != NULL)
- RtlFreeUnicodeString(&CachedDeviceName);
-
- return STATUS_NO_MEMORY;
- }
- if (CachedDevModes != NULL)
- {
- RtlCopyMemory(NewBuffer, CachedDevModes, SizeUsed);
- ExFreePool(CachedDevModes);
- }
- CachedDevModes = NewBuffer;
- CachedDevModesEnd = (DEVMODEW *)((PCHAR)NewBuffer + SizeUsed);
- }
-
- if (!IsCachedDevice)
- {
- if (CachedDeviceName.Buffer != NULL)
- RtlFreeUnicodeString(&CachedDeviceName);
-
- if (pDeviceName)
- IntSafeCopyUnicodeString(&CachedDeviceName, pDeviceName);
-
- IsCachedDevice = TRUE;
- }
-
- /* query modes */
- SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject),
- SizeNeeded,
- CachedDevModesEnd);
- if (SizeNeeded <= 0)
- {
- DPRINT("DrvGetModes failed for %S\n", CurrentName);
- }
- else
- {
- CachedDevModesEnd = (DEVMODEW *)((PCHAR)CachedDevModesEnd + SizeNeeded);
- }
- }
-
- ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY);
- }
-
- /* return cached info */
- CachedMode = CachedDevModes;
- if (CachedMode >= CachedDevModesEnd)
- {
- return STATUS_NO_MORE_ENTRIES;
- }
- while (iModeNum-- > 0 && CachedMode < CachedDevModesEnd)
- {
- ASSERT(CachedMode->dmSize > 0);
- CachedMode = (DEVMODEW *)((PCHAR)CachedMode + CachedMode->dmSize + CachedMode->dmDriverExtra);
- }
- if (CachedMode >= CachedDevModesEnd)
- {
- return STATUS_NO_MORE_ENTRIES;
- }
- }
-
- ASSERT(CachedMode != NULL);
-
- if (pDevMode != NULL)
- {
- RtlCopyMemory(pDevMode, CachedMode, min(pDevMode->dmSize, CachedMode->dmSize));
- RtlZeroMemory(pDevMode + pDevMode->dmSize, pDevMode->dmDriverExtra);
- RtlCopyMemory(pDevMode + min(pDevMode->dmSize, CachedMode->dmSize), CachedMode + CachedMode->dmSize, min(pDevMode->dmDriverExtra, CachedMode->dmDriverExtra));
- }
-
- return STATUS_SUCCESS;
-}
-
INT
APIENTRY
NtGdiDrawEscape(
@@ -1776,3 +92,4 @@ NtGdiDrawEscape(
return 0;
}
+
diff --git a/subsystems/win32/win32k/objects/dibobj.c b/subsystems/win32/win32k/objects/dibobj.c
index f8ce6460278..116aebf93f8 100644
--- a/subsystems/win32/win32k/objects/dibobj.c
+++ b/subsystems/win32/win32k/objects/dibobj.c
@@ -42,6 +42,26 @@ static const RGBQUAD EGAColorsQuads[16] = {
{ 0xff, 0xff, 0xff, 0x00 }
};
+static const RGBTRIPLE EGAColorsTriples[16] = {
+/* rgbBlue, rgbGreen, rgbRed */
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x80 },
+ { 0x00, 0x80, 0x00 },
+ { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 },
+ { 0x80, 0x00, 0x80 },
+ { 0x80, 0x80, 0x00 },
+ { 0x80, 0x80, 0x80 },
+ { 0xc0, 0xc0, 0xc0 },
+ { 0x00, 0x00, 0xff },
+ { 0x00, 0xff, 0x00 },
+ { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 },
+ { 0xff, 0x00, 0xff },
+ { 0xff, 0xff, 0x00 },
+ { 0xff, 0xff, 0xff }
+};
+
static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
{ 0x00, 0x00, 0x00, 0x00 },
@@ -66,6 +86,30 @@ static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palet
{ 0xff, 0xff, 0xff, 0x00 }
};
+static const RGBQUAD DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
+/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x80 },
+ { 0x00, 0x80, 0x00 },
+ { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 },
+ { 0x80, 0x00, 0x80 },
+ { 0x80, 0x80, 0x00 },
+ { 0xc0, 0xc0, 0xc0 },
+ { 0xc0, 0xdc, 0xc0 },
+ { 0xf0, 0xca, 0xa6 },
+ { 0xf0, 0xfb, 0xff },
+ { 0xa4, 0xa0, 0xa0 },
+ { 0x80, 0x80, 0x80 },
+ { 0x00, 0x00, 0xf0 },
+ { 0x00, 0xff, 0x00 },
+ { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 },
+ { 0xff, 0x00, 0xff },
+ { 0xff, 0xff, 0x00 },
+ { 0xff, 0xff, 0xff }
+};
+
UINT
APIENTRY
@@ -109,14 +153,15 @@ IntSetDIBColorTable(
if (StartIndex + Entries > (1 << biBitCount))
Entries = (1 << biBitCount) - StartIndex;
- PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
- if (PalGDI == NULL)
+ if (psurf->ppal == NULL)
{
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
for (Index = StartIndex;
Index < StartIndex + Entries && Index < PalGDI->NumColors;
Index++)
@@ -181,14 +226,15 @@ IntGetDIBColorTable(
if (StartIndex + Entries > (1 << biBitCount))
Entries = (1 << biBitCount) - StartIndex;
- PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
- if (PalGDI == NULL)
+ if (psurf->ppal == NULL)
{
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
for (Index = StartIndex;
Index < StartIndex + Entries && Index < PalGDI->NumColors;
Index++)
@@ -219,132 +265,67 @@ IntSetDIBits(
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
- SURFACE *bitmap;
HBITMAP SourceBitmap;
+ PSURFACE psurfDst, psurfSrc;
INT result = 0;
- BOOL copyBitsResult;
- SURFOBJ *DestSurf, *SourceSurf;
- SIZEL SourceSize;
- POINTL ZeroPoint;
- RECTL DestRect;
- EXLATEOBJ exlo;
- PPALETTE ppalDDB, ppalDIB;
- //RGBQUAD *lpRGB;
- HPALETTE DDB_Palette, DIB_Palette;
- ULONG DIB_Palette_Type;
- INT DIBWidth;
+ RECT rcDst;
+ POINTL ptSrc;
+ PVOID pvBits;
+ EXLATEOBJ exlo;
- // Check parameters
- if (!(bitmap = SURFACE_LockSurface(hBitmap)))
+ SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
+ if (0 == SourceBitmap)
{
- return 0;
- }
-
- // Get RGB values
- //if (ColorUse == DIB_PAL_COLORS)
- // lpRGB = DIB_MapPaletteColors(hDC, bmi);
- //else
- // lpRGB = &bmi->bmiColors;
-
- DestSurf = &bitmap->SurfObj;
-
- // Create source surface
- SourceSize.cx = bmi->bmiHeader.biWidth;
- SourceSize.cy = ScanLines;
-
- // Determine width of DIB
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
-
- SourceBitmap = EngCreateBitmap(SourceSize,
- DIBWidth,
- BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
- bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
- (PVOID) Bits);
- if (0 == SourceBitmap)
- {
- SURFACE_UnlockSurface(bitmap);
+ DPRINT1("Error : Could not create a DIBSection.\n");
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
- SourceSurf = EngLockSurface((HSURF)SourceBitmap);
- if (NULL == SourceSurf)
- {
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
+ RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ bmi->bmiHeader.biHeight,
+ bmi->bmiHeader.biBitCount));
- // Use hDIBPalette if it exists
- if (bitmap->hDIBPalette)
- {
- DDB_Palette = bitmap->hDIBPalette;
- }
- else
- {
- // Destination palette obtained from the hDC
- DDB_Palette = DC->ppdev->devinfo.hpalDefault;
- }
+ psurfDst = SURFACE_LockSurface(hBitmap);
+ psurfSrc = SURFACE_LockSurface(SourceBitmap);
- ppalDDB = PALETTE_LockPalette(DDB_Palette);
- if (NULL == ppalDDB)
- {
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
+ if(!(psurfSrc && psurfDst))
+ {
+ DPRINT1("Error, could not lock surfaces\n");
+ goto cleanup;
+ }
- // Source palette obtained from the BITMAPINFO
- DIB_Palette = BuildDIBPalette((PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type);
- if (NULL == DIB_Palette)
- {
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
+ rcDst.top = bmi->bmiHeader.biHeight < 0 ?
+ abs(bmi->bmiHeader.biHeight) - (ScanLines + StartScan) : StartScan;
+ rcDst.left = 0;
+ rcDst.bottom = rcDst.top + ScanLines;
+ rcDst.right = psurfDst->SurfObj.sizlBitmap.cx;
- ppalDIB = PALETTE_LockPalette(DIB_Palette);
+ ptSrc.x = 0;
+ ptSrc.y = 0;
- /* Initialize XLATEOBJ for color translation */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo, psurfSrc->ppal, psurfDst->ppal, 0, 0, 0);
- // Zero point
- ZeroPoint.x = 0;
- ZeroPoint.y = 0;
+ result = IntEngCopyBits(&psurfDst->SurfObj,
+ &psurfSrc->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDst,
+ &ptSrc);
+ if(result)
+ result = ScanLines;
- // Determine destination rectangle
- DestRect.left = 0;
- DestRect.top = abs(bmi->bmiHeader.biHeight) - StartScan - ScanLines;
- DestRect.right = SourceSize.cx;
- DestRect.bottom = DestRect.top + ScanLines;
+ EXLATEOBJ_vCleanup(&exlo);
- copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint);
-
- // If it succeeded, return number of scanlines copies
- if (copyBitsResult == TRUE)
- {
- result = SourceSize.cy;
-// or
-// result = abs(bmi->bmiHeader.biHeight) - StartScan;
- }
-
- // Clean up
- EXLATEOBJ_vCleanup(&exlo);
- PALETTE_UnlockPalette(ppalDIB);
- PALETTE_UnlockPalette(ppalDDB);
- PALETTE_FreePaletteByHandle(DIB_Palette);
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
-
-// if (ColorUse == DIB_PAL_COLORS)
-// WinFree((LPSTR)lpRGB);
-
- SURFACE_UnlockSurface(bitmap);
+cleanup:
+ if(psurfSrc)
+ {
+ SURFACE_UnlockSurface(psurfSrc);
+ }
+ if(psurfDst)
+ {
+ SURFACE_UnlockSurface(psurfDst);
+ }
+ GreDeleteObject(SourceBitmap);
return result;
}
@@ -366,17 +347,19 @@ NtGdiSetDIBits(
PDC Dc;
INT Ret;
NTSTATUS Status = STATUS_SUCCESS;
- UINT cjBits;
if (!Bits) return 0;
_SEH2_TRY
- { // FYI: We converted from CORE in gdi.
- ProbeForRead(bmi, sizeof(BITMAPINFO), 1);
- cjBits = bmi->bmiHeader.biBitCount * bmi->bmiHeader.biPlanes * bmi->bmiHeader.biWidth;
- cjBits = ((cjBits + 31) & ~31) / 8;
- cjBits *= ScanLines;
- ProbeForRead(Bits, cjBits, 1);
+ {
+ ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
+ ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, ColorUse), 1);
+ ProbeForRead(Bits,
+ DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ ScanLines,
+ bmi->bmiHeader.biBitCount),
+ 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -440,15 +423,14 @@ NtGdiSetDIBitsToDeviceInternal(
INT DIBWidth;
SIZEL SourceSize;
EXLATEOBJ exlo;
- PPALETTE ppalDDB = NULL, ppalDIB = NULL;
- HPALETTE hpalDDB, hpalDIB = NULL;
- ULONG DIBPaletteType;
+ PPALETTE ppalDIB = NULL;
+ HPALETTE hpalDIB = NULL;
if (!Bits) return 0;
_SEH2_TRY
{
- ProbeForRead(bmi, cjMaxInfo , 1);
+ ProbeForRead(bmi, cjMaxInfo, 1);
ProbeForRead(Bits, cjMaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -474,15 +456,7 @@ NtGdiSetDIBitsToDeviceInternal(
return 0;
}
- /* Use destination palette obtained from the DC by default */
- hpalDDB = pDC->ppdev->devinfo.hpalDefault;
-
- /* Try to use hDIBPalette if it exists */
pSurf = pDC->dclevel.pSurface;
- if (pSurf && pSurf->hDIBPalette)
- {
- hpalDDB = pSurf->hDIBPalette;
- }
pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
@@ -506,11 +480,12 @@ NtGdiSetDIBitsToDeviceInternal(
SourceSize.cx = bmi->bmiHeader.biWidth;
SourceSize.cy = ScanLines;
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
+ DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
hSourceBitmap = EngCreateBitmap(SourceSize,
DIBWidth,
- BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
+ BitmapFormat(bmi->bmiHeader.biBitCount,
+ bmi->bmiHeader.biCompression),
bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
(PVOID) Bits);
if (!hSourceBitmap)
@@ -527,17 +502,10 @@ NtGdiSetDIBitsToDeviceInternal(
goto Exit;
}
- /* Obtain destination palette */
- ppalDDB = PALETTE_LockPalette(hpalDDB);
- if (!ppalDDB)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- Status = STATUS_UNSUCCESSFUL;
- goto Exit;
- }
+ ASSERT(pSurf->ppal);
/* Create a palette for the DIB */
- hpalDIB = BuildDIBPalette(bmi, (PINT)&DIBPaletteType);
+ hpalDIB = BuildDIBPalette(bmi);
if (!hpalDIB)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
@@ -547,7 +515,7 @@ NtGdiSetDIBitsToDeviceInternal(
/* Lock the DIB palette */
ppalDIB = PALETTE_LockPalette(hpalDIB);
- if (!ppalDDB)
+ if (!ppalDIB)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
Status = STATUS_UNSUCCESSFUL;
@@ -555,7 +523,7 @@ NtGdiSetDIBitsToDeviceInternal(
}
/* Initialize EXLATEOBJ */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo, ppalDIB, pSurf->ppal, 0, 0, 0);
/* Copy the bits */
DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n",
@@ -583,7 +551,6 @@ Exit:
}
if (ppalDIB) PALETTE_UnlockPalette(ppalDIB);
- if (ppalDDB) PALETTE_UnlockPalette(ppalDDB);
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
@@ -608,37 +575,29 @@ NtGdiGetDIBitsInternal(
UINT MaxBits,
UINT MaxInfo)
{
- PDC Dc;
- SURFACE *psurf = NULL;
- HBITMAP hDestBitmap = NULL;
- HPALETTE hSourcePalette = NULL;
- HPALETTE hDestPalette = NULL;
- PPALETTE ppalSrc = NULL;
- PPALETTE ppalDst = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Result = 0;
- BOOL bPaletteMatch = FALSE;
- PBYTE ChkBits = Bits;
- PVOID ColorPtr;
- RGBQUAD *rgbQuads;
- ULONG DestPaletteType;
- ULONG Index;
+ BITMAPCOREINFO* pbmci = NULL;
+ PSURFACE psurf = NULL;
+ PDC pDC;
+ LONG width, height;
+ WORD planes, bpp;
+ DWORD compr, size ;
+ int i, bitmap_type;
+ RGBTRIPLE* rgbTriples;
+ RGBQUAD* rgbQuads;
+ VOID* colorPtr;
+ NTSTATUS Status = STATUS_SUCCESS;
DPRINT("Entered NtGdiGetDIBitsInternal()\n");
if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
return 0;
- // if ScanLines == 0, no need to copy Bits.
- if (!ScanLines)
- ChkBits = NULL;
-
_SEH2_TRY
{
- ProbeForRead(&Info->bmiHeader.biSize, sizeof(DWORD), 1);
-
- ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core.
- if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
+ /* Probe for read and write */
+ ProbeForRead(Info, MaxInfo, 1);
+ ProbeForWrite(Info, MaxInfo, 1);
+ if (Bits) ProbeForWrite(Bits, MaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -651,340 +610,397 @@ NtGdiGetDIBitsInternal(
return 0;
}
- Dc = DC_LockDc(hDC);
- if (Dc == NULL) return 0;
- if (Dc->dctype == DC_TYPE_INFO)
+ colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
+ rgbTriples = colorPtr;
+ rgbQuads = colorPtr;
+
+ bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
+ &width,
+ &height,
+ &planes,
+ &bpp,
+ &compr,
+ &size);
+ if(bitmap_type == -1)
+ {
+ DPRINT("Wrong bitmap format\n");
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ else if(bitmap_type == 0)
+ {
+ /* We need a BITMAPINFO to create a DIB, but we have to fill
+ * the BITMAPCOREINFO we're provided */
+ pbmci = (BITMAPCOREINFO*)Info;
+ Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage);
+ if(Info == NULL)
+ {
+ DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
+ return 0;
+ }
+ rgbQuads = Info->bmiColors;
+ }
+
+ pDC = DC_LockDc(hDC);
+ if (pDC == NULL || pDC->dctype == DC_TYPE_INFO)
{
- DC_UnlockDc(Dc);
- return 0;
+ ScanLines = 0;
+ goto done;
}
- DC_UnlockDc(Dc);
/* Get a pointer to the source bitmap object */
psurf = SURFACE_LockSurface(hBitmap);
if (psurf == NULL)
- return 0;
-
- hSourcePalette = psurf->hDIBPalette;
- if (!hSourcePalette)
{
- hSourcePalette = pPrimarySurface->devinfo.hpalDefault;
+ ScanLines = 0;
+ goto done;
}
- ColorPtr = ((PBYTE)Info + Info->bmiHeader.biSize);
- rgbQuads = (RGBQUAD *)ColorPtr;
+ /* Fill in the structure */
+ switch(bpp)
+ {
+ case 0: /* Only info */
+ if(pbmci)
+ {
+ pbmci->bmciHeader.bcWidth = psurf->SurfObj.sizlBitmap.cx;
+ pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
+ psurf->SurfObj.sizlBitmap.cy;
+ pbmci->bmciHeader.bcPlanes = 1;
+ pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ }
+ Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
+ Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
+ psurf->SurfObj.sizlBitmap.cy;;
+ Info->bmiHeader.biPlanes = 1;
+ Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( Info->bmiHeader.biWidth,
+ Info->bmiHeader.biHeight,
+ Info->bmiHeader.biBitCount);
+ if(psurf->hSecure)
+ {
+ switch(Info->bmiHeader.biBitCount)
+ {
+ case 16:
+ case 32:
+ Info->bmiHeader.biCompression = BI_BITFIELDS;
+ break;
+ default:
+ Info->bmiHeader.biCompression = BI_RGB;
+ break;
+ }
+ }
+ else if(Info->bmiHeader.biBitCount > 8)
+ {
+ Info->bmiHeader.biCompression = BI_BITFIELDS;
+ }
+ else
+ {
+ Info->bmiHeader.biCompression = BI_RGB;
+ }
+ Info->bmiHeader.biXPelsPerMeter = 0;
+ Info->bmiHeader.biYPelsPerMeter = 0;
+ Info->bmiHeader.biClrUsed = 0;
+ Info->bmiHeader.biClrImportant = 0;
+ ScanLines = abs(Info->bmiHeader.biHeight);
+ goto done;
- /* Copy palette information
- * Always create a palette for 15 & 16 bit. */
- if ((Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) &&
- Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) ||
- !ChkBits)
- {
- hDestPalette = hSourcePalette;
- bPaletteMatch = TRUE;
- }
- else
- hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault;
+ case 1:
+ case 4:
+ case 8:
+ Info->bmiHeader.biClrUsed = 0;
- ppalSrc = PALETTE_LockPalette(hSourcePalette);
- /* FIXME - ppalSrc can be NULL!!! Don't assert here! */
- ASSERT(ppalSrc);
+ /* If the bitmap if a DIB section and has the same format than what
+ * we're asked, go ahead! */
+ if((psurf->hSecure) &&
+ (BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
+ {
+ if(Usage == DIB_RGB_COLORS)
+ {
+ unsigned int colors = min(psurf->ppal->NumColors, 1 << bpp);
- if (!bPaletteMatch)
- {
- ppalDst = PALETTE_LockPalette(hDestPalette);
- /* FIXME - ppalDst can be NULL!!!! Don't assert here!!! */
- DPRINT("ppalDst : %p\n", ppalDst);
- ASSERT(ppalDst);
- }
- else
- {
- ppalDst = ppalSrc;
- }
+ if(pbmci)
+ {
+ for(i=0; i < colors; i++)
+ {
+ rgbTriples[i].rgbtRed = psurf->ppal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = psurf->ppal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = psurf->ppal->IndexedColors[i].peBlue;
+ }
+ }
+ if(colors != 1 << bpp) Info->bmiHeader.biClrUsed = colors;
+ for(i=0; i < colors; i++)
+ {
+ rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
+ rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
+ rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
+ }
+ }
+ else
+ {
+ for(i=0; i < 1 << bpp; i++)
+ {
+ if(pbmci) ((WORD*)rgbTriples)[i] = i;
+ ((WORD*)rgbQuads)[i] = i;
+ }
+ }
+ }
+ else
+ {
+ if(Usage == DIB_PAL_COLORS)
+ {
+ for(i=0; i < 1 << bpp; i++)
+ {
+ if(pbmci) ((WORD*)rgbTriples)[i] = i;
+ ((WORD*)rgbQuads)[i] = i;
+ }
+ }
+ else if(bpp > 1 && bpp == BitsPerFormat(psurf->SurfObj.iBitmapFormat)) {
+ /* For color DDBs in native depth (mono DDBs always have
+ a black/white palette):
+ Generate the color map from the selected palette */
+ PPALETTE pDcPal = PALETTE_LockPalette(pDC->dclevel.hpal);
+ if(!pDcPal)
+ {
+ ScanLines = 0 ;
+ goto done ;
+ }
+ for (i = 0; i < pDcPal->NumColors; i++) {
+ if (pbmci)
+ {
+ rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
+ }
- /* Copy palette. */
- /* FIXME: This is largely incomplete. ATM no Core!*/
- switch (Info->bmiHeader.biBitCount)
- {
- case 1:
- case 4:
- case 8:
- Info->bmiHeader.biClrUsed = 0;
- if (psurf->hSecure &&
- BitsPerFormat(psurf->SurfObj.iBitmapFormat) == Info->bmiHeader.biBitCount)
- {
- if (Usage == DIB_RGB_COLORS)
- {
- if (ppalDst->NumColors != 1 << Info->bmiHeader.biBitCount)
- Info->bmiHeader.biClrUsed = ppalDst->NumColors;
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
- Index++)
+ rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
+ rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
+ rgbQuads[i].rgbReserved = 0;
+ }
+ PALETTE_UnlockPalette(pDcPal);
+ } else {
+ switch (bpp) {
+ case 1:
+ if (pbmci)
{
- rgbQuads[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
- rgbQuads[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
- rgbQuads[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
- rgbQuads[Index].rgbReserved = 0;
+ rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
+ rgbTriples[0].rgbtBlue = 0;
+ rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
+ rgbTriples[1].rgbtBlue = 0xff;
}
- }
- else
- {
- PWORD Ptr = ColorPtr;
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount);
- Index++)
+ rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
+ rgbQuads[0].rgbBlue = 0;
+ rgbQuads[0].rgbReserved = 0;
+ rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
+ rgbQuads[1].rgbBlue = 0xff;
+ rgbQuads[1].rgbReserved = 0;
+ break;
+
+ case 4:
+ if (pbmci)
+ RtlCopyMemory(rgbTriples, EGAColorsTriples, sizeof(EGAColorsTriples));
+ RtlCopyMemory(rgbQuads, EGAColorsQuads, sizeof(EGAColorsQuads));
+
+ break;
+
+ case 8:
{
- Ptr[Index] = (WORD)Index;
- }
- }
- }
- else
- {
- if (Usage == DIB_PAL_COLORS)
- {
- PWORD Ptr = ColorPtr;
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount);
- Index++)
- {
- Ptr[Index] = (WORD)Index;
- }
- }
- else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch)
- {
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
- Index++)
- {
- Info->bmiColors[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
- Info->bmiColors[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
- Info->bmiColors[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
- Info->bmiColors[Index].rgbReserved = 0;
- }
- }
- else
- {
- switch (Info->bmiHeader.biBitCount)
- {
- case 1:
- rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
- rgbQuads[0].rgbReserved = 0;
- rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
- rgbQuads[1].rgbReserved = 0;
- break;
- case 4:
- RtlCopyMemory(ColorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
- break;
- case 8:
+ INT r, g, b;
+ RGBQUAD *color;
+ if (pbmci)
{
- INT r, g, b;
- RGBQUAD *color;
+ RGBTRIPLE *colorTriple;
- RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
- RtlCopyMemory(rgbQuads + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
- color = rgbQuads + 10;
- for (r = 0; r <= 5; r++) /* FIXME */
- for (g = 0; g <= 5; g++)
- for (b = 0; b <= 5; b++)
- {
- color->rgbRed = (r * 0xff) / 5;
- color->rgbGreen = (g * 0xff) / 5;
- color->rgbBlue = (b * 0xff) / 5;
- color->rgbReserved = 0;
+ RtlCopyMemory(rgbTriples, DefLogPaletteTriples,
+ 10 * sizeof(RGBTRIPLE));
+ RtlCopyMemory(rgbTriples + 246, DefLogPaletteTriples + 10,
+ 10 * sizeof(RGBTRIPLE));
+ colorTriple = rgbTriples + 10;
+ for(r = 0; r <= 5; r++) /* FIXME */
+ {
+ for(g = 0; g <= 5; g++)
+ {
+ for(b = 0; b <= 5; b++)
+ {
+ colorTriple->rgbtRed = (r * 0xff) / 5;
+ colorTriple->rgbtGreen = (g * 0xff) / 5;
+ colorTriple->rgbtBlue = (b * 0xff) / 5;
color++;
}
+ }
+ }
}
- break;
+ memcpy(rgbQuads, DefLogPaletteQuads,
+ 10 * sizeof(RGBQUAD));
+ memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
+ 10 * sizeof(RGBQUAD));
+ color = rgbQuads + 10;
+ for(r = 0; r <= 5; r++) /* FIXME */
+ {
+ for(g = 0; g <= 5; g++)
+ {
+ for(b = 0; b <= 5; b++)
+ {
+ color->rgbRed = (r * 0xff) / 5;
+ color->rgbGreen = (g * 0xff) / 5;
+ color->rgbBlue = (b * 0xff) / 5;
+ color->rgbReserved = 0;
+ color++;
+ }
+ }
+ }
}
}
}
+ }
+ break;
- case 15:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
- {
- ((PDWORD)Info->bmiColors)[0] = 0x7c00;
- ((PDWORD)Info->bmiColors)[1] = 0x03e0;
- ((PDWORD)Info->bmiColors)[2] = 0x001f;
- }
- break;
+ case 15:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ ((PDWORD)Info->bmiColors)[0] = 0x7c00;
+ ((PDWORD)Info->bmiColors)[1] = 0x03e0;
+ ((PDWORD)Info->bmiColors)[2] = 0x001f;
+ }
+ break;
- case 16:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ case 16:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ if (psurf->hSecure)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
+ else
{
((PDWORD)Info->bmiColors)[0] = 0xf800;
((PDWORD)Info->bmiColors)[1] = 0x07e0;
((PDWORD)Info->bmiColors)[2] = 0x001f;
}
- break;
+ }
+ break;
- case 24:
- case 32:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ case 24:
+ case 32:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ if (psurf->hSecure)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
+ else
{
((PDWORD)Info->bmiColors)[0] = 0xff0000;
((PDWORD)Info->bmiColors)[1] = 0x00ff00;
((PDWORD)Info->bmiColors)[2] = 0x0000ff;
}
- break;
- }
-
- if (!bPaletteMatch)
- PALETTE_UnlockPalette(ppalDst);
-
- /* fill out the BITMAPINFO struct */
- if (!ChkBits)
- { // Core or not to Core? We have converted from Core in Gdi~ so?
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
- coreheader->bcWidth = psurf->SurfObj.sizlBitmap.cx;
- coreheader->bcPlanes = 1;
- coreheader->bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- coreheader->bcHeight = psurf->SurfObj.sizlBitmap.cy;
- if (psurf->SurfObj.lDelta > 0)
- coreheader->bcHeight = -coreheader->bcHeight;
}
-
- if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
- {
- Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
- Info->bmiHeader.biHeight = psurf->SurfObj.sizlBitmap.cy;
- Info->bmiHeader.biPlanes = 1;
- Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- switch (psurf->SurfObj.iBitmapFormat)
- {
- /* FIXME: What about BI_BITFIELDS? */
- case BMF_1BPP:
- case BMF_4BPP:
- case BMF_8BPP:
- case BMF_16BPP:
- case BMF_24BPP:
- case BMF_32BPP:
- Info->bmiHeader.biCompression = BI_RGB;
- break;
- case BMF_4RLE:
- Info->bmiHeader.biCompression = BI_RLE4;
- break;
- case BMF_8RLE:
- Info->bmiHeader.biCompression = BI_RLE8;
- break;
- case BMF_JPEG:
- Info->bmiHeader.biCompression = BI_JPEG;
- break;
- case BMF_PNG:
- Info->bmiHeader.biCompression = BI_PNG;
- break;
- }
- /* Image size has to be calculated */
- Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(Info->bmiHeader.biWidth,
- Info->bmiHeader.biBitCount) * Info->bmiHeader.biHeight;
- Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biClrUsed = 0;
- Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
- /* Report negtive height for top-down bitmaps. */
- if (psurf->SurfObj.lDelta > 0)
- Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
- }
- Result = psurf->SurfObj.sizlBitmap.cy;
+ break;
}
- else
- {
- SIZEL DestSize;
- POINTL SourcePoint;
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
-//
-// If we have a good dib pointer, why not just copy bits from there w/o XLATE'ing them.
-//
- /* Create the destination bitmap too for the copy operation */
- if (StartScan > psurf->SurfObj.sizlBitmap.cy)
+ if(Bits && ScanLines)
+ {
+ /* Create a DIBSECTION, blt it, profit */
+ PVOID pDIBits ;
+ HBITMAP hBmpDest;
+ PSURFACE psurfDest;
+ EXLATEOBJ exlo;
+ RECT rcDest;
+ POINTL srcPoint;
+ BOOL ret ;
+
+ if (StartScan > psurf->SurfObj.sizlBitmap.cy)
{
- goto cleanup;
+ ScanLines = 0;
+ goto done;
}
else
{
ScanLines = min(ScanLines, psurf->SurfObj.sizlBitmap.cy - StartScan);
- DestSize.cx = psurf->SurfObj.sizlBitmap.cx;
- DestSize.cy = ScanLines;
+ }
- hDestBitmap = NULL;
+ /* Fixup values */
+ Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
+ Info->bmiHeader.biHeight = height < 0 ?
+ -ScanLines : ScanLines;
+ /* Create the DIB */
+ hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
+ /* Restore them */
+ Info->bmiHeader.biWidth = width;
+ Info->bmiHeader.biHeight = height;
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
- BitmapFormat(coreheader->bcBitCount, BI_RGB),
- 0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
- Bits);
- }
+ if(!hBmpDest)
+ {
+ DPRINT1("Unable to create a DIB Section!\n");
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ ScanLines = 0;
+ goto done ;
+ }
- if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
- {
- Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(DestSize.cx,
- Info->bmiHeader.biBitCount) * DestSize.cy;
+ psurfDest = SURFACE_LockSurface(hBmpDest);
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount),
- BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
- 0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
- Bits);
- }
+ rcDest.left = 0;
+ rcDest.top = 0;
+ rcDest.bottom = ScanLines;
+ rcDest.right = psurf->SurfObj.sizlBitmap.cx;
- if (hDestBitmap == NULL)
- goto cleanup;
- }
+ srcPoint.x = 0;
+ srcPoint.y = height < 0 ?
+ psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines) : StartScan;
- if (NT_SUCCESS(Status))
- {
- EXLATEOBJ exlo;
- SURFOBJ *DestSurfObj;
- RECTL DestRect;
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0, 0, 0);
- EXLATEOBJ_vInitialize(&exlo, ppalSrc, ppalDst, 0, 0, 0);
+ ret = IntEngCopyBits(&psurfDest->SurfObj,
+ &psurf->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDest,
+ &srcPoint);
- SourcePoint.x = 0;
- SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
+ if(!ret)
+ ScanLines = 0;
+ else
+ {
+ Status = STATUS_SUCCESS;
+ _SEH2_TRY
+ {
+ RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
- /* Determine destination rectangle */
- DestRect.top = 0;
- DestRect.left = 0;
- DestRect.right = DestSize.cx;
- DestRect.bottom = DestSize.cy;
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Unable to copy bits to the user provided pointer\n");
+ ScanLines = 0;
+ }
+ }
- DestSurfObj = EngLockSurface((HSURF)hDestBitmap);
+ GreDeleteObject(hBmpDest);
+ EXLATEOBJ_vCleanup(&exlo);
+ }
+ else ScanLines = abs(height);
- if (IntEngCopyBits(DestSurfObj,
- &psurf->SurfObj,
- NULL,
- &exlo.xlo,
- &DestRect,
- &SourcePoint))
- {
- DPRINT("GetDIBits %d \n",abs(Info->bmiHeader.biHeight) - StartScan);
- Result = ScanLines;
- }
+done:
- EXLATEOBJ_vCleanup(&exlo);
- EngUnlockSurface(DestSurfObj);
- }
- }
-cleanup:
- PALETTE_UnlockPalette(ppalSrc);
+ if(pDC) DC_UnlockDc(pDC);
+ if(psurf) SURFACE_UnlockSurface(psurf);
+ if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
- if (hDestBitmap != NULL)
- EngDeleteSurface((HSURF)hDestBitmap);
-
- if (hDestPalette != NULL && bPaletteMatch == FALSE)
- PALETTE_FreePaletteByHandle(hDestPalette);
-
- SURFACE_UnlockSurface(psurf);
-
- DPRINT("leaving NtGdiGetDIBitsInternal\n");
-
- return Result;
+ return ScanLines;
}
+
INT
APIENTRY
NtGdiStretchDIBitsInternal(
@@ -1005,113 +1021,121 @@ NtGdiStretchDIBitsInternal(
UINT cjMaxBits,
HANDLE hcmXform)
{
- HBITMAP hBitmap, hOldBitmap = NULL;
- HDC hdcMem;
- HPALETTE hPal = NULL;
- PDC pDC;
- BOOL Hit = FALSE;
+ PDC pdc;
+ INT ret = 0;
+ LONG height;
+ LONG width;
+ WORD planes, bpp;
+ DWORD compr, size;
+ HBITMAP hBitmap;
+ BOOL fastpath = FALSE;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PBYTE safeBits ;
if (!Bits || !BitsInfo)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
- }
+
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return 0;
+ }
+
+ if (!(pdc = DC_LockDc(hDC)))
+ {
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
_SEH2_TRY
{
ProbeForRead(BitsInfo, cjMaxInfo, 1);
ProbeForRead(Bits, cjMaxBits, 1);
+ if (DIB_GetBitmapInfo( &BitsInfo->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
+ {
+ DPRINT1("Invalid bitmap\n");
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ RtlCopyMemory(safeBits, Bits, cjMaxBits);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Hit = TRUE;
+ Status = _SEH2_GetExceptionCode();
}
_SEH2_END
- if (Hit)
+ if(!NT_SUCCESS(Status))
{
- DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits);
+ DPRINT1("Error, failed to read the DIB bits\n");
+ goto cleanup;
+ }
+
+ if (width < 0)
+ {
+ DPRINT1("Bitmap has a negative width\n");
return 0;
}
- hdcMem = NtGdiCreateCompatibleDC(hDC);
- if (hdcMem == NULL)
+ hBitmap = NtGdiGetDCObject(hDC, OBJ_BITMAP);
+
+ if (XDest == 0 && YDest == 0 && XSrc == 0 && XSrc == 0 &&
+ DestWidth == SrcWidth && DestHeight == SrcHeight &&
+ compr == BI_RGB &&
+ ROP == SRCCOPY)
{
- DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n");
- return 0;
+ BITMAP bmp;
+ if (IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp))
+ {
+ if (bmp.bmBitsPixel == bpp &&
+ bmp.bmWidth == SrcWidth &&
+ bmp.bmHeight == SrcHeight &&
+ bmp.bmPlanes == planes)
+ fastpath = TRUE;
+ }
}
- hBitmap = NtGdiCreateCompatibleBitmap(hDC,
- abs(BitsInfo->bmiHeader.biWidth),
- abs(BitsInfo->bmiHeader.biHeight));
- if (hBitmap == NULL)
+ if (fastpath)
{
- DPRINT1("NtGdiCreateCompatibleBitmap fail create bitmap\n");
- DPRINT1("hDC : 0x%08x \n", hDC);
- DPRINT1("BitsInfo->bmiHeader.biWidth : 0x%08x \n", BitsInfo->bmiHeader.biWidth);
- DPRINT1("BitsInfo->bmiHeader.biHeight : 0x%08x \n", BitsInfo->bmiHeader.biHeight);
- return 0;
+ /* fast path */
+ DPRINT1("using fast path\n");
+ ret = IntSetDIBits( pdc, hBitmap, 0, height, safeBits, BitsInfo, Usage);
}
-
- /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
- hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
-
- if (Usage == DIB_PAL_COLORS)
- {
- hPal = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE);
- hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
- }
-
- if (BitsInfo->bmiHeader.biCompression == BI_RLE4 ||
- BitsInfo->bmiHeader.biCompression == BI_RLE8)
- {
- /* copy existing bitmap from destination dc */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
- else
- NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
- ROP, 0);
- }
-
- pDC = DC_LockDc(hdcMem);
- if (pDC != NULL)
- {
- /* Note BitsInfo->bmiHeader.biHeight is the number of scanline,
- * if it negitve we getting to many scanline for scanline is UINT not
- * a INT, so we need make the negtive value to positve and that make the
- * count correct for negtive bitmap, TODO : we need testcase for this api */
- IntSetDIBits(pDC, hBitmap, 0, abs(BitsInfo->bmiHeader.biHeight), Bits,
- BitsInfo, Usage);
-
- DC_UnlockDc(pDC);
- }
-
-
- /* Origin for DIBitmap may be bottom left (positive biHeight) or top
- left (negative biHeight) */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- ROP, 0, 0);
else
- NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, ROP, 0);
+ {
+ /* slow path - need to use StretchBlt */
+ HBITMAP hOldBitmap;
+ HDC hdcMem;
+ PVOID pvBits;
- /* cleanup */
- if (hPal)
- GdiSelectPalette(hdcMem, hPal, FALSE);
+ hdcMem = NtGdiCreateCompatibleDC( hDC );
+ hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0);
+ if(!hBitmap)
+ {
+ DPRINT1("Error, failed to create a DIB section\n");
+ NtGdiDeleteObjectApp(hdcMem);
+ goto cleanup;
+ }
+ RtlCopyMemory(pvBits, safeBits, cjMaxBits);
+ hOldBitmap = NtGdiSelectBitmap( hdcMem, hBitmap );
- if (hOldBitmap)
- NtGdiSelectBitmap(hdcMem, hOldBitmap);
-
- NtGdiDeleteObjectApp(hdcMem);
-
- GreDeleteObject(hBitmap);
-
- return SrcHeight;
+ /* Origin for DIBitmap may be bottom left (positive biHeight) or top
+ left (negative biHeight) */
+ ret = NtGdiStretchBlt( hDC, XDest, YDest, DestWidth, DestHeight,
+ hdcMem, XSrc, abs(height) - SrcHeight - YSrc,
+ SrcWidth, SrcHeight, ROP, 0 );
+
+ if(ret)
+ ret = SrcHeight;
+ NtGdiSelectBitmap( hdcMem, hOldBitmap );
+ NtGdiDeleteObjectApp( hdcMem );
+ GreDeleteObject( hBitmap );
+ }
+cleanup:
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ DC_UnlockDc(pdc);
+ return ret;
}
@@ -1137,40 +1161,19 @@ IntCreateDIBitmap(
else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
else
{
- if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- const RGBQUAD *rgb = data->bmiColors;
- DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
+ const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
+ DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
- // Check if the first color of the colormap is black
- if ((col == RGB(0, 0, 0)))
- {
- rgb++;
- col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
-
- // If the second color is white, create a monochrome bitmap
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- else fColor = TRUE;
- }
- else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ // Check if the first color of the colormap is black
+ if ((col == RGB(0, 0, 0)))
{
- RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
- DWORD col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
+ rgb++;
+ col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
- if ((col == RGB(0,0,0)))
- {
- rgb++;
- col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- else fColor = TRUE;
- }
- else
- {
- DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize);
- return 0;
+ // If the second color is white, create a monochrome bitmap
+ fColor = (col != RGB(0xff,0xff,0xff));
}
+ else fColor = TRUE;
}
// Now create the bitmap
@@ -1180,11 +1183,11 @@ IntCreateDIBitmap(
}
else
{
- handle = IntGdiCreateBitmap(width,
- height,
- 1,
- 1,
- NULL);
+ handle = GreCreateBitmap(width,
+ height,
+ 1,
+ 1,
+ NULL);
}
if (height < 0)
@@ -1214,72 +1217,106 @@ NtGdiCreateDIBitmapInternal(
IN UINT cjMaxBits,
IN FLONG fl,
IN HANDLE hcmXform)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PBYTE safeBits = NULL;
+ HBITMAP hbmResult = NULL;
+
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+ }
+
+ _SEH2_TRY
+ {
+ if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ ProbeForRead(pjInit, cjMaxBits, 1);
+ RtlCopyMemory(safeBits, pjInit, cjMaxBits);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ goto cleanup;
+ }
+
+ hbmResult = GreCreateDIBitmapInternal(hDc,
+ cx,
+ cy,
+ fInit,
+ safeBits,
+ pbmi,
+ iUsage,
+ fl,
+ hcmXform);
+
+cleanup:
+ if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB);
+ return hbmResult;
+}
+
+HBITMAP
+FASTCALL
+GreCreateDIBitmapInternal(
+ IN HDC hDc,
+ IN INT cx,
+ IN INT cy,
+ IN DWORD fInit,
+ IN OPTIONAL LPBYTE pjInit,
+ IN OPTIONAL PBITMAPINFO pbmi,
+ IN DWORD iUsage,
+ IN FLONG fl,
+ IN HANDLE hcmXform)
{
PDC Dc;
HBITMAP Bmp;
- UINT bpp;
+ WORD bpp;
+ HDC hdcDest;
- if (!hDc) // CreateBitmap
+ if (!hDc) /* 1bpp monochrome bitmap */
{ // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
- hDc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
- if (!hDc)
+ hdcDest = NtGdiCreateCompatibleDC(0);
+ if(!hdcDest)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
-
- Dc = DC_LockDc(hDc);
- if (!Dc)
- {
- NtGdiDeleteObjectApp(hDc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return NULL;
- }
- bpp = 1;
- Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
-
- DC_UnlockDc(Dc);
- NtGdiDeleteObjectApp(hDc);
}
- else // CreateCompatibleBitmap
+ else
{
- Dc = DC_LockDc(hDc);
- if (!Dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return NULL;
- }
- /* pbmi == null
- First create an un-initialised bitmap. The depth of the bitmap
- should match that of the hdc and not that supplied in bmih.
- */
- if (pbmi)
- bpp = pbmi->bmiHeader.biBitCount;
- else
- {
- if (Dc->dctype != DC_TYPE_MEMORY)
- bpp = IntGdiGetDeviceCaps(Dc, BITSPIXEL);
- else
- {
- DIBSECTION dibs;
- INT Count;
- SURFACE *psurf = Dc->dclevel.pSurface;
- Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
- if (!Count)
- bpp = 1;
- else
- {
- if (Count == sizeof(BITMAP))
- /* A device-dependent bitmap is selected in the DC */
- bpp = dibs.dsBm.bmBitsPixel;
- else
- /* A DIB section is selected in the DC */
- bpp = dibs.dsBmih.biBitCount;
- }
- }
- }
- Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
- DC_UnlockDc(Dc);
+ hdcDest = hDc;
+ }
+
+ Dc = DC_LockDc(hdcDest);
+ if (!Dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return NULL;
+ }
+ /* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
+ * if bpp != 1 and ignore the real value that was passed */
+ if (pbmi)
+ bpp = pbmi->bmiHeader.biBitCount;
+ else
+ bpp = 0;
+ Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+ DC_UnlockDc(Dc);
+
+ if(!hDc)
+ {
+ NtGdiDeleteObjectApp(hdcDest);
}
return Bmp;
}
@@ -1291,7 +1328,7 @@ NtGdiCreateDIBSection(
IN HDC hDC,
IN OPTIONAL HANDLE hSection,
IN DWORD dwOffset,
- IN LPBITMAPINFO bmi,
+ IN BITMAPINFO* bmi,
IN DWORD Usage,
IN UINT cjHeader,
IN FLONG fl,
@@ -1301,9 +1338,28 @@ NtGdiCreateDIBSection(
HBITMAP hbitmap = 0;
DC *dc;
BOOL bDesktopDC = FALSE;
+ NTSTATUS Status = STATUS_SUCCESS;
if (!bmi) return hbitmap; // Make sure.
+ _SEH2_TRY
+ {
+ ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
+ ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, Usage), 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return NULL;
+ }
+
// If the reference hdc is null, take the desktop dc
if (hDC == 0)
{
@@ -1314,7 +1370,7 @@ NtGdiCreateDIBSection(
if ((dc = DC_LockDc(hDC)))
{
hbitmap = DIB_CreateDIBSection(dc,
- (BITMAPINFO*)bmi,
+ bmi,
Usage,
Bits,
hSection,
@@ -1337,7 +1393,7 @@ HBITMAP
APIENTRY
DIB_CreateDIBSection(
PDC dc,
- BITMAPINFO *bmi,
+ CONST BITMAPINFO *bmi,
UINT usage,
LPVOID *bits,
HANDLE section,
@@ -1347,17 +1403,15 @@ DIB_CreateDIBSection(
HBITMAP res = 0;
SURFACE *bmp = NULL;
void *mapBits = NULL;
+ HPALETTE hpal ;
// Fill BITMAP32 structure with DIB data
- BITMAPINFOHEADER *bi = &bmi->bmiHeader;
+ CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
INT effHeight;
ULONG totalSize;
BITMAP bm;
SIZEL Size;
- RGBQUAD *lpRGB;
HANDLE hSecure;
- DWORD dsBitfields[3] = {0};
- ULONG ColorCount;
DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
@@ -1373,7 +1427,7 @@ DIB_CreateDIBSection(
bm.bmType = 0;
bm.bmWidth = bi->biWidth;
bm.bmHeight = effHeight;
- bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
+ bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount);
bm.bmPlanes = bi->biPlanes;
bm.bmBitsPixel = bi->biBitCount;
@@ -1431,6 +1485,7 @@ DIB_CreateDIBSection(
{
offset = 0;
bm.bmBits = EngAllocUserMem(totalSize, 0);
+ if(!bm.bmBits) goto cleanup;
}
// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
@@ -1438,116 +1493,76 @@ DIB_CreateDIBSection(
if (usage == DIB_PAL_COLORS)
{
- lpRGB = DIB_MapPaletteColors(dc, bmi);
- ColorCount = bi->biClrUsed;
- if (ColorCount == 0)
- {
- ColorCount = 1 << bi->biBitCount;
- }
+ if(dc)
+ {
+ PPALETTE pdcPal ;
+ pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
+ hpal = DIB_MapPaletteColors(pdcPal, bmi);
+ PALETTE_UnlockPalette(pdcPal);
+ }
+ else
+ {
+ /* For DIB Brushes */
+ DPRINT1("FIXME : Unsupported DIB_PAL_COLORS without a DC to map colors.\n");
+ /* HACK */
+ hpal = (HPALETTE) 0xFFFFFFFF;
+ }
}
else
- {
- lpRGB = bmi->bmiColors;
- ColorCount = 1 << bi->biBitCount;
- }
+ {
+ hpal = BuildDIBPalette(bmi);
+ }
- /* Set dsBitfields values */
- if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
- {
- dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
- }
- else if (bi->biCompression == BI_RGB)
- {
- switch (bi->biBitCount)
- {
- case 15:
- case 16:
- dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB : 0x7c00;
- dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x03e0;
- dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x001f;
- break;
-
- case 24:
- case 32:
- dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB : 0xff0000;
- dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x00ff00;
- dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x0000ff;
- break;
- }
- }
- else
- {
- dsBitfields[0] = ((DWORD*)bmi->bmiColors)[0];
- dsBitfields[1] = ((DWORD*)bmi->bmiColors)[1];
- dsBitfields[2] = ((DWORD*)bmi->bmiColors)[2];
- }
+ if(!hpal)
+ {
+ DPRINT1("Error : Could not create a palette for the DIB.\n");
+ goto cleanup;
+ }
// Create Device Dependent Bitmap and add DIB pointer
Size.cx = bm.bmWidth;
Size.cy = abs(bm.bmHeight);
- res = IntCreateBitmap(Size,
- bm.bmWidthBytes,
- BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
- BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
- (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
- bm.bmBits);
+ res = GreCreateBitmapEx(bm.bmWidth,
+ abs(bm.bmHeight),
+ bm.bmWidthBytes,
+ BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
+ BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
+ (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
+ bi->biSizeImage,
+ bm.bmBits,
+ 0);
if (!res)
{
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return NULL;
+ goto cleanup;
}
bmp = SURFACE_LockSurface(res);
if (NULL == bmp)
{
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- GreDeleteObject(bmp);
- return NULL;
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ goto cleanup;
}
/* WINE NOTE: WINE makes use of a colormap, which is a color translation
table between the DIB and the X physical device. Obviously,
this is left out of the ReactOS implementation. Instead,
we call NtGdiSetDIBColorTable. */
- if (bi->biBitCount <= 8)
- {
- bi->biClrUsed = 1 << bi->biBitCount;
- }
- else
- {
- bi->biClrUsed = 0;
- }
-
bmp->hDIBSection = section;
bmp->hSecure = hSecure;
bmp->dwOffset = offset;
- bmp->flFlags = BITMAPOBJ_IS_APIBITMAP;
- bmp->dsBitfields[0] = dsBitfields[0];
- bmp->dsBitfields[1] = dsBitfields[1];
- bmp->dsBitfields[2] = dsBitfields[2];
- bmp->biClrUsed = bi->biClrUsed;
+ bmp->flags = API_BITMAP;
bmp->biClrImportant = bi->biClrImportant;
- if (bi->biClrUsed != 0)
- {
- bmp->hDIBPalette = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
- }
- else
- {
- bmp->hDIBPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
- dsBitfields[0],
- dsBitfields[1],
- dsBitfields[2]);
- }
+ /* HACK */
+ if(hpal != (HPALETTE)0xFFFFFFFF)
+ {
+ bmp->ppal = PALETTE_ShareLockPalette(hpal);
+ /* Lazy delete hpal, it will be freed at surface release */
+ GreDeleteObject(hpal);
+ }
// Clean up in case of errors
+cleanup:
if (!res || !bmp || !bm.bmBits)
{
DPRINT("got an error res=%08x, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
@@ -1574,11 +1589,6 @@ DIB_CreateDIBSection(
}
}
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
-
if (bmp)
{
SURFACE_UnlockSurface(bmp);
@@ -1594,15 +1604,39 @@ DIB_CreateDIBSection(
}
/***********************************************************************
- * DIB_GetDIBWidthBytes
+ * DIB_GetBitmapInfo
*
- * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
- * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
- * 11/16/1999 (RJJ) lifted from wine
+ * Get the info from a bitmap header.
+ * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
*/
-INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth)
+int
+FASTCALL
+DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+ LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
{
- return ((width * depth + 31) & ~31) >> 3;
+ if (header->biSize == sizeof(BITMAPCOREHEADER))
+ {
+ const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
+ *width = core->bcWidth;
+ *height = core->bcHeight;
+ *planes = core->bcPlanes;
+ *bpp = core->bcBitCount;
+ *compr = BI_RGB;
+ *size = 0;
+ return 0;
+ }
+ if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
+ {
+ *width = header->biWidth;
+ *height = header->biHeight;
+ *planes = header->biPlanes;
+ *bpp = header->biBitCount;
+ *compr = header->biCompression;
+ *size = header->biSizeImage;
+ return 1;
+ }
+ DPRINT1("(%d): unknown/wrong size for header\n", header->biSize );
+ return -1;
}
/***********************************************************************
@@ -1614,7 +1648,7 @@ INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth)
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
{
- return DIB_GetDIBWidthBytes(width, depth) * (height < 0 ? -height : height);
+ return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height);
}
/***********************************************************************
@@ -1626,90 +1660,93 @@ INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
{
- int colors;
+ unsigned int colors, size, masks = 0;
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
- BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
+ const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
- return sizeof(BITMAPCOREHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
+ return sizeof(BITMAPCOREHEADER) + colors *
+ ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
}
else /* assume BITMAPINFOHEADER */
{
colors = info->bmiHeader.biClrUsed;
- if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount;
- return sizeof(BITMAPINFOHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+ if (colors > 256) colors = 256;
+ if (!colors && (info->bmiHeader.biBitCount <= 8))
+ colors = 1 << info->bmiHeader.biBitCount;
+ if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
+ size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
+ return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
}
}
-RGBQUAD *
+HPALETTE
FASTCALL
-DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
+DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi)
{
- RGBQUAD *lpRGB;
+ PALETTEENTRY* ppalEntries;
ULONG nNumColors,i;
USHORT *lpIndex;
- PPALETTE palGDI;
+ HPALETTE hpal;
- palGDI = PALETTE_LockPalette(dc->dclevel.hpal);
-
- if (NULL == palGDI)
+ if (!(ppal->flFlags & PAL_INDEXED))
{
return NULL;
}
- if (palGDI->Mode != PAL_INDEXED)
- {
- PALETTE_UnlockPalette(palGDI);
- return NULL;
- }
-
nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
if (lpbmi->bmiHeader.biClrUsed)
{
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
}
- lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
- if (lpRGB == NULL)
+ /* Don't have more colors than we need */
+ nNumColors = min(ppal->NumColors, nNumColors);
+
+ ppalEntries = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * nNumColors, TAG_COLORMAP);
+ if (ppalEntries == NULL)
{
- PALETTE_UnlockPalette(palGDI);
+ DPRINT1("Could not allocate palette entries\n");
return NULL;
}
- lpIndex = (USHORT *)&lpbmi->bmiColors[0];
+ lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
for (i = 0; i < nNumColors; i++)
{
- if (*lpIndex < palGDI->NumColors)
+ if (*lpIndex < ppal->NumColors)
{
- lpRGB[i].rgbRed = palGDI->IndexedColors[*lpIndex].peRed;
- lpRGB[i].rgbGreen = palGDI->IndexedColors[*lpIndex].peGreen;
- lpRGB[i].rgbBlue = palGDI->IndexedColors[*lpIndex].peBlue;
+ ppalEntries[i] = ppal->IndexedColors[*lpIndex];
}
else
{
- lpRGB[i].rgbRed = 0;
- lpRGB[i].rgbGreen = 0;
- lpRGB[i].rgbBlue = 0;
+ ppalEntries[i].peRed = 0;
+ ppalEntries[i].peGreen = 0;
+ ppalEntries[i].peBlue = 0;
+ ppalEntries[i].peFlags = 0;
}
- lpRGB[i].rgbReserved = 0;
+
lpIndex++;
}
- PALETTE_UnlockPalette(palGDI);
- return lpRGB;
+ hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
+
+ ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
+
+ return hpal;
}
HPALETTE
FASTCALL
-BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
+BuildDIBPalette(CONST BITMAPINFO *bmi)
{
BYTE bits;
ULONG ColorCount;
- PALETTEENTRY *palEntries = NULL;
HPALETTE hPal;
- ULONG RedMask, GreenMask, BlueMask;
+ ULONG RedMask = 0, GreenMask = 0, BlueMask = 0;
+ PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize);
+ INT paletteType;
// Determine Bits Per Pixel
bits = bmi->bmiHeader.biBitCount;
@@ -1717,29 +1754,43 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
// Determine paletteType from Bits Per Pixel
if (bits <= 8)
{
- *paletteType = PAL_INDEXED;
+ paletteType = PAL_INDEXED;
RedMask = GreenMask = BlueMask = 0;
}
else if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
{
- *paletteType = PAL_BITFIELDS;
- RedMask = ((ULONG *)bmi->bmiColors)[0];
- GreenMask = ((ULONG *)bmi->bmiColors)[1];
- BlueMask = ((ULONG *)bmi->bmiColors)[2];
- }
- else if (bits < 24)
- {
- *paletteType = PAL_BITFIELDS;
- RedMask = 0x7c00;
- GreenMask = 0x03e0;
- BlueMask = 0x001f;
+ paletteType = PAL_BITFIELDS;
+ RedMask = pdwColors[0];
+ GreenMask = pdwColors[1];
+ BlueMask = pdwColors[2];
}
else
{
- *paletteType = PAL_BGR;
- RedMask = 0xff0000;
- GreenMask = 0x00ff00;
- BlueMask = 0x0000ff;
+ paletteType = PAL_BITFIELDS;
+ switch (bits)
+ {
+ case 15:
+ paletteType |= PAL_RGB16_555;
+ RedMask = 0x7C00;
+ GreenMask = 0x03E0;
+ BlueMask = 0x001F;
+ break;
+
+ case 16:
+ paletteType |= PAL_RGB16_565;
+ RedMask = 0xF800;
+ GreenMask = 0x07E0;
+ BlueMask = 0x001F;
+ break;
+
+ case 24:
+ case 32:
+ paletteType |= PAL_BGR;
+ RedMask = 0xFF0000;
+ GreenMask = 0x00FF00;
+ BlueMask = 0x0000FF;
+ break;
+ }
}
if (bmi->bmiHeader.biClrUsed == 0)
@@ -1751,18 +1802,96 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
ColorCount = bmi->bmiHeader.biClrUsed;
}
- if (PAL_INDEXED == *paletteType)
+ if (PAL_INDEXED == paletteType)
{
- hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors);
+ hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors);
}
else
{
- hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
- (ULONG*) palEntries,
+ hPal = PALETTE_AllocPalette(paletteType, 0,
+ NULL,
RedMask, GreenMask, BlueMask);
}
return hPal;
}
+/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
+ * or does nothing if it's already a BITMAPINFO (or V4 or V5) */
+BITMAPINFO*
+FASTCALL
+DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage)
+{
+ CONST BITMAPCOREINFO* pbmci = (BITMAPCOREINFO*)pbmi;
+ BITMAPINFO* pNewBmi ;
+ UINT numColors = 0, ColorsSize = 0;
+
+ if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi;
+ if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL;
+
+ if(pbmci->bmciHeader.bcBitCount <= 8)
+ {
+ numColors = 1 << pbmci->bmciHeader.bcBitCount;
+ if(Usage == DIB_PAL_COLORS)
+ {
+ ColorsSize = numColors * sizeof(WORD);
+ }
+ else
+ {
+ ColorsSize = numColors * sizeof(RGBQUAD);
+ }
+ }
+ else if (Usage == DIB_PAL_COLORS)
+ {
+ /* Invalid at high Res */
+ return NULL;
+ }
+
+ pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
+ if(!pNewBmi) return NULL;
+
+ RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize);
+
+ pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
+ pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
+ pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
+ pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
+ pNewBmi->bmiHeader.biCompression = BI_RGB ;
+ pNewBmi->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(pNewBmi->bmiHeader.biWidth,
+ pNewBmi->bmiHeader.biHeight,
+ pNewBmi->bmiHeader.biBitCount);
+
+ if(Usage == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
+ }
+ else
+ {
+ UINT i;
+ for(i=0; ibmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed;
+ pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen;
+ pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue;
+ }
+ }
+
+ return pNewBmi ;
+}
+
+/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
+VOID
+FASTCALL
+DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig)
+{
+ if(converted != orig)
+ ExFreePoolWithTag(converted, TAG_DIB);
+}
+
+
+
+
+
+
/* EOF */
diff --git a/subsystems/win32/win32k/objects/drawing.c b/subsystems/win32/win32k/objects/drawing.c
index 0cc9a23200d..adc6e9ccf29 100755
--- a/subsystems/win32/win32k/objects/drawing.c
+++ b/subsystems/win32/win32k/objects/drawing.c
@@ -64,14 +64,14 @@ typedef struct _Rect
} Rect, *PRect;
int FASTCALL IntFillRect(DC *dc, INT XLeft, INT YLeft, INT Width, INT Height, PBRUSH pbrush, BOOL Pen);
-int FASTCALL app_fill_rect(DC *dc, Rect r, PBRUSH pbrush, BOOL Pen);
+//int FASTCALL app_fill_rect(DC *dc, Rect r, PBRUSH pbrush, BOOL Pen);
static
POINT
INTERNAL_CALL
app_new_point(int x, int y)
{
- POINT p;
+ POINT p;
p.x = x;
p.y = y;
return p;
@@ -332,7 +332,7 @@ app_draw_ellipse(DC *g, Rect r, PBRUSH pbrush)
*
* The draw_arc algorithm is based on draw_ellipse, but unlike
* that algorithm is not symmetric in the general case, since
- * an angular portion is clipped from the shape.
+ * an angular portion is clipped from the shape.
* This clipping is performed by keeping track of two hypothetical
* lines joining the centre point to the enclosing rectangle,
* at the angles start_angle and end_angle, using a line-intersection
@@ -376,7 +376,7 @@ app_fill_arc_rect(DC *g,
rise2 = p2.y - p0.y;
run2 = p2.x - p0.x;
- if (r.y <= p0.y) //
+ if (r.y <= p0.y) //
{
/* in top half of arc ellipse */
@@ -599,7 +599,7 @@ app_fill_arc_rect(DC *g,
* between an outer and inner ellipse, and also the draw_arc and
* fill_arc operations which additionally clip drawing between
* a start_angle and an end_angle.
- *
+ *
*/
static
int
@@ -912,7 +912,7 @@ app_fill_arc(DC *g, Rect r, int start_angle, int end_angle, PBRUSH pbrush, BOOL
r1.height = r1.y+r1.height-r2.y;
r1.y = r2.y;
while (r1.height > 0) {
- result &= app_fill_arc_rect(g,
+ result &= app_fill_arc_rect(g,
rect(r1.x, r1.y, r1.width, 1),
p0, p1, p2, start_angle, end_angle, pbrush, FALSE);
r1.y += 1;
@@ -1273,7 +1273,7 @@ IntFillArc( PDC dc,
pdcattr = dc->pdcattr;
pbrush = BRUSH_LockBrush(pdcattr->hbrush);
- if (!pbrush)
+ if (!pbrush)
{
DPRINT1("FillArc Fail\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
@@ -1285,7 +1285,7 @@ IntFillArc( PDC dc,
(dc->dclevel.flPath & DCPATH_CLOCKWISE) ? -Start : -End,
pbrush, Chord);
- BRUSH_UnlockBrush(pbrush);
+ BRUSH_UnlockBrush(pbrush);
return ret;
}
@@ -1329,7 +1329,7 @@ IntFillEllipse( PDC dc,
INT XLeft,
INT YLeft,
INT Width,
- INT Height,
+ INT Height,
PBRUSH pbrush)
{
return (BOOL)app_fill_ellipse(dc, rect( XLeft, YLeft, Width, Height), pbrush);
@@ -1343,7 +1343,7 @@ IntFillRoundRect( PDC dc,
INT Right,
INT Bottom,
INT Wellipse,
- INT Hellipse,
+ INT Hellipse,
PBRUSH pbrush)
{
Rect r;
@@ -1385,7 +1385,7 @@ IntFillRoundRect( PDC dc,
270, 360, pbrush,FALSE);
app_fill_arc(dc, rect(r.x+r.width-rx-rx, r.y, rx+rx, ry+ry),
- 0, 90, pbrush,FALSE);
+ 0, 90, pbrush,FALSE);
}
if (Wellipse < r.width)
{
@@ -1419,7 +1419,7 @@ IntDrawRoundRect( PDC dc,
r = rect( Left, Top, abs(Right-Left), abs(Bottom-Top));
rx = Wellipse/2;
ry = Hellipse/2;
-
+
if (Wellipse > r.width)
{
if (Hellipse > r.height) // > W > H
@@ -1437,7 +1437,7 @@ IntDrawRoundRect( PDC dc,
app_draw_arc(dc, rect(r.x, r.y, Wellipse - 1, r.height - 1),
90, 270, pbrushPen, FALSE);
app_draw_arc(dc, rect(Right - Wellipse, r.y, Wellipse - 1, r.height - 1),
- 270, 90, pbrushPen, FALSE);
+ 270, 90, pbrushPen, FALSE);
}
else // < W < H
{
diff --git a/subsystems/win32/win32k/objects/fillshap.c b/subsystems/win32/win32k/objects/fillshap.c
index 327b628ed30..7779de4313f 100644
--- a/subsystems/win32/win32k/objects/fillshap.c
+++ b/subsystems/win32/win32k/objects/fillshap.c
@@ -110,7 +110,7 @@ IntGdiPolygon(PDC dc,
psurf,
&dc->eboFill.BrushObject,
Points,
- Count,
+ Count,
DestRect,
&BrushOrigin);
}
@@ -271,15 +271,15 @@ NtGdiEllipse(
}
if (!PenWidth) PenWidth = 1;
- pbrush->ptPenWidth.x = PenWidth;
+ pbrush->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.right = Right;
RectBounds.top = Top;
RectBounds.bottom = Bottom;
-
+
IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
-
+
RectBounds.left += dc->ptlDCOrig.x;
RectBounds.right += dc->ptlDCOrig.x;
RectBounds.top += dc->ptlDCOrig.y;
@@ -298,7 +298,7 @@ NtGdiEllipse(
CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2);
pFillBrushObj = BRUSH_LockBrush(pdcattr->hbrush);
- if (NULL == pFillBrushObj)
+ if (NULL == pFillBrushObj)
{
DPRINT1("FillEllipse Fail\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
@@ -478,6 +478,15 @@ NtGdiPolyPolyDraw( IN HDC hDC,
return TRUE;
}
+ DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+ NULL, dc->rosdc.CombinedClip->rclBounds);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
/* Perform the actual work */
switch (iFunc)
{
@@ -502,6 +511,7 @@ NtGdiPolyPolyDraw( IN HDC hDC,
}
/* Cleanup and return */
+ DC_vFinishBlit(dc, NULL);
DC_UnlockDc(dc);
ExFreePool(pTemp);
@@ -529,19 +539,6 @@ IntRectangle(PDC dc,
pdcattr = dc->pdcattr;
- /* Do we rotate or shear? */
- if (!(dc->dclevel.mxWorldToDevice.flAccel & MX_SCALE))
- {
-
- POINTL DestCoords[4];
- ULONG PolyCounts = 4;
- DestCoords[0].x = DestCoords[3].x = LeftRect;
- DestCoords[0].y = DestCoords[1].y = TopRect;
- DestCoords[1].x = DestCoords[2].x = RightRect;
- DestCoords[2].y = DestCoords[3].y = BottomRect;
- // Use IntGdiPolyPolygon so to support PATH.
- return IntGdiPolyPolygon(dc, DestCoords, &PolyCounts, 1);
- }
// Rectangle Path only.
if ( PATH_IsPathOpen(dc->dclevel) )
{
@@ -567,6 +564,8 @@ IntRectangle(PDC dc,
DestRect.bottom--;
}
+ DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
+
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
DC_vUpdateFillBrush(dc);
@@ -580,6 +579,7 @@ IntRectangle(PDC dc,
ret = FALSE;
goto cleanup;
}
+
psurf = dc->dclevel.pSurface;
if (!psurf)
{
@@ -645,6 +645,8 @@ IntRectangle(PDC dc,
}
cleanup:
+ DC_vFinishBlit(dc, NULL);
+
/* Move current position in DC?
MSDN: The current position is neither used nor updated by Rectangle. */
@@ -675,8 +677,25 @@ NtGdiRectangle(HDC hDC,
return TRUE;
}
- ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
- DC_UnlockDc ( dc );
+ /* Do we rotate or shear? */
+ if (!(dc->dclevel.mxWorldToDevice.flAccel & MX_SCALE))
+ {
+ POINTL DestCoords[4];
+ ULONG PolyCounts = 4;
+
+ DestCoords[0].x = DestCoords[3].x = LeftRect;
+ DestCoords[0].y = DestCoords[1].y = TopRect;
+ DestCoords[1].x = DestCoords[2].x = RightRect;
+ DestCoords[2].y = DestCoords[3].y = BottomRect;
+ // Use IntGdiPolyPolygon so to support PATH.
+ ret = IntGdiPolyPolygon(dc, DestCoords, &PolyCounts, 1);
+ }
+ else
+ {
+ ret = IntRectangle(dc, LeftRect, TopRect, RightRect, BottomRect );
+ }
+
+ DC_UnlockDc(dc);
return ret;
}
@@ -750,7 +769,7 @@ IntRoundRect(
}
if (!PenWidth) PenWidth = 1;
- pbrushLine->ptPenWidth.x = PenWidth;
+ pbrushLine->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.top = Top;
@@ -765,12 +784,12 @@ IntRoundRect(
RectBounds.bottom += dc->ptlDCOrig.y;
pbrushFill = BRUSH_LockBrush(pdcattr->hbrush);
- if (NULL == pbrushFill)
+ if (NULL == pbrushFill)
{
DPRINT1("FillRound Fail\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
ret = FALSE;
- }
+ }
else
{
RtlCopyMemory(&brushTemp, pbrushFill, sizeof(brushTemp));
@@ -849,16 +868,14 @@ GreGradientFill(
{
PDC pdc;
SURFACE *psurf;
- PPALETTE ppal;
EXLATEOBJ exlo;
RECTL rclExtent;
POINTL ptlDitherOrg;
ULONG i;
BOOL bRet;
- HPALETTE hDestPalette;
- /* Check parameters */
- if (ulMode == GRADIENT_FILL_TRIANGLE)
+ /* check parameters */
+ if (ulMode & GRADIENT_FILL_TRIANGLE)
{
PGRADIENT_TRIANGLE pTriangle = (PGRADIENT_TRIANGLE)pMesh;
@@ -888,13 +905,13 @@ GreGradientFill(
/* Lock the output DC */
pdc = DC_LockDc(hdc);
- if (!pdc)
+ if(!pdc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
- if (pdc->dctype == DC_TYPE_INFO)
+ if(pdc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(pdc);
/* Yes, Windows really returns TRUE in this case */
@@ -902,11 +919,11 @@ GreGradientFill(
}
psurf = pdc->dclevel.pSurface;
- if (!psurf)
+ if(!psurf)
{
/* Memory DC with no surface selected */
DC_UnlockDc(pdc);
- return TRUE; // CHECKME
+ return TRUE; //CHECKME
}
/* calculate extent */
@@ -919,8 +936,8 @@ GreGradientFill(
rclExtent.top = min(rclExtent.top, (pVertex + i)->y);
rclExtent.bottom = max(rclExtent.bottom, (pVertex + i)->y);
}
-
IntLPtoDP(pdc, (LPPOINT)&rclExtent, 2);
+
rclExtent.left += pdc->ptlDCOrig.x;
rclExtent.right += pdc->ptlDCOrig.x;
rclExtent.top += pdc->ptlDCOrig.y;
@@ -928,33 +945,29 @@ GreGradientFill(
ptlDitherOrg.x = ptlDitherOrg.y = 0;
IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1);
+
ptlDitherOrg.x += pdc->ptlDCOrig.x;
ptlDitherOrg.y += pdc->ptlDCOrig.y;
- hDestPalette = psurf->hDIBPalette;
- if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
-
- ppal = PALETTE_LockPalette(hDestPalette);
- EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0);
ASSERT(pdc->rosdc.CombinedClip);
+ DC_vPrepareDCsForBlit(pdc, rclExtent, NULL, rclExtent);
+
bRet = IntEngGradientFill(&psurf->SurfObj,
- pdc->rosdc.CombinedClip,
- &exlo.xlo,
- pVertex,
- nVertex,
- pMesh,
- nMesh,
- &rclExtent,
- &ptlDitherOrg,
- ulMode);
+ pdc->rosdc.CombinedClip,
+ &exlo.xlo,
+ pVertex,
+ nVertex,
+ pMesh,
+ nMesh,
+ &rclExtent,
+ &ptlDitherOrg,
+ ulMode);
EXLATEOBJ_vCleanup(&exlo);
-
- if (ppal)
- PALETTE_UnlockPalette(ppal);
-
+ DC_vFinishBlit(pdc, NULL);
DC_UnlockDc(pdc);
return bRet;
@@ -996,16 +1009,16 @@ NtGdiGradientFill(
return FALSE;
}
- cbVertex = nVertex * sizeof(TRIVERTEX);
- if (cbVertex + cbMesh <= cbVertex)
+ cbVertex = nVertex * sizeof(TRIVERTEX) ;
+ if(cbVertex + cbMesh <= cbVertex)
{
/* Overflow */
- return FALSE;
+ return FALSE ;
}
/* Allocate a kernel mode buffer */
SafeVertex = ExAllocatePoolWithTag(PagedPool, cbVertex + cbMesh, TAG_SHAPE);
- if (!SafeVertex)
+ if(!SafeVertex)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
@@ -1048,8 +1061,6 @@ NtGdiExtFloodFill(
PDC dc;
PDC_ATTR pdcattr;
SURFACE *psurf = NULL;
- HPALETTE hpal;
- PPALETTE ppal;
EXLATEOBJ exlo;
BOOL Ret = FALSE;
RECTL DestRect;
@@ -1094,11 +1105,7 @@ NtGdiExtFloodFill(
goto cleanup;
}
- hpal = dc->dclevel.pSurface->hDIBPalette;
- if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault;
- ppal = PALETTE_ShareLockPalette(hpal);
-
- EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0xffffff, 0);
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0xffffff, 0);
/* Only solid fills supported for now
* How to support pattern brushes and non standard surfaces (not offering dib functions):
@@ -1108,7 +1115,6 @@ NtGdiExtFloodFill(
Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);
EXLATEOBJ_vCleanup(&exlo);
- PALETTE_ShareUnlockPalette(ppal);
cleanup:
DC_UnlockDc(dc);
diff --git a/subsystems/win32/win32k/objects/freetype.c b/subsystems/win32/win32k/objects/freetype.c
index 7b44fa384d7..f4d17cc5f8c 100644
--- a/subsystems/win32/win32k/objects/freetype.c
+++ b/subsystems/win32/win32k/objects/freetype.c
@@ -2249,7 +2249,7 @@ TextIntGetTextExtentPoint(PDC dc,
Size->cx = (TotalWidth + 32) >> 6;
Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight);
- Size->cy = EngMulDiv(Size->cy, IntGdiGetDeviceCaps(dc, LOGPIXELSY), 72);
+ Size->cy = EngMulDiv(Size->cy, dc->ppdev->gdiinfo.ulLogPixelsY, 72);
return TRUE;
}
@@ -3160,7 +3160,7 @@ GreExtTextOutW(
LONGLONG TextLeft, RealXStart;
ULONG TextTop, previous, BackgroundLeft;
FT_Bool use_kerning;
- RECTL DestRect, MaskRect;
+ RECTL DestRect, MaskRect, DummyRect = {0, 0, 0, 0};
POINTL SourcePoint, BrushOrigin;
HBITMAP HSourceGlyph;
SURFOBJ *SourceGlyphSurf;
@@ -3175,8 +3175,6 @@ GreExtTextOutW(
BOOLEAN Render;
POINT Start;
BOOL DoBreak = FALSE;
- HPALETTE hDestPalette;
- PPALETTE ppalDst;
USHORT DxShift;
// TODO: Write test-cases to exactly match real Windows in different
@@ -3196,9 +3194,6 @@ GreExtTextOutW(
pdcattr = dc->pdcattr;
- if (pdcattr->ulDirty_ & DIRTY_TEXT)
- DC_vUpdateTextBrush(dc);
-
if ((fuOptions & ETO_OPAQUE) || pdcattr->jBkMode == OPAQUE)
{
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
@@ -3232,13 +3227,6 @@ GreExtTextOutW(
IntLPtoDP(dc, (POINT *)lprc, 2);
}
- psurf = dc->dclevel.pSurface;
- if (!psurf)
- {
- goto fail;
- }
- SurfObj = &psurf->SurfObj;
-
Start.x = XStart;
Start.y = YStart;
IntLPtoDP(dc, &Start, 1);
@@ -3267,8 +3255,13 @@ GreExtTextOutW(
DestRect.right += dc->ptlDCOrig.x;
DestRect.bottom += dc->ptlDCOrig.y;
+ DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
+
+ if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
+ DC_vUpdateBackgroundBrush(dc);
+
IntEngBitBlt(
- &psurf->SurfObj,
+ &dc->dclevel.pSurface->SurfObj,
NULL,
NULL,
dc->rosdc.CombinedClip,
@@ -3280,6 +3273,7 @@ GreExtTextOutW(
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
fuOptions &= ~ETO_OPAQUE;
+ DC_vFinishBlit(dc, NULL);
}
else
{
@@ -3444,19 +3438,24 @@ GreExtTextOutW(
TextTop = YStart;
BackgroundLeft = (RealXStart + 32) >> 6;
- /* Create the xlateobj */
- hDestPalette = psurf->hDIBPalette;
- if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
- ppalDst = PALETTE_LockPalette(hDestPalette);
- EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0);
- EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0);
- PALETTE_UnlockPalette(ppalDst);
+ /* Lock blit with a dummy rect */
+ DC_vPrepareDCsForBlit(dc, DummyRect, NULL, DummyRect);
+ psurf = dc->dclevel.pSurface ;
+ SurfObj = &psurf->SurfObj ;
+
+ EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0);
+
+ if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND))
+ DC_vUpdateBackgroundBrush(dc) ;
+
+ if(dc->pdcattr->ulDirty_ & DIRTY_TEXT)
+ DC_vUpdateTextBrush(dc) ;
/*
* The main rendering loop.
*/
-
for (i = 0; i < Count; i++)
{
if (fuOptions & ETO_GLYPH_INDEX)
@@ -3505,6 +3504,7 @@ GreExtTextOutW(
DestRect.right = (TextLeft + (realglyph->root.advance.x >> 10) + 32) >> 6;
DestRect.top = TextTop + yoff - ((face->size->metrics.ascender + 32) >> 6);
DestRect.bottom = TextTop + yoff + ((32 - face->size->metrics.descender) >> 6);
+ MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
IntEngBitBlt(
&psurf->SurfObj,
NULL,
@@ -3517,7 +3517,9 @@ GreExtTextOutW(
&dc->eboBackground.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
+ MouseSafetyOnDrawEnd(dc->ppdev);
BackgroundLeft = DestRect.right;
+
}
DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left;
@@ -3570,7 +3572,7 @@ GreExtTextOutW(
DestRect.right = lprc->right + dc->ptlDCOrig.x;
DoBreak = TRUE;
}
-
+ MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
IntEngMaskBlt(
SurfObj,
SourceGlyphSurf,
@@ -3581,6 +3583,7 @@ GreExtTextOutW(
(PPOINTL)&MaskRect,
&dc->eboText.BrushObject,
&BrushOrigin);
+ MouseSafetyOnDrawEnd(dc->ppdev) ;
EngUnlockSurface(SourceGlyphSurf);
EngDeleteSurface((HSURF)HSourceGlyph);
@@ -3610,9 +3613,9 @@ GreExtTextOutW(
String++;
}
-
IntUnLockFreeType;
+ DC_vFinishBlit(dc, NULL) ;
EXLATEOBJ_vCleanup(&exloRGB2Dst);
EXLATEOBJ_vCleanup(&exloDst2RGB);
if (TextObj != NULL)
@@ -3628,6 +3631,7 @@ fail2:
fail:
if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj);
+
DC_UnlockDc(dc);
return FALSE;
diff --git a/subsystems/win32/win32k/objects/gdibatch.c b/subsystems/win32/win32k/objects/gdibatch.c
index 5a367250409..7ddb1fa24e1 100644
--- a/subsystems/win32/win32k/objects/gdibatch.c
+++ b/subsystems/win32/win32k/objects/gdibatch.c
@@ -51,8 +51,9 @@ SynchonizeDriver(FLONG Flags)
Flags = DSS_TIMER_EVENT;
Device = IntEnumHDev();
-
- SurfObj = EngLockSurface( Device->pSurface );
+// UNIMPLEMENTED;
+//ASSERT(FALSE);
+ SurfObj = 0;// EngLockSurface( Device->pSurface );
if(!SurfObj) return;
DoDeviceSync( SurfObj, NULL, Flags);
EngUnlockSurface(SurfObj);
diff --git a/subsystems/win32/win32k/objects/gdiobj.c b/subsystems/win32/win32k/objects/gdiobj.c
index 66937461359..5eb43dd6feb 100644
--- a/subsystems/win32/win32k/objects/gdiobj.c
+++ b/subsystems/win32/win32k/objects/gdiobj.c
@@ -81,6 +81,8 @@ OBJ_TYPE_INFO ObjTypeInfo[BASE_OBJTYPE_COUNT] =
};
static LARGE_INTEGER ShortDelay;
+PGDI_HANDLE_TABLE GdiHandleTable = NULL;
+PSECTION_OBJECT GdiTableSection = NULL;
/** INTERNAL FUNCTIONS ********************************************************/
@@ -151,7 +153,9 @@ GDI_CleanupDummy(PVOID ObjectBody)
* Allocate GDI object table.
* \param Size - number of entries in the object table.
*/
-PGDI_HANDLE_TABLE INTERNAL_CALL
+INIT_FUNCTION
+PGDI_HANDLE_TABLE
+INTERNAL_CALL
GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject)
{
PGDI_HANDLE_TABLE HandleTable = NULL;
@@ -221,6 +225,23 @@ GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject)
return HandleTable;
}
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitGdiHandleTable()
+{
+ /* Create the GDI handle table */
+ GdiHandleTable = GDIOBJ_iAllocHandleTable(&GdiTableSection);
+ if (GdiHandleTable == NULL)
+ {
+ DPRINT1("Failed to initialize the GDI handle table.\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
static void FASTCALL
LockErrorDebugOutput(HGDIOBJ hObj, PGDI_TABLE_ENTRY Entry, LPSTR Function)
{
@@ -635,10 +656,7 @@ LockHandle:
PEPROCESS OldProcess;
Object->BaseFlags |= BASEFLAG_READY_TO_DIE;
DPRINT("Object %p, ulShareCount = %d\n", Object->hHmgr, Object->ulShareCount);
- //GDIDBG_TRACECALLER();
- //GDIDBG_TRACESHARELOCKER(GDI_HANDLE_GET_INDEX(hObj));
- /* Set NULL owner. This will permit an other process to kill the object
- * Do the work here to avoid race conditions */
+ /* Set NULL owner. Do the work here to avoid race conditions */
Status = PsLookupProcessByProcessId((HANDLE)((ULONG_PTR)PrevProcId & ~0x1), &OldProcess);
if (NT_SUCCESS(Status))
{
@@ -649,7 +667,7 @@ LockHandle:
}
ObDereferenceObject(OldProcess);
}
- (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
+ (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, NULL);
/* Don't wait on shared locks */
return FALSE;
}
@@ -660,7 +678,7 @@ LockHandle:
*/
DPRINT1("Object->cExclusiveLock = %d\n", Object->cExclusiveLock);
GDIDBG_TRACECALLER();
- GDIDBG_TRACELOCKER(GDI_HANDLE_GET_INDEX(hObj));
+ GDIDBG_TRACELOCKER(hObj);
(void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
/* do not assert here for it will call again from dxg.sys it being call twice */
@@ -702,7 +720,7 @@ LockHandle:
}
DPRINT1("Type = 0x%lx, KernelData = 0x%p, ProcessId = 0x%p\n", Entry->Type, Entry->KernelData, Entry->ProcessId);
GDIDBG_TRACECALLER();
- GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj));
+ GDIDBG_TRACEALLOCATOR(hObj);
}
}
@@ -833,7 +851,7 @@ GreDeleteObject(HGDIOBJ hObject)
break;
case GDI_OBJECT_TYPE_DC:
- DC_FreeDcAttr(hObject);
+// DC_FreeDcAttr(hObject);
break;
}
@@ -970,12 +988,14 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
if(hObj == NULL)
return NULL ;
+ GDIDBG_INITLOOPTRACE();
+
HandleIndex = GDI_HANDLE_GET_INDEX(hObj);
HandleType = GDI_HANDLE_GET_TYPE(hObj);
HandleUpper = GDI_HANDLE_GET_UPPER(hObj);
/* Check that the handle index is valid. */
- if (HandleIndex >= GDI_HANDLE_COUNT)
+ if (HandleIndex >= GDI_HANDLE_COUNT )
return NULL;
Entry = &GdiHandleTable->Entries[HandleIndex];
@@ -1001,7 +1021,7 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
{
DPRINT1("Tried to lock object (0x%p) of wrong owner! ProcessId = %p, HandleProcessId = %p\n", hObj, ProcessId, HandleProcessId);
GDIDBG_TRACECALLER();
- GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj));
+ GDIDBG_TRACEALLOCATOR(hObj);
return NULL;
}
@@ -1077,6 +1097,7 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
/*
* The handle is currently locked, wait some time and try again.
*/
+ GDIDBG_TRACELOOP(hObj, PrevProcId, NULL);
DelayExecution();
continue;
@@ -1649,6 +1670,38 @@ GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process)
return MappedView;
}
+/* Locks 2 or 3 objects at a time */
+VOID
+INTERNAL_CALL
+GDIOBJ_LockMultipleObjs(ULONG ulCount,
+ IN HGDIOBJ* ahObj,
+ OUT PGDIOBJ* apObj)
+{
+ UINT auiIndices[3] = {0,1,2};
+ UINT i, tmp ;
+ BOOL bUnsorted = TRUE;
+
+ /* First is greatest */
+ while(bUnsorted)
+ {
+ bUnsorted = FALSE;
+ for(i=1; idcattr, pDC->pdcattr, sizeof(DC_ATTR));
+ DC_vFreeDcAttr(pDC);
DC_UnlockDc( pDC );
- DC_FreeDcAttr( hDC ); // Free the dcattr!
-
if (!DC_SetOwnership( hDC, NULL )) // This hDC is inaccessible!
return Ret;
}
diff --git a/subsystems/win32/win32k/objects/icm.c b/subsystems/win32/win32k/objects/icm.c
index f0d7ef72e7a..3dfe7d01d18 100644
--- a/subsystems/win32/win32k/objects/icm.c
+++ b/subsystems/win32/win32k/objects/icm.c
@@ -256,9 +256,9 @@ UpdateDeviceGammaRamp( HDEV hPDev )
palPtr = (PALOBJ*) palGDI;
if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE)
- palGDI->Mode |= PAL_GAMMACORRECTION;
+ palGDI->flFlags |= PAL_GAMMACORRECTION;
else
- palGDI->Mode &= ~PAL_GAMMACORRECTION;
+ palGDI->flFlags &= ~PAL_GAMMACORRECTION;
if (!(pGDev->flFlags & PDEV_DRIVER_PUNTED_CALL)) // No punting, we hook
{
diff --git a/subsystems/win32/win32k/objects/line.c b/subsystems/win32/win32k/objects/line.c
index 173b3f91b25..28ff28ae049 100644
--- a/subsystems/win32/win32k/objects/line.c
+++ b/subsystems/win32/win32k/objects/line.c
@@ -113,9 +113,6 @@ IntGdiLineTo(DC *dc,
}
else
{
- if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
- DC_vUpdateLineBrush(dc);
-
psurf = dc->dclevel.pSurface;
if (NULL == psurf)
{
@@ -250,6 +247,9 @@ IntGdiPolyline(DC *dc,
if (PATH_IsPathOpen(dc->dclevel))
return PATH_Polyline(dc, pt, Count);
+ DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+ NULL, dc->rosdc.CombinedClip->rclBounds);
+
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
DC_vUpdateFillBrush(dc);
@@ -295,6 +295,8 @@ IntGdiPolyline(DC *dc,
}
}
+ DC_vFinishBlit(dc, NULL);
+
return Ret;
}
@@ -376,6 +378,7 @@ NtGdiLineTo(HDC hDC,
{
DC *dc;
BOOL Ret;
+ RECT rcLockRect ;
dc = DC_LockDc(hDC);
if (!dc)
@@ -390,8 +393,28 @@ NtGdiLineTo(HDC hDC,
return TRUE;
}
+ rcLockRect.left = dc->pdcattr->ptlCurrent.x;
+ rcLockRect.top = dc->pdcattr->ptlCurrent.y;
+ rcLockRect.right = XEnd;
+ rcLockRect.bottom = YEnd;
+
+ IntLPtoDP(dc, &rcLockRect, 2);
+
+ /* The DCOrg is in device coordinates */
+ rcLockRect.left += dc->ptlDCOrig.x;
+ rcLockRect.top += dc->ptlDCOrig.y;
+ rcLockRect.right += dc->ptlDCOrig.x;
+ rcLockRect.bottom += dc->ptlDCOrig.y;
+
+ DC_vPrepareDCsForBlit(dc, rcLockRect, NULL, rcLockRect);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
Ret = IntGdiLineTo(dc, XEnd, YEnd);
+ DC_vFinishBlit(dc, NULL);
+
DC_UnlockDc(dc);
return Ret;
}
diff --git a/subsystems/win32/win32k/objects/palette.c b/subsystems/win32/win32k/objects/palette.c
index f031fd3b1ca..e930bc116f9 100644
--- a/subsystems/win32/win32k/objects/palette.c
+++ b/subsystems/win32/win32k/objects/palette.c
@@ -14,7 +14,8 @@
static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the pallete and restore it */
-PALETTE gpalRGB, gpalBGR, gpalMono;
+PALETTE gpalRGB, gpalBGR, gpalMono, gpalRGB555, gpalRGB565, *gppalDefault;
+PPALETTE appalSurfaceDefault[11];
const PALETTEENTRY g_sysPalTemplate[NB_RESERVED_COLORS] =
{
@@ -56,7 +57,10 @@ unsigned short GetNumberOfBits(unsigned int dwMask)
}
// Create the system palette
-HPALETTE FASTCALL PALETTE_Init(VOID)
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitPaletteImpl()
{
int i;
HPALETTE hpalette;
@@ -67,7 +71,7 @@ HPALETTE FASTCALL PALETTE_Init(VOID)
sizeof(LOGPALETTE) +
(NB_RESERVED_COLORS * sizeof(PALETTEENTRY)),
TAG_PALETTE);
- if (!palPtr) return FALSE;
+ if (!palPtr) return STATUS_NO_MEMORY;
palPtr->palVersion = 0x300;
palPtr->palNumEntries = NB_RESERVED_COLORS;
@@ -84,20 +88,53 @@ HPALETTE FASTCALL PALETTE_Init(VOID)
/* palette_size = visual->map_entries; */
- gpalRGB.Mode = PAL_RGB;
+ gpalRGB.flFlags = PAL_RGB;
gpalRGB.RedMask = RGB(0xFF, 0x00, 0x00);
gpalRGB.GreenMask = RGB(0x00, 0xFF, 0x00);
gpalRGB.BlueMask = RGB(0x00, 0x00, 0xFF);
+ gpalRGB.BaseObject.ulShareCount = 0;
+ gpalRGB.BaseObject.BaseFlags = 0 ;
- gpalBGR.Mode = PAL_BGR;
+ gpalBGR.flFlags = PAL_BGR;
gpalBGR.RedMask = RGB(0x00, 0x00, 0xFF);
gpalBGR.GreenMask = RGB(0x00, 0xFF, 0x00);
gpalBGR.BlueMask = RGB(0xFF, 0x00, 0x00);
+ gpalBGR.BaseObject.ulShareCount = 0;
+ gpalBGR.BaseObject.BaseFlags = 0 ;
+
+ gpalRGB555.flFlags = PAL_RGB16_555 | PAL_BITFIELDS;
+ gpalRGB555.RedMask = 0x7C00;
+ gpalRGB555.GreenMask = 0x3E0;
+ gpalRGB555.BlueMask = 0x1F;
+ gpalRGB555.BaseObject.ulShareCount = 0;
+ gpalRGB555.BaseObject.BaseFlags = 0 ;
+
+ gpalRGB565.flFlags = PAL_RGB16_565 | PAL_BITFIELDS;
+ gpalRGB565.RedMask = 0xF800;
+ gpalRGB565.GreenMask = 0x7E0;
+ gpalRGB565.BlueMask = 0x1F;
+ gpalRGB565.BaseObject.ulShareCount = 0;
+ gpalRGB565.BaseObject.BaseFlags = 0 ;
memset(&gpalMono, 0, sizeof(PALETTE));
- gpalMono.Mode = PAL_MONOCHROME;
+ gpalMono.flFlags = PAL_MONOCHROME;
+ gpalMono.BaseObject.ulShareCount = 0;
+ gpalMono.BaseObject.BaseFlags = 0 ;
- return hpalette;
+ /* Initialize default surface palettes */
+ gppalDefault = PALETTE_ShareLockPalette(hpalette);
+ appalSurfaceDefault[BMF_1BPP] = &gpalMono;
+ appalSurfaceDefault[BMF_4BPP] = gppalDefault;
+ appalSurfaceDefault[BMF_8BPP] = gppalDefault;
+ appalSurfaceDefault[BMF_16BPP] = &gpalRGB565;
+ appalSurfaceDefault[BMF_24BPP] = &gpalBGR;
+ appalSurfaceDefault[BMF_32BPP] = &gpalBGR;
+ appalSurfaceDefault[BMF_4RLE] = gppalDefault;
+ appalSurfaceDefault[BMF_8RLE] = gppalDefault;
+ appalSurfaceDefault[BMF_JPEG] = &gpalRGB;
+ appalSurfaceDefault[BMF_PNG] = &gpalRGB;
+
+ return STATUS_SUCCESS;
}
VOID FASTCALL PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, INT size)
@@ -128,7 +165,7 @@ PALETTE_AllocPalette(ULONG Mode,
NewPalette = PalGDI->BaseObject.hHmgr;
PalGDI->Self = NewPalette;
- PalGDI->Mode = Mode;
+ PalGDI->flFlags = Mode;
if (NULL != Colors)
{
@@ -144,20 +181,22 @@ PALETTE_AllocPalette(ULONG Mode,
RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(PALETTEENTRY) * NumColors);
}
- if (PAL_INDEXED == Mode)
+ if (Mode & PAL_INDEXED)
{
PalGDI->NumColors = NumColors;
}
- else if (PAL_BITFIELDS == Mode)
+ else if (Mode & PAL_BITFIELDS)
{
PalGDI->RedMask = Red;
PalGDI->GreenMask = Green;
PalGDI->BlueMask = Blue;
-
+
if (Red == 0x7c00 && Green == 0x3E0 && Blue == 0x1F)
- PalGDI->Mode |= PAL_RGB16_555;
+ PalGDI->flFlags |= PAL_RGB16_555;
else if (Red == 0xF800 && Green == 0x7E0 && Blue == 0x1F)
- PalGDI->Mode |= PAL_RGB16_565;
+ PalGDI->flFlags |= PAL_RGB16_565;
+ else if (Red == 0xFF0000 && Green == 0xFF00 && Blue == 0xFF)
+ PalGDI->flFlags |= PAL_BGR;
}
PALETTE_UnlockPalette(PalGDI);
@@ -183,7 +222,7 @@ PALETTE_AllocPaletteIndexedRGB(ULONG NumColors,
NewPalette = PalGDI->BaseObject.hHmgr;
PalGDI->Self = NewPalette;
- PalGDI->Mode = PAL_INDEXED;
+ PalGDI->flFlags = PAL_INDEXED;
PalGDI->IndexedColors = ExAllocatePoolWithTag(PagedPool,
sizeof(PALETTEENTRY) * NumColors,
@@ -287,7 +326,7 @@ ULONG
NTAPI
PALETTE_ulGetNearestIndex(PALETTE* ppal, ULONG ulColor)
{
- if (ppal->Mode & PAL_INDEXED) // use fl & PALINDEXED
+ if (ppal->flFlags & PAL_INDEXED) // use fl & PALINDEXED
return PALETTE_ulGetNearestPaletteIndex(ppal, ulColor);
else
return PALETTE_ulGetNearestBitFieldsIndex(ppal, ulColor);
@@ -299,19 +338,19 @@ PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors)
{
ASSERT(pulColors);
- if (ppal->Mode & PAL_INDEXED || ppal->Mode & PAL_RGB)
+ if (ppal->flFlags & PAL_INDEXED || ppal->flFlags & PAL_RGB)
{
pulColors[0] = RGB(0xFF, 0x00, 0x00);
pulColors[1] = RGB(0x00, 0xFF, 0x00);
pulColors[2] = RGB(0x00, 0x00, 0xFF);
}
- else if (ppal->Mode & PAL_BGR)
+ else if (ppal->flFlags & PAL_BGR)
{
pulColors[0] = RGB(0x00, 0x00, 0xFF);
pulColors[1] = RGB(0x00, 0xFF, 0x00);
pulColors[2] = RGB(0xFF, 0x00, 0x00);
}
- else if (ppal->Mode & PAL_BITFIELDS)
+ else if (ppal->flFlags & PAL_BITFIELDS)
{
pulColors[0] = ppal->RedMask;
pulColors[1] = ppal->GreenMask;
@@ -358,7 +397,7 @@ EngCreatePalette(
{
HPALETTE Palette;
- Palette = PALETTE_AllocPalette(Mode, NumColors, Colors, Red, Green, Blue);
+ Palette = PALETTE_AllocPalette(Mode, NumColors, Colors, Red, Green, Blue);
if (Palette != NULL)
{
GDIOBJ_SetOwnership(Palette, NULL);
@@ -399,7 +438,7 @@ PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors, ULONG *PaletteEntry
/* NOTE: PaletteEntry ULONGs are in the same order as PALETTEENTRY. */
RtlCopyMemory(PaletteEntry, PalGDI->IndexedColors + Start, sizeof(ULONG) * Colors);
- if (PalGDI->Mode & PAL_GAMMACORRECTION)
+ if (PalGDI->flFlags & PAL_GAMMACORRECTION)
ColorCorrection(PalGDI, (PPALETTEENTRY)PaletteEntry, Colors);
return Colors;
@@ -630,17 +669,17 @@ COLORREF APIENTRY NtGdiGetNearestColor(HDC hDC, COLORREF Color)
return nearest;
}
- if (palGDI->Mode & PAL_INDEXED)
+ if (palGDI->flFlags & PAL_INDEXED)
{
ULONG index;
index = PALETTE_ulGetNearestPaletteIndex(palGDI, Color);
nearest = PALETTE_ulGetRGBColorFromIndex(palGDI, index);
}
- else if (palGDI->Mode & PAL_RGB || palGDI->Mode & PAL_BGR)
+ else if (palGDI->flFlags & PAL_RGB || palGDI->flFlags & PAL_BGR)
{
nearest = Color;
}
- else if (palGDI->Mode & PAL_BITFIELDS)
+ else if (palGDI->flFlags & PAL_BITFIELDS)
{
RBits = 8 - GetNumberOfBits(palGDI->RedMask);
GBits = 8 - GetNumberOfBits(palGDI->GreenMask);
@@ -668,7 +707,7 @@ NtGdiGetNearestPaletteIndex(
if (ppal)
{
- if (ppal->Mode & PAL_INDEXED)
+ if (ppal->flFlags & PAL_INDEXED)
{
/* Return closest match for the given RGB color */
index = PALETTE_ulGetNearestPaletteIndex(ppal, crColor);
diff --git a/subsystems/win32/win32k/objects/path.c b/subsystems/win32/win32k/objects/path.c
index 04a1314719d..da4e31fa572 100644
--- a/subsystems/win32/win32k/objects/path.c
+++ b/subsystems/win32/win32k/objects/path.c
@@ -408,7 +408,7 @@ BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_wid
FLOAT_POINT ellCorners[2];
pPath = PATH_LockPath( dc->dclevel.hPath );
- if (!pPath) return FALSE;
+ if (!pPath) return FALSE;
/* Check that path is open */
if(pPath->state!=PATH_Open)
@@ -544,7 +544,7 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2,
if ( pPath->state != PATH_Open )
{
Ret = FALSE;
- goto ArcExit;
+ goto ArcExit;
}
/* Check for zero height / width */
@@ -697,7 +697,7 @@ PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints )
pPath = PATH_LockPath( dc->dclevel.hPath );
if (!pPath) return FALSE;
-
+
/* Check that path is open */
if ( pPath->state != PATH_Open )
{
@@ -805,7 +805,7 @@ PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints )
pPath = PATH_LockPath( dc->dclevel.hPath );
if (!pPath) return FALSE;
-
+
/* Check that path is open */
if ( pPath->state != PATH_Open )
{
@@ -1597,7 +1597,7 @@ PATH_WidenPath(DC *dc)
numStrokes++;
j = 0;
if (numStrokes == 1)
- pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
+ pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
else
{
pOldStrokes = pStrokes; // Save old pointer.
@@ -1627,7 +1627,7 @@ PATH_WidenPath(DC *dc)
}
}
- pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
+ pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
PATH_InitGdiPath(pNewPath);
pNewPath->state = PATH_Open;
@@ -2012,7 +2012,7 @@ PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
}
IntGdiCloseFigure( pPath );
- PATH_UnlockPath( pPath );
+ PATH_UnlockPath( pPath );
return TRUE;
}
@@ -2020,7 +2020,7 @@ PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
* PATH_ExtTextOut
*/
BOOL
-FASTCALL
+FASTCALL
PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc,
LPCWSTR str, UINT count, const INT *dx)
{
@@ -2210,7 +2210,7 @@ NtGdiCloseFigure(HDC hDC)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
- }
+ }
pPath = PATH_LockPath( pDc->dclevel.hPath );
if (!pPath)
{
@@ -2281,7 +2281,7 @@ NtGdiFillPath(HDC hDC)
PPATH pPath;
PDC_ATTR pdcattr;
PDC dc = DC_LockDc ( hDC );
-
+
if ( !dc )
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
@@ -2294,6 +2294,9 @@ NtGdiFillPath(HDC hDC)
return FALSE;
}
+ DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+ NULL, dc->rosdc.CombinedClip->rclBounds);
+
pdcattr = dc->pdcattr;
if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
@@ -2311,6 +2314,7 @@ NtGdiFillPath(HDC hDC)
}
PATH_UnlockPath( pPath );
+ DC_vFinishBlit(dc, NULL);
DC_UnlockDc ( dc );
return ret;
}
@@ -2328,7 +2332,7 @@ NtGdiFlattenPath(HDC hDC)
pDc = DC_LockDc(hDC);
if (!pDc)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
@@ -2572,6 +2576,9 @@ NtGdiStrokeAndFillPath(HDC hDC)
return FALSE;
}
+ DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
+ NULL, pDc->rosdc.CombinedClip->rclBounds);
+
pdcattr = pDc->pdcattr;
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
@@ -2585,6 +2592,7 @@ NtGdiStrokeAndFillPath(HDC hDC)
if (bRet) PATH_EmptyPath(pPath);
PATH_UnlockPath( pPath );
+ DC_vFinishBlit(pDc, NULL);
DC_UnlockDc(pDc);
return bRet;
}
@@ -2612,12 +2620,17 @@ NtGdiStrokePath(HDC hDC)
return FALSE;
}
+ DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
+ NULL, pDc->rosdc.CombinedClip->rclBounds);
+
pdcattr = pDc->pdcattr;
if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
DC_vUpdateLineBrush(pDc);
bRet = PATH_StrokePath(pDc, pPath);
+
+ DC_vFinishBlit(pDc, NULL);
PATH_EmptyPath(pPath);
PATH_UnlockPath( pPath );
@@ -2630,7 +2643,7 @@ APIENTRY
NtGdiWidenPath(HDC hDC)
{
BOOL Ret;
- PDC pdc = DC_LockDc ( hDC );
+ PDC pdc = DC_LockDc ( hDC );
if ( !pdc )
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
diff --git a/subsystems/win32/win32k/objects/pen.c b/subsystems/win32/win32k/objects/pen.c
index 8d02e9bdb0a..5884945c285 100644
--- a/subsystems/win32/win32k/objects/pen.c
+++ b/subsystems/win32/win32k/objects/pen.c
@@ -63,11 +63,11 @@ IntGdiExtCreatePen(
{
HPEN hPen;
PBRUSH pbrushPen;
- static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55};
- static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0};
- static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38};
- static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0};
- static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38};
+ static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55, 0};
+ static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0, 0};
+ static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38, 0};
+ static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0, 0};
+ static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38, 0};
dwWidth = abs(dwWidth);
@@ -125,27 +125,27 @@ IntGdiExtCreatePen(
case PS_ALTERNATE:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate);
break;
case PS_DOT:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot);
break;
case PS_DASH:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash);
break;
case PS_DASHDOT:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot);
break;
case PS_DASHDOTDOT:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot);
break;
case PS_INSIDEFRAME:
diff --git a/subsystems/win32/win32k/objects/region.c b/subsystems/win32/win32k/objects/region.c
index 03814d5db60..9a73ace548e 100644
--- a/subsystems/win32/win32k/objects/region.c
+++ b/subsystems/win32/win32k/objects/region.c
@@ -3687,7 +3687,7 @@ NtGdiGetRandomRgn(
else if (pDC->dclevel.prgnMeta) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.hHmgr;
break;
case SYSRGN:
- if (pDC->prgnVis) hSrc = ((PROSRGNDATA)pDC->prgnVis)->BaseObject.hHmgr;
+ if (pDC->prgnVis) hSrc = pDC->prgnVis->BaseObject.hHmgr;
break;
default:
hSrc = 0;
diff --git a/subsystems/win32/win32k/objects/stockobj.c b/subsystems/win32/win32k/objects/stockobj.c
index 5499a6fd956..02b07dfbf94 100644
--- a/subsystems/win32/win32k/objects/stockobj.c
+++ b/subsystems/win32/win32k/objects/stockobj.c
@@ -180,7 +180,7 @@ CreateStockObjects(void)
StockObjects[NULL_PEN] = IntCreateStockPen(NullPen.lopnStyle, NullPen.lopnWidth.x, BS_SOLID, NullPen.lopnColor);
StockObjects[20] = NULL; /* TODO: Unknown internal stock object */
- StockObjects[DEFAULT_BITMAP] = IntGdiCreateBitmap(1, 1, 1, 1, NULL);
+ StockObjects[DEFAULT_BITMAP] = GreCreateBitmap(1, 1, 1, 1, NULL);
(void) TextIntCreateFontIndirect(&OEMFixedFont, (HFONT*)&StockObjects[OEM_FIXED_FONT]);
(void) TextIntCreateFontIndirect(&AnsiFixedFont, (HFONT*)&StockObjects[ANSI_FIXED_FONT]);
@@ -190,7 +190,7 @@ CreateStockObjects(void)
(void) TextIntCreateFontIndirect(&SystemFixedFont, (HFONT*)&StockObjects[SYSTEM_FIXED_FONT]);
(void) TextIntCreateFontIndirect(&DefaultGuiFont, (HFONT*)&StockObjects[DEFAULT_GUI_FONT]);
- StockObjects[DEFAULT_PALETTE] = (HGDIOBJ)PALETTE_Init();
+ StockObjects[DEFAULT_PALETTE] = (HGDIOBJ)gppalDefault->BaseObject.hHmgr;
for (Object = 0; Object < NB_STOCK_OBJECTS; Object++)
{
diff --git a/subsystems/win32/win32k/pch.h b/subsystems/win32/win32k/pch.h
index 90075c80058..339918377a1 100644
--- a/subsystems/win32/win32k/pch.h
+++ b/subsystems/win32/win32k/pch.h
@@ -33,6 +33,9 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
#define PRECT PRECTL
#define LPRECT LPRECTL
#define LPCRECT LPCRECTL
+#define POINT POINTL
+#define LPPOINT PPOINTL
+#define PPOINT PPOINTL
#include
#include
diff --git a/subsystems/win32/win32k/stubs/stubs.c b/subsystems/win32/win32k/stubs/stubs.c
index 82a8555354a..7685c19ad99 100644
--- a/subsystems/win32/win32k/stubs/stubs.c
+++ b/subsystems/win32/win32k/stubs/stubs.c
@@ -150,18 +150,6 @@ EngFindResource(
return NULL;
}
-/*
- * @unimplemented
- */
-LPWSTR
-APIENTRY
-EngGetDriverName ( IN HDEV hdev )
-{
- // www.osr.com/ddk/graphics/gdifncs_2gx3.htm
- UNIMPLEMENTED;
- return NULL;
-}
-
/*
* @unimplemented
*/
diff --git a/subsystems/win32/win32k/win32k.rbuild b/subsystems/win32/win32k/win32k.rbuild
index eaefbff9ee0..0950f08d5ed 100644
--- a/subsystems/win32/win32k/win32k.rbuild
+++ b/subsystems/win32/win32k/win32k.rbuild
@@ -38,6 +38,7 @@
dib.c
floodfill.c
stretchblt.c
+ alphablend.c
@@ -69,13 +70,16 @@
gradient.c
+ ldevobj.c
lineto.c
mapping.c
mem.c
engmisc.c
mouse.c
paint.c
+ pdevobj.c
perfcnt.c
+ rlecomp.c
semaphor.c
sort.c
string.c
@@ -85,9 +89,6 @@
engwindow.c
xlate.c
-
- loader.c
-
dllmain.c