From c12e6bbcba92c6cfb2706dc5460f173730eb34a6 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 4 Sep 2006 13:13:42 +0000 Subject: [PATCH 002/488] * move reading / applying options out of console.dll * remove unused code * notify win32csr when a property has changed svn path=/trunk/; revision=23911 --- reactos/dll/win32/console/console.c | 134 +++++++++++------------ reactos/dll/win32/console/console.h | 6 +- reactos/dll/win32/console/en.rc | 2 +- reactos/dll/win32/console/options.c | 161 ---------------------------- 4 files changed, 74 insertions(+), 229 deletions(-) diff --git a/reactos/dll/win32/console/console.c b/reactos/dll/win32/console/console.c index f9c3b2fb652..e10e3bbb908 100644 --- a/reactos/dll/win32/console/console.c +++ b/reactos/dll/win32/console/console.c @@ -60,19 +60,18 @@ InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPARAM lParam } PConsoleInfo -InitConsoleInfo() +AllocConsoleInfo() { PConsoleInfo pConInfo; - STARTUPINFO StartupInfo; - TCHAR * ptr; - SIZE_T length; pConInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ConsoleInfo)); - if (!pConInfo) - { - return NULL; - } + + return pConInfo; +} +void +InitConsoleDefaults(PConsoleInfo pConInfo) +{ /* initialize struct */ pConInfo->InsertMode = TRUE; pConInfo->HistoryBufferSize = 50; @@ -88,49 +87,9 @@ InitConsoleInfo() pConInfo->FontSize = (DWORD)MAKELONG(8, 12); pConInfo->FontWeight = FALSE; memcpy(pConInfo->Colors, s_Colors, sizeof(s_Colors)); - - GetModuleFileName(NULL, pConInfo->szProcessName, MAX_PATH); - GetStartupInfo(&StartupInfo); - - - - if ( StartupInfo.lpTitle ) - { - if ( _tcslen(StartupInfo.lpTitle) ) - { - if ( !GetWindowsDirectory(pConInfo->szProcessName, MAX_PATH) ) - { - HeapFree(GetProcessHeap(), 0, pConInfo); - return FALSE; - } - length = _tcslen(pConInfo->szProcessName); - if ( !_tcsncmp(pConInfo->szProcessName, StartupInfo.lpTitle, length) ) - { - // Windows XP SP2 uses unexpanded environment vars to get path - // i.e. c:\windows\system32\cmd.exe - // becomes - // %SystemRoot%_system32_cmd.exe - - _tcscpy(pConInfo->szProcessName, _T("%SystemRoot%")); - _tcsncpy(&pConInfo->szProcessName[12], &StartupInfo.lpTitle[length], _tcslen(StartupInfo.lpTitle) - length + 1); - - ptr = &pConInfo->szProcessName[12]; - while( (ptr = _tcsstr(ptr, _T("\\"))) ) - ptr[0] = _T('_'); - } - } - else - { - _tcscpy(pConInfo->szProcessName, _T("Console")); - } - } - else - { - _tcscpy(pConInfo->szProcessName, _T("Console")); - } - return pConInfo; } + INT_PTR CALLBACK ApplyProc( @@ -148,11 +107,7 @@ ApplyProc( { case WM_INITDIALOG: { -#if 0 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT); -#else - hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_ALL); -#endif SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0); return TRUE; } @@ -193,19 +148,15 @@ ApplyConsoleInfo(HWND hwndDlg, PConsoleInfo pConInfo) } else if ( res == IDC_RADIO_APPLY_ALL ) { - /* apply options */ - WriteConsoleOptions(pConInfo); pConInfo->AppliedConfig = TRUE; SetWindowLong(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR); + SendMessage(pConInfo->hConsoleWindow, PM_APPLY_CONSOLE_INFO, (WPARAM)pConInfo, (LPARAM)TRUE); } else if ( res == IDC_RADIO_APPLY_CURRENT ) { - /* - * TODO: - * exchange info in some private way with win32csr - */ pConInfo->AppliedConfig = TRUE; SetWindowLong(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR); + SendMessage(pConInfo->hConsoleWindow, PM_APPLY_CONSOLE_INFO, (WPARAM)pConInfo, (LPARAM)TRUE); } } @@ -218,16 +169,68 @@ InitApplet(HWND hwnd, UINT uMsg, LONG wParam, LONG lParam) INT i=0; PConsoleInfo pConInfo; - UNREFERENCED_PARAMETER(hwnd); UNREFERENCED_PARAMETER(uMsg); - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - pConInfo = InitConsoleInfo(); + /* + * console.dll shares information with win32csr with wParam, lParam + * + * wParam is a file handle to an unamed file object which contains the ConsoleInfo struct + * lParam is a boolean parameter which specifies wheter defaults should be shown + */ + + pConInfo = AllocConsoleInfo(); + if (!pConInfo) + { + return 0; + } + + if (lParam) + { + /* use defaults */ + InitConsoleDefaults(pConInfo); + } + else + { + /* use current info */ + PConsoleInfo pSharedInfo = MapViewOfFile((HANDLE)wParam, + FILE_MAP_ALL_ACCESS, + 0, + 0, + sizeof(ConsoleInfo)); + + /* copy options */ + if (pSharedInfo) + { + pConInfo->InsertMode = pSharedInfo->InsertMode; + pConInfo->HistoryBufferSize = pSharedInfo->HistoryBufferSize; + pConInfo->NumberOfHistoryBuffers = pSharedInfo->NumberOfHistoryBuffers; + pConInfo->ScreenText = pSharedInfo->ScreenText; + pConInfo->ScreenBackground = pSharedInfo->ScreenBackground; + pConInfo->PopupText = pSharedInfo->PopupText; + pConInfo->PopupBackground = pSharedInfo->PopupBackground; + pConInfo->WindowSize = pSharedInfo->WindowSize; + pConInfo->WindowPosition = pSharedInfo->WindowPosition; + pConInfo->ScreenBuffer = pSharedInfo->ScreenBuffer; + pConInfo->UseRasterFonts = pSharedInfo->UseRasterFonts; + pConInfo->FontSize = pSharedInfo->FontSize; + pConInfo->FontWeight = pSharedInfo->FontWeight; + memcpy(pConInfo->Colors, pSharedInfo->Colors, sizeof(s_Colors)); + } + } + + /* console window -> is notified on a property change event */ + pConInfo->hConsoleWindow = hwnd; ZeroMemory(&psh, sizeof(PROPSHEETHEADER)); psh.dwSize = sizeof(PROPSHEETHEADER); - psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_NOAPPLYNOW; + psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW; + + if(_tcslen(pConInfo->szProcessName)) + { + psh.dwFlags |= PSH_PROPTITLE; + psh.pszCaption = pConInfo->szProcessName; + } + psh.hwndParent = NULL; psh.hInstance = hApplet; psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON)); @@ -235,8 +238,7 @@ InitApplet(HWND hwnd, UINT uMsg, LONG wParam, LONG lParam) psh.nPages = 4; psh.nStartPage = 0; psh.ppsp = psp; - psh.pszCaption = pConInfo->szProcessName; - + InitPropSheetPage(&psp[i++], IDD_PROPPAGEOPTIONS, (DLGPROC) OptionsProc, (LPARAM)pConInfo); InitPropSheetPage(&psp[i++], IDD_PROPPAGEFONT, (DLGPROC) FontProc, (LPARAM)pConInfo); InitPropSheetPage(&psp[i++], IDD_PROPPAGELAYOUT, (DLGPROC) LayoutProc, (LPARAM)pConInfo); diff --git a/reactos/dll/win32/console/console.h b/reactos/dll/win32/console/console.h index e949aa47eba..933925811c8 100644 --- a/reactos/dll/win32/console/console.h +++ b/reactos/dll/win32/console/console.h @@ -21,11 +21,14 @@ typedef struct typedef struct TAGConsoleInfo { + HANDLE hFile; + HWND hConsoleWindow; TCHAR szProcessName[MAX_PATH]; BOOLEAN AppliedConfig; BOOLEAN UseRasterFonts; DWORD FontSize; DWORD FontWeight; + FONTSIGNATURE FontSignature; DWORD CursorSize; DWORD NumberOfHistoryBuffers; DWORD HistoryBufferSize; @@ -44,11 +47,12 @@ typedef struct TAGConsoleInfo COLORREF Colors[16]; } ConsoleInfo, *PConsoleInfo; -BOOL WriteConsoleOptions(PConsoleInfo pConInfo); void ApplyConsoleInfo(HWND hwndDlg, PConsoleInfo pConInfo); void PaintConsole(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo); void PaintText(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo); +#define PM_APPLY_CONSOLE_INFO (WM_APP + 100) + //globals extern HINSTANCE hApplet; diff --git a/reactos/dll/win32/console/en.rc b/reactos/dll/win32/console/en.rc index ee958a6d9f3..f197d19574b 100644 --- a/reactos/dll/win32/console/en.rc +++ b/reactos/dll/win32/console/en.rc @@ -135,7 +135,7 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION CAPTION "Apply Properties" FONT 8, "MS Shell Dlg" BEGIN -CONTROL "&Apply Properties to current window only", IDC_RADIO_APPLY_CURRENT, "Button", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED, 25, 25, 150, 10 +CONTROL "&Apply Properties to current window only", IDC_RADIO_APPLY_CURRENT, "Button", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 25, 25, 150, 10 CONTROL "&Save Properties for future windows with same title", IDC_RADIO_APPLY_ALL, "Button", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 25, 40, 185, 10 PUSHBUTTON "OK", IDOK, 25, 80, 40, 15, WS_VISIBLE PUSHBUTTON "Cancel", IDCANCEL, 120, 80, 50, 15, WS_VISIBLE diff --git a/reactos/dll/win32/console/options.c b/reactos/dll/win32/console/options.c index 10f06952b28..cc0ae4a472e 100644 --- a/reactos/dll/win32/console/options.c +++ b/reactos/dll/win32/console/options.c @@ -13,10 +13,6 @@ static void UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo); -static -BOOL -InitializeOptionsFromReg(TCHAR * Path, PConsoleInfo pConInfo); - INT_PTR CALLBACK OptionsProc( @@ -39,7 +35,6 @@ OptionsProc( { pConInfo = (PConsoleInfo) ((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo); - InitializeOptionsFromReg(pConInfo->szProcessName, pConInfo); UpdateDialogElements(hwndDlg, pConInfo); return TRUE; } @@ -59,11 +54,6 @@ OptionsProc( pConInfo->NumberOfHistoryBuffers = LOWORD(SendMessage(hDlgCtrl, UDM_GETPOS, 0, 0)); PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } - //else if (lppsn->hdr.code == PSN_KILLACTIVE) - //{ - // SetWindowLong(hwndDlg, DWL_MSGRESULT, FALSE); - // return FALSE; - //} else if (lppsn->hdr.code == PSN_APPLY) { if (!pConInfo->AppliedConfig) @@ -178,91 +168,6 @@ OptionsProc( return FALSE; } -static -BOOL InitializeOptionsFromReg(TCHAR * Path, PConsoleInfo pConInfo) -{ - HKEY hKey; - HKEY hSubKey; - DWORD dwNumSubKeys = 0; - DWORD dwIndex; - DWORD dwValueName; - DWORD dwValue; - DWORD dwType; - TCHAR szValueName[MAX_PATH]; - TCHAR szValue[MAX_PATH]; - DWORD Value; - - if ( RegOpenCurrentUser(KEY_READ, &hKey) != ERROR_SUCCESS ) - return FALSE; - - - if ( RegOpenKeyEx(hKey, Path, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS) - { - RegCloseKey(hKey); - return FALSE; - } - - RegQueryInfoKey(hSubKey, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); - - for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) - { - dwValue = sizeof(Value); - dwValueName = MAX_PATH; - - if ( RegEnumValue(hSubKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) - { - if (dwType == REG_SZ) - { - /* - * retry in case of string value - */ - dwValue = sizeof(szValue); - dwValueName = MAX_PATH; - if (RegEnumValue(hSubKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS) - break; - } - else - break; - } - - if ( !_tcscmp(szValueName, _T("CursorSize")) ) - { - if ( Value == 0x32) - pConInfo->CursorSize = Value; - else if ( Value == 0x64 ) - pConInfo->CursorSize = Value; - } - else if ( !_tcscmp(szValueName, _T("NumberOfHistoryBuffers")) ) - { - pConInfo->NumberOfHistoryBuffers = Value; - } - else if ( !_tcscmp(szValueName, _T("HistoryBufferSize")) ) - { - pConInfo->HistoryBufferSize = Value; - } - else if ( !_tcscmp(szValueName, _T("HistoryNoDup")) ) - { - pConInfo->HistoryNoDup = Value; - } - else if ( !_tcscmp(szValueName, _T("FullScreen")) ) - { - pConInfo->FullScreen = Value; - } - else if ( !_tcscmp(szValueName, _T("QuickEdit")) ) - { - pConInfo->QuickEdit = Value; - } - else if ( !_tcscmp(szValueName, _T("InsertMode")) ) - { - pConInfo->InsertMode = Value; - } - } - - RegCloseKey(hKey); - RegCloseKey(hSubKey); - return TRUE; -} - static void UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo) @@ -360,69 +265,3 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo) } -BOOLEAN InitializeOptionsDialog(HWND hwndDlg) -{ - PConsoleInfo pConInfo = (PConsoleInfo) GetWindowLongPtr(GetParent(hwndDlg), DWLP_USER); - - if (!pConInfo) - return FALSE; - - - return TRUE; -} - -BOOL WriteConsoleOptions(PConsoleInfo pConInfo) -{ - HKEY hKey; - HKEY hSubKey; - - if ( RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hKey) != ERROR_SUCCESS ) - return FALSE; - - - if ( RegOpenKeyEx(hKey, pConInfo->szProcessName, 0, KEY_READ | KEY_SET_VALUE, &hSubKey) != ERROR_SUCCESS) - { - RegCloseKey(hKey); - return FALSE; - } - - if ( pConInfo->CursorSize == 0x0) - RegDeleteKey(hSubKey, _T("CursorSize")); - else - RegSetValueEx(hSubKey, _T("CursorSize"), 0, REG_DWORD, (const BYTE *)&pConInfo->CursorSize, sizeof(DWORD)); - - if ( pConInfo->NumberOfHistoryBuffers == 0x5 ) - RegDeleteKey(hSubKey, _T("NumberOfHistoryBuffers")); - else - RegSetValueEx(hSubKey, _T("NumberOfHistoryBuffers"), 0, REG_DWORD, (const BYTE *)&pConInfo->NumberOfHistoryBuffers, sizeof(DWORD)); - - if ( pConInfo->HistoryBufferSize == 50 ) - RegDeleteKey(hSubKey, _T("HistoryBufferSize")); - else - RegSetValueEx(hSubKey, _T("HistoryBufferSize"), 0, REG_DWORD, (const BYTE *)&pConInfo->HistoryBufferSize, sizeof(DWORD)); - - if ( pConInfo->FullScreen == FALSE ) - RegDeleteKey(hSubKey, _T("FullScreen")); - else - RegSetValueEx(hSubKey, _T("FullScreen"), 0, REG_DWORD, (const BYTE *)&pConInfo->FullScreen, sizeof(DWORD)); - - if ( pConInfo->QuickEdit == FALSE) - RegDeleteKey(hSubKey, _T("QuickEdit")); - else - RegSetValueEx(hSubKey, _T("QuickEdit"), 0, REG_DWORD, (const BYTE *)&pConInfo->QuickEdit, sizeof(DWORD)); - - if ( pConInfo->InsertMode == TRUE ) - RegDeleteKey(hSubKey, _T("InsertMode")); - else - RegSetValueEx(hSubKey, _T("InsertMode"), 0, REG_DWORD, (const BYTE *)&pConInfo->InsertMode, sizeof(DWORD)); - - if ( pConInfo->HistoryNoDup == FALSE ) - RegDeleteKey(hSubKey, _T("HistoryNoDup")); - else - RegSetValueEx(hSubKey, _T("HistoryNoDup"), 0, REG_DWORD, (const BYTE *)&pConInfo->HistoryNoDup, sizeof(DWORD)); - - RegCloseKey(hKey); - RegCloseKey(hSubKey); - - return TRUE; -} From e0943123261d20e6ede82631b2b89d9fd733bbfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 4 Sep 2006 16:29:00 +0000 Subject: [PATCH 003/488] Fix compilation of rosapps with gcc 3.4.5. Thanks Gge on IRC svn path=/trunk/; revision=23912 --- rosapps/sysutils/pedump/pedump.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rosapps/sysutils/pedump/pedump.c b/rosapps/sysutils/pedump/pedump.c index 7e20745ee0b..a9ac30b2325 100644 --- a/rosapps/sysutils/pedump/pedump.c +++ b/rosapps/sysutils/pedump/pedump.c @@ -1956,7 +1956,8 @@ TranslateFunctionName ( int i, /*j,*/ n; - char c, cc; + char c = 0; + char cc; static char buff[512]; // result of translation From 4ba3312a811e704773d5d7766a365c9d4c5d368a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 4 Sep 2006 16:46:13 +0000 Subject: [PATCH 004/488] Add prototypes for some fmifs.dll functions. These have been found with trial and error on a MS Windows XP SP2 system with MS Visual Studio 2003 svn path=/trunk/; revision=23913 --- reactos/dll/win32/fmifs/chkdsk.c | 7 - reactos/dll/win32/fmifs/compress.c | 2 +- reactos/include/reactos/libs/fmifs/fmifs.h | 169 +++++++++++++-------- 3 files changed, 106 insertions(+), 72 deletions(-) diff --git a/reactos/dll/win32/fmifs/chkdsk.c b/reactos/dll/win32/fmifs/chkdsk.c index 907dccc8efa..a1da3b11941 100644 --- a/reactos/dll/win32/fmifs/chkdsk.c +++ b/reactos/dll/win32/fmifs/chkdsk.c @@ -31,11 +31,4 @@ Chkdsk (PWCHAR DriveRoot, &Argument); /* Argument */ } - -/* FMIFS.2 (SP4 only?) */ -VOID STDCALL -ChkdskEx (VOID) -{ -} - /* EOF */ diff --git a/reactos/dll/win32/fmifs/compress.c b/reactos/dll/win32/fmifs/compress.c index 181112face1..1560421e6f2 100644 --- a/reactos/dll/win32/fmifs/compress.c +++ b/reactos/dll/win32/fmifs/compress.c @@ -14,7 +14,7 @@ /* * @implemented */ -BOOL STDCALL +BOOLEAN STDCALL EnableVolumeCompression (PWCHAR DriveRoot, USHORT Compression) { diff --git a/reactos/include/reactos/libs/fmifs/fmifs.h b/reactos/include/reactos/libs/fmifs/fmifs.h index 9d2281f691f..9f941920429 100644 --- a/reactos/include/reactos/libs/fmifs/fmifs.h +++ b/reactos/include/reactos/libs/fmifs/fmifs.h @@ -1,7 +1,6 @@ #ifndef _FMIFS_H #define _FMIFS_H -/* $Id$ - * +/* * fmifs.h * * Copyright (c) 1998 Mark Russinovich @@ -16,21 +15,51 @@ * 1999-02-18 (Emanuele Aliberti) * Normalized function names. * + * --- + * + * 2006-09-04 (Hervé Poussineau) + * Add some prototypes + * */ /* Output command */ -typedef -struct +typedef struct { ULONG Lines; PCHAR Output; - } TEXTOUTPUT, *PTEXTOUTPUT; +/* media flags */ +typedef enum +{ + FMIFS_UNKNOWN0, + FMIFS_UNKNOWN1, + FMIFS_UNKNOWN2, + FMIFS_UNKNOWN3, + FMIFS_UNKNOWN4, + FMIFS_UNKNOWN5, + FMIFS_UNKNOWN6, + FMIFS_UNKNOWN7, + FMIFS_FLOPPY, + FMIFS_UNKNOWN9, + FMIFS_UNKNOWN10, + FMIFS_UNKNOWN11, + FMIFS_HARDDISK, + FMIFS_UNKNOWN13, + FMIFS_UNKNOWN14, + FMIFS_UNKNOWN15, + FMIFS_UNKNOWN16, + FMIFS_UNKNOWN17, + FMIFS_UNKNOWN18, + FMIFS_UNKNOWN19, + FMIFS_UNKNOWN20, + FMIFS_UNKNOWN21, + FMIFS_UNKNOWN22, + FMIFS_UNKNOWN23, +} FMIFS_MEDIA_FLAG; /* Callback command types */ -typedef -enum +typedef enum { PROGRESS, DONEWITHSTRUCTURE, @@ -48,79 +77,91 @@ enum UNKNOWND, OUTPUT, STRUCTUREPROGRESS - } CALLBACKCOMMAND; - /* FMIFS callback definition */ -typedef -BOOLEAN -(NTAPI * PFMIFSCALLBACK) ( - CALLBACKCOMMAND Command, - ULONG SubAction, - PVOID ActionInfo - ); +typedef BOOLEAN +(NTAPI* PFMIFSCALLBACK)( + IN CALLBACKCOMMAND Command, + IN ULONG SubAction, + IN PVOID ActionInfo); /* Chkdsk command in FMIFS */ -VOID -NTAPI +VOID NTAPI Chkdsk( - PWCHAR DriveRoot, - PWCHAR Format, - BOOLEAN CorrectErrors, - BOOLEAN Verbose, - BOOLEAN CheckOnlyIfDirty, - BOOLEAN ScanDrive, - PVOID Unused2, - PVOID Unused3, - PFMIFSCALLBACK Callback - ); + IN PWCHAR DriveRoot, + IN PWCHAR Format, + IN BOOLEAN CorrectErrors, + IN BOOLEAN Verbose, + IN BOOLEAN CheckOnlyIfDirty, + IN BOOLEAN ScanDrive, + IN PVOID Unused2, + IN PVOID Unused3, + IN PFMIFSCALLBACK Callback); /* ChkdskEx command in FMIFS (not in the original) */ -VOID -NTAPI -ChkDskEx( - PWCHAR DriveRoot, - PWCHAR Format, - BOOLEAN CorrectErrors, - BOOLEAN Verbose, - BOOLEAN CheckOnlyIfDirty, - BOOLEAN ScanDrive, - PVOID Unused2, - PVOID Unused3, - PFMIFSCALLBACK Callback - ); +VOID NTAPI +ChkdskEx( + IN PWCHAR DriveRoot, + IN PWCHAR Format, + IN BOOLEAN CorrectErrors, + IN BOOLEAN Verbose, + IN BOOLEAN CheckOnlyIfDirty, + IN BOOLEAN ScanDrive, + IN PVOID Unused2, + IN PVOID Unused3, + IN PFMIFSCALLBACK Callback); + +FMIFS_MEDIA_FLAG NTAPI +ComputeFmMediaType( + IN ULONG MediaType); /* DiskCopy command in FMIFS */ - -VOID -NTAPI +VOID NTAPI DiskCopy(VOID); /* Enable/Disable volume compression */ -BOOL -NTAPI +BOOLEAN NTAPI EnableVolumeCompression( - PWCHAR DriveRoot, - USHORT Compression - ); + IN PWCHAR DriveRoot, + IN USHORT Compression); /* Format command in FMIFS */ - -/* media flags */ -#define FMIFS_HARDDISK 0xC -#define FMIFS_FLOPPY 0x8 - -VOID -NTAPI +VOID NTAPI FormatEx( - PWCHAR DriveRoot, - ULONG MediaFlag, - PWCHAR Format, - PWCHAR Label, - BOOLEAN QuickFormat, - ULONG ClusterSize, - PFMIFSCALLBACK Callback - ); + IN PWCHAR DriveRoot, + IN ULONG MediaFlag, + IN PWCHAR Format, + IN PWCHAR Label, + IN BOOLEAN QuickFormat, + IN ULONG ClusterSize, + IN PFMIFSCALLBACK Callback); + +BOOLEAN NTAPI +QueryAvailableFileSystemFormat( + IN DWORD Index, + IN OUT PWCHAR FileSystem OPTIONAL, /* FIXME: Probably one minimal size is mandatory, but which one? */ + OUT UCHAR* Major OPTIONAL, + OUT UCHAR* Minor OPTIONAL, + OUT BOOLEAN* LastestVersion OPTIONAL); + +BOOL NTAPI +QueryDeviceInformation( + IN PWCHAR DriveRoot, + OUT ULONG* Buffer, /* That is probably some 4-bytes structure */ + IN ULONG BufferSize); /* 4 */ + +BOOLEAN NTAPI +QueryLatestFileSystemVersion( + IN PWCHAR FileSystem, + OUT UCHAR* Major OPTIONAL, + OUT UCHAR* Minor OPTIONAL); + +/*ULONG NTAPI +QuerySupportedMedia( + PVOID Unknown1, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4);*/ #endif /* ndef _FMIFS_H */ From 132cf4ece82ec7e8300bd09aa8a40a22905eb18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 4 Sep 2006 17:11:14 +0000 Subject: [PATCH 005/488] [FORMATTING] Add standard headers Replace the mix of tabs/spaces by tabs Replace STDCALL by NTAPI svn path=/trunk/; revision=23914 --- reactos/dll/win32/fmifs/chkdsk.c | 48 ++++----- reactos/dll/win32/fmifs/compress.c | 74 +++++++------- reactos/dll/win32/fmifs/diskcopy.c | 21 ++-- reactos/dll/win32/fmifs/extend.c | 19 ++-- reactos/dll/win32/fmifs/format.c | 112 ++++++++++----------- reactos/dll/win32/fmifs/init.c | 76 +++++++------- reactos/dll/win32/fmifs/label.c | 18 ++-- reactos/dll/win32/fmifs/media.c | 20 ++-- reactos/include/reactos/libs/fmifs/fmifs.h | 2 +- 9 files changed, 188 insertions(+), 202 deletions(-) diff --git a/reactos/dll/win32/fmifs/chkdsk.c b/reactos/dll/win32/fmifs/chkdsk.c index a1da3b11941..1d210fa7b55 100644 --- a/reactos/dll/win32/fmifs/chkdsk.c +++ b/reactos/dll/win32/fmifs/chkdsk.c @@ -1,34 +1,34 @@ -/* $Id$ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/chkdsk.c + * PURPOSE: Chkdsk * - * COPYING: See the top level directory - * PROJECT: ReactOS - * FILE: reactos/lib/fmifs/chkdsk.c - * DESCRIPTION: File management IFS utility functions - * PROGRAMMER: Emanuele Aliberti - * UPDATED - * 1999-02-16 (Emanuele Aliberti) - * Entry points added. + * PROGRAMMERS: (none) */ + #include "precomp.h" /* FMIFS.1 */ -VOID STDCALL -Chkdsk (PWCHAR DriveRoot, - PWCHAR Format, - BOOLEAN CorrectErrors, - BOOLEAN Verbose, - BOOLEAN CheckOnlyIfDirty, - BOOLEAN ScanDrive, - PVOID Unused2, - PVOID Unused3, - PFMIFSCALLBACK Callback) +VOID NTAPI +Chkdsk( + IN PWCHAR DriveRoot, + IN PWCHAR Format, + IN BOOLEAN CorrectErrors, + IN BOOLEAN Verbose, + IN BOOLEAN CheckOnlyIfDirty, + IN BOOLEAN ScanDrive, + IN PVOID Unused2, + IN PVOID Unused3, + IN PFMIFSCALLBACK Callback) { - BOOLEAN Argument = FALSE; + BOOLEAN Argument = FALSE; - /* FAIL immediately */ - Callback (DONE, /* Command */ - 0, /* DWORD Modifier */ - &Argument); /* Argument */ + /* FAIL immediately */ + Callback( + DONE, /* Command */ + 0, /* DWORD Modifier */ + &Argument);/* Argument */ } /* EOF */ diff --git a/reactos/dll/win32/fmifs/compress.c b/reactos/dll/win32/fmifs/compress.c index 1560421e6f2..8b13b423f0d 100644 --- a/reactos/dll/win32/fmifs/compress.c +++ b/reactos/dll/win32/fmifs/compress.c @@ -1,49 +1,51 @@ -/* $Id$ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/compress.c + * PURPOSE: Volume compression * - * COPYING: See the top level directory - * PROJECT: ReactOS - * FILE: reactos/lib/fmifs/compress.c - * DESCRIPTION: File management IFS utility functions - * PROGRAMMER: Emanuele Aliberti - * UPDATED - * 1999-02-16 (Emanuele Aliberti) - * Entry points added. + * PROGRAMMERS: Emanuele Aliberti */ + #include "precomp.h" /* * @implemented */ -BOOLEAN STDCALL -EnableVolumeCompression (PWCHAR DriveRoot, - USHORT Compression) +BOOLEAN NTAPI +EnableVolumeCompression( + IN PWCHAR DriveRoot, + IN USHORT Compression) { - HANDLE hFile = CreateFileW(DriveRoot, - FILE_READ_DATA | FILE_WRITE_DATA, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if(hFile != INVALID_HANDLE_VALUE) - { - DWORD RetBytes; - BOOL Ret = DeviceIoControl(hFile, - FSCTL_SET_COMPRESSION, - &Compression, - sizeof(USHORT), - NULL, - 0, - &RetBytes, - NULL); + HANDLE hFile; + DWORD RetBytes; + BOOL Ret; - CloseHandle(hFile); + hFile = CreateFileW( + DriveRoot, + FILE_READ_DATA | FILE_WRITE_DATA, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); - return (Ret != 0); - } - - return FALSE; + if (hFile == INVALID_HANDLE_VALUE) + return FALSE; + + Ret = DeviceIoControl( + hFile, + FSCTL_SET_COMPRESSION, + &Compression, + sizeof(USHORT), + NULL, + 0, + &RetBytes, + NULL); + + CloseHandle(hFile); + + return (Ret != 0); } /* EOF */ diff --git a/reactos/dll/win32/fmifs/diskcopy.c b/reactos/dll/win32/fmifs/diskcopy.c index a821f45afe1..6a87b6f510c 100644 --- a/reactos/dll/win32/fmifs/diskcopy.c +++ b/reactos/dll/win32/fmifs/diskcopy.c @@ -1,21 +1,18 @@ -/* $Id$ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/diskcopy.c + * PURPOSE: Disk copy * - * COPYING: See the top level directory - * PROJECT: ReactOS - * FILE: reactos/lib/fmifs/diskcopy.c - * DESCRIPTION: File management IFS utility functions - * PROGRAMMER: Emanuele Aliberti - * UPDATED - * 1999-02-16 (Emanuele Aliberti) - * Entry points added. + * PROGRAMMERS: (none) */ + #include "precomp.h" /* FMIFS.3 */ -VOID STDCALL -DiskCopy (VOID) +VOID NTAPI +DiskCopy(void) { } - /* EOF */ diff --git a/reactos/dll/win32/fmifs/extend.c b/reactos/dll/win32/fmifs/extend.c index dcbbdea5235..62a69cb120b 100644 --- a/reactos/dll/win32/fmifs/extend.c +++ b/reactos/dll/win32/fmifs/extend.c @@ -1,21 +1,18 @@ -/* $Id$ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/extend.c + * PURPOSE: Volume extension * - * COPYING: See the top level directory - * PROJECT: ReactOS - * FILE: reactos/lib/fmifs/extend.c - * DESCRIPTION: File management IFS utility functions - * PROGRAMMER: Emanuele Aliberti - * UPDATED - * 1999-02-16 (Emanuele Aliberti) - * Entry points added. + * PROGRAMMERS: (none) */ + #include "precomp.h" /* FMIFS.5 */ -VOID STDCALL +VOID NTAPI Extend (VOID) { } - /* EOF */ diff --git a/reactos/dll/win32/fmifs/format.c b/reactos/dll/win32/fmifs/format.c index a69346666da..4df75f14bdf 100644 --- a/reactos/dll/win32/fmifs/format.c +++ b/reactos/dll/win32/fmifs/format.c @@ -1,78 +1,74 @@ -/* $Id$ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/format.c + * PURPOSE: Volume format * - * COPYING: See the top level directory - * PROJECT: ReactOS - * FILE: reactos/lib/fmifs/format.c - * DESCRIPTION: File management IFS utility functions - * PROGRAMMER: Emanuele Aliberti - * UPDATED - * 1999-02-16 (Emanuele Aliberti) - * Entry points added. + * PROGRAMMERS: Emanuele Aliberti */ + #include "precomp.h" #define NDEBUG #include - /* FMIFS.6 */ -VOID STDCALL -Format (VOID) +VOID NTAPI +Format(void) { } - /* FMIFS.7 */ -VOID STDCALL -FormatEx (PWCHAR DriveRoot, - ULONG MediaFlag, - PWCHAR Format, - PWCHAR Label, - BOOLEAN QuickFormat, - ULONG ClusterSize, - PFMIFSCALLBACK Callback) +VOID NTAPI +FormatEx( + IN PWCHAR DriveRoot, + IN FMIFS_MEDIA_FLAG MediaFlag, + IN PWCHAR Format, + IN PWCHAR Label, + IN BOOLEAN QuickFormat, + IN ULONG ClusterSize, + IN PFMIFSCALLBACK Callback) { - UNICODE_STRING usDriveRoot; - UNICODE_STRING usLabel; - BOOLEAN Argument = FALSE; - WCHAR VolumeName[MAX_PATH]; - CURDIR CurDir; + UNICODE_STRING usDriveRoot; + UNICODE_STRING usLabel; + BOOLEAN Argument = FALSE; + WCHAR VolumeName[MAX_PATH]; + CURDIR CurDir; - if (_wcsnicmp(Format, L"FAT", 3) != 0) - { - /* Unknown file system */ - Callback (DONE, /* Command */ - 0, /* DWORD Modifier */ - &Argument); /* Argument */ - } + if (_wcsnicmp(Format, L"FAT", 3) != 0) + { + /* Unknown file system */ + Callback( + DONE, /* Command */ + 0, /* DWORD Modifier */ + &Argument); /* Argument */ + return; + } - if (!GetVolumeNameForVolumeMountPointW(DriveRoot, VolumeName, MAX_PATH) || - !RtlDosPathNameToNtPathName_U(VolumeName, &usDriveRoot, NULL, &CurDir)) - { - /* Report an error. */ - Callback (DONE, /* Command */ - 0, /* DWORD Modifier */ - &Argument); /* Argument */ + if (!GetVolumeNameForVolumeMountPointW(DriveRoot, VolumeName, MAX_PATH) + || !RtlDosPathNameToNtPathName_U(VolumeName, &usDriveRoot, NULL, &CurDir)) + { + /* Report an error. */ + Callback( + DONE, /* Command */ + 0, /* DWORD Modifier */ + &Argument); /* Argument */ + return; + } - return; - } + RtlInitUnicodeString(&usLabel, Label); - RtlInitUnicodeString(&usLabel, Label); - - if (_wcsnicmp(Format, L"FAT", 3) == 0) - { - DPRINT1("FormatEx - FAT\n"); - - VfatInitialize (); - VfatFormat (&usDriveRoot, - MediaFlag, - &usLabel, - QuickFormat, - ClusterSize, - Callback); - VfatCleanup (); - RtlFreeUnicodeString(&usDriveRoot); - } + DPRINT1("FormatEx - FAT\n"); + VfatInitialize(); + VfatFormat( + &usDriveRoot, + MediaFlag, + &usLabel, + QuickFormat, + ClusterSize, + Callback); + VfatCleanup(); + RtlFreeUnicodeString(&usDriveRoot); } /* EOF */ diff --git a/reactos/dll/win32/fmifs/init.c b/reactos/dll/win32/fmifs/init.c index b0d5d230616..c82149d98ec 100644 --- a/reactos/dll/win32/fmifs/init.c +++ b/reactos/dll/win32/fmifs/init.c @@ -1,58 +1,56 @@ -/* $Id$ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/init.c + * PURPOSE: Initialisation * - * COPYING: See the top level directory - * PROJECT: ReactOS - * FILE: reactos/lib/fmifs/init.c - * DESCRIPTION: File management IFS utility functions - * PROGRAMMER: Emanuele Aliberti - * UPDATED - * 1999-02-16 (Emanuele Aliberti) - * Entry points added. + * PROGRAMMERS: Emanuele Aliberti */ + #include "precomp.h" -static BOOL FmIfsInitialized = FALSE; +static BOOLEAN FmIfsInitialized = FALSE; -static BOOL STDCALL -InitializeFmIfsOnce (VOID) +static BOOLEAN NTAPI +InitializeFmIfsOnce(void) { /* TODO: Check how many IFS are installed in the system */ /* TOSO: and register a descriptor for each one */ return TRUE; } - /* FMIFS.8 */ -BOOL STDCALL -InitializeFmIfs (PVOID hinstDll, - DWORD dwReason, - PVOID reserved) +BOOLEAN NTAPI +InitializeFmIfs( + IN PVOID hinstDll, + IN DWORD dwReason, + IN PVOID reserved) { - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - if (FALSE == FmIfsInitialized) - { - if (FALSE == InitializeFmIfsOnce()) + switch (dwReason) { - return FALSE; + case DLL_PROCESS_ATTACH: + if (FALSE == FmIfsInitialized) + { + if (FALSE == InitializeFmIfsOnce()) + { + return FALSE; + } + + FmIfsInitialized = TRUE; + } + break; + + case DLL_THREAD_ATTACH: + break; + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + break; } - FmIfsInitialized = TRUE; - } - break; - - case DLL_THREAD_ATTACH: - break; - - case DLL_THREAD_DETACH: - break; - - case DLL_PROCESS_DETACH: - break; - } - - return TRUE; + return TRUE; } /* EOF */ diff --git a/reactos/dll/win32/fmifs/label.c b/reactos/dll/win32/fmifs/label.c index 1f150890ed9..e4b0ee48e10 100644 --- a/reactos/dll/win32/fmifs/label.c +++ b/reactos/dll/win32/fmifs/label.c @@ -1,18 +1,16 @@ -/* $Id$ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/label.c + * PURPOSE: Set volume label * - * COPYING: See the top level directory - * PROJECT: ReactOS - * FILE: reactos/lib/fmifs/label.c - * DESCRIPTION: File management IFS utility functions - * PROGRAMMER: Emanuele Aliberti - * UPDATED - * 1999-02-16 (Emanuele Aliberti) - * Entry points added. + * PROGRAMMERS: (none) */ + #include "precomp.h" /* FMIFS.10 */ -VOID STDCALL +VOID NTAPI SetLabel (VOID) { } diff --git a/reactos/dll/win32/fmifs/media.c b/reactos/dll/win32/fmifs/media.c index d8086578a3e..3837c99b2ff 100644 --- a/reactos/dll/win32/fmifs/media.c +++ b/reactos/dll/win32/fmifs/media.c @@ -1,19 +1,17 @@ -/* $Id$ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/media.c + * PURPOSE: Media * - * COPYING: See the top level directory - * PROJECT: ReactOS - * FILE: reactos/lib/fmifs/media.c - * DESCRIPTION: fmifs.dll - * PROGRAMMER: Emanuele Aliberti - * UPDATED - * 1999-02-16 (Emanuele Aliberti) - * Entry points added. + * PROGRAMMERS: (none) */ + #include "precomp.h" /* FMIFS.9 */ -VOID STDCALL -QuerySupportedMedia (VOID) +VOID NTAPI +QuerySupportedMedia(VOID) { } diff --git a/reactos/include/reactos/libs/fmifs/fmifs.h b/reactos/include/reactos/libs/fmifs/fmifs.h index 9f941920429..eb5daf8418f 100644 --- a/reactos/include/reactos/libs/fmifs/fmifs.h +++ b/reactos/include/reactos/libs/fmifs/fmifs.h @@ -130,7 +130,7 @@ EnableVolumeCompression( VOID NTAPI FormatEx( IN PWCHAR DriveRoot, - IN ULONG MediaFlag, + IN FMIFS_MEDIA_FLAG MediaFlag, IN PWCHAR Format, IN PWCHAR Label, IN BOOLEAN QuickFormat, From 90d5c198509e251aa20ee88bc0c47fbfffc9b297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 4 Sep 2006 19:27:19 +0000 Subject: [PATCH 006/488] Remove Vfat(x)Initialize and Vfat(x)Cleanup which were empty Remove vfatlib dependancy of fmifs.dll (Providers like ufat.dll are loaded dynamically at startup) svn path=/trunk/; revision=23915 --- reactos/base/setup/usetup/format.c | 4 - reactos/baseaddress.rbuild | 1 + reactos/dll/win32/fmifs/fmifs.rbuild | 1 - reactos/dll/win32/fmifs/format.c | 13 +-- reactos/dll/win32/fmifs/init.c | 80 ++++++++++++++++++- reactos/dll/win32/fmifs/precomp.h | 39 ++++++++- reactos/include/reactos/libs/fslib/vfatlib.h | 10 +-- reactos/include/reactos/libs/fslib/vfatxlib.h | 12 +-- reactos/lib/fslib/vfatlib/vfatlib.c | 22 +---- reactos/lib/fslib/vfatxlib/vfatxlib.c | 24 +----- 10 files changed, 133 insertions(+), 73 deletions(-) diff --git a/reactos/base/setup/usetup/format.c b/reactos/base/setup/usetup/format.c index 690c3703271..9f665bc6b69 100644 --- a/reactos/base/setup/usetup/format.c +++ b/reactos/base/setup/usetup/format.c @@ -105,8 +105,6 @@ FormatPartition (PUNICODE_STRING DriveRoot) ProgressSetStepCount (ProgressBar, 100); - VfatInitialize (); - Status = VfatFormat (DriveRoot, 0, /* MediaFlag */ NULL, /* Label */ @@ -114,8 +112,6 @@ FormatPartition (PUNICODE_STRING DriveRoot) 0, /* ClusterSize */ (PFMIFSCALLBACK)FormatCallback); /* Callback */ - VfatCleanup (); - DestroyProgressBar (ProgressBar); ProgressBar = NULL; diff --git a/reactos/baseaddress.rbuild b/reactos/baseaddress.rbuild index a99f59730bc..8cb1ba9f109 100644 --- a/reactos/baseaddress.rbuild +++ b/reactos/baseaddress.rbuild @@ -67,6 +67,7 @@ + diff --git a/reactos/dll/win32/fmifs/fmifs.rbuild b/reactos/dll/win32/fmifs/fmifs.rbuild index 76a1aa77f1a..dee10fe3902 100644 --- a/reactos/dll/win32/fmifs/fmifs.rbuild +++ b/reactos/dll/win32/fmifs/fmifs.rbuild @@ -4,7 +4,6 @@ 0x0600 - vfatlib ntdll kernel32 chkdsk.c diff --git a/reactos/dll/win32/fmifs/format.c b/reactos/dll/win32/fmifs/format.c index 4df75f14bdf..bef9f0ab85d 100644 --- a/reactos/dll/win32/fmifs/format.c +++ b/reactos/dll/win32/fmifs/format.c @@ -5,6 +5,7 @@ * PURPOSE: Volume format * * PROGRAMMERS: Emanuele Aliberti + * Hervé Poussineau (hpoussin@reactos.org) */ #include "precomp.h" @@ -14,7 +15,7 @@ /* FMIFS.6 */ VOID NTAPI -Format(void) +Format(VOID) { } @@ -29,13 +30,15 @@ FormatEx( IN ULONG ClusterSize, IN PFMIFSCALLBACK Callback) { + PIFS_PROVIDER Provider; UNICODE_STRING usDriveRoot; UNICODE_STRING usLabel; BOOLEAN Argument = FALSE; WCHAR VolumeName[MAX_PATH]; CURDIR CurDir; - if (_wcsnicmp(Format, L"FAT", 3) != 0) + Provider = GetProvider(Format); + if (!Provider) { /* Unknown file system */ Callback( @@ -58,16 +61,14 @@ FormatEx( RtlInitUnicodeString(&usLabel, Label); - DPRINT1("FormatEx - FAT\n"); - VfatInitialize(); - VfatFormat( + DPRINT1("FormatEx - %S\n", Format); + Provider->FormatEx( &usDriveRoot, MediaFlag, &usLabel, QuickFormat, ClusterSize, Callback); - VfatCleanup(); RtlFreeUnicodeString(&usDriveRoot); } diff --git a/reactos/dll/win32/fmifs/init.c b/reactos/dll/win32/fmifs/init.c index c82149d98ec..459f60380d0 100644 --- a/reactos/dll/win32/fmifs/init.c +++ b/reactos/dll/win32/fmifs/init.c @@ -5,17 +5,93 @@ * PURPOSE: Initialisation * * PROGRAMMERS: Emanuele Aliberti + * Hervé Poussineau (hpoussin@reactos.org) */ #include "precomp.h" static BOOLEAN FmIfsInitialized = FALSE; +LIST_ENTRY ProviderListHead; -static BOOLEAN NTAPI +PIFS_PROVIDER +GetProvider( + IN PWCHAR FileSystem) +{ + PLIST_ENTRY ListEntry; + PIFS_PROVIDER Provider; + + ListEntry = ProviderListHead.Flink; + while (ListEntry != ProviderListHead.Flink) + { + Provider = CONTAINING_RECORD(ListEntry, IFS_PROVIDER, ListEntry); + if (wcscmp(Provider->Name, FileSystem) == 0) + return Provider; + ListEntry = ListEntry->Flink; + } + + /* Provider not found */ + return NULL; +} + +static BOOLEAN +AddProvider( + IN PWCHAR FileSystem, + IN PWCHAR DllFile) +{ + PIFS_PROVIDER Provider = NULL; + ULONG RequiredSize; + HMODULE hMod = NULL; + BOOLEAN ret = FALSE; + + hMod = LoadLibraryW(DllFile); + if (!hMod) + goto cleanup; + + RequiredSize = FIELD_OFFSET(IFS_PROVIDER, Name) + + wcslen(FileSystem) * sizeof(WCHAR) + sizeof(UNICODE_NULL); + Provider = (PIFS_PROVIDER)RtlAllocateHeap( + RtlGetProcessHeap(), + 0, + RequiredSize); + if (!Provider) + goto cleanup; + RtlZeroMemory(Provider, RequiredSize); + + /* Get function pointers */ + //Provider->Chkdsk = (CHKDSK)GetProcAddress(hMod, "Chkdsk"); + //Provider->ChkdskEx = (CHKDSKEX)GetProcAddress(hMod, "ChkdskEx"); + //Provider->Extend = (EXTEND)GetProcAddress(hMod, "Extend"); + //Provider->Format = (FORMAT)GetProcAddress(hMod, "Format"); + Provider->FormatEx = (FORMATEX)GetProcAddress(hMod, "FormatEx"); + //Provider->Recover = (RECOVER)GetProcAddress(hMod, "Recover"); + + wcscpy(Provider->Name, FileSystem); + + InsertTailList(&ProviderListHead, &Provider->ListEntry); + ret = TRUE; + +cleanup: + if (!ret) + { + if (hMod) + FreeLibrary(hMod); + if (Provider) + RtlFreeHeap(RtlGetProcessHeap(), 0, Provider); + } + return ret; +} + +static BOOLEAN InitializeFmIfsOnce(void) { + InitializeListHead(&ProviderListHead); + + /* Add default providers */ + AddProvider(L"FAT", L"ufat"); + AddProvider(L"FAT32", L"ufat"); + /* TODO: Check how many IFS are installed in the system */ - /* TOSO: and register a descriptor for each one */ + /* TODO: and register a descriptor for each one */ return TRUE; } diff --git a/reactos/dll/win32/fmifs/precomp.h b/reactos/dll/win32/fmifs/precomp.h index 13ae56aa4d7..a69c66c4c57 100644 --- a/reactos/dll/win32/fmifs/precomp.h +++ b/reactos/dll/win32/fmifs/precomp.h @@ -1,9 +1,11 @@ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS System Libraries - * FILE: lib/fmifs/precomp.h - * PURPOSE: Win32 FMIFS API Libary Header - * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/precomp.h + * PURPOSE: Win32 FMIFS API Library Header + * + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * Hervé Poussineau (hpoussin@reactos.org) */ /* INCLUDES ******************************************************************/ @@ -23,4 +25,33 @@ /* VFATLIB Public Header */ #include +typedef NTSTATUS (NTAPI *FORMATEX)( + IN PUNICODE_STRING DriveRoot, + IN FMIFS_MEDIA_FLAG MediaFlag, + IN PUNICODE_STRING Label, + IN BOOLEAN QuickFormat, + IN ULONG ClusterSize, + IN PFMIFSCALLBACK Callback); + +extern LIST_ENTRY ProviderListHead; + +typedef struct _IFS_PROVIDER +{ + LIST_ENTRY ListEntry; + + PVOID Chkdsk; + PVOID ChkdskEx; + PVOID Extend; + PVOID Format; + FORMATEX FormatEx; + PVOID Recover; + + WCHAR Name[1]; +} IFS_PROVIDER, *PIFS_PROVIDER; + +/* init.c */ +PIFS_PROVIDER +GetProvider( + IN PWCHAR FileSytem); + /* EOF */ diff --git a/reactos/include/reactos/libs/fslib/vfatlib.h b/reactos/include/reactos/libs/fslib/vfatlib.h index e0c0fa948d7..c54d9260994 100755 --- a/reactos/include/reactos/libs/fslib/vfatlib.h +++ b/reactos/include/reactos/libs/fslib/vfatlib.h @@ -9,15 +9,9 @@ #include -NTSTATUS -VfatInitialize (VOID); - -NTSTATUS -VfatCleanup (VOID); - -NTSTATUS +NTSTATUS NTAPI VfatFormat (PUNICODE_STRING DriveRoot, - ULONG MediaFlag, + FMIFS_MEDIA_FLAG MediaFlag, PUNICODE_STRING Label, BOOLEAN QuickFormat, ULONG ClusterSize, diff --git a/reactos/include/reactos/libs/fslib/vfatxlib.h b/reactos/include/reactos/libs/fslib/vfatxlib.h index 0d67efe2891..b44911168fb 100644 --- a/reactos/include/reactos/libs/fslib/vfatxlib.h +++ b/reactos/include/reactos/libs/fslib/vfatxlib.h @@ -9,16 +9,12 @@ #include -NTSTATUS -VfatxInitialize (VOID); - -NTSTATUS -VfatxCleanup (VOID); - -NTSTATUS +NTSTATUS NTAPI VfatxFormat (PUNICODE_STRING DriveRoot, - ULONG MediaFlag, + FMIFS_MEDIA_FLAG MediaFlag, + PUNICODE_STRING Label, BOOLEAN QuickFormat, + ULONG ClusterSize, PFMIFSCALLBACK Callback); #endif /*__VFATLIB_H */ diff --git a/reactos/lib/fslib/vfatlib/vfatlib.c b/reactos/lib/fslib/vfatlib/vfatlib.c index 32967beb4ad..386679689d7 100755 --- a/reactos/lib/fslib/vfatlib/vfatlib.c +++ b/reactos/lib/fslib/vfatlib/vfatlib.c @@ -12,18 +12,9 @@ #define NDEBUG #include -NTSTATUS -VfatInitialize(VOID) -{ - DPRINT("VfatInitialize()\n"); - - return STATUS_SUCCESS; -} - - -NTSTATUS +NTSTATUS NTAPI VfatFormat (PUNICODE_STRING DriveRoot, - ULONG MediaFlag, + FMIFS_MEDIA_FLAG MediaFlag, PUNICODE_STRING Label, BOOLEAN QuickFormat, ULONG ClusterSize, @@ -194,15 +185,6 @@ VfatFormat (PUNICODE_STRING DriveRoot, } -NTSTATUS -VfatCleanup(VOID) -{ - DPRINT("VfatCleanup()\n"); - - return STATUS_SUCCESS; -} - - VOID UpdateProgress (PFORMAT_CONTEXT Context, ULONG Increment) diff --git a/reactos/lib/fslib/vfatxlib/vfatxlib.c b/reactos/lib/fslib/vfatxlib/vfatxlib.c index 0fe20518bb0..6f18957b19e 100644 --- a/reactos/lib/fslib/vfatxlib/vfatxlib.c +++ b/reactos/lib/fslib/vfatxlib/vfatxlib.c @@ -12,19 +12,12 @@ #define NDEBUG #include -NTSTATUS -VfatxInitialize(VOID) -{ - DPRINT("VfatxInitialize()\n"); - - return STATUS_SUCCESS; -} - - -NTSTATUS +NTSTATUS NTAPI VfatxFormat (PUNICODE_STRING DriveRoot, - ULONG MediaFlag, + FMIFS_MEDIA_FLAG MediaFlag, + PUNICODE_STRING Label, BOOLEAN QuickFormat, + ULONG ClusterSize, PFMIFSCALLBACK Callback) { OBJECT_ATTRIBUTES ObjectAttributes; @@ -163,15 +156,6 @@ VfatxFormat (PUNICODE_STRING DriveRoot, } -NTSTATUS -VfatxCleanup(VOID) -{ - DPRINT("VfatxCleanup()\n"); - - return STATUS_SUCCESS; -} - - VOID VfatxUpdateProgress (PFORMAT_CONTEXT Context, ULONG Increment) From 7ed51f5c9e42f1c2b1b56476c1c0981435737d54 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Mon, 4 Sep 2006 20:14:48 +0000 Subject: [PATCH 007/488] rename version.h to ver.h to avoid a possible conflict with include/reactos/version.h svn path=/trunk/; revision=23916 --- reactos/boot/freeldr/freeldr/arch/i386/i386trap.S | 2 +- reactos/boot/freeldr/freeldr/include/freeldr.h | 2 +- reactos/boot/freeldr/freeldr/include/{version.h => ver.h} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename reactos/boot/freeldr/freeldr/include/{version.h => ver.h} (100%) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/i386trap.S b/reactos/boot/freeldr/freeldr/arch/i386/i386trap.S index c8b132b647a..4a367311677 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/i386trap.S +++ b/reactos/boot/freeldr/freeldr/arch/i386/i386trap.S @@ -22,7 +22,7 @@ #define ASM #include -#include +#include #define SCREEN_ATTR 0x1f /* Bright white on blue background */ diff --git a/reactos/boot/freeldr/freeldr/include/freeldr.h b/reactos/boot/freeldr/freeldr/include/freeldr.h index c2cf1e122f0..e72edd71587 100644 --- a/reactos/boot/freeldr/freeldr/include/freeldr.h +++ b/reactos/boot/freeldr/freeldr/include/freeldr.h @@ -64,7 +64,7 @@ #endif /* misc files */ #include -#include +#include #include /* Needed by boot manager */ #include diff --git a/reactos/boot/freeldr/freeldr/include/version.h b/reactos/boot/freeldr/freeldr/include/ver.h similarity index 100% rename from reactos/boot/freeldr/freeldr/include/version.h rename to reactos/boot/freeldr/freeldr/include/ver.h From 94b07b79dbbea15b37c8f0707741798a249307c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 4 Sep 2006 20:55:39 +0000 Subject: [PATCH 008/488] Add ufat.dll, to be able to format drives to FAT and FAT32 format svn path=/trunk/; revision=23917 --- reactos/dll/win32/fmifs/fmifs.rbuild | 2 +- reactos/dll/win32/fmifs/init.c | 4 ++-- reactos/dll/win32/ufat/ufat.def | 3 +++ reactos/dll/win32/ufat/ufat.rbuild | 10 ++++++++++ reactos/dll/win32/ufat/ufat.rc | 5 +++++ reactos/dll/win32/win32.rbuild | 3 +++ 6 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 reactos/dll/win32/ufat/ufat.def create mode 100644 reactos/dll/win32/ufat/ufat.rbuild create mode 100644 reactos/dll/win32/ufat/ufat.rc diff --git a/reactos/dll/win32/fmifs/fmifs.rbuild b/reactos/dll/win32/fmifs/fmifs.rbuild index dee10fe3902..d4498926012 100644 --- a/reactos/dll/win32/fmifs/fmifs.rbuild +++ b/reactos/dll/win32/fmifs/fmifs.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/win32/fmifs/init.c b/reactos/dll/win32/fmifs/init.c index 459f60380d0..41ef3115d35 100644 --- a/reactos/dll/win32/fmifs/init.c +++ b/reactos/dll/win32/fmifs/init.c @@ -21,10 +21,10 @@ GetProvider( PIFS_PROVIDER Provider; ListEntry = ProviderListHead.Flink; - while (ListEntry != ProviderListHead.Flink) + while (ListEntry != &ProviderListHead) { Provider = CONTAINING_RECORD(ListEntry, IFS_PROVIDER, ListEntry); - if (wcscmp(Provider->Name, FileSystem) == 0) + if (_wcsicmp(Provider->Name, FileSystem) == 0) return Provider; ListEntry = ListEntry->Flink; } diff --git a/reactos/dll/win32/ufat/ufat.def b/reactos/dll/win32/ufat/ufat.def new file mode 100644 index 00000000000..53da9341f3a --- /dev/null +++ b/reactos/dll/win32/ufat/ufat.def @@ -0,0 +1,3 @@ +LIBRARY UFAT.DLL +EXPORTS +FormatEx=VfatFormat@24 \ No newline at end of file diff --git a/reactos/dll/win32/ufat/ufat.rbuild b/reactos/dll/win32/ufat/ufat.rbuild new file mode 100644 index 00000000000..c214aed2f24 --- /dev/null +++ b/reactos/dll/win32/ufat/ufat.rbuild @@ -0,0 +1,10 @@ + + + . + + + 0x0600 + vfatlib + ntdll + ufat.rc + diff --git a/reactos/dll/win32/ufat/ufat.rc b/reactos/dll/win32/ufat/ufat.rc new file mode 100644 index 00000000000..b6b57661884 --- /dev/null +++ b/reactos/dll/win32/ufat/ufat.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "FAT File System Management\0" +#define REACTOS_STR_INTERNAL_NAME "ufat\0" +#define REACTOS_STR_ORIGINAL_FILENAME "ufat.dll\0" +#include diff --git a/reactos/dll/win32/win32.rbuild b/reactos/dll/win32/win32.rbuild index 4eaaad1b317..9b7819a6589 100644 --- a/reactos/dll/win32/win32.rbuild +++ b/reactos/dll/win32/win32.rbuild @@ -226,6 +226,9 @@ + + + From 478f24b02bb6038dad29403e67c54fcf043e4423 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 4 Sep 2006 21:26:49 +0000 Subject: [PATCH 009/488] * use ConsoleInfo struct directly * change type in global struct (avoid buffer overflow when reading value from registry) svn path=/trunk/; revision=23918 --- reactos/dll/win32/console/console.c | 24 +++++++++++------------- reactos/dll/win32/console/console.h | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/reactos/dll/win32/console/console.c b/reactos/dll/win32/console/console.c index e10e3bbb908..3bf5de193ed 100644 --- a/reactos/dll/win32/console/console.c +++ b/reactos/dll/win32/console/console.c @@ -192,14 +192,14 @@ InitApplet(HWND hwnd, UINT uMsg, LONG wParam, LONG lParam) else { /* use current info */ - PConsoleInfo pSharedInfo = MapViewOfFile((HANDLE)wParam, - FILE_MAP_ALL_ACCESS, - 0, - 0, - sizeof(ConsoleInfo)); + PConsoleInfo pSharedInfo = (PConsoleInfo)wParam; - /* copy options */ - if (pSharedInfo) + if (IsBadReadPtr((const void *)pSharedInfo, sizeof(ConsoleInfo))) + { + /* use defaults */ + InitConsoleDefaults(pConInfo); + } + else { pConInfo->InsertMode = pSharedInfo->InsertMode; pConInfo->HistoryBufferSize = pSharedInfo->HistoryBufferSize; @@ -255,8 +255,6 @@ CPlApplet( LPARAM lParam1, LPARAM lParam2) { - int i = (int)lParam1; - switch(uMsg) { case CPL_INIT: @@ -270,14 +268,14 @@ CPlApplet( case CPL_INQUIRE: { CPLINFO *CPlInfo = (CPLINFO*)lParam2; - CPlInfo->idIcon = Applets[i].idIcon; - CPlInfo->idName = Applets[i].idName; - CPlInfo->idInfo = Applets[i].idDescription; + CPlInfo->idIcon = Applets[0].idIcon; + CPlInfo->idName = Applets[0].idName; + CPlInfo->idInfo = Applets[0].idDescription; break; } case CPL_DBLCLK: { - Applets[i].AppletProc(hwndCPl, uMsg, lParam1, lParam2); + Applets[0].AppletProc(hwndCPl, uMsg, lParam1, lParam2); break; } } diff --git a/reactos/dll/win32/console/console.h b/reactos/dll/win32/console/console.h index 933925811c8..5f01b939bc0 100644 --- a/reactos/dll/win32/console/console.h +++ b/reactos/dll/win32/console/console.h @@ -25,7 +25,7 @@ typedef struct TAGConsoleInfo HWND hConsoleWindow; TCHAR szProcessName[MAX_PATH]; BOOLEAN AppliedConfig; - BOOLEAN UseRasterFonts; + DWORD UseRasterFonts; DWORD FontSize; DWORD FontWeight; FONTSIGNATURE FontSignature; From aa34958d1bca6c7b07017b8639e3c9b8b5a7f133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 4 Sep 2006 21:58:38 +0000 Subject: [PATCH 010/488] Add a hack to enable formatting (was broken since at least r20156) svn path=/trunk/; revision=23919 --- reactos/dll/win32/fmifs/format.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/fmifs/format.c b/reactos/dll/win32/fmifs/format.c index bef9f0ab85d..0cc7a161c27 100644 --- a/reactos/dll/win32/fmifs/format.c +++ b/reactos/dll/win32/fmifs/format.c @@ -35,7 +35,7 @@ FormatEx( UNICODE_STRING usLabel; BOOLEAN Argument = FALSE; WCHAR VolumeName[MAX_PATH]; - CURDIR CurDir; + //CURDIR CurDir; Provider = GetProvider(Format); if (!Provider) @@ -48,6 +48,12 @@ FormatEx( return; } +#if 1 + DPRINT1("Warning: use GetVolumeNameForVolumeMountPointW() instead!\n"); + swprintf(VolumeName, L"\\\\.\\%c:", DriveRoot[0]); + RtlCreateUnicodeString(&usDriveRoot, VolumeName); + /* Code disabled as long as our storage stack doesn't understand IOCTL_MOUNTDEV_QUERY_DEVICE_NAME */ +#else if (!GetVolumeNameForVolumeMountPointW(DriveRoot, VolumeName, MAX_PATH) || !RtlDosPathNameToNtPathName_U(VolumeName, &usDriveRoot, NULL, &CurDir)) { @@ -58,10 +64,11 @@ FormatEx( &Argument); /* Argument */ return; } +#endif RtlInitUnicodeString(&usLabel, Label); - DPRINT1("FormatEx - %S\n", Format); + DPRINT("FormatEx - %S\n", Format); Provider->FormatEx( &usDriveRoot, MediaFlag, From d5168c3b055a5f42510c224e9e9961ec2496e69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 4 Sep 2006 22:16:43 +0000 Subject: [PATCH 011/488] Allow allow lower case when being called svn path=/trunk/; revision=23920 --- reactos/dll/win32/fmifs/format.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/fmifs/format.c b/reactos/dll/win32/fmifs/format.c index 0cc7a161c27..39a676d5c10 100644 --- a/reactos/dll/win32/fmifs/format.c +++ b/reactos/dll/win32/fmifs/format.c @@ -50,7 +50,7 @@ FormatEx( #if 1 DPRINT1("Warning: use GetVolumeNameForVolumeMountPointW() instead!\n"); - swprintf(VolumeName, L"\\\\.\\%c:", DriveRoot[0]); + swprintf(VolumeName, L"\\??\\%c:", towupper(DriveRoot[0])); RtlCreateUnicodeString(&usDriveRoot, VolumeName); /* Code disabled as long as our storage stack doesn't understand IOCTL_MOUNTDEV_QUERY_DEVICE_NAME */ #else From d6d0d40cad49fd76d72a611edc5acbf4eeaec6a3 Mon Sep 17 00:00:00 2001 From: Brandon Turner Date: Mon, 4 Sep 2006 22:51:28 +0000 Subject: [PATCH 012/488] Implement CryptSignHashW based WINE and old CryptSignHashA. Change CryptSignHashA to call CryptSignHashW. svn path=/trunk/; revision=23921 --- reactos/dll/win32/advapi32/crypt/crypt.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/advapi32/crypt/crypt.c b/reactos/dll/win32/advapi32/crypt/crypt.c index fb53ceee497..c4b832f2102 100644 --- a/reactos/dll/win32/advapi32/crypt/crypt.c +++ b/reactos/dll/win32/advapi32/crypt/crypt.c @@ -1606,6 +1606,13 @@ BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen, */ BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) +{ + /* Since sDescription is ignored we dont need to convert it, we just pass null */ + return CryptSignHashW(hHash, dwKeySpec, NULL, dwFlags, pbSignature, pdwSigLen); +} + +BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, + DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) { PCRYPTHASH hash = (PCRYPTHASH)hHash; PCRYPTPROV prov; @@ -1613,12 +1620,13 @@ BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescripti DPRINT("(0x%lx, %ld, %08ld, %p, %p)\n", hHash, dwKeySpec, dwFlags, pbSignature, pdwSigLen); if (sDescription) { + /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/cryptsignhash.asp */ DPRINT("The sDescription parameter is not supported (and no longer used). Ignoring.\n"); } if (!hash) CRYPT_ReturnLastError(ERROR_INVALID_HANDLE); - if (!pdwSigLen) + if (!pdwSigLen || !hash->pProvider) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER); prov = hash->pProvider; @@ -1626,6 +1634,7 @@ BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescripti dwFlags, pbSignature, pdwSigLen); } + /****************************************************************************** * CryptSetHashParam (ADVAPI32.@) * From 4da1de7ca13fd62510106b736087fb36d7dc2116 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 5 Sep 2006 10:14:40 +0000 Subject: [PATCH 013/488] * msvc compiling fix svn path=/trunk/; revision=23922 --- reactos/dll/cpl/desk/background.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/reactos/dll/cpl/desk/background.c b/reactos/dll/cpl/desk/background.c index 45723feab9c..aac7cc8d55b 100644 --- a/reactos/dll/cpl/desk/background.c +++ b/reactos/dll/cpl/desk/background.c @@ -307,6 +307,7 @@ void OnColorButton() /* Load custom colors from Registry */ HKEY hKey = NULL; LONG res = ERROR_SUCCESS; + CHOOSECOLOR cc; res = RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance"), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL ); /* Now the key is either created or opened existing, if res == ERROR_SUCCESS */ @@ -322,7 +323,7 @@ void OnColorButton() } /* Launch ChooseColor() dialog */ - CHOOSECOLOR cc; + cc.lStructSize = sizeof(CHOOSECOLOR); cc.hwndOwner = g_hBackgroundPage; cc.hInstance = NULL; @@ -361,10 +362,11 @@ BOOL CheckListViewFilenameExists(HWND hWndList, LPCTSTR tszFileName) /* ListView_FindItem() Macro: Searches for a list-view item with the specified * * characteristics. Returns the index of the item if successful, or -1 otherwise */ LVFINDINFO lvfi; + int retVal; lvfi.flags = LVFI_STRING; /* search item by EXACT string */ lvfi.psz = tszFileName; /* string to search */ /* other items of this structure are not valid, besacuse flags are not set. */ - int retVal = ListView_FindItem( hWndList, -1, &lvfi ); + retVal = ListView_FindItem( hWndList, -1, &lvfi ); if( retVal != -1 ) return TRUE; /* item found! */ return FALSE; /* item not found. */ } @@ -603,12 +605,17 @@ void SetDesktopBackColor() { /* Change system color */ INT iElement = COLOR_BACKGROUND; + HKEY hKey; + LONG result; + TCHAR clText[16]; + DWORD red, green, blue; + if( !SetSysColors( 1, &iElement, &g_backgroundDesktopColor ) ) MessageBox( g_hBackgroundPage, TEXT("SetSysColor() failed!"), /* these error texts can need internationalization? */ TEXT("Error!"), MB_ICONSTOP ); /* Write color to registry key: HKEY_CURRENT_USER\Control Panel\Colors\Background */ - HKEY hKey = NULL; - LONG result = ERROR_SUCCESS; + hKey = NULL; + result = ERROR_SUCCESS; result = RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, KEY_WRITE, &hKey ); if( result != ERROR_SUCCESS ) { @@ -619,11 +626,10 @@ void SetDesktopBackColor() /* On error result will not contain ERROR_SUCCESS. I don't know how to handle */ /* this case :( */ } - TCHAR clText[16] = {0}; - DWORD red = GetRValue( g_backgroundDesktopColor ); - DWORD green = GetGValue( g_backgroundDesktopColor ); - DWORD blue = GetBValue( g_backgroundDesktopColor ); - wsprintf( clText, TEXT("%d %d %d"), red, green, blue ); /* format string to be set to registry */ + red = GetRValue( g_backgroundDesktopColor ); + green = GetGValue( g_backgroundDesktopColor ); + blue = GetBValue( g_backgroundDesktopColor ); + _stprintf( clText, TEXT("%d %d %d"), red, green, blue ); /* format string to be set to registry */ RegSetValueEx( hKey, TEXT("Background"), 0, REG_SZ, (BYTE *)clText, lstrlen( clText )*sizeof(TCHAR) + sizeof(TCHAR) ); RegCloseKey( hKey ); } From 90759eb5a2935f0458e36673142dc4a532086f11 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Tue, 5 Sep 2006 16:28:20 +0000 Subject: [PATCH 014/488] Call NtUserDrawCaption directly svn path=/trunk/; revision=23923 --- reactos/dll/win32/user32/windows/nonclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/user32/windows/nonclient.c b/reactos/dll/win32/user32/windows/nonclient.c index 8df58d1edcc..6510554a6c4 100644 --- a/reactos/dll/win32/user32/windows/nonclient.c +++ b/reactos/dll/win32/user32/windows/nonclient.c @@ -410,7 +410,7 @@ DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active) CurrentRect.top += GetSystemMetrics(SM_CYCAPTION); } - DrawCaption(hWnd, hDC, &TempRect, CaptionFlags); + NtUserDrawCaption(hWnd, hDC, &TempRect, CaptionFlags); /* Draw buttons */ if (Style & WS_SYSMENU) From 173cb3c677ce2e3ed6870eb1aaa739a66c944590 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Tue, 5 Sep 2006 20:46:24 +0000 Subject: [PATCH 015/488] update it.rc languages translation by gabrielilardi at hotmail.it (Gabriel ilardi) svn path=/trunk/; revision=23924 --- reactos/base/applications/calc/lang/It.rc | 90 +++++++++++------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/reactos/base/applications/calc/lang/It.rc b/reactos/base/applications/calc/lang/It.rc index b7ae104b7a4..30ff7f97acb 100644 --- a/reactos/base/applications/calc/lang/It.rc +++ b/reactos/base/applications/calc/lang/It.rc @@ -1,7 +1,7 @@ /* * WineCalc (It.rc) * - * Copyright 2003 James Briggs + * Copyright 2006 Gabriel ilardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,9 +26,9 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { - IDS_APPNAME, "Calculator" + IDS_APPNAME, "Calcolatrice" - IDS_COPYRIGHT1, "Calculator 5.0. Licensed under LGPL 2" + IDS_COPYRIGHT1, "Calcolatrice 5.0. sotto licenza LGPL 2" IDS_COPYRIGHT2 "Copyright 2003, James Briggs" IDS_COPYRIGHT3 "San Jose, California, USA" IDS_COPYRIGHT4 "james@ActionMessage.com" @@ -43,84 +43,84 @@ STRINGTABLE DISCARDABLE IDS_BTN_MEM_PLUS, "M+" IDS_BTN_MEM_STATUS_M, "M" IDS_BTN_SQRT, "sqrt" - IDS_ERR_INVALID_INPUT, "Invalid input for function." - IDS_ERR_DIVIDE_BY_ZERO, "Cannot divide by zero." - IDS_ERR_UNDEFINED, "Result of function is undefined." + IDS_ERR_INVALID_INPUT, "Input invalido per la funzione." + IDS_ERR_DIVIDE_BY_ZERO, "Non si puň dividere per zero." + IDS_ERR_UNDEFINED, "Il risultato della funzione č indefinito." } MAIN_MENU MENU DISCARDABLE { - POPUP "&Edit" { - MENUITEM "&Copy Ctrl+C", IDM_COPY - MENUITEM "&Paste Ctrl+V", IDM_PASTE + POPUP "&Modifica" { + MENUITEM "&Copia Ctrl+C", IDM_COPY + MENUITEM "I&ncolla Ctrl+V", IDM_PASTE } - POPUP "&View" { + POPUP "&Visualizza" { MENUITEM "Standard", IDM_MODE_STANDARD - MENUITEM "Scientific", IDM_MODE_SCIENTIFIC + MENUITEM "Scientifica", IDM_MODE_SCIENTIFIC MENUITEM SEPARATOR - MENUITEM "Digit Grouping", IDM_DIGIT_GROUPING + MENUITEM "Raggruppamento cifre", IDM_DIGIT_GROUPING } - POPUP "&Help" { - MENUITEM "Help Topics", IDM_HELP_TOPICS + POPUP "&?" { + MENUITEM "Guida in linea", IDM_HELP_TOPICS MENUITEM SEPARATOR - MENUITEM "About Calculator", IDM_ABOUT + MENUITEM "Informazioni su Calcolatrice", IDM_ABOUT } } SCIMS_MENU MENU DISCARDABLE { - POPUP "&Edit" { - MENUITEM "&Copy Ctrl+C", IDM_COPY - MENUITEM "&Paste Ctrl+V", IDM_PASTE + POPUP "&Modifica" { + MENUITEM "&Copia Ctrl+C", IDM_COPY + MENUITEM "I&ncolla Ctrl+V", IDM_PASTE } - POPUP "&View" { + POPUP "&Visualizza" { MENUITEM "Standard", IDM_MODE_STANDARD - MENUITEM "Scientific", IDM_MODE_SCIENTIFIC + MENUITEM "Scientifica", IDM_MODE_SCIENTIFIC MENUITEM SEPARATOR MENUITEM "Hex\tF5", ID_CALC_NS_HEX - MENUITEM "Decimal\tF6", ID_CALC_NS_DEC - MENUITEM "Octal\tF7", ID_CALC_NS_OCT - MENUITEM "Binary\tF8", ID_CALC_NS_BIN + MENUITEM "Dec\tF6", ID_CALC_NS_DEC + MENUITEM "Oct\tF7", ID_CALC_NS_OCT + MENUITEM "Bin\tF8", ID_CALC_NS_BIN MENUITEM SEPARATOR - MENUITEM "Degrees\tF2", ID_CALC_MS_DEGREES - MENUITEM "Radians\tF3", ID_CALC_MS_RADIANS - MENUITEM "Grads\tF4", ID_CALC_MS_GRADS + MENUITEM "Gradi\tF2", ID_CALC_MS_DEGREES + MENUITEM "Radianti\tF3", ID_CALC_MS_RADIANS + MENUITEM "Gradienti\tF4", ID_CALC_MS_GRADS MENUITEM SEPARATOR - MENUITEM "Digit Grouping", IDM_DIGIT_GROUPING + MENUITEM "Raggruppamento cifre", IDM_DIGIT_GROUPING } - POPUP "&Help" { - MENUITEM "Help Topics", IDM_HELP_TOPICS + POPUP "&?" { + MENUITEM "Guida in linea", IDM_HELP_TOPICS MENUITEM SEPARATOR - MENUITEM "About Calculator", IDM_ABOUT + MENUITEM "Informazioni su calcolatrice", IDM_ABOUT } } SCIWS_MENU MENU DISCARDABLE { - POPUP "&Edit" { - MENUITEM "&Copy Ctrl+C", IDM_COPY - MENUITEM "&Paste Ctrl+V", IDM_PASTE + POPUP "&Modifica" { + MENUITEM "&Copia Ctrl+C", IDM_COPY + MENUITEM "I&ncolla Ctrl+V", IDM_PASTE } - POPUP "&View" { + POPUP "&Visualizza" { MENUITEM "Standard", IDM_MODE_STANDARD - MENUITEM "Scientific", IDM_MODE_SCIENTIFIC + MENUITEM "Scientifica", IDM_MODE_SCIENTIFIC MENUITEM SEPARATOR MENUITEM "Hex\tF5", ID_CALC_NS_HEX - MENUITEM "Decimal\tF6", ID_CALC_NS_DEC - MENUITEM "Octal\tF7", ID_CALC_NS_OCT - MENUITEM "Binary\tF8", ID_CALC_NS_BIN + MENUITEM "Dec\tF6", ID_CALC_NS_DEC + MENUITEM "Oct\tF7", ID_CALC_NS_OCT + MENUITEM "Bin\tF8", ID_CALC_NS_BIN MENUITEM SEPARATOR MENUITEM "Qword\tF12", ID_CALC_WS_QWORD MENUITEM "Dword\tF2", ID_CALC_WS_DWORD MENUITEM "Word\tF3", ID_CALC_WS_WORD MENUITEM "Byte\tF4", ID_CALC_WS_BYTE MENUITEM SEPARATOR - MENUITEM "Digit Grouping", IDM_DIGIT_GROUPING + MENUITEM "Raggruppamento cifre", IDM_DIGIT_GROUPING } - POPUP "&Help" { - MENUITEM "Help Topics", IDM_HELP_TOPICS + POPUP "&?" { + MENUITEM "Guida in linea", IDM_HELP_TOPICS MENUITEM SEPARATOR - MENUITEM "About Calculator", IDM_ABOUT + MENUITEM "Informazioni su calcolatrice", IDM_ABOUT } } @@ -132,19 +132,19 @@ END WHATS_THIS_MENU MENU DISCARDABLE { POPUP "" { - MENUITEM "What's This?", IDM_WHATS_THIS + MENUITEM "?", IDM_WHATS_THIS } } DLG_ABOUT DIALOG 12,0,120,82 -CAPTION "About GNU winecalc" +CAPTION "Informazioni su GNU winecalc" STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU BEGIN DEFPUSHBUTTON "OK", IDOK, 42, 60, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP END DLG_STATS DIALOG 12,0,125,78 -CAPTION "Statistics Box" +CAPTION "Statistiche" FONT 9, "Tahoma" STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE BEGIN From f0af84da4ee334fb0b5ef147af069cb40c05531c Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 6 Sep 2006 12:19:00 +0000 Subject: [PATCH 016/488] - MSVC Build Fixes svn path=/trunk/; revision=23925 --- reactos/include/ddk/ntifs.h | 8 ++ reactos/include/reactos/ccros.h | 6 +- .../reactos/drivers/diskdump/diskdump.h | 8 +- reactos/lib/rtl/bit.c | 57 ------------- reactos/lib/rtl/registry.c | 2 +- reactos/lib/rtl/rtl.rbuild | 1 - reactos/lib/rtl/sd.c | 2 +- reactos/ntoskrnl/include/internal/cc.h | 6 +- reactos/ntoskrnl/include/internal/dbgk.h | 2 +- reactos/ntoskrnl/include/internal/ex.h | 40 +++++----- reactos/ntoskrnl/include/internal/fsrtl.h | 8 +- reactos/ntoskrnl/include/internal/i386/ke.h | 18 +++-- reactos/ntoskrnl/include/internal/inbv.h | 2 +- reactos/ntoskrnl/include/internal/io.h | 26 ++---- reactos/ntoskrnl/include/internal/ke.h | 80 +++++++++---------- reactos/ntoskrnl/include/internal/lpc.h | 22 ++--- reactos/ntoskrnl/include/internal/mm.h | 52 ++++++------ reactos/ntoskrnl/include/internal/ntoskrnl.h | 26 ++++-- reactos/ntoskrnl/include/internal/ob_x.h | 8 +- reactos/ntoskrnl/include/internal/rtl.h | 2 +- reactos/ntoskrnl/include/internal/se.h | 19 ++--- reactos/ntoskrnl/include/internal/test.h | 8 +- reactos/ntoskrnl/include/ntoskrnl.h | 2 + reactos/ntoskrnl/ke/i386/abios.c | 2 +- 24 files changed, 178 insertions(+), 229 deletions(-) delete mode 100644 reactos/lib/rtl/bit.c diff --git a/reactos/include/ddk/ntifs.h b/reactos/include/ddk/ntifs.h index d4dc2cc6e5d..4ca545d2c26 100644 --- a/reactos/include/ddk/ntifs.h +++ b/reactos/include/ddk/ntifs.h @@ -4373,6 +4373,14 @@ SeTokenIsRestricted ( IN PACCESS_TOKEN Token ); + +NTSTATUS +NTAPI +SeLocateProcessImageName( + IN PEPROCESS Process, + OUT PUNICODE_STRING *pImageFileName +); + #endif /* (VER_PRODUCTBUILD >= 2195) */ NTKERNELAPI diff --git a/reactos/include/reactos/ccros.h b/reactos/include/reactos/ccros.h index a7907e4aea8..daad2cdcbc5 100644 --- a/reactos/include/reactos/ccros.h +++ b/reactos/include/reactos/ccros.h @@ -1,16 +1,16 @@ #ifndef __INCLUDE_DDK_NTIFS_H #define __INCLUDE_DDK_NTIFS_H -NTSTATUS STDCALL +NTSTATUS NTAPI CcRosInitializeFileCache (PFILE_OBJECT FileObject, ULONG CacheSegmentSize); -NTSTATUS STDCALL +NTSTATUS NTAPI CcRosReleaseFileCache (PFILE_OBJECT FileObject); struct _BCB; VOID -STDCALL +NTAPI CcRosTraceCacheMap ( struct _BCB* Bcb, BOOLEAN Trace ); diff --git a/reactos/include/reactos/drivers/diskdump/diskdump.h b/reactos/include/reactos/drivers/diskdump/diskdump.h index 59d134cfa4c..edfe2f42612 100644 --- a/reactos/include/reactos/drivers/diskdump/diskdump.h +++ b/reactos/include/reactos/drivers/diskdump/diskdump.h @@ -22,10 +22,10 @@ typedef struct _MM_CORE_DUMP_HEADER typedef struct MM_CORE_DUMP_FUNCTIONS { - NTSTATUS (STDCALL *DumpPrepare)(PDEVICE_OBJECT DeviceObject, PDUMP_POINTERS DumpPointers); - NTSTATUS (STDCALL *DumpInit)(VOID); - NTSTATUS (STDCALL *DumpWrite)(LARGE_INTEGER Address, PMDL Mdl); - NTSTATUS (STDCALL *DumpFinish)(VOID); + NTSTATUS (NTAPI *DumpPrepare)(PDEVICE_OBJECT DeviceObject, PDUMP_POINTERS DumpPointers); + NTSTATUS (NTAPI *DumpInit)(VOID); + NTSTATUS (NTAPI *DumpWrite)(LARGE_INTEGER Address, PMDL Mdl); + NTSTATUS (NTAPI *DumpFinish)(VOID); } MM_CORE_DUMP_FUNCTIONS, *PMM_CORE_DUMP_FUNCTIONS; #endif /* __DISKDUMP_H */ diff --git a/reactos/lib/rtl/bit.c b/reactos/lib/rtl/bit.c deleted file mode 100644 index be7008831b1..00000000000 --- a/reactos/lib/rtl/bit.c +++ /dev/null @@ -1,57 +0,0 @@ -/* COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib/rtl/bit.c - * PROGRAMER: Eric Kohl - */ - -/* INCLUDES *****************************************************************/ - -#include - -#define NDEBUG -#include - -/* FUNCTIONS ****************************************************************/ - -/* - * @implemented - */ -CCHAR NTAPI -RtlFindLeastSignificantBit(IN ULONGLONG Set) -{ - int i; - - if (Set == 0ULL) - return -1; - - for (i = 0; i < 64; i++) - { - if (Set & (1 << i)) - return (CCHAR)i; - } - - return -1; -} - - -/* - * @implemented - */ -CCHAR NTAPI -RtlFindMostSignificantBit(IN ULONGLONG Set) -{ - int i; - - if (Set == 0ULL) - return -1; - - for (i = 63; i >= 0; i--) - { - if (Set & (1 << i)) - return (CCHAR)i; - } - - return -1; -} - -/* EOF */ diff --git a/reactos/lib/rtl/registry.c b/reactos/lib/rtl/registry.c index 4ffed08cc7b..0da9966bba9 100644 --- a/reactos/lib/rtl/registry.c +++ b/reactos/lib/rtl/registry.c @@ -584,6 +584,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, PWSTR ValueName; UNICODE_STRING EnvValue; UNICODE_STRING EnvExpandedValue; + ULONG DataSize = 0; PAGED_CODE_RTL(); @@ -827,7 +828,6 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND)) { DPRINT("Expand REG_MULTI_SZ type\n"); - ULONG DataSize = 0; StringPtr = (PWSTR)ValueInfo->Data; while (DataSize < (ValueInfo->DataLength-2)) { diff --git a/reactos/lib/rtl/rtl.rbuild b/reactos/lib/rtl/rtl.rbuild index c3cacaa6d94..3d28108a795 100644 --- a/reactos/lib/rtl/rtl.rbuild +++ b/reactos/lib/rtl/rtl.rbuild @@ -43,7 +43,6 @@ access.c acl.c atom.c - bit.c bitmap.c bootdata.c compress.c diff --git a/reactos/lib/rtl/sd.c b/reactos/lib/rtl/sd.c index c8b117f066d..e5a382ecc31 100644 --- a/reactos/lib/rtl/sd.c +++ b/reactos/lib/rtl/sd.c @@ -929,7 +929,7 @@ RtlSelfRelativeToAbsoluteSD2(IN OUT PSECURITY_DESCRIPTOR SelfRelativeSD, * @implemented */ BOOLEAN NTAPI -RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, +RtlValidRelativeSecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptorInput, IN ULONG SecurityDescriptorLength, IN SECURITY_INFORMATION RequiredInformation) { diff --git a/reactos/ntoskrnl/include/internal/cc.h b/reactos/ntoskrnl/include/internal/cc.h index 1c2d0f0f7b7..95a43c1a223 100644 --- a/reactos/ntoskrnl/include/internal/cc.h +++ b/reactos/ntoskrnl/include/internal/cc.h @@ -62,14 +62,14 @@ typedef struct _INTERNAL_BCB } INTERNAL_BCB, *PINTERNAL_BCB; VOID -STDCALL +NTAPI CcMdlReadCompleteDev( IN PMDL MdlChain, IN PFILE_OBJECT FileObject ); VOID -STDCALL +NTAPI CcMdlWriteCompleteDev( IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, @@ -179,7 +179,7 @@ CcRosReleaseCacheSegment( ); NTSTATUS -STDCALL +NTAPI CcRosRequestCacheSegment( BCB *Bcb, ULONG FileOffset, diff --git a/reactos/ntoskrnl/include/internal/dbgk.h b/reactos/ntoskrnl/include/internal/dbgk.h index f757db10b47..d3feb09682b 100644 --- a/reactos/ntoskrnl/include/internal/dbgk.h +++ b/reactos/ntoskrnl/include/internal/dbgk.h @@ -2,7 +2,7 @@ #define __NTOSKRNL_INCLUDE_INTERNAL_DBGK_H VOID -STDCALL +NTAPI DbgkCreateThread(PVOID StartAddress); VOID diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 213c31fbcf8..0cbad42bfc1 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -32,63 +32,63 @@ extern POBJECT_TYPE ExEventPairObjectType; /* INITIALIZATION FUNCTIONS *************************************************/ VOID -STDCALL +NTAPI ExpWin32kInit(VOID); VOID -STDCALL +NTAPI ExInit2(VOID); VOID -STDCALL +NTAPI ExpInitTimeZoneInfo(VOID); VOID -STDCALL +NTAPI ExpInitializeWorkerThreads(VOID); VOID -STDCALL +NTAPI ExpInitLookasideLists(VOID); VOID -STDCALL +NTAPI ExpInitializeCallbacks(VOID); VOID -STDCALL +NTAPI ExpInitUuids(VOID); VOID -STDCALL +NTAPI ExpInitializeExecutive(VOID); VOID -STDCALL +NTAPI ExpInitializeEventImplementation(VOID); VOID -STDCALL +NTAPI ExpInitializeEventImplementation(VOID); VOID -STDCALL +NTAPI ExpInitializeEventPairImplementation(VOID); VOID -STDCALL +NTAPI ExpInitializeSemaphoreImplementation(VOID); VOID -STDCALL +NTAPI ExpInitializeMutantImplementation(VOID); VOID -STDCALL +NTAPI ExpInitializeTimerImplementation(VOID); VOID -STDCALL +NTAPI ExpInitializeProfileImplementation(VOID); VOID @@ -161,19 +161,19 @@ ExfWaitForRundownProtectionRelease( EX_HANDLE_ENTRY_INHERITABLE | \ EX_HANDLE_ENTRY_AUDITONCLOSE) -typedef VOID (STDCALL PEX_SWEEP_HANDLE_CALLBACK)( +typedef VOID (NTAPI PEX_SWEEP_HANDLE_CALLBACK)( PHANDLE_TABLE_ENTRY HandleTableEntry, HANDLE Handle, PVOID Context ); -typedef BOOLEAN (STDCALL PEX_DUPLICATE_HANDLE_CALLBACK)( +typedef BOOLEAN (NTAPI PEX_DUPLICATE_HANDLE_CALLBACK)( PHANDLE_TABLE HandleTable, PHANDLE_TABLE_ENTRY HandleTableEntry, PVOID Context ); -typedef BOOLEAN (STDCALL PEX_CHANGE_HANDLE_CALLBACK)( +typedef BOOLEAN (NTAPI PEX_CHANGE_HANDLE_CALLBACK)( PHANDLE_TABLE HandleTable, PHANDLE_TABLE_ENTRY HandleTableEntry, PVOID Context @@ -253,7 +253,7 @@ ExChangeHandle( /* PSEH EXCEPTION HANDLING **************************************************/ LONG -STDCALL +NTAPI ExSystemExceptionFilter(VOID); static __inline _SEH_FILTER(_SEH_ExSystemExceptionFilter) @@ -698,7 +698,7 @@ NTAPI ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId); VOID -STDCALL +NTAPI ExTimerRundown(VOID); #define InterlockedDecrementUL(Addend) \ diff --git a/reactos/ntoskrnl/include/internal/fsrtl.h b/reactos/ntoskrnl/include/internal/fsrtl.h index c74f5719a70..7ff0f24c4d7 100644 --- a/reactos/ntoskrnl/include/internal/fsrtl.h +++ b/reactos/ntoskrnl/include/internal/fsrtl.h @@ -17,15 +17,15 @@ typedef struct _FILE_LOCK_TOC VOID INIT_FUNCTION -STDCALL +NTAPI FsRtlpInitNotifyImplementation(VOID); VOID -STDCALL +NTAPI FsRtlpInitFileLockingImplementation(VOID); VOID -STDCALL +NTAPI FsRtlpFileLockCancelRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp @@ -49,7 +49,7 @@ FsRtlpFastUnlockAllByKey( IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, - IN DWORD Key, + IN ULONG Key, IN BOOLEAN UseKey, IN PVOID Context OPTIONAL ); diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 9925e96ad06..430819fabe3 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -99,11 +99,11 @@ KeCreateApplicationProcessorIdleThread(ULONG Id); typedef VOID -(STDCALL*PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine, +(NTAPI*PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine, PVOID StartContext); VOID -STDCALL +NTAPI Ke386InitThreadWithContext(PKTHREAD Thread, PKSYSTEM_ROUTINE SystemRoutine, PKSTART_ROUTINE StartRoutine, @@ -112,7 +112,7 @@ Ke386InitThreadWithContext(PKTHREAD Thread, #ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */ VOID -STDCALL +NTAPI KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine, PKSTART_ROUTINE StartRoutine, PVOID StartContext, @@ -239,8 +239,9 @@ static __forceinline void Ke386SetPageTableDirectory(ULONG X) #error Unknown compiler for inline assembler #endif -static __inline struct _KPCR * KeGetCurrentKPCR( - VOID) +FORCEINLINE +struct _KPCR * +KeGetCurrentKPCR(VOID) { ULONG Value; #if defined(__GNUC__) @@ -255,8 +256,10 @@ static __inline struct _KPCR * KeGetCurrentKPCR( return (struct _KPCR *) Value; } -static __inline struct _KPRCB * KeGetCurrentPrcb( - VOID) +#ifdef __GNUC__ +FORCEINLINE +struct _KPRCB * +KeGetCurrentPrcb(VOID) { ULONG Value; #if defined(__GNUC__) @@ -270,6 +273,7 @@ static __inline struct _KPRCB * KeGetCurrentPrcb( #endif return (struct _KPRCB *) Value; } +#endif #endif #endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_KE_H */ diff --git a/reactos/ntoskrnl/include/internal/inbv.h b/reactos/ntoskrnl/include/internal/inbv.h index c79d3083a17..ea6003c0378 100644 --- a/reactos/ntoskrnl/include/internal/inbv.h +++ b/reactos/ntoskrnl/include/internal/inbv.h @@ -8,7 +8,7 @@ /* FUNCTIONS *****************************************************************/ BOOLEAN -STDCALL +NTAPI InbvDisplayString(IN PCHAR String); #endif /* NTOSKRNL_INBV_H */ diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index 1e30e5e883f..c0dc51181bc 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -730,7 +730,7 @@ IopSaveBootLogToFile( // I/O Cancellation Routines // VOID -STDCALL +NTAPI IoCancelThreadIo( IN PETHREAD Thread ); @@ -777,7 +777,7 @@ RawFsIsRawFileSystemDeviceObject( ); NTSTATUS -STDCALL +NTAPI RawFsDriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath @@ -787,7 +787,7 @@ RawFsDriverEntry( // PnP Root MiniDriver // NTSTATUS -STDCALL +NTAPI PnpRootDriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath @@ -908,13 +908,13 @@ IopParseFile( ); VOID -STDCALL +NTAPI IopDeleteFile( IN PVOID ObjectBody ); NTSTATUS -STDCALL +NTAPI IopSecurityFile( IN PVOID ObjectBody, IN SECURITY_OPERATION_CODE OperationCode, @@ -927,7 +927,7 @@ IopSecurityFile( ); NTSTATUS -STDCALL +NTAPI IopQueryNameFile( IN PVOID ObjectBody, IN BOOLEAN HasName, @@ -938,7 +938,7 @@ IopQueryNameFile( ); VOID -STDCALL +NTAPI IopCloseFile( IN PEPROCESS Process OPTIONAL, IN PVOID Object, @@ -957,7 +957,7 @@ IopInitTimerImplementation( ); VOID -STDCALL +NTAPI IopRemoveTimerFromTimerList( IN PIO_TIMER Timer ); @@ -981,16 +981,6 @@ xHalQueryDriveLayout( OUT PDRIVE_LAYOUT_INFORMATION *LayoutInfo ); -#undef HalExamineMBR -VOID -FASTCALL -HalExamineMBR( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG MBRTypeIdentifier, - OUT PVOID *Buffer -); - VOID FASTCALL xHalIoAssignDriveLetters( diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index f184b4e0101..1559097c27d 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -215,12 +215,12 @@ extern KSPIN_LOCK DispatcherDatabaseLock; /* Readies a Thread for Execution. */ BOOLEAN -STDCALL +NTAPI KiDispatchThreadNoLock(ULONG NewThreadStatus); /* Readies a Thread for Execution. */ VOID -STDCALL +NTAPI KiDispatchThread(ULONG NewThreadStatus); /* Finds a new thread to run */ @@ -235,7 +235,7 @@ NTAPI KiReadyThread(IN PKTHREAD Thread); NTSTATUS -STDCALL +NTAPI KeSuspendThread(PKTHREAD Thread); NTSTATUS @@ -246,7 +246,7 @@ KiSwapContext( ); VOID -STDCALL +NTAPI KiAdjustQuantumThread(IN PKTHREAD Thread); VOID @@ -296,11 +296,11 @@ KeFindNextRightSetAffinity( ); VOID -STDCALL +NTAPI DbgBreakPointNoBugCheck(VOID); VOID -STDCALL +NTAPI KeInitializeProfile( struct _KPROFILE* Profile, struct _KPROCESS* Process, @@ -312,53 +312,53 @@ KeInitializeProfile( ); VOID -STDCALL +NTAPI KeStartProfile( struct _KPROFILE* Profile, PVOID Buffer ); BOOLEAN -STDCALL +NTAPI KeStopProfile(struct _KPROFILE* Profile); ULONG -STDCALL +NTAPI KeQueryIntervalProfile(KPROFILE_SOURCE ProfileSource); VOID -STDCALL +NTAPI KeSetIntervalProfile( KPROFILE_SOURCE ProfileSource, ULONG Interval ); VOID -STDCALL +NTAPI KeProfileInterrupt( PKTRAP_FRAME TrapFrame ); VOID -STDCALL +NTAPI KeProfileInterruptWithSource( IN PKTRAP_FRAME TrapFrame, IN KPROFILE_SOURCE Source ); BOOLEAN -STDCALL +NTAPI KiRosPrintAddress(PVOID Address); VOID -STDCALL +NTAPI KeUpdateRunTime( PKTRAP_FRAME TrapFrame, KIRQL Irql ); VOID -STDCALL +NTAPI KiExpireTimers( PKDPC Dpc, PVOID DeferredContext, @@ -431,7 +431,7 @@ KeSwitchKernelStack( ); VOID -STDCALL +NTAPI KeRundownThread(VOID); NTSTATUS @@ -439,11 +439,11 @@ NTAPI KeReleaseThread(PKTHREAD Thread); LONG -STDCALL +NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread); VOID -STDCALL +NTAPI KiSetPriorityThread( PKTHREAD Thread, KPRIORITY Priority, @@ -458,7 +458,7 @@ KiDispatcherObjectWake( ); VOID -STDCALL +NTAPI KeExpireTimers( PKDPC Apc, PVOID Arg1, @@ -483,7 +483,7 @@ KiAbortWaitThread( ); VOID -STDCALL +NTAPI KeInitializeProcess( struct _KPROCESS *Process, KPRIORITY Priority, @@ -507,15 +507,15 @@ KeSetPriorityAndQuantumProcess( ); ULONG -STDCALL +NTAPI KeForceResumeThread(IN PKTHREAD Thread); BOOLEAN -STDCALL +NTAPI KeDisableThreadApcQueueing(IN PKTHREAD Thread); BOOLEAN -STDCALL +NTAPI KiInsertTimer( PKTIMER Timer, LARGE_INTEGER DueTime @@ -533,7 +533,7 @@ NTAPI KeGetStackTopThread(struct _ETHREAD* Thread); VOID -STDCALL +NTAPI KeContextToTrapFrame( PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, @@ -543,7 +543,7 @@ KeContextToTrapFrame( ); VOID -STDCALL +NTAPI KiDeliverApc( KPROCESSOR_MODE PreviousMode, PVOID Reserved, @@ -551,11 +551,11 @@ KiDeliverApc( ); VOID -STDCALL +NTAPI KiCheckForKernelApcDelivery(VOID); LONG -STDCALL +NTAPI KiInsertQueue( IN PKQUEUE Queue, IN PLIST_ENTRY Entry, @@ -563,7 +563,7 @@ KiInsertQueue( ); ULONG -STDCALL +NTAPI KeSetProcess( struct _KPROCESS* Process, KPRIORITY Increment, @@ -571,11 +571,11 @@ KeSetProcess( ); VOID -STDCALL +NTAPI KeInitializeEventPair(PKEVENT_PAIR EventPair); VOID -STDCALL +NTAPI KiInitializeUserApc( IN PKEXCEPTION_FRAME Reserved, IN PKTRAP_FRAME TrapFrame, @@ -586,14 +586,14 @@ KiInitializeUserApc( ); PLIST_ENTRY -STDCALL +NTAPI KeFlushQueueApc( IN PKTHREAD Thread, IN KPROCESSOR_MODE PreviousMode ); VOID -STDCALL +NTAPI KiAttachProcess( struct _KTHREAD *Thread, struct _KPROCESS *Process, @@ -602,18 +602,18 @@ KiAttachProcess( ); VOID -STDCALL +NTAPI KiSwapProcess( struct _KPROCESS *NewProcess, struct _KPROCESS *OldProcess ); BOOLEAN -STDCALL +NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode); BOOLEAN -STDCALL +NTAPI KeRemoveQueueApc(PKAPC Apc); VOID @@ -665,7 +665,7 @@ NTAPI KiDeliverUserApc(PKTRAP_FRAME TrapFrame); VOID -STDCALL +NTAPI KiMoveApcState( PKAPC_STATE OldState, PKAPC_STATE NewState @@ -713,18 +713,18 @@ KiUserTrapHandler( ); VOID -STDCALL +NTAPI KePushAndStackSwitchAndSysRet( ULONG Push, PVOID NewStack ); VOID -STDCALL +NTAPI KeStackSwitchAndRet(PVOID NewStack); VOID -STDCALL +NTAPI KeBugCheckWithTf( ULONG BugCheckCode, ULONG BugCheckParameter1, @@ -739,7 +739,7 @@ NTAPI KeFlushCurrentTb(VOID); VOID -STDCALL +NTAPI KeRosDumpStackFrames( PULONG Frame, ULONG FrameCount diff --git a/reactos/ntoskrnl/include/internal/lpc.h b/reactos/ntoskrnl/include/internal/lpc.h index af40b0e14d0..6e0d1830419 100644 --- a/reactos/ntoskrnl/include/internal/lpc.h +++ b/reactos/ntoskrnl/include/internal/lpc.h @@ -75,14 +75,14 @@ typedef struct _QUEUEDMESSAGE } QUEUEDMESSAGE, *PQUEUEDMESSAGE; NTSTATUS -STDCALL +NTAPI LpcRequestPort( PEPORT Port, PPORT_MESSAGE LpcMessage ); NTSTATUS -STDCALL +NTAPI LpcSendTerminationPort( PEPORT Port, LARGE_INTEGER CreationTime @@ -91,7 +91,7 @@ LpcSendTerminationPort( /* Code in ntoskrnl/lpc/close.c */ VOID -STDCALL +NTAPI LpcpClosePort( IN PEPROCESS Process OPTIONAL, IN PVOID Object, @@ -101,7 +101,7 @@ LpcpClosePort( ); VOID -STDCALL +NTAPI LpcpDeletePort(IN PVOID ObjectBody); VOID @@ -111,38 +111,38 @@ LpcExitThread(IN PETHREAD Thread); /* Code in ntoskrnl/lpc/queue.c */ VOID -STDCALL +NTAPI EiEnqueueConnectMessagePort( IN OUT PEPORT Port, IN PQUEUEDMESSAGE Message ); VOID -STDCALL +NTAPI EiEnqueueMessagePort( IN OUT PEPORT Port, IN PQUEUEDMESSAGE Message ); VOID -STDCALL +NTAPI EiEnqueueMessageAtHeadPort( IN OUT PEPORT Port, IN PQUEUEDMESSAGE Message ); PQUEUEDMESSAGE -STDCALL +NTAPI EiDequeueConnectMessagePort(IN OUT PEPORT Port); PQUEUEDMESSAGE -STDCALL +NTAPI EiDequeueMessagePort(IN OUT PEPORT Port); /* Code in ntoskrnl/lpc/port.c */ NTSTATUS -STDCALL +NTAPI LpcpInitializePort( IN OUT PEPORT Port, IN USHORT Type, @@ -156,7 +156,7 @@ LpcpInitSystem (VOID); /* Code in ntoskrnl/lpc/reply.c */ NTSTATUS -STDCALL +NTAPI EiReplyOrRequestPort( IN PEPORT Port, IN PPORT_MESSAGE LpcReply, diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index f23b43ad674..db296c65c8b 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -374,7 +374,7 @@ NTAPI MmInitMemoryAreas(VOID); NTSTATUS -STDCALL +NTAPI MmCreateMemoryArea( PMADDRESS_SPACE AddressSpace, ULONG Type, @@ -388,21 +388,21 @@ MmCreateMemoryArea( ); PMEMORY_AREA -STDCALL +NTAPI MmLocateMemoryAreaByAddress( PMADDRESS_SPACE AddressSpace, PVOID Address ); ULONG_PTR -STDCALL +NTAPI MmFindGapAtAddress( PMADDRESS_SPACE AddressSpace, PVOID Address ); NTSTATUS -STDCALL +NTAPI MmFreeMemoryArea( PMADDRESS_SPACE AddressSpace, PMEMORY_AREA MemoryArea, @@ -411,7 +411,7 @@ MmFreeMemoryArea( ); NTSTATUS -STDCALL +NTAPI MmFreeMemoryAreaByPtr( PMADDRESS_SPACE AddressSpace, PVOID BaseAddress, @@ -420,11 +420,11 @@ MmFreeMemoryAreaByPtr( ); VOID -STDCALL +NTAPI MmDumpMemoryAreas(PMADDRESS_SPACE AddressSpace); PMEMORY_AREA -STDCALL +NTAPI MmLocateMemoryAreaByRegion( PMADDRESS_SPACE AddressSpace, PVOID Address, @@ -432,7 +432,7 @@ MmLocateMemoryAreaByRegion( ); PVOID -STDCALL +NTAPI MmFindGap( PMADDRESS_SPACE AddressSpace, ULONG_PTR Length, @@ -441,7 +441,7 @@ MmFindGap( ); VOID -STDCALL +NTAPI MmReleaseMemoryAreaIfDecommitted( struct _EPROCESS *Process, PMADDRESS_SPACE AddressSpace, @@ -472,7 +472,7 @@ MmGetMdlPageAddress( /* pool.c *******************************************************************/ PVOID -STDCALL +NTAPI ExAllocateNonPagedPoolWithTag( POOL_TYPE type, ULONG size, @@ -481,7 +481,7 @@ ExAllocateNonPagedPoolWithTag( ); PVOID -STDCALL +NTAPI ExAllocatePagedPoolWithTag( POOL_TYPE Type, ULONG size, @@ -489,11 +489,11 @@ ExAllocatePagedPoolWithTag( ); VOID -STDCALL +NTAPI ExFreeNonPagedPool(PVOID block); VOID -STDCALL +NTAPI ExFreePagedPool(IN PVOID Block); VOID @@ -501,7 +501,7 @@ NTAPI MmInitializePagedPool(VOID); PVOID -STDCALL +NTAPI MiAllocateSpecialPool( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, @@ -510,7 +510,7 @@ MiAllocateSpecialPool( ); BOOLEAN -STDCALL +NTAPI MiRaisePoolQuota( IN POOL_TYPE PoolType, IN ULONG CurrentMaxQuota, @@ -596,7 +596,7 @@ MmWriteToSwapPage( ); NTSTATUS -STDCALL +NTAPI MmDumpToPagingFile( ULONG BugCode, ULONG BugCodeParameter1, @@ -617,7 +617,7 @@ MmShowOutOfSpaceMessagePagingFile(VOID); /* process.c ****************************************************************/ NTSTATUS -STDCALL +NTAPI MmCreateProcessAddressSpace( IN PEPROCESS Process, IN PROS_SECTION_OBJECT Section OPTIONAL, @@ -625,11 +625,11 @@ MmCreateProcessAddressSpace( ); NTSTATUS -STDCALL +NTAPI MmCreatePeb(struct _EPROCESS *Process); PTEB -STDCALL +NTAPI MmCreateTeb( struct _EPROCESS *Process, PCLIENT_ID ClientId, @@ -637,7 +637,7 @@ MmCreateTeb( ); VOID -STDCALL +NTAPI MmDeleteTeb( struct _EPROCESS *Process, PTEB Teb @@ -713,7 +713,7 @@ MmPageOutVirtualMemory( ); NTSTATUS -STDCALL +NTAPI MmQueryAnonMem( PMEMORY_AREA MemoryArea, PVOID Address, @@ -814,11 +814,11 @@ MmInitializePageOp(VOID); /* process.c *****************************************************************/ PVOID -STDCALL +NTAPI MmCreateKernelStack(BOOLEAN GuiStack); VOID -STDCALL +NTAPI MmDeleteKernelStack(PVOID Stack, BOOLEAN GuiStack); @@ -1201,7 +1201,7 @@ MmGetPfnForProcess( ); NTSTATUS -STDCALL +NTAPI MmCopyMmInfo( struct _EPROCESS *Src, struct _EPROCESS *Dest, @@ -1308,14 +1308,14 @@ MmGetFileObjectForSection( ); PVOID -STDCALL +NTAPI MmAllocateSection( IN ULONG Length, PVOID BaseAddress ); NTSTATUS -STDCALL +NTAPI MmQuerySectionView( PMEMORY_AREA MemoryArea, PVOID Address, diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index 743709528d5..2871087b450 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -5,9 +5,15 @@ * Use these to place a function in a specific section of the executable */ #define PLACE_IN_SECTION(s) __attribute__((section (s))) +#ifdef _GNUC_ #define INIT_FUNCTION PLACE_IN_SECTION("init") #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 _NTOSKRNL_ @@ -56,11 +62,11 @@ typedef struct __DESCRIPTOR VOID MmInitSystem(ULONG Phase, PROS_LOADER_PARAMETER_BLOCK LoaderBlock, ULONG LastKernelAddress); VOID IoInit(VOID); VOID IoInit2(BOOLEAN BootLog); -VOID STDCALL IoInit3(VOID); +VOID NTAPI IoInit3(VOID); VOID ObInit(VOID); VOID PsInit(VOID); VOID CmInitializeRegistry(VOID); -VOID STDCALL CmInitHives(BOOLEAN SetupBoot); +VOID NTAPI CmInitHives(BOOLEAN SetupBoot); VOID CmInit2(PCHAR CommandLine); VOID CmShutdownRegistry(VOID); BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize); @@ -82,6 +88,7 @@ RtlpLogException(IN PEXCEPTION_RECORD ExceptionRecord, IN ULONG Size); /* FIXME: Interlocked functions that need to be made into a public header */ +#ifdef __GNUC__ FORCEINLINE LONG InterlockedAnd(IN OUT LONG volatile *Target, @@ -121,6 +128,7 @@ InterlockedOr(IN OUT LONG volatile *Target, return j; } +#endif /* * generic information class probing code @@ -156,10 +164,11 @@ typedef struct _INFORMATION_CLASS_INFO #define IQS(TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags) \ { sizeof(TypeQuery), sizeof(TypeSet), sizeof(AlignmentQuery), sizeof(AlignmentSet), Flags } -static __inline NTSTATUS -DefaultSetInfoBufferCheck(UINT Class, +FORCEINLINE +NTSTATUS +DefaultSetInfoBufferCheck(ULONG Class, const INFORMATION_CLASS_INFO *ClassList, - UINT ClassListEntries, + ULONG ClassListEntries, PVOID Buffer, ULONG BufferLength, KPROCESSOR_MODE PreviousMode) @@ -205,10 +214,11 @@ DefaultSetInfoBufferCheck(UINT Class, return Status; } -static __inline NTSTATUS -DefaultQueryInfoBufferCheck(UINT Class, +FORCEINLINE +NTSTATUS +DefaultQueryInfoBufferCheck(ULONG Class, const INFORMATION_CLASS_INFO *ClassList, - UINT ClassListEntries, + ULONG ClassListEntries, PVOID Buffer, ULONG BufferLength, PULONG ReturnLength, diff --git a/reactos/ntoskrnl/include/internal/ob_x.h b/reactos/ntoskrnl/include/internal/ob_x.h index c1dfeec9659..42e469922da 100644 --- a/reactos/ntoskrnl/include/internal/ob_x.h +++ b/reactos/ntoskrnl/include/internal/ob_x.h @@ -7,7 +7,7 @@ */ VOID -static __inline +FORCEINLINE ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo) { /* Check if we have a security descriptor */ @@ -22,12 +22,12 @@ ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo) } PVOID -static __inline +FORCEINLINE ObpAllocateCapturedAttributes(IN PP_NPAGED_LOOKASIDE_NUMBER Type) { - PKPRCB Prcb = KeGetCurrentPrcb(); PVOID Buffer; PNPAGED_LOOKASIDE_LIST List; + PKPRCB Prcb = KeGetCurrentPrcb(); /* Get the P list first */ List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P; @@ -63,8 +63,8 @@ static __inline ObpFreeCapturedAttributes(IN PVOID Buffer, IN PP_NPAGED_LOOKASIDE_NUMBER Type) { - PKPRCB Prcb = KeGetCurrentPrcb(); PNPAGED_LOOKASIDE_LIST List; + PKPRCB Prcb = KeGetCurrentPrcb(); /* Use the P List */ List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P; diff --git a/reactos/ntoskrnl/include/internal/rtl.h b/reactos/ntoskrnl/include/internal/rtl.h index d3d0c9e2d59..7aa46a163db 100644 --- a/reactos/ntoskrnl/include/internal/rtl.h +++ b/reactos/ntoskrnl/include/internal/rtl.h @@ -11,7 +11,7 @@ extern PUSHORT NlsUnicodeUpcaseTable; extern PUSHORT NlsUnicodeLowercaseTable; VOID -STDCALL +NTAPI RtlpInitNls(VOID); VOID diff --git a/reactos/ntoskrnl/include/internal/se.h b/reactos/ntoskrnl/include/internal/se.h index facbdae868f..a158320434f 100644 --- a/reactos/ntoskrnl/include/internal/se.h +++ b/reactos/ntoskrnl/include/internal/se.h @@ -137,13 +137,6 @@ SeInitializeProcessAuditName( OUT POBJECT_NAME_INFORMATION *AuditInfo ); -NTSTATUS -NTAPI -SeLocateProcessImageName( - IN PEPROCESS Process, - OUT PUNICODE_STRING *ProcessImageName -); - NTSTATUS NTAPI SeCreateAccessStateEx( @@ -163,7 +156,7 @@ SeIsTokenChild( ); NTSTATUS -STDCALL +NTAPI SepCreateImpersonationTokenDacl( PTOKEN Token, PTOKEN PrimaryToken, @@ -175,7 +168,7 @@ NTAPI SepInitializeTokenImplementation(VOID); PTOKEN -STDCALL +NTAPI SepCreateSystemProcessToken(VOID); BOOLEAN @@ -239,7 +232,7 @@ SepPrivilegeCheck( ); NTSTATUS -STDCALL +NTAPI SepDuplicateToken( PTOKEN Token, POBJECT_ATTRIBUTES ObjectAttributes, @@ -306,7 +299,7 @@ SepReleaseAcl( ); NTSTATUS -STDCALL +NTAPI SeDefaultObjectMethod( PVOID Object, SECURITY_OPERATION_CODE OperationType, @@ -344,11 +337,11 @@ SeSetWorldSecurityDescriptor( KeLeaveCriticalRegion(); \ while(0) -VOID STDCALL +VOID NTAPI SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, OUT PACCESS_MASK DesiredAccess); -VOID STDCALL +VOID NTAPI SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, OUT PACCESS_MASK DesiredAccess); diff --git a/reactos/ntoskrnl/include/internal/test.h b/reactos/ntoskrnl/include/internal/test.h index 955fa7944e6..504298f9bb6 100644 --- a/reactos/ntoskrnl/include/internal/test.h +++ b/reactos/ntoskrnl/include/internal/test.h @@ -2,11 +2,11 @@ #define __NTOSKRNL_INCLUDE_INTERNAL_TEST_H typedef VOID -STDCALL +NTAPI PExFreePool(PVOID Block); typedef PMDL -STDCALL +NTAPI PMmCreateMdl( PMDL Mdl, PVOID Base, @@ -14,7 +14,7 @@ PMmCreateMdl( ); typedef VOID -STDCALL +NTAPI PMmProbeAndLockPages( PMDL Mdl, KPROCESSOR_MODE AccessMode, @@ -26,7 +26,7 @@ FASTCALL PObDereferenceObject(PVOID Object); typedef NTSTATUS -STDCALL +NTAPI PObReferenceObjectByHandle( HANDLE Handle, ACCESS_MASK DesiredAccess, diff --git a/reactos/ntoskrnl/include/ntoskrnl.h b/reactos/ntoskrnl/include/ntoskrnl.h index 1fdfb208761..92d3ecb9253 100644 --- a/reactos/ntoskrnl/include/ntoskrnl.h +++ b/reactos/ntoskrnl/include/ntoskrnl.h @@ -13,7 +13,9 @@ #define _NTSYSTEM_ /* DDK/IFS/NDK Headers */ +#ifdef __GNUC__ #include +#endif #include #include #include diff --git a/reactos/ntoskrnl/ke/i386/abios.c b/reactos/ntoskrnl/ke/i386/abios.c index b47feb86a94..0f05043c597 100644 --- a/reactos/ntoskrnl/ke/i386/abios.c +++ b/reactos/ntoskrnl/ke/i386/abios.c @@ -18,7 +18,7 @@ * @unimplemented */ NTSTATUS -STDCALL +NTAPI KeI386FlatToGdtSelector(IN ULONG Base, IN USHORT Length, IN USHORT Selector) From 1fc89de8473fa2f75eeaee158d72c7850983ed0c Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Wed, 6 Sep 2006 16:31:03 +0000 Subject: [PATCH 017/488] Some win32k docs (from win32k rewrite branch). svn path=/trunk/; revision=23926 --- reactos/media/doc/win32k_refs.txt | 79 +++++++++++ reactos/media/doc/winsta and desktops.txt | 156 ++++++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 reactos/media/doc/win32k_refs.txt create mode 100644 reactos/media/doc/winsta and desktops.txt diff --git a/reactos/media/doc/win32k_refs.txt b/reactos/media/doc/win32k_refs.txt new file mode 100644 index 00000000000..75c479fd280 --- /dev/null +++ b/reactos/media/doc/win32k_refs.txt @@ -0,0 +1,79 @@ +References: +----------- + +window -> desktop +window -> class + +thread_input -> thread + +thread -> process +process -> winsta +thread -> desktop +desktop -> winsta +winsta -> session + +NOTE: Message queue has 1:1 relationship with (w32)thread and need no ref. count. + -If the (w32)thread is destroyed, so is the message queue. + -If the (w32)thread exist, so does the message queue. + So if you want the queue to hang around, you reference the thread instead. + +^ This is wrong, one can attach message queue to different thread using +AttachThreadInput. The number of threads sharing a queue is stored in the +message queue structure and can be considered a reference count. Also on +Windows systems there is maintained a global list of thread attachments. + +Above references create following dependencies: +----------------------------------------------- + +window -> desktop -> winsta -> session +window -> class + +thread -> process -> winsta -> session +thread -> desktop -> winsta -> session + +process -> winsta -> session + +NtUser/NtGdi/win32k syscalls +---------------------------- + +A process and/or thread automatically gets converted to a GUI thread / +process when the first syscall from the shadow service table is called (ie. +any NtUser* or NtGdi* call). GUI threads have bigger kernel stack (FIXME: +not the case on ReactOS yet) and have associated storage for the Win32 +structures. The conversion itself happens in the syscall handler and the +win32k callbacks (registered with PsEstablishWin32Callouts) are called +accordingly. + +A process automatically establishes a connection to a window station on the +GUI thread conversion. The Win32 process initialization callback routine +also creates and initializes the W32PROCESS structure and associates it with +the process. + +Similary for thread the callback routine automatically assigns a desktop +when the thread is converted to GUI thread. The thread also gets a W32THREAD +structure, a message queue and a thread input structures. + +Beware that there is an exception to these rules and that's WinLogon. Since +at the time the process starts no window stations or desktops exist, none +are assigned to the the initial thread / process. The first Win32k calls +the thread does are to create the window station and desktop and to associate +them with itself. + +FIXME: At the time of this writing there's a second exception, a "primitive +message queue" thread in CSRSS that is created before any window stations +exist and is used to capture keyboard input in console mode. Eventually we +should get rid of it and replace is with hidden window w/ focus or something +similar. + +Generally this means that when you are in a Win32k syscall function (other +than the window station or desktop functions) you can be 100% sure that the +following exists: + +- Process window station +- Win32 process structure +- Win32 thread structure +- Thread message queue +- Thread input +- Thread desktop + +There is no need to validate any of these values, because they MUST EXIST! diff --git a/reactos/media/doc/winsta and desktops.txt b/reactos/media/doc/winsta and desktops.txt new file mode 100644 index 00000000000..1896e4624dd --- /dev/null +++ b/reactos/media/doc/winsta and desktops.txt @@ -0,0 +1,156 @@ +SAWinSta +-------- +I write a GUI appication, and the user may run it in task schedule. Since +windows 2000/XP treat schedule task as a service, the schedule service can +not be associated with interactive desktop object in the in 2 states +1) No user log on +2) Log on with another account. +I write a test program, and find when the schedule service starts, the +station/desktop will be "SAWinSta\Desktop" in both cases + +Is there any way to let schedule service associated with interactive desktop +in these 2 cases? + +thanks +------------------------------------------- + +Service-0x0-3e7$ +---------------- +By default Win32 services associated with non-visible windows station (for +services which run in the local system account it is Service-0x0-3e7$) and they +can't (without using special flag MB_SERVICE_NOTIFICATION or +MB_DEFAULT_DESKTOP_ONLY in the MessageBox function) interact with user. +However, you may configure a service to have GUI capabilities. Just set Type +field of the registry service entry equal SERVICE_INTERACTIVE_PROCESS. When +this key is specified SCM will connect the service with WinSta0 instead +Service-0x0-3e7$ and it will alow to display windows and dialog boxes. + +------------------------------------------------- + +WinSta0 +------- + +-The one-and-only interactive WinSta. +-No other winsta can be visible/active. +-Only WinSta0 can recieve input. +-All other WinSta's are invisible/non-interactive WinStas. + +What good is a invisible WinSta? Its used for running services in thus services cant +interact with the user. + +There are limits to what u can do in a invisible WinSta. +-Bitblt wont work for instance, since nothing is really displayed in a invisible WinSta (to save resources). + No point in using GDI resources for stuff noone can see. +-SendInput wont work + + + +--------------------------------------------------- + MORE INFORMATION + +A Window station can either be interactive or noninteractive. (At the moment on Windows NT 3.51 and 4.0, only "Winsta0" can be an interactive Window station.) Any Desktops created on the interactive Window station will have the ability to become active. An active Desktop encompasses the ability for user objects (such as windows and dialog boxes) created on the Desktop to be visible to the interactively logged-on user (that is, the user who logs on the system via CTRL-ALT-DELETE) and receive user input. + +When the interactively logged-on user launches any processes, these processes are associated with the "default" Desktop in the "Winsta0" Window station. The "default" Desktop is considered the active Desktop. A process on the active Desktop could switch Desktops such that another Desktop becomes the active Desktop such as the "Winlogon" Desktop. Only one Desktop can be the active Desktop at any one time. + +Desktops associated with a noninteractive Window station can create user objects. These objects will never be visible to the interactively logged-on user and will never receive any user input. If you have a noninteractive Service running in the LocalSystem account, any user objects created by the service will not be visible to the interactively logged-on user. In addition, any processes launched by the service will also not be visible. +If our desktop has the same name as the active one, we are running on the +active (input) desktop. This is true because desktops have exactly one +name each, and within a window station, desktop names must be unique +---------------------------------------------------------------- + +Process closing window station with CloseWindowStation can't be assigned to the window station + it is closing. + + +The reason is that each session has its own CSRSS, as well as instanced +win32k.sys data. So in each session, you basically have a complete copy of +Windows that doesn't know about the existance of any other copy. You're not +just on a different desktop/windowstation when you're in a different +session. + + +Lawrence, you are wrong. HWNDs are valid throughout the whole +windowstation, not only the creating process. That's because they +are pointers, but not in your address space... + + +The CreateDesktop function creates a new desktop on the window station associated with the calling process. + +PROCESS: +-every w32 process is associated with a WindowStation +-can move between window stations (well, with strict limitations i would guess eg. what if + windows have been created and is using the winsta heap? or can multiple winsta heaps be mapped into + one process?? ) + +THREADS: +-can only enumerate windows on its desktop (but u can easely switch to a different desk) +-every w32 thread is associated with a Desktop +-Threads can switch between desktops, and windows are created on the thread's current desktop + (a thread can have windows on multiple desktops? IS THIS REALLY TRUE?) + +DESKTOP: +-owns windows +-Only one desktop at a time can interact with the user, and that desktop must necessarily +be associated with Winsta0 +-Only one desktop is visible to the user and only one can receives input at any time +-contain a logical display surface +-contin windows (or a pointer to the desktop window) +-contain menus +-contain hooks +-holds UI objects, such as windows, menus, and hooks +-Once a window is created it cannot move between desktops + +SESSION: +-session = win32k instance +-Every session contains one or more windows stations +-A given login session has only one window station with access to user interactions +(term server has multiple login sessions) +-each logon session is associated with a window station + +WINDOW STATION: +-only Winsta0 has access to the display +-Only one window station, called Winsta0, can interact with the user display, keyboard, mouse +-is a secure object +-Only the interactive window station WinSta0, can display + output or receive input. Other window stations are used by "services" + (but cant u switch winsta?? so a noninteractive winsta becomes active?) +-contains a set of global atoms +-contains a clipboard +-contains a set of desktop objects +-contains handle table(s) (handles are valid throughout the whole windowstation, not only the creating process) +-contain heaps (pointer(s) to the section heap(s) shared between user32/gdi32/win32k) +-A Windows 2000 session will have several windows stations, one assigned to the logon session + of the interactive user, and others assigned to the Winlogon process, the secure screen saver + process, and any service that runs in a security context other than that of the interactive user. + + The interactive window station assigned to the logon session of the interactive user also contains + the keyboard, mouse, and display device. The interactive window station is visible to the user and + can receive input from the user. All other window stations are noninteractive, which means that + they cannot be made visible to the user, and cannot receive user input. + +WINDOWS +-is owned by a desktop +-windows are tied to the window station where they started +-u cant move windows between desktops either + +The system associates a desktop with a thread when that thread is created +The desktop associated with a thread must be on the window station associated with the thread's process. +A thread can use the SetThreadDesktop function to change its desktop. +The GetThreadDesktop function retrieves a handle to the desktop associated with a specified thread. + +The calling process must have an associated window station, either assigned by the system at process creation time or set by SetProcessWindowStation. A desktop is a secure object contained within a window station object. + + +There can be several window stations in the system but only one of them can +be the interactive window station. That is the only windowstation whose +processes can communicate with the user (it has a visible desktop and can +receive mouse and keyboard input). A desktop lives inside a windowstation +and provides a display to the user. Only one desktop can be the active +desktop for a particular windowstation at any time. Furthermore only a +desktop that lives inside the interactive windowstation and is the currently +active desktop for that windowstation is visible to the user. On your +average Windows NT system there are at least 3 desktops inside the +interactive windowstation: the 'shell', winlogon and the screensaver. Each +process that runs on your system (and hence services as well) run inside a +windowstation and each thread in that process runs in the same windowstation +but can run in a different desktop. From 7f0a82ce58a31c71f2a19442895d2e26111d1e33 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 6 Sep 2006 18:43:35 +0000 Subject: [PATCH 018/488] Fix MSVC 2005 compilation (Platform SDK is correctly included) svn path=/trunk/; revision=23927 --- reactos/base/shell/explorer/utility/utility.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/base/shell/explorer/utility/utility.h b/reactos/base/shell/explorer/utility/utility.h index db37ee51767..e3de958b6a8 100644 --- a/reactos/base/shell/explorer/utility/utility.h +++ b/reactos/base/shell/explorer/utility/utility.h @@ -207,11 +207,11 @@ using namespace std; #include -/* not necessary with correct include file order for comdef.h ("\include" path first) +/* not necessary with correct include file order for comdef.h ("\include" path first) */ #if _MSC_VER>=1300 // VS.Net #define _NO_COMUTIL #endif -*/ + #if defined(_MSC_VER) && !defined(_NO_COMUTIL) From 84269d79179192cd0a773b15444a17b1067b3765 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 6 Sep 2006 18:59:30 +0000 Subject: [PATCH 019/488] Fixed difference in signedness warnings svn path=/trunk/; revision=23928 --- reactos/ntoskrnl/ke/ipi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/reactos/ntoskrnl/ke/ipi.c b/reactos/ntoskrnl/ke/ipi.c index 8592d96eeb1..0f1df39651f 100644 --- a/reactos/ntoskrnl/ke/ipi.c +++ b/reactos/ntoskrnl/ke/ipi.c @@ -33,7 +33,7 @@ KiIpiSendRequest(KAFFINITY TargetSet, ULONG IpiRequest) if (TargetSet & Current) { Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); - Ke386TestAndSetBit(IpiRequest, (PLONG)&Pcr->Prcb->IpiFrozen); + Ke386TestAndSetBit(IpiRequest, (PULONG)&Pcr->Prcb->IpiFrozen); HalRequestIpi(i); } } @@ -59,18 +59,18 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, Prcb = KeGetCurrentPrcb(); - if (Ke386TestAndClearBit(IPI_APC, (PLONG)&Prcb->IpiFrozen)) + if (Ke386TestAndClearBit(IPI_APC, (PULONG)&Prcb->IpiFrozen)) { HalRequestSoftwareInterrupt(APC_LEVEL); } - if (Ke386TestAndClearBit(IPI_DPC, (PLONG)&Prcb->IpiFrozen)) + if (Ke386TestAndClearBit(IPI_DPC, (PULONG)&Prcb->IpiFrozen)) { Prcb->DpcInterruptRequested = TRUE; HalRequestSoftwareInterrupt(DISPATCH_LEVEL); } - if (Ke386TestAndClearBit(IPI_SYNCH_REQUEST, (PLONG)&Prcb->IpiFrozen)) + if (Ke386TestAndClearBit(IPI_SYNCH_REQUEST, (PULONG)&Prcb->IpiFrozen)) { (void)InterlockedDecrementUL(&Prcb->SignalDone->CurrentPacket[1]); if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0)) @@ -91,7 +91,7 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, } } ((VOID (STDCALL*)(PVOID))(Prcb->SignalDone->WorkerRoutine))(Prcb->SignalDone->CurrentPacket[0]); - Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), (PLONG)&Prcb->SignalDone->TargetSet); + Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), (PULONG)&Prcb->SignalDone->TargetSet); if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0)) { #ifdef DBG @@ -140,7 +140,7 @@ KiIpiSendPacket(KAFFINITY TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID { Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb; while(0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0)); - Ke386TestAndSetBit(IPI_SYNCH_REQUEST, (PLONG)&Prcb->IpiFrozen); + Ke386TestAndSetBit(IPI_SYNCH_REQUEST, (PULONG)&Prcb->IpiFrozen); if (Processor != CurrentPrcb->SetMember) { HalRequestIpi(i); From 7aae13b091657bfb4984e95f8098e6fad5e56bf3 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 6 Sep 2006 19:28:35 +0000 Subject: [PATCH 020/488] Fixed difference in signedness warnings svn path=/trunk/; revision=23929 --- reactos/subsystems/win32/win32k/objects/dibobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/dibobj.c b/reactos/subsystems/win32/win32k/objects/dibobj.c index c06aa51b9b4..18b2eff6058 100644 --- a/reactos/subsystems/win32/win32k/objects/dibobj.c +++ b/reactos/subsystems/win32/win32k/objects/dibobj.c @@ -705,8 +705,8 @@ IntCreateDIBitmap(PDC Dc, const BITMAPINFOHEADER *header, LONG height; WORD planes; WORD bpp; - DWORD compr; - DWORD dibsize; + LONG compr; + LONG dibsize; BOOL fColor; SIZEL size; From 753aa1c0e29a108de990c45772004bf609062fab Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Wed, 6 Sep 2006 19:37:53 +0000 Subject: [PATCH 021/488] * halfplement reading / writing Console User settings * remove hardcoded constants * shuffle initialization code :-) * changing console text / background color now works :-))))))) * changing cursor works only for one input (needs be investigated) svn path=/trunk/; revision=23930 --- .../subsystems/win32/csrss/win32csr/conio.c | 46 +- reactos/subsystems/win32/csrss/win32csr/en.rc | 7 + .../win32/csrss/win32csr/guiconsole.c | 629 ++++++++++++++---- .../win32/csrss/win32csr/resource.h | 9 + .../win32/csrss/win32csr/tuiconsole.c | 2 +- .../subsystems/win32/csrss/win32csr/w32csr.h | 2 + .../win32/csrss/win32csr/win32csr.rbuild | 1 + 7 files changed, 567 insertions(+), 129 deletions(-) diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index e00858bf7f4..6361ed2269f 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -126,8 +126,6 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, { ClearLineBuffer(Buffer); } - Buffer->CursorInfo.bVisible = TRUE; - Buffer->CursorInfo.dwSize = 5; Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; Buffer->CurrentX = 0; Buffer->CurrentY = 0; @@ -158,8 +156,6 @@ CsrInitConsole(PCSRSS_CONSOLE Console) Console->EarlyReturn = FALSE; Console->ActiveBuffer = NULL; InitializeListHead(&Console->InputEvents); - InitializeListHead(&Console->ProcessList); - Console->CodePage = GetOEMCP(); Console->OutputCodePage = GetOEMCP(); @@ -180,6 +176,9 @@ CsrInitConsole(PCSRSS_CONSOLE Console) /* allocate console screen buffer */ NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); + /* init screen buffer with defaults */ + NewBuffer->CursorInfo.bVisible = TRUE; + NewBuffer->CursorInfo.dwSize = 5; /* make console active, and insert into console list */ Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer; /* add a reference count because the buffer is tied to the console */ @@ -275,14 +274,17 @@ CSR_API(CsrAllocConsole) { /* Allocate a console structure */ NewConsole = TRUE; - Console = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_CONSOLE)); + Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE)); if (NULL == Console) { DPRINT1("Not enough memory for console\n"); Request->Status = STATUS_NO_MEMORY; return STATUS_NO_MEMORY; } - + /* initialize list head */ + InitializeListHead(&Console->ProcessList); + /* insert process data required for GUI initialization */ + InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry); /* Initialize the Console */ Request->Status = CsrInitConsole(Console); if (!NT_SUCCESS(Request->Status)) @@ -361,10 +363,12 @@ CSR_API(CsrAllocConsole) ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher; DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher); - /* Insert into the list */ -//////////////////////////// - InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry); -/////////////////////////// + if (!NewConsole) + { + /* Insert into the list if it has not been added */ + InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry); + } + return STATUS_SUCCESS; } @@ -372,7 +376,6 @@ CSR_API(CsrFreeConsole) { PCSRSS_CONSOLE Console; - DPRINT("CsrFreeConsole\n"); Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); @@ -388,7 +391,6 @@ CSR_API(CsrFreeConsole) { ConioDeleteConsole((Object_t *) Console); } - return STATUS_SUCCESS; } @@ -1999,7 +2001,8 @@ CSR_API(CsrGetCursorInfo) { return Request->Status = Status; } - Request->Data.GetCursorInfoRequest.Info = Buff->CursorInfo; + Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible; + Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize; ConioUnlockScreenBuffer(Buff); return Request->Status = STATUS_SUCCESS; @@ -2220,13 +2223,24 @@ CSR_API(CsrCreateScreenBuffer) { Buff->MaxX = Console->ActiveBuffer->MaxX; Buff->MaxY = Console->ActiveBuffer->MaxY; + Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible; + Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize; + } + else + { + Buff->CursorInfo.bVisible = TRUE; + Buff->CursorInfo.dwSize = 5; } if (Buff->MaxX == 0) - Buff->MaxX = 80; + { + Buff->MaxX = 80; + } if (Buff->MaxY == 0) - Buff->MaxY = 25; + { + Buff->MaxY = 25; + } Status = CsrInitConsoleScreenBuffer(Console, Buff); if(! NT_SUCCESS(Status)) @@ -3308,7 +3322,7 @@ CSR_API(CsrGetProcessList) current_entry = current_entry->Flink) { current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - if(nItems++ < Request->Data.GetProcessListRequest.nMaxIds) + if(++nItems < Request->Data.GetProcessListRequest.nMaxIds) { *(Buffer++) = current->ProcessId; nCopied++; diff --git a/reactos/subsystems/win32/csrss/win32csr/en.rc b/reactos/subsystems/win32/csrss/win32csr/en.rc index d3474c1417f..dc0ac6c0dc2 100644 --- a/reactos/subsystems/win32/csrss/win32csr/en.rc +++ b/reactos/subsystems/win32/csrss/win32csr/en.rc @@ -38,4 +38,11 @@ BEGIN IDS_FIND "Find..." IDS_DEFAULTS "Defaults" IDS_PROPERTIES "Properties" + IDS_SCROLLHERE "Scroll Here" + IDS_SCROLLTOP "Scroll Top" + IDS_SCROLLBOTTOM "Scroll Bottom" + IDS_SCROLLPAGE_UP "Page Up" + IDS_SCROLLPAGE_DOWN "Page Down" + IDS_SCROLLUP "Scroll Up" + IDS_SCROLLDOWN "Scroll Down" END diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index 5a078c93e00..2ddda23bae3 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -32,14 +32,26 @@ typedef struct GUI_CONSOLE_DATA_TAG BOOL MouseDown; HMODULE ConsoleLibrary; HANDLE hGuiInitEvent; + HWND hVScrollBar; + HWND hHScrollBar; WCHAR FontName[LF_FACESIZE]; DWORD FontSize; DWORD FontWeight; - DWORD CursorSize; DWORD HistoryNoDup; DWORD FullScreen; DWORD QuickEdit; DWORD InsertMode; + DWORD NumberOfHistoryBuffers; + DWORD HistoryBufferSize; + DWORD WindowPosition; + DWORD ScreenBufferSize; + DWORD UseRasterFonts; + COLORREF ScreenText; + COLORREF ScreenBackground; + COLORREF PopupBackground; + COLORREF PopupText; + COLORREF Colors[16]; + WCHAR szProcessName[MAX_PATH]; } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA; #ifndef WM_APP @@ -49,6 +61,7 @@ typedef struct GUI_CONSOLE_DATA_TAG #define PM_DESTROY_CONSOLE (WM_APP + 2) #define CURSOR_BLINK_TIME 500 +#define DEFAULT_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY) static BOOL ConsInitialized = FALSE; static HWND NotifyWnd; @@ -82,6 +95,26 @@ static const GUICONSOLE_MENUITEM GuiConsoleMainMenuItems[] = { 0, NULL, 0 } /* End of list */ }; +static const COLORREF s_Colors[] = +{ + RGB(0, 0, 0), + RGB(0, 0, 128), + RGB(0, 128, 0), + RGB(0, 128, 128), + RGB(128, 0, 0), + RGB(128, 0, 128), + RGB(128, 128, 0), + RGB(192, 192, 192), + RGB(128, 128, 128), + RGB(0, 0, 255), + RGB(0, 255, 0), + RGB(0, 255, 255), + RGB(255, 0, 0), + RGB(255, 0, 255), + RGB(255, 255, 0), + RGB(255, 255, 255) +}; + /* FUNCTIONS *****************************************************************/ static VOID FASTCALL @@ -215,7 +248,7 @@ GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, } static BOOL FASTCALL -GuiConsoleOpenUserSettings(HWND hWnd, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired) +GuiConsoleOpenUserSettings(PGUI_CONSOLE_DATA GuiData, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired, BOOL bCreate) { WCHAR szProcessName[MAX_PATH]; WCHAR szBuffer[MAX_PATH]; @@ -224,9 +257,7 @@ GuiConsoleOpenUserSettings(HWND hWnd, DWORD ProcessId, PHKEY hSubKey, REGSAM sam WCHAR CurDrive[] = { 'A',':', 0 }; HANDLE hProcess; HKEY hKey; - WCHAR * ptr, *res; - static const WCHAR szSystemRoot[] = { '%','S','y','s','t','e','m','R','o','o','t','%', 0 }; - + WCHAR * ptr; /* * console properties are stored under @@ -243,21 +274,42 @@ GuiConsoleOpenUserSettings(HWND hWnd, DWORD ProcessId, PHKEY hSubKey, REGSAM sam * i.e. %SystemRoot%_system32_cmd.exe */ - if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) - return FALSE; + DPRINT("GuiConsoleOpenUserSettings entered\n"); - fLength = GetProcessImageFileNameW(hProcess, szProcessName, MAX_PATH); + if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) + { + DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n"); + return FALSE; + } + + fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR)); CloseHandle(hProcess); if (!fLength) { - DPRINT1("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess); - return FALSE; + DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess); + return FALSE; } - + /* + * try the process name as path + */ ptr = wcsrchr(szProcessName, L'\\'); + wcscpy(GuiData->szProcessName, ptr); + swprintf(szBuffer, L"Console%s",ptr); + DPRINT("#1 Path : %S\n", szBuffer); + + if (bCreate) + { + if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS) + { + RegCloseKey(hKey); + return TRUE; + } + RegCloseKey(hKey); + return FALSE; + } if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) { @@ -265,50 +317,179 @@ GuiConsoleOpenUserSettings(HWND hWnd, DWORD ProcessId, PHKEY hSubKey, REGSAM sam return TRUE; } - dwBitmask = GetLogicalDrives(); - while(dwBitmask) - { - if (dwBitmask & 0x1) - { - dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); - if (dwLength) - { - if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) - { - wcscpy(szBuffer, CurDrive); - wcscat(&szBuffer[(sizeof(CurDrive)/sizeof(WCHAR))-1], &szProcessName[dwLength-2]); - break; - } - } - } - dwBitmask = (dwBitmask >> 1); - CurDrive[0]++; - } - - wLength = GetWindowsDirectoryW(szProcessName, MAX_PATH); + /* + * try the "Shortcut to processname" as path + * FIXME: detect wheter the process was started as a shortcut + */ - if (!wcsncmp(szProcessName, szBuffer, wLength)) - { - wcscpy(szProcessName, szSystemRoot); - wcscpy(&szProcessName[(sizeof(szSystemRoot) / sizeof(WCHAR))-1], &szBuffer[wLength]); - ptr = res = szProcessName; - } - else - { - ptr = res = szBuffer; - } - - while((ptr = wcschr(szProcessName, L'\\'))) - ptr[0] = L'_'; - - if (RegOpenKeyExW(hKey, res, 0, samDesired, hSubKey) == ERROR_SUCCESS) + swprintf(szBuffer, L"Console\\Shortcut to %S", ptr); + DPRINT("#2 Path : %S\n", szBuffer); + if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) { + swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr); RegCloseKey(hKey); return TRUE; } + + /* + * if the path contains \\Device\\HarddiskVolume1\... remove it + */ + + if (szProcessName[0] == L'\\') + { + dwBitmask = GetLogicalDrives(); + while(dwBitmask) + { + if (dwBitmask & 0x1) + { + dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); + if (dwLength) + { + if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) + { + wcscpy(szProcessName, CurDrive); + RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1); + break; + } + } + } + dwBitmask = (dwBitmask >> 1); + CurDrive[0]++; + } + } + + /* + * last attempt: check whether the file is under %SystemRoot% + * and use path like Console\%SystemRoot%_dir_dir2_file.exe + */ + + wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH); + if (wLength) + { + if (!wcsncmp(szProcessName, szBuffer, wLength)) + { + /* replace slashes by underscores */ + while((ptr = wcschr(szProcessName, L'\\'))) + ptr[0] = L'_'; + + swprintf(szBuffer, L"Console\\\%SystemRoot\%%S", &szProcessName[wLength]); + DPRINT("#3 Path : %S\n", szBuffer); + if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) + { + swprintf(GuiData->szProcessName, L"\%SystemRoot\%%S", &szProcessName[wLength]); + RegCloseKey(hKey); + return TRUE; + } + } + } RegCloseKey(hKey); return FALSE; } + +static VOID +GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData) +{ + HKEY hKey; + PCSRSS_PROCESS_DATA ProcessData; + + if (Console->ProcessList.Flink == &Console->ProcessList) + { + DPRINT("GuiConsoleWriteUserSettings: No Process!!!\n"); + return; + } + ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); + if (!GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ | KEY_WRITE, TRUE)) + { + return; + } + + if (Console->ActiveBuffer->CursorInfo.dwSize <= 1) + { + RegDeleteKeyW(hKey, L"CursorSize"); + } + else + { + RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); + } + + if (GuiData->NumberOfHistoryBuffers == 5) + { + RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); + } + else + { + RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD)); + } + + if (GuiData->HistoryBufferSize == 50) + { + RegDeleteKeyW(hKey, L"HistoryBufferSize"); + } + else + { + RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD)); + } + + if (GuiData->FullScreen == FALSE) + { + RegDeleteKeyW(hKey, L"FullScreen"); + } + else + { + RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD)); + } + + if ( GuiData->QuickEdit == FALSE) + { + RegDeleteKeyW(hKey, L"QuickEdit"); + } + else + { + RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD)); + } + + if (GuiData->InsertMode == TRUE) + { + RegDeleteKeyW(hKey, L"InsertMode"); + } + else + { + RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); + } + + if (GuiData->HistoryNoDup == FALSE) + { + RegDeleteKeyW(hKey, L"HistoryNoDup"); + } + else + { + RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD)); + } + + if (GuiData->ScreenText == RGB(192, 192, 192)) + { + /* + * MS uses console attributes instead of real color + */ + RegDeleteKeyW(hKey, L"ScreenText"); + } + else + { + RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF)); + } + + if (GuiData->ScreenBackground == RGB(0, 0, 0)) + { + RegDeleteKeyW(hKey, L"ScreenBackground"); + } + else + { + RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF)); + } + + RegCloseKey(hKey); +} + static void FASTCALL GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) { @@ -321,7 +502,13 @@ GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA WCHAR szValue[MAX_PATH]; DWORD Value; - RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + { + DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n"); + return; + } + + DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys); for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) { @@ -343,13 +530,24 @@ GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA else break; } - if (!wcscmp(szValueName, L"CursorSize")) { if (Value == 0x32) - GuiData->CursorSize = Value; + { + Buffer->CursorInfo.dwSize = Value; + } else if (Value == 0x64) - GuiData->CursorSize = Value; + { + Buffer->CursorInfo.dwSize = Value; + } + } + else if (!wcscmp(szValueName, L"ScreenText")) + { + GuiData->ScreenText = Value; + } + else if (!wcscmp(szValueName, L"ScreenBackground")) + { + GuiData->ScreenBackground = Value; } else if (!wcscmp(szValueName, L"FaceName")) { @@ -374,11 +572,11 @@ GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA } else if (!wcscmp(szValueName, L"ScreenBufferSize")) { - if( Buffer) - { - Buffer->MaxX = LOWORD(Value); - Buffer->MaxY = HIWORD(Value); - } + if(Buffer) + { + Buffer->MaxX = LOWORD(Value); + Buffer->MaxY = HIWORD(Value); + } } else if (!wcscmp(szValueName, L"FullScreen")) { @@ -404,20 +602,31 @@ GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_ wcscpy(GuiData->FontName, L"Bitstream Vera Sans Mono"); GuiData->FontSize = 0x0008000C; // font is 8x12 GuiData->FontWeight = FW_NORMAL; - GuiData->CursorSize = 0; GuiData->HistoryNoDup = FALSE; GuiData->FullScreen = FALSE; GuiData->QuickEdit = FALSE; GuiData->InsertMode = TRUE; + GuiData->HistoryBufferSize = 50; + GuiData->NumberOfHistoryBuffers = 5; + GuiData->ScreenText = RGB(192, 192, 192); + GuiData->ScreenBackground = RGB(0, 0, 0); + GuiData->PopupText = RGB(128, 0, 128); + GuiData->PopupBackground = RGB(255, 255, 255); + GuiData->WindowPosition = UINT_MAX; + GuiData->ScreenBufferSize = MAKELONG(80, 300); //FIXME + GuiData->UseRasterFonts = TRUE; + memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); Console->Size.X = 80; Console->Size.Y = 25; if (Buffer) - { - Buffer->MaxX = 80; - Buffer->MaxY = 25; - } + { + Buffer->MaxX = 80; + Buffer->MaxY = 25; + Buffer->CursorInfo.bVisible = TRUE; + Buffer->CursorInfo.dwSize = 5; + } } @@ -446,7 +655,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create) if (Console->ProcessList.Flink != &Console->ProcessList) { ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); - if (GuiConsoleOpenUserSettings(hWnd, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ)) + if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE)) { GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer); RegCloseKey(hKey); @@ -528,9 +737,8 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create) Rect.bottom - Rect.top, FALSE); SetTimer(hWnd, 1, CURSOR_BLINK_TIME, NULL); - SetEvent(GuiData->hGuiInitEvent); - GuiConsoleCreateSysMenu(Console); + SetEvent(GuiData->hGuiInitEvent); return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create); } @@ -546,10 +754,18 @@ GuiConsoleRGBFromAttribute(BYTE Attribute) } static VOID FASTCALL -GuiConsoleSetTextColors(HDC Dc, BYTE Attribute) +GuiConsoleSetTextColors(HDC Dc, BYTE Attribute, PCSRSS_SCREEN_BUFFER Buff, COLORREF TextColor, COLORREF BkColor) { - SetTextColor(Dc, GuiConsoleRGBFromAttribute(Attribute & 0x0f)); - SetBkColor(Dc, GuiConsoleRGBFromAttribute((Attribute & 0xf0) >> 4)); + if (Attribute != Buff->DefaultAttrib) + { + SetTextColor(Dc, GuiConsoleRGBFromAttribute(Attribute & 0x0f)); + SetBkColor(Dc, GuiConsoleRGBFromAttribute((Attribute & 0xf0) >> 4)); + } + else + { + SetTextColor(Dc, TextColor); + SetBkColor(Dc, BkColor); + } } static VOID FASTCALL @@ -656,7 +872,10 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, LastAttribute = Buff->Buffer[(TopLine * Buff->MaxX + LeftChar) * 2 + 1]; GuiConsoleSetTextColors(hDC, - LastAttribute); + LastAttribute, + Buff, + GuiData->ScreenText, + GuiData->ScreenBackground); EnterCriticalSection(&Buff->Header.Lock); @@ -692,7 +911,10 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, if (Attribute != LastAttribute) { GuiConsoleSetTextColors(hDC, - Attribute); + Attribute, + Buff, + GuiData->ScreenText, + GuiData->ScreenBackground); LastAttribute = Attribute; } } @@ -729,7 +951,16 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, CursorHeight = 1; } From = Buff->Buffer + (Buff->CurrentY * Buff->MaxX + Buff->CurrentX) * 2 + 1; - CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(*From)); + + if (*From != DEFAULT_ATTRIB) + { + CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(*From)); + } + else + { + CursorBrush = CreateSolidBrush(GuiData->ScreenText); + } + OldBrush = SelectObject(hDC, CursorBrush); PatBlt(hDC, @@ -1026,6 +1257,7 @@ GuiConsoleHandleNcDestroy(HWND hWnd) PCSRSS_CONSOLE Console; PGUI_CONSOLE_DATA GuiData; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); KillTimer(hWnd, 1); Console->PrivateData = NULL; @@ -1176,25 +1408,29 @@ GuiConsoleRightMouseDown(HWND hWnd) } + static VOID -GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults) +GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData) { PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; APPLET_PROC CPLFunc; TCHAR szBuffer[MAX_PATH]; + ConsoleInfo SharedInfo; + + DPRINT("GuiConsoleShowConsoleProperties entered\n"); GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); if (GuiData == NULL) - { - DPRINT1("GuiConsoleGetDataPointers failed\n"); - return; - } + { + DPRINT("GuiConsoleGetDataPointers failed\n"); + return; + } + if (GuiData->ConsoleLibrary == NULL) { - GetWindowsDirectory(szBuffer,MAX_PATH); - _tcscat(szBuffer, _T("\\system32\\console.dll")); + GetWindowsDirectory(szBuffer,MAX_PATH); + _tcscat(szBuffer, _T("\\system32\\console.dll")); GuiData->ConsoleLibrary = LoadLibrary(szBuffer); if (GuiData->ConsoleLibrary == NULL) @@ -1206,39 +1442,47 @@ GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults) CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet")); if (!CPLFunc) - { - DPRINT("Error: Console.dll misses CPlApplet export\n"); - return; - } + { + DPRINT("Error: Console.dll misses CPlApplet export\n"); + return; + } + /* setup struct */ + SharedInfo.InsertMode = GuiData->InsertMode; + SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize; + SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers; + SharedInfo.ScreenText = GuiData->ScreenText; + SharedInfo.ScreenBackground = GuiData->ScreenBackground; + SharedInfo.PopupText = GuiData->PopupText; + SharedInfo.PopupBackground = GuiData->PopupBackground; + SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y); + SharedInfo.WindowPosition = GuiData->WindowPosition; + SharedInfo.ScreenBuffer = GuiData->ScreenBufferSize; + SharedInfo.UseRasterFonts = GuiData->UseRasterFonts; + SharedInfo.FontSize = (DWORD)GuiData->FontSize; + SharedInfo.FontWeight = GuiData->FontWeight; + SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; + SharedInfo.HistoryNoDup = GuiData->HistoryNoDup; + SharedInfo.FullScreen = GuiData->FullScreen; + SharedInfo.QuickEdit = GuiData->QuickEdit; + memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors)); + if (!CPLFunc(hWnd, CPL_INIT, 0, 0)) - { - DPRINT("Error: failed to initialize console.dll\n"); - return; - } + { + DPRINT("Error: failed to initialize console.dll\n"); + return; + } if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1) - { - DPRINT("Error: console.dll returned unexpected CPL count\n"); - return; - } + { + DPRINT("Error: console.dll returned unexpected CPL count\n"); + return; + } - CPLFunc(hWnd, CPL_DBLCLK, 0, Defaults); - - // TODO - // - // read back the changes from console.dll - // - // if the changes are system-wide then - // console.dll should have written it to - // registry - // - // if the changes only apply to this session - // then exchange this info with console.dll in - // some private way + CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); } static BOOL FASTCALL -GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam) +GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, PGUI_CONSOLE_DATA GuiData) { BOOL Ret = TRUE; @@ -1253,11 +1497,11 @@ GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam) break; case ID_SYSTEM_DEFAULTS: - GuiConsoleShowConsoleProperties(hWnd, TRUE); + GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData); break; case ID_SYSTEM_PROPERTIES: - GuiConsoleShowConsoleProperties(hWnd, FALSE); + GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData); break; default: @@ -1268,10 +1512,161 @@ GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam) return Ret; } +static VOID FASTCALL +GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED) + { + DPRINT1("GuiConsoleResize X %d Y %d\n", LOWORD(lParam), HIWORD(lParam)); + } +} + +VOID FASTCALL +GuiConsoleCreateScrollBar(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, HWND NewWindow) +{ + HMENU hMenu; + HWND hVScrollBar; + HWND hHScrollBar; + SCROLLINFO sInfo; + + hMenu = CreatePopupMenu(); + if (hMenu == NULL) + { + DPRINT("CreatePopupMenu failed\n"); + return; + } + + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN); + + hVScrollBar = CreateWindowExW(0L, + L"ScrollBar", + (LPWSTR)NULL, + WS_CHILD | WS_VSCROLL, + 0, + 0, + 200, + 50, + NewWindow, + NULL, //hMenu, + GetModuleHandleW(NULL), + (LPVOID)GuiData); + + if (hVScrollBar) + { + + /* set scrollbar sizes */ + sInfo.cbSize = sizeof(SCROLLINFO); + sInfo.fMask = SIF_RANGE | SIF_POS; + sInfo.nMin = 0; + sInfo.nMax = Console->ActiveBuffer->MaxY; + sInfo.nPos = 0; + SetScrollInfo(hVScrollBar, SB_CTL, &sInfo, TRUE); + ShowScrollBar(NewWindow, SB_CTL, TRUE); + GuiData->hVScrollBar = hVScrollBar; + } + + if (Console->ActiveBuffer->MaxX > Console->Size.X) + { + hHScrollBar = CreateWindowExW(0L, + L"ScrollBar", + (LPWSTR)NULL, + WS_CHILD | WS_HSCROLL, + 0, + 0, + 200, + CW_USEDEFAULT, + NewWindow, + hMenu, + GetModuleHandleW(NULL), + (LPVOID)GuiData); + if (hHScrollBar) + { + sInfo.nMax = Console->ActiveBuffer->MaxX; + SetScrollInfo(hHScrollBar, SB_CTL, &sInfo, TRUE); + GuiData->hHScrollBar = hHScrollBar; + } + } +} + +static VOID FASTCALL +GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo) +{ + DWORD windx, windy; + RECT rect; + + /* apply text / background color */ + GuiData->ScreenText = pConInfo->ScreenText; + GuiData->ScreenBackground = pConInfo->ScreenBackground; + + /* apply cursor size */ + Console->ActiveBuffer->CursorInfo.dwSize = max(min(pConInfo->CursorSize, 1), 100); + + windx = LOWORD(pConInfo->ScreenBuffer); + windy = HIWORD(pConInfo->ScreenBuffer); + + if (windx != Console->ActiveBuffer->MaxX || windy != Console->ActiveBuffer->MaxY) + { + // + // TODO + // resize screen buffer + + + // Console->ActiveBuffer->MaxX = windx; + // Console->ActiveBuffer->MaxY = windy; + } + + windx = LOWORD(pConInfo->WindowSize); + windy = HIWORD(pConInfo->WindowSize); + + if (windx != Console->Size.X || windy != Console->Size.Y) + { + /* resize window */ + Console->Size.X = windx; + Console->Size.Y = windy; + + GetWindowRect(pConInfo->hConsoleWindow, &rect); + + rect.right = rect.left + Console->Size.X * GuiData->CharWidth + 2 * GetSystemMetrics(SM_CXFIXEDFRAME); + rect.bottom = rect.top + Console->Size.Y * GuiData->CharHeight + 2 * GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION); + + MoveWindow(pConInfo->hConsoleWindow, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, FALSE); + + if (Console->Size.X < Console->ActiveBuffer->MaxX) + { + /* show scrollbar when window becomes smaller than active screen buffer */ + //ShowScrollBar(GuiData->hHScrollBar, SB_CTL, TRUE); + } + else + { + /* hide scrollbar */ + //ShowScrollBar(GuiData->hHScrollBar, SB_CTL, FALSE); + } + } + /* repaint window */ + InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); +} + static LRESULT CALLBACK GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { LRESULT Result = 0; + PGUI_CONSOLE_DATA GuiData = NULL; + PCSRSS_CONSOLE Console = NULL; + + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); switch(msg) { @@ -1309,10 +1704,20 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_MOUSEMOVE: GuiConsoleMouseMove(hWnd, wParam, lParam); break; - case WM_SYSCOMMAND: - if (!GuiConsoleHandleSysMenuCommand(hWnd, wParam)) + case WM_SYSCOMMAND: + if (!GuiConsoleHandleSysMenuCommand(hWnd, wParam, GuiData)) Result = DefWindowProcW(hWnd, msg, wParam, lParam); break; + case WM_SIZE: + GuiConsoleResize(hWnd, wParam, lParam); + break; + case PM_APPLY_CONSOLE_INFO: + GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam); + if (lParam) + { + GuiConsoleWriteUserSettings(Console, GuiData); + } + break; default: Result = DefWindowProcW(hWnd, msg, wParam, lParam); break; @@ -1352,7 +1757,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } NewWindow = CreateWindowW(L"ConsoleWindowClass", Title, - WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, // | WS_HSCROLL | WS_VSCROLL, + WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, //WS_OVERLAPPEDWINDOW CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, @@ -1367,8 +1772,8 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } if (NULL != NewWindow) { - //ShowScrollBar(NewWindow, SB_VERT, FALSE); - //ShowScrollBar(NewWindow, SB_HORZ, FALSE); + // scrollbar support + //GuiConsoleCreateScrollBar(Console, (PGUI_CONSOLE_DATA)Console->PrivateData, NewWindow); SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1); ShowWindow(NewWindow, SW_SHOW); } @@ -1489,7 +1894,7 @@ GuiInit(VOID) static VOID STDCALL GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) { - Buffer->DefaultAttrib = 0x0f; + Buffer->DefaultAttrib = DEFAULT_ATTRIB; } static BOOL STDCALL diff --git a/reactos/subsystems/win32/csrss/win32csr/resource.h b/reactos/subsystems/win32/csrss/win32csr/resource.h index 5ab16353d4d..f5491fa0091 100644 --- a/reactos/subsystems/win32/csrss/win32csr/resource.h +++ b/reactos/subsystems/win32/csrss/win32csr/resource.h @@ -36,6 +36,15 @@ #define IDS_DEFAULTS 211 #define IDS_PROPERTIES 212 +//scrollbar resource ids +#define IDS_SCROLLHERE 304 +#define IDS_SCROLLTOP 305 +#define IDS_SCROLLBOTTOM 306 +#define IDS_SCROLLPAGE_UP 307 +#define IDS_SCROLLPAGE_DOWN 308 +#define IDS_SCROLLUP 309 +#define IDS_SCROLLDOWN 310 + #endif /* WIN32CSR_RESOURCE_H_INCLUDED */ diff --git a/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c b/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c index 42811803974..e7401f7bbb4 100644 --- a/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c @@ -48,7 +48,7 @@ TuiInit(VOID) static VOID STDCALL TuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) { - Buffer->DefaultAttrib = 0x17; + Buffer->DefaultAttrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | BACKGROUND_BLUE; } static void FASTCALL diff --git a/reactos/subsystems/win32/csrss/win32csr/w32csr.h b/reactos/subsystems/win32/csrss/win32csr/w32csr.h index 39a6ca1e19d..150f866ad32 100644 --- a/reactos/subsystems/win32/csrss/win32csr/w32csr.h +++ b/reactos/subsystems/win32/csrss/win32csr/w32csr.h @@ -27,4 +27,6 @@ #include "resource.h" +/* shared header with console.dll */ +#include "console.h" /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild index ad463f681a6..20cf2bf1e0d 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -4,6 +4,7 @@ include include/reactos/subsys include/reactos/drivers + . 0x0501 From 02a7a3126502e93e562ddbf321485b548535298a Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 6 Sep 2006 20:00:41 +0000 Subject: [PATCH 024/488] - Force using the import libraries built by ReactOS only, don't use the ones that come with the mingw compiler (doesn't work for CPP!) - Import the mingw startup library and customized it a little. _tmain() is now supported, compiling an application as unicode is now just a matter of setting the module attribute unicode="true" - Fixed .rbuild files to import all libraries neccessary - Various GUID header changes and hacks to get everything to build/link properly - Fixed the IShellView2 interface svn path=/trunk/; revision=23933 --- reactos/base/applications/cacls/cacls.c | 12 +- reactos/base/applications/cacls/cacls.rbuild | 6 +- .../base/applications/devmgr/devmgr.rbuild | 1 + .../games/solitaire/solitaire.rbuild | 2 +- .../games/winemine/winemine.rbuild | 4 +- .../applications/getfirefox/getfirefox.rbuild | 32 +- .../applications/ibrowser/ibrowser.rbuild | 2 +- .../applications/ibrowser/ibrowser_intres.rc | 5 +- .../base/applications/network/finger/net.c | 7 +- .../base/applications/network/ftp/ftp.rbuild | 3 +- .../applications/network/ipconfig/ipconfig.c | 2 +- .../network/ipconfig/ipconfig.rbuild | 15 +- .../applications/network/telnet/telnet.rbuild | 2 +- .../base/applications/regedit/regedit.rbuild | 1 + .../screensavers/matrix/matrix.rbuild | 3 +- .../applications/shutdown/shutdown.rbuild | 11 +- reactos/base/applications/sm/sm.rbuild | 1 + .../applications/sndvol32/sndvol32.rbuild | 1 + .../base/applications/taskmgr/taskmgr.rbuild | 2 + .../testsets/smss/movefile/movefile.rbuild | 1 + .../applications/utils/rosperf/rosperf.rbuild | 2 + .../applications/winefile/winefile.rbuild | 1 + .../base/applications/winver/winver.rbuild | 1 + reactos/base/services/dhcp/dhcp.rbuild | 3 +- reactos/base/services/tcpsvcs/tcpsvcs.rbuild | 2 + reactos/base/setup/vmwinst/vmwinst.rbuild | 1 + reactos/base/shell/cmd/cmd.rbuild | 4 +- reactos/base/shell/cmd/tests/cmd_test.rbuild | 3 + reactos/base/shell/explorer/explorer.rbuild | 5 +- reactos/base/system/expand/expand.rbuild | 5 +- reactos/base/system/format/format.rbuild | 1 + reactos/base/system/lsass/lsass.rbuild | 1 + reactos/base/system/userinit/userinit.rbuild | 1 + reactos/boot/freeldr/fdebug/De.rc | 4 +- reactos/boot/freeldr/fdebug/En.rc | 4 +- reactos/boot/freeldr/fdebug/Fr.rc | 4 +- reactos/boot/freeldr/fdebug/Hu.rc | 4 +- reactos/boot/freeldr/fdebug/Ja.rc | 4 +- reactos/boot/freeldr/fdebug/No.rc | 4 +- reactos/boot/freeldr/fdebug/Pl.rc | 4 +- reactos/boot/freeldr/fdebug/Tr.rc | 4 +- reactos/dll/3rdparty/mesa32/mesa32.rbuild | 2 + reactos/dll/cpl/hdwwiz/hdwwiz.rbuild | 1 + reactos/dll/cpl/main/main.rbuild | 1 + reactos/dll/cpl/ncpa/ncpa.rbuild | 1 + reactos/dll/cpl/sysdm/sysdm.rbuild | 1 + reactos/dll/cpl/timedate/timedate.rbuild | 1 + reactos/dll/directx/ddraw/ddraw.rbuild | 5 +- reactos/dll/directx/devenum/devenum.rbuild | 4 +- reactos/dll/directx/dinput/dinput.rbuild | 2 +- reactos/dll/win32/aclui/aclui.rbuild | 1 + reactos/dll/win32/advapi32/advapi32.rbuild | 2 +- reactos/dll/win32/avifil32/avifil32.rbuild | 4 +- reactos/dll/win32/dbghelp/dbghelp.rbuild | 2 +- reactos/dll/win32/devmgr/devmgr.rbuild | 1 + reactos/dll/win32/glu32/glu32.rbuild | 5 +- reactos/dll/win32/kernel32/kernel32.def | 4 +- reactos/dll/win32/mmdrv/mmdrv.rbuild | 1 + reactos/dll/win32/msvideo/msvfw32.rbuild | 4 +- reactos/dll/win32/netcfgx/netcfgx.rbuild | 2 + reactos/dll/win32/newdev/newdev.rbuild | 4 + reactos/dll/win32/ntmarta/ntmarta.c | 6 +- reactos/dll/win32/ntmarta/ntmarta.rbuild | 1 + reactos/dll/win32/opengl32/opengl32.rbuild | 2 + reactos/dll/win32/setupapi/setupapi.rbuild | 1 + reactos/dll/win32/shellext/slayer/precomp.h | 2 +- reactos/dll/win32/shellext/slayer/slayer.c | 4 - reactos/dll/win32/shellext/slayer/slayer.h | 2 +- .../dll/win32/shellext/slayer/slayer.rbuild | 1 + reactos/dll/win32/syssetup/syssetup.rbuild | 2 +- reactos/include/psdk/shlguid.h | 208 +++-- reactos/include/psdk/shlobj.h | 44 + reactos/include/psdk/shtypes.h | 2 + reactos/include/psdk/unknwn.h | 5 +- reactos/include/psdk/winbase.h | 2 +- reactos/include/reactos/wine/shlguid.h | 2 + reactos/include/reactos/wine/unknwn.h | 4 +- reactos/lib/dxguid/dxguid-mingw.c | 7 +- reactos/lib/lib.rbuild | 3 + reactos/lib/mingw/CRTfmode.c | 16 + reactos/lib/mingw/CRTglob.c | 16 + reactos/lib/mingw/CRTinit.c | 24 + reactos/lib/{tgetopt => mingw}/_wgetopt.c | 0 reactos/lib/mingw/binmode.c | 5 + reactos/lib/mingw/cpu_features.c | 105 +++ reactos/lib/mingw/cpu_features.h | 25 + reactos/lib/mingw/crt1.c | 283 ++++++ reactos/lib/mingw/dllcrt1.c | 185 ++++ reactos/lib/mingw/gccmain.c | 79 ++ reactos/lib/{tgetopt => mingw}/getopt.c | 0 reactos/lib/mingw/include/_mingw.h | 165 ++++ reactos/lib/mingw/include/assert.h | 51 ++ reactos/lib/mingw/include/complex.h | 205 +++++ reactos/lib/mingw/include/conio.h | 53 ++ reactos/lib/mingw/include/ctype.h | 247 +++++ reactos/lib/mingw/include/dir.h | 26 + reactos/lib/mingw/include/direct.h | 73 ++ reactos/lib/mingw/include/dirent.h | 123 +++ reactos/lib/mingw/include/dos.h | 89 ++ reactos/lib/mingw/include/errno.h | 101 +++ reactos/lib/mingw/include/excpt.h | 102 +++ reactos/lib/mingw/include/fcntl.h | 69 ++ reactos/lib/mingw/include/fenv.h | 105 +++ reactos/lib/mingw/include/float.h | 152 ++++ reactos/lib/mingw/include/getopt.h | 84 ++ reactos/lib/mingw/include/inttypes.h | 278 ++++++ reactos/lib/mingw/include/io.h | 313 +++++++ reactos/lib/mingw/include/limits.h | 112 +++ reactos/lib/mingw/include/locale.h | 88 ++ reactos/lib/mingw/include/malloc.h | 98 ++ reactos/lib/mingw/include/math.h | 848 ++++++++++++++++++ reactos/lib/mingw/include/mbctype.h | 97 ++ reactos/lib/mingw/include/mbstring.h | 132 +++ reactos/lib/mingw/include/mem.h | 6 + reactos/lib/mingw/include/memory.h | 7 + reactos/lib/mingw/include/process.h | 138 +++ reactos/lib/mingw/include/search.h | 64 ++ reactos/lib/mingw/include/setjmp.h | 56 ++ reactos/lib/mingw/include/share.h | 33 + reactos/lib/mingw/include/signal.h | 98 ++ reactos/lib/mingw/include/stdint.h | 184 ++++ reactos/lib/mingw/include/stdio.h | 509 +++++++++++ reactos/lib/mingw/include/stdlib.h | 524 +++++++++++ reactos/lib/mingw/include/string.h | 193 ++++ reactos/lib/mingw/include/strings.h | 12 + reactos/lib/mingw/include/sys/fcntl.h | 7 + reactos/lib/mingw/include/sys/file.h | 7 + reactos/lib/mingw/include/sys/locking.h | 31 + reactos/lib/mingw/include/sys/param.h | 22 + reactos/lib/mingw/include/sys/stat.h | 195 ++++ reactos/lib/mingw/include/sys/time.h | 47 + reactos/lib/mingw/include/sys/timeb.h | 74 ++ reactos/lib/mingw/include/sys/types.h | 120 +++ reactos/lib/mingw/include/sys/unistd.h | 6 + reactos/lib/mingw/include/sys/utime.h | 82 ++ reactos/lib/mingw/include/tchar.h | 418 +++++++++ reactos/lib/mingw/include/time.h | 218 +++++ reactos/lib/mingw/include/unistd.h | 33 + reactos/lib/mingw/include/utime.h | 1 + reactos/lib/mingw/include/values.h | 4 + reactos/lib/mingw/include/varargs.h | 7 + reactos/lib/mingw/include/wchar.h | 475 ++++++++++ reactos/lib/mingw/include/wctype.h | 153 ++++ reactos/lib/mingw/init.c | 67 ++ reactos/lib/mingw/isascii.c | 21 + reactos/lib/mingw/iscsym.c | 20 + reactos/lib/mingw/iscsymf.c | 21 + reactos/lib/mingw/main.c | 79 ++ reactos/lib/mingw/mingw.rbuild | 36 + reactos/lib/mingw/moldname-msvcrt.def | 158 ++++ reactos/lib/mingw/pseudo-reloc.c | 46 + reactos/lib/mingw/strcasecmp.c | 21 + reactos/lib/mingw/strncasecmp.c | 21 + reactos/lib/{tgetopt => mingw}/tgetopt.h | 0 reactos/lib/mingw/toascii.c | 22 + reactos/lib/mingw/wbinmode.c | 5 + reactos/lib/mingw/wcrt1.c | 283 ++++++ reactos/lib/mingw/wcscmpi.c | 21 + reactos/lib/mingw/winit.c | 66 ++ reactos/lib/mingw/wmain.c | 79 ++ reactos/lib/strmiids/strmiids.c | 8 +- reactos/lib/uuid/uuid.c | 14 +- reactos/regtests/kmtloader/kmtloader.rbuild | 3 +- reactos/regtests/queuetest/queuetest.rbuild | 1 + .../winetests/advapi32/advapi32.rbuild | 1 + .../regtests/winetests/cabinet/cabinet.rbuild | 1 + .../winetests/comctl32/comctl32.rbuild | 3 + reactos/regtests/winetests/gdi32/gdi32.rbuild | 3 + reactos/regtests/winetests/icmp/icmp.rbuild | 1 + reactos/regtests/winetests/lz32/lz32.rbuild | 1 + .../regtests/winetests/msvcrt/msvcrt.rbuild | 1 + reactos/regtests/winetests/ntdll/ntdll.rbuild | 1 + .../winetests/powrprof/powrprof.rbuild | 14 +- reactos/regtests/winetests/psapi/psapi.rbuild | 1 + .../winetests/setupapi/setupapi.rbuild | 2 + .../regtests/winetests/shell32/shell32.rbuild | 3 +- .../regtests/winetests/shell32/shelllink.c | 2 + .../regtests/winetests/shlwapi/shlwapi.rbuild | 2 + .../regtests/winetests/version/version.rbuild | 1 + reactos/tools/rbuild/backend/mingw/mingw.cpp | 1 + .../rbuild/backend/mingw/modulehandler.cpp | 70 +- .../rbuild/backend/mingw/modulehandler.h | 8 + reactos/tools/rbuild/define.cpp | 21 +- reactos/tools/rbuild/module.cpp | 90 +- reactos/tools/rbuild/rbuild.h | 13 +- 185 files changed, 9591 insertions(+), 235 deletions(-) create mode 100644 reactos/lib/mingw/CRTfmode.c create mode 100644 reactos/lib/mingw/CRTglob.c create mode 100644 reactos/lib/mingw/CRTinit.c rename reactos/lib/{tgetopt => mingw}/_wgetopt.c (100%) create mode 100644 reactos/lib/mingw/binmode.c create mode 100644 reactos/lib/mingw/cpu_features.c create mode 100644 reactos/lib/mingw/cpu_features.h create mode 100644 reactos/lib/mingw/crt1.c create mode 100644 reactos/lib/mingw/dllcrt1.c create mode 100644 reactos/lib/mingw/gccmain.c rename reactos/lib/{tgetopt => mingw}/getopt.c (100%) create mode 100644 reactos/lib/mingw/include/_mingw.h create mode 100644 reactos/lib/mingw/include/assert.h create mode 100644 reactos/lib/mingw/include/complex.h create mode 100644 reactos/lib/mingw/include/conio.h create mode 100644 reactos/lib/mingw/include/ctype.h create mode 100644 reactos/lib/mingw/include/dir.h create mode 100644 reactos/lib/mingw/include/direct.h create mode 100644 reactos/lib/mingw/include/dirent.h create mode 100644 reactos/lib/mingw/include/dos.h create mode 100644 reactos/lib/mingw/include/errno.h create mode 100644 reactos/lib/mingw/include/excpt.h create mode 100644 reactos/lib/mingw/include/fcntl.h create mode 100644 reactos/lib/mingw/include/fenv.h create mode 100644 reactos/lib/mingw/include/float.h create mode 100644 reactos/lib/mingw/include/getopt.h create mode 100644 reactos/lib/mingw/include/inttypes.h create mode 100644 reactos/lib/mingw/include/io.h create mode 100644 reactos/lib/mingw/include/limits.h create mode 100644 reactos/lib/mingw/include/locale.h create mode 100644 reactos/lib/mingw/include/malloc.h create mode 100644 reactos/lib/mingw/include/math.h create mode 100644 reactos/lib/mingw/include/mbctype.h create mode 100644 reactos/lib/mingw/include/mbstring.h create mode 100644 reactos/lib/mingw/include/mem.h create mode 100644 reactos/lib/mingw/include/memory.h create mode 100644 reactos/lib/mingw/include/process.h create mode 100644 reactos/lib/mingw/include/search.h create mode 100644 reactos/lib/mingw/include/setjmp.h create mode 100644 reactos/lib/mingw/include/share.h create mode 100644 reactos/lib/mingw/include/signal.h create mode 100644 reactos/lib/mingw/include/stdint.h create mode 100644 reactos/lib/mingw/include/stdio.h create mode 100644 reactos/lib/mingw/include/stdlib.h create mode 100644 reactos/lib/mingw/include/string.h create mode 100644 reactos/lib/mingw/include/strings.h create mode 100644 reactos/lib/mingw/include/sys/fcntl.h create mode 100644 reactos/lib/mingw/include/sys/file.h create mode 100644 reactos/lib/mingw/include/sys/locking.h create mode 100644 reactos/lib/mingw/include/sys/param.h create mode 100644 reactos/lib/mingw/include/sys/stat.h create mode 100644 reactos/lib/mingw/include/sys/time.h create mode 100644 reactos/lib/mingw/include/sys/timeb.h create mode 100644 reactos/lib/mingw/include/sys/types.h create mode 100644 reactos/lib/mingw/include/sys/unistd.h create mode 100644 reactos/lib/mingw/include/sys/utime.h create mode 100644 reactos/lib/mingw/include/tchar.h create mode 100644 reactos/lib/mingw/include/time.h create mode 100644 reactos/lib/mingw/include/unistd.h create mode 100644 reactos/lib/mingw/include/utime.h create mode 100644 reactos/lib/mingw/include/values.h create mode 100644 reactos/lib/mingw/include/varargs.h create mode 100644 reactos/lib/mingw/include/wchar.h create mode 100644 reactos/lib/mingw/include/wctype.h create mode 100644 reactos/lib/mingw/init.c create mode 100644 reactos/lib/mingw/isascii.c create mode 100644 reactos/lib/mingw/iscsym.c create mode 100644 reactos/lib/mingw/iscsymf.c create mode 100644 reactos/lib/mingw/main.c create mode 100644 reactos/lib/mingw/mingw.rbuild create mode 100644 reactos/lib/mingw/moldname-msvcrt.def create mode 100644 reactos/lib/mingw/pseudo-reloc.c create mode 100644 reactos/lib/mingw/strcasecmp.c create mode 100644 reactos/lib/mingw/strncasecmp.c rename reactos/lib/{tgetopt => mingw}/tgetopt.h (100%) create mode 100644 reactos/lib/mingw/toascii.c create mode 100644 reactos/lib/mingw/wbinmode.c create mode 100644 reactos/lib/mingw/wcrt1.c create mode 100644 reactos/lib/mingw/wcscmpi.c create mode 100644 reactos/lib/mingw/winit.c create mode 100644 reactos/lib/mingw/wmain.c diff --git a/reactos/base/applications/cacls/cacls.c b/reactos/base/applications/cacls/cacls.c index ad93e130377..733882ba529 100644 --- a/reactos/base/applications/cacls/cacls.c +++ b/reactos/base/applications/cacls/cacls.c @@ -507,18 +507,8 @@ PrintSpecialAccess: } -#ifdef _UNICODE -int __cdecl main(void) -#else -int __cdecl _main (int argc, char *argv[]) -#endif +int __cdecl _tmain(int argc, const TCHAR *argv[]) { -#ifdef _UNICODE - PWCHAR *argv; - int argc = 0; - argv = CommandLineToArgvW(GetCommandLineW(), &argc); -#endif - if (argc < 2) { PrintHelp(); diff --git a/reactos/base/applications/cacls/cacls.rbuild b/reactos/base/applications/cacls/cacls.rbuild index 00e18111d98..a2abe968a6d 100644 --- a/reactos/base/applications/cacls/cacls.rbuild +++ b/reactos/base/applications/cacls/cacls.rbuild @@ -1,14 +1,14 @@ - + . - - 0x0500 0x0600 0x0600 kernel32 advapi32 ntdll + user32 + shell32 cacls.c lang/cacls.rc precomp.h diff --git a/reactos/base/applications/devmgr/devmgr.rbuild b/reactos/base/applications/devmgr/devmgr.rbuild index 78e60550960..b9014c42a65 100644 --- a/reactos/base/applications/devmgr/devmgr.rbuild +++ b/reactos/base/applications/devmgr/devmgr.rbuild @@ -9,6 +9,7 @@ kernel32 user32 comctl32 + advapi32 devmgr.c devmgr.rc diff --git a/reactos/base/applications/games/solitaire/solitaire.rbuild b/reactos/base/applications/games/solitaire/solitaire.rbuild index 51c36c9f0f5..6478c45e701 100644 --- a/reactos/base/applications/games/solitaire/solitaire.rbuild +++ b/reactos/base/applications/games/solitaire/solitaire.rbuild @@ -1,6 +1,6 @@ - + . cardlib -lstdc++ diff --git a/reactos/base/applications/games/winemine/winemine.rbuild b/reactos/base/applications/games/winemine/winemine.rbuild index 1ed457d6ea6..18893df9270 100644 --- a/reactos/base/applications/games/winemine/winemine.rbuild +++ b/reactos/base/applications/games/winemine/winemine.rbuild @@ -6,7 +6,9 @@ 0x0501 0x0501 kernel32 - gdi32 + gdi32 + user32 + advapi32 main.c dialog.c winemine.rc diff --git a/reactos/base/applications/getfirefox/getfirefox.rbuild b/reactos/base/applications/getfirefox/getfirefox.rbuild index ce493e8eb70..b0c276d6592 100644 --- a/reactos/base/applications/getfirefox/getfirefox.rbuild +++ b/reactos/base/applications/getfirefox/getfirefox.rbuild @@ -1,19 +1,21 @@ - . - - - - 0x0501 - . + + + + 0x0501 + - + -fexceptions . diff --git a/reactos/base/applications/ibrowser/ibrowser_intres.rc b/reactos/base/applications/ibrowser/ibrowser_intres.rc index 9c1b2319fb7..5911d099402 100644 --- a/reactos/base/applications/ibrowser/ibrowser_intres.rc +++ b/reactos/base/applications/ibrowser/ibrowser_intres.rc @@ -35,9 +35,8 @@ IDB_TOOLBAR BITMAP DISCARDABLE "res/toolbar.bmp" IDA_IBROWSER ACCELERATORS DISCARDABLE BEGIN - "X", ID_FILE_EXIT, VIRTKEY, ALT, NOINVERT - "S", ID_VIEW_FULLSCREEN, VIRTKEY, SHIFT, CONTROL, - NOINVERT + 120, ID_FILE_EXIT, ASCII, ALT // "X" + 115, ID_VIEW_FULLSCREEN, ASCII, SHIFT, CONTROL // "S" END diff --git a/reactos/base/applications/network/finger/net.c b/reactos/base/applications/network/finger/net.c index 3362fb2d5df..7f932ef2b5d 100644 --- a/reactos/base/applications/network/finger/net.c +++ b/reactos/base/applications/network/finger/net.c @@ -33,17 +33,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#include -#include +#include #include #include #include #include "various.h" -int close(int); - void netfinger(char *name) { @@ -90,7 +87,7 @@ netfinger(char *name) (void)printf("[%s]\n", hp->h_name); if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { fprintf(stderr, "finger: connect rc = %d", WSAGetLastError()); - (void)close(s); + (void)closesocket(s); return; } diff --git a/reactos/base/applications/network/ftp/ftp.rbuild b/reactos/base/applications/network/ftp/ftp.rbuild index 09e94576e93..7117e598aeb 100644 --- a/reactos/base/applications/network/ftp/ftp.rbuild +++ b/reactos/base/applications/network/ftp/ftp.rbuild @@ -1,11 +1,12 @@ - + . kernel32 ws2_32 + crtdll iphlpapi cmds.c cmdtab.c diff --git a/reactos/base/applications/network/ipconfig/ipconfig.c b/reactos/base/applications/network/ipconfig/ipconfig.c index e918cd1bab0..4d496d53d49 100644 --- a/reactos/base/applications/network/ipconfig/ipconfig.c +++ b/reactos/base/applications/network/ipconfig/ipconfig.c @@ -542,7 +542,7 @@ VOID Release(LPTSTR Index) /* Call IpReleaseAddress to release the IP address on the specified adapter. */ - if (ret = IpReleaseAddress(&AdapterInfo) != NO_ERROR) + if ((ret = IpReleaseAddress(&AdapterInfo)) != NO_ERROR) { _tprintf(_T("\nAn error occured while releasing interface %S : \n"), AdapterInfo.Name); DoFormatMessage(ret); diff --git a/reactos/base/applications/network/ipconfig/ipconfig.rbuild b/reactos/base/applications/network/ipconfig/ipconfig.rbuild index 425dc56db42..7cf80bb6976 100644 --- a/reactos/base/applications/network/ipconfig/ipconfig.rbuild +++ b/reactos/base/applications/network/ipconfig/ipconfig.rbuild @@ -1,11 +1,12 @@ - . - - kernel32 - user32 - iphlpapi - ipconfig.c - ipconfig.rc + . + + kernel32 + user32 + iphlpapi + advapi32 + ipconfig.c + ipconfig.rc diff --git a/reactos/base/applications/network/telnet/telnet.rbuild b/reactos/base/applications/network/telnet/telnet.rbuild index 653c39a765a..bde5b87b925 100644 --- a/reactos/base/applications/network/telnet/telnet.rbuild +++ b/reactos/base/applications/network/telnet/telnet.rbuild @@ -1,6 +1,6 @@ - + . diff --git a/reactos/base/applications/regedit/regedit.rbuild b/reactos/base/applications/regedit/regedit.rbuild index 50141a1ee16..519587200c1 100644 --- a/reactos/base/applications/regedit/regedit.rbuild +++ b/reactos/base/applications/regedit/regedit.rbuild @@ -16,6 +16,7 @@ comctl32 comdlg32 shlwapi + uuid about.c childwnd.c edit.c diff --git a/reactos/base/applications/screensavers/matrix/matrix.rbuild b/reactos/base/applications/screensavers/matrix/matrix.rbuild index 235772effe1..f9b2cc717eb 100644 --- a/reactos/base/applications/screensavers/matrix/matrix.rbuild +++ b/reactos/base/applications/screensavers/matrix/matrix.rbuild @@ -2,8 +2,7 @@ . - - -lstdc++ + 0x0501 0x0501 diff --git a/reactos/base/applications/shutdown/shutdown.rbuild b/reactos/base/applications/shutdown/shutdown.rbuild index cc62542cb19..c398f3cb852 100644 --- a/reactos/base/applications/shutdown/shutdown.rbuild +++ b/reactos/base/applications/shutdown/shutdown.rbuild @@ -1,8 +1,11 @@ - . - - 0x0501 - shutdown.c + . + + 0x0501 + advapi32 + user32 + kernel32 + shutdown.c diff --git a/reactos/base/applications/sm/sm.rbuild b/reactos/base/applications/sm/sm.rbuild index 32ad19a74bf..0f4888c222d 100644 --- a/reactos/base/applications/sm/sm.rbuild +++ b/reactos/base/applications/sm/sm.rbuild @@ -6,6 +6,7 @@ smdll ntdll kernel32 + user32 sm.c win32err.c sm.rc diff --git a/reactos/base/applications/sndvol32/sndvol32.rbuild b/reactos/base/applications/sndvol32/sndvol32.rbuild index 431333f57c0..c10fb16fa72 100644 --- a/reactos/base/applications/sndvol32/sndvol32.rbuild +++ b/reactos/base/applications/sndvol32/sndvol32.rbuild @@ -9,6 +9,7 @@ 0x0600 ntdll user32 + advapi32 gdi32 kernel32 comctl32 diff --git a/reactos/base/applications/taskmgr/taskmgr.rbuild b/reactos/base/applications/taskmgr/taskmgr.rbuild index 56b0b0f376b..55a28ea517b 100644 --- a/reactos/base/applications/taskmgr/taskmgr.rbuild +++ b/reactos/base/applications/taskmgr/taskmgr.rbuild @@ -7,8 +7,10 @@ ntdll kernel32 + advapi32 user32 gdi32 + shell32 comctl32 precomp.h diff --git a/reactos/base/applications/testsets/smss/movefile/movefile.rbuild b/reactos/base/applications/testsets/smss/movefile/movefile.rbuild index e0ec77bab48..c6dcaddeed5 100644 --- a/reactos/base/applications/testsets/smss/movefile/movefile.rbuild +++ b/reactos/base/applications/testsets/smss/movefile/movefile.rbuild @@ -5,6 +5,7 @@ 0x0600 0x0600 kernel32 + advapi32 user32 movefile.cpp movefile.rc diff --git a/reactos/base/applications/utils/rosperf/rosperf.rbuild b/reactos/base/applications/utils/rosperf/rosperf.rbuild index 60af37ed25d..68882be0425 100644 --- a/reactos/base/applications/utils/rosperf/rosperf.rbuild +++ b/reactos/base/applications/utils/rosperf/rosperf.rbuild @@ -6,6 +6,8 @@ version msimg32 gdi32 + shell32 + advapi32 user32 kernel32 ntdll diff --git a/reactos/base/applications/winefile/winefile.rbuild b/reactos/base/applications/winefile/winefile.rbuild index 9f3ce5e14f8..4fcf82ae188 100644 --- a/reactos/base/applications/winefile/winefile.rbuild +++ b/reactos/base/applications/winefile/winefile.rbuild @@ -11,6 +11,7 @@ gdi32 user32 comctl32 + advapi32 comdlg32 shell32 ole32 diff --git a/reactos/base/applications/winver/winver.rbuild b/reactos/base/applications/winver/winver.rbuild index 2265d49ca3e..0d484c1b22f 100644 --- a/reactos/base/applications/winver/winver.rbuild +++ b/reactos/base/applications/winver/winver.rbuild @@ -6,5 +6,6 @@ 0x501 0x0501 shell32 + kernel32 winver.c diff --git a/reactos/base/services/dhcp/dhcp.rbuild b/reactos/base/services/dhcp/dhcp.rbuild index 46efa47f639..fdbdf9f609e 100644 --- a/reactos/base/services/dhcp/dhcp.rbuild +++ b/reactos/base/services/dhcp/dhcp.rbuild @@ -8,7 +8,8 @@ kernel32 ws2_32 iphlpapi - include/rosdhcp.h + advapi32 + include/rosdhcp.h adapter.c alloc.c api.c diff --git a/reactos/base/services/tcpsvcs/tcpsvcs.rbuild b/reactos/base/services/tcpsvcs/tcpsvcs.rbuild index 0565cc831b2..c6d0458c0e9 100644 --- a/reactos/base/services/tcpsvcs/tcpsvcs.rbuild +++ b/reactos/base/services/tcpsvcs/tcpsvcs.rbuild @@ -7,6 +7,8 @@ iphlpapi ws2_32 shlwapi + advapi32 + user32 tcpsvcs.c skelserver.c echo.c diff --git a/reactos/base/setup/vmwinst/vmwinst.rbuild b/reactos/base/setup/vmwinst/vmwinst.rbuild index 5c873b0db45..44530a29202 100644 --- a/reactos/base/setup/vmwinst/vmwinst.rbuild +++ b/reactos/base/setup/vmwinst/vmwinst.rbuild @@ -8,6 +8,7 @@ advapi32 comctl32 comdlg32 + user32 setupapi shell32 vmwinst.c diff --git a/reactos/base/shell/cmd/cmd.rbuild b/reactos/base/shell/cmd/cmd.rbuild index 6b1d7de4e4f..773f4d75e6c 100644 --- a/reactos/base/shell/cmd/cmd.rbuild +++ b/reactos/base/shell/cmd/cmd.rbuild @@ -67,8 +67,10 @@ 0x0501 - kernel32 cmd_base + kernel32 + advapi32 + user32 main.c cmd.rc diff --git a/reactos/base/shell/cmd/tests/cmd_test.rbuild b/reactos/base/shell/cmd/tests/cmd_test.rbuild index 50c1fa81b45..57cdf55bdec 100644 --- a/reactos/base/shell/cmd/tests/cmd_test.rbuild +++ b/reactos/base/shell/cmd/tests/cmd_test.rbuild @@ -8,6 +8,9 @@ rtshared regtests cmd_base + kernel32 + advapi32 + cmd_base pseh ntdll setup.c diff --git a/reactos/base/shell/explorer/explorer.rbuild b/reactos/base/shell/explorer/explorer.rbuild index 87bd4817196..95b48be8058 100644 --- a/reactos/base/shell/explorer/explorer.rbuild +++ b/reactos/base/shell/explorer/explorer.rbuild @@ -1,8 +1,6 @@ - - -luuid - -lstdc++ + -fexceptions . @@ -22,6 +20,7 @@ ole32 oleaut32 shell32 + uuid notifyhook precomp.h diff --git a/reactos/base/system/expand/expand.rbuild b/reactos/base/system/expand/expand.rbuild index c2aeebb66e3..55a71e9783c 100644 --- a/reactos/base/system/expand/expand.rbuild +++ b/reactos/base/system/expand/expand.rbuild @@ -8,6 +8,7 @@ 0x0501 lz32 user32 - expand.c - expand.rc + kernel32 + expand.c + expand.rc diff --git a/reactos/base/system/format/format.rbuild b/reactos/base/system/format/format.rbuild index 35061db70ae..158dde226f8 100644 --- a/reactos/base/system/format/format.rbuild +++ b/reactos/base/system/format/format.rbuild @@ -5,6 +5,7 @@ ntdll kernel32 + user32 fmifs format.rc format.c diff --git a/reactos/base/system/lsass/lsass.rbuild b/reactos/base/system/lsass/lsass.rbuild index 0251bbda100..a63d3861375 100644 --- a/reactos/base/system/lsass/lsass.rbuild +++ b/reactos/base/system/lsass/lsass.rbuild @@ -7,6 +7,7 @@ ntdll + kernel32 lsasrv lsass.c lsass.rc diff --git a/reactos/base/system/userinit/userinit.rbuild b/reactos/base/system/userinit/userinit.rbuild index b797c50559a..73f7d9d3d6f 100644 --- a/reactos/base/system/userinit/userinit.rbuild +++ b/reactos/base/system/userinit/userinit.rbuild @@ -10,6 +10,7 @@ user32 gdi32 advapi32 + shell32 userinit.c userinit.rc diff --git a/reactos/boot/freeldr/fdebug/De.rc b/reactos/boot/freeldr/fdebug/De.rc index 278d96b1c45..ffd5e1952bb 100644 --- a/reactos/boot/freeldr/fdebug/De.rc +++ b/reactos/boot/freeldr/fdebug/De.rc @@ -40,8 +40,8 @@ END IDC_FDEBUG ACCELERATORS MOVEABLE PURE BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT + 63, IDM_ABOUT, ASCII, ALT // "?" + 47, IDM_ABOUT, ASCII, ALT // "/" END diff --git a/reactos/boot/freeldr/fdebug/En.rc b/reactos/boot/freeldr/fdebug/En.rc index 557b9dee5d2..afa2f7d9aa0 100644 --- a/reactos/boot/freeldr/fdebug/En.rc +++ b/reactos/boot/freeldr/fdebug/En.rc @@ -40,8 +40,8 @@ END IDC_FDEBUG ACCELERATORS MOVEABLE PURE BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT + 63, IDM_ABOUT, ASCII, ALT // "?" + 47, IDM_ABOUT, ASCII, ALT // "/" END diff --git a/reactos/boot/freeldr/fdebug/Fr.rc b/reactos/boot/freeldr/fdebug/Fr.rc index 60194729355..56115e92964 100644 --- a/reactos/boot/freeldr/fdebug/Fr.rc +++ b/reactos/boot/freeldr/fdebug/Fr.rc @@ -49,8 +49,8 @@ END IDC_FDEBUG ACCELERATORS MOVEABLE PURE BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT + 63, IDM_ABOUT, ASCII, ALT // "?" + 47, IDM_ABOUT, ASCII, ALT // "/" END diff --git a/reactos/boot/freeldr/fdebug/Hu.rc b/reactos/boot/freeldr/fdebug/Hu.rc index f6e8ae86ea0..5071baa28a1 100644 --- a/reactos/boot/freeldr/fdebug/Hu.rc +++ b/reactos/boot/freeldr/fdebug/Hu.rc @@ -40,8 +40,8 @@ END IDC_FDEBUG ACCELERATORS MOVEABLE PURE BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT + 63, IDM_ABOUT, ASCII, ALT // "?" + 47, IDM_ABOUT, ASCII, ALT // "/" END diff --git a/reactos/boot/freeldr/fdebug/Ja.rc b/reactos/boot/freeldr/fdebug/Ja.rc index 341c5e603d7..9a53f60a9d3 100644 --- a/reactos/boot/freeldr/fdebug/Ja.rc +++ b/reactos/boot/freeldr/fdebug/Ja.rc @@ -40,8 +40,8 @@ END IDC_FDEBUG ACCELERATORS MOVEABLE PURE BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT + 63, IDM_ABOUT, ASCII, ALT // "?" + 47, IDM_ABOUT, ASCII, ALT // "/" END diff --git a/reactos/boot/freeldr/fdebug/No.rc b/reactos/boot/freeldr/fdebug/No.rc index 10fee7a3a82..4587d6b9499 100644 --- a/reactos/boot/freeldr/fdebug/No.rc +++ b/reactos/boot/freeldr/fdebug/No.rc @@ -40,8 +40,8 @@ END IDC_FDEBUG ACCELERATORS MOVEABLE PURE BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT + 63, IDM_ABOUT, ASCII, ALT // "?" + 47, IDM_ABOUT, ASCII, ALT // "/" END diff --git a/reactos/boot/freeldr/fdebug/Pl.rc b/reactos/boot/freeldr/fdebug/Pl.rc index 4349113aea6..1751fe42217 100644 --- a/reactos/boot/freeldr/fdebug/Pl.rc +++ b/reactos/boot/freeldr/fdebug/Pl.rc @@ -40,8 +40,8 @@ END IDC_FDEBUG ACCELERATORS MOVEABLE PURE BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT + 63, IDM_ABOUT, ASCII, ALT // "?" + 47, IDM_ABOUT, ASCII, ALT // "/" END diff --git a/reactos/boot/freeldr/fdebug/Tr.rc b/reactos/boot/freeldr/fdebug/Tr.rc index 4bbae3446bd..e9bcd4a3800 100644 --- a/reactos/boot/freeldr/fdebug/Tr.rc +++ b/reactos/boot/freeldr/fdebug/Tr.rc @@ -40,8 +40,8 @@ END IDC_FDEBUG ACCELERATORS MOVEABLE PURE BEGIN - "?", IDM_ABOUT, ASCII, ALT - "/", IDM_ABOUT, ASCII, ALT + 63, IDM_ABOUT, ASCII, ALT // "?" + 47, IDM_ABOUT, ASCII, ALT // "/" END diff --git a/reactos/dll/3rdparty/mesa32/mesa32.rbuild b/reactos/dll/3rdparty/mesa32/mesa32.rbuild index 4f221d1acbb..93247e64d17 100644 --- a/reactos/dll/3rdparty/mesa32/mesa32.rbuild +++ b/reactos/dll/3rdparty/mesa32/mesa32.rbuild @@ -4,6 +4,8 @@ -Wl,--enable-stdcall-fixup ntdll kernel32 + msvcrt + user32 diff --git a/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild b/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild index 9b766b99cff..7df49f5c2e2 100644 --- a/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild +++ b/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild @@ -8,6 +8,7 @@ 0x600 0x501 setupapi + kernel32 hdwwiz.c hdwwiz.rc diff --git a/reactos/dll/cpl/main/main.rbuild b/reactos/dll/cpl/main/main.rbuild index d20ded5dbbb..7c0237685fe 100644 --- a/reactos/dll/cpl/main/main.rbuild +++ b/reactos/dll/cpl/main/main.rbuild @@ -8,6 +8,7 @@ 0x600 0x501 kernel32 + advapi32 user32 comctl32 devmgr diff --git a/reactos/dll/cpl/ncpa/ncpa.rbuild b/reactos/dll/cpl/ncpa/ncpa.rbuild index 27632f06c00..52e7aa111ae 100644 --- a/reactos/dll/cpl/ncpa/ncpa.rbuild +++ b/reactos/dll/cpl/ncpa/ncpa.rbuild @@ -8,6 +8,7 @@ 0x600 0x501 kernel32 + advapi32 user32 comctl32 iphlpapi diff --git a/reactos/dll/cpl/sysdm/sysdm.rbuild b/reactos/dll/cpl/sysdm/sysdm.rbuild index 47df84479c6..524b1213023 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rbuild +++ b/reactos/dll/cpl/sysdm/sysdm.rbuild @@ -8,6 +8,7 @@ 0x600 0x501 kernel32 + advapi32 user32 comctl32 netapi32 diff --git a/reactos/dll/cpl/timedate/timedate.rbuild b/reactos/dll/cpl/timedate/timedate.rbuild index 6515cc034c3..345f1eb1b08 100644 --- a/reactos/dll/cpl/timedate/timedate.rbuild +++ b/reactos/dll/cpl/timedate/timedate.rbuild @@ -8,6 +8,7 @@ 0x600 0x501 kernel32 + advapi32 user32 gdi32 comctl32 diff --git a/reactos/dll/directx/ddraw/ddraw.rbuild b/reactos/dll/directx/ddraw/ddraw.rbuild index e4565e94223..accd69d3336 100644 --- a/reactos/dll/directx/ddraw/ddraw.rbuild +++ b/reactos/dll/directx/ddraw/ddraw.rbuild @@ -12,7 +12,8 @@ d3d8thk dxguid ole32 - user32 + user32 + advapi32 ddraw.rc main.c @@ -20,7 +21,7 @@ startup.c cleanup.c - clipper.c + clipper.c color.c gamma.c palette.c diff --git a/reactos/dll/directx/devenum/devenum.rbuild b/reactos/dll/directx/devenum/devenum.rbuild index d674e32b7b2..8757f05f99b 100644 --- a/reactos/dll/directx/devenum/devenum.rbuild +++ b/reactos/dll/directx/devenum/devenum.rbuild @@ -14,12 +14,14 @@ uuid ntdll kernel32 + advapi32 ole32 oleaut32 winmm dxguid strmiids - devenum.rc + user32 + devenum.rc createdevenum.c devenum_main.c factory.c diff --git a/reactos/dll/directx/dinput/dinput.rbuild b/reactos/dll/directx/dinput/dinput.rbuild index 2db41b9bd77..807844e73a0 100644 --- a/reactos/dll/directx/dinput/dinput.rbuild +++ b/reactos/dll/directx/dinput/dinput.rbuild @@ -19,7 +19,7 @@ ole32 winmm dxguid - version.rc + version.rc data_formats.c device.c dinput_main.c diff --git a/reactos/dll/win32/aclui/aclui.rbuild b/reactos/dll/win32/aclui/aclui.rbuild index b6191eec2fd..2a7803dfef2 100644 --- a/reactos/dll/win32/aclui/aclui.rbuild +++ b/reactos/dll/win32/aclui/aclui.rbuild @@ -16,6 +16,7 @@ ole32 oleaut32 uxtheme + advapi32 aclui.c checklist.c guid.c diff --git a/reactos/dll/win32/advapi32/advapi32.rbuild b/reactos/dll/win32/advapi32/advapi32.rbuild index ae610410c65..07b0a5420d9 100644 --- a/reactos/dll/win32/advapi32/advapi32.rbuild +++ b/reactos/dll/win32/advapi32/advapi32.rbuild @@ -10,9 +10,9 @@ scm_client lsa_client ntdll - kernel32 rpcrt4 wine + kernel32 advapi32.h diff --git a/reactos/dll/win32/avifil32/avifil32.rbuild b/reactos/dll/win32/avifil32/avifil32.rbuild index 3eb0cfbc44d..bf68667f587 100644 --- a/reactos/dll/win32/avifil32/avifil32.rbuild +++ b/reactos/dll/win32/avifil32/avifil32.rbuild @@ -5,6 +5,7 @@ include/reactos/wine 0x501 + wine uuid ntdll winmm @@ -12,7 +13,8 @@ msvfw32 msacm32 kernel32 - wine + advapi32 + user32 acmstream.c api.c avifile.c diff --git a/reactos/dll/win32/dbghelp/dbghelp.rbuild b/reactos/dll/win32/dbghelp/dbghelp.rbuild index 13d1766bc5d..f3e3ba1fd50 100644 --- a/reactos/dll/win32/dbghelp/dbghelp.rbuild +++ b/reactos/dll/win32/dbghelp/dbghelp.rbuild @@ -8,10 +8,10 @@ 0x501 0x501 wine + pseh ntdll kernel32 psapi - pseh coff.c dbghelp.c elf_module.c diff --git a/reactos/dll/win32/devmgr/devmgr.rbuild b/reactos/dll/win32/devmgr/devmgr.rbuild index c7435dd80ca..a7ea1fc6ab1 100644 --- a/reactos/dll/win32/devmgr/devmgr.rbuild +++ b/reactos/dll/win32/devmgr/devmgr.rbuild @@ -12,6 +12,7 @@ kernel32 ntdll setupapi + advapi32 user32 devmgr.rc advprop.c diff --git a/reactos/dll/win32/glu32/glu32.rbuild b/reactos/dll/win32/glu32/glu32.rbuild index a0d5ea19884..5c85f0d0161 100644 --- a/reactos/dll/win32/glu32/glu32.rbuild +++ b/reactos/dll/win32/glu32/glu32.rbuild @@ -1,4 +1,4 @@ - + include libnurbs/internals @@ -10,12 +10,11 @@ - -lopengl32 ntdll + opengl32 kernel32 gdi32 msvcrt - opengl32 bezierEval.cc diff --git a/reactos/dll/win32/kernel32/kernel32.def b/reactos/dll/win32/kernel32/kernel32.def index 428b596a4b3..d62a91a254b 100644 --- a/reactos/dll/win32/kernel32/kernel32.def +++ b/reactos/dll/win32/kernel32/kernel32.def @@ -382,8 +382,8 @@ GetDllDirectoryA@8 GetDllDirectoryW@8 GetDriveTypeA@4 GetDriveTypeW@4 -GetEnvironmentStrings=GetEnvironmentStringsA@0 -GetEnvironmentStringsA@0 +GetEnvironmentStrings@0 +GetEnvironmentStringsA=GetEnvironmentStrings@0 GetEnvironmentStringsW@0 GetEnvironmentVariableA@12 GetEnvironmentVariableW@12 diff --git a/reactos/dll/win32/mmdrv/mmdrv.rbuild b/reactos/dll/win32/mmdrv/mmdrv.rbuild index f41b2642da5..0a9d11869fc 100644 --- a/reactos/dll/win32/mmdrv/mmdrv.rbuild +++ b/reactos/dll/win32/mmdrv/mmdrv.rbuild @@ -6,6 +6,7 @@ ntdll kernel32 + user32 winmm auxil.c entry.c diff --git a/reactos/dll/win32/msvideo/msvfw32.rbuild b/reactos/dll/win32/msvideo/msvfw32.rbuild index 4583cba3a74..14541f73489 100644 --- a/reactos/dll/win32/msvideo/msvfw32.rbuild +++ b/reactos/dll/win32/msvideo/msvfw32.rbuild @@ -6,12 +6,14 @@ 0x600 0x501 0x501 + wine winmm gdi32 comctl32 kernel32 + advapi32 + user32 ntdll - wine drawdib.c mciwnd.c msvfw32.rc diff --git a/reactos/dll/win32/netcfgx/netcfgx.rbuild b/reactos/dll/win32/netcfgx/netcfgx.rbuild index d974d63f983..1edf95d9d18 100644 --- a/reactos/dll/win32/netcfgx/netcfgx.rbuild +++ b/reactos/dll/win32/netcfgx/netcfgx.rbuild @@ -5,4 +5,6 @@ ntdll rpcrt4 setupapi + kernel32 + advapi32 diff --git a/reactos/dll/win32/newdev/newdev.rbuild b/reactos/dll/win32/newdev/newdev.rbuild index 49527a14323..790590c7062 100644 --- a/reactos/dll/win32/newdev/newdev.rbuild +++ b/reactos/dll/win32/newdev/newdev.rbuild @@ -13,4 +13,8 @@ comctl32 ntdll setupapi + kernel32 + advapi32 + user32 + shell32 diff --git a/reactos/dll/win32/ntmarta/ntmarta.c b/reactos/dll/win32/ntmarta/ntmarta.c index 564fe980624..a9ecb21125b 100644 --- a/reactos/dll/win32/ntmarta/ntmarta.c +++ b/reactos/dll/win32/ntmarta/ntmarta.c @@ -1025,9 +1025,12 @@ AccFreeIndexArray(PINHERITED_FROMW pInheritArray, USHORT AceCnt, PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL) { + PINHERITED_FROMW pLast; + UNREFERENCED_PARAMETER(pfnArray); - while (AceCnt != 0) + pLast = pInheritArray + AceCnt; + while (pInheritArray != pLast) { if (pInheritArray->AncestorName != NULL) { @@ -1036,7 +1039,6 @@ AccFreeIndexArray(PINHERITED_FROMW pInheritArray, } pInheritArray++; - AceCnt--; } return ERROR_SUCCESS; diff --git a/reactos/dll/win32/ntmarta/ntmarta.rbuild b/reactos/dll/win32/ntmarta/ntmarta.rbuild index 64ba64f1340..a46dddce5dd 100644 --- a/reactos/dll/win32/ntmarta/ntmarta.rbuild +++ b/reactos/dll/win32/ntmarta/ntmarta.rbuild @@ -10,6 +10,7 @@ ntdll kernel32 advapi32 + user32 ntmarta.c ntmarta.rc ntmarta.h diff --git a/reactos/dll/win32/opengl32/opengl32.rbuild b/reactos/dll/win32/opengl32/opengl32.rbuild index ef02d13bda8..a57b332a2e3 100644 --- a/reactos/dll/win32/opengl32/opengl32.rbuild +++ b/reactos/dll/win32/opengl32/opengl32.rbuild @@ -7,6 +7,8 @@ ntdll kernel32 gdi32 + user32 + advapi32 gl.c opengl32.c wgl.c diff --git a/reactos/dll/win32/setupapi/setupapi.rbuild b/reactos/dll/win32/setupapi/setupapi.rbuild index b4e4d6f1830..0c81f9a3a4c 100644 --- a/reactos/dll/win32/setupapi/setupapi.rbuild +++ b/reactos/dll/win32/setupapi/setupapi.rbuild @@ -22,6 +22,7 @@ user32 rpcrt4 version + shell32 cfgmgr.c devclass.c devinst.c diff --git a/reactos/dll/win32/shellext/slayer/precomp.h b/reactos/dll/win32/shellext/slayer/precomp.h index dfb412672dc..f80ea832d5e 100644 --- a/reactos/dll/win32/shellext/slayer/precomp.h +++ b/reactos/dll/win32/shellext/slayer/precomp.h @@ -1,7 +1,7 @@ -#define INITGUID #include #include #include +#include #include #include #include diff --git a/reactos/dll/win32/shellext/slayer/slayer.c b/reactos/dll/win32/shellext/slayer/slayer.c index 10854421233..f116d2dab27 100644 --- a/reactos/dll/win32/shellext/slayer/slayer.c +++ b/reactos/dll/win32/shellext/slayer/slayer.c @@ -30,10 +30,6 @@ HINSTANCE hInstance = NULL; static LONG dllrefs = 0; -/* FIXME - they should be exported somewhere instead of defined here... */ -DEFINE_GUID(IID_IClassFactory, 0x00000001, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46); -DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46); - static ifaceICompatibilityPageVbtl efvt = { /* IUnknown methods */ diff --git a/reactos/dll/win32/shellext/slayer/slayer.h b/reactos/dll/win32/shellext/slayer/slayer.h index fcb61f00e7d..f48538e430a 100644 --- a/reactos/dll/win32/shellext/slayer/slayer.h +++ b/reactos/dll/win32/shellext/slayer/slayer.h @@ -20,7 +20,7 @@ typedef struct _CITEM ICompatibilityPage ******************************************************************************/ -DEFINE_GUID(CLSID_ICompatibilityPage, 0x513D916F, 0x2A8E, 0x4F51, 0x00AE, 0xAB,0x0C,0xBC,0x76,0xFB,0x1A,0xF9); /* F8 on XP! */ +static const GUID CLSID_ICompatibilityPage = {0x513D916F,0x2A8E,0x4F51,{0xAE,0xAB,0x0C,0xBC,0x76,0xFB,0x1A,0xF9}}; /* F8 on XP! */ typedef struct ICompatibilityPage *LPCOMPATIBILITYPAGE; diff --git a/reactos/dll/win32/shellext/slayer/slayer.rbuild b/reactos/dll/win32/shellext/slayer/slayer.rbuild index 3ddf99c31ca..de6e26c3d31 100644 --- a/reactos/dll/win32/shellext/slayer/slayer.rbuild +++ b/reactos/dll/win32/shellext/slayer/slayer.rbuild @@ -12,6 +12,7 @@ advapi32 ole32 shell32 + uuid slayer.c slayer.rc precomp.h diff --git a/reactos/dll/win32/syssetup/syssetup.rbuild b/reactos/dll/win32/syssetup/syssetup.rbuild index 557e440f609..9a3efaca02a 100644 --- a/reactos/dll/win32/syssetup/syssetup.rbuild +++ b/reactos/dll/win32/syssetup/syssetup.rbuild @@ -7,6 +7,7 @@ 0x0600 0x0501 0x0501 + pseh uuid ntdll kernel32 @@ -20,7 +21,6 @@ ole32 shell32 shlwapi - pseh classinst.c dllmain.c install.c diff --git a/reactos/include/psdk/shlguid.h b/reactos/include/psdk/shlguid.h index 231feb3ee99..4335ebe544d 100644 --- a/reactos/include/psdk/shlguid.h +++ b/reactos/include/psdk/shlguid.h @@ -7,98 +7,128 @@ #ifdef __cplusplus extern "C" { #endif -#define DEFINE_SHLGUID(n,l,w1,w2) DEFINE_GUID(n,l,w1,w2,0xC0,0,0,0,0,0,0,0x46) -#define SID_SShellBrowser IID_IShellBrowser -extern const GUID CLSID_MyComputer; -extern const GUID CLSID_MyDocuments; -extern const GUID CLSID_ShellDesktop; -extern const GUID CLSID_ShellLink; -extern const GUID CLSID_ControlPanel; -extern const GUID CLSID_Internet; -extern const GUID CLSID_NetworkPlaces; -extern const GUID CLSID_RecycleBin; -extern const GUID CLSID_ShellFSFolder; -extern const GUID CLSID_Printers; -extern const GUID CLSID_FolderShortcut; -extern const GUID FMTID_Intshcut; -extern const GUID FMTID_InternetSite; -extern const GUID CGID_Explorer; -extern const GUID CGID_ShellDocView; -extern const GUID CGID_ShellServiceObject; -extern const GUID IID_INewShortcutHookA; -extern const GUID IID_IShellBrowser; -extern const GUID IID_IShellView; -extern const GUID IID_IContextMenu; -extern const GUID IID_IColumnProvider; -extern const GUID IID_IQueryInfo; -extern const GUID IID_IShellIcon; -extern const GUID IID_IShellIconOverlayIdentifier; -extern const GUID IID_IShellFolder; -extern const GUID IID_IShellExtInit; -extern const GUID IID_IShellPropSheetExt; -extern const GUID IID_IPersistFolder; -extern const GUID IID_IExtractIconA; -extern const GUID IID_IShellLinkA; -extern const GUID IID_IShellLinkDataList; -extern const GUID IID_IShellCopyHookA; -extern const GUID IID_IFileViewerA; -extern const GUID IID_ICommDlgBrowser; -extern const GUID IID_IEnumIDList; -extern const GUID IID_IFileViewerSite; -extern const GUID IID_IContextMenu2; -extern const GUID IID_IShellExecuteHookA; -extern const GUID IID_IPropSheetPage; -extern const GUID IID_INewShortcutHookW; -extern const GUID IID_IFileViewerW; -extern const GUID IID_IShellLinkW; -extern const GUID IID_IExtractIconW; -extern const GUID IID_IShellExecuteHookW; -extern const GUID IID_IShellCopyHookW; -extern const GUID IID_IShellView2; -extern const GUID LIBID_SHDocVw; -extern const GUID IID_IShellExplorer; -extern const GUID DIID_DShellExplorerEvents; -extern const GUID CLSID_ShellExplorer; -extern const GUID IID_ISHItemOC; -extern const GUID DIID_DSHItemOCEvents; -extern const GUID CLSID_SHItemOC; -extern const GUID IID_DHyperLink; -extern const GUID IID_DIExplorer; -extern const GUID DIID_DExplorerEvents; -extern const GUID CLSID_InternetExplorer; -extern const GUID CLSID_StdHyperLink; -extern const GUID CLSID_FileTypes; -extern const GUID CLSID_InternetShortcut; -extern const GUID IID_IUniformResourceLocator; -extern const GUID CLSID_DragDropHelper; -extern const GUID IID_IDropTargetHelper; -extern const GUID IID_IDragSourceHelper; -#if (_WIN32_IE >= 0x400 || _WIN32_WINNT >= 0x500) -extern const GUID IID_IPersistFolder2; -extern const GUID CLSID_AutoComplete; -#endif -#if (_WIN32_WINNT >= 0x500) -extern const GUID IID_IPersistFolder3; -extern const GUID IID_IShellFolder2; -extern const GUID IID_IFileSystemBindData; -#endif + +#define DEFINE_SHLGUID(name, l, w1, w2) DEFINE_OLEGUID(name,l,w1,w2) + +DEFINE_SHLGUID(CLSID_ShellDesktop, 0x00021400L, 0, 0); +DEFINE_SHLGUID(CLSID_ShellLink, 0x00021401L, 0, 0); + +DEFINE_SHLGUID(CATID_BrowsableShellExt, 0x00021490L, 0, 0); +DEFINE_SHLGUID(CATID_BrowseInPlace, 0x00021491L, 0, 0); +DEFINE_SHLGUID(CATID_DeskBand, 0x00021492L, 0, 0); +DEFINE_SHLGUID(CATID_InfoBand, 0x00021493L, 0, 0); +DEFINE_SHLGUID(CATID_CommBand, 0x00021494L, 0, 0); + +/* shell32 formatids */ +DEFINE_SHLGUID(FMTID_Intshcut, 0x000214A0L, 0, 0); +DEFINE_SHLGUID(FMTID_InternetSite, 0x000214A1L, 0, 0); + +/* command group ids */ +DEFINE_SHLGUID(CGID_Explorer, 0x000214D0L, 0, 0); +DEFINE_SHLGUID(CGID_ShellDocView, 0x000214D1L, 0, 0); +DEFINE_SHLGUID(CGID_ShellServiceObject, 0x000214D2L, 0, 0); +DEFINE_SHLGUID(CGID_ExplorerBarDoc, 0x000214D3L, 0, 0); + +DEFINE_SHLGUID(IID_IShellIcon, 0x000214E5L, 0, 0); +DEFINE_SHLGUID(IID_IShellPropSheetExt, 0x000214E9L, 0, 0); +DEFINE_SHLGUID(IID_IShellDetails, 0x000214ECL, 0, 0); +DEFINE_SHLGUID(IID_IDelayedRelease, 0x000214EDL, 0, 0); +DEFINE_SHLGUID(IID_IShellCopyHookA, 0x000214EFL, 0, 0); +DEFINE_SHLGUID(IID_IFileViewerA, 0x000214F0L, 0, 0); +DEFINE_SHLGUID(IID_IFileViewerSite, 0x000214F3L, 0, 0); +DEFINE_SHLGUID(IID_IPropSheetPage, 0x000214F6L, 0, 0); +DEFINE_SHLGUID(IID_IFileViewerW, 0x000214F8L, 0, 0); +DEFINE_SHLGUID(IID_IShellCopyHookW, 0x000214FCL, 0, 0); +DEFINE_SHLGUID(IID_IRemoteComputer, 0x000214FEL, 0, 0); +DEFINE_SHLGUID(IID_IQueryInfo, 0x00021500L, 0, 0); + +DEFINE_SHLGUID(IID_IExtractIconA, 0x000214EBL, 0, 0); +DEFINE_SHLGUID(IID_IExtractIconW, 0x000214FAL, 0, 0); +DEFINE_SHLGUID(IID_IContextMenu, 0x000214E4L, 0, 0); +DEFINE_SHLGUID(IID_IContextMenu2, 0x000214F4L, 0, 0); +DEFINE_SHLGUID(IID_ICommDlgBrowser, 0x000214F1L, 0, 0); +DEFINE_SHLGUID(IID_IShellBrowser, 0x000214E2L, 0, 0); +DEFINE_SHLGUID(IID_IShellView, 0x000214E3L, 0, 0); +DEFINE_SHLGUID(IID_IShellFolder, 0x000214E6L, 0, 0); +DEFINE_SHLGUID(IID_IShellExtInit, 0x000214E8L, 0, 0); +DEFINE_SHLGUID(IID_IPersistFolder, 0x000214EAL, 0, 0); +DEFINE_SHLGUID(IID_IShellLinkA, 0x000214EEL, 0, 0); +DEFINE_SHLGUID(IID_IEnumIDList, 0x000214F2L, 0, 0); +DEFINE_SHLGUID(IID_IShellLinkW, 0x000214F9L, 0, 0); +DEFINE_SHLGUID(IID_IShellExecuteHookA, 0x000214F5L, 0, 0); +DEFINE_SHLGUID(IID_IShellExecuteHookW, 0x000214FBL, 0, 0); +DEFINE_SHLGUID(IID_INewShortcutHookA, 0x000214E1L, 0, 0); +DEFINE_SHLGUID(IID_INewShortcutHookW, 0x000214F7L, 0, 0); + +DEFINE_GUID(CLSID_CUrlHistory, 0x3c374a40, 0xbae4, 0x11cf, 0xbf, 0x7d, 0x00, 0xaa, 0x00, 0x69, 0x46, 0xee); +#define SID_SUrlHistory CLSID_CUrlHistory + +DEFINE_GUID(CLSID_CURLSearchHook, 0xcfbfae00, 0x17a6, 0x11d0, 0x99, 0xcb, 0x00, 0xc0, 0x4f, 0xd6, 0x44, 0x97); + +DEFINE_GUID(SID_STopLevelBrowser, 0x4C96BE40L, 0x915C, 0x11CF, 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37); + +#define SID_SShellBrowser IID_IShellBrowser + #ifdef UNICODE -#define IID_IFileViewer IID_IFileViewerW -#define IID_IShellLink IID_IShellLinkW -#define IID_IExtractIcon IID_IExtractIconW -#define IID_IShellCopyHook IID_IShellCopyHookW -#define IID_IShellExecuteHook IID_IShellExecuteHookW -#define IID_INewShortcutHook IID_INewShortcutHookW +#define IID_IFileViewer IID_IFileViewerW +#define IID_IShellLink IID_IShellLinkW +#define IID_IExtractIcon IID_IExtractIconW +#define IID_IShellCopyHook IID_IShellCopyHookW +#define IID_IShellExecuteHook IID_IShellExecuteHookW +#define IID_INewShortcutHook IID_INewShortcutHookW #else -#define IID_IFileViewer IID_IFileViewerA -#define IID_IShellLink IID_IShellLinkA -#define IID_IExtractIcon IID_IExtractIconA -#define IID_IShellCopyHook IID_IShellCopyHookA -#define IID_IShellExecuteHook IID_IShellExecuteHookA -#define IID_INewShortcutHook IID_INewShortcutHookA +#define IID_IFileViewer IID_IFileViewerA +#define IID_IShellLink IID_IShellLinkA +#define IID_IExtractIcon IID_IExtractIconA +#define IID_IShellCopyHook IID_IShellCopyHookA +#define IID_IShellExecuteHook IID_IShellExecuteHookA +#define IID_INewShortcutHook IID_INewShortcutHookA #endif -extern const GUID IID_IInputObject; -extern const GUID IID_IInputObjectSite; + +DEFINE_GUID(IID_IDockingWindow, 0x012dd920L, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); +DEFINE_GUID(IID_IDockingWindowSite, 0x2A342FC2L, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); +DEFINE_GUID(IID_IInputObject, 0x068284FAA, 0x6A48, 0x11D0, 0x8C, 0x78, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xB4); +DEFINE_GUID(IID_IInputObjectSite, 0x0F1DB8392, 0x7331, 0x11D0, 0x8C, 0x99, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); + +/**************************************************************************** + * the next IID's are the namespace elements of the pidls + */ +DEFINE_GUID(CLSID_NetworkPlaces, 0x208D2C60, 0x3AEA, 0x1069, 0xA2, 0xD7, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); +DEFINE_GUID(CLSID_NetworkDomain, 0x46e06680, 0x4bf0, 0x11d1, 0x83, 0xee, 0x00, 0xa0, 0xc9, 0x0d, 0xc8, 0x49); +DEFINE_GUID(CLSID_NetworkServer, 0xc0542a90, 0x4bf0, 0x11d1, 0x83, 0xee, 0x00, 0xa0, 0xc9, 0x0d, 0xc8, 0x49); +DEFINE_GUID(CLSID_NetworkShare, 0x54a754c0, 0x4bf0, 0x11d1, 0x83, 0xee, 0x00, 0xa0, 0xc9, 0x0d, 0xc8, 0x49); +DEFINE_GUID(CLSID_MyComputer, 0x20D04FE0, 0x3AEA, 0x1069, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); +DEFINE_GUID(CLSID_Internet, 0x871C5380, 0x42A0, 0x1069, 0xA2, 0xEA, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); +DEFINE_GUID(CLSID_ShellFSFolder, 0xF3364BA0, 0x65B9, 0x11CE, 0xA9, 0xBA, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37); +DEFINE_GUID(CLSID_RecycleBin, 0x645FF040, 0x5081, 0x101B, 0x9F, 0x08, 0x00, 0xAA, 0x00, 0x2F, 0x95, 0x4E); +DEFINE_GUID(CLSID_ControlPanel, 0x21EC2020, 0x3AEA, 0x1069, 0xA2, 0xDD, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); +DEFINE_GUID(CLSID_Printers, 0x2227A280, 0x3AEA, 0x1069, 0xA2, 0xDE, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); +DEFINE_GUID(CLSID_MyDocuments, 0x450d8fba, 0xad25, 0x11d0, 0x98, 0xa8, 0x08, 0x00, 0x36, 0x1b, 0x11, 0x03); +DEFINE_GUID(CLSID_FolderShortcut, 0x0AFACED1, 0xE828, 0x11D1, 0x91, 0x87, 0xB5, 0x32, 0xF1, 0xE9, 0x57, 0x5D); + +DEFINE_GUID(IID_IQueryAssociations, 0xc46ca590, 0x3c3f, 0x11d2, 0xbe, 0xe6, 0x00, 0x00, 0xf8, 0x05, 0xca, 0x57); + +DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x00, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); + +DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); + +#define PSGUID_SHELLDETAILS {0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0} +DEFINE_GUID(FMTID_ShellDetails, 0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); +#define PID_FINDDATA 0 +#define PID_NETRESOURCE 1 +#define PID_DESCRIPTIONID 2 +#define PID_WHICHFOLDER 3 +#define PID_NETWORKLOCATION 4 +#define PID_COMPUTERNAME 5 + +/* Note: PSGUID_STORAGE defined in ntquery.h */ +DEFINE_GUID(FMTID_Storage, 0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac); +/* PID_* for FMTID_Storage defined in ntquery.h*/ + +#define PSGUID_DISPLACED {0x9b174b33, 0x40ff, 0x11d2, 0xa2, 0x7e, 0x0, 0xc0, 0x4f, 0xc3, 0x8, 0x71} +DEFINE_GUID(FMTID_Displaced, 0x9b174b33, 0x40ff, 0x11d2, 0xa2, 0x7e, 0x0, 0xc0, 0x4f, 0xc3, 0x8, 0x71); +#define PID_DISPLACED_FROM 2 +#define PID_DISPLACED_DATE 3 #ifdef __cplusplus } diff --git a/reactos/include/psdk/shlobj.h b/reactos/include/psdk/shlobj.h index 1f303f638d2..5c939bd3d89 100644 --- a/reactos/include/psdk/shlobj.h +++ b/reactos/include/psdk/shlobj.h @@ -349,6 +349,8 @@ extern "C" { #define FCW_STATUS 1 #define FCW_TOOLBAR 2 #define FCW_TREE 3 +#define FCW_INTERNETBAR 6 +#define FCW_PROGRESS 8 #define FCT_MERGE 1 #define FCT_CONFIGABLE 2 #define FCT_ADDTOEND 4 @@ -1549,8 +1551,36 @@ DECLARE_INTERFACE_(IShellView2,IShellView) STDMETHOD(GetItemObject)(THIS_ UINT,REFIID,PVOID*) PURE; STDMETHOD(GetView)(THIS_ SHELLVIEWID*,ULONG) PURE; STDMETHOD(CreateViewWindow2)(THIS_ LPSV2CVW2_PARAMS) PURE; + STDMETHOD(HandleRename)(THIS_ PCUITEMID_CHILD) PURE; + STDMETHOD(SelectAndPositionItem)(THIS_ PCUITEMID_CHILD,UINT,POINT*) PURE; }; #undef INTERFACE +#ifdef COBJMACROS +#define IShellView2_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b) +#define IShellView2_AddRef(T) (T)->lpVtbl->AddRef(T) +#define IShellView2_Release(T) (T)->lpVtbl->Release(T) +#define IShellView2_GetWindow(T,a) (T)->lpVtbl->GetWindow(T,a) +#define IShellView2_ContextSensitiveHelp(T,a) (T)->lpVtbl->ContextSensitiveHelp(T,a) +#define IShellView2_TranslateAccelerator(T,a) (T)->lpVtbl->TranslateAccelerator(T,a) +#ifdef _FIX_ENABLEMODELESS_CONFLICT +#define IShellView2_EnableModeless(T,a) (T)->lpVtbl->EnableModelessSV(T,a) +#else +#define IShellView2_EnableModeless(T,a) (T)->lpVtbl->EnableModeless(T,a) +#endif +#define IShellView2_UIActivate(T,a) (T)->lpVtbl->UIActivate(T,a) +#define IShellView2_Refresh(T) (T)->lpVtbl->Refresh(T) +#define IShellView2_CreateViewWindow(T,a,b,c,d,e) (T)->lpVtbl->CreateViewWindow(T,a,b,c,d,e) +#define IShellView2_DestroyViewWindow(T) (T)->lpVtbl->DestroyViewWindow(T) +#define IShellView2_GetCurrentInfo(T,a) (T)->lpVtbl->GetCurrentInfo(T,a) +#define IShellView2_AddPropertySheetPages(T,a,b,c) (T)->lpVtbl->AddPropertySheetPages(T,a,b,c) +#define IShellView2_SaveViewState(T) (T)->lpVtbl->SaveViewState(T) +#define IShellView2_SelectItem(T,a,b) (T)->lpVtbl->SelectItem(T,a,b) +#define IShellView2_GetItemObject(T,a,b,c) (T)->lpVtbl->GetItemObject(T,a,b,c) +#define IShellView2_GetView(T,a,b) (T)->lpVtbl->GetView(T,a,b) +#define IShellView2_CreateViewWindow2(T,a) (T)->lpVtbl->CreateViewWindow2(T,a) +#define IShellView2_HandleRename(T,a) (T)->lpVtbl->HandleRename(T,a) +#define IShellView2_SelectAndPositionItem(T,a,b,c) (T)->lpVtbl->SelectAndPositionItem(T,a,b,c) +#endif #define INTERFACE IShellExecuteHookA DECLARE_INTERFACE_(IShellExecuteHookA,IUnknown) @@ -1762,11 +1792,22 @@ typedef struct _CSFV FOLDERVIEWMODE fvm; } CSFV, *LPCSFV; +/* FIXME: Add the IShellFolderViewCB interface! */ +#define IShellFolderViewCB void +typedef struct _SFV_CREATE +{ + UINT cbSize; + IShellFolder *pshf; + IShellView *psvOuter; + IShellFolderViewCB *psfvcb; +} SFV_CREATE; + void WINAPI SHAddToRecentDocs(UINT,PCVOID); LPITEMIDLIST WINAPI SHBrowseForFolderA(PBROWSEINFOA); LPITEMIDLIST WINAPI SHBrowseForFolderW(PBROWSEINFOW); DWORD WINAPI SHCLSIDFromStringA(LPCSTR,CLSID*); DWORD WINAPI SHCLSIDFromStringW(LPCWSTR,CLSID*); +HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE*,IShellView**); HRESULT WINAPI SHCreateShellFolderViewEx(LPCSFV pshfvi, IShellView **ppshv); void WINAPI SHChangeNotify(LONG,UINT,PCVOID,PCVOID); HRESULT WINAPI SHGetDataFromIDListA(LPSHELLFOLDER,LPCITEMIDLIST,int,PVOID,int); @@ -1825,6 +1866,9 @@ LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST); UINT WINAPI ILGetSize(LPCITEMIDLIST); void WINAPI ILFree(LPITEMIDLIST); +void WINAPI SHFree(LPVOID); +LPITEMIDLIST WINAPI SHCloneSpecialIDList(HWND,DWORD,BOOL); + HRESULT WINAPI SHCoCreateInstance(LPCWSTR,REFCLSID,IUnknown*,REFIID,void**); BOOL WINAPI SHObjectProperties(HWND,DWORD,LPCWSTR,LPCWSTR); #endif diff --git a/reactos/include/psdk/shtypes.h b/reactos/include/psdk/shtypes.h index d5218b96c8c..3f7baa0d592 100644 --- a/reactos/include/psdk/shtypes.h +++ b/reactos/include/psdk/shtypes.h @@ -39,6 +39,8 @@ typedef enum tagSTRRET_TYPE { STRRET_CSTR = 2 } STRRET_TYPE; +#define PCUITEMID_CHILD LPCITEMIDLIST + #pragma pack(pop) #ifdef __cplusplus } diff --git a/reactos/include/psdk/unknwn.h b/reactos/include/psdk/unknwn.h index 4a8c3fc4712..3ce60d1921c 100644 --- a/reactos/include/psdk/unknwn.h +++ b/reactos/include/psdk/unknwn.h @@ -16,8 +16,9 @@ extern "C"{ void * __RPC_USER MIDL_user_allocate(size_t); void __RPC_USER MIDL_user_free(void*); -EXTERN_C const IID IID_IUnknown; -EXTERN_C const IID IID_IClassFactory; + +DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +DEFINE_OLEGUID(IID_IClassFactory, 0x00000001, 0, 0); #ifndef __IUnknown_INTERFACE_DEFINED__ #define __IUnknown_INTERFACE_DEFINED__ #define INTERFACE IUnknown diff --git a/reactos/include/psdk/winbase.h b/reactos/include/psdk/winbase.h index 9b7400f7ba6..b54e56732bd 100644 --- a/reactos/include/psdk/winbase.h +++ b/reactos/include/psdk/winbase.h @@ -1443,7 +1443,6 @@ DWORD WINAPI GetDllDirectoryW(DWORD,LPWSTR); UINT WINAPI GetDriveTypeA(LPCSTR); UINT WINAPI GetDriveTypeW(LPCWSTR); LPSTR WINAPI GetEnvironmentStrings(void); -LPSTR WINAPI GetEnvironmentStringsA(void); LPWSTR WINAPI GetEnvironmentStringsW(void); DWORD WINAPI GetEnvironmentVariableA(LPCSTR,LPSTR,DWORD); DWORD WINAPI GetEnvironmentVariableW(LPCWSTR,LPWSTR,DWORD); @@ -2360,6 +2359,7 @@ typedef ENUMRESTYPEPROCA ENUMRESTYPEPROC; #define GetDllDirectory GetDllDirectoryA #endif #define GetDriveType GetDriveTypeA +#define GetEnvironmentStringsA GetEnvironmentStrings #define GetEnvironmentVariable GetEnvironmentVariableA #define GetFileAttributes GetFileAttributesA #define GetFileAttributesEx GetFileAttributesExA diff --git a/reactos/include/reactos/wine/shlguid.h b/reactos/include/reactos/wine/shlguid.h index b63e25525f2..1956e490811 100644 --- a/reactos/include/reactos/wine/shlguid.h +++ b/reactos/include/reactos/wine/shlguid.h @@ -60,4 +60,6 @@ DEFINE_GUID(IID_IInputObjectSite, 0x0F1DB8392, 0x7331, 0x11D0, 0x8C, 0x99, 0x0 DEFINE_GUID(IID_IShellLinkDataList, 0x45e2b4ae, 0xb1c3, 0x11d0, 0xb9, 0x2f, 0x00, 0xa0, 0xc9, 0x03, 0x12, 0xe1); +DEFINE_SHLGUID(IID_IShellPropSheetExt, 0x000214E9L, 0, 0); + #endif /* __WINE_SHLGUID_H */ diff --git a/reactos/include/reactos/wine/unknwn.h b/reactos/include/reactos/wine/unknwn.h index 2dc493c94df..3e994dcaa05 100644 --- a/reactos/include/reactos/wine/unknwn.h +++ b/reactos/include/reactos/wine/unknwn.h @@ -3,14 +3,14 @@ #ifndef __WINE_UNKNWN_H #define __WINE_UNKNWN_H -DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46); +/*DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);*/ /*** IUnknown methods ***/ #define IUnknown_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) #define IUnknown_AddRef(p) (p)->lpVtbl->AddRef(p) #define IUnknown_Release(p) (p)->lpVtbl->Release(p) -DEFINE_GUID(IID_IClassFactory, 0x00000001, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46); +/*DEFINE_GUID(IID_IClassFactory, 0x00000001, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);*/ /*** IUnknown methods ***/ #define IClassFactory_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) diff --git a/reactos/lib/dxguid/dxguid-mingw.c b/reactos/lib/dxguid/dxguid-mingw.c index 65d3343e1f3..2a1ca95a7be 100644 --- a/reactos/lib/dxguid/dxguid-mingw.c +++ b/reactos/lib/dxguid/dxguid-mingw.c @@ -10,12 +10,9 @@ */ -#if defined(__LCC__) || defined(__GNUC__) -#define INITGUID 1 -#include -#else +#define INITGUID #include -#endif +#include // wine own or ? // but it keep dsound happy diff --git a/reactos/lib/lib.rbuild b/reactos/lib/lib.rbuild index f461de15335..149dabdcf43 100644 --- a/reactos/lib/lib.rbuild +++ b/reactos/lib/lib.rbuild @@ -34,6 +34,9 @@ + + + diff --git a/reactos/lib/mingw/CRTfmode.c b/reactos/lib/mingw/CRTfmode.c new file mode 100644 index 00000000000..bf750d94e1c --- /dev/null +++ b/reactos/lib/mingw/CRTfmode.c @@ -0,0 +1,16 @@ +/* + * CRTfmode.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Include this object to set _CRT_fmode to a state that will cause + * _mingw32_init_fmode to leave all file modes in their default state + * (basically text mode). + * + * To use this object include the object file in your link command: + * gcc -o foo.exe foo.o CRTfmode.o + * + */ + +int _CRT_fmode = 0; diff --git a/reactos/lib/mingw/CRTglob.c b/reactos/lib/mingw/CRTglob.c new file mode 100644 index 00000000000..a4f5fe051f9 --- /dev/null +++ b/reactos/lib/mingw/CRTglob.c @@ -0,0 +1,16 @@ +/* + * CRTglob.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Include this object file to set _CRT_glob to a state that will + * turn on command line globbing by default. NOTE: _CRT_glob has a default + * state of on. Specify CRT_noglob.o to turn off globbing by default. + * + * To use this object include the object file in your link command: + * gcc -o foo.exe foo.o CRTglob.o + * + */ + +int _CRT_glob = -1; diff --git a/reactos/lib/mingw/CRTinit.c b/reactos/lib/mingw/CRTinit.c new file mode 100644 index 00000000000..bb2304d1dd7 --- /dev/null +++ b/reactos/lib/mingw/CRTinit.c @@ -0,0 +1,24 @@ +/* + * CRTinit.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * A dummy version of _CRT_INIT for MS compatibility. Programs, or more often + * dlls, which use the static version of the MSVC run time are supposed to + * call _CRT_INIT to initialize the run time library in DllMain. This does + * not appear to be necessary when using crtdll or the dll versions of the + * MSVC runtime, so the dummy call simply does nothing. + * + * This object file is included as a standard in the link process as provided + * by the appropriate GCC frontend. + * + * To use this object include the object file in your link command: + * gcc -o foo.exe foo.o CRTinit.o + * + */ + +void +_CRT_INIT () +{ +} diff --git a/reactos/lib/tgetopt/_wgetopt.c b/reactos/lib/mingw/_wgetopt.c similarity index 100% rename from reactos/lib/tgetopt/_wgetopt.c rename to reactos/lib/mingw/_wgetopt.c diff --git a/reactos/lib/mingw/binmode.c b/reactos/lib/mingw/binmode.c new file mode 100644 index 00000000000..1cc3dedbfc8 --- /dev/null +++ b/reactos/lib/mingw/binmode.c @@ -0,0 +1,5 @@ +#include + +/* Set default file mode to binary */ + +int _fmode = _O_BINARY; diff --git a/reactos/lib/mingw/cpu_features.c b/reactos/lib/mingw/cpu_features.c new file mode 100644 index 00000000000..0eccfbfe3c6 --- /dev/null +++ b/reactos/lib/mingw/cpu_features.c @@ -0,0 +1,105 @@ +#include +#include "cpu_features.h" + +/* level 1 edx bits */ +#define EDX_CX8 (1 << 8) /* CMPXCHG8B */ +#define EDX_CMOV (1 << 15) +#define EDX_MMX (1 << 23) +#define EDX_FXSR (1 << 24) /* FXSAVE and FXRSTOR */ +#define EDX_SSE (1 << 25) +#define EDX_SSE2 (1 << 26) + +/* level 1 ecx bits */ +#define ECX_SSE3 (1 << 0) +#define ECX_CX16 (1 << 13) /* CMPXCHG16B */ + +/* extended level 0x80000001 edx bits */ +#define EDX_3DNOW (1 << 31) +#define EDX_3DNOWP (1 << 30) +#define EDX_LM (1 << 29) /*LONG MODE */ + +#define __cpuid(level,a,b,c,d) \ + __asm__ __volatile__ ("cpuid;" \ + : "=a" (a), "=b" (b), "=c" (c), "=d" (d)\ + : "0" (level)) + +/* Combine the different cpuid flags into a single bitmap. */ + +unsigned int __cpu_features = 0; + +void __cpu_features_init (void) +{ + unsigned int eax, ebx, ecx, edx; + /* Try to change the value of CPUID bit (bit 21) in EFLAGS. + If the bit can be toggled, CPUID is supported. */ + asm volatile ("pushfl; pushfl; popl %0;" + "movl %0,%1; xorl %2,%0;" + "pushl %0; popfl; pushfl; popl %0; popfl" + : "=&r" (eax), "=&r" (ebx) + : "i" (0x00200000)); + + if (((eax ^ ebx) & 0x00200000) == 0) + return; + + __cpuid (0, eax, ebx, ecx, edx); + if (eax == 0) + return; + + __cpuid (1, eax, ebx, ecx, edx); + + if (edx & EDX_CX8) + __cpu_features |= _CRT_CMPXCHG8B; + if (edx & EDX_CMOV) + __cpu_features |= _CRT_CMOV; + + if (edx & EDX_MMX) + __cpu_features |= _CRT_MMX; + if (edx & EDX_FXSR) + __cpu_features |= _CRT_FXSR; + if (edx & EDX_SSE) + __cpu_features |= _CRT_SSE; + if (edx & EDX_SSE2) + __cpu_features |= _CRT_SSE2; + + + if (ecx & ECX_SSE3) + __cpu_features |= _CRT_SSE3; + if (ecx & ECX_CX16) + __cpu_features |= _CRT_CMPXCHG16B; + + __cpuid (0x80000000, eax, ebx, ecx, edx); + if (eax < 0x80000001) + return; + __cpuid (0x80000001, eax, ebx, ecx, edx); + if (edx & EDX_3DNOW); + __cpu_features |= _CRT_3DNOW; + if (edx & EDX_3DNOWP) + __cpu_features |= _CRT_3DNOWP; + + return; +} + +#ifdef TEST + +#include +#define report(feature) \ + if ((feature) & __cpu_features) printf( #feature " found\n") + +int main() +{ + __cpu_features_init(); + + report(_CRT_CMPXCHG8B); + report(_CRT_CMOV); + report(_CRT_MMX); + report(_CRT_FXSR); + report(_CRT_SSE); + report(_CRT_SSE2); + report(_CRT_SSE3); + report(_CRT_CMPXCHG16B); + report(_CRT_3DNOW); + report(_CRT_3DNOWP); + return 0; +} + +#endif diff --git a/reactos/lib/mingw/cpu_features.h b/reactos/lib/mingw/cpu_features.h new file mode 100644 index 00000000000..64318574776 --- /dev/null +++ b/reactos/lib/mingw/cpu_features.h @@ -0,0 +1,25 @@ +#ifndef _CPU_FEATURES_H +#define _CPU_FEATURES_H + +#include + +#define _CRT_CMPXCHG8B 0x0001 +#define _CRT_CMOV 0x0002 +#define _CRT_MMX 0x0004 +#define _CRT_FXSR 0x0008 +#define _CRT_SSE 0x0010 +#define _CRT_SSE2 0x0020 +#define _CRT_SSE3 0x0040 +#define _CRT_CMPXCHG16B 0x0080 +#define _CRT_3DNOW 0x0100 +#define _CRT_3DNOWP 0x0200 + +extern unsigned int __cpu_features; + +/* Currently we use this in fpenv functions */ +#define __HAS_SSE __cpu_features & _CRT_SSE + +void __cpu_features_init (void); + + +#endif diff --git a/reactos/lib/mingw/crt1.c b/reactos/lib/mingw/crt1.c new file mode 100644 index 00000000000..65f248dd978 --- /dev/null +++ b/reactos/lib/mingw/crt1.c @@ -0,0 +1,283 @@ +/* + * crt1.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Source code for the startup proceedures used by all programs. This code + * is compiled to make crt1.o, which should be located in the library path. + * + */ + +/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to + avoid problems with older GCC. */ +#define __IN_MINGW_RUNTIME +#include +#include +#include +#include +#include +#define WIN32_LEAN_AND_MEAN +#include +#include + +/* NOTE: The code for initializing the _argv, _argc, and environ variables + * has been moved to a separate .c file which is included in both + * crt1.c and dllcrt1.c. This means changes in the code don't have to + * be manually synchronized, but it does lead to this not-generally- + * a-good-idea use of include. */ +#include "init.c" +#include "cpu_features.h" + +extern void _pei386_runtime_relocator (void); + +extern int main (int, char **, char **); + +/* + * Must have the correct app type for MSVCRT. + */ + +#ifdef __MSVCRT__ +#define __UNKNOWN_APP 0 +#define __CONSOLE_APP 1 +#define __GUI_APP 2 +__MINGW_IMPORT void __set_app_type(int); +#endif /* __MSVCRT__ */ + +/* Global _fmode for this .exe, not the one in msvcrt.dll, + The default is set in txtmode.o in libmingw32.a */ +/* Override the dllimport'd declarations in stdlib.h */ +#undef _fmode +extern int _fmode; +#ifdef __MSVCRT__ +extern int* __p__fmode(void); /* To access the dll _fmode */ +#endif + +/* + * Setup the default file handles to have the _CRT_fmode mode, as well as + * any new files created by the user. + */ +extern int _CRT_fmode; + +static void +_mingw32_init_fmode (void) +{ + /* Don't set the std file mode if the user hasn't set any value for it. */ + if (_CRT_fmode) + { + _fmode = _CRT_fmode; + + /* + * This overrides the default file mode settings for stdin, + * stdout and stderr. At first I thought you would have to + * test with isatty, but it seems that the DOS console at + * least is smart enough to handle _O_BINARY stdout and + * still display correctly. + */ + if (stdin) + { + _setmode (_fileno (stdin), _CRT_fmode); + } + if (stdout) + { + _setmode (_fileno (stdout), _CRT_fmode); + } + if (stderr) + { + _setmode (_fileno (stderr), _CRT_fmode); + } + } + + /* Now sync the dll _fmode to the one for this .exe. */ +#ifdef __MSVCRT__ + *__p__fmode() = _fmode; +#else + *_imp___fmode_dll = _fmode; +#endif +} + +/* This function will be called when a trap occurs. Thanks to Jacob + Navia for his contribution. */ +static CALLBACK long +_gnu_exception_handler (EXCEPTION_POINTERS * exception_data) +{ + void (*old_handler) (int); + long action = EXCEPTION_CONTINUE_SEARCH; + int reset_fpu = 0; + + switch (exception_data->ExceptionRecord->ExceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + /* test if the user has set SIGSEGV */ + old_handler = signal (SIGSEGV, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGSEGV, SIG_IGN); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGSEGV); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: + /* test if the user has set SIGILL */ + old_handler = signal (SIGILL, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGILL, SIG_IGN); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGILL); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_UNDERFLOW: + case EXCEPTION_FLT_INEXACT_RESULT: + reset_fpu = 1; + /* fall through. */ + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + /* test if the user has set SIGFPE */ + old_handler = signal (SIGFPE, SIG_DFL); + if (old_handler == SIG_IGN) + { + signal (SIGFPE, SIG_IGN); + if (reset_fpu) + _fpreset (); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGFPE); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + default: + break; + } + return action; +} + +/* + * The function mainCRTStartup is the entry point for all console programs. + */ +static void __attribute__((noreturn)) +__mingw_CRTStartup (void) +{ + int nRet; + + /* + * Set up the top-level exception handler so that signal handling + * works as expected. The mapping between ANSI/POSIX signals and + * Win32 SE is not 1-to-1, so caveat emptore. + * + */ + SetUnhandledExceptionFilter (_gnu_exception_handler); + + /* + * Initialize floating point unit. + */ + __cpu_features_init (); /* Do we have SSE, etc.*/ + _fpreset (); /* Supplied by the runtime library. */ + + /* + * Set up __argc, __argv and _environ. + */ + _mingw32_init_mainargs (); + + /* + * Sets the default file mode. + * If _CRT_fmode is set, also set mode for stdin, stdout + * and stderr, as well + * NOTE: DLLs don't do this because that would be rude! + */ + _mingw32_init_fmode (); + + /* Adust references to dllimported data that have non-zero offsets. */ + _pei386_runtime_relocator (); + + /* Align the stack to 16 bytes for the sake of SSE ops in main + or in functions inlined into main. */ + asm __volatile__ ("andl $-16, %%esp" : : : "%esp"); + + /* + * Call the main function. If the user does not supply one + * the one in the 'libmingw32.a' library will be linked in, and + * that one calls WinMain. See main.c in the 'lib' dir + * for more details. + */ + nRet = main (_argc, _argv, _environ); + + /* + * Perform exit processing for the C library. This means + * flushing output and calling 'atexit' registered functions. + */ + _cexit (); + + ExitProcess (nRet); +} + +/* + * The function mainCRTStartup is the entry point for all console programs. + */ +void +mainCRTStartup (void) +{ +#ifdef __MSVCRT__ + __set_app_type (__CONSOLE_APP); +#endif + __mingw_CRTStartup (); +} + +/* + * For now the GUI startup function is the same as the console one. + * This simply gets rid of the annoying warning about not being able + * to find WinMainCRTStartup when linking GUI applications. + */ +void +WinMainCRTStartup (void) +{ +#ifdef __MSVCRT__ + __set_app_type (__GUI_APP); +#endif + __mingw_CRTStartup (); +} + +#if 0 +/* + * We force use of library version of atexit, which is only + * visible in import lib as _imp__atexit + */ +extern int (*_imp__atexit)(void (*)(void)); +int atexit (void (* pfn )(void) ) +{ + return ( (*_imp__atexit)(pfn)); +} + +/* Likewise for non-ANSI _onexit */ +extern _onexit_t (*_imp___onexit)(_onexit_t); +_onexit_t +_onexit (_onexit_t pfn ) +{ + return (*_imp___onexit)(pfn); +} +#endif diff --git a/reactos/lib/mingw/dllcrt1.c b/reactos/lib/mingw/dllcrt1.c new file mode 100644 index 00000000000..8101f7133c2 --- /dev/null +++ b/reactos/lib/mingw/dllcrt1.c @@ -0,0 +1,185 @@ +/* + * dllcrt1.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Initialization code for DLLs. + * + */ +#include +#include +#include +#include +#include +#include + +/* Unlike normal crt1, I don't initialize the FPU, because the process + * should have done that already. I also don't set the file handle modes, + * because that would be rude. */ + +#ifdef __GNUC__ +extern void __main (); +extern void __do_global_dtors (); +#endif + +typedef void (* p_atexit_fn )(void); +static p_atexit_fn* first_atexit; +static p_atexit_fn* next_atexit; + +static void +__dll_exit (void); + +/* This is based on the function in the Wine project's exit.c */ +p_atexit_fn __dllonexit (p_atexit_fn, p_atexit_fn**, p_atexit_fn**); + + +extern BOOL WINAPI DllMain (HANDLE, DWORD, LPVOID); + +extern void _pei386_runtime_relocator (void); + +BOOL WINAPI +DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +{ + BOOL bRet; + + if (dwReason == DLL_PROCESS_ATTACH) + { + +#ifdef DEBUG + printf ("%s: DLL_PROCESS_ATTACH (%d)\n", __FUNCTION__); +#endif + + /* Initialize private atexit table for this dll. + 32 is min size required by ANSI */ + + first_atexit = (p_atexit_fn*) malloc (32 * sizeof (p_atexit_fn)); + if (first_atexit == NULL ) /* can't allocate memory */ + { + errno=ENOMEM; + return FALSE; + } + *first_atexit = NULL; + next_atexit = first_atexit; + + /* Adust references to dllimported data (from other DLL's) + that have non-zero offsets. */ + _pei386_runtime_relocator (); + +#ifdef __GNUC__ + /* From libgcc.a, __main calls global class constructors, + __do_global_ctors, which registers __do_global_dtors + as the first entry of the private atexit table we + have just initialised */ + __main (); + +#endif + } + + /* + * Call the user-supplied DllMain subroutine. + * This has to come after initialization of atexit table and + * registration of global constructors. + * NOTE: DllMain is optional, so libmingw32.a includes a stub + * which will be used if the user does not supply one. + */ + + bRet = DllMain (hDll, dwReason, lpReserved); + /* Handle case where DllMain returns FALSE on attachment attempt. */ + + if ( (dwReason == DLL_PROCESS_ATTACH) && !bRet) + { +#ifdef DEBUG + printf ("%s: DLL_PROCESS_ATTACH failed, cleaning up\n", __FUNCTION__); +#endif + + __dll_exit (); /* Cleanup now. This will set first_atexit to NULL so we + know we've cleaned up */ + } + + if (dwReason == DLL_PROCESS_DETACH) + { +#ifdef DEBUG + printf ("%s: DLL_PROCESS_DETACH (%d)\n", __FUNCTION__); +#endif + /* If not attached, return FALSE. Cleanup already done above + if failed attachment attempt. */ + if (! first_atexit ) + bRet = FALSE; + else + /* + * We used to call __do_global_dtors () here. This is + * no longer necessary since __do_global_dtors is now + * registered at start (last out) of private atexit table. + */ + __dll_exit (); + } + return bRet; +} + +static +void +__dll_exit(void) +/* Run LIFO terminators registered in private atexit table */ +{ + if ( first_atexit ) + { + p_atexit_fn* __last = next_atexit - 1; + while ( __last >= first_atexit ) + { + if ( *__last != NULL ) + { +#ifdef DEBUG + printf ("%s: Calling exit function 0x%x from 0x%x\n", + __FUNCTION__, (unsigned)(*__last),(unsigned)__last); +#endif + (**__last) (); + } + __last--; + } + free ( first_atexit ) ; + first_atexit = NULL ; + } + /* + Make sure output buffers opened by DllMain or + atexit-registered functions are flushed before detaching, + otherwise we can have problems with redirected output. + */ + fflush (NULL); +} + +/* + * The atexit exported from msvcrt.dll causes problems in DLLs. + * Here, we override the exported version of atexit with one that passes the + * private table initialised in DllMainCRTStartup to __dllonexit. + * That means we have to hide the mscvrt.dll atexit because the + * atexit defined here gets __dllonexit from the same lib. + */ + +#if 0 +int +atexit (p_atexit_fn pfn ) +{ +#ifdef DEBUG + printf ("%s: registering exit function 0x%x at 0x%x\n", + __FUNCTION__, (unsigned)pfn, (unsigned)next_atexit); +#endif + return (__dllonexit (pfn, &first_atexit, &next_atexit) + == NULL ? -1 : 0 ); +} + +/* + * Likewise for non-ANSI function _onexit that may be called by + * code in the dll. + */ + +_onexit_t +_onexit (_onexit_t pfn ) +{ +#ifdef DEBUG + printf ("%s: registering exit function 0x%x at 0x%x\n", + __FUNCTION__, (unsigned)pfn, (unsigned)next_atexit); +#endif + return ((_onexit_t) __dllonexit ((p_atexit_fn)pfn, &first_atexit, &next_atexit)); +} +#endif diff --git a/reactos/lib/mingw/gccmain.c b/reactos/lib/mingw/gccmain.c new file mode 100644 index 00000000000..601d15a1f5e --- /dev/null +++ b/reactos/lib/mingw/gccmain.c @@ -0,0 +1,79 @@ +/* + * gccmain.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * A separate version of __main, __do_global_ctors and __do_global_dtors for + * Mingw32 for use with Cygwin32 b19. Hopefully this object file will only + * be linked if the libgcc.a doesn't include __main, __do_global_dtors and + * __do_global_ctors. + * + */ + +/* Needed for the atexit prototype. */ +#include + +typedef void (*func_ptr) (void); +extern func_ptr __CTOR_LIST__[]; +extern func_ptr __DTOR_LIST__[]; + +void +__do_global_dtors (void) +{ + static func_ptr *p = __DTOR_LIST__ + 1; + + /* + * Call each destructor in the destructor list until a null pointer + * is encountered. + */ + while (*p) + { + (*(p)) (); + p++; + } +} + +void +__do_global_ctors (void) +{ + unsigned long nptrs = (unsigned long) __CTOR_LIST__[0]; + unsigned i; + + /* + * If the first entry in the constructor list is -1 then the list + * is terminated with a null entry. Otherwise the first entry was + * the number of pointers in the list. + */ + if (nptrs == -1) + { + for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++) + ; + } + + /* + * Go through the list backwards calling constructors. + */ + for (i = nptrs; i >= 1; i--) + { + __CTOR_LIST__[i] (); + } + + /* + * Register the destructors for processing on exit. + */ + atexit (__do_global_dtors); +} + +static int initialized = 0; + +void +__main (void) +{ + if (!initialized) + { + initialized = 1; + __do_global_ctors (); + } +} + diff --git a/reactos/lib/tgetopt/getopt.c b/reactos/lib/mingw/getopt.c similarity index 100% rename from reactos/lib/tgetopt/getopt.c rename to reactos/lib/mingw/getopt.c diff --git a/reactos/lib/mingw/include/_mingw.h b/reactos/lib/mingw/include/_mingw.h new file mode 100644 index 00000000000..59f4f39b6f7 --- /dev/null +++ b/reactos/lib/mingw/include/_mingw.h @@ -0,0 +1,165 @@ +/* + * _mingw.h + * + * Mingw specific macros included by ALL include files. + * + * This file is part of the Mingw32 package. + * + * Contributors: + * Created by Mumit Khan + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __MINGW_H +#define __MINGW_H + +/* These are defined by the user (or the compiler) + to specify how identifiers are imported from a DLL. + + __DECLSPEC_SUPPORTED Defined if dllimport attribute is supported. + __MINGW_IMPORT The attribute definition to specify imported + variables/functions. + _CRTIMP As above. For MS compatibility. + __MINGW32_VERSION Runtime version. + __MINGW32_MAJOR_VERSION Runtime major version. + __MINGW32_MINOR_VERSION Runtime minor version. + __MINGW32_BUILD_DATE Runtime build date. + + Other macros: + + __int64 define to be long long. Using a typedef doesn't + work for "unsigned __int64" + + All headers should include this first, and then use __DECLSPEC_SUPPORTED + to choose between the old ``__imp__name'' style or __MINGW_IMPORT + style declarations. */ + +/* Try to avoid problems with outdated checks for GCC __attribute__ support. */ +#undef __attribute__ + +#ifndef __GNUC__ +# ifndef __MINGW_IMPORT +# define __MINGW_IMPORT __declspec(dllimport) +# endif +# ifndef _CRTIMP +# define _CRTIMP __declspec(dllimport) +# endif +# define __DECLSPEC_SUPPORTED +# define __attribute__(x) /* nothing */ +#else /* __GNUC__ */ +# ifdef __declspec +# ifndef __MINGW_IMPORT + /* Note the extern. This is needed to work around GCC's + limitations in handling dllimport attribute. */ +# define __MINGW_IMPORT extern __attribute__ ((dllimport)) +# endif +# ifndef _CRTIMP +# ifdef __USE_CRTIMP +# define _CRTIMP __attribute__ ((dllimport)) +# else +# define _CRTIMP +# endif +# endif +# define __DECLSPEC_SUPPORTED +# else /* __declspec */ +# undef __DECLSPEC_SUPPORTED +# undef __MINGW_IMPORT +# ifndef _CRTIMP +# define _CRTIMP +# endif +# endif /* __declspec */ +# ifndef __cdecl +# define __cdecl __attribute__ ((__cdecl__)) +# endif +# ifndef __stdcall +# define __stdcall __attribute__ ((__stdcall__)) +# endif +# ifndef __int64 +# define __int64 long long +# endif +# ifndef __int32 +# define __int32 long +# endif +# ifndef __int16 +# define __int16 short +# endif +# ifndef __int8 +# define __int8 char +# endif +# ifndef __small +# define __small char +# endif +# ifndef __hyper +# define __hyper long long +# endif +#endif /* __GNUC__ */ + +#ifdef __cplusplus +#define __CRT_INLINE inline +#else +#define __CRT_INLINE extern __inline__ +#endif + +#if defined (__GNUC__) && defined (__GNUC_MINOR__) +#define __MINGW_GNUC_PREREQ(major, minor) \ + (__GNUC__ > (major) \ + || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) +#else +#define __MINGW_GNUC_PREREQ(major, minor) 0 +#endif + +#ifdef __cplusplus +# define __UNUSED_PARAM(x) +#else +# ifdef __GNUC__ +# define __UNUSED_PARAM(x) x __attribute__ ((__unused__)) +# else +# define __UNUSED_PARAM(x) x +# endif +#endif + +#ifdef __GNUC__ +#define __MINGW_ATTRIB_NORETURN __attribute__ ((__noreturn__)) +#define __MINGW_ATTRIB_CONST __attribute__ ((__const__)) +#else +#define __MINGW_ATTRIB_NORETURN +#define __MINGW_ATTRIB_CONST +#endif + +#if __MINGW_GNUC_PREREQ (3, 0) +#define __MINGW_ATTRIB_MALLOC __attribute__ ((__malloc__)) +#define __MINGW_ATTRIB_PURE __attribute__ ((__pure__)) +#else +#define __MINGW_ATTRIB_MALLOC +#define __MINGW_ATTRIB_PURE +#endif + +/* Attribute `nonnull' was valid as of gcc 3.3. We don't use GCC's + variadiac macro facility, because variadic macros cause syntax + errors with --traditional-cpp. */ +#if __MINGW_GNUC_PREREQ (3, 3) +#define __MINGW_ATTRIB_NONNULL(arg) __attribute__ ((__nonnull__ (arg))) +#else +#define __MINGW_ATTRIB_NONNULL(arg) +#endif /* GNUC >= 3.3 */ + +#ifndef __MSVCRT_VERSION__ +/* High byte is the major version, low byte is the minor. */ +# define __MSVCRT_VERSION__ 0x0600 +#endif + +#define __MINGW32_VERSION 3.10 +#define __MINGW32_MAJOR_VERSION 3 +#define __MINGW32_MINOR_VERSION 10 + +#endif /* __MINGW_H */ diff --git a/reactos/lib/mingw/include/assert.h b/reactos/lib/mingw/include/assert.h new file mode 100644 index 00000000000..9d825c9a288 --- /dev/null +++ b/reactos/lib/mingw/include/assert.h @@ -0,0 +1,51 @@ +/* + * assert.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Define the assert macro for debug output. + * + */ + +/* We should be able to include this file multiple times to allow the assert + macro to be enabled/disabled for different parts of code. So don't add a + header guard. */ + +#ifndef RC_INVOKED + +/* All the headers include this file. */ +#include <_mingw.h> + +#undef assert + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NDEBUG +/* + * If not debugging, assert does nothing. + */ +#define assert(x) ((void)0) + +#else /* debugging enabled */ + +/* + * CRTDLL nicely supplies a function which does the actual output and + * call to abort. + */ +_CRTIMP void __cdecl _assert (const char*, const char*, int) __MINGW_ATTRIB_NORETURN; + +/* + * Definition of the assert macro. + */ +#define assert(e) ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__)) + +#endif /* NDEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ diff --git a/reactos/lib/mingw/include/complex.h b/reactos/lib/mingw/include/complex.h new file mode 100644 index 00000000000..2fd73a12e2c --- /dev/null +++ b/reactos/lib/mingw/include/complex.h @@ -0,0 +1,205 @@ +/* + * complex.h + * + * This file is part of the Mingw32 package. + * + * Contributors: + * Created by Danny Smith + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef _COMPLEX_H_ +#define _COMPLEX_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \ + || !defined __STRICT_ANSI__ + +/* These macros are specified by C99 standard */ + +#ifndef __cplusplus +#define complex _Complex +#endif + +#define _Complex_I (0.0F + 1.0iF) + +/* GCC doesn't support _Imaginary type yet, so we don't + define _Imaginary_I */ + +#define I _Complex_I + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef RC_INVOKED + +double __MINGW_ATTRIB_CONST creal (double _Complex); +double __MINGW_ATTRIB_CONST cimag (double _Complex); +double __MINGW_ATTRIB_CONST carg (double _Complex); +double __MINGW_ATTRIB_CONST cabs (double _Complex); +double _Complex __MINGW_ATTRIB_CONST conj (double _Complex); +double _Complex cacos (double _Complex); +double _Complex casin (double _Complex); +double _Complex catan (double _Complex); +double _Complex ccos (double _Complex); +double _Complex csin (double _Complex); +double _Complex ctan (double _Complex); +double _Complex cacosh (double _Complex); +double _Complex casinh (double _Complex); +double _Complex catanh (double _Complex); +double _Complex ccosh (double _Complex); +double _Complex csinh (double _Complex); +double _Complex ctanh (double _Complex); +double _Complex cexp (double _Complex); +double _Complex clog (double _Complex); +double _Complex cpow (double _Complex, double _Complex); +double _Complex csqrt (double _Complex); +double _Complex __MINGW_ATTRIB_CONST cproj (double _Complex); + +float __MINGW_ATTRIB_CONST crealf (float _Complex); +float __MINGW_ATTRIB_CONST cimagf (float _Complex); +float __MINGW_ATTRIB_CONST cargf (float _Complex); +float __MINGW_ATTRIB_CONST cabsf (float _Complex); +float _Complex __MINGW_ATTRIB_CONST conjf (float _Complex); +float _Complex cacosf (float _Complex); +float _Complex casinf (float _Complex); +float _Complex catanf (float _Complex); +float _Complex ccosf (float _Complex); +float _Complex csinf (float _Complex); +float _Complex ctanf (float _Complex); +float _Complex cacoshf (float _Complex); +float _Complex casinhf (float _Complex); +float _Complex catanhf (float _Complex); +float _Complex ccoshf (float _Complex); +float _Complex csinhf (float _Complex); +float _Complex ctanhf (float _Complex); +float _Complex cexpf (float _Complex); +float _Complex clogf (float _Complex); +float _Complex cpowf (float _Complex, float _Complex); +float _Complex csqrtf (float _Complex); +float _Complex __MINGW_ATTRIB_CONST cprojf (float _Complex); + +long double __MINGW_ATTRIB_CONST creall (long double _Complex); +long double __MINGW_ATTRIB_CONST cimagl (long double _Complex); +long double __MINGW_ATTRIB_CONST cargl (long double _Complex); +long double __MINGW_ATTRIB_CONST cabsl (long double _Complex); +long double _Complex __MINGW_ATTRIB_CONST conjl (long double _Complex); +long double _Complex cacosl (long double _Complex); +long double _Complex casinl (long double _Complex); +long double _Complex catanl (long double _Complex); +long double _Complex ccosl (long double _Complex); +long double _Complex csinl (long double _Complex); +long double _Complex ctanl (long double _Complex); +long double _Complex cacoshl (long double _Complex); +long double _Complex casinhl (long double _Complex); +long double _Complex catanhl (long double _Complex); +long double _Complex ccoshl (long double _Complex); +long double _Complex csinhl (long double _Complex); +long double _Complex ctanhl (long double _Complex); +long double _Complex cexpl (long double _Complex); +long double _Complex clogl (long double _Complex); +long double _Complex cpowl (long double _Complex, long double _Complex); +long double _Complex csqrtl (long double _Complex); +long double _Complex __MINGW_ATTRIB_CONST cprojl (long double _Complex); + +#ifdef __GNUC__ + +/* double */ +__CRT_INLINE double __MINGW_ATTRIB_CONST creal (double _Complex _Z) +{ + return __real__ _Z; +} + +__CRT_INLINE double __MINGW_ATTRIB_CONST cimag (double _Complex _Z) +{ + return __imag__ _Z; +} + +__CRT_INLINE double _Complex __MINGW_ATTRIB_CONST conj (double _Complex _Z) +{ + return __extension__ ~_Z; +} + +__CRT_INLINE double __MINGW_ATTRIB_CONST carg (double _Complex _Z) +{ + double res; + __asm__ ("fpatan;" + : "=t" (res) : "0" (__real__ _Z), "u" (__imag__ _Z) : "st(1)"); + return res; +} + + +/* float */ +__CRT_INLINE float __MINGW_ATTRIB_CONST crealf (float _Complex _Z) +{ + return __real__ _Z; +} + +__CRT_INLINE float __MINGW_ATTRIB_CONST cimagf (float _Complex _Z) +{ + return __imag__ _Z; +} + +__CRT_INLINE float _Complex __MINGW_ATTRIB_CONST conjf (float _Complex _Z) +{ + return __extension__ ~_Z; +} + +__CRT_INLINE float __MINGW_ATTRIB_CONST cargf (float _Complex _Z) +{ + float res; + __asm__ ("fpatan;" + : "=t" (res) : "0" (__real__ _Z), "u" (__imag__ _Z) : "st(1)"); + return res; +} + +/* long double */ +__CRT_INLINE long double __MINGW_ATTRIB_CONST creall (long double _Complex _Z) +{ + return __real__ _Z; +} + +__CRT_INLINE long double __MINGW_ATTRIB_CONST cimagl (long double _Complex _Z) +{ + return __imag__ _Z; +} + +__CRT_INLINE long double _Complex __MINGW_ATTRIB_CONST conjl (long double _Complex _Z) +{ + return __extension__ ~_Z; +} + +__CRT_INLINE long double __MINGW_ATTRIB_CONST cargl (long double _Complex _Z) +{ + long double res; + __asm__ ("fpatan;" + : "=t" (res) : "0" (__real__ _Z), "u" (__imag__ _Z) : "st(1)"); + return res; +} + +#endif /* __GNUC__ */ + + +#endif /* RC_INVOKED */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STDC_VERSION__ >= 199901L */ + + +#endif /* _COMPLEX_H */ diff --git a/reactos/lib/mingw/include/conio.h b/reactos/lib/mingw/include/conio.h new file mode 100644 index 00000000000..a60ed85b201 --- /dev/null +++ b/reactos/lib/mingw/include/conio.h @@ -0,0 +1,53 @@ +/* + * conio.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Low level console I/O functions. Pretty please try to use the ANSI + * standard ones if you are writing new code. + * + */ + +#ifndef _CONIO_H_ +#define _CONIO_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP char* __cdecl _cgets (char*); +_CRTIMP int __cdecl _cprintf (const char*, ...); +_CRTIMP int __cdecl _cputs (const char*); +_CRTIMP int __cdecl _cscanf (char*, ...); + +_CRTIMP int __cdecl _getch (void); +_CRTIMP int __cdecl _getche (void); +_CRTIMP int __cdecl _kbhit (void); +_CRTIMP int __cdecl _putch (int); +_CRTIMP int __cdecl _ungetch (int); + + +#ifndef _NO_OLDNAMES + +_CRTIMP int __cdecl getch (void); +_CRTIMP int __cdecl getche (void); +_CRTIMP int __cdecl kbhit (void); +_CRTIMP int __cdecl putch (int); +_CRTIMP int __cdecl ungetch (int); + +#endif /* Not _NO_OLDNAMES */ + + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _CONIO_H_ */ diff --git a/reactos/lib/mingw/include/ctype.h b/reactos/lib/mingw/include/ctype.h new file mode 100644 index 00000000000..f4020afdf0e --- /dev/null +++ b/reactos/lib/mingw/include/ctype.h @@ -0,0 +1,247 @@ +/* + * ctype.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Functions for testing character types and converting characters. + * + */ + +#ifndef _CTYPE_H_ +#define _CTYPE_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define __need_wchar_t +#define __need_wint_t +#ifndef RC_INVOKED +#include +#endif /* Not RC_INVOKED */ + + +/* + * The following flags are used to tell iswctype and _isctype what character + * types you are looking for. + */ +#define _UPPER 0x0001 +#define _LOWER 0x0002 +#define _DIGIT 0x0004 +#define _SPACE 0x0008 /* HT LF VT FF CR SP */ +#define _PUNCT 0x0010 +#define _CONTROL 0x0020 +#define _BLANK 0x0040 /* this is SP only, not SP and HT as in C99 */ +#define _HEX 0x0080 +#define _LEADBYTE 0x8000 + +#define _ALPHA 0x0103 + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP int __cdecl isalnum(int); +_CRTIMP int __cdecl isalpha(int); +_CRTIMP int __cdecl iscntrl(int); +_CRTIMP int __cdecl isdigit(int); +_CRTIMP int __cdecl isgraph(int); +_CRTIMP int __cdecl islower(int); +_CRTIMP int __cdecl isprint(int); +_CRTIMP int __cdecl ispunct(int); +_CRTIMP int __cdecl isspace(int); +_CRTIMP int __cdecl isupper(int); +_CRTIMP int __cdecl isxdigit(int); + +#ifndef __STRICT_ANSI__ +_CRTIMP int __cdecl _isctype (int, int); +#endif + +/* These are the ANSI versions, with correct checking of argument */ +_CRTIMP int __cdecl tolower(int); +_CRTIMP int __cdecl toupper(int); + +/* + * NOTE: The above are not old name type wrappers, but functions exported + * explicitly by MSVCRT/CRTDLL. However, underscored versions are also + * exported. + */ +#ifndef __STRICT_ANSI__ +/* + * These are the cheap non-std versions: The return values are undefined + * if the argument is not ASCII char or is not of appropriate case + */ +_CRTIMP int __cdecl _tolower(int); +_CRTIMP int __cdecl _toupper(int); +#endif + +/* Also defined in stdlib.h */ +#ifndef MB_CUR_MAX +#ifdef __DECLSPEC_SUPPORTED +# ifdef __MSVCRT__ +# define MB_CUR_MAX __mb_cur_max + __MINGW_IMPORT int __mb_cur_max; +# else /* not __MSVCRT */ +# define MB_CUR_MAX __mb_cur_max_dll + __MINGW_IMPORT int __mb_cur_max_dll; +# endif /* not __MSVCRT */ + +#else /* ! __DECLSPEC_SUPPORTED */ +# ifdef __MSVCRT__ + extern int* _imp____mbcur_max; +# define MB_CUR_MAX (*_imp____mb_cur_max) +# else /* not __MSVCRT */ + extern int* _imp____mbcur_max_dll; +# define MB_CUR_MAX (*_imp____mb_cur_max_dll) +# endif /* not __MSVCRT */ +#endif /* __DECLSPEC_SUPPORTED */ +#endif /* MB_CUR_MAX */ + + +#ifdef __DECLSPEC_SUPPORTED +__MINGW_IMPORT unsigned short _ctype[]; +# ifdef __MSVCRT__ + __MINGW_IMPORT unsigned short* _pctype; +# else /* CRTDLL */ + __MINGW_IMPORT unsigned short* _pctype_dll; +# define _pctype _pctype_dll +# endif + +#else /* __DECLSPEC_SUPPORTED */ +extern unsigned short** _imp___ctype; +#define _ctype (*_imp___ctype) +# ifdef __MSVCRT__ + extern unsigned short** _imp___pctype; +# define _pctype (*_imp___pctype) +# else /* CRTDLL */ + extern unsigned short** _imp___pctype_dll; +# define _pctype (*_imp___pctype_dll) +# endif /* CRTDLL */ +#endif /* __DECLSPEC_SUPPORTED */ + +/* + * Use inlines here rather than macros, because macros will upset + * C++ usage (eg, ::isalnum), and so usually get undefined + * + * According to standard for SB chars, these function are defined only + * for input values representable by unsigned char or EOF. + * Thus, there is no range test. + * This reproduces behaviour of MSVCRT.dll lib implemention for SB chars. + * + * If no MB char support is needed, these can be simplified even + * more by command line define -DMB_CUR_MAX=1. The compiler will then + * optimise away the constant condition. + */ + + +#if ! (defined (__NO_INLINE__) || defined (__NO_CTYPE_INLINES) \ + || defined (__STRICT_ANSI__ )) +/* use simple lookup if SB locale, else _isctype() */ +#define __ISCTYPE(c, mask) (MB_CUR_MAX == 1 ? (_pctype[c] & mask) : _isctype(c, mask)) +__CRT_INLINE int __cdecl isalnum(int c) {return __ISCTYPE(c, (_ALPHA|_DIGIT));} +__CRT_INLINE int __cdecl isalpha(int c) {return __ISCTYPE(c, _ALPHA);} +__CRT_INLINE int __cdecl iscntrl(int c) {return __ISCTYPE(c, _CONTROL);} +__CRT_INLINE int __cdecl isdigit(int c) {return __ISCTYPE(c, _DIGIT);} +__CRT_INLINE int __cdecl isgraph(int c) {return __ISCTYPE(c, (_PUNCT|_ALPHA|_DIGIT));} +__CRT_INLINE int __cdecl islower(int c) {return __ISCTYPE(c, _LOWER);} +__CRT_INLINE int __cdecl isprint(int c) {return __ISCTYPE(c, (_BLANK|_PUNCT|_ALPHA|_DIGIT));} +__CRT_INLINE int __cdecl ispunct(int c) {return __ISCTYPE(c, _PUNCT);} +__CRT_INLINE int __cdecl isspace(int c) {return __ISCTYPE(c, _SPACE);} +__CRT_INLINE int __cdecl isupper(int c) {return __ISCTYPE(c, _UPPER);} +__CRT_INLINE int __cdecl isxdigit(int c) {return __ISCTYPE(c, _HEX);} + +/* these reproduce behaviour of lib underscored versions */ +__CRT_INLINE int __cdecl _tolower(int c) {return ( c -'A'+'a');} +__CRT_INLINE int __cdecl _toupper(int c) {return ( c -'a'+'A');} + +/* TODO? Is it worth inlining ANSI tolower, toupper? Probably only + if we only want C-locale. */ + +#endif /* _NO_CTYPE_INLINES */ + +/* Wide character equivalents */ + +#ifndef WEOF +#define WEOF (wchar_t)(0xFFFF) +#endif + +#ifndef _WCTYPE_T_DEFINED +typedef wchar_t wctype_t; +#define _WCTYPE_T_DEFINED +#endif + +_CRTIMP int __cdecl iswalnum(wint_t); +_CRTIMP int __cdecl iswalpha(wint_t); +_CRTIMP int __cdecl iswascii(wint_t); +_CRTIMP int __cdecl iswcntrl(wint_t); +_CRTIMP int __cdecl iswctype(wint_t, wctype_t); +_CRTIMP int __cdecl is_wctype(wint_t, wctype_t); /* Obsolete! */ +_CRTIMP int __cdecl iswdigit(wint_t); +_CRTIMP int __cdecl iswgraph(wint_t); +_CRTIMP int __cdecl iswlower(wint_t); +_CRTIMP int __cdecl iswprint(wint_t); +_CRTIMP int __cdecl iswpunct(wint_t); +_CRTIMP int __cdecl iswspace(wint_t); +_CRTIMP int __cdecl iswupper(wint_t); +_CRTIMP int __cdecl iswxdigit(wint_t); + +/* Older MS docs uses wchar_t for arg and return type, while newer + online MS docs say arg is wint_t and return is int. + ISO C uses wint_t for both. */ +_CRTIMP wint_t __cdecl towlower (wint_t); +_CRTIMP wint_t __cdecl towupper (wint_t); + +_CRTIMP int __cdecl isleadbyte (int); + +/* Also in wctype.h */ +#if ! (defined (__NO_INLINE__) || defined(__NO_CTYPE_INLINES) \ + || defined(__WCTYPE_INLINES_DEFINED)) +#define __WCTYPE_INLINES_DEFINED +__CRT_INLINE int __cdecl iswalnum(wint_t wc) {return (iswctype(wc,_ALPHA|_DIGIT));} +__CRT_INLINE int __cdecl iswalpha(wint_t wc) {return (iswctype(wc,_ALPHA));} +__CRT_INLINE int __cdecl iswascii(wint_t wc) {return ((wc & ~0x7F) ==0);} +__CRT_INLINE int __cdecl iswcntrl(wint_t wc) {return (iswctype(wc,_CONTROL));} +__CRT_INLINE int __cdecl iswdigit(wint_t wc) {return (iswctype(wc,_DIGIT));} +__CRT_INLINE int __cdecl iswgraph(wint_t wc) {return (iswctype(wc,_PUNCT|_ALPHA|_DIGIT));} +__CRT_INLINE int __cdecl iswlower(wint_t wc) {return (iswctype(wc,_LOWER));} +__CRT_INLINE int __cdecl iswprint(wint_t wc) {return (iswctype(wc,_BLANK|_PUNCT|_ALPHA|_DIGIT));} +__CRT_INLINE int __cdecl iswpunct(wint_t wc) {return (iswctype(wc,_PUNCT));} +__CRT_INLINE int __cdecl iswspace(wint_t wc) {return (iswctype(wc,_SPACE));} +__CRT_INLINE int __cdecl iswupper(wint_t wc) {return (iswctype(wc,_UPPER));} +__CRT_INLINE int __cdecl iswxdigit(wint_t wc) {return (iswctype(wc,_HEX));} +__CRT_INLINE int __cdecl isleadbyte(int c) {return (_pctype[(unsigned char)(c)] & _LEADBYTE);} +#endif /* !(defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED)) */ + +#ifndef __STRICT_ANSI__ +int __cdecl __isascii (int); +int __cdecl __toascii (int); +int __cdecl __iscsymf (int); /* Valid first character in C symbol */ +int __cdecl __iscsym (int); /* Valid character in C symbol (after first) */ + +#if !(defined (__NO_INLINE__) || defined (__NO_CTYPE_INLINES)) +__CRT_INLINE int __cdecl __isascii(int c) {return ((c & ~0x7F) == 0);} +__CRT_INLINE int __cdecl __toascii(int c) {return (c & 0x7F);} +__CRT_INLINE int __cdecl __iscsymf(int c) {return (isalpha(c) || (c == '_'));} +__CRT_INLINE int __cdecl __iscsym(int c) {return (isalnum(c) || (c == '_'));} +#endif /* __NO_CTYPE_INLINES */ + +#ifndef _NO_OLDNAMES +/* Not _CRTIMP */ +int __cdecl isascii (int); +int __cdecl toascii (int); +int __cdecl iscsymf (int); +int __cdecl iscsym (int); +#endif /* Not _NO_OLDNAMES */ + +#endif /* Not __STRICT_ANSI__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _CTYPE_H_ */ + diff --git a/reactos/lib/mingw/include/dir.h b/reactos/lib/mingw/include/dir.h new file mode 100644 index 00000000000..d759a0a61bb --- /dev/null +++ b/reactos/lib/mingw/include/dir.h @@ -0,0 +1,26 @@ +/* + * dir.h + * + * This file OBSOLESCENT and only provided for backward compatibility. + * Please use io.h instead. + * + * This file is part of the Mingw32 package. + * + * Contributors: + * Created by Colin Peters + * Mumit Khan + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include + diff --git a/reactos/lib/mingw/include/direct.h b/reactos/lib/mingw/include/direct.h new file mode 100644 index 00000000000..cf446627936 --- /dev/null +++ b/reactos/lib/mingw/include/direct.h @@ -0,0 +1,73 @@ +/* + * direct.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Functions for manipulating paths and directories (included from io.h) + * plus functions for setting the current drive. + * + */ +#ifndef _DIRECT_H_ +#define _DIRECT_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define __need_wchar_t +#ifndef RC_INVOKED +#include +#endif /* Not RC_INVOKED */ + +#include + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _DISKFREE_T_DEFINED +/* needed by _getdiskfree (also in dos.h) */ +struct _diskfree_t { + unsigned total_clusters; + unsigned avail_clusters; + unsigned sectors_per_cluster; + unsigned bytes_per_sector; +}; +#define _DISKFREE_T_DEFINED +#endif + +/* + * You really shouldn't be using these. Use the Win32 API functions instead. + * However, it does make it easier to port older code. + */ +_CRTIMP int __cdecl _getdrive (void); +_CRTIMP unsigned long __cdecl _getdrives(void); +_CRTIMP int __cdecl _chdrive (int); +_CRTIMP char* __cdecl _getdcwd (int, char*, int); +_CRTIMP unsigned __cdecl _getdiskfree (unsigned, struct _diskfree_t *); + +#ifndef _NO_OLDNAMES +# define diskfree_t _diskfree_t +#endif + +#ifndef _WDIRECT_DEFINED +/* wide character versions. Also in wchar.h */ +#ifdef __MSVCRT__ +_CRTIMP int __cdecl _wchdir(const wchar_t*); +_CRTIMP wchar_t* __cdecl _wgetcwd(wchar_t*, int); +_CRTIMP wchar_t* __cdecl _wgetdcwd(int, wchar_t*, int); +_CRTIMP int __cdecl _wmkdir(const wchar_t*); +_CRTIMP int __cdecl _wrmdir(const wchar_t*); +#endif /* __MSVCRT__ */ +#define _WDIRECT_DEFINED +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _DIRECT_H_ */ diff --git a/reactos/lib/mingw/include/dirent.h b/reactos/lib/mingw/include/dirent.h new file mode 100644 index 00000000000..a18cbcab902 --- /dev/null +++ b/reactos/lib/mingw/include/dirent.h @@ -0,0 +1,123 @@ +/* + * DIRENT.H (formerly DIRLIB.H) + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + */ +#ifndef _DIRENT_H_ +#define _DIRENT_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#include + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +struct dirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + char d_name[FILENAME_MAX]; /* File name. */ +}; + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + * dd_stat field is now int (was short in older versions). + */ +typedef struct +{ + /* disk transfer area for this dir */ + struct _finddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct dirent dd_dir; + + /* _findnext handle */ + long dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + char dd_name[1]; +} DIR; + +DIR* __cdecl opendir (const char*); +struct dirent* __cdecl readdir (DIR*); +int __cdecl closedir (DIR*); +void __cdecl rewinddir (DIR*); +long __cdecl telldir (DIR*); +void __cdecl seekdir (DIR*, long); + + +/* wide char versions */ + +struct _wdirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + wchar_t d_name[FILENAME_MAX]; /* File name. */ +}; + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + */ +typedef struct +{ + /* disk transfer area for this dir */ + struct _wfinddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct _wdirent dd_dir; + + /* _findnext handle */ + long dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + wchar_t dd_name[1]; +} _WDIR; + + + +_WDIR* __cdecl _wopendir (const wchar_t*); +struct _wdirent* __cdecl _wreaddir (_WDIR*); +int __cdecl _wclosedir (_WDIR*); +void __cdecl _wrewinddir (_WDIR*); +long __cdecl _wtelldir (_WDIR*); +void __cdecl _wseekdir (_WDIR*, long); + + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _DIRENT_H_ */ diff --git a/reactos/lib/mingw/include/dos.h b/reactos/lib/mingw/include/dos.h new file mode 100644 index 00000000000..b3aa9aeffd8 --- /dev/null +++ b/reactos/lib/mingw/include/dos.h @@ -0,0 +1,89 @@ +/* + * dos.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * DOS-specific functions and structures. + * + */ + +#ifndef _DOS_H_ +#define _DOS_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define __need_wchar_t +#ifndef RC_INVOKED +#include +#endif /* Not RC_INVOKED */ + +/* For DOS file attributes */ +#include + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __MSVCRT__ /* these are in CRTDLL, but not MSVCRT */ +#ifndef __DECLSPEC_SUPPORTED +extern unsigned int *_imp___basemajor_dll; +extern unsigned int *_imp___baseminor_dll; +extern unsigned int *_imp___baseversion_dll; +extern unsigned int *_imp___osmajor_dll; +extern unsigned int *_imp___osminor_dll; +extern unsigned int *_imp___osmode_dll; + +#define _basemajor (*_imp___basemajor_dll) +#define _baseminor (*_imp___baseminor_dll) +#define _baseversion (*_imp___baseversion_dll) +#define _osmajor (*_imp___osmajor_dll) +#define _osminor (*_imp___osminor_dll) +#define _osmode (*_imp___osmode_dll) + +#else /* __DECLSPEC_SUPPORTED */ + +__MINGW_IMPORT unsigned int _basemajor_dll; +__MINGW_IMPORT unsigned int _baseminor_dll; +__MINGW_IMPORT unsigned int _baseversion_dll; +__MINGW_IMPORT unsigned int _osmajor_dll; +__MINGW_IMPORT unsigned int _osminor_dll; +__MINGW_IMPORT unsigned int _osmode_dll; + +#define _basemajor _basemajor_dll +#define _baseminor _baseminor_dll +#define _baseversion _baseversion_dll +#define _osmajor _osmajor_dll +#define _osminor _osminor_dll +#define _osmode _osmode_dll + +#endif /* __DECLSPEC_SUPPORTED */ +#endif /* ! __MSVCRT__ */ + +#ifndef _DISKFREE_T_DEFINED +/* needed by _getdiskfree (also in direct.h) */ +struct _diskfree_t { + unsigned total_clusters; + unsigned avail_clusters; + unsigned sectors_per_cluster; + unsigned bytes_per_sector; +}; +#define _DISKFREE_T_DEFINED +#endif + +_CRTIMP unsigned __cdecl _getdiskfree (unsigned, struct _diskfree_t *); + +#ifndef _NO_OLDNAMES +# define diskfree_t _diskfree_t +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _DOS_H_ */ diff --git a/reactos/lib/mingw/include/errno.h b/reactos/lib/mingw/include/errno.h new file mode 100644 index 00000000000..f9f709c6584 --- /dev/null +++ b/reactos/lib/mingw/include/errno.h @@ -0,0 +1,101 @@ +/* + * errno.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Error numbers and access to error reporting. + * + */ + +#ifndef _ERRNO_H_ +#define _ERRNO_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* + * Error numbers. + * TODO: Can't be sure of some of these assignments, I guessed from the + * names given by strerror and the defines in the Cygnus errno.h. A lot + * of the names from the Cygnus errno.h are not represented, and a few + * of the descriptions returned by strerror do not obviously match + * their error naming. + */ +#define EPERM 1 /* Operation not permitted */ +#define ENOFILE 2 /* No such file or directory */ +#define ENOENT 2 +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted function call */ +#define EIO 5 /* Input/output error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file descriptor */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Resource temporarily unavailable */ +#define ENOMEM 12 /* Not enough space */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +/* 15 - Unknown Error */ +#define EBUSY 16 /* strerror reports "Resource device" */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Improper link (cross-device link?) */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate I/O control operation */ +/* 26 - Unknown Error */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Invalid seek (seek on a pipe?) */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Domain error (math functions) */ +#define ERANGE 34 /* Result too large (possibly too small) */ +/* 35 - Unknown Error */ +#define EDEADLOCK 36 /* Resource deadlock avoided (non-Cyg) */ +#define EDEADLK 36 +/* 37 - Unknown Error */ +#define ENAMETOOLONG 38 /* Filename too long (91 in Cyg?) */ +#define ENOLCK 39 /* No locks available (46 in Cyg?) */ +#define ENOSYS 40 /* Function not implemented (88 in Cyg?) */ +#define ENOTEMPTY 41 /* Directory not empty (90 in Cyg?) */ +#define EILSEQ 42 /* Illegal byte sequence */ + +/* + * NOTE: ENAMETOOLONG and ENOTEMPTY conflict with definitions in the + * sockets.h header provided with windows32api-0.1.2. + * You should go and put an #if 0 ... #endif around the whole block + * of errors (look at the comment above them). + */ + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Definitions of errno. For _doserrno, sys_nerr and * sys_errlist, see + * stdlib.h. + */ +#ifdef _UWIN +#undef errno +extern int errno; +#else +_CRTIMP int* __cdecl _errno(void); +#define errno (*_errno()) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _ERRNO_H_ */ diff --git a/reactos/lib/mingw/include/excpt.h b/reactos/lib/mingw/include/excpt.h new file mode 100644 index 00000000000..d46a1d93c7a --- /dev/null +++ b/reactos/lib/mingw/include/excpt.h @@ -0,0 +1,102 @@ +/* + * excpt.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Support for operating system level structured exception handling. + * + * NOTE: This is very preliminary stuff. I am also pretty sure it is + * completely Intel specific. + * + */ + +#ifndef _EXCPT_H_ +#define _EXCPT_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#include + +/* + * NOTE: The constants structs and typedefs below should be defined in the + * Win32 API headers. + */ +#define EH_NONCONTINUABLE 0x01 +#define EH_UNWINDING 0x02 +#define EH_EXIT_UNWIND 0x04 +#define EH_STACK_INVALID 0x08 +#define EH_NESTED_CALL 0x10 + +#ifndef RC_INVOKED + +typedef enum { + ExceptionContinueExecution, + ExceptionContinueSearch, + ExceptionNestedException, + ExceptionCollidedUnwind +} EXCEPTION_DISPOSITION; + + +/* + * End of stuff that should be in the Win32 API files. + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The type of function that is expected as an exception handler to be + * installed with _try1. + */ +typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER) + (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*); + +/* + * This is not entirely necessary, but it is the structure installed by + * the _try1 primitive below. + */ +typedef struct _EXCEPTION_REGISTRATION +{ + struct _EXCEPTION_REGISTRATION* prev; + PEXCEPTION_HANDLER handler; +} EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION; + +typedef EXCEPTION_REGISTRATION EXCEPTION_REGISTRATION_RECORD; +typedef PEXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION_RECORD; + +/* + * A macro which installs the supplied exception handler. + * Push the pointer to the new handler onto the stack, + * then push the pointer to the old registration structure (at fs:0) + * onto the stack, then put a pointer to the new registration + * structure (i.e. the current stack pointer) at fs:0. + */ +#define __try1(pHandler) \ + __asm__ ("pushl %0;pushl %%fs:0;movl %%esp,%%fs:0;" : : "g" (pHandler)); + +/* + * A macro which (despite its name) *removes* an installed + * exception handler. Should be used only in conjunction with the above + * install routine __try1. + * Move the pointer to the old reg. struct (at the current stack + * position) to fs:0, replacing the pointer we installed above, + * then add 8 to the stack pointer to get rid of the space we + * used when we pushed on our new reg. struct above. Notice that + * the stack must be in the exact state at this point that it was + * after we did _try1 or this will smash things. + */ +#define __except1 \ + __asm__ ("movl (%%esp),%%eax;movl %%eax,%%fs:0;addl $8,%%esp;" \ + : : : "%eax"); + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* _EXCPT_H_ not defined */ diff --git a/reactos/lib/mingw/include/fcntl.h b/reactos/lib/mingw/include/fcntl.h new file mode 100644 index 00000000000..e62d15950fc --- /dev/null +++ b/reactos/lib/mingw/include/fcntl.h @@ -0,0 +1,69 @@ +/* + * fcntl.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Access constants for _open. Note that the permissions constants are + * in sys/stat.h (ick). + * + */ +#ifndef _FCNTL_H_ +#define _FCNTL_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* + * It appears that fcntl.h should include io.h for compatibility... + */ +#include + +/* Specifiy one of these flags to define the access mode. */ +#define _O_RDONLY 0 +#define _O_WRONLY 1 +#define _O_RDWR 2 + +/* Mask for access mode bits in the _open flags. */ +#define _O_ACCMODE (_O_RDONLY|_O_WRONLY|_O_RDWR) + +#define _O_APPEND 0x0008 /* Writes will add to the end of the file. */ + +#define _O_RANDOM 0x0010 +#define _O_SEQUENTIAL 0x0020 +#define _O_TEMPORARY 0x0040 /* Make the file dissappear after closing. + * WARNING: Even if not created by _open! */ +#define _O_NOINHERIT 0x0080 + +#define _O_CREAT 0x0100 /* Create the file if it does not exist. */ +#define _O_TRUNC 0x0200 /* Truncate the file if it does exist. */ +#define _O_EXCL 0x0400 /* Open only if the file does not exist. */ + +#define _O_SHORT_LIVED 0x1000 + +/* NOTE: Text is the default even if the given _O_TEXT bit is not on. */ +#define _O_TEXT 0x4000 /* CR-LF in file becomes LF in memory. */ +#define _O_BINARY 0x8000 /* Input and output is not translated. */ +#define _O_RAW _O_BINARY + +#ifndef _NO_OLDNAMES + +/* POSIX/Non-ANSI names for increased portability */ +#define O_RDONLY _O_RDONLY +#define O_WRONLY _O_WRONLY +#define O_RDWR _O_RDWR +#define O_ACCMODE _O_ACCMODE +#define O_APPEND _O_APPEND +#define O_CREAT _O_CREAT +#define O_TRUNC _O_TRUNC +#define O_EXCL _O_EXCL +#define O_TEXT _O_TEXT +#define O_BINARY _O_BINARY +#define O_TEMPORARY _O_TEMPORARY +#define O_NOINHERIT _O_NOINHERIT +#define O_SEQUENTIAL _O_SEQUENTIAL +#define O_RANDOM _O_RANDOM + +#endif /* Not _NO_OLDNAMES */ + +#endif /* Not _FCNTL_H_ */ diff --git a/reactos/lib/mingw/include/fenv.h b/reactos/lib/mingw/include/fenv.h new file mode 100644 index 00000000000..5a2270289e6 --- /dev/null +++ b/reactos/lib/mingw/include/fenv.h @@ -0,0 +1,105 @@ +#ifndef _FENV_H_ +#define _FENV_H_ + +/* FPU status word exception flags */ +#define FE_INVALID 0x01 +#define FE_DENORMAL 0x02 +#define FE_DIVBYZERO 0x04 +#define FE_OVERFLOW 0x08 +#define FE_UNDERFLOW 0x10 +#define FE_INEXACT 0x20 +#define FE_ALL_EXCEPT (FE_INVALID | FE_DENORMAL | FE_DIVBYZERO \ + | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +/* FPU control word rounding flags */ +#define FE_TONEAREST 0x0000 +#define FE_DOWNWARD 0x0400 +#define FE_UPWARD 0x0800 +#define FE_TOWARDZERO 0x0c00 + +/* The MXCSR exception flags are the same as the + FE flags. */ +#define __MXCSR_EXCEPT_FLAG_SHIFT 0 + +/* How much to shift FE status word exception flags + to get the MXCSR exeptions masks, */ +#define __MXCSR_EXCEPT_MASK_SHIFT 7 + +/* How much to shift FE control word rounding flags + to get MXCSR rounding flags, */ +#define __MXCSR_ROUND_FLAG_SHIFT 3 + +#ifndef RC_INVOKED +/* + For now, support only for the basic abstraction of flags that are + either set or clear. fexcept_t could be structure that holds more + info about the fp environment. +*/ +typedef unsigned short fexcept_t; + +/* This 32-byte struct represents the entire floating point + environment as stored by fnstenv or fstenv, augmented by + the contents of the MXCSR register, as stored by stmxcsr + (if CPU supports it). */ +typedef struct +{ + unsigned short __control_word; + unsigned short __unused0; + unsigned short __status_word; + unsigned short __unused1; + unsigned short __tag_word; + unsigned short __unused2; + unsigned int __ip_offset; /* instruction pointer offset */ + unsigned short __ip_selector; + unsigned short __opcode; + unsigned int __data_offset; + unsigned short __data_selector; + unsigned short __unused3; + unsigned int __mxcsr; /* contents of the MXCSR register */ +} fenv_t; + + +/*The C99 standard (7.6.9) allows us to define implementation-specific macros for + different fp environments */ + +/* The default Intel x87 floating point environment (64-bit mantissa) */ +#define FE_PC64_ENV ((const fenv_t *)-1) + +/* The floating point environment set by MSVCRT _fpreset (53-bit mantissa) */ +#define FE_PC53_ENV ((const fenv_t *)-2) + +/* The FE_DFL_ENV macro is required by standard. + fesetenv will use the environment set at app startup.*/ +#define FE_DFL_ENV ((const fenv_t *) 0) + +#ifdef __cplusplus +extern "C" { +#endif + +/*TODO: Some of these could be inlined */ +/* 7.6.2 Exception */ + +extern int __cdecl feclearexcept (int); +extern int __cdecl fegetexceptflag (fexcept_t * flagp, int excepts); +extern int __cdecl feraiseexcept (int excepts ); +extern int __cdecl fesetexceptflag (const fexcept_t *, int); +extern int __cdecl fetestexcept (int excepts); + +/* 7.6.3 Rounding */ + +extern int __cdecl fegetround (void); +extern int __cdecl fesetround (int mode); + +/* 7.6.4 Environment */ + +extern int __cdecl fegetenv (fenv_t * envp); +extern int __cdecl fesetenv (const fenv_t * ); +extern int __cdecl feupdateenv (const fenv_t *); +extern int __cdecl feholdexcept (fenv_t *); + +#ifdef __cplusplus +} +#endif +#endif /* Not RC_INVOKED */ + +#endif /* ndef _FENV_H */ diff --git a/reactos/lib/mingw/include/float.h b/reactos/lib/mingw/include/float.h new file mode 100644 index 00000000000..53bfb34dbdf --- /dev/null +++ b/reactos/lib/mingw/include/float.h @@ -0,0 +1,152 @@ +/* + * float.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Constants related to floating point arithmetic. + * + * Also included here are some non-ANSI bits for accessing the floating + * point controller. + * + * NOTE: GCC provides float.h, but it doesn't include the non-standard + * stuff for accessing the fp controller. We include_next the + * GCC-supplied header and just define the MS-specific extensions + * here. + * + */ + +#include_next + +#ifndef _MINGW_FLOAT_H_ +#define _MINGW_FLOAT_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* + * Functions and definitions for controlling the FPU. + */ +#ifndef __STRICT_ANSI__ + +/* TODO: These constants are only valid for x86 machines */ + +/* Control word masks for unMask */ +#define _MCW_EM 0x0008001F /* Error masks */ +#define _MCW_IC 0x00040000 /* Infinity */ +#define _MCW_RC 0x00000300 /* Rounding */ +#define _MCW_PC 0x00030000 /* Precision */ + +/* Control word values for unNew (use with related unMask above) */ +#define _EM_INVALID 0x00000010 +#define _EM_DENORMAL 0x00080000 +#define _EM_ZERODIVIDE 0x00000008 +#define _EM_OVERFLOW 0x00000004 +#define _EM_UNDERFLOW 0x00000002 +#define _EM_INEXACT 0x00000001 +#define _IC_AFFINE 0x00040000 +#define _IC_PROJECTIVE 0x00000000 +#define _RC_CHOP 0x00000300 +#define _RC_UP 0x00000200 +#define _RC_DOWN 0x00000100 +#define _RC_NEAR 0x00000000 +#define _PC_24 0x00020000 +#define _PC_53 0x00010000 +#define _PC_64 0x00000000 + +/* These are also defined in Mingw math.h, needed to work around + GCC build issues. */ +/* Return values for fpclass. */ +#ifndef __MINGW_FPCLASS_DEFINED +#define __MINGW_FPCLASS_DEFINED 1 +#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ +#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ +#define _FPCLASS_NINF 0x0004 /* Negative Infinity */ +#define _FPCLASS_NN 0x0008 /* Negative Normal */ +#define _FPCLASS_ND 0x0010 /* Negative Denormal */ +#define _FPCLASS_NZ 0x0020 /* Negative Zero */ +#define _FPCLASS_PZ 0x0040 /* Positive Zero */ +#define _FPCLASS_PD 0x0080 /* Positive Denormal */ +#define _FPCLASS_PN 0x0100 /* Positive Normal */ +#define _FPCLASS_PINF 0x0200 /* Positive Infinity */ +#endif /* __MINGW_FPCLASS_DEFINED */ + +/* invalid subconditions (_SW_INVALID also set) */ +#define _SW_UNEMULATED 0x0040 /* unemulated instruction */ +#define _SW_SQRTNEG 0x0080 /* square root of a neg number */ +#define _SW_STACKOVERFLOW 0x0200 /* FP stack overflow */ +#define _SW_STACKUNDERFLOW 0x0400 /* FP stack underflow */ + +/* Floating point error signals and return codes */ +#define _FPE_INVALID 0x81 +#define _FPE_DENORMAL 0x82 +#define _FPE_ZERODIVIDE 0x83 +#define _FPE_OVERFLOW 0x84 +#define _FPE_UNDERFLOW 0x85 +#define _FPE_INEXACT 0x86 +#define _FPE_UNEMULATED 0x87 +#define _FPE_SQRTNEG 0x88 +#define _FPE_STACKOVERFLOW 0x8a +#define _FPE_STACKUNDERFLOW 0x8b +#define _FPE_EXPLICITGEN 0x8c /* raise( SIGFPE ); */ + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +/* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask), + * i.e. change the bits in unMask to have the values they have in unNew, + * leaving other bits unchanged. */ +_CRTIMP unsigned int __cdecl _controlfp (unsigned int unNew, unsigned int unMask); +_CRTIMP unsigned int __cdecl _control87 (unsigned int unNew, unsigned int unMask); + + +_CRTIMP unsigned int __cdecl _clearfp (void); /* Clear the FPU status word */ +_CRTIMP unsigned int __cdecl _statusfp (void); /* Report the FPU status word */ +#define _clear87 _clearfp +#define _status87 _statusfp + + +/* + MSVCRT.dll _fpreset initializes the control register to 0x27f, + the status register to zero and the tag word to 0FFFFh. + This differs from asm instruction finit/fninit which set control + word to 0x37f (64 bit mantissa precison rather than 53 bit). + By default, the mingw version of _fpreset sets fp control as + per fninit. To use the MSVCRT.dll _fpreset, include CRT_fp8.o when + building your application. +*/ +void __cdecl _fpreset (void); +void __cdecl fpreset (void); + +/* Global 'variable' for the current floating point error code. */ +_CRTIMP int * __cdecl __fpecode(void); +#define _fpecode (*(__fpecode())) + +/* + * IEEE recommended functions. MS puts them in float.h + * but they really belong in math.h. + */ + +_CRTIMP double __cdecl _chgsign (double); +_CRTIMP double __cdecl _copysign (double, double); +_CRTIMP double __cdecl _logb (double); +_CRTIMP double __cdecl _nextafter (double, double); +_CRTIMP double __cdecl _scalb (double, long); + +_CRTIMP int __cdecl _finite (double); +_CRTIMP int __cdecl _fpclass (double); +_CRTIMP int __cdecl _isnan (double); + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not __STRICT_ANSI__ */ + +#endif /* _FLOAT_H_ */ + diff --git a/reactos/lib/mingw/include/getopt.h b/reactos/lib/mingw/include/getopt.h new file mode 100644 index 00000000000..6b6f643b7d4 --- /dev/null +++ b/reactos/lib/mingw/include/getopt.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1987, 1993, 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __GETOPT_H__ +#define __GETOPT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int opterr; /* if error message should be printed */ +extern int optind; /* index into parent argv vector */ +extern int optopt; /* character checked for validity */ +extern int optreset; /* reset getopt */ +extern char *optarg; /* argument associated with option */ + +int getopt (int, char * const *, const char *); + +#ifdef __cplusplus +} +#endif + +#endif /* __GETOPT_H__ */ + +#ifndef __UNISTD_GETOPT__ +#ifndef __GETOPT_LONG_H__ +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; + +int getopt_long (int, char *const *, const char *, const struct option *, int *); +#ifndef HAVE_DECL_GETOPT +#define HAVE_DECL_GETOPT 1 +#endif + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#ifdef __cplusplus +} +#endif + +#endif /* __GETOPT_LONG_H__ */ +#endif /* __UNISTD_GETOPT__ */ diff --git a/reactos/lib/mingw/include/inttypes.h b/reactos/lib/mingw/include/inttypes.h new file mode 100644 index 00000000000..a2042614ab5 --- /dev/null +++ b/reactos/lib/mingw/include/inttypes.h @@ -0,0 +1,278 @@ +/* 7.8 Format conversion of integer types */ + +#ifndef _INTTYPES_H_ +#define _INTTYPES_H_ + +#include <_mingw.h> +#include +#define __need_wchar_t +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + intmax_t quot; + intmax_t rem; + } imaxdiv_t; + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) + +/* 7.8.1 Macros for format specifiers + * + * MS runtime does not yet understand C9x standard "ll" + * length specifier. It appears to treat "ll" as "l". + * The non-standard I64 length specifier causes warning in GCC, + * but understood by MS runtime functions. + */ + +/* fprintf macros for signed types */ +#define PRId8 "d" +#define PRId16 "d" +#define PRId32 "d" +#define PRId64 "I64d" + +#define PRIdLEAST8 "d" +#define PRIdLEAST16 "d" +#define PRIdLEAST32 "d" +#define PRIdLEAST64 "I64d" + +#define PRIdFAST8 "d" +#define PRIdFAST16 "d" +#define PRIdFAST32 "d" +#define PRIdFAST64 "I64d" + +#define PRIdMAX "I64d" +#define PRIdPTR "d" + +#define PRIi8 "i" +#define PRIi16 "i" +#define PRIi32 "i" +#define PRIi64 "I64i" + +#define PRIiLEAST8 "i" +#define PRIiLEAST16 "i" +#define PRIiLEAST32 "i" +#define PRIiLEAST64 "I64i" + +#define PRIiFAST8 "i" +#define PRIiFAST16 "i" +#define PRIiFAST32 "i" +#define PRIiFAST64 "I64i" + +#define PRIiMAX "I64i" +#define PRIiPTR "i" + +#define PRIo8 "o" +#define PRIo16 "o" +#define PRIo32 "o" +#define PRIo64 "I64o" + +#define PRIoLEAST8 "o" +#define PRIoLEAST16 "o" +#define PRIoLEAST32 "o" +#define PRIoLEAST64 "I64o" + +#define PRIoFAST8 "o" +#define PRIoFAST16 "o" +#define PRIoFAST32 "o" +#define PRIoFAST64 "I64o" + +#define PRIoMAX "I64o" + +#define PRIoPTR "o" + +/* fprintf macros for unsigned types */ +#define PRIu8 "u" +#define PRIu16 "u" +#define PRIu32 "u" +#define PRIu64 "I64u" + + +#define PRIuLEAST8 "u" +#define PRIuLEAST16 "u" +#define PRIuLEAST32 "u" +#define PRIuLEAST64 "I64u" + +#define PRIuFAST8 "u" +#define PRIuFAST16 "u" +#define PRIuFAST32 "u" +#define PRIuFAST64 "I64u" + +#define PRIuMAX "I64u" +#define PRIuPTR "u" + +#define PRIx8 "x" +#define PRIx16 "x" +#define PRIx32 "x" +#define PRIx64 "I64x" + +#define PRIxLEAST8 "x" +#define PRIxLEAST16 "x" +#define PRIxLEAST32 "x" +#define PRIxLEAST64 "I64x" + +#define PRIxFAST8 "x" +#define PRIxFAST16 "x" +#define PRIxFAST32 "x" +#define PRIxFAST64 "I64x" + +#define PRIxMAX "I64x" +#define PRIxPTR "x" + +#define PRIX8 "X" +#define PRIX16 "X" +#define PRIX32 "X" +#define PRIX64 "I64X" + +#define PRIXLEAST8 "X" +#define PRIXLEAST16 "X" +#define PRIXLEAST32 "X" +#define PRIXLEAST64 "I64X" + +#define PRIXFAST8 "X" +#define PRIXFAST16 "X" +#define PRIXFAST32 "X" +#define PRIXFAST64 "I64X" + +#define PRIXMAX "I64X" +#define PRIXPTR "X" + +/* + * fscanf macros for signed int types + * NOTE: if 32-bit int is used for int_fast8_t and int_fast16_t + * (see stdint.h, 7.18.1.3), FAST8 and FAST16 should have + * no length identifiers + */ + +#define SCNd16 "hd" +#define SCNd32 "d" +#define SCNd64 "I64d" + +#define SCNdLEAST16 "hd" +#define SCNdLEAST32 "d" +#define SCNdLEAST64 "I64d" + +#define SCNdFAST16 "hd" +#define SCNdFAST32 "d" +#define SCNdFAST64 "I64d" + +#define SCNdMAX "I64d" +#define SCNdPTR "d" + +#define SCNi16 "hi" +#define SCNi32 "i" +#define SCNi64 "I64i" + +#define SCNiLEAST16 "hi" +#define SCNiLEAST32 "i" +#define SCNiLEAST64 "I64i" + +#define SCNiFAST16 "hi" +#define SCNiFAST32 "i" +#define SCNiFAST64 "I64i" + +#define SCNiMAX "I64i" +#define SCNiPTR "i" + +#define SCNo16 "ho" +#define SCNo32 "o" +#define SCNo64 "I64o" + +#define SCNoLEAST16 "ho" +#define SCNoLEAST32 "o" +#define SCNoLEAST64 "I64o" + +#define SCNoFAST16 "ho" +#define SCNoFAST32 "o" +#define SCNoFAST64 "I64o" + +#define SCNoMAX "I64o" +#define SCNoPTR "o" + +#define SCNx16 "hx" +#define SCNx32 "x" +#define SCNx64 "I64x" + +#define SCNxLEAST16 "hx" +#define SCNxLEAST32 "x" +#define SCNxLEAST64 "I64x" + +#define SCNxFAST16 "hx" +#define SCNxFAST32 "x" +#define SCNxFAST64 "I64x" + +#define SCNxMAX "I64x" +#define SCNxPTR "x" + + +/* fscanf macros for unsigned int types */ + +#define SCNu16 "hu" +#define SCNu32 "u" +#define SCNu64 "I64u" + +#define SCNuLEAST16 "hu" +#define SCNuLEAST32 "u" +#define SCNuLEAST64 "I64u" + +#define SCNuFAST16 "hu" +#define SCNuFAST32 "u" +#define SCNuFAST64 "I64u" + +#define SCNuMAX "I64u" +#define SCNuPTR "u" + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +/* + * no length modifier for char types prior to C9x + * MS runtime scanf appears to treat "hh" as "h" + */ + +/* signed char */ +#define SCNd8 "hhd" +#define SCNdLEAST8 "hhd" +#define SCNdFAST8 "hhd" + +#define SCNi8 "hhi" +#define SCNiLEAST8 "hhi" +#define SCNiFAST8 "hhi" + +#define SCNo8 "hho" +#define SCNoLEAST8 "hho" +#define SCNoFAST8 "hho" + +#define SCNx8 "hhx" +#define SCNxLEAST8 "hhx" +#define SCNxFAST8 "hhx" + +/* unsigned char */ +#define SCNu8 "hhu" +#define SCNuLEAST8 "hhu" +#define SCNuFAST8 "hhu" +#endif /* __STDC_VERSION__ >= 199901 */ + +#endif /* !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) */ + +__CRT_INLINE intmax_t __cdecl imaxabs (intmax_t j) + {return (j >= 0 ? j : -j);} +imaxdiv_t __cdecl imaxdiv (intmax_t numer, intmax_t denom); + +/* 7.8.2 Conversion functions for greatest-width integer types */ + +intmax_t __cdecl strtoimax (const char* __restrict__ nptr, + char** __restrict__ endptr, int base); +uintmax_t __cdecl strtoumax (const char* __restrict__ nptr, + char** __restrict__ endptr, int base); + +intmax_t __cdecl wcstoimax (const wchar_t* __restrict__ nptr, + wchar_t** __restrict__ endptr, int base); +uintmax_t __cdecl wcstoumax (const wchar_t* __restrict__ nptr, + wchar_t** __restrict__ endptr, int base); + +#ifdef __cplusplus +} +#endif + +#endif /* ndef _INTTYPES_H */ diff --git a/reactos/lib/mingw/include/io.h b/reactos/lib/mingw/include/io.h new file mode 100644 index 00000000000..66d59b5a8d9 --- /dev/null +++ b/reactos/lib/mingw/include/io.h @@ -0,0 +1,313 @@ +/* + * io.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * System level I/O functions and types. + * + */ +#ifndef _IO_H_ +#define _IO_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* MSVC's io.h contains the stuff from dir.h, so I will too. + * NOTE: This also defines off_t, the file offset type, through + * an inclusion of sys/types.h */ + +#include /* To get time_t. */ +#include /* For intptr_t. */ + +/* + * Attributes of files as returned by _findfirst et al. + */ +#define _A_NORMAL 0x00000000 +#define _A_RDONLY 0x00000001 +#define _A_HIDDEN 0x00000002 +#define _A_SYSTEM 0x00000004 +#define _A_VOLID 0x00000008 +#define _A_SUBDIR 0x00000010 +#define _A_ARCH 0x00000020 + + +#ifndef RC_INVOKED + +#ifndef _FSIZE_T_DEFINED +typedef unsigned long _fsize_t; +#define _FSIZE_T_DEFINED +#endif + +/* + * The maximum length of a file name. You should use GetVolumeInformation + * instead of this constant. But hey, this works. + * Also defined in stdio.h. + */ +#ifndef FILENAME_MAX +#define FILENAME_MAX (260) +#endif + +/* + * The following structure is filled in by _findfirst or _findnext when + * they succeed in finding a match. + */ +struct _finddata_t +{ + unsigned attrib; /* Attributes, see constants above. */ + time_t time_create; + time_t time_access; /* always midnight local time */ + time_t time_write; + _fsize_t size; + char name[FILENAME_MAX]; /* may include spaces. */ +}; + +struct _finddatai64_t { + unsigned attrib; + time_t time_create; + time_t time_access; + time_t time_write; + __int64 size; + char name[FILENAME_MAX]; +}; + +struct __finddata64_t { + unsigned attrib; + __time64_t time_create; + __time64_t time_access; + __time64_t time_write; + _fsize_t size; + char name[FILENAME_MAX]; +}; + +#ifndef _WFINDDATA_T_DEFINED +struct _wfinddata_t { + unsigned attrib; + time_t time_create; /* -1 for FAT file systems */ + time_t time_access; /* -1 for FAT file systems */ + time_t time_write; + _fsize_t size; + wchar_t name[FILENAME_MAX]; /* may include spaces. */ +}; + +struct _wfinddatai64_t { + unsigned attrib; + time_t time_create; + time_t time_access; + time_t time_write; + __int64 size; + wchar_t name[FILENAME_MAX]; +}; + +struct __wfinddata64_t { + unsigned attrib; + __time64_t time_create; + __time64_t time_access; + __time64_t time_write; + _fsize_t size; + wchar_t name[FILENAME_MAX]; +}; + +#define _WFINDDATA_T_DEFINED +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Functions for searching for files. _findfirst returns -1 if no match + * is found. Otherwise it returns a handle to be used in _findnext and + * _findclose calls. _findnext also returns -1 if no match could be found, + * and 0 if a match was found. Call _findclose when you are finished. + */ +/* FIXME: Should these all use intptr_t, as per recent MSDN docs? */ +_CRTIMP long __cdecl _findfirst (const char*, struct _finddata_t*); +_CRTIMP int __cdecl _findnext (long, struct _finddata_t*); +_CRTIMP int __cdecl _findclose (long); + +_CRTIMP int __cdecl _chdir (const char*); +_CRTIMP char* __cdecl _getcwd (char*, int); +_CRTIMP int __cdecl _mkdir (const char*); +_CRTIMP char* __cdecl _mktemp (char*); +_CRTIMP int __cdecl _rmdir (const char*); +_CRTIMP int __cdecl _chmod (const char*, int); + +#ifdef __MSVCRT__ +_CRTIMP __int64 __cdecl _filelengthi64(int); +_CRTIMP long __cdecl _findfirsti64(const char*, struct _finddatai64_t*); +_CRTIMP int __cdecl _findnexti64(long, struct _finddatai64_t*); +_CRTIMP __int64 __cdecl _lseeki64(int, __int64, int); +_CRTIMP __int64 __cdecl _telli64(int); +/* These require newer versions of msvcrt.dll (6.1 or higher). */ +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP intptr_t __cdecl _findfirst64(const char*, struct __finddata64_t*); +_CRTIMP intptr_t __cdecl _findnext64(intptr_t, struct __finddata64_t*); +#endif /* __MSVCRT_VERSION__ >= 0x0601 */ + +#ifndef __NO_MINGW_LFS +__CRT_INLINE off64_t lseek64 (int fd, off64_t offset, int whence) +{ + return _lseeki64(fd, (__int64) offset, whence); +} +#endif + +#endif /* __MSVCRT__ */ + +#ifndef _NO_OLDNAMES + +#ifndef _UWIN +_CRTIMP int __cdecl chdir (const char*); +_CRTIMP char* __cdecl getcwd (char*, int); +_CRTIMP int __cdecl mkdir (const char*); +_CRTIMP char* __cdecl mktemp (char*); +_CRTIMP int __cdecl rmdir (const char*); +_CRTIMP int __cdecl chmod (const char*, int); +#endif /* _UWIN */ + +#endif /* Not _NO_OLDNAMES */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +/* TODO: Maximum number of open handles has not been tested, I just set + * it the same as FOPEN_MAX. */ +#define HANDLE_MAX FOPEN_MAX + +/* Some defines for _access nAccessMode (MS doesn't define them, but + * it doesn't seem to hurt to add them). */ +#define F_OK 0 /* Check for file existence */ +#define X_OK 1 /* Check for execute permission. */ +#define W_OK 2 /* Check for write permission */ +#define R_OK 4 /* Check for read permission */ + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP int __cdecl _access (const char*, int); +_CRTIMP int __cdecl _chsize (int, long); +_CRTIMP int __cdecl _close (int); +_CRTIMP int __cdecl _commit(int); + +/* NOTE: The only significant bit in unPermissions appears to be bit 7 (0x80), + * the "owner write permission" bit (on FAT). */ +_CRTIMP int __cdecl _creat (const char*, int); + +_CRTIMP int __cdecl _dup (int); +_CRTIMP int __cdecl _dup2 (int, int); +_CRTIMP long __cdecl _filelength (int); +_CRTIMP long __cdecl _get_osfhandle (int); +_CRTIMP int __cdecl _isatty (int); + +/* In a very odd turn of events this function is excluded from those + * files which define _STREAM_COMPAT. This is required in order to + * build GNU libio because of a conflict with _eof in streambuf.h + * line 107. Actually I might just be able to change the name of + * the enum member in streambuf.h... we'll see. TODO */ +#ifndef _STREAM_COMPAT +_CRTIMP int __cdecl _eof (int); +#endif + +/* LK_... locking commands defined in sys/locking.h. */ +_CRTIMP int __cdecl _locking (int, int, long); + +_CRTIMP long __cdecl _lseek (int, long, int); + +/* Optional third argument is unsigned unPermissions. */ +_CRTIMP int __cdecl _open (const char*, int, ...); + +_CRTIMP int __cdecl _open_osfhandle (long, int); +_CRTIMP int __cdecl _pipe (int *, unsigned int, int); +_CRTIMP int __cdecl _read (int, void*, unsigned int); +_CRTIMP int __cdecl _setmode (int, int); + +/* SH_... flags for nShFlags defined in share.h + * Optional fourth argument is unsigned unPermissions */ +_CRTIMP int __cdecl _sopen (const char*, int, int, ...); + +_CRTIMP long __cdecl _tell (int); +/* Should umask be in sys/stat.h and/or sys/types.h instead? */ +_CRTIMP int __cdecl _umask (int); +_CRTIMP int __cdecl _unlink (const char*); +_CRTIMP int __cdecl _write (int, const void*, unsigned int); + +/* Wide character versions. Also declared in wchar.h. */ +/* Not in crtdll.dll */ +#if !defined (_WIO_DEFINED) +#if defined (__MSVCRT__) +_CRTIMP int __cdecl _waccess(const wchar_t*, int); +_CRTIMP int __cdecl _wchmod(const wchar_t*, int); +_CRTIMP int __cdecl _wcreat(const wchar_t*, int); +_CRTIMP long __cdecl _wfindfirst(const wchar_t*, struct _wfinddata_t*); +_CRTIMP int __cdecl _wfindnext(long, struct _wfinddata_t *); +_CRTIMP int __cdecl _wunlink(const wchar_t*); +_CRTIMP int __cdecl _wopen(const wchar_t*, int, ...); +_CRTIMP int __cdecl _wsopen(const wchar_t*, int, int, ...); +_CRTIMP wchar_t * __cdecl _wmktemp(wchar_t*); +_CRTIMP long __cdecl _wfindfirsti64(const wchar_t*, struct _wfinddatai64_t*); +_CRTIMP int __cdecl _wfindnexti64(long, struct _wfinddatai64_t*); +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP intptr_t __cdecl _wfindfirst64(const wchar_t*, struct __wfinddata64_t*); +_CRTIMP intptr_t __cdecl _wfindnext64(intptr_t, struct __wfinddata64_t*); +#endif +#endif /* defined (__MSVCRT__) */ +#define _WIO_DEFINED +#endif /* _WIO_DEFINED */ + +#ifndef _NO_OLDNAMES +/* + * Non-underscored versions of non-ANSI functions to improve portability. + * These functions live in libmoldname.a. + */ + +#ifndef _UWIN +_CRTIMP int __cdecl access (const char*, int); +_CRTIMP int __cdecl chsize (int, long ); +_CRTIMP int __cdecl close (int); +_CRTIMP int __cdecl creat (const char*, int); +_CRTIMP int __cdecl dup (int); +_CRTIMP int __cdecl dup2 (int, int); +_CRTIMP int __cdecl eof (int); +_CRTIMP long __cdecl filelength (int); +_CRTIMP int __cdecl isatty (int); +_CRTIMP long __cdecl lseek (int, long, int); +_CRTIMP int __cdecl open (const char*, int, ...); +_CRTIMP int __cdecl read (int, void*, unsigned int); +_CRTIMP int __cdecl setmode (int, int); +_CRTIMP int __cdecl sopen (const char*, int, int, ...); +_CRTIMP long __cdecl tell (int); +_CRTIMP int __cdecl umask (int); +_CRTIMP int __cdecl unlink (const char*); +_CRTIMP int __cdecl write (int, const void*, unsigned int); +#endif /* _UWIN */ + +/* Wide character versions. Also declared in wchar.h. */ +/* Where do these live? Not in libmoldname.a nor in libmsvcrt.a */ +#if 0 +int waccess(const wchar_t *, int); +int wchmod(const wchar_t *, int); +int wcreat(const wchar_t *, int); +long wfindfirst(wchar_t *, struct _wfinddata_t *); +int wfindnext(long, struct _wfinddata_t *); +int wunlink(const wchar_t *); +int wrename(const wchar_t *, const wchar_t *); +int wopen(const wchar_t *, int, ...); +int wsopen(const wchar_t *, int, int, ...); +wchar_t * wmktemp(wchar_t *); +#endif + +#endif /* Not _NO_OLDNAMES */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* _IO_H_ not defined */ diff --git a/reactos/lib/mingw/include/limits.h b/reactos/lib/mingw/include/limits.h new file mode 100644 index 00000000000..04f79f58cbc --- /dev/null +++ b/reactos/lib/mingw/include/limits.h @@ -0,0 +1,112 @@ +/* + * limits.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Functions for manipulating paths and directories (included from io.h) + * plus functions for setting the current drive. + * + * Defines constants for the sizes of integral types. + * + * NOTE: GCC should supply a version of this header and it should be safe to + * use that version instead of this one (maybe safer). + * + */ + +#ifndef _LIMITS_H_ +#define _LIMITS_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* + * File system limits + * + * TODO: NAME_MAX and OPEN_MAX are file system limits or not? Are they the + * same as FILENAME_MAX and FOPEN_MAX from stdio.h? + * NOTE: Apparently the actual size of PATH_MAX is 260, but a space is + * required for the NUL. TODO: Test? + */ +#define PATH_MAX 259 + +/* + * Characteristics of the char data type. + * + * TODO: Is MB_LEN_MAX correct? + */ +#define CHAR_BIT 8 +#define MB_LEN_MAX 2 + +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 + +#define UCHAR_MAX 255 + +/* TODO: Is this safe? I think it might just be testing the preprocessor, + * not the compiler itself... */ +#if ('\x80' < 0) +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#else +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#endif + +/* + * Maximum and minimum values for ints. + */ +#define INT_MAX 2147483647 +#define INT_MIN (-INT_MAX-1) + +#define UINT_MAX 0xffffffff + +/* + * Maximum and minimum values for shorts. + */ +#define SHRT_MAX 32767 +#define SHRT_MIN (-SHRT_MAX-1) + +#define USHRT_MAX 0xffff + +/* + * Maximum and minimum values for longs and unsigned longs. + * + * TODO: This is not correct for Alphas, which have 64 bit longs. + */ +#define LONG_MAX 2147483647L +#define LONG_MIN (-LONG_MAX-1) + +#define ULONG_MAX 0xffffffffUL + +#ifndef __STRICT_ANSI__ +/* POSIX wants this. */ +#define SSIZE_MAX LONG_MAX +#endif + +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \ + || !defined(__STRICT_ANSI__) +/* ISO C9x macro names */ +#define LLONG_MAX 9223372036854775807LL +#define LLONG_MIN (-LLONG_MAX - 1) +#define ULLONG_MAX (2ULL * LLONG_MAX + 1) +#endif + +/* + * The GNU C compiler also allows 'long long int' + */ +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) + +#define LONG_LONG_MAX 9223372036854775807LL +#define LONG_LONG_MIN (-LONG_LONG_MAX-1) +#define ULONG_LONG_MAX (2ULL * LONG_LONG_MAX + 1) + +/* MSVC compatibility */ +#define _I64_MIN LONG_LONG_MIN +#define _I64_MAX LONG_LONG_MAX +#define _UI64_MAX ULONG_LONG_MAX + +#endif /* Not Strict ANSI and GNU C compiler */ + + +#endif /* not _LIMITS_H_ */ diff --git a/reactos/lib/mingw/include/locale.h b/reactos/lib/mingw/include/locale.h new file mode 100644 index 00000000000..41746c6a35b --- /dev/null +++ b/reactos/lib/mingw/include/locale.h @@ -0,0 +1,88 @@ +/* + * locale.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Functions and types for localization (ie. changing the appearance of + * output based on the standards of a certain country). + * + */ + +#ifndef _LOCALE_H_ +#define _LOCALE_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* + * NOTE: I have tried to test this, but I am limited by my knowledge of + * locale issues. The structure does not bomb if you look at the + * values, and 'decimal_point' even seems to be correct. But the + * rest of the values are, by default, not particularly useful + * (read meaningless and not related to the international settings + * of the system). + */ + +#define LC_ALL 0 +#define LC_COLLATE 1 +#define LC_CTYPE 2 +#define LC_MONETARY 3 +#define LC_NUMERIC 4 +#define LC_TIME 5 +#define LC_MIN LC_ALL +#define LC_MAX LC_TIME + +#ifndef RC_INVOKED + +/* According to C89 std, NULL is defined in locale.h too. */ +#define __need_NULL +#include + +/* + * The structure returned by 'localeconv'. + */ +struct lconv +{ + char* decimal_point; + char* thousands_sep; + char* grouping; + char* int_curr_symbol; + char* currency_symbol; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP char* __cdecl setlocale (int, const char*); +_CRTIMP struct lconv* __cdecl localeconv (void); + +#ifndef _WLOCALE_DEFINED /* also declared in wchar.h */ +# define __need_wchar_t +# include + _CRTIMP wchar_t* __cdecl _wsetlocale(int, const wchar_t*); +# define _WLOCALE_DEFINED +#endif /* ndef _WLOCALE_DEFINED */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _LOCALE_H_ */ + diff --git a/reactos/lib/mingw/include/malloc.h b/reactos/lib/mingw/include/malloc.h new file mode 100644 index 00000000000..5afa2916f43 --- /dev/null +++ b/reactos/lib/mingw/include/malloc.h @@ -0,0 +1,98 @@ +/* + * malloc.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Support for programs which want to use malloc.h to get memory management + * functions. Unless you absolutely need some of these functions and they are + * not in the ANSI headers you should use the ANSI standard header files + * instead. + * + */ + +#ifndef _MALLOC_H_ +#define _MALLOC_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#include + +#ifndef RC_INVOKED + +/* + * The structure used to walk through the heap with _heapwalk. + */ +typedef struct _heapinfo +{ + int* _pentry; + size_t _size; + int _useflag; +} _HEAPINFO; + +/* Values for _heapinfo.useflag */ +#define _FREEENTRY 0 +#define _USEDENTRY 1 + +/* Return codes for _heapwalk() */ +#define _HEAPEMPTY (-1) +#define _HEAPOK (-2) +#define _HEAPBADBEGIN (-3) +#define _HEAPBADNODE (-4) +#define _HEAPEND (-5) +#define _HEAPBADPTR (-6) + +#ifdef __cplusplus +extern "C" { +#endif +/* + The _heap* memory allocation functions are supported on NT + but not W9x. On latter, they always set errno to ENOSYS. +*/ +_CRTIMP int __cdecl _heapwalk (_HEAPINFO*); +#ifdef __GNUC__ +#define _alloca(x) __builtin_alloca((x)) +#endif + +#ifndef _NO_OLDNAMES +_CRTIMP int __cdecl heapwalk (_HEAPINFO*); +#ifdef __GNUC__ +#define alloca(x) __builtin_alloca((x)) +#endif +#endif /* Not _NO_OLDNAMES */ + +_CRTIMP int __cdecl _heapchk (void); /* Verify heap integrety. */ +_CRTIMP int __cdecl _heapmin (void); /* Return unused heap to the OS. */ +_CRTIMP int __cdecl _heapset (unsigned int); + +_CRTIMP size_t __cdecl _msize (void*); +_CRTIMP size_t __cdecl _get_sbh_threshold (void); +_CRTIMP int __cdecl _set_sbh_threshold (size_t); +_CRTIMP void* __cdecl _expand (void*, size_t); + +/* These require msvcr70.dll or higher. */ +#if __MSVCRT_VERSION__ >= 0x0700 +_CRTIMP void * __cdecl _aligned_offset_malloc(size_t, size_t, size_t); +_CRTIMP void * __cdecl _aligned_offset_realloc(void*, size_t, size_t, size_t); + +_CRTIMP void * __cdecl _aligned_malloc (size_t, size_t); +_CRTIMP void * __cdecl _aligned_realloc (void*, size_t, size_t); +_CRTIMP void __cdecl _aligned_free (void*); +#endif /* __MSVCRT_VERSION__ >= 0x0700 */ + +/* These require libmingwex.a. */ +void * __cdecl __mingw_aligned_offset_malloc (size_t, size_t, size_t); +void * __cdecl __mingw_aligned_offset_realloc (void*, size_t, size_t, size_t); + +void * __cdecl __mingw_aligned_malloc (size_t, size_t); +void * __cdecl __mingw_aligned_realloc (void*, size_t, size_t); +void __cdecl __mingw_aligned_free (void*); + +#ifdef __cplusplus +} +#endif + +#endif /* RC_INVOKED */ + +#endif /* Not _MALLOC_H_ */ diff --git a/reactos/lib/mingw/include/math.h b/reactos/lib/mingw/include/math.h new file mode 100644 index 00000000000..b03bc541ff6 --- /dev/null +++ b/reactos/lib/mingw/include/math.h @@ -0,0 +1,848 @@ +/* + * math.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Mathematical functions. + * + */ + + +#ifndef _MATH_H_ +#define _MATH_H_ + +#if __GNUC__ >= 3 +#pragma GCC system_header +#endif + +/* All the headers include this file. */ +#include <_mingw.h> + +/* + * Types for the _exception structure. + */ + +#define _DOMAIN 1 /* domain error in argument */ +#define _SING 2 /* singularity */ +#define _OVERFLOW 3 /* range overflow */ +#define _UNDERFLOW 4 /* range underflow */ +#define _TLOSS 5 /* total loss of precision */ +#define _PLOSS 6 /* partial loss of precision */ + +/* + * Exception types with non-ANSI names for compatibility. + */ + +#ifndef __STRICT_ANSI__ +#ifndef _NO_OLDNAMES + +#define DOMAIN _DOMAIN +#define SING _SING +#define OVERFLOW _OVERFLOW +#define UNDERFLOW _UNDERFLOW +#define TLOSS _TLOSS +#define PLOSS _PLOSS + +#endif /* Not _NO_OLDNAMES */ +#endif /* Not __STRICT_ANSI__ */ + + +/* Traditional/XOPEN math constants (double precison) */ +#ifndef __STRICT_ANSI__ +#define M_E 2.7182818284590452354 +#define M_LOG2E 1.4426950408889634074 +#define M_LOG10E 0.43429448190325182765 +#define M_LN2 0.69314718055994530942 +#define M_LN10 2.30258509299404568402 +#define M_PI 3.14159265358979323846 +#define M_PI_2 1.57079632679489661923 +#define M_PI_4 0.78539816339744830962 +#define M_1_PI 0.31830988618379067154 +#define M_2_PI 0.63661977236758134308 +#define M_2_SQRTPI 1.12837916709551257390 +#define M_SQRT2 1.41421356237309504880 +#define M_SQRT1_2 0.70710678118654752440 +#endif + +/* These are also defined in Mingw float.h; needed here as well to work + around GCC build issues. */ +#ifndef __STRICT_ANSI__ +#ifndef __MINGW_FPCLASS_DEFINED +#define __MINGW_FPCLASS_DEFINED 1 +/* IEEE 754 classication */ +#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ +#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ +#define _FPCLASS_NINF 0x0004 /* Negative Infinity */ +#define _FPCLASS_NN 0x0008 /* Negative Normal */ +#define _FPCLASS_ND 0x0010 /* Negative Denormal */ +#define _FPCLASS_NZ 0x0020 /* Negative Zero */ +#define _FPCLASS_PZ 0x0040 /* Positive Zero */ +#define _FPCLASS_PD 0x0080 /* Positive Denormal */ +#define _FPCLASS_PN 0x0100 /* Positive Normal */ +#define _FPCLASS_PINF 0x0200 /* Positive Infinity */ +#endif /* __MINGW_FPCLASS_DEFINED */ +#endif /* Not __STRICT_ANSI__ */ + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * HUGE_VAL is returned by strtod when the value would overflow the + * representation of 'double'. There are other uses as well. + * + * __imp__HUGE is a pointer to the actual variable _HUGE in + * MSVCRT.DLL. If we used _HUGE directly we would get a pointer + * to a thunk function. + * + * NOTE: The CRTDLL version uses _HUGE_dll instead. + */ + +#if __MINGW_GNUC_PREREQ(3, 3) +#define HUGE_VAL __builtin_huge_val() +#else + +#ifndef __DECLSPEC_SUPPORTED + +#ifdef __MSVCRT__ +extern double* _imp___HUGE; +#define HUGE_VAL (*_imp___HUGE) +#else +/* CRTDLL */ +extern double* _imp___HUGE_dll; +#define HUGE_VAL (*_imp___HUGE_dll) +#endif + +#else /* __DECLSPEC_SUPPORTED */ + +#ifdef __MSVCRT__ +__MINGW_IMPORT double _HUGE; +#define HUGE_VAL _HUGE +#else +/* CRTDLL */ +__MINGW_IMPORT double _HUGE_dll; +#define HUGE_VAL _HUGE_dll +#endif + +#endif /* __DECLSPEC_SUPPORTED */ +#endif /* __MINGW_GNUC_PREREQ(3, 3) */ + + +struct _exception +{ + int type; + char *name; + double arg1; + double arg2; + double retval; +}; + +_CRTIMP double __cdecl sin (double); +_CRTIMP double __cdecl cos (double); +_CRTIMP double __cdecl tan (double); +_CRTIMP double __cdecl sinh (double); +_CRTIMP double __cdecl cosh (double); +_CRTIMP double __cdecl tanh (double); +_CRTIMP double __cdecl asin (double); +_CRTIMP double __cdecl acos (double); +_CRTIMP double __cdecl atan (double); +_CRTIMP double __cdecl atan2 (double, double); +_CRTIMP double __cdecl exp (double); +_CRTIMP double __cdecl log (double); +_CRTIMP double __cdecl log10 (double); +_CRTIMP double __cdecl pow (double, double); +_CRTIMP double __cdecl sqrt (double); +_CRTIMP double __cdecl ceil (double); +_CRTIMP double __cdecl floor (double); +_CRTIMP double __cdecl fabs (double); +_CRTIMP double __cdecl ldexp (double, int); +_CRTIMP double __cdecl frexp (double, int*); +_CRTIMP double __cdecl modf (double, double*); +_CRTIMP double __cdecl fmod (double, double); + +/* Excess precision when using a 64-bit mantissa for FPU math ops can + cause unexpected results with some of the MSVCRT math functions. For + example, unless the function return value is stored (truncating to + 53-bit mantissa), calls to pow with both x and y as integral values + sometimes produce a non-integral result. + One workaround is to reset the FPU env to 53-bit mantissa + by a call to fesetenv (FE_PC53_ENV). Amother is to force storage + of the return value of individual math functions using wrappers. + NB, using these wrappers will disable builtin math functions and + hence disable the folding of function results at compile time when + arguments are constant. */ + +#if 0 +#define __DEFINE_FLOAT_STORE_MATHFN_D1(fn1) \ +static __inline__ double \ +__float_store_ ## fn1 (double x) \ +{ \ + __volatile__ double res = (fn1) (x); \ + return res; \ +} + +#define __DEFINE_FLOAT_STORE_MATHFN_D2(fn2) \ +static __inline__ double \ +__float_store_ ## fn2 (double x, double y) \ +{ \ + __volatile__ double res = (fn2) (x, y); \ + return res; \ +} +#endif + +/* For example, here is how to force the result of the pow function + to be stored: */ +#if 0 +#undef pow +/* Define the ___float_store_pow function and use it instead of pow(). */ +__DEFINE_FLOAT_STORE_MATHFN_D2 (pow) +#define pow __float_store_pow +#endif + +#ifndef __STRICT_ANSI__ + +/* Complex number (for _cabs). This is the MS version. The ISO + C99 counterpart _Complex is an intrinsic type in GCC and + 'complex' is defined as a macro. See complex.h */ +struct _complex +{ + double x; /* Real part */ + double y; /* Imaginary part */ +}; + +_CRTIMP double __cdecl _cabs (struct _complex); + +_CRTIMP double __cdecl _hypot (double, double); +_CRTIMP double __cdecl _j0 (double); +_CRTIMP double __cdecl _j1 (double); +_CRTIMP double __cdecl _jn (int, double); +_CRTIMP double __cdecl _y0 (double); +_CRTIMP double __cdecl _y1 (double); +_CRTIMP double __cdecl _yn (int, double); +_CRTIMP int __cdecl _matherr (struct _exception *); + +/* These are also declared in Mingw float.h; needed here as well to work + around GCC build issues. */ +/* BEGIN FLOAT.H COPY */ +/* + * IEEE recommended functions + */ + +_CRTIMP double __cdecl _chgsign (double); +_CRTIMP double __cdecl _copysign (double, double); +_CRTIMP double __cdecl _logb (double); +_CRTIMP double __cdecl _nextafter (double, double); +_CRTIMP double __cdecl _scalb (double, long); + +_CRTIMP int __cdecl _finite (double); +_CRTIMP int __cdecl _fpclass (double); +_CRTIMP int __cdecl _isnan (double); + +/* END FLOAT.H COPY */ + + +/* + * Non-underscored versions of non-ANSI functions. + * These reside in liboldnames.a. + */ + +#if !defined (_NO_OLDNAMES) + +_CRTIMP double __cdecl j0 (double); +_CRTIMP double __cdecl j1 (double); +_CRTIMP double __cdecl jn (int, double); +_CRTIMP double __cdecl y0 (double); +_CRTIMP double __cdecl y1 (double); +_CRTIMP double __cdecl yn (int, double); + +_CRTIMP double __cdecl chgsign (double); +_CRTIMP double __cdecl scalb (double, long); +_CRTIMP int __cdecl finite (double); +_CRTIMP int __cdecl fpclass (double); + +#define FP_SNAN _FPCLASS_SNAN +#define FP_QNAN _FPCLASS_QNAN +#define FP_NINF _FPCLASS_NINF +#define FP_PINF _FPCLASS_PINF +#define FP_NDENORM _FPCLASS_ND +#define FP_PDENORM _FPCLASS_PD +#define FP_NZERO _FPCLASS_NZ +#define FP_PZERO _FPCLASS_PZ +#define FP_NNORM _FPCLASS_NN +#define FP_PNORM _FPCLASS_PN + +#endif /* Not _NO_OLDNAMES */ + +/* This require msvcr70.dll or higher. */ +#if __MSVCRT_VERSION__ >= 0x0700 +_CRTIMP int __cdecl _set_SSE2_enable (int); +#endif /* __MSVCRT_VERSION__ >= 0x0700 */ + + +#endif /* __STRICT_ANSI__ */ + + +#ifndef __NO_ISOCEXT +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \ + || !defined __STRICT_ANSI__ || defined __cplusplus + +#if __MINGW_GNUC_PREREQ(3, 3) +#define HUGE_VALF __builtin_huge_valf() +#define HUGE_VALL __builtin_huge_vall() +#define INFINITY __builtin_inf() +#define NAN __builtin_nan("") +#else +extern const float __INFF; +#define HUGE_VALF __INFF +extern const long double __INFL; +#define HUGE_VALL __INFL +#define INFINITY HUGE_VALF +extern const double __QNAN; +#define NAN __QNAN +#endif /* __MINGW_GNUC_PREREQ(3, 3) */ + +/* 7.12.3.1 */ +/* + Return values for fpclassify. + These are based on Intel x87 fpu condition codes + in the high byte of status word and differ from + the return values for MS IEEE 754 extension _fpclass() +*/ +#define FP_NAN 0x0100 +#define FP_NORMAL 0x0400 +#define FP_INFINITE (FP_NAN | FP_NORMAL) +#define FP_ZERO 0x4000 +#define FP_SUBNORMAL (FP_NORMAL | FP_ZERO) +/* 0x0200 is signbit mask */ + + +/* + We can't inline float or double, because we want to ensure truncation + to semantic type before classification. + (A normal long double value might become subnormal when + converted to double, and zero when converted to float.) +*/ + +extern int __cdecl __fpclassifyf (float); +extern int __cdecl __fpclassify (double); + +__CRT_INLINE int __cdecl __fpclassifyl (long double x){ + unsigned short sw; + __asm__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x)); + return sw & (FP_NAN | FP_NORMAL | FP_ZERO ); +} + +#define fpclassify(x) (sizeof (x) == sizeof (float) ? __fpclassifyf (x) \ + : sizeof (x) == sizeof (double) ? __fpclassify (x) \ + : __fpclassifyl (x)) + +/* 7.12.3.2 */ +#define isfinite(x) ((fpclassify(x) & FP_NAN) == 0) + +/* 7.12.3.3 */ +#define isinf(x) (fpclassify(x) == FP_INFINITE) + +/* 7.12.3.4 */ +/* We don't need to worry about trucation here: + A NaN stays a NaN. */ + +__CRT_INLINE int __cdecl __isnan (double _x) +{ + unsigned short sw; + __asm__ ("fxam;" + "fstsw %%ax": "=a" (sw) : "t" (_x)); + return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL)) + == FP_NAN; +} + +__CRT_INLINE int __cdecl __isnanf (float _x) +{ + unsigned short sw; + __asm__ ("fxam;" + "fstsw %%ax": "=a" (sw) : "t" (_x)); + return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL)) + == FP_NAN; +} + +__CRT_INLINE int __cdecl __isnanl (long double _x) +{ + unsigned short sw; + __asm__ ("fxam;" + "fstsw %%ax": "=a" (sw) : "t" (_x)); + return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL)) + == FP_NAN; +} + + +#define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x) \ + : sizeof (x) == sizeof (double) ? __isnan (x) \ + : __isnanl (x)) + +/* 7.12.3.5 */ +#define isnormal(x) (fpclassify(x) == FP_NORMAL) + +/* 7.12.3.6 The signbit macro */ +__CRT_INLINE int __cdecl __signbit (double x) { + unsigned short stw; + __asm__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x)); + return (stw & 0x0200) != 0; +} + +__CRT_INLINE int __cdecl __signbitf (float x) { + unsigned short stw; + __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x)); + return (stw & 0x0200) != 0; +} + +__CRT_INLINE int __cdecl __signbitl (long double x) { + unsigned short stw; + __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x)); + return (stw & 0x0200) != 0; +} + +#define signbit(x) (sizeof (x) == sizeof (float) ? __signbitf (x) \ + : sizeof (x) == sizeof (double) ? __signbit (x) \ + : __signbitl (x)) + +/* 7.12.4 Trigonometric functions: Double in C89 */ +extern float __cdecl sinf (float); +extern long double __cdecl sinl (long double); + +extern float __cdecl cosf (float); +extern long double __cdecl cosl (long double); + +extern float __cdecl tanf (float); +extern long double __cdecl tanl (long double); + +extern float __cdecl asinf (float); +extern long double __cdecl asinl (long double); + +extern float __cdecl acosf (float); +extern long double __cdecl acosl (long double); + +extern float __cdecl atanf (float); +extern long double __cdecl atanl (long double); + +extern float __cdecl atan2f (float, float); +extern long double __cdecl atan2l (long double, long double); + +/* 7.12.5 Hyperbolic functions: Double in C89 */ +__CRT_INLINE float __cdecl sinhf (float x) + {return (float) sinh (x);} +extern long double __cdecl sinhl (long double); + +__CRT_INLINE float __cdecl coshf (float x) + {return (float) cosh (x);} +extern long double __cdecl coshl (long double); + +__CRT_INLINE float __cdecl tanhf (float x) + {return (float) tanh (x);} +extern long double __cdecl tanhl (long double); + +/* Inverse hyperbolic trig functions */ +/* 7.12.5.1 */ +extern double __cdecl acosh (double); +extern float __cdecl acoshf (float); +extern long double __cdecl acoshl (long double); + +/* 7.12.5.2 */ +extern double __cdecl asinh (double); +extern float __cdecl asinhf (float); +extern long double __cdecl asinhl (long double); + +/* 7.12.5.3 */ +extern double __cdecl atanh (double); +extern float __cdecl atanf (float); +extern long double __cdecl atanhl (long double); + +/* Exponentials and logarithms */ +/* 7.12.6.1 Double in C89 */ +__CRT_INLINE float __cdecl expf (float x) + {return (float) exp (x);} +extern long double __cdecl expl (long double); + +/* 7.12.6.2 */ +extern double __cdecl exp2(double); +extern float __cdecl exp2f(float); +extern long double __cdecl exp2l(long double); + +/* 7.12.6.3 The expm1 functions */ +/* TODO: These could be inlined */ +extern double __cdecl expm1(double); +extern float __cdecl expm1f(float); +extern long double __cdecl expm1l(long double); + +/* 7.12.6.4 Double in C89 */ +__CRT_INLINE float __cdecl frexpf (float x, int* expn) + {return (float) frexp (x, expn);} +extern long double __cdecl frexpl (long double, int*); + +/* 7.12.6.5 */ +#define FP_ILOGB0 ((int)0x80000000) +#define FP_ILOGBNAN ((int)0x80000000) +extern int __cdecl ilogb (double); +extern int __cdecl ilogbf (float); +extern int __cdecl ilogbl (long double); + +/* 7.12.6.6 Double in C89 */ +__CRT_INLINE float __cdecl ldexpf (float x, int expn) + {return (float) ldexp (x, expn);} +extern long double __cdecl ldexpl (long double, int); + +/* 7.12.6.7 Double in C89 */ +extern float __cdecl logf (float); +extern long double __cdecl logl (long double); + +/* 7.12.6.8 Double in C89 */ +extern float __cdecl log10f (float); +extern long double __cdecl log10l (long double); + +/* 7.12.6.9 */ +extern double __cdecl log1p(double); +extern float __cdecl log1pf(float); +extern long double __cdecl log1pl(long double); + +/* 7.12.6.10 */ +extern double __cdecl log2 (double); +extern float __cdecl log2f (float); +extern long double __cdecl log2l (long double); + +/* 7.12.6.11 */ +extern double __cdecl logb (double); +extern float __cdecl logbf (float); +extern long double __cdecl logbl (long double); + +/* Inline versions. GCC-4.0+ can do a better fast-math optimization + with __builtins. */ +#if !(__MINGW_GNUC_PREREQ (4, 0) && defined __FAST_MATH__ ) +__CRT_INLINE double __cdecl logb (double x) +{ + double res; + __asm__ ("fxtract\n\t" + "fstp %%st" : "=t" (res) : "0" (x)); + return res; +} + +__CRT_INLINE float __cdecl logbf (float x) +{ + float res; + __asm__ ("fxtract\n\t" + "fstp %%st" : "=t" (res) : "0" (x)); + return res; +} + +__CRT_INLINE long double __cdecl logbl (long double x) +{ + long double res; + __asm__ ("fxtract\n\t" + "fstp %%st" : "=t" (res) : "0" (x)); + return res; +} +#endif /* !defined __FAST_MATH__ || !__MINGW_GNUC_PREREQ (4, 0) */ + +/* 7.12.6.12 Double in C89 */ +extern float __cdecl modff (float, float*); +extern long double __cdecl modfl (long double, long double*); + +/* 7.12.6.13 */ +extern double __cdecl scalbn (double, int); +extern float __cdecl scalbnf (float, int); +extern long double __cdecl scalbnl (long double, int); + +extern double __cdecl scalbln (double, long); +extern float __cdecl scalblnf (float, long); +extern long double __cdecl scalblnl (long double, long); + +/* 7.12.7.1 */ +/* Implementations adapted from Cephes versions */ +extern double __cdecl cbrt (double); +extern float __cdecl cbrtf (float); +extern long double __cdecl cbrtl (long double); + +/* 7.12.7.2 The fabs functions: Double in C89 */ +extern float __cdecl fabsf (float x); +extern long double __cdecl fabsl (long double x); + +/* 7.12.7.3 */ +extern double __cdecl hypot (double, double); /* in libmoldname.a */ +__CRT_INLINE float __cdecl hypotf (float x, float y) + { return (float) hypot (x, y);} +extern long double __cdecl hypotl (long double, long double); + +/* 7.12.7.4 The pow functions. Double in C89 */ +__CRT_INLINE float __cdecl powf (float x, float y) + {return (float) pow (x, y);} +extern long double __cdecl powl (long double, long double); + +/* 7.12.7.5 The sqrt functions. Double in C89. */ +extern float __cdecl sqrtf (float); +extern long double __cdecl sqrtl (long double); + +/* 7.12.8.1 The erf functions */ +extern double __cdecl erf (double); +extern float __cdecl erff (float); +extern long double __cdecl erfl (long double); + +/* 7.12.8.2 The erfc functions */ +extern double __cdecl erfc (double); +extern float __cdecl erfcf (float); +extern long double __cdecl erfcl (long double); + +/* 7.12.8.3 The lgamma functions */ +extern double __cdecl lgamma (double); +extern float __cdecl lgammaf (float); +extern long double __cdecl lgammal (long double); + +/* 7.12.8.4 The tgamma functions */ +extern double __cdecl tgamma (double); +extern float __cdecl tgammaf (float); +extern long double __cdecl tgammal (long double); + +/* 7.12.9.1 Double in C89 */ +extern float __cdecl ceilf (float); +extern long double __cdecl ceill (long double); + +/* 7.12.9.2 Double in C89 */ +extern float __cdecl floorf (float); +extern long double __cdecl floorl (long double); + +/* 7.12.9.3 */ +extern double __cdecl nearbyint ( double); +extern float __cdecl nearbyintf (float); +extern long double __cdecl nearbyintl (long double); + +/* 7.12.9.4 */ +/* round, using fpu control word settings */ +extern double __cdecl rint (double); +extern float __cdecl rintf (float); +extern long double __cdecl rintl (long double); + +/* 7.12.9.5 */ +extern long __cdecl lrint (double); +extern long __cdecl lrintf (float); +extern long __cdecl lrintl (long double); + +extern long long __cdecl llrint (double); +extern long long __cdecl llrintf (float); +extern long long __cdecl llrintl (long double); + +/* Inline versions of above. + GCC 4.0+ can do a better fast-math job with __builtins. */ +#if !(__MINGW_GNUC_PREREQ (4, 0) && defined __FAST_MATH__ ) +__CRT_INLINE double __cdecl rint (double x) +{ + double retval; + __asm__ ("frndint;": "=t" (retval) : "0" (x)); + return retval; +} + +__CRT_INLINE float __cdecl rintf (float x) +{ + float retval; + __asm__ ("frndint;" : "=t" (retval) : "0" (x) ); + return retval; +} + +__CRT_INLINE long double __cdecl rintl (long double x) +{ + long double retval; + __asm__ ("frndint;" : "=t" (retval) : "0" (x) ); + return retval; +} + +__CRT_INLINE long __cdecl lrint (double x) +{ + long retval; + __asm__ __volatile__ + ("fistpl %0" : "=m" (retval) : "t" (x) : "st"); + return retval; +} + +__CRT_INLINE long __cdecl lrintf (float x) +{ + long retval; + __asm__ __volatile__ + ("fistpl %0" : "=m" (retval) : "t" (x) : "st"); + return retval; +} + +__CRT_INLINE long __cdecl lrintl (long double x) +{ + long retval; + __asm__ __volatile__ + ("fistpl %0" : "=m" (retval) : "t" (x) : "st"); + return retval; +} + +__CRT_INLINE long long __cdecl llrint (double x) +{ + long long retval; + __asm__ __volatile__ + ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); + return retval; +} + +__CRT_INLINE long long __cdecl llrintf (float x) +{ + long long retval; + __asm__ __volatile__ + ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); + return retval; +} + +__CRT_INLINE long long __cdecl llrintl (long double x) +{ + long long retval; + __asm__ __volatile__ + ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); + return retval; +} +#endif /* !__FAST_MATH__ || !__MINGW_GNUC_PREREQ (4,0) */ + +/* 7.12.9.6 */ +/* round away from zero, regardless of fpu control word settings */ +extern double __cdecl round (double); +extern float __cdecl roundf (float); +extern long double __cdecl roundl (long double); + +/* 7.12.9.7 */ +extern long __cdecl lround (double); +extern long __cdecl lroundf (float); +extern long __cdecl lroundl (long double); + +extern long long __cdecl llround (double); +extern long long __cdecl llroundf (float); +extern long long __cdecl llroundl (long double); + +/* 7.12.9.8 */ +/* round towards zero, regardless of fpu control word settings */ +extern double __cdecl trunc (double); +extern float __cdecl truncf (float); +extern long double __cdecl truncl (long double); + +/* 7.12.10.1 Double in C89 */ +extern float __cdecl fmodf (float, float); +extern long double __cdecl fmodl (long double, long double); + +/* 7.12.10.2 */ +extern double __cdecl remainder (double, double); +extern float __cdecl remainderf (float, float); +extern long double __cdecl remainderl (long double, long double); + +/* 7.12.10.3 */ +extern double __cdecl remquo(double, double, int *); +extern float __cdecl remquof(float, float, int *); +extern long double __cdecl remquol(long double, long double, int *); + +/* 7.12.11.1 */ +extern double __cdecl copysign (double, double); /* in libmoldname.a */ +extern float __cdecl copysignf (float, float); +extern long double __cdecl copysignl (long double, long double); + +/* 7.12.11.2 Return a NaN */ +extern double __cdecl nan(const char *tagp); +extern float __cdecl nanf(const char *tagp); +extern long double __cdecl nanl(const char *tagp); + +#ifndef __STRICT_ANSI__ +#define _nan() nan("") +#define _nanf() nanf("") +#define _nanl() nanl("") +#endif + +/* 7.12.11.3 */ +extern double __cdecl nextafter (double, double); /* in libmoldname.a */ +extern float __cdecl nextafterf (float, float); +extern long double __cdecl nextafterl (long double, long double); + +/* 7.12.11.4 The nexttoward functions */ +extern double __cdecl nexttoward (double, long double); +extern float __cdecl nexttowardf (float, long double); +extern long double __cdecl nexttowardl (long double, long double); + +/* 7.12.12.1 */ +/* x > y ? (x - y) : 0.0 */ +extern double __cdecl fdim (double x, double y); +extern float __cdecl fdimf (float x, float y); +extern long double __cdecl fdiml (long double x, long double y); + +/* fmax and fmin. + NaN arguments are treated as missing data: if one argument is a NaN + and the other numeric, then these functions choose the numeric + value. */ + +/* 7.12.12.2 */ +extern double __cdecl fmax (double, double); +extern float __cdecl fmaxf (float, float); +extern long double __cdecl fmaxl (long double, long double); + +/* 7.12.12.3 */ +extern double __cdecl fmin (double, double); +extern float __cdecl fminf (float, float); +extern long double __cdecl fminl (long double, long double); + +/* 7.12.13.1 */ +/* return x * y + z as a ternary op */ +extern double __cdecl fma (double, double, double); +extern float __cdecl fmaf (float, float, float); +extern long double __cdecl fmal (long double, long double, long double); + + +/* 7.12.14 */ +/* + * With these functions, comparisons involving quiet NaNs set the FP + * condition code to "unordered". The IEEE floating-point spec + * dictates that the result of floating-point comparisons should be + * false whenever a NaN is involved, with the exception of the != op, + * which always returns true: yes, (NaN != NaN) is true). + */ + +#if __GNUC__ >= 3 + +#define isgreater(x, y) __builtin_isgreater(x, y) +#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y) +#define isless(x, y) __builtin_isless(x, y) +#define islessequal(x, y) __builtin_islessequal(x, y) +#define islessgreater(x, y) __builtin_islessgreater(x, y) +#define isunordered(x, y) __builtin_isunordered(x, y) + +#else +/* helper */ +__CRT_INLINE int __cdecl +__fp_unordered_compare (long double x, long double y){ + unsigned short retval; + __asm__ ("fucom %%st(1);" + "fnstsw;": "=a" (retval) : "t" (x), "u" (y)); + return retval; +} + +#define isgreater(x, y) ((__fp_unordered_compare(x, y) \ + & 0x4500) == 0) +#define isless(x, y) ((__fp_unordered_compare (y, x) \ + & 0x4500) == 0) +#define isgreaterequal(x, y) ((__fp_unordered_compare (x, y) \ + & FP_INFINITE) == 0) +#define islessequal(x, y) ((__fp_unordered_compare(y, x) \ + & FP_INFINITE) == 0) +#define islessgreater(x, y) ((__fp_unordered_compare(x, y) \ + & FP_SUBNORMAL) == 0) +#define isunordered(x, y) ((__fp_unordered_compare(x, y) \ + & 0x4500) == 0x4500) + +#endif + + +#endif /* __STDC_VERSION__ >= 199901L */ +#endif /* __NO_ISOCEXT */ + + +#ifdef __cplusplus +} +#endif +#endif /* Not RC_INVOKED */ + + +#endif /* Not _MATH_H_ */ diff --git a/reactos/lib/mingw/include/mbctype.h b/reactos/lib/mingw/include/mbctype.h new file mode 100644 index 00000000000..dd57a7b5cd7 --- /dev/null +++ b/reactos/lib/mingw/include/mbctype.h @@ -0,0 +1,97 @@ +/* + * mbctype.h + * + * Functions for testing multibyte character types and converting characters. + * + * This file is part of the Mingw32 package. + * + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef _MBCTYPE_H_ +#define _MBCTYPE_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* return values for _mbsbtype and _mbbtype in mbstring.h */ +#define _MBC_SINGLE 0 +#define _MBC_LEAD 1 +#define _MBC_TRAIL 2 +#define _MBC_ILLEGAL (-1) + +/* args for setmbcp (in lieu of actual codepage) */ +#define _MB_CP_SBCS 0 +#define _MB_CP_OEM (-2) +#define _MB_CP_ANSI (-3) +#define _MB_CP_LOCALE (-4) + +/* TODO: bit masks */ +/* +#define _MS +#define _MP +#define _M1 +#define _M2 +#define _SBUP +#define _SBLOW +*/ + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __STRICT_ANSI__ + +_CRTIMP int __cdecl _setmbcp (int); +_CRTIMP int __cdecl _getmbcp (void); + +/* byte classification */ +/* NB: Corresponding _ismbc* functions are in mbstring.h */ + +_CRTIMP int __cdecl _ismbbalpha (unsigned int); +_CRTIMP int __cdecl _ismbbalnum (unsigned int); +_CRTIMP int __cdecl _ismbbgraph (unsigned int); +_CRTIMP int __cdecl _ismbbprint (unsigned int); +_CRTIMP int __cdecl _ismbbpunct (unsigned int); + +_CRTIMP int __cdecl _ismbbkana (unsigned int); +_CRTIMP int __cdecl _ismbbkalnum (unsigned int); +_CRTIMP int __cdecl _ismbbkprint (unsigned int); +_CRTIMP int __cdecl _ismbbkpunct (unsigned int); + + +/* these are also in mbstring.h */ +_CRTIMP int __cdecl _ismbblead (unsigned int); +_CRTIMP int __cdecl _ismbbtrail (unsigned int); +_CRTIMP int __cdecl _ismbslead (const unsigned char*, const unsigned char*); +_CRTIMP int __cdecl _ismbstrail (const unsigned char*, const unsigned char*); + +#ifdef __DECLSPEC_SUPPORTED +__MINGW_IMPORT unsigned char _mbctype[]; +__MINGW_IMPORT unsigned char _mbcasemap[]; +#endif + +/* TODO : _MBCS_ mappings go in tchar.h */ + +#endif /* Not strict ANSI */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _MCTYPE_H_ */ + diff --git a/reactos/lib/mingw/include/mbstring.h b/reactos/lib/mingw/include/mbstring.h new file mode 100644 index 00000000000..4ad777602af --- /dev/null +++ b/reactos/lib/mingw/include/mbstring.h @@ -0,0 +1,132 @@ +/* + * mbstring.h + * + * Protototypes for string functions supporting multibyte characters. + * + * This file is part of the Mingw32 package. + * + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef _MBSTRING_H_ +#define _MBSTRING_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#ifndef RC_INVOKED + +#define __need_size_t +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __STRICT_ANSI__ + +/* character classification */ +_CRTIMP int __cdecl _ismbcalnum (unsigned int); +_CRTIMP int __cdecl _ismbcalpha (unsigned int); +_CRTIMP int __cdecl _ismbcdigit (unsigned int); +_CRTIMP int __cdecl _ismbcgraph (unsigned int); +_CRTIMP int __cdecl _ismbcprint (unsigned int); +_CRTIMP int __cdecl _ismbcpunct (unsigned int); +_CRTIMP int __cdecl _ismbcspace (unsigned int); +_CRTIMP int __cdecl _ismbclower (unsigned int); +_CRTIMP int __cdecl _ismbcupper (unsigned int); +_CRTIMP int __cdecl _ismbclegal (unsigned int); +_CRTIMP int __cdecl _ismbcsymbol (unsigned int); + + +/* also in mbctype.h */ +_CRTIMP int __cdecl _ismbblead (unsigned int ); +_CRTIMP int __cdecl _ismbbtrail (unsigned int ); +_CRTIMP int __cdecl _ismbslead ( const unsigned char*, const unsigned char*); +_CRTIMP int __cdecl _ismbstrail ( const unsigned char*, const unsigned char*); + +_CRTIMP unsigned int __cdecl _mbctolower (unsigned int); +_CRTIMP unsigned int __cdecl _mbctoupper (unsigned int); + +_CRTIMP void __cdecl _mbccpy (unsigned char*, const unsigned char*); +_CRTIMP size_t __cdecl _mbclen (const unsigned char*); + +_CRTIMP unsigned int __cdecl _mbbtombc (unsigned int); +_CRTIMP unsigned int __cdecl _mbctombb (unsigned int); + +/* Return value constants for these are defined in mbctype.h. */ +_CRTIMP int __cdecl _mbbtype (unsigned char, int); +_CRTIMP int __cdecl _mbsbtype (const unsigned char*, size_t); + +_CRTIMP unsigned char* __cdecl _mbscpy (unsigned char*, const unsigned char*); +_CRTIMP unsigned char* __cdecl _mbsncpy (unsigned char*, const unsigned char*, size_t); +_CRTIMP unsigned char* __cdecl _mbsnbcpy (unsigned char*, const unsigned char*, size_t); +_CRTIMP unsigned char* __cdecl _mbsset (unsigned char*, unsigned int); +_CRTIMP unsigned char* __cdecl _mbsnset (unsigned char*, unsigned int, size_t); +_CRTIMP unsigned char* __cdecl _mbsnbset (unsigned char*, unsigned int, size_t); +_CRTIMP unsigned char* __cdecl _mbsdup (const unsigned char*); +_CRTIMP unsigned char* __cdecl _mbsrev (unsigned char*); +_CRTIMP unsigned char* __cdecl _mbscat (unsigned char*, const unsigned char*); +_CRTIMP unsigned char* __cdecl _mbsncat (unsigned char*, const unsigned char*, size_t); +_CRTIMP unsigned char* __cdecl _mbsnbcat (unsigned char*, const unsigned char*, size_t); +_CRTIMP size_t __cdecl _mbslen (const unsigned char*); +_CRTIMP size_t __cdecl _mbsnbcnt (const unsigned char*, size_t); +_CRTIMP size_t __cdecl _mbsnccnt (const unsigned char*, size_t); +_CRTIMP unsigned char* __cdecl _mbschr (const unsigned char*, unsigned int); +_CRTIMP unsigned char* __cdecl _mbsrchr (const unsigned char*, unsigned int); +_CRTIMP size_t __cdecl _mbsspn (const unsigned char*, const unsigned char*); +_CRTIMP size_t __cdecl _mbscspn (const unsigned char*, const unsigned char*); +_CRTIMP unsigned char* __cdecl _mbsspnp (const unsigned char*, const unsigned char*); +_CRTIMP unsigned char* __cdecl _mbspbrk (const unsigned char*, const unsigned char*); +_CRTIMP int __cdecl _mbscmp (const unsigned char*, const unsigned char*); +_CRTIMP int __cdecl _mbsicmp (const unsigned char*, const unsigned char*); +_CRTIMP int __cdecl _mbsncmp (const unsigned char*, const unsigned char*, size_t); +_CRTIMP int __cdecl _mbsnicmp (const unsigned char*, const unsigned char*, size_t); +_CRTIMP int __cdecl _mbsnbcmp (const unsigned char*, const unsigned char*, size_t); +_CRTIMP int __cdecl _mbsnbicmp (const unsigned char*, const unsigned char*, size_t); +_CRTIMP int __cdecl _mbscoll (const unsigned char*, const unsigned char*); +_CRTIMP int __cdecl _mbsicoll (const unsigned char*, const unsigned char*); +_CRTIMP int __cdecl _mbsncoll (const unsigned char*, const unsigned char*, size_t); +_CRTIMP int __cdecl _mbsnicoll (const unsigned char*, const unsigned char*, size_t); +_CRTIMP int __cdecl _mbsnbcoll (const unsigned char*, const unsigned char*, size_t); +_CRTIMP int __cdecl _mbsnbicoll (const unsigned char*, const unsigned char*, size_t); + +_CRTIMP unsigned char* __cdecl _mbsinc (const unsigned char*); +_CRTIMP unsigned char* __cdecl _mbsninc (const unsigned char*, size_t); +_CRTIMP unsigned char* __cdecl _mbsdec (const unsigned char*, const unsigned char*); +_CRTIMP unsigned int __cdecl _mbsnextc (const unsigned char*); +_CRTIMP unsigned char* __cdecl _mbslwr (unsigned char*); +_CRTIMP unsigned char* __cdecl _mbsupr (unsigned char*); +_CRTIMP unsigned char* __cdecl _mbstok (unsigned char*, const unsigned char*); + +/* Kanji */ +_CRTIMP int __cdecl _ismbchira (unsigned int); +_CRTIMP int __cdecl _ismbckata (unsigned int); +_CRTIMP int __cdecl _ismbcl0 (unsigned int); +_CRTIMP int __cdecl _ismbcl1 (unsigned int); +_CRTIMP int __cdecl _ismbcl2 (unsigned int); +_CRTIMP unsigned int __cdecl _mbcjistojms (unsigned int); +_CRTIMP unsigned int __cdecl _mbcjmstojis (unsigned int); +_CRTIMP unsigned int __cdecl _mbctohira (unsigned int); +_CRTIMP unsigned int __cdecl _mbctokata (unsigned int); + +#endif /* Not strict ANSI */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ +#endif /* Not _MBSTRING_H_ */ + + diff --git a/reactos/lib/mingw/include/mem.h b/reactos/lib/mingw/include/mem.h new file mode 100644 index 00000000000..451de0cd47e --- /dev/null +++ b/reactos/lib/mingw/include/mem.h @@ -0,0 +1,6 @@ +/* + * This file is part of the Mingw32 package. + * + * mem.h maps to string.h + */ +#include diff --git a/reactos/lib/mingw/include/memory.h b/reactos/lib/mingw/include/memory.h new file mode 100644 index 00000000000..9ba65cf690e --- /dev/null +++ b/reactos/lib/mingw/include/memory.h @@ -0,0 +1,7 @@ +/* + * This file is part of the Mingw32 package. + * + * memory.h maps to the standard string.h header. + */ + +#include diff --git a/reactos/lib/mingw/include/process.h b/reactos/lib/mingw/include/process.h new file mode 100644 index 00000000000..bdc2f0c59d2 --- /dev/null +++ b/reactos/lib/mingw/include/process.h @@ -0,0 +1,138 @@ +/* + * process.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Function calls for spawning child processes. + * + */ + +#ifndef _PROCESS_H_ +#define _PROCESS_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* Includes a definition of _pid_t and pid_t */ +#include + +/* + * Constants for cwait actions. + * Obsolete for Win32. + */ +#define _WAIT_CHILD 0 +#define _WAIT_GRANDCHILD 1 + +#ifndef _NO_OLDNAMES +#define WAIT_CHILD _WAIT_CHILD +#define WAIT_GRANDCHILD _WAIT_GRANDCHILD +#endif /* Not _NO_OLDNAMES */ + +/* + * Mode constants for spawn functions. + */ +#define _P_WAIT 0 +#define _P_NOWAIT 1 +#define _P_OVERLAY 2 +#define _OLD_P_OVERLAY _P_OVERLAY +#define _P_NOWAITO 3 +#define _P_DETACH 4 + +#ifndef _NO_OLDNAMES +#define P_WAIT _P_WAIT +#define P_NOWAIT _P_NOWAIT +#define P_OVERLAY _P_OVERLAY +#define OLD_P_OVERLAY _OLD_P_OVERLAY +#define P_NOWAITO _P_NOWAITO +#define P_DETACH _P_DETACH +#endif /* Not _NO_OLDNAMES */ + + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP void __cdecl _cexit(void); +_CRTIMP void __cdecl _c_exit(void); + +_CRTIMP int __cdecl _cwait (int*, _pid_t, int); + +_CRTIMP _pid_t __cdecl _getpid(void); + +_CRTIMP int __cdecl _execl (const char*, const char*, ...); +_CRTIMP int __cdecl _execle (const char*, const char*, ...); +_CRTIMP int __cdecl _execlp (const char*, const char*, ...); +_CRTIMP int __cdecl _execlpe (const char*, const char*, ...); +_CRTIMP int __cdecl _execv (const char*, const char* const*); +_CRTIMP int __cdecl _execve (const char*, const char* const*, const char* const*); +_CRTIMP int __cdecl _execvp (const char*, const char* const*); +_CRTIMP int __cdecl _execvpe (const char*, const char* const*, const char* const*); + +_CRTIMP int __cdecl _spawnl (int, const char*, const char*, ...); +_CRTIMP int __cdecl _spawnle (int, const char*, const char*, ...); +_CRTIMP int __cdecl _spawnlp (int, const char*, const char*, ...); +_CRTIMP int __cdecl _spawnlpe (int, const char*, const char*, ...); +_CRTIMP int __cdecl _spawnv (int, const char*, const char* const*); +_CRTIMP int __cdecl _spawnve (int, const char*, const char* const*, const char* const*); +_CRTIMP int __cdecl _spawnvp (int, const char*, const char* const*); +_CRTIMP int __cdecl _spawnvpe (int, const char*, const char* const*, const char* const*); + + +/* + * The functions _beginthreadex and _endthreadex are not provided by CRTDLL. + * They are provided by MSVCRT. + * + * NOTE: Apparently _endthread calls CloseHandle on the handle of the thread, + * making for race conditions if you are not careful. Basically you have to + * make sure that no-one is going to do *anything* with the thread handle + * after the thread calls _endthread or returns from the thread function. + * + * NOTE: No old names for these functions. Use the underscore. + */ +_CRTIMP unsigned long __cdecl + _beginthread (void (*)(void *), unsigned, void*); +_CRTIMP void __cdecl _endthread (void); + +#ifdef __MSVCRT__ +_CRTIMP unsigned long __cdecl + _beginthreadex (void *, unsigned, unsigned (__stdcall *) (void *), + void*, unsigned, unsigned*); +_CRTIMP void __cdecl _endthreadex (unsigned); +#endif + + +#ifndef _NO_OLDNAMES +/* + * Functions without the leading underscore, for portability. These functions + * live in liboldnames.a. + */ +_CRTIMP int __cdecl cwait (int*, pid_t, int); +_CRTIMP pid_t __cdecl getpid (void); +_CRTIMP int __cdecl execl (const char*, const char*, ...); +_CRTIMP int __cdecl execle (const char*, const char*, ...); +_CRTIMP int __cdecl execlp (const char*, const char*, ...); +_CRTIMP int __cdecl execlpe (const char*, const char*, ...); +_CRTIMP int __cdecl execv (const char*, const char* const*); +_CRTIMP int __cdecl execve (const char*, const char* const*, const char* const*); +_CRTIMP int __cdecl execvp (const char*, const char* const*); +_CRTIMP int __cdecl execvpe (const char*, const char* const*, const char* const*); +_CRTIMP int __cdecl spawnl (int, const char*, const char*, ...); +_CRTIMP int __cdecl spawnle (int, const char*, const char*, ...); +_CRTIMP int __cdecl spawnlp (int, const char*, const char*, ...); +_CRTIMP int __cdecl spawnlpe (int, const char*, const char*, ...); +_CRTIMP int __cdecl spawnv (int, const char*, const char* const*); +_CRTIMP int __cdecl spawnve (int, const char*, const char* const*, const char* const*); +_CRTIMP int __cdecl spawnvp (int, const char*, const char* const*); +_CRTIMP int __cdecl spawnvpe (int, const char*, const char* const*, const char* const*); +#endif /* Not _NO_OLDNAMES */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* _PROCESS_H_ not defined */ diff --git a/reactos/lib/mingw/include/search.h b/reactos/lib/mingw/include/search.h new file mode 100644 index 00000000000..2d7768b53a8 --- /dev/null +++ b/reactos/lib/mingw/include/search.h @@ -0,0 +1,64 @@ +/* + * search.h + * + * Functions for searching and sorting. + * + * This file is part of the Mingw32 package. + * + * Contributors: + * Created by Danny Smith + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef _SEARCH_H_ +#define _SEARCH_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _SIZE_T_DEFINED +typedef unsigned int size_t; +#define _SIZE_T_DEFINED +#endif + +/* bsearch and qsort are also declared in stdlib.h */ +_CRTIMP void* __cdecl bsearch (const void*, const void*, size_t, size_t, + int (*)(const void*, const void*)); +_CRTIMP void __cdecl qsort (void*, size_t, size_t, + int (*)(const void*, const void*)); + +_CRTIMP void* __cdecl _lfind (const void*, const void*, unsigned int*, + unsigned int, int (*)(const void*, const void*)); +_CRTIMP void* __cdecl _lsearch (const void*, void*, unsigned int*, unsigned int, + int (*)(const void*, const void*)); + +#ifndef _NO_OLDNAMES +_CRTIMP void* __cdecl lfind (const void*, const void*, unsigned int*, + unsigned int, int (*)(const void*, const void*)); +_CRTIMP void* __cdecl lsearch (const void*, void*, unsigned int*, unsigned int, + int (*)(const void*, const void*)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* RC_INVOKED */ + +#endif /* _SEARCH_H_ */ diff --git a/reactos/lib/mingw/include/setjmp.h b/reactos/lib/mingw/include/setjmp.h new file mode 100644 index 00000000000..38bb62a0e66 --- /dev/null +++ b/reactos/lib/mingw/include/setjmp.h @@ -0,0 +1,56 @@ +/* + * setjmp.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Declarations supporting setjmp and longjump, a method for avoiding + * the normal function call return sequence. (Bleah!) + * + */ + +#ifndef _SETJMP_H_ +#define _SETJMP_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The buffer used by setjmp to store the information used by longjmp + * to perform it's evil goto-like work. The size of this buffer was + * determined through experimentation; it's contents are a mystery. + * NOTE: This was determined on an i386 (actually a Pentium). The + * contents could be different on an Alpha or something else. + */ +#define _JBLEN 16 +#define _JBTYPE int +typedef _JBTYPE jmp_buf[_JBLEN]; + +/* + * The function provided by CRTDLL which appears to do the actual work + * of setjmp. + */ +_CRTIMP int __cdecl _setjmp (jmp_buf); + +#define setjmp(x) _setjmp(x) + +/* + * Return to the last setjmp call and act as if setjmp had returned + * nVal (which had better be non-zero!). + */ +_CRTIMP void __cdecl longjmp (jmp_buf, int) __MINGW_ATTRIB_NORETURN; + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _SETJMP_H_ */ + diff --git a/reactos/lib/mingw/include/share.h b/reactos/lib/mingw/include/share.h new file mode 100644 index 00000000000..09a54ad284f --- /dev/null +++ b/reactos/lib/mingw/include/share.h @@ -0,0 +1,33 @@ +/* + * share.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Constants for file sharing functions. + * + */ + +#ifndef _SHARE_H_ +#define _SHARE_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define _SH_COMPAT 0x00 /* Compatibility */ +#define _SH_DENYRW 0x10 /* Deny read/write */ +#define _SH_DENYWR 0x20 /* Deny write */ +#define _SH_DENYRD 0x30 /* Deny read */ +#define _SH_DENYNO 0x40 /* Deny nothing */ + +#ifndef _NO_OLDNAMES + +/* Non ANSI names */ +#define SH_DENYRW _SH_DENYRW +#define SH_DENYWR _SH_DENYWR +#define SH_DENYRD _SH_DENYRD +#define SH_DENYNO _SH_DENYNO + +#endif /* Not _NO_OLDNAMES */ + +#endif /* Not _SHARE_H_ */ diff --git a/reactos/lib/mingw/include/signal.h b/reactos/lib/mingw/include/signal.h new file mode 100644 index 00000000000..887150d81f3 --- /dev/null +++ b/reactos/lib/mingw/include/signal.h @@ -0,0 +1,98 @@ +/* + * signal.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * A way to set handlers for exceptional conditions (also known as signals). + * + */ + +#ifndef _SIGNAL_H_ +#define _SIGNAL_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* + * The actual signal values. Using other values with signal + * produces a SIG_ERR return value. + * + * NOTE: SIGINT is produced when the user presses Ctrl-C. + * SIGILL has not been tested. + * SIGFPE doesn't seem to work? + * SIGSEGV does not catch writing to a NULL pointer (that shuts down + * your app; can you say "segmentation violation core dump"?). + * SIGTERM comes from what kind of termination request exactly? + * SIGBREAK is indeed produced by pressing Ctrl-Break. + * SIGABRT is produced by calling abort. + * TODO: The above results may be related to not installing an appropriate + * structured exception handling frame. Results may be better if I ever + * manage to get the SEH stuff down. + */ +#define SIGINT 2 /* Interactive attention */ +#define SIGILL 4 /* Illegal instruction */ +#define SIGFPE 8 /* Floating point error */ +#define SIGSEGV 11 /* Segmentation violation */ +#define SIGTERM 15 /* Termination request */ +#define SIGBREAK 21 /* Control-break */ +#define SIGABRT 22 /* Abnormal termination (abort) */ + +#define NSIG 23 /* maximum signal number + 1 */ + +#ifndef RC_INVOKED + +#ifndef _SIG_ATOMIC_T_DEFINED +typedef int sig_atomic_t; +#define _SIG_ATOMIC_T_DEFINED +#endif + +/* + * The prototypes (below) are the easy part. The hard part is figuring + * out what signals are available and what numbers they are assigned + * along with appropriate values of SIG_DFL and SIG_IGN. + */ + +/* + * A pointer to a signal handler function. A signal handler takes a + * single int, which is the signal it handles. + */ +typedef void (*__p_sig_fn_t)(int); + +/* + * These are special values of signal handler pointers which are + * used to send a signal to the default handler (SIG_DFL), ignore + * the signal (SIG_IGN), indicate an error return (SIG_ERR), + * get an error (SIG_SGE), or acknowledge (SIG_ACK). + */ +#define SIG_DFL ((__p_sig_fn_t) 0) +#define SIG_IGN ((__p_sig_fn_t) 1) +#define SIG_ERR ((__p_sig_fn_t) -1) +#define SIG_SGE ((__p_sig_fn_t) 3) +#define SIG_ACK ((__p_sig_fn_t) 4) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Call signal to set the signal handler for signal sig to the + * function pointed to by handler. Returns a pointer to the + * previous handler, or SIG_ERR if an error occurs. Initially + * unhandled signals defined above will return SIG_DFL. + */ +_CRTIMP __p_sig_fn_t __cdecl signal(int, __p_sig_fn_t); + +/* + * Raise the signal indicated by sig. Returns non-zero on success. + */ +_CRTIMP int __cdecl raise (int); + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _SIGNAL_H_ */ + diff --git a/reactos/lib/mingw/include/stdint.h b/reactos/lib/mingw/include/stdint.h new file mode 100644 index 00000000000..5241d48b3a2 --- /dev/null +++ b/reactos/lib/mingw/include/stdint.h @@ -0,0 +1,184 @@ +/* ISO C9x 7.18 Integer types + * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794) + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * Contributor: Danny Smith + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Date: 2000-12-02 + */ + + +#ifndef _STDINT_H +#define _STDINT_H +#define __need_wint_t +#define __need_wchar_t +#include + +/* 7.18.1.1 Exact-width integer types */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned uint32_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; + +/* 7.18.1.2 Minimum-width integer types */ +typedef signed char int_least8_t; +typedef unsigned char uint_least8_t; +typedef short int_least16_t; +typedef unsigned short uint_least16_t; +typedef int int_least32_t; +typedef unsigned uint_least32_t; +typedef long long int_least64_t; +typedef unsigned long long uint_least64_t; + +/* 7.18.1.3 Fastest minimum-width integer types + * Not actually guaranteed to be fastest for all purposes + * Here we use the exact-width types for 8 and 16-bit ints. + */ +typedef char int_fast8_t; +typedef unsigned char uint_fast8_t; +typedef short int_fast16_t; +typedef unsigned short uint_fast16_t; +typedef int int_fast32_t; +typedef unsigned int uint_fast32_t; +typedef long long int_fast64_t; +typedef unsigned long long uint_fast64_t; + +/* 7.18.1.4 Integer types capable of holding object pointers */ +typedef int intptr_t; +typedef unsigned uintptr_t; + +/* 7.18.1.5 Greatest-width integer types */ +typedef long long intmax_t; +typedef unsigned long long uintmax_t; + +/* 7.18.2 Limits of specified-width integer types */ +#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS) + +/* 7.18.2.1 Limits of exact-width integer types */ +#define INT8_MIN (-128) +#define INT16_MIN (-32768) +#define INT32_MIN (-2147483647 - 1) +#define INT64_MIN (-9223372036854775807LL - 1) + +#define INT8_MAX 127 +#define INT16_MAX 32767 +#define INT32_MAX 2147483647 +#define INT64_MAX 9223372036854775807LL + +#define UINT8_MAX 0xff /* 255U */ +#define UINT16_MAX 0xffff /* 65535U */ +#define UINT32_MAX 0xffffffff /* 4294967295U */ +#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ + +/* 7.18.2.2 Limits of minimum-width integer types */ +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +/* 7.18.2.3 Limits of fastest minimum-width integer types */ +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST64_MIN INT64_MIN + +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MAX INT64_MAX + +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +/* 7.18.2.4 Limits of integer types capable of holding + object pointers */ +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX + +/* 7.18.2.5 Limits of greatest-width integer types */ +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +/* 7.18.3 Limits of other integer types */ +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX + +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +#define SIZE_MAX UINT32_MAX + +#ifndef WCHAR_MIN /* also in wchar.h */ +#define WCHAR_MIN 0 +#define WCHAR_MAX 0xffff /* UINT16_MAX */ +#endif + +/* + * wint_t is unsigned short for compatibility with MS runtime + */ +#define WINT_MIN 0 +#define WINT_MAX 0xffff /* UINT16_MAX */ + +#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */ + + +/* 7.18.4 Macros for integer constants */ +#if !defined ( __cplusplus) || defined (__STDC_CONSTANT_MACROS) + +/* 7.18.4.1 Macros for minimum-width integer constants + + Accoding to Douglas Gwyn : + "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC + 9899:1999 as initially published, the expansion was required + to be an integer constant of precisely matching type, which + is impossible to accomplish for the shorter types on most + platforms, because C99 provides no standard way to designate + an integer constant with width less than that of type int. + TC1 changed this to require just an integer constant + *expression* with *promoted* type." +*/ + +#define INT8_C(val) ((int8_t) + (val)) +#define UINT8_C(val) ((uint8_t) + (val##U)) +#define INT16_C(val) ((int16_t) + (val)) +#define UINT16_C(val) ((uint16_t) + (val##U)) + +#define INT32_C(val) val##L +#define UINT32_C(val) val##UL +#define INT64_C(val) val##LL +#define UINT64_C(val) val##ULL + +/* 7.18.4.2 Macros for greatest-width integer constants */ +#define INTMAX_C(val) INT64_C(val) +#define UINTMAX_C(val) UINT64_C(val) + +#endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */ + +#endif diff --git a/reactos/lib/mingw/include/stdio.h b/reactos/lib/mingw/include/stdio.h new file mode 100644 index 00000000000..a7070101c39 --- /dev/null +++ b/reactos/lib/mingw/include/stdio.h @@ -0,0 +1,509 @@ +/* + * stdio.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Definitions of types and prototypes of functions for standard input and + * output. + * + * NOTE: The file manipulation functions provided by Microsoft seem to + * work with either slash (/) or backslash (\) as the directory separator. + * + */ + +#ifndef _STDIO_H_ +#define _STDIO_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#ifndef RC_INVOKED +#define __need_size_t +#define __need_NULL +#define __need_wchar_t +#define __need_wint_t +#include +#define __need___va_list +#include +#endif /* Not RC_INVOKED */ + + +/* Flags for the iobuf structure */ +#define _IOREAD 1 /* currently reading */ +#define _IOWRT 2 /* currently writing */ +#define _IORW 0x0080 /* opened as "r+w" */ + + +/* + * The three standard file pointers provided by the run time library. + * NOTE: These will go to the bit-bucket silently in GUI applications! + */ +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +/* Returned by various functions on end of file condition or error. */ +#define EOF (-1) + +/* + * The maximum length of a file name. You should use GetVolumeInformation + * instead of this constant. But hey, this works. + * Also defined in io.h. + */ +#ifndef FILENAME_MAX +#define FILENAME_MAX (260) +#endif + +/* + * The maximum number of files that may be open at once. I have set this to + * a conservative number. The actual value may be higher. + */ +#define FOPEN_MAX (20) + +/* After creating this many names, tmpnam and tmpfile return NULL */ +#define TMP_MAX 32767 +/* + * Tmpnam, tmpfile and, sometimes, _tempnam try to create + * temp files in the root directory of the current drive + * (not in pwd, as suggested by some older MS doc's). + * Redefining these macros does not effect the CRT functions. + */ +#define _P_tmpdir "\\" +#ifndef __STRICT_ANSI__ +#define P_tmpdir _P_tmpdir +#endif +#define _wP_tmpdir L"\\" + +/* + * The maximum size of name (including NUL) that will be put in the user + * supplied buffer caName for tmpnam. + * Inferred from the size of the static buffer returned by tmpnam + * when passed a NULL argument. May actually be smaller. + */ +#define L_tmpnam (16) + +#define _IOFBF 0x0000 /* full buffered */ +#define _IOLBF 0x0040 /* line buffered */ +#define _IONBF 0x0004 /* not buffered */ + +#define _IOMYBUF 0x0008 /* stdio malloc()'d buffer */ +#define _IOEOF 0x0010 /* EOF reached on read */ +#define _IOERR 0x0020 /* I/O error from system */ +#define _IOSTRG 0x0040 /* Strange or no file descriptor */ +#ifdef _POSIX_SOURCE +# define _IOAPPEND 0x0200 +#endif +/* + * The buffer size as used by setbuf such that it is equivalent to + * (void) setvbuf(fileSetBuffer, caBuffer, _IOFBF, BUFSIZ). + */ +#define BUFSIZ 512 + +/* Constants for nOrigin indicating the position relative to which fseek + * sets the file position. Enclosed in ifdefs because io.h could also + * define them. (Though not anymore since io.h includes this file now.) */ +#ifndef SEEK_SET +#define SEEK_SET (0) +#endif + +#ifndef SEEK_CUR +#define SEEK_CUR (1) +#endif + +#ifndef SEEK_END +#define SEEK_END (2) +#endif + + +#ifndef RC_INVOKED + +#ifndef __VALIST +#ifdef __GNUC__ +#define __VALIST __gnuc_va_list +#else +#define __VALIST char* +#endif +#endif /* defined __VALIST */ + +/* + * The structure underlying the FILE type. + * + * Some believe that nobody in their right mind should make use of the + * internals of this structure. Provided by Pedro A. Aranda Gutiirrez + * . + */ +#ifndef _FILE_DEFINED +#define _FILE_DEFINED +typedef struct _iobuf +{ + char* _ptr; + int _cnt; + char* _base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char* _tmpfname; +} FILE; +#endif /* Not _FILE_DEFINED */ + + +/* + * The standard file handles + */ +#ifndef __DECLSPEC_SUPPORTED + +extern FILE (*_imp___iob)[]; /* A pointer to an array of FILE */ + +#define _iob (*_imp___iob) /* An array of FILE */ + +#else /* __DECLSPEC_SUPPORTED */ + +__MINGW_IMPORT FILE _iob[]; /* An array of FILE imported from DLL. */ + +#endif /* __DECLSPEC_SUPPORTED */ + +#define stdin (&_iob[STDIN_FILENO]) +#define stdout (&_iob[STDOUT_FILENO]) +#define stderr (&_iob[STDERR_FILENO]) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * File Operations + */ +_CRTIMP FILE* __cdecl fopen (const char*, const char*); +_CRTIMP FILE* __cdecl freopen (const char*, const char*, FILE*); +_CRTIMP int __cdecl fflush (FILE*); +_CRTIMP int __cdecl fclose (FILE*); +/* MS puts remove & rename (but not wide versions) in io.h also */ +_CRTIMP int __cdecl remove (const char*); +_CRTIMP int __cdecl rename (const char*, const char*); +_CRTIMP FILE* __cdecl tmpfile (void); +_CRTIMP char* __cdecl tmpnam (char*); + +#ifndef __STRICT_ANSI__ +_CRTIMP char* __cdecl _tempnam (const char*, const char*); +_CRTIMP int __cdecl _rmtmp(void); + +#ifndef NO_OLDNAMES +_CRTIMP char* __cdecl tempnam (const char*, const char*); +_CRTIMP int __cdecl rmtmp(void); +#endif +#endif /* __STRICT_ANSI__ */ + +_CRTIMP int __cdecl setvbuf (FILE*, char*, int, size_t); + +_CRTIMP void __cdecl setbuf (FILE*, char*); + +/* + * Formatted Output + */ + +_CRTIMP int __cdecl fprintf (FILE*, const char*, ...); +_CRTIMP int __cdecl printf (const char*, ...); +_CRTIMP int __cdecl sprintf (char*, const char*, ...); +_CRTIMP int __cdecl _snprintf (char*, size_t, const char*, ...); +_CRTIMP int __cdecl vfprintf (FILE*, const char*, __VALIST); +_CRTIMP int __cdecl vprintf (const char*, __VALIST); +_CRTIMP int __cdecl vsprintf (char*, const char*, __VALIST); +_CRTIMP int __cdecl _vsnprintf (char*, size_t, const char*, __VALIST); + +#ifndef __NO_ISOCEXT /* externs in libmingwex.a */ +int __cdecl snprintf(char* s, size_t n, const char* format, ...); +__CRT_INLINE int __cdecl +vsnprintf (char* s, size_t n, const char* format, __VALIST arg) + { return _vsnprintf ( s, n, format, arg); } +int __cdecl vscanf (const char * __restrict__, __VALIST); +int __cdecl vfscanf (FILE * __restrict__, const char * __restrict__, + __VALIST); +int __cdecl vsscanf (const char * __restrict__, + const char * __restrict__, __VALIST); +#endif + +/* + * Formatted Input + */ + +_CRTIMP int __cdecl fscanf (FILE*, const char*, ...); +_CRTIMP int __cdecl scanf (const char*, ...); +_CRTIMP int __cdecl sscanf (const char*, const char*, ...); +/* + * Character Input and Output Functions + */ + +_CRTIMP int __cdecl fgetc (FILE*); +_CRTIMP char* __cdecl fgets (char*, int, FILE*); +_CRTIMP int __cdecl fputc (int, FILE*); +_CRTIMP int __cdecl fputs (const char*, FILE*); +_CRTIMP char* __cdecl gets (char*); +_CRTIMP int __cdecl puts (const char*); +_CRTIMP int __cdecl ungetc (int, FILE*); + +/* Traditionally, getc and putc are defined as macros. but the + standard doesn't say that they must be macros. + We use inline functions here to allow the fast versions + to be used in C++ with namespace qualification, eg., ::getc. + + _filbuf and _flsbuf are not thread-safe. */ +_CRTIMP int __cdecl _filbuf (FILE*); +_CRTIMP int __cdecl _flsbuf (int, FILE*); + +#if !defined _MT + +__CRT_INLINE int __cdecl getc (FILE* __F) +{ + return (--__F->_cnt >= 0) + ? (int) (unsigned char) *__F->_ptr++ + : _filbuf (__F); +} + +__CRT_INLINE int __cdecl putc (int __c, FILE* __F) +{ + return (--__F->_cnt >= 0) + ? (int) (unsigned char) (*__F->_ptr++ = (char)__c) + : _flsbuf (__c, __F); +} + +__CRT_INLINE int __cdecl getchar (void) +{ + return (--stdin->_cnt >= 0) + ? (int) (unsigned char) *stdin->_ptr++ + : _filbuf (stdin); +} + +__CRT_INLINE int __cdecl putchar(int __c) +{ + return (--stdout->_cnt >= 0) + ? (int) (unsigned char) (*stdout->_ptr++ = (char)__c) + : _flsbuf (__c, stdout);} + +#else /* Use library functions. */ + +_CRTIMP int __cdecl getc (FILE*); +_CRTIMP int __cdecl putc (int, FILE*); +_CRTIMP int __cdecl getchar (void); +_CRTIMP int __cdecl putchar (int); + +#endif + +/* + * Direct Input and Output Functions + */ + +_CRTIMP size_t __cdecl fread (void*, size_t, size_t, FILE*); +_CRTIMP size_t __cdecl fwrite (const void*, size_t, size_t, FILE*); + +/* + * File Positioning Functions + */ + +_CRTIMP int __cdecl fseek (FILE*, long, int); +_CRTIMP long __cdecl ftell (FILE*); +_CRTIMP void __cdecl rewind (FILE*); + +#ifdef __USE_MINGW_FSEEK /* These are in libmingwex.a */ +/* + * Workaround for limitations on win9x where a file contents are + * not zero'd out if you seek past the end and then write. + */ + +int __cdecl __mingw_fseek (FILE *, long, int); +size_t __cdecl __mingw_fwrite (const void*, size_t, size_t, FILE*); +#define fseek(fp, offset, whence) __mingw_fseek(fp, offset, whence) +#define fwrite(buffer, size, count, fp) __mingw_fwrite(buffer, size, count, fp) +#endif /* __USE_MINGW_FSEEK */ + +/* + * An opaque data type used for storing file positions... The contents of + * this type are unknown, but we (the compiler) need to know the size + * because the programmer using fgetpos and fsetpos will be setting aside + * storage for fpos_t structres. Actually I tested using a byte array and + * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL). + * Perhaps an unsigned long? TODO? It's definitely a 64-bit number in + * MSVCRT however, and for now `long long' will do. + */ +#ifdef __MSVCRT__ +typedef long long fpos_t; +#else +typedef long fpos_t; +#endif + +_CRTIMP int __cdecl fgetpos (FILE*, fpos_t*); +_CRTIMP int __cdecl fsetpos (FILE*, const fpos_t*); + +/* + * Error Functions + */ + +_CRTIMP int __cdecl feof (FILE*); +_CRTIMP int __cdecl ferror (FILE*); + +#ifdef __cplusplus +inline int __cdecl feof (FILE* __F) + { return __F->_flag & _IOEOF; } +inline int __cdecl ferror (FILE* __F) + { return __F->_flag & _IOERR; } +#else +#define feof(__F) ((__F)->_flag & _IOEOF) +#define ferror(__F) ((__F)->_flag & _IOERR) +#endif + +_CRTIMP void __cdecl clearerr (FILE*); +_CRTIMP void __cdecl perror (const char*); + + +#ifndef __STRICT_ANSI__ +/* + * Pipes + */ +_CRTIMP FILE* __cdecl _popen (const char*, const char*); +_CRTIMP int __cdecl _pclose (FILE*); + +#ifndef NO_OLDNAMES +_CRTIMP FILE* __cdecl popen (const char*, const char*); +_CRTIMP int __cdecl pclose (FILE*); +#endif + +/* + * Other Non ANSI functions + */ +_CRTIMP int __cdecl _flushall (void); +_CRTIMP int __cdecl _fgetchar (void); +_CRTIMP int __cdecl _fputchar (int); +_CRTIMP FILE* __cdecl _fdopen (int, const char*); +_CRTIMP int __cdecl _fileno (FILE*); +_CRTIMP int __cdecl _fcloseall(void); +_CRTIMP FILE* __cdecl _fsopen(const char*, const char*, int); +#ifdef __MSVCRT__ +_CRTIMP int __cdecl _getmaxstdio(void); +_CRTIMP int __cdecl _setmaxstdio(int); +#endif + +#ifndef _NO_OLDNAMES +_CRTIMP int __cdecl fgetchar (void); +_CRTIMP int __cdecl fputchar (int); +_CRTIMP FILE* __cdecl fdopen (int, const char*); +_CRTIMP int __cdecl fileno (FILE*); +#endif /* Not _NO_OLDNAMES */ + +#define _fileno(__F) ((__F)->_file) +#ifndef _NO_OLDNAMES +#define fileno(__F) ((__F)->_file) +#endif + +#if defined (__MSVCRT__) && !defined (__NO_MINGW_LFS) +#include +__CRT_INLINE FILE* __cdecl fopen64 (const char* filename, const char* mode) +{ + return fopen (filename, mode); +} + +int __cdecl fseeko64 (FILE*, off64_t, int); + +#ifdef __USE_MINGW_FSEEK +int __cdecl __mingw_fseeko64 (FILE *, off64_t, int); +#define fseeko64(fp, offset, whence) __mingw_fseeko64(fp, offset, whence) +#endif + +__CRT_INLINE off64_t __cdecl ftello64 (FILE * stream) +{ + fpos_t pos; + if (fgetpos(stream, &pos)) + return -1LL; + else + return ((off64_t) pos); +} +#endif /* __NO_MINGW_LFS */ + +#endif /* Not __STRICT_ANSI__ */ + +/* Wide versions */ + +#ifndef _WSTDIO_DEFINED +/* also in wchar.h - keep in sync */ +_CRTIMP int __cdecl fwprintf (FILE*, const wchar_t*, ...); +_CRTIMP int __cdecl wprintf (const wchar_t*, ...); +_CRTIMP int __cdecl swprintf (wchar_t*, const wchar_t*, ...); +_CRTIMP int __cdecl _snwprintf (wchar_t*, size_t, const wchar_t*, ...); +_CRTIMP int __cdecl vfwprintf (FILE*, const wchar_t*, __VALIST); +_CRTIMP int __cdecl vwprintf (const wchar_t*, __VALIST); +_CRTIMP int __cdecl vswprintf (wchar_t*, const wchar_t*, __VALIST); +_CRTIMP int __cdecl _vsnwprintf (wchar_t*, size_t, const wchar_t*, __VALIST); +_CRTIMP int __cdecl fwscanf (FILE*, const wchar_t*, ...); +_CRTIMP int __cdecl wscanf (const wchar_t*, ...); +_CRTIMP int __cdecl swscanf (const wchar_t*, const wchar_t*, ...); +_CRTIMP wint_t __cdecl fgetwc (FILE*); +_CRTIMP wint_t __cdecl fputwc (wchar_t, FILE*); +_CRTIMP wint_t __cdecl ungetwc (wchar_t, FILE*); + +#ifdef __MSVCRT__ +_CRTIMP wchar_t* __cdecl fgetws (wchar_t*, int, FILE*); +_CRTIMP int __cdecl fputws (const wchar_t*, FILE*); +_CRTIMP wint_t __cdecl getwc (FILE*); +_CRTIMP wint_t __cdecl getwchar (void); +_CRTIMP wchar_t* __cdecl _getws (wchar_t*); +_CRTIMP wint_t __cdecl putwc (wint_t, FILE*); +_CRTIMP int __cdecl _putws (const wchar_t*); +_CRTIMP wint_t __cdecl putwchar (wint_t); +_CRTIMP FILE* __cdecl _wfdopen(int, wchar_t *); +_CRTIMP FILE* __cdecl _wfopen (const wchar_t*, const wchar_t*); +_CRTIMP FILE* __cdecl _wfreopen (const wchar_t*, const wchar_t*, FILE*); +_CRTIMP FILE* __cdecl _wfsopen (const wchar_t*, const wchar_t*, int); +_CRTIMP wchar_t* __cdecl _wtmpnam (wchar_t*); +_CRTIMP wchar_t* __cdecl _wtempnam (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl _wrename (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl _wremove (const wchar_t*); +_CRTIMP void __cdecl _wperror (const wchar_t*); +_CRTIMP FILE* __cdecl _wpopen (const wchar_t*, const wchar_t*); +#endif /* __MSVCRT__ */ + +#ifndef __NO_ISOCEXT /* externs in libmingwex.a */ +int __cdecl snwprintf (wchar_t* s, size_t n, const wchar_t* format, ...); +__CRT_INLINE int __cdecl +vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, __VALIST arg) + { return _vsnwprintf ( s, n, format, arg);} +int __cdecl vwscanf (const wchar_t * __restrict__, __VALIST); +int __cdecl vfwscanf (FILE * __restrict__, + const wchar_t * __restrict__, __VALIST); +int __cdecl vswscanf (const wchar_t * __restrict__, + const wchar_t * __restrict__, __VALIST); +#endif + +#define _WSTDIO_DEFINED +#endif /* _WSTDIO_DEFINED */ + +#ifndef __STRICT_ANSI__ +#ifdef __MSVCRT__ +#ifndef NO_OLDNAMES +_CRTIMP FILE* __cdecl wpopen (const wchar_t*, const wchar_t*); +#endif /* not NO_OLDNAMES */ +#endif /* MSVCRT runtime */ + +/* + * Other Non ANSI wide functions + */ +_CRTIMP wint_t __cdecl _fgetwchar (void); +_CRTIMP wint_t __cdecl _fputwchar (wint_t); +_CRTIMP int __cdecl _getw (FILE*); +_CRTIMP int __cdecl _putw (int, FILE*); + +#ifndef _NO_OLDNAMES +_CRTIMP wint_t __cdecl fgetwchar (void); +_CRTIMP wint_t __cdecl fputwchar (wint_t); +_CRTIMP int __cdecl getw (FILE*); +_CRTIMP int __cdecl putw (int, FILE*); +#endif /* Not _NO_OLDNAMES */ + +#endif /* __STRICT_ANSI */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* _STDIO_H_ */ diff --git a/reactos/lib/mingw/include/stdlib.h b/reactos/lib/mingw/include/stdlib.h new file mode 100644 index 00000000000..07a6b420ce2 --- /dev/null +++ b/reactos/lib/mingw/include/stdlib.h @@ -0,0 +1,524 @@ +/* + * stdlib.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Definitions for common types, variables, and functions. + * + */ + +#ifndef _STDLIB_H_ +#define _STDLIB_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + + +#define __need_size_t +#define __need_wchar_t +#define __need_NULL +#ifndef RC_INVOKED +#include +#endif /* RC_INVOKED */ + +/* + * RAND_MAX is the maximum value that may be returned by rand. + * The minimum is zero. + */ +#define RAND_MAX 0x7FFF + +/* + * These values may be used as exit status codes. + */ +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 + +/* + * Definitions for path name functions. + * NOTE: All of these values have simply been chosen to be conservatively high. + * Remember that with long file names we can no longer depend on + * extensions being short. + */ +#ifndef __STRICT_ANSI__ + +#ifndef MAX_PATH +#define MAX_PATH (260) +#endif + +#define _MAX_PATH MAX_PATH +#define _MAX_DRIVE (3) +#define _MAX_DIR 256 +#define _MAX_FNAME 256 +#define _MAX_EXT 256 + +#endif /* Not __STRICT_ANSI__ */ + + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined (__STRICT_ANSI__) + +/* + * This seems like a convenient place to declare these variables, which + * give programs using WinMain (or main for that matter) access to main-ish + * argc and argv. environ is a pointer to a table of environment variables. + * NOTE: Strings in _argv and environ are ANSI strings. + */ +extern int _argc; +extern char** _argv; + +/* imports from runtime dll of the above variables */ +#ifdef __MSVCRT__ + +extern int* __cdecl __p___argc(void); +extern char*** __cdecl __p___argv(void); +extern wchar_t*** __cdecl __p___wargv(void); + +#define __argc (*__p___argc()) +#define __argv (*__p___argv()) +#define __wargv (*__p___wargv()) + +#else /* !MSVCRT */ + +#ifndef __DECLSPEC_SUPPORTED + +extern int* _imp____argc_dll; +extern char*** _imp____argv_dll; +#define __argc (*_imp____argc_dll) +#define __argv (*_imp____argv_dll) + +#else /* __DECLSPEC_SUPPORTED */ + +__MINGW_IMPORT int __argc_dll; +__MINGW_IMPORT char** __argv_dll; +#define __argc __argc_dll +#define __argv __argv_dll + +#endif /* __DECLSPEC_SUPPORTED */ + +#endif /* __MSVCRT */ +#endif /* __STRICT_ANSI__ */ +/* + * Also defined in ctype.h. + */ +#ifndef MB_CUR_MAX +#ifdef __DECLSPEC_SUPPORTED +# ifdef __MSVCRT__ +# define MB_CUR_MAX __mb_cur_max + __MINGW_IMPORT int __mb_cur_max; +# else /* not __MSVCRT */ +# define MB_CUR_MAX __mb_cur_max_dll + __MINGW_IMPORT int __mb_cur_max_dll; +# endif /* not __MSVCRT */ + +#else /* ! __DECLSPEC_SUPPORTED */ +# ifdef __MSVCRT__ + extern int* _imp____mbcur_max; +# define MB_CUR_MAX (*_imp____mb_cur_max) +# else /* not __MSVCRT */ + extern int* _imp____mbcur_max_dll; +# define MB_CUR_MAX (*_imp____mb_cur_max_dll) +# endif /* not __MSVCRT */ +#endif /* __DECLSPEC_SUPPORTED */ +#endif /* MB_CUR_MAX */ + +/* + * MS likes to declare errno in stdlib.h as well. + */ + +#ifdef _UWIN +#undef errno +extern int errno; +#else + _CRTIMP int* __cdecl _errno(void); +#define errno (*_errno()) +#endif + _CRTIMP int* __cdecl __doserrno(void); +#define _doserrno (*__doserrno()) + +#if !defined (__STRICT_ANSI__) +/* + * Use environ from the DLL, not as a global. + */ + +#ifdef __MSVCRT__ + extern _CRTIMP char *** __cdecl __p__environ(void); + extern _CRTIMP wchar_t *** __cdecl __p__wenviron(void); +# define _environ (*__p__environ()) +# define _wenviron (*__p__wenviron()) +#else /* ! __MSVCRT__ */ +# ifndef __DECLSPEC_SUPPORTED + extern char *** _imp___environ_dll; +# define _environ (*_imp___environ_dll) +# else /* __DECLSPEC_SUPPORTED */ + __MINGW_IMPORT char ** _environ_dll; +# define _environ _environ_dll +# endif /* __DECLSPEC_SUPPORTED */ +#endif /* ! __MSVCRT__ */ + +#define environ _environ + +#ifdef __MSVCRT__ +/* One of the MSVCRTxx libraries */ + +#ifndef __DECLSPEC_SUPPORTED + extern int* _imp___sys_nerr; +# define sys_nerr (*_imp___sys_nerr) +#else /* __DECLSPEC_SUPPORTED */ + __MINGW_IMPORT int _sys_nerr; +# ifndef _UWIN +# define sys_nerr _sys_nerr +# endif /* _UWIN */ +#endif /* __DECLSPEC_SUPPORTED */ + +#else /* ! __MSVCRT__ */ + +/* CRTDLL run time library */ + +#ifndef __DECLSPEC_SUPPORTED + extern int* _imp___sys_nerr_dll; +# define sys_nerr (*_imp___sys_nerr_dll) +#else /* __DECLSPEC_SUPPORTED */ + __MINGW_IMPORT int _sys_nerr_dll; +# define sys_nerr _sys_nerr_dll +#endif /* __DECLSPEC_SUPPORTED */ + +#endif /* ! __MSVCRT__ */ + +#ifndef __DECLSPEC_SUPPORTED +extern char*** _imp__sys_errlist; +#define sys_errlist (*_imp___sys_errlist) +#else /* __DECLSPEC_SUPPORTED */ +__MINGW_IMPORT char* _sys_errlist[]; +#ifndef _UWIN +#define sys_errlist _sys_errlist +#endif /* _UWIN */ +#endif /* __DECLSPEC_SUPPORTED */ + +/* + * OS version and such constants. + */ + +#ifdef __MSVCRT__ +/* msvcrtxx.dll */ + +extern _CRTIMP unsigned __cdecl int* __p__osver(void); +extern _CRTIMP unsigned __cdecl int* __p__winver(void); +extern _CRTIMP unsigned __cdecl int* __p__winmajor(void); +extern _CRTIMP unsigned __cdecl int* __p__winminor(void); + +#ifndef __DECLSPEC_SUPPORTED +# define _osver (*__p__osver()) +# define _winver (*__p__winver()) +# define _winmajor (*__p__winmajor()) +# define _winminor (*__p__winminor()) +#else +__MINGW_IMPORT unsigned int _osver; +__MINGW_IMPORT unsigned int _winver; +__MINGW_IMPORT unsigned int _winmajor; +__MINGW_IMPORT unsigned int _winminor; +#endif /* __DECLSPEC_SUPPORTED */ + +#else +/* Not msvcrtxx.dll, thus crtdll.dll */ + +#ifndef __DECLSPEC_SUPPORTED + +extern unsigned int* _imp___osver_dll; +extern unsigned int* _imp___winver_dll; +extern unsigned int* _imp___winmajor_dll; +extern unsigned int* _imp___winminor_dll; + +#define _osver (*_imp___osver_dll) +#define _winver (*_imp___winver_dll) +#define _winmajor (*_imp___winmajor_dll) +#define _winminor (*_imp___winminor_dll) + +#else /* __DECLSPEC_SUPPORTED */ + +__MINGW_IMPORT unsigned int _osver_dll; +__MINGW_IMPORT unsigned int _winver_dll; +__MINGW_IMPORT unsigned int _winmajor_dll; +__MINGW_IMPORT unsigned int _winminor_dll; + +#define _osver _osver_dll +#define _winver _winver_dll +#define _winmajor _winmajor_dll +#define _winminor _winminor_dll + +#endif /* __DECLSPEC_SUPPORTED */ + +#endif + +#if defined __MSVCRT__ +/* although the _pgmptr is exported as DATA, + * be safe and use the access function __p__pgmptr() to get it. */ +_CRTIMP char** __cdecl __p__pgmptr(void); +#define _pgmptr (*__p__pgmptr()) +_CRTIMP wchar_t** __cdecl __p__wpgmptr(void); +#define _wpgmptr (*__p__wpgmptr()) +#else /* ! __MSVCRT__ */ +# ifndef __DECLSPEC_SUPPORTED + extern char** __imp__pgmptr_dll; +# define _pgmptr (*_imp___pgmptr_dll) +# else /* __DECLSPEC_SUPPORTED */ + __MINGW_IMPORT char* _pgmptr_dll; +# define _pgmptr _pgmptr_dll +# endif /* __DECLSPEC_SUPPORTED */ +/* no wide version in CRTDLL */ +#endif /* __MSVCRT__ */ + +/* + * This variable determines the default file mode. + * TODO: Which flags work? + */ +#if !defined (__DECLSPEC_SUPPORTED) || defined (__IN_MINGW_RUNTIME) + +#ifdef __MSVCRT__ +extern int* _imp___fmode; +#define _fmode (*_imp___fmode) +#else +/* CRTDLL */ +extern int* _imp___fmode_dll; +#define _fmode (*_imp___fmode_dll) +#endif + +#else /* __DECLSPEC_SUPPORTED */ + +#ifdef __MSVCRT__ +__MINGW_IMPORT int _fmode; +#else /* ! __MSVCRT__ */ +__MINGW_IMPORT int _fmode_dll; +#define _fmode _fmode_dll +#endif /* ! __MSVCRT__ */ + +#endif /* __DECLSPEC_SUPPORTED */ + +#endif /* Not __STRICT_ANSI__ */ + +_CRTIMP double __cdecl atof (const char*); +_CRTIMP int __cdecl atoi (const char*); +_CRTIMP long __cdecl atol (const char*); +#if !defined (__STRICT_ANSI__) +_CRTIMP int __cdecl _wtoi (const wchar_t *); +_CRTIMP long __cdecl _wtol (const wchar_t *); +#endif +_CRTIMP double __cdecl strtod (const char*, char**); +#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */ +float __cdecl strtof (const char *, char **); +__CRT_INLINE float __cdecl strtof (const char *__nptr, char **__endptr) + { return (strtod (__nptr, __endptr));} +long double __cdecl strtold (const char * __restrict__, char ** __restrict__); +#endif /* __NO_ISOCEXT */ + +_CRTIMP long __cdecl strtol (const char*, char**, int); +_CRTIMP unsigned long __cdecl strtoul (const char*, char**, int); + +#ifndef _WSTDLIB_DEFINED +/* also declared in wchar.h */ +_CRTIMP double __cdecl wcstod (const wchar_t*, wchar_t**); +#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */ +float __cdecl wcstof( const wchar_t *, wchar_t **); +__CRT_INLINE float __cdecl wcstof( const wchar_t *__nptr, wchar_t **__endptr) +{ return (wcstod(__nptr, __endptr)); } +long double __cdecl wcstold (const wchar_t * __restrict__, wchar_t ** __restrict__); +#endif /* __NO_ISOCEXT */ + +_CRTIMP long __cdecl wcstol (const wchar_t*, wchar_t**, int); +_CRTIMP unsigned long __cdecl wcstoul (const wchar_t*, wchar_t**, int); +#define _WSTDLIB_DEFINED +#endif + +_CRTIMP size_t __cdecl wcstombs (char*, const wchar_t*, size_t); +_CRTIMP int __cdecl wctomb (char*, wchar_t); + +_CRTIMP int __cdecl mblen (const char*, size_t); +_CRTIMP size_t __cdecl mbstowcs (wchar_t*, const char*, size_t); +_CRTIMP int __cdecl mbtowc (wchar_t*, const char*, size_t); + +_CRTIMP int __cdecl rand (void); +_CRTIMP void __cdecl srand (unsigned int); + +_CRTIMP void* __cdecl calloc (size_t, size_t) __MINGW_ATTRIB_MALLOC; +_CRTIMP void* __cdecl malloc (size_t) __MINGW_ATTRIB_MALLOC; +_CRTIMP void* __cdecl realloc (void*, size_t); +_CRTIMP void __cdecl free (void*); + +_CRTIMP void __cdecl abort (void) __MINGW_ATTRIB_NORETURN; +_CRTIMP void __cdecl exit (int) __MINGW_ATTRIB_NORETURN; + +/* Note: This is in startup code, not imported directly from dll */ +int __cdecl atexit (void (*)(void)); + +_CRTIMP int __cdecl system (const char*); +_CRTIMP char* __cdecl getenv (const char*); + +/* bsearch and qsort are also in non-ANSI header search.h */ +_CRTIMP void* __cdecl bsearch (const void*, const void*, size_t, size_t, + int (*)(const void*, const void*)); +_CRTIMP void __cdecl qsort (void*, size_t, size_t, + int (*)(const void*, const void*)); + +_CRTIMP int __cdecl abs (int) __MINGW_ATTRIB_CONST; +_CRTIMP long __cdecl labs (long) __MINGW_ATTRIB_CONST; + +/* + * div_t and ldiv_t are structures used to return the results of div and + * ldiv. + * + * NOTE: div and ldiv appear not to work correctly unless + * -fno-pcc-struct-return is specified. This is included in the + * mingw32 specs file. + */ +typedef struct { int quot, rem; } div_t; +typedef struct { long quot, rem; } ldiv_t; + +_CRTIMP div_t __cdecl div (int, int) __MINGW_ATTRIB_CONST; +_CRTIMP ldiv_t __cdecl ldiv (long, long) __MINGW_ATTRIB_CONST; + +#if !defined (__STRICT_ANSI__) + +/* + * NOTE: Officially the three following functions are obsolete. The Win32 API + * functions SetErrorMode, Beep and Sleep are their replacements. + */ +_CRTIMP void __cdecl _beep (unsigned int, unsigned int); +_CRTIMP void __cdecl _seterrormode (int); +_CRTIMP void __cdecl _sleep (unsigned long); + +_CRTIMP void __cdecl _exit (int) __MINGW_ATTRIB_NORETURN; + +/* _onexit is MS extension. Use atexit for portability. */ +/* Note: This is in startup code, not imported directly from dll */ +typedef int (* _onexit_t)(void); +_onexit_t __cdecl _onexit( _onexit_t ); + +_CRTIMP int __cdecl _putenv (const char*); +_CRTIMP void __cdecl _searchenv (const char*, const char*, char*); + + +_CRTIMP char* __cdecl _ecvt (double, int, int*, int*); +_CRTIMP char* __cdecl _fcvt (double, int, int*, int*); +_CRTIMP char* __cdecl _gcvt (double, int, char*); + +_CRTIMP void __cdecl _makepath (char*, const char*, const char*, const char*, const char*); +_CRTIMP void __cdecl _splitpath (const char*, char*, char*, char*, char*); +_CRTIMP char* __cdecl _fullpath (char*, const char*, size_t); + +_CRTIMP char* __cdecl _itoa (int, char*, int); +_CRTIMP char* __cdecl _ltoa (long, char*, int); +_CRTIMP char* __cdecl _ultoa(unsigned long, char*, int); +_CRTIMP wchar_t* __cdecl _itow (int, wchar_t*, int); +_CRTIMP wchar_t* __cdecl _ltow (long, wchar_t*, int); +_CRTIMP wchar_t* __cdecl _ultow (unsigned long, wchar_t*, int); + +#ifdef __MSVCRT__ +_CRTIMP __int64 __cdecl _atoi64(const char *); +_CRTIMP char* __cdecl _i64toa(__int64, char *, int); +_CRTIMP char* __cdecl _ui64toa(unsigned __int64, char *, int); +_CRTIMP __int64 __cdecl _wtoi64(const wchar_t *); +_CRTIMP wchar_t* __cdecl _i64tow(__int64, wchar_t *, int); +_CRTIMP wchar_t* __cdecl _ui64tow(unsigned __int64, wchar_t *, int); + +_CRTIMP wchar_t* __cdecl _wgetenv(const wchar_t*); +_CRTIMP int __cdecl _wputenv(const wchar_t*); +_CRTIMP void __cdecl _wsearchenv(const wchar_t*, const wchar_t*, wchar_t*); +_CRTIMP void __cdecl _wmakepath(wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*); +_CRTIMP void __cdecl _wsplitpath (const wchar_t*, wchar_t*, wchar_t*, wchar_t*, wchar_t*); +_CRTIMP wchar_t* __cdecl _wfullpath (wchar_t*, const wchar_t*, size_t); + +_CRTIMP unsigned int __cdecl _rotl(unsigned int, int) __MINGW_ATTRIB_CONST; +_CRTIMP unsigned int __cdecl _rotr(unsigned int, int) __MINGW_ATTRIB_CONST; +_CRTIMP unsigned long __cdecl _lrotl(unsigned long, int) __MINGW_ATTRIB_CONST; +_CRTIMP unsigned long __cdecl _lrotr(unsigned long, int) __MINGW_ATTRIB_CONST; + +_CRTIMP int __cdecl _set_error_mode (int); +#define _OUT_TO_DEFAULT 0 +#define _OUT_TO_STDERR 1 +#define _OUT_TO_MSGBOX 2 +#define _REPORT_ERRMODE 3 + +#endif + +#ifndef _NO_OLDNAMES + +_CRTIMP int __cdecl putenv (const char*); +_CRTIMP void __cdecl searchenv (const char*, const char*, char*); + +_CRTIMP char* __cdecl itoa (int, char*, int); +_CRTIMP char* __cdecl ltoa (long, char*, int); + +#ifndef _UWIN +_CRTIMP char* __cdecl ecvt (double, int, int*, int*); +_CRTIMP char* __cdecl fcvt (double, int, int*, int*); +_CRTIMP char* __cdecl gcvt (double, int, char*); +#endif /* _UWIN */ +#endif /* Not _NO_OLDNAMES */ + +#endif /* Not __STRICT_ANSI__ */ + +/* C99 names */ + +#if !defined __NO_ISOCEXT /* externs in static libmingwex.a */ + +/* C99 name for _exit */ +void __cdecl _Exit(int) __MINGW_ATTRIB_NORETURN; +#ifndef __STRICT_ANSI__ /* inline using non-ansi functions */ +__CRT_INLINE void __cdecl _Exit(int __status) + { _exit (__status); } +#endif + +typedef struct { long long quot, rem; } lldiv_t; + +lldiv_t __cdecl lldiv (long long, long long) __MINGW_ATTRIB_CONST; + +long long __cdecl llabs(long long); +__CRT_INLINE long long __cdecl llabs(long long _j) + {return (_j >= 0 ? _j : -_j);} + +long long __cdecl strtoll (const char* __restrict__, char** __restrict, int); +unsigned long long __cdecl strtoull (const char* __restrict__, char** __restrict__, int); + +#if defined (__MSVCRT__) /* these are stubs for MS _i64 versions */ +long long __cdecl atoll (const char *); + +#if !defined (__STRICT_ANSI__) +long long __cdecl wtoll (const wchar_t *); +char* __cdecl lltoa (long long, char *, int); +char* __cdecl ulltoa (unsigned long long , char *, int); +wchar_t* __cdecl lltow (long long, wchar_t *, int); +wchar_t* __cdecl ulltow (unsigned long long, wchar_t *, int); + + /* inline using non-ansi functions */ +__CRT_INLINE long long __cdecl atoll (const char * _c) + { return _atoi64 (_c); } +__CRT_INLINE char* __cdecl lltoa (long long _n, char * _c, int _i) + { return _i64toa (_n, _c, _i); } +__CRT_INLINE char* __cdecl ulltoa (unsigned long long _n, char * _c, int _i) + { return _ui64toa (_n, _c, _i); } +__CRT_INLINE long long __cdecl wtoll (const wchar_t * _w) + { return _wtoi64 (_w); } +__CRT_INLINE wchar_t* __cdecl lltow (long long _n, wchar_t * _w, int _i) + { return _i64tow (_n, _w, _i); } +__CRT_INLINE wchar_t* __cdecl ulltow (unsigned long long _n, wchar_t * _w, int _i) + { return _ui64tow (_n, _w, _i); } +#endif /* (__STRICT_ANSI__) */ + +#endif /* __MSVCRT__ */ + +#endif /* !__NO_ISOCEXT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _STDLIB_H_ */ + diff --git a/reactos/lib/mingw/include/string.h b/reactos/lib/mingw/include/string.h new file mode 100644 index 00000000000..1047e50191f --- /dev/null +++ b/reactos/lib/mingw/include/string.h @@ -0,0 +1,193 @@ +/* + * string.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Definitions for memory and string functions. + * + */ + +#ifndef _STRING_H_ +#define _STRING_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* + * Define size_t, wchar_t and NULL + */ +#define __need_size_t +#define __need_wchar_t +#define __need_NULL +#ifndef RC_INVOKED +#include +#endif /* Not RC_INVOKED */ + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Prototypes of the ANSI Standard C library string functions. + */ +_CRTIMP void* __cdecl memchr (const void*, int, size_t) __MINGW_ATTRIB_PURE; +_CRTIMP int __cdecl memcmp (const void*, const void*, size_t) __MINGW_ATTRIB_PURE; +_CRTIMP void* __cdecl memcpy (void*, const void*, size_t); +_CRTIMP void* __cdecl memmove (void*, const void*, size_t); +_CRTIMP void* __cdecl memset (void*, int, size_t); +_CRTIMP char* __cdecl strcat (char*, const char*); +_CRTIMP char* __cdecl strchr (const char*, int) __MINGW_ATTRIB_PURE; +_CRTIMP int __cdecl strcmp (const char*, const char*) __MINGW_ATTRIB_PURE; +_CRTIMP int __cdecl strcoll (const char*, const char*); /* Compare using locale */ +_CRTIMP char* __cdecl strcpy (char*, const char*); +_CRTIMP size_t __cdecl strcspn (const char*, const char*) __MINGW_ATTRIB_PURE; +_CRTIMP char* __cdecl strerror (int); /* NOTE: NOT an old name wrapper. */ + +_CRTIMP size_t __cdecl strlen (const char*) __MINGW_ATTRIB_PURE; +_CRTIMP char* __cdecl strncat (char*, const char*, size_t); +_CRTIMP int __cdecl strncmp (const char*, const char*, size_t) __MINGW_ATTRIB_PURE; +_CRTIMP char* __cdecl strncpy (char*, const char*, size_t); +_CRTIMP char* __cdecl strpbrk (const char*, const char*) __MINGW_ATTRIB_PURE; +_CRTIMP char* __cdecl strrchr (const char*, int) __MINGW_ATTRIB_PURE; +_CRTIMP size_t __cdecl strspn (const char*, const char*) __MINGW_ATTRIB_PURE; +_CRTIMP char* __cdecl strstr (const char*, const char*) __MINGW_ATTRIB_PURE; +_CRTIMP char* __cdecl strtok (char*, const char*); +_CRTIMP size_t __cdecl strxfrm (char*, const char*, size_t); + +#ifndef __STRICT_ANSI__ +/* + * Extra non-ANSI functions provided by the CRTDLL library + */ +_CRTIMP char* __cdecl _strerror (const char *); +_CRTIMP void* __cdecl _memccpy (void*, const void*, int, size_t); +_CRTIMP int __cdecl _memicmp (const void*, const void*, size_t); +_CRTIMP char* __cdecl _strdup (const char*) __MINGW_ATTRIB_MALLOC; +_CRTIMP int __cdecl _strcmpi (const char*, const char*); +_CRTIMP int __cdecl _stricmp (const char*, const char*); +_CRTIMP int __cdecl _stricoll (const char*, const char*); +_CRTIMP char* __cdecl _strlwr (char*); +_CRTIMP int __cdecl _strnicmp (const char*, const char*, size_t); +_CRTIMP char* __cdecl _strnset (char*, int, size_t); +_CRTIMP char* __cdecl _strrev (char*); +_CRTIMP char* __cdecl _strset (char*, int); +_CRTIMP char* __cdecl _strupr (char*); +_CRTIMP void __cdecl _swab (const char*, char*, size_t); + +#ifdef __MSVCRT__ +_CRTIMP int __cdecl _strncoll(const char*, const char*, size_t); +_CRTIMP int __cdecl _strnicoll(const char*, const char*, size_t); +#endif + +#ifndef _NO_OLDNAMES +/* + * Non-underscored versions of non-ANSI functions. They live in liboldnames.a + * and provide a little extra portability. Also a few extra UNIX-isms like + * strcasecmp. + */ +_CRTIMP void* __cdecl memccpy (void*, const void*, int, size_t); +_CRTIMP int __cdecl memicmp (const void*, const void*, size_t); +_CRTIMP char* __cdecl strdup (const char*) __MINGW_ATTRIB_MALLOC; +_CRTIMP int __cdecl strcmpi (const char*, const char*); +_CRTIMP int __cdecl stricmp (const char*, const char*); +__CRT_INLINE int __cdecl +strcasecmp (const char * __sz1, const char * __sz2) + {return _stricmp (__sz1, __sz2);} +_CRTIMP int __cdecl stricoll (const char*, const char*); +_CRTIMP char* __cdecl strlwr (char*); +_CRTIMP int __cdecl strnicmp (const char*, const char*, size_t); +__CRT_INLINE int __cdecl +strncasecmp (const char * __sz1, const char * __sz2, size_t __sizeMaxCompare) + {return _strnicmp (__sz1, __sz2, __sizeMaxCompare);} +_CRTIMP char* __cdecl strnset (char*, int, size_t); +_CRTIMP char* __cdecl strrev (char*); +_CRTIMP char* __cdecl strset (char*, int); +_CRTIMP char* __cdecl strupr (char*); +#ifndef _UWIN +_CRTIMP void __cdecl swab (const char*, char*, size_t); +#endif /* _UWIN */ +#endif /* _NO_OLDNAMES */ + +#endif /* Not __STRICT_ANSI__ */ + +#ifndef _WSTRING_DEFINED +/* + * Unicode versions of the standard calls. + * Also in wchar.h, where they belong according to ISO standard. + */ +_CRTIMP wchar_t* __cdecl wcscat (wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcschr (const wchar_t*, wchar_t); +_CRTIMP int __cdecl wcscmp (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl wcscoll (const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcscpy (wchar_t*, const wchar_t*); +_CRTIMP size_t __cdecl wcscspn (const wchar_t*, const wchar_t*); +/* Note: _wcserror requires __MSVCRT_VERSION__ >= 0x0700. */ +_CRTIMP size_t __cdecl wcslen (const wchar_t*); +_CRTIMP wchar_t* __cdecl wcsncat (wchar_t*, const wchar_t*, size_t); +_CRTIMP int __cdecl wcsncmp(const wchar_t*, const wchar_t*, size_t); +_CRTIMP wchar_t* __cdecl wcsncpy(wchar_t*, const wchar_t*, size_t); +_CRTIMP wchar_t* __cdecl wcspbrk(const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcsrchr(const wchar_t*, wchar_t); +_CRTIMP size_t __cdecl wcsspn(const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcsstr(const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcstok(wchar_t*, const wchar_t*); +_CRTIMP size_t __cdecl wcsxfrm(wchar_t*, const wchar_t*, size_t); + +#ifndef __STRICT_ANSI__ +/* + * Unicode versions of non-ANSI string functions provided by CRTDLL. + */ + +/* NOTE: _wcscmpi not provided by CRTDLL, this define is for portability */ +#define _wcscmpi _wcsicmp + +_CRTIMP wchar_t* __cdecl _wcsdup (const wchar_t*); +_CRTIMP int __cdecl _wcsicmp (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl _wcsicoll (const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl _wcslwr (wchar_t*); +_CRTIMP int __cdecl _wcsnicmp (const wchar_t*, const wchar_t*, size_t); +_CRTIMP wchar_t* __cdecl _wcsnset (wchar_t*, wchar_t, size_t); +_CRTIMP wchar_t* __cdecl _wcsrev (wchar_t*); +_CRTIMP wchar_t* __cdecl _wcsset (wchar_t*, wchar_t); +_CRTIMP wchar_t* __cdecl _wcsupr (wchar_t*); + +#ifdef __MSVCRT__ +_CRTIMP int __cdecl _wcsncoll(const wchar_t*, const wchar_t*, size_t); +_CRTIMP int __cdecl _wcsnicoll(const wchar_t*, const wchar_t*, size_t); +#if __MSVCRT_VERSION__ >= 0x0700 +_CRTIMP wchar_t* __cdecl _wcserror(int); +_CRTIMP wchar_t* __cdecl __wcserror(const wchar_t*); +#endif +#endif + +#ifndef _NO_OLDNAMES +/* NOTE: There is no _wcscmpi, but this is for compatibility. */ +int __cdecl wcscmpi (const wchar_t * __ws1, const wchar_t * __ws2); +__CRT_INLINE int __cdecl +wcscmpi (const wchar_t * __ws1, const wchar_t * __ws2) + {return _wcsicmp (__ws1, __ws2);} +_CRTIMP wchar_t* __cdecl wcsdup (const wchar_t*); +_CRTIMP int __cdecl wcsicmp (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl wcsicoll (const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcslwr (wchar_t*); +_CRTIMP int __cdecl wcsnicmp (const wchar_t*, const wchar_t*, size_t); +_CRTIMP wchar_t* __cdecl wcsnset (wchar_t*, wchar_t, size_t); +_CRTIMP wchar_t* __cdecl wcsrev (wchar_t*); +_CRTIMP wchar_t* __cdecl wcsset (wchar_t*, wchar_t); +_CRTIMP wchar_t* __cdecl wcsupr (wchar_t*); +#endif /* Not _NO_OLDNAMES */ + +#endif /* Not strict ANSI */ + +#define _WSTRING_DEFINED +#endif /* _WSTRING_DEFINED */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _STRING_H_ */ diff --git a/reactos/lib/mingw/include/strings.h b/reactos/lib/mingw/include/strings.h new file mode 100644 index 00000000000..2a777c2d752 --- /dev/null +++ b/reactos/lib/mingw/include/strings.h @@ -0,0 +1,12 @@ +/* + File: strings.h + Copyright: Public Domain + + This file is provided because non ANSI fuctions are described in string.h + that belong in strings.h. These functions are provided for in the OLDNAME + libraries. +*/ +#if !defined(_STRINGS_H_) +# define _STRINGS_H_ 1 +# include +#endif diff --git a/reactos/lib/mingw/include/sys/fcntl.h b/reactos/lib/mingw/include/sys/fcntl.h new file mode 100644 index 00000000000..a2090bc82fe --- /dev/null +++ b/reactos/lib/mingw/include/sys/fcntl.h @@ -0,0 +1,7 @@ +/* + * This file is part of the Mingw32 package. + * + * This fcntl.h maps to the root fcntl.h + */ + +#include diff --git a/reactos/lib/mingw/include/sys/file.h b/reactos/lib/mingw/include/sys/file.h new file mode 100644 index 00000000000..e95654c09a0 --- /dev/null +++ b/reactos/lib/mingw/include/sys/file.h @@ -0,0 +1,7 @@ +/* + * This file is part of the Mingw32 package. + * + * This file.h maps to the root fcntl.h + * TODO? + */ +#include diff --git a/reactos/lib/mingw/include/sys/locking.h b/reactos/lib/mingw/include/sys/locking.h new file mode 100644 index 00000000000..eee5e3c5413 --- /dev/null +++ b/reactos/lib/mingw/include/sys/locking.h @@ -0,0 +1,31 @@ +/* + * locking.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Constants for the mode parameter of the locking function. + * + */ + +#ifndef _LOCKING_H_ +#define _LOCKING_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define _LK_UNLCK 0 /* Unlock */ +#define _LK_LOCK 1 /* Lock */ +#define _LK_NBLCK 2 /* Non-blocking lock */ +#define _LK_RLCK 3 /* Lock for read only */ +#define _LK_NBRLCK 4 /* Non-blocking lock for read only */ + +#ifndef NO_OLDNAMES +#define LK_UNLCK _LK_UNLCK +#define LK_LOCK _LK_LOCK +#define LK_NBLCK _LK_NBLCK +#define LK_RLCK _LK_RLCK +#define LK_NBRLCK _LK_NBRLCK +#endif /* Not NO_OLDNAMES */ + +#endif /* Not _LOCKING_H_ */ diff --git a/reactos/lib/mingw/include/sys/param.h b/reactos/lib/mingw/include/sys/param.h new file mode 100644 index 00000000000..74966bd78da --- /dev/null +++ b/reactos/lib/mingw/include/sys/param.h @@ -0,0 +1,22 @@ +/* + * param.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + */ + +#ifndef _SYS_PARAM_H +#define _SYS_PARAM_H + +#include +#include + +/* These are useful for cross-compiling */ +#define BIG_ENDIAN 4321 +#define LITTLE_ENDIAN 1234 +#define BYTE_ORDER LITTLE_ENDIAN + +#define MAXPATHLEN PATH_MAX + +#endif diff --git a/reactos/lib/mingw/include/sys/stat.h b/reactos/lib/mingw/include/sys/stat.h new file mode 100644 index 00000000000..e0d01eb115c --- /dev/null +++ b/reactos/lib/mingw/include/sys/stat.h @@ -0,0 +1,195 @@ +/* + * stat.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Symbolic constants for opening and creating files, also stat, fstat and + * chmod functions. + * + */ + +#ifndef _STAT_H_ +#define _STAT_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define __need_size_t +#define __need_wchar_t +#ifndef RC_INVOKED +#include +#endif /* Not RC_INVOKED */ + +#include + +/* + * Constants for the stat st_mode member. + */ +#define _S_IFIFO 0x1000 /* FIFO */ +#define _S_IFCHR 0x2000 /* Character */ +#define _S_IFBLK 0x3000 /* Block: Is this ever set under w32? */ +#define _S_IFDIR 0x4000 /* Directory */ +#define _S_IFREG 0x8000 /* Regular */ + +#define _S_IFMT 0xF000 /* File type mask */ + +#define _S_IEXEC 0x0040 +#define _S_IWRITE 0x0080 +#define _S_IREAD 0x0100 + +#define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC) +#define _S_IXUSR _S_IEXEC +#define _S_IWUSR _S_IWRITE +#define _S_IRUSR _S_IREAD + +#define _S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#define _S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO) +#define _S_ISCHR(m) (((m) & _S_IFMT) == _S_IFCHR) +#define _S_ISBLK(m) (((m) & _S_IFMT) == _S_IFBLK) +#define _S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) + +#ifndef _NO_OLDNAMES + +#define S_IFIFO _S_IFIFO +#define S_IFCHR _S_IFCHR +#define S_IFBLK _S_IFBLK +#define S_IFDIR _S_IFDIR +#define S_IFREG _S_IFREG +#define S_IFMT _S_IFMT +#define S_IEXEC _S_IEXEC +#define S_IWRITE _S_IWRITE +#define S_IREAD _S_IREAD +#define S_IRWXU _S_IRWXU +#define S_IXUSR _S_IXUSR +#define S_IWUSR _S_IWUSR +#define S_IRUSR _S_IRUSR + +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) + +#endif /* Not _NO_OLDNAMES */ + +#ifndef RC_INVOKED + +#ifndef _STAT_DEFINED +/* + * The structure manipulated and returned by stat and fstat. + * + * NOTE: If called on a directory the values in the time fields are not only + * invalid, they will cause localtime et. al. to return NULL. And calling + * asctime with a NULL pointer causes an Invalid Page Fault. So watch it! + */ +struct _stat +{ + _dev_t st_dev; /* Equivalent to drive number 0=A 1=B ... */ + _ino_t st_ino; /* Always zero ? */ + _mode_t st_mode; /* See above constants */ + short st_nlink; /* Number of links. */ + short st_uid; /* User: Maybe significant on NT ? */ + short st_gid; /* Group: Ditto */ + _dev_t st_rdev; /* Seems useless (not even filled in) */ + _off_t st_size; /* File size in bytes */ + time_t st_atime; /* Accessed date (always 00:00 hrs local + * on FAT) */ + time_t st_mtime; /* Modified time */ + time_t st_ctime; /* Creation time */ +}; + +#ifndef _NO_OLDNAMES +/* NOTE: Must be the same as _stat above. */ +struct stat +{ + _dev_t st_dev; /* Equivalent to drive number 0=A 1=B ... */ + _ino_t st_ino; /* Always zero ? */ + _mode_t st_mode; /* See above constants */ + short st_nlink; /* Number of links. */ + short st_uid; /* User: Maybe significant on NT ? */ + short st_gid; /* Group: Ditto */ + _dev_t st_rdev; /* Seems useless (not even filled in) */ + _off_t st_size; /* File size in bytes */ + time_t st_atime; /* Accessed date (always 00:00 hrs local + * on FAT) */ + time_t st_mtime; /* Modified time */ + time_t st_ctime; /* Creation time */ +}; +#endif /* _NO_OLDNAMES */ + +#if defined (__MSVCRT__) +struct _stati64 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +}; + +struct __stat64 +{ + _dev_t st_dev; + _ino_t st_ino; + _mode_t st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; +}; +#endif /* __MSVCRT__ */ +#define _STAT_DEFINED +#endif /* _STAT_DEFINED */ + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP int __cdecl _fstat (int, struct _stat*); +_CRTIMP int __cdecl _chmod (const char*, int); +_CRTIMP int __cdecl _stat (const char*, struct _stat*); + +#ifndef _NO_OLDNAMES + +/* These functions live in liboldnames.a. */ +_CRTIMP int __cdecl fstat (int, struct stat*); +_CRTIMP int __cdecl chmod (const char*, int); +_CRTIMP int __cdecl stat (const char*, struct stat*); + +#endif /* Not _NO_OLDNAMES */ + +#if defined (__MSVCRT__) +_CRTIMP int __cdecl _fstati64(int, struct _stati64 *); +_CRTIMP int __cdecl _stati64(const char *, struct _stati64 *); +/* These require newer versions of msvcrt.dll (6.10 or higher). */ +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP int __cdecl _fstat64 (int, struct __stat64*); +_CRTIMP int __cdecl _stat64 (const char*, struct __stat64*); +#endif /* __MSVCRT_VERSION__ >= 0x0601 */ +#if !defined ( _WSTAT_DEFINED) /* also declared in wchar.h */ +_CRTIMP int __cdecl _wstat(const wchar_t*, struct _stat*); +_CRTIMP int __cdecl _wstati64 (const wchar_t*, struct _stati64*); +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP int __cdecl _wstat64 (const wchar_t*, struct __stat64*); +#endif /* __MSVCRT_VERSION__ >= 0x0601 */ +#define _WSTAT_DEFINED +#endif /* _WSTAT_DEFIND */ +#endif /* __MSVCRT__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _STAT_H_ */ diff --git a/reactos/lib/mingw/include/sys/time.h b/reactos/lib/mingw/include/sys/time.h new file mode 100644 index 00000000000..17a3960a9af --- /dev/null +++ b/reactos/lib/mingw/include/sys/time.h @@ -0,0 +1,47 @@ +#ifndef _SYS_TIME_H_ +#define _SYS_TIME_H_ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _TIMEVAL_DEFINED /* also in winsock[2].h */ +#define _TIMEVAL_DEFINED +struct timeval { + long tv_sec; + long tv_usec; +}; +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec != (uvp)->tv_sec) ? \ + ((tvp)->tv_sec cmp (uvp)->tv_sec) : \ + ((tvp)->tv_usec cmp (uvp)->tv_usec)) +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#endif /* _TIMEVAL_DEFINED */ + +/* Provided for compatibility with code that assumes that + the presence of gettimeofday function implies a definition + of struct timezone. */ +struct timezone +{ + int tz_minuteswest; /* of Greenwich */ + int tz_dsttime; /* type of dst correction to apply */ +}; + +/* + Implementation as per: + The Open Group Base Specifications, Issue 6 + IEEE Std 1003.1, 2004 Edition + + The timezone pointer arg is ignored. Errors are ignored. +*/ +int __cdecl gettimeofday(struct timeval *__restrict__, + void *__restrict__ /* tzp (unused) */); + +#ifdef __cplusplus +} +#endif + + +#endif /* _SYS_TIME_H_ */ diff --git a/reactos/lib/mingw/include/sys/timeb.h b/reactos/lib/mingw/include/sys/timeb.h new file mode 100644 index 00000000000..4cb4b2e379b --- /dev/null +++ b/reactos/lib/mingw/include/sys/timeb.h @@ -0,0 +1,74 @@ +/* + * timeb.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Support for the UNIX System V ftime system call. + * + */ + +#ifndef _TIMEB_H_ +#define _TIMEB_H_ + +/* All the headers include this file. */ +#include <_mingw.h> +#include + +#ifndef RC_INVOKED + +/* + * TODO: Structure not tested. + */ +struct _timeb +{ + long time; + short millitm; + short timezone; + short dstflag; +}; + +#ifndef _NO_OLDNAMES +/* + * TODO: Structure not tested. + */ +struct timeb +{ + long time; + short millitm; + short timezone; + short dstflag; +}; +#endif + +struct __timeb64 +{ + __time64_t time; + short millitm; + short timezone; + short dstflag; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* TODO: Not tested. */ +_CRTIMP void __cdecl _ftime (struct _timeb*); + +#ifndef _NO_OLDNAMES +_CRTIMP void __cdecl ftime (struct timeb*); +#endif /* Not _NO_OLDNAMES */ + +/* This requires newer versions of msvcrt.dll (6.10 or higher). */ +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP void __cdecl _ftime64 (struct __timeb64*); +#endif /* __MSVCRT_VERSION__ >= 0x0601 */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _TIMEB_H_ */ diff --git a/reactos/lib/mingw/include/sys/types.h b/reactos/lib/mingw/include/sys/types.h new file mode 100644 index 00000000000..2bc04e755d2 --- /dev/null +++ b/reactos/lib/mingw/include/sys/types.h @@ -0,0 +1,120 @@ +/* + * types.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * The definition of constants, data types and global variables. + * + */ + +#ifndef _TYPES_H_ +#define _TYPES_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define __need_wchar_t +#define __need_size_t +#define __need_ptrdiff_t +#ifndef RC_INVOKED +#include +#endif /* Not RC_INVOKED */ + +#ifndef RC_INVOKED + +#ifndef _TIME_T_DEFINED +typedef long time_t; +#define _TIME_T_DEFINED +#endif + +#ifndef _TIME64_T_DEFINED +typedef __int64 __time64_t; +#define _TIME64_T_DEFINED +#endif + +#ifndef _OFF_T_ +#define _OFF_T_ +typedef long _off_t; + +#ifndef _NO_OLDNAMES +typedef _off_t off_t; +#endif +#endif /* Not _OFF_T_ */ + + +#ifndef _DEV_T_ +#define _DEV_T_ +#ifdef __MSVCRT__ +typedef unsigned int _dev_t; +#else +typedef short _dev_t; +#endif + +#ifndef _NO_OLDNAMES +typedef _dev_t dev_t; +#endif +#endif /* Not _DEV_T_ */ + + +#ifndef _INO_T_ +#define _INO_T_ +typedef short _ino_t; + +#ifndef _NO_OLDNAMES +typedef _ino_t ino_t; +#endif +#endif /* Not _INO_T_ */ + + +#ifndef _PID_T_ +#define _PID_T_ +typedef int _pid_t; + +#ifndef _NO_OLDNAMES +typedef _pid_t pid_t; +#endif +#endif /* Not _PID_T_ */ + + +#ifndef _MODE_T_ +#define _MODE_T_ +typedef unsigned short _mode_t; + +#ifndef _NO_OLDNAMES +typedef _mode_t mode_t; +#endif +#endif /* Not _MODE_T_ */ + + +#ifndef _SIGSET_T_ +#define _SIGSET_T_ +typedef int _sigset_t; + +#ifndef _NO_OLDNAMES +typedef _sigset_t sigset_t; +#endif +#endif /* Not _SIGSET_T_ */ + +#ifndef _SSIZE_T_ +#define _SSIZE_T_ +typedef long _ssize_t; + +#ifndef _NO_OLDNAMES +typedef _ssize_t ssize_t; +#endif +#endif /* Not _SSIZE_T_ */ + +#ifndef _FPOS64_T_ +#define _FPOS64_T_ +typedef long long fpos64_t; +#endif + +#ifndef _OFF64_T_ +#define _OFF64_T_ +typedef long long off64_t; +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _TYPES_H_ */ diff --git a/reactos/lib/mingw/include/sys/unistd.h b/reactos/lib/mingw/include/sys/unistd.h new file mode 100644 index 00000000000..39eac4a9001 --- /dev/null +++ b/reactos/lib/mingw/include/sys/unistd.h @@ -0,0 +1,6 @@ +/* + * This file is part of the Mingw32 package. + * + * unistd.h maps (roughly) to io.h + */ +#include diff --git a/reactos/lib/mingw/include/sys/utime.h b/reactos/lib/mingw/include/sys/utime.h new file mode 100644 index 00000000000..75cfeb45a72 --- /dev/null +++ b/reactos/lib/mingw/include/sys/utime.h @@ -0,0 +1,82 @@ +/* + * utime.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Support for the utime function. + * + */ +#ifndef _UTIME_H_ +#define _UTIME_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define __need_wchar_t +#define __need_size_t +#ifndef RC_INVOKED +#include +#endif /* Not RC_INVOKED */ +#include + +#ifndef RC_INVOKED + +/* + * Structure used by _utime function. + */ +struct _utimbuf +{ + time_t actime; /* Access time */ + time_t modtime; /* Modification time */ +}; + + +#ifndef _NO_OLDNAMES +/* NOTE: Must be the same as _utimbuf above. */ +struct utimbuf +{ + time_t actime; + time_t modtime; +}; +#endif /* Not _NO_OLDNAMES */ + +struct __utimbuf64 +{ + __time64_t actime; + __time64_t modtime; +}; + + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP int __cdecl _utime (const char*, struct _utimbuf*); + +#ifndef _NO_OLDNAMES +_CRTIMP int __cdecl utime (const char*, struct utimbuf*); +#endif /* Not _NO_OLDNAMES */ + +_CRTIMP int __cdecl _futime (int, struct _utimbuf*); + +/* The wide character version, only available for MSVCRT versions of the + * C runtime library. */ +#ifdef __MSVCRT__ +_CRTIMP int __cdecl _wutime (const wchar_t*, struct _utimbuf*); +#endif /* MSVCRT runtime */ + +/* These require newer versions of msvcrt.dll (6.10 or higher). */ +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP int __cdecl _utime64 (const char*, struct __utimbuf64*); +_CRTIMP int __cdecl _wutime64 (const wchar_t*, struct __utimbuf64*); +_CRTIMP int __cdecl _futime64 (int, struct __utimbuf64*); +#endif /* __MSVCRT_VERSION__ >= 0x0601 */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _UTIME_H_ */ diff --git a/reactos/lib/mingw/include/tchar.h b/reactos/lib/mingw/include/tchar.h new file mode 100644 index 00000000000..a07d75f4586 --- /dev/null +++ b/reactos/lib/mingw/include/tchar.h @@ -0,0 +1,418 @@ +/* + * tchar.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Unicode mapping layer for the standard C library. By including this + * file and using the 't' names for string functions + * (eg. _tprintf) you can make code which can be easily adapted to both + * Unicode and non-unicode environments. In a unicode enabled compile define + * _UNICODE before including tchar.h, otherwise the standard non-unicode + * library functions will be used. + * + * Note that you still need to include string.h or stdlib.h etc. to define + * the appropriate functions. Also note that there are several defines + * included for non-ANSI functions which are commonly available (but using + * the convention of prepending an underscore to non-ANSI library function + * names). + * + */ + +#ifndef _TCHAR_H_ +#define _TCHAR_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +/* + * NOTE: This tests _UNICODE, which is different from the UNICODE define + * used to differentiate Win32 API calls. + */ +#ifdef _UNICODE + +/* + * Include for wchar_t and WEOF if _UNICODE. + */ +#include + +/* + * Use TCHAR instead of char or wchar_t. It will be appropriately translated + * if _UNICODE is correctly defined (or not). + */ +#ifndef _TCHAR_DEFINED +#ifndef RC_INVOKED +typedef wchar_t TCHAR; +typedef wchar_t _TCHAR; +#endif /* Not RC_INVOKED */ +#define _TCHAR_DEFINED +#endif + +/* + * Use _TEOF instead of EOF or WEOF. It will be appropriately translated if + * _UNICODE is correctly defined (or not). + */ +#define _TEOF WEOF + +/* + * __TEXT is a private macro whose specific use is to force the expansion of a + * macro passed as an argument to the macros _T or _TEXT. DO NOT use this + * macro within your programs. It's name and function could change without + * notice. + */ +#define __TEXT(q) L##q + +/* for porting from other Windows compilers */ +#if 0 /* no wide startup module */ +#define _tmain wmain +#define _tWinMain wWinMain +#define _tenviron _wenviron +#define __targv __wargv +#endif + +/* + * Unicode functions + */ +#define _tprintf wprintf +#define _ftprintf fwprintf +#define _stprintf swprintf +#define _sntprintf _snwprintf +#define _vtprintf vwprintf +#define _vftprintf vfwprintf +#define _vstprintf vswprintf +#define _vsntprintf _vsnwprintf +#define _tscanf wscanf +#define _ftscanf fwscanf +#define _stscanf swscanf +#define _fgettc fgetwc +#define _fgettchar _fgetwchar +#define _fgetts fgetws +#define _fputtc fputwc +#define _fputtchar _fputwchar +#define _fputts fputws +#define _gettc getwc +#define _getts _getws +#define _puttc putwc +#define _puttchar putwchar +#define _putts _putws +#define _ungettc ungetwc +#define _tcstod wcstod +#define _tcstol wcstol +#define _tcstoul wcstoul +#define _itot _itow +#define _ltot _ltow +#define _ultot _ultow +#define _ttoi _wtoi +#define _ttol _wtol +#define _tcscat wcscat +#define _tcschr wcschr +#define _tcscmp wcscmp +#define _tcscpy wcscpy +#define _tcscspn wcscspn +#define _tcslen wcslen +#define _tcsncat wcsncat +#define _tcsncmp wcsncmp +#define _tcsncpy wcsncpy +#define _tcspbrk wcspbrk +#define _tcsrchr wcsrchr +#define _tcsspn wcsspn +#define _tcsstr wcsstr +#define _tcstok wcstok +#define _tcsdup _wcsdup +#define _tcsicmp _wcsicmp +#define _tcsnicmp _wcsnicmp +#define _tcsnset _wcsnset +#define _tcsrev _wcsrev +#define _tcsset _wcsset +#define _tcslwr _wcslwr +#define _tcsupr _wcsupr +#define _tcsxfrm wcsxfrm +#define _tcscoll wcscoll +#define _tcsicoll _wcsicoll +#define _istalpha iswalpha +#define _istupper iswupper +#define _istlower iswlower +#define _istdigit iswdigit +#define _istxdigit iswxdigit +#define _istspace iswspace +#define _istpunct iswpunct +#define _istalnum iswalnum +#define _istprint iswprint +#define _istgraph iswgraph +#define _istcntrl iswcntrl +#define _istascii iswascii +#define _totupper towupper +#define _totlower towlower +#define _tcsftime wcsftime +/* Macro functions */ +#define _tcsdec _wcsdec +#define _tcsinc _wcsinc +#define _tcsnbcnt _wcsncnt +#define _tcsnccnt _wcsncnt +#define _tcsnextc _wcsnextc +#define _tcsninc _wcsninc +#define _tcsspnp _wcsspnp +#define _wcsdec(_wcs1, _wcs2) ((_wcs1)>=(_wcs2) ? NULL : (_wcs2)-1) +#define _wcsinc(_wcs) ((_wcs)+1) +#define _wcsnextc(_wcs) ((unsigned int) *(_wcs)) +#define _wcsninc(_wcs, _inc) (((_wcs)+(_inc))) +#define _wcsncnt(_wcs, _cnt) ((wcslen(_wcs)>_cnt) ? _count : wcslen(_wcs)) +#define _wcsspnp(_wcs1, _wcs2) ((*((_wcs1)+wcsspn(_wcs1,_wcs2))) ? ((_wcs1)+wcsspn(_wcs1,_wcs2)) : NULL) + +#if 1 /* defined __MSVCRT__ */ +/* + * These wide functions not in crtdll.dll. + * Define macros anyway so that _wfoo rather than _tfoo is undefined + */ +#define _ttoi64 _wtoi64 +#define _i64tot _i64tow +#define _ui64tot _ui64tow +#define _tasctime _wasctime +#define _tctime _wctime +#define _tstrdate _wstrdate +#define _tstrtime _wstrtime +#define _tutime _wutime +#define _tcsnccoll _wcsncoll +#define _tcsncoll _wcsncoll +#define _tcsncicoll _wcsnicoll +#define _tcsnicoll _wcsnicoll +#define _taccess _waccess +#define _tchmod _wchmod +#define _tcreat _wcreat +#define _tfindfirst _wfindfirst +#define _tfindnext _wfindnext +#define _tfdopen _wfdopen +#define _tfopen _wfopen +#define _tfreopen _wfreopen +#define _tfsopen _wfsopen +#define _tgetenv _wgetenv +#define _tputenv _wputenv +#define _tsearchenv _wsearchenv +#define _tmakepath _wmakepath +#define _tsplitpath _wsplitpath +#define _tfullpath _wfullpath +#define _tmktemp _wmktemp +#define _topen _wopen +#define _tremove _wremove +#define _trename _wrename +#define _tsopen _wsopen +#define _tsetlocale _wsetlocale +#define _tunlink _wunlink +#define _tfinddata_t _wfinddata_t +#define _tfindfirsti64 _wfindfirsti64 +#define _tfindnexti64 _wfindnexti64 +#define _tfinddatai64_t _wfinddatai64_t +#define _tchdir _wchdir +#define _tgetcwd _wgetcwd +#define _tgetdcwd _wgetdcwd +#define _tmkdir _wmkdir +#define _trmdir _wrmdir +#define _tstat _wstat +#define _tstati64 _wstati64 +#define _tstat64 _wstat64 +#endif /* __MSVCRT__ */ + +/* dirent structures and functions */ +#define _tdirent _wdirent +#define _TDIR _WDIR +#define _topendir _wopendir +#define _tclosedir _wclosedir +#define _treaddir _wreaddir +#define _trewinddir _wrewinddir +#define _ttelldir _wtelldir +#define _tseekdir _wseekdir + +#else /* Not _UNICODE */ + +/* + * TCHAR, the type you should use instead of char. + */ +#ifndef _TCHAR_DEFINED +#ifndef RC_INVOKED +typedef char TCHAR; +typedef char _TCHAR; +#endif +#define _TCHAR_DEFINED +#endif + +/* + * _TEOF, the constant you should use instead of EOF. + */ +#define _TEOF EOF + +/* + * __TEXT is a private macro whose specific use is to force the expansion of a + * macro passed as an argument to the macros _T or _TEXT. DO NOT use this + * macro within your programs. It's name and function could change without + * notice. + */ +#define __TEXT(q) q + +/* for porting from other Windows compilers */ +#define _tmain main +#define _tWinMain WinMain +#define _tenviron _environ +#define __targv __argv + +/* + * Non-unicode (standard) functions + */ + +#define _tprintf printf +#define _ftprintf fprintf +#define _stprintf sprintf +#define _sntprintf _snprintf +#define _vtprintf vprintf +#define _vftprintf vfprintf +#define _vstprintf vsprintf +#define _vsntprintf _vsnprintf +#define _tscanf scanf +#define _ftscanf fscanf +#define _stscanf sscanf +#define _fgettc fgetc +#define _fgettchar _fgetchar +#define _fgetts fgets +#define _fputtc fputc +#define _fputtchar _fputchar +#define _fputts fputs +#define _tfdopen _fdopen +#define _tfopen fopen +#define _tfreopen freopen +#define _tfsopen _fsopen +#define _tgetenv getenv +#define _tputenv _putenv +#define _tsearchenv _searchenv +#define _tmakepath _makepath +#define _tsplitpath _splitpath +#define _tfullpath _fullpath +#define _gettc getc +#define _getts gets +#define _puttc putc +#define _puttchar putchar +#define _putts puts +#define _ungettc ungetc +#define _tcstod strtod +#define _tcstol strtol +#define _tcstoul strtoul +#define _itot _itoa +#define _ltot _ltoa +#define _ultot _ultoa +#define _ttoi atoi +#define _ttol atol +#define _tcscat strcat +#define _tcschr strchr +#define _tcscmp strcmp +#define _tcscpy strcpy +#define _tcscspn strcspn +#define _tcslen strlen +#define _tcsncat strncat +#define _tcsncmp strncmp +#define _tcsncpy strncpy +#define _tcspbrk strpbrk +#define _tcsrchr strrchr +#define _tcsspn strspn +#define _tcsstr strstr +#define _tcstok strtok +#define _tcsdup _strdup +#define _tcsicmp _stricmp +#define _tcsnicmp _strnicmp +#define _tcsnset _strnset +#define _tcsrev _strrev +#define _tcsset _strset +#define _tcslwr _strlwr +#define _tcsupr _strupr +#define _tcsxfrm strxfrm +#define _tcscoll strcoll +#define _tcsicoll _stricoll +#define _istalpha isalpha +#define _istupper isupper +#define _istlower islower +#define _istdigit isdigit +#define _istxdigit isxdigit +#define _istspace isspace +#define _istpunct ispunct +#define _istalnum isalnum +#define _istprint isprint +#define _istgraph isgraph +#define _istcntrl iscntrl +#define _istascii isascii +#define _totupper toupper +#define _totlower tolower +#define _tasctime asctime +#define _tctime ctime +#define _tstrdate _strdate +#define _tstrtime _strtime +#define _tutime _utime +#define _tcsftime strftime +/* Macro functions */ +#define _tcsdec _strdec +#define _tcsinc _strinc +#define _tcsnbcnt _strncnt +#define _tcsnccnt _strncnt +#define _tcsnextc _strnextc +#define _tcsninc _strninc +#define _tcsspnp _strspnp +#define _strdec(_str1, _str2) ((_str1)>=(_str2) ? NULL : (_str2)-1) +#define _strinc(_str) ((_str)+1) +#define _strnextc(_str) ((unsigned int) *(_str)) +#define _strninc(_str, _inc) (((_str)+(_inc))) +#define _strncnt(_str, _cnt) ((strlen(_str)>_cnt) ? _count : strlen(_str)) +#define _strspnp(_str1, _str2) ((*((_str1)+strspn(_str1,_str2))) ? ((_str1)+strspn(_str1,_str2)) : NULL) + +#define _tchmod _chmod +#define _tcreat _creat +#define _tfindfirst _findfirst +#define _tfindnext _findnext +#define _tmktemp _mktemp +#define _topen _open +#define _taccess _access +#define _tremove remove +#define _trename rename +#define _tsopen _sopen +#define _tsetlocale setlocale +#define _tunlink _unlink +#define _tfinddata_t _finddata_t +#define _tchdir _chdir +#define _tgetcwd _getcwd +#define _tgetdcwd _getdcwd +#define _tmkdir _mkdir +#define _trmdir _rmdir +#define _tstat _stat + +#if 1 /* defined __MSVCRT__ */ +/* Not in crtdll.dll. Define macros anyway? */ +#define _ttoi64 _atoi64 +#define _i64tot _i64toa +#define _ui64tot _ui64toa +#define _tcsnccoll _strncoll +#define _tcsncoll _strncoll +#define _tcsncicoll _strnicoll +#define _tcsnicoll _strnicoll +#define _tfindfirsti64 _findfirsti64 +#define _tfindnexti64 _findnexti64 +#define _tfinddatai64_t _finddatai64_t +#define _tstati64 _stati64 +#define _tstat64 _stat64 +#endif /* __MSVCRT__ */ + +/* dirent structures and functions */ +#define _tdirent dirent +#define _TDIR DIR +#define _topendir opendir +#define _tclosedir closedir +#define _treaddir readdir +#define _trewinddir rewinddir +#define _ttelldir telldir +#define _tseekdir seekdir + +#endif /* Not _UNICODE */ + +/* + * UNICODE a constant string when _UNICODE is defined else returns the string + * unmodified. Also defined in w32api/winnt.h. + */ +#define _TEXT(x) __TEXT(x) +#define _T(x) __TEXT(x) + +#endif /* Not _TCHAR_H_ */ + diff --git a/reactos/lib/mingw/include/time.h b/reactos/lib/mingw/include/time.h new file mode 100644 index 00000000000..13d4d1630b3 --- /dev/null +++ b/reactos/lib/mingw/include/time.h @@ -0,0 +1,218 @@ +/* + * time.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Date and time functions and types. + * + */ + +#ifndef _TIME_H_ +#define _TIME_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define __need_wchar_t +#define __need_size_t +#define __need_NULL +#ifndef RC_INVOKED +#include +#endif /* Not RC_INVOKED */ + +/* + * Number of clock ticks per second. A clock tick is the unit by which + * processor time is measured and is returned by 'clock'. + */ +#define CLOCKS_PER_SEC ((clock_t)1000) +#define CLK_TCK CLOCKS_PER_SEC + + +#ifndef RC_INVOKED + +/* + * A type for storing the current time and date. This is the number of + * seconds since midnight Jan 1, 1970. + * NOTE: This is also defined in non-ISO sys/types.h. + */ +#ifndef _TIME_T_DEFINED +typedef long time_t; +#define _TIME_T_DEFINED +#endif + +#ifndef __STRICT_ANSI__ +/* A 64-bit time_t to get to Y3K */ +#ifndef _TIME64_T_DEFINED +typedef __int64 __time64_t; +#define _TIME64_T_DEFINED +#endif +#endif +/* + * A type for measuring processor time (in clock ticks). + */ +#ifndef _CLOCK_T_DEFINED +typedef long clock_t; +#define _CLOCK_T_DEFINED +#endif + +#ifndef _TM_DEFINED +/* + * A structure for storing all kinds of useful information about the + * current (or another) time. + */ +struct tm +{ + int tm_sec; /* Seconds: 0-59 (K&R says 0-61?) */ + int tm_min; /* Minutes: 0-59 */ + int tm_hour; /* Hours since midnight: 0-23 */ + int tm_mday; /* Day of the month: 1-31 */ + int tm_mon; /* Months *since* january: 0-11 */ + int tm_year; /* Years since 1900 */ + int tm_wday; /* Days since Sunday (0-6) */ + int tm_yday; /* Days since Jan. 1: 0-365 */ + int tm_isdst; /* +1 Daylight Savings Time, 0 No DST, + * -1 don't know */ +}; +#define _TM_DEFINED +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP clock_t __cdecl clock (void); +_CRTIMP time_t __cdecl time (time_t*); +_CRTIMP double __cdecl difftime (time_t, time_t); +_CRTIMP time_t __cdecl mktime (struct tm*); + +/* + * These functions write to and return pointers to static buffers that may + * be overwritten by other function calls. Yikes! + * + * NOTE: localtime, and perhaps the others of the four functions grouped + * below may return NULL if their argument is not 'acceptable'. Also note + * that calling asctime with a NULL pointer will produce an Invalid Page + * Fault and crap out your program. Guess how I know. Hint: stat called on + * a directory gives 'invalid' times in st_atime etc... + */ +_CRTIMP char* __cdecl asctime (const struct tm*); +_CRTIMP char* __cdecl ctime (const time_t*); +_CRTIMP struct tm* __cdecl gmtime (const time_t*); +_CRTIMP struct tm* __cdecl localtime (const time_t*); + +_CRTIMP size_t __cdecl strftime (char*, size_t, const char*, const struct tm*); + +#ifndef __STRICT_ANSI__ + +extern _CRTIMP void __cdecl _tzset (void); + +#ifndef _NO_OLDNAMES +extern _CRTIMP void __cdecl tzset (void); +#endif + +_CRTIMP char* __cdecl _strdate(char*); +_CRTIMP char* __cdecl _strtime(char*); + +/* These require newer versions of msvcrt.dll (6.10 or higher). */ +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP __time64_t __cdecl _time64( __time64_t*); +_CRTIMP __time64_t __cdecl _mktime64 (struct tm*); +_CRTIMP char* __cdecl _ctime64 (const __time64_t*); +_CRTIMP struct tm* __cdecl _gmtime64 (const __time64_t*); +_CRTIMP struct tm* __cdecl _localtime64 (const __time64_t*); +#endif /* __MSVCRT_VERSION__ >= 0x0601 */ + +/* + * _daylight: non zero if daylight savings time is used. + * _timezone: difference in seconds between GMT and local time. + * _tzname: standard/daylight savings time zone names (an array with two + * elements). + */ +#ifdef __MSVCRT__ + +/* These are for compatibility with pre-VC 5.0 suppied MSVCRT. */ +extern _CRTIMP int* __cdecl __p__daylight (void); +extern _CRTIMP long* __cdecl __p__timezone (void); +extern _CRTIMP char** __cdecl __p__tzname (void); + +__MINGW_IMPORT int _daylight; +__MINGW_IMPORT long _timezone; +__MINGW_IMPORT char *_tzname[2]; + +#else /* not __MSVCRT (ie. crtdll) */ + +#ifndef __DECLSPEC_SUPPORTED + +extern int* _imp___daylight_dll; +extern long* _imp___timezone_dll; +extern char** _imp___tzname; + +#define _daylight (*_imp___daylight_dll) +#define _timezone (*_imp___timezone_dll) +#define _tzname (*_imp___tzname) + +#else /* __DECLSPEC_SUPPORTED */ + +__MINGW_IMPORT int _daylight_dll; +__MINGW_IMPORT long _timezone_dll; +__MINGW_IMPORT char* _tzname[2]; + +#define _daylight _daylight_dll +#define _timezone _timezone_dll + +#endif /* __DECLSPEC_SUPPORTED */ + +#endif /* not __MSVCRT__ */ + +#ifndef _NO_OLDNAMES + +#ifdef __MSVCRT__ + +/* These go in the oldnames import library for MSVCRT. */ +__MINGW_IMPORT int daylight; +__MINGW_IMPORT long timezone; +__MINGW_IMPORT char *tzname[2]; + +#else /* not __MSVCRT__ */ + +/* CRTDLL is royally messed up when it comes to these macros. + TODO: import and alias these via oldnames import library instead + of macros. */ + +#define daylight _daylight +/* NOTE: timezone not defined as macro because it would conflict with + struct timezone in sys/time.h. + Also, tzname used to a be macro, but now it's in moldname. */ +__MINGW_IMPORT char *tzname[2]; + +#endif /* not __MSVCRT__ */ + +#endif /* Not _NO_OLDNAMES */ +#endif /* Not __STRICT_ANSI__ */ + +#ifndef _WTIME_DEFINED +/* wide function prototypes, also declared in wchar.h */ +#ifndef __STRICT_ANSI__ +#ifdef __MSVCRT__ +_CRTIMP wchar_t* __cdecl _wasctime(const struct tm*); +_CRTIMP wchar_t* __cdecl _wctime(const time_t*); +_CRTIMP wchar_t* __cdecl _wstrdate(wchar_t*); +_CRTIMP wchar_t* __cdecl _wstrtime(wchar_t*); +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP wchar_t* __cdecl _wctime64 (const __time64_t*); +#endif +#endif /* __MSVCRT__ */ +#endif /* __STRICT_ANSI__ */ +_CRTIMP size_t __cdecl wcsftime (wchar_t*, size_t, const wchar_t*, const struct tm*); +#define _WTIME_DEFINED +#endif /* _WTIME_DEFINED */ + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _TIME_H_ */ + diff --git a/reactos/lib/mingw/include/unistd.h b/reactos/lib/mingw/include/unistd.h new file mode 100644 index 00000000000..f3a54495e52 --- /dev/null +++ b/reactos/lib/mingw/include/unistd.h @@ -0,0 +1,33 @@ +/* + * This file is part of the Mingw32 package. + * + * unistd.h maps (roughly) to io.h + */ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#include +#include + +#define __UNISTD_GETOPT__ +#include +#undef __UNISTD_GETOPT__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is defined as a real library function to allow autoconf + to verify its existence. */ +int ftruncate(int, off_t); +__CRT_INLINE int ftruncate(int __fd, off_t __length) +{ + return _chsize (__fd, __length); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _UNISTD_H */ diff --git a/reactos/lib/mingw/include/utime.h b/reactos/lib/mingw/include/utime.h new file mode 100644 index 00000000000..8285f38fdef --- /dev/null +++ b/reactos/lib/mingw/include/utime.h @@ -0,0 +1 @@ +#include diff --git a/reactos/lib/mingw/include/values.h b/reactos/lib/mingw/include/values.h new file mode 100644 index 00000000000..10e16a2810b --- /dev/null +++ b/reactos/lib/mingw/include/values.h @@ -0,0 +1,4 @@ +/* + * TODO: Nothing here yet. Should provide UNIX compatibility constants + * comparible to those in limits.h and float.h. + */ diff --git a/reactos/lib/mingw/include/varargs.h b/reactos/lib/mingw/include/varargs.h new file mode 100644 index 00000000000..c1197e97e2b --- /dev/null +++ b/reactos/lib/mingw/include/varargs.h @@ -0,0 +1,7 @@ +/* + * This is just an RC_INVOKED guard for the real varargs.h + * fixincluded in gcc system dir. One day we will delete this file. + */ +#ifndef RC_INVOKED +#include_next +#endif diff --git a/reactos/lib/mingw/include/wchar.h b/reactos/lib/mingw/include/wchar.h new file mode 100644 index 00000000000..2f5c6a9453d --- /dev/null +++ b/reactos/lib/mingw/include/wchar.h @@ -0,0 +1,475 @@ +/* + * wchar.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Defines of all functions for supporting wide characters. Actually it + * just includes all those headers, which is not a good thing to do from a + * processing time point of view, but it does mean that everything will be + * in sync. + * + */ + +#ifndef _WCHAR_H_ +#define _WCHAR_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#ifndef RC_INVOKED + +#define __need_size_t +#define __need_wint_t +#define __need_wchar_t +#define __need_NULL +#include + +#ifndef __VALIST +#if defined __GNUC__ && __GNUC__ >= 3 +#define __need___va_list +#include +#define __VALIST __builtin_va_list +#else +#define __VALIST char* +#endif +#endif + +#endif /* Not RC_INVOKED */ + +/* + * MSDN says that isw* char classifications are in wchar.h and wctype.h. + * Although the wctype names are ANSI, their exposure in this header is + * not. + */ +#include + +#ifndef __STRICT_ANSI__ +/* This is necessary to support the the non-ANSI wchar declarations + here. */ +#include +#endif /* __STRICT_ANSI__ */ + +#define WCHAR_MIN 0 +#define WCHAR_MAX 0xffff + +#ifndef WEOF +#define WEOF (wchar_t)(0xFFFF) +#endif + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _FILE_DEFINED /* Also in stdio.h */ +#define _FILE_DEFINED +typedef struct _iobuf +{ + char* _ptr; + int _cnt; + char* _base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char* _tmpfname; +} FILE; +#endif /* Not _FILE_DEFINED */ + +#ifndef _TIME_T_DEFINED /* Also in time.h */ +typedef long time_t; +#define _TIME_T_DEFINED +#endif + +#ifndef _TM_DEFINED /* Also in time.h */ +struct tm { + int tm_sec; /* seconds after the minute - [0,59] */ + int tm_min; /* minutes after the hour - [0,59] */ + int tm_hour; /* hours since midnight - [0,23] */ + int tm_mday; /* day of the month - [1,31] */ + int tm_mon; /* months since January - [0,11] */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday - [0,6] */ + int tm_yday; /* days since January 1 - [0,365] */ + int tm_isdst; /* daylight savings time flag */ + }; +#define _TM_DEFINED +#endif + +#ifndef _WSTDIO_DEFINED +/* Also in stdio.h - keep in sync */ +_CRTIMP int __cdecl fwprintf (FILE*, const wchar_t*, ...); +_CRTIMP int __cdecl wprintf (const wchar_t*, ...); +_CRTIMP int __cdecl swprintf (wchar_t*, const wchar_t*, ...); +_CRTIMP int __cdecl _snwprintf (wchar_t*, size_t, const wchar_t*, ...); +_CRTIMP int __cdecl vfwprintf (FILE*, const wchar_t*, __VALIST); +_CRTIMP int __cdecl vwprintf (const wchar_t*, __VALIST); +_CRTIMP int __cdecl vswprintf (wchar_t*, const wchar_t*, __VALIST); +_CRTIMP int __cdecl _vsnwprintf (wchar_t*, size_t, const wchar_t*, __VALIST); +_CRTIMP int __cdecl fwscanf (FILE*, const wchar_t*, ...); +_CRTIMP int __cdecl wscanf (const wchar_t*, ...); +_CRTIMP int __cdecl swscanf (const wchar_t*, const wchar_t*, ...); +_CRTIMP wint_t __cdecl fgetwc (FILE*); +_CRTIMP wint_t __cdecl fputwc (wchar_t, FILE*); +_CRTIMP wint_t __cdecl ungetwc (wchar_t, FILE*); + +#ifdef __MSVCRT__ +_CRTIMP wchar_t* __cdecl fgetws (wchar_t*, int, FILE*); +_CRTIMP int __cdecl fputws (const wchar_t*, FILE*); +_CRTIMP wint_t __cdecl getwc (FILE*); +_CRTIMP wint_t __cdecl getwchar (void); +_CRTIMP wint_t __cdecl putwc (wint_t, FILE*); +_CRTIMP wint_t __cdecl putwchar (wint_t); +#ifndef __STRICT_ANSI__ +_CRTIMP wchar_t* __cdecl _getws (wchar_t*); +_CRTIMP int __cdecl _putws (const wchar_t*); +_CRTIMP FILE* __cdecl _wfdopen(int, wchar_t *); +_CRTIMP FILE* __cdecl _wfopen (const wchar_t*, const wchar_t*); +_CRTIMP FILE* __cdecl _wfreopen (const wchar_t*, const wchar_t*, FILE*); +_CRTIMP FILE* __cdecl _wfsopen (const wchar_t*, const wchar_t*, int); +_CRTIMP wchar_t* __cdecl _wtmpnam (wchar_t*); +_CRTIMP wchar_t* __cdecl _wtempnam (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl _wrename (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl _wremove (const wchar_t*); +_CRTIMP void __cdecl _wperror (const wchar_t*); +_CRTIMP FILE* __cdecl _wpopen (const wchar_t*, const wchar_t*); +#endif /* __STRICT_ANSI__ */ +#endif /* __MSVCRT__ */ + +#ifndef __NO_ISOCEXT /* externs in libmingwex.a */ +int __cdecl snwprintf (wchar_t* s, size_t n, const wchar_t* format, ...); +__CRT_INLINE int __cdecl +vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, __VALIST arg) + { return _vsnwprintf ( s, n, format, arg);} +int __cdecl vwscanf (const wchar_t * __restrict__, __VALIST); +int __cdecl vfwscanf (FILE * __restrict__, + const wchar_t * __restrict__, __VALIST); +int __cdecl vswscanf (const wchar_t * __restrict__, + const wchar_t * __restrict__, __VALIST); +#endif + +#define _WSTDIO_DEFINED +#endif /* _WSTDIO_DEFINED */ + +#ifndef _WSTDLIB_DEFINED /* also declared in stdlib.h */ +_CRTIMP long __cdecl wcstol (const wchar_t*, wchar_t**, int); +_CRTIMP unsigned long __cdecl wcstoul (const wchar_t*, wchar_t**, int); +_CRTIMP double __cdecl wcstod (const wchar_t*, wchar_t**); +#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */ +__CRT_INLINE float __cdecl wcstof( const wchar_t *nptr, wchar_t **endptr) +{ return (wcstod(nptr, endptr)); } +long double __cdecl wcstold (const wchar_t * __restrict__, wchar_t ** __restrict__); +#endif /* __NO_ISOCEXT */ +#define _WSTDLIB_DEFINED +#endif /* _WSTDLIB_DEFINED */ + +#ifndef _WTIME_DEFINED +#ifndef __STRICT_ANSI__ +#ifdef __MSVCRT__ +/* wide function prototypes, also declared in time.h */ +_CRTIMP wchar_t* __cdecl _wasctime (const struct tm*); +_CRTIMP wchar_t* __cdecl _wctime (const time_t*); +_CRTIMP wchar_t* __cdecl _wstrdate (wchar_t*); +_CRTIMP wchar_t* __cdecl _wstrtime (wchar_t*); +#if __MSVCRT_VERSION__ >= 0x601 +_CRTIMP wchar_t* __cdecl _wctime64 (const __time64_t*); +#endif +#endif /* __MSVCRT__ */ +#endif /* __STRICT_ANSI__ */ +_CRTIMP size_t __cdecl wcsftime (wchar_t*, size_t, const wchar_t*, const struct tm*); +#define _WTIME_DEFINED +#endif /* _WTIME_DEFINED */ + + +#ifndef _WSTRING_DEFINED +/* + * Unicode versions of the standard string calls. + * Also in string.h. + */ +_CRTIMP wchar_t* __cdecl wcscat (wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcschr (const wchar_t*, wchar_t); +_CRTIMP int __cdecl wcscmp (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl wcscoll (const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcscpy (wchar_t*, const wchar_t*); +_CRTIMP size_t __cdecl wcscspn (const wchar_t*, const wchar_t*); +/* Note: _wcserror requires __MSVCRT_VERSION__ >= 0x0700. */ +_CRTIMP size_t __cdecl wcslen (const wchar_t*); +_CRTIMP wchar_t* __cdecl wcsncat (wchar_t*, const wchar_t*, size_t); +_CRTIMP int __cdecl wcsncmp(const wchar_t*, const wchar_t*, size_t); +_CRTIMP wchar_t* __cdecl wcsncpy(wchar_t*, const wchar_t*, size_t); +_CRTIMP wchar_t* __cdecl wcspbrk(const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcsrchr(const wchar_t*, wchar_t); +_CRTIMP size_t __cdecl wcsspn(const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcsstr(const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcstok(wchar_t*, const wchar_t*); +_CRTIMP size_t __cdecl wcsxfrm(wchar_t*, const wchar_t*, size_t); + +#ifndef __STRICT_ANSI__ +/* + * Unicode versions of non-ANSI functions provided by CRTDLL. + */ + +/* NOTE: _wcscmpi not provided by CRTDLL, this define is for portability */ +#define _wcscmpi _wcsicmp + +_CRTIMP wchar_t* __cdecl _wcsdup (const wchar_t*); +_CRTIMP int __cdecl _wcsicmp (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl _wcsicoll (const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl _wcslwr (wchar_t*); +_CRTIMP int __cdecl _wcsnicmp (const wchar_t*, const wchar_t*, size_t); +_CRTIMP wchar_t* __cdecl _wcsnset (wchar_t*, wchar_t, size_t); +_CRTIMP wchar_t* __cdecl _wcsrev (wchar_t*); +_CRTIMP wchar_t* __cdecl _wcsset (wchar_t*, wchar_t); +_CRTIMP wchar_t* __cdecl _wcsupr (wchar_t*); + +#ifdef __MSVCRT__ +_CRTIMP int __cdecl _wcsncoll(const wchar_t*, const wchar_t*, size_t); +_CRTIMP int __cdecl _wcsnicoll(const wchar_t*, const wchar_t*, size_t); +#if __MSVCRT_VERSION__ >= 0x0700 +_CRTIMP wchar_t* __cdecl _wcserror(int); +_CRTIMP wchar_t* __cdecl __wcserror(const wchar_t*); +#endif +#endif + +#ifndef _NO_OLDNAMES +/* NOTE: There is no _wcscmpi, but this is for compatibility. */ +__CRT_INLINE int __cdecl +wcscmpi (const wchar_t * __ws1, const wchar_t * __ws2) + {return _wcsicmp (__ws1, __ws2);} +_CRTIMP wchar_t* __cdecl wcsdup (const wchar_t*); +_CRTIMP int __cdecl wcsicmp (const wchar_t*, const wchar_t*); +_CRTIMP int __cdecl wcsicoll (const wchar_t*, const wchar_t*); +_CRTIMP wchar_t* __cdecl wcslwr (wchar_t*); +_CRTIMP int __cdecl wcsnicmp (const wchar_t*, const wchar_t*, size_t); +_CRTIMP wchar_t* __cdecl wcsnset (wchar_t*, wchar_t, size_t); +_CRTIMP wchar_t* __cdecl wcsrev (wchar_t*); +_CRTIMP wchar_t* __cdecl wcsset (wchar_t*, wchar_t); +_CRTIMP wchar_t* __cdecl wcsupr (wchar_t*); +#endif /* Not _NO_OLDNAMES */ + +#endif /* Not strict ANSI */ + +#define _WSTRING_DEFINED +#endif /* _WSTRING_DEFINED */ + +/* These are resolved by -lmingwex. Alternatively, they can be resolved by + adding -lmsvcp60 to your command line, which will give you the VC++ + versions of these functions. If you want the latter and don't have + msvcp60.dll in your windows system directory, you can easily obtain + it with a search from your favorite search engine. */ +#ifndef __STRICT_ANSI__ +typedef wchar_t _Wint_t; +#endif + +typedef int mbstate_t; + +wint_t __cdecl btowc(int); +size_t __cdecl mbrlen(const char * __restrict__, size_t, + mbstate_t * __restrict__); +size_t __cdecl mbrtowc(wchar_t * __restrict__, const char * __restrict__, + size_t, mbstate_t * __restrict__); +size_t __cdecl mbsrtowcs(wchar_t * __restrict__, const char ** __restrict__, + size_t, mbstate_t * __restrict__); +size_t __cdecl wcrtomb(char * __restrict__, wchar_t, + mbstate_t * __restrict__); +size_t __cdecl wcsrtombs(char * __restrict__, const wchar_t ** __restrict__, + size_t, mbstate_t * __restrict__); +int __cdecl wctob(wint_t); + +#ifndef __NO_ISOCEXT /* these need static lib libmingwex.a */ +__CRT_INLINE int __cdecl fwide(FILE* __UNUSED_PARAM(stream), + int __UNUSED_PARAM(mode)) + {return -1;} /* limited to byte orientation */ +__CRT_INLINE int __cdecl mbsinit(const mbstate_t* __UNUSED_PARAM(ps)) + {return 1;} +wchar_t* __cdecl wmemset(wchar_t *, wchar_t, size_t); +wchar_t* __cdecl wmemchr(const wchar_t*, wchar_t, size_t); +int wmemcmp(const wchar_t*, const wchar_t *, size_t); +wchar_t* __cdecl wmemcpy(wchar_t* __restrict__, + const wchar_t* __restrict__, + size_t); +wchar_t* __cdecl wmemmove(wchar_t* s1, const wchar_t *, size_t); +long long __cdecl wcstoll(const wchar_t * __restrict__, + wchar_t** __restrict__, int); +unsigned long long __cdecl wcstoull(const wchar_t * __restrict__, + wchar_t ** __restrict__, int); +#endif /* __NO_ISOCEXT */ + +#ifndef __STRICT_ANSI__ +/* non-ANSI wide char functions from io.h, direct.h, sys/stat.h and locale.h. */ + +#ifndef _FSIZE_T_DEFINED +typedef unsigned long _fsize_t; +#define _FSIZE_T_DEFINED +#endif + +#ifndef _WFINDDATA_T_DEFINED +struct _wfinddata_t { + unsigned attrib; + time_t time_create; /* -1 for FAT file systems */ + time_t time_access; /* -1 for FAT file systems */ + time_t time_write; + _fsize_t size; + wchar_t name[260]; /* may include spaces. */ +}; +struct _wfinddatai64_t { + unsigned attrib; + time_t time_create; + time_t time_access; + time_t time_write; + __int64 size; + wchar_t name[260]; +}; +struct __wfinddata64_t { + unsigned attrib; + __time64_t time_create; + __time64_t time_access; + __time64_t time_write; + _fsize_t size; + wchar_t name[260]; +}; +#define _WFINDDATA_T_DEFINED +#endif + +/* Wide character versions. Also defined in io.h. */ +/* CHECK: I believe these only exist in MSVCRT, and not in CRTDLL. Also + applies to other wide character versions? */ +#if !defined (_WIO_DEFINED) +#if defined (__MSVCRT__) +#include /* For intptr_t. */ +_CRTIMP int __cdecl _waccess (const wchar_t*, int); +_CRTIMP int __cdecl _wchmod (const wchar_t*, int); +_CRTIMP int __cdecl _wcreat (const wchar_t*, int); +_CRTIMP long __cdecl _wfindfirst (const wchar_t*, struct _wfinddata_t *); +_CRTIMP int __cdecl _wfindnext (long, struct _wfinddata_t *); +_CRTIMP int __cdecl _wunlink (const wchar_t*); +_CRTIMP int __cdecl _wopen (const wchar_t*, int, ...); +_CRTIMP int __cdecl _wsopen (const wchar_t*, int, int, ...); +_CRTIMP wchar_t* __cdecl _wmktemp (wchar_t*); +_CRTIMP long __cdecl _wfindfirsti64 (const wchar_t*, struct _wfinddatai64_t*); +_CRTIMP int __cdecl _wfindnexti64 (long, struct _wfinddatai64_t*); +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP intptr_t __cdecl _wfindfirst64(const wchar_t*, struct __wfinddata64_t*); +_CRTIMP intptr_t __cdecl _wfindnext64(intptr_t, struct __wfinddata64_t*); +#endif /* __MSVCRT_VERSION__ >= 0x0601 */ +#endif /* defined (__MSVCRT__) */ +#define _WIO_DEFINED +#endif /* _WIO_DEFINED */ + +#ifndef _WDIRECT_DEFINED +/* Also in direct.h */ +#ifdef __MSVCRT__ +_CRTIMP int __cdecl _wchdir (const wchar_t*); +_CRTIMP wchar_t* __cdecl _wgetcwd (wchar_t*, int); +_CRTIMP wchar_t* __cdecl _wgetdcwd (int, wchar_t*, int); +_CRTIMP int __cdecl _wmkdir (const wchar_t*); +_CRTIMP int __cdecl _wrmdir (const wchar_t*); +#endif /* __MSVCRT__ */ +#define _WDIRECT_DEFINED +#endif /* _WDIRECT_DEFINED */ + +#ifndef _STAT_DEFINED +/* + * The structure manipulated and returned by stat and fstat. + * + * NOTE: If called on a directory the values in the time fields are not only + * invalid, they will cause localtime et. al. to return NULL. And calling + * asctime with a NULL pointer causes an Invalid Page Fault. So watch it! + */ +struct _stat +{ + _dev_t st_dev; /* Equivalent to drive number 0=A 1=B ... */ + _ino_t st_ino; /* Always zero ? */ + _mode_t st_mode; /* See above constants */ + short st_nlink; /* Number of links. */ + short st_uid; /* User: Maybe significant on NT ? */ + short st_gid; /* Group: Ditto */ + _dev_t st_rdev; /* Seems useless (not even filled in) */ + _off_t st_size; /* File size in bytes */ + time_t st_atime; /* Accessed date (always 00:00 hrs local + * on FAT) */ + time_t st_mtime; /* Modified time */ + time_t st_ctime; /* Creation time */ +}; + +#ifndef _NO_OLDNAMES +/* NOTE: Must be the same as _stat above. */ +struct stat +{ + _dev_t st_dev; /* Equivalent to drive number 0=A 1=B ... */ + _ino_t st_ino; /* Always zero ? */ + _mode_t st_mode; /* See above constants */ + short st_nlink; /* Number of links. */ + short st_uid; /* User: Maybe significant on NT ? */ + short st_gid; /* Group: Ditto */ + _dev_t st_rdev; /* Seems useless (not even filled in) */ + _off_t st_size; /* File size in bytes */ + time_t st_atime; /* Accessed date (always 00:00 hrs local + * on FAT) */ + time_t st_mtime; /* Modified time */ + time_t st_ctime; /* Creation time */ +}; +#endif /* _NO_OLDNAMES */ + +#if defined (__MSVCRT__) +struct _stati64 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; + }; + +struct __stat64 +{ + _dev_t st_dev; + _ino_t st_ino; + _mode_t st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; +}; +#endif /* __MSVCRT__ */ +#define _STAT_DEFINED +#endif /* _STAT_DEFINED */ + +#if !defined ( _WSTAT_DEFINED) +/* also declared in sys/stat.h */ +#if defined __MSVCRT__ +_CRTIMP int __cdecl _wstat (const wchar_t*, struct _stat*); +_CRTIMP int __cdecl _wstati64 (const wchar_t*, struct _stati64*); +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP int __cdecl _wstat64 (const wchar_t*, struct __stat64*); +#endif /* __MSVCRT_VERSION__ >= 0x0601 */ +#endif /* __MSVCRT__ */ +#define _WSTAT_DEFINED +#endif /* ! _WSTAT_DEFIND */ + +#ifndef _WLOCALE_DEFINED /* also declared in locale.h */ +_CRTIMP wchar_t* __cdecl _wsetlocale (int, const wchar_t*); +#define _WLOCALE_DEFINED +#endif + +#endif /* not __STRICT_ANSI__ */ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* not _WCHAR_H_ */ + diff --git a/reactos/lib/mingw/include/wctype.h b/reactos/lib/mingw/include/wctype.h new file mode 100644 index 00000000000..ed8f05f7764 --- /dev/null +++ b/reactos/lib/mingw/include/wctype.h @@ -0,0 +1,153 @@ +/* + * wctype.h + * + * Functions for testing wide character types and converting characters. + * + * This file is part of the Mingw32 package. + * + * Contributors: + * Created by Mumit Khan + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef _WCTYPE_H_ +#define _WCTYPE_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#define __need_wchar_t +#define __need_wint_t +#ifndef RC_INVOKED +#include +#endif /* Not RC_INVOKED */ + +/* + * The following flags are used to tell iswctype and _isctype what character + * types you are looking for. + */ +#define _UPPER 0x0001 +#define _LOWER 0x0002 +#define _DIGIT 0x0004 +#define _SPACE 0x0008 +#define _PUNCT 0x0010 +#define _CONTROL 0x0020 +#define _BLANK 0x0040 +#define _HEX 0x0080 +#define _LEADBYTE 0x8000 + +#define _ALPHA 0x0103 + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WEOF +#define WEOF (wchar_t)(0xFFFF) +#endif + +#ifndef _WCTYPE_T_DEFINED +typedef wchar_t wctype_t; +#define _WCTYPE_T_DEFINED +#endif + +/* Wide character equivalents - also in ctype.h */ +_CRTIMP int __cdecl iswalnum(wint_t); +_CRTIMP int __cdecl iswalpha(wint_t); +_CRTIMP int __cdecl iswascii(wint_t); +_CRTIMP int __cdecl iswcntrl(wint_t); +_CRTIMP int __cdecl iswctype(wint_t, wctype_t); +_CRTIMP int __cdecl is_wctype(wint_t, wctype_t); /* Obsolete! */ +_CRTIMP int __cdecl iswdigit(wint_t); +_CRTIMP int __cdecl iswgraph(wint_t); +_CRTIMP int __cdecl iswlower(wint_t); +_CRTIMP int __cdecl iswprint(wint_t); +_CRTIMP int __cdecl iswpunct(wint_t); +_CRTIMP int __cdecl iswspace(wint_t); +_CRTIMP int __cdecl iswupper(wint_t); +_CRTIMP int __cdecl iswxdigit(wint_t); + +/* Older MS docs uses wchar_t for arg and return type, while newer + online MS docs say arg is wint_t and return is int. + ISO C uses wint_t for both. */ +_CRTIMP wint_t __cdecl towlower (wint_t); +_CRTIMP wint_t __cdecl towupper (wint_t); + +_CRTIMP int __cdecl isleadbyte (int); + +/* Also in ctype.h */ + +#ifdef __DECLSPEC_SUPPORTED +__MINGW_IMPORT unsigned short _ctype[]; +# ifdef __MSVCRT__ + __MINGW_IMPORT unsigned short* _pctype; +# else /* CRTDLL */ + __MINGW_IMPORT unsigned short* _pctype_dll; +# define _pctype _pctype_dll +# endif + +#else /* ! __DECLSPEC_SUPPORTED */ +extern unsigned short** _imp___ctype; +#define _ctype (*_imp___ctype) +# ifdef __MSVCRT__ + extern unsigned short** _imp___pctype; +# define _pctype (*_imp___pctype) +# else /* CRTDLL */ + extern unsigned short** _imp___pctype_dll; +# define _pctype (*_imp___pctype_dll) +# endif /* CRTDLL */ +#endif /* __DECLSPEC_SUPPORTED */ + + +#if !(defined (__NO_INLINE__) || defined(__NO_CTYPE_INLINES) \ + || defined(__WCTYPE_INLINES_DEFINED)) +#define __WCTYPE_INLINES_DEFINED +__CRT_INLINE int __cdecl iswalnum(wint_t wc) {return (iswctype(wc,_ALPHA|_DIGIT));} +__CRT_INLINE int __cdecl iswalpha(wint_t wc) {return (iswctype(wc,_ALPHA));} +__CRT_INLINE int __cdecl iswascii(wint_t wc) {return ((wc & ~0x7F) ==0);} +__CRT_INLINE int __cdecl iswcntrl(wint_t wc) {return (iswctype(wc,_CONTROL));} +__CRT_INLINE int __cdecl iswdigit(wint_t wc) {return (iswctype(wc,_DIGIT));} +__CRT_INLINE int __cdecl iswgraph(wint_t wc) {return (iswctype(wc,_PUNCT|_ALPHA|_DIGIT));} +__CRT_INLINE int __cdecl iswlower(wint_t wc) {return (iswctype(wc,_LOWER));} +__CRT_INLINE int __cdecl iswprint(wint_t wc) {return (iswctype(wc,_BLANK|_PUNCT|_ALPHA|_DIGIT));} +__CRT_INLINE int __cdecl iswpunct(wint_t wc) {return (iswctype(wc,_PUNCT));} +__CRT_INLINE int __cdecl iswspace(wint_t wc) {return (iswctype(wc,_SPACE));} +__CRT_INLINE int __cdecl iswupper(wint_t wc) {return (iswctype(wc,_UPPER));} +__CRT_INLINE int __cdecl iswxdigit(wint_t wc) {return (iswctype(wc,_HEX));} +__CRT_INLINE int __cdecl isleadbyte(int c) {return (_pctype[(unsigned char)(c)] & _LEADBYTE);} +#endif /* !(defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED)) */ + + +typedef wchar_t wctrans_t; + +/* These are resolved by libmingwex.a. Note, that they are also exported + by the MS C++ runtime lib (msvcp60.dll). The msvcp60.dll implementations + of wctrans and towctrans are not C99 compliant in that wctrans("tolower") + returns 0, while std specifies that a non-zero value should be returned + for a valid string descriptor. If you want the MS behaviour (and you have + msvcp60.dll in your path) add -lmsvcp60 to your command line. */ + +wint_t __cdecl towctrans(wint_t, wctrans_t); +wctrans_t __cdecl wctrans(const char*); +wctype_t __cdecl wctype(const char*); + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _WCTYPE_H_ */ + diff --git a/reactos/lib/mingw/init.c b/reactos/lib/mingw/init.c new file mode 100644 index 00000000000..a30c035f25e --- /dev/null +++ b/reactos/lib/mingw/init.c @@ -0,0 +1,67 @@ +/* + * init.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Code to initialize standard file handles and command line arguments. + * This file is #included in both crt1.c and dllcrt1.c. + * + */ + +/* + * Access to a standard 'main'-like argument count and list. Also included + * is a table of environment variables. + */ +int _argc = 0; +char **_argv = 0; + +/* NOTE: Thanks to Pedro A. Aranda Gutiirrez for pointing + * this out to me. GetMainArgs (used below) takes a fourth argument + * which is an int that controls the globbing of the command line. If + * _CRT_glob is non-zero the command line will be globbed (e.g. *.* + * expanded to be all files in the startup directory). In the mingw32 + * library a _CRT_glob variable is defined as being -1, enabling + * this command line globbing by default. To turn it off and do all + * command line processing yourself (and possibly escape bogons in + * MS's globbing code) include a line in one of your source modules + * defining _CRT_glob and setting it to zero, like this: + * int _CRT_glob = 0; + */ +extern int _CRT_glob; + +#ifdef __MSVCRT__ +typedef struct { + int newmode; +} _startupinfo; +extern void __getmainargs (int *, char ***, char ***, int, _startupinfo *); +#else +extern void __GetMainArgs (int *, char ***, char ***, int); +#endif + +/* + * Initialize the _argc, _argv and environ variables. + */ +static void +_mingw32_init_mainargs () +{ + /* The environ variable is provided directly in stdlib.h through + * a dll function call. */ + char **dummy_environ; +#ifdef __MSVCRT__ + _startupinfo start_info; + start_info.newmode = 0; +#endif + + /* + * Microsoft's runtime provides a function for doing just that. + */ +#ifdef __MSVCRT__ + (void) __getmainargs (&_argc, &_argv, &dummy_environ, _CRT_glob, + &start_info); +#else + /* CRTDLL version */ + (void) __GetMainArgs (&_argc, &_argv, &dummy_environ, _CRT_glob); +#endif +} + diff --git a/reactos/lib/mingw/isascii.c b/reactos/lib/mingw/isascii.c new file mode 100644 index 00000000000..9d3385c3f01 --- /dev/null +++ b/reactos/lib/mingw/isascii.c @@ -0,0 +1,21 @@ +/* + * isascii.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Oldnames from ANSI header ctype.h + * + * Some wrapper functions for those old name functions whose appropriate + * equivalents are not simply underscore prefixed. + * + */ + +#include + +int +isascii (int c) +{ + return __isascii(c); +} + diff --git a/reactos/lib/mingw/iscsym.c b/reactos/lib/mingw/iscsym.c new file mode 100644 index 00000000000..ea9a571ac18 --- /dev/null +++ b/reactos/lib/mingw/iscsym.c @@ -0,0 +1,20 @@ +/* + * iscsym.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Oldnames from ANSI header ctype.h + * + * Some wrapper functions for those old name functions whose appropriate + * equivalents are not simply underscore prefixed. + * + */ + +#include + +int +iscsym (int c) +{ + return __iscsym(c); +} diff --git a/reactos/lib/mingw/iscsymf.c b/reactos/lib/mingw/iscsymf.c new file mode 100644 index 00000000000..6afde993e6a --- /dev/null +++ b/reactos/lib/mingw/iscsymf.c @@ -0,0 +1,21 @@ +/* + * iscsymf.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Oldnames from ANSI header ctype.h + * + * Some wrapper functions for those old name functions whose appropriate + * equivalents are not simply underscore prefixed. + * + */ + +#include + +int +iscsymf (int c) +{ + return __iscsymf(c); +} + diff --git a/reactos/lib/mingw/main.c b/reactos/lib/mingw/main.c new file mode 100644 index 00000000000..5eeb57044bb --- /dev/null +++ b/reactos/lib/mingw/main.c @@ -0,0 +1,79 @@ +/* + * main.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Extra startup code for applications which do not have a main function + * of their own (but do have a WinMain). Generally these are GUI + * applications, but they don't *have* to be. + * + */ + +#include +#include +#include + +#define ISSPACE(a) (a == ' ' || a == '\t') + +extern int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, + LPSTR szCmdLine, int nShow); + +int +main (int argc, const char *argv[], const char *environ[]) +{ + char *szCmd; + STARTUPINFO startinfo; + int nRet; + + /* Get the command line passed to the process. */ + szCmd = GetCommandLineA (); + GetStartupInfoA (&startinfo); + + /* Strip off the name of the application and any leading + * whitespace. */ + if (szCmd) + { + while (ISSPACE (*szCmd)) + { + szCmd++; + } + + /* On my system I always get the app name enclosed + * in quotes... */ + if (*szCmd == '\"') + { + do + { + szCmd++; + } + while (*szCmd != '\"' && *szCmd != '\0'); + + if (*szCmd == '\"') + { + szCmd++; + } + } + else + { + /* If no quotes then assume first token is program + * name. */ + while (!ISSPACE (*szCmd) && *szCmd != '\0') + { + szCmd++; + } + } + + while (ISSPACE (*szCmd)) + { + szCmd++; + } + } + + nRet = WinMain (GetModuleHandle (NULL), NULL, szCmd, + (startinfo.dwFlags & STARTF_USESHOWWINDOW) ? + startinfo.wShowWindow : SW_SHOWDEFAULT); + + return nRet; +} + diff --git a/reactos/lib/mingw/mingw.rbuild b/reactos/lib/mingw/mingw.rbuild new file mode 100644 index 00000000000..47343e63281 --- /dev/null +++ b/reactos/lib/mingw/mingw.rbuild @@ -0,0 +1,36 @@ + + + + + + cpu_features.c + CRTfmode.c + CRTglob.c + CRTinit.c + gccmain.c + getopt.c + isascii.c + iscsym.c + iscsymf.c + pseudo-reloc.c + strcasecmp.c + strncasecmp.c + toascii.c + wcscmpi.c + _wgetopt.c + + + binmode.c + crt1.c + main.c + + + wbinmode.c + wcrt1.c + wmain.c + + + dllcrt1.c + + + diff --git a/reactos/lib/mingw/moldname-msvcrt.def b/reactos/lib/mingw/moldname-msvcrt.def new file mode 100644 index 00000000000..b4f06807000 --- /dev/null +++ b/reactos/lib/mingw/moldname-msvcrt.def @@ -0,0 +1,158 @@ + + +; +; moldname-msvcrt.def +; +; Exports from the runtime except that these exports are actually preceeded +; by a underscore in the actual DLL. These correspond to functions which +; are non-ANSI and were prefixed with an underscore to avoid name space +; clutter. However many, in fact most programs still use a few of these +; functions without the underscore. This .def file is specially processed +; to make those non-underscored name function calls call the equivalent +; underscored functions. +; +; Contributors: +; Created by Colin Peters +; Maintained by Mumit Khan +; +; THIS SOFTWARE IS NOT COPYRIGHTED +; +; This source code is offered for use in the public domain. You may +; use, modify or distribute it freely. +; +; This code is distributed in the hope that it will be useful but +; WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY +; DISCLAMED. This includes but is not limited to warrenties of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; +EXPORTS +access +chdir +chmod +chsize +close +creat +cwait + +daylight DATA + +dup +dup2 +ecvt +eof +execl +execle +execlp +execlpe +execv +execve +execvp +execvpe +fcvt +fdopen +fgetchar +fgetwchar +filelength +fileno +; Alias fpreset is set in CRT_fp10,c and CRT_fp8.c. +; fpreset +fputchar +fputwchar +fstat +ftime +gcvt +getch +getche +getcwd +getpid +getw +heapwalk +isatty +itoa +kbhit +lfind +lsearch +lseek +ltoa +memccpy +memicmp +mkdir +mktemp +open +pclose +popen +putch +putenv +putw +read +rmdir +rmtmp +searchenv +setmode +sopen +spawnl +spawnle +spawnlp +spawnlpe +spawnv +spawnve +spawnvp +spawnvpe +stat +strcmpi +strdup +stricmp +stricoll +strlwr +strnicmp +strnset +strrev +strset +strupr +swab +tell +tempnam + +timezone DATA + +; export tzname for both. See +tzname DATA +tzset +umask +ungetch +unlink +utime +wcsdup +wcsicmp +wcsicoll +wcslwr +wcsnicmp +wcsnset +wcsrev +wcsset +wcsupr + +wpopen + +write +; non-ANSI functions declared in math.h +j0 +j1 +jn +y0 +y1 +yn +chgsign +scalb +finite +fpclass +; C99 functions +cabs +hypot +logb +nextafter + +; Additional definitions for ReactOS: +snwprintf +snprintf +strtoull=_strtoui64 diff --git a/reactos/lib/mingw/pseudo-reloc.c b/reactos/lib/mingw/pseudo-reloc.c new file mode 100644 index 00000000000..9fe607d2cb8 --- /dev/null +++ b/reactos/lib/mingw/pseudo-reloc.c @@ -0,0 +1,46 @@ +/* pseudo-reloc.c + + Written by Egor Duda + THIS SOFTWARE IS NOT COPYRIGHTED + + This source code is offered for use in the public domain. You may + use, modify or distribute it freely. + + This code is distributed in the hope that it will be useful but + WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY + DISCLAMED. This includes but is not limited to warrenties of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +*/ + +#include + +extern char __RUNTIME_PSEUDO_RELOC_LIST__; +extern char __RUNTIME_PSEUDO_RELOC_LIST_END__; +extern char _image_base__; + +typedef struct + { + DWORD addend; + DWORD target; + } +runtime_pseudo_reloc; + +static void +do_pseudo_reloc (void* start, void* end, void* base) +{ + DWORD reloc_target; + runtime_pseudo_reloc* r; + for (r = (runtime_pseudo_reloc*) start; r < (runtime_pseudo_reloc*) end; r++) + { + reloc_target = (DWORD) base + r->target; + *((DWORD*) reloc_target) += r->addend; + } +} + +void +_pei386_runtime_relocator () +{ + do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__, + &__RUNTIME_PSEUDO_RELOC_LIST_END__, + &_image_base__); +} diff --git a/reactos/lib/mingw/strcasecmp.c b/reactos/lib/mingw/strcasecmp.c new file mode 100644 index 00000000000..a238e22f259 --- /dev/null +++ b/reactos/lib/mingw/strcasecmp.c @@ -0,0 +1,21 @@ +/* + * strcasecmp.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Oldnames from ANSI header string.h + * + * Some wrapper functions for those old name functions whose appropriate + * equivalents are not simply underscore prefixed. + * + */ + +#include + +int +strcasecmp (const char *sz1, const char *sz2) +{ + return _stricmp (sz1, sz2); +} + diff --git a/reactos/lib/mingw/strncasecmp.c b/reactos/lib/mingw/strncasecmp.c new file mode 100644 index 00000000000..7607ea1d001 --- /dev/null +++ b/reactos/lib/mingw/strncasecmp.c @@ -0,0 +1,21 @@ +/* + * strncasecmp.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Oldnames from ANSI header string.h + * + * Some wrapper functions for those old name functions whose appropriate + * equivalents are not simply underscore prefixed. + * + */ + +#include + +int +strncasecmp (const char *sz1, const char *sz2, size_t sizeMaxCompare) +{ + return _strnicmp (sz1, sz2, sizeMaxCompare); +} + diff --git a/reactos/lib/tgetopt/tgetopt.h b/reactos/lib/mingw/tgetopt.h similarity index 100% rename from reactos/lib/tgetopt/tgetopt.h rename to reactos/lib/mingw/tgetopt.h diff --git a/reactos/lib/mingw/toascii.c b/reactos/lib/mingw/toascii.c new file mode 100644 index 00000000000..be9f2f50bd5 --- /dev/null +++ b/reactos/lib/mingw/toascii.c @@ -0,0 +1,22 @@ +/* + * toascii.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Oldnames from ANSI header ctype.h + * + * Some wrapper functions for those old name functions whose appropriate + * equivalents are not simply underscore prefixed. + * + */ + +#include + + +int +toascii (int c) +{ + return __toascii(c); +} + diff --git a/reactos/lib/mingw/wbinmode.c b/reactos/lib/mingw/wbinmode.c new file mode 100644 index 00000000000..1cc3dedbfc8 --- /dev/null +++ b/reactos/lib/mingw/wbinmode.c @@ -0,0 +1,5 @@ +#include + +/* Set default file mode to binary */ + +int _fmode = _O_BINARY; diff --git a/reactos/lib/mingw/wcrt1.c b/reactos/lib/mingw/wcrt1.c new file mode 100644 index 00000000000..b7eeaece113 --- /dev/null +++ b/reactos/lib/mingw/wcrt1.c @@ -0,0 +1,283 @@ +/* + * crt1.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Source code for the startup proceedures used by all programs. This code + * is compiled to make crt1.o, which should be located in the library path. + * + */ + +/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to + avoid problems with older GCC. */ +#define __IN_MINGW_RUNTIME +#include +#include +#include +#include +#include +#define WIN32_LEAN_AND_MEAN +#include +#include + +/* NOTE: The code for initializing the _argv, _argc, and environ variables + * has been moved to a separate .c file which is included in both + * crt1.c and dllcrt1.c. This means changes in the code don't have to + * be manually synchronized, but it does lead to this not-generally- + * a-good-idea use of include. */ +#include "winit.c" +#include "cpu_features.h" + +extern void _pei386_runtime_relocator (void); + +extern int wmain (int, wchar_t **, wchar_t **); + +/* + * Must have the correct app type for MSVCRT. + */ + +#ifdef __MSVCRT__ +#define __UNKNOWN_APP 0 +#define __CONSOLE_APP 1 +#define __GUI_APP 2 +__MINGW_IMPORT void __set_app_type(int); +#endif /* __MSVCRT__ */ + +/* Global _fmode for this .exe, not the one in msvcrt.dll, + The default is set in txtmode.o in libmingw32.a */ +/* Override the dllimport'd declarations in stdlib.h */ +#undef _fmode +extern int _fmode; +#ifdef __MSVCRT__ +extern int* __p__fmode(void); /* To access the dll _fmode */ +#endif + +/* + * Setup the default file handles to have the _CRT_fmode mode, as well as + * any new files created by the user. + */ +extern int _CRT_fmode; + +static void +_mingw32_init_fmode (void) +{ + /* Don't set the std file mode if the user hasn't set any value for it. */ + if (_CRT_fmode) + { + _fmode = _CRT_fmode; + + /* + * This overrides the default file mode settings for stdin, + * stdout and stderr. At first I thought you would have to + * test with isatty, but it seems that the DOS console at + * least is smart enough to handle _O_BINARY stdout and + * still display correctly. + */ + if (stdin) + { + _setmode (_fileno (stdin), _CRT_fmode); + } + if (stdout) + { + _setmode (_fileno (stdout), _CRT_fmode); + } + if (stderr) + { + _setmode (_fileno (stderr), _CRT_fmode); + } + } + + /* Now sync the dll _fmode to the one for this .exe. */ +#ifdef __MSVCRT__ + *__p__fmode() = _fmode; +#else + *_imp___fmode_dll = _fmode; +#endif +} + +/* This function will be called when a trap occurs. Thanks to Jacob + Navia for his contribution. */ +static CALLBACK long +_gnu_exception_handler (EXCEPTION_POINTERS * exception_data) +{ + void (*old_handler) (int); + long action = EXCEPTION_CONTINUE_SEARCH; + int reset_fpu = 0; + + switch (exception_data->ExceptionRecord->ExceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + /* test if the user has set SIGSEGV */ + old_handler = signal (SIGSEGV, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGSEGV, SIG_IGN); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGSEGV); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: + /* test if the user has set SIGILL */ + old_handler = signal (SIGILL, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGILL, SIG_IGN); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGILL); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_UNDERFLOW: + case EXCEPTION_FLT_INEXACT_RESULT: + reset_fpu = 1; + /* fall through. */ + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + /* test if the user has set SIGFPE */ + old_handler = signal (SIGFPE, SIG_DFL); + if (old_handler == SIG_IGN) + { + signal (SIGFPE, SIG_IGN); + if (reset_fpu) + _fpreset (); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGFPE); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + default: + break; + } + return action; +} + +/* + * The function mainCRTStartup is the entry point for all console programs. + */ +static void __attribute__((noreturn)) +__mingw_wCRTStartup (void) +{ + int nRet; + + /* + * Set up the top-level exception handler so that signal handling + * works as expected. The mapping between ANSI/POSIX signals and + * Win32 SE is not 1-to-1, so caveat emptore. + * + */ + SetUnhandledExceptionFilter (_gnu_exception_handler); + + /* + * Initialize floating point unit. + */ + __cpu_features_init (); /* Do we have SSE, etc.*/ + _fpreset (); /* Supplied by the runtime library. */ + + /* + * Set up __argc, __argv and _wenviron. + */ + _mingw32_init_wmainargs (); + + /* + * Sets the default file mode. + * If _CRT_fmode is set, also set mode for stdin, stdout + * and stderr, as well + * NOTE: DLLs don't do this because that would be rude! + */ + _mingw32_init_fmode (); + + /* Adust references to dllimported data that have non-zero offsets. */ + _pei386_runtime_relocator (); + + /* Align the stack to 16 bytes for the sake of SSE ops in main + or in functions inlined into main. */ + asm __volatile__ ("andl $-16, %%esp" : : : "%esp"); + + /* + * Call the main function. If the user does not supply one + * the one in the 'libmingw32.a' library will be linked in, and + * that one calls WinMain. See main.c in the 'lib' dir + * for more details. + */ + nRet = wmain (_argc, _wargv, _wenviron); + + /* + * Perform exit processing for the C library. This means + * flushing output and calling 'atexit' registered functions. + */ + _cexit (); + + ExitProcess (nRet); +} + +/* + * The function mainCRTStartup is the entry point for all console programs. + */ +void +wmainCRTStartup (void) +{ +#ifdef __MSVCRT__ + __set_app_type (__CONSOLE_APP); +#endif + __mingw_wCRTStartup (); +} + +/* + * For now the GUI startup function is the same as the console one. + * This simply gets rid of the annoying warning about not being able + * to find WinMainCRTStartup when linking GUI applications. + */ +void +wWinMainCRTStartup (void) +{ +#ifdef __MSVCRT__ + __set_app_type (__GUI_APP); +#endif + __mingw_wCRTStartup (); +} + +#if 0 +/* + * We force use of library version of atexit, which is only + * visible in import lib as _imp__atexit + */ +extern int (*_imp__atexit)(void (*)(void)); +int atexit (void (* pfn )(void) ) +{ + return ( (*_imp__atexit)(pfn)); +} + +/* Likewise for non-ANSI _onexit */ +extern _onexit_t (*_imp___onexit)(_onexit_t); +_onexit_t +_onexit (_onexit_t pfn ) +{ + return (*_imp___onexit)(pfn); +} +#endif diff --git a/reactos/lib/mingw/wcscmpi.c b/reactos/lib/mingw/wcscmpi.c new file mode 100644 index 00000000000..497964b3964 --- /dev/null +++ b/reactos/lib/mingw/wcscmpi.c @@ -0,0 +1,21 @@ +/* + * wcscmpi.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Oldnames from ANSI header string.h + * + * Some wrapper functions for those old name functions whose appropriate + * equivalents are not simply underscore prefixed. + * + */ + +#include + +int +wcscmpi (const wchar_t * ws1, const wchar_t * ws2) +{ + return _wcsicmp (ws1, ws2); +} + diff --git a/reactos/lib/mingw/winit.c b/reactos/lib/mingw/winit.c new file mode 100644 index 00000000000..4a5917ebeb8 --- /dev/null +++ b/reactos/lib/mingw/winit.c @@ -0,0 +1,66 @@ +/* + * init.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Code to initialize standard file handles and command line arguments. + * This file is #included in both crt1.c and dllcrt1.c. + * + */ + +/* + * Access to a standard 'main'-like argument count and list. Also included + * is a table of environment variables. + */ +int _argc = 0; +wchar_t **_wargv = 0; + +/* NOTE: Thanks to Pedro A. Aranda Gutiirrez for pointing + * this out to me. GetMainArgs (used below) takes a fourth argument + * which is an int that controls the globbing of the command line. If + * _CRT_glob is non-zero the command line will be globbed (e.g. *.* + * expanded to be all files in the startup directory). In the mingw32 + * library a _CRT_glob variable is defined as being -1, enabling + * this command line globbing by default. To turn it off and do all + * command line processing yourself (and possibly escape bogons in + * MS's globbing code) include a line in one of your source modules + * defining _CRT_glob and setting it to zero, like this: + * int _CRT_glob = 0; + */ +extern int _CRT_glob; + +#ifdef __MSVCRT__ +typedef struct { + int newmode; +} _startupinfo; +extern void __wgetmainargs (int *, wchar_t ***, wchar_t ***, int, _startupinfo *); +#else +#error Cannot build unicode version against crtdll +#endif + +/* + * Initialize the _argc, _argv and environ variables. + */ +static void +_mingw32_init_wmainargs () +{ + /* The environ variable is provided directly in stdlib.h through + * a dll function call. */ + wchar_t **dummy_environ; +#ifdef __MSVCRT__ + _startupinfo start_info; + start_info.newmode = 0; +#endif + + /* + * Microsoft's runtime provides a function for doing just that. + */ +#ifdef __MSVCRT__ + (void) __wgetmainargs (&_argc, &_wargv, &dummy_environ, _CRT_glob, + &start_info); +#else +#error Cannot build unicode version against crtdll +#endif +} + diff --git a/reactos/lib/mingw/wmain.c b/reactos/lib/mingw/wmain.c new file mode 100644 index 00000000000..f3846b12765 --- /dev/null +++ b/reactos/lib/mingw/wmain.c @@ -0,0 +1,79 @@ +/* + * main.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Extra startup code for applications which do not have a main function + * of their own (but do have a WinMain). Generally these are GUI + * applications, but they don't *have* to be. + * + */ + +#include +#include +#include + +#define ISSPACE(a) (a == ' ' || a == '\t') + +extern int PASCAL wWinMain (HINSTANCE hInst, HINSTANCE hPrevInst, + LPWSTR szCmdLine, int nShow); + +int +wmain (int argc, const wchar_t *argv[], const wchar_t *environ[]) +{ + wchar_t *szCmd; + STARTUPINFOW startinfo; + int nRet; + + /* Get the command line passed to the process. */ + szCmd = GetCommandLineW (); + GetStartupInfoW (&startinfo); + + /* Strip off the name of the application and any leading + * whitespace. */ + if (szCmd) + { + while (ISSPACE (*szCmd)) + { + szCmd++; + } + + /* On my system I always get the app name enclosed + * in quotes... */ + if (*szCmd == '\"') + { + do + { + szCmd++; + } + while (*szCmd != '\"' && *szCmd != '\0'); + + if (*szCmd == '\"') + { + szCmd++; + } + } + else + { + /* If no quotes then assume first token is program + * name. */ + while (!ISSPACE (*szCmd) && *szCmd != '\0') + { + szCmd++; + } + } + + while (ISSPACE (*szCmd)) + { + szCmd++; + } + } + + nRet = wWinMain (GetModuleHandle (NULL), NULL, szCmd, + (startinfo.dwFlags & STARTF_USESHOWWINDOW) ? + startinfo.wShowWindow : SW_SHOWDEFAULT); + + return nRet; +} + diff --git a/reactos/lib/strmiids/strmiids.c b/reactos/lib/strmiids/strmiids.c index 1f9c2fe786a..deed1ecf6d9 100644 --- a/reactos/lib/strmiids/strmiids.c +++ b/reactos/lib/strmiids/strmiids.c @@ -9,13 +9,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ - -#if defined(__LCC__) || defined(__GNUC__) -#define INITGUID 1 -#include -#else +#define INITGUID #include -#endif +#include DEFINE_GUID(CLSID_AMAudioData,0xf2468580,0xaf8a,0x11d0,0x82,0x12,0x00,0xc0,0x4f,0xc3,0x2c,0x45); DEFINE_GUID(CLSID_AMAudioStream,0x8496e040,0xaf4c,0x11d0,0x82,0x12,0x00,0xc0,0x4f,0xc3,0x2c,0x45); diff --git a/reactos/lib/uuid/uuid.c b/reactos/lib/uuid/uuid.c index c470ccfd732..69a8a65e2f3 100644 --- a/reactos/lib/uuid/uuid.c +++ b/reactos/lib/uuid/uuid.c @@ -26,29 +26,27 @@ /* GUIDs defined in uuids.lib */ -DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); - #include "windef.h" #include "winbase.h" #include "wingdi.h" #include "winuser.h" #include "objbase.h" -#include "servprov.h" +#include "wine/servprov.h" #include "oleauto.h" #include "oleidl.h" -#include "objidl.h" +#include "wine/oleidl.h" #include "olectl.h" -#include "ocidl.h" +#include "wine/ocidl.h" #include "mshtmhst.h" #include "docobj.h" -#include "exdisp.h" +#include "wine/exdisp.h" #include "hlink.h" -#include "shlguid.h" +#include "wine/shlguid.h" #include "shlobj.h" #include "shldisp.h" #include "comcat.h" @@ -94,3 +92,5 @@ DEFINE_GUID(CLSID_StdFont,0x0be35203,0x8f91,0x11ce,0x9d,0xe3,0x00,0xaa,0x00,0x4b DEFINE_GUID(CLSID_StdPicture,0x0be35204,0x8f91,0x11ce,0x9d,0xe3,0x00,0xaa,0x00,0x4b,0xb8,0x51); DEFINE_GUID(CLSID_HTMLDocument, 0x25336920, 0x03f9, 0x11cf, 0x8f,0xd0, 0x00,0xaa,0x00,0x68,0x6f,0x13); + +DEFINE_GUID(GUID_NULL, 0L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); diff --git a/reactos/regtests/kmtloader/kmtloader.rbuild b/reactos/regtests/kmtloader/kmtloader.rbuild index df91cf15338..56afda216c8 100644 --- a/reactos/regtests/kmtloader/kmtloader.rbuild +++ b/reactos/regtests/kmtloader/kmtloader.rbuild @@ -1,5 +1,6 @@ - + kernel32 + advapi32 kmtloader.c diff --git a/reactos/regtests/queuetest/queuetest.rbuild b/reactos/regtests/queuetest/queuetest.rbuild index 14458dd6dcb..7211e75ea32 100644 --- a/reactos/regtests/queuetest/queuetest.rbuild +++ b/reactos/regtests/queuetest/queuetest.rbuild @@ -1,4 +1,5 @@ + kernel32 queuetest.c diff --git a/reactos/regtests/winetests/advapi32/advapi32.rbuild b/reactos/regtests/winetests/advapi32/advapi32.rbuild index ae881725782..a77f327c75c 100644 --- a/reactos/regtests/winetests/advapi32/advapi32.rbuild +++ b/reactos/regtests/winetests/advapi32/advapi32.rbuild @@ -2,6 +2,7 @@ . advapi32 + kernel32 ntdll registry.c security.c diff --git a/reactos/regtests/winetests/cabinet/cabinet.rbuild b/reactos/regtests/winetests/cabinet/cabinet.rbuild index 69b9e57cb36..faa517953cc 100644 --- a/reactos/regtests/winetests/cabinet/cabinet.rbuild +++ b/reactos/regtests/winetests/cabinet/cabinet.rbuild @@ -2,6 +2,7 @@ . cabinet + kernel32 ntdll extract.c testlist.c diff --git a/reactos/regtests/winetests/comctl32/comctl32.rbuild b/reactos/regtests/winetests/comctl32/comctl32.rbuild index 6d29726bad0..407eac31b69 100644 --- a/reactos/regtests/winetests/comctl32/comctl32.rbuild +++ b/reactos/regtests/winetests/comctl32/comctl32.rbuild @@ -6,6 +6,9 @@ comctl32 ntdll gdi32 + user32 + kernel32 + advapi32 comboex.c dpa.c header.c diff --git a/reactos/regtests/winetests/gdi32/gdi32.rbuild b/reactos/regtests/winetests/gdi32/gdi32.rbuild index 54567679566..d9d1e40945f 100644 --- a/reactos/regtests/winetests/gdi32/gdi32.rbuild +++ b/reactos/regtests/winetests/gdi32/gdi32.rbuild @@ -3,6 +3,9 @@ ntdll gdi32 + kernel32 + user32 + advapi32 bitmap.c brush.c gdiobj.c diff --git a/reactos/regtests/winetests/icmp/icmp.rbuild b/reactos/regtests/winetests/icmp/icmp.rbuild index 5a351bdf1e3..535a36256d3 100644 --- a/reactos/regtests/winetests/icmp/icmp.rbuild +++ b/reactos/regtests/winetests/icmp/icmp.rbuild @@ -1,6 +1,7 @@ . + kernel32 ntdll icmp icmp.c diff --git a/reactos/regtests/winetests/lz32/lz32.rbuild b/reactos/regtests/winetests/lz32/lz32.rbuild index c8360256fb4..dd2500a3069 100644 --- a/reactos/regtests/winetests/lz32/lz32.rbuild +++ b/reactos/regtests/winetests/lz32/lz32.rbuild @@ -1,6 +1,7 @@ . + kernel32 ntdll lz32 testlist.c diff --git a/reactos/regtests/winetests/msvcrt/msvcrt.rbuild b/reactos/regtests/winetests/msvcrt/msvcrt.rbuild index d20f58a7ee3..3b20696c4f8 100644 --- a/reactos/regtests/winetests/msvcrt/msvcrt.rbuild +++ b/reactos/regtests/winetests/msvcrt/msvcrt.rbuild @@ -1,6 +1,7 @@ . + kernel32 ntdll cpp.c dir.c diff --git a/reactos/regtests/winetests/ntdll/ntdll.rbuild b/reactos/regtests/winetests/ntdll/ntdll.rbuild index 91833dd7730..886ac2af625 100644 --- a/reactos/regtests/winetests/ntdll/ntdll.rbuild +++ b/reactos/regtests/winetests/ntdll/ntdll.rbuild @@ -1,6 +1,7 @@ . + kernel32 ntdll atom.c change.c diff --git a/reactos/regtests/winetests/powrprof/powrprof.rbuild b/reactos/regtests/winetests/powrprof/powrprof.rbuild index ea0b1b9b0a3..4d21fb5ca28 100644 --- a/reactos/regtests/winetests/powrprof/powrprof.rbuild +++ b/reactos/regtests/winetests/powrprof/powrprof.rbuild @@ -1,10 +1,12 @@ - . - + . + - ntdll - powrprof - testlist.c - pwrprof.c + powrprof + ntdll + advapi32 + kernel32 + testlist.c + pwrprof.c diff --git a/reactos/regtests/winetests/psapi/psapi.rbuild b/reactos/regtests/winetests/psapi/psapi.rbuild index a34f15c1635..97725f7244a 100644 --- a/reactos/regtests/winetests/psapi/psapi.rbuild +++ b/reactos/regtests/winetests/psapi/psapi.rbuild @@ -1,6 +1,7 @@ . + kernel32 ntdll psapi testlist.c diff --git a/reactos/regtests/winetests/setupapi/setupapi.rbuild b/reactos/regtests/winetests/setupapi/setupapi.rbuild index 7ed50010b77..9b4ab741170 100644 --- a/reactos/regtests/winetests/setupapi/setupapi.rbuild +++ b/reactos/regtests/winetests/setupapi/setupapi.rbuild @@ -2,6 +2,8 @@ . ntdll + kernel32 + advapi32 setupapi devclass.c install.c diff --git a/reactos/regtests/winetests/shell32/shell32.rbuild b/reactos/regtests/winetests/shell32/shell32.rbuild index 3b7ff981e83..a4c85e1123d 100644 --- a/reactos/regtests/winetests/shell32/shell32.rbuild +++ b/reactos/regtests/winetests/shell32/shell32.rbuild @@ -3,9 +3,10 @@ ntdll shell32 + kernel32 + advapi32 shlwapi ole32 - uuid shelllink.c shellpath.c shlexec.c diff --git a/reactos/regtests/winetests/shell32/shelllink.c b/reactos/regtests/winetests/shell32/shelllink.c index 0ff121d5e42..12d15552a14 100755 --- a/reactos/regtests/winetests/shell32/shelllink.c +++ b/reactos/regtests/winetests/shell32/shelllink.c @@ -30,6 +30,7 @@ #include #include "windef.h" #include "winbase.h" +#include "basetyps.h" #include "shlguid.h" //#include "wine/shobjidl.h" #include "shlobj.h" @@ -44,6 +45,7 @@ extern void WINAPI ILFree(LPITEMIDLIST pidl); static const WCHAR lnkfile[]= { 'C',':','\\','t','e','s','t','.','l','n','k',0 }; static const WCHAR notafile[]= { 'C',':','\\','n','o','n','e','x','i','s','t','e','n','t','\\','f','i','l','e',0 }; +const GUID IID_IPersistFile = { 0x0000010b, 0x0000, 0x0000, { 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46 } }; /* For some reason SHILCreateFromPath does not work on Win98 and * SHSimpleIDListFromPathA does not work on NT4. But if we call both we diff --git a/reactos/regtests/winetests/shlwapi/shlwapi.rbuild b/reactos/regtests/winetests/shlwapi/shlwapi.rbuild index 35a25892616..5c23c6d9d7e 100644 --- a/reactos/regtests/winetests/shlwapi/shlwapi.rbuild +++ b/reactos/regtests/winetests/shlwapi/shlwapi.rbuild @@ -5,6 +5,8 @@ shlwapi ole32 oleaut32 + kernel32 + advapi32 clist.c ordinal.c shreg.c diff --git a/reactos/regtests/winetests/version/version.rbuild b/reactos/regtests/winetests/version/version.rbuild index 872405cdfd8..3fc14d46aac 100644 --- a/reactos/regtests/winetests/version/version.rbuild +++ b/reactos/regtests/winetests/version/version.rbuild @@ -3,6 +3,7 @@ ntdll version + kernel32 testlist.c info.c diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index b20a2180187..f7b382b4897 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -147,6 +147,7 @@ MingwBackend::ProcessModules () MingwModuleHandler* h = MingwModuleHandler::InstanciateHandler ( module, this ); + h->AddImplicitLibraries ( module ); if ( use_pch && CanEnablePreCompiledHeaderSupportForModule ( module ) ) h->EnablePreCompiledHeaderSupport (); if ( module.host == HostDefault ) diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp index 0bca7e11d62..1478eed6d66 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp @@ -1556,12 +1556,13 @@ MingwModuleHandler::GenerateLinkerCommand ( fprintf ( fMakefile, "\t$(ECHO_LD)\n" ); string targetName ( module.GetTargetName () ); + string killAt = module.mangledSymbols ? "" : "--kill-at"; + if ( module.IsDLL () ) { string temp_exp = ros_temp + module.name + ".temp.exp"; CLEAN_FILE ( temp_exp ); - string killAt = module.mangledSymbols ? "" : "--kill-at"; fprintf ( fMakefile, "\t${dlltool} --dllname %s --def %s --output-exp %s %s\n", targetName.c_str (), @@ -1734,6 +1735,18 @@ MingwModuleHandler::GenerateArchiveTarget ( const string& ar, objs_macro.c_str (), GetDirectory(archiveFilename).c_str() ); + if ( module.type == StaticLibrary && module.importLibrary ) + { + string archiveFilename ( GetModuleArchiveFilename () ); + string definitionFilename ( GetDefinitionFilename () ); + + fprintf ( fMakefile, + "\t${dlltool} --dllname %s --def %s --output-lib $@ %s -U\n", + module.importLibrary->dllname.c_str (), + definitionFilename.c_str (), + module.mangledSymbols ? "" : "--kill-at" ); + } + fprintf ( fMakefile, "\t$(ECHO_AR)\n" ); fprintf ( fMakefile, @@ -1950,6 +1963,13 @@ MingwModuleHandler::GenerateOtherMacros () linkerflags.c_str () ); } + if ( module.type == StaticLibrary && module.isStartupLib ) + { + fprintf ( fMakefile, + "%s += -Wno-main\n\n", + cflagsMacro.c_str () ); + } + fprintf ( fMakefile, "\n\n" ); // future references to the macros will be to get their values @@ -2564,6 +2584,42 @@ MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler ( { } +static void +MingwAddImplicitLibraries( Module &module ) +{ + Library* pLibrary; + + if ( !module.isDefaultEntryPoint ) + return; + + if ( module.IsDLL () ) + { + //pLibrary = new Library ( module, "__mingw_dllmain" ); + //module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary ); + } + else + { + pLibrary = new Library ( module, module.isUnicode ? "mingw_wmain" : "mingw_main" ); + module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary ); + } + + pLibrary = new Library ( module, "mingw_common" ); + module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin() + 1, pLibrary ); + + if ( module.name != "msvcrt" ) + { + // always link in msvcrt to get the basic routines + pLibrary = new Library ( module, "msvcrt" ); + module.non_if_data.libraries.push_back ( pLibrary ); + } +} + +void +MingwWin32DLLModuleHandler::AddImplicitLibraries ( Module& module ) +{ + MingwAddImplicitLibraries ( module ); +} + void MingwWin32DLLModuleHandler::Process () { @@ -2617,6 +2673,12 @@ MingwWin32CUIModuleHandler::MingwWin32CUIModuleHandler ( { } +void +MingwWin32CUIModuleHandler::AddImplicitLibraries ( Module& module ) +{ + MingwAddImplicitLibraries ( module ); +} + void MingwWin32CUIModuleHandler::Process () { @@ -2670,6 +2732,12 @@ MingwWin32GUIModuleHandler::MingwWin32GUIModuleHandler ( { } +void +MingwWin32GUIModuleHandler::AddImplicitLibraries ( Module& module ) +{ + MingwAddImplicitLibraries ( module ); +} + void MingwWin32GUIModuleHandler::Process () { diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.h b/reactos/tools/rbuild/backend/mingw/modulehandler.h index a000c2ad847..e11457da69c 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.h +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.h @@ -82,6 +82,7 @@ public: void GenerateInstallTarget () const; void GenerateDependsTarget () const; static bool ReferenceObjects ( const Module& module ); + virtual void AddImplicitLibraries ( Module& module ) { return; } protected: virtual void GetModuleSpecificCompilationUnits ( std::vector& compilationUnits ); std::string GetWorkingDirectory () const; @@ -329,6 +330,8 @@ public: MingwWin32DLLModuleHandler ( const Module& module ); virtual HostType DefaultHost() { return HostFalse; } virtual void Process (); + std::string TypeSpecificLinkerFlags() { return module.useHostStdlib ? "-nostartfiles -lgcc" : "-nostartfiles -nostdlib -lgcc"; } + void AddImplicitLibraries ( Module& module ); private: void GenerateWin32DLLModuleTarget (); }; @@ -340,6 +343,8 @@ public: MingwWin32CUIModuleHandler ( const Module& module ); virtual HostType DefaultHost() { return HostFalse; } virtual void Process (); + std::string TypeSpecificLinkerFlags() { return module.useHostStdlib ? "-nostartfiles -lgcc" : "-nostartfiles -nostdlib -lgcc"; } + void AddImplicitLibraries ( Module& module ); private: void GenerateWin32CUIModuleTarget (); }; @@ -351,6 +356,8 @@ public: MingwWin32GUIModuleHandler ( const Module& module ); virtual HostType DefaultHost() { return HostFalse; } virtual void Process (); + std::string TypeSpecificLinkerFlags() { return module.useHostStdlib ? "-nostartfiles -lgcc" : "-nostartfiles -nostdlib -lgcc"; } + void AddImplicitLibraries ( Module& module ); private: void GenerateWin32GUIModuleTarget (); }; @@ -440,6 +447,7 @@ public: MingwTestModuleHandler ( const Module& module ); virtual HostType DefaultHost() { return HostFalse; } virtual void Process (); + std::string TypeSpecificLinkerFlags() { return "-nostartfiles -nostdlib"; } protected: virtual void GetModuleSpecificCompilationUnits ( std::vector& compilationUnits ); private: diff --git a/reactos/tools/rbuild/define.cpp b/reactos/tools/rbuild/define.cpp index b2fc6b93c78..e2a90100a77 100644 --- a/reactos/tools/rbuild/define.cpp +++ b/reactos/tools/rbuild/define.cpp @@ -27,7 +27,7 @@ Define::Define ( const Project& project, const XMLElement& defineNode ) : project(project), module(NULL), - node(defineNode) + node(&defineNode) { Initialize(); } @@ -37,11 +37,22 @@ Define::Define ( const Project& project, const XMLElement& defineNode ) : project(project), module(module), - node(defineNode) + node(&defineNode) { Initialize(); } +Define::Define ( const Project& project, + const Module* module, + const std::string name_ ) + : project(project), + module(module), + node(NULL) +{ + name = name_; + value = ""; +} + Define::~Define () { } @@ -49,11 +60,11 @@ Define::~Define () void Define::Initialize() { - const XMLAttribute* att = node.GetAttribute ( "name", true ); - const XMLAttribute* empty = node.GetAttribute ( "empty", false ); + const XMLAttribute* att = node->GetAttribute ( "name", true ); + const XMLAttribute* empty = node->GetAttribute ( "empty", false ); assert(att); name = att->value; - value = node.value; + value = node->value; if( empty ) value = " "; } diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp index 8445778388c..5aa42fb5a7a 100644 --- a/reactos/tools/rbuild/module.cpp +++ b/reactos/tools/rbuild/module.cpp @@ -307,11 +307,46 @@ Module::Module ( const Project& project, else isUnicode = false; + att = moduleNode.GetAttribute ( "stdlib", false ); + if ( att != NULL ) + { + const char* p = att->value.c_str(); + if ( !stricmp ( p, "host" ) ) + useHostStdlib = true; + else if ( !stricmp ( p, "default" ) ) + useHostStdlib = false; + else + { + throw InvalidAttributeValueException ( + moduleNode.location, + "stdlib", + att->value ); + } + } + else + useHostStdlib = false; + + if (isUnicode) + { + // Always define UNICODE and _UNICODE + Define* pDefine = new Define ( project, this, "UNICODE" ); + non_if_data.defines.push_back ( pDefine ); + + pDefine = new Define ( project, this, "_UNICODE" ); + non_if_data.defines.push_back ( pDefine ); + } + att = moduleNode.GetAttribute ( "entrypoint", false ); if ( att != NULL ) + { entrypoint = att->value; + isDefaultEntryPoint = false; + } else + { entrypoint = GetDefaultModuleEntrypoint (); + isDefaultEntryPoint = true; + } att = moduleNode.GetAttribute ( "baseaddress", false ); if ( att != NULL ) @@ -355,6 +390,25 @@ Module::Module ( const Project& project, } } + att = moduleNode.GetAttribute ( "isstartuplib", false ); + if ( att != NULL ) + { + const char* p = att->value.c_str(); + if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) ) + isStartupLib = true; + else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) ) + isStartupLib = false; + else + { + throw InvalidAttributeValueException ( + moduleNode.location, + "host", + att->value ); + } + } + else + isStartupLib = false; + att = moduleNode.GetAttribute ( "prefix", false ); if ( att != NULL ) prefix = att->value; @@ -918,7 +972,7 @@ Module::GetDefaultModuleBaseaddress () const bool Module::HasImportLibrary () const { - return importLibrary != NULL; + return importLibrary != NULL && type != StaticLibrary; } bool @@ -1118,7 +1172,7 @@ File::ProcessXML() Library::Library ( const XMLElement& _node, const Module& _module, const string& _name ) - : node(_node), + : node(&_node), module(_module), name(_name), importedModule(_module.project.LocateModule(_name)) @@ -1126,27 +1180,36 @@ Library::Library ( const XMLElement& _node, if ( module.name == name ) { throw XMLInvalidBuildFileException ( - node.location, + node->location, "module '%s' cannot link against itself", name.c_str() ); } if ( !importedModule ) { throw XMLInvalidBuildFileException ( - node.location, + node->location, "module '%s' trying to import non-existant module '%s'", module.name.c_str(), name.c_str() ); } } +Library::Library ( const Module& _module, + const string& _name ) + : node(NULL), + module(_module), + name(_name), + importedModule(_module.project.LocateModule(_name)) +{ +} + void Library::ProcessXML() { - if ( !module.project.LocateModule ( name ) ) + if ( node && !module.project.LocateModule ( name ) ) { throw XMLInvalidBuildFileException ( - node.location, + node->location, "module '%s' is trying to link against non-existant module '%s'", module.name.c_str(), name.c_str() ); @@ -1341,6 +1404,21 @@ ImportLibrary::ImportLibrary ( const XMLElement& _node, else basename = module.name; + att = _node.GetAttribute ( "dllname", false ); + if (att != NULL) + dllname = att->value; + else + { + if ( _module.type == StaticLibrary ) + { + throw XMLInvalidBuildFileException ( + node.location, + " dllname attribute required." ); + } + + dllname = ""; + } + att = _node.GetAttribute ( "definition", true ); assert (att); definition = FixSeparator(att->value); diff --git a/reactos/tools/rbuild/rbuild.h b/reactos/tools/rbuild/rbuild.h index 0f5f0a24727..f45b53f1b4d 100644 --- a/reactos/tools/rbuild/rbuild.h +++ b/reactos/tools/rbuild/rbuild.h @@ -296,6 +296,7 @@ public: ImportLibrary* importLibrary; bool mangledSymbols; bool isUnicode; + bool isDefaultEntryPoint; Bootstrap* bootstrap; AutoRegister* autoRegister; IfableData non_if_data; @@ -315,6 +316,8 @@ public: bool useWRC; bool allowWarnings; bool enabled; + bool useHostStdlib; + bool isStartupLib; Module ( const Project& project, const XMLElement& moduleNode, @@ -379,7 +382,7 @@ class Define public: const Project& project; const Module* module; - const XMLElement& node; + const XMLElement* node; std::string name; std::string value; @@ -388,6 +391,9 @@ public: Define ( const Project& project, const Module* module, const XMLElement& defineNode ); + Define ( const Project& project, + const Module* module, + const std::string name_ ); ~Define(); void ProcessXML(); private: @@ -414,8 +420,8 @@ public: class Library { + const XMLElement *node; public: - const XMLElement& node; const Module& module; std::string name; const Module* importedModule; @@ -423,6 +429,8 @@ public: Library ( const XMLElement& _node, const Module& _module, const std::string& _name ); + Library ( const Module& _module, + const std::string& _name ); void ProcessXML(); }; @@ -485,6 +493,7 @@ public: const Module& module; std::string basename; std::string definition; + std::string dllname; ImportLibrary ( const XMLElement& _node, const Module& module ); From ec6a7a35c4a0c7dcb17a99498a612e4fb8161873 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 6 Sep 2006 20:30:28 +0000 Subject: [PATCH 026/488] Added _fpreset prototype. Not sure why this isn't picked up here. svn path=/trunk/; revision=23935 --- reactos/lib/mingw/wcrt1.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/reactos/lib/mingw/wcrt1.c b/reactos/lib/mingw/wcrt1.c index b7eeaece113..00b30bc0081 100644 --- a/reactos/lib/mingw/wcrt1.c +++ b/reactos/lib/mingw/wcrt1.c @@ -17,10 +17,16 @@ #include #include #include +#include #define WIN32_LEAN_AND_MEAN #include #include +/* This prototype is needed for me, even though it's present in float.h + * Not sure what's blocking it. + */ +void __cdecl _fpreset(); + /* NOTE: The code for initializing the _argv, _argc, and environ variables * has been moved to a separate .c file which is included in both * crt1.c and dllcrt1.c. This means changes in the code don't have to From d7a2739bdfd11191bd769f413afadd36029ad1b8 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 6 Sep 2006 20:31:11 +0000 Subject: [PATCH 027/488] Ditto. svn path=/trunk/; revision=23936 --- reactos/lib/mingw/crt1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/lib/mingw/crt1.c b/reactos/lib/mingw/crt1.c index 65f248dd978..956c6853fa4 100644 --- a/reactos/lib/mingw/crt1.c +++ b/reactos/lib/mingw/crt1.c @@ -21,6 +21,8 @@ #include #include +void __cdecl _fpreset(); + /* NOTE: The code for initializing the _argv, _argc, and environ variables * has been moved to a separate .c file which is included in both * crt1.c and dllcrt1.c. This means changes in the code don't have to From e1ba8f15ae5b7549768f2d5e304ba9ac6f9d03be Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 6 Sep 2006 20:58:02 +0000 Subject: [PATCH 028/488] Fix this properly: specify the search path among our various header sets. svn path=/trunk/; revision=23937 --- reactos/lib/mingw/crt1.c | 2 -- reactos/lib/mingw/mingw.rbuild | 12 ++++++++++++ reactos/lib/mingw/wcrt1.c | 5 ----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/reactos/lib/mingw/crt1.c b/reactos/lib/mingw/crt1.c index 956c6853fa4..65f248dd978 100644 --- a/reactos/lib/mingw/crt1.c +++ b/reactos/lib/mingw/crt1.c @@ -21,8 +21,6 @@ #include #include -void __cdecl _fpreset(); - /* NOTE: The code for initializing the _argv, _argc, and environ variables * has been moved to a separate .c file which is included in both * crt1.c and dllcrt1.c. This means changes in the code don't have to diff --git a/reactos/lib/mingw/mingw.rbuild b/reactos/lib/mingw/mingw.rbuild index 47343e63281..475212d7f95 100644 --- a/reactos/lib/mingw/mingw.rbuild +++ b/reactos/lib/mingw/mingw.rbuild @@ -3,6 +3,9 @@ + include/crt + include/psdk + include cpu_features.c CRTfmode.c CRTglob.c @@ -20,16 +23,25 @@ _wgetopt.c + include/crt + include/psdk + include binmode.c crt1.c main.c + include/crt + include/psdk + include wbinmode.c wcrt1.c wmain.c + include/crt + include/psdk + include dllcrt1.c diff --git a/reactos/lib/mingw/wcrt1.c b/reactos/lib/mingw/wcrt1.c index 00b30bc0081..2f3aea1bbea 100644 --- a/reactos/lib/mingw/wcrt1.c +++ b/reactos/lib/mingw/wcrt1.c @@ -22,11 +22,6 @@ #include #include -/* This prototype is needed for me, even though it's present in float.h - * Not sure what's blocking it. - */ -void __cdecl _fpreset(); - /* NOTE: The code for initializing the _argv, _argc, and environ variables * has been moved to a separate .c file which is included in both * crt1.c and dllcrt1.c. This means changes in the code don't have to From 29a8ffa699a0c6b413615aae4587461740354dca Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Wed, 6 Sep 2006 21:12:06 +0000 Subject: [PATCH 029/488] * add console.dll to bootcd * add setting for unattended GUI setup (disabled) svn path=/trunk/; revision=23938 --- reactos/boot/bootdata/packages/reactos.dff | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index 3a1874811f1..ca0c724416c 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -150,6 +150,7 @@ dll\win32\avifil32\avifil32.dll 1 dll\win32\cabinet\cabinet.dll 1 dll\win32\cards\cards.dll 1 dll\win32\cfgmgr32\cfgmgr32.dll 1 +dll\win32\console\console.dll 1 dll\win32\comctl32\comctl32.dll 1 dll\win32\comdlg32\comdlg32.dll 1 dll\win32\crtdll\crtdll.dll 1 @@ -391,6 +392,7 @@ media\inf\usbport.inf 6 media\inf\usb.inf 6 media\inf\usbstor.inf 6 media\inf\xboxdisp.inf 6 +;boot\bootdata\unattend.inf 6 optional ; Subsystems From 80562db6318eadb6c8d32601322e73d9c7345d0c Mon Sep 17 00:00:00 2001 From: Brandon Turner Date: Wed, 6 Sep 2006 21:17:23 +0000 Subject: [PATCH 030/488] Link to shell32 so we can use CommandLineToArgvW when compiling unicode. Thanks to Usurp for finding the problem. svn path=/trunk/; revision=23939 --- reactos/base/shell/cmd/cmd.rbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/base/shell/cmd/cmd.rbuild b/reactos/base/shell/cmd/cmd.rbuild index 773f4d75e6c..94ff2044f1c 100644 --- a/reactos/base/shell/cmd/cmd.rbuild +++ b/reactos/base/shell/cmd/cmd.rbuild @@ -70,6 +70,7 @@ cmd_base kernel32 advapi32 + shell32 user32 main.c cmd.rc From 17e434d5bd85434cfe91c13e25d7580d5a05eb26 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 6 Sep 2006 21:44:06 +0000 Subject: [PATCH 031/488] Add user32 to build notifyhook svn path=/trunk/; revision=23940 --- reactos/base/shell/explorer/notifyhook/notifyhook.rbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/base/shell/explorer/notifyhook/notifyhook.rbuild b/reactos/base/shell/explorer/notifyhook/notifyhook.rbuild index 43d4ed62b2c..95b10c65dbd 100644 --- a/reactos/base/shell/explorer/notifyhook/notifyhook.rbuild +++ b/reactos/base/shell/explorer/notifyhook/notifyhook.rbuild @@ -7,6 +7,7 @@ 0x0600 kernel32 + user32 notifyhook.c notifyhook.rc From dd25974e25e593f110e4fa2017010aeb3fe60963 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 7 Sep 2006 05:07:34 +0000 Subject: [PATCH 032/488] - More MSVC fixes: Additions or changes to headers: FSRTL_PER_FILEOBJECT_CONTEXT, FsRtlAreNamesEqual uses CONST buffers, KiIpiGenericCall + PKPIP_BROADCAST_WORKER, MmPageEntireDriver returns PVOID, Obf(De)referenceObject return LONG_PTR, KeGetPreviousMode is ExGetPreviousMode. KeGetCurrentPrcb is reimplemented in inline, MAX_PATH exposed to drivers. - Changes: STATIC->static. static __inline ->FORCEINLINE. STDCALL -> NTAPI (Some). WORD/DWORD/BYTE -> NT Types. - Kernel bugs fixed: Some string concatenations were broken, some functions had wrong return values. svn path=/trunk/; revision=23941 --- reactos/include/ddk/ntifs.h | 23 ++-- reactos/include/ddk/winddk.h | 25 +++- reactos/include/ndk/i386/ketypes.h | 15 ++- reactos/include/ndk/rtltypes.h | 133 ++++++++++--------- reactos/include/reactos/rosldr.h | 78 +++++------ reactos/ntoskrnl/cc/view.c | 4 +- reactos/ntoskrnl/cm/regobj.c | 2 +- reactos/ntoskrnl/deprecated/irq.c | 4 +- reactos/ntoskrnl/ex/error.c | 4 +- reactos/ntoskrnl/ex/locale.c | 2 +- reactos/ntoskrnl/fs/context.c | 6 +- reactos/ntoskrnl/fs/filelock.c | 2 +- reactos/ntoskrnl/fs/name.c | 6 +- reactos/ntoskrnl/fs/pool.c | 2 + reactos/ntoskrnl/fs/util.c | 8 +- reactos/ntoskrnl/inbv/inbv.c | 4 +- reactos/ntoskrnl/include/internal/cc.h | 2 +- reactos/ntoskrnl/include/internal/debug.h | 5 + reactos/ntoskrnl/include/internal/ex.h | 16 ++- reactos/ntoskrnl/include/internal/ntoskrnl.h | 2 +- reactos/ntoskrnl/include/internal/test.h | 2 +- reactos/ntoskrnl/include/ntoskrnl.h | 6 +- reactos/ntoskrnl/io/iomgr/arcname.c | 8 +- reactos/ntoskrnl/io/iomgr/device.c | 20 +-- reactos/ntoskrnl/io/iomgr/drvrlist.c | 10 +- reactos/ntoskrnl/io/pnpmgr/plugplay.c | 2 +- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 2 +- reactos/ntoskrnl/kd/wrappers/bochs.c | 2 +- reactos/ntoskrnl/kd/wrappers/gdbstub.c | 10 +- reactos/ntoskrnl/ke/clock.c | 1 + reactos/ntoskrnl/ke/i386/ldt.c | 2 +- reactos/ntoskrnl/ke/ipi.c | 7 +- reactos/ntoskrnl/ke/kthread.c | 8 +- reactos/ntoskrnl/ldr/loader.c | 18 +-- reactos/ntoskrnl/lpc/create.c | 2 +- reactos/ntoskrnl/mm/anonmem.c | 4 +- reactos/ntoskrnl/mm/drvlck.c | 19 ++- reactos/ntoskrnl/mm/elf.inc.h | 20 +-- reactos/ntoskrnl/mm/mm.c | 14 +- reactos/ntoskrnl/mm/mminit.c | 2 +- reactos/ntoskrnl/mm/ncache.c | 2 +- reactos/ntoskrnl/mm/npool.c | 16 +-- reactos/ntoskrnl/mm/pagefile.c | 6 +- reactos/ntoskrnl/mm/pool.c | 2 +- reactos/ntoskrnl/mm/ppool.c | 6 +- reactos/ntoskrnl/mm/region.c | 4 +- reactos/ntoskrnl/mm/section.c | 30 ++--- reactos/ntoskrnl/mm/virtual.c | 2 +- reactos/ntoskrnl/ntoskrnl.rbuild | 1 + reactos/ntoskrnl/ob/oblife.c | 2 +- reactos/ntoskrnl/ob/obref.c | 17 ++- reactos/ntoskrnl/ps/process.c | 2 +- reactos/ntoskrnl/rtl/libsupp.c | 4 +- reactos/ntoskrnl/rtl/strtok.c | 2 +- reactos/ntoskrnl/se/lsa.c | 58 ++++---- reactos/ntoskrnl/se/sd.c | 6 +- reactos/ntoskrnl/se/token.c | 4 +- reactos/ntoskrnl/vdm/vdmexec.c | 2 +- reactos/ntoskrnl/vdm/vdmmain.c | 2 +- 59 files changed, 357 insertions(+), 313 deletions(-) diff --git a/reactos/include/ddk/ntifs.h b/reactos/include/ddk/ntifs.h index 4ca545d2c26..5cfec2d5d94 100644 --- a/reactos/include/ddk/ntifs.h +++ b/reactos/include/ddk/ntifs.h @@ -28,6 +28,8 @@ #pragma GCC system_header #endif +#define NTKERNELAPI + #include "ntddk.h" #define _NTIFS_INCLUDED_ @@ -43,14 +45,6 @@ extern "C" { #define NTSYSAPI #endif -#ifndef NTKERNELAPI -#if defined(_NTDRIVER_) || defined(_NTDDK_) || defined (_NTIFS_) || defined(_NTHAL_) -#define NTKERNELAPI DECLSPEC_IMPORT -#else -#define NTKERNELAPI -#endif -#endif - #include "csq.h" typedef struct _SE_EXPORTS *PSE_EXPORTS; @@ -1220,6 +1214,13 @@ typedef struct _FSRTL_PER_STREAM_CONTEXT { PFREE_FUNCTION FreeCallback; } FSRTL_PER_STREAM_CONTEXT, *PFSRTL_PER_STREAM_CONTEXT; +typedef struct _FSRTL_PER_FILEOBJECT_CONTEXT +{ + LIST_ENTRY Links; + PVOID OwnerId; + PVOID InstanceId; +} FSRTL_PER_FILEOBJECT_CONTEXT, *PFSRTL_PER_FILEOBJECT_CONTEXT; + #endif /* (VER_PRODUCTBUILD >= 2600) */ typedef struct _BASE_MCB @@ -2298,10 +2299,10 @@ NTKERNELAPI BOOLEAN NTAPI FsRtlAreNamesEqual ( - IN PUNICODE_STRING Name1, - IN PUNICODE_STRING Name2, + IN PCUNICODE_STRING Name1, + IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, - IN PWCHAR UpcaseTable OPTIONAL + IN PCWCH UpcaseTable OPTIONAL ); #define FsRtlAreThereCurrentFileLocks(FL) ( \ diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 4dffeee09a2..3d99f011e4a 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -40,11 +40,8 @@ extern "C" { #define DDKCDECLAPI __cdecl /* FIXME: REMOVE THIS UNCOMPATIBLE CRUFT!!! */ -#if defined(_NTDRIVER_) || defined(_NTDDK_) || defined (_NTIFS_) || defined(_NTHAL_) -#define NTKERNELAPI DECLSPEC_IMPORT -#else #define NTKERNELAPI -#endif + #ifndef NTOSAPI #define NTOSAPI NTKERNELAPI #endif @@ -8983,6 +8980,20 @@ KeWaitForSingleObject( IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL); +typedef +ULONG_PTR +(*NTAPI PKIPI_BROADCAST_WORKER)( + IN ULONG_PTR Argument +); + +NTKERNELAPI +ULONG_PTR +NTAPI +KeIpiGenericCall( + IN PKIPI_BROADCAST_WORKER BroadcastFunction, + IN ULONG_PTR Context +); + #if defined(_X86_) NTHALAPI @@ -9378,7 +9389,7 @@ MmMapLockedPages( IN KPROCESSOR_MODE AccessMode); NTOSAPI -VOID +PVOID DDKAPI MmPageEntireDriver( IN PVOID AddressWithinSection); @@ -9536,7 +9547,7 @@ ObDereferenceSecurityDescriptor( ULONG Count); NTOSAPI -VOID +LONG_PTR DDKFASTAPI ObfDereferenceObject( IN PVOID Object); @@ -9568,7 +9579,7 @@ ObInsertObject( OUT PHANDLE Handle); NTOSAPI -VOID +LONG_PTR DDKFASTAPI ObfReferenceObject( IN PVOID Object); diff --git a/reactos/include/ndk/i386/ketypes.h b/reactos/include/ndk/i386/ketypes.h index f48f66a9dd5..0f95e500934 100644 --- a/reactos/include/ndk/i386/ketypes.h +++ b/reactos/include/ndk/i386/ketypes.h @@ -109,9 +109,18 @@ Author: // // Macro to get current KPRCB // -#ifndef _REACTOS_ // fixme -#define KeGetCurrentPrcb() \ - (PKPRCB)__readfsdword(KPCR_PRCB); +#ifndef __GNUC__ // fixme +FORCEINLINE +struct _KPRCB * +KeGetCurrentPrcb(VOID) +{ + return (struct _KPRCB *)(ULONG_PTR)__readfsdword(FIELD_OFFSET(KPCR, Prcb)); +} + +// +// Macro to get current previous mode +// +#define KeGetPreviousMode ExGetPreviousMode #endif // diff --git a/reactos/include/ndk/rtltypes.h b/reactos/include/ndk/rtltypes.h index a0e682e1776..cc9838267c7 100644 --- a/reactos/include/ndk/rtltypes.h +++ b/reactos/include/ndk/rtltypes.h @@ -28,44 +28,44 @@ Author: // // Maximum Atom Length // -#define RTL_MAXIMUM_ATOM_LENGTH 255 +#define RTL_MAXIMUM_ATOM_LENGTH 255 // // Process Parameters Flags // -#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED 0x01 -#define RTL_USER_PROCESS_PARAMETERS_PROFILE_USER 0x02 -#define RTL_USER_PROCESS_PARAMETERS_PROFILE_SERVER 0x04 -#define RTL_USER_PROCESS_PARAMETERS_PROFILE_KERNEL 0x08 -#define RTL_USER_PROCESS_PARAMETERS_UNKNOWN 0x10 -#define RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB 0x20 -#define RTL_USER_PROCESS_PARAMETERS_DISABLE_HEAP_CHECKS 0x100 -#define RTL_USER_PROCESS_PARAMETERS_PROCESS_OR_1 0x200 -#define RTL_USER_PROCESS_PARAMETERS_PROCESS_OR_2 0x400 -#define RTL_USER_PROCESS_PARAMETERS_PRIVATE_DLL_PATH 0x1000 -#define RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH 0x2000 -#define RTL_USER_PROCESS_PARAMETERS_NX 0x20000 +#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED 0x01 +#define RTL_USER_PROCESS_PARAMETERS_PROFILE_USER 0x02 +#define RTL_USER_PROCESS_PARAMETERS_PROFILE_SERVER 0x04 +#define RTL_USER_PROCESS_PARAMETERS_PROFILE_KERNEL 0x08 +#define RTL_USER_PROCESS_PARAMETERS_UNKNOWN 0x10 +#define RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB 0x20 +#define RTL_USER_PROCESS_PARAMETERS_DISABLE_HEAP_CHECKS 0x100 +#define RTL_USER_PROCESS_PARAMETERS_PROCESS_OR_1 0x200 +#define RTL_USER_PROCESS_PARAMETERS_PROCESS_OR_2 0x400 +#define RTL_USER_PROCESS_PARAMETERS_PRIVATE_DLL_PATH 0x1000 +#define RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH 0x2000 +#define RTL_USER_PROCESS_PARAMETERS_NX 0x20000 // // Exception Flags // -#define EXCEPTION_CHAIN_END ((PEXCEPTION_REGISTRATION_RECORD)-1) -#define EXCEPTION_UNWINDING 0x02 -#define EXCEPTION_EXIT_UNWIND 0x04 -#define EXCEPTION_STACK_INVALID 0x08 -#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND) -#define EXCEPTION_NESTED_CALL 0x10 -#define EXCEPTION_TARGET_UNWIND 0x20 -#define EXCEPTION_COLLIDED_UNWIND 0x20 +#define EXCEPTION_CHAIN_END ((PEXCEPTION_REGISTRATION_RECORD)-1) +#define EXCEPTION_UNWINDING 0x02 +#define EXCEPTION_EXIT_UNWIND 0x04 +#define EXCEPTION_STACK_INVALID 0x08 +#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND) +#define EXCEPTION_NESTED_CALL 0x10 +#define EXCEPTION_TARGET_UNWIND 0x20 +#define EXCEPTION_COLLIDED_UNWIND 0x20 // // Range and Range List Flags // -#define RTL_RANGE_LIST_ADD_IF_CONFLICT 0x00000001 -#define RTL_RANGE_LIST_ADD_SHARED 0x00000002 +#define RTL_RANGE_LIST_ADD_IF_CONFLICT 0x00000001 +#define RTL_RANGE_LIST_ADD_SHARED 0x00000002 -#define RTL_RANGE_SHARED 0x01 -#define RTL_RANGE_CONFLICT 0x02 +#define RTL_RANGE_SHARED 0x01 +#define RTL_RANGE_CONFLICT 0x02 // // Activation Context Frame Flags @@ -145,53 +145,58 @@ C_ASSERT(HEAP_CREATE_VALID_MASK == 0x0007F0FF); // // Registry Keys // -#define RTL_REGISTRY_ABSOLUTE 0 -#define RTL_REGISTRY_SERVICES 1 -#define RTL_REGISTRY_CONTROL 2 -#define RTL_REGISTRY_WINDOWS_NT 3 -#define RTL_REGISTRY_DEVICEMAP 4 -#define RTL_REGISTRY_USER 5 -#define RTL_REGISTRY_MAXIMUM 6 -#define RTL_REGISTRY_HANDLE 0x40000000 -#define RTL_REGISTRY_OPTIONAL 0x80000000 -#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 -#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 -#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 -#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 -#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 -#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 -#define RTL_QUERY_REGISTRY_DELETE 0x00000040 +#define RTL_REGISTRY_ABSOLUTE 0 +#define RTL_REGISTRY_SERVICES 1 +#define RTL_REGISTRY_CONTROL 2 +#define RTL_REGISTRY_WINDOWS_NT 3 +#define RTL_REGISTRY_DEVICEMAP 4 +#define RTL_REGISTRY_USER 5 +#define RTL_REGISTRY_MAXIMUM 6 +#define RTL_REGISTRY_HANDLE 0x40000000 +#define RTL_REGISTRY_OPTIONAL 0x80000000 +#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 +#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 +#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 +#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 +#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 +#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 +#define RTL_QUERY_REGISTRY_DELETE 0x00000040 // // Versioning // -#define VER_MINORVERSION 0x0000001 -#define VER_MAJORVERSION 0x0000002 -#define VER_BUILDNUMBER 0x0000004 -#define VER_PLATFORMID 0x0000008 -#define VER_SERVICEPACKMINOR 0x0000010 -#define VER_SERVICEPACKMAJOR 0x0000020 -#define VER_SUITENAME 0x0000040 -#define VER_PRODUCT_TYPE 0x0000080 -#define VER_PLATFORM_WIN32s 0 -#define VER_PLATFORM_WIN32_WINDOWS 1 -#define VER_PLATFORM_WIN32_NT 2 -#define VER_EQUAL 1 -#define VER_GREATER 2 -#define VER_GREATER_EQUAL 3 -#define VER_LESS 4 -#define VER_LESS_EQUAL 5 -#define VER_AND 6 -#define VER_OR 7 -#define VER_CONDITION_MASK 7 -#define VER_NUM_BITS_PER_CONDITION_MASK 3 +#define VER_MINORVERSION 0x0000001 +#define VER_MAJORVERSION 0x0000002 +#define VER_BUILDNUMBER 0x0000004 +#define VER_PLATFORMID 0x0000008 +#define VER_SERVICEPACKMINOR 0x0000010 +#define VER_SERVICEPACKMAJOR 0x0000020 +#define VER_SUITENAME 0x0000040 +#define VER_PRODUCT_TYPE 0x0000080 +#define VER_PLATFORM_WIN32s 0 +#define VER_PLATFORM_WIN32_WINDOWS 1 +#define VER_PLATFORM_WIN32_NT 2 +#define VER_EQUAL 1 +#define VER_GREATER 2 +#define VER_GREATER_EQUAL 3 +#define VER_LESS 4 +#define VER_LESS_EQUAL 5 +#define VER_AND 6 +#define VER_OR 7 +#define VER_CONDITION_MASK 7 +#define VER_NUM_BITS_PER_CONDITION_MASK 3 // // Timezone IDs // -#define TIME_ZONE_ID_UNKNOWN 0 -#define TIME_ZONE_ID_STANDARD 1 -#define TIME_ZONE_ID_DAYLIGHT 2 +#define TIME_ZONE_ID_UNKNOWN 0 +#define TIME_ZONE_ID_STANDARD 1 +#define TIME_ZONE_ID_DAYLIGHT 2 + +// +// Maximum Path Length +// +#define MAX_PATH 260 // // RTL Lock Type (Critical Section or Resource) diff --git a/reactos/include/reactos/rosldr.h b/reactos/include/reactos/rosldr.h index 86842c838dd..10c12e02966 100644 --- a/reactos/include/reactos/rosldr.h +++ b/reactos/include/reactos/rosldr.h @@ -1,47 +1,47 @@ #ifndef __REACTOS_LDR_H #define __REACTOS_LDR_H -#define MB_FLAGS_MEM_INFO (0x1) -#define MB_FLAGS_BOOT_DEVICE (0x2) -#define MB_FLAGS_COMMAND_LINE (0x4) -#define MB_FLAGS_MODULE_INFO (0x8) -#define MB_FLAGS_AOUT_SYMS (0x10) -#define MB_FLAGS_ELF_SYMS (0x20) -#define MB_FLAGS_MMAP_INFO (0x40) -#define MB_FLAGS_DRIVES_INFO (0x80) -#define MB_FLAGS_CONFIG_TABLE (0x100) -#define MB_FLAGS_BOOT_LOADER_NAME (0x200) -#define MB_FLAGS_APM_TABLE (0x400) -#define MB_FLAGS_GRAPHICS_TABLE (0x800) -#define MB_FLAGS_ACPI_TABLE (0x1000) - -typedef struct _LOADER_MODULE -{ - ULONG ModStart; - ULONG ModEnd; - ULONG String; - ULONG Reserved; +#define MB_FLAGS_MEM_INFO (0x1) +#define MB_FLAGS_BOOT_DEVICE (0x2) +#define MB_FLAGS_COMMAND_LINE (0x4) +#define MB_FLAGS_MODULE_INFO (0x8) +#define MB_FLAGS_AOUT_SYMS (0x10) +#define MB_FLAGS_ELF_SYMS (0x20) +#define MB_FLAGS_MMAP_INFO (0x40) +#define MB_FLAGS_DRIVES_INFO (0x80) +#define MB_FLAGS_CONFIG_TABLE (0x100) +#define MB_FLAGS_BOOT_LOADER_NAME (0x200) +#define MB_FLAGS_APM_TABLE (0x400) +#define MB_FLAGS_GRAPHICS_TABLE (0x800) +#define MB_FLAGS_ACPI_TABLE (0x1000) + +typedef struct _LOADER_MODULE +{ + ULONG ModStart; + ULONG ModEnd; + ULONG String; + ULONG Reserved; } LOADER_MODULE, *PLOADER_MODULE; -typedef struct _ROS_LOADER_PARAMETER_BLOCK -{ - ULONG Flags; - ULONG MemLower; - ULONG MemHigher; - ULONG BootDevice; - ULONG CommandLine; - ULONG ModsCount; - ULONG ModsAddr; - UCHAR Syms[12]; - ULONG MmapLength; - ULONG MmapAddr; - ULONG DrivesCount; - ULONG DrivesAddr; - ULONG ConfigTable; - ULONG BootLoaderName; - ULONG PageDirectoryStart; - ULONG PageDirectoryEnd; - ULONG KernelBase; +typedef struct _ROS_LOADER_PARAMETER_BLOCK +{ + ULONG Flags; + ULONG MemLower; + ULONG MemHigher; + ULONG BootDevice; + ULONG CommandLine; + ULONG ModsCount; + ULONG ModsAddr; + UCHAR Syms[12]; + ULONG MmapLength; + ULONG MmapAddr; + ULONG DrivesCount; + ULONG DrivesAddr; + ULONG ConfigTable; + ULONG BootLoaderName; + ULONG PageDirectoryStart; + ULONG PageDirectoryEnd; + ULONG KernelBase; } ROS_LOADER_PARAMETER_BLOCK, *PROS_LOADER_PARAMETER_BLOCK; #endif diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index fb15002161c..94544146657 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -556,7 +556,7 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty) return(STATUS_SUCCESS); } -NTSTATUS STATIC +NTSTATUS static CcRosCreateCacheSegment(PBCB Bcb, ULONG FileOffset, PCACHE_SEGMENT* CacheSeg) @@ -863,7 +863,7 @@ CcRosRequestCacheSegment(PBCB Bcb, } #ifdef CACHE_BITMAP #else -STATIC VOID +static VOID CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty) { diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index 3c961f28661..1868c1e562c 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -803,7 +803,7 @@ NTSTATUS CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove) { PKEY_OBJECT ParentKey; - DWORD Index; + ULONG Index; ParentKey = KeyToRemove->ParentKey; /* FIXME: If list maintained in alphabetic order, use dichotomic search */ diff --git a/reactos/ntoskrnl/deprecated/irq.c b/reactos/ntoskrnl/deprecated/irq.c index e96fc70eae7..e1147b87c06 100644 --- a/reactos/ntoskrnl/deprecated/irq.c +++ b/reactos/ntoskrnl/deprecated/irq.c @@ -177,7 +177,7 @@ KeInitInterrupts (VOID) } } -STATIC VOID +static VOID KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame, PKTRAP_FRAME TrapFrame) { @@ -198,7 +198,7 @@ KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame, TrapFrame->EFlags = IrqTrapFrame->Eflags; } -STATIC VOID +static VOID KeTrapFrameToIRQTrapFrame(PKTRAP_FRAME TrapFrame, PKIRQ_TRAPFRAME IrqTrapFrame) { diff --git a/reactos/ntoskrnl/ex/error.c b/reactos/ntoskrnl/ex/error.c index 67d8c89b75c..0664e2682e5 100644 --- a/reactos/ntoskrnl/ex/error.c +++ b/reactos/ntoskrnl/ex/error.c @@ -142,7 +142,7 @@ ExSystemExceptionFilter(VOID) * Optional string parameter (can be only one per error code) * * @param Parameters - * Array of DWORD parameters for use in error message string + * Array of ULONG parameters for use in error message string * * @param ValidResponseOptions * See HARDERROR_RESPONSE_OPTION for possible values description @@ -193,7 +193,7 @@ ExRaiseHardError(IN NTSTATUS ErrorStatus, * Optional string parameter (can be only one per error code) * * @param Parameters - * Array of DWORD parameters for use in error message string + * Array of ULONG parameters for use in error message string * * @param ValidResponseOptions * See HARDERROR_RESPONSE_OPTION for possible values description diff --git a/reactos/ntoskrnl/ex/locale.c b/reactos/ntoskrnl/ex/locale.c index d969a04a92f..c4ca67db2ba 100644 --- a/reactos/ntoskrnl/ex/locale.c +++ b/reactos/ntoskrnl/ex/locale.c @@ -229,7 +229,7 @@ NtSetDefaultLocale(IN BOOLEAN UserProfile, /* Initialize the system registry location */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet" - "\\Control\\Nls\\Language"); + L"\\Control\\Nls\\Language"); RtlInitUnicodeString(&ValueName, L"Default"); } diff --git a/reactos/ntoskrnl/fs/context.c b/reactos/ntoskrnl/fs/context.c index dc2d5b1d6de..2d4c27f4f8b 100644 --- a/reactos/ntoskrnl/fs/context.c +++ b/reactos/ntoskrnl/fs/context.c @@ -50,8 +50,8 @@ FsRtlRemovePerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, */ NTSTATUS NTAPI -FsRtlInsertPerFileObjectContext(IN PFSRTL_ADVANCED_FCB_HEADER PerFileObjectContext, - IN PVOID /* PFSRTL_PER_FILE_OBJECT_CONTEXT*/ Ptr) +FsRtlInsertPerFileObjectContext(IN PFILE_OBJECT FileObject, + IN PFSRTL_PER_FILEOBJECT_CONTEXT Ptr) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; @@ -60,7 +60,7 @@ FsRtlInsertPerFileObjectContext(IN PFSRTL_ADVANCED_FCB_HEADER PerFileObjectConte /* * @unimplemented */ -PVOID /* PFSRTL_PER_FILE_OBJECT_CONTEXT*/ +PFSRTL_PER_FILEOBJECT_CONTEXT NTAPI FsRtlRemovePerFileObjectContext(IN PFSRTL_ADVANCED_FCB_HEADER PerFileObjectContext, IN PVOID OwnerId OPTIONAL, diff --git a/reactos/ntoskrnl/fs/filelock.c b/reactos/ntoskrnl/fs/filelock.c index ad67add87c6..048e8d7b651 100644 --- a/reactos/ntoskrnl/fs/filelock.c +++ b/reactos/ntoskrnl/fs/filelock.c @@ -353,7 +353,7 @@ FsRtlpFastUnlockAllByKey( IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, - IN DWORD Key, + IN ULONG Key, IN BOOLEAN UseKey, IN PVOID Context OPTIONAL ) diff --git a/reactos/ntoskrnl/fs/name.c b/reactos/ntoskrnl/fs/name.c index 39bb5d1946b..49d87c5141d 100644 --- a/reactos/ntoskrnl/fs/name.c +++ b/reactos/ntoskrnl/fs/name.c @@ -179,10 +179,10 @@ PUCHAR FsRtlLegalAnsiCharacterArray = LegalAnsiCharacterArray; *--*/ BOOLEAN NTAPI -FsRtlAreNamesEqual(IN PUNICODE_STRING Name1, - IN PUNICODE_STRING Name2, +FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, + IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, - IN PWCHAR UpcaseTable OPTIONAL) + IN PCWCH UpcaseTable OPTIONAL) { UNICODE_STRING UpcaseName1; UNICODE_STRING UpcaseName2; diff --git a/reactos/ntoskrnl/fs/pool.c b/reactos/ntoskrnl/fs/pool.c index c4aaa7461fe..ffaf43ee7ed 100644 --- a/reactos/ntoskrnl/fs/pool.c +++ b/reactos/ntoskrnl/fs/pool.c @@ -107,6 +107,7 @@ FsRtlAllocatePoolWithQuota(IN POOL_TYPE PoolType, * @remarks None * *--*/ +#undef FsRtlAllocatePoolWithQuotaTag PVOID NTAPI FsRtlAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, @@ -147,6 +148,7 @@ FsRtlAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, * @remarks None * *--*/ +#undef FsRtlAllocatePoolWithTag PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, diff --git a/reactos/ntoskrnl/fs/util.c b/reactos/ntoskrnl/fs/util.c index 8b985547508..8f9704c56bf 100644 --- a/reactos/ntoskrnl/fs/util.c +++ b/reactos/ntoskrnl/fs/util.c @@ -117,7 +117,7 @@ FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus) * @remarks None. * *--*/ -BOOLEAN +LOGICAL NTAPI FsRtlIsPagingFile(IN PFILE_OBJECT FileObject) { @@ -293,9 +293,9 @@ FsRtlPostStackOverflow(IN PVOID Context, *--*/ NTSTATUS NTAPI -FsRtlSyncVolumes(DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) +FsRtlSyncVolumes(ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2) { return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/inbv/inbv.c b/reactos/ntoskrnl/inbv/inbv.c index 7aa18e2c4e1..2a684b743f7 100644 --- a/reactos/ntoskrnl/inbv/inbv.c +++ b/reactos/ntoskrnl/inbv/inbv.c @@ -30,13 +30,13 @@ HalReleaseDisplayOwnership(VOID); /* DATA **********************************************************************/ static HANDLE BootVidDevice = NULL; -static BOOL BootVidDriverInstalled = FALSE; +static BOOLEAN BootVidDriverInstalled = FALSE; static NTBOOTVID_FUNCTION_TABLE BootVidFunctionTable; /* FUNCTIONS *****************************************************************/ NTSTATUS -STATIC +static InbvCheckBootVid(VOID) { IO_STATUS_BLOCK Iosb; diff --git a/reactos/ntoskrnl/include/internal/cc.h b/reactos/ntoskrnl/include/internal/cc.h index 95a43c1a223..16b425637d2 100644 --- a/reactos/ntoskrnl/include/internal/cc.h +++ b/reactos/ntoskrnl/include/internal/cc.h @@ -198,7 +198,7 @@ CcTryToInitializeFileCache(PFILE_OBJECT FileObject); */ #define KEBUGCHECKCC \ KEBUGCHECKEX(CACHE_MANAGER, \ - (*(DWORD*)(__FILE__ + sizeof(__FILE__) - 4) << 16) | \ + (*(ULONG*)(__FILE__ + sizeof(__FILE__) - 4) << 16) | \ (__LINE__ & 0xFFFF), 0, 0, 0) #endif diff --git a/reactos/ntoskrnl/include/internal/debug.h b/reactos/ntoskrnl/include/internal/debug.h index 283b8ba016b..cbf943683b6 100644 --- a/reactos/ntoskrnl/include/internal/debug.h +++ b/reactos/ntoskrnl/include/internal/debug.h @@ -105,8 +105,13 @@ #else /* DBG */ +#ifdef __GNUC__ /* using GNU C/C99 macro ellipsis */ #define CPRINT(args...) #define DPRINT1(args...) +#else +#define CPRINT +#define DPRINT1 +#endif #ifndef __USE_W32API #define assert(x) #define ASSERT(x) diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 0cbad42bfc1..9642d12b7b3 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -29,6 +29,12 @@ extern POBJECT_TYPE ExEventPairObjectType; #define ExReleaseResourceLock(l, i) KeReleaseSpinLock(l, i); #endif +#define ExAcquireRundownProtection _ExAcquireRundownProtection +#define ExReleaseRundownProtection _ExReleaseRundownProtection +#define ExInitializeRundownProtection _ExInitializeRundownProtection +#define ExWaitForRundownProtectionRelease _ExWaitForRundownProtectionRelease +#define ExRundownCompleted _ExRundownCompleted + /* INITIALIZATION FUNCTIONS *************************************************/ VOID @@ -290,7 +296,7 @@ static __inline _SEH_FILTER(_SEH_ExSystemExceptionFilter) *--*/ BOOLEAN FORCEINLINE -ExAcquireRundownProtection(IN PEX_RUNDOWN_REF RunRef) +_ExAcquireRundownProtection(IN PEX_RUNDOWN_REF RunRef) { ULONG_PTR Value, NewValue, OldValue; @@ -331,7 +337,7 @@ ExAcquireRundownProtection(IN PEX_RUNDOWN_REF RunRef) *--*/ VOID FORCEINLINE -ExReleaseRundownProtection(IN PEX_RUNDOWN_REF RunRef) +_ExReleaseRundownProtection(IN PEX_RUNDOWN_REF RunRef) { ULONG_PTR Value, NewValue, OldValue; @@ -374,7 +380,7 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REF RunRef) *--*/ VOID FORCEINLINE -ExInitializeRundownProtection(IN PEX_RUNDOWN_REF RunRef) +_ExInitializeRundownProtection(IN PEX_RUNDOWN_REF RunRef) { /* Set the count to zero */ RunRef->Count = 0; @@ -398,7 +404,7 @@ ExInitializeRundownProtection(IN PEX_RUNDOWN_REF RunRef) *--*/ VOID FORCEINLINE -ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REF RunRef) +_ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REF RunRef) { ULONG_PTR Value; @@ -428,7 +434,7 @@ ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REF RunRef) *--*/ VOID FORCEINLINE -ExRundownCompleted(IN PEX_RUNDOWN_REF RunRef) +_ExRundownCompleted(IN PEX_RUNDOWN_REF RunRef) { /* Sanity check */ ASSERT((RunRef->Count & EX_RUNDOWN_ACTIVE) != 0); diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index 2871087b450..a0bae6e7b62 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -23,7 +23,7 @@ #include "i386/v86m.h" #include "ob.h" #include "mm.h" -#include "ex.h" +#include "ex2.h" #include "ps.h" #include "cc.h" #include "io.h" diff --git a/reactos/ntoskrnl/include/internal/test.h b/reactos/ntoskrnl/include/internal/test.h index 504298f9bb6..5576a1ddd52 100644 --- a/reactos/ntoskrnl/include/internal/test.h +++ b/reactos/ntoskrnl/include/internal/test.h @@ -21,7 +21,7 @@ PMmProbeAndLockPages( LOCK_OPERATION Operation ); -typedef VOID +typedef LONG_PTR FASTCALL PObDereferenceObject(PVOID Object); diff --git a/reactos/ntoskrnl/include/ntoskrnl.h b/reactos/ntoskrnl/include/ntoskrnl.h index 92d3ecb9253..7e961e827b3 100644 --- a/reactos/ntoskrnl/include/ntoskrnl.h +++ b/reactos/ntoskrnl/include/ntoskrnl.h @@ -9,17 +9,13 @@ /* INCLUDES ******************************************************************/ /* We are the Kernel */ -#define NTKERNELAPI #define _NTSYSTEM_ /* DDK/IFS/NDK Headers */ -#ifdef __GNUC__ -#include -#endif #include #include #include -#include +#include #undef TEXT #define TEXT(s) L##s #include diff --git a/reactos/ntoskrnl/io/iomgr/arcname.c b/reactos/ntoskrnl/io/iomgr/arcname.c index 409e1135ec4..59a9e95bf00 100644 --- a/reactos/ntoskrnl/io/iomgr/arcname.c +++ b/reactos/ntoskrnl/io/iomgr/arcname.c @@ -53,7 +53,7 @@ IopCheckCdromDevices(PULONG DeviceNumber); /* FUNCTIONS ****************************************************************/ -STATIC +static NTSTATUS STDCALL INIT_FUNCTION @@ -94,7 +94,7 @@ DiskQueryRoutine(PWSTR ValueName, #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter" -STATIC VOID INIT_FUNCTION +static VOID INIT_FUNCTION IopEnumerateBiosDisks(PLIST_ENTRY ListHead) { RTL_QUERY_REGISTRY_TABLE QueryTable[2]; @@ -178,7 +178,7 @@ IopEnumerateBiosDisks(PLIST_ENTRY ListHead) } } -STATIC VOID INIT_FUNCTION +static VOID INIT_FUNCTION IopEnumerateDisks(PLIST_ENTRY ListHead) { ULONG i, k; @@ -321,7 +321,7 @@ IopEnumerateDisks(PLIST_ENTRY ListHead) } } -STATIC NTSTATUS INIT_FUNCTION +static NTSTATUS INIT_FUNCTION IopAssignArcNamesToDisk(PDEVICE_OBJECT DeviceObject, ULONG RDisk, ULONG DiskNumber) { WCHAR DeviceNameBuffer[80]; diff --git a/reactos/ntoskrnl/io/iomgr/device.c b/reactos/ntoskrnl/io/iomgr/device.c index 9a7a43ff35e..a0ea1cf262f 100644 --- a/reactos/ntoskrnl/io/iomgr/device.c +++ b/reactos/ntoskrnl/io/iomgr/device.c @@ -1376,15 +1376,15 @@ IoStartNextPacketByKey(IN PDEVICE_OBJECT DeviceObject, if (DeviceExtension->StartIoFlags & DOE_SIO_DEFERRED) { /* Call our internal function to handle the defered case */ - return IopStartNextPacketByKeyEx(DeviceObject, - Key, - DOE_SIO_WITH_KEY | - (Cancelable) ? DOE_SIO_CANCELABLE : 0); + IopStartNextPacketByKeyEx(DeviceObject, + Key, + DOE_SIO_WITH_KEY | + (Cancelable) ? DOE_SIO_CANCELABLE : 0); } else { /* Call the normal routine */ - return IopStartNextPacketByKey(DeviceObject, Cancelable, Key); + IopStartNextPacketByKey(DeviceObject, Cancelable, Key); } } @@ -1405,15 +1405,15 @@ IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, if (DeviceExtension->StartIoFlags & DOE_SIO_DEFERRED) { /* Call our internal function to handle the defered case */ - return IopStartNextPacketByKeyEx(DeviceObject, - 0, - DOE_SIO_NO_KEY | - (Cancelable) ? DOE_SIO_CANCELABLE : 0); + IopStartNextPacketByKeyEx(DeviceObject, + 0, + DOE_SIO_NO_KEY | + (Cancelable) ? DOE_SIO_CANCELABLE : 0); } else { /* Call the normal routine */ - return IopStartNextPacket(DeviceObject, Cancelable); + IopStartNextPacket(DeviceObject, Cancelable); } } diff --git a/reactos/ntoskrnl/io/iomgr/drvrlist.c b/reactos/ntoskrnl/io/iomgr/drvrlist.c index 4f5466f5d01..74c046ba648 100644 --- a/reactos/ntoskrnl/io/iomgr/drvrlist.c +++ b/reactos/ntoskrnl/io/iomgr/drvrlist.c @@ -67,22 +67,22 @@ IopGetGroupOrderList(PWSTR ValueName, if (ValueType == REG_BINARY && ValueData != NULL && - ValueLength >= sizeof(DWORD) && - ValueLength >= (*(PULONG)ValueData + 1) * sizeof(DWORD)) + ValueLength >= sizeof(ULONG) && + ValueLength >= (*(PULONG)ValueData + 1) * sizeof(ULONG)) { Group = (PSERVICE_GROUP)Context; Group->TagCount = ((PULONG)ValueData)[0]; if (Group->TagCount > 0) { - if (ValueLength >= (Group->TagCount + 1) * sizeof(DWORD)) + if (ValueLength >= (Group->TagCount + 1) * sizeof(ULONG)) { - Group->TagArray = ExAllocatePool(NonPagedPool, Group->TagCount * sizeof(DWORD)); + Group->TagArray = ExAllocatePool(NonPagedPool, Group->TagCount * sizeof(ULONG)); if (Group->TagArray == NULL) { Group->TagCount = 0; return STATUS_INSUFFICIENT_RESOURCES; } - memcpy(Group->TagArray, (PULONG)ValueData + 1, Group->TagCount * sizeof(DWORD)); + memcpy(Group->TagArray, (PULONG)ValueData + 1, Group->TagCount * sizeof(ULONG)); } else { diff --git a/reactos/ntoskrnl/io/pnpmgr/plugplay.c b/reactos/ntoskrnl/io/pnpmgr/plugplay.c index e44e7e0d0c8..5d8a8be3da4 100644 --- a/reactos/ntoskrnl/io/pnpmgr/plugplay.c +++ b/reactos/ntoskrnl/io/pnpmgr/plugplay.c @@ -50,7 +50,7 @@ IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds) { PPNP_EVENT_ENTRY EventEntry; - DWORD TotalSize; + ULONG TotalSize; TotalSize = FIELD_OFFSET(PLUGPLAY_EVENT_BLOCK, TargetDevice.DeviceIds) + diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 80975a51caf..a0ef467c557 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -2307,7 +2307,7 @@ IopInvalidateDeviceRelations(IN PDEVICE_NODE DeviceNode, IO_STATUS_BLOCK IoStatusBlock; PDEVICE_NODE ChildDeviceNode; IO_STACK_LOCATION Stack; - BOOL BootDrivers; + BOOLEAN BootDrivers; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING LinkName; HANDLE Handle; diff --git a/reactos/ntoskrnl/kd/wrappers/bochs.c b/reactos/ntoskrnl/kd/wrappers/bochs.c index dd5f0782c59..83912c8211c 100644 --- a/reactos/ntoskrnl/kd/wrappers/bochs.c +++ b/reactos/ntoskrnl/kd/wrappers/bochs.c @@ -49,7 +49,7 @@ STDCALL KdpBochsInit(PKD_DISPATCH_TABLE DispatchTable, ULONG BootPhase) { - BYTE Value; + UCHAR Value; if (!KdpDebugMode.Bochs) return; if (BootPhase == 0) diff --git a/reactos/ntoskrnl/kd/wrappers/gdbstub.c b/reactos/ntoskrnl/kd/wrappers/gdbstub.c index c0dad9686be..f8ac460279e 100644 --- a/reactos/ntoskrnl/kd/wrappers/gdbstub.c +++ b/reactos/ntoskrnl/kd/wrappers/gdbstub.c @@ -120,9 +120,9 @@ enum REGISTER_NAMES typedef struct _CPU_REGISTER { - DWORD Size; - DWORD OffsetInTF; - DWORD OffsetInContext; + ULONG Size; + ULONG OffsetInTF; + ULONG OffsetInContext; BOOLEAN SetInContext; } CPU_REGISTER, *PCPU_REGISTER; @@ -573,7 +573,7 @@ GspGetRegisters(PCHAR Address, { ULONG_PTR Value; PULONG p; - DWORD i; + ULONG i; PETHREAD Thread; ULONG_PTR *KernelStack; @@ -670,7 +670,7 @@ GspSetRegistersInTrapFrame(PCHAR Address, ULONG Value; PCHAR Buffer; PULONG p; - DWORD i; + ULONG i; if (!TrapFrame) { diff --git a/reactos/ntoskrnl/ke/clock.c b/reactos/ntoskrnl/ke/clock.c index 0204c70a23f..1e4e5393afa 100644 --- a/reactos/ntoskrnl/ke/clock.c +++ b/reactos/ntoskrnl/ke/clock.c @@ -147,6 +147,7 @@ KeQueryTimeIncrement(VOID) /* * @implemented */ +#undef KeQueryTickCount VOID STDCALL KeQueryTickCount(PLARGE_INTEGER TickCount) diff --git a/reactos/ntoskrnl/ke/i386/ldt.c b/reactos/ntoskrnl/ke/i386/ldt.c index 41d1a216a75..1e1efc4a9ef 100644 --- a/reactos/ntoskrnl/ke/i386/ldt.c +++ b/reactos/ntoskrnl/ke/i386/ldt.c @@ -81,7 +81,7 @@ KeSetGdtSelector(ULONG Entry, KeReleaseSpinLock(&GdtLock, oldIrql); } -BOOL PspIsDescriptorValid(PLDT_ENTRY ldt_entry) +BOOLEAN PspIsDescriptorValid(PLDT_ENTRY ldt_entry) { ULONG Base, SegLimit; /* diff --git a/reactos/ntoskrnl/ke/ipi.c b/reactos/ntoskrnl/ke/ipi.c index 0f1df39651f..451b724527c 100644 --- a/reactos/ntoskrnl/ke/ipi.c +++ b/reactos/ntoskrnl/ke/ipi.c @@ -117,7 +117,7 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, VOID STDCALL -KiIpiSendPacket(KAFFINITY TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID Argument, ULONG Count, BOOLEAN Synchronize) +KiIpiSendPacket(KAFFINITY TargetSet, PKIPI_BROADCAST_WORKER WorkerRoutine, ULONG_PTR Argument, ULONG Count, BOOLEAN Synchronize) { KAFFINITY Processor; LONG i; @@ -155,9 +155,9 @@ KiIpiSendPacket(KAFFINITY TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID } } -VOID +ULONG_PTR NTAPI -KeIpiGenericCall(VOID (STDCALL *Function)(PVOID), PVOID Argument) +KeIpiGenericCall(PKIPI_BROADCAST_WORKER Function, ULONG_PTR Argument) { KIRQL oldIrql; KAFFINITY TargetSet; @@ -177,6 +177,7 @@ KeIpiGenericCall(VOID (STDCALL *Function)(PVOID), PVOID Argument) KeLowerIrql(oldIrql); DPRINT("KeIpiGenericCall on CPU%d done\n", KeGetCurrentProcessorNumber()); + return 0; // FIXME } diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index 80e97533489..4b621debd7d 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -55,7 +55,7 @@ KeFindNextRightSetAffinity(IN UCHAR Number, return (UCHAR)Result; } -STATIC +static VOID KiRequestReschedule(CCHAR Processor) { @@ -66,7 +66,7 @@ KiRequestReschedule(CCHAR Processor) KiIpiSendRequest(1 << Processor, IPI_DPC); } -STATIC +static VOID KiInsertIntoThreadList(KPRIORITY Priority, PKTHREAD Thread) @@ -84,7 +84,7 @@ KiInsertIntoThreadList(KPRIORITY Priority, PriorityListMask |= (1 << Priority); } -STATIC +static VOID KiRemoveFromThreadList(PKTHREAD Thread) { @@ -96,7 +96,7 @@ KiRemoveFromThreadList(PKTHREAD Thread) } } -STATIC +static PKTHREAD KiScanThreadList(KPRIORITY Priority, KAFFINITY Affinity) diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index ad57df7a875..b4b943c7af0 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -79,7 +79,7 @@ static PVOID LdrPEGetExportByName ( PVOID BaseAddress, PUCHAR SymbolName, - WORD Hint ); + USHORT Hint ); static PVOID LdrPEFixupForward ( PCHAR ForwardName ); @@ -682,7 +682,7 @@ LdrPEProcessModule( PLDR_DATA_TABLE_ENTRY *ModuleObject ) { unsigned int DriverSize, Idx; - DWORD CurrentSize; + ULONG CurrentSize; PVOID DriverBase; PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_NT_HEADERS PENtHeaders; @@ -1279,11 +1279,11 @@ static PVOID LdrPEGetExportByName ( PVOID BaseAddress, PUCHAR SymbolName, - WORD Hint ) + USHORT Hint ) { PIMAGE_EXPORT_DIRECTORY ExportDir; - PDWORD * ExFunctions; - PDWORD * ExNames; + PULONG * ExFunctions; + PULONG * ExNames; USHORT * ExOrdinals; PVOID ExName; ULONG Ordinal; @@ -1314,9 +1314,9 @@ LdrPEGetExportByName ( /* * Get header pointers */ - ExNames = (PDWORD *)RVA(BaseAddress, ExportDir->AddressOfNames); + ExNames = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfNames); ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals); - ExFunctions = (PDWORD *)RVA(BaseAddress, ExportDir->AddressOfFunctions); + ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions); /* * Check the hint first @@ -1399,7 +1399,7 @@ LdrPEGetExportByOrdinal ( { PIMAGE_EXPORT_DIRECTORY ExportDir; ULONG ExportDirSize; - PDWORD * ExFunctions; + PULONG * ExFunctions; PVOID Function; ExportDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData ( @@ -1408,7 +1408,7 @@ LdrPEGetExportByOrdinal ( IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportDirSize); - ExFunctions = (PDWORD *)RVA(BaseAddress, + ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions); DPRINT("LdrPEGetExportByOrdinal(Ordinal %d) = %x\n", Ordinal, diff --git a/reactos/ntoskrnl/lpc/create.c b/reactos/ntoskrnl/lpc/create.c index 190693197b1..1fcefa0d6b0 100644 --- a/reactos/ntoskrnl/lpc/create.c +++ b/reactos/ntoskrnl/lpc/create.c @@ -26,7 +26,7 @@ * * RETURN VALUE */ -STATIC NTSTATUS STDCALL +static NTSTATUS STDCALL LpcpVerifyCreateParameters (IN PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, diff --git a/reactos/ntoskrnl/mm/anonmem.c b/reactos/ntoskrnl/mm/anonmem.c index 8846c0c75fa..d307183d004 100644 --- a/reactos/ntoskrnl/mm/anonmem.c +++ b/reactos/ntoskrnl/mm/anonmem.c @@ -434,7 +434,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, return(STATUS_SUCCESS); } -VOID STATIC +VOID static MmModifyAttributes(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress, ULONG RegionSize, @@ -765,7 +765,7 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle, return(STATUS_SUCCESS); } -VOID STATIC +VOID static MmFreeVirtualMemoryPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, diff --git a/reactos/ntoskrnl/mm/drvlck.c b/reactos/ntoskrnl/mm/drvlck.c index 74d202e7b47..a3dbfb712a2 100644 --- a/reactos/ntoskrnl/mm/drvlck.c +++ b/reactos/ntoskrnl/mm/drvlck.c @@ -39,8 +39,7 @@ MmUnlockPagableImageSection(IN PVOID ImageSectionHandle) VOID STDCALL MmLockPagableSectionByHandle(IN PVOID ImageSectionHandle) { - // MmLockMemoryArea((MEMORY_AREA *)ImageSectionHandle); - DPRINT1("MmLockPagableSectionByHandle is unimplemented\n"); + UNIMPLEMENTED; } @@ -75,15 +74,19 @@ MmLockPagableDataSection(IN PVOID AddressWithinSection) */ VOID STDCALL MmUnlockPagableImageSection(IN PVOID ImageSectionHandle) -{} - +{ + UNIMPLEMENTED; +} /* * @unimplemented */ -VOID STDCALL +PVOID STDCALL MmPageEntireDriver(IN PVOID AddressWithinSection) -{} +{ + UNIMPLEMENTED; + return NULL; +} /* @@ -91,6 +94,8 @@ MmPageEntireDriver(IN PVOID AddressWithinSection) */ VOID STDCALL MmResetDriverPaging(IN PVOID AddressWithinSection) -{} +{ + UNIMPLEMENTED; +} /* EOF */ diff --git a/reactos/ntoskrnl/mm/elf.inc.h b/reactos/ntoskrnl/mm/elf.inc.h index 472a6571775..4defb91c840 100644 --- a/reactos/ntoskrnl/mm/elf.inc.h +++ b/reactos/ntoskrnl/mm/elf.inc.h @@ -172,12 +172,12 @@ static __inline ULONG64 ElfFmtpReadULong64 IN ULONG DataType ) { - PBYTE p; + PUCHAR p; if(DataType == ELF_TARG_DATA) return Input; - p = (PBYTE)&Input; + p = (PUCHAR)&Input; switch(DataType) { @@ -195,12 +195,12 @@ static __inline ULONG ElfFmtpReadULong IN ULONG DataType ) { - PBYTE p; + PUCHAR p; if(DataType == ELF_TARG_DATA) return Input; - p = (PBYTE)&Input; + p = (PUCHAR)&Input; switch(DataType) { @@ -218,12 +218,12 @@ static __inline USHORT ElfFmtpReadUShort IN ULONG DataType ) { - PBYTE p; + PUCHAR p; if(DataType == ELF_TARG_DATA) return Input; - p = (PBYTE)&Input; + p = (PUCHAR)&Input; switch(DataType) { @@ -241,12 +241,12 @@ static __inline ULONG64 ElfFmtpSafeReadULong64 IN ULONG DataType ) { - PBYTE p; + PUCHAR p; ULONG64 nSafeInput; RtlRetrieveUlonglong(&nSafeInput, Input); - p = (PBYTE)&nSafeInput; + p = (PUCHAR)&nSafeInput; switch(DataType) { @@ -264,7 +264,7 @@ static __inline ULONG ElfFmtpSafeReadULong IN ULONG DataType ) { - PBYTE p; + PUCHAR p; ULONG nSafeInput; union { @@ -277,7 +277,7 @@ static __inline ULONG ElfFmtpSafeReadULong if(DataType == ELF_TARG_DATA) return nSafeInput; - p = (PBYTE)&nSafeInput; + p = (PUCHAR)&nSafeInput; switch(DataType) { diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index 032a9e5a17e..5c7c3889286 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -331,21 +331,21 @@ MmNotPresentFault(KPROCESSOR_MODE Mode, /* * @unimplemented */ -DWORD STDCALL -MmAdjustWorkingSetSize (DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) +ULONG STDCALL +MmAdjustWorkingSetSize (ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2) { UNIMPLEMENTED; return (0); } -DWORD +ULONG STDCALL MmDbgTranslatePhysicalAddress ( - DWORD Unknown0, - DWORD Unknown1 + ULONG Unknown0, + ULONG Unknown1 ) { UNIMPLEMENTED; diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index c4fcb0d16d7..69a4a56b0e4 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -467,7 +467,7 @@ MmInit3(VOID) /* FIXME: Read parameters from memory */ } -VOID STATIC +VOID static MiFreeInitMemoryPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty) diff --git a/reactos/ntoskrnl/mm/ncache.c b/reactos/ntoskrnl/mm/ncache.c index 02375bdbb91..9d82fa89abd 100644 --- a/reactos/ntoskrnl/mm/ncache.c +++ b/reactos/ntoskrnl/mm/ncache.c @@ -84,7 +84,7 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes) return ((PVOID)Result); } -VOID STATIC +VOID static MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty) diff --git a/reactos/ntoskrnl/mm/npool.c b/reactos/ntoskrnl/mm/npool.c index 3e823ef058a..505497cffc8 100644 --- a/reactos/ntoskrnl/mm/npool.c +++ b/reactos/ntoskrnl/mm/npool.c @@ -95,7 +95,7 @@ typedef struct _HDR_FREE #define HDR_FREE_SIZE ROUND_UP(sizeof(HDR_FREE), MM_POOL_ALIGNMENT) -#if defined(NPOOL_REDZONE_CHECK) || #defined(NPOOL_REDZONE_CHECK_FULL) +#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) #define HDR_USED_SIZE ROUND_UP(sizeof(HDR_USED) + NPOOL_REDZONE_SIZE, MM_POOL_ALIGNMENT) #else #define HDR_USED_SIZE ROUND_UP(sizeof(HDR_USED), MM_POOL_ALIGNMENT) @@ -760,7 +760,7 @@ MiAddToTagHashTable(HDR_USED* block) #endif /* TAG_STATISTICS_TRACKING */ #if defined(TAG_STATISTICS_TRACKING) -VOID STATIC +VOID static MiDumpTagStats(ULONG CurrentTag, ULONG CurrentNrBlocks, ULONG CurrentSize) { CHAR c1, c2, c3, c4; @@ -1106,7 +1106,7 @@ static void validate_kernel_pool(void) #endif #if 0 -STATIC VOID +static VOID free_pages(HDR_FREE* blk) { ULONG start; @@ -1154,7 +1154,7 @@ add_to_free_list(HDR_FREE* blk) */ { HDR_FREE* current; - BOOL UpdatePrevPtr = FALSE; + BOOLEAN UpdatePrevPtr = FALSE; DPRINT("add_to_free_list (%d)\n", blk->hdr.Size); @@ -1469,10 +1469,10 @@ ExRosQueryNonPagedPoolTag ( PVOID Addr ) #if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) void check_redzone_header(HDR_USED* hdr) { - PBYTE LoZone = (PBYTE)((ULONG_PTR)hdr + HDR_USED_SIZE - NPOOL_REDZONE_SIZE); - PBYTE HiZone = (PBYTE)((ULONG_PTR)hdr + HDR_USED_SIZE + hdr->UserSize); - BOOL LoOK = TRUE; - BOOL HiOK = TRUE; + PUCHAR LoZone = (PUCHAR)((ULONG_PTR)hdr + HDR_USED_SIZE - NPOOL_REDZONE_SIZE); + PUCHAR HiZone = (PUCHAR)((ULONG_PTR)hdr + HDR_USED_SIZE + hdr->UserSize); + BOOLEAN LoOK = TRUE; + BOOLEAN HiOK = TRUE; ULONG i; CHAR c[5]; diff --git a/reactos/ntoskrnl/mm/pagefile.c b/reactos/ntoskrnl/mm/pagefile.c index 26f72f86202..b6253b2029e 100644 --- a/reactos/ntoskrnl/mm/pagefile.c +++ b/reactos/ntoskrnl/mm/pagefile.c @@ -149,7 +149,7 @@ MmShowOutOfSpaceMessagePagingFile(VOID) } } -LARGE_INTEGER STATIC +LARGE_INTEGER static MmGetOffsetPageFile(PRETRIEVAL_POINTERS_BUFFER RetrievalPointers, LARGE_INTEGER Offset) { /* Simple binary search */ @@ -498,7 +498,7 @@ MmAllocSwapPage(VOID) return(0); } -STATIC PRETRIEVEL_DESCRIPTOR_LIST FASTCALL +static PRETRIEVEL_DESCRIPTOR_LIST FASTCALL MmAllocRetrievelDescriptorList(ULONG Pairs) { ULONG Size; @@ -551,7 +551,7 @@ MmDumpToPagingFile(ULONG BugCode, if (!(TrapFrame->EFlags & (1 << 17))) { memcpy(&Headers->TrapFrame, TrapFrame, - sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD))); + sizeof(KTRAP_FRAME) - (4 * sizeof(ULONG))); } else { diff --git a/reactos/ntoskrnl/mm/pool.c b/reactos/ntoskrnl/mm/pool.c index 5737263c7e3..28afe5b4c7f 100644 --- a/reactos/ntoskrnl/mm/pool.c +++ b/reactos/ntoskrnl/mm/pool.c @@ -22,7 +22,7 @@ extern MM_STATS MmStats; /* FUNCTIONS ***************************************************************/ -STATIC PVOID STDCALL +static PVOID STDCALL EiAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes, ULONG Tag, diff --git a/reactos/ntoskrnl/mm/ppool.c b/reactos/ntoskrnl/mm/ppool.c index edca15f3b3e..c458c54a6ab 100644 --- a/reactos/ntoskrnl/mm/ppool.c +++ b/reactos/ntoskrnl/mm/ppool.c @@ -11,13 +11,9 @@ /* INCLUDES *****************************************************************/ -#ifdef PPOOL_UMODE_TEST -#include "ppool_umode.h" -#else//PPOOL_UMODE_TEST #include #define NDEBUG #include -#endif//PPOOL_UMODE_TEST #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, MmInitializePagedPool) @@ -138,7 +134,7 @@ int main() char* trash[COUNT]; int AllocSize[] = { 15, 31, 63, 127, 255, 511, 1023, 2047 }; const int ALLOCS = sizeof(AllocSize) / sizeof(0[AllocSize]); - DWORD dwStart; + ULONG dwStart; MmPagedPoolSize = 1*1024*1024; MmPagedPoolBase = malloc ( MmPagedPoolSize ); diff --git a/reactos/ntoskrnl/mm/region.c b/reactos/ntoskrnl/mm/region.c index 5102cf35ca5..1608c226053 100644 --- a/reactos/ntoskrnl/mm/region.c +++ b/reactos/ntoskrnl/mm/region.c @@ -16,7 +16,7 @@ /* FUNCTIONS *****************************************************************/ -VOID STATIC +VOID static InsertAfterEntry(PLIST_ENTRY Previous, PLIST_ENTRY Entry) /* @@ -31,7 +31,7 @@ InsertAfterEntry(PLIST_ENTRY Previous, Previous->Flink = Entry; } -PMM_REGION STATIC +PMM_REGION static MmSplitRegion(PMM_REGION InitialRegion, PVOID InitialBaseAddress, PVOID StartAddress, ULONG Length, ULONG NewType, ULONG NewProtect, PMADDRESS_SPACE AddressSpace, diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index d31ec1e38c6..d6e5dbdd4b2 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -461,7 +461,7 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section, return(SHARE_COUNT_FROM_SSE(Entry) > 0); } -BOOL MiIsPageFromCache(PMEMORY_AREA MemoryArea, +BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea, ULONG SegOffset) { if (!(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SCN_MEM_SHARED)) @@ -669,7 +669,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, ULONG Attributes; PMM_PAGEOP PageOp; PMM_REGION Region; - BOOL HasSwapEntry; + BOOLEAN HasSwapEntry; /* * There is a window between taking the page fault and locking the @@ -1889,7 +1889,7 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace, return(STATUS_SUCCESS); } -VOID STATIC +VOID static MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress, ULONG RegionSize, @@ -1900,7 +1900,7 @@ MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace, { PMEMORY_AREA MemoryArea; PMM_SECTION_SEGMENT Segment; - BOOL DoCOW = FALSE; + BOOLEAN DoCOW = FALSE; ULONG i; MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress); @@ -2011,7 +2011,7 @@ MmQuerySectionView(PMEMORY_AREA MemoryArea, if (Section->AllocationAttributes & SEC_IMAGE) { Segment = MemoryArea->Data.SectionData.Segment; - Info->AllocationBase = (PBYTE)MemoryArea->StartingAddress - Segment->VirtualAddress; + Info->AllocationBase = (PUCHAR)MemoryArea->StartingAddress - Segment->VirtualAddress; Info->Type = MEM_IMAGE; } else @@ -3500,7 +3500,7 @@ NtOpenSection(PHANDLE SectionHandle, return(Status); } -NTSTATUS STATIC +NTSTATUS static MmMapViewOfSegment(PMADDRESS_SPACE AddressSpace, PROS_SECTION_OBJECT Section, PMM_SECTION_SEGMENT Segment, @@ -3748,7 +3748,7 @@ NtMapViewOfSection(IN HANDLE SectionHandle, return(Status); } -VOID STATIC +VOID static MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty) { @@ -3855,7 +3855,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, } } -STATIC NTSTATUS +static NTSTATUS MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress) { @@ -4623,7 +4623,7 @@ MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, * @unimplemented */ BOOLEAN STDCALL -MmDisableModifiedWriteOfSection (DWORD Unknown0) +MmDisableModifiedWriteOfSection (ULONG Unknown0) { UNIMPLEMENTED; return (FALSE); @@ -4763,12 +4763,12 @@ MmUnmapViewInSessionSpace ( * @unimplemented */ NTSTATUS STDCALL -MmSetBankedSection (DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5) +MmSetBankedSection (ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4, + ULONG Unknown5) { UNIMPLEMENTED; return (STATUS_NOT_IMPLEMENTED); diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index f5fd8542d5e..273eca1a3f3 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -104,7 +104,7 @@ NtLockVirtualMemory(HANDLE ProcessHandle, NumberOfBytesLocked, ObReferenceObjectByHandle, MmCreateMdl, - ObfDereferenceObject, + (PVOID)ObfDereferenceObject, MmProbeAndLockPages, ExFreePool); } diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 443ba8e0cb4..dca4cab0aa1 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -7,6 +7,7 @@ + include . include diff --git a/reactos/ntoskrnl/ob/oblife.c b/reactos/ntoskrnl/ob/oblife.c index fac35da0b7e..a6b06e026cb 100644 --- a/reactos/ntoskrnl/ob/oblife.c +++ b/reactos/ntoskrnl/ob/oblife.c @@ -232,7 +232,7 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName, NTSTATUS Status = STATUS_SUCCESS; ULONG StringLength, MaximumLength; PWCHAR StringBuffer = NULL; - UNICODE_STRING LocalName = {}; /* <= GCC 4.0 + Optimizer */ + UNICODE_STRING LocalName = {0}; /* <= GCC 4.0 + Optimizer */ PAGED_CODE(); /* Initialize the Input String */ diff --git a/reactos/ntoskrnl/ob/obref.c b/reactos/ntoskrnl/ob/obref.c index 064305be0b3..07cc74f1c13 100644 --- a/reactos/ntoskrnl/ob/obref.c +++ b/reactos/ntoskrnl/ob/obref.c @@ -267,21 +267,22 @@ ObFastReplaceObject(IN PEX_FAST_REF FastRef, /* PUBLIC FUNCTIONS *********************************************************/ -VOID +LONG_PTR FASTCALL ObfReferenceObject(IN PVOID Object) { ASSERT(Object); /* Get the header and increment the reference count */ - InterlockedIncrement(&OBJECT_TO_OBJECT_HEADER(Object)->PointerCount); + return InterlockedIncrement(&OBJECT_TO_OBJECT_HEADER(Object)->PointerCount); } -VOID +LONG_PTR FASTCALL ObfDereferenceObject(IN PVOID Object) { POBJECT_HEADER Header; + LONG_PTR OldCount; /* Extract the object header */ Header = OBJECT_TO_OBJECT_HEADER(Object); @@ -289,17 +290,18 @@ ObfDereferenceObject(IN PVOID Object) if (Header->PointerCount < Header->HandleCount) { DPRINT("Misbehaving object: %wZ\n", &Header->Type->Name); - return; + return Header->PointerCount; } /* Check whether the object can now be deleted. */ - if (!(InterlockedDecrement(&Header->PointerCount))) + OldCount = InterlockedDecrement(&Header->PointerCount); + if (!OldCount) { /* Sanity check */ if (Header->HandleCount) { DPRINT("Misbehaving object: %wZ\n", &Header->Type->Name); - return; + return Header->PointerCount; } /* Check if we're at PASSIVE */ @@ -314,6 +316,9 @@ ObfDereferenceObject(IN PVOID Object) ObpDeferObjectDeletion(Object); } } + + /* Return the old count */ + return OldCount; } VOID diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 0ac2e337399..de76e161090 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -356,7 +356,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcess OPTIONAL, - IN DWORD Flags, + IN ULONG Flags, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, diff --git a/reactos/ntoskrnl/rtl/libsupp.c b/reactos/ntoskrnl/rtl/libsupp.c index f752f8db917..6caf3670670 100644 --- a/reactos/ntoskrnl/rtl/libsupp.c +++ b/reactos/ntoskrnl/rtl/libsupp.c @@ -42,7 +42,7 @@ RtlpGetMode() PVOID STDCALL -RtlpAllocateMemory(UINT Bytes, +RtlpAllocateMemory(ULONG Bytes, ULONG Tag) { return ExAllocatePoolWithTag(PagedPool, @@ -399,7 +399,7 @@ IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir, LPCWSTR name, void *root, int want_dir ); IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( IMAGE_RESOURCE_DIRECTORY *dir, - WORD id, void *root, int want_dir ); + USHORT id, void *root, int want_dir ); IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir, void *root, int want_dir ); diff --git a/reactos/ntoskrnl/rtl/strtok.c b/reactos/ntoskrnl/rtl/strtok.c index 70a31d2126b..ecb20aa7222 100644 --- a/reactos/ntoskrnl/rtl/strtok.c +++ b/reactos/ntoskrnl/rtl/strtok.c @@ -16,7 +16,7 @@ /* FUNCTIONS *****************************************************************/ -char* strtok(char *s, const char *delim) +char* __cdecl strtok(char *s, const char *delim) { const char *spanp; int c, sc; diff --git a/reactos/ntoskrnl/se/lsa.c b/reactos/ntoskrnl/se/lsa.c index a59b90a3b4e..0e9a98321fd 100644 --- a/reactos/ntoskrnl/se/lsa.c +++ b/reactos/ntoskrnl/se/lsa.c @@ -17,13 +17,13 @@ * @unimplemented */ NTSTATUS STDCALL LsaCallAuthenticationPackage ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6 + ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4, + ULONG Unknown5, + ULONG Unknown6 ) { return STATUS_NOT_IMPLEMENTED; @@ -34,8 +34,8 @@ NTSTATUS STDCALL LsaCallAuthenticationPackage ( * @unimplemented */ NTSTATUS STDCALL LsaDeregisterLogonProcess ( - DWORD Unknown0, - DWORD Unknown1 + ULONG Unknown0, + ULONG Unknown1 ) { return STATUS_NOT_IMPLEMENTED; @@ -62,20 +62,20 @@ NTSTATUS STDCALL LsaFreeReturnBuffer (PVOID Buffer) * @unimplemented */ NTSTATUS STDCALL LsaLogonUser ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6, - DWORD Unknown7, - DWORD Unknown8, - DWORD Unknown9, - DWORD Unknown10, - DWORD Unknown11, - DWORD Unknown12, - DWORD Unknown13 + ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4, + ULONG Unknown5, + ULONG Unknown6, + ULONG Unknown7, + ULONG Unknown8, + ULONG Unknown9, + ULONG Unknown10, + ULONG Unknown11, + ULONG Unknown12, + ULONG Unknown13 ) { return STATUS_NOT_IMPLEMENTED; @@ -86,9 +86,9 @@ NTSTATUS STDCALL LsaLogonUser ( * @unimplemented */ NTSTATUS STDCALL LsaLookupAuthenticationPackage ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 + ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2 ) { return STATUS_NOT_IMPLEMENTED; @@ -99,9 +99,9 @@ NTSTATUS STDCALL LsaLookupAuthenticationPackage ( * @unimplemented */ NTSTATUS STDCALL LsaRegisterLogonProcess ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 + ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2 ) { return STATUS_NOT_IMPLEMENTED; diff --git a/reactos/ntoskrnl/se/sd.c b/reactos/ntoskrnl/se/sd.c index 93f48031a2b..1924c872dd4 100644 --- a/reactos/ntoskrnl/se/sd.c +++ b/reactos/ntoskrnl/se/sd.c @@ -168,7 +168,7 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, RtlCopyMemory((PVOID)Current, SeWorldSid, SidSize); - SdRel->Owner = (DWORD)((ULONG_PTR)Current - (ULONG_PTR)SdRel); + SdRel->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); Current += SidSize; } @@ -177,7 +177,7 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, RtlCopyMemory((PVOID)Current, SeWorldSid, SidSize); - SdRel->Group = (DWORD)((ULONG_PTR)Current - (ULONG_PTR)SdRel); + SdRel->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); Current += SidSize; } @@ -199,7 +199,7 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, if (!NT_SUCCESS(Status)) return Status; - SdRel->Dacl = (DWORD)((ULONG_PTR)Current - (ULONG_PTR)SdRel); + SdRel->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); } if (SecurityInformation & SACL_SECURITY_INFORMATION) diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 0f5052cc304..12f3051a5e9 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -2135,9 +2135,9 @@ NtCreateToken(OUT PHANDLE TokenHandle, PVOID EndMem; ULONG uLength; ULONG i; - ULONG nTokenPrivileges = 0; - LARGE_INTEGER LocalExpirationTime = {}; KPROCESSOR_MODE PreviousMode; + ULONG nTokenPrivileges = 0; + LARGE_INTEGER LocalExpirationTime = {{0}}; NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); diff --git a/reactos/ntoskrnl/vdm/vdmexec.c b/reactos/ntoskrnl/vdm/vdmexec.c index 18cdc82041c..4371f46fa36 100644 --- a/reactos/ntoskrnl/vdm/vdmexec.c +++ b/reactos/ntoskrnl/vdm/vdmexec.c @@ -22,8 +22,8 @@ NTSTATUS NTAPI VdmpGetVdmTib(OUT PVDM_TIB *VdmTib) { - PAGED_CODE(); PVDM_TIB Tib; + PAGED_CODE(); /* Assume vailure */ *VdmTib = NULL; diff --git a/reactos/ntoskrnl/vdm/vdmmain.c b/reactos/ntoskrnl/vdm/vdmmain.c index 63bfbc20798..8f6a28b6ad5 100644 --- a/reactos/ntoskrnl/vdm/vdmmain.c +++ b/reactos/ntoskrnl/vdm/vdmmain.c @@ -56,7 +56,7 @@ KeI386VdmInitialize(VOID) /* Make sure that there is a WOW key */ RtlInitUnicodeString(&Name, L"\\Registry\\Machine\\System\\CurrentControlSet\\" - "Control\\Wow"); + L"Control\\Wow"); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, From e50296456bd090f9992df39a8d12c22f013350ce Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 06:36:33 +0000 Subject: [PATCH 033/488] Fixed so explorer can be compiling again. Have not tested with rest of reactos if this break any anything. svn path=/trunk/; revision=23942 --- reactos/include/psdk/shlguid.h | 4 ++++ reactos/include/reactos/wine/shlguid.h | 23 ++--------------------- reactos/include/reactos/wine/shobjidl.h | 4 ++-- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/reactos/include/psdk/shlguid.h b/reactos/include/psdk/shlguid.h index 4335ebe544d..447c2af4067 100644 --- a/reactos/include/psdk/shlguid.h +++ b/reactos/include/psdk/shlguid.h @@ -112,6 +112,10 @@ DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x00, DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); +DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); +DEFINE_GUID(IID_IDragSourceHelper, 0xde5bf786, 0x477a, 0x11d2, 0x83, 0x9d, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); +DEFINE_GUID(IID_IDropTargetHelper, 0x4657278b, 0x411b, 0x11d2, 0x83, 0x9a, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); + #define PSGUID_SHELLDETAILS {0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0} DEFINE_GUID(FMTID_ShellDetails, 0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); #define PID_FINDDATA 0 diff --git a/reactos/include/reactos/wine/shlguid.h b/reactos/include/reactos/wine/shlguid.h index 1956e490811..6f032953d7d 100644 --- a/reactos/include/reactos/wine/shlguid.h +++ b/reactos/include/reactos/wine/shlguid.h @@ -12,28 +12,9 @@ #ifndef __WINE_SHLGUID_H #define __WINE_SHLGUID_H -DEFINE_SHLGUID(CLSID_ShellDesktop, 0x00021400L, 0, 0); -DEFINE_SHLGUID(CLSID_ShellLink, 0x00021401L, 0, 0); /* command group ids */ -DEFINE_SHLGUID(CGID_Explorer, 0x000214D0L, 0, 0); -DEFINE_SHLGUID(CGID_ShellDocView, 0x000214D1L, 0, 0); -DEFINE_SHLGUID(IID_IExtractIconA, 0x000214EBL, 0, 0); -DEFINE_SHLGUID(IID_IExtractIconW, 0x000214FAL, 0, 0); -DEFINE_SHLGUID(IID_IContextMenu, 0x000214E4L, 0, 0); -DEFINE_SHLGUID(IID_IContextMenu2, 0x000214F4L, 0, 0); -DEFINE_SHLGUID(IID_ICommDlgBrowser, 0x000214F1L, 0, 0); -DEFINE_SHLGUID(IID_IShellBrowser, 0x000214E2L, 0, 0); -DEFINE_SHLGUID(IID_IShellView, 0x000214E3L, 0, 0); -DEFINE_SHLGUID(IID_IShellFolder, 0x000214E6L, 0, 0); -DEFINE_SHLGUID(IID_IShellExtInit, 0x000214E8L, 0, 0); -DEFINE_SHLGUID(IID_IPersistFolder, 0x000214EAL, 0, 0); -DEFINE_SHLGUID(IID_IShellLinkA, 0x000214EEL, 0, 0); -DEFINE_SHLGUID(IID_IEnumIDList, 0x000214F2L, 0, 0); -DEFINE_SHLGUID(IID_IShellLinkW, 0x000214F9L, 0, 0); -DEFINE_SHLGUID(IID_IShellExecuteHookA, 0x000214F5L, 0, 0); -DEFINE_SHLGUID(IID_IShellExecuteHookW, 0x000214FBL, 0, 0); DEFINE_SHLGUID(IID_IQueryInfo, 0x00021500L, 0, 0); DEFINE_GUID(SID_STopLevelBrowser, 0x4C96BE40L, 0x915C, 0x11CF, 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37); @@ -51,7 +32,7 @@ DEFINE_GUID(CLSID_FolderShortcut, 0x0AFACED1, 0xE828, 0x11D1, 0x91, 0x87, 0xB5, DEFINE_GUID(IID_IQueryAssociations, 0xc46ca590, 0x3c3f, 0x11d2, 0xbe, 0xe6, 0x00, 0x00, 0xf8, 0x05, 0xca, 0x57); -DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); + DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); @@ -60,6 +41,6 @@ DEFINE_GUID(IID_IInputObjectSite, 0x0F1DB8392, 0x7331, 0x11D0, 0x8C, 0x99, 0x0 DEFINE_GUID(IID_IShellLinkDataList, 0x45e2b4ae, 0xb1c3, 0x11d0, 0xb9, 0x2f, 0x00, 0xa0, 0xc9, 0x03, 0x12, 0xe1); -DEFINE_SHLGUID(IID_IShellPropSheetExt, 0x000214E9L, 0, 0); + #endif /* __WINE_SHLGUID_H */ diff --git a/reactos/include/reactos/wine/shobjidl.h b/reactos/include/reactos/wine/shobjidl.h index 9c85291af41..9b9fe227e90 100644 --- a/reactos/include/reactos/wine/shobjidl.h +++ b/reactos/include/reactos/wine/shobjidl.h @@ -14,9 +14,9 @@ #define CMIC_MASK_ASYNCOK SEE_MASK_ASYNCOK /***************************************************************************** - * IDropTargetHelper interface + * IDropTargetHelper interface define in shlguid.h */ -DEFINE_GUID(IID_IDropTargetHelper, 0x4657278b, 0x411b, 0x11d2, 0x83,0x9a, 0x00,0xc0,0x4f,0xd9,0x18,0xd0); +// DEFINE_GUID(IID_IDropTargetHelper, 0x4657278b, 0x411b, 0x11d2, 0x83,0x9a, 0x00,0xc0,0x4f,0xd9,0x18,0xd0); /***************************************************************************** * IPersistFolder2 interface From d6fbed40b0786ff5c6f2c6a9e9ea0fd0a644bf25 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 07:13:07 +0000 Subject: [PATCH 034/488] include psdk shlguid.h svn path=/trunk/; revision=23943 --- reactos/lib/uuid/uuid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/lib/uuid/uuid.c b/reactos/lib/uuid/uuid.c index 69a8a65e2f3..f3b32affec5 100644 --- a/reactos/lib/uuid/uuid.c +++ b/reactos/lib/uuid/uuid.c @@ -46,6 +46,7 @@ #include "wine/exdisp.h" #include "hlink.h" +#include "shlguid.h" #include "wine/shlguid.h" #include "shlobj.h" #include "shldisp.h" From bff34182ebd1dc47d8c6913c4e6e49bc68ae3068 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 07:14:49 +0000 Subject: [PATCH 035/488] update shlguid, remove the dublacte guid, winefiles can be build now again svn path=/trunk/; revision=23944 --- reactos/include/psdk/shlguid.h | 1 - reactos/include/reactos/wine/shlguid.h | 32 ++++---------------------- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/reactos/include/psdk/shlguid.h b/reactos/include/psdk/shlguid.h index 447c2af4067..f61fdfbc94e 100644 --- a/reactos/include/psdk/shlguid.h +++ b/reactos/include/psdk/shlguid.h @@ -112,7 +112,6 @@ DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x00, DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); -DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); DEFINE_GUID(IID_IDragSourceHelper, 0xde5bf786, 0x477a, 0x11d2, 0x83, 0x9d, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); DEFINE_GUID(IID_IDropTargetHelper, 0x4657278b, 0x411b, 0x11d2, 0x83, 0x9a, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); diff --git a/reactos/include/reactos/wine/shlguid.h b/reactos/include/reactos/wine/shlguid.h index 6f032953d7d..f5af4ffbf58 100644 --- a/reactos/include/reactos/wine/shlguid.h +++ b/reactos/include/reactos/wine/shlguid.h @@ -9,38 +9,14 @@ #include_next + #ifndef __WINE_SHLGUID_H #define __WINE_SHLGUID_H - /* command group ids */ - -DEFINE_SHLGUID(IID_IQueryInfo, 0x00021500L, 0, 0); - -DEFINE_GUID(SID_STopLevelBrowser, 0x4C96BE40L, 0x915C, 0x11CF, 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37); - -DEFINE_GUID(CLSID_NetworkPlaces, 0x208D2C60, 0x3AEA, 0x1069, 0xA2, 0xD7, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); -DEFINE_GUID(CLSID_MyComputer, 0x20D04FE0, 0x3AEA, 0x1069, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); -DEFINE_GUID(CLSID_Internet, 0x871C5380, 0x42A0, 0x1069, 0xA2, 0xEA, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); -DEFINE_GUID(CLSID_ShellFSFolder, 0xF3364BA0, 0x65B9, 0x11CE, 0xA9, 0xBA, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37); -DEFINE_GUID(CLSID_RecycleBin, 0x645FF040, 0x5081, 0x101B, 0x9F, 0x08, 0x00, 0xAA, 0x00, 0x2F, 0x95, 0x4E); -DEFINE_GUID(CLSID_ControlPanel, 0x21EC2020, 0x3AEA, 0x1069, 0xA2, 0xDD, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); -DEFINE_GUID(CLSID_Printers, 0x2227A280, 0x3AEA, 0x1069, 0xA2, 0xDE, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); -DEFINE_GUID(CLSID_MyDocuments, 0x450d8fba, 0xad25, 0x11d0, 0x98, 0xa8, 0x08, 0x00, 0x36, 0x1b, 0x11, 0x03); -DEFINE_GUID(CLSID_FolderShortcut, 0x0AFACED1, 0xE828, 0x11D1, 0x91, 0x87, 0xB5, 0x32, 0xF1, 0xE9, 0x57, 0x5D); - - -DEFINE_GUID(IID_IQueryAssociations, 0xc46ca590, 0x3c3f, 0x11d2, 0xbe, 0xe6, 0x00, 0x00, 0xf8, 0x05, 0xca, 0x57); - - - -DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); - -DEFINE_GUID(IID_IInputObject, 0x068284FAA, 0x6A48, 0x11D0, 0x8C, 0x78, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xB4); -DEFINE_GUID(IID_IInputObjectSite, 0x0F1DB8392, 0x7331, 0x11D0, 0x8C, 0x99, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); - DEFINE_GUID(IID_IShellLinkDataList, 0x45e2b4ae, 0xb1c3, 0x11d0, 0xb9, 0x2f, 0x00, 0xa0, 0xc9, 0x03, 0x12, 0xe1); - - #endif /* __WINE_SHLGUID_H */ + + + From 49b27aaae4c3427b5a7cb1b6f48dc2bb1288b474 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 08:20:29 +0000 Subject: [PATCH 036/488] fixed mode can be compile again. svn path=/trunk/; revision=23945 --- rosapps/cmdutils/mode/mode.rbuild | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rosapps/cmdutils/mode/mode.rbuild b/rosapps/cmdutils/mode/mode.rbuild index 017dcf2e217..98a338cd251 100644 --- a/rosapps/cmdutils/mode/mode.rbuild +++ b/rosapps/cmdutils/mode/mode.rbuild @@ -5,6 +5,8 @@ 0x0501 0x0501 kernel32 + shell32 + user32 mode.c mode.rc \ No newline at end of file From b780b50b58a7d1dc17afd3dac6f967071c130949 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 08:23:54 +0000 Subject: [PATCH 037/488] fixed build for touch again svn path=/trunk/; revision=23946 --- rosapps/cmdutils/touch/touch.rbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/rosapps/cmdutils/touch/touch.rbuild b/rosapps/cmdutils/touch/touch.rbuild index 24fdba54714..4642de716da 100644 --- a/rosapps/cmdutils/touch/touch.rbuild +++ b/rosapps/cmdutils/touch/touch.rbuild @@ -4,6 +4,7 @@ 0x0501 0x0501 ntdll + kernel32 err.c touch.c touch.rc From e32b3e758837875ab719aa97d87d96b118975bda Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 08:26:54 +0000 Subject: [PATCH 038/488] fixed build for maze again svn path=/trunk/; revision=23947 --- rosapps/demos/maze/maze.rbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/rosapps/demos/maze/maze.rbuild b/rosapps/demos/maze/maze.rbuild index 1867a51f79b..193927eca29 100644 --- a/rosapps/demos/maze/maze.rbuild +++ b/rosapps/demos/maze/maze.rbuild @@ -4,6 +4,7 @@ kernel32 gdi32 + user32 maze.c maze.rc From fa303561afe7bd91e363055e6f13401ec9d267ec Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 08:29:06 +0000 Subject: [PATCH 039/488] fixed build for ddraw_demo svn path=/trunk/; revision=23948 --- rosapps/demos/ddraw/ddraw.rbuild | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rosapps/demos/ddraw/ddraw.rbuild b/rosapps/demos/ddraw/ddraw.rbuild index 98a0fb36db8..8c6dce419da 100644 --- a/rosapps/demos/ddraw/ddraw.rbuild +++ b/rosapps/demos/ddraw/ddraw.rbuild @@ -8,6 +8,8 @@ ddraw dxguid string + user32 + main.cpp \ No newline at end of file From a5ea7e70cdccfdf5a4c29b5532bba289fe656c9e Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 08:50:42 +0000 Subject: [PATCH 040/488] fixed gdb2 build thx hpoussin for the host info svn path=/trunk/; revision=23949 --- rosapps/devutils/gdb2/gdb2.rbuild | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rosapps/devutils/gdb2/gdb2.rbuild b/rosapps/devutils/gdb2/gdb2.rbuild index 812fa93ee64..deff43c1926 100644 --- a/rosapps/devutils/gdb2/gdb2.rbuild +++ b/rosapps/devutils/gdb2/gdb2.rbuild @@ -1,7 +1,9 @@ - + . 0x0501 0x0501 + kernel32 + user32 gdb2.cpp \ No newline at end of file From 4d044a7f0da3d3af45b33f4e5808025a11d4e7b4 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 7 Sep 2006 09:06:47 +0000 Subject: [PATCH 041/488] * fix building ntoskrnl svn path=/trunk/; revision=23950 --- reactos/ntoskrnl/include/internal/ntoskrnl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index a0bae6e7b62..2871087b450 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -23,7 +23,7 @@ #include "i386/v86m.h" #include "ob.h" #include "mm.h" -#include "ex2.h" +#include "ex.h" #include "ps.h" #include "cc.h" #include "io.h" From e3d7c1e7aa676ce1246b37a16388def3f69ffb4e Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 09:17:39 +0000 Subject: [PATCH 042/488] 1. fixed mc build again 2. fixed some warnings svn path=/trunk/; revision=23951 --- rosapps/mc/mc.rbuild | 1 + rosapps/mc/slang/slvideo.c | 3 ++- rosapps/mc/slang/slw32tty.c | 8 +++----- rosapps/mc/src/cmd.c | 3 +-- rosapps/mc/src/main.c | 3 +++ 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/rosapps/mc/mc.rbuild b/rosapps/mc/mc.rbuild index a1c05c7a6e9..7fae4abbf8d 100644 --- a/rosapps/mc/mc.rbuild +++ b/rosapps/mc/mc.rbuild @@ -9,6 +9,7 @@ kernel32 user32 + advapi32 terms.c diff --git a/rosapps/mc/slang/slvideo.c b/rosapps/mc/slang/slvideo.c index b877601feff..edc1b037d97 100644 --- a/rosapps/mc/slang/slvideo.c +++ b/rosapps/mc/slang/slvideo.c @@ -1253,11 +1253,12 @@ void SLtt_putchar (char ch) # else /* GO32_VIDEO */ pp = mkScreenPointer (Cursor_Row, Cursor_Col); p = (Attribute_Byte << 8) | (unsigned char) ch; + *pp = p; # ifdef USE_ASM SNOW_CHECK; # endif - *pp = p; + # endif /* GO32_VIDEO */ # endif /* __os2__ */ #endif /* EMX_VIDEO */ diff --git a/rosapps/mc/slang/slw32tty.c b/rosapps/mc/slang/slw32tty.c index a92c7d93a64..2cc3538388b 100644 --- a/rosapps/mc/slang/slw32tty.c +++ b/rosapps/mc/slang/slw32tty.c @@ -130,8 +130,7 @@ void SLang_reset_tty (void) \*----------------------------------------------------------------------*/ int SLsys_input_pending (int tsecs) { - INPUT_RECORD record; - long one = 1; + INPUT_RECORD record; DWORD bytesRead; while (1) @@ -193,9 +192,8 @@ int SLsys_input_pending (int tsecs) * extended keys are prefixed by a null character \*----------------------------------------------------------------------*/ unsigned int SLsys_getkey (void) -{ - unsigned int scan, ch, shift; - long key; +{ + // long key; DWORD bytesRead; INPUT_RECORD record; diff --git a/rosapps/mc/src/cmd.c b/rosapps/mc/src/cmd.c index ba09f408102..a3f529af2ae 100644 --- a/rosapps/mc/src/cmd.c +++ b/rosapps/mc/src/cmd.c @@ -721,8 +721,7 @@ void reselect_vfs (void) static int compare_files (char *name1, char *name2, long size) { - int file1, file2; - char *data1, *data2; + int file1, file2; int result = -1; /* Different by default */ file1 = open (name1, O_RDONLY); diff --git a/rosapps/mc/src/main.c b/rosapps/mc/src/main.c index 4554db0f26c..46c57924206 100644 --- a/rosapps/mc/src/main.c +++ b/rosapps/mc/src/main.c @@ -379,7 +379,10 @@ try_to_select (WPanel *panel, char *name) void cd_try_to_select (WPanel *panel) { +#ifdef USE_VFS char *p, *q; +#endif + int i, j = 4; if (strlen (panel->lwd) > strlen (panel->cwd) From d287153576427c505bbf79a82844aa4e5125067c Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 09:42:17 +0000 Subject: [PATCH 043/488] fixed all network apps in rosapps. svn path=/trunk/; revision=23952 --- rosapps/net/ncftp/ncftp.rbuild | 2 ++ rosapps/net/netreg/netreg.rbuild | 3 ++- rosapps/net/niclist/niclist.rbuild | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rosapps/net/ncftp/ncftp.rbuild b/rosapps/net/ncftp/ncftp.rbuild index f309b3b7562..7dd739e7463 100644 --- a/rosapps/net/ncftp/ncftp.rbuild +++ b/rosapps/net/ncftp/ncftp.rbuild @@ -10,6 +10,8 @@ 0x0501 0x0501 kernel32 + user32 + advapi32 ws2_32 diff --git a/rosapps/net/netreg/netreg.rbuild b/rosapps/net/netreg/netreg.rbuild index b2ee9fb29ab..bb4a5d67008 100644 --- a/rosapps/net/netreg/netreg.rbuild +++ b/rosapps/net/netreg/netreg.rbuild @@ -1,9 +1,10 @@ - + . 0x0501 0x0501 kernel32 + user32 ws2_32 netreg.cpp diff --git a/rosapps/net/niclist/niclist.rbuild b/rosapps/net/niclist/niclist.rbuild index 6b721f214be..dc0d21a9c72 100644 --- a/rosapps/net/niclist/niclist.rbuild +++ b/rosapps/net/niclist/niclist.rbuild @@ -3,6 +3,8 @@ 0x0501 0x0501 + kernel32 + user32 niclist.c niclist.rc From c410304d3c5841d263ea325c3633e22b863fe68e Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 09:46:50 +0000 Subject: [PATCH 044/488] fixed waring msg newline svn path=/trunk/; revision=23953 --- rosapps/packmgr/gui/fr.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rosapps/packmgr/gui/fr.rc b/rosapps/packmgr/gui/fr.rc index b22871724df..adcd36f3ec5 100644 --- a/rosapps/packmgr/gui/fr.rc +++ b/rosapps/packmgr/gui/fr.rc @@ -43,4 +43,4 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Action !", 6 END -END \ No newline at end of file +END From d6a960a8844515c5d50477eccf05e9ca9c7e5d95 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 09:53:25 +0000 Subject: [PATCH 045/488] fixed so packmgr builds again svn path=/trunk/; revision=23954 --- rosapps/packmgr/lib/package.rbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rosapps/packmgr/lib/package.rbuild b/rosapps/packmgr/lib/package.rbuild index 8d916d66b6a..af9c2532f4e 100644 --- a/rosapps/packmgr/lib/package.rbuild +++ b/rosapps/packmgr/lib/package.rbuild @@ -1,4 +1,4 @@ - + . From 433252a0844ecdb756bdc4510a78494090c6234c Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 10:01:22 +0000 Subject: [PATCH 046/488] fixed ctm, kill, lsdd, man, regexpl, tcat can be build again svn path=/trunk/; revision=23955 --- rosapps/sysutils/ctm/ctm.rbuild | 3 +++ rosapps/sysutils/kill/kill.rbuild | 3 +++ rosapps/sysutils/lsdd/lsdd.rbuild | 3 +++ rosapps/sysutils/man/man.rbuild | 3 +++ rosapps/sysutils/regexpl/regexpl.rbuild | 4 +++- rosapps/sysutils/tcat/cat.rbuild | 3 +++ 6 files changed, 18 insertions(+), 1 deletion(-) diff --git a/rosapps/sysutils/ctm/ctm.rbuild b/rosapps/sysutils/ctm/ctm.rbuild index ae9206a77a8..63d4fc7089b 100644 --- a/rosapps/sysutils/ctm/ctm.rbuild +++ b/rosapps/sysutils/ctm/ctm.rbuild @@ -4,6 +4,9 @@ epsapi ntdll + kernel32 + user32 + ctm.c ctm.rc diff --git a/rosapps/sysutils/kill/kill.rbuild b/rosapps/sysutils/kill/kill.rbuild index 09f7d835448..7f9e4b385b4 100644 --- a/rosapps/sysutils/kill/kill.rbuild +++ b/rosapps/sysutils/kill/kill.rbuild @@ -1,6 +1,9 @@ ntdll + kernel32 + user32 + kill.c kill.rc diff --git a/rosapps/sysutils/lsdd/lsdd.rbuild b/rosapps/sysutils/lsdd/lsdd.rbuild index babd252f57a..38d429f8e63 100644 --- a/rosapps/sysutils/lsdd/lsdd.rbuild +++ b/rosapps/sysutils/lsdd/lsdd.rbuild @@ -4,6 +4,9 @@ 0x0501 0x0501 lib + kernel32 + user32 + lsdd.c lsdd.rc diff --git a/rosapps/sysutils/man/man.rbuild b/rosapps/sysutils/man/man.rbuild index 04ee13478af..da407112e68 100644 --- a/rosapps/sysutils/man/man.rbuild +++ b/rosapps/sysutils/man/man.rbuild @@ -1,5 +1,8 @@ ntdll + kernel32 + user32 + man.c diff --git a/rosapps/sysutils/regexpl/regexpl.rbuild b/rosapps/sysutils/regexpl/regexpl.rbuild index 6683dcbabbf..2003c734f94 100644 --- a/rosapps/sysutils/regexpl/regexpl.rbuild +++ b/rosapps/sysutils/regexpl/regexpl.rbuild @@ -1,6 +1,8 @@ - + . + kernel32 + user32 ArgumentParser.cpp Console.cpp diff --git a/rosapps/sysutils/tcat/cat.rbuild b/rosapps/sysutils/tcat/cat.rbuild index 692ce6cfbae..972be2c6d5f 100644 --- a/rosapps/sysutils/tcat/cat.rbuild +++ b/rosapps/sysutils/tcat/cat.rbuild @@ -1,5 +1,8 @@ ntdll + kernel32 + user32 + cat.c From 01acfd4778dd3e4a142e5a673726dd160570ecbf Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 10:31:37 +0000 Subject: [PATCH 047/488] fixed follow test, acclertor, alive, alphablend, bitblt, button, button2, capclock, carets, combotst, dibtest, dirdlg, DxHalTest, edit, enhmetafile, enumfonts, enumwnd, enumws, gradient, hello, hivtest, icontest, lineclip, linetest, mdi, midtest svn path=/trunk/; revision=23956 --- rosapps/tests/DxHalTest/DxHalTest.rbuild | 1 + rosapps/tests/accelerator/accelerator.rbuild | 1 + rosapps/tests/alive/alive.rbuild | 1 + rosapps/tests/alphablend/alphablend.rbuild | 1 + rosapps/tests/bitblt/bitblt.rbuild | 1 + rosapps/tests/button/button.rbuild | 1 + rosapps/tests/button2/button2.rbuild | 1 + rosapps/tests/capclock/capclock.rbuild | 1 + rosapps/tests/carets/carets.rbuild | 1 + rosapps/tests/combotst/combotst.rbuild | 1 + rosapps/tests/dibtest/dibtest.rbuild | 1 + rosapps/tests/dirdlg/dirdlg.rbuild | 1 + rosapps/tests/edit/edit.rbuild | 1 + rosapps/tests/enhmetafile/enhmetafile.rbuild | 1 + rosapps/tests/enumfonts/enumfonts.rbuild | 3 ++- rosapps/tests/enumwnd/enumwnd.rbuild | 1 + rosapps/tests/enumws/enumws.rbuild | 1 + rosapps/tests/gradient/gradient.rbuild | 1 + rosapps/tests/hello/hello.rbuild | 1 + rosapps/tests/hivetest/hivetest.rbuild | 2 ++ rosapps/tests/icontest/icontest.rbuild | 1 + rosapps/tests/lineclip/lineclip.rbuild | 1 + rosapps/tests/linetest/linetest.rbuild | 1 + rosapps/tests/mdi/mdi.rbuild | 1 + rosapps/tests/miditest/miditest.rbuild | 1 + 25 files changed, 27 insertions(+), 1 deletion(-) diff --git a/rosapps/tests/DxHalTest/DxHalTest.rbuild b/rosapps/tests/DxHalTest/DxHalTest.rbuild index 6e8f6d436c8..ed3a146ce00 100644 --- a/rosapps/tests/DxHalTest/DxHalTest.rbuild +++ b/rosapps/tests/DxHalTest/DxHalTest.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 main.c diff --git a/rosapps/tests/accelerator/accelerator.rbuild b/rosapps/tests/accelerator/accelerator.rbuild index 642694cb4b3..59b32676b1c 100644 --- a/rosapps/tests/accelerator/accelerator.rbuild +++ b/rosapps/tests/accelerator/accelerator.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 accelerator.c diff --git a/rosapps/tests/alive/alive.rbuild b/rosapps/tests/alive/alive.rbuild index e5d39c0b320..369699809c1 100644 --- a/rosapps/tests/alive/alive.rbuild +++ b/rosapps/tests/alive/alive.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 alive.c diff --git a/rosapps/tests/alphablend/alphablend.rbuild b/rosapps/tests/alphablend/alphablend.rbuild index 9e195012529..843a46ba97f 100644 --- a/rosapps/tests/alphablend/alphablend.rbuild +++ b/rosapps/tests/alphablend/alphablend.rbuild @@ -4,6 +4,7 @@ . kernel32 + user32 gdi32 alphablend.c alphablend.rc diff --git a/rosapps/tests/bitblt/bitblt.rbuild b/rosapps/tests/bitblt/bitblt.rbuild index 958d1ee5bef..f55909c5320 100644 --- a/rosapps/tests/bitblt/bitblt.rbuild +++ b/rosapps/tests/bitblt/bitblt.rbuild @@ -4,6 +4,7 @@ . kernel32 + user32 gdi32 bitblt.c bitblt.rc diff --git a/rosapps/tests/button/button.rbuild b/rosapps/tests/button/button.rbuild index 798c7b3654c..0f269c14046 100644 --- a/rosapps/tests/button/button.rbuild +++ b/rosapps/tests/button/button.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 buttontst.c diff --git a/rosapps/tests/button2/button2.rbuild b/rosapps/tests/button2/button2.rbuild index e553737600a..98a94728bab 100644 --- a/rosapps/tests/button2/button2.rbuild +++ b/rosapps/tests/button2/button2.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 buttontst2.c diff --git a/rosapps/tests/capclock/capclock.rbuild b/rosapps/tests/capclock/capclock.rbuild index 75cb985f251..78b5a645df8 100644 --- a/rosapps/tests/capclock/capclock.rbuild +++ b/rosapps/tests/capclock/capclock.rbuild @@ -4,6 +4,7 @@ . kernel32 + user32 gdi32 capclock.c capclock.rc diff --git a/rosapps/tests/carets/carets.rbuild b/rosapps/tests/carets/carets.rbuild index 0e8394fe523..bbd3acfc54d 100644 --- a/rosapps/tests/carets/carets.rbuild +++ b/rosapps/tests/carets/carets.rbuild @@ -4,6 +4,7 @@ . kernel32 + user32 gdi32 ntdll carets.c diff --git a/rosapps/tests/combotst/combotst.rbuild b/rosapps/tests/combotst/combotst.rbuild index 5ca773623bd..873635bd93d 100644 --- a/rosapps/tests/combotst/combotst.rbuild +++ b/rosapps/tests/combotst/combotst.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 combotst.c utils.c diff --git a/rosapps/tests/dibtest/dibtest.rbuild b/rosapps/tests/dibtest/dibtest.rbuild index 17910a2da74..4b44f5fad73 100644 --- a/rosapps/tests/dibtest/dibtest.rbuild +++ b/rosapps/tests/dibtest/dibtest.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 dibtest.c diff --git a/rosapps/tests/dirdlg/dirdlg.rbuild b/rosapps/tests/dirdlg/dirdlg.rbuild index 9798f6ba3a8..361f4df1c51 100644 --- a/rosapps/tests/dirdlg/dirdlg.rbuild +++ b/rosapps/tests/dirdlg/dirdlg.rbuild @@ -4,6 +4,7 @@ . kernel32 + user32 gdi32 dirdlg.c dirdlg.rc diff --git a/rosapps/tests/edit/edit.rbuild b/rosapps/tests/edit/edit.rbuild index 8f75ea66879..3f1180bec24 100644 --- a/rosapps/tests/edit/edit.rbuild +++ b/rosapps/tests/edit/edit.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 edittest.c utils.c diff --git a/rosapps/tests/enhmetafile/enhmetafile.rbuild b/rosapps/tests/enhmetafile/enhmetafile.rbuild index 330b705aba1..f37c9049f51 100644 --- a/rosapps/tests/enhmetafile/enhmetafile.rbuild +++ b/rosapps/tests/enhmetafile/enhmetafile.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 enhmetafile.c diff --git a/rosapps/tests/enumfonts/enumfonts.rbuild b/rosapps/tests/enumfonts/enumfonts.rbuild index cd36f503d97..64d96b3994c 100644 --- a/rosapps/tests/enumfonts/enumfonts.rbuild +++ b/rosapps/tests/enumfonts/enumfonts.rbuild @@ -1,8 +1,9 @@ - + 0x0501 0x0501 kernel32 + user32 gdi32 enumfonts.cpp diff --git a/rosapps/tests/enumwnd/enumwnd.rbuild b/rosapps/tests/enumwnd/enumwnd.rbuild index 480183b56da..71adefa1a6e 100644 --- a/rosapps/tests/enumwnd/enumwnd.rbuild +++ b/rosapps/tests/enumwnd/enumwnd.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 enumwnd.c diff --git a/rosapps/tests/enumws/enumws.rbuild b/rosapps/tests/enumws/enumws.rbuild index 18a93ffd1c8..336845c8c32 100644 --- a/rosapps/tests/enumws/enumws.rbuild +++ b/rosapps/tests/enumws/enumws.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 enumws.c diff --git a/rosapps/tests/gradient/gradient.rbuild b/rosapps/tests/gradient/gradient.rbuild index 43ca3b692ae..c1abf616af6 100644 --- a/rosapps/tests/gradient/gradient.rbuild +++ b/rosapps/tests/gradient/gradient.rbuild @@ -4,6 +4,7 @@ 0x0501 kernel32 + user32 gdi32 gradient.c diff --git a/rosapps/tests/hello/hello.rbuild b/rosapps/tests/hello/hello.rbuild index 49641eaa694..6fe80047e88 100644 --- a/rosapps/tests/hello/hello.rbuild +++ b/rosapps/tests/hello/hello.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 hello.c diff --git a/rosapps/tests/hivetest/hivetest.rbuild b/rosapps/tests/hivetest/hivetest.rbuild index e7e21e9cb27..54784969a8e 100644 --- a/rosapps/tests/hivetest/hivetest.rbuild +++ b/rosapps/tests/hivetest/hivetest.rbuild @@ -3,6 +3,8 @@ 0x0501 kernel32 + user32 ntdll + advapi32 hivetest.c diff --git a/rosapps/tests/icontest/icontest.rbuild b/rosapps/tests/icontest/icontest.rbuild index 9223a2b579b..e61c3df6324 100644 --- a/rosapps/tests/icontest/icontest.rbuild +++ b/rosapps/tests/icontest/icontest.rbuild @@ -4,6 +4,7 @@ . kernel32 + user32 gdi32 ntdll icontest.c diff --git a/rosapps/tests/lineclip/lineclip.rbuild b/rosapps/tests/lineclip/lineclip.rbuild index fdeab748ddf..f18d31a9bdc 100644 --- a/rosapps/tests/lineclip/lineclip.rbuild +++ b/rosapps/tests/lineclip/lineclip.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 lineclip.c diff --git a/rosapps/tests/linetest/linetest.rbuild b/rosapps/tests/linetest/linetest.rbuild index 88dff36d5a5..a2b203b4249 100644 --- a/rosapps/tests/linetest/linetest.rbuild +++ b/rosapps/tests/linetest/linetest.rbuild @@ -4,6 +4,7 @@ 0x0501 kernel32 + user32 gdi32 linetest.c diff --git a/rosapps/tests/mdi/mdi.rbuild b/rosapps/tests/mdi/mdi.rbuild index 3a19e18badb..1198f68df42 100644 --- a/rosapps/tests/mdi/mdi.rbuild +++ b/rosapps/tests/mdi/mdi.rbuild @@ -4,6 +4,7 @@ . kernel32 + user32 gdi32 comctl32 comdlg32 diff --git a/rosapps/tests/miditest/miditest.rbuild b/rosapps/tests/miditest/miditest.rbuild index 0496cc96947..7b58d7bd544 100644 --- a/rosapps/tests/miditest/miditest.rbuild +++ b/rosapps/tests/miditest/miditest.rbuild @@ -4,6 +4,7 @@ . kernel32 + user32 winmm miditest.c From 861ae4bcca50ea8ab5196e1e25afbf995a337616 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 11:10:27 +0000 Subject: [PATCH 048/488] fixed rosapps so it compiles again svn path=/trunk/; revision=23957 --- rosapps/tests/multithrdwin/multithrdwin.rbuild | 4 +++- rosapps/tests/multiwin/multiwin.rbuild | 1 + rosapps/tests/noexecute/noexecute.rbuild | 4 +++- rosapps/tests/palbitblt/palbitblt.rbuild | 3 ++- rosapps/tests/patblt/patblt.rbuild | 3 ++- rosapps/tests/popupmenu/popupmenu.rbuild | 1 + rosapps/tests/primitives/primitives.rbuild | 1 + rosapps/tests/regqueryvalue/regqueryvalue.rbuild | 2 ++ rosapps/tests/shaptest/shaptest.rbuild | 1 + rosapps/tests/statst/statst.rbuild | 1 + rosapps/tests/statst2/statst2.rbuild | 1 + rosapps/tests/stretchblt/stretchblt.rbuild | 3 ++- rosapps/tests/subclass/subclass.rbuild | 1 + rosapps/tests/thread_msg/thread_msg.rbuild | 1 + rosapps/tests/txtscale/txtscale.rbuild | 3 ++- rosapps/tests/wclickat/wclickat.rbuild | 1 + rosapps/tests/winhello/winhello.rbuild | 1 + rosapps/tests/wm_erasebkgnd/wm_erasebkgnd.rbuild | 1 + rosapps/tests/wm_paint/wm_paint.rbuild | 1 + 19 files changed, 28 insertions(+), 6 deletions(-) diff --git a/rosapps/tests/multithrdwin/multithrdwin.rbuild b/rosapps/tests/multithrdwin/multithrdwin.rbuild index b1fe5ca02c4..d404e70f89d 100644 --- a/rosapps/tests/multithrdwin/multithrdwin.rbuild +++ b/rosapps/tests/multithrdwin/multithrdwin.rbuild @@ -3,7 +3,9 @@ 0x0501 kernel32 + user32 gdi32 - ntdll + ntdll + multithrdwin.c diff --git a/rosapps/tests/multiwin/multiwin.rbuild b/rosapps/tests/multiwin/multiwin.rbuild index a738f3b6dba..3b1f2c320ee 100644 --- a/rosapps/tests/multiwin/multiwin.rbuild +++ b/rosapps/tests/multiwin/multiwin.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 multiwin.c diff --git a/rosapps/tests/noexecute/noexecute.rbuild b/rosapps/tests/noexecute/noexecute.rbuild index 7adc14ac0ab..afed6b3e6dc 100644 --- a/rosapps/tests/noexecute/noexecute.rbuild +++ b/rosapps/tests/noexecute/noexecute.rbuild @@ -2,7 +2,9 @@ 0x0501 0x0501 - kernel32 pseh + kernel32 + user32 + noexecute.c diff --git a/rosapps/tests/palbitblt/palbitblt.rbuild b/rosapps/tests/palbitblt/palbitblt.rbuild index f5e84fb206e..dc7b902008e 100644 --- a/rosapps/tests/palbitblt/palbitblt.rbuild +++ b/rosapps/tests/palbitblt/palbitblt.rbuild @@ -1,8 +1,9 @@ - + 0x0501 0x0501 kernel32 + user32 gdi32 pal.c diff --git a/rosapps/tests/patblt/patblt.rbuild b/rosapps/tests/patblt/patblt.rbuild index 318c535fa10..56631d4c290 100644 --- a/rosapps/tests/patblt/patblt.rbuild +++ b/rosapps/tests/patblt/patblt.rbuild @@ -1,8 +1,9 @@ - + 0x0501 0x0501 kernel32 + user32 gdi32 patblt.cpp diff --git a/rosapps/tests/popupmenu/popupmenu.rbuild b/rosapps/tests/popupmenu/popupmenu.rbuild index f627033e873..d0c527c195e 100644 --- a/rosapps/tests/popupmenu/popupmenu.rbuild +++ b/rosapps/tests/popupmenu/popupmenu.rbuild @@ -4,6 +4,7 @@ . kernel32 + user32 gdi32 popupmenu.c popupmenu.rc diff --git a/rosapps/tests/primitives/primitives.rbuild b/rosapps/tests/primitives/primitives.rbuild index 549e90e8c44..482e9d47eb7 100644 --- a/rosapps/tests/primitives/primitives.rbuild +++ b/rosapps/tests/primitives/primitives.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 primitives.cpp mk_font.cpp diff --git a/rosapps/tests/regqueryvalue/regqueryvalue.rbuild b/rosapps/tests/regqueryvalue/regqueryvalue.rbuild index c1d7c4fbb31..0c345e6052c 100644 --- a/rosapps/tests/regqueryvalue/regqueryvalue.rbuild +++ b/rosapps/tests/regqueryvalue/regqueryvalue.rbuild @@ -3,6 +3,8 @@ 0x0501 kernel32 + user32 + advapi32 gdi32 regqueryvalue.c diff --git a/rosapps/tests/shaptest/shaptest.rbuild b/rosapps/tests/shaptest/shaptest.rbuild index 35317cd57a3..0bcdafe8ab0 100644 --- a/rosapps/tests/shaptest/shaptest.rbuild +++ b/rosapps/tests/shaptest/shaptest.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 shaptest.c diff --git a/rosapps/tests/statst/statst.rbuild b/rosapps/tests/statst/statst.rbuild index 790a1828056..5dd54df4c78 100644 --- a/rosapps/tests/statst/statst.rbuild +++ b/rosapps/tests/statst/statst.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 statst.c diff --git a/rosapps/tests/statst2/statst2.rbuild b/rosapps/tests/statst2/statst2.rbuild index 5cfb8fdd932..a8489f4785c 100644 --- a/rosapps/tests/statst2/statst2.rbuild +++ b/rosapps/tests/statst2/statst2.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 statst2.c diff --git a/rosapps/tests/stretchblt/stretchblt.rbuild b/rosapps/tests/stretchblt/stretchblt.rbuild index ad8de6ee3cf..76a319dea9b 100644 --- a/rosapps/tests/stretchblt/stretchblt.rbuild +++ b/rosapps/tests/stretchblt/stretchblt.rbuild @@ -1,8 +1,9 @@ - + 0x0501 0x0501 kernel32 + user32 gdi32 stretchblt.cpp diff --git a/rosapps/tests/subclass/subclass.rbuild b/rosapps/tests/subclass/subclass.rbuild index cb58165f94a..8eb191482ec 100644 --- a/rosapps/tests/subclass/subclass.rbuild +++ b/rosapps/tests/subclass/subclass.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 subclass.c diff --git a/rosapps/tests/thread_msg/thread_msg.rbuild b/rosapps/tests/thread_msg/thread_msg.rbuild index bb63b8bb66c..f8ed4f07b82 100644 --- a/rosapps/tests/thread_msg/thread_msg.rbuild +++ b/rosapps/tests/thread_msg/thread_msg.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 thread_msg.c diff --git a/rosapps/tests/txtscale/txtscale.rbuild b/rosapps/tests/txtscale/txtscale.rbuild index 2b4ac4c0fdf..2faacefd36a 100644 --- a/rosapps/tests/txtscale/txtscale.rbuild +++ b/rosapps/tests/txtscale/txtscale.rbuild @@ -1,8 +1,9 @@ - + 0x0501 0x0501 kernel32 + user32 gdi32 comctl32 txtscale.cpp diff --git a/rosapps/tests/wclickat/wclickat.rbuild b/rosapps/tests/wclickat/wclickat.rbuild index 5c3d0cb3b16..2a354eecef3 100644 --- a/rosapps/tests/wclickat/wclickat.rbuild +++ b/rosapps/tests/wclickat/wclickat.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 wclickat.c diff --git a/rosapps/tests/winhello/winhello.rbuild b/rosapps/tests/winhello/winhello.rbuild index 57689a5cacd..2217e6d6b0d 100644 --- a/rosapps/tests/winhello/winhello.rbuild +++ b/rosapps/tests/winhello/winhello.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 winhello.c diff --git a/rosapps/tests/wm_erasebkgnd/wm_erasebkgnd.rbuild b/rosapps/tests/wm_erasebkgnd/wm_erasebkgnd.rbuild index 71c5ea213b2..5f0f800d4f7 100644 --- a/rosapps/tests/wm_erasebkgnd/wm_erasebkgnd.rbuild +++ b/rosapps/tests/wm_erasebkgnd/wm_erasebkgnd.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 wm_erasebkgnd.cpp diff --git a/rosapps/tests/wm_paint/wm_paint.rbuild b/rosapps/tests/wm_paint/wm_paint.rbuild index 3e5e2732d46..5bcfc22d64f 100644 --- a/rosapps/tests/wm_paint/wm_paint.rbuild +++ b/rosapps/tests/wm_paint/wm_paint.rbuild @@ -3,6 +3,7 @@ 0x0501 kernel32 + user32 gdi32 wm_paint.c From 8f329a85658f63c62c08971f3d5986b1e8db39a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 13:47:14 +0000 Subject: [PATCH 049/488] Fix typo: _GNUC_ -> __GNUC__ svn path=/trunk/; revision=23958 --- reactos/ntoskrnl/include/internal/ntoskrnl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index 2871087b450..4ebee9234d7 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -5,7 +5,7 @@ * Use these to place a function in a specific section of the executable */ #define PLACE_IN_SECTION(s) __attribute__((section (s))) -#ifdef _GNUC_ +#ifdef __GNUC__ #define INIT_FUNCTION PLACE_IN_SECTION("init") #define PAGE_LOCKED_FUNCTION PLACE_IN_SECTION("pagelk") #define PAGE_UNLOCKED_FUNCTION PLACE_IN_SECTION("pagepo") From 3387c46e161b577e0ae1737e31d9ff6de6e99d9b Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 7 Sep 2006 17:35:31 +0000 Subject: [PATCH 050/488] fixed win32k build, trunks builds again thanks w3seek for the help svn path=/trunk/; revision=23959 --- reactos/include/ddk/winddk.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 3d99f011e4a..1c11651c97d 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -40,7 +40,14 @@ extern "C" { #define DDKCDECLAPI __cdecl /* FIXME: REMOVE THIS UNCOMPATIBLE CRUFT!!! */ -#define NTKERNELAPI +//#define NTKERNELAPI + +#ifdef _NTOSKRNL_ +#define NTKERNELAPI +#else +#define NTKERNELAPI DECLSPEC_IMPORT +#endif + #ifndef NTOSAPI #define NTOSAPI NTKERNELAPI From eb50899ee05c7e8443a8a7e0a85b7b0709643998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 17:39:42 +0000 Subject: [PATCH 051/488] Declare prototype for ChkdskEx function in u{FS}.dll svn path=/trunk/; revision=23960 --- reactos/base/system/autochk/autochk.c | 2 +- reactos/dll/win32/fmifs/init.c | 5 +---- reactos/dll/win32/fmifs/precomp.h | 13 +------------ reactos/include/reactos/libs/fmifs/fmifs.h | 20 ++++++++++++++++++++ reactos/lib/fslib/vfatlib/vfatlib.h | 2 +- reactos/lib/fslib/vfatxlib/vfatxlib.h | 2 +- 6 files changed, 25 insertions(+), 19 deletions(-) diff --git a/reactos/base/system/autochk/autochk.c b/reactos/base/system/autochk/autochk.c index 4d49ae27603..21a4786ee03 100644 --- a/reactos/base/system/autochk/autochk.c +++ b/reactos/base/system/autochk/autochk.c @@ -15,9 +15,9 @@ #include #define WIN32_NO_STATUS #include -#include #define NTOS_MODE_USER #include +#include /* DEFINES ******************************************************************/ diff --git a/reactos/dll/win32/fmifs/init.c b/reactos/dll/win32/fmifs/init.c index 41ef3115d35..b6a0c15c478 100644 --- a/reactos/dll/win32/fmifs/init.c +++ b/reactos/dll/win32/fmifs/init.c @@ -58,12 +58,9 @@ AddProvider( RtlZeroMemory(Provider, RequiredSize); /* Get function pointers */ - //Provider->Chkdsk = (CHKDSK)GetProcAddress(hMod, "Chkdsk"); - //Provider->ChkdskEx = (CHKDSKEX)GetProcAddress(hMod, "ChkdskEx"); + Provider->ChkdskEx = (CHKDSKEX)GetProcAddress(hMod, "ChkdskEx"); //Provider->Extend = (EXTEND)GetProcAddress(hMod, "Extend"); - //Provider->Format = (FORMAT)GetProcAddress(hMod, "Format"); Provider->FormatEx = (FORMATEX)GetProcAddress(hMod, "FormatEx"); - //Provider->Recover = (RECOVER)GetProcAddress(hMod, "Recover"); wcscpy(Provider->Name, FileSystem); diff --git a/reactos/dll/win32/fmifs/precomp.h b/reactos/dll/win32/fmifs/precomp.h index a69c66c4c57..4e8d37713aa 100644 --- a/reactos/dll/win32/fmifs/precomp.h +++ b/reactos/dll/win32/fmifs/precomp.h @@ -25,26 +25,15 @@ /* VFATLIB Public Header */ #include -typedef NTSTATUS (NTAPI *FORMATEX)( - IN PUNICODE_STRING DriveRoot, - IN FMIFS_MEDIA_FLAG MediaFlag, - IN PUNICODE_STRING Label, - IN BOOLEAN QuickFormat, - IN ULONG ClusterSize, - IN PFMIFSCALLBACK Callback); - extern LIST_ENTRY ProviderListHead; typedef struct _IFS_PROVIDER { LIST_ENTRY ListEntry; - PVOID Chkdsk; - PVOID ChkdskEx; + CHKDSKEX ChkdskEx; PVOID Extend; - PVOID Format; FORMATEX FormatEx; - PVOID Recover; WCHAR Name[1]; } IFS_PROVIDER, *PIFS_PROVIDER; diff --git a/reactos/include/reactos/libs/fmifs/fmifs.h b/reactos/include/reactos/libs/fmifs/fmifs.h index eb5daf8418f..36a36c5fb0d 100644 --- a/reactos/include/reactos/libs/fmifs/fmifs.h +++ b/reactos/include/reactos/libs/fmifs/fmifs.h @@ -164,4 +164,24 @@ QuerySupportedMedia( ULONG Unknown3, ULONG Unknown4);*/ +/* Functions provided by u*.dll */ + +typedef NTSTATUS +(NTAPI *FORMATEX)( + IN PUNICODE_STRING DriveRoot, + IN FMIFS_MEDIA_FLAG MediaFlag, + IN PUNICODE_STRING Label, + IN BOOLEAN QuickFormat, + IN ULONG ClusterSize, + IN PFMIFSCALLBACK Callback); + +typedef NTSTATUS +(NTAPI *CHKDSKEX)( + IN PUNICODE_STRING DriveRoot, + IN BOOLEAN FixErrors, + IN BOOLEAN Verbose, + IN BOOLEAN CheckOnlyIfDirty, + IN BOOLEAN ScanDrive, + IN PFMIFSCALLBACK Callback); + #endif /* ndef _FMIFS_H */ diff --git a/reactos/lib/fslib/vfatlib/vfatlib.h b/reactos/lib/fslib/vfatlib/vfatlib.h index cbc770f362e..ed3c793559f 100755 --- a/reactos/lib/fslib/vfatlib/vfatlib.h +++ b/reactos/lib/fslib/vfatlib/vfatlib.h @@ -6,9 +6,9 @@ #define WIN32_NO_STATUS #include -#include #define NTOS_MODE_USER #include +#include #define SECTORSIZE 512 diff --git a/reactos/lib/fslib/vfatxlib/vfatxlib.h b/reactos/lib/fslib/vfatxlib/vfatxlib.h index 9d358e1882e..d67d8712403 100644 --- a/reactos/lib/fslib/vfatxlib/vfatxlib.h +++ b/reactos/lib/fslib/vfatxlib/vfatxlib.h @@ -5,9 +5,9 @@ */ #define WIN32_NO_STATUS #include -#include #define NTOS_MODE_USER #include +#include typedef struct _FATX_BOOT_SECTOR { From 611b577fd6872e4f811803a039ec33eab9ce9117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 17:44:08 +0000 Subject: [PATCH 052/488] Add a stub for FAT12/16/32 chkdsk svn path=/trunk/; revision=23961 --- reactos/dll/win32/ufat/ufat.c | 27 +++++++++++++++++++++++++++ reactos/dll/win32/ufat/ufat.def | 1 + reactos/dll/win32/ufat/ufat.rbuild | 1 + reactos/lib/fslib/vfatlib/vfatlib.c | 13 +++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 reactos/dll/win32/ufat/ufat.c diff --git a/reactos/dll/win32/ufat/ufat.c b/reactos/dll/win32/ufat/ufat.c new file mode 100644 index 00000000000..8a876a29ab3 --- /dev/null +++ b/reactos/dll/win32/ufat/ufat.c @@ -0,0 +1,27 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: FAT File System Management + * FILE: reactos/dll/win32/fmifs/init.c + * PURPOSE: Initialisation + * + * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + */ + +#define WIN32_NO_STATUS +#include +#define NTOS_MODE_USER +#include +#include + +INT WINAPI +DllMain( + IN HINSTANCE hinstDLL, + IN DWORD dwReason, + IN LPVOID lpvReserved) +{ + UNREFERENCED_PARAMETER(hinstDLL); + UNREFERENCED_PARAMETER(dwReason); + UNREFERENCED_PARAMETER(lpvReserved); + + return TRUE; +} diff --git a/reactos/dll/win32/ufat/ufat.def b/reactos/dll/win32/ufat/ufat.def index 53da9341f3a..778424762f7 100644 --- a/reactos/dll/win32/ufat/ufat.def +++ b/reactos/dll/win32/ufat/ufat.def @@ -1,3 +1,4 @@ LIBRARY UFAT.DLL EXPORTS +ChkdskEx=VfatChkdsk@24 FormatEx=VfatFormat@24 \ No newline at end of file diff --git a/reactos/dll/win32/ufat/ufat.rbuild b/reactos/dll/win32/ufat/ufat.rbuild index c214aed2f24..033f7e92541 100644 --- a/reactos/dll/win32/ufat/ufat.rbuild +++ b/reactos/dll/win32/ufat/ufat.rbuild @@ -6,5 +6,6 @@ 0x0600 vfatlib ntdll + ufat.c ufat.rc diff --git a/reactos/lib/fslib/vfatlib/vfatlib.c b/reactos/lib/fslib/vfatlib/vfatlib.c index 386679689d7..1401da39963 100755 --- a/reactos/lib/fslib/vfatlib/vfatlib.c +++ b/reactos/lib/fslib/vfatlib/vfatlib.c @@ -203,4 +203,17 @@ UpdateProgress (PFORMAT_CONTEXT Context, } } +NTSTATUS WINAPI +VfatChkdsk( + IN PUNICODE_STRING DriveRoot, + IN BOOLEAN FixErrors, + IN BOOLEAN Verbose, + IN BOOLEAN CheckOnlyIfDirty, + IN BOOLEAN ScanDrive, + IN PFMIFSCALLBACK Callback) +{ + DPRINT1("VfatChkdsk() unimplemented!\n"); + return STATUS_NOT_IMPLEMENTED; +} + /* EOF */ From 0d173915ac0d267a0bd100441e53560596dc9684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 17:54:23 +0000 Subject: [PATCH 053/488] Correctly implement autochk, which now calls the ChkdskEx function in u{FS}.dll. svn path=/trunk/; revision=23962 --- reactos/base/system/autochk/autochk.c | 207 +++++++++++++++----------- 1 file changed, 118 insertions(+), 89 deletions(-) diff --git a/reactos/base/system/autochk/autochk.c b/reactos/base/system/autochk/autochk.c index 21a4786ee03..86f6cc29e44 100644 --- a/reactos/base/system/autochk/autochk.c +++ b/reactos/base/system/autochk/autochk.c @@ -1,10 +1,10 @@ -/* $Id$ - * PROJECT: ReactOS Kernel +/* PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/autochk/autochk.c * PURPOSE: Filesystem checker * PROGRAMMERS: Aleksey Bragin * Eric Kohl + * Hervé Poussineau */ /* INCLUDES *****************************************************************/ @@ -28,30 +28,8 @@ // // FMIFS function // -typedef -VOID -(STDCALL *PCHKDSK)(PWCHAR DriveRoot, - PWCHAR Format, - BOOLEAN CorrectErrors, - BOOLEAN Verbose, - BOOLEAN CheckOnlyIfDirty, - BOOLEAN ScanDrive, - PVOID Unused2, - PVOID Unused3, - PFMIFSCALLBACK Callback); -PCHKDSK ChkdskFunc = NULL; - -void -DisplayString(LPCWSTR lpwString) -{ - UNICODE_STRING us; - - RtlInitUnicodeString(&us, lpwString); - NtDisplayString(&us); -} - -void +static VOID PrintString(char* fmt,...) { char buffer[512]; @@ -72,9 +50,10 @@ PrintString(char* fmt,...) } // this func is taken from kernel32/file/volume.c -HANDLE -OpenDirectory(LPCWSTR DirName, - BOOLEAN Write) +static HANDLE +OpenDirectory( + IN LPCWSTR DirName, + IN BOOLEAN Write) { UNICODE_STRING NtPathU; OBJECT_ATTRIBUTES ObjectAttributes; @@ -121,10 +100,11 @@ OpenDirectory(LPCWSTR DirName, return hFile; } -NTSTATUS -GetFileSystem(LPCWSTR Drive, - LPWSTR FileSystemName, - ULONG FileSystemNameSize) +static NTSTATUS +GetFileSystem( + IN LPCWSTR Drive, + IN OUT LPWSTR FileSystemName, + IN SIZE_T FileSystemNameSize) { HANDLE FileHandle; NTSTATUS Status; @@ -149,9 +129,9 @@ GetFileSystem(LPCWSTR Drive, { if (FileSystemNameSize * sizeof(WCHAR) >= FileFsAttribute->FileSystemNameLength + sizeof(WCHAR)) { - memcpy(FileSystemName, - FileFsAttribute->FileSystemName, - FileFsAttribute->FileSystemNameLength); + CopyMemory(FileSystemName, + FileFsAttribute->FileSystemName, + FileFsAttribute->FileSystemNameLength); FileSystemName[FileFsAttribute->FileSystemNameLength / sizeof(WCHAR)] = 0; } else @@ -164,11 +144,11 @@ GetFileSystem(LPCWSTR Drive, } // This is based on SysInternal's ChkDsk app -BOOLEAN -STDCALL -ChkdskCallback(CALLBACKCOMMAND Command, - DWORD Modifier, - PVOID Argument) +static BOOLEAN CALLBACK +ChkdskCallback( + IN CALLBACKCOMMAND Command, + IN DWORD Modifier, + IN PVOID Argument) { PDWORD Percent; PBOOLEAN Status; @@ -254,6 +234,86 @@ ChkdskCallback(CALLBACKCOMMAND Command, return TRUE; } +/* Load the provider associated with this file system */ +static PVOID +LoadProvider( + IN PWCHAR FileSystem) +{ + UNICODE_STRING ProviderDll = RTL_CONSTANT_STRING(L"ufat.dll"); + PVOID BaseAddress; + NTSTATUS Status; + + /* FIXME: add more providers here */ + + if (wcscmp(FileSystem, L"FAT") != 0 + && wcscmp(FileSystem, L"FAT32") != 0) + { + return NULL; + } + + Status = LdrLoadDll(NULL, NULL, &ProviderDll, &BaseAddress); + if (!NT_SUCCESS(Status)) + return NULL; + return BaseAddress; +} + +static NTSTATUS +CheckVolume( + IN PWCHAR DrivePath) +{ + WCHAR FileSystem[128]; + ANSI_STRING ChkdskFunctionName = RTL_CONSTANT_STRING("ChkdskEx"); + PVOID Provider; + CHKDSKEX ChkdskFunc; + UNICODE_STRING DrivePathU; + NTSTATUS Status; + + /* Get the file system */ + Status = GetFileSystem(DrivePath, + FileSystem, + sizeof(FileSystem) / sizeof(FileSystem[0])); + if (!NT_SUCCESS(Status)) + { + DPRINT1("GetFileSystem() failed with status 0x%08lx\n", Status); + PrintString(" Unable to get file system of %S\n", DrivePath); + return Status; + } + + /* Load the provider which will do the chkdsk */ + Provider = LoadProvider(FileSystem); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LoadProvider() failed\n"); + PrintString(" Unable to verify a %S volume\n", FileSystem); + return STATUS_DLL_NOT_FOUND; + } + + /* Get the Chkdsk function address */ + Status = LdrGetProcedureAddress(Provider, + &ChkdskFunctionName, + 0, + (PVOID*)&ChkdskFunc); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LdrGetProcedureAddress() failed with status 0x%08lx\n", Status); + PrintString(" Unable to verify a %S volume\n", FileSystem); + LdrUnloadDll(Provider); + return Status; + } + + /* Call provider */ + PrintString(" Verifying volume %S\n", DrivePath); + RtlInitUnicodeString(&DrivePathU, DrivePath); + Status = ChkdskFunc(&DrivePathU, + TRUE, // FixErrors + TRUE, // Verbose + FALSE, // CheckOnlyIfDirty + FALSE,// ScanDrive + ChkdskCallback); + + LdrUnloadDll(Provider); + return Status; +} /* Native image's entry point */ int @@ -266,11 +326,8 @@ _main(int argc, PROCESS_DEVICEMAP_INFORMATION DeviceMap; ULONG i; NTSTATUS Status; - WCHAR FileSystem[128]; WCHAR DrivePath[128]; - PrintString("Autochk 0.0.2\n"); - // Win2003 passes the only param - "*". Probably means to check all drives /* DPRINT("Got %d params\n", argc); @@ -278,61 +335,33 @@ _main(int argc, DPRINT("Param %d: %s\n", i, argv[i]); */ + /* FIXME: We should probably use here the mount manager to be + * able to check volumes which don't have a drive letter. + */ + Status = NtQueryInformationProcess(NtCurrentProcess(), ProcessDeviceMap, &DeviceMap.Query, sizeof(DeviceMap.Query), NULL); - - if(NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { - for (i = 0; i < 26; i++) - { - if ((DeviceMap.Query.DriveMap & (1 << i)) && - (DeviceMap.Query.DriveType[i] == DOSDEVICE_DRIVE_FIXED)) - { - swprintf(DrivePath, L"%c:\\", 'A'+i); - Status = GetFileSystem(DrivePath, - FileSystem, - sizeof(FileSystem)); - PrintString(" Checking drive %c: \n", 'A'+i); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Error getting FS information, Status=0x%08X\n", - Status); - // skip to the next volume - continue; - } - - // FS type known, show it to user and then call chkdsk routine - PrintString(" Filesystem type "); - DisplayString(FileSystem); - PrintString("\n"); - - /*ChkdskFunc(DrivePath, - FileSystem, - TRUE, // FixErrors - TRUE, // Verbose - FALSE, // SkipClean - FALSE,// ScanSectors - NULL, - NULL, - ChkdskCallback);*/ - - PrintString(" OK\n"); - } - } - PrintString("\n"); - return 0; - } - else - { - DPRINT1("NtQueryInformationProcess() failed with status=0x%08X\n", + DPRINT1("NtQueryInformationProcess() failed with status 0x%08lx\n", Status); + return 1; } - return 1; + for (i = 0; i < 26; i++) + { + if ((DeviceMap.Query.DriveMap & (1 << i)) + && (DeviceMap.Query.DriveType[i] == DOSDEVICE_DRIVE_FIXED)) + { + swprintf(DrivePath, L"%c:\\", 'A'+i); + CheckVolume(DrivePath); + } + } + PrintString(" Done\n\n"); + return 0; } /* EOF */ From 24ff7a71b42090da4bbabbf7ae85b1ca9bc2b931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 17:55:51 +0000 Subject: [PATCH 054/488] Fix compilation svn path=/trunk/; revision=23963 --- reactos/base/setup/usetup/usetup.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/setup/usetup/usetup.h b/reactos/base/setup/usetup/usetup.h index b309bee5330..133b76b9eb0 100644 --- a/reactos/base/setup/usetup/usetup.h +++ b/reactos/base/setup/usetup/usetup.h @@ -35,9 +35,9 @@ /* PSDK/NDK */ #define WIN32_NO_STATUS #include -#include #define NTOS_MODE_USER #include +#include /* VFAT */ #include From a2548c11a4cd4b0505917abd3112f062f9883cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 18:08:00 +0000 Subject: [PATCH 055/488] Fix format.exe compilation svn path=/trunk/; revision=23964 --- reactos/base/system/format/format.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/base/system/format/format.c b/reactos/base/system/format/format.c index aabd9280fc8..1bdf1f25778 100755 --- a/reactos/base/system/format/format.c +++ b/reactos/base/system/format/format.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include "resource.h" From 022504ad3cf21ae1f6b6ca800424826a1f7c5f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 19:13:37 +0000 Subject: [PATCH 056/488] Some 64 bits fixes (approved by Filip) svn path=/trunk/; revision=23965 --- reactos/lib/cmlib/cminit.c | 4 ++-- reactos/lib/cmlib/cmlib.h | 15 ++++++++------- reactos/lib/cmlib/cmlib.mak | 15 +++++++++++++++ reactos/lib/cmlib/hivebin.c | 2 +- reactos/lib/cmlib/hivecell.c | 2 +- reactos/lib/cmlib/hiveinit.c | 4 ++-- reactos/lib/cmlib/hivewrt.c | 8 ++++---- reactos/ntoskrnl/cm/regfile.c | 10 +++++----- 8 files changed, 38 insertions(+), 22 deletions(-) diff --git a/reactos/lib/cmlib/cminit.c b/reactos/lib/cmlib/cminit.c index 5da56d3e6d7..ac4a41314f6 100644 --- a/reactos/lib/cmlib/cminit.c +++ b/reactos/lib/cmlib/cminit.c @@ -14,7 +14,7 @@ CmCreateRootNode( { PCM_KEY_NODE KeyCell; HCELL_INDEX RootCellIndex; - ULONG NameSize; + SIZE_T NameSize; NameSize = wcslen(Name) * sizeof(WCHAR); RootCellIndex = HvAllocateCell(Hive, sizeof(CM_KEY_NODE) + NameSize, HvStable); @@ -37,7 +37,7 @@ CmCreateRootNode( KeyCell->ValueList.List = HCELL_NULL; KeyCell->SecurityKeyOffset = HCELL_NULL; KeyCell->ClassNameOffset = HCELL_NULL; - KeyCell->NameSize = NameSize; + KeyCell->NameSize = (USHORT)NameSize; KeyCell->ClassSize = 0; memcpy(KeyCell->Name, Name, NameSize); diff --git a/reactos/lib/cmlib/cmlib.h b/reactos/lib/cmlib/cmlib.h index b94af317c8d..ab699d63906 100644 --- a/reactos/lib/cmlib/cmlib.h +++ b/reactos/lib/cmlib/cmlib.h @@ -8,6 +8,7 @@ #ifndef CMLIB_H #define CMLIB_H +#define WIN32_NO_STATUS #include #include "hivedata.h" #include "cmdata.h" @@ -30,7 +31,7 @@ typedef VOID (CMAPI *PRELEASE_CELL_ROUTINE)( HCELL_INDEX Cell); typedef PVOID (CMAPI *PALLOCATE_ROUTINE)( - ULONG Size, + SIZE_T Size, BOOLEAN Paged); typedef VOID (CMAPI *PFREE_ROUTINE)( @@ -39,21 +40,21 @@ typedef VOID (CMAPI *PFREE_ROUTINE)( typedef BOOLEAN (CMAPI *PFILE_READ_ROUTINE)( struct _HHIVE *RegistryHive, ULONG FileType, - ULONG FileOffset, + ULONGLONG FileOffset, PVOID Buffer, - ULONG BufferLength); + SIZE_T BufferLength); typedef BOOLEAN (CMAPI *PFILE_WRITE_ROUTINE)( struct _HHIVE *RegistryHive, ULONG FileType, - ULONG FileOffset, + ULONGLONG FileOffset, PVOID Buffer, - ULONG BufferLength); + SIZE_T BufferLength); typedef BOOLEAN (CMAPI *PFILE_SET_SIZE_ROUTINE)( struct _HHIVE *RegistryHive, ULONG FileType, - ULONG FileSize); + ULONGLONG FileSize); typedef BOOLEAN (CMAPI *PFILE_FLUSH_ROUTINE)( struct _HHIVE *RegistryHive, @@ -168,7 +169,7 @@ HvGetCellSize( HCELL_INDEX CMAPI HvAllocateCell( PHHIVE RegistryHive, - ULONG Size, + SIZE_T Size, HV_STORAGE_TYPE Storage); HCELL_INDEX CMAPI diff --git a/reactos/lib/cmlib/cmlib.mak b/reactos/lib/cmlib/cmlib.mak index 301f3bd3ffd..076a7925853 100644 --- a/reactos/lib/cmlib/cmlib.mak +++ b/reactos/lib/cmlib/cmlib.mak @@ -19,9 +19,12 @@ CMLIB_HOST_TARGET = \ $(CMLIB_OUT)$(SEP)cmlib.a CMLIB_HOST_SOURCES = $(addprefix $(CMLIB_BASE_), \ + cminit.c \ hivebin.c \ hivecell.c \ hiveinit.c \ + hivesum.c \ + hivewrt.c \ ) CMLIB_HOST_OBJECTS = \ @@ -36,6 +39,10 @@ $(CMLIB_HOST_TARGET): $(CMLIB_HOST_OBJECTS) | $(CMLIB_OUT) $(ECHO_AR) $(host_ar) -r $@ $(CMLIB_HOST_OBJECTS) +$(CMLIB_INT_)cminit.o: $(CMLIB_BASE_)cminit.c | $(CMLIB_INT) + $(ECHO_CC) + ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ + $(CMLIB_INT_)hivebin.o: $(CMLIB_BASE_)hivebin.c | $(CMLIB_INT) $(ECHO_CC) ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ @@ -48,6 +55,14 @@ $(CMLIB_INT_)hiveinit.o: $(CMLIB_BASE_)hiveinit.c | $(CMLIB_INT) $(ECHO_CC) ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ +$(CMLIB_INT_)hivesum.o: $(CMLIB_BASE_)hivesum.c | $(CMLIB_INT) + $(ECHO_CC) + ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ + +$(CMLIB_INT_)hivewrt.o: $(CMLIB_BASE_)hivewrt.c | $(CMLIB_INT) + $(ECHO_CC) + ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ + .PHONY: cmlib_host cmlib_host: $(CMLIB_HOST_TARGET) diff --git a/reactos/lib/cmlib/hivebin.c b/reactos/lib/cmlib/hivebin.c index ad13e9286b3..29e74b925ae 100644 --- a/reactos/lib/cmlib/hivebin.c +++ b/reactos/lib/cmlib/hivebin.c @@ -16,7 +16,7 @@ HvpAddBin( { PHMAP_ENTRY BlockList; PHBIN Bin; - ULONG BinSize; + SIZE_T BinSize; ULONG i; ULONG BitmapSize; ULONG BlockCount; diff --git a/reactos/lib/cmlib/hivecell.c b/reactos/lib/cmlib/hivecell.c index 893388e1721..ce341276d39 100644 --- a/reactos/lib/cmlib/hivecell.c +++ b/reactos/lib/cmlib/hivecell.c @@ -351,7 +351,7 @@ HvReallocateCell( return HCELL_NULL; NewCell = HvGetCell(RegistryHive, NewCellIndex); - RtlCopyMemory(NewCell, OldCell, -OldCellSize); + RtlCopyMemory(NewCell, OldCell, (SIZE_T)-OldCellSize); HvFreeCell(RegistryHive, CellIndex); diff --git a/reactos/lib/cmlib/hiveinit.c b/reactos/lib/cmlib/hiveinit.c index f587cfded26..567789cd383 100644 --- a/reactos/lib/cmlib/hiveinit.c +++ b/reactos/lib/cmlib/hiveinit.c @@ -151,7 +151,7 @@ HvpInitializeMemoryHive( // ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length; ((PHBASE_BLOCK)ChunkBase)->Length = HV_BLOCK_SIZE; - DPRINT1("ChunkSize: %lx\n", ChunkSize); + DPRINT("ChunkSize: %lx\n", ChunkSize); if (ChunkSize < sizeof(HBASE_BLOCK) || !HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase)) @@ -173,7 +173,7 @@ HvpInitializeMemoryHive( * we go. */ - Hive->Storage[HvStable].Length = (ChunkSize / HV_BLOCK_SIZE) - 1; + Hive->Storage[HvStable].Length = (ULONG)(ChunkSize / HV_BLOCK_SIZE) - 1; Hive->Storage[HvStable].BlockList = Hive->Allocate(Hive->Storage[HvStable].Length * sizeof(HMAP_ENTRY), FALSE); diff --git a/reactos/lib/cmlib/hivewrt.c b/reactos/lib/cmlib/hivewrt.c index ce0e1af87cc..e1d1c11e752 100644 --- a/reactos/lib/cmlib/hivewrt.c +++ b/reactos/lib/cmlib/hivewrt.c @@ -13,9 +13,9 @@ static BOOLEAN CMAPI HvpWriteLog( PHHIVE RegistryHive) { - ULONG FileOffset; - ULONG BufferSize; - ULONG BitmapSize; + ULONGLONG FileOffset; + SIZE_T BufferSize; + SIZE_T BitmapSize; PUCHAR Buffer; PUCHAR Ptr; ULONG BlockIndex; @@ -138,7 +138,7 @@ HvpWriteHive( PHHIVE RegistryHive, BOOLEAN OnlyDirty) { - ULONG FileOffset; + ULONGLONG FileOffset; ULONG BlockIndex; ULONG LastIndex; PVOID BlockPtr; diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index 858d5f618fa..8ccb8a09e3c 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -46,9 +46,9 @@ BOOLEAN CMAPI CmpFileRead( PHHIVE RegistryHive, ULONG FileType, - ULONG FileOffset, + ULONGLONG FileOffset, PVOID Buffer, - ULONG BufferLength) + SIZE_T BufferLength) { PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; @@ -67,9 +67,9 @@ BOOLEAN CMAPI CmpFileWrite( PHHIVE RegistryHive, ULONG FileType, - ULONG FileOffset, + ULONGLONG FileOffset, PVOID Buffer, - ULONG BufferLength) + SIZE_T BufferLength) { PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; @@ -88,7 +88,7 @@ BOOLEAN CMAPI CmpFileSetSize( PHHIVE RegistryHive, ULONG FileType, - ULONG FileSize) + ULONGLONG FileSize) { PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; From 2417bf273fabee77c652d447567ed683f66541f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 19:16:47 +0000 Subject: [PATCH 057/488] Correctly handle optional parameters svn path=/trunk/; revision=23966 --- reactos/dll/ntdll/ldr/utils.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 44f62fe5d17..f7a94cd4d07 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -727,7 +727,7 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL, */ NTSTATUS NTAPI LdrLoadDll (IN PWSTR SearchPath OPTIONAL, - IN PULONG LoadFlags, + IN PULONG LoadFlags OPTIONAL, IN PUNICODE_STRING Name, OUT PVOID *BaseAddress OPTIONAL) { @@ -741,19 +741,22 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, if (Name == NULL) { - *BaseAddress = NtCurrentPeb()->ImageBaseAddress; + if (BaseAddress) + *BaseAddress = NtCurrentPeb()->ImageBaseAddress; return STATUS_SUCCESS; } - *BaseAddress = NULL; + if (BaseAddress) + *BaseAddress = NULL; - Status = LdrpLoadModule(SearchPath, *LoadFlags, Name, &Module, BaseAddress); - if (NT_SUCCESS(Status) && 0 == (*LoadFlags & LOAD_LIBRARY_AS_DATAFILE)) + Status = LdrpLoadModule(SearchPath, LoadFlags ? *LoadFlags : 0, Name, &Module, BaseAddress); + if (NT_SUCCESS(Status) + && (!LoadFlags || 0 == (*LoadFlags & LOAD_LIBRARY_AS_DATAFILE))) { RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock); Status = LdrpAttachProcess(); RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); - if (NT_SUCCESS(Status)) + if (NT_SUCCESS(Status) && BaseAddress) { *BaseAddress = Module->DllBase; } From 3a4bb3b8dce8f70c2a14f7df0da251067b0811c1 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Thu, 7 Sep 2006 19:20:42 +0000 Subject: [PATCH 058/488] Yes we should do it as WINE. Fixes a buffer overflow in RtlDetermineDosPathNameType_U() svn path=/trunk/; revision=23967 --- reactos/lib/rtl/path.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/reactos/lib/rtl/path.c b/reactos/lib/rtl/path.c index 2b69c371264..4b23f14f29e 100644 --- a/reactos/lib/rtl/path.c +++ b/reactos/lib/rtl/path.c @@ -75,12 +75,7 @@ RtlDetermineDosPathNameType_U(PCWSTR Path) } else { - /* FIXME: the Wine version of this line reads: - * if (!Path[1] || Path[1] != L':') return RtlPathTypeRelative - * Should we do this too? - * -Gunnar - */ - if (Path[1] != L':') return RtlPathTypeRelative; /* xxx */ + if (!Path[1] || Path[1] != L':') return RtlPathTypeRelative; /* xxx */ if (IS_PATH_SEPARATOR(Path[2])) return RtlPathTypeDriveAbsolute; /* x:\xxx */ return RtlPathTypeDriveRelative; /* x:xxx */ From 2fad285b1409d9237e76f3dbfda8f092b00b066f Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 7 Sep 2006 19:23:39 +0000 Subject: [PATCH 059/488] Removed NtUserGetKeyboardType, there was no win32k.db entry for it. svn path=/trunk/; revision=23968 --- .../subsystems/win32/win32k/ntuser/keyboard.c | 27 +++++++++---------- .../subsystems/win32/win32k/ntuser/ntstubs.c | 15 ----------- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/keyboard.c b/reactos/subsystems/win32/win32k/ntuser/keyboard.c index 57c21740a6b..6694acb0a10 100644 --- a/reactos/subsystems/win32/win32k/ntuser/keyboard.c +++ b/reactos/subsystems/win32/win32k/ntuser/keyboard.c @@ -1284,7 +1284,8 @@ UserGetKeyboardLayout( SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; } - W32Thread = Thread->Tcb.Win32Thread; + W32Thread = Thread->Tcb.Win32Thread; /* Wrong, but returning the pointer to + the table. */ } layout = W32Thread->KeyboardLayout; if(!layout) @@ -1330,22 +1331,20 @@ UserGetKeyboardType( } } + DWORD STDCALL -NtUserGetKeyboardType( - DWORD TypeFlag) +NtUserLoadKeyboardLayoutEx( + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3, + DWORD Unknown4, + DWORD Unknown5) { - DECLARE_RETURN(DWORD); - - DPRINT("Enter NtUserGetKeyboardType\n"); - UserEnterShared(); - - RETURN( UserGetKeyboardType(TypeFlag)); - -CLEANUP: - DPRINT("Leave NtUserGetKeyboardType, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; + UNIMPLEMENTED + + return 0; } diff --git a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c index c4a6ee56f12..56495fc0ae6 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c @@ -441,21 +441,6 @@ NtUserInitTask( return 0; } -DWORD -STDCALL -NtUserLoadKeyboardLayoutEx( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5) -{ - UNIMPLEMENTED - - return 0; -} - DWORD STDCALL NtUserLockWorkStation(VOID) From 1b337150cc1992c40fc41938cd81ecc24a7a081c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 19:46:18 +0000 Subject: [PATCH 060/488] Update prototypes svn path=/trunk/; revision=23969 --- reactos/ntoskrnl/cm/cm.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 1a554d7424e..8af8576539a 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -401,23 +401,23 @@ BOOLEAN CMAPI CmpFileRead( PHHIVE RegistryHive, ULONG FileType, - ULONG FileOffset, + ULONGLONG FileOffset, PVOID Buffer, - ULONG BufferLength); + SIZE_T BufferLength); BOOLEAN CMAPI CmpFileWrite( PHHIVE RegistryHive, ULONG FileType, - ULONG FileOffset, + ULONGLONG FileOffset, PVOID Buffer, - ULONG BufferLength); + SIZE_T BufferLength); BOOLEAN CMAPI CmpFileSetSize( PHHIVE RegistryHive, ULONG FileType, - ULONG FileSize); + ULONGLONG FileSize); BOOLEAN CMAPI CmpFileFlush( From 8c22629a9eda677027de92a239984b6a3f90789e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 20:15:45 +0000 Subject: [PATCH 061/488] [FORMATTING] Fix tab/space mess by replacing them by 4 spaces. No code change svn path=/trunk/; revision=23970 --- reactos/base/setup/usetup/format.c | 123 ++++++++++----------- reactos/base/setup/usetup/format.h | 3 +- reactos/base/setup/usetup/fslist.c | 167 +++++++++++++++-------------- reactos/base/setup/usetup/fslist.h | 21 ++-- 4 files changed, 156 insertions(+), 158 deletions(-) diff --git a/reactos/base/setup/usetup/format.c b/reactos/base/setup/usetup/format.c index 9f665bc6b69..3c22a7f1d24 100644 --- a/reactos/base/setup/usetup/format.c +++ b/reactos/base/setup/usetup/format.c @@ -16,8 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS text-mode setup * FILE: subsys/system/usetup/format.c * PURPOSE: Filesystem format support functions @@ -35,89 +34,81 @@ PPROGRESSBAR ProgressBar = NULL; /* FUNCTIONS ****************************************************************/ - -BOOLEAN NTAPI -FormatCallback (CALLBACKCOMMAND Command, - ULONG Modifier, - PVOID Argument) +static BOOLEAN NTAPI +FormatCallback( + IN CALLBACKCOMMAND Command, + IN ULONG Modifier, + IN PVOID Argument) { -// DPRINT1 ("FormatCallback() called\n"); - - switch (Command) + switch (Command) { - case PROGRESS: - { - PULONG Percent; + case PROGRESS: + { + PULONG Percent; - Percent = (PULONG)Argument; - DPRINT ("%lu percent completed\n", *Percent); + Percent = (PULONG)Argument; + DPRINT("%lu percent completed\n", *Percent); - ProgressSetStep (ProgressBar, *Percent); - } - break; + ProgressSetStep(ProgressBar, *Percent); + break; + } -// case OUTPUT: -// { -// PTEXTOUTPUT Output; -// output = (PTEXTOUTPUT) Argument; -// fprintf(stdout, "%s", output->Output); -// } -// break; + /*case OUTPUT: + { + PTEXTOUTPUT Output; + output = (PTEXTOUTPUT) Argument; + DPRINT("%s\n", output->Output); + break; + }*/ - case DONE: - { - DPRINT ("Done\n"); -// PBOOLEAN Success; -// status = (PBOOLEAN) Argument; -// if ( *status == FALSE ) -// { -// wprintf(L"FormatEx was unable to complete successfully.\n\n"); -// Error = TRUE; -// } - } - break; + case DONE: + { + /*PBOOLEAN Success;*/ + DPRINT("Done\n"); - default: - DPRINT ("Unknown callback %lu\n", (ULONG)Command); - break; + /*Success = (PBOOLEAN)Argument; + if (*Success == FALSE) + { + DPRINT("FormatEx was unable to complete successfully.\n\n"); + }*/ + break; + } + + default: + DPRINT("Unknown callback %lu\n", (ULONG)Command); + break; } -// DPRINT1 ("FormatCallback() done\n"); - - return TRUE; + return TRUE; } - NTSTATUS -FormatPartition (PUNICODE_STRING DriveRoot) +FormatPartition( + IN PUNICODE_STRING DriveRoot) { - NTSTATUS Status; - SHORT xScreen; - SHORT yScreen; + NTSTATUS Status; - CONSOLE_GetScreenSize(&xScreen, &yScreen); + ProgressBar = CreateProgressBar(6, + yScreen - 14, + xScreen - 7, + yScreen - 10, + "Setup is formatting your disk"); - ProgressBar = CreateProgressBar (6, - yScreen - 14, - xScreen - 7, - yScreen - 10, - "Setup is formatting your disk"); + ProgressSetStepCount(ProgressBar, 100); - ProgressSetStepCount (ProgressBar, 100); + Status = VfatFormat(DriveRoot, + FMIFS_HARDDISK, /* MediaFlag */ + NULL, /* Label */ + TRUE, /* QuickFormat */ + 0, /* ClusterSize */ + FormatCallback); /* Callback */ - Status = VfatFormat (DriveRoot, - 0, /* MediaFlag */ - NULL, /* Label */ - TRUE, /* QuickFormat */ - 0, /* ClusterSize */ - (PFMIFSCALLBACK)FormatCallback); /* Callback */ + DestroyProgressBar(ProgressBar); + ProgressBar = NULL; - DestroyProgressBar (ProgressBar); - ProgressBar = NULL; + DPRINT("FormatEx() finished with status 0x%08lx\n", Status); - DPRINT ("VfatFormat() status 0x%.08x\n", Status); - - return Status; + return Status; } /* EOF */ diff --git a/reactos/base/setup/usetup/format.h b/reactos/base/setup/usetup/format.h index 193e3d43ee0..1725664b27f 100644 --- a/reactos/base/setup/usetup/format.h +++ b/reactos/base/setup/usetup/format.h @@ -28,7 +28,8 @@ #define __FORMAT_H__ NTSTATUS -FormatPartition(PUNICODE_STRING DriveRoot); +FormatPartition( + IN PUNICODE_STRING DriveRoot); #endif /* __FILESUP_H__ */ diff --git a/reactos/base/setup/usetup/fslist.c b/reactos/base/setup/usetup/fslist.c index 684acee2a7d..34b4f22085c 100644 --- a/reactos/base/setup/usetup/fslist.c +++ b/reactos/base/setup/usetup/fslist.c @@ -33,128 +33,129 @@ /* FUNCTIONS ****************************************************************/ PFILE_SYSTEM_LIST -CreateFileSystemList (SHORT Left, - SHORT Top, - BOOLEAN ForceFormat, - FILE_SYSTEM ForceFileSystem) +CreateFileSystemList( + IN SHORT Left, + IN SHORT Top, + IN BOOLEAN ForceFormat, + IN FILE_SYSTEM ForceFileSystem) { - PFILE_SYSTEM_LIST List; + PFILE_SYSTEM_LIST List; - List = (PFILE_SYSTEM_LIST)RtlAllocateHeap (ProcessHeap, 0, sizeof(FILE_SYSTEM_LIST)); - if (List == NULL) - return NULL; + List = (PFILE_SYSTEM_LIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_LIST)); + if (List == NULL) + return NULL; - List->Left = Left; - List->Top = Top; + List->Left = Left; + List->Top = Top; - List->ForceFormat = ForceFormat; - List->FileSystemCount = 1; - if (ForceFormat) + List->ForceFormat = ForceFormat; + List->FileSystemCount = 1; + if (ForceFormat) { - List->CurrentFileSystem = ForceFileSystem; + List->CurrentFileSystem = ForceFileSystem; } - else + else { - List->FileSystemCount++; - List->CurrentFileSystem = FsKeep; + List->FileSystemCount++; + List->CurrentFileSystem = FsKeep; } - return List; + return List; } - VOID -DestroyFileSystemList (PFILE_SYSTEM_LIST List) +DestroyFileSystemList( + IN PFILE_SYSTEM_LIST List) { - RtlFreeHeap (ProcessHeap, 0, List); + RtlFreeHeap(ProcessHeap, 0, List); } - VOID -DrawFileSystemList (PFILE_SYSTEM_LIST List) +DrawFileSystemList( + IN PFILE_SYSTEM_LIST List) { - COORD coPos; - ULONG Written; - ULONG Index; + COORD coPos; + ULONG Written; + ULONG Index; - Index = 0; + Index = 0; - coPos.X = List->Left; - coPos.Y = List->Top + Index; - FillConsoleOutputAttribute (StdOutput, - FOREGROUND_WHITE | BACKGROUND_BLUE, - 50, - coPos, - &Written); - FillConsoleOutputCharacterA (StdOutput, - ' ', - 50, - coPos, - &Written); + coPos.X = List->Left; + coPos.Y = List->Top + Index; + FillConsoleOutputAttribute(StdOutput, + FOREGROUND_WHITE | BACKGROUND_BLUE, + 50, + coPos, + &Written); + FillConsoleOutputCharacterA(StdOutput, + ' ', + 50, + coPos, + &Written); - if (List->CurrentFileSystem == FsFat) + if (List->CurrentFileSystem == FsFat) { - CONSOLE_SetInvertedTextXY (List->Left, - List->Top + Index, - " Format partition as FAT file system "); + CONSOLE_SetInvertedTextXY(List->Left, + List->Top + Index, + " Format partition as FAT file system "); } - else + else { - CONSOLE_SetTextXY (List->Left, - List->Top + Index, - " Format partition as FAT file system "); + CONSOLE_SetTextXY(List->Left, + List->Top + Index, + " Format partition as FAT file system "); } - Index++; + Index++; - if (List->ForceFormat == FALSE) + if (List->ForceFormat == FALSE) { - coPos.X = List->Left; - coPos.Y = List->Top + Index; - FillConsoleOutputAttribute (StdOutput, - FOREGROUND_WHITE | BACKGROUND_BLUE, - 50, - coPos, - &Written); - FillConsoleOutputCharacterA (StdOutput, - ' ', - 50, - coPos, - &Written); + coPos.X = List->Left; + coPos.Y = List->Top + Index; + FillConsoleOutputAttribute(StdOutput, + FOREGROUND_WHITE | BACKGROUND_BLUE, + 50, + coPos, + &Written); + FillConsoleOutputCharacterA(StdOutput, + ' ', + 50, + coPos, + &Written); - if (List->CurrentFileSystem == FsKeep) - { - CONSOLE_SetInvertedTextXY (List->Left, - List->Top + Index, - " Keep current file system (no changes) "); - } - else - { - CONSOLE_SetTextXY (List->Left, - List->Top + Index, - " Keep current file system (no changes) "); - } + if (List->CurrentFileSystem == FsKeep) + { + CONSOLE_SetInvertedTextXY(List->Left, + List->Top + Index, + " Keep current file system (no changes) "); + } + else + { + CONSOLE_SetTextXY(List->Left, + List->Top + Index, + " Keep current file system (no changes) "); + } } } - VOID -ScrollDownFileSystemList (PFILE_SYSTEM_LIST List) +ScrollDownFileSystemList( + IN PFILE_SYSTEM_LIST List) { - if ((ULONG) List->CurrentFileSystem < List->FileSystemCount - 1) + if ((ULONG)List->CurrentFileSystem < List->FileSystemCount - 1) { - List->CurrentFileSystem++; - DrawFileSystemList (List); + List->CurrentFileSystem++; + DrawFileSystemList(List); } } - VOID -ScrollUpFileSystemList (PFILE_SYSTEM_LIST List) +ScrollUpFileSystemList( + IN PFILE_SYSTEM_LIST List) { - if ((ULONG) List->CurrentFileSystem > 0) + if ((ULONG)List->CurrentFileSystem > 0) { - List->CurrentFileSystem--; - DrawFileSystemList (List); + List->CurrentFileSystem--; + DrawFileSystemList(List); } } diff --git a/reactos/base/setup/usetup/fslist.h b/reactos/base/setup/usetup/fslist.h index 94eda71da12..98c0463c8e9 100644 --- a/reactos/base/setup/usetup/fslist.h +++ b/reactos/base/setup/usetup/fslist.h @@ -45,22 +45,27 @@ typedef struct _FILE_SYSTEM_LIST PFILE_SYSTEM_LIST -CreateFileSystemList (SHORT Left, - SHORT Top, - BOOLEAN ForceFormat, - FILE_SYSTEM ForceFileSystem); +CreateFileSystemList( + IN SHORT Left, + IN SHORT Top, + IN BOOLEAN ForceFormat, + IN FILE_SYSTEM ForceFileSystem); VOID -DestroyFileSystemList (PFILE_SYSTEM_LIST List); +DestroyFileSystemList( + IN PFILE_SYSTEM_LIST List); VOID -DrawFileSystemList (PFILE_SYSTEM_LIST List); +DrawFileSystemList( + IN PFILE_SYSTEM_LIST List); VOID -ScrollDownFileSystemList (PFILE_SYSTEM_LIST List); +ScrollDownFileSystemList( + IN PFILE_SYSTEM_LIST List); VOID -ScrollUpFileSystemList (PFILE_SYSTEM_LIST List); +ScrollUpFileSystemList( + IN PFILE_SYSTEM_LIST List); #endif /* __FSLIST_H__ */ From 7d80cdabff7b4b7e7b2d4bb0b0208d7c6cd13d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 20:57:02 +0000 Subject: [PATCH 062/488] Add ufat.dll and the optional ufatx.dll (to be added later to repository) svn path=/trunk/; revision=23971 --- reactos/boot/bootdata/packages/reactos.dff | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index ca0c724416c..00e212933cf 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -141,7 +141,7 @@ dll\keyboard\kbdur\kbdur.dll 1 dll\keyboard\kbdus\kbdus.dll 1 dll\keyboard\kbdpo\kbdpo.dll 1 -dll\ntdll\ntdll.dll 1 +dll\ntdll\ntdll.dll 1 dll\win32\advapi32\advapi32.dll 1 dll\win32\advpack\advpack.dll 1 @@ -213,6 +213,8 @@ dll\win32\shlwapi\shlwapi.dll 1 dll\win32\smdll\smdll.dll 1 dll\win32\syssetup\syssetup.dll 1 dll\win32\twain_32\twain_32.dll 1 +dll\win32\ufat\ufat.dll 1 +dll\win32\ufatx\ufatx.dll 1 optional dll\win32\urlmon\urlmon.dll 1 dll\win32\user32\user32.dll 1 dll\win32\userenv\userenv.dll 1 @@ -274,8 +276,8 @@ drivers\video\videoprt\videoprt.sys 2 ; Media media\fonts\DejaVuSans.ttf 3 -media\fonts\DejaVuSans-Bold.ttf 3 -media\fonts\DejaVuSans-BoldOblique.ttf 3 +media\fonts\DejaVuSans-Bold.ttf 3 +media\fonts\DejaVuSans-BoldOblique.ttf 3 media\fonts\DejaVuSansCondensed.ttf 3 media\fonts\DejaVuSansCondensed-Bold.ttf 3 media\fonts\DejaVuSansCondensed-Oblique.ttf 3 @@ -284,14 +286,14 @@ media\fonts\DejaVuSansMono.ttf 3 media\fonts\DejaVuSansMono-Bold.ttf 3 media\fonts\DejaVuSansMono-BoldOblique.ttf 3 media\fonts\DejaVuSansMono-Oblique.ttf 3 -media\fonts\DejaVuSans-Oblique.ttf 3 +media\fonts\DejaVuSans-Oblique.ttf 3 media\fonts\DejaVuSerif.ttf 3 media\fonts\DejaVuSerif-Bold.ttf 3 media\fonts\DejaVuSerif-BoldOblique.ttf 3 media\fonts\DejaVuSerifCondensed.ttf 3 media\fonts\DejaVuSerifCondensed-Bold.ttf 3 -media\fonts\DejaVuSerifCondensed-BoldOblique.ttf 3 -media\fonts\DejaVuSerifCondensed-Oblique.ttf 3 +media\fonts\DejaVuSerifCondensed-BoldOblique.ttf 3 +media\fonts\DejaVuSerifCondensed-Oblique.ttf 3 media\fonts\DejaVuSerif-Oblique.ttf 3 media\fonts\c0419bt_.ttf 3 media\fonts\c0582bt_.ttf 3 From 254f6b62acbd7ce8f43621fbc7fbccfc637bb480 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 7 Sep 2006 21:36:15 +0000 Subject: [PATCH 063/488] - More MSVC fixes (down to 19 errors): - Header changes: fix FILE_LOCK_INFO, LARGE_MCB, BASE_MCB, MM_SYSTEMSIZE. - Remove many things in W32API which are incorrectly there (due to winnt being used by the win32api DDK). Defined them in the NDK instead, where appropriate (mostly definitions that are present in user-mode headers, but not kernel-mode headers). - Hacked the ERESOURCE functions to define a special ERESOURCE_XP type. This is necessary because ERESOURCE is an opaque-yet-exported structure, and its structure changed in Vista. - Removed support for IMAGE_SCN_TYPE_NO_LOAD. It is a reserved field and Windows does not "respect" it. (sections marked as no-load will still be loaded by NT). svn path=/trunk/; revision=23972 --- reactos/drivers/base/bootvid/bootvid.c | 2 +- reactos/drivers/base/bootvid/ntbootvid.h | 2 +- reactos/include/ddk/ntifs.h | 63 ++++++------------ reactos/include/ddk/winddk.h | 7 +- reactos/include/ndk/extypes.h | 42 +++++++++++- reactos/include/ndk/i386/ketypes.h | 9 +++ reactos/include/ndk/iotypes.h | 16 +++++ reactos/include/ndk/mmtypes.h | 51 +++++++++++---- reactos/include/ndk/psfuncs.h | 21 ++++++ reactos/include/ndk/pstypes.h | 11 +++- reactos/include/ndk/setypes.h | 31 +++++++++ reactos/include/psdk/winnt.h | 21 +++++- reactos/ntoskrnl/ex/resource.c | 71 +++++++++++++-------- reactos/ntoskrnl/fs/filelock.c | 10 +-- reactos/ntoskrnl/fs/mcb.c | 16 ++--- reactos/ntoskrnl/include/internal/i386/ke.h | 4 +- reactos/ntoskrnl/io/iomgr/driver.c | 3 - reactos/ntoskrnl/ke/clock.c | 12 ---- reactos/ntoskrnl/ke/i386/cpu.c | 18 +++++- reactos/ntoskrnl/ldr/loader.c | 10 ++- reactos/ntoskrnl/mm/marea.c | 4 +- reactos/ntoskrnl/mm/mminit.c | 4 +- reactos/ntoskrnl/mm/pool.c | 1 + reactos/ntoskrnl/mm/process.c | 2 +- reactos/ntoskrnl/mm/section.c | 20 ++++-- reactos/ntoskrnl/ntoskrnl.def | 1 - 26 files changed, 314 insertions(+), 138 deletions(-) diff --git a/reactos/drivers/base/bootvid/bootvid.c b/reactos/drivers/base/bootvid/bootvid.c index 62cfad382f9..5b44fe43b0f 100644 --- a/reactos/drivers/base/bootvid/bootvid.c +++ b/reactos/drivers/base/bootvid/bootvid.c @@ -225,7 +225,7 @@ InbvInitVGAMode(VOID) } -static BOOL STDCALL +static BOOLEAN STDCALL VidResetDisplay(VOID) { /* diff --git a/reactos/drivers/base/bootvid/ntbootvid.h b/reactos/drivers/base/bootvid/ntbootvid.h index 199a0201f6a..ab441542bfb 100644 --- a/reactos/drivers/base/bootvid/ntbootvid.h +++ b/reactos/drivers/base/bootvid/ntbootvid.h @@ -9,5 +9,5 @@ typedef struct { - BOOL (STDCALL *ResetDisplay)(VOID); + BOOLEAN (NTAPI *ResetDisplay)(VOID); } NTBOOTVID_FUNCTION_TABLE; diff --git a/reactos/include/ddk/ntifs.h b/reactos/include/ddk/ntifs.h index 5cfec2d5d94..6e77057acf7 100644 --- a/reactos/include/ddk/ntifs.h +++ b/reactos/include/ddk/ntifs.h @@ -272,11 +272,7 @@ extern LARGE_INTEGER IoOtherTransferCount; #define IO_ATTACH_DEVICE 0x0400 #define IO_ATTACH_DEVICE_API 0x80000000 -/* also in winnt.h */ -#define IO_COMPLETION_QUERY_STATE 0x0001 -#define IO_COMPLETION_MODIFY_STATE 0x0002 -#define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) -/* end winnt.h */ + #define IO_FILE_OBJECT_NON_PAGED_POOL_CHARGE 64 #define IO_FILE_OBJECT_PAGED_POOL_CHARGE 1024 @@ -297,9 +293,7 @@ extern LARGE_INTEGER IoOtherTransferCount; #define MAP_PROCESS 1L #define MAP_SYSTEM 2L #define MEM_DOS_LIM 0x40000000 -/* also in winnt.h */ -#define MEM_IMAGE SEC_IMAGE -/* end winnt.h */ + #define OB_TYPE_TYPE 1 #define OB_TYPE_DIRECTORY 2 #define OB_TYPE_SYMBOLIC_LINK 3 @@ -332,15 +326,7 @@ extern LARGE_INTEGER IoOtherTransferCount; #define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE 1 #define RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING 2 -/* also in winnt.h */ #define SEC_BASED 0x00200000 -#define SEC_NO_CHANGE 0x00400000 -#define SEC_FILE 0x00800000 -#define SEC_IMAGE 0x01000000 -#define SEC_VLM 0x02000000 -#define SEC_RESERVE 0x04000000 -#define SEC_COMMIT 0x08000000 -#define SEC_NOCACHE 0x10000000 #define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1} #define SECURITY_WORLD_RID (0x00000000L) @@ -921,14 +907,15 @@ typedef struct _FILE_LINK_INFORMATION { WCHAR FileName[1]; } FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION; -typedef struct _FILE_LOCK_INFO { - LARGE_INTEGER StartingByte; - LARGE_INTEGER Length; - BOOLEAN ExclusiveLock; - ULONG Key; - PFILE_OBJECT FileObject; - PEPROCESS Process; - LARGE_INTEGER EndingByte; +typedef struct _FILE_LOCK_INFO +{ + LARGE_INTEGER StartingByte; + LARGE_INTEGER Length; + BOOLEAN ExclusiveLock; + ULONG Key; + PFILE_OBJECT FileObject; + PVOID ProcessId; + LARGE_INTEGER EndingByte; } FILE_LOCK_INFO, *PFILE_LOCK_INFO; /* raw internal file lock struct returned from FsRtlGetNextFileLock */ @@ -1227,25 +1214,21 @@ typedef struct _BASE_MCB { ULONG MaximumPairCount; ULONG PairCount; - POOL_TYPE PoolType; + USHORT PoolType; + USHORT Flags; PVOID Mapping; -} BASE_MCB; -typedef BASE_MCB *PBASE_MCB; +} BASE_MCB, *PBASE_MCB; -typedef struct _LARGE_MCB { - PFAST_MUTEX FastMutex; - ULONG MaximumPairCount; - ULONG PairCount; - POOL_TYPE PoolType; - PVOID Mapping; -} LARGE_MCB; -typedef LARGE_MCB *PLARGE_MCB; +typedef struct _LARGE_MCB +{ + PKGUARDED_MUTEX GuardedMutex; + BASE_MCB BaseMcb; +} LARGE_MCB, *PLARGE_MCB; -typedef struct _MCB +typedef struct _MCB { LARGE_MCB DummyFieldThatSizesThisStructureCorrectly; -} MCB; -typedef MCB *PMCB; +} MCB, *PMCB; typedef struct _GENERATE_NAME_CONTEXT { USHORT Checksum; @@ -1268,10 +1251,6 @@ typedef struct _GET_RETRIEVAL_DESCRIPTOR { MAPPING_PAIR Pair[1]; } GET_RETRIEVAL_DESCRIPTOR, *PGET_RETRIEVAL_DESCRIPTOR; -typedef struct _IO_COMPLETION_BASIC_INFORMATION { - LONG Depth; -} IO_COMPLETION_BASIC_INFORMATION, *PIO_COMPLETION_BASIC_INFORMATION; - typedef struct _KQUEUE { DISPATCHER_HEADER Header; LIST_ENTRY EntryListHead; diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 1c11651c97d..8bd053379a9 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -397,7 +397,6 @@ extern POBJECT_TYPE NTSYSAPI IoDriverObjectType; extern POBJECT_TYPE NTSYSAPI IoFileObjectType; extern POBJECT_TYPE NTSYSAPI PsThreadType; extern POBJECT_TYPE NTSYSAPI LpcPortObjectType; -extern POBJECT_TYPE NTSYSAPI MmSectionObjectType; extern POBJECT_TYPE NTSYSAPI SeTokenObjectType; #if (NTDDI_VERSION >= NTDDI_LONGHORN) @@ -4627,7 +4626,7 @@ typedef enum _MM_SYSTEM_SIZE { MmSmallSystem, MmMediumSystem, MmLargeSystem -} MM_SYSTEM_SIZE; +} MM_SYSTEMSIZE; typedef struct _OBJECT_HANDLE_INFORMATION { ULONG HandleAttributes; @@ -5114,7 +5113,6 @@ typedef ULONG PFN_NUMBER, *PPFN_NUMBER; #define CLOCK1_LEVEL 28 #define CLOCK2_LEVEL 28 #define IPI_LEVEL 29 -#define SYNCH_LEVEL (IPI_LEVEL-1) #define POWER_LEVEL 30 #define HIGH_LEVEL 31 @@ -9466,7 +9464,7 @@ MmProbeAndLockPages( IN LOCK_OPERATION Operation); NTOSAPI -MM_SYSTEM_SIZE +MM_SYSTEMSIZE DDKAPI MmQuerySystemSize( VOID); @@ -10246,7 +10244,6 @@ ZwSetValueKey( /* [Nt|Zw]MapViewOfSection.InheritDisposition constants */ #define AT_EXTENDABLE_FILE 0x00002000 -#define SEC_NO_CHANGE 0x00400000 #define AT_RESERVED 0x20000000 #define AT_ROUND_TO_PAGE 0x40000000 diff --git a/reactos/include/ndk/extypes.h b/reactos/include/ndk/extypes.h index b94c5ee5c4c..30437447db8 100644 --- a/reactos/include/ndk/extypes.h +++ b/reactos/include/ndk/extypes.h @@ -92,9 +92,18 @@ extern ULONG NTSYSAPI NtBuildNumber; #define EVENT_QUERY_STATE 0x0001 // -// Semaphore Object Acess Masks +// Semaphore Object Access Masks // #define SEMAPHORE_QUERY_STATE 0x0001 +#else + +// +// Mutant Object Access Masks +// +#define MUTANT_QUERY_STATE 0x0001 +#define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ + SYNCHRONIZE | \ + MUTANT_QUERY_STATE) #endif // @@ -343,6 +352,29 @@ NTSTATUS #else +// +// Compatibility with Windows XP Drivers using ERESOURCE +// +typedef struct _ERESOURCE_XP +{ + LIST_ENTRY SystemResourcesList; + POWNER_ENTRY OwnerTable; + SHORT ActiveCount; + USHORT Flag; + PKSEMAPHORE SharedWaiters; + PKEVENT ExclusiveWaiters; + OWNER_ENTRY OwnerThreads[2]; + ULONG ContentionCount; + USHORT NumberOfSharedWaiters; + USHORT NumberOfExclusiveWaiters; + union + { + PVOID Address; + ULONG_PTR CreatorBackTraceIndex; + }; + KSPIN_LOCK SpinLock; +} ERESOURCE_XP, *PERESOURCE_XP; + // // Executive Work Queue Structures // @@ -519,6 +551,14 @@ typedef struct _HANDLE_TABLE_ENTRY }; } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; +// +// FIXME +// +#ifdef _REACTOS_ +#undef NTDDI_VERSION +#define NTDDI_VERSION NTDDI_WIN2K +#endif + typedef struct _HANDLE_TABLE { #if (NTDDI_VERSION >= NTDDI_WINXP) diff --git a/reactos/include/ndk/i386/ketypes.h b/reactos/include/ndk/i386/ketypes.h index 0f95e500934..3f10f732cb3 100644 --- a/reactos/include/ndk/i386/ketypes.h +++ b/reactos/include/ndk/i386/ketypes.h @@ -106,6 +106,15 @@ Author: // #define KSEG0_BASE 0x80000000 +// +// Synchronization-level IRQL +// +#if defined(NT_UP) +#define SYNCH_LEVEL DISPATCH_LEVEL +#else +#define SYNCH_LEVEL (IPI_LEVEL - 1) +#endif + // // Macro to get current KPRCB // diff --git a/reactos/include/ndk/iotypes.h b/reactos/include/ndk/iotypes.h index de2034cf23b..54644305983 100644 --- a/reactos/include/ndk/iotypes.h +++ b/reactos/include/ndk/iotypes.h @@ -27,7 +27,15 @@ Author: typedef PVOID PFS_FILTER_CALLBACKS; #endif +// +// I/O Completion Access Rights +// +#define IO_COMPLETION_QUERY_STATE 0x0001 #ifndef NTOS_MODE_USER +#define IO_COMPLETION_MODIFY_STATE 0x0002 +#define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ + SYNCHRONIZE | \ + 0x3) // // Kernel Exported Object Types @@ -649,6 +657,14 @@ typedef struct _IO_ERROR_LOG_MESSAGE #endif +// +// I/O Completion Information structures +// +typedef struct _IO_COMPLETION_BASIC_INFORMATION +{ + LONG Depth; +} IO_COMPLETION_BASIC_INFORMATION, *PIO_COMPLETION_BASIC_INFORMATION; + // // Parameters for NtCreateMailslotFile/NtCreateNamedPipeFile // diff --git a/reactos/include/ndk/mmtypes.h b/reactos/include/ndk/mmtypes.h index 3ff541be0d5..f440545c83e 100644 --- a/reactos/include/ndk/mmtypes.h +++ b/reactos/include/ndk/mmtypes.h @@ -28,27 +28,50 @@ Author: // // Page-Rounding Macros // -#define PAGE_ROUND_DOWN(x) (((ULONG_PTR)x)&(~(PAGE_SIZE-1))) -#define PAGE_ROUND_UP(x) \ - ( (((ULONG_PTR)x)%PAGE_SIZE) ? ((((ULONG_PTR)x)&(~(PAGE_SIZE-1)))+PAGE_SIZE) : ((ULONG_PTR)x) ) +#define PAGE_ROUND_DOWN(x) \ + (((ULONG_PTR)x)&(~(PAGE_SIZE-1))) +#define PAGE_ROUND_UP(x) \ + ( (((ULONG_PTR)x)%PAGE_SIZE) ? \ + ((((ULONG_PTR)x)&(~(PAGE_SIZE-1)))+PAGE_SIZE) : \ + ((ULONG_PTR)x) ) #ifdef NTOS_MODE_USER -#define ROUND_TO_PAGES(Size) (((ULONG_PTR)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) +#define ROUND_TO_PAGES(Size) \ + (((ULONG_PTR)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) #endif -#define ROUND_TO_ALLOCATION_GRANULARITY(Size) (((ULONG_PTR)(Size) + MM_ALLOCATION_GRANULARITY - 1) \ +#define ROUND_TO_ALLOCATION_GRANULARITY(Size) \ + (((ULONG_PTR)(Size) + MM_ALLOCATION_GRANULARITY - 1) \ & ~(MM_ALLOCATION_GRANULARITY - 1)) // // Macro for generating pool tags // -#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) +#define TAG(A, B, C, D) \ + (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) -#ifdef NTOS_MODE_USER +#ifndef NTOS_MODE_USER + +// +// Virtual Memory Flags +// +#define MEM_WRITE_WATCH 0x200000 +#define MEM_PHYSICAL 0x400000 +#define MEM_ROTATE 0x800000 +#define MEM_IMAGE SEC_IMAGE // // Section Flags for NtCreateSection // -#define SEC_BASED 0x00200000 -#define SEC_NO_CHANGE 0x00400000 +#define SEC_NO_CHANGE 0x400000 +#define SEC_FILE 0x800000 +#define SEC_IMAGE 0x1000000 +#define SEC_PROTECTED_IMAGE 0x2000000 +#define SEC_RESERVE 0x4000000 +#define SEC_COMMIT 0x8000000 +#define SEC_NOCACHE 0x10000000 +#define SEC_WRITECOMBINE 0x40000000 +#define SEC_LARGE_PAGES 0x80000000 +#else +#define SEC_BASED 0x200000 // // Section Inherit Flags for NtCreateSection @@ -583,11 +606,6 @@ typedef struct _MEMORY_BASIC_INFORMATION ULONG Type; } MEMORY_BASIC_INFORMATION,*PMEMORY_BASIC_INFORMATION; - -// -// Mm Global Variables -// - // // Default heap size values. For user mode, these values are copied to a new // process's PEB by the kernel in MmCreatePeb. In kernel mode, RtlCreateHeap @@ -601,6 +619,11 @@ extern SIZE_T MmHeapSegmentCommit; extern SIZE_T MmHeapDeCommitTotalFreeThreshold; extern SIZE_T MmHeapDeCommitFreeBlockThreshold; +// +// Section Object Type +// +extern POBJECT_TYPE MmSectionObjectType; + #endif // !NTOS_MODE_USER #endif // _MMTYPES_H diff --git a/reactos/include/ndk/psfuncs.h b/reactos/include/ndk/psfuncs.h index 32656d136e3..a057c8dd48a 100644 --- a/reactos/include/ndk/psfuncs.h +++ b/reactos/include/ndk/psfuncs.h @@ -175,6 +175,27 @@ NtCreateThread( IN BOOLEAN CreateSuspended ); +#ifndef NTOS_MODE_USER +FORCEINLINE +PTEB +NtCurrentTeb(VOID) +{ +#ifndef __GNUC__ + return (PTEB)(ULONG_PTR)__readfsdword(0x18); +#else + struct _TEB *ret; + + __asm__ __volatile__ ( + "movl %%fs:0x18, %0\n" + : "=r" (ret) + : /* no inputs */ + ); + + return ret; +#endif +} +#endif + NTSYSCALLAPI NTSTATUS NTAPI diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index e19da5c6e5d..548102fcac5 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -119,10 +119,19 @@ extern NTSYSAPI POBJECT_TYPE PsProcessType; // #define TLS_EXPANSION_SLOTS 64 +#ifndef NTOS_MODE_USER + +// +// Thread Access Types +// +#define THREAD_QUERY_INFORMATION 0x0040 +#define THREAD_SET_THREAD_TOKEN 0x0080 +#define THREAD_IMPERSONATE 0x0100 +#define THREAD_DIRECT_IMPERSONATION 0x0200 + // // Process Access Types // -#ifndef NTOS_MODE_USER #define PROCESS_TERMINATE 0x0001 #define PROCESS_CREATE_THREAD 0x0002 #define PROCESS_SET_SESSIONID 0x0004 diff --git a/reactos/include/ndk/setypes.h b/reactos/include/ndk/setypes.h index 03563a74c16..6d36d7b22cb 100644 --- a/reactos/include/ndk/setypes.h +++ b/reactos/include/ndk/setypes.h @@ -59,8 +59,33 @@ Author: #define SE_CHANGE_NOTIFY_PRIVILEGE (23L) #define SE_REMOTE_SHUTDOWN_PRIVILEGE (24L) #define SE_MAX_WELL_KNOWN_PRIVILEGE (SE_REMOTE_SHUTDOWN_PRIVILEGE) + #else +// +// User and Group-related SID Attributes +// +#define SE_GROUP_MANDATORY 0x00000001 +#define SE_GROUP_ENABLED_BY_DEFAULT 0x00000002 +#define SE_GROUP_ENABLED 0x00000004 +#define SE_GROUP_OWNER 0x00000008 +#define SE_GROUP_USE_FOR_DENY_ONLY 0x00000010 +#define SE_GROUP_INTEGRITY 0x00000020 +#define SE_GROUP_INTEGRITY_ENABLED 0x00000040 +#define SE_GROUP_RESOURCE 0x20000000 +#define SE_GROUP_LOGON_ID 0xC0000000 + +#define SE_GROUP_VALID_ATTRIBUTES \ + (SE_GROUP_MANDATORY | \ + SE_GROUP_ENABLED_BY_DEFAULT | \ + SE_GROUP_ENABLED | \ + SE_GROUP_OWNER | \ + SE_GROUP_USE_FOR_DENY_ONLY | \ + SE_GROUP_LOGON_ID | \ + SE_GROUP_RESOURCE | \ + SE_GROUP_INTEGRITY | \ + SE_GROUP_INTEGRITY_ENABLED) + // // Audit and Policy Structures // @@ -142,5 +167,11 @@ typedef struct _AUX_DATA ULONG Reserved; } AUX_DATA, *PAUX_DATA; +// +// External SRM Data +// +extern PACL SePublicDefaultDacl; +extern PACL SeSystemDefaultDacl; + #endif #endif diff --git a/reactos/include/psdk/winnt.h b/reactos/include/psdk/winnt.h index af06ef9892c..c0901cce594 100644 --- a/reactos/include/psdk/winnt.h +++ b/reactos/include/psdk/winnt.h @@ -424,9 +424,12 @@ typedef DWORD FLONG; #define FILE_SUPPORTS_ENCRYPTION 0x00020000 #define FILE_NAMED_STREAMS 0x00040000 +/* FIXME: Oh how I wish, I wish the w32api DDK wouldn't include winnt.h... */ +#ifndef __NTDDK_H #define IO_COMPLETION_QUERY_STATE 0x0001 #define IO_COMPLETION_MODIFY_STATE 0x0002 #define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) +#endif /* end ntifs.h */ /* also in ddk/winddk.h */ @@ -457,10 +460,13 @@ typedef DWORD FLONG; #define THREAD_GET_CONTEXT 8 #define THREAD_SET_CONTEXT 16 #define THREAD_SET_INFORMATION 32 +/* FIXME: Oh how I wish, I wish the w32api DDK wouldn't include winnt.h... */ +#ifndef __NTDDK_H #define THREAD_QUERY_INFORMATION 64 #define THREAD_SET_THREAD_TOKEN 128 #define THREAD_IMPERSONATE 256 #define THREAD_DIRECT_IMPERSONATION 0x200 +#endif #define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3FF) #define THREAD_BASE_PRIORITY_LOWRT 15 #define THREAD_BASE_PRIORITY_MAX 2 @@ -468,8 +474,11 @@ typedef DWORD FLONG; #define THREAD_BASE_PRIORITY_IDLE (-15) #define EXCEPTION_NONCONTINUABLE 1 #define EXCEPTION_MAXIMUM_PARAMETERS 15 +/* FIXME: Oh how I wish, I wish the w32api DDK wouldn't include winnt.h... */ +#ifndef __NTDDK_H #define MUTANT_QUERY_STATE 0x0001 #define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|MUTANT_QUERY_STATE) +#endif #define TIMER_QUERY_STATE 0x0001 #define TIMER_MODIFY_STATE 0x0002 #define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|TIMER_QUERY_STATE|TIMER_MODIFY_STATE) @@ -654,6 +663,8 @@ typedef enum #define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege") #define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege") #define SE_CREATE_GLOBAL_NAME TEXT("SeCreateGlobalPrivilege") +/* FIXME: Oh how I wish, I wish the w32api DDK wouldn't include winnt.h... */ +#ifndef __NTDDK_H #define SE_GROUP_MANDATORY 1 #define SE_GROUP_ENABLED_BY_DEFAULT 2 #define SE_GROUP_ENABLED 4 @@ -661,6 +672,7 @@ typedef enum #define SE_GROUP_USE_FOR_DENY_ONLY 16 #define SE_GROUP_LOGON_ID 3221225472U #define SE_GROUP_RESOURCE 536870912 +#endif #define LANG_NEUTRAL 0x00 #define LANG_ARABIC 0x01 #define LANG_BULGARIAN 0x02 @@ -1005,9 +1017,9 @@ typedef enum #define MEM_WRITE_WATCH 0x200000 /* 98/Me */ #define MEM_PHYSICAL 0x400000 #define MEM_4MB_PAGES 0x80000000 -/* also in ddk/ntifs.h */ +/* FIXME: Oh how I wish, I wish the w32api DDK wouldn't include winnt.h... */ +#ifndef __NTDDK_H #define MEM_IMAGE SEC_IMAGE -#define SEC_BASED 0x00200000 #define SEC_NO_CHANGE 0x00400000 #define SEC_FILE 0x00800000 #define SEC_IMAGE 0x01000000 @@ -1015,7 +1027,7 @@ typedef enum #define SEC_RESERVE 0x04000000 #define SEC_COMMIT 0x08000000 #define SEC_NOCACHE 0x10000000 -/* end ntifs.h */ +#endif #define SECTION_EXTEND_SIZE 16 #define SECTION_MAP_READ 4 #define SECTION_MAP_WRITE 2 @@ -3772,6 +3784,8 @@ static __inline__ PVOID GetCurrentFiber(void) return ret; } +/* FIXME: Oh how I wish, I wish the w32api DDK wouldn't include winnt.h... */ +#ifndef __NTDDK_H static __inline__ struct _TEB * NtCurrentTeb(void) { struct _TEB *ret; @@ -3784,6 +3798,7 @@ static __inline__ struct _TEB * NtCurrentTeb(void) return ret; } +#endif #elif defined(__WATCOMC__) diff --git a/reactos/ntoskrnl/ex/resource.c b/reactos/ntoskrnl/ex/resource.c index ce3927ff33e..cdca8c1e981 100644 --- a/reactos/ntoskrnl/ex/resource.c +++ b/reactos/ntoskrnl/ex/resource.c @@ -57,7 +57,7 @@ BOOLEAN ExResourceStrict = FALSE; /* FIXME */ *--*/ VOID NTAPI -ExpVerifyResource(IN PERESOURCE Resource) +ExpVerifyResource(IN PERESOURCE_XP Resource) { /* Verify the resource data */ ASSERT((((ULONG_PTR)Resource) & (sizeof(ULONG_PTR) - 1)) == 0); @@ -94,7 +94,7 @@ ExpVerifyResource(IN PERESOURCE Resource) VOID NTAPI ExpCheckForApcsDisabled(IN BOOLEAN BreakIfTrue, - IN PERESOURCE Resource, + IN PERESOURCE_XP Resource, IN PETHREAD Thread) { /* Check if we should care and check if we should break */ @@ -156,7 +156,7 @@ ExpResourceInitialization(VOID) *--*/ VOID NTAPI -ExpAllocateExclusiveWaiterEvent(IN PERESOURCE Resource, +ExpAllocateExclusiveWaiterEvent(IN PERESOURCE_XP Resource, IN PKIRQL OldIrql) { PKEVENT Event; @@ -205,7 +205,7 @@ ExpAllocateExclusiveWaiterEvent(IN PERESOURCE Resource, *--*/ VOID NTAPI -ExpAllocateSharedWaiterSemaphore(IN PERESOURCE Resource, +ExpAllocateSharedWaiterSemaphore(IN PERESOURCE_XP Resource, IN PKIRQL OldIrql) { PKSEMAPHORE Semaphore; @@ -254,7 +254,7 @@ ExpAllocateSharedWaiterSemaphore(IN PERESOURCE Resource, *--*/ VOID NTAPI -ExpExpandResourceOwnerTable(IN PERESOURCE Resource, +ExpExpandResourceOwnerTable(IN PERESOURCE_XP Resource, IN PKIRQL OldIrql) { POWNER_ENTRY Owner, Table; @@ -354,7 +354,7 @@ ExpExpandResourceOwnerTable(IN PERESOURCE Resource, *--*/ POWNER_ENTRY FASTCALL -ExpFindFreeEntry(IN PERESOURCE Resource, +ExpFindFreeEntry(IN PERESOURCE_XP Resource, IN PKIRQL OldIrql) { POWNER_ENTRY Owner, Limit; @@ -440,7 +440,7 @@ ExpFindFreeEntry(IN PERESOURCE Resource, *--*/ POWNER_ENTRY FASTCALL -ExpFindEntryForThread(IN PERESOURCE Resource, +ExpFindEntryForThread(IN PERESOURCE_XP Resource, IN ERESOURCE_THREAD Thread, IN PKIRQL OldIrql) { @@ -598,7 +598,7 @@ ExpBoostOwnerThread(IN PKTHREAD Thread, *--*/ VOID FASTCALL -ExpWaitForResource(IN PERESOURCE Resource, +ExpWaitForResource(IN PERESOURCE_XP Resource, IN PVOID Object) { #if DBG @@ -767,12 +767,13 @@ ExpWaitForResource(IN PERESOURCE Resource, *--*/ BOOLEAN NTAPI -ExAcquireResourceExclusiveLite(PERESOURCE Resource, +ExAcquireResourceExclusiveLite(PERESOURCE resource, BOOLEAN Wait) { KIRQL OldIrql = PASSIVE_LEVEL; ERESOURCE_THREAD Thread; BOOLEAN Success; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; /* Sanity check */ ASSERT((Resource->Flag & ResourceNeverExclusive) == 0); @@ -883,12 +884,13 @@ TryAcquire: *--*/ BOOLEAN NTAPI -ExAcquireResourceSharedLite(PERESOURCE Resource, +ExAcquireResourceSharedLite(PERESOURCE resource, BOOLEAN Wait) { KIRQL OldIrql; ERESOURCE_THREAD Thread; POWNER_ENTRY Owner; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; /* Get the thread */ Thread = ExGetCurrentResourceThread(); @@ -1044,12 +1046,13 @@ TryAcquire: *--*/ BOOLEAN NTAPI -ExAcquireSharedStarveExclusive(PERESOURCE Resource, +ExAcquireSharedStarveExclusive(PERESOURCE resource, BOOLEAN Wait) { KIRQL OldIrql; ERESOURCE_THREAD Thread; POWNER_ENTRY Owner; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; /* Get the thread */ Thread = ExGetCurrentResourceThread(); @@ -1191,12 +1194,13 @@ TryAcquire: *--*/ BOOLEAN NTAPI -ExAcquireSharedWaitForExclusive(PERESOURCE Resource, +ExAcquireSharedWaitForExclusive(PERESOURCE resource, BOOLEAN Wait) { KIRQL OldIrql; ERESOURCE_THREAD Thread; POWNER_ENTRY Owner; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; /* Get the thread */ Thread = ExGetCurrentResourceThread(); @@ -1363,10 +1367,11 @@ TryAcquire: *--*/ VOID NTAPI -ExConvertExclusiveToSharedLite(PERESOURCE Resource) +ExConvertExclusiveToSharedLite(PERESOURCE resource) { ULONG OldWaiters; KIRQL OldIrql; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; DPRINT("ExConvertExclusiveToSharedLite(Resource 0x%p)\n", Resource); /* Lock the resource */ @@ -1418,9 +1423,10 @@ ExConvertExclusiveToSharedLite(PERESOURCE Resource) *--*/ NTSTATUS NTAPI -ExDeleteResourceLite(PERESOURCE Resource) +ExDeleteResourceLite(PERESOURCE resource) { KIRQL OldIrql; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; DPRINT("ExDeleteResourceLite(Resource 0x%p)\n", Resource); /* Sanity checks */ @@ -1464,9 +1470,10 @@ ExDeleteResourceLite(PERESOURCE Resource) *--*/ VOID NTAPI -ExDisableResourceBoostLite(PERESOURCE Resource) +ExDisableResourceBoostLite(PERESOURCE resource) { KIRQL OldIrql; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; /* Sanity check */ ExpVerifyResource(Resource); @@ -1498,8 +1505,10 @@ ExDisableResourceBoostLite(PERESOURCE Resource) *--*/ ULONG NTAPI -ExGetExclusiveWaiterCount(PERESOURCE Resource) +ExGetExclusiveWaiterCount(PERESOURCE resource) { + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; + /* Return the count */ return Resource->NumberOfExclusiveWaiters; } @@ -1521,8 +1530,10 @@ ExGetExclusiveWaiterCount(PERESOURCE Resource) *--*/ ULONG NTAPI -ExGetSharedWaiterCount(PERESOURCE Resource) +ExGetSharedWaiterCount(PERESOURCE resource) { + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; + /* Return the count */ return Resource->NumberOfSharedWaiters; } @@ -1545,12 +1556,13 @@ ExGetSharedWaiterCount(PERESOURCE Resource) *--*/ NTSTATUS NTAPI -ExInitializeResourceLite(PERESOURCE Resource) +ExInitializeResourceLite(PERESOURCE resource) { + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; DPRINT("ExInitializeResourceLite(Resource 0x%p)\n", Resource); /* Clear the structure */ - RtlZeroMemory(Resource, sizeof(ERESOURCE)); + RtlZeroMemory(Resource, sizeof(ERESOURCE_XP)); /* Initialize the lock */ KeInitializeSpinLock(&Resource->SpinLock); @@ -1582,10 +1594,11 @@ ExInitializeResourceLite(PERESOURCE Resource) *--*/ BOOLEAN NTAPI -ExIsResourceAcquiredExclusiveLite(PERESOURCE Resource) +ExIsResourceAcquiredExclusiveLite(PERESOURCE resource) { ERESOURCE_THREAD Thread = ExGetCurrentResourceThread(); BOOLEAN IsAcquired = FALSE; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; /* Sanity check */ ExpVerifyResource(Resource); @@ -1622,13 +1635,14 @@ ExIsResourceAcquiredExclusiveLite(PERESOURCE Resource) *--*/ ULONG NTAPI -ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource) +ExIsResourceAcquiredSharedLite(IN PERESOURCE resource) { ERESOURCE_THREAD Thread; ULONG i, Size; ULONG Count = 0; KIRQL OldIrql; POWNER_ENTRY Owner; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; /* Sanity check */ ExpVerifyResource(Resource); @@ -1719,12 +1733,13 @@ ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource) *--*/ NTSTATUS NTAPI -ExReinitializeResourceLite(PERESOURCE Resource) +ExReinitializeResourceLite(PERESOURCE resource) { PKEVENT Event; PKSEMAPHORE Semaphore; ULONG i, Size; POWNER_ENTRY Owner; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; /* Get the owner table */ Owner = Resource->OwnerTable; @@ -1784,12 +1799,13 @@ ExReinitializeResourceLite(PERESOURCE Resource) *--*/ VOID FASTCALL -ExReleaseResourceLite(PERESOURCE Resource) +ExReleaseResourceLite(PERESOURCE resource) { ERESOURCE_THREAD Thread; ULONG Count, i; KIRQL OldIrql; POWNER_ENTRY Owner, Limit; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; DPRINT("ExReleaseResourceLite: %p\n", Resource); /* Sanity check */ @@ -1973,13 +1989,14 @@ ExReleaseResourceLite(PERESOURCE Resource) *--*/ VOID NTAPI -ExReleaseResourceForThreadLite(PERESOURCE Resource, +ExReleaseResourceForThreadLite(PERESOURCE resource, ERESOURCE_THREAD Thread) { ULONG i; ULONG Count; KIRQL OldIrql; POWNER_ENTRY Owner; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; ASSERT(Thread != 0); DPRINT("ExReleaseResourceForThreadLite: %p\n", Resource); @@ -2164,12 +2181,13 @@ ExReleaseResourceForThreadLite(PERESOURCE Resource, *--*/ VOID NTAPI -ExSetResourceOwnerPointer(IN PERESOURCE Resource, +ExSetResourceOwnerPointer(IN PERESOURCE resource, IN PVOID OwnerPointer) { ERESOURCE_THREAD Thread; KIRQL OldIrql; POWNER_ENTRY Owner, ThisOwner; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; /* Sanity check */ ASSERT((OwnerPointer != 0) && (((ULONG_PTR)OwnerPointer & 3) == 3)); @@ -2242,11 +2260,12 @@ ExSetResourceOwnerPointer(IN PERESOURCE Resource, *--*/ BOOLEAN NTAPI -ExTryToAcquireResourceExclusiveLite(PERESOURCE Resource) +ExTryToAcquireResourceExclusiveLite(PERESOURCE resource) { ERESOURCE_THREAD Thread; KIRQL OldIrql; BOOLEAN Acquired = FALSE; + PERESOURCE_XP Resource = (PERESOURCE_XP)resource; DPRINT("ExTryToAcquireResourceExclusiveLite: %p\n", Resource); /* Sanity check */ diff --git a/reactos/ntoskrnl/fs/filelock.c b/reactos/ntoskrnl/fs/filelock.c index 048e8d7b651..61c94cf04cd 100644 --- a/reactos/ntoskrnl/fs/filelock.c +++ b/reactos/ntoskrnl/fs/filelock.c @@ -190,7 +190,7 @@ FsRtlpCheckLockForReadOrWriteAccess( //No write conflict if exclusive lock AND our lock if ((Read && !Granted->Lock.ExclusiveLock) || (Granted->Lock.ExclusiveLock && - Granted->Lock.Process == Process && + Granted->Lock.ProcessId == Process && Granted->Lock.FileObject == FileObject && Granted->Lock.Key == Key ) ) { @@ -382,7 +382,7 @@ FsRtlpFastUnlockAllByKey( LIST_FOR_EACH_SAFE(Granted, tmp, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry) { - if (Granted->Lock.Process == Process && + if (Granted->Lock.ProcessId == Process && Granted->Lock.FileObject == FileObject && (!UseKey || (UseKey && Granted->Lock.Key == Key)) ) { @@ -548,7 +548,7 @@ FsRtlpAddLock( Granted->Lock.ExclusiveLock = ExclusiveLock; Granted->Lock.Key = Key; Granted->Lock.FileObject = FileObject; - Granted->Lock.Process = Process; + Granted->Lock.ProcessId = Process; //ending offset Granted->Lock.EndingByte = EndOffset; Granted->UnlockContext = Context; @@ -693,7 +693,7 @@ FsRtlpUnlockSingle( //must be exact match if (FileOffset->QuadPart == Granted->Lock.StartingByte.QuadPart && Length->QuadPart == Granted->Lock.Length.QuadPart && - Granted->Lock.Process == Process && + Granted->Lock.ProcessId == Process && Granted->Lock.FileObject == FileObject && Granted->Lock.Key == Key) { @@ -799,7 +799,7 @@ FsRtlpDumpFileLocks( Granted->Lock.Length.QuadPart, Granted->Lock.EndingByte.QuadPart, Granted->Lock.Key, - Granted->Lock.Process, + Granted->Lock.ProcessId, Granted->Lock.FileObject ); diff --git a/reactos/ntoskrnl/fs/mcb.c b/reactos/ntoskrnl/fs/mcb.c index c5506e4e5ca..5f60d7cabbe 100644 --- a/reactos/ntoskrnl/fs/mcb.c +++ b/reactos/ntoskrnl/fs/mcb.c @@ -117,7 +117,7 @@ FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType) { UNIMPLEMENTED; - Mcb->PoolType = PoolType; + Mcb->BaseMcb.PoolType = PoolType; } /* @@ -179,11 +179,11 @@ FsRtlLookupPerStreamContextInternal(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, /* * @unimplemented */ -PVOID /* PFSRTL_PER_FILE_OBJECT_CONTEXT*/ +PFSRTL_PER_FILEOBJECT_CONTEXT NTAPI -FsRtlLookupPerFileObjectContext(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, - IN PVOID OwnerId OPTIONAL, - IN PVOID InstanceId OPTIONAL) +FsRtlLookupPerFileObjectContext(IN PFILE_OBJECT FileObject, + IN PVOID OwnerId OPTIONAL, + IN PVOID InstanceId OPTIONAL) { UNIMPLEMENTED; return FALSE; @@ -269,9 +269,9 @@ FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb) { ULONG NumberOfRuns; - ExAcquireFastMutex(Mcb->FastMutex); - NumberOfRuns = Mcb->PairCount; - ExReleaseFastMutex(Mcb->FastMutex); + KeAcquireGuardedMutex(Mcb->GuardedMutex); + NumberOfRuns = Mcb->BaseMcb.PairCount; + KeReleaseGuardedMutex(Mcb->GuardedMutex); return NumberOfRuns; } diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 430819fabe3..c1c7a6727e6 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -224,8 +224,8 @@ static inline void Ki386Cpuid(ULONG Op, PULONG Eax, PULONG Ebx, PULONG Ecx, PULO #elif defined(_MSC_VER) -#define Ke386DisableInterrupts() __asm cli -#define Ke386EnableInterrupts() __asm sti +#define Ke386DisableInterrupts() _cli() +#define Ke386EnableInterrupts() _sti() #define Ke386HaltProcessor() __asm hlt #define Ke386GetPageTableDirectory(X) \ __asm mov eax, cr3; \ diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index 243291567a6..690c57458ee 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -43,9 +43,6 @@ LdrProcessModule( #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, IopInitDriverImplementation) -#pragma alloc_text(INIT, IopDisplayLoadingMessage) -#pragma alloc_text(INIT, MiFreeBootDriverMemory) -#pragma alloc_text(INIT, IopInitializeBuiltinDriver) #endif diff --git a/reactos/ntoskrnl/ke/clock.c b/reactos/ntoskrnl/ke/clock.c index 1e4e5393afa..20b691c2a5a 100644 --- a/reactos/ntoskrnl/ke/clock.c +++ b/reactos/ntoskrnl/ke/clock.c @@ -208,18 +208,6 @@ KeSetTimeIncrement( KeMinimumIncrement = MinIncrement; } -/* - * @unimplemented - */ -VOID -FASTCALL -KeSetTimeUpdateNotifyRoutine( - IN PTIME_UPDATE_NOTIFY_ROUTINE NotifyRoutine - ) -{ - UNIMPLEMENTED; -} - /* * @implemented */ diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index e4462832c9e..83a2630cd79 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -654,7 +654,14 @@ KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save) if (!FpState) return STATUS_INSUFFICIENT_RESOURCES; *((PVOID *) Save) = FpState; +#ifdef __GNUC__ asm volatile("fnsave %0\n\t" : "=m" (*FpState)); +#else + __asm + { + fnsave [FpState] + }; +#endif KeGetCurrentThread()->DispatcherHeader.NpxIrql = KeGetCurrentIrql(); return STATUS_SUCCESS; @@ -668,8 +675,16 @@ KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save) ASSERT(KeGetCurrentThread()->DispatcherHeader.NpxIrql == KeGetCurrentIrql()); +#ifdef __GNUC__ asm volatile("fnclex\n\t"); asm volatile("frstor %0\n\t" : "=m" (*FpState)); +#else + __asm + { + fnclex + frstor [FpState] + }; +#endif ExFreePool(FpState); return STATUS_SUCCESS; @@ -688,8 +703,7 @@ Ki386SetProcessorFeatures(VOID) struct { KEY_VALUE_PARTIAL_INFORMATION Info; - UCHAR Buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, - Data[0]) + sizeof(ULONG)]; + UCHAR Buffer[20]; } ValueData; NTSTATUS Status; ULONG FastSystemCallDisable = 0; diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index b4b943c7af0..4e2cc3a9b8b 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -639,7 +639,10 @@ LdrLookupPageProtection ( for (Idx = 0; Idx < PEFileHeader->NumberOfSections && (!Write || !Execute); Idx++) { Characteristics = PESectionHeaders[Idx].Characteristics; - if (!(Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // + // This field is RESERVED and not respected by Windows + // + //if (!(Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { Length = max(PESectionHeaders[Idx].Misc.VirtualSize, PESectionHeaders[Idx].SizeOfRawData); BaseAddress = PESectionHeaders[Idx].VirtualAddress + (char*)DriverBase; @@ -736,7 +739,10 @@ LdrPEProcessModule( DriverSize = 0; for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++) { - if (!(PESectionHeaders[Idx].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // + // This field is RESERVED and not respected by Windows + // + //if (!(PESectionHeaders[Idx].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { CurrentSize = PESectionHeaders[Idx].VirtualAddress + PESectionHeaders[Idx].Misc.VirtualSize; DriverSize = max(DriverSize, CurrentSize); diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index 97921c83ea0..cad4fe89283 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -947,9 +947,9 @@ MmCreateMemoryArea(PMADDRESS_SPACE AddressSpace, PMEMORY_AREA MemoryArea; DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %p, " - "*BaseAddress %p, Length %p, Attributes %x, TopDown: %x, " + "*BaseAddress %p, Length %p, AllocationFlags %x, " "FixedAddress %x, Result %p)\n", - Type, BaseAddress, *BaseAddress, Length, Attributes, TopDown, + Type, BaseAddress, *BaseAddress, Length, AllocationFlags, FixedAddress, Result); MmVerifyMemoryAreas(AddressSpace); diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 69a4a56b0e4..0e64b2bc83a 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -29,7 +29,7 @@ extern unsigned int _bss_end__; static BOOLEAN IsThisAnNtAsSystem = FALSE; -MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem; +MM_SYSTEMSIZE MmSystemSize = MmSmallSystem; PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress; @@ -58,7 +58,7 @@ BOOLEAN STDCALL MmIsThisAnNtAsSystem(VOID) /* * @implemented */ -MM_SYSTEM_SIZE STDCALL MmQuerySystemSize(VOID) +MM_SYSTEMSIZE STDCALL MmQuerySystemSize(VOID) { return(MmSystemSize); } diff --git a/reactos/ntoskrnl/mm/pool.c b/reactos/ntoskrnl/mm/pool.c index 28afe5b4c7f..7e25ca30920 100644 --- a/reactos/ntoskrnl/mm/pool.c +++ b/reactos/ntoskrnl/mm/pool.c @@ -213,6 +213,7 @@ ExAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, /* * @implemented */ +#undef ExFreePool VOID STDCALL ExFreePool(IN PVOID Block) { diff --git a/reactos/ntoskrnl/mm/process.c b/reactos/ntoskrnl/mm/process.c index 200d98487ad..5be30d7e250 100644 --- a/reactos/ntoskrnl/mm/process.c +++ b/reactos/ntoskrnl/mm/process.c @@ -17,7 +17,7 @@ extern ULONG NtMajorVersion; extern ULONG NtMinorVersion; extern ULONG NtOSCSDVersion; extern ULONG NtGlobalFlag; -extern MM_SYSTEM_SIZE MmSystemSize; +extern MM_SYSTEMSIZE MmSystemSize; #define MM_HIGHEST_VAD_ADDRESS \ (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE)) diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index d6e5dbdd4b2..67cf0bb0a6e 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -3994,7 +3994,10 @@ MmUnmapViewOfSection(PEPROCESS Process, * and calculate the image base address */ for (i = 0; i < NrSegments; i++) { - if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // + // This field is RESERVED and not respected by Windows + // + //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { if (Segment == &SectionSegments[i]) { @@ -4010,7 +4013,10 @@ MmUnmapViewOfSection(PEPROCESS Process, for (i = 0; i < NrSegments; i++) { - if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // + // This field is RESERVED and not respected by Windows + // + //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { PVOID SBaseAddress = (PVOID) ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress); @@ -4476,7 +4482,10 @@ MmMapViewOfSection(IN PVOID SectionObject, ImageSize = 0; for (i = 0; i < NrSegments; i++) { - if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // + // This field is RESERVED and not respected by Windows + // + //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { ULONG_PTR MaxExtent; MaxExtent = (ULONG_PTR)SectionSegments[i].VirtualAddress + @@ -4506,7 +4515,10 @@ MmMapViewOfSection(IN PVOID SectionObject, for (i = 0; i < NrSegments; i++) { - if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + // + // This field is RESERVED and not respected by Windows + // + //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { PVOID SBaseAddress = (PVOID) ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress); diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 952686596cb..849637f97cb 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -638,7 +638,6 @@ KeSetTargetProcessorDpc@8 KeSetTimeIncrement@8 KeSetTimer@16 KeSetTimerEx@20 -@KeSetTimeUpdateNotifyRoutine@4 KeStackAttachProcess@8 KeSynchronizeExecution@12 KeTerminateThread@4 From e6fd23de2cbb9a796d9918efadb23001ac63821c Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 7 Sep 2006 22:38:06 +0000 Subject: [PATCH 064/488] - 1>Build Time 0:04 1>ReactOS Kernel - 0 error(s), 253 warning(s) - Add winerror.h to ps/win32.c so it can get the Win32 error definition it needs (winerror.h doesn't add any other nasty win32 headers, so this isn't really a header policy violation). - Fix prototypes of KdEnableDebugger and KdDisableDebugger. - Write one of the cleanest and most ingenious hacks I've ever come up with it, which bypasses the incompatibility of hard-coded WDK externals. svn path=/trunk/; revision=23973 --- reactos/include/ddk/winddk.h | 13 +++++----- reactos/include/ndk/i386/ketypes.h | 34 +++++++++++++------------- reactos/lib/rtl/bitmap.c | 1 + reactos/lib/rtl/swprintf.c | 6 ++--- reactos/ntoskrnl/cm/cm.h | 6 ----- reactos/ntoskrnl/cm/ntfunc.c | 2 +- reactos/ntoskrnl/include/internal/io.h | 2 ++ reactos/ntoskrnl/include/internal/kd.h | 2 ++ reactos/ntoskrnl/include/internal/ps.h | 1 + reactos/ntoskrnl/include/ntoskrnl.h | 26 ++++++++++++++++++-- reactos/ntoskrnl/kd/kdmain.c | 10 ++++++-- reactos/ntoskrnl/ntoskrnl.def | 12 ++++----- reactos/ntoskrnl/ntoskrnl.rbuild | 1 + reactos/ntoskrnl/ps/win32.c | 1 + 14 files changed, 74 insertions(+), 43 deletions(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 8bd053379a9..a29a81703c9 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -4876,10 +4876,11 @@ typedef enum _REG_NOTIFY_CLASS } REG_NOTIFY_CLASS, *PREG_NOTIFY_CLASS; typedef NTSTATUS -(DDKAPI *PEX_CALLBACK_FUNCTION)( - IN PVOID CallbackContext, - IN REG_NOTIFY_CLASS Argument1, - IN PVOID Argument2); +(NTAPI *PEX_CALLBACK_FUNCTION)( + IN PVOID CallbackContext, + IN PVOID Argument1, + IN PVOID Argument2 +); typedef struct _REG_DELETE_KEY_INFORMATION { @@ -10451,13 +10452,13 @@ WmiTraceMessageVa( /** Kernel debugger routines **/ NTOSAPI -VOID +NTSTATUS DDKAPI KdDisableDebugger( VOID); NTOSAPI -VOID +NTSTATUS DDKAPI KdEnableDebugger( VOID); diff --git a/reactos/include/ndk/i386/ketypes.h b/reactos/include/ndk/i386/ketypes.h index 3f10f732cb3..484cb767e81 100644 --- a/reactos/include/ndk/i386/ketypes.h +++ b/reactos/include/ndk/i386/ketypes.h @@ -115,23 +115,6 @@ Author: #define SYNCH_LEVEL (IPI_LEVEL - 1) #endif -// -// Macro to get current KPRCB -// -#ifndef __GNUC__ // fixme -FORCEINLINE -struct _KPRCB * -KeGetCurrentPrcb(VOID) -{ - return (struct _KPRCB *)(ULONG_PTR)__readfsdword(FIELD_OFFSET(KPCR, Prcb)); -} - -// -// Macro to get current previous mode -// -#define KeGetPreviousMode ExGetPreviousMode -#endif - // // Trap Frame Definition // @@ -282,6 +265,23 @@ typedef struct _DESCRIPTOR #ifndef NTOS_MODE_USER +// +// Macro to get current KPRCB +// +#ifndef __GNUC__ // fixme +FORCEINLINE +struct _KPRCB * +KeGetCurrentPrcb(VOID) +{ + return (struct _KPRCB *)(ULONG_PTR)__readfsdword(FIELD_OFFSET(KPCR, Prcb)); +} + +// +// Macro to get current previous mode +// +#define KeGetPreviousMode ExGetPreviousMode +#endif + // // FN/FX (FPU) Save Area Structures // diff --git a/reactos/lib/rtl/bitmap.c b/reactos/lib/rtl/bitmap.c index 584bfcf1660..98514ae85fd 100644 --- a/reactos/lib/rtl/bitmap.c +++ b/reactos/lib/rtl/bitmap.c @@ -36,6 +36,7 @@ static const signed char NTDLL_mostSignificant[16] = { static int +__cdecl NTDLL_RunSortFn(const void *lhs, const void *rhs) { diff --git a/reactos/lib/rtl/swprintf.c b/reactos/lib/rtl/swprintf.c index f8d35052555..8d8ab1afbd8 100644 --- a/reactos/lib/rtl/swprintf.c +++ b/reactos/lib/rtl/swprintf.c @@ -383,7 +383,7 @@ stringw(wchar_t* buf, wchar_t* end, const wchar_t* sw, int len, int field_width, /* * @implemented */ -int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) +int __cdecl _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args) { int len; unsigned long long num; @@ -726,7 +726,7 @@ int swprintf(wchar_t *buf, const wchar_t *fmt, ...) /* * @implemented */ -int _snwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, ...) +int __cdecl _snwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, ...) { va_list args; int i; @@ -741,7 +741,7 @@ int _snwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, ...) /* * @implemented */ -int vswprintf(wchar_t *buf, const wchar_t *fmt, va_list args) +int __cdecl vswprintf(wchar_t *buf, const wchar_t *fmt, va_list args) { return _vsnwprintf(buf,MAXLONG,fmt,args); } diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 8af8576539a..008048fe92e 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -116,12 +116,6 @@ extern ERESOURCE CmiRegistryLock; /* Registry Callback Function */ -typedef NTSTATUS (STDCALL *PEX_CALLBACK_FUNCTION ) ( - IN PVOID CallbackContext, - IN REG_NOTIFY_CLASS Argument1, - IN PVOID Argument2 - ); - typedef struct _REGISTRY_CALLBACK { LIST_ENTRY ListEntry; diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 155a3aca99a..a89885017f4 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -257,7 +257,7 @@ CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, ExReleaseFastMutex(&CmiCallbackLock); Status = CurrentCallback->Function(CurrentCallback->Context, - Argument1, + (PVOID)Argument1, Argument2); ExAcquireFastMutex(&CmiCallbackLock); diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index c0dc51181bc..8a30fab5487 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -1027,6 +1027,8 @@ extern ULONG IopTraceLevel; extern NPAGED_LOOKASIDE_LIST IopMdlLookasideList; extern GENERIC_MAPPING IopCompletionMapping; extern GENERIC_MAPPING IopFileMapping; +extern POBJECT_TYPE _IoFileObjectType; +extern HAL_DISPATCH _HalDispatchTable; // // Inlined Functions diff --git a/reactos/ntoskrnl/include/internal/kd.h b/reactos/ntoskrnl/include/internal/kd.h index f42e69ecafd..9a42617ff67 100644 --- a/reactos/ntoskrnl/include/internal/kd.h +++ b/reactos/ntoskrnl/include/internal/kd.h @@ -13,6 +13,8 @@ typedef struct _KD_PORT_INFORMATION struct _KD_DISPATCH_TABLE; extern KD_PORT_INFORMATION GdbPortInfo; +extern BOOLEAN _KdDebuggerEnabled; +extern BOOLEAN _KdDebuggerNotPresent; BOOLEAN NTAPI diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index d4ee2681d84..cadf8379bb7 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -366,6 +366,7 @@ extern PVOID PspSystemDllBase; extern BOOLEAN PspUseJobSchedulingClasses; extern CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES]; extern ULONG PsRawPrioritySeparation; +extern POBJECT_TYPE _PsThreadType; // // Inlined Functions diff --git a/reactos/ntoskrnl/include/ntoskrnl.h b/reactos/ntoskrnl/include/ntoskrnl.h index 7e961e827b3..86b14e3e1eb 100644 --- a/reactos/ntoskrnl/include/ntoskrnl.h +++ b/reactos/ntoskrnl/include/ntoskrnl.h @@ -8,8 +8,8 @@ /* INCLUDES ******************************************************************/ -/* We are the Kernel */ -#define _NTSYSTEM_ +/* Tells the WDK that we don't want to import */ +#define NTKERNELAPI /* DDK/IFS/NDK Headers */ #include @@ -53,3 +53,25 @@ /* Internal Headers */ #include "internal/ntoskrnl.h" #include "config.h" + +// +// Define the internal versions of external and public global data +// +#define IoFileObjectType _IoFileObjectType +#define PsThreadType _PsThreadType +#define KdDebuggerEnabled _KdDebuggerEnabled +#define KdDebuggerNotPresent _KdDebuggerNotPresent +#define FsRtlLegalAnsiCharacterArray _FsRtlLegalAnsiCharacterArray +#undef LEGAL_ANSI_CHARACTER_ARRAY +#undef NLS_MB_CODE_PAGE_TAG +#undef NLS_OEM_LEAD_BYTE_INFO +#define LEGAL_ANSI_CHARACTER_ARRAY FsRtlLegalAnsiCharacterArray +#define NLS_MB_CODE_PAGE_TAG NlsMbOemCodePageTag +#define NLS_OEM_LEAD_BYTE_INFO NlsOemLeadByteInfo +#undef KD_DEBUGGER_ENABLED +#undef KD_DEBUGGER_NOT_PRESENT +#define KD_DEBUGGER_ENABLED KdDebuggerEnabled +#define KD_DEBUGGER_NOT_PRESENT KdDebuggerNotPresent +#define HalDispatchTable _HalDispatchTable +#undef HALDISPATCH +#define HALDISPATCH (&HalDispatchTable) diff --git a/reactos/ntoskrnl/kd/kdmain.c b/reactos/ntoskrnl/kd/kdmain.c index 1a55f5ee26c..32f9828e57b 100644 --- a/reactos/ntoskrnl/kd/kdmain.c +++ b/reactos/ntoskrnl/kd/kdmain.c @@ -136,7 +136,7 @@ KdpEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, /* * @implemented */ -VOID +NTSTATUS STDCALL KdDisableDebugger(VOID) { @@ -152,12 +152,15 @@ KdDisableDebugger(VOID) /* Lower the IRQL */ KeLowerIrql(OldIrql); + + /* Return success */ + return STATUS_SUCCESS; } /* * @implemented */ -VOID +NTSTATUS STDCALL KdEnableDebugger(VOID) { @@ -173,6 +176,9 @@ KdEnableDebugger(VOID) /* Lower the IRQL */ KeLowerIrql(OldIrql); + + /* Return success */ + return STATUS_SUCCESS; } /* diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 849637f97cb..04ba96f7b54 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -229,7 +229,7 @@ FsRtlIsNameInExpression@16 FsRtlIsNtstatusExpected@4 FsRtlIsPagingFile@4 FsRtlIsTotalDeviceFailure@4 -FsRtlLegalAnsiCharacterArray DATA +FsRtlLegalAnsiCharacterArray=_FsRtlLegalAnsiCharacterArray FsRtlLookupLargeMcbEntry@32 FsRtlLookupLastLargeMcbEntry@12 FsRtlLookupLastLargeMcbEntryAndIndex@16 @@ -280,7 +280,7 @@ FsRtlUninitializeFileLock@4 FsRtlUninitializeLargeMcb@4 FsRtlUninitializeMcb@4 FsRtlUninitializeOplock@4 -HalDispatchTable DATA +HalDispatchTable=_HalDispatchTable HalPrivateDispatchTable DATA @HalExamineMBR@16 InbvAcquireDisplayOwnership@0 @@ -368,7 +368,7 @@ IoDriverObjectType DATA IoEnqueueIrp@4 IoEnumerateDeviceObjectList@16 IoFastQueryNetworkAttributes@20 -IoFileObjectType DATA +IoFileObjectType=_IoFileObjectType IoForwardAndCatchIrp@8=IoForwardIrpSynchronously@8 IoForwardIrpSynchronously@8 IoFreeController@4 @@ -504,8 +504,8 @@ IoWriteTransferCount DATA @IofCompleteRequest@8 IoIsWdmVersionAvailable@8 KdComPortInUse DATA -KdDebuggerEnabled DATA -KdDebuggerNotPresent DATA +KdDebuggerEnabled=_KdDebuggerEnabled +KdDebuggerNotPresent=_KdDebuggerNotPresent KdDisableDebugger@0 KdEnableDebugger@0 KdEnteredDebugger @@ -964,7 +964,7 @@ PsSetThreadHardErrorsAreDisabled@8 PsSetThreadWin32Thread@8 PsSetLoadImageNotifyRoutine@4 PsTerminateSystemThread@4 -PsThreadType DATA +PsThreadType=_PsThreadType READ_REGISTER_UCHAR@4 READ_REGISTER_ULONG@4 READ_REGISTER_USHORT@4 diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index dca4cab0aa1..a936e40a59e 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -5,6 +5,7 @@ + diff --git a/reactos/ntoskrnl/ps/win32.c b/reactos/ntoskrnl/ps/win32.c index a9f9933c23e..c09291cf497 100644 --- a/reactos/ntoskrnl/ps/win32.c +++ b/reactos/ntoskrnl/ps/win32.c @@ -9,6 +9,7 @@ /* INCLUDES ****************************************************************/ #include +#include #define NDEBUG #include From 9243a83d80845647799e27e0c724ef611cab2285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 7 Sep 2006 22:42:28 +0000 Subject: [PATCH 065/488] Adapt usetup to handle more easily additional filesystems This also prepares ground for the Chkdsk disk page svn path=/trunk/; revision=23974 --- reactos/base/setup/usetup/format.c | 15 +- reactos/base/setup/usetup/format.h | 3 +- reactos/base/setup/usetup/fslist.c | 147 +++++++++++------- reactos/base/setup/usetup/fslist.h | 18 ++- reactos/base/setup/usetup/usetup.c | 229 ++++++++++++++--------------- reactos/base/setup/usetup/usetup.h | 2 +- 6 files changed, 230 insertions(+), 184 deletions(-) diff --git a/reactos/base/setup/usetup/format.c b/reactos/base/setup/usetup/format.c index 3c22a7f1d24..06137c42b5c 100644 --- a/reactos/base/setup/usetup/format.c +++ b/reactos/base/setup/usetup/format.c @@ -84,7 +84,8 @@ FormatCallback( NTSTATUS FormatPartition( - IN PUNICODE_STRING DriveRoot) + IN PUNICODE_STRING DriveRoot, + IN PFILE_SYSTEM_ITEM FileSystem) { NTSTATUS Status; @@ -96,12 +97,12 @@ FormatPartition( ProgressSetStepCount(ProgressBar, 100); - Status = VfatFormat(DriveRoot, - FMIFS_HARDDISK, /* MediaFlag */ - NULL, /* Label */ - TRUE, /* QuickFormat */ - 0, /* ClusterSize */ - FormatCallback); /* Callback */ + Status = FileSystem->FormatFunc(DriveRoot, + FMIFS_HARDDISK, /* MediaFlag */ + NULL, /* Label */ + FileSystem->QuickFormat, /* QuickFormat */ + 0, /* ClusterSize */ + FormatCallback); /* Callback */ DestroyProgressBar(ProgressBar); ProgressBar = NULL; diff --git a/reactos/base/setup/usetup/format.h b/reactos/base/setup/usetup/format.h index 1725664b27f..c72b86d96b0 100644 --- a/reactos/base/setup/usetup/format.h +++ b/reactos/base/setup/usetup/format.h @@ -29,7 +29,8 @@ NTSTATUS FormatPartition( - IN PUNICODE_STRING DriveRoot); + IN PUNICODE_STRING DriveRoot, + IN PFILE_SYSTEM_ITEM FileSystem); #endif /* __FILESUP_H__ */ diff --git a/reactos/base/setup/usetup/fslist.c b/reactos/base/setup/usetup/fslist.c index 34b4f22085c..b8712f82988 100644 --- a/reactos/base/setup/usetup/fslist.c +++ b/reactos/base/setup/usetup/fslist.c @@ -32,14 +32,49 @@ /* FUNCTIONS ****************************************************************/ +static VOID +AddProvider( + IN OUT PFILE_SYSTEM_LIST List, + IN LPCSTR FileSystem, + IN FORMATEX FormatFunc, + IN CHKDSKEX ChkdskFunc) +{ + PFILE_SYSTEM_ITEM Item; + + Item = (PFILE_SYSTEM_ITEM)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_ITEM)); + if (!Item) + return; + + Item->FileSystem = FileSystem; + Item->FormatFunc = FormatFunc; + Item->ChkdskFunc = ChkdskFunc; + Item->QuickFormat = FALSE; + InsertTailList(&List->ListHead, &Item->ListEntry); + + if (!FormatFunc) + return; + + Item = (PFILE_SYSTEM_ITEM)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_ITEM)); + if (!Item) + return; + + Item->FileSystem = FileSystem; + Item->FormatFunc = FormatFunc; + Item->ChkdskFunc = ChkdskFunc; + Item->QuickFormat = TRUE; + InsertTailList(&List->ListHead, &Item->ListEntry); +} + PFILE_SYSTEM_LIST CreateFileSystemList( IN SHORT Left, IN SHORT Top, IN BOOLEAN ForceFormat, - IN FILE_SYSTEM ForceFileSystem) + IN LPCSTR ForceFileSystem) { PFILE_SYSTEM_LIST List; + PFILE_SYSTEM_ITEM Item; + PLIST_ENTRY ListEntry; List = (PFILE_SYSTEM_LIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_LIST)); if (List == NULL) @@ -47,18 +82,30 @@ CreateFileSystemList( List->Left = Left; List->Top = Top; + List->Selected = NULL; + InitializeListHead(&List->ListHead); - List->ForceFormat = ForceFormat; - List->FileSystemCount = 1; - if (ForceFormat) + AddProvider(List, "FAT", VfatFormat, NULL); + if (!ForceFormat) { - List->CurrentFileSystem = ForceFileSystem; + /* Add 'Keep' provider */ + AddProvider(List, NULL, NULL, NULL); } - else + + /* Search for ForceFileSystem in list */ + ListEntry = List->ListHead.Flink; + while (ListEntry != &List->ListHead) { - List->FileSystemCount++; - List->CurrentFileSystem = FsKeep; + Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry); + if (Item->FileSystem && strcmp(ForceFileSystem, Item->FileSystem) == 0) + { + List->Selected = Item; + break; + } + ListEntry = ListEntry->Flink; } + if (!List->Selected) + List->Selected = CONTAINING_RECORD(List->ListHead.Flink, FILE_SYSTEM_ITEM, ListEntry); return List; } @@ -67,6 +114,19 @@ VOID DestroyFileSystemList( IN PFILE_SYSTEM_LIST List) { + PLIST_ENTRY ListEntry = List->ListHead.Flink; + PFILE_SYSTEM_ITEM Item; + PLIST_ENTRY Next; + + while (ListEntry != &List->ListHead) + { + Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry); + Next = ListEntry->Flink; + + RtlFreeHeap(ProcessHeap, 0, Item); + + ListEntry = Next; + } RtlFreeHeap(ProcessHeap, 0, List); } @@ -74,66 +134,51 @@ VOID DrawFileSystemList( IN PFILE_SYSTEM_LIST List) { + PLIST_ENTRY ListEntry; + PFILE_SYSTEM_ITEM Item; COORD coPos; ULONG Written; - ULONG Index; + ULONG Index = 0; + CHAR Buffer[70]; - Index = 0; - - coPos.X = List->Left; - coPos.Y = List->Top + Index; - FillConsoleOutputAttribute(StdOutput, - FOREGROUND_WHITE | BACKGROUND_BLUE, - 50, - coPos, - &Written); - FillConsoleOutputCharacterA(StdOutput, - ' ', - 50, - coPos, - &Written); - - if (List->CurrentFileSystem == FsFat) + ListEntry = List->ListHead.Flink; + while (ListEntry != &List->ListHead) { - CONSOLE_SetInvertedTextXY(List->Left, - List->Top + Index, - " Format partition as FAT file system "); - } - else - { - CONSOLE_SetTextXY(List->Left, - List->Top + Index, - " Format partition as FAT file system "); - } - Index++; + Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry); - if (List->ForceFormat == FALSE) - { coPos.X = List->Left; coPos.Y = List->Top + Index; FillConsoleOutputAttribute(StdOutput, FOREGROUND_WHITE | BACKGROUND_BLUE, - 50, + sizeof(Buffer), coPos, &Written); FillConsoleOutputCharacterA(StdOutput, ' ', - 50, + sizeof(Buffer), coPos, &Written); - if (List->CurrentFileSystem == FsKeep) + if (Item->FileSystem) { - CONSOLE_SetInvertedTextXY(List->Left, - List->Top + Index, - " Keep current file system (no changes) "); + if (Item->QuickFormat) + sprintf(Buffer, " Format partition as %s file system (quick format) ", Item->FileSystem); + else + sprintf(Buffer, " Format partition as %s file system ", Item->FileSystem); } else - { + sprintf(Buffer, " Keep current file system (no changes) "); + + if (ListEntry == &List->Selected->ListEntry) + CONSOLE_SetInvertedTextXY(List->Left, + List->Top + Index, + Buffer); + else CONSOLE_SetTextXY(List->Left, List->Top + Index, - " Keep current file system (no changes) "); - } + Buffer); + Index++; + ListEntry = ListEntry->Flink; } } @@ -141,9 +186,9 @@ VOID ScrollDownFileSystemList( IN PFILE_SYSTEM_LIST List) { - if ((ULONG)List->CurrentFileSystem < List->FileSystemCount - 1) + if (List->Selected->ListEntry.Flink != &List->ListHead) { - List->CurrentFileSystem++; + List->Selected = CONTAINING_RECORD(List->Selected->ListEntry.Flink, FILE_SYSTEM_ITEM, ListEntry); DrawFileSystemList(List); } } @@ -152,9 +197,9 @@ VOID ScrollUpFileSystemList( IN PFILE_SYSTEM_LIST List) { - if ((ULONG)List->CurrentFileSystem > 0) + if (List->Selected->ListEntry.Blink != &List->ListHead) { - List->CurrentFileSystem--; + List->Selected = CONTAINING_RECORD(List->Selected->ListEntry.Blink, FILE_SYSTEM_ITEM, ListEntry); DrawFileSystemList(List); } } diff --git a/reactos/base/setup/usetup/fslist.h b/reactos/base/setup/usetup/fslist.h index 98c0463c8e9..7e114f0371c 100644 --- a/reactos/base/setup/usetup/fslist.h +++ b/reactos/base/setup/usetup/fslist.h @@ -28,19 +28,21 @@ #ifndef __FSLIST_H__ #define __FSLIST_H__ -typedef enum +typedef struct _FILE_SYSTEM_ITEM { - FsFat = 0, - FsKeep = 1 -} FILE_SYSTEM; + LIST_ENTRY ListEntry; + LPCSTR FileSystem; /* Not owned by the item */ + FORMATEX FormatFunc; + CHKDSKEX ChkdskFunc; + BOOLEAN QuickFormat; +} FILE_SYSTEM_ITEM, *PFILE_SYSTEM_ITEM; typedef struct _FILE_SYSTEM_LIST { SHORT Left; SHORT Top; - BOOLEAN ForceFormat; - FILE_SYSTEM CurrentFileSystem; - ULONG FileSystemCount; + PFILE_SYSTEM_ITEM Selected; + LIST_ENTRY ListHead; /* List of FILE_SYSTEM_ITEM */ } FILE_SYSTEM_LIST, *PFILE_SYSTEM_LIST; @@ -49,7 +51,7 @@ CreateFileSystemList( IN SHORT Left, IN SHORT Top, IN BOOLEAN ForceFormat, - IN FILE_SYSTEM ForceFileSystem); + IN LPCSTR ForceFileSystem); VOID DestroyFileSystemList( diff --git a/reactos/base/setup/usetup/usetup.c b/reactos/base/setup/usetup/usetup.c index 681fb19de9f..7bb7e846d06 100644 --- a/reactos/base/setup/usetup/usetup.c +++ b/reactos/base/setup/usetup/usetup.c @@ -2099,7 +2099,7 @@ SelectFileSystemPage (PINPUT_RECORD Ir) if (FileSystemList == NULL) { - FileSystemList = CreateFileSystemList (6, 26, PartEntry->New, FsFat); + FileSystemList = CreateFileSystemList (6, 26, PartEntry->New, "FAT"); if (FileSystemList == NULL) { /* FIXME: show an error dialog */ @@ -2147,7 +2147,7 @@ SelectFileSystemPage (PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */ { - if (FileSystemList->CurrentFileSystem == FsKeep) + if (!FileSystemList->Selected->FormatFunc) { return CHECK_FILE_SYSTEM_PAGE; } @@ -2212,60 +2212,55 @@ FormatPartitionPage (PINPUT_RECORD Ir) { CONSOLE_SetStatusText (" Please wait ..."); - if (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED) - { - switch (FileSystemList->CurrentFileSystem) - { - case FsFat: - if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (4200LL * 1024LL)) - { - /* FAT12 CHS partition (disk is smaller than 4.1MB) */ - PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_12; - } - else if (PartEntry->PartInfo[0].StartingOffset.QuadPart < (1024LL * 255LL * 63LL * 512LL)) - { - /* Partition starts below the 8.4GB boundary ==> CHS partition */ + if (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED) + { + if (strcmp(FileSystemList->Selected->FileSystem, "FAT") == 0) + { + if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (4200LL * 1024LL)) + { + /* FAT12 CHS partition (disk is smaller than 4.1MB) */ + PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_12; + } + else if (PartEntry->PartInfo[0].StartingOffset.QuadPart < (1024LL * 255LL * 63LL * 512LL)) + { + /* Partition starts below the 8.4GB boundary ==> CHS partition */ - if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (32LL * 1024LL * 1024LL)) - { - /* FAT16 CHS partition (partiton size < 32MB) */ - PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_16; - } - else if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL)) - { - /* FAT16 CHS partition (partition size < 512MB) */ - PartEntry->PartInfo[0].PartitionType = PARTITION_HUGE; - } - else - { - /* FAT32 CHS partition (partition size >= 512MB) */ - PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32; - } - } - else - { - /* Partition starts above the 8.4GB boundary ==> LBA partition */ + if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (32LL * 1024LL * 1024LL)) + { + /* FAT16 CHS partition (partiton size < 32MB) */ + PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_16; + } + else if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL)) + { + /* FAT16 CHS partition (partition size < 512MB) */ + PartEntry->PartInfo[0].PartitionType = PARTITION_HUGE; + } + else + { + /* FAT32 CHS partition (partition size >= 512MB) */ + PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32; + } + } + else + { + /* Partition starts above the 8.4GB boundary ==> LBA partition */ - if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL)) - { - /* FAT16 LBA partition (partition size < 512MB) */ - PartEntry->PartInfo[0].PartitionType = PARTITION_XINT13; - } - else - { - /* FAT32 LBA partition (partition size >= 512MB) */ - PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32_XINT13; - } - } - break; - - case FsKeep: - break; - - default: - return QUIT_PAGE; - } - } + if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL)) + { + /* FAT16 LBA partition (partition size < 512MB) */ + PartEntry->PartInfo[0].PartitionType = PARTITION_XINT13; + } + else + { + /* FAT32 LBA partition (partition size >= 512MB) */ + PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32_XINT13; + } + } + break; + } + else if (FileSystemList->Selected->FormatFunc) + return QUIT_PAGE; + } CheckActiveBootPartition (PartitionList); @@ -2343,79 +2338,81 @@ FormatPartitionPage (PINPUT_RECORD Ir) DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath); - switch (FileSystemList->CurrentFileSystem) - { - case FsFat: - Status = FormatPartition (&DestinationRootPath); - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("FormatPartition() failed with status 0x%.08x\n", Status); - /* FIXME: show an error dialog */ - return QUIT_PAGE; - } + if (FileSystemList->Selected->FormatFunc) + { + Status = FormatPartition(&DestinationRootPath, FileSystemList->Selected); + if (!NT_SUCCESS(Status)) + { + DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status); + /* FIXME: show an error dialog */ + return QUIT_PAGE; + } - PartEntry->New = FALSE; - if (FileSystemList != NULL) - { - DestroyFileSystemList (FileSystemList); - FileSystemList = NULL; - } + PartEntry->New = FALSE; - CheckActiveBootPartition (PartitionList); + CheckActiveBootPartition(PartitionList); + } - /* FIXME: Install boot code. This is a hack! */ - if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32)) - { - wcscpy (PathBuffer, SourceRootPath.Buffer); - wcscat (PathBuffer, L"\\loader\\fat32.bin"); + if (strcmp(FileSystemList->Selected->FileSystem, "FAT") == 0) + { + /* FIXME: Install boot code. This is a hack! */ + if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13) + || (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32)) + { + wcscpy(PathBuffer, SourceRootPath.Buffer); + wcscat(PathBuffer, L"\\loader\\fat32.bin"); - DPRINT ("Install FAT32 bootcode: %S ==> %S\n", PathBuffer, - DestinationRootPath.Buffer); - Status = InstallFat32BootCodeToDisk (PathBuffer, - DestinationRootPath.Buffer); - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("InstallFat32BootCodeToDisk() failed with status 0x%.08x\n", Status); - /* FIXME: show an error dialog */ - return QUIT_PAGE; - } - } - else - { - wcscpy (PathBuffer, SourceRootPath.Buffer); - wcscat (PathBuffer, L"\\loader\\fat.bin"); + DPRINT("Install FAT32 bootcode: %S ==> %S\n", PathBuffer, + DestinationRootPath.Buffer); + Status = InstallFat32BootCodeToDisk(PathBuffer, + DestinationRootPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status); + /* FIXME: show an error dialog */ + DestroyFileSystemList(FileSystemList); + FileSystemList = NULL; + return QUIT_PAGE; + } + } + else + { + wcscpy(PathBuffer, SourceRootPath.Buffer); + wcscat(PathBuffer, L"\\loader\\fat.bin"); - DPRINT ("Install FAT bootcode: %S ==> %S\n", PathBuffer, - DestinationRootPath.Buffer); - Status = InstallFat16BootCodeToDisk (PathBuffer, - DestinationRootPath.Buffer); - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status); - /* FIXME: show an error dialog */ - return QUIT_PAGE; - } - } - break; - - case FsKeep: - break; - - default: - return QUIT_PAGE; - } + DPRINT("Install FAT bootcode: %S ==> %S\n", PathBuffer, + DestinationRootPath.Buffer); + Status = InstallFat16BootCodeToDisk(PathBuffer, + DestinationRootPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status); + /* FIXME: show an error dialog */ + DestroyFileSystemList(FileSystemList); + FileSystemList = NULL; + return QUIT_PAGE; + } + } + } + else if (FileSystemList->Selected->FormatFunc) + { + DestroyFileSystemList(FileSystemList); + FileSystemList = NULL; + return QUIT_PAGE; + } #ifndef NDEBUG - CONSOLE_SetStatusText (" Done. Press any key ..."); - CONSOLE_ConInKey(Ir); + CONSOLE_SetStatusText (" Done. Press any key ..."); + CONSOLE_ConInKey(Ir); #endif - return INSTALL_DIRECTORY_PAGE; - } + DestroyFileSystemList(FileSystemList); + FileSystemList = NULL; + return INSTALL_DIRECTORY_PAGE; + } } - return FORMAT_PARTITION_PAGE; + return FORMAT_PARTITION_PAGE; } diff --git a/reactos/base/setup/usetup/usetup.h b/reactos/base/setup/usetup/usetup.h index 133b76b9eb0..fa151f89071 100644 --- a/reactos/base/setup/usetup/usetup.h +++ b/reactos/base/setup/usetup/usetup.h @@ -64,8 +64,8 @@ #include "bootsup.h" #include "keytrans.h" #include "registry.h" -#include "format.h" #include "fslist.h" +#include "format.h" #include "cabinet.h" #include "filesup.h" #include "drivesup.h" From 335e03625a211b41ae9a1b520870c1a74b90e41c Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 8 Sep 2006 15:39:34 +0000 Subject: [PATCH 066/488] Fix invalid charset (DOS -> Windows) svn path=/trunk/; revision=23975 --- reactos/dll/cpl/powercfg/ru.rc | 174 ++++++++++++++++----------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/reactos/dll/cpl/powercfg/ru.rc b/reactos/dll/cpl/powercfg/ru.rc index f1623f19639..6f0925a692b 100644 --- a/reactos/dll/cpl/powercfg/ru.rc +++ b/reactos/dll/cpl/powercfg/ru.rc @@ -4,159 +4,159 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_NEUTRAL IDD_PROPPAGEPOWERSHEMES DIALOGEX 0, 0, 250, 220 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "‘奬ë ăŻŕ ˘«Ą­¨ď Ż¨â ­¨Ą¬" +CAPTION "Ńőĺěű óďđŕâëĺíč˙ ďčňŕíčĺě" FONT 8, "MS Shell Dlg" BEGIN ICON IDI_ACDC, IDI_ACDC, 7,7,28,22 - LTEXT "‚롥ŕ¨âĄ á奬ă ăŻŕ ˘«Ą­¨ď í«ĄŞâய¨â ­¨Ą¬ á ­ ¨ˇ®«ĄĄ Ż®¤ĺ®¤ď騬¨ Ż ŕ ¬Ąâŕ ¬¨ ¤«ď í⮣® Ş®¬ŻěîâĄŕ . §¬Ą­Ą­¨Ą ­¨¦Ąá«Ą¤ăîé¨ĺ Ż ŕ ¬Ąâ஢ ¨§¬Ą­¨â ˘ëˇŕ ­­ăî á奬ă.", + LTEXT "Âűáĺđčňĺ ńőĺěó óďđŕâëĺíč˙ ýëĺęňđîďčňŕíčĺě ń íŕčáîëĺĺ ďîäőîä˙ůčěč ďŕđŕěĺňđŕěč äë˙ ýňîăî ęîěďüţňĺđŕ. Čçěĺíĺíčĺ íčćĺńëĺäóţůčő ďŕđŕěĺňđîâ čçěĺíčň âűáđŕííóţ ńőĺěó.", -1,45,13,194,36 - GROUPBOX "&‘奬ë ăŻŕ ˘«Ą­¨ď Ż¨â ­¨Ą¬", -1, 7,57,240,46 + GROUPBOX "&Ńőĺěű óďđŕâëĺíč˙ ďčňŕíčĺě", -1, 7,57,240,46 COMBOBOX IDC_ENERGYLIST, 14,70,224,92, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "‘®ĺŕ ­¨âě &Ş Ş...", -1, 100,85,75,15,WS_DISABLED - PUSHBUTTON "&“¤ «¨âě", -1, 180,85,55,15,WS_DISABLED - GROUPBOX "ŤĄâ ¤ ­­ëĺ", IDC_GRPDETAIL, 7,108,240,105 - LTEXT "Źŕ¨ Ż¨â ­¨¨:",IDC_SAT,15,120,60,10 - LTEXT "®â áĄâ¨",IDC_SAC,100,120,45,15 + PUSHBUTTON "Ńîőđŕíčňü &ęŕę...", -1, 100,85,75,15,WS_DISABLED + PUSHBUTTON "&Óäŕëčňü", -1, 180,85,55,15,WS_DISABLED + GROUPBOX "Íĺň äŕííűő", IDC_GRPDETAIL, 7,108,240,105 + LTEXT "Ďđč ďčňŕíčč:",IDC_SAT,15,120,60,10 + LTEXT "îň ńĺňč",IDC_SAC,100,120,45,15 ICON IDI_AC, IDC_IAC, 75,115,25,15 - LTEXT "®â ˇ â ŕĄ©",IDC_SDC,197,120,45,15 + LTEXT "îň áŕňŕđĺé",IDC_SDC,197,120,45,15 ICON IDI_DC, IDC_IDC, 165,115,25,15 - LTEXT "ŽâŞ«îç¨âě &¬®­¨â®ŕ:",IDC_MONITOR,15,142,80,10 + LTEXT "Îňęëţ÷čňü &ěîíčňîđ:",IDC_MONITOR,15,142,80,10 COMBOBOX IDC_MONITORACLIST, 100,140,65,150, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_MONITORDCLIST, 175,140,65,150, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ŽâŞ«îç¨âě &¤¨áި:",IDC_DISK,15,157,80,10 + LTEXT "Îňęëţ÷čňü &äčńęč:",IDC_DISK,15,157,80,10 COMBOBOX IDC_DISKACLIST, 100,155,65,150, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_DISKDCLIST, 175,155,65,150, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "&†¤ă騩 ०¨¬ çĄŕĄ§:",IDC_STANDBY,15,177,80,10 + LTEXT "&Ćäóůčé đĺćčě ÷ĺđĺç:",IDC_STANDBY,15,177,80,10 COMBOBOX IDC_STANDBYACLIST, 100,175,65,150, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_STANDBYDCLIST, 175,175,65,150, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "‘&Żď騩 ०¨¬ çĄŕĄ§:",IDC_HYBERNATE,15,192,80,10 + LTEXT "Ń&ď˙ůčé đĺćčě ÷ĺđĺç:",IDC_HYBERNATE,15,192,80,10 COMBOBOX IDC_HYBERNATEACLIST, 100,190,65,150, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_HYBERNATEDCLIST, 175,190,65,150, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_PROPPAGEALARMS DIALOG DISCARDABLE 0, 0, 250, 220 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "“˘Ą¤®¬«Ą­¨ď" +CAPTION "Óâĺäîěëĺíč˙" FONT 8, "MS Sans Serif" BEGIN - GROUPBOX "‘¨Ł­ « ­¨§Ş®Ł® § ŕ鸞 ˇ â ŕĄ©",-1,10,15,235,95 - CONTROL "‚Ş«îç¨âě ᨣ­ « ­&¨§Ş®Ł® § ŕ鸞 Żŕ¨ ă஢­Ą:",IDC_ALARM1, + GROUPBOX "Ńčăíŕë íčçęîăî çŕđ˙äŕ áŕňŕđĺé",-1,10,15,235,95 + CONTROL "Âęëţ÷čňü ńčăíŕë í&čçęîăî çŕđ˙äŕ ďđč óđîâíĺ:",IDC_ALARM1, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,25,180,15 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_ALARMVALUE1,200,25,40,10 + LTEXT "Íĺň äŕííűő",IDC_ALARMVALUE1,200,25,40,10 LTEXT "0%",-1,20,40,15,15 CONTROL "Slider1",IDC_ALARMBAR1,"msctls_trackbar32",TBS_HORZ | TBS_AUTOTICKS | WS_TABSTOP,30,40,170,15 LTEXT "100%",-1,215,40,25,10 - PUSHBUTTON "„&Ą©á⢨Ą...",-1,20,70,70,15,WS_DISABLED - LTEXT "“˘Ą¤®¬«Ą­¨Ą:",-1,95,70,50,10 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_ALARMMSG1,145,70,95,10 - LTEXT "„Ą©á⢨Ą:",-1,95,80,45,10 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_ALARMAKTION1,145,80,95,10 - LTEXT "‡ Żă᪠Żŕ®Łŕ ¬¬ë:",-1,95,90,50,10 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_ALARMPROG1,150,90,40,10 + PUSHBUTTON "Ä&ĺéńňâčĺ...",-1,20,70,70,15,WS_DISABLED + LTEXT "Óâĺäîěëĺíčĺ:",-1,95,70,50,10 + LTEXT "Íĺň äŕííűő",IDC_ALARMMSG1,145,70,95,10 + LTEXT "Äĺéńňâčĺ:",-1,95,80,45,10 + LTEXT "Íĺň äŕííűő",IDC_ALARMAKTION1,145,80,95,10 + LTEXT "Çŕďóńę ďđîăđŕěěű:",-1,95,90,50,10 + LTEXT "Íĺň äŕííűő",IDC_ALARMPROG1,150,90,40,10 - GROUPBOX "‘¨Ł­ « Şŕ¨â¨çĄáި ­¨§Ş®Ł® § ŕ鸞 ˇ â ŕĄ©",-1,10,115,235,95 - CONTROL "‚Ş«îç¨âě â Ş®© &ᨣ­ « Żŕ¨ ă஢­Ą:",IDC_ALARM2, + GROUPBOX "Ńčăíŕë ęđčňč÷ĺńęč íčçęîăî çŕđ˙äŕ áŕňŕđĺé",-1,10,115,235,95 + CONTROL "Âęëţ÷čňü ňŕęîé &ńčăíŕë ďđč óđîâíĺ:",IDC_ALARM2, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,125,180,15 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_ALARMVALUE2,200,125,40,10 + LTEXT "Íĺň äŕííűő",IDC_ALARMVALUE2,200,125,40,10 LTEXT "0%",-1,20,140,15,15 CONTROL "Slider1",IDC_ALARMBAR2,"msctls_trackbar32",TBS_HORZ | TBS_AUTOTICKS | WS_TABSTOP,30,140,170,15 LTEXT "100%",-1,215,140,25,10 - PUSHBUTTON "„Ą&©á⢨Ą...",-1,20,170,70,15,WS_DISABLED - LTEXT "“˘Ą¤®¬«Ą­¨Ą:",-1,95,170,50,10 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_ALARMMSG2,145,170,95,10 - LTEXT "„Ą©á⢨Ą:",-1,95,180,45,10 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_ALARMAKTION2,145,180,95,10 - LTEXT "‡ Żă᪠Żŕ®Łŕ ¬¬ë:",-1,95,190,50,10 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_ALARMPROG2,150,190,40,10 + PUSHBUTTON "Äĺ&éńňâčĺ...",-1,20,170,70,15,WS_DISABLED + LTEXT "Óâĺäîěëĺíčĺ:",-1,95,170,50,10 + LTEXT "Íĺň äŕííűő",IDC_ALARMMSG2,145,170,95,10 + LTEXT "Äĺéńňâčĺ:",-1,95,180,45,10 + LTEXT "Íĺň äŕííűő",IDC_ALARMAKTION2,145,180,95,10 + LTEXT "Çŕďóńę ďđîăđŕěěű:",-1,95,190,50,10 + LTEXT "Íĺň äŕííűő",IDC_ALARMPROG2,150,190,40,10 END IDD_PROPPAGEADVANCED DIALOG DISCARDABLE 0, 0, 250, 220 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "„®Ż®«­¨âĄ«ě­®" +CAPTION "Äîďîëíčňĺëüíî" FONT 8, "MS Sans Serif" BEGIN ICON IDI_ACDC,IDI_ACDC,5,5,20,20 - LTEXT "‚롥ŕ¨âĄ ¦Ą« Ą¬ëĄ Ż ŕ ¬Ąâŕë í­ĄŕŁ®áˇĄŕĄ¦Ą­¨ď.",-1,30,5,205,20 - GROUPBOX "Ź ŕ ¬Ąâŕë",-1,5,35,225,55 - CONTROL "&‚ᥣ¤  ®â®ˇŕ ¦ âě §­ ç®Ş ­  Ż ­Ą«¨ § ¤ ç",IDC_SYSTRAYBATTERYMETER,"Button",BS_AUTOCHECKBOX | + LTEXT "Âűáĺđčňĺ ćĺëŕĺěűĺ ďŕđŕěĺňđű ýíĺđăîńáĺđĺćĺíč˙.",-1,30,5,205,20 + GROUPBOX "Ďŕđŕěĺňđű",-1,5,35,225,55 + CONTROL "&Âńĺăäŕ îňîáđŕćŕňü çíŕ÷îę íŕ ďŕíĺëč çŕäŕ÷",IDC_SYSTRAYBATTERYMETER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,48,200,10 - CONTROL "&‡ Żŕ č¨˘ âě Ż ŕ®«ě Żŕ¨ ˘ë室Ą ¨§ ¦¤ă饣® ०¨¬ ",IDC_PASSWORDLOGON,"Button",BS_AUTOCHECKBOX | + CONTROL "&Çŕďđŕřčâŕňü ďŕđîëü ďđč âűőîäĺ čç ćäóůĺăî đĺćčěŕ",IDC_PASSWORDLOGON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,60,200,10 - CONTROL "&‘­¨§¨âě ďમáâě ¬®­¨â®ŕ  Żŕ¨ ŕ ˇ®âĄ ®â ˇ â ŕĄ©",IDC_VIDEODIMDISPLAY,"Button",BS_AUTOCHECKBOX | + CONTROL "&Ńíčçčňü ˙đęîńňü ěîíčňîđŕ ďđč đŕáîňĺ îň áŕňŕđĺé",IDC_VIDEODIMDISPLAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,72,200,10 - GROUPBOX "Š­®ŻŞ¨ Ż¨â ­¨ď",-1,5,100,230,105 - LTEXT "&Źŕ¨ § Şŕë⨨ Şŕë誨 ŻĄŕĄ­®á­®Ł® Ş®¬ŻěîâĄŕ :", IDC_SLIDCLOSE,10,110,210,10 + GROUPBOX "Ęíîďęč ďčňŕíč˙",-1,5,100,230,105 + LTEXT "&Ďđč çŕęđűňčč ęđűřęč ďĺđĺíîńíîăî ęîěďüţňĺđŕ:", IDC_SLIDCLOSE,10,110,210,10 COMBOBOX IDC_LIDCLOSE,10,120,220,90,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Źŕ¨ &­ ¦ â¨¨ Ş­®ŻŞ¨ ˘Ş«î祭¨ď Ż¨â ­¨ď Ş®¬ŻěîâĄŕ :", IDC_SPOWERBUTTON,10,140,210,10 + LTEXT "Ďđč &íŕćŕňčč ęíîďęč âęëţ÷ĺíč˙ ďčňŕíč˙ ęîěďüţňĺđŕ:", IDC_SPOWERBUTTON,10,140,210,10 COMBOBOX IDC_POWERBUTTON,10,150,220,90,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Źŕ¨ ­ ¦ â¨¨ &Ş­®ŻŞ¨ ŻĄŕĄĺ®¤  ˘ áŻď騩 ०¨¬:", IDC_SSLEEPBUTTON,10,170,210,10 + LTEXT "Ďđč íŕćŕňčč &ęíîďęč ďĺđĺőîäŕ â ńď˙ůčé đĺćčě:", IDC_SSLEEPBUTTON,10,170,210,10 COMBOBOX IDC_SLEEPBUTTON,10,180,220,90,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP END IDD_PROPPAGEHIBERNATE DIALOG DISCARDABLE 0, 0, 250, 220 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "‘Żď騩 ०¨¬" +CAPTION "Ńď˙ůčé đĺćčě" FONT 8, "MS Sans Serif" BEGIN ICON IDI_SCREEN,IDI_SCREEN,5,5,20,20 - LTEXT "Źŕ¨ ŻĄŕĄĺ®¤Ą ˘ áŻď騩 ०¨¬ Ş®¬ŻěîâĄŕ ŻĄŕĄ­®á¨â ᮤĄŕ¦¨¬®Ą ®ŻĄŕ â¨˘­®© Ż ¬ď⨠­  ¤¨áŞ ¨ ˘ëŞ«îç Ąâáď. Źŕ¨ ˘ë室Ą ¨§ áŻď饣® ०¨¬  Ş®¬ŻěîâĄŕ ˘®§˘ŕ é Ąâáď ˘ ŻŕĄ¦­ĄĄ á®áâ®ď­¨Ą.", + LTEXT "Ďđč ďĺđĺőîäĺ â ńď˙ůčé đĺćčě ęîěďüţňĺđ ďĺđĺíîńčň ńîäĺđćčěîĺ îďĺđŕňčâíîé ďŕě˙ňč íŕ äčńę č âűęëţ÷ŕĺňń˙. Ďđč âűőîäĺ čç ńď˙ůĺăî đĺćčěŕ ęîěďüţňĺđ âîçâđŕůŕĺňń˙ â ďđĺćíĺĺ ńîńňî˙íčĺ.", -1,35,5,195,35 - GROUPBOX "‘Żď騩 ०¨¬",-1,5,45,235,25 - CONTROL "& §ŕĄč¨âě ŻĄŕĄĺ®¤ ˘ áŻď騩 ०¨¬",IDC_HIBERNATEFILE,"Button",BS_AUTOCHECKBOX | + GROUPBOX "Ńď˙ůčé đĺćčě",-1,5,45,235,25 + CONTROL "&Đŕçđĺřčňü ďĺđĺőîä â ńď˙ůčé đĺćčě",IDC_HIBERNATEFILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,55,210,10 - GROUPBOX "ŚĄáâ® ­  ¤¨áŞĄ ¤«ď ŻĄŕĄĺ®¤  ˘ áŻď騩 ०¨¬",-1,5,80,240,60 - LTEXT "‘˘®ˇ®¤­® ¬Ąáâ  ­  ¤¨áŞĄ:",-1,10,90,100,10 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_FREESPACE,130,90,70,10 - LTEXT "’ॡăĄâáď ¤«ď áŻď饣® ०¨¬ :",-1,10,100,115,10 - LTEXT "ŤĄâ ¤ ­­ëĺ",IDC_SPACEFORHIBERNATEFILE,130,100,55,10 - LTEXT "„«ď ˘®§¬®¦­®áâ¨ ŻĄŕĄĺ®¤  ˘ áŻď騩 ०¨¬ âॡăĄâáď ®á˘®ˇ®¤¨âě ¬Ąáâ® ­  ¤¨áŞĄ.",IDC_TOLESSFREESPACE,10,115,220,20 + GROUPBOX "Ěĺńňî íŕ äčńęĺ äë˙ ďĺđĺőîäŕ â ńď˙ůčé đĺćčě",-1,5,80,240,60 + LTEXT "Ńâîáîäíî ěĺńňŕ íŕ äčńęĺ:",-1,10,90,100,10 + LTEXT "Íĺň äŕííűő",IDC_FREESPACE,130,90,70,10 + LTEXT "Ňđĺáóĺňń˙ äë˙ ńď˙ůĺăî đĺćčěŕ:",-1,10,100,115,10 + LTEXT "Íĺň äŕííűő",IDC_SPACEFORHIBERNATEFILE,130,100,55,10 + LTEXT "Äë˙ âîçěîćíîńňč ďĺđĺőîäŕ â ńď˙ůčé đĺćčě ňđĺáóĺňń˙ îńâîáîäčňü ěĺńňî íŕ äčńęĺ.",IDC_TOLESSFREESPACE,10,115,220,20 END STRINGTABLE BEGIN - IDS_CPLNAME_1 "ť«ĄŞâய¨â ­¨Ą" - IDS_CPLDESCRIPTION_1 "Ť áâŕ®©Ş  Ż ŕ ¬Ąâ஢ í­ĄŕŁ®áˇĄŕĄ¦Ą­¨ď ¤«ď Ş®¬ŻěîâĄŕ ." + IDS_CPLNAME_1 "Ýëĺęňđîďčňŕíčĺ" + IDS_CPLDESCRIPTION_1 "Íŕńňđîéęŕ ďŕđŕěĺňđîâ ýíĺđăîńáĺđĺćĺíč˙ äë˙ ęîěďüţňĺđŕ." IDS_PROCENT "%i%%" - IDS_SOUND "‡˘ăŞ" - IDS_TEXT "’ĄŞáâ" - IDS_CONFIG1 "Ź ŕ ¬Ąâŕë á奬ë %1" - IDS_CONFIG2 "„®Ż®«­¨âĄ«ě­ëĄ Ż ŕ ¬Ąâŕë á奬ë %1" + IDS_SOUND "Çâóę" + IDS_TEXT "Ňĺęńň" + IDS_CONFIG1 "Ďŕđŕěĺňđű ńőĺěű %1" + IDS_CONFIG2 "Äîďîëíčňĺëüíűĺ ďŕđŕěĺňđű ńőĺěű %1" - IDS_SIZEBYTS "%i ˇ ©â" - IDS_SIZEMB "%i Ś" + IDS_SIZEBYTS "%i áŕéň" + IDS_SIZEMB "%i ĚÁ" IDS_NOACTION "Do nothing" - IDS_PowerActionNone1 "„Ą©á⢨Ą ­Ą âॡăĄâáď" - IDS_PowerActionUnknown "ŤĄâ ¤ ­­ëĺ" - IDS_PowerActionSleep "†¤ă騩 ०¨¬" - IDS_PowerActionHibernate "‘Żď騩 ०¨¬" - IDS_PowerActionShutdown "‡ ˘Ąŕ襭¨Ą ŕ ˇ®âë" - IDS_PowerActionRestart "ŹĄŕĄ§ Łŕă§Ş " - IDS_PowerActionShutdownOff "‡ ˘Ąŕ襭¨Ą ŕ ˇ®âë ¨ ˘ëŞ«î祭¨Ą Ż¨â ­¨ď" - IDS_PowerActionWarmEject "‘Żŕ®á¨âě ® ­ă¦­®¬ ¤Ą©á⢨¨" - IDS_PowerActionNone2 "Žâáăâáâ˘ăĄâ" + IDS_PowerActionNone1 "Äĺéńňâčĺ íĺ ňđĺáóĺňń˙" + IDS_PowerActionUnknown "Íĺň äŕííűő" + IDS_PowerActionSleep "Ćäóůčé đĺćčě" + IDS_PowerActionHibernate "Ńď˙ůčé đĺćčě" + IDS_PowerActionShutdown "Çŕâĺđřĺíčĺ đŕáîňű" + IDS_PowerActionRestart "Ďĺđĺçŕăđóçęŕ" + IDS_PowerActionShutdownOff "Çŕâĺđřĺíčĺ đŕáîňű č âűęëţ÷ĺíčĺ ďčňŕíč˙" + IDS_PowerActionWarmEject "Ńďđîńčňü î íóćíîě äĺéńňâčč" + IDS_PowerActionNone2 "Îňńóňńňâóĺň" - IDS_TIMEOUT1 "çĄŕĄ§ 1 ¬¨­" - IDS_TIMEOUT2 "çĄŕĄ§ 2 ¬¨­" - IDS_TIMEOUT3 "çĄŕĄ§ 3 ¬¨­" - IDS_TIMEOUT4 "çĄŕĄ§ 5 ¬¨­" - IDS_TIMEOUT5 "çĄŕĄ§ 10 ¬¨­" - IDS_TIMEOUT6 "çĄŕĄ§ 15 ¬¨­" - IDS_TIMEOUT7 "çĄŕĄ§ 20 ¬¨­" - IDS_TIMEOUT8 "çĄŕĄ§ 25 ¬¨­" - IDS_TIMEOUT9 "çĄŕĄ§ 30 ¬¨­" - IDS_TIMEOUT10 "çĄŕĄ§ 45 ¬¨­" - IDS_TIMEOUT11 "çĄŕĄ§ 1 ç á" - IDS_TIMEOUT12 "çĄŕĄ§ 2 ç á " - IDS_TIMEOUT13 "çĄŕĄ§ 3 ç á " - IDS_TIMEOUT14 "çĄŕĄ§ 4 ç á " - IDS_TIMEOUT15 "çĄŕĄ§ 5 ç á®˘" - IDS_TIMEOUT16 "­¨Ş®Ł¤ " + IDS_TIMEOUT1 "÷ĺđĺç 1 ěčí" + IDS_TIMEOUT2 "÷ĺđĺç 2 ěčí" + IDS_TIMEOUT3 "÷ĺđĺç 3 ěčí" + IDS_TIMEOUT4 "÷ĺđĺç 5 ěčí" + IDS_TIMEOUT5 "÷ĺđĺç 10 ěčí" + IDS_TIMEOUT6 "÷ĺđĺç 15 ěčí" + IDS_TIMEOUT7 "÷ĺđĺç 20 ěčí" + IDS_TIMEOUT8 "÷ĺđĺç 25 ěčí" + IDS_TIMEOUT9 "÷ĺđĺç 30 ěčí" + IDS_TIMEOUT10 "÷ĺđĺç 45 ěčí" + IDS_TIMEOUT11 "÷ĺđĺç 1 ÷ŕń" + IDS_TIMEOUT12 "÷ĺđĺç 2 ÷ŕńŕ" + IDS_TIMEOUT13 "÷ĺđĺç 3 ÷ŕńŕ" + IDS_TIMEOUT14 "÷ĺđĺç 4 ÷ŕńŕ" + IDS_TIMEOUT15 "÷ĺđĺç 5 ÷ŕńîâ" + IDS_TIMEOUT16 "íčęîăäŕ" END From 527fb9fa9b1d48e2f270f01971a045c662a230ab Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Fri, 8 Sep 2006 19:33:33 +0000 Subject: [PATCH 067/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=23976 --- reactos/dll/win32/cabinet/cabinet.h | 8 ++++--- reactos/dll/win32/cabinet/cabinet_main.c | 30 +++++++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/reactos/dll/win32/cabinet/cabinet.h b/reactos/dll/win32/cabinet/cabinet.h index d658cdf31b6..53744afae26 100644 --- a/reactos/dll/win32/cabinet/cabinet.h +++ b/reactos/dll/win32/cabinet/cabinet.h @@ -621,7 +621,7 @@ static const cab_UWORD Zipmask[17] = { struct ExtractFileList { LPSTR filename; struct ExtractFileList *next; - BOOL unknown; /* always 1L */ + BOOL flag; } ; /* the first parameter of the function extract */ @@ -631,8 +631,10 @@ typedef struct { struct ExtractFileList *filelist; /* 0x010 */ long filecount; /* 0x014 */ DWORD flags; /* 0x018 */ - char directory[0x104]; /* 0x01c */ - char lastfile[0x20c]; /* 0x120 */ + char directory[MAX_PATH]; /* 0x01c */ + char lastfile[MAX_PATH]; /* 0x120 */ + char unknown2[MAX_PATH]; /* 0x224 */ + struct ExtractFileList *filterlist; /* 0x328 */ } EXTRACTdest; diff --git a/reactos/dll/win32/cabinet/cabinet_main.c b/reactos/dll/win32/cabinet/cabinet_main.c index fe2739daf3a..ccba93224bb 100644 --- a/reactos/dll/win32/cabinet/cabinet_main.c +++ b/reactos/dll/win32/cabinet/cabinet_main.c @@ -157,7 +157,7 @@ static long fdi_seek(INT_PTR hf, long dist, int seektype) static void fill_file_node(struct ExtractFileList *pNode, LPSTR szFilename) { pNode->next = NULL; - pNode->unknown = TRUE; + pNode->flag = FALSE; pNode->filename = HeapAlloc(GetProcessHeap(), 0, strlen(szFilename) + 1); lstrcpyA(pNode->filename, szFilename); @@ -216,7 +216,8 @@ static INT_PTR fdi_notify_extract(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pf pDestination->filecount++; } - if (pDestination->flags & EXTRACT_EXTRACTFILES) + if ((pDestination->flags & EXTRACT_EXTRACTFILES) || + file_in_list(pDestination->filterlist, pfdin->psz1)) { /* skip this file it it's not in the file list */ if (!file_in_list(pDestination->filelist, pfdin->psz1)) @@ -303,6 +304,7 @@ HRESULT WINAPI Extract(EXTRACTdest *dest, LPCSTR szCabName) HRESULT res = S_OK; HFDI hfdi; ERF erf; + char *str, *path, *name; TRACE("(%p, %s)\n", dest, szCabName); @@ -322,10 +324,32 @@ HRESULT WINAPI Extract(EXTRACTdest *dest, LPCSTR szCabName) if (GetFileAttributesA(dest->directory) == INVALID_FILE_ATTRIBUTES) return S_OK; - if (!FDICopy(hfdi, (LPSTR)szCabName, "", 0, + /* split the cabinet name into path + name */ + str = HeapAlloc(GetProcessHeap(), 0, lstrlenA(szCabName)+1); + if (!str) + { + res = E_OUTOFMEMORY; + goto end; + } + lstrcpyA(str, szCabName); + + path = str; + name = strrchr(path, '\\'); + if (name) + *name++ = 0; + else + { + name = path; + path = NULL; + } + + if (!FDICopy(hfdi, name, path, 0, fdi_notify_extract, NULL, dest)) res = E_FAIL; + HeapFree(GetProcessHeap(), 0, str); +end: + FDIDestroy(hfdi); return res; From 5a367d19d2b9246a46f691575d0e2ab85fd888b6 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Fri, 8 Sep 2006 20:08:45 +0000 Subject: [PATCH 068/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=23977 --- reactos/dll/win32/mpr/auth.c | 2 +- reactos/dll/win32/mpr/mpr.rbuild | 9 ++- reactos/dll/win32/mpr/mpr.rc | 9 ++- reactos/dll/win32/mpr/mpr.spec | 12 ++-- reactos/dll/win32/mpr/mpr_Bg.rc | 2 +- reactos/dll/win32/mpr/mpr_Cs.rc | 19 ++--- reactos/dll/win32/mpr/mpr_De.rc | 2 +- reactos/dll/win32/mpr/mpr_En.rc | 2 +- reactos/dll/win32/mpr/mpr_Eo.rc | 46 ++++++++++++ reactos/dll/win32/mpr/mpr_Es.rc | 2 +- reactos/dll/win32/mpr/mpr_Fr.rc | 2 +- reactos/dll/win32/mpr/mpr_Hu.rc | 17 +++-- reactos/dll/win32/mpr/mpr_It.rc | 23 +++++- reactos/dll/win32/mpr/mpr_Ja.rc | 24 +------ reactos/dll/win32/mpr/mpr_Ko.rc | 2 +- reactos/dll/win32/mpr/mpr_Nl.rc | 2 +- reactos/dll/win32/mpr/mpr_No.rc | 2 +- reactos/dll/win32/mpr/mpr_Pt.rc | 2 +- reactos/dll/win32/mpr/mpr_Ru.rc | 46 ------------ .../dll/win32/mpr/{mpr_Sv.rc => mpr_Tr.rc} | 24 +++---- reactos/dll/win32/mpr/mpr_Uk.rc | 46 ------------ reactos/dll/win32/mpr/mpr_main.c | 2 +- reactos/dll/win32/mpr/mprres.h | 2 +- reactos/dll/win32/mpr/multinet.c | 2 +- reactos/dll/win32/mpr/netspi.h | 2 +- reactos/dll/win32/mpr/nps.c | 70 ++++++++++++++++++- reactos/dll/win32/mpr/pwcache.c | 2 +- reactos/dll/win32/mpr/version.rc | 2 +- reactos/dll/win32/mpr/wnet.c | 34 +++++++-- reactos/dll/win32/mpr/wnetpriv.h | 2 +- 30 files changed, 230 insertions(+), 183 deletions(-) create mode 100644 reactos/dll/win32/mpr/mpr_Eo.rc delete mode 100644 reactos/dll/win32/mpr/mpr_Ru.rc rename reactos/dll/win32/mpr/{mpr_Sv.rc => mpr_Tr.rc} (66%) delete mode 100644 reactos/dll/win32/mpr/mpr_Uk.rc diff --git a/reactos/dll/win32/mpr/auth.c b/reactos/dll/win32/mpr/auth.c index 531ca8a60fe..e2a28a3d83e 100644 --- a/reactos/dll/win32/mpr/auth.c +++ b/reactos/dll/win32/mpr/auth.c @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/reactos/dll/win32/mpr/mpr.rbuild b/reactos/dll/win32/mpr/mpr.rbuild index 41189f1eadd..5db8307bacb 100644 --- a/reactos/dll/win32/mpr/mpr.rbuild +++ b/reactos/dll/win32/mpr/mpr.rbuild @@ -2,18 +2,17 @@ . include/reactos/wine - - + 0x600 0x501 0x501 wine - ntdll - kernel32 - advapi32 user32 + advapi32 + kernel32 + ntdll auth.c mpr_main.c multinet.c diff --git a/reactos/dll/win32/mpr/mpr.rc b/reactos/dll/win32/mpr/mpr.rc index 418d41d4e9a..aa7db7fa693 100644 --- a/reactos/dll/win32/mpr/mpr.rc +++ b/reactos/dll/win32/mpr/mpr.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "windef.h" #include "winbase.h" @@ -28,15 +28,14 @@ #include "mpr_Cs.rc" #include "mpr_De.rc" #include "mpr_En.rc" +#include "mpr_Eo.rc" #include "mpr_Es.rc" #include "mpr_Fr.rc" +#include "mpr_Hu.rc" #include "mpr_It.rc" #include "mpr_Ja.rc" #include "mpr_Ko.rc" #include "mpr_Nl.rc" #include "mpr_No.rc" #include "mpr_Pt.rc" -#include "mpr_Ru.rc" -#include "mpr_Sv.rc" -#include "mpr_Hu.rc" -#include "mpr_Uk.rc" +#include "mpr_Tr.rc" diff --git a/reactos/dll/win32/mpr/mpr.spec b/reactos/dll/win32/mpr/mpr.spec index c383c75966a..53466155f03 100644 --- a/reactos/dll/win32/mpr/mpr.spec +++ b/reactos/dll/win32/mpr/mpr.spec @@ -40,12 +40,12 @@ @ stdcall NPSNotifyRegisterA(long ptr) @ stdcall NPSSetCustomTextA(str) @ stdcall NPSSetExtendedErrorA(long str) -@ stub PwdChangePasswordA -@ stub PwdChangePasswordW -@ stub PwdGetPasswordStatusA -@ stub PwdGetPasswordStatusW -@ stub PwdSetPasswordStatusA -@ stub PwdSetPasswordStatusW +@ stdcall PwdChangePasswordA(str ptr long ptr) +@ stdcall PwdChangePasswordW(wstr ptr long ptr) +@ stdcall PwdGetPasswordStatusA(str long ptr) +@ stdcall PwdGetPasswordStatusW(wstr long ptr) +@ stdcall PwdSetPasswordStatusA(str long long) +@ stdcall PwdSetPasswordStatusW(wstr long long) @ stdcall WNetAddConnection2A(ptr str str long) @ stdcall WNetAddConnection2W(ptr wstr wstr long) @ stdcall WNetAddConnection3A(long ptr str str long) diff --git a/reactos/dll/win32/mpr/mpr_Bg.rc b/reactos/dll/win32/mpr/mpr_Bg.rc index 615e0938b85..a37f7961be1 100644 --- a/reactos/dll/win32/mpr/mpr_Bg.rc +++ b/reactos/dll/win32/mpr/mpr_Bg.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT diff --git a/reactos/dll/win32/mpr/mpr_Cs.rc b/reactos/dll/win32/mpr/mpr_Cs.rc index cda57e32d63..6085e7160c6 100644 --- a/reactos/dll/win32/mpr/mpr_Cs.rc +++ b/reactos/dll/win32/mpr/mpr_Cs.rc @@ -1,4 +1,5 @@ -/* +/* Hey, Emacs, open this file with -*- coding: cp1250 -*- + * * Czech MPR dll resources * Copyright (C) 2004 Juan Lang * Copyright (C) 2004, 2005 David Kredba @@ -15,32 +16,34 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +/* Czech strings in CP1250 */ + STRINGTABLE DISCARDABLE { - IDS_ENTIRENETWORK "Celá sí»" + IDS_ENTIRENETWORK "Celá síť" } IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Zadání sí»ového hesla" +CAPTION "Zadání síťového hesla" FONT 8, "MS Shell Dlg" { - LTEXT "Prosím zadejte své uľivatelské jméno a heslo:", IDC_EXPLAIN, 40, 6, 150, 15 + LTEXT "Prosím zadejte své uživatelské jméno a heslo:", IDC_EXPLAIN, 40, 6, 150, 15 LTEXT "Proxy", -1, 40, 26, 50, 10 /* LTEXT "Realm", -1, 40, 46, 50, 10 */ - LTEXT "Uľivatel", -1, 40, 66, 50, 10 + LTEXT "Uživatel", -1, 40, 66, 50, 10 LTEXT "Heslo", -1, 40, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Uloľit toto heslo (Není bezpečné) ?", IDC_SAVEPASSWORD, + CHECKBOX "&Uložit toto heslo (Není bezpečné) ?", IDC_SAVEPASSWORD, 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Zruąit", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Zrušit", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } diff --git a/reactos/dll/win32/mpr/mpr_De.rc b/reactos/dll/win32/mpr/mpr_De.rc index a91f7b33e92..9ce8398d32c 100644 --- a/reactos/dll/win32/mpr/mpr_De.rc +++ b/reactos/dll/win32/mpr/mpr_De.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT diff --git a/reactos/dll/win32/mpr/mpr_En.rc b/reactos/dll/win32/mpr/mpr_En.rc index 461a53924ac..c71840423f4 100644 --- a/reactos/dll/win32/mpr/mpr_En.rc +++ b/reactos/dll/win32/mpr/mpr_En.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT diff --git a/reactos/dll/win32/mpr/mpr_Eo.rc b/reactos/dll/win32/mpr/mpr_Eo.rc new file mode 100644 index 00000000000..0ed9f470d40 --- /dev/null +++ b/reactos/dll/win32/mpr/mpr_Eo.rc @@ -0,0 +1,46 @@ +/* + * MPR dll resources - Esperanto Language Support + * + * Copyright 2006 Antonio Codazzi + * + * 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 + */ + +LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Tuta Reto" +} + +IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Enmetu Retan Pasvorton" +FONT 8, "MS Shell Dlg" +{ +LTEXT "Enmetu uzantonomon kaj pasvorton:", IDC_EXPLAIN, 40, 6, 150, 15 +LTEXT "Proxy", -1, 40, 26, 50, 10 +/* LTEXT "Realm", -1, 40, 46, 50, 10 */ +LTEXT "Uzanto", -1, 40, 66, 50, 10 +LTEXT "Pasvorto", -1, 40, 86, 50, 10 +LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 +LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 +EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP +EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD +CHECKBOX "&Storu pasvorton ( RISKE! )", IDC_SAVEPASSWORD, +80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP +PUSHBUTTON "Bone", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON +PUSHBUTTON "Rezigni", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP +} diff --git a/reactos/dll/win32/mpr/mpr_Es.rc b/reactos/dll/win32/mpr/mpr_Es.rc index 370e3cf14c5..d82758cbeae 100644 --- a/reactos/dll/win32/mpr/mpr_Es.rc +++ b/reactos/dll/win32/mpr/mpr_Es.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL diff --git a/reactos/dll/win32/mpr/mpr_Fr.rc b/reactos/dll/win32/mpr/mpr_Fr.rc index 5e2d9997261..ba43eefa077 100644 --- a/reactos/dll/win32/mpr/mpr_Fr.rc +++ b/reactos/dll/win32/mpr/mpr_Fr.rc @@ -16,7 +16,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL diff --git a/reactos/dll/win32/mpr/mpr_Hu.rc b/reactos/dll/win32/mpr/mpr_Hu.rc index df01bb32706..d3561cb3fe6 100644 --- a/reactos/dll/win32/mpr/mpr_Hu.rc +++ b/reactos/dll/win32/mpr/mpr_Hu.rc @@ -1,8 +1,7 @@ /* * MPR dll resources * - * Copyright (C) 2004 Juan Lang - * Copyright (C) 2005 Gergely Risko + * Copyright (C) 2006 Andras Kovacs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,31 +15,31 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_HUNGARIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { - IDS_ENTIRENETWORK "Teljes álózat" + IDS_ENTIRENETWORK "Teljes hálózat" } IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Hálózati Bejelentkezés" +CAPTION "Hálózati jelszó megadása" FONT 8, "MS Shell Dlg" { - LTEXT "Írd be a felhasználó nevet és jelszót:", IDC_EXPLAIN, 40, 6, 150, 15 + LTEXT "Kérem adja meg a felhasználónevét és jelszavát:", IDC_EXPLAIN, 40, 6, 150, 15 LTEXT "Proxy", -1, 40, 26, 50, 10 /* LTEXT "Realm", -1, 40, 46, 50, 10 */ - LTEXT "Felhasználó", -1, 40, 66, 50, 10 + LTEXT "Felhasználónév", -1, 40, 66, 50, 10 LTEXT "Jelszó", -1, 40, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "Jelszó &mentése (Nem biztonságos)", IDC_SAVEPASSWORD, + CHECKBOX "&Jelszó mentése (nem biztonságos)", IDC_SAVEPASSWORD, 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON PUSHBUTTON "Mégse", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mpr/mpr_It.rc b/reactos/dll/win32/mpr/mpr_It.rc index 1a733729a14..efd6f2a6d39 100644 --- a/reactos/dll/win32/mpr/mpr_It.rc +++ b/reactos/dll/win32/mpr/mpr_It.rc @@ -2,6 +2,7 @@ * MPR dll Italian resources * * Copyright 2004 Ivan Leo Puoti + * Copyright 2006 Antonio Codazzi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -15,7 +16,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT @@ -24,3 +25,23 @@ STRINGTABLE DISCARDABLE { IDS_ENTIRENETWORK "Tutta la rete" } + +IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Inserisci la Password di Rete" +FONT 8, "MS Shell Dlg" +{ +LTEXT "Inserire nome utente e password:", IDC_EXPLAIN, 40, 6, 150, 15 +LTEXT "Proxy", -1, 40, 26, 50, 10 +/* LTEXT "Realm", -1, 40, 46, 50, 10 */ +LTEXT "Utente", -1, 40, 66, 50, 10 +LTEXT "Password", -1, 40, 86, 50, 10 +LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 +LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 +EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP +EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD +CHECKBOX "&Memorizza la password ( RISCHIOSO! )", IDC_SAVEPASSWORD, +80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP +PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON +PUSHBUTTON "Annulla", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP +} diff --git a/reactos/dll/win32/mpr/mpr_Ja.rc b/reactos/dll/win32/mpr/mpr_Ja.rc index 9481b09e619..08fdfd00822 100644 --- a/reactos/dll/win32/mpr/mpr_Ja.rc +++ b/reactos/dll/win32/mpr/mpr_Ja.rc @@ -15,32 +15,12 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_JAPANESE, SUBLANG_NEUTRAL +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { IDS_ENTIRENETWORK "lbgŹ[N‘S‘Ě" } - -IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "lbgŹ[NpXŹ[h‚Ě“ü—Í" -FONT 9, "MS UI Gothic" -{ - LTEXT "†[U[–Ľ‚ĆpXŹ[h‚đ“ü—Í‚µ‚ĉş‚ł‚˘:", IDC_EXPLAIN, 40, 6, 150, 15 - LTEXT "vŤLV", -1, 40, 26, 50, 10 -/* LTEXT "Realm", -1, 40, 46, 50, 10 */ - LTEXT "†[U–Ľ", -1, 40, 66, 50, 10 - LTEXT "pXŹ[h", -1, 40, 86, 50, 10 - LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "pXŹ[h‚đ•Ű‘¶‚·‚é(&S) (Ŕ‘S‚ł͂ ‚č‚Ü‚ą‚ń)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "L“Z‹", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} diff --git a/reactos/dll/win32/mpr/mpr_Ko.rc b/reactos/dll/win32/mpr/mpr_Ko.rc index d4481220da3..96411656c1a 100644 --- a/reactos/dll/win32/mpr/mpr_Ko.rc +++ b/reactos/dll/win32/mpr/mpr_Ko.rc @@ -16,7 +16,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT diff --git a/reactos/dll/win32/mpr/mpr_Nl.rc b/reactos/dll/win32/mpr/mpr_Nl.rc index a0569cc6613..f22bd789cd6 100644 --- a/reactos/dll/win32/mpr/mpr_Nl.rc +++ b/reactos/dll/win32/mpr/mpr_Nl.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT diff --git a/reactos/dll/win32/mpr/mpr_No.rc b/reactos/dll/win32/mpr/mpr_No.rc index 60b7acd6ec5..32833542db9 100644 --- a/reactos/dll/win32/mpr/mpr_No.rc +++ b/reactos/dll/win32/mpr/mpr_No.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL diff --git a/reactos/dll/win32/mpr/mpr_Pt.rc b/reactos/dll/win32/mpr/mpr_Pt.rc index e22c49c8cf7..74523d176ba 100644 --- a/reactos/dll/win32/mpr/mpr_Pt.rc +++ b/reactos/dll/win32/mpr/mpr_Pt.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT diff --git a/reactos/dll/win32/mpr/mpr_Ru.rc b/reactos/dll/win32/mpr/mpr_Ru.rc deleted file mode 100644 index bd821b4e107..00000000000 --- a/reactos/dll/win32/mpr/mpr_Ru.rc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * MPR dll resources - * - * Copyright (C) 2005 Mikhail Y. Zvyozdochkin - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT - -STRINGTABLE DISCARDABLE -{ - IDS_ENTIRENETWORK "Âń˙ ńĺňü" -} - -IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Ââĺäčňĺ Ńĺňĺâîé Ďŕđîëü" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Ďîćŕëóéńňŕ, ââĺäčňĺ Âŕřč čě˙ č ďŕđîëü:", IDC_EXPLAIN, 40, 6, 150, 15 - LTEXT "Ďđîęńč-ńĺđâĺđ", -1, 40, 26, 50, 10 -/* LTEXT "Realm", -1, 40, 46, 50, 10 */ - LTEXT "Čě˙ ďîëüçîâŕňĺë˙", -1, 40, 66, 50, 10 - LTEXT "Ďŕđîëü", -1, 40, 86, 50, 10 - LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Ńîőđŕíčňü ďŕđîëü (íĺáĺçîďŕńíî)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Îňěĺíŕ", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} diff --git a/reactos/dll/win32/mpr/mpr_Sv.rc b/reactos/dll/win32/mpr/mpr_Tr.rc similarity index 66% rename from reactos/dll/win32/mpr/mpr_Sv.rc rename to reactos/dll/win32/mpr/mpr_Tr.rc index b1ee8daa299..b9f3af1fa03 100644 --- a/reactos/dll/win32/mpr/mpr_Sv.rc +++ b/reactos/dll/win32/mpr/mpr_Tr.rc @@ -1,7 +1,7 @@ /* - * MPR dll Swedish resources + * MPR dll resources for Turkish * - * Copyright (C) 2005 Andreas Bjerkeholt + * Copyright (C) 2006 Fatih Aţýcý * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -15,32 +15,32 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { - IDS_ENTIRENETWORK "Hela nätverket" + IDS_ENTIRENETWORK "Tüm Ađ" } IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Ange nätverkslösenord" +CAPTION "Ađ Parolanýzý Girin" FONT 8, "MS Shell Dlg" { - LTEXT "Ange ditt användarnamn och lösenord:", IDC_EXPLAIN, 40, 6, 150, 15 + LTEXT "Lütfen kullanýcý adýnýzý ve parolanýzý girin:", IDC_EXPLAIN, 40, 6, 150, 15 LTEXT "Proxy", -1, 40, 26, 50, 10 /* LTEXT "Realm", -1, 40, 46, 50, 10 */ - LTEXT "Användare", -1, 40, 66, 50, 10 - LTEXT "Lösenord", -1, 40, 86, 50, 10 + LTEXT "Kullanýcý", -1, 40, 66, 50, 10 + LTEXT "Parola", -1, 40, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Spara detta lösenord (Osäkert)", IDC_SAVEPASSWORD, + CHECKBOX "Bu parolayý &sakla (Güvensiz)", IDC_SAVEPASSWORD, 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Avbryt", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Tamam", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Ýptal", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } diff --git a/reactos/dll/win32/mpr/mpr_Uk.rc b/reactos/dll/win32/mpr/mpr_Uk.rc deleted file mode 100644 index c5181f11208..00000000000 --- a/reactos/dll/win32/mpr/mpr_Uk.rc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * MPR dll resources (Ukrainian) - * - * Copyright 2006 Artem Reznikov - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT - -STRINGTABLE DISCARDABLE -{ - IDS_ENTIRENETWORK "Âń˙ Ěĺđĺćŕ" -} - -IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Ââĺäłňü Ěĺđĺćíčé Ďŕđîëü" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Áóäü ëŕńęŕ, ââĺäłňü Âŕřł łě'˙ ňŕ ďŕđîëü:", IDC_EXPLAIN, 40, 6, 150, 15 - LTEXT "Ďđîęńł", -1, 40, 26, 50, 10 -/* LTEXT "Realm", -1, 40, 46, 50, 10 */ - LTEXT "Ęîđčńňóâŕ÷", -1, 40, 66, 50, 10 - LTEXT "Ďŕđîëü", -1, 40, 86, 50, 10 - LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Çáĺđĺăňč öĺé ďŕđîëü (íĺáĺçďĺ÷íî)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Ńęŕńóâŕňč", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} diff --git a/reactos/dll/win32/mpr/mpr_main.c b/reactos/dll/win32/mpr/mpr_main.c index b9446496150..3f9ea4a3c21 100644 --- a/reactos/dll/win32/mpr/mpr_main.c +++ b/reactos/dll/win32/mpr/mpr_main.c @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/reactos/dll/win32/mpr/mprres.h b/reactos/dll/win32/mpr/mprres.h index fa9cf8be7d6..292b4765260 100644 --- a/reactos/dll/win32/mpr/mprres.h +++ b/reactos/dll/win32/mpr/mprres.h @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_MPRRES_H__ #define __WINE_MPRRES_H__ diff --git a/reactos/dll/win32/mpr/multinet.c b/reactos/dll/win32/mpr/multinet.c index aa8cfb8908b..6c550e243a3 100644 --- a/reactos/dll/win32/mpr/multinet.c +++ b/reactos/dll/win32/mpr/multinet.c @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/reactos/dll/win32/mpr/netspi.h b/reactos/dll/win32/mpr/netspi.h index 7695584aec2..0a82475931a 100644 --- a/reactos/dll/win32/mpr/netspi.h +++ b/reactos/dll/win32/mpr/netspi.h @@ -18,7 +18,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef _NETSPI_H_ diff --git a/reactos/dll/win32/mpr/nps.c b/reactos/dll/win32/mpr/nps.c index 7fe15565b89..044fcb8a6bb 100644 --- a/reactos/dll/win32/mpr/nps.c +++ b/reactos/dll/win32/mpr/nps.c @@ -16,7 +16,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" @@ -211,3 +211,71 @@ LPVOID WINAPI NPSNotifyGetContextA( NOTIFYCALLBACK pfNotifyCallBack ) FIXME( "(%p): stub\n", pfNotifyCallBack ); return NULL; } + +/***************************************************************** + * PwdGetPasswordStatusA [MPR.@] + */ +DWORD WINAPI PwdGetPasswordStatusA( LPCSTR lpProvider, DWORD dwIndex, LPDWORD status ) +{ + FIXME("%s %ld %p\n", debugstr_a(lpProvider), dwIndex, status ); + *status = 0; + return WN_SUCCESS; +} + +/***************************************************************** + * PwdGetPasswordStatusA [MPR.@] + */ +DWORD WINAPI PwdGetPasswordStatusW( LPCWSTR lpProvider, DWORD dwIndex, LPDWORD status ) +{ + FIXME("%s %ld %p\n", debugstr_w(lpProvider), dwIndex, status ); + *status = 0; + return WN_SUCCESS; +} + +/***************************************************************** + * PwdSetPasswordStatusA [MPR.@] + */ +DWORD WINAPI PwdSetPasswordStatusA( LPCSTR lpProvider, DWORD dwIndex, DWORD status ) +{ + FIXME("%s %ld %ld\n", debugstr_a(lpProvider), dwIndex, status ); + return WN_SUCCESS; +} + +/***************************************************************** + * PwdSetPasswordStatusW [MPR.@] + */ +DWORD WINAPI PwdSetPasswordStatusW( LPCWSTR lpProvider, DWORD dwIndex, DWORD status ) +{ + FIXME("%s %ld %ld\n", debugstr_w(lpProvider), dwIndex, status ); + return WN_SUCCESS; +} + +typedef struct _CHANGEPWDINFOA { + LPSTR lpUsername; + LPSTR lpPassword; + DWORD cbPassword; +} CHANGEPWDINFOA, *LPCHANGEPWDINFOA; + +typedef struct _CHANGEPWDINFOW { + LPWSTR lpUsername; + LPWSTR lpPassword; + DWORD cbPassword; +} CHANGEPWDINFOW, *LPCHANGEPWDINFOW; + +/***************************************************************** + * PwdChangePasswordA [MPR.@] + */ +DWORD WINAPI PwdChangePasswordA( LPCSTR lpProvider, HWND hWnd, DWORD flags, LPCHANGEPWDINFOA info ) +{ + FIXME("%s %p %lx %p\n", debugstr_a(lpProvider), hWnd, flags, info ); + return WN_SUCCESS; +} + +/***************************************************************** + * PwdChangePasswordA [MPR.@] + */ +DWORD WINAPI PwdChangePasswordW( LPCWSTR lpProvider, HWND hWnd, DWORD flags, LPCHANGEPWDINFOW info ) +{ + FIXME("%s %p %lx %p\n", debugstr_w(lpProvider), hWnd, flags, info ); + return WN_SUCCESS; +} diff --git a/reactos/dll/win32/mpr/pwcache.c b/reactos/dll/win32/mpr/pwcache.c index 682ec4cecfa..b1d9112d644 100644 --- a/reactos/dll/win32/mpr/pwcache.c +++ b/reactos/dll/win32/mpr/pwcache.c @@ -16,7 +16,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/reactos/dll/win32/mpr/version.rc b/reactos/dll/win32/mpr/version.rc index f22cc4d5ba1..c27f9c78889 100644 --- a/reactos/dll/win32/mpr/version.rc +++ b/reactos/dll/win32/mpr/version.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define WINE_FILEDESCRIPTION_STR "Wine Multiprotocol Router Library" diff --git a/reactos/dll/win32/mpr/wnet.c b/reactos/dll/win32/mpr/wnet.c index 3b585c07b13..804b4571322 100644 --- a/reactos/dll/win32/mpr/wnet.c +++ b/reactos/dll/win32/mpr/wnet.c @@ -16,13 +16,12 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include "windef.h" #include "winbase.h" -#include "winuser.h" #include "winnls.h" #include "winnetwk.h" #include "npapi.h" @@ -654,7 +653,7 @@ DWORD WINAPI WNetOpenEnumA( DWORD dwScope, DWORD dwType, DWORD dwUsage, if (ret == WN_SUCCESS) ret = WNetOpenEnumW(dwScope, dwType, dwUsage, lpNetWide, lphEnum); - if (allocated && lpNetWide) + if (allocated) HeapFree(GetProcessHeap(), 0, lpNetWide); } else @@ -1712,11 +1711,36 @@ DWORD WINAPI WNetGetUniversalNameA ( LPCSTR lpLocalPath, DWORD dwInfoLevel, DWORD WINAPI WNetGetUniversalNameW ( LPCWSTR lpLocalPath, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpBufferSize ) { + LPUNIVERSAL_NAME_INFOW uniw; + DWORD err, len; + FIXME( "(%s, 0x%08lX, %p, %p): stub\n", debugstr_w(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize); - SetLastError(WN_NO_NETWORK); - return WN_NO_NETWORK; + switch (dwInfoLevel) + { + case UNIVERSAL_NAME_INFO_LEVEL: + err = WN_MORE_DATA; + len = sizeof (*uniw) + lstrlenW(lpLocalPath); + if (*lpBufferSize <= len) + break; + uniw = lpBuffer; + uniw->lpUniversalName = (LPWSTR) &uniw[1]; + lstrcpyW(uniw->lpUniversalName, lpLocalPath); + *lpBufferSize = len; + err = WN_NO_ERROR; + break; + + case REMOTE_NAME_INFO_LEVEL: + err = WN_NO_NETWORK; + break; + + default: + err = WN_BAD_VALUE; + } + + SetLastError(err); + return err; } diff --git a/reactos/dll/win32/mpr/wnetpriv.h b/reactos/dll/win32/mpr/wnetpriv.h index 7a275de1445..7a329029f3d 100644 --- a/reactos/dll/win32/mpr/wnetpriv.h +++ b/reactos/dll/win32/mpr/wnetpriv.h @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WNET_PRIV_H__ From 8377230a7ba319c48e4f5322ca92529a4c582646 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Fri, 8 Sep 2006 20:12:06 +0000 Subject: [PATCH 069/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=23978 --- reactos/dll/win32/oledlg/insobjdlg.c | 2 +- reactos/dll/win32/oledlg/oledlg_Ko.rc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/oledlg/insobjdlg.c b/reactos/dll/win32/oledlg/insobjdlg.c index e13917ca634..8928b35acc4 100644 --- a/reactos/dll/win32/oledlg/insobjdlg.c +++ b/reactos/dll/win32/oledlg/insobjdlg.c @@ -73,7 +73,7 @@ static void UIINSERTOBJECTDLG_AddControl(InsertObjectDlgInfo* pdlgInfo); typedef HRESULT (*DLLREGISTER) (void); extern HINSTANCE OLEDLG_hInstance; -const char *OleUIInsertObjectInfoStr = "OleUIInsertObjectInfoStr"; +static const char OleUIInsertObjectInfoStr[] = "OleUIInsertObjectInfoStr"; /*********************************************************************** * OleUIInsertObjectA (OLEDLG.3) diff --git a/reactos/dll/win32/oledlg/oledlg_Ko.rc b/reactos/dll/win32/oledlg/oledlg_Ko.rc index 29827ccefa0..b29ef980f8c 100644 --- a/reactos/dll/win32/oledlg/oledlg_Ko.rc +++ b/reactos/dll/win32/oledlg/oledlg_Ko.rc @@ -51,5 +51,5 @@ STRINGTABLE DISCARDABLE IDS_RESULTFILEOBJDESC "ŔŰĽşÇŃ Ç®±×¸˛Ŕ» »çżëÇĎż© ȰĽşČ­˝ĂĹłĽö ŔÖ´Â °´ĂĽ¸¦ ą®Ľ­ĆÄŔĎ ł»żëŔ¸·Î »đŔÔÇϽÿŔ." IDS_BROWSE "ĂŁ±â" IDS_NOTOLEMOD "ŔĚ ĆÄŔĎŔş żĂąŮ¸Ą OLE¸đµâŔĚ ľĆ´Ń°Ĺ·Î ş¸ŔÔ´Ď´Ů. OLEÄÁĆ®·ŃŔ» µî·ĎÇŇĽö ľř˝Ŕ´Ď´Ů." - IDS_NOTOLEMODCAPTION "ÄÜĆ®·Ń Ăß°ˇ" + IDS_NOTOLEMODCAPTION "ÄÁĆ®·Ń ´őÇϱâ" } From 1869f86db688fc5a0d6743bae2040b10f9da0d35 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Fri, 8 Sep 2006 20:13:51 +0000 Subject: [PATCH 070/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=23979 --- reactos/dll/win32/uxtheme/msstyles.c | 255 ++++++++++++++++++++++++--- reactos/dll/win32/uxtheme/system.c | 88 +++++++-- 2 files changed, 307 insertions(+), 36 deletions(-) diff --git a/reactos/dll/win32/uxtheme/msstyles.c b/reactos/dll/win32/uxtheme/msstyles.c index 76414d90867..9225206d002 100644 --- a/reactos/dll/win32/uxtheme/msstyles.c +++ b/reactos/dll/win32/uxtheme/msstyles.c @@ -25,9 +25,9 @@ #include "windef.h" #include "winbase.h" +#include "wingdi.h" #include "winuser.h" #include "winnls.h" -#include "wingdi.h" #include "uxtheme.h" #include "tmschema.h" @@ -46,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); BOOL MSSTYLES_GetNextInteger(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, int *value); BOOL MSSTYLES_GetNextToken(LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LPWSTR lpBuff, DWORD buffSize); void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics); +HRESULT MSSTYLES_GetFont (LPCWSTR lpStringStart, LPCWSTR lpStringEnd, LPCWSTR *lpValEnd, LOGFONTW* logfont); extern HINSTANCE hDllInst; extern int alphaBlendMode; @@ -664,6 +665,185 @@ static PTHEME_PROPERTY MSSTYLES_AddMetric(PTHEME_FILE tf, int iPropertyPrimitive return cur; } +/* Color-related state for theme ini parsing */ +struct PARSECOLORSTATE +{ + int colorCount; + int colorElements[TMT_LASTCOLOR-TMT_FIRSTCOLOR]; + COLORREF colorRgb[TMT_LASTCOLOR-TMT_FIRSTCOLOR]; + int captionColors; +}; + +inline void parse_init_color (struct PARSECOLORSTATE* state) +{ + memset (state, 0, sizeof (*state)); +} + +static BOOL parse_handle_color_property (struct PARSECOLORSTATE* state, + int iPropertyId, LPCWSTR lpValue, + DWORD dwValueLen) +{ + int r,g,b; + LPCWSTR lpValueEnd = lpValue + dwValueLen; + MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &r); + MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &g); + if(MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &b)) { + state->colorElements[state->colorCount] = iPropertyId - TMT_FIRSTCOLOR; + state->colorRgb[state->colorCount++] = RGB(r,g,b); + switch (iPropertyId) + { + case TMT_ACTIVECAPTION: + state->captionColors |= 0x1; + break; + case TMT_INACTIVECAPTION: + state->captionColors |= 0x2; + break; + case TMT_GRADIENTACTIVECAPTION: + state->captionColors |= 0x4; + break; + case TMT_GRADIENTINACTIVECAPTION: + state->captionColors |= 0x8; + break; + } + return TRUE; + } + else { + return FALSE; + } +} + +static void parse_apply_color (struct PARSECOLORSTATE* state) +{ + if (state->colorCount > 0) + SetSysColors(state->colorCount, state->colorElements, state->colorRgb); + if (state->captionColors == 0xf) + SystemParametersInfoW (SPI_SETGRADIENTCAPTIONS, 0, (PVOID)TRUE, 0); +} + +/* Non-client-metrics-related state for theme ini parsing */ +struct PARSENONCLIENTSTATE +{ + NONCLIENTMETRICSW metrics; + BOOL metricsDirty; + LOGFONTW iconTitleFont; +}; + +inline void parse_init_nonclient (struct PARSENONCLIENTSTATE* state) +{ + memset (state, 0, sizeof (*state)); + state->metrics.cbSize = sizeof (NONCLIENTMETRICSW); + SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof (NONCLIENTMETRICSW), + (PVOID)&state->metrics, 0); + SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (LOGFONTW), + (PVOID)&state->iconTitleFont, 0); +} + +static BOOL parse_handle_nonclient_font (struct PARSENONCLIENTSTATE* state, + int iPropertyId, LPCWSTR lpValue, + DWORD dwValueLen) +{ + LOGFONTW font; + + memset (&font, 0, sizeof (font)); + if (SUCCEEDED (MSSTYLES_GetFont (lpValue, lpValue + dwValueLen, &lpValue, + &font))) + { + switch (iPropertyId) + { + case TMT_CAPTIONFONT: + memcpy (&state->metrics.lfCaptionFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_SMALLCAPTIONFONT: + memcpy (&state->metrics.lfSmCaptionFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_MENUFONT: + memcpy (&state->metrics.lfMenuFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_STATUSFONT: + memcpy (&state->metrics.lfStatusFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_MSGBOXFONT: + memcpy (&state->metrics.lfMessageFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + case TMT_ICONTITLEFONT: + memcpy (&state->iconTitleFont, &font, sizeof (LOGFONTW)); + state->metricsDirty = TRUE; + break; + } + return TRUE; + } + else + return FALSE; +} + +static BOOL parse_handle_nonclient_size (struct PARSENONCLIENTSTATE* state, + int iPropertyId, LPCWSTR lpValue, + DWORD dwValueLen) +{ + int size; + LPCWSTR lpValueEnd = lpValue + dwValueLen; + if(MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &size)) { + switch (iPropertyId) + { + case TMT_SIZINGBORDERWIDTH: + state->metrics.iBorderWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_SCROLLBARWIDTH: + state->metrics.iScrollWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_SCROLLBARHEIGHT: + state->metrics.iScrollHeight = size; + state->metricsDirty = TRUE; + break; + case TMT_CAPTIONBARWIDTH: + state->metrics.iCaptionWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_CAPTIONBARHEIGHT: + state->metrics.iCaptionHeight = size; + state->metricsDirty = TRUE; + break; + case TMT_SMCAPTIONBARWIDTH: + state->metrics.iSmCaptionWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_SMCAPTIONBARHEIGHT: + state->metrics.iSmCaptionHeight = size; + state->metricsDirty = TRUE; + break; + case TMT_MENUBARWIDTH: + state->metrics.iMenuWidth = size; + state->metricsDirty = TRUE; + break; + case TMT_MENUBARHEIGHT: + state->metrics.iMenuHeight = size; + state->metricsDirty = TRUE; + break; + } + return TRUE; + } + else + return FALSE; +} + +static void parse_apply_nonclient (struct PARSENONCLIENTSTATE* state) +{ + if (state->metricsDirty) + { + SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, sizeof (state->metrics), + (PVOID)&state->metrics, 0); + SystemParametersInfoW (SPI_SETICONTITLELOGFONT, sizeof (state->iconTitleFont), + (PVOID)&state->iconTitleFont, 0); + } +} + /*********************************************************************** * MSSTYLES_ParseThemeIni * @@ -696,31 +876,41 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) while((lpName=UXINI_GetNextSection(ini, &dwLen))) { if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpName, dwLen, szSysMetrics, -1) == CSTR_EQUAL) { - int colorCount = 0; - int colorElements[TMT_LASTCOLOR-TMT_FIRSTCOLOR]; - COLORREF colorRgb[TMT_LASTCOLOR-TMT_FIRSTCOLOR]; - LPCWSTR lpValueEnd; + struct PARSECOLORSTATE colorState; + struct PARSENONCLIENTSTATE nonClientState; + + parse_init_color (&colorState); + parse_init_nonclient (&nonClientState); while((lpName=UXINI_GetNextValue(ini, &dwLen, &lpValue, &dwValueLen))) { lstrcpynW(szPropertyName, lpName, min(dwLen+1, sizeof(szPropertyName)/sizeof(szPropertyName[0]))); if(MSSTYLES_LookupProperty(szPropertyName, &iPropertyPrimitive, &iPropertyId)) { if(iPropertyId >= TMT_FIRSTCOLOR && iPropertyId <= TMT_LASTCOLOR) { - int r,g,b; - lpValueEnd = lpValue + dwValueLen; - MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &r); - MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &g); - if(MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &b)) { - colorElements[colorCount] = iPropertyId - TMT_FIRSTCOLOR; - colorRgb[colorCount++] = RGB(r,g,b); - } - else { - FIXME("Invalid color value for %s\n", debugstr_w(szPropertyName)); - } + if (!parse_handle_color_property (&colorState, iPropertyId, + lpValue, dwValueLen)) + FIXME("Invalid color value for %s\n", + debugstr_w(szPropertyName)); } else if (setMetrics && (iPropertyId == TMT_FLATMENUS)) { BOOL flatMenus = (*lpValue == 'T') || (*lpValue == 't'); SystemParametersInfoW (SPI_SETFLATMENU, 0, (PVOID)(INT_PTR)flatMenus, 0); } + else if ((iPropertyId >= TMT_FIRSTFONT) + && (iPropertyId <= TMT_LASTFONT)) + { + if (!parse_handle_nonclient_font (&nonClientState, + iPropertyId, lpValue, dwValueLen)) + FIXME("Invalid font value for %s\n", + debugstr_w(szPropertyName)); + } + else if ((iPropertyId >= TMT_FIRSTSIZE) + && (iPropertyId <= TMT_LASTSIZE)) + { + if (!parse_handle_nonclient_size (&nonClientState, + iPropertyId, lpValue, dwValueLen)) + FIXME("Invalid size value for %s\n", + debugstr_w(szPropertyName)); + } /* Catch all metrics, including colors */ MSSTYLES_AddMetric(tf, iPropertyPrimitive, iPropertyId, lpValue, dwValueLen); } @@ -728,8 +918,11 @@ void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) TRACE("Unknown system metric %s\n", debugstr_w(szPropertyName)); } } - if (setMetrics && (colorCount > 0)) - SetSysColors(colorCount, colorElements, colorRgb); + if (setMetrics) + { + parse_apply_color (&colorState); + parse_apply_nonclient (&nonClientState); + } continue; } if(MSSTYLES_ParseIniSectionName(lpName, dwLen, szAppName, szClassName, &iPartId, &iStateId)) { @@ -1032,7 +1225,8 @@ HRESULT MSSTYLES_GetPropertyColor(PTHEME_PROPERTY tp, COLORREF *pColor) * * Retrieve a color value for a property */ -HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) +HRESULT MSSTYLES_GetFont (LPCWSTR lpCur, LPCWSTR lpEnd, + LPCWSTR *lpValEnd, LOGFONTW* pFont) { static const WCHAR szBold[] = {'b','o','l','d','\0'}; static const WCHAR szItalic[] = {'i','t','a','l','i','c','\0'}; @@ -1040,20 +1234,18 @@ HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) static const WCHAR szStrikeOut[] = {'s','t','r','i','k','e','o','u','t','\0'}; int pointSize; WCHAR attr[32]; - LPCWSTR lpCur = tp->lpValue; - LPCWSTR lpEnd = tp->lpValue + tp->dwValueLen; - - ZeroMemory(pFont, sizeof(LOGFONTW)); if(!MSSTYLES_GetNextToken(lpCur, lpEnd, &lpCur, pFont->lfFaceName, LF_FACESIZE)) { TRACE("Property is there, but failed to get face name\n"); + *lpValEnd = lpCur; return E_PROP_ID_UNSUPPORTED; } if(!MSSTYLES_GetNextInteger(lpCur, lpEnd, &lpCur, &pointSize)) { TRACE("Property is there, but failed to get point size\n"); + *lpValEnd = lpCur; return E_PROP_ID_UNSUPPORTED; } - pFont->lfHeight = -MulDiv(pointSize, GetDeviceCaps(hdc, LOGPIXELSY), 72); + pFont->lfHeight = pointSize; pFont->lfWeight = FW_REGULAR; pFont->lfCharSet = DEFAULT_CHARSET; while(MSSTYLES_GetNextToken(lpCur, lpEnd, &lpCur, attr, sizeof(attr)/sizeof(attr[0]))) { @@ -1062,9 +1254,24 @@ HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) else if(!!lstrcmpiW(szUnderline, attr)) pFont->lfUnderline = TRUE; else if(!!lstrcmpiW(szStrikeOut, attr)) pFont->lfStrikeOut = TRUE; } + *lpValEnd = lpCur; return S_OK; } +HRESULT MSSTYLES_GetPropertyFont(PTHEME_PROPERTY tp, HDC hdc, LOGFONTW *pFont) +{ + LPCWSTR lpCur = tp->lpValue; + LPCWSTR lpEnd = tp->lpValue + tp->dwValueLen; + HRESULT hr; + + ZeroMemory(pFont, sizeof(LOGFONTW)); + hr = MSSTYLES_GetFont (lpCur, lpEnd, &lpCur, pFont); + if (SUCCEEDED (hr)) + pFont->lfHeight = -MulDiv(pFont->lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72); + + return hr; +} + /*********************************************************************** * MSSTYLES_GetPropertyInt * diff --git a/reactos/dll/win32/uxtheme/system.c b/reactos/dll/win32/uxtheme/system.c index c834c52c1cb..b115c536a6e 100644 --- a/reactos/dll/win32/uxtheme/system.c +++ b/reactos/dll/win32/uxtheme/system.c @@ -25,8 +25,8 @@ #include "windef.h" #include "winbase.h" -#include "winuser.h" #include "wingdi.h" +#include "winuser.h" #include "winreg.h" #include "uxtheme.h" #include "tmschema.h" @@ -57,17 +57,17 @@ static const WCHAR szDllName[] = {'D','l','l','N','a','m','e','\0'}; static const WCHAR szIniDocumentation[] = {'d','o','c','u','m','e','n','t','a','t','i','o','n','\0'}; HINSTANCE hDllInst; - -DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS; -ATOM atWindowTheme; -ATOM atSubAppName; -ATOM atSubIdList; ATOM atDialogThemeEnabled; -BOOL bThemeActive = FALSE; -WCHAR szCurrentTheme[MAX_PATH]; -WCHAR szCurrentColor[64]; -WCHAR szCurrentSize[64]; +static DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS; +static ATOM atWindowTheme; +static ATOM atSubAppName; +static ATOM atSubIdList; + +static BOOL bThemeActive = FALSE; +static WCHAR szCurrentTheme[MAX_PATH]; +static WCHAR szCurrentColor[64]; +static WCHAR szCurrentSize[64]; /***********************************************************************/ @@ -249,6 +249,12 @@ static const WCHAR strColorKey[] = { 'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\', 'C','o','l','o','r','s',0 }; static const WCHAR keyFlatMenus[] = { 'F','l','a','t','M','e','n','u', 0}; +static const WCHAR keyGradientCaption[] = { 'G','r','a','d','i','e','n','t', + 'C','a','p','t','i','o','n', 0 }; +static const WCHAR keyNonClientMetrics[] = { 'N','o','n','C','l','i','e','n','t', + 'M','e','t','r','i','c','s',0 }; +static const WCHAR keyIconTitleFont[] = { 'I','c','o','n','T','i','t','l','e', + 'F','o','n','t',0 }; static const struct BackupSysParam { @@ -257,6 +263,7 @@ static const struct BackupSysParam } backupSysParams[] = { {SPI_GETFLATMENU, SPI_SETFLATMENU, keyFlatMenus}, + {SPI_GETGRADIENTCAPTIONS, SPI_SETGRADIENTCAPTIONS, keyGradientCaption}, {-1, -1, 0} }; @@ -298,8 +305,13 @@ static void UXTHEME_BackupSystemMetrics(void) 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0) == ERROR_SUCCESS) { + NONCLIENTMETRICSW ncm; + LOGFONTW iconTitleFont; + + /* back up colors */ save_sys_colors (hKey); + /* back up "other" settings */ while (bsp->spiGet >= 0) { DWORD value; @@ -310,6 +322,18 @@ static void UXTHEME_BackupSystemMetrics(void) bsp++; } + + /* back up non-client metrics */ + memset (&ncm, 0, sizeof (ncm)); + ncm.cbSize = sizeof (ncm); + SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof (ncm), &ncm, 0); + RegSetValueExW (hKey, keyNonClientMetrics, 0, REG_BINARY, (LPBYTE)&ncm, + sizeof (ncm)); + memset (&iconTitleFont, 0, sizeof (iconTitleFont)); + SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (iconTitleFont), + &iconTitleFont, 0); + RegSetValueExW (hKey, keyIconTitleFont, 0, REG_BINARY, + (LPBYTE)&iconTitleFont, sizeof (iconTitleFont)); RegCloseKey (hKey); } @@ -375,16 +399,43 @@ static void UXTHEME_RestoreSystemMetrics(void) bsp++; } + /* read backed-up non-client metrics */ + { + NONCLIENTMETRICSW ncm; + LOGFONTW iconTitleFont; + DWORD count = sizeof(ncm); + DWORD type; + + if (RegQueryValueExW (hKey, keyNonClientMetrics, 0, + &type, (LPBYTE)&ncm, &count) == ERROR_SUCCESS) + { + SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, + count, (LPVOID)&ncm, SPIF_UPDATEINIFILE); + } + + count = sizeof(iconTitleFont); + + if (RegQueryValueExW (hKey, keyIconTitleFont, 0, + &type, (LPBYTE)&iconTitleFont, &count) == ERROR_SUCCESS) + { + SystemParametersInfoW (SPI_SETICONTITLELOGFONT, + count, (LPVOID)&iconTitleFont, SPIF_UPDATEINIFILE); + } + } RegCloseKey (hKey); } } /* Make system settings persistent, so they're in effect even w/o uxtheme - * loaded */ + * loaded. + * For efficiency reasons, only the last SystemParametersInfoW sets + * SPIF_SENDWININICHANGE */ static void UXTHEME_SaveSystemMetrics(void) { const struct BackupSysParam* bsp = backupSysParams; + NONCLIENTMETRICSW ncm; + LOGFONTW iconTitleFont; save_sys_colors (HKEY_CURRENT_USER); @@ -398,7 +449,20 @@ static void UXTHEME_SaveSystemMetrics(void) bsp++; } + + memset (&ncm, 0, sizeof (ncm)); + ncm.cbSize = sizeof (ncm); + SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, + sizeof (ncm), (LPVOID)&ncm, 0); + SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, + sizeof (ncm), (LPVOID)&ncm, SPIF_UPDATEINIFILE); + memset (&iconTitleFont, 0, sizeof (iconTitleFont)); + SystemParametersInfoW (SPI_GETICONTITLELOGFONT, + sizeof (iconTitleFont), (LPVOID)&iconTitleFont, 0); + SystemParametersInfoW (SPI_SETICONTITLELOGFONT, + sizeof (iconTitleFont), (LPVOID)&iconTitleFont, + SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); } /*********************************************************************** @@ -412,7 +476,7 @@ HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf) WCHAR tmp[2]; HRESULT hr; - if(tf) UXTHEME_BackupSystemMetrics(); + if(tf && !bThemeActive) UXTHEME_BackupSystemMetrics(); hr = MSSTYLES_SetActiveTheme(tf, TRUE); if(FAILED(hr)) return hr; From 9233af3e507901308cc9bdc9ddd6ea9c2fc9d8f4 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 8 Sep 2006 22:00:39 +0000 Subject: [PATCH 071/488] Add a bit of error reporting svn path=/trunk/; revision=23980 --- .../drivers/usb/nt4compat/usbdriver/uhci.c | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c index 53fcc0df3c5..bf9a559c849 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c @@ -128,7 +128,7 @@ extern VOID rh_timer_svc_reset_port_completion(PUSB_DEV dev, PVOID context); extern VOID rh_timer_svc_int_completion(PUSB_DEV dev, PVOID context); -ULONG debug_level = DBGLVL_ULTRA;//DBGLVL_MAXIMUM; +ULONG debug_level = DBGLVL_MAXIMUM; PDRIVER_OBJECT usb_driver_obj = NULL; extern USB_DEV_MANAGER g_dev_mgr; @@ -1284,6 +1284,8 @@ uhci_process_pending_endp(PUHCI_DEV uhci) { //abort these URBs InsertTailList(&abort_list, (LIST_ENTRY *) purb); + uhci_dbg_print(DBGLVL_MEDIUM, ("uhci_process_pending_endp(): unable to submit urb 0x%x, " + "with status=0x%x\n", purb, can_submit)); purb->status = can_submit; } @@ -1330,7 +1332,12 @@ uhci_submit_urb(PUHCI_DEV uhci, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb) USE_BASIC_IRQL; if (uhci == NULL || pdev == NULL || pendp == NULL || purb == NULL) + { + uhci_dbg_print(DBGLVL_MEDIUM, + ("uhci_submit_urb(): uhci=0x%x, pdev=0x%x, pendp=0x%x, purb=0x%x " + "called with invalid param!\n", uhci, pdev, pendp, purb)); return STATUS_INVALID_PARAMETER; + } lock_pending_endp_list(&uhci->pending_endp_list_lock); lock_dev(pdev, TRUE); @@ -1356,6 +1363,10 @@ uhci_submit_urb(PUHCI_DEV uhci, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb) if (dev_from_endp(purb->pendp) != pdev) { + uhci_dbg_print(DBGLVL_MEDIUM, + ("uhci_submit_urb(): dev_from_endp=0x%x\n, pdev=0x%x, pendp=0x%x " + "devices mismatch!\n", dev_from_endp(purb->pendp), pdev, pendp)); + status = purb->status = STATUS_INVALID_PARAMETER; goto LBL_OUT; } @@ -2234,13 +2245,21 @@ uhci_internal_submit_int(PUHCI_DEV uhci, PURB urb) BOOLEAN ret; if (uhci == NULL || urb == NULL) + { + uhci_dbg_print(DBGLVL_MEDIUM, + ("uhci_internal_submit_int(): uhci=0x%x, urb=0x%x " + "returning STATUS_INVALID_PARAMETER!\n", uhci, urb)); return STATUS_INVALID_PARAMETER; + } toggle = (urb->pendp->flags & USB_ENDP_FLAG_DATATOGGLE) ? TRUE : FALSE; max_packet_size = endp_max_packet_size(urb->pendp); if (max_packet_size < urb->data_length || max_packet_size == 0 || max_packet_size > 64) { + uhci_dbg_print(DBGLVL_MEDIUM, + ("uhci_internal_submit_int(): max_packet_size=%d, urb->data_length=%d " + "returning STATUS_INVALID_PARAMETER!\n", max_packet_size, urb->data_length)); return STATUS_INVALID_PARAMETER; } From 03a2724000604bf42d0943fa9eb081a3d72f7331 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Fri, 8 Sep 2006 22:30:46 +0000 Subject: [PATCH 072/488] User32 static.c: - Patch by Dmitry Timoshkov, modified for ReactOS. - Use computed icon rectangle if SS_CENTERIMAGE style is set. svn path=/trunk/; revision=23981 --- reactos/dll/win32/user32/controls/static.c | 10 ++++------ reactos/media/doc/README.WINE | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/reactos/dll/win32/user32/controls/static.c b/reactos/dll/win32/user32/controls/static.c index 8957ca7ed76..e2bc81a04d1 100644 --- a/reactos/dll/win32/user32/controls/static.c +++ b/reactos/dll/win32/user32/controls/static.c @@ -746,14 +746,12 @@ static void STATIC_PaintIconfn( HWND hwnd, HDC hdc, DWORD style ) iconRect.top = (rc.bottom - rc.top) / 2 - bm.bmHeight / 2; iconRect.right = iconRect.left + bm.bmWidth; iconRect.bottom = iconRect.top + bm.bmHeight; - FillRect( hdc, &iconRect, hbrush ); /* Wine source has &rc */ } else - { - FillRect( hdc, &rc, hbrush ); - DrawIconEx( hdc, rc.left, rc.top, hIcon, rc.right - rc.left, - rc.bottom - rc.top, 0, NULL, DI_NORMAL ); - } + iconRect = rc; + FillRect( hdc, &rc, hbrush ); + DrawIconEx( hdc, iconRect.left, iconRect.top, hIcon, iconRect.right - iconRect.left, + iconRect.bottom - iconRect.top, 0, NULL, DI_NORMAL ); } } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 014a8f01173..e53ab86563f 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -124,7 +124,7 @@ User32 - reactos/dll/win32/user32/controls/icontitle.c # Synced at 20060617 reactos/dll/win32/user32/controls/listbox.c # Synced at 20060616 reactos/dll/win32/user32/controls/scrollbar.c # Forked - reactos/dll/win32/user32/controls/static.c # Synced at 20060622 + reactos/dll/win32/user32/controls/static.c # Synced at 20060908 reactos/dll/win32/user32/misc/dde.c # Synced at 20060623 (dde_misc.c) reactos/dll/win32/user32/misc/ddeclient.c # Synced at 20060623 From 94a97e085a06408271aa7c4557f10c6b286d54ec Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sat, 9 Sep 2006 09:26:26 +0000 Subject: [PATCH 073/488] Added missing definitions svn path=/trunk/; revision=23982 --- reactos/include/psdk/olectlid.h | 2 -- reactos/include/psdk/shlguid.h | 2 ++ reactos/include/psdk/shlobj.h | 57 +++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/reactos/include/psdk/olectlid.h b/reactos/include/psdk/olectlid.h index dd4c069f4d1..7ebb21605a4 100644 --- a/reactos/include/psdk/olectlid.h +++ b/reactos/include/psdk/olectlid.h @@ -97,8 +97,6 @@ extern const GUID IID_IOleLink; extern const GUID IID_IOleCache; extern const GUID IID_IOleManager; extern const GUID IID_IOlePresObj; -extern const GUID IID_IDropSource; -extern const GUID IID_IDropTarget; extern const GUID IID_IDebug; extern const GUID IID_IDebugStream; extern const GUID IID_IAdviseSink2; diff --git a/reactos/include/psdk/shlguid.h b/reactos/include/psdk/shlguid.h index f61fdfbc94e..9daca5de1ba 100644 --- a/reactos/include/psdk/shlguid.h +++ b/reactos/include/psdk/shlguid.h @@ -10,6 +10,8 @@ extern "C" { #define DEFINE_SHLGUID(name, l, w1, w2) DEFINE_OLEGUID(name,l,w1,w2) +DEFINE_GUID(IID_IShellFolderViewCB, 0x2047E320L, 0xF2A9, 0x11CE, 0xAE, 0x65, 0x08, 0x00, 0x2B, 0x2E, 0x12, 0x62); + DEFINE_SHLGUID(CLSID_ShellDesktop, 0x00021400L, 0, 0); DEFINE_SHLGUID(CLSID_ShellLink, 0x00021401L, 0, 0); diff --git a/reactos/include/psdk/shlobj.h b/reactos/include/psdk/shlobj.h index 5c939bd3d89..f77f36501a4 100644 --- a/reactos/include/psdk/shlobj.h +++ b/reactos/include/psdk/shlobj.h @@ -1728,6 +1728,19 @@ DECLARE_INTERFACE_(IDropTargetHelper, IUnknown) #undef INTERFACE #endif /* _WIN32_IE >= 0x0500 */ +#if defined(COBJMACROS) +/*** IUnknown methods ***/ +#define IDropTargetHelper_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDropTargetHelper_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDropTargetHelper_Release(p) (p)->lpVtbl->Release(p) +/*** IDropTargetHelper methods ***/ +#define IDropTargetHelper_DragEnter(p,a,b,c,d) (p)->lpVtbl->DragEnter(p,a,b,c,d) +#define IDropTargetHelper_DragLeave(p) (p)->lpVtbl->DragLeave(p) +#define IDropTargetHelper_DragOver(p,a,b) (p)->lpVtbl->DragOver(p,a,b) +#define IDropTargetHelper_Drop(p,a,b,c) (p)->lpVtbl->Drop(p,a,b,c) +#define IDropTargetHelper_Show(p,a) (p)->lpVtbl->Show(p,a) +#endif + #define INTERFACE IInputObject DECLARE_INTERFACE_(IInputObject,IUnknown) { @@ -1792,8 +1805,48 @@ typedef struct _CSFV FOLDERVIEWMODE fvm; } CSFV, *LPCSFV; -/* FIXME: Add the IShellFolderViewCB interface! */ -#define IShellFolderViewCB void +#define INTERFACE IShellFolderViewCB +DECLARE_INTERFACE_(IShellFolderViewCB,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IShellFolderViewCB methods ***/ + STDMETHOD(MessageSFVCB)(THIS_ UINT uMsg, WPARAM wParam, LPARAM lParam) PURE; +}; +#undef INTERFACE + +#define SFVM_MERGEMENU 1 +#define SFVM_INVOKECOMMAND 2 +#define SFVM_GETHELPTEXT 3 +#define SFVM_GETTOOLTIPTEXT 4 +#define SFVM_GETBUTTONINFO 5 +#define SFVM_GETBUTTONS 6 +#define SFVM_INITMENUPOPUP 7 +#define SFVM_FSNOTIFY 14 +#define SFVM_WINDOWCREATED 15 +#define SFVM_GETDETAILSOF 23 +#define SFVM_COLUMNCLICK 24 +#define SFVM_QUERYFSNOTIFY 25 +#define SFVM_DEFITEMCOUNT 26 +#define SFVM_DEFVIEWMODE 27 +#define SFVM_UNMERGEMENU 28 +#define SFVM_UPDATESTATUSBAR 31 +#define SFVM_BACKGROUNDENUM 32 +#define SFVM_DIDDRAGDROP 36 +#define SFVM_SETISFV 39 +#define SFVM_THISIDLIST 41 +#define SFVM_ADDPROPERTYPAGES 47 +#define SFVM_BACKGROUNDENUMDONE 48 +#define SFVM_GETNOTIFY 49 +#define SFVM_GETSORTDEFAULTS 53 +#define SFVM_SIZE 57 +#define SFVM_GETZONE 58 +#define SFVM_GETPANE 59 +#define SFVM_GETHELPTOPIC 63 +#define SFVM_GETANIMATION 68 + typedef struct _SFV_CREATE { UINT cbSize; From 25c11e5f6eab7e1265a162e03a4f7ac3a4015c9c Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 9 Sep 2006 09:41:09 +0000 Subject: [PATCH 074/488] Make UNIMPLEMENTED available everywhere and remove some #ifdef cruft. svn path=/trunk/; revision=23983 --- reactos/boot/freeldr/freeldr/include/debug.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/include/debug.h b/reactos/boot/freeldr/freeldr/include/debug.h index 7d9efe29d3a..ee7c1064619 100644 --- a/reactos/boot/freeldr/freeldr/include/debug.h +++ b/reactos/boot/freeldr/freeldr/include/debug.h @@ -73,9 +73,7 @@ void INSTRUCTION_BREAKPOINT4(unsigned long addr); void MEMORY_READWRITE_BREAKPOINT4(unsigned long addr); void MEMORY_WRITE_BREAKPOINT4(unsigned long addr); -#elif defined(__PowerPC__) -#define UNIMPLEMENTED() BugCheck((DPRINT_WARNING, "This function is unimplemented!\n")) -#endif // defined __i386__ +#endif #else @@ -85,8 +83,8 @@ void MEMORY_WRITE_BREAKPOINT4(unsigned long addr); #define BugCheck(_x_) #define DbgDumpBuffer(_x_, _y_, _z_) -#define UNIMPLEMENTED() BugCheck((DPRINT_WARNING, "This function is unimplemented!\n")) #endif // defined DEBUG +#define UNIMPLEMENTED() BugCheck((DPRINT_WARNING, "This function is unimplemented!\n")) #endif // defined __DEBUG_H From dd77d1676bfc9823082a785fc4c3e385266ec1e4 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Sat, 9 Sep 2006 10:53:28 +0000 Subject: [PATCH 075/488] modified Resources/hresult.xml Added S_OK and S_FALSE modified Resources/ntstatus.xml Added all possible STATUS_WAIT_XX codes as STATUS_WAIT_0 + XX modified TechBot.Console/App.config Don't use hard-coded paths, please! modified TechBot.Library/ErrorCommand.cs New and improved !error command, now performs heuristics to catch all possible or likely uses modified TechBot.Library/HresultCommand.cs Removed useless field modified TechBot.Library/NumberParser.cs Made a couple of methods static modified TechBot.Library/TechBotService.cs Disable !api until it fails gracefully svn path=/trunk/; revision=23984 --- irc/TechBot/Resources/hresult.xml | 2 + irc/TechBot/Resources/ntstatus.xml | 65 ++++++- irc/TechBot/TechBot.Console/App.config | 8 +- irc/TechBot/TechBot.Library/ErrorCommand.cs | 165 +++++++++++++++--- irc/TechBot/TechBot.Library/HresultCommand.cs | 2 - irc/TechBot/TechBot.Library/NumberParser.cs | 6 +- irc/TechBot/TechBot.Library/TechBotService.cs | 4 +- 7 files changed, 213 insertions(+), 39 deletions(-) diff --git a/irc/TechBot/Resources/hresult.xml b/irc/TechBot/Resources/hresult.xml index 743d04012e2..68e5bdc55e2 100644 --- a/irc/TechBot/Resources/hresult.xml +++ b/irc/TechBot/Resources/hresult.xml @@ -1,5 +1,7 @@  + + diff --git a/irc/TechBot/Resources/ntstatus.xml b/irc/TechBot/Resources/ntstatus.xml index ce44f8d5ca7..2e99a3bd13d 100644 --- a/irc/TechBot/Resources/ntstatus.xml +++ b/irc/TechBot/Resources/ntstatus.xml @@ -2,8 +2,69 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/irc/TechBot/TechBot.Console/App.config b/irc/TechBot/TechBot.Console/App.config index 397d4b0773c..a7d7eeb7a5f 100644 --- a/irc/TechBot/TechBot.Console/App.config +++ b/irc/TechBot/TechBot.Console/App.config @@ -8,10 +8,10 @@ - - - - + + + + diff --git a/irc/TechBot/TechBot.Library/ErrorCommand.cs b/irc/TechBot/TechBot.Library/ErrorCommand.cs index 6ee2d68f865..35b7789b71e 100644 --- a/irc/TechBot/TechBot.Library/ErrorCommand.cs +++ b/irc/TechBot/TechBot.Library/ErrorCommand.cs @@ -1,5 +1,6 @@ using System; using System.Xml; +using System.Collections; namespace TechBot.Library { @@ -28,58 +29,170 @@ namespace TechBot.Library new string[] { "error" }); } + private static int GetSeverity(long error) + { + return (int)((error >> 30) & 0x3); + } + + private static bool IsCustomer(long error) + { + return (error & 0x20000000) != 0; + } + + private static bool IsReserved(long error) + { + return (error & 0x10000000) != 0; + } + + private static int GetFacility(long error) + { + return (int)((error >> 16) & 0xFFF); + } + + private static short GetCode(long error) + { + return (short)((error >> 0) & 0xFFFF); + } + + private static string FormatSeverity(long error) + { + int severity = GetSeverity(error); + switch (severity) + { + case 0: return "SUCCESS"; + case 1: return "INFORMATIONAL"; + case 2: return "WARNING"; + case 3: return "ERROR"; + } + return null; + } + + private static string FormatFacility(long error) + { + int facility = GetFacility(error); + return facility.ToString(); + } + + private static string FormatCode(long error) + { + int code = GetCode(error); + return code.ToString(); + } + public void Handle(MessageContext context, string commandName, string parameters) { - string errorText = parameters; - if (errorText.Equals(String.Empty)) + string originalErrorText = parameters.Trim(); + if (originalErrorText.Equals(String.Empty)) { serviceOutput.WriteLine(context, "Please provide an Error Code."); return; } + + string errorText = originalErrorText; + retry: NumberParser np = new NumberParser(); long error = np.Parse(errorText); if (np.Error) { serviceOutput.WriteLine(context, String.Format("{0} is not a valid Error Code.", - errorText)); + originalErrorText)); return; } + + ArrayList descriptions = new ArrayList(); - string description = null; - if (winerror.GetWinerrorDescription(error) != null) + // Error is out of bounds + if ((ulong)error > uint.MaxValue) { - description = winerror.GetWinerrorDescription(error); - serviceOutput.WriteLine(context, - String.Format("{0} is {1}.", - error, - description)); + // Do nothing } - if (ntStatus.GetNtstatusDescription(error) != null) + // Error is outside of the range [0, 65535]: it cannot be a plain Win32 error code + else if ((ulong)error > ushort.MaxValue) { - description = ntStatus.GetNtstatusDescription(error); - serviceOutput.WriteLine(context, - String.Format("{0} is {1}.", - errorText, - description)); + // Customer bit is set: custom error code + if (IsCustomer(error)) + { + string description = String.Format("[custom, severity {0}, facility {1}, code {2}]", + FormatSeverity(error), + FormatFacility(error), + FormatCode(error)); + descriptions.Add(description); + } + // Reserved bit is set: HRESULT_FROM_NT(ntstatus) + else if (IsReserved(error)) + { + int status = (int)(error & 0xCFFFFFFF); + string description = ntStatus.GetNtstatusDescription(status); + + if (description == null) + description = status.ToString("X"); + + description = String.Format("HRESULT_FROM_NT({0})", description); + descriptions.Add(description); + } + // Win32 facility: HRESULT_FROM_WIN32(winerror) + else if (GetFacility(error) == 7) + { + // Must be an error code + if (GetSeverity(error) == 2) + { + short err = GetCode(error); + string description = winerror.GetWinerrorDescription(err); + + if (description == null) + description = err.ToString("D"); + + description = String.Format("HRESULT_FROM_WIN32({0})", description); + descriptions.Add(description); + } + } } - if (hresult.GetHresultDescription(error) != null) - { - description = hresult.GetHresultDescription(error); - serviceOutput.WriteLine(context, - String.Format("{0} is {1}.", - errorText, - description)); - } - if(description == null) + + string winerrorDescription = winerror.GetWinerrorDescription(error); + string ntstatusDescription = ntStatus.GetNtstatusDescription(error); + string hresultDescription = hresult.GetHresultDescription(error); + + if (winerrorDescription != null) + descriptions.Add(winerrorDescription); + if (ntstatusDescription != null) + descriptions.Add(ntstatusDescription); + if (hresultDescription != null) + descriptions.Add(hresultDescription); + + if (descriptions.Count == 0) { + // Last chance heuristics: attempt to parse a 8-digit decimal as hexadecimal + if (errorText.Length == 8) + { + errorText = "0x" + errorText; + goto retry; + } + serviceOutput.WriteLine(context, String.Format("I don't know about Error Code {0}.", - errorText)); + originalErrorText)); + } + else if (descriptions.Count == 1) + { + string description = (string)descriptions[0]; + serviceOutput.WriteLine(context, + String.Format("{0} is {1}.", + originalErrorText, + description)); + } + else + { + serviceOutput.WriteLine(context, + String.Format("{0} could be:", + originalErrorText)); + + foreach(string description in descriptions) + serviceOutput.WriteLine(context, String.Format("\t{0}", description)); } } diff --git a/irc/TechBot/TechBot.Library/HresultCommand.cs b/irc/TechBot/TechBot.Library/HresultCommand.cs index c17b577c912..32b76672b30 100644 --- a/irc/TechBot/TechBot.Library/HresultCommand.cs +++ b/irc/TechBot/TechBot.Library/HresultCommand.cs @@ -6,14 +6,12 @@ namespace TechBot.Library public class HresultCommand : BaseCommand, ICommand { private IServiceOutput serviceOutput; - private string hresultXml; private XmlDocument hresultXmlDocument; public HresultCommand(IServiceOutput serviceOutput, string hresultXml) { this.serviceOutput = serviceOutput; - this.hresultXml = hresultXml; hresultXmlDocument = new XmlDocument(); hresultXmlDocument.Load(hresultXml); } diff --git a/irc/TechBot/TechBot.Library/NumberParser.cs b/irc/TechBot/TechBot.Library/NumberParser.cs index 15521ede73b..232ed0be1f2 100644 --- a/irc/TechBot/TechBot.Library/NumberParser.cs +++ b/irc/TechBot/TechBot.Library/NumberParser.cs @@ -9,7 +9,7 @@ namespace TechBot.Library private const string SpecialHexCharacters = "ABCDEF"; - private bool IsSpecialHexCharacter(char ch) + private static bool IsSpecialHexCharacter(char ch) { foreach (char specialChar in SpecialHexCharacters) { @@ -19,7 +19,7 @@ namespace TechBot.Library return false; } - private bool HasSpecialHexCharacters(string s) + private static bool HasSpecialHexCharacters(string s) { foreach (char ch in s) { @@ -35,7 +35,7 @@ namespace TechBot.Library { Error = false; bool useHex = false; - if (s.StartsWith("0x")) + if (s.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase)) { s = s.Substring(2); useHex = true; diff --git a/irc/TechBot/TechBot.Library/TechBotService.cs b/irc/TechBot/TechBot.Library/TechBotService.cs index 1efb858f5d3..f727c33fc00 100644 --- a/irc/TechBot/TechBot.Library/TechBotService.cs +++ b/irc/TechBot/TechBot.Library/TechBotService.cs @@ -49,9 +49,9 @@ namespace TechBot.Library { commands.Add(new HelpCommand(serviceOutput, commands)); - commands.Add(new ApiCommand(serviceOutput, + /*commands.Add(new ApiCommand(serviceOutput, chmPath, - mainChm)); + mainChm));*/ commands.Add(new NtStatusCommand(serviceOutput, ntstatusXml)); commands.Add(new WinerrorCommand(serviceOutput, From 249e8c91baebfb375f45c177dc5fc1bf590b1dc8 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 9 Sep 2006 11:41:24 +0000 Subject: [PATCH 076/488] Dmitry Philippov: GCC 4 compiling fixes for PackMgr and tests/wm_paint svn path=/trunk/; revision=23985 --- rosapps/packmgr/gui/main.c | 8 +++----- rosapps/tests/wm_paint/wm_paint.c | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/rosapps/packmgr/gui/main.c b/rosapps/packmgr/gui/main.c index 002ee93924b..6398ca30117 100644 --- a/rosapps/packmgr/gui/main.c +++ b/rosapps/packmgr/gui/main.c @@ -200,9 +200,7 @@ int SetIcon (int id, int icon) item.iSelectedImage = icon; item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; - TreeView_SetItem(hTree, &item); - - return 1; + return (int)TreeView_SetItem(hTree, &item); } // Set the Icons @@ -320,9 +318,9 @@ LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if(item != NULL) { - // mark the one as seleacted + // mark the one as selected SendMessage (hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)item); - TreeView_EnsureVisible (hTree, item); + (BOOL)TreeView_EnsureVisible (hTree, item); } // create the context menu diff --git a/rosapps/tests/wm_paint/wm_paint.c b/rosapps/tests/wm_paint/wm_paint.c index a488206fd83..24f00aa5b9c 100644 --- a/rosapps/tests/wm_paint/wm_paint.c +++ b/rosapps/tests/wm_paint/wm_paint.c @@ -90,10 +90,10 @@ LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, RUpdate.right, RUpdate.bottom); // fill the client area with the background brush - //HBRUSH HBrush = - //reinterpret_cast + /*HBRUSH HBrush = + reinterpret_cast (HBRUSH)(GetClassLong(HWnd, GCL_HBRBACKGROUND) - ); + );*/ FillRect(Hdc, &RClient, NULL); // render the persistent text From c439fb86f7a6873f2b9949986ce00f2d443f4c1f Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Sat, 9 Sep 2006 11:42:52 +0000 Subject: [PATCH 077/488] Add winetests to bootcd svn path=/trunk/; revision=23986 --- reactos/boot/bootdata/packages/reactos.dff | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index 00e212933cf..43355b22aaa 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -16,9 +16,10 @@ Signature = "$ReactOS$" 1 = system32 2 = system32\drivers 3 = media\fonts -4 = +4 = 5 = system32\drivers\etc 6 = inf +7 = bin .InfEnd @@ -408,6 +409,25 @@ subsystems\ntvdm\ntvdm.exe 1 subsystems\win32\win32k\win32k.sys 1 +; Winetests +regtests\winetests\advapi32\advapi32_winetest.exe 7 +regtests\winetests\cabinet\cabinet_winetest.exe 7 +regtests\winetests\comctl32\comctl32_winetest.exe 7 +regtests\winetests\gdi32\gdi32_winetest.exe 7 +regtests\winetests\icmp\icmp_winetest.exe 7 +regtests\winetests\kernel32\kernel32_winetest.exe 7 +regtests\winetests\lz32\lz32_winetest.exe 7 +regtests\winetests\msi\msi_winetest.exe 7 +regtests\winetests\msvcrt\msvcrt_winetest.exe 7 +regtests\winetests\ntdll\ntdll_winetest.exe 7 +regtests\winetests\powrprof\powrprof_winetest.exe 7 +regtests\winetests\psapi\psapi_winetest.exe 7 +regtests\winetests\setupapi\setupapi_winetest.exe 7 +regtests\winetests\shell32\shell32_winetest.exe 7 +regtests\winetests\shlwapi\shlwapi_winetest.exe 7 +regtests\winetests\user32\user32_winetest.exe 7 +regtests\winetests\version\version_winetest.exe 7 + ; Modules modules\os2\server\os2srv.dll 1 optional modules\os2\dll\win32\doscalls\doscalls.dll 1 optional From 68c6a664cf76d0012f196f91f4266b866d210918 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Sat, 9 Sep 2006 13:19:03 +0000 Subject: [PATCH 079/488] Replace MmCopyFromCaller with probing and seh. svn path=/trunk/; revision=23988 --- .../subsystems/win32/win32k/ntuser/painting.c | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/painting.c b/reactos/subsystems/win32/win32k/ntuser/painting.c index 47746549acb..35ca36374b6 100644 --- a/reactos/subsystems/win32/win32k/ntuser/painting.c +++ b/reactos/subsystems/win32/win32k/ntuser/painting.c @@ -1380,7 +1380,7 @@ BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxW PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon); BOOL -IntDrawSysMenuButton( +UserDrawSysMenuButton( PWINDOW_OBJECT pWnd, HDC hDc, LPRECT lpRc, @@ -1421,7 +1421,7 @@ IntDrawSysMenuButton( } BOOL -IntDrawCaptionText(HDC hDc, +UserDrawCaptionText(HDC hDc, const PUNICODE_STRING Text, const LPRECT lpRc, UINT uFlags) @@ -1672,7 +1672,7 @@ BOOL UserDrawCaption( { r.top ++; r.left -= --IconWidth; - IntDrawSysMenuButton(pWnd, hMemDc, &r, FALSE); + UserDrawSysMenuButton(pWnd, hMemDc, &r, FALSE); r.left += IconWidth; r.top --; } @@ -1705,7 +1705,7 @@ BOOL UserDrawCaption( } } - IntDrawCaptionText(hMemDc, &pWnd->WindowName, &r, uFlags); + UserDrawCaptionText(hMemDc, &pWnd->WindowName, &r, uFlags); } if(!NtGdiBitBlt(hDc, lpRc->left, lpRc->top, @@ -1737,13 +1737,7 @@ NtUserDrawCaption(HWND hWnd, { PWINDOW_OBJECT pWnd; RECT SafeRect; - BOOL Ret; - - if(!NT_SUCCESS(MmCopyFromCaller(&SafeRect, lpRc, sizeof(RECT)))) - { - DPRINT1("%s: MmCopyFromCaller failed!", __FUNCTION__); - return FALSE; - } + BOOL Ret = FALSE; UserEnterExclusive(); @@ -1753,7 +1747,17 @@ NtUserDrawCaption(HWND hWnd, return FALSE; } - Ret = UserDrawCaption(pWnd, hDc, &SafeRect, uFlags); + _SEH_TRY + { + ProbeForRead(lpRc, sizeof(RECT), sizeof(ULONG)); + RtlCopyMemory(&SafeRect, lpRc, sizeof(RECT)); + Ret = UserDrawCaption(pWnd, hDc, &SafeRect, uFlags); + } + _SEH_HANDLE + { + SetLastNtError(_SEH_GetExceptionCode()); + } + _SEH_END; UserLeave(); return Ret; From 812b97ae664c22a190ac11d4af5bc7c423fd2885 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 9 Sep 2006 13:47:45 +0000 Subject: [PATCH 080/488] Correct bug in cache which could cause us to lose the last block of a file. This is wierd and insidious, and probably was the cause of n00bs not being able to boot on occasion. svn path=/trunk/; revision=23990 --- reactos/boot/freeldr/freeldr/cache/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/boot/freeldr/freeldr/cache/cache.c b/reactos/boot/freeldr/freeldr/cache/cache.c index ac02a72151a..eaf024fbfb4 100644 --- a/reactos/boot/freeldr/freeldr/cache/cache.c +++ b/reactos/boot/freeldr/freeldr/cache/cache.c @@ -138,7 +138,7 @@ BOOLEAN CacheReadDiskSectors(ULONG DiskNumber, ULONG StartSector, ULONG SectorCo SectorOffsetInStartBlock = StartSector % CacheManagerDrive.BlockSize; CopyLengthInStartBlock = (SectorCount > (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock)) ? (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock) : SectorCount; EndBlock = (StartSector + (SectorCount - 1)) / CacheManagerDrive.BlockSize; - SectorOffsetInEndBlock = (StartSector + SectorCount) % CacheManagerDrive.BlockSize; + SectorOffsetInEndBlock = 1 + (StartSector + (SectorCount - 1)) % CacheManagerDrive.BlockSize; BlockCount = (EndBlock - StartBlock) + 1; DbgPrint((DPRINT_CACHE, "StartBlock: %d SectorOffsetInStartBlock: %d CopyLengthInStartBlock: %d EndBlock: %d SectorOffsetInEndBlock: %d BlockCount: %d\n", StartBlock, SectorOffsetInStartBlock, CopyLengthInStartBlock, EndBlock, SectorOffsetInEndBlock, BlockCount)); From b2dbae0fab10718258cfd67bee1a43ddda6ed5a4 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Sat, 9 Sep 2006 14:38:07 +0000 Subject: [PATCH 081/488] Messageboxes shouldn't have WS_SYSMENU svn path=/trunk/; revision=23992 --- reactos/dll/win32/user32/windows/messagebox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/user32/windows/messagebox.c b/reactos/dll/win32/user32/windows/messagebox.c index 85e72992959..ba43796fc36 100644 --- a/reactos/dll/win32/user32/windows/messagebox.c +++ b/reactos/dll/win32/user32/windows/messagebox.c @@ -378,7 +378,7 @@ MessageBoxTimeoutIndirectW( tpl = (DLGTEMPLATE *)buf; - tpl->style = WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU | DS_CENTER | DS_MODALFRAME | DS_NOIDLEMSG; + tpl->style = WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | DS_CENTER | DS_MODALFRAME | DS_NOIDLEMSG; tpl->dwExtendedStyle = WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; if(lpMsgBoxParams->dwStyle & MB_TOPMOST) tpl->dwExtendedStyle |= WS_EX_TOPMOST; From 52c652809d85b8e52c414774ce19b21408691df8 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Sat, 9 Sep 2006 14:49:11 +0000 Subject: [PATCH 082/488] revert last commit svn path=/trunk/; revision=23993 --- reactos/dll/win32/user32/windows/messagebox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/user32/windows/messagebox.c b/reactos/dll/win32/user32/windows/messagebox.c index ba43796fc36..85e72992959 100644 --- a/reactos/dll/win32/user32/windows/messagebox.c +++ b/reactos/dll/win32/user32/windows/messagebox.c @@ -378,7 +378,7 @@ MessageBoxTimeoutIndirectW( tpl = (DLGTEMPLATE *)buf; - tpl->style = WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | DS_CENTER | DS_MODALFRAME | DS_NOIDLEMSG; + tpl->style = WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU | DS_CENTER | DS_MODALFRAME | DS_NOIDLEMSG; tpl->dwExtendedStyle = WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; if(lpMsgBoxParams->dwStyle & MB_TOPMOST) tpl->dwExtendedStyle |= WS_EX_TOPMOST; From 1dc7b0f6af1b6929c13bcc35e003dfa91d7a879f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 16:47:09 +0000 Subject: [PATCH 083/488] Add VfatChkdsk() prototype svn path=/trunk/; revision=23995 --- reactos/include/reactos/libs/fslib/vfatlib.h | 22 ++++++++++++++------ reactos/lib/fslib/vfatlib/vfatlib.c | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/reactos/include/reactos/libs/fslib/vfatlib.h b/reactos/include/reactos/libs/fslib/vfatlib.h index c54d9260994..fcebc431938 100755 --- a/reactos/include/reactos/libs/fslib/vfatlib.h +++ b/reactos/include/reactos/libs/fslib/vfatlib.h @@ -10,11 +10,21 @@ #include NTSTATUS NTAPI -VfatFormat (PUNICODE_STRING DriveRoot, - FMIFS_MEDIA_FLAG MediaFlag, - PUNICODE_STRING Label, - BOOLEAN QuickFormat, - ULONG ClusterSize, - PFMIFSCALLBACK Callback); +VfatChkdsk( + IN PUNICODE_STRING DriveRoot, + IN BOOLEAN FixErrors, + IN BOOLEAN Verbose, + IN BOOLEAN CheckOnlyIfDirty, + IN BOOLEAN ScanDrive, + IN PFMIFSCALLBACK Callback); + +NTSTATUS NTAPI +VfatFormat( + IN PUNICODE_STRING DriveRoot, + IN FMIFS_MEDIA_FLAG MediaFlag, + IN PUNICODE_STRING Label, + IN BOOLEAN QuickFormat, + IN ULONG ClusterSize, + IN PFMIFSCALLBACK Callback); #endif /*__VFATLIB_H */ diff --git a/reactos/lib/fslib/vfatlib/vfatlib.c b/reactos/lib/fslib/vfatlib/vfatlib.c index 1401da39963..ea38162a013 100755 --- a/reactos/lib/fslib/vfatlib/vfatlib.c +++ b/reactos/lib/fslib/vfatlib/vfatlib.c @@ -213,7 +213,7 @@ VfatChkdsk( IN PFMIFSCALLBACK Callback) { DPRINT1("VfatChkdsk() unimplemented!\n"); - return STATUS_NOT_IMPLEMENTED; + return STATUS_SUCCESS; } /* EOF */ From 4ca190a004f699b72d5108e097dd26158ddc7b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 17:09:33 +0000 Subject: [PATCH 084/488] Remove useless member in DESKTOP_OBJECT structure svn path=/trunk/; revision=23996 --- reactos/subsystems/win32/win32k/include/desktop.h | 1 - 1 file changed, 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/include/desktop.h b/reactos/subsystems/win32/win32k/include/desktop.h index df36a66a300..7a877b025a8 100644 --- a/reactos/subsystems/win32/win32k/include/desktop.h +++ b/reactos/subsystems/win32/win32k/include/desktop.h @@ -18,7 +18,6 @@ typedef struct _DESKTOP_OBJECT RECT WorkArea; /* Handle of the desktop window. */ HANDLE DesktopWindow; - HANDLE PrevActiveWindow; /* Thread blocking input */ PVOID BlockInputThread; From 52d59f6a4f99da9650f0aa505a2bf7fe5b0a5fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 17:09:45 +0000 Subject: [PATCH 085/488] Don't use buffered input when reading username/password in text mode svn path=/trunk/; revision=23997 --- reactos/dll/win32/msgina/tui.c | 63 +++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/reactos/dll/win32/msgina/tui.c b/reactos/dll/win32/msgina/tui.c index 0d454e2ce15..87983630f99 100644 --- a/reactos/dll/win32/msgina/tui.c +++ b/reactos/dll/win32/msgina/tui.c @@ -33,13 +33,13 @@ TUIDisplayStatusMessage( TRACE("TUIDisplayStatusMessage(%ws)\n", pMessage); return - WriteConsole( + WriteConsoleW( GetStdHandle(STD_OUTPUT_HANDLE), pMessage, wcslen(pMessage), &result, NULL) && - WriteConsole( + WriteConsoleW( GetStdHandle(STD_OUTPUT_HANDLE), newLine, wcslen(newLine), @@ -66,7 +66,7 @@ DisplayResourceText( if (!LoadStringW(hDllInstance, uIdResourceText, Prompt, 256)) return FALSE; - if (!WriteConsole( + if (!WriteConsoleW( GetStdHandle(STD_OUTPUT_HANDLE), Prompt, wcslen(Prompt), &count, NULL)) @@ -122,27 +122,64 @@ ReadString( IN BOOL ShowString) { DWORD count, i; + WCHAR charToDisplay[] = { 0, UNICODE_NULL }; - if (!SetConsoleMode( - GetStdHandle(STD_INPUT_HANDLE), - ShowString ? ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT: ENABLE_LINE_INPUT)) - { + if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0)) + return FALSE; + + if (!FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE))) return FALSE; - } if (!DisplayResourceText(uIdResourcePrompt, FALSE)) return FALSE; i = 0; - do + for (;;) { - if (!ReadConsole(GetStdHandle(STD_INPUT_HANDLE), &Buffer[i], 1, &count, NULL)) + WCHAR readChar; + if (!ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), &readChar, 1, &count, NULL)) return FALSE; - i++; + if (readChar == '\r' || readChar == '\n') + { + /* End of string */ + charToDisplay[0] = L'\n'; + WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + charToDisplay, + wcslen(charToDisplay), + &count, + NULL); + break; + } + if (ShowString) + { + /* Display the char */ + charToDisplay[0] = readChar; + WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + charToDisplay, + wcslen(charToDisplay), + &count, + NULL); + } + Buffer[i++] = readChar; /* FIXME: buffer overflow if the user writes too many chars! */ /* FIXME: handle backspace */ - } while (Buffer[i - 1] != '\n'); - Buffer[i - 1] = 0; + } + Buffer[i] = UNICODE_NULL; + + if (!ShowString) + { + /* Still display the \n */ + static LPCWSTR newLine = L"\n"; + DWORD result; + WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + newLine, + wcslen(newLine), + &result, + NULL); + } return TRUE; } From 8dcf1980fe705b95d38772f6017fce402f113ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 17:10:42 +0000 Subject: [PATCH 086/488] Set 2nd stage setup to language selected in registry Try to use GetLastInputInfo API instead of a keyboard/mouse hook for screensaver (not enabled yet) svn path=/trunk/; revision=23998 --- reactos/base/system/winlogon/sas.c | 6 ++-- reactos/base/system/winlogon/screensaver.c | 39 +++++++++++++++++++++- reactos/base/system/winlogon/winlogon.c | 3 ++ reactos/base/system/winlogon/winlogon.h | 10 ++++++ 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/reactos/base/system/winlogon/sas.c b/reactos/base/system/winlogon/sas.c index 12669287574..00068eaa14d 100644 --- a/reactos/base/system/winlogon/sas.c +++ b/reactos/base/system/winlogon/sas.c @@ -94,13 +94,12 @@ SetDefaultLanguage( goto cleanup; } - Value = HeapAlloc(GetProcessHeap(), 0, dwSize + sizeof(UNICODE_NULL)); + Value = HeapAlloc(GetProcessHeap(), 0, dwSize); if (!Value) { TRACE("HeapAlloc() failed\n"); goto cleanup; } - Value[dwSize / sizeof(WCHAR)] = UNICODE_NULL; rc = RegQueryValueExW( hKey, ValueName, @@ -115,7 +114,8 @@ SetDefaultLanguage( } /* Convert Value to a Lcid */ - RtlInitUnicodeString(&ValueString, Value); + ValueString.Length = ValueString.MaximumLength = dwSize; + ValueString.Buffer = Value; Status = RtlUnicodeStringToInteger(&ValueString, 16, &Lcid); if (!NT_SUCCESS(Status)) { diff --git a/reactos/base/system/winlogon/screensaver.c b/reactos/base/system/winlogon/screensaver.c index 62febd804d4..329fe9f8fab 100644 --- a/reactos/base/system/winlogon/screensaver.c +++ b/reactos/base/system/winlogon/screensaver.c @@ -11,6 +11,7 @@ #define YDEBUG #include +#ifndef USE_GETLASTINPUTINFO static LRESULT CALLBACK KeyboardActivityProc( IN INT nCode, @@ -30,6 +31,7 @@ MouseActivityProc( InterlockedExchange((LONG*)&WLSession->LastActivity, ((PMSLLHOOKSTRUCT)lParam)->time); return CallNextHookEx(NULL, nCode, wParam, lParam); } +#endif static VOID LoadScreenSaverParameters( @@ -65,7 +67,12 @@ ScreenSaverThreadMain( { PWLSESSION Session = (PWLSESSION)lpParameter; HANDLE HandleArray[3]; - DWORD LastActivity, TimeToWait; +#ifdef USE_GETLASTINPUTINFO + LASTINPUTINFO lastInputInfo; +#else + DWORD LastActivity; +#endif + DWORD TimeToWait; DWORD Timeout; /* Timeout before screen saver starts, in milliseconds */ DWORD ret; @@ -88,12 +95,26 @@ ScreenSaverThreadMain( LoadScreenSaverParameters(&Timeout); +#ifndef USE_GETLASTINPUTINFO InterlockedExchange((LONG*)&Session->LastActivity, GetTickCount()); +#else + lastInputInfo.cbSize = sizeof(LASTINPUTINFO); +#endif for (;;) { /* See the time of last activity and calculate a timeout */ +#ifndef USE_GETLASTINPUTINFO LastActivity = InterlockedCompareExchange((LONG*)&Session->LastActivity, 0, 0); TimeToWait = Timeout - (GetTickCount() - LastActivity); +#else + if (GetLastInputInfo(&lastInputInfo)) + TimeToWait = Timeout - (GetTickCount() - lastInputInfo.dwTime); + else + { + WARN("GetLastInputInfo() failed with error %lu\n", GetLastError()); + TimeToWait = 10; /* Try again in 10 ms */ + } +#endif if (TimeToWait > Timeout) { /* GetTickCount() got back to 0 */ @@ -108,9 +129,19 @@ ScreenSaverThreadMain( LoadScreenSaverParameters(&Timeout); /* Check if we didn't had recent activity */ +#ifndef USE_GETLASTINPUTINFO LastActivity = InterlockedCompareExchange((LONG*)&Session->LastActivity, 0, 0); if (LastActivity + Timeout > GetTickCount()) continue; +#else + if (!GetLastInputInfo(&lastInputInfo)) + { + WARN("GetLastInputInfo() failed with error %lu\n", GetLastError()); + continue; + } + if (lastInputInfo.dwTime + Timeout > GetTickCount()) + continue; +#endif /* Run screen saver */ PostMessageW(Session->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_SCRNSVR_TIMEOUT, 0); @@ -129,10 +160,12 @@ cleanup: RevertToSelf(); if (Session->hUserActivity) CloseHandle(Session->hUserActivity); +#ifndef USE_GETLASTINPUTINFO if (Session->KeyboardHook) UnhookWindowsHookEx(Session->KeyboardHook); if (Session->MouseHook) UnhookWindowsHookEx(Session->MouseHook); +#endif CloseHandle(Session->hEndOfScreenSaverThread); CloseHandle(Session->hScreenSaverParametersChanged); return 0; @@ -147,6 +180,7 @@ InitializeScreenSaver( FIXME("Disabling screen saver due to numerous bugs in ReactOS (see r23540)!\n"); return TRUE; +#ifndef USE_GETLASTINPUTINFO /* Register hooks to detect keyboard and mouse activity */ Session->KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardActivityProc, hAppInstance, 0); if (!Session->KeyboardHook) @@ -160,6 +194,7 @@ InitializeScreenSaver( ERR("WL: Unable to register mouse hook\n"); return FALSE; } +#endif if (!(Session->hScreenSaverParametersChanged = CreateEventW(NULL, FALSE, FALSE, NULL))) { @@ -264,6 +299,8 @@ cleanup: else { PostMessageW(Session->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_SCRNSVR_ACTIVITY, 0); +#ifndef USE_GETLASTINPUTINFO InterlockedExchange((LONG*)&Session->LastActivity, GetTickCount()); +#endif } } diff --git a/reactos/base/system/winlogon/winlogon.c b/reactos/base/system/winlogon/winlogon.c index c0896e980cc..245720c9227 100644 --- a/reactos/base/system/winlogon/winlogon.c +++ b/reactos/base/system/winlogon/winlogon.c @@ -406,6 +406,9 @@ WinMain( { TRACE("WL: Setup mode detected\n"); + /* Set locale */ + SetDefaultLanguage(FALSE); + /* Run setup and reboot when done */ SwitchDesktop(WLSession->ApplicationDesktop); RunSetup(); diff --git a/reactos/base/system/winlogon/winlogon.h b/reactos/base/system/winlogon/winlogon.h index 4bcaa421c8a..6487484cdf7 100644 --- a/reactos/base/system/winlogon/winlogon.h +++ b/reactos/base/system/winlogon/winlogon.h @@ -27,6 +27,8 @@ #ifndef __WINLOGON_MAIN_H__ #define __WINLOGON_MAIN_H__ +//#define USE_GETLASTINPUTINFO + #define WIN32_NO_STATUS #include #include @@ -137,12 +139,16 @@ typedef struct _WLSESSION DWORD DialogTimeout; /* Timeout for dialog boxes, in seconds */ /* Screen-saver informations */ +#ifndef USE_GETLASTINPUTINFO HHOOK KeyboardHook; HHOOK MouseHook; +#endif HANDLE hEndOfScreenSaverThread; HANDLE hScreenSaverParametersChanged; HANDLE hUserActivity; +#ifndef USE_GETLASTINPUTINFO DWORD LastActivity; +#endif /* Logon informations */ DWORD Options; @@ -171,6 +177,10 @@ UpdatePerUserSystemParameters(DWORD dwUnknown, DWORD dwReserved); /* sas.c */ +BOOL +SetDefaultLanguage( + IN BOOL UserProfile); + BOOL InitializeSAS( IN OUT PWLSESSION Session); From 07f8340c1597d111dbb81cc35badde10d0ffe01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 17:10:51 +0000 Subject: [PATCH 087/488] Use Guid specified in device info set (if available) in SetupDiGetClassDevsExW. Update some documentation (taken from Wine) svn path=/trunk/; revision=23999 --- reactos/dll/win32/setupapi/devclass.c | 74 ++++++++++++++++----------- reactos/dll/win32/setupapi/devinst.c | 27 +++++++--- 2 files changed, 65 insertions(+), 36 deletions(-) diff --git a/reactos/dll/win32/setupapi/devclass.c b/reactos/dll/win32/setupapi/devclass.c index 9bd5f9a764f..f289e394323 100644 --- a/reactos/dll/win32/setupapi/devclass.c +++ b/reactos/dll/win32/setupapi/devclass.c @@ -129,6 +129,9 @@ SetupDiBuildClassInfoList( /*********************************************************************** * SetupDiBuildClassInfoListExA (SETUPAPI.@) * + * Returns a list of setup class GUIDs that identify the classes + * that are installed on a local or remote macine. + * * PARAMS * Flags [I] control exclusion of classes from the list. * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs. @@ -906,10 +909,10 @@ cleanup: * SETUP_CreateDevicesListFromEnumerator * * PARAMS - * list [I] Device info set to fill with discovered devices. + * list [IO] Device info set to fill with discovered devices. * pClassGuid [I] If specified, only devices which belong to this class will be added. * Enumerator [I] Location to search devices to add. - * hEnumeratorKey [O] Registry key corresponding to Enumerator key. Must have KEY_ENUMERATE_SUB_KEYS right. + * hEnumeratorKey [I] Registry key corresponding to Enumerator key. Must have KEY_ENUMERATE_SUB_KEYS right. * * RETURNS * Success: ERROR_SUCCESS. @@ -1169,45 +1172,58 @@ SetupDiGetClassDevsExW( if (Flags & DIGCF_PROFILE) FIXME(": flag DIGCF_PROFILE ignored\n"); - /* FIXME: list->ClassGuid is never used! */ - if (Flags & DIGCF_ALLCLASSES) - pClassGuid = NULL; - else if (ClassGuid) - pClassGuid = ClassGuid; - else - { - SetLastError(ERROR_INVALID_PARAMETER); - goto cleanup; - } - if (Flags & DIGCF_DEVICEINTERFACE) - { rc = SETUP_CreateInterfaceList(list, MachineName, ClassGuid, Enumerator, Flags & DIGCF_PRESENT); - if (rc != ERROR_SUCCESS) - { - SetLastError(rc); - goto cleanup; - } - ret = hDeviceInfo; - } else { + /* Determine which class(es) should be included in the deviceset */ if (Flags & DIGCF_ALLCLASSES) - rc = SETUP_CreateDevicesList(list, MachineName, NULL, Enumerator); + { + /* The caller wants all classes. Check if + * the deviceset limits us to one class */ + if (IsEqualIID(&list->ClassGuid, &GUID_NULL)) + pClassGuid = NULL; + else + pClassGuid = &list->ClassGuid; + } else if (ClassGuid) - rc = SETUP_CreateDevicesList(list, MachineName, pClassGuid, Enumerator); + { + /* The caller wants one class. Check if it matches deviceset class */ + if (IsEqualIID(&list->ClassGuid, ClassGuid) + || IsEqualIID(&list->ClassGuid, &GUID_NULL)) + { + pClassGuid = ClassGuid; + } + else + { + SetLastError(ERROR_INVALID_PARAMETER); + goto cleanup; + } + } + else if (!IsEqualIID(&list->ClassGuid, &GUID_NULL)) + { + /* No class specified. Try to use the one of the deviceset */ + if (IsEqualIID(&list->ClassGuid, &GUID_NULL)) + pClassGuid = &list->ClassGuid; + else + { + SetLastError(ERROR_INVALID_PARAMETER); + goto cleanup; + } + } else { SetLastError(ERROR_INVALID_PARAMETER); goto cleanup; } - if (rc != ERROR_SUCCESS) - { - SetLastError(rc); - goto cleanup; - } - ret = hDeviceInfo; + rc = SETUP_CreateDevicesList(list, MachineName, pClassGuid, Enumerator); } + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + goto cleanup; + } + ret = hDeviceInfo; cleanup: if (!DeviceInfoSet && hDeviceInfo != INVALID_HANDLE_VALUE && hDeviceInfo != ret) diff --git a/reactos/dll/win32/setupapi/devinst.c b/reactos/dll/win32/setupapi/devinst.c index 7cdd36391ab..909196359d7 100644 --- a/reactos/dll/win32/setupapi/devinst.c +++ b/reactos/dll/win32/setupapi/devinst.c @@ -83,7 +83,7 @@ SetupDiCreateDeviceInfoList( IN CONST GUID *ClassGuid OPTIONAL, IN HWND hwndParent OPTIONAL) { - return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL); + return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL); } /*********************************************************************** @@ -112,8 +112,7 @@ SetupDiCreateDeviceInfoListExA( hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, MachineNameW, Reserved); - if (MachineNameW) - MyFree(MachineNameW); + MyFree(MachineNameW); return hDevInfo; } @@ -148,6 +147,20 @@ GetErrorCodeFromCrCode(const IN CONFIGRET cr) /*********************************************************************** * SetupDiCreateDeviceInfoListExW (SETUPAPI.@) + * + * Create an empty DeviceInfoSet list. + * + * PARAMS + * ClassGuid [I] if not NULL only devices with GUID ClcassGuid are associated + * with this list. + * hwndParent [I] hwnd needed for interface related actions. + * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL + * local regestry will be used. + * Reserved [I] must be NULL + * + * RETURNS + * Success: empty list. + * Failure: INVALID_HANDLE_VALUE. */ HDEVINFO WINAPI SetupDiCreateDeviceInfoListExW( @@ -175,7 +188,7 @@ SetupDiCreateDeviceInfoListExW( SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } - memset(list, 0, sizeof(struct DeviceInfoSet)); + ZeroMemory(list, sizeof(struct DeviceInfoSet)); list->magic = SETUP_DEV_INFO_SET_MAGIC; memcpy( @@ -805,7 +818,7 @@ CreateDeviceInfoElement( SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - memset(deviceInfo, 0, size); + ZeroMemory(deviceInfo, size); cr = CM_Locate_DevNode_ExW(&deviceInfo->dnDevInst, (DEVINSTID_W)InstancePath, CM_LOCATE_DEVNODE_PHANTOM, list->hMachine); if (cr != CR_SUCCESS) @@ -1510,7 +1523,7 @@ SetupDiCallClassInstaller( coinstaller = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CoInstallerElement)); if (!coinstaller) continue; - memset(coinstaller, 0, sizeof(struct CoInstallerElement)); + ZeroMemory(coinstaller, sizeof(struct CoInstallerElement)); if (GetFunctionPointer(ptr, &coinstaller->Module, (PVOID*)&coinstaller->Function) == ERROR_SUCCESS) InsertTailList(&DeviceCoInstallersListHead, &coinstaller->ListEntry); else @@ -1554,7 +1567,7 @@ SetupDiCallClassInstaller( coinstaller = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CoInstallerElement)); if (!coinstaller) continue; - memset(coinstaller, 0, sizeof(struct CoInstallerElement)); + ZeroMemory(coinstaller, sizeof(struct CoInstallerElement)); if (GetFunctionPointer(ptr, &coinstaller->Module, (PVOID*)&coinstaller->Function) == ERROR_SUCCESS) InsertTailList(&ClassCoInstallersListHead, &coinstaller->ListEntry); else From 8e420b397426bff3cbd9d9977089abc36ad7b867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 17:11:03 +0000 Subject: [PATCH 088/488] Implement "Check volume" page in usetup. Doesn't work yet because VfatChkdsk() is not implemented svn path=/trunk/; revision=24000 --- reactos/base/setup/usetup/chkdsk.c | 86 +++++++++++++++++++ reactos/base/setup/usetup/chkdsk.h | 36 ++++++++ reactos/base/setup/usetup/format.c | 25 +++--- reactos/base/setup/usetup/fslist.c | 2 +- reactos/base/setup/usetup/usetup.c | 108 ++++++++++++++---------- reactos/base/setup/usetup/usetup.h | 1 + reactos/base/setup/usetup/usetup.rbuild | 3 +- 7 files changed, 205 insertions(+), 56 deletions(-) create mode 100644 reactos/base/setup/usetup/chkdsk.c create mode 100644 reactos/base/setup/usetup/chkdsk.h diff --git a/reactos/base/setup/usetup/chkdsk.c b/reactos/base/setup/usetup/chkdsk.c new file mode 100644 index 00000000000..8752a7baae8 --- /dev/null +++ b/reactos/base/setup/usetup/chkdsk.c @@ -0,0 +1,86 @@ +/* + * ReactOS kernel + * Copyright (C) 2006 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/chkdsk.c + * PURPOSE: Filesystem chkdsk support functions + * PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include "usetup.h" + +#define NDEBUG +#include + +static PPROGRESSBAR ChkdskProgressBar = NULL; + +/* FUNCTIONS ****************************************************************/ + +static BOOLEAN NTAPI +ChkdskCallback( + IN CALLBACKCOMMAND Command, + IN ULONG Modifier, + IN PVOID Argument) +{ + switch (Command) + { + default: + DPRINT("Unknown callback %lu\n", (ULONG)Command); + break; + } + + return TRUE; +} + +NTSTATUS +ChkdskPartition( + IN PUNICODE_STRING DriveRoot, + IN PFILE_SYSTEM_ITEM FileSystem) +{ + NTSTATUS Status; + + if (!FileSystem->ChkdskFunc) + return STATUS_NOT_SUPPORTED; + + ChkdskProgressBar = CreateProgressBar(6, + yScreen - 14, + xScreen - 7, + yScreen - 10, + "Setup is checking your disk"); + + ProgressSetStepCount(ChkdskProgressBar, 100); + + Status = FileSystem->ChkdskFunc(DriveRoot, + TRUE, /* FixErrors */ + FALSE, /* Verbose */ + FALSE, /* CheckOnlyIfDirty */ + FALSE, /* ScanDrive */ + ChkdskCallback); /* Callback */ + + DestroyProgressBar(ChkdskProgressBar); + ChkdskProgressBar = NULL; + + DPRINT("ChkdskPartition() finished with status 0x%08lx\n", Status); + + return Status; +} + +/* EOF */ diff --git a/reactos/base/setup/usetup/chkdsk.h b/reactos/base/setup/usetup/chkdsk.h new file mode 100644 index 00000000000..c9879d65624 --- /dev/null +++ b/reactos/base/setup/usetup/chkdsk.h @@ -0,0 +1,36 @@ +/* + * ReactOS kernel + * Copyright (C) 2006 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/chkdsk.h + * PURPOSE: Filesystem chkdsk support functions + * PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org) + */ + +#ifndef __CHKDSK_H__ +#define __CHKDSK_H__ + +NTSTATUS +ChkdskPartition( + IN PUNICODE_STRING DriveRoot, + IN PFILE_SYSTEM_ITEM FileSystem); + +#endif /* __CHKDSK_H__ */ + +/* EOF */ diff --git a/reactos/base/setup/usetup/format.c b/reactos/base/setup/usetup/format.c index 06137c42b5c..4fcf2622b8b 100644 --- a/reactos/base/setup/usetup/format.c +++ b/reactos/base/setup/usetup/format.c @@ -30,7 +30,7 @@ #define NDEBUG #include -PPROGRESSBAR ProgressBar = NULL; +static PPROGRESSBAR FormatProgressBar = NULL; /* FUNCTIONS ****************************************************************/ @@ -49,7 +49,7 @@ FormatCallback( Percent = (PULONG)Argument; DPRINT("%lu percent completed\n", *Percent); - ProgressSetStep(ProgressBar, *Percent); + ProgressSetStep(FormatProgressBar, *Percent); break; } @@ -89,13 +89,16 @@ FormatPartition( { NTSTATUS Status; - ProgressBar = CreateProgressBar(6, - yScreen - 14, - xScreen - 7, - yScreen - 10, - "Setup is formatting your disk"); + if (!FileSystem->FormatFunc) + return STATUS_NOT_SUPPORTED; - ProgressSetStepCount(ProgressBar, 100); + FormatProgressBar = CreateProgressBar(6, + yScreen - 14, + xScreen - 7, + yScreen - 10, + "Setup is formatting your disk"); + + ProgressSetStepCount(FormatProgressBar, 100); Status = FileSystem->FormatFunc(DriveRoot, FMIFS_HARDDISK, /* MediaFlag */ @@ -104,10 +107,10 @@ FormatPartition( 0, /* ClusterSize */ FormatCallback); /* Callback */ - DestroyProgressBar(ProgressBar); - ProgressBar = NULL; + DestroyProgressBar(FormatProgressBar); + FormatProgressBar = NULL; - DPRINT("FormatEx() finished with status 0x%08lx\n", Status); + DPRINT("FormatPartition() finished with status 0x%08lx\n", Status); return Status; } diff --git a/reactos/base/setup/usetup/fslist.c b/reactos/base/setup/usetup/fslist.c index b8712f82988..e5751a07b33 100644 --- a/reactos/base/setup/usetup/fslist.c +++ b/reactos/base/setup/usetup/fslist.c @@ -85,7 +85,7 @@ CreateFileSystemList( List->Selected = NULL; InitializeListHead(&List->ListHead); - AddProvider(List, "FAT", VfatFormat, NULL); + AddProvider(List, "FAT", VfatFormat, VfatChkdsk); if (!ForceFormat) { /* Add 'Keep' provider */ diff --git a/reactos/base/setup/usetup/usetup.c b/reactos/base/setup/usetup/usetup.c index 7bb7e846d06..3ca85ec7075 100644 --- a/reactos/base/setup/usetup/usetup.c +++ b/reactos/base/setup/usetup/usetup.c @@ -2419,62 +2419,84 @@ FormatPartitionPage (PINPUT_RECORD Ir) static ULONG CheckFileSystemPage(PINPUT_RECORD Ir) { + PFILE_SYSTEM_ITEM CurrentFileSystem; WCHAR PathBuffer[MAX_PATH]; + CHAR Buffer[MAX_PATH]; + NTSTATUS Status; - CONSOLE_SetTextXY(6, 8, "Check file system"); - - CONSOLE_SetTextXY(6, 10, "At present, ReactOS can not check file systems."); - - CONSOLE_SetStatusText(" Please wait ..."); - - - CONSOLE_SetStatusText(" ENTER = Continue F3 = Quit"); - - + /* FIXME: code duplicated in FormatPartitionPage */ /* Set DestinationRootPath */ - RtlFreeUnicodeString (&DestinationRootPath); - swprintf (PathBuffer, - L"\\Device\\Harddisk%lu\\Partition%lu", - PartitionList->CurrentDisk->DiskNumber, - PartitionList->CurrentPartition->PartInfo[0].PartitionNumber); - RtlCreateUnicodeString (&DestinationRootPath, - PathBuffer); - DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath); + RtlFreeUnicodeString(&DestinationRootPath); + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + PartitionList->CurrentDisk->DiskNumber, + PartitionList->CurrentPartition->PartInfo[0].PartitionNumber); + RtlCreateUnicodeString(&DestinationRootPath, PathBuffer); + DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath); /* Set SystemRootPath */ - RtlFreeUnicodeString (&SystemRootPath); - swprintf (PathBuffer, - L"\\Device\\Harddisk%lu\\Partition%lu", - PartitionList->ActiveBootDisk->DiskNumber, - PartitionList->ActiveBootPartition->PartInfo[0].PartitionNumber); - RtlCreateUnicodeString (&SystemRootPath, - PathBuffer); - DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath); + RtlFreeUnicodeString(&SystemRootPath); + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + PartitionList->ActiveBootDisk->DiskNumber, + PartitionList->ActiveBootPartition->PartInfo[0].PartitionNumber); + RtlCreateUnicodeString(&SystemRootPath, PathBuffer); + DPRINT("SystemRootPath: %wZ\n", &SystemRootPath); + CONSOLE_SetTextXY(6, 8, "Setup is now checking the selected partition."); - if (IsUnattendedSetup) - { - return(INSTALL_DIRECTORY_PAGE); - } + CONSOLE_SetStatusText(" Please wait..."); - while(TRUE) + /* WRONG: first filesystem is not necesseraly the one of the current partition! */ + CurrentFileSystem = CONTAINING_RECORD(FileSystemList->ListHead.Flink, FILE_SYSTEM_ITEM, ListEntry); + + if (!CurrentFileSystem->ChkdskFunc) + { + sprintf(Buffer, + "Setup is currently unable to check a partition formatted in %s.\n" + "\n" + " \x07 Press ENTER to continue Setup.\n" + " \x07 Press F3 to quit Setup.", + CurrentFileSystem->FileSystem); + PopupError( + Buffer, + "F3= Quit ENTER = Continue", + NULL, POPUP_WAIT_NONE); + + while(TRUE) { CONSOLE_ConInKey(Ir); - if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && - (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ - { - if (ConfirmQuit(Ir) == TRUE) - return(QUIT_PAGE); - break; - } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(INSTALL_DIRECTORY_PAGE); - } + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00 + && Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3) /* F3 */ + { + if (ConfirmQuit(Ir)) + return QUIT_PAGE; + else + return CHECK_FILE_SYSTEM_PAGE; + } + else if (Ir->Event.KeyEvent.uChar.AsciiChar == VK_RETURN) /* ENTER */ + { + return INSTALL_DIRECTORY_PAGE; + } + } + } + else + { + Status = ChkdskPartition(&DestinationRootPath, CurrentFileSystem); + if (!NT_SUCCESS(Status)) + { + DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status); + sprintf(Buffer, "Setup failed to verify the selected partition.\n" + "(Status 0x%08lx).\n", Status); + PopupError(Buffer, + "ENTER = Reboot computer", + Ir, POPUP_WAIT_ENTER); + return QUIT_PAGE; } - return(CHECK_FILE_SYSTEM_PAGE); + return INSTALL_DIRECTORY_PAGE; + } } diff --git a/reactos/base/setup/usetup/usetup.h b/reactos/base/setup/usetup/usetup.h index fa151f89071..62366e44a77 100644 --- a/reactos/base/setup/usetup/usetup.h +++ b/reactos/base/setup/usetup/usetup.h @@ -65,6 +65,7 @@ #include "keytrans.h" #include "registry.h" #include "fslist.h" +#include "chkdsk.h" #include "format.h" #include "cabinet.h" #include "filesup.h" diff --git a/reactos/base/setup/usetup/usetup.rbuild b/reactos/base/setup/usetup/usetup.rbuild index 1e6a405ef7c..f4eb911b6e7 100644 --- a/reactos/base/setup/usetup/usetup.rbuild +++ b/reactos/base/setup/usetup/usetup.rbuild @@ -13,10 +13,11 @@ inflib vfatlib ntdll - + usetup.h bootsup.c cabinet.c + chkdsk.c console.c drivesup.c filequeue.c From b5957ce8966c2aeb3a4f21cd7be8f112323842b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 17:42:28 +0000 Subject: [PATCH 089/488] Fix MsiDatabaseIsTablePersistentA/W prototype Update msi_ros.diff file for upcoming update svn path=/trunk/; revision=24001 --- reactos/dll/win32/msi/msi_ros.diff | 10538 +++++++++++++-------------- reactos/dll/win32/msi/msiquery.c | 4 +- reactos/include/psdk/msiquery.h | 4 +- 3 files changed, 5270 insertions(+), 5276 deletions(-) diff --git a/reactos/dll/win32/msi/msi_ros.diff b/reactos/dll/win32/msi/msi_ros.diff index 47c970dacdc..57c22de2d8f 100644 --- a/reactos/dll/win32/msi/msi_ros.diff +++ b/reactos/dll/win32/msi/msi_ros.diff @@ -3,5350 +3,5344 @@ Index: action.c --- action.c (revision 23808) +++ action.c (working copy) @@ -30,6 +30,7 @@ - - #define COBJMACROS - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" + + #define COBJMACROS + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" #include "winerror.h" Index: appsearch.c =================================================================== --- appsearch.c (revision 23782) +++ appsearch.c (working copy) @@ -21,6 +21,7 @@ - - #define COBJMACROS - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winreg.h" + + #define COBJMACROS + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winreg.h" Index: classes.c =================================================================== --- classes.c (revision 23808) +++ classes.c (working copy) @@ -31,6 +31,7 @@ - - #include - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winerror.h" + + #include + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winerror.h" Index: cond.tab.c =================================================================== --- cond.tab.c (revision 23782) +++ cond.tab.c (working copy) @@ -0,0 +1,2239 @@ -+/* A Bison parser, made by GNU Bison 1.875c. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -+ -+ 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, 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., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Written by Richard Stallman by simplifying the original so called -+ ``semantic'' parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 1 -+ -+/* Using locations. */ -+#define YYLSP_NEEDED 0 -+ -+/* If NAME_PREFIX is specified substitute the variables and functions -+ names. */ -+#define yyparse COND_parse -+#define yylex COND_lex -+#define yyerror COND_error -+#define yylval COND_lval -+#define yychar COND_char -+#define yydebug COND_debug -+#define yynerrs COND_nerrs -+ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COND_SPACE = 258, -+ COND_EOF = 259, -+ COND_OR = 260, -+ COND_AND = 261, -+ COND_NOT = 262, -+ COND_LT = 263, -+ COND_GT = 264, -+ COND_EQ = 265, -+ COND_LPAR = 266, -+ COND_RPAR = 267, -+ COND_TILDA = 268, -+ COND_PERCENT = 269, -+ COND_DOLLARS = 270, -+ COND_QUESTION = 271, -+ COND_AMPER = 272, -+ COND_EXCLAM = 273, -+ COND_IDENT = 274, -+ COND_NUMBER = 275, -+ COND_LITER = 276, -+ COND_ERROR = 277 -+ }; -+#endif -+#define COND_SPACE 258 -+#define COND_EOF 259 -+#define COND_OR 260 -+#define COND_AND 261 -+#define COND_NOT 262 -+#define COND_LT 263 -+#define COND_GT 264 -+#define COND_EQ 265 -+#define COND_LPAR 266 -+#define COND_RPAR 267 -+#define COND_TILDA 268 -+#define COND_PERCENT 269 -+#define COND_DOLLARS 270 -+#define COND_QUESTION 271 -+#define COND_AMPER 272 -+#define COND_EXCLAM 273 -+#define COND_IDENT 274 -+#define COND_NUMBER 275 -+#define COND_LITER 276 -+#define COND_ERROR 277 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+#line 1 "./cond.y" -+ -+ -+/* -+ * Implementation of the Microsoft Installer (msi.dll) -+ * -+ * Copyright 2003 Mike McCormack for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "wine/debug.h" -+#include "wine/unicode.h" -+ -+#include "msi.h" -+#include "msiquery.h" -+#include "msipriv.h" -+ -+#define YYLEX_PARAM info -+#define YYPARSE_PARAM info -+ -+static int COND_error(const char *str); -+ -+WINE_DEFAULT_DEBUG_CHANNEL(msi); -+ -+typedef struct tag_yyinput -+{ -+ MSIPACKAGE *package; -+ LPCWSTR str; -+ INT n; -+ MSICONDITION result; -+} COND_input; -+ -+struct cond_str { -+ LPCWSTR data; -+ INT len; -+}; -+ -+static LPWSTR COND_GetString( struct cond_str *str ); -+static LPWSTR COND_GetLiteral( struct cond_str *str ); -+static int COND_lex( void *COND_lval, COND_input *info); -+ -+typedef INT (*comp_int)(INT a, INT b); -+typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless); -+typedef INT (*comp_m1)(LPWSTR a,int b); -+typedef INT (*comp_m2)(int a,LPWSTR b); -+ -+static INT comp_lt_i(INT a, INT b); -+static INT comp_gt_i(INT a, INT b); -+static INT comp_le_i(INT a, INT b); -+static INT comp_ge_i(INT a, INT b); -+static INT comp_eq_i(INT a, INT b); -+static INT comp_ne_i(INT a, INT b); -+static INT comp_bitand(INT a, INT b); -+static INT comp_highcomp(INT a, INT b); -+static INT comp_lowcomp(INT a, INT b); -+ -+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless); -+ -+static INT comp_eq_m1(LPWSTR a, INT b); -+static INT comp_ne_m1(LPWSTR a, INT b); -+static INT comp_lt_m1(LPWSTR a, INT b); -+static INT comp_gt_m1(LPWSTR a, INT b); -+static INT comp_le_m1(LPWSTR a, INT b); -+static INT comp_ge_m1(LPWSTR a, INT b); -+ -+static INT comp_eq_m2(INT a, LPWSTR b); -+static INT comp_ne_m2(INT a, LPWSTR b); -+static INT comp_lt_m2(INT a, LPWSTR b); -+static INT comp_gt_m2(INT a, LPWSTR b); -+static INT comp_le_m2(INT a, LPWSTR b); -+static INT comp_ge_m2(INT a, LPWSTR b); -+ -+ -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 106 "./cond.y" -+typedef union YYSTYPE { -+ struct cond_str str; -+ LPWSTR string; -+ INT value; -+ comp_int fn_comp_int; -+ comp_str fn_comp_str; -+ comp_m1 fn_comp_m1; -+ comp_m2 fn_comp_m2; -+} YYSTYPE; -+/* Line 191 of yacc.c. */ -+#line 241 "cond.tab.c" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+/* Copy the second part of user declarations. */ -+ -+ -+/* Line 214 of yacc.c. */ -+#line 253 "cond.tab.c" -+ -+#if ! defined (yyoverflow) || YYERROR_VERBOSE -+ -+# ifndef YYFREE -+# define YYFREE free -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# endif -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# define YYSTACK_ALLOC alloca -+# endif -+# else -+# if defined (alloca) || defined (_ALLOCA_H) -+# define YYSTACK_ALLOC alloca -+# else -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+# else -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# endif -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# endif -+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ -+ -+ -+#if (! defined (yyoverflow) \ -+ && (! defined (__cplusplus) \ -+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ short yyss; -+ YYSTYPE yyvs; -+ }; -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ -+ + YYSTACK_GAP_MAXIMUM) -+ -+/* Copy COUNT objects from FROM to TO. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined (__GNUC__) && 1 < __GNUC__ -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# else -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ register YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (0) -+# endif -+# endif -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack, Stack, yysize); \ -+ Stack = &yyptr->Stack; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) -+ -+#endif -+ -+#if defined (__STDC__) || defined (__cplusplus) -+ typedef signed char yysigned_char; -+#else -+ typedef short yysigned_char; -+#endif -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 30 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 146 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 23 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 17 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 65 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 74 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 277 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const unsigned char yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22 -+}; -+ -+#if YYDEBUG -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const unsigned char yyprhs[] = -+{ -+ 0, 0, 3, 5, 7, 11, 13, 17, 19, 22, -+ 24, 26, 30, 34, 39, 43, 47, 51, 53, 56, -+ 58, 60, 63, 66, 69, 72, 75, 77, 80, 82, -+ 84, 87, 90, 93, 96, 99, 101, 104, 106, 108, -+ 111, 114, 117, 120, 123, 125, 128, 130, 132, 135, -+ 138, 141, 144, 147, 149, 151, 153, 155, 157, 160, -+ 163, 166, 169, 171, 174, 176 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yysigned_char yyrhs[] = -+{ -+ 24, 0, -1, 25, -1, 26, -1, 26, 5, 25, -+ -1, 27, -1, 26, 6, 27, -1, 28, -1, 7, -+ 28, -1, 33, -1, 34, -1, 33, 29, 33, -1, -+ 34, 30, 34, -1, 34, 13, 30, 34, -1, 34, -+ 31, 33, -1, 33, 32, 34, -1, 11, 25, 12, -+ -1, 10, -1, 8, 9, -1, 8, -1, 9, -1, -+ 8, 10, -1, 9, 10, -1, 9, 8, -1, 8, -+ 8, -1, 9, 9, -1, 10, -1, 8, 9, -1, -+ 8, -1, 9, -1, 8, 10, -1, 9, 10, -1, -+ 9, 8, -1, 8, 8, -1, 9, 9, -1, 10, -+ -1, 8, 9, -1, 8, -1, 9, -1, 8, 10, -+ -1, 9, 10, -1, 9, 8, -1, 8, 8, -1, -+ 9, 9, -1, 10, -1, 8, 9, -1, 8, -1, -+ 9, -1, 8, 10, -1, 9, 10, -1, 9, 8, -+ -1, 8, 8, -1, 9, 9, -1, 36, -1, 39, -+ -1, 37, -1, 35, -1, 21, -1, 15, 38, -1, -+ 16, 38, -1, 17, 38, -1, 18, 38, -1, 38, -+ -1, 14, 38, -1, 19, -1, 20, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const unsigned short yyrline[] = -+{ -+ 0, 136, 136, 144, 148, 155, 159, 166, 170, 178, -+ 182, 187, 191, 197, 203, 208, 213, 221, 225, 229, -+ 233, 237, 241, 246, 250, 254, 262, 266, 270, 274, -+ 278, 282, 287, 291, 295, 303, 307, 311, 315, 319, -+ 323, 328, 332, 336, 344, 348, 352, 356, 360, 364, -+ 369, 373, 377, 384, 388, 395, 399, 406, 415, 424, -+ 433, 442, 454, 477, 491, 500 -+}; -+#endif -+ -+#if YYDEBUG || YYERROR_VERBOSE -+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR", -+ "COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR", -+ "COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS", -+ "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT", -+ "COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition", -+ "expression", "boolean_term", "boolean_factor", "term", "comp_op_i", -+ "comp_op_s", "comp_op_m1", "comp_op_m2", "value_i", "value_s", "literal", -+ "symbol_i", "symbol_s", "identifier", "integer", 0 -+}; -+#endif -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const unsigned short yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -+ 275, 276, 277 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const unsigned char yyr1[] = -+{ -+ 0, 23, 24, 25, 25, 26, 26, 27, 27, 28, -+ 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, -+ 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, -+ 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, -+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, -+ 32, 32, 32, 33, 33, 34, 34, 35, 36, 36, -+ 36, 36, 37, 37, 38, 39 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const unsigned char yyr2[] = -+{ -+ 0, 2, 1, 1, 3, 1, 3, 1, 2, 1, -+ 1, 3, 3, 4, 3, 3, 3, 1, 2, 1, -+ 1, 2, 2, 2, 2, 2, 1, 2, 1, 1, -+ 2, 2, 2, 2, 2, 1, 2, 1, 1, 2, -+ 2, 2, 2, 2, 1, 2, 1, 1, 2, 2, -+ 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, -+ 2, 2, 1, 2, 1, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state -+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const unsigned char yydefact[] = -+{ -+ 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, -+ 57, 0, 2, 3, 5, 7, 9, 10, 56, 53, -+ 55, 62, 54, 8, 0, 63, 58, 59, 60, 61, -+ 1, 0, 0, 19, 20, 17, 0, 0, 37, 38, -+ 35, 0, 0, 0, 16, 4, 6, 24, 18, 21, -+ 23, 25, 22, 11, 15, 42, 36, 39, 41, 43, -+ 40, 28, 29, 26, 0, 12, 14, 33, 27, 30, -+ 32, 34, 31, 13 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const yysigned_char yydefgoto[] = -+{ -+ -1, 11, 12, 13, 14, 15, 36, 42, 43, 37, -+ 16, 17, 18, 19, 20, 21, 22 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -37 -+static const short yypact[] = -+{ -+ -4, 51, -4, -11, -11, -11, -11, -11, -37, -37, -+ -37, 18, -37, -1, -37, -37, 49, 14, -37, -37, -+ -37, -37, -37, -37, 19, -37, -37, -37, -37, -37, -+ -37, -4, -4, 11, 25, 34, 111, 59, 28, 42, -+ 60, 130, 59, 111, -37, -37, -37, 63, 69, 72, -+ 73, 81, 82, -37, -37, 85, 91, 94, 95, 103, -+ 104, 133, 136, -37, 59, -37, -37, -37, -37, -37, -+ -37, -37, -37, -37 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const short yypgoto[] = -+{ -+ -37, -37, -2, -37, -6, 39, -37, 0, -37, -37, -+ -34, -36, -37, -37, -37, 129, -37 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If zero, do what YYDEFACT says. -+ If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -53 -+static const yysigned_char yytable[] = -+{ -+ 24, 54, 53, 1, 31, 32, 65, 2, 8, 66, -+ 3, 4, 5, 6, 7, 8, 9, 10, 30, 47, -+ 48, 49, 38, 39, 40, -46, 46, 41, 73, 45, -+ -46, 44, -46, 50, 51, 52, 55, 56, 57, -47, -+ 23, 64, -28, 0, -47, 0, -47, -28, -44, -28, -+ 58, 59, 60, -44, 0, -44, -29, 33, 34, 35, -+ 0, -29, 2, -29, 0, 3, 4, 5, 6, 7, -+ 8, 9, 10, 3, -26, 0, 0, -51, 8, -26, -+ 10, -26, -51, -45, -51, 0, -48, -50, -45, 0, -+ -45, -48, -50, -48, -50, -52, -49, 0, 0, -33, -+ -52, -49, -52, -49, -33, -27, -33, 0, -30, -32, -+ -27, 0, -27, -30, -32, -30, -32, -34, -31, 0, -+ 0, 0, -34, -31, -34, -31, 4, 5, 6, 7, -+ 0, 9, 25, 26, 27, 28, 29, 0, 61, 62, -+ 63, 67, 68, 69, 70, 71, 72 -+}; -+ -+static const yysigned_char yycheck[] = -+{ -+ 2, 37, 36, 7, 5, 6, 42, 11, 19, 43, -+ 14, 15, 16, 17, 18, 19, 20, 21, 0, 8, -+ 9, 10, 8, 9, 10, 14, 32, 13, 64, 31, -+ 19, 12, 21, 8, 9, 10, 8, 9, 10, 14, -+ 1, 41, 14, -1, 19, -1, 21, 19, 14, 21, -+ 8, 9, 10, 19, -1, 21, 14, 8, 9, 10, -+ -1, 19, 11, 21, -1, 14, 15, 16, 17, 18, -+ 19, 20, 21, 14, 14, -1, -1, 14, 19, 19, -+ 21, 21, 19, 14, 21, -1, 14, 14, 19, -1, -+ 21, 19, 19, 21, 21, 14, 14, -1, -1, 14, -+ 19, 19, 21, 21, 19, 14, 21, -1, 14, 14, -+ 19, -1, 21, 19, 19, 21, 21, 14, 14, -1, -+ -1, -1, 19, 19, 21, 21, 15, 16, 17, 18, -+ -1, 20, 3, 4, 5, 6, 7, -1, 8, 9, -+ 10, 8, 9, 10, 8, 9, 10 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const unsigned char yystos[] = -+{ -+ 0, 7, 11, 14, 15, 16, 17, 18, 19, 20, -+ 21, 24, 25, 26, 27, 28, 33, 34, 35, 36, -+ 37, 38, 39, 28, 25, 38, 38, 38, 38, 38, -+ 0, 5, 6, 8, 9, 10, 29, 32, 8, 9, -+ 10, 13, 30, 31, 12, 25, 27, 8, 9, 10, -+ 8, 9, 10, 33, 34, 8, 9, 10, 8, 9, -+ 10, 8, 9, 10, 30, 34, 33, 8, 9, 10, -+ 8, 9, 10, 34 -+}; -+ -+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -+# define YYSIZE_T __SIZE_TYPE__ -+#endif -+#if ! defined (YYSIZE_T) && defined (size_t) -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# endif -+#endif -+#if ! defined (YYSIZE_T) -+# define YYSIZE_T unsigned int -+#endif -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. */ -+ -+#define YYFAIL goto yyerrlab -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ yytoken = YYTRANSLATE (yychar); \ -+ YYPOPSTACK; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror ("syntax error: cannot back up");\ -+ YYERROR; \ -+ } \ -+while (0) -+ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+/* YYLLOC_DEFAULT -- Compute the default location (before the actions -+ are run). */ -+ -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ ((Current).first_line = (Rhs)[1].first_line, \ -+ (Current).first_column = (Rhs)[1].first_column, \ -+ (Current).last_line = (Rhs)[N].last_line, \ -+ (Current).last_column = (Rhs)[N].last_column) -+#endif -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (&yylval, YYLEX_PARAM) -+#else -+# define YYLEX yylex (&yylval) -+#endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ -+# define YYDSYMPRINT(Args) \ -+do { \ -+ if (yydebug) \ -+ yysymprint Args; \ -+} while (0) -+ -+# define YYDSYMPRINTF(Title, Token, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yysymprint (stderr, \ -+ Token, Value); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_stack_print (short *bottom, short *top) -+#else -+static void -+yy_stack_print (bottom, top) -+ short *bottom; -+ short *top; -+#endif -+{ -+ YYFPRINTF (stderr, "Stack now"); -+ for (/* Nothing. */; bottom <= top; ++bottom) -+ YYFPRINTF (stderr, " %d", *bottom); -+ YYFPRINTF (stderr, "\n"); -+} -+ -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) -+ -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_reduce_print (int yyrule) -+#else -+static void -+yy_reduce_print (yyrule) -+ int yyrule; -+#endif -+{ -+ int yyi; -+ unsigned int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", -+ yyrule - 1, yylno); -+ /* Print the symbols being reduced, and their result. */ -+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) -+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); -+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -+} -+ -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (Rule); \ -+} while (0) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YYDSYMPRINT(Args) -+# define YYDSYMPRINTF(Title, Token, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 -+# undef YYMAXDEPTH -+#endif -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined (__GLIBC__) && defined (_STRING_H) -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+static YYSIZE_T -+# if defined (__STDC__) || defined (__cplusplus) -+yystrlen (const char *yystr) -+# else -+yystrlen (yystr) -+ const char *yystr; -+# endif -+{ -+ register const char *yys = yystr; -+ -+ while (*yys++ != '\0') -+ continue; -+ -+ return yys - yystr - 1; -+} -+# endif -+# endif -+ -+# ifndef yystpcpy -+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+static char * -+# if defined (__STDC__) || defined (__cplusplus) -+yystpcpy (char *yydest, const char *yysrc) -+# else -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+# endif -+{ -+ register char *yyd = yydest; -+ register const char *yys = yysrc; -+ -+ while ((*yyd++ = *yys++) != '\0') -+ continue; -+ -+ return yyd - 1; -+} -+# endif -+# endif -+ -+#endif /* !YYERROR_VERBOSE */ -+ -+ -+ -+#if YYDEBUG -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yysymprint (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (yytype < YYNTOKENS) -+ { -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+# ifdef YYPRINT -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# endif -+ } -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+ YYFPRINTF (yyoutput, ")"); -+} -+ -+#endif /* ! YYDEBUG */ -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yydestruct (int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yydestruct (yytype, yyvaluep) -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } -+} -+ -+ -+/* Prevent warnings from -Wmissing-prototypes. */ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM); -+# else -+int yyparse (); -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+ -+ -+ -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM) -+# else -+int yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int -+yyparse (void) -+#else -+int -+yyparse () -+ -+#endif -+#endif -+{ -+ /* The lookahead symbol. */ -+int yychar; -+ -+/* The semantic value of the lookahead symbol. */ -+YYSTYPE yylval; -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+ -+ register int yystate; -+ register int yyn; -+ int yyresult; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ /* Lookahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+ -+ /* Three stacks and their tools: -+ `yyss': related to states, -+ `yyvs': related to semantic values, -+ `yyls': related to locations. -+ -+ Refer to the stacks thru separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ short yyssa[YYINITDEPTH]; -+ short *yyss = yyssa; -+ register short *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs = yyvsa; -+ register YYSTYPE *yyvsp; -+ -+ -+ -+#define YYPOPSTACK (yyvsp--, yyssp--) -+ -+ YYSIZE_T yystacksize = YYINITDEPTH; -+ -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ -+ -+ /* When reducing, the number of symbols on the RHS of the reduced -+ rule. */ -+ int yylen; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. so pushing a state here evens the stacks. -+ */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ short *yyss1 = yyss; -+ -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow ("parser stack overflow", -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ -+ &yystacksize); -+ -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyoverflowlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyoverflowlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ short *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyoverflowlab; -+ YYSTACK_RELOCATE (yyss); -+ YYSTACK_RELOCATE (yyvs); -+ -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; -+ } -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+/* Do appropriate processing given the current state. */ -+/* Read a lookahead token if we need one and don't already have one. */ -+/* yyresume: */ -+ -+ /* First try to decide what to do without reference to lookahead token. */ -+ -+ yyn = yypact[yystate]; -+ if (yyn == YYPACT_NINF) -+ goto yydefault; -+ -+ /* Not known => get a lookahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ -+ if (yychar == YYEMPTY) -+ { -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) -+ { -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); -+ } -+ else -+ { -+ yytoken = YYTRANSLATE (yychar); -+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yyn == 0 || yyn == YYTABLE_NINF) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ /* Shift the lookahead token. */ -+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); -+ -+ /* Discard the token being shifted unless it is eof. */ -+ if (yychar != YYEOF) -+ yychar = YYEMPTY; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ -+yyreduce: -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+#line 137 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ cond->result = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 3: -+#line 145 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 4: -+#line 149 "./cond.y" -+ { -+ yyval.value = yyvsp[-2].value || yyvsp[0].value; -+ ;} -+ break; -+ -+ case 5: -+#line 156 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 6: -+#line 160 "./cond.y" -+ { -+ yyval.value = yyvsp[-2].value && yyvsp[0].value; -+ ;} -+ break; -+ -+ case 7: -+#line 167 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 8: -+#line 171 "./cond.y" -+ { -+ yyval.value = ! yyvsp[0].value; -+ ;} -+ break; -+ -+ case 9: -+#line 179 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 10: -+#line 183 "./cond.y" -+ { -+ yyval.value = (yyvsp[0].string && yyvsp[0].string[0]) ? MSICONDITION_TRUE : MSICONDITION_FALSE; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 11: -+#line 188 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_int( yyvsp[-2].value, yyvsp[0].value ); -+ ;} -+ break; -+ -+ case 12: -+#line 192 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-2].string, yyvsp[0].string, FALSE ); -+ msi_free( yyvsp[-2].string ); -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 13: -+#line 198 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-3].string, yyvsp[0].string, TRUE ); -+ msi_free( yyvsp[-3].string ); -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 14: -+#line 204 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_m1( yyvsp[-2].string, yyvsp[0].value ); -+ msi_free( yyvsp[-2].string ); -+ ;} -+ break; -+ -+ case 15: -+#line 209 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_m2( yyvsp[-2].value, yyvsp[0].string ); -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 16: -+#line 214 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].value; -+ ;} -+ break; -+ -+ case 17: -+#line 222 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_eq_i; -+ ;} -+ break; -+ -+ case 18: -+#line 226 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_ne_i; -+ ;} -+ break; -+ -+ case 19: -+#line 230 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_lt_i; -+ ;} -+ break; -+ -+ case 20: -+#line 234 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_gt_i; -+ ;} -+ break; -+ -+ case 21: -+#line 238 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_le_i; -+ ;} -+ break; -+ -+ case 22: -+#line 242 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_ge_i; -+ ;} -+ break; -+ -+ case 23: -+#line 247 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_bitand; -+ ;} -+ break; -+ -+ case 24: -+#line 251 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_highcomp; -+ ;} -+ break; -+ -+ case 25: -+#line 255 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_lowcomp; -+ ;} -+ break; -+ -+ case 26: -+#line 263 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_eq_s; -+ ;} -+ break; -+ -+ case 27: -+#line 267 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_ne_s; -+ ;} -+ break; -+ -+ case 28: -+#line 271 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_lt_s; -+ ;} -+ break; -+ -+ case 29: -+#line 275 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_gt_s; -+ ;} -+ break; -+ -+ case 30: -+#line 279 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_le_s; -+ ;} -+ break; -+ -+ case 31: -+#line 283 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_ge_s; -+ ;} -+ break; -+ -+ case 32: -+#line 288 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_substring; -+ ;} -+ break; -+ -+ case 33: -+#line 292 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_start; -+ ;} -+ break; -+ -+ case 34: -+#line 296 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_end; -+ ;} -+ break; -+ -+ case 35: -+#line 304 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_eq_m1; -+ ;} -+ break; -+ -+ case 36: -+#line 308 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_ne_m1; -+ ;} -+ break; -+ -+ case 37: -+#line 312 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_lt_m1; -+ ;} -+ break; -+ -+ case 38: -+#line 316 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_gt_m1; -+ ;} -+ break; -+ -+ case 39: -+#line 320 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_le_m1; -+ ;} -+ break; -+ -+ case 40: -+#line 324 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_ge_m1; -+ ;} -+ break; -+ -+ case 41: -+#line 329 "./cond.y" -+ { -+ yyval.fn_comp_m1 = 0; -+ ;} -+ break; -+ -+ case 42: -+#line 333 "./cond.y" -+ { -+ yyval.fn_comp_m1 = 0; -+ ;} -+ break; -+ -+ case 43: -+#line 337 "./cond.y" -+ { -+ yyval.fn_comp_m1 = 0; -+ ;} -+ break; -+ -+ case 44: -+#line 345 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_eq_m2; -+ ;} -+ break; -+ -+ case 45: -+#line 349 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_ne_m2; -+ ;} -+ break; -+ -+ case 46: -+#line 353 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_lt_m2; -+ ;} -+ break; -+ -+ case 47: -+#line 357 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_gt_m2; -+ ;} -+ break; -+ -+ case 48: -+#line 361 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_le_m2; -+ ;} -+ break; -+ -+ case 49: -+#line 365 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_ge_m2; -+ ;} -+ break; -+ -+ case 50: -+#line 370 "./cond.y" -+ { -+ yyval.fn_comp_m2 = 0; -+ ;} -+ break; -+ -+ case 51: -+#line 374 "./cond.y" -+ { -+ yyval.fn_comp_m2 = 0; -+ ;} -+ break; -+ -+ case 52: -+#line 378 "./cond.y" -+ { -+ yyval.fn_comp_m2 = 0; -+ ;} -+ break; -+ -+ case 53: -+#line 385 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 54: -+#line 389 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 55: -+#line 396 "./cond.y" -+ { -+ yyval.string = yyvsp[0].string; -+ ;} -+ break; -+ -+ case 56: -+#line 400 "./cond.y" -+ { -+ yyval.string = yyvsp[0].string; -+ ;} -+ break; -+ -+ case 57: -+#line 407 "./cond.y" -+ { -+ yyval.string = COND_GetLiteral(&yyvsp[0].str); -+ if( !yyval.string ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 58: -+#line 416 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action ); -+ yyval.value = action; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 59: -+#line 425 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action ); -+ yyval.value = install; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 60: -+#line 434 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action ); -+ yyval.value = action; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 61: -+#line 443 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action ); -+ yyval.value = install; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 62: -+#line 455 "./cond.y" -+ { -+ DWORD sz; -+ COND_input* cond = (COND_input*) info; -+ -+ sz = 0; -+ MSI_GetPropertyW(cond->package, yyvsp[0].string, NULL, &sz); -+ if (sz == 0) -+ { -+ yyval.string = msi_alloc( sizeof(WCHAR)); -+ yyval.string[0] = 0; -+ } -+ else -+ { -+ sz ++; -+ yyval.string = msi_alloc( sz*sizeof (WCHAR) ); -+ -+ /* Lookup the identifier */ -+ -+ MSI_GetPropertyW(cond->package,yyvsp[0].string,yyval.string,&sz); -+ } -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 63: -+#line 478 "./cond.y" -+ { -+ UINT len = GetEnvironmentVariableW( yyvsp[0].string, NULL, 0 ); -+ if( len++ ) -+ { -+ yyval.string = msi_alloc( len*sizeof (WCHAR) ); -+ if( yyval.string ) -+ GetEnvironmentVariableW( yyvsp[0].string, yyval.string, len ); -+ } -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 64: -+#line 492 "./cond.y" -+ { -+ yyval.string = COND_GetString(&yyvsp[0].str); -+ if( !yyval.string ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 65: -+#line 501 "./cond.y" -+ { -+ LPWSTR szNum = COND_GetString(&yyvsp[0].str); -+ if( !szNum ) -+ YYABORT; -+ yyval.value = atoiW( szNum ); -+ msi_free( szNum ); -+ ;} -+ break; -+ -+ -+ } -+ -+/* Line 1000 of yacc.c. */ -+#line 1733 "cond.tab.c" -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ -+ -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) -+ { -+ ++yynerrs; -+#if YYERROR_VERBOSE -+ yyn = yypact[yystate]; -+ -+ if (YYPACT_NINF < yyn && yyn < YYLAST) -+ { -+ YYSIZE_T yysize = 0; -+ int yytype = YYTRANSLATE (yychar); -+ const char* yyprefix; -+ char *yymsg; -+ int yyx; -+ -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yycount = 0; -+ -+ yyprefix = ", expecting "; -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); -+ yycount += 1; -+ if (yycount == 5) -+ { -+ yysize = 0; -+ break; -+ } -+ } -+ yysize += (sizeof ("syntax error, unexpected ") -+ + yystrlen (yytname[yytype])); -+ yymsg = (char *) YYSTACK_ALLOC (yysize); -+ if (yymsg != 0) -+ { -+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); -+ yyp = yystpcpy (yyp, yytname[yytype]); -+ -+ if (yycount < 5) -+ { -+ yyprefix = ", expecting "; -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ yyp = yystpcpy (yyp, yyprefix); -+ yyp = yystpcpy (yyp, yytname[yyx]); -+ yyprefix = " or "; -+ } -+ } -+ yyerror (yymsg); -+ YYSTACK_FREE (yymsg); -+ } -+ else -+ yyerror ("syntax error; also virtual memory exhausted"); -+ } -+ else -+#endif /* YYERROR_VERBOSE */ -+ yyerror ("syntax error"); -+ } -+ -+ -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse lookahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* If at end of input, pop the error token, -+ then the rest of the stack, then return failure. */ -+ if (yychar == YYEOF) -+ for (;;) -+ { -+ YYPOPSTACK; -+ if (yyssp == yyss) -+ YYABORT; -+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); -+ yydestruct (yystos[*yyssp], yyvsp); -+ } -+ } -+ else -+ { -+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); -+ yydestruct (yytoken, &yylval); -+ yychar = YYEMPTY; -+ -+ } -+ } -+ -+ /* Else will try to reuse lookahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+#ifdef __GNUC__ -+ /* Pacify GCC when the user code never invokes YYERROR and the label -+ yyerrorlab therefore never appears in user code. */ -+ if (0) -+ goto yyerrorlab; -+#endif -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (yyn != YYPACT_NINF) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); -+ yydestruct (yystos[yystate], yyvsp); -+ YYPOPSTACK; -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ YYDPRINTF ((stderr, "Shifting error token, ")); -+ -+ *++yyvsp = yylval; -+ -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#ifndef yyoverflow -+/*----------------------------------------------. -+| yyoverflowlab -- parser overflow comes here. | -+`----------------------------------------------*/ -+yyoverflowlab: -+ yyerror ("parser stack overflow"); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+ return yyresult; -+} -+ -+ -+#line 510 "./cond.y" -+ -+ -+ -+static int COND_IsAlpha( WCHAR x ) -+{ -+ return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) || -+ ( ( x >= 'a' ) && ( x <= 'z' ) ) || -+ ( ( x == '_' ) ) ); -+} -+ -+static int COND_IsNumber( WCHAR x ) -+{ -+ return( (( x >= '0' ) && ( x <= '9' )) || (x =='-') || (x =='.') ); -+} -+ -+ -+/* the mess of comparison functions */ -+ -+static INT comp_lt_i(INT a, INT b) -+{ return (a < b); } -+static INT comp_gt_i(INT a, INT b) -+{ return (a > b); } -+static INT comp_le_i(INT a, INT b) -+{ return (a <= b); } -+static INT comp_ge_i(INT a, INT b) -+{ return (a >= b); } -+static INT comp_eq_i(INT a, INT b) -+{ return (a == b); } -+static INT comp_ne_i(INT a, INT b) -+{ return (a != b); } -+static INT comp_bitand(INT a, INT b) -+{ return a & b;} -+static INT comp_highcomp(INT a, INT b) -+{ return HIWORD(a)==b; } -+static INT comp_lowcomp(INT a, INT b) -+{ return LOWORD(a)==b; } -+ -+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return !strcmpiW(a,b); else return !strcmpW(a,b);} -+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b); else return strcmpW(a,b);} -+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b)<0; else return strcmpW(a,b)<0;} -+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b)>0; else return strcmpW(a,b)>0;} -+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b)<=0; else return strcmpW(a,b)<=0;} -+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b)>=0; else return strcmpW(a,b)>=0;} -+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless) -+/* ERROR NOT WORKING REWRITE */ -+{ if (casless) return strstrW(a,b)!=NULL; else return strstrW(a,b)!=NULL;} -+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strncmpiW(a,b,strlenW(b))==0; -+ else return strncmpW(a,b,strlenW(b))==0;} -+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless) -+{ -+ int i = strlenW(a); -+ int j = strlenW(b); -+ if (j>i) -+ return 0; -+ if (casless) return (!strcmpiW(&a[i-j-1],b)); -+ else return (!strcmpW(&a[i-j-1],b)); -+} -+ -+ -+static INT comp_eq_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;} -+static INT comp_ne_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;} -+static INT comp_lt_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)b; else return 0;} -+static INT comp_le_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;} -+static INT comp_ge_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;} -+ -+static INT comp_eq_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;} -+static INT comp_ne_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;} -+static INT comp_lt_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;} -+static INT comp_gt_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;} -+static INT comp_le_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;} -+static INT comp_ge_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;} -+ -+ -+ -+static int COND_IsIdent( WCHAR x ) -+{ -+ return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) -+ || ( x == '#' ) || (x == '.') ); -+} -+ -+static int COND_GetOne( struct cond_str *str, COND_input *cond ) -+{ -+ static const WCHAR szNot[] = {'N','O','T',0}; -+ static const WCHAR szAnd[] = {'A','N','D',0}; -+ static const WCHAR szOr[] = {'O','R',0}; -+ WCHAR ch; -+ int rc, len = 1; -+ -+ str->data = &cond->str[cond->n]; -+ -+ ch = str->data[0]; -+ switch( ch ) -+ { -+ case 0: return 0; -+ case '(': rc = COND_LPAR; break; -+ case ')': rc = COND_RPAR; break; -+ case '&': rc = COND_AMPER; break; -+ case '!': rc = COND_EXCLAM; break; -+ case '$': rc = COND_DOLLARS; break; -+ case '?': rc = COND_QUESTION; break; -+ case '%': rc = COND_PERCENT; break; -+ case ' ': rc = COND_SPACE; break; -+ case '=': rc = COND_EQ; break; -+ case '~': rc = COND_TILDA; break; -+ case '<': rc = COND_LT; break; -+ case '>': rc = COND_GT; break; -+ case '"': -+ { -+ const WCHAR *ch2 = str->data + 1; -+ -+ -+ while ( *ch2 && *ch2 != '"' ) -+ ++ch2; -+ if (*ch2 == '"') -+ { -+ len = ch2 - str->data + 1; -+ rc = COND_LITER; -+ break; -+ } -+ } -+ ERR("Unterminated string\n"); -+ rc = COND_ERROR; -+ break; -+ default: -+ if( COND_IsAlpha( ch ) ) -+ { -+ while( COND_IsIdent( str->data[len] ) ) -+ len++; -+ rc = COND_IDENT; -+ break; -+ } -+ -+ if( COND_IsNumber( ch ) ) -+ { -+ while( COND_IsNumber( str->data[len] ) ) -+ len++; -+ rc = COND_NUMBER; -+ break; -+ } -+ -+ ERR("Got unknown character %c(%x)\n",ch,ch); -+ rc = COND_ERROR; -+ break; -+ } -+ -+ /* keyword identifiers */ -+ if( rc == COND_IDENT ) -+ { -+ if( (len==3) && (strncmpiW(str->data,szNot,len)==0) ) -+ rc = COND_NOT; -+ else if( (len==3) && (strncmpiW(str->data,szAnd,len)==0) ) -+ rc = COND_AND; -+ else if( (len==2) && (strncmpiW(str->data,szOr,len)==0) ) -+ rc = COND_OR; -+ } -+ -+ cond->n += len; -+ str->len = len; -+ -+ return rc; -+} -+ -+static int COND_lex( void *COND_lval, COND_input *cond ) -+{ -+ int rc; -+ struct cond_str *str = COND_lval; -+ -+ do { -+ rc = COND_GetOne( str, cond ); -+ } while (rc == COND_SPACE); -+ -+ return rc; -+} -+ -+static LPWSTR COND_GetString( struct cond_str *str ) -+{ -+ LPWSTR ret; -+ -+ ret = msi_alloc( (str->len+1) * sizeof (WCHAR) ); -+ if( ret ) -+ { -+ memcpy( ret, str->data, str->len * sizeof(WCHAR)); -+ ret[str->len]=0; -+ } -+ TRACE("Got identifier %s\n",debugstr_w(ret)); -+ return ret; -+} -+ -+static LPWSTR COND_GetLiteral( struct cond_str *str ) -+{ -+ LPWSTR ret; -+ -+ ret = msi_alloc( (str->len-1) * sizeof (WCHAR) ); -+ if( ret ) -+ { -+ memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) ); -+ ret[str->len - 2]=0; -+ } -+ TRACE("Got literal %s\n",debugstr_w(ret)); -+ return ret; -+} -+ -+static int COND_error(const char *str) -+{ -+ return 0; -+} -+ -+MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition ) -+{ -+ COND_input cond; -+ MSICONDITION r; -+ -+ cond.package = package; -+ cond.str = szCondition; -+ cond.n = 0; -+ cond.result = -1; -+ -+ TRACE("Evaluating %s\n",debugstr_w(szCondition)); -+ -+ if ( szCondition == NULL || szCondition[0] == 0) -+ r = MSICONDITION_NONE; -+ else if ( !COND_parse( &cond ) ) -+ r = cond.result; -+ else -+ r = MSICONDITION_ERROR; -+ -+ TRACE("Evaluates to %i\n",r); -+ return r; -+} -+ -+MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition ) -+{ -+ MSIPACKAGE *package; -+ UINT ret; -+ -+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); -+ if( !package) -+ return ERROR_INVALID_HANDLE; -+ ret = MSI_EvaluateConditionW( package, szCondition ); -+ msiobj_release( &package->hdr ); -+ return ret; -+} -+ -+MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition ) -+{ -+ LPWSTR szwCond = NULL; -+ MSICONDITION r; -+ -+ if( szCondition ) -+ { -+ UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 ); -+ szwCond = msi_alloc( len * sizeof (WCHAR) ); -+ MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len ); -+ } -+ -+ r = MsiEvaluateConditionW( hInstall, szwCond ); -+ -+ msi_free( szwCond ); -+ -+ return r; -+} -+ ++/* A Bison parser, made by GNU Bison 1.875c. */ ++ ++/* Skeleton parser for Yacc-like parsing with Bison, ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++ 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, 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., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ ++ ++/* Written by Richard Stallman by simplifying the original so called ++ ``semantic'' parser. */ ++ ++/* All symbols defined below should begin with yy or YY, to avoid ++ infringing on user name space. This should be done even for local ++ variables, as they might otherwise be expanded by user macros. ++ There are some unavoidable exceptions within include files to ++ define necessary library symbols; they are noted "INFRINGES ON ++ USER NAME SPACE" below. */ ++ ++/* Identify Bison output. */ ++#define YYBISON 1 ++ ++/* Skeleton name. */ ++#define YYSKELETON_NAME "yacc.c" ++ ++/* Pure parsers. */ ++#define YYPURE 1 ++ ++/* Using locations. */ ++#define YYLSP_NEEDED 0 ++ ++/* If NAME_PREFIX is specified substitute the variables and functions ++ names. */ ++#define yyparse COND_parse ++#define yylex COND_lex ++#define yyerror COND_error ++#define yylval COND_lval ++#define yychar COND_char ++#define yydebug COND_debug ++#define yynerrs COND_nerrs ++ ++ ++/* Tokens. */ ++#ifndef YYTOKENTYPE ++# define YYTOKENTYPE ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ COND_SPACE = 258, ++ COND_EOF = 259, ++ COND_OR = 260, ++ COND_AND = 261, ++ COND_NOT = 262, ++ COND_LT = 263, ++ COND_GT = 264, ++ COND_EQ = 265, ++ COND_LPAR = 266, ++ COND_RPAR = 267, ++ COND_TILDA = 268, ++ COND_PERCENT = 269, ++ COND_DOLLARS = 270, ++ COND_QUESTION = 271, ++ COND_AMPER = 272, ++ COND_EXCLAM = 273, ++ COND_IDENT = 274, ++ COND_NUMBER = 275, ++ COND_LITER = 276, ++ COND_ERROR = 277 ++ }; ++#endif ++#define COND_SPACE 258 ++#define COND_EOF 259 ++#define COND_OR 260 ++#define COND_AND 261 ++#define COND_NOT 262 ++#define COND_LT 263 ++#define COND_GT 264 ++#define COND_EQ 265 ++#define COND_LPAR 266 ++#define COND_RPAR 267 ++#define COND_TILDA 268 ++#define COND_PERCENT 269 ++#define COND_DOLLARS 270 ++#define COND_QUESTION 271 ++#define COND_AMPER 272 ++#define COND_EXCLAM 273 ++#define COND_IDENT 274 ++#define COND_NUMBER 275 ++#define COND_LITER 276 ++#define COND_ERROR 277 ++ ++ ++ ++ ++/* Copy the first part of user declarations. */ ++#line 1 "./cond.y" ++ ++ ++/* ++ * Implementation of the Microsoft Installer (msi.dll) ++ * ++ * Copyright 2003 Mike McCormack for CodeWeavers ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "wine/debug.h" ++#include "wine/unicode.h" ++ ++#include "msi.h" ++#include "msiquery.h" ++#include "msipriv.h" ++ ++#define YYLEX_PARAM info ++#define YYPARSE_PARAM info ++ ++static int COND_error(const char *str); ++ ++WINE_DEFAULT_DEBUG_CHANNEL(msi); ++ ++typedef struct tag_yyinput ++{ ++ MSIPACKAGE *package; ++ LPCWSTR str; ++ INT n; ++ MSICONDITION result; ++} COND_input; ++ ++struct cond_str { ++ LPCWSTR data; ++ INT len; ++}; ++ ++static LPWSTR COND_GetString( struct cond_str *str ); ++static LPWSTR COND_GetLiteral( struct cond_str *str ); ++static int COND_lex( void *COND_lval, COND_input *info); ++ ++typedef INT (*comp_int)(INT a, INT b); ++typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless); ++typedef INT (*comp_m1)(LPWSTR a,int b); ++typedef INT (*comp_m2)(int a,LPWSTR b); ++ ++static INT comp_lt_i(INT a, INT b); ++static INT comp_gt_i(INT a, INT b); ++static INT comp_le_i(INT a, INT b); ++static INT comp_ge_i(INT a, INT b); ++static INT comp_eq_i(INT a, INT b); ++static INT comp_ne_i(INT a, INT b); ++static INT comp_bitand(INT a, INT b); ++static INT comp_highcomp(INT a, INT b); ++static INT comp_lowcomp(INT a, INT b); ++ ++static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless); ++ ++static INT comp_eq_m1(LPWSTR a, INT b); ++static INT comp_ne_m1(LPWSTR a, INT b); ++static INT comp_lt_m1(LPWSTR a, INT b); ++static INT comp_gt_m1(LPWSTR a, INT b); ++static INT comp_le_m1(LPWSTR a, INT b); ++static INT comp_ge_m1(LPWSTR a, INT b); ++ ++static INT comp_eq_m2(INT a, LPWSTR b); ++static INT comp_ne_m2(INT a, LPWSTR b); ++static INT comp_lt_m2(INT a, LPWSTR b); ++static INT comp_gt_m2(INT a, LPWSTR b); ++static INT comp_le_m2(INT a, LPWSTR b); ++static INT comp_ge_m2(INT a, LPWSTR b); ++ ++ ++ ++/* Enabling traces. */ ++#ifndef YYDEBUG ++# define YYDEBUG 0 ++#endif ++ ++/* Enabling verbose error messages. */ ++#ifdef YYERROR_VERBOSE ++# undef YYERROR_VERBOSE ++# define YYERROR_VERBOSE 1 ++#else ++# define YYERROR_VERBOSE 0 ++#endif ++ ++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) ++#line 106 "./cond.y" ++typedef union YYSTYPE { ++ struct cond_str str; ++ LPWSTR string; ++ INT value; ++ comp_int fn_comp_int; ++ comp_str fn_comp_str; ++ comp_m1 fn_comp_m1; ++ comp_m2 fn_comp_m2; ++} YYSTYPE; ++/* Line 191 of yacc.c. */ ++#line 241 "cond.tab.c" ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ ++# define YYSTYPE_IS_DECLARED 1 ++# define YYSTYPE_IS_TRIVIAL 1 ++#endif ++ ++ ++ ++/* Copy the second part of user declarations. */ ++ ++ ++/* Line 214 of yacc.c. */ ++#line 253 "cond.tab.c" ++ ++#if ! defined (yyoverflow) || YYERROR_VERBOSE ++ ++# ifndef YYFREE ++# define YYFREE free ++# endif ++# ifndef YYMALLOC ++# define YYMALLOC malloc ++# endif ++ ++/* The parser invokes alloca or malloc; define the necessary symbols. */ ++ ++# ifdef YYSTACK_USE_ALLOCA ++# if YYSTACK_USE_ALLOCA ++# define YYSTACK_ALLOC alloca ++# endif ++# else ++# if defined (alloca) || defined (_ALLOCA_H) ++# define YYSTACK_ALLOC alloca ++# else ++# ifdef __GNUC__ ++# define YYSTACK_ALLOC __builtin_alloca ++# endif ++# endif ++# endif ++ ++# ifdef YYSTACK_ALLOC ++ /* Pacify GCC's `empty if-body' warning. */ ++# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) ++# else ++# if defined (__STDC__) || defined (__cplusplus) ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYSIZE_T size_t ++# endif ++# define YYSTACK_ALLOC YYMALLOC ++# define YYSTACK_FREE YYFREE ++# endif ++#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ ++ ++ ++#if (! defined (yyoverflow) \ ++ && (! defined (__cplusplus) \ ++ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) ++ ++/* A type that is properly aligned for any stack member. */ ++union yyalloc ++{ ++ short yyss; ++ YYSTYPE yyvs; ++ }; ++ ++/* The size of the maximum gap between one aligned stack and the next. */ ++# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) ++ ++/* The size of an array large to enough to hold all stacks, each with ++ N elements. */ ++# define YYSTACK_BYTES(N) \ ++ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ ++ + YYSTACK_GAP_MAXIMUM) ++ ++/* Copy COUNT objects from FROM to TO. The source and destination do ++ not overlap. */ ++# ifndef YYCOPY ++# if defined (__GNUC__) && 1 < __GNUC__ ++# define YYCOPY(To, From, Count) \ ++ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) ++# else ++# define YYCOPY(To, From, Count) \ ++ do \ ++ { \ ++ register YYSIZE_T yyi; \ ++ for (yyi = 0; yyi < (Count); yyi++) \ ++ (To)[yyi] = (From)[yyi]; \ ++ } \ ++ while (0) ++# endif ++# endif ++ ++/* Relocate STACK from its old location to the new one. The ++ local variables YYSIZE and YYSTACKSIZE give the old and new number of ++ elements in the stack, and YYPTR gives the new location of the ++ stack. Advance YYPTR to a properly aligned location for the next ++ stack. */ ++# define YYSTACK_RELOCATE(Stack) \ ++ do \ ++ { \ ++ YYSIZE_T yynewbytes; \ ++ YYCOPY (&yyptr->Stack, Stack, yysize); \ ++ Stack = &yyptr->Stack; \ ++ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ ++ yyptr += yynewbytes / sizeof (*yyptr); \ ++ } \ ++ while (0) ++ ++#endif ++ ++#if defined (__STDC__) || defined (__cplusplus) ++ typedef signed char yysigned_char; ++#else ++ typedef short yysigned_char; ++#endif ++ ++/* YYFINAL -- State number of the termination state. */ ++#define YYFINAL 30 ++/* YYLAST -- Last index in YYTABLE. */ ++#define YYLAST 146 ++ ++/* YYNTOKENS -- Number of terminals. */ ++#define YYNTOKENS 23 ++/* YYNNTS -- Number of nonterminals. */ ++#define YYNNTS 17 ++/* YYNRULES -- Number of rules. */ ++#define YYNRULES 65 ++/* YYNRULES -- Number of states. */ ++#define YYNSTATES 74 ++ ++/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ ++#define YYUNDEFTOK 2 ++#define YYMAXUTOK 277 ++ ++#define YYTRANSLATE(YYX) \ ++ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) ++ ++/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ ++static const unsigned char yytranslate[] = ++{ ++ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, ++ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ++ 15, 16, 17, 18, 19, 20, 21, 22 ++}; ++ ++#if YYDEBUG ++/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in ++ YYRHS. */ ++static const unsigned char yyprhs[] = ++{ ++ 0, 0, 3, 5, 7, 11, 13, 17, 19, 22, ++ 24, 26, 30, 34, 39, 43, 47, 51, 53, 56, ++ 58, 60, 63, 66, 69, 72, 75, 77, 80, 82, ++ 84, 87, 90, 93, 96, 99, 101, 104, 106, 108, ++ 111, 114, 117, 120, 123, 125, 128, 130, 132, 135, ++ 138, 141, 144, 147, 149, 151, 153, 155, 157, 160, ++ 163, 166, 169, 171, 174, 176 ++}; ++ ++/* YYRHS -- A `-1'-separated list of the rules' RHS. */ ++static const yysigned_char yyrhs[] = ++{ ++ 24, 0, -1, 25, -1, 26, -1, 26, 5, 25, ++ -1, 27, -1, 26, 6, 27, -1, 28, -1, 7, ++ 28, -1, 33, -1, 34, -1, 33, 29, 33, -1, ++ 34, 30, 34, -1, 34, 13, 30, 34, -1, 34, ++ 31, 33, -1, 33, 32, 34, -1, 11, 25, 12, ++ -1, 10, -1, 8, 9, -1, 8, -1, 9, -1, ++ 8, 10, -1, 9, 10, -1, 9, 8, -1, 8, ++ 8, -1, 9, 9, -1, 10, -1, 8, 9, -1, ++ 8, -1, 9, -1, 8, 10, -1, 9, 10, -1, ++ 9, 8, -1, 8, 8, -1, 9, 9, -1, 10, ++ -1, 8, 9, -1, 8, -1, 9, -1, 8, 10, ++ -1, 9, 10, -1, 9, 8, -1, 8, 8, -1, ++ 9, 9, -1, 10, -1, 8, 9, -1, 8, -1, ++ 9, -1, 8, 10, -1, 9, 10, -1, 9, 8, ++ -1, 8, 8, -1, 9, 9, -1, 36, -1, 39, ++ -1, 37, -1, 35, -1, 21, -1, 15, 38, -1, ++ 16, 38, -1, 17, 38, -1, 18, 38, -1, 38, ++ -1, 14, 38, -1, 19, -1, 20, -1 ++}; ++ ++/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ ++static const unsigned short yyrline[] = ++{ ++ 0, 136, 136, 144, 148, 155, 159, 166, 170, 178, ++ 182, 187, 191, 197, 203, 208, 213, 221, 225, 229, ++ 233, 237, 241, 246, 250, 254, 262, 266, 270, 274, ++ 278, 282, 287, 291, 295, 303, 307, 311, 315, 319, ++ 323, 328, 332, 336, 344, 348, 352, 356, 360, 364, ++ 369, 373, 377, 384, 388, 395, 399, 406, 415, 424, ++ 433, 442, 454, 477, 491, 500 ++}; ++#endif ++ ++#if YYDEBUG || YYERROR_VERBOSE ++/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. ++ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ ++static const char *const yytname[] = ++{ ++ "$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR", ++ "COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR", ++ "COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS", ++ "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT", ++ "COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition", ++ "expression", "boolean_term", "boolean_factor", "term", "comp_op_i", ++ "comp_op_s", "comp_op_m1", "comp_op_m2", "value_i", "value_s", "literal", ++ "symbol_i", "symbol_s", "identifier", "integer", 0 ++}; ++#endif ++ ++# ifdef YYPRINT ++/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to ++ token YYLEX-NUM. */ ++static const unsigned short yytoknum[] = ++{ ++ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, ++ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, ++ 275, 276, 277 ++}; ++# endif ++ ++/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ ++static const unsigned char yyr1[] = ++{ ++ 0, 23, 24, 25, 25, 26, 26, 27, 27, 28, ++ 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, ++ 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, ++ 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, ++ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, ++ 32, 32, 32, 33, 33, 34, 34, 35, 36, 36, ++ 36, 36, 37, 37, 38, 39 ++}; ++ ++/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ ++static const unsigned char yyr2[] = ++{ ++ 0, 2, 1, 1, 3, 1, 3, 1, 2, 1, ++ 1, 3, 3, 4, 3, 3, 3, 1, 2, 1, ++ 1, 2, 2, 2, 2, 2, 1, 2, 1, 1, ++ 2, 2, 2, 2, 2, 1, 2, 1, 1, 2, ++ 2, 2, 2, 2, 1, 2, 1, 1, 2, 2, ++ 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, ++ 2, 2, 1, 2, 1, 1 ++}; ++ ++/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state ++ STATE-NUM when YYTABLE doesn't specify something else to do. Zero ++ means the default is an error. */ ++static const unsigned char yydefact[] = ++{ ++ 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, ++ 57, 0, 2, 3, 5, 7, 9, 10, 56, 53, ++ 55, 62, 54, 8, 0, 63, 58, 59, 60, 61, ++ 1, 0, 0, 19, 20, 17, 0, 0, 37, 38, ++ 35, 0, 0, 0, 16, 4, 6, 24, 18, 21, ++ 23, 25, 22, 11, 15, 42, 36, 39, 41, 43, ++ 40, 28, 29, 26, 0, 12, 14, 33, 27, 30, ++ 32, 34, 31, 13 ++}; ++ ++/* YYDEFGOTO[NTERM-NUM]. */ ++static const yysigned_char yydefgoto[] = ++{ ++ -1, 11, 12, 13, 14, 15, 36, 42, 43, 37, ++ 16, 17, 18, 19, 20, 21, 22 ++}; ++ ++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ ++#define YYPACT_NINF -37 ++static const short yypact[] = ++{ ++ -4, 51, -4, -11, -11, -11, -11, -11, -37, -37, ++ -37, 18, -37, -1, -37, -37, 49, 14, -37, -37, ++ -37, -37, -37, -37, 19, -37, -37, -37, -37, -37, ++ -37, -4, -4, 11, 25, 34, 111, 59, 28, 42, ++ 60, 130, 59, 111, -37, -37, -37, 63, 69, 72, ++ 73, 81, 82, -37, -37, 85, 91, 94, 95, 103, ++ 104, 133, 136, -37, 59, -37, -37, -37, -37, -37, ++ -37, -37, -37, -37 ++}; ++ ++/* YYPGOTO[NTERM-NUM]. */ ++static const short yypgoto[] = ++{ ++ -37, -37, -2, -37, -6, 39, -37, 0, -37, -37, ++ -34, -36, -37, -37, -37, 129, -37 ++}; ++ ++/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule which ++ number is the opposite. If zero, do what YYDEFACT says. ++ If YYTABLE_NINF, syntax error. */ ++#define YYTABLE_NINF -53 ++static const yysigned_char yytable[] = ++{ ++ 24, 54, 53, 1, 31, 32, 65, 2, 8, 66, ++ 3, 4, 5, 6, 7, 8, 9, 10, 30, 47, ++ 48, 49, 38, 39, 40, -46, 46, 41, 73, 45, ++ -46, 44, -46, 50, 51, 52, 55, 56, 57, -47, ++ 23, 64, -28, 0, -47, 0, -47, -28, -44, -28, ++ 58, 59, 60, -44, 0, -44, -29, 33, 34, 35, ++ 0, -29, 2, -29, 0, 3, 4, 5, 6, 7, ++ 8, 9, 10, 3, -26, 0, 0, -51, 8, -26, ++ 10, -26, -51, -45, -51, 0, -48, -50, -45, 0, ++ -45, -48, -50, -48, -50, -52, -49, 0, 0, -33, ++ -52, -49, -52, -49, -33, -27, -33, 0, -30, -32, ++ -27, 0, -27, -30, -32, -30, -32, -34, -31, 0, ++ 0, 0, -34, -31, -34, -31, 4, 5, 6, 7, ++ 0, 9, 25, 26, 27, 28, 29, 0, 61, 62, ++ 63, 67, 68, 69, 70, 71, 72 ++}; ++ ++static const yysigned_char yycheck[] = ++{ ++ 2, 37, 36, 7, 5, 6, 42, 11, 19, 43, ++ 14, 15, 16, 17, 18, 19, 20, 21, 0, 8, ++ 9, 10, 8, 9, 10, 14, 32, 13, 64, 31, ++ 19, 12, 21, 8, 9, 10, 8, 9, 10, 14, ++ 1, 41, 14, -1, 19, -1, 21, 19, 14, 21, ++ 8, 9, 10, 19, -1, 21, 14, 8, 9, 10, ++ -1, 19, 11, 21, -1, 14, 15, 16, 17, 18, ++ 19, 20, 21, 14, 14, -1, -1, 14, 19, 19, ++ 21, 21, 19, 14, 21, -1, 14, 14, 19, -1, ++ 21, 19, 19, 21, 21, 14, 14, -1, -1, 14, ++ 19, 19, 21, 21, 19, 14, 21, -1, 14, 14, ++ 19, -1, 21, 19, 19, 21, 21, 14, 14, -1, ++ -1, -1, 19, 19, 21, 21, 15, 16, 17, 18, ++ -1, 20, 3, 4, 5, 6, 7, -1, 8, 9, ++ 10, 8, 9, 10, 8, 9, 10 ++}; ++ ++/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing ++ symbol of state STATE-NUM. */ ++static const unsigned char yystos[] = ++{ ++ 0, 7, 11, 14, 15, 16, 17, 18, 19, 20, ++ 21, 24, 25, 26, 27, 28, 33, 34, 35, 36, ++ 37, 38, 39, 28, 25, 38, 38, 38, 38, 38, ++ 0, 5, 6, 8, 9, 10, 29, 32, 8, 9, ++ 10, 13, 30, 31, 12, 25, 27, 8, 9, 10, ++ 8, 9, 10, 33, 34, 8, 9, 10, 8, 9, ++ 10, 8, 9, 10, 30, 34, 33, 8, 9, 10, ++ 8, 9, 10, 34 ++}; ++ ++#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) ++# define YYSIZE_T __SIZE_TYPE__ ++#endif ++#if ! defined (YYSIZE_T) && defined (size_t) ++# define YYSIZE_T size_t ++#endif ++#if ! defined (YYSIZE_T) ++# if defined (__STDC__) || defined (__cplusplus) ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYSIZE_T size_t ++# endif ++#endif ++#if ! defined (YYSIZE_T) ++# define YYSIZE_T unsigned int ++#endif ++ ++#define yyerrok (yyerrstatus = 0) ++#define yyclearin (yychar = YYEMPTY) ++#define YYEMPTY (-2) ++#define YYEOF 0 ++ ++#define YYACCEPT goto yyacceptlab ++#define YYABORT goto yyabortlab ++#define YYERROR goto yyerrorlab ++ ++ ++/* Like YYERROR except do call yyerror. This remains here temporarily ++ to ease the transition to the new meaning of YYERROR, for GCC. ++ Once GCC version 2 has supplanted version 1, this can go. */ ++ ++#define YYFAIL goto yyerrlab ++ ++#define YYRECOVERING() (!!yyerrstatus) ++ ++#define YYBACKUP(Token, Value) \ ++do \ ++ if (yychar == YYEMPTY && yylen == 1) \ ++ { \ ++ yychar = (Token); \ ++ yylval = (Value); \ ++ yytoken = YYTRANSLATE (yychar); \ ++ YYPOPSTACK; \ ++ goto yybackup; \ ++ } \ ++ else \ ++ { \ ++ yyerror ("syntax error: cannot back up");\ ++ YYERROR; \ ++ } \ ++while (0) ++ ++#define YYTERROR 1 ++#define YYERRCODE 256 ++ ++/* YYLLOC_DEFAULT -- Compute the default location (before the actions ++ are run). */ ++ ++#ifndef YYLLOC_DEFAULT ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ ((Current).first_line = (Rhs)[1].first_line, \ ++ (Current).first_column = (Rhs)[1].first_column, \ ++ (Current).last_line = (Rhs)[N].last_line, \ ++ (Current).last_column = (Rhs)[N].last_column) ++#endif ++ ++/* YYLEX -- calling `yylex' with the right arguments. */ ++ ++#ifdef YYLEX_PARAM ++# define YYLEX yylex (&yylval, YYLEX_PARAM) ++#else ++# define YYLEX yylex (&yylval) ++#endif ++ ++/* Enable debugging if requested. */ ++#if YYDEBUG ++ ++# ifndef YYFPRINTF ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYFPRINTF fprintf ++# endif ++ ++# define YYDPRINTF(Args) \ ++do { \ ++ if (yydebug) \ ++ YYFPRINTF Args; \ ++} while (0) ++ ++# define YYDSYMPRINT(Args) \ ++do { \ ++ if (yydebug) \ ++ yysymprint Args; \ ++} while (0) ++ ++# define YYDSYMPRINTF(Title, Token, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yysymprint (stderr, \ ++ Token, Value); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (0) ++ ++/*------------------------------------------------------------------. ++| yy_stack_print -- Print the state stack from its BOTTOM up to its | ++| TOP (included). | ++`------------------------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_stack_print (short *bottom, short *top) ++#else ++static void ++yy_stack_print (bottom, top) ++ short *bottom; ++ short *top; ++#endif ++{ ++ YYFPRINTF (stderr, "Stack now"); ++ for (/* Nothing. */; bottom <= top; ++bottom) ++ YYFPRINTF (stderr, " %d", *bottom); ++ YYFPRINTF (stderr, "\n"); ++} ++ ++# define YY_STACK_PRINT(Bottom, Top) \ ++do { \ ++ if (yydebug) \ ++ yy_stack_print ((Bottom), (Top)); \ ++} while (0) ++ ++ ++/*------------------------------------------------. ++| Report that the YYRULE is going to be reduced. | ++`------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_reduce_print (int yyrule) ++#else ++static void ++yy_reduce_print (yyrule) ++ int yyrule; ++#endif ++{ ++ int yyi; ++ unsigned int yylno = yyrline[yyrule]; ++ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", ++ yyrule - 1, yylno); ++ /* Print the symbols being reduced, and their result. */ ++ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) ++ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); ++ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); ++} ++ ++# define YY_REDUCE_PRINT(Rule) \ ++do { \ ++ if (yydebug) \ ++ yy_reduce_print (Rule); \ ++} while (0) ++ ++/* Nonzero means print parse trace. It is left uninitialized so that ++ multiple parsers can coexist. */ ++int yydebug; ++#else /* !YYDEBUG */ ++# define YYDPRINTF(Args) ++# define YYDSYMPRINT(Args) ++# define YYDSYMPRINTF(Title, Token, Value, Location) ++# define YY_STACK_PRINT(Bottom, Top) ++# define YY_REDUCE_PRINT(Rule) ++#endif /* !YYDEBUG */ ++ ++ ++/* YYINITDEPTH -- initial size of the parser's stacks. */ ++#ifndef YYINITDEPTH ++# define YYINITDEPTH 200 ++#endif ++ ++/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only ++ if the built-in stack extension method is used). ++ ++ Do not make this value too large; the results are undefined if ++ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) ++ evaluated with infinite-precision integer arithmetic. */ ++ ++#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 ++# undef YYMAXDEPTH ++#endif ++ ++#ifndef YYMAXDEPTH ++# define YYMAXDEPTH 10000 ++#endif ++ ++ ++ ++#if YYERROR_VERBOSE ++ ++# ifndef yystrlen ++# if defined (__GLIBC__) && defined (_STRING_H) ++# define yystrlen strlen ++# else ++/* Return the length of YYSTR. */ ++static YYSIZE_T ++# if defined (__STDC__) || defined (__cplusplus) ++yystrlen (const char *yystr) ++# else ++yystrlen (yystr) ++ const char *yystr; ++# endif ++{ ++ register const char *yys = yystr; ++ ++ while (*yys++ != '\0') ++ continue; ++ ++ return yys - yystr - 1; ++} ++# endif ++# endif ++ ++# ifndef yystpcpy ++# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) ++# define yystpcpy stpcpy ++# else ++/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in ++ YYDEST. */ ++static char * ++# if defined (__STDC__) || defined (__cplusplus) ++yystpcpy (char *yydest, const char *yysrc) ++# else ++yystpcpy (yydest, yysrc) ++ char *yydest; ++ const char *yysrc; ++# endif ++{ ++ register char *yyd = yydest; ++ register const char *yys = yysrc; ++ ++ while ((*yyd++ = *yys++) != '\0') ++ continue; ++ ++ return yyd - 1; ++} ++# endif ++# endif ++ ++#endif /* !YYERROR_VERBOSE */ ++ ++ ++ ++#if YYDEBUG ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yysymprint (yyoutput, yytype, yyvaluep) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ if (yytype < YYNTOKENS) ++ { ++ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); ++# ifdef YYPRINT ++ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++# endif ++ } ++ else ++ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); ++ ++ switch (yytype) ++ { ++ default: ++ break; ++ } ++ YYFPRINTF (yyoutput, ")"); ++} ++ ++#endif /* ! YYDEBUG */ ++/*-----------------------------------------------. ++| Release the memory associated to this symbol. | ++`-----------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yydestruct (int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yydestruct (yytype, yyvaluep) ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ switch (yytype) ++ { ++ ++ default: ++ break; ++ } ++} ++ ++ ++/* Prevent warnings from -Wmissing-prototypes. */ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM); ++# else ++int yyparse (); ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void); ++#else ++int yyparse (); ++#endif ++#endif /* ! YYPARSE_PARAM */ ++ ++ ++ ++ ++ ++ ++/*----------. ++| yyparse. | ++`----------*/ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM) ++# else ++int yyparse (YYPARSE_PARAM) ++ void *YYPARSE_PARAM; ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int ++yyparse (void) ++#else ++int ++yyparse () ++ ++#endif ++#endif ++{ ++ /* The lookahead symbol. */ ++int yychar; ++ ++/* The semantic value of the lookahead symbol. */ ++YYSTYPE yylval; ++ ++/* Number of syntax errors so far. */ ++int yynerrs; ++ ++ register int yystate; ++ register int yyn; ++ int yyresult; ++ /* Number of tokens to shift before error messages enabled. */ ++ int yyerrstatus; ++ /* Lookahead token as an internal (translated) token number. */ ++ int yytoken = 0; ++ ++ /* Three stacks and their tools: ++ `yyss': related to states, ++ `yyvs': related to semantic values, ++ `yyls': related to locations. ++ ++ Refer to the stacks thru separate pointers, to allow yyoverflow ++ to reallocate them elsewhere. */ ++ ++ /* The state stack. */ ++ short yyssa[YYINITDEPTH]; ++ short *yyss = yyssa; ++ register short *yyssp; ++ ++ /* The semantic value stack. */ ++ YYSTYPE yyvsa[YYINITDEPTH]; ++ YYSTYPE *yyvs = yyvsa; ++ register YYSTYPE *yyvsp; ++ ++ ++ ++#define YYPOPSTACK (yyvsp--, yyssp--) ++ ++ YYSIZE_T yystacksize = YYINITDEPTH; ++ ++ /* The variables used to return semantic value and location from the ++ action routines. */ ++ YYSTYPE yyval; ++ ++ ++ /* When reducing, the number of symbols on the RHS of the reduced ++ rule. */ ++ int yylen; ++ ++ YYDPRINTF ((stderr, "Starting parse\n")); ++ ++ yystate = 0; ++ yyerrstatus = 0; ++ yynerrs = 0; ++ yychar = YYEMPTY; /* Cause a token to be read. */ ++ ++ /* Initialize stack pointers. ++ Waste one element of value and location stack ++ so that they stay on the same level as the state stack. ++ The wasted elements are never initialized. */ ++ ++ yyssp = yyss; ++ yyvsp = yyvs; ++ ++ goto yysetstate; ++ ++/*------------------------------------------------------------. ++| yynewstate -- Push a new state, which is found in yystate. | ++`------------------------------------------------------------*/ ++ yynewstate: ++ /* In all cases, when you get here, the value and location stacks ++ have just been pushed. so pushing a state here evens the stacks. ++ */ ++ yyssp++; ++ ++ yysetstate: ++ *yyssp = yystate; ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ { ++ /* Get the current used size of the three stacks, in elements. */ ++ YYSIZE_T yysize = yyssp - yyss + 1; ++ ++#ifdef yyoverflow ++ { ++ /* Give user a chance to reallocate the stack. Use copies of ++ these so that the &'s don't force the real ones into ++ memory. */ ++ YYSTYPE *yyvs1 = yyvs; ++ short *yyss1 = yyss; ++ ++ ++ /* Each stack pointer address is followed by the size of the ++ data in use in that stack, in bytes. This used to be a ++ conditional around just the two extra args, but that might ++ be undefined if yyoverflow is a macro. */ ++ yyoverflow ("parser stack overflow", ++ &yyss1, yysize * sizeof (*yyssp), ++ &yyvs1, yysize * sizeof (*yyvsp), ++ ++ &yystacksize); ++ ++ yyss = yyss1; ++ yyvs = yyvs1; ++ } ++#else /* no yyoverflow */ ++# ifndef YYSTACK_RELOCATE ++ goto yyoverflowlab; ++# else ++ /* Extend the stack our own way. */ ++ if (YYMAXDEPTH <= yystacksize) ++ goto yyoverflowlab; ++ yystacksize *= 2; ++ if (YYMAXDEPTH < yystacksize) ++ yystacksize = YYMAXDEPTH; ++ ++ { ++ short *yyss1 = yyss; ++ union yyalloc *yyptr = ++ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ if (! yyptr) ++ goto yyoverflowlab; ++ YYSTACK_RELOCATE (yyss); ++ YYSTACK_RELOCATE (yyvs); ++ ++# undef YYSTACK_RELOCATE ++ if (yyss1 != yyssa) ++ YYSTACK_FREE (yyss1); ++ } ++# endif ++#endif /* no yyoverflow */ ++ ++ yyssp = yyss + yysize - 1; ++ yyvsp = yyvs + yysize - 1; ++ ++ ++ YYDPRINTF ((stderr, "Stack size increased to %lu\n", ++ (unsigned long int) yystacksize)); ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ YYABORT; ++ } ++ ++ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); ++ ++ goto yybackup; ++ ++/*-----------. ++| yybackup. | ++`-----------*/ ++yybackup: ++ ++/* Do appropriate processing given the current state. */ ++/* Read a lookahead token if we need one and don't already have one. */ ++/* yyresume: */ ++ ++ /* First try to decide what to do without reference to lookahead token. */ ++ ++ yyn = yypact[yystate]; ++ if (yyn == YYPACT_NINF) ++ goto yydefault; ++ ++ /* Not known => get a lookahead token if don't already have one. */ ++ ++ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ ++ if (yychar == YYEMPTY) ++ { ++ YYDPRINTF ((stderr, "Reading a token: ")); ++ yychar = YYLEX; ++ } ++ ++ if (yychar <= YYEOF) ++ { ++ yychar = yytoken = YYEOF; ++ YYDPRINTF ((stderr, "Now at end of input.\n")); ++ } ++ else ++ { ++ yytoken = YYTRANSLATE (yychar); ++ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); ++ } ++ ++ /* If the proper action on seeing token YYTOKEN is to reduce or to ++ detect an error, take that action. */ ++ yyn += yytoken; ++ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) ++ goto yydefault; ++ yyn = yytable[yyn]; ++ if (yyn <= 0) ++ { ++ if (yyn == 0 || yyn == YYTABLE_NINF) ++ goto yyerrlab; ++ yyn = -yyn; ++ goto yyreduce; ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ /* Shift the lookahead token. */ ++ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); ++ ++ /* Discard the token being shifted unless it is eof. */ ++ if (yychar != YYEOF) ++ yychar = YYEMPTY; ++ ++ *++yyvsp = yylval; ++ ++ ++ /* Count tokens shifted since error; after three, turn off error ++ status. */ ++ if (yyerrstatus) ++ yyerrstatus--; ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-----------------------------------------------------------. ++| yydefault -- do the default action for the current state. | ++`-----------------------------------------------------------*/ ++yydefault: ++ yyn = yydefact[yystate]; ++ if (yyn == 0) ++ goto yyerrlab; ++ goto yyreduce; ++ ++ ++/*-----------------------------. ++| yyreduce -- Do a reduction. | ++`-----------------------------*/ ++yyreduce: ++ /* yyn is the number of a rule to reduce with. */ ++ yylen = yyr2[yyn]; ++ ++ /* If YYLEN is nonzero, implement the default value of the action: ++ `$$ = $1'. ++ ++ Otherwise, the following line sets YYVAL to garbage. ++ This behavior is undocumented and Bison ++ users should not rely upon it. Assigning to YYVAL ++ unconditionally makes the parser a bit smaller, and it avoids a ++ GCC warning that YYVAL may be used uninitialized. */ ++ yyval = yyvsp[1-yylen]; ++ ++ ++ YY_REDUCE_PRINT (yyn); ++ switch (yyn) ++ { ++ case 2: ++#line 137 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ cond->result = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 3: ++#line 145 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 4: ++#line 149 "./cond.y" ++ { ++ yyval.value = yyvsp[-2].value || yyvsp[0].value; ++ ;} ++ break; ++ ++ case 5: ++#line 156 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 6: ++#line 160 "./cond.y" ++ { ++ yyval.value = yyvsp[-2].value && yyvsp[0].value; ++ ;} ++ break; ++ ++ case 7: ++#line 167 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 8: ++#line 171 "./cond.y" ++ { ++ yyval.value = ! yyvsp[0].value; ++ ;} ++ break; ++ ++ case 9: ++#line 179 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 10: ++#line 183 "./cond.y" ++ { ++ yyval.value = (yyvsp[0].string && yyvsp[0].string[0]) ? MSICONDITION_TRUE : MSICONDITION_FALSE; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 11: ++#line 188 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_int( yyvsp[-2].value, yyvsp[0].value ); ++ ;} ++ break; ++ ++ case 12: ++#line 192 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-2].string, yyvsp[0].string, FALSE ); ++ msi_free( yyvsp[-2].string ); ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 13: ++#line 198 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-3].string, yyvsp[0].string, TRUE ); ++ msi_free( yyvsp[-3].string ); ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 14: ++#line 204 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_m1( yyvsp[-2].string, yyvsp[0].value ); ++ msi_free( yyvsp[-2].string ); ++ ;} ++ break; ++ ++ case 15: ++#line 209 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_m2( yyvsp[-2].value, yyvsp[0].string ); ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 16: ++#line 214 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].value; ++ ;} ++ break; ++ ++ case 17: ++#line 222 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_eq_i; ++ ;} ++ break; ++ ++ case 18: ++#line 226 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_ne_i; ++ ;} ++ break; ++ ++ case 19: ++#line 230 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_lt_i; ++ ;} ++ break; ++ ++ case 20: ++#line 234 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_gt_i; ++ ;} ++ break; ++ ++ case 21: ++#line 238 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_le_i; ++ ;} ++ break; ++ ++ case 22: ++#line 242 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_ge_i; ++ ;} ++ break; ++ ++ case 23: ++#line 247 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_bitand; ++ ;} ++ break; ++ ++ case 24: ++#line 251 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_highcomp; ++ ;} ++ break; ++ ++ case 25: ++#line 255 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_lowcomp; ++ ;} ++ break; ++ ++ case 26: ++#line 263 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_eq_s; ++ ;} ++ break; ++ ++ case 27: ++#line 267 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_ne_s; ++ ;} ++ break; ++ ++ case 28: ++#line 271 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_lt_s; ++ ;} ++ break; ++ ++ case 29: ++#line 275 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_gt_s; ++ ;} ++ break; ++ ++ case 30: ++#line 279 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_le_s; ++ ;} ++ break; ++ ++ case 31: ++#line 283 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_ge_s; ++ ;} ++ break; ++ ++ case 32: ++#line 288 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_substring; ++ ;} ++ break; ++ ++ case 33: ++#line 292 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_start; ++ ;} ++ break; ++ ++ case 34: ++#line 296 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_end; ++ ;} ++ break; ++ ++ case 35: ++#line 304 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_eq_m1; ++ ;} ++ break; ++ ++ case 36: ++#line 308 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_ne_m1; ++ ;} ++ break; ++ ++ case 37: ++#line 312 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_lt_m1; ++ ;} ++ break; ++ ++ case 38: ++#line 316 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_gt_m1; ++ ;} ++ break; ++ ++ case 39: ++#line 320 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_le_m1; ++ ;} ++ break; ++ ++ case 40: ++#line 324 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_ge_m1; ++ ;} ++ break; ++ ++ case 41: ++#line 329 "./cond.y" ++ { ++ yyval.fn_comp_m1 = 0; ++ ;} ++ break; ++ ++ case 42: ++#line 333 "./cond.y" ++ { ++ yyval.fn_comp_m1 = 0; ++ ;} ++ break; ++ ++ case 43: ++#line 337 "./cond.y" ++ { ++ yyval.fn_comp_m1 = 0; ++ ;} ++ break; ++ ++ case 44: ++#line 345 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_eq_m2; ++ ;} ++ break; ++ ++ case 45: ++#line 349 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_ne_m2; ++ ;} ++ break; ++ ++ case 46: ++#line 353 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_lt_m2; ++ ;} ++ break; ++ ++ case 47: ++#line 357 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_gt_m2; ++ ;} ++ break; ++ ++ case 48: ++#line 361 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_le_m2; ++ ;} ++ break; ++ ++ case 49: ++#line 365 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_ge_m2; ++ ;} ++ break; ++ ++ case 50: ++#line 370 "./cond.y" ++ { ++ yyval.fn_comp_m2 = 0; ++ ;} ++ break; ++ ++ case 51: ++#line 374 "./cond.y" ++ { ++ yyval.fn_comp_m2 = 0; ++ ;} ++ break; ++ ++ case 52: ++#line 378 "./cond.y" ++ { ++ yyval.fn_comp_m2 = 0; ++ ;} ++ break; ++ ++ case 53: ++#line 385 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 54: ++#line 389 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 55: ++#line 396 "./cond.y" ++ { ++ yyval.string = yyvsp[0].string; ++ ;} ++ break; ++ ++ case 56: ++#line 400 "./cond.y" ++ { ++ yyval.string = yyvsp[0].string; ++ ;} ++ break; ++ ++ case 57: ++#line 407 "./cond.y" ++ { ++ yyval.string = COND_GetLiteral(&yyvsp[0].str); ++ if( !yyval.string ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 58: ++#line 416 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; ++ ++ MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action ); ++ yyval.value = action; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 59: ++#line 425 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; ++ ++ MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action ); ++ yyval.value = install; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 60: ++#line 434 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; ++ ++ MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action ); ++ yyval.value = action; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 61: ++#line 443 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; ++ ++ MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action ); ++ yyval.value = install; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 62: ++#line 455 "./cond.y" ++ { ++ DWORD sz; ++ COND_input* cond = (COND_input*) info; ++ ++ sz = 0; ++ MSI_GetPropertyW(cond->package, yyvsp[0].string, NULL, &sz); ++ if (sz == 0) ++ { ++ yyval.string = msi_alloc( sizeof(WCHAR)); ++ yyval.string[0] = 0; ++ } ++ else ++ { ++ sz ++; ++ yyval.string = msi_alloc( sz*sizeof (WCHAR) ); ++ ++ /* Lookup the identifier */ ++ ++ MSI_GetPropertyW(cond->package,yyvsp[0].string,yyval.string,&sz); ++ } ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 63: ++#line 478 "./cond.y" ++ { ++ UINT len = GetEnvironmentVariableW( yyvsp[0].string, NULL, 0 ); ++ if( len++ ) ++ { ++ yyval.string = msi_alloc( len*sizeof (WCHAR) ); ++ if( yyval.string ) ++ GetEnvironmentVariableW( yyvsp[0].string, yyval.string, len ); ++ } ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 64: ++#line 492 "./cond.y" ++ { ++ yyval.string = COND_GetString(&yyvsp[0].str); ++ if( !yyval.string ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 65: ++#line 501 "./cond.y" ++ { ++ LPWSTR szNum = COND_GetString(&yyvsp[0].str); ++ if( !szNum ) ++ YYABORT; ++ yyval.value = atoiW( szNum ); ++ msi_free( szNum ); ++ ;} ++ break; ++ ++ ++ } ++ ++/* Line 1000 of yacc.c. */ ++#line 1733 "cond.tab.c" ++ ++ yyvsp -= yylen; ++ yyssp -= yylen; ++ ++ ++ YY_STACK_PRINT (yyss, yyssp); ++ ++ *++yyvsp = yyval; ++ ++ ++ /* Now `shift' the result of the reduction. Determine what state ++ that goes to, based on the state we popped back to and the rule ++ number reduced by. */ ++ ++ yyn = yyr1[yyn]; ++ ++ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; ++ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) ++ yystate = yytable[yystate]; ++ else ++ yystate = yydefgoto[yyn - YYNTOKENS]; ++ ++ goto yynewstate; ++ ++ ++/*------------------------------------. ++| yyerrlab -- here on detecting error | ++`------------------------------------*/ ++yyerrlab: ++ /* If not already recovering from an error, report this error. */ ++ if (!yyerrstatus) ++ { ++ ++yynerrs; ++#if YYERROR_VERBOSE ++ yyn = yypact[yystate]; ++ ++ if (YYPACT_NINF < yyn && yyn < YYLAST) ++ { ++ YYSIZE_T yysize = 0; ++ int yytype = YYTRANSLATE (yychar); ++ const char* yyprefix; ++ char *yymsg; ++ int yyx; ++ ++ /* Start YYX at -YYN if negative to avoid negative indexes in ++ YYCHECK. */ ++ int yyxbegin = yyn < 0 ? -yyn : 0; ++ ++ /* Stay within bounds of both yycheck and yytname. */ ++ int yychecklim = YYLAST - yyn; ++ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; ++ int yycount = 0; ++ ++ yyprefix = ", expecting "; ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); ++ yycount += 1; ++ if (yycount == 5) ++ { ++ yysize = 0; ++ break; ++ } ++ } ++ yysize += (sizeof ("syntax error, unexpected ") ++ + yystrlen (yytname[yytype])); ++ yymsg = (char *) YYSTACK_ALLOC (yysize); ++ if (yymsg != 0) ++ { ++ char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); ++ yyp = yystpcpy (yyp, yytname[yytype]); ++ ++ if (yycount < 5) ++ { ++ yyprefix = ", expecting "; ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ yyp = yystpcpy (yyp, yyprefix); ++ yyp = yystpcpy (yyp, yytname[yyx]); ++ yyprefix = " or "; ++ } ++ } ++ yyerror (yymsg); ++ YYSTACK_FREE (yymsg); ++ } ++ else ++ yyerror ("syntax error; also virtual memory exhausted"); ++ } ++ else ++#endif /* YYERROR_VERBOSE */ ++ yyerror ("syntax error"); ++ } ++ ++ ++ ++ if (yyerrstatus == 3) ++ { ++ /* If just tried and failed to reuse lookahead token after an ++ error, discard it. */ ++ ++ if (yychar <= YYEOF) ++ { ++ /* If at end of input, pop the error token, ++ then the rest of the stack, then return failure. */ ++ if (yychar == YYEOF) ++ for (;;) ++ { ++ YYPOPSTACK; ++ if (yyssp == yyss) ++ YYABORT; ++ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); ++ yydestruct (yystos[*yyssp], yyvsp); ++ } ++ } ++ else ++ { ++ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); ++ yydestruct (yytoken, &yylval); ++ yychar = YYEMPTY; ++ ++ } ++ } ++ ++ /* Else will try to reuse lookahead token after shifting the error ++ token. */ ++ goto yyerrlab1; ++ ++ ++/*---------------------------------------------------. ++| yyerrorlab -- error raised explicitly by YYERROR. | ++`---------------------------------------------------*/ ++yyerrorlab: ++ ++#ifdef __GNUC__ ++ /* Pacify GCC when the user code never invokes YYERROR and the label ++ yyerrorlab therefore never appears in user code. */ ++ if (0) ++ goto yyerrorlab; ++#endif ++ ++ yyvsp -= yylen; ++ yyssp -= yylen; ++ yystate = *yyssp; ++ goto yyerrlab1; ++ ++ ++/*-------------------------------------------------------------. ++| yyerrlab1 -- common code for both syntax error and YYERROR. | ++`-------------------------------------------------------------*/ ++yyerrlab1: ++ yyerrstatus = 3; /* Each real token shifted decrements this. */ ++ ++ for (;;) ++ { ++ yyn = yypact[yystate]; ++ if (yyn != YYPACT_NINF) ++ { ++ yyn += YYTERROR; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ { ++ yyn = yytable[yyn]; ++ if (0 < yyn) ++ break; ++ } ++ } ++ ++ /* Pop the current state because it cannot handle the error token. */ ++ if (yyssp == yyss) ++ YYABORT; ++ ++ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); ++ yydestruct (yystos[yystate], yyvsp); ++ YYPOPSTACK; ++ yystate = *yyssp; ++ YY_STACK_PRINT (yyss, yyssp); ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ YYDPRINTF ((stderr, "Shifting error token, ")); ++ ++ *++yyvsp = yylval; ++ ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-------------------------------------. ++| yyacceptlab -- YYACCEPT comes here. | ++`-------------------------------------*/ ++yyacceptlab: ++ yyresult = 0; ++ goto yyreturn; ++ ++/*-----------------------------------. ++| yyabortlab -- YYABORT comes here. | ++`-----------------------------------*/ ++yyabortlab: ++ yyresult = 1; ++ goto yyreturn; ++ ++#ifndef yyoverflow ++/*----------------------------------------------. ++| yyoverflowlab -- parser overflow comes here. | ++`----------------------------------------------*/ ++yyoverflowlab: ++ yyerror ("parser stack overflow"); ++ yyresult = 2; ++ /* Fall through. */ ++#endif ++ ++yyreturn: ++#ifndef yyoverflow ++ if (yyss != yyssa) ++ YYSTACK_FREE (yyss); ++#endif ++ return yyresult; ++} ++ ++ ++#line 510 "./cond.y" ++ ++ ++ ++static int COND_IsAlpha( WCHAR x ) ++{ ++ return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) || ++ ( ( x >= 'a' ) && ( x <= 'z' ) ) || ++ ( ( x == '_' ) ) ); ++} ++ ++static int COND_IsNumber( WCHAR x ) ++{ ++ return( (( x >= '0' ) && ( x <= '9' )) || (x =='-') || (x =='.') ); ++} ++ ++ ++/* the mess of comparison functions */ ++ ++static INT comp_lt_i(INT a, INT b) ++{ return (a < b); } ++static INT comp_gt_i(INT a, INT b) ++{ return (a > b); } ++static INT comp_le_i(INT a, INT b) ++{ return (a <= b); } ++static INT comp_ge_i(INT a, INT b) ++{ return (a >= b); } ++static INT comp_eq_i(INT a, INT b) ++{ return (a == b); } ++static INT comp_ne_i(INT a, INT b) ++{ return (a != b); } ++static INT comp_bitand(INT a, INT b) ++{ return a & b;} ++static INT comp_highcomp(INT a, INT b) ++{ return HIWORD(a)==b; } ++static INT comp_lowcomp(INT a, INT b) ++{ return LOWORD(a)==b; } ++ ++static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return !strcmpiW(a,b); else return !strcmpW(a,b);} ++static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b); else return strcmpW(a,b);} ++static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b)<0; else return strcmpW(a,b)<0;} ++static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b)>0; else return strcmpW(a,b)>0;} ++static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b)<=0; else return strcmpW(a,b)<=0;} ++static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b)>=0; else return strcmpW(a,b)>=0;} ++static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless) ++/* ERROR NOT WORKING REWRITE */ ++{ if (casless) return strstrW(a,b)!=NULL; else return strstrW(a,b)!=NULL;} ++static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strncmpiW(a,b,strlenW(b))==0; ++ else return strncmpW(a,b,strlenW(b))==0;} ++static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless) ++{ ++ int i = strlenW(a); ++ int j = strlenW(b); ++ if (j>i) ++ return 0; ++ if (casless) return (!strcmpiW(&a[i-j-1],b)); ++ else return (!strcmpW(&a[i-j-1],b)); ++} ++ ++ ++static INT comp_eq_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;} ++static INT comp_ne_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;} ++static INT comp_lt_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)b; else return 0;} ++static INT comp_le_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;} ++static INT comp_ge_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;} ++ ++static INT comp_eq_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;} ++static INT comp_ne_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;} ++static INT comp_lt_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;} ++static INT comp_gt_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;} ++static INT comp_le_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;} ++static INT comp_ge_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;} ++ ++ ++ ++static int COND_IsIdent( WCHAR x ) ++{ ++ return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) ++ || ( x == '#' ) || (x == '.') ); ++} ++ ++static int COND_GetOne( struct cond_str *str, COND_input *cond ) ++{ ++ static const WCHAR szNot[] = {'N','O','T',0}; ++ static const WCHAR szAnd[] = {'A','N','D',0}; ++ static const WCHAR szOr[] = {'O','R',0}; ++ WCHAR ch; ++ int rc, len = 1; ++ ++ str->data = &cond->str[cond->n]; ++ ++ ch = str->data[0]; ++ switch( ch ) ++ { ++ case 0: return 0; ++ case '(': rc = COND_LPAR; break; ++ case ')': rc = COND_RPAR; break; ++ case '&': rc = COND_AMPER; break; ++ case '!': rc = COND_EXCLAM; break; ++ case '$': rc = COND_DOLLARS; break; ++ case '?': rc = COND_QUESTION; break; ++ case '%': rc = COND_PERCENT; break; ++ case ' ': rc = COND_SPACE; break; ++ case '=': rc = COND_EQ; break; ++ case '~': rc = COND_TILDA; break; ++ case '<': rc = COND_LT; break; ++ case '>': rc = COND_GT; break; ++ case '"': ++ { ++ const WCHAR *ch2 = str->data + 1; ++ ++ ++ while ( *ch2 && *ch2 != '"' ) ++ ++ch2; ++ if (*ch2 == '"') ++ { ++ len = ch2 - str->data + 1; ++ rc = COND_LITER; ++ break; ++ } ++ } ++ ERR("Unterminated string\n"); ++ rc = COND_ERROR; ++ break; ++ default: ++ if( COND_IsAlpha( ch ) ) ++ { ++ while( COND_IsIdent( str->data[len] ) ) ++ len++; ++ rc = COND_IDENT; ++ break; ++ } ++ ++ if( COND_IsNumber( ch ) ) ++ { ++ while( COND_IsNumber( str->data[len] ) ) ++ len++; ++ rc = COND_NUMBER; ++ break; ++ } ++ ++ ERR("Got unknown character %c(%x)\n",ch,ch); ++ rc = COND_ERROR; ++ break; ++ } ++ ++ /* keyword identifiers */ ++ if( rc == COND_IDENT ) ++ { ++ if( (len==3) && (strncmpiW(str->data,szNot,len)==0) ) ++ rc = COND_NOT; ++ else if( (len==3) && (strncmpiW(str->data,szAnd,len)==0) ) ++ rc = COND_AND; ++ else if( (len==2) && (strncmpiW(str->data,szOr,len)==0) ) ++ rc = COND_OR; ++ } ++ ++ cond->n += len; ++ str->len = len; ++ ++ return rc; ++} ++ ++static int COND_lex( void *COND_lval, COND_input *cond ) ++{ ++ int rc; ++ struct cond_str *str = COND_lval; ++ ++ do { ++ rc = COND_GetOne( str, cond ); ++ } while (rc == COND_SPACE); ++ ++ return rc; ++} ++ ++static LPWSTR COND_GetString( struct cond_str *str ) ++{ ++ LPWSTR ret; ++ ++ ret = msi_alloc( (str->len+1) * sizeof (WCHAR) ); ++ if( ret ) ++ { ++ memcpy( ret, str->data, str->len * sizeof(WCHAR)); ++ ret[str->len]=0; ++ } ++ TRACE("Got identifier %s\n",debugstr_w(ret)); ++ return ret; ++} ++ ++static LPWSTR COND_GetLiteral( struct cond_str *str ) ++{ ++ LPWSTR ret; ++ ++ ret = msi_alloc( (str->len-1) * sizeof (WCHAR) ); ++ if( ret ) ++ { ++ memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) ); ++ ret[str->len - 2]=0; ++ } ++ TRACE("Got literal %s\n",debugstr_w(ret)); ++ return ret; ++} ++ ++static int COND_error(const char *str) ++{ ++ return 0; ++} ++ ++MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition ) ++{ ++ COND_input cond; ++ MSICONDITION r; ++ ++ cond.package = package; ++ cond.str = szCondition; ++ cond.n = 0; ++ cond.result = -1; ++ ++ TRACE("Evaluating %s\n",debugstr_w(szCondition)); ++ ++ if ( szCondition == NULL || szCondition[0] == 0) ++ r = MSICONDITION_NONE; ++ else if ( !COND_parse( &cond ) ) ++ r = cond.result; ++ else ++ r = MSICONDITION_ERROR; ++ ++ TRACE("Evaluates to %i\n",r); ++ return r; ++} ++ ++MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition ) ++{ ++ MSIPACKAGE *package; ++ UINT ret; ++ ++ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); ++ if( !package) ++ return ERROR_INVALID_HANDLE; ++ ret = MSI_EvaluateConditionW( package, szCondition ); ++ msiobj_release( &package->hdr ); ++ return ret; ++} ++ ++MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition ) ++{ ++ LPWSTR szwCond = NULL; ++ MSICONDITION r; ++ ++ if( szCondition ) ++ { ++ UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 ); ++ szwCond = msi_alloc( len * sizeof (WCHAR) ); ++ MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len ); ++ } ++ ++ r = MsiEvaluateConditionW( hInstall, szwCond ); ++ ++ msi_free( szwCond ); ++ ++ return r; ++} ++ Index: cond.tab.h =================================================================== --- cond.tab.h (revision 23782) +++ cond.tab.h (working copy) @@ -0,0 +1,99 @@ -+/* A Bison parser, made by GNU Bison 1.875c. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -+ -+ 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, 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., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COND_SPACE = 258, -+ COND_EOF = 259, -+ COND_OR = 260, -+ COND_AND = 261, -+ COND_NOT = 262, -+ COND_LT = 263, -+ COND_GT = 264, -+ COND_EQ = 265, -+ COND_LPAR = 266, -+ COND_RPAR = 267, -+ COND_TILDA = 268, -+ COND_PERCENT = 269, -+ COND_DOLLARS = 270, -+ COND_QUESTION = 271, -+ COND_AMPER = 272, -+ COND_EXCLAM = 273, -+ COND_IDENT = 274, -+ COND_NUMBER = 275, -+ COND_LITER = 276, -+ COND_ERROR = 277 -+ }; -+#endif -+#define COND_SPACE 258 -+#define COND_EOF 259 -+#define COND_OR 260 -+#define COND_AND 261 -+#define COND_NOT 262 -+#define COND_LT 263 -+#define COND_GT 264 -+#define COND_EQ 265 -+#define COND_LPAR 266 -+#define COND_RPAR 267 -+#define COND_TILDA 268 -+#define COND_PERCENT 269 -+#define COND_DOLLARS 270 -+#define COND_QUESTION 271 -+#define COND_AMPER 272 -+#define COND_EXCLAM 273 -+#define COND_IDENT 274 -+#define COND_NUMBER 275 -+#define COND_LITER 276 -+#define COND_ERROR 277 -+ -+ -+ -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 106 "./cond.y" -+typedef union YYSTYPE { -+ struct cond_str str; -+ LPWSTR string; -+ INT value; -+ comp_int fn_comp_int; -+ comp_str fn_comp_str; -+ comp_m1 fn_comp_m1; -+ comp_m2 fn_comp_m2; -+} YYSTYPE; -+/* Line 1275 of yacc.c. */ -+#line 91 "cond.tab.h" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+ -+ ++/* A Bison parser, made by GNU Bison 1.875c. */ ++ ++/* Skeleton parser for Yacc-like parsing with Bison, ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++ 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, 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., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ ++ ++/* Tokens. */ ++#ifndef YYTOKENTYPE ++# define YYTOKENTYPE ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ COND_SPACE = 258, ++ COND_EOF = 259, ++ COND_OR = 260, ++ COND_AND = 261, ++ COND_NOT = 262, ++ COND_LT = 263, ++ COND_GT = 264, ++ COND_EQ = 265, ++ COND_LPAR = 266, ++ COND_RPAR = 267, ++ COND_TILDA = 268, ++ COND_PERCENT = 269, ++ COND_DOLLARS = 270, ++ COND_QUESTION = 271, ++ COND_AMPER = 272, ++ COND_EXCLAM = 273, ++ COND_IDENT = 274, ++ COND_NUMBER = 275, ++ COND_LITER = 276, ++ COND_ERROR = 277 ++ }; ++#endif ++#define COND_SPACE 258 ++#define COND_EOF 259 ++#define COND_OR 260 ++#define COND_AND 261 ++#define COND_NOT 262 ++#define COND_LT 263 ++#define COND_GT 264 ++#define COND_EQ 265 ++#define COND_LPAR 266 ++#define COND_RPAR 267 ++#define COND_TILDA 268 ++#define COND_PERCENT 269 ++#define COND_DOLLARS 270 ++#define COND_QUESTION 271 ++#define COND_AMPER 272 ++#define COND_EXCLAM 273 ++#define COND_IDENT 274 ++#define COND_NUMBER 275 ++#define COND_LITER 276 ++#define COND_ERROR 277 ++ ++ ++ ++ ++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) ++#line 106 "./cond.y" ++typedef union YYSTYPE { ++ struct cond_str str; ++ LPWSTR string; ++ INT value; ++ comp_int fn_comp_int; ++ comp_str fn_comp_str; ++ comp_m1 fn_comp_m1; ++ comp_m2 fn_comp_m2; ++} YYSTYPE; ++/* Line 1275 of yacc.c. */ ++#line 91 "cond.tab.h" ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ ++# define YYSTYPE_IS_DECLARED 1 ++# define YYSTYPE_IS_TRIVIAL 1 ++#endif ++ ++ ++ ++ ++ Index: helpers.c =================================================================== --- helpers.c (revision 23808) +++ helpers.c (working copy) @@ -25,6 +25,7 @@ - - #include - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winerror.h" + + #include + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winerror.h" Index: install.c =================================================================== --- install.c (revision 23808) +++ install.c (working copy) @@ -22,6 +22,7 @@ - - #include - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winerror.h" + + #include + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winerror.h" Index: msi.c =================================================================== --- msi.c (revision 23808) +++ msi.c (working copy) @@ -23,6 +23,7 @@ - #define COBJMACROS - #define NONAMELESSUNION - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winreg.h" + #define COBJMACROS + #define NONAMELESSUNION + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winreg.h" Index: msi.rbuild =================================================================== --- msi.rbuild (revision 23808) +++ msi.rbuild (working copy) -@@ -1,4 +1,5 @@ - -+ - - . - include/reactos/wine -@@ -28,6 +29,7 @@ - alter.c - appsearch.c - classes.c -+ cond.tab.c - create.c - custom.c - database.c -@@ -53,6 +55,7 @@ - regsvr.c - select.c - source.c -+ sql.tab.c - string.c - suminfo.c - table.c +@@ -29,6 +29,7 @@ + alter.c + appsearch.c + classes.c ++ cond.tab.c + create.c + custom.c + database.c +@@ -54,6 +55,7 @@ + regsvr.c + select.c + source.c ++ sql.tab.c + string.c + suminfo.c + table.c Index: msi_Ja.rc =================================================================== --- msi_Ja.rc (revision 23782) +++ msi_Ja.rc (working copy) @@ -0,0 +1,13 @@ -+LANGUAGE LANG_JAPANESE, SUBLANG_NEUTRAL -+ -+STRINGTABLE DISCARDABLE -+{ -+ 5 "pX %s ‚Ş‚Ý‚Â‚©‚č‚Ü‚ą‚ń‚Ĺ‚µ‚˝" -+ 9 "fBXN %s ‚đ‘}“ü‚µ‚Ä‚­‚ľ‚ł‚˘" -+ 10 "–łŚř‚Čp‰[^‚Ĺ‚·" -+ 11 "%s ‚Ě‚ ‚étH‹_‚đ“ü—Í‚µ‚Ä‚­‚ľ‚ł‚˘" -+ 12 "‹@”\\‚ĚC“Xg[‹Śł‚Ş‚ ‚č‚Ü‚ą‚ń" -+ 13 "‹@”\\‚Ş‚ ‚élbgŹ[N h‰Cu‚Ş‚ ‚č‚Ü‚ą‚ń" -+ 14 "‹@”\\‚̏ꏊ:" -+ 15 "%s ‚Ě‚ ‚étH‹_‚đ‘I‘đ‚µ‚Ä‚­‚ľ‚ł‚˘" ++LANGUAGE LANG_JAPANESE, SUBLANG_NEUTRAL ++ ++STRINGTABLE DISCARDABLE ++{ ++ 5 "pX %s ‚Ş‚Ý‚Â‚©‚č‚Ü‚ą‚ń‚Ĺ‚µ‚˝" ++ 9 "fBXN %s ‚đ‘}“ü‚µ‚Ä‚­‚ľ‚ł‚˘" ++ 10 "–łŚř‚Čp‰[^‚Ĺ‚·" ++ 11 "%s ‚Ě‚ ‚étH‹_‚đ“ü—Í‚µ‚Ä‚­‚ľ‚ł‚˘" ++ 12 "‹@”\\‚ĚC“Xg[‹Śł‚Ş‚ ‚č‚Ü‚ą‚ń" ++ 13 "‹@”\\‚Ş‚ ‚élbgŹ[N h‰Cu‚Ş‚ ‚č‚Ü‚ą‚ń" ++ 14 "‹@”\\‚̏ꏊ:" ++ 15 "%s ‚Ě‚ ‚étH‹_‚đ‘I‘đ‚µ‚Ä‚­‚ľ‚ł‚˘" +} Index: msiquery.c =================================================================== --- msiquery.c (revision 23808) +++ msiquery.c (working copy) @@ -22,6 +22,7 @@ - - #define COBJMACROS - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winerror.h" + + #define COBJMACROS + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winerror.h" Index: registry.c =================================================================== --- registry.c (revision 23808) +++ registry.c (working copy) @@ -24,6 +24,7 @@ - #define COBJMACROS - #define NONAMELESSUNION - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winreg.h" + #define COBJMACROS + #define NONAMELESSUNION + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winreg.h" Index: source.c =================================================================== --- source.c (revision 23808) +++ source.c (working copy) @@ -23,6 +23,7 @@ - #define COBJMACROS - #define NONAMELESSUNION - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winreg.h" + #define COBJMACROS + #define NONAMELESSUNION + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winreg.h" Index: sql.tab.c =================================================================== --- sql.tab.c (revision 23782) +++ sql.tab.c (working copy) @@ -0,0 +1,2484 @@ -+/* A Bison parser, made by GNU Bison 1.875c. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -+ -+ 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, 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., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Written by Richard Stallman by simplifying the original so called -+ ``semantic'' parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 1 -+ -+/* Using locations. */ -+#define YYLSP_NEEDED 0 -+ -+/* If NAME_PREFIX is specified substitute the variables and functions -+ names. */ -+#define yyparse SQL_parse -+#define yylex SQL_lex -+#define yyerror SQL_error -+#define yylval SQL_lval -+#define yychar SQL_char -+#define yydebug SQL_debug -+#define yynerrs SQL_nerrs -+ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ TK_ABORT = 258, -+ TK_AFTER = 259, -+ TK_AGG_FUNCTION = 260, -+ TK_ALL = 261, -+ TK_AND = 262, -+ TK_AS = 263, -+ TK_ASC = 264, -+ TK_BEFORE = 265, -+ TK_BEGIN = 266, -+ TK_BETWEEN = 267, -+ TK_BITAND = 268, -+ TK_BITNOT = 269, -+ TK_BITOR = 270, -+ TK_BY = 271, -+ TK_CASCADE = 272, -+ TK_CASE = 273, -+ TK_CHAR = 274, -+ TK_CHECK = 275, -+ TK_CLUSTER = 276, -+ TK_COLLATE = 277, -+ TK_COLUMN = 278, -+ TK_COMMA = 279, -+ TK_COMMENT = 280, -+ TK_COMMIT = 281, -+ TK_CONCAT = 282, -+ TK_CONFLICT = 283, -+ TK_CONSTRAINT = 284, -+ TK_COPY = 285, -+ TK_CREATE = 286, -+ TK_DEFAULT = 287, -+ TK_DEFERRABLE = 288, -+ TK_DEFERRED = 289, -+ TK_DELETE = 290, -+ TK_DELIMITERS = 291, -+ TK_DESC = 292, -+ TK_DISTINCT = 293, -+ TK_DOT = 294, -+ TK_DROP = 295, -+ TK_EACH = 296, -+ TK_ELSE = 297, -+ TK_END = 298, -+ TK_END_OF_FILE = 299, -+ TK_EQ = 300, -+ TK_EXCEPT = 301, -+ TK_EXPLAIN = 302, -+ TK_FAIL = 303, -+ TK_FLOAT = 304, -+ TK_FOR = 305, -+ TK_FOREIGN = 306, -+ TK_FROM = 307, -+ TK_FUNCTION = 308, -+ TK_GE = 309, -+ TK_GLOB = 310, -+ TK_GROUP = 311, -+ TK_GT = 312, -+ TK_HAVING = 313, -+ TK_HOLD = 314, -+ TK_IGNORE = 315, -+ TK_ILLEGAL = 316, -+ TK_IMMEDIATE = 317, -+ TK_IN = 318, -+ TK_INDEX = 319, -+ TK_INITIALLY = 320, -+ TK_ID = 321, -+ TK_INSERT = 322, -+ TK_INSTEAD = 323, -+ TK_INT = 324, -+ TK_INTEGER = 325, -+ TK_INTERSECT = 326, -+ TK_INTO = 327, -+ TK_IS = 328, -+ TK_ISNULL = 329, -+ TK_JOIN = 330, -+ TK_JOIN_KW = 331, -+ TK_KEY = 332, -+ TK_LE = 333, -+ TK_LIKE = 334, -+ TK_LIMIT = 335, -+ TK_LONG = 336, -+ TK_LONGCHAR = 337, -+ TK_LP = 338, -+ TK_LSHIFT = 339, -+ TK_LT = 340, -+ TK_LOCALIZABLE = 341, -+ TK_MATCH = 342, -+ TK_MINUS = 343, -+ TK_NE = 344, -+ TK_NOT = 345, -+ TK_NOTNULL = 346, -+ TK_NULL = 347, -+ TK_OBJECT = 348, -+ TK_OF = 349, -+ TK_OFFSET = 350, -+ TK_ON = 351, -+ TK_OR = 352, -+ TK_ORACLE_OUTER_JOIN = 353, -+ TK_ORDER = 354, -+ TK_PLUS = 355, -+ TK_PRAGMA = 356, -+ TK_PRIMARY = 357, -+ TK_RAISE = 358, -+ TK_REFERENCES = 359, -+ TK_REM = 360, -+ TK_REPLACE = 361, -+ TK_RESTRICT = 362, -+ TK_ROLLBACK = 363, -+ TK_ROW = 364, -+ TK_RP = 365, -+ TK_RSHIFT = 366, -+ TK_SELECT = 367, -+ TK_SEMI = 368, -+ TK_SET = 369, -+ TK_SHORT = 370, -+ TK_SLASH = 371, -+ TK_SPACE = 372, -+ TK_STAR = 373, -+ TK_STATEMENT = 374, -+ TK_STRING = 375, -+ TK_TABLE = 376, -+ TK_TEMP = 377, -+ TK_THEN = 378, -+ TK_TRANSACTION = 379, -+ TK_TRIGGER = 380, -+ TK_UMINUS = 381, -+ TK_UNCLOSED_STRING = 382, -+ TK_UNION = 383, -+ TK_UNIQUE = 384, -+ TK_UPDATE = 385, -+ TK_UPLUS = 386, -+ TK_USING = 387, -+ TK_VACUUM = 388, -+ TK_VALUES = 389, -+ TK_VIEW = 390, -+ TK_WHEN = 391, -+ TK_WHERE = 392, -+ TK_WILDCARD = 393, -+ COLUMN = 395, -+ FUNCTION = 396, -+ COMMENT = 397, -+ UNCLOSED_STRING = 398, -+ SPACE = 399, -+ ILLEGAL = 400, -+ END_OF_FILE = 401 -+ }; -+#endif -+#define TK_ABORT 258 -+#define TK_AFTER 259 -+#define TK_AGG_FUNCTION 260 -+#define TK_ALL 261 -+#define TK_AND 262 -+#define TK_AS 263 -+#define TK_ASC 264 -+#define TK_BEFORE 265 -+#define TK_BEGIN 266 -+#define TK_BETWEEN 267 -+#define TK_BITAND 268 -+#define TK_BITNOT 269 -+#define TK_BITOR 270 -+#define TK_BY 271 -+#define TK_CASCADE 272 -+#define TK_CASE 273 -+#define TK_CHAR 274 -+#define TK_CHECK 275 -+#define TK_CLUSTER 276 -+#define TK_COLLATE 277 -+#define TK_COLUMN 278 -+#define TK_COMMA 279 -+#define TK_COMMENT 280 -+#define TK_COMMIT 281 -+#define TK_CONCAT 282 -+#define TK_CONFLICT 283 -+#define TK_CONSTRAINT 284 -+#define TK_COPY 285 -+#define TK_CREATE 286 -+#define TK_DEFAULT 287 -+#define TK_DEFERRABLE 288 -+#define TK_DEFERRED 289 -+#define TK_DELETE 290 -+#define TK_DELIMITERS 291 -+#define TK_DESC 292 -+#define TK_DISTINCT 293 -+#define TK_DOT 294 -+#define TK_DROP 295 -+#define TK_EACH 296 -+#define TK_ELSE 297 -+#define TK_END 298 -+#define TK_END_OF_FILE 299 -+#define TK_EQ 300 -+#define TK_EXCEPT 301 -+#define TK_EXPLAIN 302 -+#define TK_FAIL 303 -+#define TK_FLOAT 304 -+#define TK_FOR 305 -+#define TK_FOREIGN 306 -+#define TK_FROM 307 -+#define TK_FUNCTION 308 -+#define TK_GE 309 -+#define TK_GLOB 310 -+#define TK_GROUP 311 -+#define TK_GT 312 -+#define TK_HAVING 313 -+#define TK_HOLD 314 -+#define TK_IGNORE 315 -+#define TK_ILLEGAL 316 -+#define TK_IMMEDIATE 317 -+#define TK_IN 318 -+#define TK_INDEX 319 -+#define TK_INITIALLY 320 -+#define TK_ID 321 -+#define TK_INSERT 322 -+#define TK_INSTEAD 323 -+#define TK_INT 324 -+#define TK_INTEGER 325 -+#define TK_INTERSECT 326 -+#define TK_INTO 327 -+#define TK_IS 328 -+#define TK_ISNULL 329 -+#define TK_JOIN 330 -+#define TK_JOIN_KW 331 -+#define TK_KEY 332 -+#define TK_LE 333 -+#define TK_LIKE 334 -+#define TK_LIMIT 335 -+#define TK_LONG 336 -+#define TK_LONGCHAR 337 -+#define TK_LP 338 -+#define TK_LSHIFT 339 -+#define TK_LT 340 -+#define TK_LOCALIZABLE 341 -+#define TK_MATCH 342 -+#define TK_MINUS 343 -+#define TK_NE 344 -+#define TK_NOT 345 -+#define TK_NOTNULL 346 -+#define TK_NULL 347 -+#define TK_OBJECT 348 -+#define TK_OF 349 -+#define TK_OFFSET 350 -+#define TK_ON 351 -+#define TK_OR 352 -+#define TK_ORACLE_OUTER_JOIN 353 -+#define TK_ORDER 354 -+#define TK_PLUS 355 -+#define TK_PRAGMA 356 -+#define TK_PRIMARY 357 -+#define TK_RAISE 358 -+#define TK_REFERENCES 359 -+#define TK_REM 360 -+#define TK_REPLACE 361 -+#define TK_RESTRICT 362 -+#define TK_ROLLBACK 363 -+#define TK_ROW 364 -+#define TK_RP 365 -+#define TK_RSHIFT 366 -+#define TK_SELECT 367 -+#define TK_SEMI 368 -+#define TK_SET 369 -+#define TK_SHORT 370 -+#define TK_SLASH 371 -+#define TK_SPACE 372 -+#define TK_STAR 373 -+#define TK_STATEMENT 374 -+#define TK_STRING 375 -+#define TK_TABLE 376 -+#define TK_TEMP 377 -+#define TK_THEN 378 -+#define TK_TRANSACTION 379 -+#define TK_TRIGGER 380 -+#define TK_UMINUS 381 -+#define TK_UNCLOSED_STRING 382 -+#define TK_UNION 383 -+#define TK_UNIQUE 384 -+#define TK_UPDATE 385 -+#define TK_UPLUS 386 -+#define TK_USING 387 -+#define TK_VACUUM 388 -+#define TK_VALUES 389 -+#define TK_VIEW 390 -+#define TK_WHEN 391 -+#define TK_WHERE 392 -+#define TK_WILDCARD 393 -+#define COLUMN 395 -+#define FUNCTION 396 -+#define COMMENT 397 -+#define UNCLOSED_STRING 398 -+#define SPACE 399 -+#define ILLEGAL 400 -+#define END_OF_FILE 401 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+#line 1 "./sql.y" -+ -+ -+/* -+ * Implementation of the Microsoft Installer (msi.dll) -+ * -+ * Copyright 2002-2004 Mike McCormack for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "query.h" -+#include "wine/list.h" -+#include "wine/debug.h" -+ -+#define YYLEX_PARAM info -+#define YYPARSE_PARAM info -+ -+extern int SQL_error(const char *str); -+ -+WINE_DEFAULT_DEBUG_CHANNEL(msi); -+ -+typedef struct tag_SQL_input -+{ -+ MSIDATABASE *db; -+ LPCWSTR command; -+ DWORD n, len; -+ MSIVIEW **view; /* view structure for the resulting query */ -+ struct list *mem; -+} SQL_input; -+ -+static LPWSTR SQL_getstring( void *info, struct sql_str *str ); -+static INT SQL_getint( void *info ); -+static int SQL_lex( void *SQL_lval, SQL_input *info ); -+ -+static void *parser_alloc( void *info, unsigned int sz ); -+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ); -+ -+static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys); -+ -+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ); -+static struct expr * EXPR_column( void *info, column_info *column ); -+static struct expr * EXPR_ival( void *info, int val ); -+static struct expr * EXPR_sval( void *info, struct sql_str * ); -+static struct expr * EXPR_wildcard( void *info ); -+ -+ -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 72 "./sql.y" -+typedef union YYSTYPE { -+ struct sql_str str; -+ LPWSTR string; -+ column_info *column_list; -+ MSIVIEW *query; -+ struct expr *expr; -+ USHORT column_type; -+ int integer; -+} YYSTYPE; -+/* Line 191 of yacc.c. */ -+#line 453 "sql.tab.c" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+/* Copy the second part of user declarations. */ -+ -+ -+/* Line 214 of yacc.c. */ -+#line 465 "sql.tab.c" -+ -+#if ! defined (yyoverflow) || YYERROR_VERBOSE -+ -+# ifndef YYFREE -+# define YYFREE free -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# endif -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# define YYSTACK_ALLOC alloca -+# endif -+# else -+# if defined (alloca) || defined (_ALLOCA_H) -+# define YYSTACK_ALLOC alloca -+# else -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+# else -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# endif -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# endif -+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ -+ -+ -+#if (! defined (yyoverflow) \ -+ && (! defined (__cplusplus) \ -+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ short yyss; -+ YYSTYPE yyvs; -+ }; -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ -+ + YYSTACK_GAP_MAXIMUM) -+ -+/* Copy COUNT objects from FROM to TO. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined (__GNUC__) && 1 < __GNUC__ -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# else -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ register YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (0) -+# endif -+# endif -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack, Stack, yysize); \ -+ Stack = &yyptr->Stack; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) -+ -+#endif -+ -+#if defined (__STDC__) || defined (__cplusplus) -+ typedef signed char yysigned_char; -+#else -+ typedef short yysigned_char; -+#endif -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 29 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 124 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 147 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 31 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 69 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 127 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 401 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const unsigned char yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, -+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, -+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, -+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, -+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, -+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, -+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, -+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, -+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, -+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, -+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, -+ 145, 146 -+}; -+ -+#if YYDEBUG -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const unsigned char yyprhs[] = -+{ -+ 0, 0, 3, 5, 7, 9, 11, 13, 15, 26, -+ 38, 45, 53, 60, 63, 68, 72, 74, 77, 79, -+ 82, 84, 88, 90, 95, 97, 99, 101, 103, 105, -+ 107, 112, 114, 117, 121, 124, 126, 130, 132, 134, -+ 138, 141, 145, 149, 153, 157, 161, 165, 169, 173, -+ 177, 181, 185, 190, 192, 194, 196, 200, 202, 206, -+ 210, 212, 215, 217, 219, 221, 225, 227, 229, 231 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const short yyrhs[] = -+{ -+ 148, 0, -1, 149, -1, 161, -1, 151, -1, 150, -+ -1, 152, -1, 153, -1, 67, 72, 175, 83, 164, -+ 110, 134, 83, 169, 110, -1, 67, 72, 175, 83, -+ 164, 110, 134, 83, 169, 110, 122, -1, 31, 121, -+ 175, 83, 154, 110, -1, 31, 121, 175, 83, 154, -+ 110, 59, -1, 130, 175, 114, 170, 137, 167, -1, -+ 35, 165, -1, 155, 102, 77, 164, -1, 155, 24, -+ 156, -1, 156, -1, 174, 157, -1, 158, -1, 158, -+ 86, -1, 159, -1, 159, 90, 92, -1, 19, -1, -+ 19, 83, 160, 110, -1, 82, -1, 115, -1, 69, -+ -1, 81, -1, 93, -1, 177, -1, 162, 99, 16, -+ 164, -1, 162, -1, 112, 163, -1, 112, 38, 163, -+ -1, 164, 165, -1, 174, -1, 174, 24, 164, -1, -+ 118, -1, 166, -1, 166, 137, 167, -1, 52, 175, -+ -1, 83, 167, 110, -1, 173, 45, 173, -1, 167, -+ 7, 167, -1, 167, 97, 167, -1, 173, 45, 168, -+ -1, 173, 57, 168, -1, 173, 85, 168, -1, 173, -+ 78, 168, -1, 173, 54, 168, -1, 173, 89, 168, -+ -1, 173, 73, 92, -1, 173, 73, 90, 92, -1, -+ 173, -1, 172, -1, 172, -1, 172, 24, 169, -1, -+ 171, -1, 171, 24, 170, -1, 174, 45, 172, -1, -+ 177, -1, 88, 177, -1, 120, -1, 138, -1, 174, -+ -1, 175, 39, 176, -1, 176, -1, 176, -1, 66, -+ -1, 70, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const unsigned short yyrline[] = -+{ -+ 0, 138, 138, 146, 147, 148, 149, 150, 154, 165, -+ 178, 190, 205, 218, 231, 241, 251, 258, 266, 270, -+ 277, 281, 288, 292, 296, 300, 304, 308, 312, 319, -+ 328, 340, 344, 348, 364, 385, 386, 390, 397, 398, -+ 414, 427, 433, 439, 445, 451, 457, 463, 469, 475, -+ 481, 487, 493, 502, 503, 507, 514, 525, 526, 534, -+ 542, 548, 554, 560, 569, 578, 584, 593, 600, 609 -+}; -+#endif -+ -+#if YYDEBUG || YYERROR_VERBOSE -+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "TK_ABORT", "TK_AFTER", -+ "TK_AGG_FUNCTION", "TK_ALL", "TK_AND", "TK_AS", "TK_ASC", "TK_BEFORE", -+ "TK_BEGIN", "TK_BETWEEN", "TK_BITAND", "TK_BITNOT", "TK_BITOR", "TK_BY", -+ "TK_CASCADE", "TK_CASE", "TK_CHAR", "TK_CHECK", "TK_CLUSTER", -+ "TK_COLLATE", "TK_COLUMN", "TK_COMMA", "TK_COMMENT", "TK_COMMIT", -+ "TK_CONCAT", "TK_CONFLICT", "TK_CONSTRAINT", "TK_COPY", "TK_CREATE", -+ "TK_DEFAULT", "TK_DEFERRABLE", "TK_DEFERRED", "TK_DELETE", -+ "TK_DELIMITERS", "TK_DESC", "TK_DISTINCT", "TK_DOT", "TK_DROP", -+ "TK_EACH", "TK_ELSE", "TK_END", "TK_END_OF_FILE", "TK_EQ", "TK_EXCEPT", -+ "TK_EXPLAIN", "TK_FAIL", "TK_FLOAT", "TK_FOR", "TK_FOREIGN", "TK_FROM", -+ "TK_FUNCTION", "TK_GE", "TK_GLOB", "TK_GROUP", "TK_GT", "TK_HAVING", -+ "TK_HOLD", "TK_IGNORE", "TK_ILLEGAL", "TK_IMMEDIATE", "TK_IN", -+ "TK_INDEX", "TK_INITIALLY", "TK_ID", "TK_INSERT", "TK_INSTEAD", "TK_INT", -+ "TK_INTEGER", "TK_INTERSECT", "TK_INTO", "TK_IS", "TK_ISNULL", "TK_JOIN", -+ "TK_JOIN_KW", "TK_KEY", "TK_LE", "TK_LIKE", "TK_LIMIT", "TK_LONG", -+ "TK_LONGCHAR", "TK_LP", "TK_LSHIFT", "TK_LT", "TK_LOCALIZABLE", -+ "TK_MATCH", "TK_MINUS", "TK_NE", "TK_NOT", "TK_NOTNULL", "TK_NULL", -+ "TK_OBJECT", "TK_OF", "TK_OFFSET", "TK_ON", "TK_OR", -+ "TK_ORACLE_OUTER_JOIN", "TK_ORDER", "TK_PLUS", "TK_PRAGMA", "TK_PRIMARY", -+ "TK_RAISE", "TK_REFERENCES", "TK_REM", "TK_REPLACE", "TK_RESTRICT", -+ "TK_ROLLBACK", "TK_ROW", "TK_RP", "TK_RSHIFT", "TK_SELECT", "TK_SEMI", -+ "TK_SET", "TK_SHORT", "TK_SLASH", "TK_SPACE", "TK_STAR", "TK_STATEMENT", -+ "TK_STRING", "TK_TABLE", "TK_TEMP", "TK_THEN", "TK_TRANSACTION", -+ "TK_TRIGGER", "TK_UMINUS", "TK_UNCLOSED_STRING", "TK_UNION", "TK_UNIQUE", -+ "TK_UPDATE", "TK_UPLUS", "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW", -+ "TK_WHEN", "TK_WHERE", "TK_WILDCARD", "AGG_FUNCTION.", "COLUMN", -+ "FUNCTION", "COMMENT", "UNCLOSED_STRING", "SPACE", "ILLEGAL", -+ "END_OF_FILE", "$accept", "query", "onequery", "oneinsert", "onecreate", -+ "oneupdate", "onedelete", "table_def", "column_def", "column_and_type", -+ "column_type", "data_type_l", "data_type", "data_count", "oneselect", -+ "unorderedsel", "selectfrom", "selcollist", "from", "fromtable", "expr", -+ "val", "constlist", "update_assign_list", "column_assignment", -+ "const_val", "column_val", "column", "table", "id", "number", 0 -+}; -+#endif -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const unsigned short yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, -+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, -+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, -+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, -+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, -+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, -+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, -+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, -+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, -+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -+ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, -+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, -+ 395, 396, 397, 398, 399, 400, 401 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const unsigned char yyr1[] = -+{ -+ 0, 147, 148, 149, 149, 149, 149, 149, 150, 150, -+ 151, 151, 152, 153, 154, 155, 155, 156, 157, 157, -+ 158, 158, 159, 159, 159, 159, 159, 159, 159, 160, -+ 161, 161, 162, 162, 163, 164, 164, 164, 165, 165, -+ 166, 167, 167, 167, 167, 167, 167, 167, 167, 167, -+ 167, 167, 167, 168, 168, 169, 169, 170, 170, 171, -+ 172, 172, 172, 172, 173, 174, 174, 175, 176, 177 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const unsigned char yyr2[] = -+{ -+ 0, 2, 1, 1, 1, 1, 1, 1, 10, 11, -+ 6, 7, 6, 2, 4, 3, 1, 2, 1, 2, -+ 1, 3, 1, 4, 1, 1, 1, 1, 1, 1, -+ 4, 1, 2, 3, 2, 1, 3, 1, 1, 3, -+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, -+ 3, 3, 4, 1, 1, 1, 3, 1, 3, 3, -+ 1, 2, 1, 1, 1, 3, 1, 1, 1, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state -+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const unsigned char yydefact[] = -+{ -+ 0, 0, 0, 0, 0, 0, 0, 2, 5, 4, -+ 6, 7, 3, 31, 0, 0, 13, 38, 0, 0, -+ 68, 37, 32, 0, 35, 0, 66, 0, 67, 1, -+ 0, 0, 40, 0, 0, 33, 34, 0, 0, 0, -+ 0, 0, 0, 39, 0, 64, 0, 36, 65, 0, -+ 57, 0, 30, 0, 0, 16, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 10, 0, 0, 22, 26, 27, 24, 28, 25, -+ 17, 18, 20, 41, 43, 44, 69, 0, 62, 63, -+ 45, 54, 42, 60, 49, 53, 46, 0, 51, 48, -+ 47, 50, 0, 12, 58, 59, 11, 15, 0, 0, -+ 19, 0, 61, 52, 0, 14, 0, 29, 21, 0, -+ 23, 0, 55, 8, 0, 9, 56 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const yysigned_char yydefgoto[] = -+{ -+ -1, 6, 7, 8, 9, 10, 11, 53, 54, 55, -+ 80, 81, 82, 116, 12, 13, 22, 23, 16, 17, -+ 43, 90, 121, 49, 50, 91, 44, 45, 25, 26, -+ 93 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -111 -+static const yysigned_char yypact[] = -+{ -+ -28, -110, -38, -46, -32, -42, 29, -111, -111, -111, -+ -111, -111, -111, -67, -42, -42, -111, -99, -42, -48, -+ -111, -111, -111, -38, 17, 7, 11, -62, -111, -111, -+ 37, -22, -111, -43, -16, -111, -111, -48, -42, -42, -+ -48, -42, -43, -3, -29, -111, -48, -111, -111, -68, -+ 48, 28, -111, -36, -19, -111, -18, -5, -43, -43, -+ -58, -58, -58, -70, -58, -58, -58, -34, -43, -42, -+ -61, 20, -42, 5, 2, -111, -111, -111, -111, -111, -+ -111, 1, -2, -111, -3, -3, -111, 19, -111, -111, -+ -111, -111, -111, -111, -111, -111, -111, -1, -111, -111, -+ -111, -111, -41, -3, -111, -111, -111, -111, -48, 19, -+ -111, 3, -111, -111, 13, -111, -12, -111, -111, -61, -+ -111, -9, 91, -13, -61, -111, -111 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const yysigned_char yypgoto[] = -+{ -+ -111, -111, -111, -111, -111, -111, -111, -111, -111, 47, -+ -111, -111, -111, -111, -111, -111, 101, -27, 98, -111, -+ -11, 52, 0, 53, -111, -53, 46, -4, 85, 40, -+ -66 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If zero, do what YYDEFACT says. -+ If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -68 -+static const yysigned_char yytable[] = -+{ -+ 24, 74, 58, 1, 58, 72, 19, 2, 20, 86, -+ 47, 14, 86, 52, 15, 24, 60, 105, 20, 67, -+ 97, 112, 98, 20, 20, 61, 18, 87, 62, 29, -+ 87, 57, 30, 24, 20, 51, 24, 56, 33, 3, -+ 42, 37, 24, 117, 63, 28, 38, 84, 85, 64, -+ -67, 75, 39, 40, 28, 28, 65, 103, 28, 88, -+ 66, 41, 88, 76, 77, 51, 122, 46, 56, 68, -+ 21, 122, 69, 70, 71, 78, 102, 89, 48, 106, -+ 89, 115, 108, 73, 4, 109, 21, 110, 111, 86, -+ 27, 113, 59, 114, 59, 118, 119, 79, 120, 31, -+ 32, 123, 5, 34, 24, 83, 92, 95, 95, 125, -+ 95, 95, 95, 94, 96, 124, 99, 100, 101, 107, -+ 35, 36, 104, 0, 126 -+}; -+ -+static const short yycheck[] = -+{ -+ 4, 19, 7, 31, 7, 24, 38, 35, 66, 70, -+ 37, 121, 70, 40, 52, 19, 45, 70, 66, 46, -+ 90, 87, 92, 66, 66, 54, 72, 88, 57, 0, -+ 88, 42, 99, 37, 66, 39, 40, 41, 137, 67, -+ 83, 24, 46, 109, 73, 5, 39, 58, 59, 78, -+ 39, 69, 114, 16, 14, 15, 85, 68, 18, 120, -+ 89, 83, 120, 81, 82, 69, 119, 83, 72, 137, -+ 118, 124, 24, 45, 110, 93, 110, 138, 38, 59, -+ 138, 108, 77, 102, 112, 83, 118, 86, 90, 70, -+ 5, 92, 97, 134, 97, 92, 83, 115, 110, 14, -+ 15, 110, 130, 18, 108, 110, 60, 61, 62, 122, -+ 64, 65, 66, 61, 62, 24, 64, 65, 66, 72, -+ 19, 23, 69, -1, 124 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const unsigned char yystos[] = -+{ -+ 0, 31, 35, 67, 112, 130, 148, 149, 150, 151, -+ 152, 153, 161, 162, 121, 52, 165, 166, 72, 38, -+ 66, 118, 163, 164, 174, 175, 176, 175, 176, 0, -+ 99, 175, 175, 137, 175, 163, 165, 24, 39, 114, -+ 16, 83, 83, 167, 173, 174, 83, 164, 176, 170, -+ 171, 174, 164, 154, 155, 156, 174, 167, 7, 97, -+ 45, 54, 57, 73, 78, 85, 89, 164, 137, 24, -+ 45, 110, 24, 102, 19, 69, 81, 82, 93, 115, -+ 157, 158, 159, 110, 167, 167, 70, 88, 120, 138, -+ 168, 172, 173, 177, 168, 173, 168, 90, 92, 168, -+ 168, 168, 110, 167, 170, 172, 59, 156, 77, 83, -+ 86, 90, 177, 92, 134, 164, 160, 177, 92, 83, -+ 110, 169, 172, 110, 24, 122, 169 -+}; -+ -+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -+# define YYSIZE_T __SIZE_TYPE__ -+#endif -+#if ! defined (YYSIZE_T) && defined (size_t) -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# endif -+#endif -+#if ! defined (YYSIZE_T) -+# define YYSIZE_T unsigned int -+#endif -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. */ -+ -+#define YYFAIL goto yyerrlab -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ yytoken = YYTRANSLATE (yychar); \ -+ YYPOPSTACK; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror ("syntax error: cannot back up");\ -+ YYERROR; \ -+ } \ -+while (0) -+ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+/* YYLLOC_DEFAULT -- Compute the default location (before the actions -+ are run). */ -+ -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ ((Current).first_line = (Rhs)[1].first_line, \ -+ (Current).first_column = (Rhs)[1].first_column, \ -+ (Current).last_line = (Rhs)[N].last_line, \ -+ (Current).last_column = (Rhs)[N].last_column) -+#endif -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (&yylval, YYLEX_PARAM) -+#else -+# define YYLEX yylex (&yylval) -+#endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ -+# define YYDSYMPRINT(Args) \ -+do { \ -+ if (yydebug) \ -+ yysymprint Args; \ -+} while (0) -+ -+# define YYDSYMPRINTF(Title, Token, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yysymprint (stderr, \ -+ Token, Value); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_stack_print (short *bottom, short *top) -+#else -+static void -+yy_stack_print (bottom, top) -+ short *bottom; -+ short *top; -+#endif -+{ -+ YYFPRINTF (stderr, "Stack now"); -+ for (/* Nothing. */; bottom <= top; ++bottom) -+ YYFPRINTF (stderr, " %d", *bottom); -+ YYFPRINTF (stderr, "\n"); -+} -+ -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) -+ -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_reduce_print (int yyrule) -+#else -+static void -+yy_reduce_print (yyrule) -+ int yyrule; -+#endif -+{ -+ int yyi; -+ unsigned int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", -+ yyrule - 1, yylno); -+ /* Print the symbols being reduced, and their result. */ -+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) -+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); -+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -+} -+ -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (Rule); \ -+} while (0) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YYDSYMPRINT(Args) -+# define YYDSYMPRINTF(Title, Token, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 -+# undef YYMAXDEPTH -+#endif -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined (__GLIBC__) && defined (_STRING_H) -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+static YYSIZE_T -+# if defined (__STDC__) || defined (__cplusplus) -+yystrlen (const char *yystr) -+# else -+yystrlen (yystr) -+ const char *yystr; -+# endif -+{ -+ register const char *yys = yystr; -+ -+ while (*yys++ != '\0') -+ continue; -+ -+ return yys - yystr - 1; -+} -+# endif -+# endif -+ -+# ifndef yystpcpy -+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+static char * -+# if defined (__STDC__) || defined (__cplusplus) -+yystpcpy (char *yydest, const char *yysrc) -+# else -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+# endif -+{ -+ register char *yyd = yydest; -+ register const char *yys = yysrc; -+ -+ while ((*yyd++ = *yys++) != '\0') -+ continue; -+ -+ return yyd - 1; -+} -+# endif -+# endif -+ -+#endif /* !YYERROR_VERBOSE */ -+ -+ -+ -+#if YYDEBUG -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yysymprint (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (yytype < YYNTOKENS) -+ { -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+# ifdef YYPRINT -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# endif -+ } -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+ YYFPRINTF (yyoutput, ")"); -+} -+ -+#endif /* ! YYDEBUG */ -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yydestruct (int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yydestruct (yytype, yyvaluep) -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } -+} -+ -+ -+/* Prevent warnings from -Wmissing-prototypes. */ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM); -+# else -+int yyparse (); -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+ -+ -+ -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM) -+# else -+int yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int -+yyparse (void) -+#else -+int -+yyparse () -+ -+#endif -+#endif -+{ -+ /* The lookahead symbol. */ -+int yychar; -+ -+/* The semantic value of the lookahead symbol. */ -+YYSTYPE yylval; -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+ -+ register int yystate; -+ register int yyn; -+ int yyresult; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ /* Lookahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+ -+ /* Three stacks and their tools: -+ `yyss': related to states, -+ `yyvs': related to semantic values, -+ `yyls': related to locations. -+ -+ Refer to the stacks thru separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ short yyssa[YYINITDEPTH]; -+ short *yyss = yyssa; -+ register short *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs = yyvsa; -+ register YYSTYPE *yyvsp; -+ -+ -+ -+#define YYPOPSTACK (yyvsp--, yyssp--) -+ -+ YYSIZE_T yystacksize = YYINITDEPTH; -+ -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ -+ -+ /* When reducing, the number of symbols on the RHS of the reduced -+ rule. */ -+ int yylen; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. so pushing a state here evens the stacks. -+ */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ short *yyss1 = yyss; -+ -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow ("parser stack overflow", -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ -+ &yystacksize); -+ -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyoverflowlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyoverflowlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ short *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyoverflowlab; -+ YYSTACK_RELOCATE (yyss); -+ YYSTACK_RELOCATE (yyvs); -+ -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; -+ } -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+/* Do appropriate processing given the current state. */ -+/* Read a lookahead token if we need one and don't already have one. */ -+/* yyresume: */ -+ -+ /* First try to decide what to do without reference to lookahead token. */ -+ -+ yyn = yypact[yystate]; -+ if (yyn == YYPACT_NINF) -+ goto yydefault; -+ -+ /* Not known => get a lookahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ -+ if (yychar == YYEMPTY) -+ { -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) -+ { -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); -+ } -+ else -+ { -+ yytoken = YYTRANSLATE (yychar); -+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yyn == 0 || yyn == YYTABLE_NINF) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ /* Shift the lookahead token. */ -+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); -+ -+ /* Discard the token being shifted unless it is eof. */ -+ if (yychar != YYEOF) -+ yychar = YYEMPTY; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ -+yyreduce: -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+#line 139 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ *sql->view = yyvsp[0].query; -+ ;} -+ break; -+ -+ case 8: -+#line 155 "./sql.y" -+ { -+ SQL_input *sql = (SQL_input*) info; -+ MSIVIEW *insert = NULL; -+ UINT r; -+ -+ r = INSERT_CreateView( sql->db, &insert, yyvsp[-7].string, yyvsp[-5].column_list, yyvsp[-1].column_list, FALSE ); -+ if( !insert ) -+ YYABORT; -+ yyval.query = insert; -+ ;} -+ break; -+ -+ case 9: -+#line 166 "./sql.y" -+ { -+ SQL_input *sql = (SQL_input*) info; -+ MSIVIEW *insert = NULL; -+ -+ INSERT_CreateView( sql->db, &insert, yyvsp[-8].string, yyvsp[-6].column_list, yyvsp[-2].column_list, TRUE ); -+ if( !insert ) -+ YYABORT; -+ yyval.query = insert; -+ ;} -+ break; -+ -+ case 10: -+#line 179 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *create = NULL; -+ -+ if( !yyvsp[-1].column_list ) -+ YYABORT; -+ CREATE_CreateView( sql->db, &create, yyvsp[-3].string, yyvsp[-1].column_list, FALSE ); -+ if( !create ) -+ YYABORT; -+ yyval.query = create; -+ ;} -+ break; -+ -+ case 11: -+#line 191 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *create = NULL; -+ -+ if( !yyvsp[-2].column_list ) -+ YYABORT; -+ CREATE_CreateView( sql->db, &create, yyvsp[-4].string, yyvsp[-2].column_list, TRUE ); -+ if( !create ) -+ YYABORT; -+ yyval.query = create; -+ ;} -+ break; -+ -+ case 12: -+#line 206 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *update = NULL; -+ -+ UPDATE_CreateView( sql->db, &update, yyvsp[-4].string, yyvsp[-2].column_list, yyvsp[0].expr ); -+ if( !update ) -+ YYABORT; -+ yyval.query = update; -+ ;} -+ break; -+ -+ case 13: -+#line 219 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *delete = NULL; -+ -+ DELETE_CreateView( sql->db, &delete, yyvsp[0].query ); -+ if( !delete ) -+ YYABORT; -+ yyval.query = delete; -+ ;} -+ break; -+ -+ case 14: -+#line 232 "./sql.y" -+ { -+ if( SQL_MarkPrimaryKeys( yyvsp[-3].column_list, yyvsp[0].column_list ) ) -+ yyval.column_list = yyvsp[-3].column_list; -+ else -+ yyval.column_list = NULL; -+ ;} -+ break; -+ -+ case 15: -+#line 242 "./sql.y" -+ { -+ column_info *ci; -+ -+ for( ci = yyvsp[-2].column_list; ci->next; ci = ci->next ) -+ ; -+ -+ ci->next = yyvsp[0].column_list; -+ yyval.column_list = yyvsp[-2].column_list; -+ ;} -+ break; -+ -+ case 16: -+#line 252 "./sql.y" -+ { -+ yyval.column_list = yyvsp[0].column_list; -+ ;} -+ break; -+ -+ case 17: -+#line 259 "./sql.y" -+ { -+ yyval.column_list = yyvsp[-1].column_list; -+ yyval.column_list->type = yyvsp[0].column_type | MSITYPE_VALID; -+ ;} -+ break; -+ -+ case 18: -+#line 267 "./sql.y" -+ { -+ yyval.column_type = yyvsp[0].column_type; -+ ;} -+ break; -+ -+ case 19: -+#line 271 "./sql.y" -+ { -+ yyval.column_type = yyvsp[-1].column_type | MSITYPE_LOCALIZABLE; -+ ;} -+ break; -+ -+ case 20: -+#line 278 "./sql.y" -+ { -+ yyval.column_type |= MSITYPE_NULLABLE; -+ ;} -+ break; -+ -+ case 21: -+#line 282 "./sql.y" -+ { -+ yyval.column_type = yyvsp[-2].column_type; -+ ;} -+ break; -+ -+ case 22: -+#line 289 "./sql.y" -+ { -+ yyval.column_type = MSITYPE_STRING | 1; -+ ;} -+ break; -+ -+ case 23: -+#line 293 "./sql.y" -+ { -+ yyval.column_type = MSITYPE_STRING | 0x400 | yyvsp[-1].column_type; -+ ;} -+ break; -+ -+ case 24: -+#line 297 "./sql.y" -+ { -+ yyval.column_type = 2; -+ ;} -+ break; -+ -+ case 25: -+#line 301 "./sql.y" -+ { -+ yyval.column_type = 2; -+ ;} -+ break; -+ -+ case 26: -+#line 305 "./sql.y" -+ { -+ yyval.column_type = 2; -+ ;} -+ break; -+ -+ case 27: -+#line 309 "./sql.y" -+ { -+ yyval.column_type = 4; -+ ;} -+ break; -+ -+ case 28: -+#line 313 "./sql.y" -+ { -+ yyval.column_type = MSITYPE_STRING | MSITYPE_VALID; -+ ;} -+ break; -+ -+ case 29: -+#line 320 "./sql.y" -+ { -+ if( ( yyvsp[0].integer > 255 ) || ( yyvsp[0].integer < 0 ) ) -+ YYABORT; -+ yyval.column_type = yyvsp[0].integer; -+ ;} -+ break; -+ -+ case 30: -+#line 329 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ -+ yyval.query = NULL; -+ if( yyvsp[0].column_list ) -+ ORDER_CreateView( sql->db, &yyval.query, yyvsp[-3].query, yyvsp[0].column_list ); -+ else -+ yyval.query = yyvsp[-3].query; -+ if( !yyval.query ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 32: -+#line 345 "./sql.y" -+ { -+ yyval.query = yyvsp[0].query; -+ ;} -+ break; -+ -+ case 33: -+#line 349 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ yyval.query = NULL; -+ r = DISTINCT_CreateView( sql->db, &yyval.query, yyvsp[0].query ); -+ if (r != ERROR_SUCCESS) -+ { -+ yyvsp[0].query->ops->delete(yyvsp[0].query); -+ YYABORT; -+ } -+ ;} -+ break; -+ -+ case 34: -+#line 365 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ yyval.query = NULL; -+ if( yyvsp[-1].column_list ) -+ { -+ r = SELECT_CreateView( sql->db, &yyval.query, yyvsp[0].query, yyvsp[-1].column_list ); -+ if (r != ERROR_SUCCESS) -+ { -+ yyvsp[0].query->ops->delete(yyvsp[0].query); -+ YYABORT; -+ } -+ } -+ else -+ yyval.query = yyvsp[0].query; -+ ;} -+ break; -+ -+ case 36: -+#line 387 "./sql.y" -+ { -+ yyvsp[-2].column_list->next = yyvsp[0].column_list; -+ ;} -+ break; -+ -+ case 37: -+#line 391 "./sql.y" -+ { -+ yyval.column_list = NULL; -+ ;} -+ break; -+ -+ case 39: -+#line 399 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ yyval.query = NULL; -+ r = WHERE_CreateView( sql->db, &yyval.query, yyvsp[-2].query, yyvsp[0].expr ); -+ if( r != ERROR_SUCCESS ) -+ { -+ yyvsp[-2].query->ops->delete( yyvsp[-2].query ); -+ YYABORT; -+ } -+ ;} -+ break; -+ -+ case 40: -+#line 415 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ yyval.query = NULL; -+ r = TABLE_CreateView( sql->db, yyvsp[0].string, &yyval.query ); -+ if( r != ERROR_SUCCESS || !yyval.query ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 41: -+#line 428 "./sql.y" -+ { -+ yyval.expr = yyvsp[-1].expr; -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 42: -+#line 434 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 43: -+#line 440 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_AND, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 44: -+#line 446 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_OR, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 45: -+#line 452 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 46: -+#line 458 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GT, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 47: -+#line 464 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LT, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 48: -+#line 470 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LE, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 49: -+#line 476 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GE, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 50: -+#line 482 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_NE, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 51: -+#line 488 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_ISNULL, NULL ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 52: -+#line 494 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-3].expr, OP_NOTNULL, NULL ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 55: -+#line 508 "./sql.y" -+ { -+ yyval.column_list = parser_alloc_column( info, NULL, NULL ); -+ if( !yyval.column_list ) -+ YYABORT; -+ yyval.column_list->val = yyvsp[0].expr; -+ ;} -+ break; -+ -+ case 56: -+#line 515 "./sql.y" -+ { -+ yyval.column_list = parser_alloc_column( info, NULL, NULL ); -+ if( !yyval.column_list ) -+ YYABORT; -+ yyval.column_list->val = yyvsp[-2].expr; -+ yyval.column_list->next = yyvsp[0].column_list; -+ ;} -+ break; -+ -+ case 58: -+#line 527 "./sql.y" -+ { -+ yyval.column_list = yyvsp[-2].column_list; -+ yyval.column_list->next = yyvsp[0].column_list; -+ ;} -+ break; -+ -+ case 59: -+#line 535 "./sql.y" -+ { -+ yyval.column_list = yyvsp[-2].column_list; -+ yyval.column_list->val = yyvsp[0].expr; -+ ;} -+ break; -+ -+ case 60: -+#line 543 "./sql.y" -+ { -+ yyval.expr = EXPR_ival( info, yyvsp[0].integer ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 61: -+#line 549 "./sql.y" -+ { -+ yyval.expr = EXPR_ival( info, -yyvsp[0].integer ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 62: -+#line 555 "./sql.y" -+ { -+ yyval.expr = EXPR_sval( info, &yyvsp[0].str ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 63: -+#line 561 "./sql.y" -+ { -+ yyval.expr = EXPR_wildcard( info ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 64: -+#line 570 "./sql.y" -+ { -+ yyval.expr = EXPR_column( info, yyvsp[0].column_list ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 65: -+#line 579 "./sql.y" -+ { -+ yyval.column_list = parser_alloc_column( info, yyvsp[-2].string, yyvsp[0].string ); -+ if( !yyval.column_list ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 66: -+#line 585 "./sql.y" -+ { -+ yyval.column_list = parser_alloc_column( info, NULL, yyvsp[0].string ); -+ if( !yyval.column_list ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 67: -+#line 594 "./sql.y" -+ { -+ yyval.string = yyvsp[0].string; -+ ;} -+ break; -+ -+ case 68: -+#line 601 "./sql.y" -+ { -+ yyval.string = SQL_getstring( info, &yyvsp[0].str ); -+ if( !yyval.string ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 69: -+#line 610 "./sql.y" -+ { -+ yyval.integer = SQL_getint( info ); -+ ;} -+ break; -+ -+ -+ } -+ -+/* Line 1000 of yacc.c. */ -+#line 2054 "sql.tab.c" -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ -+ -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) -+ { -+ ++yynerrs; -+#if YYERROR_VERBOSE -+ yyn = yypact[yystate]; -+ -+ if (YYPACT_NINF < yyn && yyn < YYLAST) -+ { -+ YYSIZE_T yysize = 0; -+ int yytype = YYTRANSLATE (yychar); -+ const char* yyprefix; -+ char *yymsg; -+ int yyx; -+ -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yycount = 0; -+ -+ yyprefix = ", expecting "; -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); -+ yycount += 1; -+ if (yycount == 5) -+ { -+ yysize = 0; -+ break; -+ } -+ } -+ yysize += (sizeof ("syntax error, unexpected ") -+ + yystrlen (yytname[yytype])); -+ yymsg = (char *) YYSTACK_ALLOC (yysize); -+ if (yymsg != 0) -+ { -+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); -+ yyp = yystpcpy (yyp, yytname[yytype]); -+ -+ if (yycount < 5) -+ { -+ yyprefix = ", expecting "; -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ yyp = yystpcpy (yyp, yyprefix); -+ yyp = yystpcpy (yyp, yytname[yyx]); -+ yyprefix = " or "; -+ } -+ } -+ yyerror (yymsg); -+ YYSTACK_FREE (yymsg); -+ } -+ else -+ yyerror ("syntax error; also virtual memory exhausted"); -+ } -+ else -+#endif /* YYERROR_VERBOSE */ -+ yyerror ("syntax error"); -+ } -+ -+ -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse lookahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* If at end of input, pop the error token, -+ then the rest of the stack, then return failure. */ -+ if (yychar == YYEOF) -+ for (;;) -+ { -+ YYPOPSTACK; -+ if (yyssp == yyss) -+ YYABORT; -+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); -+ yydestruct (yystos[*yyssp], yyvsp); -+ } -+ } -+ else -+ { -+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); -+ yydestruct (yytoken, &yylval); -+ yychar = YYEMPTY; -+ -+ } -+ } -+ -+ /* Else will try to reuse lookahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+#ifdef __GNUC__ -+ /* Pacify GCC when the user code never invokes YYERROR and the label -+ yyerrorlab therefore never appears in user code. */ -+ if (0) -+ goto yyerrorlab; -+#endif -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (yyn != YYPACT_NINF) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); -+ yydestruct (yystos[yystate], yyvsp); -+ YYPOPSTACK; -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ YYDPRINTF ((stderr, "Shifting error token, ")); -+ -+ *++yyvsp = yylval; -+ -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#ifndef yyoverflow -+/*----------------------------------------------. -+| yyoverflowlab -- parser overflow comes here. | -+`----------------------------------------------*/ -+yyoverflowlab: -+ yyerror ("parser stack overflow"); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+ return yyresult; -+} -+ -+ -+#line 615 "./sql.y" -+ -+ -+static void *parser_alloc( void *info, unsigned int sz ) -+{ -+ SQL_input* sql = (SQL_input*) info; -+ struct list *mem; -+ -+ mem = msi_alloc( sizeof (struct list) + sz ); -+ list_add_tail( sql->mem, mem ); -+ return &mem[1]; -+} -+ -+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ) -+{ -+ column_info *col; -+ -+ col = parser_alloc( info, sizeof (*col) ); -+ if( col ) -+ { -+ col->table = table; -+ col->column = column; -+ col->val = NULL; -+ col->type = 0; -+ col->next = NULL; -+ } -+ -+ return col; -+} -+ -+int SQL_lex( void *SQL_lval, SQL_input *sql ) -+{ -+ int token; -+ struct sql_str * str = SQL_lval; -+ -+ do -+ { -+ sql->n += sql->len; -+ if( ! sql->command[sql->n] ) -+ return 0; /* end of input */ -+ -+ /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */ -+ sql->len = sqliteGetToken( &sql->command[sql->n], &token ); -+ if( sql->len==0 ) -+ break; -+ str->data = &sql->command[sql->n]; -+ str->len = sql->len; -+ } -+ while( token == TK_SPACE ); -+ -+ /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */ -+ -+ return token; -+} -+ -+LPWSTR SQL_getstring( void *info, struct sql_str *strdata ) -+{ -+ LPCWSTR p = strdata->data; -+ UINT len = strdata->len; -+ LPWSTR str; -+ -+ /* if there's quotes, remove them */ -+ if( ( (p[0]=='`') && (p[len-1]=='`') ) || -+ ( (p[0]=='\'') && (p[len-1]=='\'') ) ) -+ { -+ p++; -+ len -= 2; -+ } -+ str = parser_alloc( info, (len + 1)*sizeof(WCHAR) ); -+ if( !str ) -+ return str; -+ memcpy( str, p, len*sizeof(WCHAR) ); -+ str[len]=0; -+ -+ return str; -+} -+ -+INT SQL_getint( void *info ) -+{ -+ SQL_input* sql = (SQL_input*) info; -+ LPCWSTR p = &sql->command[sql->n]; -+ INT i, r = 0; -+ -+ for( i=0; ilen; i++ ) -+ { -+ if( '0' > p[i] || '9' < p[i] ) -+ { -+ ERR("should only be numbers here!\n"); -+ break; -+ } -+ r = (p[i]-'0') + r*10; -+ } -+ -+ return r; -+} -+ -+int SQL_error( const char *str ) -+{ -+ return 0; -+} -+ -+static struct expr * EXPR_wildcard( void *info ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_WILDCARD; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_COMPLEX; -+ e->u.expr.left = l; -+ e->u.expr.op = op; -+ e->u.expr.right = r; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_column( void *info, column_info *column ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_COLUMN; -+ e->u.sval = column->column; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_ival( void *info, int val ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_IVAL; -+ e->u.ival = val; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_sval( void *info, struct sql_str *str ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_SVAL; -+ e->u.sval = SQL_getstring( info, str ); -+ } -+ return e; -+} -+ -+static BOOL SQL_MarkPrimaryKeys( column_info *cols, -+ column_info *keys ) -+{ -+ column_info *k; -+ BOOL found = TRUE; -+ -+ for( k = keys; k && found; k = k->next ) -+ { -+ column_info *c; -+ -+ found = FALSE; -+ for( c = cols; c && !found; c = c->next ) -+ { -+ if( lstrcmpW( k->column, c->column ) ) -+ continue; -+ c->type |= MSITYPE_KEY; -+ found = TRUE; -+ } -+ } -+ -+ return found; -+} -+ -+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, -+ struct list *mem ) -+{ -+ SQL_input sql; -+ int r; -+ -+ *phview = NULL; -+ -+ sql.db = db; -+ sql.command = command; -+ sql.n = 0; -+ sql.len = 0; -+ sql.view = phview; -+ sql.mem = mem; -+ -+ r = SQL_parse(&sql); -+ -+ TRACE("Parse returned %d\n", r); -+ if( r ) -+ { -+ *sql.view = NULL; -+ return ERROR_BAD_QUERY_SYNTAX; -+ } -+ -+ return ERROR_SUCCESS; -+} -+ ++/* A Bison parser, made by GNU Bison 1.875c. */ ++ ++/* Skeleton parser for Yacc-like parsing with Bison, ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++ 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, 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., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ ++ ++/* Written by Richard Stallman by simplifying the original so called ++ ``semantic'' parser. */ ++ ++/* All symbols defined below should begin with yy or YY, to avoid ++ infringing on user name space. This should be done even for local ++ variables, as they might otherwise be expanded by user macros. ++ There are some unavoidable exceptions within include files to ++ define necessary library symbols; they are noted "INFRINGES ON ++ USER NAME SPACE" below. */ ++ ++/* Identify Bison output. */ ++#define YYBISON 1 ++ ++/* Skeleton name. */ ++#define YYSKELETON_NAME "yacc.c" ++ ++/* Pure parsers. */ ++#define YYPURE 1 ++ ++/* Using locations. */ ++#define YYLSP_NEEDED 0 ++ ++/* If NAME_PREFIX is specified substitute the variables and functions ++ names. */ ++#define yyparse SQL_parse ++#define yylex SQL_lex ++#define yyerror SQL_error ++#define yylval SQL_lval ++#define yychar SQL_char ++#define yydebug SQL_debug ++#define yynerrs SQL_nerrs ++ ++ ++/* Tokens. */ ++#ifndef YYTOKENTYPE ++# define YYTOKENTYPE ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ TK_ABORT = 258, ++ TK_AFTER = 259, ++ TK_AGG_FUNCTION = 260, ++ TK_ALL = 261, ++ TK_AND = 262, ++ TK_AS = 263, ++ TK_ASC = 264, ++ TK_BEFORE = 265, ++ TK_BEGIN = 266, ++ TK_BETWEEN = 267, ++ TK_BITAND = 268, ++ TK_BITNOT = 269, ++ TK_BITOR = 270, ++ TK_BY = 271, ++ TK_CASCADE = 272, ++ TK_CASE = 273, ++ TK_CHAR = 274, ++ TK_CHECK = 275, ++ TK_CLUSTER = 276, ++ TK_COLLATE = 277, ++ TK_COLUMN = 278, ++ TK_COMMA = 279, ++ TK_COMMENT = 280, ++ TK_COMMIT = 281, ++ TK_CONCAT = 282, ++ TK_CONFLICT = 283, ++ TK_CONSTRAINT = 284, ++ TK_COPY = 285, ++ TK_CREATE = 286, ++ TK_DEFAULT = 287, ++ TK_DEFERRABLE = 288, ++ TK_DEFERRED = 289, ++ TK_DELETE = 290, ++ TK_DELIMITERS = 291, ++ TK_DESC = 292, ++ TK_DISTINCT = 293, ++ TK_DOT = 294, ++ TK_DROP = 295, ++ TK_EACH = 296, ++ TK_ELSE = 297, ++ TK_END = 298, ++ TK_END_OF_FILE = 299, ++ TK_EQ = 300, ++ TK_EXCEPT = 301, ++ TK_EXPLAIN = 302, ++ TK_FAIL = 303, ++ TK_FLOAT = 304, ++ TK_FOR = 305, ++ TK_FOREIGN = 306, ++ TK_FROM = 307, ++ TK_FUNCTION = 308, ++ TK_GE = 309, ++ TK_GLOB = 310, ++ TK_GROUP = 311, ++ TK_GT = 312, ++ TK_HAVING = 313, ++ TK_HOLD = 314, ++ TK_IGNORE = 315, ++ TK_ILLEGAL = 316, ++ TK_IMMEDIATE = 317, ++ TK_IN = 318, ++ TK_INDEX = 319, ++ TK_INITIALLY = 320, ++ TK_ID = 321, ++ TK_INSERT = 322, ++ TK_INSTEAD = 323, ++ TK_INT = 324, ++ TK_INTEGER = 325, ++ TK_INTERSECT = 326, ++ TK_INTO = 327, ++ TK_IS = 328, ++ TK_ISNULL = 329, ++ TK_JOIN = 330, ++ TK_JOIN_KW = 331, ++ TK_KEY = 332, ++ TK_LE = 333, ++ TK_LIKE = 334, ++ TK_LIMIT = 335, ++ TK_LONG = 336, ++ TK_LONGCHAR = 337, ++ TK_LP = 338, ++ TK_LSHIFT = 339, ++ TK_LT = 340, ++ TK_LOCALIZABLE = 341, ++ TK_MATCH = 342, ++ TK_MINUS = 343, ++ TK_NE = 344, ++ TK_NOT = 345, ++ TK_NOTNULL = 346, ++ TK_NULL = 347, ++ TK_OBJECT = 348, ++ TK_OF = 349, ++ TK_OFFSET = 350, ++ TK_ON = 351, ++ TK_OR = 352, ++ TK_ORACLE_OUTER_JOIN = 353, ++ TK_ORDER = 354, ++ TK_PLUS = 355, ++ TK_PRAGMA = 356, ++ TK_PRIMARY = 357, ++ TK_RAISE = 358, ++ TK_REFERENCES = 359, ++ TK_REM = 360, ++ TK_REPLACE = 361, ++ TK_RESTRICT = 362, ++ TK_ROLLBACK = 363, ++ TK_ROW = 364, ++ TK_RP = 365, ++ TK_RSHIFT = 366, ++ TK_SELECT = 367, ++ TK_SEMI = 368, ++ TK_SET = 369, ++ TK_SHORT = 370, ++ TK_SLASH = 371, ++ TK_SPACE = 372, ++ TK_STAR = 373, ++ TK_STATEMENT = 374, ++ TK_STRING = 375, ++ TK_TABLE = 376, ++ TK_TEMP = 377, ++ TK_THEN = 378, ++ TK_TRANSACTION = 379, ++ TK_TRIGGER = 380, ++ TK_UMINUS = 381, ++ TK_UNCLOSED_STRING = 382, ++ TK_UNION = 383, ++ TK_UNIQUE = 384, ++ TK_UPDATE = 385, ++ TK_UPLUS = 386, ++ TK_USING = 387, ++ TK_VACUUM = 388, ++ TK_VALUES = 389, ++ TK_VIEW = 390, ++ TK_WHEN = 391, ++ TK_WHERE = 392, ++ TK_WILDCARD = 393, ++ COLUMN = 395, ++ FUNCTION = 396, ++ COMMENT = 397, ++ UNCLOSED_STRING = 398, ++ SPACE = 399, ++ ILLEGAL = 400, ++ END_OF_FILE = 401 ++ }; ++#endif ++#define TK_ABORT 258 ++#define TK_AFTER 259 ++#define TK_AGG_FUNCTION 260 ++#define TK_ALL 261 ++#define TK_AND 262 ++#define TK_AS 263 ++#define TK_ASC 264 ++#define TK_BEFORE 265 ++#define TK_BEGIN 266 ++#define TK_BETWEEN 267 ++#define TK_BITAND 268 ++#define TK_BITNOT 269 ++#define TK_BITOR 270 ++#define TK_BY 271 ++#define TK_CASCADE 272 ++#define TK_CASE 273 ++#define TK_CHAR 274 ++#define TK_CHECK 275 ++#define TK_CLUSTER 276 ++#define TK_COLLATE 277 ++#define TK_COLUMN 278 ++#define TK_COMMA 279 ++#define TK_COMMENT 280 ++#define TK_COMMIT 281 ++#define TK_CONCAT 282 ++#define TK_CONFLICT 283 ++#define TK_CONSTRAINT 284 ++#define TK_COPY 285 ++#define TK_CREATE 286 ++#define TK_DEFAULT 287 ++#define TK_DEFERRABLE 288 ++#define TK_DEFERRED 289 ++#define TK_DELETE 290 ++#define TK_DELIMITERS 291 ++#define TK_DESC 292 ++#define TK_DISTINCT 293 ++#define TK_DOT 294 ++#define TK_DROP 295 ++#define TK_EACH 296 ++#define TK_ELSE 297 ++#define TK_END 298 ++#define TK_END_OF_FILE 299 ++#define TK_EQ 300 ++#define TK_EXCEPT 301 ++#define TK_EXPLAIN 302 ++#define TK_FAIL 303 ++#define TK_FLOAT 304 ++#define TK_FOR 305 ++#define TK_FOREIGN 306 ++#define TK_FROM 307 ++#define TK_FUNCTION 308 ++#define TK_GE 309 ++#define TK_GLOB 310 ++#define TK_GROUP 311 ++#define TK_GT 312 ++#define TK_HAVING 313 ++#define TK_HOLD 314 ++#define TK_IGNORE 315 ++#define TK_ILLEGAL 316 ++#define TK_IMMEDIATE 317 ++#define TK_IN 318 ++#define TK_INDEX 319 ++#define TK_INITIALLY 320 ++#define TK_ID 321 ++#define TK_INSERT 322 ++#define TK_INSTEAD 323 ++#define TK_INT 324 ++#define TK_INTEGER 325 ++#define TK_INTERSECT 326 ++#define TK_INTO 327 ++#define TK_IS 328 ++#define TK_ISNULL 329 ++#define TK_JOIN 330 ++#define TK_JOIN_KW 331 ++#define TK_KEY 332 ++#define TK_LE 333 ++#define TK_LIKE 334 ++#define TK_LIMIT 335 ++#define TK_LONG 336 ++#define TK_LONGCHAR 337 ++#define TK_LP 338 ++#define TK_LSHIFT 339 ++#define TK_LT 340 ++#define TK_LOCALIZABLE 341 ++#define TK_MATCH 342 ++#define TK_MINUS 343 ++#define TK_NE 344 ++#define TK_NOT 345 ++#define TK_NOTNULL 346 ++#define TK_NULL 347 ++#define TK_OBJECT 348 ++#define TK_OF 349 ++#define TK_OFFSET 350 ++#define TK_ON 351 ++#define TK_OR 352 ++#define TK_ORACLE_OUTER_JOIN 353 ++#define TK_ORDER 354 ++#define TK_PLUS 355 ++#define TK_PRAGMA 356 ++#define TK_PRIMARY 357 ++#define TK_RAISE 358 ++#define TK_REFERENCES 359 ++#define TK_REM 360 ++#define TK_REPLACE 361 ++#define TK_RESTRICT 362 ++#define TK_ROLLBACK 363 ++#define TK_ROW 364 ++#define TK_RP 365 ++#define TK_RSHIFT 366 ++#define TK_SELECT 367 ++#define TK_SEMI 368 ++#define TK_SET 369 ++#define TK_SHORT 370 ++#define TK_SLASH 371 ++#define TK_SPACE 372 ++#define TK_STAR 373 ++#define TK_STATEMENT 374 ++#define TK_STRING 375 ++#define TK_TABLE 376 ++#define TK_TEMP 377 ++#define TK_THEN 378 ++#define TK_TRANSACTION 379 ++#define TK_TRIGGER 380 ++#define TK_UMINUS 381 ++#define TK_UNCLOSED_STRING 382 ++#define TK_UNION 383 ++#define TK_UNIQUE 384 ++#define TK_UPDATE 385 ++#define TK_UPLUS 386 ++#define TK_USING 387 ++#define TK_VACUUM 388 ++#define TK_VALUES 389 ++#define TK_VIEW 390 ++#define TK_WHEN 391 ++#define TK_WHERE 392 ++#define TK_WILDCARD 393 ++#define COLUMN 395 ++#define FUNCTION 396 ++#define COMMENT 397 ++#define UNCLOSED_STRING 398 ++#define SPACE 399 ++#define ILLEGAL 400 ++#define END_OF_FILE 401 ++ ++ ++ ++ ++/* Copy the first part of user declarations. */ ++#line 1 "./sql.y" ++ ++ ++/* ++ * Implementation of the Microsoft Installer (msi.dll) ++ * ++ * Copyright 2002-2004 Mike McCormack for CodeWeavers ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "query.h" ++#include "wine/list.h" ++#include "wine/debug.h" ++ ++#define YYLEX_PARAM info ++#define YYPARSE_PARAM info ++ ++extern int SQL_error(const char *str); ++ ++WINE_DEFAULT_DEBUG_CHANNEL(msi); ++ ++typedef struct tag_SQL_input ++{ ++ MSIDATABASE *db; ++ LPCWSTR command; ++ DWORD n, len; ++ MSIVIEW **view; /* view structure for the resulting query */ ++ struct list *mem; ++} SQL_input; ++ ++static LPWSTR SQL_getstring( void *info, struct sql_str *str ); ++static INT SQL_getint( void *info ); ++static int SQL_lex( void *SQL_lval, SQL_input *info ); ++ ++static void *parser_alloc( void *info, unsigned int sz ); ++static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ); ++ ++static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys); ++ ++static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ); ++static struct expr * EXPR_column( void *info, column_info *column ); ++static struct expr * EXPR_ival( void *info, int val ); ++static struct expr * EXPR_sval( void *info, struct sql_str * ); ++static struct expr * EXPR_wildcard( void *info ); ++ ++ ++ ++/* Enabling traces. */ ++#ifndef YYDEBUG ++# define YYDEBUG 0 ++#endif ++ ++/* Enabling verbose error messages. */ ++#ifdef YYERROR_VERBOSE ++# undef YYERROR_VERBOSE ++# define YYERROR_VERBOSE 1 ++#else ++# define YYERROR_VERBOSE 0 ++#endif ++ ++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) ++#line 72 "./sql.y" ++typedef union YYSTYPE { ++ struct sql_str str; ++ LPWSTR string; ++ column_info *column_list; ++ MSIVIEW *query; ++ struct expr *expr; ++ USHORT column_type; ++ int integer; ++} YYSTYPE; ++/* Line 191 of yacc.c. */ ++#line 453 "sql.tab.c" ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ ++# define YYSTYPE_IS_DECLARED 1 ++# define YYSTYPE_IS_TRIVIAL 1 ++#endif ++ ++ ++ ++/* Copy the second part of user declarations. */ ++ ++ ++/* Line 214 of yacc.c. */ ++#line 465 "sql.tab.c" ++ ++#if ! defined (yyoverflow) || YYERROR_VERBOSE ++ ++# ifndef YYFREE ++# define YYFREE free ++# endif ++# ifndef YYMALLOC ++# define YYMALLOC malloc ++# endif ++ ++/* The parser invokes alloca or malloc; define the necessary symbols. */ ++ ++# ifdef YYSTACK_USE_ALLOCA ++# if YYSTACK_USE_ALLOCA ++# define YYSTACK_ALLOC alloca ++# endif ++# else ++# if defined (alloca) || defined (_ALLOCA_H) ++# define YYSTACK_ALLOC alloca ++# else ++# ifdef __GNUC__ ++# define YYSTACK_ALLOC __builtin_alloca ++# endif ++# endif ++# endif ++ ++# ifdef YYSTACK_ALLOC ++ /* Pacify GCC's `empty if-body' warning. */ ++# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) ++# else ++# if defined (__STDC__) || defined (__cplusplus) ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYSIZE_T size_t ++# endif ++# define YYSTACK_ALLOC YYMALLOC ++# define YYSTACK_FREE YYFREE ++# endif ++#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ ++ ++ ++#if (! defined (yyoverflow) \ ++ && (! defined (__cplusplus) \ ++ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) ++ ++/* A type that is properly aligned for any stack member. */ ++union yyalloc ++{ ++ short yyss; ++ YYSTYPE yyvs; ++ }; ++ ++/* The size of the maximum gap between one aligned stack and the next. */ ++# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) ++ ++/* The size of an array large to enough to hold all stacks, each with ++ N elements. */ ++# define YYSTACK_BYTES(N) \ ++ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ ++ + YYSTACK_GAP_MAXIMUM) ++ ++/* Copy COUNT objects from FROM to TO. The source and destination do ++ not overlap. */ ++# ifndef YYCOPY ++# if defined (__GNUC__) && 1 < __GNUC__ ++# define YYCOPY(To, From, Count) \ ++ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) ++# else ++# define YYCOPY(To, From, Count) \ ++ do \ ++ { \ ++ register YYSIZE_T yyi; \ ++ for (yyi = 0; yyi < (Count); yyi++) \ ++ (To)[yyi] = (From)[yyi]; \ ++ } \ ++ while (0) ++# endif ++# endif ++ ++/* Relocate STACK from its old location to the new one. The ++ local variables YYSIZE and YYSTACKSIZE give the old and new number of ++ elements in the stack, and YYPTR gives the new location of the ++ stack. Advance YYPTR to a properly aligned location for the next ++ stack. */ ++# define YYSTACK_RELOCATE(Stack) \ ++ do \ ++ { \ ++ YYSIZE_T yynewbytes; \ ++ YYCOPY (&yyptr->Stack, Stack, yysize); \ ++ Stack = &yyptr->Stack; \ ++ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ ++ yyptr += yynewbytes / sizeof (*yyptr); \ ++ } \ ++ while (0) ++ ++#endif ++ ++#if defined (__STDC__) || defined (__cplusplus) ++ typedef signed char yysigned_char; ++#else ++ typedef short yysigned_char; ++#endif ++ ++/* YYFINAL -- State number of the termination state. */ ++#define YYFINAL 29 ++/* YYLAST -- Last index in YYTABLE. */ ++#define YYLAST 124 ++ ++/* YYNTOKENS -- Number of terminals. */ ++#define YYNTOKENS 147 ++/* YYNNTS -- Number of nonterminals. */ ++#define YYNNTS 31 ++/* YYNRULES -- Number of rules. */ ++#define YYNRULES 69 ++/* YYNRULES -- Number of states. */ ++#define YYNSTATES 127 ++ ++/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ ++#define YYUNDEFTOK 2 ++#define YYMAXUTOK 401 ++ ++#define YYTRANSLATE(YYX) \ ++ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) ++ ++/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ ++static const unsigned char yytranslate[] = ++{ ++ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, ++ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ++ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, ++ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, ++ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, ++ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, ++ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, ++ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, ++ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, ++ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, ++ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, ++ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, ++ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, ++ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, ++ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, ++ 145, 146 ++}; ++ ++#if YYDEBUG ++/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in ++ YYRHS. */ ++static const unsigned char yyprhs[] = ++{ ++ 0, 0, 3, 5, 7, 9, 11, 13, 15, 26, ++ 38, 45, 53, 60, 63, 68, 72, 74, 77, 79, ++ 82, 84, 88, 90, 95, 97, 99, 101, 103, 105, ++ 107, 112, 114, 117, 121, 124, 126, 130, 132, 134, ++ 138, 141, 145, 149, 153, 157, 161, 165, 169, 173, ++ 177, 181, 185, 190, 192, 194, 196, 200, 202, 206, ++ 210, 212, 215, 217, 219, 221, 225, 227, 229, 231 ++}; ++ ++/* YYRHS -- A `-1'-separated list of the rules' RHS. */ ++static const short yyrhs[] = ++{ ++ 148, 0, -1, 149, -1, 161, -1, 151, -1, 150, ++ -1, 152, -1, 153, -1, 67, 72, 175, 83, 164, ++ 110, 134, 83, 169, 110, -1, 67, 72, 175, 83, ++ 164, 110, 134, 83, 169, 110, 122, -1, 31, 121, ++ 175, 83, 154, 110, -1, 31, 121, 175, 83, 154, ++ 110, 59, -1, 130, 175, 114, 170, 137, 167, -1, ++ 35, 165, -1, 155, 102, 77, 164, -1, 155, 24, ++ 156, -1, 156, -1, 174, 157, -1, 158, -1, 158, ++ 86, -1, 159, -1, 159, 90, 92, -1, 19, -1, ++ 19, 83, 160, 110, -1, 82, -1, 115, -1, 69, ++ -1, 81, -1, 93, -1, 177, -1, 162, 99, 16, ++ 164, -1, 162, -1, 112, 163, -1, 112, 38, 163, ++ -1, 164, 165, -1, 174, -1, 174, 24, 164, -1, ++ 118, -1, 166, -1, 166, 137, 167, -1, 52, 175, ++ -1, 83, 167, 110, -1, 173, 45, 173, -1, 167, ++ 7, 167, -1, 167, 97, 167, -1, 173, 45, 168, ++ -1, 173, 57, 168, -1, 173, 85, 168, -1, 173, ++ 78, 168, -1, 173, 54, 168, -1, 173, 89, 168, ++ -1, 173, 73, 92, -1, 173, 73, 90, 92, -1, ++ 173, -1, 172, -1, 172, -1, 172, 24, 169, -1, ++ 171, -1, 171, 24, 170, -1, 174, 45, 172, -1, ++ 177, -1, 88, 177, -1, 120, -1, 138, -1, 174, ++ -1, 175, 39, 176, -1, 176, -1, 176, -1, 66, ++ -1, 70, -1 ++}; ++ ++/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ ++static const unsigned short yyrline[] = ++{ ++ 0, 138, 138, 146, 147, 148, 149, 150, 154, 165, ++ 178, 190, 205, 218, 231, 241, 251, 258, 266, 270, ++ 277, 281, 288, 292, 296, 300, 304, 308, 312, 319, ++ 328, 340, 344, 348, 364, 385, 386, 390, 397, 398, ++ 414, 427, 433, 439, 445, 451, 457, 463, 469, 475, ++ 481, 487, 493, 502, 503, 507, 514, 525, 526, 534, ++ 542, 548, 554, 560, 569, 578, 584, 593, 600, 609 ++}; ++#endif ++ ++#if YYDEBUG || YYERROR_VERBOSE ++/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. ++ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ ++static const char *const yytname[] = ++{ ++ "$end", "error", "$undefined", "TK_ABORT", "TK_AFTER", ++ "TK_AGG_FUNCTION", "TK_ALL", "TK_AND", "TK_AS", "TK_ASC", "TK_BEFORE", ++ "TK_BEGIN", "TK_BETWEEN", "TK_BITAND", "TK_BITNOT", "TK_BITOR", "TK_BY", ++ "TK_CASCADE", "TK_CASE", "TK_CHAR", "TK_CHECK", "TK_CLUSTER", ++ "TK_COLLATE", "TK_COLUMN", "TK_COMMA", "TK_COMMENT", "TK_COMMIT", ++ "TK_CONCAT", "TK_CONFLICT", "TK_CONSTRAINT", "TK_COPY", "TK_CREATE", ++ "TK_DEFAULT", "TK_DEFERRABLE", "TK_DEFERRED", "TK_DELETE", ++ "TK_DELIMITERS", "TK_DESC", "TK_DISTINCT", "TK_DOT", "TK_DROP", ++ "TK_EACH", "TK_ELSE", "TK_END", "TK_END_OF_FILE", "TK_EQ", "TK_EXCEPT", ++ "TK_EXPLAIN", "TK_FAIL", "TK_FLOAT", "TK_FOR", "TK_FOREIGN", "TK_FROM", ++ "TK_FUNCTION", "TK_GE", "TK_GLOB", "TK_GROUP", "TK_GT", "TK_HAVING", ++ "TK_HOLD", "TK_IGNORE", "TK_ILLEGAL", "TK_IMMEDIATE", "TK_IN", ++ "TK_INDEX", "TK_INITIALLY", "TK_ID", "TK_INSERT", "TK_INSTEAD", "TK_INT", ++ "TK_INTEGER", "TK_INTERSECT", "TK_INTO", "TK_IS", "TK_ISNULL", "TK_JOIN", ++ "TK_JOIN_KW", "TK_KEY", "TK_LE", "TK_LIKE", "TK_LIMIT", "TK_LONG", ++ "TK_LONGCHAR", "TK_LP", "TK_LSHIFT", "TK_LT", "TK_LOCALIZABLE", ++ "TK_MATCH", "TK_MINUS", "TK_NE", "TK_NOT", "TK_NOTNULL", "TK_NULL", ++ "TK_OBJECT", "TK_OF", "TK_OFFSET", "TK_ON", "TK_OR", ++ "TK_ORACLE_OUTER_JOIN", "TK_ORDER", "TK_PLUS", "TK_PRAGMA", "TK_PRIMARY", ++ "TK_RAISE", "TK_REFERENCES", "TK_REM", "TK_REPLACE", "TK_RESTRICT", ++ "TK_ROLLBACK", "TK_ROW", "TK_RP", "TK_RSHIFT", "TK_SELECT", "TK_SEMI", ++ "TK_SET", "TK_SHORT", "TK_SLASH", "TK_SPACE", "TK_STAR", "TK_STATEMENT", ++ "TK_STRING", "TK_TABLE", "TK_TEMP", "TK_THEN", "TK_TRANSACTION", ++ "TK_TRIGGER", "TK_UMINUS", "TK_UNCLOSED_STRING", "TK_UNION", "TK_UNIQUE", ++ "TK_UPDATE", "TK_UPLUS", "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW", ++ "TK_WHEN", "TK_WHERE", "TK_WILDCARD", "AGG_FUNCTION.", "COLUMN", ++ "FUNCTION", "COMMENT", "UNCLOSED_STRING", "SPACE", "ILLEGAL", ++ "END_OF_FILE", "$accept", "query", "onequery", "oneinsert", "onecreate", ++ "oneupdate", "onedelete", "table_def", "column_def", "column_and_type", ++ "column_type", "data_type_l", "data_type", "data_count", "oneselect", ++ "unorderedsel", "selectfrom", "selcollist", "from", "fromtable", "expr", ++ "val", "constlist", "update_assign_list", "column_assignment", ++ "const_val", "column_val", "column", "table", "id", "number", 0 ++}; ++#endif ++ ++# ifdef YYPRINT ++/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to ++ token YYLEX-NUM. */ ++static const unsigned short yytoknum[] = ++{ ++ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, ++ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, ++ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, ++ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, ++ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, ++ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, ++ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, ++ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, ++ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, ++ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, ++ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, ++ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, ++ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, ++ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, ++ 395, 396, 397, 398, 399, 400, 401 ++}; ++# endif ++ ++/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ ++static const unsigned char yyr1[] = ++{ ++ 0, 147, 148, 149, 149, 149, 149, 149, 150, 150, ++ 151, 151, 152, 153, 154, 155, 155, 156, 157, 157, ++ 158, 158, 159, 159, 159, 159, 159, 159, 159, 160, ++ 161, 161, 162, 162, 163, 164, 164, 164, 165, 165, ++ 166, 167, 167, 167, 167, 167, 167, 167, 167, 167, ++ 167, 167, 167, 168, 168, 169, 169, 170, 170, 171, ++ 172, 172, 172, 172, 173, 174, 174, 175, 176, 177 ++}; ++ ++/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ ++static const unsigned char yyr2[] = ++{ ++ 0, 2, 1, 1, 1, 1, 1, 1, 10, 11, ++ 6, 7, 6, 2, 4, 3, 1, 2, 1, 2, ++ 1, 3, 1, 4, 1, 1, 1, 1, 1, 1, ++ 4, 1, 2, 3, 2, 1, 3, 1, 1, 3, ++ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, ++ 3, 3, 4, 1, 1, 1, 3, 1, 3, 3, ++ 1, 2, 1, 1, 1, 3, 1, 1, 1, 1 ++}; ++ ++/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state ++ STATE-NUM when YYTABLE doesn't specify something else to do. Zero ++ means the default is an error. */ ++static const unsigned char yydefact[] = ++{ ++ 0, 0, 0, 0, 0, 0, 0, 2, 5, 4, ++ 6, 7, 3, 31, 0, 0, 13, 38, 0, 0, ++ 68, 37, 32, 0, 35, 0, 66, 0, 67, 1, ++ 0, 0, 40, 0, 0, 33, 34, 0, 0, 0, ++ 0, 0, 0, 39, 0, 64, 0, 36, 65, 0, ++ 57, 0, 30, 0, 0, 16, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 10, 0, 0, 22, 26, 27, 24, 28, 25, ++ 17, 18, 20, 41, 43, 44, 69, 0, 62, 63, ++ 45, 54, 42, 60, 49, 53, 46, 0, 51, 48, ++ 47, 50, 0, 12, 58, 59, 11, 15, 0, 0, ++ 19, 0, 61, 52, 0, 14, 0, 29, 21, 0, ++ 23, 0, 55, 8, 0, 9, 56 ++}; ++ ++/* YYDEFGOTO[NTERM-NUM]. */ ++static const yysigned_char yydefgoto[] = ++{ ++ -1, 6, 7, 8, 9, 10, 11, 53, 54, 55, ++ 80, 81, 82, 116, 12, 13, 22, 23, 16, 17, ++ 43, 90, 121, 49, 50, 91, 44, 45, 25, 26, ++ 93 ++}; ++ ++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ ++#define YYPACT_NINF -111 ++static const yysigned_char yypact[] = ++{ ++ -28, -110, -38, -46, -32, -42, 29, -111, -111, -111, ++ -111, -111, -111, -67, -42, -42, -111, -99, -42, -48, ++ -111, -111, -111, -38, 17, 7, 11, -62, -111, -111, ++ 37, -22, -111, -43, -16, -111, -111, -48, -42, -42, ++ -48, -42, -43, -3, -29, -111, -48, -111, -111, -68, ++ 48, 28, -111, -36, -19, -111, -18, -5, -43, -43, ++ -58, -58, -58, -70, -58, -58, -58, -34, -43, -42, ++ -61, 20, -42, 5, 2, -111, -111, -111, -111, -111, ++ -111, 1, -2, -111, -3, -3, -111, 19, -111, -111, ++ -111, -111, -111, -111, -111, -111, -111, -1, -111, -111, ++ -111, -111, -41, -3, -111, -111, -111, -111, -48, 19, ++ -111, 3, -111, -111, 13, -111, -12, -111, -111, -61, ++ -111, -9, 91, -13, -61, -111, -111 ++}; ++ ++/* YYPGOTO[NTERM-NUM]. */ ++static const yysigned_char yypgoto[] = ++{ ++ -111, -111, -111, -111, -111, -111, -111, -111, -111, 47, ++ -111, -111, -111, -111, -111, -111, 101, -27, 98, -111, ++ -11, 52, 0, 53, -111, -53, 46, -4, 85, 40, ++ -66 ++}; ++ ++/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule which ++ number is the opposite. If zero, do what YYDEFACT says. ++ If YYTABLE_NINF, syntax error. */ ++#define YYTABLE_NINF -68 ++static const yysigned_char yytable[] = ++{ ++ 24, 74, 58, 1, 58, 72, 19, 2, 20, 86, ++ 47, 14, 86, 52, 15, 24, 60, 105, 20, 67, ++ 97, 112, 98, 20, 20, 61, 18, 87, 62, 29, ++ 87, 57, 30, 24, 20, 51, 24, 56, 33, 3, ++ 42, 37, 24, 117, 63, 28, 38, 84, 85, 64, ++ -67, 75, 39, 40, 28, 28, 65, 103, 28, 88, ++ 66, 41, 88, 76, 77, 51, 122, 46, 56, 68, ++ 21, 122, 69, 70, 71, 78, 102, 89, 48, 106, ++ 89, 115, 108, 73, 4, 109, 21, 110, 111, 86, ++ 27, 113, 59, 114, 59, 118, 119, 79, 120, 31, ++ 32, 123, 5, 34, 24, 83, 92, 95, 95, 125, ++ 95, 95, 95, 94, 96, 124, 99, 100, 101, 107, ++ 35, 36, 104, 0, 126 ++}; ++ ++static const short yycheck[] = ++{ ++ 4, 19, 7, 31, 7, 24, 38, 35, 66, 70, ++ 37, 121, 70, 40, 52, 19, 45, 70, 66, 46, ++ 90, 87, 92, 66, 66, 54, 72, 88, 57, 0, ++ 88, 42, 99, 37, 66, 39, 40, 41, 137, 67, ++ 83, 24, 46, 109, 73, 5, 39, 58, 59, 78, ++ 39, 69, 114, 16, 14, 15, 85, 68, 18, 120, ++ 89, 83, 120, 81, 82, 69, 119, 83, 72, 137, ++ 118, 124, 24, 45, 110, 93, 110, 138, 38, 59, ++ 138, 108, 77, 102, 112, 83, 118, 86, 90, 70, ++ 5, 92, 97, 134, 97, 92, 83, 115, 110, 14, ++ 15, 110, 130, 18, 108, 110, 60, 61, 62, 122, ++ 64, 65, 66, 61, 62, 24, 64, 65, 66, 72, ++ 19, 23, 69, -1, 124 ++}; ++ ++/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing ++ symbol of state STATE-NUM. */ ++static const unsigned char yystos[] = ++{ ++ 0, 31, 35, 67, 112, 130, 148, 149, 150, 151, ++ 152, 153, 161, 162, 121, 52, 165, 166, 72, 38, ++ 66, 118, 163, 164, 174, 175, 176, 175, 176, 0, ++ 99, 175, 175, 137, 175, 163, 165, 24, 39, 114, ++ 16, 83, 83, 167, 173, 174, 83, 164, 176, 170, ++ 171, 174, 164, 154, 155, 156, 174, 167, 7, 97, ++ 45, 54, 57, 73, 78, 85, 89, 164, 137, 24, ++ 45, 110, 24, 102, 19, 69, 81, 82, 93, 115, ++ 157, 158, 159, 110, 167, 167, 70, 88, 120, 138, ++ 168, 172, 173, 177, 168, 173, 168, 90, 92, 168, ++ 168, 168, 110, 167, 170, 172, 59, 156, 77, 83, ++ 86, 90, 177, 92, 134, 164, 160, 177, 92, 83, ++ 110, 169, 172, 110, 24, 122, 169 ++}; ++ ++#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) ++# define YYSIZE_T __SIZE_TYPE__ ++#endif ++#if ! defined (YYSIZE_T) && defined (size_t) ++# define YYSIZE_T size_t ++#endif ++#if ! defined (YYSIZE_T) ++# if defined (__STDC__) || defined (__cplusplus) ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYSIZE_T size_t ++# endif ++#endif ++#if ! defined (YYSIZE_T) ++# define YYSIZE_T unsigned int ++#endif ++ ++#define yyerrok (yyerrstatus = 0) ++#define yyclearin (yychar = YYEMPTY) ++#define YYEMPTY (-2) ++#define YYEOF 0 ++ ++#define YYACCEPT goto yyacceptlab ++#define YYABORT goto yyabortlab ++#define YYERROR goto yyerrorlab ++ ++ ++/* Like YYERROR except do call yyerror. This remains here temporarily ++ to ease the transition to the new meaning of YYERROR, for GCC. ++ Once GCC version 2 has supplanted version 1, this can go. */ ++ ++#define YYFAIL goto yyerrlab ++ ++#define YYRECOVERING() (!!yyerrstatus) ++ ++#define YYBACKUP(Token, Value) \ ++do \ ++ if (yychar == YYEMPTY && yylen == 1) \ ++ { \ ++ yychar = (Token); \ ++ yylval = (Value); \ ++ yytoken = YYTRANSLATE (yychar); \ ++ YYPOPSTACK; \ ++ goto yybackup; \ ++ } \ ++ else \ ++ { \ ++ yyerror ("syntax error: cannot back up");\ ++ YYERROR; \ ++ } \ ++while (0) ++ ++#define YYTERROR 1 ++#define YYERRCODE 256 ++ ++/* YYLLOC_DEFAULT -- Compute the default location (before the actions ++ are run). */ ++ ++#ifndef YYLLOC_DEFAULT ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ ((Current).first_line = (Rhs)[1].first_line, \ ++ (Current).first_column = (Rhs)[1].first_column, \ ++ (Current).last_line = (Rhs)[N].last_line, \ ++ (Current).last_column = (Rhs)[N].last_column) ++#endif ++ ++/* YYLEX -- calling `yylex' with the right arguments. */ ++ ++#ifdef YYLEX_PARAM ++# define YYLEX yylex (&yylval, YYLEX_PARAM) ++#else ++# define YYLEX yylex (&yylval) ++#endif ++ ++/* Enable debugging if requested. */ ++#if YYDEBUG ++ ++# ifndef YYFPRINTF ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYFPRINTF fprintf ++# endif ++ ++# define YYDPRINTF(Args) \ ++do { \ ++ if (yydebug) \ ++ YYFPRINTF Args; \ ++} while (0) ++ ++# define YYDSYMPRINT(Args) \ ++do { \ ++ if (yydebug) \ ++ yysymprint Args; \ ++} while (0) ++ ++# define YYDSYMPRINTF(Title, Token, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yysymprint (stderr, \ ++ Token, Value); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (0) ++ ++/*------------------------------------------------------------------. ++| yy_stack_print -- Print the state stack from its BOTTOM up to its | ++| TOP (included). | ++`------------------------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_stack_print (short *bottom, short *top) ++#else ++static void ++yy_stack_print (bottom, top) ++ short *bottom; ++ short *top; ++#endif ++{ ++ YYFPRINTF (stderr, "Stack now"); ++ for (/* Nothing. */; bottom <= top; ++bottom) ++ YYFPRINTF (stderr, " %d", *bottom); ++ YYFPRINTF (stderr, "\n"); ++} ++ ++# define YY_STACK_PRINT(Bottom, Top) \ ++do { \ ++ if (yydebug) \ ++ yy_stack_print ((Bottom), (Top)); \ ++} while (0) ++ ++ ++/*------------------------------------------------. ++| Report that the YYRULE is going to be reduced. | ++`------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_reduce_print (int yyrule) ++#else ++static void ++yy_reduce_print (yyrule) ++ int yyrule; ++#endif ++{ ++ int yyi; ++ unsigned int yylno = yyrline[yyrule]; ++ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", ++ yyrule - 1, yylno); ++ /* Print the symbols being reduced, and their result. */ ++ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) ++ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); ++ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); ++} ++ ++# define YY_REDUCE_PRINT(Rule) \ ++do { \ ++ if (yydebug) \ ++ yy_reduce_print (Rule); \ ++} while (0) ++ ++/* Nonzero means print parse trace. It is left uninitialized so that ++ multiple parsers can coexist. */ ++int yydebug; ++#else /* !YYDEBUG */ ++# define YYDPRINTF(Args) ++# define YYDSYMPRINT(Args) ++# define YYDSYMPRINTF(Title, Token, Value, Location) ++# define YY_STACK_PRINT(Bottom, Top) ++# define YY_REDUCE_PRINT(Rule) ++#endif /* !YYDEBUG */ ++ ++ ++/* YYINITDEPTH -- initial size of the parser's stacks. */ ++#ifndef YYINITDEPTH ++# define YYINITDEPTH 200 ++#endif ++ ++/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only ++ if the built-in stack extension method is used). ++ ++ Do not make this value too large; the results are undefined if ++ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) ++ evaluated with infinite-precision integer arithmetic. */ ++ ++#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 ++# undef YYMAXDEPTH ++#endif ++ ++#ifndef YYMAXDEPTH ++# define YYMAXDEPTH 10000 ++#endif ++ ++ ++ ++#if YYERROR_VERBOSE ++ ++# ifndef yystrlen ++# if defined (__GLIBC__) && defined (_STRING_H) ++# define yystrlen strlen ++# else ++/* Return the length of YYSTR. */ ++static YYSIZE_T ++# if defined (__STDC__) || defined (__cplusplus) ++yystrlen (const char *yystr) ++# else ++yystrlen (yystr) ++ const char *yystr; ++# endif ++{ ++ register const char *yys = yystr; ++ ++ while (*yys++ != '\0') ++ continue; ++ ++ return yys - yystr - 1; ++} ++# endif ++# endif ++ ++# ifndef yystpcpy ++# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) ++# define yystpcpy stpcpy ++# else ++/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in ++ YYDEST. */ ++static char * ++# if defined (__STDC__) || defined (__cplusplus) ++yystpcpy (char *yydest, const char *yysrc) ++# else ++yystpcpy (yydest, yysrc) ++ char *yydest; ++ const char *yysrc; ++# endif ++{ ++ register char *yyd = yydest; ++ register const char *yys = yysrc; ++ ++ while ((*yyd++ = *yys++) != '\0') ++ continue; ++ ++ return yyd - 1; ++} ++# endif ++# endif ++ ++#endif /* !YYERROR_VERBOSE */ ++ ++ ++ ++#if YYDEBUG ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yysymprint (yyoutput, yytype, yyvaluep) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ if (yytype < YYNTOKENS) ++ { ++ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); ++# ifdef YYPRINT ++ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++# endif ++ } ++ else ++ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); ++ ++ switch (yytype) ++ { ++ default: ++ break; ++ } ++ YYFPRINTF (yyoutput, ")"); ++} ++ ++#endif /* ! YYDEBUG */ ++/*-----------------------------------------------. ++| Release the memory associated to this symbol. | ++`-----------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yydestruct (int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yydestruct (yytype, yyvaluep) ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ switch (yytype) ++ { ++ ++ default: ++ break; ++ } ++} ++ ++ ++/* Prevent warnings from -Wmissing-prototypes. */ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM); ++# else ++int yyparse (); ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void); ++#else ++int yyparse (); ++#endif ++#endif /* ! YYPARSE_PARAM */ ++ ++ ++ ++ ++ ++ ++/*----------. ++| yyparse. | ++`----------*/ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM) ++# else ++int yyparse (YYPARSE_PARAM) ++ void *YYPARSE_PARAM; ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int ++yyparse (void) ++#else ++int ++yyparse () ++ ++#endif ++#endif ++{ ++ /* The lookahead symbol. */ ++int yychar; ++ ++/* The semantic value of the lookahead symbol. */ ++YYSTYPE yylval; ++ ++/* Number of syntax errors so far. */ ++int yynerrs; ++ ++ register int yystate; ++ register int yyn; ++ int yyresult; ++ /* Number of tokens to shift before error messages enabled. */ ++ int yyerrstatus; ++ /* Lookahead token as an internal (translated) token number. */ ++ int yytoken = 0; ++ ++ /* Three stacks and their tools: ++ `yyss': related to states, ++ `yyvs': related to semantic values, ++ `yyls': related to locations. ++ ++ Refer to the stacks thru separate pointers, to allow yyoverflow ++ to reallocate them elsewhere. */ ++ ++ /* The state stack. */ ++ short yyssa[YYINITDEPTH]; ++ short *yyss = yyssa; ++ register short *yyssp; ++ ++ /* The semantic value stack. */ ++ YYSTYPE yyvsa[YYINITDEPTH]; ++ YYSTYPE *yyvs = yyvsa; ++ register YYSTYPE *yyvsp; ++ ++ ++ ++#define YYPOPSTACK (yyvsp--, yyssp--) ++ ++ YYSIZE_T yystacksize = YYINITDEPTH; ++ ++ /* The variables used to return semantic value and location from the ++ action routines. */ ++ YYSTYPE yyval; ++ ++ ++ /* When reducing, the number of symbols on the RHS of the reduced ++ rule. */ ++ int yylen; ++ ++ YYDPRINTF ((stderr, "Starting parse\n")); ++ ++ yystate = 0; ++ yyerrstatus = 0; ++ yynerrs = 0; ++ yychar = YYEMPTY; /* Cause a token to be read. */ ++ ++ /* Initialize stack pointers. ++ Waste one element of value and location stack ++ so that they stay on the same level as the state stack. ++ The wasted elements are never initialized. */ ++ ++ yyssp = yyss; ++ yyvsp = yyvs; ++ ++ goto yysetstate; ++ ++/*------------------------------------------------------------. ++| yynewstate -- Push a new state, which is found in yystate. | ++`------------------------------------------------------------*/ ++ yynewstate: ++ /* In all cases, when you get here, the value and location stacks ++ have just been pushed. so pushing a state here evens the stacks. ++ */ ++ yyssp++; ++ ++ yysetstate: ++ *yyssp = yystate; ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ { ++ /* Get the current used size of the three stacks, in elements. */ ++ YYSIZE_T yysize = yyssp - yyss + 1; ++ ++#ifdef yyoverflow ++ { ++ /* Give user a chance to reallocate the stack. Use copies of ++ these so that the &'s don't force the real ones into ++ memory. */ ++ YYSTYPE *yyvs1 = yyvs; ++ short *yyss1 = yyss; ++ ++ ++ /* Each stack pointer address is followed by the size of the ++ data in use in that stack, in bytes. This used to be a ++ conditional around just the two extra args, but that might ++ be undefined if yyoverflow is a macro. */ ++ yyoverflow ("parser stack overflow", ++ &yyss1, yysize * sizeof (*yyssp), ++ &yyvs1, yysize * sizeof (*yyvsp), ++ ++ &yystacksize); ++ ++ yyss = yyss1; ++ yyvs = yyvs1; ++ } ++#else /* no yyoverflow */ ++# ifndef YYSTACK_RELOCATE ++ goto yyoverflowlab; ++# else ++ /* Extend the stack our own way. */ ++ if (YYMAXDEPTH <= yystacksize) ++ goto yyoverflowlab; ++ yystacksize *= 2; ++ if (YYMAXDEPTH < yystacksize) ++ yystacksize = YYMAXDEPTH; ++ ++ { ++ short *yyss1 = yyss; ++ union yyalloc *yyptr = ++ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ if (! yyptr) ++ goto yyoverflowlab; ++ YYSTACK_RELOCATE (yyss); ++ YYSTACK_RELOCATE (yyvs); ++ ++# undef YYSTACK_RELOCATE ++ if (yyss1 != yyssa) ++ YYSTACK_FREE (yyss1); ++ } ++# endif ++#endif /* no yyoverflow */ ++ ++ yyssp = yyss + yysize - 1; ++ yyvsp = yyvs + yysize - 1; ++ ++ ++ YYDPRINTF ((stderr, "Stack size increased to %lu\n", ++ (unsigned long int) yystacksize)); ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ YYABORT; ++ } ++ ++ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); ++ ++ goto yybackup; ++ ++/*-----------. ++| yybackup. | ++`-----------*/ ++yybackup: ++ ++/* Do appropriate processing given the current state. */ ++/* Read a lookahead token if we need one and don't already have one. */ ++/* yyresume: */ ++ ++ /* First try to decide what to do without reference to lookahead token. */ ++ ++ yyn = yypact[yystate]; ++ if (yyn == YYPACT_NINF) ++ goto yydefault; ++ ++ /* Not known => get a lookahead token if don't already have one. */ ++ ++ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ ++ if (yychar == YYEMPTY) ++ { ++ YYDPRINTF ((stderr, "Reading a token: ")); ++ yychar = YYLEX; ++ } ++ ++ if (yychar <= YYEOF) ++ { ++ yychar = yytoken = YYEOF; ++ YYDPRINTF ((stderr, "Now at end of input.\n")); ++ } ++ else ++ { ++ yytoken = YYTRANSLATE (yychar); ++ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); ++ } ++ ++ /* If the proper action on seeing token YYTOKEN is to reduce or to ++ detect an error, take that action. */ ++ yyn += yytoken; ++ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) ++ goto yydefault; ++ yyn = yytable[yyn]; ++ if (yyn <= 0) ++ { ++ if (yyn == 0 || yyn == YYTABLE_NINF) ++ goto yyerrlab; ++ yyn = -yyn; ++ goto yyreduce; ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ /* Shift the lookahead token. */ ++ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); ++ ++ /* Discard the token being shifted unless it is eof. */ ++ if (yychar != YYEOF) ++ yychar = YYEMPTY; ++ ++ *++yyvsp = yylval; ++ ++ ++ /* Count tokens shifted since error; after three, turn off error ++ status. */ ++ if (yyerrstatus) ++ yyerrstatus--; ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-----------------------------------------------------------. ++| yydefault -- do the default action for the current state. | ++`-----------------------------------------------------------*/ ++yydefault: ++ yyn = yydefact[yystate]; ++ if (yyn == 0) ++ goto yyerrlab; ++ goto yyreduce; ++ ++ ++/*-----------------------------. ++| yyreduce -- Do a reduction. | ++`-----------------------------*/ ++yyreduce: ++ /* yyn is the number of a rule to reduce with. */ ++ yylen = yyr2[yyn]; ++ ++ /* If YYLEN is nonzero, implement the default value of the action: ++ `$$ = $1'. ++ ++ Otherwise, the following line sets YYVAL to garbage. ++ This behavior is undocumented and Bison ++ users should not rely upon it. Assigning to YYVAL ++ unconditionally makes the parser a bit smaller, and it avoids a ++ GCC warning that YYVAL may be used uninitialized. */ ++ yyval = yyvsp[1-yylen]; ++ ++ ++ YY_REDUCE_PRINT (yyn); ++ switch (yyn) ++ { ++ case 2: ++#line 139 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ *sql->view = yyvsp[0].query; ++ ;} ++ break; ++ ++ case 8: ++#line 155 "./sql.y" ++ { ++ SQL_input *sql = (SQL_input*) info; ++ MSIVIEW *insert = NULL; ++ UINT r; ++ ++ r = INSERT_CreateView( sql->db, &insert, yyvsp[-7].string, yyvsp[-5].column_list, yyvsp[-1].column_list, FALSE ); ++ if( !insert ) ++ YYABORT; ++ yyval.query = insert; ++ ;} ++ break; ++ ++ case 9: ++#line 166 "./sql.y" ++ { ++ SQL_input *sql = (SQL_input*) info; ++ MSIVIEW *insert = NULL; ++ ++ INSERT_CreateView( sql->db, &insert, yyvsp[-8].string, yyvsp[-6].column_list, yyvsp[-2].column_list, TRUE ); ++ if( !insert ) ++ YYABORT; ++ yyval.query = insert; ++ ;} ++ break; ++ ++ case 10: ++#line 179 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ MSIVIEW *create = NULL; ++ ++ if( !yyvsp[-1].column_list ) ++ YYABORT; ++ CREATE_CreateView( sql->db, &create, yyvsp[-3].string, yyvsp[-1].column_list, FALSE ); ++ if( !create ) ++ YYABORT; ++ yyval.query = create; ++ ;} ++ break; ++ ++ case 11: ++#line 191 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ MSIVIEW *create = NULL; ++ ++ if( !yyvsp[-2].column_list ) ++ YYABORT; ++ CREATE_CreateView( sql->db, &create, yyvsp[-4].string, yyvsp[-2].column_list, TRUE ); ++ if( !create ) ++ YYABORT; ++ yyval.query = create; ++ ;} ++ break; ++ ++ case 12: ++#line 206 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ MSIVIEW *update = NULL; ++ ++ UPDATE_CreateView( sql->db, &update, yyvsp[-4].string, yyvsp[-2].column_list, yyvsp[0].expr ); ++ if( !update ) ++ YYABORT; ++ yyval.query = update; ++ ;} ++ break; ++ ++ case 13: ++#line 219 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ MSIVIEW *delete = NULL; ++ ++ DELETE_CreateView( sql->db, &delete, yyvsp[0].query ); ++ if( !delete ) ++ YYABORT; ++ yyval.query = delete; ++ ;} ++ break; ++ ++ case 14: ++#line 232 "./sql.y" ++ { ++ if( SQL_MarkPrimaryKeys( yyvsp[-3].column_list, yyvsp[0].column_list ) ) ++ yyval.column_list = yyvsp[-3].column_list; ++ else ++ yyval.column_list = NULL; ++ ;} ++ break; ++ ++ case 15: ++#line 242 "./sql.y" ++ { ++ column_info *ci; ++ ++ for( ci = yyvsp[-2].column_list; ci->next; ci = ci->next ) ++ ; ++ ++ ci->next = yyvsp[0].column_list; ++ yyval.column_list = yyvsp[-2].column_list; ++ ;} ++ break; ++ ++ case 16: ++#line 252 "./sql.y" ++ { ++ yyval.column_list = yyvsp[0].column_list; ++ ;} ++ break; ++ ++ case 17: ++#line 259 "./sql.y" ++ { ++ yyval.column_list = yyvsp[-1].column_list; ++ yyval.column_list->type = yyvsp[0].column_type | MSITYPE_VALID; ++ ;} ++ break; ++ ++ case 18: ++#line 267 "./sql.y" ++ { ++ yyval.column_type = yyvsp[0].column_type; ++ ;} ++ break; ++ ++ case 19: ++#line 271 "./sql.y" ++ { ++ yyval.column_type = yyvsp[-1].column_type | MSITYPE_LOCALIZABLE; ++ ;} ++ break; ++ ++ case 20: ++#line 278 "./sql.y" ++ { ++ yyval.column_type |= MSITYPE_NULLABLE; ++ ;} ++ break; ++ ++ case 21: ++#line 282 "./sql.y" ++ { ++ yyval.column_type = yyvsp[-2].column_type; ++ ;} ++ break; ++ ++ case 22: ++#line 289 "./sql.y" ++ { ++ yyval.column_type = MSITYPE_STRING | 1; ++ ;} ++ break; ++ ++ case 23: ++#line 293 "./sql.y" ++ { ++ yyval.column_type = MSITYPE_STRING | 0x400 | yyvsp[-1].column_type; ++ ;} ++ break; ++ ++ case 24: ++#line 297 "./sql.y" ++ { ++ yyval.column_type = 2; ++ ;} ++ break; ++ ++ case 25: ++#line 301 "./sql.y" ++ { ++ yyval.column_type = 2; ++ ;} ++ break; ++ ++ case 26: ++#line 305 "./sql.y" ++ { ++ yyval.column_type = 2; ++ ;} ++ break; ++ ++ case 27: ++#line 309 "./sql.y" ++ { ++ yyval.column_type = 4; ++ ;} ++ break; ++ ++ case 28: ++#line 313 "./sql.y" ++ { ++ yyval.column_type = MSITYPE_STRING | MSITYPE_VALID; ++ ;} ++ break; ++ ++ case 29: ++#line 320 "./sql.y" ++ { ++ if( ( yyvsp[0].integer > 255 ) || ( yyvsp[0].integer < 0 ) ) ++ YYABORT; ++ yyval.column_type = yyvsp[0].integer; ++ ;} ++ break; ++ ++ case 30: ++#line 329 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ ++ yyval.query = NULL; ++ if( yyvsp[0].column_list ) ++ ORDER_CreateView( sql->db, &yyval.query, yyvsp[-3].query, yyvsp[0].column_list ); ++ else ++ yyval.query = yyvsp[-3].query; ++ if( !yyval.query ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 32: ++#line 345 "./sql.y" ++ { ++ yyval.query = yyvsp[0].query; ++ ;} ++ break; ++ ++ case 33: ++#line 349 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ UINT r; ++ ++ yyval.query = NULL; ++ r = DISTINCT_CreateView( sql->db, &yyval.query, yyvsp[0].query ); ++ if (r != ERROR_SUCCESS) ++ { ++ yyvsp[0].query->ops->delete(yyvsp[0].query); ++ YYABORT; ++ } ++ ;} ++ break; ++ ++ case 34: ++#line 365 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ UINT r; ++ ++ yyval.query = NULL; ++ if( yyvsp[-1].column_list ) ++ { ++ r = SELECT_CreateView( sql->db, &yyval.query, yyvsp[0].query, yyvsp[-1].column_list ); ++ if (r != ERROR_SUCCESS) ++ { ++ yyvsp[0].query->ops->delete(yyvsp[0].query); ++ YYABORT; ++ } ++ } ++ else ++ yyval.query = yyvsp[0].query; ++ ;} ++ break; ++ ++ case 36: ++#line 387 "./sql.y" ++ { ++ yyvsp[-2].column_list->next = yyvsp[0].column_list; ++ ;} ++ break; ++ ++ case 37: ++#line 391 "./sql.y" ++ { ++ yyval.column_list = NULL; ++ ;} ++ break; ++ ++ case 39: ++#line 399 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ UINT r; ++ ++ yyval.query = NULL; ++ r = WHERE_CreateView( sql->db, &yyval.query, yyvsp[-2].query, yyvsp[0].expr ); ++ if( r != ERROR_SUCCESS ) ++ { ++ yyvsp[-2].query->ops->delete( yyvsp[-2].query ); ++ YYABORT; ++ } ++ ;} ++ break; ++ ++ case 40: ++#line 415 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ UINT r; ++ ++ yyval.query = NULL; ++ r = TABLE_CreateView( sql->db, yyvsp[0].string, &yyval.query ); ++ if( r != ERROR_SUCCESS || !yyval.query ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 41: ++#line 428 "./sql.y" ++ { ++ yyval.expr = yyvsp[-1].expr; ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 42: ++#line 434 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 43: ++#line 440 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_AND, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 44: ++#line 446 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_OR, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 45: ++#line 452 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 46: ++#line 458 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GT, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 47: ++#line 464 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LT, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 48: ++#line 470 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LE, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 49: ++#line 476 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GE, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 50: ++#line 482 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_NE, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 51: ++#line 488 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_ISNULL, NULL ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 52: ++#line 494 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-3].expr, OP_NOTNULL, NULL ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 55: ++#line 508 "./sql.y" ++ { ++ yyval.column_list = parser_alloc_column( info, NULL, NULL ); ++ if( !yyval.column_list ) ++ YYABORT; ++ yyval.column_list->val = yyvsp[0].expr; ++ ;} ++ break; ++ ++ case 56: ++#line 515 "./sql.y" ++ { ++ yyval.column_list = parser_alloc_column( info, NULL, NULL ); ++ if( !yyval.column_list ) ++ YYABORT; ++ yyval.column_list->val = yyvsp[-2].expr; ++ yyval.column_list->next = yyvsp[0].column_list; ++ ;} ++ break; ++ ++ case 58: ++#line 527 "./sql.y" ++ { ++ yyval.column_list = yyvsp[-2].column_list; ++ yyval.column_list->next = yyvsp[0].column_list; ++ ;} ++ break; ++ ++ case 59: ++#line 535 "./sql.y" ++ { ++ yyval.column_list = yyvsp[-2].column_list; ++ yyval.column_list->val = yyvsp[0].expr; ++ ;} ++ break; ++ ++ case 60: ++#line 543 "./sql.y" ++ { ++ yyval.expr = EXPR_ival( info, yyvsp[0].integer ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 61: ++#line 549 "./sql.y" ++ { ++ yyval.expr = EXPR_ival( info, -yyvsp[0].integer ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 62: ++#line 555 "./sql.y" ++ { ++ yyval.expr = EXPR_sval( info, &yyvsp[0].str ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 63: ++#line 561 "./sql.y" ++ { ++ yyval.expr = EXPR_wildcard( info ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 64: ++#line 570 "./sql.y" ++ { ++ yyval.expr = EXPR_column( info, yyvsp[0].column_list ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 65: ++#line 579 "./sql.y" ++ { ++ yyval.column_list = parser_alloc_column( info, yyvsp[-2].string, yyvsp[0].string ); ++ if( !yyval.column_list ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 66: ++#line 585 "./sql.y" ++ { ++ yyval.column_list = parser_alloc_column( info, NULL, yyvsp[0].string ); ++ if( !yyval.column_list ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 67: ++#line 594 "./sql.y" ++ { ++ yyval.string = yyvsp[0].string; ++ ;} ++ break; ++ ++ case 68: ++#line 601 "./sql.y" ++ { ++ yyval.string = SQL_getstring( info, &yyvsp[0].str ); ++ if( !yyval.string ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 69: ++#line 610 "./sql.y" ++ { ++ yyval.integer = SQL_getint( info ); ++ ;} ++ break; ++ ++ ++ } ++ ++/* Line 1000 of yacc.c. */ ++#line 2054 "sql.tab.c" ++ ++ yyvsp -= yylen; ++ yyssp -= yylen; ++ ++ ++ YY_STACK_PRINT (yyss, yyssp); ++ ++ *++yyvsp = yyval; ++ ++ ++ /* Now `shift' the result of the reduction. Determine what state ++ that goes to, based on the state we popped back to and the rule ++ number reduced by. */ ++ ++ yyn = yyr1[yyn]; ++ ++ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; ++ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) ++ yystate = yytable[yystate]; ++ else ++ yystate = yydefgoto[yyn - YYNTOKENS]; ++ ++ goto yynewstate; ++ ++ ++/*------------------------------------. ++| yyerrlab -- here on detecting error | ++`------------------------------------*/ ++yyerrlab: ++ /* If not already recovering from an error, report this error. */ ++ if (!yyerrstatus) ++ { ++ ++yynerrs; ++#if YYERROR_VERBOSE ++ yyn = yypact[yystate]; ++ ++ if (YYPACT_NINF < yyn && yyn < YYLAST) ++ { ++ YYSIZE_T yysize = 0; ++ int yytype = YYTRANSLATE (yychar); ++ const char* yyprefix; ++ char *yymsg; ++ int yyx; ++ ++ /* Start YYX at -YYN if negative to avoid negative indexes in ++ YYCHECK. */ ++ int yyxbegin = yyn < 0 ? -yyn : 0; ++ ++ /* Stay within bounds of both yycheck and yytname. */ ++ int yychecklim = YYLAST - yyn; ++ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; ++ int yycount = 0; ++ ++ yyprefix = ", expecting "; ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); ++ yycount += 1; ++ if (yycount == 5) ++ { ++ yysize = 0; ++ break; ++ } ++ } ++ yysize += (sizeof ("syntax error, unexpected ") ++ + yystrlen (yytname[yytype])); ++ yymsg = (char *) YYSTACK_ALLOC (yysize); ++ if (yymsg != 0) ++ { ++ char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); ++ yyp = yystpcpy (yyp, yytname[yytype]); ++ ++ if (yycount < 5) ++ { ++ yyprefix = ", expecting "; ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ yyp = yystpcpy (yyp, yyprefix); ++ yyp = yystpcpy (yyp, yytname[yyx]); ++ yyprefix = " or "; ++ } ++ } ++ yyerror (yymsg); ++ YYSTACK_FREE (yymsg); ++ } ++ else ++ yyerror ("syntax error; also virtual memory exhausted"); ++ } ++ else ++#endif /* YYERROR_VERBOSE */ ++ yyerror ("syntax error"); ++ } ++ ++ ++ ++ if (yyerrstatus == 3) ++ { ++ /* If just tried and failed to reuse lookahead token after an ++ error, discard it. */ ++ ++ if (yychar <= YYEOF) ++ { ++ /* If at end of input, pop the error token, ++ then the rest of the stack, then return failure. */ ++ if (yychar == YYEOF) ++ for (;;) ++ { ++ YYPOPSTACK; ++ if (yyssp == yyss) ++ YYABORT; ++ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); ++ yydestruct (yystos[*yyssp], yyvsp); ++ } ++ } ++ else ++ { ++ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); ++ yydestruct (yytoken, &yylval); ++ yychar = YYEMPTY; ++ ++ } ++ } ++ ++ /* Else will try to reuse lookahead token after shifting the error ++ token. */ ++ goto yyerrlab1; ++ ++ ++/*---------------------------------------------------. ++| yyerrorlab -- error raised explicitly by YYERROR. | ++`---------------------------------------------------*/ ++yyerrorlab: ++ ++#ifdef __GNUC__ ++ /* Pacify GCC when the user code never invokes YYERROR and the label ++ yyerrorlab therefore never appears in user code. */ ++ if (0) ++ goto yyerrorlab; ++#endif ++ ++ yyvsp -= yylen; ++ yyssp -= yylen; ++ yystate = *yyssp; ++ goto yyerrlab1; ++ ++ ++/*-------------------------------------------------------------. ++| yyerrlab1 -- common code for both syntax error and YYERROR. | ++`-------------------------------------------------------------*/ ++yyerrlab1: ++ yyerrstatus = 3; /* Each real token shifted decrements this. */ ++ ++ for (;;) ++ { ++ yyn = yypact[yystate]; ++ if (yyn != YYPACT_NINF) ++ { ++ yyn += YYTERROR; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ { ++ yyn = yytable[yyn]; ++ if (0 < yyn) ++ break; ++ } ++ } ++ ++ /* Pop the current state because it cannot handle the error token. */ ++ if (yyssp == yyss) ++ YYABORT; ++ ++ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); ++ yydestruct (yystos[yystate], yyvsp); ++ YYPOPSTACK; ++ yystate = *yyssp; ++ YY_STACK_PRINT (yyss, yyssp); ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ YYDPRINTF ((stderr, "Shifting error token, ")); ++ ++ *++yyvsp = yylval; ++ ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-------------------------------------. ++| yyacceptlab -- YYACCEPT comes here. | ++`-------------------------------------*/ ++yyacceptlab: ++ yyresult = 0; ++ goto yyreturn; ++ ++/*-----------------------------------. ++| yyabortlab -- YYABORT comes here. | ++`-----------------------------------*/ ++yyabortlab: ++ yyresult = 1; ++ goto yyreturn; ++ ++#ifndef yyoverflow ++/*----------------------------------------------. ++| yyoverflowlab -- parser overflow comes here. | ++`----------------------------------------------*/ ++yyoverflowlab: ++ yyerror ("parser stack overflow"); ++ yyresult = 2; ++ /* Fall through. */ ++#endif ++ ++yyreturn: ++#ifndef yyoverflow ++ if (yyss != yyssa) ++ YYSTACK_FREE (yyss); ++#endif ++ return yyresult; ++} ++ ++ ++#line 615 "./sql.y" ++ ++ ++static void *parser_alloc( void *info, unsigned int sz ) ++{ ++ SQL_input* sql = (SQL_input*) info; ++ struct list *mem; ++ ++ mem = msi_alloc( sizeof (struct list) + sz ); ++ list_add_tail( sql->mem, mem ); ++ return &mem[1]; ++} ++ ++static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ) ++{ ++ column_info *col; ++ ++ col = parser_alloc( info, sizeof (*col) ); ++ if( col ) ++ { ++ col->table = table; ++ col->column = column; ++ col->val = NULL; ++ col->type = 0; ++ col->next = NULL; ++ } ++ ++ return col; ++} ++ ++int SQL_lex( void *SQL_lval, SQL_input *sql ) ++{ ++ int token; ++ struct sql_str * str = SQL_lval; ++ ++ do ++ { ++ sql->n += sql->len; ++ if( ! sql->command[sql->n] ) ++ return 0; /* end of input */ ++ ++ /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */ ++ sql->len = sqliteGetToken( &sql->command[sql->n], &token ); ++ if( sql->len==0 ) ++ break; ++ str->data = &sql->command[sql->n]; ++ str->len = sql->len; ++ } ++ while( token == TK_SPACE ); ++ ++ /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */ ++ ++ return token; ++} ++ ++LPWSTR SQL_getstring( void *info, struct sql_str *strdata ) ++{ ++ LPCWSTR p = strdata->data; ++ UINT len = strdata->len; ++ LPWSTR str; ++ ++ /* if there's quotes, remove them */ ++ if( ( (p[0]=='`') && (p[len-1]=='`') ) || ++ ( (p[0]=='\'') && (p[len-1]=='\'') ) ) ++ { ++ p++; ++ len -= 2; ++ } ++ str = parser_alloc( info, (len + 1)*sizeof(WCHAR) ); ++ if( !str ) ++ return str; ++ memcpy( str, p, len*sizeof(WCHAR) ); ++ str[len]=0; ++ ++ return str; ++} ++ ++INT SQL_getint( void *info ) ++{ ++ SQL_input* sql = (SQL_input*) info; ++ LPCWSTR p = &sql->command[sql->n]; ++ INT i, r = 0; ++ ++ for( i=0; ilen; i++ ) ++ { ++ if( '0' > p[i] || '9' < p[i] ) ++ { ++ ERR("should only be numbers here!\n"); ++ break; ++ } ++ r = (p[i]-'0') + r*10; ++ } ++ ++ return r; ++} ++ ++int SQL_error( const char *str ) ++{ ++ return 0; ++} ++ ++static struct expr * EXPR_wildcard( void *info ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_WILDCARD; ++ } ++ return e; ++} ++ ++static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_COMPLEX; ++ e->u.expr.left = l; ++ e->u.expr.op = op; ++ e->u.expr.right = r; ++ } ++ return e; ++} ++ ++static struct expr * EXPR_column( void *info, column_info *column ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_COLUMN; ++ e->u.sval = column->column; ++ } ++ return e; ++} ++ ++static struct expr * EXPR_ival( void *info, int val ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_IVAL; ++ e->u.ival = val; ++ } ++ return e; ++} ++ ++static struct expr * EXPR_sval( void *info, struct sql_str *str ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_SVAL; ++ e->u.sval = SQL_getstring( info, str ); ++ } ++ return e; ++} ++ ++static BOOL SQL_MarkPrimaryKeys( column_info *cols, ++ column_info *keys ) ++{ ++ column_info *k; ++ BOOL found = TRUE; ++ ++ for( k = keys; k && found; k = k->next ) ++ { ++ column_info *c; ++ ++ found = FALSE; ++ for( c = cols; c && !found; c = c->next ) ++ { ++ if( lstrcmpW( k->column, c->column ) ) ++ continue; ++ c->type |= MSITYPE_KEY; ++ found = TRUE; ++ } ++ } ++ ++ return found; ++} ++ ++UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, ++ struct list *mem ) ++{ ++ SQL_input sql; ++ int r; ++ ++ *phview = NULL; ++ ++ sql.db = db; ++ sql.command = command; ++ sql.n = 0; ++ sql.len = 0; ++ sql.view = phview; ++ sql.mem = mem; ++ ++ r = SQL_parse(&sql); ++ ++ TRACE("Parse returned %d\n", r); ++ if( r ) ++ { ++ *sql.view = NULL; ++ return ERROR_BAD_QUERY_SYNTAX; ++ } ++ ++ return ERROR_SUCCESS; ++} ++ Index: sql.tab.h =================================================================== --- sql.tab.h (revision 23782) +++ sql.tab.h (working copy) @@ -0,0 +1,345 @@ -+/* A Bison parser, made by GNU Bison 1.875c. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -+ -+ 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, 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., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ TK_ABORT = 258, -+ TK_AFTER = 259, -+ TK_AGG_FUNCTION = 260, -+ TK_ALL = 261, -+ TK_AND = 262, -+ TK_AS = 263, -+ TK_ASC = 264, -+ TK_BEFORE = 265, -+ TK_BEGIN = 266, -+ TK_BETWEEN = 267, -+ TK_BITAND = 268, -+ TK_BITNOT = 269, -+ TK_BITOR = 270, -+ TK_BY = 271, -+ TK_CASCADE = 272, -+ TK_CASE = 273, -+ TK_CHAR = 274, -+ TK_CHECK = 275, -+ TK_CLUSTER = 276, -+ TK_COLLATE = 277, -+ TK_COLUMN = 278, -+ TK_COMMA = 279, -+ TK_COMMENT = 280, -+ TK_COMMIT = 281, -+ TK_CONCAT = 282, -+ TK_CONFLICT = 283, -+ TK_CONSTRAINT = 284, -+ TK_COPY = 285, -+ TK_CREATE = 286, -+ TK_DEFAULT = 287, -+ TK_DEFERRABLE = 288, -+ TK_DEFERRED = 289, -+ TK_DELETE = 290, -+ TK_DELIMITERS = 291, -+ TK_DESC = 292, -+ TK_DISTINCT = 293, -+ TK_DOT = 294, -+ TK_DROP = 295, -+ TK_EACH = 296, -+ TK_ELSE = 297, -+ TK_END = 298, -+ TK_END_OF_FILE = 299, -+ TK_EQ = 300, -+ TK_EXCEPT = 301, -+ TK_EXPLAIN = 302, -+ TK_FAIL = 303, -+ TK_FLOAT = 304, -+ TK_FOR = 305, -+ TK_FOREIGN = 306, -+ TK_FROM = 307, -+ TK_FUNCTION = 308, -+ TK_GE = 309, -+ TK_GLOB = 310, -+ TK_GROUP = 311, -+ TK_GT = 312, -+ TK_HAVING = 313, -+ TK_HOLD = 314, -+ TK_IGNORE = 315, -+ TK_ILLEGAL = 316, -+ TK_IMMEDIATE = 317, -+ TK_IN = 318, -+ TK_INDEX = 319, -+ TK_INITIALLY = 320, -+ TK_ID = 321, -+ TK_INSERT = 322, -+ TK_INSTEAD = 323, -+ TK_INT = 324, -+ TK_INTEGER = 325, -+ TK_INTERSECT = 326, -+ TK_INTO = 327, -+ TK_IS = 328, -+ TK_ISNULL = 329, -+ TK_JOIN = 330, -+ TK_JOIN_KW = 331, -+ TK_KEY = 332, -+ TK_LE = 333, -+ TK_LIKE = 334, -+ TK_LIMIT = 335, -+ TK_LONG = 336, -+ TK_LONGCHAR = 337, -+ TK_LP = 338, -+ TK_LSHIFT = 339, -+ TK_LT = 340, -+ TK_LOCALIZABLE = 341, -+ TK_MATCH = 342, -+ TK_MINUS = 343, -+ TK_NE = 344, -+ TK_NOT = 345, -+ TK_NOTNULL = 346, -+ TK_NULL = 347, -+ TK_OBJECT = 348, -+ TK_OF = 349, -+ TK_OFFSET = 350, -+ TK_ON = 351, -+ TK_OR = 352, -+ TK_ORACLE_OUTER_JOIN = 353, -+ TK_ORDER = 354, -+ TK_PLUS = 355, -+ TK_PRAGMA = 356, -+ TK_PRIMARY = 357, -+ TK_RAISE = 358, -+ TK_REFERENCES = 359, -+ TK_REM = 360, -+ TK_REPLACE = 361, -+ TK_RESTRICT = 362, -+ TK_ROLLBACK = 363, -+ TK_ROW = 364, -+ TK_RP = 365, -+ TK_RSHIFT = 366, -+ TK_SELECT = 367, -+ TK_SEMI = 368, -+ TK_SET = 369, -+ TK_SHORT = 370, -+ TK_SLASH = 371, -+ TK_SPACE = 372, -+ TK_STAR = 373, -+ TK_STATEMENT = 374, -+ TK_STRING = 375, -+ TK_TABLE = 376, -+ TK_TEMP = 377, -+ TK_THEN = 378, -+ TK_TRANSACTION = 379, -+ TK_TRIGGER = 380, -+ TK_UMINUS = 381, -+ TK_UNCLOSED_STRING = 382, -+ TK_UNION = 383, -+ TK_UNIQUE = 384, -+ TK_UPDATE = 385, -+ TK_UPLUS = 386, -+ TK_USING = 387, -+ TK_VACUUM = 388, -+ TK_VALUES = 389, -+ TK_VIEW = 390, -+ TK_WHEN = 391, -+ TK_WHERE = 392, -+ TK_WILDCARD = 393, -+ COLUMN = 395, -+ FUNCTION = 396, -+ COMMENT = 397, -+ UNCLOSED_STRING = 398, -+ SPACE = 399, -+ ILLEGAL = 400, -+ END_OF_FILE = 401 -+ }; -+#endif -+#define TK_ABORT 258 -+#define TK_AFTER 259 -+#define TK_AGG_FUNCTION 260 -+#define TK_ALL 261 -+#define TK_AND 262 -+#define TK_AS 263 -+#define TK_ASC 264 -+#define TK_BEFORE 265 -+#define TK_BEGIN 266 -+#define TK_BETWEEN 267 -+#define TK_BITAND 268 -+#define TK_BITNOT 269 -+#define TK_BITOR 270 -+#define TK_BY 271 -+#define TK_CASCADE 272 -+#define TK_CASE 273 -+#define TK_CHAR 274 -+#define TK_CHECK 275 -+#define TK_CLUSTER 276 -+#define TK_COLLATE 277 -+#define TK_COLUMN 278 -+#define TK_COMMA 279 -+#define TK_COMMENT 280 -+#define TK_COMMIT 281 -+#define TK_CONCAT 282 -+#define TK_CONFLICT 283 -+#define TK_CONSTRAINT 284 -+#define TK_COPY 285 -+#define TK_CREATE 286 -+#define TK_DEFAULT 287 -+#define TK_DEFERRABLE 288 -+#define TK_DEFERRED 289 -+#define TK_DELETE 290 -+#define TK_DELIMITERS 291 -+#define TK_DESC 292 -+#define TK_DISTINCT 293 -+#define TK_DOT 294 -+#define TK_DROP 295 -+#define TK_EACH 296 -+#define TK_ELSE 297 -+#define TK_END 298 -+#define TK_END_OF_FILE 299 -+#define TK_EQ 300 -+#define TK_EXCEPT 301 -+#define TK_EXPLAIN 302 -+#define TK_FAIL 303 -+#define TK_FLOAT 304 -+#define TK_FOR 305 -+#define TK_FOREIGN 306 -+#define TK_FROM 307 -+#define TK_FUNCTION 308 -+#define TK_GE 309 -+#define TK_GLOB 310 -+#define TK_GROUP 311 -+#define TK_GT 312 -+#define TK_HAVING 313 -+#define TK_HOLD 314 -+#define TK_IGNORE 315 -+#define TK_ILLEGAL 316 -+#define TK_IMMEDIATE 317 -+#define TK_IN 318 -+#define TK_INDEX 319 -+#define TK_INITIALLY 320 -+#define TK_ID 321 -+#define TK_INSERT 322 -+#define TK_INSTEAD 323 -+#define TK_INT 324 -+#define TK_INTEGER 325 -+#define TK_INTERSECT 326 -+#define TK_INTO 327 -+#define TK_IS 328 -+#define TK_ISNULL 329 -+#define TK_JOIN 330 -+#define TK_JOIN_KW 331 -+#define TK_KEY 332 -+#define TK_LE 333 -+#define TK_LIKE 334 -+#define TK_LIMIT 335 -+#define TK_LONG 336 -+#define TK_LONGCHAR 337 -+#define TK_LP 338 -+#define TK_LSHIFT 339 -+#define TK_LT 340 -+#define TK_LOCALIZABLE 341 -+#define TK_MATCH 342 -+#define TK_MINUS 343 -+#define TK_NE 344 -+#define TK_NOT 345 -+#define TK_NOTNULL 346 -+#define TK_NULL 347 -+#define TK_OBJECT 348 -+#define TK_OF 349 -+#define TK_OFFSET 350 -+#define TK_ON 351 -+#define TK_OR 352 -+#define TK_ORACLE_OUTER_JOIN 353 -+#define TK_ORDER 354 -+#define TK_PLUS 355 -+#define TK_PRAGMA 356 -+#define TK_PRIMARY 357 -+#define TK_RAISE 358 -+#define TK_REFERENCES 359 -+#define TK_REM 360 -+#define TK_REPLACE 361 -+#define TK_RESTRICT 362 -+#define TK_ROLLBACK 363 -+#define TK_ROW 364 -+#define TK_RP 365 -+#define TK_RSHIFT 366 -+#define TK_SELECT 367 -+#define TK_SEMI 368 -+#define TK_SET 369 -+#define TK_SHORT 370 -+#define TK_SLASH 371 -+#define TK_SPACE 372 -+#define TK_STAR 373 -+#define TK_STATEMENT 374 -+#define TK_STRING 375 -+#define TK_TABLE 376 -+#define TK_TEMP 377 -+#define TK_THEN 378 -+#define TK_TRANSACTION 379 -+#define TK_TRIGGER 380 -+#define TK_UMINUS 381 -+#define TK_UNCLOSED_STRING 382 -+#define TK_UNION 383 -+#define TK_UNIQUE 384 -+#define TK_UPDATE 385 -+#define TK_UPLUS 386 -+#define TK_USING 387 -+#define TK_VACUUM 388 -+#define TK_VALUES 389 -+#define TK_VIEW 390 -+#define TK_WHEN 391 -+#define TK_WHERE 392 -+#define TK_WILDCARD 393 -+#define COLUMN 395 -+#define FUNCTION 396 -+#define COMMENT 397 -+#define UNCLOSED_STRING 398 -+#define SPACE 399 -+#define ILLEGAL 400 -+#define END_OF_FILE 401 -+ -+ -+ -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 72 "./sql.y" -+typedef union YYSTYPE { -+ struct sql_str str; -+ LPWSTR string; -+ column_info *column_list; -+ MSIVIEW *query; -+ struct expr *expr; -+ USHORT column_type; -+ int integer; -+} YYSTYPE; -+/* Line 1275 of yacc.c. */ -+#line 337 "sql.tab.h" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+ -+ ++/* A Bison parser, made by GNU Bison 1.875c. */ ++ ++/* Skeleton parser for Yacc-like parsing with Bison, ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++ 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, 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., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ ++ ++/* Tokens. */ ++#ifndef YYTOKENTYPE ++# define YYTOKENTYPE ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ TK_ABORT = 258, ++ TK_AFTER = 259, ++ TK_AGG_FUNCTION = 260, ++ TK_ALL = 261, ++ TK_AND = 262, ++ TK_AS = 263, ++ TK_ASC = 264, ++ TK_BEFORE = 265, ++ TK_BEGIN = 266, ++ TK_BETWEEN = 267, ++ TK_BITAND = 268, ++ TK_BITNOT = 269, ++ TK_BITOR = 270, ++ TK_BY = 271, ++ TK_CASCADE = 272, ++ TK_CASE = 273, ++ TK_CHAR = 274, ++ TK_CHECK = 275, ++ TK_CLUSTER = 276, ++ TK_COLLATE = 277, ++ TK_COLUMN = 278, ++ TK_COMMA = 279, ++ TK_COMMENT = 280, ++ TK_COMMIT = 281, ++ TK_CONCAT = 282, ++ TK_CONFLICT = 283, ++ TK_CONSTRAINT = 284, ++ TK_COPY = 285, ++ TK_CREATE = 286, ++ TK_DEFAULT = 287, ++ TK_DEFERRABLE = 288, ++ TK_DEFERRED = 289, ++ TK_DELETE = 290, ++ TK_DELIMITERS = 291, ++ TK_DESC = 292, ++ TK_DISTINCT = 293, ++ TK_DOT = 294, ++ TK_DROP = 295, ++ TK_EACH = 296, ++ TK_ELSE = 297, ++ TK_END = 298, ++ TK_END_OF_FILE = 299, ++ TK_EQ = 300, ++ TK_EXCEPT = 301, ++ TK_EXPLAIN = 302, ++ TK_FAIL = 303, ++ TK_FLOAT = 304, ++ TK_FOR = 305, ++ TK_FOREIGN = 306, ++ TK_FROM = 307, ++ TK_FUNCTION = 308, ++ TK_GE = 309, ++ TK_GLOB = 310, ++ TK_GROUP = 311, ++ TK_GT = 312, ++ TK_HAVING = 313, ++ TK_HOLD = 314, ++ TK_IGNORE = 315, ++ TK_ILLEGAL = 316, ++ TK_IMMEDIATE = 317, ++ TK_IN = 318, ++ TK_INDEX = 319, ++ TK_INITIALLY = 320, ++ TK_ID = 321, ++ TK_INSERT = 322, ++ TK_INSTEAD = 323, ++ TK_INT = 324, ++ TK_INTEGER = 325, ++ TK_INTERSECT = 326, ++ TK_INTO = 327, ++ TK_IS = 328, ++ TK_ISNULL = 329, ++ TK_JOIN = 330, ++ TK_JOIN_KW = 331, ++ TK_KEY = 332, ++ TK_LE = 333, ++ TK_LIKE = 334, ++ TK_LIMIT = 335, ++ TK_LONG = 336, ++ TK_LONGCHAR = 337, ++ TK_LP = 338, ++ TK_LSHIFT = 339, ++ TK_LT = 340, ++ TK_LOCALIZABLE = 341, ++ TK_MATCH = 342, ++ TK_MINUS = 343, ++ TK_NE = 344, ++ TK_NOT = 345, ++ TK_NOTNULL = 346, ++ TK_NULL = 347, ++ TK_OBJECT = 348, ++ TK_OF = 349, ++ TK_OFFSET = 350, ++ TK_ON = 351, ++ TK_OR = 352, ++ TK_ORACLE_OUTER_JOIN = 353, ++ TK_ORDER = 354, ++ TK_PLUS = 355, ++ TK_PRAGMA = 356, ++ TK_PRIMARY = 357, ++ TK_RAISE = 358, ++ TK_REFERENCES = 359, ++ TK_REM = 360, ++ TK_REPLACE = 361, ++ TK_RESTRICT = 362, ++ TK_ROLLBACK = 363, ++ TK_ROW = 364, ++ TK_RP = 365, ++ TK_RSHIFT = 366, ++ TK_SELECT = 367, ++ TK_SEMI = 368, ++ TK_SET = 369, ++ TK_SHORT = 370, ++ TK_SLASH = 371, ++ TK_SPACE = 372, ++ TK_STAR = 373, ++ TK_STATEMENT = 374, ++ TK_STRING = 375, ++ TK_TABLE = 376, ++ TK_TEMP = 377, ++ TK_THEN = 378, ++ TK_TRANSACTION = 379, ++ TK_TRIGGER = 380, ++ TK_UMINUS = 381, ++ TK_UNCLOSED_STRING = 382, ++ TK_UNION = 383, ++ TK_UNIQUE = 384, ++ TK_UPDATE = 385, ++ TK_UPLUS = 386, ++ TK_USING = 387, ++ TK_VACUUM = 388, ++ TK_VALUES = 389, ++ TK_VIEW = 390, ++ TK_WHEN = 391, ++ TK_WHERE = 392, ++ TK_WILDCARD = 393, ++ COLUMN = 395, ++ FUNCTION = 396, ++ COMMENT = 397, ++ UNCLOSED_STRING = 398, ++ SPACE = 399, ++ ILLEGAL = 400, ++ END_OF_FILE = 401 ++ }; ++#endif ++#define TK_ABORT 258 ++#define TK_AFTER 259 ++#define TK_AGG_FUNCTION 260 ++#define TK_ALL 261 ++#define TK_AND 262 ++#define TK_AS 263 ++#define TK_ASC 264 ++#define TK_BEFORE 265 ++#define TK_BEGIN 266 ++#define TK_BETWEEN 267 ++#define TK_BITAND 268 ++#define TK_BITNOT 269 ++#define TK_BITOR 270 ++#define TK_BY 271 ++#define TK_CASCADE 272 ++#define TK_CASE 273 ++#define TK_CHAR 274 ++#define TK_CHECK 275 ++#define TK_CLUSTER 276 ++#define TK_COLLATE 277 ++#define TK_COLUMN 278 ++#define TK_COMMA 279 ++#define TK_COMMENT 280 ++#define TK_COMMIT 281 ++#define TK_CONCAT 282 ++#define TK_CONFLICT 283 ++#define TK_CONSTRAINT 284 ++#define TK_COPY 285 ++#define TK_CREATE 286 ++#define TK_DEFAULT 287 ++#define TK_DEFERRABLE 288 ++#define TK_DEFERRED 289 ++#define TK_DELETE 290 ++#define TK_DELIMITERS 291 ++#define TK_DESC 292 ++#define TK_DISTINCT 293 ++#define TK_DOT 294 ++#define TK_DROP 295 ++#define TK_EACH 296 ++#define TK_ELSE 297 ++#define TK_END 298 ++#define TK_END_OF_FILE 299 ++#define TK_EQ 300 ++#define TK_EXCEPT 301 ++#define TK_EXPLAIN 302 ++#define TK_FAIL 303 ++#define TK_FLOAT 304 ++#define TK_FOR 305 ++#define TK_FOREIGN 306 ++#define TK_FROM 307 ++#define TK_FUNCTION 308 ++#define TK_GE 309 ++#define TK_GLOB 310 ++#define TK_GROUP 311 ++#define TK_GT 312 ++#define TK_HAVING 313 ++#define TK_HOLD 314 ++#define TK_IGNORE 315 ++#define TK_ILLEGAL 316 ++#define TK_IMMEDIATE 317 ++#define TK_IN 318 ++#define TK_INDEX 319 ++#define TK_INITIALLY 320 ++#define TK_ID 321 ++#define TK_INSERT 322 ++#define TK_INSTEAD 323 ++#define TK_INT 324 ++#define TK_INTEGER 325 ++#define TK_INTERSECT 326 ++#define TK_INTO 327 ++#define TK_IS 328 ++#define TK_ISNULL 329 ++#define TK_JOIN 330 ++#define TK_JOIN_KW 331 ++#define TK_KEY 332 ++#define TK_LE 333 ++#define TK_LIKE 334 ++#define TK_LIMIT 335 ++#define TK_LONG 336 ++#define TK_LONGCHAR 337 ++#define TK_LP 338 ++#define TK_LSHIFT 339 ++#define TK_LT 340 ++#define TK_LOCALIZABLE 341 ++#define TK_MATCH 342 ++#define TK_MINUS 343 ++#define TK_NE 344 ++#define TK_NOT 345 ++#define TK_NOTNULL 346 ++#define TK_NULL 347 ++#define TK_OBJECT 348 ++#define TK_OF 349 ++#define TK_OFFSET 350 ++#define TK_ON 351 ++#define TK_OR 352 ++#define TK_ORACLE_OUTER_JOIN 353 ++#define TK_ORDER 354 ++#define TK_PLUS 355 ++#define TK_PRAGMA 356 ++#define TK_PRIMARY 357 ++#define TK_RAISE 358 ++#define TK_REFERENCES 359 ++#define TK_REM 360 ++#define TK_REPLACE 361 ++#define TK_RESTRICT 362 ++#define TK_ROLLBACK 363 ++#define TK_ROW 364 ++#define TK_RP 365 ++#define TK_RSHIFT 366 ++#define TK_SELECT 367 ++#define TK_SEMI 368 ++#define TK_SET 369 ++#define TK_SHORT 370 ++#define TK_SLASH 371 ++#define TK_SPACE 372 ++#define TK_STAR 373 ++#define TK_STATEMENT 374 ++#define TK_STRING 375 ++#define TK_TABLE 376 ++#define TK_TEMP 377 ++#define TK_THEN 378 ++#define TK_TRANSACTION 379 ++#define TK_TRIGGER 380 ++#define TK_UMINUS 381 ++#define TK_UNCLOSED_STRING 382 ++#define TK_UNION 383 ++#define TK_UNIQUE 384 ++#define TK_UPDATE 385 ++#define TK_UPLUS 386 ++#define TK_USING 387 ++#define TK_VACUUM 388 ++#define TK_VALUES 389 ++#define TK_VIEW 390 ++#define TK_WHEN 391 ++#define TK_WHERE 392 ++#define TK_WILDCARD 393 ++#define COLUMN 395 ++#define FUNCTION 396 ++#define COMMENT 397 ++#define UNCLOSED_STRING 398 ++#define SPACE 399 ++#define ILLEGAL 400 ++#define END_OF_FILE 401 ++ ++ ++ ++ ++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) ++#line 72 "./sql.y" ++typedef union YYSTYPE { ++ struct sql_str str; ++ LPWSTR string; ++ column_info *column_list; ++ MSIVIEW *query; ++ struct expr *expr; ++ USHORT column_type; ++ int integer; ++} YYSTYPE; ++/* Line 1275 of yacc.c. */ ++#line 337 "sql.tab.h" ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ ++# define YYSTYPE_IS_DECLARED 1 ++# define YYSTYPE_IS_TRIVIAL 1 ++#endif ++ ++ ++ ++ ++ Index: tokenize.c =================================================================== --- tokenize.c (revision 23808) +++ tokenize.c (working copy) -@@ -154,7 +154,7 @@ - static const Keyword aKeywordTable[] = { - { ABORT_W, TK_ABORT }, - { AFTER_W, TK_AFTER }, -+ /*{ ALTER_W, TK_ALTER },*/ -- { ALTER_W, TK_ALTER }, - { ALL_W, TK_ALL }, - { AND_W, TK_AND }, - { AS_W, TK_AS }, +@@ -156,7 +156,7 @@ + static const Keyword aKeywordTable[] = { + { ABORT_W, TK_ABORT }, + { AFTER_W, TK_AFTER }, ++ /*{ ALTER_W, TK_ALTER },*/ +- { ALTER_W, TK_ALTER }, + { ALL_W, TK_ALL }, + { AND_W, TK_AND }, + { AS_W, TK_AS }, diff --git a/reactos/dll/win32/msi/msiquery.c b/reactos/dll/win32/msi/msiquery.c index 44dc4e38584..00a4853b103 100644 --- a/reactos/dll/win32/msi/msiquery.c +++ b/reactos/dll/win32/msi/msiquery.c @@ -867,7 +867,7 @@ UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, } MSICONDITION WINAPI MsiDatabaseIsTablePersistentA( - MSIHANDLE hDatabase, LPSTR szTableName) + MSIHANDLE hDatabase, LPCSTR szTableName) { LPWSTR szwTableName = NULL; MSICONDITION r; @@ -887,7 +887,7 @@ MSICONDITION WINAPI MsiDatabaseIsTablePersistentA( } MSICONDITION WINAPI MsiDatabaseIsTablePersistentW( - MSIHANDLE hDatabase, LPWSTR szTableName) + MSIHANDLE hDatabase, LPCWSTR szTableName) { FIXME("%lx %s\n", hDatabase, debugstr_w(szTableName)); return MSICONDITION_FALSE; diff --git a/reactos/include/psdk/msiquery.h b/reactos/include/psdk/msiquery.h index 57f7577a317..8ea24b6cece 100644 --- a/reactos/include/psdk/msiquery.h +++ b/reactos/include/psdk/msiquery.h @@ -273,8 +273,8 @@ UINT WINAPI MsiOpenDatabaseW(LPCWSTR, LPCWSTR, MSIHANDLE*); UINT WINAPI MsiOpenDatabaseA(LPCSTR, LPCSTR, MSIHANDLE*); #define MsiOpenDatabase WINELIB_NAME_AW(MsiOpenDatabase) -MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE, LPSTR); -MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(MSIHANDLE, LPWSTR); +MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE, LPCSTR); +MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(MSIHANDLE, LPCWSTR); #define MsiDatabaseIsTablePersistent WINELIB_NAME_AW(MsiDatabaseIsTablePersistent) UINT WINAPI MsiSequenceA(MSIHANDLE, LPCSTR, INT); From 4246de31912aeb1be4b699ce2178c4c010a5cfab Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Sat, 9 Sep 2006 17:48:42 +0000 Subject: [PATCH 090/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24002 --- reactos/dll/win32/msi/action.c | 61 +- reactos/dll/win32/msi/create.c | 20 +- reactos/dll/win32/msi/custom.c | 48 +- reactos/dll/win32/msi/database.c | 132 +- reactos/dll/win32/msi/dialog.c | 396 +- reactos/dll/win32/msi/format.c | 52 +- reactos/dll/win32/msi/insert.c | 20 +- reactos/dll/win32/msi/join.c | 17 +- reactos/dll/win32/msi/msi_ros.diff | 10701 ++++++++++++++------------- reactos/dll/win32/msi/msipriv.h | 8 +- reactos/dll/win32/msi/msiquery.c | 74 +- reactos/dll/win32/msi/record.c | 48 +- reactos/dll/win32/msi/select.c | 27 +- reactos/dll/win32/msi/sql.y | 8 +- reactos/dll/win32/msi/string.c | 2 +- reactos/dll/win32/msi/table.c | 59 +- reactos/dll/win32/msi/tokenize.c | 34 +- 17 files changed, 6177 insertions(+), 5530 deletions(-) diff --git a/reactos/dll/win32/msi/action.c b/reactos/dll/win32/msi/action.c index 5fbac06169d..40fbd912569 100644 --- a/reactos/dll/win32/msi/action.c +++ b/reactos/dll/win32/msi/action.c @@ -3488,32 +3488,25 @@ end: return rc; } -static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) +static UINT msi_get_local_package_name( LPWSTR path ) { - static const WCHAR installerPathFmt[] = { - '%','s','\\','I','n','s','t','a','l','l','e','r','\\',0}; - static const WCHAR fmt[] = { - '%','s','\\', - 'I','n','s','t','a','l','l','e','r','\\', - '%','x','.','m','s','i',0}; - static const WCHAR szOriginalDatabase[] = - {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; - WCHAR windir[MAX_PATH], path[MAX_PATH], packagefile[MAX_PATH]; - INT num, start; - LPWSTR msiFilePath; - BOOL r; + static const WCHAR szInstaller[] = { + '\\','I','n','s','t','a','l','l','e','r','\\',0}; + static const WCHAR fmt[] = { '%','x','.','m','s','i',0}; + DWORD time, len, i; + HANDLE handle; - /* copy the package locally */ - num = GetTickCount() & 0xffff; - if (!num) - num = 1; - start = num; - GetWindowsDirectoryW( windir, MAX_PATH ); - snprintfW( packagefile, MAX_PATH, fmt, windir, num ); - do + time = GetTickCount(); + GetWindowsDirectoryW( path, MAX_PATH ); + lstrcatW( path, szInstaller ); + CreateDirectoryW( path, NULL ); + + len = lstrlenW(path); + for (i=0; i<0x10000; i++) { - HANDLE handle = CreateFileW(packagefile,GENERIC_WRITE, 0, NULL, - CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); + snprintfW( &path[len], MAX_PATH - len, fmt, (time+i)&0xffff ); + handle = CreateFileW( path, GENERIC_WRITE, 0, NULL, + CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); if (handle != INVALID_HANDLE_VALUE) { CloseHandle(handle); @@ -3521,13 +3514,23 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) } if (GetLastError() != ERROR_FILE_EXISTS && GetLastError() != ERROR_SHARING_VIOLATION) - break; - if (!(++num & 0xffff)) num = 1; - sprintfW(packagefile,fmt,num); - } while (num != start); + return ERROR_FUNCTION_FAILED; + } - snprintfW( path, MAX_PATH, installerPathFmt, windir ); - create_full_pathW(path); + return ERROR_SUCCESS; +} + +static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) +{ + static const WCHAR szOriginalDatabase[] = + {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; + WCHAR packagefile[MAX_PATH]; + LPWSTR msiFilePath; + UINT r; + + r = msi_get_local_package_name( packagefile ); + if (r != ERROR_SUCCESS) + return r; TRACE("Copying to local package %s\n",debugstr_w(packagefile)); diff --git a/reactos/dll/win32/msi/create.c b/reactos/dll/win32/msi/create.c index a8fe65caef6..740f563808f 100644 --- a/reactos/dll/win32/msi/create.c +++ b/reactos/dll/win32/msi/create.c @@ -221,17 +221,35 @@ static const MSIVIEWOPS create_ops = CREATE_delete }; +static UINT check_columns( column_info *col_info ) +{ + column_info *c1, *c2; + + /* check for two columns with the same name */ + for( c1 = col_info; c1; c1 = c1->next ) + for( c2 = c1->next; c2; c2 = c2->next ) + if (!lstrcmpW(c1->column, c2->column)) + return ERROR_BAD_QUERY_SYNTAX; + + return ERROR_SUCCESS; +} + UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, column_info *col_info, BOOL temp ) { MSICREATEVIEW *cv = NULL; + UINT r; TRACE("%p\n", cv ); + r = check_columns( col_info ); + if( r != ERROR_SUCCESS ) + return r; + cv = msi_alloc_zero( sizeof *cv ); if( !cv ) return ERROR_FUNCTION_FAILED; - + /* fill the structure */ cv->view.ops = &create_ops; msiobj_addref( &db->hdr ); diff --git a/reactos/dll/win32/msi/custom.c b/reactos/dll/win32/msi/custom.c index 4c824bf1209..dad67a22824 100644 --- a/reactos/dll/win32/msi/custom.c +++ b/reactos/dll/win32/msi/custom.c @@ -117,6 +117,31 @@ static BOOL check_execution_scheduling_options(MSIPACKAGE *package, LPCWSTR acti return TRUE; } +/* stores the CustomActionData before the action: + * [CustomActionData]Action + */ +LPWSTR msi_get_deferred_action(LPCWSTR action, LPWSTR actiondata) +{ + LPWSTR deferred; + DWORD len; + + static const WCHAR begin[] = {'[',0}; + static const WCHAR end[] = {']',0}; + + if (!actiondata) + return strdupW(action); + + len = lstrlenW(action) + lstrlenW(actiondata) + 3; + deferred = msi_alloc(len * sizeof(WCHAR)); + + lstrcpyW(deferred, begin); + lstrcatW(deferred, actiondata); + lstrcatW(deferred, end); + lstrcatW(deferred, action); + + return deferred; +} + UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute) { UINT rc = ERROR_SUCCESS; @@ -128,8 +153,18 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute) '=',' ','\'','%','s','\'',0}; UINT type; LPCWSTR source, target; + LPWSTR ptr, deferred_data = NULL; + LPWSTR action_copy = strdupW(action); WCHAR *deformated=NULL; + /* deferred action: [CustomActionData]Action */ + if ((ptr = strchrW(action_copy, ']'))) + { + deferred_data = action_copy + 1; + *ptr = '\0'; + action = ptr + 1; + } + row = MSI_QueryGetRecord( package->db, ExecSeqQuery, action ); if (!row) return ERROR_CALL_NOT_IMPLEMENTED; @@ -160,18 +195,22 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute) } if (!execute) { + LPWSTR actiondata = msi_dup_property(package, action); + LPWSTR deferred = msi_get_deferred_action(action, actiondata); + if (type & msidbCustomActionTypeCommit) { TRACE("Deferring Commit Action!\n"); - schedule_action(package, COMMIT_SCRIPT, action); + schedule_action(package, COMMIT_SCRIPT, deferred); } else { TRACE("Deferring Action!\n"); - schedule_action(package, INSTALL_SCRIPT, action); + schedule_action(package, INSTALL_SCRIPT, deferred); } rc = ERROR_SUCCESS; + msi_free(deferred); goto end; } else @@ -182,7 +221,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute) 'C','u','s','t','o','m','A','c','t','i','o','n','D','a','t','a',0}; static const WCHAR szBlank[] = {0}; LPWSTR actiondata = msi_dup_property( package, action ); - if (actiondata) + if (deferred_data) + MSI_SetPropertyW(package,szActionData,deferred_data); + else if (actiondata) MSI_SetPropertyW(package,szActionData,actiondata); else MSI_SetPropertyW(package,szActionData,szBlank); @@ -235,6 +276,7 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute) } end: + msi_free(action_copy); msiobj_release(&row->hdr); return rc; } diff --git a/reactos/dll/win32/msi/database.c b/reactos/dll/win32/msi/database.c index 609db238988..b92d3bf27a6 100644 --- a/reactos/dll/win32/msi/database.c +++ b/reactos/dll/win32/msi/database.c @@ -287,18 +287,144 @@ end: return r; } +static UINT msi_export_record( HANDLE handle, MSIRECORD *row, UINT start ) +{ + UINT i, count, len, r = ERROR_SUCCESS; + const char *sep; + char *buffer; + DWORD sz; + + len = 0x100; + buffer = msi_alloc( len ); + if ( !buffer ) + return ERROR_OUTOFMEMORY; + + count = MSI_RecordGetFieldCount( row ); + for ( i=start; i<=count; i++ ) + { + sz = len; + r = MSI_RecordGetStringA( row, i, buffer, &sz ); + if (r == ERROR_MORE_DATA) + { + char *p = msi_realloc( buffer, sz + 1 ); + if (!p) + break; + len = sz + 1; + buffer = p; + } + sz = len; + r = MSI_RecordGetStringA( row, i, buffer, &sz ); + if (r != ERROR_SUCCESS) + break; + + if (!WriteFile( handle, buffer, sz, &sz, NULL )) + { + r = ERROR_FUNCTION_FAILED; + break; + } + + sep = (i < count) ? "\t" : "\r\n"; + if (!WriteFile( handle, sep, strlen(sep), &sz, NULL )) + { + r = ERROR_FUNCTION_FAILED; + break; + } + } + msi_free( buffer ); + return r; +} + +static UINT msi_export_row( MSIRECORD *row, void *arg ) +{ + return msi_export_record( arg, row, 1 ); +} + UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, LPCWSTR folder, LPCWSTR file ) { - FIXME("%p %s %s %s\n", db, debugstr_w(table), + static const WCHAR query[] = { + 's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','%','s',0 }; + static const WCHAR szbs[] = { '\\', 0 }; + MSIRECORD *rec = NULL; + MSIQUERY *view = NULL; + LPWSTR filename; + HANDLE handle; + UINT len, r; + + TRACE("%p %s %s %s\n", db, debugstr_w(table), debugstr_w(folder), debugstr_w(file) ); if( folder == NULL || file == NULL ) return ERROR_INVALID_PARAMETER; - - return ERROR_CALL_NOT_IMPLEMENTED; + + len = lstrlenW(folder) + lstrlenW(file) + 2; + filename = msi_alloc(len * sizeof (WCHAR)); + if (!filename) + return ERROR_OUTOFMEMORY; + + lstrcpyW( filename, folder ); + lstrcatW( filename, szbs ); + lstrcatW( filename, file ); + + handle = CreateFileW( filename, GENERIC_READ | GENERIC_WRITE, 0, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + msi_free( filename ); + if (handle == INVALID_HANDLE_VALUE) + return ERROR_FUNCTION_FAILED; + + r = MSI_OpenQuery( db, &view, query, table ); + if (r == ERROR_SUCCESS) + { + /* write out row 1, the column names */ + r = MSI_ViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); + if (r == ERROR_SUCCESS) + { + msi_export_record( handle, rec, 1 ); + msiobj_release( &rec->hdr ); + } + + /* write out row 2, the column types */ + r = MSI_ViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); + if (r == ERROR_SUCCESS) + { + msi_export_record( handle, rec, 1 ); + msiobj_release( &rec->hdr ); + } + + /* write out row 3, the table name + keys */ + r = MSI_DatabaseGetPrimaryKeys( db, table, &rec ); + if (r == ERROR_SUCCESS) + { + MSI_RecordSetStringW( rec, 0, table ); + msi_export_record( handle, rec, 0 ); + msiobj_release( &rec->hdr ); + } + + /* write out row 4 onwards, the data */ + r = MSI_IterateRecords( view, 0, msi_export_row, handle ); + msiobj_release( &view->hdr ); + } + + CloseHandle( handle ); + + return r; } +/*********************************************************************** + * MsiExportDatabaseW [MSI.@] + * + * Writes a file containing the table data as tab separated ASCII. + * + * The format is as follows: + * + * row1 : colname1 colname2 .... colnameN + * row2 : coltype1 coltype2 .... coltypeN + * row3 : tablename key1 key2 ... keyM + * + * Followed by the data, starting at row 1 with one row per line + * + * row4 : data data data ... data + */ UINT WINAPI MsiDatabaseExportW( MSIHANDLE handle, LPCWSTR szTable, LPCWSTR szFolder, LPCWSTR szFilename ) { diff --git a/reactos/dll/win32/msi/dialog.c b/reactos/dll/win32/msi/dialog.c index f5096550509..aa0e2ae88b4 100644 --- a/reactos/dll/win32/msi/dialog.c +++ b/reactos/dll/win32/msi/dialog.c @@ -63,6 +63,7 @@ struct msi_control_tag HBITMAP hBitmap; HICON hIcon; LPWSTR tabnext; + LPWSTR type; HMODULE hDll; float progress_current; float progress_max; @@ -85,6 +86,7 @@ struct msi_dialog_tag BOOL finished; INT scale; DWORD attributes; + SIZE size; HWND hwnd; LPWSTR default_font; msi_font *font_list; @@ -177,6 +179,18 @@ static msi_control *msi_dialog_find_control( msi_dialog *dialog, LPCWSTR name ) return NULL; } +static msi_control *msi_dialog_find_control_by_type( msi_dialog *dialog, LPCWSTR type ) +{ + msi_control *control; + + if( !type ) + return NULL; + LIST_FOR_EACH_ENTRY( control, &dialog->controls, msi_control, entry ) + if( !strcmpW( control->type, type ) ) /* FIXME: case sensitive? */ + return control; + return NULL; +} + static msi_control *msi_dialog_find_control_by_hwnd( msi_dialog *dialog, HWND hwnd ) { msi_control *control; @@ -359,6 +373,7 @@ static msi_control *msi_dialog_create_window( msi_dialog *dialog, control->hIcon = NULL; control->hDll = NULL; control->tabnext = strdupW( MSI_RecordGetString( rec, 11) ); + control->type = strdupW( MSI_RecordGetString( rec, 3 ) ); control->progress_current = 0; control->progress_max = 100; @@ -393,6 +408,24 @@ static msi_control *msi_dialog_create_window( msi_dialog *dialog, return control; } +static LPWSTR msi_dialog_get_uitext( msi_dialog *dialog, LPCWSTR key ) +{ + MSIRECORD *rec; + LPWSTR text; + + static const WCHAR query[] = { + 's','e','l','e','c','t',' ','*',' ', + 'f','r','o','m',' ','`','U','I','T','e','x','t','`',' ', + 'w','h','e','r','e',' ','`','K','e','y','`',' ','=',' ','\'','%','s','\'',0 + }; + + rec = MSI_QueryGetRecord( dialog->package->db, query, key ); + if (!rec) return NULL; + text = strdupW( MSI_RecordGetString( rec, 2 ) ); + msiobj_release( &rec->hdr ); + return text; +} + static MSIRECORD *msi_get_binary_record( MSIDATABASE *db, LPCWSTR name ) { static const WCHAR query[] = { @@ -1374,6 +1407,13 @@ static UINT msi_dialog_progress_bar( msi_dialog *dialog, MSIRECORD *rec ) /******************** Path Edit ********************************************/ +struct msi_pathedit_info +{ + msi_dialog *dialog; + msi_control *control; + WNDPROC oldproc; +}; + static LPWSTR msi_get_window_text( HWND hwnd ) { UINT sz, r; @@ -1393,38 +1433,14 @@ static LPWSTR msi_get_window_text( HWND hwnd ) return buf; } -static UINT msi_dialog_pathedit_handler( msi_dialog *dialog, - msi_control *control, WPARAM param ) +static void msi_dialog_update_pathedit( msi_dialog *dialog, msi_control *control ) { - LPWSTR buf, prop; - BOOL indirect; - - if( HIWORD(param) != EN_KILLFOCUS ) - return ERROR_SUCCESS; - - indirect = control->attributes & msidbControlAttributesIndirect; - prop = msi_dialog_dup_property( dialog, control->property, indirect ); - - /* FIXME: verify the new path */ - buf = msi_get_window_text( control->hwnd ); - MSI_SetPropertyW( dialog->package, prop, buf ); - - TRACE("edit %s contents changed, set %s\n", debugstr_w(control->name), - debugstr_w(prop)); - - msi_free( buf ); - msi_free( prop ); - - return ERROR_SUCCESS; -} - -static void msi_dialog_update_pathedit( msi_dialog *dialog ) -{ - msi_control *control; LPWSTR prop, path; BOOL indirect; - control = msi_dialog_find_control( dialog, szPathEdit ); + if (!control && !(control = msi_dialog_find_control_by_type( dialog, szPathEdit ))) + return; + indirect = control->attributes & msidbControlAttributesIndirect; prop = msi_dialog_dup_property( dialog, control->property, indirect ); @@ -1436,19 +1452,102 @@ static void msi_dialog_update_pathedit( msi_dialog *dialog ) msi_free( prop ); } +/* FIXME: test when this should fail */ +static BOOL msi_dialog_verify_path( LPWSTR path ) +{ + if ( !lstrlenW( path ) ) + return FALSE; + + if ( PathIsRelativeW( path ) ) + return FALSE; + + return TRUE; +} + +/* returns TRUE if the path is valid, FALSE otherwise */ +static BOOL msi_dialog_onkillfocus( msi_dialog *dialog, msi_control *control ) +{ + LPWSTR buf, prop; + BOOL indirect; + BOOL valid; + + indirect = control->attributes & msidbControlAttributesIndirect; + prop = msi_dialog_dup_property( dialog, control->property, indirect ); + + buf = msi_get_window_text( control->hwnd ); + + if ( !msi_dialog_verify_path( buf ) ) + { + /* FIXME: display an error message box */ + ERR("Invalid path %s\n", debugstr_w( buf )); + valid = FALSE; + SetFocus( control->hwnd ); + } + else + { + valid = TRUE; + MSI_SetPropertyW( dialog->package, prop, buf ); + } + + msi_dialog_update_pathedit( dialog, control ); + + TRACE("edit %s contents changed, set %s\n", debugstr_w(control->name), + debugstr_w(prop)); + + msi_free( buf ); + msi_free( prop ); + + return valid; +} + +static LRESULT WINAPI MSIPathEdit_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + struct msi_pathedit_info *info = GetPropW(hWnd, szButtonData); + LRESULT r = 0; + + TRACE("%p %04x %08x %08lx\n", hWnd, msg, wParam, lParam); + + if ( msg == WM_KILLFOCUS ) + { + /* if the path is invalid, don't handle this message */ + if ( !msi_dialog_onkillfocus( info->dialog, info->control ) ) + return 0; + } + + r = CallWindowProcW(info->oldproc, hWnd, msg, wParam, lParam); + + if ( msg == WM_NCDESTROY ) + { + msi_free( info ); + RemovePropW( hWnd, szButtonData ); + } + + return r; +} + static UINT msi_dialog_pathedit_control( msi_dialog *dialog, MSIRECORD *rec ) { + struct msi_pathedit_info *info; msi_control *control; LPCWSTR prop; + info = msi_alloc( sizeof *info ); + if (!info) + return ERROR_FUNCTION_FAILED; + control = msi_dialog_add_control( dialog, rec, szEdit, WS_BORDER | WS_TABSTOP ); - control->handler = msi_dialog_pathedit_handler; control->attributes = MSI_RecordGetInteger( rec, 8 ); prop = MSI_RecordGetString( rec, 9 ); control->property = msi_dialog_dup_property( dialog, prop, FALSE ); - msi_dialog_update_pathedit( dialog ); + info->dialog = dialog; + info->control = control; + info->oldproc = (WNDPROC) SetWindowLongPtrW( control->hwnd, GWLP_WNDPROC, + (LONG_PTR)MSIPathEdit_WndProc ); + SetPropW( control->hwnd, szButtonData, info ); + + msi_dialog_update_pathedit( dialog, control ); return ERROR_SUCCESS; } @@ -1961,13 +2060,14 @@ static UINT msi_dialog_list_box( msi_dialog *dialog, MSIRECORD *rec ) /******************** Directory Combo ***************************************/ -static void msi_dialog_update_directory_combo( msi_dialog *dialog ) +static void msi_dialog_update_directory_combo( msi_dialog *dialog, msi_control *control ) { - msi_control *control; LPWSTR prop, path; BOOL indirect; - control = msi_dialog_find_control( dialog, szDirectoryCombo ); + if (!control && !(control = msi_dialog_find_control_by_type( dialog, szDirectoryCombo ))) + return; + indirect = control->attributes & msidbControlAttributesIndirect; prop = msi_dialog_dup_property( dialog, control->property, indirect ); path = msi_dup_property( dialog->package, prop ); @@ -1999,20 +2099,72 @@ static UINT msi_dialog_directory_combo( msi_dialog *dialog, MSIRECORD *rec ) prop = MSI_RecordGetString( rec, 9 ); control->property = msi_dialog_dup_property( dialog, prop, FALSE ); - msi_dialog_update_directory_combo( dialog ); + msi_dialog_update_directory_combo( dialog, control ); return ERROR_SUCCESS; } /******************** Directory List ***************************************/ +static void msi_dialog_update_directory_list( msi_dialog *dialog, msi_control *control ) +{ + WCHAR dir_spec[MAX_PATH]; + WIN32_FIND_DATAW wfd; + LPWSTR prop, path; + BOOL indirect; + LVITEMW item; + HANDLE file; + + static const WCHAR asterisk[] = {'*',0}; + static const WCHAR dot[] = {'.',0}; + static const WCHAR dotdot[] = {'.','.',0}; + + if (!control && !(control = msi_dialog_find_control_by_type( dialog, szDirectoryList ))) + return; + + /* clear the list-view */ + SendMessageW( control->hwnd, LVM_DELETEALLITEMS, 0, 0 ); + + indirect = control->attributes & msidbControlAttributesIndirect; + prop = msi_dialog_dup_property( dialog, control->property, indirect ); + path = msi_dup_property( dialog->package, prop ); + + lstrcpyW( dir_spec, path ); + lstrcatW( dir_spec, asterisk ); + + file = FindFirstFileW( dir_spec, &wfd ); + if ( file == INVALID_HANDLE_VALUE ) + return; + + do + { + if ( wfd.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY ) + continue; + + if ( !lstrcmpW( wfd.cFileName, dot ) || !lstrcmpW( wfd.cFileName, dotdot ) ) + continue; + + item.mask = LVIF_TEXT; + item.cchTextMax = MAX_PATH; + item.iItem = 0; + item.iSubItem = 0; + item.pszText = wfd.cFileName; + + SendMessageW( control->hwnd, LVM_INSERTITEMW, 0, (LPARAM)&item ); + } while ( FindNextFileW( file, &wfd ) ); + + msi_free( prop ); + msi_free( path ); + FindClose( file ); +} + UINT msi_dialog_directorylist_up( msi_dialog *dialog ) { msi_control *control; LPWSTR prop, path, ptr; BOOL indirect; - control = msi_dialog_find_control( dialog, szDirectoryList ); + control = msi_dialog_find_control_by_type( dialog, szDirectoryList ); indirect = control->attributes & msidbControlAttributesIndirect; prop = msi_dialog_dup_property( dialog, control->property, indirect ); @@ -2025,8 +2177,9 @@ UINT msi_dialog_directorylist_up( msi_dialog *dialog ) MSI_SetPropertyW( dialog->package, prop, path ); - msi_dialog_update_directory_combo( dialog ); - msi_dialog_update_pathedit( dialog ); + msi_dialog_update_directory_list( dialog, NULL ); + msi_dialog_update_directory_combo( dialog, NULL ); + msi_dialog_update_pathedit( dialog, NULL ); msi_free( path ); msi_free( prop ); @@ -2034,13 +2187,60 @@ UINT msi_dialog_directorylist_up( msi_dialog *dialog ) return ERROR_SUCCESS; } +static UINT msi_dialog_dirlist_handler( msi_dialog *dialog, + msi_control *control, WPARAM param ) +{ + LPNMHDR nmhdr = (LPNMHDR)param; + WCHAR new_path[MAX_PATH]; + WCHAR text[MAX_PATH]; + LPWSTR path, prop; + BOOL indirect; + LVITEMW item; + int index; + + static const WCHAR backslash[] = {'\\',0}; + + if (nmhdr->code != LVN_ITEMACTIVATE) + return ERROR_SUCCESS; + + index = SendMessageW( control->hwnd, LVM_GETNEXTITEM, -1, LVNI_SELECTED ); + if ( index < 0 ) + { + ERR("No list-view item selected!\n"); + return ERROR_FUNCTION_FAILED; + } + + item.iSubItem = 0; + item.pszText = text; + item.cchTextMax = MAX_PATH; + SendMessageW( control->hwnd, LVM_GETITEMTEXTW, index, (LPARAM)&item ); + + indirect = control->attributes & msidbControlAttributesIndirect; + prop = msi_dialog_dup_property( dialog, control->property, indirect ); + path = msi_dup_property( dialog->package, prop ); + + lstrcpyW( new_path, path ); + lstrcatW( new_path, text ); + lstrcatW( new_path, backslash ); + + MSI_SetPropertyW( dialog->package, prop, new_path ); + + msi_dialog_update_directory_list( dialog, NULL ); + msi_dialog_update_directory_combo( dialog, NULL ); + msi_dialog_update_pathedit( dialog, NULL ); + + msi_free( prop ); + msi_free( path ); + return ERROR_SUCCESS; +} + static UINT msi_dialog_directory_list( msi_dialog *dialog, MSIRECORD *rec ) { msi_control *control; LPCWSTR prop; DWORD style; - style = LVS_LIST | LVS_EDITLABELS | WS_VSCROLL | LVS_SHAREIMAGELISTS | + style = LVS_LIST | WS_VSCROLL | LVS_SHAREIMAGELISTS | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_BORDER | LVS_SORTASCENDING | WS_CHILD | WS_GROUP | WS_TABSTOP; control = msi_dialog_add_control( dialog, rec, WC_LISTVIEWW, style ); @@ -2048,14 +2248,86 @@ static UINT msi_dialog_directory_list( msi_dialog *dialog, MSIRECORD *rec ) return ERROR_FUNCTION_FAILED; control->attributes = MSI_RecordGetInteger( rec, 8 ); + control->handler = msi_dialog_dirlist_handler; prop = MSI_RecordGetString( rec, 9 ); control->property = msi_dialog_dup_property( dialog, prop, FALSE ); + /* double click to activate an item in the list */ + SendMessageW( control->hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, + 0, LVS_EX_TWOCLICKACTIVATE ); + + msi_dialog_update_directory_list( dialog, control ); + return ERROR_SUCCESS; } /******************** VolumeCost List ***************************************/ +static BOOL str_is_number( LPCWSTR str ) +{ + int i; + + for (i = 0; i < lstrlenW( str ); i++) + if (!isdigitW(str[i])) + return FALSE; + + return TRUE; +} + +WCHAR column_keys[][80] = +{ + {'V','o','l','u','m','e','C','o','s','t','V','o','l','u','m','e',0}, + {'V','o','l','u','m','e','C','o','s','t','S','i','z','e',0}, + {'V','o','l','u','m','e','C','o','s','t','A','v','a','i','l','a','b','l','e',0}, + {'V','o','l','u','m','e','C','o','s','t','R','e','q','u','i','r','e','d',0}, + {'V','o','l','u','m','e','C','o','s','t','D','i','f','f','e','r','e','n','c','e',0} +}; + +static void msi_dialog_vcl_add_columns( msi_dialog *dialog, msi_control *control, MSIRECORD *rec ) +{ + LPCWSTR text = MSI_RecordGetString( rec, 10 ); + LPCWSTR begin = text, end; + WCHAR num[10]; + LVCOLUMNW lvc; + DWORD count = 0; + LRESULT r; + + static const WCHAR zero[] = {'0',0}; + static const WCHAR negative[] = {'-',0}; + + while ((begin = strchrW( begin, '{' )) && count < 5) + { + if (!(end = strchrW( begin, '}' ))) + return; + + lstrcpynW( num, begin + 1, end - begin ); + begin += end - begin + 1; + + /* empty braces or '0' hides the column */ + if ( !num[0] || !lstrcmpW( num, zero ) ) + { + count++; + continue; + } + + /* the width must be a positive number + * if a width is invalid, all remaining columns are hidden + */ + if ( !strncmpW( num, negative, 1 ) || !str_is_number( num ) ) + return; + + lvc.mask = LVCF_FMT | LVCF_ORDER | LVCF_WIDTH | LVCF_TEXT; + lvc.iOrder = count; + lvc.pszText = msi_dialog_get_uitext( dialog, column_keys[count++] ); + lvc.cx = atolW( num ); + lvc.fmt = LVCFMT_LEFT; + + r = SendMessageW( control->hwnd, LVM_INSERTCOLUMNW, 0, (LPARAM)&lvc ); + msi_free( lvc.pszText ); + if ( r ) return; + } +} + static UINT msi_dialog_volumecost_list( msi_dialog *dialog, MSIRECORD *rec ) { msi_control *control; @@ -2068,6 +2340,8 @@ static UINT msi_dialog_volumecost_list( msi_dialog *dialog, MSIRECORD *rec ) if (!control) return ERROR_FUNCTION_FAILED; + msi_dialog_vcl_add_columns( dialog, control, rec ); + return ERROR_SUCCESS; } @@ -2292,10 +2566,27 @@ static void msi_dialog_adjust_dialog_pos( msi_dialog *dialog, MSIRECORD *rec, LP center.y = MulDiv( center.y, yres, 100 ); /* turn the client pos into the window rectangle */ - pos->left = center.x - sz.cx/2; - pos->right = pos->left + sz.cx; - pos->top = center.y - sz.cy/2; - pos->bottom = pos->top + sz.cy; + if (dialog->package->center_x && dialog->package->center_y) + { + pos->left = dialog->package->center_x - sz.cx / 2.0; + pos->right = pos->left + sz.cx; + pos->top = dialog->package->center_y - sz.cy / 2.0; + pos->bottom = pos->top + sz.cy; + } + else + { + pos->left = center.x - sz.cx/2; + pos->right = pos->left + sz.cx; + pos->top = center.y - sz.cy/2; + pos->bottom = pos->top + sz.cy; + + /* save the center */ + dialog->package->center_x = center.x; + dialog->package->center_y = center.y; + } + + dialog->size.cx = sz.cx; + dialog->size.cy = sz.cy; TRACE("%lu %lu %lu %lu\n", pos->left, pos->top, pos->right, pos->bottom); @@ -2609,6 +2900,19 @@ static LRESULT msi_dialog_oncommand( msi_dialog *dialog, WPARAM param, HWND hwnd return 0; } +static LRESULT msi_dialog_onnotify( msi_dialog *dialog, LPARAM param ) +{ + LPNMHDR nmhdr = (LPNMHDR) param; + msi_control *control = msi_dialog_find_control_by_hwnd( dialog, nmhdr->hwndFrom ); + + TRACE("%p %p", dialog, nmhdr->hwndFrom); + + if ( control && control->handler ) + control->handler( dialog, control, param ); + + return 0; +} + static void msi_dialog_setfocus( msi_dialog *dialog ) { HWND hwnd = dialog->hWndFocus; @@ -2628,6 +2932,11 @@ static LRESULT WINAPI MSIDialog_WndProc( HWND hwnd, UINT msg, switch (msg) { + case WM_MOVE: + dialog->package->center_x = LOWORD(lParam) + dialog->size.cx / 2.0; + dialog->package->center_y = HIWORD(lParam) + dialog->size.cy / 2.0; + break; + case WM_CREATE: return msi_dialog_oncreate( hwnd, (LPCREATESTRUCTW)lParam ); @@ -2652,6 +2961,8 @@ static LRESULT WINAPI MSIDialog_WndProc( HWND hwnd, UINT msg, case WM_DESTROY: dialog->hwnd = NULL; return 0; + case WM_NOTIFY: + return msi_dialog_onnotify( dialog, lParam ); } return DefWindowProcW(hwnd, msg, wParam, lParam); } @@ -2861,6 +3172,7 @@ void msi_dialog_destroy( msi_dialog *dialog ) if( t->hIcon ) DestroyIcon( t->hIcon ); msi_free( t->tabnext ); + msi_free( t->type ); msi_free( t ); if (t->hDll) FreeLibrary( t->hDll ); diff --git a/reactos/dll/win32/msi/format.c b/reactos/dll/win32/msi/format.c index b0d9d5219a5..290908947de 100644 --- a/reactos/dll/win32/msi/format.c +++ b/reactos/dll/win32/msi/format.c @@ -50,19 +50,53 @@ static LPWSTR build_default_format(MSIRECORD* record) { int i; int count; - LPWSTR rc; - static const WCHAR fmt[] = {'%','i',':',' ','[','%','i',']',' ',0}; - WCHAR buf[11]; + LPWSTR rc, buf; + static const WCHAR fmt[] = {'%','i',':',' ','%','s',' ',0}; + static const WCHAR fmt_null[] = {'%','i',':',' ',' ',0}; + static const WCHAR fmt_index[] = {'%','i',0}; + LPCWSTR str; + WCHAR index[10]; + DWORD size, max_len, len; count = MSI_RecordGetFieldCount(record); - rc = msi_alloc((11*count)*sizeof(WCHAR)); - rc[0] = 0; + max_len = MAX_PATH; + buf = msi_alloc((max_len + 1) * sizeof(WCHAR)); + + rc = NULL; + size = 1; for (i = 1; i <= count; i++) { - sprintfW(buf,fmt,i,i); - strcatW(rc,buf); + sprintfW(index,fmt_index,i); + str = MSI_RecordGetString(record, i); + len = (str) ? lstrlenW(str) : 0; + len += (sizeof(fmt_null) - 3) + lstrlenW(index); + size += len; + + if (len > max_len) + { + max_len = len; + buf = msi_realloc(buf, (max_len + 1) * sizeof(WCHAR)); + if (!buf) return NULL; + } + + if (str) + sprintfW(buf,fmt,i,str); + else + sprintfW(buf,fmt_null,i); + + if (!rc) + { + rc = msi_alloc(size * sizeof(WCHAR)); + lstrcpyW(rc, buf); + } + else + { + rc = msi_realloc(rc, size * sizeof(WCHAR)); + lstrcatW(rc, buf); + } } + msi_free(buf); return rc; } @@ -131,8 +165,8 @@ static LPWSTR deformat_file(MSIPACKAGE* package, LPCWSTR key, DWORD* sz, { ERR("Unable to get ShortPath size (%s)\n", debugstr_w( file->TargetPath) ); - value = NULL; - *sz = 0; + value = strdupW( file->TargetPath ); + *sz = (lstrlenW(value)) * sizeof(WCHAR); } } } diff --git a/reactos/dll/win32/msi/insert.c b/reactos/dll/win32/msi/insert.c index 85c9f51a3f7..2b0f68a70ca 100644 --- a/reactos/dll/win32/msi/insert.c +++ b/reactos/dll/win32/msi/insert.c @@ -66,7 +66,6 @@ static MSIRECORD *INSERT_merge_record( UINT fields, column_info *vl, MSIRECORD * { MSIRECORD *merged; DWORD wildcard_count = 1, i; - const WCHAR *str; merged = MSI_CreateRecord( fields ); for( i=1; i <= fields; i++ ) @@ -88,10 +87,7 @@ static MSIRECORD *INSERT_merge_record( UINT fields, column_info *vl, MSIRECORD * case EXPR_WILDCARD: if( !rec ) goto err; - if( MSI_RecordIsNull( rec, wildcard_count ) ) - goto err; - str = MSI_RecordGetString( rec, wildcard_count ); - MSI_RecordSetStringW( merged, i, str ); + MSI_RecordCopyField( rec, wildcard_count, merged, i ); wildcard_count++; break; default: @@ -238,6 +234,14 @@ static const MSIVIEWOPS insert_ops = INSERT_find_matching_rows }; +static UINT count_column_info( column_info *ci ) +{ + UINT n = 0; + for ( ; ci; ci = ci->next ) + n++; + return n; +} + UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, column_info *columns, column_info *values, BOOL temp ) { @@ -247,6 +251,10 @@ UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, TRACE("%p\n", iv ); + /* there should be one value for each column */ + if ( count_column_info( columns ) != count_column_info(values) ) + return ERROR_BAD_QUERY_SYNTAX; + r = TABLE_CreateView( db, table, &tv ); if( r != ERROR_SUCCESS ) return r; @@ -258,7 +266,7 @@ UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, tv->ops->delete( tv ); return r; } - + iv = msi_alloc_zero( sizeof *iv ); if( !iv ) return ERROR_FUNCTION_FAILED; diff --git a/reactos/dll/win32/msi/join.c b/reactos/dll/win32/msi/join.c index 17f04c0a9e2..fda6b1b309b 100644 --- a/reactos/dll/win32/msi/join.c +++ b/reactos/dll/win32/msi/join.c @@ -364,7 +364,7 @@ static const MSIVIEWOPS join_ops = */ static UINT join_check_condition(MSIJOINVIEW *jv, struct expr *cond) { - UINT r, type = 0; + UINT r; /* assume that we have `KeyColumn` = `SubkeyColumn` */ if ( cond->type != EXPR_COMPLEX ) @@ -388,21 +388,6 @@ static UINT join_check_condition(MSIJOINVIEW *jv, struct expr *cond) if (r != ERROR_SUCCESS) return ERROR_FUNCTION_FAILED; - /* make sure both columns are keys */ - r = jv->left->ops->get_column_info( jv->left, jv->left_key, NULL, &type ); - if (r != ERROR_SUCCESS) - return ERROR_FUNCTION_FAILED; - - if (!(type & MSITYPE_KEY)) - return ERROR_FUNCTION_FAILED; - - r = jv->right->ops->get_column_info( jv->right, jv->right_key, NULL, &type ); - if (r != ERROR_SUCCESS) - return ERROR_FUNCTION_FAILED; - - if (!(type & MSITYPE_KEY)) - return ERROR_FUNCTION_FAILED; - TRACE("left %s (%u) right %s (%u)\n", debugstr_w(cond->u.expr.left->u.column), jv->left_key, debugstr_w(cond->u.expr.right->u.column), jv->right_key); diff --git a/reactos/dll/win32/msi/msi_ros.diff b/reactos/dll/win32/msi/msi_ros.diff index 57c22de2d8f..e779ac1ff8e 100644 --- a/reactos/dll/win32/msi/msi_ros.diff +++ b/reactos/dll/win32/msi/msi_ros.diff @@ -1,5346 +1,5355 @@ -Index: action.c -=================================================================== ---- action.c (revision 23808) -+++ action.c (working copy) -@@ -30,6 +30,7 @@ - - #define COBJMACROS - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winerror.h" -Index: appsearch.c -=================================================================== ---- appsearch.c (revision 23782) -+++ appsearch.c (working copy) -@@ -21,6 +21,7 @@ - - #define COBJMACROS - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winreg.h" -Index: classes.c -=================================================================== ---- classes.c (revision 23808) -+++ classes.c (working copy) -@@ -31,6 +31,7 @@ - - #include - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winerror.h" -Index: cond.tab.c -=================================================================== ---- cond.tab.c (revision 23782) -+++ cond.tab.c (working copy) -@@ -0,0 +1,2239 @@ -+/* A Bison parser, made by GNU Bison 1.875c. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -+ -+ 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, 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., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Written by Richard Stallman by simplifying the original so called -+ ``semantic'' parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 1 -+ -+/* Using locations. */ -+#define YYLSP_NEEDED 0 -+ -+/* If NAME_PREFIX is specified substitute the variables and functions -+ names. */ -+#define yyparse COND_parse -+#define yylex COND_lex -+#define yyerror COND_error -+#define yylval COND_lval -+#define yychar COND_char -+#define yydebug COND_debug -+#define yynerrs COND_nerrs -+ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COND_SPACE = 258, -+ COND_EOF = 259, -+ COND_OR = 260, -+ COND_AND = 261, -+ COND_NOT = 262, -+ COND_LT = 263, -+ COND_GT = 264, -+ COND_EQ = 265, -+ COND_LPAR = 266, -+ COND_RPAR = 267, -+ COND_TILDA = 268, -+ COND_PERCENT = 269, -+ COND_DOLLARS = 270, -+ COND_QUESTION = 271, -+ COND_AMPER = 272, -+ COND_EXCLAM = 273, -+ COND_IDENT = 274, -+ COND_NUMBER = 275, -+ COND_LITER = 276, -+ COND_ERROR = 277 -+ }; -+#endif -+#define COND_SPACE 258 -+#define COND_EOF 259 -+#define COND_OR 260 -+#define COND_AND 261 -+#define COND_NOT 262 -+#define COND_LT 263 -+#define COND_GT 264 -+#define COND_EQ 265 -+#define COND_LPAR 266 -+#define COND_RPAR 267 -+#define COND_TILDA 268 -+#define COND_PERCENT 269 -+#define COND_DOLLARS 270 -+#define COND_QUESTION 271 -+#define COND_AMPER 272 -+#define COND_EXCLAM 273 -+#define COND_IDENT 274 -+#define COND_NUMBER 275 -+#define COND_LITER 276 -+#define COND_ERROR 277 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+#line 1 "./cond.y" -+ -+ -+/* -+ * Implementation of the Microsoft Installer (msi.dll) -+ * -+ * Copyright 2003 Mike McCormack for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "wine/debug.h" -+#include "wine/unicode.h" -+ -+#include "msi.h" -+#include "msiquery.h" -+#include "msipriv.h" -+ -+#define YYLEX_PARAM info -+#define YYPARSE_PARAM info -+ -+static int COND_error(const char *str); -+ -+WINE_DEFAULT_DEBUG_CHANNEL(msi); -+ -+typedef struct tag_yyinput -+{ -+ MSIPACKAGE *package; -+ LPCWSTR str; -+ INT n; -+ MSICONDITION result; -+} COND_input; -+ -+struct cond_str { -+ LPCWSTR data; -+ INT len; -+}; -+ -+static LPWSTR COND_GetString( struct cond_str *str ); -+static LPWSTR COND_GetLiteral( struct cond_str *str ); -+static int COND_lex( void *COND_lval, COND_input *info); -+ -+typedef INT (*comp_int)(INT a, INT b); -+typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless); -+typedef INT (*comp_m1)(LPWSTR a,int b); -+typedef INT (*comp_m2)(int a,LPWSTR b); -+ -+static INT comp_lt_i(INT a, INT b); -+static INT comp_gt_i(INT a, INT b); -+static INT comp_le_i(INT a, INT b); -+static INT comp_ge_i(INT a, INT b); -+static INT comp_eq_i(INT a, INT b); -+static INT comp_ne_i(INT a, INT b); -+static INT comp_bitand(INT a, INT b); -+static INT comp_highcomp(INT a, INT b); -+static INT comp_lowcomp(INT a, INT b); -+ -+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless); -+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless); -+ -+static INT comp_eq_m1(LPWSTR a, INT b); -+static INT comp_ne_m1(LPWSTR a, INT b); -+static INT comp_lt_m1(LPWSTR a, INT b); -+static INT comp_gt_m1(LPWSTR a, INT b); -+static INT comp_le_m1(LPWSTR a, INT b); -+static INT comp_ge_m1(LPWSTR a, INT b); -+ -+static INT comp_eq_m2(INT a, LPWSTR b); -+static INT comp_ne_m2(INT a, LPWSTR b); -+static INT comp_lt_m2(INT a, LPWSTR b); -+static INT comp_gt_m2(INT a, LPWSTR b); -+static INT comp_le_m2(INT a, LPWSTR b); -+static INT comp_ge_m2(INT a, LPWSTR b); -+ -+ -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 106 "./cond.y" -+typedef union YYSTYPE { -+ struct cond_str str; -+ LPWSTR string; -+ INT value; -+ comp_int fn_comp_int; -+ comp_str fn_comp_str; -+ comp_m1 fn_comp_m1; -+ comp_m2 fn_comp_m2; -+} YYSTYPE; -+/* Line 191 of yacc.c. */ -+#line 241 "cond.tab.c" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+/* Copy the second part of user declarations. */ -+ -+ -+/* Line 214 of yacc.c. */ -+#line 253 "cond.tab.c" -+ -+#if ! defined (yyoverflow) || YYERROR_VERBOSE -+ -+# ifndef YYFREE -+# define YYFREE free -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# endif -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# define YYSTACK_ALLOC alloca -+# endif -+# else -+# if defined (alloca) || defined (_ALLOCA_H) -+# define YYSTACK_ALLOC alloca -+# else -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+# else -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# endif -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# endif -+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ -+ -+ -+#if (! defined (yyoverflow) \ -+ && (! defined (__cplusplus) \ -+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ short yyss; -+ YYSTYPE yyvs; -+ }; -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ -+ + YYSTACK_GAP_MAXIMUM) -+ -+/* Copy COUNT objects from FROM to TO. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined (__GNUC__) && 1 < __GNUC__ -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# else -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ register YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (0) -+# endif -+# endif -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack, Stack, yysize); \ -+ Stack = &yyptr->Stack; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) -+ -+#endif -+ -+#if defined (__STDC__) || defined (__cplusplus) -+ typedef signed char yysigned_char; -+#else -+ typedef short yysigned_char; -+#endif -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 30 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 146 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 23 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 17 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 65 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 74 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 277 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const unsigned char yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22 -+}; -+ -+#if YYDEBUG -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const unsigned char yyprhs[] = -+{ -+ 0, 0, 3, 5, 7, 11, 13, 17, 19, 22, -+ 24, 26, 30, 34, 39, 43, 47, 51, 53, 56, -+ 58, 60, 63, 66, 69, 72, 75, 77, 80, 82, -+ 84, 87, 90, 93, 96, 99, 101, 104, 106, 108, -+ 111, 114, 117, 120, 123, 125, 128, 130, 132, 135, -+ 138, 141, 144, 147, 149, 151, 153, 155, 157, 160, -+ 163, 166, 169, 171, 174, 176 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yysigned_char yyrhs[] = -+{ -+ 24, 0, -1, 25, -1, 26, -1, 26, 5, 25, -+ -1, 27, -1, 26, 6, 27, -1, 28, -1, 7, -+ 28, -1, 33, -1, 34, -1, 33, 29, 33, -1, -+ 34, 30, 34, -1, 34, 13, 30, 34, -1, 34, -+ 31, 33, -1, 33, 32, 34, -1, 11, 25, 12, -+ -1, 10, -1, 8, 9, -1, 8, -1, 9, -1, -+ 8, 10, -1, 9, 10, -1, 9, 8, -1, 8, -+ 8, -1, 9, 9, -1, 10, -1, 8, 9, -1, -+ 8, -1, 9, -1, 8, 10, -1, 9, 10, -1, -+ 9, 8, -1, 8, 8, -1, 9, 9, -1, 10, -+ -1, 8, 9, -1, 8, -1, 9, -1, 8, 10, -+ -1, 9, 10, -1, 9, 8, -1, 8, 8, -1, -+ 9, 9, -1, 10, -1, 8, 9, -1, 8, -1, -+ 9, -1, 8, 10, -1, 9, 10, -1, 9, 8, -+ -1, 8, 8, -1, 9, 9, -1, 36, -1, 39, -+ -1, 37, -1, 35, -1, 21, -1, 15, 38, -1, -+ 16, 38, -1, 17, 38, -1, 18, 38, -1, 38, -+ -1, 14, 38, -1, 19, -1, 20, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const unsigned short yyrline[] = -+{ -+ 0, 136, 136, 144, 148, 155, 159, 166, 170, 178, -+ 182, 187, 191, 197, 203, 208, 213, 221, 225, 229, -+ 233, 237, 241, 246, 250, 254, 262, 266, 270, 274, -+ 278, 282, 287, 291, 295, 303, 307, 311, 315, 319, -+ 323, 328, 332, 336, 344, 348, 352, 356, 360, 364, -+ 369, 373, 377, 384, 388, 395, 399, 406, 415, 424, -+ 433, 442, 454, 477, 491, 500 -+}; -+#endif -+ -+#if YYDEBUG || YYERROR_VERBOSE -+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR", -+ "COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR", -+ "COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS", -+ "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT", -+ "COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition", -+ "expression", "boolean_term", "boolean_factor", "term", "comp_op_i", -+ "comp_op_s", "comp_op_m1", "comp_op_m2", "value_i", "value_s", "literal", -+ "symbol_i", "symbol_s", "identifier", "integer", 0 -+}; -+#endif -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const unsigned short yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -+ 275, 276, 277 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const unsigned char yyr1[] = -+{ -+ 0, 23, 24, 25, 25, 26, 26, 27, 27, 28, -+ 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, -+ 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, -+ 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, -+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, -+ 32, 32, 32, 33, 33, 34, 34, 35, 36, 36, -+ 36, 36, 37, 37, 38, 39 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const unsigned char yyr2[] = -+{ -+ 0, 2, 1, 1, 3, 1, 3, 1, 2, 1, -+ 1, 3, 3, 4, 3, 3, 3, 1, 2, 1, -+ 1, 2, 2, 2, 2, 2, 1, 2, 1, 1, -+ 2, 2, 2, 2, 2, 1, 2, 1, 1, 2, -+ 2, 2, 2, 2, 1, 2, 1, 1, 2, 2, -+ 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, -+ 2, 2, 1, 2, 1, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state -+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const unsigned char yydefact[] = -+{ -+ 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, -+ 57, 0, 2, 3, 5, 7, 9, 10, 56, 53, -+ 55, 62, 54, 8, 0, 63, 58, 59, 60, 61, -+ 1, 0, 0, 19, 20, 17, 0, 0, 37, 38, -+ 35, 0, 0, 0, 16, 4, 6, 24, 18, 21, -+ 23, 25, 22, 11, 15, 42, 36, 39, 41, 43, -+ 40, 28, 29, 26, 0, 12, 14, 33, 27, 30, -+ 32, 34, 31, 13 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const yysigned_char yydefgoto[] = -+{ -+ -1, 11, 12, 13, 14, 15, 36, 42, 43, 37, -+ 16, 17, 18, 19, 20, 21, 22 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -37 -+static const short yypact[] = -+{ -+ -4, 51, -4, -11, -11, -11, -11, -11, -37, -37, -+ -37, 18, -37, -1, -37, -37, 49, 14, -37, -37, -+ -37, -37, -37, -37, 19, -37, -37, -37, -37, -37, -+ -37, -4, -4, 11, 25, 34, 111, 59, 28, 42, -+ 60, 130, 59, 111, -37, -37, -37, 63, 69, 72, -+ 73, 81, 82, -37, -37, 85, 91, 94, 95, 103, -+ 104, 133, 136, -37, 59, -37, -37, -37, -37, -37, -+ -37, -37, -37, -37 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const short yypgoto[] = -+{ -+ -37, -37, -2, -37, -6, 39, -37, 0, -37, -37, -+ -34, -36, -37, -37, -37, 129, -37 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If zero, do what YYDEFACT says. -+ If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -53 -+static const yysigned_char yytable[] = -+{ -+ 24, 54, 53, 1, 31, 32, 65, 2, 8, 66, -+ 3, 4, 5, 6, 7, 8, 9, 10, 30, 47, -+ 48, 49, 38, 39, 40, -46, 46, 41, 73, 45, -+ -46, 44, -46, 50, 51, 52, 55, 56, 57, -47, -+ 23, 64, -28, 0, -47, 0, -47, -28, -44, -28, -+ 58, 59, 60, -44, 0, -44, -29, 33, 34, 35, -+ 0, -29, 2, -29, 0, 3, 4, 5, 6, 7, -+ 8, 9, 10, 3, -26, 0, 0, -51, 8, -26, -+ 10, -26, -51, -45, -51, 0, -48, -50, -45, 0, -+ -45, -48, -50, -48, -50, -52, -49, 0, 0, -33, -+ -52, -49, -52, -49, -33, -27, -33, 0, -30, -32, -+ -27, 0, -27, -30, -32, -30, -32, -34, -31, 0, -+ 0, 0, -34, -31, -34, -31, 4, 5, 6, 7, -+ 0, 9, 25, 26, 27, 28, 29, 0, 61, 62, -+ 63, 67, 68, 69, 70, 71, 72 -+}; -+ -+static const yysigned_char yycheck[] = -+{ -+ 2, 37, 36, 7, 5, 6, 42, 11, 19, 43, -+ 14, 15, 16, 17, 18, 19, 20, 21, 0, 8, -+ 9, 10, 8, 9, 10, 14, 32, 13, 64, 31, -+ 19, 12, 21, 8, 9, 10, 8, 9, 10, 14, -+ 1, 41, 14, -1, 19, -1, 21, 19, 14, 21, -+ 8, 9, 10, 19, -1, 21, 14, 8, 9, 10, -+ -1, 19, 11, 21, -1, 14, 15, 16, 17, 18, -+ 19, 20, 21, 14, 14, -1, -1, 14, 19, 19, -+ 21, 21, 19, 14, 21, -1, 14, 14, 19, -1, -+ 21, 19, 19, 21, 21, 14, 14, -1, -1, 14, -+ 19, 19, 21, 21, 19, 14, 21, -1, 14, 14, -+ 19, -1, 21, 19, 19, 21, 21, 14, 14, -1, -+ -1, -1, 19, 19, 21, 21, 15, 16, 17, 18, -+ -1, 20, 3, 4, 5, 6, 7, -1, 8, 9, -+ 10, 8, 9, 10, 8, 9, 10 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const unsigned char yystos[] = -+{ -+ 0, 7, 11, 14, 15, 16, 17, 18, 19, 20, -+ 21, 24, 25, 26, 27, 28, 33, 34, 35, 36, -+ 37, 38, 39, 28, 25, 38, 38, 38, 38, 38, -+ 0, 5, 6, 8, 9, 10, 29, 32, 8, 9, -+ 10, 13, 30, 31, 12, 25, 27, 8, 9, 10, -+ 8, 9, 10, 33, 34, 8, 9, 10, 8, 9, -+ 10, 8, 9, 10, 30, 34, 33, 8, 9, 10, -+ 8, 9, 10, 34 -+}; -+ -+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -+# define YYSIZE_T __SIZE_TYPE__ -+#endif -+#if ! defined (YYSIZE_T) && defined (size_t) -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# endif -+#endif -+#if ! defined (YYSIZE_T) -+# define YYSIZE_T unsigned int -+#endif -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. */ -+ -+#define YYFAIL goto yyerrlab -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ yytoken = YYTRANSLATE (yychar); \ -+ YYPOPSTACK; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror ("syntax error: cannot back up");\ -+ YYERROR; \ -+ } \ -+while (0) -+ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+/* YYLLOC_DEFAULT -- Compute the default location (before the actions -+ are run). */ -+ -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ ((Current).first_line = (Rhs)[1].first_line, \ -+ (Current).first_column = (Rhs)[1].first_column, \ -+ (Current).last_line = (Rhs)[N].last_line, \ -+ (Current).last_column = (Rhs)[N].last_column) -+#endif -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (&yylval, YYLEX_PARAM) -+#else -+# define YYLEX yylex (&yylval) -+#endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ -+# define YYDSYMPRINT(Args) \ -+do { \ -+ if (yydebug) \ -+ yysymprint Args; \ -+} while (0) -+ -+# define YYDSYMPRINTF(Title, Token, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yysymprint (stderr, \ -+ Token, Value); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_stack_print (short *bottom, short *top) -+#else -+static void -+yy_stack_print (bottom, top) -+ short *bottom; -+ short *top; -+#endif -+{ -+ YYFPRINTF (stderr, "Stack now"); -+ for (/* Nothing. */; bottom <= top; ++bottom) -+ YYFPRINTF (stderr, " %d", *bottom); -+ YYFPRINTF (stderr, "\n"); -+} -+ -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) -+ -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_reduce_print (int yyrule) -+#else -+static void -+yy_reduce_print (yyrule) -+ int yyrule; -+#endif -+{ -+ int yyi; -+ unsigned int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", -+ yyrule - 1, yylno); -+ /* Print the symbols being reduced, and their result. */ -+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) -+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); -+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -+} -+ -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (Rule); \ -+} while (0) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YYDSYMPRINT(Args) -+# define YYDSYMPRINTF(Title, Token, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 -+# undef YYMAXDEPTH -+#endif -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined (__GLIBC__) && defined (_STRING_H) -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+static YYSIZE_T -+# if defined (__STDC__) || defined (__cplusplus) -+yystrlen (const char *yystr) -+# else -+yystrlen (yystr) -+ const char *yystr; -+# endif -+{ -+ register const char *yys = yystr; -+ -+ while (*yys++ != '\0') -+ continue; -+ -+ return yys - yystr - 1; -+} -+# endif -+# endif -+ -+# ifndef yystpcpy -+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+static char * -+# if defined (__STDC__) || defined (__cplusplus) -+yystpcpy (char *yydest, const char *yysrc) -+# else -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+# endif -+{ -+ register char *yyd = yydest; -+ register const char *yys = yysrc; -+ -+ while ((*yyd++ = *yys++) != '\0') -+ continue; -+ -+ return yyd - 1; -+} -+# endif -+# endif -+ -+#endif /* !YYERROR_VERBOSE */ -+ -+ -+ -+#if YYDEBUG -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yysymprint (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (yytype < YYNTOKENS) -+ { -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+# ifdef YYPRINT -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# endif -+ } -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+ YYFPRINTF (yyoutput, ")"); -+} -+ -+#endif /* ! YYDEBUG */ -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yydestruct (int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yydestruct (yytype, yyvaluep) -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } -+} -+ -+ -+/* Prevent warnings from -Wmissing-prototypes. */ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM); -+# else -+int yyparse (); -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+ -+ -+ -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM) -+# else -+int yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int -+yyparse (void) -+#else -+int -+yyparse () -+ -+#endif -+#endif -+{ -+ /* The lookahead symbol. */ -+int yychar; -+ -+/* The semantic value of the lookahead symbol. */ -+YYSTYPE yylval; -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+ -+ register int yystate; -+ register int yyn; -+ int yyresult; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ /* Lookahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+ -+ /* Three stacks and their tools: -+ `yyss': related to states, -+ `yyvs': related to semantic values, -+ `yyls': related to locations. -+ -+ Refer to the stacks thru separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ short yyssa[YYINITDEPTH]; -+ short *yyss = yyssa; -+ register short *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs = yyvsa; -+ register YYSTYPE *yyvsp; -+ -+ -+ -+#define YYPOPSTACK (yyvsp--, yyssp--) -+ -+ YYSIZE_T yystacksize = YYINITDEPTH; -+ -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ -+ -+ /* When reducing, the number of symbols on the RHS of the reduced -+ rule. */ -+ int yylen; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. so pushing a state here evens the stacks. -+ */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ short *yyss1 = yyss; -+ -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow ("parser stack overflow", -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ -+ &yystacksize); -+ -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyoverflowlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyoverflowlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ short *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyoverflowlab; -+ YYSTACK_RELOCATE (yyss); -+ YYSTACK_RELOCATE (yyvs); -+ -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; -+ } -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+/* Do appropriate processing given the current state. */ -+/* Read a lookahead token if we need one and don't already have one. */ -+/* yyresume: */ -+ -+ /* First try to decide what to do without reference to lookahead token. */ -+ -+ yyn = yypact[yystate]; -+ if (yyn == YYPACT_NINF) -+ goto yydefault; -+ -+ /* Not known => get a lookahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ -+ if (yychar == YYEMPTY) -+ { -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) -+ { -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); -+ } -+ else -+ { -+ yytoken = YYTRANSLATE (yychar); -+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yyn == 0 || yyn == YYTABLE_NINF) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ /* Shift the lookahead token. */ -+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); -+ -+ /* Discard the token being shifted unless it is eof. */ -+ if (yychar != YYEOF) -+ yychar = YYEMPTY; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ -+yyreduce: -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+#line 137 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ cond->result = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 3: -+#line 145 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 4: -+#line 149 "./cond.y" -+ { -+ yyval.value = yyvsp[-2].value || yyvsp[0].value; -+ ;} -+ break; -+ -+ case 5: -+#line 156 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 6: -+#line 160 "./cond.y" -+ { -+ yyval.value = yyvsp[-2].value && yyvsp[0].value; -+ ;} -+ break; -+ -+ case 7: -+#line 167 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 8: -+#line 171 "./cond.y" -+ { -+ yyval.value = ! yyvsp[0].value; -+ ;} -+ break; -+ -+ case 9: -+#line 179 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 10: -+#line 183 "./cond.y" -+ { -+ yyval.value = (yyvsp[0].string && yyvsp[0].string[0]) ? MSICONDITION_TRUE : MSICONDITION_FALSE; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 11: -+#line 188 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_int( yyvsp[-2].value, yyvsp[0].value ); -+ ;} -+ break; -+ -+ case 12: -+#line 192 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-2].string, yyvsp[0].string, FALSE ); -+ msi_free( yyvsp[-2].string ); -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 13: -+#line 198 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-3].string, yyvsp[0].string, TRUE ); -+ msi_free( yyvsp[-3].string ); -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 14: -+#line 204 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_m1( yyvsp[-2].string, yyvsp[0].value ); -+ msi_free( yyvsp[-2].string ); -+ ;} -+ break; -+ -+ case 15: -+#line 209 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].fn_comp_m2( yyvsp[-2].value, yyvsp[0].string ); -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 16: -+#line 214 "./cond.y" -+ { -+ yyval.value = yyvsp[-1].value; -+ ;} -+ break; -+ -+ case 17: -+#line 222 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_eq_i; -+ ;} -+ break; -+ -+ case 18: -+#line 226 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_ne_i; -+ ;} -+ break; -+ -+ case 19: -+#line 230 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_lt_i; -+ ;} -+ break; -+ -+ case 20: -+#line 234 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_gt_i; -+ ;} -+ break; -+ -+ case 21: -+#line 238 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_le_i; -+ ;} -+ break; -+ -+ case 22: -+#line 242 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_ge_i; -+ ;} -+ break; -+ -+ case 23: -+#line 247 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_bitand; -+ ;} -+ break; -+ -+ case 24: -+#line 251 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_highcomp; -+ ;} -+ break; -+ -+ case 25: -+#line 255 "./cond.y" -+ { -+ yyval.fn_comp_int = comp_lowcomp; -+ ;} -+ break; -+ -+ case 26: -+#line 263 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_eq_s; -+ ;} -+ break; -+ -+ case 27: -+#line 267 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_ne_s; -+ ;} -+ break; -+ -+ case 28: -+#line 271 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_lt_s; -+ ;} -+ break; -+ -+ case 29: -+#line 275 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_gt_s; -+ ;} -+ break; -+ -+ case 30: -+#line 279 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_le_s; -+ ;} -+ break; -+ -+ case 31: -+#line 283 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_ge_s; -+ ;} -+ break; -+ -+ case 32: -+#line 288 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_substring; -+ ;} -+ break; -+ -+ case 33: -+#line 292 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_start; -+ ;} -+ break; -+ -+ case 34: -+#line 296 "./cond.y" -+ { -+ yyval.fn_comp_str = comp_end; -+ ;} -+ break; -+ -+ case 35: -+#line 304 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_eq_m1; -+ ;} -+ break; -+ -+ case 36: -+#line 308 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_ne_m1; -+ ;} -+ break; -+ -+ case 37: -+#line 312 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_lt_m1; -+ ;} -+ break; -+ -+ case 38: -+#line 316 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_gt_m1; -+ ;} -+ break; -+ -+ case 39: -+#line 320 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_le_m1; -+ ;} -+ break; -+ -+ case 40: -+#line 324 "./cond.y" -+ { -+ yyval.fn_comp_m1 = comp_ge_m1; -+ ;} -+ break; -+ -+ case 41: -+#line 329 "./cond.y" -+ { -+ yyval.fn_comp_m1 = 0; -+ ;} -+ break; -+ -+ case 42: -+#line 333 "./cond.y" -+ { -+ yyval.fn_comp_m1 = 0; -+ ;} -+ break; -+ -+ case 43: -+#line 337 "./cond.y" -+ { -+ yyval.fn_comp_m1 = 0; -+ ;} -+ break; -+ -+ case 44: -+#line 345 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_eq_m2; -+ ;} -+ break; -+ -+ case 45: -+#line 349 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_ne_m2; -+ ;} -+ break; -+ -+ case 46: -+#line 353 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_lt_m2; -+ ;} -+ break; -+ -+ case 47: -+#line 357 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_gt_m2; -+ ;} -+ break; -+ -+ case 48: -+#line 361 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_le_m2; -+ ;} -+ break; -+ -+ case 49: -+#line 365 "./cond.y" -+ { -+ yyval.fn_comp_m2 = comp_ge_m2; -+ ;} -+ break; -+ -+ case 50: -+#line 370 "./cond.y" -+ { -+ yyval.fn_comp_m2 = 0; -+ ;} -+ break; -+ -+ case 51: -+#line 374 "./cond.y" -+ { -+ yyval.fn_comp_m2 = 0; -+ ;} -+ break; -+ -+ case 52: -+#line 378 "./cond.y" -+ { -+ yyval.fn_comp_m2 = 0; -+ ;} -+ break; -+ -+ case 53: -+#line 385 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 54: -+#line 389 "./cond.y" -+ { -+ yyval.value = yyvsp[0].value; -+ ;} -+ break; -+ -+ case 55: -+#line 396 "./cond.y" -+ { -+ yyval.string = yyvsp[0].string; -+ ;} -+ break; -+ -+ case 56: -+#line 400 "./cond.y" -+ { -+ yyval.string = yyvsp[0].string; -+ ;} -+ break; -+ -+ case 57: -+#line 407 "./cond.y" -+ { -+ yyval.string = COND_GetLiteral(&yyvsp[0].str); -+ if( !yyval.string ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 58: -+#line 416 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action ); -+ yyval.value = action; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 59: -+#line 425 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action ); -+ yyval.value = install; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 60: -+#line 434 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action ); -+ yyval.value = action; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 61: -+#line 443 "./cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action ); -+ yyval.value = install; -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 62: -+#line 455 "./cond.y" -+ { -+ DWORD sz; -+ COND_input* cond = (COND_input*) info; -+ -+ sz = 0; -+ MSI_GetPropertyW(cond->package, yyvsp[0].string, NULL, &sz); -+ if (sz == 0) -+ { -+ yyval.string = msi_alloc( sizeof(WCHAR)); -+ yyval.string[0] = 0; -+ } -+ else -+ { -+ sz ++; -+ yyval.string = msi_alloc( sz*sizeof (WCHAR) ); -+ -+ /* Lookup the identifier */ -+ -+ MSI_GetPropertyW(cond->package,yyvsp[0].string,yyval.string,&sz); -+ } -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 63: -+#line 478 "./cond.y" -+ { -+ UINT len = GetEnvironmentVariableW( yyvsp[0].string, NULL, 0 ); -+ if( len++ ) -+ { -+ yyval.string = msi_alloc( len*sizeof (WCHAR) ); -+ if( yyval.string ) -+ GetEnvironmentVariableW( yyvsp[0].string, yyval.string, len ); -+ } -+ msi_free( yyvsp[0].string ); -+ ;} -+ break; -+ -+ case 64: -+#line 492 "./cond.y" -+ { -+ yyval.string = COND_GetString(&yyvsp[0].str); -+ if( !yyval.string ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 65: -+#line 501 "./cond.y" -+ { -+ LPWSTR szNum = COND_GetString(&yyvsp[0].str); -+ if( !szNum ) -+ YYABORT; -+ yyval.value = atoiW( szNum ); -+ msi_free( szNum ); -+ ;} -+ break; -+ -+ -+ } -+ -+/* Line 1000 of yacc.c. */ -+#line 1733 "cond.tab.c" -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ -+ -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) -+ { -+ ++yynerrs; -+#if YYERROR_VERBOSE -+ yyn = yypact[yystate]; -+ -+ if (YYPACT_NINF < yyn && yyn < YYLAST) -+ { -+ YYSIZE_T yysize = 0; -+ int yytype = YYTRANSLATE (yychar); -+ const char* yyprefix; -+ char *yymsg; -+ int yyx; -+ -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yycount = 0; -+ -+ yyprefix = ", expecting "; -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); -+ yycount += 1; -+ if (yycount == 5) -+ { -+ yysize = 0; -+ break; -+ } -+ } -+ yysize += (sizeof ("syntax error, unexpected ") -+ + yystrlen (yytname[yytype])); -+ yymsg = (char *) YYSTACK_ALLOC (yysize); -+ if (yymsg != 0) -+ { -+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); -+ yyp = yystpcpy (yyp, yytname[yytype]); -+ -+ if (yycount < 5) -+ { -+ yyprefix = ", expecting "; -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ yyp = yystpcpy (yyp, yyprefix); -+ yyp = yystpcpy (yyp, yytname[yyx]); -+ yyprefix = " or "; -+ } -+ } -+ yyerror (yymsg); -+ YYSTACK_FREE (yymsg); -+ } -+ else -+ yyerror ("syntax error; also virtual memory exhausted"); -+ } -+ else -+#endif /* YYERROR_VERBOSE */ -+ yyerror ("syntax error"); -+ } -+ -+ -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse lookahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* If at end of input, pop the error token, -+ then the rest of the stack, then return failure. */ -+ if (yychar == YYEOF) -+ for (;;) -+ { -+ YYPOPSTACK; -+ if (yyssp == yyss) -+ YYABORT; -+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); -+ yydestruct (yystos[*yyssp], yyvsp); -+ } -+ } -+ else -+ { -+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); -+ yydestruct (yytoken, &yylval); -+ yychar = YYEMPTY; -+ -+ } -+ } -+ -+ /* Else will try to reuse lookahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+#ifdef __GNUC__ -+ /* Pacify GCC when the user code never invokes YYERROR and the label -+ yyerrorlab therefore never appears in user code. */ -+ if (0) -+ goto yyerrorlab; -+#endif -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (yyn != YYPACT_NINF) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); -+ yydestruct (yystos[yystate], yyvsp); -+ YYPOPSTACK; -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ YYDPRINTF ((stderr, "Shifting error token, ")); -+ -+ *++yyvsp = yylval; -+ -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#ifndef yyoverflow -+/*----------------------------------------------. -+| yyoverflowlab -- parser overflow comes here. | -+`----------------------------------------------*/ -+yyoverflowlab: -+ yyerror ("parser stack overflow"); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+ return yyresult; -+} -+ -+ -+#line 510 "./cond.y" -+ -+ -+ -+static int COND_IsAlpha( WCHAR x ) -+{ -+ return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) || -+ ( ( x >= 'a' ) && ( x <= 'z' ) ) || -+ ( ( x == '_' ) ) ); -+} -+ -+static int COND_IsNumber( WCHAR x ) -+{ -+ return( (( x >= '0' ) && ( x <= '9' )) || (x =='-') || (x =='.') ); -+} -+ -+ -+/* the mess of comparison functions */ -+ -+static INT comp_lt_i(INT a, INT b) -+{ return (a < b); } -+static INT comp_gt_i(INT a, INT b) -+{ return (a > b); } -+static INT comp_le_i(INT a, INT b) -+{ return (a <= b); } -+static INT comp_ge_i(INT a, INT b) -+{ return (a >= b); } -+static INT comp_eq_i(INT a, INT b) -+{ return (a == b); } -+static INT comp_ne_i(INT a, INT b) -+{ return (a != b); } -+static INT comp_bitand(INT a, INT b) -+{ return a & b;} -+static INT comp_highcomp(INT a, INT b) -+{ return HIWORD(a)==b; } -+static INT comp_lowcomp(INT a, INT b) -+{ return LOWORD(a)==b; } -+ -+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return !strcmpiW(a,b); else return !strcmpW(a,b);} -+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b); else return strcmpW(a,b);} -+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b)<0; else return strcmpW(a,b)<0;} -+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b)>0; else return strcmpW(a,b)>0;} -+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b)<=0; else return strcmpW(a,b)<=0;} -+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strcmpiW(a,b)>=0; else return strcmpW(a,b)>=0;} -+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless) -+/* ERROR NOT WORKING REWRITE */ -+{ if (casless) return strstrW(a,b)!=NULL; else return strstrW(a,b)!=NULL;} -+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless) -+{ if (casless) return strncmpiW(a,b,strlenW(b))==0; -+ else return strncmpW(a,b,strlenW(b))==0;} -+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless) -+{ -+ int i = strlenW(a); -+ int j = strlenW(b); -+ if (j>i) -+ return 0; -+ if (casless) return (!strcmpiW(&a[i-j-1],b)); -+ else return (!strcmpW(&a[i-j-1],b)); -+} -+ -+ -+static INT comp_eq_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;} -+static INT comp_ne_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;} -+static INT comp_lt_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)b; else return 0;} -+static INT comp_le_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;} -+static INT comp_ge_m1(LPWSTR a, INT b) -+{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;} -+ -+static INT comp_eq_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;} -+static INT comp_ne_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;} -+static INT comp_lt_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;} -+static INT comp_gt_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;} -+static INT comp_le_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;} -+static INT comp_ge_m2(INT a, LPWSTR b) -+{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;} -+ -+ -+ -+static int COND_IsIdent( WCHAR x ) -+{ -+ return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) -+ || ( x == '#' ) || (x == '.') ); -+} -+ -+static int COND_GetOne( struct cond_str *str, COND_input *cond ) -+{ -+ static const WCHAR szNot[] = {'N','O','T',0}; -+ static const WCHAR szAnd[] = {'A','N','D',0}; -+ static const WCHAR szOr[] = {'O','R',0}; -+ WCHAR ch; -+ int rc, len = 1; -+ -+ str->data = &cond->str[cond->n]; -+ -+ ch = str->data[0]; -+ switch( ch ) -+ { -+ case 0: return 0; -+ case '(': rc = COND_LPAR; break; -+ case ')': rc = COND_RPAR; break; -+ case '&': rc = COND_AMPER; break; -+ case '!': rc = COND_EXCLAM; break; -+ case '$': rc = COND_DOLLARS; break; -+ case '?': rc = COND_QUESTION; break; -+ case '%': rc = COND_PERCENT; break; -+ case ' ': rc = COND_SPACE; break; -+ case '=': rc = COND_EQ; break; -+ case '~': rc = COND_TILDA; break; -+ case '<': rc = COND_LT; break; -+ case '>': rc = COND_GT; break; -+ case '"': -+ { -+ const WCHAR *ch2 = str->data + 1; -+ -+ -+ while ( *ch2 && *ch2 != '"' ) -+ ++ch2; -+ if (*ch2 == '"') -+ { -+ len = ch2 - str->data + 1; -+ rc = COND_LITER; -+ break; -+ } -+ } -+ ERR("Unterminated string\n"); -+ rc = COND_ERROR; -+ break; -+ default: -+ if( COND_IsAlpha( ch ) ) -+ { -+ while( COND_IsIdent( str->data[len] ) ) -+ len++; -+ rc = COND_IDENT; -+ break; -+ } -+ -+ if( COND_IsNumber( ch ) ) -+ { -+ while( COND_IsNumber( str->data[len] ) ) -+ len++; -+ rc = COND_NUMBER; -+ break; -+ } -+ -+ ERR("Got unknown character %c(%x)\n",ch,ch); -+ rc = COND_ERROR; -+ break; -+ } -+ -+ /* keyword identifiers */ -+ if( rc == COND_IDENT ) -+ { -+ if( (len==3) && (strncmpiW(str->data,szNot,len)==0) ) -+ rc = COND_NOT; -+ else if( (len==3) && (strncmpiW(str->data,szAnd,len)==0) ) -+ rc = COND_AND; -+ else if( (len==2) && (strncmpiW(str->data,szOr,len)==0) ) -+ rc = COND_OR; -+ } -+ -+ cond->n += len; -+ str->len = len; -+ -+ return rc; -+} -+ -+static int COND_lex( void *COND_lval, COND_input *cond ) -+{ -+ int rc; -+ struct cond_str *str = COND_lval; -+ -+ do { -+ rc = COND_GetOne( str, cond ); -+ } while (rc == COND_SPACE); -+ -+ return rc; -+} -+ -+static LPWSTR COND_GetString( struct cond_str *str ) -+{ -+ LPWSTR ret; -+ -+ ret = msi_alloc( (str->len+1) * sizeof (WCHAR) ); -+ if( ret ) -+ { -+ memcpy( ret, str->data, str->len * sizeof(WCHAR)); -+ ret[str->len]=0; -+ } -+ TRACE("Got identifier %s\n",debugstr_w(ret)); -+ return ret; -+} -+ -+static LPWSTR COND_GetLiteral( struct cond_str *str ) -+{ -+ LPWSTR ret; -+ -+ ret = msi_alloc( (str->len-1) * sizeof (WCHAR) ); -+ if( ret ) -+ { -+ memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) ); -+ ret[str->len - 2]=0; -+ } -+ TRACE("Got literal %s\n",debugstr_w(ret)); -+ return ret; -+} -+ -+static int COND_error(const char *str) -+{ -+ return 0; -+} -+ -+MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition ) -+{ -+ COND_input cond; -+ MSICONDITION r; -+ -+ cond.package = package; -+ cond.str = szCondition; -+ cond.n = 0; -+ cond.result = -1; -+ -+ TRACE("Evaluating %s\n",debugstr_w(szCondition)); -+ -+ if ( szCondition == NULL || szCondition[0] == 0) -+ r = MSICONDITION_NONE; -+ else if ( !COND_parse( &cond ) ) -+ r = cond.result; -+ else -+ r = MSICONDITION_ERROR; -+ -+ TRACE("Evaluates to %i\n",r); -+ return r; -+} -+ -+MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition ) -+{ -+ MSIPACKAGE *package; -+ UINT ret; -+ -+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); -+ if( !package) -+ return ERROR_INVALID_HANDLE; -+ ret = MSI_EvaluateConditionW( package, szCondition ); -+ msiobj_release( &package->hdr ); -+ return ret; -+} -+ -+MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition ) -+{ -+ LPWSTR szwCond = NULL; -+ MSICONDITION r; -+ -+ if( szCondition ) -+ { -+ UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 ); -+ szwCond = msi_alloc( len * sizeof (WCHAR) ); -+ MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len ); -+ } -+ -+ r = MsiEvaluateConditionW( hInstall, szwCond ); -+ -+ msi_free( szwCond ); -+ -+ return r; -+} -+ -Index: cond.tab.h -=================================================================== ---- cond.tab.h (revision 23782) -+++ cond.tab.h (working copy) -@@ -0,0 +1,99 @@ -+/* A Bison parser, made by GNU Bison 1.875c. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -+ -+ 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, 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., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COND_SPACE = 258, -+ COND_EOF = 259, -+ COND_OR = 260, -+ COND_AND = 261, -+ COND_NOT = 262, -+ COND_LT = 263, -+ COND_GT = 264, -+ COND_EQ = 265, -+ COND_LPAR = 266, -+ COND_RPAR = 267, -+ COND_TILDA = 268, -+ COND_PERCENT = 269, -+ COND_DOLLARS = 270, -+ COND_QUESTION = 271, -+ COND_AMPER = 272, -+ COND_EXCLAM = 273, -+ COND_IDENT = 274, -+ COND_NUMBER = 275, -+ COND_LITER = 276, -+ COND_ERROR = 277 -+ }; -+#endif -+#define COND_SPACE 258 -+#define COND_EOF 259 -+#define COND_OR 260 -+#define COND_AND 261 -+#define COND_NOT 262 -+#define COND_LT 263 -+#define COND_GT 264 -+#define COND_EQ 265 -+#define COND_LPAR 266 -+#define COND_RPAR 267 -+#define COND_TILDA 268 -+#define COND_PERCENT 269 -+#define COND_DOLLARS 270 -+#define COND_QUESTION 271 -+#define COND_AMPER 272 -+#define COND_EXCLAM 273 -+#define COND_IDENT 274 -+#define COND_NUMBER 275 -+#define COND_LITER 276 -+#define COND_ERROR 277 -+ -+ -+ -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 106 "./cond.y" -+typedef union YYSTYPE { -+ struct cond_str str; -+ LPWSTR string; -+ INT value; -+ comp_int fn_comp_int; -+ comp_str fn_comp_str; -+ comp_m1 fn_comp_m1; -+ comp_m2 fn_comp_m2; -+} YYSTYPE; -+/* Line 1275 of yacc.c. */ -+#line 91 "cond.tab.h" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+ -+ -Index: helpers.c -=================================================================== ---- helpers.c (revision 23808) -+++ helpers.c (working copy) -@@ -25,6 +25,7 @@ - - #include - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winerror.h" -Index: install.c -=================================================================== ---- install.c (revision 23808) -+++ install.c (working copy) -@@ -22,6 +22,7 @@ - - #include - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winerror.h" -Index: msi.c -=================================================================== ---- msi.c (revision 23808) -+++ msi.c (working copy) -@@ -23,6 +23,7 @@ - #define COBJMACROS - #define NONAMELESSUNION - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winreg.h" -Index: msi.rbuild -=================================================================== ---- msi.rbuild (revision 23808) -+++ msi.rbuild (working copy) -@@ -29,6 +29,7 @@ - alter.c - appsearch.c - classes.c -+ cond.tab.c - create.c - custom.c - database.c -@@ -54,6 +55,7 @@ - regsvr.c - select.c - source.c -+ sql.tab.c - string.c - suminfo.c - table.c -Index: msi_Ja.rc -=================================================================== ---- msi_Ja.rc (revision 23782) -+++ msi_Ja.rc (working copy) -@@ -0,0 +1,13 @@ -+LANGUAGE LANG_JAPANESE, SUBLANG_NEUTRAL -+ -+STRINGTABLE DISCARDABLE -+{ -+ 5 "pX %s ‚Ş‚Ý‚Â‚©‚č‚Ü‚ą‚ń‚Ĺ‚µ‚˝" -+ 9 "fBXN %s ‚đ‘}“ü‚µ‚Ä‚­‚ľ‚ł‚˘" -+ 10 "–łŚř‚Čp‰[^‚Ĺ‚·" -+ 11 "%s ‚Ě‚ ‚étH‹_‚đ“ü—Í‚µ‚Ä‚­‚ľ‚ł‚˘" -+ 12 "‹@”\\‚ĚC“Xg[‹Śł‚Ş‚ ‚č‚Ü‚ą‚ń" -+ 13 "‹@”\\‚Ş‚ ‚élbgŹ[N h‰Cu‚Ş‚ ‚č‚Ü‚ą‚ń" -+ 14 "‹@”\\‚̏ꏊ:" -+ 15 "%s ‚Ě‚ ‚étH‹_‚đ‘I‘đ‚µ‚Ä‚­‚ľ‚ł‚˘" -+} -Index: msiquery.c -=================================================================== ---- msiquery.c (revision 23808) -+++ msiquery.c (working copy) -@@ -22,6 +22,7 @@ - - #define COBJMACROS - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winerror.h" -Index: registry.c -=================================================================== ---- registry.c (revision 23808) -+++ registry.c (working copy) -@@ -24,6 +24,7 @@ - #define COBJMACROS - #define NONAMELESSUNION - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winreg.h" -Index: source.c -=================================================================== ---- source.c (revision 23808) -+++ source.c (working copy) -@@ -23,6 +23,7 @@ - #define COBJMACROS - #define NONAMELESSUNION - -+#include "stdio.h" - #include "windef.h" - #include "winbase.h" - #include "winreg.h" -Index: sql.tab.c -=================================================================== ---- sql.tab.c (revision 23782) -+++ sql.tab.c (working copy) -@@ -0,0 +1,2484 @@ -+/* A Bison parser, made by GNU Bison 1.875c. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -+ -+ 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, 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., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Written by Richard Stallman by simplifying the original so called -+ ``semantic'' parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 1 -+ -+/* Using locations. */ -+#define YYLSP_NEEDED 0 -+ -+/* If NAME_PREFIX is specified substitute the variables and functions -+ names. */ -+#define yyparse SQL_parse -+#define yylex SQL_lex -+#define yyerror SQL_error -+#define yylval SQL_lval -+#define yychar SQL_char -+#define yydebug SQL_debug -+#define yynerrs SQL_nerrs -+ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ TK_ABORT = 258, -+ TK_AFTER = 259, -+ TK_AGG_FUNCTION = 260, -+ TK_ALL = 261, -+ TK_AND = 262, -+ TK_AS = 263, -+ TK_ASC = 264, -+ TK_BEFORE = 265, -+ TK_BEGIN = 266, -+ TK_BETWEEN = 267, -+ TK_BITAND = 268, -+ TK_BITNOT = 269, -+ TK_BITOR = 270, -+ TK_BY = 271, -+ TK_CASCADE = 272, -+ TK_CASE = 273, -+ TK_CHAR = 274, -+ TK_CHECK = 275, -+ TK_CLUSTER = 276, -+ TK_COLLATE = 277, -+ TK_COLUMN = 278, -+ TK_COMMA = 279, -+ TK_COMMENT = 280, -+ TK_COMMIT = 281, -+ TK_CONCAT = 282, -+ TK_CONFLICT = 283, -+ TK_CONSTRAINT = 284, -+ TK_COPY = 285, -+ TK_CREATE = 286, -+ TK_DEFAULT = 287, -+ TK_DEFERRABLE = 288, -+ TK_DEFERRED = 289, -+ TK_DELETE = 290, -+ TK_DELIMITERS = 291, -+ TK_DESC = 292, -+ TK_DISTINCT = 293, -+ TK_DOT = 294, -+ TK_DROP = 295, -+ TK_EACH = 296, -+ TK_ELSE = 297, -+ TK_END = 298, -+ TK_END_OF_FILE = 299, -+ TK_EQ = 300, -+ TK_EXCEPT = 301, -+ TK_EXPLAIN = 302, -+ TK_FAIL = 303, -+ TK_FLOAT = 304, -+ TK_FOR = 305, -+ TK_FOREIGN = 306, -+ TK_FROM = 307, -+ TK_FUNCTION = 308, -+ TK_GE = 309, -+ TK_GLOB = 310, -+ TK_GROUP = 311, -+ TK_GT = 312, -+ TK_HAVING = 313, -+ TK_HOLD = 314, -+ TK_IGNORE = 315, -+ TK_ILLEGAL = 316, -+ TK_IMMEDIATE = 317, -+ TK_IN = 318, -+ TK_INDEX = 319, -+ TK_INITIALLY = 320, -+ TK_ID = 321, -+ TK_INSERT = 322, -+ TK_INSTEAD = 323, -+ TK_INT = 324, -+ TK_INTEGER = 325, -+ TK_INTERSECT = 326, -+ TK_INTO = 327, -+ TK_IS = 328, -+ TK_ISNULL = 329, -+ TK_JOIN = 330, -+ TK_JOIN_KW = 331, -+ TK_KEY = 332, -+ TK_LE = 333, -+ TK_LIKE = 334, -+ TK_LIMIT = 335, -+ TK_LONG = 336, -+ TK_LONGCHAR = 337, -+ TK_LP = 338, -+ TK_LSHIFT = 339, -+ TK_LT = 340, -+ TK_LOCALIZABLE = 341, -+ TK_MATCH = 342, -+ TK_MINUS = 343, -+ TK_NE = 344, -+ TK_NOT = 345, -+ TK_NOTNULL = 346, -+ TK_NULL = 347, -+ TK_OBJECT = 348, -+ TK_OF = 349, -+ TK_OFFSET = 350, -+ TK_ON = 351, -+ TK_OR = 352, -+ TK_ORACLE_OUTER_JOIN = 353, -+ TK_ORDER = 354, -+ TK_PLUS = 355, -+ TK_PRAGMA = 356, -+ TK_PRIMARY = 357, -+ TK_RAISE = 358, -+ TK_REFERENCES = 359, -+ TK_REM = 360, -+ TK_REPLACE = 361, -+ TK_RESTRICT = 362, -+ TK_ROLLBACK = 363, -+ TK_ROW = 364, -+ TK_RP = 365, -+ TK_RSHIFT = 366, -+ TK_SELECT = 367, -+ TK_SEMI = 368, -+ TK_SET = 369, -+ TK_SHORT = 370, -+ TK_SLASH = 371, -+ TK_SPACE = 372, -+ TK_STAR = 373, -+ TK_STATEMENT = 374, -+ TK_STRING = 375, -+ TK_TABLE = 376, -+ TK_TEMP = 377, -+ TK_THEN = 378, -+ TK_TRANSACTION = 379, -+ TK_TRIGGER = 380, -+ TK_UMINUS = 381, -+ TK_UNCLOSED_STRING = 382, -+ TK_UNION = 383, -+ TK_UNIQUE = 384, -+ TK_UPDATE = 385, -+ TK_UPLUS = 386, -+ TK_USING = 387, -+ TK_VACUUM = 388, -+ TK_VALUES = 389, -+ TK_VIEW = 390, -+ TK_WHEN = 391, -+ TK_WHERE = 392, -+ TK_WILDCARD = 393, -+ COLUMN = 395, -+ FUNCTION = 396, -+ COMMENT = 397, -+ UNCLOSED_STRING = 398, -+ SPACE = 399, -+ ILLEGAL = 400, -+ END_OF_FILE = 401 -+ }; -+#endif -+#define TK_ABORT 258 -+#define TK_AFTER 259 -+#define TK_AGG_FUNCTION 260 -+#define TK_ALL 261 -+#define TK_AND 262 -+#define TK_AS 263 -+#define TK_ASC 264 -+#define TK_BEFORE 265 -+#define TK_BEGIN 266 -+#define TK_BETWEEN 267 -+#define TK_BITAND 268 -+#define TK_BITNOT 269 -+#define TK_BITOR 270 -+#define TK_BY 271 -+#define TK_CASCADE 272 -+#define TK_CASE 273 -+#define TK_CHAR 274 -+#define TK_CHECK 275 -+#define TK_CLUSTER 276 -+#define TK_COLLATE 277 -+#define TK_COLUMN 278 -+#define TK_COMMA 279 -+#define TK_COMMENT 280 -+#define TK_COMMIT 281 -+#define TK_CONCAT 282 -+#define TK_CONFLICT 283 -+#define TK_CONSTRAINT 284 -+#define TK_COPY 285 -+#define TK_CREATE 286 -+#define TK_DEFAULT 287 -+#define TK_DEFERRABLE 288 -+#define TK_DEFERRED 289 -+#define TK_DELETE 290 -+#define TK_DELIMITERS 291 -+#define TK_DESC 292 -+#define TK_DISTINCT 293 -+#define TK_DOT 294 -+#define TK_DROP 295 -+#define TK_EACH 296 -+#define TK_ELSE 297 -+#define TK_END 298 -+#define TK_END_OF_FILE 299 -+#define TK_EQ 300 -+#define TK_EXCEPT 301 -+#define TK_EXPLAIN 302 -+#define TK_FAIL 303 -+#define TK_FLOAT 304 -+#define TK_FOR 305 -+#define TK_FOREIGN 306 -+#define TK_FROM 307 -+#define TK_FUNCTION 308 -+#define TK_GE 309 -+#define TK_GLOB 310 -+#define TK_GROUP 311 -+#define TK_GT 312 -+#define TK_HAVING 313 -+#define TK_HOLD 314 -+#define TK_IGNORE 315 -+#define TK_ILLEGAL 316 -+#define TK_IMMEDIATE 317 -+#define TK_IN 318 -+#define TK_INDEX 319 -+#define TK_INITIALLY 320 -+#define TK_ID 321 -+#define TK_INSERT 322 -+#define TK_INSTEAD 323 -+#define TK_INT 324 -+#define TK_INTEGER 325 -+#define TK_INTERSECT 326 -+#define TK_INTO 327 -+#define TK_IS 328 -+#define TK_ISNULL 329 -+#define TK_JOIN 330 -+#define TK_JOIN_KW 331 -+#define TK_KEY 332 -+#define TK_LE 333 -+#define TK_LIKE 334 -+#define TK_LIMIT 335 -+#define TK_LONG 336 -+#define TK_LONGCHAR 337 -+#define TK_LP 338 -+#define TK_LSHIFT 339 -+#define TK_LT 340 -+#define TK_LOCALIZABLE 341 -+#define TK_MATCH 342 -+#define TK_MINUS 343 -+#define TK_NE 344 -+#define TK_NOT 345 -+#define TK_NOTNULL 346 -+#define TK_NULL 347 -+#define TK_OBJECT 348 -+#define TK_OF 349 -+#define TK_OFFSET 350 -+#define TK_ON 351 -+#define TK_OR 352 -+#define TK_ORACLE_OUTER_JOIN 353 -+#define TK_ORDER 354 -+#define TK_PLUS 355 -+#define TK_PRAGMA 356 -+#define TK_PRIMARY 357 -+#define TK_RAISE 358 -+#define TK_REFERENCES 359 -+#define TK_REM 360 -+#define TK_REPLACE 361 -+#define TK_RESTRICT 362 -+#define TK_ROLLBACK 363 -+#define TK_ROW 364 -+#define TK_RP 365 -+#define TK_RSHIFT 366 -+#define TK_SELECT 367 -+#define TK_SEMI 368 -+#define TK_SET 369 -+#define TK_SHORT 370 -+#define TK_SLASH 371 -+#define TK_SPACE 372 -+#define TK_STAR 373 -+#define TK_STATEMENT 374 -+#define TK_STRING 375 -+#define TK_TABLE 376 -+#define TK_TEMP 377 -+#define TK_THEN 378 -+#define TK_TRANSACTION 379 -+#define TK_TRIGGER 380 -+#define TK_UMINUS 381 -+#define TK_UNCLOSED_STRING 382 -+#define TK_UNION 383 -+#define TK_UNIQUE 384 -+#define TK_UPDATE 385 -+#define TK_UPLUS 386 -+#define TK_USING 387 -+#define TK_VACUUM 388 -+#define TK_VALUES 389 -+#define TK_VIEW 390 -+#define TK_WHEN 391 -+#define TK_WHERE 392 -+#define TK_WILDCARD 393 -+#define COLUMN 395 -+#define FUNCTION 396 -+#define COMMENT 397 -+#define UNCLOSED_STRING 398 -+#define SPACE 399 -+#define ILLEGAL 400 -+#define END_OF_FILE 401 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+#line 1 "./sql.y" -+ -+ -+/* -+ * Implementation of the Microsoft Installer (msi.dll) -+ * -+ * Copyright 2002-2004 Mike McCormack for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "query.h" -+#include "wine/list.h" -+#include "wine/debug.h" -+ -+#define YYLEX_PARAM info -+#define YYPARSE_PARAM info -+ -+extern int SQL_error(const char *str); -+ -+WINE_DEFAULT_DEBUG_CHANNEL(msi); -+ -+typedef struct tag_SQL_input -+{ -+ MSIDATABASE *db; -+ LPCWSTR command; -+ DWORD n, len; -+ MSIVIEW **view; /* view structure for the resulting query */ -+ struct list *mem; -+} SQL_input; -+ -+static LPWSTR SQL_getstring( void *info, struct sql_str *str ); -+static INT SQL_getint( void *info ); -+static int SQL_lex( void *SQL_lval, SQL_input *info ); -+ -+static void *parser_alloc( void *info, unsigned int sz ); -+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ); -+ -+static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys); -+ -+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ); -+static struct expr * EXPR_column( void *info, column_info *column ); -+static struct expr * EXPR_ival( void *info, int val ); -+static struct expr * EXPR_sval( void *info, struct sql_str * ); -+static struct expr * EXPR_wildcard( void *info ); -+ -+ -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 72 "./sql.y" -+typedef union YYSTYPE { -+ struct sql_str str; -+ LPWSTR string; -+ column_info *column_list; -+ MSIVIEW *query; -+ struct expr *expr; -+ USHORT column_type; -+ int integer; -+} YYSTYPE; -+/* Line 191 of yacc.c. */ -+#line 453 "sql.tab.c" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+/* Copy the second part of user declarations. */ -+ -+ -+/* Line 214 of yacc.c. */ -+#line 465 "sql.tab.c" -+ -+#if ! defined (yyoverflow) || YYERROR_VERBOSE -+ -+# ifndef YYFREE -+# define YYFREE free -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# endif -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# define YYSTACK_ALLOC alloca -+# endif -+# else -+# if defined (alloca) || defined (_ALLOCA_H) -+# define YYSTACK_ALLOC alloca -+# else -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+# else -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# endif -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# endif -+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ -+ -+ -+#if (! defined (yyoverflow) \ -+ && (! defined (__cplusplus) \ -+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ short yyss; -+ YYSTYPE yyvs; -+ }; -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ -+ + YYSTACK_GAP_MAXIMUM) -+ -+/* Copy COUNT objects from FROM to TO. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined (__GNUC__) && 1 < __GNUC__ -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# else -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ register YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (0) -+# endif -+# endif -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack, Stack, yysize); \ -+ Stack = &yyptr->Stack; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) -+ -+#endif -+ -+#if defined (__STDC__) || defined (__cplusplus) -+ typedef signed char yysigned_char; -+#else -+ typedef short yysigned_char; -+#endif -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 29 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 124 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 147 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 31 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 69 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 127 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 401 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const unsigned char yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, -+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, -+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, -+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, -+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, -+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, -+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, -+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, -+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, -+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, -+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, -+ 145, 146 -+}; -+ -+#if YYDEBUG -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const unsigned char yyprhs[] = -+{ -+ 0, 0, 3, 5, 7, 9, 11, 13, 15, 26, -+ 38, 45, 53, 60, 63, 68, 72, 74, 77, 79, -+ 82, 84, 88, 90, 95, 97, 99, 101, 103, 105, -+ 107, 112, 114, 117, 121, 124, 126, 130, 132, 134, -+ 138, 141, 145, 149, 153, 157, 161, 165, 169, 173, -+ 177, 181, 185, 190, 192, 194, 196, 200, 202, 206, -+ 210, 212, 215, 217, 219, 221, 225, 227, 229, 231 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const short yyrhs[] = -+{ -+ 148, 0, -1, 149, -1, 161, -1, 151, -1, 150, -+ -1, 152, -1, 153, -1, 67, 72, 175, 83, 164, -+ 110, 134, 83, 169, 110, -1, 67, 72, 175, 83, -+ 164, 110, 134, 83, 169, 110, 122, -1, 31, 121, -+ 175, 83, 154, 110, -1, 31, 121, 175, 83, 154, -+ 110, 59, -1, 130, 175, 114, 170, 137, 167, -1, -+ 35, 165, -1, 155, 102, 77, 164, -1, 155, 24, -+ 156, -1, 156, -1, 174, 157, -1, 158, -1, 158, -+ 86, -1, 159, -1, 159, 90, 92, -1, 19, -1, -+ 19, 83, 160, 110, -1, 82, -1, 115, -1, 69, -+ -1, 81, -1, 93, -1, 177, -1, 162, 99, 16, -+ 164, -1, 162, -1, 112, 163, -1, 112, 38, 163, -+ -1, 164, 165, -1, 174, -1, 174, 24, 164, -1, -+ 118, -1, 166, -1, 166, 137, 167, -1, 52, 175, -+ -1, 83, 167, 110, -1, 173, 45, 173, -1, 167, -+ 7, 167, -1, 167, 97, 167, -1, 173, 45, 168, -+ -1, 173, 57, 168, -1, 173, 85, 168, -1, 173, -+ 78, 168, -1, 173, 54, 168, -1, 173, 89, 168, -+ -1, 173, 73, 92, -1, 173, 73, 90, 92, -1, -+ 173, -1, 172, -1, 172, -1, 172, 24, 169, -1, -+ 171, -1, 171, 24, 170, -1, 174, 45, 172, -1, -+ 177, -1, 88, 177, -1, 120, -1, 138, -1, 174, -+ -1, 175, 39, 176, -1, 176, -1, 176, -1, 66, -+ -1, 70, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const unsigned short yyrline[] = -+{ -+ 0, 138, 138, 146, 147, 148, 149, 150, 154, 165, -+ 178, 190, 205, 218, 231, 241, 251, 258, 266, 270, -+ 277, 281, 288, 292, 296, 300, 304, 308, 312, 319, -+ 328, 340, 344, 348, 364, 385, 386, 390, 397, 398, -+ 414, 427, 433, 439, 445, 451, 457, 463, 469, 475, -+ 481, 487, 493, 502, 503, 507, 514, 525, 526, 534, -+ 542, 548, 554, 560, 569, 578, 584, 593, 600, 609 -+}; -+#endif -+ -+#if YYDEBUG || YYERROR_VERBOSE -+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "TK_ABORT", "TK_AFTER", -+ "TK_AGG_FUNCTION", "TK_ALL", "TK_AND", "TK_AS", "TK_ASC", "TK_BEFORE", -+ "TK_BEGIN", "TK_BETWEEN", "TK_BITAND", "TK_BITNOT", "TK_BITOR", "TK_BY", -+ "TK_CASCADE", "TK_CASE", "TK_CHAR", "TK_CHECK", "TK_CLUSTER", -+ "TK_COLLATE", "TK_COLUMN", "TK_COMMA", "TK_COMMENT", "TK_COMMIT", -+ "TK_CONCAT", "TK_CONFLICT", "TK_CONSTRAINT", "TK_COPY", "TK_CREATE", -+ "TK_DEFAULT", "TK_DEFERRABLE", "TK_DEFERRED", "TK_DELETE", -+ "TK_DELIMITERS", "TK_DESC", "TK_DISTINCT", "TK_DOT", "TK_DROP", -+ "TK_EACH", "TK_ELSE", "TK_END", "TK_END_OF_FILE", "TK_EQ", "TK_EXCEPT", -+ "TK_EXPLAIN", "TK_FAIL", "TK_FLOAT", "TK_FOR", "TK_FOREIGN", "TK_FROM", -+ "TK_FUNCTION", "TK_GE", "TK_GLOB", "TK_GROUP", "TK_GT", "TK_HAVING", -+ "TK_HOLD", "TK_IGNORE", "TK_ILLEGAL", "TK_IMMEDIATE", "TK_IN", -+ "TK_INDEX", "TK_INITIALLY", "TK_ID", "TK_INSERT", "TK_INSTEAD", "TK_INT", -+ "TK_INTEGER", "TK_INTERSECT", "TK_INTO", "TK_IS", "TK_ISNULL", "TK_JOIN", -+ "TK_JOIN_KW", "TK_KEY", "TK_LE", "TK_LIKE", "TK_LIMIT", "TK_LONG", -+ "TK_LONGCHAR", "TK_LP", "TK_LSHIFT", "TK_LT", "TK_LOCALIZABLE", -+ "TK_MATCH", "TK_MINUS", "TK_NE", "TK_NOT", "TK_NOTNULL", "TK_NULL", -+ "TK_OBJECT", "TK_OF", "TK_OFFSET", "TK_ON", "TK_OR", -+ "TK_ORACLE_OUTER_JOIN", "TK_ORDER", "TK_PLUS", "TK_PRAGMA", "TK_PRIMARY", -+ "TK_RAISE", "TK_REFERENCES", "TK_REM", "TK_REPLACE", "TK_RESTRICT", -+ "TK_ROLLBACK", "TK_ROW", "TK_RP", "TK_RSHIFT", "TK_SELECT", "TK_SEMI", -+ "TK_SET", "TK_SHORT", "TK_SLASH", "TK_SPACE", "TK_STAR", "TK_STATEMENT", -+ "TK_STRING", "TK_TABLE", "TK_TEMP", "TK_THEN", "TK_TRANSACTION", -+ "TK_TRIGGER", "TK_UMINUS", "TK_UNCLOSED_STRING", "TK_UNION", "TK_UNIQUE", -+ "TK_UPDATE", "TK_UPLUS", "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW", -+ "TK_WHEN", "TK_WHERE", "TK_WILDCARD", "AGG_FUNCTION.", "COLUMN", -+ "FUNCTION", "COMMENT", "UNCLOSED_STRING", "SPACE", "ILLEGAL", -+ "END_OF_FILE", "$accept", "query", "onequery", "oneinsert", "onecreate", -+ "oneupdate", "onedelete", "table_def", "column_def", "column_and_type", -+ "column_type", "data_type_l", "data_type", "data_count", "oneselect", -+ "unorderedsel", "selectfrom", "selcollist", "from", "fromtable", "expr", -+ "val", "constlist", "update_assign_list", "column_assignment", -+ "const_val", "column_val", "column", "table", "id", "number", 0 -+}; -+#endif -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const unsigned short yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, -+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, -+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, -+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, -+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, -+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, -+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, -+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, -+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, -+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -+ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, -+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, -+ 395, 396, 397, 398, 399, 400, 401 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const unsigned char yyr1[] = -+{ -+ 0, 147, 148, 149, 149, 149, 149, 149, 150, 150, -+ 151, 151, 152, 153, 154, 155, 155, 156, 157, 157, -+ 158, 158, 159, 159, 159, 159, 159, 159, 159, 160, -+ 161, 161, 162, 162, 163, 164, 164, 164, 165, 165, -+ 166, 167, 167, 167, 167, 167, 167, 167, 167, 167, -+ 167, 167, 167, 168, 168, 169, 169, 170, 170, 171, -+ 172, 172, 172, 172, 173, 174, 174, 175, 176, 177 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const unsigned char yyr2[] = -+{ -+ 0, 2, 1, 1, 1, 1, 1, 1, 10, 11, -+ 6, 7, 6, 2, 4, 3, 1, 2, 1, 2, -+ 1, 3, 1, 4, 1, 1, 1, 1, 1, 1, -+ 4, 1, 2, 3, 2, 1, 3, 1, 1, 3, -+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, -+ 3, 3, 4, 1, 1, 1, 3, 1, 3, 3, -+ 1, 2, 1, 1, 1, 3, 1, 1, 1, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state -+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const unsigned char yydefact[] = -+{ -+ 0, 0, 0, 0, 0, 0, 0, 2, 5, 4, -+ 6, 7, 3, 31, 0, 0, 13, 38, 0, 0, -+ 68, 37, 32, 0, 35, 0, 66, 0, 67, 1, -+ 0, 0, 40, 0, 0, 33, 34, 0, 0, 0, -+ 0, 0, 0, 39, 0, 64, 0, 36, 65, 0, -+ 57, 0, 30, 0, 0, 16, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 10, 0, 0, 22, 26, 27, 24, 28, 25, -+ 17, 18, 20, 41, 43, 44, 69, 0, 62, 63, -+ 45, 54, 42, 60, 49, 53, 46, 0, 51, 48, -+ 47, 50, 0, 12, 58, 59, 11, 15, 0, 0, -+ 19, 0, 61, 52, 0, 14, 0, 29, 21, 0, -+ 23, 0, 55, 8, 0, 9, 56 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const yysigned_char yydefgoto[] = -+{ -+ -1, 6, 7, 8, 9, 10, 11, 53, 54, 55, -+ 80, 81, 82, 116, 12, 13, 22, 23, 16, 17, -+ 43, 90, 121, 49, 50, 91, 44, 45, 25, 26, -+ 93 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -111 -+static const yysigned_char yypact[] = -+{ -+ -28, -110, -38, -46, -32, -42, 29, -111, -111, -111, -+ -111, -111, -111, -67, -42, -42, -111, -99, -42, -48, -+ -111, -111, -111, -38, 17, 7, 11, -62, -111, -111, -+ 37, -22, -111, -43, -16, -111, -111, -48, -42, -42, -+ -48, -42, -43, -3, -29, -111, -48, -111, -111, -68, -+ 48, 28, -111, -36, -19, -111, -18, -5, -43, -43, -+ -58, -58, -58, -70, -58, -58, -58, -34, -43, -42, -+ -61, 20, -42, 5, 2, -111, -111, -111, -111, -111, -+ -111, 1, -2, -111, -3, -3, -111, 19, -111, -111, -+ -111, -111, -111, -111, -111, -111, -111, -1, -111, -111, -+ -111, -111, -41, -3, -111, -111, -111, -111, -48, 19, -+ -111, 3, -111, -111, 13, -111, -12, -111, -111, -61, -+ -111, -9, 91, -13, -61, -111, -111 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const yysigned_char yypgoto[] = -+{ -+ -111, -111, -111, -111, -111, -111, -111, -111, -111, 47, -+ -111, -111, -111, -111, -111, -111, 101, -27, 98, -111, -+ -11, 52, 0, 53, -111, -53, 46, -4, 85, 40, -+ -66 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If zero, do what YYDEFACT says. -+ If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -68 -+static const yysigned_char yytable[] = -+{ -+ 24, 74, 58, 1, 58, 72, 19, 2, 20, 86, -+ 47, 14, 86, 52, 15, 24, 60, 105, 20, 67, -+ 97, 112, 98, 20, 20, 61, 18, 87, 62, 29, -+ 87, 57, 30, 24, 20, 51, 24, 56, 33, 3, -+ 42, 37, 24, 117, 63, 28, 38, 84, 85, 64, -+ -67, 75, 39, 40, 28, 28, 65, 103, 28, 88, -+ 66, 41, 88, 76, 77, 51, 122, 46, 56, 68, -+ 21, 122, 69, 70, 71, 78, 102, 89, 48, 106, -+ 89, 115, 108, 73, 4, 109, 21, 110, 111, 86, -+ 27, 113, 59, 114, 59, 118, 119, 79, 120, 31, -+ 32, 123, 5, 34, 24, 83, 92, 95, 95, 125, -+ 95, 95, 95, 94, 96, 124, 99, 100, 101, 107, -+ 35, 36, 104, 0, 126 -+}; -+ -+static const short yycheck[] = -+{ -+ 4, 19, 7, 31, 7, 24, 38, 35, 66, 70, -+ 37, 121, 70, 40, 52, 19, 45, 70, 66, 46, -+ 90, 87, 92, 66, 66, 54, 72, 88, 57, 0, -+ 88, 42, 99, 37, 66, 39, 40, 41, 137, 67, -+ 83, 24, 46, 109, 73, 5, 39, 58, 59, 78, -+ 39, 69, 114, 16, 14, 15, 85, 68, 18, 120, -+ 89, 83, 120, 81, 82, 69, 119, 83, 72, 137, -+ 118, 124, 24, 45, 110, 93, 110, 138, 38, 59, -+ 138, 108, 77, 102, 112, 83, 118, 86, 90, 70, -+ 5, 92, 97, 134, 97, 92, 83, 115, 110, 14, -+ 15, 110, 130, 18, 108, 110, 60, 61, 62, 122, -+ 64, 65, 66, 61, 62, 24, 64, 65, 66, 72, -+ 19, 23, 69, -1, 124 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const unsigned char yystos[] = -+{ -+ 0, 31, 35, 67, 112, 130, 148, 149, 150, 151, -+ 152, 153, 161, 162, 121, 52, 165, 166, 72, 38, -+ 66, 118, 163, 164, 174, 175, 176, 175, 176, 0, -+ 99, 175, 175, 137, 175, 163, 165, 24, 39, 114, -+ 16, 83, 83, 167, 173, 174, 83, 164, 176, 170, -+ 171, 174, 164, 154, 155, 156, 174, 167, 7, 97, -+ 45, 54, 57, 73, 78, 85, 89, 164, 137, 24, -+ 45, 110, 24, 102, 19, 69, 81, 82, 93, 115, -+ 157, 158, 159, 110, 167, 167, 70, 88, 120, 138, -+ 168, 172, 173, 177, 168, 173, 168, 90, 92, 168, -+ 168, 168, 110, 167, 170, 172, 59, 156, 77, 83, -+ 86, 90, 177, 92, 134, 164, 160, 177, 92, 83, -+ 110, 169, 172, 110, 24, 122, 169 -+}; -+ -+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -+# define YYSIZE_T __SIZE_TYPE__ -+#endif -+#if ! defined (YYSIZE_T) && defined (size_t) -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# endif -+#endif -+#if ! defined (YYSIZE_T) -+# define YYSIZE_T unsigned int -+#endif -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. */ -+ -+#define YYFAIL goto yyerrlab -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ yytoken = YYTRANSLATE (yychar); \ -+ YYPOPSTACK; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror ("syntax error: cannot back up");\ -+ YYERROR; \ -+ } \ -+while (0) -+ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+/* YYLLOC_DEFAULT -- Compute the default location (before the actions -+ are run). */ -+ -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ ((Current).first_line = (Rhs)[1].first_line, \ -+ (Current).first_column = (Rhs)[1].first_column, \ -+ (Current).last_line = (Rhs)[N].last_line, \ -+ (Current).last_column = (Rhs)[N].last_column) -+#endif -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (&yylval, YYLEX_PARAM) -+#else -+# define YYLEX yylex (&yylval) -+#endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ -+# define YYDSYMPRINT(Args) \ -+do { \ -+ if (yydebug) \ -+ yysymprint Args; \ -+} while (0) -+ -+# define YYDSYMPRINTF(Title, Token, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yysymprint (stderr, \ -+ Token, Value); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_stack_print (short *bottom, short *top) -+#else -+static void -+yy_stack_print (bottom, top) -+ short *bottom; -+ short *top; -+#endif -+{ -+ YYFPRINTF (stderr, "Stack now"); -+ for (/* Nothing. */; bottom <= top; ++bottom) -+ YYFPRINTF (stderr, " %d", *bottom); -+ YYFPRINTF (stderr, "\n"); -+} -+ -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) -+ -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_reduce_print (int yyrule) -+#else -+static void -+yy_reduce_print (yyrule) -+ int yyrule; -+#endif -+{ -+ int yyi; -+ unsigned int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", -+ yyrule - 1, yylno); -+ /* Print the symbols being reduced, and their result. */ -+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) -+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); -+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -+} -+ -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (Rule); \ -+} while (0) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YYDSYMPRINT(Args) -+# define YYDSYMPRINTF(Title, Token, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 -+# undef YYMAXDEPTH -+#endif -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined (__GLIBC__) && defined (_STRING_H) -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+static YYSIZE_T -+# if defined (__STDC__) || defined (__cplusplus) -+yystrlen (const char *yystr) -+# else -+yystrlen (yystr) -+ const char *yystr; -+# endif -+{ -+ register const char *yys = yystr; -+ -+ while (*yys++ != '\0') -+ continue; -+ -+ return yys - yystr - 1; -+} -+# endif -+# endif -+ -+# ifndef yystpcpy -+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+static char * -+# if defined (__STDC__) || defined (__cplusplus) -+yystpcpy (char *yydest, const char *yysrc) -+# else -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+# endif -+{ -+ register char *yyd = yydest; -+ register const char *yys = yysrc; -+ -+ while ((*yyd++ = *yys++) != '\0') -+ continue; -+ -+ return yyd - 1; -+} -+# endif -+# endif -+ -+#endif /* !YYERROR_VERBOSE */ -+ -+ -+ -+#if YYDEBUG -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yysymprint (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (yytype < YYNTOKENS) -+ { -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+# ifdef YYPRINT -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# endif -+ } -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+ YYFPRINTF (yyoutput, ")"); -+} -+ -+#endif /* ! YYDEBUG */ -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yydestruct (int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yydestruct (yytype, yyvaluep) -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } -+} -+ -+ -+/* Prevent warnings from -Wmissing-prototypes. */ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM); -+# else -+int yyparse (); -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+ -+ -+ -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM) -+# else -+int yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int -+yyparse (void) -+#else -+int -+yyparse () -+ -+#endif -+#endif -+{ -+ /* The lookahead symbol. */ -+int yychar; -+ -+/* The semantic value of the lookahead symbol. */ -+YYSTYPE yylval; -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+ -+ register int yystate; -+ register int yyn; -+ int yyresult; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ /* Lookahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+ -+ /* Three stacks and their tools: -+ `yyss': related to states, -+ `yyvs': related to semantic values, -+ `yyls': related to locations. -+ -+ Refer to the stacks thru separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ short yyssa[YYINITDEPTH]; -+ short *yyss = yyssa; -+ register short *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs = yyvsa; -+ register YYSTYPE *yyvsp; -+ -+ -+ -+#define YYPOPSTACK (yyvsp--, yyssp--) -+ -+ YYSIZE_T yystacksize = YYINITDEPTH; -+ -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ -+ -+ /* When reducing, the number of symbols on the RHS of the reduced -+ rule. */ -+ int yylen; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. so pushing a state here evens the stacks. -+ */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ short *yyss1 = yyss; -+ -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow ("parser stack overflow", -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ -+ &yystacksize); -+ -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyoverflowlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyoverflowlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ short *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyoverflowlab; -+ YYSTACK_RELOCATE (yyss); -+ YYSTACK_RELOCATE (yyvs); -+ -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; -+ } -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+/* Do appropriate processing given the current state. */ -+/* Read a lookahead token if we need one and don't already have one. */ -+/* yyresume: */ -+ -+ /* First try to decide what to do without reference to lookahead token. */ -+ -+ yyn = yypact[yystate]; -+ if (yyn == YYPACT_NINF) -+ goto yydefault; -+ -+ /* Not known => get a lookahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ -+ if (yychar == YYEMPTY) -+ { -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) -+ { -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); -+ } -+ else -+ { -+ yytoken = YYTRANSLATE (yychar); -+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yyn == 0 || yyn == YYTABLE_NINF) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ /* Shift the lookahead token. */ -+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); -+ -+ /* Discard the token being shifted unless it is eof. */ -+ if (yychar != YYEOF) -+ yychar = YYEMPTY; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ -+yyreduce: -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+#line 139 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ *sql->view = yyvsp[0].query; -+ ;} -+ break; -+ -+ case 8: -+#line 155 "./sql.y" -+ { -+ SQL_input *sql = (SQL_input*) info; -+ MSIVIEW *insert = NULL; -+ UINT r; -+ -+ r = INSERT_CreateView( sql->db, &insert, yyvsp[-7].string, yyvsp[-5].column_list, yyvsp[-1].column_list, FALSE ); -+ if( !insert ) -+ YYABORT; -+ yyval.query = insert; -+ ;} -+ break; -+ -+ case 9: -+#line 166 "./sql.y" -+ { -+ SQL_input *sql = (SQL_input*) info; -+ MSIVIEW *insert = NULL; -+ -+ INSERT_CreateView( sql->db, &insert, yyvsp[-8].string, yyvsp[-6].column_list, yyvsp[-2].column_list, TRUE ); -+ if( !insert ) -+ YYABORT; -+ yyval.query = insert; -+ ;} -+ break; -+ -+ case 10: -+#line 179 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *create = NULL; -+ -+ if( !yyvsp[-1].column_list ) -+ YYABORT; -+ CREATE_CreateView( sql->db, &create, yyvsp[-3].string, yyvsp[-1].column_list, FALSE ); -+ if( !create ) -+ YYABORT; -+ yyval.query = create; -+ ;} -+ break; -+ -+ case 11: -+#line 191 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *create = NULL; -+ -+ if( !yyvsp[-2].column_list ) -+ YYABORT; -+ CREATE_CreateView( sql->db, &create, yyvsp[-4].string, yyvsp[-2].column_list, TRUE ); -+ if( !create ) -+ YYABORT; -+ yyval.query = create; -+ ;} -+ break; -+ -+ case 12: -+#line 206 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *update = NULL; -+ -+ UPDATE_CreateView( sql->db, &update, yyvsp[-4].string, yyvsp[-2].column_list, yyvsp[0].expr ); -+ if( !update ) -+ YYABORT; -+ yyval.query = update; -+ ;} -+ break; -+ -+ case 13: -+#line 219 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *delete = NULL; -+ -+ DELETE_CreateView( sql->db, &delete, yyvsp[0].query ); -+ if( !delete ) -+ YYABORT; -+ yyval.query = delete; -+ ;} -+ break; -+ -+ case 14: -+#line 232 "./sql.y" -+ { -+ if( SQL_MarkPrimaryKeys( yyvsp[-3].column_list, yyvsp[0].column_list ) ) -+ yyval.column_list = yyvsp[-3].column_list; -+ else -+ yyval.column_list = NULL; -+ ;} -+ break; -+ -+ case 15: -+#line 242 "./sql.y" -+ { -+ column_info *ci; -+ -+ for( ci = yyvsp[-2].column_list; ci->next; ci = ci->next ) -+ ; -+ -+ ci->next = yyvsp[0].column_list; -+ yyval.column_list = yyvsp[-2].column_list; -+ ;} -+ break; -+ -+ case 16: -+#line 252 "./sql.y" -+ { -+ yyval.column_list = yyvsp[0].column_list; -+ ;} -+ break; -+ -+ case 17: -+#line 259 "./sql.y" -+ { -+ yyval.column_list = yyvsp[-1].column_list; -+ yyval.column_list->type = yyvsp[0].column_type | MSITYPE_VALID; -+ ;} -+ break; -+ -+ case 18: -+#line 267 "./sql.y" -+ { -+ yyval.column_type = yyvsp[0].column_type; -+ ;} -+ break; -+ -+ case 19: -+#line 271 "./sql.y" -+ { -+ yyval.column_type = yyvsp[-1].column_type | MSITYPE_LOCALIZABLE; -+ ;} -+ break; -+ -+ case 20: -+#line 278 "./sql.y" -+ { -+ yyval.column_type |= MSITYPE_NULLABLE; -+ ;} -+ break; -+ -+ case 21: -+#line 282 "./sql.y" -+ { -+ yyval.column_type = yyvsp[-2].column_type; -+ ;} -+ break; -+ -+ case 22: -+#line 289 "./sql.y" -+ { -+ yyval.column_type = MSITYPE_STRING | 1; -+ ;} -+ break; -+ -+ case 23: -+#line 293 "./sql.y" -+ { -+ yyval.column_type = MSITYPE_STRING | 0x400 | yyvsp[-1].column_type; -+ ;} -+ break; -+ -+ case 24: -+#line 297 "./sql.y" -+ { -+ yyval.column_type = 2; -+ ;} -+ break; -+ -+ case 25: -+#line 301 "./sql.y" -+ { -+ yyval.column_type = 2; -+ ;} -+ break; -+ -+ case 26: -+#line 305 "./sql.y" -+ { -+ yyval.column_type = 2; -+ ;} -+ break; -+ -+ case 27: -+#line 309 "./sql.y" -+ { -+ yyval.column_type = 4; -+ ;} -+ break; -+ -+ case 28: -+#line 313 "./sql.y" -+ { -+ yyval.column_type = MSITYPE_STRING | MSITYPE_VALID; -+ ;} -+ break; -+ -+ case 29: -+#line 320 "./sql.y" -+ { -+ if( ( yyvsp[0].integer > 255 ) || ( yyvsp[0].integer < 0 ) ) -+ YYABORT; -+ yyval.column_type = yyvsp[0].integer; -+ ;} -+ break; -+ -+ case 30: -+#line 329 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ -+ yyval.query = NULL; -+ if( yyvsp[0].column_list ) -+ ORDER_CreateView( sql->db, &yyval.query, yyvsp[-3].query, yyvsp[0].column_list ); -+ else -+ yyval.query = yyvsp[-3].query; -+ if( !yyval.query ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 32: -+#line 345 "./sql.y" -+ { -+ yyval.query = yyvsp[0].query; -+ ;} -+ break; -+ -+ case 33: -+#line 349 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ yyval.query = NULL; -+ r = DISTINCT_CreateView( sql->db, &yyval.query, yyvsp[0].query ); -+ if (r != ERROR_SUCCESS) -+ { -+ yyvsp[0].query->ops->delete(yyvsp[0].query); -+ YYABORT; -+ } -+ ;} -+ break; -+ -+ case 34: -+#line 365 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ yyval.query = NULL; -+ if( yyvsp[-1].column_list ) -+ { -+ r = SELECT_CreateView( sql->db, &yyval.query, yyvsp[0].query, yyvsp[-1].column_list ); -+ if (r != ERROR_SUCCESS) -+ { -+ yyvsp[0].query->ops->delete(yyvsp[0].query); -+ YYABORT; -+ } -+ } -+ else -+ yyval.query = yyvsp[0].query; -+ ;} -+ break; -+ -+ case 36: -+#line 387 "./sql.y" -+ { -+ yyvsp[-2].column_list->next = yyvsp[0].column_list; -+ ;} -+ break; -+ -+ case 37: -+#line 391 "./sql.y" -+ { -+ yyval.column_list = NULL; -+ ;} -+ break; -+ -+ case 39: -+#line 399 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ yyval.query = NULL; -+ r = WHERE_CreateView( sql->db, &yyval.query, yyvsp[-2].query, yyvsp[0].expr ); -+ if( r != ERROR_SUCCESS ) -+ { -+ yyvsp[-2].query->ops->delete( yyvsp[-2].query ); -+ YYABORT; -+ } -+ ;} -+ break; -+ -+ case 40: -+#line 415 "./sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ yyval.query = NULL; -+ r = TABLE_CreateView( sql->db, yyvsp[0].string, &yyval.query ); -+ if( r != ERROR_SUCCESS || !yyval.query ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 41: -+#line 428 "./sql.y" -+ { -+ yyval.expr = yyvsp[-1].expr; -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 42: -+#line 434 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 43: -+#line 440 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_AND, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 44: -+#line 446 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_OR, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 45: -+#line 452 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 46: -+#line 458 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GT, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 47: -+#line 464 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LT, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 48: -+#line 470 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LE, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 49: -+#line 476 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GE, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 50: -+#line 482 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_NE, yyvsp[0].expr ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 51: -+#line 488 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_ISNULL, NULL ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 52: -+#line 494 "./sql.y" -+ { -+ yyval.expr = EXPR_complex( info, yyvsp[-3].expr, OP_NOTNULL, NULL ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 55: -+#line 508 "./sql.y" -+ { -+ yyval.column_list = parser_alloc_column( info, NULL, NULL ); -+ if( !yyval.column_list ) -+ YYABORT; -+ yyval.column_list->val = yyvsp[0].expr; -+ ;} -+ break; -+ -+ case 56: -+#line 515 "./sql.y" -+ { -+ yyval.column_list = parser_alloc_column( info, NULL, NULL ); -+ if( !yyval.column_list ) -+ YYABORT; -+ yyval.column_list->val = yyvsp[-2].expr; -+ yyval.column_list->next = yyvsp[0].column_list; -+ ;} -+ break; -+ -+ case 58: -+#line 527 "./sql.y" -+ { -+ yyval.column_list = yyvsp[-2].column_list; -+ yyval.column_list->next = yyvsp[0].column_list; -+ ;} -+ break; -+ -+ case 59: -+#line 535 "./sql.y" -+ { -+ yyval.column_list = yyvsp[-2].column_list; -+ yyval.column_list->val = yyvsp[0].expr; -+ ;} -+ break; -+ -+ case 60: -+#line 543 "./sql.y" -+ { -+ yyval.expr = EXPR_ival( info, yyvsp[0].integer ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 61: -+#line 549 "./sql.y" -+ { -+ yyval.expr = EXPR_ival( info, -yyvsp[0].integer ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 62: -+#line 555 "./sql.y" -+ { -+ yyval.expr = EXPR_sval( info, &yyvsp[0].str ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 63: -+#line 561 "./sql.y" -+ { -+ yyval.expr = EXPR_wildcard( info ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 64: -+#line 570 "./sql.y" -+ { -+ yyval.expr = EXPR_column( info, yyvsp[0].column_list ); -+ if( !yyval.expr ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 65: -+#line 579 "./sql.y" -+ { -+ yyval.column_list = parser_alloc_column( info, yyvsp[-2].string, yyvsp[0].string ); -+ if( !yyval.column_list ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 66: -+#line 585 "./sql.y" -+ { -+ yyval.column_list = parser_alloc_column( info, NULL, yyvsp[0].string ); -+ if( !yyval.column_list ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 67: -+#line 594 "./sql.y" -+ { -+ yyval.string = yyvsp[0].string; -+ ;} -+ break; -+ -+ case 68: -+#line 601 "./sql.y" -+ { -+ yyval.string = SQL_getstring( info, &yyvsp[0].str ); -+ if( !yyval.string ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 69: -+#line 610 "./sql.y" -+ { -+ yyval.integer = SQL_getint( info ); -+ ;} -+ break; -+ -+ -+ } -+ -+/* Line 1000 of yacc.c. */ -+#line 2054 "sql.tab.c" -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ -+ -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) -+ { -+ ++yynerrs; -+#if YYERROR_VERBOSE -+ yyn = yypact[yystate]; -+ -+ if (YYPACT_NINF < yyn && yyn < YYLAST) -+ { -+ YYSIZE_T yysize = 0; -+ int yytype = YYTRANSLATE (yychar); -+ const char* yyprefix; -+ char *yymsg; -+ int yyx; -+ -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yycount = 0; -+ -+ yyprefix = ", expecting "; -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); -+ yycount += 1; -+ if (yycount == 5) -+ { -+ yysize = 0; -+ break; -+ } -+ } -+ yysize += (sizeof ("syntax error, unexpected ") -+ + yystrlen (yytname[yytype])); -+ yymsg = (char *) YYSTACK_ALLOC (yysize); -+ if (yymsg != 0) -+ { -+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); -+ yyp = yystpcpy (yyp, yytname[yytype]); -+ -+ if (yycount < 5) -+ { -+ yyprefix = ", expecting "; -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ yyp = yystpcpy (yyp, yyprefix); -+ yyp = yystpcpy (yyp, yytname[yyx]); -+ yyprefix = " or "; -+ } -+ } -+ yyerror (yymsg); -+ YYSTACK_FREE (yymsg); -+ } -+ else -+ yyerror ("syntax error; also virtual memory exhausted"); -+ } -+ else -+#endif /* YYERROR_VERBOSE */ -+ yyerror ("syntax error"); -+ } -+ -+ -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse lookahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* If at end of input, pop the error token, -+ then the rest of the stack, then return failure. */ -+ if (yychar == YYEOF) -+ for (;;) -+ { -+ YYPOPSTACK; -+ if (yyssp == yyss) -+ YYABORT; -+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); -+ yydestruct (yystos[*yyssp], yyvsp); -+ } -+ } -+ else -+ { -+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); -+ yydestruct (yytoken, &yylval); -+ yychar = YYEMPTY; -+ -+ } -+ } -+ -+ /* Else will try to reuse lookahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+#ifdef __GNUC__ -+ /* Pacify GCC when the user code never invokes YYERROR and the label -+ yyerrorlab therefore never appears in user code. */ -+ if (0) -+ goto yyerrorlab; -+#endif -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (yyn != YYPACT_NINF) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); -+ yydestruct (yystos[yystate], yyvsp); -+ YYPOPSTACK; -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ YYDPRINTF ((stderr, "Shifting error token, ")); -+ -+ *++yyvsp = yylval; -+ -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#ifndef yyoverflow -+/*----------------------------------------------. -+| yyoverflowlab -- parser overflow comes here. | -+`----------------------------------------------*/ -+yyoverflowlab: -+ yyerror ("parser stack overflow"); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+ return yyresult; -+} -+ -+ -+#line 615 "./sql.y" -+ -+ -+static void *parser_alloc( void *info, unsigned int sz ) -+{ -+ SQL_input* sql = (SQL_input*) info; -+ struct list *mem; -+ -+ mem = msi_alloc( sizeof (struct list) + sz ); -+ list_add_tail( sql->mem, mem ); -+ return &mem[1]; -+} -+ -+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ) -+{ -+ column_info *col; -+ -+ col = parser_alloc( info, sizeof (*col) ); -+ if( col ) -+ { -+ col->table = table; -+ col->column = column; -+ col->val = NULL; -+ col->type = 0; -+ col->next = NULL; -+ } -+ -+ return col; -+} -+ -+int SQL_lex( void *SQL_lval, SQL_input *sql ) -+{ -+ int token; -+ struct sql_str * str = SQL_lval; -+ -+ do -+ { -+ sql->n += sql->len; -+ if( ! sql->command[sql->n] ) -+ return 0; /* end of input */ -+ -+ /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */ -+ sql->len = sqliteGetToken( &sql->command[sql->n], &token ); -+ if( sql->len==0 ) -+ break; -+ str->data = &sql->command[sql->n]; -+ str->len = sql->len; -+ } -+ while( token == TK_SPACE ); -+ -+ /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */ -+ -+ return token; -+} -+ -+LPWSTR SQL_getstring( void *info, struct sql_str *strdata ) -+{ -+ LPCWSTR p = strdata->data; -+ UINT len = strdata->len; -+ LPWSTR str; -+ -+ /* if there's quotes, remove them */ -+ if( ( (p[0]=='`') && (p[len-1]=='`') ) || -+ ( (p[0]=='\'') && (p[len-1]=='\'') ) ) -+ { -+ p++; -+ len -= 2; -+ } -+ str = parser_alloc( info, (len + 1)*sizeof(WCHAR) ); -+ if( !str ) -+ return str; -+ memcpy( str, p, len*sizeof(WCHAR) ); -+ str[len]=0; -+ -+ return str; -+} -+ -+INT SQL_getint( void *info ) -+{ -+ SQL_input* sql = (SQL_input*) info; -+ LPCWSTR p = &sql->command[sql->n]; -+ INT i, r = 0; -+ -+ for( i=0; ilen; i++ ) -+ { -+ if( '0' > p[i] || '9' < p[i] ) -+ { -+ ERR("should only be numbers here!\n"); -+ break; -+ } -+ r = (p[i]-'0') + r*10; -+ } -+ -+ return r; -+} -+ -+int SQL_error( const char *str ) -+{ -+ return 0; -+} -+ -+static struct expr * EXPR_wildcard( void *info ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_WILDCARD; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_COMPLEX; -+ e->u.expr.left = l; -+ e->u.expr.op = op; -+ e->u.expr.right = r; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_column( void *info, column_info *column ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_COLUMN; -+ e->u.sval = column->column; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_ival( void *info, int val ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_IVAL; -+ e->u.ival = val; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_sval( void *info, struct sql_str *str ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_SVAL; -+ e->u.sval = SQL_getstring( info, str ); -+ } -+ return e; -+} -+ -+static BOOL SQL_MarkPrimaryKeys( column_info *cols, -+ column_info *keys ) -+{ -+ column_info *k; -+ BOOL found = TRUE; -+ -+ for( k = keys; k && found; k = k->next ) -+ { -+ column_info *c; -+ -+ found = FALSE; -+ for( c = cols; c && !found; c = c->next ) -+ { -+ if( lstrcmpW( k->column, c->column ) ) -+ continue; -+ c->type |= MSITYPE_KEY; -+ found = TRUE; -+ } -+ } -+ -+ return found; -+} -+ -+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, -+ struct list *mem ) -+{ -+ SQL_input sql; -+ int r; -+ -+ *phview = NULL; -+ -+ sql.db = db; -+ sql.command = command; -+ sql.n = 0; -+ sql.len = 0; -+ sql.view = phview; -+ sql.mem = mem; -+ -+ r = SQL_parse(&sql); -+ -+ TRACE("Parse returned %d\n", r); -+ if( r ) -+ { -+ *sql.view = NULL; -+ return ERROR_BAD_QUERY_SYNTAX; -+ } -+ -+ return ERROR_SUCCESS; -+} -+ -Index: sql.tab.h -=================================================================== ---- sql.tab.h (revision 23782) -+++ sql.tab.h (working copy) -@@ -0,0 +1,345 @@ -+/* A Bison parser, made by GNU Bison 1.875c. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -+ -+ 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, 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., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ TK_ABORT = 258, -+ TK_AFTER = 259, -+ TK_AGG_FUNCTION = 260, -+ TK_ALL = 261, -+ TK_AND = 262, -+ TK_AS = 263, -+ TK_ASC = 264, -+ TK_BEFORE = 265, -+ TK_BEGIN = 266, -+ TK_BETWEEN = 267, -+ TK_BITAND = 268, -+ TK_BITNOT = 269, -+ TK_BITOR = 270, -+ TK_BY = 271, -+ TK_CASCADE = 272, -+ TK_CASE = 273, -+ TK_CHAR = 274, -+ TK_CHECK = 275, -+ TK_CLUSTER = 276, -+ TK_COLLATE = 277, -+ TK_COLUMN = 278, -+ TK_COMMA = 279, -+ TK_COMMENT = 280, -+ TK_COMMIT = 281, -+ TK_CONCAT = 282, -+ TK_CONFLICT = 283, -+ TK_CONSTRAINT = 284, -+ TK_COPY = 285, -+ TK_CREATE = 286, -+ TK_DEFAULT = 287, -+ TK_DEFERRABLE = 288, -+ TK_DEFERRED = 289, -+ TK_DELETE = 290, -+ TK_DELIMITERS = 291, -+ TK_DESC = 292, -+ TK_DISTINCT = 293, -+ TK_DOT = 294, -+ TK_DROP = 295, -+ TK_EACH = 296, -+ TK_ELSE = 297, -+ TK_END = 298, -+ TK_END_OF_FILE = 299, -+ TK_EQ = 300, -+ TK_EXCEPT = 301, -+ TK_EXPLAIN = 302, -+ TK_FAIL = 303, -+ TK_FLOAT = 304, -+ TK_FOR = 305, -+ TK_FOREIGN = 306, -+ TK_FROM = 307, -+ TK_FUNCTION = 308, -+ TK_GE = 309, -+ TK_GLOB = 310, -+ TK_GROUP = 311, -+ TK_GT = 312, -+ TK_HAVING = 313, -+ TK_HOLD = 314, -+ TK_IGNORE = 315, -+ TK_ILLEGAL = 316, -+ TK_IMMEDIATE = 317, -+ TK_IN = 318, -+ TK_INDEX = 319, -+ TK_INITIALLY = 320, -+ TK_ID = 321, -+ TK_INSERT = 322, -+ TK_INSTEAD = 323, -+ TK_INT = 324, -+ TK_INTEGER = 325, -+ TK_INTERSECT = 326, -+ TK_INTO = 327, -+ TK_IS = 328, -+ TK_ISNULL = 329, -+ TK_JOIN = 330, -+ TK_JOIN_KW = 331, -+ TK_KEY = 332, -+ TK_LE = 333, -+ TK_LIKE = 334, -+ TK_LIMIT = 335, -+ TK_LONG = 336, -+ TK_LONGCHAR = 337, -+ TK_LP = 338, -+ TK_LSHIFT = 339, -+ TK_LT = 340, -+ TK_LOCALIZABLE = 341, -+ TK_MATCH = 342, -+ TK_MINUS = 343, -+ TK_NE = 344, -+ TK_NOT = 345, -+ TK_NOTNULL = 346, -+ TK_NULL = 347, -+ TK_OBJECT = 348, -+ TK_OF = 349, -+ TK_OFFSET = 350, -+ TK_ON = 351, -+ TK_OR = 352, -+ TK_ORACLE_OUTER_JOIN = 353, -+ TK_ORDER = 354, -+ TK_PLUS = 355, -+ TK_PRAGMA = 356, -+ TK_PRIMARY = 357, -+ TK_RAISE = 358, -+ TK_REFERENCES = 359, -+ TK_REM = 360, -+ TK_REPLACE = 361, -+ TK_RESTRICT = 362, -+ TK_ROLLBACK = 363, -+ TK_ROW = 364, -+ TK_RP = 365, -+ TK_RSHIFT = 366, -+ TK_SELECT = 367, -+ TK_SEMI = 368, -+ TK_SET = 369, -+ TK_SHORT = 370, -+ TK_SLASH = 371, -+ TK_SPACE = 372, -+ TK_STAR = 373, -+ TK_STATEMENT = 374, -+ TK_STRING = 375, -+ TK_TABLE = 376, -+ TK_TEMP = 377, -+ TK_THEN = 378, -+ TK_TRANSACTION = 379, -+ TK_TRIGGER = 380, -+ TK_UMINUS = 381, -+ TK_UNCLOSED_STRING = 382, -+ TK_UNION = 383, -+ TK_UNIQUE = 384, -+ TK_UPDATE = 385, -+ TK_UPLUS = 386, -+ TK_USING = 387, -+ TK_VACUUM = 388, -+ TK_VALUES = 389, -+ TK_VIEW = 390, -+ TK_WHEN = 391, -+ TK_WHERE = 392, -+ TK_WILDCARD = 393, -+ COLUMN = 395, -+ FUNCTION = 396, -+ COMMENT = 397, -+ UNCLOSED_STRING = 398, -+ SPACE = 399, -+ ILLEGAL = 400, -+ END_OF_FILE = 401 -+ }; -+#endif -+#define TK_ABORT 258 -+#define TK_AFTER 259 -+#define TK_AGG_FUNCTION 260 -+#define TK_ALL 261 -+#define TK_AND 262 -+#define TK_AS 263 -+#define TK_ASC 264 -+#define TK_BEFORE 265 -+#define TK_BEGIN 266 -+#define TK_BETWEEN 267 -+#define TK_BITAND 268 -+#define TK_BITNOT 269 -+#define TK_BITOR 270 -+#define TK_BY 271 -+#define TK_CASCADE 272 -+#define TK_CASE 273 -+#define TK_CHAR 274 -+#define TK_CHECK 275 -+#define TK_CLUSTER 276 -+#define TK_COLLATE 277 -+#define TK_COLUMN 278 -+#define TK_COMMA 279 -+#define TK_COMMENT 280 -+#define TK_COMMIT 281 -+#define TK_CONCAT 282 -+#define TK_CONFLICT 283 -+#define TK_CONSTRAINT 284 -+#define TK_COPY 285 -+#define TK_CREATE 286 -+#define TK_DEFAULT 287 -+#define TK_DEFERRABLE 288 -+#define TK_DEFERRED 289 -+#define TK_DELETE 290 -+#define TK_DELIMITERS 291 -+#define TK_DESC 292 -+#define TK_DISTINCT 293 -+#define TK_DOT 294 -+#define TK_DROP 295 -+#define TK_EACH 296 -+#define TK_ELSE 297 -+#define TK_END 298 -+#define TK_END_OF_FILE 299 -+#define TK_EQ 300 -+#define TK_EXCEPT 301 -+#define TK_EXPLAIN 302 -+#define TK_FAIL 303 -+#define TK_FLOAT 304 -+#define TK_FOR 305 -+#define TK_FOREIGN 306 -+#define TK_FROM 307 -+#define TK_FUNCTION 308 -+#define TK_GE 309 -+#define TK_GLOB 310 -+#define TK_GROUP 311 -+#define TK_GT 312 -+#define TK_HAVING 313 -+#define TK_HOLD 314 -+#define TK_IGNORE 315 -+#define TK_ILLEGAL 316 -+#define TK_IMMEDIATE 317 -+#define TK_IN 318 -+#define TK_INDEX 319 -+#define TK_INITIALLY 320 -+#define TK_ID 321 -+#define TK_INSERT 322 -+#define TK_INSTEAD 323 -+#define TK_INT 324 -+#define TK_INTEGER 325 -+#define TK_INTERSECT 326 -+#define TK_INTO 327 -+#define TK_IS 328 -+#define TK_ISNULL 329 -+#define TK_JOIN 330 -+#define TK_JOIN_KW 331 -+#define TK_KEY 332 -+#define TK_LE 333 -+#define TK_LIKE 334 -+#define TK_LIMIT 335 -+#define TK_LONG 336 -+#define TK_LONGCHAR 337 -+#define TK_LP 338 -+#define TK_LSHIFT 339 -+#define TK_LT 340 -+#define TK_LOCALIZABLE 341 -+#define TK_MATCH 342 -+#define TK_MINUS 343 -+#define TK_NE 344 -+#define TK_NOT 345 -+#define TK_NOTNULL 346 -+#define TK_NULL 347 -+#define TK_OBJECT 348 -+#define TK_OF 349 -+#define TK_OFFSET 350 -+#define TK_ON 351 -+#define TK_OR 352 -+#define TK_ORACLE_OUTER_JOIN 353 -+#define TK_ORDER 354 -+#define TK_PLUS 355 -+#define TK_PRAGMA 356 -+#define TK_PRIMARY 357 -+#define TK_RAISE 358 -+#define TK_REFERENCES 359 -+#define TK_REM 360 -+#define TK_REPLACE 361 -+#define TK_RESTRICT 362 -+#define TK_ROLLBACK 363 -+#define TK_ROW 364 -+#define TK_RP 365 -+#define TK_RSHIFT 366 -+#define TK_SELECT 367 -+#define TK_SEMI 368 -+#define TK_SET 369 -+#define TK_SHORT 370 -+#define TK_SLASH 371 -+#define TK_SPACE 372 -+#define TK_STAR 373 -+#define TK_STATEMENT 374 -+#define TK_STRING 375 -+#define TK_TABLE 376 -+#define TK_TEMP 377 -+#define TK_THEN 378 -+#define TK_TRANSACTION 379 -+#define TK_TRIGGER 380 -+#define TK_UMINUS 381 -+#define TK_UNCLOSED_STRING 382 -+#define TK_UNION 383 -+#define TK_UNIQUE 384 -+#define TK_UPDATE 385 -+#define TK_UPLUS 386 -+#define TK_USING 387 -+#define TK_VACUUM 388 -+#define TK_VALUES 389 -+#define TK_VIEW 390 -+#define TK_WHEN 391 -+#define TK_WHERE 392 -+#define TK_WILDCARD 393 -+#define COLUMN 395 -+#define FUNCTION 396 -+#define COMMENT 397 -+#define UNCLOSED_STRING 398 -+#define SPACE 399 -+#define ILLEGAL 400 -+#define END_OF_FILE 401 -+ -+ -+ -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 72 "./sql.y" -+typedef union YYSTYPE { -+ struct sql_str str; -+ LPWSTR string; -+ column_info *column_list; -+ MSIVIEW *query; -+ struct expr *expr; -+ USHORT column_type; -+ int integer; -+} YYSTYPE; -+/* Line 1275 of yacc.c. */ -+#line 337 "sql.tab.h" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+ -+ -Index: tokenize.c -=================================================================== ---- tokenize.c (revision 23808) -+++ tokenize.c (working copy) -@@ -156,7 +156,7 @@ - static const Keyword aKeywordTable[] = { - { ABORT_W, TK_ABORT }, - { AFTER_W, TK_AFTER }, -+ /*{ ALTER_W, TK_ALTER },*/ -- { ALTER_W, TK_ALTER }, - { ALL_W, TK_ALL }, - { AND_W, TK_AND }, - { AS_W, TK_AS }, +Index: action.c +=================================================================== +--- action.c (revision 23808) ++++ action.c (working copy) +@@ -30,6 +30,7 @@ + + #define COBJMACROS + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winerror.h" +Index: appsearch.c +=================================================================== +--- appsearch.c (revision 23782) ++++ appsearch.c (working copy) +@@ -21,6 +21,7 @@ + + #define COBJMACROS + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winreg.h" +Index: classes.c +=================================================================== +--- classes.c (revision 23808) ++++ classes.c (working copy) +@@ -31,6 +31,7 @@ + + #include + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winerror.h" +Index: cond.tab.c +=================================================================== +--- cond.tab.c (revision 23782) ++++ cond.tab.c (working copy) +@@ -0,0 +1,2239 @@ ++/* A Bison parser, made by GNU Bison 1.875c. */ ++ ++/* Skeleton parser for Yacc-like parsing with Bison, ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++ 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, 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., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ ++ ++/* Written by Richard Stallman by simplifying the original so called ++ ``semantic'' parser. */ ++ ++/* All symbols defined below should begin with yy or YY, to avoid ++ infringing on user name space. This should be done even for local ++ variables, as they might otherwise be expanded by user macros. ++ There are some unavoidable exceptions within include files to ++ define necessary library symbols; they are noted "INFRINGES ON ++ USER NAME SPACE" below. */ ++ ++/* Identify Bison output. */ ++#define YYBISON 1 ++ ++/* Skeleton name. */ ++#define YYSKELETON_NAME "yacc.c" ++ ++/* Pure parsers. */ ++#define YYPURE 1 ++ ++/* Using locations. */ ++#define YYLSP_NEEDED 0 ++ ++/* If NAME_PREFIX is specified substitute the variables and functions ++ names. */ ++#define yyparse COND_parse ++#define yylex COND_lex ++#define yyerror COND_error ++#define yylval COND_lval ++#define yychar COND_char ++#define yydebug COND_debug ++#define yynerrs COND_nerrs ++ ++ ++/* Tokens. */ ++#ifndef YYTOKENTYPE ++# define YYTOKENTYPE ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ COND_SPACE = 258, ++ COND_EOF = 259, ++ COND_OR = 260, ++ COND_AND = 261, ++ COND_NOT = 262, ++ COND_LT = 263, ++ COND_GT = 264, ++ COND_EQ = 265, ++ COND_LPAR = 266, ++ COND_RPAR = 267, ++ COND_TILDA = 268, ++ COND_PERCENT = 269, ++ COND_DOLLARS = 270, ++ COND_QUESTION = 271, ++ COND_AMPER = 272, ++ COND_EXCLAM = 273, ++ COND_IDENT = 274, ++ COND_NUMBER = 275, ++ COND_LITER = 276, ++ COND_ERROR = 277 ++ }; ++#endif ++#define COND_SPACE 258 ++#define COND_EOF 259 ++#define COND_OR 260 ++#define COND_AND 261 ++#define COND_NOT 262 ++#define COND_LT 263 ++#define COND_GT 264 ++#define COND_EQ 265 ++#define COND_LPAR 266 ++#define COND_RPAR 267 ++#define COND_TILDA 268 ++#define COND_PERCENT 269 ++#define COND_DOLLARS 270 ++#define COND_QUESTION 271 ++#define COND_AMPER 272 ++#define COND_EXCLAM 273 ++#define COND_IDENT 274 ++#define COND_NUMBER 275 ++#define COND_LITER 276 ++#define COND_ERROR 277 ++ ++ ++ ++ ++/* Copy the first part of user declarations. */ ++#line 1 "./cond.y" ++ ++ ++/* ++ * Implementation of the Microsoft Installer (msi.dll) ++ * ++ * Copyright 2003 Mike McCormack for CodeWeavers ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "wine/debug.h" ++#include "wine/unicode.h" ++ ++#include "msi.h" ++#include "msiquery.h" ++#include "msipriv.h" ++ ++#define YYLEX_PARAM info ++#define YYPARSE_PARAM info ++ ++static int COND_error(const char *str); ++ ++WINE_DEFAULT_DEBUG_CHANNEL(msi); ++ ++typedef struct tag_yyinput ++{ ++ MSIPACKAGE *package; ++ LPCWSTR str; ++ INT n; ++ MSICONDITION result; ++} COND_input; ++ ++struct cond_str { ++ LPCWSTR data; ++ INT len; ++}; ++ ++static LPWSTR COND_GetString( struct cond_str *str ); ++static LPWSTR COND_GetLiteral( struct cond_str *str ); ++static int COND_lex( void *COND_lval, COND_input *info); ++ ++typedef INT (*comp_int)(INT a, INT b); ++typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless); ++typedef INT (*comp_m1)(LPWSTR a,int b); ++typedef INT (*comp_m2)(int a,LPWSTR b); ++ ++static INT comp_lt_i(INT a, INT b); ++static INT comp_gt_i(INT a, INT b); ++static INT comp_le_i(INT a, INT b); ++static INT comp_ge_i(INT a, INT b); ++static INT comp_eq_i(INT a, INT b); ++static INT comp_ne_i(INT a, INT b); ++static INT comp_bitand(INT a, INT b); ++static INT comp_highcomp(INT a, INT b); ++static INT comp_lowcomp(INT a, INT b); ++ ++static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless); ++static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless); ++ ++static INT comp_eq_m1(LPWSTR a, INT b); ++static INT comp_ne_m1(LPWSTR a, INT b); ++static INT comp_lt_m1(LPWSTR a, INT b); ++static INT comp_gt_m1(LPWSTR a, INT b); ++static INT comp_le_m1(LPWSTR a, INT b); ++static INT comp_ge_m1(LPWSTR a, INT b); ++ ++static INT comp_eq_m2(INT a, LPWSTR b); ++static INT comp_ne_m2(INT a, LPWSTR b); ++static INT comp_lt_m2(INT a, LPWSTR b); ++static INT comp_gt_m2(INT a, LPWSTR b); ++static INT comp_le_m2(INT a, LPWSTR b); ++static INT comp_ge_m2(INT a, LPWSTR b); ++ ++ ++ ++/* Enabling traces. */ ++#ifndef YYDEBUG ++# define YYDEBUG 0 ++#endif ++ ++/* Enabling verbose error messages. */ ++#ifdef YYERROR_VERBOSE ++# undef YYERROR_VERBOSE ++# define YYERROR_VERBOSE 1 ++#else ++# define YYERROR_VERBOSE 0 ++#endif ++ ++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) ++#line 106 "./cond.y" ++typedef union YYSTYPE { ++ struct cond_str str; ++ LPWSTR string; ++ INT value; ++ comp_int fn_comp_int; ++ comp_str fn_comp_str; ++ comp_m1 fn_comp_m1; ++ comp_m2 fn_comp_m2; ++} YYSTYPE; ++/* Line 191 of yacc.c. */ ++#line 241 "cond.tab.c" ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ ++# define YYSTYPE_IS_DECLARED 1 ++# define YYSTYPE_IS_TRIVIAL 1 ++#endif ++ ++ ++ ++/* Copy the second part of user declarations. */ ++ ++ ++/* Line 214 of yacc.c. */ ++#line 253 "cond.tab.c" ++ ++#if ! defined (yyoverflow) || YYERROR_VERBOSE ++ ++# ifndef YYFREE ++# define YYFREE free ++# endif ++# ifndef YYMALLOC ++# define YYMALLOC malloc ++# endif ++ ++/* The parser invokes alloca or malloc; define the necessary symbols. */ ++ ++# ifdef YYSTACK_USE_ALLOCA ++# if YYSTACK_USE_ALLOCA ++# define YYSTACK_ALLOC alloca ++# endif ++# else ++# if defined (alloca) || defined (_ALLOCA_H) ++# define YYSTACK_ALLOC alloca ++# else ++# ifdef __GNUC__ ++# define YYSTACK_ALLOC __builtin_alloca ++# endif ++# endif ++# endif ++ ++# ifdef YYSTACK_ALLOC ++ /* Pacify GCC's `empty if-body' warning. */ ++# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) ++# else ++# if defined (__STDC__) || defined (__cplusplus) ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYSIZE_T size_t ++# endif ++# define YYSTACK_ALLOC YYMALLOC ++# define YYSTACK_FREE YYFREE ++# endif ++#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ ++ ++ ++#if (! defined (yyoverflow) \ ++ && (! defined (__cplusplus) \ ++ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) ++ ++/* A type that is properly aligned for any stack member. */ ++union yyalloc ++{ ++ short yyss; ++ YYSTYPE yyvs; ++ }; ++ ++/* The size of the maximum gap between one aligned stack and the next. */ ++# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) ++ ++/* The size of an array large to enough to hold all stacks, each with ++ N elements. */ ++# define YYSTACK_BYTES(N) \ ++ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ ++ + YYSTACK_GAP_MAXIMUM) ++ ++/* Copy COUNT objects from FROM to TO. The source and destination do ++ not overlap. */ ++# ifndef YYCOPY ++# if defined (__GNUC__) && 1 < __GNUC__ ++# define YYCOPY(To, From, Count) \ ++ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) ++# else ++# define YYCOPY(To, From, Count) \ ++ do \ ++ { \ ++ register YYSIZE_T yyi; \ ++ for (yyi = 0; yyi < (Count); yyi++) \ ++ (To)[yyi] = (From)[yyi]; \ ++ } \ ++ while (0) ++# endif ++# endif ++ ++/* Relocate STACK from its old location to the new one. The ++ local variables YYSIZE and YYSTACKSIZE give the old and new number of ++ elements in the stack, and YYPTR gives the new location of the ++ stack. Advance YYPTR to a properly aligned location for the next ++ stack. */ ++# define YYSTACK_RELOCATE(Stack) \ ++ do \ ++ { \ ++ YYSIZE_T yynewbytes; \ ++ YYCOPY (&yyptr->Stack, Stack, yysize); \ ++ Stack = &yyptr->Stack; \ ++ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ ++ yyptr += yynewbytes / sizeof (*yyptr); \ ++ } \ ++ while (0) ++ ++#endif ++ ++#if defined (__STDC__) || defined (__cplusplus) ++ typedef signed char yysigned_char; ++#else ++ typedef short yysigned_char; ++#endif ++ ++/* YYFINAL -- State number of the termination state. */ ++#define YYFINAL 30 ++/* YYLAST -- Last index in YYTABLE. */ ++#define YYLAST 146 ++ ++/* YYNTOKENS -- Number of terminals. */ ++#define YYNTOKENS 23 ++/* YYNNTS -- Number of nonterminals. */ ++#define YYNNTS 17 ++/* YYNRULES -- Number of rules. */ ++#define YYNRULES 65 ++/* YYNRULES -- Number of states. */ ++#define YYNSTATES 74 ++ ++/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ ++#define YYUNDEFTOK 2 ++#define YYMAXUTOK 277 ++ ++#define YYTRANSLATE(YYX) \ ++ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) ++ ++/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ ++static const unsigned char yytranslate[] = ++{ ++ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, ++ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ++ 15, 16, 17, 18, 19, 20, 21, 22 ++}; ++ ++#if YYDEBUG ++/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in ++ YYRHS. */ ++static const unsigned char yyprhs[] = ++{ ++ 0, 0, 3, 5, 7, 11, 13, 17, 19, 22, ++ 24, 26, 30, 34, 39, 43, 47, 51, 53, 56, ++ 58, 60, 63, 66, 69, 72, 75, 77, 80, 82, ++ 84, 87, 90, 93, 96, 99, 101, 104, 106, 108, ++ 111, 114, 117, 120, 123, 125, 128, 130, 132, 135, ++ 138, 141, 144, 147, 149, 151, 153, 155, 157, 160, ++ 163, 166, 169, 171, 174, 176 ++}; ++ ++/* YYRHS -- A `-1'-separated list of the rules' RHS. */ ++static const yysigned_char yyrhs[] = ++{ ++ 24, 0, -1, 25, -1, 26, -1, 26, 5, 25, ++ -1, 27, -1, 26, 6, 27, -1, 28, -1, 7, ++ 28, -1, 33, -1, 34, -1, 33, 29, 33, -1, ++ 34, 30, 34, -1, 34, 13, 30, 34, -1, 34, ++ 31, 33, -1, 33, 32, 34, -1, 11, 25, 12, ++ -1, 10, -1, 8, 9, -1, 8, -1, 9, -1, ++ 8, 10, -1, 9, 10, -1, 9, 8, -1, 8, ++ 8, -1, 9, 9, -1, 10, -1, 8, 9, -1, ++ 8, -1, 9, -1, 8, 10, -1, 9, 10, -1, ++ 9, 8, -1, 8, 8, -1, 9, 9, -1, 10, ++ -1, 8, 9, -1, 8, -1, 9, -1, 8, 10, ++ -1, 9, 10, -1, 9, 8, -1, 8, 8, -1, ++ 9, 9, -1, 10, -1, 8, 9, -1, 8, -1, ++ 9, -1, 8, 10, -1, 9, 10, -1, 9, 8, ++ -1, 8, 8, -1, 9, 9, -1, 36, -1, 39, ++ -1, 37, -1, 35, -1, 21, -1, 15, 38, -1, ++ 16, 38, -1, 17, 38, -1, 18, 38, -1, 38, ++ -1, 14, 38, -1, 19, -1, 20, -1 ++}; ++ ++/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ ++static const unsigned short yyrline[] = ++{ ++ 0, 136, 136, 144, 148, 155, 159, 166, 170, 178, ++ 182, 187, 191, 197, 203, 208, 213, 221, 225, 229, ++ 233, 237, 241, 246, 250, 254, 262, 266, 270, 274, ++ 278, 282, 287, 291, 295, 303, 307, 311, 315, 319, ++ 323, 328, 332, 336, 344, 348, 352, 356, 360, 364, ++ 369, 373, 377, 384, 388, 395, 399, 406, 415, 424, ++ 433, 442, 454, 477, 491, 500 ++}; ++#endif ++ ++#if YYDEBUG || YYERROR_VERBOSE ++/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. ++ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ ++static const char *const yytname[] = ++{ ++ "$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR", ++ "COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR", ++ "COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS", ++ "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT", ++ "COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition", ++ "expression", "boolean_term", "boolean_factor", "term", "comp_op_i", ++ "comp_op_s", "comp_op_m1", "comp_op_m2", "value_i", "value_s", "literal", ++ "symbol_i", "symbol_s", "identifier", "integer", 0 ++}; ++#endif ++ ++# ifdef YYPRINT ++/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to ++ token YYLEX-NUM. */ ++static const unsigned short yytoknum[] = ++{ ++ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, ++ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, ++ 275, 276, 277 ++}; ++# endif ++ ++/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ ++static const unsigned char yyr1[] = ++{ ++ 0, 23, 24, 25, 25, 26, 26, 27, 27, 28, ++ 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, ++ 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, ++ 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, ++ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, ++ 32, 32, 32, 33, 33, 34, 34, 35, 36, 36, ++ 36, 36, 37, 37, 38, 39 ++}; ++ ++/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ ++static const unsigned char yyr2[] = ++{ ++ 0, 2, 1, 1, 3, 1, 3, 1, 2, 1, ++ 1, 3, 3, 4, 3, 3, 3, 1, 2, 1, ++ 1, 2, 2, 2, 2, 2, 1, 2, 1, 1, ++ 2, 2, 2, 2, 2, 1, 2, 1, 1, 2, ++ 2, 2, 2, 2, 1, 2, 1, 1, 2, 2, ++ 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, ++ 2, 2, 1, 2, 1, 1 ++}; ++ ++/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state ++ STATE-NUM when YYTABLE doesn't specify something else to do. Zero ++ means the default is an error. */ ++static const unsigned char yydefact[] = ++{ ++ 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, ++ 57, 0, 2, 3, 5, 7, 9, 10, 56, 53, ++ 55, 62, 54, 8, 0, 63, 58, 59, 60, 61, ++ 1, 0, 0, 19, 20, 17, 0, 0, 37, 38, ++ 35, 0, 0, 0, 16, 4, 6, 24, 18, 21, ++ 23, 25, 22, 11, 15, 42, 36, 39, 41, 43, ++ 40, 28, 29, 26, 0, 12, 14, 33, 27, 30, ++ 32, 34, 31, 13 ++}; ++ ++/* YYDEFGOTO[NTERM-NUM]. */ ++static const yysigned_char yydefgoto[] = ++{ ++ -1, 11, 12, 13, 14, 15, 36, 42, 43, 37, ++ 16, 17, 18, 19, 20, 21, 22 ++}; ++ ++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ ++#define YYPACT_NINF -37 ++static const short yypact[] = ++{ ++ -4, 51, -4, -11, -11, -11, -11, -11, -37, -37, ++ -37, 18, -37, -1, -37, -37, 49, 14, -37, -37, ++ -37, -37, -37, -37, 19, -37, -37, -37, -37, -37, ++ -37, -4, -4, 11, 25, 34, 111, 59, 28, 42, ++ 60, 130, 59, 111, -37, -37, -37, 63, 69, 72, ++ 73, 81, 82, -37, -37, 85, 91, 94, 95, 103, ++ 104, 133, 136, -37, 59, -37, -37, -37, -37, -37, ++ -37, -37, -37, -37 ++}; ++ ++/* YYPGOTO[NTERM-NUM]. */ ++static const short yypgoto[] = ++{ ++ -37, -37, -2, -37, -6, 39, -37, 0, -37, -37, ++ -34, -36, -37, -37, -37, 129, -37 ++}; ++ ++/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule which ++ number is the opposite. If zero, do what YYDEFACT says. ++ If YYTABLE_NINF, syntax error. */ ++#define YYTABLE_NINF -53 ++static const yysigned_char yytable[] = ++{ ++ 24, 54, 53, 1, 31, 32, 65, 2, 8, 66, ++ 3, 4, 5, 6, 7, 8, 9, 10, 30, 47, ++ 48, 49, 38, 39, 40, -46, 46, 41, 73, 45, ++ -46, 44, -46, 50, 51, 52, 55, 56, 57, -47, ++ 23, 64, -28, 0, -47, 0, -47, -28, -44, -28, ++ 58, 59, 60, -44, 0, -44, -29, 33, 34, 35, ++ 0, -29, 2, -29, 0, 3, 4, 5, 6, 7, ++ 8, 9, 10, 3, -26, 0, 0, -51, 8, -26, ++ 10, -26, -51, -45, -51, 0, -48, -50, -45, 0, ++ -45, -48, -50, -48, -50, -52, -49, 0, 0, -33, ++ -52, -49, -52, -49, -33, -27, -33, 0, -30, -32, ++ -27, 0, -27, -30, -32, -30, -32, -34, -31, 0, ++ 0, 0, -34, -31, -34, -31, 4, 5, 6, 7, ++ 0, 9, 25, 26, 27, 28, 29, 0, 61, 62, ++ 63, 67, 68, 69, 70, 71, 72 ++}; ++ ++static const yysigned_char yycheck[] = ++{ ++ 2, 37, 36, 7, 5, 6, 42, 11, 19, 43, ++ 14, 15, 16, 17, 18, 19, 20, 21, 0, 8, ++ 9, 10, 8, 9, 10, 14, 32, 13, 64, 31, ++ 19, 12, 21, 8, 9, 10, 8, 9, 10, 14, ++ 1, 41, 14, -1, 19, -1, 21, 19, 14, 21, ++ 8, 9, 10, 19, -1, 21, 14, 8, 9, 10, ++ -1, 19, 11, 21, -1, 14, 15, 16, 17, 18, ++ 19, 20, 21, 14, 14, -1, -1, 14, 19, 19, ++ 21, 21, 19, 14, 21, -1, 14, 14, 19, -1, ++ 21, 19, 19, 21, 21, 14, 14, -1, -1, 14, ++ 19, 19, 21, 21, 19, 14, 21, -1, 14, 14, ++ 19, -1, 21, 19, 19, 21, 21, 14, 14, -1, ++ -1, -1, 19, 19, 21, 21, 15, 16, 17, 18, ++ -1, 20, 3, 4, 5, 6, 7, -1, 8, 9, ++ 10, 8, 9, 10, 8, 9, 10 ++}; ++ ++/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing ++ symbol of state STATE-NUM. */ ++static const unsigned char yystos[] = ++{ ++ 0, 7, 11, 14, 15, 16, 17, 18, 19, 20, ++ 21, 24, 25, 26, 27, 28, 33, 34, 35, 36, ++ 37, 38, 39, 28, 25, 38, 38, 38, 38, 38, ++ 0, 5, 6, 8, 9, 10, 29, 32, 8, 9, ++ 10, 13, 30, 31, 12, 25, 27, 8, 9, 10, ++ 8, 9, 10, 33, 34, 8, 9, 10, 8, 9, ++ 10, 8, 9, 10, 30, 34, 33, 8, 9, 10, ++ 8, 9, 10, 34 ++}; ++ ++#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) ++# define YYSIZE_T __SIZE_TYPE__ ++#endif ++#if ! defined (YYSIZE_T) && defined (size_t) ++# define YYSIZE_T size_t ++#endif ++#if ! defined (YYSIZE_T) ++# if defined (__STDC__) || defined (__cplusplus) ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYSIZE_T size_t ++# endif ++#endif ++#if ! defined (YYSIZE_T) ++# define YYSIZE_T unsigned int ++#endif ++ ++#define yyerrok (yyerrstatus = 0) ++#define yyclearin (yychar = YYEMPTY) ++#define YYEMPTY (-2) ++#define YYEOF 0 ++ ++#define YYACCEPT goto yyacceptlab ++#define YYABORT goto yyabortlab ++#define YYERROR goto yyerrorlab ++ ++ ++/* Like YYERROR except do call yyerror. This remains here temporarily ++ to ease the transition to the new meaning of YYERROR, for GCC. ++ Once GCC version 2 has supplanted version 1, this can go. */ ++ ++#define YYFAIL goto yyerrlab ++ ++#define YYRECOVERING() (!!yyerrstatus) ++ ++#define YYBACKUP(Token, Value) \ ++do \ ++ if (yychar == YYEMPTY && yylen == 1) \ ++ { \ ++ yychar = (Token); \ ++ yylval = (Value); \ ++ yytoken = YYTRANSLATE (yychar); \ ++ YYPOPSTACK; \ ++ goto yybackup; \ ++ } \ ++ else \ ++ { \ ++ yyerror ("syntax error: cannot back up");\ ++ YYERROR; \ ++ } \ ++while (0) ++ ++#define YYTERROR 1 ++#define YYERRCODE 256 ++ ++/* YYLLOC_DEFAULT -- Compute the default location (before the actions ++ are run). */ ++ ++#ifndef YYLLOC_DEFAULT ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ ((Current).first_line = (Rhs)[1].first_line, \ ++ (Current).first_column = (Rhs)[1].first_column, \ ++ (Current).last_line = (Rhs)[N].last_line, \ ++ (Current).last_column = (Rhs)[N].last_column) ++#endif ++ ++/* YYLEX -- calling `yylex' with the right arguments. */ ++ ++#ifdef YYLEX_PARAM ++# define YYLEX yylex (&yylval, YYLEX_PARAM) ++#else ++# define YYLEX yylex (&yylval) ++#endif ++ ++/* Enable debugging if requested. */ ++#if YYDEBUG ++ ++# ifndef YYFPRINTF ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYFPRINTF fprintf ++# endif ++ ++# define YYDPRINTF(Args) \ ++do { \ ++ if (yydebug) \ ++ YYFPRINTF Args; \ ++} while (0) ++ ++# define YYDSYMPRINT(Args) \ ++do { \ ++ if (yydebug) \ ++ yysymprint Args; \ ++} while (0) ++ ++# define YYDSYMPRINTF(Title, Token, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yysymprint (stderr, \ ++ Token, Value); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (0) ++ ++/*------------------------------------------------------------------. ++| yy_stack_print -- Print the state stack from its BOTTOM up to its | ++| TOP (included). | ++`------------------------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_stack_print (short *bottom, short *top) ++#else ++static void ++yy_stack_print (bottom, top) ++ short *bottom; ++ short *top; ++#endif ++{ ++ YYFPRINTF (stderr, "Stack now"); ++ for (/* Nothing. */; bottom <= top; ++bottom) ++ YYFPRINTF (stderr, " %d", *bottom); ++ YYFPRINTF (stderr, "\n"); ++} ++ ++# define YY_STACK_PRINT(Bottom, Top) \ ++do { \ ++ if (yydebug) \ ++ yy_stack_print ((Bottom), (Top)); \ ++} while (0) ++ ++ ++/*------------------------------------------------. ++| Report that the YYRULE is going to be reduced. | ++`------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_reduce_print (int yyrule) ++#else ++static void ++yy_reduce_print (yyrule) ++ int yyrule; ++#endif ++{ ++ int yyi; ++ unsigned int yylno = yyrline[yyrule]; ++ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", ++ yyrule - 1, yylno); ++ /* Print the symbols being reduced, and their result. */ ++ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) ++ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); ++ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); ++} ++ ++# define YY_REDUCE_PRINT(Rule) \ ++do { \ ++ if (yydebug) \ ++ yy_reduce_print (Rule); \ ++} while (0) ++ ++/* Nonzero means print parse trace. It is left uninitialized so that ++ multiple parsers can coexist. */ ++int yydebug; ++#else /* !YYDEBUG */ ++# define YYDPRINTF(Args) ++# define YYDSYMPRINT(Args) ++# define YYDSYMPRINTF(Title, Token, Value, Location) ++# define YY_STACK_PRINT(Bottom, Top) ++# define YY_REDUCE_PRINT(Rule) ++#endif /* !YYDEBUG */ ++ ++ ++/* YYINITDEPTH -- initial size of the parser's stacks. */ ++#ifndef YYINITDEPTH ++# define YYINITDEPTH 200 ++#endif ++ ++/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only ++ if the built-in stack extension method is used). ++ ++ Do not make this value too large; the results are undefined if ++ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) ++ evaluated with infinite-precision integer arithmetic. */ ++ ++#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 ++# undef YYMAXDEPTH ++#endif ++ ++#ifndef YYMAXDEPTH ++# define YYMAXDEPTH 10000 ++#endif ++ ++ ++ ++#if YYERROR_VERBOSE ++ ++# ifndef yystrlen ++# if defined (__GLIBC__) && defined (_STRING_H) ++# define yystrlen strlen ++# else ++/* Return the length of YYSTR. */ ++static YYSIZE_T ++# if defined (__STDC__) || defined (__cplusplus) ++yystrlen (const char *yystr) ++# else ++yystrlen (yystr) ++ const char *yystr; ++# endif ++{ ++ register const char *yys = yystr; ++ ++ while (*yys++ != '\0') ++ continue; ++ ++ return yys - yystr - 1; ++} ++# endif ++# endif ++ ++# ifndef yystpcpy ++# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) ++# define yystpcpy stpcpy ++# else ++/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in ++ YYDEST. */ ++static char * ++# if defined (__STDC__) || defined (__cplusplus) ++yystpcpy (char *yydest, const char *yysrc) ++# else ++yystpcpy (yydest, yysrc) ++ char *yydest; ++ const char *yysrc; ++# endif ++{ ++ register char *yyd = yydest; ++ register const char *yys = yysrc; ++ ++ while ((*yyd++ = *yys++) != '\0') ++ continue; ++ ++ return yyd - 1; ++} ++# endif ++# endif ++ ++#endif /* !YYERROR_VERBOSE */ ++ ++ ++ ++#if YYDEBUG ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yysymprint (yyoutput, yytype, yyvaluep) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ if (yytype < YYNTOKENS) ++ { ++ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); ++# ifdef YYPRINT ++ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++# endif ++ } ++ else ++ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); ++ ++ switch (yytype) ++ { ++ default: ++ break; ++ } ++ YYFPRINTF (yyoutput, ")"); ++} ++ ++#endif /* ! YYDEBUG */ ++/*-----------------------------------------------. ++| Release the memory associated to this symbol. | ++`-----------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yydestruct (int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yydestruct (yytype, yyvaluep) ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ switch (yytype) ++ { ++ ++ default: ++ break; ++ } ++} ++ ++ ++/* Prevent warnings from -Wmissing-prototypes. */ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM); ++# else ++int yyparse (); ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void); ++#else ++int yyparse (); ++#endif ++#endif /* ! YYPARSE_PARAM */ ++ ++ ++ ++ ++ ++ ++/*----------. ++| yyparse. | ++`----------*/ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM) ++# else ++int yyparse (YYPARSE_PARAM) ++ void *YYPARSE_PARAM; ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int ++yyparse (void) ++#else ++int ++yyparse () ++ ++#endif ++#endif ++{ ++ /* The lookahead symbol. */ ++int yychar; ++ ++/* The semantic value of the lookahead symbol. */ ++YYSTYPE yylval; ++ ++/* Number of syntax errors so far. */ ++int yynerrs; ++ ++ register int yystate; ++ register int yyn; ++ int yyresult; ++ /* Number of tokens to shift before error messages enabled. */ ++ int yyerrstatus; ++ /* Lookahead token as an internal (translated) token number. */ ++ int yytoken = 0; ++ ++ /* Three stacks and their tools: ++ `yyss': related to states, ++ `yyvs': related to semantic values, ++ `yyls': related to locations. ++ ++ Refer to the stacks thru separate pointers, to allow yyoverflow ++ to reallocate them elsewhere. */ ++ ++ /* The state stack. */ ++ short yyssa[YYINITDEPTH]; ++ short *yyss = yyssa; ++ register short *yyssp; ++ ++ /* The semantic value stack. */ ++ YYSTYPE yyvsa[YYINITDEPTH]; ++ YYSTYPE *yyvs = yyvsa; ++ register YYSTYPE *yyvsp; ++ ++ ++ ++#define YYPOPSTACK (yyvsp--, yyssp--) ++ ++ YYSIZE_T yystacksize = YYINITDEPTH; ++ ++ /* The variables used to return semantic value and location from the ++ action routines. */ ++ YYSTYPE yyval; ++ ++ ++ /* When reducing, the number of symbols on the RHS of the reduced ++ rule. */ ++ int yylen; ++ ++ YYDPRINTF ((stderr, "Starting parse\n")); ++ ++ yystate = 0; ++ yyerrstatus = 0; ++ yynerrs = 0; ++ yychar = YYEMPTY; /* Cause a token to be read. */ ++ ++ /* Initialize stack pointers. ++ Waste one element of value and location stack ++ so that they stay on the same level as the state stack. ++ The wasted elements are never initialized. */ ++ ++ yyssp = yyss; ++ yyvsp = yyvs; ++ ++ goto yysetstate; ++ ++/*------------------------------------------------------------. ++| yynewstate -- Push a new state, which is found in yystate. | ++`------------------------------------------------------------*/ ++ yynewstate: ++ /* In all cases, when you get here, the value and location stacks ++ have just been pushed. so pushing a state here evens the stacks. ++ */ ++ yyssp++; ++ ++ yysetstate: ++ *yyssp = yystate; ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ { ++ /* Get the current used size of the three stacks, in elements. */ ++ YYSIZE_T yysize = yyssp - yyss + 1; ++ ++#ifdef yyoverflow ++ { ++ /* Give user a chance to reallocate the stack. Use copies of ++ these so that the &'s don't force the real ones into ++ memory. */ ++ YYSTYPE *yyvs1 = yyvs; ++ short *yyss1 = yyss; ++ ++ ++ /* Each stack pointer address is followed by the size of the ++ data in use in that stack, in bytes. This used to be a ++ conditional around just the two extra args, but that might ++ be undefined if yyoverflow is a macro. */ ++ yyoverflow ("parser stack overflow", ++ &yyss1, yysize * sizeof (*yyssp), ++ &yyvs1, yysize * sizeof (*yyvsp), ++ ++ &yystacksize); ++ ++ yyss = yyss1; ++ yyvs = yyvs1; ++ } ++#else /* no yyoverflow */ ++# ifndef YYSTACK_RELOCATE ++ goto yyoverflowlab; ++# else ++ /* Extend the stack our own way. */ ++ if (YYMAXDEPTH <= yystacksize) ++ goto yyoverflowlab; ++ yystacksize *= 2; ++ if (YYMAXDEPTH < yystacksize) ++ yystacksize = YYMAXDEPTH; ++ ++ { ++ short *yyss1 = yyss; ++ union yyalloc *yyptr = ++ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ if (! yyptr) ++ goto yyoverflowlab; ++ YYSTACK_RELOCATE (yyss); ++ YYSTACK_RELOCATE (yyvs); ++ ++# undef YYSTACK_RELOCATE ++ if (yyss1 != yyssa) ++ YYSTACK_FREE (yyss1); ++ } ++# endif ++#endif /* no yyoverflow */ ++ ++ yyssp = yyss + yysize - 1; ++ yyvsp = yyvs + yysize - 1; ++ ++ ++ YYDPRINTF ((stderr, "Stack size increased to %lu\n", ++ (unsigned long int) yystacksize)); ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ YYABORT; ++ } ++ ++ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); ++ ++ goto yybackup; ++ ++/*-----------. ++| yybackup. | ++`-----------*/ ++yybackup: ++ ++/* Do appropriate processing given the current state. */ ++/* Read a lookahead token if we need one and don't already have one. */ ++/* yyresume: */ ++ ++ /* First try to decide what to do without reference to lookahead token. */ ++ ++ yyn = yypact[yystate]; ++ if (yyn == YYPACT_NINF) ++ goto yydefault; ++ ++ /* Not known => get a lookahead token if don't already have one. */ ++ ++ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ ++ if (yychar == YYEMPTY) ++ { ++ YYDPRINTF ((stderr, "Reading a token: ")); ++ yychar = YYLEX; ++ } ++ ++ if (yychar <= YYEOF) ++ { ++ yychar = yytoken = YYEOF; ++ YYDPRINTF ((stderr, "Now at end of input.\n")); ++ } ++ else ++ { ++ yytoken = YYTRANSLATE (yychar); ++ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); ++ } ++ ++ /* If the proper action on seeing token YYTOKEN is to reduce or to ++ detect an error, take that action. */ ++ yyn += yytoken; ++ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) ++ goto yydefault; ++ yyn = yytable[yyn]; ++ if (yyn <= 0) ++ { ++ if (yyn == 0 || yyn == YYTABLE_NINF) ++ goto yyerrlab; ++ yyn = -yyn; ++ goto yyreduce; ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ /* Shift the lookahead token. */ ++ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); ++ ++ /* Discard the token being shifted unless it is eof. */ ++ if (yychar != YYEOF) ++ yychar = YYEMPTY; ++ ++ *++yyvsp = yylval; ++ ++ ++ /* Count tokens shifted since error; after three, turn off error ++ status. */ ++ if (yyerrstatus) ++ yyerrstatus--; ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-----------------------------------------------------------. ++| yydefault -- do the default action for the current state. | ++`-----------------------------------------------------------*/ ++yydefault: ++ yyn = yydefact[yystate]; ++ if (yyn == 0) ++ goto yyerrlab; ++ goto yyreduce; ++ ++ ++/*-----------------------------. ++| yyreduce -- Do a reduction. | ++`-----------------------------*/ ++yyreduce: ++ /* yyn is the number of a rule to reduce with. */ ++ yylen = yyr2[yyn]; ++ ++ /* If YYLEN is nonzero, implement the default value of the action: ++ `$$ = $1'. ++ ++ Otherwise, the following line sets YYVAL to garbage. ++ This behavior is undocumented and Bison ++ users should not rely upon it. Assigning to YYVAL ++ unconditionally makes the parser a bit smaller, and it avoids a ++ GCC warning that YYVAL may be used uninitialized. */ ++ yyval = yyvsp[1-yylen]; ++ ++ ++ YY_REDUCE_PRINT (yyn); ++ switch (yyn) ++ { ++ case 2: ++#line 137 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ cond->result = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 3: ++#line 145 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 4: ++#line 149 "./cond.y" ++ { ++ yyval.value = yyvsp[-2].value || yyvsp[0].value; ++ ;} ++ break; ++ ++ case 5: ++#line 156 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 6: ++#line 160 "./cond.y" ++ { ++ yyval.value = yyvsp[-2].value && yyvsp[0].value; ++ ;} ++ break; ++ ++ case 7: ++#line 167 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 8: ++#line 171 "./cond.y" ++ { ++ yyval.value = ! yyvsp[0].value; ++ ;} ++ break; ++ ++ case 9: ++#line 179 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 10: ++#line 183 "./cond.y" ++ { ++ yyval.value = (yyvsp[0].string && yyvsp[0].string[0]) ? MSICONDITION_TRUE : MSICONDITION_FALSE; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 11: ++#line 188 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_int( yyvsp[-2].value, yyvsp[0].value ); ++ ;} ++ break; ++ ++ case 12: ++#line 192 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-2].string, yyvsp[0].string, FALSE ); ++ msi_free( yyvsp[-2].string ); ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 13: ++#line 198 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_str( yyvsp[-3].string, yyvsp[0].string, TRUE ); ++ msi_free( yyvsp[-3].string ); ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 14: ++#line 204 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_m1( yyvsp[-2].string, yyvsp[0].value ); ++ msi_free( yyvsp[-2].string ); ++ ;} ++ break; ++ ++ case 15: ++#line 209 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].fn_comp_m2( yyvsp[-2].value, yyvsp[0].string ); ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 16: ++#line 214 "./cond.y" ++ { ++ yyval.value = yyvsp[-1].value; ++ ;} ++ break; ++ ++ case 17: ++#line 222 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_eq_i; ++ ;} ++ break; ++ ++ case 18: ++#line 226 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_ne_i; ++ ;} ++ break; ++ ++ case 19: ++#line 230 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_lt_i; ++ ;} ++ break; ++ ++ case 20: ++#line 234 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_gt_i; ++ ;} ++ break; ++ ++ case 21: ++#line 238 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_le_i; ++ ;} ++ break; ++ ++ case 22: ++#line 242 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_ge_i; ++ ;} ++ break; ++ ++ case 23: ++#line 247 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_bitand; ++ ;} ++ break; ++ ++ case 24: ++#line 251 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_highcomp; ++ ;} ++ break; ++ ++ case 25: ++#line 255 "./cond.y" ++ { ++ yyval.fn_comp_int = comp_lowcomp; ++ ;} ++ break; ++ ++ case 26: ++#line 263 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_eq_s; ++ ;} ++ break; ++ ++ case 27: ++#line 267 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_ne_s; ++ ;} ++ break; ++ ++ case 28: ++#line 271 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_lt_s; ++ ;} ++ break; ++ ++ case 29: ++#line 275 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_gt_s; ++ ;} ++ break; ++ ++ case 30: ++#line 279 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_le_s; ++ ;} ++ break; ++ ++ case 31: ++#line 283 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_ge_s; ++ ;} ++ break; ++ ++ case 32: ++#line 288 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_substring; ++ ;} ++ break; ++ ++ case 33: ++#line 292 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_start; ++ ;} ++ break; ++ ++ case 34: ++#line 296 "./cond.y" ++ { ++ yyval.fn_comp_str = comp_end; ++ ;} ++ break; ++ ++ case 35: ++#line 304 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_eq_m1; ++ ;} ++ break; ++ ++ case 36: ++#line 308 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_ne_m1; ++ ;} ++ break; ++ ++ case 37: ++#line 312 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_lt_m1; ++ ;} ++ break; ++ ++ case 38: ++#line 316 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_gt_m1; ++ ;} ++ break; ++ ++ case 39: ++#line 320 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_le_m1; ++ ;} ++ break; ++ ++ case 40: ++#line 324 "./cond.y" ++ { ++ yyval.fn_comp_m1 = comp_ge_m1; ++ ;} ++ break; ++ ++ case 41: ++#line 329 "./cond.y" ++ { ++ yyval.fn_comp_m1 = 0; ++ ;} ++ break; ++ ++ case 42: ++#line 333 "./cond.y" ++ { ++ yyval.fn_comp_m1 = 0; ++ ;} ++ break; ++ ++ case 43: ++#line 337 "./cond.y" ++ { ++ yyval.fn_comp_m1 = 0; ++ ;} ++ break; ++ ++ case 44: ++#line 345 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_eq_m2; ++ ;} ++ break; ++ ++ case 45: ++#line 349 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_ne_m2; ++ ;} ++ break; ++ ++ case 46: ++#line 353 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_lt_m2; ++ ;} ++ break; ++ ++ case 47: ++#line 357 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_gt_m2; ++ ;} ++ break; ++ ++ case 48: ++#line 361 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_le_m2; ++ ;} ++ break; ++ ++ case 49: ++#line 365 "./cond.y" ++ { ++ yyval.fn_comp_m2 = comp_ge_m2; ++ ;} ++ break; ++ ++ case 50: ++#line 370 "./cond.y" ++ { ++ yyval.fn_comp_m2 = 0; ++ ;} ++ break; ++ ++ case 51: ++#line 374 "./cond.y" ++ { ++ yyval.fn_comp_m2 = 0; ++ ;} ++ break; ++ ++ case 52: ++#line 378 "./cond.y" ++ { ++ yyval.fn_comp_m2 = 0; ++ ;} ++ break; ++ ++ case 53: ++#line 385 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 54: ++#line 389 "./cond.y" ++ { ++ yyval.value = yyvsp[0].value; ++ ;} ++ break; ++ ++ case 55: ++#line 396 "./cond.y" ++ { ++ yyval.string = yyvsp[0].string; ++ ;} ++ break; ++ ++ case 56: ++#line 400 "./cond.y" ++ { ++ yyval.string = yyvsp[0].string; ++ ;} ++ break; ++ ++ case 57: ++#line 407 "./cond.y" ++ { ++ yyval.string = COND_GetLiteral(&yyvsp[0].str); ++ if( !yyval.string ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 58: ++#line 416 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; ++ ++ MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action ); ++ yyval.value = action; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 59: ++#line 425 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; ++ ++ MSI_GetComponentStateW(cond->package, yyvsp[0].string, &install, &action ); ++ yyval.value = install; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 60: ++#line 434 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; ++ ++ MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action ); ++ yyval.value = action; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 61: ++#line 443 "./cond.y" ++ { ++ COND_input* cond = (COND_input*) info; ++ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; ++ ++ MSI_GetFeatureStateW(cond->package, yyvsp[0].string, &install, &action ); ++ yyval.value = install; ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 62: ++#line 455 "./cond.y" ++ { ++ DWORD sz; ++ COND_input* cond = (COND_input*) info; ++ ++ sz = 0; ++ MSI_GetPropertyW(cond->package, yyvsp[0].string, NULL, &sz); ++ if (sz == 0) ++ { ++ yyval.string = msi_alloc( sizeof(WCHAR)); ++ yyval.string[0] = 0; ++ } ++ else ++ { ++ sz ++; ++ yyval.string = msi_alloc( sz*sizeof (WCHAR) ); ++ ++ /* Lookup the identifier */ ++ ++ MSI_GetPropertyW(cond->package,yyvsp[0].string,yyval.string,&sz); ++ } ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 63: ++#line 478 "./cond.y" ++ { ++ UINT len = GetEnvironmentVariableW( yyvsp[0].string, NULL, 0 ); ++ if( len++ ) ++ { ++ yyval.string = msi_alloc( len*sizeof (WCHAR) ); ++ if( yyval.string ) ++ GetEnvironmentVariableW( yyvsp[0].string, yyval.string, len ); ++ } ++ msi_free( yyvsp[0].string ); ++ ;} ++ break; ++ ++ case 64: ++#line 492 "./cond.y" ++ { ++ yyval.string = COND_GetString(&yyvsp[0].str); ++ if( !yyval.string ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 65: ++#line 501 "./cond.y" ++ { ++ LPWSTR szNum = COND_GetString(&yyvsp[0].str); ++ if( !szNum ) ++ YYABORT; ++ yyval.value = atoiW( szNum ); ++ msi_free( szNum ); ++ ;} ++ break; ++ ++ ++ } ++ ++/* Line 1000 of yacc.c. */ ++#line 1733 "cond.tab.c" ++ ++ yyvsp -= yylen; ++ yyssp -= yylen; ++ ++ ++ YY_STACK_PRINT (yyss, yyssp); ++ ++ *++yyvsp = yyval; ++ ++ ++ /* Now `shift' the result of the reduction. Determine what state ++ that goes to, based on the state we popped back to and the rule ++ number reduced by. */ ++ ++ yyn = yyr1[yyn]; ++ ++ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; ++ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) ++ yystate = yytable[yystate]; ++ else ++ yystate = yydefgoto[yyn - YYNTOKENS]; ++ ++ goto yynewstate; ++ ++ ++/*------------------------------------. ++| yyerrlab -- here on detecting error | ++`------------------------------------*/ ++yyerrlab: ++ /* If not already recovering from an error, report this error. */ ++ if (!yyerrstatus) ++ { ++ ++yynerrs; ++#if YYERROR_VERBOSE ++ yyn = yypact[yystate]; ++ ++ if (YYPACT_NINF < yyn && yyn < YYLAST) ++ { ++ YYSIZE_T yysize = 0; ++ int yytype = YYTRANSLATE (yychar); ++ const char* yyprefix; ++ char *yymsg; ++ int yyx; ++ ++ /* Start YYX at -YYN if negative to avoid negative indexes in ++ YYCHECK. */ ++ int yyxbegin = yyn < 0 ? -yyn : 0; ++ ++ /* Stay within bounds of both yycheck and yytname. */ ++ int yychecklim = YYLAST - yyn; ++ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; ++ int yycount = 0; ++ ++ yyprefix = ", expecting "; ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); ++ yycount += 1; ++ if (yycount == 5) ++ { ++ yysize = 0; ++ break; ++ } ++ } ++ yysize += (sizeof ("syntax error, unexpected ") ++ + yystrlen (yytname[yytype])); ++ yymsg = (char *) YYSTACK_ALLOC (yysize); ++ if (yymsg != 0) ++ { ++ char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); ++ yyp = yystpcpy (yyp, yytname[yytype]); ++ ++ if (yycount < 5) ++ { ++ yyprefix = ", expecting "; ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ yyp = yystpcpy (yyp, yyprefix); ++ yyp = yystpcpy (yyp, yytname[yyx]); ++ yyprefix = " or "; ++ } ++ } ++ yyerror (yymsg); ++ YYSTACK_FREE (yymsg); ++ } ++ else ++ yyerror ("syntax error; also virtual memory exhausted"); ++ } ++ else ++#endif /* YYERROR_VERBOSE */ ++ yyerror ("syntax error"); ++ } ++ ++ ++ ++ if (yyerrstatus == 3) ++ { ++ /* If just tried and failed to reuse lookahead token after an ++ error, discard it. */ ++ ++ if (yychar <= YYEOF) ++ { ++ /* If at end of input, pop the error token, ++ then the rest of the stack, then return failure. */ ++ if (yychar == YYEOF) ++ for (;;) ++ { ++ YYPOPSTACK; ++ if (yyssp == yyss) ++ YYABORT; ++ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); ++ yydestruct (yystos[*yyssp], yyvsp); ++ } ++ } ++ else ++ { ++ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); ++ yydestruct (yytoken, &yylval); ++ yychar = YYEMPTY; ++ ++ } ++ } ++ ++ /* Else will try to reuse lookahead token after shifting the error ++ token. */ ++ goto yyerrlab1; ++ ++ ++/*---------------------------------------------------. ++| yyerrorlab -- error raised explicitly by YYERROR. | ++`---------------------------------------------------*/ ++yyerrorlab: ++ ++#ifdef __GNUC__ ++ /* Pacify GCC when the user code never invokes YYERROR and the label ++ yyerrorlab therefore never appears in user code. */ ++ if (0) ++ goto yyerrorlab; ++#endif ++ ++ yyvsp -= yylen; ++ yyssp -= yylen; ++ yystate = *yyssp; ++ goto yyerrlab1; ++ ++ ++/*-------------------------------------------------------------. ++| yyerrlab1 -- common code for both syntax error and YYERROR. | ++`-------------------------------------------------------------*/ ++yyerrlab1: ++ yyerrstatus = 3; /* Each real token shifted decrements this. */ ++ ++ for (;;) ++ { ++ yyn = yypact[yystate]; ++ if (yyn != YYPACT_NINF) ++ { ++ yyn += YYTERROR; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ { ++ yyn = yytable[yyn]; ++ if (0 < yyn) ++ break; ++ } ++ } ++ ++ /* Pop the current state because it cannot handle the error token. */ ++ if (yyssp == yyss) ++ YYABORT; ++ ++ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); ++ yydestruct (yystos[yystate], yyvsp); ++ YYPOPSTACK; ++ yystate = *yyssp; ++ YY_STACK_PRINT (yyss, yyssp); ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ YYDPRINTF ((stderr, "Shifting error token, ")); ++ ++ *++yyvsp = yylval; ++ ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-------------------------------------. ++| yyacceptlab -- YYACCEPT comes here. | ++`-------------------------------------*/ ++yyacceptlab: ++ yyresult = 0; ++ goto yyreturn; ++ ++/*-----------------------------------. ++| yyabortlab -- YYABORT comes here. | ++`-----------------------------------*/ ++yyabortlab: ++ yyresult = 1; ++ goto yyreturn; ++ ++#ifndef yyoverflow ++/*----------------------------------------------. ++| yyoverflowlab -- parser overflow comes here. | ++`----------------------------------------------*/ ++yyoverflowlab: ++ yyerror ("parser stack overflow"); ++ yyresult = 2; ++ /* Fall through. */ ++#endif ++ ++yyreturn: ++#ifndef yyoverflow ++ if (yyss != yyssa) ++ YYSTACK_FREE (yyss); ++#endif ++ return yyresult; ++} ++ ++ ++#line 510 "./cond.y" ++ ++ ++ ++static int COND_IsAlpha( WCHAR x ) ++{ ++ return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) || ++ ( ( x >= 'a' ) && ( x <= 'z' ) ) || ++ ( ( x == '_' ) ) ); ++} ++ ++static int COND_IsNumber( WCHAR x ) ++{ ++ return( (( x >= '0' ) && ( x <= '9' )) || (x =='-') || (x =='.') ); ++} ++ ++ ++/* the mess of comparison functions */ ++ ++static INT comp_lt_i(INT a, INT b) ++{ return (a < b); } ++static INT comp_gt_i(INT a, INT b) ++{ return (a > b); } ++static INT comp_le_i(INT a, INT b) ++{ return (a <= b); } ++static INT comp_ge_i(INT a, INT b) ++{ return (a >= b); } ++static INT comp_eq_i(INT a, INT b) ++{ return (a == b); } ++static INT comp_ne_i(INT a, INT b) ++{ return (a != b); } ++static INT comp_bitand(INT a, INT b) ++{ return a & b;} ++static INT comp_highcomp(INT a, INT b) ++{ return HIWORD(a)==b; } ++static INT comp_lowcomp(INT a, INT b) ++{ return LOWORD(a)==b; } ++ ++static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return !strcmpiW(a,b); else return !strcmpW(a,b);} ++static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b); else return strcmpW(a,b);} ++static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b)<0; else return strcmpW(a,b)<0;} ++static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b)>0; else return strcmpW(a,b)>0;} ++static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b)<=0; else return strcmpW(a,b)<=0;} ++static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strcmpiW(a,b)>=0; else return strcmpW(a,b)>=0;} ++static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless) ++/* ERROR NOT WORKING REWRITE */ ++{ if (casless) return strstrW(a,b)!=NULL; else return strstrW(a,b)!=NULL;} ++static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless) ++{ if (casless) return strncmpiW(a,b,strlenW(b))==0; ++ else return strncmpW(a,b,strlenW(b))==0;} ++static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless) ++{ ++ int i = strlenW(a); ++ int j = strlenW(b); ++ if (j>i) ++ return 0; ++ if (casless) return (!strcmpiW(&a[i-j-1],b)); ++ else return (!strcmpW(&a[i-j-1],b)); ++} ++ ++ ++static INT comp_eq_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;} ++static INT comp_ne_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;} ++static INT comp_lt_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)b; else return 0;} ++static INT comp_le_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;} ++static INT comp_ge_m1(LPWSTR a, INT b) ++{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;} ++ ++static INT comp_eq_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;} ++static INT comp_ne_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;} ++static INT comp_lt_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;} ++static INT comp_gt_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;} ++static INT comp_le_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;} ++static INT comp_ge_m2(INT a, LPWSTR b) ++{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;} ++ ++ ++ ++static int COND_IsIdent( WCHAR x ) ++{ ++ return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) ++ || ( x == '#' ) || (x == '.') ); ++} ++ ++static int COND_GetOne( struct cond_str *str, COND_input *cond ) ++{ ++ static const WCHAR szNot[] = {'N','O','T',0}; ++ static const WCHAR szAnd[] = {'A','N','D',0}; ++ static const WCHAR szOr[] = {'O','R',0}; ++ WCHAR ch; ++ int rc, len = 1; ++ ++ str->data = &cond->str[cond->n]; ++ ++ ch = str->data[0]; ++ switch( ch ) ++ { ++ case 0: return 0; ++ case '(': rc = COND_LPAR; break; ++ case ')': rc = COND_RPAR; break; ++ case '&': rc = COND_AMPER; break; ++ case '!': rc = COND_EXCLAM; break; ++ case '$': rc = COND_DOLLARS; break; ++ case '?': rc = COND_QUESTION; break; ++ case '%': rc = COND_PERCENT; break; ++ case ' ': rc = COND_SPACE; break; ++ case '=': rc = COND_EQ; break; ++ case '~': rc = COND_TILDA; break; ++ case '<': rc = COND_LT; break; ++ case '>': rc = COND_GT; break; ++ case '"': ++ { ++ const WCHAR *ch2 = str->data + 1; ++ ++ ++ while ( *ch2 && *ch2 != '"' ) ++ ++ch2; ++ if (*ch2 == '"') ++ { ++ len = ch2 - str->data + 1; ++ rc = COND_LITER; ++ break; ++ } ++ } ++ ERR("Unterminated string\n"); ++ rc = COND_ERROR; ++ break; ++ default: ++ if( COND_IsAlpha( ch ) ) ++ { ++ while( COND_IsIdent( str->data[len] ) ) ++ len++; ++ rc = COND_IDENT; ++ break; ++ } ++ ++ if( COND_IsNumber( ch ) ) ++ { ++ while( COND_IsNumber( str->data[len] ) ) ++ len++; ++ rc = COND_NUMBER; ++ break; ++ } ++ ++ ERR("Got unknown character %c(%x)\n",ch,ch); ++ rc = COND_ERROR; ++ break; ++ } ++ ++ /* keyword identifiers */ ++ if( rc == COND_IDENT ) ++ { ++ if( (len==3) && (strncmpiW(str->data,szNot,len)==0) ) ++ rc = COND_NOT; ++ else if( (len==3) && (strncmpiW(str->data,szAnd,len)==0) ) ++ rc = COND_AND; ++ else if( (len==2) && (strncmpiW(str->data,szOr,len)==0) ) ++ rc = COND_OR; ++ } ++ ++ cond->n += len; ++ str->len = len; ++ ++ return rc; ++} ++ ++static int COND_lex( void *COND_lval, COND_input *cond ) ++{ ++ int rc; ++ struct cond_str *str = COND_lval; ++ ++ do { ++ rc = COND_GetOne( str, cond ); ++ } while (rc == COND_SPACE); ++ ++ return rc; ++} ++ ++static LPWSTR COND_GetString( struct cond_str *str ) ++{ ++ LPWSTR ret; ++ ++ ret = msi_alloc( (str->len+1) * sizeof (WCHAR) ); ++ if( ret ) ++ { ++ memcpy( ret, str->data, str->len * sizeof(WCHAR)); ++ ret[str->len]=0; ++ } ++ TRACE("Got identifier %s\n",debugstr_w(ret)); ++ return ret; ++} ++ ++static LPWSTR COND_GetLiteral( struct cond_str *str ) ++{ ++ LPWSTR ret; ++ ++ ret = msi_alloc( (str->len-1) * sizeof (WCHAR) ); ++ if( ret ) ++ { ++ memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) ); ++ ret[str->len - 2]=0; ++ } ++ TRACE("Got literal %s\n",debugstr_w(ret)); ++ return ret; ++} ++ ++static int COND_error(const char *str) ++{ ++ return 0; ++} ++ ++MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition ) ++{ ++ COND_input cond; ++ MSICONDITION r; ++ ++ cond.package = package; ++ cond.str = szCondition; ++ cond.n = 0; ++ cond.result = -1; ++ ++ TRACE("Evaluating %s\n",debugstr_w(szCondition)); ++ ++ if ( szCondition == NULL || szCondition[0] == 0) ++ r = MSICONDITION_NONE; ++ else if ( !COND_parse( &cond ) ) ++ r = cond.result; ++ else ++ r = MSICONDITION_ERROR; ++ ++ TRACE("Evaluates to %i\n",r); ++ return r; ++} ++ ++MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition ) ++{ ++ MSIPACKAGE *package; ++ UINT ret; ++ ++ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); ++ if( !package) ++ return ERROR_INVALID_HANDLE; ++ ret = MSI_EvaluateConditionW( package, szCondition ); ++ msiobj_release( &package->hdr ); ++ return ret; ++} ++ ++MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition ) ++{ ++ LPWSTR szwCond = NULL; ++ MSICONDITION r; ++ ++ if( szCondition ) ++ { ++ UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 ); ++ szwCond = msi_alloc( len * sizeof (WCHAR) ); ++ MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len ); ++ } ++ ++ r = MsiEvaluateConditionW( hInstall, szwCond ); ++ ++ msi_free( szwCond ); ++ ++ return r; ++} ++ +Index: cond.tab.h +=================================================================== +--- cond.tab.h (revision 23782) ++++ cond.tab.h (working copy) +@@ -0,0 +1,99 @@ ++/* A Bison parser, made by GNU Bison 1.875c. */ ++ ++/* Skeleton parser for Yacc-like parsing with Bison, ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++ 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, 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., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ ++ ++/* Tokens. */ ++#ifndef YYTOKENTYPE ++# define YYTOKENTYPE ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ COND_SPACE = 258, ++ COND_EOF = 259, ++ COND_OR = 260, ++ COND_AND = 261, ++ COND_NOT = 262, ++ COND_LT = 263, ++ COND_GT = 264, ++ COND_EQ = 265, ++ COND_LPAR = 266, ++ COND_RPAR = 267, ++ COND_TILDA = 268, ++ COND_PERCENT = 269, ++ COND_DOLLARS = 270, ++ COND_QUESTION = 271, ++ COND_AMPER = 272, ++ COND_EXCLAM = 273, ++ COND_IDENT = 274, ++ COND_NUMBER = 275, ++ COND_LITER = 276, ++ COND_ERROR = 277 ++ }; ++#endif ++#define COND_SPACE 258 ++#define COND_EOF 259 ++#define COND_OR 260 ++#define COND_AND 261 ++#define COND_NOT 262 ++#define COND_LT 263 ++#define COND_GT 264 ++#define COND_EQ 265 ++#define COND_LPAR 266 ++#define COND_RPAR 267 ++#define COND_TILDA 268 ++#define COND_PERCENT 269 ++#define COND_DOLLARS 270 ++#define COND_QUESTION 271 ++#define COND_AMPER 272 ++#define COND_EXCLAM 273 ++#define COND_IDENT 274 ++#define COND_NUMBER 275 ++#define COND_LITER 276 ++#define COND_ERROR 277 ++ ++ ++ ++ ++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) ++#line 106 "./cond.y" ++typedef union YYSTYPE { ++ struct cond_str str; ++ LPWSTR string; ++ INT value; ++ comp_int fn_comp_int; ++ comp_str fn_comp_str; ++ comp_m1 fn_comp_m1; ++ comp_m2 fn_comp_m2; ++} YYSTYPE; ++/* Line 1275 of yacc.c. */ ++#line 91 "cond.tab.h" ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ ++# define YYSTYPE_IS_DECLARED 1 ++# define YYSTYPE_IS_TRIVIAL 1 ++#endif ++ ++ ++ ++ ++ +Index: helpers.c +=================================================================== +--- helpers.c (revision 23808) ++++ helpers.c (working copy) +@@ -25,6 +25,7 @@ + + #include + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winerror.h" +Index: install.c +=================================================================== +--- install.c (revision 23808) ++++ install.c (working copy) +@@ -22,6 +22,7 @@ + + #include + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winerror.h" +Index: msi.c +=================================================================== +--- msi.c (revision 23808) ++++ msi.c (working copy) +@@ -23,6 +23,7 @@ + #define COBJMACROS + #define NONAMELESSUNION + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winreg.h" +Index: msi.rbuild +=================================================================== +--- msi.rbuild (revision 23808) ++++ msi.rbuild (working copy) +@@ -29,6 +29,7 @@ + alter.c + appsearch.c + classes.c ++ cond.tab.c + create.c + custom.c + database.c +@@ -54,6 +55,7 @@ + regsvr.c + select.c + source.c ++ sql.tab.c + string.c + suminfo.c + table.c +Index: msi_Ja.rc +=================================================================== +--- msi_Ja.rc (revision 23782) ++++ msi_Ja.rc (working copy) +@@ -0,0 +1,13 @@ ++LANGUAGE LANG_JAPANESE, SUBLANG_NEUTRAL ++ ++STRINGTABLE DISCARDABLE ++{ ++ 5 "pX %s ‚Ş‚Ý‚Â‚©‚č‚Ü‚ą‚ń‚Ĺ‚µ‚˝" ++ 9 "fBXN %s ‚đ‘}“ü‚µ‚Ä‚­‚ľ‚ł‚˘" ++ 10 "–łŚř‚Čp‰[^‚Ĺ‚·" ++ 11 "%s ‚Ě‚ ‚étH‹_‚đ“ü—Í‚µ‚Ä‚­‚ľ‚ł‚˘" ++ 12 "‹@”\\‚ĚC“Xg[‹Śł‚Ş‚ ‚č‚Ü‚ą‚ń" ++ 13 "‹@”\\‚Ş‚ ‚élbgŹ[N h‰Cu‚Ş‚ ‚č‚Ü‚ą‚ń" ++ 14 "‹@”\\‚̏ꏊ:" ++ 15 "%s ‚Ě‚ ‚étH‹_‚đ‘I‘đ‚µ‚Ä‚­‚ľ‚ł‚˘" ++} +Index: msiquery.c +=================================================================== +--- msiquery.c (revision 23808) ++++ msiquery.c (working copy) +@@ -22,6 +22,7 @@ + + #define COBJMACROS + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winerror.h" +Index: registry.c +=================================================================== +--- registry.c (revision 23808) ++++ registry.c (working copy) +@@ -24,6 +24,7 @@ + #define COBJMACROS + #define NONAMELESSUNION + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winreg.h" +Index: source.c +=================================================================== +--- source.c (revision 23808) ++++ source.c (working copy) +@@ -23,6 +23,7 @@ + #define COBJMACROS + #define NONAMELESSUNION + ++#include "stdio.h" + #include "windef.h" + #include "winbase.h" + #include "winreg.h" +Index: sql.tab.c +=================================================================== +--- sql.tab.c (revision 23782) ++++ sql.tab.c (working copy) +@@ -0,0 +1,2484 @@ ++/* A Bison parser, made by GNU Bison 1.875c. */ ++ ++/* Skeleton parser for Yacc-like parsing with Bison, ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++ 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, 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., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ ++ ++/* Written by Richard Stallman by simplifying the original so called ++ ``semantic'' parser. */ ++ ++/* All symbols defined below should begin with yy or YY, to avoid ++ infringing on user name space. This should be done even for local ++ variables, as they might otherwise be expanded by user macros. ++ There are some unavoidable exceptions within include files to ++ define necessary library symbols; they are noted "INFRINGES ON ++ USER NAME SPACE" below. */ ++ ++/* Identify Bison output. */ ++#define YYBISON 1 ++ ++/* Skeleton name. */ ++#define YYSKELETON_NAME "yacc.c" ++ ++/* Pure parsers. */ ++#define YYPURE 1 ++ ++/* Using locations. */ ++#define YYLSP_NEEDED 0 ++ ++/* If NAME_PREFIX is specified substitute the variables and functions ++ names. */ ++#define yyparse SQL_parse ++#define yylex SQL_lex ++#define yyerror SQL_error ++#define yylval SQL_lval ++#define yychar SQL_char ++#define yydebug SQL_debug ++#define yynerrs SQL_nerrs ++ ++ ++/* Tokens. */ ++#ifndef YYTOKENTYPE ++# define YYTOKENTYPE ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ TK_ABORT = 258, ++ TK_AFTER = 259, ++ TK_AGG_FUNCTION = 260, ++ TK_ALL = 261, ++ TK_AND = 262, ++ TK_AS = 263, ++ TK_ASC = 264, ++ TK_BEFORE = 265, ++ TK_BEGIN = 266, ++ TK_BETWEEN = 267, ++ TK_BITAND = 268, ++ TK_BITNOT = 269, ++ TK_BITOR = 270, ++ TK_BY = 271, ++ TK_CASCADE = 272, ++ TK_CASE = 273, ++ TK_CHAR = 274, ++ TK_CHECK = 275, ++ TK_CLUSTER = 276, ++ TK_COLLATE = 277, ++ TK_COLUMN = 278, ++ TK_COMMA = 279, ++ TK_COMMENT = 280, ++ TK_COMMIT = 281, ++ TK_CONCAT = 282, ++ TK_CONFLICT = 283, ++ TK_CONSTRAINT = 284, ++ TK_COPY = 285, ++ TK_CREATE = 286, ++ TK_DEFAULT = 287, ++ TK_DEFERRABLE = 288, ++ TK_DEFERRED = 289, ++ TK_DELETE = 290, ++ TK_DELIMITERS = 291, ++ TK_DESC = 292, ++ TK_DISTINCT = 293, ++ TK_DOT = 294, ++ TK_DROP = 295, ++ TK_EACH = 296, ++ TK_ELSE = 297, ++ TK_END = 298, ++ TK_END_OF_FILE = 299, ++ TK_EQ = 300, ++ TK_EXCEPT = 301, ++ TK_EXPLAIN = 302, ++ TK_FAIL = 303, ++ TK_FLOAT = 304, ++ TK_FOR = 305, ++ TK_FOREIGN = 306, ++ TK_FROM = 307, ++ TK_FUNCTION = 308, ++ TK_GE = 309, ++ TK_GLOB = 310, ++ TK_GROUP = 311, ++ TK_GT = 312, ++ TK_HAVING = 313, ++ TK_HOLD = 314, ++ TK_IGNORE = 315, ++ TK_ILLEGAL = 316, ++ TK_IMMEDIATE = 317, ++ TK_IN = 318, ++ TK_INDEX = 319, ++ TK_INITIALLY = 320, ++ TK_ID = 321, ++ TK_INSERT = 322, ++ TK_INSTEAD = 323, ++ TK_INT = 324, ++ TK_INTEGER = 325, ++ TK_INTERSECT = 326, ++ TK_INTO = 327, ++ TK_IS = 328, ++ TK_ISNULL = 329, ++ TK_JOIN = 330, ++ TK_JOIN_KW = 331, ++ TK_KEY = 332, ++ TK_LE = 333, ++ TK_LIKE = 334, ++ TK_LIMIT = 335, ++ TK_LONG = 336, ++ TK_LONGCHAR = 337, ++ TK_LP = 338, ++ TK_LSHIFT = 339, ++ TK_LT = 340, ++ TK_LOCALIZABLE = 341, ++ TK_MATCH = 342, ++ TK_MINUS = 343, ++ TK_NE = 344, ++ TK_NOT = 345, ++ TK_NOTNULL = 346, ++ TK_NULL = 347, ++ TK_OBJECT = 348, ++ TK_OF = 349, ++ TK_OFFSET = 350, ++ TK_ON = 351, ++ TK_OR = 352, ++ TK_ORACLE_OUTER_JOIN = 353, ++ TK_ORDER = 354, ++ TK_PLUS = 355, ++ TK_PRAGMA = 356, ++ TK_PRIMARY = 357, ++ TK_RAISE = 358, ++ TK_REFERENCES = 359, ++ TK_REM = 360, ++ TK_REPLACE = 361, ++ TK_RESTRICT = 362, ++ TK_ROLLBACK = 363, ++ TK_ROW = 364, ++ TK_RP = 365, ++ TK_RSHIFT = 366, ++ TK_SELECT = 367, ++ TK_SEMI = 368, ++ TK_SET = 369, ++ TK_SHORT = 370, ++ TK_SLASH = 371, ++ TK_SPACE = 372, ++ TK_STAR = 373, ++ TK_STATEMENT = 374, ++ TK_STRING = 375, ++ TK_TABLE = 376, ++ TK_TEMP = 377, ++ TK_THEN = 378, ++ TK_TRANSACTION = 379, ++ TK_TRIGGER = 380, ++ TK_UMINUS = 381, ++ TK_UNCLOSED_STRING = 382, ++ TK_UNION = 383, ++ TK_UNIQUE = 384, ++ TK_UPDATE = 385, ++ TK_UPLUS = 386, ++ TK_USING = 387, ++ TK_VACUUM = 388, ++ TK_VALUES = 389, ++ TK_VIEW = 390, ++ TK_WHEN = 391, ++ TK_WHERE = 392, ++ TK_WILDCARD = 393, ++ COLUMN = 395, ++ FUNCTION = 396, ++ COMMENT = 397, ++ UNCLOSED_STRING = 398, ++ SPACE = 399, ++ ILLEGAL = 400, ++ END_OF_FILE = 401 ++ }; ++#endif ++#define TK_ABORT 258 ++#define TK_AFTER 259 ++#define TK_AGG_FUNCTION 260 ++#define TK_ALL 261 ++#define TK_AND 262 ++#define TK_AS 263 ++#define TK_ASC 264 ++#define TK_BEFORE 265 ++#define TK_BEGIN 266 ++#define TK_BETWEEN 267 ++#define TK_BITAND 268 ++#define TK_BITNOT 269 ++#define TK_BITOR 270 ++#define TK_BY 271 ++#define TK_CASCADE 272 ++#define TK_CASE 273 ++#define TK_CHAR 274 ++#define TK_CHECK 275 ++#define TK_CLUSTER 276 ++#define TK_COLLATE 277 ++#define TK_COLUMN 278 ++#define TK_COMMA 279 ++#define TK_COMMENT 280 ++#define TK_COMMIT 281 ++#define TK_CONCAT 282 ++#define TK_CONFLICT 283 ++#define TK_CONSTRAINT 284 ++#define TK_COPY 285 ++#define TK_CREATE 286 ++#define TK_DEFAULT 287 ++#define TK_DEFERRABLE 288 ++#define TK_DEFERRED 289 ++#define TK_DELETE 290 ++#define TK_DELIMITERS 291 ++#define TK_DESC 292 ++#define TK_DISTINCT 293 ++#define TK_DOT 294 ++#define TK_DROP 295 ++#define TK_EACH 296 ++#define TK_ELSE 297 ++#define TK_END 298 ++#define TK_END_OF_FILE 299 ++#define TK_EQ 300 ++#define TK_EXCEPT 301 ++#define TK_EXPLAIN 302 ++#define TK_FAIL 303 ++#define TK_FLOAT 304 ++#define TK_FOR 305 ++#define TK_FOREIGN 306 ++#define TK_FROM 307 ++#define TK_FUNCTION 308 ++#define TK_GE 309 ++#define TK_GLOB 310 ++#define TK_GROUP 311 ++#define TK_GT 312 ++#define TK_HAVING 313 ++#define TK_HOLD 314 ++#define TK_IGNORE 315 ++#define TK_ILLEGAL 316 ++#define TK_IMMEDIATE 317 ++#define TK_IN 318 ++#define TK_INDEX 319 ++#define TK_INITIALLY 320 ++#define TK_ID 321 ++#define TK_INSERT 322 ++#define TK_INSTEAD 323 ++#define TK_INT 324 ++#define TK_INTEGER 325 ++#define TK_INTERSECT 326 ++#define TK_INTO 327 ++#define TK_IS 328 ++#define TK_ISNULL 329 ++#define TK_JOIN 330 ++#define TK_JOIN_KW 331 ++#define TK_KEY 332 ++#define TK_LE 333 ++#define TK_LIKE 334 ++#define TK_LIMIT 335 ++#define TK_LONG 336 ++#define TK_LONGCHAR 337 ++#define TK_LP 338 ++#define TK_LSHIFT 339 ++#define TK_LT 340 ++#define TK_LOCALIZABLE 341 ++#define TK_MATCH 342 ++#define TK_MINUS 343 ++#define TK_NE 344 ++#define TK_NOT 345 ++#define TK_NOTNULL 346 ++#define TK_NULL 347 ++#define TK_OBJECT 348 ++#define TK_OF 349 ++#define TK_OFFSET 350 ++#define TK_ON 351 ++#define TK_OR 352 ++#define TK_ORACLE_OUTER_JOIN 353 ++#define TK_ORDER 354 ++#define TK_PLUS 355 ++#define TK_PRAGMA 356 ++#define TK_PRIMARY 357 ++#define TK_RAISE 358 ++#define TK_REFERENCES 359 ++#define TK_REM 360 ++#define TK_REPLACE 361 ++#define TK_RESTRICT 362 ++#define TK_ROLLBACK 363 ++#define TK_ROW 364 ++#define TK_RP 365 ++#define TK_RSHIFT 366 ++#define TK_SELECT 367 ++#define TK_SEMI 368 ++#define TK_SET 369 ++#define TK_SHORT 370 ++#define TK_SLASH 371 ++#define TK_SPACE 372 ++#define TK_STAR 373 ++#define TK_STATEMENT 374 ++#define TK_STRING 375 ++#define TK_TABLE 376 ++#define TK_TEMP 377 ++#define TK_THEN 378 ++#define TK_TRANSACTION 379 ++#define TK_TRIGGER 380 ++#define TK_UMINUS 381 ++#define TK_UNCLOSED_STRING 382 ++#define TK_UNION 383 ++#define TK_UNIQUE 384 ++#define TK_UPDATE 385 ++#define TK_UPLUS 386 ++#define TK_USING 387 ++#define TK_VACUUM 388 ++#define TK_VALUES 389 ++#define TK_VIEW 390 ++#define TK_WHEN 391 ++#define TK_WHERE 392 ++#define TK_WILDCARD 393 ++#define COLUMN 395 ++#define FUNCTION 396 ++#define COMMENT 397 ++#define UNCLOSED_STRING 398 ++#define SPACE 399 ++#define ILLEGAL 400 ++#define END_OF_FILE 401 ++ ++ ++ ++ ++/* Copy the first part of user declarations. */ ++#line 1 "./sql.y" ++ ++ ++/* ++ * Implementation of the Microsoft Installer (msi.dll) ++ * ++ * Copyright 2002-2004 Mike McCormack for CodeWeavers ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "query.h" ++#include "wine/list.h" ++#include "wine/debug.h" ++ ++#define YYLEX_PARAM info ++#define YYPARSE_PARAM info ++ ++extern int SQL_error(const char *str); ++ ++WINE_DEFAULT_DEBUG_CHANNEL(msi); ++ ++typedef struct tag_SQL_input ++{ ++ MSIDATABASE *db; ++ LPCWSTR command; ++ DWORD n, len; ++ MSIVIEW **view; /* view structure for the resulting query */ ++ struct list *mem; ++} SQL_input; ++ ++static LPWSTR SQL_getstring( void *info, struct sql_str *str ); ++static INT SQL_getint( void *info ); ++static int SQL_lex( void *SQL_lval, SQL_input *info ); ++ ++static void *parser_alloc( void *info, unsigned int sz ); ++static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ); ++ ++static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys); ++ ++static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ); ++static struct expr * EXPR_column( void *info, column_info *column ); ++static struct expr * EXPR_ival( void *info, int val ); ++static struct expr * EXPR_sval( void *info, struct sql_str * ); ++static struct expr * EXPR_wildcard( void *info ); ++ ++ ++ ++/* Enabling traces. */ ++#ifndef YYDEBUG ++# define YYDEBUG 0 ++#endif ++ ++/* Enabling verbose error messages. */ ++#ifdef YYERROR_VERBOSE ++# undef YYERROR_VERBOSE ++# define YYERROR_VERBOSE 1 ++#else ++# define YYERROR_VERBOSE 0 ++#endif ++ ++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) ++#line 72 "./sql.y" ++typedef union YYSTYPE { ++ struct sql_str str; ++ LPWSTR string; ++ column_info *column_list; ++ MSIVIEW *query; ++ struct expr *expr; ++ USHORT column_type; ++ int integer; ++} YYSTYPE; ++/* Line 191 of yacc.c. */ ++#line 453 "sql.tab.c" ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ ++# define YYSTYPE_IS_DECLARED 1 ++# define YYSTYPE_IS_TRIVIAL 1 ++#endif ++ ++ ++ ++/* Copy the second part of user declarations. */ ++ ++ ++/* Line 214 of yacc.c. */ ++#line 465 "sql.tab.c" ++ ++#if ! defined (yyoverflow) || YYERROR_VERBOSE ++ ++# ifndef YYFREE ++# define YYFREE free ++# endif ++# ifndef YYMALLOC ++# define YYMALLOC malloc ++# endif ++ ++/* The parser invokes alloca or malloc; define the necessary symbols. */ ++ ++# ifdef YYSTACK_USE_ALLOCA ++# if YYSTACK_USE_ALLOCA ++# define YYSTACK_ALLOC alloca ++# endif ++# else ++# if defined (alloca) || defined (_ALLOCA_H) ++# define YYSTACK_ALLOC alloca ++# else ++# ifdef __GNUC__ ++# define YYSTACK_ALLOC __builtin_alloca ++# endif ++# endif ++# endif ++ ++# ifdef YYSTACK_ALLOC ++ /* Pacify GCC's `empty if-body' warning. */ ++# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) ++# else ++# if defined (__STDC__) || defined (__cplusplus) ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYSIZE_T size_t ++# endif ++# define YYSTACK_ALLOC YYMALLOC ++# define YYSTACK_FREE YYFREE ++# endif ++#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ ++ ++ ++#if (! defined (yyoverflow) \ ++ && (! defined (__cplusplus) \ ++ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) ++ ++/* A type that is properly aligned for any stack member. */ ++union yyalloc ++{ ++ short yyss; ++ YYSTYPE yyvs; ++ }; ++ ++/* The size of the maximum gap between one aligned stack and the next. */ ++# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) ++ ++/* The size of an array large to enough to hold all stacks, each with ++ N elements. */ ++# define YYSTACK_BYTES(N) \ ++ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ ++ + YYSTACK_GAP_MAXIMUM) ++ ++/* Copy COUNT objects from FROM to TO. The source and destination do ++ not overlap. */ ++# ifndef YYCOPY ++# if defined (__GNUC__) && 1 < __GNUC__ ++# define YYCOPY(To, From, Count) \ ++ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) ++# else ++# define YYCOPY(To, From, Count) \ ++ do \ ++ { \ ++ register YYSIZE_T yyi; \ ++ for (yyi = 0; yyi < (Count); yyi++) \ ++ (To)[yyi] = (From)[yyi]; \ ++ } \ ++ while (0) ++# endif ++# endif ++ ++/* Relocate STACK from its old location to the new one. The ++ local variables YYSIZE and YYSTACKSIZE give the old and new number of ++ elements in the stack, and YYPTR gives the new location of the ++ stack. Advance YYPTR to a properly aligned location for the next ++ stack. */ ++# define YYSTACK_RELOCATE(Stack) \ ++ do \ ++ { \ ++ YYSIZE_T yynewbytes; \ ++ YYCOPY (&yyptr->Stack, Stack, yysize); \ ++ Stack = &yyptr->Stack; \ ++ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ ++ yyptr += yynewbytes / sizeof (*yyptr); \ ++ } \ ++ while (0) ++ ++#endif ++ ++#if defined (__STDC__) || defined (__cplusplus) ++ typedef signed char yysigned_char; ++#else ++ typedef short yysigned_char; ++#endif ++ ++/* YYFINAL -- State number of the termination state. */ ++#define YYFINAL 29 ++/* YYLAST -- Last index in YYTABLE. */ ++#define YYLAST 124 ++ ++/* YYNTOKENS -- Number of terminals. */ ++#define YYNTOKENS 147 ++/* YYNNTS -- Number of nonterminals. */ ++#define YYNNTS 31 ++/* YYNRULES -- Number of rules. */ ++#define YYNRULES 69 ++/* YYNRULES -- Number of states. */ ++#define YYNSTATES 127 ++ ++/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ ++#define YYUNDEFTOK 2 ++#define YYMAXUTOK 401 ++ ++#define YYTRANSLATE(YYX) \ ++ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) ++ ++/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ ++static const unsigned char yytranslate[] = ++{ ++ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, ++ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ++ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, ++ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, ++ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, ++ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, ++ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, ++ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, ++ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, ++ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, ++ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, ++ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, ++ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, ++ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, ++ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, ++ 145, 146 ++}; ++ ++#if YYDEBUG ++/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in ++ YYRHS. */ ++static const unsigned char yyprhs[] = ++{ ++ 0, 0, 3, 5, 7, 9, 11, 13, 15, 26, ++ 38, 45, 53, 60, 63, 68, 72, 74, 77, 79, ++ 82, 84, 88, 90, 95, 97, 99, 101, 103, 105, ++ 107, 112, 114, 117, 121, 124, 126, 130, 132, 134, ++ 138, 141, 145, 149, 153, 157, 161, 165, 169, 173, ++ 177, 181, 185, 190, 192, 194, 196, 200, 202, 206, ++ 210, 212, 215, 217, 219, 221, 225, 227, 229, 231 ++}; ++ ++/* YYRHS -- A `-1'-separated list of the rules' RHS. */ ++static const short yyrhs[] = ++{ ++ 148, 0, -1, 149, -1, 161, -1, 151, -1, 150, ++ -1, 152, -1, 153, -1, 67, 72, 175, 83, 164, ++ 110, 134, 83, 169, 110, -1, 67, 72, 175, 83, ++ 164, 110, 134, 83, 169, 110, 122, -1, 31, 121, ++ 175, 83, 154, 110, -1, 31, 121, 175, 83, 154, ++ 110, 59, -1, 130, 175, 114, 170, 137, 167, -1, ++ 35, 165, -1, 155, 102, 77, 164, -1, 155, 24, ++ 156, -1, 156, -1, 174, 157, -1, 158, -1, 158, ++ 86, -1, 159, -1, 159, 90, 92, -1, 19, -1, ++ 19, 83, 160, 110, -1, 82, -1, 115, -1, 69, ++ -1, 81, -1, 93, -1, 177, -1, 162, 99, 16, ++ 164, -1, 162, -1, 112, 163, -1, 112, 38, 163, ++ -1, 164, 165, -1, 174, -1, 174, 24, 164, -1, ++ 118, -1, 166, -1, 166, 137, 167, -1, 52, 175, ++ -1, 83, 167, 110, -1, 173, 45, 173, -1, 167, ++ 7, 167, -1, 167, 97, 167, -1, 173, 45, 168, ++ -1, 173, 57, 168, -1, 173, 85, 168, -1, 173, ++ 78, 168, -1, 173, 54, 168, -1, 173, 89, 168, ++ -1, 173, 73, 92, -1, 173, 73, 90, 92, -1, ++ 173, -1, 172, -1, 172, -1, 172, 24, 169, -1, ++ 171, -1, 171, 24, 170, -1, 174, 45, 172, -1, ++ 177, -1, 88, 177, -1, 120, -1, 138, -1, 174, ++ -1, 175, 39, 176, -1, 176, -1, 176, -1, 66, ++ -1, 70, -1 ++}; ++ ++/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ ++static const unsigned short yyrline[] = ++{ ++ 0, 138, 138, 146, 147, 148, 149, 150, 154, 165, ++ 178, 190, 205, 218, 231, 241, 251, 258, 266, 270, ++ 277, 281, 288, 292, 296, 300, 304, 308, 312, 319, ++ 328, 340, 344, 348, 364, 385, 386, 390, 397, 398, ++ 414, 427, 433, 439, 445, 451, 457, 463, 469, 475, ++ 481, 487, 493, 502, 503, 507, 514, 525, 526, 534, ++ 542, 548, 554, 560, 569, 578, 584, 593, 600, 609 ++}; ++#endif ++ ++#if YYDEBUG || YYERROR_VERBOSE ++/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. ++ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ ++static const char *const yytname[] = ++{ ++ "$end", "error", "$undefined", "TK_ABORT", "TK_AFTER", ++ "TK_AGG_FUNCTION", "TK_ALL", "TK_AND", "TK_AS", "TK_ASC", "TK_BEFORE", ++ "TK_BEGIN", "TK_BETWEEN", "TK_BITAND", "TK_BITNOT", "TK_BITOR", "TK_BY", ++ "TK_CASCADE", "TK_CASE", "TK_CHAR", "TK_CHECK", "TK_CLUSTER", ++ "TK_COLLATE", "TK_COLUMN", "TK_COMMA", "TK_COMMENT", "TK_COMMIT", ++ "TK_CONCAT", "TK_CONFLICT", "TK_CONSTRAINT", "TK_COPY", "TK_CREATE", ++ "TK_DEFAULT", "TK_DEFERRABLE", "TK_DEFERRED", "TK_DELETE", ++ "TK_DELIMITERS", "TK_DESC", "TK_DISTINCT", "TK_DOT", "TK_DROP", ++ "TK_EACH", "TK_ELSE", "TK_END", "TK_END_OF_FILE", "TK_EQ", "TK_EXCEPT", ++ "TK_EXPLAIN", "TK_FAIL", "TK_FLOAT", "TK_FOR", "TK_FOREIGN", "TK_FROM", ++ "TK_FUNCTION", "TK_GE", "TK_GLOB", "TK_GROUP", "TK_GT", "TK_HAVING", ++ "TK_HOLD", "TK_IGNORE", "TK_ILLEGAL", "TK_IMMEDIATE", "TK_IN", ++ "TK_INDEX", "TK_INITIALLY", "TK_ID", "TK_INSERT", "TK_INSTEAD", "TK_INT", ++ "TK_INTEGER", "TK_INTERSECT", "TK_INTO", "TK_IS", "TK_ISNULL", "TK_JOIN", ++ "TK_JOIN_KW", "TK_KEY", "TK_LE", "TK_LIKE", "TK_LIMIT", "TK_LONG", ++ "TK_LONGCHAR", "TK_LP", "TK_LSHIFT", "TK_LT", "TK_LOCALIZABLE", ++ "TK_MATCH", "TK_MINUS", "TK_NE", "TK_NOT", "TK_NOTNULL", "TK_NULL", ++ "TK_OBJECT", "TK_OF", "TK_OFFSET", "TK_ON", "TK_OR", ++ "TK_ORACLE_OUTER_JOIN", "TK_ORDER", "TK_PLUS", "TK_PRAGMA", "TK_PRIMARY", ++ "TK_RAISE", "TK_REFERENCES", "TK_REM", "TK_REPLACE", "TK_RESTRICT", ++ "TK_ROLLBACK", "TK_ROW", "TK_RP", "TK_RSHIFT", "TK_SELECT", "TK_SEMI", ++ "TK_SET", "TK_SHORT", "TK_SLASH", "TK_SPACE", "TK_STAR", "TK_STATEMENT", ++ "TK_STRING", "TK_TABLE", "TK_TEMP", "TK_THEN", "TK_TRANSACTION", ++ "TK_TRIGGER", "TK_UMINUS", "TK_UNCLOSED_STRING", "TK_UNION", "TK_UNIQUE", ++ "TK_UPDATE", "TK_UPLUS", "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW", ++ "TK_WHEN", "TK_WHERE", "TK_WILDCARD", "AGG_FUNCTION.", "COLUMN", ++ "FUNCTION", "COMMENT", "UNCLOSED_STRING", "SPACE", "ILLEGAL", ++ "END_OF_FILE", "$accept", "query", "onequery", "oneinsert", "onecreate", ++ "oneupdate", "onedelete", "table_def", "column_def", "column_and_type", ++ "column_type", "data_type_l", "data_type", "data_count", "oneselect", ++ "unorderedsel", "selectfrom", "selcollist", "from", "fromtable", "expr", ++ "val", "constlist", "update_assign_list", "column_assignment", ++ "const_val", "column_val", "column", "table", "id", "number", 0 ++}; ++#endif ++ ++# ifdef YYPRINT ++/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to ++ token YYLEX-NUM. */ ++static const unsigned short yytoknum[] = ++{ ++ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, ++ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, ++ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, ++ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, ++ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, ++ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, ++ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, ++ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, ++ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, ++ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, ++ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, ++ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, ++ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, ++ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, ++ 395, 396, 397, 398, 399, 400, 401 ++}; ++# endif ++ ++/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ ++static const unsigned char yyr1[] = ++{ ++ 0, 147, 148, 149, 149, 149, 149, 149, 150, 150, ++ 151, 151, 152, 153, 154, 155, 155, 156, 157, 157, ++ 158, 158, 159, 159, 159, 159, 159, 159, 159, 160, ++ 161, 161, 162, 162, 163, 164, 164, 164, 165, 165, ++ 166, 167, 167, 167, 167, 167, 167, 167, 167, 167, ++ 167, 167, 167, 168, 168, 169, 169, 170, 170, 171, ++ 172, 172, 172, 172, 173, 174, 174, 175, 176, 177 ++}; ++ ++/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ ++static const unsigned char yyr2[] = ++{ ++ 0, 2, 1, 1, 1, 1, 1, 1, 10, 11, ++ 6, 7, 6, 2, 4, 3, 1, 2, 1, 2, ++ 1, 3, 1, 4, 1, 1, 1, 1, 1, 1, ++ 4, 1, 2, 3, 2, 1, 3, 1, 1, 3, ++ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, ++ 3, 3, 4, 1, 1, 1, 3, 1, 3, 3, ++ 1, 2, 1, 1, 1, 3, 1, 1, 1, 1 ++}; ++ ++/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state ++ STATE-NUM when YYTABLE doesn't specify something else to do. Zero ++ means the default is an error. */ ++static const unsigned char yydefact[] = ++{ ++ 0, 0, 0, 0, 0, 0, 0, 2, 5, 4, ++ 6, 7, 3, 31, 0, 0, 13, 38, 0, 0, ++ 68, 37, 32, 0, 35, 0, 66, 0, 67, 1, ++ 0, 0, 40, 0, 0, 33, 34, 0, 0, 0, ++ 0, 0, 0, 39, 0, 64, 0, 36, 65, 0, ++ 57, 0, 30, 0, 0, 16, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 10, 0, 0, 22, 26, 27, 24, 28, 25, ++ 17, 18, 20, 41, 43, 44, 69, 0, 62, 63, ++ 45, 54, 42, 60, 49, 53, 46, 0, 51, 48, ++ 47, 50, 0, 12, 58, 59, 11, 15, 0, 0, ++ 19, 0, 61, 52, 0, 14, 0, 29, 21, 0, ++ 23, 0, 55, 8, 0, 9, 56 ++}; ++ ++/* YYDEFGOTO[NTERM-NUM]. */ ++static const yysigned_char yydefgoto[] = ++{ ++ -1, 6, 7, 8, 9, 10, 11, 53, 54, 55, ++ 80, 81, 82, 116, 12, 13, 22, 23, 16, 17, ++ 43, 90, 121, 49, 50, 91, 44, 45, 25, 26, ++ 93 ++}; ++ ++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ ++#define YYPACT_NINF -111 ++static const yysigned_char yypact[] = ++{ ++ -28, -110, -38, -46, -32, -42, 29, -111, -111, -111, ++ -111, -111, -111, -67, -42, -42, -111, -99, -42, -48, ++ -111, -111, -111, -38, 17, 7, 11, -62, -111, -111, ++ 37, -22, -111, -43, -16, -111, -111, -48, -42, -42, ++ -48, -42, -43, -3, -29, -111, -48, -111, -111, -68, ++ 48, 28, -111, -36, -19, -111, -18, -5, -43, -43, ++ -58, -58, -58, -70, -58, -58, -58, -34, -43, -42, ++ -61, 20, -42, 5, 2, -111, -111, -111, -111, -111, ++ -111, 1, -2, -111, -3, -3, -111, 19, -111, -111, ++ -111, -111, -111, -111, -111, -111, -111, -1, -111, -111, ++ -111, -111, -41, -3, -111, -111, -111, -111, -48, 19, ++ -111, 3, -111, -111, 13, -111, -12, -111, -111, -61, ++ -111, -9, 91, -13, -61, -111, -111 ++}; ++ ++/* YYPGOTO[NTERM-NUM]. */ ++static const yysigned_char yypgoto[] = ++{ ++ -111, -111, -111, -111, -111, -111, -111, -111, -111, 47, ++ -111, -111, -111, -111, -111, -111, 101, -27, 98, -111, ++ -11, 52, 0, 53, -111, -53, 46, -4, 85, 40, ++ -66 ++}; ++ ++/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule which ++ number is the opposite. If zero, do what YYDEFACT says. ++ If YYTABLE_NINF, syntax error. */ ++#define YYTABLE_NINF -68 ++static const yysigned_char yytable[] = ++{ ++ 24, 74, 58, 1, 58, 72, 19, 2, 20, 86, ++ 47, 14, 86, 52, 15, 24, 60, 105, 20, 67, ++ 97, 112, 98, 20, 20, 61, 18, 87, 62, 29, ++ 87, 57, 30, 24, 20, 51, 24, 56, 33, 3, ++ 42, 37, 24, 117, 63, 28, 38, 84, 85, 64, ++ -67, 75, 39, 40, 28, 28, 65, 103, 28, 88, ++ 66, 41, 88, 76, 77, 51, 122, 46, 56, 68, ++ 21, 122, 69, 70, 71, 78, 102, 89, 48, 106, ++ 89, 115, 108, 73, 4, 109, 21, 110, 111, 86, ++ 27, 113, 59, 114, 59, 118, 119, 79, 120, 31, ++ 32, 123, 5, 34, 24, 83, 92, 95, 95, 125, ++ 95, 95, 95, 94, 96, 124, 99, 100, 101, 107, ++ 35, 36, 104, 0, 126 ++}; ++ ++static const short yycheck[] = ++{ ++ 4, 19, 7, 31, 7, 24, 38, 35, 66, 70, ++ 37, 121, 70, 40, 52, 19, 45, 70, 66, 46, ++ 90, 87, 92, 66, 66, 54, 72, 88, 57, 0, ++ 88, 42, 99, 37, 66, 39, 40, 41, 137, 67, ++ 83, 24, 46, 109, 73, 5, 39, 58, 59, 78, ++ 39, 69, 114, 16, 14, 15, 85, 68, 18, 120, ++ 89, 83, 120, 81, 82, 69, 119, 83, 72, 137, ++ 118, 124, 24, 45, 110, 93, 110, 138, 38, 59, ++ 138, 108, 77, 102, 112, 83, 118, 86, 90, 70, ++ 5, 92, 97, 134, 97, 92, 83, 115, 110, 14, ++ 15, 110, 130, 18, 108, 110, 60, 61, 62, 122, ++ 64, 65, 66, 61, 62, 24, 64, 65, 66, 72, ++ 19, 23, 69, -1, 124 ++}; ++ ++/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing ++ symbol of state STATE-NUM. */ ++static const unsigned char yystos[] = ++{ ++ 0, 31, 35, 67, 112, 130, 148, 149, 150, 151, ++ 152, 153, 161, 162, 121, 52, 165, 166, 72, 38, ++ 66, 118, 163, 164, 174, 175, 176, 175, 176, 0, ++ 99, 175, 175, 137, 175, 163, 165, 24, 39, 114, ++ 16, 83, 83, 167, 173, 174, 83, 164, 176, 170, ++ 171, 174, 164, 154, 155, 156, 174, 167, 7, 97, ++ 45, 54, 57, 73, 78, 85, 89, 164, 137, 24, ++ 45, 110, 24, 102, 19, 69, 81, 82, 93, 115, ++ 157, 158, 159, 110, 167, 167, 70, 88, 120, 138, ++ 168, 172, 173, 177, 168, 173, 168, 90, 92, 168, ++ 168, 168, 110, 167, 170, 172, 59, 156, 77, 83, ++ 86, 90, 177, 92, 134, 164, 160, 177, 92, 83, ++ 110, 169, 172, 110, 24, 122, 169 ++}; ++ ++#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) ++# define YYSIZE_T __SIZE_TYPE__ ++#endif ++#if ! defined (YYSIZE_T) && defined (size_t) ++# define YYSIZE_T size_t ++#endif ++#if ! defined (YYSIZE_T) ++# if defined (__STDC__) || defined (__cplusplus) ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYSIZE_T size_t ++# endif ++#endif ++#if ! defined (YYSIZE_T) ++# define YYSIZE_T unsigned int ++#endif ++ ++#define yyerrok (yyerrstatus = 0) ++#define yyclearin (yychar = YYEMPTY) ++#define YYEMPTY (-2) ++#define YYEOF 0 ++ ++#define YYACCEPT goto yyacceptlab ++#define YYABORT goto yyabortlab ++#define YYERROR goto yyerrorlab ++ ++ ++/* Like YYERROR except do call yyerror. This remains here temporarily ++ to ease the transition to the new meaning of YYERROR, for GCC. ++ Once GCC version 2 has supplanted version 1, this can go. */ ++ ++#define YYFAIL goto yyerrlab ++ ++#define YYRECOVERING() (!!yyerrstatus) ++ ++#define YYBACKUP(Token, Value) \ ++do \ ++ if (yychar == YYEMPTY && yylen == 1) \ ++ { \ ++ yychar = (Token); \ ++ yylval = (Value); \ ++ yytoken = YYTRANSLATE (yychar); \ ++ YYPOPSTACK; \ ++ goto yybackup; \ ++ } \ ++ else \ ++ { \ ++ yyerror ("syntax error: cannot back up");\ ++ YYERROR; \ ++ } \ ++while (0) ++ ++#define YYTERROR 1 ++#define YYERRCODE 256 ++ ++/* YYLLOC_DEFAULT -- Compute the default location (before the actions ++ are run). */ ++ ++#ifndef YYLLOC_DEFAULT ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ ((Current).first_line = (Rhs)[1].first_line, \ ++ (Current).first_column = (Rhs)[1].first_column, \ ++ (Current).last_line = (Rhs)[N].last_line, \ ++ (Current).last_column = (Rhs)[N].last_column) ++#endif ++ ++/* YYLEX -- calling `yylex' with the right arguments. */ ++ ++#ifdef YYLEX_PARAM ++# define YYLEX yylex (&yylval, YYLEX_PARAM) ++#else ++# define YYLEX yylex (&yylval) ++#endif ++ ++/* Enable debugging if requested. */ ++#if YYDEBUG ++ ++# ifndef YYFPRINTF ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYFPRINTF fprintf ++# endif ++ ++# define YYDPRINTF(Args) \ ++do { \ ++ if (yydebug) \ ++ YYFPRINTF Args; \ ++} while (0) ++ ++# define YYDSYMPRINT(Args) \ ++do { \ ++ if (yydebug) \ ++ yysymprint Args; \ ++} while (0) ++ ++# define YYDSYMPRINTF(Title, Token, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yysymprint (stderr, \ ++ Token, Value); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (0) ++ ++/*------------------------------------------------------------------. ++| yy_stack_print -- Print the state stack from its BOTTOM up to its | ++| TOP (included). | ++`------------------------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_stack_print (short *bottom, short *top) ++#else ++static void ++yy_stack_print (bottom, top) ++ short *bottom; ++ short *top; ++#endif ++{ ++ YYFPRINTF (stderr, "Stack now"); ++ for (/* Nothing. */; bottom <= top; ++bottom) ++ YYFPRINTF (stderr, " %d", *bottom); ++ YYFPRINTF (stderr, "\n"); ++} ++ ++# define YY_STACK_PRINT(Bottom, Top) \ ++do { \ ++ if (yydebug) \ ++ yy_stack_print ((Bottom), (Top)); \ ++} while (0) ++ ++ ++/*------------------------------------------------. ++| Report that the YYRULE is going to be reduced. | ++`------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_reduce_print (int yyrule) ++#else ++static void ++yy_reduce_print (yyrule) ++ int yyrule; ++#endif ++{ ++ int yyi; ++ unsigned int yylno = yyrline[yyrule]; ++ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", ++ yyrule - 1, yylno); ++ /* Print the symbols being reduced, and their result. */ ++ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) ++ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); ++ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); ++} ++ ++# define YY_REDUCE_PRINT(Rule) \ ++do { \ ++ if (yydebug) \ ++ yy_reduce_print (Rule); \ ++} while (0) ++ ++/* Nonzero means print parse trace. It is left uninitialized so that ++ multiple parsers can coexist. */ ++int yydebug; ++#else /* !YYDEBUG */ ++# define YYDPRINTF(Args) ++# define YYDSYMPRINT(Args) ++# define YYDSYMPRINTF(Title, Token, Value, Location) ++# define YY_STACK_PRINT(Bottom, Top) ++# define YY_REDUCE_PRINT(Rule) ++#endif /* !YYDEBUG */ ++ ++ ++/* YYINITDEPTH -- initial size of the parser's stacks. */ ++#ifndef YYINITDEPTH ++# define YYINITDEPTH 200 ++#endif ++ ++/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only ++ if the built-in stack extension method is used). ++ ++ Do not make this value too large; the results are undefined if ++ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) ++ evaluated with infinite-precision integer arithmetic. */ ++ ++#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 ++# undef YYMAXDEPTH ++#endif ++ ++#ifndef YYMAXDEPTH ++# define YYMAXDEPTH 10000 ++#endif ++ ++ ++ ++#if YYERROR_VERBOSE ++ ++# ifndef yystrlen ++# if defined (__GLIBC__) && defined (_STRING_H) ++# define yystrlen strlen ++# else ++/* Return the length of YYSTR. */ ++static YYSIZE_T ++# if defined (__STDC__) || defined (__cplusplus) ++yystrlen (const char *yystr) ++# else ++yystrlen (yystr) ++ const char *yystr; ++# endif ++{ ++ register const char *yys = yystr; ++ ++ while (*yys++ != '\0') ++ continue; ++ ++ return yys - yystr - 1; ++} ++# endif ++# endif ++ ++# ifndef yystpcpy ++# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) ++# define yystpcpy stpcpy ++# else ++/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in ++ YYDEST. */ ++static char * ++# if defined (__STDC__) || defined (__cplusplus) ++yystpcpy (char *yydest, const char *yysrc) ++# else ++yystpcpy (yydest, yysrc) ++ char *yydest; ++ const char *yysrc; ++# endif ++{ ++ register char *yyd = yydest; ++ register const char *yys = yysrc; ++ ++ while ((*yyd++ = *yys++) != '\0') ++ continue; ++ ++ return yyd - 1; ++} ++# endif ++# endif ++ ++#endif /* !YYERROR_VERBOSE */ ++ ++ ++ ++#if YYDEBUG ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yysymprint (yyoutput, yytype, yyvaluep) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ if (yytype < YYNTOKENS) ++ { ++ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); ++# ifdef YYPRINT ++ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++# endif ++ } ++ else ++ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); ++ ++ switch (yytype) ++ { ++ default: ++ break; ++ } ++ YYFPRINTF (yyoutput, ")"); ++} ++ ++#endif /* ! YYDEBUG */ ++/*-----------------------------------------------. ++| Release the memory associated to this symbol. | ++`-----------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yydestruct (int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yydestruct (yytype, yyvaluep) ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ switch (yytype) ++ { ++ ++ default: ++ break; ++ } ++} ++ ++ ++/* Prevent warnings from -Wmissing-prototypes. */ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM); ++# else ++int yyparse (); ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void); ++#else ++int yyparse (); ++#endif ++#endif /* ! YYPARSE_PARAM */ ++ ++ ++ ++ ++ ++ ++/*----------. ++| yyparse. | ++`----------*/ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM) ++# else ++int yyparse (YYPARSE_PARAM) ++ void *YYPARSE_PARAM; ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int ++yyparse (void) ++#else ++int ++yyparse () ++ ++#endif ++#endif ++{ ++ /* The lookahead symbol. */ ++int yychar; ++ ++/* The semantic value of the lookahead symbol. */ ++YYSTYPE yylval; ++ ++/* Number of syntax errors so far. */ ++int yynerrs; ++ ++ register int yystate; ++ register int yyn; ++ int yyresult; ++ /* Number of tokens to shift before error messages enabled. */ ++ int yyerrstatus; ++ /* Lookahead token as an internal (translated) token number. */ ++ int yytoken = 0; ++ ++ /* Three stacks and their tools: ++ `yyss': related to states, ++ `yyvs': related to semantic values, ++ `yyls': related to locations. ++ ++ Refer to the stacks thru separate pointers, to allow yyoverflow ++ to reallocate them elsewhere. */ ++ ++ /* The state stack. */ ++ short yyssa[YYINITDEPTH]; ++ short *yyss = yyssa; ++ register short *yyssp; ++ ++ /* The semantic value stack. */ ++ YYSTYPE yyvsa[YYINITDEPTH]; ++ YYSTYPE *yyvs = yyvsa; ++ register YYSTYPE *yyvsp; ++ ++ ++ ++#define YYPOPSTACK (yyvsp--, yyssp--) ++ ++ YYSIZE_T yystacksize = YYINITDEPTH; ++ ++ /* The variables used to return semantic value and location from the ++ action routines. */ ++ YYSTYPE yyval; ++ ++ ++ /* When reducing, the number of symbols on the RHS of the reduced ++ rule. */ ++ int yylen; ++ ++ YYDPRINTF ((stderr, "Starting parse\n")); ++ ++ yystate = 0; ++ yyerrstatus = 0; ++ yynerrs = 0; ++ yychar = YYEMPTY; /* Cause a token to be read. */ ++ ++ /* Initialize stack pointers. ++ Waste one element of value and location stack ++ so that they stay on the same level as the state stack. ++ The wasted elements are never initialized. */ ++ ++ yyssp = yyss; ++ yyvsp = yyvs; ++ ++ goto yysetstate; ++ ++/*------------------------------------------------------------. ++| yynewstate -- Push a new state, which is found in yystate. | ++`------------------------------------------------------------*/ ++ yynewstate: ++ /* In all cases, when you get here, the value and location stacks ++ have just been pushed. so pushing a state here evens the stacks. ++ */ ++ yyssp++; ++ ++ yysetstate: ++ *yyssp = yystate; ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ { ++ /* Get the current used size of the three stacks, in elements. */ ++ YYSIZE_T yysize = yyssp - yyss + 1; ++ ++#ifdef yyoverflow ++ { ++ /* Give user a chance to reallocate the stack. Use copies of ++ these so that the &'s don't force the real ones into ++ memory. */ ++ YYSTYPE *yyvs1 = yyvs; ++ short *yyss1 = yyss; ++ ++ ++ /* Each stack pointer address is followed by the size of the ++ data in use in that stack, in bytes. This used to be a ++ conditional around just the two extra args, but that might ++ be undefined if yyoverflow is a macro. */ ++ yyoverflow ("parser stack overflow", ++ &yyss1, yysize * sizeof (*yyssp), ++ &yyvs1, yysize * sizeof (*yyvsp), ++ ++ &yystacksize); ++ ++ yyss = yyss1; ++ yyvs = yyvs1; ++ } ++#else /* no yyoverflow */ ++# ifndef YYSTACK_RELOCATE ++ goto yyoverflowlab; ++# else ++ /* Extend the stack our own way. */ ++ if (YYMAXDEPTH <= yystacksize) ++ goto yyoverflowlab; ++ yystacksize *= 2; ++ if (YYMAXDEPTH < yystacksize) ++ yystacksize = YYMAXDEPTH; ++ ++ { ++ short *yyss1 = yyss; ++ union yyalloc *yyptr = ++ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ if (! yyptr) ++ goto yyoverflowlab; ++ YYSTACK_RELOCATE (yyss); ++ YYSTACK_RELOCATE (yyvs); ++ ++# undef YYSTACK_RELOCATE ++ if (yyss1 != yyssa) ++ YYSTACK_FREE (yyss1); ++ } ++# endif ++#endif /* no yyoverflow */ ++ ++ yyssp = yyss + yysize - 1; ++ yyvsp = yyvs + yysize - 1; ++ ++ ++ YYDPRINTF ((stderr, "Stack size increased to %lu\n", ++ (unsigned long int) yystacksize)); ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ YYABORT; ++ } ++ ++ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); ++ ++ goto yybackup; ++ ++/*-----------. ++| yybackup. | ++`-----------*/ ++yybackup: ++ ++/* Do appropriate processing given the current state. */ ++/* Read a lookahead token if we need one and don't already have one. */ ++/* yyresume: */ ++ ++ /* First try to decide what to do without reference to lookahead token. */ ++ ++ yyn = yypact[yystate]; ++ if (yyn == YYPACT_NINF) ++ goto yydefault; ++ ++ /* Not known => get a lookahead token if don't already have one. */ ++ ++ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ ++ if (yychar == YYEMPTY) ++ { ++ YYDPRINTF ((stderr, "Reading a token: ")); ++ yychar = YYLEX; ++ } ++ ++ if (yychar <= YYEOF) ++ { ++ yychar = yytoken = YYEOF; ++ YYDPRINTF ((stderr, "Now at end of input.\n")); ++ } ++ else ++ { ++ yytoken = YYTRANSLATE (yychar); ++ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); ++ } ++ ++ /* If the proper action on seeing token YYTOKEN is to reduce or to ++ detect an error, take that action. */ ++ yyn += yytoken; ++ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) ++ goto yydefault; ++ yyn = yytable[yyn]; ++ if (yyn <= 0) ++ { ++ if (yyn == 0 || yyn == YYTABLE_NINF) ++ goto yyerrlab; ++ yyn = -yyn; ++ goto yyreduce; ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ /* Shift the lookahead token. */ ++ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); ++ ++ /* Discard the token being shifted unless it is eof. */ ++ if (yychar != YYEOF) ++ yychar = YYEMPTY; ++ ++ *++yyvsp = yylval; ++ ++ ++ /* Count tokens shifted since error; after three, turn off error ++ status. */ ++ if (yyerrstatus) ++ yyerrstatus--; ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-----------------------------------------------------------. ++| yydefault -- do the default action for the current state. | ++`-----------------------------------------------------------*/ ++yydefault: ++ yyn = yydefact[yystate]; ++ if (yyn == 0) ++ goto yyerrlab; ++ goto yyreduce; ++ ++ ++/*-----------------------------. ++| yyreduce -- Do a reduction. | ++`-----------------------------*/ ++yyreduce: ++ /* yyn is the number of a rule to reduce with. */ ++ yylen = yyr2[yyn]; ++ ++ /* If YYLEN is nonzero, implement the default value of the action: ++ `$$ = $1'. ++ ++ Otherwise, the following line sets YYVAL to garbage. ++ This behavior is undocumented and Bison ++ users should not rely upon it. Assigning to YYVAL ++ unconditionally makes the parser a bit smaller, and it avoids a ++ GCC warning that YYVAL may be used uninitialized. */ ++ yyval = yyvsp[1-yylen]; ++ ++ ++ YY_REDUCE_PRINT (yyn); ++ switch (yyn) ++ { ++ case 2: ++#line 139 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ *sql->view = yyvsp[0].query; ++ ;} ++ break; ++ ++ case 8: ++#line 155 "./sql.y" ++ { ++ SQL_input *sql = (SQL_input*) info; ++ MSIVIEW *insert = NULL; ++ UINT r; ++ ++ r = INSERT_CreateView( sql->db, &insert, yyvsp[-7].string, yyvsp[-5].column_list, yyvsp[-1].column_list, FALSE ); ++ if( !insert ) ++ YYABORT; ++ yyval.query = insert; ++ ;} ++ break; ++ ++ case 9: ++#line 166 "./sql.y" ++ { ++ SQL_input *sql = (SQL_input*) info; ++ MSIVIEW *insert = NULL; ++ ++ INSERT_CreateView( sql->db, &insert, yyvsp[-8].string, yyvsp[-6].column_list, yyvsp[-2].column_list, TRUE ); ++ if( !insert ) ++ YYABORT; ++ yyval.query = insert; ++ ;} ++ break; ++ ++ case 10: ++#line 179 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ MSIVIEW *create = NULL; ++ ++ if( !yyvsp[-1].column_list ) ++ YYABORT; ++ CREATE_CreateView( sql->db, &create, yyvsp[-3].string, yyvsp[-1].column_list, FALSE ); ++ if( !create ) ++ YYABORT; ++ yyval.query = create; ++ ;} ++ break; ++ ++ case 11: ++#line 191 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ MSIVIEW *create = NULL; ++ ++ if( !yyvsp[-2].column_list ) ++ YYABORT; ++ CREATE_CreateView( sql->db, &create, yyvsp[-4].string, yyvsp[-2].column_list, TRUE ); ++ if( !create ) ++ YYABORT; ++ yyval.query = create; ++ ;} ++ break; ++ ++ case 12: ++#line 206 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ MSIVIEW *update = NULL; ++ ++ UPDATE_CreateView( sql->db, &update, yyvsp[-4].string, yyvsp[-2].column_list, yyvsp[0].expr ); ++ if( !update ) ++ YYABORT; ++ yyval.query = update; ++ ;} ++ break; ++ ++ case 13: ++#line 219 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ MSIVIEW *delete = NULL; ++ ++ DELETE_CreateView( sql->db, &delete, yyvsp[0].query ); ++ if( !delete ) ++ YYABORT; ++ yyval.query = delete; ++ ;} ++ break; ++ ++ case 14: ++#line 232 "./sql.y" ++ { ++ if( SQL_MarkPrimaryKeys( yyvsp[-3].column_list, yyvsp[0].column_list ) ) ++ yyval.column_list = yyvsp[-3].column_list; ++ else ++ yyval.column_list = NULL; ++ ;} ++ break; ++ ++ case 15: ++#line 242 "./sql.y" ++ { ++ column_info *ci; ++ ++ for( ci = yyvsp[-2].column_list; ci->next; ci = ci->next ) ++ ; ++ ++ ci->next = yyvsp[0].column_list; ++ yyval.column_list = yyvsp[-2].column_list; ++ ;} ++ break; ++ ++ case 16: ++#line 252 "./sql.y" ++ { ++ yyval.column_list = yyvsp[0].column_list; ++ ;} ++ break; ++ ++ case 17: ++#line 259 "./sql.y" ++ { ++ yyval.column_list = yyvsp[-1].column_list; ++ yyval.column_list->type = yyvsp[0].column_type | MSITYPE_VALID; ++ ;} ++ break; ++ ++ case 18: ++#line 267 "./sql.y" ++ { ++ yyval.column_type = yyvsp[0].column_type; ++ ;} ++ break; ++ ++ case 19: ++#line 271 "./sql.y" ++ { ++ yyval.column_type = yyvsp[-1].column_type | MSITYPE_LOCALIZABLE; ++ ;} ++ break; ++ ++ case 20: ++#line 278 "./sql.y" ++ { ++ yyval.column_type |= MSITYPE_NULLABLE; ++ ;} ++ break; ++ ++ case 21: ++#line 282 "./sql.y" ++ { ++ yyval.column_type = yyvsp[-2].column_type; ++ ;} ++ break; ++ ++ case 22: ++#line 289 "./sql.y" ++ { ++ yyval.column_type = MSITYPE_STRING | 1; ++ ;} ++ break; ++ ++ case 23: ++#line 293 "./sql.y" ++ { ++ yyval.column_type = MSITYPE_STRING | 0x400 | yyvsp[-1].column_type; ++ ;} ++ break; ++ ++ case 24: ++#line 297 "./sql.y" ++ { ++ yyval.column_type = 2; ++ ;} ++ break; ++ ++ case 25: ++#line 301 "./sql.y" ++ { ++ yyval.column_type = 2; ++ ;} ++ break; ++ ++ case 26: ++#line 305 "./sql.y" ++ { ++ yyval.column_type = 2; ++ ;} ++ break; ++ ++ case 27: ++#line 309 "./sql.y" ++ { ++ yyval.column_type = 4; ++ ;} ++ break; ++ ++ case 28: ++#line 313 "./sql.y" ++ { ++ yyval.column_type = MSITYPE_STRING | MSITYPE_VALID; ++ ;} ++ break; ++ ++ case 29: ++#line 320 "./sql.y" ++ { ++ if( ( yyvsp[0].integer > 255 ) || ( yyvsp[0].integer < 0 ) ) ++ YYABORT; ++ yyval.column_type = yyvsp[0].integer; ++ ;} ++ break; ++ ++ case 30: ++#line 329 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ ++ yyval.query = NULL; ++ if( yyvsp[0].column_list ) ++ ORDER_CreateView( sql->db, &yyval.query, yyvsp[-3].query, yyvsp[0].column_list ); ++ else ++ yyval.query = yyvsp[-3].query; ++ if( !yyval.query ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 32: ++#line 345 "./sql.y" ++ { ++ yyval.query = yyvsp[0].query; ++ ;} ++ break; ++ ++ case 33: ++#line 349 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ UINT r; ++ ++ yyval.query = NULL; ++ r = DISTINCT_CreateView( sql->db, &yyval.query, yyvsp[0].query ); ++ if (r != ERROR_SUCCESS) ++ { ++ yyvsp[0].query->ops->delete(yyvsp[0].query); ++ YYABORT; ++ } ++ ;} ++ break; ++ ++ case 34: ++#line 365 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ UINT r; ++ ++ yyval.query = NULL; ++ if( yyvsp[-1].column_list ) ++ { ++ r = SELECT_CreateView( sql->db, &yyval.query, yyvsp[0].query, yyvsp[-1].column_list ); ++ if (r != ERROR_SUCCESS) ++ { ++ yyvsp[0].query->ops->delete(yyvsp[0].query); ++ YYABORT; ++ } ++ } ++ else ++ yyval.query = yyvsp[0].query; ++ ;} ++ break; ++ ++ case 36: ++#line 387 "./sql.y" ++ { ++ yyvsp[-2].column_list->next = yyvsp[0].column_list; ++ ;} ++ break; ++ ++ case 37: ++#line 391 "./sql.y" ++ { ++ yyval.column_list = NULL; ++ ;} ++ break; ++ ++ case 39: ++#line 399 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ UINT r; ++ ++ yyval.query = NULL; ++ r = WHERE_CreateView( sql->db, &yyval.query, yyvsp[-2].query, yyvsp[0].expr ); ++ if( r != ERROR_SUCCESS ) ++ { ++ yyvsp[-2].query->ops->delete( yyvsp[-2].query ); ++ YYABORT; ++ } ++ ;} ++ break; ++ ++ case 40: ++#line 415 "./sql.y" ++ { ++ SQL_input* sql = (SQL_input*) info; ++ UINT r; ++ ++ yyval.query = NULL; ++ r = TABLE_CreateView( sql->db, yyvsp[0].string, &yyval.query ); ++ if( r != ERROR_SUCCESS || !yyval.query ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 41: ++#line 428 "./sql.y" ++ { ++ yyval.expr = yyvsp[-1].expr; ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 42: ++#line 434 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 43: ++#line 440 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_AND, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 44: ++#line 446 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_OR, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 45: ++#line 452 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 46: ++#line 458 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GT, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 47: ++#line 464 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LT, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 48: ++#line 470 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LE, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 49: ++#line 476 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GE, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 50: ++#line 482 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_NE, yyvsp[0].expr ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 51: ++#line 488 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_ISNULL, NULL ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 52: ++#line 494 "./sql.y" ++ { ++ yyval.expr = EXPR_complex( info, yyvsp[-3].expr, OP_NOTNULL, NULL ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 55: ++#line 508 "./sql.y" ++ { ++ yyval.column_list = parser_alloc_column( info, NULL, NULL ); ++ if( !yyval.column_list ) ++ YYABORT; ++ yyval.column_list->val = yyvsp[0].expr; ++ ;} ++ break; ++ ++ case 56: ++#line 515 "./sql.y" ++ { ++ yyval.column_list = parser_alloc_column( info, NULL, NULL ); ++ if( !yyval.column_list ) ++ YYABORT; ++ yyval.column_list->val = yyvsp[-2].expr; ++ yyval.column_list->next = yyvsp[0].column_list; ++ ;} ++ break; ++ ++ case 58: ++#line 527 "./sql.y" ++ { ++ yyval.column_list = yyvsp[-2].column_list; ++ yyval.column_list->next = yyvsp[0].column_list; ++ ;} ++ break; ++ ++ case 59: ++#line 535 "./sql.y" ++ { ++ yyval.column_list = yyvsp[-2].column_list; ++ yyval.column_list->val = yyvsp[0].expr; ++ ;} ++ break; ++ ++ case 60: ++#line 543 "./sql.y" ++ { ++ yyval.expr = EXPR_ival( info, yyvsp[0].integer ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 61: ++#line 549 "./sql.y" ++ { ++ yyval.expr = EXPR_ival( info, -yyvsp[0].integer ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 62: ++#line 555 "./sql.y" ++ { ++ yyval.expr = EXPR_sval( info, &yyvsp[0].str ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 63: ++#line 561 "./sql.y" ++ { ++ yyval.expr = EXPR_wildcard( info ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 64: ++#line 570 "./sql.y" ++ { ++ yyval.expr = EXPR_column( info, yyvsp[0].column_list ); ++ if( !yyval.expr ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 65: ++#line 579 "./sql.y" ++ { ++ yyval.column_list = parser_alloc_column( info, yyvsp[-2].string, yyvsp[0].string ); ++ if( !yyval.column_list ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 66: ++#line 585 "./sql.y" ++ { ++ yyval.column_list = parser_alloc_column( info, NULL, yyvsp[0].string ); ++ if( !yyval.column_list ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 67: ++#line 594 "./sql.y" ++ { ++ yyval.string = yyvsp[0].string; ++ ;} ++ break; ++ ++ case 68: ++#line 601 "./sql.y" ++ { ++ yyval.string = SQL_getstring( info, &yyvsp[0].str ); ++ if( !yyval.string ) ++ YYABORT; ++ ;} ++ break; ++ ++ case 69: ++#line 610 "./sql.y" ++ { ++ yyval.integer = SQL_getint( info ); ++ ;} ++ break; ++ ++ ++ } ++ ++/* Line 1000 of yacc.c. */ ++#line 2054 "sql.tab.c" ++ ++ yyvsp -= yylen; ++ yyssp -= yylen; ++ ++ ++ YY_STACK_PRINT (yyss, yyssp); ++ ++ *++yyvsp = yyval; ++ ++ ++ /* Now `shift' the result of the reduction. Determine what state ++ that goes to, based on the state we popped back to and the rule ++ number reduced by. */ ++ ++ yyn = yyr1[yyn]; ++ ++ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; ++ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) ++ yystate = yytable[yystate]; ++ else ++ yystate = yydefgoto[yyn - YYNTOKENS]; ++ ++ goto yynewstate; ++ ++ ++/*------------------------------------. ++| yyerrlab -- here on detecting error | ++`------------------------------------*/ ++yyerrlab: ++ /* If not already recovering from an error, report this error. */ ++ if (!yyerrstatus) ++ { ++ ++yynerrs; ++#if YYERROR_VERBOSE ++ yyn = yypact[yystate]; ++ ++ if (YYPACT_NINF < yyn && yyn < YYLAST) ++ { ++ YYSIZE_T yysize = 0; ++ int yytype = YYTRANSLATE (yychar); ++ const char* yyprefix; ++ char *yymsg; ++ int yyx; ++ ++ /* Start YYX at -YYN if negative to avoid negative indexes in ++ YYCHECK. */ ++ int yyxbegin = yyn < 0 ? -yyn : 0; ++ ++ /* Stay within bounds of both yycheck and yytname. */ ++ int yychecklim = YYLAST - yyn; ++ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; ++ int yycount = 0; ++ ++ yyprefix = ", expecting "; ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); ++ yycount += 1; ++ if (yycount == 5) ++ { ++ yysize = 0; ++ break; ++ } ++ } ++ yysize += (sizeof ("syntax error, unexpected ") ++ + yystrlen (yytname[yytype])); ++ yymsg = (char *) YYSTACK_ALLOC (yysize); ++ if (yymsg != 0) ++ { ++ char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); ++ yyp = yystpcpy (yyp, yytname[yytype]); ++ ++ if (yycount < 5) ++ { ++ yyprefix = ", expecting "; ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ yyp = yystpcpy (yyp, yyprefix); ++ yyp = yystpcpy (yyp, yytname[yyx]); ++ yyprefix = " or "; ++ } ++ } ++ yyerror (yymsg); ++ YYSTACK_FREE (yymsg); ++ } ++ else ++ yyerror ("syntax error; also virtual memory exhausted"); ++ } ++ else ++#endif /* YYERROR_VERBOSE */ ++ yyerror ("syntax error"); ++ } ++ ++ ++ ++ if (yyerrstatus == 3) ++ { ++ /* If just tried and failed to reuse lookahead token after an ++ error, discard it. */ ++ ++ if (yychar <= YYEOF) ++ { ++ /* If at end of input, pop the error token, ++ then the rest of the stack, then return failure. */ ++ if (yychar == YYEOF) ++ for (;;) ++ { ++ YYPOPSTACK; ++ if (yyssp == yyss) ++ YYABORT; ++ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); ++ yydestruct (yystos[*yyssp], yyvsp); ++ } ++ } ++ else ++ { ++ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); ++ yydestruct (yytoken, &yylval); ++ yychar = YYEMPTY; ++ ++ } ++ } ++ ++ /* Else will try to reuse lookahead token after shifting the error ++ token. */ ++ goto yyerrlab1; ++ ++ ++/*---------------------------------------------------. ++| yyerrorlab -- error raised explicitly by YYERROR. | ++`---------------------------------------------------*/ ++yyerrorlab: ++ ++#ifdef __GNUC__ ++ /* Pacify GCC when the user code never invokes YYERROR and the label ++ yyerrorlab therefore never appears in user code. */ ++ if (0) ++ goto yyerrorlab; ++#endif ++ ++ yyvsp -= yylen; ++ yyssp -= yylen; ++ yystate = *yyssp; ++ goto yyerrlab1; ++ ++ ++/*-------------------------------------------------------------. ++| yyerrlab1 -- common code for both syntax error and YYERROR. | ++`-------------------------------------------------------------*/ ++yyerrlab1: ++ yyerrstatus = 3; /* Each real token shifted decrements this. */ ++ ++ for (;;) ++ { ++ yyn = yypact[yystate]; ++ if (yyn != YYPACT_NINF) ++ { ++ yyn += YYTERROR; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ { ++ yyn = yytable[yyn]; ++ if (0 < yyn) ++ break; ++ } ++ } ++ ++ /* Pop the current state because it cannot handle the error token. */ ++ if (yyssp == yyss) ++ YYABORT; ++ ++ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); ++ yydestruct (yystos[yystate], yyvsp); ++ YYPOPSTACK; ++ yystate = *yyssp; ++ YY_STACK_PRINT (yyss, yyssp); ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ YYDPRINTF ((stderr, "Shifting error token, ")); ++ ++ *++yyvsp = yylval; ++ ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-------------------------------------. ++| yyacceptlab -- YYACCEPT comes here. | ++`-------------------------------------*/ ++yyacceptlab: ++ yyresult = 0; ++ goto yyreturn; ++ ++/*-----------------------------------. ++| yyabortlab -- YYABORT comes here. | ++`-----------------------------------*/ ++yyabortlab: ++ yyresult = 1; ++ goto yyreturn; ++ ++#ifndef yyoverflow ++/*----------------------------------------------. ++| yyoverflowlab -- parser overflow comes here. | ++`----------------------------------------------*/ ++yyoverflowlab: ++ yyerror ("parser stack overflow"); ++ yyresult = 2; ++ /* Fall through. */ ++#endif ++ ++yyreturn: ++#ifndef yyoverflow ++ if (yyss != yyssa) ++ YYSTACK_FREE (yyss); ++#endif ++ return yyresult; ++} ++ ++ ++#line 615 "./sql.y" ++ ++ ++static void *parser_alloc( void *info, unsigned int sz ) ++{ ++ SQL_input* sql = (SQL_input*) info; ++ struct list *mem; ++ ++ mem = msi_alloc( sizeof (struct list) + sz ); ++ list_add_tail( sql->mem, mem ); ++ return &mem[1]; ++} ++ ++static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ) ++{ ++ column_info *col; ++ ++ col = parser_alloc( info, sizeof (*col) ); ++ if( col ) ++ { ++ col->table = table; ++ col->column = column; ++ col->val = NULL; ++ col->type = 0; ++ col->next = NULL; ++ } ++ ++ return col; ++} ++ ++int SQL_lex( void *SQL_lval, SQL_input *sql ) ++{ ++ int token; ++ struct sql_str * str = SQL_lval; ++ ++ do ++ { ++ sql->n += sql->len; ++ if( ! sql->command[sql->n] ) ++ return 0; /* end of input */ ++ ++ /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */ ++ sql->len = sqliteGetToken( &sql->command[sql->n], &token ); ++ if( sql->len==0 ) ++ break; ++ str->data = &sql->command[sql->n]; ++ str->len = sql->len; ++ } ++ while( token == TK_SPACE ); ++ ++ /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */ ++ ++ return token; ++} ++ ++LPWSTR SQL_getstring( void *info, struct sql_str *strdata ) ++{ ++ LPCWSTR p = strdata->data; ++ UINT len = strdata->len; ++ LPWSTR str; ++ ++ /* if there's quotes, remove them */ ++ if( ( (p[0]=='`') && (p[len-1]=='`') ) || ++ ( (p[0]=='\'') && (p[len-1]=='\'') ) ) ++ { ++ p++; ++ len -= 2; ++ } ++ str = parser_alloc( info, (len + 1)*sizeof(WCHAR) ); ++ if( !str ) ++ return str; ++ memcpy( str, p, len*sizeof(WCHAR) ); ++ str[len]=0; ++ ++ return str; ++} ++ ++INT SQL_getint( void *info ) ++{ ++ SQL_input* sql = (SQL_input*) info; ++ LPCWSTR p = &sql->command[sql->n]; ++ INT i, r = 0; ++ ++ for( i=0; ilen; i++ ) ++ { ++ if( '0' > p[i] || '9' < p[i] ) ++ { ++ ERR("should only be numbers here!\n"); ++ break; ++ } ++ r = (p[i]-'0') + r*10; ++ } ++ ++ return r; ++} ++ ++int SQL_error( const char *str ) ++{ ++ return 0; ++} ++ ++static struct expr * EXPR_wildcard( void *info ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_WILDCARD; ++ } ++ return e; ++} ++ ++static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_COMPLEX; ++ e->u.expr.left = l; ++ e->u.expr.op = op; ++ e->u.expr.right = r; ++ } ++ return e; ++} ++ ++static struct expr * EXPR_column( void *info, column_info *column ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_COLUMN; ++ e->u.sval = column->column; ++ } ++ return e; ++} ++ ++static struct expr * EXPR_ival( void *info, int val ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_IVAL; ++ e->u.ival = val; ++ } ++ return e; ++} ++ ++static struct expr * EXPR_sval( void *info, struct sql_str *str ) ++{ ++ struct expr *e = parser_alloc( info, sizeof *e ); ++ if( e ) ++ { ++ e->type = EXPR_SVAL; ++ e->u.sval = SQL_getstring( info, str ); ++ } ++ return e; ++} ++ ++static BOOL SQL_MarkPrimaryKeys( column_info *cols, ++ column_info *keys ) ++{ ++ column_info *k; ++ BOOL found = TRUE; ++ ++ for( k = keys; k && found; k = k->next ) ++ { ++ column_info *c; ++ ++ found = FALSE; ++ for( c = cols; c && !found; c = c->next ) ++ { ++ if( lstrcmpW( k->column, c->column ) ) ++ continue; ++ c->type |= MSITYPE_KEY; ++ found = TRUE; ++ } ++ } ++ ++ return found; ++} ++ ++UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, ++ struct list *mem ) ++{ ++ SQL_input sql; ++ int r; ++ ++ *phview = NULL; ++ ++ sql.db = db; ++ sql.command = command; ++ sql.n = 0; ++ sql.len = 0; ++ sql.view = phview; ++ sql.mem = mem; ++ ++ r = SQL_parse(&sql); ++ ++ TRACE("Parse returned %d\n", r); ++ if( r ) ++ { ++ *sql.view = NULL; ++ return ERROR_BAD_QUERY_SYNTAX; ++ } ++ ++ return ERROR_SUCCESS; ++} ++ +Index: sql.tab.h +=================================================================== +--- sql.tab.h (revision 23782) ++++ sql.tab.h (working copy) +@@ -0,0 +1,345 @@ ++/* A Bison parser, made by GNU Bison 1.875c. */ ++ ++/* Skeleton parser for Yacc-like parsing with Bison, ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++ 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, 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., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ ++ ++/* Tokens. */ ++#ifndef YYTOKENTYPE ++# define YYTOKENTYPE ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ TK_ABORT = 258, ++ TK_AFTER = 259, ++ TK_AGG_FUNCTION = 260, ++ TK_ALL = 261, ++ TK_AND = 262, ++ TK_AS = 263, ++ TK_ASC = 264, ++ TK_BEFORE = 265, ++ TK_BEGIN = 266, ++ TK_BETWEEN = 267, ++ TK_BITAND = 268, ++ TK_BITNOT = 269, ++ TK_BITOR = 270, ++ TK_BY = 271, ++ TK_CASCADE = 272, ++ TK_CASE = 273, ++ TK_CHAR = 274, ++ TK_CHECK = 275, ++ TK_CLUSTER = 276, ++ TK_COLLATE = 277, ++ TK_COLUMN = 278, ++ TK_COMMA = 279, ++ TK_COMMENT = 280, ++ TK_COMMIT = 281, ++ TK_CONCAT = 282, ++ TK_CONFLICT = 283, ++ TK_CONSTRAINT = 284, ++ TK_COPY = 285, ++ TK_CREATE = 286, ++ TK_DEFAULT = 287, ++ TK_DEFERRABLE = 288, ++ TK_DEFERRED = 289, ++ TK_DELETE = 290, ++ TK_DELIMITERS = 291, ++ TK_DESC = 292, ++ TK_DISTINCT = 293, ++ TK_DOT = 294, ++ TK_DROP = 295, ++ TK_EACH = 296, ++ TK_ELSE = 297, ++ TK_END = 298, ++ TK_END_OF_FILE = 299, ++ TK_EQ = 300, ++ TK_EXCEPT = 301, ++ TK_EXPLAIN = 302, ++ TK_FAIL = 303, ++ TK_FLOAT = 304, ++ TK_FOR = 305, ++ TK_FOREIGN = 306, ++ TK_FROM = 307, ++ TK_FUNCTION = 308, ++ TK_GE = 309, ++ TK_GLOB = 310, ++ TK_GROUP = 311, ++ TK_GT = 312, ++ TK_HAVING = 313, ++ TK_HOLD = 314, ++ TK_IGNORE = 315, ++ TK_ILLEGAL = 316, ++ TK_IMMEDIATE = 317, ++ TK_IN = 318, ++ TK_INDEX = 319, ++ TK_INITIALLY = 320, ++ TK_ID = 321, ++ TK_INSERT = 322, ++ TK_INSTEAD = 323, ++ TK_INT = 324, ++ TK_INTEGER = 325, ++ TK_INTERSECT = 326, ++ TK_INTO = 327, ++ TK_IS = 328, ++ TK_ISNULL = 329, ++ TK_JOIN = 330, ++ TK_JOIN_KW = 331, ++ TK_KEY = 332, ++ TK_LE = 333, ++ TK_LIKE = 334, ++ TK_LIMIT = 335, ++ TK_LONG = 336, ++ TK_LONGCHAR = 337, ++ TK_LP = 338, ++ TK_LSHIFT = 339, ++ TK_LT = 340, ++ TK_LOCALIZABLE = 341, ++ TK_MATCH = 342, ++ TK_MINUS = 343, ++ TK_NE = 344, ++ TK_NOT = 345, ++ TK_NOTNULL = 346, ++ TK_NULL = 347, ++ TK_OBJECT = 348, ++ TK_OF = 349, ++ TK_OFFSET = 350, ++ TK_ON = 351, ++ TK_OR = 352, ++ TK_ORACLE_OUTER_JOIN = 353, ++ TK_ORDER = 354, ++ TK_PLUS = 355, ++ TK_PRAGMA = 356, ++ TK_PRIMARY = 357, ++ TK_RAISE = 358, ++ TK_REFERENCES = 359, ++ TK_REM = 360, ++ TK_REPLACE = 361, ++ TK_RESTRICT = 362, ++ TK_ROLLBACK = 363, ++ TK_ROW = 364, ++ TK_RP = 365, ++ TK_RSHIFT = 366, ++ TK_SELECT = 367, ++ TK_SEMI = 368, ++ TK_SET = 369, ++ TK_SHORT = 370, ++ TK_SLASH = 371, ++ TK_SPACE = 372, ++ TK_STAR = 373, ++ TK_STATEMENT = 374, ++ TK_STRING = 375, ++ TK_TABLE = 376, ++ TK_TEMP = 377, ++ TK_THEN = 378, ++ TK_TRANSACTION = 379, ++ TK_TRIGGER = 380, ++ TK_UMINUS = 381, ++ TK_UNCLOSED_STRING = 382, ++ TK_UNION = 383, ++ TK_UNIQUE = 384, ++ TK_UPDATE = 385, ++ TK_UPLUS = 386, ++ TK_USING = 387, ++ TK_VACUUM = 388, ++ TK_VALUES = 389, ++ TK_VIEW = 390, ++ TK_WHEN = 391, ++ TK_WHERE = 392, ++ TK_WILDCARD = 393, ++ COLUMN = 395, ++ FUNCTION = 396, ++ COMMENT = 397, ++ UNCLOSED_STRING = 398, ++ SPACE = 399, ++ ILLEGAL = 400, ++ END_OF_FILE = 401 ++ }; ++#endif ++#define TK_ABORT 258 ++#define TK_AFTER 259 ++#define TK_AGG_FUNCTION 260 ++#define TK_ALL 261 ++#define TK_AND 262 ++#define TK_AS 263 ++#define TK_ASC 264 ++#define TK_BEFORE 265 ++#define TK_BEGIN 266 ++#define TK_BETWEEN 267 ++#define TK_BITAND 268 ++#define TK_BITNOT 269 ++#define TK_BITOR 270 ++#define TK_BY 271 ++#define TK_CASCADE 272 ++#define TK_CASE 273 ++#define TK_CHAR 274 ++#define TK_CHECK 275 ++#define TK_CLUSTER 276 ++#define TK_COLLATE 277 ++#define TK_COLUMN 278 ++#define TK_COMMA 279 ++#define TK_COMMENT 280 ++#define TK_COMMIT 281 ++#define TK_CONCAT 282 ++#define TK_CONFLICT 283 ++#define TK_CONSTRAINT 284 ++#define TK_COPY 285 ++#define TK_CREATE 286 ++#define TK_DEFAULT 287 ++#define TK_DEFERRABLE 288 ++#define TK_DEFERRED 289 ++#define TK_DELETE 290 ++#define TK_DELIMITERS 291 ++#define TK_DESC 292 ++#define TK_DISTINCT 293 ++#define TK_DOT 294 ++#define TK_DROP 295 ++#define TK_EACH 296 ++#define TK_ELSE 297 ++#define TK_END 298 ++#define TK_END_OF_FILE 299 ++#define TK_EQ 300 ++#define TK_EXCEPT 301 ++#define TK_EXPLAIN 302 ++#define TK_FAIL 303 ++#define TK_FLOAT 304 ++#define TK_FOR 305 ++#define TK_FOREIGN 306 ++#define TK_FROM 307 ++#define TK_FUNCTION 308 ++#define TK_GE 309 ++#define TK_GLOB 310 ++#define TK_GROUP 311 ++#define TK_GT 312 ++#define TK_HAVING 313 ++#define TK_HOLD 314 ++#define TK_IGNORE 315 ++#define TK_ILLEGAL 316 ++#define TK_IMMEDIATE 317 ++#define TK_IN 318 ++#define TK_INDEX 319 ++#define TK_INITIALLY 320 ++#define TK_ID 321 ++#define TK_INSERT 322 ++#define TK_INSTEAD 323 ++#define TK_INT 324 ++#define TK_INTEGER 325 ++#define TK_INTERSECT 326 ++#define TK_INTO 327 ++#define TK_IS 328 ++#define TK_ISNULL 329 ++#define TK_JOIN 330 ++#define TK_JOIN_KW 331 ++#define TK_KEY 332 ++#define TK_LE 333 ++#define TK_LIKE 334 ++#define TK_LIMIT 335 ++#define TK_LONG 336 ++#define TK_LONGCHAR 337 ++#define TK_LP 338 ++#define TK_LSHIFT 339 ++#define TK_LT 340 ++#define TK_LOCALIZABLE 341 ++#define TK_MATCH 342 ++#define TK_MINUS 343 ++#define TK_NE 344 ++#define TK_NOT 345 ++#define TK_NOTNULL 346 ++#define TK_NULL 347 ++#define TK_OBJECT 348 ++#define TK_OF 349 ++#define TK_OFFSET 350 ++#define TK_ON 351 ++#define TK_OR 352 ++#define TK_ORACLE_OUTER_JOIN 353 ++#define TK_ORDER 354 ++#define TK_PLUS 355 ++#define TK_PRAGMA 356 ++#define TK_PRIMARY 357 ++#define TK_RAISE 358 ++#define TK_REFERENCES 359 ++#define TK_REM 360 ++#define TK_REPLACE 361 ++#define TK_RESTRICT 362 ++#define TK_ROLLBACK 363 ++#define TK_ROW 364 ++#define TK_RP 365 ++#define TK_RSHIFT 366 ++#define TK_SELECT 367 ++#define TK_SEMI 368 ++#define TK_SET 369 ++#define TK_SHORT 370 ++#define TK_SLASH 371 ++#define TK_SPACE 372 ++#define TK_STAR 373 ++#define TK_STATEMENT 374 ++#define TK_STRING 375 ++#define TK_TABLE 376 ++#define TK_TEMP 377 ++#define TK_THEN 378 ++#define TK_TRANSACTION 379 ++#define TK_TRIGGER 380 ++#define TK_UMINUS 381 ++#define TK_UNCLOSED_STRING 382 ++#define TK_UNION 383 ++#define TK_UNIQUE 384 ++#define TK_UPDATE 385 ++#define TK_UPLUS 386 ++#define TK_USING 387 ++#define TK_VACUUM 388 ++#define TK_VALUES 389 ++#define TK_VIEW 390 ++#define TK_WHEN 391 ++#define TK_WHERE 392 ++#define TK_WILDCARD 393 ++#define COLUMN 395 ++#define FUNCTION 396 ++#define COMMENT 397 ++#define UNCLOSED_STRING 398 ++#define SPACE 399 ++#define ILLEGAL 400 ++#define END_OF_FILE 401 ++ ++ ++ ++ ++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) ++#line 72 "./sql.y" ++typedef union YYSTYPE { ++ struct sql_str str; ++ LPWSTR string; ++ column_info *column_list; ++ MSIVIEW *query; ++ struct expr *expr; ++ USHORT column_type; ++ int integer; ++} YYSTYPE; ++/* Line 1275 of yacc.c. */ ++#line 337 "sql.tab.h" ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ ++# define YYSTYPE_IS_DECLARED 1 ++# define YYSTYPE_IS_TRIVIAL 1 ++#endif ++ ++ ++ ++ ++ +Index: tokenize.c +=================================================================== +--- tokenize.c (revision 23808) ++++ tokenize.c (working copy) +@@ -156,7 +156,7 @@ + static const Keyword aKeywordTable[] = { + { ABORT_W, TK_ABORT }, + { AFTER_W, TK_AFTER }, ++ /*{ ALTER_W, TK_ALTER },*/ +- { ALTER_W, TK_ALTER }, + { ALL_W, TK_ALL }, + { AND_W, TK_AND }, + { AS_W, TK_AS }, +@@ -247,7 +247,7 @@ + { SHORT_W, TK_SHORT }, + { STATEMENT_W, TK_STATEMENT }, + { TABLE_W, TK_TABLE }, ++ /*{ TEMPORARY_W, TK_TEMPORARY },*/ +- { TEMPORARY_W, TK_TEMPORARY }, + { THEN_W, TK_THEN }, + { TRANSACTION_W, TK_TRANSACTION }, + { TRIGGER_W, TK_TRIGGER }, diff --git a/reactos/dll/win32/msi/msipriv.h b/reactos/dll/win32/msi/msipriv.h index 991c11cb1fa..9a9b8b4bac3 100644 --- a/reactos/dll/win32/msi/msipriv.h +++ b/reactos/dll/win32/msi/msipriv.h @@ -231,6 +231,8 @@ typedef struct tagMSIPACKAGE UINT CurrentInstallState; msi_dialog *dialog; LPWSTR next_dialog; + float center_x; + float center_y; UINT WordCount; @@ -334,8 +336,6 @@ extern const WCHAR *msi_string_lookup_id( string_table *st, UINT id ); extern UINT msi_string_get_codepage( string_table *st ); -extern UINT VIEW_find_column( MSIVIEW *view, LPCWSTR name, UINT *n ); - extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name ); extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname, @@ -371,6 +371,7 @@ extern UINT MSI_RecordSetStreamW( MSIRECORD *, unsigned int, LPCWSTR ); extern UINT MSI_RecordSetStreamA( MSIRECORD *, unsigned int, LPCSTR ); extern UINT MSI_RecordDataSize( MSIRECORD *, unsigned int ); extern UINT MSI_RecordStreamToFile( MSIRECORD *, unsigned int, LPCWSTR ); +extern UINT MSI_RecordCopyField( MSIRECORD *, unsigned int, MSIRECORD *, unsigned int ); /* stream internals */ extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm ); @@ -392,6 +393,9 @@ extern UINT MSI_DatabaseGetPrimaryKeys( MSIDATABASE *, LPCWSTR, MSIRECORD ** ); extern UINT MSI_ViewExecute( MSIQUERY*, MSIRECORD * ); extern UINT MSI_ViewFetch( MSIQUERY*, MSIRECORD ** ); extern UINT MSI_ViewClose( MSIQUERY* ); +extern UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **); +extern UINT VIEW_find_column( MSIVIEW *, LPCWSTR, UINT * ); + /* install internals */ extern UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ); diff --git a/reactos/dll/win32/msi/msiquery.c b/reactos/dll/win32/msi/msiquery.c index 00a4853b103..fe1a68fa318 100644 --- a/reactos/dll/win32/msi/msiquery.c +++ b/reactos/dll/win32/msi/msiquery.c @@ -480,48 +480,28 @@ static UINT msi_set_record_type_string( MSIRECORD *rec, UINT field, UINT type ) return MSI_RecordSetStringW( rec, field, szType ); } -UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec) +UINT MSI_ViewGetColumnInfo( MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec ) { - MSIVIEW *view = NULL; - MSIQUERY *query = NULL; - MSIRECORD *rec = NULL; UINT r = ERROR_FUNCTION_FAILED, i, count = 0, type; + MSIRECORD *rec; + MSIVIEW *view = query->view; LPWSTR name; - TRACE("%ld %d %p\n", hView, info, hRec); - - if( !hRec ) - return ERROR_INVALID_PARAMETER; - - if( info != MSICOLINFO_NAMES && info != MSICOLINFO_TYPES ) - return ERROR_INVALID_PARAMETER; - - query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW ); - if( !query ) - return ERROR_INVALID_HANDLE; - - view = query->view; if( !view ) - goto out; + return ERROR_FUNCTION_FAILED; if( !view->ops->get_dimensions ) - goto out; + return ERROR_FUNCTION_FAILED; r = view->ops->get_dimensions( view, NULL, &count ); - if( r ) - goto out; + if( r != ERROR_SUCCESS ) + return r; if( !count ) - { - r = ERROR_INVALID_PARAMETER; - goto out; - } + return ERROR_INVALID_PARAMETER; rec = MSI_CreateRecord( count ); if( !rec ) - { - r = ERROR_FUNCTION_FAILED; - goto out; - } + return ERROR_FUNCTION_FAILED; for( i=0; ihdr ); - if (! *hRec) - r = ERROR_NOT_ENOUGH_MEMORY; + *prec = rec; + return ERROR_SUCCESS; +} -out: - msiobj_release( &query->hdr ); - if( rec ) +UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec) +{ + MSIQUERY *query = NULL; + MSIRECORD *rec = NULL; + UINT r; + + TRACE("%ld %d %p\n", hView, info, hRec); + + if( !hRec ) + return ERROR_INVALID_PARAMETER; + + if( info != MSICOLINFO_NAMES && info != MSICOLINFO_TYPES ) + return ERROR_INVALID_PARAMETER; + + query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW ); + if( !query ) + return ERROR_INVALID_HANDLE; + + r = MSI_ViewGetColumnInfo( query, info, &rec ); + if ( r == ERROR_SUCCESS ) + { + *hRec = alloc_msihandle( &rec->hdr ); + if ( !*hRec ) + r = ERROR_NOT_ENOUGH_MEMORY; msiobj_release( &rec->hdr ); + } + + msiobj_release( &query->hdr ); return r; } diff --git a/reactos/dll/win32/msi/record.c b/reactos/dll/win32/msi/record.c index 6c9a56713c9..8bc3871d3d8 100644 --- a/reactos/dll/win32/msi/record.c +++ b/reactos/dll/win32/msi/record.c @@ -43,7 +43,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb); #define MSIFIELD_NULL 0 #define MSIFIELD_INT 1 -#define MSIFIELD_STR 2 #define MSIFIELD_WSTR 3 #define MSIFIELD_STREAM 4 @@ -154,6 +153,53 @@ static BOOL string2intW( LPCWSTR str, int *out ) return TRUE; } +UINT MSI_RecordCopyField( MSIRECORD *in_rec, unsigned int in_n, + MSIRECORD *out_rec, unsigned int out_n ) +{ + UINT r = ERROR_SUCCESS; + + msiobj_lock( &in_rec->hdr ); + + if ( in_n > in_rec->count || out_n > out_rec->count ) + r = ERROR_FUNCTION_FAILED; + else if ( in_rec != out_rec || in_n != out_n ) + { + LPWSTR str; + MSIFIELD *in, *out; + + in = &in_rec->fields[in_n]; + out = &out_rec->fields[out_n]; + + switch ( in->type ) + { + case MSIFIELD_NULL: + break; + case MSIFIELD_INT: + out->u.iVal = in->u.iVal; + break; + case MSIFIELD_WSTR: + str = strdupW( in->u.szwVal ); + if ( !str ) + r = ERROR_OUTOFMEMORY; + else + out->u.szwVal = str; + break; + case MSIFIELD_STREAM: + IStream_AddRef( in->u.stream ); + out->u.stream = in->u.stream; + break; + default: + ERR("invalid field type %d\n", in->type); + } + if (r == ERROR_SUCCESS) + out->type = in->type; + } + + msiobj_unlock( &in_rec->hdr ); + + return r; +} + int MSI_RecordGetInteger( MSIRECORD *rec, unsigned int iField) { int ret = 0; diff --git a/reactos/dll/win32/msi/select.c b/reactos/dll/win32/msi/select.c index abb2dbdb33b..d47792b225f 100644 --- a/reactos/dll/win32/msi/select.c +++ b/reactos/dll/win32/msi/select.c @@ -102,13 +102,34 @@ static UINT SELECT_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT va static UINT SELECT_insert_row( struct tagMSIVIEW *view, MSIRECORD *record ) { MSISELECTVIEW *sv = (MSISELECTVIEW*)view; + UINT i, table_cols, r; + MSIRECORD *outrec; TRACE("%p %p\n", sv, record ); - if( !sv->table ) - return ERROR_FUNCTION_FAILED; + if ( !sv->table ) + return ERROR_FUNCTION_FAILED; - return sv->table->ops->insert_row( sv->table, record ); + /* rearrange the record to suit the table */ + r = sv->table->ops->get_dimensions( sv->table, NULL, &table_cols ); + if (r != ERROR_SUCCESS) + return r; + + outrec = MSI_CreateRecord( table_cols + 1 ); + + for (i=0; inum_cols; i++) + { + r = MSI_RecordCopyField( record, i+1, outrec, sv->cols[i] ); + if (r != ERROR_SUCCESS) + goto fail; + } + + r = sv->table->ops->insert_row( sv->table, outrec ); + +fail: + msiobj_release( &outrec->hdr ); + + return r; } static UINT SELECT_execute( struct tagMSIVIEW *view, MSIRECORD *record ) diff --git a/reactos/dll/win32/msi/sql.y b/reactos/dll/win32/msi/sql.y index a4e0f7e4463..8fa0fb340c3 100644 --- a/reactos/dll/win32/msi/sql.y +++ b/reactos/dll/win32/msi/sql.y @@ -108,7 +108,7 @@ static struct expr * EXPR_wildcard( void *info ); %token TK_ROW TK_RP TK_RSHIFT %token TK_SELECT TK_SEMI TK_SET TK_SHORT TK_SLASH TK_SPACE TK_STAR TK_STATEMENT %token TK_STRING -%token TK_TABLE TK_TEMP TK_THEN TK_TRANSACTION TK_TRIGGER +%token TK_TABLE TK_TEMPORARY TK_THEN TK_TRANSACTION TK_TRIGGER %token TK_UMINUS TK_UNCLOSED_STRING TK_UNION TK_UNIQUE %token TK_UPDATE TK_UPLUS TK_USING %token TK_VACUUM TK_VALUES TK_VIEW @@ -171,7 +171,7 @@ oneinsert: YYABORT; $$ = insert; } - | TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMP + | TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMPORARY { SQL_input *sql = (SQL_input*) info; MSIVIEW *insert = NULL; @@ -304,6 +304,10 @@ column_type: { $$ = $1 | MSITYPE_LOCALIZABLE; } + | data_type_l TK_TEMPORARY + { + FIXME("temporary column\n"); + } ; data_type_l: diff --git a/reactos/dll/win32/msi/string.c b/reactos/dll/win32/msi/string.c index db10ae5f1ad..7a806630354 100644 --- a/reactos/dll/win32/msi/string.c +++ b/reactos/dll/win32/msi/string.c @@ -37,7 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb); -#define HASH_SIZE 67 +#define HASH_SIZE 0x101 typedef struct _msistring { diff --git a/reactos/dll/win32/msi/table.c b/reactos/dll/win32/msi/table.c index fb468bc68b1..1c05e797d2e 100644 --- a/reactos/dll/win32/msi/table.c +++ b/reactos/dll/win32/msi/table.c @@ -926,20 +926,7 @@ static void msi_free_colinfo( MSICOLUMNINFO *colinfo, UINT count ) LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid) { - UINT sz=0, r; - LPWSTR str; - - r = msi_id2stringW( db->strings, stringid, NULL, &sz ); - if( r != ERROR_SUCCESS ) - return NULL; - str = msi_alloc( sz*sizeof (WCHAR) ); - if( !str ) - return str; - r = msi_id2stringW( db->strings, stringid, str, &sz ); - if( r == ERROR_SUCCESS ) - return str; - msi_free( str ); - return NULL; + return strdupW(msi_string_lookup_id( db->strings, stringid )); } static UINT get_tablecolumns( MSIDATABASE *db, @@ -1116,7 +1103,7 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt { MSITABLEVIEW *tv = (MSITABLEVIEW*)view; UINT ival = 0, refcol = 0, r; - LPWSTR sval; + LPCWSTR sval; LPWSTR full_name; DWORD len; static const WCHAR szDot[] = { '.', 0 }; @@ -1140,7 +1127,7 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt return r; /* lookup the string value from the string table */ - sval = MSI_makestring( tv->db, refcol ); + sval = msi_string_lookup_id( tv->db->strings, refcol ); if( !sval ) return ERROR_INVALID_PARAMETER; @@ -1154,7 +1141,6 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt if( r ) ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r); msi_free( full_name ); - msi_free( sval ); return r; } @@ -1302,12 +1288,38 @@ static UINT msi_table_find_row( MSITABLEVIEW *tv, MSIRECORD *rec, UINT *row ); static UINT table_validate_new( MSITABLEVIEW *tv, MSIRECORD *rec ) { - UINT r, row; + UINT r, row, i; + /* check there's no null values where they're not allowed */ + for( i = 0; i < tv->num_cols; i++ ) + { + if ( tv->columns[i].type & MSITYPE_NULLABLE ) + continue; + + if ( tv->columns[i].type & MSITYPE_STRING ) + { + LPCWSTR str; + + str = MSI_RecordGetString( rec, i+1 ); + if (str == NULL || str[0] == 0) + return ERROR_INVALID_DATA; + } + else + { + UINT n; + + n = MSI_RecordGetInteger( rec, i+1 ); + if (n == MSI_NULL_INTEGER) + return ERROR_INVALID_DATA; + } + } + + /* check there's no duplicate keys */ r = msi_table_find_row( tv, rec, &row ); - if (r != ERROR_SUCCESS) - return ERROR_SUCCESS; - return ERROR_INVALID_DATA; + if (r == ERROR_SUCCESS) + return ERROR_INVALID_DATA; + + return ERROR_SUCCESS; } static UINT msi_table_modify_row( MSITABLEVIEW *tv, MSIRECORD *rec, @@ -1352,6 +1364,11 @@ static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec ) TRACE("%p %p\n", tv, rec ); + /* check that the key is unique - can we find a matching row? */ + r = table_validate_new( tv, rec ); + if( r != ERROR_SUCCESS ) + return ERROR_FUNCTION_FAILED; + r = table_create_new_row( view, &row ); TRACE("insert_row returned %08x\n", r); if( r != ERROR_SUCCESS ) diff --git a/reactos/dll/win32/msi/tokenize.c b/reactos/dll/win32/msi/tokenize.c index c5f9a2d15d2..e8e41e31721 100644 --- a/reactos/dll/win32/msi/tokenize.c +++ b/reactos/dll/win32/msi/tokenize.c @@ -39,6 +39,8 @@ struct Keyword { int tokenType; /* The token value for this keyword */ }; +#define MAX_TOKEN_LEN 11 + static const WCHAR ABORT_W[] = { 'A','B','O','R','T',0 }; static const WCHAR AFTER_W[] = { 'A','F','T','E','R',0 }; static const WCHAR ALTER_W[] = { 'A','L','T','E','R',0 }; @@ -245,8 +247,7 @@ static const Keyword aKeywordTable[] = { { SHORT_W, TK_SHORT }, { STATEMENT_W, TK_STATEMENT }, { TABLE_W, TK_TABLE }, - { TEMP_W, TK_TEMP }, - { TEMPORARY_W, TK_TEMP }, + /*{ TEMPORARY_W, TK_TEMPORARY },*/ { THEN_W, TK_THEN }, { TRANSACTION_W, TK_TRANSACTION }, { TRIGGER_W, TK_TRIGGER }, @@ -263,21 +264,34 @@ static const Keyword aKeywordTable[] = { #define KEYWORD_COUNT ( sizeof aKeywordTable/sizeof (Keyword) ) +/* +** Comparison function for binary search. +*/ +static int compKeyword(const void *m1, const void *m2){ + const Keyword *k1 = m1, *k2 = m2; + + return strcmpiW( k1->zName, k2->zName ); +} + /* ** This function looks up an identifier to determine if it is a ** keyword. If it is a keyword, the token code of that keyword is ** returned. If the input is not a keyword, TK_ID is returned. */ static int sqliteKeywordCode(const WCHAR *z, int n){ - UINT i; + WCHAR str[MAX_TOKEN_LEN+1]; + Keyword key, *r; - for(i=0; iMAX_TOKEN_LEN ) + return TK_ID; + + memcpy( str, z, n*sizeof (WCHAR) ); + str[n] = 0; + key.tokenType = 0; + key.zName = str; + r = bsearch( &key, aKeywordTable, KEYWORD_COUNT, sizeof (Keyword), compKeyword ); + if( r ) + return r->tokenType; return TK_ID; } From 0f51b5f0bc5ec5546ad10577b82dfdc1eceb017d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 19:08:37 +0000 Subject: [PATCH 091/488] Implement registry handle closing notifications in ntoskrnl svn path=/trunk/; revision=24003 --- reactos/include/ddk/winddk.h | 7 ++++++- reactos/ntoskrnl/cm/regobj.c | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index a29a81703c9..b97d6ab0664 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -4990,6 +4990,11 @@ typedef struct _REG_POST_OPERATION_INFORMATION NTSTATUS Status; } REG_POST_OPERATION_INFORMATION,*PREG_POST_OPERATION_INFORMATION; +typedef struct _REG_KEY_HANDLE_CLOSE_INFORMATION +{ + PVOID Object; +} REG_KEY_HANDLE_CLOSE_INFORMATION, *PREG_KEY_HANDLE_CLOSE_INFORMATION; + /* ** Storage structures */ @@ -8988,7 +8993,7 @@ KeWaitForSingleObject( typedef ULONG_PTR -(*NTAPI PKIPI_BROADCAST_WORKER)( +(NTAPI *PKIPI_BROADCAST_WORKER)( IN ULONG_PTR Argument ); diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index 1868c1e562c..6ed5f62ca10 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -482,6 +482,9 @@ CmiObjectDelete(PVOID DeletedObject) { PKEY_OBJECT ParentKeyObject; PKEY_OBJECT KeyObject; + REG_KEY_HANDLE_CLOSE_INFORMATION KeyHandleCloseInfo; + REG_POST_OPERATION_INFORMATION PostOperationInfo; + NTSTATUS Status; DPRINT("Delete key object (%p)\n", DeletedObject); @@ -490,6 +493,17 @@ CmiObjectDelete(PVOID DeletedObject) ObReferenceObject (ParentKeyObject); + PostOperationInfo.Object = (PVOID)KeyObject; + KeyHandleCloseInfo.Object = (PVOID)KeyObject; + Status = CmiCallRegisteredCallbacks(RegNtPreKeyHandleClose, &KeyHandleCloseInfo); + if (!NT_SUCCESS(Status)) + { + PostOperationInfo.Status = Status; + CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo); + ObDereferenceObject (ParentKeyObject); + return; + } + /* Acquire hive lock */ KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); @@ -535,6 +549,8 @@ CmiObjectDelete(PVOID DeletedObject) ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); + PostOperationInfo.Status = STATUS_SUCCESS; + CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo); } From 70a18c5a4e8cb1dc5c7711b7dd14a194f44dea59 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Sat, 9 Sep 2006 19:26:43 +0000 Subject: [PATCH 092/488] Implement NtGdiGetPath (based on wine) svn path=/trunk/; revision=24004 --- .../subsystems/win32/win32k/objects/path.c | 62 +++++++++++++++++-- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/path.c b/reactos/subsystems/win32/win32k/objects/path.c index ccfb3f3cd62..fe7b3150708 100644 --- a/reactos/subsystems/win32/win32k/objects/path.c +++ b/reactos/subsystems/win32/win32k/objects/path.c @@ -189,13 +189,63 @@ NtGdiGetMiterLimit( INT STDCALL -NtGdiGetPath(HDC hDC, - LPPOINT Points, - LPBYTE Types, - INT nSize) +NtGdiGetPath( + HDC hDC, + LPPOINT Points, + LPBYTE Types, + INT nSize) { - UNIMPLEMENTED; - return 0; + INT ret = -1; + GdiPath *pPath; + + DPRINT("Enter NtGdiGetPath\n"); + + DC *dc = DC_LockDc(hDC); + if(!dc) + { + DPRINT1("Can't lock dc!\n"); + return -1; + } + + pPath = &dc->w.path; + + if(pPath->state != PATH_Closed) + { + SetLastWin32Error(ERROR_CAN_NOT_COMPLETE); + goto done; + } + + if(nSize==0) + { + ret = pPath->numEntriesUsed; + } + else if(nSizenumEntriesUsed) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + goto done; + } + else + { + _SEH_TRY + { + RtlCopyMemory(Points, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); + RtlCopyMemory(Types, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); + + /* Convert the points to logical coordinates */ + IntDPtoLP(dc, Points, pPath->numEntriesUsed); + + ret = pPath->numEntriesUsed; + } + _SEH_HANDLE + { + SetLastNtError(_SEH_GetExceptionCode()); + } + _SEH_END + } + +done: + DC_UnlockDc(dc); + return ret; } HRGN From eb1866f25cd74c9cc015c99fc15d43100ae58ab7 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sat, 9 Sep 2006 19:41:12 +0000 Subject: [PATCH 093/488] Implement GetLastInput base on bug 1753 patch by P43LOk, It did not catch the last input tick from keyboard or mouse. This code is not tested in reactos, but should work. See issue #1753 for more details. svn path=/trunk/; revision=24005 --- reactos/dll/win32/user32/windows/input.c | 5 +- reactos/include/reactos/win32k/ntuser.h | 6 + .../subsystems/win32/win32k/ntuser/input.c | 166 ++++++------------ reactos/tools/nci/w32ksvc.db | 1 + 4 files changed, 61 insertions(+), 117 deletions(-) diff --git a/reactos/dll/win32/user32/windows/input.c b/reactos/dll/win32/user32/windows/input.c index edf560529e4..fe8a9d25219 100644 --- a/reactos/dll/win32/user32/windows/input.c +++ b/reactos/dll/win32/user32/windows/input.c @@ -290,13 +290,12 @@ return (int)NtUserCallOneParam((DWORD) nTypeFlag, ONEPARAM_ROUTINE_GETKEYBOARDT /* - * @unimplemented + * @implemented */ BOOL STDCALL GetLastInputInfo(PLASTINPUTINFO plii) { - UNIMPLEMENTED; - return FALSE; + return NtUserGetLastInputInfo(plii); } diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index ca46d810e95..27d6a456331 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -1447,6 +1447,12 @@ NtUserRegisterHotKey(HWND hWnd, UINT fsModifiers, UINT vk); + +BOOL +NTAPI +NtUserGetLastInputInfo( + PLASTINPUTINFO plii); + DWORD NTAPI NtUserRegisterTasklist( diff --git a/reactos/subsystems/win32/win32k/ntuser/input.c b/reactos/subsystems/win32/win32k/ntuser/input.c index cf06fb5b636..bdcbcba5ddb 100644 --- a/reactos/subsystems/win32/win32k/ntuser/input.c +++ b/reactos/subsystems/win32/win32k/ntuser/input.c @@ -39,10 +39,6 @@ extern BYTE gQueueKeyStateTable[]; /* GLOBALS *******************************************************************/ -static HANDLE ScreenSaverThreadHandle; -static CLIENT_ID ScreenSaverThreadId; -static LARGE_INTEGER MouseInputCurrentTime; -static LARGE_INTEGER KeyboardInputCurrentTime; static HANDLE MouseDeviceHandle; static HANDLE MouseThreadHandle; @@ -57,6 +53,7 @@ PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue = 0; /* FUNCTIONS *****************************************************************/ ULONG FASTCALL IntSystemParametersInfo(UINT uiAction, UINT uiParam,PVOID pvParam, UINT fWinIni); +DWORD IntLastInputTick(BOOL LastInputTickSetGet); #define ClearMouseInput(mi) \ mi.dx = 0; \ @@ -71,6 +68,53 @@ IntSystemParametersInfo(UINT uiAction, UINT uiParam,PVOID pvParam, UINT fWinIni) IntMouseInput(&mi); \ ClearMouseInput(mi); + +DWORD IntLastInputTick(BOOL LastInputTickSetGet) +{ + static DWORD LastInputTick = 0; + if (LastInputTickSetGet == TRUE) + { + LARGE_INTEGER TickCount; + KeQueryTickCount(&TickCount); + LastInputTick = TickCount.u.LowPart; + } + return LastInputTick; +} + +BOOL +STDCALL +NtUserGetLastInputInfo(PLASTINPUTINFO plii) +{ + BOOL ret = TRUE; + + UserEnterShared(); + + _SEH_TRY + { + if (ProbeForReadUint(&plii->cbSize) != sizeof(LASTINPUTINFO)) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + ret = FALSE; + _SEH_LEAVE; + } + + ProbeForWrite(plii, sizeof(LASTINPUTINFO), sizeof(DWORD)); + + plii->dwTime = IntLastInputTick(FALSE); + } + _SEH_HANDLE + { + SetLastNtError(_SEH_GetExceptionCode()); + ret = FALSE; + } + _SEH_END; + + UserLeave(); + + return ret; +} + + VOID FASTCALL ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount) { @@ -155,101 +199,7 @@ ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount) SendMouseEvent(mi); } -VOID STDCALL -ScreenSaverThreadMain(PVOID StartContext) -{ - KEVENT Event; - LARGE_INTEGER Timeout; - LARGE_INTEGER DelayTimer; - LARGE_INTEGER CurrentTime; - LARGE_INTEGER DiffTimeMouse; - LARGE_INTEGER DiffTimeKeyboard; - UINT ScreenSaverTimeOut = 0; - BOOL nPreviousState = FALSE; - NTSTATUS Status; - BOOL FirstTime = TRUE; - return; - KeSetPriorityThread(&PsGetCurrentThread()->Tcb, - LOW_REALTIME_PRIORITY + 3); - - KeQuerySystemTime(&MouseInputCurrentTime); - KeQuerySystemTime(&KeyboardInputCurrentTime); - - DelayTimer.QuadPart = -10000000LL; /* 1 second timeout */ - - for(;;) - { - DPRINT("Screen Saver auto start Thread Waiting for start event\n"); - Status = KeWaitForSingleObject(&InputThreadsStart, - 0, - KernelMode, - TRUE, - NULL); - DPRINT("Screen Saver auto start Thread Starting...\n"); - while(InputThreadsRunning) - { - - IntSystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &ScreenSaverTimeOut, 0); - IntSystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &nPreviousState, 0); - - Timeout.QuadPart = ((LONGLONG)ScreenSaverTimeOut) * 10000000LL; - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DelayTimer); - - if(Status == STATUS_ALERTED && !InputThreadsRunning) - { - break; - } - if(!NT_SUCCESS(Status)) - { - DPRINT1("Win32K: Failed to read from Screen Saver auto thread.\n"); - return; //(Status); - } - - KeQuerySystemTime(&CurrentTime); - DiffTimeMouse.QuadPart = CurrentTime.QuadPart - MouseInputCurrentTime.QuadPart; - DiffTimeKeyboard.QuadPart = CurrentTime.QuadPart - KeyboardInputCurrentTime.QuadPart; - - if ( (DiffTimeMouse.QuadPart >= Timeout.QuadPart) && - (DiffTimeKeyboard.QuadPart >= Timeout.QuadPart) && - (nPreviousState == FALSE)) - { - BOOL nPreviousState = FALSE; - DPRINT("Keyboard and Mouse TimeOut Starting Screen Saver ...\n"); - DPRINT(" %I64d Keyboard Timeout Value\n",DiffTimeKeyboard.QuadPart); - DPRINT(" %I64d Mouse Timeout Value \n",DiffTimeMouse.QuadPart); - DPRINT(" %I64d TimeOut \n",DiffTimeMouse.QuadPart); - - if (FirstTime == FALSE) - { - CSR_API_MESSAGE Request; - CsrInit(); - Request.Type = MAKE_CSR_API(START_SCREEN_SAVER, CSR_GUI); - Request.Data.StartScreenSaver.Start = TRUE; - co_CsrNotifyScreenSaver(&Request ); - - IntSystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, &nPreviousState, 0); - } - else - { - FirstTime = FALSE; - } - } - - if ( (DiffTimeMouse.QuadPart < Timeout.QuadPart) && - (DiffTimeKeyboard.QuadPart < Timeout.QuadPart) && - (nPreviousState == TRUE)) - { - IntSystemParametersInfo(SPI_SETSCREENSAVERRUNNING, FALSE, &nPreviousState, 0); - } - - - } - DPRINT("Screen Saver auto start Thread Stopped...\n"); - } -} VOID STDCALL @@ -325,9 +275,8 @@ MouseThreadMain(PVOID StartContext) DPRINT1("Win32K: Failed to read from mouse.\n"); return; //(Status); } - DPRINT("MouseEvent\n"); - - KeQuerySystemTime(&MouseInputCurrentTime); + DPRINT("MouseEvent\n"); + IntLastInputTick(TRUE); UserEnterExclusive(); @@ -637,7 +586,8 @@ KeyboardThreadMain(PVOID StartContext) return; //(Status); } - KeQuerySystemTime(&KeyboardInputCurrentTime); + /* Set LastInputTick */ + IntLastInputTick(TRUE); /* Update modifier state */ fsModifiers = IntKeyboardGetModifiers(&KeyInput); @@ -917,18 +867,6 @@ InitInputImpl(VOID) DPRINT1("Win32K: Failed to create mouse thread.\n"); } - Status = PsCreateSystemThread(&ScreenSaverThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &ScreenSaverThreadId, - ScreenSaverThreadMain, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Win32K: Failed to create ScreenSaver auto start thread.\n"); - } - return STATUS_SUCCESS; } diff --git a/reactos/tools/nci/w32ksvc.db b/reactos/tools/nci/w32ksvc.db index 823f9edf195..0f27f3fb5aa 100644 --- a/reactos/tools/nci/w32ksvc.db +++ b/reactos/tools/nci/w32ksvc.db @@ -390,6 +390,7 @@ NtUserGetKeyboardLayoutName 1 NtUserGetKeyboardState 1 NtUserGetKeyNameText 3 NtUserGetKeyState 1 +NtUserGetLastInputInfo 1 NtUserGetListBoxInfo 1 NtUserGetMenuBarInfo 4 NtUserGetMenuIndex 2 From e10a07af0056a30a14bc789a73c9ef40d0962654 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 9 Sep 2006 20:38:41 +0000 Subject: [PATCH 094/488] *add support for the new SVN 1.4.x binary format svn path=/trunk/; revision=24006 --- reactos/tools/buildno/buildno.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/reactos/tools/buildno/buildno.cpp b/reactos/tools/buildno/buildno.cpp index c859f2dd6cd..9a49bbf6303 100644 --- a/reactos/tools/buildno/buildno.cpp +++ b/reactos/tools/buildno/buildno.cpp @@ -3,6 +3,7 @@ * buildno - Generate the build number for ReactOS * * Copyright (c) 1999,2000 Emanuele Aliberti + * Copyright (c) 2006 Christoph von Wittich * * The build number is the day on which the build took * place, as YYYYMMDD @@ -16,6 +17,8 @@ * * REVISIONS * --------- + * 2006-09-09 (cwittich) + * read binary entries files from SVN 1.4.x * 2000-01-22 (ea) * Fixed bugs: tm_year is (current_year - 1900), * tm_month is 0-11 not 1-12 and code ignored TZ. @@ -176,6 +179,32 @@ GetRev(void) static char Unknown[] = "UNKNOWN"; static char Revision[10]; /* 999999999 revisions should be enough for everyone... */ + /* SVN 1.4.x */ + FILE *fp = NULL; + char ch; + size_t count = 0, chars = 0; + fp = fopen(".svn/entries", "r"); + if (fp != NULL) + { + if (fgetc(fp) == 56) /* some kind of header? */ + { + while((ch=fgetc(fp)) != EOF) + { + if (ch == 10) count++; /* seems to used as a seperator */ + if (count > 3) + break; + if ((count == 3) && (chars < sizeof(Revision))) + { + if (chars != 0) + Revision[chars - 1] = ch; + chars++; + } + } + fclose(fp); + return Revision; + } + } + try { XMLElement *head; From bc6649b7461db82c0d02cc3a938732fea6c8b10b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 20:39:50 +0000 Subject: [PATCH 095/488] Put a NULL entry point if explicitly asked for. Thanks w3seek for his help on this issue svn path=/trunk/; revision=24007 --- reactos/tools/rbuild/module.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp index 5aa42fb5a7a..4fee8b0bb5b 100644 --- a/reactos/tools/rbuild/module.cpp +++ b/reactos/tools/rbuild/module.cpp @@ -1110,6 +1110,8 @@ string Module::GetEntryPoint(bool leadingUnderscore) const { string result = ""; + if (entrypoint == "0" || entrypoint == "0x0") + return "0"; if (leadingUnderscore) result = "_"; From ae5f6b945d6eddc11ad308fda4ca50ee2cedce30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 22:33:07 +0000 Subject: [PATCH 096/488] Add missing entrypoint="0" directive in rbuild files [Part 1/2] svn path=/trunk/; revision=24008 --- .../explorer/notifyhook/notifyhook.rbuild | 2 +- reactos/dll/3rdparty/freetype/freetype.rbuild | 2 +- reactos/dll/3rdparty/mesa32/mesa32.rbuild | 2 +- reactos/dll/cpl/access/access.rbuild | 2 +- reactos/dll/cpl/appwiz/appwiz.rbuild | 3 +- reactos/dll/cpl/desk/desk.rbuild | 3 +- reactos/dll/cpl/hdwwiz/hdwwiz.rbuild | 2 +- reactos/dll/cpl/intl/intl.rbuild | 3 +- reactos/dll/cpl/intl_new/intl.rbuild | 3 +- reactos/dll/cpl/main/main.rbuild | 3 +- reactos/dll/cpl/mmsys/mmsys.rbuild | 2 +- reactos/dll/cpl/ncpa/ncpa.rbuild | 3 +- reactos/dll/cpl/powercfg/powercfg.rbuild | 3 +- reactos/dll/cpl/sysdm/sysdm.rbuild | 3 +- reactos/dll/cpl/timedate/timedate.rbuild | 3 +- reactos/dll/directx/d3d8thk/d3d8thk.rbuild | 2 +- reactos/dll/directx/ddraw/ddraw.rbuild | 2 +- reactos/dll/directx/devenum/devenum.rbuild | 2 +- reactos/dll/directx/dinput/dinput.rbuild | 2 +- reactos/dll/directx/dinput8/dinput8.rbuild | 2 +- reactos/dll/directx/dplay/dplay.rbuild | 2 +- reactos/dll/directx/dplayx/dplayx.rbuild | 2 +- reactos/dll/directx/dsound/dsound.rbuild | 31 ++++++++++--------- reactos/dll/directx/dxdiagn/dxdiagn.rbuild | 2 +- reactos/dll/ntdll/ntdll.rbuild | 2 +- .../drivers/network/wshtcpip/wshtcpip.rbuild | 2 +- reactos/hal/halx86/mp/halmp.rbuild | 2 +- reactos/hal/halx86/up/halup.rbuild | 2 +- reactos/hal/halx86/xbox/halxbox.rbuild | 2 +- reactos/lib/3rdparty/bzip2/bzip2.rbuild | 2 +- reactos/subsystems/win/basesrv/basesrv.rbuild | 2 +- reactos/subsystems/win/winsrv/winsrv.rbuild | 2 +- .../win32/csrss/win32csr/win32csr.rbuild | 3 +- reactos/tools/rbuild/tests/data/module.rbuild | 2 +- 34 files changed, 59 insertions(+), 48 deletions(-) diff --git a/reactos/base/shell/explorer/notifyhook/notifyhook.rbuild b/reactos/base/shell/explorer/notifyhook/notifyhook.rbuild index 95b10c65dbd..524d2893186 100644 --- a/reactos/base/shell/explorer/notifyhook/notifyhook.rbuild +++ b/reactos/base/shell/explorer/notifyhook/notifyhook.rbuild @@ -1,6 +1,6 @@ - + . diff --git a/reactos/dll/3rdparty/freetype/freetype.rbuild b/reactos/dll/3rdparty/freetype/freetype.rbuild index d03c1a39021..cf22185e459 100644 --- a/reactos/dll/3rdparty/freetype/freetype.rbuild +++ b/reactos/dll/3rdparty/freetype/freetype.rbuild @@ -1,4 +1,4 @@ - + include diff --git a/reactos/dll/3rdparty/mesa32/mesa32.rbuild b/reactos/dll/3rdparty/mesa32/mesa32.rbuild index 93247e64d17..3934fb75164 100644 --- a/reactos/dll/3rdparty/mesa32/mesa32.rbuild +++ b/reactos/dll/3rdparty/mesa32/mesa32.rbuild @@ -1,5 +1,5 @@ - + -Wl,--enable-stdcall-fixup ntdll diff --git a/reactos/dll/cpl/access/access.rbuild b/reactos/dll/cpl/access/access.rbuild index b225ef8727e..b5145efea4c 100644 --- a/reactos/dll/cpl/access/access.rbuild +++ b/reactos/dll/cpl/access/access.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/appwiz/appwiz.rbuild b/reactos/dll/cpl/appwiz/appwiz.rbuild index 46310579fd9..1146c2f2646 100644 --- a/reactos/dll/cpl/appwiz/appwiz.rbuild +++ b/reactos/dll/cpl/appwiz/appwiz.rbuild @@ -1,4 +1,4 @@ - + . @@ -11,6 +11,7 @@ advapi32 user32 comctl32 + msvcrt appwiz.c appwiz.rc diff --git a/reactos/dll/cpl/desk/desk.rbuild b/reactos/dll/cpl/desk/desk.rbuild index 4592c1d4f1f..5452bc10b0e 100644 --- a/reactos/dll/cpl/desk/desk.rbuild +++ b/reactos/dll/cpl/desk/desk.rbuild @@ -1,4 +1,4 @@ - + . @@ -19,6 +19,7 @@ shell32 ntdll msimg32 + msvcrt classinst.c desk.c background.c diff --git a/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild b/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild index 7df49f5c2e2..d3abf8b6114 100644 --- a/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild +++ b/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/intl/intl.rbuild b/reactos/dll/cpl/intl/intl.rbuild index 84f5a7e050a..de434fd8594 100644 --- a/reactos/dll/cpl/intl/intl.rbuild +++ b/reactos/dll/cpl/intl/intl.rbuild @@ -1,4 +1,4 @@ - + . @@ -12,6 +12,7 @@ comctl32 advapi32 setupapi + msvcrt currency.c date.c general.c diff --git a/reactos/dll/cpl/intl_new/intl.rbuild b/reactos/dll/cpl/intl_new/intl.rbuild index 536afb17821..bc48954992e 100644 --- a/reactos/dll/cpl/intl_new/intl.rbuild +++ b/reactos/dll/cpl/intl_new/intl.rbuild @@ -1,4 +1,4 @@ - + . @@ -11,6 +11,7 @@ user32 comctl32 advapi32 + msvcrt intl.c locale.c extra.c diff --git a/reactos/dll/cpl/main/main.rbuild b/reactos/dll/cpl/main/main.rbuild index 7c0237685fe..8747fb38b9a 100644 --- a/reactos/dll/cpl/main/main.rbuild +++ b/reactos/dll/cpl/main/main.rbuild @@ -1,4 +1,4 @@ - + . @@ -14,6 +14,7 @@ devmgr comdlg32 gdi32 + msvcrt keyboard.c main.c mouse.c diff --git a/reactos/dll/cpl/mmsys/mmsys.rbuild b/reactos/dll/cpl/mmsys/mmsys.rbuild index e6a7b362ee2..69eeff2e21b 100644 --- a/reactos/dll/cpl/mmsys/mmsys.rbuild +++ b/reactos/dll/cpl/mmsys/mmsys.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/ncpa/ncpa.rbuild b/reactos/dll/cpl/ncpa/ncpa.rbuild index 52e7aa111ae..32d766b5be2 100644 --- a/reactos/dll/cpl/ncpa/ncpa.rbuild +++ b/reactos/dll/cpl/ncpa/ncpa.rbuild @@ -1,4 +1,4 @@ - + . @@ -15,6 +15,7 @@ ws2_32 dhcpcsvc ntdll + msvcrt ncpa.c tcpip_properties.c ncpa.rc diff --git a/reactos/dll/cpl/powercfg/powercfg.rbuild b/reactos/dll/cpl/powercfg/powercfg.rbuild index a43f876523a..e1d257bc141 100644 --- a/reactos/dll/cpl/powercfg/powercfg.rbuild +++ b/reactos/dll/cpl/powercfg/powercfg.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine @@ -12,6 +12,7 @@ user32 powrprof comctl32 + msvcrt powercfg.c powershemes.c alarms.c diff --git a/reactos/dll/cpl/sysdm/sysdm.rbuild b/reactos/dll/cpl/sysdm/sysdm.rbuild index 524b1213023..220551a854e 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rbuild +++ b/reactos/dll/cpl/sysdm/sysdm.rbuild @@ -1,4 +1,4 @@ - + . @@ -13,6 +13,7 @@ comctl32 netapi32 ntdll + msvcrt advanced.c computer.c environment.c diff --git a/reactos/dll/cpl/timedate/timedate.rbuild b/reactos/dll/cpl/timedate/timedate.rbuild index 345f1eb1b08..cc558a57f91 100644 --- a/reactos/dll/cpl/timedate/timedate.rbuild +++ b/reactos/dll/cpl/timedate/timedate.rbuild @@ -1,4 +1,4 @@ - + . @@ -14,6 +14,7 @@ comctl32 ws2_32 iphlpapi + msvcrt clock.c dateandtime.c internettime.c diff --git a/reactos/dll/directx/d3d8thk/d3d8thk.rbuild b/reactos/dll/directx/d3d8thk/d3d8thk.rbuild index 594bb29a9c4..6587124ee4c 100644 --- a/reactos/dll/directx/d3d8thk/d3d8thk.rbuild +++ b/reactos/dll/directx/d3d8thk/d3d8thk.rbuild @@ -1,4 +1,4 @@ - + gdi32 d3d8thk.rc diff --git a/reactos/dll/directx/ddraw/ddraw.rbuild b/reactos/dll/directx/ddraw/ddraw.rbuild index accd69d3336..84191863bd5 100644 --- a/reactos/dll/directx/ddraw/ddraw.rbuild +++ b/reactos/dll/directx/ddraw/ddraw.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/directx/devenum/devenum.rbuild b/reactos/dll/directx/devenum/devenum.rbuild index 8757f05f99b..c26c2dc3115 100644 --- a/reactos/dll/directx/devenum/devenum.rbuild +++ b/reactos/dll/directx/devenum/devenum.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/directx/dinput/dinput.rbuild b/reactos/dll/directx/dinput/dinput.rbuild index 807844e73a0..15022bdb13d 100644 --- a/reactos/dll/directx/dinput/dinput.rbuild +++ b/reactos/dll/directx/dinput/dinput.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/directx/dinput8/dinput8.rbuild b/reactos/dll/directx/dinput8/dinput8.rbuild index 7e32a23977c..4379d1dd5d3 100644 --- a/reactos/dll/directx/dinput8/dinput8.rbuild +++ b/reactos/dll/directx/dinput8/dinput8.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/directx/dplay/dplay.rbuild b/reactos/dll/directx/dplay/dplay.rbuild index 2e356af13ca..090f696c0c2 100644 --- a/reactos/dll/directx/dplay/dplay.rbuild +++ b/reactos/dll/directx/dplay/dplay.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/directx/dplayx/dplayx.rbuild b/reactos/dll/directx/dplayx/dplayx.rbuild index 1bbabb48f9a..086ffc43d5b 100644 --- a/reactos/dll/directx/dplayx/dplayx.rbuild +++ b/reactos/dll/directx/dplayx/dplayx.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/directx/dsound/dsound.rbuild b/reactos/dll/directx/dsound/dsound.rbuild index 0c41c14434e..6d81120e074 100644 --- a/reactos/dll/directx/dsound/dsound.rbuild +++ b/reactos/dll/directx/dsound/dsound.rbuild @@ -1,4 +1,4 @@ - + . @@ -17,20 +17,21 @@ ole32 winmm dxguid - version.rc + msvcrt + version.rc buffer.c - capture.c - dsound.c - dsound_main.c - duplex.c - mixer.c - primary.c - propset.c - regsvr.c - sound3d.c - dxroslayer/dxrosdrv_querydsounddesc.c - dxroslayer/dxrosdrv_querydsoundiface.c - dxroslayer/dxroslayer.c - dxroslayer/getguidfromstring.c + capture.c + dsound.c + dsound_main.c + duplex.c + mixer.c + primary.c + propset.c + regsvr.c + sound3d.c + dxroslayer/dxrosdrv_querydsounddesc.c + dxroslayer/dxrosdrv_querydsoundiface.c + dxroslayer/dxroslayer.c + dxroslayer/getguidfromstring.c dsound.spec diff --git a/reactos/dll/directx/dxdiagn/dxdiagn.rbuild b/reactos/dll/directx/dxdiagn/dxdiagn.rbuild index efcb5cd8ea0..d12f629915c 100644 --- a/reactos/dll/directx/dxdiagn/dxdiagn.rbuild +++ b/reactos/dll/directx/dxdiagn/dxdiagn.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/ntdll/ntdll.rbuild b/reactos/dll/ntdll/ntdll.rbuild index 41bd902c1b2..a1132f68eda 100644 --- a/reactos/dll/ntdll/ntdll.rbuild +++ b/reactos/dll/ntdll/ntdll.rbuild @@ -1,4 +1,4 @@ - + inc diff --git a/reactos/drivers/network/wshtcpip/wshtcpip.rbuild b/reactos/drivers/network/wshtcpip/wshtcpip.rbuild index 8dfa6f7e0a1..e409bdbc471 100644 --- a/reactos/drivers/network/wshtcpip/wshtcpip.rbuild +++ b/reactos/drivers/network/wshtcpip/wshtcpip.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/hal/halx86/mp/halmp.rbuild b/reactos/hal/halx86/mp/halmp.rbuild index b2facb92013..96329497363 100644 --- a/reactos/hal/halx86/mp/halmp.rbuild +++ b/reactos/hal/halx86/mp/halmp.rbuild @@ -1,4 +1,4 @@ - + ../include diff --git a/reactos/hal/halx86/up/halup.rbuild b/reactos/hal/halx86/up/halup.rbuild index eb550f562e1..925a7b5f0a4 100644 --- a/reactos/hal/halx86/up/halup.rbuild +++ b/reactos/hal/halx86/up/halup.rbuild @@ -1,4 +1,4 @@ - + ../include diff --git a/reactos/hal/halx86/xbox/halxbox.rbuild b/reactos/hal/halx86/xbox/halxbox.rbuild index a47856ce58b..a38820e99a1 100644 --- a/reactos/hal/halx86/xbox/halxbox.rbuild +++ b/reactos/hal/halx86/xbox/halxbox.rbuild @@ -1,4 +1,4 @@ - + ../include . diff --git a/reactos/lib/3rdparty/bzip2/bzip2.rbuild b/reactos/lib/3rdparty/bzip2/bzip2.rbuild index 895598b6e29..5c38ea256f9 100644 --- a/reactos/lib/3rdparty/bzip2/bzip2.rbuild +++ b/reactos/lib/3rdparty/bzip2/bzip2.rbuild @@ -1,4 +1,4 @@ - + diff --git a/reactos/subsystems/win/basesrv/basesrv.rbuild b/reactos/subsystems/win/basesrv/basesrv.rbuild index e1c3df76345..f88701e8a34 100644 --- a/reactos/subsystems/win/basesrv/basesrv.rbuild +++ b/reactos/subsystems/win/basesrv/basesrv.rbuild @@ -1,4 +1,4 @@ - + . include diff --git a/reactos/subsystems/win/winsrv/winsrv.rbuild b/reactos/subsystems/win/winsrv/winsrv.rbuild index 565e2e2c946..dfa187c1197 100644 --- a/reactos/subsystems/win/winsrv/winsrv.rbuild +++ b/reactos/subsystems/win/winsrv/winsrv.rbuild @@ -1,4 +1,4 @@ - + . include diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild index 20cf2bf1e0d..dc9c96ca927 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -1,4 +1,4 @@ - + . include @@ -14,6 +14,7 @@ gdi32 advapi32 psapi + msvcrt w32csr.h conio.c desktopbg.c diff --git a/reactos/tools/rbuild/tests/data/module.rbuild b/reactos/tools/rbuild/tests/data/module.rbuild index 6ccc81839e1..d81e14e9d9f 100644 --- a/reactos/tools/rbuild/tests/data/module.rbuild +++ b/reactos/tools/rbuild/tests/data/module.rbuild @@ -7,7 +7,7 @@ - + module1 module1 file3.c From 54ad3ea87ba28e8dbd69ff005dad9ed3f44e6f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 9 Sep 2006 22:55:57 +0000 Subject: [PATCH 097/488] Add missing entrypoint="0" directive in rbuild files [Part 2/2] svn path=/trunk/; revision=24009 --- reactos/dll/win32/cabinet/cabinet.rbuild | 2 +- reactos/dll/win32/cfgmgr32/cfgmgr32.rbuild | 2 +- reactos/dll/win32/dnsapi/dnsapi.rbuild | 2 +- reactos/dll/win32/glu32/glu32.rbuild | 2 +- reactos/dll/win32/icmp/icmp.rbuild | 3 ++- reactos/dll/win32/icmp/icmp_main.c | 2 +- reactos/dll/win32/lsasrv/lsasrv.rbuild | 2 +- reactos/dll/win32/lz32/lz32.rbuild | 2 +- reactos/dll/win32/msvcrt20/msvcrt20.rbuild | 3 ++- reactos/dll/win32/netcfgx/netcfgx.rbuild | 2 +- reactos/dll/win32/oleacc/oleacc.rbuild | 2 +- reactos/dll/win32/olepro32/olepro32.rbuild | 2 +- reactos/dll/win32/samsrv/samsrv.rbuild | 2 +- reactos/dll/win32/security/security.rbuild | 2 +- reactos/dll/win32/shfolder/shfolder.rbuild | 2 +- reactos/dll/win32/winmm/midimap/midimap.rbuild | 3 ++- reactos/dll/win32/winmm/wavemap/wavemap.rbuild | 2 +- 17 files changed, 20 insertions(+), 17 deletions(-) diff --git a/reactos/dll/win32/cabinet/cabinet.rbuild b/reactos/dll/win32/cabinet/cabinet.rbuild index a14559f57c9..2a3b0ae61c4 100644 --- a/reactos/dll/win32/cabinet/cabinet.rbuild +++ b/reactos/dll/win32/cabinet/cabinet.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/cfgmgr32/cfgmgr32.rbuild b/reactos/dll/win32/cfgmgr32/cfgmgr32.rbuild index 2fb10c9f91c..225514355a9 100644 --- a/reactos/dll/win32/cfgmgr32/cfgmgr32.rbuild +++ b/reactos/dll/win32/cfgmgr32/cfgmgr32.rbuild @@ -1,4 +1,4 @@ - + -nostartfiles -nostdlib -lgcc diff --git a/reactos/dll/win32/dnsapi/dnsapi.rbuild b/reactos/dll/win32/dnsapi/dnsapi.rbuild index 1601eaee551..567611f6501 100644 --- a/reactos/dll/win32/dnsapi/dnsapi.rbuild +++ b/reactos/dll/win32/dnsapi/dnsapi.rbuild @@ -1,4 +1,4 @@ - + include src diff --git a/reactos/dll/win32/glu32/glu32.rbuild b/reactos/dll/win32/glu32/glu32.rbuild index 5c85f0d0161..a699396beeb 100644 --- a/reactos/dll/win32/glu32/glu32.rbuild +++ b/reactos/dll/win32/glu32/glu32.rbuild @@ -1,4 +1,4 @@ - + include libnurbs/internals diff --git a/reactos/dll/win32/icmp/icmp.rbuild b/reactos/dll/win32/icmp/icmp.rbuild index 7e1b15e3ba8..237979ab096 100644 --- a/reactos/dll/win32/icmp/icmp.rbuild +++ b/reactos/dll/win32/icmp/icmp.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine @@ -7,6 +7,7 @@ kernel32 ws2_32 wine + msvcrt icmp_main.c icmp.rc icmp.spec diff --git a/reactos/dll/win32/icmp/icmp_main.c b/reactos/dll/win32/icmp/icmp_main.c index 3218337a05c..3d7af0c65f3 100644 --- a/reactos/dll/win32/icmp/icmp_main.c +++ b/reactos/dll/win32/icmp/icmp_main.c @@ -231,7 +231,7 @@ DWORD WINAPI IcmpSendEcho( /* check the request size against SO_MAX_MSG_SIZE using getsockopt */ /* Prepare the request */ - id=getpid() & 0xFFFF; + id=_getpid() & 0xFFFF; seq=InterlockedIncrement(&icmp_sequence) & 0xFFFF; reqsize=ICMP_MINLEN+RequestSize; diff --git a/reactos/dll/win32/lsasrv/lsasrv.rbuild b/reactos/dll/win32/lsasrv/lsasrv.rbuild index fcaf7d58109..48bcf86221e 100644 --- a/reactos/dll/win32/lsasrv/lsasrv.rbuild +++ b/reactos/dll/win32/lsasrv/lsasrv.rbuild @@ -1,4 +1,4 @@ - + . . diff --git a/reactos/dll/win32/lz32/lz32.rbuild b/reactos/dll/win32/lz32/lz32.rbuild index ec9470a9e3d..90982abe250 100644 --- a/reactos/dll/win32/lz32/lz32.rbuild +++ b/reactos/dll/win32/lz32/lz32.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/msvcrt20/msvcrt20.rbuild b/reactos/dll/win32/msvcrt20/msvcrt20.rbuild index 5d00b03278b..179789af098 100644 --- a/reactos/dll/win32/msvcrt20/msvcrt20.rbuild +++ b/reactos/dll/win32/msvcrt20/msvcrt20.rbuild @@ -1,4 +1,4 @@ - + . @@ -12,6 +12,7 @@ string ntdll kernel32 + msvcrt msvcrt20.c msvcrt20.rc diff --git a/reactos/dll/win32/netcfgx/netcfgx.rbuild b/reactos/dll/win32/netcfgx/netcfgx.rbuild index 1edf95d9d18..226940ffe4f 100644 --- a/reactos/dll/win32/netcfgx/netcfgx.rbuild +++ b/reactos/dll/win32/netcfgx/netcfgx.rbuild @@ -1,4 +1,4 @@ - + netcfgx.c diff --git a/reactos/dll/win32/oleacc/oleacc.rbuild b/reactos/dll/win32/oleacc/oleacc.rbuild index dfc4304f3fa..21772894a16 100644 --- a/reactos/dll/win32/oleacc/oleacc.rbuild +++ b/reactos/dll/win32/oleacc/oleacc.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/olepro32/olepro32.rbuild b/reactos/dll/win32/olepro32/olepro32.rbuild index 8652577a01f..e1402f59f9d 100644 --- a/reactos/dll/win32/olepro32/olepro32.rbuild +++ b/reactos/dll/win32/olepro32/olepro32.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/samsrv/samsrv.rbuild b/reactos/dll/win32/samsrv/samsrv.rbuild index e2c28e7660b..616254da836 100644 --- a/reactos/dll/win32/samsrv/samsrv.rbuild +++ b/reactos/dll/win32/samsrv/samsrv.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/win32/security/security.rbuild b/reactos/dll/win32/security/security.rbuild index dae1b177ca3..43c1bdd0c09 100644 --- a/reactos/dll/win32/security/security.rbuild +++ b/reactos/dll/win32/security/security.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/win32/shfolder/shfolder.rbuild b/reactos/dll/win32/shfolder/shfolder.rbuild index 5138073606d..269632814ca 100644 --- a/reactos/dll/win32/shfolder/shfolder.rbuild +++ b/reactos/dll/win32/shfolder/shfolder.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/winmm/midimap/midimap.rbuild b/reactos/dll/win32/winmm/midimap/midimap.rbuild index a32ebe03d5f..bd650b8f56e 100644 --- a/reactos/dll/win32/winmm/midimap/midimap.rbuild +++ b/reactos/dll/win32/winmm/midimap/midimap.rbuild @@ -1,4 +1,4 @@ - + . include/wine @@ -16,6 +16,7 @@ advapi32 user32 winmm + msvcrt midimap.c midimap.rc midimap.spec diff --git a/reactos/dll/win32/winmm/wavemap/wavemap.rbuild b/reactos/dll/win32/winmm/wavemap/wavemap.rbuild index 25fd37f3dd8..41d13cdd6e4 100644 --- a/reactos/dll/win32/winmm/wavemap/wavemap.rbuild +++ b/reactos/dll/win32/winmm/wavemap/wavemap.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine From b61c75703cec16329db9505c43b56769315bd228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 10 Sep 2006 01:08:35 +0000 Subject: [PATCH 098/488] LastInputTick value should be in milliseconds, according to the help of GetTickCount in MSDN svn path=/trunk/; revision=24010 --- reactos/subsystems/win32/win32k/ntuser/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/input.c b/reactos/subsystems/win32/win32k/ntuser/input.c index bdcbcba5ddb..e452751b8a2 100644 --- a/reactos/subsystems/win32/win32k/ntuser/input.c +++ b/reactos/subsystems/win32/win32k/ntuser/input.c @@ -76,7 +76,7 @@ DWORD IntLastInputTick(BOOL LastInputTickSetGet) { LARGE_INTEGER TickCount; KeQueryTickCount(&TickCount); - LastInputTick = TickCount.u.LowPart; + LastInputTick = TickCount.u.LowPart * (KeQueryTimeIncrement() / 10000); } return LastInputTick; } From c9657557546c6bee6ecdae98b4521f0411c92491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 10 Sep 2006 01:20:53 +0000 Subject: [PATCH 099/488] Remove screensaver implementation of win32k (ie revert revision 22879). svn path=/trunk/; revision=24011 --- reactos/include/reactos/subsys/csrss/csrss.h | 7 -- .../win32/csrss/include/desktopbg.h | 1 - .../subsystems/win32/csrss/win32csr/conio.c | 85 ------------------- .../subsystems/win32/csrss/win32csr/dllmain.c | 1 - reactos/subsystems/win32/win32k/include/csr.h | 1 - reactos/subsystems/win32/win32k/ntuser/csr.c | 40 --------- 6 files changed, 135 deletions(-) diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index 20ff51d7fba..c37b3878d66 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -410,12 +410,6 @@ typedef struct HANDLE InputWaitHandle; } CSRSS_GET_INPUT_WAIT_HANDLE, *PCSRSS_GET_INPUT_WAIT_HANDLE; -typedef struct -{ - BOOL Start; -} CSRSS_START_SCREEN_SAVER, *PCSRSS_START_SCREEN_SAVER; - - #define CSR_API_MESSAGE_HEADER_SIZE(Type) (FIELD_OFFSET(CSR_API_MESSAGE, Data) + sizeof(Type)) #define CSRSS_MAX_WRITE_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)) #define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)) @@ -549,7 +543,6 @@ typedef struct _CSR_API_MESSAGE CSRSS_SET_CONSOLE_OUTPUT_CP SetConsoleOutputCodePage; CSRSS_GET_INPUT_WAIT_HANDLE GetConsoleInputWaitHandle; CSRSS_GET_PROCESS_LIST GetProcessListRequest; - CSRSS_START_SCREEN_SAVER StartScreenSaver; } Data; } CSR_API_MESSAGE, *PCSR_API_MESSAGE; diff --git a/reactos/subsystems/win32/csrss/include/desktopbg.h b/reactos/subsystems/win32/csrss/include/desktopbg.h index 4bac760014b..b06a16c95f3 100644 --- a/reactos/subsystems/win32/csrss/include/desktopbg.h +++ b/reactos/subsystems/win32/csrss/include/desktopbg.h @@ -16,7 +16,6 @@ CSR_API(CsrCreateDesktop); CSR_API(CsrShowDesktop); CSR_API(CsrHideDesktop); CSR_API(CsrRegisterSystemClasses); -CSR_API(CsrStartScreenSaver); BOOL FASTCALL DtbgIsDesktopVisible(VOID); diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 6361ed2269f..1a9f766f80b 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -3343,89 +3343,4 @@ CSR_API(CsrGetProcessList) return Request->Status = STATUS_SUCCESS; } -CSR_API(CsrStartScreenSaver) -{ - - DPRINT("CsrStartScreenSaver : %s Screen Saver \n", - (Request->Data.StartScreenSaver.Start) ? "Start" : "Stop"); - - if (Request->Data.StartScreenSaver.Start == TRUE) - { - STARTUPINFOW si; - PROCESS_INFORMATION pi; - WCHAR szCmdline[MAX_PATH]; - - HKEY hKey; - WCHAR szBuffer[MAX_PATH]; - DWORD bufferSize = sizeof(szBuffer); - DWORD varType = REG_SZ; - LONG result; - - /* FIXME : - 1. Make it unicode and ansi compatible with TCHAR - - 2. Return state it is running if a tree try start it - one more screen saver when we already have one - screen saver running - - 3. Use GetLongPath or GetPathName so we can use %SystemRoot% in - the key that will make it posible for livecd have a preview screen - saver install. - - 4. Move the code to winlogon SAS and screen saver must run in - the secuar desktop. But current our Winlogon does not working - well with SAS and with Secure desktop, So I (Magnus Olsen aka GreatLord) - add the code here as w3seek recomandete - */ - - result = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_QUERY_VALUE, &hKey); - if (result == ERROR_SUCCESS) - { - result = RegQueryValueExW(hKey, L"SCRNSAVE.EXE", 0, &varType, (LPBYTE)szBuffer, &bufferSize); - if(result == ERROR_SUCCESS) - { - swprintf(szCmdline, L"%s /s",szBuffer); - DPRINT("CsrStartScreenSaver : OK %S, Name %S\n", szCmdline, szBuffer); - ZeroMemory( &si, sizeof(si) ); - si.cb = sizeof(si); - ZeroMemory( &pi, sizeof(pi) ); - if(CreateProcessW( NULL, szCmdline, NULL, NULL, FALSE, 0, NULL,NULL,&si, &pi )) - { - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - } - } - else - { - GetSystemDirectoryW(szCmdline,MAX_PATH); - wprintf(szCmdline, L"%s\\%s /s",szCmdline,szBuffer); - DPRINT("CsrStartScreenSaver : OK %S, Name %S\n", szCmdline, szBuffer); - ZeroMemory( &si, sizeof(si) ); - si.cb = sizeof(si); - ZeroMemory( &pi, sizeof(pi) ); - if(CreateProcessW( NULL, szCmdline, NULL, NULL, FALSE, 0, NULL,NULL,&si, &pi )) - { - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - } - else - { - DPRINT("CsrStartScreenSaver : failed 0x%08X\n", result); - } - } - RegCloseKey(hKey); - } - else - { - DPRINT1("CsrStartScreenSaver : failed to RegOpenKeyExW (error 0x%lx)\n", result); - } - return Request->Status = STATUS_SUCCESS; - } - else - { - /* TODO: Stopping the screensaver */ - return Request->Status = STATUS_NOT_IMPLEMENTED; - } -} - /* EOF */ diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index 5a8399c1aa8..5fd8e1635ec 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -68,7 +68,6 @@ static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = CSRSS_DEFINE_API(GET_CONSOLE_OUTPUT_CP, CsrGetConsoleOutputCodePage), CSRSS_DEFINE_API(SET_CONSOLE_OUTPUT_CP, CsrSetConsoleOutputCodePage), CSRSS_DEFINE_API(GET_PROCESS_LIST, CsrGetProcessList), - CSRSS_DEFINE_API(START_SCREEN_SAVER, CsrStartScreenSaver), { 0, 0, NULL } }; diff --git a/reactos/subsystems/win32/win32k/include/csr.h b/reactos/subsystems/win32/win32k/include/csr.h index 64031180025..e3caa96cd0c 100644 --- a/reactos/subsystems/win32/win32k/include/csr.h +++ b/reactos/subsystems/win32/win32k/include/csr.h @@ -14,7 +14,6 @@ extern PEPROCESS CsrProcess; NTSTATUS FASTCALL CsrInit(void); NTSTATUS FASTCALL co_CsrNotify(PCSR_API_MESSAGE Request); -NTSTATUS FASTCALL co_CsrNotifyScreenSaver(PCSR_API_MESSAGE Request); NTSTATUS FASTCALL CsrCloseHandle(HANDLE Handle); NTSTATUS WINAPI CsrInsertObject(HANDLE ObjectHandle, ACCESS_MASK DesiredAccess, diff --git a/reactos/subsystems/win32/win32k/ntuser/csr.c b/reactos/subsystems/win32/win32k/ntuser/csr.c index 83745d47b0d..649d593cebf 100644 --- a/reactos/subsystems/win32/win32k/ntuser/csr.c +++ b/reactos/subsystems/win32/win32k/ntuser/csr.c @@ -86,46 +86,6 @@ co_CsrNotify(PCSR_API_MESSAGE Request) } -NTSTATUS FASTCALL -co_CsrNotifyScreenSaver(PCSR_API_MESSAGE Request) -{ - NTSTATUS Status; - PEPROCESS OldProcess; - - if (NULL == CsrProcess) - { - return STATUS_INVALID_PORT_HANDLE; - } - - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - - /* Switch to the process in which the WindowsApiPort handle is valid */ - OldProcess = PsGetCurrentProcess(); - if (CsrProcess != OldProcess) - { - KeAttachProcess(&CsrProcess->Pcb); - } - - Status = ZwRequestWaitReplyPort(WindowsApiPort, - &Request->Header, - &Request->Header); - - - if (CsrProcess != OldProcess) - { - KeDetachProcess(); - } - - if (NT_SUCCESS(Status)) - { - Status = Request->Status; - } - - return Status; -} - - NTSTATUS STDCALL CsrInsertObject(HANDLE ObjectHandle, From 96bb2d5365afe1cbde5ffce5c85865a1018808e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 10 Sep 2006 02:20:29 +0000 Subject: [PATCH 100/488] Add stub for SPI_GETSCREENSAVEACTIVE (which always return TRUE at the moment...) svn path=/trunk/; revision=24012 --- reactos/subsystems/win32/win32k/ntuser/misc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reactos/subsystems/win32/win32k/ntuser/misc.c b/reactos/subsystems/win32/win32k/ntuser/misc.c index e99164c19c2..da1c667b78b 100644 --- a/reactos/subsystems/win32/win32k/ntuser/misc.c +++ b/reactos/subsystems/win32/win32k/ntuser/misc.c @@ -994,6 +994,7 @@ IntSystemParametersInfo( case SPI_GETSCREENSAVERRUNNING: case SPI_GETSCREENSAVETIMEOUT: case SPI_SETSCREENSAVETIMEOUT: + case SPI_GETSCREENSAVEACTIVE: case SPI_GETFLATMENU: case SPI_SETFLATMENU: { @@ -1033,6 +1034,11 @@ IntSystemParametersInfo( if (pvParam != NULL) *((BOOL*)pvParam) = WinStaObject->ScreenSaverRunning; WinStaObject->ScreenSaverRunning = uiParam; break; + case SPI_GETSCREENSAVEACTIVE: + /* FIXME: how to disable the screensaver? */ + if (pvParam != NULL) *((BOOL*)pvParam) = TRUE; + return TRUE; + break; case SPI_GETWHEELSCROLLLINES: CurInfo = IntGetSysCursorInfo(WinStaObject); if (pvParam != NULL) *((UINT*)pvParam) = CurInfo->WheelScroLines; @@ -1409,6 +1415,7 @@ UserSystemParametersInfo( case SPI_SETSCREENSAVERRUNNING: case SPI_GETSCREENSAVETIMEOUT: case SPI_SETSCREENSAVETIMEOUT: + case SPI_GETSCREENSAVEACTIVE: case SPI_GETFLATMENU: case SPI_SETFLATMENU: { From 0fbf1539ac275b039159f1a7e5692a889497032f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 10 Sep 2006 02:22:12 +0000 Subject: [PATCH 101/488] At last, enable screensaver svn path=/trunk/; revision=24013 --- reactos/base/system/winlogon/sas.c | 2 +- reactos/base/system/winlogon/screensaver.c | 36 +++++++++++++++++----- reactos/base/system/winlogon/winlogon.h | 3 +- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/reactos/base/system/winlogon/sas.c b/reactos/base/system/winlogon/sas.c index 00068eaa14d..31801b5f325 100644 --- a/reactos/base/system/winlogon/sas.c +++ b/reactos/base/system/winlogon/sas.c @@ -545,7 +545,7 @@ DispatchSAS( if (!Session->Gina.Functions.WlxScreenSaverNotify(Session->Gina.Context, &bSecure)) { /* Skip start of screen saver */ - SetEvent(Session->hUserActivity); + SetEvent(Session->hEndOfScreenSaver); } else { diff --git a/reactos/base/system/winlogon/screensaver.c b/reactos/base/system/winlogon/screensaver.c index 329fe9f8fab..9e56fad9b9d 100644 --- a/reactos/base/system/winlogon/screensaver.c +++ b/reactos/base/system/winlogon/screensaver.c @@ -89,9 +89,16 @@ ScreenSaverThreadMain( goto cleanup; } + Session->hEndOfScreenSaver = CreateEventW(NULL, FALSE, FALSE, NULL); + if (!Session->hEndOfScreenSaver) + { + ERR("WL: Unable to create event (error %lu)\n", GetLastError()); + goto cleanup; + } + HandleArray[0] = Session->hEndOfScreenSaverThread; HandleArray[1] = Session->hScreenSaverParametersChanged; - HandleArray[2] = Session->hUserActivity; + HandleArray[2] = Session->hEndOfScreenSaver; LoadScreenSaverParameters(&Timeout); @@ -160,6 +167,8 @@ cleanup: RevertToSelf(); if (Session->hUserActivity) CloseHandle(Session->hUserActivity); + if (Session->hEndOfScreenSaver) + CloseHandle(Session->hEndOfScreenSaver); #ifndef USE_GETLASTINPUTINFO if (Session->KeyboardHook) UnhookWindowsHookEx(Session->KeyboardHook); @@ -177,9 +186,6 @@ InitializeScreenSaver( { HANDLE ScreenSaverThread; - FIXME("Disabling screen saver due to numerous bugs in ReactOS (see r23540)!\n"); - return TRUE; - #ifndef USE_GETLASTINPUTINFO /* Register hooks to detect keyboard and mouse activity */ Session->KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardActivityProc, hAppInstance, 0); @@ -234,7 +240,9 @@ StartScreenSaver( DWORD dwType; STARTUPINFOW StartupInfo; PROCESS_INFORMATION ProcessInformation; + HANDLE HandleArray[2]; LONG rc; + NTSTATUS Status; BOOL ret = FALSE; if (!ImpersonateLoggedOnUser(Session->UserToken)) @@ -286,17 +294,29 @@ StartScreenSaver( WARN("WL: Unable to start %S, error %lu\n", szApplicationName, GetLastError()); goto cleanup; } + CloseHandle(ProcessInformation.hThread); + + SystemParametersInfoW(SPI_SETSCREENSAVERRUNNING, TRUE, NULL, 0); + + /* Wait the end of the process or some other activity */ + ResetEvent(Session->hUserActivity); + HandleArray[0] = ProcessInformation.hProcess; + HandleArray[1] = Session->hUserActivity; + Status = WaitForMultipleObjects(2, HandleArray, FALSE, INFINITE); + if (Status == WAIT_OBJECT_0 + 1) + { + /* Kill the screen saver */ + TerminateProcess(ProcessInformation.hProcess, 0); + } + SetEvent(Session->hEndOfScreenSaver); CloseHandle(ProcessInformation.hProcess); - CloseHandle(ProcessInformation.hThread); cleanup: RevertToSelf(); if (hKey) RegCloseKey(hKey); - if (ret) - SystemParametersInfoW(SPI_SETSCREENSAVERRUNNING, TRUE, NULL, 0); - else + if (!ret) { PostMessageW(Session->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_SCRNSVR_ACTIVITY, 0); #ifndef USE_GETLASTINPUTINFO diff --git a/reactos/base/system/winlogon/winlogon.h b/reactos/base/system/winlogon/winlogon.h index 6487484cdf7..ffc9692e04f 100644 --- a/reactos/base/system/winlogon/winlogon.h +++ b/reactos/base/system/winlogon/winlogon.h @@ -27,7 +27,7 @@ #ifndef __WINLOGON_MAIN_H__ #define __WINLOGON_MAIN_H__ -//#define USE_GETLASTINPUTINFO +#define USE_GETLASTINPUTINFO #define WIN32_NO_STATUS #include @@ -146,6 +146,7 @@ typedef struct _WLSESSION HANDLE hEndOfScreenSaverThread; HANDLE hScreenSaverParametersChanged; HANDLE hUserActivity; + HANDLE hEndOfScreenSaver; #ifndef USE_GETLASTINPUTINFO DWORD LastActivity; #endif From 746299a0dafd37bf2679522f89e40d2513b6e64e Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 10 Sep 2006 08:00:57 +0000 Subject: [PATCH 102/488] - Move and slightly modify the relocation code to RTL, change its prototype so that it can be used in future in freeldr, ntdll and in kernel (right now there is code duplication, which is removed from kernel by this commit). svn path=/trunk/; revision=24016 --- reactos/include/ndk/rtlfuncs.h | 12 ++++ reactos/lib/rtl/image.c | 109 ++++++++++++++++++++++++++++++++- reactos/ntoskrnl/ldr/loader.c | 108 ++------------------------------ 3 files changed, 125 insertions(+), 104 deletions(-) diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index ec76c604720..b7d3f1e4d21 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -2593,6 +2593,18 @@ RtlImageRvaToSection( ULONG Rva ); +NTSYSAPI +ULONG +NTAPI +LdrRelocateImageWithBias( + IN PVOID NewAddress, + IN LONGLONG AdditionalBias, + IN PUCHAR LoaderName, + IN ULONG Success, + IN ULONG Conflict, + IN ULONG Invalid +); + // // Activation Context Functions // diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index 09435070b75..8b87b39672b 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -2,7 +2,9 @@ * PROJECT: ReactOS system libraries * FILE: lib/rtl/image.c * PURPOSE: Image handling functions - * PROGRAMMER: Eric Kohl + * Relocate functions were previously located in + * ntoskrnl/ldr/loader.c + * PROGRAMMER: Eric Kohl + original authors from loader.c file */ /* INCLUDES *****************************************************************/ @@ -147,4 +149,109 @@ RtlImageRvaToVa ( (ULONG_PTR)Section->VirtualAddress); } +ULONG +NTAPI +LdrRelocateImageWithBias( + IN PVOID BaseAddress, + IN LONGLONG AdditionalBias, + IN PUCHAR LoaderName, + IN ULONG Success, + IN ULONG Conflict, + IN ULONG Invalid + ) +{ + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_DATA_DIRECTORY RelocationDDir; + PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; + ULONG Count, i; + PVOID Address;//, MaxAddress; + PUSHORT TypeOffset; + ULONG_PTR Delta; + SHORT Offset; + USHORT Type; + PUSHORT ShortPtr; + PULONG LongPtr; + + NtHeaders = RtlImageNtHeader(BaseAddress); + + if (NtHeaders == NULL) + return Invalid; + + if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) + { + return Conflict; + } + + RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + + if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0) + { + return Success; + } + + Delta = (ULONG_PTR)BaseAddress - NtHeaders->OptionalHeader.ImageBase + AdditionalBias; + RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + RelocationDDir->VirtualAddress); + RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size); + //MaxAddress = RVA(BaseAddress, DriverSize); + + while (RelocationDir < RelocationEnd && + RelocationDir->SizeOfBlock > 0) + { + Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); + Address = RVA(BaseAddress, RelocationDir->VirtualAddress); + TypeOffset = (PUSHORT)(RelocationDir + 1); + + for (i = 0; i < Count; i++) + { + Offset = *TypeOffset & 0xFFF; + Type = *TypeOffset >> 12; + ShortPtr = (PUSHORT)(RVA(Address, Offset)); + + /* Don't relocate after the end of the loaded driver */ + /*if ((PVOID)ShortPtr >= MaxAddress) + { + break; + }*/ + + /* + * Don't relocate within the relocation section itself. + * GCC/LD generates sometimes relocation records for the relocation section. + * This is a bug in GCC/LD. + */ + if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir || + (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd) + { + switch (Type) + { + case IMAGE_REL_BASED_ABSOLUTE: + break; + + case IMAGE_REL_BASED_HIGH: + *ShortPtr += HIWORD(Delta); + break; + + case IMAGE_REL_BASED_LOW: + *ShortPtr += LOWORD(Delta); + break; + + case IMAGE_REL_BASED_HIGHLOW: + LongPtr = (PULONG)ShortPtr; + *LongPtr += Delta; + break; + + case IMAGE_REL_BASED_HIGHADJ: + case IMAGE_REL_BASED_MIPS_JMPADDR: + default: + DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); + DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset); + return Invalid; + } + } + TypeOffset++; + } + RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock); + } + + return Success; +} /* EOF */ diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 4e2cc3a9b8b..0c320666754 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -84,11 +84,6 @@ LdrPEGetExportByName ( static PVOID LdrPEFixupForward ( PCHAR ForwardName ); -static NTSTATUS -LdrPEPerformRelocations ( - PVOID DriverBase, - ULONG DriverSize ); - static NTSTATUS LdrPEFixupImports ( PLDR_DATA_TABLE_ENTRY Module ); @@ -782,7 +777,8 @@ LdrPEProcessModule( } /* Perform relocation fixups */ - Status = LdrPEPerformRelocations(DriverBase, DriverSize); + Status = LdrRelocateImageWithBias(DriverBase, 0, "", STATUS_SUCCESS, + STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT); if (!NT_SUCCESS(Status)) { // MmFreeSection(DriverBase); @@ -1009,7 +1005,9 @@ LdrSafePEProcessModule ( } /* Perform relocation fixups */ - Status = LdrPEPerformRelocations(DriverBase, *DriverSize); + Status = LdrRelocateImageWithBias(DriverBase, 0, "", STATUS_SUCCESS, + STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT); + if (!NT_SUCCESS(Status)) { return NULL; @@ -1108,102 +1106,6 @@ LdrPEFixupForward ( PCHAR ForwardName ) return LdrPEGetExportByName(ModuleObject->DllBase, (PUCHAR)(p+1), 0xffff); } -static NTSTATUS -LdrPEPerformRelocations ( - PVOID DriverBase, - ULONG DriverSize) -{ - PIMAGE_NT_HEADERS NtHeaders; - PIMAGE_DATA_DIRECTORY RelocationDDir; - PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; - ULONG Count, i; - PVOID Address, MaxAddress; - PUSHORT TypeOffset; - ULONG_PTR Delta; - SHORT Offset; - USHORT Type; - PUSHORT ShortPtr; - PULONG LongPtr; - - NtHeaders = RtlImageNtHeader(DriverBase); - - if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) - { - return STATUS_UNSUCCESSFUL; - } - - RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; - - if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0) - { - return STATUS_SUCCESS; - } - - Delta = (ULONG_PTR)DriverBase - NtHeaders->OptionalHeader.ImageBase; - RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)DriverBase + RelocationDDir->VirtualAddress); - RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size); - MaxAddress = RVA(DriverBase, DriverSize); - - while (RelocationDir < RelocationEnd && - RelocationDir->SizeOfBlock > 0) - { - Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - Address = RVA(DriverBase, RelocationDir->VirtualAddress); - TypeOffset = (PUSHORT)(RelocationDir + 1); - - for (i = 0; i < Count; i++) - { - Offset = *TypeOffset & 0xFFF; - Type = *TypeOffset >> 12; - ShortPtr = (PUSHORT)(RVA(Address, Offset)); - - /* Don't relocate after the end of the loaded driver */ - if ((PVOID)ShortPtr >= MaxAddress) - { - break; - } - - /* - * Don't relocate within the relocation section itself. - * GCC/LD generates sometimes relocation records for the relocation section. - * This is a bug in GCC/LD. - */ - if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir || - (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd) - { - switch (Type) - { - case IMAGE_REL_BASED_ABSOLUTE: - break; - - case IMAGE_REL_BASED_HIGH: - *ShortPtr += HIWORD(Delta); - break; - - case IMAGE_REL_BASED_LOW: - *ShortPtr += LOWORD(Delta); - break; - - case IMAGE_REL_BASED_HIGHLOW: - LongPtr = (PULONG)ShortPtr; - *LongPtr += Delta; - break; - - case IMAGE_REL_BASED_HIGHADJ: - case IMAGE_REL_BASED_MIPS_JMPADDR: - default: - DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); - DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset); - return STATUS_UNSUCCESSFUL; - } - } - TypeOffset++; - } - RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock); - } - - return STATUS_SUCCESS; -} #ifndef PATH_MAX #define PATH_MAX 260 #endif From a9bca34078d2261882e694f6baa9858aa2f5ce80 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 10 Sep 2006 09:31:44 +0000 Subject: [PATCH 104/488] Dmitry Philippov: Fix GCC4 warning svn path=/trunk/; revision=24018 --- rosapps/packmgr/gui/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rosapps/packmgr/gui/main.c b/rosapps/packmgr/gui/main.c index 6398ca30117..e97299ebcb6 100644 --- a/rosapps/packmgr/gui/main.c +++ b/rosapps/packmgr/gui/main.c @@ -320,7 +320,7 @@ LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { // mark the one as selected SendMessage (hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)item); - (BOOL)TreeView_EnsureVisible (hTree, item); + (void)TreeView_EnsureVisible (hTree, item); } // create the context menu From 65df8c2badf0c9ebd4f2eca359f88340c726bcf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 10 Sep 2006 10:26:58 +0000 Subject: [PATCH 105/488] Revert part of r23972. Now we can boot again (+ fix a little bug) svn path=/trunk/; revision=24019 --- reactos/ntoskrnl/ldr/loader.c | 12 +++--------- reactos/ntoskrnl/mm/section.c | 20 ++++---------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 0c320666754..19324d1f9a5 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -634,10 +634,7 @@ LdrLookupPageProtection ( for (Idx = 0; Idx < PEFileHeader->NumberOfSections && (!Write || !Execute); Idx++) { Characteristics = PESectionHeaders[Idx].Characteristics; - // - // This field is RESERVED and not respected by Windows - // - //if (!(Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + if (!(Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { Length = max(PESectionHeaders[Idx].Misc.VirtualSize, PESectionHeaders[Idx].SizeOfRawData); BaseAddress = PESectionHeaders[Idx].VirtualAddress + (char*)DriverBase; @@ -734,10 +731,7 @@ LdrPEProcessModule( DriverSize = 0; for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++) { - // - // This field is RESERVED and not respected by Windows - // - //if (!(PESectionHeaders[Idx].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + if (!(PESectionHeaders[Idx].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { CurrentSize = PESectionHeaders[Idx].VirtualAddress + PESectionHeaders[Idx].Misc.VirtualSize; DriverSize = max(DriverSize, CurrentSize); @@ -1154,7 +1148,7 @@ LdrPEGetOrLoadModule ( NameString.MaximumLength = NameString.Length = PathLength + DriverName.Length; /* NULL-terminate */ - NameString.MaximumLength++; + NameString.MaximumLength += sizeof(WCHAR); NameBuffer[NameString.Length / sizeof(WCHAR)] = 0; Status = LdrLoadModule(&NameString, ImportedModule); diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 67cf0bb0a6e..d6e5dbdd4b2 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -3994,10 +3994,7 @@ MmUnmapViewOfSection(PEPROCESS Process, * and calculate the image base address */ for (i = 0; i < NrSegments; i++) { - // - // This field is RESERVED and not respected by Windows - // - //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { if (Segment == &SectionSegments[i]) { @@ -4013,10 +4010,7 @@ MmUnmapViewOfSection(PEPROCESS Process, for (i = 0; i < NrSegments; i++) { - // - // This field is RESERVED and not respected by Windows - // - //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { PVOID SBaseAddress = (PVOID) ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress); @@ -4482,10 +4476,7 @@ MmMapViewOfSection(IN PVOID SectionObject, ImageSize = 0; for (i = 0; i < NrSegments; i++) { - // - // This field is RESERVED and not respected by Windows - // - //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { ULONG_PTR MaxExtent; MaxExtent = (ULONG_PTR)SectionSegments[i].VirtualAddress + @@ -4515,10 +4506,7 @@ MmMapViewOfSection(IN PVOID SectionObject, for (i = 0; i < NrSegments; i++) { - // - // This field is RESERVED and not respected by Windows - // - //if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { PVOID SBaseAddress = (PVOID) ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress); From b52f7b069b82b8bc95d19e3de3e8029f38768fae Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 10 Sep 2006 13:33:30 +0000 Subject: [PATCH 106/488] - Implement enable/disable of protection for PE sections in ntdll - Finally get rid of duplicated relocation code in ntdll by using the relocate function from RTL and enable/disable protection - Some improvements added to RTL's relocation function, it's split up into two functions now svn path=/trunk/; revision=24020 --- reactos/dll/ntdll/ldr/utils.c | 208 ++++++++++++++++------------------ reactos/lib/rtl/image.c | 138 ++++++++++++---------- 2 files changed, 177 insertions(+), 169 deletions(-) diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index f7a94cd4d07..5fbb7d9aca0 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -1198,126 +1198,89 @@ LdrGetExportByName(PVOID BaseAddress, return (PVOID)NULL; } - -/********************************************************************** - * NAME LOCAL - * LdrPerformRelocations - * - * DESCRIPTION - * Relocate a DLL's memory image. - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - * NOTE - * - */ -static NTSTATUS -LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, - PVOID ImageBase) +/*++ +* @name LdrpSetProtection +* +* Local routine, used to set or reset pages protection. +* Used during PE relocation process. +* +* @param BaseAddress +* Base address of the image. +* +* @param Protection +* FALSE to disable protection, TRUE to enable it +* +* @return Usual NTSTATUS. +* +* @remarks None. +* +*--*/ +NTSTATUS +LdrpSetProtection(IN PVOID BaseAddress, + IN BOOLEAN Protection) { - PIMAGE_DATA_DIRECTORY RelocationDDir; - PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; - ULONG Count, ProtectSize, OldProtect, OldProtect2; - PVOID Page, ProtectPage, ProtectPage2; - PUSHORT TypeOffset; - ULONG_PTR Delta; - NTSTATUS Status; + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_SECTION_HEADER SectionHeader; + ULONG i; + PVOID Address; + SIZE_T Size; + NTSTATUS Status; + ULONG NewAccess, OldAccess; - if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) + NtHeaders = RtlImageNtHeader(BaseAddress); + + /* Ensure image is valid */ + if (NtHeaders == NULL) + return STATUS_INVALID_IMAGE_FORMAT; + + /* Get the first section header */ + SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); + + /* Loop through every section */ + for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++, SectionHeader++) { - return STATUS_UNSUCCESSFUL; - } + /* If section has no data - just skip to the next section */ + if (SectionHeader->SizeOfRawData == 0) + continue; - RelocationDDir = - &NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; - - if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0) - { - return STATUS_SUCCESS; - } - - ProtectSize = PAGE_SIZE; - Delta = (ULONG_PTR)ImageBase - NTHeaders->OptionalHeader.ImageBase; - RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase + - RelocationDDir->VirtualAddress); - RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase + - RelocationDDir->VirtualAddress + RelocationDDir->Size); - - while (RelocationDir < RelocationEnd && - RelocationDir->SizeOfBlock > 0) - { - Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / - sizeof(USHORT); - Page = (PVOID)((ULONG_PTR)ImageBase + (ULONG_PTR)RelocationDir->VirtualAddress); - TypeOffset = (PUSHORT)(RelocationDir + 1); - - /* Unprotect the page(s) we're about to relocate. */ - ProtectPage = Page; - Status = NtProtectVirtualMemory(NtCurrentProcess(), - &ProtectPage, - &ProtectSize, - PAGE_READWRITE, - &OldProtect); - if (!NT_SUCCESS(Status)) + /* We need to act only if section isn't RW */ + if (!(SectionHeader->Characteristics & IMAGE_SCN_MEM_WRITE)) { - DPRINT1("Failed to unprotect relocation target.\n"); - return Status; - } - - if (RelocationDir->VirtualAddress + PAGE_SIZE < - NTHeaders->OptionalHeader.SizeOfImage) - { - ProtectPage2 = (PVOID)((ULONG_PTR)ProtectPage + PAGE_SIZE); - Status = NtProtectVirtualMemory(NtCurrentProcess(), - &ProtectPage2, - &ProtectSize, - PAGE_READWRITE, - &OldProtect2); - if (!NT_SUCCESS(Status)) + if (Protection) { - DPRINT1("Failed to unprotect relocation target (2).\n"); - NtProtectVirtualMemory(NtCurrentProcess(), - &ProtectPage, - &ProtectSize, - OldProtect, - &OldProtect); - return Status; + /* Check if the section was also executable, then we should + give it PAGE_EXECUTE, otherwise just PAGE_READONLY */ + NewAccess = (SectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) ? PAGE_EXECUTE : PAGE_READONLY; + + /* Also check caching */ + NewAccess |= (SectionHeader->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) ? PAGE_NOCACHE : 0; + } + else + { + /* Set access to RW */ + NewAccess = PAGE_READWRITE; } - } - else - { - ProtectPage2 = NULL; - } - RelocationDir = LdrProcessRelocationBlock((ULONG_PTR)Page, - Count, - TypeOffset, - Delta); - if (RelocationDir == NULL) - return STATUS_UNSUCCESSFUL; + /* Get the address and size of the section, and set protectin accordingly */ + Address = (PVOID)((ULONG_PTR)BaseAddress + SectionHeader->VirtualAddress); + Size = SectionHeader->SizeOfRawData; - /* Restore old page protection. */ - NtProtectVirtualMemory(NtCurrentProcess(), - &ProtectPage, - &ProtectSize, - OldProtect, - &OldProtect); + Status = NtProtectVirtualMemory(NtCurrentProcess(), + &Address, + &Size, + NewAccess, + &OldAccess); - if (ProtectPage2 != NULL) - { - NtProtectVirtualMemory(NtCurrentProcess(), - &ProtectPage2, - &ProtectSize, - OldProtect2, - &OldProtect2); + if (!NT_SUCCESS(Status)) + return Status; } } - return STATUS_SUCCESS; + /* Instruction cache should be flushed if we enabled protection */ + if (Protection) + NtFlushInstructionCache(NtCurrentProcess(), NULL, 0); + + return STATUS_SUCCESS; } static NTSTATUS @@ -1898,12 +1861,32 @@ PEPFUNC LdrPEStartup (PVOID ImageBase, if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase) { DPRINT("LDR: Performing relocations\n"); - Status = LdrPerformRelocations(NTHeaders, ImageBase); + + /* Remove protection */ + Status = LdrpSetProtection(ImageBase, FALSE); if (!NT_SUCCESS(Status)) { - DPRINT1("LdrPerformRelocations() failed\n"); + DPRINT1("LdrpSetProtection() failed with Status=0x%08X\n", Status); return NULL; } + + /* Relocate */ + Status = LdrRelocateImageWithBias(ImageBase, 0, "", STATUS_SUCCESS, + STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LdrRelocateImageWithBias() failed with Status=0x%08X\n", Status); + return NULL; + } + + /* Set protection back */ + Status = LdrpSetProtection(ImageBase, TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("LdrpSetProtection() failed with Status=0x%08X\n", Status); + return NULL; + } + } if (Module != NULL) @@ -2078,10 +2061,13 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL, { DPRINT1("Relocating (%lx -> %p) %wZ\n", NtHeaders->OptionalHeader.ImageBase, ImageBase, &FullDosName); - Status = LdrPerformRelocations(NtHeaders, ImageBase); + + Status = LdrRelocateImageWithBias(ImageBase, 0, "", STATUS_SUCCESS, + STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT); + if (!NT_SUCCESS(Status)) { - DPRINT1("LdrPerformRelocations() failed\n"); + DPRINT1("LdrRelocateImageWithBias() failed\n"); NtUnmapViewOfSection (NtCurrentProcess (), ImageBase); NtClose (SectionHandle); RtlFreeUnicodeString(&FullDosName); diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index 8b87b39672b..a37b3c728bf 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -3,8 +3,10 @@ * FILE: lib/rtl/image.c * PURPOSE: Image handling functions * Relocate functions were previously located in - * ntoskrnl/ldr/loader.c - * PROGRAMMER: Eric Kohl + original authors from loader.c file + * ntoskrnl/ldr/loader.c and + * dll/ntdll/ldr/utils.c files + * PROGRAMMER: Eric Kohl + original authors from loader.c and utils.c file + * Aleksey Bragin */ /* INCLUDES *****************************************************************/ @@ -149,6 +151,70 @@ RtlImageRvaToVa ( (ULONG_PTR)Section->VirtualAddress); } +PIMAGE_BASE_RELOCATION +LdrProcessRelocationBlockLongLong( + IN ULONG_PTR Address, + IN ULONG Count, + IN PUSHORT TypeOffset, + IN LONGLONG Delta + ) +{ + SHORT Offset; + USHORT Type; + USHORT i; + PUSHORT ShortPtr; + PULONG LongPtr; + + for (i = 0; i < Count; i++) + { + Offset = *TypeOffset & 0xFFF; + Type = *TypeOffset >> 12; + ShortPtr = (PUSHORT)(RVA(Address, Offset)); + + /* + * Don't relocate within the relocation section itself. + * GCC/LD generates sometimes relocation records for the relocation section. + * This is a bug in GCC/LD. + * Fix for it disabled, since it was only in ntoskrnl and not in ntdll + */ + /* + if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir || + (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd) + {*/ + switch (Type) + { + /* case IMAGE_REL_BASED_SECTION : */ + /* case IMAGE_REL_BASED_REL32 : */ + case IMAGE_REL_BASED_ABSOLUTE: + break; + + case IMAGE_REL_BASED_HIGH: + *ShortPtr += HIWORD(Delta); + break; + + case IMAGE_REL_BASED_LOW: + *ShortPtr += LOWORD(Delta); + break; + + case IMAGE_REL_BASED_HIGHLOW: + LongPtr = (PULONG)RVA(Address, Offset); + *LongPtr += Delta; + break; + + case IMAGE_REL_BASED_HIGHADJ: + case IMAGE_REL_BASED_MIPS_JMPADDR: + default: + DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); + DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset); + return (PIMAGE_BASE_RELOCATION)NULL; + } + + TypeOffset++; + } + + return (PIMAGE_BASE_RELOCATION)TypeOffset; +} + ULONG NTAPI LdrRelocateImageWithBias( @@ -163,14 +229,10 @@ LdrRelocateImageWithBias( PIMAGE_NT_HEADERS NtHeaders; PIMAGE_DATA_DIRECTORY RelocationDDir; PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; - ULONG Count, i; - PVOID Address;//, MaxAddress; + ULONG Count; + ULONG_PTR Address; PUSHORT TypeOffset; - ULONG_PTR Delta; - SHORT Offset; - USHORT Type; - PUSHORT ShortPtr; - PULONG LongPtr; + LONGLONG Delta; NtHeaders = RtlImageNtHeader(BaseAddress); @@ -192,64 +254,24 @@ LdrRelocateImageWithBias( Delta = (ULONG_PTR)BaseAddress - NtHeaders->OptionalHeader.ImageBase + AdditionalBias; RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + RelocationDDir->VirtualAddress); RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size); - //MaxAddress = RVA(BaseAddress, DriverSize); while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) { Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - Address = RVA(BaseAddress, RelocationDir->VirtualAddress); + Address = (ULONG_PTR)RVA(BaseAddress, RelocationDir->VirtualAddress); TypeOffset = (PUSHORT)(RelocationDir + 1); - for (i = 0; i < Count; i++) + RelocationDir = LdrProcessRelocationBlockLongLong(Address, + Count, + TypeOffset, + Delta); + + if (RelocationDir == NULL) { - Offset = *TypeOffset & 0xFFF; - Type = *TypeOffset >> 12; - ShortPtr = (PUSHORT)(RVA(Address, Offset)); - - /* Don't relocate after the end of the loaded driver */ - /*if ((PVOID)ShortPtr >= MaxAddress) - { - break; - }*/ - - /* - * Don't relocate within the relocation section itself. - * GCC/LD generates sometimes relocation records for the relocation section. - * This is a bug in GCC/LD. - */ - if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir || - (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd) - { - switch (Type) - { - case IMAGE_REL_BASED_ABSOLUTE: - break; - - case IMAGE_REL_BASED_HIGH: - *ShortPtr += HIWORD(Delta); - break; - - case IMAGE_REL_BASED_LOW: - *ShortPtr += LOWORD(Delta); - break; - - case IMAGE_REL_BASED_HIGHLOW: - LongPtr = (PULONG)ShortPtr; - *LongPtr += Delta; - break; - - case IMAGE_REL_BASED_HIGHADJ: - case IMAGE_REL_BASED_MIPS_JMPADDR: - default: - DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); - DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset); - return Invalid; - } - } - TypeOffset++; + DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n"); + return Invalid; } - RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock); } return Success; From 098292d473a34a4fda7944e48e44cf4af97b180a Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 10 Sep 2006 14:23:13 +0000 Subject: [PATCH 107/488] These DPRINT1s are ONLY for Magnus' debuggin session. Correcting his mistake of commiting them to the tree. (taskmgr.exe should work again) svn path=/trunk/; revision=24021 --- reactos/subsystems/win32/win32k/objects/bitmaps.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/bitmaps.c b/reactos/subsystems/win32/win32k/objects/bitmaps.c index 016271a02f3..f2cd1180f35 100644 --- a/reactos/subsystems/win32/win32k/objects/bitmaps.c +++ b/reactos/subsystems/win32/win32k/objects/bitmaps.c @@ -1069,25 +1069,25 @@ NtGdiSetPixel( COLORREF Color) { - DPRINT1("0 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); + DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); if (((Color>>24) & 0xff)<0x10) { Color = ((Color>>16) & 0x0000ff) | ((Color<<16) & 0xff0000) | (Color & 0x00ff00); } - DPRINT1("0 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); + DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); if (NtGdiSetPixelV(hDC,X,Y,Color)) { Color = NtGdiGetPixel(hDC,X,Y); - DPRINT1("1 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); + DPRINT("1 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); return Color; } Color = ((COLORREF) -1); - DPRINT1("2 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); + DPRINT("2 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); return Color; } From d2cb3868b7543bfd95b8ab624ee68377bb314317 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 14:43:12 +0000 Subject: [PATCH 108/488] - Add some definitions to ketypes.h - Fix multiple bugs in KTHREAD/KPROCESS where signed char values were marked as unsigned (and define SCHAR in ntdef.h) - Change prototype of KiSwapThread for future compatibility. - Fix prototype of KeSetIdealProcessorThread. - Add KiAcquireDispatcherLock, KiReleaseDispatcherLock, KiAcquireDispatcherLockAtDpcLevel, KiReleaseDispatcherLockFromDpcLevel to ke_x.h for future use. - Add KiInsertDeferredReadyList, KiRescheduleThread, KiSetThreadSwapBusy, KiRundownThread, KiCheckDeferredReadyList for future use. - Add KiAcquirePrcbLock, KiReleasePrcbLock, KiAcquireThreadLock, KiReleaseThreadLock for future use. - Add KxQueueReadyThread, KiSelectReadyThread for future use. - Add KiComputeNewPriority for future use. svn path=/trunk/; revision=24022 --- reactos/include/ndk/ketypes.h | 28 +- reactos/include/psdk/ntdef.h | 2 + reactos/ntoskrnl/include/internal/ke.h | 93 +++-- reactos/ntoskrnl/include/internal/ke_x.h | 461 +++++++++++++++++++++++ reactos/ntoskrnl/ke/gate.c | 2 +- reactos/ntoskrnl/ke/kthread.c | 10 +- reactos/ntoskrnl/ke/queue.c | 2 +- reactos/ntoskrnl/ke/wait.c | 6 +- 8 files changed, 553 insertions(+), 51 deletions(-) diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index 691b88a2e4f..d480a6382ee 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -59,6 +59,13 @@ Author: // #define KI_USER_SHARED_DATA_PHYSICAL 0x41000 +// +// Quantum values and decrements +// +#define MAX_QUANTUM 0x7F +#define WAIT_QUANTUM_DECREMENT 1 +#define CLOCK_QUANTUM_DECREMENT 3 + // // Kernel Feature Bits // @@ -679,13 +686,13 @@ typedef struct _KTHREAD volatile UCHAR NextProcessor; volatile UCHAR DeferredProcessor; UCHAR AdjustReason; - UCHAR AdjustIncrement; + SCHAR AdjustIncrement; KSPIN_LOCK ApcQueueLock; ULONG ContextSwitches; volatile UCHAR State; UCHAR NpxState; UCHAR WaitIrql; - UCHAR WaitMode; + SCHAR WaitMode; LONG WaitStatus; union { @@ -695,7 +702,7 @@ typedef struct _KTHREAD UCHAR Alertable; UCHAR WaitNext; UCHAR WaitReason; - UCHAR Priority; + SCHAR Priority; UCHAR EnableStackSwap; volatile UCHAR SwapBusy; UCHAR Alerted[2]; @@ -752,7 +759,7 @@ typedef struct _KTHREAD struct { UCHAR WaitBlockFill1[47]; - UCHAR PreviousMode; + SCHAR PreviousMode; }; struct { @@ -810,10 +817,10 @@ typedef struct _KTHREAD union { UCHAR SavedApcStateFill[23]; - CHAR FreezeCount; + SCHAR FreezeCount; }; }; - CHAR SuspendCount; + SCHAR SuspendCount; UCHAR UserIdealProcessor; #if (NTDDI_VERSION >= NTDDI_LONGHORN) union @@ -838,7 +845,7 @@ typedef struct _KTHREAD struct { UCHAR SuspendApcFill0[1]; - CHAR Quantum; + SCHAR Quantum; }; struct { @@ -888,6 +895,9 @@ typedef struct _KTHREAD } KTHREAD; #include +#define ASSERT_THREAD(object) \ + ASSERT((((object)->Header.Type & KOBJECT_TYPE_MASK) == ThreadObject)) + // // Kernel Process (KPROCESS) // @@ -923,8 +933,8 @@ typedef struct _KPROCESS }; ULONG ProcessFlags; }; - CHAR BasePriority; - CHAR QuantumReset; + SCHAR BasePriority; + SCHAR QuantumReset; UCHAR State; UCHAR ThreadSeed; UCHAR PowerState; diff --git a/reactos/include/psdk/ntdef.h b/reactos/include/psdk/ntdef.h index c2dfa45e510..8dcc53cf6d0 100644 --- a/reactos/include/psdk/ntdef.h +++ b/reactos/include/psdk/ntdef.h @@ -64,6 +64,8 @@ typedef STRING CANSI_STRING; typedef PSTRING PCANSI_STRING; typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; typedef CONST CHAR *LPCCH, *PCCH; +typedef signed char SCHAR; +typedef SCHAR *PSCHAR; typedef enum _SECTION_INHERIT { ViewShare = 1, ViewUnmap = 2 diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 1559097c27d..b57dfcb43ba 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -132,28 +132,8 @@ extern VOID KiTrap2(VOID); /* MACROS *************************************************************************/ -/* - * On UP machines, we don't actually have a spinlock, we merely raise - * IRQL to DPC level. - */ -#ifdef CONFIG_SMP -#define KeInitializeDispatcher() KeInitializeSpinLock(&DispatcherDatabaseLock); -#define KeAcquireDispatcherDatabaseLock() KfAcquireSpinLock(&DispatcherDatabaseLock); -#define KeAcquireDispatcherDatabaseLockAtDpcLevel() \ - KeAcquireSpinLockAtDpcLevel (&DispatcherDatabaseLock); -#define KeReleaseDispatcherDatabaseLockFromDpcLevel() \ - KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock); -#define KeReleaseDispatcherDatabaseLock(OldIrql) \ - KiExitDispatcher(OldIrql); -#else -#define KeInitializeDispatcher() -#define KeAcquireDispatcherDatabaseLock() KeRaiseIrqlToDpcLevel(); -#define KeReleaseDispatcherDatabaseLock(OldIrql) KiExitDispatcher(OldIrql); -#define KeAcquireDispatcherDatabaseLockAtDpcLevel() -#define KeReleaseDispatcherDatabaseLockFromDpcLevel() -#endif - #define AFFINITY_MASK(Id) KiMask32Array[Id] +#define PRIORITY_MASK(Id) KiMask32Array[Id] /* The following macro initializes a dispatcher object's header */ #define KeInitializeDispatcherHeader(Header, t, s, State) \ @@ -166,8 +146,6 @@ extern VOID KiTrap2(VOID); InitializeListHead(&((Header)->WaitListHead)); \ } -extern KSPIN_LOCK DispatcherDatabaseLock; - #define KeEnterCriticalRegion() \ { \ PKTHREAD _Thread = KeGetCurrentThread(); \ @@ -209,9 +187,11 @@ extern KSPIN_LOCK DispatcherDatabaseLock; /* INTERNAL KERNEL FUNCTIONS ************************************************/ -/* threadsch.c ********************************************************************/ - -/* Thread Scheduler Functions */ +#define KeInitializeDispatcher() +#define KeAcquireDispatcherDatabaseLock() KeRaiseIrqlToDpcLevel(); +#define KeReleaseDispatcherDatabaseLock(OldIrql) KiExitDispatcher(OldIrql); +#define KeAcquireDispatcherDatabaseLockAtDpcLevel() +#define KeReleaseDispatcherDatabaseLockFromDpcLevel() /* Readies a Thread for Execution. */ BOOLEAN @@ -225,9 +205,10 @@ KiDispatchThread(ULONG NewThreadStatus); /* Finds a new thread to run */ NTSTATUS -NTAPI +FASTCALL KiSwapThread( - VOID + IN PKTHREAD Thread, + IN PKPRCB Prcb ); VOID @@ -238,7 +219,7 @@ NTSTATUS NTAPI KeSuspendThread(PKTHREAD Thread); -NTSTATUS +BOOLEAN FASTCALL KiSwapContext( IN PKTHREAD CurrentThread, @@ -253,6 +234,23 @@ VOID FASTCALL KiExitDispatcher(KIRQL OldIrql); +VOID +NTAPI +KiDeferredReadyThread(IN PKTHREAD Thread); + +KAFFINITY +NTAPI +KiSetAffinityThread( + IN PKTHREAD Thread, + IN KAFFINITY Affinity +); + +PKTHREAD +NTAPI +KiSelectNextThread( + IN PKPRCB Prcb +); + /* gmutex.c ********************************************************************/ VOID @@ -438,6 +436,30 @@ NTSTATUS NTAPI KeReleaseThread(PKTHREAD Thread); +VOID +NTAPI +KiSuspendRundown( + IN PKAPC Apc +); + +VOID +NTAPI +KiSuspendNop( + IN PKAPC Apc, + IN PKNORMAL_ROUTINE *NormalRoutine, + IN PVOID *NormalContext, + IN PVOID *SystemArgument1, + IN PVOID *SystemArgument2 +); + +VOID +NTAPI +KiSuspendThread( + IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 +); + LONG NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread); @@ -445,9 +467,9 @@ KeQueryBasePriorityThread(IN PKTHREAD Thread); VOID NTAPI KiSetPriorityThread( - PKTHREAD Thread, - KPRIORITY Priority, - PBOOLEAN Released + IN PKTHREAD Thread, + IN KPRIORITY Priority, + IN PBOOLEAN Released // hack ); BOOLEAN @@ -825,6 +847,13 @@ KiInitSystem( VOID ); +VOID +FASTCALL +KiInsertQueueApc( + IN PKAPC Apc, + IN KPRIORITY PriorityBoost +); + #include "ke_x.h" #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */ diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 4199406833f..214fb70d568 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -248,3 +248,464 @@ KiRecalculateDueTime(IN PLARGE_INTEGER OriginalDueTime, break; \ } \ } + +// +// Thread Scheduling Routines +// +#ifndef _CONFIG_SMP +KIRQL +FORCEINLINE +KiAcquireDispatcherLock(VOID) +{ + /* Raise to DPC level */ + return KeRaiseIrqlToDpcLevel(); +} + +VOID +FORCEINLINE +KiReleaseDispatcherLock(IN KIRQL OldIrql) +{ + /* Just exit the dispatcher */ + KiExitDispatcher(OldIrql); +} + +VOID +FORCEINLINE +KiAcquireDispatcherLockAtDpcLevel(VOID) +{ + /* This is a no-op at DPC Level for UP systems */ + return; +} + +VOID +FORCEINLINE +KiReleaseDispatcherLockFromDpcLevel(VOID) +{ + /* This is a no-op at DPC Level for UP systems */ + return; +} + +// +// This routine makes the thread deferred ready on the boot CPU. +// +FORCEINLINE +VOID +KiInsertDeferredReadyList(IN PKTHREAD Thread) +{ + /* Set the thread to deferred state and boot CPU */ + Thread->State = DeferredReady; + Thread->DeferredProcessor = 0; + + /* Make the thread ready immediately */ + KiDeferredReadyThread(Thread); +} + +FORCEINLINE +VOID +KiRescheduleThread(IN BOOLEAN NewThread, + IN ULONG Cpu) +{ + /* This is meaningless on UP systems */ + UNREFERENCED_PARAMETER(NewThread); + UNREFERENCED_PARAMETER(Cpu); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiSetThreadSwapBusy(IN PKTHREAD Thread) +{ + UNREFERENCED_PARAMETER(Thread); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiAcquirePrcbLock(IN PKPRCB Prcb) +{ + UNREFERENCED_PARAMETER(Prcb); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiReleasePrcbLock(IN PKPRCB Prcb) +{ + UNREFERENCED_PARAMETER(Prcb); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiAcquireThreadLock(IN PKTHREAD Thread) +{ + UNREFERENCED_PARAMETER(Thread); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiReleaseThreadLock(IN PKTHREAD Thread) +{ + UNREFERENCED_PARAMETER(Thread); +} + +FORCEINLINE +VOID +KiCheckDeferredReadyList(IN PKPRCB Prcb) +{ + /* There are no deferred ready lists on UP systems */ + UNREFERENCED_PARAMETER(Prcb); +} + +FORCEINLINE +VOID +KiRundownThread(IN PKTHREAD Thread) +{ + /* Check if this is the NPX Thread */ + if (KeGetCurrentPrcb()->NpxThread == Thread) + { + /* Clear it */ + KeGetCurrentPrcb()->NpxThread = NULL; +#ifdef __GNUC__ + __asm__("fninit\n\t"); +#else + __asm fninit; +#endif + } +} + +#else + +KIRQL +FORCEINLINE +KiAcquireDispatcherLock(VOID) +{ + /* Raise to synchronization level and acquire the dispatcher lock */ + return KeAcquireQueuedSpinLockRaiseToSynch(LockQueueDispatcherLock); +} + +VOID +FORCEINLINE +KiReleaseDispatcherLock(IN KIRQL OldIrql) +{ + /* First release the lock */ + KeReleaseQueuedSpinLockFromDpcLevel(&KeGetCurrentPrcb()-> + LockQueue[LockQueueDispatcherLock]); + + /* Then exit the dispatcher */ + KiExitDispatcher(OldIrql); +} + +// +// This routine inserts a thread into the deferred ready list of the given CPU +// +FORCEINLINE +VOID +KiInsertDeferredReadyList(IN PKTHREAD Thread) +{ + PKPRCB Prcb = KeGetCurrentPrcb(); + + /* Set the thread to deferred state and CPU */ + Thread->State = DeferredReady; + Thread->DeferredProcessor = Prcb->Number; + + /* Add it on the list */ + PushEntryList(&Prcb->DeferredReadyListHead, &Thread->SwapListEntry); +} + +FORCEINLINE +VOID +KiRescheduleThread(IN BOOLEAN NewThread, + IN ULONG Cpu) +{ + /* Check if a new thread needs to be scheduled on a different CPU */ + if ((NewThread) && !(KeGetPcr()->Number == Cpu)) + { + /* Send an IPI to request delivery */ + KiIpiSendRequest(AFFINITY_MASK(Cpu), IPI_DPC); + } +} + +// +// This routine sets the current thread in a swap busy state, which ensure that +// nobody else tries to swap it concurrently. +// +FORCEINLINE +VOID +KiSetThreadSwapBusy(IN PKTHREAD Thread) +{ + /* Make sure nobody already set it */ + ASSERT(Thread->SwapBusy == FALSE); + + /* Set it ourselves */ + Thread->SwapBusy = TRUE; +} + +// +// This routine acquires the PRCB lock so that only one caller can touch +// volatile PRCB data. +// +// Since this is a simple optimized spin-lock, it must be be only acquired +// at dispatcher level or higher! +// +FORCEINLINE +VOID +KiAcquirePrcbLock(IN PKPRCB Prcb) +{ + /* Make sure we're at a safe level to touch the PRCB lock */ + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); + + /* Start acquire loop */ + for (;;) + { + /* Acquire the lock and break out if we acquired it first */ + if (!InterlockedExchange(&Prcb->PrcbLock, 1)) break; + + /* Loop until the other CPU releases it */ + do + { + /* Let the CPU know that this is a loop */ + YieldProcessor(); + } while (Prcb->PrcbLock); + } +} + +// +// This routine releases the PRCB lock so that other callers can touch +// volatile PRCB data. +// +// Since this is a simple optimized spin-lock, it must be be only acquired +// at dispatcher level or higher! +// +FORCEINLINE +VOID +KiReleasePrcbLock(IN PKPRCB Prcb) +{ + /* Make sure it's acquired! */ + ASSERT(Prcb->PrcbLock != 0); + + /* Release it */ + InterlockedAnd(&Prcb->PrcbLock, 0); +} + +// +// This routine acquires the thread lock so that only one caller can touch +// volatile thread data. +// +// Since this is a simple optimized spin-lock, it must be be only acquired +// at dispatcher level or higher! +// +FORCEINLINE +VOID +KiAcquireThreadLock(IN PKTHREAD Thread) +{ + /* Make sure we're at a safe level to touch the thread lock */ + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); + + /* Start acquire loop */ + for (;;) + { + /* Acquire the lock and break out if we acquired it first */ + if (!InterlockedExchange(&Thread->ThreadLock, 1)) break; + + /* Loop until the other CPU releases it */ + do + { + /* Let the CPU know that this is a loop */ + YieldProcessor(); + } while (Thread->ThreadLock); + } +} + +// +// This routine releases the thread lock so that other callers can touch +// volatile thread data. +// +// Since this is a simple optimized spin-lock, it must be be only acquired +// at dispatcher level or higher! +// +FORCEINLINE +VOID +KiReleaseThreadLock(IN PKTHREAD Thread) +{ + /* Release it */ + InterlockedAnd(&Thread->ThreadLock, 0); +} + +FORCEINLINE +VOID +KiCheckDeferredReadyList(IN PKPRCB Prcb) +{ + /* Scan the deferred ready lists if required */ + if (Prcb->DeferredReadyListHead.Next) KiProcessDeferredReadyList(Prcb); +} + +#endif + +// +// This routine queues a thread that is ready on the PRCB's ready lists. +// If this thread cannot currently run on this CPU, then the thread is +// added to the deferred ready list instead. +// +// This routine must be entered with the PRCB lock held and it will exit +// with the PRCB lock released! +// +FORCEINLINE +VOID +KxQueueReadyThread(IN PKTHREAD Thread, + IN PKPRCB Prcb) +{ + BOOLEAN Preempted; + KPRIORITY Priority; + + /* Sanity checks */ + ASSERT(Prcb == KeGetCurrentPrcb()); + ASSERT(Thread->State == Running); + ASSERT(Thread->NextProcessor == Prcb->Number); + + /* Check if this thread is allowed to run in this CPU */ +#ifdef _CONFIG_SMP + if ((Thread->Affinity) & (Prcb->SetMember)) +#else + if (TRUE) +#endif + { + /* Set thread ready for execution */ + Thread->State = Ready; + + /* Save current priority and if someone had pre-empted it */ + Priority = Thread->Priority; + Preempted = Thread->Preempted; + + /* We're not pre-empting now, and set the wait time */ + Thread->Preempted = FALSE; + Thread->WaitTime = KeTickCount.LowPart; + + /* Sanity check */ + ASSERT((Priority >= 0) && (Priority <= HIGH_PRIORITY)); + + /* Insert this thread in the appropriate order */ + Preempted ? InsertHeadList(&Prcb->DispatcherReadyListHead[Priority], + &Thread->WaitListEntry) : + InsertTailList(&Prcb->DispatcherReadyListHead[Priority], + &Thread->WaitListEntry); + + /* Update the ready summary */ + Prcb->ReadySummary |= PRIORITY_MASK(Priority); + + /* Sanity check */ + ASSERT(Priority == Thread->Priority); + + /* Release the PRCB lock */ + KiReleasePrcbLock(Prcb); + } + else + { + /* Otherwise, prepare this thread to be deferred */ + Thread->State = DeferredReady; + Thread->DeferredProcessor = Prcb->Number; + + /* Release the lock and defer scheduling */ + KiReleasePrcbLock(Prcb); + KiDeferredReadyThread(Thread); + } +} + +// +// This routine scans for an appropriate ready thread to select at the +// given priority and for the given CPU. +// +FORCEINLINE +PKTHREAD +KiSelectReadyThread(IN KPRIORITY Priority, + IN PKPRCB Prcb) +{ + LONG PriorityMask, PrioritySet, HighPriority; + PLIST_ENTRY ListEntry; + PKTHREAD Thread; + + /* Save the current mask and get the priority set for the CPU */ + PriorityMask = Priority; + PrioritySet = Prcb->ReadySummary >> (UCHAR)Priority; + if (!PrioritySet) return NULL; + + /* Get the highest priority possible */ + BitScanReverse(&HighPriority, PrioritySet); + ASSERT((PrioritySet & PRIORITY_MASK(HighPriority)) != 0); + HighPriority += PriorityMask; + + /* Make sure the list isn't at highest priority */ + ASSERT(IsListEmpty(&Prcb->DispatcherReadyListHead[HighPriority]) == FALSE); + + /* Get the first thread on the list */ + ListEntry = &Prcb->DispatcherReadyListHead[HighPriority]; + Thread = CONTAINING_RECORD(ListEntry, KTHREAD, WaitListEntry); + + /* Make sure this thread is here for a reason */ + ASSERT(HighPriority == Thread->Priority); + ASSERT(Thread->Affinity & AFFINITY_MASK(Prcb->Number)); + ASSERT(Thread->NextProcessor == Prcb->Number); + + /* Remove it from the list */ + RemoveEntryList(&Thread->WaitListEntry); + if (IsListEmpty(&Thread->WaitListEntry)) + { + /* The list is empty now, reset the ready summary */ + Prcb->ReadySummary ^= PRIORITY_MASK(HighPriority); + } + + /* Sanity check and return the thread */ + ASSERT((Thread == NULL) || + (Thread->BasePriority == 0) || + (Thread->Priority != 0)); + return Thread; +} + +// +// This routine computes the new priority for a thread. It is only valid for +// threads with priorities in the dynamic priority range. +// +SCHAR +FORCEINLINE +KiComputeNewPriority(IN PKTHREAD Thread) +{ + SCHAR Priority; + + /* Priority sanity checks */ + ASSERT((Thread->PriorityDecrement >= 0) && + (Thread->PriorityDecrement <= Thread->Priority)); + ASSERT((Thread->Priority < LOW_REALTIME_PRIORITY) ? + TRUE : (Thread->PriorityDecrement == 0)); + + /* Get the current priority */ + Priority = Thread->Priority; + if (Priority < LOW_REALTIME_PRIORITY) + { + /* Set the New Priority and add the Priority Decrement */ + Priority += (Priority - Thread->PriorityDecrement - 1); + + /* Don't go out of bounds */ + if (Priority < Thread->BasePriority) Priority = Thread->BasePriority; + + /* Reset the priority decrement */ + Thread->PriorityDecrement = 0; + } + + /* Sanity check */ + ASSERT((Thread->BasePriority == 0) || (Priority != 0)); + + /* Return the new priority */ + return Priority; +} + diff --git a/reactos/ntoskrnl/ke/gate.c b/reactos/ntoskrnl/ke/gate.c index cae5497c9e7..a9583caf6ef 100644 --- a/reactos/ntoskrnl/ke/gate.c +++ b/reactos/ntoskrnl/ke/gate.c @@ -85,7 +85,7 @@ KeWaitForGate(IN PKGATE Gate, if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue); /* Find a new thread to run */ - Status = KiSwapThread(); + Status = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); /* Check if we were executing an APC */ if (Status != STATUS_KERNEL_APC) return; diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index 4b621debd7d..b6a211409a4 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -200,10 +200,10 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus) } NTSTATUS -NTAPI -KiSwapThread(VOID) +FASTCALL +KiSwapThread(IN PKTHREAD CurrentThread, + IN PKPRCB Prcb) { - PKTHREAD CurrentThread = KeGetCurrentThread(); BOOLEAN ApcState; /* Find a new thread to run */ @@ -1068,10 +1068,10 @@ KeRevertToUserAffinityThread(VOID) /* * @implemented */ -CCHAR +UCHAR STDCALL KeSetIdealProcessorThread(IN PKTHREAD Thread, - IN CCHAR Processor) + IN UCHAR Processor) { CCHAR PreviousIdealProcessor; KIRQL OldIrql; diff --git a/reactos/ntoskrnl/ke/queue.c b/reactos/ntoskrnl/ke/queue.c index 3149645b1f0..041af562cc8 100644 --- a/reactos/ntoskrnl/ke/queue.c +++ b/reactos/ntoskrnl/ke/queue.c @@ -426,7 +426,7 @@ KeRemoveQueue(IN PKQUEUE Queue, /* Find a new thread to run */ KiAddThreadToWaitList(Thread, Swappable); - Status = KiSwapThread(); + Status = KiSwapThread(Thread, KeGetCurrentPrcb()); /* Reset the wait reason */ Thread->WaitReason = 0; diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 92749c23bf3..06bd18c4996 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -352,7 +352,7 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, /* Find a new thread to run */ KiAddThreadToWaitList(CurrentThread, Swappable); - WaitStatus = KiSwapThread(); + WaitStatus = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Check if we were executing an APC or if we timed out */ @@ -540,7 +540,7 @@ KeWaitForSingleObject(IN PVOID Object, /* Find a new thread to run */ KiAddThreadToWaitList(CurrentThread, Swappable); - WaitStatus = KiSwapThread(); + WaitStatus = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Check if we were executing an APC */ @@ -828,7 +828,7 @@ KeWaitForMultipleObjects(IN ULONG Count, /* Find a new thread to run */ KiAddThreadToWaitList(CurrentThread, Swappable); - WaitStatus = KiSwapThread(); + WaitStatus = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Check if we were executing an APC */ From f9b0ee1a037803272a80fac4c7274d0d65a3add0 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 10 Sep 2006 15:07:02 +0000 Subject: [PATCH 109/488] vsnprintf -> _vsnprintf svn path=/trunk/; revision=24023 --- reactos/base/services/dhcp/util.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/reactos/base/services/dhcp/util.c b/reactos/base/services/dhcp/util.c index c72a2b29819..8e66ba4f49b 100644 --- a/reactos/base/services/dhcp/util.c +++ b/reactos/base/services/dhcp/util.c @@ -18,7 +18,7 @@ int note( char *format, ... ) { va_list arg_begin; va_start( arg_begin, format ); - ret = vsnprintf( buf, sizeof(buf), format, arg_begin ); + ret = _vsnprintf( buf, sizeof(buf), format, arg_begin ); DPRINT("NOTE: %s\n", buf); @@ -31,7 +31,7 @@ int debug( char *format, ... ) { va_list arg_begin; va_start( arg_begin, format ); - ret = vsnprintf( buf, sizeof(buf), format, arg_begin ); + ret = _vsnprintf( buf, sizeof(buf), format, arg_begin ); DPRINT("DEBUG: %s\n", buf); @@ -44,7 +44,7 @@ int warn( char *format, ... ) { va_list arg_begin; va_start( arg_begin, format ); - ret = vsnprintf( buf, sizeof(buf), format, arg_begin ); + ret = _vsnprintf( buf, sizeof(buf), format, arg_begin ); DPRINT("WARN: %s\n", buf); @@ -57,7 +57,7 @@ int warning( char *format, ... ) { va_list arg_begin; va_start( arg_begin, format ); - ret = vsnprintf( buf, sizeof(buf), format, arg_begin ); + ret = _vsnprintf( buf, sizeof(buf), format, arg_begin ); DPRINT("WARNING: %s\n", buf); @@ -69,7 +69,7 @@ void error( char *format, ... ) { va_list arg_begin; va_start( arg_begin, format ); - vsnprintf( buf, sizeof(buf), format, arg_begin ); + _vsnprintf( buf, sizeof(buf), format, arg_begin ); DPRINT1("ERROR: %s\n", buf); } From aafcd436d5cfacb57bc373db53ed9d61a6d2f7db Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 15:23:20 +0000 Subject: [PATCH 110/488] - Thread Support cleanup 1: Separate kthread.c into thrdobj.c (Exported and globally accesible functions dealing with the KTHREAD object) and thrdschd.c (Fully internal thread scheduling routines for Ke* only). - Also fix KeSetAffinityThread to return the old affinity, instead of NTSTATUS and move NtYieldExecution from Ps to Ke, and move NtDelayExecution to wait.c - No code changes. svn path=/trunk/; revision=24024 --- reactos/include/ndk/kefuncs.h | 2 +- reactos/ntoskrnl/include/internal/ke.h | 5 +- reactos/ntoskrnl/ke/dpc.c | 2 +- reactos/ntoskrnl/ke/{kthread.c => thrdobj.c} | 2812 ++++++++---------- reactos/ntoskrnl/ke/thrdschd.c | 430 +++ reactos/ntoskrnl/ke/wait.c | 37 + reactos/ntoskrnl/ntoskrnl.rbuild | 3 +- reactos/ntoskrnl/ps/thread.c | 11 - 8 files changed, 1672 insertions(+), 1630 deletions(-) rename reactos/ntoskrnl/ke/{kthread.c => thrdobj.c} (72%) create mode 100644 reactos/ntoskrnl/ke/thrdschd.c diff --git a/reactos/include/ndk/kefuncs.h b/reactos/include/ndk/kefuncs.h index a43f2256271..9606535fada 100644 --- a/reactos/include/ndk/kefuncs.h +++ b/reactos/include/ndk/kefuncs.h @@ -73,7 +73,7 @@ KeSetEventBoostPriority( IN PKTHREAD *Thread OPTIONAL ); -NTSTATUS +KAFFINITY NTAPI KeSetAffinityThread( PKTHREAD Thread, diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index b57dfcb43ba..e75dec5fe60 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -126,7 +126,7 @@ extern LIST_ENTRY KiStackInSwapListHead; extern KEVENT KiSwapEvent; extern PKPRCB KiProcessorBlock[]; extern ULONG KiMask32Array[MAXIMUM_PRIORITY]; -extern ULONG IdleProcessorMask; +extern ULONG KiIdleSummary; extern VOID KiTrap8(VOID); extern VOID KiTrap2(VOID); @@ -242,7 +242,8 @@ KAFFINITY NTAPI KiSetAffinityThread( IN PKTHREAD Thread, - IN KAFFINITY Affinity + IN KAFFINITY Affinity, + IN PBOOLEAN Released // hack ); PKTHREAD diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 9500adba101..70cba3cf283 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -337,7 +337,7 @@ KeInsertQueueDpc(IN PKDPC Dpc, if (((Dpc->Importance == HighImportance) || (DpcData->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth)) && - (!(AFFINITY_MASK(Cpu) & IdleProcessorMask) || + (!(AFFINITY_MASK(Cpu) & KiIdleSummary) || (Prcb->Sleeping))) { /* Set interrupt requested */ diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/thrdobj.c similarity index 72% rename from reactos/ntoskrnl/ke/kthread.c rename to reactos/ntoskrnl/ke/thrdobj.c index b6a211409a4..e67e584ea80 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -1,1614 +1,1198 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/kthread.c - * PURPOSE: Microkernel thread support - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * David Welch (welch@cwcom.net) - */ - -/* INCLUDES *****************************************************************/ - -#include -#define NDEBUG -#include - -extern EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue]; - -/* - * PURPOSE: List of threads associated with each priority level - */ -LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY]; -static ULONG PriorityListMask = 0; -ULONG IdleProcessorMask = 0; -extern LIST_ENTRY PspReaperListHead; - -ULONG KiMask32Array[MAXIMUM_PRIORITY] = -{ - 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, - 0x40, 0x80, 0x100, 0x200, 0x4000, 0x800, - 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, - 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, - 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, - 0x40000000, 0x80000000 -}; - -/* FUNCTIONS *****************************************************************/ - -UCHAR -NTAPI -KeFindNextRightSetAffinity(IN UCHAR Number, - IN ULONG Set) -{ - ULONG Bit, Result; - ASSERT(Set != 0); - - /* Calculate the mask */ - Bit = (AFFINITY_MASK(Number) - 1) & Set; - - /* If it's 0, use the one we got */ - if (!Bit) Bit = Set; - - /* Now find the right set and return it */ - BitScanReverse(&Result, Bit); - return (UCHAR)Result; -} - -static -VOID -KiRequestReschedule(CCHAR Processor) -{ - PKPCR Pcr; - - Pcr = (PKPCR)(KPCR_BASE + Processor * PAGE_SIZE); - Pcr->Prcb->QuantumEnd = TRUE; - KiIpiSendRequest(1 << Processor, IPI_DPC); -} - -static -VOID -KiInsertIntoThreadList(KPRIORITY Priority, - PKTHREAD Thread) -{ - ASSERT(Ready == Thread->State); - ASSERT(Thread->Priority == Priority); - - if (Priority >= MAXIMUM_PRIORITY || Priority < LOW_PRIORITY) { - - DPRINT1("Invalid thread priority (%d)\n", Priority); - KEBUGCHECK(0); - } - - InsertTailList(&PriorityListHead[Priority], &Thread->WaitListEntry); - PriorityListMask |= (1 << Priority); -} - -static -VOID -KiRemoveFromThreadList(PKTHREAD Thread) -{ - ASSERT(Ready == Thread->State); - RemoveEntryList(&Thread->WaitListEntry); - if (IsListEmpty(&PriorityListHead[(ULONG)Thread->Priority])) { - - PriorityListMask &= ~(1 << Thread->Priority); - } -} - -static -PKTHREAD -KiScanThreadList(KPRIORITY Priority, - KAFFINITY Affinity) -{ - PKTHREAD current; - ULONG Mask; - - Mask = (1 << Priority); - - if (PriorityListMask & Mask) { - - LIST_FOR_EACH(current, &PriorityListHead[Priority], KTHREAD, WaitListEntry) { - - if (current->State != Ready) { - - DPRINT1("%p/%d\n", current, current->State); - } - - ASSERT(current->State == Ready); - - if (current->Affinity & Affinity) { - - KiRemoveFromThreadList(current); - return(current); - } - } - } - - return(NULL); -} - -BOOLEAN -STDCALL -KiDispatchThreadNoLock(ULONG NewThreadStatus) -{ - KPRIORITY CurrentPriority; - PKTHREAD Candidate; - ULONG Affinity; - PKTHREAD CurrentThread = KeGetCurrentThread(); - BOOLEAN ApcState; - - DPRINT("KiDispatchThreadNoLock() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(), - CurrentThread, NewThreadStatus, CurrentThread->State); - - CurrentThread->State = (UCHAR)NewThreadStatus; - - if (NewThreadStatus == Ready) { - - KiInsertIntoThreadList(CurrentThread->Priority, - CurrentThread); - } - - Affinity = 1 << KeGetCurrentProcessorNumber(); - - for (CurrentPriority = HIGH_PRIORITY; CurrentPriority >= LOW_PRIORITY; CurrentPriority--) { - - Candidate = KiScanThreadList(CurrentPriority, Affinity); - - if (Candidate == CurrentThread) { - - Candidate->State = Running; - KeReleaseDispatcherDatabaseLockFromDpcLevel(); - return FALSE; - } - - if (Candidate != NULL) { - - PKTHREAD OldThread; - PKTHREAD IdleThread; - - DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority); - - Candidate->State = Running; - - OldThread = CurrentThread; - CurrentThread = Candidate; - IdleThread = KeGetCurrentPrcb()->IdleThread; - - if (OldThread == IdleThread) { - - IdleProcessorMask &= ~Affinity; - - } else if (CurrentThread == IdleThread) { - - IdleProcessorMask |= Affinity; - } - - MmUpdatePageDir((PEPROCESS)PsGetCurrentProcess(),((PETHREAD)CurrentThread)->ThreadsProcess, sizeof(EPROCESS)); - - /* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */ - DPRINT("You are : %x, swapping to: %x.\n", OldThread, CurrentThread); - ApcState = KiSwapContext(OldThread, CurrentThread); - DPRINT("You are : %x, swapped from: %x\n", OldThread, CurrentThread); - return ApcState; - } - } - - DPRINT1("CRITICAL: No threads are ready (CPU%d)\n", KeGetCurrentProcessorNumber()); - KEBUGCHECK(0); - return FALSE; -} - -NTSTATUS -FASTCALL -KiSwapThread(IN PKTHREAD CurrentThread, - IN PKPRCB Prcb) -{ - BOOLEAN ApcState; - - /* Find a new thread to run */ - DPRINT("Dispatching Thread as blocked\n"); - ApcState = KiDispatchThreadNoLock(Waiting); - - /* Check if we need to deliver APCs */ - if (ApcState) - { - /* Lower to APC_LEVEL */ - KeLowerIrql(APC_LEVEL); - - /* Deliver APCs */ - KiDeliverApc(KernelMode, NULL, NULL); - ASSERT(CurrentThread->WaitIrql == 0); - } - - /* Lower IRQL back to what it was */ - KfLowerIrql(CurrentThread->WaitIrql); - - /* Return the wait status */ - return CurrentThread->WaitStatus; -} - -VOID -STDCALL -KiDispatchThread(ULONG NewThreadStatus) -{ - KIRQL OldIrql; - - if (KeGetCurrentPrcb()->IdleThread == NULL) { - return; - } - - OldIrql = KeAcquireDispatcherDatabaseLock(); - KiDispatchThreadNoLock(NewThreadStatus); - KeLowerIrql(OldIrql); -} - -VOID -NTAPI -KiReadyThread(IN PKTHREAD Thread) -{ - /* Makes a thread ready */ - Thread->State = Ready; - KiInsertIntoThreadList(Thread->Priority, Thread); -} - -VOID -STDCALL -KiAdjustQuantumThread(IN PKTHREAD Thread) -{ - KPRIORITY Priority; - - /* Don't adjust for RT threads */ - if ((Thread->Priority < LOW_REALTIME_PRIORITY) && - Thread->BasePriority < LOW_REALTIME_PRIORITY - 2) - { - /* Decrease Quantum by one and see if we've ran out */ - if (--Thread->Quantum <= 0) - { - /* Return quantum */ - Thread->Quantum = Thread->QuantumReset; - - /* Calculate new Priority */ - Priority = Thread->Priority - (Thread->PriorityDecrement + 1); - - /* Normalize it if we've gone too low */ - if (Priority < Thread->BasePriority) Priority = Thread->BasePriority; - - /* Reset the priority decrement, we've done it */ - Thread->PriorityDecrement = 0; - - /* Set the new priority, if needed */ - if (Priority != Thread->Priority) - { - /* - * FIXME: This should be a call to KiSetPriorityThread but - * due to the current ""scheduler"" in ROS, it can't be done - * cleanly since it actualyl dispatches threads instead. - */ - Thread->Priority = Priority; - } - else - { - /* FIXME: Priority hasn't changed, find a new thread */ - } - } - } - - /* Nothing to do... */ - return; -} - - -VOID -STDCALL -KiSuspendThreadKernelRoutine(PKAPC Apc, - PKNORMAL_ROUTINE* NormalRoutine, - PVOID* NormalContext, - PVOID* SystemArgument1, - PVOID* SystemArguemnt2) -{ -} - -VOID -STDCALL -KiSuspendThreadNormalRoutine(PVOID NormalContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PKTHREAD CurrentThread = KeGetCurrentThread(); - - /* Non-alertable kernel-mode suspended wait */ - DPRINT("Waiting...\n"); - KeWaitForSingleObject(&CurrentThread->SuspendSemaphore, - Suspended, - KernelMode, - FALSE, - NULL); - DPRINT("Done Waiting\n"); -} - -#ifdef KeGetCurrentThread -#undef KeGetCurrentThread -#endif -/* - * @implemented - */ -PKTHREAD -STDCALL -KeGetCurrentThread(VOID) -{ -#ifdef CONFIG_SMP - ULONG Flags; - PKTHREAD Thread; - Ke386SaveFlags(Flags); - Ke386DisableInterrupts(); - Thread = KeGetCurrentPrcb()->CurrentThread; - Ke386RestoreFlags(Flags); - return Thread; -#else - return(KeGetCurrentPrcb()->CurrentThread); -#endif -} - -VOID -STDCALL -KeSetPreviousMode(ULONG Mode) -{ - PsGetCurrentThread()->Tcb.PreviousMode = (UCHAR)Mode; -} - -/* - * @implemented - */ -KPROCESSOR_MODE -STDCALL -KeGetPreviousMode(VOID) -{ - return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode; -} - -BOOLEAN -STDCALL -KeDisableThreadApcQueueing(IN PKTHREAD Thread) -{ - KIRQL OldIrql; - BOOLEAN PreviousState; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save old state */ - PreviousState = Thread->ApcQueueable; - - /* Disable it now */ - Thread->ApcQueueable = FALSE; - - /* Release the Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - /* Return old state */ - return PreviousState; -} - -VOID -STDCALL -KeRundownThread(VOID) -{ - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - PLIST_ENTRY NextEntry, ListHead; - PKMUTANT Mutant; - DPRINT("KeRundownThread: %x\n", Thread); - - /* Optimized path if nothing is on the list at the moment */ - if (IsListEmpty(&Thread->MutantListHead)) return; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Get the List Pointers */ - ListHead = &Thread->MutantListHead; - NextEntry = ListHead->Flink; - while (NextEntry != ListHead) - { - /* Get the Mutant */ - Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry); - DPRINT1("Mutant: %p. Type, Size %x %x\n", - Mutant, - Mutant->Header.Type, - Mutant->Header.Size); - - /* Make sure it's not terminating with APCs off */ - if (Mutant->ApcDisable) - { - /* Bugcheck the system */ - KEBUGCHECKEX(0,//THREAD_TERMINATE_HELD_MUTEX, - (ULONG_PTR)Thread, - (ULONG_PTR)Mutant, - 0, - 0); - } - - /* Now we can remove it */ - RemoveEntryList(&Mutant->MutantListEntry); - - /* Unconditionally abandon it */ - DPRINT("Abandonning the Mutant\n"); - Mutant->Header.SignalState = 1; - Mutant->Abandoned = TRUE; - Mutant->OwnerThread = NULL; - - /* Check if the Wait List isn't empty */ - DPRINT("Checking whether to wake the Mutant\n"); - if (!IsListEmpty(&Mutant->Header.WaitListHead)) - { - /* Wake the Mutant */ - DPRINT("Waking the Mutant\n"); - KiWaitTest(&Mutant->Header, MUTANT_INCREMENT); - } - - /* Move on */ - NextEntry = NextEntry->Flink; - } - - /* Release the Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); -} - -ULONG -NTAPI -KeResumeThread(IN PKTHREAD Thread) -{ - ULONG PreviousCount; - KIRQL OldIrql; - - DPRINT("KeResumeThread (Thread %p called). %x, %x\n", Thread, - Thread->SuspendCount, Thread->FreezeCount); - - /* Lock the Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save the Old Count */ - PreviousCount = Thread->SuspendCount; - - /* Check if it existed */ - if (PreviousCount) { - - Thread->SuspendCount--; - - /* Decrease the current Suspend Count and Check Freeze Count */ - if ((!Thread->SuspendCount) && (!Thread->FreezeCount)) { - - /* Signal the Suspend Semaphore */ - Thread->SuspendSemaphore.Header.SignalState++; - KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); - } - } - - /* Release Lock and return the Old State */ - KeReleaseDispatcherDatabaseLock(OldIrql); - return PreviousCount; -} - -VOID -FASTCALL -KiInsertQueueApc(PKAPC Apc, - KPRIORITY PriorityBoost); - -/* - * Used by the debugging code to freeze all the process's threads - * while the debugger is examining their state. - */ -VOID -STDCALL -KeFreezeAllThreads(PKPROCESS Process) -{ - KIRQL OldIrql; - PKTHREAD Current; - PKTHREAD CurrentThread = KeGetCurrentThread(); - - /* Acquire Lock */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* If someone is already trying to free us, try again */ - while (CurrentThread->FreezeCount) - { - /* Release and re-acquire the lock so the APC will go through */ - KeReleaseDispatcherDatabaseLock(OldIrql); - OldIrql = KeAcquireDispatcherDatabaseLock(); - } - - /* Enter a critical region */ - KeEnterCriticalRegion(); - - /* Loop the Process's Threads */ - LIST_FOR_EACH(Current, &Process->ThreadListHead, KTHREAD, ThreadListEntry) - { - /* Make sure it's not ours */ - if (Current != CurrentThread) - { - /* Should be bother inserting the APC? */ - if (Current->ApcQueueable) - { - /* Make sure it wasn't already frozen, and that it's not suspended */ - if (!(++Current->FreezeCount) && !(Current->SuspendCount)) - { - /* Did we already insert it? */ - if (!Current->SuspendApc.Inserted) - { - /* Insert the APC */ - Current->SuspendApc.Inserted = TRUE; - KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT); - } - else - { - /* Unsignal the Semaphore, the APC already got inserted */ - Current->SuspendSemaphore.Header.SignalState--; - } - } - } - } - } - - /* Release the lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); -} - -NTSTATUS -STDCALL -KeSuspendThread(PKTHREAD Thread) -{ - ULONG PreviousCount; - KIRQL OldIrql; - - DPRINT("KeSuspendThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount); - - /* Lock the Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save the Old Count */ - PreviousCount = Thread->SuspendCount; - - /* Handle the maximum */ - if (PreviousCount == MAXIMUM_SUSPEND_COUNT) - { - /* Raise an exception */ - KeReleaseDispatcherDatabaseLock(OldIrql); - RtlRaiseStatus(STATUS_SUSPEND_COUNT_EXCEEDED); - } - - /* Should we bother to queue at all? */ - if (Thread->ApcQueueable) - { - /* Increment the suspend count */ - Thread->SuspendCount++; - - /* Check if we should suspend it */ - if (!PreviousCount && !Thread->FreezeCount) - { - /* Is the APC already inserted? */ - if (!Thread->SuspendApc.Inserted) - { - /* Not inserted, insert it */ - Thread->SuspendApc.Inserted = TRUE; - KiInsertQueueApc(&Thread->SuspendApc, IO_NO_INCREMENT); - } - else - { - /* Unsignal the Semaphore, the APC already got inserted */ - Thread->SuspendSemaphore.Header.SignalState--; - } - } - } - - /* Release Lock and return the Old State */ - KeReleaseDispatcherDatabaseLock(OldIrql); - return PreviousCount; -} - -ULONG -STDCALL -KeForceResumeThread(IN PKTHREAD Thread) -{ - KIRQL OldIrql; - ULONG PreviousCount; - - /* Lock the Dispatcher Database and the APC Queue */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save the old Suspend Count */ - PreviousCount = Thread->SuspendCount + Thread->FreezeCount; - - /* If the thread is suspended, wake it up!!! */ - if (PreviousCount) { - - /* Unwait it completely */ - Thread->SuspendCount = 0; - Thread->FreezeCount = 0; - - /* Signal and satisfy */ - Thread->SuspendSemaphore.Header.SignalState++; - KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); - } - - /* Release Lock and return the Old State */ - KeReleaseDispatcherDatabaseLock(OldIrql); - return PreviousCount; -} - -ULONG -NTAPI -KeAlertResumeThread(IN PKTHREAD Thread) -{ - ULONG PreviousCount; - KIRQL OldIrql; - - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - /* Lock the Dispatcher Database and the APC Queue */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - KiAcquireSpinLock(&Thread->ApcQueueLock); - - /* Return if Thread is already alerted. */ - if (Thread->Alerted[KernelMode] == FALSE) { - - /* If it's Blocked, unblock if it we should */ - if (Thread->State == Waiting && Thread->Alertable) { - - DPRINT("Aborting Wait\n"); - KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); - - } else { - - /* If not, simply Alert it */ - Thread->Alerted[KernelMode] = TRUE; - } - } - - /* Save the old Suspend Count */ - PreviousCount = Thread->SuspendCount; - - /* If the thread is suspended, decrease one of the suspend counts */ - if (PreviousCount) { - - /* Decrease count. If we are now zero, unwait it completely */ - if (--Thread->SuspendCount) { - - /* Signal and satisfy */ - Thread->SuspendSemaphore.Header.SignalState++; - KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); - } - } - - /* Release Locks and return the Old State */ - KiReleaseSpinLock(&Thread->ApcQueueLock); - KeReleaseDispatcherDatabaseLock(OldIrql); - return PreviousCount; -} - -BOOLEAN -NTAPI -KeAlertThread(IN PKTHREAD Thread, - IN KPROCESSOR_MODE AlertMode) -{ - KIRQL OldIrql; - BOOLEAN PreviousState; - - /* Acquire the Dispatcher Database Lock */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save the Previous State */ - PreviousState = Thread->Alerted[AlertMode]; - - /* Return if Thread is already alerted. */ - if (PreviousState == FALSE) { - - /* If it's Blocked, unblock if it we should */ - if (Thread->State == Waiting && - (AlertMode == KernelMode || Thread->WaitMode == AlertMode) && - Thread->Alertable) { - - DPRINT("Aborting Wait\n"); - KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); - - } else { - - /* If not, simply Alert it */ - Thread->Alerted[AlertMode] = TRUE; - } - } - - /* Release the Dispatcher Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - /* Return the old state */ - return PreviousState; -} - -/* - * @unimplemented - */ -VOID -STDCALL -KeCapturePersistentThreadState(IN PVOID CurrentThread, - IN ULONG Setting1, - IN ULONG Setting2, - IN ULONG Setting3, - IN ULONG Setting4, - IN ULONG Setting5, - IN PVOID ThreadState) -{ - UNIMPLEMENTED; -} - -VOID -NTAPI -KeUninitThread(IN PKTHREAD Thread) -{ - /* Delete the stack */ - MmDeleteKernelStack(Thread->StackBase, FALSE); - Thread->InitialStack = NULL; -} - -NTSTATUS -NTAPI -KeInitThread(IN OUT PKTHREAD Thread, - IN PVOID KernelStack, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT Context, - IN PVOID Teb, - IN PKPROCESS Process) -{ - BOOLEAN AllocatedStack = FALSE; - ULONG i; - PKWAIT_BLOCK TimerWaitBlock; - PKTIMER Timer; - NTSTATUS Status; - - /* Initalize the Dispatcher Header */ - KeInitializeDispatcherHeader(&Thread->DispatcherHeader, - ThreadObject, - sizeof(KTHREAD) / sizeof(LONG), - FALSE); - - /* Initialize the Mutant List */ - InitializeListHead(&Thread->MutantListHead); - - /* Initialize the wait blocks */ - for (i = 0; i< (THREAD_WAIT_OBJECTS + 1); i++) - { - /* Put our pointer */ - Thread->WaitBlock[i].Thread = Thread; - } - - /* Set swap settings */ - Thread->EnableStackSwap = FALSE;//TRUE; - Thread->IdealProcessor = 1; - Thread->SwapBusy = FALSE; - Thread->AdjustReason = 0; - - /* Initialize the lock */ - KeInitializeSpinLock(&Thread->ThreadLock); - - /* Setup the Service Descriptor Table for Native Calls */ - Thread->ServiceTable = KeServiceDescriptorTable; - - /* Setup APC Fields */ - InitializeListHead(&Thread->ApcState.ApcListHead[0]); - InitializeListHead(&Thread->ApcState.ApcListHead[1]); - Thread->ApcState.Process = Process; - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; - Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; - Thread->ApcStateIndex = OriginalApcEnvironment; - Thread->ApcQueueable = TRUE; - KeInitializeSpinLock(&Thread->ApcQueueLock); - - /* Initialize the Suspend APC */ - KeInitializeApc(&Thread->SuspendApc, - Thread, - OriginalApcEnvironment, - KiSuspendThreadKernelRoutine, - NULL, - KiSuspendThreadNormalRoutine, - KernelMode, - NULL); - - /* Initialize the Suspend Semaphore */ - KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2); - - /* Setup the timer */ - Timer = &Thread->Timer; - KeInitializeTimer(Timer); - TimerWaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK]; - TimerWaitBlock->Object = Timer; - TimerWaitBlock->WaitKey = STATUS_TIMEOUT; - TimerWaitBlock->WaitType = WaitAny; - TimerWaitBlock->NextWaitBlock = NULL; - - /* Link the two wait lists together */ - TimerWaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead; - TimerWaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead; - - /* Set the TEB */ - Thread->Teb = Teb; - - /* Check if we have a kernel stack */ - if (!KernelStack) - { - /* We don't, allocate one */ - KernelStack = (PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) + - KERNEL_STACK_SIZE); - if (!KernelStack) return STATUS_INSUFFICIENT_RESOURCES; - - /* Remember for later */ - AllocatedStack = TRUE; - } - - /* Set the Thread Stacks */ - Thread->InitialStack = (PCHAR)KernelStack; - Thread->StackBase = (PCHAR)KernelStack; - Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE; - Thread->KernelStackResident = TRUE; - - /* ROS Mm HACK */ - MmUpdatePageDir((PEPROCESS)Process, - (PVOID)Thread->StackLimit, - KERNEL_STACK_SIZE); - MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); - - /* Enter SEH to avoid crashes due to user mode */ - Status = STATUS_SUCCESS; - _SEH_TRY - { - /* Initalize the Thread Context */ - Ke386InitThreadWithContext(Thread, - SystemRoutine, - StartRoutine, - StartContext, - Context); - } - _SEH_HANDLE - { - /* Set failure status */ - Status = STATUS_UNSUCCESSFUL; - - /* Check if a stack was allocated */ - if (AllocatedStack) - { - /* Delete the stack */ - MmDeleteKernelStack(Thread->StackBase, FALSE); - Thread->InitialStack = NULL; - } - } - _SEH_END; - - /* Set the Thread to initalized */ - Thread->State = Initialized; - return Status; -} - -VOID -NTAPI -KeStartThread(IN OUT PKTHREAD Thread) -{ - KIRQL OldIrql; - PKPROCESS Process = Thread->ApcState.Process; - PKNODE Node; - PKPRCB NodePrcb; - ULONG Set, Mask; - UCHAR IdealProcessor; - - /* Setup static fields from parent */ - Thread->Iopl = Process->Iopl; - Thread->Quantum = Process->QuantumReset; - Thread->QuantumReset = Process->QuantumReset; - Thread->SystemAffinityActive = FALSE; - - /* Lock the process */ - KeAcquireSpinLock(&Process->ProcessLock, &OldIrql); - - /* Setup volatile data */ - Thread->Priority = Process->BasePriority; - Thread->BasePriority = Process->BasePriority; - Thread->Affinity = Process->Affinity; - Thread->UserAffinity = Process->Affinity; - - /* Get the KNODE and its PRCB */ - Node = KeNodeBlock[Process->IdealNode]; - NodePrcb = (PKPRCB)(KPCR_BASE + (Process->ThreadSeed * PAGE_SIZE)); - - /* Calculate affinity mask */ - Set = ~NodePrcb->MultiThreadProcessorSet; - Mask = (ULONG)(Node->ProcessorMask & Process->Affinity); - Set &= Mask; - if (Set) Mask = Set; - - /* Get the new thread seed */ - IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask); - Process->ThreadSeed = IdealProcessor; - - /* Sanity check */ - ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor))); - - /* Set the Ideal Processor */ - Thread->IdealProcessor = IdealProcessor; - Thread->UserIdealProcessor = IdealProcessor; - - /* Lock the Dispatcher Database */ - KeAcquireDispatcherDatabaseLockAtDpcLevel(); - - /* Insert the thread into the process list */ - InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry); - - /* Increase the stack count */ - ASSERT(Process->StackCount != MAXULONG_PTR); - Process->StackCount++; - - /* Release locks and return */ - KeReleaseDispatcherDatabaseLockFromDpcLevel(); - KeReleaseSpinLock(&Process->ProcessLock, OldIrql); -} - -VOID -NTAPI -KeInitializeThread(IN PKPROCESS Process, - IN OUT PKTHREAD Thread, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT Context, - IN PVOID Teb, - IN PVOID KernelStack) -{ - /* Initailize and start the thread on success */ - if (NT_SUCCESS(KeInitThread(Thread, - KernelStack, - SystemRoutine, - StartRoutine, - StartContext, - Context, - Teb, - Process))) - { - /* Start it */ - KeStartThread(Thread); - } -} - -/* - * @implemented - */ -KPRIORITY -STDCALL -KeQueryPriorityThread (IN PKTHREAD Thread) -{ - return Thread->Priority; -} - -/* - * @implemented - */ -ULONG -STDCALL -KeQueryRuntimeThread(IN PKTHREAD Thread, - OUT PULONG UserTime) -{ - /* Return the User Time */ - *UserTime = Thread->UserTime; - - /* Return the Kernel Time */ - return Thread->KernelTime; -} - -/* - * @implemented - */ -BOOLEAN -STDCALL -KeSetKernelStackSwapEnable(IN BOOLEAN Enable) -{ - PKTHREAD Thread = KeGetCurrentThread(); - BOOLEAN PreviousState; - KIRQL OldIrql; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save Old State */ - PreviousState = Thread->EnableStackSwap; - - /* Set New State */ - Thread->EnableStackSwap = Enable; - - /* No, Release Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - /* Return Old State */ - return PreviousState; -} - -/* - * @implemented - */ -VOID -STDCALL -KeRevertToUserAffinityThread(VOID) -{ - PKTHREAD CurrentThread = KeGetCurrentThread(); - KIRQL OldIrql; - - ASSERT(CurrentThread->SystemAffinityActive != FALSE); - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Return to User Affinity */ - CurrentThread->Affinity = CurrentThread->UserAffinity; - - /* Disable System Affinity */ - CurrentThread->SystemAffinityActive = FALSE; - - /* Check if we need to Dispatch a New thread */ - if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber())) { - - /* No, just release */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - } else { - - /* We need to dispatch a new thread */ - CurrentThread->WaitIrql = OldIrql; - KiDispatchThreadNoLock(Ready); - KeLowerIrql(OldIrql); - } -} - -/* - * @implemented - */ -UCHAR -STDCALL -KeSetIdealProcessorThread(IN PKTHREAD Thread, - IN UCHAR Processor) -{ - CCHAR PreviousIdealProcessor; - KIRQL OldIrql; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save Old Ideal Processor */ - PreviousIdealProcessor = Thread->IdealProcessor; - - /* Set New Ideal Processor */ - Thread->IdealProcessor = Processor; - - /* Release Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - /* Return Old Ideal Processor */ - return PreviousIdealProcessor; -} - -/* - * @implemented - */ -VOID -STDCALL -KeSetSystemAffinityThread(IN KAFFINITY Affinity) -{ - PKTHREAD CurrentThread = KeGetCurrentThread(); - KIRQL OldIrql; - - ASSERT(Affinity & ((1 << KeNumberProcessors) - 1)); - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Set the System Affinity Specified */ - CurrentThread->Affinity = Affinity; - - /* Enable System Affinity */ - CurrentThread->SystemAffinityActive = TRUE; - - /* Check if we need to Dispatch a New thread */ - if (Affinity & (1 << KeGetCurrentProcessorNumber())) { - - /* No, just release */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - } else { - - /* We need to dispatch a new thread */ - CurrentThread->WaitIrql = OldIrql; - KiDispatchThreadNoLock(Ready); - KeLowerIrql(OldIrql); - } -} - -LONG -STDCALL -KeQueryBasePriorityThread(IN PKTHREAD Thread) -{ - LONG BasePriorityIncrement; - KIRQL OldIrql; - PKPROCESS Process; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Get the Process */ - Process = Thread->ApcStatePointer[0]->Process; - - /* Calculate the BPI */ - BasePriorityIncrement = Thread->BasePriority - Process->BasePriority; - - /* If saturation occured, return the SI instead */ - if (Thread->Saturation) BasePriorityIncrement = (HIGH_PRIORITY + 1) / 2 * - Thread->Saturation; - - /* Release Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - /* Return Increment */ - return BasePriorityIncrement; -} - -VOID -STDCALL -KiSetPriorityThread(PKTHREAD Thread, - KPRIORITY Priority, - PBOOLEAN Released) -{ - KPRIORITY OldPriority = Thread->Priority; - ULONG Mask; - int i; - PKPCR Pcr; - DPRINT("Changing prio to : %lx\n", Priority); - - /* Check if priority changed */ - if (OldPriority != Priority) - { - /* Set it */ - Thread->Priority = Priority; - - /* Choose action based on thread's state */ - if (Thread->State == Ready) - { - /* Remove it from the current queue */ - KiRemoveFromThreadList(Thread); - - /* Re-insert it at its current priority */ - KiInsertIntoThreadList(Priority, Thread); - - /* Check if the old priority was lower */ - if (KeGetCurrentThread()->Priority < Priority) - { - /* Dispatch it immediately */ - KiDispatchThreadNoLock(Ready); - *Released = TRUE; - return; - } - } - else if (Thread->State == Running) - { - /* Check if the new priority is lower */ - if (Priority < OldPriority) - { - /* Check for threads with a higher priority */ - Mask = ~((1 << (Priority + 1)) - 1); - if (PriorityListMask & Mask) - { - /* Found a thread, is it us? */ - if (Thread == KeGetCurrentThread()) - { - /* Dispatch us */ - KiDispatchThreadNoLock(Ready); - *Released = TRUE; - return; - } - else - { - /* Loop every CPU */ - for (i = 0; i < KeNumberProcessors; i++) - { - /* Get the PCR for this CPU */ - Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); - - /* Reschedule if the new one is already on a CPU */ - if (Pcr->Prcb->CurrentThread == Thread) - { - KeReleaseDispatcherDatabaseLockFromDpcLevel(); - KiRequestReschedule(i); - *Released = TRUE; - return; - } - } - } - } - } - } - } - - /* Return to caller */ - return; -} - -/* - * @implemented - */ -LONG -STDCALL -KeSetBasePriorityThread(PKTHREAD Thread, - LONG Increment) -{ - KIRQL OldIrql; - PKPROCESS Process; - KPRIORITY Priority; - KPRIORITY CurrentBasePriority; - KPRIORITY BasePriority; - BOOLEAN Released = FALSE; - LONG CurrentIncrement; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Get the process and calculate current BP and BPI */ - Process = Thread->ApcStatePointer[0]->Process; - CurrentBasePriority = Thread->BasePriority; - CurrentIncrement = CurrentBasePriority - Process->BasePriority; - - /* Change to use the SI if Saturation was used */ - if (Thread->Saturation) CurrentIncrement = (HIGH_PRIORITY + 1) / 2 * - Thread->Saturation; - - /* Now check if saturation is being used for the new value */ - if (abs(Increment) >= ((HIGH_PRIORITY + 1) / 2)) - { - /* Check if we need positive or negative saturation */ - Thread->Saturation = (Increment > 0) ? 1 : -1; - } - - /* Normalize the Base Priority */ - BasePriority = Process->BasePriority + Increment; - if (Process->BasePriority >= LOW_REALTIME_PRIORITY) - { - /* Check if it's too low */ - if (BasePriority < LOW_REALTIME_PRIORITY) - BasePriority = LOW_REALTIME_PRIORITY; - - /* Check if it's too high */ - if (BasePriority > HIGH_PRIORITY) BasePriority = HIGH_PRIORITY; - - /* We are at RTP, so use the raw BP */ - Priority = BasePriority; - } - else - { - /* Check if it's entering RTP */ - if (BasePriority >= LOW_REALTIME_PRIORITY) - BasePriority = LOW_REALTIME_PRIORITY - 1; - - /* Check if it's too low */ - if (BasePriority <= LOW_PRIORITY) - BasePriority = 1; - - /* If Saturation is used, then use the raw BP */ - if (Thread->Saturation) - { - Priority = BasePriority; - } - else - { - /* Calculate the new priority */ - Priority = Thread->Priority + (BasePriority - CurrentBasePriority)- - Thread->PriorityDecrement; - - /* Make sure it won't enter RTP ranges */ - if (Priority >= LOW_REALTIME_PRIORITY) - Priority = LOW_REALTIME_PRIORITY - 1; - } - } - - /* Finally set the new base priority */ - Thread->BasePriority = BasePriority; - - /* Reset the decrements */ - Thread->PriorityDecrement = 0; - - /* If the priority will change, reset quantum and change it for real */ - if (Priority != Thread->Priority) - { - Thread->Quantum = Thread->QuantumReset; - KiSetPriorityThread(Thread, Priority, &Released); - } - - /* Release Lock if needed */ - if (!Released) - { - KeReleaseDispatcherDatabaseLock(OldIrql); - } - else - { - KeLowerIrql(OldIrql); - } - - /* Return the Old Increment */ - return CurrentIncrement; -} - -/* - * @implemented - */ -KPRIORITY -STDCALL -KeSetPriorityThread(PKTHREAD Thread, - KPRIORITY Priority) -{ - KPRIORITY OldPriority; - BOOLEAN Released = FALSE; - KIRQL OldIrql; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save the old Priority */ - OldPriority = Thread->Priority; - - /* Reset the Quantum and Decrements */ - Thread->Quantum = Thread->QuantumReset; - Thread->PriorityDecrement = 0; - - /* Set the new Priority */ - KiSetPriorityThread(Thread, Priority, &Released); - - /* Release Lock if needed */ - if (!Released) - { - KeReleaseDispatcherDatabaseLock(OldIrql); - } - else - { - KeLowerIrql(OldIrql); - } - - /* Return Old Priority */ - return OldPriority; -} - -/* - * @implemented - * - * Sets thread's affinity - */ -NTSTATUS -STDCALL -KeSetAffinityThread(PKTHREAD Thread, - KAFFINITY Affinity) -{ - KIRQL OldIrql; - LONG i; - PKPCR Pcr; - KAFFINITY ProcessorMask; - - DPRINT("KeSetAffinityThread(Thread %x, Affinity %x)\n", Thread, Affinity); - - /* Verify correct affinity */ - if ((Affinity & Thread->ApcStatePointer[0]->Process->Affinity) != - Affinity || !Affinity) - { - KEBUGCHECK(INVALID_AFFINITY_SET); - } - - OldIrql = KeAcquireDispatcherDatabaseLock(); - - Thread->UserAffinity = Affinity; - - if (Thread->SystemAffinityActive == FALSE) { - - Thread->Affinity = Affinity; - - if (Thread->State == Running) { - - ProcessorMask = 1 << KeGetCurrentProcessorNumber(); - if (Thread == KeGetCurrentThread()) { - - if (!(Affinity & ProcessorMask)) { - - KiDispatchThreadNoLock(Ready); - KeLowerIrql(OldIrql); - return STATUS_SUCCESS; - } - - } else { - - for (i = 0; i < KeNumberProcessors; i++) { - - Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); - if (Pcr->Prcb->CurrentThread == Thread) { - - if (!(Affinity & ProcessorMask)) { - - KeReleaseDispatcherDatabaseLockFromDpcLevel(); - KiRequestReschedule(i); - KeLowerIrql(OldIrql); - return STATUS_SUCCESS; - } - - break; - } - } - - ASSERT (i < KeNumberProcessors); - } - } - } - - KeReleaseDispatcherDatabaseLock(OldIrql); - return STATUS_SUCCESS; -} - -/* - * @implemented - */ - /* The Increment Argument seems to be ignored by NT and always 0 when called */ -VOID -STDCALL -KeTerminateThread(IN KPRIORITY Increment) -{ - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - PKPROCESS Process = Thread->ApcState.Process; - PLIST_ENTRY *ListHead; - PETHREAD Entry, SavedEntry; - PETHREAD *ThreadAddr; - DPRINT("Terminating\n"); - - /* Lock the Dispatcher Database and the APC Queue */ - ASSERT_IRQL(DISPATCH_LEVEL); - OldIrql = KeAcquireDispatcherDatabaseLock(); - ASSERT(Thread->SwapBusy == FALSE); - - /* Make sure we won't get Swapped */ - Thread->SwapBusy = TRUE; - - /* Save the Kernel and User Times */ - Process->KernelTime += Thread->KernelTime; - Process->UserTime += Thread->UserTime; - - /* Get the current entry and our Port */ - Entry = (PETHREAD)PspReaperListHead.Flink; - ThreadAddr = &((PETHREAD)Thread)->ReaperLink; - - /* Add it to the reaper's list */ - do - { - /* Get the list head */ - ListHead = &PspReaperListHead.Flink; - - /* Link ourselves */ - *ThreadAddr = Entry; - SavedEntry = Entry; - - /* Now try to do the exchange */ - Entry = InterlockedCompareExchangePointer(ListHead, ThreadAddr, Entry); - - /* Break out if the change was succesful */ - } while (Entry != SavedEntry); - - /* Check if the reaper wasn't active */ - if (!Entry) - { - /* Activate it as a work item, directly through its Queue */ - KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue, - &PspReaperWorkItem.List, - FALSE); - } - - /* Handle Kernel Queues */ - if (Thread->Queue) - { - DPRINT("Waking Queue\n"); - RemoveEntryList(&Thread->QueueListEntry); - KiWakeQueue(Thread->Queue); - } - - /* Signal the thread */ - Thread->DispatcherHeader.SignalState = TRUE; - if (IsListEmpty(&Thread->DispatcherHeader.WaitListHead) != TRUE) - { - /* Satisfy waits */ - KiWaitTest((PVOID)Thread, Increment); - } - - /* Remove the thread from the list */ - RemoveEntryList(&Thread->ThreadListEntry); - - /* Set us as terminated, decrease the Process's stack count */ - Thread->State = Terminated; - Process->StackCount--; - - /* Find a new Thread */ - KiDispatchThreadNoLock(Terminated); -} - -/* - * FUNCTION: Tests whether there are any pending APCs for the current thread - * and if so the APCs will be delivered on exit from kernel mode - */ -BOOLEAN -STDCALL -KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) -{ - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - BOOLEAN OldState; - - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - /* Lock the Dispatcher Database and the APC Queue */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - KiAcquireSpinLock(&Thread->ApcQueueLock); - - /* Save the old State */ - OldState = Thread->Alerted[AlertMode]; - - /* If the Thread is Alerted, Clear it */ - if (OldState) { - - Thread->Alerted[AlertMode] = FALSE; - - } else if ((AlertMode != KernelMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) { - - /* If the mode is User and the Queue isn't empty, set Pending */ - Thread->ApcState.UserApcPending = TRUE; - } - - /* Release Locks and return the Old State */ - KiReleaseSpinLock(&Thread->ApcQueueLock); - KeReleaseDispatcherDatabaseLock(OldIrql); - return OldState; -} - -NTSTATUS -STDCALL -NtDelayExecution(IN BOOLEAN Alertable, - IN PLARGE_INTEGER DelayInterval) -{ - KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); - LARGE_INTEGER SafeInterval; - NTSTATUS Status; - - /* Check if parameters are valid */ - if(PreviousMode != KernelMode) { - - Status = STATUS_SUCCESS; - - _SEH_TRY { - - /* make a copy on the kernel stack and let DelayInterval point to it so - we don't need to wrap KeDelayExecutionThread in SEH! */ - SafeInterval = ProbeForReadLargeInteger(DelayInterval); - DelayInterval = &SafeInterval; - - } _SEH_HANDLE { - - Status = _SEH_GetExceptionCode(); - } _SEH_END; - - if (!NT_SUCCESS(Status)) - { - return Status; - } - } - - /* Call the Kernel Function */ - Status = KeDelayExecutionThread(PreviousMode, - Alertable, - DelayInterval); - - /* Return Status */ - return Status; -} +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/thrdobj.c + * PURPOSE: Implements routines to manage the Kernel Thread Object + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +extern EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue]; +extern LIST_ENTRY PspReaperListHead; + +ULONG KiMask32Array[MAXIMUM_PRIORITY] = +{ + 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, + 0x40, 0x80, 0x100, 0x200, 0x4000, 0x800, + 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, + 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, + 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, + 0x40000000, 0x80000000 +}; + +/* FUNCTIONS *****************************************************************/ + +UCHAR +NTAPI +KeFindNextRightSetAffinity(IN UCHAR Number, + IN ULONG Set) +{ + ULONG Bit, Result; + ASSERT(Set != 0); + + /* Calculate the mask */ + Bit = (AFFINITY_MASK(Number) - 1) & Set; + + /* If it's 0, use the one we got */ + if (!Bit) Bit = Set; + + /* Now find the right set and return it */ + BitScanReverse(&Result, Bit); + return (UCHAR)Result; +} + +VOID +STDCALL +KiSuspendThreadKernelRoutine(PKAPC Apc, + PKNORMAL_ROUTINE* NormalRoutine, + PVOID* NormalContext, + PVOID* SystemArgument1, + PVOID* SystemArguemnt2) +{ +} + +VOID +STDCALL +KiSuspendThreadNormalRoutine(PVOID NormalContext, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + PKTHREAD CurrentThread = KeGetCurrentThread(); + + /* Non-alertable kernel-mode suspended wait */ + DPRINT("Waiting...\n"); + KeWaitForSingleObject(&CurrentThread->SuspendSemaphore, + Suspended, + KernelMode, + FALSE, + NULL); + DPRINT("Done Waiting\n"); +} + +#ifdef KeGetCurrentThread +#undef KeGetCurrentThread +#endif +/* + * @implemented + */ +PKTHREAD +STDCALL +KeGetCurrentThread(VOID) +{ +#ifdef CONFIG_SMP + ULONG Flags; + PKTHREAD Thread; + Ke386SaveFlags(Flags); + Ke386DisableInterrupts(); + Thread = KeGetCurrentPrcb()->CurrentThread; + Ke386RestoreFlags(Flags); + return Thread; +#else + return(KeGetCurrentPrcb()->CurrentThread); +#endif +} + +VOID +STDCALL +KeSetPreviousMode(ULONG Mode) +{ + PsGetCurrentThread()->Tcb.PreviousMode = (UCHAR)Mode; +} + +/* + * @implemented + */ +KPROCESSOR_MODE +STDCALL +KeGetPreviousMode(VOID) +{ + return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode; +} + +BOOLEAN +STDCALL +KeDisableThreadApcQueueing(IN PKTHREAD Thread) +{ + KIRQL OldIrql; + BOOLEAN PreviousState; + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Save old state */ + PreviousState = Thread->ApcQueueable; + + /* Disable it now */ + Thread->ApcQueueable = FALSE; + + /* Release the Lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + /* Return old state */ + return PreviousState; +} + +VOID +STDCALL +KeRundownThread(VOID) +{ + KIRQL OldIrql; + PKTHREAD Thread = KeGetCurrentThread(); + PLIST_ENTRY NextEntry, ListHead; + PKMUTANT Mutant; + DPRINT("KeRundownThread: %x\n", Thread); + + /* Optimized path if nothing is on the list at the moment */ + if (IsListEmpty(&Thread->MutantListHead)) return; + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Get the List Pointers */ + ListHead = &Thread->MutantListHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the Mutant */ + Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry); + DPRINT1("Mutant: %p. Type, Size %x %x\n", + Mutant, + Mutant->Header.Type, + Mutant->Header.Size); + + /* Make sure it's not terminating with APCs off */ + if (Mutant->ApcDisable) + { + /* Bugcheck the system */ + KEBUGCHECKEX(0,//THREAD_TERMINATE_HELD_MUTEX, + (ULONG_PTR)Thread, + (ULONG_PTR)Mutant, + 0, + 0); + } + + /* Now we can remove it */ + RemoveEntryList(&Mutant->MutantListEntry); + + /* Unconditionally abandon it */ + DPRINT("Abandonning the Mutant\n"); + Mutant->Header.SignalState = 1; + Mutant->Abandoned = TRUE; + Mutant->OwnerThread = NULL; + + /* Check if the Wait List isn't empty */ + DPRINT("Checking whether to wake the Mutant\n"); + if (!IsListEmpty(&Mutant->Header.WaitListHead)) + { + /* Wake the Mutant */ + DPRINT("Waking the Mutant\n"); + KiWaitTest(&Mutant->Header, MUTANT_INCREMENT); + } + + /* Move on */ + NextEntry = NextEntry->Flink; + } + + /* Release the Lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); +} + +ULONG +NTAPI +KeResumeThread(IN PKTHREAD Thread) +{ + ULONG PreviousCount; + KIRQL OldIrql; + + DPRINT("KeResumeThread (Thread %p called). %x, %x\n", Thread, + Thread->SuspendCount, Thread->FreezeCount); + + /* Lock the Dispatcher */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Save the Old Count */ + PreviousCount = Thread->SuspendCount; + + /* Check if it existed */ + if (PreviousCount) { + + Thread->SuspendCount--; + + /* Decrease the current Suspend Count and Check Freeze Count */ + if ((!Thread->SuspendCount) && (!Thread->FreezeCount)) { + + /* Signal the Suspend Semaphore */ + Thread->SuspendSemaphore.Header.SignalState++; + KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); + } + } + + /* Release Lock and return the Old State */ + KeReleaseDispatcherDatabaseLock(OldIrql); + return PreviousCount; +} + +/* + * Used by the debugging code to freeze all the process's threads + * while the debugger is examining their state. + */ +VOID +STDCALL +KeFreezeAllThreads(PKPROCESS Process) +{ + KIRQL OldIrql; + PKTHREAD Current; + PKTHREAD CurrentThread = KeGetCurrentThread(); + + /* Acquire Lock */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* If someone is already trying to free us, try again */ + while (CurrentThread->FreezeCount) + { + /* Release and re-acquire the lock so the APC will go through */ + KeReleaseDispatcherDatabaseLock(OldIrql); + OldIrql = KeAcquireDispatcherDatabaseLock(); + } + + /* Enter a critical region */ + KeEnterCriticalRegion(); + + /* Loop the Process's Threads */ + LIST_FOR_EACH(Current, &Process->ThreadListHead, KTHREAD, ThreadListEntry) + { + /* Make sure it's not ours */ + if (Current != CurrentThread) + { + /* Should be bother inserting the APC? */ + if (Current->ApcQueueable) + { + /* Make sure it wasn't already frozen, and that it's not suspended */ + if (!(++Current->FreezeCount) && !(Current->SuspendCount)) + { + /* Did we already insert it? */ + if (!Current->SuspendApc.Inserted) + { + /* Insert the APC */ + Current->SuspendApc.Inserted = TRUE; + KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT); + } + else + { + /* Unsignal the Semaphore, the APC already got inserted */ + Current->SuspendSemaphore.Header.SignalState--; + } + } + } + } + } + + /* Release the lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); +} + +NTSTATUS +STDCALL +KeSuspendThread(PKTHREAD Thread) +{ + ULONG PreviousCount; + KIRQL OldIrql; + + DPRINT("KeSuspendThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount); + + /* Lock the Dispatcher */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Save the Old Count */ + PreviousCount = Thread->SuspendCount; + + /* Handle the maximum */ + if (PreviousCount == MAXIMUM_SUSPEND_COUNT) + { + /* Raise an exception */ + KeReleaseDispatcherDatabaseLock(OldIrql); + RtlRaiseStatus(STATUS_SUSPEND_COUNT_EXCEEDED); + } + + /* Should we bother to queue at all? */ + if (Thread->ApcQueueable) + { + /* Increment the suspend count */ + Thread->SuspendCount++; + + /* Check if we should suspend it */ + if (!PreviousCount && !Thread->FreezeCount) + { + /* Is the APC already inserted? */ + if (!Thread->SuspendApc.Inserted) + { + /* Not inserted, insert it */ + Thread->SuspendApc.Inserted = TRUE; + KiInsertQueueApc(&Thread->SuspendApc, IO_NO_INCREMENT); + } + else + { + /* Unsignal the Semaphore, the APC already got inserted */ + Thread->SuspendSemaphore.Header.SignalState--; + } + } + } + + /* Release Lock and return the Old State */ + KeReleaseDispatcherDatabaseLock(OldIrql); + return PreviousCount; +} + +ULONG +STDCALL +KeForceResumeThread(IN PKTHREAD Thread) +{ + KIRQL OldIrql; + ULONG PreviousCount; + + /* Lock the Dispatcher Database and the APC Queue */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Save the old Suspend Count */ + PreviousCount = Thread->SuspendCount + Thread->FreezeCount; + + /* If the thread is suspended, wake it up!!! */ + if (PreviousCount) { + + /* Unwait it completely */ + Thread->SuspendCount = 0; + Thread->FreezeCount = 0; + + /* Signal and satisfy */ + Thread->SuspendSemaphore.Header.SignalState++; + KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); + } + + /* Release Lock and return the Old State */ + KeReleaseDispatcherDatabaseLock(OldIrql); + return PreviousCount; +} + +ULONG +NTAPI +KeAlertResumeThread(IN PKTHREAD Thread) +{ + ULONG PreviousCount; + KIRQL OldIrql; + + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Lock the Dispatcher Database and the APC Queue */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + KiAcquireSpinLock(&Thread->ApcQueueLock); + + /* Return if Thread is already alerted. */ + if (Thread->Alerted[KernelMode] == FALSE) { + + /* If it's Blocked, unblock if it we should */ + if (Thread->State == Waiting && Thread->Alertable) { + + DPRINT("Aborting Wait\n"); + KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); + + } else { + + /* If not, simply Alert it */ + Thread->Alerted[KernelMode] = TRUE; + } + } + + /* Save the old Suspend Count */ + PreviousCount = Thread->SuspendCount; + + /* If the thread is suspended, decrease one of the suspend counts */ + if (PreviousCount) { + + /* Decrease count. If we are now zero, unwait it completely */ + if (--Thread->SuspendCount) { + + /* Signal and satisfy */ + Thread->SuspendSemaphore.Header.SignalState++; + KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); + } + } + + /* Release Locks and return the Old State */ + KiReleaseSpinLock(&Thread->ApcQueueLock); + KeReleaseDispatcherDatabaseLock(OldIrql); + return PreviousCount; +} + +BOOLEAN +NTAPI +KeAlertThread(IN PKTHREAD Thread, + IN KPROCESSOR_MODE AlertMode) +{ + KIRQL OldIrql; + BOOLEAN PreviousState; + + /* Acquire the Dispatcher Database Lock */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Save the Previous State */ + PreviousState = Thread->Alerted[AlertMode]; + + /* Return if Thread is already alerted. */ + if (PreviousState == FALSE) { + + /* If it's Blocked, unblock if it we should */ + if (Thread->State == Waiting && + (AlertMode == KernelMode || Thread->WaitMode == AlertMode) && + Thread->Alertable) { + + DPRINT("Aborting Wait\n"); + KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); + + } else { + + /* If not, simply Alert it */ + Thread->Alerted[AlertMode] = TRUE; + } + } + + /* Release the Dispatcher Lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + /* Return the old state */ + return PreviousState; +} + +/* + * @unimplemented + */ +VOID +STDCALL +KeCapturePersistentThreadState(IN PVOID CurrentThread, + IN ULONG Setting1, + IN ULONG Setting2, + IN ULONG Setting3, + IN ULONG Setting4, + IN ULONG Setting5, + IN PVOID ThreadState) +{ + UNIMPLEMENTED; +} + +VOID +NTAPI +KeUninitThread(IN PKTHREAD Thread) +{ + /* Delete the stack */ + MmDeleteKernelStack(Thread->StackBase, FALSE); + Thread->InitialStack = NULL; +} + +NTSTATUS +NTAPI +KeInitThread(IN OUT PKTHREAD Thread, + IN PVOID KernelStack, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT Context, + IN PVOID Teb, + IN PKPROCESS Process) +{ + BOOLEAN AllocatedStack = FALSE; + ULONG i; + PKWAIT_BLOCK TimerWaitBlock; + PKTIMER Timer; + NTSTATUS Status; + + /* Initalize the Dispatcher Header */ + KeInitializeDispatcherHeader(&Thread->DispatcherHeader, + ThreadObject, + sizeof(KTHREAD) / sizeof(LONG), + FALSE); + + /* Initialize the Mutant List */ + InitializeListHead(&Thread->MutantListHead); + + /* Initialize the wait blocks */ + for (i = 0; i< (THREAD_WAIT_OBJECTS + 1); i++) + { + /* Put our pointer */ + Thread->WaitBlock[i].Thread = Thread; + } + + /* Set swap settings */ + Thread->EnableStackSwap = FALSE;//TRUE; + Thread->IdealProcessor = 1; + Thread->SwapBusy = FALSE; + Thread->AdjustReason = 0; + + /* Initialize the lock */ + KeInitializeSpinLock(&Thread->ThreadLock); + + /* Setup the Service Descriptor Table for Native Calls */ + Thread->ServiceTable = KeServiceDescriptorTable; + + /* Setup APC Fields */ + InitializeListHead(&Thread->ApcState.ApcListHead[0]); + InitializeListHead(&Thread->ApcState.ApcListHead[1]); + Thread->ApcState.Process = Process; + Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; + Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; + Thread->ApcStateIndex = OriginalApcEnvironment; + Thread->ApcQueueable = TRUE; + KeInitializeSpinLock(&Thread->ApcQueueLock); + + /* Initialize the Suspend APC */ + KeInitializeApc(&Thread->SuspendApc, + Thread, + OriginalApcEnvironment, + KiSuspendThreadKernelRoutine, + NULL, + KiSuspendThreadNormalRoutine, + KernelMode, + NULL); + + /* Initialize the Suspend Semaphore */ + KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2); + + /* Setup the timer */ + Timer = &Thread->Timer; + KeInitializeTimer(Timer); + TimerWaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK]; + TimerWaitBlock->Object = Timer; + TimerWaitBlock->WaitKey = STATUS_TIMEOUT; + TimerWaitBlock->WaitType = WaitAny; + TimerWaitBlock->NextWaitBlock = NULL; + + /* Link the two wait lists together */ + TimerWaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead; + TimerWaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead; + + /* Set the TEB */ + Thread->Teb = Teb; + + /* Check if we have a kernel stack */ + if (!KernelStack) + { + /* We don't, allocate one */ + KernelStack = (PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) + + KERNEL_STACK_SIZE); + if (!KernelStack) return STATUS_INSUFFICIENT_RESOURCES; + + /* Remember for later */ + AllocatedStack = TRUE; + } + + /* Set the Thread Stacks */ + Thread->InitialStack = (PCHAR)KernelStack; + Thread->StackBase = (PCHAR)KernelStack; + Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE; + Thread->KernelStackResident = TRUE; + + /* ROS Mm HACK */ + MmUpdatePageDir((PEPROCESS)Process, + (PVOID)Thread->StackLimit, + KERNEL_STACK_SIZE); + MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); + + /* Enter SEH to avoid crashes due to user mode */ + Status = STATUS_SUCCESS; + _SEH_TRY + { + /* Initalize the Thread Context */ + Ke386InitThreadWithContext(Thread, + SystemRoutine, + StartRoutine, + StartContext, + Context); + } + _SEH_HANDLE + { + /* Set failure status */ + Status = STATUS_UNSUCCESSFUL; + + /* Check if a stack was allocated */ + if (AllocatedStack) + { + /* Delete the stack */ + MmDeleteKernelStack(Thread->StackBase, FALSE); + Thread->InitialStack = NULL; + } + } + _SEH_END; + + /* Set the Thread to initalized */ + Thread->State = Initialized; + return Status; +} + +VOID +NTAPI +KeStartThread(IN OUT PKTHREAD Thread) +{ + KIRQL OldIrql; + PKPROCESS Process = Thread->ApcState.Process; + PKNODE Node; + PKPRCB NodePrcb; + ULONG Set, Mask; + UCHAR IdealProcessor; + + /* Setup static fields from parent */ + Thread->Iopl = Process->Iopl; + Thread->Quantum = Process->QuantumReset; + Thread->QuantumReset = Process->QuantumReset; + Thread->SystemAffinityActive = FALSE; + + /* Lock the process */ + KeAcquireSpinLock(&Process->ProcessLock, &OldIrql); + + /* Setup volatile data */ + Thread->Priority = Process->BasePriority; + Thread->BasePriority = Process->BasePriority; + Thread->Affinity = Process->Affinity; + Thread->UserAffinity = Process->Affinity; + + /* Get the KNODE and its PRCB */ + Node = KeNodeBlock[Process->IdealNode]; + NodePrcb = (PKPRCB)(KPCR_BASE + (Process->ThreadSeed * PAGE_SIZE)); + + /* Calculate affinity mask */ + Set = ~NodePrcb->MultiThreadProcessorSet; + Mask = (ULONG)(Node->ProcessorMask & Process->Affinity); + Set &= Mask; + if (Set) Mask = Set; + + /* Get the new thread seed */ + IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask); + Process->ThreadSeed = IdealProcessor; + + /* Sanity check */ + ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor))); + + /* Set the Ideal Processor */ + Thread->IdealProcessor = IdealProcessor; + Thread->UserIdealProcessor = IdealProcessor; + + /* Lock the Dispatcher Database */ + KeAcquireDispatcherDatabaseLockAtDpcLevel(); + + /* Insert the thread into the process list */ + InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry); + + /* Increase the stack count */ + ASSERT(Process->StackCount != MAXULONG_PTR); + Process->StackCount++; + + /* Release locks and return */ + KeReleaseDispatcherDatabaseLockFromDpcLevel(); + KeReleaseSpinLock(&Process->ProcessLock, OldIrql); +} + +VOID +NTAPI +KeInitializeThread(IN PKPROCESS Process, + IN OUT PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT Context, + IN PVOID Teb, + IN PVOID KernelStack) +{ + /* Initailize and start the thread on success */ + if (NT_SUCCESS(KeInitThread(Thread, + KernelStack, + SystemRoutine, + StartRoutine, + StartContext, + Context, + Teb, + Process))) + { + /* Start it */ + KeStartThread(Thread); + } +} + +/* + * @implemented + */ +KPRIORITY +STDCALL +KeQueryPriorityThread (IN PKTHREAD Thread) +{ + return Thread->Priority; +} + +/* + * @implemented + */ +ULONG +STDCALL +KeQueryRuntimeThread(IN PKTHREAD Thread, + OUT PULONG UserTime) +{ + /* Return the User Time */ + *UserTime = Thread->UserTime; + + /* Return the Kernel Time */ + return Thread->KernelTime; +} + +/* + * @implemented + */ +BOOLEAN +STDCALL +KeSetKernelStackSwapEnable(IN BOOLEAN Enable) +{ + PKTHREAD Thread = KeGetCurrentThread(); + BOOLEAN PreviousState; + KIRQL OldIrql; + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Save Old State */ + PreviousState = Thread->EnableStackSwap; + + /* Set New State */ + Thread->EnableStackSwap = Enable; + + /* No, Release Lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + /* Return Old State */ + return PreviousState; +} + +/* + * @implemented + */ +VOID +STDCALL +KeRevertToUserAffinityThread(VOID) +{ + PKTHREAD CurrentThread = KeGetCurrentThread(); + KIRQL OldIrql; + + ASSERT(CurrentThread->SystemAffinityActive != FALSE); + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Return to User Affinity */ + CurrentThread->Affinity = CurrentThread->UserAffinity; + + /* Disable System Affinity */ + CurrentThread->SystemAffinityActive = FALSE; + + /* Check if we need to Dispatch a New thread */ + if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber())) { + + /* No, just release */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + } else { + + /* We need to dispatch a new thread */ + CurrentThread->WaitIrql = OldIrql; + KiDispatchThreadNoLock(Ready); + KeLowerIrql(OldIrql); + } +} + +/* + * @implemented + */ +UCHAR +STDCALL +KeSetIdealProcessorThread(IN PKTHREAD Thread, + IN UCHAR Processor) +{ + CCHAR PreviousIdealProcessor; + KIRQL OldIrql; + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Save Old Ideal Processor */ + PreviousIdealProcessor = Thread->IdealProcessor; + + /* Set New Ideal Processor */ + Thread->IdealProcessor = Processor; + + /* Release Lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + /* Return Old Ideal Processor */ + return PreviousIdealProcessor; +} + +/* + * @implemented + */ +VOID +STDCALL +KeSetSystemAffinityThread(IN KAFFINITY Affinity) +{ + PKTHREAD CurrentThread = KeGetCurrentThread(); + KIRQL OldIrql; + + ASSERT(Affinity & ((1 << KeNumberProcessors) - 1)); + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Set the System Affinity Specified */ + CurrentThread->Affinity = Affinity; + + /* Enable System Affinity */ + CurrentThread->SystemAffinityActive = TRUE; + + /* Check if we need to Dispatch a New thread */ + if (Affinity & (1 << KeGetCurrentProcessorNumber())) { + + /* No, just release */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + } else { + + /* We need to dispatch a new thread */ + CurrentThread->WaitIrql = OldIrql; + KiDispatchThreadNoLock(Ready); + KeLowerIrql(OldIrql); + } +} + +LONG +STDCALL +KeQueryBasePriorityThread(IN PKTHREAD Thread) +{ + LONG BasePriorityIncrement; + KIRQL OldIrql; + PKPROCESS Process; + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Get the Process */ + Process = Thread->ApcStatePointer[0]->Process; + + /* Calculate the BPI */ + BasePriorityIncrement = Thread->BasePriority - Process->BasePriority; + + /* If saturation occured, return the SI instead */ + if (Thread->Saturation) BasePriorityIncrement = (HIGH_PRIORITY + 1) / 2 * + Thread->Saturation; + + /* Release Lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + /* Return Increment */ + return BasePriorityIncrement; +} + +/* + * @implemented + */ +LONG +STDCALL +KeSetBasePriorityThread(PKTHREAD Thread, + LONG Increment) +{ + KIRQL OldIrql; + PKPROCESS Process; + KPRIORITY Priority; + KPRIORITY CurrentBasePriority; + KPRIORITY BasePriority; + BOOLEAN Released = FALSE; + LONG CurrentIncrement; + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Get the process and calculate current BP and BPI */ + Process = Thread->ApcStatePointer[0]->Process; + CurrentBasePriority = Thread->BasePriority; + CurrentIncrement = CurrentBasePriority - Process->BasePriority; + + /* Change to use the SI if Saturation was used */ + if (Thread->Saturation) CurrentIncrement = (HIGH_PRIORITY + 1) / 2 * + Thread->Saturation; + + /* Now check if saturation is being used for the new value */ + if (abs(Increment) >= ((HIGH_PRIORITY + 1) / 2)) + { + /* Check if we need positive or negative saturation */ + Thread->Saturation = (Increment > 0) ? 1 : -1; + } + + /* Normalize the Base Priority */ + BasePriority = Process->BasePriority + Increment; + if (Process->BasePriority >= LOW_REALTIME_PRIORITY) + { + /* Check if it's too low */ + if (BasePriority < LOW_REALTIME_PRIORITY) + BasePriority = LOW_REALTIME_PRIORITY; + + /* Check if it's too high */ + if (BasePriority > HIGH_PRIORITY) BasePriority = HIGH_PRIORITY; + + /* We are at RTP, so use the raw BP */ + Priority = BasePriority; + } + else + { + /* Check if it's entering RTP */ + if (BasePriority >= LOW_REALTIME_PRIORITY) + BasePriority = LOW_REALTIME_PRIORITY - 1; + + /* Check if it's too low */ + if (BasePriority <= LOW_PRIORITY) + BasePriority = 1; + + /* If Saturation is used, then use the raw BP */ + if (Thread->Saturation) + { + Priority = BasePriority; + } + else + { + /* Calculate the new priority */ + Priority = Thread->Priority + (BasePriority - CurrentBasePriority)- + Thread->PriorityDecrement; + + /* Make sure it won't enter RTP ranges */ + if (Priority >= LOW_REALTIME_PRIORITY) + Priority = LOW_REALTIME_PRIORITY - 1; + } + } + + /* Finally set the new base priority */ + Thread->BasePriority = BasePriority; + + /* Reset the decrements */ + Thread->PriorityDecrement = 0; + + /* If the priority will change, reset quantum and change it for real */ + if (Priority != Thread->Priority) + { + Thread->Quantum = Thread->QuantumReset; + KiSetPriorityThread(Thread, Priority, &Released); + } + + /* Release Lock if needed */ + if (!Released) + { + KeReleaseDispatcherDatabaseLock(OldIrql); + } + else + { + KeLowerIrql(OldIrql); + } + + /* Return the Old Increment */ + return CurrentIncrement; +} + +/* + * @implemented + */ +KPRIORITY +STDCALL +KeSetPriorityThread(PKTHREAD Thread, + KPRIORITY Priority) +{ + KPRIORITY OldPriority; + BOOLEAN Released = FALSE; + KIRQL OldIrql; + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Save the old Priority */ + OldPriority = Thread->Priority; + + /* Reset the Quantum and Decrements */ + Thread->Quantum = Thread->QuantumReset; + Thread->PriorityDecrement = 0; + + /* Set the new Priority */ + KiSetPriorityThread(Thread, Priority, &Released); + + /* Release Lock if needed */ + if (!Released) + { + KeReleaseDispatcherDatabaseLock(OldIrql); + } + else + { + KeLowerIrql(OldIrql); + } + + /* Return Old Priority */ + return OldPriority; +} + +/* + * @implemented + * + * Sets thread's affinity + */ +KAFFINITY +STDCALL +KeSetAffinityThread(PKTHREAD Thread, + KAFFINITY Affinity) +{ + KIRQL OldIrql; + KAFFINITY OldAffinity; + BOOLEAN Released; + + DPRINT("KeSetAffinityThread(Thread %x, Affinity %x)\n", Thread, Affinity); + + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Call the internal function */ + OldAffinity = KiSetAffinityThread(Thread, Affinity, &Released); + + /* Release Lock if needed */ + if (!Released) + { + KeReleaseDispatcherDatabaseLock(OldIrql); + } + else + { + KeLowerIrql(OldIrql); + } + + return OldAffinity; +} + +/* + * @implemented + */ + /* The Increment Argument seems to be ignored by NT and always 0 when called */ +VOID +STDCALL +KeTerminateThread(IN KPRIORITY Increment) +{ + KIRQL OldIrql; + PKTHREAD Thread = KeGetCurrentThread(); + PKPROCESS Process = Thread->ApcState.Process; + PLIST_ENTRY *ListHead; + PETHREAD Entry, SavedEntry; + PETHREAD *ThreadAddr; + DPRINT("Terminating\n"); + + /* Lock the Dispatcher Database and the APC Queue */ + ASSERT_IRQL(DISPATCH_LEVEL); + OldIrql = KeAcquireDispatcherDatabaseLock(); + ASSERT(Thread->SwapBusy == FALSE); + + /* Make sure we won't get Swapped */ + Thread->SwapBusy = TRUE; + + /* Save the Kernel and User Times */ + Process->KernelTime += Thread->KernelTime; + Process->UserTime += Thread->UserTime; + + /* Get the current entry and our Port */ + Entry = (PETHREAD)PspReaperListHead.Flink; + ThreadAddr = &((PETHREAD)Thread)->ReaperLink; + + /* Add it to the reaper's list */ + do + { + /* Get the list head */ + ListHead = &PspReaperListHead.Flink; + + /* Link ourselves */ + *ThreadAddr = Entry; + SavedEntry = Entry; + + /* Now try to do the exchange */ + Entry = InterlockedCompareExchangePointer(ListHead, ThreadAddr, Entry); + + /* Break out if the change was succesful */ + } while (Entry != SavedEntry); + + /* Check if the reaper wasn't active */ + if (!Entry) + { + /* Activate it as a work item, directly through its Queue */ + KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue, + &PspReaperWorkItem.List, + FALSE); + } + + /* Handle Kernel Queues */ + if (Thread->Queue) + { + DPRINT("Waking Queue\n"); + RemoveEntryList(&Thread->QueueListEntry); + KiWakeQueue(Thread->Queue); + } + + /* Signal the thread */ + Thread->DispatcherHeader.SignalState = TRUE; + if (IsListEmpty(&Thread->DispatcherHeader.WaitListHead) != TRUE) + { + /* Satisfy waits */ + KiWaitTest((PVOID)Thread, Increment); + } + + /* Remove the thread from the list */ + RemoveEntryList(&Thread->ThreadListEntry); + + /* Set us as terminated, decrease the Process's stack count */ + Thread->State = Terminated; + Process->StackCount--; + + /* Find a new Thread */ + KiDispatchThreadNoLock(Terminated); +} + +/* + * FUNCTION: Tests whether there are any pending APCs for the current thread + * and if so the APCs will be delivered on exit from kernel mode + */ +BOOLEAN +STDCALL +KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) +{ + KIRQL OldIrql; + PKTHREAD Thread = KeGetCurrentThread(); + BOOLEAN OldState; + + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Lock the Dispatcher Database and the APC Queue */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + KiAcquireSpinLock(&Thread->ApcQueueLock); + + /* Save the old State */ + OldState = Thread->Alerted[AlertMode]; + + /* If the Thread is Alerted, Clear it */ + if (OldState) { + + Thread->Alerted[AlertMode] = FALSE; + + } else if ((AlertMode != KernelMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) { + + /* If the mode is User and the Queue isn't empty, set Pending */ + Thread->ApcState.UserApcPending = TRUE; + } + + /* Release Locks and return the Old State */ + KiReleaseSpinLock(&Thread->ApcQueueLock); + KeReleaseDispatcherDatabaseLock(OldIrql); + return OldState; +} + diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c new file mode 100644 index 00000000000..6cb0601fc9e --- /dev/null +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -0,0 +1,430 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/thrdschd.c + * PURPOSE: Kernel Thread Scheduler (Affinity, Priority, Scheduling) + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY]; +ULONG PriorityListMask = 0; +ULONG KiIdleSummary; +ULONG KiIdleSMTSummary; + +/* FUNCTIONS *****************************************************************/ + +static +VOID +KiRequestReschedule(CCHAR Processor) +{ + PKPCR Pcr; + + Pcr = (PKPCR)(KPCR_BASE + Processor * PAGE_SIZE); + Pcr->Prcb->QuantumEnd = TRUE; + KiIpiSendRequest(1 << Processor, IPI_DPC); +} + +static +VOID +KiInsertIntoThreadList(KPRIORITY Priority, + PKTHREAD Thread) +{ + ASSERT(Ready == Thread->State); + ASSERT(Thread->Priority == Priority); + + if (Priority >= MAXIMUM_PRIORITY || Priority < LOW_PRIORITY) { + + DPRINT1("Invalid thread priority (%d)\n", Priority); + KEBUGCHECK(0); + } + + InsertTailList(&PriorityListHead[Priority], &Thread->WaitListEntry); + PriorityListMask |= (1 << Priority); +} + +static +VOID +KiRemoveFromThreadList(PKTHREAD Thread) +{ + ASSERT(Ready == Thread->State); + RemoveEntryList(&Thread->WaitListEntry); + if (IsListEmpty(&PriorityListHead[(ULONG)Thread->Priority])) { + + PriorityListMask &= ~(1 << Thread->Priority); + } +} + +static +PKTHREAD +KiScanThreadList(KPRIORITY Priority, + KAFFINITY Affinity) +{ + PKTHREAD current; + ULONG Mask; + + Mask = (1 << Priority); + + if (PriorityListMask & Mask) { + + LIST_FOR_EACH(current, &PriorityListHead[Priority], KTHREAD, WaitListEntry) { + + if (current->State != Ready) { + + DPRINT1("%p/%d\n", current, current->State); + } + + ASSERT(current->State == Ready); + + if (current->Affinity & Affinity) { + + KiRemoveFromThreadList(current); + return(current); + } + } + } + + return(NULL); +} + +BOOLEAN +STDCALL +KiDispatchThreadNoLock(ULONG NewThreadStatus) +{ + KPRIORITY CurrentPriority; + PKTHREAD Candidate; + ULONG Affinity; + PKTHREAD CurrentThread = KeGetCurrentThread(); + BOOLEAN ApcState; + + DPRINT("KiDispatchThreadNoLock() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(), + CurrentThread, NewThreadStatus, CurrentThread->State); + + CurrentThread->State = (UCHAR)NewThreadStatus; + + if (NewThreadStatus == Ready) { + + KiInsertIntoThreadList(CurrentThread->Priority, + CurrentThread); + } + + Affinity = 1 << KeGetCurrentProcessorNumber(); + + for (CurrentPriority = HIGH_PRIORITY; CurrentPriority >= LOW_PRIORITY; CurrentPriority--) { + + Candidate = KiScanThreadList(CurrentPriority, Affinity); + + if (Candidate == CurrentThread) { + + Candidate->State = Running; + KeReleaseDispatcherDatabaseLockFromDpcLevel(); + return FALSE; + } + + if (Candidate != NULL) { + + PKTHREAD OldThread; + PKTHREAD IdleThread; + + DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority); + + Candidate->State = Running; + + OldThread = CurrentThread; + CurrentThread = Candidate; + IdleThread = KeGetCurrentPrcb()->IdleThread; + + if (OldThread == IdleThread) { + + KiIdleSummary &= ~Affinity; + + } else if (CurrentThread == IdleThread) { + + KiIdleSummary |= Affinity; + } + + MmUpdatePageDir((PEPROCESS)PsGetCurrentProcess(),((PETHREAD)CurrentThread)->ThreadsProcess, sizeof(EPROCESS)); + + /* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */ + DPRINT("You are : %x, swapping to: %x.\n", OldThread, CurrentThread); + ApcState = KiSwapContext(OldThread, CurrentThread); + DPRINT("You are : %x, swapped from: %x\n", OldThread, CurrentThread); + return ApcState; + } + } + + DPRINT1("CRITICAL: No threads are ready (CPU%d)\n", KeGetCurrentProcessorNumber()); + KEBUGCHECK(0); + return FALSE; +} + +NTSTATUS +FASTCALL +KiSwapThread(IN PKTHREAD CurrentThread, + IN PKPRCB Prcb) +{ + BOOLEAN ApcState; + + /* Find a new thread to run */ + DPRINT("Dispatching Thread as blocked\n"); + ApcState = KiDispatchThreadNoLock(Waiting); + + /* Check if we need to deliver APCs */ + if (ApcState) + { + /* Lower to APC_LEVEL */ + KeLowerIrql(APC_LEVEL); + + /* Deliver APCs */ + KiDeliverApc(KernelMode, NULL, NULL); + ASSERT(CurrentThread->WaitIrql == 0); + } + + /* Lower IRQL back to what it was */ + KfLowerIrql(CurrentThread->WaitIrql); + + /* Return the wait status */ + return CurrentThread->WaitStatus; +} + +VOID +STDCALL +KiDispatchThread(ULONG NewThreadStatus) +{ + KIRQL OldIrql; + + if (KeGetCurrentPrcb()->IdleThread == NULL) { + return; + } + + OldIrql = KeAcquireDispatcherDatabaseLock(); + KiDispatchThreadNoLock(NewThreadStatus); + KeLowerIrql(OldIrql); +} + +VOID +NTAPI +KiReadyThread(IN PKTHREAD Thread) +{ + /* Makes a thread ready */ + Thread->State = Ready; + KiInsertIntoThreadList(Thread->Priority, Thread); +} + +VOID +STDCALL +KiAdjustQuantumThread(IN PKTHREAD Thread) +{ + KPRIORITY Priority; + + /* Don't adjust for RT threads */ + if ((Thread->Priority < LOW_REALTIME_PRIORITY) && + Thread->BasePriority < LOW_REALTIME_PRIORITY - 2) + { + /* Decrease Quantum by one and see if we've ran out */ + if (--Thread->Quantum <= 0) + { + /* Return quantum */ + Thread->Quantum = Thread->QuantumReset; + + /* Calculate new Priority */ + Priority = Thread->Priority - (Thread->PriorityDecrement + 1); + + /* Normalize it if we've gone too low */ + if (Priority < Thread->BasePriority) Priority = Thread->BasePriority; + + /* Reset the priority decrement, we've done it */ + Thread->PriorityDecrement = 0; + + /* Set the new priority, if needed */ + if (Priority != Thread->Priority) + { + /* + * FIXME: This should be a call to KiSetPriorityThread but + * due to the current ""scheduler"" in ROS, it can't be done + * cleanly since it actualyl dispatches threads instead. + */ + Thread->Priority = Priority; + } + else + { + /* FIXME: Priority hasn't changed, find a new thread */ + } + } + } + + /* Nothing to do... */ + return; +} + +VOID +STDCALL +KiSetPriorityThread(PKTHREAD Thread, + KPRIORITY Priority, + PBOOLEAN Released) +{ + KPRIORITY OldPriority = Thread->Priority; + ULONG Mask; + int i; + PKPCR Pcr; + DPRINT("Changing prio to : %lx\n", Priority); + + /* Check if priority changed */ + if (OldPriority != Priority) + { + /* Set it */ + Thread->Priority = Priority; + + /* Choose action based on thread's state */ + if (Thread->State == Ready) + { + /* Remove it from the current queue */ + KiRemoveFromThreadList(Thread); + + /* Re-insert it at its current priority */ + KiInsertIntoThreadList(Priority, Thread); + + /* Check if the old priority was lower */ + if (KeGetCurrentThread()->Priority < Priority) + { + /* Dispatch it immediately */ + KiDispatchThreadNoLock(Ready); + *Released = TRUE; + return; + } + } + else if (Thread->State == Running) + { + /* Check if the new priority is lower */ + if (Priority < OldPriority) + { + /* Check for threads with a higher priority */ + Mask = ~((1 << (Priority + 1)) - 1); + if (PriorityListMask & Mask) + { + /* Found a thread, is it us? */ + if (Thread == KeGetCurrentThread()) + { + /* Dispatch us */ + KiDispatchThreadNoLock(Ready); + *Released = TRUE; + return; + } + else + { + /* Loop every CPU */ + for (i = 0; i < KeNumberProcessors; i++) + { + /* Get the PCR for this CPU */ + Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); + + /* Reschedule if the new one is already on a CPU */ + if (Pcr->Prcb->CurrentThread == Thread) + { + KeReleaseDispatcherDatabaseLockFromDpcLevel(); + KiRequestReschedule(i); + *Released = TRUE; + return; + } + } + } + } + } + } + } + + /* Return to caller */ + return; +} + +KAFFINITY +NTAPI +KiSetAffinityThread(IN PKTHREAD Thread, + IN KAFFINITY Affinity, + PBOOLEAN Released) +{ + KAFFINITY OldAffinity; + ULONG ProcessorMask; + ULONG i; + PKPCR Pcr; + + /* Make sure that the affinity is valid */ + if (((Affinity & Thread->ApcState.Process->Affinity) != (Affinity)) || + (!Affinity)) + { + /* Bugcheck the system */ + KeBugCheck(INVALID_AFFINITY_SET); + } + + /* Get the old affinity */ + OldAffinity = Thread->UserAffinity; + + Thread->UserAffinity = Affinity; + + if (Thread->SystemAffinityActive == FALSE) { + + Thread->Affinity = Affinity; + + if (Thread->State == Running) { + + ProcessorMask = 1 << KeGetCurrentProcessorNumber(); + if (Thread == KeGetCurrentThread()) { + + if (!(Affinity & ProcessorMask)) { + + KiDispatchThreadNoLock(Ready); + *Released = TRUE; + return OldAffinity; + } + + } else { + + for (i = 0; i < KeNumberProcessors; i++) { + + Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); + if (Pcr->Prcb->CurrentThread == Thread) { + + if (!(Affinity & ProcessorMask)) { + + KeReleaseDispatcherDatabaseLockFromDpcLevel(); + KiRequestReschedule(i); + *Released = TRUE; + return OldAffinity; + } + + break; + } + } + + ASSERT (i < KeNumberProcessors); + } + } + } + + *Released = FALSE; + return OldAffinity; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtYieldExecution(VOID) +{ + // + // TODO (nothing too hard, just want to test out other code) + // + //DPRINT1("NO YIELD PERFORMED! If you see this, contact Alex\n"); + //return STATUS_NO_YIELD_PERFORMED; + KiDispatchThread(Ready); + return STATUS_SUCCESS; +} + diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 06bd18c4996..24bd29abbfb 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -861,4 +861,41 @@ DontWait: return WaitStatus; } +NTSTATUS +NTAPI +NtDelayExecution(IN BOOLEAN Alertable, + IN PLARGE_INTEGER DelayInterval) +{ + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + LARGE_INTEGER SafeInterval; + NTSTATUS Status = STATUS_SUCCESS; + + /* Check if parameters are valid */ + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + /* make a copy on the kernel stack and let DelayInterval point to it so + we don't need to wrap KeDelayExecutionThread in SEH! */ + SafeInterval = ProbeForReadLargeInteger(DelayInterval); + DelayInterval = &SafeInterval; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) return Status; + } + + /* Call the Kernel Function */ + Status = KeDelayExecutionThread(PreviousMode, + Alertable, + DelayInterval); + + /* Return Status */ + return Status; +} + /* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index a936e40a59e..d21d1cee21a 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -57,13 +57,14 @@ ipi.c kqueue.c krnlinit.c - kthread.c mutex.c process.c profile.c queue.c sem.c spinlock.c + thrdschd.c + thrdobj.c timer.c usercall.c wait.c diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index c8dfa3ab97b..3ac6d69fc3a 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1077,15 +1077,4 @@ NtOpenThread(OUT PHANDLE ThreadHandle, return Status; } -/* - * @implemented - */ -NTSTATUS -NTAPI -NtYieldExecution(VOID) -{ - KiDispatchThread(Ready); - return STATUS_SUCCESS; -} - /* EOF */ From 2ca81c55739bcca3f3c081046e835ad5686d2a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 10 Sep 2006 15:26:48 +0000 Subject: [PATCH 111/488] Fix some warnings svn path=/trunk/; revision=24025 --- reactos/lib/cmlib/cmlib.mak | 2 +- reactos/lib/cmlib/hivebin.c | 8 ++++---- reactos/lib/cmlib/hivecell.c | 14 +++++++------- reactos/lib/rtl/bitmap.c | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/reactos/lib/cmlib/cmlib.mak b/reactos/lib/cmlib/cmlib.mak index 076a7925853..0b83185cb60 100644 --- a/reactos/lib/cmlib/cmlib.mak +++ b/reactos/lib/cmlib/cmlib.mak @@ -31,7 +31,7 @@ CMLIB_HOST_OBJECTS = \ $(subst $(CMLIB_BASE), $(CMLIB_INT), $(CMLIB_HOST_SOURCES:.c=.o)) CMLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ - -D_X86_ -D__i386__ -D_REACTOS_ \ + -D_X86_ -D__i386__ -D_REACTOS_ -D_NTOSKRNL_\ -DCMLIB_HOST -D_M_IX86 -I$(CMLIB_BASE) -Iinclude/reactos -Iinclude/psdk -Iinclude/ddk \ -D__NO_CTYPE_INLINES diff --git a/reactos/lib/cmlib/hivebin.c b/reactos/lib/cmlib/hivebin.c index 29e74b925ae..5a70b8d4aa1 100644 --- a/reactos/lib/cmlib/hivebin.c +++ b/reactos/lib/cmlib/hivebin.c @@ -24,17 +24,17 @@ HvpAddBin( PHCELL Block; BinSize = ROUND_UP(Size + sizeof(HBIN), HV_BLOCK_SIZE); - BlockCount = BinSize / HV_BLOCK_SIZE; + BlockCount = (ULONG)(BinSize / HV_BLOCK_SIZE); Bin = RegistryHive->Allocate(BinSize, TRUE); if (Bin == NULL) return NULL; - RtlZeroMemory(Bin, sizeof(HBIN)); + RtlZeroMemory(Bin, BinSize); Bin->Signature = HV_BIN_SIGNATURE; Bin->FileOffset = RegistryHive->Storage[Storage].Length * HV_BLOCK_SIZE; - Bin->Size = BinSize; + Bin->Size = (ULONG)BinSize; /* Allocate new block list */ OldBlockListSize = RegistryHive->Storage[Storage].Length; @@ -65,7 +65,7 @@ HvpAddBin( /* Initialize a free block in this heap. */ Block = (PHCELL)(Bin + 1); - Block->Size = BinSize - sizeof(HBIN); + Block->Size = (LONG)(BinSize - sizeof(HBIN)); if (Storage == HvStable) { diff --git a/reactos/lib/cmlib/hivecell.c b/reactos/lib/cmlib/hivecell.c index ce341276d39..d829bc895f3 100644 --- a/reactos/lib/cmlib/hivecell.c +++ b/reactos/lib/cmlib/hivecell.c @@ -202,7 +202,7 @@ HvpFindFree( while (*pFreeCellOffset != HCELL_NULL) { FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset); - if (HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size) + if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size) { FreeCellOffset = *pFreeCellOffset; *pFreeCellOffset = *FreeCellData; @@ -299,7 +299,7 @@ HvAllocateCell( /* Split the block in two parts */ /* FIXME: There is some minimal cell size that we must respect. */ - if (FreeCell->Size > Size + sizeof(HCELL_INDEX)) + if ((ULONG)FreeCell->Size > Size + sizeof(HCELL_INDEX)) { NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size); NewCell->Size = FreeCell->Size - Size; @@ -344,7 +344,7 @@ HvReallocateCell( * FIXME: Merge with adjacent free cell if possible. * FIXME: Implement shrinking. */ - if (Size > -OldCellSize) + if (Size > (ULONG)-OldCellSize) { NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage); if (NewCellIndex == HCELL_NULL) @@ -393,8 +393,8 @@ HvFreeCell( if (Neighbor->Size > 0) { HvpRemoveFree(RegistryHive, Neighbor, - ((HCELL_INDEX)Neighbor - (HCELL_INDEX)Bin + - Bin->FileOffset) | (CellIndex & HCELL_TYPE_MASK)); + ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin + + Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK)); Free->Size += Neighbor->Size; } } @@ -409,8 +409,8 @@ HvFreeCell( Neighbor->Size += Free->Size; if (CellType == HvStable) HvMarkCellDirty(RegistryHive, - (HCELL_INDEX)Neighbor - (HCELL_INDEX)Bin + - Bin->FileOffset); + (HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin + + Bin->FileOffset)); return; } Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size); diff --git a/reactos/lib/rtl/bitmap.c b/reactos/lib/rtl/bitmap.c index 98514ae85fd..feb742e0054 100644 --- a/reactos/lib/rtl/bitmap.c +++ b/reactos/lib/rtl/bitmap.c @@ -874,7 +874,7 @@ RtlTestBit(PRTL_BITMAP BitMapHeader, Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32); - return (*Ptr & (1 << (BitNumber % 32))); + return (BOOLEAN)(*Ptr & (1 << (BitNumber % 32))); } /* @@ -923,7 +923,7 @@ CCHAR WINAPI RtlFindMostSignificantBit(ULONGLONG ulLong) signed char ret = 32; DWORD dw; - if (!(dw = (ulLong >> 32))) + if (!(dw = (DWORD)(ulLong >> 32))) { ret = 0; dw = (DWORD)ulLong; @@ -957,7 +957,7 @@ CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG ulLong) if (!(dw = (DWORD)ulLong)) { ret = 32; - if (!(dw = ulLong >> 32)) return -1; + if (!(dw = (DWORD)(ulLong >> 32))) return -1; } if (!(dw & 0xffff)) { From 6702dd5240e1a0138f20af804f27a6be4d330280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 10 Sep 2006 15:39:11 +0000 Subject: [PATCH 112/488] Let mkhive use cmlib. "make install" now works and this let the livecd go further than before svn path=/trunk/; revision=24026 --- reactos/tools/mkhive/binhive.c | 1416 +------------------------------ reactos/tools/mkhive/binhive.h | 12 +- reactos/tools/mkhive/cmi.c | 791 +++++++++++++++++ reactos/tools/mkhive/cmi.h | 67 ++ reactos/tools/mkhive/mkhive.c | 47 +- reactos/tools/mkhive/mkhive.h | 46 +- reactos/tools/mkhive/mkhive.mak | 134 +-- reactos/tools/mkhive/reginf.c | 71 +- reactos/tools/mkhive/reginf.h | 11 +- reactos/tools/mkhive/registry.c | 1154 ++++++++++++------------- reactos/tools/mkhive/registry.h | 198 ++--- reactos/tools/mkhive/rtl.c | 143 ++++ 12 files changed, 1813 insertions(+), 2277 deletions(-) create mode 100644 reactos/tools/mkhive/cmi.c create mode 100644 reactos/tools/mkhive/cmi.h create mode 100644 reactos/tools/mkhive/rtl.c diff --git a/reactos/tools/mkhive/binhive.c b/reactos/tools/mkhive/binhive.c index cc50be3e865..cf17a8bb91e 100644 --- a/reactos/tools/mkhive/binhive.c +++ b/reactos/tools/mkhive/binhive.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2003, 2004 ReactOS Team + * Copyright (C) 2006 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 @@ -16,1421 +16,43 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS hive maker * FILE: tools/mkhive/binhive.c * PURPOSE: Binary hive export code - * PROGRAMMER: Eric Kohl + * PROGRAMMER: Hervé Poussineau */ /* INCLUDES *****************************************************************/ -//#include -#include #include -#include #include "mkhive.h" -#include "binhive.h" -#include "registry.h" - - -#define REG_HIVE_ID 0x66676572 -#define REG_BIN_ID 0x6e696268 -#define REG_KEY_CELL_ID 0x6b6e -#define REG_HASH_TABLE_CELL_ID 0x666c -#define REG_VALUE_CELL_ID 0x6b76 - -#define REG_BLOCK_SIZE 4096 -#define REG_HBIN_DATA_OFFSET 32 -#define REG_INIT_BLOCK_LIST_SIZE 32 -#define REG_INIT_HASH_TABLE_SIZE 3 -#define REG_EXTEND_HASH_TABLE_SIZE 4 -#define REG_VALUE_LIST_CELL_MULTIPLE 4 - -#define ROUND_UP_POW2(N,S) (((N) + (S) - 1) & ~((S) - 1)) -#define ROUND_DOWN_POW2(N,S) ((N) & ~((S) - 1)) - -#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V)) - - -// BLOCK_OFFSET = offset in file after header block -typedef ULONG BLOCK_OFFSET, *PBLOCK_OFFSET; - -#ifdef _MSC_VER -typedef unsigned __int64 FILETIME; -#else -typedef unsigned long long FILETIME; -#endif - -#ifdef _MSC_VER -#pragma pack ( push, hive_header, 1 ) -#endif//_MSC_VER - -/* header for registry hive file : */ -typedef struct _HIVE_HEADER -{ - /* Hive identifier "regf" (0x66676572) */ - ULONG BlockId; - - /* Update counter */ - ULONG UpdateCounter1; - - /* Update counter */ - ULONG UpdateCounter2; - - /* When this hive file was last modified */ - FILETIME DateModified; - - /* Registry format major version (1) */ - ULONG MajorVersion; - - /* Registry format minor version (3) - Version 3 added fast indexes, version 5 has large value optimizations */ - ULONG MinorVersion; - - /* Registry file type (0 - Primary, 1 - Log) */ - ULONG Type; - - /* Registry format (1 is the only defined value so far) */ - ULONG Format; - - /* Offset into file from the byte after the end of the base block. - If the hive is volatile, this is the actual pointer to the KEY_CELL */ - BLOCK_OFFSET RootKeyOffset; - - /* Size of each hive block ? */ - ULONG BlockSize; - - /* (1?) */ - ULONG Unused7; - - /* Name of hive file */ - WCHAR FileName[32]; - - ULONG Reserved[99]; - - /* Checksum of first 0x200 bytes */ - ULONG Checksum; -} GCC_PACKED HIVE_HEADER, *PHIVE_HEADER; - -typedef struct _HBIN -{ - /* Bin identifier "hbin" (0x6E696268) */ - ULONG HeaderId; - - /* Block offset of this bin */ - BLOCK_OFFSET BinOffset; - - /* Size in bytes, multiple of the block size (4KB) */ - ULONG BinSize; - - ULONG Reserved[2]; - - /* When this bin was last modified */ - FILETIME DateModified; - - /* ? (In-memory only) */ - ULONG MemAlloc; -} GCC_PACKED HBIN, *PHBIN; - -typedef struct _CELL_HEADER -{ - /* <0 if used, >0 if free */ - LONG CellSize; -} GCC_PACKED CELL_HEADER, *PCELL_HEADER; - -typedef struct _KEY_CELL -{ - /* Size of this cell */ - LONG CellSize; - - /* Key cell identifier "kn" (0x6b6e) */ - USHORT Id; - - /* ? */ - USHORT Type; - - /* Time of last flush */ - FILETIME LastWriteTime; - - /* ? */ - ULONG UnUsed1; - - /* Block offset of parent key cell */ - BLOCK_OFFSET ParentKeyOffset; - - /* Count of sub keys for the key in this key cell */ - ULONG NumberOfSubKeys; - - /* ? */ - ULONG UnUsed2; - - /* Block offset of has table for FIXME: subkeys/values? */ - BLOCK_OFFSET HashTableOffset; - - /* ? */ - ULONG UnUsed3; - - /* Count of values contained in this key cell */ - ULONG NumberOfValues; - - /* Block offset of VALUE_LIST_CELL */ - BLOCK_OFFSET ValueListOffset; - - /* Block offset of security cell */ - BLOCK_OFFSET SecurityKeyOffset; - - /* Block offset of registry key class */ - BLOCK_OFFSET ClassNameOffset; - - /* ? */ - ULONG Unused4[5]; - - /* Size in bytes of key name */ - USHORT NameSize; - - /* Size of class name in bytes */ - USHORT ClassSize; - - /* Name of key (not zero terminated) */ - CHAR Name[0]; -} GCC_PACKED KEY_CELL, *PKEY_CELL; - -/* KEY_CELL.Type constants */ -#define REG_LINK_KEY_CELL_TYPE 0x10 -#define REG_KEY_CELL_TYPE 0x20 -#define REG_ROOT_KEY_CELL_TYPE 0x2c - - -// hash record : -// HashValue=four letters of value's name -typedef struct _HASH_RECORD -{ - BLOCK_OFFSET KeyOffset; - ULONG HashValue; -} GCC_PACKED HASH_RECORD, *PHASH_RECORD; - -typedef struct _HASH_TABLE_CELL -{ - LONG CellSize; - USHORT Id; - USHORT HashTableSize; - HASH_RECORD Table[0]; -} GCC_PACKED HASH_TABLE_CELL, *PHASH_TABLE_CELL; - -typedef struct _VALUE_LIST_CELL -{ - LONG CellSize; - BLOCK_OFFSET ValueOffset[0]; -} GCC_PACKED VALUE_LIST_CELL, *PVALUE_LIST_CELL; - -typedef struct _VALUE_CELL -{ - LONG CellSize; - USHORT Id; // "kv" - USHORT NameSize; // length of Name - ULONG DataSize; // length of datas in the cell pointed by DataOffset - BLOCK_OFFSET DataOffset;// datas are here if high bit of DataSize is set - ULONG DataType; - USHORT Flags; - USHORT Unused1; - CHAR Name[0]; /* warning : not zero terminated */ -} GCC_PACKED VALUE_CELL, *PVALUE_CELL; - -/* VALUE_CELL.Flags constants */ -#define REG_VALUE_NAME_PACKED 0x0001 - -/* VALUE_CELL.DataSize mask constants */ -#define REG_DATA_SIZE_MASK 0x7FFFFFFF -#define REG_DATA_IN_OFFSET 0x80000000 - -typedef struct _DATA_CELL -{ - LONG CellSize; - CHAR Data[0]; -} GCC_PACKED DATA_CELL, *PDATA_CELL; - -#ifdef _MSC_VER -#pragma pack ( pop, hive_header ) -#endif//_MSC_VER - -typedef struct _REGISTRY_HIVE -{ - ULONG FileSize; - PHIVE_HEADER HiveHeader; - ULONG BlockListSize; - PHBIN *BlockList; - ULONG FreeListSize; - ULONG FreeListMax; - PCELL_HEADER *FreeList; - BLOCK_OFFSET *FreeListOffset; -} REGISTRY_HIVE, *PREGISTRY_HIVE; - -/* FUNCTIONS ****************************************************************/ - -static VOID -memexpand (PWCHAR Dst, - PCHAR Src, - ULONG Length) -{ - ULONG i; - - for (i = 0; i < Length; i++) - Dst[i] = (WCHAR)Src[i]; -} - - -static VOID -CmiCreateDefaultHiveHeader (PHIVE_HEADER Header) -{ - assert (Header); - memset (Header, 0, REG_BLOCK_SIZE); - Header->BlockId = REG_HIVE_ID; - Header->UpdateCounter1 = 0; - Header->UpdateCounter2 = 0; - Header->DateModified = 0; - Header->MajorVersion = 1; - Header->MinorVersion = 3; - Header->Type = 0; - Header->Format = 1; - Header->Unused7 = 1; - Header->RootKeyOffset = -1; - Header->BlockSize = REG_BLOCK_SIZE; - Header->Checksum = 0; -} - - -static VOID -CmiCreateDefaultBinCell(PHBIN BinCell) -{ - assert (BinCell); - memset (BinCell, 0, REG_BLOCK_SIZE); - BinCell->HeaderId = REG_BIN_ID; - BinCell->DateModified = 0; - BinCell->BinSize = REG_BLOCK_SIZE; -} - - -static VOID -CmiCreateDefaultRootKeyCell(PKEY_CELL RootKeyCell, PCHAR KeyName) -{ - PCHAR BaseKeyName; - USHORT NameSize; - ULONG CellSize; - - assert (RootKeyCell); - - BaseKeyName = strrchr(KeyName, '\\') + 1; - NameSize = strlen(BaseKeyName); - CellSize = ROUND_UP_POW2(sizeof(KEY_CELL) + NameSize - 1, 16); - - memset (RootKeyCell, 0, CellSize); - RootKeyCell->CellSize = (ULONG)-(LONG)CellSize; - RootKeyCell->Id = REG_KEY_CELL_ID; - RootKeyCell->Type = REG_ROOT_KEY_CELL_TYPE; - RootKeyCell->LastWriteTime = 0; - RootKeyCell->ParentKeyOffset = 0; - RootKeyCell->NumberOfSubKeys = 0; - RootKeyCell->HashTableOffset = -1; - RootKeyCell->NumberOfValues = 0; - RootKeyCell->ValueListOffset = -1; - RootKeyCell->SecurityKeyOffset = 0; - RootKeyCell->ClassNameOffset = -1; - RootKeyCell->NameSize = NameSize; - RootKeyCell->ClassSize = 0; - memcpy (RootKeyCell->Name, - BaseKeyName, - NameSize); -} - - -static PREGISTRY_HIVE -CmiCreateRegistryHive (PCHAR KeyName) -{ - PREGISTRY_HIVE Hive; - PCELL_HEADER FreeCell; - PKEY_CELL RootKeyCell; - PHBIN BinCell; - - Hive = (PREGISTRY_HIVE) malloc (sizeof(REGISTRY_HIVE)); - if (Hive == NULL) - { - return NULL; - } - memset (Hive, 0, sizeof(REGISTRY_HIVE)); - - DPRINT("Hive %p\n", Hive); - - /* Create hive beader (aka 'base block') */ - Hive->HiveHeader = (PHIVE_HEADER) malloc (REG_BLOCK_SIZE); - if (Hive->HiveHeader == NULL) - { - free (Hive); - return NULL; - } - CmiCreateDefaultHiveHeader (Hive->HiveHeader); - Hive->FileSize = REG_BLOCK_SIZE; - - /* Allocate block list */ - Hive->BlockListSize = 1; - Hive->BlockList = malloc (sizeof(PHBIN) * Hive->BlockListSize); - if (Hive->BlockList == NULL) - { - free (Hive->HiveHeader); - free (Hive); - return NULL; - } - - /* Allocate free cell list */ - Hive->FreeListMax = 32; - Hive->FreeList = malloc(sizeof(PCELL_HEADER) * Hive->FreeListMax); - if (Hive->FreeList == NULL) - { - free (Hive->BlockList); - free (Hive->HiveHeader); - free (Hive); - return NULL; - } - Hive->FreeListOffset = malloc(sizeof(BLOCK_OFFSET) * Hive->FreeListMax); - if (Hive->FreeListOffset == NULL) - { - free (Hive->FreeList); - free (Hive->BlockList); - free (Hive->HiveHeader); - free (Hive); - return NULL; - } - - /* Allocate first bin */ - Hive->BlockList[0] = (PHBIN) malloc (REG_BLOCK_SIZE); - if (Hive->BlockList[0] == NULL) - { - free (Hive->FreeListOffset); - free (Hive->FreeList); - free (Hive->BlockList); - free (Hive->HiveHeader); - free (Hive); - return NULL; - } - Hive->FileSize += REG_BLOCK_SIZE; - - /* Init first bin */ - BinCell = (PHBIN)Hive->BlockList[0]; - CmiCreateDefaultBinCell (BinCell); - BinCell->BinOffset = 0; - - /* Init root key cell */ - RootKeyCell = (PKEY_CELL)((ULONG_PTR)BinCell + REG_HBIN_DATA_OFFSET); - CmiCreateDefaultRootKeyCell (RootKeyCell, KeyName); - Hive->HiveHeader->RootKeyOffset = REG_HBIN_DATA_OFFSET; - - /* Init free cell */ - FreeCell = (PCELL_HEADER)((ULONG_PTR)RootKeyCell - RootKeyCell->CellSize); - FreeCell->CellSize = REG_BLOCK_SIZE - (REG_HBIN_DATA_OFFSET - RootKeyCell->CellSize); - - Hive->FreeList[0] = FreeCell; - Hive->FreeListOffset[0] = REG_HBIN_DATA_OFFSET - RootKeyCell->CellSize; - Hive->FreeListSize++; - - return Hive; -} - - -static VOID -CmiDestroyRegistryHive (PREGISTRY_HIVE Hive) -{ - PHBIN Bin; - ULONG i; - - if (Hive == NULL) - return; - - /* Release free offset list */ - if (Hive->FreeListOffset != NULL) - free (Hive->FreeListOffset); - - /* Release free list */ - if (Hive->FreeList != NULL) - free (Hive->FreeList); - - if (Hive->BlockList != NULL) - { - /* Release bins */ - Bin = NULL; - for (i = 0; i < Hive->BlockListSize; i++) - { - if ((Hive->BlockList[i] != NULL) && - (Hive->BlockList[i] != Bin)) - { - Bin = Hive->BlockList[i]; - - DPRINT ("Bin[%lu]: Offset 0x%lx Size 0x%lx\n", - i, Bin->BinOffset, Bin->BinSize); - - free (Bin); - } - } - - /* Release block list */ - free (Hive->BlockList); - } - - /* Release hive header */ - if (Hive->HiveHeader != NULL) - free (Hive->HiveHeader); - - /* Release hive */ - free (Hive); -} - - -static PVOID -CmiGetCell (PREGISTRY_HIVE Hive, - BLOCK_OFFSET BlockOffset, - PHBIN * ppBin) -{ - PHBIN pBin; - ULONG BlockIndex; - - if (ppBin) - *ppBin = NULL; - - if (BlockOffset == (ULONG_PTR) -1) - return NULL; - - BlockIndex = BlockOffset / 4096; - if (BlockIndex >= Hive->BlockListSize) - return NULL; - - pBin = Hive->BlockList[BlockIndex]; - if (ppBin) - *ppBin = pBin; - - return (PVOID)((ULONG_PTR)pBin + (BlockOffset - pBin->BinOffset)); -} - - -static BOOL -CmiMergeFree(PREGISTRY_HIVE RegistryHive, - PCELL_HEADER FreeBlock, - BLOCK_OFFSET FreeOffset) -{ - BLOCK_OFFSET BlockOffset; - BLOCK_OFFSET BinOffset; - ULONG BlockSize; - ULONG BinSize; - PHBIN Bin; - ULONG i; - - DPRINT("CmiMergeFree(Block %p Offset %lx Size %lx) called\n", - FreeBlock, FreeOffset, FreeBlock->CellSize); - - CmiGetCell (RegistryHive, - FreeOffset, - &Bin); - DPRINT("Bin %p\n", Bin); - if (Bin == NULL) - return FALSE; - - BinOffset = Bin->BinOffset; - BinSize = Bin->BinSize; - DPRINT("Bin %p Offset %lx Size %lx\n", Bin, BinOffset, BinSize); - - for (i = 0; i < RegistryHive->FreeListSize; i++) - { - BlockOffset = RegistryHive->FreeListOffset[i]; - BlockSize = RegistryHive->FreeList[i]->CellSize; - if (BlockOffset > BinOffset && - BlockOffset < BinOffset + BinSize) - { - DPRINT("Free block: Offset %lx Size %lx\n", - BlockOffset, BlockSize); - - if ((i < (RegistryHive->FreeListSize - 1)) && - (BlockOffset + BlockSize == FreeOffset) && - (FreeOffset + FreeBlock->CellSize == RegistryHive->FreeListOffset[i + 1])) - { - DPRINT("Merge current block with previous and next block\n"); - - RegistryHive->FreeList[i]->CellSize += - (FreeBlock->CellSize + RegistryHive->FreeList[i + 1]->CellSize); - - FreeBlock->CellSize = 0; - RegistryHive->FreeList[i + 1]->CellSize = 0; - - - if ((i + 2) < RegistryHive->FreeListSize) - { - memmove (&RegistryHive->FreeList[i + 1], - &RegistryHive->FreeList[i + 2], - sizeof(RegistryHive->FreeList[0]) - * (RegistryHive->FreeListSize - i - 2)); - memmove (&RegistryHive->FreeListOffset[i + 1], - &RegistryHive->FreeListOffset[i + 2], - sizeof(RegistryHive->FreeListOffset[0]) - * (RegistryHive->FreeListSize - i - 2)); - } - RegistryHive->FreeListSize--; - - return TRUE; - } - else if (BlockOffset + BlockSize == FreeOffset) - { - DPRINT("Merge current block with previous block\n"); - - RegistryHive->FreeList[i]->CellSize += FreeBlock->CellSize; - FreeBlock->CellSize = 0; - - return TRUE; - } - else if (FreeOffset + FreeBlock->CellSize == BlockOffset) - { - DPRINT("Merge current block with next block\n"); - - FreeBlock->CellSize += RegistryHive->FreeList[i]->CellSize; - RegistryHive->FreeList[i]->CellSize = 0; - RegistryHive->FreeList[i] = FreeBlock; - RegistryHive->FreeListOffset[i] = FreeOffset; - - return TRUE; - } - } - } - - return FALSE; -} - - -static BOOL -CmiAddFree(PREGISTRY_HIVE RegistryHive, - PCELL_HEADER FreeBlock, - BLOCK_OFFSET FreeOffset, - BOOL MergeFreeBlocks) -{ - PCELL_HEADER *tmpList; - BLOCK_OFFSET *tmpListOffset; - LONG minInd; - LONG maxInd; - LONG medInd; - - assert(RegistryHive); - assert(FreeBlock); - - DPRINT("FreeBlock %p FreeOffset %.08lx\n", - FreeBlock, FreeOffset); - - /* Merge free blocks */ - if (MergeFreeBlocks == TRUE) - { - if (CmiMergeFree(RegistryHive, FreeBlock, FreeOffset)) - return TRUE; - } - - if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax) - { - tmpList = malloc (sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32)); - if (tmpList == NULL) - { - return FALSE; - } - - tmpListOffset = malloc (sizeof(BLOCK_OFFSET) * (RegistryHive->FreeListMax + 32)); - if (tmpListOffset == NULL) - { - free (tmpList); - return FALSE; - } - - if (RegistryHive->FreeListMax) - { - memmove (tmpList, - RegistryHive->FreeList, - sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax)); - memmove (tmpListOffset, - RegistryHive->FreeListOffset, - sizeof(BLOCK_OFFSET) * (RegistryHive->FreeListMax)); - free (RegistryHive->FreeList); - free (RegistryHive->FreeListOffset); - } - RegistryHive->FreeList = tmpList; - RegistryHive->FreeListOffset = tmpListOffset; - RegistryHive->FreeListMax += 32; - } - - /* Add new offset to free list, maintaining list in ascending order */ - if ((RegistryHive->FreeListSize == 0) - || (RegistryHive->FreeListOffset[RegistryHive->FreeListSize-1] < FreeOffset)) - { - /* Add to end of list */ - RegistryHive->FreeList[RegistryHive->FreeListSize] = FreeBlock; - RegistryHive->FreeListOffset[RegistryHive->FreeListSize++] = FreeOffset; - } - else if (RegistryHive->FreeListOffset[0] > FreeOffset) - { - /* Add to begin of list */ - memmove (&RegistryHive->FreeList[1], - &RegistryHive->FreeList[0], - sizeof(RegistryHive->FreeList[0]) * RegistryHive->FreeListSize); - memmove (&RegistryHive->FreeListOffset[1], - &RegistryHive->FreeListOffset[0], - sizeof(RegistryHive->FreeListOffset[0]) * RegistryHive->FreeListSize); - RegistryHive->FreeList[0] = FreeBlock; - RegistryHive->FreeListOffset[0] = FreeOffset; - RegistryHive->FreeListSize++; - } - else - { - /* Search where to insert */ - minInd = 0; - maxInd = RegistryHive->FreeListSize - 1; - while ((maxInd - minInd) > 1) - { - medInd = (minInd + maxInd) / 2; - if (RegistryHive->FreeListOffset[medInd] > FreeOffset) - maxInd = medInd; - else - minInd = medInd; - } - - /* Insert before maxInd */ - memmove (&RegistryHive->FreeList[maxInd+1], - &RegistryHive->FreeList[maxInd], - sizeof(RegistryHive->FreeList[0]) * (RegistryHive->FreeListSize - minInd)); - memmove (&RegistryHive->FreeListOffset[maxInd + 1], - &RegistryHive->FreeListOffset[maxInd], - sizeof(RegistryHive->FreeListOffset[0]) * (RegistryHive->FreeListSize-minInd)); - RegistryHive->FreeList[maxInd] = FreeBlock; - RegistryHive->FreeListOffset[maxInd] = FreeOffset; - RegistryHive->FreeListSize++; - } - - return TRUE; -} - - -static BOOL -CmiAddBin(PREGISTRY_HIVE RegistryHive, - ULONG BlockCount, - PVOID *NewBlock, - PBLOCK_OFFSET NewBlockOffset) -{ - PCELL_HEADER tmpBlock; - PHBIN * tmpBlockList; - PHBIN tmpBin; - ULONG BinSize; - ULONG i; - - BinSize = BlockCount *REG_BLOCK_SIZE; - tmpBin = malloc (BinSize); - if (tmpBin == NULL) - { - return FALSE; - } - memset (tmpBin, 0, BinSize); - - tmpBin->HeaderId = REG_BIN_ID; - tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE; - RegistryHive->FileSize += BinSize; - tmpBin->BinSize = BinSize; - tmpBin->DateModified = 0; - tmpBin->MemAlloc = 0; - - /* Increase size of list of blocks */ - tmpBlockList = malloc (sizeof(PHBIN) * (RegistryHive->BlockListSize + BlockCount)); - if (tmpBlockList == NULL) - { - free (tmpBin); - return FALSE; - } - - if (RegistryHive->BlockListSize > 0) - { - memcpy (tmpBlockList, - RegistryHive->BlockList, - sizeof(PHBIN) * RegistryHive->BlockListSize); - free (RegistryHive->BlockList); - } - - RegistryHive->BlockList = tmpBlockList; - for (i = 0; i < BlockCount; i++) - RegistryHive->BlockList[RegistryHive->BlockListSize + i] = tmpBin; - RegistryHive->BlockListSize += BlockCount; - - /* Initialize a free block in this heap : */ - tmpBlock = (PCELL_HEADER)((ULONG_PTR) tmpBin + REG_HBIN_DATA_OFFSET); - tmpBlock->CellSize = (REG_BLOCK_SIZE - REG_HBIN_DATA_OFFSET); - - *NewBlock = (PVOID) tmpBlock; - - if (NewBlockOffset) - *NewBlockOffset = tmpBin->BinOffset + REG_HBIN_DATA_OFFSET; - - return TRUE; -} - - -static BOOL -CmiAllocateCell (PREGISTRY_HIVE RegistryHive, - LONG CellSize, - PVOID *Block, - PBLOCK_OFFSET pBlockOffset) -{ - PCELL_HEADER NewBlock; - ULONG i; - - *Block = NULL; - - /* Round to 16 bytes multiple */ - CellSize = ROUND_UP_POW2(CellSize, 16); - - /* first search in free blocks */ - NewBlock = NULL; - for (i = 0; i < RegistryHive->FreeListSize; i++) - { - if (RegistryHive->FreeList[i]->CellSize >= CellSize) - { - NewBlock = RegistryHive->FreeList[i]; - if (pBlockOffset) - *pBlockOffset = RegistryHive->FreeListOffset[i]; - - if ((i + 1) < RegistryHive->FreeListSize) - { - memmove (&RegistryHive->FreeList[i], - &RegistryHive->FreeList[i + 1], - sizeof(RegistryHive->FreeList[0]) - * (RegistryHive->FreeListSize - i - 1)); - memmove (&RegistryHive->FreeListOffset[i], - &RegistryHive->FreeListOffset[i + 1], - sizeof(RegistryHive->FreeListOffset[0]) - * (RegistryHive->FreeListSize - i - 1)); - } - RegistryHive->FreeListSize--; - break; - } - } - - /* Need to extend hive file : */ - if (NewBlock == NULL) - { - /* Add a new block */ - if (!CmiAddBin(RegistryHive, - ((sizeof(HBIN) + CellSize - 1) / REG_BLOCK_SIZE) + 1, - (PVOID *)&NewBlock, - pBlockOffset)) - return FALSE; - } - - *Block = NewBlock; - - /* Split the block in two parts */ - if (NewBlock->CellSize > CellSize) - { - NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock + CellSize); - NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - CellSize; - ((PCELL_HEADER) (*Block))->CellSize = CellSize; - CmiAddFree (RegistryHive, - NewBlock, - *pBlockOffset + CellSize, - TRUE); - } - else if (NewBlock->CellSize < CellSize) - { - return FALSE; - } - - memset((PVOID)((ULONG_PTR)*Block + sizeof(CELL_HEADER)), 0, - CellSize - sizeof(CELL_HEADER)); - ((PCELL_HEADER)(*Block))->CellSize *= -1; - - return TRUE; -} - - -static BOOL -CmiAllocateHashTableCell (PREGISTRY_HIVE Hive, - PBLOCK_OFFSET HBOffset, - USHORT SubKeyCount) -{ - PHASH_TABLE_CELL HashCell; - ULONG NewHashSize; - BOOL Status; - - NewHashSize = sizeof(HASH_TABLE_CELL) + - (SubKeyCount * sizeof(HASH_RECORD)); - Status = CmiAllocateCell (Hive, - NewHashSize, - (PVOID*) &HashCell, - HBOffset); - if ((HashCell == NULL) || (Status == FALSE)) - { - return FALSE; - } - - HashCell->Id = REG_HASH_TABLE_CELL_ID; - HashCell->HashTableSize = SubKeyCount; - - return TRUE; -} - - -static BOOL -CmiAddKeyToParentHashTable (PREGISTRY_HIVE Hive, - BLOCK_OFFSET ParentKeyOffset, - PKEY_CELL NewKeyCell, - BLOCK_OFFSET NKBOffset) -{ - PHASH_TABLE_CELL HashBlock; - PKEY_CELL ParentKeyCell; - ULONG i; - - ParentKeyCell = CmiGetCell (Hive, - ParentKeyOffset, - NULL); - if (ParentKeyCell == NULL) - { - DPRINT1 ("CmiGetBlock() failed\n"); - return FALSE; - } - - HashBlock =CmiGetCell (Hive, - ParentKeyCell->HashTableOffset, - NULL); - if (HashBlock == NULL) - { - DPRINT1 ("CmiGetBlock() failed\n"); - return FALSE; - } - - for (i = 0; i < HashBlock->HashTableSize; i++) - { - if (HashBlock->Table[i].KeyOffset == 0) - { - HashBlock->Table[i].KeyOffset = NKBOffset; - memcpy (&HashBlock->Table[i].HashValue, - NewKeyCell->Name, - 4); - ParentKeyCell->NumberOfSubKeys++; - return TRUE; - } - } - - return FALSE; -} - - -static BOOL -CmiAllocateValueListCell (PREGISTRY_HIVE Hive, - PBLOCK_OFFSET ValueListOffset, - ULONG ValueCount) -{ - PVALUE_LIST_CELL ValueListCell; - ULONG ValueListSize; - BOOL Status; - - ValueListSize = sizeof(VALUE_LIST_CELL) + - (ValueCount * sizeof(BLOCK_OFFSET)); - Status = CmiAllocateCell (Hive, - ValueListSize, - (PVOID)&ValueListCell, - ValueListOffset); - if ((ValueListCell == NULL) || (Status == FALSE)) - { - DPRINT1 ("CmiAllocateBlock() failed\n"); - return FALSE; - } - - return TRUE; -} - - -static BOOL -CmiAllocateValueCell(PREGISTRY_HIVE Hive, - PVALUE_CELL *ValueCell, - BLOCK_OFFSET *ValueCellOffset, - PCHAR ValueName) -{ - PVALUE_CELL NewValueCell; - USHORT NameSize; - BOOL Status; - - NameSize = (ValueName == NULL) ? 0 : strlen (ValueName); - Status = CmiAllocateCell (Hive, - sizeof(VALUE_CELL) + NameSize, - (PVOID*)&NewValueCell, - ValueCellOffset); - if ((NewValueCell == NULL) || (Status == FALSE)) - { - DPRINT1 ("CmiAllocateBlock() failed\n"); - return FALSE; - } - - NewValueCell->Id = REG_VALUE_CELL_ID; - NewValueCell->NameSize = NameSize; - if (NameSize > 0) - { - memcpy (NewValueCell->Name, - ValueName, - NameSize); - NewValueCell->Flags = REG_VALUE_NAME_PACKED; - } - NewValueCell->DataType = 0; - NewValueCell->DataSize = 0; - NewValueCell->DataOffset = -1; - - *ValueCell = NewValueCell; - - return TRUE; -} - - -static BOOL -CmiAddValueToKeyValueList(PREGISTRY_HIVE Hive, - BLOCK_OFFSET KeyCellOffset, - BLOCK_OFFSET ValueCellOffset) -{ - PVALUE_LIST_CELL ValueListCell; - PKEY_CELL KeyCell; - - KeyCell = CmiGetCell (Hive, KeyCellOffset, NULL); - if (KeyCell == NULL) - { - DPRINT1 ("CmiGetBlock() failed\n"); - return FALSE; - } - - ValueListCell = CmiGetCell (Hive, KeyCell->ValueListOffset, NULL); - if (ValueListCell == NULL) - { - DPRINT1 ("CmiGetBlock() failed\n"); - return FALSE; - } - - ValueListCell->ValueOffset[KeyCell->NumberOfValues] = ValueCellOffset; - KeyCell->NumberOfValues++; - - return TRUE; -} - - -static BOOL -CmiExportValue (PREGISTRY_HIVE Hive, - BLOCK_OFFSET KeyCellOffset, - HKEY Key, - PVALUE Value) -{ - BLOCK_OFFSET ValueCellOffset; - BLOCK_OFFSET DataCellOffset; - PVALUE_CELL ValueCell; - PDATA_CELL DataCell; - ULONG SrcDataSize; - ULONG DstDataSize; - ULONG DataType; - PCHAR Data; - BOOL Expand = FALSE; - - DPRINT ("CmiExportValue('%s') called\n", (Value == NULL) ? "" : (PCHAR)Value->Name); - DPRINT ("DataSize %lu\n", (Value == NULL) ? Key->DataSize : Value->DataSize); - - /* Allocate value cell */ - if (!CmiAllocateValueCell(Hive, &ValueCell, &ValueCellOffset, (Value == NULL) ? NULL : Value->Name)) - { - return FALSE; - } - - if (!CmiAddValueToKeyValueList(Hive, KeyCellOffset, ValueCellOffset)) - { - return FALSE; - } - - if (Value == NULL) - { - DataType = Key->DataType; - SrcDataSize = Key->DataSize; - Data = Key->Data; - } - else - { - DataType = Value->DataType; - SrcDataSize = Value->DataSize; - Data = Value->Data; - } - - DstDataSize = SrcDataSize; - if (DataType == REG_SZ || - DataType == REG_EXPAND_SZ || - DataType == REG_MULTI_SZ) - { - DstDataSize *= sizeof(WCHAR); - Expand = TRUE; - } - - if ((DstDataSize & REG_DATA_SIZE_MASK) <= sizeof(BLOCK_OFFSET)) - { - ValueCell->DataSize = DstDataSize | REG_DATA_IN_OFFSET; - ValueCell->DataType = DataType; - if (Expand) - { - memexpand ((PWCHAR)&ValueCell->DataOffset, - (PCHAR)&Data, - SrcDataSize); - } - else - { - memcpy (&ValueCell->DataOffset, - &Data, - SrcDataSize); - } - } - else - { - /* Allocate data cell */ - if (!CmiAllocateCell (Hive, - sizeof(CELL_HEADER) + DstDataSize, - (PVOID *)&DataCell, - &DataCellOffset)) - { - return FALSE; - } - - ValueCell->DataOffset = DataCellOffset; - ValueCell->DataSize = DstDataSize & REG_DATA_SIZE_MASK; - ValueCell->DataType = DataType; - - if (Expand) - { - if (SrcDataSize <= sizeof(BLOCK_OFFSET)) - { - memexpand ((PWCHAR)DataCell->Data, - (PCHAR)&Data, - SrcDataSize); - } - else - { - memexpand ((PWCHAR)DataCell->Data, - Data, - SrcDataSize); - } - } - else - { - memcpy (DataCell->Data, - Data, - SrcDataSize); - } - } - - return TRUE; -} - - -static BOOL -CmiExportSubKey (PREGISTRY_HIVE Hive, - BLOCK_OFFSET ParentKeyOffset, - HKEY ParentKey, - HKEY Key) -{ - BLOCK_OFFSET NKBOffset; - PKEY_CELL NewKeyCell; - ULONG KeyCellSize; - USHORT SubKeyCount; - ULONG ValueCount; - PLIST_ENTRY Entry; - HKEY SubKey; - PVALUE Value; - - DPRINT ("CmiExportSubKey('%s') called\n", Key->Name); - - /* Don't export links */ - if (Key->DataType == REG_LINK) - return TRUE; - - /* Allocate key cell */ - KeyCellSize = sizeof(KEY_CELL) + Key->NameSize - 1; - if (!CmiAllocateCell (Hive, KeyCellSize, (PVOID)&NewKeyCell, &NKBOffset)) - { - DPRINT1 ("CmiAllocateBlock() failed\n"); - return FALSE; - } - - /* Initialize key cell */ - NewKeyCell->Id = REG_KEY_CELL_ID; - NewKeyCell->Type = REG_KEY_CELL_TYPE; - NewKeyCell->LastWriteTime = 0; - NewKeyCell->ParentKeyOffset = ParentKeyOffset; - NewKeyCell->NumberOfSubKeys = 0; - NewKeyCell->HashTableOffset = -1; - NewKeyCell->NumberOfValues = 0; - NewKeyCell->ValueListOffset = -1; - NewKeyCell->SecurityKeyOffset = -1; - NewKeyCell->NameSize = Key->NameSize - 1; - NewKeyCell->ClassNameOffset = -1; - memcpy (NewKeyCell->Name, - Key->Name, - Key->NameSize - 1); - - /* Add key cell to the parent key's hash table */ - if (!CmiAddKeyToParentHashTable (Hive, - ParentKeyOffset, - NewKeyCell, - NKBOffset)) - { - DPRINT1 ("CmiAddKeyToParentHashTable() failed\n"); - return FALSE; - } - - ValueCount = RegGetValueCount (Key); - DPRINT ("ValueCount: %lu\n", ValueCount); - if (ValueCount > 0) - { - /* Allocate value list cell */ - CmiAllocateValueListCell (Hive, - &NewKeyCell->ValueListOffset, - ValueCount); - - if (Key->DataSize != 0) - { - if (!CmiExportValue (Hive, NKBOffset, Key, NULL)) - return FALSE; - } - - /* Enumerate values */ - Entry = Key->ValueList.Flink; - while (Entry != &Key->ValueList) - { - Value = CONTAINING_RECORD(Entry, - VALUE, - ValueList); - - if (!CmiExportValue (Hive, NKBOffset, Key, Value)) - return FALSE; - - Entry = Entry->Flink; - } - } - - SubKeyCount = RegGetSubKeyCount (Key); - DPRINT ("SubKeyCount: %lu\n", SubKeyCount); - if (SubKeyCount > 0) - { - /* Allocate hash table cell */ - CmiAllocateHashTableCell (Hive, - &NewKeyCell->HashTableOffset, - SubKeyCount); - - /* Enumerate subkeys */ - Entry = Key->SubKeyList.Flink; - while (Entry != &Key->SubKeyList) - { - SubKey = CONTAINING_RECORD(Entry, - KEY, - KeyList); - - if (!CmiExportSubKey (Hive, NKBOffset, Key, SubKey)) - return FALSE; - - Entry = Entry->Flink; - } - } - - return TRUE; -} - - -static VOID -CmiCalcHiveChecksum (PREGISTRY_HIVE Hive) -{ - PULONG Buffer; - ULONG Sum; - ULONG i; - - Buffer = (PULONG)Hive->HiveHeader; - Sum = 0; - for (i = 0; i < 127; i++) - Sum ^= Buffer[i]; - if (Sum == (ULONG)-1) - Sum = (ULONG)-2; - if (Sum == 0) - Sum = 1; - - Hive->HiveHeader->Checksum = Sum; -} - BOOL -CmiExportHive (PREGISTRY_HIVE Hive, - PCHAR KeyName) +ExportBinaryHive( + IN PCSTR FileName, + IN PEREGISTRY_HIVE Hive) { - PKEY_CELL KeyCell; - HKEY Key; - USHORT SubKeyCount; - ULONG ValueCount; - PLIST_ENTRY Entry; - HKEY SubKey; - PVALUE Value; + FILE *File; + BOOL ret; - DPRINT ("CmiExportHive(%p, '%s') called\n", Hive, KeyName); + printf (" Creating binary hive: %s\n", FileName); - if (RegOpenKey (NULL, KeyName, &Key) != ERROR_SUCCESS) - { - DPRINT1 ("RegOpenKey() failed\n"); - return FALSE; - } - - DPRINT ("Name: %s\n", KeyName); - - KeyCell = CmiGetCell (Hive, - Hive->HiveHeader->RootKeyOffset, - NULL); - if (KeyCell == NULL) - { - DPRINT1 ("CmiGetCell() failed\n"); - return FALSE; - } - - ValueCount = RegGetValueCount (Key); - DPRINT ("ValueCount: %lu\n", ValueCount); - if (ValueCount > 0) - { - /* Allocate value list cell */ - CmiAllocateValueListCell (Hive, - &KeyCell->ValueListOffset, - ValueCount); - - if (Key->DataSize != 0) + /* Create new hive file */ + File = fopen (FileName, "w+b"); + if (File == NULL) { - if (!CmiExportValue (Hive, Hive->HiveHeader->RootKeyOffset, Key, NULL)) - return FALSE; + printf(" Error creating/opening file\n"); + return FALSE; } - /* Enumerate values */ - Entry = Key->ValueList.Flink; - while (Entry != &Key->ValueList) - { - Value = CONTAINING_RECORD(Entry, - VALUE, - ValueList); + fseek (File, 0, SEEK_SET); - if (!CmiExportValue (Hive, Hive->HiveHeader->RootKeyOffset, Key, Value)) - return FALSE; - - Entry = Entry->Flink; - } - } - - SubKeyCount = RegGetSubKeyCount (Key); - DPRINT ("SubKeyCount: %lu\n", SubKeyCount); - if (SubKeyCount > 0) - { - /* Allocate hash table cell */ - CmiAllocateHashTableCell (Hive, - &KeyCell->HashTableOffset, - SubKeyCount); - - /* Enumerate subkeys */ - Entry = Key->SubKeyList.Flink; - while (Entry != &Key->SubKeyList) - { - SubKey = CONTAINING_RECORD(Entry, - KEY, - KeyList); - - if (!CmiExportSubKey (Hive, Hive->HiveHeader->RootKeyOffset, Key, SubKey)) - return FALSE; - - Entry = Entry->Flink; - } - } - - CmiCalcHiveChecksum (Hive); - - return TRUE; -} - - -static BOOL -CmiWriteHive(PREGISTRY_HIVE Hive, - PCHAR FileName) -{ - PHBIN Bin; - FILE *File; - ULONG i; - -#if 0 - /* Check for existing hive file */ - File = fopen (FileName, "rb"); - if (File != NULL) - { - printf (" File already exists\n"); - fclose (File); - return TRUE; - } -#endif - - /* Create new hive file */ - File = fopen (FileName, "w+b"); - if (File == NULL) - { - printf(" Error creating/opening file\n"); - return FALSE; - } - - fseek (File, 0, SEEK_SET); - - /* Calculate header checksum */ - CmiCalcHiveChecksum (Hive); - - /* Write hive header */ - fwrite (Hive->HiveHeader, REG_BLOCK_SIZE, 1, File); - - Bin = NULL; - for (i = 0; i < Hive->BlockListSize; i++) - { - if (Hive->BlockList[i] != Bin) - { - Bin = Hive->BlockList[i]; - - DPRINT ("Bin[%lu]: Offset 0x%lx Size 0x%lx\n", - i, Bin->BinOffset, Bin->BinSize); - - fwrite (Bin, Bin->BinSize, 1, File); - } - } - - fclose (File); - - return TRUE; -} - - -BOOL -ExportBinaryHive (PCHAR FileName, - PCHAR KeyName) -{ - PREGISTRY_HIVE Hive; - - printf (" Creating binary hive: %s\n", FileName); - - Hive = CmiCreateRegistryHive (KeyName); - if (Hive == NULL) - return FALSE; - - if (!CmiExportHive (Hive, KeyName)) - { - CmiDestroyRegistryHive (Hive); - return FALSE; - } - - if (!CmiWriteHive (Hive, FileName)) - { - CmiDestroyRegistryHive (Hive); - return FALSE; - } - - CmiDestroyRegistryHive (Hive); - - return TRUE; + Hive->HiveHandle = (HANDLE)File; + ret = HvWriteHive(&Hive->Hive); + fclose (File); + return ret; } /* EOF */ diff --git a/reactos/tools/mkhive/binhive.h b/reactos/tools/mkhive/binhive.h index 1ab398b28b9..b252b941246 100644 --- a/reactos/tools/mkhive/binhive.h +++ b/reactos/tools/mkhive/binhive.h @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2003 ReactOS Team + * Copyright (C) 2006 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 @@ -16,20 +16,20 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS hive maker * FILE: tools/mkhive/binhive.h * PURPOSE: Binary hive export code - * PROGRAMMER: Eric Kohl + * PROGRAMMER: Hervé Poussineau */ #ifndef __BINHIVE_H__ #define __BINHIVE_H__ BOOL -ExportBinaryHive (PCHAR FileName, - PCHAR KeyName); +ExportBinaryHive( + IN PCSTR FileName, + IN PEREGISTRY_HIVE Hive); #endif /* __BINHIVE_H__ */ diff --git a/reactos/tools/mkhive/cmi.c b/reactos/tools/mkhive/cmi.c new file mode 100644 index 00000000000..e8cd3e5e556 --- /dev/null +++ b/reactos/tools/mkhive/cmi.c @@ -0,0 +1,791 @@ +/* + * ReactOS kernel + * Copyright (C) 2006 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/cmi.c + * PURPOSE: Registry file manipulation routines + * PROGRAMMER: Hervé Poussineau + */ + +#define NDEBUG +#include "mkhive.h" + +static PVOID +CmpAllocate( + IN SIZE_T Size, + IN BOOLEAN Paged) +{ + return malloc(Size); +} + +static VOID +CmpFree( + IN PVOID Ptr) +{ + free(Ptr); +} + +static BOOLEAN +CmpFileRead( + IN PHHIVE RegistryHive, + IN ULONG FileType, + IN ULONGLONG FileOffset, + OUT PVOID Buffer, + IN SIZE_T BufferLength) +{ + DPRINT1("CmpFileRead() unimplemented\n"); + return FALSE; +} + +static BOOLEAN +CmpFileWrite( + IN PHHIVE RegistryHive, + IN ULONG FileType, + IN ULONGLONG FileOffset, + IN PVOID Buffer, + IN SIZE_T BufferLength) +{ + PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; + FILE *File = CmHive->HiveHandle; + if (0 != fseek (File, (long)FileOffset, SEEK_SET)) + return FALSE; + return BufferLength == fwrite (Buffer, 1, BufferLength, File); +} + +static BOOLEAN +CmpFileSetSize( + IN PHHIVE RegistryHive, + IN ULONG FileType, + IN ULONGLONG FileSize) +{ + DPRINT1("CmpFileSetSize() unimplemented\n"); + return FALSE; +} + +static BOOLEAN +CmpFileFlush( + IN PHHIVE RegistryHive, + IN ULONG FileType) +{ + PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; + FILE *File = CmHive->HiveHandle; + return 0 == fflush (File); +} + +NTSTATUS +CmiInitializeTempHive( + IN OUT PEREGISTRY_HIVE Hive) +{ + NTSTATUS Status; + + RtlZeroMemory ( + Hive, + sizeof(EREGISTRY_HIVE)); + + DPRINT("Hive 0x%p\n", Hive); + + Status = HvInitialize( + &Hive->Hive, + HV_OPERATION_CREATE_HIVE, 0, 0, + CmpAllocate, CmpFree, + CmpFileRead, CmpFileWrite, CmpFileSetSize, + CmpFileFlush, NULL); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + if (!CmCreateRootNode (&Hive->Hive, L"")) + { + HvFree (&Hive->Hive); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Hive->Flags = HIVE_NO_FILE; + + /* Add the new hive to the hive list */ + InsertTailList ( + &CmiHiveListHead, + &Hive->HiveList); + + VERIFY_REGISTRY_HIVE (Hive); + + return STATUS_SUCCESS; +} + +static NTSTATUS +CmiAddKeyToHashTable( + IN PEREGISTRY_HIVE RegistryHive, + IN OUT PHASH_TABLE_CELL HashCell, + IN PCM_KEY_NODE KeyCell, + IN HV_STORAGE_TYPE StorageType, + IN PCM_KEY_NODE NewKeyCell, + IN HCELL_INDEX NKBOffset) +{ + ULONG i = KeyCell->SubKeyCounts[StorageType]; + + HashCell->Table[i].KeyOffset = NKBOffset; + HashCell->Table[i].HashValue = 0; + if (NewKeyCell->Flags & REG_KEY_NAME_PACKED) + { + RtlCopyMemory( + &HashCell->Table[i].HashValue, + NewKeyCell->Name, + min(NewKeyCell->NameSize, sizeof(ULONG))); + } + HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType]); + return STATUS_SUCCESS; +} + +static NTSTATUS +CmiAllocateHashTableCell ( + IN PEREGISTRY_HIVE RegistryHive, + OUT PHASH_TABLE_CELL *HashBlock, + OUT HCELL_INDEX *HBOffset, + IN USHORT SubKeyCount, + IN HV_STORAGE_TYPE Storage) +{ + PHASH_TABLE_CELL NewHashBlock; + ULONG NewHashSize; + NTSTATUS Status; + + Status = STATUS_SUCCESS; + *HashBlock = NULL; + NewHashSize = sizeof(HASH_TABLE_CELL) + + (SubKeyCount * sizeof(HASH_RECORD)); + *HBOffset = HvAllocateCell(&RegistryHive->Hive, NewHashSize, Storage); + + if (*HBOffset == HCELL_NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + ASSERT(SubKeyCount <= USHORT_MAX); + NewHashBlock = HvGetCell (&RegistryHive->Hive, *HBOffset); + NewHashBlock->Id = REG_HASH_TABLE_CELL_ID; + NewHashBlock->HashTableSize = SubKeyCount; + *HashBlock = NewHashBlock; + } + + return Status; +} + +NTSTATUS +CmiAddSubKey( + IN PEREGISTRY_HIVE RegistryHive, + IN PCM_KEY_NODE ParentKeyCell, + IN HCELL_INDEX ParentKeyCellOffset, + IN PCUNICODE_STRING SubKeyName, + IN ULONG CreateOptions, + OUT PCM_KEY_NODE *pSubKeyCell, + OUT HCELL_INDEX *pBlockOffset) +{ + PHASH_TABLE_CELL HashBlock; + HCELL_INDEX NKBOffset; + PCM_KEY_NODE NewKeyCell; + ULONG NewBlockSize; + NTSTATUS Status; + USHORT NameSize; + PWSTR NamePtr; + BOOLEAN Packable; + HV_STORAGE_TYPE Storage; + ULONG i; + + DPRINT("CmiAddSubKey(%p '%wZ')\n", RegistryHive, SubKeyName); + + VERIFY_KEY_CELL(ParentKeyCell); + + /* Skip leading backslash */ + if (SubKeyName->Buffer[0] == L'\\') + { + NamePtr = &SubKeyName->Buffer[1]; + NameSize = SubKeyName->Length - sizeof(WCHAR); + } + else + { + NamePtr = SubKeyName->Buffer; + NameSize = SubKeyName->Length; + } + + /* Check whether key name can be packed */ + Packable = TRUE; + for (i = 0; i < NameSize / sizeof(WCHAR); i++) + { + if (NamePtr[i] & 0xFF00) + { + Packable = FALSE; + break; + } + } + + /* Adjust name size */ + if (Packable) + { + NameSize = NameSize / sizeof(WCHAR); + } + + Status = STATUS_SUCCESS; + + Storage = (CreateOptions & REG_OPTION_VOLATILE) ? HvVolatile : HvStable; + NewBlockSize = sizeof(CM_KEY_NODE) + NameSize; + NKBOffset = HvAllocateCell(&RegistryHive->Hive, NewBlockSize, Storage); + if (NKBOffset == HCELL_NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + NewKeyCell = HvGetCell (&RegistryHive->Hive, NKBOffset); + NewKeyCell->Id = REG_KEY_CELL_ID; + if (CreateOptions & REG_OPTION_VOLATILE) + { + NewKeyCell->Flags = REG_KEY_VOLATILE_CELL; + } + else + { + NewKeyCell->Flags = 0; + } + KeQuerySystemTime(&NewKeyCell->LastWriteTime); + NewKeyCell->Parent = HCELL_NULL; + NewKeyCell->SubKeyCounts[HvStable] = 0; + NewKeyCell->SubKeyCounts[HvVolatile] = 0; + NewKeyCell->SubKeyLists[HvStable] = HCELL_NULL; + NewKeyCell->SubKeyLists[HvVolatile] = HCELL_NULL; + NewKeyCell->ValueList.Count = 0; + NewKeyCell->ValueList.List = HCELL_NULL; + NewKeyCell->SecurityKeyOffset = HCELL_NULL; + NewKeyCell->ClassNameOffset = HCELL_NULL; + + /* Pack the key name */ + NewKeyCell->NameSize = NameSize; + if (Packable) + { + NewKeyCell->Flags |= REG_KEY_NAME_PACKED; + for (i = 0; i < NameSize; i++) + { + NewKeyCell->Name[i] = (CHAR)(NamePtr[i] & 0x00FF); + } + } + else + { + RtlCopyMemory( + NewKeyCell->Name, + NamePtr, + NameSize); + } + + VERIFY_KEY_CELL(NewKeyCell); + } + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + if (ParentKeyCell->SubKeyLists[Storage] == HCELL_NULL) + { + Status = CmiAllocateHashTableCell ( + RegistryHive, + &HashBlock, + &ParentKeyCell->SubKeyLists[Storage], + REG_INIT_HASH_TABLE_SIZE, + Storage); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + else + { + HashBlock = HvGetCell ( + &RegistryHive->Hive, + ParentKeyCell->SubKeyLists[Storage]); + ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID); + + if (((ParentKeyCell->SubKeyCounts[Storage] + 1) >= HashBlock->HashTableSize)) + { + PHASH_TABLE_CELL NewHashBlock; + HCELL_INDEX HTOffset; + + /* Reallocate the hash table cell */ + Status = CmiAllocateHashTableCell ( + RegistryHive, + &NewHashBlock, + &HTOffset, + HashBlock->HashTableSize + + REG_EXTEND_HASH_TABLE_SIZE, + Storage); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + RtlZeroMemory( + &NewHashBlock->Table[0], + sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize); + RtlCopyMemory( + &NewHashBlock->Table[0], + &HashBlock->Table[0], + sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize); + HvFreeCell (&RegistryHive->Hive, ParentKeyCell->SubKeyLists[Storage]); + ParentKeyCell->SubKeyLists[Storage] = HTOffset; + HashBlock = NewHashBlock; + } + } + + Status = CmiAddKeyToHashTable( + RegistryHive, + HashBlock, + ParentKeyCell, + Storage, + NewKeyCell, + NKBOffset); + if (NT_SUCCESS(Status)) + { + ParentKeyCell->SubKeyCounts[Storage]++; + *pSubKeyCell = NewKeyCell; + *pBlockOffset = NKBOffset; + } + + KeQuerySystemTime(&ParentKeyCell->LastWriteTime); + HvMarkCellDirty(&RegistryHive->Hive, ParentKeyCellOffset); + + return Status; +} + +static BOOLEAN +CmiCompareHash( + IN PCUNICODE_STRING KeyName, + IN PCHAR HashString) +{ + CHAR Buffer[4]; + + Buffer[0] = (KeyName->Length >= 2) ? (CHAR)KeyName->Buffer[0] : 0; + Buffer[1] = (KeyName->Length >= 4) ? (CHAR)KeyName->Buffer[1] : 0; + Buffer[2] = (KeyName->Length >= 6) ? (CHAR)KeyName->Buffer[2] : 0; + Buffer[3] = (KeyName->Length >= 8) ? (CHAR)KeyName->Buffer[3] : 0; + + return (strncmp(Buffer, HashString, 4) == 0); +} + + +BOOLEAN +CmiCompareHashI( + IN PCUNICODE_STRING KeyName, + IN PCHAR HashString) +{ + CHAR Buffer[4]; + + Buffer[0] = (KeyName->Length >= 2) ? (CHAR)KeyName->Buffer[0] : 0; + Buffer[1] = (KeyName->Length >= 4) ? (CHAR)KeyName->Buffer[1] : 0; + Buffer[2] = (KeyName->Length >= 6) ? (CHAR)KeyName->Buffer[2] : 0; + Buffer[3] = (KeyName->Length >= 8) ? (CHAR)KeyName->Buffer[3] : 0; + + return (_strnicmp(Buffer, HashString, 4) == 0); +} + +static BOOLEAN +CmiCompareKeyNames( + IN PCUNICODE_STRING KeyName, + IN PCM_KEY_NODE KeyCell) +{ + PWCHAR UnicodeName; + USHORT i; + + if (KeyCell->Flags & REG_KEY_NAME_PACKED) + { + if (KeyName->Length != KeyCell->NameSize * sizeof(WCHAR)) + return FALSE; + + for (i = 0; i < KeyCell->NameSize; i++) + { + if (KeyName->Buffer[i] != (WCHAR)KeyCell->Name[i]) + return FALSE; + } + } + else + { + if (KeyName->Length != KeyCell->NameSize) + return FALSE; + + UnicodeName = (PWCHAR)KeyCell->Name; + for (i = 0; i < KeyCell->NameSize / sizeof(WCHAR); i++) + { + if (KeyName->Buffer[i] != UnicodeName[i]) + return FALSE; + } + } + + return TRUE; +} + +static BOOLEAN +CmiCompareKeyNamesI( + IN PCUNICODE_STRING KeyName, + IN PCM_KEY_NODE KeyCell) +{ + PWCHAR UnicodeName; + USHORT i; + + DPRINT("Flags: %hx\n", KeyCell->Flags); + + if (KeyCell->Flags & REG_KEY_NAME_PACKED) + { + if (KeyName->Length != KeyCell->NameSize * sizeof(WCHAR)) + return FALSE; + + /* FIXME: use _strnicmp */ + for (i = 0; i < KeyCell->NameSize; i++) + { + if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) != + RtlUpcaseUnicodeChar((WCHAR)KeyCell->Name[i])) + return FALSE; + } + } + else + { + if (KeyName->Length != KeyCell->NameSize) + return FALSE; + + UnicodeName = (PWCHAR)KeyCell->Name; + /* FIXME: use _strnicmp */ + for (i = 0; i < KeyCell->NameSize / sizeof(WCHAR); i++) + { + if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) != + RtlUpcaseUnicodeChar(UnicodeName[i])) + return FALSE; + } + } + + return TRUE; +} + +NTSTATUS +CmiScanForSubKey( + IN PEREGISTRY_HIVE RegistryHive, + IN PCM_KEY_NODE KeyCell, + IN PCUNICODE_STRING SubKeyName, + IN ULONG Attributes, + OUT PCM_KEY_NODE *pSubKeyCell, + OUT HCELL_INDEX *pBlockOffset) +{ + PHASH_TABLE_CELL HashBlock; + PCM_KEY_NODE CurSubKeyCell; + ULONG Storage; + ULONG i; + + VERIFY_KEY_CELL(KeyCell); + + DPRINT("CmiScanForSubKey('%wZ')\n", SubKeyName); + + ASSERT(RegistryHive); + + *pSubKeyCell = NULL; + + for (Storage = HvStable; Storage < HvMaxStorageType; Storage++) + { + if (KeyCell->SubKeyLists[Storage] == HCELL_NULL) + { + /* The key does not have any subkeys */ + continue; + } + + /* Get hash table */ + HashBlock = HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]); + if (!HashBlock || HashBlock->Id != REG_HASH_TABLE_CELL_ID) + return STATUS_UNSUCCESSFUL; + + for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++) + { + if (Attributes & OBJ_CASE_INSENSITIVE) + { + if ((HashBlock->Table[i].HashValue == 0 + || CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue))) + { + CurSubKeyCell = HvGetCell ( + &RegistryHive->Hive, + HashBlock->Table[i].KeyOffset); + + if (CmiCompareKeyNamesI(SubKeyName, CurSubKeyCell)) + { + *pSubKeyCell = CurSubKeyCell; + *pBlockOffset = HashBlock->Table[i].KeyOffset; + return STATUS_SUCCESS; + } + } + } + else + { + if ((HashBlock->Table[i].HashValue == 0 + || CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue))) + { + CurSubKeyCell = HvGetCell ( + &RegistryHive->Hive, + HashBlock->Table[i].KeyOffset); + + if (CmiCompareKeyNames(SubKeyName, CurSubKeyCell)) + { + *pSubKeyCell = CurSubKeyCell; + *pBlockOffset = HashBlock->Table[i].KeyOffset; + return STATUS_SUCCESS; + } + } + } + } + } + + return STATUS_OBJECT_NAME_NOT_FOUND; +} + +static USHORT +CmiGetPackedNameLength( + IN PCUNICODE_STRING Name, + OUT PBOOLEAN pPackable) +{ + USHORT i; + + *pPackable = TRUE; + + for (i = 0; i < Name->Length / sizeof(WCHAR); i++) + { + if (Name->Buffer[i] & 0xFF00) + { + *pPackable = FALSE; + return Name->Length; + } + } + + return (Name->Length / sizeof(WCHAR)); +} + +static NTSTATUS +CmiAllocateValueCell( + IN PEREGISTRY_HIVE RegistryHive, + OUT PCM_KEY_VALUE *ValueCell, + OUT HCELL_INDEX *VBOffset, + IN PCUNICODE_STRING ValueName, + IN HV_STORAGE_TYPE Storage) +{ + PCM_KEY_VALUE NewValueCell; + BOOLEAN Packable; + USHORT NameSize, i; + NTSTATUS Status; + + Status = STATUS_SUCCESS; + + NameSize = CmiGetPackedNameLength(ValueName, &Packable); + + DPRINT("ValueName->Length %lu NameSize %lu\n", ValueName->Length, NameSize); + + *VBOffset = HvAllocateCell(&RegistryHive->Hive, sizeof(CM_KEY_VALUE) + NameSize, Storage); + if (*VBOffset == HCELL_NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + ASSERT(NameSize <= USHORT_MAX); + NewValueCell = HvGetCell (&RegistryHive->Hive, *VBOffset); + NewValueCell->Id = REG_VALUE_CELL_ID; + NewValueCell->NameSize = (USHORT)NameSize; + if (Packable) + { + /* Pack the value name */ + for (i = 0; i < NameSize; i++) + NewValueCell->Name[i] = (CHAR)ValueName->Buffer[i]; + NewValueCell->Flags |= REG_VALUE_NAME_PACKED; + } + else + { + /* Copy the value name */ + RtlCopyMemory( + NewValueCell->Name, + ValueName->Buffer, + NameSize); + NewValueCell->Flags = 0; + } + NewValueCell->DataType = 0; + NewValueCell->DataSize = 0; + NewValueCell->DataOffset = HCELL_NULL; + *ValueCell = NewValueCell; + } + + return Status; +} + +NTSTATUS +CmiAddValueKey( + IN PEREGISTRY_HIVE RegistryHive, + IN PCM_KEY_NODE KeyCell, + IN HCELL_INDEX KeyCellOffset, + IN PCUNICODE_STRING ValueName, + OUT PCM_KEY_VALUE *pValueCell, + OUT HCELL_INDEX *pValueCellOffset) +{ + PVALUE_LIST_CELL ValueListCell; + PCM_KEY_VALUE NewValueCell; + HCELL_INDEX ValueListCellOffset; + HCELL_INDEX NewValueCellOffset; + ULONG CellSize; + HV_STORAGE_TYPE Storage; + NTSTATUS Status; + + Storage = (KeyCell->Flags & REG_KEY_VOLATILE_CELL) ? HvVolatile : HvStable; + if (KeyCell->ValueList.List == HCELL_NULL) + { + /* Allocate some room for the value list */ + CellSize = sizeof(VALUE_LIST_CELL) + (3 * sizeof(HCELL_INDEX)); + ValueListCellOffset = HvAllocateCell(&RegistryHive->Hive, CellSize, Storage); + if (ValueListCellOffset == HCELL_NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + ValueListCell = HvGetCell(&RegistryHive->Hive, ValueListCellOffset); + if (!ValueListCell) + return STATUS_UNSUCCESSFUL; + KeyCell->ValueList.List = ValueListCellOffset; + HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset); + } + else + { + ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive, KeyCell->ValueList.List); + if (!ValueListCell) + return STATUS_UNSUCCESSFUL; + CellSize = ABS_VALUE(HvGetCellSize(&RegistryHive->Hive, ValueListCell)); + + if (KeyCell->ValueList.Count >= CellSize / sizeof(HCELL_INDEX)) + { + CellSize *= 2; + ValueListCellOffset = HvReallocateCell(&RegistryHive->Hive, KeyCell->ValueList.List, CellSize); + if (ValueListCellOffset == HCELL_NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + ValueListCell = HvGetCell(&RegistryHive->Hive, ValueListCellOffset); + if (!ValueListCell) + return STATUS_UNSUCCESSFUL; + KeyCell->ValueList.List = ValueListCellOffset; + HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset); + } + } + + Status = CmiAllocateValueCell( + RegistryHive, + &NewValueCell, + &NewValueCellOffset, + ValueName, + Storage); + if (!NT_SUCCESS(Status)) + return Status; + + ValueListCell->ValueOffset[KeyCell->ValueList.Count] = NewValueCellOffset; + KeyCell->ValueList.Count++; + + HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset); + HvMarkCellDirty(&RegistryHive->Hive, KeyCell->ValueList.List); + HvMarkCellDirty(&RegistryHive->Hive, NewValueCellOffset); + + *pValueCell = NewValueCell; + *pValueCellOffset = NewValueCellOffset; + + return STATUS_SUCCESS; +} + +static BOOLEAN +CmiComparePackedNames( + IN PCUNICODE_STRING Name, + IN PUCHAR NameBuffer, + IN USHORT NameBufferSize, + IN BOOLEAN NamePacked) +{ + PWCHAR UNameBuffer; + ULONG i; + + if (NamePacked == TRUE) + { + if (Name->Length != NameBufferSize * sizeof(WCHAR)) + return FALSE; + + for (i = 0; i < Name->Length / sizeof(WCHAR); i++) + { + if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar((WCHAR)NameBuffer[i])) + return FALSE; + } + } + else + { + if (Name->Length != NameBufferSize) + return FALSE; + + UNameBuffer = (PWCHAR)NameBuffer; + + for (i = 0; i < Name->Length / sizeof(WCHAR); i++) + { + if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar(UNameBuffer[i])) + return FALSE; + } + } + + return TRUE; +} + +NTSTATUS +CmiScanForValueKey( + IN PEREGISTRY_HIVE RegistryHive, + IN PCM_KEY_NODE KeyCell, + IN PCUNICODE_STRING ValueName, + OUT PCM_KEY_VALUE *pValueCell, + OUT HCELL_INDEX *pValueCellOffset) +{ + PVALUE_LIST_CELL ValueListCell; + PCM_KEY_VALUE CurValueCell; + ULONG i; + + *pValueCell = NULL; + *pValueCellOffset = HCELL_NULL; + + /* The key does not have any values */ + if (KeyCell->ValueList.List == HCELL_NULL) + { + return STATUS_OBJECT_NAME_NOT_FOUND; + } + + ValueListCell = HvGetCell(&RegistryHive->Hive, KeyCell->ValueList.List); + + VERIFY_VALUE_LIST_CELL(ValueListCell); + + for (i = 0; i < KeyCell->ValueList.Count; i++) + { + CurValueCell = HvGetCell( + &RegistryHive->Hive, + ValueListCell->ValueOffset[i]); + + if (CmiComparePackedNames( + ValueName, + CurValueCell->Name, + CurValueCell->NameSize, + (BOOLEAN)((CurValueCell->Flags & REG_VALUE_NAME_PACKED) ? TRUE : FALSE))) + { + *pValueCell = CurValueCell; + *pValueCellOffset = ValueListCell->ValueOffset[i]; + return STATUS_SUCCESS; + } + } + + return STATUS_OBJECT_NAME_NOT_FOUND; +} diff --git a/reactos/tools/mkhive/cmi.h b/reactos/tools/mkhive/cmi.h new file mode 100644 index 00000000000..b66d39ccde4 --- /dev/null +++ b/reactos/tools/mkhive/cmi.h @@ -0,0 +1,67 @@ +/* + * ReactOS kernel + * Copyright (C) 2006 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/cmi.h + * PURPOSE: Registry file manipulation routines + * PROGRAMMER: Hervé Poussineau + */ + +#define VERIFY_KEY_CELL(key) +#define VERIFY_VALUE_LIST_CELL(cell) + +NTSTATUS +CmiInitializeTempHive( + IN OUT PEREGISTRY_HIVE Hive); + +NTSTATUS +CmiAddSubKey( + IN PEREGISTRY_HIVE RegistryHive, + IN PCM_KEY_NODE ParentKeyCell, + IN HCELL_INDEX ParentKeyCellOffset, + IN PCUNICODE_STRING SubKeyName, + IN ULONG CreateOptions, + OUT PCM_KEY_NODE *pSubKeyCell, + OUT HCELL_INDEX *pBlockOffset); + +NTSTATUS +CmiScanForSubKey( + IN PEREGISTRY_HIVE RegistryHive, + IN PCM_KEY_NODE KeyCell, + IN PCUNICODE_STRING SubKeyName, + IN ULONG Attributes, + OUT PCM_KEY_NODE *pSubKeyCell, + OUT HCELL_INDEX *pBlockOffset); + +NTSTATUS +CmiAddValueKey( + IN PEREGISTRY_HIVE RegistryHive, + IN PCM_KEY_NODE KeyCell, + IN HCELL_INDEX KeyCellOffset, + IN PCUNICODE_STRING ValueName, + OUT PCM_KEY_VALUE *pValueCell, + OUT HCELL_INDEX *pValueCellOffset); + +NTSTATUS +CmiScanForValueKey( + IN PEREGISTRY_HIVE RegistryHive, + IN PCM_KEY_NODE KeyCell, + IN PCUNICODE_STRING ValueName, + OUT PCM_KEY_VALUE *pValueCell, + OUT HCELL_INDEX *pValueCellOffset); diff --git a/reactos/tools/mkhive/mkhive.c b/reactos/tools/mkhive/mkhive.c index 1bfa3c5070c..360021e9030 100644 --- a/reactos/tools/mkhive/mkhive.c +++ b/reactos/tools/mkhive/mkhive.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2003 ReactOS Team + * Copyright (C) 2003, 2006 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 @@ -16,12 +16,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS hive maker * FILE: tools/mkhive/mkhive.c * PURPOSE: Hive maker * PROGRAMMER: Eric Kohl + * Hervé Poussineau */ #include @@ -29,9 +29,6 @@ #include #include "mkhive.h" -#include "registry.h" -#include "reginf.h" -#include "binhive.h" #ifdef _MSC_VER #include @@ -105,41 +102,33 @@ int main (int argc, char *argv[]) convert_path (FileName, argv[1]); strcat (FileName, DIR_SEPARATOR_STRING); strcat (FileName, "hivesys.inf"); - ImportRegistryFile (FileName, "AddReg", FALSE); + ImportRegistryFile (FileName); convert_path (FileName, argv[1]); strcat (FileName, DIR_SEPARATOR_STRING); strcat (FileName, "hivecls.inf"); - ImportRegistryFile (FileName, "AddReg", FALSE); + ImportRegistryFile (FileName); convert_path (FileName, argv[1]); strcat (FileName, DIR_SEPARATOR_STRING); strcat (FileName, "hivesft.inf"); - ImportRegistryFile (FileName, "AddReg", FALSE); + ImportRegistryFile (FileName); convert_path (FileName, argv[1]); strcat (FileName, DIR_SEPARATOR_STRING); strcat (FileName, "hivedef.inf"); - ImportRegistryFile (FileName, "AddReg", FALSE); + ImportRegistryFile (FileName); for (Param = 3; Param < argc; Param++) { convert_path (FileName, argv[Param]); - ImportRegistryFile (FileName, "AddReg", FALSE); + ImportRegistryFile (FileName); } convert_path (FileName, argv[2]); strcat (FileName, DIR_SEPARATOR_STRING); - strcat (FileName, "system"); - if (!ExportBinaryHive (FileName, "\\Registry\\Machine\\SYSTEM")) - { - return 1; - } - - convert_path (FileName, argv[2]); - strcat (FileName, DIR_SEPARATOR_STRING); - strcat (FileName, "software"); - if (!ExportBinaryHive (FileName, "\\Registry\\Machine\\SOFTWARE")) + strcat (FileName, "default"); + if (!ExportBinaryHive (FileName, &DefaultHive)) { return 1; } @@ -147,7 +136,7 @@ int main (int argc, char *argv[]) convert_path (FileName, argv[2]); strcat (FileName, DIR_SEPARATOR_STRING); strcat (FileName, "sam"); - if (!ExportBinaryHive (FileName, "\\Registry\\Machine\\SAM")) + if (!ExportBinaryHive (FileName, &SamHive)) { return 1; } @@ -155,15 +144,23 @@ int main (int argc, char *argv[]) convert_path (FileName, argv[2]); strcat (FileName, DIR_SEPARATOR_STRING); strcat (FileName, "security"); - if (!ExportBinaryHive (FileName, "\\Registry\\Machine\\SECURITY")) + if (!ExportBinaryHive (FileName, &SecurityHive)) { return 1; } convert_path (FileName, argv[2]); strcat (FileName, DIR_SEPARATOR_STRING); - strcat (FileName, "default"); - if (!ExportBinaryHive (FileName, "\\Registry\\User\\.DEFAULT")) + strcat (FileName, "software"); + if (!ExportBinaryHive (FileName, &SoftwareHive)) + { + return 1; + } + + convert_path (FileName, argv[2]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "system"); + if (!ExportBinaryHive (FileName, &SystemHive)) { return 1; } diff --git a/reactos/tools/mkhive/mkhive.h b/reactos/tools/mkhive/mkhive.h index c4f83860339..a81322cb77f 100644 --- a/reactos/tools/mkhive/mkhive.h +++ b/reactos/tools/mkhive/mkhive.h @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2003 ReactOS Team + * Copyright (C) 2003, 2006 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 @@ -16,43 +16,33 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS hive maker * FILE: tools/mkhive/mkhive.h * PURPOSE: Hive maker * PROGRAMMER: Eric Kohl + * Hervé Poussineau */ #ifndef __MKHIVE_H__ #define __MKHIVE_H__ +#include -#define VOID void -typedef void *PVOID; -typedef char CHAR, *PCHAR; -typedef short WCHAR, *PWCHAR; -typedef unsigned char UCHAR, *PUCHAR; -typedef short SHORT, *PSHORT; -typedef unsigned short USHORT, *PUSHORT; -typedef long LONG, *PLONG; -typedef unsigned long ULONG, *PULONG; - -typedef unsigned long ULONG_PTR; - -typedef int BOOL, *PBOOL; - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef NULL -#define NULL ((void*)0) -#endif +#define NTOS_MODE_USER +#define WIN32_NO_STATUS +#include +#include +#include +#include "reginf.h" +#include "cmi.h" +#include "registry.h" +#include "binhive.h" +#define HIVE_NO_FILE 2 +#define VERIFY_REGISTRY_HIVE(hive) +extern LIST_ENTRY CmiHiveListHead; +#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V)) #ifndef max #define max(a, b) (((a) > (b)) ? (a) : (b)) @@ -88,7 +78,7 @@ static void DPRINT ( const char* fmt, ... ) #ifdef WIN32 #define strncasecmp strnicmp -#define strcasecmp stricmp +#define strcasecmp _stricmp #endif//WIN32 #ifdef _MSC_VER diff --git a/reactos/tools/mkhive/mkhive.mak b/reactos/tools/mkhive/mkhive.mak index 0feaeaee53f..1f847076ae1 100644 --- a/reactos/tools/mkhive/mkhive.mak +++ b/reactos/tools/mkhive/mkhive.mak @@ -1,61 +1,73 @@ -MKHIVE_BASE = $(TOOLS_BASE_)mkhive -MKHIVE_BASE_ = $(MKHIVE_BASE)$(SEP) -MKHIVE_INT = $(INTERMEDIATE_)$(MKHIVE_BASE) -MKHIVE_INT_ = $(MKHIVE_INT)$(SEP) -MKHIVE_OUT = $(OUTPUT_)$(MKHIVE_BASE) -MKHIVE_OUT_ = $(MKHIVE_OUT)$(SEP) - -$(MKHIVE_INT): | $(TOOLS_INT) - $(ECHO_MKDIR) - ${mkdir} $@ - -ifneq ($(INTERMEDIATE),$(OUTPUT)) -$(MKHIVE_OUT): | $(TOOLS_OUT) - $(ECHO_MKDIR) - ${mkdir} $@ -endif - -MKHIVE_TARGET = \ - $(EXEPREFIX)$(MKHIVE_OUT_)mkhive$(EXEPOSTFIX) - -MKHIVE_SOURCES = $(addprefix $(MKHIVE_BASE_), \ - binhive.c \ - mkhive.c \ - reginf.c \ - registry.c \ - ) - -MKHIVE_OBJECTS = \ - $(addprefix $(INTERMEDIATE_), $(MKHIVE_SOURCES:.c=.o)) - -MKHIVE_HOST_CFLAGS = $(xTOOLS_CFLAGS) -I$(INFLIB_BASE) -g3 - -MKHIVE_HOST_LFLAGS = $(xTOOLS_LFLAGS) -g3 - -.PHONY: mkhive -mkhive: $(MKHIVE_TARGET) - -$(MKHIVE_TARGET): $(MKHIVE_OBJECTS) $(INFLIB_HOST_OBJECTS) | $(MKHIVE_OUT) - $(ECHO_LD) - ${host_gcc} $(MKHIVE_OBJECTS) $(INFLIB_HOST_OBJECTS) $(MKHIVE_HOST_LFLAGS) -o $@ - -$(MKHIVE_INT_)binhive.o: $(MKHIVE_BASE_)binhive.c | $(MKHIVE_INT) - $(ECHO_CC) - ${host_gcc} $(MKHIVE_HOST_CFLAGS) -c $< -o $@ - -$(MKHIVE_INT_)mkhive.o: $(MKHIVE_BASE_)mkhive.c | $(MKHIVE_INT) - $(ECHO_CC) - ${host_gcc} $(MKHIVE_HOST_CFLAGS) -c $< -o $@ - -$(MKHIVE_INT_)reginf.o: $(MKHIVE_BASE_)reginf.c | $(MKHIVE_INT) - $(ECHO_CC) - ${host_gcc} $(MKHIVE_HOST_CFLAGS) -c $< -o $@ - -$(MKHIVE_INT_)registry.o: $(MKHIVE_BASE_)registry.c | $(MKHIVE_INT) - $(ECHO_CC) - ${host_gcc} $(MKHIVE_HOST_CFLAGS) -c $< -o $@ - -.PHONY: mkhive_clean -mkhive_clean: - -@$(rm) $(MKHIVE_TARGET) $(MKHIVE_OBJECTS) 2>$(NUL) -clean: mkhive_clean +MKHIVE_BASE = $(TOOLS_BASE_)mkhive +MKHIVE_BASE_ = $(MKHIVE_BASE)$(SEP) +MKHIVE_INT = $(INTERMEDIATE_)$(MKHIVE_BASE) +MKHIVE_INT_ = $(MKHIVE_INT)$(SEP) +MKHIVE_OUT = $(OUTPUT_)$(MKHIVE_BASE) +MKHIVE_OUT_ = $(MKHIVE_OUT)$(SEP) + +$(MKHIVE_INT): | $(TOOLS_INT) + $(ECHO_MKDIR) + ${mkdir} $@ + +ifneq ($(INTERMEDIATE),$(OUTPUT)) +$(MKHIVE_OUT): | $(TOOLS_OUT) + $(ECHO_MKDIR) + ${mkdir} $@ +endif + +MKHIVE_TARGET = \ + $(EXEPREFIX)$(MKHIVE_OUT_)mkhive$(EXEPOSTFIX) + +MKHIVE_SOURCES = $(addprefix $(MKHIVE_BASE_), \ + binhive.c \ + cmi.c \ + mkhive.c \ + reginf.c \ + registry.c \ + rtl.c \ + ) + +MKHIVE_OBJECTS = \ + $(addprefix $(INTERMEDIATE_), $(MKHIVE_SOURCES:.c=.o)) + +MKHIVE_HOST_CFLAGS = $(xTOOLS_CFLAGS) -I$(INFLIB_BASE) -I$(CMLIB_BASE) \ + -D_NTOSKRNL_ \ + -Iinclude/reactos -Iinclude/ddk -Iinclude/ndk -Iinclude/psdk -Iinclude -g3 + +MKHIVE_HOST_LFLAGS = $(xTOOLS_LFLAGS) -g3 + +.PHONY: mkhive +mkhive: $(MKHIVE_TARGET) + +$(MKHIVE_TARGET): $(MKHIVE_OBJECTS) $(INFLIB_HOST_OBJECTS) $(CMLIB_HOST_OBJECTS) | $(MKHIVE_OUT) + $(ECHO_LD) + ${host_gcc} $(MKHIVE_OBJECTS) $(INFLIB_HOST_OBJECTS) $(CMLIB_HOST_OBJECTS) $(MKHIVE_HOST_LFLAGS) -o $@ + +$(MKHIVE_INT_)binhive.o: $(MKHIVE_BASE_)binhive.c | $(MKHIVE_INT) + $(ECHO_CC) + ${host_gcc} $(MKHIVE_HOST_CFLAGS) -c $< -o $@ + +$(MKHIVE_INT_)cmi.o: $(MKHIVE_BASE_)cmi.c | $(MKHIVE_INT) + $(ECHO_CC) + ${host_gcc} $(MKHIVE_HOST_CFLAGS) -c $< -o $@ + +$(MKHIVE_INT_)mkhive.o: $(MKHIVE_BASE_)mkhive.c | $(MKHIVE_INT) + $(ECHO_CC) + ${host_gcc} $(MKHIVE_HOST_CFLAGS) -c $< -o $@ + +$(MKHIVE_INT_)reginf.o: $(MKHIVE_BASE_)reginf.c | $(MKHIVE_INT) + $(ECHO_CC) + ${host_gcc} $(MKHIVE_HOST_CFLAGS) -c $< -o $@ + +$(MKHIVE_INT_)registry.o: $(MKHIVE_BASE_)registry.c | $(MKHIVE_INT) + $(ECHO_CC) + ${host_gcc} $(MKHIVE_HOST_CFLAGS) -c $< -o $@ + +$(MKHIVE_INT_)rtl.o: $(MKHIVE_BASE_)rtl.c | $(MKHIVE_INT) + $(ECHO_CC) + ${host_gcc} $(MKHIVE_HOST_CFLAGS) -Ilib/rtl -c $< -o $@ + +.PHONY: mkhive_clean +mkhive_clean: + -@$(rm) $(MKHIVE_TARGET) $(MKHIVE_OBJECTS) 2>$(NUL) +clean: mkhive_clean diff --git a/reactos/tools/mkhive/reginf.c b/reactos/tools/mkhive/reginf.c index 5cbd8992c8c..da801aed086 100644 --- a/reactos/tools/mkhive/reginf.c +++ b/reactos/tools/mkhive/reginf.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2003 ReactOS Team + * Copyright (C) 2003, 2006 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 @@ -16,12 +16,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS hive maker * FILE: tools/mkhive/reginf.h * PURPOSE: Inf file import code * PROGRAMMER: Eric Kohl + * Hervé Poussineau */ /* INCLUDES *****************************************************************/ @@ -30,11 +30,8 @@ #include #include +#define NDEBUG #include "mkhive.h" -#include "registry.h" -#include - - #define FLG_ADDREG_BINVALUETYPE 0x00000001 #define FLG_ADDREG_NOCLOBBER 0x00000002 @@ -98,18 +95,19 @@ static VOID AppendMultiSzValue (HKEY KeyHandle, PCHAR ValueName, PCHAR Strings, - ULONG StringSize) + SIZE_T StringSize) { - ULONG Size; + SIZE_T Size; ULONG Type; - ULONG Total; + size_t Total; PCHAR Buffer; PCHAR p; - int len; + size_t len; LONG Error; - Error = RegQueryValue (KeyHandle, + Error = RegQueryValueExA (KeyHandle, ValueName, + NULL, &Type, NULL, &Size); @@ -121,10 +119,11 @@ AppendMultiSzValue (HKEY KeyHandle, if (Buffer == NULL) return; - Error = RegQueryValue (KeyHandle, + Error = RegQueryValueExA (KeyHandle, ValueName, NULL, - (PCHAR)Buffer, + NULL, + (PUCHAR)Buffer, &Size); if (Error != ERROR_SUCCESS) goto done; @@ -151,11 +150,12 @@ AppendMultiSzValue (HKEY KeyHandle, if (Total != Size) { DPRINT ("setting value %s to %s\n", ValueName, Buffer); - RegSetValue (KeyHandle, + RegSetValueExA (KeyHandle, ValueName, + 0, REG_MULTI_SZ, (PCHAR)Buffer, - Total); + (ULONG)Total); } done: @@ -176,19 +176,19 @@ do_reg_operation(HKEY KeyHandle, { CHAR EmptyStr = (CHAR)0; ULONG Type; - ULONG Size; + SIZE_T Size; LONG Error; if (Flags & FLG_ADDREG_DELVAL) /* deletion */ { if (ValueName) { - RegDeleteValue (KeyHandle, + RegDeleteValueA (KeyHandle, ValueName); } else { - RegDeleteKey (KeyHandle, + RegDeleteKeyA (KeyHandle, NULL); } @@ -200,10 +200,11 @@ do_reg_operation(HKEY KeyHandle, if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY)) { - Error = RegQueryValue (KeyHandle, + Error = RegQueryValueExA (KeyHandle, ValueName, NULL, NULL, + NULL, NULL); if ((Error == ERROR_SUCCESS) && (Flags & FLG_ADDREG_NOCLOBBER)) @@ -300,10 +301,11 @@ do_reg_operation(HKEY KeyHandle, DPRINT("setting dword %s to %lx\n", ValueName, dw); - RegSetValue (KeyHandle, + RegSetValueExA (KeyHandle, ValueName, + 0, Type, - (PVOID)&dw, + (const PUCHAR)&dw, sizeof(ULONG)); } else @@ -312,19 +314,21 @@ do_reg_operation(HKEY KeyHandle, if (Str) { - RegSetValue (KeyHandle, + RegSetValueExA (KeyHandle, ValueName, + 0, Type, (PVOID)Str, - Size); + (ULONG)Size); } else { - RegSetValue (KeyHandle, + RegSetValueExA (KeyHandle, ValueName, + 0, Type, (PVOID)&EmptyStr, - sizeof(CHAR)); + (ULONG)sizeof(CHAR)); } } free (Str); @@ -346,11 +350,12 @@ do_reg_operation(HKEY KeyHandle, InfHostGetBinaryField (Context, 5, Data, Size, NULL); } - RegSetValue (KeyHandle, + RegSetValueExA (KeyHandle, ValueName, + 0, Type, (PVOID)Data, - Size); + (ULONG)Size); free (Data); } @@ -370,7 +375,7 @@ registry_callback (HINF hInf, PCHAR Section, BOOL Delete) CHAR Buffer[MAX_INF_STRING_LENGTH]; PCHAR ValuePtr; ULONG Flags; - ULONG Length; + size_t Length; PINFCONTEXT Context = NULL; HKEY KeyHandle; @@ -411,7 +416,7 @@ registry_callback (HINF hInf, PCHAR Section, BOOL Delete) if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) { - if (RegOpenKey (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS) + if (RegOpenKeyA (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS) { DPRINT("RegOpenKey(%s) failed\n", Buffer); continue; /* ignore if it doesn't exist */ @@ -419,7 +424,7 @@ registry_callback (HINF hInf, PCHAR Section, BOOL Delete) } else { - if (RegCreateKey (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS) + if (RegCreateKeyA (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS) { DPRINT("RegCreateKey(%s) failed\n", Buffer); continue; @@ -450,9 +455,7 @@ registry_callback (HINF hInf, PCHAR Section, BOOL Delete) BOOL -ImportRegistryFile(PCHAR FileName, - PCHAR Section, - BOOL Delete) +ImportRegistryFile(PCHAR FileName) { HINF hInf; ULONG ErrorLine; diff --git a/reactos/tools/mkhive/reginf.h b/reactos/tools/mkhive/reginf.h index 65cfd925f3f..04e8b0bebbf 100644 --- a/reactos/tools/mkhive/reginf.h +++ b/reactos/tools/mkhive/reginf.h @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2003 ReactOS Team + * Copyright (C) 2006 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 @@ -16,21 +16,18 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS hive maker * FILE: tools/mkhive/reginf.h * PURPOSE: Inf file import code - * PROGRAMMER: Eric Kohl + * PROGRAMMER: Hervé Poussineau */ #ifndef __REGINF_H__ #define __REGINF_H__ BOOL -ImportRegistryFile(PCHAR Filename, - PCHAR Section, - BOOL Delete); +ImportRegistryFile(PCHAR Filename); #endif /* __REGINF_H__ */ diff --git a/reactos/tools/mkhive/registry.c b/reactos/tools/mkhive/registry.c index 105f897fb22..f4863d37850 100644 --- a/reactos/tools/mkhive/registry.c +++ b/reactos/tools/mkhive/registry.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2003 ReactOS Team + * Copyright (C) 2006 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 @@ -16,230 +16,230 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS hive maker * FILE: tools/mkhive/registry.c * PURPOSE: Registry code - * PROGRAMMER: Eric Kohl + * PROGRAMMER: Hervé Poussineau */ /* * TODO: - * - Implement RegDeleteKey(). - * - Fix RegEnumValue(). + * - Implement RegDeleteKey() + * - Implement RegEnumValue() + * - Implement RegQueryValueExA() */ #include #include #include +#define NDEBUG #include "mkhive.h" -#include "registry.h" +static EREGISTRY_HIVE RootHive; +static MEMKEY RootKey; +EREGISTRY_HIVE DefaultHive; /* \Registry\User\.DEFAULT */ +EREGISTRY_HIVE SamHive; /* \Registry\Machine\SAM */ +EREGISTRY_HIVE SecurityHive; /* \Registry\Machine\SECURITY */ +EREGISTRY_HIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */ +EREGISTRY_HIVE SystemHive; /* \Registry\Machine\SYSTEM */ -static HKEY RootKey; - - -VOID -RegInitializeRegistry(VOID) +static MEMKEY +CreateInMemoryStructure( + IN PEREGISTRY_HIVE RegistryHive, + IN HCELL_INDEX KeyCellOffset, + IN PCUNICODE_STRING KeyName) { - HKEY ControlSetKey; - HKEY LinkKey; + MEMKEY Key; - /* Create root key */ - RootKey = (HKEY)malloc(sizeof(KEY)); + Key = (MEMKEY) malloc (sizeof(KEY)); + if (!Key) + return NULL; - InitializeListHead(&RootKey->SubKeyList); - InitializeListHead(&RootKey->ValueList); - InitializeListHead(&RootKey->KeyList); + InitializeListHead (&Key->SubKeyList); + InitializeListHead (&Key->ValueList); + InitializeListHead (&Key->KeyList); - RootKey->SubKeyCount = 0; - RootKey->ValueCount = 0; + Key->SubKeyCount = 0; + Key->ValueCount = 0; - RootKey->NameSize = 2; - RootKey->Name = (PCHAR)malloc(2); - strcpy(RootKey->Name, "\\"); + Key->NameSize = KeyName->Length; + Key->Name = malloc (Key->NameSize); + if (!Key->Name) + return NULL; + memcpy(Key->Name, KeyName->Buffer, KeyName->Length); - RootKey->DataType = 0; - RootKey->DataSize = 0; - RootKey->Data = NULL; + Key->DataType = 0; + Key->DataSize = 0; + Key->Data = NULL; - /* Create SYSTEM key */ - RegCreateKey(RootKey, - "Registry\\Machine\\SYSTEM", - NULL); - - /* Create link 'CurrentControlSet' --> 'ControlSet001' */ - RegCreateKey(RootKey, - "Registry\\Machine\\SYSTEM\\ControlSet001", - &ControlSetKey); - - RegCreateKey(RootKey, - "Registry\\Machine\\SYSTEM\\CurrentControlSet", - &LinkKey); - - RegSetValue(LinkKey, - NULL, - REG_LINK, - (PCHAR)&ControlSetKey, - sizeof(PVOID)); - - /* Create HARDWARE key */ - RegCreateKey(RootKey, - "Registry\\Machine\\HARDWARE", - NULL); - - /* Create SAM key */ - RegCreateKey(RootKey, - "Registry\\Machine\\SAM", - NULL); - - /* Create SECURITY key */ - RegCreateKey(RootKey, - "Registry\\Machine\\SECURITY", - NULL); - - /* Create SOFTWARE key */ - RegCreateKey(RootKey, - "Registry\\Machine\\SOFTWARE", - NULL); - - /* Create DEFAULT key */ - RegCreateKey(RootKey, - "Registry\\User\\.DEFAULT", - NULL); + Key->RegistryHive = RegistryHive; + Key->KeyCellOffset = KeyCellOffset; + Key->KeyCell = HvGetCell (&RegistryHive->Hive, Key->KeyCellOffset); + if (!Key->KeyCell) + { + free(Key); + return NULL; + } + Key->LinkedKey = NULL; + return Key; } - -LONG -RegCreateKey(HKEY ParentKey, - PCHAR KeyName, - PHKEY Key) +static LONG +RegpOpenOrCreateKey( + IN HKEY hParentKey, + IN PCWSTR KeyName, + IN BOOL AllowCreation, + OUT PHKEY Key) { - PLIST_ENTRY Ptr; - HKEY SearchKey = INVALID_HANDLE_VALUE; - HKEY CurrentKey; - HKEY NewKey; - PCHAR p; - PCHAR name; - int subkeyLength; - int stringLength; + PWSTR LocalKeyName; + PWSTR End; + UNICODE_STRING KeyString; + NTSTATUS Status; + MEMKEY ParentKey; + MEMKEY CurrentKey; + PLIST_ENTRY Ptr; + PCM_KEY_NODE SubKeyCell; + HCELL_INDEX BlockOffset; - DPRINT ("RegCreateKey('%s')\n", KeyName); + DPRINT("RegpCreateOpenKey('%S')\n", KeyName); - if (*KeyName == '\\') - { - KeyName++; - CurrentKey = RootKey; - } - else if (ParentKey == NULL) - { - CurrentKey = RootKey; - } - else - { - CurrentKey = ParentKey; - } - - /* Check whether current key is a link */ - if (CurrentKey->DataType == REG_LINK) - { - CurrentKey = (HKEY)CurrentKey->Data; - } - - while (*KeyName != 0) - { - DPRINT ("KeyName '%s'\n", KeyName); - - if (*KeyName == '\\') - KeyName++; - p = strchr (KeyName, '\\'); - if ((p != NULL) && (p != KeyName)) + if (*KeyName == L'\\') { - subkeyLength = p - KeyName; - stringLength = subkeyLength + 1; - name = KeyName; + KeyName++; + ParentKey = RootKey; } - else + else if (hParentKey == NULL) { - subkeyLength = strlen (KeyName); - stringLength = subkeyLength; - name = KeyName; + ParentKey = RootKey; + } + else + { + ParentKey = HKEY_TO_MEMKEY(RootKey); } - Ptr = CurrentKey->SubKeyList.Flink; - while (Ptr != &CurrentKey->SubKeyList) + LocalKeyName = (PWSTR)KeyName; + for (;;) { - DPRINT ("Ptr 0x%p\n", Ptr); + End = wcschr(LocalKeyName, '\\'); + if (End) + { + KeyString.Buffer = LocalKeyName; + KeyString.Length = KeyString.MaximumLength = + (USHORT)((ULONG_PTR)End - (ULONG_PTR)LocalKeyName); + } + else + RtlInitUnicodeString(&KeyString, LocalKeyName); - SearchKey = CONTAINING_RECORD(Ptr, - KEY, - KeyList); - DPRINT ("SearchKey 0x%p\n", SearchKey); - DPRINT ("Searching '%s'\n", SearchKey->Name); - if (strncasecmp (SearchKey->Name, name, subkeyLength) == 0) - break; + /* Check subkey in memory structure */ + Ptr = ParentKey->SubKeyList.Flink; + while (Ptr != &ParentKey->SubKeyList) + { + CurrentKey = CONTAINING_RECORD(Ptr, KEY, KeyList); + if (CurrentKey->NameSize == KeyString.Length + && memcmp(CurrentKey->Name, KeyString.Buffer, KeyString.Length) == 0) + { + goto nextsubkey; + } - Ptr = Ptr->Flink; + Ptr = Ptr->Flink; + } + + Status = CmiScanForSubKey( + ParentKey->RegistryHive, + ParentKey->KeyCell, + &KeyString, + 0, + &SubKeyCell, + &BlockOffset); + if (AllowCreation && Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + Status = CmiAddSubKey( + ParentKey->RegistryHive, + ParentKey->KeyCell, + ParentKey->KeyCellOffset, + &KeyString, + 0, + &SubKeyCell, + &BlockOffset); + } + if (!NT_SUCCESS(Status)) + return ERROR_UNSUCCESSFUL; + + /* Now, SubKeyCell/BlockOffset are valid */ + CurrentKey = CreateInMemoryStructure( + ParentKey->RegistryHive, + BlockOffset, + &KeyString); + if (!CurrentKey) + return ERROR_OUTOFMEMORY; + + /* Add CurrentKey in ParentKey */ + InsertTailList(&ParentKey->SubKeyList, &CurrentKey->KeyList); + ParentKey->SubKeyCount++; + +nextsubkey: + /* Follow registry links */ + while (CurrentKey->LinkedKey) + CurrentKey = CurrentKey->LinkedKey; + ParentKey = CurrentKey; + if (End) + LocalKeyName = End + 1; + else + break; } - if (Ptr == &CurrentKey->SubKeyList) - { - /* no key found -> create new subkey */ - NewKey = (HKEY)malloc (sizeof(KEY)); - if (NewKey == NULL) - return ERROR_OUTOFMEMORY; + *Key = MEMKEY_TO_HKEY(ParentKey); - InitializeListHead (&NewKey->SubKeyList); - InitializeListHead (&NewKey->ValueList); - - NewKey->SubKeyCount = 0; - NewKey->ValueCount = 0; - - NewKey->DataType = 0; - NewKey->DataSize = 0; - NewKey->Data = NULL; - - InsertTailList (&CurrentKey->SubKeyList, &NewKey->KeyList); - CurrentKey->SubKeyCount++; - - NewKey->NameSize = subkeyLength + 1; - NewKey->Name = (PCHAR)malloc (NewKey->NameSize); - if (NewKey->Name == NULL) - return(ERROR_OUTOFMEMORY); - memcpy(NewKey->Name, name, subkeyLength); - NewKey->Name[subkeyLength] = 0; - - DPRINT ("NewKey 0x%p\n", NewKey); - DPRINT ("NewKey '%s' Length %ld\n", NewKey->Name, NewKey->NameSize); - - CurrentKey = NewKey; - } - else - { - CurrentKey = SearchKey; - - /* Check whether current key is a link */ - if (CurrentKey->DataType == REG_LINK) - { - CurrentKey = (HKEY)CurrentKey->Data; - } - } - - KeyName = KeyName + stringLength; - } - - if (Key != NULL) - *Key = CurrentKey; - - return ERROR_SUCCESS; + return ERROR_SUCCESS; } +LONG WINAPI +RegCreateKeyW( + IN HKEY hKey, + IN LPCWSTR lpSubKey, + OUT PHKEY phkResult) +{ + return RegpOpenOrCreateKey(hKey, lpSubKey, TRUE, phkResult); +} -LONG -RegDeleteKey(HKEY Key, - PCHAR Name) +static PWSTR +MultiByteToWideChar( + IN PCSTR MultiByteString) +{ + ANSI_STRING Source; + UNICODE_STRING Destination; + NTSTATUS Status; + + RtlInitAnsiString(&Source, MultiByteString); + Status = RtlAnsiStringToUnicodeString(&Destination, &Source, TRUE); + if (!NT_SUCCESS(Status)) + return NULL; + return Destination.Buffer; +} + +LONG WINAPI +RegCreateKeyA( + IN HKEY hKey, + IN LPCSTR lpSubKey, + OUT PHKEY phkResult) +{ + PWSTR lpSubKeyW; + LONG rc; + + lpSubKeyW = MultiByteToWideChar(lpSubKey); + if (!lpSubKeyW) + return ERROR_OUTOFMEMORY; + + rc = RegCreateKeyW(hKey, lpSubKeyW, phkResult); + free(lpSubKeyW); + return rc; +} + +LONG WINAPI +RegDeleteKeyA(HKEY Key, + LPCSTR Name) { if (Name != NULL && strchr(Name, '\\') != NULL) return(ERROR_INVALID_PARAMETER); @@ -249,458 +249,432 @@ RegDeleteKey(HKEY Key, return(ERROR_SUCCESS); } - -LONG -RegEnumKey(HKEY Key, - ULONG Index, - PCHAR Name, - PULONG NameSize) +LONG WINAPI +RegOpenKeyW( + IN HKEY hKey, + IN LPCWSTR lpSubKey, + OUT PHKEY phkResult) { - PLIST_ENTRY Ptr; - HKEY SearchKey; - ULONG Count = 0; - ULONG Size; - - Ptr = Key->SubKeyList.Flink; - while (Ptr != &Key->SubKeyList) - { - if (Index == Count) - break; - - Count++; - Ptr = Ptr->Flink; - } - - if (Ptr == &Key->SubKeyList) - return(ERROR_NO_MORE_ITEMS); - - SearchKey = CONTAINING_RECORD(Ptr, - KEY, - KeyList); - - DPRINT ("Name '%s' Length %ld\n", SearchKey->Name, SearchKey->NameSize); - - Size = min(SearchKey->NameSize, *NameSize); - *NameSize = Size; - memcpy(Name, SearchKey->Name, Size); - - return(ERROR_SUCCESS); + return RegpOpenOrCreateKey(hKey, lpSubKey, FALSE, phkResult); } - -LONG -RegOpenKey(HKEY ParentKey, - PCHAR KeyName, - PHKEY Key) +LONG WINAPI +RegOpenKeyA( + IN HKEY hKey, + IN LPCSTR lpSubKey, + OUT PHKEY phkResult) { - PLIST_ENTRY Ptr; - HKEY SearchKey = INVALID_HANDLE_VALUE; - HKEY CurrentKey; - PCHAR p; - PCHAR name; - int subkeyLength; - int stringLength; + PWSTR lpSubKeyW; + LONG rc; - DPRINT("KeyName '%s'\n", KeyName); + lpSubKeyW = MultiByteToWideChar(lpSubKey); + if (!lpSubKeyW) + return ERROR_OUTOFMEMORY; - *Key = NULL; - - if (*KeyName == '\\') - { - KeyName++; - CurrentKey = RootKey; - } - else if (ParentKey == NULL) - { - CurrentKey = RootKey; - } - else - { - CurrentKey = ParentKey; - } - - /* Check whether current key is a link */ - if (CurrentKey->DataType == REG_LINK) - { - CurrentKey = (HKEY)CurrentKey->Data; - } - - while (*KeyName != 0) - { - DPRINT ("KeyName '%s'\n", KeyName); - - if (*KeyName == '\\') - KeyName++; - p = strchr(KeyName, '\\'); - if ((p != NULL) && (p != KeyName)) - { - subkeyLength = p - KeyName; - stringLength = subkeyLength + 1; - name = KeyName; - } - else - { - subkeyLength = strlen(KeyName); - stringLength = subkeyLength; - name = KeyName; - } - - Ptr = CurrentKey->SubKeyList.Flink; - while (Ptr != &CurrentKey->SubKeyList) - { - DPRINT ("Ptr 0x%p\n", Ptr); - - SearchKey = CONTAINING_RECORD(Ptr, - KEY, - KeyList); - - DPRINT ("SearchKey 0x%p\n", SearchKey); - DPRINT ("Searching '%s'\n", SearchKey->Name); - - if (strncasecmp(SearchKey->Name, name, subkeyLength) == 0) - break; - - Ptr = Ptr->Flink; - } - - if (Ptr == &CurrentKey->SubKeyList) - { - return(ERROR_PATH_NOT_FOUND); - } - else - { - CurrentKey = SearchKey; - - /* Check whether current key is a link */ - if (CurrentKey->DataType == REG_LINK) - { - CurrentKey = (HKEY)CurrentKey->Data; - } - } - - KeyName = KeyName + stringLength; - } - - if (Key != NULL) - *Key = CurrentKey; - - return(ERROR_SUCCESS); + rc = RegOpenKeyW(hKey, lpSubKeyW, phkResult); + free(lpSubKeyW); + return rc; } - -LONG -RegSetValue(HKEY Key, - PCHAR ValueName, - ULONG Type, - PCHAR Data, - ULONG DataSize) +static NTSTATUS +RegpOpenOrCreateValue( + IN HKEY hKey, + IN LPCWSTR ValueName, + IN BOOL AllowCreation, + OUT PCM_KEY_VALUE *ValueCell, + OUT PHCELL_INDEX ValueCellOffset) { - PLIST_ENTRY Ptr; - PVALUE Value = NULL; + MEMKEY ParentKey; + UNICODE_STRING ValueString; + NTSTATUS Status; - DPRINT ("Key 0x%x, ValueName '%s', Type %d, Data 0x%x, DataSize %d\n", - (int)Key, ValueName, (int)Type, (int)Data, (int)DataSize); + ParentKey = HKEY_TO_MEMKEY(hKey); + RtlInitUnicodeString(&ValueString, ValueName); - if ((ValueName == NULL) || (*ValueName == 0)) - { - /* set default value */ - if ((Key->Data != NULL) && (Key->DataSize > sizeof(PCHAR))) + Status = CmiScanForValueKey( + ParentKey->RegistryHive, + ParentKey->KeyCell, + &ValueString, + ValueCell, + ValueCellOffset); + if (AllowCreation && Status == STATUS_OBJECT_NAME_NOT_FOUND) { - free(Key->Data); + Status = CmiAddValueKey( + ParentKey->RegistryHive, + ParentKey->KeyCell, + ParentKey->KeyCellOffset, + &ValueString, + ValueCell, + ValueCellOffset); } - - if (DataSize <= sizeof(PCHAR)) - { - Key->DataSize = DataSize; - Key->DataType = Type; - memcpy(&Key->Data, Data, DataSize); - } - else - { - Key->Data = (PCHAR)malloc(DataSize); - Key->DataSize = DataSize; - Key->DataType = Type; - memcpy(Key->Data, Data, DataSize); - } - } - else - { - /* set non-default value */ - Ptr = Key->ValueList.Flink; - while (Ptr != &Key->ValueList) - { - Value = CONTAINING_RECORD(Ptr, - VALUE, - ValueList); - - DPRINT ("Value->Name '%s'\n", Value->Name); - - if (strcasecmp(Value->Name, ValueName) == 0) - break; - - Ptr = Ptr->Flink; - } - - if (Ptr == &Key->ValueList) - { - /* add new value */ - DPRINT("No value found - adding new value\n"); - - Value = (PVALUE)malloc(sizeof(VALUE)); - if (Value == NULL) - return(ERROR_OUTOFMEMORY); - InsertTailList(&Key->ValueList, &Value->ValueList); - Key->ValueCount++; - Value->NameSize = strlen(ValueName)+1; - Value->Name = (PCHAR)malloc(Value->NameSize); - if (Value->Name == NULL) - return(ERROR_OUTOFMEMORY); - strcpy(Value->Name, ValueName); - Value->DataType = REG_NONE; - Value->DataSize = 0; - Value->Data = NULL; - } - - /* set new value */ - if ((Value->Data != NULL) && (Value->DataSize > sizeof(PCHAR))) - { - free(Value->Data); - } - - if (DataSize <= sizeof(PCHAR)) - { - Value->DataSize = DataSize; - Value->DataType = Type; - memcpy(&Value->Data, Data, DataSize); - } - else - { - Value->Data = (PCHAR)malloc(DataSize); - if (Value->Data == NULL) - return(ERROR_OUTOFMEMORY); - Value->DataType = Type; - Value->DataSize = DataSize; - memcpy(Value->Data, Data, DataSize); - } - } - return(ERROR_SUCCESS); + if (!NT_SUCCESS(Status)) + return Status; + return STATUS_SUCCESS; } - -LONG -RegQueryValue(HKEY Key, - PCHAR ValueName, - PULONG Type, - PCHAR Data, - PULONG DataSize) +LONG WINAPI +RegSetValueExW( + IN HKEY hKey, + IN LPCWSTR lpValueName OPTIONAL, + IN ULONG Reserved, + IN ULONG dwType, + IN const PUCHAR lpData, + IN USHORT cbData) { - ULONG Size; - PLIST_ENTRY Ptr; - PVALUE Value = NULL; + MEMKEY Key, DestKey; + PHKEY phKey; + PCM_KEY_VALUE ValueCell; + HCELL_INDEX ValueCellOffset; + PVOID DataCell; + LONG DataCellSize; + NTSTATUS Status; - if ((ValueName == NULL) || (*ValueName == 0)) - { - /* query default value */ - if (Key->Data == NULL) - return(ERROR_INVALID_PARAMETER); - - if (Type != NULL) - *Type = Key->DataType; - if ((Data != NULL) && (DataSize != NULL)) + if (dwType == REG_LINK) { - if (Key->DataSize <= sizeof(PCHAR)) - { - Size = min(Key->DataSize, *DataSize); - memcpy(Data, &Key->Data, Size); - *DataSize = Size; - } - else - { - Size = min(Key->DataSize, *DataSize); - memcpy(Data, Key->Data, Size); - *DataSize = Size; - } - } - else if ((Data == NULL) && (DataSize != NULL)) - { - *DataSize = Key->DataSize; - } - } - else - { - /* query non-default value */ - Ptr = Key->ValueList.Flink; - while (Ptr != &Key->ValueList) - { - Value = CONTAINING_RECORD(Ptr, - VALUE, - ValueList); + /* Special handling of registry links */ + if (cbData != sizeof(PVOID)) + return STATUS_INVALID_PARAMETER; + phKey = (PHKEY)lpData; + Key = HKEY_TO_MEMKEY(hKey); + DestKey = HKEY_TO_MEMKEY(*phKey); - DPRINT("Searching for '%s'. Value name '%s'\n", ValueName, Value->Name); + /* Create the link in memory */ + Key->LinkedKey = DestKey; - if (strcasecmp(Value->Name, ValueName) == 0) - break; - - Ptr = Ptr->Flink; + /* Create the link in registry hive (if applicable) */ + if (Key->RegistryHive != DestKey->RegistryHive) + return STATUS_SUCCESS; + DPRINT1("Save link to registry\n"); + return STATUS_NOT_IMPLEMENTED; } - if (Ptr == &Key->ValueList) - return(ERROR_INVALID_PARAMETER); + if ((cbData & REG_DATA_SIZE_MASK) != cbData) + return STATUS_UNSUCCESSFUL; - if (Type != NULL) - *Type = Value->DataType; - if ((Data != NULL) && (DataSize != NULL)) - { - if (Value->DataSize <= sizeof(PCHAR)) - { - Size = min(Value->DataSize, *DataSize); - memcpy(Data, &Value->Data, Size); - *DataSize = Size; - } - else - { - Size = min(Value->DataSize, *DataSize); - memcpy(Data, Value->Data, Size); - *DataSize = Size; - } - } - else if ((Data == NULL) && (DataSize != NULL)) - { - *DataSize = Value->DataSize; - } - } + Key = HKEY_TO_MEMKEY(hKey); - return(ERROR_SUCCESS); + Status = RegpOpenOrCreateValue(hKey, lpValueName, TRUE, &ValueCell, &ValueCellOffset); + if (!NT_SUCCESS(Status)) + return ERROR_UNSUCCESSFUL; + + /* Get size of the allocated cellule (if any) */ + if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET) && + (ValueCell->DataSize & REG_DATA_SIZE_MASK) != 0) + { + DataCell = HvGetCell(&Key->RegistryHive->Hive, ValueCell->DataOffset); + if (!DataCell) + return ERROR_UNSUCCESSFUL; + DataCellSize = -HvGetCellSize(&Key->RegistryHive->Hive, DataCell); + } + else + { + DataCell = NULL; + DataCellSize = 0; + } + + if (cbData <= sizeof(HCELL_INDEX)) + { + /* If data size <= sizeof(HCELL_INDEX) then store data in the data offset */ + DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize); + if (DataCell) + HvFreeCell(&Key->RegistryHive->Hive, ValueCell->DataOffset); + + RtlCopyMemory(&ValueCell->DataOffset, lpData, cbData); + ValueCell->DataSize = (ULONG)(cbData | REG_DATA_IN_OFFSET); + ValueCell->DataType = dwType; + HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset); + } + else + { + if (cbData > (SIZE_T)DataCellSize) + { + /* New data size is larger than the current, destroy current + * data block and allocate a new one. */ + HCELL_INDEX NewOffset; + + DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize); + + NewOffset = HvAllocateCell(&Key->RegistryHive->Hive, cbData, HvStable); + if (NewOffset == HCELL_NULL) + { + DPRINT("HvAllocateCell() failed with status 0x%08lx\n", Status); + return ERROR_UNSUCCESSFUL; + } + + if (DataCell) + HvFreeCell(&Key->RegistryHive->Hive, ValueCell->DataOffset); + + ValueCell->DataOffset = NewOffset; + DataCell = HvGetCell(&Key->RegistryHive->Hive, NewOffset); + } + + /* Copy new contents to cellule */ + RtlCopyMemory(DataCell, lpData, cbData); + ValueCell->DataSize = (ULONG)(cbData & REG_DATA_SIZE_MASK); + ValueCell->DataType = dwType; + HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->DataOffset); + HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset); + } + + HvMarkCellDirty(&Key->RegistryHive->Hive, Key->KeyCellOffset); + + DPRINT("Return status 0x%08lx\n", Status); + return Status; } - -LONG -RegDeleteValue(HKEY Key, - PCHAR ValueName) +LONG WINAPI +RegSetValueExA( + IN HKEY hKey, + IN LPCSTR lpValueName OPTIONAL, + IN ULONG Reserved, + IN ULONG dwType, + IN const PUCHAR lpData, + IN ULONG cbData) { - PLIST_ENTRY Ptr; - PVALUE Value = NULL; + LPWSTR lpValueNameW = NULL; + PUCHAR lpDataW; + USHORT cbDataW; + LONG rc = ERROR_SUCCESS; - if ((ValueName == NULL) || (*ValueName == 0)) - { - /* delete default value */ - if (Key->Data != NULL) - free(Key->Data); - Key->Data = NULL; - Key->DataSize = 0; - Key->DataType = 0; - } - else - { - /* delete non-default value */ - Ptr = Key->ValueList.Flink; - while (Ptr != &Key->ValueList) + DPRINT("RegSetValueA(%s)\n", lpValueName); + if (lpValueName) { - Value = CONTAINING_RECORD(Ptr, - VALUE, - ValueList); - if (strcasecmp(Value->Name, ValueName) == 0) - break; - - Ptr = Ptr->Flink; + lpValueNameW = MultiByteToWideChar(lpValueName); + if (!lpValueNameW) + return ERROR_OUTOFMEMORY; } - if (Ptr == &Key->ValueList) - return(ERROR_INVALID_PARAMETER); - - /* delete value */ - Key->ValueCount--; - if (Value->Name != NULL) - free(Value->Name); - Value->Name = NULL; - Value->NameSize = 0; - - if (Value->DataSize > sizeof(PCHAR)) + if ((dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ) + && cbData != 0) { - if (Value->Data != NULL) - free(Value->Data); - } - Value->Data = NULL; - Value->DataSize = 0; - Value->DataType = 0; + ANSI_STRING AnsiString; + UNICODE_STRING Data; - RemoveEntryList(&Value->ValueList); - free(Value); - } - return(ERROR_SUCCESS); + if (lpData[cbData - 1] != '\0') + cbData++; + RtlInitAnsiString(&AnsiString, NULL); + AnsiString.Buffer = (PSTR)lpData; + AnsiString.Length = (USHORT)cbData - 1; + AnsiString.MaximumLength = (USHORT)cbData; + RtlAnsiStringToUnicodeString (&Data, &AnsiString, TRUE); + lpDataW = (const PUCHAR)Data.Buffer; + cbDataW = Data.MaximumLength; + } + else + { + lpDataW = lpData; + cbDataW = (USHORT)cbData; + } + + if (rc == ERROR_SUCCESS) + rc = RegSetValueExW(hKey, lpValueNameW, 0, dwType, lpDataW, cbDataW); + if (lpValueNameW) + free(lpValueNameW); + if (lpData != lpDataW) + free(lpDataW); + return rc; } - -LONG -RegEnumValue(HKEY Key, - ULONG Index, - PCHAR ValueName, - PULONG NameSize, - PULONG Type, - PCHAR Data, - PULONG DataSize) +LONG WINAPI +RegQueryValueExW( + IN HKEY hKey, + IN LPCWSTR lpValueName, + IN PULONG lpReserved, + OUT PULONG lpType, + OUT PUCHAR lpData, + OUT PSIZE_T lpcbData) { - PLIST_ENTRY Ptr; - PVALUE Value; - ULONG Count = 0; + //ParentKey = HKEY_TO_MEMKEY(RootKey); + PCM_KEY_VALUE ValueCell; + HCELL_INDEX ValueCellOffset; + NTSTATUS Status; - if (Key->Data != NULL) - { - if (Index > 0) - { - Index--; - } - else - { - /* enumerate default value */ - if (ValueName != NULL) - *ValueName = 0; - if (Type != NULL) - *Type = Key->DataType; - if (DataSize != NULL) - *DataSize = Key->DataSize; + Status = RegpOpenOrCreateValue( + hKey, + lpValueName, + FALSE, + &ValueCell, + &ValueCellOffset); - /* FIXME: return more values */ - } - } - - Ptr = Key->ValueList.Flink; - while (Ptr != &Key->ValueList) - { - if (Index == Count) - break; - - Count++; - Ptr = Ptr->Flink; - } - - if (Ptr == &Key->ValueList) - return(ERROR_NO_MORE_ITEMS); - - Value = CONTAINING_RECORD(Ptr, - VALUE, - ValueList); - - /* FIXME: return values */ - - return(ERROR_SUCCESS); + //Status = CmiScanForValueKey( + // x + return ERROR_UNSUCCESSFUL; } - -USHORT -RegGetSubKeyCount (HKEY Key) +LONG WINAPI +RegQueryValueExA( + IN HKEY hKey, + IN LPCSTR lpValueName, + IN PULONG lpReserved, + OUT PULONG lpType, + OUT PUCHAR lpData, + OUT PSIZE_T lpcbData) { - return Key->SubKeyCount; + LPWSTR lpValueNameW = NULL; + LONG rc; + + DPRINT1("RegQueryValueExA(%s) not implemented\n", lpValueName); + if (lpValueName) + { + lpValueNameW = MultiByteToWideChar(lpValueName); + if (!lpValueNameW) + return ERROR_OUTOFMEMORY; + } + + rc = RegQueryValueExW(hKey, lpValueNameW, lpReserved, lpType, lpData, lpcbData); + if (lpValueNameW) + free(lpValueNameW); + return ERROR_UNSUCCESSFUL; } - -ULONG -RegGetValueCount (HKEY Key) +LONG WINAPI +RegDeleteValueW( + IN HKEY hKey, + IN LPCWSTR lpValueName OPTIONAL) { - if (Key->DataSize != 0) - return Key->ValueCount + 1; + DPRINT1("RegDeleteValueW() unimplemented\n"); + return ERROR_UNSUCCESSFUL; +} - return Key->ValueCount; +LONG WINAPI +RegDeleteValueA( + IN HKEY hKey, + IN LPCSTR lpValueName OPTIONAL) +{ + LPWSTR lpValueNameW; + LONG rc; + + if (lpValueName) + { + lpValueNameW = MultiByteToWideChar(lpValueName); + if (!lpValueNameW) + return ERROR_OUTOFMEMORY; + rc = RegDeleteValueW(hKey, lpValueNameW); + free(lpValueNameW); + } + else + rc = RegDeleteValueW(hKey, NULL); + return rc; +} + +static BOOL +ConnectRegistry( + IN HKEY RootKey, + IN PEREGISTRY_HIVE HiveToConnect, + IN LPCWSTR Path) +{ + NTSTATUS Status; + MEMKEY NewKey; + LONG rc; + + Status = CmiInitializeTempHive(HiveToConnect); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmiInitializeTempHive() failed with status 0x%08lx\n", Status); + return FALSE; + } + + /* Create key */ + rc = RegCreateKeyW( + RootKey, + Path, + (PHKEY)&NewKey); + if (rc != ERROR_SUCCESS) + return FALSE; + + NewKey->RegistryHive = HiveToConnect; + NewKey->KeyCellOffset = HiveToConnect->Hive.HiveHeader->RootCell; + NewKey->KeyCell = HvGetCell (&HiveToConnect->Hive, NewKey->KeyCellOffset); + return TRUE; +} + +static BOOL +MyExportBinaryHive (PCHAR FileName, + PEREGISTRY_HIVE RootHive) +{ + FILE *File; + BOOL ret; + + /* Create new hive file */ + File = fopen (FileName, "w+b"); + if (File == NULL) + { + printf(" Error creating/opening file\n"); + return FALSE; + } + + fseek (File, 0, SEEK_SET); + + RootHive->HiveHandle = (HANDLE)File; + ret = HvWriteHive(&RootHive->Hive); + fclose (File); + return ret; +} + +LIST_ENTRY CmiHiveListHead; + +VOID +RegInitializeRegistry(VOID) +{ + UNICODE_STRING RootKeyName = RTL_CONSTANT_STRING(L"\\"); + NTSTATUS Status; + HKEY ControlSetKey, LinkKey; + + InitializeListHead(&CmiHiveListHead); + + Status = CmiInitializeTempHive(&RootHive); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmiInitializeTempHive() failed with status 0x%08lx\n", Status); + return; + } + + RootKey = CreateInMemoryStructure( + &RootHive, + RootHive.Hive.HiveHeader->RootCell, + &RootKeyName); + + /* Create DEFAULT key */ + ConnectRegistry( + NULL, + &DefaultHive, + L"Registry\\User\\.DEFAULT"); + + /* Create SAM key */ + ConnectRegistry( + NULL, + &SamHive, + L"Registry\\Machine\\SAM"); + + /* Create SECURITY key */ + ConnectRegistry( + NULL, + &SecurityHive, + L"Registry\\Machine\\SECURITY"); + + /* Create SOFTWARE key */ + ConnectRegistry( + NULL, + &SoftwareHive, + L"Registry\\Machine\\SOFTWARE"); + + /* Create SYSTEM key */ + ConnectRegistry( + NULL, + &SystemHive, + L"Registry\\Machine\\SYSTEM"); + + /* Create link 'CurrentControlSet' --> 'ControlSet001' */ + RegCreateKeyW( + NULL, + L"Registry\\Machine\\SYSTEM\\ControlSet001", + &ControlSetKey); + RegCreateKeyW( + NULL, + L"Registry\\Machine\\SYSTEM\\CurrentControlSet", + &LinkKey); + printf("ControlSetKey %p\n", ControlSetKey); + RegSetValueExW(LinkKey, NULL, 0, REG_LINK, (PCHAR)&ControlSetKey, sizeof(PVOID)); } /* EOF */ diff --git a/reactos/tools/mkhive/registry.h b/reactos/tools/mkhive/registry.h index 4aed67278ab..a957cccd943 100644 --- a/reactos/tools/mkhive/registry.h +++ b/reactos/tools/mkhive/registry.h @@ -1,61 +1,12 @@ -/* - * ReactOS kernel - * Copyright (C) 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS hive maker * FILE: tools/mkhive/registry.h * PURPOSE: Registry code - * PROGRAMMER: Eric Kohl */ #ifndef __REGISTRY_H__ #define __REGISTRY_H__ - -#define INVALID_HANDLE_VALUE NULL - -typedef struct _LIST_ENTRY -{ - struct _LIST_ENTRY *Flink; - struct _LIST_ENTRY *Blink; -} LIST_ENTRY, *PLIST_ENTRY; - - -typedef struct _REG_KEY -{ - LIST_ENTRY KeyList; - LIST_ENTRY SubKeyList; - LIST_ENTRY ValueList; - - USHORT SubKeyCount; - ULONG ValueCount; - - USHORT NameSize; - PCHAR Name; - - /* default data */ - ULONG DataType; - ULONG DataSize; - PCHAR Data; -} KEY, *HKEY, **PHKEY; - - typedef struct _REG_VALUE { LIST_ENTRY ValueList; @@ -70,9 +21,43 @@ typedef struct _REG_VALUE PCHAR Data; } VALUE, *PVALUE; +typedef struct _REG_KEY +{ + LIST_ENTRY KeyList; + LIST_ENTRY SubKeyList; + LIST_ENTRY ValueList; + + ULONG SubKeyCount; + ULONG ValueCount; + + ULONG NameSize; + PWCHAR Name; + + /* default data */ + ULONG DataType; + ULONG DataSize; + PCHAR Data; + + /* Information on hard disk structure */ + HCELL_INDEX KeyCellOffset; + PCM_KEY_NODE KeyCell; + PEREGISTRY_HIVE RegistryHive; + + /* Used when linking to another key */ + struct _REG_KEY* LinkedKey; +} KEY, *FRLDRHKEY, **PFRLDRHKEY, *MEMKEY, **PMEMKEY; + +#define HKEY_TO_MEMKEY(hKey) ((MEMKEY)(hKey)) +#define MEMKEY_TO_HKEY(memKey) ((HKEY)(memKey)) + +extern EREGISTRY_HIVE DefaultHive; /* \Registry\User\.DEFAULT */ +extern EREGISTRY_HIVE SamHive; /* \Registry\Machine\SAM */ +extern EREGISTRY_HIVE SecurityHive; /* \Registry\Machine\SECURITY */ +extern EREGISTRY_HIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */ +extern EREGISTRY_HIVE SystemHive; /* \Registry\Machine\SYSTEM */ #define ERROR_SUCCESS 0L -#define ERROR_PATH_NOT_FOUND 2L +#define ERROR_UNSUCCESSFUL 1L #define ERROR_OUTOFMEMORY 14L #define ERROR_INVALID_PARAMETER 87L #define ERROR_MORE_DATA 234L @@ -155,22 +140,6 @@ typedef struct _REG_VALUE assert((ListEntry)->Flink->Blink == (ListEntry)); \ } -/* - * BOOLEAN - * IsListEmpty ( - * PLIST_ENTRY ListHead - * ); - * - * FUNCTION: - * Checks if a double linked list is empty - * - * ARGUMENTS: - * ListHead = Head of the list -*/ -#define IsListEmpty(ListHead) \ - ((ListHead)->Flink == (ListHead)) - - /* *VOID *RemoveEntryList ( @@ -200,11 +169,6 @@ typedef struct _REG_VALUE (ListEntry)->Blink = NULL; \ } -/* - * PURPOSE: Returns the byte offset of a field within a structure - */ -#define FIELD_OFFSET(Type,Field) (LONG)(&(((Type *)(0))->Field)) - /* * PURPOSE: Returns the base address structure if the caller knows the * address of a field within the structure @@ -230,58 +194,42 @@ typedef struct _REG_VALUE #define REG_FULL_RESOURCE_DESCRIPTOR 9 #define REG_RESOURCE_REQUIREMENTS_LIST 10 +LONG WINAPI +RegCreateKeyA( + IN HKEY hKey, + IN LPCSTR lpSubKey, + OUT PHKEY phkResult); +LONG WINAPI +RegOpenKeyA( + IN HKEY hKey, + IN LPCSTR lpSubKey, + OUT PHKEY phkResult); -VOID -RegInitializeRegistry(VOID); - -LONG -RegCreateKey(HKEY ParentKey, - PCHAR KeyName, - PHKEY Key); - -LONG -RegDeleteKey(HKEY Key, - PCHAR Name); - -LONG -RegEnumKey(HKEY Key, - ULONG Index, - PCHAR Name, - PULONG NameSize); - -LONG -RegOpenKey(HKEY ParentKey, - PCHAR KeyName, - PHKEY Key); - - -LONG -RegSetValue(HKEY Key, - PCHAR ValueName, - ULONG Type, - PCHAR Data, - ULONG DataSize); - -LONG -RegQueryValue(HKEY Key, - PCHAR ValueName, +LONG WINAPI +RegQueryValueExA(HKEY Key, + LPCSTR ValueName, + PULONG Reserved, PULONG Type, - PCHAR Data, - PULONG DataSize); + PUCHAR Data, + PSIZE_T DataSize); -LONG -RegDeleteValue(HKEY Key, - PCHAR ValueName); +LONG WINAPI +RegSetValueExA( + IN HKEY hKey, + IN LPCSTR lpValueName OPTIONAL, + ULONG Reserved, + IN ULONG dwType, + IN const PUCHAR lpData, + IN ULONG cbData); -LONG -RegEnumValue(HKEY Key, - ULONG Index, - PCHAR ValueName, - PULONG NameSize, - PULONG Type, - PCHAR Data, - PULONG DataSize); +LONG WINAPI +RegDeleteValueA(HKEY Key, + LPCSTR ValueName); + +LONG WINAPI +RegDeleteKeyA(HKEY Key, + LPCSTR Name); USHORT RegGetSubKeyCount (HKEY Key); @@ -289,16 +237,8 @@ RegGetSubKeyCount (HKEY Key); ULONG RegGetValueCount (HKEY Key); - -#if 0 -BOOL -RegImportTextHive(PCHAR ChunkBase, - U32 ChunkSize); - -BOOL -RegImportBinaryHive(PCHAR ChunkBase, - U32 ChunkSize); -#endif +VOID +RegInitializeRegistry(VOID); #endif /* __REGISTRY_H__ */ diff --git a/reactos/tools/mkhive/rtl.c b/reactos/tools/mkhive/rtl.c new file mode 100644 index 00000000000..4ff2be3dd50 --- /dev/null +++ b/reactos/tools/mkhive/rtl.c @@ -0,0 +1,143 @@ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/rtl.c + * PURPOSE: Runtime Library + */ + +#define RTL_H + +#define NTOS_MODE_USER +#define WIN32_NO_STATUS +#include +#include + +/* + * @implemented + * + * NOTES + * If source is NULL the length of source is assumed to be 0. + */ +VOID NTAPI +RtlInitAnsiString( + IN OUT PANSI_STRING DestinationString, + IN PCSTR SourceString) +{ + SIZE_T DestSize; + + if(SourceString) + { + DestSize = strlen(SourceString); + DestinationString->Length = (USHORT)DestSize; + DestinationString->MaximumLength = (USHORT)DestSize + sizeof(CHAR); + } + else + { + DestinationString->Length = 0; + DestinationString->MaximumLength = 0; + } + + DestinationString->Buffer = (PCHAR)SourceString; +} + +/* + * @implemented + * + * NOTES + * If source is NULL the length of source is assumed to be 0. + */ +VOID NTAPI +RtlInitUnicodeString( + IN OUT PUNICODE_STRING DestinationString, + IN PCWSTR SourceString) +{ + SIZE_T DestSize; + + if(SourceString) + { + DestSize = wcslen(SourceString) * sizeof(WCHAR); + DestinationString->Length = (USHORT)DestSize; + DestinationString->MaximumLength = (USHORT)DestSize + sizeof(WCHAR); + } + else + { + DestinationString->Length = 0; + DestinationString->MaximumLength = 0; + } + + DestinationString->Buffer = (PWCHAR)SourceString; +} + +NTSTATUS NTAPI +RtlAnsiStringToUnicodeString( + IN OUT PUNICODE_STRING UniDest, + IN PANSI_STRING AnsiSource, + IN BOOLEAN AllocateDestinationString) +{ + ULONG Length; + PUCHAR WideString; + USHORT i; + + Length = AnsiSource->Length * sizeof(WCHAR); + if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2; + UniDest->Length = (USHORT)Length; + + if (AllocateDestinationString) + { + UniDest->MaximumLength = (USHORT)Length + sizeof(WCHAR); + UniDest->Buffer = malloc(UniDest->MaximumLength); + if (!UniDest->Buffer) + return STATUS_NO_MEMORY; + } + else if (UniDest->Length >= UniDest->MaximumLength) + { + return STATUS_BUFFER_OVERFLOW; + } + + WideString = (PUCHAR)UniDest->Buffer; + for (i = 0; i <= AnsiSource->Length; i++) + { + WideString[2 * i + 0] = AnsiSource->Buffer[i]; + WideString[2 * i + 1] = 0; + } + return STATUS_SUCCESS; +} + +WCHAR NTAPI +RtlUpcaseUnicodeChar( + IN WCHAR Source) +{ + USHORT Offset; + + if (Source < 'a') + return Source; + + if (Source <= 'z') + return (Source - ('a' - 'A')); + + Offset = 0; + + return Source + (SHORT)Offset; +} + +VOID NTAPI +KeQuerySystemTime( + OUT PLARGE_INTEGER CurrentTime) +{ + DPRINT1("KeQuerySystemTime() unimplemented\n"); +} + +PVOID NTAPI +ExAllocatePool( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes) +{ + return malloc(NumberOfBytes); +} + +VOID NTAPI +ExFreePool( + IN PVOID p) +{ + free(p); +} + From bd33d7902588844e686ce3f64604cddb1a916003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 10 Sep 2006 15:58:29 +0000 Subject: [PATCH 113/488] Initialize MainResource and PagingIoResource fields in FSRTL_COMMON_FCB_HEADER structure svn path=/trunk/; revision=24027 --- reactos/drivers/filesystems/cdfs/cdfs.h | 1 + reactos/drivers/filesystems/cdfs/cdfs.rbuild | 2 +- reactos/drivers/filesystems/cdfs/fcb.c | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/reactos/drivers/filesystems/cdfs/cdfs.h b/reactos/drivers/filesystems/cdfs/cdfs.h index eca0a4b27f1..cef813cc52b 100644 --- a/reactos/drivers/filesystems/cdfs/cdfs.h +++ b/reactos/drivers/filesystems/cdfs/cdfs.h @@ -180,6 +180,7 @@ typedef struct _FCB { FSRTL_COMMON_FCB_HEADER RFCB; SECTION_OBJECT_POINTERS SectionObjectPointers; + ERESOURCE PagingIoResource; PFILE_OBJECT FileObject; PDEVICE_EXTENSION DevExt; diff --git a/reactos/drivers/filesystems/cdfs/cdfs.rbuild b/reactos/drivers/filesystems/cdfs/cdfs.rbuild index 05b6e0bc5c9..24382282c22 100644 --- a/reactos/drivers/filesystems/cdfs/cdfs.rbuild +++ b/reactos/drivers/filesystems/cdfs/cdfs.rbuild @@ -1,7 +1,7 @@ . - + ntoskrnl hal cdfs.c diff --git a/reactos/drivers/filesystems/cdfs/fcb.c b/reactos/drivers/filesystems/cdfs/fcb.c index 7e6b2e0aa14..c56e52382fe 100644 --- a/reactos/drivers/filesystems/cdfs/fcb.c +++ b/reactos/drivers/filesystems/cdfs/fcb.c @@ -88,7 +88,11 @@ CdfsCreateFCB(PCWSTR FileName) } } + ExInitializeResourceLite(&Fcb->PagingIoResource); ExInitializeResourceLite(&Fcb->MainResource); + Fcb->RFCB.PagingIoResource = &Fcb->PagingIoResource; + Fcb->RFCB.Resource = &Fcb->MainResource; + Fcb->RFCB.IsFastIoPossible = FastIoIsNotPossible; return(Fcb); } @@ -97,6 +101,7 @@ CdfsCreateFCB(PCWSTR FileName) VOID CdfsDestroyFCB(PFCB Fcb) { + ExDeleteResourceLite(&Fcb->PagingIoResource); ExDeleteResourceLite(&Fcb->MainResource); ExFreePool(Fcb); From e61739c38c98f0ce19ffb63efe51b1d9da3834b5 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 16:09:58 +0000 Subject: [PATCH 114/488] - Fix definition of SYNCH_LEVEL. - Implement KeAcquireInStackQueuedSpinLockRaiseToSynch for UP systems. - Implement KiAcquireApcLock, KiAcquireApcLockAtDpcLevel, KiReleaseApcLock, KiReleaseApcLockFromDpcLevel. - KeResumeThread, KeSuspendThread, KeAlertThread, KeForceResumeThread, KeTestAlertThread, KeAlertResumeThread are now the first to use the new APC In-Stack Queued Spinlock for sychronization. svn path=/trunk/; revision=24028 --- reactos/hal/hal/hal.c | 9 + reactos/hal/hal/hal.def | 1 + reactos/hal/halx86/generic/spinlock.c | 12 + reactos/hal/halx86/mp/spinlock.c | 13 + reactos/include/ndk/i386/ketypes.h | 2 +- reactos/include/ndk/kefuncs.h | 2 +- reactos/include/ndk/ketypes.h | 2 +- reactos/ntoskrnl/include/internal/ke_x.h | 34 +++ reactos/ntoskrnl/ke/thrdobj.c | 360 +++++++++++++---------- 9 files changed, 276 insertions(+), 159 deletions(-) diff --git a/reactos/hal/hal/hal.c b/reactos/hal/hal/hal.c index 995a1df1d89..05400bf04bf 100644 --- a/reactos/hal/hal/hal.c +++ b/reactos/hal/hal/hal.c @@ -784,6 +784,15 @@ KeAcquireInStackQueuedSpinLock( UNIMPLEMENTED; } +VOID +FASTCALL +KeAcquireInStackQueuedSpinLockRaiseToSynch( + IN PKSPIN_LOCK SpinLock, + IN PKLOCK_QUEUE_HANDLE LockHandle + ) +{ + UNIMPLEMENTED; +} VOID FASTCALL diff --git a/reactos/hal/hal/hal.def b/reactos/hal/hal/hal.def index 58ba18bfa93..0e4c035630e 100644 --- a/reactos/hal/hal/hal.def +++ b/reactos/hal/hal/hal.def @@ -71,6 +71,7 @@ KdPortDisableInterrupts@0 KdPortEnableInterrupts@0 KeAcquireSpinLock@8 @KeAcquireInStackQueuedSpinLock@8 +@KeAcquireInStackQueuedSpinLockRaiseToSynch@8 @KeAcquireSpinLockRaiseToSynch@4 @KeAcquireQueuedSpinLock@4 KeGetCurrentIrql@0 diff --git a/reactos/hal/halx86/generic/spinlock.c b/reactos/hal/halx86/generic/spinlock.c index 30d66bb230b..b88e269dcc4 100644 --- a/reactos/hal/halx86/generic/spinlock.c +++ b/reactos/hal/halx86/generic/spinlock.c @@ -134,6 +134,18 @@ KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock, LockHandle->OldIrql = KfRaiseIrql(DISPATCH_LEVEL); } +/* + * @implemented + */ +VOID +FASTCALL +KeAcquireInStackQueuedSpinLockRaiseToSynch(IN PKSPIN_LOCK SpinLock, + IN PKLOCK_QUEUE_HANDLE LockHandle) +{ + /* Simply raise to synch */ + LockHandle->OldIrql = KfRaiseIrql(SYNCH_LEVEL); +} + /* * @implemented */ diff --git a/reactos/hal/halx86/mp/spinlock.c b/reactos/hal/halx86/mp/spinlock.c index e7b18f72a44..4bca3da8159 100644 --- a/reactos/hal/halx86/mp/spinlock.c +++ b/reactos/hal/halx86/mp/spinlock.c @@ -117,6 +117,19 @@ KeAcquireInStackQueuedSpinLock( UNIMPLEMENTED; } +/* + * @unimplemented + */ +VOID +FASTCALL +KeAcquireInStackQueuedSpinLockRaiseToSynch( + IN PKSPIN_LOCK SpinLock, + IN PKLOCK_QUEUE_HANDLE LockHandle + ) +{ + UNIMPLEMENTED; +} + /* * @unimplemented diff --git a/reactos/include/ndk/i386/ketypes.h b/reactos/include/ndk/i386/ketypes.h index 484cb767e81..0a5752d0cc8 100644 --- a/reactos/include/ndk/i386/ketypes.h +++ b/reactos/include/ndk/i386/ketypes.h @@ -109,7 +109,7 @@ Author: // // Synchronization-level IRQL // -#if defined(NT_UP) +#ifndef CONFIG_SMP #define SYNCH_LEVEL DISPATCH_LEVEL #else #define SYNCH_LEVEL (IPI_LEVEL - 1) diff --git a/reactos/include/ndk/kefuncs.h b/reactos/include/ndk/kefuncs.h index 9606535fada..c55c87ed572 100644 --- a/reactos/include/ndk/kefuncs.h +++ b/reactos/include/ndk/kefuncs.h @@ -117,7 +117,7 @@ KeAcquireQueuedSpinLockRaiseToSynch( IN KSPIN_LOCK_QUEUE_NUMBER LockNumber ); -KIRQL +VOID FASTCALL KeAcquireInStackQueuedSpinLockRaiseToSynch( IN PKSPIN_LOCK SpinLock, diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index d480a6382ee..f6893df052a 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -896,7 +896,7 @@ typedef struct _KTHREAD #include #define ASSERT_THREAD(object) \ - ASSERT((((object)->Header.Type & KOBJECT_TYPE_MASK) == ThreadObject)) + ASSERT((((object)->DispatcherHeader.Type & KOBJECT_TYPE_MASK) == ThreadObject)) // // Kernel Process (KPROCESS) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 214fb70d568..cd85c1b1f0d 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -553,6 +553,40 @@ KiCheckDeferredReadyList(IN PKPRCB Prcb) #endif +FORCEINLINE +VOID +KiAcquireApcLock(IN PKTHREAD Thread, + IN PKLOCK_QUEUE_HANDLE Handle) +{ + /* Acquire the lock and raise to synchronization level */ + KeAcquireInStackQueuedSpinLockRaiseToSynch(&Thread->ApcQueueLock, Handle); +} + +FORCEINLINE +VOID +KiAcquireApcLockAtDpcLevel(IN PKTHREAD Thread, + IN PKLOCK_QUEUE_HANDLE Handle) +{ + /* Acquire the lock */ + KeAcquireInStackQueuedSpinLockAtDpcLevel(&Thread->ApcQueueLock, Handle); +} + +FORCEINLINE +VOID +KiReleaseApcLock(IN PKLOCK_QUEUE_HANDLE Handle) +{ + /* Release the lock */ + KeReleaseInStackQueuedSpinLock(Handle); +} + +FORCEINLINE +VOID +KiReleaseApcLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle) +{ + /* Release the lock */ + KeReleaseInStackQueuedSpinLockFromDpcLevel(Handle); +} + // // This routine queues a thread that is ready on the PRCB's ready lists. // If this thread cannot currently run on this CPU, then the thread is diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index e67e584ea80..5487e1e968c 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -46,33 +46,6 @@ KeFindNextRightSetAffinity(IN UCHAR Number, return (UCHAR)Result; } -VOID -STDCALL -KiSuspendThreadKernelRoutine(PKAPC Apc, - PKNORMAL_ROUTINE* NormalRoutine, - PVOID* NormalContext, - PVOID* SystemArgument1, - PVOID* SystemArguemnt2) -{ -} - -VOID -STDCALL -KiSuspendThreadNormalRoutine(PVOID NormalContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PKTHREAD CurrentThread = KeGetCurrentThread(); - - /* Non-alertable kernel-mode suspended wait */ - DPRINT("Waiting...\n"); - KeWaitForSingleObject(&CurrentThread->SuspendSemaphore, - Suspended, - KernelMode, - FALSE, - NULL); - DPRINT("Done Waiting\n"); -} #ifdef KeGetCurrentThread #undef KeGetCurrentThread @@ -202,41 +175,6 @@ KeRundownThread(VOID) KeReleaseDispatcherDatabaseLock(OldIrql); } -ULONG -NTAPI -KeResumeThread(IN PKTHREAD Thread) -{ - ULONG PreviousCount; - KIRQL OldIrql; - - DPRINT("KeResumeThread (Thread %p called). %x, %x\n", Thread, - Thread->SuspendCount, Thread->FreezeCount); - - /* Lock the Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save the Old Count */ - PreviousCount = Thread->SuspendCount; - - /* Check if it existed */ - if (PreviousCount) { - - Thread->SuspendCount--; - - /* Decrease the current Suspend Count and Check Freeze Count */ - if ((!Thread->SuspendCount) && (!Thread->FreezeCount)) { - - /* Signal the Suspend Semaphore */ - Thread->SuspendSemaphore.Header.SignalState++; - KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); - } - } - - /* Release Lock and return the Old State */ - KeReleaseDispatcherDatabaseLock(OldIrql); - return PreviousCount; -} - /* * Used by the debugging code to freeze all the process's threads * while the debugger is examining their state. @@ -296,17 +234,99 @@ KeFreezeAllThreads(PKPROCESS Process) KeReleaseDispatcherDatabaseLock(OldIrql); } +ULONG +NTAPI +KeResumeThread(IN PKTHREAD Thread) +{ + KLOCK_QUEUE_HANDLE ApcLock; + ULONG PreviousCount; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + DPRINT1("Resuming Thread: %p\n", Thread); + + /* Lock the APC Queue */ + KiAcquireApcLock(Thread, &ApcLock); + + /* Save the Old Count */ + PreviousCount = Thread->SuspendCount; + + /* Check if it existed */ + if (PreviousCount) + { + /* Decrease the suspend count */ + Thread->SuspendCount--; + + /* Check if the thrad is still suspended or not */ + if ((!Thread->SuspendCount) && (!Thread->FreezeCount)) + { + /* Acquire the dispatcher lock */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Signal the Suspend Semaphore */ + Thread->SuspendSemaphore.Header.SignalState++; + KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); + + /* Release the dispatcher lock */ + KiReleaseDispatcherLockFromDpcLevel(); + } + } + + /* Release APC Queue lock and return the Old State */ + KiReleaseApcLockFromDpcLevel(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); + return PreviousCount; +} + +VOID +NTAPI +KiSuspendRundown(IN PKAPC Apc) +{ + /* Does nothing */ + UNREFERENCED_PARAMETER(Apc); +} + +VOID +NTAPI +KiSuspendNop(IN PKAPC Apc, + IN PKNORMAL_ROUTINE *NormalRoutine, + IN PVOID *NormalContext, + IN PVOID *SystemArgument1, + IN PVOID *SystemArgument2) +{ + /* Does nothing */ + UNREFERENCED_PARAMETER(Apc); + UNREFERENCED_PARAMETER(NormalRoutine); + UNREFERENCED_PARAMETER(NormalContext); + UNREFERENCED_PARAMETER(SystemArgument1); + UNREFERENCED_PARAMETER(SystemArgument2); +} + +VOID +NTAPI +KiSuspendThread(IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +{ + /* Non-alertable kernel-mode suspended wait */ + KeWaitForSingleObject(&KeGetCurrentThread()->SuspendSemaphore, + Suspended, + KernelMode, + FALSE, + NULL); +} + NTSTATUS -STDCALL +NTAPI KeSuspendThread(PKTHREAD Thread) { + KLOCK_QUEUE_HANDLE ApcLock; ULONG PreviousCount; - KIRQL OldIrql; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + DPRINT1("Suspending Thread: %p\n", Thread); - DPRINT("KeSuspendThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount); - - /* Lock the Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + /* Lock the APC Queue */ + KiAcquireApcLock(Thread, &ApcLock); /* Save the Old Count */ PreviousCount = Thread->SuspendCount; @@ -315,7 +335,7 @@ KeSuspendThread(PKTHREAD Thread) if (PreviousCount == MAXIMUM_SUSPEND_COUNT) { /* Raise an exception */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseApcLock(&ApcLock); RtlRaiseStatus(STATUS_SUSPEND_COUNT_EXCEEDED); } @@ -326,7 +346,7 @@ KeSuspendThread(PKTHREAD Thread) Thread->SuspendCount++; /* Check if we should suspend it */ - if (!PreviousCount && !Thread->FreezeCount) + if (!(PreviousCount) && !(Thread->FreezeCount)) { /* Is the APC already inserted? */ if (!Thread->SuspendApc.Inserted) @@ -337,44 +357,61 @@ KeSuspendThread(PKTHREAD Thread) } else { - /* Unsignal the Semaphore, the APC already got inserted */ + /* Lock the dispatcher */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Unsignal the semaphore, the APC was already inserted */ Thread->SuspendSemaphore.Header.SignalState--; + + /* Release the dispatcher */ + KiReleaseDispatcherLockFromDpcLevel(); } } } /* Release Lock and return the Old State */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseApcLockFromDpcLevel(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); return PreviousCount; } ULONG -STDCALL +NTAPI KeForceResumeThread(IN PKTHREAD Thread) { - KIRQL OldIrql; + KLOCK_QUEUE_HANDLE ApcLock; ULONG PreviousCount; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + DPRINT1("Force-Resuming Thread: %p\n", Thread); - /* Lock the Dispatcher Database and the APC Queue */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + /* Lock the APC Queue */ + KiAcquireApcLock(Thread, &ApcLock); /* Save the old Suspend Count */ PreviousCount = Thread->SuspendCount + Thread->FreezeCount; /* If the thread is suspended, wake it up!!! */ - if (PreviousCount) { - + if (PreviousCount) + { /* Unwait it completely */ Thread->SuspendCount = 0; Thread->FreezeCount = 0; + /* Lock the dispatcher */ + KiAcquireDispatcherLockAtDpcLevel(); + /* Signal and satisfy */ Thread->SuspendSemaphore.Header.SignalState++; KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); + + /* Release the dispatcher */ + KiReleaseDispatcherLockFromDpcLevel(); } /* Release Lock and return the Old State */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseApcLockFromDpcLevel(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); return PreviousCount; } @@ -383,25 +420,26 @@ NTAPI KeAlertResumeThread(IN PKTHREAD Thread) { ULONG PreviousCount; - KIRQL OldIrql; - + KLOCK_QUEUE_HANDLE ApcLock; + ASSERT_THREAD(Thread); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + DPRINT1("Alert-Resuming Thread: %p\n", Thread); /* Lock the Dispatcher Database and the APC Queue */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - KiAcquireSpinLock(&Thread->ApcQueueLock); + KiAcquireApcLock(Thread, &ApcLock); + KiAcquireDispatcherLockAtDpcLevel(); /* Return if Thread is already alerted. */ - if (Thread->Alerted[KernelMode] == FALSE) { - + if (!Thread->Alerted[KernelMode]) + { /* If it's Blocked, unblock if it we should */ - if (Thread->State == Waiting && Thread->Alertable) { - - DPRINT("Aborting Wait\n"); + if ((Thread->State == Waiting) && (Thread->Alertable)) + { + /* Abort the wait */ KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); - - } else { - + } + else + { /* If not, simply Alert it */ Thread->Alerted[KernelMode] = TRUE; } @@ -411,11 +449,11 @@ KeAlertResumeThread(IN PKTHREAD Thread) PreviousCount = Thread->SuspendCount; /* If the thread is suspended, decrease one of the suspend counts */ - if (PreviousCount) { - + if (PreviousCount) + { /* Decrease count. If we are now zero, unwait it completely */ - if (--Thread->SuspendCount) { - + if (--Thread->SuspendCount) + { /* Signal and satisfy */ Thread->SuspendSemaphore.Header.SignalState++; KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); @@ -423,8 +461,9 @@ KeAlertResumeThread(IN PKTHREAD Thread) } /* Release Locks and return the Old State */ - KiReleaseSpinLock(&Thread->ApcQueueLock); - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLockFromDpcLevel(); + KiReleaseApcLockFromDpcLevel(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); return PreviousCount; } @@ -433,40 +472,88 @@ NTAPI KeAlertThread(IN PKTHREAD Thread, IN KPROCESSOR_MODE AlertMode) { - KIRQL OldIrql; BOOLEAN PreviousState; + KLOCK_QUEUE_HANDLE ApcLock; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + DPRINT1("Alerting Thread: %p\n", Thread); - /* Acquire the Dispatcher Database Lock */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + /* Lock the Dispatcher Database and the APC Queue */ + KiAcquireApcLock(Thread, &ApcLock); + KiAcquireDispatcherLockAtDpcLevel(); /* Save the Previous State */ PreviousState = Thread->Alerted[AlertMode]; - /* Return if Thread is already alerted. */ - if (PreviousState == FALSE) { - - /* If it's Blocked, unblock if it we should */ - if (Thread->State == Waiting && - (AlertMode == KernelMode || Thread->WaitMode == AlertMode) && - Thread->Alertable) { - - DPRINT("Aborting Wait\n"); + /* Check if it's already alerted */ + if (!PreviousState) + { + /* Check if the thread is alertable, and blocked in the given mode */ + if ((Thread->State == Waiting) && + ((AlertMode == KernelMode) || (Thread->WaitMode == AlertMode)) && + (Thread->Alertable)) + { + /* Abort the wait to alert the thread */ KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); - - } else { - - /* If not, simply Alert it */ + } + else + { + /* Otherwise, merely set the alerted state */ Thread->Alerted[AlertMode] = TRUE; } } /* Release the Dispatcher Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLockFromDpcLevel(); + KiReleaseApcLockFromDpcLevel(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); /* Return the old state */ return PreviousState; } +/* + * FUNCTION: Tests whether there are any pending APCs for the current thread + * and if so the APCs will be delivered on exit from kernel mode + */ +BOOLEAN +STDCALL +KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) +{ + PKTHREAD Thread = KeGetCurrentThread(); + BOOLEAN OldState; + KLOCK_QUEUE_HANDLE ApcLock; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + DPRINT1("Test-Alerting Thread: %p\n", Thread); + + /* Lock the Dispatcher Database and the APC Queue */ + KiAcquireApcLock(Thread, &ApcLock); + KiAcquireDispatcherLockAtDpcLevel(); + + /* Save the old State */ + OldState = Thread->Alerted[AlertMode]; + + /* Check the Thread is alerted */ + if (OldState) + { + /* Disable alert for this mode */ + Thread->Alerted[AlertMode] = FALSE; + } + else if ((AlertMode != KernelMode) && + (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) + { + /* If the mode is User and the Queue isn't empty, set Pending */ + Thread->ApcState.UserApcPending = TRUE; + } + + /* Release Locks and return the Old State */ + KiReleaseDispatcherLockFromDpcLevel(); + KiReleaseApcLockFromDpcLevel(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); + return OldState; +} + /* * @unimplemented */ @@ -551,9 +638,9 @@ KeInitThread(IN OUT PKTHREAD Thread, KeInitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, - KiSuspendThreadKernelRoutine, - NULL, - KiSuspendThreadNormalRoutine, + KiSuspendNop, + KiSuspendRundown, + KiSuspendThread, KernelMode, NULL); @@ -1157,42 +1244,3 @@ KeTerminateThread(IN KPRIORITY Increment) /* Find a new Thread */ KiDispatchThreadNoLock(Terminated); } - -/* - * FUNCTION: Tests whether there are any pending APCs for the current thread - * and if so the APCs will be delivered on exit from kernel mode - */ -BOOLEAN -STDCALL -KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) -{ - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - BOOLEAN OldState; - - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - /* Lock the Dispatcher Database and the APC Queue */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - KiAcquireSpinLock(&Thread->ApcQueueLock); - - /* Save the old State */ - OldState = Thread->Alerted[AlertMode]; - - /* If the Thread is Alerted, Clear it */ - if (OldState) { - - Thread->Alerted[AlertMode] = FALSE; - - } else if ((AlertMode != KernelMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) { - - /* If the mode is User and the Queue isn't empty, set Pending */ - Thread->ApcState.UserApcPending = TRUE; - } - - /* Release Locks and return the Old State */ - KiReleaseSpinLock(&Thread->ApcQueueLock); - KeReleaseDispatcherDatabaseLock(OldIrql); - return OldState; -} - From 1b223aebfbdc0273e4b91da4ab9261723825b414 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 16:25:57 +0000 Subject: [PATCH 115/488] - Implement KiAcquireProcessLock, KiReleaseProcessLock. - Update KeFreezeAllThreads to use the Process and APC In-Stack Queued Spinlock. - Update KeTerminateThread to use the Process Lock. Call KiRundownThread to cleanup the NPX thread. Add some assertions for Stack in/out-paging. Use KiSetThreadSwapBusy for proper SMP vs UP building. - NUMA Node semantics in KeStartThread only need to be done for CONFIG_SMP builds, so #ifed them appropriately. Also made it use the Process In-Stack QSL. svn path=/trunk/; revision=24029 --- reactos/ntoskrnl/include/internal/ke_x.h | 17 ++ reactos/ntoskrnl/ke/thrdobj.c | 272 +++++++++++++---------- 2 files changed, 169 insertions(+), 120 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index cd85c1b1f0d..e92971e51c6 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -587,6 +587,23 @@ KiReleaseApcLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle) KeReleaseInStackQueuedSpinLockFromDpcLevel(Handle); } +FORCEINLINE +VOID +KiAcquireProcessLock(IN PKPROCESS Process, + IN PKLOCK_QUEUE_HANDLE Handle) +{ + /* Acquire the lock and raise to synchronization level */ + KeAcquireInStackQueuedSpinLockRaiseToSynch(&Process->ProcessLock, Handle); +} + +FORCEINLINE +VOID +KiReleaseProcessLock(IN PKLOCK_QUEUE_HANDLE Handle) +{ + /* Release the lock */ + KeReleaseInStackQueuedSpinLock(Handle); +} + // // This routine queues a thread that is ready on the PRCB's ready lists. // If this thread cannot currently run on this CPU, then the thread is diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 5487e1e968c..8ed01d5f95d 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -180,58 +180,81 @@ KeRundownThread(VOID) * while the debugger is examining their state. */ VOID -STDCALL -KeFreezeAllThreads(PKPROCESS Process) +NTAPI +KeFreezeAllThreads(IN PKPROCESS Process) { - KIRQL OldIrql; - PKTHREAD Current; - PKTHREAD CurrentThread = KeGetCurrentThread(); + KLOCK_QUEUE_HANDLE LockHandle, ApcLock; + PKTHREAD Current, CurrentThread = KeGetCurrentThread(); + PLIST_ENTRY ListHead, NextEntry; + LONG OldCount; + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - /* Acquire Lock */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + /* Lock the process */ + KiAcquireProcessLock(Process, &LockHandle); /* If someone is already trying to free us, try again */ while (CurrentThread->FreezeCount) { - /* Release and re-acquire the lock so the APC will go through */ - KeReleaseDispatcherDatabaseLock(OldIrql); - OldIrql = KeAcquireDispatcherDatabaseLock(); + /* Release and re-acquire the process lock so the APC will go through */ + KiReleaseProcessLock(&LockHandle); + KiAcquireProcessLock(Process, &LockHandle); } /* Enter a critical region */ KeEnterCriticalRegion(); /* Loop the Process's Threads */ - LIST_FOR_EACH(Current, &Process->ThreadListHead, KTHREAD, ThreadListEntry) + ListHead = &Process->ThreadListHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) { - /* Make sure it's not ours */ - if (Current != CurrentThread) + /* Get the current thread */ + Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry); + + /* Lock it */ + KiAcquireApcLockAtDpcLevel(Current, &ApcLock); + + /* Make sure it's not ours, and check if APCs are enabled */ + if ((Current != CurrentThread) && (Current->ApcQueueable)) { - /* Should be bother inserting the APC? */ - if (Current->ApcQueueable) + /* Sanity check */ + OldCount = Current->SuspendCount; + ASSERT(OldCount != MAXIMUM_SUSPEND_COUNT); + + /* Increase the freeze count */ + Current->FreezeCount++; + + /* Make sure it wasn't already suspended */ + if (!(OldCount) && !(Current->SuspendCount)) { - /* Make sure it wasn't already frozen, and that it's not suspended */ - if (!(++Current->FreezeCount) && !(Current->SuspendCount)) + /* Did we already insert it? */ + if (!Current->SuspendApc.Inserted) { - /* Did we already insert it? */ - if (!Current->SuspendApc.Inserted) - { - /* Insert the APC */ - Current->SuspendApc.Inserted = TRUE; - KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT); - } - else - { - /* Unsignal the Semaphore, the APC already got inserted */ - Current->SuspendSemaphore.Header.SignalState--; - } + /* Insert the APC */ + Current->SuspendApc.Inserted = TRUE; + KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT); + } + else + { + /* Lock the dispatcher */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Unsignal the semaphore, the APC was already inserted */ + Current->SuspendSemaphore.Header.SignalState--; + + /* Release the dispatcher */ + KiReleaseDispatcherLockFromDpcLevel(); } } } + + /* Release the APC lock */ + KiReleaseApcLockFromDpcLevel(&ApcLock); } - /* Release the lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Release the process lock and exit the dispatcher */ + KiReleaseProcessLock(&LockHandle); + KiExitDispatcher(LockHandle.OldIrql); } ULONG @@ -242,7 +265,6 @@ KeResumeThread(IN PKTHREAD Thread) ULONG PreviousCount; ASSERT_THREAD(Thread); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT1("Resuming Thread: %p\n", Thread); /* Lock the APC Queue */ KiAcquireApcLock(Thread, &ApcLock); @@ -323,7 +345,6 @@ KeSuspendThread(PKTHREAD Thread) ULONG PreviousCount; ASSERT_THREAD(Thread); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT1("Suspending Thread: %p\n", Thread); /* Lock the APC Queue */ KiAcquireApcLock(Thread, &ApcLock); @@ -383,7 +404,6 @@ KeForceResumeThread(IN PKTHREAD Thread) ULONG PreviousCount; ASSERT_THREAD(Thread); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT1("Force-Resuming Thread: %p\n", Thread); /* Lock the APC Queue */ KiAcquireApcLock(Thread, &ApcLock); @@ -423,7 +443,6 @@ KeAlertResumeThread(IN PKTHREAD Thread) KLOCK_QUEUE_HANDLE ApcLock; ASSERT_THREAD(Thread); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT1("Alert-Resuming Thread: %p\n", Thread); /* Lock the Dispatcher Database and the APC Queue */ KiAcquireApcLock(Thread, &ApcLock); @@ -476,7 +495,6 @@ KeAlertThread(IN PKTHREAD Thread, KLOCK_QUEUE_HANDLE ApcLock; ASSERT_THREAD(Thread); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT1("Alerting Thread: %p\n", Thread); /* Lock the Dispatcher Database and the APC Queue */ KiAcquireApcLock(Thread, &ApcLock); @@ -512,12 +530,8 @@ KeAlertThread(IN PKTHREAD Thread, return PreviousState; } -/* - * FUNCTION: Tests whether there are any pending APCs for the current thread - * and if so the APCs will be delivered on exit from kernel mode - */ BOOLEAN -STDCALL +NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) { PKTHREAD Thread = KeGetCurrentThread(); @@ -525,7 +539,6 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) KLOCK_QUEUE_HANDLE ApcLock; ASSERT_THREAD(Thread); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT1("Test-Alerting Thread: %p\n", Thread); /* Lock the Dispatcher Database and the APC Queue */ KiAcquireApcLock(Thread, &ApcLock); @@ -718,68 +731,6 @@ KeInitThread(IN OUT PKTHREAD Thread, return Status; } -VOID -NTAPI -KeStartThread(IN OUT PKTHREAD Thread) -{ - KIRQL OldIrql; - PKPROCESS Process = Thread->ApcState.Process; - PKNODE Node; - PKPRCB NodePrcb; - ULONG Set, Mask; - UCHAR IdealProcessor; - - /* Setup static fields from parent */ - Thread->Iopl = Process->Iopl; - Thread->Quantum = Process->QuantumReset; - Thread->QuantumReset = Process->QuantumReset; - Thread->SystemAffinityActive = FALSE; - - /* Lock the process */ - KeAcquireSpinLock(&Process->ProcessLock, &OldIrql); - - /* Setup volatile data */ - Thread->Priority = Process->BasePriority; - Thread->BasePriority = Process->BasePriority; - Thread->Affinity = Process->Affinity; - Thread->UserAffinity = Process->Affinity; - - /* Get the KNODE and its PRCB */ - Node = KeNodeBlock[Process->IdealNode]; - NodePrcb = (PKPRCB)(KPCR_BASE + (Process->ThreadSeed * PAGE_SIZE)); - - /* Calculate affinity mask */ - Set = ~NodePrcb->MultiThreadProcessorSet; - Mask = (ULONG)(Node->ProcessorMask & Process->Affinity); - Set &= Mask; - if (Set) Mask = Set; - - /* Get the new thread seed */ - IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask); - Process->ThreadSeed = IdealProcessor; - - /* Sanity check */ - ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor))); - - /* Set the Ideal Processor */ - Thread->IdealProcessor = IdealProcessor; - Thread->UserIdealProcessor = IdealProcessor; - - /* Lock the Dispatcher Database */ - KeAcquireDispatcherDatabaseLockAtDpcLevel(); - - /* Insert the thread into the process list */ - InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry); - - /* Increase the stack count */ - ASSERT(Process->StackCount != MAXULONG_PTR); - Process->StackCount++; - - /* Release locks and return */ - KeReleaseDispatcherDatabaseLockFromDpcLevel(); - KeReleaseSpinLock(&Process->ProcessLock, OldIrql); -} - VOID NTAPI KeInitializeThread(IN PKPROCESS Process, @@ -806,6 +757,72 @@ KeInitializeThread(IN PKPROCESS Process, } } +VOID +NTAPI +KeStartThread(IN OUT PKTHREAD Thread) +{ + KLOCK_QUEUE_HANDLE LockHandle; +#ifdef CONFIG_SMP + PKNODE Node; + PKPRCB NodePrcb; + ULONG Set, Mask; +#endif + UCHAR IdealProcessor = 0; + PKPROCESS Process = Thread->ApcState.Process; + + /* Setup static fields from parent */ + Thread->Iopl = Process->Iopl; + Thread->Quantum = Process->QuantumReset; + Thread->QuantumReset = Process->QuantumReset; + Thread->SystemAffinityActive = FALSE; + + /* Lock the process */ + KiAcquireProcessLock(Process, &LockHandle); + + /* Setup volatile data */ + Thread->Priority = Process->BasePriority; + Thread->BasePriority = Process->BasePriority; + Thread->Affinity = Process->Affinity; + Thread->UserAffinity = Process->Affinity; + +#ifdef CONFIG_SMP + /* Get the KNODE and its PRCB */ + Node = KeNodeBlock[Process->IdealNode]; + NodePrcb = (PKPRCB)(KPCR_BASE + (Process->ThreadSeed * PAGE_SIZE)); + + /* Calculate affinity mask */ + Set = ~NodePrcb->MultiThreadProcessorSet; + Mask = (ULONG)(Node->ProcessorMask & Process->Affinity); + Set &= Mask; + if (Set) Mask = Set; + + /* Get the new thread seed */ + IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask); + Process->ThreadSeed = IdealProcessor; + + /* Sanity check */ + ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor))); +#endif + + /* Set the Ideal Processor */ + Thread->IdealProcessor = IdealProcessor; + Thread->UserIdealProcessor = IdealProcessor; + + /* Lock the Dispatcher Database */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Insert the thread into the process list */ + InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry); + + /* Increase the stack count */ + ASSERT(Process->StackCount != MAXULONG_PTR); + Process->StackCount++; + + /* Release locks and return */ + KiReleaseDispatcherLockFromDpcLevel(); + KiReleaseProcessLock(&LockHandle); +} + /* * @implemented */ @@ -1164,26 +1181,23 @@ KeSetAffinityThread(PKTHREAD Thread, /* * @implemented */ - /* The Increment Argument seems to be ignored by NT and always 0 when called */ VOID -STDCALL +NTAPI KeTerminateThread(IN KPRIORITY Increment) { - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - PKPROCESS Process = Thread->ApcState.Process; PLIST_ENTRY *ListHead; PETHREAD Entry, SavedEntry; PETHREAD *ThreadAddr; - DPRINT("Terminating\n"); + KLOCK_QUEUE_HANDLE LockHandle; + PKTHREAD Thread = KeGetCurrentThread(); + PKPROCESS Process = Thread->ApcState.Process; + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - /* Lock the Dispatcher Database and the APC Queue */ - ASSERT_IRQL(DISPATCH_LEVEL); - OldIrql = KeAcquireDispatcherDatabaseLock(); - ASSERT(Thread->SwapBusy == FALSE); + /* Lock the process */ + KiAcquireProcessLock(Process, &LockHandle); /* Make sure we won't get Swapped */ - Thread->SwapBusy = TRUE; + KiSetThreadSwapBusy(Thread); /* Save the Kernel and User Times */ Process->KernelTime += Thread->KernelTime; @@ -1209,6 +1223,9 @@ KeTerminateThread(IN KPRIORITY Increment) /* Break out if the change was succesful */ } while (Entry != SavedEntry); + /* Acquire the dispatcher lock */ + KiAcquireDispatcherLockAtDpcLevel(); + /* Check if the reaper wasn't active */ if (!Entry) { @@ -1218,10 +1235,10 @@ KeTerminateThread(IN KPRIORITY Increment) FALSE); } - /* Handle Kernel Queues */ + /* Check the thread has an associated queue */ if (Thread->Queue) { - DPRINT("Waking Queue\n"); + /* Remove it from the list, and handle the queue */ RemoveEntryList(&Thread->QueueListEntry); KiWakeQueue(Thread->Queue); } @@ -1237,10 +1254,25 @@ KeTerminateThread(IN KPRIORITY Increment) /* Remove the thread from the list */ RemoveEntryList(&Thread->ThreadListEntry); + /* Release the process lock */ + KiReleaseProcessLock(&LockHandle); + /* Set us as terminated, decrease the Process's stack count */ Thread->State = Terminated; - Process->StackCount--; - /* Find a new Thread */ - KiDispatchThreadNoLock(Terminated); + /* Decrease stack count */ + ASSERT(Process->StackCount != 0); + ASSERT(Process->State == ProcessInMemory); + Process->StackCount--; + if (!Process->StackCount) + { + /* FIXME: Swap stacks */ + } + + /* Rundown arch-specific parts */ + KiRundownThread(Thread); + + /* Swap to a new thread */ + KiReleaseDispatcherLockFromDpcLevel(); + KiSwapThread(Thread, KeGetCurrentPrcb()); } From af9e8a64e74b3dfbc92e085f70e806a233163eb1 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 16:30:49 +0000 Subject: [PATCH 116/488] - Remove KeSetPreviousMode, KeDisableThreadApcQueueing. - Stargint reorganizing some public functions to the bottom of the file. - Don't hold lock during KeSetKernelStackSwapEnable. svn path=/trunk/; revision=24030 --- reactos/ntoskrnl/ke/thrdobj.c | 224 ++++++++++++++-------------------- 1 file changed, 92 insertions(+), 132 deletions(-) diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 8ed01d5f95d..b61dbb84b16 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -46,70 +46,6 @@ KeFindNextRightSetAffinity(IN UCHAR Number, return (UCHAR)Result; } - -#ifdef KeGetCurrentThread -#undef KeGetCurrentThread -#endif -/* - * @implemented - */ -PKTHREAD -STDCALL -KeGetCurrentThread(VOID) -{ -#ifdef CONFIG_SMP - ULONG Flags; - PKTHREAD Thread; - Ke386SaveFlags(Flags); - Ke386DisableInterrupts(); - Thread = KeGetCurrentPrcb()->CurrentThread; - Ke386RestoreFlags(Flags); - return Thread; -#else - return(KeGetCurrentPrcb()->CurrentThread); -#endif -} - -VOID -STDCALL -KeSetPreviousMode(ULONG Mode) -{ - PsGetCurrentThread()->Tcb.PreviousMode = (UCHAR)Mode; -} - -/* - * @implemented - */ -KPROCESSOR_MODE -STDCALL -KeGetPreviousMode(VOID) -{ - return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode; -} - -BOOLEAN -STDCALL -KeDisableThreadApcQueueing(IN PKTHREAD Thread) -{ - KIRQL OldIrql; - BOOLEAN PreviousState; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save old state */ - PreviousState = Thread->ApcQueueable; - - /* Disable it now */ - Thread->ApcQueueable = FALSE; - - /* Release the Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - /* Return old state */ - return PreviousState; -} - VOID STDCALL KeRundownThread(VOID) @@ -567,22 +503,6 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) return OldState; } -/* - * @unimplemented - */ -VOID -STDCALL -KeCapturePersistentThreadState(IN PVOID CurrentThread, - IN ULONG Setting1, - IN ULONG Setting2, - IN ULONG Setting3, - IN ULONG Setting4, - IN ULONG Setting5, - IN PVOID ThreadState) -{ - UNIMPLEMENTED; -} - VOID NTAPI KeUninitThread(IN PKTHREAD Thread) @@ -823,58 +743,6 @@ KeStartThread(IN OUT PKTHREAD Thread) KiReleaseProcessLock(&LockHandle); } -/* - * @implemented - */ -KPRIORITY -STDCALL -KeQueryPriorityThread (IN PKTHREAD Thread) -{ - return Thread->Priority; -} - -/* - * @implemented - */ -ULONG -STDCALL -KeQueryRuntimeThread(IN PKTHREAD Thread, - OUT PULONG UserTime) -{ - /* Return the User Time */ - *UserTime = Thread->UserTime; - - /* Return the Kernel Time */ - return Thread->KernelTime; -} - -/* - * @implemented - */ -BOOLEAN -STDCALL -KeSetKernelStackSwapEnable(IN BOOLEAN Enable) -{ - PKTHREAD Thread = KeGetCurrentThread(); - BOOLEAN PreviousState; - KIRQL OldIrql; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Save Old State */ - PreviousState = Thread->EnableStackSwap; - - /* Set New State */ - Thread->EnableStackSwap = Enable; - - /* No, Release Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - /* Return Old State */ - return PreviousState; -} - /* * @implemented */ @@ -1276,3 +1144,95 @@ KeTerminateThread(IN KPRIORITY Increment) KiReleaseDispatcherLockFromDpcLevel(); KiSwapThread(Thread, KeGetCurrentPrcb()); } + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @unimplemented + */ +VOID +NTAPI +KeCapturePersistentThreadState(IN PVOID CurrentThread, + IN ULONG Setting1, + IN ULONG Setting2, + IN ULONG Setting3, + IN ULONG Setting4, + IN ULONG Setting5, + IN PVOID ThreadState) +{ + UNIMPLEMENTED; +} + +/* + * @implemented + */ +#undef KeGetCurrentThread +PKTHREAD +NTAPI +KeGetCurrentThread(VOID) +{ + /* Return the current thread on this PCR */ + return ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread; +} + +/* + * @implemented + */ +KPROCESSOR_MODE +NTAPI +KeGetPreviousMode(VOID) +{ + /* Return the previous mode of this thread */ + return KeGetCurrentThread()->PreviousMode; +} + +/* + * @implemented + */ +ULONG +NTAPI +KeQueryRuntimeThread(IN PKTHREAD Thread, + OUT PULONG UserTime) +{ + ASSERT_THREAD(Thread); + + /* Return the User Time */ + *UserTime = Thread->UserTime; + + /* Return the Kernel Time */ + return Thread->KernelTime; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +KeSetKernelStackSwapEnable(IN BOOLEAN Enable) +{ + BOOLEAN PreviousState; + PKTHREAD Thread = KeGetCurrentThread(); + + /* Save Old State */ + PreviousState = Thread->EnableStackSwap; + + /* Set New State */ + Thread->EnableStackSwap = Enable; + + /* Return Old State */ + return PreviousState; +} + +/* + * @implemented + */ +KPRIORITY +NTAPI +KeQueryPriorityThread(IN PKTHREAD Thread) +{ + ASSERT_THREAD(Thread); + + /* Return the current priority */ + return Thread->Priority; +} + From a9d0596841a1a8afa72d7870e178c27a3701820c Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 10 Sep 2006 16:32:37 +0000 Subject: [PATCH 117/488] - Add msvcrt linking where needed - Change "rintf" unixism to ceil() and data conversion to integer type svn path=/trunk/; revision=24031 --- reactos/dll/cpl/access/access.rbuild | 1 + reactos/dll/cpl/main/mouse.c | 2 +- reactos/dll/cpl/mmsys/mmsys.rbuild | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/reactos/dll/cpl/access/access.rbuild b/reactos/dll/cpl/access/access.rbuild index b5145efea4c..21e401bb9f5 100644 --- a/reactos/dll/cpl/access/access.rbuild +++ b/reactos/dll/cpl/access/access.rbuild @@ -10,6 +10,7 @@ kernel32 user32 comctl32 + msvcrt access.c display.c general.c diff --git a/reactos/dll/cpl/main/mouse.c b/reactos/dll/cpl/main/mouse.c index 4e635674044..de7208b2301 100644 --- a/reactos/dll/cpl/main/mouse.c +++ b/reactos/dll/cpl/main/mouse.c @@ -235,7 +235,7 @@ ButtonProc(IN HWND hwndDlg, SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 14)); pos = ((float)g_DoubleClickSpeed / MAX_DOUBLE_CLICK_SPEED); pos /= (1.0f/11.0f); - SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(INT)rintf(pos)); + SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(INT)ceil(pos)); } diff --git a/reactos/dll/cpl/mmsys/mmsys.rbuild b/reactos/dll/cpl/mmsys/mmsys.rbuild index 69eeff2e21b..357f1b2b793 100644 --- a/reactos/dll/cpl/mmsys/mmsys.rbuild +++ b/reactos/dll/cpl/mmsys/mmsys.rbuild @@ -10,6 +10,7 @@ kernel32 user32 comctl32 + msvcrt devmgr mmsys.c mmsys.rc From d3a7b531f347a22424fc7216d0dede8379023bbe Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 16:38:02 +0000 Subject: [PATCH 118/488] - Re-organize all internal functions in 3 groups: - 1) Utility (FindRightmost/LeftMost Set, etc) - 2) State (Alert, AlertResume, ForceResume, Freeze, Resume, Rundown, Start, Suspend, TestAlert) - 3) Un/Initialization (KeInitThread, KeInitializeThread, KeUninitThread). svn path=/trunk/; revision=24032 --- reactos/ntoskrnl/ke/thrdobj.c | 691 +++++++++++++++++----------------- 1 file changed, 342 insertions(+), 349 deletions(-) diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index b61dbb84b16..5f1094f4505 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -46,69 +46,138 @@ KeFindNextRightSetAffinity(IN UCHAR Number, return (UCHAR)Result; } -VOID -STDCALL -KeRundownThread(VOID) +ULONG +NTAPI +KeAlertResumeThread(IN PKTHREAD Thread) { - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - PLIST_ENTRY NextEntry, ListHead; - PKMUTANT Mutant; - DPRINT("KeRundownThread: %x\n", Thread); + ULONG PreviousCount; + KLOCK_QUEUE_HANDLE ApcLock; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - /* Optimized path if nothing is on the list at the moment */ - if (IsListEmpty(&Thread->MutantListHead)) return; + /* Lock the Dispatcher Database and the APC Queue */ + KiAcquireApcLock(Thread, &ApcLock); + KiAcquireDispatcherLockAtDpcLevel(); - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Get the List Pointers */ - ListHead = &Thread->MutantListHead; - NextEntry = ListHead->Flink; - while (NextEntry != ListHead) + /* Return if Thread is already alerted. */ + if (!Thread->Alerted[KernelMode]) { - /* Get the Mutant */ - Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry); - DPRINT1("Mutant: %p. Type, Size %x %x\n", - Mutant, - Mutant->Header.Type, - Mutant->Header.Size); - - /* Make sure it's not terminating with APCs off */ - if (Mutant->ApcDisable) + /* If it's Blocked, unblock if it we should */ + if ((Thread->State == Waiting) && (Thread->Alertable)) { - /* Bugcheck the system */ - KEBUGCHECKEX(0,//THREAD_TERMINATE_HELD_MUTEX, - (ULONG_PTR)Thread, - (ULONG_PTR)Mutant, - 0, - 0); + /* Abort the wait */ + KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); } - - /* Now we can remove it */ - RemoveEntryList(&Mutant->MutantListEntry); - - /* Unconditionally abandon it */ - DPRINT("Abandonning the Mutant\n"); - Mutant->Header.SignalState = 1; - Mutant->Abandoned = TRUE; - Mutant->OwnerThread = NULL; - - /* Check if the Wait List isn't empty */ - DPRINT("Checking whether to wake the Mutant\n"); - if (!IsListEmpty(&Mutant->Header.WaitListHead)) + else { - /* Wake the Mutant */ - DPRINT("Waking the Mutant\n"); - KiWaitTest(&Mutant->Header, MUTANT_INCREMENT); + /* If not, simply Alert it */ + Thread->Alerted[KernelMode] = TRUE; } - - /* Move on */ - NextEntry = NextEntry->Flink; } - /* Release the Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Save the old Suspend Count */ + PreviousCount = Thread->SuspendCount; + + /* If the thread is suspended, decrease one of the suspend counts */ + if (PreviousCount) + { + /* Decrease count. If we are now zero, unwait it completely */ + if (--Thread->SuspendCount) + { + /* Signal and satisfy */ + Thread->SuspendSemaphore.Header.SignalState++; + KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); + } + } + + /* Release Locks and return the Old State */ + KiReleaseDispatcherLockFromDpcLevel(); + KiReleaseApcLockFromDpcLevel(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); + return PreviousCount; +} + +BOOLEAN +NTAPI +KeAlertThread(IN PKTHREAD Thread, + IN KPROCESSOR_MODE AlertMode) +{ + BOOLEAN PreviousState; + KLOCK_QUEUE_HANDLE ApcLock; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Lock the Dispatcher Database and the APC Queue */ + KiAcquireApcLock(Thread, &ApcLock); + KiAcquireDispatcherLockAtDpcLevel(); + + /* Save the Previous State */ + PreviousState = Thread->Alerted[AlertMode]; + + /* Check if it's already alerted */ + if (!PreviousState) + { + /* Check if the thread is alertable, and blocked in the given mode */ + if ((Thread->State == Waiting) && + ((AlertMode == KernelMode) || (Thread->WaitMode == AlertMode)) && + (Thread->Alertable)) + { + /* Abort the wait to alert the thread */ + KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); + } + else + { + /* Otherwise, merely set the alerted state */ + Thread->Alerted[AlertMode] = TRUE; + } + } + + /* Release the Dispatcher Lock */ + KiReleaseDispatcherLockFromDpcLevel(); + KiReleaseApcLockFromDpcLevel(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); + + /* Return the old state */ + return PreviousState; +} + +ULONG +NTAPI +KeForceResumeThread(IN PKTHREAD Thread) +{ + KLOCK_QUEUE_HANDLE ApcLock; + ULONG PreviousCount; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Lock the APC Queue */ + KiAcquireApcLock(Thread, &ApcLock); + + /* Save the old Suspend Count */ + PreviousCount = Thread->SuspendCount + Thread->FreezeCount; + + /* If the thread is suspended, wake it up!!! */ + if (PreviousCount) + { + /* Unwait it completely */ + Thread->SuspendCount = 0; + Thread->FreezeCount = 0; + + /* Lock the dispatcher */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Signal and satisfy */ + Thread->SuspendSemaphore.Header.SignalState++; + KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); + + /* Release the dispatcher */ + KiReleaseDispatcherLockFromDpcLevel(); + } + + /* Release Lock and return the Old State */ + KiReleaseApcLockFromDpcLevel(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); + return PreviousCount; } /* @@ -235,6 +304,129 @@ KeResumeThread(IN PKTHREAD Thread) return PreviousCount; } +VOID +NTAPI +KeRundownThread(VOID) +{ + KIRQL OldIrql; + PKTHREAD Thread = KeGetCurrentThread(); + PLIST_ENTRY NextEntry, ListHead; + PKMUTANT Mutant; + + /* Optimized path if nothing is on the list at the moment */ + if (IsListEmpty(&Thread->MutantListHead)) return; + + /* Lock the Dispatcher Database */ + OldIrql = KiAcquireDispatcherLock(); + + /* Get the List Pointers */ + ListHead = &Thread->MutantListHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the Mutant */ + Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry); + + /* Make sure it's not terminating with APCs off */ + if (Mutant->ApcDisable) + { + /* Bugcheck the system */ + KEBUGCHECKEX(0, //THREAD_TERMINATE_HELD_MUTEX, + (ULONG_PTR)Thread, + (ULONG_PTR)Mutant, + 0, + 0); + } + + /* Now we can remove it */ + RemoveEntryList(&Mutant->MutantListEntry); + + /* Unconditionally abandon it */ + Mutant->Header.SignalState = 1; + Mutant->Abandoned = TRUE; + Mutant->OwnerThread = NULL; + + /* Check if the Wait List isn't empty */ + if (!IsListEmpty(&Mutant->Header.WaitListHead)) + { + /* Wake the Mutant */ + KiWaitTest(&Mutant->Header, MUTANT_INCREMENT); + } + + /* Move on */ + NextEntry = NextEntry->Flink; + } + + /* Release the Lock */ + KiReleaseDispatcherLock(OldIrql); +} + +VOID +NTAPI +KeStartThread(IN OUT PKTHREAD Thread) +{ + KLOCK_QUEUE_HANDLE LockHandle; +#ifdef CONFIG_SMP + PKNODE Node; + PKPRCB NodePrcb; + ULONG Set, Mask; +#endif + UCHAR IdealProcessor = 0; + PKPROCESS Process = Thread->ApcState.Process; + + /* Setup static fields from parent */ + Thread->Iopl = Process->Iopl; + Thread->Quantum = Process->QuantumReset; + Thread->QuantumReset = Process->QuantumReset; + Thread->SystemAffinityActive = FALSE; + + /* Lock the process */ + KiAcquireProcessLock(Process, &LockHandle); + + /* Setup volatile data */ + Thread->Priority = Process->BasePriority; + Thread->BasePriority = Process->BasePriority; + Thread->Affinity = Process->Affinity; + Thread->UserAffinity = Process->Affinity; + +#ifdef CONFIG_SMP + /* Get the KNODE and its PRCB */ + Node = KeNodeBlock[Process->IdealNode]; + NodePrcb = (PKPRCB)(KPCR_BASE + (Process->ThreadSeed * PAGE_SIZE)); + + /* Calculate affinity mask */ + Set = ~NodePrcb->MultiThreadProcessorSet; + Mask = (ULONG)(Node->ProcessorMask & Process->Affinity); + Set &= Mask; + if (Set) Mask = Set; + + /* Get the new thread seed */ + IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask); + Process->ThreadSeed = IdealProcessor; + + /* Sanity check */ + ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor))); +#endif + + /* Set the Ideal Processor */ + Thread->IdealProcessor = IdealProcessor; + Thread->UserIdealProcessor = IdealProcessor; + + /* Lock the Dispatcher Database */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Insert the thread into the process list */ + InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry); + + /* Increase the stack count */ + ASSERT(Process->StackCount != MAXULONG_PTR); + Process->StackCount++; + + /* Release locks and return */ + KiReleaseDispatcherLockFromDpcLevel(); + KiReleaseProcessLock(&LockHandle); +} + VOID NTAPI KiSuspendRundown(IN PKAPC Apc) @@ -332,140 +524,6 @@ KeSuspendThread(PKTHREAD Thread) return PreviousCount; } -ULONG -NTAPI -KeForceResumeThread(IN PKTHREAD Thread) -{ - KLOCK_QUEUE_HANDLE ApcLock; - ULONG PreviousCount; - ASSERT_THREAD(Thread); - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - /* Lock the APC Queue */ - KiAcquireApcLock(Thread, &ApcLock); - - /* Save the old Suspend Count */ - PreviousCount = Thread->SuspendCount + Thread->FreezeCount; - - /* If the thread is suspended, wake it up!!! */ - if (PreviousCount) - { - /* Unwait it completely */ - Thread->SuspendCount = 0; - Thread->FreezeCount = 0; - - /* Lock the dispatcher */ - KiAcquireDispatcherLockAtDpcLevel(); - - /* Signal and satisfy */ - Thread->SuspendSemaphore.Header.SignalState++; - KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); - - /* Release the dispatcher */ - KiReleaseDispatcherLockFromDpcLevel(); - } - - /* Release Lock and return the Old State */ - KiReleaseApcLockFromDpcLevel(&ApcLock); - KiExitDispatcher(ApcLock.OldIrql); - return PreviousCount; -} - -ULONG -NTAPI -KeAlertResumeThread(IN PKTHREAD Thread) -{ - ULONG PreviousCount; - KLOCK_QUEUE_HANDLE ApcLock; - ASSERT_THREAD(Thread); - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - /* Lock the Dispatcher Database and the APC Queue */ - KiAcquireApcLock(Thread, &ApcLock); - KiAcquireDispatcherLockAtDpcLevel(); - - /* Return if Thread is already alerted. */ - if (!Thread->Alerted[KernelMode]) - { - /* If it's Blocked, unblock if it we should */ - if ((Thread->State == Waiting) && (Thread->Alertable)) - { - /* Abort the wait */ - KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); - } - else - { - /* If not, simply Alert it */ - Thread->Alerted[KernelMode] = TRUE; - } - } - - /* Save the old Suspend Count */ - PreviousCount = Thread->SuspendCount; - - /* If the thread is suspended, decrease one of the suspend counts */ - if (PreviousCount) - { - /* Decrease count. If we are now zero, unwait it completely */ - if (--Thread->SuspendCount) - { - /* Signal and satisfy */ - Thread->SuspendSemaphore.Header.SignalState++; - KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); - } - } - - /* Release Locks and return the Old State */ - KiReleaseDispatcherLockFromDpcLevel(); - KiReleaseApcLockFromDpcLevel(&ApcLock); - KiExitDispatcher(ApcLock.OldIrql); - return PreviousCount; -} - -BOOLEAN -NTAPI -KeAlertThread(IN PKTHREAD Thread, - IN KPROCESSOR_MODE AlertMode) -{ - BOOLEAN PreviousState; - KLOCK_QUEUE_HANDLE ApcLock; - ASSERT_THREAD(Thread); - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - /* Lock the Dispatcher Database and the APC Queue */ - KiAcquireApcLock(Thread, &ApcLock); - KiAcquireDispatcherLockAtDpcLevel(); - - /* Save the Previous State */ - PreviousState = Thread->Alerted[AlertMode]; - - /* Check if it's already alerted */ - if (!PreviousState) - { - /* Check if the thread is alertable, and blocked in the given mode */ - if ((Thread->State == Waiting) && - ((AlertMode == KernelMode) || (Thread->WaitMode == AlertMode)) && - (Thread->Alertable)) - { - /* Abort the wait to alert the thread */ - KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); - } - else - { - /* Otherwise, merely set the alerted state */ - Thread->Alerted[AlertMode] = TRUE; - } - } - - /* Release the Dispatcher Lock */ - KiReleaseDispatcherLockFromDpcLevel(); - KiReleaseApcLockFromDpcLevel(&ApcLock); - KiExitDispatcher(ApcLock.OldIrql); - - /* Return the old state */ - return PreviousState; -} - BOOLEAN NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) @@ -503,15 +561,6 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) return OldState; } -VOID -NTAPI -KeUninitThread(IN PKTHREAD Thread) -{ - /* Delete the stack */ - MmDeleteKernelStack(Thread->StackBase, FALSE); - Thread->InitialStack = NULL; -} - NTSTATUS NTAPI KeInitThread(IN OUT PKTHREAD Thread, @@ -679,70 +728,106 @@ KeInitializeThread(IN PKPROCESS Process, VOID NTAPI -KeStartThread(IN OUT PKTHREAD Thread) +KeUninitThread(IN PKTHREAD Thread) { - KLOCK_QUEUE_HANDLE LockHandle; -#ifdef CONFIG_SMP - PKNODE Node; - PKPRCB NodePrcb; - ULONG Set, Mask; -#endif - UCHAR IdealProcessor = 0; - PKPROCESS Process = Thread->ApcState.Process; - - /* Setup static fields from parent */ - Thread->Iopl = Process->Iopl; - Thread->Quantum = Process->QuantumReset; - Thread->QuantumReset = Process->QuantumReset; - Thread->SystemAffinityActive = FALSE; - - /* Lock the process */ - KiAcquireProcessLock(Process, &LockHandle); - - /* Setup volatile data */ - Thread->Priority = Process->BasePriority; - Thread->BasePriority = Process->BasePriority; - Thread->Affinity = Process->Affinity; - Thread->UserAffinity = Process->Affinity; - -#ifdef CONFIG_SMP - /* Get the KNODE and its PRCB */ - Node = KeNodeBlock[Process->IdealNode]; - NodePrcb = (PKPRCB)(KPCR_BASE + (Process->ThreadSeed * PAGE_SIZE)); - - /* Calculate affinity mask */ - Set = ~NodePrcb->MultiThreadProcessorSet; - Mask = (ULONG)(Node->ProcessorMask & Process->Affinity); - Set &= Mask; - if (Set) Mask = Set; - - /* Get the new thread seed */ - IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask); - Process->ThreadSeed = IdealProcessor; - - /* Sanity check */ - ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor))); -#endif - - /* Set the Ideal Processor */ - Thread->IdealProcessor = IdealProcessor; - Thread->UserIdealProcessor = IdealProcessor; - - /* Lock the Dispatcher Database */ - KiAcquireDispatcherLockAtDpcLevel(); - - /* Insert the thread into the process list */ - InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry); - - /* Increase the stack count */ - ASSERT(Process->StackCount != MAXULONG_PTR); - Process->StackCount++; - - /* Release locks and return */ - KiReleaseDispatcherLockFromDpcLevel(); - KiReleaseProcessLock(&LockHandle); + /* Delete the stack */ + MmDeleteKernelStack(Thread->StackBase, FALSE); + Thread->InitialStack = NULL; } +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @unimplemented + */ +VOID +NTAPI +KeCapturePersistentThreadState(IN PVOID CurrentThread, + IN ULONG Setting1, + IN ULONG Setting2, + IN ULONG Setting3, + IN ULONG Setting4, + IN ULONG Setting5, + IN PVOID ThreadState) +{ + UNIMPLEMENTED; +} + +/* + * @implemented + */ +#undef KeGetCurrentThread +PKTHREAD +NTAPI +KeGetCurrentThread(VOID) +{ + /* Return the current thread on this PCR */ + return ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread; +} + +/* + * @implemented + */ +KPROCESSOR_MODE +NTAPI +KeGetPreviousMode(VOID) +{ + /* Return the previous mode of this thread */ + return KeGetCurrentThread()->PreviousMode; +} + +/* + * @implemented + */ +ULONG +NTAPI +KeQueryRuntimeThread(IN PKTHREAD Thread, + OUT PULONG UserTime) +{ + ASSERT_THREAD(Thread); + + /* Return the User Time */ + *UserTime = Thread->UserTime; + + /* Return the Kernel Time */ + return Thread->KernelTime; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +KeSetKernelStackSwapEnable(IN BOOLEAN Enable) +{ + BOOLEAN PreviousState; + PKTHREAD Thread = KeGetCurrentThread(); + + /* Save Old State */ + PreviousState = Thread->EnableStackSwap; + + /* Set New State */ + Thread->EnableStackSwap = Enable; + + /* Return Old State */ + return PreviousState; +} + +/* + * @implemented + */ +KPRIORITY +NTAPI +KeQueryPriorityThread(IN PKTHREAD Thread) +{ + ASSERT_THREAD(Thread); + + /* Return the current priority */ + return Thread->Priority; +} + + +// re-org /* * @implemented */ @@ -1144,95 +1229,3 @@ KeTerminateThread(IN KPRIORITY Increment) KiReleaseDispatcherLockFromDpcLevel(); KiSwapThread(Thread, KeGetCurrentPrcb()); } - -/* PUBLIC FUNCTIONS **********************************************************/ - -/* - * @unimplemented - */ -VOID -NTAPI -KeCapturePersistentThreadState(IN PVOID CurrentThread, - IN ULONG Setting1, - IN ULONG Setting2, - IN ULONG Setting3, - IN ULONG Setting4, - IN ULONG Setting5, - IN PVOID ThreadState) -{ - UNIMPLEMENTED; -} - -/* - * @implemented - */ -#undef KeGetCurrentThread -PKTHREAD -NTAPI -KeGetCurrentThread(VOID) -{ - /* Return the current thread on this PCR */ - return ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread; -} - -/* - * @implemented - */ -KPROCESSOR_MODE -NTAPI -KeGetPreviousMode(VOID) -{ - /* Return the previous mode of this thread */ - return KeGetCurrentThread()->PreviousMode; -} - -/* - * @implemented - */ -ULONG -NTAPI -KeQueryRuntimeThread(IN PKTHREAD Thread, - OUT PULONG UserTime) -{ - ASSERT_THREAD(Thread); - - /* Return the User Time */ - *UserTime = Thread->UserTime; - - /* Return the Kernel Time */ - return Thread->KernelTime; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -KeSetKernelStackSwapEnable(IN BOOLEAN Enable) -{ - BOOLEAN PreviousState; - PKTHREAD Thread = KeGetCurrentThread(); - - /* Save Old State */ - PreviousState = Thread->EnableStackSwap; - - /* Set New State */ - Thread->EnableStackSwap = Enable; - - /* Return Old State */ - return PreviousState; -} - -/* - * @implemented - */ -KPRIORITY -NTAPI -KeQueryPriorityThread(IN PKTHREAD Thread) -{ - ASSERT_THREAD(Thread); - - /* Return the current priority */ - return Thread->Priority; -} - From 678df444b7d591dcdaf680731d3a227a5346260d Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 16:55:03 +0000 Subject: [PATCH 119/488] - Update KeRevertToUserAffinityThread, KeSetSystemAffinityThread to use new lock functions, and add code to support future scheduler. - Update KeSetIdealProcessorThread to properly do Ideal CPU logic instead of blindgly setting it (most importantly, respect UserIdealProcessor and SystemAffinityActive seettings). svn path=/trunk/; revision=24033 --- reactos/ntoskrnl/ke/thrdobj.c | 150 +++++++++++++++++++++++++--------- 1 file changed, 111 insertions(+), 39 deletions(-) diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 5f1094f4505..84cf7b58c90 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -826,105 +826,177 @@ KeQueryPriorityThread(IN PKTHREAD Thread) return Thread->Priority; } - -// re-org /* * @implemented */ VOID -STDCALL +NTAPI KeRevertToUserAffinityThread(VOID) { - PKTHREAD CurrentThread = KeGetCurrentThread(); KIRQL OldIrql; - + PKPRCB Prcb; + PKTHREAD NextThread, CurrentThread = KeGetCurrentThread(); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); ASSERT(CurrentThread->SystemAffinityActive != FALSE); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); - /* Return to User Affinity */ + /* Set the user affinity and processor and disable system affinity */ CurrentThread->Affinity = CurrentThread->UserAffinity; - - /* Disable System Affinity */ + CurrentThread->IdealProcessor = CurrentThread->UserIdealProcessor; CurrentThread->SystemAffinityActive = FALSE; - /* Check if we need to Dispatch a New thread */ - if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber())) { - - /* No, just release */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - } else { + /* Get the current PRCB and check if it doesn't match this affinity */ + Prcb = KeGetCurrentPrcb(); + if (!(Prcb->SetMember & CurrentThread->Affinity)) + { + /* Lock the PRCB */ + KiAcquirePrcbLock(Prcb); +#ifdef NEW_SCHEDULER + /* Check if there's no next thread scheduled */ + if (!Prcb->NextThread) + { + /* Select a new thread and set it on standby */ + NextThread = KiSelectNextThread(Prcb); + NextThread->State = Standby; + Prcb->NextThread = NextThread; + } +#else /* We need to dispatch a new thread */ + NextThread = NULL; CurrentThread->WaitIrql = OldIrql; KiDispatchThreadNoLock(Ready); KeLowerIrql(OldIrql); + return; +#endif + + /* Release the PRCB lock */ + KiReleasePrcbLock(Prcb); } + + /* Unlock dispatcher database */ + KiReleaseDispatcherLock(OldIrql); } /* * @implemented */ UCHAR -STDCALL +NTAPI KeSetIdealProcessorThread(IN PKTHREAD Thread, IN UCHAR Processor) { - CCHAR PreviousIdealProcessor; + CCHAR OldIdealProcessor; KIRQL OldIrql; + ASSERT(Processor <= MAXIMUM_PROCESSORS); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Save Old Ideal Processor */ - PreviousIdealProcessor = Thread->IdealProcessor; + OldIdealProcessor = Thread->UserIdealProcessor; - /* Set New Ideal Processor */ - Thread->IdealProcessor = Processor; + /* Make sure a valid CPU was given */ + if (Processor < MAXIMUM_PROCESSORS) + { + /* Check if the user ideal CPU is in the affinity */ + if (Thread->UserIdealProcessor & AFFINITY_MASK(Processor)) + { + /* Set the ideal processor */ + Thread->IdealProcessor = Processor; - /* Release Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Check if system affinity is used */ + if (!Thread->SystemAffinityActive) + { + /* It's not, so update the user CPU too */ + Thread->UserIdealProcessor = Processor; + } + } + } - /* Return Old Ideal Processor */ - return PreviousIdealProcessor; + /* Release dispatcher lock and return the old ideal CPU */ + KiReleaseDispatcherLock(OldIrql); + return OldIdealProcessor; } /* * @implemented */ VOID -STDCALL +NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity) { - PKTHREAD CurrentThread = KeGetCurrentThread(); KIRQL OldIrql; - - ASSERT(Affinity & ((1 << KeNumberProcessors) - 1)); + PKPRCB Prcb; +#ifdef CONFIG_SMP + ULONG AffinitySet, NodeMask; +#endif + PKTHREAD NextThread, CurrentThread = KeGetCurrentThread(); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + ASSERT((Affinity & KeActiveProcessors) != 0); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); - /* Set the System Affinity Specified */ + /* Restore the affinity and enable system affinity */ CurrentThread->Affinity = Affinity; - - /* Enable System Affinity */ CurrentThread->SystemAffinityActive = TRUE; - /* Check if we need to Dispatch a New thread */ - if (Affinity & (1 << KeGetCurrentProcessorNumber())) { + /* Check if the ideal processor is part of the affinity */ +#ifdef CONFIG_SMP + if (!(Affinity & AFFINITY_MASK(CurrentThread->IdealProcessor))) + { + /* It's not! Get the PRCB */ + Prcb = KiProcessorBlock[CurrentThread->IdealProcessor]; - /* No, just release */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Calculate the affinity set */ + AffinitySet = KeActiveProcessors & Affinity; + NodeMask = Prcb->ParentNode->ProcessorMask & AffinitySet; + if (NodeMask) + { + /* Use the Node set instead */ + AffinitySet = NodeMask; + } - } else { + /* Calculate the ideal CPU from the affinity set */ + BitScanReverse(&NodeMask, AffinitySet); + CurrentThread->IdealProcessor = (UCHAR)NodeMask; + } +#endif + /* Get the current PRCB and check if it doesn't match this affinity */ + Prcb = KeGetCurrentPrcb(); + if (!(Prcb->SetMember & CurrentThread->Affinity)) + { + /* Lock the PRCB */ + KiAcquirePrcbLock(Prcb); + +#ifdef NEW_SCHEDULER + /* Check if there's no next thread scheduled */ + if (!Prcb->NextThread) + { + /* Select a new thread and set it on standby */ + NextThread = KiSelectNextThread(Prcb); + NextThread->State = Standby; + Prcb->NextThread = NextThread; + } +#else /* We need to dispatch a new thread */ + NextThread = NULL; CurrentThread->WaitIrql = OldIrql; KiDispatchThreadNoLock(Ready); KeLowerIrql(OldIrql); + return; +#endif + + /* Release the PRCB lock */ + KiReleasePrcbLock(Prcb); } + + /* Unlock dispatcher database */ + KiReleaseDispatcherLock(OldIrql); } LONG From 1ee6196a10fdc23363aef712fe0fd2b5273d2bec Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 17:05:07 +0000 Subject: [PATCH 120/488] - Reposition and update KeQueryBasePriorityThread to use the new locks. - Update KeSetAFfinityThread, KeSetPriorityThread with new locks and assertions (plus the current ROS scheduler hack). svn path=/trunk/; revision=24034 --- reactos/ntoskrnl/ke/thrdobj.c | 180 +++++++++++++++++++--------------- 1 file changed, 101 insertions(+), 79 deletions(-) diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 84cf7b58c90..6177510451b 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -46,6 +46,40 @@ KeFindNextRightSetAffinity(IN UCHAR Number, return (UCHAR)Result; } +KPRIORITY +NTAPI +KeQueryBasePriorityThread(IN PKTHREAD Thread) +{ + LONG BaseIncrement; + KIRQL OldIrql; + PKPROCESS Process; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Raise IRQL to synch level */ + OldIrql = KeRaiseIrqlToSynchLevel(); + + /* Lock the thread */ + KiAcquireThreadLock(Thread); + + /* Get the Process */ + Process = Thread->ApcStatePointer[0]->Process; + + /* Calculate the base increment */ + BaseIncrement = Thread->BasePriority - Process->BasePriority; + + /* If saturation occured, return the saturation increment instead */ + if (Thread->Saturation) BaseIncrement = (HIGH_PRIORITY + 1) / 2 * + Thread->Saturation; + + /* Release thread lock */ + KiReleaseThreadLock(Thread); + + /* Lower IRQl and return Increment */ + KeLowerIrql(OldIrql); + return BaseIncrement; +} + ULONG NTAPI KeAlertResumeThread(IN PKTHREAD Thread) @@ -930,9 +964,6 @@ KeSetSystemAffinityThread(IN KAFFINITY Affinity) { KIRQL OldIrql; PKPRCB Prcb; -#ifdef CONFIG_SMP - ULONG AffinitySet, NodeMask; -#endif PKTHREAD NextThread, CurrentThread = KeGetCurrentThread(); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); ASSERT((Affinity & KeActiveProcessors) != 0); @@ -948,6 +979,8 @@ KeSetSystemAffinityThread(IN KAFFINITY Affinity) #ifdef CONFIG_SMP if (!(Affinity & AFFINITY_MASK(CurrentThread->IdealProcessor))) { + ULONG AffinitySet, NodeMask; + /* It's not! Get the PRCB */ Prcb = KiProcessorBlock[CurrentThread->IdealProcessor]; @@ -999,34 +1032,6 @@ KeSetSystemAffinityThread(IN KAFFINITY Affinity) KiReleaseDispatcherLock(OldIrql); } -LONG -STDCALL -KeQueryBasePriorityThread(IN PKTHREAD Thread) -{ - LONG BasePriorityIncrement; - KIRQL OldIrql; - PKPROCESS Process; - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Get the Process */ - Process = Thread->ApcStatePointer[0]->Process; - - /* Calculate the BPI */ - BasePriorityIncrement = Thread->BasePriority - Process->BasePriority; - - /* If saturation occured, return the SI instead */ - if (Thread->Saturation) BasePriorityIncrement = (HIGH_PRIORITY + 1) / 2 * - Thread->Saturation; - - /* Release Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); - - /* Return Increment */ - return BasePriorityIncrement; -} - /* * @implemented */ @@ -1133,35 +1138,86 @@ KeSetBasePriorityThread(PKTHREAD Thread, /* * @implemented */ -KPRIORITY -STDCALL -KeSetPriorityThread(PKTHREAD Thread, - KPRIORITY Priority) +KAFFINITY +NTAPI +KeSetAffinityThread(IN PKTHREAD Thread, + IN KAFFINITY Affinity) { - KPRIORITY OldPriority; - BOOLEAN Released = FALSE; KIRQL OldIrql; + KAFFINITY OldAffinity; + BOOLEAN Released; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Lock the dispatcher database */ + OldIrql = KiAcquireDispatcherLock(); + + /* Call the internal function */ + OldAffinity = KiSetAffinityThread(Thread, Affinity, &Released); + + /* Check if lock was released */ + if (!Released) + { + /* Release the dispatcher database */ + KiReleaseDispatcherLock(OldIrql); + } + else + { + /* Lower IRQL only */ + KeLowerIrql(OldIrql); + } + + /* Return old affinity */ + return OldAffinity; +} + +/* + * @implemented + */ +KPRIORITY +NTAPI +KeSetPriorityThread(IN PKTHREAD Thread, + IN KPRIORITY Priority) +{ + KIRQL OldIrql; + KPRIORITY OldPriority; + BOOLEAN Released; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + ASSERT((Priority <= HIGH_PRIORITY) && (Priority >= LOW_PRIORITY)); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); + + /* Lock the thread */ + KiAcquireThreadLock(Thread); /* Save the old Priority */ OldPriority = Thread->Priority; - /* Reset the Quantum and Decrements */ - Thread->Quantum = Thread->QuantumReset; - Thread->PriorityDecrement = 0; + /* Make sure that an actual change is being done */ + if (OldPriority != Priority) + { + /* Reset the Quantum and Decrements */ + Thread->Quantum = Thread->QuantumReset; + Thread->PriorityDecrement = 0; - /* Set the new Priority */ - KiSetPriorityThread(Thread, Priority, &Released); + /* Set the new Priority */ + KiSetPriorityThread(Thread, Priority, &Released); + } - /* Release Lock if needed */ + /* Release thread lock */ + KiReleaseThreadLock(Thread); + + /* Check if lock was released */ if (!Released) { - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Release the dispatcher database */ + KiReleaseDispatcherLock(OldIrql); } else { + /* Lower IRQL only */ KeLowerIrql(OldIrql); } @@ -1169,40 +1225,6 @@ KeSetPriorityThread(PKTHREAD Thread, return OldPriority; } -/* - * @implemented - * - * Sets thread's affinity - */ -KAFFINITY -STDCALL -KeSetAffinityThread(PKTHREAD Thread, - KAFFINITY Affinity) -{ - KIRQL OldIrql; - KAFFINITY OldAffinity; - BOOLEAN Released; - - DPRINT("KeSetAffinityThread(Thread %x, Affinity %x)\n", Thread, Affinity); - - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Call the internal function */ - OldAffinity = KiSetAffinityThread(Thread, Affinity, &Released); - - /* Release Lock if needed */ - if (!Released) - { - KeReleaseDispatcherDatabaseLock(OldIrql); - } - else - { - KeLowerIrql(OldIrql); - } - - return OldAffinity; -} - /* * @implemented */ From 4300e4effe7637d3a6ba0dd15d1df2d78fd1f43b Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 17:13:55 +0000 Subject: [PATCH 121/488] - Update the last remaining old function, KeSetBasePriority. Use new locks and assertions, and also make use of KiComputeNewPriority. svn path=/trunk/; revision=24035 --- reactos/ntoskrnl/ke/thrdobj.c | 85 +++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 6177510451b..b948f835e82 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -1036,29 +1036,34 @@ KeSetSystemAffinityThread(IN KAFFINITY Affinity) * @implemented */ LONG -STDCALL -KeSetBasePriorityThread(PKTHREAD Thread, - LONG Increment) +NTAPI +KeSetBasePriorityThread(IN PKTHREAD Thread, + IN LONG Increment) { KIRQL OldIrql; + KPRIORITY OldBasePriority, Priority, BasePriority; + LONG OldIncrement; PKPROCESS Process; - KPRIORITY Priority; - KPRIORITY CurrentBasePriority; - KPRIORITY BasePriority; - BOOLEAN Released = FALSE; - LONG CurrentIncrement; - + BOOLEAN Released; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Get the process */ + Process = Thread->ApcState.Process; + /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); - /* Get the process and calculate current BP and BPI */ - Process = Thread->ApcStatePointer[0]->Process; - CurrentBasePriority = Thread->BasePriority; - CurrentIncrement = CurrentBasePriority - Process->BasePriority; + /* Lock the thread */ + KiAcquireThreadLock(Thread); - /* Change to use the SI if Saturation was used */ - if (Thread->Saturation) CurrentIncrement = (HIGH_PRIORITY + 1) / 2 * - Thread->Saturation; + /* Save the old base priority and increment */ + OldBasePriority = Thread->BasePriority; + OldIncrement = OldBasePriority - Process->BasePriority; + + /* If priority saturation happened, use the saturated increment */ + if (Thread->Saturation) OldIncrement = (HIGH_PRIORITY + 1) / 2 * + Thread->Saturation; /* Now check if saturation is being used for the new value */ if (abs(Increment) >= ((HIGH_PRIORITY + 1) / 2)) @@ -1073,66 +1078,80 @@ KeSetBasePriorityThread(PKTHREAD Thread, { /* Check if it's too low */ if (BasePriority < LOW_REALTIME_PRIORITY) + { + /* Set it to the lowest real time level */ BasePriority = LOW_REALTIME_PRIORITY; + } /* Check if it's too high */ if (BasePriority > HIGH_PRIORITY) BasePriority = HIGH_PRIORITY; - /* We are at RTP, so use the raw BP */ + /* We are at real time, so use the raw base priority */ Priority = BasePriority; } else { - /* Check if it's entering RTP */ + /* Check if it's entering the real time range */ if (BasePriority >= LOW_REALTIME_PRIORITY) + { + /* Set it to the highest dynamic level */ BasePriority = LOW_REALTIME_PRIORITY - 1; + } - /* Check if it's too low */ - if (BasePriority <= LOW_PRIORITY) - BasePriority = 1; + /* Check if it's too low and normalize it */ + if (BasePriority <= LOW_PRIORITY) BasePriority = 1; - /* If Saturation is used, then use the raw BP */ + /* Check if Saturation is used */ if (Thread->Saturation) { + /* Use the raw base priority */ Priority = BasePriority; } else { - /* Calculate the new priority */ - Priority = Thread->Priority + (BasePriority - CurrentBasePriority)- - Thread->PriorityDecrement; + /* Otherwise, calculate the new priority */ + Priority = KiComputeNewPriority(Thread); - /* Make sure it won't enter RTP ranges */ + /* Check if it entered the real-time range */ if (Priority >= LOW_REALTIME_PRIORITY) + { + /* Normalize it down to the highest dynamic priority */ Priority = LOW_REALTIME_PRIORITY - 1; + } } } /* Finally set the new base priority */ - Thread->BasePriority = BasePriority; + Thread->BasePriority = (SCHAR)BasePriority; /* Reset the decrements */ Thread->PriorityDecrement = 0; - /* If the priority will change, reset quantum and change it for real */ + /* Check if we're changing priority after all */ if (Priority != Thread->Priority) { + /* Reset the quantum and do the actual priority modification */ Thread->Quantum = Thread->QuantumReset; KiSetPriorityThread(Thread, Priority, &Released); } - /* Release Lock if needed */ + /* Release thread lock */ + KiReleaseThreadLock(Thread); + + /* Check if lock was released */ if (!Released) { - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Release the dispatcher database */ + KiReleaseDispatcherLock(OldIrql); } else { + /* Lower IRQL only */ KeLowerIrql(OldIrql); } - /* Return the Old Increment */ - return CurrentIncrement; + /* Return old increment */ + return OldIncrement; } /* From ac14f5a03362c3856275fcd7c6812cc8089c3b9b Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sun, 10 Sep 2006 17:16:59 +0000 Subject: [PATCH 122/488] Fix LdrRelocateImageWithBias prototype: Strings in C are neither signed nor unsigned, and they are constants. Fixes warnings with GCC4 svn path=/trunk/; revision=24036 --- reactos/include/ndk/rtlfuncs.h | 2 +- reactos/lib/rtl/image.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index b7d3f1e4d21..58b20f6d3c8 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -2599,7 +2599,7 @@ NTAPI LdrRelocateImageWithBias( IN PVOID NewAddress, IN LONGLONG AdditionalBias, - IN PUCHAR LoaderName, + IN PCCH LoaderName, IN ULONG Success, IN ULONG Conflict, IN ULONG Invalid diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index a37b3c728bf..388e3acac47 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -220,7 +220,7 @@ NTAPI LdrRelocateImageWithBias( IN PVOID BaseAddress, IN LONGLONG AdditionalBias, - IN PUCHAR LoaderName, + IN PCCH LoaderName, IN ULONG Success, IN ULONG Conflict, IN ULONG Invalid From 63346a8ddaa652dd8b819ff4f8918d5a5b695482 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sun, 10 Sep 2006 18:22:48 +0000 Subject: [PATCH 123/488] Fix difference in signedness warning svn path=/trunk/; revision=24037 --- reactos/ntoskrnl/include/internal/ke_x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index e92971e51c6..7b3dcf97511 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -692,7 +692,7 @@ KiSelectReadyThread(IN KPRIORITY Priority, if (!PrioritySet) return NULL; /* Get the highest priority possible */ - BitScanReverse(&HighPriority, PrioritySet); + BitScanReverse((PULONG)&HighPriority, PrioritySet); ASSERT((PrioritySet & PRIORITY_MASK(HighPriority)) != 0); HighPriority += PriorityMask; From da15ddafc8093eafe67c64b14eb25a6191a8b5d9 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 18:26:50 +0000 Subject: [PATCH 124/488] - Get completely rid of old Dispatcher Lock macros and use new ones. - apc.c -> Also multiple optimizations to use the APC lock instead of the full-fledged dispatcher lock. - gate.c -> Use APC lock as well, the full dispatcher lock isn't required because a thread can only wait on one and only one gate. - process.c -> Optimize the code to use the Process and/or APC lock instead of the dispatcher lock. Also delay acquiring the locks after some checks, to make the exit paths simpler. - More fixes are teh needed. svn path=/trunk/; revision=24038 --- reactos/ntoskrnl/ex/resource.c | 8 +- reactos/ntoskrnl/include/internal/ke.h | 8 +- reactos/ntoskrnl/ke/apc.c | 73 +++---- reactos/ntoskrnl/ke/clock.c | 4 +- reactos/ntoskrnl/ke/event.c | 16 +- reactos/ntoskrnl/ke/gate.c | 38 ++-- reactos/ntoskrnl/ke/krnlinit.c | 1 - reactos/ntoskrnl/ke/mutex.c | 10 +- reactos/ntoskrnl/ke/process.c | 260 ++++++++++++------------- reactos/ntoskrnl/ke/queue.c | 20 +- reactos/ntoskrnl/ke/sem.c | 6 +- reactos/ntoskrnl/ke/thrdschd.c | 8 +- reactos/ntoskrnl/ke/timer.c | 12 +- reactos/ntoskrnl/ke/wait.c | 36 ++-- reactos/ntoskrnl/ps/idle.c | 4 +- reactos/ntoskrnl/ps/thread.c | 16 +- 16 files changed, 254 insertions(+), 266 deletions(-) diff --git a/reactos/ntoskrnl/ex/resource.c b/reactos/ntoskrnl/ex/resource.c index cdca8c1e981..a34fad90ad9 100644 --- a/reactos/ntoskrnl/ex/resource.c +++ b/reactos/ntoskrnl/ex/resource.c @@ -307,7 +307,7 @@ ExpExpandResourceOwnerTable(IN PERESOURCE_XP Resource, OldSize * sizeof(OWNER_ENTRY)); /* Acquire dispatcher lock to prevent thread boosting */ - KeAcquireDispatcherDatabaseLockAtDpcLevel(); + KiAcquireDispatcherLockAtDpcLevel(); /* Set the new table data */ Table->TableSize = NewSize; @@ -317,7 +317,7 @@ ExpExpandResourceOwnerTable(IN PERESOURCE_XP Resource, ExpVerifyResource(Resource); /* Release locks */ - KeReleaseDispatcherDatabaseLockFromDpcLevel(); + KiReleaseDispatcherLockFromDpcLevel(); ExReleaseResourceLock(&Resource->SpinLock, *OldIrql); /* Free the old table */ @@ -571,7 +571,7 @@ ExpBoostOwnerThread(IN PKTHREAD Thread, KiSetPriorityThread(OwnerThread, 14, &Released); /* Reacquire lock if it got releases */ - if (Released) KeAcquireDispatcherDatabaseLockFromDpcLevel(); + if (Released) KiAcquireDispatcherLockFromDpcLevel(); /* Make sure we're still at dispatch */ ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); @@ -691,7 +691,7 @@ ExpWaitForResource(IN PERESOURCE_XP Resource, /* Get the current kernel thread and lock the dispatcher */ Thread = KeGetCurrentThread(); - Thread->WaitIrql = KeAcquireDispatcherDatabaseLock(); + Thread->WaitIrql = KiAcquireDispatcherLock(); Thread->WaitNext = TRUE; /* Get the owner thread and boost it */ diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index e75dec5fe60..d1689129ec1 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -187,12 +187,6 @@ extern VOID KiTrap2(VOID); /* INTERNAL KERNEL FUNCTIONS ************************************************/ -#define KeInitializeDispatcher() -#define KeAcquireDispatcherDatabaseLock() KeRaiseIrqlToDpcLevel(); -#define KeReleaseDispatcherDatabaseLock(OldIrql) KiExitDispatcher(OldIrql); -#define KeAcquireDispatcherDatabaseLockAtDpcLevel() -#define KeReleaseDispatcherDatabaseLockFromDpcLevel() - /* Readies a Thread for Execution. */ BOOLEAN NTAPI @@ -620,7 +614,7 @@ NTAPI KiAttachProcess( struct _KTHREAD *Thread, struct _KPROCESS *Process, - KIRQL ApcLock, + PKLOCK_QUEUE_HANDLE ApcLock, struct _KAPC_STATE *SavedApcState ); diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index a367aeeb04f..da66359f99c 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -482,39 +482,34 @@ KeInsertQueueApc(PKAPC Apc, PVOID SystemArgument2, KPRIORITY PriorityBoost) { - KIRQL OldIrql; - PKTHREAD Thread; + PKTHREAD Thread = Apc->Thread; + KLOCK_QUEUE_HANDLE ApcLock; + BOOLEAN State = TRUE; - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, " - "SystemArgument2 %x)\n",Apc,SystemArgument1, - SystemArgument2); - - /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Get the Thread specified in the APC */ - Thread = Apc->Thread; + /* Get the APC lock */ + KiAcquireApcLock(Thread, &ApcLock); /* Make sure we can Queue APCs and that this one isn't already inserted */ if ((Thread->ApcQueueable == FALSE) && (Apc->Inserted == TRUE)) { - DPRINT("Can't queue the APC\n"); - KeReleaseDispatcherDatabaseLock(OldIrql); - return FALSE; + /* Fail */ + State = FALSE; + } + else + { + /* Set the System Arguments and set it as inserted */ + Apc->SystemArgument1 = SystemArgument1; + Apc->SystemArgument2 = SystemArgument2; + Apc->Inserted = TRUE; + + /* Call the Internal Function */ + KiInsertQueueApc(Apc, PriorityBoost); } - /* Set the System Arguments and set it as inserted */ - Apc->SystemArgument1 = SystemArgument1; - Apc->SystemArgument2 = SystemArgument2; - Apc->Inserted = TRUE; - - /* Call the Internal Function */ - KiInsertQueueApc(Apc, PriorityBoost); - - /* Return Sucess if we are here */ - KeReleaseDispatcherDatabaseLock(OldIrql); - return TRUE; + /* Release the APC lock and return success */ + KiReleaseApcLock(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); + return State; } /*++ @@ -542,13 +537,12 @@ STDCALL KeFlushQueueApc(IN PKTHREAD Thread, IN KPROCESSOR_MODE PreviousMode) { - KIRQL OldIrql; PKAPC Apc; PLIST_ENTRY FirstEntry, CurrentEntry; + KLOCK_QUEUE_HANDLE ApcLock; - /* Lock the Dispatcher Database and APC Queue */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock); + /* Get the APC lock */ + KiAcquireApcLock(Thread, &ApcLock); if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) { FirstEntry = NULL; @@ -563,9 +557,8 @@ KeFlushQueueApc(IN PKTHREAD Thread, } while (CurrentEntry != FirstEntry); } - /* Release the locks */ - KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Release the lock */ + KiReleaseApcLock(&ApcLock); /* Return the first entry */ return FirstEntry; @@ -596,16 +589,13 @@ BOOLEAN STDCALL KeRemoveQueueApc(PKAPC Apc) { - KIRQL OldIrql; PKTHREAD Thread = Apc->Thread; PKAPC_STATE ApcState; BOOLEAN Inserted; - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc); + KLOCK_QUEUE_HANDLE ApcLock; - /* Acquire locks */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock); + /* Get the APC lock */ + KiAcquireApcLock(Thread, &ApcLock); /* Check if it's inserted */ if ((Inserted = Apc->Inserted)) @@ -630,9 +620,8 @@ KeRemoveQueueApc(PKAPC Apc) } } - /* Restore IRQL and Return */ - KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Release the lock and return */ + KiReleaseApcLock(&ApcLock); return Inserted; } diff --git a/reactos/ntoskrnl/ke/clock.c b/reactos/ntoskrnl/ke/clock.c index 20b691c2a5a..2bca7c9f630 100644 --- a/reactos/ntoskrnl/ke/clock.c +++ b/reactos/ntoskrnl/ke/clock.c @@ -99,7 +99,7 @@ KiSetSystemTime(PLARGE_INTEGER NewSystemTime) ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); do { @@ -122,7 +122,7 @@ KiSetSystemTime(PLARGE_INTEGER NewSystemTime) /* Update absolute timers */ DPRINT1("FIXME: TIMER UPDATE NOT DONE!!!\n"); - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* * NOTE: Expired timers will be processed at the next clock tick! diff --git a/reactos/ntoskrnl/ke/event.c b/reactos/ntoskrnl/ke/event.c index 68930adc0bb..1887e4e6313 100644 --- a/reactos/ntoskrnl/ke/event.c +++ b/reactos/ntoskrnl/ke/event.c @@ -80,7 +80,7 @@ KePulseEvent(IN PKEVENT Event, DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Save the Old State */ PreviousState = Event->Header.SignalState; @@ -102,7 +102,7 @@ KePulseEvent(IN PKEVENT Event, if (Wait == FALSE) { /* Wait not requested, release Dispatcher Database and return */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); } else { @@ -140,7 +140,7 @@ KeResetEvent(PKEVENT Event) DPRINT("KeResetEvent(Event %x)\n",Event); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Save the Previous State */ PreviousState = Event->Header.SignalState; @@ -149,7 +149,7 @@ KeResetEvent(PKEVENT Event) Event->Header.SignalState = 0; /* Release Dispatcher Database and return previous state */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); return PreviousState; } @@ -169,7 +169,7 @@ KeSetEvent(PKEVENT Event, DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait); /* Lock the Dispathcer Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Save the Previous State */ PreviousState = Event->Header.SignalState; @@ -212,7 +212,7 @@ KeSetEvent(PKEVENT Event, if (Wait == FALSE) { /* Wait not requested, release Dispatcher Database and return */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); } else { @@ -241,7 +241,7 @@ KeSetEventBoostPriority(IN PKEVENT Event, DPRINT("KeSetEventBoostPriority(Event %x, Thread %x)\n",Event,Thread); /* Acquire Dispatcher Database Lock */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* If our wait list is empty, then signal the event and return */ if (IsListEmpty(&Event->Header.WaitListHead)) { @@ -264,7 +264,7 @@ KeSetEventBoostPriority(IN PKEVENT Event, } /* Release the Dispatcher Database Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); } /* EOF */ diff --git a/reactos/ntoskrnl/ke/gate.c b/reactos/ntoskrnl/ke/gate.c index a9583caf6ef..c625c6c5dde 100644 --- a/reactos/ntoskrnl/ke/gate.c +++ b/reactos/ntoskrnl/ke/gate.c @@ -32,7 +32,7 @@ KeWaitForGate(IN PKGATE Gate, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode) { - KIRQL OldIrql; + KLOCK_QUEUE_HANDLE ApcLock; PKTHREAD CurrentThread = KeGetCurrentThread(); PKWAIT_BLOCK GateWaitBlock; NTSTATUS Status; @@ -42,15 +42,16 @@ KeWaitForGate(IN PKGATE Gate, /* Start wait loop */ do { - /* Lock the dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + /* Acquire the APC lock */ + KiAcquireApcLock(CurrentThread, &ApcLock); /* Check if a kernel APC is pending and we're below APC_LEVEL */ if ((CurrentThread->ApcState.KernelApcPending) && - !(CurrentThread->SpecialApcDisable) && (OldIrql < APC_LEVEL)) + !(CurrentThread->SpecialApcDisable) && + (ApcLock.OldIrql < APC_LEVEL)) { - /* Unlock the dispatcher, this will fire the APC */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Release the lock, this will fire the APC */ + KiReleaseApcLock(&ApcLock); } else { @@ -60,8 +61,8 @@ KeWaitForGate(IN PKGATE Gate, /* Unsignal it */ Gate->Header.SignalState = 0; - /* Unlock the Queue and return */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Release the APC lock and return */ + KiReleaseApcLock(&ApcLock); return; } @@ -73,7 +74,7 @@ KeWaitForGate(IN PKGATE Gate, /* Set the Thread Wait Data */ CurrentThread->WaitMode = WaitMode; CurrentThread->WaitReason = WaitReason; - CurrentThread->WaitIrql = OldIrql; + CurrentThread->WaitIrql = ApcLock.OldIrql; CurrentThread->State = GateWait; CurrentThread->GateObject = Gate; @@ -84,6 +85,9 @@ KeWaitForGate(IN PKGATE Gate, /* Handle Kernel Queues */ if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue); + /* Release the APC lock but stay at DPC level */ + KiReleaseApcLockFromDpcLevel(&ApcLock); + /* Find a new thread to run */ Status = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); @@ -104,11 +108,16 @@ KeSignalGateBoostPriority(IN PKGATE Gate) ASSERT_GATE(Gate); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - /* Acquire Dispatcher Database Lock */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + /* Raise to synch level */ + OldIrql = KeRaiseIrqlToSynchLevel(); /* Make sure we're not already signaled or that the list is empty */ - if (Gate->Header.SignalState) goto quit; + if (Gate->Header.SignalState) + { + /* Lower IRQL and quit */ + KeLowerIrql(OldIrql); + return; + } /* Check if our wait list is empty */ if (IsListEmpty(&Gate->Header.WaitListHead)) @@ -136,9 +145,8 @@ KeSignalGateBoostPriority(IN PKGATE Gate) KiAbortWaitThread(WaitThread, WaitStatus, EVENT_INCREMENT); } -quit: - /* Release the Dispatcher Database Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Exit the dispatcher */ + KiExitDispatcher(OldIrql); } /* EOF */ diff --git a/reactos/ntoskrnl/ke/krnlinit.c b/reactos/ntoskrnl/ke/krnlinit.c index 734d1ee54e2..ea0849d00e8 100644 --- a/reactos/ntoskrnl/ke/krnlinit.c +++ b/reactos/ntoskrnl/ke/krnlinit.c @@ -264,7 +264,6 @@ KiInitSpinLocks(IN PKPRCB Prcb, KeInitializeSpinLock(&MmNonPagedPoolLock); KeInitializeSpinLock(&NtfsStructLock); KeInitializeSpinLock(&AfdWorkQueueSpinLock); - KeInitializeDispatcher(); // ROS OLD DISPATCHER } } diff --git a/reactos/ntoskrnl/ke/mutex.c b/reactos/ntoskrnl/ke/mutex.c index e45cf486d5b..2d7c248a6dd 100644 --- a/reactos/ntoskrnl/ke/mutex.c +++ b/reactos/ntoskrnl/ke/mutex.c @@ -39,14 +39,14 @@ KeInitializeMutant(IN PKMUTANT Mutant, Mutant->OwnerThread = CurrentThread; /* We're about to touch the Thread, so lock the Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* And insert it into its list */ InsertTailList(&CurrentThread->MutantListHead, &Mutant->MutantListEntry); /* Release Dispatcher Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); DPRINT("Mutant with Initial Owner\n"); } else @@ -115,7 +115,7 @@ KeReleaseMutant(IN PKMUTANT Mutant, DPRINT("KeReleaseMutant: %x\n", Mutant); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Save the Previous State */ PreviousState = Mutant->Header.SignalState; @@ -129,7 +129,7 @@ KeReleaseMutant(IN PKMUTANT Mutant, DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n"); /* Release the lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* Raise an exception */ ExRaiseStatus(Mutant->Abandoned ? STATUS_ABANDONED : @@ -194,7 +194,7 @@ KeReleaseMutant(IN PKMUTANT Mutant, if (Wait == FALSE) { /* Release the Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); } else { diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index 40683146960..cd30899c03c 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -61,7 +61,7 @@ VOID NTAPI KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, - KIRQL OldIrql, + PKLOCK_QUEUE_HANDLE ApcLock, PRKAPC_STATE SavedApcState) { ASSERT(Process != Thread->ApcState.Process); @@ -95,11 +95,14 @@ KiAttachProcess(PKTHREAD Thread, { /* FIXME: Scan the Ready Thread List once new scheduler is in */ - /* Swap the Processes */ + /* Release lock */ + KiReleaseApcLockFromDpcLevel(ApcLock); + + /* Swap Processes */ KiSwapProcess(Process, SavedApcState->Process); - /* Return to old IRQL*/ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Exit the dispatcher */ + KiExitDispatcher(ApcLock->OldIrql); } else { @@ -189,7 +192,7 @@ KeSetProcess(PKPROCESS Process, ULONG OldState; /* Lock Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Get Old State */ OldState = Process->Header.SignalState; @@ -203,7 +206,7 @@ KeSetProcess(PKPROCESS Process, } /* Release Dispatcher Database */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* Return the previous State */ return OldState; @@ -223,14 +226,14 @@ NTAPI KeSetQuantumProcess(IN PKPROCESS Process, IN UCHAR Quantum) { - KIRQL OldIrql; + KLOCK_QUEUE_HANDLE ProcessLock; PLIST_ENTRY NextEntry, ListHead; PKTHREAD Thread; ASSERT_PROCESS(Process); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - /* Lock Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + /* Lock the process */ + KiAcquireProcessLock(Process, &ProcessLock); /* Set new quantum */ Process->QuantumReset = Quantum; @@ -250,8 +253,8 @@ KeSetQuantumProcess(IN PKPROCESS Process, NextEntry = NextEntry->Flink; } - /* Release Dispatcher Database */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Release lock */ + KiReleaseProcessLock(&ProcessLock); } KPRIORITY @@ -280,7 +283,7 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, if (!Priority) Priority = 1; /* Lock Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Check if we are modifying the quantum too */ if (Quantum) Process->QuantumReset = Quantum; @@ -410,7 +413,7 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, } /* Release Dispatcher Database */ - if (!Released) KeReleaseDispatcherDatabaseLock(OldIrql); + if (!Released) KiReleaseDispatcherLock(OldIrql); /* Return previous priority */ return OldPriority; @@ -423,7 +426,7 @@ VOID NTAPI KeAttachProcess(PKPROCESS Process) { - KIRQL OldIrql; + KLOCK_QUEUE_HANDLE ApcLock; PKTHREAD Thread; ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); DPRINT("KeAttachProcess: %x\n", Process); @@ -432,19 +435,17 @@ KeAttachProcess(PKPROCESS Process) Thread = KeGetCurrentThread(); UpdatePageDirs(Thread, Process); - /* Lock Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - /* Check if we're already in that process */ - if (Thread->ApcState.Process == Process) + if (Thread->ApcState.Process == Process) return; + + /* Acquire APC Lock */ + KiAcquireApcLock(Thread, &ApcLock); + + /* Check if a DPC is executing or if we're already attached */ + if ((Thread->ApcStateIndex != OriginalApcEnvironment) || + (KeIsExecutingDpc())) { - /* Unlock the dispatcher, nothing to do */ - KeReleaseDispatcherDatabaseLock(OldIrql); - } - else if ((Thread->ApcStateIndex != OriginalApcEnvironment) || - (KeIsExecutingDpc())) - { - /* Executing a DPC or already attached, crash! */ + /* Invalid attempt */ KEBUGCHECKEX(INVALID_PROCESS_ATTACH_ATTEMPT, (ULONG_PTR)Process, (ULONG_PTR)Thread->ApcState.Process, @@ -454,7 +455,7 @@ KeAttachProcess(PKPROCESS Process) else { /* Legit attach attempt: do it! */ - KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); + KiAttachProcess(Thread, Process, &ApcLock, &Thread->SavedApcState); } } @@ -465,45 +466,46 @@ VOID NTAPI KeDetachProcess (VOID) { - PKTHREAD Thread; - KIRQL OldIrql; + PKTHREAD Thread = KeGetCurrentThread(); + KLOCK_QUEUE_HANDLE ApcLock; ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); DPRINT("KeDetachProcess()\n"); - /* Get Current Thread and lock the dispatcher */ - Thread = KeGetCurrentThread(); - OldIrql = KeAcquireDispatcherDatabaseLock(); - /* Check if it's attached */ - if (Thread->ApcStateIndex != OriginalApcEnvironment) + if (Thread->ApcStateIndex == OriginalApcEnvironment) return; + + /* Acquire APC Lock */ + KiAcquireApcLock(Thread, &ApcLock); + + /* It is, decrease Stack Count */ + if(!(--Thread->ApcState.Process->StackCount)) { - /* It is, decrease Stack Count */ - if(!(--Thread->ApcState.Process->StackCount)) - { - /* FIXME: Swap the process out */ - } - - /* Restore the APC State */ - KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); - Thread->SavedApcState.Process = NULL; - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; - Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; - Thread->ApcStateIndex = OriginalApcEnvironment; - - /* Check if we have pending APCs */ - if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) - { - /* What do you know, we do! Request them to be delivered */ - Thread->ApcState.KernelApcPending = TRUE; - HalRequestSoftwareInterrupt(APC_LEVEL); - } - - /* Swap Processes */ - KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); + /* FIXME: Swap the process out */ } - /* Unlock Dispatcher */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Restore the APC State */ + KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); + Thread->SavedApcState.Process = NULL; + Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; + Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; + Thread->ApcStateIndex = OriginalApcEnvironment; + + /* Release lock */ + KiReleaseApcLockFromDpcLevel(&ApcLock); + + /* Swap Processes */ + KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); + + /* Exit the dispatcher */ + KiExitDispatcher(ApcLock.OldIrql); + + /* Check if we have pending APCs */ + if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) + { + /* What do you know, we do! Request them to be delivered */ + Thread->ApcState.KernelApcPending = TRUE; + HalRequestSoftwareInterrupt(APC_LEVEL); + } } /* @@ -525,17 +527,13 @@ NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState) { - KIRQL OldIrql; - PKTHREAD Thread; + KLOCK_QUEUE_HANDLE ApcLock; + PKTHREAD Thread = KeGetCurrentThread(); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Make sure that we are in the right page directory */ - Thread = KeGetCurrentThread(); UpdatePageDirs(Thread, Process); - /* Acquire the dispatcher lock */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - /* Crash system if DPC is being executed! */ if (KeIsExecutingDpc()) { @@ -550,26 +548,25 @@ KeStackAttachProcess(IN PKPROCESS Process, /* Check if we are already in the target process */ if (Thread->ApcState.Process == Process) { - /* Unlock the dispatcher database */ - KeReleaseDispatcherDatabaseLock(OldIrql); - /* Set magic value so we don't crash later when detaching */ ApcState->Process = (PKPROCESS)1; + return; + } + + /* Acquire APC Lock */ + KiAcquireApcLock(Thread, &ApcLock); + + /* Check if the Current Thread is already attached */ + if (Thread->ApcStateIndex != OriginalApcEnvironment) + { + /* We're already attached, so save the APC State into what we got */ + KiAttachProcess(Thread, Process, &ApcLock, ApcState); } else { - /* Check if the Current Thread is already attached */ - if (Thread->ApcStateIndex != OriginalApcEnvironment) - { - /* We're already attached, so save the APC State into what we got */ - KiAttachProcess(Thread, Process, OldIrql, ApcState); - } - else - { - /* We're not attached, so save the APC State into SavedApcState */ - KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); - ApcState->Process = NULL; - } + /* We're not attached, so save the APC State into SavedApcState */ + KiAttachProcess(Thread, Process, &ApcLock, &Thread->SavedApcState); + ApcState->Process = NULL; } } @@ -580,64 +577,65 @@ VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState) { - KIRQL OldIrql; - PKTHREAD Thread; + KLOCK_QUEUE_HANDLE ApcLock; + PKTHREAD Thread = KeGetCurrentThread(); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - /* Get the current thread and acquire the dispatcher lock */ - Thread = KeGetCurrentThread(); - OldIrql = KeAcquireDispatcherDatabaseLock(); - /* Check for magic value meaning we were already in the same process */ - if (ApcState->Process != (PKPROCESS)1) + if (ApcState->Process == (PKPROCESS)1) return; + + /* Acquire APC Lock */ + KiAcquireApcLock(Thread, &ApcLock); + + /* + * Check if the process isn't attacked, or has a Kernel APC in progress + * or has pending APC of any kind. + */ + if ((Thread->ApcStateIndex == OriginalApcEnvironment) || + (Thread->ApcState.KernelApcInProgress) || + (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) || + (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) { - /* - * Check if the process isn't attacked, or has a Kernel APC in progress - * or has pending APC of any kind. - */ - if ((Thread->ApcStateIndex == OriginalApcEnvironment) || - (Thread->ApcState.KernelApcInProgress) || - (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) || - (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) - { - KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT); - } - - /* Decrease Stack Count */ - if(!(--Thread->ApcState.Process->StackCount)) - { - /* FIXME: Swap the process out */ - } - - if (ApcState->Process != NULL) - { - /* Restore the APC State */ - KiMoveApcState(ApcState, &Thread->ApcState); - } - else - { - /* The ApcState parameter is useless, so use the saved data and reset it */ - KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); - Thread->SavedApcState.Process = NULL; - Thread->ApcStateIndex = OriginalApcEnvironment; - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; - Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; - } - - /* Check if we have pending APCs */ - if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) - { - /* What do you know, we do! Request them to be delivered */ - Thread->ApcState.KernelApcPending = TRUE; - HalRequestSoftwareInterrupt(APC_LEVEL); - } - - /* Swap Processes */ - KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); + KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT); } - /* Return to old IRQL*/ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Decrease Stack Count */ + if(!(--Thread->ApcState.Process->StackCount)) + { + /* FIXME: Swap the process out */ + } + + if (ApcState->Process != NULL) + { + /* Restore the APC State */ + KiMoveApcState(ApcState, &Thread->ApcState); + } + else + { + /* The ApcState parameter is useless, so use the saved data and reset it */ + KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); + Thread->SavedApcState.Process = NULL; + Thread->ApcStateIndex = OriginalApcEnvironment; + Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; + Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; + } + + /* Release lock */ + KiReleaseApcLockFromDpcLevel(&ApcLock); + + /* Swap Processes */ + KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); + + /* Exit the dispatcher */ + KiExitDispatcher(ApcLock.OldIrql); + + /* Check if we have pending APCs */ + if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) + { + /* What do you know, we do! Request them to be delivered */ + Thread->ApcState.KernelApcPending = TRUE; + HalRequestSoftwareInterrupt(APC_LEVEL); + } } /* diff --git a/reactos/ntoskrnl/ke/queue.c b/reactos/ntoskrnl/ke/queue.c index 041af562cc8..8e5469160aa 100644 --- a/reactos/ntoskrnl/ke/queue.c +++ b/reactos/ntoskrnl/ke/queue.c @@ -180,13 +180,13 @@ KeInsertHeadQueue(IN PKQUEUE Queue, ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Insert the Queue */ PreviousState = KiInsertQueue(Queue, Entry, TRUE); /* Release the Dispatcher Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* Return previous State */ return PreviousState; @@ -206,13 +206,13 @@ KeInsertQueue(IN PKQUEUE Queue, ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Insert the Queue */ PreviousState = KiInsertQueue(Queue, Entry, FALSE); /* Release the Dispatcher Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* Return previous State */ return PreviousState; @@ -263,7 +263,7 @@ KeRemoveQueue(IN PKQUEUE Queue, else { /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); Thread->WaitIrql = OldIrql; } @@ -335,7 +335,7 @@ KeRemoveQueue(IN PKQUEUE Queue, { /* Increment the count and unlock the dispatcher */ Queue->CurrentCount++; - KeReleaseDispatcherDatabaseLock(Thread->WaitIrql); + KiReleaseDispatcherLock(Thread->WaitIrql); } else { @@ -449,7 +449,7 @@ KeRemoveQueue(IN PKQUEUE Queue, } /* Reacquire the lock */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Save the new IRQL and decrease number of waiting threads */ Thread->WaitIrql = OldIrql; @@ -458,7 +458,7 @@ KeRemoveQueue(IN PKQUEUE Queue, } /* Unlock Database and return */ - KeReleaseDispatcherDatabaseLock(Thread->WaitIrql); + KiReleaseDispatcherLock(Thread->WaitIrql); return QueueEntry; } @@ -478,7 +478,7 @@ KeRundownQueue(IN PKQUEUE Queue) ASSERT(IsListEmpty(&Queue->Header.WaitListHead)); /* Get the Dispatcher Lock */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Make sure the list is not empty */ if (!IsListEmpty(&Queue->EntryListHead)) @@ -501,7 +501,7 @@ KeRundownQueue(IN PKQUEUE Queue) } /* Release the lock and return */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); return FirstEntry; } diff --git a/reactos/ntoskrnl/ke/sem.c b/reactos/ntoskrnl/ke/sem.c index 69d3b2a9a64..92baf77daee 100644 --- a/reactos/ntoskrnl/ke/sem.c +++ b/reactos/ntoskrnl/ke/sem.c @@ -87,7 +87,7 @@ KeReleaseSemaphore(PKSEMAPHORE Semaphore, Wait); /* Lock the Dispatcher Database */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Save the Old State and get new one */ InitialState = Semaphore->Header.SignalState; @@ -97,7 +97,7 @@ KeReleaseSemaphore(PKSEMAPHORE Semaphore, if ((Semaphore->Limit < State) || (InitialState > State)) { /* Raise an error if it was exceeded */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED); } @@ -115,7 +115,7 @@ KeReleaseSemaphore(PKSEMAPHORE Semaphore, if (Wait == FALSE) { /* Release the Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); } else { diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c index 6cb0601fc9e..dad5c83c546 100644 --- a/reactos/ntoskrnl/ke/thrdschd.c +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -124,7 +124,7 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus) if (Candidate == CurrentThread) { Candidate->State = Running; - KeReleaseDispatcherDatabaseLockFromDpcLevel(); + KiReleaseDispatcherLockFromDpcLevel(); return FALSE; } @@ -204,7 +204,7 @@ KiDispatchThread(ULONG NewThreadStatus) return; } - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); KiDispatchThreadNoLock(NewThreadStatus); KeLowerIrql(OldIrql); } @@ -328,7 +328,7 @@ KiSetPriorityThread(PKTHREAD Thread, /* Reschedule if the new one is already on a CPU */ if (Pcr->Prcb->CurrentThread == Thread) { - KeReleaseDispatcherDatabaseLockFromDpcLevel(); + KiReleaseDispatcherLockFromDpcLevel(); KiRequestReschedule(i); *Released = TRUE; return; @@ -393,7 +393,7 @@ KiSetAffinityThread(IN PKTHREAD Thread, if (!(Affinity & ProcessorMask)) { - KeReleaseDispatcherDatabaseLockFromDpcLevel(); + KiReleaseDispatcherLockFromDpcLevel(); KiRequestReschedule(i); *Released = TRUE; return OldAffinity; diff --git a/reactos/ntoskrnl/ke/timer.c b/reactos/ntoskrnl/ke/timer.c index b212ddba1a8..160f869cc05 100644 --- a/reactos/ntoskrnl/ke/timer.c +++ b/reactos/ntoskrnl/ke/timer.c @@ -142,7 +142,7 @@ KiExpireTimers(IN PKDPC Dpc, InitializeListHead(&ExpiredTimerList); /* Lock the Database and Raise IRQL */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Query Interrupt Times */ InterruptTime = KeQueryInterruptTime(); @@ -185,7 +185,7 @@ KiExpireTimers(IN PKDPC Dpc, } /* Release Dispatcher Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); } /* PUBLIC FUNCTIONS **********************************************************/ @@ -203,7 +203,7 @@ KeCancelTimer(IN OUT PKTIMER Timer) ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock the Database and Raise IRQL */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Check if it's inserted, and remove it if it is */ Inserted = Timer->Header.Inserted; @@ -218,7 +218,7 @@ KeCancelTimer(IN OUT PKTIMER Timer) } /* Release Dispatcher Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); return Inserted; } @@ -293,7 +293,7 @@ KeSetTimerEx(IN OUT PKTIMER Timer, ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock the Database and Raise IRQL */ - OldIrql = KeAcquireDispatcherDatabaseLock(); + OldIrql = KiAcquireDispatcherLock(); /* Check if it's inserted, and remove it if it is */ Inserted = Timer->Header.Inserted; @@ -341,7 +341,7 @@ KeSetTimerEx(IN OUT PKTIMER Timer, } /* Release Dispatcher Lock */ - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* Return old state */ return Inserted; diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 24bd29abbfb..38eac343f74 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -252,7 +252,7 @@ KiExitDispatcher(IN KIRQL OldIrql) else { /* Otherwise just release the lock */ - KeReleaseDispatcherDatabaseLockFromDpcLevel(); + KiReleaseDispatcherLockFromDpcLevel(); } /* Lower irql back */ @@ -287,7 +287,7 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, else { /* Lock not held, acquire it */ - CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock(); + CurrentThread->WaitIrql = KiAcquireDispatcherLock(); } /* Use built-in Wait block */ @@ -302,7 +302,7 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, (CurrentThread->WaitIrql < APC_LEVEL)) { /* Unlock the dispatcher */ - KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(CurrentThread->WaitIrql); } else { @@ -372,11 +372,11 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, } /* Acquire again the lock */ - CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock(); + CurrentThread->WaitIrql = KiAcquireDispatcherLock(); } while (TRUE); /* Release the Lock, we are done */ - KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(CurrentThread->WaitIrql); return WaitStatus; } @@ -410,7 +410,7 @@ KeWaitForSingleObject(IN PVOID Object, else { /* Lock not held, acquire it */ - CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock(); + CurrentThread->WaitIrql = KiAcquireDispatcherLock(); } /* Start the actual Loop */ @@ -423,7 +423,7 @@ KeWaitForSingleObject(IN PVOID Object, (CurrentThread->WaitIrql < APC_LEVEL)) { /* Unlock the dispatcher */ - KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(CurrentThread->WaitIrql); } else { @@ -451,7 +451,7 @@ KeWaitForSingleObject(IN PVOID Object, else { /* Raise an exception (see wasm.ru) */ - KeReleaseDispatcherDatabaseLock(CurrentThread-> + KiReleaseDispatcherLock(CurrentThread-> WaitIrql); ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); } @@ -557,11 +557,11 @@ KeWaitForSingleObject(IN PVOID Object, } /* Acquire again the lock */ - CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock(); + CurrentThread->WaitIrql = KiAcquireDispatcherLock(); } while (TRUE); /* Release the Lock, we are done */ - KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(CurrentThread->WaitIrql); return WaitStatus; DontWait: @@ -569,7 +569,7 @@ DontWait: KiAdjustQuantumThread(CurrentThread); /* Release & Return */ - KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(CurrentThread->WaitIrql); return WaitStatus; } @@ -611,7 +611,7 @@ KeWaitForMultipleObjects(IN ULONG Count, else { /* Lock not held, acquire it */ - CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock(); + CurrentThread->WaitIrql = KiAcquireDispatcherLock(); } /* Make sure the Wait Count is valid */ @@ -646,7 +646,7 @@ KeWaitForMultipleObjects(IN ULONG Count, (CurrentThread->WaitIrql < APC_LEVEL)) { /* Unlock the dispatcher */ - KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(CurrentThread->WaitIrql); } else { @@ -689,7 +689,7 @@ KeWaitForMultipleObjects(IN ULONG Count, else { /* Raise an exception (see wasm.ru) */ - KeReleaseDispatcherDatabaseLock(CurrentThread-> + KiReleaseDispatcherLock(CurrentThread-> WaitIrql); ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); } @@ -713,7 +713,7 @@ KeWaitForMultipleObjects(IN ULONG Count, (CurrentObject->Header.SignalState == MINLONG)) { /* Raise an exception */ - KeReleaseDispatcherDatabaseLock(CurrentThread-> + KiReleaseDispatcherLock(CurrentThread-> WaitIrql); ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); } @@ -844,12 +844,12 @@ KeWaitForMultipleObjects(IN ULONG Count, } /* Acquire again the lock */ - CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock(); + CurrentThread->WaitIrql = KiAcquireDispatcherLock(); } } while (TRUE); /* Release the Lock, we are done */ - KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(CurrentThread->WaitIrql); return WaitStatus; DontWait: @@ -857,7 +857,7 @@ DontWait: KiAdjustQuantumThread(CurrentThread); /* Release & Return */ - KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(CurrentThread->WaitIrql); return WaitStatus; } diff --git a/reactos/ntoskrnl/ps/idle.c b/reactos/ntoskrnl/ps/idle.c index 575c12ca78a..e46a744435c 100644 --- a/reactos/ntoskrnl/ps/idle.c +++ b/reactos/ntoskrnl/ps/idle.c @@ -105,9 +105,9 @@ PsInitIdleThread(VOID) KernelMode, FALSE); - oldIrql = KeAcquireDispatcherDatabaseLock (); + oldIrql = KiAcquireDispatcherLock (); KiReadyThread(&IdleThread->Tcb); - KeReleaseDispatcherDatabaseLock(oldIrql); + KiReleaseDispatcherLock(oldIrql); KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 3ac6d69fc3a..61e496565cf 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -397,9 +397,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle, if (CreateSuspended) KeResumeThread(&Thread->Tcb); /* Dispatch thread */ - OldIrql = KeAcquireDispatcherDatabaseLock (); + OldIrql = KiAcquireDispatcherLock (); KiReadyThread(&Thread->Tcb); - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* Dereference completely to kill it */ ObDereferenceObjectEx(Thread, 2); @@ -439,9 +439,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle, if (CreateSuspended) KeResumeThread(&Thread->Tcb); /* Dispatch thread */ - OldIrql = KeAcquireDispatcherDatabaseLock (); + OldIrql = KiAcquireDispatcherLock (); KiReadyThread(&Thread->Tcb); - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* Dereference it, leaving only the keep-alive */ ObDereferenceObject(Thread); @@ -482,9 +482,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle, if (CreateSuspended) KeResumeThread(&Thread->Tcb); /* Dispatch thread */ - OldIrql = KeAcquireDispatcherDatabaseLock (); + OldIrql = KiAcquireDispatcherLock (); KiReadyThread(&Thread->Tcb); - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* Dereference it, leaving only the keep-alive */ ObDereferenceObject(Thread); @@ -533,9 +533,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle, /* Dispatch thread */ PSREFTRACE(Thread); - OldIrql = KeAcquireDispatcherDatabaseLock (); + OldIrql = KiAcquireDispatcherLock (); KiReadyThread(&Thread->Tcb); - KeReleaseDispatcherDatabaseLock(OldIrql); + KiReleaseDispatcherLock(OldIrql); /* Dereference it, leaving only the keep-alive */ ObDereferenceObject(Thread); From b5c8cf43e724aba1a2bcb09b96b2a8f0cd507e30 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 18:47:53 +0000 Subject: [PATCH 125/488] - Add ASSERT_MUTANT and ASSERT_SEMAPHORE to our DDK. - Cleanup mutex.c and sem.c. No real code changes, just add ASSERTs, STDCALL->NTAPI, IN/OUT decoration. - One change though, in KeReleaseMutant, use KeLeaveCriticalRegion instead of manually writing down the code, it's more readable this way. svn path=/trunk/; revision=24039 --- reactos/include/ddk/winddk.h | 6 ++++ reactos/ntoskrnl/ke/mutex.c | 68 ++++++++++++------------------------ reactos/ntoskrnl/ke/sem.c | 64 +++++++++++---------------------- 3 files changed, 48 insertions(+), 90 deletions(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index b97d6ab0664..f1c8c07e15e 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -1226,6 +1226,12 @@ typedef struct _KTIMER { ASSERT(((E)->Header.Type == TimerNotificationObject) || \ ((E)->Header.Type == TimerSynchronizationObject)) +#define ASSERT_MUTANT(E) \ + ASSERT((E)->Header.Type == MutantObject) + +#define ASSERT_SEMAPHORE(E) \ + ASSERT((E)->Header.Type == SemaphoreObject) + typedef struct _KMUTANT { DISPATCHER_HEADER Header; LIST_ENTRY MutantListEntry; diff --git a/reactos/ntoskrnl/ke/mutex.c b/reactos/ntoskrnl/ke/mutex.c index 2d7c248a6dd..f35ac4981c3 100644 --- a/reactos/ntoskrnl/ke/mutex.c +++ b/reactos/ntoskrnl/ke/mutex.c @@ -1,14 +1,9 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/mutex.c - * PURPOSE: Implements Mutexes and Mutants (that silly davec...) - * - * PROGRAMMERS: - * Alex Ionescu (alex@relsoft.net) - Reorganized/commented some of the code. - * Simplified some functions, fixed some return values and - * corrected some minor bugs, added debug output. - * David Welch (welch@mcmail.com) + * PURPOSE: Implements the Mutant Dispatcher Object + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES *****************************************************************/ @@ -23,16 +18,15 @@ * @implemented */ VOID -STDCALL +NTAPI KeInitializeMutant(IN PKMUTANT Mutant, IN BOOLEAN InitialOwner) { PKTHREAD CurrentThread; KIRQL OldIrql; - DPRINT("KeInitializeMutant: %x\n", Mutant); /* Check if we have an initial owner */ - if (InitialOwner == TRUE) + if (InitialOwner) { /* We also need to associate a thread */ CurrentThread = KeGetCurrentThread(); @@ -47,7 +41,6 @@ KeInitializeMutant(IN PKMUTANT Mutant, /* Release Dispatcher Lock */ KiReleaseDispatcherLock(OldIrql); - DPRINT("Mutant with Initial Owner\n"); } else { @@ -70,12 +63,10 @@ KeInitializeMutant(IN PKMUTANT Mutant, * @implemented */ VOID -STDCALL +NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level) { - DPRINT("KeInitializeMutex: %x\n", Mutex); - /* Set up the Dispatcher Header */ KeInitializeDispatcherHeader(&Mutex->Header, MutantObject, @@ -92,18 +83,18 @@ KeInitializeMutex(IN PKMUTEX Mutex, * @implemented */ LONG -STDCALL +NTAPI KeReadStateMutant(IN PKMUTANT Mutant) { /* Return the Signal State */ - return(Mutant->Header.SignalState); + return Mutant->Header.SignalState; } /* * @implemented */ LONG -STDCALL +NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, @@ -112,7 +103,9 @@ KeReleaseMutant(IN PKMUTANT Mutant, KIRQL OldIrql; LONG PreviousState; PKTHREAD CurrentThread = KeGetCurrentThread(); - DPRINT("KeReleaseMutant: %x\n", Mutant); + BOOLEAN EnableApc = FALSE; + ASSERT_MUTANT(Mutant); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock the Dispatcher Database */ OldIrql = KiAcquireDispatcherLock(); @@ -126,8 +119,6 @@ KeReleaseMutant(IN PKMUTANT Mutant, /* Make sure that the Owner Thread is the current Thread */ if (Mutant->OwnerThread != CurrentThread) { - DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n"); - /* Release the lock */ KiReleaseDispatcherLock(OldIrql); @@ -142,7 +133,6 @@ KeReleaseMutant(IN PKMUTANT Mutant, else { /* It's going to be abandonned */ - DPRINT("Abandonning the Mutant\n"); Mutant->Header.SignalState = 1; Mutant->Abandoned = TRUE; } @@ -154,43 +144,24 @@ KeReleaseMutant(IN PKMUTANT Mutant, if (PreviousState <= 0) { /* Remove the mutant from the list */ - DPRINT("Removing Mutant %p\n", Mutant); RemoveEntryList(&Mutant->MutantListEntry); - /* Reenable APCs */ - DPRINT("Re-enabling APCs\n"); - CurrentThread->KernelApcDisable += Mutant->ApcDisable; - - /* Check if the thread has APCs enabled */ - if (!CurrentThread->KernelApcDisable) - { - /* Check if any are pending */ - if (!IsListEmpty(&CurrentThread->ApcState.ApcListHead[KernelMode])) - { - /* Set Kernel APC Pending */ - CurrentThread->ApcState.KernelApcPending = TRUE; - - /* Request the Interrupt */ - DPRINT("Requesting APC Interupt\n"); - HalRequestSoftwareInterrupt(APC_LEVEL); - } - } + /* Save if we need to re-enable APCs */ + EnableApc = Mutant->ApcDisable; } /* Remove the Owning Thread and wake it */ Mutant->OwnerThread = NULL; /* Check if the Wait List isn't empty */ - DPRINT("Checking whether to wake the Mutant\n"); if (!IsListEmpty(&Mutant->Header.WaitListHead)) { /* Wake the Mutant */ - DPRINT("Waking the Mutant\n"); KiWaitTest(&Mutant->Header, Increment); } } - /* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */ + /* Check if the caller wants to wait after this release */ if (Wait == FALSE) { /* Release the Lock */ @@ -203,6 +174,9 @@ KeReleaseMutant(IN PKMUTANT Mutant, CurrentThread->WaitIrql = OldIrql; } + /* Check if we need to re-enable APCs */ + if (EnableApc) KeLeaveCriticalRegion(); + /* Return the previous state */ return PreviousState; } @@ -211,10 +185,12 @@ KeReleaseMutant(IN PKMUTANT Mutant, * @implemented */ LONG -STDCALL +NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait) { + ASSERT_MUTANT(Mutex); + /* There's no difference at this level between the two */ return KeReleaseMutant(Mutex, 1, FALSE, Wait); } diff --git a/reactos/ntoskrnl/ke/sem.c b/reactos/ntoskrnl/ke/sem.c index 92baf77daee..06d4118cbb1 100644 --- a/reactos/ntoskrnl/ke/sem.c +++ b/reactos/ntoskrnl/ke/sem.c @@ -1,10 +1,9 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/sem.c - * PURPOSE: Implements kernel semaphores - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * David Welch (welch@mcmail.com) + * PURPOSE: Implements the Semaphore Dispatcher Object + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES *****************************************************************/ @@ -19,13 +18,11 @@ * @implemented */ VOID -STDCALL -KeInitializeSemaphore(PKSEMAPHORE Semaphore, - LONG Count, - LONG Limit) +NTAPI +KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit) { - DPRINT("KeInitializeSemaphore Sem: %x\n", Semaphore); - /* Simply Initialize the Header */ KeInitializeDispatcherHeader(&Semaphore->Header, SemaphoreObject, @@ -40,51 +37,30 @@ KeInitializeSemaphore(PKSEMAPHORE Semaphore, * @implemented */ LONG -STDCALL -KeReadStateSemaphore(PKSEMAPHORE Semaphore) +NTAPI +KeReadStateSemaphore(IN PKSEMAPHORE Semaphore) { + ASSERT_SEMAPHORE(Semaphore); + /* Just return the Signal State */ return Semaphore->Header.SignalState; } /* * @implemented - * - * FUNCTION: KeReleaseSemaphore releases a given semaphore object. This - * routine supplies a runtime priority boost for waiting threads. If this - * call sets the semaphore to the Signaled state, the semaphore count is - * augmented by the given value. The caller can also specify whether it - * will call one of the KeWaitXXX routines as soon as KeReleaseSemaphore - * returns control. - * ARGUMENTS: - * Semaphore = Points to an initialized semaphore object for which the - * caller provides the storage. - * Increment = Specifies the priority increment to be applied if - * releasing the semaphore causes a wait to be - * satisfied. - * Adjustment = Specifies a value to be added to the current semaphore - * count. This value must be positive - * Wait = Specifies whether the call to KeReleaseSemaphore is to be - * followed immediately by a call to one of the KeWaitXXX. - * RETURNS: If the return value is zero, the previous state of the semaphore - * object is Not-Signaled. */ LONG -STDCALL -KeReleaseSemaphore(PKSEMAPHORE Semaphore, - KPRIORITY Increment, - LONG Adjustment, - BOOLEAN Wait) +NTAPI +KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, + IN KPRIORITY Increment, + IN LONG Adjustment, + IN BOOLEAN Wait) { LONG InitialState, State; KIRQL OldIrql; PKTHREAD CurrentThread; - - DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, Wait %d)\n", - Semaphore, - Increment, - Adjustment, - Wait); + ASSERT_SEMAPHORE(Semaphore); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock the Dispatcher Database */ OldIrql = KiAcquireDispatcherLock(); @@ -111,7 +87,7 @@ KeReleaseSemaphore(PKSEMAPHORE Semaphore, KiWaitTest(&Semaphore->Header, Increment); } - /* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */ + /* Check if the caller wants to wait after this release */ if (Wait == FALSE) { /* Release the Lock */ From ecb32725f75e651e3658199582539145fa54b66d Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 19:14:03 +0000 Subject: [PATCH 126/488] - Add ASSERT_EVENT. - Same changes to event.c as with the other files. - Remove lock property, these files have already been audited as clean and were unlocked. svn path=/trunk/; revision=24040 --- reactos/include/ddk/winddk.h | 4 + reactos/ntoskrnl/ke/event.c | 158 +++++++++++++++++------------------ reactos/ntoskrnl/ke/mutex.c | 2 +- reactos/ntoskrnl/ke/sem.c | 2 +- 4 files changed, 85 insertions(+), 81 deletions(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index f1c8c07e15e..119262d0315 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -1232,6 +1232,10 @@ typedef struct _KTIMER { #define ASSERT_SEMAPHORE(E) \ ASSERT((E)->Header.Type == SemaphoreObject) +#define ASSERT_EVENT(E) \ + ASSERT(((E)->Header.Type == NotificationEvent) || \ + ((E)->Header.Type == SynchronizationEvent)) + typedef struct _KMUTANT { DISPATCHER_HEADER Header; LIST_ENTRY MutantListEntry; diff --git a/reactos/ntoskrnl/ke/event.c b/reactos/ntoskrnl/ke/event.c index 1887e4e6313..e73f7e1cccf 100644 --- a/reactos/ntoskrnl/ke/event.c +++ b/reactos/ntoskrnl/ke/event.c @@ -1,30 +1,27 @@ /* - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/event.c - * PURPOSE: Implements events - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * David Welch (welch@mcmail.com) + * PURPOSE: Implements the Event Dispatcher Object + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG #include -/* FUNCTIONS ****************************************************************/ +/* FUNCTIONS *****************************************************************/ /* * @implemented */ VOID -STDCALL -KeClearEvent(PKEVENT Event) +NTAPI +KeClearEvent(IN PKEVENT Event) { - DPRINT("KeClearEvent(Event %x)\n", Event); + ASSERT_EVENT(Event); /* Reset Signal State */ Event->Header.SignalState = FALSE; @@ -34,13 +31,11 @@ KeClearEvent(PKEVENT Event) * @implemented */ VOID -STDCALL -KeInitializeEvent(PKEVENT Event, - EVENT_TYPE Type, - BOOLEAN State) +NTAPI +KeInitializeEvent(IN PKEVENT Event, + IN EVENT_TYPE Type, + IN BOOLEAN State) { - DPRINT("KeInitializeEvent(Event %x)\n", Event); - /* Initialize the Dispatcher Header */ KeInitializeDispatcherHeader(&Event->Header, Type, @@ -52,11 +47,9 @@ KeInitializeEvent(PKEVENT Event, * @implemented */ VOID -STDCALL -KeInitializeEventPair(PKEVENT_PAIR EventPair) +NTAPI +KeInitializeEventPair(IN PKEVENT_PAIR EventPair) { - DPRINT("KeInitializeEventPair(Event %x)\n", EventPair); - /* Initialize the Event Pair Type and Size */ EventPair->Type = EventPairObject; EventPair->Size = sizeof(KEVENT_PAIR); @@ -69,15 +62,17 @@ KeInitializeEventPair(PKEVENT_PAIR EventPair) /* * @implemented */ -LONG STDCALL +LONG +NTAPI KePulseEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait) { KIRQL OldIrql; LONG PreviousState; - - DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait); + PKTHREAD Thread; + ASSERT_EVENT(Event); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock the Dispatcher Database */ OldIrql = KiAcquireDispatcherLock(); @@ -86,8 +81,8 @@ KePulseEvent(IN PKEVENT Event, PreviousState = Event->Header.SignalState; /* Check if we are non-signaled and we have stuff in the Wait Queue */ - if (!PreviousState && !IsListEmpty(&Event->Header.WaitListHead)) { - + if (!PreviousState && !IsListEmpty(&Event->Header.WaitListHead)) + { /* Set the Event to Signaled */ Event->Header.SignalState = 1; @@ -99,15 +94,15 @@ KePulseEvent(IN PKEVENT Event, Event->Header.SignalState = 0; /* Check what wait state was requested */ - if (Wait == FALSE) { - + if (Wait == FALSE) + { /* Wait not requested, release Dispatcher Database and return */ KiReleaseDispatcherLock(OldIrql); - - } else { - + } + else + { /* Return Locked and with a Wait */ - KTHREAD *Thread = KeGetCurrentThread(); + Thread = KeGetCurrentThread(); Thread->WaitNext = TRUE; Thread->WaitIrql = OldIrql; } @@ -120,9 +115,11 @@ KePulseEvent(IN PKEVENT Event, * @implemented */ LONG -STDCALL -KeReadStateEvent(PKEVENT Event) +NTAPI +KeReadStateEvent(IN PKEVENT Event) { + ASSERT_EVENT(Event); + /* Return the Signal State */ return Event->Header.SignalState; } @@ -131,13 +128,13 @@ KeReadStateEvent(PKEVENT Event) * @implemented */ LONG -STDCALL -KeResetEvent(PKEVENT Event) +NTAPI +KeResetEvent(IN PKEVENT Event) { KIRQL OldIrql; LONG PreviousState; - - DPRINT("KeResetEvent(Event %x)\n",Event); + ASSERT_EVENT(Event); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock the Dispatcher Database */ OldIrql = KiAcquireDispatcherLock(); @@ -157,16 +154,17 @@ KeResetEvent(PKEVENT Event) * @implemented */ LONG -STDCALL -KeSetEvent(PKEVENT Event, - KPRIORITY Increment, - BOOLEAN Wait) +NTAPI +KeSetEvent(IN PKEVENT Event, + IN KPRIORITY Increment, + IN BOOLEAN Wait) { KIRQL OldIrql; LONG PreviousState; PKWAIT_BLOCK WaitBlock; - - DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait); + PKTHREAD Thread; + ASSERT_EVENT(Event); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock the Dispathcer Database */ OldIrql = KiAcquireDispatcherLock(); @@ -175,55 +173,53 @@ KeSetEvent(PKEVENT Event, PreviousState = Event->Header.SignalState; /* Check if we have stuff in the Wait Queue */ - if (IsListEmpty(&Event->Header.WaitListHead)) { - + if (IsListEmpty(&Event->Header.WaitListHead)) + { /* Set the Event to Signaled */ - DPRINT("Empty Wait Queue, Signal the Event\n"); Event->Header.SignalState = 1; - - } else { - + } + else + { /* Get the Wait Block */ WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink, KWAIT_BLOCK, WaitListEntry); - /* Check the type of event */ - if (Event->Header.Type == NotificationEvent || WaitBlock->WaitType == WaitAll) { - - if (PreviousState == 0) { - + if ((Event->Header.Type == NotificationEvent) || (WaitBlock->WaitType == WaitAll)) + { + /* Check if it wasn't signaled */ + if (!PreviousState) + { /* We must do a full wait satisfaction */ - DPRINT("Notification Event or WaitAll, Wait on the Event and Signal\n"); Event->Header.SignalState = 1; KiWaitTest(&Event->Header, Increment); } - - } else { - - /* We can satisfy wait simply by waking the thread, since our signal state is 0 now */ - DPRINT("WaitAny or Sync Event, just unwait the thread\n"); - KiAbortWaitThread(WaitBlock->Thread, WaitBlock->WaitKey, Increment); + } + else + { + /* We can satisfy wait simply by waking the thread */ + KiAbortWaitThread(WaitBlock->Thread, + WaitBlock->WaitKey, + Increment); } } /* Check what wait state was requested */ - if (Wait == FALSE) { - + if (!Wait) + { /* Wait not requested, release Dispatcher Database and return */ KiReleaseDispatcherLock(OldIrql); - - } else { - + } + else + { /* Return Locked and with a Wait */ - KTHREAD *Thread = KeGetCurrentThread(); + Thread = KeGetCurrentThread(); Thread->WaitNext = TRUE; Thread->WaitIrql = OldIrql; } /* Return the previous State */ - DPRINT("Done: %d\n", PreviousState); return PreviousState; } @@ -231,32 +227,36 @@ KeSetEvent(PKEVENT Event, * @implemented */ VOID -STDCALL +NTAPI KeSetEventBoostPriority(IN PKEVENT Event, IN PKTHREAD *Thread OPTIONAL) { PKTHREAD WaitingThread; KIRQL OldIrql; + ASSERT_EVENT(Event); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT("KeSetEventBoostPriority(Event %x, Thread %x)\n",Event,Thread); + // + // FIXME: This is half-broken, there's no boosting! + // /* Acquire Dispatcher Database Lock */ OldIrql = KiAcquireDispatcherLock(); /* If our wait list is empty, then signal the event and return */ - if (IsListEmpty(&Event->Header.WaitListHead)) { - + if (IsListEmpty(&Event->Header.WaitListHead)) + { Event->Header.SignalState = 1; - - } else { - - /* Get Thread that is currently waiting. First get the Wait Block, then the Thread */ + } + else + { + /* Get the waiting thread */ WaitingThread = CONTAINING_RECORD(Event->Header.WaitListHead.Flink, KWAIT_BLOCK, WaitListEntry)->Thread; /* Return it to caller if requested */ - if ARGUMENT_PRESENT(Thread) *Thread = WaitingThread; + if (Thread) *Thread = WaitingThread; /* Reset the Quantum and Unwait the Thread */ WaitingThread->Quantum = WaitingThread->QuantumReset; diff --git a/reactos/ntoskrnl/ke/mutex.c b/reactos/ntoskrnl/ke/mutex.c index f35ac4981c3..18836750267 100644 --- a/reactos/ntoskrnl/ke/mutex.c +++ b/reactos/ntoskrnl/ke/mutex.c @@ -6,7 +6,7 @@ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG diff --git a/reactos/ntoskrnl/ke/sem.c b/reactos/ntoskrnl/ke/sem.c index 06d4118cbb1..918dd1c2f51 100644 --- a/reactos/ntoskrnl/ke/sem.c +++ b/reactos/ntoskrnl/ke/sem.c @@ -6,7 +6,7 @@ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG From 344fd0845274d30e84ab6b9822a80ace6b9d4c75 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 19:41:31 +0000 Subject: [PATCH 127/488] - No need to apply the ROS Page hack inside thread switching, since the process is the same. svn path=/trunk/; revision=24041 --- reactos/ntoskrnl/ke/thrdobj.c | 6 ------ reactos/ntoskrnl/ke/thrdschd.c | 2 -- 2 files changed, 8 deletions(-) diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index b948f835e82..b3193c3bfcc 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -697,12 +697,6 @@ KeInitThread(IN OUT PKTHREAD Thread, Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE; Thread->KernelStackResident = TRUE; - /* ROS Mm HACK */ - MmUpdatePageDir((PEPROCESS)Process, - (PVOID)Thread->StackLimit, - KERNEL_STACK_SIZE); - MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); - /* Enter SEH to avoid crashes due to user mode */ Status = STATUS_SUCCESS; _SEH_TRY diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c index dad5c83c546..22679d26bdd 100644 --- a/reactos/ntoskrnl/ke/thrdschd.c +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -150,8 +150,6 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus) KiIdleSummary |= Affinity; } - MmUpdatePageDir((PEPROCESS)PsGetCurrentProcess(),((PETHREAD)CurrentThread)->ThreadsProcess, sizeof(EPROCESS)); - /* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */ DPRINT("You are : %x, swapping to: %x.\n", OldThread, CurrentThread); ApcState = KiSwapContext(OldThread, CurrentThread); From 6a37552f9ef43660d00451f5fefaf10a00597b67 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Sun, 10 Sep 2006 19:42:09 +0000 Subject: [PATCH 128/488] implement NtGdiPathToRegion svn path=/trunk/; revision=24042 --- .../subsystems/win32/win32k/objects/path.c | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/path.c b/reactos/subsystems/win32/win32k/objects/path.c index fe7b3150708..40f08085ec9 100644 --- a/reactos/subsystems/win32/win32k/objects/path.c +++ b/reactos/subsystems/win32/win32k/objects/path.c @@ -252,8 +252,31 @@ HRGN STDCALL NtGdiPathToRegion(HDC hDC) { - UNIMPLEMENTED; - return 0; + GdiPath *pPath; + HRGN hrgnRval = 0; + DC *pDc; + + DPRINT("Enter %s\n", __FUNCTION__); + + pDc = DC_LockDc(hDC); + if(!pDc) return NULL; + + pPath = &pDc->w.path; + + if(pPath->state!=PATH_Closed) + { + //FIXME: check that setlasterror is being called correctly + SetLastWin32Error(ERROR_CAN_NOT_COMPLETE); + } + else + { + /* FIXME: Should we empty the path even if conversion failed? */ + if(PATH_PathToRegion(pPath, pDc->w.polyFillMode, &hrgnRval)) + PATH_EmptyPath(pPath); + } + + DC_UnlockDc(pDc); + return hrgnRval; } BOOL From 54a6548aa78067c1e9fcc2305b1e976ff95349c0 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 10 Sep 2006 20:12:16 +0000 Subject: [PATCH 129/488] Fix inconsistent formatting and other trails of GreatLord's fixing svn path=/trunk/; revision=24043 --- rosapps/cmdutils/mode/mode.rbuild | 2 +- rosapps/cmdutils/touch/touch.rbuild | 2 +- rosapps/demos/ddraw/ddraw.rbuild | 5 +---- rosapps/demos/maze/maze.rbuild | 2 +- rosapps/devutils/gdb2/gdb2.rbuild | 4 ++-- rosapps/mc/mc.rbuild | 2 +- rosapps/mc/slang/slw32tty.c | 5 ++--- rosapps/mc/src/cmd.c | 2 +- rosapps/tests/multithrdwin/multithrdwin.rbuild | 2 +- rosapps/tests/noexecute/noexecute.rbuild | 2 +- 10 files changed, 12 insertions(+), 16 deletions(-) diff --git a/rosapps/cmdutils/mode/mode.rbuild b/rosapps/cmdutils/mode/mode.rbuild index 98a338cd251..6f993663cbe 100644 --- a/rosapps/cmdutils/mode/mode.rbuild +++ b/rosapps/cmdutils/mode/mode.rbuild @@ -5,7 +5,7 @@ 0x0501 0x0501 kernel32 - shell32 + shell32 user32 mode.c mode.rc diff --git a/rosapps/cmdutils/touch/touch.rbuild b/rosapps/cmdutils/touch/touch.rbuild index 4642de716da..19547086564 100644 --- a/rosapps/cmdutils/touch/touch.rbuild +++ b/rosapps/cmdutils/touch/touch.rbuild @@ -4,7 +4,7 @@ 0x0501 0x0501 ntdll - kernel32 + kernel32 err.c touch.c touch.rc diff --git a/rosapps/demos/ddraw/ddraw.rbuild b/rosapps/demos/ddraw/ddraw.rbuild index 8c6dce419da..ec8380f2c31 100644 --- a/rosapps/demos/ddraw/ddraw.rbuild +++ b/rosapps/demos/ddraw/ddraw.rbuild @@ -2,14 +2,11 @@ 0x0501 0x0501 - kernel32 gdi32 ddraw dxguid string - user32 - - + user32 main.cpp \ No newline at end of file diff --git a/rosapps/demos/maze/maze.rbuild b/rosapps/demos/maze/maze.rbuild index 193927eca29..f7936e9b618 100644 --- a/rosapps/demos/maze/maze.rbuild +++ b/rosapps/demos/maze/maze.rbuild @@ -4,7 +4,7 @@ kernel32 gdi32 - user32 + user32 maze.c maze.rc diff --git a/rosapps/devutils/gdb2/gdb2.rbuild b/rosapps/devutils/gdb2/gdb2.rbuild index deff43c1926..7731f5ea632 100644 --- a/rosapps/devutils/gdb2/gdb2.rbuild +++ b/rosapps/devutils/gdb2/gdb2.rbuild @@ -3,7 +3,7 @@ 0x0501 0x0501 - kernel32 - user32 + kernel32 + user32 gdb2.cpp \ No newline at end of file diff --git a/rosapps/mc/mc.rbuild b/rosapps/mc/mc.rbuild index 7fae4abbf8d..873c8316ede 100644 --- a/rosapps/mc/mc.rbuild +++ b/rosapps/mc/mc.rbuild @@ -9,7 +9,7 @@ kernel32 user32 - advapi32 + advapi32 terms.c diff --git a/rosapps/mc/slang/slw32tty.c b/rosapps/mc/slang/slw32tty.c index 2cc3538388b..4e4efcadf10 100644 --- a/rosapps/mc/slang/slw32tty.c +++ b/rosapps/mc/slang/slw32tty.c @@ -130,7 +130,7 @@ void SLang_reset_tty (void) \*----------------------------------------------------------------------*/ int SLsys_input_pending (int tsecs) { - INPUT_RECORD record; + INPUT_RECORD record; DWORD bytesRead; while (1) @@ -192,8 +192,7 @@ int SLsys_input_pending (int tsecs) * extended keys are prefixed by a null character \*----------------------------------------------------------------------*/ unsigned int SLsys_getkey (void) -{ - // long key; +{ DWORD bytesRead; INPUT_RECORD record; diff --git a/rosapps/mc/src/cmd.c b/rosapps/mc/src/cmd.c index a3f529af2ae..3e1603fda6f 100644 --- a/rosapps/mc/src/cmd.c +++ b/rosapps/mc/src/cmd.c @@ -721,7 +721,7 @@ void reselect_vfs (void) static int compare_files (char *name1, char *name2, long size) { - int file1, file2; + int file1, file2; int result = -1; /* Different by default */ file1 = open (name1, O_RDONLY); diff --git a/rosapps/tests/multithrdwin/multithrdwin.rbuild b/rosapps/tests/multithrdwin/multithrdwin.rbuild index d404e70f89d..91d237c181b 100644 --- a/rosapps/tests/multithrdwin/multithrdwin.rbuild +++ b/rosapps/tests/multithrdwin/multithrdwin.rbuild @@ -5,7 +5,7 @@ kernel32 user32 gdi32 - ntdll + ntdll multithrdwin.c diff --git a/rosapps/tests/noexecute/noexecute.rbuild b/rosapps/tests/noexecute/noexecute.rbuild index afed6b3e6dc..15062c6a1e5 100644 --- a/rosapps/tests/noexecute/noexecute.rbuild +++ b/rosapps/tests/noexecute/noexecute.rbuild @@ -4,7 +4,7 @@ pseh kernel32 - user32 + user32 noexecute.c From faa5f58b848d5768cb595bd3534a27cfc19a192d Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 20:23:02 +0000 Subject: [PATCH 130/488] - Remove KeGetCurrentProcess. This API doesn't exist. - Add assertions to relevant functions in process.c and re-format some code. - Check for invalid APC state in KeDetachProcess. - Decrease process stack count while holding the Dispatcher Lock at DPC level. - Implement KiSwapProcess in ctxswitch.S and add SMP-support and LDT swap support for the future, as well as updating the IOPM base in the TSS. svn path=/trunk/; revision=24044 --- reactos/ntoskrnl/ke/apc.c | 2 +- reactos/ntoskrnl/ke/i386/ctxswitch.S | 58 +++++++++++++++++ reactos/ntoskrnl/ke/i386/ldt.c | 2 +- reactos/ntoskrnl/ke/process.c | 96 ++++++++++++++++++---------- reactos/ntoskrnl/mm/i386/pfault.c | 2 +- reactos/ntoskrnl/ntoskrnl.def | 2 +- 6 files changed, 126 insertions(+), 36 deletions(-) diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index da66359f99c..675a6d41ba4 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -658,7 +658,7 @@ KiDeliverApc(KPROCESSOR_MODE DeliveryMode, PKTRAP_FRAME TrapFrame) { PKTHREAD Thread = KeGetCurrentThread(); - PKPROCESS Process = KeGetCurrentProcess(); + PKPROCESS Process = Thread->ApcState.Process; PKTRAP_FRAME OldTrapFrame; PLIST_ENTRY ApcListEntry; PKAPC Apc; diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 7ec6cb62b7a..b76e4d3689d 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -546,3 +546,61 @@ _Ki386AdjustEsp0@4: popf ret 4 .endfunc + +.globl _KiSwapProcess@8 +.func KiSwapProcess@8 +_KiSwapProcess@8: + + /* Get process pointers */ + mov edx, [esp+4] + mov eax, [esp+8] + +#ifdef CONFIG_SMP + /* Update active processors */ + mov ecx, fs:[KPCR_SET_MEMBER] + lock xor [edx+KPROCESS_ACTIVE_PROCESSORS], ecx + lock xor [eax+KPROCESS_ACTIVE_PROCESSORS], ecx + + /* Sanity check */ +#ifdef DBG + test dword ptr [edx+KPROCESS_ACTIVE_PROCESSORS], 0 + jz WrongCpu1 + test dword ptr [eax+KPROCESS_ACTIVE_PROCESSORS], 0 + jnz WrongCpu2 +#endif +#endif + + /* Check if their LDTs changed */ + mov ecx, [edx+KPROCESS_LDT_DESCRIPTOR0] + or ecx, [eax+KPROCESS_LDT_DESCRIPTOR0] + jnz NewLdt + + /* Update CR3 */ + mov eax, [edx+KPROCESS_DIRECTORY_TABLE_BASE] + mov cr3, eax + + /* Get the KTSS */ + mov ecx, fs:[KPCR_TSS] + + /* Clear GS on process swap */ + xor eax, eax + mov gs, ax + + /* Update IOPM offset */ + mov ax, [edx+KPROCESS_IOPM_OFFSET] + mov [ecx+KTSS_IOMAPBASE], ax + + /* Return */ + ret 8 + +NewLdt: + /* FIXME: TODO */ + int 3 + +#ifdef DBG +WrongCpu1: + int 3 +WrongCpu2: + int 3 +#endif +.endfunc diff --git a/reactos/ntoskrnl/ke/i386/ldt.c b/reactos/ntoskrnl/ke/i386/ldt.c index 1e1efc4a9ef..67446e77ba3 100644 --- a/reactos/ntoskrnl/ke/i386/ldt.c +++ b/reactos/ntoskrnl/ke/i386/ldt.c @@ -157,7 +157,7 @@ NtSetLdtEntries (ULONG Selector1, KeAcquireSpinLock(&LdtLock, &oldIrql); - LdtDescriptor = (PUSHORT) &KeGetCurrentProcess()->LdtDescriptor; + LdtDescriptor = (PUSHORT) &PsGetCurrentProcess()->Pcb.LdtDescriptor; LdtBase = LdtDescriptor[1] | ((LdtDescriptor[2] & 0xff) << 16) | ((LdtDescriptor[3] & ~0xff) << 16); diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index cd30899c03c..4ce27d24b54 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -1,13 +1,13 @@ /* - * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/process.c * PURPOSE: Kernel Process Management and System Call Tables * PROGRAMMERS: Alex Ionescu * Gregor Anich */ -/* INCLUDES ********(*********************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG @@ -28,16 +28,9 @@ PVOID KeUserCallbackDispatcher; PVOID KeUserExceptionDispatcher; PVOID KeRaiseUserExceptionDispatcher; -/* FUNCTIONS *****************************************************************/ +/* PRIVATE FUNCTIONS *********************************************************/ -PKPROCESS -STDCALL -KeGetCurrentProcess(VOID) -{ - return(&(PsGetCurrentProcess()->Pcb)); -} - -static __inline +FORCEINLINE VOID NTAPI UpdatePageDirs(IN PKTHREAD Thread, @@ -65,10 +58,9 @@ KiAttachProcess(PKTHREAD Thread, PRKAPC_STATE SavedApcState) { ASSERT(Process != Thread->ApcState.Process); - DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", - Thread, Process, SavedApcState); /* Increase Stack Count */ + ASSERT(Process->StackCount != MAXULONG_PTR); Process->StackCount++; /* Swap the APC Environment */ @@ -85,7 +77,8 @@ KiAttachProcess(PKTHREAD Thread, /* Update Environment Pointers if needed*/ if (SavedApcState == &Thread->SavedApcState) { - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState; + Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread-> + SavedApcState; Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState; Thread->ApcStateIndex = AttachedApcEnvironment; } @@ -107,7 +100,7 @@ KiAttachProcess(PKTHREAD Thread, else { DPRINT1("Errr. ReactOS doesn't support paging out processes yet...\n"); - DbgBreakPoint(); + ASSERT(FALSE); } } @@ -190,6 +183,8 @@ KeSetProcess(PKPROCESS Process, { KIRQL OldIrql; ULONG OldState; + ASSERT_PROCESS(Process); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Lock Dispatcher */ OldIrql = KiAcquireDispatcherLock(); @@ -199,7 +194,10 @@ KeSetProcess(PKPROCESS Process, /* Signal the Process */ Process->Header.SignalState = TRUE; - if ((OldState == 0) && IsListEmpty(&Process->Header.WaitListHead) != TRUE) + + /* Check if was unsignaled and has waiters */ + if (!(OldState) && + !(IsListEmpty(&Process->Header.WaitListHead))) { /* Satisfy waits */ KiWaitTest((PVOID)Process, Increment); @@ -212,15 +210,6 @@ KeSetProcess(PKPROCESS Process, return OldState; } -VOID -NTAPI -KiSwapProcess(PKPROCESS NewProcess, - PKPROCESS OldProcess) -{ - DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart); - Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart); -} - VOID NTAPI KeSetQuantumProcess(IN PKPROCESS Process, @@ -419,6 +408,8 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, return OldPriority; } +/* PUBLIC FUNCTIONS **********************************************************/ + /* * @implemented */ @@ -464,12 +455,12 @@ KeAttachProcess(PKPROCESS Process) */ VOID NTAPI -KeDetachProcess (VOID) +KeDetachProcess(VOID) { PKTHREAD Thread = KeGetCurrentThread(); KLOCK_QUEUE_HANDLE ApcLock; + PKPROCESS Process; ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT("KeDetachProcess()\n"); /* Check if it's attached */ if (Thread->ApcStateIndex == OriginalApcEnvironment) return; @@ -477,12 +468,35 @@ KeDetachProcess (VOID) /* Acquire APC Lock */ KiAcquireApcLock(Thread, &ApcLock); - /* It is, decrease Stack Count */ - if(!(--Thread->ApcState.Process->StackCount)) + /* Check for invalid attach attempts */ + if ((Thread->ApcState.KernelApcInProgress) || + !(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) || + !(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) + { + /* Crash the system */ + KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT); + } + + /* Get the process */ + Process = Thread->ApcState.Process; + + /* Acquire dispatcher lock */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Decrease the stack count */ + ASSERT(Process->StackCount != 0); + ASSERT(Process->State == ProcessInMemory); + Process->StackCount--; + + /* Check if we can swap the process out */ + if (!Process->StackCount) { /* FIXME: Swap the process out */ } + /* Release dispatcher lock */ + KiReleaseDispatcherLockFromDpcLevel(); + /* Restore the APC State */ KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); Thread->SavedApcState.Process = NULL; @@ -529,6 +543,7 @@ KeStackAttachProcess(IN PKPROCESS Process, { KLOCK_QUEUE_HANDLE ApcLock; PKTHREAD Thread = KeGetCurrentThread(); + ASSERT_PROCESS(Process); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Make sure that we are in the right page directory */ @@ -579,6 +594,7 @@ KeUnstackDetachProcess(IN PRKAPC_STATE ApcState) { KLOCK_QUEUE_HANDLE ApcLock; PKTHREAD Thread = KeGetCurrentThread(); + PKPROCESS Process; ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Check for magic value meaning we were already in the same process */ @@ -596,16 +612,32 @@ KeUnstackDetachProcess(IN PRKAPC_STATE ApcState) (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) || (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) { + /* Bugcheck the system */ KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT); } - /* Decrease Stack Count */ - if(!(--Thread->ApcState.Process->StackCount)) + /* Get the process */ + Process = Thread->ApcState.Process; + + /* Acquire dispatcher lock */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Decrease the stack count */ + ASSERT(Process->StackCount != 0); + ASSERT(Process->State == ProcessInMemory); + Process->StackCount--; + + /* Check if we can swap the process out */ + if (!Process->StackCount) { /* FIXME: Swap the process out */ } - if (ApcState->Process != NULL) + /* Release dispatcher lock */ + KiReleaseDispatcherLockFromDpcLevel(); + + /* Check if there's an APC state to restore */ + if (ApcState->Process) { /* Restore the APC State */ KiMoveApcState(ApcState, &Thread->ApcState); diff --git a/reactos/ntoskrnl/mm/i386/pfault.c b/reactos/ntoskrnl/mm/i386/pfault.c index 0a94556cc63..96adea4e5a0 100644 --- a/reactos/ntoskrnl/mm/i386/pfault.c +++ b/reactos/ntoskrnl/mm/i386/pfault.c @@ -79,7 +79,7 @@ ULONG KiPageFaultHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) if (!NT_SUCCESS(Status)) { /* FIXME: This should use ->VdmObjects */ - if(!KeGetCurrentProcess()->Unused) + if(!PsGetCurrentProcess()->Pcb.Unused) { *((PKV86M_TRAP_FRAME)Tf)->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; } diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 04ba96f7b54..51a843c927b 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -891,7 +891,7 @@ PsDereferencePrimaryToken@4 PsDisableImpersonation@8 PsEstablishWin32Callouts@4 PsGetContextThread@12 -PsGetCurrentProcess@0=KeGetCurrentProcess@0 +PsGetCurrentProcess@0=IoGetCurrentProcess@0 PsGetCurrentProcessId@0 PsGetCurrentProcessWin32Process@0 PsGetCurrentProcessSessionId@0 From 5e7a9fc74e76a3659f91cdd248dafef179f3d724 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 10 Sep 2006 21:32:02 +0000 Subject: [PATCH 131/488] Create a place for some R&D work about booting Windows from inside of FreeLdr svn path=/trunk/; revision=24046 --- reactos/boot/freeldr/freeldr/bootmgr.c | 16 +++++++++ .../boot/freeldr/freeldr/freeldr_base.rbuild | 3 ++ .../boot/freeldr/freeldr/include/freeldr.h | 1 + reactos/boot/freeldr/freeldr/windows/winldr.c | 36 +++++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 reactos/boot/freeldr/freeldr/windows/winldr.c diff --git a/reactos/boot/freeldr/freeldr/bootmgr.c b/reactos/boot/freeldr/freeldr/bootmgr.c index ac2585b5e92..470c6775859 100644 --- a/reactos/boot/freeldr/freeldr/bootmgr.c +++ b/reactos/boot/freeldr/freeldr/bootmgr.c @@ -124,6 +124,22 @@ NoGui: { LoadAndBootReactOS(OperatingSystemSectionNames[SelectedOperatingSystem]); } + else if (_stricmp(SettingValue, "WindowsNT40") == 0) + { + LoadAndBootWindows(OperatingSystemSectionNames[SelectedOperatingSystem], _WIN32_WINNT_NT4); + } + else if (_stricmp(SettingValue, "Windows2000") == 0) + { + LoadAndBootWindows(OperatingSystemSectionNames[SelectedOperatingSystem], _WIN32_WINNT_WIN2K); + } + else if (_stricmp(SettingValue, "WindowsXP") == 0) + { + LoadAndBootWindows(OperatingSystemSectionNames[SelectedOperatingSystem], _WIN32_WINNT_WINXP); + } + else if (_stricmp(SettingValue, "Windows2003") == 0) + { + LoadAndBootWindows(OperatingSystemSectionNames[SelectedOperatingSystem], _WIN32_WINNT_WS03); + } else if (_stricmp(SettingValue, "Linux") == 0) { LoadAndBootLinux(OperatingSystemSectionNames[SelectedOperatingSystem], OperatingSystemDisplayNames[SelectedOperatingSystem]); diff --git a/reactos/boot/freeldr/freeldr/freeldr_base.rbuild b/reactos/boot/freeldr/freeldr/freeldr_base.rbuild index 0268e100606..15094f34202 100644 --- a/reactos/boot/freeldr/freeldr/freeldr_base.rbuild +++ b/reactos/boot/freeldr/freeldr/freeldr_base.rbuild @@ -66,6 +66,9 @@ pixel.c video.c + + winldr.c + freeldr.c debug.c version.c diff --git a/reactos/boot/freeldr/freeldr/include/freeldr.h b/reactos/boot/freeldr/freeldr/include/freeldr.h index e72edd71587..5aa3e5cbc6c 100644 --- a/reactos/boot/freeldr/freeldr/include/freeldr.h +++ b/reactos/boot/freeldr/freeldr/include/freeldr.h @@ -45,6 +45,7 @@ #include #include #include +#include #include /* file system headers */ #include diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c new file mode 100644 index 00000000000..6f20403b21f --- /dev/null +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -0,0 +1,36 @@ +/* + * FreeLoader + * + * Copyright (C) 1998-2003 Brian Palmer + * Copyright (C) 2006 Aleksey Bragin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#define NDEBUG +#include + +VOID +LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) +{ + CHAR MsgBuffer[256]; + + sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion); + UiMessageBox(MsgBuffer); + + return; +} From d7ae142cf1c73ba0b7095c4c5dfd3fa4cacc57c6 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 23:17:22 +0000 Subject: [PATCH 132/488] - KPROCSES Flags are LONG, not ULONG. - Add some missing decoration. - NUMA node semantics for KeInitializeProcess are only required on SMP builds. - Allow KeInitailizeProcess to receive an argument specifying if alignment faults should be enabled or not. - Use KiComputeIopmOffset to get the IopmOFfset instead of setting -1 svn path=/trunk/; revision=24047 --- reactos/include/ndk/ketypes.h | 14 ++++++------- reactos/ntoskrnl/include/internal/ke.h | 3 ++- reactos/ntoskrnl/ke/i386/kiinit.c | 3 ++- reactos/ntoskrnl/ke/process.c | 27 +++++++++++++++----------- reactos/ntoskrnl/ps/process.c | 3 ++- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index f6893df052a..982b8955715 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -905,7 +905,7 @@ typedef struct _KPROCESS { DISPATCHER_HEADER Header; LIST_ENTRY ProfileListHead; - PHYSICAL_ADDRESS DirectoryTableBase; + LARGE_INTEGER DirectoryTableBase; #if defined(_M_IX86) KGDTENTRY LdtDescriptor; KIDTENTRY Int21Descriptor; @@ -926,12 +926,12 @@ typedef struct _KPROCESS { struct { - ULONG AutoAlignment:1; - ULONG DisableBoost:1; - ULONG DisableQuantum:1; - ULONG ReservedFlags:29; + LONG AutoAlignment:1; + LONG DisableBoost:1; + LONG DisableQuantum:1; + LONG ReservedFlags:29; }; - ULONG ProcessFlags; + LONG ProcessFlags; }; SCHAR BasePriority; SCHAR QuantumReset; @@ -943,9 +943,7 @@ typedef struct _KPROCESS union { KEXECUTE_OPTIONS Flags; -#if (NTDDI_VERSION >= NTDDI_LONGHORN) UCHAR ExecuteOptions; -#endif }; ULONG StackCount; LIST_ENTRY ProcessListEntry; diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index d1689129ec1..98a0ea3b885 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -505,7 +505,8 @@ KeInitializeProcess( struct _KPROCESS *Process, KPRIORITY Priority, KAFFINITY Affinity, - LARGE_INTEGER DirectoryTableBase + PLARGE_INTEGER DirectoryTableBase, + IN BOOLEAN Enable ); VOID diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index fc7d9f54772..ddb73613a52 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -147,7 +147,8 @@ KiInitializeKernel(IN PKPROCESS InitProcess, KeInitializeProcess(InitProcess, 0, 0xFFFFFFFF, - PageDirectory); + &PageDirectory, + FALSE); InitProcess->QuantumReset = MAXCHAR; } else diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index 4ce27d24b54..b89b01386d3 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -52,10 +52,10 @@ UpdatePageDirs(IN PKTHREAD Thread, VOID NTAPI -KiAttachProcess(PKTHREAD Thread, - PKPROCESS Process, - PKLOCK_QUEUE_HANDLE ApcLock, - PRKAPC_STATE SavedApcState) +KiAttachProcess(IN PKTHREAD Thread, + IN PKPROCESS Process, + IN PKLOCK_QUEUE_HANDLE ApcLock, + IN PRKAPC_STATE SavedApcState) { ASSERT(Process != Thread->ApcState.Process); @@ -109,11 +109,14 @@ NTAPI KeInitializeProcess(IN OUT PKPROCESS Process, IN KPRIORITY Priority, IN KAFFINITY Affinity, - IN LARGE_INTEGER DirectoryTableBase) + IN PLARGE_INTEGER DirectoryTableBase, + IN BOOLEAN Enable) { +#ifdef CONFIG_SMP ULONG i = 0; UCHAR IdealNode = 0; PKNODE Node; +#endif /* Initialize the Dispatcher Header */ KeInitializeDispatcherHeader(&Process->Header, @@ -125,9 +128,9 @@ KeInitializeProcess(IN OUT PKPROCESS Process, Process->Affinity = Affinity; Process->BasePriority = (CHAR)Priority; Process->QuantumReset = 6; - Process->DirectoryTableBase = DirectoryTableBase; - Process->AutoAlignment = TRUE; - Process->IopmOffset = 0xFFFF; + Process->DirectoryTableBase = *DirectoryTableBase; + Process->AutoAlignment = Enable; + Process->IopmOffset = KiComputeIopmOffset(IO_ACCESS_MAP_NONE); /* Initialize the lists */ InitializeListHead(&Process->ThreadListHead); @@ -138,6 +141,7 @@ KeInitializeProcess(IN OUT PKPROCESS Process, Process->State = ProcessInMemory; /* Check how many Nodes there are on the system */ +#ifdef CONFIG_SMP if (KeNumberNodes > 1) { /* Set the new seed */ @@ -173,13 +177,14 @@ KeInitializeProcess(IN OUT PKPROCESS Process, Process->ThreadSeed = KeFindNextRightSetAffinity(Node->Seed, (ULONG)Affinity); Node->Seed = Process->ThreadSeed; +#endif } ULONG NTAPI -KeSetProcess(PKPROCESS Process, - KPRIORITY Increment, - BOOLEAN InWait) +KeSetProcess(IN PKPROCESS Process, + IN KPRIORITY Increment, + IN BOOLEAN InWait) { KIRQL OldIrql; ULONG OldState; diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index de76e161090..6efff9ab6d1 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -582,7 +582,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, KeInitializeProcess(&Process->Pcb, PROCESS_PRIORITY_NORMAL, Affinity, - DirectoryTableBase); + &DirectoryTableBase, + Process->DefaultHardErrorProcessing & 4); /* Duplicate Parent Token */ Status = PspInitializeProcessSecurity(Process, Parent); From 38759195cb62d3e4552123148bbceeac33fae6c2 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 23:41:08 +0000 Subject: [PATCH 133/488] - We only need to update the page directory for the current stack, not the whole ETHREAD. (the page fault will be handled). - Release dispatcher lock from DPC level in KiAttachProcess. - Add missing decoration/assert to KeAttachProcess, and only acquire APC lock after we've made the invalid attach test. Also acquire dispatcher lock at DPC level here and in KeStackAttachProcess. - Loop in KeUnStachDetachProcess to avoid the case where we acquired the APC lock while a kernel APC was pending. Keep releaing the loop and re-attemping acquire until it has been delivered. - Add Decoration for *ServiceTable* functions. svn path=/trunk/; revision=24048 --- reactos/ntoskrnl/ke/process.c | 66 ++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index b89b01386d3..b8ab303e8c5 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -46,8 +46,9 @@ UpdatePageDirs(IN PKTHREAD Thread, * To prevent this, make sure the page directory of the process we're * attaching to is up-to-date. */ - MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, KERNEL_STACK_SIZE); - MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); + MmUpdatePageDir((PEPROCESS)Process, + (PVOID)Thread->StackLimit, + KERNEL_STACK_SIZE); } VOID @@ -88,6 +89,9 @@ KiAttachProcess(IN PKTHREAD Thread, { /* FIXME: Scan the Ready Thread List once new scheduler is in */ + /* Release dispatcher lock */ + KiReleaseDispatcherLockFromDpcLevel(); + /* Release lock */ KiReleaseApcLockFromDpcLevel(ApcLock); @@ -420,12 +424,12 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, */ VOID NTAPI -KeAttachProcess(PKPROCESS Process) +KeAttachProcess(IN PKPROCESS Process) { KLOCK_QUEUE_HANDLE ApcLock; PKTHREAD Thread; + ASSERT_PROCESS(Process); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - DPRINT("KeAttachProcess: %x\n", Process); /* Make sure that we are in the right page directory */ Thread = KeGetCurrentThread(); @@ -434,9 +438,6 @@ KeAttachProcess(PKPROCESS Process) /* Check if we're already in that process */ if (Thread->ApcState.Process == Process) return; - /* Acquire APC Lock */ - KiAcquireApcLock(Thread, &ApcLock); - /* Check if a DPC is executing or if we're already attached */ if ((Thread->ApcStateIndex != OriginalApcEnvironment) || (KeIsExecutingDpc())) @@ -450,6 +451,12 @@ KeAttachProcess(PKPROCESS Process) } else { + /* Acquire APC Lock */ + KiAcquireApcLock(Thread, &ApcLock); + + /* Acquire the dispatcher lock */ + KiAcquireDispatcherLockAtDpcLevel(); + /* Legit attach attempt: do it! */ KiAttachProcess(Thread, Process, &ApcLock, &Thread->SavedApcState); } @@ -576,6 +583,9 @@ KeStackAttachProcess(IN PKPROCESS Process, /* Acquire APC Lock */ KiAcquireApcLock(Thread, &ApcLock); + /* Acquire dispatcher lock */ + KiAcquireDispatcherLockAtDpcLevel(); + /* Check if the Current Thread is already attached */ if (Thread->ApcStateIndex != OriginalApcEnvironment) { @@ -605,8 +615,27 @@ KeUnstackDetachProcess(IN PRKAPC_STATE ApcState) /* Check for magic value meaning we were already in the same process */ if (ApcState->Process == (PKPROCESS)1) return; - /* Acquire APC Lock */ - KiAcquireApcLock(Thread, &ApcLock); + /* Loop to make sure no APCs are pending */ + for (;;) + { + /* Acquire APC Lock */ + KiAcquireApcLock(Thread, &ApcLock); + + /* Check if a kernel APC is pending */ + if (Thread->ApcState.KernelApcPending) + { + /* Check if kernel APC should be delivered */ + if (!(Thread->KernelApcDisable) && (ApcLock.OldIrql <= APC_LEVEL)) + { + /* Release the APC lock so that the APC can be delivered */ + KiReleaseApcLock(&ApcLock); + continue; + } + } + + /* Otherwise, break out */ + break; + } /* * Check if the process isn't attacked, or has a Kernel APC in progress @@ -680,17 +709,20 @@ KeUnstackDetachProcess(IN PRKAPC_STATE ApcState) */ BOOLEAN NTAPI -KeAddSystemServiceTable(PULONG_PTR Base, - PULONG Count OPTIONAL, - ULONG Limit, - PUCHAR Number, - ULONG Index) +KeAddSystemServiceTable(IN PULONG_PTR Base, + IN PULONG Count OPTIONAL, + IN ULONG Limit, + IN PUCHAR Number, + IN ULONG Index) { + PAGED_CODE(); + /* Check if descriptor table entry is free */ if ((Index > SSDT_MAX_ENTRIES - 1) || (KeServiceDescriptorTable[Index].Base) || (KeServiceDescriptorTableShadow[Index].Base)) { + /* It's not, fail */ return FALSE; } @@ -699,7 +731,6 @@ KeAddSystemServiceTable(PULONG_PTR Base, KeServiceDescriptorTableShadow[Index].Limit = Limit; KeServiceDescriptorTableShadow[Index].Number = Number; KeServiceDescriptorTableShadow[Index].Count = Count; - return TRUE; } @@ -710,8 +741,10 @@ BOOLEAN NTAPI KeRemoveSystemServiceTable(IN ULONG Index) { + PAGED_CODE(); + /* Make sure the Index is valid */ - if (Index > SSDT_MAX_ENTRIES - 1) return FALSE; + if (Index > (SSDT_MAX_ENTRIES - 1)) return FALSE; /* Is there a Normal Descriptor Table? */ if (!KeServiceDescriptorTable[Index].Base) @@ -735,6 +768,7 @@ KeRemoveSystemServiceTable(IN ULONG Index) KeServiceDescriptorTable[Index].Count = NULL; } + /* Return success */ return TRUE; } /* EOF */ From 4d94e0557f848cda59c586672b7f1a1e1f33e9d0 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 00:26:17 +0000 Subject: [PATCH 134/488] - Fix KeEnterCriticalRegion/KeLeaveCriticalRegion by moving to ke_x and adding ASSERTs, and change the code in apc.c to call these inlined versions instead. Also fix comment headers for these functions in apc.c to match the official standard. svn path=/trunk/; revision=24049 --- reactos/ntoskrnl/include/internal/ke.h | 19 ----- reactos/ntoskrnl/include/internal/ke_x.h | 49 ++++++++++++- reactos/ntoskrnl/ke/apc.c | 90 +++++++++--------------- reactos/ntoskrnl/ntoskrnl.def | 4 +- reactos/ntoskrnl/ps/process.c | 2 +- 5 files changed, 83 insertions(+), 81 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 98a0ea3b885..166a0b82887 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -146,25 +146,6 @@ extern VOID KiTrap2(VOID); InitializeListHead(&((Header)->WaitListHead)); \ } -#define KeEnterCriticalRegion() \ -{ \ - PKTHREAD _Thread = KeGetCurrentThread(); \ - if (_Thread) _Thread->KernelApcDisable--; \ -} - -#define KeLeaveCriticalRegion() \ -{ \ - PKTHREAD _Thread = KeGetCurrentThread(); \ - if((_Thread) && (++_Thread->KernelApcDisable == 0)) \ - { \ - if (!IsListEmpty(&_Thread->ApcState.ApcListHead[KernelMode]) && \ - (_Thread->SpecialApcDisable == 0)) \ - { \ - KiCheckForKernelApcDelivery(); \ - } \ - } \ -} - #define KEBUGCHECKWITHTF(a,b,c,d,e,f) \ DbgPrint("KeBugCheckWithTf at %s:%i\n",__FILE__,__LINE__), \ KeBugCheckWithTf(a,b,c,d,e,f) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 7b3dcf97511..40183b9167a 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -7,7 +7,7 @@ */ // -// Enters a Critical Region +// Enters a Guarded Region // #define KeEnterGuardedRegion() \ { \ @@ -24,7 +24,7 @@ } // -// Leaves a Critical Region +// Leaves a Guarded Region // #define KeLeaveGuardedRegion() \ { \ @@ -53,8 +53,51 @@ // // -// TODO: Critical Region Routines +// Enters a Critical Region // +#define KeEnterCriticalRegion() \ +{ \ + PKTHREAD Thread = KeGetCurrentThread(); \ + if (Thread) \ + { \ + /* Sanity checks */ \ + ASSERT(Thread == KeGetCurrentThread()); \ + ASSERT((Thread->KernelApcDisable <= 0) && \ + (Thread->KernelApcDisable != -32768)); \ + \ + /* Disable Kernel APCs */ \ + Thread->KernelApcDisable--; \ + } \ +} + +// +// Leaves a Critical Region +// +#define KeLeaveCriticalRegion() \ +{ \ + PKTHREAD Thread = KeGetCurrentThread(); \ + if (Thread) \ + { \ + /* Sanity checks */ \ + ASSERT(Thread == KeGetCurrentThread()); \ + ASSERT(Thread->KernelApcDisable < 0); \ + \ + /* Enable Kernel APCs */ \ + Thread->KernelApcDisable++; \ + \ + /* Check if Kernel APCs are now enabled */ \ + if (!(Thread->KernelApcDisable)) \ + { \ + /* Check if we need to request an APC Delivery */ \ + if (!(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) && \ + !(Thread->KernelApcDisable)) \ + { \ + /* Check for the right environment */ \ + KiCheckForKernelApcDelivery(); \ + } \ + } \ + } \ +} // // Satisfies the wait of any dispatcher object diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 675a6d41ba4..4e39c01a5c2 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -1,11 +1,9 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/apc.c - * PURPOSE: NT Implementation of APCs - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * Phillip Susi + * PURPOSE: Implements the Asyncronous Procedure Call mechanism + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES *****************************************************************/ @@ -17,27 +15,24 @@ /* FUNCTIONS *****************************************************************/ /*++ - * KiCheckForKernelApcDelivery + * @name KiCheckForKernelApcDelivery * @implemented NT 5.2 * * The KiCheckForKernelApcDelivery routine is called whenever APCs have just * been re-enabled in Kernel Mode, such as after leaving a Critical or * Guarded Region. It delivers APCs if the environment is right. * - * Params: - * None. + * @param None. * - * Returns: - * None. + * @return None. * - * Remarks: - * This routine allows KeLeave/EnterCritical/GuardedRegion to be used as a - * macro from inside WIN32K or other Drivers, which will then only have to - * do an Import API call in the case where APCs are enabled again. + * @remarks This routine allows KeLeave/EnterCritical/GuardedRegion to be used + * as macro from inside WIN32K or other Drivers, which will then only + * have do an Import API call in the case where APCs are enabled again. * *--*/ VOID -STDCALL +NTAPI KiCheckForKernelApcDelivery(VOID) { /* We should only deliver at passive */ @@ -63,34 +58,31 @@ KiCheckForKernelApcDelivery(VOID) } /*++ - * KeEnterCriticalRegion + * @name KeEnterCriticalRegion * @implemented NT4 * * The KeEnterCriticalRegion routine temporarily disables the delivery of * normal kernel APCs; special kernel-mode APCs are still delivered. * - * Params: - * None. + * @param None. * - * Returns: - * None. + * @return None. * - * Remarks: - * Highest-level drivers can call this routine while running in the context - * of the thread that requested the current I/O operation. Any caller of - * this routine should call KeLeaveCriticalRegion as quickly as possible. + * @remarks Highest-level drivers can call this routine while running in the + * context of the thread that requested the current I/O operation. + * Any caller of this routine should call KeLeaveCriticalRegion as + * quickly as possible. * - * Callers of KeEnterCriticalRegion must be running at IRQL <= APC_LEVEL. + * Callers of KeEnterCriticalRegion must be running at IRQL <= + * APC_LEVEL. * *--*/ -#undef KeEnterCriticalRegion VOID -STDCALL -KeEnterCriticalRegion(VOID) +NTAPI +_KeEnterCriticalRegion(VOID) { - /* Disable Kernel APCs */ - PKTHREAD Thread = KeGetCurrentThread(); - if (Thread) Thread->KernelApcDisable--; + /* Use inlined function */ + KeEnterCriticalRegion(); } /*++ @@ -100,37 +92,23 @@ KeEnterCriticalRegion(VOID) * The KeLeaveCriticalRegion routine reenables the delivery of normal * kernel-mode APCs that were disabled by a call to KeEnterCriticalRegion. * - * Params: - * None. + * @param None. * - * Returns: - * None. + * @return None. * - * Remarks: - * Highest-level drivers can call this routine while running in the context - * of the thread that requested the current I/O operation. + * @remarks Highest-level drivers can call this routine while running in the + * context of the thread that requested the current I/O operation. * - * Callers of KeLeaveCriticalRegion must be running at IRQL <= DISPATCH_LEVEL. + * Callers of KeLeaveCriticalRegion must be running at IRQL <= + * DISPATCH_LEVEL. * *--*/ -#undef KeLeaveCriticalRegion VOID -STDCALL -KeLeaveCriticalRegion (VOID) +NTAPI +_KeLeaveCriticalRegion(VOID) { - PKTHREAD Thread = KeGetCurrentThread(); - - /* Check if Kernel APCs are now enabled */ - if((Thread) && (++Thread->KernelApcDisable == 0)) - { - /* Check if we need to request an APC Delivery */ - if ((!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) && - (Thread->SpecialApcDisable == 0)) - { - /* Check for the right environment */ - KiCheckForKernelApcDelivery(); - } - } + /* Use inlined version */ + KeLeaveCriticalRegion(); } /*++ diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 51a843c927b..f668f690d77 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -534,7 +534,7 @@ KeDeregisterBugCheckCallback@4 KeDeregisterBugCheckReasonCallback@4 KeDetachProcess@0 KeDisconnectInterrupt@4 -KeEnterCriticalRegion@0 +KeEnterCriticalRegion@=_KeEnterCriticalRegion@0 KeEnterGuardedRegion@0 KeEnterKernelDebugger@0 KeFindConfigurationEntry@16 @@ -576,7 +576,7 @@ KeInsertQueueApc@16 KeInsertQueueDpc@12 KeIsAttachedProcess@0 KeIsExecutingDpc@0 -KeLeaveCriticalRegion@0 +KeLeaveCriticalRegion@0=_KeLeaveCriticalRegion@0 KeLeaveGuardedRegion@0 KeLoaderBlock DATA KeNumberProcessors DATA diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 6efff9ab6d1..b2b9415f9e7 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -583,7 +583,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, PROCESS_PRIORITY_NORMAL, Affinity, &DirectoryTableBase, - Process->DefaultHardErrorProcessing & 4); + (BOOLEAN)(Process->DefaultHardErrorProcessing & 4)); /* Duplicate Parent Token */ Status = PspInitializeProcessSecurity(Process, Parent); From 1462b71058741274c8679c1a0bf902270d4c2af7 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 00:54:12 +0000 Subject: [PATCH 135/488] - Re-organize apc.c into private/public functions (no code change). - Move KiInitializeUserApc to ke/i386/userapc.c. The routine is non-portable. - Force Ring 3 state into User APC TrapFrame to maintain system integrity and coherency. Also respect IOPL. - Use SEH handling routine just like when handling exceptions, to properly re-direct a crash here. Thanks to KJK again for showing me how to write these kinds of routines. svn path=/trunk/; revision=24050 --- reactos/include/ndk/asm.h | 1 + reactos/ntoskrnl/ke/apc.c | 741 +++++++++++++---------------- reactos/ntoskrnl/ke/i386/userapc.c | 135 ++++++ reactos/ntoskrnl/ntoskrnl.rbuild | 1 + 4 files changed, 470 insertions(+), 408 deletions(-) create mode 100644 reactos/ntoskrnl/ke/i386/userapc.c diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 57ecee2eca1..5fbcd49b081 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -381,6 +381,7 @@ Author: #define EFLAG_ZERO 0x4000 #define EFLAG_SELECT (EFLAG_SIGN + EFLAG_ZERO) #endif +#define EFLAGS_USER_SANITIZE 0x3F4DD7 // // CR0 diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 4e39c01a5c2..6ae0679cf67 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -12,7 +12,7 @@ #define NDEBUG #include -/* FUNCTIONS *****************************************************************/ +/* PRIVATE FUNCTIONS *********************************************************/ /*++ * @name KiCheckForKernelApcDelivery @@ -57,154 +57,6 @@ KiCheckForKernelApcDelivery(VOID) } } -/*++ - * @name KeEnterCriticalRegion - * @implemented NT4 - * - * The KeEnterCriticalRegion routine temporarily disables the delivery of - * normal kernel APCs; special kernel-mode APCs are still delivered. - * - * @param None. - * - * @return None. - * - * @remarks Highest-level drivers can call this routine while running in the - * context of the thread that requested the current I/O operation. - * Any caller of this routine should call KeLeaveCriticalRegion as - * quickly as possible. - * - * Callers of KeEnterCriticalRegion must be running at IRQL <= - * APC_LEVEL. - * - *--*/ -VOID -NTAPI -_KeEnterCriticalRegion(VOID) -{ - /* Use inlined function */ - KeEnterCriticalRegion(); -} - -/*++ - * KeLeaveCriticalRegion - * @implemented NT4 - * - * The KeLeaveCriticalRegion routine reenables the delivery of normal - * kernel-mode APCs that were disabled by a call to KeEnterCriticalRegion. - * - * @param None. - * - * @return None. - * - * @remarks Highest-level drivers can call this routine while running in the - * context of the thread that requested the current I/O operation. - * - * Callers of KeLeaveCriticalRegion must be running at IRQL <= - * DISPATCH_LEVEL. - * - *--*/ -VOID -NTAPI -_KeLeaveCriticalRegion(VOID) -{ - /* Use inlined version */ - KeLeaveCriticalRegion(); -} - -/*++ - * KeInitializeApc - * @implemented NT4 - * - * The The KeInitializeApc routine initializes an APC object, and registers - * the Kernel, Rundown and Normal routines for that object. - * - * Params: - * Apc - Pointer to a KAPC structure that represents the APC object to - * initialize. The caller must allocate storage for the structure - * from resident memory. - * - * Thread - Thread to which to deliver the APC. - * - * TargetEnvironment - APC Environment to be used. - * - * KernelRoutine - Points to the KernelRoutine to associate with the APC. - * This routine is executed for all APCs. - * - * RundownRoutine - Points to the RundownRoutine to associate with the APC. - * This routine is executed when the Thread exists with - * the APC executing. - * - * NormalRoutine - Points to the NormalRoutine to associate with the APC. - * This routine is executed at PASSIVE_LEVEL. If this is - * not specifed, the APC becomes a Special APC and the - * Mode and Context parameters are ignored. - * - * Mode - Specifies the processor mode at which to run the Normal Routine. - * - * Context - Specifices the value to pass as Context parameter to the - * registered routines. - * - * Returns: - * None. - * - * Remarks: - * The caller can queue an initialized APC with KeInsertQueueApc. - * - * Storage for the APC object must be resident, such as nonpaged pool - * allocated by the caller. - * - * Callers of this routine must be running at IRQL = PASSIVE_LEVEL. - * - *--*/ -VOID -STDCALL -KeInitializeApc(IN PKAPC Apc, - IN PKTHREAD Thread, - IN KAPC_ENVIRONMENT TargetEnvironment, - IN PKKERNEL_ROUTINE KernelRoutine, - IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, - IN PKNORMAL_ROUTINE NormalRoutine, - IN KPROCESSOR_MODE Mode, - IN PVOID Context) -{ - DPRINT("KeInitializeApc(Apc %x, Thread %x, Environment %d, " - "KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, " - "Context %x)\n",Apc,Thread,TargetEnvironment,KernelRoutine,RundownRoutine, - NormalRoutine,Mode,Context); - - /* Set up the basic APC Structure Data */ - RtlZeroMemory(Apc, sizeof(KAPC)); - Apc->Type = ApcObject; - Apc->Size = sizeof(KAPC); - - /* Set the Environment */ - if (TargetEnvironment == CurrentApcEnvironment) { - - Apc->ApcStateIndex = Thread->ApcStateIndex; - - } else { - - Apc->ApcStateIndex = TargetEnvironment; - } - - /* Set the Thread and Routines */ - Apc->Thread = Thread; - Apc->KernelRoutine = KernelRoutine; - Apc->RundownRoutine = RundownRoutine; - Apc->NormalRoutine = NormalRoutine; - - /* Check if this is a Special APC, in which case we use KernelMode and no Context */ - if (ARGUMENT_PRESENT(NormalRoutine)) { - - Apc->ApcMode = Mode; - Apc->NormalContext = Context; - - } else { - - Apc->ApcMode = KernelMode; - } -} - static __inline VOID @@ -426,183 +278,6 @@ Unwait: return; } -/*++ - * KeInsertQueueApc - * @implemented NT4 - * - * The KeInsertQueueApc routine queues a APC for execution when the right - * scheduler environment exists. - * - * Params: - * Apc - Pointer to an initialized control object of type DPC for which the - * caller provides the storage. - * - * SystemArgument[1,2] - Pointer to a set of two parameters that contain - * untyped data. - * - * PriorityBoost - Priority Boost to apply to the Thread. - * - * Returns: - * If the APC is already inserted or APC queueing is disabled, FALSE. - * Otherwise, TRUE. - * - * Remarks: - * The APC will execute at APC_LEVEL for the KernelRoutine registered, and - * at PASSIVE_LEVEL for the NormalRoutine registered. - * - * Callers of this routine must be running at IRQL = PASSIVE_LEVEL. - * - *--*/ -BOOLEAN -STDCALL -KeInsertQueueApc(PKAPC Apc, - PVOID SystemArgument1, - PVOID SystemArgument2, - KPRIORITY PriorityBoost) -{ - PKTHREAD Thread = Apc->Thread; - KLOCK_QUEUE_HANDLE ApcLock; - BOOLEAN State = TRUE; - - /* Get the APC lock */ - KiAcquireApcLock(Thread, &ApcLock); - - /* Make sure we can Queue APCs and that this one isn't already inserted */ - if ((Thread->ApcQueueable == FALSE) && (Apc->Inserted == TRUE)) - { - /* Fail */ - State = FALSE; - } - else - { - /* Set the System Arguments and set it as inserted */ - Apc->SystemArgument1 = SystemArgument1; - Apc->SystemArgument2 = SystemArgument2; - Apc->Inserted = TRUE; - - /* Call the Internal Function */ - KiInsertQueueApc(Apc, PriorityBoost); - } - - /* Release the APC lock and return success */ - KiReleaseApcLock(&ApcLock); - KiExitDispatcher(ApcLock.OldIrql); - return State; -} - -/*++ - * KeFlushQueueApc - * - * The KeFlushQueueApc routine flushes all APCs of the given processor mode - * from the specified Thread's APC queue. - * - * Params: - * Thread - Pointer to the thread whose APC queue will be flushed. - * - * PreviousMode - Specifies which APC Queue to flush. - * - * Returns: - * A pointer to the first entry in the flushed APC queue. - * - * Remarks: - * If the routine returns NULL, it means that no APCs were to be flushed. - * - * Callers of KeFlushQueueApc must be running at DISPATCH_LEVEL or lower. - * - *--*/ -PLIST_ENTRY -STDCALL -KeFlushQueueApc(IN PKTHREAD Thread, - IN KPROCESSOR_MODE PreviousMode) -{ - PKAPC Apc; - PLIST_ENTRY FirstEntry, CurrentEntry; - KLOCK_QUEUE_HANDLE ApcLock; - - /* Get the APC lock */ - KiAcquireApcLock(Thread, &ApcLock); - - if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) { - FirstEntry = NULL; - } else { - FirstEntry = Thread->ApcState.ApcListHead[PreviousMode].Flink; - RemoveEntryList(&Thread->ApcState.ApcListHead[PreviousMode]); - CurrentEntry = FirstEntry; - do { - Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry); - Apc->Inserted = FALSE; - CurrentEntry = CurrentEntry->Flink; - } while (CurrentEntry != FirstEntry); - } - - /* Release the lock */ - KiReleaseApcLock(&ApcLock); - - /* Return the first entry */ - return FirstEntry; -} - -/*++ - * KeRemoveQueueApc - * - * The KeRemoveQueueApc routine removes a given APC object from the system - * APC queue. - * - * Params: - * APC - Pointer to an initialized APC object that was queued by calling - * KeInsertQueueApc. - * - * Returns: - * TRUE if the APC Object is in the APC Queue. If it isn't, no operation is - * performed and FALSE is returned. - * - * Remarks: - * If the given APC Object is currently queued, it is removed from the queue - * and any calls to the registered routines are cancelled. - * - * Callers of KeLeaveCriticalRegion can be running at any IRQL. - * - *--*/ -BOOLEAN -STDCALL -KeRemoveQueueApc(PKAPC Apc) -{ - PKTHREAD Thread = Apc->Thread; - PKAPC_STATE ApcState; - BOOLEAN Inserted; - KLOCK_QUEUE_HANDLE ApcLock; - - /* Get the APC lock */ - KiAcquireApcLock(Thread, &ApcLock); - - /* Check if it's inserted */ - if ((Inserted = Apc->Inserted)) - { - /* Remove it from the Queue*/ - Apc->Inserted = FALSE; - ApcState = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]; - RemoveEntryList(&Apc->ApcListEntry); - - /* If the Queue is completely empty, then no more APCs are pending */ - if (IsListEmpty(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode])) - { - /* Set the correct State based on the Apc Mode */ - if (Apc->ApcMode == KernelMode) - { - ApcState->KernelApcPending = FALSE; - } - else - { - ApcState->UserApcPending = FALSE; - } - } - } - - /* Release the lock and return */ - KiReleaseApcLock(&ApcLock); - return Inserted; -} - /*++ * KiDeliverApc * @implemented @NT4 @@ -835,81 +510,363 @@ KiFreeApcRoutine(PKAPC Apc, ExFreePool(Apc); } +static __inline +VOID RepairList(PLIST_ENTRY Original, + PLIST_ENTRY Copy, + KPROCESSOR_MODE Mode) +{ + /* Copy Source to Desination */ + if (IsListEmpty(&Original[(int)Mode])) { + + InitializeListHead(&Copy[(int)Mode]); + + } else { + + Copy[(int)Mode].Flink = Original[(int)Mode].Flink; + Copy[(int)Mode].Blink = Original[(int)Mode].Blink; + Original[(int)Mode].Flink->Blink = &Copy[(int)Mode]; + Original[(int)Mode].Blink->Flink = &Copy[(int)Mode]; + } +} + +VOID +STDCALL +KiMoveApcState(PKAPC_STATE OldState, + PKAPC_STATE NewState) +{ + /* Restore backup of Original Environment */ + *NewState = *OldState; + + /* Repair Lists */ + RepairList(NewState->ApcListHead, OldState->ApcListHead, KernelMode); + RepairList(NewState->ApcListHead, OldState->ApcListHead, UserMode); +} + +/* PUBLIC FUNCTIONS **********************************************************/ + /*++ - * KiInitializeUserApc + * @name KeEnterCriticalRegion + * @implemented NT4 * - * Prepares the Context for a User-Mode APC called through NTDLL.DLL + * The KeEnterCriticalRegion routine temporarily disables the delivery of + * normal kernel APCs; special kernel-mode APCs are still delivered. + * + * @param None. + * + * @return None. + * + * @remarks Highest-level drivers can call this routine while running in the + * context of the thread that requested the current I/O operation. + * Any caller of this routine should call KeLeaveCriticalRegion as + * quickly as possible. + * + * Callers of KeEnterCriticalRegion must be running at IRQL <= + * APC_LEVEL. + * + *--*/ +VOID +NTAPI +_KeEnterCriticalRegion(VOID) +{ + /* Use inlined function */ + KeEnterCriticalRegion(); +} + +/*++ + * KeLeaveCriticalRegion + * @implemented NT4 + * + * The KeLeaveCriticalRegion routine reenables the delivery of normal + * kernel-mode APCs that were disabled by a call to KeEnterCriticalRegion. + * + * @param None. + * + * @return None. + * + * @remarks Highest-level drivers can call this routine while running in the + * context of the thread that requested the current I/O operation. + * + * Callers of KeLeaveCriticalRegion must be running at IRQL <= + * DISPATCH_LEVEL. + * + *--*/ +VOID +NTAPI +_KeLeaveCriticalRegion(VOID) +{ + /* Use inlined version */ + KeLeaveCriticalRegion(); +} + +/*++ + * KeInitializeApc + * @implemented NT4 + * + * The The KeInitializeApc routine initializes an APC object, and registers + * the Kernel, Rundown and Normal routines for that object. * * Params: - * Reserved - Pointer to the Exception Frame on non-i386 builds. + * Apc - Pointer to a KAPC structure that represents the APC object to + * initialize. The caller must allocate storage for the structure + * from resident memory. * - * TrapFrame - Pointer to the Trap Frame. + * Thread - Thread to which to deliver the APC. * - * NormalRoutine - Pointer to the NormalRoutine to call. + * TargetEnvironment - APC Environment to be used. * - * NormalContext - Pointer to the context to send to the Normal Routine. + * KernelRoutine - Points to the KernelRoutine to associate with the APC. + * This routine is executed for all APCs. * - * SystemArgument[1-2] - Pointer to a set of two parameters that contain - * untyped data. + * RundownRoutine - Points to the RundownRoutine to associate with the APC. + * This routine is executed when the Thread exists with + * the APC executing. + * + * NormalRoutine - Points to the NormalRoutine to associate with the APC. + * This routine is executed at PASSIVE_LEVEL. If this is + * not specifed, the APC becomes a Special APC and the + * Mode and Context parameters are ignored. + * + * Mode - Specifies the processor mode at which to run the Normal Routine. + * + * Context - Specifices the value to pass as Context parameter to the + * registered routines. * * Returns: * None. * * Remarks: - * None. + * The caller can queue an initialized APC with KeInsertQueueApc. + * + * Storage for the APC object must be resident, such as nonpaged pool + * allocated by the caller. + * + * Callers of this routine must be running at IRQL = PASSIVE_LEVEL. * *--*/ VOID STDCALL -KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, - IN PKTRAP_FRAME TrapFrame, - IN PKNORMAL_ROUTINE NormalRoutine, - IN PVOID NormalContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) +KeInitializeApc(IN PKAPC Apc, + IN PKTHREAD Thread, + IN KAPC_ENVIRONMENT TargetEnvironment, + IN PKKERNEL_ROUTINE KernelRoutine, + IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, + IN PKNORMAL_ROUTINE NormalRoutine, + IN KPROCESSOR_MODE Mode, + IN PVOID Context) { - CONTEXT Context; - ULONG_PTR Stack; - ULONG Size; + DPRINT("KeInitializeApc(Apc %x, Thread %x, Environment %d, " + "KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, " + "Context %x)\n",Apc,Thread,TargetEnvironment,KernelRoutine,RundownRoutine, + NormalRoutine,Mode,Context); - DPRINT("KiInitializeUserApc(TrapFrame %x/%x)\n", TrapFrame, - KeGetCurrentThread()->TrapFrame); + /* Set up the basic APC Structure Data */ + RtlZeroMemory(Apc, sizeof(KAPC)); + Apc->Type = ApcObject; + Apc->Size = sizeof(KAPC); - /* Don't deliver APCs in V86 mode */ - if (TrapFrame->EFlags & X86_EFLAGS_VM) return; + /* Set the Environment */ + if (TargetEnvironment == CurrentApcEnvironment) { - /* Save the full context */ - Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; - KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context); + Apc->ApcStateIndex = Thread->ApcStateIndex; - /* Protect with SEH */ - _SEH_TRY - { - /* Get the aligned size */ - Size = ((sizeof(CONTEXT) + 3) & ~3) + 4 * sizeof(ULONG_PTR); - Stack = (Context.Esp & ~3) - Size; + } else { - /* Probe and copy */ - ProbeForWrite((PVOID)Stack, Size, 4); - RtlMoveMemory((PVOID)(Stack + 4 * sizeof(ULONG_PTR)), - &Context, - sizeof(CONTEXT)); - - /* Run at APC dispatcher */ - TrapFrame->Eip = (ULONG)KeUserApcDispatcher; - TrapFrame->HardwareEsp = Stack; - - /* Setup the stack */ - *(PULONG_PTR)(Stack + 0 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalRoutine; - *(PULONG_PTR)(Stack + 1 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalContext; - *(PULONG_PTR)(Stack + 2 * sizeof(ULONG_PTR)) = (ULONG_PTR)SystemArgument1; - *(PULONG_PTR)(Stack + 3 * sizeof(ULONG_PTR)) = (ULONG_PTR)SystemArgument2; + Apc->ApcStateIndex = TargetEnvironment; } - _SEH_HANDLE - { - /* FIXME: Get the record and raise an exception */ + + /* Set the Thread and Routines */ + Apc->Thread = Thread; + Apc->KernelRoutine = KernelRoutine; + Apc->RundownRoutine = RundownRoutine; + Apc->NormalRoutine = NormalRoutine; + + /* Check if this is a Special APC, in which case we use KernelMode and no Context */ + if (ARGUMENT_PRESENT(NormalRoutine)) { + + Apc->ApcMode = Mode; + Apc->NormalContext = Context; + + } else { + + Apc->ApcMode = KernelMode; } - _SEH_END; +} + +/*++ + * KeInsertQueueApc + * @implemented NT4 + * + * The KeInsertQueueApc routine queues a APC for execution when the right + * scheduler environment exists. + * + * Params: + * Apc - Pointer to an initialized control object of type DPC for which the + * caller provides the storage. + * + * SystemArgument[1,2] - Pointer to a set of two parameters that contain + * untyped data. + * + * PriorityBoost - Priority Boost to apply to the Thread. + * + * Returns: + * If the APC is already inserted or APC queueing is disabled, FALSE. + * Otherwise, TRUE. + * + * Remarks: + * The APC will execute at APC_LEVEL for the KernelRoutine registered, and + * at PASSIVE_LEVEL for the NormalRoutine registered. + * + * Callers of this routine must be running at IRQL = PASSIVE_LEVEL. + * + *--*/ +BOOLEAN +STDCALL +KeInsertQueueApc(PKAPC Apc, + PVOID SystemArgument1, + PVOID SystemArgument2, + KPRIORITY PriorityBoost) +{ + PKTHREAD Thread = Apc->Thread; + KLOCK_QUEUE_HANDLE ApcLock; + BOOLEAN State = TRUE; + + /* Get the APC lock */ + KiAcquireApcLock(Thread, &ApcLock); + + /* Make sure we can Queue APCs and that this one isn't already inserted */ + if ((Thread->ApcQueueable == FALSE) && (Apc->Inserted == TRUE)) + { + /* Fail */ + State = FALSE; + } + else + { + /* Set the System Arguments and set it as inserted */ + Apc->SystemArgument1 = SystemArgument1; + Apc->SystemArgument2 = SystemArgument2; + Apc->Inserted = TRUE; + + /* Call the Internal Function */ + KiInsertQueueApc(Apc, PriorityBoost); + } + + /* Release the APC lock and return success */ + KiReleaseApcLock(&ApcLock); + KiExitDispatcher(ApcLock.OldIrql); + return State; +} + +/*++ + * KeFlushQueueApc + * + * The KeFlushQueueApc routine flushes all APCs of the given processor mode + * from the specified Thread's APC queue. + * + * Params: + * Thread - Pointer to the thread whose APC queue will be flushed. + * + * PreviousMode - Specifies which APC Queue to flush. + * + * Returns: + * A pointer to the first entry in the flushed APC queue. + * + * Remarks: + * If the routine returns NULL, it means that no APCs were to be flushed. + * + * Callers of KeFlushQueueApc must be running at DISPATCH_LEVEL or lower. + * + *--*/ +PLIST_ENTRY +STDCALL +KeFlushQueueApc(IN PKTHREAD Thread, + IN KPROCESSOR_MODE PreviousMode) +{ + PKAPC Apc; + PLIST_ENTRY FirstEntry, CurrentEntry; + KLOCK_QUEUE_HANDLE ApcLock; + + /* Get the APC lock */ + KiAcquireApcLock(Thread, &ApcLock); + + if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) { + FirstEntry = NULL; + } else { + FirstEntry = Thread->ApcState.ApcListHead[PreviousMode].Flink; + RemoveEntryList(&Thread->ApcState.ApcListHead[PreviousMode]); + CurrentEntry = FirstEntry; + do { + Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry); + Apc->Inserted = FALSE; + CurrentEntry = CurrentEntry->Flink; + } while (CurrentEntry != FirstEntry); + } + + /* Release the lock */ + KiReleaseApcLock(&ApcLock); + + /* Return the first entry */ + return FirstEntry; +} + +/*++ + * KeRemoveQueueApc + * + * The KeRemoveQueueApc routine removes a given APC object from the system + * APC queue. + * + * Params: + * APC - Pointer to an initialized APC object that was queued by calling + * KeInsertQueueApc. + * + * Returns: + * TRUE if the APC Object is in the APC Queue. If it isn't, no operation is + * performed and FALSE is returned. + * + * Remarks: + * If the given APC Object is currently queued, it is removed from the queue + * and any calls to the registered routines are cancelled. + * + * Callers of KeLeaveCriticalRegion can be running at any IRQL. + * + *--*/ +BOOLEAN +STDCALL +KeRemoveQueueApc(PKAPC Apc) +{ + PKTHREAD Thread = Apc->Thread; + PKAPC_STATE ApcState; + BOOLEAN Inserted; + KLOCK_QUEUE_HANDLE ApcLock; + + /* Get the APC lock */ + KiAcquireApcLock(Thread, &ApcLock); + + /* Check if it's inserted */ + if ((Inserted = Apc->Inserted)) + { + /* Remove it from the Queue*/ + Apc->Inserted = FALSE; + ApcState = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]; + RemoveEntryList(&Apc->ApcListEntry); + + /* If the Queue is completely empty, then no more APCs are pending */ + if (IsListEmpty(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode])) + { + /* Set the correct State based on the Apc Mode */ + if (Apc->ApcMode == KernelMode) + { + ApcState->KernelApcPending = FALSE; + } + else + { + ApcState->UserApcPending = FALSE; + } + } + } + + /* Release the lock and return */ + KiReleaseApcLock(&ApcLock); + return Inserted; } /*++ @@ -1034,35 +991,3 @@ NtQueueApcThread(HANDLE ThreadHandle, return Status; } -static __inline -VOID RepairList(PLIST_ENTRY Original, - PLIST_ENTRY Copy, - KPROCESSOR_MODE Mode) -{ - /* Copy Source to Desination */ - if (IsListEmpty(&Original[(int)Mode])) { - - InitializeListHead(&Copy[(int)Mode]); - - } else { - - Copy[(int)Mode].Flink = Original[(int)Mode].Flink; - Copy[(int)Mode].Blink = Original[(int)Mode].Blink; - Original[(int)Mode].Flink->Blink = &Copy[(int)Mode]; - Original[(int)Mode].Blink->Flink = &Copy[(int)Mode]; - } -} - -VOID -STDCALL -KiMoveApcState(PKAPC_STATE OldState, - PKAPC_STATE NewState) -{ - /* Restore backup of Original Environment */ - *NewState = *OldState; - - /* Repair Lists */ - RepairList(NewState->ApcListHead, OldState->ApcListHead, KernelMode); - RepairList(NewState->ApcListHead, OldState->ApcListHead, UserMode); -} - diff --git a/reactos/ntoskrnl/ke/i386/userapc.c b/reactos/ntoskrnl/ke/i386/userapc.c new file mode 100644 index 00000000000..cfc2a0aa8f5 --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/userapc.c @@ -0,0 +1,135 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/i386/userapc.c + * PURPOSE: Implements User-Mode APC Initialization + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* PRIVATE FUNCTIONS *********************************************************/ + +_SEH_DEFINE_LOCALS(KiCopyInfo) +{ + volatile EXCEPTION_RECORD SehExceptRecord; +}; + +_SEH_FILTER(KiCopyInformation2) +{ + _SEH_ACCESS_LOCALS(KiCopyInfo); + + /* Copy the exception records and return to the handler */ + RtlMoveMemory((PVOID)&_SEH_VAR(SehExceptRecord), + _SEH_GetExceptionPointers()->ExceptionRecord, + sizeof(EXCEPTION_RECORD)); + return EXCEPTION_EXECUTE_HANDLER; +} + +/*++ + * KiInitializeUserApc + * + * Prepares the Context for a User-Mode APC called through NTDLL.DLL + * + * Params: + * Reserved - Pointer to the Exception Frame on non-i386 builds. + * + * TrapFrame - Pointer to the Trap Frame. + * + * NormalRoutine - Pointer to the NormalRoutine to call. + * + * NormalContext - Pointer to the context to send to the Normal Routine. + * + * SystemArgument[1-2] - Pointer to a set of two parameters that contain + * untyped data. + * + * Returns: + * None. + * + * Remarks: + * None. + * + *--*/ +VOID +STDCALL +KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, + IN PKTRAP_FRAME TrapFrame, + IN PKNORMAL_ROUTINE NormalRoutine, + IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +{ + CONTEXT Context; + ULONG_PTR Stack; + ULONG Size; + EXCEPTION_RECORD SehExceptRecord; + _SEH_DECLARE_LOCALS(KiCopyInfo); + + /* Don't deliver APCs in V86 mode */ + if (TrapFrame->EFlags & X86_EFLAGS_VM) return; + + /* Save the full context */ + Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; + KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context); + + /* Protect with SEH */ + _SEH_TRY + { + /* Sanity check */ + ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode); + + /* Get the aligned size */ + Size = ((sizeof(CONTEXT) + 3) & ~3) + 4 * sizeof(ULONG_PTR); + Stack = (Context.Esp & ~3) - Size; + + /* Probe and copy */ + ProbeForWrite((PVOID)Stack, Size, 4); + RtlMoveMemory((PVOID)(Stack + (4 * sizeof(ULONG_PTR))), + &Context, + sizeof(CONTEXT)); + + /* Run at APC dispatcher */ + TrapFrame->Eip = (ULONG)KeUserApcDispatcher; + TrapFrame->HardwareEsp = Stack; + + /* Setup Ring 3 state */ + TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK; + TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK; + TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK; + TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK; + TrapFrame->SegGs = 0; + + /* Sanitize EFLAGS */ + TrapFrame->EFlags = Context.EFlags & EFLAGS_USER_SANITIZE; + TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK; + + /* Check if user-mode has IO privileges */ + if (KeGetCurrentThread()->Iopl) + { + /* Enable them*/ + TrapFrame->EFlags |= (0x3000); + } + + /* Setup the stack */ + *(PULONG_PTR)(Stack + 0 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalRoutine; + *(PULONG_PTR)(Stack + 1 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalContext; + *(PULONG_PTR)(Stack + 2 * sizeof(ULONG_PTR)) = (ULONG_PTR)SystemArgument1; + *(PULONG_PTR)(Stack + 3 * sizeof(ULONG_PTR)) = (ULONG_PTR)SystemArgument2; + } + _SEH_EXCEPT(KiCopyInformation2) + { + /* Dispatch the exception */ + _SEH_VAR(SehExceptRecord).ExceptionAddress = (PVOID)TrapFrame->Eip; + KiDispatchException(&SehExceptRecord, + ExceptionFrame, + TrapFrame, + UserMode, + TRUE); + } + _SEH_END; +} + diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index d21d1cee21a..30f4e239246 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -40,6 +40,7 @@ thread.c trap.s usercall_asm.S + userapc.c v86vdm.c v86m_sup.S From 2fea34f0e1f5f9c4b2a8c1f17e2facdb15059b7a Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 01:15:03 +0000 Subject: [PATCH 136/488] - Re-implement KiRequestApcInterrupt in ke_x.h. Make it work by CPU number (as documented) instead of comparing PRCBs. - Move NtQueueApcThread to ps/state.c since it's a Ps-level function. - Make NtQueueApcThread use POOL_QUOTA_FAIL_INSTEAD_OF_RAISE and add that flag to our DDK. Also fix the check for SystemThread by looking at the flag, not checking if TEB == NULL. Also fix a memory leak and comment header. - Fix comment header in KiInitalizeUserApc. svn path=/trunk/; revision=24051 --- reactos/include/ddk/winddk.h | 5 + reactos/ntoskrnl/include/internal/ke_x.h | 24 ++++ reactos/ntoskrnl/include/internal/tag.h | 1 + reactos/ntoskrnl/ke/apc.c | 135 +---------------------- reactos/ntoskrnl/ke/i386/userapc.c | 25 +++-- reactos/ntoskrnl/ps/state.c | 107 ++++++++++++++++++ 6 files changed, 153 insertions(+), 144 deletions(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 119262d0315..e9695a694ff 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -4108,6 +4108,11 @@ typedef enum _POOL_TYPE { NonPagedPoolCacheAlignedMustSSession } POOL_TYPE; +#define POOL_COLD_ALLOCATION 256 +#define POOL_QUOTA_FAIL_INSTEAD_OF_RAISE 8 +#define POOL_RAISE_IF_ALLOCATION_FAILURE 16 + + typedef enum _EX_POOL_PRIORITY { LowPoolPriority, LowPoolPrioritySpecialPoolOverrun = 8, diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 40183b9167a..9c193e9b06f 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -428,6 +428,14 @@ KiRundownThread(IN PKTHREAD Thread) } } +FORCEINLINE +VOID +KiRequestApcInterrupt(IN UCHAR Processor) +{ + /* Request a software interrupt */ + HalRequestSoftwareInterrupt(APC_LEVEL); +} + #else KIRQL @@ -594,6 +602,22 @@ KiCheckDeferredReadyList(IN PKPRCB Prcb) if (Prcb->DeferredReadyListHead.Next) KiProcessDeferredReadyList(Prcb); } +FORCEINLINE +VOID +KiRequestApcInterrupt(IN UCHAR Processor) +{ + /* Check if we're on the same CPU */ + if (KeGetCurrentPrcb()->Number == Processor) + { + /* Request a software interrupt */ + HalRequestSoftwareInterrupt(APC_LEVEL); + } + else + { + KiIpiSendRequest(KeGetCurrentPrcb()->SetMember, IPI_APC); + } +} + #endif FORCEINLINE diff --git a/reactos/ntoskrnl/include/internal/tag.h b/reactos/ntoskrnl/include/internal/tag.h index 862d321b585..e474a624038 100644 --- a/reactos/ntoskrnl/include/internal/tag.h +++ b/reactos/ntoskrnl/include/internal/tag.h @@ -140,6 +140,7 @@ /* formerly located in ps/notify.c */ #define TAG_KAPC TAG('k','p','a','p') /* kpap - kernel ps apc */ +#define TAG_PS_APC TAG('P', 's', 'a', 'p') /* Psap - Ps APC */ /* formerly located in rtl/handle.c */ #define TAG_HDTB TAG('H', 'D', 'T', 'B') diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 6ae0679cf67..52ab295f300 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -18,8 +18,8 @@ * @name KiCheckForKernelApcDelivery * @implemented NT 5.2 * - * The KiCheckForKernelApcDelivery routine is called whenever APCs have just - * been re-enabled in Kernel Mode, such as after leaving a Critical or + * The KiCheckForKernelApcDelivery routine is called whenever APCs have + * just been re-enabled in Kernel Mode, such as after leaving a Critical or * Guarded Region. It delivers APCs if the environment is right. * * @param None. @@ -57,32 +57,6 @@ KiCheckForKernelApcDelivery(VOID) } } -static -__inline -VOID -KiRequestApcInterrupt(IN PKTHREAD Thread) -{ -#ifdef CONFIG_SMP - PKPRCB Prcb, CurrentPrcb; - LONG i; - - CurrentPrcb = KeGetCurrentPrcb(); - for (i = 0; i < KeNumberProcessors; i++) - { - Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb; - if (Prcb->CurrentThread == Thread) - { - ASSERT (CurrentPrcb != Prcb); - KiIpiSendRequest(Prcb->SetMember, IPI_APC); - break; - } - } - ASSERT (i < KeNumberProcessors); -#else - HalRequestSoftwareInterrupt(APC_LEVEL); -#endif -} - /*++ * KiInsertQueueApc * @@ -236,7 +210,7 @@ KiInsertQueueApc(PKAPC Apc, if (Thread->State == Running) { /* The thread is running, so send an APC request */ - KiRequestApcInterrupt(Thread); + KiRequestApcInterrupt(Thread->NextProcessor); } else { @@ -498,18 +472,6 @@ Quickie: return; } -VOID -STDCALL -KiFreeApcRoutine(PKAPC Apc, - PKNORMAL_ROUTINE* NormalRoutine, - PVOID* NormalContext, - PVOID* SystemArgument1, - PVOID* SystemArgument2) -{ - /* Free the APC and do nothing else */ - ExFreePool(Apc); -} - static __inline VOID RepairList(PLIST_ENTRY Original, PLIST_ENTRY Copy, @@ -900,94 +862,3 @@ KeAreApcsDisabled(VOID) return KeGetCurrentThread()->CombinedApcDisable ? TRUE : FALSE; } -/*++ - * NtQueueApcThread - * NT4 - * - * This routine is used to queue an APC from user-mode for the specified - * thread. - * - * Params: - * Thread Handle - Handle to the Thread. This handle must have THREAD_SET_CONTEXT privileges. - * - * ApcRoutine - Pointer to the APC Routine to call when the APC executes. - * - * NormalContext - Pointer to the context to send to the Normal Routine. - * - * SystemArgument[1-2] - Pointer to a set of two parameters that contain - * untyped data. - * - * Returns: - * STATUS_SUCCESS or failure cute from associated calls. - * - * Remarks: - * The thread must enter an alertable wait before the APC will be - * delivered. - * - *--*/ -NTSTATUS -STDCALL -NtQueueApcThread(HANDLE ThreadHandle, - PKNORMAL_ROUTINE ApcRoutine, - PVOID NormalContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PKAPC Apc; - PETHREAD Thread; - KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); - NTSTATUS Status; - - /* Get ETHREAD from Handle */ - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_SET_CONTEXT, - PsThreadType, - PreviousMode, - (PVOID)&Thread, - NULL); - - /* Fail if the Handle is invalid for some reason */ - if (!NT_SUCCESS(Status)) { - - return(Status); - } - - /* If this is a Kernel or System Thread, then fail */ - if (Thread->Tcb.Teb == NULL) { - - ObDereferenceObject(Thread); - return STATUS_INVALID_HANDLE; - } - - /* Allocate an APC */ - Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG('P', 's', 'a', 'p')); - if (Apc == NULL) { - - ObDereferenceObject(Thread); - return(STATUS_NO_MEMORY); - } - - /* Initialize and Queue a user mode apc (always!) */ - KeInitializeApc(Apc, - &Thread->Tcb, - OriginalApcEnvironment, - KiFreeApcRoutine, - NULL, - ApcRoutine, - UserMode, - NormalContext); - - if (!KeInsertQueueApc(Apc, SystemArgument1, SystemArgument2, IO_NO_INCREMENT)) { - - Status = STATUS_UNSUCCESSFUL; - - } else { - - Status = STATUS_SUCCESS; - } - - /* Dereference Thread and Return */ - ObDereferenceObject(Thread); - return Status; -} - diff --git a/reactos/ntoskrnl/ke/i386/userapc.c b/reactos/ntoskrnl/ke/i386/userapc.c index cfc2a0aa8f5..13fcf7f0625 100644 --- a/reactos/ntoskrnl/ke/i386/userapc.c +++ b/reactos/ntoskrnl/ke/i386/userapc.c @@ -31,27 +31,28 @@ _SEH_FILTER(KiCopyInformation2) } /*++ - * KiInitializeUserApc + * @name KiInitializeUserApc * * Prepares the Context for a User-Mode APC called through NTDLL.DLL * - * Params: - * Reserved - Pointer to the Exception Frame on non-i386 builds. + * @param Reserved + * Pointer to the Exception Frame on non-i386 builds. * - * TrapFrame - Pointer to the Trap Frame. + * @param TrapFrame + * Pointer to the Trap Frame. * - * NormalRoutine - Pointer to the NormalRoutine to call. + * @param NormalRoutine + * Pointer to the NormalRoutine to call. * - * NormalContext - Pointer to the context to send to the Normal Routine. + * @param NormalContext + * Pointer to the context to send to the Normal Routine. * - * SystemArgument[1-2] - Pointer to a set of two parameters that contain - * untyped data. + * @param SystemArgument[1-2] + * Pointer to a set of two parameters that contain untyped data. * - * Returns: - * None. + * @return None. * - * Remarks: - * None. + * @remarks None. * *--*/ VOID diff --git a/reactos/ntoskrnl/ps/state.c b/reactos/ntoskrnl/ps/state.c index 9739fec7593..964b9f62aed 100644 --- a/reactos/ntoskrnl/ps/state.c +++ b/reactos/ntoskrnl/ps/state.c @@ -15,6 +15,18 @@ /* PRIVATE FUNCTIONS *********************************************************/ +VOID +NTAPI +PspQueueApcSpecialApc(IN PKAPC Apc, + IN OUT PKNORMAL_ROUTINE* NormalRoutine, + IN OUT PVOID* NormalContext, + IN OUT PVOID* SystemArgument1, + IN OUT PVOID* SystemArgument2) +{ + /* Free the APC and do nothing else */ + ExFreePool(Apc); +} + NTSTATUS NTAPI PsResumeThread(IN PETHREAD Thread, @@ -448,4 +460,99 @@ NtTestAlert(VOID) STATUS_ALERTED : STATUS_SUCCESS; } +/*++ + * @name NtQueueApcThread + * NT4 + * + * This routine is used to queue an APC from user-mode for the specified + * thread. + * + * @param ThreadHandle + * Handle to the Thread. + * This handle must have THREAD_SET_CONTEXT privileges. + * + * @param ApcRoutine + * Pointer to the APC Routine to call when the APC executes. + * + * @param NormalContext + * Pointer to the context to send to the Normal Routine. + * + * @param SystemArgument[1-2] + * Pointer to a set of two parameters that contain untyped data. + * + * @return STATUS_SUCCESS or failure cute from associated calls. + * + * @remarks The thread must enter an alertable wait before the APC will be + * delivered. + * + *--*/ +NTSTATUS +NTAPI +NtQueueApcThread(IN HANDLE ThreadHandle, + IN PKNORMAL_ROUTINE ApcRoutine, + IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +{ + PKAPC Apc; + PETHREAD Thread; + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + /* Get ETHREAD from Handle */ + Status = ObReferenceObjectByHandle(ThreadHandle, + THREAD_SET_CONTEXT, + PsThreadType, + ExGetPreviousMode(), + (PVOID)&Thread, + NULL); + if (NT_SUCCESS(Status)) return Status; + + /* Check if this is a System Thread */ + if (Thread->SystemThread) + { + /* Fail */ + Status = STATUS_INVALID_HANDLE; + goto Quit; + } + + /* Allocate an APC */ + Apc = ExAllocatePoolWithTag(NonPagedPool | + POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, + sizeof(KAPC), + TAG_PS_APC); + if (!Apc) + { + /* Fail */ + Status = STATUS_NO_MEMORY; + goto Quit; + } + + /* Initialize the APC */ + KeInitializeApc(Apc, + &Thread->Tcb, + OriginalApcEnvironment, + PspQueueApcSpecialApc, + NULL, + ApcRoutine, + UserMode, + NormalContext); + + /* Queue it */ + if (!KeInsertQueueApc(Apc, + SystemArgument1, + SystemArgument2, + IO_NO_INCREMENT)) + { + /* We failed, free it */ + ExFreePool(Apc); + Status = STATUS_UNSUCCESSFUL; + } + + /* Dereference Thread and Return */ +Quit: + ObDereferenceObject(Thread); + return Status; +} + /* EOF */ From 4b35027c0f82081813e73b7a21c0f4cf117a6bd3 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 01:30:24 +0000 Subject: [PATCH 137/488] - Cleanup RepairList, KiMoveApcState. - Fixup comments for KeAreApcsDisabled. - Implement and add comment header to KeAreAllApcsDisabled. svn path=/trunk/; revision=24052 --- reactos/ntoskrnl/ke/apc.c | 94 ++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 52ab295f300..86419bd0f7d 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -472,27 +472,30 @@ Quickie: return; } -static __inline -VOID RepairList(PLIST_ENTRY Original, - PLIST_ENTRY Copy, - KPROCESSOR_MODE Mode) +FORCEINLINE +VOID +RepairList(IN PLIST_ENTRY Original, + IN PLIST_ENTRY Copy, + IN KPROCESSOR_MODE Mode) { - /* Copy Source to Desination */ - if (IsListEmpty(&Original[(int)Mode])) { - - InitializeListHead(&Copy[(int)Mode]); - - } else { - - Copy[(int)Mode].Flink = Original[(int)Mode].Flink; - Copy[(int)Mode].Blink = Original[(int)Mode].Blink; - Original[(int)Mode].Flink->Blink = &Copy[(int)Mode]; - Original[(int)Mode].Blink->Flink = &Copy[(int)Mode]; + /* Check if the list for this mode is empty */ + if (IsListEmpty(&Original[Mode])) + { + /* It is, all we need to do is initialize it */ + InitializeListHead(&Copy[Mode]); + } + else + { + /* Copy the lists */ + Copy[Mode].Flink = Original[Mode].Flink; + Copy[Mode].Blink = Original[Mode].Blink; + Original[Mode].Flink->Blink = &Copy[Mode]; + Original[Mode].Blink->Flink = &Copy[Mode]; } } VOID -STDCALL +NTAPI KiMoveApcState(PKAPC_STATE OldState, PKAPC_STATE NewState) { @@ -832,33 +835,62 @@ KeRemoveQueueApc(PKAPC Apc) } /*++ - * KeAreApcsDisabled + * @name KeAreApcsDisabled * @implemented NT4 * - * Prepares the Context for a User-Mode APC called through NTDLL.DLL + * The KeAreApcsDisabled routine returns whether kernel APC delivery is + * disabled for the current thread. * - * Params: - * None. + * @param None. * - * Returns: - * KeAreApcsDisabled returns TRUE if the thread is within a critical region - * or a guarded region, and FALSE otherwise. + * @return KeAreApcsDisabled returns TRUE if the thread is within a critical + * region or a guarded region, and FALSE otherwise. * - * Remarks: - * A thread running at IRQL = PASSIVE_LEVEL can use KeAreApcsDisabled to - * determine if normal kernel APCs are disabled. A thread that is inside a - * critical region has both user APCs and normal kernel APCs disabled, but - * not special kernel APCs. A thread that is inside a guarded region has - * all APCs disabled, including special kernel APCs. + * @remarks A thread running at IRQL = PASSIVE_LEVEL can use KeAreApcsDisabled + * determine if normal kernel APCs are disabled. * - * Callers of this routine must be running at IRQL <= APC_LEVEL. + * A thread that is inside critical region has both user APCs and + * normal kernel APCs disabled, but not special kernel APCs. + * + * A thread that is inside a guarded region has all APCs disabled, + * including special kernel APCs. + * + * Callers of this routine must be running at IRQL <= DISPATCH_LEVEL. * *--*/ BOOLEAN -STDCALL +NTAPI KeAreApcsDisabled(VOID) { /* Return the Kernel APC State */ return KeGetCurrentThread()->CombinedApcDisable ? TRUE : FALSE; } +/*++ + * @name KeAreAllApcsDisabled + * @implemented NT5.1 + * + * The KeAreAllApcsDisabled routine returns whether the calling thread is + * inside a guarded region or running at IRQL = APC_LEVEL, which disables + * all APC delivery. + * + * @param None. + * + * @return KeAreAllApcsDisabled returns TRUE if the thread is within a guarded + * guarded region or running at IRQL >= APC_LEVEL, and FALSE otherwise. + * + * @remarks A thread running at IRQL = PASSIVE_LEVEL can use this routine to + * determine if all APCs delivery is disabled. + * + * Callers of this routine must be running at IRQL <= DISPATCH_LEVEL. + * + *--*/ +BOOLEAN +NTAPI +KeAreAllApcsDisabled(VOID) +{ + /* Return the Special APC State */ + return ((KeGetCurrentThread()->SpecialApcDisable) || + (KeGetCurrentIrql() >= APC_LEVEL)) ? TRUE : FALSE; +} + From 43a412db60279634030df7ad271a2afea51067a8 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 01:45:11 +0000 Subject: [PATCH 138/488] - Add ASSERT_APC definition. - Fix KeRemoveQueueApc comment header and clean up function. - Acquire dispatcher lock at DPC level during ApcListEntry read/write. svn path=/trunk/; revision=24053 --- reactos/include/ddk/winddk.h | 9 ++++--- reactos/ntoskrnl/ke/apc.c | 46 ++++++++++++++++++++++-------------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index e9695a694ff..3e43a6095d1 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -1085,9 +1085,12 @@ typedef struct _KLOCK_QUEUE_HANDLE { #define DPC_NORMAL 0 #define DPC_THREADED 1 -#define ASSERT_DPC(Object) \ - ASSERT(((Object)->Type == 0) || \ - ((Object)->Type == DpcObject) || \ +#define ASSERT_APC(Object) \ + ASSERT((Object)->Type == ApcObject) + +#define ASSERT_DPC(Object) \ + ASSERT(((Object)->Type == 0) || \ + ((Object)->Type == DpcObject) || \ ((Object)->Type == ThreadedDpcObject)) typedef struct _KDPC diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 86419bd0f7d..bd48f21c5fa 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -774,59 +774,69 @@ KeFlushQueueApc(IN PKTHREAD Thread, } /*++ - * KeRemoveQueueApc + * @name KeRemoveQueueApc + * @implemented NT4 * * The KeRemoveQueueApc routine removes a given APC object from the system * APC queue. * - * Params: - * APC - Pointer to an initialized APC object that was queued by calling - * KeInsertQueueApc. + * @params Apc + * Pointer to an initialized APC object that was queued by calling + * KeInsertQueueApc. * - * Returns: - * TRUE if the APC Object is in the APC Queue. If it isn't, no operation is - * performed and FALSE is returned. + * @return TRUE if the APC Object is in the APC Queue. Otherwise, no operation + * is performed and FALSE is returned. * - * Remarks: - * If the given APC Object is currently queued, it is removed from the queue - * and any calls to the registered routines are cancelled. + * @remarks If the given APC Object is currently queued, it is removed from the + * queue and any calls to the registered routines are cancelled. * - * Callers of KeLeaveCriticalRegion can be running at any IRQL. + * Callers of this routine must be running at IRQL <= DISPATCH_LEVEL. * *--*/ BOOLEAN -STDCALL -KeRemoveQueueApc(PKAPC Apc) +NTAPI +KeRemoveQueueApc(IN PKAPC Apc) { PKTHREAD Thread = Apc->Thread; PKAPC_STATE ApcState; BOOLEAN Inserted; KLOCK_QUEUE_HANDLE ApcLock; + ASSERT_APC(Apc); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Get the APC lock */ KiAcquireApcLock(Thread, &ApcLock); /* Check if it's inserted */ - if ((Inserted = Apc->Inserted)) + Inserted = Apc->Inserted; + if (Inserted) { - /* Remove it from the Queue*/ + /* Set it as non-inserted and get the APC state */ Apc->Inserted = FALSE; - ApcState = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]; + ApcState = Thread->ApcStatePointer[(SCHAR)Apc->ApcStateIndex]; + + /* Acquire the dispatcher lock and remove it from the list */ + KiAcquireDispatcherLockAtDpcLevel(); RemoveEntryList(&Apc->ApcListEntry); /* If the Queue is completely empty, then no more APCs are pending */ - if (IsListEmpty(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode])) + if (IsListEmpty(&ApcState->ApcListHead[Apc->ApcMode])) { - /* Set the correct State based on the Apc Mode */ + /* Set the correct state based on the APC Mode */ if (Apc->ApcMode == KernelMode) { + /* No more pending kernel APCs */ ApcState->KernelApcPending = FALSE; } else { + /* No more pending user APCs */ ApcState->UserApcPending = FALSE; } } + + /* Release dispatcher lock */ + KiReleaseDispatcherLockFromDpcLevel(); } /* Release the lock and return */ From c9607ffe8942e641cd920b8a12d402c44fbeedfd Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 02:09:13 +0000 Subject: [PATCH 139/488] - Fix for Windows Kernel APC Data-Free Local Privilege Escalation Vulnerability (re-initialize the list head after cleaning it, so that the list is circular). - Optimize KeFlushQueueApc: we can check if the Kernel-Mode APC list is empty without acquiring the lock. If it's empty, we can quit immediately, if not, then we'll acquire and check it again. For user APCs we always need to acquire the lock, though. svn path=/trunk/; revision=24054 --- reactos/ntoskrnl/ke/apc.c | 55 ++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index bd48f21c5fa..5a1ad02d8d2 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -742,31 +742,72 @@ KeInsertQueueApc(PKAPC Apc, * *--*/ PLIST_ENTRY -STDCALL +NTAPI KeFlushQueueApc(IN PKTHREAD Thread, IN KPROCESSOR_MODE PreviousMode) { PKAPC Apc; PLIST_ENTRY FirstEntry, CurrentEntry; KLOCK_QUEUE_HANDLE ApcLock; + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - /* Get the APC lock */ - KiAcquireApcLock(Thread, &ApcLock); + /* Check if this was user mode */ + if (PreviousMode == UserMode) + { + /* Get the APC lock */ + KiAcquireApcLock(Thread, &ApcLock); - if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) { + /* Select user list and check if it's empty */ + if (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) + { + /* Don't return anything */ + FirstEntry = NULL; + goto FlushDone; + } + } + else + { + /* Select kernel list and check if it's empty */ + if (IsListEmpty( &Thread->ApcState.ApcListHead[KernelMode])) + { + /* Don't return anything */ + return NULL; + } + + /* Otherwise, acquire the APC lock */ + KiAcquireApcLock(Thread, &ApcLock); + } + + /* Get the first entry and check if the list is empty now */ + FirstEntry = Thread->ApcState.ApcListHead[PreviousMode].Flink; + if (FirstEntry == &Thread->ApcState.ApcListHead[PreviousMode]) + { + /* It is, clear the returned entry */ FirstEntry = NULL; - } else { - FirstEntry = Thread->ApcState.ApcListHead[PreviousMode].Flink; + } + else + { + /* It's not, remove the first entry */ RemoveEntryList(&Thread->ApcState.ApcListHead[PreviousMode]); + + /* Loop all the entries */ CurrentEntry = FirstEntry; - do { + do + { + /* Get the APC and make it un-inserted */ Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry); Apc->Inserted = FALSE; + + /* Get the next entry */ CurrentEntry = CurrentEntry->Flink; } while (CurrentEntry != FirstEntry); + + /* Re-initialize the list */ + InitializeListHead(&Thread->ApcState.ApcListHead[PreviousMode]); } /* Release the lock */ +FlushDone: KiReleaseApcLock(&ApcLock); /* Return the first entry */ From 8b90aed6bed78ea74e6b87784b4936ac5a3bce0f Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 02:17:57 +0000 Subject: [PATCH 140/488] - Fix comment headers for KeFlushQueueApc, KeInsertQueueApc. - ASSERTify KeInsertQueueApc and some formatting fixes. svn path=/trunk/; revision=24055 --- reactos/ntoskrnl/ke/apc.c | 60 +++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 5a1ad02d8d2..de25ef04b1a 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -658,48 +658,49 @@ KeInitializeApc(IN PKAPC Apc, } /*++ - * KeInsertQueueApc + * @name KeInsertQueueApc * @implemented NT4 * * The KeInsertQueueApc routine queues a APC for execution when the right * scheduler environment exists. * - * Params: - * Apc - Pointer to an initialized control object of type DPC for which the - * caller provides the storage. + * @param Apc + * Pointer to an initialized control object of type DPC for which the + * caller provides the storage. * - * SystemArgument[1,2] - Pointer to a set of two parameters that contain - * untyped data. + * @param SystemArgument[1,2] + * Pointer to a set of two parameters that contain untyped data. * - * PriorityBoost - Priority Boost to apply to the Thread. + * @param PriorityBoost + * Priority Boost to apply to the Thread. * - * Returns: - * If the APC is already inserted or APC queueing is disabled, FALSE. - * Otherwise, TRUE. + * @return If the APC is already inserted or APC queueing is disabled, FALSE. + * Otherwise, TRUE. * - * Remarks: - * The APC will execute at APC_LEVEL for the KernelRoutine registered, and - * at PASSIVE_LEVEL for the NormalRoutine registered. + * @remarks The APC will execute at APC_LEVEL for the KernelRoutine registered, + * and at PASSIVE_LEVEL for the NormalRoutine registered. * - * Callers of this routine must be running at IRQL = PASSIVE_LEVEL. + * Callers of this routine must be running at IRQL <= DISPATCH_LEVEL. * *--*/ BOOLEAN -STDCALL -KeInsertQueueApc(PKAPC Apc, - PVOID SystemArgument1, - PVOID SystemArgument2, - KPRIORITY PriorityBoost) +NTAPI +KeInsertQueueApc(IN PKAPC Apc, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2, + IN KPRIORITY PriorityBoost) { PKTHREAD Thread = Apc->Thread; KLOCK_QUEUE_HANDLE ApcLock; BOOLEAN State = TRUE; + ASSERT_APC(Apc); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Get the APC lock */ KiAcquireApcLock(Thread, &ApcLock); /* Make sure we can Queue APCs and that this one isn't already inserted */ - if ((Thread->ApcQueueable == FALSE) && (Apc->Inserted == TRUE)) + if (!(Thread->ApcQueueable) && (Apc->Inserted)) { /* Fail */ State = FALSE; @@ -722,23 +723,22 @@ KeInsertQueueApc(PKAPC Apc, } /*++ - * KeFlushQueueApc + * @name KeFlushQueueApc + * @implemented NT4 * * The KeFlushQueueApc routine flushes all APCs of the given processor mode * from the specified Thread's APC queue. * - * Params: - * Thread - Pointer to the thread whose APC queue will be flushed. + * @param Thread + * Pointer to the thread whose APC queue will be flushed. * - * PreviousMode - Specifies which APC Queue to flush. + * @paramt PreviousMode + * Specifies which APC Queue to flush. * - * Returns: - * A pointer to the first entry in the flushed APC queue. + * @return A pointer to the first entry in the flushed APC queue. * - * Remarks: - * If the routine returns NULL, it means that no APCs were to be flushed. - * - * Callers of KeFlushQueueApc must be running at DISPATCH_LEVEL or lower. + * @remarks If the routine returns NULL, it means that no APCs were flushed. + * Callers of this routine must be running at DISPATCH_LEVEL or lower. * *--*/ PLIST_ENTRY From 90a7bca11283199270abacdcb53232513bf9343e Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 02:28:09 +0000 Subject: [PATCH 141/488] - Add new KAPC_ENVIRONMENT mode: InsertApcEnvironment. - Fixup KeInitalizeApc like all the other functions. - Don't use an expensive 48-byte RtlZeroMemory instead of just clearing two members. svn path=/trunk/; revision=24056 --- reactos/include/ndk/ketypes.h | 3 +- reactos/ntoskrnl/ke/apc.c | 96 +++++++++++++++++++---------------- 2 files changed, 54 insertions(+), 45 deletions(-) diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index 982b8955715..07a1cabbdfd 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -473,7 +473,8 @@ typedef enum _KAPC_ENVIRONMENT { OriginalApcEnvironment, AttachedApcEnvironment, - CurrentApcEnvironment + CurrentApcEnvironment, + InsertApcEnvironment } KAPC_ENVIRONMENT; // diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index de25ef04b1a..edd43dcf5aa 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -570,46 +570,45 @@ _KeLeaveCriticalRegion(VOID) * The The KeInitializeApc routine initializes an APC object, and registers * the Kernel, Rundown and Normal routines for that object. * - * Params: - * Apc - Pointer to a KAPC structure that represents the APC object to - * initialize. The caller must allocate storage for the structure - * from resident memory. + * @param Apc + * Pointer to a KAPC structure that represents the APC object to + * initialize. The caller must allocate storage for the structure + * from resident memory. * - * Thread - Thread to which to deliver the APC. + * @param Thread + * Thread to which to deliver the APC. * - * TargetEnvironment - APC Environment to be used. + * @param TargetEnvironment + * APC Environment to be used. * - * KernelRoutine - Points to the KernelRoutine to associate with the APC. - * This routine is executed for all APCs. + * @param KernelRoutine + * Points to the KernelRoutine to associate with the APC. + * This routine is executed for all APCs. * - * RundownRoutine - Points to the RundownRoutine to associate with the APC. - * This routine is executed when the Thread exists with - * the APC executing. + * @param RundownRoutine + * Points to the RundownRoutine to associate with the APC. + * This routine is executed when the Thread exists during APC execution. * - * NormalRoutine - Points to the NormalRoutine to associate with the APC. - * This routine is executed at PASSIVE_LEVEL. If this is - * not specifed, the APC becomes a Special APC and the - * Mode and Context parameters are ignored. + * @param NormalRoutine + * Points to the NormalRoutine to associate with the APC. + * This routine is executed at PASSIVE_LEVEL. If this is not specifed, + * the APC becomes a Special APC and the Mode and Context parameters are + * ignored. * - * Mode - Specifies the processor mode at which to run the Normal Routine. + * @param Mode + * Specifies the processor mode at which to run the Normal Routine. * - * Context - Specifices the value to pass as Context parameter to the - * registered routines. + * @param Context + * Specifices the value to pass as Context parameter to the registered + * routines. * - * Returns: - * None. + * @return None. * - * Remarks: - * The caller can queue an initialized APC with KeInsertQueueApc. - * - * Storage for the APC object must be resident, such as nonpaged pool - * allocated by the caller. - * - * Callers of this routine must be running at IRQL = PASSIVE_LEVEL. + * @remarks The caller can queue an initialized APC with KeInsertQueueApc. * *--*/ VOID -STDCALL +NTAPI KeInitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT TargetEnvironment, @@ -619,23 +618,26 @@ KeInitializeApc(IN PKAPC Apc, IN KPROCESSOR_MODE Mode, IN PVOID Context) { - DPRINT("KeInitializeApc(Apc %x, Thread %x, Environment %d, " - "KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, " - "Context %x)\n",Apc,Thread,TargetEnvironment,KernelRoutine,RundownRoutine, - NormalRoutine,Mode,Context); + /* Sanity check */ + ASSERT(TargetEnvironment <= InsertApcEnvironment); /* Set up the basic APC Structure Data */ - RtlZeroMemory(Apc, sizeof(KAPC)); Apc->Type = ApcObject; Apc->Size = sizeof(KAPC); /* Set the Environment */ - if (TargetEnvironment == CurrentApcEnvironment) { - + if (TargetEnvironment == CurrentApcEnvironment) + { + /* Use the current one for the thread */ Apc->ApcStateIndex = Thread->ApcStateIndex; + } + else + { + /* Sanity check */ + ASSERT((TargetEnvironment <= Thread->ApcStateIndex) || + (TargetEnvironment == InsertApcEnvironment)); - } else { - + /* Use the one that was given */ Apc->ApcStateIndex = TargetEnvironment; } @@ -645,16 +647,22 @@ KeInitializeApc(IN PKAPC Apc, Apc->RundownRoutine = RundownRoutine; Apc->NormalRoutine = NormalRoutine; - /* Check if this is a Special APC, in which case we use KernelMode and no Context */ - if (ARGUMENT_PRESENT(NormalRoutine)) { - + /* Check if this is a special APC */ + if (NormalRoutine) + { + /* It's a normal one. Set the context and mode */ Apc->ApcMode = Mode; Apc->NormalContext = Context; - - } else { - - Apc->ApcMode = KernelMode; } + else + { + /* It's a special APC, which can only be kernel mode */ + Apc->ApcMode = KernelMode; + Apc->NormalContext = NULL; + } + + /* The APC is not inserted*/ + Apc->Inserted = FALSE; } /*++ From 52b3dfb608655de66575951aaa324c11b18f533a Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 02:30:38 +0000 Subject: [PATCH 142/488] - Fix stupid typo. svn path=/trunk/; revision=24057 --- reactos/ntoskrnl/ntoskrnl.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index f668f690d77..b649232d783 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -534,7 +534,7 @@ KeDeregisterBugCheckCallback@4 KeDeregisterBugCheckReasonCallback@4 KeDetachProcess@0 KeDisconnectInterrupt@4 -KeEnterCriticalRegion@=_KeEnterCriticalRegion@0 +KeEnterCriticalRegion@0=_KeEnterCriticalRegion@0 KeEnterGuardedRegion@0 KeEnterKernelDebugger@0 KeFindConfigurationEntry@16 From d011801cefad59379c642fc0b1e894c2b9a752b2 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 03:14:26 +0000 Subject: [PATCH 143/488] - Fix lock acquisition/release mismathces in KiInsertQueueApc. - Support and document InsertApcEnvironment KAPC_ENVIRONMENT type. - Fixup formatting and ASSERTify. - Acquire dispatcher lock when insereting an APC into another thread. - Use delayed interrupt request on SMP systems (and fixup KiRequestApcInterrupt accordingly). svn path=/trunk/; revision=24058 --- reactos/ntoskrnl/include/internal/ke_x.h | 32 ++++--- reactos/ntoskrnl/ke/apc.c | 106 +++++++++++++---------- 2 files changed, 78 insertions(+), 60 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 9c193e9b06f..31cab53421f 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -430,10 +430,12 @@ KiRundownThread(IN PKTHREAD Thread) FORCEINLINE VOID -KiRequestApcInterrupt(IN UCHAR Processor) +KiRequestApcInterrupt(IN BOOLEAN NeedApc, + IN UCHAR Processor) { - /* Request a software interrupt */ - HalRequestSoftwareInterrupt(APC_LEVEL); + /* We deliver instantly on UP */ + UNREFERENCED_PARAMETER(NeedApc); + UNREFERENCED_PARAMETER(Processor); } #else @@ -604,17 +606,23 @@ KiCheckDeferredReadyList(IN PKPRCB Prcb) FORCEINLINE VOID -KiRequestApcInterrupt(IN UCHAR Processor) +KiRequestApcInterrupt(IN BOOLEAN NeedApc, + IN UCHAR Processor) { - /* Check if we're on the same CPU */ - if (KeGetCurrentPrcb()->Number == Processor) + /* Check if we need to request APC delivery */ + if (NeedApc) { - /* Request a software interrupt */ - HalRequestSoftwareInterrupt(APC_LEVEL); - } - else - { - KiIpiSendRequest(KeGetCurrentPrcb()->SetMember, IPI_APC); + /* Check if it's on another CPU */ + if (KeGetPcr()->Number != Cpu) + { + /* Send an IPI to request delivery */ + KiIpiSendRequest(AFFINITY_MASK(Cpu), IPI_DPC); + } + else + { + /* Request a software interrupt */ + HalRequestSoftwareInterrupt(APC_LEVEL); + } } } diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index edd43dcf5aa..5629b2b6632 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -81,8 +81,8 @@ KiCheckForKernelApcDelivery(VOID) *--*/ VOID FASTCALL -KiInsertQueueApc(PKAPC Apc, - KPRIORITY PriorityBoost) +KiInsertQueueApc(IN PKAPC Apc, + IN KPRIORITY PriorityBoost) { PKTHREAD Thread = Apc->Thread; PKAPC_STATE ApcState; @@ -90,23 +90,25 @@ KiInsertQueueApc(PKAPC Apc, PLIST_ENTRY ListHead, NextEntry; PKAPC QueuedApc; NTSTATUS Status; + BOOLEAN RequestInterrupt; - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - - /* Acquire the lock (only needed on MP) */ - KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock); - - /* Little undocumented feature: Special Apc State Index */ - if (Apc->ApcStateIndex == 3) + /* + * Check if the caller wanted this APC to use the thread's environment at + * insertion time. + */ + if (Apc->ApcStateIndex == InsertApcEnvironment) { - /* This tells us to use the thread's */ + /* Copy it over */ Apc->ApcStateIndex = Thread->ApcStateIndex; } /* Get the APC State for this Index, and the mode too */ - ApcState = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]; + ApcState = Thread->ApcStatePointer[(UCHAR)Apc->ApcStateIndex]; ApcMode = Apc->ApcMode; + /* The APC must be "inserted" already */ + ASSERT(Apc->Inserted == TRUE); + /* Three scenarios: * 1) Kernel APC with Normal Routine or User APC = Put it at the end of the List * 2) User APC which is PsExitSpecialApc = Put it at the front of the List @@ -115,26 +117,21 @@ KiInsertQueueApc(PKAPC Apc, if (Apc->NormalRoutine) { /* Normal APC; is it the Thread Termination APC? */ - if ((ApcMode != KernelMode) && (Apc->KernelRoutine == PsExitSpecialApc)) + if ((ApcMode != KernelMode) && + (Apc->KernelRoutine == PsExitSpecialApc)) { /* Set User APC pending to true */ Thread->ApcState.UserApcPending = TRUE; /* Insert it at the top of the list */ - InsertHeadList(&ApcState->ApcListHead[ApcMode], &Apc->ApcListEntry); - - /* Display debug message */ - DPRINT("Inserted the Thread Exit APC for '%.16s' into the Queue\n", - ((PETHREAD)Thread)->ThreadsProcess->ImageFileName); + InsertHeadList(&ApcState->ApcListHead[ApcMode], + &Apc->ApcListEntry); } else { /* Regular user or kernel Normal APC */ - InsertTailList(&ApcState->ApcListHead[ApcMode], &Apc->ApcListEntry); - - /* Display debug message */ - DPRINT("Inserted Normal APC for '%.16s' into the Queue\n", - ((PETHREAD)Thread)->ThreadsProcess->ImageFileName); + InsertTailList(&ApcState->ApcListHead[ApcMode], + &Apc->ApcListEntry); } } else @@ -159,8 +156,6 @@ KiInsertQueueApc(PKAPC Apc, /* Insert us here */ InsertHeadList(NextEntry, &Apc->ApcListEntry); - DPRINT("Inserted Special APC for '%.16s' into the Queue\n", - ((PETHREAD)Thread)->ThreadsProcess->ImageFileName); } /* Now check if the Apc State Indexes match */ @@ -169,6 +164,9 @@ KiInsertQueueApc(PKAPC Apc, /* Check that if the thread matches */ if (Thread == KeGetCurrentThread()) { + /* Sanity check */ + ASSERT(Thread->State == Running); + /* Check if this is kernel mode */ if (ApcMode == KernelMode) { @@ -176,7 +174,7 @@ KiInsertQueueApc(PKAPC Apc, Thread->ApcState.KernelApcPending = TRUE; /* Check if Special APCs are disabled */ - if (Thread->SpecialApcDisable == 0) + if (!Thread->SpecialApcDisable) { /* They're not, so request the interrupt */ HalRequestSoftwareInterrupt(APC_LEVEL); @@ -185,20 +183,23 @@ KiInsertQueueApc(PKAPC Apc, } else { + /* Acquire the dispatcher lock */ + KiAcquireDispatcherLock(); + /* Check if this is a non-kernel mode APC */ if (ApcMode != KernelMode) { - /* Not a Kernel-Mode APC. Are we waiting in user-mode? */ - if ((Thread->State == Waiting) && (Thread->WaitMode == UserMode)) + /* + * Not a Kernel-Mode APC. Are we waiting in user-mode? + * If so, then are we alertable or already have an APC pending? + */ + if (((Thread->State == Waiting) && (Thread->WaitMode == UserMode)) && + ((Thread->Alertable) || (Thread->ApcState.UserApcPending))) { - /* The thread is waiting. Are we alertable, or is an APC pending */ - if ((Thread->Alertable) || (Thread->ApcState.UserApcPending)) - { - /* Set user-mode APC pending */ - Thread->ApcState.UserApcPending = TRUE; - Status = STATUS_USER_APC; - goto Unwait; - } + /* Set user-mode APC pending */ + Thread->ApcState.UserApcPending = TRUE; + Status = STATUS_USER_APC; + goto Unwait; } } else @@ -209,8 +210,12 @@ KiInsertQueueApc(PKAPC Apc, /* Are we currently running? */ if (Thread->State == Running) { - /* The thread is running, so send an APC request */ - KiRequestApcInterrupt(Thread->NextProcessor); + /* The thread is running, so remember to send a request */ + RequestInterrupt = TRUE; +#ifndef CONFIG_SMP + /* On UP systems, request it immediately */ + HalRequestSoftwareInterrupt(APC_LEVEL); +#endif } else { @@ -225,31 +230,36 @@ KiInsertQueueApc(PKAPC Apc, */ if ((Thread->State == Waiting) && (Thread->WaitIrql == PASSIVE_LEVEL) && - (!Thread->SpecialApcDisable) && - ((!Apc->NormalRoutine) || - ((!Thread->KernelApcDisable) && - (!Thread->ApcState.KernelApcInProgress)))) + !(Thread->SpecialApcDisable) && + (!(Apc->NormalRoutine) || + (!(Thread->KernelApcDisable) && + !(Thread->ApcState.KernelApcInProgress)))) { /* We'll unwait with this status */ Status = STATUS_KERNEL_APC; /* Wake up the thread */ Unwait: - DPRINT("Waking up Thread for %lx Delivery \n", Status); KiAbortWaitThread(Thread, Status, PriorityBoost); } else { - /* FIXME: Handle deferred ready sometime far far in the future */ + /* Check if the thread is in a deferred ready state */ + if (Thread->State == DeferredReady) + { + /* FIXME: TODO in new scheduler */ + } } } } + + /* Release dispatcher lock */ + KiReleaseDispatcherLockFromDpcLevel(); + + /* Check if an interrupt was requested */ + KiRequestApcInterrupt(RequestInterrupt, Thread->NextProcessor); } } - - /* Return to caller */ - KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock); - return; } /*++ @@ -862,7 +872,7 @@ KeRemoveQueueApc(IN PKAPC Apc) { /* Set it as non-inserted and get the APC state */ Apc->Inserted = FALSE; - ApcState = Thread->ApcStatePointer[(SCHAR)Apc->ApcStateIndex]; + ApcState = Thread->ApcStatePointer[(UCHAR)Apc->ApcStateIndex]; /* Acquire the dispatcher lock and remove it from the list */ KiAcquireDispatcherLockAtDpcLevel(); From 8028be67cbf80b5a393c59d5efb6bf5760c36d78 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 04:34:25 +0000 Subject: [PATCH 144/488] - Fix KiDeliverApc prototype for PPC compatibilty. - Fixup comment header for KiDeliverApc and KiInsertQueueApc. - Set APC trap frame during APC delivery. We actually weren't doing this before (I'm kind of amazed at ROS's previous functionality due to importance of this bug!). - Use proper in-stack queued spinlock mechanisms. - Make sure that the Kernel APC list didn't become empty while we acquired the APC lock after the first verification. - Validate IRQL on return from APC routines, to catch bad code. svn path=/trunk/; revision=24059 --- reactos/include/ndk/kefuncs.h | 2 +- reactos/ntoskrnl/include/internal/ke.h | 8 -- reactos/ntoskrnl/include/internal/ke_x.h | 9 ++ reactos/ntoskrnl/ke/apc.c | 153 +++++++++++++---------- reactos/ntoskrnl/ntoskrnl.mc | 11 ++ 5 files changed, 105 insertions(+), 78 deletions(-) diff --git a/reactos/include/ndk/kefuncs.h b/reactos/include/ndk/kefuncs.h index c55c87ed572..2174cfcc4c7 100644 --- a/reactos/include/ndk/kefuncs.h +++ b/reactos/include/ndk/kefuncs.h @@ -47,7 +47,7 @@ VOID NTAPI KiDeliverApc( IN KPROCESSOR_MODE PreviousMode, - IN PVOID Reserved, + IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame ); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 166a0b82887..eb14eca4f74 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -541,14 +541,6 @@ KeContextToTrapFrame( KPROCESSOR_MODE PreviousMode ); -VOID -NTAPI -KiDeliverApc( - KPROCESSOR_MODE PreviousMode, - PVOID Reserved, - PKTRAP_FRAME TrapFrame -); - VOID NTAPI KiCheckForKernelApcDelivery(VOID); diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 31cab53421f..db2e030f994 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -646,6 +646,15 @@ KiAcquireApcLockAtDpcLevel(IN PKTHREAD Thread, KeAcquireInStackQueuedSpinLockAtDpcLevel(&Thread->ApcQueueLock, Handle); } +FORCEINLINE +VOID +KiAcquireApcLockAtApcLevel(IN PKTHREAD Thread, + IN PKLOCK_QUEUE_HANDLE Handle) +{ + /* Acquire the lock */ + KeAcquireInStackQueuedSpinLock(&Thread->ApcQueueLock, Handle); +} + FORCEINLINE VOID KiReleaseApcLock(IN PKLOCK_QUEUE_HANDLE Handle) diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 5629b2b6632..00a0851616e 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -58,25 +58,24 @@ KiCheckForKernelApcDelivery(VOID) } /*++ - * KiInsertQueueApc + * @name KiInsertQueueApc * * The KiInsertQueueApc routine queues a APC for execution when the right * scheduler environment exists. * - * Params: - * Apc - Pointer to an initialized control object of type DPC for which the - * caller provides the storage. + * @param Apc + * Pointer to an initialized control object of type DPC for which the + * caller provides the storage. * - * PriorityBoost - Priority Boost to apply to the Thread. + * @param PriorityBoost + * Priority Boost to apply to the Thread. * - * Returns: - * None + * @return None * - * Remarks: - * The APC will execute at APC_LEVEL for the KernelRoutine registered, and - * at PASSIVE_LEVEL for the NormalRoutine registered. + * @remarks The APC will execute at APC_LEVEL for the KernelRoutine registered, + * and at PASSIVE_LEVEL for the NormalRoutine registered. * - * Callers of this routine must have locked the dipatcher database. + * Callers of this routine must have locked the dipatcher database. * *--*/ VOID @@ -263,43 +262,42 @@ Unwait: } /*++ - * KiDeliverApc + * @name KiDeliverApc * @implemented @NT4 * * The KiDeliverApc routine is called from IRQL switching code if the * thread is returning from an IRQL >= APC_LEVEL and Kernel-Mode APCs are * pending. * - * Params: - * DeliveryMode - Specifies the current processor mode. + * @param DeliveryMode + * Specifies the current processor mode. * - * Reserved - Pointer to the Exception Frame on non-i386 builds. + * @param ExceptionFrame + * Pointer to the Exception Frame on non-i386 builds. * - * TrapFrame - Pointer to the Trap Frame. + * @param TrapFrame + * Pointer to the Trap Frame. * - * Returns: - * None. + * @return None. * - * Remarks: - * First, Special APCs are delivered, followed by Kernel-Mode APCs and - * User-Mode APCs. Note that the TrapFrame is only valid if the previous - * mode is User. - * - * Upon entry, this routine executes at APC_LEVEL. + * @remarks First, Special APCs are delivered, followed by Kernel-Mode APCs and + * User-Mode APCs. Note that the TrapFrame is only valid if the + * delivery mode is User-Mode. + * Upon entry, this routine executes at APC_LEVEL. * *--*/ VOID -STDCALL -KiDeliverApc(KPROCESSOR_MODE DeliveryMode, - PVOID Reserved, - PKTRAP_FRAME TrapFrame) +NTAPI +KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PKTRAP_FRAME TrapFrame) { PKTHREAD Thread = KeGetCurrentThread(); PKPROCESS Process = Thread->ApcState.Process; PKTRAP_FRAME OldTrapFrame; PLIST_ENTRY ApcListEntry; PKAPC Apc; - KIRQL OldIrql; + KLOCK_QUEUE_HANDLE ApcLock; PKKERNEL_ROUTINE KernelRoutine; PVOID NormalContext; PKNORMAL_ROUTINE NormalRoutine; @@ -307,20 +305,29 @@ KiDeliverApc(KPROCESSOR_MODE DeliveryMode, PVOID SystemArgument2; ASSERT_IRQL_EQUAL(APC_LEVEL); - /* Save the old trap frame */ + /* Save the old trap frame and set current one */ OldTrapFrame = Thread->TrapFrame; + Thread->TrapFrame = TrapFrame; /* Clear Kernel APC Pending */ Thread->ApcState.KernelApcPending = FALSE; /* Check if Special APCs are disabled */ - if (Thread->SpecialApcDisable != 0) goto Quickie; + if (Thread->SpecialApcDisable) goto Quickie; /* Do the Kernel APCs first */ while (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) { - /* Lock the APC Queue and Raise IRQL to Synch */ - KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql); + /* Lock the APC Queue */ + KiAcquireApcLockAtApcLevel(Thread, &ApcLock); + + /* Check if the list became empty now */ + if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) + { + /* It is, release the lock and break out */ + KiReleaseApcLock(&ApcLock); + break; + } /* Get the next Entry */ ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink; @@ -340,33 +347,35 @@ KiDeliverApc(KPROCESSOR_MODE DeliveryMode, RemoveEntryList(ApcListEntry); Apc->Inserted = FALSE; - /* Go back to APC_LEVEL */ - KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql); + /* Rrelease the APC lock */ + KiReleaseApcLock(&ApcLock); /* Call the Special APC */ - DPRINT("Delivering a Special APC: %x\n", Apc); KernelRoutine(Apc, &NormalRoutine, &NormalContext, &SystemArgument1, &SystemArgument2); + + /* Make sure it returned correctly */ + if (KeGetCurrentIrql() != ApcLock.OldIrql) + { + KeBugCheckEx(IRQL_UNEXPECTED_VALUE, + (KeGetCurrentIrql() << 16) | + (ApcLock.OldIrql << 8), + (ULONG_PTR)KernelRoutine, + (ULONG_PTR)Apc, + (ULONG_PTR)NormalRoutine); + } } else { - /* Normal Kernel APC, make sur APCs aren't disabled or in progress*/ + /* Normal Kernel APC, make sure it's safe to deliver */ if ((Thread->ApcState.KernelApcInProgress) || (Thread->KernelApcDisable)) { - /* - * DeliveryMode must be KernelMode in this case, since one may not - * return to umode while being inside a critical section or while - * a regular kmode apc is running (the latter should be impossible btw). - * -Gunnar - */ - ASSERT(DeliveryMode == KernelMode); - /* Release lock and return */ - KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql); + KiReleaseApcLock(&ApcLock); goto Quickie; } @@ -375,27 +384,36 @@ KiDeliverApc(KPROCESSOR_MODE DeliveryMode, Apc->Inserted = FALSE; /* Go back to APC_LEVEL */ - KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql); + KiReleaseApcLock(&ApcLock); /* Call the Kernel APC */ - DPRINT("Delivering a Normal APC: %x\n", Apc); KernelRoutine(Apc, &NormalRoutine, &NormalContext, &SystemArgument1, &SystemArgument2); - /* If There still is a Normal Routine, then we need to call this at PASSIVE_LEVEL */ + /* Make sure it returned correctly */ + if (KeGetCurrentIrql() != ApcLock.OldIrql) + { + KeBugCheckEx(IRQL_UNEXPECTED_VALUE, + (KeGetCurrentIrql() << 16) | + (ApcLock.OldIrql << 8), + (ULONG_PTR)KernelRoutine, + (ULONG_PTR)Apc, + (ULONG_PTR)NormalRoutine); + } + + /* Check if There still is a Normal Routine */ if (NormalRoutine) { - /* At Passive Level, this APC can be prempted by a Special APC */ + /* At Passive Level, an APC can be prempted by a Special APC */ Thread->ApcState.KernelApcInProgress = TRUE; KeLowerIrql(PASSIVE_LEVEL); /* Call and Raise IRQ back to APC_LEVEL */ - DPRINT("Calling the Normal Routine for a Normal APC: %x\n", Apc); NormalRoutine(NormalContext, SystemArgument1, SystemArgument2); - KeRaiseIrql(APC_LEVEL, &OldIrql); + KeRaiseIrql(APC_LEVEL, &ApcLock.OldIrql); } /* Set Kernel APC in progress to false and loop again */ @@ -405,27 +423,25 @@ KiDeliverApc(KPROCESSOR_MODE DeliveryMode, /* Now we do the User APCs */ if ((DeliveryMode == UserMode) && - (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) && - (Thread->ApcState.UserApcPending == TRUE)) + !(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) && + (Thread->ApcState.UserApcPending)) { - /* Lock the APC Queue and Raise IRQL to Synch */ - KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql); + /* Lock the APC Queue */ + KiAcquireApcLockAtApcLevel(Thread, &ApcLock); /* It's not pending anymore */ Thread->ApcState.UserApcPending = FALSE; - /* Get the APC Entry */ - ApcListEntry = Thread->ApcState.ApcListHead[UserMode].Flink; - - /* Is it empty now? */ - if (ApcListEntry == &Thread->ApcState.ApcListHead[UserMode]) + /* Check if the list became empty now */ + if (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) { - /* Release the lock and return */ - KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql); + /* It is, release the lock and break out */ + KiReleaseApcLock(&ApcLock); goto Quickie; } /* Get the actual APC object */ + ApcListEntry = Thread->ApcState.ApcListHead[UserMode].Flink; Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry); /* Save Parameters so that it's safe to free the Object in Kernel Routine*/ @@ -435,18 +451,19 @@ KiDeliverApc(KPROCESSOR_MODE DeliveryMode, SystemArgument1 = Apc->SystemArgument1; SystemArgument2 = Apc->SystemArgument2; - /* Remove the APC from Queue, restore IRQL and call the APC */ + /* Remove the APC from Queue, and release the lock */ RemoveEntryList(ApcListEntry); Apc->Inserted = FALSE; - KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql); + KiReleaseApcLock(&ApcLock); - DPRINT("Calling the Kernel Routine for for a User APC: %x\n", Apc); + /* Call the kernel routine */ KernelRoutine(Apc, &NormalRoutine, &NormalContext, &SystemArgument1, &SystemArgument2); + /* Check if there's no normal routine */ if (!NormalRoutine) { /* Check if more User APCs are Pending */ @@ -455,8 +472,7 @@ KiDeliverApc(KPROCESSOR_MODE DeliveryMode, else { /* Set up the Trap Frame and prepare for Execution in NTDLL.DLL */ - DPRINT("Delivering a User APC: %x\n", Apc); - KiInitializeUserApc(Reserved, + KiInitializeUserApc(ExceptionFrame, TrapFrame, NormalRoutine, NormalContext, @@ -479,7 +495,6 @@ Quickie: /* Restore the trap frame */ Thread->TrapFrame = OldTrapFrame; - return; } FORCEINLINE diff --git a/reactos/ntoskrnl/ntoskrnl.mc b/reactos/ntoskrnl/ntoskrnl.mc index dd1ff9a8da5..3ebb82e572d 100644 --- a/reactos/ntoskrnl/ntoskrnl.mc +++ b/reactos/ntoskrnl/ntoskrnl.mc @@ -1154,6 +1154,17 @@ restart your computer, press F8 to select Advanced Startup Options, and then select Safe Mode. . +MessageId=0xC8 +Severity=Success +Facility=System +SymbolicName=IRQL_UNEXPECTED_VALUE +Language=English +The processor's IRQL is not valid for the currently executing context. +This is a software error condition and is usually caused by a device +driver changing IRQL and not restoring it to its previous value when +it has finished its task. +. + MessageId=0xCB Severity=Success Facility=System From 6c853c9c32071f263b0957f1be41ad026af4faf3 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 05:21:18 +0000 Subject: [PATCH 145/488] - Fix a critical bug in KiComputeNewPriority. - Fix a bug in KiSetPriorityThread which wasn't setting *released = FALSE, which left the var uninitailized and usually = TRUE on the stack. - Half-copy KiQuantumEnd from my new scheduler code. Main difference is usage of newly created locks, support for quantum-disable and RT threads, and usage of KiComputeNewPriority. svn path=/trunk/; revision=24060 --- reactos/ntoskrnl/include/internal/ke_x.h | 4 +- reactos/ntoskrnl/ke/dpc.c | 98 ++++++++++++------------ reactos/ntoskrnl/ke/thrdschd.c | 1 + 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index db2e030f994..f9762e9128a 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -827,8 +827,8 @@ KiComputeNewPriority(IN PKTHREAD Thread) Priority = Thread->Priority; if (Priority < LOW_REALTIME_PRIORITY) { - /* Set the New Priority and add the Priority Decrement */ - Priority += (Priority - Thread->PriorityDecrement - 1); + /* Decrease priority by the priority decrement */ + Priority -= (Thread->PriorityDecrement + 1); /* Don't go out of bounds */ if (Priority < Thread->BasePriority) Priority = Thread->BasePriority; diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 70cba3cf283..e6c1bd3a1be 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -26,16 +26,21 @@ KMUTEX KiGenericCallDpcMutex; /* PRIVATE FUNCTIONS *********************************************************/ +// +// This routine executes at the end of a thread's quantum. +// If the thread's quantum has expired, then a new thread is attempted +// to be scheduled. +// +// If no candidate thread has been found, the routine will return, otherwise +// it will swap contexts to the next scheduled thread. +// VOID NTAPI KiQuantumEnd(VOID) { + KPRIORITY Priority; PKPRCB Prcb = KeGetCurrentPrcb(); - PKTHREAD CurrentThread = KeGetCurrentThread(); - KIRQL OldIrql; - PKPROCESS Process; - KPRIORITY OldPriority; - KPRIORITY NewPriority; + PKTHREAD NextThread, Thread = Prcb->CurrentThread; /* Check if a DPC Event was requested to be signaled */ if (InterlockedExchange(&Prcb->DpcSetEventRequest, 0)) @@ -44,68 +49,59 @@ KiQuantumEnd(VOID) KeSetEvent(&Prcb->DpcEvent, 0, 0); } - /* Lock dispatcher */ - OldIrql = KeRaiseIrqlToSynchLevel(); - ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); - - /* Get the Thread's Process */ - Process = CurrentThread->ApcState.Process; + /* Raise to synchronization level and lock the PRCB and thread */ + KeRaiseIrqlToSynchLevel(); + KiAcquireThreadLock(Thread); + KiAcquirePrcbLock(Prcb); /* Check if Quantum expired */ - if (CurrentThread->Quantum <= 0) + if (Thread->Quantum <= 0) { - /* Reset the new Quantum */ - CurrentThread->Quantum = CurrentThread->QuantumReset; - - /* Calculate new priority */ - OldPriority = CurrentThread->Priority; - if (OldPriority < LOW_REALTIME_PRIORITY) + /* Make sure that we're not real-time or without a quantum */ + if ((Thread->Priority < LOW_REALTIME_PRIORITY) && + !(Thread->ApcState.Process->DisableQuantum)) { - /* Set the New Priority and add the Priority Decrement */ - NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1; + /* Reset the new Quantum */ + Thread->Quantum = Thread->QuantumReset; - /* Don't go out of bounds */ - if (NewPriority < CurrentThread->BasePriority) + /* Calculate new priority */ + Priority = Thread->Priority = KiComputeNewPriority(Thread); + + /* Check if a new thread is scheduled */ + if (!Prcb->NextThread) { - NewPriority = CurrentThread->BasePriority; - } - - /* Reset the priority decrement */ - CurrentThread->PriorityDecrement = 0; - - /* Set a new priority if needed */ - if (OldPriority != NewPriority) - { - /* Set new Priority */ - BOOLEAN Dummy; /* <- This is a hack anyways... */ - KiSetPriorityThread(CurrentThread, NewPriority, &Dummy); + /* FIXME: TODO. Add code from new scheduler */ + NextThread = NULL; } else { - /* Queue new thread if none is already */ - if (!Prcb->NextThread) - { - /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */ - } - else - { - /* Make the current thread non-premeptive if a new thread is queued */ - CurrentThread->Preempted = FALSE; - } + /* Otherwise, make sure that this thread doesn't get preempted */ + Thread->Preempted = FALSE; } } else { - /* Set the Quantum back to Maximum */ - //if (CurrentThread->DisableQuantum) { - // CurrentThread->Quantum = MAX_QUANTUM; - //} + /* Otherwise, set maximum quantum */ + Thread->Quantum = MAX_QUANTUM; } } - /* Dispatch the Thread */ - KeLowerIrql(DISPATCH_LEVEL); - KiDispatchThread(Ready); + /* Release the thread lock */ + KiReleaseThreadLock(Thread); + + /* Check if there's no thread scheduled */ + if (!Prcb->NextThread) + { + /* Just leave now */ + KiReleasePrcbLock(Prcb); + KeLowerIrql(DISPATCH_LEVEL); + KiDispatchThread(Ready); // FIXME: ROS + return; + } + + /* This shouldn't happen on ROS yet */ + DPRINT1("The impossible happened - Tell Alex\n"); + ASSERT(FALSE); } VOID diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c index 22679d26bdd..28fb3554adc 100644 --- a/reactos/ntoskrnl/ke/thrdschd.c +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -339,6 +339,7 @@ KiSetPriorityThread(PKTHREAD Thread, } /* Return to caller */ + *Released = FALSE; return; } From a0fac81cfd35ac667780182b30134b6ee4aaf118 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 05:26:38 +0000 Subject: [PATCH 146/488] - Add the actual missing code to KiQuantumEnd. It's asserted to make sure it'll never execute (yet). - Add KiExitDispatcher from my new scheduler code. Same as KiQuantumEnd, added an assertion to make sure it doesn't enter in code paths that shouldn't yet happen. svn path=/trunk/; revision=24061 --- reactos/ntoskrnl/ke/dpc.c | 27 +++++++++++- reactos/ntoskrnl/ke/wait.c | 85 ++++++++++++++++++++++++++++++++------ 2 files changed, 98 insertions(+), 14 deletions(-) diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index e6c1bd3a1be..926a874f6f8 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -71,7 +71,6 @@ KiQuantumEnd(VOID) if (!Prcb->NextThread) { /* FIXME: TODO. Add code from new scheduler */ - NextThread = NULL; } else { @@ -102,6 +101,32 @@ KiQuantumEnd(VOID) /* This shouldn't happen on ROS yet */ DPRINT1("The impossible happened - Tell Alex\n"); ASSERT(FALSE); + + /* Get the next thread now */ + NextThread = Prcb->NextThread; + + /* Set current thread's swap busy to true */ + KiSetThreadSwapBusy(Thread); + + /* Switch threads in PRCB */ + Prcb->NextThread = NULL; + Prcb->CurrentThread = NextThread; + + /* Set thread to running and the switch reason to Quantum End */ + NextThread->State = Running; + Thread->WaitReason = WrQuantumEnd; + + /* Queue it on the ready lists */ + KxQueueReadyThread(Thread, Prcb); + + /* Set wait IRQL to APC_LEVEL */ + Thread->WaitIrql = APC_LEVEL; + + /* Swap threads */ + KiSwapContext(Thread, NextThread); + + /* Lower IRQL back to DISPATCH_LEVEL */ + KeLowerIrql(DISPATCH_LEVEL); } VOID diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 38eac343f74..91935a2d657 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -236,26 +236,85 @@ KiAcquireFastMutex(IN PFAST_MUTEX FastMutex) NULL); } +// +// This routine exits the dispatcher after a compatible operation and +// swaps the context to the next scheduled thread on the current CPU if +// one is available. +// +// It does NOT attempt to scan for a new thread to schedule. +// VOID FASTCALL KiExitDispatcher(IN KIRQL OldIrql) { - /* Check if it's the idle thread */ - if (!(KeIsExecutingDpc()) && - (OldIrql < DISPATCH_LEVEL) && - (KeGetCurrentThread()) && - (KeGetCurrentThread() == KeGetCurrentPrcb()->IdleThread)) + PKPRCB Prcb = KeGetCurrentPrcb(); + PKTHREAD Thread, NextThread; + BOOLEAN PendingApc; + + /* Make sure we're at synchronization level */ + ASSERT_IRQL(SYNCH_LEVEL); + + /* Check if we have deferred threads */ + KiCheckDeferredReadyList(Prcb); + + /* Check if we were called at dispatcher level or higher */ + if (OldIrql >= DISPATCH_LEVEL) { - /* Dispatch a new thread */ - KiDispatchThreadNoLock(Ready); - } - else - { - /* Otherwise just release the lock */ - KiReleaseDispatcherLockFromDpcLevel(); + /* Check if we have a thread to schedule, and that no DPC is active */ + if ((Prcb->NextThread) && !(Prcb->DpcRoutineActive)) + { + /* Request DPC interrupt */ + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + } + + /* Lower IRQL and exit */ + goto Quickie; } - /* Lower irql back */ + /* Make sure there's a new thread scheduled */ + if (!Prcb->NextThread) goto Quickie; + + /* This shouldn't happen on ROS yet */ + DPRINT1("The impossible happened - Tell Alex\n"); + ASSERT(FALSE); + + /* Lock the PRCB */ + KiAcquirePrcbLock(Prcb); + + /* Get the next and current threads now */ + NextThread = Prcb->NextThread; + Thread = Prcb->CurrentThread; + + /* Set current thread's swap busy to true */ + KiSetThreadSwapBusy(Thread); + + /* Switch threads in PRCB */ + Prcb->NextThread = NULL; + Prcb->CurrentThread = NextThread; + + /* Set thread to running */ + NextThread->State = Running; + + /* Queue it on the ready lists */ + KxQueueReadyThread(Thread, Prcb); + + /* Set wait IRQL */ + Thread->WaitIrql = OldIrql; + + /* Swap threads and check if APCs were pending */ + PendingApc = KiSwapContext(Thread, NextThread); + if (PendingApc) + { + /* Lower only to APC */ + KeLowerIrql(APC_LEVEL); + + /* Deliver APCs */ + KiDeliverApc(KernelMode, NULL, NULL); + ASSERT(OldIrql == PASSIVE_LEVEL); + } + + /* Lower IRQl back */ +Quickie: KeLowerIrql(OldIrql); } From 81997fc0bc597f92d7728fcf75c4202b8aac4471 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 06:22:26 +0000 Subject: [PATCH 147/488] - Implement and export HalClearSoftawareInterrupt (currently implemented to match the hacked ROS version, no new version written yet). - Implement CPU Idle Loop in assembly for UP and SMP systems. Differences: * Runs with interrupts off most of the time, except when it does interrupt cycling at each iteration. * Calls KiRetireDpcList directly, instead of going through KiDispatchInterrupt. * Support for new scheduler and immediate thread switch. * Support for Idle Scheduler. * Support for HAL/ACPI/CPU Driver-defined "Idle Function". currently disabled and STI+HLT harcoded instead. - Removed ps/idle.c and dumped the hack code directly in psmgr.c wher eit's used. svn path=/trunk/; revision=24062 --- reactos/hal/hal/hal.c | 7 ++ reactos/hal/hal/hal.def | 2 +- reactos/hal/halx86/generic/irql.c | 19 ++++ reactos/include/ndk/asm.h | 1 + reactos/ntoskrnl/ke/i386/ctxswitch.S | 125 +++++++++++++++++++++++++++ reactos/ntoskrnl/ntoskrnl.rbuild | 1 - reactos/ntoskrnl/ps/idle.c | 115 ------------------------ reactos/ntoskrnl/ps/psmgr.c | 72 ++++++++++++++- 8 files changed, 223 insertions(+), 119 deletions(-) delete mode 100644 reactos/ntoskrnl/ps/idle.c diff --git a/reactos/hal/hal/hal.c b/reactos/hal/hal/hal.c index 05400bf04bf..23ccbf835bf 100644 --- a/reactos/hal/hal/hal.c +++ b/reactos/hal/hal/hal.c @@ -446,6 +446,13 @@ HalRequestSoftwareInterrupt( UNIMPLEMENTED; } +VOID FASTCALL +HalClearSoftwareInterrupt( + IN KIRQL Request) +{ + UNIMPLEMENTED; +} + VOID NTAPI diff --git a/reactos/hal/hal/hal.def b/reactos/hal/hal/hal.def index 0e4c035630e..d6b38061a42 100644 --- a/reactos/hal/hal/hal.def +++ b/reactos/hal/hal/hal.def @@ -15,7 +15,7 @@ HalAllocateCrashDumpRegisters@8 HalAssignSlotResources@32 HalBeginSystemInterrupt@12 HalCalibratePerformanceCounter@4 -;@HalClearSoftwareInterrupt@4 +@HalClearSoftwareInterrupt@4 HalDisableSystemInterrupt@8 HalDisplayString@4 HalEnableSystemInterrupt@12 diff --git a/reactos/hal/halx86/generic/irql.c b/reactos/hal/halx86/generic/irql.c index fd55e42c1f7..f54f646d7fd 100644 --- a/reactos/hal/halx86/generic/irql.c +++ b/reactos/hal/halx86/generic/irql.c @@ -422,4 +422,23 @@ HalRequestSoftwareInterrupt( } } +VOID FASTCALL +HalClearSoftwareInterrupt( + IN KIRQL Request) +{ + switch (Request) + { + case APC_LEVEL: + ((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = FALSE; + break; + + case DISPATCH_LEVEL: + ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE; + break; + + default: + KEBUGCHECK(0); + } +} + /* EOF */ diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 5fbcd49b081..802b2d6582f 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -147,6 +147,7 @@ Author: #define KPCR_TSS 0x40 #define KPCR_SET_MEMBER 0x48 #define KPCR_NUMBER 0x51 +#define KPCR_PRCB_DATA 0x120 #define KPCR_CURRENT_THREAD 0x124 #define KPCR_PRCB_NEXT_THREAD 0x128 #define KPCR_PRCB_IDLE_THREAD 0x12C diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index b76e4d3689d..4f0fc71b9c2 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -472,6 +472,7 @@ BugCheckDpc: * *--*/ .globl @KiSwapContext@8 +.func @KiSwapContext@8, @KiSwapContext@8 @KiSwapContext@8: /* Note, we CANNOT touch ebp */ @@ -511,6 +512,130 @@ BugCheckDpc: /* Clean stack */ add esp, 4 * 4 ret +.endfunc + +.globl @KiIdleLoop@0 +.func @KiIdleLoop@0, @KiIdleLoop@0 +@KiIdleLoop@0: + + /* Jump into mainline code */ + jmp MainLoop + +CpuIdle: + /* Call the CPU's idle function */ +#if 0 + lea ecx, [ebx+KPCR_PRCB_POWER_STATE_IDLE_FUNCTION] + call [ecx] +#else + sti + hlt +#endif + +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 + + /* Handle the above */ + lea ecx, [ebx+KPCR_PRCB_DATA] + 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 + +#ifdef CONFIG_SMP + /* There is, raise IRQL to synch level */ + mov ecx, SYNCH_LEVEL + call @KfRaiseIrql@4 +#endif + sti + + /* Set the current thread to ready */ + mov edi, [ebx+KPCR_CURRENT_THREAD] +#ifdef CONFIG_SMP + mov [edi+KTHREAD_STATE], Ready + + /* Acquire the PRCB Lock */ + lock bts [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 [ebx+KPCR_PRCB_PRCB_LOCK], 0 +#endif + +SwapContext: + /* 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 thready 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_PRCBDATA] + 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 .globl _Ki386AdjustEsp0@4 .func Ki386AdjustEsp0@4 diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 30f4e239246..ce341471dfd 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -292,7 +292,6 @@ debug.c - idle.c job.c kill.c notify.c diff --git a/reactos/ntoskrnl/ps/idle.c b/reactos/ntoskrnl/ps/idle.c deleted file mode 100644 index e46a744435c..00000000000 --- a/reactos/ntoskrnl/ps/idle.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ps/idle.c - * PURPOSE: Using idle time - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * David Welch (welch@cwcom.net) - */ - -/* INCLUDES *****************************************************************/ - -#include -#define NDEBUG -#include - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, PsInitIdleThread) -#endif - -/* FUNCTIONS *****************************************************************/ - -/** System idle thread procedure - * - */ -VOID STDCALL -PsIdleThreadMain(PVOID Context) -{ - KIRQL oldlvl; - - PKPRCB Prcb = KeGetCurrentPrcb(); - - for(;;) - { - if (Prcb->DpcData[0].DpcQueueDepth > 0) - { - KeRaiseIrql(DISPATCH_LEVEL,&oldlvl); - KiDispatchInterrupt(); - KeLowerIrql(oldlvl); - } - - NtYieldExecution(); - - Ke386HaltProcessor(); - } -} - -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ -NTSTATUS -NTAPI -PsInitializeIdleOrFirstThread(PEPROCESS Process, - PETHREAD* ThreadPtr, - PKSTART_ROUTINE StartRoutine, - KPROCESSOR_MODE AccessMode, - BOOLEAN First) -{ - PETHREAD Thread; - PVOID KernelStack; - - Thread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); - RtlZeroMemory(Thread, sizeof(ETHREAD)); - Thread->ThreadsProcess = Process; - if (First) - { - KernelStack = P0BootStack; - } - else - { - KernelStack = (PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) + - KERNEL_STACK_SIZE); - } - KeInitializeThread(&Process->Pcb, - &Thread->Tcb, - PspSystemThreadStartup, - StartRoutine, - NULL, - NULL, - NULL, - KernelStack); - InitializeListHead(&Thread->IrpList); - *ThreadPtr = Thread; - return STATUS_SUCCESS; -} - -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ -VOID -INIT_FUNCTION -NTAPI -PsInitIdleThread(VOID) -{ - PETHREAD IdleThread; - KIRQL oldIrql; - - PsInitializeIdleOrFirstThread(PsIdleProcess, - &IdleThread, - PsIdleThreadMain, - KernelMode, - FALSE); - - oldIrql = KiAcquireDispatcherLock (); - KiReadyThread(&IdleThread->Tcb); - KiReleaseDispatcherLock(oldIrql); - - KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; - KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); - KeSetAffinityThread(&IdleThread->Tcb, 1 << 0); -} diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index df6d3c287ff..b4d71c0ee6d 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -64,6 +64,74 @@ NTSTATUS STDCALL INIT_FUNCTION PspLookupKernelUserEntryPoints(VOID); /* FUNCTIONS ***************************************************************/ +VOID +FASTCALL +KiIdleLoop(VOID); + +/* FUNCTIONS *****************************************************************/ + +/* + * HACK-O-RAMA + * Antique vestigial code left alive for the sole purpose of First/Idle Thread + * creation until I can merge my fix for properly creating them. + */ +VOID +INIT_FUNCTION +NTAPI +PsInitHackThread(VOID) +{ + PETHREAD IdleThread; + KIRQL oldIrql; + + IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); + RtlZeroMemory(IdleThread, sizeof(ETHREAD)); + IdleThread->ThreadsProcess = PsIdleProcess; + KeInitializeThread(&PsIdleProcess->Pcb, + &IdleThread->Tcb, + PspSystemThreadStartup, + (PVOID)KiIdleLoop, + NULL, + NULL, + NULL, + P0BootStack); + InitializeListHead(&IdleThread->IrpList); + + oldIrql = KiAcquireDispatcherLock (); + KiReadyThread(&IdleThread->Tcb); + KiReleaseDispatcherLock(oldIrql); + + KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; + KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); + KeSetAffinityThread(&IdleThread->Tcb, 1 << 0); +} + +/* + * HACK-O-RAMA + * Antique vestigial code left alive for the sole purpose of First/Idle Thread + * creation until I can merge my fix for properly creating them. + */ +VOID +INIT_FUNCTION +NTAPI +PsInitHackThread2(IN PETHREAD *Hack) +{ + PETHREAD IdleThread; + + IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); + RtlZeroMemory(IdleThread, sizeof(ETHREAD)); + IdleThread->ThreadsProcess = PsInitialSystemProcess; + KeInitializeThread(&PsInitialSystemProcess->Pcb, + &IdleThread->Tcb, + PspSystemThreadStartup, + NULL, + NULL, + NULL, + NULL, + P0BootStack); + InitializeListHead(&IdleThread->IrpList); + *Hack = IdleThread; +} + VOID INIT_FUNCTION NTAPI @@ -72,7 +140,7 @@ PiInitProcessManager(VOID) PsInitJobManagment(); PsInitProcessManagment(); PsInitThreadManagment(); - PsInitIdleThread(); + PsInitHackThread(); } VOID @@ -115,7 +183,7 @@ PsInitThreadManagment(VOID) ObjectTypeInitializer.DeleteProcedure = PspDeleteThread; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsThreadType); - PsInitializeIdleOrFirstThread(PsInitialSystemProcess, &FirstThread, NULL, KernelMode, TRUE); + PsInitHackThread2(&FirstThread); FirstThread->Tcb.State = Running; FirstThread->Tcb.FreezeCount = 0; FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */ From c19a362969b799e0af19a624f52de258041c7f1b Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 06:50:19 +0000 Subject: [PATCH 148/488] - Implement HalProcessorIdle. - Fix KiIdleLoop to actuall load the PCR in EBX. It was using a completely random value. - Call the Processor Idle Routine now, isntead of hard-coding STI+HLT. This routine had already been setup during bootup by PoInitailizePrcb. - Implemented PopIdle0 and made it call HalProcessorIdle. No performance/throttling is done yet. svn path=/trunk/; revision=24063 --- reactos/hal/halx86/generic/misc.c | 12 ------------ reactos/hal/halx86/generic/processor.c | 8 ++++++++ reactos/include/ndk/asm.h | 1 + reactos/include/ndk/halfuncs.h | 10 ++++++++++ reactos/ntoskrnl/ke/i386/ctxswitch.S | 8 +++----- reactos/ntoskrnl/po/power.c | 7 ++++--- 6 files changed, 26 insertions(+), 20 deletions(-) diff --git a/reactos/hal/halx86/generic/misc.c b/reactos/hal/halx86/generic/misc.c index a2378eed7d5..b5ecdfa7909 100644 --- a/reactos/hal/halx86/generic/misc.c +++ b/reactos/hal/halx86/generic/misc.c @@ -45,18 +45,6 @@ HalHandleNMI(PVOID NmiInfo) KeEnterKernelDebugger (); } - -VOID STDCALL -HalProcessorIdle(VOID) -{ -#if 1 - Ki386EnableInterrupts(); - Ki386HaltProcessor(); -#else - -#endif -} - ULONG FASTCALL HalSystemVectorDispatchEntry ( ULONG Unknown1, diff --git a/reactos/hal/halx86/generic/processor.c b/reactos/hal/halx86/generic/processor.c index d9c6a8d82ed..f2b3a60d892 100644 --- a/reactos/hal/halx86/generic/processor.c +++ b/reactos/hal/halx86/generic/processor.c @@ -47,4 +47,12 @@ HalStartNextProcessor(ULONG Unknown1, return TRUE; } +VOID +NTAPI +HalProcessorIdle(VOID) +{ + Ki386EnableInterrupts(); + Ki386HaltProcessor(); +} + /* EOF */ diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 802b2d6582f..5d90b39a8c4 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -176,6 +176,7 @@ Author: #define KPCR_PRCB_TIMER_REQUEST 0xA88 #define KPCR_PRCB_QUANTUM_END 0xAA1 #define KPCR_PRCB_DEFERRED_READY_LIST_HEAD 0xC10 +#define KPCR_PRCB_POWER_STATE_IDLE_FUNCTION 0xEC0 // // KINTERRUPT Offsets diff --git a/reactos/include/ndk/halfuncs.h b/reactos/include/ndk/halfuncs.h index 2544e9de306..358f6255454 100644 --- a/reactos/include/ndk/halfuncs.h +++ b/reactos/include/ndk/halfuncs.h @@ -88,6 +88,16 @@ HalStartNextProcessor( ULONG Unknown2 ); +// +// CPU Routines +// +NTHALAPI +VOID +NTAPI +HalProcessorIdle( + VOID +); + // // Interrupt Functions // diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 4f0fc71b9c2..6cfa4f9b5f0 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -518,18 +518,16 @@ BugCheckDpc: .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 */ -#if 0 lea ecx, [ebx+KPCR_PRCB_POWER_STATE_IDLE_FUNCTION] call [ecx] -#else - sti - hlt -#endif MainLoop: /* Cycle interrupts for 1 cycle */ diff --git a/reactos/ntoskrnl/po/power.c b/reactos/ntoskrnl/po/power.c index 684b4a4189b..4589cba3c18 100644 --- a/reactos/ntoskrnl/po/power.c +++ b/reactos/ntoskrnl/po/power.c @@ -340,9 +340,10 @@ PopPerfIdleDpc(IN PKDPC Dpc, VOID FASTCALL -PopIdle0(IN PKPRCB Prcb) +PopIdle0(IN PPROCESSOR_POWER_STATE PowerState) { - DPRINT1("Idle function: %p\n", Prcb); + /* FIXME: Extremly naive implementation */ + HalProcessorIdle(); } VOID @@ -358,7 +359,7 @@ PoInitializePrcb(IN PKPRCB Prcb) /* Initialize the Perf DPC and Timer */ KeInitializeDpc(&Prcb->PowerState.PerfDpc, PopPerfIdleDpc, Prcb); - //KeSetTargetProcessorDpc(&Prcb->PowerState.PerfDpc, Prcb->Number); + KeSetTargetProcessorDpc(&Prcb->PowerState.PerfDpc, Prcb->Number); KeInitializeTimerEx(&Prcb->PowerState.PerfTimer, SynchronizationTimer); } From 059fb2c54e15430c814651f165fc4d49d7ecd090 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Mon, 11 Sep 2006 10:43:42 +0000 Subject: [PATCH 149/488] Implement NtGdiFlattenPath svn path=/trunk/; revision=24064 --- reactos/subsystems/win32/win32k/objects/path.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/path.c b/reactos/subsystems/win32/win32k/objects/path.c index 40f08085ec9..71a957aed9f 100644 --- a/reactos/subsystems/win32/win32k/objects/path.c +++ b/reactos/subsystems/win32/win32k/objects/path.c @@ -172,8 +172,19 @@ BOOL STDCALL NtGdiFlattenPath(HDC hDC) { - UNIMPLEMENTED; - return FALSE; + BOOL Ret = FALSE; + DC *pDc; + + DPRINT("Enter %s\n", __FUNCTION__); + + pDc = DC_LockDc(hDC); + if(!pDc) return FALSE; + + if(pDc->w.path.state == PATH_Open) + Ret = PATH_FlattenPath(&pDc->w.path); + + DC_UnlockDc(pDc); + return Ret; } From 4f6a751b6f8e2df4baff7ae2340256fd34c98d48 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Mon, 11 Sep 2006 11:01:35 +0000 Subject: [PATCH 150/488] Implement NtGdiCloseFigure (Fixes BSOD!) svn path=/trunk/; revision=24065 --- .../subsystems/win32/win32k/objects/path.c | 64 +++++++++++-------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/path.c b/reactos/subsystems/win32/win32k/objects/path.c index 71a957aed9f..27de4689ca5 100644 --- a/reactos/subsystems/win32/win32k/objects/path.c +++ b/reactos/subsystems/win32/win32k/objects/path.c @@ -94,28 +94,48 @@ NtGdiBeginPath( HDC hDC ) return ret; } -BOOL +VOID FASTCALL -IntCloseFigure ( PDC dc ) +IntGdiCloseFigure(PDC pDc) { - UNIMPLEMENTED; - return FALSE; + ASSERT(pDc); + ASSERT(pDc->w.path.state == PATH_Open); + + // FIXME: Shouldn't we draw a line to the beginning of the figure? + // Set PT_CLOSEFIGURE on the last entry and start a new stroke + if(pDc->w.path.numEntriesUsed) + { + pDc->w.path.pFlags[pDc->w.path.numEntriesUsed-1]|=PT_CLOSEFIGURE; + pDc->w.path.newStroke=TRUE; + } } BOOL STDCALL -NtGdiCloseFigure ( HDC hDC ) +NtGdiCloseFigure(HDC hDC) { - PDC dc = DC_LockDc ( hDC ); - BOOL ret = FALSE; // default to failure + BOOL Ret = FALSE; // default to failure + PDC pDc; + + DPRINT("Enter %s\n", __FUNCTION__); + + pDc = DC_LockDc(hDC); + if(!pDc) return FALSE; + + if(pDc->w.path.state==PATH_Open) + { + IntGdiCloseFigure(pDc); + Ret = TRUE; + } + else + { + // FIXME: check if lasterror is set correctly + SetLastWin32Error(ERROR_CAN_NOT_COMPLETE); + } + + DC_UnlockDc(pDc); - if ( dc ) - { - ret = IntCloseFigure ( dc ); - DC_UnlockDc ( dc ); - } - - return ret; + return Ret; } BOOL @@ -617,12 +637,7 @@ PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) } /* Close any previous figure */ - if ( !IntCloseFigure ( dc ) ) - { - /* The NtGdiCloseFigure call shouldn't have failed */ - assert(FALSE); - return FALSE; - } + IntGdiCloseFigure(dc); /* Add four points to the path */ pointTemp.x=corners[1].x; @@ -639,13 +654,8 @@ PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) return FALSE; /* Close the rectangle figure */ - if ( !IntCloseFigure ( dc ) ) - { - /* The IntCloseFigure call shouldn't have failed */ - assert(FALSE); - return FALSE; - } - + IntGdiCloseFigure(dc) ; + return TRUE; } From 7b79f44d6bc079801870ec495ae47316d87a1179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 11 Sep 2006 11:04:33 +0000 Subject: [PATCH 151/488] Better handling of REG_LINK values Try to fix Linux build (thanks Usurp on IRC) svn path=/trunk/; revision=24066 --- reactos/lib/cmlib/cmlib.mak | 2 +- reactos/tools/mkhive/cmi.c | 2 +- reactos/tools/mkhive/mkhive.h | 8 ++++--- reactos/tools/mkhive/mkhive.mak | 2 +- reactos/tools/mkhive/registry.c | 40 +++++++++++++++++---------------- reactos/tools/mkhive/registry.h | 2 +- 6 files changed, 30 insertions(+), 26 deletions(-) diff --git a/reactos/lib/cmlib/cmlib.mak b/reactos/lib/cmlib/cmlib.mak index 0b83185cb60..f4114943cdc 100644 --- a/reactos/lib/cmlib/cmlib.mak +++ b/reactos/lib/cmlib/cmlib.mak @@ -32,7 +32,7 @@ CMLIB_HOST_OBJECTS = \ CMLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -D_X86_ -D__i386__ -D_REACTOS_ -D_NTOSKRNL_\ - -DCMLIB_HOST -D_M_IX86 -I$(CMLIB_BASE) -Iinclude/reactos -Iinclude/psdk -Iinclude/ddk \ + -DCMLIB_HOST -D_M_IX86 -I$(CMLIB_BASE) -Iinclude/reactos -Iinclude/psdk -Iinclude/ddk -Iinclude/crt \ -D__NO_CTYPE_INLINES $(CMLIB_HOST_TARGET): $(CMLIB_HOST_OBJECTS) | $(CMLIB_OUT) diff --git a/reactos/tools/mkhive/cmi.c b/reactos/tools/mkhive/cmi.c index e8cd3e5e556..b84c1d25776 100644 --- a/reactos/tools/mkhive/cmi.c +++ b/reactos/tools/mkhive/cmi.c @@ -398,7 +398,7 @@ CmiCompareHashI( Buffer[2] = (KeyName->Length >= 6) ? (CHAR)KeyName->Buffer[2] : 0; Buffer[3] = (KeyName->Length >= 8) ? (CHAR)KeyName->Buffer[3] : 0; - return (_strnicmp(Buffer, HashString, 4) == 0); + return (strncasecmp(Buffer, HashString, 4) == 0); } static BOOLEAN diff --git a/reactos/tools/mkhive/mkhive.h b/reactos/tools/mkhive/mkhive.h index a81322cb77f..50161404ef8 100644 --- a/reactos/tools/mkhive/mkhive.h +++ b/reactos/tools/mkhive/mkhive.h @@ -76,10 +76,12 @@ static void DPRINT ( const char* fmt, ... ) #define CHECKPOINT -#ifdef WIN32 -#define strncasecmp strnicmp +#ifdef _WIN32 +#define strncasecmp _strnicmp #define strcasecmp _stricmp -#endif//WIN32 +#else +#include +#endif//_WIN32 #ifdef _MSC_VER #define GCC_PACKED diff --git a/reactos/tools/mkhive/mkhive.mak b/reactos/tools/mkhive/mkhive.mak index 1f847076ae1..a4d20753d32 100644 --- a/reactos/tools/mkhive/mkhive.mak +++ b/reactos/tools/mkhive/mkhive.mak @@ -32,7 +32,7 @@ MKHIVE_OBJECTS = \ MKHIVE_HOST_CFLAGS = $(xTOOLS_CFLAGS) -I$(INFLIB_BASE) -I$(CMLIB_BASE) \ -D_NTOSKRNL_ \ - -Iinclude/reactos -Iinclude/ddk -Iinclude/ndk -Iinclude/psdk -Iinclude -g3 + -Iinclude/reactos -Iinclude/ddk -Iinclude/ndk -Iinclude/psdk -Iinclude -Iinclude/crt -g3 MKHIVE_HOST_LFLAGS = $(xTOOLS_LFLAGS) -g3 diff --git a/reactos/tools/mkhive/registry.c b/reactos/tools/mkhive/registry.c index f4863d37850..0a2847e78da 100644 --- a/reactos/tools/mkhive/registry.c +++ b/reactos/tools/mkhive/registry.c @@ -132,6 +132,9 @@ RegpOpenOrCreateKey( else RtlInitUnicodeString(&KeyString, LocalKeyName); + while (ParentKey->DataType == REG_LINK) + ParentKey = ParentKey->LinkedKey; + /* Check subkey in memory structure */ Ptr = ParentKey->SubKeyList.Flink; while (Ptr != &ParentKey->SubKeyList) @@ -180,9 +183,6 @@ RegpOpenOrCreateKey( ParentKey->SubKeyCount++; nextsubkey: - /* Follow registry links */ - while (CurrentKey->LinkedKey) - CurrentKey = CurrentKey->LinkedKey; ParentKey = CurrentKey; if (End) LocalKeyName = End + 1; @@ -276,7 +276,7 @@ RegOpenKeyA( return rc; } -static NTSTATUS +static LONG RegpOpenOrCreateValue( IN HKEY hKey, IN LPCWSTR ValueName, @@ -308,8 +308,8 @@ RegpOpenOrCreateValue( ValueCellOffset); } if (!NT_SUCCESS(Status)) - return Status; - return STATUS_SUCCESS; + return ERROR_UNSUCCESSFUL; + return ERROR_SUCCESS; } LONG WINAPI @@ -318,7 +318,7 @@ RegSetValueExW( IN LPCWSTR lpValueName OPTIONAL, IN ULONG Reserved, IN ULONG dwType, - IN const PUCHAR lpData, + IN const UCHAR* lpData, IN USHORT cbData) { MEMKEY Key, DestKey; @@ -339,13 +339,14 @@ RegSetValueExW( DestKey = HKEY_TO_MEMKEY(*phKey); /* Create the link in memory */ + Key->DataType = REG_LINK; Key->LinkedKey = DestKey; /* Create the link in registry hive (if applicable) */ if (Key->RegistryHive != DestKey->RegistryHive) return STATUS_SUCCESS; - DPRINT1("Save link to registry\n"); - return STATUS_NOT_IMPLEMENTED; + lpData = (PUCHAR)&DestKey->KeyCellOffset; + cbData = sizeof(HCELL_INDEX); } if ((cbData & REG_DATA_SIZE_MASK) != cbData) @@ -428,11 +429,11 @@ RegSetValueExA( IN LPCSTR lpValueName OPTIONAL, IN ULONG Reserved, IN ULONG dwType, - IN const PUCHAR lpData, + IN const UCHAR* lpData, IN ULONG cbData) { LPWSTR lpValueNameW = NULL; - PUCHAR lpDataW; + const UCHAR* lpDataW; USHORT cbDataW; LONG rc = ERROR_SUCCESS; @@ -457,7 +458,7 @@ RegSetValueExA( AnsiString.Length = (USHORT)cbData - 1; AnsiString.MaximumLength = (USHORT)cbData; RtlAnsiStringToUnicodeString (&Data, &AnsiString, TRUE); - lpDataW = (const PUCHAR)Data.Buffer; + lpDataW = (const UCHAR*)Data.Buffer; cbDataW = Data.MaximumLength; } else @@ -471,7 +472,7 @@ RegSetValueExA( if (lpValueNameW) free(lpValueNameW); if (lpData != lpDataW) - free(lpDataW); + free((PVOID)lpDataW); return rc; } @@ -487,17 +488,20 @@ RegQueryValueExW( //ParentKey = HKEY_TO_MEMKEY(RootKey); PCM_KEY_VALUE ValueCell; HCELL_INDEX ValueCellOffset; - NTSTATUS Status; + LONG rc; - Status = RegpOpenOrCreateValue( + rc = RegpOpenOrCreateValue( hKey, lpValueName, FALSE, &ValueCell, &ValueCellOffset); + if (rc != ERROR_SUCCESS) + return rc; + + DPRINT1("RegQueryValueExW(%S) not implemented\n", lpValueName); + /* ValueCell and ValueCellOffset are valid */ - //Status = CmiScanForValueKey( - // x return ERROR_UNSUCCESSFUL; } @@ -513,7 +517,6 @@ RegQueryValueExA( LPWSTR lpValueNameW = NULL; LONG rc; - DPRINT1("RegQueryValueExA(%s) not implemented\n", lpValueName); if (lpValueName) { lpValueNameW = MultiByteToWideChar(lpValueName); @@ -673,7 +676,6 @@ RegInitializeRegistry(VOID) NULL, L"Registry\\Machine\\SYSTEM\\CurrentControlSet", &LinkKey); - printf("ControlSetKey %p\n", ControlSetKey); RegSetValueExW(LinkKey, NULL, 0, REG_LINK, (PCHAR)&ControlSetKey, sizeof(PVOID)); } diff --git a/reactos/tools/mkhive/registry.h b/reactos/tools/mkhive/registry.h index a957cccd943..5691858a1ce 100644 --- a/reactos/tools/mkhive/registry.h +++ b/reactos/tools/mkhive/registry.h @@ -220,7 +220,7 @@ RegSetValueExA( IN LPCSTR lpValueName OPTIONAL, ULONG Reserved, IN ULONG dwType, - IN const PUCHAR lpData, + IN const UCHAR* lpData, IN ULONG cbData); LONG WINAPI From 07dc58982f8366137df53d7312e58fb3b14749ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 11 Sep 2006 11:28:54 +0000 Subject: [PATCH 152/488] We want to support hives version 1.3+ (up to 1.5 currently). Fix test accordingly svn path=/trunk/; revision=24067 --- reactos/lib/cmlib/hiveinit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/lib/cmlib/hiveinit.c b/reactos/lib/cmlib/hiveinit.c index 567789cd383..1c3fc5dea0d 100644 --- a/reactos/lib/cmlib/hiveinit.c +++ b/reactos/lib/cmlib/hiveinit.c @@ -21,7 +21,7 @@ HvpVerifyHiveHeader( { if (HiveHeader->Signature != HV_SIGNATURE || HiveHeader->Major != HV_MAJOR_VER || - HiveHeader->Minor > HV_MINOR_VER || + HiveHeader->Minor < HV_MINOR_VER || HiveHeader->Type != HV_TYPE_PRIMARY || HiveHeader->Format != HV_FORMAT_MEMORY || HiveHeader->Cluster != 1 || @@ -31,7 +31,7 @@ HvpVerifyHiveHeader( DPRINT1("Verify Hive Header failed: \n"); DPRINT1(" Signature: 0x%x and not 0x%x, Major: 0x%x and not 0x%x\n", HiveHeader->Signature, HV_SIGNATURE, HiveHeader->Major, HV_MAJOR_VER); - DPRINT1(" Minor: 0x%x is not > 0x%x, Type: 0x%x and not 0x%x\n", + DPRINT1(" Minor: 0x%x is not >= 0x%x, Type: 0x%x and not 0x%x\n", HiveHeader->Minor, HV_MINOR_VER, HiveHeader->Type, HV_TYPE_PRIMARY); DPRINT1(" Format: 0x%x and not 0x%x, Cluster: 0x%x and not 1\n", HiveHeader->Format, HV_FORMAT_MEMORY, HiveHeader->Cluster); From 5fb31962db4aa128fa79818f93799af065de2173 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 11 Sep 2006 12:00:02 +0000 Subject: [PATCH 153/488] - Implement KiReleaseProcessLockFromDpcLevel and use it in KeTerminateThread. We were lowering to PASSIVE during thread termination, and then doing a context switch at PASSIVE, which you can guess is pretty bad. svn path=/trunk/; revision=24068 --- reactos/ntoskrnl/include/internal/ke_x.h | 8 ++++++++ reactos/ntoskrnl/ke/thrdobj.c | 2 +- reactos/ntoskrnl/ke/thrdschd.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index f9762e9128a..8db34413bf9 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -688,6 +688,14 @@ KiReleaseProcessLock(IN PKLOCK_QUEUE_HANDLE Handle) KeReleaseInStackQueuedSpinLock(Handle); } +FORCEINLINE +VOID +KiReleaseProcessLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle) +{ + /* Release the lock */ + KeReleaseInStackQueuedSpinLockFromDpcLevel(Handle); +} + // // This routine queues a thread that is ready on the PRCB's ready lists. // If this thread cannot currently run on this CPU, then the thread is diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index b3193c3bfcc..15d94351899 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -1315,7 +1315,7 @@ KeTerminateThread(IN KPRIORITY Increment) RemoveEntryList(&Thread->ThreadListEntry); /* Release the process lock */ - KiReleaseProcessLock(&LockHandle); + KiReleaseProcessLockFromDpcLevel(&LockHandle); /* Set us as terminated, decrease the Process's stack count */ Thread->State = Terminated; diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c index 28fb3554adc..9bda109f51f 100644 --- a/reactos/ntoskrnl/ke/thrdschd.c +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -169,9 +169,9 @@ KiSwapThread(IN PKTHREAD CurrentThread, IN PKPRCB Prcb) { BOOLEAN ApcState; + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); /* Find a new thread to run */ - DPRINT("Dispatching Thread as blocked\n"); ApcState = KiDispatchThreadNoLock(Waiting); /* Check if we need to deliver APCs */ From 60fb482ad47d6fdc2be2bd5c4be593474a55f3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 11 Sep 2006 12:42:35 +0000 Subject: [PATCH 154/488] Fix compilation on Linux hosts - try #2 We can't use the _WIN32 symbol which is automatically defined once you include psdk/windef.h ... svn path=/trunk/; revision=24069 --- reactos/tools/mkhive/mkhive.c | 4 ++-- reactos/tools/mkhive/mkhive.h | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/reactos/tools/mkhive/mkhive.c b/reactos/tools/mkhive/mkhive.c index 360021e9030..a7f99f49471 100644 --- a/reactos/tools/mkhive/mkhive.c +++ b/reactos/tools/mkhive/mkhive.c @@ -35,7 +35,7 @@ #define PATH_MAX _MAX_PATH #endif//_MSC_VER -#ifndef WIN32 +#ifndef WINDOWS_HOST #ifndef PATH_MAX #define PATH_MAX 260 #endif @@ -62,7 +62,7 @@ void convert_path(char *dst, char *src) i = 0; while (src[i] != 0) { -#ifdef WIN32 +#ifdef WINDOWS_HOST if (src[i] == '/') { dst[i] = '\\'; diff --git a/reactos/tools/mkhive/mkhive.h b/reactos/tools/mkhive/mkhive.h index 50161404ef8..bb7da55512c 100644 --- a/reactos/tools/mkhive/mkhive.h +++ b/reactos/tools/mkhive/mkhive.h @@ -29,6 +29,11 @@ #include +/* We have to do this because psdk/windef.h will _always_ define _WIN32... */ +#if defined(_WIN32) || defined(_WIN64) +#define WINDOWS_HOST +#endif + #define NTOS_MODE_USER #define WIN32_NO_STATUS #include @@ -76,7 +81,7 @@ static void DPRINT ( const char* fmt, ... ) #define CHECKPOINT -#ifdef _WIN32 +#ifdef WINDOWS_HOST #define strncasecmp _strnicmp #define strcasecmp _stricmp #else From d263039fe9661d0ff4c3b28e2204590363ff3b68 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 11 Sep 2006 13:01:39 +0000 Subject: [PATCH 155/488] Add missing header svn path=/trunk/; revision=24070 --- reactos/boot/freeldr/freeldr/include/winldr.h | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 reactos/boot/freeldr/freeldr/include/winldr.h diff --git a/reactos/boot/freeldr/freeldr/include/winldr.h b/reactos/boot/freeldr/freeldr/include/winldr.h new file mode 100644 index 00000000000..f3607fd29ba --- /dev/null +++ b/reactos/boot/freeldr/freeldr/include/winldr.h @@ -0,0 +1,33 @@ +/* + * FreeLoader + * Copyright (C) 1998-2003 Brian Palmer + * Copyright (C) 2006 Aleksey Bragin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __WINLDR_H +#define __WINLDR_H + + +/////////////////////////////////////////////////////////////////////////////////////// +// +// ReactOS Loading Functions +// +/////////////////////////////////////////////////////////////////////////////////////// +VOID LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion); + + +#endif // defined __WINLDR_H From 529631027a5476c92146c5017d6258c7a96e24bc Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Mon, 11 Sep 2006 13:07:12 +0000 Subject: [PATCH 156/488] Fix WS_SYSMENU+WS_EX_DLGMODALFRAME bug. Fixes Messagebox broblem and some others. svn path=/trunk/; revision=24071 --- reactos/subsystems/win32/win32k/ntuser/painting.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/painting.c b/reactos/subsystems/win32/win32k/ntuser/painting.c index 35ca36374b6..09e371dc71f 100644 --- a/reactos/subsystems/win32/win32k/ntuser/painting.c +++ b/reactos/subsystems/win32/win32k/ntuser/painting.c @@ -1531,7 +1531,8 @@ BOOL UserDrawCaption( VCenter = (lpRc->bottom - lpRc->top) / 2; Padding = VCenter - (Height / 2); HasIcon = (uFlags & DC_ICON) && (pWnd->Style & WS_SYSMENU) - && !(uFlags & DC_SMALLCAP); + && !(uFlags & DC_SMALLCAP) && !(pWnd->ExStyle & WS_EX_DLGMODALFRAME) + && !(pWnd->ExStyle & WS_EX_TOOLWINDOW); IconWidth = UserGetSystemMetrics(SM_CXSIZE) + Padding; r.left = Padding; From 68f5e47ce63172e3cee25a99fd53cec1be123ab4 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Mon, 11 Sep 2006 13:09:12 +0000 Subject: [PATCH 157/488] This testapp demonstrates WS_SYSMENU + WS_EX_DLGMODALFRAME behavior and shows that DrawCaption does care about WS_EX_DLGMODALFRAME and WS_EX_TOOLWINDOW. svn path=/trunk/; revision=24072 --- .../testsets/user32/sysicon/sysicon.c | 163 ++++++++++++++++++ .../testsets/user32/sysicon/sysicon.rbuild | 13 ++ .../testsets/user32/user32.rbuild | 3 + 3 files changed, 179 insertions(+) create mode 100644 reactos/base/applications/testsets/user32/sysicon/sysicon.c create mode 100644 reactos/base/applications/testsets/user32/sysicon/sysicon.rbuild diff --git a/reactos/base/applications/testsets/user32/sysicon/sysicon.c b/reactos/base/applications/testsets/user32/sysicon/sysicon.c new file mode 100644 index 00000000000..e6f38c643e4 --- /dev/null +++ b/reactos/base/applications/testsets/user32/sysicon/sysicon.c @@ -0,0 +1,163 @@ +/* + * Copyright 2006 Saveliy Tretiakov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + /* This testapp demonstrates WS_SYSMENU + WS_EX_DLGMODALFRAME + * behavior and shows that DrawCaption does care + * about WS_EX_DLGMODALFRAME and WS_EX_TOOLWINDOW + */ + +#include "windows.h" +#include "stdio.h" +#include "resource.h" + +WCHAR WndClass[] = L"sysicon_class"; + +LRESULT CALLBACK WndProc(HWND hWnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + + switch (msg) + { + + case WM_PAINT: + { + HDC hDc; + PAINTSTRUCT Ps; + RECT Rect; + GetClientRect(hWnd, &Rect); + + Rect.left = 10; + Rect.top = 10; + Rect.right-=10; + Rect.bottom = 25; + + hDc = BeginPaint(hWnd, &Ps); + SetBkMode( hDc, TRANSPARENT ); + + DrawCaption(hWnd, hDc, &Rect, DC_GRADIENT | DC_ACTIVE | DC_TEXT | DC_ICON); + + EndPaint(hWnd, &Ps); + + return 0; + } + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +int APIENTRY WinMain(HINSTANCE hInst, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + HWND hWnd1, hWnd2, hWnd3; + MSG msg; + WNDCLASSEX wcx; + UINT result; + + memset(&wcx, 0, sizeof(wcx)); + wcx.cbSize = sizeof(wcx); + wcx.lpfnWndProc = (WNDPROC) WndProc; + wcx.hInstance = hInst; + wcx.hbrBackground = (HBRUSH)COLOR_WINDOW; + wcx.lpszClassName = WndClass; + + if(!(result = RegisterClassEx(&wcx))) + { + return 1; + } + + /* WS_EX_DLGMODALFRAME */ + hWnd1 = CreateWindowEx(WS_EX_DLGMODALFRAME, + WndClass, + L"WS_SYSMENU | WS_EX_DLGMODALFRAME", + WS_CAPTION | WS_SYSMENU , + CW_USEDEFAULT, + CW_USEDEFAULT, + 400, + 100, + NULL, + 0, + hInst, + NULL); + + if(!hWnd1) + { + return 1; + } + + ShowWindow(hWnd1, SW_SHOW); + UpdateWindow(hWnd1); + + hWnd2 = CreateWindowEx(WS_EX_TOOLWINDOW, + WndClass, + L"WS_SYSMENU | WS_EX_TOOLWINDOW", + WS_CAPTION | WS_SYSMENU , + CW_USEDEFAULT, + CW_USEDEFAULT, + 400, + 100, + NULL, + 0, + hInst, + NULL); + + if(!hWnd2) + { + return 1; + } + + ShowWindow(hWnd2, SW_SHOW); + UpdateWindow(hWnd2); + + hWnd3 = CreateWindowEx(0, + WndClass, + L"WS_SYSMENU ", + WS_CAPTION | WS_SYSMENU , + CW_USEDEFAULT, + CW_USEDEFAULT, + 400, + 100, + NULL, + 0, + hInst, + NULL); + + if(!hWnd3) + { + return 1; + } + + ShowWindow(hWnd3, SW_SHOW); + UpdateWindow(hWnd3); + + while(GetMessage(&msg, NULL, 0, 0 )) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + UnregisterClass(WndClass, hInst); + return 0; +} diff --git a/reactos/base/applications/testsets/user32/sysicon/sysicon.rbuild b/reactos/base/applications/testsets/user32/sysicon/sysicon.rbuild new file mode 100644 index 00000000000..e94e0ba443d --- /dev/null +++ b/reactos/base/applications/testsets/user32/sysicon/sysicon.rbuild @@ -0,0 +1,13 @@ + + . + + + + 0x0500 + 0x0600 + 0x0600 + kernel32 + user32 + gdi32 + sysicon.c + diff --git a/reactos/base/applications/testsets/user32/user32.rbuild b/reactos/base/applications/testsets/user32/user32.rbuild index 647e1ac882d..d72d18db67e 100644 --- a/reactos/base/applications/testsets/user32/user32.rbuild +++ b/reactos/base/applications/testsets/user32/user32.rbuild @@ -4,4 +4,7 @@ + + + From 6f5c6f23d3d8841a8328b12dea57563c1059f231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 11 Sep 2006 14:35:46 +0000 Subject: [PATCH 158/488] Fix halmp compilation svn path=/trunk/; revision=24073 --- reactos/hal/halx86/generic/generic.rbuild | 4 ++-- reactos/hal/halx86/mp/mpsirql.c | 7 +++++++ reactos/hal/halx86/mp/processor_mp.c | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/reactos/hal/halx86/generic/generic.rbuild b/reactos/hal/halx86/generic/generic.rbuild index 21562e7fe54..b1e203c28fb 100644 --- a/reactos/hal/halx86/generic/generic.rbuild +++ b/reactos/hal/halx86/generic/generic.rbuild @@ -31,11 +31,11 @@ ipi.c - irql.c + irql.c processor.c resource.c spinlock.c - systimer.S + systimer.S ../include diff --git a/reactos/hal/halx86/mp/mpsirql.c b/reactos/hal/halx86/mp/mpsirql.c index 347880f4183..6bb51abc307 100644 --- a/reactos/hal/halx86/mp/mpsirql.c +++ b/reactos/hal/halx86/mp/mpsirql.c @@ -397,3 +397,10 @@ HalRequestSoftwareInterrupt(IN KIRQL Request) KEBUGCHECK(0); } } + +VOID FASTCALL +HalClearSoftwareInterrupt( + IN KIRQL Request) +{ + UNIMPLEMENTED; +} diff --git a/reactos/hal/halx86/mp/processor_mp.c b/reactos/hal/halx86/mp/processor_mp.c index 82fe5856a05..07bb6ad1066 100644 --- a/reactos/hal/halx86/mp/processor_mp.c +++ b/reactos/hal/halx86/mp/processor_mp.c @@ -115,4 +115,12 @@ HalStartNextProcessor(ULONG Unknown1, return TRUE; } + +VOID +NTAPI +HalProcessorIdle(VOID) +{ + UNIMPLEMENTED; +} + /* EOF */ From 17189649afe3fcce678b666802b875ee584877a6 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Mon, 11 Sep 2006 15:49:42 +0000 Subject: [PATCH 159/488] For windows with WS_EX_DLGMODALFRAME sysmenu can be opened only by right mouse click svn path=/trunk/; revision=24074 --- reactos/dll/win32/user32/windows/nonclient.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/reactos/dll/win32/user32/windows/nonclient.c b/reactos/dll/win32/user32/windows/nonclient.c index 6510554a6c4..b403ab1061b 100644 --- a/reactos/dll/win32/user32/windows/nonclient.c +++ b/reactos/dll/win32/user32/windows/nonclient.c @@ -735,7 +735,7 @@ DefWndNCHitTest(HWND hWnd, POINT Point) return HTBORDER; } - if ((Style & WS_CAPTION) == WS_CAPTION) + if (Style & WS_CAPTION) { if (ExStyle & WS_EX_TOOLWINDOW) WindowRect.top += GetSystemMetrics(SM_CYSMCAPTION); @@ -751,11 +751,15 @@ DefWndNCHitTest(HWND hWnd, POINT Point) } else { - WindowRect.left += GetSystemMetrics(SM_CXSIZE); WindowRect.right -= GetSystemMetrics(SM_CXSIZE); } + + // On windows with WS_EX_DLGMODALFRAME and + // WS_EX_TOOLWINDOW there is no system menu button. + if (!(ExStyle & WS_EX_DLGMODALFRAME) && !(ExStyle & WS_EX_TOOLWINDOW)) + WindowRect.left += GetSystemMetrics(SM_CXSIZE); } - if (Point.x <= WindowRect.left) + if (Point.x < WindowRect.left) return HTSYSMENU; if (WindowRect.right <= Point.x) return HTCLOSE; From 4e03e0ec4a4ff76a15afed9216f6dcb1ed3e4861 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 11 Sep 2006 21:40:50 +0000 Subject: [PATCH 160/488] Those two #ifdefs were wrong on my setup (straightforward RosBE 3.4.2, and also updated to 3.4.4). So: 1. Removed the stricmp guard 2. Added a #ifdef->#undef solution If this break compilation on linux or on gcc 4 on win32 (very low probability, if any), let's think further. svn path=/trunk/; revision=24076 --- reactos/lib/libwine/string.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/reactos/lib/libwine/string.c b/reactos/lib/libwine/string.c index 04fc54cb3af..09a1de45432 100644 --- a/reactos/lib/libwine/string.c +++ b/reactos/lib/libwine/string.c @@ -3,7 +3,11 @@ #include "wine/port.h" #ifndef HAVE_STRCASECMP -# ifndef HAVE__STRICMP + +#ifdef strcasecmp +# undef strcasecmp +#endif + int strcasecmp( const char *str1, const char *str2 ) { const unsigned char *ustr1 = (const unsigned char *)str1; @@ -16,4 +20,3 @@ int strcasecmp( const char *str1, const char *str2 ) return toupper(*ustr1) - toupper(*ustr2); } #endif -#endif From 978da5c0aff5a31ff94b50ec253026403ad58086 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 12 Sep 2006 05:21:27 +0000 Subject: [PATCH 161/488] - Revert 24020 (good code, but buggy) and 24041 (bad code/revision). - This gets us as far as 24061(+24048) for booting. svn path=/trunk/; revision=24078 --- reactos/dll/ntdll/ldr/utils.c | 208 +++++++++++++------------ reactos/lib/rtl/image.c | 140 +++++++---------- reactos/ntoskrnl/include/internal/po.h | 58 +++++-- reactos/ntoskrnl/ke/thrdobj.c | 6 + reactos/ntoskrnl/ke/thrdschd.c | 2 + 5 files changed, 225 insertions(+), 189 deletions(-) diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 5fbb7d9aca0..f7a94cd4d07 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -1198,89 +1198,126 @@ LdrGetExportByName(PVOID BaseAddress, return (PVOID)NULL; } -/*++ -* @name LdrpSetProtection -* -* Local routine, used to set or reset pages protection. -* Used during PE relocation process. -* -* @param BaseAddress -* Base address of the image. -* -* @param Protection -* FALSE to disable protection, TRUE to enable it -* -* @return Usual NTSTATUS. -* -* @remarks None. -* -*--*/ -NTSTATUS -LdrpSetProtection(IN PVOID BaseAddress, - IN BOOLEAN Protection) + +/********************************************************************** + * NAME LOCAL + * LdrPerformRelocations + * + * DESCRIPTION + * Relocate a DLL's memory image. + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + * + * NOTE + * + */ +static NTSTATUS +LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, + PVOID ImageBase) { - PIMAGE_NT_HEADERS NtHeaders; - PIMAGE_SECTION_HEADER SectionHeader; - ULONG i; - PVOID Address; - SIZE_T Size; - NTSTATUS Status; - ULONG NewAccess, OldAccess; + PIMAGE_DATA_DIRECTORY RelocationDDir; + PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; + ULONG Count, ProtectSize, OldProtect, OldProtect2; + PVOID Page, ProtectPage, ProtectPage2; + PUSHORT TypeOffset; + ULONG_PTR Delta; + NTSTATUS Status; - NtHeaders = RtlImageNtHeader(BaseAddress); - - /* Ensure image is valid */ - if (NtHeaders == NULL) - return STATUS_INVALID_IMAGE_FORMAT; - - /* Get the first section header */ - SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); - - /* Loop through every section */ - for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++, SectionHeader++) + if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { - /* If section has no data - just skip to the next section */ - if (SectionHeader->SizeOfRawData == 0) - continue; + return STATUS_UNSUCCESSFUL; + } - /* We need to act only if section isn't RW */ - if (!(SectionHeader->Characteristics & IMAGE_SCN_MEM_WRITE)) + RelocationDDir = + &NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + + if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0) + { + return STATUS_SUCCESS; + } + + ProtectSize = PAGE_SIZE; + Delta = (ULONG_PTR)ImageBase - NTHeaders->OptionalHeader.ImageBase; + RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase + + RelocationDDir->VirtualAddress); + RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase + + RelocationDDir->VirtualAddress + RelocationDDir->Size); + + while (RelocationDir < RelocationEnd && + RelocationDir->SizeOfBlock > 0) + { + Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / + sizeof(USHORT); + Page = (PVOID)((ULONG_PTR)ImageBase + (ULONG_PTR)RelocationDir->VirtualAddress); + TypeOffset = (PUSHORT)(RelocationDir + 1); + + /* Unprotect the page(s) we're about to relocate. */ + ProtectPage = Page; + Status = NtProtectVirtualMemory(NtCurrentProcess(), + &ProtectPage, + &ProtectSize, + PAGE_READWRITE, + &OldProtect); + if (!NT_SUCCESS(Status)) { - if (Protection) + DPRINT1("Failed to unprotect relocation target.\n"); + return Status; + } + + if (RelocationDir->VirtualAddress + PAGE_SIZE < + NTHeaders->OptionalHeader.SizeOfImage) + { + ProtectPage2 = (PVOID)((ULONG_PTR)ProtectPage + PAGE_SIZE); + Status = NtProtectVirtualMemory(NtCurrentProcess(), + &ProtectPage2, + &ProtectSize, + PAGE_READWRITE, + &OldProtect2); + if (!NT_SUCCESS(Status)) { - /* Check if the section was also executable, then we should - give it PAGE_EXECUTE, otherwise just PAGE_READONLY */ - NewAccess = (SectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) ? PAGE_EXECUTE : PAGE_READONLY; - - /* Also check caching */ - NewAccess |= (SectionHeader->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) ? PAGE_NOCACHE : 0; - } - else - { - /* Set access to RW */ - NewAccess = PAGE_READWRITE; + DPRINT1("Failed to unprotect relocation target (2).\n"); + NtProtectVirtualMemory(NtCurrentProcess(), + &ProtectPage, + &ProtectSize, + OldProtect, + &OldProtect); + return Status; } + } + else + { + ProtectPage2 = NULL; + } - /* Get the address and size of the section, and set protectin accordingly */ - Address = (PVOID)((ULONG_PTR)BaseAddress + SectionHeader->VirtualAddress); - Size = SectionHeader->SizeOfRawData; + RelocationDir = LdrProcessRelocationBlock((ULONG_PTR)Page, + Count, + TypeOffset, + Delta); + if (RelocationDir == NULL) + return STATUS_UNSUCCESSFUL; - Status = NtProtectVirtualMemory(NtCurrentProcess(), - &Address, - &Size, - NewAccess, - &OldAccess); + /* Restore old page protection. */ + NtProtectVirtualMemory(NtCurrentProcess(), + &ProtectPage, + &ProtectSize, + OldProtect, + &OldProtect); - if (!NT_SUCCESS(Status)) - return Status; + if (ProtectPage2 != NULL) + { + NtProtectVirtualMemory(NtCurrentProcess(), + &ProtectPage2, + &ProtectSize, + OldProtect2, + &OldProtect2); } } - /* Instruction cache should be flushed if we enabled protection */ - if (Protection) - NtFlushInstructionCache(NtCurrentProcess(), NULL, 0); - - return STATUS_SUCCESS; + return STATUS_SUCCESS; } static NTSTATUS @@ -1861,32 +1898,12 @@ PEPFUNC LdrPEStartup (PVOID ImageBase, if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase) { DPRINT("LDR: Performing relocations\n"); - - /* Remove protection */ - Status = LdrpSetProtection(ImageBase, FALSE); + Status = LdrPerformRelocations(NTHeaders, ImageBase); if (!NT_SUCCESS(Status)) { - DPRINT1("LdrpSetProtection() failed with Status=0x%08X\n", Status); + DPRINT1("LdrPerformRelocations() failed\n"); return NULL; } - - /* Relocate */ - Status = LdrRelocateImageWithBias(ImageBase, 0, "", STATUS_SUCCESS, - STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT); - if (!NT_SUCCESS(Status)) - { - DPRINT1("LdrRelocateImageWithBias() failed with Status=0x%08X\n", Status); - return NULL; - } - - /* Set protection back */ - Status = LdrpSetProtection(ImageBase, TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("LdrpSetProtection() failed with Status=0x%08X\n", Status); - return NULL; - } - } if (Module != NULL) @@ -2061,13 +2078,10 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL, { DPRINT1("Relocating (%lx -> %p) %wZ\n", NtHeaders->OptionalHeader.ImageBase, ImageBase, &FullDosName); - - Status = LdrRelocateImageWithBias(ImageBase, 0, "", STATUS_SUCCESS, - STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT); - + Status = LdrPerformRelocations(NtHeaders, ImageBase); if (!NT_SUCCESS(Status)) { - DPRINT1("LdrRelocateImageWithBias() failed\n"); + DPRINT1("LdrPerformRelocations() failed\n"); NtUnmapViewOfSection (NtCurrentProcess (), ImageBase); NtClose (SectionHandle); RtlFreeUnicodeString(&FullDosName); diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index 388e3acac47..97b5a9b4643 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -3,10 +3,8 @@ * FILE: lib/rtl/image.c * PURPOSE: Image handling functions * Relocate functions were previously located in - * ntoskrnl/ldr/loader.c and - * dll/ntdll/ldr/utils.c files - * PROGRAMMER: Eric Kohl + original authors from loader.c and utils.c file - * Aleksey Bragin + * ntoskrnl/ldr/loader.c + * PROGRAMMER: Eric Kohl + original authors from loader.c file */ /* INCLUDES *****************************************************************/ @@ -151,76 +149,12 @@ RtlImageRvaToVa ( (ULONG_PTR)Section->VirtualAddress); } -PIMAGE_BASE_RELOCATION -LdrProcessRelocationBlockLongLong( - IN ULONG_PTR Address, - IN ULONG Count, - IN PUSHORT TypeOffset, - IN LONGLONG Delta - ) -{ - SHORT Offset; - USHORT Type; - USHORT i; - PUSHORT ShortPtr; - PULONG LongPtr; - - for (i = 0; i < Count; i++) - { - Offset = *TypeOffset & 0xFFF; - Type = *TypeOffset >> 12; - ShortPtr = (PUSHORT)(RVA(Address, Offset)); - - /* - * Don't relocate within the relocation section itself. - * GCC/LD generates sometimes relocation records for the relocation section. - * This is a bug in GCC/LD. - * Fix for it disabled, since it was only in ntoskrnl and not in ntdll - */ - /* - if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir || - (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd) - {*/ - switch (Type) - { - /* case IMAGE_REL_BASED_SECTION : */ - /* case IMAGE_REL_BASED_REL32 : */ - case IMAGE_REL_BASED_ABSOLUTE: - break; - - case IMAGE_REL_BASED_HIGH: - *ShortPtr += HIWORD(Delta); - break; - - case IMAGE_REL_BASED_LOW: - *ShortPtr += LOWORD(Delta); - break; - - case IMAGE_REL_BASED_HIGHLOW: - LongPtr = (PULONG)RVA(Address, Offset); - *LongPtr += Delta; - break; - - case IMAGE_REL_BASED_HIGHADJ: - case IMAGE_REL_BASED_MIPS_JMPADDR: - default: - DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); - DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset); - return (PIMAGE_BASE_RELOCATION)NULL; - } - - TypeOffset++; - } - - return (PIMAGE_BASE_RELOCATION)TypeOffset; -} - ULONG NTAPI LdrRelocateImageWithBias( IN PVOID BaseAddress, IN LONGLONG AdditionalBias, - IN PCCH LoaderName, + IN PCCH LoaderName, IN ULONG Success, IN ULONG Conflict, IN ULONG Invalid @@ -229,10 +163,14 @@ LdrRelocateImageWithBias( PIMAGE_NT_HEADERS NtHeaders; PIMAGE_DATA_DIRECTORY RelocationDDir; PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; - ULONG Count; - ULONG_PTR Address; + ULONG Count, i; + PVOID Address;//, MaxAddress; PUSHORT TypeOffset; - LONGLONG Delta; + ULONG_PTR Delta; + SHORT Offset; + USHORT Type; + PUSHORT ShortPtr; + PULONG LongPtr; NtHeaders = RtlImageNtHeader(BaseAddress); @@ -254,24 +192,64 @@ LdrRelocateImageWithBias( Delta = (ULONG_PTR)BaseAddress - NtHeaders->OptionalHeader.ImageBase + AdditionalBias; RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + RelocationDDir->VirtualAddress); RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size); + //MaxAddress = RVA(BaseAddress, DriverSize); while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) { Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - Address = (ULONG_PTR)RVA(BaseAddress, RelocationDir->VirtualAddress); + Address = RVA(BaseAddress, RelocationDir->VirtualAddress); TypeOffset = (PUSHORT)(RelocationDir + 1); - RelocationDir = LdrProcessRelocationBlockLongLong(Address, - Count, - TypeOffset, - Delta); - - if (RelocationDir == NULL) + for (i = 0; i < Count; i++) { - DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n"); - return Invalid; + Offset = *TypeOffset & 0xFFF; + Type = *TypeOffset >> 12; + ShortPtr = (PUSHORT)(RVA(Address, Offset)); + + /* Don't relocate after the end of the loaded driver */ + /*if ((PVOID)ShortPtr >= MaxAddress) + { + break; + }*/ + + /* + * Don't relocate within the relocation section itself. + * GCC/LD generates sometimes relocation records for the relocation section. + * This is a bug in GCC/LD. + */ + if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir || + (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd) + { + switch (Type) + { + case IMAGE_REL_BASED_ABSOLUTE: + break; + + case IMAGE_REL_BASED_HIGH: + *ShortPtr += HIWORD(Delta); + break; + + case IMAGE_REL_BASED_LOW: + *ShortPtr += LOWORD(Delta); + break; + + case IMAGE_REL_BASED_HIGHLOW: + LongPtr = (PULONG)ShortPtr; + *LongPtr += Delta; + break; + + case IMAGE_REL_BASED_HIGHADJ: + case IMAGE_REL_BASED_MIPS_JMPADDR: + default: + DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); + DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset); + return Invalid; + } + } + TypeOffset++; } + RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock); } return Success; diff --git a/reactos/ntoskrnl/include/internal/po.h b/reactos/ntoskrnl/include/internal/po.h index 6d6ce241f4e..5677d28cc8a 100644 --- a/reactos/ntoskrnl/include/internal/po.h +++ b/reactos/ntoskrnl/include/internal/po.h @@ -1,15 +1,54 @@ -#ifndef __NTOSKRNL_INCLUDE_INTERNAL_PO_H -#define __NTOSKRNL_INCLUDE_INTERNAL_PO_H +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/include/po.h +* PURPOSE: Internal header for the Power Manager +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ -extern PDEVICE_NODE PopSystemPowerDeviceNode; +// +// Define this if you want debugging support +// +#define _PO_DEBUG_ 0x00 +// +// These define the Debug Masks Supported +// +#define PO_STATE_DEBUG 0x01 + +// +// Debug/Tracing support +// +#if _PO_DEBUG_ +#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented +#define POTRACE DbgPrintEx +#else +#define POTRACE(x, ...) \ + if (x & PopTraceLevel) DbgPrint(__VA_ARGS__) +#endif +#else +#define POTRACE(x, ...) DPRINT(__VA_ARGS__) +#endif + +// +// Initialization routines +// VOID NTAPI PoInit( - PROS_LOADER_PARAMETER_BLOCK LoaderBlock, + PROS_LOADER_PARAMETER_BLOCK LoaderBlock, BOOLEAN ForceAcpiDisable ); +VOID +NTAPI +PoInitializePrcb( + IN PKPRCB Prcb +); + +// +// Power State routines +// NTSTATUS NTAPI PopSetSystemPowerState( @@ -22,10 +61,7 @@ PopCleanupPowerState( IN PPOWER_STATE PowerState ); -VOID -NTAPI -PoInitializePrcb( - IN PKPRCB Prcb -); - -#endif /* __NTOSKRNL_INCLUDE_INTERNAL_PO_H */ +// +// Global data inside the Power Manager +// +extern PDEVICE_NODE PopSystemPowerDeviceNode; diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 15d94351899..3841656a4a2 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -697,6 +697,12 @@ KeInitThread(IN OUT PKTHREAD Thread, Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE; Thread->KernelStackResident = TRUE; + /* ROS Mm HACK */ + MmUpdatePageDir((PEPROCESS)Process, + (PVOID)Thread->StackLimit, + KERNEL_STACK_SIZE); + MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); + /* Enter SEH to avoid crashes due to user mode */ Status = STATUS_SUCCESS; _SEH_TRY diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c index 9bda109f51f..942530724f8 100644 --- a/reactos/ntoskrnl/ke/thrdschd.c +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -150,6 +150,8 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus) KiIdleSummary |= Affinity; } + MmUpdatePageDir((PEPROCESS)PsGetCurrentProcess(),((PETHREAD)CurrentThread)->ThreadsProcess, sizeof(EPROCESS)); + /* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */ DPRINT("You are : %x, swapping to: %x.\n", OldThread, CurrentThread); ApcState = KiSwapContext(OldThread, CurrentThread); From 6b1e4db5b5760a5f6b2aa85c482075023eeea990 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 12 Sep 2006 05:37:14 +0000 Subject: [PATCH 162/488] - Partial revert of r20462/63. New HAL/Po/Ki code remains, but restored the original PsIdleThread code. I know what the bug is but I'm too tired to fix it, so I'd rather revert the broken part. - Install + 2nd stage + boot to desktop will not work in qemu, kernel-kqemu and vmware (all wax and I tested). svn path=/trunk/; revision=24079 --- reactos/ntoskrnl/ntoskrnl.rbuild | 1 + reactos/ntoskrnl/ps/idle.c | 115 +++++++++++++++++++++++++++++++ reactos/ntoskrnl/ps/psmgr.c | 72 +------------------ 3 files changed, 118 insertions(+), 70 deletions(-) create mode 100644 reactos/ntoskrnl/ps/idle.c diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index ce341471dfd..30f4e239246 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -292,6 +292,7 @@ debug.c + idle.c job.c kill.c notify.c diff --git a/reactos/ntoskrnl/ps/idle.c b/reactos/ntoskrnl/ps/idle.c new file mode 100644 index 00000000000..e46a744435c --- /dev/null +++ b/reactos/ntoskrnl/ps/idle.c @@ -0,0 +1,115 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ps/idle.c + * PURPOSE: Using idle time + * + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * David Welch (welch@cwcom.net) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +#if defined (ALLOC_PRAGMA) +#pragma alloc_text(INIT, PsInitIdleThread) +#endif + +/* FUNCTIONS *****************************************************************/ + +/** System idle thread procedure + * + */ +VOID STDCALL +PsIdleThreadMain(PVOID Context) +{ + KIRQL oldlvl; + + PKPRCB Prcb = KeGetCurrentPrcb(); + + for(;;) + { + if (Prcb->DpcData[0].DpcQueueDepth > 0) + { + KeRaiseIrql(DISPATCH_LEVEL,&oldlvl); + KiDispatchInterrupt(); + KeLowerIrql(oldlvl); + } + + NtYieldExecution(); + + Ke386HaltProcessor(); + } +} + +/* + * HACK-O-RAMA + * Antique vestigial code left alive for the sole purpose of First/Idle Thread + * creation until I can merge my fix for properly creating them. + */ +NTSTATUS +NTAPI +PsInitializeIdleOrFirstThread(PEPROCESS Process, + PETHREAD* ThreadPtr, + PKSTART_ROUTINE StartRoutine, + KPROCESSOR_MODE AccessMode, + BOOLEAN First) +{ + PETHREAD Thread; + PVOID KernelStack; + + Thread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); + RtlZeroMemory(Thread, sizeof(ETHREAD)); + Thread->ThreadsProcess = Process; + if (First) + { + KernelStack = P0BootStack; + } + else + { + KernelStack = (PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) + + KERNEL_STACK_SIZE); + } + KeInitializeThread(&Process->Pcb, + &Thread->Tcb, + PspSystemThreadStartup, + StartRoutine, + NULL, + NULL, + NULL, + KernelStack); + InitializeListHead(&Thread->IrpList); + *ThreadPtr = Thread; + return STATUS_SUCCESS; +} + +/* + * HACK-O-RAMA + * Antique vestigial code left alive for the sole purpose of First/Idle Thread + * creation until I can merge my fix for properly creating them. + */ +VOID +INIT_FUNCTION +NTAPI +PsInitIdleThread(VOID) +{ + PETHREAD IdleThread; + KIRQL oldIrql; + + PsInitializeIdleOrFirstThread(PsIdleProcess, + &IdleThread, + PsIdleThreadMain, + KernelMode, + FALSE); + + oldIrql = KiAcquireDispatcherLock (); + KiReadyThread(&IdleThread->Tcb); + KiReleaseDispatcherLock(oldIrql); + + KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; + KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); + KeSetAffinityThread(&IdleThread->Tcb, 1 << 0); +} diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index b4d71c0ee6d..df6d3c287ff 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -64,74 +64,6 @@ NTSTATUS STDCALL INIT_FUNCTION PspLookupKernelUserEntryPoints(VOID); /* FUNCTIONS ***************************************************************/ -VOID -FASTCALL -KiIdleLoop(VOID); - -/* FUNCTIONS *****************************************************************/ - -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ -VOID -INIT_FUNCTION -NTAPI -PsInitHackThread(VOID) -{ - PETHREAD IdleThread; - KIRQL oldIrql; - - IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); - RtlZeroMemory(IdleThread, sizeof(ETHREAD)); - IdleThread->ThreadsProcess = PsIdleProcess; - KeInitializeThread(&PsIdleProcess->Pcb, - &IdleThread->Tcb, - PspSystemThreadStartup, - (PVOID)KiIdleLoop, - NULL, - NULL, - NULL, - P0BootStack); - InitializeListHead(&IdleThread->IrpList); - - oldIrql = KiAcquireDispatcherLock (); - KiReadyThread(&IdleThread->Tcb); - KiReleaseDispatcherLock(oldIrql); - - KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; - KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); - KeSetAffinityThread(&IdleThread->Tcb, 1 << 0); -} - -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ -VOID -INIT_FUNCTION -NTAPI -PsInitHackThread2(IN PETHREAD *Hack) -{ - PETHREAD IdleThread; - - IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); - RtlZeroMemory(IdleThread, sizeof(ETHREAD)); - IdleThread->ThreadsProcess = PsInitialSystemProcess; - KeInitializeThread(&PsInitialSystemProcess->Pcb, - &IdleThread->Tcb, - PspSystemThreadStartup, - NULL, - NULL, - NULL, - NULL, - P0BootStack); - InitializeListHead(&IdleThread->IrpList); - *Hack = IdleThread; -} - VOID INIT_FUNCTION NTAPI @@ -140,7 +72,7 @@ PiInitProcessManager(VOID) PsInitJobManagment(); PsInitProcessManagment(); PsInitThreadManagment(); - PsInitHackThread(); + PsInitIdleThread(); } VOID @@ -183,7 +115,7 @@ PsInitThreadManagment(VOID) ObjectTypeInitializer.DeleteProcedure = PspDeleteThread; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsThreadType); - PsInitHackThread2(&FirstThread); + PsInitializeIdleOrFirstThread(PsInitialSystemProcess, &FirstThread, NULL, KernelMode, TRUE); FirstThread->Tcb.State = Running; FirstThread->Tcb.FreezeCount = 0; FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */ From 2829cc5982b1b70739bb19f216858e0f8aa1da81 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 12 Sep 2006 13:54:52 +0000 Subject: [PATCH 163/488] - Re-merge 24062+24063, with a minor difference, they work now. svn path=/trunk/; revision=24080 --- reactos/ntoskrnl/ke/i386/ctxswitch.S | 9 +++ reactos/ntoskrnl/ntoskrnl.rbuild | 1 - reactos/ntoskrnl/ps/idle.c | 115 --------------------------- reactos/ntoskrnl/ps/psmgr.c | 73 ++++++++++++++++- 4 files changed, 80 insertions(+), 118 deletions(-) delete mode 100644 reactos/ntoskrnl/ps/idle.c diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 6cfa4f9b5f0..04a16d18ca8 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -544,10 +544,19 @@ MainLoop: #endif jz CheckSchedule + /* Raise to DISPATCH_LEVEL */ + mov ecx, DISPATCH_LEVEL + call @KfRaiseIrql@4 + mov edi, eax + /* Handle the above */ lea ecx, [ebx+KPCR_PRCB_DATA] call @KiRetireDpcList@4 + /* Lower IRQL */ + mov ecx, edi + call @KfLowerIrql@4 + CheckSchedule: /* Check if a next thread is queued */ cmp dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0 diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 30f4e239246..ce341471dfd 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -292,7 +292,6 @@ debug.c - idle.c job.c kill.c notify.c diff --git a/reactos/ntoskrnl/ps/idle.c b/reactos/ntoskrnl/ps/idle.c deleted file mode 100644 index e46a744435c..00000000000 --- a/reactos/ntoskrnl/ps/idle.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ps/idle.c - * PURPOSE: Using idle time - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * David Welch (welch@cwcom.net) - */ - -/* INCLUDES *****************************************************************/ - -#include -#define NDEBUG -#include - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, PsInitIdleThread) -#endif - -/* FUNCTIONS *****************************************************************/ - -/** System idle thread procedure - * - */ -VOID STDCALL -PsIdleThreadMain(PVOID Context) -{ - KIRQL oldlvl; - - PKPRCB Prcb = KeGetCurrentPrcb(); - - for(;;) - { - if (Prcb->DpcData[0].DpcQueueDepth > 0) - { - KeRaiseIrql(DISPATCH_LEVEL,&oldlvl); - KiDispatchInterrupt(); - KeLowerIrql(oldlvl); - } - - NtYieldExecution(); - - Ke386HaltProcessor(); - } -} - -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ -NTSTATUS -NTAPI -PsInitializeIdleOrFirstThread(PEPROCESS Process, - PETHREAD* ThreadPtr, - PKSTART_ROUTINE StartRoutine, - KPROCESSOR_MODE AccessMode, - BOOLEAN First) -{ - PETHREAD Thread; - PVOID KernelStack; - - Thread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); - RtlZeroMemory(Thread, sizeof(ETHREAD)); - Thread->ThreadsProcess = Process; - if (First) - { - KernelStack = P0BootStack; - } - else - { - KernelStack = (PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) + - KERNEL_STACK_SIZE); - } - KeInitializeThread(&Process->Pcb, - &Thread->Tcb, - PspSystemThreadStartup, - StartRoutine, - NULL, - NULL, - NULL, - KernelStack); - InitializeListHead(&Thread->IrpList); - *ThreadPtr = Thread; - return STATUS_SUCCESS; -} - -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ -VOID -INIT_FUNCTION -NTAPI -PsInitIdleThread(VOID) -{ - PETHREAD IdleThread; - KIRQL oldIrql; - - PsInitializeIdleOrFirstThread(PsIdleProcess, - &IdleThread, - PsIdleThreadMain, - KernelMode, - FALSE); - - oldIrql = KiAcquireDispatcherLock (); - KiReadyThread(&IdleThread->Tcb); - KiReleaseDispatcherLock(oldIrql); - - KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; - KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); - KeSetAffinityThread(&IdleThread->Tcb, 1 << 0); -} diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index df6d3c287ff..1346d98f11b 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -64,6 +64,75 @@ NTSTATUS STDCALL INIT_FUNCTION PspLookupKernelUserEntryPoints(VOID); /* FUNCTIONS ***************************************************************/ +VOID +FASTCALL +KiIdleLoop(VOID); + +/* FUNCTIONS *****************************************************************/ + +/* + * HACK-O-RAMA + * Antique vestigial code left alive for the sole purpose of First/Idle Thread + * creation until I can merge my fix for properly creating them. + */ +VOID +INIT_FUNCTION +NTAPI +PsInitHackThread(VOID) +{ + PETHREAD IdleThread; + KIRQL oldIrql; + + IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); + RtlZeroMemory(IdleThread, sizeof(ETHREAD)); + IdleThread->ThreadsProcess = PsIdleProcess; + KeInitializeThread(&PsIdleProcess->Pcb, + &IdleThread->Tcb, + PspSystemThreadStartup, + (PVOID)KiIdleLoop, + NULL, + NULL, + NULL, + (PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) + + KERNEL_STACK_SIZE)); + InitializeListHead(&IdleThread->IrpList); + + oldIrql = KiAcquireDispatcherLock (); + KiReadyThread(&IdleThread->Tcb); + KiReleaseDispatcherLock(oldIrql); + + KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; + KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); + KeSetAffinityThread(&IdleThread->Tcb, 1 << 0); +} + +/* + * HACK-O-RAMA + * Antique vestigial code left alive for the sole purpose of First/Idle Thread + * creation until I can merge my fix for properly creating them. + */ +VOID +INIT_FUNCTION +NTAPI +PsInitHackThread2(IN PETHREAD *Hack) +{ + PETHREAD IdleThread; + + IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); + RtlZeroMemory(IdleThread, sizeof(ETHREAD)); + IdleThread->ThreadsProcess = PsInitialSystemProcess; + KeInitializeThread(&PsInitialSystemProcess->Pcb, + &IdleThread->Tcb, + PspSystemThreadStartup, + NULL, + NULL, + NULL, + NULL, + P0BootStack); + InitializeListHead(&IdleThread->IrpList); + *Hack = IdleThread; +} + VOID INIT_FUNCTION NTAPI @@ -72,7 +141,7 @@ PiInitProcessManager(VOID) PsInitJobManagment(); PsInitProcessManagment(); PsInitThreadManagment(); - PsInitIdleThread(); + PsInitHackThread(); } VOID @@ -115,7 +184,7 @@ PsInitThreadManagment(VOID) ObjectTypeInitializer.DeleteProcedure = PspDeleteThread; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsThreadType); - PsInitializeIdleOrFirstThread(PsInitialSystemProcess, &FirstThread, NULL, KernelMode, TRUE); + PsInitHackThread2(&FirstThread); FirstThread->Tcb.State = Running; FirstThread->Tcb.FreezeCount = 0; FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */ From fec5904b5087c2148e843141e2295a1c89be169e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 12 Sep 2006 15:19:17 +0000 Subject: [PATCH 164/488] [AUDIT] This file only include other files, so it can't be dirty. Additionally, define GUID_DEVICE_SYS_BUTTON svn path=/trunk/; revision=24081 --- reactos/lib/wdmguid/wdmguid.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reactos/lib/wdmguid/wdmguid.c b/reactos/lib/wdmguid/wdmguid.c index 3c3fff42479..44a0383e7e3 100644 --- a/reactos/lib/wdmguid/wdmguid.c +++ b/reactos/lib/wdmguid/wdmguid.c @@ -7,4 +7,8 @@ #include #include +/* FIXME: shouldn't go there! */ +DEFINE_GUID(GUID_DEVICE_SYS_BUTTON, + 0x4AFA3D53L, 0x74A7, 0x11d0, 0xbe, 0x5e, 0x00, 0xA0, 0xC9, 0x06, 0x28, 0x57); + /* EOF */ From 2140d54ca5437af61f03807a52c7e21469ded3d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 12 Sep 2006 15:19:51 +0000 Subject: [PATCH 165/488] Start to support GUID_DEVICE_SYS_BUTTON interface. It is required to handle keyboards with power buttons (wake/sleep/power) (This commit is done now to be able to debug an APC problem) svn path=/trunk/; revision=24082 --- reactos/ntoskrnl/include/internal/po.h | 9 +++ reactos/ntoskrnl/ntoskrnl.rbuild | 81 ++++++++++----------- reactos/ntoskrnl/po/events.c | 97 ++++++++++++++++++++++++++ reactos/ntoskrnl/po/power.c | 11 +++ 4 files changed, 158 insertions(+), 40 deletions(-) create mode 100644 reactos/ntoskrnl/po/events.c diff --git a/reactos/ntoskrnl/include/internal/po.h b/reactos/ntoskrnl/include/internal/po.h index 5677d28cc8a..98f1c3dc527 100644 --- a/reactos/ntoskrnl/include/internal/po.h +++ b/reactos/ntoskrnl/include/internal/po.h @@ -6,6 +6,8 @@ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ +#include + // // Define this if you want debugging support // @@ -61,6 +63,13 @@ PopCleanupPowerState( IN PPOWER_STATE PowerState ); +NTSTATUS +CALLBACK +PopAddRemoveSysCapsCallback( + IN PVOID NotificationStructure, + IN PVOID Context +); + // // Global data inside the Power Manager // diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index ce341471dfd..141fab2e3cc 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -32,15 +32,15 @@ abios.c cpu.c ctxswitch.S - clock.S + clock.S exp.c - + kiinit.c ldt.c thread.c trap.s usercall_asm.S - userapc.c + userapc.c v86vdm.c v86m_sup.S @@ -70,10 +70,10 @@ usercall.c wait.c - - irqhand.S - irq.c - + + irqhand.S + irq.c + cacheman.c copy.c @@ -129,7 +129,7 @@ callback.c dbgctrl.c error.c - efi.c + efi.c event.c evtpair.c fmutex.c @@ -170,7 +170,7 @@ inbv.c - + adapter.c arcname.c bootlog.c @@ -182,31 +182,31 @@ drvrlist.c error.c event.c - file.c - iocomp.c - iofunc.c - iomgr.c - iowork.c - irp.c - irq.c - mdl.c - rawfs.c - remlock.c - resource.c - util.c - symlink.c - timer.c - volume.c - - - plugplay.c - pnpdma.c - pnpmgr.c - pnpnotify.c - pnpreport.c - pnproot.c - - + file.c + iocomp.c + iofunc.c + iomgr.c + iowork.c + irp.c + irq.c + mdl.c + rawfs.c + remlock.c + resource.c + util.c + symlink.c + timer.c + volume.c + + + plugplay.c + pnpdma.c + pnpmgr.c + pnpnotify.c + pnpreport.c + pnproot.c + + bochs.c @@ -289,6 +289,7 @@ power.c + events.c debug.c @@ -331,13 +332,13 @@ - vdmmain.c - vdmexec.c + vdmmain.c + vdmexec.c - - - wmi.c - + + + wmi.c + ntoskrnl.rc -nostartfiles -nostdlib diff --git a/reactos/ntoskrnl/po/events.c b/reactos/ntoskrnl/po/events.c new file mode 100644 index 00000000000..5fbc3943c25 --- /dev/null +++ b/reactos/ntoskrnl/po/events.c @@ -0,0 +1,97 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/po/events.c + * PURPOSE: Power Manager + * + * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + */ + +#include +//#define NDEBUG +#include + +NTSTATUS CALLBACK +PopAddRemoveSysCapsCallback( + IN PVOID NotificationStructure, + IN PVOID Context) +{ + PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE DeviceHandle; + IO_STATUS_BLOCK IoStatusBlock; + BOOLEAN Arrival; + ULONG Caps; + NTSTATUS Status; + + DPRINT("PopAddRemoveSysCapsCallback(%p %p)\n", + NotificationStructure, Context); + + Notification = (PDEVICE_INTERFACE_CHANGE_NOTIFICATION)NotificationStructure; + if (Notification->Version != 1) + return STATUS_REVISION_MISMATCH; + if (Notification->Size != sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION)) + return STATUS_INVALID_PARAMETER; + if (RtlCompareMemory(&Notification->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID) == sizeof(GUID))) + Arrival = TRUE; + else if (RtlCompareMemory(&Notification->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID) == sizeof(GUID))) + Arrival = FALSE; + else + return STATUS_INVALID_PARAMETER; + + if (Arrival) + { + DPRINT("Arrival of %wZ\n", Notification->SymbolicLinkName); + + /* Open device */ + InitializeObjectAttributes( + &ObjectAttributes, + Notification->SymbolicLinkName, + OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwOpenFile( + &DeviceHandle, + FILE_READ_DATA, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenFile() failed with status 0x%08lx\n", Status); + return Status; + } + + /* Send IOCTL_GET_SYS_BUTTON_CAPS to get new caps */ + Status = ZwDeviceIoControlFile( + DeviceHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + IOCTL_GET_SYS_BUTTON_CAPS, + NULL, + 0, + &Caps, + sizeof(Caps)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwDeviceIoControlFile(IOCTL_GET_SYS_BUTTON_CAPS) failed with status 0x%08lx\n", Status); + ZwClose(DeviceHandle); + return Status; + } + /* FIXME: What do do with this? */ + DPRINT1("Device capabilities: 0x%lx\n", Caps); + + /* Send IOCTL_GET_SYS_BUTTON_CAPS to get current caps */ + /* FIXME: Set a IO completion routine on it to be able to send a new one */ + DPRINT1("Send a IOCTL_GET_SYS_BUTTON_EVENT\n"); + return ZwClose(DeviceHandle); + } + else + { + DPRINT1("Removal of a power capable device not implemented\n"); + return STATUS_NOT_IMPLEMENTED; + } +} diff --git a/reactos/ntoskrnl/po/power.c b/reactos/ntoskrnl/po/power.c index 4589cba3c18..da9b41e0e0f 100644 --- a/reactos/ntoskrnl/po/power.c +++ b/reactos/ntoskrnl/po/power.c @@ -308,6 +308,8 @@ NTAPI PoInit(PROS_LOADER_PARAMETER_BLOCK LoaderBlock, BOOLEAN ForceAcpiDisable) { + PVOID NotificationEntry; + if (ForceAcpiDisable) { /* Set the ACPI State to False if it's been forced that way */ @@ -318,6 +320,15 @@ PoInit(PROS_LOADER_PARAMETER_BLOCK LoaderBlock, /* Otherwise check the LoaderBlock's Flag */ PopAcpiPresent = (LoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE; } + + IoRegisterPlugPlayNotification( + EventCategoryDeviceInterfaceChange, + 0, /* The registry has not been initialized yet */ + (PVOID)&GUID_DEVICE_SYS_BUTTON, + IopRootDeviceNode->PhysicalDeviceObject->DriverObject, + PopAddRemoveSysCapsCallback, + NULL, + &NotificationEntry); } VOID From 3b58ac193232d266e89b0b60cb06fecd0d835268 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 12 Sep 2006 18:51:05 +0000 Subject: [PATCH 166/488] Fix last things preventing me from compiling the tree: vsnprintt -> _vsnprintf in the wine/unicode.h and in riched20 svn path=/trunk/; revision=24083 --- reactos/dll/win32/riched20/writer.c | 2 +- reactos/include/reactos/wine/unicode.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/riched20/writer.c b/reactos/dll/win32/riched20/writer.c index c8d1226c894..3054e2fec9e 100644 --- a/reactos/dll/win32/riched20/writer.c +++ b/reactos/dll/win32/riched20/writer.c @@ -116,7 +116,7 @@ ME_StreamOutPrint(ME_TextEditor *editor, const char *format, ...) va_list valist; va_start(valist, format); - len = vsnprintf(string, sizeof(string), format, valist); + len = _vsnprintf(string, sizeof(string), format, valist); va_end(valist); return ME_StreamOutMove(editor, string, len); diff --git a/reactos/include/reactos/wine/unicode.h b/reactos/include/reactos/wine/unicode.h index 97b417a7f23..d65876d5d6e 100644 --- a/reactos/include/reactos/wine/unicode.h +++ b/reactos/include/reactos/wine/unicode.h @@ -37,7 +37,7 @@ #define sprintfW swprintf #define vsprintfW vswprintf #define snprintfW _snwprintf -#define vsnprintfW vsnwprintf +#define vsnprintfW _vsnwprintf #ifndef WINE_UNICODE_API #define WINE_UNICODE_API __attribute__((dllimport)) From 3fd92a4f96e48068a6bb9506f5adcc5fb9984ebe Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 12 Sep 2006 21:02:39 +0000 Subject: [PATCH 167/488] Revert changes from r23620 until a better solution can be found as it breaks opening of cpl applets with VS. The 'DebugSettings' should be stored in the .user file. svn path=/trunk/; revision=24084 --- reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp index 6e5c7c391bb..756f05611d3 100644 --- a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp @@ -243,14 +243,6 @@ MSVCBackend::_generate_vcproj ( const Module& module ) fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", exe ? 1 : dll ? 2 : lib ? 4 : -1 ); fprintf ( OUT, "\t\t\tCharacterSet=\"2\">\r\n" ); - if ( module_type == ".cpl" && configuration.VSProjectVersion == "8.00") - { - fprintf ( OUT, "\t\t\t" ); - } - fprintf ( OUT, "\t\t\t Date: Tue, 12 Sep 2006 21:18:22 +0000 Subject: [PATCH 168/488] Don't call notification procedures with APC disabled, it may lead to some strange results. Thanks Alex for the time he took to help me to debug this issue svn path=/trunk/; revision=24085 --- reactos/ntoskrnl/io/pnpmgr/pnpnotify.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c b/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c index 1960c2209ba..f51569df013 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c @@ -202,6 +202,7 @@ IopNotifyPlugPlayNotification( IN PVOID EventCategoryData2) { PPNP_NOTIFY_ENTRY ChangeEntry; + PLIST_ENTRY ListEntry; PVOID NotificationStructure; BOOLEAN CallCurrentEntry; @@ -265,9 +266,10 @@ IopNotifyPlugPlayNotification( /* Loop through procedures registred in PnpNotifyListHead * list to find those that meet some criteria. */ - - LIST_FOR_EACH(ChangeEntry,&PnpNotifyListHead, PNP_NOTIFY_ENTRY, PnpNotifyList) + ListEntry = PnpNotifyListHead.Flink; + while (ListEntry != &PnpNotifyListHead) { + ChangeEntry = CONTAINING_RECORD(ListEntry, PNP_NOTIFY_ENTRY, PnpNotifyList); CallCurrentEntry = FALSE; switch (EventCategory) @@ -298,15 +300,22 @@ IopNotifyPlugPlayNotification( } } + /* Move to the next element now, as callback may unregister itself */ + ListEntry = ListEntry->Flink; + /* FIXME: If ListEntry was the last element and that callback registers + * new notifications, those won't be checked... */ + if (CallCurrentEntry) { /* Call entry into new allocated memory */ DPRINT("IopNotifyPlugPlayNotification(): found suitable callback %p\n", ChangeEntry); + KeReleaseGuardedMutex(&PnpNotifyListLock); (ChangeEntry->PnpNotificationProc)( NotificationStructure, ChangeEntry->Context); + KeAcquireGuardedMutex(&PnpNotifyListLock); } } From c0cda24302561d031a073f914486b561313bc7df Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 12 Sep 2006 21:33:56 +0000 Subject: [PATCH 169/488] Just one entrypoint="0" is enough svn path=/trunk/; revision=24086 --- reactos/dll/3rdparty/freetype/freetype.rbuild | 2 +- reactos/dll/win32/lsasrv/lsasrv.rbuild | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/dll/3rdparty/freetype/freetype.rbuild b/reactos/dll/3rdparty/freetype/freetype.rbuild index cf22185e459..ec83eec9377 100644 --- a/reactos/dll/3rdparty/freetype/freetype.rbuild +++ b/reactos/dll/3rdparty/freetype/freetype.rbuild @@ -1,4 +1,4 @@ - + include diff --git a/reactos/dll/win32/lsasrv/lsasrv.rbuild b/reactos/dll/win32/lsasrv/lsasrv.rbuild index 48bcf86221e..1f5003e7032 100644 --- a/reactos/dll/win32/lsasrv/lsasrv.rbuild +++ b/reactos/dll/win32/lsasrv/lsasrv.rbuild @@ -1,4 +1,4 @@ - + . . From d99f96a29544dacf53f419347ee07417097d19f0 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 00:20:46 +0000 Subject: [PATCH 170/488] - Implement KiAcquireDeviceQueueLock/KiReleaseDeviceQueueLock for locking KDEVICE_QUEUEs, since they can be used from Threaded DPCs which don't execute at DISPATCH_LEVEL, so the lock needs to be acquired differently. - Add ASSERT_DEVICE_QUEUE and ASSERTify + reformat kqueue.c. - Implement KeRemoveByKeyDeviceQueueIfBusy. - Cleanup exception.c - Remove dangerous/broken KeGetCurrentIrql() define. svn path=/trunk/; revision=24087 --- reactos/include/ddk/winddk.h | 3 + reactos/ntoskrnl/include/internal/i386/ke.h | 1 - reactos/ntoskrnl/include/internal/ke_x.h | 38 +++ reactos/ntoskrnl/ke/exception.c | 28 +-- reactos/ntoskrnl/ke/kqueue.c | 260 +++++++++++--------- 5 files changed, 200 insertions(+), 130 deletions(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 3e43a6095d1..4bdd4d8c53c 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -1093,6 +1093,9 @@ typedef struct _KLOCK_QUEUE_HANDLE { ((Object)->Type == DpcObject) || \ ((Object)->Type == ThreadedDpcObject)) +#define ASSERT_DEVICE_QUEUE(Object) \ + ASSERT((Object)->Type == DeviceQueueObject) + typedef struct _KDPC { UCHAR Type; diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index c1c7a6727e6..62c496163eb 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -124,7 +124,6 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine, #define LOCK "lock ; " #else #define LOCK "" -#define KeGetCurrentIrql() (((PKPCR)KPCR_BASE)->Irql) #endif #if defined(__GNUC__) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 8db34413bf9..f9580053cc3 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -696,6 +696,44 @@ KiReleaseProcessLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle) KeReleaseInStackQueuedSpinLockFromDpcLevel(Handle); } +FORCEINLINE +VOID +KiAcquireDeviceQueueLock(IN PKDEVICE_QUEUE DeviceQueue, + IN PKLOCK_QUEUE_HANDLE DeviceLock) +{ + /* Check if we were called from a threaded DPC */ + if (KeGetCurrentPrcb()->DpcThreadActive) + { + /* Lock the Queue, we're not at DPC level */ + KeAcquireInStackQueuedSpinLock(&DeviceQueue->Lock, DeviceLock); + } + else + { + /* We must be at DPC level, acquire the lock safely */ + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + KeAcquireInStackQueuedSpinLockAtDpcLevel(&DeviceQueue->Lock, + DeviceLock); + } +} + +FORCEINLINE +VOID +KiReleaseDeviceQueueLock(IN PKLOCK_QUEUE_HANDLE DeviceLock) +{ + /* Check if we were called from a threaded DPC */ + if (KeGetCurrentPrcb()->DpcThreadActive) + { + /* Unlock the Queue, we're not at DPC level */ + KeReleaseInStackQueuedSpinLock(DeviceLock); + } + else + { + /* We must be at DPC level, release the lock safely */ + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + KeReleaseInStackQueuedSpinLockFromDpcLevel(DeviceLock); + } +} + // // This routine queues a thread that is ready on the PRCB's ready lists. // If this thread cannot currently run on this CPU, then the thread is diff --git a/reactos/ntoskrnl/ke/exception.c b/reactos/ntoskrnl/ke/exception.c index 4f762dd7b65..1caf27f660a 100644 --- a/reactos/ntoskrnl/ke/exception.c +++ b/reactos/ntoskrnl/ke/exception.c @@ -1,18 +1,18 @@ /* - * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/exception.c * PURPOSE: Platform independent exception handling - * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG #include -/* FUNCTIONS ****************************************************************/ +/* INCLUDES ******************************************************************/ VOID NTAPI @@ -46,11 +46,7 @@ KiContinue(IN PCONTEXT Context, KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); /* Raise to APC_LEVEL, only if needed */ - if (KeGetCurrentIrql() < APC_LEVEL) - { - /* Raise to APC_LEVEL */ - KeRaiseIrql(APC_LEVEL, &OldIrql); - } + if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql); /* Set up SEH to validate the context */ _SEH_TRY @@ -75,6 +71,7 @@ KiContinue(IN PCONTEXT Context, } _SEH_HANDLE { + /* Save the exception code */ Status = _SEH_GetExceptionCode(); } _SEH_END; @@ -88,18 +85,17 @@ KiContinue(IN PCONTEXT Context, NTSTATUS NTAPI -KiRaiseException(PEXCEPTION_RECORD ExceptionRecord, - PCONTEXT Context, - PKEXCEPTION_FRAME ExceptionFrame, - PKTRAP_FRAME TrapFrame, - BOOLEAN SearchFrames) +KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PKTRAP_FRAME TrapFrame, + IN BOOLEAN SearchFrames) { KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); CONTEXT LocalContext; EXCEPTION_RECORD LocalExceptionRecord; ULONG ParameterCount, Size; NTSTATUS Status = STATUS_SUCCESS; - DPRINT1("KiRaiseException\n"); /* Set up SEH */ _SEH_TRY @@ -143,10 +139,12 @@ KiRaiseException(PEXCEPTION_RECORD ExceptionRecord, } _SEH_HANDLE { + /* Get the exception code */ Status = _SEH_GetExceptionCode(); } _SEH_END; + /* Make sure we didn't crash in SEH */ if (NT_SUCCESS(Status)) { /* Convert the context record */ diff --git a/reactos/ntoskrnl/ke/kqueue.c b/reactos/ntoskrnl/ke/kqueue.c index 954f3811a09..a3a408a2238 100644 --- a/reactos/ntoskrnl/ke/kqueue.c +++ b/reactos/ntoskrnl/ke/kqueue.c @@ -1,16 +1,12 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PURPOSE: ReactOS kernel + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/kqueue.c * PURPOSE: Implement device queues - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Several optimizations and implement - * usage of Inserted flag + reformat and - * add debug output. - * David Welch (welch@mcmail.com) + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES ****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG @@ -20,16 +16,11 @@ /* * @implemented - * - * FUNCTION: Intializes a device queue - * ARGUMENTS: - * DeviceQueue = Device queue to initialize */ VOID -STDCALL +NTAPI KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue) { - /* Initialize the Header */ DeviceQueue->Type = DeviceQueueObject; DeviceQueue->Size = sizeof(KDEVICE_QUEUE); @@ -44,48 +35,41 @@ KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue) /* * @implemented - * - * FUNCTION: Inserts an entry in a device queue - * ARGUMENTS: - * DeviceQueue = Queue to insert the entry in - * DeviceQueueEntry = Entry to insert - * RETURNS: False is the device queue wasn't busy - * True otherwise */ BOOLEAN -STDCALL +NTAPI KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry) { + KLOCK_QUEUE_HANDLE DeviceLock; BOOLEAN Inserted; + ASSERT_DEVICE_QUEUE(DeviceQueue); - DPRINT("KeInsertDeviceQueue(DeviceQueue %x)\n", DeviceQueue); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - - /* Lock the Queue */ - KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock); - - if (!DeviceQueue->Busy) { + /* Lock the queue */ + KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); + /* Check if it's not busy */ + if (!DeviceQueue->Busy) + { /* Set it as busy */ Inserted = FALSE; DeviceQueue->Busy = TRUE; - - } else { - + } + else + { /* Insert it into the list */ Inserted = TRUE; InsertTailList(&DeviceQueue->DeviceListHead, &DeviceQueueEntry->DeviceListEntry); - - } /* Sert the Insert state into the entry */ DeviceQueueEntry->Inserted = Inserted; - /* Release lock and return */ - KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock); + /* Release the lock */ + KiReleaseDeviceQueueLock(&DeviceLock); + + /* Return the state */ return Inserted; } @@ -93,29 +77,30 @@ KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, * @implemented */ BOOLEAN -STDCALL +NTAPI KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, IN ULONG SortKey) { + KLOCK_QUEUE_HANDLE DeviceLock; BOOLEAN Inserted; + ASSERT_DEVICE_QUEUE(DeviceQueue); - DPRINT("KeInsertByKeyDeviceQueue(DeviceQueue %x)\n", DeviceQueue); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - - /* Acquire the Lock */ - KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock); + /* Lock the queue */ + KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); /* Set the Sort Key */ - DeviceQueueEntry->SortKey=SortKey; + DeviceQueueEntry->SortKey = SortKey; - if (!DeviceQueue->Busy) { - - DeviceQueue->Busy=TRUE; + /* Check if it's not busy */ + if (!DeviceQueue->Busy) + { + /* Set it as busy */ Inserted = FALSE; - - } else { - + DeviceQueue->Busy = TRUE; + } + else + { /* Insert new entry after the last entry with SortKey less or equal to passed-in SortKey */ InsertAscendingListFIFO(&DeviceQueue->DeviceListHead, DeviceQueueEntry, @@ -125,43 +110,38 @@ KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, Inserted = TRUE; } - /* Reset the Inserted State */ - DeviceQueueEntry->Inserted = Inserted; + /* Release the lock */ + KiReleaseDeviceQueueLock(&DeviceLock); - /* Release Lock and Return */ - KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock); + /* Return the state */ return Inserted; } /* * @implemented - * - * FUNCTION: Removes an entry from a device queue - * ARGUMENTS: - * DeviceQueue = Queue to remove the entry - * RETURNS: The removed entry */ PKDEVICE_QUEUE_ENTRY -STDCALL +NTAPI KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue) { PLIST_ENTRY ListEntry; PKDEVICE_QUEUE_ENTRY ReturnEntry; + KLOCK_QUEUE_HANDLE DeviceLock; + ASSERT_DEVICE_QUEUE(DeviceQueue); - DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n", DeviceQueue); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - - /* Acquire the Lock */ - KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock); + /* Lock the queue */ + KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); ASSERT(DeviceQueue->Busy); - /* An attempt to remove an entry from an empty (and busy) queue sets the queue idle */ - if (IsListEmpty(&DeviceQueue->DeviceListHead)) { + /* Check if this is an empty queue */ + if (IsListEmpty(&DeviceQueue->DeviceListHead)) + { + /* Set it to idle and return nothing*/ DeviceQueue->Busy = FALSE; ReturnEntry = NULL; - - } else { - + } + else + { /* Remove the Entry from the List */ ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead); ReturnEntry = CONTAINING_RECORD(ListEntry, @@ -172,8 +152,10 @@ KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue) ReturnEntry->Inserted = FALSE; } - /* Release lock and Return */ - KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock); + /* Release the lock */ + KiReleaseDeviceQueueLock(&DeviceLock); + + /* Return the entry */ return ReturnEntry; } @@ -181,33 +163,34 @@ KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue) * @implemented */ PKDEVICE_QUEUE_ENTRY -STDCALL -KeRemoveByKeyDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue, - IN ULONG SortKey) +NTAPI +KeRemoveByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, + IN ULONG SortKey) { PLIST_ENTRY ListEntry; PKDEVICE_QUEUE_ENTRY ReturnEntry; + KLOCK_QUEUE_HANDLE DeviceLock; + ASSERT_DEVICE_QUEUE(DeviceQueue); - DPRINT("KeRemoveByKeyDeviceQueue(DeviceQueue %x)\n", DeviceQueue); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - - /* Acquire the Lock */ - KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock); + /* Lock the queue */ + KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); ASSERT(DeviceQueue->Busy); - /* An attempt to remove an entry from an empty (and busy) queue sets the queue idle */ - if (IsListEmpty(&DeviceQueue->DeviceListHead)) { - + /* Check if this is an empty queue */ + if (IsListEmpty(&DeviceQueue->DeviceListHead)) + { + /* Set it to idle and return nothing*/ DeviceQueue->Busy = FALSE; ReturnEntry = NULL; - - } else { - + } + else + { /* Find entry with SortKey greater than or equal to the passed-in SortKey */ LIST_FOR_EACH(ReturnEntry, &DeviceQueue->DeviceListHead, KDEVICE_QUEUE_ENTRY, DeviceListEntry) { /* Check if keys match */ - if (ReturnEntry->SortKey >= SortKey) { + if (ReturnEntry->SortKey >= SortKey) + { /* We found it, so just remove it */ RemoveEntryList(&ReturnEntry->DeviceListEntry); break; @@ -215,61 +198,110 @@ KeRemoveByKeyDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue, } /* Check if we found something */ - if (!ReturnEntry) { - + if (!ReturnEntry) + { /* Not found, return the first entry */ ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead); ReturnEntry = CONTAINING_RECORD(ListEntry, KDEVICE_QUEUE_ENTRY, DeviceListEntry); - } + } /* Set it as non-inserted */ ReturnEntry->Inserted = FALSE; } - /* Release lock and Return */ - KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock); - return ReturnEntry; -} + /* Release the lock */ + KiReleaseDeviceQueueLock(&DeviceLock); -/* - * @unimplemented - */ -PKDEVICE_QUEUE_ENTRY -STDCALL -KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue, - IN ULONG SortKey) -{ - UNIMPLEMENTED; - return 0; + /* Return the entry */ + return ReturnEntry; } /* * @implemented */ -BOOLEAN STDCALL +PKDEVICE_QUEUE_ENTRY +NTAPI +KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue, + IN ULONG SortKey) +{ + PLIST_ENTRY ListEntry; + PKDEVICE_QUEUE_ENTRY ReturnEntry; + KLOCK_QUEUE_HANDLE DeviceLock; + ASSERT_DEVICE_QUEUE(DeviceQueue); + + /* Lock the queue */ + KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); + + /* Check if this is an empty or idle queue */ + if (!(DeviceQueue->Busy) || (IsListEmpty(&DeviceQueue->DeviceListHead))) + { + /* Set it to idle and return nothing*/ + DeviceQueue->Busy = FALSE; + ReturnEntry = NULL; + } + else + { + /* Find entry with SortKey greater than or equal to the passed-in SortKey */ + LIST_FOR_EACH(ReturnEntry, &DeviceQueue->DeviceListHead, KDEVICE_QUEUE_ENTRY, DeviceListEntry) + { + /* Check if keys match */ + if (ReturnEntry->SortKey >= SortKey) + { + /* We found it, so just remove it */ + RemoveEntryList(&ReturnEntry->DeviceListEntry); + break; + } + } + + /* Check if we found something */ + if (!ReturnEntry) + { + /* Not found, return the first entry */ + ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead); + ReturnEntry = CONTAINING_RECORD(ListEntry, + KDEVICE_QUEUE_ENTRY, + DeviceListEntry); + } + + /* Set it as non-inserted */ + ReturnEntry->Inserted = FALSE; + } + + /* Release the lock */ + KiReleaseDeviceQueueLock(&DeviceLock); + + /* Return the entry */ + return ReturnEntry; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI KeRemoveEntryDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry) { - KIRQL OldIrql; BOOLEAN OldState; + KLOCK_QUEUE_HANDLE DeviceLock; + ASSERT_DEVICE_QUEUE(DeviceQueue); - DPRINT("KeRemoveEntryDeviceQueue(DeviceQueue %x)\n", DeviceQueue); - ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); - - /* Acquire the Lock */ - KeAcquireSpinLock(&DeviceQueue->Lock, &OldIrql); - - /* Check/Set Old State */ - if ((OldState = DeviceQueueEntry->Inserted)) { + /* Lock the queue */ + KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); + ASSERT(DeviceQueue->Busy); + /* Check the insertion state */ + OldState = DeviceQueueEntry->Inserted; + if (OldState) + { /* Remove it */ DeviceQueueEntry->Inserted = FALSE; RemoveEntryList(&DeviceQueueEntry->DeviceListEntry); } /* Unlock and return old state */ - KeReleaseSpinLock(&DeviceQueue->Lock, OldIrql); + KiReleaseDeviceQueueLock(&DeviceLock); return OldState; } From a614833b086f2dd8974417f59fad23c9fbd542ff Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 00:35:56 +0000 Subject: [PATCH 171/488] - Use inlined guarded region routines instead of duplicating code. - Add @implemented tags. svn path=/trunk/; revision=24088 --- reactos/ntoskrnl/include/internal/ke_x.h | 64 ++++++++++++------------ reactos/ntoskrnl/ke/gmutex.c | 55 +++++++++----------- reactos/ntoskrnl/ntoskrnl.def | 4 +- 3 files changed, 58 insertions(+), 65 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index f9580053cc3..5a5634cc6af 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -9,43 +9,43 @@ // // Enters a Guarded Region // -#define KeEnterGuardedRegion() \ -{ \ - PKTHREAD Thread = KeGetCurrentThread(); \ - \ - /* Sanity checks */ \ - ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL); \ - ASSERT(Thread == KeGetCurrentThread()); \ - ASSERT((Thread->SpecialApcDisable <= 0) && \ - (Thread->SpecialApcDisable != -32768)); \ - \ - /* Disable Special APCs */ \ - Thread->SpecialApcDisable--; \ +#define KeEnterGuardedRegion() \ +{ \ + PKTHREAD Thread = KeGetCurrentThread(); \ + \ + /* Sanity checks */ \ + ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL); \ + ASSERT(Thread == KeGetCurrentThread()); \ + ASSERT((Thread->SpecialApcDisable <= 0) && \ + (Thread->SpecialApcDisable != -32768)); \ + \ + /* Disable Special APCs */ \ + Thread->SpecialApcDisable--; \ } // // Leaves a Guarded Region // -#define KeLeaveGuardedRegion() \ -{ \ - PKTHREAD Thread = KeGetCurrentThread(); \ - \ - /* Sanity checks */ \ - ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL); \ - ASSERT(Thread == KeGetCurrentThread()); \ - ASSERT(Thread->SpecialApcDisable < 0); \ - \ - /* Leave region and check if APCs are OK now */ \ - if (!(++Thread->SpecialApcDisable)) \ - { \ - /* Check for Kernel APCs on the list */ \ - if (!IsListEmpty(&Thread->ApcState. \ - ApcListHead[KernelMode])) \ - { \ - /* Check for APC Delivery */ \ - KiCheckForKernelApcDelivery(); \ - } \ - } \ +#define KeLeaveGuardedRegion() \ +{ \ + PKTHREAD Thread = KeGetCurrentThread(); \ + \ + /* Sanity checks */ \ + ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL); \ + ASSERT(Thread == KeGetCurrentThread()); \ + ASSERT(Thread->SpecialApcDisable < 0); \ + \ + /* Leave region and check if APCs are OK now */ \ + if (!(++Thread->SpecialApcDisable)) \ + { \ + /* Check for Kernel APCs on the list */ \ + if (!IsListEmpty(&Thread->ApcState. \ + ApcListHead[KernelMode])) \ + { \ + /* Check for APC Delivery */ \ + KiCheckForKernelApcDelivery(); \ + } \ + } \ } // diff --git a/reactos/ntoskrnl/ke/gmutex.c b/reactos/ntoskrnl/ke/gmutex.c index 19d11cf7dbd..b8a92bcb1dd 100644 --- a/reactos/ntoskrnl/ke/gmutex.c +++ b/reactos/ntoskrnl/ke/gmutex.c @@ -131,6 +131,9 @@ KiReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex) /* PUBLIC FUNCTIONS **********************************************************/ +/* + * @implemented + */ VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex) @@ -144,6 +147,9 @@ KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex) KeInitializeGate(&GuardedMutex->Gate); } +/* + * @implemented + */ VOID FASTCALL KeAcquireGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex) @@ -164,6 +170,9 @@ KeAcquireGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex) GuardedMutex->Owner = Thread; } +/* + * @implemented + */ VOID FASTCALL KeReleaseGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex) @@ -179,6 +188,9 @@ KeReleaseGuardedMutexUnsafe(IN OUT PKGUARDED_MUTEX GuardedMutex) KiReleaseGuardedMutex(GuardedMutex); } +/* + * @implemented + */ VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex) @@ -200,6 +212,9 @@ KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex) GuardedMutex->SpecialApcDisable = Thread->SpecialApcDisable; } +/* + * @implemented + */ VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex) @@ -217,6 +232,9 @@ KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex) KeLeaveGuardedRegion(); } +/* + * @implemented + */ BOOLEAN FASTCALL KeTryToAcquireGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex) @@ -251,21 +269,12 @@ KeTryToAcquireGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex) * Enters a guarded region. This causes all (incl. special kernel) APCs * to be disabled. */ -#undef KeEnterGuardedRegion VOID NTAPI -KeEnterGuardedRegion(VOID) +_KeEnterGuardedRegion(VOID) { - PKTHREAD Thread = KeGetCurrentThread(); - - /* Sanity checks */ - ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL); - ASSERT(Thread == KeGetCurrentThread()); - ASSERT((Thread->SpecialApcDisable <= 0) && - (Thread->SpecialApcDisable != -32768)); - - /* Disable Special APCs */ - Thread->SpecialApcDisable--; + /* Use the inlined version */ + KeEnterGuardedRegion(); } /** @@ -273,28 +282,12 @@ KeEnterGuardedRegion(VOID) * * Leaves a guarded region and delivers pending APCs if possible. */ -#undef KeLeaveGuardedRegion VOID NTAPI -KeLeaveGuardedRegion(VOID) +_KeLeaveGuardedRegion(VOID) { - PKTHREAD Thread = KeGetCurrentThread(); - - /* Sanity checks */ - ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL); - ASSERT(Thread == KeGetCurrentThread()); - ASSERT(Thread->SpecialApcDisable < 0); - - /* Boost the enable count and check if Special APCs are enabled */ - if (!(++Thread->SpecialApcDisable)) - { - /* Check if there are Kernel APCs on the list */ - if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) - { - /* Check for APC Delivery */ - KiCheckForKernelApcDelivery(); - } - } + /* Use the inlined version */ + KeLeaveGuardedRegion(); } /* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index b649232d783..59e18b11cff 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -535,7 +535,7 @@ KeDeregisterBugCheckReasonCallback@4 KeDetachProcess@0 KeDisconnectInterrupt@4 KeEnterCriticalRegion@0=_KeEnterCriticalRegion@0 -KeEnterGuardedRegion@0 +KeEnterGuardedRegion@0=_KeEnterGuardedRegion@0 KeEnterKernelDebugger@0 KeFindConfigurationEntry@16 KeFindConfigurationNextEntry@20 @@ -577,7 +577,7 @@ KeInsertQueueDpc@12 KeIsAttachedProcess@0 KeIsExecutingDpc@0 KeLeaveCriticalRegion@0=_KeLeaveCriticalRegion@0 -KeLeaveGuardedRegion@0 +KeLeaveGuardedRegion@0=_KeLeaveGuardedRegion@0 KeLoaderBlock DATA KeNumberProcessors DATA KeProfileInterrupt@4 From 07a0973e216781eeee4000b23173287808da173f Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 01:00:50 +0000 Subject: [PATCH 172/488] - Remove usercall.c from portable part of Ke and add it to ke\i386. The implementation is slightly arch-specific. - Remove code in userapc.c and move it into usercall.c, since both functions basically deal with user-mode callouts. - Handle STATUS_CALLBACK_POP_STACK and add the status to ntstatus.h - Also handle future support for GDI Batch flushing. svn path=/trunk/; revision=24089 --- reactos/include/ddk/ntstatus.h | 1 + reactos/include/psdk/ntstatus.h | 1 + reactos/ntoskrnl/include/internal/ke.h | 13 + .../ke/i386/{userapc.c => usercall.c} | 100 ++- reactos/ntoskrnl/ntoskrnl.rbuild | 687 +++++++++--------- 5 files changed, 453 insertions(+), 349 deletions(-) rename reactos/ntoskrnl/ke/i386/{userapc.c => usercall.c} (57%) diff --git a/reactos/include/ddk/ntstatus.h b/reactos/include/ddk/ntstatus.h index 61b04fbd858..5e5452a7eac 100644 --- a/reactos/include/ddk/ntstatus.h +++ b/reactos/include/ddk/ntstatus.h @@ -877,6 +877,7 @@ extern "C" { #define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS)0xC000038CL) #define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS)0xC000038DL) #define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS)0xC000038EL) +#define STATUS_CALLBACK_POP_STACK ((NTSTATUS)0xC0000423L) #define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898L) #define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001L) #define RPC_NT_WRONG_KIND_OF_BINDING ((NTSTATUS)0xC0020002L) diff --git a/reactos/include/psdk/ntstatus.h b/reactos/include/psdk/ntstatus.h index d36f97c007e..97b93a6a010 100644 --- a/reactos/include/psdk/ntstatus.h +++ b/reactos/include/psdk/ntstatus.h @@ -921,6 +921,7 @@ #define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS)0xC0000413) #define STATUS_VDM_DISALLOWED ((NTSTATUS)0xC0000414) #define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS)0xC0000415) +#define STATUS_CALLBACK_POP_STACK ((NTSTATUS)0xC0000423) #define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898) #define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001) diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index eb14eca4f74..bd67ce1fd4e 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -823,6 +823,19 @@ KiInsertQueueApc( IN KPRIORITY PriorityBoost ); +NTSTATUS +NTAPI +KiCallUserMode( + IN PVOID *OutputBuffer, + IN PULONG OutputLength +); + +PULONG +NTAPI +KiGetUserModeStackAddress( + VOID +); + #include "ke_x.h" #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */ diff --git a/reactos/ntoskrnl/ke/i386/userapc.c b/reactos/ntoskrnl/ke/i386/usercall.c similarity index 57% rename from reactos/ntoskrnl/ke/i386/userapc.c rename to reactos/ntoskrnl/ke/i386/usercall.c index 13fcf7f0625..722c8e6c487 100644 --- a/reactos/ntoskrnl/ke/i386/userapc.c +++ b/reactos/ntoskrnl/ke/i386/usercall.c @@ -1,16 +1,16 @@ /* * PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/ke/i386/userapc.c - * PURPOSE: Implements User-Mode APC Initialization + * FILE: ntoskrnl/ke/i386/usercall.c + * PURPOSE: User-mode Callout Mechanisms (APC and Win32K Callbacks) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG -#include +#include /* PRIVATE FUNCTIONS *********************************************************/ @@ -56,7 +56,7 @@ _SEH_FILTER(KiCopyInformation2) * *--*/ VOID -STDCALL +NTAPI KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN PKNORMAL_ROUTINE NormalRoutine, @@ -134,3 +134,93 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, _SEH_END; } +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +KeUserModeCallback(IN ULONG RoutineIndex, + IN PVOID Argument, + IN ULONG ArgumentLength, + OUT PVOID *Result, + OUT PULONG ResultLength) +{ + ULONG_PTR NewStack, OldStack; + PULONG UserEsp; + NTSTATUS CallbackStatus = STATUS_SUCCESS; + PEXCEPTION_REGISTRATION_RECORD ExceptionList; + PTEB Teb; + ULONG GdiBatchCount = 0; + ASSERT(KeGetCurrentThread()->ApcState.KernelApcInProgress == FALSE); + ASSERT(KeGetPreviousMode() == UserMode); + + /* Get the current user-mode stack */ + UserEsp = KiGetUserModeStackAddress(); + OldStack = *UserEsp; + + /* Enter a SEH Block */ + _SEH_TRY + { + /* Calculate and align the stack size */ + NewStack = (OldStack - ArgumentLength) & ~3; + + /* Make sure it's writable */ + ProbeForWrite((PVOID)(NewStack - 6 * sizeof(ULONG_PTR)), + ArgumentLength + 6 * sizeof(ULONG_PTR), + sizeof(CHAR)); + + /* Copy the buffer into the stack */ + RtlCopyMemory((PVOID)NewStack, Argument, ArgumentLength); + + /* Write the arguments */ + NewStack -= 24; + *(PULONG)NewStack = 0; + *(PULONG)(NewStack + 4) = RoutineIndex; + *(PULONG)(NewStack + 8) = (NewStack + 24); + *(PULONG)(NewStack + 12) = ArgumentLength; + + /* Save the exception list */ + Teb = KeGetCurrentThread()->Teb; + ExceptionList = Teb->Tib.ExceptionList; + + /* Jump to user mode */ + *UserEsp = NewStack; + CallbackStatus = KiCallUserMode(Result, ResultLength); + if (CallbackStatus != STATUS_CALLBACK_POP_STACK) + { + /* Only restore the exception list if we didn't crash in ring 3 */ + Teb->Tib.ExceptionList = ExceptionList; + CallbackStatus = STATUS_SUCCESS; + } + else + { + /* Otherwise, pop the stack */ + OldStack = *UserEsp; + } + + /* Read the GDI Batch count */ + GdiBatchCount = Teb->GdiBatchCount; + } + _SEH_HANDLE + { + /* Get the SEH exception */ + CallbackStatus = _SEH_GetExceptionCode(); + } + _SEH_END; + if (!NT_SUCCESS(CallbackStatus)) return CallbackStatus; + + /* Check if we have GDI Batch operations */ + if (GdiBatchCount) + { + /* Shouldn't happen in ROS yet */ + ASSERT(FALSE); + } + + /* Restore stack and return */ + *UserEsp = OldStack; + return CallbackStatus; +} + +/* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 141fab2e3cc..670bb1dd7e6 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -1,346 +1,345 @@ - - - - - - - - - - - include - . - include - include/reactos/drivers - csq - hal - kjs - pseh - cmlib - rtl - rossym - string - wdmguid - - ntoskrnl.h - - - - - boot.S - abios.c - cpu.c - ctxswitch.S - clock.S - exp.c - - kiinit.c - ldt.c - thread.c - trap.s - usercall_asm.S - userapc.c - v86vdm.c - v86m_sup.S - - - apc.c - bug.c - clock.c - device.c - dpc.c - event.c - exception.c - freeldr.c - gate.c - gmutex.c - ipi.c - kqueue.c - krnlinit.c - mutex.c - process.c - profile.c - queue.c - sem.c - spinlock.c - thrdschd.c - thrdobj.c - timer.c - usercall.c - wait.c - - - irqhand.S - irq.c - - - cacheman.c - copy.c - fs.c - mdl.c - pin.c - view.c - - - import.c - ntfunc.c - regfile.c - registry.c - regobj.c - - - - - - - i386-dis.c - kdb_help.S - longjmp.S - setjmp.S - - - - - - kdb.c - kdb_cli.c - kdb_expr.c - kdb_keyboard.c - kdb_serial.c - kdb_string.c - - - kdb_symbols.c - - - - dbgkutil.c - debug.c - - - - - interlck_asm.S - fastinterlck_asm.S - - - atom.c - callback.c - dbgctrl.c - error.c - efi.c - event.c - evtpair.c - fmutex.c - handle.c - init.c - locale.c - lookas.c - mutant.c - power.c - pushlock.c - profile.c - resource.c - rundown.c - sem.c - sysinfo.c - time.c - timer.c - uuid.c - win32k.c - work.c - zone.c - zw.S - - - context.c - fastio.c - filelock.c - mcb.c - name.c - notify.c - oplock.c - pool.c - tunnel.c - unc.c - util.c - - - inbv.c - - - - adapter.c - arcname.c - bootlog.c - controller.c - device.c - deviface.c - disk.c - driver.c - drvrlist.c - error.c - event.c - file.c - iocomp.c - iofunc.c - iomgr.c - iowork.c - irp.c - irq.c - mdl.c - rawfs.c - remlock.c - resource.c - util.c - symlink.c - timer.c - volume.c - - - plugplay.c - pnpdma.c - pnpmgr.c - pnpnotify.c - pnpreport.c - pnproot.c - - - - - bochs.c - gdbstub.c - - kdinit.c - kdio.c - kdmain.c - - - loader.c - rtl.c - - - close.c - complete.c - connect.c - create.c - listen.c - port.c - query.c - queue.c - receive.c - reply.c - send.c - - - - - memsafe.s - page.c - pfault.c - - - anonmem.c - aspace.c - balance.c - cont.c - drvlck.c - freelist.c - iospace.c - kmap.c - marea.c - mdl.c - mm.c - process.c - mminit.c - mpw.c - ncache.c - npool.c - pagefile.c - pageop.c - pager.c - pagfault.c - paging.c - pe.c - physical.c - pool.c - ppool.c - region.c - rmap.c - section.c - verifier.c - virtual.c - wset.c - elf32.c - elf64.c - - - obdir.c - obinit.c - obhandle.c - obname.c - oblife.c - obref.c - sdcache.c - obsecure.c - symlink.c - obwait.c - - - power.c - events.c - - - debug.c - job.c - kill.c - notify.c - process.c - psmgr.c - query.c - quota.c - security.c - state.c - thread.c - win32.c - - - - - exception.c - seh.s - - - libsupp.c - misc.c - nls.c - regio.c - strtok.c - - - access.c - acl.c - audit.c - lsa.c - luid.c - priv.c - sd.c - semgr.c - sid.c - token.c - - - - vdmmain.c - vdmexec.c - - - - wmi.c - - ntoskrnl.rc - -nostartfiles - -nostdlib - -lgcc + + + + + + + + + + + include + . + include + include/reactos/drivers + csq + hal + kjs + pseh + cmlib + rtl + rossym + string + wdmguid + + ntoskrnl.h + + + + + boot.S + abios.c + cpu.c + ctxswitch.S + clock.S + exp.c + + kiinit.c + ldt.c + thread.c + trap.s + usercall_asm.S + usercall.c + v86vdm.c + v86m_sup.S + + + apc.c + bug.c + clock.c + device.c + dpc.c + event.c + exception.c + freeldr.c + gate.c + gmutex.c + ipi.c + kqueue.c + krnlinit.c + mutex.c + process.c + profile.c + queue.c + sem.c + spinlock.c + thrdschd.c + thrdobj.c + timer.c + wait.c + + + irqhand.S + irq.c + + + cacheman.c + copy.c + fs.c + mdl.c + pin.c + view.c + + + import.c + ntfunc.c + regfile.c + registry.c + regobj.c + + + + + + + i386-dis.c + kdb_help.S + longjmp.S + setjmp.S + + + + + + kdb.c + kdb_cli.c + kdb_expr.c + kdb_keyboard.c + kdb_serial.c + kdb_string.c + + + kdb_symbols.c + + + + dbgkutil.c + debug.c + + + + + interlck_asm.S + fastinterlck_asm.S + + + atom.c + callback.c + dbgctrl.c + error.c + efi.c + event.c + evtpair.c + fmutex.c + handle.c + init.c + locale.c + lookas.c + mutant.c + power.c + pushlock.c + profile.c + resource.c + rundown.c + sem.c + sysinfo.c + time.c + timer.c + uuid.c + win32k.c + work.c + zone.c + zw.S + + + context.c + fastio.c + filelock.c + mcb.c + name.c + notify.c + oplock.c + pool.c + tunnel.c + unc.c + util.c + + + inbv.c + + + + adapter.c + arcname.c + bootlog.c + controller.c + device.c + deviface.c + disk.c + driver.c + drvrlist.c + error.c + event.c + file.c + iocomp.c + iofunc.c + iomgr.c + iowork.c + irp.c + irq.c + mdl.c + rawfs.c + remlock.c + resource.c + util.c + symlink.c + timer.c + volume.c + + + plugplay.c + pnpdma.c + pnpmgr.c + pnpnotify.c + pnpreport.c + pnproot.c + + + + + bochs.c + gdbstub.c + + kdinit.c + kdio.c + kdmain.c + + + loader.c + rtl.c + + + close.c + complete.c + connect.c + create.c + listen.c + port.c + query.c + queue.c + receive.c + reply.c + send.c + + + + + memsafe.s + page.c + pfault.c + + + anonmem.c + aspace.c + balance.c + cont.c + drvlck.c + freelist.c + iospace.c + kmap.c + marea.c + mdl.c + mm.c + process.c + mminit.c + mpw.c + ncache.c + npool.c + pagefile.c + pageop.c + pager.c + pagfault.c + paging.c + pe.c + physical.c + pool.c + ppool.c + region.c + rmap.c + section.c + verifier.c + virtual.c + wset.c + elf32.c + elf64.c + + + obdir.c + obinit.c + obhandle.c + obname.c + oblife.c + obref.c + sdcache.c + obsecure.c + symlink.c + obwait.c + + + power.c + events.c + + + debug.c + job.c + kill.c + notify.c + process.c + psmgr.c + query.c + quota.c + security.c + state.c + thread.c + win32.c + + + + + exception.c + seh.s + + + libsupp.c + misc.c + nls.c + regio.c + strtok.c + + + access.c + acl.c + audit.c + lsa.c + luid.c + priv.c + sd.c + semgr.c + sid.c + token.c + + + + vdmmain.c + vdmexec.c + + + + wmi.c + + ntoskrnl.rc + -nostartfiles + -nostdlib + -lgcc From 7687187bf05fa5b6bf2ae314c37e3bb4591de81c Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 01:41:17 +0000 Subject: [PATCH 173/488] - Implement KxAcquireSpinLock/KxReleaseSpinLock for inline acquisition of spinlocks, SMP, UP and DBG. (on DBG builds, we OR the spinlock value with the KTHREAD address, then compare on release.) - Make In-Stack QSLs a complete no-op in UP, we were still touching some fields. - Cleanup and re-organize spinlock.c svn path=/trunk/; revision=24090 --- reactos/ntoskrnl/include/internal/ke_x.h | 65 +++++ reactos/ntoskrnl/ke/spinlock.c | 328 ++++++++++------------- 2 files changed, 212 insertions(+), 181 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 5a5634cc6af..c615c659563 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -292,6 +292,71 @@ KiRecalculateDueTime(IN PLARGE_INTEGER OriginalDueTime, } \ } +// +// Spinlock Acquisition at IRQL >= DISPATCH_LEVEL +// +FORCEINLINE +VOID +KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock) +{ +#ifdef CONFIG_SMP + for (;;) + { + /* Try to acquire it */ + if (InterlockedBitTestAndSet((PLONG)SpinLock, 0)) + { + /* Value changed... wait until it's locked */ + while (*(volatile KSPIN_LOCK *)SpinLock == 1) + { +#ifdef DBG + /* On debug builds, we use a much slower but useful routine */ + Kii386SpinOnSpinLock(SpinLock, 5); +#else + /* Otherwise, just yield and keep looping */ + YieldProcessor(); +#endif + } + } + else + { +#ifdef DBG + /* On debug builds, we OR in the KTHREAD */ + *SpinLock = KeGetCurrentThread() | 1; +#endif + /* All is well, break out */ + break; + } + } +#else + /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */ + UNREFERENCED_PARAMETER(SpinLock); +#endif +} + +// +// Spinlock Release at IRQL >= DISPATCH_LEVEL +// +FORCEINLINE +VOID +KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock) +{ +#ifdef CONFIG_SMP +#ifdef DBG + /* Make sure that the threads match */ + if ((KeGetCurrentThread() | 1) != *SpinLock) + { + /* They don't, bugcheck */ + KeBugCheckEx(SPIN_LOCK_NOT_OWNED, SpinLock, 0, 0, 0); + } +#endif + /* Clear the lock */ + InterlockedAnd(SpinLock, 0); +#else + /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */ + UNREFERENCED_PARAMETER(SpinLock); +#endif +} + // // Thread Scheduling Routines // diff --git a/reactos/ntoskrnl/ke/spinlock.c b/reactos/ntoskrnl/ke/spinlock.c index 456576b00c1..b78f5f12579 100644 --- a/reactos/ntoskrnl/ke/spinlock.c +++ b/reactos/ntoskrnl/ke/spinlock.c @@ -1,197 +1,21 @@ /* - * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/spinlock.c - * PURPOSE: Implements spinlocks - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * David Welch (welch@cwcom.net) + * PURPOSE: Spinlock and Queued Spinlock Support + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES ****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG #include -#undef KefAcquireSpinLockAtDpcLevel -#undef KeAcquireSpinLockAtDpcLevel -#undef KefReleaseSpinLockFromDpcLevel -#undef KeReleaseSpinLockFromDpcLevel - #define LQ_WAIT 1 #define LQ_OWN 2 -/* FUNCTIONS ***************************************************************/ - -/* - * @implemented - * - * FUNCTION: Synchronizes the execution of a given routine with the ISR - * of a given interrupt object - * ARGUMENTS: - * Interrupt = Interrupt object to synchronize with - * SynchronizeRoutine = Routine to call whose execution is - * synchronized with the ISR - * SynchronizeContext = Parameter to pass to the synchronized routine - * RETURNS: TRUE if the operation succeeded - */ -BOOLEAN -STDCALL -KeSynchronizeExecution(PKINTERRUPT Interrupt, - PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, - PVOID SynchronizeContext) -{ - KIRQL OldIrql; - BOOLEAN Status; - - /* Raise IRQL and acquire lock on MP */ - OldIrql = KeAcquireInterruptSpinLock(Interrupt); - - /* Call the routine */ - Status = SynchronizeRoutine(SynchronizeContext); - - /* Release lock and lower IRQL */ - KeReleaseInterruptSpinLock(Interrupt, OldIrql); - - /* Return routine status */ - return Status; -} - -/* - * @implemented - */ -KIRQL -STDCALL -KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt) -{ - KIRQL OldIrql; - - /* Raise IRQL */ - KeRaiseIrql(Interrupt->SynchronizeIrql, &OldIrql); - - /* Acquire spinlock on MP */ - KiAcquireSpinLock(Interrupt->ActualLock); - return OldIrql; -} - -/* - * @implemented - * - * FUNCTION: Initalizes a spinlock - * ARGUMENTS: - * SpinLock = Caller supplied storage for the spinlock - */ -VOID -STDCALL -KeInitializeSpinLock(PKSPIN_LOCK SpinLock) -{ - *SpinLock = 0; -} - -/* - * @implemented - */ -VOID -FASTCALL -KefAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock) -{ - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - KiAcquireSpinLock(SpinLock); -} - -/* - * @implemented - * - * FUNCTION: Acquires a spinlock when the caller is already running at - * dispatch level - * ARGUMENTS: - * SpinLock = Spinlock to acquire - */ -VOID -STDCALL -KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock) -{ - KefAcquireSpinLockAtDpcLevel(SpinLock); -} - -/* - * @implemented - */ -VOID -FASTCALL -KefReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock) -{ - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - KiReleaseSpinLock(SpinLock); -} - -/* - * @implemented - * - * FUNCTION: Releases a spinlock when the caller was running at dispatch - * level before acquiring it - * ARGUMENTS: - * SpinLock = Spinlock to release - */ -VOID -STDCALL -KeReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock) -{ - KefReleaseSpinLockFromDpcLevel(SpinLock); -} - -/* - * @implemented - */ -VOID -FASTCALL -KiAcquireSpinLock(PKSPIN_LOCK SpinLock) -{ -#ifdef CONFIG_SMP - for (;;) - { - /* Try to acquire it */ - if (InterlockedBitTestAndSet((PLONG)SpinLock, 0)) - { - /* Value changed... wait until it's locked */ - while (*(volatile KSPIN_LOCK *)SpinLock == 1) YieldProcessor(); - } - else - { - /* All is well, break out */ - break; - } - } -#endif /* CONFIG_SMP */ -} - -/* - * @implemented - */ -VOID -STDCALL -KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, - IN KIRQL OldIrql) -{ - /* Release lock on MP */ - KiReleaseSpinLock(Interrupt->ActualLock); - - /* Lower IRQL */ - KeLowerIrql(OldIrql); -} - -/* - * @implemented - */ -VOID -FASTCALL -KiReleaseSpinLock(PKSPIN_LOCK SpinLock) -{ -#ifdef CONFIG_SMP - /* Simply clear it */ - *SpinLock = 0; -#endif -} +/* PRIVATE FUNCTIONS *********************************************************/ VOID FASTCALL @@ -260,6 +84,87 @@ KeReleaseQueuedSpinLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle) #endif } +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +VOID +NTAPI +KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock) +{ + /* Clear it */ + *SpinLock = 0; +} + +/* + * @implemented + */ +#undef KeAcquireSpinLockAtDpcLevel +VOID +NTAPI +KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock) +{ + /* Do the inlined function */ + KxAcquireSpinLock(SpinLock); +} + +/* + * @implemented + */ +#undef KeReleaseSpinLockFromDpcLevel +VOID +NTAPI +KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock) +{ + /* Do the lined function */ + KxReleaseSpinLock(SpinLock); +} + +/* + * @implemented + */ +VOID +FASTCALL +KefAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock) +{ + /* Do the inlined function */ + KxAcquireSpinLock(SpinLock); +} + +/* + * @implemented + */ +VOID +FASTCALL +KefReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock) +{ + /* Do the lined function */ + KxReleaseSpinLock(SpinLock); +} + +/* + * @implemented + */ +VOID +FASTCALL +KiAcquireSpinLock(IN PKSPIN_LOCK SpinLock) +{ + /* Do the inlined function */ + KxAcquireSpinLock(SpinLock); +} + +/* + * @implemented + */ +VOID +FASTCALL +KiReleaseSpinLock(IN PKSPIN_LOCK SpinLock) +{ + /* Do the lined function */ + KxReleaseSpinLock(SpinLock); +} + /* * @implemented */ @@ -268,11 +173,13 @@ FASTCALL KeAcquireInStackQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle) { +#ifdef CONFIG_SMP /* Set it up properly */ LockHandle->LockQueue.Next = NULL; LockHandle->LockQueue.Lock = SpinLock; KeAcquireQueuedSpinLockAtDpcLevel((PKLOCK_QUEUE_HANDLE) &LockHandle->LockQueue.Next); +#endif } /* @@ -282,9 +189,68 @@ VOID FASTCALL KeReleaseInStackQueuedSpinLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle) { +#ifdef CONFIG_SMP /* Call the internal function */ KeReleaseQueuedSpinLockFromDpcLevel((PKLOCK_QUEUE_HANDLE) &LockHandle->LockQueue.Next); +#endif +} + +/* + * @implemented + */ +KIRQL +NTAPI +KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt) +{ + KIRQL OldIrql; + + /* Raise IRQL */ + KeRaiseIrql(Interrupt->SynchronizeIrql, &OldIrql); + + /* Acquire spinlock on MP */ + KefAcquireSpinLockAtDpcLevel(Interrupt->ActualLock); + return OldIrql; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +KeSynchronizeExecution(IN PKINTERRUPT Interrupt, + IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, + IN PVOID SynchronizeContext) +{ + KIRQL OldIrql; + BOOLEAN Status; + + /* Raise IRQL and acquire lock on MP */ + OldIrql = KeAcquireInterruptSpinLock(Interrupt); + + /* Call the routine */ + Status = SynchronizeRoutine(SynchronizeContext); + + /* Release lock and lower IRQL */ + KeReleaseInterruptSpinLock(Interrupt, OldIrql); + + /* Return routine status */ + return Status; +} + +/* + * @implemented + */ +VOID +STDCALL +KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, + IN KIRQL OldIrql) +{ + /* Release lock on MP */ + KefReleaseSpinLock(Interrupt->ActualLock); + + /* Lower IRQL */ + KeLowerIrql(OldIrql); } /* EOF */ From b4aab80937342789a78b84c8de44aef4208c0200 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 02:04:33 +0000 Subject: [PATCH 174/488] - Fix a typo that happened after-the-fact. svn path=/trunk/; revision=24091 --- reactos/ntoskrnl/ke/spinlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/ke/spinlock.c b/reactos/ntoskrnl/ke/spinlock.c index b78f5f12579..07a80048316 100644 --- a/reactos/ntoskrnl/ke/spinlock.c +++ b/reactos/ntoskrnl/ke/spinlock.c @@ -247,7 +247,7 @@ KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql) { /* Release lock on MP */ - KefReleaseSpinLock(Interrupt->ActualLock); + KefReleaseSpinLockFromDpcLevel(Interrupt->ActualLock); /* Lower IRQL */ KeLowerIrql(OldIrql); From 31e4c651c4bcdb5b575d75e465c8d43bccf96d34 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 02:08:22 +0000 Subject: [PATCH 175/488] - Renamed device.c to config.c and removed all irrelevant code from it, leaving only the two KeFindConfigurationEntry*** functions in it. - Also fixed the above for incorrect formatting/excessive whitespace. - The other routines in device.c were moved to cpu.c, since they deal with CPU-specific things. - Cleaned up KeFlushEntireTb. - Added inlined routines for setting/getting CR, and also getting GDTR, IDTR, LDTR, TR. Used to implement KiSaveProcessorControlState. - Implemented KeSaveStateForHibernate. svn path=/trunk/; revision=24092 --- reactos/ntoskrnl/include/internal/i386/ke.h | 25 +++ reactos/ntoskrnl/ke/config.c | 126 ++++++++++++ reactos/ntoskrnl/ke/device.c | 215 -------------------- reactos/ntoskrnl/ke/exception.c | 2 +- reactos/ntoskrnl/ke/i386/cpu.c | 203 +++++++++++++----- reactos/ntoskrnl/ke/spinlock.c | 2 +- reactos/ntoskrnl/ntoskrnl.rbuild | 2 +- 7 files changed, 304 insertions(+), 271 deletions(-) create mode 100644 reactos/ntoskrnl/ke/config.c delete mode 100644 reactos/ntoskrnl/ke/device.c diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 62c496163eb..71c5887dd7c 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -152,6 +152,22 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine, __asm__("lgdt %0\n\t" \ : /* no outputs */ \ : "m" (X)); + +#define Ke386GetInterruptDescriptorTable(X) \ + __asm__("sidt %0\n\t" \ + : /* no outputs */ \ + : "m" (X)); + +#define Ke386GetGlobalDescriptorTable(X) \ + __asm__("sgdt %0\n\t" \ + : /* no outputs */ \ + : "m" (X)); + +#define Ke386GetLocalDescriptorTable(X) \ + __asm__("lldt %0\n\t" \ + : /* no outputs */ \ + : "m" (X)); + #define Ke386SaveFlags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */) #define Ke386RestoreFlags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory") @@ -166,9 +182,18 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine, __asm__("movl %%cr" #N ",%0\n\t" :"=r" (__d)); \ __d; \ }) + +#define _Ke386GetDr(N) ({ \ + unsigned int __d; \ + __asm__("movl %%dr" #N ",%0\n\t" :"=r" (__d)); \ + __d; \ + }) #define _Ke386SetCr(N,X) __asm__ __volatile__("movl %0,%%cr" #N : :"r" (X)); +#define _Ke386SetDr(N,X) __asm__ __volatile__("movl %0,%%dr" #N : :"r" (X)); #define Ke386SetTr(X) __asm__ __volatile__("ltr %%ax" : :"a" (X)); +#define Ke386GetTr(X) __asm__ __volatile__("str %%ax" : :"a" (X)); + #define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X)); #define Ke386GetCr0() _Ke386GetCr(0) diff --git a/reactos/ntoskrnl/ke/config.c b/reactos/ntoskrnl/ke/config.c new file mode 100644 index 00000000000..67f374f3d06 --- /dev/null +++ b/reactos/ntoskrnl/ke/config.c @@ -0,0 +1,126 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/config.c + * PURPOSE: Configuration Tree Routines + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +/* + * @implemented + */ +PCONFIGURATION_COMPONENT_DATA +NTAPI +INIT_FUNCTION +KeFindConfigurationEntry(IN PCONFIGURATION_COMPONENT_DATA Child, + IN CONFIGURATION_CLASS Class, + IN CONFIGURATION_TYPE Type, + IN PULONG ComponentKey OPTIONAL) +{ + /* Start Search at Root */ + return KeFindConfigurationNextEntry(Child, + Class, + Type, + ComponentKey, + NULL); +} + +/* + * @implemented + */ +PCONFIGURATION_COMPONENT_DATA +NTAPI +INIT_FUNCTION +KeFindConfigurationNextEntry(IN PCONFIGURATION_COMPONENT_DATA Child, + IN CONFIGURATION_CLASS Class, + IN CONFIGURATION_TYPE Type, + IN PULONG ComponentKey OPTIONAL, + IN PCONFIGURATION_COMPONENT_DATA *NextLink) +{ + ULONG Key = 0; + ULONG Mask = 0; + PCONFIGURATION_COMPONENT_DATA Sibling; + PCONFIGURATION_COMPONENT_DATA ReturnEntry; + + /* If we did get a key, then use it instead */ + if (ComponentKey) + { + Key = *ComponentKey; + Mask = -1; + } + + /* Loop the Components until we find a a match */ + while (Child) + { + /* Check if we are starting somewhere already */ + if (*NextLink) + { + /* If we've found the place where we started, clear and continue */ + if (Child == *NextLink) *NextLink = NULL; + } + else + { + /* Try to get a match */ + if ((Child->ComponentEntry.Class) == Class && + (Child->ComponentEntry.Type) == Type && + (Child->ComponentEntry.Key & Mask) == Key) + { + /* Match found */ + return Child; + } + } + + /* Now we've also got to lookup the siblings */ + Sibling = Child->Sibling; + while (Sibling) + { + /* Check if we are starting somewhere already */ + if (*NextLink) + { + /* If we've found the place where we started, clear and continue */ + if (Sibling == *NextLink) *NextLink = NULL; + } + else + { + /* Try to get a match */ + if ((Sibling->ComponentEntry.Class == Class) && + (Sibling->ComponentEntry.Type == Type) && + (Sibling->ComponentEntry.Key & Mask) == Key) + { + /* Match found */ + return Sibling; + } + } + + /* We've got to check if the Sibling has a Child as well */ + if (Sibling->Child) + { + /* We're just going to call ourselves again */ + ReturnEntry = KeFindConfigurationNextEntry(Sibling->Child, + Class, + Type, + ComponentKey, + NextLink); + if (ReturnEntry) return ReturnEntry; + } + + /* Next Sibling */ + Sibling = Sibling->Sibling; + } + + /* Next Child */ + Child = Child->Child; + } + + /* If we got here, nothign was found */ + return NULL; +} + diff --git a/reactos/ntoskrnl/ke/device.c b/reactos/ntoskrnl/ke/device.c deleted file mode 100644 index b1d5300e0f5..00000000000 --- a/reactos/ntoskrnl/ke/device.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/device.c - * PURPOSE: Kernel Device/Settings Functions - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -#include -#define NDEBUG -#include - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, KeFindConfigurationEntry) -#pragma alloc_text(INIT, KeFindConfigurationNextEntry) -#endif - -/* - * @implemented - */ -PCONFIGURATION_COMPONENT_DATA -STDCALL -INIT_FUNCTION -KeFindConfigurationEntry(IN PCONFIGURATION_COMPONENT_DATA Child, - IN CONFIGURATION_CLASS Class, - IN CONFIGURATION_TYPE Type, - IN PULONG ComponentKey OPTIONAL) -{ - /* Start Search at Root */ - return KeFindConfigurationNextEntry(Child, - Class, - Type, - ComponentKey, - NULL); -} - -/* - * @implemented - */ -PCONFIGURATION_COMPONENT_DATA -STDCALL -INIT_FUNCTION -KeFindConfigurationNextEntry(IN PCONFIGURATION_COMPONENT_DATA Child, - IN CONFIGURATION_CLASS Class, - IN CONFIGURATION_TYPE Type, - IN PULONG ComponentKey OPTIONAL, - IN PCONFIGURATION_COMPONENT_DATA *NextLink) -{ - ULONG Key = 0; - ULONG Mask = 0; - PCONFIGURATION_COMPONENT_DATA Sibling; - PCONFIGURATION_COMPONENT_DATA ReturnEntry; - - /* If we did get a key, then use it instead */ - if (ComponentKey) - { - Key = *ComponentKey; - Mask = -1; - } - - /* Loop the Components until we find a a match */ - while (Child) - { - /* Check if we are starting somewhere already */ - if (*NextLink) - { - /* If we've found the place where we started, clear and continue */ - if (Child == *NextLink) *NextLink = NULL; - } - else - { - /* Try to get a match */ - if (Child->ComponentEntry.Class == Class && - Child->ComponentEntry.Type == Type && - (Child->ComponentEntry.Key & Mask) == Key) - { - /* Match found */ - return Child; - } - } - - /* Now we've also got to lookup the siblings */ - Sibling = Child->Sibling; - while (Sibling) - { - /* Check if we are starting somewhere already */ - if (*NextLink) - { - /* If we've found the place where we started, clear and continue */ - if (Sibling == *NextLink) *NextLink = NULL; - } - else - { - /* Try to get a match */ - if (Sibling->ComponentEntry.Class == Class && - Sibling->ComponentEntry.Type == Type && - (Sibling->ComponentEntry.Key & Mask) == Key) - { - /* Match found */ - return Sibling; - } - } - - /* We've got to check if the Sibling has a Child as well */ - if (Sibling->Child) - { - /* We're just going to call ourselves again */ - if ((ReturnEntry = KeFindConfigurationNextEntry(Sibling->Child, - Class, - Type, - ComponentKey, - NextLink))) - { - return ReturnEntry; - } - } - - /* Next Sibling */ - Sibling = Sibling->Sibling; - } - - /* Next Child */ - Child = Child->Child; - } - - /* If we got here, nothign was found */ - return NULL; -} - -/* - * @implemented - */ -VOID -STDCALL -KeFlushEntireTb( - IN BOOLEAN Unknown, - IN BOOLEAN CurrentCpuOnly -) -{ - KIRQL OldIrql; - PKPROCESS Process = NULL; - PKPRCB Prcb = NULL; - - /* Raise the IRQL for the TB Flush */ - OldIrql = KeRaiseIrqlToSynchLevel(); - - /* All CPUs need to have the TB flushed. */ - if (CurrentCpuOnly == FALSE) { - Prcb = KeGetCurrentPrcb(); - - /* How many CPUs is our caller using? */ - Process = Prcb->CurrentThread->ApcState.Process; - - /* More then one, so send an IPI */ - if (Process->ActiveProcessors > 1) { - /* Send IPI Packet */ - } - } - - /* Flush the TB for the Current CPU */ - KeFlushCurrentTb(); - - /* Clean up */ - if (CurrentCpuOnly == FALSE) { - /* Did we send an IPI? If so, wait for completion */ - if (Process->ActiveProcessors > 1) { - do { - } while (Prcb->TargetSet != 0); - } - } - - /* FIXME: According to MSKB, we should increment a counter? */ - - /* Return to Original IRQL */ - KeLowerIrql(OldIrql); -} - - -/* - * @implemented - */ -VOID -STDCALL -KeSetDmaIoCoherency( - IN ULONG Coherency -) -{ - KiDmaIoCoherency = Coherency; -} - -/* - * @implemented - */ -KAFFINITY -STDCALL -KeQueryActiveProcessors ( - VOID - ) -{ - return KeActiveProcessors; -} - - -/* - * @unimplemented - */ -VOID -__cdecl -KeSaveStateForHibernate( - IN PVOID State -) -{ - UNIMPLEMENTED; -} diff --git a/reactos/ntoskrnl/ke/exception.c b/reactos/ntoskrnl/ke/exception.c index 1caf27f660a..c3b8059e5cf 100644 --- a/reactos/ntoskrnl/ke/exception.c +++ b/reactos/ntoskrnl/ke/exception.c @@ -12,7 +12,7 @@ #define NDEBUG #include -/* INCLUDES ******************************************************************/ +/* FUNCTIONS *****************************************************************/ VOID NTAPI diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 83a2630cd79..633701f692b 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -638,58 +638,6 @@ Ki386InitializeTss(VOID) TssEntry->LimitLow = KTSS_IO_MAPS; } -/* This is a rather naive implementation of Ke(Save/Restore)FloatingPointState - which will not work for WDM drivers. Please feel free to improve */ -NTSTATUS -NTAPI -KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save) -{ - PFNSAVE_FORMAT FpState; - ASSERT_IRQL(DISPATCH_LEVEL); - - /* check if we are doing software emulation */ - if (!KeI386NpxPresent) return STATUS_ILLEGAL_FLOAT_CONTEXT; - - FpState = ExAllocatePool(NonPagedPool, sizeof (FNSAVE_FORMAT)); - if (!FpState) return STATUS_INSUFFICIENT_RESOURCES; - - *((PVOID *) Save) = FpState; -#ifdef __GNUC__ - asm volatile("fnsave %0\n\t" : "=m" (*FpState)); -#else - __asm - { - fnsave [FpState] - }; -#endif - - KeGetCurrentThread()->DispatcherHeader.NpxIrql = KeGetCurrentIrql(); - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save) -{ - PFNSAVE_FORMAT FpState = *((PVOID *) Save); - - ASSERT(KeGetCurrentThread()->DispatcherHeader.NpxIrql == KeGetCurrentIrql()); - -#ifdef __GNUC__ - asm volatile("fnclex\n\t"); - asm volatile("frstor %0\n\t" : "=m" (*FpState)); -#else - __asm - { - fnclex - frstor [FpState] - }; -#endif - - ExFreePool(FpState); - return STATUS_SUCCESS; -} - VOID INIT_FUNCTION Ki386SetProcessorFeatures(VOID) @@ -789,12 +737,161 @@ KeFlushCurrentTb(VOID) _Ke386SetCr(3, _Ke386GetCr(3)); } +VOID +NTAPI +KiSaveProcessorControlState(IN PKPROCESSOR_STATE ProcessorState) +{ + /* Save the CR registers */ + ProcessorState->SpecialRegisters.Cr0 = _Ke386GetCr(0); + ProcessorState->SpecialRegisters.Cr2 = _Ke386GetCr(2); + ProcessorState->SpecialRegisters.Cr3 = _Ke386GetCr(3); + ProcessorState->SpecialRegisters.Cr4 = _Ke386GetCr(4); + + /* Save the DR registers */ + ProcessorState->SpecialRegisters.KernelDr0 = _Ke386GetDr(0); + ProcessorState->SpecialRegisters.KernelDr1 = _Ke386GetDr(1); + ProcessorState->SpecialRegisters.KernelDr2 = _Ke386GetDr(2); + ProcessorState->SpecialRegisters.KernelDr3 = _Ke386GetDr(3); + ProcessorState->SpecialRegisters.KernelDr6 = _Ke386GetDr(6); + ProcessorState->SpecialRegisters.KernelDr7 = _Ke386GetDr(7); + _Ke386SetDr(7, 0); + + /* Save GDT, IDT, LDT and TSS */ + Ke386GetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr); + Ke386GetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr); + Ke386GetTr(ProcessorState->SpecialRegisters.Tr); + Ke386GetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr); +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save) +{ + PFNSAVE_FORMAT FpState; + ASSERT_IRQL(DISPATCH_LEVEL); + DPRINT1("%s is not really implemented\n", __FUNCTION__); + + /* check if we are doing software emulation */ + if (!KeI386NpxPresent) return STATUS_ILLEGAL_FLOAT_CONTEXT; + + FpState = ExAllocatePool(NonPagedPool, sizeof (FNSAVE_FORMAT)); + if (!FpState) return STATUS_INSUFFICIENT_RESOURCES; + + *((PVOID *) Save) = FpState; +#ifdef __GNUC__ + asm volatile("fnsave %0\n\t" : "=m" (*FpState)); +#else + __asm + { + fnsave [FpState] + }; +#endif + + KeGetCurrentThread()->DispatcherHeader.NpxIrql = KeGetCurrentIrql(); + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save) +{ + PFNSAVE_FORMAT FpState = *((PVOID *) Save); + ASSERT(KeGetCurrentThread()->DispatcherHeader.NpxIrql == KeGetCurrentIrql()); + DPRINT1("%s is not really implemented\n", __FUNCTION__); + +#ifdef __GNUC__ + asm volatile("fnclex\n\t"); + asm volatile("frstor %0\n\t" : "=m" (*FpState)); +#else + __asm + { + fnclex + frstor [FpState] + }; +#endif + + ExFreePool(FpState); + return STATUS_SUCCESS; +} + /* * @implemented */ ULONG -STDCALL +NTAPI KeGetRecommendedSharedDataAlignment(VOID) { + /* Return the global variable */ return KeLargestCacheLine; } + +/* + * @implemented + */ +VOID +NTAPI +KeFlushEntireTb(IN BOOLEAN Invalid, + IN BOOLEAN AllProcessors) +{ + KIRQL OldIrql; + + /* Raise the IRQL for the TB Flush */ + OldIrql = KeRaiseIrqlToSynchLevel(); + +#ifdef CONFIG_SMP + /* FIXME: Support IPI Flush */ +#error Not yet implemented! +#endif + + /* Flush the TB for the Current CPU */ + KeFlushCurrentTb(); + + /* Return to Original IRQL */ + KeLowerIrql(OldIrql); +} + +/* + * @implemented + */ +VOID +NTAPI +KeSetDmaIoCoherency(IN ULONG Coherency) +{ + /* Save the coherency globally */ + KiDmaIoCoherency = Coherency; +} + +/* + * @implemented + */ +KAFFINITY +NTAPI +KeQueryActiveProcessors(VOID) +{ + PAGED_CODE(); + + /* Simply return the number of active processors */ + return KeActiveProcessors; +} + +/* + * @implemented + */ +VOID +__cdecl +KeSaveStateForHibernate(IN PKPROCESSOR_STATE State) +{ + /* Capture the context */ + RtlCaptureContext(&State->ContextFrame); + + /* Capture the control state */ + KiSaveProcessorControlState(State); +} diff --git a/reactos/ntoskrnl/ke/spinlock.c b/reactos/ntoskrnl/ke/spinlock.c index 07a80048316..0a634148f47 100644 --- a/reactos/ntoskrnl/ke/spinlock.c +++ b/reactos/ntoskrnl/ke/spinlock.c @@ -242,7 +242,7 @@ KeSynchronizeExecution(IN PKINTERRUPT Interrupt, * @implemented */ VOID -STDCALL +NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql) { diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 670bb1dd7e6..cab005e5b66 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -48,7 +48,7 @@ apc.c bug.c clock.c - device.c + config.c dpc.c event.c exception.c From 630f3d1e69f1592e855b3d0363499b17fcdaf051 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 02:25:32 +0000 Subject: [PATCH 176/488] - Cleanup ipi.c, reformat, and re-organize. - Undefine all functions for UP builds, except KeIpiGenericCall. - Implement KeIpiGenericCall for UP builds and add @implemented tag. svn path=/trunk/; revision=24093 --- reactos/ntoskrnl/ke/ipi.c | 244 ++++++++++++++++++-------------------- 1 file changed, 117 insertions(+), 127 deletions(-) diff --git a/reactos/ntoskrnl/ke/ipi.c b/reactos/ntoskrnl/ke/ipi.c index 451b724527c..7c72771cbc6 100644 --- a/reactos/ntoskrnl/ke/ipi.c +++ b/reactos/ntoskrnl/ke/ipi.c @@ -1,14 +1,12 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ke/ipi.c - * PURPOSE: IPI Routines (Inter-Processor Interrupts). NT5+ - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * PURPOSE: Inter-Processor Packet Interface + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG @@ -18,107 +16,41 @@ KSPIN_LOCK KiIpiLock; -/* FUNCTIONS *****************************************************************/ +/* PRIVATE FUNCTIONS *********************************************************/ VOID NTAPI -KiIpiSendRequest(KAFFINITY TargetSet, ULONG IpiRequest) +KiIpiSendRequest(IN KAFFINITY TargetSet, + IN ULONG IpiRequest) { - LONG i; - PKPCR Pcr; - KAFFINITY Current; +#ifdef CONFIG_SMP +#error VerifyMe! + LONG i; + PKPCR Pcr; + KAFFINITY Current; - for (i = 0, Current = 1; i < KeNumberProcessors; i++, Current <<= 1) - { - if (TargetSet & Current) - { - Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); - Ke386TestAndSetBit(IpiRequest, (PULONG)&Pcr->Prcb->IpiFrozen); - HalRequestIpi(i); - } - } -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, - IN PVOID ExceptionFrame) -{ -#ifdef DBG - LARGE_INTEGER StartTime, CurrentTime, Frequency; - ULONG Count = 5; + for (i = 0, Current = 1; i < KeNumberProcessors; i++, Current <<= 1) + { + if (TargetSet & Current) + { + Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); + Ke386TestAndSetBit(IpiRequest, (PULONG)&Pcr->Prcb->IpiFrozen); + HalRequestIpi(i); + } + } #endif - PKPRCB Prcb; - - ASSERT(KeGetCurrentIrql() == IPI_LEVEL); - - DPRINT("KiIpiServiceRoutine\n"); - - Prcb = KeGetCurrentPrcb(); - - if (Ke386TestAndClearBit(IPI_APC, (PULONG)&Prcb->IpiFrozen)) - { - HalRequestSoftwareInterrupt(APC_LEVEL); - } - - if (Ke386TestAndClearBit(IPI_DPC, (PULONG)&Prcb->IpiFrozen)) - { - Prcb->DpcInterruptRequested = TRUE; - HalRequestSoftwareInterrupt(DISPATCH_LEVEL); - } - - if (Ke386TestAndClearBit(IPI_SYNCH_REQUEST, (PULONG)&Prcb->IpiFrozen)) - { - (void)InterlockedDecrementUL(&Prcb->SignalDone->CurrentPacket[1]); - if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0)) - { -#ifdef DBG - StartTime = KeQueryPerformanceCounter(&Frequency); -#endif - while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[1], 0, 0)) - { -#ifdef DBG - CurrentTime = KeQueryPerformanceCounter(NULL); - if (CurrentTime.QuadPart > StartTime.QuadPart + Count * Frequency.QuadPart) - { - DbgPrint("(%s:%d) CPU%d, waiting longer than %d seconds to start the ipi routine\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber(), Count); - KEBUGCHECK(0); - } -#endif - } - } - ((VOID (STDCALL*)(PVOID))(Prcb->SignalDone->WorkerRoutine))(Prcb->SignalDone->CurrentPacket[0]); - Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), (PULONG)&Prcb->SignalDone->TargetSet); - if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0)) - { -#ifdef DBG - StartTime = KeQueryPerformanceCounter(&Frequency); -#endif - while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->TargetSet, 0, 0)) - { -#ifdef DBG - CurrentTime = KeQueryPerformanceCounter(NULL); - if (CurrentTime.QuadPart > StartTime.QuadPart + Count * Frequency.QuadPart) - { - DbgPrint("(%s:%d) CPU%d, waiting longer than %d seconds after executing the ipi routine\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber(), Count); - KEBUGCHECK(0); - } -#endif - } - } - (void)InterlockedExchangePointer(&Prcb->SignalDone, NULL); - } - DPRINT("KiIpiServiceRoutine done\n"); - return TRUE; } VOID -STDCALL -KiIpiSendPacket(KAFFINITY TargetSet, PKIPI_BROADCAST_WORKER WorkerRoutine, ULONG_PTR Argument, ULONG Count, BOOLEAN Synchronize) +NTAPI +KiIpiSendPacket(IN KAFFINITY TargetSet, + IN PKIPI_BROADCAST_WORKER WorkerRoutine, + IN ULONG_PTR Argument, + IN ULONG Count, + IN BOOLEAN Synchronize) { +#ifdef CONFIG_SMP +#error VerifyMe! KAFFINITY Processor; LONG i; PKPRCB Prcb, CurrentPrcb; @@ -136,49 +68,107 @@ KiIpiSendPacket(KAFFINITY TargetSet, PKIPI_BROADCAST_WORKER WorkerRoutine, ULONG for (i = 0, Processor = 1; i < KeNumberProcessors; i++, Processor <<= 1) { - if (TargetSet & Processor) - { - Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb; - while(0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0)); - Ke386TestAndSetBit(IPI_SYNCH_REQUEST, (PULONG)&Prcb->IpiFrozen); - if (Processor != CurrentPrcb->SetMember) - { - HalRequestIpi(i); - } - } + if (TargetSet & Processor) + { + Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb; + while(0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0)); + Ke386TestAndSetBit(IPI_SYNCH_REQUEST, (PULONG)&Prcb->IpiFrozen); + if (Processor != CurrentPrcb->SetMember) + { + HalRequestIpi(i); + } + } } if (TargetSet & CurrentPrcb->SetMember) { - KeRaiseIrql(IPI_LEVEL, &oldIrql); - KiIpiServiceRoutine(NULL, NULL); - KeLowerIrql(oldIrql); + KeRaiseIrql(IPI_LEVEL, &oldIrql); + KiIpiServiceRoutine(NULL, NULL); + KeLowerIrql(oldIrql); } +#endif } +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +BOOLEAN +NTAPI +KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, + IN PVOID ExceptionFrame) +{ +#ifdef CONFIG_SMP +#error VerifyMe! + PKPRCB Prcb; + ASSERT(KeGetCurrentIrql() == IPI_LEVEL); + + Prcb = KeGetCurrentPrcb(); + + if (Ke386TestAndClearBit(IPI_APC, (PULONG)&Prcb->IpiFrozen)) + { + HalRequestSoftwareInterrupt(APC_LEVEL); + } + + if (Ke386TestAndClearBit(IPI_DPC, (PULONG)&Prcb->IpiFrozen)) + { + Prcb->DpcInterruptRequested = TRUE; + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + } + + if (Ke386TestAndClearBit(IPI_SYNCH_REQUEST, (PULONG)&Prcb->IpiFrozen)) + { + (void)InterlockedDecrementUL(&Prcb->SignalDone->CurrentPacket[1]); + if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0)) + { + while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[1], 0, 0)); + } + ((VOID (STDCALL*)(PVOID))(Prcb->SignalDone->WorkerRoutine))(Prcb->SignalDone->CurrentPacket[0]); + Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), (PULONG)&Prcb->SignalDone->TargetSet); + if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0)) + { + while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->TargetSet, 0, 0)); + } + (void)InterlockedExchangePointer(&Prcb->SignalDone, NULL); + } +#endif + return TRUE; +} + +/* + * @implemented + */ ULONG_PTR NTAPI -KeIpiGenericCall(PKIPI_BROADCAST_WORKER Function, ULONG_PTR Argument) +KeIpiGenericCall(IN PKIPI_BROADCAST_WORKER Function, + IN ULONG_PTR Argument) { - KIRQL oldIrql; - KAFFINITY TargetSet; +#ifdef CONFIG_SMP +#error Not yet implemented! +#else + ULONG_PTR Status; + KIRQL OldIrql; - DPRINT("KeIpiGenericCall on CPU%d\n", KeGetCurrentProcessorNumber()); + /* Raise to DPC level if required */ + OldIrql = KeGetCurrentIrql(); + if (OldIrql <= DISPATCH_LEVEL) KfRaiseIrql(DISPATCH_LEVEL); - KeRaiseIrql(SYNCH_LEVEL, &oldIrql); + /* Acquire the IPI lock */ + KefAcquireSpinLockAtDpcLevel(&KiIpiLock); - KiAcquireSpinLock(&KiIpiLock); + /* Raise to IPI level */ + KfRaiseIrql(IPI_LEVEL); - TargetSet = (1 << KeNumberProcessors) - 1; + /* Call the function */ + Status = Function(Argument); - KiIpiSendPacket(TargetSet, Function, Argument, KeNumberProcessors, TRUE); + /* Release the lock */ + KefReleaseSpinLockFromDpcLevel(&KiIpiLock); - KiReleaseSpinLock(&KiIpiLock); - - KeLowerIrql(oldIrql); - - DPRINT("KeIpiGenericCall on CPU%d done\n", KeGetCurrentProcessorNumber()); - return 0; // FIXME + /* Lower IRQL back */ + KfLowerIrql(OldIrql); + return Status; +#endif } - /* EOF */ From 63142230b2f7bfddf4c66956d4821c85eaa1a36c Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 03:02:40 +0000 Subject: [PATCH 177/488] - Rename kqueue.c to devque. KQUEUE (kernel queues) are implemented in queue.c, and this filename always confused me. Why would you name KDEVICE_QUEUE into kqueue.c, when you already have KQUEUE in queue.c?! - Rename exception.c to except.c, mostly due to MSVC's incompatibility with multiple identically named files. - SVN delete usercall.c leftover. - Fix KeSetPriorityAndQuantumProcess to use Queued Spinlocks and KiAcquireProcess/ThreadLock when needed. svn path=/trunk/; revision=24094 --- reactos/ntoskrnl/ke/{kqueue.c => devqueue.c} | 2 +- reactos/ntoskrnl/ke/{exception.c => except.c} | 2 +- reactos/ntoskrnl/ke/process.c | 32 ++++-- reactos/ntoskrnl/ke/queue.c | 6 +- reactos/ntoskrnl/ke/usercall.c | 100 ------------------ reactos/ntoskrnl/ntoskrnl.rbuild | 4 +- 6 files changed, 29 insertions(+), 117 deletions(-) rename reactos/ntoskrnl/ke/{kqueue.c => devqueue.c} (99%) rename reactos/ntoskrnl/ke/{exception.c => except.c} (96%) delete mode 100644 reactos/ntoskrnl/ke/usercall.c diff --git a/reactos/ntoskrnl/ke/kqueue.c b/reactos/ntoskrnl/ke/devqueue.c similarity index 99% rename from reactos/ntoskrnl/ke/kqueue.c rename to reactos/ntoskrnl/ke/devqueue.c index a3a408a2238..94b5f6b51ac 100644 --- a/reactos/ntoskrnl/ke/kqueue.c +++ b/reactos/ntoskrnl/ke/devqueue.c @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/ke/kqueue.c + * FILE: ntoskrnl/ke/devqueue.c * PURPOSE: Implement device queues * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ diff --git a/reactos/ntoskrnl/ke/exception.c b/reactos/ntoskrnl/ke/except.c similarity index 96% rename from reactos/ntoskrnl/ke/exception.c rename to reactos/ntoskrnl/ke/except.c index c3b8059e5cf..86ad261bbea 100644 --- a/reactos/ntoskrnl/ke/exception.c +++ b/reactos/ntoskrnl/ke/except.c @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/ke/exception.c + * FILE: ntoskrnl/ke/except.c * PURPOSE: Platform independent exception handling * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index b8ab303e8c5..de6cd07ed58 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -261,27 +261,23 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, IN KPRIORITY Priority, IN UCHAR Quantum OPTIONAL) { + KLOCK_QUEUE_HANDLE ProcessLock; KPRIORITY Delta; PLIST_ENTRY NextEntry, ListHead; KPRIORITY NewPriority, OldPriority; - KIRQL OldIrql; PKTHREAD Thread; BOOLEAN Released; ASSERT_PROCESS(Process); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Check if the process already has this priority */ - if (Process->BasePriority == Priority) - { - /* Don't change anything */ - return Process->BasePriority; - } + if (Process->BasePriority == Priority) return Process->BasePriority; /* If the caller gave priority 0, normalize to 1 */ - if (!Priority) Priority = 1; + if (!LOW_PRIORITY) Priority = LOW_PRIORITY + 1; - /* Lock Dispatcher */ - OldIrql = KiAcquireDispatcherLock(); + /* Lock the process */ + KiAcquireProcessLock(Process, &ProcessLock); /* Check if we are modifying the quantum too */ if (Quantum) Process->QuantumReset = Quantum; @@ -309,6 +305,9 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, /* Update the quantum if we had one */ if (Quantum) Thread->QuantumReset = Quantum; + /* Acquire the thread lock */ + KiAcquireThreadLock(Thread); + /* Calculate the new priority */ NewPriority = Thread->BasePriority + Delta; if (NewPriority < LOW_REALTIME_PRIORITY) @@ -349,6 +348,9 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, KiSetPriorityThread(Thread, NewPriority, &Released); } + /* Release the thread lock */ + KiReleaseThreadLock(Thread); + /* Go to the next thread */ NextEntry = NextEntry->Flink; } @@ -364,6 +366,9 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, /* Update the quantum if we had one */ if (Quantum) Thread->QuantumReset = Quantum; + /* Lock the thread */ + KiAcquireThreadLock(Thread); + /* Calculate the new priority */ NewPriority = Thread->BasePriority + Delta; if (NewPriority >= LOW_REALTIME_PRIORITY) @@ -405,13 +410,20 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, KiSetPriorityThread(Thread, NewPriority, &Released); } + /* Release the thread lock */ + KiReleaseThreadLock(Thread); + /* Go to the next thread */ NextEntry = NextEntry->Flink; } } /* Release Dispatcher Database */ - if (!Released) KiReleaseDispatcherLock(OldIrql); + if (!Released) KiReleaseDispatcherLockFromDpcLevel(); + + /* Release the process lock */ + KiReleaseProcessLockFromDpcLevel(&ProcessLock); + KiExitDispatcher(ProcessLock.OldIrql); /* Return previous priority */ return OldPriority; diff --git a/reactos/ntoskrnl/ke/queue.c b/reactos/ntoskrnl/ke/queue.c index 8e5469160aa..245fad872f0 100644 --- a/reactos/ntoskrnl/ke/queue.c +++ b/reactos/ntoskrnl/ke/queue.c @@ -69,7 +69,7 @@ LONG NTAPI KiInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry, - BOOLEAN Head) + IN BOOLEAN Head) { ULONG InitialState; PKTHREAD Thread = KeGetCurrentThread(); @@ -103,10 +103,10 @@ KiInsertQueue(IN PKQUEUE Queue, /* Remove the queue from the thread's wait list */ Thread->WaitStatus = (NTSTATUS)Entry; if (Thread->WaitListEntry.Flink) RemoveEntryList(&Thread->WaitListEntry); - Thread->WaitReason = 0; - /* Increase the active threads and set the status*/ + /* Increase the active threads and remove any wait reason */ Queue->CurrentCount++; + Thread->WaitReason = 0; /* Check if there's a Thread Timer */ if (Thread->Timer.Header.Inserted) diff --git a/reactos/ntoskrnl/ke/usercall.c b/reactos/ntoskrnl/ke/usercall.c deleted file mode 100644 index 9ca8b1f1c21..00000000000 --- a/reactos/ntoskrnl/ke/usercall.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/usercall.c - * PURPOSE: User-Mode callbacks. Portable part. - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES ******************************************************************/ - -#include -#define NDEBUG -#include - -NTSTATUS -STDCALL -KiCallUserMode( - IN PVOID *OutputBuffer, - IN PULONG OutputLength -); - -PULONG -STDCALL -KiGetUserModeStackAddress( - VOID -); - -/* FUNCTIONS *****************************************************************/ - -/* - * @implemented - */ -NTSTATUS -STDCALL -KeUserModeCallback(IN ULONG RoutineIndex, - IN PVOID Argument, - IN ULONG ArgumentLength, - OUT PVOID *Result, - OUT PULONG ResultLength) -{ - ULONG_PTR NewStack, OldStack; - PULONG UserEsp; - NTSTATUS CallbackStatus = STATUS_SUCCESS; - PEXCEPTION_REGISTRATION_RECORD ExceptionList; - DPRINT("KeUserModeCallback(RoutineIndex %d, Argument %X, ArgumentLength %d)\n", - RoutineIndex, Argument, ArgumentLength); - ASSERT(KeGetCurrentThread()->ApcState.KernelApcInProgress == FALSE); - ASSERT(KeGetPreviousMode() == UserMode); - - /* Get the current user-mode stack */ - UserEsp = KiGetUserModeStackAddress(); - OldStack = *UserEsp; - - /* Enter a SEH Block */ - _SEH_TRY - { - /* Calculate and align the stack size */ - NewStack = (OldStack - ArgumentLength) & ~3; - - /* Make sure it's writable */ - ProbeForWrite((PVOID)(NewStack - 6 * sizeof(ULONG_PTR)), - ArgumentLength + 6 * sizeof(ULONG_PTR), - sizeof(CHAR)); - - /* Copy the buffer into the stack */ - RtlCopyMemory((PVOID)NewStack, Argument, ArgumentLength); - - /* Write the arguments */ - NewStack -= 24; - *(PULONG)NewStack = 0; - *(PULONG)(NewStack + 4) = RoutineIndex; - *(PULONG)(NewStack + 8) = (NewStack + 24); - *(PULONG)(NewStack + 12) = ArgumentLength; - - /* Save the exception list */ - ExceptionList = KeGetCurrentThread()->Teb->Tib.ExceptionList; - - /* Jump to user mode */ - *UserEsp = NewStack; - CallbackStatus = KiCallUserMode(Result, ResultLength); - - /* FIXME: Handle user-mode exception status */ - - /* Restore exception list */ - KeGetCurrentThread()->Teb->Tib.ExceptionList = ExceptionList; - } - _SEH_HANDLE - { - CallbackStatus = _SEH_GetExceptionCode(); - } - _SEH_END; - - /* FIXME: Flush GDI Batch */ - - /* Restore stack and return */ - *UserEsp = OldStack; - return CallbackStatus; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index cab005e5b66..02925121c28 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -49,14 +49,14 @@ bug.c clock.c config.c + devqueue.c dpc.c event.c - exception.c + except.c freeldr.c gate.c gmutex.c ipi.c - kqueue.c krnlinit.c mutex.c process.c From e6c1f9ca4bad8599a244b06dfb86ed5dfb79dc0d Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Wed, 13 Sep 2006 12:33:59 +0000 Subject: [PATCH 178/488] Add UnattendSetupEnabled key for enabling\disabling unattended setup without editing rbuild files. Modifing rbuild files all the time is not handy and slows down build process. svn path=/trunk/; revision=24095 --- reactos/base/setup/usetup/usetup.c | 23 +++++++++++++++-- reactos/boot/bootdata/unattend.inf.sample | 21 +++++++++++++--- reactos/dll/win32/syssetup/wizard.c | 30 +++++++++++++++++++++-- 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/reactos/base/setup/usetup/usetup.c b/reactos/base/setup/usetup/usetup.c index 3ca85ec7075..86f997ec60c 100644 --- a/reactos/base/setup/usetup/usetup.c +++ b/reactos/base/setup/usetup/usetup.c @@ -73,7 +73,7 @@ typedef enum _PAGE_NUMBER HANDLE ProcessHeap; UNICODE_STRING SourceRootPath; -BOOLEAN IsUnattendedSetup; +BOOLEAN IsUnattendedSetup = FALSE; LONG UnattendDestinationDiskNumber; LONG UnattendDestinationPartitionNumber; LONG UnattendMBRInstallType = -1; @@ -433,7 +433,6 @@ CheckUnattendedSetup(VOID) if (DoesFileExist(SourcePath.Buffer, L"unattend.inf") == FALSE) { DPRINT("Does not exist: %S\\%S\n", SourcePath.Buffer, L"unattend.inf"); - IsUnattendedSetup = FALSE; return; } @@ -475,6 +474,26 @@ CheckUnattendedSetup(VOID) return; } + /* Check if Unattend setup is enabled */ + if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"UnattendSetupEnabled", &Context)) + { + DPRINT("Can't find key 'UnattendSetupEnabled'\n"); + SetupCloseInfFile(&UnattendInf); + return; + } + if (!INF_GetData(&Context, NULL, &Value)) + { + DPRINT("Can't read key 'UnattendSetupEnabled'\n"); + SetupCloseInfFile(&UnattendInf); + return; + } + if (_wcsicmp(Value, L"yes") != 0) + { + DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n"); + SetupCloseInfFile(&UnattendInf); + return; + } + /* Search for 'DestinationDiskNumber' in the 'Unattend' section */ if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"DestinationDiskNumber", &Context)) { diff --git a/reactos/boot/bootdata/unattend.inf.sample b/reactos/boot/bootdata/unattend.inf.sample index 8469c182f01..955f3cb683c 100644 --- a/reactos/boot/bootdata/unattend.inf.sample +++ b/reactos/boot/bootdata/unattend.inf.sample @@ -1,18 +1,31 @@ -; Install to \Device\Harddisk0\Partition1\ReactOS +; In order to get unattended setup working: +; 1. Copy unattend.inf.sample to unattend.inf, adjust as needed +; 2. Uncomment the line in bootdata.rbuild to include it into bootcd + [Unattend] Signature = "$ReactOS$" + +; yes - unattend setup enabled +; no - unattend setup disabled +UnattendSetupEnabled = yes + +; Install to \Device\Harddisk0\Partition1\ReactOS DestinationDiskNumber = 0 DestinationPartitionNumber = 1 InstallationDirectory=ReactOS -;MBRInstallType=0 skips MBR installation -;MBRInstallType=1 install MBR on floppy -;MBRInstallType=2 install MBR on hdd + +; MBRInstallType=0 skips MBR installation +; MBRInstallType=1 install MBR on floppy +; MBRInstallType=2 install MBR on hdd MBRInstallType=2 + FullName="MyName" ;OrgName="MyOrg" ComputerName="MYCOMPUTERNAME"; AdminPassword="MyPassword" + ; TimeZone is set GMT as default TimeZoneIndex=85 + ; enable this setting to disable daylight saving changes ; DisableAutoDaylightTimeSet = 1 \ No newline at end of file diff --git a/reactos/dll/win32/syssetup/wizard.c b/reactos/dll/win32/syssetup/wizard.c index 807ecd2a822..4019a2870e6 100644 --- a/reactos/dll/win32/syssetup/wizard.c +++ b/reactos/dll/win32/syssetup/wizard.c @@ -1909,6 +1909,31 @@ ProcessUnattendInf(HINF hUnattendedInf) TCHAR szValue[256]; DWORD LineLength; + if (!SetupFindFirstLine(hUnattendedInf, + _T("Unattend"), + _T("UnattendSetupEnabled"), + &InfContext)) + { + DPRINT1("Error: Cant find UnattendSetupEnabled Key! %d\n", GetLastError()); + return FALSE; + } + + if (!SetupGetStringField(&InfContext, + 1, + szValue, + sizeof(szValue) / sizeof(TCHAR), + &LineLength)) + { + DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError()); + return FALSE; + } + + if (_tcscmp(szValue, _T("yes")) != 0) + { + DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n"); + return FALSE; + } + if (!SetupFindFirstLine(hUnattendedInf, _T("Unattend"), NULL, @@ -1917,7 +1942,8 @@ ProcessUnattendInf(HINF hUnattendedInf) DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError()); return FALSE; } - + + do { if (!SetupGetStringField(&InfContext, @@ -1994,7 +2020,7 @@ InstallWizard(VOID) /* Clear setup data */ ZeroMemory(&SetupData, sizeof(SETUPDATA)); - + hUnattendedInf = SetupOpenInfFileW(L"unattend.inf", NULL, INF_STYLE_OLDNT, From 0eabb5d7bcc74635f3f314bee53125c45797199b Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Wed, 13 Sep 2006 13:03:17 +0000 Subject: [PATCH 179/488] Move UserDrawIconEx and UserGetCurIconObject prototyepes to header file. svn path=/trunk/; revision=24096 --- reactos/subsystems/win32/win32k/include/cursoricon.h | 4 ++++ reactos/subsystems/win32/win32k/ntuser/painting.c | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/cursoricon.h b/reactos/subsystems/win32/win32k/include/cursoricon.h index 18004968771..e3c70a6ad3b 100644 --- a/reactos/subsystems/win32/win32k/include/cursoricon.h +++ b/reactos/subsystems/win32/win32k/include/cursoricon.h @@ -58,6 +58,10 @@ VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Pro BOOL FASTCALL IntGetCursorLocation(PWINSTATION_OBJECT WinStaObject, POINT *loc); +BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, + INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags); +PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon); + #define IntGetSysCursorInfo(WinStaObj) \ (PSYSTEM_CURSORINFO)((WinStaObj)->SystemCursor) diff --git a/reactos/subsystems/win32/win32k/ntuser/painting.c b/reactos/subsystems/win32/win32k/ntuser/painting.c index 09e371dc71f..1625b7375cf 100644 --- a/reactos/subsystems/win32/win32k/ntuser/painting.c +++ b/reactos/subsystems/win32/win32k/ntuser/painting.c @@ -1375,9 +1375,6 @@ CLEANUP: /* Don't know where to put this */ BOOL FASTCALL IntGdiGradientFill(DC *dc, PTRIVERTEX pVertex, ULONG uVertex, PVOID pMesh, ULONG uMesh, ULONG ulMode); ULONG FASTCALL IntSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni); -BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, - INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags); -PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon); BOOL UserDrawSysMenuButton( From 457e0142bdd1c4ce58ee682870d6ff29c35bc4e6 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Wed, 13 Sep 2006 13:43:39 +0000 Subject: [PATCH 180/488] Move IntGdiGradientFill and IntSystemParametersInfo prototypes to header files. Delete DestroyThreadWindows prototype (function does not exist). svn path=/trunk/; revision=24097 --- reactos/subsystems/win32/win32k/include/intgdi.h | 5 +++++ reactos/subsystems/win32/win32k/include/misc.h | 5 ++--- reactos/subsystems/win32/win32k/ntuser/painting.c | 3 --- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/intgdi.h b/reactos/subsystems/win32/win32k/include/intgdi.h index a3d5a405222..6c1eaa7399e 100644 --- a/reactos/subsystems/win32/win32k/include/intgdi.h +++ b/reactos/subsystems/win32/win32k/include/intgdi.h @@ -115,6 +115,11 @@ IntGdiPolyPolygon(DC *dc, LPINT PolyCounts, int Count); +BOOL FASTCALL IntGdiGradientFill(DC *dc, + PTRIVERTEX pVertex, + ULONG uVertex, + PVOID pMesh, ULONG uMesh, ULONG ulMode); + /* Rgn functions */ int FASTCALL diff --git a/reactos/subsystems/win32/win32k/include/misc.h b/reactos/subsystems/win32/win32k/include/misc.h index 85491f464a6..1e4f2a86268 100644 --- a/reactos/subsystems/win32/win32k/include/misc.h +++ b/reactos/subsystems/win32/win32k/include/misc.h @@ -6,8 +6,7 @@ #define W32PF_MANUALGUICHECK (0x0002) #define W32PF_CREATEDWINORDC (0x0004) -VOID -FASTCALL -DestroyThreadWindows(struct _ETHREAD *Thread); +ULONG FASTCALL IntSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni); + #endif /* __WIN32K_MISC_H */ diff --git a/reactos/subsystems/win32/win32k/ntuser/painting.c b/reactos/subsystems/win32/win32k/ntuser/painting.c index 1625b7375cf..17829f9d4a5 100644 --- a/reactos/subsystems/win32/win32k/ntuser/painting.c +++ b/reactos/subsystems/win32/win32k/ntuser/painting.c @@ -1372,9 +1372,6 @@ CLEANUP: END_CLEANUP; } -/* Don't know where to put this */ -BOOL FASTCALL IntGdiGradientFill(DC *dc, PTRIVERTEX pVertex, ULONG uVertex, PVOID pMesh, ULONG uMesh, ULONG ulMode); -ULONG FASTCALL IntSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni); BOOL UserDrawSysMenuButton( From 182b4dc71dc10c52c7bb0927d829333466896472 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Wed, 13 Sep 2006 14:07:41 +0000 Subject: [PATCH 181/488] compatibility header. Implements Visual C++ intrinsics in GCC. Licensed very liberally, please keep it that way svn path=/trunk/; revision=24098 --- reactos/include/psdk/intrin.h | 1116 +++++++++++++++++++++++++++++++++ 1 file changed, 1116 insertions(+) create mode 100644 reactos/include/psdk/intrin.h diff --git a/reactos/include/psdk/intrin.h b/reactos/include/psdk/intrin.h new file mode 100644 index 00000000000..6b68ef1776e --- /dev/null +++ b/reactos/include/psdk/intrin.h @@ -0,0 +1,1116 @@ +/* + Compatibility header for GCC -- GCC equivalents of intrinsic + Microsoft Visual C++ functions. Originally developed for the ReactOS + () and TinyKrnl () + projects. + + Copyright (c) 2006 KJK::Hyperion + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KJK_INTRIN_H_ +#define KJK_INTRIN_H_ + +#ifndef __GNUC__ +#error Unsupported compiler +#endif + +/* + FIXME: review all "memory" clobbers, add/remove to match Visual C++ + behavior: some "obvious" memory barriers are not present in the Visual C++ + implementation - e.g. __stosX; on the other hand, some memory barriers that + *are* present could have been missed +*/ +/* + FIXME: atomic intrinsics haven't been tested yet +*/ + +/* + NOTE: this is a *compatibility* header. Some functions may look wrong at + first, but they're only "as wrong" as they would be on Visual C++. Our + priority is compatibility + + NOTE: unlike most people who write __inline__ asm for GCC, I didn't pull the + constraints and the uses of __volatile__ out of my... hat. Do not touch + them. I hate cargo cult programming + + NOTE: be very careful with declaring "memory" clobbers. Some "obvious" + barriers aren't there in Visual C++ (e.g. __stosX) + + NOTE: review all intrinsics with a return value, add/remove __volatile__ + where necessary. If an intrinsic whose value is ignored generates a no-op + under Visual C++, __volatile__ must be omitted; if it always generates code + (for example, if it has side effects), __volatile__ must be specified. GCC + will only optimize out non-volatile asm blocks with outputs, so input-only + blocks are safe. Oddities such as the non-volatile 'rdmsr' are intentional + and follow Visual C++ behavior + + NOTE: on GCC 4.1.0, please use the __sync_* built-ins for barriers and + atomic operations. Test the version like this: + + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 + ... + + Pay attention to the type of barrier. Make it match with what Visual C++ + would use in the same case +*/ + +/* + BUGBUG: 'long long' arguments and returns mess up GCC royally. There has to + be something we can do about them +*/ +#ifdef __i386__ + +/*** Stack frame juggling ***/ +#define _ReturnAddress() (__builtin_return_address(0)) +#define _AddressOfReturnAddress() (&(((void **)(__builtin_frame_address(0)))[1])) +/* TODO: __getcallerseflags but how??? */ + + +/*** Atomic operations ***/ +/* TODO: _ReadBarrier */ +/* TODO: _WriteBarrier */ + +#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 +#define _ReadWriteBarrier() __sync_synchronize() +#else +/* TODO: _ReadWriteBarrier() */ +#endif + +#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 + +static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand) +{ + return __sync_val_compare_and_swap(Destination, Comperand, Exchange); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value) +{ + /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */ + __sync_synchronize(); + return __sync_lock_test_and_set(Target, Value); +} + +static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value) +{ + /* NOTE: ditto */ + __sync_synchronize(); + return __sync_lock_test_and_set(Target, Value); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value) +{ + return __sync_fetch_and_add(Addend, Value); +} + +static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask) +{ + return __sync_fetch_and_and(value, mask); +} + +static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask) +{ + return __sync_fetch_and_and(value, mask); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask) +{ + return __sync_fetch_and_and(value, mask); +} + +static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask) +{ + return __sync_fetch_and_or(value, mask); +} + +static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask) +{ + return __sync_fetch_and_or(value, mask); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask) +{ + return __sync_fetch_and_or(value, mask); +} + +static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask) +{ + return __sync_fetch_and_xor(value, mask); +} + +static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask) +{ + return __sync_fetch_and_xor(value, mask); +} + +static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask) +{ + return __sync_fetch_and_xor(value, mask); +} + +#else + +static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand) +{ + char retval = Comperand; + __asm__("lock; cmpxchgb %b[Exchange], %[Destination]" : "a" (retval) : [Destination] "rm" (Destination), [Exchange] "r" (Exchange) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand) +{ + short retval = Comperand; + __asm__("lock; cmpxchgw %w[Exchange], %[Destination]" : "a" (retval) : [Destination] "rm" (Destination), [Exchange] "r" (Exchange): "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand) +{ + long retval = Comperand; + __asm__("lock; cmpxchgl %l[Exchange], %[Destination]" : "a" (retval) : [Destination] "rm" (Destination), [Exchange] "r" (Exchange): "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand) +{ + /* TODO: this form of passing long long values makes GCC generate inefficient code. Use what's used elsewhere */ + union + { + long long ll; + struct + { + unsigned long lo32; + long hi32; + }; + } + LlRetval = { ll : Comperand }; + + union + { + long long ll; + struct + { + unsigned long lo32; + long hi32; + }; + } + LlExchange = { ll : Exchange }; + + __asm__ + ( + "cmpxchg8b %[Destination]" : + "a" (LlRetval.lo32), "d" (LlRetval.hi32) : + [Destination] "rm" (Destination), "b" (LlExchange.lo32), "c" (LlExchange.hi32) : + "memory" + ); + + return LlRetval.ll; +} + +static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand) +{ + void * retval; + __asm__("lock; cmpxchgl %l[Exchange], %[Destination]" : "a" (retval) : [Destination] "rm" (Destination), [Exchange] "r" (Exchange), "a" (Comperand) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value) +{ + long retval = Value; + __asm__("lock; xchgl %[retval], %[Target]" : [retval] "r" (retval) : [Target] "rm" (Target) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value) +{ + void * retval = Value; + __asm__("lock; xchgl %[retval], %[Target]" : [retval] "r" (retval) : [Target] "rm" (Target) : "memory"); + return retval; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value) +{ + long retval = Value; + __asm__("lock; xaddl %[retval], %[Addend]" : "r" (retval) : "rm" (Addend)); + return retval; +} + +static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask) +{ + char x; + char y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange8(value, x & mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask) +{ + short x; + short y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange16(value, x & mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask) +{ + long x; + long y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange(value, x & mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask) +{ + char x; + char y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange8(value, x | mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask) +{ + short x; + short y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange16(value, x | mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask) +{ + long x; + long y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange(value, x | mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask) +{ + char x; + char y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange8(value, x ^ mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask) +{ + short x; + short y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange16(value, x ^ mask, x); + } + while(y != x); + + return y; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask) +{ + long x; + long y; + + y = *value; + + do + { + x = y; + y = _InterlockedCompareExchange(value, x ^ mask, x); + } + while(y != x); + + return y; +} + +#endif + +static __inline__ __attribute__((always_inline)) long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value) +{ + __asm__ + ( + "lock; add %[Value], %[Lo32];" + "jae LABEL%=;" + "lock; adc $0, %[Hi32];" + "LABEL%=:;" : + [Lo32] "=m" (*((volatile long *)(Addend) + 0)), [Hi32] "=m" (*((volatile long *)(Addend) + 1)) : + [Value] "ir" (Value) + ); + + return Value; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedDecrement(volatile long * const lpAddend) +{ + return _InterlockedExchangeAdd(lpAddend, -1) - 1; +} + +static __inline__ __attribute__((always_inline)) long _InterlockedIncrement(volatile long * const lpAddend) +{ + return _InterlockedExchangeAdd(lpAddend, 1) + 1; +} + +static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandreset(volatile long * const a, const long b) +{ + unsigned char retval; + __asm__("lock; btr %[b], %[a]; setc %b[retval]" : [retval] "=q" (retval) : [a] "rm" (a), [b] "Nr" (b)); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandset(volatile long * const a, const long b) +{ + unsigned char retval; + __asm__("lock; bts %[b], %[a]; setc %b[retval]" : [retval] "=q" (retval) : [a] "rm" (a), [b] "Nr" (b)); + return retval; +} + + +/*** String operations ***/ +/* NOTE: we don't set a memory barrier in the __stosX functions because Visual C++ doesn't */ +static __inline__ __attribute__((always_inline)) void __stosb(unsigned char * Dest, const unsigned char Data, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; stosb" : + [Dest] "=D" (Dest), [Count] "=c" (Count) : + "[Dest]" (Dest), "a" (Data), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __stosw(unsigned short * Dest, const unsigned short Data, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; stosw" : + [Dest] "=D" (Dest), [Count] "=c" (Count) : + "[Dest]" (Dest), "a" (Data), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __stosd(unsigned long * Dest, const unsigned long Data, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; stosl" : + [Dest] "=D" (Dest), [Count] "=c" (Count) : + "[Dest]" (Dest), "a" (Data), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __movsb(unsigned char * Destination, const unsigned char * Source, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; movsb" : + [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) : + "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __movsw(unsigned short * Destination, const unsigned short * Source, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; movsw" : + [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) : + "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count) + ); +} + +static __inline__ __attribute__((always_inline)) void __movsd(unsigned long * Destination, const unsigned long * Source, size_t Count) +{ + __asm__ __volatile__ + ( + "rep; movsd" : + [Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) : + "[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count) + ); +} + + +/*** FS segment addressing ***/ +static __inline__ __attribute__((always_inline)) void __writefsbyte(const unsigned long Offset, const unsigned char Data) +{ + __asm__("movb %b[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __writefsword(const unsigned long Offset, const unsigned short Data) +{ + __asm__("movw %w[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __writefsdword(const unsigned long Offset, const unsigned long Data) +{ + __asm__("movl %k[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) unsigned char __readfsbyte(const unsigned long Offset) +{ + unsigned char value; + __asm__("movb %%fs:%a[Offset], %b[value]" : [value] "=q" (value) : [Offset] "irm" (Offset)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned short __readfsword(const unsigned long Offset) +{ + unsigned short value; + __asm__("movw %%fs:%a[Offset], %w[value]" : [value] "=q" (value) : [Offset] "irm" (Offset)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readfsdword(const unsigned long Offset) +{ + unsigned long value; + __asm__("movl %%fs:%a[Offset], %l[value]" : [value] "=q" (value) : [Offset] "irm" (Offset)); + return value; +} + +static __inline__ __attribute__((always_inline)) void __incfsbyte(const unsigned long Offset) +{ + __asm__("incb %%fs:%a[Offset]" : : [Offset] "ir" (Offset)); +} + +static __inline__ __attribute__((always_inline)) void __incfsword(const unsigned long Offset) +{ + __asm__("incw %%fs:%a[Offset]" : : [Offset] "ir" (Offset)); +} + +static __inline__ __attribute__((always_inline)) void __incfsdword(const unsigned long Offset) +{ + __asm__("incl %%fs:%a[Offset]" : : [Offset] "ir" (Offset)); +} + +/* NOTE: the bizarre implementation of __addfsxxx mimics the broken Visual C++ behavior */ +static __inline__ __attribute__((always_inline)) void __addfsbyte(const unsigned long Offset, const unsigned char Data) +{ + if(!__builtin_constant_p(Offset)) + __asm__("addb %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset)); + else + __asm__("addb %b[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __addfsword(const unsigned long Offset, const unsigned short Data) +{ + if(!__builtin_constant_p(Offset)) + __asm__("addw %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset)); + else + __asm__("addw %w[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __addfsdword(const unsigned long Offset, const unsigned int Data) +{ + if(!__builtin_constant_p(Offset)) + __asm__("addl %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset)); + else + __asm__("addl %k[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + + +/*** Bit manipulation ***/ +static __attribute__((always_inline)) unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask) +{ + __asm__("bsfl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask)); + return Mask ? 1 : 0; +} + +static __attribute__((always_inline)) unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask) +{ + __asm__("bsrl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask)); + return Mask ? 1 : 0; +} + +/* NOTE: again, the bizarre implementation follows Visual C++ */ +static __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b) +{ + unsigned char retval; + + if(__builtin_constant_p(b)) + __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32)); + else + __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b)); + + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _bittestandcomplement(long * const a, const long b) +{ + unsigned char retval; + + if(__builtin_constant_p(b)) + __asm__("btc %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32)); + else + __asm__("btc %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b)); + + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _bittestandreset(long * const a, const long b) +{ + unsigned char retval; + + if(__builtin_constant_p(b)) + __asm__("btr %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32)); + else + __asm__("btr %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b)); + + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _bittestandset(long * const a, const long b) +{ + unsigned char retval; + + if(__builtin_constant_p(b)) + __asm__("bts %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32)); + else + __asm__("bts %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b)); + + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _rotl8(const unsigned char value, const unsigned char shift) +{ + unsigned char retval; + __asm__("rolb %b[shift], %b[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned short _rotl16(const unsigned short value, const unsigned char shift) +{ + unsigned short retval; + __asm__("rolw %b[shift], %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned char _rotr8(const unsigned char value, const unsigned char shift) +{ + unsigned char retval; + __asm__("rorb %b[shift], %b[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned short _rotr16(const unsigned short value, const unsigned char shift) +{ + unsigned short retval; + __asm__("rorw %b[shift], %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + return retval; +} + +static __inline__ __attribute__((always_inline)) unsigned long long __ll_lshift(const unsigned long long Mask, int Bit) +{ + unsigned long lo32 = (unsigned long)((Mask >> 0) & 0xFFFFFFFF); + unsigned long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF); + + __asm__ + ( + "shldl %b[Bit], %k[Lo32], %k[Hi32]; sall %b[Bit], %k[Lo32]" : + [Lo32] "=q" (lo32), [Hi32] "=qm" (hi32): + "[Lo32]" (lo32), "[Hi32]" (hi32), [Bit] "Ic" (Bit) + ); + + { + union u_ + { + unsigned long long ull; + struct s_ + { + unsigned long lo32; + unsigned long hi32; + } + s; + } + u = { s : { lo32 : lo32, hi32 : hi32 } }; + + return u.ull; + } +} + +static __inline__ __attribute__((always_inline)) long long __ll_rshift(const long long Mask, const int Bit) +{ + unsigned long lo32 = (unsigned long)((Mask >> 0) & 0xFFFFFFFF); + long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF); + + __asm__ + ( + "shrdl %b[Bit], %k[Lo32], %k[Hi32]; sarl %b[Bit], %k[Lo32]" : + [Lo32] "=q" (lo32), [Hi32] "=qm" (hi32): + "[Lo32]" (lo32), "[Hi32]" (hi32), [Bit] "Ic" (Bit) + ); + + { + union u_ + { + long long ll; + struct s_ + { + unsigned long lo32; + long hi32; + } + s; + } + u = { s : { lo32 : lo32, hi32 : hi32 } }; + + return u.ll; + } +} + +static __inline__ __attribute__((always_inline)) unsigned long long __ull_rshift(const unsigned long long Mask, int Bit) +{ + unsigned long lo32 = (unsigned long)((Mask >> 0) & 0xFFFFFFFF); + unsigned long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF); + + __asm__ + ( + "shrdl %b[Bit], %k[Hi32], %k[Lo32]; shrl %b[Bit], %k[Hi32]" : + [Lo32] "=qm" (lo32), [Hi32] "=q" (hi32): + "[Lo32]" (lo32), "[Hi32]" (hi32), [Bit] "Ic" (Bit) + ); + + { + union u_ + { + unsigned long long ull; + struct s_ + { + unsigned long lo32; + unsigned long hi32; + } + s; + } + u = { s : { lo32 : lo32, hi32 : hi32 } }; + + return u.ull; + } +} + + +/*** 64-bit math ***/ +static __inline__ __attribute__((always_inline)) long long __emul(const int a, const int b) +{ + unsigned long lo32; + long hi32; + + __asm__("imul %[b]" : "=a" (lo32), "=d" (hi32) : [a] "a" (a), [b] "rm" (b)); + + { + union u_ + { + long long ll; + struct s_ + { + unsigned long lo32; + long hi32; + } + s; + } + u = { s : { lo32 : lo32, hi32 : hi32 } }; + + return u.ll; + } +} + +static __inline__ __attribute__((always_inline)) unsigned long long __emulu(const unsigned int a, const unsigned int b) +{ + unsigned long lo32; + unsigned long hi32; + + __asm__("mul %[b]" : "=a" (lo32), "=d" (hi32) : [a] "a" (a), [b] "rm" (b)); + + { + union u_ + { + unsigned long long ull; + struct s_ + { + unsigned long lo32; + unsigned long hi32; + } + s; + } + u = { s : { lo32 : lo32, hi32 : hi32 } }; + + return u.ull; + } +} + + +/*** Port I/O ***/ +static __inline__ __attribute__((always_inline)) unsigned char __inbyte(const unsigned short Port) +{ + unsigned char byte; + __asm__ __volatile__("inb %w[Port], %b[byte]" : [byte] "=a" (byte) : [Port] "Nd" (Port)); + return byte; +} + +static __inline__ __attribute__((always_inline)) unsigned short __inword(const unsigned short Port) +{ + unsigned short word; + __asm__ __volatile__("inw %w[Port], %w[word]" : [word] "=a" (word) : [Port] "Nd" (Port)); + return word; +} + +static __inline__ __attribute__((always_inline)) unsigned long __indword(const unsigned short Port) +{ + unsigned long dword; + __asm__ __volatile__("inl %w[Port], %k[dword]" : [dword] "=a" (dword) : [Port] "Nd" (Port)); + return dword; +} + +static __inline__ __attribute__((always_inline)) void __inbytestring(unsigned short Port, unsigned char * Buffer, unsigned long Count) +{ + __asm__ __volatile__ + ( + "rep; insb" : + [Buffer] "=D" (Buffer), [Count] "=c" (Count) : + "d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) : + "memory" + ); +} + +static __inline__ __attribute__((always_inline)) void __inwordstring(unsigned short Port, unsigned short * Buffer, unsigned long Count) +{ + __asm__ __volatile__ + ( + "rep; insw" : + [Buffer] "=D" (Buffer), [Count] "=c" (Count) : + "d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) : + "memory" + ); +} + +static __inline__ __attribute__((always_inline)) void __indwordstring(unsigned short Port, unsigned long * Buffer, unsigned long Count) +{ + __asm__ __volatile__ + ( + "rep; insl" : + [Buffer] "=D" (Buffer), [Count] "=c" (Count) : + "d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) : + "memory" + ); +} + +static __inline__ __attribute__((always_inline)) void __outbyte(unsigned short const Port, const unsigned char Data) +{ + __asm__ __volatile__("outb %b[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __outword(unsigned short const Port, const unsigned short Data) +{ + __asm__ __volatile__("outw %w[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __outdword(unsigned short const Port, const unsigned long Data) +{ + __asm__ __volatile__("outl %k[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data)); +} + +static __inline__ __attribute__((always_inline)) void __outbytestring(unsigned short const Port, const unsigned char * const Buffer, const unsigned long Count) +{ + __asm__ __volatile__("rep; outsb" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count)); +} + +static __inline__ __attribute__((always_inline)) void __outwordstring(unsigned short const Port, const unsigned short * const Buffer, const unsigned long Count) +{ + __asm__ __volatile__("rep; outsw" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count)); +} + +static __inline__ __attribute__((always_inline)) void __outdwordstring(unsigned short const Port, const unsigned long * const Buffer, const unsigned long Count) +{ + __asm__ __volatile__("rep; outsl" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count)); +} + + +/*** System information ***/ +static __inline__ __attribute__((always_inline)) void __cpuid(int CPUInfo[], const int InfoType) +{ + __asm__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType)); +} + +static __inline__ __attribute__((always_inline)) unsigned long long __rdtsc(void) +{ + unsigned long lo32; + unsigned long hi32; + + __asm__("rdtsc" : "=a" (lo32), "=d" (hi32)); + + { + union u_ + { + unsigned long long ull; + struct s_ + { + unsigned long lo32; + unsigned long hi32; + } + s; + } + u = { s : { lo32 : lo32, hi32 : hi32 } }; + + return u.ull; + } +} + + +/*** Interrupts ***/ +static __inline__ __attribute__((always_inline)) void __debugbreak(void) +{ + __asm__("int $3"); +} + +static __inline__ __attribute__((always_inline)) void __int2c(void) +{ + __asm__("int $0x2c"); +} + +static __inline__ __attribute__((always_inline)) void _disable(void) +{ + __asm__("cli"); +} + +static __inline__ __attribute__((always_inline)) void _enable(void) +{ + __asm__("sti"); +} + + +/*** Protected memory management ***/ +static __inline__ __attribute__((always_inline)) unsigned long __readcr0(void) +{ + unsigned long value; + __asm__("mov %%cr0, %[value]" : [value] "=q" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr2(void) +{ + unsigned long value; + __asm__("mov %%cr2, %[value]" : [value] "=q" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr3(void) +{ + unsigned long value; + __asm__("mov %%cr3, %[value]" : [value] "=q" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr4(void) +{ + unsigned long value; + __asm__("mov %%cr4, %[value]" : [value] "=q" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) void __writecr0(const unsigned long long Data) +{ + __asm__("mov %[value], %%cr0" : : "q" ((const unsigned long)(Data & 0xFFFFFFFF))); +} + +static __inline__ __attribute__((always_inline)) void __writecr3(const unsigned long long Data) +{ + __asm__("mov %[value], %%cr3" : : "q" ((const unsigned long)(Data & 0xFFFFFFFF))); +} + +static __inline__ __attribute__((always_inline)) void __writecr4(const unsigned long long Data) +{ + __asm__("mov %[value], %%cr4" : : "q" ((const unsigned long)(Data & 0xFFFFFFFF))); +} + +static __inline__ __attribute__((always_inline)) void __invlpg(void * const Address) +{ + __asm__("invlpg %[Address]" : : [Address] "m" (*((unsigned char *)(Address)))); +} + + +/*** System operations ***/ +static __inline__ __attribute__((always_inline)) unsigned long long __readmsr(const int reg) +{ + unsigned long lo32; + unsigned long hi32; + + __asm__("rdmsr" : "=a" (lo32), "=d" (hi32) : "c" (reg)); + + { + union u_ + { + unsigned long long ull; + struct s_ + { + unsigned long lo32; + unsigned long hi32; + } + s; + } + u = { s : { lo32 : lo32, hi32 : hi32 } }; + + return u.ull; + } +} + +static __inline__ __attribute__((always_inline)) void __writemsr(const unsigned long Register, const unsigned long long Value) +{ + __asm__ + ( + "wrmsr" : + : + "a" ((unsigned long)((Value >> 0) & 0xFFFFFFFF)), + "d" ((unsigned long)((Value >> 32) & 0xFFFFFFFF)), + "c" (Register) + ); +} + +static __inline__ __attribute__((always_inline)) unsigned long long __readpmc(const int counter) +{ + unsigned long lo32; + unsigned long hi32; + + __asm__("rdpmc" : "=a" (lo32), "=d" (hi32) : "c" (counter)); + + { + union u_ + { + unsigned long long ull; + struct s_ + { + unsigned long lo32; + unsigned long hi32; + } + s; + } + u = { s : { lo32 : lo32, hi32 : hi32 } }; + + return u.ull; + } +} + +/* NOTE: an immediate value for 'a' will raise an ICE in Visual C++ */ +static __inline__ __attribute__((always_inline)) unsigned long __segmentlimit(const unsigned long a) +{ + unsigned long retval; + __asm__ __volatile__("lsl %[a], %[retval]" : [retval] "=r" (retval) : [a] "rm" (a)); + return retval; +} + +static __inline__ __attribute__((always_inline)) void __wbinvd(void) +{ + __asm__("wbinvd"); +} + +#else +/* TODO: the x64 architecture shares most of the intrinsics. It should be easy to support */ +#error Unsupported architecture +#endif + + +/*** Miscellaneous ***/ +/* BUGBUG: only good for use in macros. Cannot be taken the address of */ +#define __noop(...) ((void)0) + +/* TODO: __assume. GCC only supports the weaker __builtin_expect */ + +#endif + +/* EOF */ From 5971670b9b53df2b80170bdf8d9a9bfc88246f22 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Wed, 13 Sep 2006 16:50:19 +0000 Subject: [PATCH 182/488] Separate NtGdiModifyWorldTransform and IntGdiModifyWorldTransform for internal usage. svn path=/trunk/; revision=24099 --- .../subsystems/win32/win32k/include/coord.h | 6 + .../subsystems/win32/win32k/objects/coord.c | 105 +++++++++--------- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/coord.h b/reactos/subsystems/win32/win32k/include/coord.h index fe6badccc13..17d737735c3 100644 --- a/reactos/subsystems/win32/win32k/include/coord.h +++ b/reactos/subsystems/win32/win32k/include/coord.h @@ -21,4 +21,10 @@ VOID FASTCALL IntLPtoDP ( PDC dc, LPPOINT Points, INT Count ); +BOOL +FASTCALL +IntGdiModifyWorldTransform(PDC pDc, + CONST LPXFORM lpXForm, + DWORD Mode); + #endif diff --git a/reactos/subsystems/win32/win32k/objects/coord.c b/reactos/subsystems/win32/win32k/objects/coord.c index d6a8b888aaa..ea37b6a4b40 100644 --- a/reactos/subsystems/win32/win32k/objects/coord.c +++ b/reactos/subsystems/win32/win32k/objects/coord.c @@ -258,6 +258,43 @@ IntGetGraphicsMode ( PDC dc ) return dc->w.GraphicsMode; } +BOOL +FASTCALL +IntGdiModifyWorldTransform(PDC pDc, + CONST LPXFORM lpXForm, + DWORD Mode) +{ + ASSERT(pDc && lpXForm); + + switch(Mode) + { + case MWT_IDENTITY: + pDc->w.xformWorld2Wnd.eM11 = 1.0f; + pDc->w.xformWorld2Wnd.eM12 = 0.0f; + pDc->w.xformWorld2Wnd.eM21 = 0.0f; + pDc->w.xformWorld2Wnd.eM22 = 1.0f; + pDc->w.xformWorld2Wnd.eDx = 0.0f; + pDc->w.xformWorld2Wnd.eDy = 0.0f; + break; + + case MWT_LEFTMULTIPLY: + IntGdiCombineTransform(&pDc->w.xformWorld2Wnd, lpXForm, &pDc->w.xformWorld2Wnd ); + break; + + case MWT_RIGHTMULTIPLY: + IntGdiCombineTransform(&pDc->w.xformWorld2Wnd, &pDc->w.xformWorld2Wnd, lpXForm); + break; + + default: + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + DC_UpdateXforms(pDc); + DC_UnlockDc(pDc); + return TRUE; +} + int STDCALL NtGdiGetGraphicsMode ( HDC hDC ) @@ -438,14 +475,20 @@ NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count ) BOOL STDCALL -NtGdiModifyWorldTransform(HDC hDC, +NtGdiModifyWorldTransform(HDC hDC, CONST LPXFORM UnsafeXForm, - DWORD Mode) + DWORD Mode) { PDC dc; - XFORM SafeXForm = {0}; - NTSTATUS Status = STATUS_SUCCESS; + XFORM SafeXForm; + BOOL Ret = FALSE; + if (!UnsafeXForm) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + dc = DC_LockDc(hDC); if (!dc) { @@ -453,61 +496,21 @@ NtGdiModifyWorldTransform(HDC hDC, return FALSE; } - if (!UnsafeXForm) - { - DC_UnlockDc(dc); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return FALSE; - } - _SEH_TRY { - ProbeForRead(UnsafeXForm, - sizeof(XFORM), - 1); - SafeXForm = *UnsafeXForm; + ProbeForRead(UnsafeXForm, sizeof(XFORM), 1); + RtlCopyMemory(&SafeXForm, UnsafeXForm, sizeof(XFORM)); + + Ret = IntGdiModifyWorldTransform(dc, &SafeXForm, Mode); } _SEH_HANDLE { - Status = _SEH_GetExceptionCode(); + SetLastNtError(_SEH_GetExceptionCode()); } _SEH_END; - if(!NT_SUCCESS(Status)) - { - DC_UnlockDc(dc); - SetLastNtError(Status); - return FALSE; - } - - switch(Mode) - { - case MWT_IDENTITY: - dc->w.xformWorld2Wnd.eM11 = 1.0f; - dc->w.xformWorld2Wnd.eM12 = 0.0f; - dc->w.xformWorld2Wnd.eM21 = 0.0f; - dc->w.xformWorld2Wnd.eM22 = 1.0f; - dc->w.xformWorld2Wnd.eDx = 0.0f; - dc->w.xformWorld2Wnd.eDy = 0.0f; - break; - - case MWT_LEFTMULTIPLY: - IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &SafeXForm, &dc->w.xformWorld2Wnd ); - break; - - case MWT_RIGHTMULTIPLY: - IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, &SafeXForm); - break; - - default: - DC_UnlockDc(dc); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return FALSE; - } - - DC_UpdateXforms(dc); - DC_UnlockDc(dc); - return TRUE; + DC_UnlockDc(dc); + return Ret; } BOOL From a2a7c9632ff9899d499e5324aa64a5fa18a833cc Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Wed, 13 Sep 2006 19:08:41 +0000 Subject: [PATCH 183/488] Greek keyboard layout changes by Apal See issue #1631 for more details. svn path=/trunk/; revision=24100 --- reactos/dll/keyboard/kbdhe/kbdhe.c | 89 ++++++++++++++++-------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/reactos/dll/keyboard/kbdhe/kbdhe.c b/reactos/dll/keyboard/kbdhe/kbdhe.c index 2552d583d0b..e5dfb52c2c5 100644 --- a/reactos/dll/keyboard/kbdhe/kbdhe.c +++ b/reactos/dll/keyboard/kbdhe/kbdhe.c @@ -2,7 +2,7 @@ * ReactOS Greek ASCII Keyboard layout * Copyright (C) 2005 ReactOS * License: LGPL, see: LGPL.txt - * author: Apostolos Alexiadis (Dj Apal®) + * author: Apostolos Alexiadis (Dj Apal®) * * Thanks to: http://www.barcodeman.com/altek/mule/scandoc.php * and http://win.tue.nl/~aeb/linux/kbd/scancodes-1.html @@ -36,7 +36,7 @@ ROSDATA USHORT scancode_to_vk[] = { /* Numbers Row */ /* - 00 - */ - /* 1 ... 2 ... 3 ... 4 ... */ + /* 1 ... 2 ... 3 ... 4 ... */ VK_EMPTY, VK_ESCAPE, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', @@ -45,14 +45,14 @@ ROSDATA USHORT scancode_to_vk[] = { /* First Letters Row */ VK_TAB, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', - 'I', 'O', 'P', + 'I', 'O', 'P', VK_OEM_4, VK_OEM_6, VK_RETURN, /* - 1d - */ /* Second Letters Row */ - VK_LCONTROL, + VK_LCONTROL, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', - 'L', VK_OEM_1, VK_OEM_7, VK_OEM_3, + 'L', VK_OEM_1, VK_OEM_7, VK_OEM_3, VK_LSHIFT, VK_OEM_5, /* - 2c - */ /* Third letters row */ @@ -62,15 +62,15 @@ ROSDATA USHORT scancode_to_vk[] = { /* - 37 - */ /* Bottom Row */ VK_MULTIPLY, VK_LMENU, VK_SPACE, VK_CAPITAL, - + /* - 3b - */ /* F-Keys */ - VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, + VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* - 45 - */ /* Locks */ - VK_NUMLOCK | KMEXT, - VK_SCROLL | KMULTI, + VK_NUMLOCK | KMEXT, + VK_SCROLL | KMULTI, /* - 47 - */ /* Number-Pad */ VK_HOME | KNUMS, VK_UP | KNUMS, VK_PRIOR | KNUMS, VK_SUBTRACT, @@ -86,11 +86,11 @@ ROSDATA USHORT scancode_to_vk[] = { /* - 59 - */ VK_CLEAR, VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* EREOF */ VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* ZOOM */ - VK_HELP, + VK_HELP, /* - 64 - */ /* Even more F-Keys (for example, NCR keyboards from the early 90's) */ VK_F13, VK_F14, VK_F15, VK_F16, VK_F17, VK_F18, VK_F19, VK_F20, - VK_F21, VK_F22, VK_F23, + VK_F21, VK_F22, VK_F23, /* - 6f - */ /* Not sure who uses these codes */ VK_EMPTY, VK_EMPTY, VK_EMPTY, @@ -179,32 +179,32 @@ ROSDATA VK_TO_WCHARS4 key_to_chars_4mod[] = { /* Normal, Shifted, Ctrl, C-S-x */ /* The alphabet */ - { 'A', CAPS, {'á', 'Á', 0x01, 0x01} }, - { 'B', CAPS, {'â', 'Â', 0x02, 0x02} }, - { 'C', CAPS, {'ř', 'Ř', 0x03, 0x03} }, - { 'D', CAPS, {'ä', 'Ä', 0x04, 0x04} }, - { 'E', CAPS, {'ĺ', 'Ĺ', 0x05, 0x05} }, - { 'F', CAPS, {'ö', 'Ö', 0x06, 0x06} }, - { 'G', CAPS, {'ă', 'Ă', 0x07, 0x07} }, - { 'H', CAPS, {'ç', 'Ç', 0x08, 0x08} }, - { 'I', CAPS, {'é', 'É', 0x09, 0x09} }, - { 'J', CAPS, {'î', 'Î', 0x0a, 0x0a} }, - { 'K', CAPS, {'ę', 'Ę', 0x0b, 0x0b} }, - { 'L', CAPS, {'ë', 'Ë', 0x0c, 0x0c} }, - { 'M', CAPS, {'ě', 'Ě', 0x0d, 0x0d} }, - { 'N', CAPS, {'í', 'Í', 0x0e, 0x0e} }, - { 'O', CAPS, {'ď', 'Ď', 0x0f, 0x0f} }, - { 'P', CAPS, {'đ', 'Đ', 0x10, 0x10} }, - { 'Q', CAPS, {';', ';', 0x11, 0x11} }, - { 'R', CAPS, {'ń', 'Ń', 0x12, 0x12} }, - { 'S', CAPS, {'ó', 'Ó', 0x13, 0x13} }, - { 'T', CAPS, {'ô', 'Ô', 0x14, 0x14} }, - { 'U', CAPS, {'č', 'Č', 0x15, 0x15} }, - { 'V', CAPS, {'ů', 'Ů', 0x16, 0x16} }, - { 'W', CAPS, {'ň', 'ň', 0x17, 0x17} }, - { 'X', CAPS, {'÷', '×', 0x18, 0x18} }, - { 'Y', CAPS, {'ő', 'Ő', 0x19, 0x19} }, - { 'Z', CAPS, {'ć', 'Ć', 0x1a, 0x1a} }, + { 'A', CAPS, {0x3B1, 0x391} }, + { 'B', CAPS, {0x3B2, 0x392} }, + { 'C', CAPS, {0x3C8, 0x3A8} }, + { 'D', CAPS, {0x3B4, 0x394} }, + { 'E', CAPS, {0x3B5, 0x395} }, + { 'F', CAPS, {0x3C6, 0x3A6} }, + { 'G', CAPS, {0x3B3, 0x393} }, + { 'H', CAPS, {0x3B7, 0x397} }, + { 'I', CAPS, {0x3B9, 0x399} }, + { 'J', CAPS, {0x3BE, 0x39E} }, + { 'K', CAPS, {0x3BA, 0x39A} }, + { 'L', CAPS, {0x3BB, 0x39B} }, + { 'M', CAPS, {0x3BC, 0x39C} }, + { 'N', CAPS, {0x3BD, 0x39D} }, + { 'O', CAPS, {0x3BF, 0x39F} }, + { 'P', CAPS, {0x3C0, 0x3A0} }, + { 'Q', CAPS, {';',';'} }, + { 'R', CAPS, {0x3C1, 0x3A1} }, + { 'S', CAPS, {0x3C3, 0x3A3} }, + { 'T', CAPS, {0x3C4, 0x3A4} }, + { 'U', CAPS, {0x3B8, 0x398} }, + { 'V', CAPS, {0x3C9, 0x3A9} }, + { 'W', CAPS, {0x3C2, 0x3C2} }, + { 'X', CAPS, {0x3C7, 0x3A7} }, + { 'Y', CAPS, {0x3C5, 0x3A5} }, + { 'Z', CAPS, {0x3B6, 0x396} }, /* Legacy Ascii generators */ { '2', NOCAPS, {'2', '@', WCH_NONE, 0} }, @@ -239,6 +239,15 @@ ROSDATA VK_TO_WCHAR_TABLE vk_to_wchar_master_table[] = { { 0,0,0 } }; +#define DEADTRANS(ch, accent, comp, flags) MAKELONG(ch, accent), comp, flags +ROSDATA DEADKEY deadkey[] = +{ + { DEADTRANS(0x03B1, 0x037E, 0x03AC, 0x0000) }, + { DEADTRANS(0x037E, 0x03B5, 0x03AD, 0x0000) }, + { 0, 0, 0} +}; + + ROSDATA VSC_LPWSTR key_names[] = { { 0x00, L"" }, { 0x01, L"Esc" }, @@ -325,13 +334,13 @@ ROSDATA VSC_LPWSTR extended_key_names[] = { ROSDATA KBDTABLES keyboard_layout_table = { /* modifier assignments */ &modifier_bits, - + /* character from vk tables */ vk_to_wchar_master_table, - + /* diacritical marks -- currently implemented by wine code */ /* English doesn't have any, anyway */ - NULL, + deadkey, /* Key names */ (VSC_LPWSTR *)key_names, From c440454c10b665b7cf85a49b5af3fafc92f04d5e Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 21:46:32 +0000 Subject: [PATCH 184/488] - Update Kernel Fun. svn path=/trunk/; revision=24101 --- reactos/ntoskrnl/KrnlFun.c | 5 +++-- reactos/ntoskrnl/include/internal/po.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index ccfa08ac410..e093cbca02b 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -32,9 +32,10 @@ // * Sanitize some context fields during conversions. // * Add DR macro/save and VM macro/save. // - FEATURES: -// * Use Queued Spinlocks for scheduling and dispatching. // * New optimized table-based tick-hashed timer implementation. -// * New Thread Scheduler based on XP. +// * New optimized dispatching logic/branching. +// * New Thread Scheduler based on 2003. +// * Proper Idle/Initial Thread setup and 2nd stage boot. // * Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion. // // Ex: diff --git a/reactos/ntoskrnl/include/internal/po.h b/reactos/ntoskrnl/include/internal/po.h index 98f1c3dc527..73e7dc04762 100644 --- a/reactos/ntoskrnl/include/internal/po.h +++ b/reactos/ntoskrnl/include/internal/po.h @@ -64,7 +64,7 @@ PopCleanupPowerState( ); NTSTATUS -CALLBACK +NTAPI PopAddRemoveSysCapsCallback( IN PVOID NotificationStructure, IN PVOID Context From d53352c6779576725e93fac8d65288a40869e891 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 14 Sep 2006 03:49:20 +0000 Subject: [PATCH 185/488] - Implement KiUnlinkThread to unlink a thread from its wait blocks, handle queue and timer activation/removal. - Don't play with priorities in KiAbortWaitThread anymore, since we'll soon support Win2003 delayed "adjust increment" functionality, so that the code is not repeated many times. - Rename KiAbortWaitThread to KiUnwaitThread, make it use KiUnlinkThread and delayed adjustment. - Implement KxUnwaitThread and KxUnwaitThreadForEvent, optimized versions of KiWaitTest that can be used in special circumstances (notification events, thread termination, process signalling). - Optimize KeSetEvent by handling signaled notification events without acquiring the dispatcher lock, and by using new inlined routines described above. - Reimplement KeSetEventBoostPriority properly to actually do boosting. - Fixup KeRundownQueue with a more typical/proper LIST_ENTRY loop. - Let me know if you see regressions... svn path=/trunk/; revision=24102 --- reactos/ntoskrnl/include/internal/ke.h | 9 ++- reactos/ntoskrnl/include/internal/ke_x.h | 92 +++++++++++++++++++++++ reactos/ntoskrnl/ke/apc.c | 3 +- reactos/ntoskrnl/ke/event.c | 95 +++++++++++++++--------- reactos/ntoskrnl/ke/gate.c | 2 +- reactos/ntoskrnl/ke/process.c | 4 +- reactos/ntoskrnl/ke/queue.c | 21 ++++-- reactos/ntoskrnl/ke/thrdobj.c | 10 +-- reactos/ntoskrnl/ke/wait.c | 85 +++++---------------- 9 files changed, 201 insertions(+), 120 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index bd67ce1fd4e..5f422135bf5 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -455,6 +455,13 @@ KiDispatcherObjectWake( KPRIORITY increment ); +VOID +FASTCALL +KiUnlinkThread( + IN PKTHREAD Thread, + IN NTSTATUS WaitStatus +); + VOID NTAPI KeExpireTimers( @@ -474,7 +481,7 @@ KiTestAlert(VOID); VOID FASTCALL -KiAbortWaitThread( +KiUnwaitThread( IN PKTHREAD Thread, IN NTSTATUS WaitStatus, IN KPRIORITY Increment diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index c615c659563..9b3d8bffe6c 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -292,6 +292,98 @@ KiRecalculateDueTime(IN PLARGE_INTEGER OriginalDueTime, } \ } +// +// Unwaits a Thread +// +FORCEINLINE +VOID +KxUnwaitThread(IN DISPATCHER_HEADER *Object, + IN KPRIORITY Increment) +{ + PLIST_ENTRY WaitEntry, WaitList; + PKWAIT_BLOCK CurrentWaitBlock; + PKTHREAD WaitThread; + ULONG WaitKey; + + /* Loop the Wait Entries */ + WaitList = &Object->WaitListHead; + WaitEntry = WaitList->Flink; + do + { + /* Get the current wait block */ + CurrentWaitBlock = CONTAINING_RECORD(WaitEntry, + KWAIT_BLOCK, + WaitListEntry); + + /* Get the waiting thread */ + WaitThread = CurrentWaitBlock->Thread; + + /* Check the current Wait Mode */ + if (CurrentWaitBlock->WaitType == WaitAny) + { + /* Use the actual wait key */ + WaitKey = CurrentWaitBlock->WaitKey; + } + else + { + /* Otherwise, use STATUS_KERNEL_APC */ + WaitKey = STATUS_KERNEL_APC; + } + + /* Unwait the thread */ + KiUnwaitThread(WaitThread, WaitKey, Increment); + + /* Next entry */ + WaitEntry = WaitList->Flink; + } while (WaitEntry != WaitList); +} + +// +// Unwaits a Thread waiting on an event +// +FORCEINLINE +VOID +KxUnwaitThreadForEvent(IN PKEVENT Event, + IN KPRIORITY Increment) +{ + PLIST_ENTRY WaitEntry, WaitList; + PKWAIT_BLOCK CurrentWaitBlock; + PKTHREAD WaitThread; + + /* Loop the Wait Entries */ + WaitList = &Event->Header.WaitListHead; + WaitEntry = WaitList->Flink; + do + { + /* Get the current wait block */ + CurrentWaitBlock = CONTAINING_RECORD(WaitEntry, + KWAIT_BLOCK, + WaitListEntry); + + /* Get the waiting thread */ + WaitThread = CurrentWaitBlock->Thread; + + /* Check the current Wait Mode */ + if (CurrentWaitBlock->WaitType == WaitAny) + { + /* Un-signal it */ + Event->Header.SignalState = 0; + + /* Un-signal the event and unwait the thread */ + KiUnwaitThread(WaitThread, CurrentWaitBlock->WaitKey, Increment); + break; + } + else + { + /* Unwait the thread with STATUS_KERNEL_APC */ + KiUnwaitThread(WaitThread, STATUS_KERNEL_APC, Increment); + } + + /* Next entry */ + WaitEntry = WaitList->Flink; + } while (WaitEntry != WaitList); +} + // // Spinlock Acquisition at IRQL >= DISPATCH_LEVEL // diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 00a0851616e..6f198042b8f 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -239,7 +239,7 @@ KiInsertQueueApc(IN PKAPC Apc, /* Wake up the thread */ Unwait: - KiAbortWaitThread(Thread, Status, PriorityBoost); + KiUnwaitThread(Thread, Status, PriorityBoost); } else { @@ -978,3 +978,4 @@ KeAreAllApcsDisabled(VOID) (KeGetCurrentIrql() >= APC_LEVEL)) ? TRUE : FALSE; } + diff --git a/reactos/ntoskrnl/ke/event.c b/reactos/ntoskrnl/ke/event.c index e73f7e1cccf..23b3b33fa25 100644 --- a/reactos/ntoskrnl/ke/event.c +++ b/reactos/ntoskrnl/ke/event.c @@ -166,19 +166,29 @@ KeSetEvent(IN PKEVENT Event, ASSERT_EVENT(Event); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + /* + * Check if this is an signaled notification event without an upcoming wait. + * In this case, we can immediately return TRUE, without locking. + */ + if ((Event->Header.Type == NotificationEvent) && + (Event->Header.SignalState == 1) && + !(Wait)) + { + /* Return the signal state (TRUE/Signalled) */ + return TRUE; + } + /* Lock the Dispathcer Database */ OldIrql = KiAcquireDispatcherLock(); /* Save the Previous State */ PreviousState = Event->Header.SignalState; - /* Check if we have stuff in the Wait Queue */ - if (IsListEmpty(&Event->Header.WaitListHead)) - { - /* Set the Event to Signaled */ - Event->Header.SignalState = 1; - } - else + /* Set the Event to Signaled */ + Event->Header.SignalState = 1; + + /* Check if the event just became signaled now, and it has waiters */ + if (!(PreviousState) && !(IsListEmpty(&Event->Header.WaitListHead))) { /* Get the Wait Block */ WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink, @@ -186,22 +196,15 @@ KeSetEvent(IN PKEVENT Event, WaitListEntry); /* Check the type of event */ - if ((Event->Header.Type == NotificationEvent) || (WaitBlock->WaitType == WaitAll)) + if (Event->Header.Type == NotificationEvent) { - /* Check if it wasn't signaled */ - if (!PreviousState) - { - /* We must do a full wait satisfaction */ - Event->Header.SignalState = 1; - KiWaitTest(&Event->Header, Increment); - } + /* Unwait the thread */ + KxUnwaitThread(&Event->Header, Increment); } else { - /* We can satisfy wait simply by waking the thread */ - KiAbortWaitThread(WaitBlock->Thread, - WaitBlock->WaitKey, - Increment); + /* Otherwise unwait the thread and unsignal the event */ + KxUnwaitThreadForEvent(Event, Increment); } } @@ -229,38 +232,60 @@ KeSetEvent(IN PKEVENT Event, VOID NTAPI KeSetEventBoostPriority(IN PKEVENT Event, - IN PKTHREAD *Thread OPTIONAL) + IN PKTHREAD *WaitingThread OPTIONAL) { - PKTHREAD WaitingThread; KIRQL OldIrql; + PKWAIT_BLOCK WaitBlock; + PKTHREAD Thread = KeGetCurrentThread(), WaitThread; ASSERT_EVENT(Event); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - // - // FIXME: This is half-broken, there's no boosting! - // - /* Acquire Dispatcher Database Lock */ OldIrql = KiAcquireDispatcherLock(); - /* If our wait list is empty, then signal the event and return */ + /* Check if the list is empty */ if (IsListEmpty(&Event->Header.WaitListHead)) { + /* Set the Event to Signaled */ Event->Header.SignalState = 1; + + /* Return */ + KiReleaseDispatcherLock(OldIrql); + return; + } + + /* Get the Wait Block */ + WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink, + KWAIT_BLOCK, + WaitListEntry); + + /* Check if this is a WaitAll */ + if (WaitBlock->WaitType == WaitAll) + { + /* Set the Event to Signaled */ + Event->Header.SignalState = 1; + + /* Unwait the thread and unsignal the event */ + KxUnwaitThreadForEvent(Event, EVENT_INCREMENT); } else { - /* Get the waiting thread */ - WaitingThread = CONTAINING_RECORD(Event->Header.WaitListHead.Flink, - KWAIT_BLOCK, - WaitListEntry)->Thread; + /* Return waiting thread to caller */ + WaitThread = WaitBlock->Thread; + if (WaitingThread) *WaitingThread = WaitThread; - /* Return it to caller if requested */ - if (Thread) *Thread = WaitingThread; + /* Calculate new priority */ + Thread->Priority = KiComputeNewPriority(Thread); - /* Reset the Quantum and Unwait the Thread */ - WaitingThread->Quantum = WaitingThread->QuantumReset; - KiAbortWaitThread(WaitingThread, STATUS_SUCCESS, EVENT_INCREMENT); + /* Unlink the waiting thread */ + KiUnlinkThread(WaitThread, STATUS_WAIT_0); + + /* Request priority boosting */ + WaitThread->AdjustIncrement = Thread->Priority; + WaitThread->AdjustReason = 2; + + /* Ready the thread */ + KiReadyThread(WaitThread); } /* Release the Dispatcher Database Lock */ diff --git a/reactos/ntoskrnl/ke/gate.c b/reactos/ntoskrnl/ke/gate.c index c625c6c5dde..f2cd3726d50 100644 --- a/reactos/ntoskrnl/ke/gate.c +++ b/reactos/ntoskrnl/ke/gate.c @@ -142,7 +142,7 @@ KeSignalGateBoostPriority(IN PKGATE Gate) if (WaitThread->Queue) WaitThread->Queue->CurrentCount++; /* FIXME: This isn't really correct!!! */ - KiAbortWaitThread(WaitThread, WaitStatus, EVENT_INCREMENT); + KiUnwaitThread(WaitThread, WaitStatus, EVENT_INCREMENT); } /* Exit the dispatcher */ diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index de6cd07ed58..48abeafed9c 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -208,8 +208,8 @@ KeSetProcess(IN PKPROCESS Process, if (!(OldState) && !(IsListEmpty(&Process->Header.WaitListHead))) { - /* Satisfy waits */ - KiWaitTest((PVOID)Process, Increment); + /* Unwait the threads */ + KxUnwaitThread(&Process->Header, Increment); } /* Release Dispatcher Database */ diff --git a/reactos/ntoskrnl/ke/queue.c b/reactos/ntoskrnl/ke/queue.c index 245fad872f0..91d9efed4d6 100644 --- a/reactos/ntoskrnl/ke/queue.c +++ b/reactos/ntoskrnl/ke/queue.c @@ -57,7 +57,7 @@ KiWakeQueue(IN PKQUEUE Queue) KWAIT_BLOCK, WaitListEntry); Thread = WaitBlock->Thread; - KiAbortWaitThread(Thread, (NTSTATUS)QueueEntry, IO_NO_INCREMENT); + KiUnwaitThread(Thread, (NTSTATUS)QueueEntry, IO_NO_INCREMENT); } } } @@ -401,7 +401,7 @@ KeRemoveQueue(IN PKQUEUE Queue, if (!KiInsertTimer(Timer, *Timeout)) { /* FIXME */ - DPRINT1("If you see thie message contact Alex ASAP\n"); + DPRINT1("If you see this message contact Alex ASAP\n"); KEBUGCHECK(0); } @@ -469,7 +469,7 @@ PLIST_ENTRY NTAPI KeRundownQueue(IN PKQUEUE Queue) { - PLIST_ENTRY EnumEntry; + PLIST_ENTRY ListHead, NextEntry; PLIST_ENTRY FirstEntry = NULL; PKTHREAD Thread; KIRQL OldIrql; @@ -488,16 +488,21 @@ KeRundownQueue(IN PKQUEUE Queue) } /* Unlink threads and clear their Thread->Queue */ - while (!IsListEmpty(&Queue->ThreadListHead)) + ListHead = &Queue->ThreadListHead; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) { - /* Get the Entry and Remove it */ - EnumEntry = RemoveHeadList(&Queue->ThreadListHead); - /* Get the Entry's Thread */ - Thread = CONTAINING_RECORD(EnumEntry, KTHREAD, QueueListEntry); + Thread = CONTAINING_RECORD(NextEntry, KTHREAD, QueueListEntry); /* Kill its Queue */ Thread->Queue = NULL; + + /* Remove this entry */ + RemoveEntryList(NextEntry); + + /* Get the next entry */ + NextEntry = NextEntry->Flink; } /* Release the lock and return */ diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 3841656a4a2..33a94239e1a 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -100,7 +100,7 @@ KeAlertResumeThread(IN PKTHREAD Thread) if ((Thread->State == Waiting) && (Thread->Alertable)) { /* Abort the wait */ - KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); + KiUnwaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); } else { @@ -157,7 +157,7 @@ KeAlertThread(IN PKTHREAD Thread, (Thread->Alertable)) { /* Abort the wait to alert the thread */ - KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); + KiUnwaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT); } else { @@ -1311,10 +1311,10 @@ KeTerminateThread(IN KPRIORITY Increment) /* Signal the thread */ Thread->DispatcherHeader.SignalState = TRUE; - if (IsListEmpty(&Thread->DispatcherHeader.WaitListHead) != TRUE) + if (!IsListEmpty(&Thread->DispatcherHeader.WaitListHead)) { - /* Satisfy waits */ - KiWaitTest((PVOID)Thread, Increment); + /* Unwait the threads */ + KxUnwaitThread(&Thread->DispatcherHeader, Increment); } /* Remove the thread from the list */ diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 91935a2d657..950b9d475c4 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -13,10 +13,6 @@ #define NDEBUG #include -/* GLOBALS ******************************************************************/ - -KSPIN_LOCK DispatcherDatabaseLock; - /* PRIVATE FUNCTIONS *********************************************************/ VOID @@ -110,7 +106,7 @@ KiWaitTest(IN PVOID ObjectPointer, } /* All waits satisfied, unwait the thread */ - KiAbortWaitThread(WaitThread, CurrentWaitBlock->WaitKey, Increment); + KiUnwaitThread(WaitThread, CurrentWaitBlock->WaitKey, Increment); SkipUnwait: /* Next entry */ @@ -118,16 +114,13 @@ SkipUnwait: } } -/* Must be called with the dispatcher lock held */ VOID FASTCALL -KiAbortWaitThread(IN PKTHREAD Thread, - IN NTSTATUS WaitStatus, - IN KPRIORITY Increment) +KiUnlinkThread(IN PKTHREAD Thread, + IN NTSTATUS WaitStatus) { PKWAIT_BLOCK WaitBlock; PKTIMER Timer; - LONG NewPriority; /* Update wait status */ Thread->WaitStatus |= WaitStatus; @@ -158,64 +151,22 @@ KiAbortWaitThread(IN PKTHREAD Thread, /* Increment the Queue's active threads */ if (Thread->Queue) Thread->Queue->CurrentCount++; +} - /* Check if this is a non-RT thread */ - if (Thread->Priority < LOW_REALTIME_PRIORITY) - { - /* Check if boosting is enabled and we can boost */ - if (!(Thread->DisableBoost) && !(Thread->PriorityDecrement)) - { - /* We can boost, so calculate the new priority */ - NewPriority = Thread->BasePriority + Increment; - if (NewPriority > Thread->Priority) - { - /* Make sure the new priority wouldn't push the thread to RT */ - if (NewPriority >= LOW_REALTIME_PRIORITY) - { - /* Set it just before the RT zone */ - Thread->Priority = LOW_REALTIME_PRIORITY - 1; - } - else - { - /* Otherwise, set our calculated priority */ - Thread->Priority = NewPriority; - } - } - } +/* Must be called with the dispatcher lock held */ +VOID +FASTCALL +KiUnwaitThread(IN PKTHREAD Thread, + IN NTSTATUS WaitStatus, + IN KPRIORITY Increment) +{ + /* Unlink the thread */ + KiUnlinkThread(Thread, WaitStatus); - /* Check if this is a high-priority thread */ - if (Thread->BasePriority >= 14) - { - /* It is, simply reset the quantum */ - Thread->Quantum = Thread->QuantumReset; - } - else - { - /* Otherwise, decrease quantum */ - Thread->Quantum--; - if (Thread->Quantum <= 0) - { - /* We've went below 0, reset it */ - Thread->Quantum = Thread->QuantumReset; - - /* Apply per-quantum priority decrement */ - Thread->Priority -= (Thread->PriorityDecrement + 1); - if (Thread->Priority < Thread->BasePriority) - { - /* We've went too low, reset it */ - Thread->Priority = Thread->BasePriority; - } - - /* Delete per-quantum decrement */ - Thread->PriorityDecrement = 0; - } - } - } - else - { - /* For real time threads, just reset the quantum */ - Thread->Quantum = Thread->QuantumReset; - } + /* Tell the scheduler do to the increment when it readies the thread */ + ASSERT(Increment >= 0); + Thread->AdjustIncrement = (SCHAR)Increment; + Thread->AdjustReason = 1; /* Reschedule the Thread */ KiReadyThread(Thread); @@ -794,7 +745,7 @@ KeWaitForMultipleObjects(IN ULONG Count, WaitBlock->Object = CurrentObject; WaitBlock->Thread = CurrentThread; WaitBlock->WaitKey = (USHORT)WaitIndex; - WaitBlock->WaitType = (USHORT)WaitType; + WaitBlock->WaitType = (UCHAR)WaitType; WaitBlock->NextWaitBlock = WaitBlock + 1; /* Move to the next Wait Block */ From 20425875ce380811ece9841a9fc83fa52ec2c96e Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 14 Sep 2006 05:53:51 +0000 Subject: [PATCH 186/488] - Implement KiAcquireDispatcherObject, KiReleaseDispatcherObject, used on SMP for dispatcher objects which use the volatile long member in the dispatcher header (such as gates). - Implement KiTryThreadLock which tries to acquire the lock but exits if it can't, isntead of looping. - Re-factor KeWaitForGate to make it SMP-safe by acquiring various locks when required. - Fixed up KeSignalGateBoostPriority so it can also be SMP-safe, and also fix what exactly happens when the gate is signaled (directly make the other thread ready instead of doing a KiUnwaitThread on it). - Split KxAcquireSpinLock/KxReleaseSpinLock into SMP vs UP like the other routines. svn path=/trunk/; revision=24103 --- reactos/include/ndk/ketypes.h | 1 + reactos/ntoskrnl/include/internal/ke_x.h | 186 +++++++++++++++++------ reactos/ntoskrnl/ke/gate.c | 185 +++++++++++++++------- 3 files changed, 275 insertions(+), 97 deletions(-) diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index 07a1cabbdfd..4df317882be 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -43,6 +43,7 @@ Author: // Object Type Mask for Kernel Dispatcher Objects // #define KOBJECT_TYPE_MASK 0x7F +#define KOBJECT_LOCK_BIT 0x80 // // Dispatcher Priority increments diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 9b3d8bffe6c..c70eb871396 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -384,45 +384,16 @@ KxUnwaitThreadForEvent(IN PKEVENT Event, } while (WaitEntry != WaitList); } +#ifndef _CONFIG_SMP // -// Spinlock Acquisition at IRQL >= DISPATCH_LEVEL +// Spinlock Acquire at IRQL >= DISPATCH_LEVEL // FORCEINLINE VOID KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock) { -#ifdef CONFIG_SMP - for (;;) - { - /* Try to acquire it */ - if (InterlockedBitTestAndSet((PLONG)SpinLock, 0)) - { - /* Value changed... wait until it's locked */ - while (*(volatile KSPIN_LOCK *)SpinLock == 1) - { -#ifdef DBG - /* On debug builds, we use a much slower but useful routine */ - Kii386SpinOnSpinLock(SpinLock, 5); -#else - /* Otherwise, just yield and keep looping */ - YieldProcessor(); -#endif - } - } - else - { -#ifdef DBG - /* On debug builds, we OR in the KTHREAD */ - *SpinLock = KeGetCurrentThread() | 1; -#endif - /* All is well, break out */ - break; - } - } -#else /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */ UNREFERENCED_PARAMETER(SpinLock); -#endif } // @@ -432,27 +403,30 @@ FORCEINLINE VOID KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock) { -#ifdef CONFIG_SMP -#ifdef DBG - /* Make sure that the threads match */ - if ((KeGetCurrentThread() | 1) != *SpinLock) - { - /* They don't, bugcheck */ - KeBugCheckEx(SPIN_LOCK_NOT_OWNED, SpinLock, 0, 0, 0); - } -#endif - /* Clear the lock */ - InterlockedAnd(SpinLock, 0); -#else /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */ UNREFERENCED_PARAMETER(SpinLock); -#endif } // -// Thread Scheduling Routines +// This routine protects against multiple CPU acquires, it's meaningless on UP. // -#ifndef _CONFIG_SMP +VOID +FORCEINLINE +KiAcquireDispatcherObject(IN DISPATCHER_HEADER* Object) +{ + UNREFERENCED_PARAMETER(Object); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +VOID +FORCEINLINE +KiReleaseDispatcherObject(IN DISPATCHER_HEADER* Object) +{ + UNREFERENCED_PARAMETER(Object); +} + KIRQL FORCEINLINE KiAcquireDispatcherLock(VOID) @@ -560,6 +534,17 @@ KiReleaseThreadLock(IN PKTHREAD Thread) UNREFERENCED_PARAMETER(Thread); } +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +BOOLEAN +KiTryThreadLock(IN PKTHREAD Thread) +{ + UNREFERENCED_PARAMETER(Thread); + return FALSE; +} + FORCEINLINE VOID KiCheckDeferredReadyList(IN PKPRCB Prcb) @@ -597,6 +582,98 @@ KiRequestApcInterrupt(IN BOOLEAN NeedApc, #else +// +// Spinlock Acquisition at IRQL >= DISPATCH_LEVEL +// +FORCEINLINE +VOID +KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock) +{ + for (;;) + { + /* Try to acquire it */ + if (InterlockedBitTestAndSet((PLONG)SpinLock, 0)) + { + /* Value changed... wait until it's locked */ + while (*(volatile KSPIN_LOCK *)SpinLock == 1) + { +#ifdef DBG + /* On debug builds, we use a much slower but useful routine */ + Kii386SpinOnSpinLock(SpinLock, 5); +#else + /* Otherwise, just yield and keep looping */ + YieldProcessor(); +#endif + } + } + else + { +#ifdef DBG + /* On debug builds, we OR in the KTHREAD */ + *SpinLock = KeGetCurrentThread() | 1; +#endif + /* All is well, break out */ + break; + } + } +} + +// +// Spinlock Release at IRQL >= DISPATCH_LEVEL +// +FORCEINLINE +VOID +KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock) +{ +#ifdef DBG + /* Make sure that the threads match */ + if ((KeGetCurrentThread() | 1) != *SpinLock) + { + /* They don't, bugcheck */ + KeBugCheckEx(SPIN_LOCK_NOT_OWNED, SpinLock, 0, 0, 0); + } +#endif + /* Clear the lock */ + InterlockedAnd(SpinLock, 0); +} + +KIRQL +FORCEINLINE +KiAcquireDispatcherObject(IN DISPATCHER_HEADER* Object) +{ + LONG OldValue, NewValue; + + /* Make sure we're at a safe level to touch the lock */ + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); + + /* Start acquire loop */ + do + { + /* Loop until the other CPU releases it */ + while ((UCHAR)Object->Lock & KOBJECT_LOCK_BIT) + { + /* Let the CPU know that this is a loop */ + YieldProcessor(); + }; + + /* Try acquiring the lock now */ + NewValue = InterlockedCompareExchange(&Object->Lock, + OldValue | KOBJECT_LOCK_BIT, + OldValue); + } while (NewValue != OldValue); +} + +KIRQL +FORCEINLINE +KiReleaseDispatcherObject(IN DISPATCHER_HEADER* Object) +{ + /* Make sure we're at a safe level to touch the lock */ + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); + + /* Release it */ + InterlockedAnd(&Object->Lock, ~KOBJECT_LOCK_BIT); +} + KIRQL FORCEINLINE KiAcquireDispatcherLock(VOID) @@ -753,6 +830,23 @@ KiReleaseThreadLock(IN PKTHREAD Thread) InterlockedAnd(&Thread->ThreadLock, 0); } +FORCEINLINE +BOOLEAN +KiTryThreadLock(IN PKTHREAD Thread) +{ + LONG Value; + + /* If the lock isn't acquired, return false */ + if (!Thread->ThreadLock) return FALSE; + + /* Otherwise, try to acquire it and check the result */ + Value = 1; + Value = InterlockedExchange(&Thread->ThreadLock, &Value); + + /* Return the lock state */ + return (Value == TRUE); +} + FORCEINLINE VOID KiCheckDeferredReadyList(IN PKPRCB Prcb) diff --git a/reactos/ntoskrnl/ke/gate.c b/reactos/ntoskrnl/ke/gate.c index f2cd3726d50..a8dab73d0b0 100644 --- a/reactos/ntoskrnl/ke/gate.c +++ b/reactos/ntoskrnl/ke/gate.c @@ -33,21 +33,23 @@ KeWaitForGate(IN PKGATE Gate, IN KPROCESSOR_MODE WaitMode) { KLOCK_QUEUE_HANDLE ApcLock; - PKTHREAD CurrentThread = KeGetCurrentThread(); + PKTHREAD Thread = KeGetCurrentThread(); PKWAIT_BLOCK GateWaitBlock; NTSTATUS Status; + PKQUEUE Queue; ASSERT_GATE(Gate); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + ASSERT(FALSE); /* Start wait loop */ do { /* Acquire the APC lock */ - KiAcquireApcLock(CurrentThread, &ApcLock); + KiAcquireApcLock(Thread, &ApcLock); /* Check if a kernel APC is pending and we're below APC_LEVEL */ - if ((CurrentThread->ApcState.KernelApcPending) && - !(CurrentThread->SpecialApcDisable) && + if ((Thread->ApcState.KernelApcPending) && + !(Thread->SpecialApcDisable) && (ApcLock.OldIrql < APC_LEVEL)) { /* Release the lock, this will fire the APC */ @@ -55,41 +57,71 @@ KeWaitForGate(IN PKGATE Gate, } else { + /* Check if we have a queue and lock the dispatcher if so */ + Queue = Thread->Queue; + if (Queue) KiAcquireDispatcherLockAtDpcLevel(); + + /* Lock the thread */ + KiAcquireThreadLock(Thread); + + /* Lock the gate */ + KiAcquireDispatcherObject(&Gate->Header); + /* Check if it's already signaled */ if (Gate->Header.SignalState) { /* Unsignal it */ Gate->Header.SignalState = 0; + /* Release the gate and thread locks */ + KiReleaseDispatcherObject(&Gate->Header); + KiReleaseThreadLock(Thread); + /* Release the APC lock and return */ KiReleaseApcLock(&ApcLock); return; } /* Setup a Wait Block */ - GateWaitBlock = &CurrentThread->WaitBlock[0]; + GateWaitBlock = &Thread->WaitBlock[0]; GateWaitBlock->Object = (PVOID)Gate; - GateWaitBlock->Thread = CurrentThread; + GateWaitBlock->Thread = Thread; /* Set the Thread Wait Data */ - CurrentThread->WaitMode = WaitMode; - CurrentThread->WaitReason = WaitReason; - CurrentThread->WaitIrql = ApcLock.OldIrql; - CurrentThread->State = GateWait; - CurrentThread->GateObject = Gate; + Thread->WaitMode = WaitMode; + Thread->WaitReason = WaitReason; + Thread->WaitIrql = ApcLock.OldIrql; + Thread->State = GateWait; + Thread->GateObject = Gate; /* Insert into the Wait List */ InsertTailList(&Gate->Header.WaitListHead, &GateWaitBlock->WaitListEntry); - /* Handle Kernel Queues */ - if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue); + /* Release the gate lock */ + KiReleaseDispatcherObject(&Gate->Header); + + /* Set swap busy */ + KiSetThreadSwapBusy(Thread); + + /* Release the thread lock */ + KiReleaseThreadLock(Thread); + + /* Check if we had a queue */ + if (Queue) + { + /* Wake it up */ + KiWakeQueue(Queue); + + /* Release the dispatcher lock */ + KiReleaseDispatcherLockFromDpcLevel(); + } /* Release the APC lock but stay at DPC level */ KiReleaseApcLockFromDpcLevel(&ApcLock); /* Find a new thread to run */ - Status = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); + Status = KiSwapThread(Thread, KeGetCurrentPrcb()); /* Check if we were executing an APC */ if (Status != STATUS_KERNEL_APC) return; @@ -104,49 +136,100 @@ KeSignalGateBoostPriority(IN PKGATE Gate) PKTHREAD WaitThread; PKWAIT_BLOCK WaitBlock; KIRQL OldIrql; - NTSTATUS WaitStatus = STATUS_SUCCESS; ASSERT_GATE(Gate); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + ASSERT(FALSE); - /* Raise to synch level */ - OldIrql = KeRaiseIrqlToSynchLevel(); - - /* Make sure we're not already signaled or that the list is empty */ - if (Gate->Header.SignalState) + /* Start entry loop */ + for (;;) { - /* Lower IRQL and quit */ - KeLowerIrql(OldIrql); - return; + /* Raise to synch level */ + OldIrql = KeRaiseIrqlToSynchLevel(); + + /* Lock the gate */ + KiAcquireDispatcherObject(&Gate->Header); + + /* Make sure we're not already signaled or that the list is empty */ + if (Gate->Header.SignalState) + { + /* Lower IRQL and quit */ + KeLowerIrql(OldIrql); + return; + } + + /* Check if our wait list is empty */ + if (IsListEmpty(&Gate->Header.WaitListHead)) + { + /* It is, so signal the event */ + Gate->Header.SignalState = 1; + } + else + { + /* Get WaitBlock */ + WaitBlock = CONTAINING_RECORD(Gate->Header.WaitListHead.Flink, + KWAIT_BLOCK, + WaitListEntry); + + /* Get the Associated thread */ + WaitThread = WaitBlock->Thread; + + /* Check to see if the waiting thread is locked */ + if (!KiTryThreadLock(WaitThread)) + { + /* Unlock the gate */ + KiReleaseDispatcherObject(&Gate->Header); + + /* Lower IRQL and loop again */ + KeLowerIrql(OldIrql); + continue; + } + + /* Remove it */ + RemoveEntryList(&WaitBlock->WaitListEntry); + + /* Clear wait status */ + WaitThread->WaitStatus = 0; + + /* Set state and CPU */ + WaitThread->State = DeferredReady; + WaitThread->DeferredProcessor = KeGetCurrentPrcb()->Number; + + /* Release the gate lock */ + KiReleaseDispatcherObject(&Gate->Header); + + /* Release the thread lock */ + KiReleaseThreadLock(WaitThread); + + /* FIXME: Boosting */ + + /* Check if we have a queue */ + if (WaitThread->Queue) + { + /* Acquire the dispatcher lock */ + KiAcquireDispatcherLockAtDpcLevel(); + + /* Check if we still have one */ + if (WaitThread->Queue) + { + /* Increment active threads */ + WaitThread->Queue->CurrentCount++; + } + + /* Release lock */ + KiReleaseDispatcherLockFromDpcLevel(); + } + + /* Make the thread ready */ + KiReadyThread(WaitThread); + + /* Exit the dispatcher */ + KiExitDispatcher(OldIrql); + } } - /* Check if our wait list is empty */ - if (IsListEmpty(&Gate->Header.WaitListHead)) - { - /* It is, so signal the event */ - Gate->Header.SignalState = 1; - } - else - { - /* Get WaitBlock */ - WaitBlock = CONTAINING_RECORD(Gate->Header.WaitListHead.Flink, - KWAIT_BLOCK, - WaitListEntry); - - /* Remove it */ - RemoveEntryList(&WaitBlock->WaitListEntry); - - /* Get the Associated thread */ - WaitThread = WaitBlock->Thread; - - /* Increment the Queue's active threads */ - if (WaitThread->Queue) WaitThread->Queue->CurrentCount++; - - /* FIXME: This isn't really correct!!! */ - KiUnwaitThread(WaitThread, WaitStatus, EVENT_INCREMENT); - } - - /* Exit the dispatcher */ - KiExitDispatcher(OldIrql); + /* If we got here, then there's no rescheduling. */ + KiReleaseDispatcherObject(&Gate->Header); + KeLowerIrql(OldIrql); } /* EOF */ From dc1e8191503177344db900e25f35de3f728dc090 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 14 Sep 2006 07:43:20 +0000 Subject: [PATCH 187/488] Fixing two NULL pointer crash in win32k. I do not known if I done right in NtGdiRealizePalette step2, step2 is not tested. svn path=/trunk/; revision=24104 --- .../subsystems/win32/win32k/objects/color.c | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/color.c b/reactos/subsystems/win32/win32k/objects/color.c index 2eb0ce3a5c9..fea52d7385a 100644 --- a/reactos/subsystems/win32/win32k/objects/color.c +++ b/reactos/subsystems/win32/win32k/objects/color.c @@ -383,8 +383,32 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC) systemPalette = NtGdiGetStockObject((INT)DEFAULT_PALETTE); palGDI = PALETTE_LockPalette(dc->w.hPalette); palPtr = (PALOBJ*) palGDI; - /* FIXME - Handle palGDI == NULL!!!! */ + if (palGDI == NULL) + { + /* FIXME - Handle palGDI == NULL!!!! + we should not unlock dc and return 0 ?? + shall we create the palate ?? + */ + DC_UnlockDc(dc); + return 0; + } + + sysGDI = PALETTE_LockPalette(systemPalette); + sysPtr = (PALOBJ*) sysGDI; + + if (palGDI == NULL) + { + /* FIXME - Handle sysGDI == NULL!!!!! + we should not unlock dc and return 0 ?? + shall we create the palate ?? + */ + PALETTE_UnlockPalette(palGDI); + DC_UnlockDc(dc); + return 0; + } + + // Step 1: Create mapping of system palette\DC palette #ifndef NO_MAPPING realized = PALETTE_SetMapping(palPtr, 0, palGDI->NumColors, @@ -394,9 +418,7 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC) realized = 0; #endif - sysGDI = PALETTE_LockPalette(systemPalette); - sysPtr = (PALOBJ*) sysGDI; - /* FIXME - Handle sysGDI == NULL!!!!! */ + // Step 2: // The RealizePalette function modifies the palette for the device associated with the specified device context. If the @@ -404,8 +426,11 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC) // context is a display DC, the physical palette for that device is modified. if(dc->w.flags == DC_MEMORY) { - // Memory managed DC - DbgPrint("win32k: realizepalette unimplemented step 2 for DC_MEMORY"); + // Memory managed DC + ASSERT(sysGDI->NumColors <= 256); + success = ((GDIDEVICE *)dc->GDIDevice)->DriverFunctions.SetPalette( + dc->PDev, sysPtr, 0, 0, sysGDI->NumColors); + } else { if( ((GDIDEVICE *)dc->GDIDevice)->DriverFunctions.SetPalette) { From d64332beb253c78ec303888437d1de8d86f1f7f3 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 14 Sep 2006 08:20:50 +0000 Subject: [PATCH 188/488] Mikhail Zvyozdochkin: If I enter directly DNS server address in TCP/IP properties window, and after it open this window again, DNS server address is not retrieved to text field. Patch 1746 svn path=/trunk/; revision=24105 --- reactos/dll/cpl/ncpa/tcpip_properties.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/reactos/dll/cpl/ncpa/tcpip_properties.c b/reactos/dll/cpl/ncpa/tcpip_properties.c index 9cb905f6001..d2163435cd7 100644 --- a/reactos/dll/cpl/ncpa/tcpip_properties.c +++ b/reactos/dll/cpl/ncpa/tcpip_properties.c @@ -357,7 +357,7 @@ TCPIPPropertyPageProc(HWND Dlg, UINT uMsg, WPARAM wParam, LPARAM lParam) DlgData = (PTCPIP_PROPERTIES_DATA) GetWindowLongPtrW(Dlg, GWL_USERDATA); switch(uMsg) { - case WM_INITDIALOG: + case WM_INITDIALOG: Page = (LPPROPSHEETPAGEW) lParam; DlgData = (PTCPIP_PROPERTIES_DATA) Page->lParam; SetWindowLongPtrW(Dlg, GWL_USERDATA, Page->lParam); @@ -390,7 +390,12 @@ TCPIPPropertyPageProc(HWND Dlg, UINT uMsg, WPARAM wParam, LPARAM lParam) ntohl(DlgData->OldDns2)); } } - ManualDNS(Dlg, INADDR_NONE != DlgData->OldDns1, 0); + + if (DlgData->OldDhcpEnabled) + { + ManualDNS(Dlg, INADDR_NONE != DlgData->OldDns1, 0); + } + break; case WM_COMMAND: From 4309a525f488b67086e50d68cb02fabc255716f7 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 14 Sep 2006 08:27:08 +0000 Subject: [PATCH 189/488] Show the value, not the address in memory! (Thanks to Dmitry Philippov) svn path=/trunk/; revision=24106 --- reactos/regtests/winetests/ntdll/reg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/regtests/winetests/ntdll/reg.c b/reactos/regtests/winetests/ntdll/reg.c index 3a77fb88ea1..a2ee8d3c382 100755 --- a/reactos/regtests/winetests/ntdll/reg.c +++ b/reactos/regtests/winetests/ntdll/reg.c @@ -191,7 +191,7 @@ static NTSTATUS WINAPI QueryRoutine (IN PCWSTR ValueName, IN ULONG ValueType, IN case REG_BINARY: trace("ValueType: REG_BINARY\n"); - trace("ValueData: %d\n", (int)ValueData); + trace("ValueData: %d\n", *(unsigned int *)ValueData); break; case REG_SZ: @@ -211,7 +211,7 @@ static NTSTATUS WINAPI QueryRoutine (IN PCWSTR ValueName, IN ULONG ValueType, IN case REG_DWORD: trace("ValueType: REG_DWORD\n"); - trace("ValueData: %d\n", (int)ValueData); + trace("ValueData: %d\n", *(unsigned int *)ValueData); break; }; trace("ValueLength: %d\n", (int)ValueLength); From beb74a2356cbd5ada7fc53e2c6699ccc21d3422c Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 14 Sep 2006 09:10:13 +0000 Subject: [PATCH 190/488] remove entrypoint in rbuild files. 1. This change are right but binutils setting PE header flags wrongs for cpl/dll wrong 2. Remove entrypoint for cpl until this bug have been fixed in binutils. svn path=/trunk/; revision=24107 --- reactos/dll/cpl/access/access.rbuild | 2 +- reactos/dll/cpl/appwiz/appwiz.rbuild | 2 +- reactos/dll/cpl/desk/desk.rbuild | 2 +- reactos/dll/cpl/hdwwiz/hdwwiz.rbuild | 2 +- reactos/dll/cpl/intl/intl.rbuild | 2 +- reactos/dll/cpl/intl_new/intl.rbuild | 2 +- reactos/dll/cpl/main/main.rbuild | 2 +- reactos/dll/cpl/mmsys/mmsys.rbuild | 2 +- reactos/dll/cpl/ncpa/ncpa.rbuild | 2 +- reactos/dll/cpl/powercfg/powercfg.rbuild | 2 +- reactos/dll/cpl/sysdm/sysdm.rbuild | 2 +- reactos/dll/cpl/timedate/timedate.rbuild | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/reactos/dll/cpl/access/access.rbuild b/reactos/dll/cpl/access/access.rbuild index 21e401bb9f5..7af06170ade 100644 --- a/reactos/dll/cpl/access/access.rbuild +++ b/reactos/dll/cpl/access/access.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/appwiz/appwiz.rbuild b/reactos/dll/cpl/appwiz/appwiz.rbuild index 1146c2f2646..1b941d6b60f 100644 --- a/reactos/dll/cpl/appwiz/appwiz.rbuild +++ b/reactos/dll/cpl/appwiz/appwiz.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/desk/desk.rbuild b/reactos/dll/cpl/desk/desk.rbuild index 5452bc10b0e..2088c9950f1 100644 --- a/reactos/dll/cpl/desk/desk.rbuild +++ b/reactos/dll/cpl/desk/desk.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild b/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild index d3abf8b6114..7df49f5c2e2 100644 --- a/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild +++ b/reactos/dll/cpl/hdwwiz/hdwwiz.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/intl/intl.rbuild b/reactos/dll/cpl/intl/intl.rbuild index de434fd8594..6297017df86 100644 --- a/reactos/dll/cpl/intl/intl.rbuild +++ b/reactos/dll/cpl/intl/intl.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/intl_new/intl.rbuild b/reactos/dll/cpl/intl_new/intl.rbuild index bc48954992e..d3ee94d4d10 100644 --- a/reactos/dll/cpl/intl_new/intl.rbuild +++ b/reactos/dll/cpl/intl_new/intl.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/main/main.rbuild b/reactos/dll/cpl/main/main.rbuild index 8747fb38b9a..428eafacca3 100644 --- a/reactos/dll/cpl/main/main.rbuild +++ b/reactos/dll/cpl/main/main.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/mmsys/mmsys.rbuild b/reactos/dll/cpl/mmsys/mmsys.rbuild index 357f1b2b793..7db004c02b4 100644 --- a/reactos/dll/cpl/mmsys/mmsys.rbuild +++ b/reactos/dll/cpl/mmsys/mmsys.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/ncpa/ncpa.rbuild b/reactos/dll/cpl/ncpa/ncpa.rbuild index 32d766b5be2..35f865f96eb 100644 --- a/reactos/dll/cpl/ncpa/ncpa.rbuild +++ b/reactos/dll/cpl/ncpa/ncpa.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/powercfg/powercfg.rbuild b/reactos/dll/cpl/powercfg/powercfg.rbuild index e1d257bc141..9342c73c20c 100644 --- a/reactos/dll/cpl/powercfg/powercfg.rbuild +++ b/reactos/dll/cpl/powercfg/powercfg.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/cpl/sysdm/sysdm.rbuild b/reactos/dll/cpl/sysdm/sysdm.rbuild index 220551a854e..c5c5d2eeec1 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rbuild +++ b/reactos/dll/cpl/sysdm/sysdm.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/cpl/timedate/timedate.rbuild b/reactos/dll/cpl/timedate/timedate.rbuild index cc558a57f91..88f568ba90b 100644 --- a/reactos/dll/cpl/timedate/timedate.rbuild +++ b/reactos/dll/cpl/timedate/timedate.rbuild @@ -1,4 +1,4 @@ - + . From 74703ca40858db29caa56376c839f1653bdc2696 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 14 Sep 2006 12:13:32 +0000 Subject: [PATCH 191/488] - Implement KeReadyThread that wraps KiReadyThread so that \ps doesn't have to worry about dispatcher lock. - Make sure all a process's threads are ready if they're on the ready queue, during attachment. - Merge in KiReadyThread from scheduler code, with a small code change to keep working with ROS's scheduler lists instead. svn path=/trunk/; revision=24108 --- reactos/ntoskrnl/include/internal/ke.h | 6 +++++ reactos/ntoskrnl/ke/process.c | 21 +++++++++++++++- reactos/ntoskrnl/ke/thrdobj.c | 18 +++++++++++++ reactos/ntoskrnl/ke/thrdschd.c | 35 +++++++++++++++++++++++--- reactos/ntoskrnl/ps/psmgr.c | 5 +--- reactos/ntoskrnl/ps/thread.c | 17 +++---------- 6 files changed, 81 insertions(+), 21 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 5f422135bf5..622bf01a2de 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -186,6 +186,12 @@ KiSwapThread( IN PKPRCB Prcb ); +VOID +NTAPI +KeReadyThread( + IN PKTHREAD Thread +); + VOID NTAPI KiReadyThread(IN PKTHREAD Thread); diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index 48abeafed9c..dbb7fd8f1d4 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -58,6 +58,8 @@ KiAttachProcess(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE ApcLock, IN PRKAPC_STATE SavedApcState) { + PLIST_ENTRY ListHead, NextEntry; + PKTHREAD CurrentThread; ASSERT(Process != Thread->ApcState.Process); /* Increase Stack Count */ @@ -87,7 +89,24 @@ KiAttachProcess(IN PKTHREAD Thread, /* Check if the process is paged in */ if (Process->State == ProcessInMemory) { - /* FIXME: Scan the Ready Thread List once new scheduler is in */ + /* Scan the ready list */ + ListHead = &Process->ReadyListHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the thread */ + CurrentThread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry); + + /* Remove it */ + RemoveEntryList(NextEntry); + CurrentThread->ProcessReadyQueue = FALSE; + + /* Mark it ready */ + KiReadyThread(CurrentThread); + + /* Go to the next one */ + NextEntry = ListHead->Flink; + } /* Release dispatcher lock */ KiReleaseDispatcherLockFromDpcLevel(); diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 33a94239e1a..12dfb0a327c 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -80,6 +80,24 @@ KeQueryBasePriorityThread(IN PKTHREAD Thread) return BaseIncrement; } +VOID +NTAPI +KeReadyThread(IN PKTHREAD Thread) +{ + KIRQL OldIrql; + ASSERT_THREAD(Thread); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Lock the Dispatcher Database */ + OldIrql = KiAcquireDispatcherLock(); + + /* Make the thread ready */ + KiReadyThread(Thread); + + /* Unlock dispatcher database */ + KiReleaseDispatcherLock(OldIrql); +} + ULONG NTAPI KeAlertResumeThread(IN PKTHREAD Thread) diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c index 942530724f8..fea767e046a 100644 --- a/reactos/ntoskrnl/ke/thrdschd.c +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -213,9 +213,38 @@ VOID NTAPI KiReadyThread(IN PKTHREAD Thread) { - /* Makes a thread ready */ - Thread->State = Ready; - KiInsertIntoThreadList(Thread->Priority, Thread); + IN PKPROCESS Process = Thread->ApcState.Process; + + /* Check if the process is paged out */ + if (Process->State != ProcessInMemory) + { + /* We don't page out processes in ROS */ + ASSERT(FALSE); + } + else if (!Thread->KernelStackResident) + { + /* Increase the stack count */ + ASSERT(Process->StackCount != MAXULONG_PTR); + Process->StackCount++; + + /* Set the thread to transition */ + ASSERT(Thread->State != Transition); + Thread->State = Transition; + + /* The stack is always resident in ROS */ + ASSERT(FALSE); + } + else + { + /* Insert the thread on the deferred ready list */ +#if 0 + KiInsertDeferredReadyList(Thread); +#else + /* Insert the thread into the thread list */ + Thread->State = Ready; + KiInsertIntoThreadList(Thread->Priority, Thread); +#endif + } } VOID diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index 1346d98f11b..2e56ad58915 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -81,7 +81,6 @@ NTAPI PsInitHackThread(VOID) { PETHREAD IdleThread; - KIRQL oldIrql; IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); RtlZeroMemory(IdleThread, sizeof(ETHREAD)); @@ -97,9 +96,7 @@ PsInitHackThread(VOID) KERNEL_STACK_SIZE)); InitializeListHead(&IdleThread->IrpList); - oldIrql = KiAcquireDispatcherLock (); - KiReadyThread(&IdleThread->Tcb); - KiReleaseDispatcherLock(oldIrql); + KeReadyThread(&IdleThread->Tcb); KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 61e496565cf..c8ac1fc0655 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -156,7 +156,6 @@ PspCreateThread(OUT PHANDLE ThreadHandle, PEPROCESS Process; PETHREAD Thread; PTEB TebBase = NULL; - KIRQL OldIrql; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); NTSTATUS Status, AccessStatus; HANDLE_TABLE_ENTRY CidEntry; @@ -397,9 +396,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle, if (CreateSuspended) KeResumeThread(&Thread->Tcb); /* Dispatch thread */ - OldIrql = KiAcquireDispatcherLock (); - KiReadyThread(&Thread->Tcb); - KiReleaseDispatcherLock(OldIrql); + KeReadyThread(&Thread->Tcb); /* Dereference completely to kill it */ ObDereferenceObjectEx(Thread, 2); @@ -439,9 +436,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle, if (CreateSuspended) KeResumeThread(&Thread->Tcb); /* Dispatch thread */ - OldIrql = KiAcquireDispatcherLock (); - KiReadyThread(&Thread->Tcb); - KiReleaseDispatcherLock(OldIrql); + KeReadyThread(&Thread->Tcb); /* Dereference it, leaving only the keep-alive */ ObDereferenceObject(Thread); @@ -482,9 +477,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle, if (CreateSuspended) KeResumeThread(&Thread->Tcb); /* Dispatch thread */ - OldIrql = KiAcquireDispatcherLock (); - KiReadyThread(&Thread->Tcb); - KiReleaseDispatcherLock(OldIrql); + KeReadyThread(&Thread->Tcb); /* Dereference it, leaving only the keep-alive */ ObDereferenceObject(Thread); @@ -533,9 +526,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle, /* Dispatch thread */ PSREFTRACE(Thread); - OldIrql = KiAcquireDispatcherLock (); - KiReadyThread(&Thread->Tcb); - KiReleaseDispatcherLock(OldIrql); + KeReadyThread(&Thread->Tcb); /* Dereference it, leaving only the keep-alive */ ObDereferenceObject(Thread); From bb617c9ac99e5220b3faf7cbefa01e19e66050ce Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 14 Sep 2006 15:40:16 +0000 Subject: [PATCH 192/488] Sylvain Petreolle: Fix a typo in the code (palGDI -> sysGDI) svn path=/trunk/; revision=24109 --- reactos/subsystems/win32/win32k/objects/color.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/objects/color.c b/reactos/subsystems/win32/win32k/objects/color.c index fea52d7385a..5f5c06555ea 100644 --- a/reactos/subsystems/win32/win32k/objects/color.c +++ b/reactos/subsystems/win32/win32k/objects/color.c @@ -397,7 +397,7 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC) sysGDI = PALETTE_LockPalette(systemPalette); sysPtr = (PALOBJ*) sysGDI; - if (palGDI == NULL) + if (sysGDI == NULL) { /* FIXME - Handle sysGDI == NULL!!!!! we should not unlock dc and return 0 ?? From 1b75e6549e407e44c3a58e88c73c1da95b77d1cb Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 14 Sep 2006 15:48:02 +0000 Subject: [PATCH 193/488] - Converted some macros to inlined functions. - Modified KeDelayExecutionThread and KeWaitForSingleObject to be much simpler and readable, reducing some of the loops and continues, and 4th-level indentation. Also packed up common wait initialization at the beginning of the function, and into two new inline functions: KxDelayThreadWait and KxSingleThreadWait. No actual semantic changes, just re-ordering. - Rename KiUnwakeQueue to KiActivateWaiterQueue. svn path=/trunk/; revision=24110 --- reactos/ntoskrnl/include/internal/ke.h | 2 +- reactos/ntoskrnl/include/internal/ke_x.h | 198 ++++++++--- reactos/ntoskrnl/ke/gate.c | 2 +- reactos/ntoskrnl/ke/queue.c | 6 +- reactos/ntoskrnl/ke/thrdobj.c | 2 +- reactos/ntoskrnl/ke/wait.c | 419 ++++++++++------------- 6 files changed, 338 insertions(+), 291 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 622bf01a2de..f14a2657eb6 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -622,7 +622,7 @@ KeRemoveQueueApc(PKAPC Apc); VOID FASTCALL -KiWakeQueue(IN PKQUEUE Queue); +KiActivateWaiterQueue(IN PKQUEUE Queue); /* INITIALIZATION FUNCTIONS *************************************************/ diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index c70eb871396..0f35b072f56 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -219,21 +219,24 @@ KiRecalculateDueTime(IN PLARGE_INTEGER OriginalDueTime, // // Determines wether a thread should be added to the wait list // -#define KiCheckThreadStackSwap(WaitMode, Thread, Swappable) \ -{ \ - /* Check the required conditions */ \ - if ((WaitMode != KernelMode) && \ - (Thread->EnableStackSwap) && \ - (Thread->Priority >= (LOW_REALTIME_PRIORITY + 9))) \ - { \ - /* We are go for swap */ \ - Swappable = TRUE; \ - } \ - else \ - { \ - /* Don't swap the thread */ \ - Swappable = FALSE; \ - } \ +FORCEINLINE +BOOLEAN +KiCheckThreadStackSwap(IN PKTHREAD Thread, + IN KPROCESSOR_MODE WaitMode) +{ + /* Check the required conditions */ + if ((WaitMode != KernelMode) && + (Thread->EnableStackSwap) && + (Thread->Priority >= (LOW_REALTIME_PRIORITY + 9))) + { + /* We are go for swap */ + return TRUE; + } + else + { + /* Don't swap the thread */ + return FALSE; + } } // @@ -251,45 +254,134 @@ KiRecalculateDueTime(IN PLARGE_INTEGER OriginalDueTime, } // -// Rules for checking alertability: -// - For Alertable waits ONLY: -// * We don't wait and return STATUS_ALERTED if the thread is alerted -// in EITHER the specified wait mode OR in Kernel Mode. -// - For BOTH Alertable AND Non-Alertable waits: -// * We don't want and return STATUS_USER_APC if the User Mode APC list -// is not empty AND the wait mode is User Mode. +// Checks if a wait in progress should be interrupted by APCs or an alertable +// state. // -#define KiCheckAlertability() \ -{ \ - if (Alertable) \ - { \ - if (CurrentThread->Alerted[(int)WaitMode]) \ - { \ - CurrentThread->Alerted[(int)WaitMode] = FALSE; \ - WaitStatus = STATUS_ALERTED; \ - break; \ - } \ - else if ((WaitMode != KernelMode) && \ - (!IsListEmpty(&CurrentThread-> \ - ApcState.ApcListHead[UserMode]))) \ - { \ - CurrentThread->ApcState.UserApcPending = TRUE; \ - WaitStatus = STATUS_USER_APC; \ - break; \ - } \ - else if (CurrentThread->Alerted[KernelMode]) \ - { \ - CurrentThread->Alerted[KernelMode] = FALSE; \ - WaitStatus = STATUS_ALERTED; \ - break; \ - } \ - } \ - else if ((WaitMode != KernelMode) && \ - (CurrentThread->ApcState.UserApcPending)) \ - { \ - WaitStatus = STATUS_USER_APC; \ - break; \ - } \ +FORCEINLINE +NTSTATUS +KiCheckAlertability(IN PKTHREAD Thread, + IN BOOLEAN Alertable, + IN KPROCESSOR_MODE WaitMode) +{ + /* Check if the wait is alertable */ + if (Alertable) + { + /* It is, first check if the thread is alerted in this mode */ + if (Thread->Alerted[WaitMode]) + { + /* It is, so bail out of the wait */ + Thread->Alerted[WaitMode] = FALSE; + return STATUS_ALERTED; + } + else if ((WaitMode != KernelMode) && + (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) + { + /* It's isn't, but this is a user wait with queued user APCs */ + Thread->ApcState.UserApcPending = TRUE; + return STATUS_USER_APC; + } + else if (Thread->Alerted[KernelMode]) + { + /* It isn't that either, but we're alered in kernel mode */ + Thread->Alerted[KernelMode] = FALSE; + return STATUS_ALERTED; + } + } + else if ((WaitMode != KernelMode) && (Thread->ApcState.UserApcPending)) + { + /* Not alertable, but this is a user wait with pending user APCs */ + return STATUS_USER_APC; + } + + /* Otherwise, we're fine */ + return STATUS_WAIT_0; +} + +FORCEINLINE +BOOLEAN +KxDelayThreadWait(IN PKTHREAD Thread, + IN BOOLEAN Alertable, + IN KPROCESSOR_MODE WaitMode) +{ + BOOLEAN Swappable; + PKWAIT_BLOCK TimerBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK]; + + /* Setup the Wait Block */ + Thread->WaitBlockList = TimerBlock; + TimerBlock->NextWaitBlock = TimerBlock; + + /* Link the timer to this Wait Block */ + Thread->Timer.Header.WaitListHead.Flink = &TimerBlock->WaitListEntry; + Thread->Timer.Header.WaitListHead.Blink = &TimerBlock->WaitListEntry; + + /* Clear wait status */ + Thread->WaitStatus = STATUS_WAIT_0; + + /* Setup wait fields */ + Thread->Alertable = Alertable; + Thread->WaitReason = DelayExecution; + Thread->WaitMode = WaitMode; + + /* Check if we can swap the thread's stack */ + Thread->WaitListEntry.Flink = NULL; + Swappable = KiCheckThreadStackSwap(Thread, WaitMode); + + /* Set the wait time */ + Thread->WaitTime = ((PLARGE_INTEGER)&KeTickCount)->LowPart; + return Swappable; +} + +FORCEINLINE +BOOLEAN +KxSingleThreadWait(IN PKTHREAD Thread, + IN PKWAIT_BLOCK WaitBlock, + IN PVOID Object, + IN PLARGE_INTEGER Timeout, + IN BOOLEAN Alertable, + IN KWAIT_REASON WaitReason, + IN KPROCESSOR_MODE WaitMode) +{ + BOOLEAN Swappable; + PKWAIT_BLOCK TimerBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK]; + + /* Setup the Wait Block */ + Thread->WaitBlockList = WaitBlock; + WaitBlock->WaitKey = STATUS_WAIT_0; + WaitBlock->Object = Object; + WaitBlock->WaitType = WaitAny; + + /* Clear wait status */ + Thread->WaitStatus = STATUS_WAIT_0; + + /* Check if we have a timer */ + if (Timeout) + { + /* Pointer to timer block */ + WaitBlock->NextWaitBlock = TimerBlock; + TimerBlock->NextWaitBlock = WaitBlock; + + /* Link the timer to this Wait Block */ + Thread->Timer.Header.WaitListHead.Flink = &TimerBlock->WaitListEntry; + Thread->Timer.Header.WaitListHead.Blink = &TimerBlock->WaitListEntry; + } + else + { + /* No timer block, just ourselves */ + WaitBlock->NextWaitBlock = WaitBlock; + } + + /* Setup wait fields */ + Thread->Alertable = Alertable; + Thread->WaitReason = WaitReason; + Thread->WaitMode = WaitMode; + + /* Check if we can swap the thread's stack */ + Thread->WaitListEntry.Flink = NULL; + Swappable = KiCheckThreadStackSwap(Thread, WaitMode); + + /* Set the wait time */ + Thread->WaitTime = ((PLARGE_INTEGER)&KeTickCount)->LowPart; + return Swappable; } // diff --git a/reactos/ntoskrnl/ke/gate.c b/reactos/ntoskrnl/ke/gate.c index a8dab73d0b0..7357cfe9560 100644 --- a/reactos/ntoskrnl/ke/gate.c +++ b/reactos/ntoskrnl/ke/gate.c @@ -111,7 +111,7 @@ KeWaitForGate(IN PKGATE Gate, if (Queue) { /* Wake it up */ - KiWakeQueue(Queue); + KiActivateWaiterQueue(Queue); /* Release the dispatcher lock */ KiReleaseDispatcherLockFromDpcLevel(); diff --git a/reactos/ntoskrnl/ke/queue.c b/reactos/ntoskrnl/ke/queue.c index 91d9efed4d6..57e83f2a825 100644 --- a/reactos/ntoskrnl/ke/queue.c +++ b/reactos/ntoskrnl/ke/queue.c @@ -21,7 +21,7 @@ */ VOID FASTCALL -KiWakeQueue(IN PKQUEUE Queue) +KiActivateWaiterQueue(IN PKQUEUE Queue) { PLIST_ENTRY QueueEntry; PLIST_ENTRY WaitEntry; @@ -285,7 +285,7 @@ KeRemoveQueue(IN PKQUEUE Queue, RemoveEntryList(QueueEntry); /* Wake the queue */ - KiWakeQueue(PreviousQueue); + KiActivateWaiterQueue(PreviousQueue); } /* Insert in this new Queue */ @@ -359,7 +359,7 @@ KeRemoveQueue(IN PKQUEUE Queue, /* Check if we can swap the thread's stack */ Thread->WaitListEntry.Flink = NULL; - KiCheckThreadStackSwap(WaitMode, Thread, Swappable); + Swappable = KiCheckThreadStackSwap(Thread, WaitMode); /* We need to wait for the object... check for a timeout */ if (Timeout) diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 12dfb0a327c..e4c683b1a5b 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -1324,7 +1324,7 @@ KeTerminateThread(IN KPRIORITY Increment) { /* Remove it from the list, and handle the queue */ RemoveEntryList(&Thread->QueueListEntry); - KiWakeQueue(Thread->Queue); + KiActivateWaiterQueue(Thread->Queue); } /* Signal the thread */ diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 950b9d475c4..21bf97560c1 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -280,113 +280,88 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL) { - PKWAIT_BLOCK TimerWaitBlock; PKTIMER ThreadTimer; - PKTHREAD CurrentThread = KeGetCurrentThread(); - NTSTATUS WaitStatus = STATUS_SUCCESS; + PKTHREAD Thread = KeGetCurrentThread(); + NTSTATUS WaitStatus; BOOLEAN Swappable; PLARGE_INTEGER OriginalDueTime = Interval; LARGE_INTEGER DueTime, NewDueTime; /* Check if the lock is already held */ - if (CurrentThread->WaitNext) + if (Thread->WaitNext) { /* Lock is held, disable Wait Next */ - CurrentThread->WaitNext = FALSE; + Thread->WaitNext = FALSE; + Swappable = KxDelayThreadWait(Thread, Alertable, WaitMode); } else { /* Lock not held, acquire it */ - CurrentThread->WaitIrql = KiAcquireDispatcherLock(); +WaitStart: + Thread->WaitIrql = KiAcquireDispatcherLock(); + Swappable = KxDelayThreadWait(Thread, Alertable, WaitMode); } - /* Use built-in Wait block */ - TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK]; - - /* Start Wait Loop */ - do + /* Check if a kernel APC is pending and we're below APC_LEVEL */ + if ((Thread->ApcState.KernelApcPending) && !(Thread->SpecialApcDisable) && + (Thread->WaitIrql < APC_LEVEL)) { - /* Check if a kernel APC is pending and we're below APC_LEVEL */ - if ((CurrentThread->ApcState.KernelApcPending) && - !(CurrentThread->SpecialApcDisable) && - (CurrentThread->WaitIrql < APC_LEVEL)) - { - /* Unlock the dispatcher */ - KiReleaseDispatcherLock(CurrentThread->WaitIrql); - } - else - { - /* Check if we can do an alertable wait, if requested */ - KiCheckAlertability(); + /* Unlock the dispatcher */ + KiReleaseDispatcherLock(Thread->WaitIrql); + goto WaitStart; + } - /* Check if we can swap the thread's stack */ - CurrentThread->WaitListEntry.Flink = NULL; - KiCheckThreadStackSwap(WaitMode, CurrentThread, Swappable); + /* Check if we have to bail out due to an alerted state */ + WaitStatus = KiCheckAlertability(Thread, Alertable, WaitMode); + if (WaitStatus != STATUS_WAIT_0) + { + /* Unlock the dispatcher and return */ + KiReleaseDispatcherLock(Thread->WaitIrql); + return WaitStatus; + } - /* Set status */ - CurrentThread->WaitStatus = STATUS_WAIT_0; + /* Set Timer */ + ThreadTimer = &Thread->Timer; - /* Set Timer */ - ThreadTimer = &CurrentThread->Timer; + /* Insert the Timer into the Timer Lists and enable it */ + if (!KiInsertTimer(ThreadTimer, *Interval)) + { + /* FIXME: We should find a new ready thread */ + KiReleaseDispatcherLock(Thread->WaitIrql); + return STATUS_WAIT_0; + } - /* Setup the Wait Block */ - CurrentThread->WaitBlockList = TimerWaitBlock; - TimerWaitBlock->NextWaitBlock = TimerWaitBlock; + /* Save due time */ + DueTime.QuadPart = ThreadTimer->DueTime.QuadPart; - /* Link the timer to this Wait Block */ - ThreadTimer->Header.WaitListHead.Flink = - &TimerWaitBlock->WaitListEntry; - ThreadTimer->Header.WaitListHead.Blink = - &TimerWaitBlock->WaitListEntry; + /* Handle Kernel Queues */ + if (Thread->Queue) KiActivateWaiterQueue(Thread->Queue); - /* Insert the Timer into the Timer Lists and enable it */ - if (!KiInsertTimer(ThreadTimer, *Interval)) - { - /* FIXME: We should find a new ready thread */ - WaitStatus = STATUS_SUCCESS; - break; - } + /* Setup the wait information */ + Thread->State = Waiting; - /* Save due time */ - DueTime.QuadPart = ThreadTimer->DueTime.QuadPart; + /* Add the thread to the wait list */ + KiAddThreadToWaitList(Thread, Swappable); - /* Handle Kernel Queues */ - if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue); + /* Swap the thread */ + ASSERT(Thread->WaitIrql <= DISPATCH_LEVEL); + KiSetThreadSwapBusy(Thread); + WaitStatus = KiSwapThread(Thread, KeGetCurrentPrcb()); - /* Setup the wait information */ - CurrentThread->Alertable = Alertable; - CurrentThread->WaitMode = WaitMode; - CurrentThread->WaitReason = DelayExecution; - CurrentThread->WaitTime = ((PLARGE_INTEGER)&KeTickCount)->LowPart; - CurrentThread->State = Waiting; + /* Check if we were executing an APC or if we timed out */ + if (WaitStatus == STATUS_KERNEL_APC) + { + /* Recalculate due times */ + Interval = KiRecalculateDueTime(OriginalDueTime, + &DueTime, + &NewDueTime); + goto WaitStart; + } - /* Find a new thread to run */ - KiAddThreadToWaitList(CurrentThread, Swappable); - WaitStatus = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + /* This is a good thing */ + if (WaitStatus == STATUS_TIMEOUT) WaitStatus = STATUS_SUCCESS; - /* Check if we were executing an APC or if we timed out */ - if (WaitStatus != STATUS_KERNEL_APC) - { - /* This is a good thing */ - if (WaitStatus == STATUS_TIMEOUT) WaitStatus = STATUS_SUCCESS; - - /* Return Status */ - return WaitStatus; - } - - /* Recalculate due times */ - Interval = KiRecalculateDueTime(OriginalDueTime, - &DueTime, - &NewDueTime); - } - - /* Acquire again the lock */ - CurrentThread->WaitIrql = KiAcquireDispatcherLock(); - } while (TRUE); - - /* Release the Lock, we are done */ - KiReleaseDispatcherLock(CurrentThread->WaitIrql); + /* Return Status */ return WaitStatus; } @@ -403,183 +378,163 @@ KeWaitForSingleObject(IN PVOID Object, { PKMUTANT CurrentObject; PKWAIT_BLOCK WaitBlock; - PKWAIT_BLOCK TimerWaitBlock; PKTIMER ThreadTimer; - PKTHREAD CurrentThread = KeGetCurrentThread(); - NTSTATUS WaitStatus = STATUS_SUCCESS; + PKTHREAD Thread = KeGetCurrentThread(); + NTSTATUS WaitStatus; BOOLEAN Swappable; LARGE_INTEGER DueTime, NewDueTime; PLARGE_INTEGER OriginalDueTime = Timeout; + /* Get wait block */ + WaitBlock = &Thread->WaitBlock[0]; + /* Check if the lock is already held */ - if (CurrentThread->WaitNext) + if (Thread->WaitNext) { /* Lock is held, disable Wait Next */ - CurrentThread->WaitNext = FALSE; + Thread->WaitNext = FALSE; + Swappable = KxSingleThreadWait(Thread, + WaitBlock, + Object, + Timeout, + Alertable, + WaitReason, + WaitMode); } else { +StartWait: /* Lock not held, acquire it */ - CurrentThread->WaitIrql = KiAcquireDispatcherLock(); + Thread->WaitIrql = KiAcquireDispatcherLock(); + Swappable = KxSingleThreadWait(Thread, + WaitBlock, + Object, + Timeout, + WaitReason, + WaitMode, + Alertable); } - /* Start the actual Loop */ - WaitBlock = &CurrentThread->WaitBlock[0]; - do + /* Check if a kernel APC is pending and we're below APC_LEVEL */ + if ((Thread->ApcState.KernelApcPending) && !(Thread->SpecialApcDisable) && + (Thread->WaitIrql < APC_LEVEL)) { - /* Check if a kernel APC is pending and we're below APC_LEVEL */ - if ((CurrentThread->ApcState.KernelApcPending) && - !(CurrentThread->SpecialApcDisable) && - (CurrentThread->WaitIrql < APC_LEVEL)) - { - /* Unlock the dispatcher */ - KiReleaseDispatcherLock(CurrentThread->WaitIrql); - } - else - { - /* Set default status */ - CurrentThread->WaitStatus = STATUS_WAIT_0; + /* Unlock the dispatcher and wait again */ + KiReleaseDispatcherLock(Thread->WaitIrql); + goto StartWait; + } - /* Get the Current Object */ - CurrentObject = (PKMUTANT)Object; + /* Get the Current Object */ + CurrentObject = (PKMUTANT)Object; + ASSERT(CurrentObject->Header.Type != QueueObject); - /* Check if it's a mutant */ - if (CurrentObject->Header.Type == MutantObject) + /* Check if it's a mutant */ + if (CurrentObject->Header.Type == MutantObject) + { + /* Check its signal state or if we own it */ + if ((CurrentObject->Header.SignalState > 0) || + (Thread == CurrentObject->OwnerThread)) + { + /* Just unwait this guy and exit */ + if (CurrentObject->Header.SignalState != (LONG)MINLONG) { - /* Check its signal state or if we own it */ - if ((CurrentObject->Header.SignalState > 0) || - (CurrentThread == CurrentObject->OwnerThread)) - { - /* Just unwait this guy and exit */ - if (CurrentObject->Header.SignalState != (LONG)MINLONG) - { - /* It has a normal signal state. Unwait and return */ - KiSatisfyMutantWait(CurrentObject, CurrentThread); - WaitStatus = CurrentThread->WaitStatus; - goto DontWait; - } - else - { - /* Raise an exception (see wasm.ru) */ - KiReleaseDispatcherLock(CurrentThread-> - WaitIrql); - ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); - } - } - } - else if (CurrentObject->Header.SignalState > 0) - { - /* Another satisfied object */ - KiSatisfyNonMutantWait(CurrentObject, CurrentThread); - WaitStatus = STATUS_WAIT_0; + /* It has a normal signal state. Unwait and return */ + KiSatisfyMutantWait(CurrentObject, Thread); + WaitStatus = Thread->WaitStatus; goto DontWait; } - - /* Append wait block to the KTHREAD wait block list */ - CurrentThread->WaitBlockList = WaitBlock; - - /* Set up the Wait Block */ - WaitBlock->Object = CurrentObject; - WaitBlock->WaitKey = (USHORT)(STATUS_SUCCESS); - WaitBlock->WaitType = WaitAny; - - /* Make sure we can satisfy the Alertable request */ - KiCheckAlertability(); - - /* Check if we can swap the thread's stack */ - CurrentThread->WaitListEntry.Flink = NULL; - KiCheckThreadStackSwap(WaitMode, CurrentThread, Swappable); - - /* Enable the Timeout Timer if there was any specified */ - if (Timeout) - { - /* Fail if the timeout interval is actually 0 */ - if (!Timeout->QuadPart) - { - /* Return a timeout */ - WaitStatus = STATUS_TIMEOUT; - goto DontWait; - } - - /* Point to Timer Wait Block and Thread Timer */ - TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK]; - ThreadTimer = &CurrentThread->Timer; - - /* Connect the Timer Wait Block */ - WaitBlock->NextWaitBlock = TimerWaitBlock; - - /* Set up the Timer Wait Block */ - TimerWaitBlock->NextWaitBlock = WaitBlock; - - /* Link the timer to this Wait Block */ - ThreadTimer->Header.WaitListHead.Flink = - &TimerWaitBlock->WaitListEntry; - ThreadTimer->Header.WaitListHead.Blink = - &TimerWaitBlock->WaitListEntry; - - /* Insert the Timer into the Timer Lists and enable it */ - if (!KiInsertTimer(ThreadTimer, *Timeout)) - { - /* Return a timeout if we couldn't insert the timer */ - WaitStatus = STATUS_TIMEOUT; - goto DontWait; - } - - /* Set the current due time */ - DueTime.QuadPart = ThreadTimer->DueTime.QuadPart; - } else { - /* No timer block, so just set our wait block as next */ - WaitBlock->NextWaitBlock = WaitBlock; - } + /* Raise an exception */ + KiReleaseDispatcherLock(Thread->WaitIrql); + ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); + } + } + } + else if (CurrentObject->Header.SignalState > 0) + { + /* Another satisfied object */ + KiSatisfyNonMutantWait(CurrentObject, Thread); + WaitStatus = STATUS_WAIT_0; + goto DontWait; + } - /* Link the Object to this Wait Block */ - InsertTailList(&CurrentObject->Header.WaitListHead, - &WaitBlock->WaitListEntry); + /* Make sure we can satisfy the Alertable request */ + WaitStatus = KiCheckAlertability(Thread, Alertable, WaitMode); + if (WaitStatus != STATUS_WAIT_0) + { + /* Unlock the dispatcher and return */ + KiReleaseDispatcherLock(Thread->WaitIrql); + return WaitStatus; + } - /* Handle Kernel Queues */ - if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue); - - /* Setup the wait information */ - CurrentThread->Alertable = Alertable; - CurrentThread->WaitMode = WaitMode; - CurrentThread->WaitReason = WaitReason; - CurrentThread->WaitTime = ((PLARGE_INTEGER)&KeTickCount)->LowPart; - CurrentThread->State = Waiting; - - /* Find a new thread to run */ - KiAddThreadToWaitList(CurrentThread, Swappable); - WaitStatus = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - /* Check if we were executing an APC */ - if (WaitStatus != STATUS_KERNEL_APC) return WaitStatus; - - /* Check if we had a timeout */ - if (Timeout) - { - /* Recalculate due times */ - Timeout = KiRecalculateDueTime(OriginalDueTime, - &DueTime, - &NewDueTime); - } + /* Enable the Timeout Timer if there was any specified */ + if (Timeout) + { + /* Fail if the timeout interval is actually 0 */ + if (!Timeout->QuadPart) + { + /* Return a timeout */ + WaitStatus = STATUS_TIMEOUT; + goto DontWait; } - /* Acquire again the lock */ - CurrentThread->WaitIrql = KiAcquireDispatcherLock(); - } while (TRUE); + /* Insert the Timer into the Timer Lists and enable it */ + ThreadTimer = &Thread->Timer; + if (!KiInsertTimer(ThreadTimer, *Timeout)) + { + /* Return a timeout if we couldn't insert the timer */ + WaitStatus = STATUS_TIMEOUT; + goto DontWait; + } - /* Release the Lock, we are done */ - KiReleaseDispatcherLock(CurrentThread->WaitIrql); + /* Set the current due time */ + DueTime.QuadPart = ThreadTimer->DueTime.QuadPart; + } + + /* Link the Object to this Wait Block */ + InsertTailList(&CurrentObject->Header.WaitListHead, + &WaitBlock->WaitListEntry); + + /* Handle Kernel Queues */ + if (Thread->Queue) KiActivateWaiterQueue(Thread->Queue); + + /* Setup the wait information */ + Thread->State = Waiting; + + /* Add the thread to the wait list */ + KiAddThreadToWaitList(Thread, Swappable); + + /* Swap the thread */ + ASSERT(Thread->WaitIrql <= DISPATCH_LEVEL); + KiSetThreadSwapBusy(Thread); + WaitStatus = KiSwapThread(Thread, KeGetCurrentPrcb()); + + /* Check if we were executing an APC */ + if (WaitStatus == STATUS_KERNEL_APC) + { + /* Check if we had a timeout */ + if (Timeout) + { + /* Recalculate due times */ + Timeout = KiRecalculateDueTime(OriginalDueTime, + &DueTime, + &NewDueTime); + } + + /* Wait again */ + goto StartWait; + } + + /* Wait complete */ return WaitStatus; DontWait: /* Adjust the Quantum */ - KiAdjustQuantumThread(CurrentThread); + KiAdjustQuantumThread(Thread); /* Release & Return */ - KiReleaseDispatcherLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(Thread->WaitIrql); return WaitStatus; } @@ -769,11 +724,11 @@ KeWaitForMultipleObjects(IN ULONG Count, } /* Make sure we can satisfy the Alertable request */ - KiCheckAlertability(); + WaitStatus = KiCheckAlertability(CurrentThread, Alertable, WaitMode); /* Check if we can swap the thread's stack */ CurrentThread->WaitListEntry.Flink = NULL; - KiCheckThreadStackSwap(WaitMode, CurrentThread, Swappable); + Swappable = KiCheckThreadStackSwap(CurrentThread, WaitMode); /* Enable the Timeout Timer if there was any specified */ if (Timeout) @@ -827,7 +782,7 @@ KeWaitForMultipleObjects(IN ULONG Count, } while (WaitBlock != WaitBlockArray); /* Handle Kernel Queues */ - if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue); + if (CurrentThread->Queue) KiActivateWaiterQueue(CurrentThread->Queue); /* Setup the wait information */ CurrentThread->Alertable = Alertable; @@ -880,22 +835,22 @@ NtDelayExecution(IN BOOLEAN Alertable, LARGE_INTEGER SafeInterval; NTSTATUS Status = STATUS_SUCCESS; - /* Check if parameters are valid */ + /* Check the previous mode */ if(PreviousMode != KernelMode) { + /* Enter SEH for probing */ _SEH_TRY { - /* make a copy on the kernel stack and let DelayInterval point to it so - we don't need to wrap KeDelayExecutionThread in SEH! */ + /* Probe and capture the time out */ SafeInterval = ProbeForReadLargeInteger(DelayInterval); DelayInterval = &SafeInterval; } _SEH_HANDLE { + /* Get SEH exception */ Status = _SEH_GetExceptionCode(); } _SEH_END; - if (!NT_SUCCESS(Status)) return Status; } From 63ae6043557587e55d704cea3d7c15af6d9dac72 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Thu, 14 Sep 2006 16:04:08 +0000 Subject: [PATCH 194/488] Fix typo. palate -> pallete svn path=/trunk/; revision=24111 --- reactos/subsystems/win32/win32k/objects/color.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/color.c b/reactos/subsystems/win32/win32k/objects/color.c index 5f5c06555ea..caefc106682 100644 --- a/reactos/subsystems/win32/win32k/objects/color.c +++ b/reactos/subsystems/win32/win32k/objects/color.c @@ -36,7 +36,7 @@ static HPALETTE hPrimaryPalette = 0; // used for WM_PALETTECHANGED //static HPALETTE hLastRealizedPalette = 0; // UnrealizeObject() needs it -static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the palate and restore it */ +static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the pallete and restore it */ const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] = { @@ -388,7 +388,7 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC) { /* FIXME - Handle palGDI == NULL!!!! we should not unlock dc and return 0 ?? - shall we create the palate ?? + shall we create the pallete ?? */ DC_UnlockDc(dc); return 0; @@ -401,7 +401,7 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC) { /* FIXME - Handle sysGDI == NULL!!!!! we should not unlock dc and return 0 ?? - shall we create the palate ?? + shall we create the pallete ?? */ PALETTE_UnlockPalette(palGDI); DC_UnlockDc(dc); From efcc4447c11aad25142e7f2a1512bca6ac69f68a Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 14 Sep 2006 16:37:05 +0000 Subject: [PATCH 195/488] Reapply fixed half of 24020 (relocation update in rtl). Tested on vmware and real hardware. svn path=/trunk/; revision=24112 --- reactos/lib/rtl/image.c | 138 +++++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 58 deletions(-) diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index 97b5a9b4643..6fb56c01310 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -3,8 +3,10 @@ * FILE: lib/rtl/image.c * PURPOSE: Image handling functions * Relocate functions were previously located in - * ntoskrnl/ldr/loader.c - * PROGRAMMER: Eric Kohl + original authors from loader.c file + * ntoskrnl/ldr/loader.c and + * dll/ntdll/ldr/utils.c files + * PROGRAMMER: Eric Kohl + original authors from loader.c and utils.c file + * Aleksey Bragin */ /* INCLUDES *****************************************************************/ @@ -149,6 +151,70 @@ RtlImageRvaToVa ( (ULONG_PTR)Section->VirtualAddress); } +PIMAGE_BASE_RELOCATION +LdrProcessRelocationBlockLongLong( + IN ULONG_PTR Address, + IN ULONG Count, + IN PUSHORT TypeOffset, + IN LONGLONG Delta + ) +{ + SHORT Offset; + USHORT Type; + USHORT i; + PUSHORT ShortPtr; + PULONG LongPtr; + + for (i = 0; i < Count; i++) + { + Offset = *TypeOffset & 0xFFF; + Type = *TypeOffset >> 12; + ShortPtr = (PUSHORT)(RVA(Address, Offset)); + + /* + * Don't relocate within the relocation section itself. + * GCC/LD generates sometimes relocation records for the relocation section. + * This is a bug in GCC/LD. + * Fix for it disabled, since it was only in ntoskrnl and not in ntdll + */ + /* + if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir || + (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd) + {*/ + switch (Type) + { + /* case IMAGE_REL_BASED_SECTION : */ + /* case IMAGE_REL_BASED_REL32 : */ + case IMAGE_REL_BASED_ABSOLUTE: + break; + + case IMAGE_REL_BASED_HIGH: + *ShortPtr = HIWORD(MAKELONG(0, *ShortPtr) + (LONG)Delta); + break; + + case IMAGE_REL_BASED_LOW: + *ShortPtr += LOWORD(Delta); + break; + + case IMAGE_REL_BASED_HIGHLOW: + LongPtr = (PULONG)RVA(Address, Offset); + *LongPtr += (ULONG)Delta; + break; + + case IMAGE_REL_BASED_HIGHADJ: + case IMAGE_REL_BASED_MIPS_JMPADDR: + default: + DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); + DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset); + return (PIMAGE_BASE_RELOCATION)NULL; + } + + TypeOffset++; + } + + return (PIMAGE_BASE_RELOCATION)TypeOffset; +} + ULONG NTAPI LdrRelocateImageWithBias( @@ -163,14 +229,10 @@ LdrRelocateImageWithBias( PIMAGE_NT_HEADERS NtHeaders; PIMAGE_DATA_DIRECTORY RelocationDDir; PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; - ULONG Count, i; - PVOID Address;//, MaxAddress; + ULONG Count; + ULONG_PTR Address; PUSHORT TypeOffset; - ULONG_PTR Delta; - SHORT Offset; - USHORT Type; - PUSHORT ShortPtr; - PULONG LongPtr; + LONGLONG Delta; NtHeaders = RtlImageNtHeader(BaseAddress); @@ -192,64 +254,24 @@ LdrRelocateImageWithBias( Delta = (ULONG_PTR)BaseAddress - NtHeaders->OptionalHeader.ImageBase + AdditionalBias; RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + RelocationDDir->VirtualAddress); RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size); - //MaxAddress = RVA(BaseAddress, DriverSize); while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) { Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - Address = RVA(BaseAddress, RelocationDir->VirtualAddress); + Address = (ULONG_PTR)RVA(BaseAddress, RelocationDir->VirtualAddress); TypeOffset = (PUSHORT)(RelocationDir + 1); - for (i = 0; i < Count; i++) + RelocationDir = LdrProcessRelocationBlockLongLong(Address, + Count, + TypeOffset, + Delta); + + if (RelocationDir == NULL) { - Offset = *TypeOffset & 0xFFF; - Type = *TypeOffset >> 12; - ShortPtr = (PUSHORT)(RVA(Address, Offset)); - - /* Don't relocate after the end of the loaded driver */ - /*if ((PVOID)ShortPtr >= MaxAddress) - { - break; - }*/ - - /* - * Don't relocate within the relocation section itself. - * GCC/LD generates sometimes relocation records for the relocation section. - * This is a bug in GCC/LD. - */ - if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir || - (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd) - { - switch (Type) - { - case IMAGE_REL_BASED_ABSOLUTE: - break; - - case IMAGE_REL_BASED_HIGH: - *ShortPtr += HIWORD(Delta); - break; - - case IMAGE_REL_BASED_LOW: - *ShortPtr += LOWORD(Delta); - break; - - case IMAGE_REL_BASED_HIGHLOW: - LongPtr = (PULONG)ShortPtr; - *LongPtr += Delta; - break; - - case IMAGE_REL_BASED_HIGHADJ: - case IMAGE_REL_BASED_MIPS_JMPADDR: - default: - DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); - DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset); - return Invalid; - } - } - TypeOffset++; + DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n"); + return Invalid; } - RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock); } return Success; From 3f285b2d736b254d2fcf9f0972742357e8097cff Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 14 Sep 2006 16:39:35 +0000 Subject: [PATCH 196/488] adding Japanese keyboard drv patch from ja731j (real name : Simon Hanae mail : ja731j at ja731j dot homeip dot net See issue #1795 for more details. svn path=/trunk/; revision=24113 --- reactos/dll/keyboard/kbdja/kbdja.c | 371 ++++++++++++++++++++++++ reactos/dll/keyboard/kbdja/kbdja.def | 8 + reactos/dll/keyboard/kbdja/kbdja.rbuild | 9 + reactos/dll/keyboard/kbdja/kbdja.rc | 5 + reactos/dll/keyboard/keyboard.rbuild | 3 + 5 files changed, 396 insertions(+) create mode 100644 reactos/dll/keyboard/kbdja/kbdja.c create mode 100644 reactos/dll/keyboard/kbdja/kbdja.def create mode 100644 reactos/dll/keyboard/kbdja/kbdja.rbuild create mode 100644 reactos/dll/keyboard/kbdja/kbdja.rc diff --git a/reactos/dll/keyboard/kbdja/kbdja.c b/reactos/dll/keyboard/kbdja/kbdja.c new file mode 100644 index 00000000000..f5621c4d7b1 --- /dev/null +++ b/reactos/dll/keyboard/kbdja/kbdja.c @@ -0,0 +1,371 @@ +/* + * ReactOS USASCII Keyboard layout + * Copyright (C) 2003 ReactOS + * License: LGPL, see: LGPL.txt + * + * Thanks to: http://www.barcodeman.com/altek/mule/scandoc.php + * and http://win.tue.nl/~aeb/linux/kbd/scancodes-1.html + */ + +#include +#include + +#ifdef _M_IA64 +#define ROSDATA static __declspec(allocate(".data")) +#else +#ifdef _MSC_VER +#pragma data_seg(".data") +#define ROSDATA static +#else +#define ROSDATA static __attribute__((section(".data"))) +#endif +#endif + +#define VK_EMPTY 0xff /* The non-existent VK */ +#define KSHIFT 0x001 /* Shift modifier */ +#define KCTRL 0x002 /* Ctrl modifier */ +#define KALT 0x004 /* Alt modifier */ +#define KEXT 0x100 /* Extended key code */ +#define KMULTI 0x200 /* Multi-key */ +#define KSPEC 0x400 /* Special key */ +#define KNUMP 0x800 /* Number-pad */ +#define KNUMS 0xc00 /* Special + number pad */ +#define KMEXT 0x300 /* Multi + ext */ + +/* temporary */ +#define SC_13 0xde +#define SC_27 0xc0 +#define SC_40 0xbb +#define SC_41 0xba + +ROSDATA USHORT scancode_to_vk[] = { + /* Numbers Row */ + /* - 00 - */ + /* 1 ... 2 ... 3 ... 4 ... */ + VK_EMPTY, VK_ESCAPE, '1', '2', + '3', '4', '5', '6', + '7', '8', '9', '0', + VK_OEM_MINUS, SC_13, VK_BACK, + /* - 0f - */ + /* First Letters Row */ + VK_TAB, 'Q', 'W', 'E', + 'R', 'T', 'Y', 'U', + 'I', 'O', 'P', + SC_27, VK_OEM_4, VK_RETURN, + /* - 1d - */ + /* Second Letters Row */ + VK_LCONTROL, + 'A', 'S', 'D', 'F', + 'G', 'H', 'J', 'K', + 'L', SC_40, SC_41, VK_EMPTY, + VK_LSHIFT, VK_OEM_6, + /* - 2c - */ + /* Third letters row */ + 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', VK_OEM_COMMA, + VK_OEM_PERIOD,VK_OEM_2,VK_OEM_5, VK_RSHIFT, + /* - 37 - */ + /* Bottom Row */ + VK_MULTIPLY, VK_LMENU, VK_SPACE, VK_CAPITAL, + + /* - 3b - */ + /* F-Keys */ + VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, + VK_F7, VK_F8, VK_F9, VK_F10, + /* - 45 - */ + /* Locks */ + VK_NUMLOCK | KMEXT, + VK_SCROLL | KMULTI, + /* - 47 - */ + /* Number-Pad */ + VK_HOME | KNUMS, VK_UP | KNUMS, VK_PRIOR | KNUMS, VK_SUBTRACT, + VK_LEFT | KNUMS, VK_CLEAR | KNUMS, VK_RIGHT | KNUMS, VK_ADD, + VK_END | KNUMS, VK_DOWN | KNUMS, VK_NEXT | KNUMS, + VK_INSERT | KNUMS, VK_DELETE | KNUMS, + /* - 54 - */ + /* Presumably PrtSc */ + VK_SNAPSHOT, + /* - 55 - */ + /* Oddities, and the remaining standard F-Keys */ + VK_EMPTY, VK_EMPTY, VK_F11, VK_F12, + /* - 59 - */ + VK_CLEAR, VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* EREOF */ + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* ZOOM */ + VK_HELP, + /* - 64 - */ + /* Even more F-Keys (for example, NCR keyboards from the early 90's) */ + VK_F13, VK_F14, VK_F15, VK_F16, VK_F17, VK_F18, VK_F19, VK_F20, + VK_F21, VK_F22, VK_F23, + /* - 6f - */ + /* Not sure who uses these codes */ + VK_EMPTY, VK_EMPTY, VK_EMPTY, + /* - 72 - */ + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, + /* - 76 - */ + /* One more f-key */ + VK_F24, + /* - 77 - */ + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* PA1 */ + VK_EMPTY, + /* - 80 - */ + 0 +}; + +ROSDATA VSC_VK extcode0_to_vk[] = { + { 0, 0 }, +}; + +ROSDATA VSC_VK extcode1_to_vk[] = { + { 0, 0 }, +}; + +ROSDATA VK_TO_BIT modifier_keys[] = { + { VK_SHIFT, KSHIFT }, + { VK_CONTROL, KCTRL }, + { VK_MENU, KALT }, + { 0, 0 } +}; + +ROSDATA MODIFIERS modifier_bits = { + modifier_keys, + 3, + { 0, 1, 2, 3 } /* Modifier bit order, NONE, SHIFT, CTRL, ALT */ +}; + +#define NOCAPS 0 +#define CAPS KSHIFT /* Caps -> shift */ + +ROSDATA VK_TO_WCHARS2 key_to_chars_2mod[] = { + /* Normal vs Shifted */ + /* The numbers */ + { '1', NOCAPS, {'1', '!'} }, + /* Ctrl-2 generates NUL */ + { '2', NOCAPS, {'2', '\"'} }, + { '3', NOCAPS, {'3', '#'} }, + { '4', NOCAPS, {'4', '$'} }, + { '5', NOCAPS, {'5', '%'} }, + /* Ctrl-6 generates RS */ + { '6', NOCAPS, {'6', '&'} }, + { '7', NOCAPS, {'7', '\''} }, + { '8', NOCAPS, {'8', '('} }, + { '9', NOCAPS, {'9', ')'} }, + { '0', NOCAPS, {'0', 0xff} }, + + /*Japanese Keys*/ + { SC_13, NOCAPS, { '^','~'} }, + { SC_27, NOCAPS, { '@','`'} }, + { SC_40, NOCAPS, { ';','+'} }, + { SC_41, NOCAPS, { ':','*'} }, + + /* Specials */ + /* Ctrl-_ generates US */ + { VK_OEM_PLUS ,NOCAPS, {';', '+'} }, + { VK_OEM_1 ,NOCAPS, {';', ':'} }, + { VK_OEM_7 ,NOCAPS, {'\'','\"'} }, + { VK_OEM_3 ,NOCAPS, {'`', '~'} }, + { VK_OEM_COMMA ,NOCAPS, {',', '<'} }, + { VK_OEM_PERIOD ,NOCAPS, {'.', '>'} }, + { VK_OEM_2 ,NOCAPS, {'/', '?'} }, + /* Keys that do not have shift states */ + { VK_TAB ,NOCAPS, {'\t','\t'} }, + { VK_ADD ,NOCAPS, {'+', '+'} }, + { VK_SUBTRACT,NOCAPS, {'-', '-'} }, + { VK_MULTIPLY,NOCAPS, {'*', '*'} }, + { VK_DIVIDE ,NOCAPS, {'/', '/'} }, + { VK_ESCAPE ,NOCAPS, {'\x1b','\x1b'} }, + { VK_SPACE ,NOCAPS, {' ', ' '} }, + { 0, 0 } +}; + +ROSDATA VK_TO_WCHARS3 key_to_chars_3mod[] = { + /* Normal, Shifted, Ctrl */ + /* Legacy (telnet-style) ascii escapes */ + { VK_OEM_4, 0, {'[', '{', 0x1b /* ESC */} }, + { VK_OEM_6, 0, {']', '}', 0x1d /* GS */} }, + { VK_OEM_5, 0, {'\\','|', 0x1c /* FS */} }, + { VK_RETURN,0, {'\r', '\r', '\n'} }, + { 0,0 } +}; + +ROSDATA VK_TO_WCHARS4 key_to_chars_4mod[] = { + /* Normal, Shifted, Ctrl, C-S-x */ + + /* The alphabet */ + { 'A', CAPS, {'a', 'A', 0x01, 0x01} }, + { 'B', CAPS, {'b', 'B', 0x02, 0x02} }, + { 'C', CAPS, {'c', 'C', 0x03, 0x03} }, + { 'D', CAPS, {'d', 'D', 0x04, 0x04} }, + { 'E', CAPS, {'e', 'E', 0x05, 0x05} }, + { 'F', CAPS, {'f', 'F', 0x06, 0x06} }, + { 'G', CAPS, {'g', 'G', 0x07, 0x07} }, + { 'H', CAPS, {'h', 'H', 0x08, 0x08} }, + { 'I', CAPS, {'i', 'I', 0x09, 0x09} }, + { 'J', CAPS, {'j', 'J', 0x0a, 0x0a} }, + { 'K', CAPS, {'k', 'K', 0x0b, 0x0b} }, + { 'L', CAPS, {'l', 'L', 0x0c, 0x0c} }, + { 'M', CAPS, {'m', 'M', 0x0d, 0x0d} }, + { 'N', CAPS, {'n', 'N', 0x0e, 0x0e} }, + { 'O', CAPS, {'o', 'O', 0x0f, 0x0f} }, + { 'P', CAPS, {'p', 'P', 0x10, 0x10} }, + { 'Q', CAPS, {'q', 'Q', 0x11, 0x11} }, + { 'R', CAPS, {'r', 'R', 0x12, 0x12} }, + { 'S', CAPS, {'s', 'S', 0x13, 0x13} }, + { 'T', CAPS, {'t', 'T', 0x14, 0x14} }, + { 'U', CAPS, {'u', 'U', 0x15, 0x15} }, + { 'V', CAPS, {'v', 'V', 0x16, 0x16} }, + { 'W', CAPS, {'w', 'W', 0x17, 0x17} }, + { 'X', CAPS, {'x', 'X', 0x18, 0x18} }, + { 'Y', CAPS, {'y', 'Y', 0x19, 0x19} }, + { 'Z', CAPS, {'z', 'Z', 0x1a, 0x1a} }, + + /* Legacy Ascii generators */ + { '2', NOCAPS, {'2', '@', WCH_NONE, 0} }, + { '6', NOCAPS, {'6', '^', WCH_NONE, 0x1e /* RS */} }, + { VK_OEM_MINUS, NOCAPS, {'-', '=', WCH_NONE, 0x1f /* US */} }, + { 0, 0 } +}; + +ROSDATA VK_TO_WCHARS1 keypad_numbers[] = { + { VK_NUMPAD0, 0, {'0'} }, + { VK_NUMPAD1, 0, {'1'} }, + { VK_NUMPAD2, 0, {'2'} }, + { VK_NUMPAD3, 0, {'3'} }, + { VK_NUMPAD4, 0, {'4'} }, + { VK_NUMPAD5, 0, {'5'} }, + { VK_NUMPAD6, 0, {'6'} }, + { VK_NUMPAD7, 0, {'7'} }, + { VK_NUMPAD8, 0, {'8'} }, + { VK_NUMPAD9, 0, {'9'} }, + { VK_DECIMAL, 0, {'.'} }, + { VK_BACK, 0, {'\010'} }, + { 0,0 } +}; + +#define vk_master(n,x) { (PVK_TO_WCHARS1)x, n, sizeof(x[0]) } + +ROSDATA VK_TO_WCHAR_TABLE vk_to_wchar_master_table[] = { + vk_master(1,keypad_numbers), + vk_master(2,key_to_chars_2mod), + vk_master(3,key_to_chars_3mod), + vk_master(4,key_to_chars_4mod), + { 0,0,0 } +}; + +ROSDATA VSC_LPWSTR key_names[] = { + { 0x00, L"" }, + { 0x01, L"Esc" }, + { 0x0e, L"Backspace" }, + { 0x0f, L"Tab" }, + { 0x1c, L"Enter" }, + { 0x1d, L"Ctrl" }, + { 0x2a, L"Shift" }, + { 0x36, L"Right Shift" }, + { 0x37, L"Num *" }, + { 0x38, L"Alt" }, + { 0x39, L"Space" }, + { 0x3a, L"Caps Lock" }, + { 0x3b, L"F1" }, + { 0x3c, L"F2" }, + { 0x3d, L"F3" }, + { 0x3e, L"F4" }, + { 0x3f, L"F5" }, + { 0x40, L"F6" }, + { 0x41, L"F7" }, + { 0x42, L"F8" }, + { 0x43, L"F9" }, + { 0x44, L"F10" }, + { 0x45, L"Pause" }, + { 0x46, L"Scroll Lock" }, + { 0x47, L"Num 7" }, + { 0x48, L"Num 8" }, + { 0x49, L"Num 9" }, + { 0x4a, L"Num -" }, + { 0x4b, L"Num 4" }, + { 0x4c, L"Num 5" }, + { 0x4d, L"Num 6" }, + { 0x4e, L"Num +" }, + { 0x4f, L"Num 1" }, + { 0x50, L"Num 2" }, + { 0x51, L"Num 3" }, + { 0x52, L"Num 0" }, + { 0x53, L"Num Del" }, + { 0x54, L"Sys Req" }, + { 0x57, L"F11" }, + { 0x58, L"F12" }, + { 0x7c, L"F13" }, + { 0x7d, L"F14" }, + { 0x7e, L"F15" }, + { 0x7f, L"F16" }, + { 0x80, L"F17" }, + { 0x81, L"F18" }, + { 0x82, L"F19" }, + { 0x83, L"F20" }, + { 0x84, L"F21" }, + { 0x85, L"F22" }, + { 0x86, L"F23" }, + { 0x87, L"F24" }, + { 0, NULL }, +}; + +ROSDATA VSC_LPWSTR extended_key_names[] = { + { 0x1c, L"Num Enter" }, + { 0x1d, L"Right Ctrl" }, + { 0x35, L"Num /" }, + { 0x37, L"Prnt Scrn" }, + { 0x38, L"Right Alt" }, + { 0x45, L"Num Lock" }, + { 0x46, L"Break" }, + { 0x47, L"Home" }, + { 0x48, L"Up" }, + { 0x49, L"Page Up" }, + { 0x4a, L"Left" }, + { 0x4c, L"Center" }, + { 0x4d, L"Right" }, + { 0x4f, L"End" }, + { 0x50, L"Down" }, + { 0x51, L"Page Down" }, + { 0x52, L"Insert" }, + { 0x53, L"Delete" }, + { 0x54, L"" }, + { 0x55, L"Help" }, + { 0x56, L"Left Windows" }, + { 0x5b, L"Right Windows" }, + { 0, NULL }, +}; + +/* Finally, the master table */ +ROSDATA KBDTABLES keyboard_layout_table = { + /* modifier assignments */ + &modifier_bits, + + /* character from vk tables */ + vk_to_wchar_master_table, + + /* diacritical marks -- currently implemented by wine code */ + /* English doesn't have any, anyway */ + NULL, + + /* Key names */ + (VSC_LPWSTR *)key_names, + (VSC_LPWSTR *)extended_key_names, + NULL, /* Dead key names */ + + /* scan code to virtual key maps */ + scancode_to_vk, + sizeof(scancode_to_vk) / sizeof(scancode_to_vk[0]), + extcode0_to_vk, + extcode1_to_vk, + + MAKELONG(0,1), /* Version 1.0 */ + + /* Ligatures -- English doesn't have any */ + 0, + 0, + NULL +}; + +PKBDTABLES STDCALL KbdLayerDescriptor() { + return &keyboard_layout_table; +} + diff --git a/reactos/dll/keyboard/kbdja/kbdja.def b/reactos/dll/keyboard/kbdja/kbdja.def new file mode 100644 index 00000000000..6a67344ff6c --- /dev/null +++ b/reactos/dll/keyboard/kbdja/kbdja.def @@ -0,0 +1,8 @@ +; +; ReactOS Operating System +; +LIBRARY kbdja.dll + +EXPORTS +KbdLayerDescriptor@0 +;EOF diff --git a/reactos/dll/keyboard/kbdja/kbdja.rbuild b/reactos/dll/keyboard/kbdja/kbdja.rbuild new file mode 100644 index 00000000000..cf7adc327a8 --- /dev/null +++ b/reactos/dll/keyboard/kbdja/kbdja.rbuild @@ -0,0 +1,9 @@ + + + include + + + 0x0500 + kbdja.c + kbdja.rc + diff --git a/reactos/dll/keyboard/kbdja/kbdja.rc b/reactos/dll/keyboard/kbdja/kbdja.rc new file mode 100644 index 00000000000..e180ea5ef4b --- /dev/null +++ b/reactos/dll/keyboard/kbdja/kbdja.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Japanese (JIS 106) Keyboard Layout\0" +#define REACTOS_STR_INTERNAL_NAME "kbdja\0" +#define REACTOS_STR_ORIGINAL_FILENAME "kbdja.dll\0" +#include diff --git a/reactos/dll/keyboard/keyboard.rbuild b/reactos/dll/keyboard/keyboard.rbuild index 0533e7ce71e..280651591c3 100644 --- a/reactos/dll/keyboard/keyboard.rbuild +++ b/reactos/dll/keyboard/keyboard.rbuild @@ -50,4 +50,7 @@ + + + From 4a1ee5a2287347746e785c007a08f255772678b2 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 14 Sep 2006 16:40:40 +0000 Subject: [PATCH 197/488] adding Japanese keyboard to reactos installer svn path=/trunk/; revision=24114 --- reactos/boot/bootdata/packages/reactos.dff | 3 ++- reactos/boot/bootdata/txtsetup.sif | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index 43355b22aaa..bdf754ec872 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -133,6 +133,8 @@ dll\keyboard\kbdfr\kbdfr.dll 1 dll\keyboard\kbdgr\kbdgr.dll 1 dll\keyboard\kbdhe\kbdhe.dll 1 dll\keyboard\kbdhu\kbdhu.dll 1 +dll\keyboard\kbdpo\kbdja.dll 1 +dll\keyboard\kbdpo\kbdpo.dll 1 dll\keyboard\kbdru\kbdru.dll 1 dll\keyboard\kbdse\kbdse.dll 1 dll\keyboard\kbdsg\kbdsg.dll 1 @@ -140,7 +142,6 @@ dll\keyboard\kbdsk\kbdsk.dll 1 dll\keyboard\kbduk\kbduk.dll 1 dll\keyboard\kbdur\kbdur.dll 1 dll\keyboard\kbdus\kbdus.dll 1 -dll\keyboard\kbdpo\kbdpo.dll 1 dll\ntdll\ntdll.dll 1 diff --git a/reactos/boot/bootdata/txtsetup.sif b/reactos/boot/bootdata/txtsetup.sif index 385b4bdf371..9525fa55089 100644 --- a/reactos/boot/bootdata/txtsetup.sif +++ b/reactos/boot/bootdata/txtsetup.sif @@ -98,16 +98,17 @@ Default = "XT-, AT- or extended keyboard (83-105 keys)" 00010409 = "English (USA-Dvorak)" 0000040C = "French (France)" 00000407 = "German (Germany)" -0000040E = "Hungarian" -00000419 = "Russian" -0000040A = "Spanish (traditional short)" -0000041D = "Swedish (Sweden)" 00000807 = "German (Swiss)" 00000408 = "Greek" -00000422 = "Ukrainian" 00010408 = "Greek 220" -0000041B = "Slovak (QWERTZ)" +0000040E = "Hungarian" +00000411 = "Japanese" 00000816 = "Portuguese (Portugal)" +00000419 = "Russian" +0000041B = "Slovak (QWERTZ)" +0000040A = "Spanish (traditional short)" +0000041D = "Swedish (Sweden)" +00000422 = "Ukrainian" [Files.KeyboardLayout] 00000406 = kbdda.dll @@ -127,6 +128,7 @@ Default = "XT-, AT- or extended keyboard (83-105 keys)" 00010408 = kbdhe.dll 0000041B = kbdsk.dll 00000816 = kbdpo.dll +00000411 = kbdja.dll [HiveInfs.Install] AddReg=hivecls.inf,AddReg From d667517b420bcfdf643d4fe4fb4a95922e918dae Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 14 Sep 2006 16:49:11 +0000 Subject: [PATCH 198/488] start to rewrite the virtmem code to remove many bugs and make it more readable. I'm currently working on enhancements to sysdm, but it's probably better to commit this separately svn path=/trunk/; revision=24115 --- reactos/dll/cpl/sysdm/advanced.c | 6 +- reactos/dll/cpl/sysdm/computer.c | 7 +- reactos/dll/cpl/sysdm/environment.c | 8 +- reactos/dll/cpl/sysdm/general.c | 6 +- reactos/dll/cpl/sysdm/hardware.c | 6 +- reactos/dll/cpl/sysdm/{sysdm.h => precomp.h} | 89 +- reactos/dll/cpl/sysdm/sysdm.c | 8 +- reactos/dll/cpl/sysdm/sysdm.def | 2 +- reactos/dll/cpl/sysdm/userprofile.c | 6 +- reactos/dll/cpl/sysdm/virtmem.c | 1227 ++++++++---------- 10 files changed, 595 insertions(+), 770 deletions(-) rename reactos/dll/cpl/sysdm/{sysdm.h => precomp.h} (59%) diff --git a/reactos/dll/cpl/sysdm/advanced.c b/reactos/dll/cpl/sysdm/advanced.c index 20806dbce12..0ecaaebe93b 100644 --- a/reactos/dll/cpl/sysdm/advanced.c +++ b/reactos/dll/cpl/sysdm/advanced.c @@ -25,12 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" /* Property page dialog callback */ INT_PTR CALLBACK diff --git a/reactos/dll/cpl/sysdm/computer.c b/reactos/dll/cpl/sysdm/computer.c index 220810a5333..1e17de5a5b4 100644 --- a/reactos/dll/cpl/sysdm/computer.c +++ b/reactos/dll/cpl/sysdm/computer.c @@ -25,11 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include "resource.h" -#include "sysdm.h" + +#include "precomp.h" /* Property page dialog callback */ INT_PTR CALLBACK diff --git a/reactos/dll/cpl/sysdm/environment.c b/reactos/dll/cpl/sysdm/environment.c index fd902c7b0cf..e7ba4a5f0f0 100644 --- a/reactos/dll/cpl/sysdm/environment.c +++ b/reactos/dll/cpl/sysdm/environment.c @@ -24,13 +24,7 @@ * PROGRAMMER: Eric Kohl */ -#include -#include -#include -#include - -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" typedef struct _VARIABLE_DATA diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index 686d0702a0a..b0dffe56510 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -25,12 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" void ShowLastWin32Error(HWND hWndOwner) diff --git a/reactos/dll/cpl/sysdm/hardware.c b/reactos/dll/cpl/sysdm/hardware.c index 349afdc79c6..14a24ad5959 100644 --- a/reactos/dll/cpl/sysdm/hardware.c +++ b/reactos/dll/cpl/sysdm/hardware.c @@ -25,12 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" typedef BOOL (STDCALL *PDEVMGREXEC)(HWND hWndParent, HINSTANCE hInst, PVOID Unknown, int nCmdShow); BOOL LaunchDeviceManager(HWND hWndParent) diff --git a/reactos/dll/cpl/sysdm/sysdm.h b/reactos/dll/cpl/sysdm/precomp.h similarity index 59% rename from reactos/dll/cpl/sysdm/sysdm.h rename to reactos/dll/cpl/sysdm/precomp.h index 1bf21fcc1d4..bb4622063fa 100644 --- a/reactos/dll/cpl/sysdm/sysdm.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -1,33 +1,56 @@ -#ifndef __CPL_SYSDM_H -#define __CPL_SYSDM_H - -typedef LONG (CALLBACK *APPLET_INITPROC)(VOID); - -typedef struct -{ - int idIcon; - int idName; - int idDescription; - APPLET_INITPROC AppletProc; -} APPLET, *PAPPLET; - -extern HINSTANCE hApplet; - -void ShowLastWin32Error(HWND hWndOwner); - -INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK ComputerPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK HardwarePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK AdvancedPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK UserProfilePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -/* environment.c */ -INT_PTR CALLBACK EnvironmentDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -/* virtmem.c */ -INT_PTR CALLBACK VirtMemDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - - -#endif /* __CPL_SYSDM_H */ - -/* EOF */ +#ifndef __CPL_PRECOMP_H +#define __CPL_PRECOMP_H + +#include +#include +#include +#include +#include +#include "resource.h" + +#define NUM_APPLETS (1) + +typedef LONG (CALLBACK *APPLET_INITPROC)(VOID); + +typedef struct _APPLET +{ + int idIcon; + int idName; + int idDescription; + APPLET_INITPROC AppletProc; +} APPLET, *PAPPLET; + +extern HINSTANCE hApplet; + +void ShowLastWin32Error(HWND hWndOwner); + +INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK ComputerPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK HardwarePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK AdvancedPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK UserProfilePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +INT_PTR CALLBACK EnvironmentDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK VirtMemDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +typedef struct _PAGEFILE +{ + TCHAR szDrive[3]; + INT InitialValue; + INT MaxValue; + BOOL bUsed; +} PAGEFILE, *PPAGEFILE; + +typedef struct _VIRTMEM +{ + HWND hSelf; + HWND hListView; + LPTSTR szPagingFiles; + TCHAR szDrive[10]; + INT Count; + BOOL bSave; + PAGEFILE Pagefile[26]; +} VIRTMEM, *PVIRTMEM; + + +#endif /* __CPL_SYSDM_H */ diff --git a/reactos/dll/cpl/sysdm/sysdm.c b/reactos/dll/cpl/sysdm/sysdm.c index f17b02fd585..11c4263caf0 100644 --- a/reactos/dll/cpl/sysdm/sysdm.c +++ b/reactos/dll/cpl/sysdm/sysdm.c @@ -25,14 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include -#include -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" #define NUM_APPLETS (1) diff --git a/reactos/dll/cpl/sysdm/sysdm.def b/reactos/dll/cpl/sysdm/sysdm.def index f4110df42fa..1feaf5fb76f 100644 --- a/reactos/dll/cpl/sysdm/sysdm.def +++ b/reactos/dll/cpl/sysdm/sysdm.def @@ -1,6 +1,6 @@ LIBRARY sysdm.cpl EXPORTS -CPlApplet@16 +CPlApplet ; EOF diff --git a/reactos/dll/cpl/sysdm/userprofile.c b/reactos/dll/cpl/sysdm/userprofile.c index 3c2ebe9b36c..91b6d4bedde 100644 --- a/reactos/dll/cpl/sysdm/userprofile.c +++ b/reactos/dll/cpl/sysdm/userprofile.c @@ -25,10 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include "resource.h" -#include "sysdm.h" + +#include "precomp.h" /* Property page dialog callback */ INT_PTR CALLBACK diff --git a/reactos/dll/cpl/sysdm/virtmem.c b/reactos/dll/cpl/sysdm/virtmem.c index 6fd33a47663..0c1c055b112 100644 --- a/reactos/dll/cpl/sysdm/virtmem.c +++ b/reactos/dll/cpl/sysdm/virtmem.c @@ -1,735 +1,566 @@ /* -* ReactOS -* Copyright (C) 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* $Id$ -* -* PROJECT: ReactOS System Control Panel -* FILE: lib/cpl/sysdm/virtmem.c -* PURPOSE: pagefile settings -* PROGRAMMER: Christian Wallukat cwallukat(at)gmx(dot)at -*/ + * PROJECT: ReactOS system properties, control panel applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/virtual.c + * PURPOSE: Virtual memory control dialog + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ -#include -#include -#include -#include -#include "resource.h" -#include "sysdm.h" -#include -#include +#include "precomp.h" +static LPCTSTR lpKey = _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"); - -// -// An array of these structs will interally manage system page files -// -typedef struct _sPagefiles +static BOOL +ReadPageFileSettings(PVIRTMEM pVirtMem) { - WCHAR szDrive[10]; - INT nMinValue; - INT nMaxValue; - INT nUsed; -} sPageFiles; + HKEY hkey = NULL; + DWORD dwType; + DWORD dwDataSize; + BOOL bRet = FALSE; + + if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, + lpKey, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_QUERY_VALUE, + NULL, + &hkey, + NULL) == ERROR_SUCCESS) + { + if(RegQueryValueEx(hkey, + _T("PagingFiles"), + NULL, + &dwType, + NULL, + &dwDataSize) == ERROR_SUCCESS) + { + pVirtMem->szPagingFiles = (LPTSTR)HeapAlloc(GetProcessHeap(), + 0, + dwDataSize); + if (pVirtMem->szPagingFiles != NULL) + { + if(RegQueryValueEx(hkey, + _T("PagingFiles"), + NULL, + &dwType, + (PBYTE)pVirtMem->szPagingFiles, + &dwDataSize) == ERROR_SUCCESS) + { + bRet = TRUE; + } + } + + } + } + + if (!bRet) + ShowLastWin32Error(pVirtMem->hSelf); + + if (hkey != NULL) + RegCloseKey(hkey); + + return bRet; +} +static INT +GetPageFileSizes(LPTSTR lpPageFiles) +{ + while (*lpPageFiles != _T('\0')) + { + if (*lpPageFiles == _T(' ')) + { + lpPageFiles++; + return (INT)_ttoi(lpPageFiles); + } -// -// At most there can be 32 drives, so only 32 page files -// -sPageFiles g_sPagefile[32]; -// -// This is the number of drives that could have page files -// -INT g_nCount; -// -// Will save the user set action signal saving to the registry on exit -// -BOOL g_bSave; + lpPageFiles++; + } + + return -1; +} -// -// ReadRegSettings reads the page file settings from the regisrty -// -VOID ReadRegSettings(HWND hwndDlg); -// -// ParseMemSettings takes the regisrty string and create the internal page file array -// -VOID ParseMemSettings(TCHAR *szSettings, HWND hwndDlg); -// -// SaveSettings writes the paging file array to the registry -// -VOID SaveSettings(HWND hwndDlg); +static VOID +ParseMemSettings(PVIRTMEM pVirtMem) +{ + TCHAR szDrives[1024]; // all drives + LPTSTR DrivePtr = szDrives; + TCHAR szDrive[MAX_PATH]; // single drive + TCHAR szVolume[MAX_PATH]; + INT InitialSize = 0; + INT MaxSize = 0; + INT DriveLen; + INT PgCnt = 0; -// -// Callback function for messages for the windows -// -INT_PTR -CALLBACK -VirtMemDlgProc(HWND hwndDlg, - UINT uMsg, + DriveLen = GetLogicalDriveStrings(1023, + szDrives); + + while (DriveLen != 0) + { + LVITEM Item; + INT Len; + + Len = lstrlen(DrivePtr) + 1; + DriveLen -= Len; + + DrivePtr = _tcsupr(DrivePtr); + + /* copy the 'X:' portion */ + lstrcpyn(szDrive, DrivePtr, 3); + + if(GetDriveType(DrivePtr) == DRIVE_FIXED) + { + /* does drive match the one in the registry ? */ + if(!_tcsncmp(pVirtMem->szPagingFiles, szDrive, 2)) + { + /* FIXME: we only check the first available pagefile in the reg */ + InitialSize = GetPageFileSizes(pVirtMem->szPagingFiles); + MaxSize = GetPageFileSizes(pVirtMem->szPagingFiles); + + pVirtMem->Pagefile[PgCnt].InitialValue = InitialSize; + pVirtMem->Pagefile[PgCnt].MaxValue = MaxSize; + pVirtMem->Pagefile[PgCnt].bUsed = TRUE; + lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); + } + else + { + pVirtMem->Pagefile[PgCnt].InitialValue = 0; + pVirtMem->Pagefile[PgCnt].MaxValue = 0; + pVirtMem->Pagefile[PgCnt].bUsed = FALSE; + lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); + } + + /* fill out the listview */ + ZeroMemory(&Item, sizeof(Item)); + Item.mask = LVIF_TEXT; + Item.iItem = ListView_GetItemCount(pVirtMem->hListView); + Item.pszText = szDrive; + Item.iItem = ListView_InsertItem(pVirtMem->hListView, &Item); + + /* set a volume label if there is one */ + if (GetVolumeInformation(DrivePtr, + szVolume, + 255, + NULL, + NULL, + NULL, + NULL, + 0)) + { + if (szVolume != _T('\0')) + { + TCHAR szVol[MAX_PATH + 2]; + + wsprintf(szVol, _T("[%s]"), szVolume); + + Item.iSubItem = 1; + Item.pszText = szVol; + ListView_InsertItem(pVirtMem->hListView, &Item); + } + } + + if ((InitialSize != 0) || (MaxSize != 0)) + { + TCHAR szSize[64]; + + wsprintf(szSize, _T("%i - %i"), InitialSize, MaxSize); + + Item.iSubItem = 2; + Item.pszText = szSize; + ListView_InsertItem(pVirtMem->hListView, &Item); + } + + PgCnt++; + } + + DrivePtr += Len; + } + + pVirtMem->Count = PgCnt; +} + + +static VOID +WritePageFileSettings(PVIRTMEM pVirtMem) +{ + HKEY hk = NULL; + TCHAR szPagingFiles[2048]; + INT i; + INT nPos = 0; + BOOL bErr = TRUE; + + for(i = 0; i < pVirtMem->Count; ++i) + { + if(pVirtMem->Pagefile[i].bUsed) + { + TCHAR szText[256]; + + wsprintf(szText, _T("%s\\pagefile.sys %i %i"), + pVirtMem->Pagefile[i].szDrive, + pVirtMem->Pagefile[i].InitialValue, + pVirtMem->Pagefile[i].MaxValue); + + /* Add it to our overall registry string */ + lstrcat(szPagingFiles + nPos, szText); + + /* Record the position where the next string will start */ + nPos += (INT)lstrlen(szText) + 1; + + /* add another NULL for REG_MULTI_SZ */ + szPagingFiles[nPos] = _T('\0'); + nPos++; + } + } + + if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, + lpKey, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + NULL, + &hk, + NULL) == ERROR_SUCCESS) + { + if (RegSetValueEx(hk, + _T("PagingFiles"), + 0, + REG_MULTI_SZ, + (LPBYTE) szPagingFiles, + (DWORD) nPos * sizeof(TCHAR))) + { + bErr = FALSE; + } + + RegCloseKey(hk); + } + + if (bErr) + ShowLastWin32Error(pVirtMem->hSelf); +} + + +static VOID +SetListViewColumns(HWND hwndListView) +{ + RECT rect; + LV_COLUMN lvc; + + GetClientRect(hwndListView, &rect); + + (void)ListView_SetExtendedListViewStyle(hwndListView, + LVS_EX_FULLROWSELECT); + + ZeroMemory(&lvc, sizeof(lvc)); + lvc.mask = LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT; + lvc.fmt = LVCFMT_LEFT; + + lvc.cx = (INT)((rect.right - rect.left) * 0.1); + lvc.iSubItem = 0; + (void)ListView_InsertColumn(hwndListView, 0, &lvc); + + lvc.cx = (INT)((rect.right - rect.left) * 0.3); + lvc.iSubItem = 1; + (void)ListView_InsertColumn(hwndListView, 1, &lvc); + + lvc.cx = (INT)((rect.right - rect.left) * 0.6); + lvc.iSubItem = 2; + (void)ListView_InsertColumn(hwndListView, 2, &lvc); +} + + +static VOID +OnNoPagingFile(PVIRTMEM pVirtMem) +{ + /* Disable the page file custom size boxes */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE); +} + + +static VOID +OnSysManSize(PVIRTMEM pVirtMem) +{ + /* Disable the page file custom size boxes */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE); +} + + +static VOID +OnCustom(PVIRTMEM pVirtMem) +{ + /* Enable the page file custom size boxes */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE); +} + + +static VOID +OnSet(PVIRTMEM pVirtMem) +{ + INT Index; + + pVirtMem->bSave = TRUE; + + Index = (INT)SendDlgItemMessage(pVirtMem->hSelf, + IDC_PAGEFILELIST, + LB_GETCURSEL, + 0, + 0); + + if(Index < pVirtMem->Count) + { + TCHAR szText[255]; + + /* check if custom settings are checked */ + if(SendDlgItemMessage(pVirtMem->hSelf, + IDC_CUSTOM, + BM_GETCHECK, + 0, + 0) == BST_CHECKED) + { + SendDlgItemMessage(pVirtMem->hSelf, + IDC_INITIALSIZE, + WM_GETTEXT, + 254, + (LPARAM)szText); + pVirtMem->Pagefile[Index].InitialValue = _ttoi(szText); + + SendDlgItemMessage(pVirtMem->hSelf, + IDC_MAXSIZE, + WM_GETTEXT, + 254, + (LPARAM)szText); + pVirtMem->Pagefile[Index].MaxValue = _ttoi(szText); + } + else + { + /* set sizes to 0 */ + pVirtMem->Pagefile[Index].InitialValue = pVirtMem->Pagefile[Index].MaxValue = 0; + + // check to see if this drive is used for a paging file + if (SendDlgItemMessage(pVirtMem->hSelf, + IDC_NOPAGEFILE, + BM_GETCHECK, + 0, + 0) == BST_UNCHECKED) + { + pVirtMem->Pagefile[Index].bUsed = TRUE; + } + else + { + pVirtMem->Pagefile[Index].bUsed = FALSE; + } + } + } +} + + +static BOOL +OnSelChange(PVIRTMEM pVirtMem, + LPNMLISTVIEW pnmv) +{ + TCHAR szCustVals[255]; + INT Index; + + Index = (INT)SendDlgItemMessage(pVirtMem->hSelf, + IDC_PAGEFILELIST, + LB_GETCURSEL, + 0, + 0); + + if(Index < pVirtMem->Count) + { + + if(pVirtMem->Pagefile[Index].InitialValue != 0 && + pVirtMem->Pagefile[Index].MaxValue != 0) + { + /* enable and fill the custom values */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE); + + _itot(pVirtMem->Pagefile[Index].InitialValue , szCustVals, 10); + SendDlgItemMessage(pVirtMem->hSelf, + IDC_INITIALSIZE, + WM_SETTEXT, + 0, + (LPARAM)szCustVals); + + _itot(pVirtMem->Pagefile[Index].MaxValue, szCustVals, 10); + SendDlgItemMessage(pVirtMem->hSelf, + IDC_MAXSIZE, + WM_SETTEXT, + 0, + (LPARAM)szCustVals); + + SendDlgItemMessage(pVirtMem->hSelf, + IDC_CUSTOM, + BM_SETCHECK, + 1, + 0); + } + else + { + /* It's not a custom value */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE); + + /* is it system managed */ + if(pVirtMem->Pagefile[Index].bUsed) + { + SendDlgItemMessage(pVirtMem->hSelf, + IDC_SYSMANSIZE, + BM_SETCHECK, + 1, + 0); + } + else + { + SendDlgItemMessage(pVirtMem->hSelf, + IDC_NOPAGEFILE, + BM_SETCHECK, + 1, + 0); + } + } + } + + return TRUE; +} + + +static VOID +OnOk(PVIRTMEM pVirtMem) +{ + if(pVirtMem->bSave == TRUE) + { + WritePageFileSettings(pVirtMem); + } + + if (pVirtMem->szPagingFiles) + HeapFree(GetProcessHeap(), + 0, + pVirtMem->szPagingFiles); + + HeapFree(GetProcessHeap(), + 0, + pVirtMem); +} + + +static VOID +OnCancel(PVIRTMEM pVirtMem) +{ + if (pVirtMem->szPagingFiles) + HeapFree(GetProcessHeap(), + 0, + pVirtMem->szPagingFiles); + + HeapFree(GetProcessHeap(), + 0, + pVirtMem); +} + + +static PVIRTMEM +OnInitDialog(HWND hwnd) +{ + PVIRTMEM pVirtMem = (PVIRTMEM)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(VIRTMEM)); + if (pVirtMem == NULL) + { + EndDialog(hwnd, 0); + } + + pVirtMem->hSelf = hwnd; + pVirtMem->hListView = GetDlgItem(hwnd, IDC_PAGEFILELIST); + pVirtMem->bSave = FALSE; + + SetListViewColumns(pVirtMem->hListView); + + /* Load the pagefile systems from the reg */ + if (ReadPageFileSettings(pVirtMem)) + { + /* Parse our settings and set up dialog */ + ParseMemSettings(pVirtMem); + } + + return pVirtMem; +} + + +INT_PTR CALLBACK +VirtMemDlgProc(HWND hwndDlg, + UINT uMsg, WPARAM wParam, LPARAM lParam) { - SYSTEM_PROCESS_INFORMATION siSysPInfo; - TCHAR szTemp[255]; - INT nIndex = 0; + /* there can only be one instance of this dialog */ + static PVIRTMEM pVirtMem = NULL; - // - // We dont need to look at this part of the message - // UNREFERENCED_PARAMETER(lParam); switch (uMsg) { - case WM_INITDIALOG: - { - // - // We dont save the changes until set is clicked - // - g_bSave = FALSE; - // - // We start with no page files - // - g_nCount = 0; - // - // Clear out the file pagefile - // - g_sPagefile[0].nMaxValue = 0; - g_sPagefile[0].nMinValue = 0; - g_sPagefile[0].nUsed = 0; + case WM_INITDIALOG: + pVirtMem = OnInitDialog(hwndDlg); + break; - // - // Grad the system stats to get some page file into - // - NtQuerySystemInformation(SystemProcessInformation, &siSysPInfo, sizeof(SYSTEM_PROCESS_INFORMATION), NULL); - - // - // Convert the pagefile usage to a string - // - _itow(siSysPInfo.PeakPagefileUsage, szTemp, 10); - - // - // Set pagefle useage to its label - // - SendDlgItemMessage(hwndDlg, IDC_CURRENT, WM_SETTEXT, (WPARAM)0, (LPARAM)szTemp); - - // - // Load the pagefile systems from the reg - // - ReadRegSettings(hwndDlg); - }; - break; - - case WM_COMMAND: + case WM_COMMAND: { switch (LOWORD(wParam)) { - case IDCANCEL: - { - // - // If the user hits cancel we just close and dont save - // + case IDCANCEL: + OnCancel(pVirtMem); EndDialog(hwndDlg, 0); return TRUE; - }; - break; - - case IDOK: - { - // - // Check to make sure that the user hit set and we will save the settings - // - if(g_bSave == TRUE) - { - SaveSettings(hwndDlg); - }; - - // - // Close out the window - // + case IDOK: + OnOk(pVirtMem); EndDialog(hwndDlg, 0); - }; - break; + return TRUE; + case IDC_NOPAGEFILE: + OnNoPagingFile(pVirtMem); + return TRUE; - case IDC_PAGEFILELIST: - { - switch(HIWORD(wParam)) - { - case LBN_SELCHANGE: - { - // - // Get the currently selected page file from the list box - // - nIndex = (INT)SendDlgItemMessage(hwndDlg, IDC_PAGEFILELIST, LB_GETCURSEL, (WPARAM)0, (LPARAM)0); + case IDC_SYSMANSIZE: + OnSysManSize(pVirtMem); + return TRUE; - // - // If the index is in our range then process that page file - // - if(nIndex < g_nCount) - { - // - // Convert the minvalue for the page file - // - _itow(g_sPagefile[nIndex].nMinValue, szTemp, 10); + case IDC_CUSTOM: + OnCustom(pVirtMem); + return TRUE; - // - // Set the min value to its textbox - // - SendDlgItemMessage(hwndDlg, IDC_INITIALSIZE, WM_SETTEXT, (WPARAM)0, (LPARAM)szTemp); - - // - // Convert the max value of the page file to a string - // - _itow(g_sPagefile[nIndex].nMaxValue, szTemp, 10); - - // - // Set the max value to its textbox - // - SendDlgItemMessage(hwndDlg, IDC_MAXSIZE, WM_SETTEXT, (WPARAM)0, (LPARAM)szTemp); - - // - // Figure out what type of page file it is - // - if(g_sPagefile[nIndex].nMinValue == 0 && g_sPagefile[nIndex].nMaxValue == 0) - { - // - // There is either no page file or a system managed page file so we disable custom sizes - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), FALSE); - // - // Check to see if that drive is used for paging - // - if(g_sPagefile[nIndex].nUsed == 1) - { - // - // This is a system managed page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - } - else - { - // - // There is no page file on this drive - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - } - } - else - { - // - // THis is a custom sized page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - // - // We need to allow the user to change the sizes - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), TRUE); - } - }; - }; - break; - }; - }; - break; - - - case IDC_NOPAGEFILE: - { - // - // Set the pagefile to no page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - - // - // Disable the page file custom size boxes - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), FALSE); - }; - break; - - case IDC_SYSMANSIZE: - { - // - // User changed this to a system managed page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - - // - // Disable the page file custom size boxes - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), FALSE); - }; - break; - - case IDC_CUSTOM: - { - // - // User changed this to a cutom sized page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - - // - // The user should be able to change the size of these files - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), TRUE); - }; - break; - - case IDC_SET: - { - // - // The user hit set, so we are clear to save the settings when we are done - // - g_bSave = TRUE; - - // - // Figure out which pagefile we are saving the settings too - // - nIndex = SendDlgItemMessage(hwndDlg, IDC_PAGEFILELIST, LB_GETCURSEL, (WPARAM)0, (LPARAM)0); - - // - // Make sure it isnt out of our range - // - if(nIndex < g_nCount) - { - // - // Check to see what the current user input settings are - // - if(SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) - { - // - // If custom is checked we need to get the min size - // - SendDlgItemMessage(hwndDlg, IDC_INITIALSIZE, WM_GETTEXT, (WPARAM)254, (LPARAM)szTemp); - - // - // Convert the size to an int and save it - // - g_sPagefile[nIndex].nMinValue = _wtoi(szTemp); - - // - // If custom is checked we need to get the max size - // - SendDlgItemMessage(hwndDlg, IDC_MAXSIZE, WM_GETTEXT, (WPARAM)254, (LPARAM)szTemp); - - // - // If custom is checked we need to get the max size - // - g_sPagefile[nIndex].nMaxValue = _wtoi(szTemp); - - } - else - { - // - // If it is no paging file or system then we set the sizes to zero - // - g_sPagefile[nIndex].nMinValue = g_sPagefile[nIndex].nMaxValue = 0; - } - - // - // We check to see if this drive is used for a paging file anymore - // - g_sPagefile[nIndex].nUsed = (SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_UNCHECKED); - - - // - // FIXME: Rebuild the paging list - // - }; - }; - break; - }; - }; + case IDC_SET: + OnSet(pVirtMem); + return TRUE; + } + } break; - case WM_NOTIFY: + case WM_NOTIFY: { - }; + LPNMHDR pnmhdr = (LPNMHDR)lParam; + + switch (pnmhdr->code) + { + case LVN_ITEMCHANGED: + { + LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam; + + OnSelChange(pVirtMem, pnmv); + + } + } + } break; - }; + } return FALSE; -}; - - -VOID -ReadRegSettings(HWND hwndDlg) -{ - HKEY hk = NULL; - DWORD dwType = 0x0; - DWORD dwDataSize = 0x0; - TCHAR szValue[2048]; - - - // - // Open or create this key to read our settings - // - if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, - _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"), - 0x0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_WRITE | KEY_READ, - NULL, - &hk, - NULL) == ERROR_SUCCESS) - { - - // - // Get the size of the data - // - if(RegQueryValueEx(hk, _T("PagingFiles"), 0, &dwType, (PBYTE)NULL, &dwDataSize) == ERROR_SUCCESS) - { - - // - // Read paging file settings from the regisrty - // - if(RegQueryValueEx(hk, _T("PagingFiles"), 0, &dwType, (PBYTE)(LPTSTR)szValue, &dwDataSize) == ERROR_SUCCESS) - { - // - // Parse our settings and set up controls accordingly - // - ParseMemSettings(szValue, hwndDlg); - } - else - { - // - // We had a problem :( - // - OutputDebugString(_T("Err read pagefile\n")); - }; - } - else - { - // - // We had a problem :( - // - OutputDebugString(_T("Err open reg pagefile\n")); - }; - - // - // Close our key - // - RegCloseKey(hk); - }; -}; - - -VOID -ParseMemSettings(TCHAR *szSettings, HWND hwndDlg) -{ - TCHAR szVolName[256]; - TCHAR szDrive[25]; - TCHAR szDrvLst[256]; - TCHAR szTemp[256]; - TCHAR szList[256]; - INT nLastPos = 0; - INT nMinSize = 0; - INT nMaxSize = 0; - INT nTemp = 0; - BOOL bFound = FALSE; - - g_nCount = 0; - - // - // Clear out all our buffers - // - _wcsnset(szTemp, 0, sizeof(szTemp)); - _wcsnset(szVolName, 0, sizeof(szVolName)); - _wcsnset(szDrive, 0, sizeof(szDrive)); - _wcsnset(szList, 0, sizeof(szList)); - - // - // Get a list of all the drives - // - GetLogicalDriveStrings(255, szDrvLst); - - // - // Print out our drives and our reg string - // - OutputDebugString(szDrvLst); - OutputDebugString((TCHAR*)szSettings); - - // - // Loop through all the drives - // - while(TRUE) - { - // - // Copy over the drive letter - // - wsprintf(szDrive, _T("%s"), szDrvLst + nLastPos); - nLastPos += 4; - - // - // We should fixed and removeable drives, no network / cd - // - if(GetDriveType(szDrive) == DRIVE_FIXED || GetDriveType(szDrive) == DRIVE_REMOVABLE) - { - // - // Get some info about out drive - // - GetVolumeInformation(szDrive, (LPTSTR)szVolName, 255, NULL, NULL, NULL, NULL, 0); - - // - // Cut off the Drive letter : - // - szDrive[2] = 0; - - // - // Clear out our vars to prepare to walk page file setting string - // - nTemp = 0; - bFound = FALSE; - - // - // Walk through the list of page files - // - while(TRUE) - { - // - // Copy over a page file setting for a drive skipping already processed ones - // - wsprintf(szTemp, _T("%s"), szSettings + nTemp); - - - // - // Check to see if the drive for the page file setting matches our current drive - // - if(!_tcsnicmp(szTemp,szDrive,1)) - { - // - // Extract the min/max size from the string - // - nMinSize = (INT)(wcsstr(szTemp + 16, _T(" ")) - (szTemp + 16)) + 1; - nMaxSize = _wtoi(szTemp + 16 + nMinSize); - nMinSize = _wtoi(szTemp + 16); - - // - // Fill in the page file settings in the internal array - // - g_sPagefile[g_nCount].nMaxValue = nMaxSize; - g_sPagefile[g_nCount].nMinValue = nMinSize; - g_sPagefile[g_nCount].nUsed = 1; - wsprintf(g_sPagefile[g_nCount].szDrive, _T("%s"), szDrive); - - // - // Add up one more page file found - // - ++g_nCount; - - // - // Indicate that we found a pagefile for this drive - // - bFound = TRUE; - - break; - }; - - // - // Skip passed the just processed drive setting - // - nTemp += _tcslen(szSettings + nTemp) + 1; - - // - // If we are done looking through the page file settings - // or found a matching setting then break out - // - if((_tcslen(szSettings + nTemp) <= 0) || (bFound == TRUE)) - { - break; - }; - }; - - // - // If we found a page file we make a string for the list box with the size - // - if(bFound == TRUE) - { - wsprintf(szList, _T("%s [%s] %i - %i"), szDrive, szVolName, nMinSize, nMaxSize); - } - else - { - // - // Otherwise we make a blank pagefile element to show no page file - // - g_sPagefile[g_nCount].nMaxValue = 0; - g_sPagefile[g_nCount].nMinValue = 0; - g_sPagefile[g_nCount].nUsed = 0; - - // - // Copy over the drive for the blank page file element - // - wsprintf(g_sPagefile[g_nCount].szDrive, _T("%s"), szDrive); - - // - // Add up one for the blank page file - // - ++g_nCount; - - // - // We just show the name of the drive if there is no page file - // - wsprintf(szList, _T("%s [%s]"), szDrive, szVolName); - }; - - // - // Add our string to the page file list - // - SendDlgItemMessage(hwndDlg, IDC_PAGEFILELIST, LB_ADDSTRING, (WPARAM)NULL, (LPARAM)szList); - - // - // Print out the newly added string - // - OutputDebugString(szList); - }; - - // - // Once all drive have finished being processed then we break out - // - if(_tcslen(szDrvLst + nLastPos) <= 0) - { - return; - }; - }; -}; - - -void SaveSettings(HWND hwndDlg) -{ - HKEY hk = NULL; - TCHAR szValue[2048]; - TCHAR szTemp[512]; - INT nCount = 0; - INT nPos = 0; - - // - // Clear out our buffers - // - _wcsnset(szValue, 0, sizeof(szValue)); - _wcsnset(szTemp, 0, sizeof(szTemp)); - - // - // Go through all our internal pagefile records - // - for(nCount = 0; nCount < g_nCount; ++nCount) - { - // - // We only save it to the regisrty if is used - // - if(g_sPagefile[nCount].nUsed == 1) - { - // - // Clear out our temp buffer - // - _wcsnset(szTemp, 0, sizeof(szTemp)); - // - // Copy the path and sizes to our temp buffer for the page file - // - wsprintf(szTemp, _T("%s\\pagefile.sys %i %i"), g_sPagefile[nCount].szDrive, g_sPagefile[nCount].nMinValue, g_sPagefile[nCount].nMaxValue); - - // - // Add it to our overall regisrty string - // - _tcscat(szValue+nPos,szTemp); - - // - // Record the positioon where the next string will be placed in the buffer - // - nPos += _tcslen(szTemp) + 1; - // Add our null chars in to seperate the page files(REG_MULTI_SZ string) - szValue[nPos - 1] = 0; - szValue[nPos] = 0; - }; - }; - - // - // Now that we have page file setting string we open up the key to save it - // - if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, - _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"), - 0x0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hk, - NULL) == ERROR_SUCCESS) - { - // - // We save our page file settings to the PagingFiles value - // - if (RegSetValueEx(hk, - _T("PagingFiles"), - 0, - REG_MULTI_SZ, - (LPBYTE) szValue, - (DWORD) (nPos+2)*sizeof(TCHAR))) - { - // - // We had a problem, so print out a message - // - OutputDebugString(_T("Could not save")); - - // - // Get the error for our last operation - // - _ltow(GetLastError(), szValue, 10); - - // - // Print out the error code - // - OutputDebugString(szValue); - - } - - // - // Close up the regisrty - // - RegCloseKey(hk); - } - else - { - // - // Print out an error that we couldnt open(create) the registry key. - // - OutputDebugString(_T("Could not open key")); - }; -}; - - -/* EOF */ +} From eb39f6f8dc4937ea665216905b964196db591b79 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 14 Sep 2006 16:53:53 +0000 Subject: [PATCH 199/488] translations patch accepted from LMH1 (with small modification from me) See issue #1679 for more details. svn path=/trunk/; revision=24116 --- reactos/base/applications/notepad/lang/No.rc | 204 +++++++++++++++++++ reactos/base/applications/notepad/rsrc.rc | 1 + 2 files changed, 205 insertions(+) create mode 100644 reactos/base/applications/notepad/lang/No.rc diff --git a/reactos/base/applications/notepad/lang/No.rc b/reactos/base/applications/notepad/lang/No.rc new file mode 100644 index 00000000000..06b814a062a --- /dev/null +++ b/reactos/base/applications/notepad/lang/No.rc @@ -0,0 +1,204 @@ +/* + * Notepad (English resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Fil" + BEGIN + MENUITEM "&Ny...", CMD_NEW + MENUITEM "&?ne\tCtrl+O", CMD_OPEN + MENUITEM "&Lagre\tCtrl+S", CMD_SAVE + MENUITEM "Lagre &som...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Side &Innstillinger...", CMD_PAGE_SETUP + MENUITEM "&Utskrift", CMD_PRINT + MENUITEM "U&tskrift innstillinger...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "A&vslutt", CMD_EXIT + END + POPUP "&Rediger" + BEGIN + MENUITEM "&Angre\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Klipp &ut\tCtrl+X", CMD_CUT + MENUITEM "&Kopier\tCtrl+C", CMD_COPY + MENUITEM "&Lim inn\tCtrl+V", CMD_PASTE + MENUITEM "&Slett\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Finn...\tCtrl+F", CMD_SEARCH + MENUITEM "Finn &neste\tF3", CMD_SEARCH_NEXT + MENUITEM "Erstatt\tCtrl+H", CMD_REPLACE + MENUITEM "G?il...\tCtrl+G", CMD_GOTO + MENUITEM SEPARATOR + MENUITEM "Merk &alt\tCtrl+A", CMD_SELECT_ALL + MENUITEM "&Klokkeslett/dato\tF5", CMD_TIME_DATE + END + POPUP "F&ormat" + BEGIN + MENUITEM "&Tekstbryting", CMD_WRAP + MENUITEM "&Skrift...", CMD_FONT + END + POPUP "&Vis" + BEGIN + MENUITEM "Status&linje", CMD_STATUSBAR + END + POPUP "&Hjelp" + BEGIN + MENUITEM "&Emner i hjelp", CMD_HELP_CONTENTS + MENUITEM "&S?", CMD_HELP_SEARCH + MENUITEM "&Hjelp om hjelp", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&Om" CMD_ABOUT + MENUITEM "&Infomasjon", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Side innstillinger" +{ +LTEXT "&Header:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Bunntekst:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Marger:", 0x144, 10, 43,160, 45 +LTEXT "&Venstre:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Topp:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&H?", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Bunn:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", IDOK, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Avbryt", IDCANCEL, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Hjelp", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +/* Dialog `Encoding' */ +DIALOG_ENCODING DIALOG 0, 0, 256, 44 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | + WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Koding" +{ +COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP +LTEXT "Koding:",0x155,5,2,41,12 +COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +LTEXT "Sluttlinje:",0x156,5,20,41,12 +} + +/* Dialog 'Go To' */ +DIALOG_GOTO DIALOG 0,0,165,50 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "G?l linje" +{ +EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Line nummer:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER +DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP +PUSHBUTTON "Avbryt", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Om ReactOS Notisblokk" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notisblokk v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Avslutt",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Side &r" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notisblokk" +STRING_ERROR, "FEIL" +STRING_WARNING, "ADVARSEL" +STRING_INFO, "Informasjon" + +STRING_UNTITLED, "(uten navn)" + +STRING_ALL_FILES, "Alle filer (*.*)" +STRING_TEXT_FILES_TXT, "Tekst filer (*.txt)" + +STRING_TOOLARGE, "Filen '%s' er for stor for notisblokk.\n \ +Vennligst bruk en annen editor." +STRING_NOTEXT, "Du utf?ikke innskrivet tekst. \ +\nVennligst skriv noe og pr?jen" +STRING_DOESNOTEXIST, "Filen '%s'\n eksistere ikke\n\n \ +Vil du opprette en ny fil?" +STRING_NOTSAVED, "Filen '%s'\nhar ikke blitt lagret\n\n \ +Vil du lagre endringen?" +STRING_NOTFOUND, "'%s' ble ikke funnet." +STRING_OUT_OF_MEMORY, "Ikke nok minne for ?ullf?enne \ +oppgaven. \nAvslutt en eller mere applikasjoner for ?ke mengden av \nledig \ +minne." +STRING_CANNOTFIND "Kan ikke finne '%s'" +STRING_ANSI, "ANSI" +STRING_UNICODE, "Unicode" +STRING_UNICODE_BE, "Unicode (big endian)" +STRING_UTF8, "UTF-8" +STRING_CRLF, "Windows" +STRING_LF, "Unix" +STRING_CR, "Mac" +} diff --git a/reactos/base/applications/notepad/rsrc.rc b/reactos/base/applications/notepad/rsrc.rc index 03e02e63bad..dead224b521 100644 --- a/reactos/base/applications/notepad/rsrc.rc +++ b/reactos/base/applications/notepad/rsrc.rc @@ -38,6 +38,7 @@ IDI_NPICON ICON "res/notepad.ico" #include "lang/Hu.rc" #include "lang/It.rc" #include "lang/Ja.rc" +#include "lang/No.rc" #include "lang/Nl.rc" #include "lang/Pl.rc" #include "lang/Pt.rc" From 3e4ab62ccacd424324d07c00dc243e384d493a70 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 14 Sep 2006 17:17:51 +0000 Subject: [PATCH 200/488] 1. move all languages to own folder 2. accepted LMH1 languages patch (with small modification) 3. fixed right sublang on few languages rc files See issue #1685 for more details. svn path=/trunk/; revision=24117 --- reactos/base/system/userinit/{ => lang}/De.rc | 0 reactos/base/system/userinit/{ => lang}/En.rc | 0 reactos/base/system/userinit/{ => lang}/Es.rc | 0 reactos/base/system/userinit/{ => lang}/Gr.rc | 0 reactos/base/system/userinit/{ => lang}/Hu.rc | 2 +- reactos/base/system/userinit/{ => lang}/Ja.rc | 0 reactos/base/system/userinit/lang/No.rc | 12 ++++++++++++ reactos/base/system/userinit/{ => lang}/Ru.rc | 2 +- reactos/base/system/userinit/{ => lang}/Sv.rc | 0 reactos/base/system/userinit/{ => lang}/Uk.rc | 2 +- reactos/base/system/userinit/userinit.rc | 10 +--------- 11 files changed, 16 insertions(+), 12 deletions(-) rename reactos/base/system/userinit/{ => lang}/De.rc (100%) rename reactos/base/system/userinit/{ => lang}/En.rc (100%) rename reactos/base/system/userinit/{ => lang}/Es.rc (100%) rename reactos/base/system/userinit/{ => lang}/Gr.rc (100%) rename reactos/base/system/userinit/{ => lang}/Hu.rc (83%) rename reactos/base/system/userinit/{ => lang}/Ja.rc (100%) create mode 100644 reactos/base/system/userinit/lang/No.rc rename reactos/base/system/userinit/{ => lang}/Ru.rc (85%) rename reactos/base/system/userinit/{ => lang}/Sv.rc (100%) rename reactos/base/system/userinit/{ => lang}/Uk.rc (89%) diff --git a/reactos/base/system/userinit/De.rc b/reactos/base/system/userinit/lang/De.rc similarity index 100% rename from reactos/base/system/userinit/De.rc rename to reactos/base/system/userinit/lang/De.rc diff --git a/reactos/base/system/userinit/En.rc b/reactos/base/system/userinit/lang/En.rc similarity index 100% rename from reactos/base/system/userinit/En.rc rename to reactos/base/system/userinit/lang/En.rc diff --git a/reactos/base/system/userinit/Es.rc b/reactos/base/system/userinit/lang/Es.rc similarity index 100% rename from reactos/base/system/userinit/Es.rc rename to reactos/base/system/userinit/lang/Es.rc diff --git a/reactos/base/system/userinit/Gr.rc b/reactos/base/system/userinit/lang/Gr.rc similarity index 100% rename from reactos/base/system/userinit/Gr.rc rename to reactos/base/system/userinit/lang/Gr.rc diff --git a/reactos/base/system/userinit/Hu.rc b/reactos/base/system/userinit/lang/Hu.rc similarity index 83% rename from reactos/base/system/userinit/Hu.rc rename to reactos/base/system/userinit/lang/Hu.rc index 35a4f7873b8..cb698d1554e 100644 --- a/reactos/base/system/userinit/Hu.rc +++ b/reactos/base/system/userinit/lang/Hu.rc @@ -4,7 +4,7 @@ * Hungarian version is Copyright 2005 - Peter Nagy */ -LANGUAGE LANG_HUNGARIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { diff --git a/reactos/base/system/userinit/Ja.rc b/reactos/base/system/userinit/lang/Ja.rc similarity index 100% rename from reactos/base/system/userinit/Ja.rc rename to reactos/base/system/userinit/lang/Ja.rc diff --git a/reactos/base/system/userinit/lang/No.rc b/reactos/base/system/userinit/lang/No.rc new file mode 100644 index 00000000000..e7960894134 --- /dev/null +++ b/reactos/base/system/userinit/lang/No.rc @@ -0,0 +1,12 @@ +#include "resource.h" +/* Start move all hard code string to En.rc + * By Magnus Olsen 2005 + */ + +LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL +STRINGTABLE DISCARDABLE +{ + +STRING_USERINIT_FAIL, "Userinit mislykket ĺ starte skall!\n" + +} diff --git a/reactos/base/system/userinit/Ru.rc b/reactos/base/system/userinit/lang/Ru.rc similarity index 85% rename from reactos/base/system/userinit/Ru.rc rename to reactos/base/system/userinit/lang/Ru.rc index fe0d6793e57..a06133fee6b 100644 --- a/reactos/base/system/userinit/Ru.rc +++ b/reactos/base/system/userinit/lang/Ru.rc @@ -3,7 +3,7 @@ * By Magnus Olsen 2005 */ -LANGUAGE LANG_RUSSIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { diff --git a/reactos/base/system/userinit/Sv.rc b/reactos/base/system/userinit/lang/Sv.rc similarity index 100% rename from reactos/base/system/userinit/Sv.rc rename to reactos/base/system/userinit/lang/Sv.rc diff --git a/reactos/base/system/userinit/Uk.rc b/reactos/base/system/userinit/lang/Uk.rc similarity index 89% rename from reactos/base/system/userinit/Uk.rc rename to reactos/base/system/userinit/lang/Uk.rc index 757593b03ec..95aa27d836b 100644 --- a/reactos/base/system/userinit/Uk.rc +++ b/reactos/base/system/userinit/lang/Uk.rc @@ -8,7 +8,7 @@ #include "resource.h" -LANGUAGE LANG_UKRAINIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE DISCARDABLE { diff --git a/reactos/base/system/userinit/userinit.rc b/reactos/base/system/userinit/userinit.rc index 4d40f3ada07..a3d1cac4be1 100644 --- a/reactos/base/system/userinit/userinit.rc +++ b/reactos/base/system/userinit/userinit.rc @@ -6,12 +6,4 @@ #define REACTOS_STR_ORIGINAL_FILENAME "userinit.dll\0" #include -#include "De.rc" -#include "En.rc" -#include "Ja.rc" -#include "Sv.rc" -#include "Hu.rc" -#include "Es.rc" -#include "Ru.rc" -#include "Gr.rc" -#include "Uk.rc" +#include "rsrc.rc" From 5f0ec93a17b81cc560a1e0a354404899a170def4 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 14 Sep 2006 17:26:08 +0000 Subject: [PATCH 201/488] translations patch accepted from LMH1 (with small modification from me) See issue #1695 for more details. svn path=/trunk/; revision=24118 --- .../base/applications/imagesoft/lang/No.rc | 200 ++++++++++++++++++ reactos/base/applications/imagesoft/rsrc.rc | 1 + 2 files changed, 201 insertions(+) create mode 100644 reactos/base/applications/imagesoft/lang/No.rc diff --git a/reactos/base/applications/imagesoft/lang/No.rc b/reactos/base/applications/imagesoft/lang/No.rc new file mode 100644 index 00000000000..d10a7ef9aa7 --- /dev/null +++ b/reactos/base/applications/imagesoft/lang/No.rc @@ -0,0 +1,200 @@ +LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL + +IDR_MAINMENU MENU +BEGIN + POPUP "&Fil" + BEGIN + MENUITEM "&Ny...", ID_NEW + MENUITEM "&Ĺpne...", ID_OPEN + MENUITEM SEPARATOR + MENUITEM "&Lukk\tCtrl+F4", ID_CLOSE, GRAYED + MENUITEM "L&ukk alt", ID_CLOSEALL, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Lagre", ID_SAVE, GRAYED + MENUITEM "Lagre &som...", ID_SAVEAS, GRAYED + MENUITEM SEPARATOR + MENUITEM "Utskrift &Forhĺndsvisning", ID_PRINTPRE, GRAYED + MENUITEM "&Utskrift...", ID_PRINT, GRAYED + MENUITEM SEPARATOR + MENUITEM "E&genskaper...", ID_PROP, GRAYED + MENUITEM SEPARATOR + MENUITEM "A&vslutt\tAlt+F4", ID_EXIT + END + POPUP "&Rediger" + BEGIN + MENUITEM "&Angre", ID_UNDO, GRAYED + MENUITEM "&Gjenta", ID_REDO, GRAYED + MENUITEM SEPARATOR + MENUITEM "Klipp &ut", ID_CUT, GRAYED + MENUITEM "&Kopier", ID_COPY, GRAYED + MENUITEM "&Lim inn", ID_PASTE, GRAYED + MENUITEM "lim inn som ny &bilde", ID_PASTENEWIMAGE, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Velg Alt", ID_SELALL, GRAYED + END + POPUP "&Vis" + BEGIN + MENUITEM "&Vertřy", ID_TOOLS, CHECKED + MENUITEM "&Farger", ID_COLOR, CHECKED + MENUITEM "&Historie", ID_HISTORY, CHECKED + MENUITEM "&Statuslinje", ID_STATUSBAR, CHECKED + END + POPUP "&Bilde" + BEGIN + MENUITEM "&Crop...", -1, GRAYED + MENUITEM "&Endre střrrelse ...", -1, GRAYED + MENUITEM "R&oter ...", -1, GRAYED + MENUITEM "&Flip...", -1, GRAYED + MENUITEM "&Strekk...", -1, GRAYED + MENUITEM "S&kew...", -1, GRAYED + MENUITEM "&Inverter Farger", -1, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Attributter...", -1, GRAYED + END + POPUP "&Farger" + BEGIN + MENUITEM "&Rediger farger...", ID_EDITCOLOURS + END + POPUP "&vindu" + BEGIN + MENUITEM "&Cascade", ID_WINDOW_CASCADE + MENUITEM "Sorter &horisontalt", ID_WINDOW_TILE_HORZ + MENUITEM "Sorter &vertikalt", ID_WINDOW_TILE_VERT + MENUITEM "&Ordne Ikoner", ID_WINDOW_ARRANGE + MENUITEM SEPARATOR + MENUITEM "Nes&te\tCtrl+F6", ID_WINDOW_NEXT + END + POPUP "&Hjelp" + BEGIN + MENUITEM "&Om...", ID_ABOUT + END +END + +IDR_POPUP MENU +BEGIN + POPUP "popup" + BEGIN + + MENUITEM SEPARATOR + + END +END + + +IDD_ABOUTBOX DIALOGEX 22,16,210,182 +CAPTION "Om ImageSoft" +FONT 8,"Tahoma",0,0 +STYLE WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME +//EXSTYLE WS_EX_LAYERED +BEGIN + LTEXT "ImageSoft v0.1\nCopyright (C) 2006\nThomas Weidenmueller (w3seek@reactos.org)\nGed Murphy (gedmurphy@gmail.com)", IDC_STATIC, 48, 7, 150, 36 + PUSHBUTTON "Lukk", IDOK, 75, 162, 44, 15 + ICON IDI_IMAGESOFTICON, IDC_STATIC, 10, 10, 7, 30 + EDITTEXT IDC_LICENSE_EDIT, 8, 44, 194, 107, WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | ES_READONLY | ES_MULTILINE +END + + +IDD_IMAGE_PROP DIALOGEX 6, 5, 156, 163 +CAPTION "Bilde egenskaper" +FONT 8,"MS Sans Serif",0,0 +STYLE WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME +BEGIN + LTEXT "Navn:", IDC_STATIC, 12, 5, 38, 9 + EDITTEXT IDC_IMAGE_NAME_EDIT, 58, 3, 94, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP + GROUPBOX "maleri egenskaper", IDC_STATIC, 4, 22, 148, 98 + LTEXT "bilde type:", IDC_STATIC, 12, 36, 42, 9 + CONTROL "", IDC_IMAGETYPE, "ComboBox", WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST, 58, 35, 88, 54 + LTEXT "Lengde:", IDC_STATIC, 12, 51, 42, 9 + EDITTEXT IDC_WIDTH_EDIT, 58, 49, 32, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_NUMBER + LTEXT "", IDC_WIDTH_STAT, 94, 51, 40, 9 + LTEXT "Hřyde:", IDC_STATIC, 12, 68, 42, 9 + EDITTEXT IDC_HEIGHT_EDIT, 58, 66, 32, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_NUMBER + LTEXT "", IDC_HEIGHT_STAT, 94, 68, 40, 9 + LTEXT "Opplřsning:", IDC_STATIC, 12, 84, 42, 9 + EDITTEXT IDC_RES_EDIT, 58, 83, 32, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_NUMBER + LTEXT "", IDC_RES_STAT, 94, 84, 40, 9 + LTEXT "Enhet:", IDC_STATIC, 12, 99, 42, 9 + CONTROL "", IDC_UNIT, "ComboBox", WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST, 58, 99, 54, 50 + LTEXT "bilde střrrelse:", IDC_STATIC, 12, 125, 42, 9 + LTEXT "", IDC_IMAGE_SIZE, 58, 125, 54, 9 + PUSHBUTTON "OK", IDOK, 50, 144, 48, 13 + PUSHBUTTON "Avbryt", IDCANCEL, 102, 144, 48, 13 +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_LICENSE "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." + IDS_READY " Klart." + IDS_TOOLBAR_STANDARD "Standard" + IDS_TOOLBAR_TEST "Test" + IDS_IMAGE_NAME "Bilde %1!u!" + IDS_FLT_TOOLS "Verktřy" + IDS_FLT_COLORS "Farger" + IDS_FLT_HISTORY "Historie" +END + +/* imageprop.c */ +STRINGTABLE DISCARDABLE +BEGIN + IDS_IMAGE_MONOCHROME "Monokromt (1 bit)" + IDS_IMAGE_GREYSCALE "Grĺverdiskala (8 bit)" + IDS_IMAGE_PALETTE "Palett eller 256 farger (8 bit)" + IDS_IMAGE_TRUECOLOR "Nřyaktig farger (24 bit)" + + IDS_UNIT_PIXELS "pikseler" + IDS_UNIT_CM "Cm" + IDS_UNIT_INCHES "tommer" + IDS_UNIT_DOTSCM "Tommer / Cm" + IDS_UNIT_DPI "DPI" + IDS_UNIT_KB "%d KB" + IDS_UNIT_MB "%d MB" +END + +/* Tooltips */ +STRINGTABLE DISCARDABLE +BEGIN + IDS_TOOLTIP_NEW "Ny" + IDS_TOOLTIP_OPEN "Ĺpne" + IDS_TOOLTIP_SAVE "Lagre" + IDS_TOOLTIP_PRINTPRE "Utskrift &Forhĺndsvisning" + IDS_TOOLTIP_PRINT "Utskrift" + IDS_TOOLTIP_CUT "Klipp ut" + IDS_TOOLTIP_COPY "Kopier" + IDS_TOOLTIP_PASTE "Lim inn" + IDS_TOOLTIP_UNDO "Angre" + IDS_TOOLTIP_REDO "Gjenta" +END + + +/* Hints */ +STRINGTABLE DISCARDABLE +BEGIN + IDS_HINT_BLANK " " + IDS_HINT_NEW " Ĺpne et nytt dokument." + IDS_HINT_OPEN " Ĺpene en eksisterende dokument." + IDS_HINT_CLOSE " Lukk dette vinduet." + IDS_HINT_CLOSEALL " Lukk alle vinduer." + IDS_HINT_SAVE " Lagre aktive dokument." + IDS_HINT_SAVEAS " Lagre aktive dokument med nytt navn." + IDS_HINT_PRINTPRE " Forhĺndsvis utskrift." + IDS_HINT_PRINT " Skriv ut aktive dokument." + IDS_HINT_PROP " Vis egenskaper for aktive bilde." + IDS_HINT_EXIT " Avslutt denne applikasjonen." + + IDS_HINT_TOOLS " Vis eller skjul verktřy floating vindu." + IDS_HINT_COLORS " Vis eller skjul fargene floating vindu." + IDS_HINT_HISTORY " Vis eller skjul historie floating vindu." + IDS_HINT_STATUS " Vis eller skjul statuslinje." + + IDS_HINT_CASCADE " Ordne vinduer sĺ de overlapper." + IDS_HINT_TILE_HORZ " Ordne vinduer sĺ ingen-overlapper tittelen." + IDS_HINT_TILE_VERT " Ordne vinduer sĺ ingen-overlapper tittelen." + IDS_HINT_ARRANGE " Ordne ikoner ved knappen av vinduet." + IDS_HINT_NEXT " Aktivere neste vinduet." + + IDS_HINT_SYS_RESTORE " Endre vinduet til normal střrrelse." + IDS_HINT_SYS_MOVE " Flytt vinduet." + IDS_HINT_SYS_SIZE " Endre střrrelse pĺ dette vinduet." + IDS_HINT_SYS_MINIMIZE " Minimer vinduet til en ikon." + IDS_HINT_SYS_MAXIMIZE " Expands dette vindu for ĺ fylle skjermen." +END diff --git a/reactos/base/applications/imagesoft/rsrc.rc b/reactos/base/applications/imagesoft/rsrc.rc index f1127d2d9f0..55c9c574544 100644 --- a/reactos/base/applications/imagesoft/rsrc.rc +++ b/reactos/base/applications/imagesoft/rsrc.rc @@ -9,4 +9,5 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* include localised resources */ #include "lang/En.rc" +#include "lang/No.rc" From e1ba479b2cc90315dd4b75867644fdf53b64d060 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 14 Sep 2006 17:33:25 +0000 Subject: [PATCH 202/488] 1. move all languages to own folder 2. accepted LMH1 languages patch (with small modification) See issue #1696 for more details. svn path=/trunk/; revision=24119 --- .../applications/wordpad/{ => lang}/En.rc | 0 reactos/base/applications/wordpad/lang/No.rc | 169 ++++++++++++++++++ reactos/base/applications/wordpad/rsrc.rc | 6 + reactos/base/applications/wordpad/wordpad.rc | 8 +- 4 files changed, 179 insertions(+), 4 deletions(-) rename reactos/base/applications/wordpad/{ => lang}/En.rc (100%) create mode 100644 reactos/base/applications/wordpad/lang/No.rc create mode 100644 reactos/base/applications/wordpad/rsrc.rc diff --git a/reactos/base/applications/wordpad/En.rc b/reactos/base/applications/wordpad/lang/En.rc similarity index 100% rename from reactos/base/applications/wordpad/En.rc rename to reactos/base/applications/wordpad/lang/En.rc diff --git a/reactos/base/applications/wordpad/lang/No.rc b/reactos/base/applications/wordpad/lang/No.rc new file mode 100644 index 00000000000..cffbabf51fa --- /dev/null +++ b/reactos/base/applications/wordpad/lang/No.rc @@ -0,0 +1,169 @@ +LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL + +IDR_MAINMENU MENU +BEGIN + POPUP "&Fil" + BEGIN + MENUITEM "&Ny...", ID_NEW + MENUITEM "&Ĺpne...", ID_OPEN + MENUITEM SEPARATOR + MENUITEM "&Lukk\tCtrl+F4", ID_CLOSE, GRAYED + MENUITEM "L&ukk alt", ID_CLOSEALL, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Lagre", ID_SAVE, GRAYED + MENUITEM "Lagre &som...", ID_SAVEAS, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Forhĺndsvisning", ID_PRINTPRE, GRAYED + MENUITEM "&Skriv ut...", ID_PRINT, GRAYED + MENUITEM SEPARATOR + MENUITEM "Utskrift &format...", ID_PAGESETUP, GRAYED + MENUITEM SEPARATOR + MENUITEM "A&vslutt\tAlt+F4", ID_EXIT + END + POPUP "&Rediger" + BEGIN + MENUITEM "&Angre", ID_UNDO, GRAYED + MENUITEM "&Gjenta", ID_REDO, GRAYED + MENUITEM SEPARATOR + MENUITEM "Klipp &ut", ID_CUT, GRAYED + MENUITEM "&Kopier", ID_COPY, GRAYED + MENUITEM "&Lim inn", ID_PASTE, GRAYED + MENUITEM SEPARATOR + MENUITEM "Rens", -1, GRAYED + MENUITEM "Merk &alt", ID_SELALL, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Finn...\tCtrl+F",-1, GRAYED + MENUITEM "Finn neste", -1, GRAYED + MENUITEM "Erstatt\tCtrl+H", -1, GRAYED + MENUITEM SEPARATOR + MENUITEM "Objektegenskaper",-1, GRAYED + MENUITEM "Objekt", -1, GRAYED + END + POPUP "&Vis" + BEGIN + MENUITEM "&Verktřylinje", -1, CHECKED + MENUITEM "&Formatlinje", -1, CHECKED + MENUITEM "&Linjal", -1, CHECKED + MENUITEM "&Statuslinje", ID_STATUSBAR, CHECKED + END + POPUP "&Sett inn" + BEGIN + MENUITEM "&Dato og tid...",-1, GRAYED + MENUITEM "&Objekt...", -1, GRAYED + END + POPUP "&Format" + BEGIN + MENUITEM "&Skrift...", -1 GRAYED + MENUITEM "Punktmerking", -1, GRAYED + MENUITEM "Avsnitt...", -1, GRAYED + MENUITEM "Tabulatorer...", -1, GRAYED + END + POPUP "&Vindu" + BEGIN + MENUITEM "&Cascade", ID_WINDOW_CASCADE + MENUITEM "Hele &Horisontalt", ID_WINDOW_TILE_HORZ + MENUITEM "Hele &Vertikalt", ID_WINDOW_TILE_VERT + MENUITEM "&Ordne Ikoner", ID_WINDOW_ARRANGE + MENUITEM SEPARATOR + MENUITEM "Nes&te\tCtrl+F6", ID_WINDOW_NEXT + END + POPUP "&Hjelp" + BEGIN + MENUITEM "&Om...", ID_ABOUT + END +END + +IDR_POPUP MENU +BEGIN + POPUP "popup" + BEGIN + + MENUITEM SEPARATOR + + END +END + + +IDD_NEWDOCSEL DIALOGEX 6,6,159,67 +CAPTION "Ny" +FONT 8, "MS Shell Dlg",0,0 +STYLE WS_BORDER | WS_DLGFRAME | DS_MODALFRAME +BEGIN + LTEXT "Ny dokument Type:", IDC_STATIC, 4, 3, 72, 9 + LISTBOX IDC_LIST, 4, 16, 104, 46, WS_TABSTOP + PUSHBUTTON "&OK", IDOK, 112, 16, 44, 13 + PUSHBUTTON "&Avbryt", IDCANCEL, 112, 33, 44, 13 +END + + +IDD_ABOUTBOX DIALOGEX 22,16,190,182 +CAPTION "Om WordPad" +FONT 8, "MS Shell Dlg",0,0 +STYLE WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME +BEGIN + LTEXT "WordPad II v0.1\nCopyright (C) 2006\nGed Murphy (gedmurphy@gmail.com)", IDC_STATIC, 48, 7, 150, 36 + PUSHBUTTON "Lukk", IDOK, 65, 162, 44, 15 + ICON IDI_ICON, IDC_STATIC, 10, 10, 7, 30 + EDITTEXT IDC_LICENSE_EDIT, 8, 40, 174, 110, WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | ES_READONLY | ES_MULTILINE +END + + +STRINGTABLE DISCARDABLE +BEGIN + IDS_LICENSE "Denne programet er gratis programvare; 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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." + IDS_DEFAULT_NAME "Dokument %1!u!" + IDS_READY " Klar." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_DOC_TYPE_RICH_TEXT "Rik Tekst Dokument" + IDS_DOC_TYPE_UNICODE_TEXT "Tekst Dokument" + IDS_DOC_TYPE_TEXT "Unicode Tekst Dokument" +END + + + +/* Tooltips */ +STRINGTABLE DISCARDABLE +BEGIN + IDS_TOOLTIP_NEW "Ny" + IDS_TOOLTIP_OPEN "Ĺpen" + IDS_TOOLTIP_SAVE "Lagre" + IDS_TOOLTIP_PRINTPRE "Forhĺndsvisning" + IDS_TOOLTIP_PRINT "Skriv ut" + IDS_TOOLTIP_CUT "Klipp ut" + IDS_TOOLTIP_COPY "Kopiere" + IDS_TOOLTIP_PASTE "Paste" + IDS_TOOLTIP_UNDO "Angre" + IDS_TOOLTIP_REDO "Gjenta" +END + +/* Hints */ +STRINGTABLE DISCARDABLE +BEGIN + IDS_HINT_BLANK " " + IDS_HINT_NEW " Opprette et nytt dokument." + IDS_HINT_OPEN " Ĺpene en eksisterende dokument." + IDS_HINT_CLOSE " Lukk dette vinduet." + IDS_HINT_CLOSEALL " Lukk alle vinduer." + IDS_HINT_SAVE " Lagre aktive dokument." + IDS_HINT_SAVEAS " Lagre aktive dokument med nytt navn." + IDS_HINT_PRINT " Skriv ut aktive dokument." + IDS_HINT_PRINTPRE " Forhĺndsvis utskrevet dokument." + IDS_HINT_PAGESETUP " Endre side utsende instillinger." + IDS_HINT_EXIT " Avslutt denne applikasjonen." + + IDS_HINT_CASCADE " Ordne vinduer sĺ de ikke overlapper." + IDS_HINT_TILE_HORZ " Ordne vinduer som de ikke overlapper tittelen." + IDS_HINT_TILE_VERT " Ordne vinduer som de ikke overlapper tittelen." + IDS_HINT_ARRANGE " Ordne ikoner ved knappen av vinduet." + IDS_HINT_NEXT " Aktivere neste vindu." + + IDS_HINT_SYS_RESTORE " Endre vinduet til normal střrrelse." + IDS_HINT_SYS_MOVE " Flytt vinduet." + IDS_HINT_SYS_SIZE " Endre vinduet střrrelse." + IDS_HINT_SYS_MINIMIZE " Endre vinduet til en ikon." + IDS_HINT_SYS_MAXIMIZE " Endre vinduet til ĺ fylle skjermen." +END + diff --git a/reactos/base/applications/wordpad/rsrc.rc b/reactos/base/applications/wordpad/rsrc.rc new file mode 100644 index 00000000000..049e020f12c --- /dev/null +++ b/reactos/base/applications/wordpad/rsrc.rc @@ -0,0 +1,6 @@ +#include +#include +#include "resource.h" + +#include "lang/En.rc" +#include "lang/No.rc" diff --git a/reactos/base/applications/wordpad/wordpad.rc b/reactos/base/applications/wordpad/wordpad.rc index c8ff16a5c76..9a574bb6645 100644 --- a/reactos/base/applications/wordpad/wordpad.rc +++ b/reactos/base/applications/wordpad/wordpad.rc @@ -7,8 +7,6 @@ #define REACTOS_STR_ORIGINAL_FILENAME "wordpad.exe\0" //#include -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - 1 24 DISCARDABLE "manifest.xml" STRINGTABLE DISCARDABLE @@ -22,5 +20,7 @@ IDI_ICON ICON "res/wordpad.ico" /* main toolbar icons */ IDB_TEXTTOOLBAR BITMAP DISCARDABLE "res/toolbar.bmp" -#include "En.rc" -/* please do not add any other languages whilst this is being developed */ +#include "rsrc.rc" + + + From a413ba4de276d00ff2a90a13d4e3c635f5034fd1 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 14 Sep 2006 19:02:56 +0000 Subject: [PATCH 203/488] forget this file thx Quip at irc svn path=/trunk/; revision=24120 --- reactos/base/system/userinit/rsrc.rc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 reactos/base/system/userinit/rsrc.rc diff --git a/reactos/base/system/userinit/rsrc.rc b/reactos/base/system/userinit/rsrc.rc new file mode 100644 index 00000000000..72d81040090 --- /dev/null +++ b/reactos/base/system/userinit/rsrc.rc @@ -0,0 +1,17 @@ + +#include +#include "resource.h" + + +#include "lang/De.rc" +#include "lang/En.rc" +#include "lang/Ja.rc" +#include "lang/Sv.rc" +#include "lang/Hu.rc" +#include "lang/Es.rc" +#include "lang/Ru.rc" +#include "lang/Gr.rc" +#include "lang/Uk.rc" +#include "lang/No.rc" +LANGUAGE LANG_NEUTRAL,SUBLANG_NEUTRAL + From 4732ef2b6acb39a31847889506b72db5807710e0 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 14 Sep 2006 19:09:56 +0000 Subject: [PATCH 204/488] start to overhaul sysdm.cpl and make it more like XP's, which is much more user friendly - completely rewrite the resource file to make it readable and logical - do the same with the resource.h file (I'll cry if anyone messes these 2 up, it's mega neat now ... ;p) - add the ReactOS logo to the first page (general tab) - move the licence to it's own dialog accessable from the general tab - rearrange the computer name and hardware pages - delete the user profile page and add it as a separate dialog accessable from the advanced page - add an error reporting button (as per XP) which opens a web browser directly to bugzilla. - loads of other little alterations. *note, I've dissabled language files until I've finished messing with the resources* svn path=/trunk/; revision=24121 --- reactos/dll/cpl/sysdm/advanced.c | 119 ++++++------ reactos/dll/cpl/sysdm/computer.c | 29 +-- reactos/dll/cpl/sysdm/en.rc | 268 +++++++++++++++------------- reactos/dll/cpl/sysdm/environment.c | 57 +++--- reactos/dll/cpl/sysdm/general.c | 216 ++++++++++++---------- reactos/dll/cpl/sysdm/hardware.c | 29 +-- reactos/dll/cpl/sysdm/licence.c | 81 +++++++++ reactos/dll/cpl/sysdm/precomp.h | 5 +- reactos/dll/cpl/sysdm/resource.h | 155 ++++++++-------- reactos/dll/cpl/sysdm/sysdm.c | 48 ++--- reactos/dll/cpl/sysdm/sysdm.rbuild | 5 + reactos/dll/cpl/sysdm/sysdm.rc | 19 +- reactos/dll/cpl/sysdm/userprofile.c | 67 ++++--- reactos/dll/cpl/sysdm/virtmem.c | 4 +- 14 files changed, 592 insertions(+), 510 deletions(-) create mode 100644 reactos/dll/cpl/sysdm/licence.c diff --git a/reactos/dll/cpl/sysdm/advanced.c b/reactos/dll/cpl/sysdm/advanced.c index 0ecaaebe93b..898c0890abb 100644 --- a/reactos/dll/cpl/sysdm/advanced.c +++ b/reactos/dll/cpl/sysdm/advanced.c @@ -1,66 +1,77 @@ /* - * ReactOS - * Copyright (C) 2004 ReactOS Team + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/advanced.c + * PURPOSE: Memory, start-up and profiles settings + * COPYRIGHT: Copyright Thomas Weidenmueller + Copyright 2006 Ged Murphy * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * - * PROJECT: ReactOS System Control Panel - * FILE: lib/cpl/system/advanced.c - * PURPOSE: Memory, start-up and profiles settings - * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) - * UPDATE HISTORY: - * 03-04-2004 Created */ #include "precomp.h" +static TCHAR BugLink[] = _T("http://www.reactos.org/bugzilla"); + /* Property page dialog callback */ INT_PTR CALLBACK -AdvancedPageProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) +AdvancedPageProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { - UNREFERENCED_PARAMETER(lParam); - switch (uMsg) - { - case WM_INITDIALOG: + UNREFERENCED_PARAMETER(lParam); + + switch (uMsg) + { + case WM_INITDIALOG: + break; + + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDC_PERFOR: + { + DialogBox(hApplet, + MAKEINTRESOURCE(IDD_VIRTMEM), + hwndDlg, + (DLGPROC)VirtMemDlgProc); + } + break; + + case IDC_USERPROFILE: + { + DialogBox(hApplet, + MAKEINTRESOURCE(IDD_USERPROFILE), + hwndDlg, + (DLGPROC)UserProfileDialogProc); + } + break; + + case IDC_ENVVAR: + { + DialogBox(hApplet, + MAKEINTRESOURCE(IDD_ENVIRONMENT_VARIABLES), + hwndDlg, + (DLGPROC)EnvironmentDlgProc); + } + break; + + case IDC_ERRORREPORT: + { + ShellExecute(NULL, + _T("open"), + BugLink, + NULL, + NULL, + SW_SHOWNORMAL); + } + break; + + } + } break; - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDC_PERFOR: - DialogBox(hApplet, - MAKEINTRESOURCE(IDD_VIRTMEM), - hwndDlg, - (DLGPROC) VirtMemDlgProc); - break; - - case IDC_ENVVAR: - DialogBox(hApplet, - MAKEINTRESOURCE(IDD_ENVIRONMENT_VARIABLES), - hwndDlg, - (DLGPROC) EnvironmentDlgProc); - break; - } - break; - - } - return FALSE; + } + return FALSE; } diff --git a/reactos/dll/cpl/sysdm/computer.c b/reactos/dll/cpl/sysdm/computer.c index 1e17de5a5b4..3ddbebc8d3f 100644 --- a/reactos/dll/cpl/sysdm/computer.c +++ b/reactos/dll/cpl/sysdm/computer.c @@ -1,29 +1,10 @@ /* - * ReactOS - * Copyright (C) 2004 ReactOS Team + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/computer.c + * PURPOSE: Computer settings for networking + * COPYRIGHT: Copyright Thomas Weidenmueller * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * - * PROJECT: ReactOS System Control Panel - * FILE: lib/cpl/system/computer.c - * PURPOSE: Computer settings for networking - * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) - * UPDATE HISTORY: - * 03-04-2004 Created */ #include "precomp.h" diff --git a/reactos/dll/cpl/sysdm/en.rc b/reactos/dll/cpl/sysdm/en.rc index fe9378012ef..213750324c3 100644 --- a/reactos/dll/cpl/sysdm/en.rc +++ b/reactos/dll/cpl/sysdm/en.rc @@ -1,147 +1,165 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -RC_LICENSE RTDATA "resources/gpl.txt" - -IDD_PROPPAGEGENERAL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT +IDD_PROPPAGEGENERAL DIALOGEX 0, 0, 256, 218 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "General" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - LTEXT "Operating System",-1,SYSTEM_COLUMN,LABELLINE(2),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING(1),8 - LTEXT REACTOS_STR_PRODUCT_NAME,-1,SYSTEM_COLUMN+PROPSHEETPADDING(1),LABELLINE(3),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING(1),8 - LTEXT "Version "REACTOS_STR_PRODUCT_VERSION,-1,SYSTEM_COLUMN+PROPSHEETPADDING(1),LABELLINE(4),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING(1),8 - - LTEXT "Computer",-1,SYSTEM_COLUMN,LABELLINE(6),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING(1),8 - LTEXT "",IDC_PROCESSORMANUFACTURER,SYSTEM_COLUMN+PROPSHEETPADDING(1),LABELLINE(7),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING(1),8 - LTEXT "",IDC_PROCESSOR,SYSTEM_COLUMN+PROPSHEETPADDING(1),LABELLINE(8),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING(1),8 - LTEXT "",IDC_PROCESSORSPEED,SYSTEM_COLUMN+PROPSHEETPADDING(1),LABELLINE(9),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING(1),8 - LTEXT "",IDC_SYSTEMMEMORY,SYSTEM_COLUMN+PROPSHEETPADDING(1),LABELLINE(10),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING(1),8 - - EDITTEXT IDC_LICENSEMEMO,PROPSHEETPADDING(1),LABELLINE(13),PROPSHEETWIDTH-PROPSHEETPADDING(2),PROPSHEETHEIGHT-LABELLINE(13)-PROPSHEETPADDING(1),ES_LEFT|WS_TABSTOP|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_GROUP|ES_MULTILINE|ES_READONLY + CONTROL "", IDC_ROSIMG, "Static", SS_OWNERDRAW, 4, 5, 248, 111 + LTEXT "System:", IDC_STATIC, 4, 132, 32, 9 +// LTEXT REACTOS_STR_PRODUCT_NAME, IDC_STATIC, 114, 29, 142, 8 +// LTEXT "Version " REACTOS_STR_PRODUCT_VERSION, IDC_STATIC, 114, 38, 142, 8 + LTEXT "Machine:", IDC_STATIC, 124, 132, 34, 9 + LTEXT "", IDC_PROCESSORMANUFACTURER, 130, 144, 118, 9 + LTEXT "", IDC_PROCESSOR, 130, 153, 118, 9 + LTEXT "", IDC_PROCESSORSPEED, 130, 162, 118, 9 + LTEXT "", IDC_SYSTEMMEMORY, 130, 171, 118, 9 + PUSHBUTTON "View licence...", IDC_LICENCE, 78, 199, 78, 13 END -IDD_PROPPAGECOMPUTER DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT +IDD_PROPPAGECOMPUTER DIALOGEX 0, 0, 256, 218 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Network Identification" +CAPTION "Computer Name" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING(1),LABELLINE(1)-5, ICONSIZE, ICONSIZE, SS_ICON - LTEXT "ReactOS uses the following information to identify your computer on the network.",-1,PROPSHEETPADDING(4)+ICONSIZE,LABELLINE(1)-5,PROPSHEETWIDTH-PROPSHEETPADDING(6)-ICONSIZE,LABELLINE(3) - LTEXT "Full computer name:",-1,PROPSHEETPADDING(1),LABELLINE(4)-4,PROPSHEETPADDING(17),LABELLINE(4)-4 - LTEXT "(Default)",IDC_COMPUTERNAME,PROPSHEETPADDING(17),LABELLINE(4)-5,60,LABELLINE(4)-5 - LTEXT "Workgroup:",IDC_WORKGROUPDOMAIN,PROPSHEETPADDING(1),LABELLINE(6)-6,PROPSHEETPADDING(17),LABELLINE(6)-6 - LTEXT "(empty)",IDC_WORKGROUPDOMAIN_NAME,PROPSHEETPADDING(17),LABELLINE(6)-6,60,LABELLINE(6)-6 - LTEXT "To use the Network Identfication Wizard to join a domain and create a local user, click Network ID.",-1,PROPSHEETPADDING(1),LABELLINE(7)+5,PROPSHEETWIDTH-PROPSHEETPADDING(12)-ICONSIZE,LABELLINE(8)+5 - PUSHBUTTON "&Network ID...",IDC_NETWORK_ID,175,LABELLINE(7)+5,70,LABELLINE(1)+4 - LTEXT "To rename this computer or join a domain, click Properties.",-1,PROPSHEETPADDING(1),LABELLINE(11)+2,PROPSHEETWIDTH-PROPSHEETPADDING(12)-ICONSIZE,LABELLINE(12)+2 - PUSHBUTTON "&Properties...",IDC_NETWORK_PROPERTY,175,LABELLINE(11)+2,70,LABELLINE(1)+4 + ICON IDI_DEVMGR, IDC_ICON1, 4, 3, 26, 24, SS_ICON + LTEXT "ReactOS uses the following information to identify your computer on the network.", IDC_STATIC, 40, 5, 204, 20 + LTEXT "Computer Description:", IDC_STATIC, 6, 40, 70, 9 + EDITTEXT IDC_COMPDESC, 98, 38, 146, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Full computer name:", IDC_STATIC, 6, 68, 64, 9 + LTEXT "(Default)", IDC_COMPUTERNAME, 98, 68, 144, 11 + LTEXT "Workgroup:", IDC_WORKGROUPDOMAIN, 6, 84, 64, 9 + LTEXT "(empty)", IDC_WORKGROUPDOMAIN_NAME, 98, 84, 144, 9 + LTEXT "To use the Network Identfication Wizard to join a domain and create a local user, click Network ID.", IDC_STATIC, 6, 108, 172, 24 + PUSHBUTTON "&Network ID...", IDC_NETWORK_ID, 190, 114, 58, 15 + LTEXT "To rename this computer or join a domain, click Properties.", IDC_STATIC, 6, 149, 170, 17 + PUSHBUTTON "&Change...",IDC_NETWORK_PROPERTY, 190, 149, 58, 15 + LTEXT "Note: Only Administrators can change the identification of this computer", IDC_STATIC, 6, 179, 230, 9 END -IDD_PROPPAGEHARDWARE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT + +IDD_PROPPAGEHARDWARE DIALOGEX 0, 0, 256, 218 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Hardware" FONT 8, "MS Shell Dlg", 0, 0, 0x0 -BEGIN - GROUPBOX "Hardware Wizard",-1,PROPSHEETPADDING(1),LABELLINE(1),PROPSHEETWIDTH-PROPSHEETPADDING(2),LABELLINE(6)+PROPSHEETPADDING(1) - LTEXT "The Hardware wizard helps you install, uninstall, repair, unplug, eject, and configure your hardware.",-1,PROPSHEETPADDING(4)+ICONSIZE,LABELLINE(2),PROPSHEETWIDTH-PROPSHEETPADDING(6)-ICONSIZE,LABELLINE(3) - ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING(2),LABELLINE(2), ICONSIZE, ICONSIZE, SS_ICON - PUSHBUTTON "&Hardware Wizard...",IDC_HARDWARE_WIZARD,PROPSHEETWIDTH-PROPSHEETPADDING(17),LABELLINE(5)+2,PROPSHEETPADDING(15),14 - - GROUPBOX "Device Manager",-1,PROPSHEETPADDING(1),LABELLINE(8)+5,PROPSHEETWIDTH-PROPSHEETPADDING(2),LABELLINE(7)+2 - ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING(2),LABELLINE(10)-3,ICONSIZE, ICONSIZE, SS_ICON - LTEXT "The Device Manager lists all the hardware devices installed on your computer. Use the Device Manager to change the properties of any device.",-1,PROPSHEETPADDING(4)+ICONSIZE,LABELLINE(10)-3,PROPSHEETWIDTH-PROPSHEETPADDING(6)-ICONSIZE,LABELLINE(3) - - PUSHBUTTON "&Device Manager...",IDC_HARDWARE_DEVICE_MANAGER,PROPSHEETWIDTH-PROPSHEETPADDING(17),LABELLINE(13)+2,PROPSHEETPADDING(15),14 - - GROUPBOX "Hardware Profiles",-1,PROPSHEETPADDING(1),LABELLINE(16)+3,PROPSHEETWIDTH-PROPSHEETPADDING(2),LABELLINE(6)+PROPSHEETPADDING(1) - ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING(2),LABELLINE(18)-5, ICONSIZE, ICONSIZE, SS_ICON - LTEXT "Hardware profiles provide a way for you to set up and store different hardware configurations.",0,PROPSHEETPADDING(4)+ICONSIZE,LABELLINE(18)-5,PROPSHEETWIDTH-PROPSHEETPADDING(6)-ICONSIZE,LABELLINE(3) - PUSHBUTTON "Hard&ware Profiles...",IDC_HARDWARE_PROFILE,PROPSHEETWIDTH-PROPSHEETPADDING(17),LABELLINE(20)+2,PROPSHEETPADDING(15),14 -END - -IDD_PROPPAGEUSERPROFILE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "User Profiles" -FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING(1),LABELLINE(1), ICONSIZE, ICONSIZE, SS_ICON - LTEXT "User profiles contain desktop settings and other information related to your login. A different profile can be created on each computer you use, or you can select a roaming profile that is the same on every computer you use.",-1,PROPSHEETPADDING(4)+ICONSIZE,LABELLINE(1),PROPSHEETWIDTH-PROPSHEETPADDING(6)-ICONSIZE,LABELLINE(4) - LTEXT "Profiles stored on this computer:",-1,PROPSHEETPADDING(1),LABELLINE(6),PROPSHEETWIDTH-PROPSHEETPADDING(6)-ICONSIZE,LABELLINE(1) - CONTROL "",IDC_USERPROFILE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|WS_BORDER|WS_TABSTOP,PROPSHEETPADDING(1),LABELLINE(8),PROPSHEETWIDTH-PROPSHEETPADDING(2),LABELLINE(11),WS_EX_CLIENTEDGE - - PUSHBUTTON "Delete",IDC_USERPROFILE_DELETE,PROPSHEETPADDING(1),LABELLINE(20),60,LABELLINE(1)+2 - PUSHBUTTON "Change Type...",IDC_USERPROFILE_CHANGE,(PROPSHEETWIDTH/2)-30,LABELLINE(20),60,LABELLINE(1)+2 - PUSHBUTTON "Copy To...",IDC_USERPROFILE_COPY,PROPSHEETWIDTH-PROPSHEETPADDING(1)-60,LABELLINE(20),60,LABELLINE(1)+2 + GROUPBOX "Device Manager", IDC_STATIC, 6, 7, 244, 61 + ICON IDI_DEVMGR, IDC_ICON1, 12, 18, 23, 21, SS_ICON + LTEXT "The Device Manager lists all the hardware devices installed on your computer. Use the Device Manager to change the properties of any device.", IDC_STATIC, 42, 18, 204, 24 + PUSHBUTTON "&Device Manager...", IDC_HARDWARE_DEVICE_MANAGER, 154, 48, 90, 15 + + GROUPBOX "Hardware Wizard", IDC_STATIC, 6, 79, 244, 61 + ICON IDI_DEVMGR, IDC_ICON1, 12, 90, 23, 21, SS_ICON + LTEXT "The Hardware wizard helps you install, uninstall, repair, unplug, eject, and configure your hardware.", IDC_STATIC, 42, 90, 204, 24 + PUSHBUTTON "&Hardware Wizard...", IDC_HARDWARE_WIZARD, 154, 120, 90, 15 + + GROUPBOX "Hardware Profiles", IDC_STATIC, 6, 149, 244, 61 + ICON IDI_DEVMGR, IDC_ICON1, 12, 160, 23, 21, SS_ICON + LTEXT "Hardware profiles provide a way for you to set up and store different hardware configurations.", IDC_STATIC, 42, 160, 204, 24 + PUSHBUTTON "Hard&ware Profiles...", IDC_HARDWARE_PROFILE, 154, 190, 90, 15 END -IDD_PROPPAGEADVANCED DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT + +IDD_PROPPAGEADVANCED DIALOGEX 0, 0, 256, 218 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Advanced" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - GROUPBOX "Performance",-1,PROPSHEETPADDING(1),LABELLINE(1),PROPSHEETWIDTH-PROPSHEETPADDING(2),LABELLINE(6)+PROPSHEETPADDING(1) - ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING(2),LABELLINE(2), ICONSIZE, ICONSIZE, SS_ICON - LTEXT "Performance options control how applications use memory, which affects the speed of your computer.",-1,PROPSHEETPADDING(4)+ICONSIZE,LABELLINE(2),PROPSHEETWIDTH-PROPSHEETPADDING(6)-ICONSIZE,LABELLINE(3) - PUSHBUTTON "&Performance Options...",IDC_PERFOR,PROPSHEETWIDTH-PROPSHEETPADDING(20),LABELLINE(5)+2,PROPSHEETPADDING(18),14 - GROUPBOX "Environment Variables",-1,PROPSHEETPADDING(1),LABELLINE(8)+2,PROPSHEETWIDTH-PROPSHEETPADDING(2),LABELLINE(6)+PROPSHEETPADDING(1) - ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING(2),LABELLINE(10)-5, ICONSIZE, ICONSIZE, SS_ICON - LTEXT "Environment variables tell your computer where to find certain types of information.",-1,PROPSHEETPADDING(4)+ICONSIZE,LABELLINE(10)-5,PROPSHEETWIDTH-PROPSHEETPADDING(6)-ICONSIZE,LABELLINE(3) - PUSHBUTTON "&Environment Variables...",IDC_ENVVAR,PROPSHEETWIDTH-PROPSHEETPADDING(20),LABELLINE(12)+2,PROPSHEETPADDING(18),14 - GROUPBOX "&Startup and Recovery",-1,PROPSHEETPADDING(1),LABELLINE(15)+3,PROPSHEETWIDTH-PROPSHEETPADDING(2),LABELLINE(6)+PROPSHEETPADDING(1) - ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING(2),LABELLINE(17)-5, ICONSIZE, ICONSIZE, SS_ICON - LTEXT "Startup and recovery options tell your computer how to start and what to do if an error causes your computer to stop.",0,PROPSHEETPADDING(4)+ICONSIZE,LABELLINE(17)-5,PROPSHEETWIDTH-PROPSHEETPADDING(6)-ICONSIZE,LABELLINE(3) - PUSHBUTTON "&Startup and Recovery...",IDC_STAREC,PROPSHEETWIDTH-PROPSHEETPADDING(20),LABELLINE(19)+2,PROPSHEETPADDING(18),14 + LTEXT "You must be logged on as an administrator to make most of these changes.", IDC_STATIC, 12, 5, 236, 8 + GROUPBOX "Performance", IDC_STATIC, 6, 18, 244, 50 + LTEXT "Performance options control how applications use memory, which affects the speed of your computer.", IDC_STATIC, 16, 29, 210, 17 + PUSHBUTTON "Settings", IDC_PERFOR, 194, 48, 50, 15 + + GROUPBOX "User Profiles", IDC_STATIC, 6,75,244,48 + LTEXT "Desktop settings related to your logon", IDC_STATIC, 16, 88, 210, 20 + PUSHBUTTON "Settings", IDC_USERPROFILE, 194, 103, 50, 15 + + GROUPBOX "Startup and Recovery", IDC_STATIC, 6, 131, 244, 52 + LTEXT "Startup and recovery options tell your computer how to start and what to do if an error causes your computer to stop.", IDC_STATIC, 16, 144, 210, 19 + PUSHBUTTON "Settings", IDC_STAREC, 194, 162, 50, 15 + + PUSHBUTTON "Environment Variables", IDC_ENVVAR, 84, 192, 80, 15 + PUSHBUTTON "Error Reporting", IDC_ERRORREPORT, 170, 192, 80, 15 +END + + +IDD_USERPROFILE DIALOGEX 0, 0, 256, 218 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "User Profiles" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + ICON IDI_DEVMGR, IDC_ICON1, 6, 11, 16, 16, SS_ICON + LTEXT "User profiles contain desktop settings and other information related to your login. A different profile can be created on each computer you use, or you can select a roaming profile that is the same on every computer you use.", + IDC_STATIC, 40, 11, 204, 35 + LTEXT "Profiles stored on this computer:", IDC_STATIC, 16, 51, 204, 9 + CONTROL "", IDC_USERPROFILE_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 6, 66, 244, 85, WS_EX_CLIENTEDGE + PUSHBUTTON "Change Type...", IDC_USERPROFILE_CHANGE, 134, 156, 62, 13 + + LTEXT "To create new user accounts, open ", IDC_STATIC, 10, 175, 116, 9 + // FIXME: needs custom control writing + // CONTROL "", IDC_CUST_LINK, "LinkCtlProc", WS_CHILD | VS_VISIBLE | WS_TABSTOP, 127, 175, 60, 9 + LTEXT "in Control Panel.", IDC_STATIC, 184, 175, 64, 9 + + PUSHBUTTON "OK", IDOK, 134, 197, 54, 13 + PUSHBUTTON "Cancel", IDCANCEL, 196, 197, 54, 13 END IDD_VIRTMEM DIALOGEX 6, 6, 223, 248 -STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Virtual Memory" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - CONTROL "",IDC_PAGEFILELIST,"ListBox",0x50010141,10,16,204,52,0x00000200 - LTEXT "Drive [Volume Label]", -1, 12, 5, 96, 9 - LTEXT "Paging File Size (MB)", -1, 114, 5, 100, 9 - CONTROL "Paging file size for selected drive",IDC_DRIVEGROUP,"Button",0x50000007,10,70,204,104 - LTEXT "", IDC_DRIVE, 20, 84, 100, 9 - LTEXT "", IDC_SPACEAVAIL, 20, 94, 112, 8 - CONTROL "Custom size",IDC_CUSTOM,"Button",0x50010009,20,105,54,9 - CONTROL "",IDC_INITIALSIZE,"Edit",0x50010000,100,114,44,13,0x00000200 - CONTROL "",IDC_MAXSIZE,"Edit",0x50010000,100,129,44,13,0x00000200 - LTEXT "Initial size (MB):", -1 ,22,118,54,9 - LTEXT "Maximum size (MB):", -1 ,22,131,64,9 - CONTROL "System managed size",IDC_SYSMANSIZE,"Button",0x50010009,20,145,88,9 - CONTROL "No paging file",IDC_NOPAGEFILE,"Button",0x50010009,20,158,78,9 - PUSHBUTTON "Set",IDC_SET, 158, 155, 50, 13 - CONTROL "Total paging file size for all drives", IDC_TOTALGROUP, "Button", 0x50000007, 10, 179, 204, 46 - PUSHBUTTON "OK", IDOK, 114, 232, 48, 13 - PUSHBUTTON "Cancel", IDCANCEL, 168, 232, 48, 13 - LTEXT "", IDC_MINIMUM, 18, 200, 100, 9 - LTEXT "", IDC_RECOMMENDED, 18, 200, 100, 9 - LTEXT "", IDC_CURRENT, 18, 200, 100, 9 + LTEXT "Drive [Volume Label] Paging File Size (MB)", -1, 12, 5, 96, 9 + CONTROL "", IDC_PAGEFILELIST, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP, + 10, 16, 204, 52, WS_EX_CLIENTEDGE + + GROUPBOX "Paging file size for selected drive", IDC_DRIVEGROUP, 10, 70, 204, 104 + LTEXT "", IDC_DRIVE, 20, 244, 100, 9 + LTEXT "", IDC_SPACEAVAIL, 20, 94, 112, 8 + LTEXT "Initial size (MB):", -1, 22, 118, 54, 9 + LTEXT "Maximum size (MB):", -1, 22, 131, 64, 9 + CONTROL "Custom size", IDC_CUSTOM, "Button", BS_AUTORADIOBUTTON, 20, 105, 54, 9 + CONTROL "System managed size", IDC_SYSMANSIZE, "Button", BS_AUTORADIOBUTTON, 20, 145, 88, 9 + CONTROL "No paging file", IDC_NOPAGEFILE, "Button", BS_AUTORADIOBUTTON, 20, 158, 78,9 + EDITTEXT IDC_INITIALSIZE, 100, 114, 44, 13, NOT WS_BORDER, WS_EX_CLIENTEDGE + EDITTEXT IDC_MAXSIZE, 100, 129, 44, 13, NOT WS_BORDER, WS_EX_CLIENTEDGE + PUSHBUTTON "Set", IDC_SET, 158, 155, 50, 13 + + GROUPBOX "Total paging file size for all drives", IDC_TOTALGROUP, 10, 179, 204, 46 + LTEXT "", IDC_MINIMUM, 18, 200, 100, 9 + LTEXT "", IDC_RECOMMENDED, 18, 200, 100, 9 + LTEXT "", IDC_CURRENT, 18, 200, 100, 9 + + PUSHBUTTON "OK", IDOK, 114, 232, 48, 13 + PUSHBUTTON "Cancel", IDCANCEL, 168, 232, 48, 13 END + IDD_ENVIRONMENT_VARIABLES DIALOGEX 6, 18, 252, 245 STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Environment Variables" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - GROUPBOX "User variables",-1,7,12,238,100 - LTEXT "&Variables:",-1,14,24,224,8 - CONTROL "",IDC_USER_VARIABLE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|LVS_NOSORTHEADER|WS_VSCROLL|WS_HSCROLL|WS_TABSTOP,14,35,224,48,WS_EX_CLIENTEDGE - PUSHBUTTON "&New...",IDC_USER_VARIABLE_NEW,80,90,50,14 - PUSHBUTTON "&Edit...",IDC_USER_VARIABLE_EDIT,134,90,50,14 - PUSHBUTTON "&Delete",IDC_USER_VARIABLE_DELETE,188,90,50,14 - - GROUPBOX "System variables",-1,7,116,238,100 - LTEXT "V&ariables:",-1,14,128,224,8 - CONTROL "",IDC_SYSTEM_VARIABLE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|LVS_NOSORTHEADER|WS_VSCROLL|WS_HSCROLL|WS_TABSTOP,14,139,224,48,WS_EX_CLIENTEDGE - PUSHBUTTON "Ne&w...",IDC_SYSTEM_VARIABLE_NEW,80,194,50,14 - PUSHBUTTON "Ed&it...",IDC_SYSTEM_VARIABLE_EDIT,134,194,50,14 - PUSHBUTTON "De&lete",IDC_SYSTEM_VARIABLE_DELETE,188,194,50,14 - - DEFPUSHBUTTON "OK",IDOK,141,224,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,195,224,50,14 + GROUPBOX "User variables", IDC_STATIC, 7, 12, 238, 100 + LTEXT "&Variables:", IDC_STATIC, 14, 24, 224, 8 + CONTROL "", IDC_USER_VARIABLE_LIST, "SysListView32", + LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOSORTHEADER | + WS_VSCROLL | WS_HSCROLL | WS_TABSTOP, 14, 35, 224, 48, WS_EX_CLIENTEDGE + PUSHBUTTON "&New...", IDC_USER_VARIABLE_NEW, 80, 90, 50, 14 + PUSHBUTTON "&Edit...", IDC_USER_VARIABLE_EDIT, 134, 90, 50, 14 + PUSHBUTTON "&Delete", IDC_USER_VARIABLE_DELETE, 188, 90, 50, 14 + GROUPBOX "System variables", IDC_STATIC, 7, 116, 238, 100 + LTEXT "V&ariables:", IDC_STATIC, 14, 128, 224, 8 + CONTROL "", IDC_SYSTEM_VARIABLE_LIST, "SysListView32", + LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOSORTHEADER | + WS_VSCROLL | WS_HSCROLL | WS_TABSTOP, 14, 139, 224, 48, WS_EX_CLIENTEDGE + PUSHBUTTON "Ne&w...", IDC_SYSTEM_VARIABLE_NEW, 80, 194, 50, 14 + PUSHBUTTON "Ed&it...", IDC_SYSTEM_VARIABLE_EDIT, 134, 194, 50, 14 + PUSHBUTTON "De&lete", IDC_SYSTEM_VARIABLE_DELETE, 188, 194, 50, 14 + PUSHBUTTON "OK", IDOK, 141, 224, 50, 14, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, 195, 224, 50, 14 END @@ -150,23 +168,31 @@ STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_S CAPTION "Edit Variable" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - LTEXT "Variable &Name:",-1,7,14,50,8 - EDITTEXT IDC_VARIABLE_NAME,75,12,145,12,ES_AUTOHSCROLL - LTEXT "Variable &Value:",-1,7,32,50,8 - EDITTEXT IDC_VARIABLE_VALUE,75,30,145,12,ES_AUTOHSCROLL - - DEFPUSHBUTTON "OK",IDOK,116,50,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,170,50,50,14 + LTEXT "Variable &Name:", IDC_STATIC, 7, 14, 50, 8 + EDITTEXT IDC_VARIABLE_NAME, 75, 12, 145, 12, ES_AUTOHSCROLL + LTEXT "Variable &Value:", IDC_STATIC, 7, 32, 50, 8 + EDITTEXT IDC_VARIABLE_VALUE, 75, 30, 145, 12, ES_AUTOHSCROLL + PUSHBUTTON "OK",IDOK,116,50,50,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,170,50,50,14 +END + + +IDD_LICENCE DIALOGEX 6, 6, 267, 142 +CAPTION "Licence" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +STYLE WS_BORDER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +BEGIN + EDITTEXT IDC_LICENCEEDIT, 0, 0, 268, 142, WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | ES_READONLY | ES_MULTILINE END STRINGTABLE DISCARDABLE BEGIN - IDS_CPLSYSTEMNAME "System" - IDS_CPLSYSTEMDESCRIPTION "See information about your computer and change various system and hardware settings." - IDS_DRIVE "Drive: %s" - IDS_SPACE "Space available: %s" - IDS_MIN "Minimum allowed: %s" - IDS_REC "Recommended: %s" - IDS_CUR "Currently allocated: %s" + IDS_CPLSYSTEMNAME "System" + IDS_CPLSYSTEMDESCRIPTION "See information about your computer and change various system and hardware settings." + IDS_DRIVE "Drive: %s" + IDS_SPACE "Space available: %s" + IDS_MIN "Minimum allowed: %s" + IDS_REC "Recommended: %s" + IDS_CUR "Currently allocated: %s" END diff --git a/reactos/dll/cpl/sysdm/environment.c b/reactos/dll/cpl/sysdm/environment.c index e7ba4a5f0f0..3b5b6104b4f 100644 --- a/reactos/dll/cpl/sysdm/environment.c +++ b/reactos/dll/cpl/sysdm/environment.c @@ -1,27 +1,10 @@ /* - * ReactOS - * Copyright (C) 2004 ReactOS Team + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/environment.c + * PURPOSE: Environment variable settings + * COPYRIGHT: Copyright Eric Kohl * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * - * PROJECT: ReactOS System Control Panel - * FILE: lib/cpl/sysdm/environment.c - * PURPOSE: Environment variable settings - * PROGRAMMER: Eric Kohl */ #include "precomp.h" @@ -38,9 +21,9 @@ typedef struct _VARIABLE_DATA INT_PTR CALLBACK EditVariableDlgProc(HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { PVARIABLE_DATA VarData; DWORD dwNameLength; @@ -51,7 +34,7 @@ EditVariableDlgProc(HWND hwndDlg, switch (uMsg) { case WM_INITDIALOG: - SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)lParam); + SetWindowLongPtr(hwndDlg, GWL_USERDATA, (LONG_PTR)lParam); VarData = (PVARIABLE_DATA)lParam; if (VarData->lpName != NULL) @@ -489,15 +472,15 @@ SetAllVars(HWND hwndDlg, lvi.iItem = iItem; /* Open or create the key */ - if (RegCreateKeyEx((iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER), - (iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")), - 0, - NULL, + if (RegCreateKeyEx((iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER), + (iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")), + 0, + NULL, REG_OPTION_NON_VOLATILE, - KEY_WRITE | KEY_READ, - NULL, - &hk, - NULL)) + KEY_WRITE | KEY_READ, + NULL, + &hk, + NULL)) { return; } @@ -518,9 +501,9 @@ SetAllVars(HWND hwndDlg, 0, Type, (LPBYTE) VarData->lpRawValue, - (DWORD) (_tcsclen(VarData->lpRawValue)* sizeof(TCHAR))+1)) + (DWORD) (_tcslen(VarData->lpRawValue)* sizeof(TCHAR))+1)) // was _tcsclen. lstrlen? { - RegCloseKey(hk); + RegCloseKey(hk); return; } } @@ -596,7 +579,7 @@ EnvironmentDlgProc(HWND hwndDlg, if (phdr->idFrom == IDC_USER_VARIABLE_LIST || phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST) { - OnEditVariable(hwndDlg, phdr->idFrom); + OnEditVariable(hwndDlg, (INT)phdr->idFrom); return TRUE; } } diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index b0dffe56510..c2357575bc5 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -1,132 +1,152 @@ /* - * ReactOS - * Copyright (C) 2004 ReactOS Team + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/general.c + * PURPOSE: General System Information + * COPYRIGHT: Copyright Thomas Weidenmueller + * Copyright 2006 Ged Murphy * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * - * PROJECT: ReactOS System Control Panel - * FILE: lib/cpl/system/general.c - * PURPOSE: General System Information - * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) - * UPDATE HISTORY: - * 03-04-2004 Created */ + #include "precomp.h" +typedef struct _IMGINFO +{ + HBITMAP hBitmap; + INT cxSource; + INT cySource; +} IMGINFO, *PIMGINFO; + + void ShowLastWin32Error(HWND hWndOwner) { LPTSTR lpMsg; DWORD LastError; - + LastError = GetLastError(); - - if((LastError == 0) || !FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, NULL, LastError, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)&lpMsg, 0, - NULL)) + + if((LastError == 0) || + !FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + LastError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&lpMsg, + 0, + NULL)) { return; } - + MessageBox(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR); - + LocalFree((LPVOID)lpMsg); } -typedef struct + +static VOID +InitImageInfo(PIMGINFO ImgInfo) { - HWND hDlg; -} OSITINFO, *POSITINFO; + BITMAP bitmap; + + ZeroMemory(ImgInfo, sizeof(*ImgInfo)); + + ImgInfo->hBitmap = LoadImage(hApplet, + MAKEINTRESOURCE(IDB_ROSBMP), + IMAGE_BITMAP, + 0, + 0, + LR_DEFAULTCOLOR); + + if (ImgInfo->hBitmap != NULL) + { + GetObject(ImgInfo->hBitmap, sizeof(BITMAP), &bitmap); + + ImgInfo->cxSource = bitmap.bmWidth; + ImgInfo->cySource = bitmap.bmHeight; + } +} + DWORD WINAPI -ObtainSystemInformationThread(POSITINFO posit) +GetSystemInformation(HWND hwnd) { - HRSRC hResInfo; - HGLOBAL hResMem; - WCHAR *LicenseText; - - /* wait a bit */ - Sleep(100); - - /* load license from resource */ - if(!(hResInfo = FindResource(hApplet, MAKEINTRESOURCE(RC_LICENSE), - MAKEINTRESOURCE(RTDATA))) || - !(hResMem = LoadResource(hApplet, hResInfo)) || - !(LicenseText = LockResource(hResMem))) - { - ShowLastWin32Error(posit->hDlg); - goto LoadSystemInfo; - } - /* insert the license into the edit control (unicode!) */ - SetDlgItemText(posit->hDlg, IDC_LICENSEMEMO, LicenseText); - SendDlgItemMessage(posit->hDlg, IDC_LICENSEMEMO, EM_SETSEL, 0, 0); - - LoadSystemInfo: - /* FIXME */ - /*free:*/ - HeapFree(GetProcessHeap(), 0, posit); - + UNREFERENCED_PARAMETER(hwnd); + return 0; } + /* Property page dialog callback */ INT_PTR CALLBACK -GeneralPageProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) +GeneralPageProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { - UNREFERENCED_PARAMETER(lParam); - UNREFERENCED_PARAMETER(wParam); + static IMGINFO ImgInfo; - switch(uMsg) - { - case WM_INITDIALOG: + UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(wParam); + + switch(uMsg) { - HANDLE Thread; - DWORD ThreadId; - POSITINFO posit; - - posit = (POSITINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OSITINFO)); - if(!posit) - { - ShowLastWin32Error(hwndDlg); - return FALSE; - } - posit->hDlg = hwndDlg; - Thread = CreateThread(NULL, - 0, - (LPTHREAD_START_ROUTINE)ObtainSystemInformationThread, - (PVOID)posit, - 0, - &ThreadId); - if(Thread) - { - CloseHandle(Thread); - return FALSE; - } - - break; + case WM_INITDIALOG: + { + InitImageInfo(&ImgInfo); + GetSystemInformation(hwndDlg); + } + break; + + case WM_COMMAND: + { + if (LOWORD(wParam) == IDC_LICENCE) + { + DialogBox(hApplet, + MAKEINTRESOURCE(IDD_LICENCE), + hwndDlg, + LicenceDialogProc); + + return TRUE; + } + } + break; + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpDrawItem; + lpDrawItem = (LPDRAWITEMSTRUCT) lParam; + if(lpDrawItem->CtlID == IDC_ROSIMG) + { + HDC hdcMem; + LONG left; + + /* position image in centre of dialog */ + left = (lpDrawItem->rcItem.right - ImgInfo.cxSource) / 2; + + hdcMem = CreateCompatibleDC(lpDrawItem->hDC); + if (hdcMem != NULL) + { + SelectObject(hdcMem, ImgInfo.hBitmap); + BitBlt(lpDrawItem->hDC, + left, + lpDrawItem->rcItem.top, + lpDrawItem->rcItem.right - lpDrawItem->rcItem.left, + lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top, + hdcMem, + 0, + 0, + SRCCOPY); + DeleteDC(hdcMem); + } + } + return TRUE; + } + } - } - return FALSE; + + return FALSE; } diff --git a/reactos/dll/cpl/sysdm/hardware.c b/reactos/dll/cpl/sysdm/hardware.c index 14a24ad5959..6f98c2dc8c7 100644 --- a/reactos/dll/cpl/sysdm/hardware.c +++ b/reactos/dll/cpl/sysdm/hardware.c @@ -1,29 +1,10 @@ /* - * ReactOS - * Copyright (C) 2004 ReactOS Team + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/hardware.c + * PURPOSE: Hardware devices + * COPYRIGHT: Copyright Thomas Weidenmueller * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * - * PROJECT: ReactOS System Control Panel - * FILE: lib/cpl/system/hardware.c - * PURPOSE: Hardware devices - * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) - * UPDATE HISTORY: - * 03-04-2004 Created */ #include "precomp.h" diff --git a/reactos/dll/cpl/sysdm/licence.c b/reactos/dll/cpl/sysdm/licence.c new file mode 100644 index 00000000000..733cd01fa7e --- /dev/null +++ b/reactos/dll/cpl/sysdm/licence.c @@ -0,0 +1,81 @@ +/* + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/general.c + * PURPOSE: Licence dialog box message handler + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + + +INT_PTR CALLBACK +LicenceDialogProc(HWND hDlg, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + HRSRC hResInfo; + HGLOBAL hResMem; + WCHAR *LicenseText; + static HICON hIcon; + + UNREFERENCED_PARAMETER(lParam); + + switch (message) + { + case WM_INITDIALOG: + { + hIcon = LoadImage(hApplet, + MAKEINTRESOURCE(IDI_CPLSYSTEM), + IMAGE_ICON, + 16, + 16, + 0); + + SendMessage(hDlg, + WM_SETICON, + ICON_SMALL, + (LPARAM)hIcon); + + /* load license from resource */ + if(!(hResInfo = FindResource(hApplet, + MAKEINTRESOURCE(RC_LICENSE), + MAKEINTRESOURCE(RTDATA))) || + !(hResMem = LoadResource(hApplet, hResInfo)) || + !(LicenseText = LockResource(hResMem))) + { + ShowLastWin32Error(hDlg); + break; + } + + /* insert the license into the edit control (unicode!) */ + SetDlgItemText(hDlg, + IDC_LICENCEEDIT, + LicenseText); + + SendDlgItemMessage(hDlg, + IDC_LICENCEEDIT, + EM_SETSEL, + -1, + 0); + + return TRUE; + } + + case WM_COMMAND: + { + if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) + { + DestroyIcon(hIcon); + EndDialog(hDlg, + LOWORD(wParam)); + return TRUE; + } + } + break; + } + + return FALSE; +} diff --git a/reactos/dll/cpl/sysdm/precomp.h b/reactos/dll/cpl/sysdm/precomp.h index bb4622063fa..973d264883b 100644 --- a/reactos/dll/cpl/sysdm/precomp.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -24,14 +24,17 @@ extern HINSTANCE hApplet; void ShowLastWin32Error(HWND hWndOwner); +/* prop sheet pages */ INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK ComputerPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK HardwarePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK AdvancedPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK UserProfilePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +/* dialogs */ +INT_PTR CALLBACK UserProfileDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK EnvironmentDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK VirtMemDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK LicenceDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); typedef struct _PAGEFILE { diff --git a/reactos/dll/cpl/sysdm/resource.h b/reactos/dll/cpl/sysdm/resource.h index 94546509913..f2fe0364116 100644 --- a/reactos/dll/cpl/sysdm/resource.h +++ b/reactos/dll/cpl/sysdm/resource.h @@ -1,93 +1,106 @@ #ifndef __CPL_RESOURCE_H #define __CPL_RESOURCE_H -/* metrics */ -#define PROPSHEETWIDTH 256 -#define PROPSHEETHEIGHT 218 -#define PROPSHEETPADDING(x) (x+x+x+x+x+x) -#define SYSTEM_COLUMN PROPSHEETPADDING(18) -#define LABELLINE(x) (x+x+x+2+x+x+x+x+x+x) -#define ICONSIZE 16 +#define IDC_STATIC -1 -/* ids */ -#define RC_LICENSE 101 -#define RTDATA 300 +#define IDI_CPLSYSTEM 50 +#define IDI_DEVMGR 51 +#define IDC_ICON1 52 +#define IDB_ROSBMP 53 -#define IDI_CPLSYSTEM 100 -#define IDI_DEVMGR 101 +#define IDS_CPLSYSTEMNAME 60 +#define IDS_CPLSYSTEMDESCRIPTION 61 + +/* propsheet - general */ #define IDD_PROPPAGEGENERAL 100 -#define IDD_PROPPAGECOMPUTER 101 -#define IDD_PROPPAGEHARDWARE 102 -#define IDD_PROPPAGEUSERPROFILE 103 -#define IDD_PROPPAGEADVANCED 104 +#define IDC_PROCESSORMANUFACTURER 101 +#define IDC_PROCESSOR 102 +#define IDC_PROCESSORSPEED 103 +#define IDC_SYSTEMMEMORY 104 +#define IDC_LICENCE 105 +#define IDC_ROSIMG 106 -#define IDS_CPLSYSTEMNAME 1001 -#define IDS_CPLSYSTEMDESCRIPTION 2001 -#define IDS_DRIVE 3000 -#define IDS_SPACE 3001 -#define IDS_MIN 3002 -#define IDS_REC 3003 -#define IDS_CUR 3004 - -/* controls */ -#define IDC_LICENSEMEMO 101 -#define IDC_PROCESSORMANUFACTURER 102 -#define IDC_PROCESSOR 103 -#define IDC_PROCESSORSPEED 104 -#define IDC_SYSTEMMEMORY 105 -#define IDC_DEVMGR 106 -#define IDC_ENVVAR 107 -#define IDC_STAREC 108 -#define IDC_PERFOR 109 -#define IDC_ICON1 201 +/* propsheet - computer name */ +#define IDD_PROPPAGECOMPUTER 200 +#define IDC_COMPDESC 201 #define IDC_COMPUTERNAME 202 #define IDC_WORKGROUPDOMAIN_NAME 203 #define IDC_WORKGROUPDOMAIN 204 #define IDC_NETWORK_ID 205 #define IDC_NETWORK_PROPERTY 206 + + +/* propsheet - hardware */ +#define IDD_PROPPAGEHARDWARE 300 #define IDC_HARDWARE_WIZARD 207 -#define IDC_HARDWARE_PROFILE 210 -#define IDC_HARDWARE_DRIVER_SIGN 211 -#define IDC_HARDWARE_DEVICE_MANAGER 212 +#define IDC_HARDWARE_PROFILE 209 +#define IDC_HARDWARE_DRIVER_SIGN 210 +#define IDC_HARDWARE_DEVICE_MANAGER 211 -#define IDC_USERPROFILE_LIST 213 -#define IDC_USERPROFILE_DELETE 214 -#define IDC_USERPROFILE_CHANGE 215 -#define IDC_USERPROFILE_COPY 216 -#define IDD_ENVIRONMENT_VARIABLES 105 -#define IDC_USER_VARIABLE_LIST 220 -#define IDC_USER_VARIABLE_NEW 221 -#define IDC_USER_VARIABLE_EDIT 222 -#define IDC_USER_VARIABLE_DELETE 223 -#define IDC_SYSTEM_VARIABLE_LIST 224 -#define IDC_SYSTEM_VARIABLE_NEW 225 -#define IDC_SYSTEM_VARIABLE_EDIT 226 -#define IDC_SYSTEM_VARIABLE_DELETE 227 +/* propsheet - advanced */ +#define IDD_PROPPAGEADVANCED 400 +#define IDC_ENVVAR 401 +#define IDC_STAREC 402 +#define IDC_PERFOR 403 +#define IDC_USERPROFILE 404 +#define IDC_ERRORREPORT 405 + + +/* user profiles */ +#define IDD_USERPROFILE 500 +#define IDC_USERPROFILE_LIST 501 +#define IDC_USERPROFILE_CHANGE 503 +#define IDC_CUST_LINK 504 + + +/* environment variables */ +#define IDD_ENVIRONMENT_VARIABLES 600 +#define IDC_USER_VARIABLE_LIST 601 +#define IDC_USER_VARIABLE_NEW 602 +#define IDC_USER_VARIABLE_EDIT 603 +#define IDC_USER_VARIABLE_DELETE 604 +#define IDC_SYSTEM_VARIABLE_LIST 605 +#define IDC_SYSTEM_VARIABLE_NEW 606 +#define IDC_SYSTEM_VARIABLE_EDIT 607 +#define IDC_SYSTEM_VARIABLE_DELETE 608 + + +/* edit environment variables */ +#define IDD_EDIT_VARIABLE 700 +#define IDC_VARIABLE_NAME 701 +#define IDC_VARIABLE_VALUE 702 -#define IDD_EDIT_VARIABLE 106 -#define IDC_VARIABLE_NAME 230 -#define IDC_VARIABLE_VALUE 231 /* Virtual memory */ -#define IDD_VIRTMEM 107 -#define IDC_PAGEFILELIST 240 -#define IDC_DRIVEGROUP 241 -#define IDC_DRIVE 242 -#define IDC_SPACEAVAIL 243 -#define IDC_CUSTOM 244 -#define IDC_INITIALSIZE 245 -#define IDC_MAXSIZE 246 -#define IDC_SYSMANSIZE 247 -#define IDC_NOPAGEFILE 248 -#define IDC_SET 249 -#define IDC_TOTALGROUP 250 -#define IDC_MINIMUM 251 -#define IDC_RECOMMENDED 252 -#define IDC_CURRENT 253 +#define IDD_VIRTMEM 900 +#define IDC_PAGEFILELIST 901 +#define IDC_DRIVEGROUP 902 +#define IDC_DRIVE 903 +#define IDC_SPACEAVAIL 904 +#define IDC_CUSTOM 905 +#define IDC_INITIALSIZE 906 +#define IDC_MAXSIZE 907 +#define IDC_SYSMANSIZE 908 +#define IDC_NOPAGEFILE 909 +#define IDC_SET 910 +#define IDC_TOTALGROUP 911 +#define IDC_MINIMUM 912 +#define IDC_RECOMMENDED 913 +#define IDC_CURRENT 914 +#define IDS_DRIVE 920 +#define IDS_SPACE 921 +#define IDS_MIN 922 +#define IDS_REC 923 +#define IDS_CUR 924 + +/* licence */ +#define IDD_LICENCE 1000 +#define IDC_LICENCEEDIT 1001 +#define RC_LICENSE 1002 +#define RTDATA 1003 + #endif /* __CPL_RESOURCE_H */ - -/* EOF */ diff --git a/reactos/dll/cpl/sysdm/sysdm.c b/reactos/dll/cpl/sysdm/sysdm.c index 11c4263caf0..99aa816c2c7 100644 --- a/reactos/dll/cpl/sysdm/sysdm.c +++ b/reactos/dll/cpl/sysdm/sysdm.c @@ -1,40 +1,19 @@ /* - * ReactOS - * Copyright (C) 2004 ReactOS Team + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/sysdm.c + * PURPOSE: dll entry file + * COPYRIGHT: Copyright Thomas Weidenmueller * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * - * PROJECT: ReactOS System Control Panel - * FILE: lib/cpl/system/sysdm.c - * PURPOSE: ReactOS System Control Panel - * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) - * UPDATE HISTORY: - * 03-04-2004 Created */ #include "precomp.h" -#define NUM_APPLETS (1) - LONG CALLBACK SystemApplet(VOID); HINSTANCE hApplet = 0; /* Applets */ -APPLET Applets[NUM_APPLETS] = +APPLET Applets[NUM_APPLETS] = { {IDI_CPLSYSTEM, IDS_CPLSYSTEMNAME, IDS_CPLSYSTEMDESCRIPTION, SystemApplet} }; @@ -76,7 +55,7 @@ PropSheetProc( return FALSE; } break; - + case PSCB_INITIALIZED: break; } @@ -88,12 +67,12 @@ PropSheetProc( LONG CALLBACK SystemApplet(VOID) { - PROPSHEETPAGE psp[5]; + PROPSHEETPAGE psp[4]; PROPSHEETHEADER psh; TCHAR Caption[1024]; - + LoadString(hApplet, IDS_CPLSYSTEMNAME, Caption, sizeof(Caption) / sizeof(TCHAR)); - + ZeroMemory(&psh, sizeof(PROPSHEETHEADER)); psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE; /* | PSH_USECALLBACK */ @@ -105,13 +84,12 @@ SystemApplet(VOID) psh.nStartPage = 0; psh.ppsp = psp; psh.pfnCallback = NULL; /* PropSheetProc; */ - + InitPropSheetPage(&psp[0], IDD_PROPPAGEGENERAL, (DLGPROC) GeneralPageProc); InitPropSheetPage(&psp[1], IDD_PROPPAGECOMPUTER, (DLGPROC) ComputerPageProc); InitPropSheetPage(&psp[2], IDD_PROPPAGEHARDWARE, (DLGPROC) HardwarePageProc); - InitPropSheetPage(&psp[3], IDD_PROPPAGEUSERPROFILE, (DLGPROC) UserProfilePageProc); - InitPropSheetPage(&psp[4], IDD_PROPPAGEADVANCED, (DLGPROC) AdvancedPageProc); - + InitPropSheetPage(&psp[3], IDD_PROPPAGEADVANCED, (DLGPROC) AdvancedPageProc); + return (LONG)(PropertySheet(&psh) != -1); } diff --git a/reactos/dll/cpl/sysdm/sysdm.rbuild b/reactos/dll/cpl/sysdm/sysdm.rbuild index c5c5d2eeec1..4d9e6bf4b33 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rbuild +++ b/reactos/dll/cpl/sysdm/sysdm.rbuild @@ -7,18 +7,23 @@ 0x600 0x501 + 0x501 kernel32 advapi32 user32 + gdi32 comctl32 netapi32 ntdll msvcrt + msimg32 + shell32 advanced.c computer.c environment.c general.c hardware.c + licence.c sysdm.c userprofile.c virtmem.c diff --git a/reactos/dll/cpl/sysdm/sysdm.rc b/reactos/dll/cpl/sysdm/sysdm.rc index eafe173d936..cfc514d2711 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rc +++ b/reactos/dll/cpl/sysdm/sysdm.rc @@ -1,20 +1,24 @@ -#include "resource.h" -#include "windows.h" - +#include #include +#include "resource.h" LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS System Applet\0" -#define REACTOS_STR_INTERNAL_NAME "sysdm\0" -#define REACTOS_STR_ORIGINAL_FILENAME "sysdm.cpl\0" -#include +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS System Applet\0" +#define REACTOS_STR_INTERNAL_NAME "sysdm\0" +#define REACTOS_STR_ORIGINAL_FILENAME "sysdm.cpl\0" +//#include IDI_CPLSYSTEM ICON "resources/applet.ico" IDI_DEVMGR ICON "resources/devmgr.ico" +IDB_ROSBMP BITMAP "resources/rosbitmap.bmp" + +RC_LICENSE RTDATA "resources/gpl.txt" + #include "en.rc" +/* #include "cz.rc" #include "de.rc" #include "dk.rc" @@ -26,3 +30,4 @@ IDI_DEVMGR ICON "resources/devmgr.ico" #include "hu.rc" #include "ru.rc" #include "uk.rc" +*/ diff --git a/reactos/dll/cpl/sysdm/userprofile.c b/reactos/dll/cpl/sysdm/userprofile.c index 91b6d4bedde..656431437b6 100644 --- a/reactos/dll/cpl/sysdm/userprofile.c +++ b/reactos/dll/cpl/sysdm/userprofile.c @@ -1,49 +1,42 @@ /* - * ReactOS - * Copyright (C) 2004 ReactOS Team + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/userprofile.c + * PURPOSE: Computer settings for networking + * COPYRIGHT: Copyright Thomas Weidenmueller + * Copyright 2006 Ged Murphy * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * - * PROJECT: ReactOS System Control Panel - * FILE: lib/cpl/system/computer.c - * PURPOSE: Computer settings for networking - * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) - * UPDATE HISTORY: - * 03-04-2004 Created */ #include "precomp.h" /* Property page dialog callback */ INT_PTR CALLBACK -UserProfilePageProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) +UserProfileDialogProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { - UNREFERENCED_PARAMETER(lParam); - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(hwndDlg); - switch(uMsg) - { - case WM_INITDIALOG: - break; //GetUserName + UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(hwndDlg); + switch(uMsg) + { + case WM_INITDIALOG: + { + } + break; //GetUserName + + case WM_COMMAND: + { + if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) + { + EndDialog(hwndDlg, + LOWORD(wParam)); + return TRUE; + } + } + break; } return FALSE; } diff --git a/reactos/dll/cpl/sysdm/virtmem.c b/reactos/dll/cpl/sysdm/virtmem.c index 0c1c055b112..ac6acda2f3c 100644 --- a/reactos/dll/cpl/sysdm/virtmem.c +++ b/reactos/dll/cpl/sysdm/virtmem.c @@ -138,7 +138,7 @@ ParseMemSettings(PVIRTMEM pVirtMem) Item.mask = LVIF_TEXT; Item.iItem = ListView_GetItemCount(pVirtMem->hListView); Item.pszText = szDrive; - Item.iItem = ListView_InsertItem(pVirtMem->hListView, &Item); + ListView_InsertItem(pVirtMem->hListView, &Item); /* set a volume label if there is one */ if (GetVolumeInformation(DrivePtr, @@ -367,6 +367,8 @@ OnSelChange(PVIRTMEM pVirtMem, TCHAR szCustVals[255]; INT Index; + UNREFERENCED_PARAMETER(pnmv); + Index = (INT)SendDlgItemMessage(pVirtMem->hSelf, IDC_PAGEFILELIST, LB_GETCURSEL, From da666d1ce5a0430cef224f5c3db417f29cdd8a6f Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 14 Sep 2006 19:12:48 +0000 Subject: [PATCH 205/488] sneaky little blighter svn path=/trunk/; revision=24122 --- reactos/dll/cpl/sysdm/resources/rosbitmap.bmp | Bin 0 -> 164750 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 reactos/dll/cpl/sysdm/resources/rosbitmap.bmp diff --git a/reactos/dll/cpl/sysdm/resources/rosbitmap.bmp b/reactos/dll/cpl/sysdm/resources/rosbitmap.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8a94a6ec9dff917db3ab166e9857e2a9d96d2d37 GIT binary patch literal 164750 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૨$9^m9 z`Z>?&zsi1~%dElc=YF+m(Flxi@70rcZn6*GzG#2IDry*$4|t!A54>L%ErJ9 z{&=b>q%~|hp=-r(%CA(>TuXMB`w|n?0$_fc0mvBiFx0S-I*khu3n;Wklfd=!#_+7< zcf~CuGmHVVb!C?deoL({+C?iEM)~Za-(^f{SQd7z6dQm!vKrrWtdVC&`C_lgy~zHc zM#TjaCvuiVXb+b>sPS zM|_2}Hqr9R()`%q4eK5Hy3HHpwRHH-RpTSJOpoejKEoD+2gXX=a3Hl~ao3jFeru;~ zTRw5~;?XX1zFskX&=Q;8bH{$7`1W10xFFVcupE(}X*0|5-P3kSn zgQoVQ$dP2yQrq56Q@-G2+0-vq*!5X8W58M>Rd~FMMtCeA=i@SkMTimJODUyb9}S8q z2urrdrw;koUwJfcp84ws_8U?hvYSki?5<`(iqiUNEm6@xmYdCo-#mmbZFUG*6 zg%3345=0CM2}!$fk!xZoi7v3p-f5h`-dY9AGc^xoOo0%MRmAcsfy62nX%tshS$qny zzr-IJy`46*L2}ZA&LBC}(aJ=J`gL=ai@{;M3nds0qR{mj$$`E!N86Sw;9XUC*X zd8D5^l#!{rU!++ds4F>?)4~Za>c7SZ0IKwEHn6IV5X&4HR>a1$)LKhSd3&OgUMz53|QL&Tulj_SlxUVORVkQ zefmP}_g_g`$YbG9f9Ej~o2DJ~U7Q@gF8#3Atuvt|mk(5BCD!I9*B72?C`oH7ztnv9 zYD;xyOZAQByVo1aF4g9pDZi1Jm$vWP@u0J@o=IWradbns%=KM6)kFEWlrAruI$+Vn zUURHMQ?`TuVe{qN9Fx8Ty8kuhtM~1``FQ4-Pv6cR*ursem+L;i<)QBL0$iv0uA1nj zXx3xt2vS@G%zd241#OtNZ^x3Ok(<+x1?OfQs?I;xQgywfDeqBh@skJD-+wC|yfkP5 z5;(!Uf|RU*fgTin%C6dK8=BfiOyw-X3MpsKFsnLN#6w|{fhaa`QE54Ri_RtGD~6J# zv`%}=h@W_Kkc3rdDV`AruLw{Tr&&N^$fQ9Y%G~40>PKu!IT5&v=X8DPq8b(*#@;P%rrbZE}G4oe?5v=5(g*J@? zrKMQ3^A+_0F^ZIhX<}7w(lSTZ_y1Gldzsg{J`<`L5&?p5bMgy=f`en@;t&oLxyG%Q z4`57SlXs(IV`~YDsCLlIHTT6u%%L(B+!T*QpsP1KZogNUn;GTf>^^_+j-|uH*4xJJ zSdbjP_HyEmoO9uonTPB0PBfOBZK_Cbsk+))li606-ClpYz5Y&H?Ja?B$%X2i6D3#T zZk-9gl;C$Fa?8PhRblS)SrWL_X`Ji4;VbRG#7Jftki)1Ci9A8JwnP5YX3*Oc2foQM zVZd7x2E0A-%YRND`rfqRA32O+L0_*$lfGDN^Z8<%&*T8Qw!N0v_F8J&Yx&eKR!;A` zX68WGIYTxs_e26d7tPg>-IyX<$>-qy0ls*ruKR+_-QNGwY*Jnsf z8Nz|#1a7nMKLt`78QWxT4c% zCip?3kUosm0B&DAEO7O>D34jkcCE}v@XkFS0ogVdpJ}PQ)LL`By)OG+!=3w0dH0(N z?lx!GKvQCE-(<>sE>d-Z5wO4QavL2JXeF7$V?+q!g|>s&FC!Qq@SJ;?(Z zp#4%nJE8v@3nvm)7ThjTtm|a^ zIk$_@3|FsT-T;~o2y2854#<6(V&t=+9*BOBuX27u^cH8o?V0H7tuhcRL%B_cO zrJiKjD1R55aF020L95Tid1am3S8?ZLV|m8C`s@eIxgBk#kI4N!W<92u#}XQ-szYiK zO{B$I9L;G&f&n(B5Tr^}`S^(wq|M9kR_lbS`DnOWMO6)DFgpVSIYHs_GD05hSW=I{_JY<%vX$o3_p6{QYp2lq5CS$~Tl>9|f~@$^O@1pzg>Rgi5a4(r z&LijS?&{k~O=aiWs$ryCVD&*uVMl9mM{7w(OA-GC$t`!UG!~z~n|-t(eShYOkkpv% z@geIXwk`HwH$(VVq`w?N-W(SSw+mc zrE%MrkM(dG<+gbErUk<`%pJU5FO!%zm;!7pWWUuDi6O`CTygS%$MuvwrCG-tO4IMv zXFY1mf80^|gjF$*WH}3#3s8g%fhF@VAh8Ig`NU-!aXQNHq8XV(o&r&2y#VW4<_&Ri zEzKF3UM?sOa7qd~x1hL0aH|4cJXui+>iS&Gz>KE8r~m4A<*yRgE|O`E>V;3bTu}c? z=Z~tfnZq+)f4PzTGH!qBW*F;Fz4ZrqUE>yG3CU1V?xu_@SGRk5ie#wN88V>{G&=Pd zF|h|jL&FdeLo%v`E`Vs4JLSLf4D|9T3v^*!d|kGpJb7S8sH^RPZL?DLth;$4u>8j1 z=F;=`YcpY_2dza9+sYocmvcO5ExF&Ua9eq$q3G=0?4-hs=o=?PaB(fToetl!{!aMT z3b$e*4|sEYzrT+KtKjyFzl`ejmyx~xGN#WP;|IKDJM^6yBi^UJO5=8k&1aa$%ck}w zC&!0Vc z?qGi37oYvnpLylQe)`36`(nTMzxgemANp9cA{w1%f9djNl0Y|a-3GU4aY+)W?v4Cc zJGX}u62!S}YSqGr8HPG%(z^_sSDp{u`}f&1CjI!nXm&adSbFKu_QLe2hQiYwb=My@ z=R9mJdemP2=ss-_%OA9r;1CMmR%Fx{oUXW;XyMy!@gXh|+ZF|^o96_ z$kx8!Dmh@?foo?Ca+y779ROCxy4mE42Dmu%U*|Bubyok4a|UghKZK%d3N3;+O^@;+ z7PaZpv7o%mhii(`+Uv3&w-xZwS*epUfL^7h&3;1ugT*9P$}lKH^63Cy%3~ zqB3g#{*YavB;nAcmZu|?0)+a{rCspevEz1b9{&~G5;Cl)<_ga~oh}dSmHhAPh1-ki zm*88L4M;p$H4Q>}b0QhS+jm%OKn94n067$GI=9b#@Xtb*Z;@JT>*#1|sLf74ek5e= z@vt@5lXsTih;J#o(18=!Qt+saw!=_vDcsx9l-pj5f16&Hf2uq)UP8*p0#EP9zg@F? z>jLsX?v7(v&BMZX!@nK=K7|(APR6-acJg1x^!^K!JEqTH$Mt(-;=s423}z{xte&TH z&4TegmQ4EG$riHhYmHkd*LgZf?z?gZzHUEYyvDx&+L`@0*2v$!E)MnaAd&SFR5j88FKWl4q=*dy z+KaIjIj5T{ui>AwvjNN5DMY6n*VJ_2@E4iZoKI{PB7EpaLV!{@(b!BKo1444`G5#e ziB^^62VHS1eA|s%b1Gk@lV@<-gjk@?Z{5iu*k;nF;m9Y2-QEYqRb*-sxz(eXs5Yaps1CGgVnh zMd|yqPKKl%^h^qMjq-L3+F^I-J4Y;3JlRMR5>F;B1#U_4W6%O!<7mGRTw`KlN#53}zCpUg=ea?tXQxP@ ztCB-RM_~ZGHFCwsmIRsE8Mv{w_;z~6v5+fA1M<_Ot8z{@mR@Khyj*jw?QVKgacb?I zW1CUXr&f!`SE;j+$P9p6xDq$sy|laTVn zfo}+Up~^?=Z-oWQpfsPgRY z`pu2p^XE5zbyI#Vy_V~0o zv_zr4_Fgf1=ejB39`j;@R-KIAcI9MvL1t2IX+}p&>60h-9+L1;?dfr7CEsIRS)l^C zzh=htXXF7{CD_3&{rbYg!=qzj8k$@6qtSm^Q%N3ZhmQ~IJI7Ihvg>-1-}&gRlr%^0SQ55*rr(;$baHi> zJ%oleG=>lRx2DZu_Y)?R4>JT^$G=f9bYx*fz(JfP*zNILa5%)} zOq|d4)V+l_lj|xnAGFs#e$4(AlI+nT03EvPlBE5W)1^Pgq(RZZ&kQM37scvms;251 zoAlGsf2->1DRQLl0?WwI7ge=V%Jy66{Wp#65B}j-9Jfj=sX_Hdlk(}LJfp;=+t zsh_W&jzcRnO9M)p?9g|THSwWt4hMXllJ;!Am=v6oarkawMq5+)!-uU8AJGdzTKfuY z>Q%4Y=k@jdt<$9+kW@{n1qQ$}K0X15rM97wr-P2r8WucLSiUW8-~s)n z;r)?6{Ho(ttp}nE0Q?ZK#0+C&k-)$pR$vr(!u&?)+dDewS5jNS4tU2-vnt)+G0taUwAcK-^fB8s-G9|Y8p>^)KXmQP z0nT=Pa6}i4?=gSOhXk1jH964STtRpG(0{1oZM$Lr0Li>K^Ba0fNi1rvFfDFv4})eW z3TT&35`q;-ZSyPvM@)RjtHqNATf^M}#^yqd@ zo~NfL%fyI+80!2keEWi8fjA0!4dP{Om#kifA`m$IXJ|yBx4EW_4eR3%1+ETWH`Q;& zXm47&F8XTI+(9lg`>(R=O|WkHt6$Rs?wy&# z-@wxbu9ym9ab^3gbLhW*&Y(>ThEj6OTAu(H z;n@9tPDjEwrXKdoOclg7*Azau-%QJB`ZmFMdRowZSP&`%^;7}l3yZbjR;O@q(jk#Z&SsMAQ#e74Ny6Q@Z%94CCdXxv8v-O(S+1-&GAM!q{|l>D7N z;$1nH&@qUWC=}6S_*o&gC$6lM4Nfcs``Jp;Jk!6Rpkke>TNFRmY2=Po69U&yqa|H5 ztvU8=Jf9G7GcBep?_z6x>BEjzcCuj$AG(F1Wi(VY&0;}tI}$gx)DpgoSU-zfdWPby zs0Gq>(ymN3WU6auqQ4X`5^Yvd!zT2gL=Ar_OZPHk`-6Y?6~`@-LBvu=KE#7+YUSAz zu?&xhfM#jPKsP|7GdC|E+)|Z+BWmT}z98RPKXQ#;#-Kc2Le0`w3F5_(1`^1nY)JFq zeq&t~ZA4QOc89vnU+*w*`J|7RP5gNIq#jOKxf4EK0)N7y5+D9>q5SgQGWOsV6weKqgJ9`jq*;$cCml^*x6GJ!8h-4?L z;MK`dTQ42om4E$MZTYQxZFP?xcFg3hOtyp4ei8g@2RHnp& zK1S~D?m2n+s*mh<)DILEmni@C94@G6bW1$>cX6Mrplf9_H(@hVStYw^=>3P_xAyiH z%A51D=s6b=>E*P|ar9cso510up3v`7o1TvNs}p)?h?356viVf~{e*X+*5v}%FM#XH z>3!DN_j7TeR&lV~!mqY1B}zOY(A93Y`|N$*iw^EwaeVKVOUFWUGLBXkXSOy}Jb+*y zKm7JP*#=2A@A;0sq@UnkD)U%Mjxmq1S(rxa^*t|-6NOu}sss+DM48opwe?UdozU5a zMmP7RsR*TP9^1BExptj$RGuJai&4tIbVzIiF-bbLfi;ClacGwBPpa(cgIlRp=Km1?Icy;e;90<02hT7f;R2-bO8 zZ+zp`Gy1NbX>croF7_qby>;HqGRFs`oSCQA&RP(T-{aZH7di1cmy1J;S zmNO*FvRV_TZ}5eu$bwrV!H)aDD%`_|HyjY38txxqbvP> zA3bKj@4}*@{QP`&0cY2Bw!?Yy?YH#u#s_Ywt12(a&CkAk{o;vp$M+wL4Lr1a>%KtO za4+Y;P4j$QrhBiN!uCJjt8Cd>*WYy}yJkmtEk6*nA#tx~>XF@<=Z_ZN%BU{OZ*HJr ze+xbSQ4QGV^sI+kF*h0-8|hBWu9j@%eeK$H+9ndhMTOz*qvjYYZaKq-6> zm~gLNgRbsZ-}rCB17FegQrdUG*kStu@;&?a?`J|#WGszjizaqOglrj!LAFGasm*$g zjbtYIwZLr`%EikqDk)6LANzuoiSdVIWQ#HX-yPVX%g#J2|;jM^hw(iFoVwZ8mK|YU$RE_p6)8 zOE-Cfs~sKp*!H-cM*PjqP4sK2s;Mrot|+P~&MhstU6P+wR&=YfBPG{Cgt1OmHb8w31>`4g1j=(q#Dl1M;Qp&p_@pFenHWhUp>w1JtGg43!B1 zGa9|z1$i|lM*-Mi;7$x%@vxqppP4l6!bp}*wU~$D*^o&Wz@Ss;=%0DxCTsVY8S161 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 Date: Thu, 14 Sep 2006 20:00:28 +0000 Subject: [PATCH 206/488] thx fireball fixing a spelling fault svn path=/trunk/; revision=24123 --- reactos/boot/bootdata/packages/reactos.dff | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index bdf754ec872..d78742bc0ef 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -133,7 +133,7 @@ dll\keyboard\kbdfr\kbdfr.dll 1 dll\keyboard\kbdgr\kbdgr.dll 1 dll\keyboard\kbdhe\kbdhe.dll 1 dll\keyboard\kbdhu\kbdhu.dll 1 -dll\keyboard\kbdpo\kbdja.dll 1 +dll\keyboard\kbdja\kbdja.dll 1 dll\keyboard\kbdpo\kbdpo.dll 1 dll\keyboard\kbdru\kbdru.dll 1 dll\keyboard\kbdse\kbdse.dll 1 From 7ac40876f4f884564355f8ccf9471f98b6bfb7ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 14 Sep 2006 20:30:35 +0000 Subject: [PATCH 207/488] Report to registry hardware found by Freeloader. See issue #645 for more details. svn path=/trunk/; revision=24124 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 349 +++++++++++++++++++++++++++- 1 file changed, 348 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index a0ef467c557..29e4d25c47b 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -32,6 +32,8 @@ IopSetRootDeviceInstanceData(PDEVICE_NODE DeviceNode); #pragma alloc_text(INIT, IopSetRootDeviceInstanceData) #pragma alloc_text(INIT, PnpInit) #pragma alloc_text(INIT, PnpInit2) +#pragma alloc_text(INIT, IopUpdateRootKey) +#pragma alloc_text(INIT, IopEnumerateDetectedDevices) #endif @@ -175,6 +177,25 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, &Stack); } +typedef struct _INVALIDATE_DEVICE_RELATION_DATA +{ + DEVICE_RELATION_TYPE Type; + PIO_WORKITEM WorkItem; +} INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA; + +static VOID +NTAPI +IoInvalidateDeviceRelationsWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PINVALIDATE_DEVICE_RELATION_DATA Data = Context; + + IopInvalidateDeviceRelations(IopGetDeviceNode(DeviceObject), Data->Type); + IoFreeWorkItem(Data->WorkItem); + ExFreePool(Data); +} + /* * @implemented */ @@ -183,7 +204,27 @@ STDCALL IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type) { - IopInvalidateDeviceRelations(IopGetDeviceNode(DeviceObject), Type); + PIO_WORKITEM WorkItem; + PINVALIDATE_DEVICE_RELATION_DATA Data; + + Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA)); + if (!Data) + return; + WorkItem = IoAllocateWorkItem(DeviceObject); + if (!WorkItem) + { + ExFreePool(Data); + return; + } + + Data->Type = Type; + Data->WorkItem = WorkItem; + + IoQueueWorkItem( + WorkItem, + IoInvalidateDeviceRelationsWorker, + DelayedWorkQueue, + Data); } /* @@ -2549,12 +2590,318 @@ PnpInit(VOID) IopRootDeviceNode->PhysicalDeviceObject); } +static NTSTATUS INIT_FUNCTION +IopEnumerateDetectedDevices( + IN HANDLE hBaseKey, + IN PUNICODE_STRING RelativePath, + IN HANDLE hRootKey, + IN BOOLEAN EnumerateSubKeys) +{ + UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); + UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc"); + UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hDevicesKey = NULL; + HANDLE hDeviceKey = NULL; + HANDLE hLevel1Key, hLevel2Key = NULL; + UNICODE_STRING Level2NameU; + WCHAR Level2Name[5]; + ULONG IndexDevice = 0; + ULONG IndexSubKey; + PKEY_BASIC_INFORMATION pDeviceInformation = NULL; + ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR); + PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL; + ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR); + UNICODE_STRING DeviceName, ValueName; + ULONG RequiredSize; + NTSTATUS Status; + + const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI BIOS"); + UNICODE_STRING HardwareIdPci = RTL_CONSTANT_STRING(L"*PNP0A03"); + static ULONG DeviceIndexPci = 0; + const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController"); + UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501"); + static ULONG DeviceIndexSerial = 0; + const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardPeripheral"); + UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303"); + static ULONG DeviceIndexKeyboard = 0; + const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerPeripheral"); + UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13"); + static ULONG DeviceIndexMouse = 0; + PUNICODE_STRING pHardwareId; + ULONG DeviceIndex = 0; + + InitializeObjectAttributes(&ObjectAttributes, RelativePath, OBJ_KERNEL_HANDLE, hBaseKey, NULL); + Status = ZwOpenKey(&hDevicesKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength); + if (!pDeviceInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + + while (TRUE) + { + Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); + if (Status == STATUS_NO_MORE_ENTRIES) + break; + else if (Status == STATUS_BUFFER_OVERFLOW) + { + ExFreePool(pDeviceInformation); + DeviceInfoLength = RequiredSize; + pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength); + if (!pDeviceInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + IndexDevice++; + + /* Open device key */ + DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength; + DeviceName.Buffer = pDeviceInformation->Name; + InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_KERNEL_HANDLE, hDevicesKey, NULL); + Status = ZwOpenKey( + &hDeviceKey, + KEY_QUERY_VALUE + EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + if (EnumerateSubKeys) + { + IndexSubKey = 0; + while (TRUE) + { + Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); + if (Status == STATUS_NO_MORE_ENTRIES) + break; + else if (Status == STATUS_BUFFER_OVERFLOW) + { + ExFreePool(pDeviceInformation); + DeviceInfoLength = RequiredSize; + pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength); + if (!pDeviceInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + IndexSubKey++; + DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength; + DeviceName.Buffer = pDeviceInformation->Name; + + Status = IopEnumerateDetectedDevices(hDeviceKey, &DeviceName, hRootKey, TRUE); + if (!NT_SUCCESS(Status)) + goto cleanup; + } + } + + /* Read identifier */ + Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + if (Status == STATUS_BUFFER_OVERFLOW) + { + ExFreePool(pValueInformation); + ValueInfoLength = RequiredSize; + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + else if (pValueInformation->Type != REG_SZ) + { + DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); + goto nextdevice; + } + + /* Assign hardware id to this device */ + ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; + ValueName.Buffer = (PWCHAR)pValueInformation->Data; + if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) + ValueName.Length -= sizeof(WCHAR); + if (RtlCompareUnicodeString(&ValueName, &IdentifierPci, FALSE) == 0) + { + pHardwareId = &HardwareIdPci; + DeviceIndex = DeviceIndexPci++; + } + else if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0) + { + pHardwareId = &HardwareIdSerial; + DeviceIndex = DeviceIndexSerial++; + } + else if (RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0) + { + pHardwareId = &HardwareIdKeyboard; + DeviceIndex = DeviceIndexKeyboard++; + } + else if (RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0) + { + pHardwareId = &HardwareIdMouse; + DeviceIndex = DeviceIndexMouse++; + } + else + { + /* Unknown device */ + DPRINT("Unknown device %wZ in %wZ\n", &ValueName, RelativePath); + goto nextdevice; + } + + /* Add the detected device to Root key */ + InitializeObjectAttributes(&ObjectAttributes, pHardwareId, OBJ_KERNEL_HANDLE, hRootKey, NULL); + Status = ZwCreateKey( + &hLevel1Key, + KEY_CREATE_SUB_KEY, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + swprintf(Level2Name, L"%04lu", DeviceIndex); + RtlInitUnicodeString(&Level2NameU, Level2Name); + InitializeObjectAttributes(&ObjectAttributes, &Level2NameU, OBJ_KERNEL_HANDLE, hLevel1Key, NULL); + Status = ZwCreateKey( + &hLevel2Key, + KEY_SET_VALUE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + ZwClose(hLevel1Key); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, pHardwareId); + Status = ZwSetValueKey(hLevel2Key, &DeviceDescU, 0, REG_SZ, ValueName.Buffer, ValueName.MaximumLength); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + +nextdevice: + if (hLevel2Key) + { + ZwClose(hLevel2Key); + hLevel2Key = NULL; + } + if (hDeviceKey) + { + ZwClose(hDeviceKey); + hDeviceKey = NULL; + } + } + + Status = STATUS_SUCCESS; + +cleanup: + if (hDevicesKey) + ZwClose(hDevicesKey); + if (hDeviceKey) + ZwClose(hDeviceKey); + if (pDeviceInformation) + ExFreePool(pDeviceInformation); + if (pValueInformation) + ExFreePool(pValueInformation); + return Status; +} + +static NTSTATUS INIT_FUNCTION +IopUpdateRootKey(VOID) +{ + UNICODE_STRING RootPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum\\Root"); + UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hRoot; + NTSTATUS Status; + + InitializeObjectAttributes(&ObjectAttributes, &RootPathU, OBJ_KERNEL_HANDLE, NULL, NULL); + Status = ZwOpenKey(&hRoot, KEY_CREATE_SUB_KEY, &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + return Status; + } + Status = IopEnumerateDetectedDevices( + NULL, + &MultiKeyPathU, + hRoot, + TRUE); + ZwClose(hRoot); + return Status; +} VOID INIT_FUNCTION PnpInit2(VOID) { NTSTATUS Status; + /* Move information about devices detected by Freeloader to SYSTEM\CurrentControlSet\Root\ */ + /* FIXME: this should be done only when ACPI is disabled or not present! */ + Status = IopUpdateRootKey(); + if (!NT_SUCCESS(Status)) + { + CPRINT("IopUpdateRootKey() failed\n"); + KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); + } + /* Set root device instance data */ Status = IopSetRootDeviceInstanceData(IopRootDeviceNode); if (!NT_SUCCESS(Status)) From faa4bd22bbcc1cbf0fa8acff51ee32c0e9fbdbbd Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 14 Sep 2006 20:46:06 +0000 Subject: [PATCH 208/488] put system info back in svn path=/trunk/; revision=24125 --- reactos/dll/cpl/sysdm/en.rc | 4 ++-- reactos/dll/cpl/sysdm/sysdm.rc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/dll/cpl/sysdm/en.rc b/reactos/dll/cpl/sysdm/en.rc index 213750324c3..9484778f5fb 100644 --- a/reactos/dll/cpl/sysdm/en.rc +++ b/reactos/dll/cpl/sysdm/en.rc @@ -7,8 +7,8 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN CONTROL "", IDC_ROSIMG, "Static", SS_OWNERDRAW, 4, 5, 248, 111 LTEXT "System:", IDC_STATIC, 4, 132, 32, 9 -// LTEXT REACTOS_STR_PRODUCT_NAME, IDC_STATIC, 114, 29, 142, 8 -// LTEXT "Version " REACTOS_STR_PRODUCT_VERSION, IDC_STATIC, 114, 38, 142, 8 + LTEXT REACTOS_STR_PRODUCT_NAME, IDC_STATIC, 10, 144, 116, 9 + LTEXT "Version "REACTOS_STR_PRODUCT_VERSION, IDC_STATIC, 10, 153, 116, 9 LTEXT "Machine:", IDC_STATIC, 124, 132, 34, 9 LTEXT "", IDC_PROCESSORMANUFACTURER, 130, 144, 118, 9 LTEXT "", IDC_PROCESSOR, 130, 153, 118, 9 diff --git a/reactos/dll/cpl/sysdm/sysdm.rc b/reactos/dll/cpl/sysdm/sysdm.rc index cfc514d2711..32bf69913e6 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rc +++ b/reactos/dll/cpl/sysdm/sysdm.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #define REACTOS_STR_FILE_DESCRIPTION "ReactOS System Applet\0" #define REACTOS_STR_INTERNAL_NAME "sysdm\0" #define REACTOS_STR_ORIGINAL_FILENAME "sysdm.cpl\0" -//#include +#include IDI_CPLSYSTEM ICON "resources/applet.ico" IDI_DEVMGR ICON "resources/devmgr.ico" From af77fee9dd66fcaf7aabf42e1a77cc8e66df462b Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 14 Sep 2006 21:51:56 +0000 Subject: [PATCH 209/488] fix a few dialog asthetics svn path=/trunk/; revision=24126 --- reactos/dll/cpl/sysdm/en.rc | 45 +++++++++++++++-------------- reactos/dll/cpl/sysdm/environment.c | 4 +-- reactos/dll/cpl/sysdm/resource.h | 6 +--- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/reactos/dll/cpl/sysdm/en.rc b/reactos/dll/cpl/sysdm/en.rc index 9484778f5fb..e92e3f47a67 100644 --- a/reactos/dll/cpl/sysdm/en.rc +++ b/reactos/dll/cpl/sysdm/en.rc @@ -14,7 +14,7 @@ BEGIN LTEXT "", IDC_PROCESSOR, 130, 153, 118, 9 LTEXT "", IDC_PROCESSORSPEED, 130, 162, 118, 9 LTEXT "", IDC_SYSTEMMEMORY, 130, 171, 118, 9 - PUSHBUTTON "View licence...", IDC_LICENCE, 78, 199, 78, 13 + PUSHBUTTON "View licence...", IDC_LICENCE, 90, 199, 78, 13 END IDD_PROPPAGECOMPUTER DIALOGEX 0, 0, 256, 218 @@ -111,26 +111,32 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSM CAPTION "Virtual Memory" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - LTEXT "Drive [Volume Label] Paging File Size (MB)", -1, 12, 5, 96, 9 + LTEXT "Drive [Volume Label]", IDC_STATIC, 12, 5, 96, 9 + LTEXT "Paging File Size (MB)", IDC_STATIC, 115, 5, 96, 9 CONTROL "", IDC_PAGEFILELIST, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP, 10, 16, 204, 52, WS_EX_CLIENTEDGE GROUPBOX "Paging file size for selected drive", IDC_DRIVEGROUP, 10, 70, 204, 104 - LTEXT "", IDC_DRIVE, 20, 244, 100, 9 - LTEXT "", IDC_SPACEAVAIL, 20, 94, 112, 8 - LTEXT "Initial size (MB):", -1, 22, 118, 54, 9 - LTEXT "Maximum size (MB):", -1, 22, 131, 64, 9 - CONTROL "Custom size", IDC_CUSTOM, "Button", BS_AUTORADIOBUTTON, 20, 105, 54, 9 - CONTROL "System managed size", IDC_SYSMANSIZE, "Button", BS_AUTORADIOBUTTON, 20, 145, 88, 9 - CONTROL "No paging file", IDC_NOPAGEFILE, "Button", BS_AUTORADIOBUTTON, 20, 158, 78,9 + LTEXT "Drive:", IDC_STATIC, 20, 80, 20, 8 + LTEXT "", IDC_DRIVE, 88, 81, 100, 9 + LTEXT "Space available:", IDC_STATIC, 20, 92, 56, 9 + LTEXT "", IDC_SPACEAVAIL, 84, 92, 104, 9 + LTEXT "&Initial size (MB):", -1, 22, 118, 54, 9 + LTEXT "Ma&ximum size (MB):", -1, 22, 131, 64, 9 + CONTROL "&Custom size", IDC_CUSTOM, "Button", BS_AUTORADIOBUTTON, 20, 105, 54, 9 + CONTROL "S&ystem managed size", IDC_SYSMANSIZE, "Button", BS_AUTORADIOBUTTON, 20, 145, 88, 9 + CONTROL "&No paging file", IDC_NOPAGEFILE, "Button", BS_AUTORADIOBUTTON, 20, 158, 78,9 EDITTEXT IDC_INITIALSIZE, 100, 114, 44, 13, NOT WS_BORDER, WS_EX_CLIENTEDGE EDITTEXT IDC_MAXSIZE, 100, 129, 44, 13, NOT WS_BORDER, WS_EX_CLIENTEDGE PUSHBUTTON "Set", IDC_SET, 158, 155, 50, 13 - GROUPBOX "Total paging file size for all drives", IDC_TOTALGROUP, 10, 179, 204, 46 - LTEXT "", IDC_MINIMUM, 18, 200, 100, 9 - LTEXT "", IDC_RECOMMENDED, 18, 200, 100, 9 - LTEXT "", IDC_CURRENT, 18, 200, 100, 9 + GROUPBOX "Total paging file size for all drives", IDC_TOTALGROUP, 10, 177, 204, 46 + LTEXT "Minimum allowed:", IDC_STATIC, 18, 188, 58, 9 + LTEXT "", IDC_MINIMUM, 86, 186, 100, 9 + LTEXT "Recommended:", IDC_STATIC, 18, 199, 52, 9 + LTEXT "", IDC_RECOMMENDED, 88, 197, 100, 9 + LTEXT "Currently allocated:", IDC_STATIC, 18, 210, 66, 9 + LTEXT "", IDC_CURRENT, 88, 208, 100, 9 PUSHBUTTON "OK", IDOK, 114, 232, 48, 13 PUSHBUTTON "Cancel", IDCANCEL, 168, 232, 48, 13 @@ -143,18 +149,18 @@ CAPTION "Environment Variables" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN GROUPBOX "User variables", IDC_STATIC, 7, 12, 238, 100 - LTEXT "&Variables:", IDC_STATIC, 14, 24, 224, 8 + CONTROL "", IDC_USER_VARIABLE_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOSORTHEADER | - WS_VSCROLL | WS_HSCROLL | WS_TABSTOP, 14, 35, 224, 48, WS_EX_CLIENTEDGE + WS_VSCROLL | WS_HSCROLL | WS_TABSTOP, 14, 25, 224, 58, WS_EX_CLIENTEDGE PUSHBUTTON "&New...", IDC_USER_VARIABLE_NEW, 80, 90, 50, 14 PUSHBUTTON "&Edit...", IDC_USER_VARIABLE_EDIT, 134, 90, 50, 14 PUSHBUTTON "&Delete", IDC_USER_VARIABLE_DELETE, 188, 90, 50, 14 GROUPBOX "System variables", IDC_STATIC, 7, 116, 238, 100 - LTEXT "V&ariables:", IDC_STATIC, 14, 128, 224, 8 + CONTROL "", IDC_SYSTEM_VARIABLE_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOSORTHEADER | - WS_VSCROLL | WS_HSCROLL | WS_TABSTOP, 14, 139, 224, 48, WS_EX_CLIENTEDGE + WS_VSCROLL | WS_HSCROLL | WS_TABSTOP, 14, 129, 224, 58, WS_EX_CLIENTEDGE PUSHBUTTON "Ne&w...", IDC_SYSTEM_VARIABLE_NEW, 80, 194, 50, 14 PUSHBUTTON "Ed&it...", IDC_SYSTEM_VARIABLE_EDIT, 134, 194, 50, 14 PUSHBUTTON "De&lete", IDC_SYSTEM_VARIABLE_DELETE, 188, 194, 50, 14 @@ -190,9 +196,4 @@ STRINGTABLE DISCARDABLE BEGIN IDS_CPLSYSTEMNAME "System" IDS_CPLSYSTEMDESCRIPTION "See information about your computer and change various system and hardware settings." - IDS_DRIVE "Drive: %s" - IDS_SPACE "Space available: %s" - IDS_MIN "Minimum allowed: %s" - IDS_REC "Recommended: %s" - IDS_CUR "Currently allocated: %s" END diff --git a/reactos/dll/cpl/sysdm/environment.c b/reactos/dll/cpl/sysdm/environment.c index 3b5b6104b4f..f348a52a8a1 100644 --- a/reactos/dll/cpl/sysdm/environment.c +++ b/reactos/dll/cpl/sysdm/environment.c @@ -243,12 +243,12 @@ SetListViewColumns(HWND hwndListView) memset(&column, 0x00, sizeof(column)); column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT; column.fmt=LVCFMT_LEFT; - column.cx = (rect.right - rect.left) / 3; + column.cx = (INT)((rect.right - rect.left) * 0.32); column.iSubItem = 0; column.pszText = _T("Variable"); (void)ListView_InsertColumn(hwndListView, 0, &column); - column.cx = (rect.right - rect.left) - ((rect.right - rect.left) / 3) - 1; + column.cx = (INT)((rect.right - rect.left) * 0.63); column.iSubItem = 1; column.pszText = _T("Value"); (void)ListView_InsertColumn(hwndListView, 1, &column); diff --git a/reactos/dll/cpl/sysdm/resource.h b/reactos/dll/cpl/sysdm/resource.h index f2fe0364116..c83723cb6b7 100644 --- a/reactos/dll/cpl/sysdm/resource.h +++ b/reactos/dll/cpl/sysdm/resource.h @@ -90,11 +90,7 @@ #define IDC_MINIMUM 912 #define IDC_RECOMMENDED 913 #define IDC_CURRENT 914 -#define IDS_DRIVE 920 -#define IDS_SPACE 921 -#define IDS_MIN 922 -#define IDS_REC 923 -#define IDS_CUR 924 + /* licence */ #define IDD_LICENCE 1000 From 3daa4394f76eeb77c1da8d406b87213eee53a105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 14 Sep 2006 22:29:07 +0000 Subject: [PATCH 210/488] Check for ACPI BIOS identifier, to prevent double enumeration of devices Move boot resource informations to Root\ key (if available) Add a missing \0 at the end of hardwareId list svn path=/trunk/; revision=24127 --- reactos/boot/bootdata/hivesys.inf | 5 - reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 269 ++++++++++++++++++++++++++-- 2 files changed, 251 insertions(+), 23 deletions(-) diff --git a/reactos/boot/bootdata/hivesys.inf b/reactos/boot/bootdata/hivesys.inf index eaf9208aa63..f3f995405e6 100644 --- a/reactos/boot/bootdata/hivesys.inf +++ b/reactos/boot/bootdata/hivesys.inf @@ -648,11 +648,6 @@ HKLM,"SYSTEM\CurrentControlSet\Enum\Root\*PNP0A03\0000\LogConf","BasicConfigVect 01,00,00,00,01,00,01,00,01,00,00,00, \ 00,06,00,00,00,00,00,00,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 -; ACPI bus -HKLM,"SYSTEM\CurrentControlSet\Enum\Root\*PNP0C08\0000","HardwareID",0x00010000,"*PNP0C08" -HKLM,"SYSTEM\CurrentControlSet\Enum\Root\*PNP0C08\0000","DeviceDesc",0x00000000,"ACPI bus" -HKLM,"SYSTEM\CurrentControlSet\Enum\Root\*PNP0C08\0000","Service",0x00000000,"acpi" - ; NetLogon HKLM,"SYSTEM\CurrentControlSet\Services\NetLogon","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Netlogon","ImagePath",0x00020000,"%SystemRoot%\system32\lsass.exe" diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 29e4d25c47b..6793ee67d57 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -34,6 +34,7 @@ IopSetRootDeviceInstanceData(PDEVICE_NODE DeviceNode); #pragma alloc_text(INIT, PnpInit2) #pragma alloc_text(INIT, IopUpdateRootKey) #pragma alloc_text(INIT, IopEnumerateDetectedDevices) +#pragma alloc_text(INIT, IopIsAcpiComputer) #endif @@ -2600,10 +2601,13 @@ IopEnumerateDetectedDevices( UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc"); UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID"); + UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration Data"); + UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig"); + UNICODE_STRING LogConfU = RTL_CONSTANT_STRING(L"LogConf"); OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hDevicesKey = NULL; HANDLE hDeviceKey = NULL; - HANDLE hLevel1Key, hLevel2Key = NULL; + HANDLE hLevel1Key, hLevel2Key = NULL, hLogConf; UNICODE_STRING Level2NameU; WCHAR Level2Name[5]; ULONG IndexDevice = 0; @@ -2617,16 +2621,19 @@ IopEnumerateDetectedDevices( NTSTATUS Status; const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI BIOS"); - UNICODE_STRING HardwareIdPci = RTL_CONSTANT_STRING(L"*PNP0A03"); + UNICODE_STRING HardwareIdPci = RTL_CONSTANT_STRING(L"*PNP0A03\0"); static ULONG DeviceIndexPci = 0; + const UNICODE_STRING IdentifierAcpi = RTL_CONSTANT_STRING(L"ACPI BIOS"); + UNICODE_STRING HardwareIdAcpi = RTL_CONSTANT_STRING(L"*PNP0C08\0"); + static ULONG DeviceIndexAcpi = 0; const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController"); - UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501"); + UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0"); static ULONG DeviceIndexSerial = 0; const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardPeripheral"); - UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303"); + UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303\0"); static ULONG DeviceIndexKeyboard = 0; const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerPeripheral"); - UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13"); + UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0"); static ULONG DeviceIndexMouse = 0; PUNICODE_STRING pHardwareId; ULONG DeviceIndex = 0; @@ -2766,6 +2773,11 @@ IopEnumerateDetectedDevices( pHardwareId = &HardwareIdPci; DeviceIndex = DeviceIndexPci++; } + else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0) + { + pHardwareId = &HardwareIdAcpi; + DeviceIndex = DeviceIndexAcpi++; + } else if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0) { pHardwareId = &HardwareIdSerial; @@ -2808,7 +2820,7 @@ IopEnumerateDetectedDevices( InitializeObjectAttributes(&ObjectAttributes, &Level2NameU, OBJ_KERNEL_HANDLE, hLevel1Key, NULL); Status = ZwCreateKey( &hLevel2Key, - KEY_SET_VALUE, + KEY_SET_VALUE | KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, @@ -2828,7 +2840,60 @@ IopEnumerateDetectedDevices( ZwDeleteKey(hLevel2Key); goto nextdevice; } - Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength); + Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + /* Copy 'Configuration Data' to 'LogConf\BootConfig' */ + Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + if (Status == STATUS_BUFFER_OVERFLOW) + { + ExFreePool(pValueInformation); + ValueInfoLength = RequiredSize; + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("ExAllocatePool() failed\n"); + ZwDeleteKey(hLevel2Key); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + } + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + goto nextdevice; + else if (!NT_SUCCESS(Status)) + { + DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR) + { + DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE, hLevel2Key, NULL); + Status = ZwCreateKey( + &hLogConf, + KEY_SET_VALUE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, pValueInformation->Type, pValueInformation->Data, pValueInformation->DataLength); + ZwClose(hLogConf); if (!NT_SUCCESS(Status)) { DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); @@ -2863,29 +2928,198 @@ cleanup: return Status; } +static BOOLEAN INIT_FUNCTION +IopIsAcpiComputer(VOID) +{ + UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"); + UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); + UNICODE_STRING AcpiBiosIdentifier = RTL_CONSTANT_STRING(L"ACPI BIOS"); + OBJECT_ATTRIBUTES ObjectAttributes; + PKEY_BASIC_INFORMATION pDeviceInformation = NULL; + ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR); + PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL; + ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR); + ULONG RequiredSize; + ULONG IndexDevice = 0; + UNICODE_STRING DeviceName, ValueName; + HANDLE hDevicesKey = NULL; + HANDLE hDeviceKey = NULL; + NTSTATUS Status; + BOOLEAN ret = FALSE; + + InitializeObjectAttributes(&ObjectAttributes, &MultiKeyPathU, OBJ_KERNEL_HANDLE, NULL, NULL); + Status = ZwOpenKey(&hDevicesKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength); + if (!pDeviceInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pDeviceInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + + while (TRUE) + { + Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); + if (Status == STATUS_NO_MORE_ENTRIES) + break; + else if (Status == STATUS_BUFFER_OVERFLOW) + { + ExFreePool(pDeviceInformation); + DeviceInfoLength = RequiredSize; + pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength); + if (!pDeviceInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + IndexDevice++; + + /* Open device key */ + DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength; + DeviceName.Buffer = pDeviceInformation->Name; + InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_KERNEL_HANDLE, hDevicesKey, NULL); + Status = ZwOpenKey( + &hDeviceKey, + KEY_QUERY_VALUE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + /* Read identifier */ + Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + if (Status == STATUS_BUFFER_OVERFLOW) + { + ExFreePool(pValueInformation); + ValueInfoLength = RequiredSize; + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + else if (pValueInformation->Type != REG_SZ) + { + DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); + goto nextdevice; + } + + ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; + ValueName.Buffer = (PWCHAR)pValueInformation->Data; + if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) + ValueName.Length -= sizeof(WCHAR); + if (RtlCompareUnicodeString(&ValueName, &AcpiBiosIdentifier, FALSE) == 0) + { + DPRINT("Found ACPI BIOS\n"); + ret = TRUE; + goto cleanup; + } + +nextdevice: + ZwClose(hDeviceKey); + hDeviceKey = NULL; + } + +cleanup: + if (pDeviceInformation) + ExFreePool(pDeviceInformation); + if (pValueInformation) + ExFreePool(pValueInformation); + if (hDevicesKey) + ZwClose(hDevicesKey); + if (hDeviceKey) + ZwClose(hDeviceKey); + return ret; +} + static NTSTATUS INIT_FUNCTION IopUpdateRootKey(VOID) { UNICODE_STRING RootPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum\\Root"); UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"); + UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc"); + UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID"); + UNICODE_STRING HalAcpiDevice = RTL_CONSTANT_STRING(L"ACPI_HAL"); + UNICODE_STRING HalAcpiId = RTL_CONSTANT_STRING(L"0000"); + UNICODE_STRING HalAcpiDeviceDesc = RTL_CONSTANT_STRING(L"HAL ACPI"); + UNICODE_STRING HalAcpiHardwareID = RTL_CONSTANT_STRING(L"*PNP0C08\0"); OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hRoot; + HANDLE hRoot, hHalAcpiDevice, hHalAcpiId; NTSTATUS Status; InitializeObjectAttributes(&ObjectAttributes, &RootPathU, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenKey(&hRoot, KEY_CREATE_SUB_KEY, &ObjectAttributes); - if (!NT_SUCCESS(Status)) + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { - DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + /* We are probably in 1st stage */ + return STATUS_SUCCESS; + } + else if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status); + return Status; + } + + if (IopIsAcpiComputer()) + { + InitializeObjectAttributes(&ObjectAttributes, &HalAcpiDevice, OBJ_KERNEL_HANDLE, hRoot, NULL); + Status = ZwCreateKey(&hHalAcpiDevice, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); + ZwClose(hRoot); + if (!NT_SUCCESS(Status)) + return Status; + InitializeObjectAttributes(&ObjectAttributes, &HalAcpiId, OBJ_KERNEL_HANDLE, hHalAcpiDevice, NULL); + Status = ZwCreateKey(&hHalAcpiId, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); + ZwClose(hHalAcpiDevice); + if (!NT_SUCCESS(Status)) + return Status; + Status = ZwSetValueKey(hHalAcpiId, &DeviceDescU, 0, REG_SZ, HalAcpiDeviceDesc.Buffer, HalAcpiDeviceDesc.MaximumLength); + if (NT_SUCCESS(Status)) + Status = ZwSetValueKey(hHalAcpiId, &HardwareIDU, 0, REG_MULTI_SZ, HalAcpiHardwareID.Buffer, HalAcpiHardwareID.MaximumLength + sizeof(WCHAR)); + ZwClose(hHalAcpiId); + return Status; + } + else + { + Status = IopEnumerateDetectedDevices( + NULL, + &MultiKeyPathU, + hRoot, + TRUE); + ZwClose(hRoot); return Status; } - Status = IopEnumerateDetectedDevices( - NULL, - &MultiKeyPathU, - hRoot, - TRUE); - ZwClose(hRoot); - return Status; } VOID INIT_FUNCTION @@ -2894,7 +3128,6 @@ PnpInit2(VOID) NTSTATUS Status; /* Move information about devices detected by Freeloader to SYSTEM\CurrentControlSet\Root\ */ - /* FIXME: this should be done only when ACPI is disabled or not present! */ Status = IopUpdateRootKey(); if (!NT_SUCCESS(Status)) { From 2a1513dc5cdadec9d78f9b0d6f340846b551f489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Fri, 15 Sep 2006 06:48:01 +0000 Subject: [PATCH 211/488] - Fix Freeldr to correctly send reported resources (at least PCI buses and PS/2 devices) - Let Root bus report BootResources - If no resource requirement are found, use the boot resource list (not sure of this one) svn path=/trunk/; revision=24128 --- reactos/boot/bootdata/hivesys.inf | 8 - .../boot/freeldr/freeldr/arch/i386/hardware.c | 6 +- .../boot/freeldr/freeldr/arch/i386/hwpci.c | 11 +- reactos/ntoskrnl/io/pnpmgr/pnproot.c | 150 +++++++++--------- 4 files changed, 84 insertions(+), 91 deletions(-) diff --git a/reactos/boot/bootdata/hivesys.inf b/reactos/boot/bootdata/hivesys.inf index f3f995405e6..c24b42aaed5 100644 --- a/reactos/boot/bootdata/hivesys.inf +++ b/reactos/boot/bootdata/hivesys.inf @@ -640,14 +640,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","ImagePath",0x00020000,"system32\d HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Type",0x00010001,0x00000001 -; PCI driver -HKLM,"SYSTEM\CurrentControlSet\Enum\Root\*PNP0A03\0000","HardwareID",0x00010000,"*PNP0A03" -HKLM,"SYSTEM\CurrentControlSet\Enum\Root\*PNP0A03\0000","DeviceDesc",0x00000000,"PCI bus" -HKLM,"SYSTEM\CurrentControlSet\Enum\Root\*PNP0A03\0000\LogConf","BasicConfigVector",0x000A0001, \ -40,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, \ -01,00,00,00,01,00,01,00,01,00,00,00, \ -00,06,00,00,00,00,00,00,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 - ; NetLogon HKLM,"SYSTEM\CurrentControlSet\Services\NetLogon","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Netlogon","ImagePath",0x00020000,"%SystemRoot%\system32\lsass.exe" diff --git a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c index 0d719486ac8..ad37d57fbe2 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c @@ -1270,6 +1270,8 @@ DetectSerialPointerPeripheral(FRLDRHKEY ControllerKey, FullResourceDescriptor.InterfaceType = Isa; FullResourceDescriptor.BusNumber = 0; FullResourceDescriptor.PartialResourceList.Count = 0; + FullResourceDescriptor.PartialResourceList.Version = 1; + FullResourceDescriptor.PartialResourceList.Revision = 1; Error = RegSetValue(PeripheralKey, L"Configuration Data", @@ -1688,8 +1690,8 @@ DetectKeyboardPeripheral(FRLDRHKEY ControllerKey) PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_KEYBOARD_DEVICE_DATA); KeyboardData = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR)); - KeyboardData->Version = 0; - KeyboardData->Revision = 0; + KeyboardData->Version = 1; + KeyboardData->Revision = 1; KeyboardData->Type = 4; KeyboardData->Subtype = 0; KeyboardData->KeyboardFlags = 0x20; diff --git a/reactos/boot/freeldr/freeldr/arch/i386/hwpci.c b/reactos/boot/freeldr/freeldr/arch/i386/hwpci.c index 55d8fa10f0b..1046ec1ed6e 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/hwpci.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/hwpci.c @@ -277,8 +277,7 @@ DetectPciBios(FRLDRHKEY SystemKey, ULONG *BusNumber) } /* Set 'Configuration Data' value */ - Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) - - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR); FullResourceDescriptor = MmAllocateMemory(Size); if (FullResourceDescriptor == NULL) { @@ -291,7 +290,13 @@ DetectPciBios(FRLDRHKEY SystemKey, ULONG *BusNumber) memset(FullResourceDescriptor, 0, Size); FullResourceDescriptor->InterfaceType = PCIBus; FullResourceDescriptor->BusNumber = 0; - FullResourceDescriptor->PartialResourceList.Count = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; + FullResourceDescriptor->PartialResourceList.Count = 1; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeBusNumber; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.BusNumber.Start = 0; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.BusNumber.Length = 1; /* Set 'Configuration Data' value */ Error = RegSetValue(BiosKey, diff --git a/reactos/ntoskrnl/io/pnpmgr/pnproot.c b/reactos/ntoskrnl/io/pnpmgr/pnproot.c index dca0644a1b2..2f72a3b42d9 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnproot.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnproot.c @@ -33,6 +33,9 @@ typedef struct _PNPROOT_DEVICE UNICODE_STRING InstanceID; // Device description UNICODE_STRING DeviceDescription; + // Boot resource list + PCM_FULL_RESOURCE_DESCRIPTOR BootResourceList; + SIZE_T BootResourceListSize; // Resource requirement list PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList; } PNPROOT_DEVICE, *PPNPROOT_DEVICE; @@ -67,12 +70,8 @@ typedef struct _PNPROOT_PDO_DEVICE_EXTENSION { // Common device data PNPROOT_COMMON_DEVICE_EXTENSION Common; - // Device ID - UNICODE_STRING DeviceID; - // Instance ID - UNICODE_STRING InstanceID; - // Resource requirement list - PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList; + // Device + PPNPROOT_DEVICE Device; } PNPROOT_PDO_DEVICE_EXTENSION, *PPNPROOT_PDO_DEVICE_EXTENSION; @@ -158,23 +157,6 @@ PnpRootCreateDevice( PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0; - if (!RtlCreateUnicodeString( - &PdoDeviceExtension->DeviceID, - ENUM_NAME_ROOT \ - L"\\LEGACY_UNKNOWN")) - { - /* FIXME: */ - DPRINT("RtlCreateUnicodeString() failed\n"); - } - - if (!RtlCreateUnicodeString( - &PdoDeviceExtension->InstanceID, - L"0000")) - { - /* FIXME: */ - DPRINT("RtlCreateUnicodeString() failed\n"); - } - ExInterlockedInsertTailList( &DeviceExtension->DeviceListHead, &Device->ListEntry, @@ -210,9 +192,12 @@ PdoQueryId( switch (IrpSp->Parameters.QueryId.IdType) { case BusQueryDeviceID: - Status = RtlDuplicateUnicodeString(TRUE, - &DeviceExtension->DeviceID, + if (DeviceExtension->Device) + Status = RtlDuplicateUnicodeString(TRUE, + &DeviceExtension->Device->DeviceID, &String); + else + Status = RtlCreateUnicodeString(&String, ENUM_NAME_ROOT L"\\LEGACY_UNKNOWN"); DPRINT("DeviceID: %wZ\n", &String); @@ -225,9 +210,12 @@ PdoQueryId( break; case BusQueryInstanceID: - Status = RtlDuplicateUnicodeString(TRUE, - &DeviceExtension->InstanceID, + if (DeviceExtension->Device) + Status = RtlDuplicateUnicodeString(TRUE, + &DeviceExtension->Device->InstanceID, &String); + else + Status = RtlCreateUnicodeString(&String, L"0000"); DPRINT("InstanceID: %S\n", String.Buffer); @@ -249,16 +237,40 @@ PdoQueryResources( IN PIRP Irp, PIO_STACK_LOCATION IrpSp) { + PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension; PCM_RESOURCE_LIST ResourceList; ULONG ResourceListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List); - ResourceList = ExAllocatePool(PagedPool, ResourceListSize); - if (ResourceList == NULL) - return STATUS_INSUFFICIENT_RESOURCES; + DPRINT("Called\n"); - ResourceList->Count = 0; + DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (!DeviceExtension->Device || DeviceExtension->Device->BootResourceList == NULL) + { + /* Create an empty resource list */ + ResourceList = ExAllocatePool(PagedPool, ResourceListSize); + if (ResourceList == NULL) + return STATUS_INSUFFICIENT_RESOURCES; - Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + ResourceList->Count = 0; + + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + } + else + { + /* Copy existing resource list */ + ResourceList = ExAllocatePool(PagedPool, + FIELD_OFFSET(CM_RESOURCE_LIST, List) + DeviceExtension->Device->BootResourceListSize); + if (ResourceList == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + ResourceList->Count = 1; + RtlCopyMemory( + &ResourceList->List, + DeviceExtension->Device->BootResourceList, + DeviceExtension->Device->BootResourceListSize); + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + } return STATUS_SUCCESS; } @@ -278,7 +290,7 @@ PdoQueryResourceRequirements( DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - if (DeviceExtension->ResourceRequirementsList == NULL) + if (!DeviceExtension->Device || DeviceExtension->Device->ResourceRequirementsList == NULL) { /* Create an empty resource list */ ResourceList = ExAllocatePool(PagedPool, ResourceListSize); @@ -293,14 +305,14 @@ PdoQueryResourceRequirements( else { /* Copy existing resource requirement list */ - ResourceList = ExAllocatePool(PagedPool, DeviceExtension->ResourceRequirementsList->ListSize); + ResourceList = ExAllocatePool(PagedPool, DeviceExtension->Device->ResourceRequirementsList->ListSize); if (ResourceList == NULL) return STATUS_INSUFFICIENT_RESOURCES; RtlCopyMemory( ResourceList, - DeviceExtension->ResourceRequirementsList, - DeviceExtension->ResourceRequirementsList->ListSize); + DeviceExtension->Device->ResourceRequirementsList, + DeviceExtension->Device->ResourceRequirementsList->ListSize); Irp->IoStatus.Information = (ULONG_PTR)ResourceList; } @@ -449,7 +461,8 @@ static NTSTATUS PnpRootReadRegistryBinary( IN PWSTR KeyName, IN PWSTR ValueKeyName, - OUT PVOID* Buffer) + OUT PVOID* Buffer, + OUT SIZE_T* BufferSize OPTIONAL) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyNameU; @@ -500,7 +513,7 @@ PnpRootReadRegistryBinary( { DPRINT("ExAllocatePoolWithTag() failed\n", Status); ZwClose(KeyHandle); - return Status; + return STATUS_NO_MEMORY; } Status = ZwQueryValueKey( @@ -512,12 +525,13 @@ PnpRootReadRegistryBinary( if (NT_SUCCESS(Status)) { *Buffer = ExAllocatePoolWithTag(PagedPool, Data->DataLength, TAG_PNP_ROOT); + if (BufferSize) *BufferSize = Data->DataLength; if (!*Buffer) { DPRINT("ExAllocatePoolWithTag() failed\n", Status); ExFreePoolWithTag(Data, TAG_PNP_ROOT); ZwClose(KeyHandle); - return Status; + return STATUS_NO_MEMORY; } RtlCopyMemory( @@ -591,7 +605,21 @@ PnpRootFdoReadDeviceInfo( Status = PnpRootReadRegistryBinary( KeyName, L"BasicConfigVector", - (PVOID*)&Device->ResourceRequirementsList); + (PVOID*)&Device->ResourceRequirementsList, + NULL); + + DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status); + + if (!NT_SUCCESS(Status)) + { + /* FIXME: */ + } + + Status = PnpRootReadRegistryBinary( + KeyName, + L"BootConfig", + (PVOID*)&Device->BootResourceList, + &Device->BootResourceListSize); DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status); @@ -861,52 +889,18 @@ PnpRootQueryBusRelations( PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0; - if (!RtlCreateUnicodeString( - &PdoDeviceExtension->DeviceID, - Device->DeviceID.Buffer)) - { - DPRINT("Insufficient resources\n"); - /* FIXME: */ - } + PdoDeviceExtension->Device = Device; DPRINT("DeviceID: %wZ PDO %p\n", - &PdoDeviceExtension->DeviceID, + &PdoDeviceExtension->Device->DeviceID, Device->Pdo); - if (!RtlCreateUnicodeString( - &PdoDeviceExtension->InstanceID, - Device->InstanceID.Buffer)) - { - DPRINT("Insufficient resources\n"); - /* FIXME: */ - } - DPRINT("InstanceID: %wZ PDO %p\n", - &PdoDeviceExtension->InstanceID, + &PdoDeviceExtension->Device->InstanceID, Device->Pdo); - if (Device->ResourceRequirementsList != NULL) - { - PdoDeviceExtension->ResourceRequirementsList = ExAllocatePoolWithTag( - PagedPool, - Device->ResourceRequirementsList->ListSize, - TAG_PNP_ROOT); - if (PdoDeviceExtension->ResourceRequirementsList) - { - RtlCopyMemory( - PdoDeviceExtension->ResourceRequirementsList, - Device->ResourceRequirementsList, - Device->ResourceRequirementsList->ListSize); - } - else - { - /* FIXME */ - DPRINT("ExAllocatePoolWithTag() failed\n"); - } - } - DPRINT("ResourceRequirementsList: %p PDO %p\n", - PdoDeviceExtension->ResourceRequirementsList, + PdoDeviceExtension->Device->ResourceRequirementsList, Device->Pdo); } From b73a685a798436691749352f14a893c54d503cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Fri, 15 Sep 2006 09:09:18 +0000 Subject: [PATCH 212/488] Assume bus number #0 if not specified in resource list svn path=/trunk/; revision=24129 --- reactos/drivers/bus/pci/fdo.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/reactos/drivers/bus/pci/fdo.c b/reactos/drivers/bus/pci/fdo.c index 7daa2e7661b..bf86f69ee3f 100644 --- a/reactos/drivers/bus/pci/fdo.c +++ b/reactos/drivers/bus/pci/fdo.c @@ -370,6 +370,14 @@ FdoStartDevice( DPRINT("No allocated resources sent to driver\n"); return STATUS_INSUFFICIENT_RESOURCES; } + /* HACK due to a bug in ACPI driver, which doesn't report the bus number */ + if (AllocatedResources->Count == 0) + { + DPRINT1("No bus number resource found (bug in acpi.sys?), assuming bus number #0\n"); + DeviceExtension->BusNumber = 0; + goto next; + } + /* END HACK */ if (AllocatedResources->Count < 1) { DPRINT("Not enough allocated resources sent to driver\n"); @@ -405,6 +413,7 @@ FdoStartDevice( return STATUS_INSUFFICIENT_RESOURCES; } +next: InitializeListHead(&DeviceExtension->DeviceListHead); KeInitializeSpinLock(&DeviceExtension->DeviceListLock); DeviceExtension->DeviceListCount = 0; From ed022d17fda03b04be0aac91f3a101486c165797 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Fri, 15 Sep 2006 10:36:50 +0000 Subject: [PATCH 213/488] arcoding winetest CreateEnhMetaFileA all param can be NULL and we fail on this. But this is only one bugfix, We need bugfix win32k now. To completed the bugfix svn path=/trunk/; revision=24130 --- reactos/dll/win32/gdi32/objects/metafile.c | 42 +++++++++++++--------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/reactos/dll/win32/gdi32/objects/metafile.c b/reactos/dll/win32/gdi32/objects/metafile.c index c428a0750cf..9ca1f02c93b 100644 --- a/reactos/dll/win32/gdi32/objects/metafile.c +++ b/reactos/dll/win32/gdi32/objects/metafile.c @@ -194,23 +194,33 @@ CreateEnhMetaFileA( LPWSTR lpFileNameW, lpDescriptionW; HDC rc = 0; - Status = HEAP_strdupA2W ( &lpFileNameW, lpFileName ); - if (!NT_SUCCESS (Status)) - SetLastError (RtlNtStatusToDosError(Status)); - else - { - Status = HEAP_strdupA2W ( &lpDescriptionW, lpDescription ); - if (!NT_SUCCESS (Status)) - SetLastError (RtlNtStatusToDosError(Status)); - else - { - rc = NtGdiCreateEnhMetaFile ( - hdcRef, lpFileNameW, (CONST LPRECT)lpRect, lpDescriptionW ); + lpFileNameW = NULL; + if (lpFileName != NULL) + { + Status = HEAP_strdupA2W ( &lpFileNameW, lpFileName ); + if (!NT_SUCCESS (Status)) + SetLastError (RtlNtStatusToDosError(Status)); - HEAP_free ( lpDescriptionW ); - } - HEAP_free ( lpFileNameW ); - } + return rc; + } + + lpDescriptionW = NULL; + if (lpDescription != NULL) + { + Status = HEAP_strdupA2W ( &lpDescriptionW, lpDescription ); + if (!NT_SUCCESS (Status)) + SetLastError (RtlNtStatusToDosError(Status)); + + return rc; + } + + rc = NtGdiCreateEnhMetaFile (hdcRef, lpFileNameW, (CONST LPRECT)lpRect, lpDescriptionW ); + + if (lpDescriptionW != NULL) + HEAP_free ( lpDescriptionW ); + + if (lpFileNameW != NULL) + HEAP_free ( lpFileNameW ); return rc; } From 04a96186b47e69c186569beea3ec919557e71cdb Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 15 Sep 2006 10:45:53 +0000 Subject: [PATCH 214/488] Revert a change in debug.h introduced in 19329 by Hartmut Birr. Freeldr's debug output doesn't expect any DbgPrint call to result in a "__FILE__:__LINE__ output_string" substitution. Now FreeLdr's debug output looks good again. svn path=/trunk/; revision=24131 --- reactos/boot/freeldr/freeldr/include/debug.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/include/debug.h b/reactos/boot/freeldr/freeldr/include/debug.h index ee7c1064619..07371aa32aa 100644 --- a/reactos/boot/freeldr/freeldr/include/debug.h +++ b/reactos/boot/freeldr/freeldr/include/debug.h @@ -41,9 +41,7 @@ VOID DebugPrint1(char *format, ...); VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length); - - #define DbgPrint(_x_) _DbgPrint _x_ ; - #define _DbgPrint(_m_,_x_...) { DebugPrint(_m_, "(%s:%d)", __FILE__, __LINE__); DebugPrint(_m_,_x_);}while(0) + #define DbgPrint(_x_) DebugPrint _x_ ; #define DPRINT1 DebugPrint1 #define BugCheck(_x_) { DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d(%s)\n", __FILE__, __LINE__, __FUNCTION__); DebugPrint _x_ ; for (;;); } #define DbgDumpBuffer(_x_, _y_, _z_) DebugDumpBuffer(_x_, _y_, _z_) From ee7e88e8ec0b95c652ba8633a4f3cb7b37ca01c9 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 15 Sep 2006 16:01:50 +0000 Subject: [PATCH 215/488] Add missing "NTAPI" svn path=/trunk/; revision=24132 --- reactos/lib/rtl/image.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index 6fb56c01310..e7dafc25e25 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -152,6 +152,7 @@ RtlImageRvaToVa ( } PIMAGE_BASE_RELOCATION +NTAPI LdrProcessRelocationBlockLongLong( IN ULONG_PTR Address, IN ULONG Count, From 4094a71f3eca63a14162981c965e20d7e32a8be1 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 15 Sep 2006 16:07:11 +0000 Subject: [PATCH 216/488] Fix typos in comments svn path=/trunk/; revision=24133 --- reactos/boot/freeldr/freeldr/arch/i386/loader.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/loader.c b/reactos/boot/freeldr/freeldr/arch/i386/loader.c index 703567955d2..43a2d975f0f 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/loader.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/loader.c @@ -38,11 +38,11 @@ #define RaToPa(p) \ (ULONG_PTR)((ULONG_PTR)p + KERNEL_BASE_PHYS) -/* Converts a Phsyical Address Pointer into a Page Frame Number */ +/* Converts a Physical Address Pointer into a Page Frame Number */ #define PaPtrToPfn(p) \ (((ULONG_PTR)&p) >> PFN_SHIFT) -/* Converts a Phsyical Address into a Page Frame Number */ +/* Converts a Physical Address into a Page Frame Number */ #define PaToPfn(p) \ ((p) >> PFN_SHIFT) @@ -76,7 +76,7 @@ PLOADER_MODULE CurrentModule = NULL; /* Unrelocated Kernel Base in Virtual Memory */ ULONG_PTR KernelBase; -/* Wether PAE is to be used or not */ +/* Whether PAE is to be used or not */ BOOLEAN PaeModeEnabled; /* Kernel Entrypoint in Physical Memory */ @@ -261,7 +261,7 @@ FrLdrGetKernelBase(VOID) * FrLdrGetPaeMode * INTERNAL * - * Determines whether PAE mode shoudl be enabled or not. + * Determines whether PAE mode should be enabled or not. * * Params: * None. From c09e1c12ab981a1a9db0483a753b205214badb8c Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 15 Sep 2006 16:37:26 +0000 Subject: [PATCH 217/488] - add hardware profile and start and recovery dialogs - popup a message box for dialogs not yet implemented svn path=/trunk/; revision=24134 --- reactos/dll/cpl/sysdm/advanced.c | 11 ++- reactos/dll/cpl/sysdm/en.rc | 129 +++++++++++++++++++++++----- reactos/dll/cpl/sysdm/hardprof.c | 88 +++++++++++++++++++ reactos/dll/cpl/sysdm/hardware.c | 98 ++++++++++++--------- reactos/dll/cpl/sysdm/licence.c | 8 +- reactos/dll/cpl/sysdm/precomp.h | 7 +- reactos/dll/cpl/sysdm/resource.h | 53 ++++++++++-- reactos/dll/cpl/sysdm/startrec.c | 42 +++++++++ reactos/dll/cpl/sysdm/sysdm.rbuild | 2 + reactos/dll/cpl/sysdm/sysdm.rc | 12 ++- reactos/dll/cpl/sysdm/userprofile.c | 11 +-- 11 files changed, 378 insertions(+), 83 deletions(-) create mode 100644 reactos/dll/cpl/sysdm/hardprof.c create mode 100644 reactos/dll/cpl/sysdm/startrec.c diff --git a/reactos/dll/cpl/sysdm/advanced.c b/reactos/dll/cpl/sysdm/advanced.c index 898c0890abb..00603aab7ee 100644 --- a/reactos/dll/cpl/sysdm/advanced.c +++ b/reactos/dll/cpl/sysdm/advanced.c @@ -44,7 +44,16 @@ AdvancedPageProc(HWND hwndDlg, DialogBox(hApplet, MAKEINTRESOURCE(IDD_USERPROFILE), hwndDlg, - (DLGPROC)UserProfileDialogProc); + (DLGPROC)UserProfileDlgProc); + } + break; + + case IDC_STAREC: + { + DialogBox(hApplet, + MAKEINTRESOURCE(IDD_STARTUPRECOVERY), + hwndDlg, + (DLGPROC)StartRecDlgProc); } break; diff --git a/reactos/dll/cpl/sysdm/en.rc b/reactos/dll/cpl/sysdm/en.rc index e92e3f47a67..f4cb1df79a2 100644 --- a/reactos/dll/cpl/sysdm/en.rc +++ b/reactos/dll/cpl/sysdm/en.rc @@ -7,8 +7,9 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN CONTROL "", IDC_ROSIMG, "Static", SS_OWNERDRAW, 4, 5, 248, 111 LTEXT "System:", IDC_STATIC, 4, 132, 32, 9 - LTEXT REACTOS_STR_PRODUCT_NAME, IDC_STATIC, 10, 144, 116, 9 - LTEXT "Version "REACTOS_STR_PRODUCT_VERSION, IDC_STATIC, 10, 153, 116, 9 + //LTEXT REACTOS_STR_PRODUCT_NAME, IDC_STATIC, 10, 144, 116, 9 + LTEXT "Version ", IDC_STATIC, 10, 153, 25, 9 + //LTEXT REACTOS_STR_PRODUCT_VERSION, IDC_STATIC, 35, 153, 91, 9 LTEXT "Machine:", IDC_STATIC, 124, 132, 34, 9 LTEXT "", IDC_PROCESSORMANUFACTURER, 130, 144, 118, 9 LTEXT "", IDC_PROCESSOR, 130, 153, 118, 9 @@ -17,12 +18,13 @@ BEGIN PUSHBUTTON "View licence...", IDC_LICENCE, 90, 199, 78, 13 END + IDD_PROPPAGECOMPUTER DIALOGEX 0, 0, 256, 218 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Computer Name" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - ICON IDI_DEVMGR, IDC_ICON1, 4, 3, 26, 24, SS_ICON + ICON IDI_COMPNAME, IDC_STATIC, 4, 3, 26, 24, SS_ICON LTEXT "ReactOS uses the following information to identify your computer on the network.", IDC_STATIC, 40, 5, 204, 20 LTEXT "Computer Description:", IDC_STATIC, 6, 40, 70, 9 EDITTEXT IDC_COMPDESC, 98, 38, 146, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP @@ -44,17 +46,17 @@ CAPTION "Hardware" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN GROUPBOX "Device Manager", IDC_STATIC, 6, 7, 244, 61 - ICON IDI_DEVMGR, IDC_ICON1, 12, 18, 23, 21, SS_ICON + ICON IDI_DEVMGR, IDC_STATIC, 12, 18, 23, 21, SS_ICON LTEXT "The Device Manager lists all the hardware devices installed on your computer. Use the Device Manager to change the properties of any device.", IDC_STATIC, 42, 18, 204, 24 PUSHBUTTON "&Device Manager...", IDC_HARDWARE_DEVICE_MANAGER, 154, 48, 90, 15 GROUPBOX "Hardware Wizard", IDC_STATIC, 6, 79, 244, 61 - ICON IDI_DEVMGR, IDC_ICON1, 12, 90, 23, 21, SS_ICON + ICON IDI_DEVMGR, IDC_STATIC, 12, 90, 23, 21, SS_ICON LTEXT "The Hardware wizard helps you install, uninstall, repair, unplug, eject, and configure your hardware.", IDC_STATIC, 42, 90, 204, 24 PUSHBUTTON "&Hardware Wizard...", IDC_HARDWARE_WIZARD, 154, 120, 90, 15 GROUPBOX "Hardware Profiles", IDC_STATIC, 6, 149, 244, 61 - ICON IDI_DEVMGR, IDC_ICON1, 12, 160, 23, 21, SS_ICON + ICON IDI_HARDPROF, IDC_STATIC, 12, 160, 23, 21, SS_ICON LTEXT "Hardware profiles provide a way for you to set up and store different hardware configurations.", IDC_STATIC, 42, 160, 204, 24 PUSHBUTTON "Hard&ware Profiles...", IDC_HARDWARE_PROFILE, 154, 190, 90, 15 END @@ -83,12 +85,58 @@ BEGIN END +IDD_HARDWAREPROFILES DIALOGEX 6, 18, 254, 234 +STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Hardware Profiles" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_HARDPROF, IDC_STATIC, 8, 11, 18, 20, SS_ICON + LTEXT "You can set up hardware profiles for different hardware configurations. At startup, you can choose the profile you want to use.", IDC_STATIC, 46, 11, 188, 25 + LTEXT "Available hardware profiles:", IDC_STATIC, 8, 41, 120, 8 + LISTBOX IDC_HRDPROFLSTBOX, 8, 52, 215, 54, LBS_NOTIFY + PUSHBUTTON "", IDC_HRDPROFUP, 232, 59, 15, 15 + PUSHBUTTON "", IDC_HRDPROFDWN, 232, 79, 15, 15 + PUSHBUTTON "&Properties", IDC_HRDPROFPROP, 8, 106, 50, 14 + PUSHBUTTON "&Copy", IDC_HRDPROFCOPY, 63, 106, 50, 14 + PUSHBUTTON "&Rename", IDC_HRDPROFRENAME, 118, 106, 50, 14 + PUSHBUTTON "&Delete", IDC_HRDPROFDEL, 173, 106, 50, 14 + + GROUPBOX "Hardware profiles selection", IDC_STATIC, 7, 130, 240, 75 + LTEXT "When Windows starts:", IDC_STATIC, 14, 142, 210, 8 + //RADIOBUTTON "&Wait until I select a hardware profile", IDC_HRDPROFWAIT, 14, 158, 133, 8 + //RADIOBUTTON "&Select the first profile listed if I don't select a profile in", IDC_HRDPROFSELECT, 14, 173, 190, 8 + CONTROL "&Wait until I select a hardware profile", IDC_HRDPROFWAIT, "button", BS_AUTORADIOBUTTON, 14, 158, 133, 8 + CONTROL "&Select the first profile listed if I don't select a profile in", IDC_HRDPROFSELECT, "button", BS_AUTORADIOBUTTON, 14, 173, 190, 8 + LTEXT "seconds", IDC_STATIC, 65, 187, 35, 8 + EDITTEXT IDC_HRDPROFEDIT, 25, 185, 35, 12 + CONTROL "", IDC_HRDPROFUPDWN, "msctls_updown32", UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | WS_CHILD | WS_VISIBLE, 25, 185, 7, 10 + + DEFPUSHBUTTON "OK", IDOK, 143, 213, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 197, 213, 50, 14 +END + + +IDD_RENAMEPROFILE DIALOGEX 12, 26, 256, 52 +STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Rename Profile" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "From:", IDC_STATIC, 5, 10, 20, 8 + LTEXT "", IDC_RENPROFEDITFROM, 30, 10, 160, 10 + LTEXT "To:", IDC_STATIC, 5, 30, 20, 8 + EDITTEXT IDC_RENPROFEDITTO, 30, 30, 160, 12 + + DEFPUSHBUTTON "OK", IDOK, 196, 6, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 196, 24, 50, 14 +END + + IDD_USERPROFILE DIALOGEX 0, 0, 256, 218 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "User Profiles" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - ICON IDI_DEVMGR, IDC_ICON1, 6, 11, 16, 16, SS_ICON + ICON IDI_USERPROF, IDC_STATIC, 6, 11, 16, 16, SS_ICON LTEXT "User profiles contain desktop settings and other information related to your login. A different profile can be created on each computer you use, or you can select a roaming profile that is the same on every computer you use.", IDC_STATIC, 40, 11, 204, 35 LTEXT "Profiles stored on this computer:", IDC_STATIC, 16, 51, 204, 9 @@ -98,16 +146,52 @@ BEGIN LTEXT "To create new user accounts, open ", IDC_STATIC, 10, 175, 116, 9 // FIXME: needs custom control writing - // CONTROL "", IDC_CUST_LINK, "LinkCtlProc", WS_CHILD | VS_VISIBLE | WS_TABSTOP, 127, 175, 60, 9 + //CONTROL "", IDC_CUST_LINK, "LinkCtlProc", WS_CHILD | VS_VISIBLE | WS_TABSTOP, 127, 175, 60, 9 LTEXT "in Control Panel.", IDC_STATIC, 184, 175, 64, 9 - PUSHBUTTON "OK", IDOK, 134, 197, 54, 13 + DEFPUSHBUTTON "OK", IDOK, 134, 197, 54, 13 PUSHBUTTON "Cancel", IDCANCEL, 196, 197, 54, 13 END +IDD_STARTUPRECOVERY DIALOGEX 6, 18, 252, 280 +STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Startup and Recovery" +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "System startup", IDC_STATIC, 7, 12, 238, 95 + LTEXT "Default operating &system:", IDC_STATIC, 14, 26, 100, 8 + COMBOBOX IDC_STRECOSCOMBO, 14, 37, 224, 46, CBS_DROPDOWNLIST + //CHECKBOX "&Time to display list of operating systems:", IDC_STRECLIST, 14, 56, 150, 8 + CONTROL "&Time to display list of operating systems:", IDC_STRECLIST, "button", BS_CHECKBOX, 14, 56, 150, 8 + EDITTEXT IDC_STRRECLISTEDIT, 179, 54, 30, 12 + CONTROL "", IDC_STRRECLISTUPDWN, "msctls_updown32", UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | WS_CHILD | WS_VISIBLE, 0, 0, 8, 13 + LTEXT "seconds", IDC_STATIC, 215, 56, 25, 8 + CONTROL "Time to &display recovery options when needed:", IDC_STRRECREC, "button", BS_CHECKBOX, 14, 70, 163, 8 + EDITTEXT IDC_STRRECRECEDIT, 179, 68, 30, 12 + CONTROL "", IDC_STRRECRECUPDWN, "msctls_updown32", UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | WS_CHILD | WS_VISIBLE, 0, 0, 8, 13 + LTEXT "seconds", IDC_STATIC, 215, 70, 25, 8 + LTEXT "To edit the startup options file manually, click Edit.", IDC_STATIC, 14, 89, 187, 8 + PUSHBUTTON "&Edit", IDC_STRRECEDIT, 188, 87, 50, 14 + + GROUPBOX "System failure", IDC_STATIC, 7, 111, 238, 140 + CONTROL "&Write an event to the system log", IDC_STRRECWRITEEVENT, "button", BS_AUTOCHECKBOX, 14, 124, 148, 10 + CONTROL "Se&nd an administrative alert", IDC_STRRECSENDALERT, "button", BS_AUTOCHECKBOX, 14, 138, 148, 10 + CONTROL "Automatically &restart", IDC_STRRECRESTART, "button", BS_AUTOCHECKBOX, 14, 152, 145, 10 + + GROUPBOX "Write debugging information", IDC_STATIC, 12, 167, 227, 76 + COMBOBOX IDC_STRRECDEBUGCOMBO, 17, 182, 151, 49, CBS_DROPDOWNLIST + LTEXT "Dump &file:", IDC_STATIC, 17, 202, 150, 8 + EDITTEXT IDC_STRRECDUMPFILE, 17, 210, 153, 12 + CONTROL "&Overwrite any existing file", IDC_STRRECOVERWRITE, "button", BS_AUTOCHECKBOX, 17, 228, 125, 10 + + DEFPUSHBUTTON "OK", IDOK, 141, 259, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 195, 259, 50, 14 +END + + IDD_VIRTMEM DIALOGEX 6, 6, 223, 248 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Virtual Memory" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN @@ -117,9 +201,9 @@ BEGIN 10, 16, 204, 52, WS_EX_CLIENTEDGE GROUPBOX "Paging file size for selected drive", IDC_DRIVEGROUP, 10, 70, 204, 104 - LTEXT "Drive:", IDC_STATIC, 20, 80, 20, 8 + LTEXT "Drive:", IDC_STATIC, 20, 80, 20, 8 LTEXT "", IDC_DRIVE, 88, 81, 100, 9 - LTEXT "Space available:", IDC_STATIC, 20, 92, 56, 9 + LTEXT "Space available:", IDC_STATIC, 20, 92, 56, 9 LTEXT "", IDC_SPACEAVAIL, 84, 92, 104, 9 LTEXT "&Initial size (MB):", -1, 22, 118, 54, 9 LTEXT "Ma&ximum size (MB):", -1, 22, 131, 64, 9 @@ -131,20 +215,20 @@ BEGIN PUSHBUTTON "Set", IDC_SET, 158, 155, 50, 13 GROUPBOX "Total paging file size for all drives", IDC_TOTALGROUP, 10, 177, 204, 46 - LTEXT "Minimum allowed:", IDC_STATIC, 18, 188, 58, 9 + LTEXT "Minimum allowed:", IDC_STATIC, 18, 188, 58, 9 LTEXT "", IDC_MINIMUM, 86, 186, 100, 9 LTEXT "Recommended:", IDC_STATIC, 18, 199, 52, 9 LTEXT "", IDC_RECOMMENDED, 88, 197, 100, 9 LTEXT "Currently allocated:", IDC_STATIC, 18, 210, 66, 9 LTEXT "", IDC_CURRENT, 88, 208, 100, 9 - PUSHBUTTON "OK", IDOK, 114, 232, 48, 13 + DEFPUSHBUTTON "OK", IDOK, 114, 232, 48, 13 PUSHBUTTON "Cancel", IDCANCEL, 168, 232, 48, 13 END IDD_ENVIRONMENT_VARIABLES DIALOGEX 6, 18, 252, 245 -STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Environment Variables" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -164,7 +248,7 @@ BEGIN PUSHBUTTON "Ne&w...", IDC_SYSTEM_VARIABLE_NEW, 80, 194, 50, 14 PUSHBUTTON "Ed&it...", IDC_SYSTEM_VARIABLE_EDIT, 134, 194, 50, 14 PUSHBUTTON "De&lete", IDC_SYSTEM_VARIABLE_DELETE, 188, 194, 50, 14 - PUSHBUTTON "OK", IDOK, 141, 224, 50, 14, WS_GROUP + DEFPUSHBUTTON "OK", IDOK, 141, 224, 50, 14, WS_GROUP PUSHBUTTON "Cancel", IDCANCEL, 195, 224, 50, 14 END @@ -178,17 +262,18 @@ BEGIN EDITTEXT IDC_VARIABLE_NAME, 75, 12, 145, 12, ES_AUTOHSCROLL LTEXT "Variable &Value:", IDC_STATIC, 7, 32, 50, 8 EDITTEXT IDC_VARIABLE_VALUE, 75, 30, 145, 12, ES_AUTOHSCROLL - PUSHBUTTON "OK",IDOK,116,50,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,170,50,50,14 + DEFPUSHBUTTON "OK", IDOK, 116, 50, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 170, 50, 50, 14 END -IDD_LICENCE DIALOGEX 6, 6, 267, 142 +IDD_LICENCE DIALOGEX 6, 5, 267, 159 CAPTION "Licence" FONT 8, "MS Shell Dlg", 0, 0, 0x0 -STYLE WS_BORDER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +STYLE WS_BORDER | WS_THICKFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU BEGIN - EDITTEXT IDC_LICENCEEDIT, 0, 0, 268, 142, WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | ES_READONLY | ES_MULTILINE + EDITTEXT IDC_LICENCEEDIT, 6, 3, 255, 131, WS_VSCROLL | ES_READONLY | ES_MULTILINE + DEFPUSHBUTTON "OK", IDOK, 106, 142, 54, 13 END diff --git a/reactos/dll/cpl/sysdm/hardprof.c b/reactos/dll/cpl/sysdm/hardprof.c new file mode 100644 index 00000000000..32e93ef395a --- /dev/null +++ b/reactos/dll/cpl/sysdm/hardprof.c @@ -0,0 +1,88 @@ +/* + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/hardprof.c + * PURPOSE: Modify hardware profiles + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +/* Property page dialog callback */ +static INT_PTR CALLBACK +RenameProfDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(hwndDlg); + switch(uMsg) + { + case WM_INITDIALOG: + { + MessageBox(hwndDlg, _T("Dialog not yet implemented!"), NULL, 0); + } + break; + + case WM_COMMAND: + { + if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) + { + EndDialog(hwndDlg, + LOWORD(wParam)); + return TRUE; + } + } + break; + } + return FALSE; +} + + +/* Property page dialog callback */ +INT_PTR CALLBACK +HardProfDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(hwndDlg); + switch(uMsg) + { + case WM_INITDIALOG: + { + MessageBox(hwndDlg, _T("Dialog not yet implemented!"), NULL, 0); + } + break; + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_HRDPROFRENAME: + { + DialogBox(hApplet, + MAKEINTRESOURCE(IDD_RENAMEPROFILE), + hwndDlg, + (DLGPROC)RenameProfDlgProc); + } + + case IDOK: + case IDCANCEL: + { + EndDialog(hwndDlg, + LOWORD(wParam)); + return TRUE; + } + } + + } + break; + } + return FALSE; +} diff --git a/reactos/dll/cpl/sysdm/hardware.c b/reactos/dll/cpl/sysdm/hardware.c index 6f98c2dc8c7..27d609312fb 100644 --- a/reactos/dll/cpl/sysdm/hardware.c +++ b/reactos/dll/cpl/sysdm/hardware.c @@ -4,59 +4,79 @@ * FILE: dll/cpl/sysdm/hardware.c * PURPOSE: Hardware devices * COPYRIGHT: Copyright Thomas Weidenmueller + * Copyright 2006 Ged Murphy * */ #include "precomp.h" typedef BOOL (STDCALL *PDEVMGREXEC)(HWND hWndParent, HINSTANCE hInst, PVOID Unknown, int nCmdShow); + BOOL LaunchDeviceManager(HWND hWndParent) { - HMODULE hDll; - PDEVMGREXEC DevMgrExec; - BOOL Ret; + HMODULE hDll; + PDEVMGREXEC DevMgrExec; + BOOL Ret; - hDll = LoadLibrary(_TEXT("devmgr.dll")); - if(!hDll) - return FALSE; - DevMgrExec = (PDEVMGREXEC)GetProcAddress(hDll, "DeviceManager_ExecuteW"); - if(!DevMgrExec) - { + hDll = LoadLibrary(_TEXT("devmgr.dll")); + if(!hDll) + return FALSE; + + DevMgrExec = (PDEVMGREXEC)GetProcAddress(hDll, "DeviceManager_ExecuteW"); + if(!DevMgrExec) + { + FreeLibrary(hDll); + return FALSE; + } + + /* run the Device Manager */ + Ret = DevMgrExec(hWndParent, hApplet, NULL /* ??? */, SW_SHOW); FreeLibrary(hDll); - return FALSE; - } - /* run the Device Manager */ - Ret = DevMgrExec(hWndParent, hApplet, NULL /* ??? */, SW_SHOW); - FreeLibrary(hDll); - return Ret; + return Ret; } /* Property page dialog callback */ INT_PTR CALLBACK -HardwarePageProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) +HardwarePageProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { - UNREFERENCED_PARAMETER(lParam); - switch(uMsg) - { - case WM_INITDIALOG: - break; - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDC_HARDWARE_DEVICE_MANAGER: - if(!LaunchDeviceManager(hwndDlg)) - { - /* FIXME */ - } - break; - } - break; - } - return FALSE; + UNREFERENCED_PARAMETER(lParam); + + switch(uMsg) + { + case WM_INITDIALOG: + break; + + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDC_HARDWARE_DEVICE_MANAGER: + { + if(!LaunchDeviceManager(hwndDlg)) + { + /* FIXME */ + } + + return TRUE; + } + + case IDC_HARDWARE_PROFILE: + { + DialogBox(hApplet, + MAKEINTRESOURCE(IDD_HARDWAREPROFILES), + hwndDlg, + (DLGPROC)HardProfDlgProc); + + return TRUE; + } + } + } + break; + } + + return FALSE; } diff --git a/reactos/dll/cpl/sysdm/licence.c b/reactos/dll/cpl/sysdm/licence.c index 733cd01fa7e..9976eea7281 100644 --- a/reactos/dll/cpl/sysdm/licence.c +++ b/reactos/dll/cpl/sysdm/licence.c @@ -11,10 +11,10 @@ INT_PTR CALLBACK -LicenceDialogProc(HWND hDlg, - UINT message, - WPARAM wParam, - LPARAM lParam) +LicenceDlgProc(HWND hDlg, + UINT message, + WPARAM wParam, + LPARAM lParam) { HRSRC hResInfo; HGLOBAL hResMem; diff --git a/reactos/dll/cpl/sysdm/precomp.h b/reactos/dll/cpl/sysdm/precomp.h index 973d264883b..0e3a8fb9207 100644 --- a/reactos/dll/cpl/sysdm/precomp.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -6,6 +6,7 @@ #include #include #include +#include //shellexecute #include "resource.h" #define NUM_APPLETS (1) @@ -31,10 +32,12 @@ INT_PTR CALLBACK HardwarePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM INT_PTR CALLBACK AdvancedPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); /* dialogs */ -INT_PTR CALLBACK UserProfileDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK HardProfDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK UserProfileDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK EnvironmentDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK StartRecDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK VirtMemDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK LicenceDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK LicenceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); typedef struct _PAGEFILE { diff --git a/reactos/dll/cpl/sysdm/resource.h b/reactos/dll/cpl/sysdm/resource.h index c83723cb6b7..8b402c260f0 100644 --- a/reactos/dll/cpl/sysdm/resource.h +++ b/reactos/dll/cpl/sysdm/resource.h @@ -5,8 +5,11 @@ #define IDI_CPLSYSTEM 50 #define IDI_DEVMGR 51 -#define IDC_ICON1 52 -#define IDB_ROSBMP 53 +#define IDI_COMPNAME 52 +#define IDI_HARDPROF 53 +#define IDI_USERPROF 54 + +#define IDB_ROSBMP 55 #define IDS_CPLSYSTEMNAME 60 #define IDS_CPLSYSTEMDESCRIPTION 61 @@ -92,11 +95,49 @@ #define IDC_CURRENT 914 +/* startup and recovery */ +#define IDD_STARTUPRECOVERY 1000 +#define IDC_STRECOSCOMBO 1001 +#define IDC_STRECLIST 1002 +#define IDC_STRRECLISTEDIT 1003 +#define IDC_STRRECLISTUPDWN 1004 +#define IDC_STRRECREC 1005 +#define IDC_STRRECRECEDIT 1006 +#define IDC_STRRECRECUPDWN 1007 +#define IDC_STRRECEDIT 1008 +#define IDC_STRRECWRITEEVENT 1009 +#define IDC_STRRECSENDALERT 1010 +#define IDC_STRRECRESTART 1011 +#define IDC_STRRECDEBUGCOMBO 1012 +#define IDC_STRRECDUMPFILE 1013 +#define IDC_STRRECOVERWRITE 1014 + + +/* hardware profiles */ +#define IDD_HARDWAREPROFILES 1100 +#define IDC_HRDPROFLSTBOX 1102 +#define IDC_HRDPROFUP 1103 +#define IDC_HRDPROFDWN 1104 +#define IDC_HRDPROFPROP 1105 +#define IDC_HRDPROFCOPY 1106 +#define IDC_HRDPROFRENAME 1107 +#define IDC_HRDPROFDEL 1108 +#define IDC_HRDPROFWAIT 1109 +#define IDC_HRDPROFSELECT 1110 +#define IDC_HRDPROFEDIT 1111 +#define IDC_HRDPROFUPDWN 1112 + + +/* rename profile */ +#define IDD_RENAMEPROFILE 1200 +#define IDC_RENPROFEDITFROM 1201 +#define IDC_RENPROFEDITTO 1202 + /* licence */ -#define IDD_LICENCE 1000 -#define IDC_LICENCEEDIT 1001 -#define RC_LICENSE 1002 -#define RTDATA 1003 +#define IDD_LICENCE 1500 +#define IDC_LICENCEEDIT 1501 +#define RC_LICENSE 1502 +#define RTDATA 1503 #endif /* __CPL_RESOURCE_H */ diff --git a/reactos/dll/cpl/sysdm/startrec.c b/reactos/dll/cpl/sysdm/startrec.c new file mode 100644 index 00000000000..880df23c8d3 --- /dev/null +++ b/reactos/dll/cpl/sysdm/startrec.c @@ -0,0 +1,42 @@ +/* + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/startrec.c + * PURPOSE: Computer settings for startup and recovery + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +/* Property page dialog callback */ +INT_PTR CALLBACK +StartRecDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(hwndDlg); + switch(uMsg) + { + case WM_INITDIALOG: + { + MessageBox(hwndDlg, _T("Dialog not yet implemented!"), NULL, 0); + } + break; + + case WM_COMMAND: + { + if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) + { + EndDialog(hwndDlg, + LOWORD(wParam)); + return TRUE; + } + } + break; + } + return FALSE; +} diff --git a/reactos/dll/cpl/sysdm/sysdm.rbuild b/reactos/dll/cpl/sysdm/sysdm.rbuild index 4d9e6bf4b33..eb574d67635 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rbuild +++ b/reactos/dll/cpl/sysdm/sysdm.rbuild @@ -22,8 +22,10 @@ computer.c environment.c general.c + hardprof.c hardware.c licence.c + startrec.c sysdm.c userprofile.c virtmem.c diff --git a/reactos/dll/cpl/sysdm/sysdm.rc b/reactos/dll/cpl/sysdm/sysdm.rc index 32bf69913e6..11bd6a04581 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rc +++ b/reactos/dll/cpl/sysdm/sysdm.rc @@ -8,12 +8,16 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #define REACTOS_STR_FILE_DESCRIPTION "ReactOS System Applet\0" #define REACTOS_STR_INTERNAL_NAME "sysdm\0" #define REACTOS_STR_ORIGINAL_FILENAME "sysdm.cpl\0" -#include +//#include -IDI_CPLSYSTEM ICON "resources/applet.ico" -IDI_DEVMGR ICON "resources/devmgr.ico" +IDI_CPLSYSTEM ICON "resources/applet.ico" -IDB_ROSBMP BITMAP "resources/rosbitmap.bmp" +IDI_USERPROF ICON "resources/devmgr.ico" +IDI_COMPNAME ICON "resources/devmgr.ico" +IDI_HARDPROF ICON "resources/devmgr.ico" +IDI_DEVMGR ICON "resources/devmgr.ico" + +IDB_ROSBMP BITMAP "resources/rosbitmap.bmp" RC_LICENSE RTDATA "resources/gpl.txt" diff --git a/reactos/dll/cpl/sysdm/userprofile.c b/reactos/dll/cpl/sysdm/userprofile.c index 656431437b6..c1ed603c542 100644 --- a/reactos/dll/cpl/sysdm/userprofile.c +++ b/reactos/dll/cpl/sysdm/userprofile.c @@ -12,10 +12,10 @@ /* Property page dialog callback */ INT_PTR CALLBACK -UserProfileDialogProc(HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) +UserProfileDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(wParam); @@ -24,8 +24,9 @@ UserProfileDialogProc(HWND hwndDlg, { case WM_INITDIALOG: { + MessageBox(hwndDlg, _T("Dialog not yet implemented!"), NULL, 0); } - break; //GetUserName + break; case WM_COMMAND: { From 4db2ab349a3c54e48bb98766225246b146413fc9 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 15 Sep 2006 16:45:00 +0000 Subject: [PATCH 218/488] enable system info (again) svn path=/trunk/; revision=24135 --- reactos/dll/cpl/sysdm/en.rc | 4 ++-- reactos/dll/cpl/sysdm/sysdm.rc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/dll/cpl/sysdm/en.rc b/reactos/dll/cpl/sysdm/en.rc index f4cb1df79a2..109506f89b1 100644 --- a/reactos/dll/cpl/sysdm/en.rc +++ b/reactos/dll/cpl/sysdm/en.rc @@ -7,9 +7,9 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN CONTROL "", IDC_ROSIMG, "Static", SS_OWNERDRAW, 4, 5, 248, 111 LTEXT "System:", IDC_STATIC, 4, 132, 32, 9 - //LTEXT REACTOS_STR_PRODUCT_NAME, IDC_STATIC, 10, 144, 116, 9 + LTEXT REACTOS_STR_PRODUCT_NAME, IDC_STATIC, 10, 144, 116, 9 LTEXT "Version ", IDC_STATIC, 10, 153, 25, 9 - //LTEXT REACTOS_STR_PRODUCT_VERSION, IDC_STATIC, 35, 153, 91, 9 + LTEXT REACTOS_STR_PRODUCT_VERSION, IDC_STATIC, 35, 153, 91, 9 LTEXT "Machine:", IDC_STATIC, 124, 132, 34, 9 LTEXT "", IDC_PROCESSORMANUFACTURER, 130, 144, 118, 9 LTEXT "", IDC_PROCESSOR, 130, 153, 118, 9 diff --git a/reactos/dll/cpl/sysdm/sysdm.rc b/reactos/dll/cpl/sysdm/sysdm.rc index 11bd6a04581..51eed9b9284 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rc +++ b/reactos/dll/cpl/sysdm/sysdm.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #define REACTOS_STR_FILE_DESCRIPTION "ReactOS System Applet\0" #define REACTOS_STR_INTERNAL_NAME "sysdm\0" #define REACTOS_STR_ORIGINAL_FILENAME "sysdm.cpl\0" -//#include +#include IDI_CPLSYSTEM ICON "resources/applet.ico" From dfda3eceff84995d0e608ec26f84ea3719478928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Fri, 15 Sep 2006 17:04:18 +0000 Subject: [PATCH 219/488] Fix "normal" formatting, by removing differences between quick and normal formatting. Normal formatting is quick formatting + fill sectors with 0 (not done yet) svn path=/trunk/; revision=24136 --- reactos/lib/fslib/vfatlib/fat12.c | 11 ++--------- reactos/lib/fslib/vfatlib/fat16.c | 11 ++--------- reactos/lib/fslib/vfatlib/fat32.c | 11 ++--------- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/reactos/lib/fslib/vfatlib/fat12.c b/reactos/lib/fslib/vfatlib/fat12.c index a86a4621b3a..1d4f01afd55 100644 --- a/reactos/lib/fslib/vfatlib/fat12.c +++ b/reactos/lib/fslib/vfatlib/fat12.c @@ -338,15 +338,8 @@ Fat12Format (HANDLE FileHandle, DPRINT("BootSector.FATSectors = %hx\n", BootSector.FATSectors); /* Init context data */ - if (QuickFormat) - { - Context->TotalSectorCount = - 1 + (BootSector.FATSectors * 2) + RootDirSectors; - } - else - { - Context->TotalSectorCount = SectorCount; - } + Context->TotalSectorCount = + 1 + (BootSector.FATSectors * 2) + RootDirSectors; Status = Fat12WriteBootSector (FileHandle, &BootSector, diff --git a/reactos/lib/fslib/vfatlib/fat16.c b/reactos/lib/fslib/vfatlib/fat16.c index de41a2ac6e9..d59b47edcff 100644 --- a/reactos/lib/fslib/vfatlib/fat16.c +++ b/reactos/lib/fslib/vfatlib/fat16.c @@ -356,15 +356,8 @@ Fat16Format (HANDLE FileHandle, DPRINT("BootSector.FATSectors = %hu\n", BootSector.FATSectors); /* Init context data */ - if (QuickFormat) - { - Context->TotalSectorCount = - 1 + (BootSector.FATSectors * 2) + RootDirSectors; - } - else - { - Context->TotalSectorCount = SectorCount; - } + Context->TotalSectorCount = + 1 + (BootSector.FATSectors * 2) + RootDirSectors; Status = Fat16WriteBootSector (FileHandle, &BootSector, diff --git a/reactos/lib/fslib/vfatlib/fat32.c b/reactos/lib/fslib/vfatlib/fat32.c index c2b87665c36..13c2a2e06bb 100644 --- a/reactos/lib/fslib/vfatlib/fat32.c +++ b/reactos/lib/fslib/vfatlib/fat32.c @@ -429,15 +429,8 @@ Fat32Format (HANDLE FileHandle, DPRINT("FATSectors32 = %lu\n", BootSector.FATSectors32); /* Init context data */ - if (QuickFormat) - { - Context->TotalSectorCount = - 2 + (BootSector.FATSectors32 * BootSector.FATCount) + BootSector.SectorsPerCluster; - } - else - { - Context->TotalSectorCount = BootSector.SectorsHuge; - } + Context->TotalSectorCount = + 2 + (BootSector.FATSectors32 * BootSector.FATCount) + BootSector.SectorsPerCluster; Status = Fat32WriteBootSector (FileHandle, &BootSector, From aa64d1177fb47d3f0ebafd85a6aed42efa85924b Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Fri, 15 Sep 2006 23:24:04 +0000 Subject: [PATCH 220/488] Implement NtGdiCreateEnhMetaFile it is base on wine cvs 15/9-2006 version of CreateEnhMetaFileW in wine gdi32.dll Our are not complete it can not create the file. But we parseing now some NULL pointer test and some other test in winetest for gdi32. svn path=/trunk/; revision=24137 --- reactos/subsystems/win32/win32k/include/dc.h | 4 + .../win32/win32k/objects/metafile.c | 166 +++++++++++++++++- 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index e1019f6de77..542a19de282 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -121,6 +121,10 @@ typedef struct _DC HPALETTE PalIndexed; WIN_DC_INFO w; + + HANDLE hFile; + LPENHMETAHEADER emh; + } DC, *PDC; typedef struct _GDIPOINTER /* should stay private to ENG */ diff --git a/reactos/subsystems/win32/win32k/objects/metafile.c b/reactos/subsystems/win32/win32k/objects/metafile.c index aa7e02f6f0a..9c832ba371e 100644 --- a/reactos/subsystems/win32/win32k/objects/metafile.c +++ b/reactos/subsystems/win32/win32k/objects/metafile.c @@ -64,10 +64,172 @@ NtGdiCreateEnhMetaFile(HDC hDCRef, CONST LPRECT Rect, LPCWSTR Description) { - UNIMPLEMENTED; - return 0; + PDC Dc; + HDC ret = NULL; + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + DWORD length = 0; + HDC tempHDC; + DWORD MemSize; + + tempHDC = hDCRef; + if (hDCRef == NULL) + { + /* FIXME ?? + * Shall we create hdc NtGdiHdcCompatible hdc ?? + */ + UNICODE_STRING DriverName; + RtlInitUnicodeString(&DriverName, L"DISPLAY"); + tempHDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE); + } + + + Dc = DC_LockDc(tempHDC); + if (Dc == NULL) + { + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + SetLastWin32Error(ERROR_INVALID_HANDLE); + return NULL; + } + + if(Description) + { + length = wcslen(Description); + length += wcslen(Description + length + 1); + length += 3; + length *= 2; + } + + MemSize = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4; + + if (!(Dc->emh = EngAllocMem(FL_ZERO_MEMORY, MemSize, 0))) + { + DC_UnlockDc(Dc); + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + SetLastWin32Error(ERROR_INVALID_HANDLE); + return NULL; + } + + Dc->emh->iType = EMR_HEADER; + Dc->emh->nSize = MemSize; + + Dc->emh->rclBounds.left = Dc->emh->rclBounds.top = 0; + Dc->emh->rclBounds.right = Dc->emh->rclBounds.bottom = -1; + + if(Rect) + { + Dc->emh->rclFrame.left = Rect->left; + Dc->emh->rclFrame.top = Rect->top; + Dc->emh->rclFrame.right = Rect->right; + Dc->emh->rclFrame.bottom = Rect->bottom; + } + else + { + /* Set this to {0,0 - -1,-1} and update it at the end */ + Dc->emh->rclFrame.left = Dc->emh->rclFrame.top = 0; + Dc->emh->rclFrame.right = Dc->emh->rclFrame.bottom = -1; + } + + Dc->emh->dSignature = ENHMETA_SIGNATURE; + Dc->emh->nVersion = 0x10000; + Dc->emh->nBytes = Dc->emh->nSize; + Dc->emh->nRecords = 1; + Dc->emh->nHandles = 1; + + Dc->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */ + Dc->emh->nDescription = length / 2; + + Dc->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0; + + Dc->emh->nPalEntries = 0; /* I guess this should start at 0 */ + + /* Size in pixels */ + Dc->emh->szlDevice.cx = NtGdiGetDeviceCaps(tempHDC, HORZRES); + Dc->emh->szlDevice.cy = NtGdiGetDeviceCaps(tempHDC, VERTRES); + + /* Size in millimeters */ + Dc->emh->szlMillimeters.cx = NtGdiGetDeviceCaps(tempHDC, HORZSIZE); + Dc->emh->szlMillimeters.cy = NtGdiGetDeviceCaps(tempHDC, VERTSIZE); + + /* Size in micrometers */ + Dc->emh->szlMicrometers.cx = Dc->emh->szlMillimeters.cx * 1000; + Dc->emh->szlMicrometers.cy = Dc->emh->szlMillimeters.cy * 1000; + + if(Description) + { + memcpy((char *)Dc->emh + sizeof(ENHMETAHEADER), Description, length); + } + + ret = tempHDC; + + DPRINT1("File cretae unimplement in NtGdiCreateEnhMetaFile\n"); + if (File) + { + + + + /* disk based metafile */ + + /* FIXME + if ((Dc->hFile = CreateFileW(File, GENERIC_WRITE | GENERIC_READ, 0, + NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) + { + DC_UnLockDc(Dc); + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + return 0; + } + */ + + Status = NtWriteFile(Dc->hFile, NULL, NULL, NULL, &Iosb, (PVOID)&Dc->emh, Dc->emh->nSize, NULL, NULL); + if (Status == STATUS_PENDING) + { + Status = NtWaitForSingleObject(Dc->hFile,FALSE,NULL); + if (NT_SUCCESS(Status)) + { + Status = Iosb.Status; + } + } + + if (NT_SUCCESS(Status)) + { + //ret = Dc->hSelf; + ret = tempHDC; + DC_UnlockDc(Dc); + } + else + { + Dc->hFile = NULL; + /* FIXME use SetLastErrorByStatus */ + //SetLastErrorByStatus(Status); + SetLastWin32Error(ERROR_CAN_NOT_COMPLETE); + ret = NULL; + DC_UnlockDc(Dc); + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + } + } + else + { + DC_UnlockDc(Dc); + } + + return ret; } + + + HDC STDCALL NtGdiCreateMetaFile(LPCWSTR File) From d6644201824262520c20663f24e38d220f5e4d26 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sat, 16 Sep 2006 00:07:02 +0000 Subject: [PATCH 221/488] - Merge in my latest Dispatcher changes for KeWaitForMultipleObject, which are basically the same kind of changes as have been done for KeDelay/KeWaitForSingle. (Optimizations and readability improvements). - Also fixed a previous bug where we didn't respect alertable waits anymore for KeWaitForMultiple... - Remove krnlfun entry, the rest of dispatcher changes are tied to the new timer implementation for later. svn path=/trunk/; revision=24138 --- reactos/ntoskrnl/KrnlFun.c | 1 - reactos/ntoskrnl/include/internal/ke_x.h | 34 ++ reactos/ntoskrnl/ke/wait.c | 423 +++++++++++------------ 3 files changed, 240 insertions(+), 218 deletions(-) diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index e093cbca02b..d3ced538cc7 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -33,7 +33,6 @@ // * Add DR macro/save and VM macro/save. // - FEATURES: // * New optimized table-based tick-hashed timer implementation. -// * New optimized dispatching logic/branching. // * New Thread Scheduler based on 2003. // * Proper Idle/Initial Thread setup and 2nd stage boot. // * Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion. diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 0f35b072f56..3fc6da54c21 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -331,6 +331,40 @@ KxDelayThreadWait(IN PKTHREAD Thread, return Swappable; } +FORCEINLINE +BOOLEAN +KxMultiThreadWait(IN PKTHREAD Thread, + IN PKWAIT_BLOCK WaitBlock, + IN BOOLEAN Alertable, + IN KWAIT_REASON WaitReason, + IN KPROCESSOR_MODE WaitMode) +{ + BOOLEAN Swappable; + PKTIMER ThreadTimer = &Thread->Timer; + + /* Set default wait status */ + Thread->WaitStatus = STATUS_WAIT_0; + + /* Link wait block array to the thread */ + Thread->WaitBlockList = WaitBlock; + + /* Initialize the timer list */ + InitializeListHead(&ThreadTimer->Header.WaitListHead); + + /* Set wait settings */ + Thread->Alertable = Alertable; + Thread->WaitMode = WaitMode; + Thread->WaitReason = WaitReason; + + /* Check if we can swap the thread's stack */ + Thread->WaitListEntry.Flink = NULL; + Swappable = KiCheckThreadStackSwap(Thread, WaitMode); + + /* Set the wait time */ + Thread->WaitTime = ((PLARGE_INTEGER)&KeTickCount)->LowPart; + return Swappable; +} + FORCEINLINE BOOLEAN KxSingleThreadWait(IN PKTHREAD Thread, diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 21bf97560c1..2f35b05797e 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -556,7 +556,7 @@ KeWaitForMultipleObjects(IN ULONG Count, PKWAIT_BLOCK WaitBlock; PKWAIT_BLOCK TimerWaitBlock; PKTIMER ThreadTimer; - PKTHREAD CurrentThread = KeGetCurrentThread(); + PKTHREAD Thread = KeGetCurrentThread(); ULONG AllObjectsSignaled; ULONG WaitIndex; NTSTATUS WaitStatus = STATUS_SUCCESS; @@ -564,21 +564,6 @@ KeWaitForMultipleObjects(IN ULONG Count, PLARGE_INTEGER OriginalDueTime = Timeout; LARGE_INTEGER DueTime, NewDueTime; - /* Set the Current Thread */ - CurrentThread = KeGetCurrentThread(); - - /* Check if the lock is already held */ - if (CurrentThread->WaitNext) - { - /* Lock is held, disable Wait Next */ - CurrentThread->WaitNext = FALSE; - } - else - { - /* Lock not held, acquire it */ - CurrentThread->WaitIrql = KiAcquireDispatcherLock(); - } - /* Make sure the Wait Count is valid */ if (!WaitBlockArray) { @@ -590,7 +575,7 @@ KeWaitForMultipleObjects(IN ULONG Count, } /* Use the Thread's Wait Block */ - WaitBlockArray = &CurrentThread->WaitBlock[0]; + WaitBlockArray = &Thread->WaitBlock[0]; } else { @@ -602,227 +587,231 @@ KeWaitForMultipleObjects(IN ULONG Count, } } - /* Start the actual Loop */ - do + /* Sanity check */ + ASSERT(Count != 0); + + /* Check if the lock is already held */ + if (Thread->WaitNext) { - /* Check if a kernel APC is pending and we're below APC_LEVEL */ - if ((CurrentThread->ApcState.KernelApcPending) && - !(CurrentThread->SpecialApcDisable) && - (CurrentThread->WaitIrql < APC_LEVEL)) + /* Lock is held, disable Wait Next */ + Thread->WaitNext = FALSE; + } + else + { + /* Lock not held, acquire it */ +StartWait: + Thread->WaitIrql = KiAcquireDispatcherLock(); + } + + /* Prepare for the wait */ + Swappable = KxMultiThreadWait(Thread, + WaitBlockArray, + Alertable, + WaitReason, + WaitMode); + + /* Check if a kernel APC is pending and we're below APC_LEVEL */ + if ((Thread->ApcState.KernelApcPending) && !(Thread->SpecialApcDisable) && + (Thread->WaitIrql < APC_LEVEL)) + { + /* Unlock the dispatcher */ + KiReleaseDispatcherLock(Thread->WaitIrql); + goto StartWait; + } + + /* Append wait block to the KTHREAD wait block list */ + WaitBlock = WaitBlockArray; + + /* Check if the wait is (already) satisfied */ + AllObjectsSignaled = TRUE; + + /* First, we'll try to satisfy the wait directly */ + for (WaitIndex = 0; WaitIndex < Count; WaitIndex++) + { + /* Get the Current Object */ + CurrentObject = (PKMUTANT)Object[WaitIndex]; + ASSERT(CurrentObject->Header.Type != QueueObject); + + /* Check the type of wait */ + if (WaitType == WaitAny) { - /* Unlock the dispatcher */ - KiReleaseDispatcherLock(CurrentThread->WaitIrql); + /* Check if the Object is a mutant */ + if (CurrentObject->Header.Type == MutantObject) + { + /* Check if it's signaled */ + if ((CurrentObject->Header.SignalState > 0) || + (Thread == CurrentObject->OwnerThread)) + { + /* This is a Wait Any, so unwait this and exit */ + if (CurrentObject->Header.SignalState != + (LONG)MINLONG) + { + /* Normal signal state, unwait it and return */ + KiSatisfyMutantWait(CurrentObject, Thread); + WaitStatus = Thread->WaitStatus | WaitIndex; + goto DontWait; + } + else + { + /* Raise an exception (see wasm.ru) */ + KiReleaseDispatcherLock(Thread->WaitIrql); + ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); + } + } + } + else if (CurrentObject->Header.SignalState > 0) + { + /* Another signaled object, unwait and return */ + KiSatisfyNonMutantWait(CurrentObject, Thread); + WaitStatus = WaitIndex; + goto DontWait; + } } else { - /* Append wait block to the KTHREAD wait block list */ - CurrentThread->WaitBlockList = WaitBlock = WaitBlockArray; - - /* Set default wait status */ - CurrentThread->WaitStatus = STATUS_WAIT_0; - - /* Check if the wait is (already) satisfied */ - AllObjectsSignaled = TRUE; - - /* First, we'll try to satisfy the wait directly */ - for (WaitIndex = 0; WaitIndex < Count; WaitIndex++) + /* Check if we're dealing with a mutant again */ + if (CurrentObject->Header.Type == MutantObject) { - /* Get the Current Object */ - CurrentObject = (PKMUTANT)Object[WaitIndex]; - - /* Check the type of wait */ - if (WaitType == WaitAny) + /* Check if it has an invalid count */ + if ((Thread == CurrentObject->OwnerThread) && + (CurrentObject->Header.SignalState == MINLONG)) { - /* Check if the Object is a mutant */ - if (CurrentObject->Header.Type == MutantObject) - { - /* Check if it's signaled */ - if ((CurrentObject->Header.SignalState > 0) || - (CurrentThread == CurrentObject->OwnerThread)) - { - /* This is a Wait Any, so unwait this and exit */ - if (CurrentObject->Header.SignalState != - (LONG)MINLONG) - { - /* Normal signal state, unwait it and return */ - KiSatisfyMutantWait(CurrentObject, - CurrentThread); - WaitStatus = CurrentThread->WaitStatus | - WaitIndex; - goto DontWait; - } - else - { - /* Raise an exception (see wasm.ru) */ - KiReleaseDispatcherLock(CurrentThread-> - WaitIrql); - ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); - } - } - } - else if (CurrentObject->Header.SignalState > 0) - { - /* Another signaled object, unwait and return */ - KiSatisfyNonMutantWait(CurrentObject, CurrentThread); - WaitStatus = WaitIndex; - goto DontWait; - } + /* Raise an exception */ + KiReleaseDispatcherLock(Thread->WaitIrql); + ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); } - else + else if ((CurrentObject->Header.SignalState <= 0) && + (Thread != CurrentObject->OwnerThread)) { - /* Check if we're dealing with a mutant again */ - if (CurrentObject->Header.Type == MutantObject) - { - /* Check if it has an invalid count */ - if ((CurrentThread == CurrentObject->OwnerThread) && - (CurrentObject->Header.SignalState == MINLONG)) - { - /* Raise an exception */ - KiReleaseDispatcherLock(CurrentThread-> - WaitIrql); - ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); - } - else if ((CurrentObject->Header.SignalState <= 0) && - (CurrentThread != CurrentObject->OwnerThread)) - { - /* We don't own it, can't satisfy the wait */ - AllObjectsSignaled = FALSE; - } - } - else if (CurrentObject->Header.SignalState <= 0) - { - /* Not signaled, can't satisfy */ - AllObjectsSignaled = FALSE; - } + /* We don't own it, can't satisfy the wait */ + AllObjectsSignaled = FALSE; } - - /* Set up a Wait Block for this Object */ - WaitBlock->Object = CurrentObject; - WaitBlock->Thread = CurrentThread; - WaitBlock->WaitKey = (USHORT)WaitIndex; - WaitBlock->WaitType = (UCHAR)WaitType; - WaitBlock->NextWaitBlock = WaitBlock + 1; - - /* Move to the next Wait Block */ - WaitBlock = WaitBlock->NextWaitBlock; } - - /* Return to the Root Wait Block */ - WaitBlock--; - WaitBlock->NextWaitBlock = WaitBlockArray; - - /* Check if this is a Wait All and all the objects are signaled */ - if ((WaitType == WaitAll) && (AllObjectsSignaled)) + else if (CurrentObject->Header.SignalState <= 0) { - /* Return to the Root Wait Block */ - WaitBlock = CurrentThread->WaitBlockList; - - /* Satisfy their Waits and return to the caller */ - KiWaitSatisfyAll(WaitBlock); - WaitStatus = CurrentThread->WaitStatus; - goto DontWait; + /* Not signaled, can't satisfy */ + AllObjectsSignaled = FALSE; } - - /* Make sure we can satisfy the Alertable request */ - WaitStatus = KiCheckAlertability(CurrentThread, Alertable, WaitMode); - - /* Check if we can swap the thread's stack */ - CurrentThread->WaitListEntry.Flink = NULL; - Swappable = KiCheckThreadStackSwap(CurrentThread, WaitMode); - - /* Enable the Timeout Timer if there was any specified */ - if (Timeout) - { - /* Make sure the timeout interval isn't actually 0 */ - if (!Timeout->QuadPart) - { - /* Return a timeout */ - WaitStatus = STATUS_TIMEOUT; - goto DontWait; - } - - /* Point to Timer Wait Block and Thread Timer */ - TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK]; - ThreadTimer = &CurrentThread->Timer; - - /* Connect the Timer Wait Block */ - WaitBlock->NextWaitBlock = TimerWaitBlock; - - /* Set up the Timer Wait Block */ - TimerWaitBlock->NextWaitBlock = WaitBlockArray; - - /* Initialize the list head */ - InitializeListHead(&ThreadTimer->Header.WaitListHead); - - /* Insert the Timer into the Timer Lists and enable it */ - if (!KiInsertTimer(ThreadTimer, *Timeout)) - { - /* Return a timeout if we couldn't insert the timer */ - WaitStatus = STATUS_TIMEOUT; - goto DontWait; - } - - /* Set the current due time */ - DueTime.QuadPart = ThreadTimer->DueTime.QuadPart; - } - - /* Insert into Object's Wait List*/ - WaitBlock = CurrentThread->WaitBlockList; - do - { - /* Get the Current Object */ - CurrentObject = WaitBlock->Object; - - /* Link the Object to this Wait Block */ - InsertTailList(&CurrentObject->Header.WaitListHead, - &WaitBlock->WaitListEntry); - - /* Move to the next Wait Block */ - WaitBlock = WaitBlock->NextWaitBlock; - } while (WaitBlock != WaitBlockArray); - - /* Handle Kernel Queues */ - if (CurrentThread->Queue) KiActivateWaiterQueue(CurrentThread->Queue); - - /* Setup the wait information */ - CurrentThread->Alertable = Alertable; - CurrentThread->WaitMode = WaitMode; - CurrentThread->WaitReason = WaitReason; - CurrentThread->WaitTime = ((PLARGE_INTEGER)&KeTickCount)->LowPart; - CurrentThread->State = Waiting; - - /* Find a new thread to run */ - KiAddThreadToWaitList(CurrentThread, Swappable); - WaitStatus = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - /* Check if we were executing an APC */ - if (WaitStatus != STATUS_KERNEL_APC) return WaitStatus; - - /* Check if we had a timeout */ - if (Timeout) - { - /* Recalculate due times */ - Timeout = KiRecalculateDueTime(OriginalDueTime, - &DueTime, - &NewDueTime); - } - - /* Acquire again the lock */ - CurrentThread->WaitIrql = KiAcquireDispatcherLock(); } - } while (TRUE); - /* Release the Lock, we are done */ - KiReleaseDispatcherLock(CurrentThread->WaitIrql); + /* Set up a Wait Block for this Object */ + WaitBlock = &WaitBlockArray[WaitIndex]; + WaitBlock->Object = CurrentObject; + WaitBlock->Thread = Thread; + WaitBlock->WaitKey = (USHORT)WaitIndex; + WaitBlock->WaitType = (UCHAR)WaitType; + WaitBlock->NextWaitBlock = &WaitBlockArray[WaitIndex + 1]; + } + + /* Check if this is a Wait All and all the objects are signaled */ + if ((WaitType == WaitAll) && (AllObjectsSignaled)) + { + /* Return to the Root Wait Block */ + WaitBlock->NextWaitBlock = &WaitBlockArray[0]; + + /* Satisfy their Waits and return to the caller */ + KiWaitSatisfyAll(WaitBlock); + WaitStatus = Thread->WaitStatus; + goto DontWait; + } + + /* Make sure we can satisfy the Alertable request */ + WaitStatus = KiCheckAlertability(Thread, Alertable, WaitMode); + if (WaitStatus != STATUS_WAIT_0) + { + /* Unlock the dispatcher and return */ + KiReleaseDispatcherLock(Thread->WaitIrql); + return WaitStatus; + } + + /* Enable the Timeout Timer if there was any specified */ + if (Timeout) + { + /* Make sure the timeout interval isn't actually 0 */ + if (!Timeout->QuadPart) + { + /* Return a timeout */ + WaitStatus = STATUS_TIMEOUT; + goto DontWait; + } + + /* Link timer wait block */ + TimerWaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK]; + WaitBlock->NextWaitBlock = TimerWaitBlock; + + /* Use this the timer block for linking below */ + WaitBlock = TimerWaitBlock; + + /* Insert the Timer into the Timer Lists and enable it */ + ThreadTimer = &Thread->Timer; + if (!KiInsertTimer(ThreadTimer, *Timeout)) + { + /* Return a timeout if we couldn't insert the timer */ + WaitStatus = STATUS_TIMEOUT; + goto DontWait; + } + + /* Set the current due time */ + DueTime.QuadPart = ThreadTimer->DueTime.QuadPart; + } + + /* Link to the Root Wait Block */ + WaitBlock->NextWaitBlock = &WaitBlockArray[0]; + + /* Insert into Object's Wait List*/ + WaitBlock = &WaitBlockArray[0]; + do + { + /* Get the Current Object */ + CurrentObject = WaitBlock->Object; + + /* Link the Object to this Wait Block */ + InsertTailList(&CurrentObject->Header.WaitListHead, + &WaitBlock->WaitListEntry); + + /* Move to the next Wait Block */ + WaitBlock = WaitBlock->NextWaitBlock; + } while (WaitBlock != WaitBlockArray); + + /* Handle Kernel Queues */ + if (Thread->Queue) KiActivateWaiterQueue(Thread->Queue); + + /* Setup the wait information */ + Thread->State = Waiting; + + /* Add the thread to the wait list */ + KiAddThreadToWaitList(Thread, Swappable); + + /* Swap the thread */ + ASSERT(Thread->WaitIrql <= DISPATCH_LEVEL); + KiSetThreadSwapBusy(Thread); + WaitStatus = KiSwapThread(Thread, KeGetCurrentPrcb()); + + /* Check if we were executing an APC */ + if (WaitStatus == STATUS_KERNEL_APC) + { + /* Check if we had a timeout */ + if (Timeout) + { + /* Recalculate due times */ + Timeout = KiRecalculateDueTime(OriginalDueTime, + &DueTime, + &NewDueTime); + } + + /* Wait again */ + goto StartWait; + } + + /* We are done */ return WaitStatus; DontWait: /* Adjust the Quantum */ - KiAdjustQuantumThread(CurrentThread); + KiAdjustQuantumThread(Thread); /* Release & Return */ - KiReleaseDispatcherLock(CurrentThread->WaitIrql); + KiReleaseDispatcherLock(Thread->WaitIrql); return WaitStatus; } From f20c6b89df6ac9256859f256b929422320d6cdda Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 16 Sep 2006 01:56:51 +0000 Subject: [PATCH 222/488] Not sure where LicenseDialogProc is supposed to come from. For now, we'll disable it until it gets fixed. svn path=/trunk/; revision=24139 --- reactos/dll/cpl/sysdm/general.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index c2357575bc5..39d28633ddb 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -104,11 +104,12 @@ GeneralPageProc(HWND hwndDlg, { if (LOWORD(wParam) == IDC_LICENCE) { +#ifdef LICENSE_FIXME_I_CANT_FIND_LICENSE_DIALOG_PROC_ANYWHERE DialogBox(hApplet, MAKEINTRESOURCE(IDD_LICENCE), hwndDlg, - LicenceDialogProc); - + LicenseDialogProc); +#endif return TRUE; } } From 6b30b92bf0e65415b3c33b43c98cb42e21c10302 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 16 Sep 2006 05:29:25 +0000 Subject: [PATCH 223/488] I think this was on Ged mind. svn path=/trunk/; revision=24140 --- reactos/dll/cpl/sysdm/general.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index 39d28633ddb..84d66a745ff 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -104,12 +104,10 @@ GeneralPageProc(HWND hwndDlg, { if (LOWORD(wParam) == IDC_LICENCE) { -#ifdef LICENSE_FIXME_I_CANT_FIND_LICENSE_DIALOG_PROC_ANYWHERE DialogBox(hApplet, MAKEINTRESOURCE(IDD_LICENCE), hwndDlg, - LicenseDialogProc); -#endif + LicenceDlgProc); return TRUE; } } From 5acd247d8eac4be20f5fac90ee5143319f3af3b9 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sat, 16 Sep 2006 06:03:04 +0000 Subject: [PATCH 224/488] - Implement most of the Ring 3/0 Invalid Opcode handler. Stops apps like mIRC from BSODing the system anymore. svn path=/trunk/; revision=24141 --- reactos/include/ndk/asm.h | 2 + reactos/ntoskrnl/KrnlFun.c | 1 - reactos/ntoskrnl/ke/i386/trap.s | 103 +++++++++++++++++++++++++++++++- 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 5d90b39a8c4..568e6b117d1 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -440,12 +440,14 @@ Author: #define STATUS_CALLBACK_POP_STACK 0xC0000423 #define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C #define STATUS_ILLEGAL_INSTRUCTION 0xC000001D +#define STATUS_INVALID_LOCK_SEQUENCE 0xC000001E #define STATUS_BREAKPOINT 0x80000003 #define STATUS_SINGLE_STEP 0x80000004 #define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094 #define STATUS_INTEGER_OVERFLOW 0xC0000095 #define APC_INDEX_MISMATCH 0x01 #define TRAP_CAUSE_UNKNOWN 0x12 +#define KMODE_EXCEPTION_NOT_HANDLED 0x13 #define IRQL_GT_ZERO_AT_SYSTEM_SERVICE 0x4A #define UNEXPECTED_KERNEL_MODE_TRAP 0x7F #define ATTEMPTED_SWITCH_FROM_DPC 0xB8 diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index d3ced538cc7..8a011352c37 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -27,7 +27,6 @@ // Ke: // // - FIXES: -// * Implement invalid opcode handler (fixes some apps from crashing). // * Get rid of KiRosPrintAddress and use KiDumpParameterImages instead. // * Sanitize some context fields during conversions. // * Add DR macro/save and VM macro/save. diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 5ceffb3c0f3..6d061dfb8ff 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -966,18 +966,117 @@ V86Int5: .func KiTrap6 _KiTrap6: + + /* It this a V86 GPF? */ + test dword ptr [esp+8], EFLAGS_V86_MASK + jz NotV86UD + + /* Enter V86 Trap */ + V86_TRAP_PROLOG kit6 + + /* Not yet supported (Invalid OPCODE from V86) */ + int 3 + jmp $ + +NotV86UD: /* Push error code */ push 0 /* Enter trap */ TRAP_PROLOG(6) - /* Not yet supported */ + /* Check if this happened in kernel mode */ + test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK + jz KmodeOpcode + + /* Check for VDM */ + cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK + jz UmodeOpcode + + /* Check if the process is vDM */ + mov ebx, fs:[KPCR_CURRENT_THREAD] + mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS] + cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 + jnz IsVdmOpcode + +UmodeOpcode: + /* Get EIP and enable interrupts at this point */ + mov esi, [ebp+KTRAP_FRAME_EIP] + sti + + /* Set intruction prefix length */ + mov ecx, 4 + + /* Setup a SEH frame */ + push ebp + push OpcodeSEH + push fs:[KPCR_EXCEPTION_LIST] + mov fs:[KPCR_EXCEPTION_LIST], esp + +OpcodeLoop: + /* Get the instruction and check if it's LOCK */ + mov al, [esi] + cmp al, 0xF0 + jz LockCrash + + /* Keep moving */ + add esi, 1 + loop OpcodeLoop + + /* Undo SEH frame */ + pop fs:[KPCR_EXCEPTION_LIST] + add esp, 8 + +KmodeOpcode: + + /* Re-enable interrupts */ + sti + + /* Setup illegal instruction exception and dispatch it */ + mov ebx, [ebp+KTRAP_FRAME_EIP] + mov eax, STATUS_ILLEGAL_INSTRUCTION + jmp _DispatchNoParam + +LockCrash: + + /* Undo SEH Frame */ + pop fs:[KPCR_EXCEPTION_LIST] + add esp, 8 + + /* Setup invalid lock exception and dispatch it */ + mov ebx, [ebp+KTRAP_FRAME_EIP] + mov eax, STATUS_INVALID_LOCK_SEQUENCE + jmp _DispatchNoParam + +IsVdmOpcode: + + /* Unhandled yet */ int 3 jmp $ /* Return to caller */ jmp _Kei386EoiHelper@0 + +OpcodeSEH: + + /* Get SEH frame */ + mov esp, [esp+8] + pop fs:[KPCR_EXCEPTION_LIST] + add esp, 4 + pop ebp + + /* Check if this was user mode */ + test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK + jnz KmodeOpcode + + /* Do a bugcheck */ + push ebp + push 0 + push 0 + push 0 + push 0 + push KMODE_EXCEPTION_NOT_HANDLED + call _KeBugCheckWithTf@24 .endfunc .func KiTrap7 @@ -1552,7 +1651,7 @@ Handled: _KiUnexpectedInterrupt: /* Bugcheck with invalid interrupt code */ - push 0x12 + push TRAP_CAUSE_UNKNOWN call _KeBugCheck@4 /* INTERRUPT HANDLERS ********************************************************/ From bb1f92d0d368b880b3a54c366a91baf5f87cbcb8 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sat, 16 Sep 2006 06:40:37 +0000 Subject: [PATCH 225/488] fixed a memory I accident created when to free a hdc svn path=/trunk/; revision=24142 --- reactos/subsystems/win32/win32k/objects/dc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index 446da68073a..f3a43d4607e 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -1110,6 +1110,12 @@ NtGdiDeleteObjectApp(HANDLE DCHandle) #if 0 /* FIXME */ PATH_DestroyGdiPath (&DCToDelete->w.path); #endif + + if (DCToDelete->emh) + { + EngFreeMem(DCToDelete->emh); + } + DC_UnlockDc( DCToDelete ); DC_FreeDC ( DCHandle ); From a06bdc9503e63b1ccd9860d24097b6fb823a9942 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Sat, 16 Sep 2006 15:39:07 +0000 Subject: [PATCH 226/488] explorer: handle child window creation errors svn path=/trunk/; revision=24143 --- reactos/base/shell/explorer/shell/filechild.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/reactos/base/shell/explorer/shell/filechild.cpp b/reactos/base/shell/explorer/shell/filechild.cpp index 87e280c331e..f23d271600e 100644 --- a/reactos/base/shell/explorer/shell/filechild.cpp +++ b/reactos/base/shell/explorer/shell/filechild.cpp @@ -246,9 +246,12 @@ FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info) _header_wdths_ok = false; + if (!_left_hwnd && !_right_hwnd) + return; + if (entry) set_curdir(entry); - else + else if (_root._entry) set_curdir(_root._entry); if (_left_hwnd) { @@ -391,6 +394,11 @@ FileChildWindow* FileChildWindow::create(const FileChildWndInfo& info) FileChildWindow* child = static_cast( create_mdi_child(info, mcs, WINDOW_CREATOR_INFO(FileChildWindow,FileChildWndInfo))); + if (!child->_left_hwnd && !child->_right_hwnd) { + SendMessage(info._hmdiclient, WM_MDIDESTROY, (WPARAM)child->_hwnd, 0); + MessageBox(info._hmdiclient, TEXT("Error opening child window"), TEXT("ROS Explorer"), MB_OK); + } + return child; } From fcfeb832174035c7ba29309dce46ec693d2cb6ab Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Sat, 16 Sep 2006 15:40:24 +0000 Subject: [PATCH 227/488] "Debug Release" mix configuration for notifyhook project file svn path=/trunk/; revision=24144 --- .../shell/explorer/notifyhook/notifyhook.dsp | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/reactos/base/shell/explorer/notifyhook/notifyhook.dsp b/reactos/base/shell/explorer/notifyhook/notifyhook.dsp index 32beddfa132..5987f96d342 100644 --- a/reactos/base/shell/explorer/notifyhook/notifyhook.dsp +++ b/reactos/base/shell/explorer/notifyhook/notifyhook.dsp @@ -20,6 +20,7 @@ CFG=notifyhook - Win32 !MESSAGE "notifyhook - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "notifyhook - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "notifyhook - Win32" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "notifyhook - Win32 Debug Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project @@ -113,6 +114,35 @@ LINK32=link.exe # ADD BASE LINK32 user32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 user32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +!ELSEIF "$(CFG)" == "notifyhook - Win32 Debug Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "DRelease" +# PROP BASE Intermediate_Dir "DRelease" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "DRelease" +# PROP Intermediate_Dir "DRelease" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_NOTIFYHOOK_IMPL" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_NOTIFYHOOK_IMPL" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x407 /d "NDEBUG" +# ADD RSC /l 0x407 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 user32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 user32.lib /nologo /subsystem:windows /dll /machine:I386 + !ENDIF # Begin Target @@ -120,6 +150,7 @@ LINK32=link.exe # Name "notifyhook - Win32 Release" # Name "notifyhook - Win32 Debug" # Name "notifyhook - Win32" +# Name "notifyhook - Win32 Debug Release" # Begin Source File SOURCE=.\notifyhook.c From 30f438bb7ba73e642d51eb015a2e6e78bf7e356d Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Sat, 16 Sep 2006 15:41:17 +0000 Subject: [PATCH 228/488] explorer: minor code cleanup svn path=/trunk/; revision=24145 --- reactos/base/shell/explorer/shell/pane.h | 4 ++-- reactos/base/shell/explorer/utility/window.cpp | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/reactos/base/shell/explorer/shell/pane.h b/reactos/base/shell/explorer/shell/pane.h index 7ec88d0ab4c..68ea5eba68b 100644 --- a/reactos/base/shell/explorer/shell/pane.h +++ b/reactos/base/shell/explorer/shell/pane.h @@ -94,10 +94,10 @@ struct Pane : public SubclassedWindow int insert_entries(Entry* dir, int idx=-1); BOOL command(UINT cmd); - int Notify(int id, NMHDR* pnmh); + virtual int Notify(int id, NMHDR* pnmh); protected: - LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + virtual LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); void calc_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str); void calc_tabbed_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str); diff --git a/reactos/base/shell/explorer/utility/window.cpp b/reactos/base/shell/explorer/utility/window.cpp index 63a330a3ed5..c05acb20d4b 100644 --- a/reactos/base/shell/explorer/utility/window.cpp +++ b/reactos/base/shell/explorer/utility/window.cpp @@ -129,7 +129,9 @@ Window* Window::create_mdi_child(const ChildWndInfo& info, const MDICREATESTRUCT HWND hwnd = (HWND) SendMessage(info._hmdiclient, WM_MDICREATE, 0, (LPARAM)&mcs); - UnhookWindowsHookEx(s_hcbtHook); + // end hook in case it's not already done + if (s_hcbtHook) + UnhookWindowsHookEx(s_hcbtHook); Window* child = get_window(hwnd); s_new_info = NULL; @@ -143,6 +145,9 @@ Window* Window::create_mdi_child(const ChildWndInfo& info, const MDICREATESTRUCT LRESULT CALLBACK Window::MDICBTHookProc(int code, WPARAM wparam, LPARAM lparam) { if (code == HCBT_CREATEWND) { + UnhookWindowsHookEx(s_hcbtHook); // use the hook only for the first created window + s_hcbtHook = 0; + HWND hwnd = (HWND)wparam; // create Window controller and associate it with the window handle From 25e2b01535f6fa0ee0b97b193006a6b25f3f1dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 16 Sep 2006 20:22:54 +0000 Subject: [PATCH 229/488] Don't crash if PCI AddDevice is called with a NULL Pdo (happens if pci.sys is considered as a legacy driver) svn path=/trunk/; revision=24146 --- reactos/drivers/bus/pci/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/drivers/bus/pci/pci.c b/reactos/drivers/bus/pci/pci.c index 9cd4b47fc76..f5590a086d4 100644 --- a/reactos/drivers/bus/pci/pci.c +++ b/reactos/drivers/bus/pci/pci.c @@ -135,6 +135,8 @@ PciAddDevice( NTSTATUS Status; DPRINT("Called\n"); + if (PhysicalDeviceObject == NULL) + return STATUS_SUCCESS; Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo); From 0d996fd421270cbcd322ca3d43c64d05469abdfe Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sat, 16 Sep 2006 20:27:53 +0000 Subject: [PATCH 230/488] - Revert part of 24108 which was scanning the process's thread ready list and making the threads ready. This shouldn't currently happen on ReactOS but it seems that happens on Fireball's machine and crashes it, so I'm reverting it. svn path=/trunk/; revision=24147 --- reactos/ntoskrnl/ke/process.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index dbb7fd8f1d4..2e09a03f26f 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -90,6 +90,7 @@ KiAttachProcess(IN PKTHREAD Thread, if (Process->State == ProcessInMemory) { /* Scan the ready list */ +#if 0 ListHead = &Process->ReadyListHead; NextEntry = ListHead->Flink; while (NextEntry != ListHead) @@ -107,6 +108,7 @@ KiAttachProcess(IN PKTHREAD Thread, /* Go to the next one */ NextEntry = ListHead->Flink; } +#endif /* Release dispatcher lock */ KiReleaseDispatcherLockFromDpcLevel(); From 78ef70dedacceec84beeddc018157c12a0fd4633 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sat, 16 Sep 2006 20:37:49 +0000 Subject: [PATCH 231/488] - Fix one of the oldest hacks in ReactOS: KeGetCurrentThread() and PsGetcurrentProcess used to be NULL during early boot stage. We also didn't have an official idle therad/process. Also system intialization was not in its sepearte thread. Changes: - Implemented SeAssignPrimaryToken. - Setup Boot/System Token for Idle Process in SeInit2. - Remove ROS hack in SeCaptureSubjectContextEx. - Call SeAssignPrimaryToken in PspInitializeProcessSecurty when called for the Initial Process creation. - Implement PsInitiailizeQuotaSystem and set PspDefauptQuotaBlock for the idle process so that it can be used for the initial process. - Rewrite Process Manager Phase 0 initialization from scratch, to create a new initial system process and thread which will be used for Phase 1 (in ROS, phase 2) initialization of the executive. - Fix a bug in PspCreateProcess which was using an uninitialized value of SectionObject in some cases, instead of NULL. - Call PsInitailizeQuotaSystem from ObInit, and also create the system handle table inside the idle process, and make it the ObpKernelHandleTable. - Do Executive Phase 0 Initialization at APC_LEVEL. - Start idle thread at HIGH_PRIORITY then lower it to 0 once the Initial Thread is setup, so that it can run, then keep priority to 0 at DISPATCH_LEVEL and jump into idle loop code. - Add NtYieldExecution to idle loop code since it's now being used. - Fix IoGetCurrentProcess which was previously hacked. - Remove some checks for Thread == NULL in ke_x.h, since this is now impossible. - Split Phase 0/1 initialization in ex\init.c, since one runs in a separate thread now. Also don't lower IRQL to PASSIVE_LEVEL anymore (run at APC_LEVEL). svn path=/trunk/; revision=24148 --- reactos/ntoskrnl/KrnlFun.c | 2 +- reactos/ntoskrnl/ex/init.c | 125 +++--- reactos/ntoskrnl/include/internal/ke_x.h | 8 +- reactos/ntoskrnl/io/iomgr/util.c | 11 +- reactos/ntoskrnl/ke/i386/ctxswitch.S | 3 + reactos/ntoskrnl/ke/i386/kiinit.c | 41 +- reactos/ntoskrnl/ob/obinit.c | 11 + reactos/ntoskrnl/ps/job.c | 26 +- reactos/ntoskrnl/ps/process.c | 21 +- reactos/ntoskrnl/ps/psmgr.c | 520 ++++++++++------------- reactos/ntoskrnl/ps/quota.c | 13 + reactos/ntoskrnl/ps/security.c | 13 +- reactos/ntoskrnl/se/semgr.c | 22 +- reactos/ntoskrnl/se/token.c | 26 +- 14 files changed, 404 insertions(+), 438 deletions(-) diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index 8a011352c37..b0e9f4546a1 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -33,10 +33,10 @@ // - FEATURES: // * New optimized table-based tick-hashed timer implementation. // * New Thread Scheduler based on 2003. -// * Proper Idle/Initial Thread setup and 2nd stage boot. // * Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion. // // Ex: +// - Implement Generic Callback mechanism. // - Use pushlocks for handle implementation. // /////////////////////////////////////////////////////////////////////////////// diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 56935d2a479..55763b86b11 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -36,14 +36,12 @@ extern ULONG_PTR LastKrnlPhysAddr; extern ULONG_PTR LastKernelAddress; extern LOADER_MODULE KeLoaderModules[64]; extern PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages; -BOOLEAN SetupMode = TRUE; + BOOLEAN NoGuiBoot = FALSE; - -VOID PspPostInitSystemProcess(VOID); - -static VOID INIT_FUNCTION InitSystemSharedUserPage (PCSZ ParameterLine); -VOID INIT_FUNCTION ExpDisplayNotice(VOID); -INIT_FUNCTION NTSTATUS ExpLoadInitialProcess(PHANDLE ProcessHandle, PHANDLE ThreadHandle); +static BOOLEAN BootLog = FALSE; +static ULONG MaxMem = 0; +BOOLEAN SetupMode = TRUE; +static BOOLEAN ForceAcpiDisable = FALSE; #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, InitSystemSharedUserPage) @@ -53,6 +51,12 @@ INIT_FUNCTION NTSTATUS ExpLoadInitialProcess(PHANDLE ProcessHandle, PHANDLE Thre #pragma alloc_text(INIT, ExInit2) #endif +BOOLEAN +NTAPI +PspInitPhase0( + VOID +); + /* FUNCTIONS ****************************************************************/ static @@ -493,21 +497,32 @@ ExpLoadInitialProcess(PHANDLE ProcessHandle, } VOID -INIT_FUNCTION -STDCALL +NTAPI +ExInit2(VOID) +{ + ExpInitLookasideLists(); + ExpInitializeHandleTables(); +} + +VOID +NTAPI +ExInit3(VOID) +{ + ExpInitializeEventImplementation(); + ExpInitializeEventPairImplementation(); + ExpInitializeMutantImplementation(); + ExpInitializeSemaphoreImplementation(); + ExpInitializeTimerImplementation(); + LpcpInitSystem(); + ExpInitializeProfileImplementation(); + ExpWin32kInit(); + ExpInitUuids(); +} + +VOID +NTAPI ExpInitializeExecutive(VOID) { - UNICODE_STRING EventName; - HANDLE InitDoneEventHandle; - OBJECT_ATTRIBUTES ObjectAttributes; - BOOLEAN BootLog = FALSE; - ULONG MaxMem = 0; - BOOLEAN ForceAcpiDisable = FALSE; - LARGE_INTEGER Timeout; - HANDLE ProcessHandle; - HANDLE ThreadHandle; - NTSTATUS Status; - /* Check if the structures match the ASM offset constants */ ExecuteRuntimeAsserts(); @@ -520,9 +535,6 @@ ExpInitializeExecutive(VOID) /* Setup bugcheck messages */ KiInitializeBugCheck(); - /* Lower the IRQL to Dispatch Level */ - KeLowerIrql(DISPATCH_LEVEL); - /* Sets up the VDM Data */ NtEarlyInitVdm(); @@ -546,17 +558,14 @@ ExpInitializeExecutive(VOID) /* Initialize the second stage of the kernel */ KeInit2(); - /* Bring back the IRQL to Passive */ - KeLowerIrql(PASSIVE_LEVEL); - /* Initialize resources */ ExpResourceInitialization(); /* Load basic Security for other Managers */ if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED); - /* Initialize Lookaside Lists */ - ExpInitLookasideLists(); + /* Initialize Lookaside Lists and Handle Table */ + ExInit2(); /* Create the Basic Object Manager Types to allow new Object Types */ ObInit(); @@ -568,7 +577,7 @@ ExpInitializeExecutive(VOID) if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED); /* Initalize the Process Manager */ - PiInitProcessManager(); + PspInitPhase0(); /* Break into the Debugger if requested */ if (KdPollBreakIn()) DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C); @@ -578,15 +587,25 @@ ExpInitializeExecutive(VOID) /* Do Phase 1 HAL Initalization */ HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock); +} + +VOID +NTAPI +ExPhase2Init(PVOID Context) +{ + UNICODE_STRING EventName; + HANDLE InitDoneEventHandle; + OBJECT_ATTRIBUTES ObjectAttributes; + LARGE_INTEGER Timeout; + HANDLE ProcessHandle; + HANDLE ThreadHandle; + NTSTATUS Status; + + /* Set us at maximum priority */ + KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY); /* Initialize Basic System Objects and Worker Threads */ - ExInit2(); - - /* Create the system handle table, assign it to the system process, create - the client id table and assign a PID for the system process. This needs - to be done before the worker threads are initialized so the system - process gets the first PID (4) */ - PspPostInitSystemProcess(); + ExInit3(); /* initialize the worker threads */ ExpInitializeWorkerThreads(); @@ -747,23 +766,25 @@ ExpInitializeExecutive(VOID) KiTimerSystemAuditing = 1; ZwClose(ThreadHandle); ZwClose(ProcessHandle); -} -VOID -STDCALL -INIT_FUNCTION -ExInit2(VOID) -{ - ExpInitializeEventImplementation(); - ExpInitializeEventPairImplementation(); - ExpInitializeMutantImplementation(); - ExpInitializeSemaphoreImplementation(); - ExpInitializeTimerImplementation(); - LpcpInitSystem(); - ExpInitializeProfileImplementation(); - ExpWin32kInit(); - ExpInitUuids(); - ExpInitializeHandleTables(); + DPRINT1("System initialization complete\n"); + { + /* FIXME: We should instead jump to zero-page thread */ + /* Free initial kernel memory */ + MiFreeInitMemory(); + + /* Set our priority to 0 */ + KeGetCurrentThread()->BasePriority = 0; + KeSetPriorityThread(KeGetCurrentThread(), 0); + + /* Wait ad-infinitum */ + for (;;) + { + LARGE_INTEGER Timeout; + Timeout.QuadPart = 0x7fffffffffffffffLL; + KeDelayExecutionThread(KernelMode, FALSE, &Timeout); + } + } } /* EOF */ diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 3fc6da54c21..6124312a894 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -58,8 +58,7 @@ #define KeEnterCriticalRegion() \ { \ PKTHREAD Thread = KeGetCurrentThread(); \ - if (Thread) \ - { \ + \ /* Sanity checks */ \ ASSERT(Thread == KeGetCurrentThread()); \ ASSERT((Thread->KernelApcDisable <= 0) && \ @@ -67,7 +66,6 @@ \ /* Disable Kernel APCs */ \ Thread->KernelApcDisable--; \ - } \ } // @@ -76,8 +74,7 @@ #define KeLeaveCriticalRegion() \ { \ PKTHREAD Thread = KeGetCurrentThread(); \ - if (Thread) \ - { \ + \ /* Sanity checks */ \ ASSERT(Thread == KeGetCurrentThread()); \ ASSERT(Thread->KernelApcDisable < 0); \ @@ -96,7 +93,6 @@ KiCheckForKernelApcDelivery(); \ } \ } \ - } \ } // diff --git a/reactos/ntoskrnl/io/iomgr/util.c b/reactos/ntoskrnl/io/iomgr/util.c index 5368074b862..14090dd918b 100644 --- a/reactos/ntoskrnl/io/iomgr/util.c +++ b/reactos/ntoskrnl/io/iomgr/util.c @@ -85,16 +85,7 @@ PEPROCESS NTAPI IoGetCurrentProcess(VOID) { - /* FIXME: Completely broken */ - if (PsGetCurrentThread() == NULL || - PsGetCurrentThread()->Tcb.ApcState.Process == NULL) - { - return(PsInitialSystemProcess); - } - else - { - return(PEPROCESS)(PsGetCurrentThread()->Tcb.ApcState.Process); - } + return (PEPROCESS)PsGetCurrentThread()->Tcb.ApcState.Process; } /* diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 04a16d18ca8..6dbcfa69692 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -558,6 +558,9 @@ MainLoop: call @KfLowerIrql@4 CheckSchedule: + /* FIXME: ROS HACK */ + call _NtYieldExecution@0 + /* Check if a next thread is queued */ cmp dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0 #ifdef CONFIG_SMP diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index ddb73613a52..48fe4d439e9 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -14,6 +14,10 @@ /* GLOBALS *******************************************************************/ +VOID +FASTCALL +KiIdleLoop(VOID); + /* Spinlocks used only on X86 */ KSPIN_LOCK KiFreezeExecutionLock; KSPIN_LOCK Ki486CompatibilityLock; @@ -134,6 +138,9 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Set the current MP Master KPRCB to the Boot PRCB */ Prcb->MultiThreadSetMaster = Prcb; + /* Lower to APC_LEVEL */ + KfLowerIrql(APC_LEVEL); + /* Initialize some spinlocks */ KeInitializeSpinLock(&KiFreezeExecutionLock); KeInitializeSpinLock(&Ki486CompatibilityLock); @@ -157,7 +164,6 @@ KiInitializeKernel(IN PKPROCESS InitProcess, DPRINT1("SMP Boot support not yet present\n"); } -#if 0 /* Setup the Idle Thread */ KeInitializeThread(InitProcess, InitThread, @@ -167,7 +173,6 @@ KiInitializeKernel(IN PKPROCESS InitProcess, NULL, NULL, IdleStack); -#endif InitThread->NextProcessor = Number; InitThread->Priority = HIGH_PRIORITY; InitThread->State = Running; @@ -175,10 +180,13 @@ KiInitializeKernel(IN PKPROCESS InitProcess, InitThread->WaitIrql = DISPATCH_LEVEL; InitProcess->ActiveProcessors = 1 << Number; + /* HACK for MmUpdatePageDir */ + ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess; + /* Set up the thread-related fields in the PRCB */ - //Prcb->CurrentThread = InitThread; + Prcb->CurrentThread = InitThread; Prcb->NextThread = NULL; - //Prcb->IdleThread = InitThread; + Prcb->IdleThread = InitThread; /* Initialize the Kernel Executive */ ExpInitializeExecutive(); @@ -212,19 +220,11 @@ KiInitializeKernel(IN PKPROCESS InitProcess, } } - /* Free Initial Memory */ - MiFreeInitMemory(); + /* Raise to Dispatch */ + KfRaiseIrql(DISPATCH_LEVEL); - while (1) - { - LARGE_INTEGER Timeout; - Timeout.QuadPart = 0x7fffffffffffffffLL; - KeDelayExecutionThread(KernelMode, FALSE, &Timeout); - } - - /* Bug Check and loop forever if anything failed */ - KEBUGCHECK(0); - for(;;); + /* Set the Idle Priority to 0. This will jump into Phase 1 */ + KeSetPriorityThread(InitThread, 0); } VOID @@ -303,5 +303,14 @@ AppCpuInit: Prcb, Cpu, LoaderBlock); + + /* Lower IRQL back to DISPATCH_LEVEL */ + KfLowerIrql(DISPATCH_LEVEL); + + /* Set the priority of this thread to 0 */ + KeGetCurrentThread()->Priority = 0; + + /* Jump into the idle loop */ + KiIdleLoop(); } diff --git a/reactos/ntoskrnl/ob/obinit.c b/reactos/ntoskrnl/ob/obinit.c index 613cc8f65e6..3ac6e0304cd 100644 --- a/reactos/ntoskrnl/ob/obinit.c +++ b/reactos/ntoskrnl/ob/obinit.c @@ -40,6 +40,10 @@ GENERIC_MAPPING ObpDirectoryMapping = PDEVICE_MAP ObSystemDeviceMap = NULL; ULONG ObpTraceLevel = OB_HANDLE_DEBUG | OB_REFERENCE_DEBUG; +VOID +NTAPI +PsInitializeQuotaSystem(VOID); + /* PRIVATE FUNCTIONS *********************************************************/ VOID @@ -148,6 +152,13 @@ ObInit(VOID) /* Initialize lookaside lists */ ObInit2(); + /* Initialize default Quota block */ + PsInitializeQuotaSystem(); + + /* Create kernel handle table */ + PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable(NULL); + ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable; + /* Create the Type Type */ DPRINT("Creating Type Type\n"); RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); diff --git a/reactos/ntoskrnl/ps/job.c b/reactos/ntoskrnl/ps/job.c index 25125b9ade1..791f16a252a 100644 --- a/reactos/ntoskrnl/ps/job.c +++ b/reactos/ntoskrnl/ps/job.c @@ -41,7 +41,7 @@ CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES] = 10 * 6 }; -static GENERIC_MAPPING PiJobMapping = +GENERIC_MAPPING PspJobMapping = { STANDARD_RIGHTS_READ | JOB_OBJECT_QUERY, STANDARD_RIGHTS_WRITE | JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_SET_ATTRIBUTES | JOB_OBJECT_TERMINATE | JOB_OBJECT_SET_SECURITY_ATTRIBUTES, @@ -53,7 +53,7 @@ static GENERIC_MAPPING PiJobMapping = VOID NTAPI -PiDeleteJob ( PVOID ObjectBody ) +PspDeleteJob ( PVOID ObjectBody ) { PEJOB Job = (PEJOB)ObjectBody; @@ -74,28 +74,10 @@ PiDeleteJob ( PVOID ObjectBody ) ExDeleteResource(&Job->JobLock); } -VOID -INIT_FUNCTION +VOID NTAPI -PsInitJobManagment ( VOID ) +PspInitializeJobStructures(VOID) { - UNICODE_STRING Name; - OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - - DPRINT("Creating Job Object Type\n"); - - /* Initialize the Job type */ - RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); - RtlInitUnicodeString(&Name, L"Job"); - ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); - ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EJOB); - ObjectTypeInitializer.GenericMapping = PiJobMapping; - ObjectTypeInitializer.PoolType = NonPagedPool; - ObjectTypeInitializer.ValidAccessMask = JOB_OBJECT_ALL_ACCESS; - ObjectTypeInitializer.UseDefaultObject = TRUE; - ObjectTypeInitializer.DeleteProcedure = PiDeleteJob; - ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsJobType); - InitializeListHead(&PsJobListHead); ExInitializeFastMutex(&PsJobListLock); } diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index b2b9415f9e7..c360c18df89 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -15,12 +15,9 @@ /* GLOBALS *******************************************************************/ -PEPROCESS PsInitialSystemProcess = NULL; -PEPROCESS PsIdleProcess = NULL; -POBJECT_TYPE PsProcessType = NULL; +extern ULONG PsMinimumWorkingSet, PsMaximumWorkingSet; -EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock; -ULONG PsMinimumWorkingSet, PsMaximumWorkingSet; +POBJECT_TYPE PsProcessType = NULL; LIST_ENTRY PsActiveProcessHead; KGUARDED_MUTEX PspActiveProcessMutex; @@ -384,13 +381,13 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, SECURITY_SUBJECT_CONTEXT SubjectContext; PAGED_CODE(); PSTRACE(PS_PROCESS_DEBUG, - "ProcessHandle: %p Parent: %p\n", ProcessHandle, Parent); + "ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess); /* Validate flags */ if (Flags & ~PS_ALL_FLAGS) return STATUS_INVALID_PARAMETER; /* Check for parent */ - if(ParentProcess) + if (ParentProcess) { /* Reference it */ Status = ObReferenceObjectByHandle(ParentProcess, @@ -417,14 +414,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, { /* We have no parent */ Parent = NULL; -#ifdef CONFIG_SMP - /* - * FIXME: Only the boot cpu is initialized in the early boot phase. - */ - Affinity = 0xffffffff; -#else Affinity = KeActiveProcessors; -#endif } /* Save working set data */ @@ -488,6 +478,9 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, } else { + /* Assume no section object */ + SectionObject = NULL; + /* Is the parent the initial process? */ if (Parent != PsInitialSystemProcess) { diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index 2e56ad58915..d0708efd820 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -14,28 +14,28 @@ #define NDEBUG #include -#define LockEvent Spare0[0] -#define LockCount Spare0[1] -#define LockOwner Spare0[2] - -extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout; +extern LARGE_INTEGER ShortPsLockDelay; extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY]; -static GENERIC_MAPPING PiProcessMapping = { +GENERIC_MAPPING PspProcessMapping = +{ STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, - PROCESS_ALL_ACCESS}; + PROCESS_ALL_ACCESS +}; -static GENERIC_MAPPING PiThreadMapping = { +GENERIC_MAPPING PspThreadMapping = +{ STANDARD_RIGHTS_READ | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, STANDARD_RIGHTS_WRITE | THREAD_TERMINATE | THREAD_SUSPEND_RESUME | THREAD_ALERT | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, - THREAD_ALL_ACCESS}; + THREAD_ALL_ACCESS +}; extern ULONG NtBuildNumber; extern ULONG NtMajorVersion; @@ -45,336 +45,264 @@ extern PVOID KeUserCallbackDispatcher; extern PVOID KeUserExceptionDispatcher; extern PVOID KeRaiseUserExceptionDispatcher; -PVOID PspSystemDllBase = NULL; -PVOID PspSystemDllSection = NULL; -PVOID PspSystemDllEntryPoint = NULL; -PHANDLE_TABLE PspCidTable = NULL; -VOID STDCALL PspKillMostProcesses(); -VOID INIT_FUNCTION NTAPI PsInitClientIDManagment(VOID); -NTSTATUS STDCALL INIT_FUNCTION PspLookupKernelUserEntryPoints(VOID); +PVOID PspSystemDllBase; +PVOID PspSystemDllSection; +PVOID PspSystemDllEntryPoint; -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, PiInitProcessManager) -#pragma alloc_text(INIT, PsInitClientIDManagment) -#pragma alloc_text(INIT, PsInitThreadManagment) -#pragma alloc_text(INIT, PsInitProcessManagment) -#pragma alloc_text(INIT, PspLookupKernelUserEntryPoints) -#pragma alloc_text(INIT, PsLocateSystemDll) -#endif +PHANDLE_TABLE PspCidTable; + +PEPROCESS PsInitialSystemProcess = NULL; +PEPROCESS PsIdleProcess = NULL; +HANDLE PspInitialSystemProcessHandle; + +ULONG PsMinimumWorkingSet, PsMaximumWorkingSet; +struct +{ + LIST_ENTRY List; + KGUARDED_MUTEX Lock; +} PspWorkingSetChangeHead; +ULONG PspDefaultPagedLimit, PspDefaultNonPagedLimit, PspDefaultPagefileLimit; +BOOLEAN PspDoingGiveBacks; + +extern PTOKEN PspBootAccessToken; + +extern GENERIC_MAPPING PspJobMapping; +extern POBJECT_TYPE PsJobType; + +VOID +NTAPI +PspInitializeJobStructures(VOID); + +VOID +NTAPI +PspDeleteJob(IN PVOID ObjectBody); /* FUNCTIONS ***************************************************************/ -VOID -FASTCALL -KiIdleLoop(VOID); +NTSTATUS +NTAPI +PspCreateProcess(OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN HANDLE ParentProcess OPTIONAL, + IN ULONG Flags, + IN HANDLE SectionHandle OPTIONAL, + IN HANDLE DebugPort OPTIONAL, + IN HANDLE ExceptionPort OPTIONAL, + IN BOOLEAN InJob); /* FUNCTIONS *****************************************************************/ -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ VOID -INIT_FUNCTION NTAPI -PsInitHackThread(VOID) -{ - PETHREAD IdleThread; +ExPhase2Init( + IN PVOID Context +); - IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); - RtlZeroMemory(IdleThread, sizeof(ETHREAD)); - IdleThread->ThreadsProcess = PsIdleProcess; - KeInitializeThread(&PsIdleProcess->Pcb, - &IdleThread->Tcb, - PspSystemThreadStartup, - (PVOID)KiIdleLoop, - NULL, - NULL, - NULL, - (PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) + - KERNEL_STACK_SIZE)); - InitializeListHead(&IdleThread->IrpList); - - KeReadyThread(&IdleThread->Tcb); - - KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; - KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY); - KeSetAffinityThread(&IdleThread->Tcb, 1 << 0); -} - -/* - * HACK-O-RAMA - * Antique vestigial code left alive for the sole purpose of First/Idle Thread - * creation until I can merge my fix for properly creating them. - */ -VOID -INIT_FUNCTION +BOOLEAN NTAPI -PsInitHackThread2(IN PETHREAD *Hack) +PspInitPhase0(VOID) { - PETHREAD IdleThread; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE SysThreadHandle; + PETHREAD SysThread; + MM_SYSTEMSIZE SystemSize; + UNICODE_STRING Name; + ULONG i; + OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD)); - RtlZeroMemory(IdleThread, sizeof(ETHREAD)); - IdleThread->ThreadsProcess = PsInitialSystemProcess; - KeInitializeThread(&PsInitialSystemProcess->Pcb, - &IdleThread->Tcb, - PspSystemThreadStartup, - NULL, - NULL, - NULL, - NULL, - P0BootStack); - InitializeListHead(&IdleThread->IrpList); - *Hack = IdleThread; -} + /* FIXME: Initialize Lock Data do it STATIC */ + ShortPsLockDelay.QuadPart = -100LL; -VOID -INIT_FUNCTION -NTAPI -PiInitProcessManager(VOID) -{ - PsInitJobManagment(); - PsInitProcessManagment(); - PsInitThreadManagment(); - PsInitHackThread(); -} + /* Get the system size */ + SystemSize = MmQuerySystemSize(); -VOID -INIT_FUNCTION -NTAPI -PsInitClientIDManagment(VOID) -{ - PspCidTable = ExCreateHandleTable(NULL); - ASSERT(PspCidTable); -} + /* Setup some memory options */ + PspDefaultPagefileLimit = -1; + switch (SystemSize) + { + /* Medimum systems */ + case MmMediumSystem: -VOID -INIT_FUNCTION -NTAPI -PsInitThreadManagment(VOID) -/* - * FUNCTION: Initialize thread managment - */ -{ - UNICODE_STRING Name; - OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - PETHREAD FirstThread; - ULONG i; + /* Increase the WS sizes a bit */ + PsMinimumWorkingSet += 10; + PsMaximumWorkingSet += 100; - for (i=0; i < MAXIMUM_PRIORITY; i++) - { - InitializeListHead(&PriorityListHead[i]); - } + /* Large systems */ + case MmLargeSystem: + + /* Increase the WS sizes a bit more */ + PsMinimumWorkingSet += 30; + PsMaximumWorkingSet += 300; + + /* Small and other systems */ + default: + break; + } + + /* Setup the quantum table */ + PsChangeQuantumTable(FALSE, PsRawPrioritySeparation); + + /* Setup callbacks when we implement Generic Callbacks */ + + /* Set quota settings */ + if (!PspDefaultPagedLimit) PspDefaultPagedLimit = 0; + if (!PspDefaultNonPagedLimit) PspDefaultNonPagedLimit = 0; + if (!(PspDefaultNonPagedLimit) && !(PspDefaultPagedLimit)) + { + /* Enable give-backs */ + PspDoingGiveBacks = TRUE; + } + else + { + /* Disable them */ + PspDoingGiveBacks = FALSE; + } + + /* Now multiply limits by 1MB */ + PspDefaultPagedLimit <<= 20; + PspDefaultNonPagedLimit <<= 20; + if (PspDefaultPagefileLimit != -1) PspDefaultPagefileLimit <<= 20; + + /* Initialize the Active Process List */ + InitializeListHead(&PsActiveProcessHead); + KeInitializeGuardedMutex(&PspActiveProcessMutex); + + /* Get the idle process */ + PsIdleProcess = PsGetCurrentProcess(); + + /* Setup the locks */ + PsIdleProcess->ProcessLock.Value = 0; + ExInitializeRundownProtection(&PsIdleProcess->RundownProtect); + + /* Initialize the thread list */ + InitializeListHead(&PsIdleProcess->ThreadListHead); + + /* Clear kernel time */ + PsIdleProcess->Pcb.KernelTime = 0; + + /* Initialize the Process type */ + RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); + RtlInitUnicodeString(&Name, L"Process"); + ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); + ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EPROCESS); + ObjectTypeInitializer.GenericMapping = PspProcessMapping; + ObjectTypeInitializer.PoolType = NonPagedPool; + ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS; + ObjectTypeInitializer.DeleteProcedure = PspDeleteProcess; + ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsProcessType); + + /* Setup ROS Scheduler lists (HACK!) */ + for (i = 0; i < MAXIMUM_PRIORITY; i++) + { + InitializeListHead(&PriorityListHead[i]); + } - DPRINT("Creating Thread Object Type\n"); - /* Initialize the Thread type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Thread"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(ETHREAD); - ObjectTypeInitializer.GenericMapping = PiThreadMapping; + ObjectTypeInitializer.GenericMapping = PspThreadMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS; ObjectTypeInitializer.DeleteProcedure = PspDeleteThread; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsThreadType); - PsInitHackThread2(&FirstThread); - FirstThread->Tcb.State = Running; - FirstThread->Tcb.FreezeCount = 0; - FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */ - FirstThread->Tcb.Affinity = (1 << 0); - KeGetCurrentPrcb()->CurrentThread = (PVOID)FirstThread; + /* Initialize the Job type */ + RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); + RtlInitUnicodeString(&Name, L"Job"); + ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); + ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EJOB); + ObjectTypeInitializer.GenericMapping = PspJobMapping; + ObjectTypeInitializer.PoolType = NonPagedPool; + ObjectTypeInitializer.ValidAccessMask = JOB_OBJECT_ALL_ACCESS; + ObjectTypeInitializer.UseDefaultObject = TRUE; + ObjectTypeInitializer.DeleteProcedure = PspDeleteJob; + ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsJobType); - DPRINT("FirstThread %x\n",FirstThread); + /* Initialize job structures external to this file */ + PspInitializeJobStructures(); - ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL); -} + /* Initialize the Working Set data */ + InitializeListHead(&PspWorkingSetChangeHead.List); + KeInitializeGuardedMutex(&PspWorkingSetChangeHead.Lock); -VOID -INIT_FUNCTION -NTAPI -PsInitProcessManagment(VOID) -{ - PKPROCESS KProcess; - NTSTATUS Status; - UNICODE_STRING Name; - OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; + /* Create the CID Handle table */ + PspCidTable = ExCreateHandleTable(NULL); - ShortPsLockDelay.QuadPart = -100LL; + /* FIXME: Initialize LDT/VDM support */ - /* - * Register the process object type - */ + /* Setup the reaper */ + ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL); - DPRINT("Creating Process Object Type\n"); - - /* Initialize the Process type */ - RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); - RtlInitUnicodeString(&Name, L"Process"); - ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); - ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EPROCESS); - ObjectTypeInitializer.GenericMapping = PiProcessMapping; - ObjectTypeInitializer.PoolType = NonPagedPool; - ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS; - ObjectTypeInitializer.DeleteProcedure = PspDeleteProcess; - ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsProcessType); + /* Set the boot access token */ + PspBootAccessToken = (PTOKEN)(PsIdleProcess->Token.Value & ~MAX_FAST_REFS); - InitializeListHead(&PsActiveProcessHead); - KeInitializeGuardedMutex(&PspActiveProcessMutex); + /* Setup default object attributes */ + InitializeObjectAttributes(&ObjectAttributes, + NULL, + 0, + NULL, + NULL); - /* Setup the quantum table */ - PsChangeQuantumTable(FALSE, PsRawPrioritySeparation); + /* Create the Initial System Process */ + Status = PspCreateProcess(&PspInitialSystemProcessHandle, + PROCESS_ALL_ACCESS, + &ObjectAttributes, + 0, + FALSE, + 0, + 0, + 0, + FALSE); + if (!NT_SUCCESS(Status)) return FALSE; - /* - * Initialize the default quota block. - */ + /* Get a reference to it */ + ObReferenceObjectByHandle(PspInitialSystemProcessHandle, + 0, + PsProcessType, + KernelMode, + (PVOID*)&PsInitialSystemProcess, + NULL); - RtlZeroMemory(&PspDefaultQuotaBlock, sizeof(PspDefaultQuotaBlock)); - PspDefaultQuotaBlock.QuotaEntry[PagedPool].Limit = (SIZE_T)-1; - PspDefaultQuotaBlock.QuotaEntry[NonPagedPool].Limit = (SIZE_T)-1; - PspDefaultQuotaBlock.QuotaEntry[2].Limit = (SIZE_T)-1; /* Page file */ + /* The PD we gave it is invalid at this point, do what old ROS did */ + PsInitialSystemProcess->Pcb.DirectoryTableBase = (LARGE_INTEGER) + (LONGLONG) + (ULONG)MmGetPageDirectory(); + PsIdleProcess->Pcb.DirectoryTableBase = PsInitialSystemProcess->Pcb.DirectoryTableBase; - /* - * Initialize the idle process - */ - Status = ObCreateObject(KernelMode, - PsProcessType, - NULL, - KernelMode, - NULL, - sizeof(EPROCESS), - 0, - 0, - (PVOID*)&PsIdleProcess); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status); - KEBUGCHECK(0); - return; - } + /* Copy the process names */ + strcpy(PsIdleProcess->ImageFileName, "Idle"); + strcpy(PsInitialSystemProcess->ImageFileName, "System"); - RtlZeroMemory(PsIdleProcess, sizeof(EPROCESS)); + /* Allocate a structure for the audit name */ + PsIdleProcess->SeAuditProcessCreationInfo.ImageFileName = + ExAllocatePoolWithTag(PagedPool, sizeof(UNICODE_STRING), TAG_SEPA); + if (!PsIdleProcess->SeAuditProcessCreationInfo.ImageFileName) KEBUGCHECK(0); - PsIdleProcess->Pcb.Affinity = 0xFFFFFFFF; - PsIdleProcess->Pcb.IopmOffset = 0xffff; - PsIdleProcess->Pcb.BasePriority = PROCESS_PRIORITY_IDLE; - PsIdleProcess->Pcb.QuantumReset = 6; - InitializeListHead(&PsIdleProcess->Pcb.ThreadListHead); - InitializeListHead(&PsIdleProcess->ThreadListHead); - InitializeListHead(&PsIdleProcess->ActiveProcessLinks); - ObInitializeFastReference(&PsIdleProcess->Token, NULL); - KeInitializeDispatcherHeader(&PsIdleProcess->Pcb.Header, - ProcessObject, - sizeof(EPROCESS) / sizeof(LONG), - FALSE); - PsIdleProcess->Pcb.DirectoryTableBase.QuadPart = (ULONG_PTR)MmGetPageDirectory(); - strcpy(PsIdleProcess->ImageFileName, "Idle"); - PspInheritQuota(PsIdleProcess, NULL); + /* Setup the system initailization thread */ + Status = PsCreateSystemThread(&SysThreadHandle, + THREAD_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + ExPhase2Init, + NULL); + if (!NT_SUCCESS(Status)) return FALSE; - /* - * Initialize the system process - */ - Status = ObCreateObject(KernelMode, - PsProcessType, - NULL, - KernelMode, - NULL, - sizeof(EPROCESS), - 0, - 0, - (PVOID*)&PsInitialSystemProcess); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status); - KEBUGCHECK(0); - return; - } + /* Create a handle to it */ + ObReferenceObjectByHandle(SysThreadHandle, + 0, + PsThreadType, + KernelMode, + (PVOID*)&SysThread, + NULL); + ZwClose(SysThreadHandle); - /* System threads may run on any processor. */ - RtlZeroMemory(PsInitialSystemProcess, sizeof(EPROCESS)); -#ifdef CONFIG_SMP - /* FIXME: - * Only the boot cpu is initialized. Threads of the - * system process should be able to run on all cpus. - */ - PsInitialSystemProcess->Pcb.Affinity = 0xffffffff; -#else - PsInitialSystemProcess->Pcb.Affinity = KeActiveProcessors; -#endif - PsInitialSystemProcess->Pcb.IopmOffset = 0xffff; - PsInitialSystemProcess->Pcb.BasePriority = PROCESS_PRIORITY_NORMAL; - PsInitialSystemProcess->Pcb.QuantumReset = 6; - InitializeListHead(&PsInitialSystemProcess->Pcb.ThreadListHead); - KeInitializeDispatcherHeader(&PsInitialSystemProcess->Pcb.Header, - ProcessObject, - sizeof(EPROCESS) / sizeof(LONG), - FALSE); - KProcess = &PsInitialSystemProcess->Pcb; - PspInheritQuota(PsInitialSystemProcess, NULL); - - MmInitializeAddressSpace(PsInitialSystemProcess, - (PMADDRESS_SPACE)&(PsInitialSystemProcess)->VadRoot); - - (PsInitialSystemProcess)->LockEvent = - ExAllocatePoolWithTag(PagedPool, sizeof(KEVENT), TAG('P', 's', 'L', 'k')); - KeInitializeEvent((PsInitialSystemProcess)->LockEvent, SynchronizationEvent, FALSE); - -#if defined(__GNUC__) - KProcess->DirectoryTableBase = - (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory(); -#else - { - LARGE_INTEGER dummy; - dummy.QuadPart = (LONGLONG)(ULONG)MmGetPageDirectory(); - KProcess->DirectoryTableBase = dummy; - } -#endif - - strcpy(PsInitialSystemProcess->ImageFileName, "System"); - - PsInitialSystemProcess->Win32WindowStation = (HANDLE)0; - - InsertHeadList(&PsActiveProcessHead, - &PsInitialSystemProcess->ActiveProcessLinks); - InitializeListHead(&PsInitialSystemProcess->ThreadListHead); - -#ifndef SCHED_REWRITE - { - PTOKEN BootToken; - - /* No parent, this is the Initial System Process. Assign Boot Token */ - BootToken = SepCreateSystemProcessToken(); - BootToken->TokenInUse = TRUE; - ObInitializeFastReference(&PsInitialSystemProcess->Token, BootToken); - } -#endif -} - -VOID -PspPostInitSystemProcess(VOID) -{ - HANDLE_TABLE_ENTRY CidEntry; - - /* this routine is called directly after the exectuive handle tables were - initialized. We'll set up the Client ID handle table and assign the system - process a PID */ - PsInitClientIDManagment(); - - ObpCreateHandleTable(NULL, PsInitialSystemProcess); - ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable; - - CidEntry.Object = PsInitialSystemProcess; - CidEntry.GrantedAccess = 0; - PsInitialSystemProcess->UniqueProcessId = ExCreateHandle(PspCidTable, &CidEntry); - - if(!PsInitialSystemProcess->UniqueProcessId) - { - DPRINT1("Failed to create CID handle (unique process id) for the system process!\n"); - KEBUGCHECK(0); - } + /* Return success */ + return TRUE; } NTSTATUS diff --git a/reactos/ntoskrnl/ps/quota.c b/reactos/ntoskrnl/ps/quota.c index 798036a3f31..2b26e458842 100644 --- a/reactos/ntoskrnl/ps/quota.c +++ b/reactos/ntoskrnl/ps/quota.c @@ -13,8 +13,21 @@ #define NDEBUG #include +EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock; + /* FUNCTIONS ***************************************************************/ +VOID +NTAPI +PsInitializeQuotaSystem(VOID) +{ + RtlZeroMemory(&PspDefaultQuotaBlock, sizeof(PspDefaultQuotaBlock)); + PspDefaultQuotaBlock.QuotaEntry[PagedPool].Limit = (SIZE_T)-1; + PspDefaultQuotaBlock.QuotaEntry[NonPagedPool].Limit = (SIZE_T)-1; + PspDefaultQuotaBlock.QuotaEntry[2].Limit = (SIZE_T)-1; /* Page file */ + PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock; +} + VOID STDCALL PspInheritQuota(PEPROCESS Process, PEPROCESS ParentProcess) diff --git a/reactos/ntoskrnl/ps/security.c b/reactos/ntoskrnl/ps/security.c index 25222edb0c4..bd6af32b2df 100644 --- a/reactos/ntoskrnl/ps/security.c +++ b/reactos/ntoskrnl/ps/security.c @@ -14,6 +14,15 @@ #define NDEBUG #include +PTOKEN PspBootAccessToken; + +VOID +NTAPI +SeAssignPrimaryToken( + IN PEPROCESS Process, + IN PTOKEN Token +); + /* PRIVATE FUNCTIONS *********************************************************/ VOID @@ -86,13 +95,9 @@ PspInitializeProcessSecurity(IN PEPROCESS Process, } else { -#ifdef SCHED_REWRITE /* No parent, assign the Boot Token */ ObInitializeFastReference(&Process->Token, NULL); SeAssignPrimaryToken(Process, PspBootAccessToken); -#else - DPRINT1("PspInitializeProcessSecurity called with no parent.\n"); -#endif } /* Return to caller */ diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index b154ff6a2b3..da9b141d681 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -67,9 +67,18 @@ INIT_FUNCTION NTAPI SeInit2(VOID) { - SepInitializeTokenImplementation(); + /* Initialize token objects */ + SepInitializeTokenImplementation(); - return TRUE; + /* Clear impersonation info for the idle thread */ + PsGetCurrentThread()->ImpersonationInfo = NULL; + PspClearCrossThreadFlag(PsGetCurrentThread(), CT_ACTIVE_IMPERSONATION_INFO_BIT); + + /* Initailize the boot token */ + ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL); + ObInitializeFastReference(&PsGetCurrentProcess()->Token, + SepCreateSystemProcessToken()); + return TRUE; } @@ -425,15 +434,6 @@ SeCaptureSubjectContextEx(IN PETHREAD Thread, BOOLEAN CopyOnOpen, EffectiveOnly; PAGED_CODE(); - /* ROS HACK */ - if (!Process) - { - SubjectContext->PrimaryToken = NULL; - SubjectContext->ProcessAuditId = 0; - SubjectContext->ClientToken = NULL; - return; - } - /* Save the unique ID */ SubjectContext->ProcessAuditId = Process->UniqueProcessId; diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 12f3051a5e9..2268c3f71ec 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -1896,6 +1896,26 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, return Status; } +VOID +NTAPI +SeAssignPrimaryToken(IN PEPROCESS Process, + IN PTOKEN Token) +{ + PAGED_CODE(); + + /* Sanity checks */ + ASSERT(Token->TokenType == TokenPrimary); + ASSERT(!Token->TokenInUse); + + /* Clean any previous token */ + if (Process->Token.Object) SeDeassignPrimaryToken(Process); + + /* Set the new token */ + ObReferenceObject(Token); + Token->TokenInUse = TRUE; + ObInitializeFastReference(&Process->Token, Token); +} + PTOKEN STDCALL SepCreateSystemProcessToken(VOID) @@ -1933,12 +1953,6 @@ SepCreateSystemProcessToken(VOID) { return NULL; } - Status = ObInsertObject(AccessToken, - NULL, - TOKEN_ALL_ACCESS, - 0, - NULL, - NULL); Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId); if (!NT_SUCCESS(Status)) From 47f4f5c36a901f00c8cc2d9576f8cc000d4b3f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 16 Sep 2006 20:53:27 +0000 Subject: [PATCH 232/488] Change detection method to see if a driver is a legacy one Fix last issues with PCI driver svn path=/trunk/; revision=24149 --- reactos/drivers/bus/pci/fdo.c | 16 +++++++++------- reactos/drivers/bus/pci/pci.c | 2 -- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 9 ++++++++- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/reactos/drivers/bus/pci/fdo.c b/reactos/drivers/bus/pci/fdo.c index bf86f69ee3f..7f3d7420d9e 100644 --- a/reactos/drivers/bus/pci/fdo.c +++ b/reactos/drivers/bus/pci/fdo.c @@ -354,6 +354,7 @@ FdoStartDevice( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + static BOOLEAN FoundBuggyAllocatedResourcesList = FALSE; PFDO_DEVICE_EXTENSION DeviceExtension; PCM_RESOURCE_LIST AllocatedResources; PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; @@ -363,21 +364,22 @@ FdoStartDevice( DPRINT("Called\n"); DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - + AllocatedResources = IoGetCurrentIrpStackLocation(Irp)->Parameters.StartDevice.AllocatedResources; - if (!AllocatedResources) - { - DPRINT("No allocated resources sent to driver\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } /* HACK due to a bug in ACPI driver, which doesn't report the bus number */ - if (AllocatedResources->Count == 0) + if (!FoundBuggyAllocatedResourcesList || !AllocatedResources || AllocatedResources->Count == 0) { + FoundBuggyAllocatedResourcesList = TRUE; DPRINT1("No bus number resource found (bug in acpi.sys?), assuming bus number #0\n"); DeviceExtension->BusNumber = 0; goto next; } /* END HACK */ + if (!AllocatedResources) + { + DPRINT("No allocated resources sent to driver\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } if (AllocatedResources->Count < 1) { DPRINT("Not enough allocated resources sent to driver\n"); diff --git a/reactos/drivers/bus/pci/pci.c b/reactos/drivers/bus/pci/pci.c index f5590a086d4..9cd4b47fc76 100644 --- a/reactos/drivers/bus/pci/pci.c +++ b/reactos/drivers/bus/pci/pci.c @@ -135,8 +135,6 @@ PciAddDevice( NTSTATUS Status; DPRINT("Called\n"); - if (PhysicalDeviceObject == NULL) - return STATUS_SUCCESS; Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo); diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 6793ee67d57..00f3fcae53b 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -66,7 +66,7 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode, DPRINT("Calling driver AddDevice entrypoint at %08lx\n", DriverObject->DriverExtension->AddDevice); - IsPnpDriver = !IopDeviceNodeHasFlag(DeviceNode, DNF_LEGACY_DRIVER); + IsPnpDriver = (DeviceNode->PhysicalDeviceObject != NULL); Status = DriverObject->DriverExtension->AddDevice( DriverObject, IsPnpDriver ? DeviceNode->PhysicalDeviceObject : NULL); @@ -1215,6 +1215,13 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) ULONG i; NTSTATUS Status; + if (DeviceNode->BootResources) + { + /* FIXME: Not sure of this! */ + DeviceNode->ResourceList = DeviceNode->ResourceListTranslated = DeviceNode->BootResources; + return STATUS_SUCCESS; + } + /* Fill DeviceNode->ResourceList and DeviceNode->ResourceListTranslated; * by using DeviceNode->ResourceRequirements */ From 5ed7c7746ee77634a53017e0792b3bfae54c14bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 16 Sep 2006 21:21:05 +0000 Subject: [PATCH 233/488] Fix compilation (3 variables were unused) svn path=/trunk/; revision=24150 --- reactos/ntoskrnl/ke/process.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index 2e09a03f26f..b6280e3bacd 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -58,8 +58,10 @@ KiAttachProcess(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE ApcLock, IN PRKAPC_STATE SavedApcState) { +#if 0 PLIST_ENTRY ListHead, NextEntry; PKTHREAD CurrentThread; +#endif ASSERT(Process != Thread->ApcState.Process); /* Increase Stack Count */ From 5d0d792e679f4abcc3fb239745e98a25e8f8cfc5 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 16 Sep 2006 21:41:57 +0000 Subject: [PATCH 234/488] * update comments * remove unused members in ConsoleInfo struct * update global struct on UDN_DELTAPOS events * update WindowSize ScreenBuffer member when bigger / smaller on scroll events svn path=/trunk/; revision=24151 --- reactos/dll/win32/console/console.c | 12 ++- reactos/dll/win32/console/console.h | 3 +- reactos/dll/win32/console/layout.c | 118 ++++++++++++++++++++++++++-- reactos/dll/win32/console/options.c | 2 +- 4 files changed, 120 insertions(+), 15 deletions(-) diff --git a/reactos/dll/win32/console/console.c b/reactos/dll/win32/console/console.c index 3bf5de193ed..1b23bf5cac3 100644 --- a/reactos/dll/win32/console/console.c +++ b/reactos/dll/win32/console/console.c @@ -85,7 +85,7 @@ InitConsoleDefaults(PConsoleInfo pConInfo) pConInfo->ScreenBuffer = MAKELONG(80, 300); pConInfo->UseRasterFonts = TRUE; pConInfo->FontSize = (DWORD)MAKELONG(8, 12); - pConInfo->FontWeight = FALSE; + pConInfo->FontWeight = FW_NORMAL; memcpy(pConInfo->Colors, s_Colors, sizeof(s_Colors)); } @@ -162,19 +162,20 @@ ApplyConsoleInfo(HWND hwndDlg, PConsoleInfo pConInfo) /* First Applet */ LONG APIENTRY -InitApplet(HWND hwnd, UINT uMsg, LONG wParam, LONG lParam) +InitApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam) { PROPSHEETPAGE psp[4]; PROPSHEETHEADER psh; INT i=0; PConsoleInfo pConInfo; + PConsoleInfo pSharedInfo = (PConsoleInfo)wParam; UNREFERENCED_PARAMETER(uMsg); /* * console.dll shares information with win32csr with wParam, lParam * - * wParam is a file handle to an unamed file object which contains the ConsoleInfo struct + * wParam is a pointer to an ConsoleInfo struct * lParam is a boolean parameter which specifies wheter defaults should be shown */ @@ -191,9 +192,6 @@ InitApplet(HWND hwnd, UINT uMsg, LONG wParam, LONG lParam) } else { - /* use current info */ - PConsoleInfo pSharedInfo = (PConsoleInfo)wParam; - if (IsBadReadPtr((const void *)pSharedInfo, sizeof(ConsoleInfo))) { /* use defaults */ @@ -275,7 +273,7 @@ CPlApplet( } case CPL_DBLCLK: { - Applets[0].AppletProc(hwndCPl, uMsg, lParam1, lParam2); + InitApplet(hwndCPl, uMsg, lParam1, lParam2); break; } } diff --git a/reactos/dll/win32/console/console.h b/reactos/dll/win32/console/console.h index 5f01b939bc0..1a07871a65f 100644 --- a/reactos/dll/win32/console/console.h +++ b/reactos/dll/win32/console/console.h @@ -21,9 +21,8 @@ typedef struct typedef struct TAGConsoleInfo { - HANDLE hFile; HWND hConsoleWindow; - TCHAR szProcessName[MAX_PATH]; + WCHAR szProcessName[MAX_PATH]; BOOLEAN AppliedConfig; DWORD UseRasterFonts; DWORD FontSize; diff --git a/reactos/dll/win32/console/layout.c b/reactos/dll/win32/console/layout.c index 88aecb7b2dc..8a9127e8d67 100644 --- a/reactos/dll/win32/console/layout.c +++ b/reactos/dll/win32/console/layout.c @@ -131,6 +131,8 @@ LayoutProc( LPARAM lParam ) { + LPNMUPDOWN lpnmud; + LPPSHNOTIFY lppsn; PConsoleInfo pConInfo = (PConsoleInfo)GetWindowLongPtr(hwndDlg, DWLP_USER); UNREFERENCED_PARAMETER(hwndDlg); @@ -148,10 +150,10 @@ LayoutProc( SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, LOWORD(pConInfo->ScreenBuffer), FALSE); SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, HIWORD(pConInfo->WindowSize), FALSE); SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, LOWORD(pConInfo->WindowSize), FALSE); - SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 0)); - SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 0)); - SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 0)); - SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 0)); + SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); + SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); + SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); + SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1)); hDC = GetDC(NULL); xres = GetDeviceCaps(hDC, HORZRES); @@ -183,6 +185,112 @@ LayoutProc( PaintConsole((LPDRAWITEMSTRUCT)lParam, pConInfo); return TRUE; } + case WM_NOTIFY: + { + lpnmud = (LPNMUPDOWN) lParam; + lppsn = (LPPSHNOTIFY) lParam; + + if (lppsn->hdr.code == UDN_DELTAPOS) + { + DWORD wheight, wwidth; + DWORD sheight, swidth; + DWORD left, top; + + if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH) + { + wwidth = lpnmud->iPos + lpnmud->iDelta; + } + else + { + wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE); + } + + if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT) + { + wheight = lpnmud->iPos + lpnmud->iDelta; + } + else + { + wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, NULL, FALSE); + } + + if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH) + { + swidth = lpnmud->iPos + lpnmud->iDelta; + } + else + { + swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE); + } + + if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT) + { + sheight = lpnmud->iPos + lpnmud->iDelta; + } + else + { + sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE); + } + + if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_LEFT) + { + left = lpnmud->iPos + lpnmud->iDelta; + } + else + { + left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE); + } + + if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_TOP) + { + top = lpnmud->iPos + lpnmud->iDelta; + } + else + { + top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE); + } + + if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT) + { + /* automatically adjust screen buffer size when window size enlarges */ + if (wwidth >= swidth) + { + SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, wwidth, TRUE); + swidth = wwidth; + } + + if (wheight >= sheight) + { + SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, wheight, TRUE); + sheight = wheight; + } + } + swidth = max(swidth, 1); + sheight = max(sheight, 1); + + if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT) + { + /* automatically adjust window size when screen buffer decreases */ + if (wwidth > swidth) + { + SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, swidth, TRUE); + wwidth = swidth; + } + + if (wheight > sheight) + { + SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, sheight, TRUE); + wheight = sheight; + } + } + + pConInfo->ScreenBuffer = MAKELONG(swidth, sheight); + pConInfo->WindowSize = MAKELONG(wwidth, wheight); + pConInfo->WindowPosition = MAKELONG(left, top); + PropSheet_Changed(GetParent(hwndDlg), hwndDlg); + } + break; + } case WM_COMMAND: { switch(LOWORD(wParam)) @@ -205,7 +313,7 @@ LayoutProc( } else if (res == BST_UNCHECKED) { - pConInfo->WindowPosition = -1; + pConInfo->WindowPosition = UINT_MAX; SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), FALSE); diff --git a/reactos/dll/win32/console/options.c b/reactos/dll/win32/console/options.c index cc0ae4a472e..522839c0150 100644 --- a/reactos/dll/win32/console/options.c +++ b/reactos/dll/win32/console/options.c @@ -176,7 +176,7 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo) TCHAR szBuffer[MAX_PATH]; /* update cursor size */ - if ( pConInfo->CursorSize == 0 ) + if ( pConInfo->CursorSize == 0) { /* small cursor */ hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_SMALL_CURSOR); From 68bee00b1d8a5eec0fb4f79f3a752253a9905575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 16 Sep 2006 23:30:57 +0000 Subject: [PATCH 235/488] Make IoInvalidateDeviceRelations really asynchronous Implement IoSynchronousInvalidateDeviceRelations svn path=/trunk/; revision=24152 --- reactos/ntoskrnl/include/internal/io.h | 6 - reactos/ntoskrnl/io/iomgr/iomgr.c | 4 +- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 422 ++++++++++++------------- 3 files changed, 206 insertions(+), 226 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index 8a30fab5487..e9165f63302 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -558,12 +558,6 @@ IopInitializePnpServices( IN BOOLEAN BootDrivers) ; -NTSTATUS -IopInvalidateDeviceRelations( - IN PDEVICE_NODE DeviceNode, - IN DEVICE_RELATION_TYPE Type -); - // // Initialization Routines // diff --git a/reactos/ntoskrnl/io/iomgr/iomgr.c b/reactos/ntoskrnl/io/iomgr/iomgr.c index 6d47c12917c..6e656d69600 100644 --- a/reactos/ntoskrnl/io/iomgr/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr/iomgr.c @@ -448,8 +448,8 @@ IoInit2(BOOLEAN BootLog) /* * Initialize PnP root releations */ - IopInvalidateDeviceRelations( - IopRootDeviceNode, + IoInvalidateDeviceRelations( + IopRootDeviceNode->PhysicalDeviceObject, BusRelations); /* Start boot logging */ diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 00f3fcae53b..c668049fbf2 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -25,11 +25,7 @@ KSPIN_LOCK IopDeviceTreeLock; PDRIVER_OBJECT IopRootDriverObject; PIO_BUS_TYPE_GUID_LIST IopBusTypeGuidList = NULL; -static NTSTATUS INIT_FUNCTION -IopSetRootDeviceInstanceData(PDEVICE_NODE DeviceNode); - #if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, IopSetRootDeviceInstanceData) #pragma alloc_text(INIT, PnpInit) #pragma alloc_text(INIT, PnpInit2) #pragma alloc_text(INIT, IopUpdateRootKey) @@ -37,6 +33,18 @@ IopSetRootDeviceInstanceData(PDEVICE_NODE DeviceNode); #pragma alloc_text(INIT, IopIsAcpiComputer) #endif +typedef struct _INVALIDATE_DEVICE_RELATION_DATA +{ + DEVICE_RELATION_TYPE Type; + PIO_WORKITEM WorkItem; + PKEVENT Event; + NTSTATUS Status; +} INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA; + +static VOID CALLBACK +IopInvalidateDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID InvalidateContext); /* FUNCTIONS *****************************************************************/ @@ -66,7 +74,7 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode, DPRINT("Calling driver AddDevice entrypoint at %08lx\n", DriverObject->DriverExtension->AddDevice); - IsPnpDriver = (DeviceNode->PhysicalDeviceObject != NULL); + IsPnpDriver = !IopDeviceNodeHasFlag(DeviceNode, DNF_LEGACY_DRIVER); Status = DriverObject->DriverExtension->AddDevice( DriverObject, IsPnpDriver ? DeviceNode->PhysicalDeviceObject : NULL); @@ -139,8 +147,8 @@ IopStartDevice( if (IopDeviceNodeHasFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY)) { DPRINT("Device needs enumeration, invalidating bus relations\n"); - Status = IopInvalidateDeviceRelations(DeviceNode, BusRelations); - IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY); + IoInvalidateDeviceRelations(DeviceNode->PhysicalDeviceObject, BusRelations); + IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY); } } @@ -178,32 +186,14 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, &Stack); } -typedef struct _INVALIDATE_DEVICE_RELATION_DATA -{ - DEVICE_RELATION_TYPE Type; - PIO_WORKITEM WorkItem; -} INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA; - -static VOID -NTAPI -IoInvalidateDeviceRelationsWorker( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - PINVALIDATE_DEVICE_RELATION_DATA Data = Context; - - IopInvalidateDeviceRelations(IopGetDeviceNode(DeviceObject), Data->Type); - IoFreeWorkItem(Data->WorkItem); - ExFreePool(Data); -} - /* * @implemented */ VOID -STDCALL -IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, - IN DEVICE_RELATION_TYPE Type) +NTAPI +IoInvalidateDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN DEVICE_RELATION_TYPE Type) { PIO_WORKITEM WorkItem; PINVALIDATE_DEVICE_RELATION_DATA Data; @@ -220,23 +210,51 @@ IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, Data->Type = Type; Data->WorkItem = WorkItem; + Data->Event = NULL; IoQueueWorkItem( WorkItem, - IoInvalidateDeviceRelationsWorker, + IopInvalidateDeviceRelations, DelayedWorkQueue, Data); } /* - * @unimplemented + * @implemented */ VOID -STDCALL -IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, - IN DEVICE_RELATION_TYPE Type) +NTAPI +IoSynchronousInvalidateDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN DEVICE_RELATION_TYPE Type) { - UNIMPLEMENTED; + PIO_WORKITEM WorkItem; + PINVALIDATE_DEVICE_RELATION_DATA Data; + KEVENT Event; + + Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA)); + if (!Data) + return; + WorkItem = IoAllocateWorkItem(DeviceObject); + if (!WorkItem) + { + ExFreePool(Data); + return; + } + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + Data->Type = Type; + Data->WorkItem = WorkItem; + Data->Event = &Event; + + IoQueueWorkItem( + WorkItem, + IopInvalidateDeviceRelations, + DelayedWorkQueue, + Data); + + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + ExFreePool(Data); } /* @@ -2346,191 +2364,167 @@ IopInitializePnpServices(IN PDEVICE_NODE DeviceNode, return IopTraverseDeviceTree(&Context); } - -NTSTATUS -IopInvalidateDeviceRelations(IN PDEVICE_NODE DeviceNode, - IN DEVICE_RELATION_TYPE Type) +/* Invalidate device list enumerated by a device node. + * The call can be make synchronous by defining the Event field + * of the INVALIDATE_DEVICE_RELATION_DATA structure + */ +static VOID CALLBACK +IopInvalidateDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID InvalidateContext) /* PINVALIDATE_DEVICE_RELATION_DATA */ { - DEVICETREE_TRAVERSE_CONTEXT Context; - PDEVICE_RELATIONS DeviceRelations; - IO_STATUS_BLOCK IoStatusBlock; - PDEVICE_NODE ChildDeviceNode; - IO_STACK_LOCATION Stack; - BOOLEAN BootDrivers; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING LinkName; - HANDLE Handle; - NTSTATUS Status; - ULONG i; - - DPRINT("DeviceNode 0x%p, Type %d\n", DeviceNode, Type); - - DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); - - Stack.Parameters.QueryDeviceRelations.Type = Type/*BusRelations*/; - - Status = IopInitiatePnpIrp( - DeviceNode->PhysicalDeviceObject, - &IoStatusBlock, - IRP_MN_QUERY_DEVICE_RELATIONS, - &Stack); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopInitiatePnpIrp() failed\n"); - return Status; - } - - DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; - - if ((!DeviceRelations) || (DeviceRelations->Count <= 0)) - { - DPRINT("No PDOs\n"); - if (DeviceRelations) - { - ExFreePool(DeviceRelations); - } - return STATUS_SUCCESS; - } - - DPRINT("Got %d PDOs\n", DeviceRelations->Count); - - /* - * Create device nodes for all discovered devices - */ - - for (i = 0; i < DeviceRelations->Count; i++) - { - Status = IopCreateDeviceNode( - DeviceNode, - DeviceRelations->Objects[i], - &ChildDeviceNode); - DeviceNode->Flags |= DNF_ENUMERATED; - if (!NT_SUCCESS(Status)) - { - DPRINT("No resources\n"); - for (i = 0; i < DeviceRelations->Count; i++) - ObDereferenceObject(DeviceRelations->Objects[i]); - ExFreePool(DeviceRelations); - return STATUS_INSUFFICIENT_RESOURCES; - } - } - ExFreePool(DeviceRelations); - - /* - * Retrieve information about all discovered children from the bus driver - */ - - IopInitDeviceTreeTraverseContext( - &Context, - DeviceNode, - IopActionInterrogateDeviceStack, - DeviceNode); - - Status = IopTraverseDeviceTree(&Context); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status); - return Status; - } - - /* - * Retrieve configuration from the registry for discovered children - */ - - IopInitDeviceTreeTraverseContext( - &Context, - DeviceNode, - IopActionConfigureChildServices, - DeviceNode); - - Status = IopTraverseDeviceTree(&Context); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status); - return Status; - } - - /* - * Get the state of the system boot. If the \\SystemRoot link isn't - * created yet, we will assume that it's possible to load only boot - * drivers. - */ - - RtlInitUnicodeString(&LinkName, L"\\SystemRoot"); - - InitializeObjectAttributes( - &ObjectAttributes, - &LinkName, - 0, - NULL, - NULL); - - Status = ZwOpenFile( - &Handle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - 0, - 0); - if(NT_SUCCESS(Status)) - { - BootDrivers = FALSE; - ZwClose(Handle); - } - else - BootDrivers = TRUE; - - /* - * Initialize services for discovered children. Only boot drivers will - * be loaded from boot driver! - */ - - Status = IopInitializePnpServices(DeviceNode, BootDrivers); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopInitializePnpServices() failed with status (%x)\n", Status); - return Status; - } - - DPRINT("IopInvalidateDeviceRelations() finished\n"); - return STATUS_SUCCESS; -} - - -static -NTSTATUS -INIT_FUNCTION -IopSetRootDeviceInstanceData(PDEVICE_NODE DeviceNode) -{ -#if 0 - PWSTR KeyBuffer; - HANDLE InstanceKey = NULL; + PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext; + PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); + PKEVENT Event = Data->Event; + DEVICETREE_TRAVERSE_CONTEXT Context; + PDEVICE_RELATIONS DeviceRelations; + IO_STATUS_BLOCK IoStatusBlock; + PDEVICE_NODE ChildDeviceNode; + IO_STACK_LOCATION Stack; + BOOLEAN BootDrivers; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot"); + HANDLE Handle; NTSTATUS Status; + ULONG i; - /* Create registry key for the instance id, if it doesn't exist yet */ - KeyBuffer = ExAllocatePool(PagedPool, - (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length); - wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\"); - wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer); - Status = IopCreateDeviceKeyPath(KeyBuffer, - &InstanceKey); - ExFreePool(KeyBuffer); + DPRINT("DeviceObject 0x%p, Type %d\n", DeviceObject, Type); + + DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); + + Stack.Parameters.QueryDeviceRelations.Type = Data->Type; + + Status = IopInitiatePnpIrp( + DeviceObject, + &IoStatusBlock, + IRP_MN_QUERY_DEVICE_RELATIONS, + &Stack); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to create the instance key! (Status %lx)\n", Status); - return Status; + DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status); + goto cleanup; } - /* FIXME: Set 'ConfigFlags' value */ + DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; - ZwClose(InstanceKey); + if (!DeviceRelations || DeviceRelations->Count <= 0) + { + DPRINT("No PDOs\n"); + if (DeviceRelations) + { + ExFreePool(DeviceRelations); + } + Status = STATUS_SUCCESS; + goto cleanup; + } - return Status; -#endif - return STATUS_SUCCESS; + DPRINT("Got %d PDOs\n", DeviceRelations->Count); + + /* + * Create device nodes for all discovered devices + */ + for (i = 0; i < DeviceRelations->Count; i++) + { + Status = IopCreateDeviceNode( + DeviceNode, + DeviceRelations->Objects[i], + &ChildDeviceNode); + DeviceNode->Flags |= DNF_ENUMERATED; + if (!NT_SUCCESS(Status)) + { + DPRINT("No resources\n"); + for (i = 0; i < DeviceRelations->Count; i++) + ObDereferenceObject(DeviceRelations->Objects[i]); + ExFreePool(DeviceRelations); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + } + ExFreePool(DeviceRelations); + + /* + * Retrieve information about all discovered children from the bus driver + */ + IopInitDeviceTreeTraverseContext( + &Context, + DeviceNode, + IopActionInterrogateDeviceStack, + DeviceNode); + + Status = IopTraverseDeviceTree(&Context); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + /* + * Retrieve configuration from the registry for discovered children + */ + IopInitDeviceTreeTraverseContext( + &Context, + DeviceNode, + IopActionConfigureChildServices, + DeviceNode); + + Status = IopTraverseDeviceTree(&Context); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + /* + * Get the state of the system boot. If the \\SystemRoot link isn't + * created yet, we will assume that it's possible to load only boot + * drivers. + */ + InitializeObjectAttributes( + &ObjectAttributes, + &LinkName, + 0, + NULL, + NULL); + Status = ZwOpenFile( + &Handle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + 0); + if (NT_SUCCESS(Status)) + { + BootDrivers = FALSE; + ZwClose(Handle); + } + else + BootDrivers = TRUE; + + /* + * Initialize services for discovered children. Only boot drivers will + * be loaded from boot driver! + */ + Status = IopInitializePnpServices(DeviceNode, BootDrivers); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + DPRINT("IopInvalidateDeviceRelations() finished\n"); + Status = STATUS_SUCCESS; + +cleanup: + IoFreeWorkItem(Data->WorkItem); + if (Event) + { + Data->Status = Status; + KeSetEvent(Event, 0, FALSE); + } + else + ExFreePool(Data); } - VOID INIT_FUNCTION PnpInit(VOID) { @@ -2584,7 +2578,7 @@ PnpInit(VOID) L"HTREE\\ROOT\\0")) { CPRINT("Failed to create the instance path!\n"); - KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, STATUS_UNSUCCESSFUL, 0, 0, 0); + KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0); } /* Report the device to the user-mode pnp manager */ @@ -3141,14 +3135,6 @@ PnpInit2(VOID) CPRINT("IopUpdateRootKey() failed\n"); KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); } - - /* Set root device instance data */ - Status = IopSetRootDeviceInstanceData(IopRootDeviceNode); - if (!NT_SUCCESS(Status)) - { - CPRINT("Failed to set instance data\n"); - KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); - } } /* EOF */ From 1b0d4ce1546c3018af0472a8e65c9ad13fcddaf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 17 Sep 2006 00:28:19 +0000 Subject: [PATCH 236/488] Install VMware driver using UpdateDriverForPlugAndPlayDevicesW function. Installing a driver is not as easy as copying files and adding some registry entries, especially when autogenerated PnP ids change... svn path=/trunk/; revision=24153 --- reactos/base/setup/vmwinst/vmware.inf | 32 --- reactos/base/setup/vmwinst/vmwinst.c | 275 ++++------------------ reactos/base/setup/vmwinst/vmwinst.h | 2 - reactos/base/setup/vmwinst/vmwinst.rbuild | 2 + reactos/base/setup/vmwinst/vmwinst.rc | 6 - 5 files changed, 44 insertions(+), 273 deletions(-) delete mode 100755 reactos/base/setup/vmwinst/vmware.inf diff --git a/reactos/base/setup/vmwinst/vmware.inf b/reactos/base/setup/vmwinst/vmware.inf deleted file mode 100755 index 3bae93ef4c0..00000000000 --- a/reactos/base/setup/vmwinst/vmware.inf +++ /dev/null @@ -1,32 +0,0 @@ -[version] -signature="$CHICAGO$" - -[DefaultInstall] -AddReg=VMXReg - -[VMXReg] -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","ErrorControl",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Group",0x00000000,"Video" -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","ImagePath",0x00020000,"system32\drivers\vmx_svga.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Start",0x00010001,0x00000004 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Type",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","InstalledDisplayDrivers",0x00010000,"vmx_fb" -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.0",0x00000001,36,34,30,78,34,38,30,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.1",0x00000001,38,30,30,78,36,30,30,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.2",0x00000001,31,30,32,34,78,37,36,38,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.3",0x00000001,31,31,35,32,78,38,36,34,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.4",0x00000001,31,32,38,30,78,39,36,30,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.5",0x00000001,31,32,38,30,78,31,30,32,34,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.6",0x00000001,31,34,30,30,78,31,30,35,30,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.7",0x00000001,31,36,30,30,78,31,32,30,30,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.8",0x00000001,31,37,39,32,78,31,33,34,34,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.9",0x00000001,31,38,35,36,78,31,33,39,32,00 -HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.10",0x00000001,31,39,32,30,78,31,34,34,30,00 -HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.Flags",0x00010001,0 -HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.VRefresh",0x00010001,85 -HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.XPanning",0x00010001,0 -HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.YPanning",0x00010001,0 -HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.BitsPerPel",0x00010001,16 -HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.XResolution",0x00010001,800 -HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.YResolution",0x00010001,600 -HKLM,"SYSTEM\CurrentControlSet\Enum\PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD&REV_00\1&f103bba4&0F","Service",0x00000000,"vmx_svga" diff --git a/reactos/base/setup/vmwinst/vmwinst.c b/reactos/base/setup/vmwinst/vmwinst.c index 3729fba5fc1..c68242cb928 100644 --- a/reactos/base/setup/vmwinst/vmwinst.c +++ b/reactos/base/setup/vmwinst/vmwinst.c @@ -18,8 +18,7 @@ * * VMware is a registered trademark of VMware, Inc. */ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS VMware(r) driver installation utility * FILE: subsys/system/vmwinst/vmwinst.c @@ -28,9 +27,11 @@ */ #include #include +#include #include #include #include "vmwinst.h" +#include extern VOID CALLBACK InstallHinfSectionW(HWND hwnd, HINSTANCE ModuleHandle, PCWSTR CmdLineBuffer, INT nCmdShow); @@ -67,7 +68,7 @@ LONG CALLBACK VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) return EXCEPTION_CONTINUE_EXECUTION; } -BOOL +static BOOL DetectVMware(int *Version) { int magic, ver; @@ -95,27 +96,8 @@ DetectVMware(int *Version) return FALSE; } -BOOL -ProcessMessage(void) -{ - MSG msg; - if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - return TRUE; - } - return FALSE; -} - -void -ProcessMessages(void) -{ - while(ProcessMessage()); -} - /* try to open the file */ -BOOL +static BOOL FileExists(WCHAR *Path, WCHAR *File) { WCHAR FileName[MAX_PATH + 1]; @@ -167,54 +149,8 @@ CenterWindow(HWND hWnd) } -/* Copy file */ -BOOL -InstallFile(WCHAR *Destination, WCHAR *File) -{ - static char Buffer[1024]; - WCHAR SourceFileName[MAX_PATH + 1]; - WCHAR DestFileName[MAX_PATH + 1]; - HANDLE SourceFileHandle, DestFileHandle; - DWORD DataRead, DataWritten; - - SourceFileName[0] = L'\0'; - DestFileName[0] = L'\0'; - wcscat(SourceFileName, SrcPath); - wcscat(SourceFileName, File); - wcscat(DestFileName, Destination); - wcscat(DestFileName, File); - - SourceFileHandle = CreateFile(SourceFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if(SourceFileHandle == INVALID_HANDLE_VALUE) - { - return FALSE; - } - DestFileHandle = CreateFile(DestFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if(DestFileHandle == INVALID_HANDLE_VALUE) - { - CloseHandle(SourceFileHandle); - return FALSE; - } - - while(ReadFile(SourceFileHandle, Buffer, sizeof(Buffer), &DataRead, NULL) && DataRead > 0) - { - if(!WriteFile(DestFileHandle, Buffer, DataRead, &DataWritten, NULL) || - DataRead != DataWritten) - { - CloseHandle(SourceFileHandle); - CloseHandle(DestFileHandle); - DeleteFile(DestFileName); - return FALSE; - } - } - - CloseHandle(SourceFileHandle); - CloseHandle(DestFileHandle); - return TRUE; -} - /* Find the drive with the inserted VMware cd-rom */ -BOOL +static BOOL IsVMwareCDInDrive(WCHAR *Drv) { static WCHAR Drive[4] = L"X:\\"; @@ -258,14 +194,14 @@ IsVMwareCDInDrive(WCHAR *Drv) return FALSE; } -BOOL +static BOOL LoadResolutionSettings(DWORD *ResX, DWORD *ResY, DWORD *ColDepth) { HKEY hReg; DWORD Type, Size; if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0", + L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga\\Device0", 0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS) { return FALSE; @@ -273,29 +209,26 @@ LoadResolutionSettings(DWORD *ResX, DWORD *ResY, DWORD *ColDepth) if(RegQueryValueEx(hReg, L"DefaultSettings.BitsPerPel", 0, &Type, (BYTE*)ColDepth, &Size) != ERROR_SUCCESS || Type != REG_DWORD) { - RegCloseKey(hReg); - return FALSE; + *ColDepth = 8; } if(RegQueryValueEx(hReg, L"DefaultSettings.XResolution", 0, &Type, (BYTE*)ResX, &Size) != ERROR_SUCCESS || Type != REG_DWORD) { - RegCloseKey(hReg); - return FALSE; + *ResX = 640; } if(RegQueryValueEx(hReg, L"DefaultSettings.YResolution", 0, &Type, (BYTE*)ResY, &Size) != ERROR_SUCCESS || Type != REG_DWORD) { - RegCloseKey(hReg); - return FALSE; + *ResY = 480; } RegCloseKey(hReg); return TRUE; } -BOOL +static BOOL IsVmwSVGAEnabled(VOID) { HKEY hReg; @@ -320,13 +253,13 @@ IsVmwSVGAEnabled(VOID) -BOOL +static BOOL SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth) { HKEY hReg; if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0", + L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga\\Device0", 0, KEY_SET_VALUE, &hReg) != ERROR_SUCCESS) { return FALSE; @@ -353,7 +286,7 @@ SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth) return TRUE; } -BOOL +static BOOL EnableDriver(WCHAR *Key, BOOL Enable) { DWORD Value; @@ -376,7 +309,7 @@ EnableDriver(WCHAR *Key, BOOL Enable) } /* Activate the vmware driver and deactivate the others */ -BOOL +static BOOL EnableVmwareDriver(BOOL VBE, BOOL VGA, BOOL VMX) { if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\VBE", VBE)) @@ -395,94 +328,11 @@ EnableVmwareDriver(BOOL VBE, BOOL VGA, BOOL VMX) return TRUE; } -/* Make sure the required registry entries are present */ -BOOL -AddVmwareRegistryEntries() -{ - HRSRC VmwareInfResource; - HGLOBAL VmwareInfMem; - PVOID VmwareInfLocked; - DWORD Size; - WCHAR TempPath[MAX_PATH]; - WCHAR BufferSize; - WCHAR TempFileName[MAX_PATH]; - HANDLE TempFile; - DWORD Written; - WCHAR CmdLine[19 + MAX_PATH]; - - VmwareInfResource = FindResourceW(hAppInstance, - MAKEINTRESOURCE(IDR_VMWARE_INF), - L"RT_INF"); - if (NULL == VmwareInfResource) - { - return FALSE; - } - Size = SizeofResource(hAppInstance, VmwareInfResource); - if (0 == Size) - { - return FALSE; - } - VmwareInfMem = LoadResource(hAppInstance, VmwareInfResource); - if (NULL == VmwareInfMem) - { - return FALSE; - } - VmwareInfLocked = LockResource(VmwareInfMem); - if (NULL == VmwareInfLocked) - { - return FALSE; - } - - BufferSize = GetTempPathW(sizeof(TempPath) / sizeof(TempPath[0]), TempPath); - if (0 == BufferSize || sizeof(TempPath) / sizeof(TempPath[0]) < BufferSize) - { - return FALSE; - } - if (0 == GetTempFileNameW(TempPath, L"vmx", 0, TempFileName)) - { - return FALSE; - } - - TempFile = CreateFileW(TempFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (INVALID_HANDLE_VALUE == TempFile) - { - DeleteFile(TempFileName); - return FALSE; - } - if (! WriteFile(TempFile, VmwareInfLocked, Size, &Written, NULL) || - Written != Size) - { - CloseHandle(TempFile); - DeleteFile(TempFileName); - return FALSE; - } - CloseHandle(TempFile); - - wcscpy(CmdLine, L"DefaultInstall 128 "); - wcscat(CmdLine, TempFileName); - InstallHinfSectionW(NULL, NULL, CmdLine, 0); - - DeleteFile(TempFileName); - - return TRUE; -} - /* GUI */ -void -InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DWORD Flags, DLGPROC DlgProc) -{ - ZeroMemory(psp, sizeof(PROPSHEETPAGE)); - psp->dwSize = sizeof(PROPSHEETPAGE); - psp->dwFlags = PSP_DEFAULT | Flags; - psp->hInstance = hAppInstance; - psp->pszTemplate = MAKEINTRESOURCE(idDlg); - psp->pfnDlgProc = DlgProc; -} /* Property page dialog callback */ -INT_PTR CALLBACK +static INT_PTR CALLBACK PageWelcomeProc( HWND hwndDlg, UINT uMsg, @@ -512,23 +362,6 @@ PageWelcomeProc( { if(DriverFilesFound) { - if(!AddVmwareRegistryEntries()) - { - WCHAR Msg[1024]; - LoadString(hAppInstance, IDS_FAILEDTOADDREGENTRIES, Msg, sizeof(Msg) / sizeof(WCHAR)); - MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING); - SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_WELCOMEPAGE); - return TRUE; - } - if(!EnableVmwareDriver(TRUE, TRUE, TRUE)) - { - - WCHAR Msg[1024]; - LoadString(hAppInstance, IDS_FAILEDTOACTIVATEDRIVER, Msg, sizeof(Msg) / sizeof(WCHAR)); - MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING); - SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_WELCOMEPAGE); - return TRUE; - } SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CONFIG); return TRUE; } @@ -542,7 +375,7 @@ PageWelcomeProc( } /* Property page dialog callback */ -INT_PTR CALLBACK +static INT_PTR CALLBACK PageInsertDiscProc( HWND hwndDlg, UINT uMsg, @@ -570,7 +403,7 @@ PageInsertDiscProc( return FALSE; } -VOID +static VOID InstTerminateInstaller(BOOL Wait) { if(hInstallationThread != NULL) @@ -587,10 +420,11 @@ InstTerminateInstaller(BOOL Wait) } } -DWORD STDCALL +static DWORD STDCALL InstInstallationThread(LPVOID lpParameter) { HANDLE hThread; + WCHAR InfFileName[1024]; BOOL DriveAvailable; int DrivesTested = 0; @@ -613,48 +447,23 @@ InstInstallationThread(LPVOID lpParameter) if(AbortInstall != 0) goto done; PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_COPYINGFILES, 0); - if(AbortInstall != 0) goto done; - if(!InstallFile(DestinationPath, vmx_fb)) + wcscpy(InfFileName, SrcPath); + wcscat(InfFileName, L"vmx_svga.inf"); + DPRINT1("Calling UpdateDriverForPlugAndPlayDevices()\n"); + if (!UpdateDriverForPlugAndPlayDevices( + hInstallationNotifyWnd, + L"PCI\\VEN_15AD&DEV_0405&SUBSYS_040515AD&REV_00", + InfFileName, + 0, + NULL)) { - PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0); - goto cleanup; + AbortInstall = 1; } - - Sleep(250); - - if(AbortInstall != 0) goto done; - if(!InstallFile(DestinationPath, vmx_mode)) + else { - PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0); - goto cleanup; + AbortInstall = 0; } - Sleep(250); - - if(AbortInstall != 0) goto done; - if(!InstallFile(DestinationDriversPath, vmx_svga)) - { - PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0); - goto cleanup; - } - - Sleep(250); - - if(AbortInstall != 0) goto done; - PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_ENABLINGDRIVER, 0); - if(!AddVmwareRegistryEntries()) - { - PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOADDREGENTRIES, 0); - goto cleanup; - } - if(!EnableVmwareDriver(TRUE, TRUE, TRUE)) - { - PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOACTIVATEDRIVER, 0); - goto cleanup; - } - - Sleep(500); - done: switch(AbortInstall) { @@ -675,7 +484,7 @@ cleanup: return 0; } -BOOL +static BOOL InstStartInstallationThread(HWND hwndNotify) { if(hInstallationThread == NULL) @@ -702,7 +511,7 @@ InstStartInstallationThread(HWND hwndNotify) } /* Property page dialog callback */ -INT_PTR CALLBACK +static INT_PTR CALLBACK PageInstallingProc( HWND hwndDlg, UINT uMsg, @@ -771,7 +580,7 @@ PageInstallingProc( } /* Property page dialog callback */ -INT_PTR CALLBACK +static INT_PTR CALLBACK PageInstallFailedProc( HWND hwndDlg, UINT uMsg, @@ -796,7 +605,7 @@ PageInstallFailedProc( return FALSE; } -void +static void FillComboBox(HWND Dlg, int idComboBox, int From, int To) { int i; @@ -819,7 +628,7 @@ typedef struct } MAPCTLRES; /* Property page dialog callback */ -INT_PTR CALLBACK +static INT_PTR CALLBACK PageConfigProc( HWND hwndDlg, UINT uMsg, @@ -938,7 +747,7 @@ PageConfigProc( } /* Property page dialog callback */ -INT_PTR CALLBACK +static INT_PTR CALLBACK PageChooseActionProc( HWND hwndDlg, UINT uMsg, @@ -990,7 +799,7 @@ PageChooseActionProc( } /* Property page dialog callback */ -INT_PTR CALLBACK +static INT_PTR CALLBACK PageSelectDriverProc( HWND hwndDlg, UINT uMsg, @@ -1052,7 +861,7 @@ PageSelectDriverProc( return FALSE; } -VOID +static VOID ShowUninstNotice(HWND Owner) { WCHAR Msg[1024]; @@ -1060,7 +869,7 @@ ShowUninstNotice(HWND Owner) MessageBox(Owner, Msg, NULL, MB_ICONINFORMATION); } -INT_PTR CALLBACK +static INT_PTR CALLBACK PageDoUninstallProc( HWND hwndDlg, UINT uMsg, diff --git a/reactos/base/setup/vmwinst/vmwinst.h b/reactos/base/setup/vmwinst/vmwinst.h index 34664530f7c..a94df9d5f61 100644 --- a/reactos/base/setup/vmwinst/vmwinst.h +++ b/reactos/base/setup/vmwinst/vmwinst.h @@ -68,6 +68,4 @@ #define IDD_DOUNINSTALLTITLE 361 #define IDD_DOUNINSTALLSUBTITLE 362 -#define IDR_VMWARE_INF 400 - #endif /* __VMWINST_H */ diff --git a/reactos/base/setup/vmwinst/vmwinst.rbuild b/reactos/base/setup/vmwinst/vmwinst.rbuild index 44530a29202..8fd35910c3c 100644 --- a/reactos/base/setup/vmwinst/vmwinst.rbuild +++ b/reactos/base/setup/vmwinst/vmwinst.rbuild @@ -8,9 +8,11 @@ advapi32 comctl32 comdlg32 + newdev user32 setupapi shell32 + ntdll vmwinst.c vmwinst.rc diff --git a/reactos/base/setup/vmwinst/vmwinst.rc b/reactos/base/setup/vmwinst/vmwinst.rc index 432d86466e3..3674249cab7 100644 --- a/reactos/base/setup/vmwinst/vmwinst.rc +++ b/reactos/base/setup/vmwinst/vmwinst.rc @@ -1,5 +1,3 @@ -/* $Id$ */ - #include #include "vmwinst.h" @@ -16,10 +14,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US IDB_WATERMARK BITMAP "resources/watermark.bmp" IDB_HEADER BITMAP "resources/header.bmp" -/* The vmware.inf file */ -IDR_VMWARE_INF RT_INF "vmware.inf" - - /* * Everything specific to any language goes in one of the specific * files. Note that you can and may override resources which also have From bee17dc2902b5621a4c28f061721686d9d968dcc Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 17 Sep 2006 05:20:24 +0000 Subject: [PATCH 237/488] - Large cleanup of psmgr.c. Move all externs and prototype, into headers, reformat and re-arrange the code. - Optimize PspLookupUserEntrypoints to use static ANSI_STRINGs instead of building them at runtime. - Fix mapping/loading of the System DLL so that it's loaded as executable code, not read-only code. Also fix a handle leak of the section, and re-factor some code into smaller shared functions to reduce code duplication. svn path=/trunk/; revision=24154 --- reactos/ntoskrnl/include/internal/ex.h | 9 + reactos/ntoskrnl/include/internal/ke.h | 4 + reactos/ntoskrnl/include/internal/ps.h | 79 ++--- reactos/ntoskrnl/ps/psmgr.c | 464 ++++++++----------------- 4 files changed, 200 insertions(+), 356 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 9642d12b7b3..d8e3674fa55 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -7,6 +7,9 @@ extern TIME_ZONE_INFORMATION ExpTimeZoneInfo; extern LARGE_INTEGER ExpTimeZoneBias; extern ULONG ExpTimeZoneId; extern POBJECT_TYPE ExEventPairObjectType; +extern ULONG NtBuildNumber; +extern ULONG NtMajorVersion; +extern ULONG NtMinorVersion; #define MAX_FAST_REFS 7 @@ -45,6 +48,12 @@ VOID NTAPI ExInit2(VOID); +VOID +NTAPI +ExPhase2Init( + IN PVOID Context +); + VOID NTAPI ExpInitTimeZoneInfo(VOID); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index f14a2657eb6..4ddb372711c 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -129,6 +129,10 @@ extern ULONG KiMask32Array[MAXIMUM_PRIORITY]; extern ULONG KiIdleSummary; extern VOID KiTrap8(VOID); extern VOID KiTrap2(VOID); +extern PVOID KeUserApcDispatcher; +extern PVOID KeUserCallbackDispatcher; +extern PVOID KeUserExceptionDispatcher; +extern PVOID KeRaiseUserExceptionDispatcher; /* MACROS *************************************************************************/ diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index cadf8379bb7..60d3acfed36 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -79,51 +79,6 @@ PspShutdownProcessManager( VOID ); -VOID -INIT_FUNCTION -NTAPI -PsInitThreadManagment( - VOID -); - -VOID -INIT_FUNCTION -NTAPI -PiInitProcessManager( - VOID -); - -VOID -INIT_FUNCTION -NTAPI -PsInitProcessManagment( - VOID -); - -VOID -INIT_FUNCTION -NTAPI -PsInitIdleThread( - VOID -); - -NTSTATUS -NTAPI -PsInitializeIdleOrFirstThread( - IN PEPROCESS Process, - OUT PETHREAD* ThreadPtr, - IN PKSTART_ROUTINE StartRoutine, - IN KPROCESSOR_MODE AccessMode, - IN BOOLEAN First -); - -VOID -NTAPI -INIT_FUNCTION -PsInitJobManagment( - VOID -); - // // Utility Routines // @@ -173,6 +128,23 @@ PsReferenceProcessFilePointer( OUT PFILE_OBJECT *FileObject ); +// +// Process Routines +// +NTSTATUS +NTAPI +PspCreateProcess( + OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN HANDLE ParentProcess OPTIONAL, + IN ULONG Flags, + IN HANDLE SectionHandle OPTIONAL, + IN HANDLE DebugPort OPTIONAL, + IN HANDLE ExceptionPort OPTIONAL, + IN BOOLEAN InJob +); + // // Security Routines // @@ -335,6 +307,18 @@ PspRemoveProcessFromJob( IN PEJOB Job ); +VOID +NTAPI +PspInitializeJobStructures( + VOID +); + +VOID +NTAPI +PspDeleteJob( + IN PVOID ObjectBody +); + // // Global data inside the Process Manager // @@ -367,6 +351,11 @@ extern BOOLEAN PspUseJobSchedulingClasses; extern CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES]; extern ULONG PsRawPrioritySeparation; extern POBJECT_TYPE _PsThreadType; +extern PTOKEN PspBootAccessToken; +extern GENERIC_MAPPING PspJobMapping; +extern POBJECT_TYPE PsJobType; +extern LARGE_INTEGER ShortPsLockDelay; +extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY]; // // Inlined Functions diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index d0708efd820..158a443db72 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -1,22 +1,17 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ps/psmgr.c - * PURPOSE: Process management - * - * PROGRAMMERS: David Welch (welch@mcmail.com) + * PURPOSE: Process Manager: Initialization Code + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES **************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG #include -extern LARGE_INTEGER ShortPsLockDelay; -extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY]; - GENERIC_MAPPING PspProcessMapping = { STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, @@ -37,18 +32,16 @@ GENERIC_MAPPING PspThreadMapping = THREAD_ALL_ACCESS }; -extern ULONG NtBuildNumber; -extern ULONG NtMajorVersion; -extern ULONG NtMinorVersion; -extern PVOID KeUserApcDispatcher; -extern PVOID KeUserCallbackDispatcher; -extern PVOID KeUserExceptionDispatcher; -extern PVOID KeRaiseUserExceptionDispatcher; - PVOID PspSystemDllBase; PVOID PspSystemDllSection; PVOID PspSystemDllEntryPoint; +ANSI_STRING ThunkName = RTL_CONSTANT_STRING("LdrInitializeThunk"); +ANSI_STRING ApcName = RTL_CONSTANT_STRING("KiUserApcDispatcher"); +ANSI_STRING ExceptName = RTL_CONSTANT_STRING("KiUserExceptionDispatcher"); +ANSI_STRING CallbackName = RTL_CONSTANT_STRING("KiUserCallbackDispatcher"); +ANSI_STRING RaiseName = RTL_CONSTANT_STRING("KiRaiseUserExceptionDispatcher"); + PHANDLE_TABLE PspCidTable; PEPROCESS PsInitialSystemProcess = NULL; @@ -64,40 +57,141 @@ struct ULONG PspDefaultPagedLimit, PspDefaultNonPagedLimit, PspDefaultPagefileLimit; BOOLEAN PspDoingGiveBacks; -extern PTOKEN PspBootAccessToken; - -extern GENERIC_MAPPING PspJobMapping; -extern POBJECT_TYPE PsJobType; - -VOID -NTAPI -PspInitializeJobStructures(VOID); - -VOID -NTAPI -PspDeleteJob(IN PVOID ObjectBody); - -/* FUNCTIONS ***************************************************************/ +/* PRIVATE FUNCTIONS *********************************************************/ NTSTATUS NTAPI -PspCreateProcess(OUT PHANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN HANDLE ParentProcess OPTIONAL, - IN ULONG Flags, - IN HANDLE SectionHandle OPTIONAL, - IN HANDLE DebugPort OPTIONAL, - IN HANDLE ExceptionPort OPTIONAL, - IN BOOLEAN InJob); +PspLookupSystemDllEntryPoint(IN PANSI_STRING Name, + IN PVOID *EntryPoint) +{ + /* Call the LDR Routine */ + return LdrGetProcedureAddress(PspSystemDllBase, Name, 0, EntryPoint); +} -/* FUNCTIONS *****************************************************************/ - -VOID +NTSTATUS NTAPI -ExPhase2Init( - IN PVOID Context -); +PspLookupKernelUserEntryPoints(VOID) +{ + NTSTATUS Status; + + /* Get user-mode startup thunk */ + Status = PspLookupSystemDllEntryPoint(&ThunkName, + &PspSystemDllEntryPoint); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode APC trampoline */ + Status = PspLookupSystemDllEntryPoint(&ApcName, + &KeUserApcDispatcher); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode exception dispatcher */ + Status = PspLookupSystemDllEntryPoint(&ExceptName, + &KeUserExceptionDispatcher); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode callback dispatcher */ + Status = PspLookupSystemDllEntryPoint(&CallbackName, + &KeUserCallbackDispatcher); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode exception raise trampoline */ + Status = PspLookupSystemDllEntryPoint(&RaiseName, + &KeRaiseUserExceptionDispatcher); + return Status; +} + +NTSTATUS +NTAPI +PspMapSystemDll(IN PEPROCESS Process, + IN PVOID *DllBase) +{ + NTSTATUS Status; + LARGE_INTEGER Offset = {{0}}; + SIZE_T ViewSize = 0; + PVOID ImageBase = 0; + + /* Map the System DLL */ + Status = MmMapViewOfSection(PspSystemDllSection, + Process, + (PVOID*)&ImageBase, + 0, + 0, + &Offset, + &ViewSize, + ViewShare, + 0, + PAGE_READWRITE); + + /* Write the image base and return status */ + if (DllBase) *DllBase = ImageBase; + return Status; +} + +NTSTATUS +NTAPI +PsLocateSystemDll(VOID) +{ + UNICODE_STRING DllName = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll"); + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle, SectionHandle; + NTSTATUS Status; + ULONG_PTR HardErrorParameters; + ULONG HardErrorResponse; + + /* Locate and open NTDLL to determine ImageBase and LdrStartup */ + InitializeObjectAttributes(&ObjectAttributes, &DllName, 0, NULL, NULL); + Status = ZwOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + 0); + if (!NT_SUCCESS(Status)) return Status; + + /* FIXME: Check if the image is valid */ + Status = STATUS_SUCCESS; //MmCheckSystemImage(FileHandle, TRUE); + if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) + { + /* Raise a hard error */ + HardErrorParameters = (ULONG_PTR)&DllName; + NtRaiseHardError(Status, + 1, + 1, + &HardErrorParameters, + OptionOk, + &HardErrorResponse); + return Status; + } + + /* Create a section for NTDLL */ + Status = ZwCreateSection(&SectionHandle, + SECTION_ALL_ACCESS, + NULL, + NULL, + PAGE_EXECUTE, + SEC_IMAGE, + FileHandle); + ZwClose(FileHandle); + if (!NT_SUCCESS(Status)) return Status; + + /* Reference the Section */ + Status = ObReferenceObjectByHandle(SectionHandle, + SECTION_ALL_ACCESS, + MmSectionObjectType, + KernelMode, + (PVOID*)&PspSystemDllSection, + NULL); + ZwClose(SectionHandle); + if (!NT_SUCCESS(Status)) return Status; + + /* Map it */ + Status = PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase); + + /* Now get the Entrypoints */ + PspLookupKernelUserEntryPoints(); + return STATUS_SUCCESS; +} BOOLEAN NTAPI @@ -268,9 +362,7 @@ PspInitPhase0(VOID) NULL); /* The PD we gave it is invalid at this point, do what old ROS did */ - PsInitialSystemProcess->Pcb.DirectoryTableBase = (LARGE_INTEGER) - (LONGLONG) - (ULONG)MmGetPageDirectory(); + PsInitialSystemProcess->Pcb.DirectoryTableBase.LowPart = (ULONG)MmGetPageDirectory(); PsIdleProcess->Pcb.DirectoryTableBase = PsInitialSystemProcess->Pcb.DirectoryTableBase; /* Copy the process names */ @@ -305,271 +397,21 @@ PspInitPhase0(VOID) return TRUE; } -NTSTATUS -STDCALL -INIT_FUNCTION -PspLookupKernelUserEntryPoints(VOID) -{ - ANSI_STRING ProcedureName; - NTSTATUS Status; +/* PUBLIC FUNCTIONS **********************************************************/ - /* Retrieve ntdll's startup address */ - DPRINT("Getting Entrypoint: %p\n", PspSystemDllBase); - RtlInitAnsiString(&ProcedureName, "LdrInitializeThunk"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &PspSystemDllEntryPoint); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Get User APC Dispatcher */ - DPRINT("Getting Entrypoint\n"); - RtlInitAnsiString(&ProcedureName, "KiUserApcDispatcher"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &KeUserApcDispatcher); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Get Exception Dispatcher */ - DPRINT("Getting Entrypoint\n"); - RtlInitAnsiString(&ProcedureName, "KiUserExceptionDispatcher"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &KeUserExceptionDispatcher); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Get Callback Dispatcher */ - DPRINT("Getting Entrypoint\n"); - RtlInitAnsiString(&ProcedureName, "KiUserCallbackDispatcher"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &KeUserCallbackDispatcher); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Get Raise Exception Dispatcher */ - DPRINT("Getting Entrypoint\n"); - RtlInitAnsiString(&ProcedureName, "KiRaiseUserExceptionDispatcher"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &KeRaiseUserExceptionDispatcher); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Return success */ - return(STATUS_SUCCESS); -} - -NTSTATUS -STDCALL -PspMapSystemDll(PEPROCESS Process, - PVOID *DllBase) -{ - NTSTATUS Status; - SIZE_T ViewSize = 0; - PVOID ImageBase = 0; - - /* Map the System DLL */ - DPRINT("Mapping System DLL\n"); - Status = MmMapViewOfSection(PspSystemDllSection, - Process, - (PVOID*)&ImageBase, - 0, - 0, - NULL, - &ViewSize, - 0, - MEM_COMMIT, - PAGE_READWRITE); - - if (!NT_SUCCESS(Status)) { - - DPRINT1("Failed to map System DLL Into Process\n"); - } - - if (DllBase) *DllBase = ImageBase; - - return Status; -} - -NTSTATUS -STDCALL -INIT_FUNCTION -PsLocateSystemDll(VOID) -{ - UNICODE_STRING DllPathname = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll"); - OBJECT_ATTRIBUTES FileObjectAttributes; - IO_STATUS_BLOCK Iosb; - HANDLE FileHandle; - HANDLE NTDllSectionHandle; - NTSTATUS Status; - CHAR BlockBuffer[1024]; - PIMAGE_DOS_HEADER DosHeader; - PIMAGE_NT_HEADERS NTHeaders; - - /* Locate and open NTDLL to determine ImageBase and LdrStartup */ - InitializeObjectAttributes(&FileObjectAttributes, - &DllPathname, - 0, - NULL, - NULL); - - DPRINT("Opening NTDLL\n"); - Status = ZwOpenFile(&FileHandle, - FILE_READ_ACCESS, - &FileObjectAttributes, - &Iosb, - FILE_SHARE_READ, - FILE_SYNCHRONOUS_IO_NONALERT); - - if (!NT_SUCCESS(Status)) { - DPRINT1("NTDLL open failed (Status %x)\n", Status); - return Status; - } - - /* Load NTDLL is valid */ - DPRINT("Reading NTDLL\n"); - Status = ZwReadFile(FileHandle, - 0, - 0, - 0, - &Iosb, - BlockBuffer, - sizeof(BlockBuffer), - 0, - 0); - if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer)) { - - DPRINT1("NTDLL header read failed (Status %x)\n", Status); - ZwClose(FileHandle); - return Status; - } - - /* Check if it's valid */ - DosHeader = (PIMAGE_DOS_HEADER)BlockBuffer; - NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew); - - if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE) || - (DosHeader->e_lfanew == 0L) || - (*(PULONG) NTHeaders != IMAGE_NT_SIGNATURE)) { - - DPRINT1("NTDLL format invalid\n"); - ZwClose(FileHandle); - return(STATUS_UNSUCCESSFUL); - } - - /* Create a section for NTDLL */ - DPRINT("Creating section\n"); - Status = ZwCreateSection(&NTDllSectionHandle, - SECTION_ALL_ACCESS, - NULL, - NULL, - PAGE_READONLY, - SEC_IMAGE | SEC_COMMIT, - FileHandle); - if (!NT_SUCCESS(Status)) { - - DPRINT1("NTDLL create section failed (Status %x)\n", Status); - ZwClose(FileHandle); - return(Status); - } - ZwClose(FileHandle); - - /* Reference the Section */ - DPRINT("ObReferenceObjectByHandle section: %d\n", NTDllSectionHandle); - Status = ObReferenceObjectByHandle(NTDllSectionHandle, - SECTION_ALL_ACCESS, - MmSectionObjectType, - KernelMode, - (PVOID*)&PspSystemDllSection, - NULL); - if (!NT_SUCCESS(Status)) { - - DPRINT1("NTDLL section reference failed (Status %x)\n", Status); - return(Status); - } - - /* Map it */ - PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase); - DPRINT("LdrpSystemDllBase: %x\n", PspSystemDllBase); - - /* Now get the Entrypoints */ - PspLookupKernelUserEntryPoints(); - - return STATUS_SUCCESS; -} - - -/********************************************************************** - * NAME EXPORTED - * PsGetVersion - * - * DESCRIPTION - * Retrieves the current OS version. - * - * ARGUMENTS - * MajorVersion Pointer to a variable that will be set to the - * major version of the OS. Can be NULL. - * - * MinorVersion Pointer to a variable that will be set to the - * minor version of the OS. Can be NULL. - * - * BuildNumber Pointer to a variable that will be set to the - * build number of the OS. Can be NULL. - * - * CSDVersion Pointer to a variable that will be set to the - * CSD string of the OS. Can be NULL. - * - * RETURN VALUE - * TRUE OS is a checked build. - * FALSE OS is a free build. - * - * NOTES - * +/* * @implemented */ BOOLEAN -STDCALL -PsGetVersion(PULONG MajorVersion OPTIONAL, - PULONG MinorVersion OPTIONAL, - PULONG BuildNumber OPTIONAL, - PUNICODE_STRING CSDVersion OPTIONAL) +NTAPI +PsGetVersion(IN PULONG MajorVersion OPTIONAL, + IN PULONG MinorVersion OPTIONAL, + IN PULONG BuildNumber OPTIONAL, + IN PUNICODE_STRING CSDVersion OPTIONAL) { - if (MajorVersion) - *MajorVersion = NtMajorVersion; - - if (MinorVersion) - *MinorVersion = NtMinorVersion; - - if (BuildNumber) - *BuildNumber = NtBuildNumber; + if (MajorVersion) *MajorVersion = NtMajorVersion; + if (MinorVersion) *MinorVersion = NtMinorVersion; + if (BuildNumber) *BuildNumber = NtBuildNumber; if (CSDVersion) { From 8ef78cb6e6e396302180be58ad81337a281d524e Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 17 Sep 2006 07:06:35 +0000 Subject: [PATCH 238/488] - Create a KD-compatible KiDebugRoutine and piggyback KDBG on it. - Create separate GDB entry hack routine. - Fix booting with /BREAK and continuing after an INT3/ASSERTion. svn path=/trunk/; revision=24155 --- reactos/ntoskrnl/include/internal/kd.h | 28 ++++++---- reactos/ntoskrnl/kd/kdmain.c | 67 ++++++++++++++++-------- reactos/ntoskrnl/ke/i386/exp.c | 71 +++++++++++++++----------- reactos/ntoskrnl/ke/i386/kiinit.c | 2 +- 4 files changed, 108 insertions(+), 60 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/kd.h b/reactos/ntoskrnl/include/internal/kd.h index 9a42617ff67..f3a90047d6b 100644 --- a/reactos/ntoskrnl/include/internal/kd.h +++ b/reactos/ntoskrnl/include/internal/kd.h @@ -215,15 +215,12 @@ KdpGdbStubInit( /* KD ROUTINES ***************************************************************/ -KD_CONTINUE_TYPE -STDCALL -KdpEnterDebuggerException( - PEXCEPTION_RECORD ExceptionRecord, - KPROCESSOR_MODE PreviousMode, - PCONTEXT Context, - PKTRAP_FRAME TrapFrame, - BOOLEAN FirstChance, - BOOLEAN Gdb +BOOLEAN +NTAPI +KdpCallGdb( + IN PKTRAP_FRAME TrapFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context ); ULONG @@ -245,6 +242,17 @@ KdpBochsDebugPrint( /* KD GLOBALS ***************************************************************/ +typedef +BOOLEAN +(NTAPI *PKDEBUG_ROUTINE)( + IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN SecondChance +); + /* serial debug connection */ #define DEFAULT_DEBUG_PORT 2 /* COM2 */ #define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */ @@ -337,5 +345,7 @@ extern LIST_ENTRY KdProviders; /* Whether to enter KDB as early as possible or not */ extern BOOLEAN KdpEarlyBreak; +extern PKDEBUG_ROUTINE KiDebugRoutine; + #endif #endif /* __INCLUDE_INTERNAL_KERNEL_DEBUGGER_H */ diff --git a/reactos/ntoskrnl/kd/kdmain.c b/reactos/ntoskrnl/kd/kdmain.c index 32f9828e57b..38460244794 100644 --- a/reactos/ntoskrnl/kd/kdmain.c +++ b/reactos/ntoskrnl/kd/kdmain.c @@ -96,17 +96,45 @@ KdpServiceDispatcher(ULONG Service, return Result; } -KD_CONTINUE_TYPE -STDCALL -KdpEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, - KPROCESSOR_MODE PreviousMode, - PCONTEXT Context, - PKTRAP_FRAME TrapFrame, - BOOLEAN FirstChance, - BOOLEAN Gdb) +BOOLEAN +NTAPI +KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN SecondChance) { + KD_CONTINUE_TYPE Return; + + /* HACK (just like all this routine */ + if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) Context->Eip++; + /* Get out of here if the Debugger isn't connected */ - if (KdDebuggerNotPresent) return kdHandleException; + if (KdDebuggerNotPresent) return FALSE; + + /* Call KDBG if available */ + Return = KdbEnterDebuggerException(ExceptionRecord, + PreviousMode, + Context, + TrapFrame, + !SecondChance); + + /* Convert return to BOOLEAN */ + if (Return == kdContinue) return TRUE; + return FALSE; +} + +BOOLEAN +NTAPI +KdpCallGdb(IN PKTRAP_FRAME TrapFrame, + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context) +{ + KD_CONTINUE_TYPE Return = kdDoNotHandleException; + + /* Get out of here if the Debugger isn't connected */ + if (KdDebuggerNotPresent) return FALSE; /* FIXME: * Right now, the GDB wrapper seems to handle exceptions differntly @@ -114,21 +142,16 @@ KdpEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, * one is only called once and that's it. I don't really have the knowledge * to fix the GDB stub, so until then, we'll be using this hack */ - if (Gdb) + if (WrapperInitRoutine) { - /* Call the registered wrapper */ - if (WrapperInitRoutine) return WrapperTable. - KdpExceptionRoutine(ExceptionRecord, - Context, - TrapFrame); + Return = WrapperTable.KdpExceptionRoutine(ExceptionRecord, + Context, + TrapFrame); } - /* Call KDBG if available */ - return KdbEnterDebuggerException(ExceptionRecord, - PreviousMode, - Context, - TrapFrame, - FirstChance); + /* Convert return to BOOLEAN */ + if (Return == kdContinue) return TRUE; + return FALSE; } /* PUBLIC FUNCTIONS *********************************************************/ @@ -268,4 +291,6 @@ NtSetDebugFilterState(IN ULONG ComponentId, return STATUS_SUCCESS; } +PKDEBUG_ROUTINE KiDebugRoutine = KdpEnterDebuggerException; + /* EOF */ diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 29bf6808fdb..93cc1b2bd2b 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -407,7 +407,7 @@ KeContextToTrapFrame(IN PCONTEXT Context, { /* Set the Debug Flag */ KeGetCurrentThread()->DispatcherHeader.DebugActive = - (Context->Dr7 & DR7_ACTIVE); + (Context->Dr7 & DR7_ACTIVE) ? TRUE: FALSE; } } @@ -601,7 +601,6 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, BOOLEAN FirstChance) { CONTEXT Context; - KD_CONTINUE_TYPE Action; ULONG_PTR Stack, NewStack; ULONG Size; EXCEPTION_RECORD LocalExceptRecord; @@ -647,30 +646,35 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, if (FirstChance == TRUE) { /* Break into the debugger for the first time */ - Action = KdpEnterDebuggerException(ExceptionRecord, - PreviousMode, - &Context, - TrapFrame, - TRUE, - TRUE); + if (KiDebugRoutine(TrapFrame, + ExceptionFrame, + ExceptionRecord, + &Context, + PreviousMode, + FALSE)) + { + /* Exception was handled */ + goto Handled; + } - /* If the debugger said continue, then continue */ - if (Action == kdContinue) goto Handled; + /* HACK: GDB Entry */ + if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled; /* If the Debugger couldn't handle it, dispatch the exception */ if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled; } /* This is a second-chance exception, only for the debugger */ - Action = KdpEnterDebuggerException(ExceptionRecord, - PreviousMode, - &Context, - TrapFrame, - FALSE, - FALSE); - - /* If the debugger said continue, then continue */ - if (Action == kdContinue) goto Handled; + if (KiDebugRoutine(TrapFrame, + ExceptionFrame, + ExceptionRecord, + &Context, + PreviousMode, + TRUE)) + { + /* Exception was handled */ + goto Handled; + } /* Third strike; you're out */ KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, @@ -685,17 +689,26 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, if (FirstChance) { /* Enter Debugger if available */ - Action = KdpEnterDebuggerException(ExceptionRecord, - PreviousMode, - &Context, - TrapFrame, - TRUE, - TRUE); + if (PsGetCurrentProcess()->DebugPort) + { + /* FIXME : TODO */ + ASSERT(FALSE); + } + else if (KiDebugRoutine(TrapFrame, + ExceptionFrame, + ExceptionRecord, + &Context, + PreviousMode, + FALSE)) + { + /* Exception was handled */ + goto Handled; + } - /* Exit if we're continuing */ - if (Action == kdContinue) goto Handled; + /* HACK: GDB Entry */ + if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled; - /* FIXME: Forward exception to user mode debugger */ + /* Forward exception to user mode debugger */ if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) goto Exit; /* Set up the user-stack */ @@ -797,7 +810,7 @@ DispatchToUser: Handled: /* Convert the context back into Trap/Exception Frames */ KeContextToTrapFrame(&Context, - NULL, + ExceptionFrame, TrapFrame, Context.ContextFlags, PreviousMode); diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index 48fe4d439e9..778c088d409 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -41,7 +41,7 @@ KiInitializePcr(IN ULONG ProcessorNumber, Pcr->NtTib.Self = 0; /* Set the Current Thread */ - //Pcr->PrcbData.CurrentThread = IdleThread; + Pcr->PrcbData.CurrentThread = IdleThread; /* Set pointers to ourselves */ Pcr->Self = (PKPCR)Pcr; From f07b34a9d08f0c6b97646e058fad5369c7613e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 17 Sep 2006 08:44:17 +0000 Subject: [PATCH 239/488] I don't know how to save REG_LINK info on disk, so ignore them. Incidently, fixes "make install_registry" svn path=/trunk/; revision=24156 --- reactos/tools/mkhive/registry.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/tools/mkhive/registry.c b/reactos/tools/mkhive/registry.c index 0a2847e78da..9a7aca0243a 100644 --- a/reactos/tools/mkhive/registry.c +++ b/reactos/tools/mkhive/registry.c @@ -345,8 +345,8 @@ RegSetValueExW( /* Create the link in registry hive (if applicable) */ if (Key->RegistryHive != DestKey->RegistryHive) return STATUS_SUCCESS; - lpData = (PUCHAR)&DestKey->KeyCellOffset; - cbData = sizeof(HCELL_INDEX); + DPRINT1("Save link to registry\n"); + return STATUS_NOT_IMPLEMENTED; } if ((cbData & REG_DATA_SIZE_MASK) != cbData) From b6919c977dbc3c38dd5a3810628b03c858e80316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 17 Sep 2006 10:34:51 +0000 Subject: [PATCH 240/488] Merge from Wine: James Hawkins - Add stubs for SetupOpenLog, SetupCloseLog, and SetupLogError - Implement pSetupGetField, with tests. svn path=/trunk/; revision=24162 --- reactos/dll/win32/setupapi/parser.c | 16 ++++++++++++++ reactos/dll/win32/setupapi/setupapi.spec | 7 +++--- reactos/dll/win32/setupapi/stubs.c | 27 ++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/reactos/dll/win32/setupapi/parser.c b/reactos/dll/win32/setupapi/parser.c index 0b9974d3106..f83e0ea0c3c 100644 --- a/reactos/dll/win32/setupapi/parser.c +++ b/reactos/dll/win32/setupapi/parser.c @@ -1982,6 +1982,22 @@ BOOL WINAPI SetupGetMultiSzFieldW( PINFCONTEXT context, DWORD index, PWSTR buffe return TRUE; } +/*********************************************************************** + * pSetupGetField (SETUPAPI.@) + */ +LPCWSTR WINAPI pSetupGetField( PINFCONTEXT context, DWORD index ) +{ + struct inf_file *file = context->CurrentInf; + struct field *field = get_field( file, context->Section, context->Line, index ); + + if (!field) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return NULL; + } + return field->text; +} + /*********************************************************************** * SetupGetInfFileListW (SETUPAPI.@) */ diff --git a/reactos/dll/win32/setupapi/setupapi.spec b/reactos/dll/win32/setupapi/setupapi.spec index 7c3bae3db34..83298e0eb8e 100644 --- a/reactos/dll/win32/setupapi/setupapi.spec +++ b/reactos/dll/win32/setupapi/setupapi.spec @@ -248,7 +248,7 @@ @ stub SetupCancelTemporarySourceList @ stdcall SetupCloseFileQueue(ptr) @ stdcall SetupCloseInfFile(long) -@ stub SetupCloseLog +@ stdcall SetupCloseLog() @ stdcall SetupCommitFileQueueA(long long ptr ptr) @ stdcall SetupCommitFileQueueW(long long ptr ptr) @ stdcall SetupCopyErrorA(long str str str str str long long str long ptr) @@ -446,7 +446,7 @@ @ stdcall SetupIterateCabinetA(str long ptr ptr) @ stdcall SetupIterateCabinetW(wstr long ptr ptr) @ stub SetupLogErrorA -@ stub SetupLogErrorW +@ stdcall SetupLogErrorW(wstr long) @ stub SetupLogFileA @ stub SetupLogFileW @ stdcall SetupOpenAppendInfFileA(str long ptr) @@ -454,6 +454,7 @@ @ stdcall SetupOpenFileQueue() @ stdcall SetupOpenInfFileA(str str long ptr) @ stdcall SetupOpenInfFileW(wstr wstr long ptr) +@ stdcall SetupOpenLog(long) @ stdcall SetupOpenMasterInf() @ stub SetupPromptForDiskA @ stub SetupPromptForDiskW @@ -543,7 +544,7 @@ @ stub pSetupAppendStringToMultiSz @ stub pSetupDestroyRunOnceNodeList @ stub pSetupDirectoryIdToPath -@ stub pSetupGetField +@ stdcall pSetupGetField(ptr long) @ stub pSetupGetGlobalFlags @ stub pSetupGetOsLoaderDriveAndPath @ stub pSetupGetQueueFlags diff --git a/reactos/dll/win32/setupapi/stubs.c b/reactos/dll/win32/setupapi/stubs.c index 0c22d743e9d..fbc71540eae 100644 --- a/reactos/dll/win32/setupapi/stubs.c +++ b/reactos/dll/win32/setupapi/stubs.c @@ -129,6 +129,33 @@ BOOL WINAPI SetupTerminateFileLog(HANDLE FileLogHandle) } +/*********************************************************************** + * SetupCloseLog(SETUPAPI.@) + */ +void WINAPI SetupCloseLog() +{ + FIXME("() stub\n"); +} + +/*********************************************************************** + * SetupLogErrorW(SETUPAPI.@) + */ +BOOL WINAPI SetupLogErrorW(PCWSTR MessageString, LogSeverity Severity) +{ + FIXME("(%s, %ld) stub\n", debugstr_w(MessageString), Severity); + return TRUE; +} + +/*********************************************************************** + * SetupOpenLog(SETUPAPI.@) + */ +BOOL WINAPI SetupOpenLog(BOOL Reserved) +{ + FIXME("(%d) stub\n", Reserved); + return TRUE; +} + + /*********************************************************************** * SetupDiDestroyClassImageList(SETUPAPI.@) */ From 15732d3ae276d58cafbe16efc04ca7982f016f1d Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 17 Sep 2006 10:56:13 +0000 Subject: [PATCH 241/488] implement last part of NtGdiCreateEnhMetaFile it can now create file. (add ntdll.a to rbuild need RtlDosPathNameToNtPathName_U api) svn path=/trunk/; revision=24164 --- .../win32/win32k/objects/metafile.c | 79 +++++++++++++------ reactos/subsystems/win32/win32k/win32k.rbuild | 3 +- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/metafile.c b/reactos/subsystems/win32/win32k/objects/metafile.c index 9c832ba371e..e817318b16c 100644 --- a/reactos/subsystems/win32/win32k/objects/metafile.c +++ b/reactos/subsystems/win32/win32k/objects/metafile.c @@ -23,6 +23,9 @@ #define NDEBUG #include +#define FILE_FLAG_POSIX_SEMANTICS 16777216 + + HENHMETAFILE STDCALL NtGdiCloseEnhMetaFile(HDC hDC) @@ -65,8 +68,7 @@ NtGdiCreateEnhMetaFile(HDC hDCRef, LPCWSTR Description) { PDC Dc; - HDC ret = NULL; - NTSTATUS Status; + HDC ret = NULL; IO_STATUS_BLOCK Iosb; DWORD length = 0; HDC tempHDC; @@ -166,28 +168,55 @@ NtGdiCreateEnhMetaFile(HDC hDCRef, memcpy((char *)Dc->emh + sizeof(ENHMETAHEADER), Description, length); } - ret = tempHDC; - - DPRINT1("File cretae unimplement in NtGdiCreateEnhMetaFile\n"); + ret = tempHDC; if (File) { - + DPRINT1("Trying Create EnhMetaFile\n"); - - /* disk based metafile */ - - /* FIXME - if ((Dc->hFile = CreateFileW(File, GENERIC_WRITE | GENERIC_READ, 0, - NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) - { - DC_UnLockDc(Dc); - if (hDCRef == NULL) - { - NtGdiDeleteObjectApp(tempHDC); - } - return 0; + /* disk based metafile */ + DWORD dwDesiredAccess = GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES; + + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING NtPathU; + NTSTATUS Status; + ULONG FileAttributes = (FILE_ATTRIBUTE_VALID_FLAGS & ~FILE_ATTRIBUTE_DIRECTORY); + + if (!RtlDosPathNameToNtPathName_U (File, &NtPathU, NULL, NULL)) + { + DC_UnlockDc(Dc); + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + DPRINT1("Can not Create EnhMetaFile\n"); + SetLastWin32Error(ERROR_PATH_NOT_FOUND); + return NULL; } - */ + + + InitializeObjectAttributes(&ObjectAttributes, &NtPathU, 0, NULL, NULL); + + Status = NtCreateFile (&Dc->hFile, dwDesiredAccess, &ObjectAttributes, &IoStatusBlock, + NULL, FileAttributes, 0, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE, + NULL, 0); + + RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathU.Buffer); + + if (!NT_SUCCESS(Status)) + { + Dc->hFile = NULL; + DC_UnlockDc(Dc); + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + DPRINT1("Create EnhMetaFile fail\n"); + SetLastWin32Error(ERROR_INVALID_HANDLE); + return NULL; + } + + SetLastWin32Error(IoStatusBlock.Information == FILE_OVERWRITTEN ? ERROR_ALREADY_EXISTS : 0); Status = NtWriteFile(Dc->hFile, NULL, NULL, NULL, &Iosb, (PVOID)&Dc->emh, Dc->emh->nSize, NULL, NULL); if (Status == STATUS_PENDING) @@ -200,16 +229,14 @@ NtGdiCreateEnhMetaFile(HDC hDCRef, } if (NT_SUCCESS(Status)) - { - //ret = Dc->hSelf; - ret = tempHDC; - DC_UnlockDc(Dc); + { + ret = tempHDC; + DC_UnlockDc(Dc); } else { Dc->hFile = NULL; - /* FIXME use SetLastErrorByStatus */ - //SetLastErrorByStatus(Status); + DPRINT1("Write to EnhMetaFile fail\n"); SetLastWin32Error(ERROR_CAN_NOT_COMPLETE); ret = NULL; DC_UnlockDc(Dc); diff --git a/reactos/subsystems/win32/win32k/win32k.rbuild b/reactos/subsystems/win32/win32k/win32k.rbuild index f135d7a6416..e609299d8c9 100644 --- a/reactos/subsystems/win32/win32k/win32k.rbuild +++ b/reactos/subsystems/win32/win32k/win32k.rbuild @@ -1,7 +1,7 @@ . include - include + include include include/reactos/subsys include/reactos/drivers @@ -182,6 +182,7 @@ win32k_base pseh ntoskrnl + ntdll hal freetype win32k.rc From f271868696a15b70dd894631c1d77bf12837f769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 17 Sep 2006 12:17:44 +0000 Subject: [PATCH 242/488] Don't enable acpi service by default, it would be automatically installed if necessary svn path=/trunk/; revision=24165 --- reactos/boot/bootdata/hivesys.inf | 8 -------- 1 file changed, 8 deletions(-) diff --git a/reactos/boot/bootdata/hivesys.inf b/reactos/boot/bootdata/hivesys.inf index c24b42aaed5..c0f44f258ed 100644 --- a/reactos/boot/bootdata/hivesys.inf +++ b/reactos/boot/bootdata/hivesys.inf @@ -470,14 +470,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\BusLogic","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\BusLogic","Type",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\BusLogic","Tag",0x00010001,0x00000020 -; ACPI driver -HKLM,"SYSTEM\CurrentControlSet\Services\ACPI","ErrorControl",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\ACPI","Group",0x00000000,"Boot Bus Extender" -HKLM,"SYSTEM\CurrentControlSet\Services\ACPI","ImagePath",0x00020000,"system32\drivers\acpi.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\ACPI","Start",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\ACPI","Type",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\ACPI","Tag",0x00010001,0x00000001 - ; Beep device driver HKLM,"SYSTEM\CurrentControlSet\Services\Beep","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Group",0x00000000,"Base" From ac233d6e61dc99aaa85881329b605ba009af2c44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 17 Sep 2006 12:20:44 +0000 Subject: [PATCH 243/488] Don't go further than end of string when writing value to registry svn path=/trunk/; revision=24166 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index c668049fbf2..5f47531f800 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -2841,7 +2841,7 @@ IopEnumerateDetectedDevices( ZwDeleteKey(hLevel2Key); goto nextdevice; } - Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength + sizeof(WCHAR)); + Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength); if (!NT_SUCCESS(Status)) { DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); @@ -3107,7 +3107,7 @@ IopUpdateRootKey(VOID) return Status; Status = ZwSetValueKey(hHalAcpiId, &DeviceDescU, 0, REG_SZ, HalAcpiDeviceDesc.Buffer, HalAcpiDeviceDesc.MaximumLength); if (NT_SUCCESS(Status)) - Status = ZwSetValueKey(hHalAcpiId, &HardwareIDU, 0, REG_MULTI_SZ, HalAcpiHardwareID.Buffer, HalAcpiHardwareID.MaximumLength + sizeof(WCHAR)); + Status = ZwSetValueKey(hHalAcpiId, &HardwareIDU, 0, REG_MULTI_SZ, HalAcpiHardwareID.Buffer, HalAcpiHardwareID.MaximumLength); ZwClose(hHalAcpiId); return Status; } From 5c66b358e1bf82349409a3b9ec50b4777a126478 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 17 Sep 2006 13:37:59 +0000 Subject: [PATCH 244/488] Upgrade from dejavu font 2.9 to 2.10 reason 1. Bugfix some charters that did not show in Windows/ReactOS 2. Fixing space between some charters 3. Dejvau san font support 100% folllow Latin Extended-B, Latin Extended-C, Greek and Coptic, Superscripts and Subscripts, Currency Symbols. 4. and allot more new charters svn path=/trunk/; revision=24167 --- reactos/media/fonts/DejaVuSans-Bold.ttf | Bin 457696 -> 484288 bytes .../media/fonts/DejaVuSans-BoldOblique.ttf | Bin 433172 -> 459340 bytes reactos/media/fonts/DejaVuSans-ExtraLight.ttf | Bin 125960 -> 131336 bytes reactos/media/fonts/DejaVuSans-Oblique.ttf | Bin 421060 -> 448076 bytes reactos/media/fonts/DejaVuSans.ttf | Bin 479440 -> 508652 bytes .../media/fonts/DejaVuSansCondensed-Bold.ttf | Bin 397988 -> 402732 bytes .../fonts/DejaVuSansCondensed-BoldOblique.ttf | Bin 375620 -> 379976 bytes .../fonts/DejaVuSansCondensed-Oblique.ttf | Bin 363684 -> 367800 bytes reactos/media/fonts/DejaVuSansCondensed.ttf | Bin 405392 -> 408940 bytes reactos/media/fonts/DejaVuSansMono-Bold.ttf | Bin 227828 -> 229352 bytes .../fonts/DejaVuSansMono-BoldOblique.ttf | Bin 176260 -> 177772 bytes .../media/fonts/DejaVuSansMono-Oblique.ttf | Bin 183424 -> 185004 bytes reactos/media/fonts/DejaVuSansMono.ttf | Bin 235924 -> 237508 bytes reactos/media/fonts/DejaVuSerif-Bold.ttf | Bin 197168 -> 199444 bytes .../media/fonts/DejaVuSerif-BoldOblique.ttf | Bin 178792 -> 181188 bytes reactos/media/fonts/DejaVuSerif-Oblique.ttf | Bin 177312 -> 179812 bytes reactos/media/fonts/DejaVuSerif.ttf | Bin 209112 -> 211636 bytes .../media/fonts/DejaVuSerifCondensed-Bold.ttf | Bin 174812 -> 175764 bytes .../DejaVuSerifCondensed-BoldOblique.ttf | Bin 178508 -> 179460 bytes .../fonts/DejaVuSerifCondensed-Oblique.ttf | Bin 177180 -> 178200 bytes reactos/media/fonts/DejaVuSerifCondensed.ttf | Bin 173212 -> 174232 bytes reactos/media/fonts/doc/DejaVu_NEWS.txt | 43 +++ reactos/media/fonts/doc/DejaVu_README.txt | 10 +- reactos/media/fonts/doc/DejaVu_langcover.txt | 32 ++- reactos/media/fonts/doc/DejaVu_status.txt | 264 ++++++++++++++---- reactos/media/fonts/doc/DejaVu_unicover.txt | 36 +-- 26 files changed, 298 insertions(+), 87 deletions(-) diff --git a/reactos/media/fonts/DejaVuSans-Bold.ttf b/reactos/media/fonts/DejaVuSans-Bold.ttf index b4116cab7ed07c2ba4b72a1b21fa6a30de7376a1..8af003b04216362422c7c398438f2047b4f907f9 100644 GIT binary patch delta 89556 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 D=n){? delta 64707 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%0DrUz7P*2p@=O442nG?kQo+m4Xs#%HlVd1vvX2Vy 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 diff --git a/reactos/media/fonts/DejaVuSans-BoldOblique.ttf b/reactos/media/fonts/DejaVuSans-BoldOblique.ttf index c4ee231de88b572dceb4af7cf410d7cc36f5879c..c2786a6f31b13f8e3f13650484a0c0d19217f1d4 100644 GIT binary patch delta 81858 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≶~nO4WIj&)?B!V4oyz0g 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 S!QWyeN1x&iy*&U=B>o4c;L&RU diff --git a/reactos/media/fonts/DejaVuSans-ExtraLight.ttf b/reactos/media/fonts/DejaVuSans-ExtraLight.ttf index df658374c807a714712da2972019ddc1c79b3e87..367c8cbf5d96e2ce493cf699aeefc46b8080c724 100644 GIT binary patch delta 28909 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

-+JzvV-P9V04x!8sbUk5LW^b)())q^ni^HiFPj# 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

Ttx-F=C~D3b!Zg&{+>ljc}!(Vd*D?rNf2B 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 delta 24616 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 W0{8OgYpoWaKzQ$dAs|CMME)0LCzuxi delta 59878 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 diff --git a/reactos/media/fonts/DejaVuSans.ttf b/reactos/media/fonts/DejaVuSans.ttf index 62f2d9b49b14bcd24678826493ccb19fc7be1650..981d8c0d51d23016d55eea3a294375c223b996d6 100644 GIT binary patch delta 94115 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�~POP*Nx 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

Z+LwT%|H7Is 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 delta 1666 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 delta 5306 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 OIOn(ibGGy9+W!IYA6^y! diff --git a/reactos/media/fonts/DejaVuSansCondensed-Oblique.ttf b/reactos/media/fonts/DejaVuSansCondensed-Oblique.ttf index f58a8857f336f16c81c09683e248c7e26933f494..4fd70e3fd627289016b7f7d1e8be1d07c3eebb06 100644 GIT binary patch delta 4907 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 delta 1678 zcmZXUdq`V%6vxkf{B9DjuNz|wthPy=PTAhN)M1FqIWB{=5Rt`$nu8{^tMnrP8h zNMs9TuFk-=M%bei?C9z?VO_a{ZO{#2jy*c?uRUN-ie=g{wt-q#cWyizvL#%8pY!{k z-?`^^&hK}Z*Ik+KT$y;XAPA6}0f3%hY#@BH;nb4=<7mR{Kp+tV3;tpJ4YczIPK*Yt zzp4qN{Vs@dZAcIF-z;CK1@YVx>JNo*BEQbj1mdI{?R!Jvp%G=-_Bq=709t-NuE!%U z?yIc>aiJPOl}<$a0{0{#bs3mgiw;ZSz(}lQw+(Hd3j?^r(fG(p;oKzJO#qJhNFc0t zI42GRdvpWf;htDDG4#QnnlfP7!vIq+$Krad)$$vFRP_e{3&rBm*u+)11kwXN0K#72 zFls&kZ^e;^ZV+JbYK%LYY~*pG^Ez-m$S44GBMShWhz|pvlR)IK4xAO)hGQO%@>8p+ zv#Tl2SWWQ{b|i5X7m^&naI8=&6b~0#N^v2UUO$7g=9~Z3l|~ObaG?}SPpvJpv?*=Z zD@#2}J?eL-Q&UrtWBts3^u~IWJxi&((^D+HwwzmPytcr%S)`4akP$M*?Hl|p!HKD` zv^bADk}!hD#(5MEd;09kB5$lL3j0sDu}y)cStZs1H&>>3luFZsCD)h4x9|8jB=_3) zasE{^J`ex%%|$bY{o+Y&=gnaD^&h2UMe3ih%PcOyhvKKR|BQw>DK=FXb0N%P+mr3Q zCXR{h8DPd|*Tn1jRugmP3m=JB#_}BRV*qRyw)cRK)f>P2*bQs;b~noy6Ngy2EOZLz zvsZdqds5~<-l`yOw1mGyYz0NACzhdH7$+{Uzf%1TaUnFc{zP01vRX^5fKBb%Vr-2| zJwnXk{13!D*u8d>vG;gdY~Dvm5JB;Vi5WV5ODsXLR!VGvLT!xL3bOVEu?;NRDsdj< z`*sq`VD|-c%;geF5Ss}le<6d1GH)fZnb1*U5q5c##AZUj5=&s$s)#L6q&-V)#pJ#w zwn3>6_lIrZ@Yomo?kASP=^M>4pG4K8p4&1oJsTbaa{-U{r_6hSSOP_BCbl5IM4Sh* zPbHS|1(_TR7@$;rixeUC-@qLGN+H>CH29~H8m(-Yty)Q8-s^muPH z(x1IN!)iMGQTP6Mpl=96B%mvhaQExmCJyR@5qDdBxG$uGUr!{4BLP!AjovzR=z7H6 h8`p=A>yhl2GptuOKd<=PoP{IL*Nr)h?n}%y{WlebCzSvI diff --git a/reactos/media/fonts/DejaVuSansMono-Bold.ttf b/reactos/media/fonts/DejaVuSansMono-Bold.ttf index 35a9d46ea201b76d53f3d27a724a7793f688a615..62e05a4e8954d2084fef2cdf40650b9afb1ea9d6 100644 GIT binary patch delta 6856 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 delta 5370 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 diff --git a/reactos/media/fonts/DejaVuSansMono-BoldOblique.ttf b/reactos/media/fonts/DejaVuSansMono-BoldOblique.ttf index 60c4af739222506ad9eefeaa3094ee06f58d41f5..9e87cdba69ee561c7e9f18eda4d6db58c3e0112e 100644 GIT binary patch delta 6071 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 diff --git a/reactos/media/fonts/DejaVuSansMono-Oblique.ttf b/reactos/media/fonts/DejaVuSansMono-Oblique.ttf index dbd3745f3dfba8ae1d9fc770e6cee7d40c6ab9cb..1e90c4a9fc459fb295c0d5d0cbff531202535906 100644 GIT binary patch delta 6558 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 delta 5060 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 diff --git a/reactos/media/fonts/DejaVuSansMono.ttf b/reactos/media/fonts/DejaVuSansMono.ttf index a390ee1ce89416fb662f3d18ca9637c916c1d9b7..81737e4c87765de7eb8bce0cab7684f67afff901 100644 GIT binary patch delta 7626 zcmb7}3tUuX-pBv{=L}~CK^t^HQB+_MZxr`SEh%0oGBQ#kWGO*F!9WR7@r@cVGb$2v z$RRb?%H4H~jD#BGCLt;+DkTybDz_~wDl)fMcMKkw&#@$)^;^ZfqT=bV{y zPE$$6sHQ`s48%k<8V41*J~%)80h+GqA!0A6lOBwEbaB$(vR=bF5^L877e7ANesl0Y zu};T&!J~`4{g!Y1(>|=Lu#QQ}NX&FjTiZb-v_$fMC9TVL{l=uWC(;x`^I4v`BIA$Z z=}SZ-YT;kDB5{o&lhpV}cBv5TSEO%Po|qrA4eM+Y-J4QV5|jH(A(;1HgFPq}!iWr^ zCh@%w)*h)D**T9;@Nul8i5wczS0^Rf`5#OmaZ^X6&(289$sCn$+d-0h0sLK8C1#`~ zbX|S{Yc%cVn7MlHn(W>u{+vV7yauAhBQvv7GVeRqpeAX1E0KCaX4dM=(?`66NqVy% zyKJ|dE$oM!fWS)9d}$2h)x6bM&TGbIlVtI5A(c%m{1@T8s%eq&K5=8>-R}3hr@6oC zzRmqD_fziQ=!M=+@1S?qyXmLsXBeX-ZysNfCpojNMz7V6)4S@YRP0vW%ZtsumAxPK z?(Z$@&F@{?`($ryZ*=d%-iY4t-g!Mg^|bX=_9S+{*!^7hhVFIUsol=q$|QK7aK0@a2Oc*k*0>Y!dDJwW0-tb#X7bAA!qFT=1rO~bVU^> zKdYTe&khaIF0H4g!FV8QDmPS|kFsU1Gxj~E=NhACk)G>~UW>fB))>ENCRbM!Ec$~m z)ZsI<7FmwqgS1fnwAPcR5oy(^_FFyUwqE}`ec^4r+NvK%9@&z|%aW%KXH&_4r(QFx zkG2|=0tj$WYwC^Bk5A=lWA5XJ&}nGQOzfaA#@SA3&ClXdgSE1k@)%_=UGS)`uz%tM zWvgAW!;T?V$F5k#QMJSy2?Le{b4^A1k`HWgHe8aX!|*_oHy<{xOA6#e#uF^6s* z;MHjM*_*vKuCk+cs^(zD4@r9FM&sxd#dU5<3S9T4D8Zkl1VYy=pAOw``BEs`mV0x3 zMdR|tjJ}*wi(vjs>IObs;hJ`kVL89@kBr(u>B{wpOHbm1#`^TJe6XTD{b9x6z6#kZ z3RZoj6r7d0n42oLWnNM&Sy@Wmj;!gJi#4cX^jo7SrE8Yrcx{ayNnEl=Ds^Y9eFxE} z*S^3_#zpItwhpYDhvP5n=HMiRte=P!G3%AhY+jFjSJbXIIUz^%7H=FkS&o&KW8aoU zxISN`H>MToV0*qOnCmJ&E<&qy6=Lg6#>Rwk=R?T4yK^j8SA5**V27dk>w9gTEtg#@ zOB%~Zboj%y5a+YnIR2-lv*@YN z^VJ#98!Oze-V}`Czh4^9jplb9_>8bEJrqAb;Xeb z(XRay9;QeqUIOJWP8PRzCtiwG&{(XROv{y_+O&Nvzr@w%N#pqBc&;~n>&Hu-EgxI0 zO!rut!mUMhz|w4uX_-HN4zK$H5L;tf8NloLu&E~idF#z{19>t&0H$R@Sk{>ugDgH* zl+|I=qF@ZQrUSuz2)3*c*lNvhhw!<(u(_NFF2Y{Tnui&moknwVB)@Ds@#qk4!}yXO zWf$Del$(GXI+1LC!s$6`8WF>KK5D)vhX1AE2GfkCDBfUNFg&cppvH|utEOyI=2CWs z>D^(|iC<06np%fVBN8mZGcZ`A)|#{lmMF!f+=8@fn_0?@2VG3yYnEFPZb9a^6S!uk zp+FTSU#GD&KFr2`q|D?UIvDCpVX{r(2&X~^?|$!o9~*~&;Gp23v1(7X?C79V%W8RQ zuv2i5uzzaK*3Da1#xKly(mGi`Uv^)a9Ilq1d1jtuv+erDUl%wHf@TlpscaH^r&)n@d!8-9Bs{K`a^0rug+kV?>SU76SL>3DkTP;6noi5I}{?7kh zHA%1WEBv#0%WGWaZQwIQSETi_j%;vicXPxulF#tIfht*7bUgzS$H6YFb_bXPB~djX z>#kjtjYW$6xA6}C4*rgOrfOj5irW2phQ>sFiaMa1}o`C^Df8ap9yJtX%BYiPvZKGBlf~nH z=D+|?y}PV)@*ji2QRn0r6v+O5K>?mvA&s(zhu|}3Hk$MEm*nIu$89g6T`z3=ZAZXw_Asr*T?1M$H#4K-S}~S zUfgNwtEaQ7VJhRfl``YAZ3ay)Nk-B8xh>K>8EdxjEJ#|JOgOYZgc=2z?a z1JxtE8JFo{d9;$(mi=vUFL{Zb-yQlI2eDBq9?Trf#7CNc@27{Wv|#A#ci9;Sv2id{ zDwc}L9DJDHA1~Cl=C3ZWnc2a-`w~AToYXSjuk^~DOBFsusy=y|R;|{VM)$C{VS;!L z`C+=*FLWZ+Vw!;48(s_*4eo!3=Bb8;BW{3NSv~O%+imp@eK-c*h;hHero?!vCocTe zDAI(^QcSHzQ~zTFmNa)H`fX$Grcu58o*K6!RP;1A^zy;(DJ$s$){|&T=Ya>$m;c1y4S+K|xwt{<|$y(Js6rIF-7jx>QL zlb)vIo9v74GEH&R2l@w&!BIg1dN9?|->N7oD{5ejVz7dl>g1`oHTb)_e@Ep&Omi0g zR7cjt?Z9$JOxE))S#cb(e?Kp*sJNk3jB#;UEw>b2)*Pc~Sy?g7=5ZH=qsCCJTrpd-op>$Dyv~7>W4ntW|Xv59cz8FS*Dehh~Mco$ndLf z$**>{`s?x1fjUZlQ`uL-*77Febz7W_W)8^8^S{<~`YSP3=@C60LdFEdOh)Yk>aj2@ zUCu)7T1)L<)eq7R`2u={C;ZVdi`)LO(BTK&(iwF4t4_(6q1O-VyoRn=^+>t@wq9r8 z82Uv?gaQZDj<*d+$6l5KvPDO~ih_n3Ee(0w$kN-ElXUB3{8s;?^<<>n;s3sNs))pC z{`$6V>it@bo{c6^Yax25mX%k^!#5+T7(O)#D5`u3oZon;sA1C5yF&j#lkuvGzfb(W zjk-0O11^gR_R?$$G%dU;dR*{4i&LOjO2l&}RuJXlR_n)`d9yk6A0l66E8}Zw`Dd!S zE|!?b{8N;VH6#<~4-#)|1O3D=xPmB<30jCZO#>z1D)Ec)po@5OEEphuserg3m-uD) zybS#n{XO zx8;FKVxtyBfpX#!dw_XKF&H3z9mQTp>~<}{hPJm5n|#1N;!=#It;BESf(GIp$iD+k z?1b;mNHXxwO_=l(??RGYDEwv)K-aq?Krv_|{!tz;VA1!1zHtfNwd0NKi`rp$=d?5DL&h1=bY-AR1(Y5>QE8sR0ATAL&3kXaa-8 z)rNgIw1R8IHPZl!*5m>N)$|kBBCs|LK(B>fy9Xe+wu`uqKmaHN(CVPoV^{T=U@vF@ z$Z-fo5BY#dkP0?|Du9Lz4Jg`>40eG|;!ivP5`0nu;PeSJe9gEKdSe7g2gRTqv;j1J z*ad`wc#sSBfM$RKO|Uf~t_eAtpf|OEtHej3ADNHqe*}gjyFe3w;ixM>z)|Q&p&vz} zqeyfNJ3BTXKtEOrYQbgVW*rCx$)FfOZ|);L4*fXt9M1*i0NM%UIDxZpViSPhiL1E& zC%r%dC;=#Ta*(*i2SkHBPzE}PPZ5{~pr3+%suFY&pSA~KARVBw(=Ff{@fi;g3km>= z;kPGlMc&qAuoocbrv?oU5dd9&ib9|E6Mq%}azGpLS=i4a`Poc>ptDT?McZ6KC_sU> zY)}jk-_{KJh|i(eIS&vC5PPl^zuCV6^`g069}o$0KnbV?9k~8|1YAKhC?)>82Y}PxJBhz)BmNqNE{B3_fJVM?0hoW& zLi{a~ewzpO0W|WR7Hk5D>z@W<0oMKH0QtU0o$r$YV!q!643#(_(GTOme2@vy#19Q% zkod<4fMP$wd4NC|$OW|k_MhPYQy=k_cz~i;p#AItu+yKhiJwaVa{b&%d{qUm68|HC z_!k}VKV5PC2fK)GU~vP9ZoqK};t+OoGZU|YAz&8?#wewekhLHJG>}jSfI91?eh;kRQIXeOaUE**5o77}A!$soof;dlg1hy=AHToCB8 zm&8OAn3PRoaw!Q{9{`(MG70xK68d5i9#No=#FRl2o>))y09a3h&$KQQ)6wvB6q$k8 z8LcE{qRE-iy->%ilf>Pj0N;OcPdN#16!J!}&nAE%UnKFH2KJKh$2xF;L=birjCDvA ziF>h=KSYxVMY2%X?=L1XD;8WPF&pFTYb3(3>o63YgP1v3&qcm@5hUh&fpmZz;RYURz5|8ANSP1P=G#XVx;;~E;i+o5d4j>T?{qb@V zF(~u|cJ)LViCAb$5FfXTM7%4BC(+nbxg?gte<`#CG?Or&gdrgvlNJ(*_5g*Kp+M3; z63MkBQjjF2i^Ov1E08=5MblLzGEi(460L&13cjlbNMu%$$ciG7jXdj{NNhmfXSJY| zL~a;~=le+H!9O3d8_P(%&_QBT6|Vn_p(I}1Lt--$Z;k+kBwmUpQGj_tGZ-ZCatO!; z2zEcF5<0QNV+ zaQ)xd3s7VSlJ6KGu@jCvivbeuf^By!i9O)0QWEc=p+BSWJ`~)KL?0B8_^^Y-0oW=~ zyi!NvBP2I#NmRk_APVBqE^0CXa@D{Wk91KR0*ZkFMQf3?wvR*|40T9a7Xc7lA5Y>C zv_qXF8e##0Keo zr>ekHRUCzn;g|=BV^|y;AkjPyq=G7d({o%45Of^P9EWzo9)tj_PwWHzBu<8c0?6kFiq+u*(ZB0J$#ok+?Vxq=Qn>N#c?Q z6vp9zB$trj5_WK@pF|fD;~^xv0zf242DzXFAX!%vKmt6FM7KTg0HGinq=QY$e?MqC zO>-woDYNalM_J-ercq*~b*>=?5oVp+(L}MuIv;6kbZoQEM^V7!&rDxUl)`6^<7WJ3 z#VT7Qap51Wa}Bu*7wg=P?h}iw^O0jbMVWOzic%-1npaMeF0g|y`QZQOrDUy1TfNHF z?;c+t^W(0P%Oq3gEXj>K&D&;4SM6k3$P)e4RJcHzp_QHG@l+&FkX_`7R6?(tk1mj6 z@B__5>ILeD)sgB))C<**s-x78sTa{fv)?1qyTa7 UQz@?^J580Q3eR2qDW8^q1NV@h_W%F@ delta 6039 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 delta 30509 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 diff --git a/reactos/media/fonts/DejaVuSerif-BoldOblique.ttf b/reactos/media/fonts/DejaVuSerif-BoldOblique.ttf index d5291684622c9e3efc1277f5d59a3f5976719241..1e1bf56fbde5520f8449f595654508d24cd4ae76 100644 GIT binary patch delta 31473 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 a>Z;R7RWxH`d|@`QnxSbTuIGvIko-T_T8WbY delta 29089 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Ⓢxp*bofvX$2b#wxH7W<_hH}Z%D756 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�SO4$FGPljDNCt?Bb1!Qx`v861XIG zNzszx_v*YC^4_xd*1UIZsl(EqOQV;@Ej1@BOo*o<%1i` z9hVPSzI1uY@`KAuKeYRB^oJWiO#d+F!@DcoSBzV+X2tOpPd;k@(bSJNesnI;Juxyd zE^&EcX5#t8E9OM&%5E!TR;I1IxXNx-?^V&O;#MWBN?NsX)xD1cKaTx4_v5=s?n&K~ z1|*G43QdYgib;x3T9LFaDJ3Z_DLbhksW|Ck(v75hNxvsOTdl5kTHSoL@9MzSeOC`& zJ#uyE>WI|~Rxewr>@_;zGVHqPvuX8K8^h} z{nL^S%{O%0ux3N^*h4>tDPn6PpG#>bodHZ9n+Zd2B#^C`|LJyRl5R-`=q ztoLWDKD+eUv&{jU6E>H9?)~}H&oe%MXx`$tW$2cfTefVuwAFEI(AJQx6SmIW8oM=N zYtq(@Thq7ZY%Sb+dh4aFrCaZBeUd7tI;J*FZJpXVH7Ip->eSTO)P&Te)Qzd>sX3{I zsi#vfrIx1NPkpjY-sZTi>9*F}I&bT}ZRobK+oo=d-nL|0;2ZX`9n_rtMEVk#;GqEbY-35I}Y?tk$lT~2pQZ<^jZy>oi+^r7iv)2F6Kr!PrQO5dEGm0p;B zI{i|5Y5M*2C)?%ij@z4VZ@sh|dEOSUI&U%x$dd)D@Y+fQsS*?xWd z-R+MuNJgCu*Nm1K9Wr`k1ZRxS2+N4fSdx*Hu{k3vqcG!K#`TQ*=8W`dCZacBC@oSlU`Pw%|6vvlYEolkbjyBv2l-Q~M0a97`5!*-3^HGNmiuBE$H z?b@&_ZCCcL!d+)}UENi->-SyOO#4i8qfF1t_LYFtzYh2d!teC8&S*x-(W~FE4WEEwd$-0ttGwVUtvpwn_r#;R0 z_?q_w?g`oxvL|#;#Gbf4EB370ld>mcPxhXIJ;(Q)-*aWp%{}+_JlFMeO*zT|zI z_hs%oul4S?9beP{!8*@^Dl>eIsMDnFIRn;^W~ib6AnDex6gOaZ=c^S zKPW#WKQw<`{=xjm2hH6Njy#xg@X;Z^LxG2S9~yjU^r6s0GY`caT5@Q`q2xo?3jzwZ z9JV_==5XlYqle22<-$6J&V?-tI~N8OjxL;97+bi!aD8EV;r_xCg_jCT3!i-D_*Lt# z`hKjf8?(DXyc>N zM>ibJIePx+-DC2xM#p@Q^*A={Sm?3D{RlplvC-a za!(bVI(O>Ysj^cKPgzgbIqi9R=;^Vim!IDMjd|oZ8@{=Arr^x!GdIrMKg-TKp7lN( zcsAs0=-HUF31`=zO*?z=Z1LIaXYZXO=N!(pJQr{-_}rLtk>}#iC7;`JZvVLx=WcvU zz776%^0yn#JDra_f9Cw%@0`Eu{axgDDc_y{?s18IN%N8(C2=KbCFe?RmOQ!OaKZaR z@P&vAaTiuxSa)HI`NHuFS1&xc$SyXz*!kkPi_sUCUo5zI?c%fV8-L&Z`}pq*zJGS9 z`=w!*CSO``Dd|$mrJPGemo8o&e1%*IyK?l0IzOcR@Z@UX)tIaMuipI8@yE~~_y2hJ zn&-9HYa6fK{m0OMEcnNo>+aWkUyr(;dcEZOlb@RZH1nqwKW+Fa^QVV5dfymxBl1T7 zWj8k5$i7j0g-SQUEg4D(eQ;wY_>zaY!z|19>#SZu3zE$o>5+El+Cyv0sI34zTANGD~GQ% z;HwOHl2QIhJKvLyHuFbIa16uGwFqAL&R^6`_(NnAiZXY6*5h*?U(!@@q}u`KTKs04 zghxEw@jr%)!2eh_0}s@X!wbMykqK-y-u)g5JJyoPcn!FP%)~3}b4VmRhS$(X;{lLS zB*un6NRe@8SZnnLbJWa{tPTzu^gk-pku3Y#yVS>a@MY+0FG0ab#lf8&j*#u4W*r

VLXI$-ZjYqi-u3@-3;2MsrBd(*s@6TQ~+sPxgikx1y zr?@^X#`RP$y!PQV3g2iKd$KNG1b=nO0=AgU#jnQ1kqEX3-w26k@#;IYw)hDblJDM& zg;TSKsimov$;af)tMI4qMLY1WfulsxEe7D4g3lG;0jI8_TktpYQ}|!Te@ooTsE<9h zC;nTbl`ESWTR7v7x2{xKK)tFGKW5}F^{}-bI=J z@gbsng)1rJS90*1IjWOdUt86i^^=0}2uDe8wn%#85Gp-DfcIQv%_)g-AVsO0_#d%**ZH0P)e;1fcuKw=nX* zYM%X>f2+R$Y6lSibVi=HpnoshGm3lw@*R+uwFUi|7p<$M^k=8~bRD(t#Pj zUSQ)PuXt z$jijhBZ}wIai~HZJT4mu{E~&IkH~`$myNf&nPY?HrMxOID7aIkMxOj9l@-nIKvChaV$UidjDslAWzi@#LhNPjp zE=+=^cJ3tx99DYppQhk6GTxSzZsZkG*Au580?v(`Eb{U&K$^OLsuzUoel+ronB4WI zktqVV$9MxSlcpXAjl2Rz&PHA(^*!fn4}w|$KCbj9j6EvX!kF`BvXQqVo~*Z#uT8q+ zYbrWT-3H#Q#K=34nJtn?Kkc6*81AjS$-?sgHHf`O>v!ZGa?G@td9&V)at~LIm2J**b0Uy(!F)kSz$(W-dn?oE!8V+g(82)_7rEc~oSTl~OAJN(Rs zzo~JMxSM>%>JJk>H0f>gR)q(0j#Q2H$EtuM9(NNT#q)tNJFf|PM sa5WtHS?Xk9Bh&~$aAwq^wyB94Nou1RTjK%B&UH+_3B-m!^lb8f07_N;E&u=k delta 27818 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

NtP!a{>YBgQ*Oa599dHD}< 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 QAIskKpblk;o-ND&04z9CX8-^I literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/shell32/res/icons/25.ico b/reactos/dll/win32/shell32/res/icons/25.ico index f3477987de40108d7e16d3541ef520a1f0eb6694..572ad0175bb10e8114133f93580cf23cbc6251c3 100644 GIT binary patch literal 17542 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 B5_|vv literal 17542 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 gP}?wE_%ct&N+bz>% diff --git a/reactos/dll/win32/shell32/res/icons/328.ico b/reactos/dll/win32/shell32/res/icons/328.ico index 84ae31d971fc7d2a1d0e1fdd0a702b2061a83e3c..572ad0175bb10e8114133f93580cf23cbc6251c3 100644 GIT binary patch literal 17542 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 B5_|vv literal 17542 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 LiC+jMvfLj5={+c+ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/shell32/shresdef.h b/reactos/dll/win32/shell32/shresdef.h index b166dc409d8..34756e07357 100644 --- a/reactos/dll/win32/shell32/shresdef.h +++ b/reactos/dll/win32/shell32/shresdef.h @@ -133,6 +133,7 @@ #define IDI_SHELL_PROGRAMS_FOLDER2 37 #define IDI_SHELL_PRINTERS_FOLDER 38 #define IDI_SHELL_FONTS_FOLDER 39 +#define IDI_SHELL_TSKBAR_STARTMENU 40 #define IDI_SHELL_CD_MUSIC 41 #define IDI_SHELL_FAVORITES 44 #define IDI_SHELL_LOGOFF 45 @@ -140,6 +141,8 @@ #define IDI_SHELL_LOCKED 48 +#define IDI_SHELL_FIND_IN_FILE 134 + #define IDI_SHELL_CONTROL_PANEL3 137 #define IDI_SHELL_PRINTER2 138 #define IDI_SHELL_INF_FILE 151 From 4da759421631d5ba8e85f81b62c7f4a1fbb6cb32 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 29 Sep 2006 09:08:20 +0000 Subject: [PATCH 368/488] - Change in CONNECT_DATA for drivers so that they get direct pointer to the raw configuration data returned by the device - Spelling fixes - More debug prints added to ease debugging - Added entries for mouse and keyboard drivers (keyboard is currently commented out) - Implemented actual usb mouse driver - contains 1 hack aimed to correct determining the endpoint. Driver fully works except for actually sending data to win32k/HID driver stack svn path=/trunk/; revision=24296 --- .../drivers/usb/nt4compat/usbdriver/compdrv.c | 6 +- .../drivers/usb/nt4compat/usbdriver/devmgr.c | 6 + .../drivers/usb/nt4compat/usbdriver/devmgr.h | 5 +- .../drivers/usb/nt4compat/usbdriver/mouse.c | 365 ++++++++++++++++++ .../drivers/usb/nt4compat/usbdriver/mouse.h | 23 ++ .../drivers/usb/nt4compat/usbdriver/uhci.c | 2 + reactos/drivers/usb/nt4compat/usbdriver/usb.c | 1 - reactos/drivers/usb/nt4compat/usbdriver/usb.h | 9 + .../usb/nt4compat/usbdriver/usbdriver.h | 1 + .../usb/nt4compat/usbdriver/usbdriver.rbuild | 1 + 10 files changed, 416 insertions(+), 3 deletions(-) create mode 100644 reactos/drivers/usb/nt4compat/usbdriver/mouse.c create mode 100644 reactos/drivers/usb/nt4compat/usbdriver/mouse.h diff --git a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c index d978d6a402e..6ca86d1ba4a 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c @@ -370,7 +370,7 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) TRAP(); } - // let's scan the interfacs for those we recognize + // let's scan the interfaces for those we recognize pconfig_desc = (PUSB_CONFIGURATION_DESC) buf; if (pconfig_desc->wTotalLength > 512) { @@ -387,6 +387,9 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) return; } + usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): got %d interfaces\n", + (LONG)pconfig_desc->bNumInterfaces)); + for(i = 0; i < (LONG) pconfig_desc->bNumInterfaces; i++) { for(j = 0, credit = 0, pcand = NULL; j < DEVMGR_MAX_DRIVERS; j++) @@ -407,6 +410,7 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) param.dev_mgr = dev_mgr; param.pdriver = pcand; param.dev_handle = 0; + param.if_desc = pif_desc; pcand->disp_tbl.dev_connect(¶m, usb_make_handle(dev_id, i, 0)); } } diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c index 3e33097417c..d99dbddfe30 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c @@ -158,6 +158,12 @@ dev_mgr_driver_entry_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr) pdrvr[GEN_IF_DRIVER_IDX].driver_init = gendrv_if_driver_init; pdrvr[GEN_IF_DRIVER_IDX].driver_destroy = gendrv_if_driver_destroy; + + pdrvr[MOUSE_DRIVER_IDX].driver_init = mouse_driver_init; + pdrvr[MOUSE_DRIVER_IDX].driver_destroy = mouse_driver_destroy; + + //pdrvr[KEYBOARD_DRIVER_IDX].driver_init = gendrv_if_driver_init; + //pdrvr[KEYBOARD_DRIVER_IDX].driver_destroy = gendrv_if_driver_destroy; } BOOLEAN diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h index 625cb587c4b..91b4c1d4273 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h +++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h @@ -6,6 +6,7 @@ typedef struct _CONNECT_DATA DEV_HANDLE dev_handle; struct _USB_DRIVER *pdriver; struct _USB_DEV_MANAGER *dev_mgr; + PUSB_INTERFACE_DESC if_desc; } CONNECT_DATA, *PCONNECT_DATA; @@ -49,13 +50,15 @@ typedef struct _USB_DRIVER_DESCRIPTION } USB_DRIVER_DESCRIPTION,*PUSB_DRIVER_DESCRIPTION; -#define DEVMGR_MAX_DRIVERS 6 +#define DEVMGR_MAX_DRIVERS 7//8 #define RH_DRIVER_IDX 0 #define HUB_DRIVER_IDX 1 #define UMSS_DRIVER_IDX 2 #define COMP_DRIVER_IDX 3 #define GEN_DRIVER_IDX 4 #define GEN_IF_DRIVER_IDX 5 +#define MOUSE_DRIVER_IDX 6 +#define KEYBOARD_DRIVER_IDX 7//temp disabled typedef struct _USB_DRIVER { diff --git a/reactos/drivers/usb/nt4compat/usbdriver/mouse.c b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c new file mode 100644 index 00000000000..6e79298c6d4 --- /dev/null +++ b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c @@ -0,0 +1,365 @@ +/* + * PROJECT: ReactOS USB Drivers + * COPYRIGHT: GPL - See COPYING in the top level directory + * FILE: mouse.c + * PURPOSE: Generic USB mouse driver + * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + */ + +#include "usbdriver.h" +#include "ntddmou.h" + +BOOLEAN mouse_connect(PCONNECT_DATA dev_mgr, DEV_HANDLE dev_handle); +BOOLEAN mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); +BOOLEAN mouse_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); + +VOID mouse_irq(PURB purb, PVOID pcontext); +VOID mouse_set_cfg_completion(PURB purb, PVOID pcontext); + + +BOOLEAN +mouse_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) +{ + PMOUSE_DRVR_EXTENSION pdrvr_ext; + + if (dev_mgr == NULL || pdriver == NULL) + return FALSE; + + //init driver structure, no PNP table functions + pdriver->driver_desc.flags = USB_DRIVER_FLAG_IF_CAPABLE; + pdriver->driver_desc.vendor_id = 0xffff; // USB Vendor ID + pdriver->driver_desc.product_id = 0xffff; // USB Product ID. + pdriver->driver_desc.release_num = 0x100; // Release Number of Device + + pdriver->driver_desc.config_val = 1; // Configuration Value + pdriver->driver_desc.if_num = 1; // Interface Number + pdriver->driver_desc.if_class = USB_CLASS_HID; // Interface Class + pdriver->driver_desc.if_sub_class = 1; // Interface SubClass + pdriver->driver_desc.if_protocol = 2; // Interface Protocol + + pdriver->driver_desc.driver_name = "USB Mouse driver"; // Driver name for Name Registry + pdriver->driver_desc.dev_class = USB_CLASS_HID; + pdriver->driver_desc.dev_sub_class = 1; // Device Subclass + pdriver->driver_desc.dev_protocol = 2; // Protocol Info. + + pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(MOUSE_DRVR_EXTENSION)); + pdriver->driver_ext_size = sizeof(MOUSE_DRVR_EXTENSION); + + RtlZeroMemory(pdriver->driver_ext, sizeof(MOUSE_DRVR_EXTENSION)); + pdrvr_ext = (PMOUSE_DRVR_EXTENSION) pdriver->driver_ext; + pdrvr_ext->dev_mgr = dev_mgr; + + pdriver->disp_tbl.version = 1; + pdriver->disp_tbl.dev_connect = mouse_connect; + pdriver->disp_tbl.dev_disconnect = mouse_disconnect; + pdriver->disp_tbl.dev_stop = mouse_stop; + pdriver->disp_tbl.dev_reserved = NULL; + + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_driver_init(): mouse driver is initialized\n")); + return TRUE; +} + +BOOLEAN +mouse_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) +{ + //PMOUSE_DRVR_EXTENSION pdrvr_ext; + if (dev_mgr == NULL || pdriver == NULL) + return FALSE; + + //pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext; + //umss_delete_port_device(pdrvr_ext->port_dev_obj); + //pdrvr_ext->port_dev_obj = NULL; + + //ASSERT(IsListEmpty(&pdrvr_ext->dev_list) == TRUE); + usb_free_mem(pdriver->driver_ext); + pdriver->driver_ext = NULL; + pdriver->driver_ext_size = 0; + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_driver_destroy(): mouse driver is destroyed\n")); + return TRUE; +} + +BOOLEAN +mouse_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) +{ + PURB purb; + NTSTATUS status; + PUSB_DEV_MANAGER dev_mgr; + PUSB_DRIVER pdrvr; + PUSB_DEV pdev; + PMOUSE_DRVR_EXTENSION pdev_ext; +// LONG i; + PUSB_ENDPOINT_DESC pendp_desc = NULL; + ULONG MaxPacketSize; + + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_connect(): entering...\n")); + + dev_mgr = param->dev_mgr; + pdrvr = param->pdriver; + pdev_ext = (PMOUSE_DRVR_EXTENSION)pdrvr->driver_ext; + + // Lock USB Device + status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev); + if (status != STATUS_SUCCESS) + { + //usb_free_mem(desc_buf); + usb_dbg_print(DBGLVL_MEDIUM, ("mouse_connect(): unable to query&lock device, status=0x%x\n", status)); + return FALSE; + } + + // Endpoint-finding code + if (param->if_desc) + { + // Get a pointer to the config packet from compdev + PUCHAR Buffer = (PUCHAR)param->if_desc; + ULONG Offset = 0; + BOOLEAN FoundEndpoint = FALSE; + + // Find our the only needed endpoint descriptor + while (Offset < 512) + { + pendp_desc = (PUSB_ENDPOINT_DESC)&Buffer[Offset]; + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_connect(): DescType=0x%x, Attrs=0x%x, Len=%d\n", + pendp_desc->bDescriptorType, pendp_desc->bmAttributes, pendp_desc->bLength)); + + if (pendp_desc->bDescriptorType == USB_DT_ENDPOINT && + pendp_desc->bLength == sizeof(USB_ENDPOINT_DESC)) + { + // Found it + FoundEndpoint = TRUE; + break; + } + + Offset += pendp_desc->bLength; + } + + if (!FoundEndpoint) + return FALSE; + + // FIXME: Check if it's INT endpoint + // (pendp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) + + // endpoint must be IN + if ((pendp_desc->bEndpointAddress & USB_DIR_IN) == 0) + return FALSE; + } + + + // Endpoint descriptor substitution code + { + ULONG if_idx, endp_idx; + PUSB_ENDPOINT pendp; + + //FoundEndpoint = FALSE; + for(if_idx = 0; if_idx < MAX_INTERFACES_PER_CONFIG /*pdev->usb_config->if_count*/; if_idx++) + { + for(endp_idx = 0; endp_idx < MAX_ENDPS_PER_IF /*pdev->usb_config->interf[if_idx].endp_count*/; endp_idx++) + { + pendp = &pdev->usb_config->interf[if_idx].endp[endp_idx]; + + if (pendp->pusb_endp_desc != NULL) + { + //HACKHACK: for some reason this usb driver chooses different and completely wrong + // endpoint. Since I don't have time to research this, I just find the + // endpoint descriptor myself and copy it + memcpy(pendp->pusb_endp_desc, pendp_desc, pendp_desc->bLength); + + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_connect(): [%i][%i] DescType=0x%x, Attrs=0x%x, Len=%d\n",if_idx, endp_idx, + pendp->pusb_endp_desc->bDescriptorType, pendp->pusb_endp_desc->bmAttributes, pendp->pusb_endp_desc->bLength)); + } + } + } + } + + // Unlock USB Device + usb_unlock_dev(pdev); + + // Send URB + purb = usb_alloc_mem(NonPagedPool, sizeof(URB)); + if (purb == NULL) + return FALSE; + RtlZeroMemory(purb, sizeof(URB)); + + MaxPacketSize = pendp_desc->wMaxPacketSize; + if (MaxPacketSize > 8) + MaxPacketSize = 8; + + // Build a URB for our interrupt transfer + UsbBuildInterruptOrBulkTransferRequest(purb, + usb_make_handle((dev_handle >> 16), 0, 0), + (PUCHAR)&pdev_ext->mouse_data, + MaxPacketSize, //use max packet size + mouse_irq, + pdev_ext, + 0); + + // Call USB driver stack + status = usb_submit_urb(pdev_ext->dev_mgr, purb); + if (status != STATUS_PENDING) + { + usb_free_mem(purb); + purb = NULL; + } + + return TRUE; +} + +// pcontext == device extension +VOID +mouse_set_cfg_completion(PURB purb, PVOID pcontext) +{ + PMOUSE_DRVR_EXTENSION pdev_ext = (PMOUSE_DRVR_EXTENSION)pcontext; + DEV_HANDLE endp_handle; + NTSTATUS status; + + if (purb->status != STATUS_SUCCESS) + { + usb_free_mem(purb); + return; + } + + endp_handle = purb->endp_handle; + + //usb_free_mem(purb); + //purb = NULL; + + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_set_cfg_completion() endpoint handle=0x%x\n", endp_handle)); + + // Build a URB for our interrupt transfer + UsbBuildInterruptOrBulkTransferRequest(purb, + endp_handle, + /*usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, + pdev_ext->int_endp_idx),*/ + (PUCHAR)&pdev_ext->mouse_data, + 4, // FIXME: use max packet size! + mouse_irq, + pdev_ext, + 0); + + // Call USB driver stack + status = usb_submit_urb(pdev_ext->dev_mgr, purb); + if (status != STATUS_PENDING) + { + usb_free_mem(purb); + purb = NULL; + } +} + + +VOID +mouse_irq(PURB purb, PVOID pcontext) +{ + MOUSE_INPUT_DATA MouseInputData; + //ULONG InputDataConsumed; + NTSTATUS status; + PMOUSE_DRVR_EXTENSION pdev_ext = (PMOUSE_DRVR_EXTENSION)pcontext; + signed char *data = pdev_ext->mouse_data; + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_irq(): called\n")); + + ASSERT(purb); + + if (purb->status != STATUS_SUCCESS) + { + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_irq(): purb->status 0x%08X\n", purb->status)); + //return; + } + + usb_dbg_print(DBGLVL_MAXIMUM, ("Mouse input: x %d, y %d, w %d, btn: 0x%02x\n", data[1], data[2], data[3], data[0])); + + // Fill mouse input data structure + MouseInputData.Flags = MOUSE_MOVE_RELATIVE; + MouseInputData.LastX = data[1]; + MouseInputData.LastY = data[2]; + + MouseInputData.ButtonFlags = 0; + MouseInputData.ButtonData = 0; + + if ((data[0] & 0x01) && ((pdev_ext->btn_old & 0x01) != (data[0] & 0x01))) + MouseInputData.ButtonFlags |= MOUSE_LEFT_BUTTON_DOWN; + else if (!(data[0] & 0x01) && ((pdev_ext->btn_old & 0x01) != (data[0] & 0x01))) + MouseInputData.ButtonFlags |= MOUSE_LEFT_BUTTON_UP; + + if ((data[0] & 0x02) && ((pdev_ext->btn_old & 0x02) != (data[0] & 0x02))) + MouseInputData.ButtonFlags |= MOUSE_RIGHT_BUTTON_DOWN; + else if (!(data[0] & 0x02) && ((pdev_ext->btn_old & 0x02) != (data[0] & 0x02))) + MouseInputData.ButtonFlags |= MOUSE_RIGHT_BUTTON_UP; + + if ((data[0] & 0x04) && ((pdev_ext->btn_old & 0x04) != (data[0] & 0x04))) + MouseInputData.ButtonFlags |= MOUSE_MIDDLE_BUTTON_DOWN; + else if (!(data[0] & 0x04) && ((pdev_ext->btn_old & 0x04) != (data[0] & 0x04))) + MouseInputData.ButtonFlags |= MOUSE_MIDDLE_BUTTON_UP; + + if ((data[0] & 0x08) && ((pdev_ext->btn_old & 0x08) != (data[0] & 0x08))) + MouseInputData.ButtonFlags |= MOUSE_BUTTON_4_DOWN; + else if (!(data[0] & 0x08) && ((pdev_ext->btn_old & 0x08) != (data[0] & 0x08))) + MouseInputData.ButtonFlags |= MOUSE_BUTTON_4_UP; + + if ((data[0] & 0x10) && ((pdev_ext->btn_old & 0x10) != (data[0] & 0x10))) + MouseInputData.ButtonFlags |= MOUSE_BUTTON_5_DOWN; + else if (!(data[0] & 0x10) && ((pdev_ext->btn_old & 0x10) != (data[0] & 0x10))) + MouseInputData.ButtonFlags |= MOUSE_BUTTON_5_UP; + + if (data[3]) + { + MouseInputData.ButtonFlags |= MOUSE_WHEEL; + MouseInputData.ButtonData = data[3]; + } + + // Commit the input data somewhere... + /*if (UsbPortInterface.MouseConnectData->ClassService) + { + KIRQL OldIrql; + + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + (*(PSERVICE_CALLBACK_ROUTINE)UsbPortInterface.MouseConnectData->ClassService)( + UsbPortInterface.MouseConnectData->ClassDeviceObject, + &MouseInputData, + (&MouseInputData)+1, + &InputDataConsumed); + KeLowerIrql(OldIrql); + }*/ + + // Save old button data + pdev_ext->btn_old = data[0]; + + // resubmit the urb + status = usb_submit_urb(pdev_ext->dev_mgr, purb); +} + +BOOLEAN +mouse_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) +{ + UNREFERENCED_PARAMETER(dev_handle); + UNREFERENCED_PARAMETER(dev_mgr); + return TRUE; +} + +BOOLEAN +mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) +{ + PDEVICE_OBJECT dev_obj; + NTSTATUS status; + PUSB_DEV pdev; + PUSB_DRIVER pdrvr; + + if (dev_mgr == NULL || dev_handle == 0) + return FALSE; + + pdev = NULL; + //special use of the lock dev, simply use this routine to get the dev + status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev); + if (pdev == NULL) + { + return FALSE; + } + if (status == STATUS_SUCCESS) + { + // must be a bug + TRAP(); + usb_unlock_dev(pdev); + } + pdrvr = pdev->dev_driver; + dev_obj = pdev->dev_obj; + pdev = NULL; + + return TRUE;//umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE); +} diff --git a/reactos/drivers/usb/nt4compat/usbdriver/mouse.h b/reactos/drivers/usb/nt4compat/usbdriver/mouse.h new file mode 100644 index 00000000000..6162b9b8b8f --- /dev/null +++ b/reactos/drivers/usb/nt4compat/usbdriver/mouse.h @@ -0,0 +1,23 @@ +#ifndef __MOUSE_H__ +#define __MOUSE_H__ + +typedef struct _MOUSE_DRVR_EXTENSION +{ + //INTERRUPT_DATA_BLOCK idb; + PUSB_INTERFACE_DESC pif_desc; + UCHAR if_idx, out_endp_idx, in_endp_idx, int_endp_idx; + PUSB_ENDPOINT_DESC pout_endp_desc, pin_endp_desc, pint_endp_desc; + + PUSB_DEV_MANAGER dev_mgr; + signed char mouse_data[8]; + UCHAR btn_old; +} MOUSE_DRVR_EXTENSION, *PMOUSE_DRVR_EXTENSION; + + +BOOLEAN +mouse_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver); + +BOOLEAN +mouse_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver); + +#endif diff --git a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c index bf9a559c849..f54c61fac9b 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c @@ -1241,6 +1241,8 @@ uhci_process_pending_endp(PUHCI_DEV uhci) } // if can_submit is STATUS_SUCCESS, the purb is inserted into the schedule + uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_process_pending_endp(): endp_type=0x%x\n", + endp_type(pendp))); switch (endp_type(pendp)) { case USB_ENDPOINT_XFER_BULK: diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usb.c b/reactos/drivers/usb/nt4compat/usbdriver/usb.c index e7eb2edb599..73859497e65 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usb.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/usb.c @@ -781,7 +781,6 @@ LBL_OUT: return status; } - void usb_config_dev_completion(PURB purb, PVOID context) { diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usb.h b/reactos/drivers/usb/nt4compat/usbdriver/usb.h index 8a622ca3d3a..aaa9a76b750 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usb.h +++ b/reactos/drivers/usb/nt4compat/usbdriver/usb.h @@ -955,6 +955,15 @@ ULONG endp_ref, PURB purb ); +void usb_fill_int_urb(PURB urb, + struct _USB_DEV *dev, + ULONG pipe, + PVOID transfer_buffer, + LONG buffer_length, + PURBCOMPLETION complete, + PVOID context, + int interval); + LONG usb_calc_bus_time( LONG low_speed, diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h index a6c26a36927..29c6d6b144b 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h +++ b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h @@ -26,4 +26,5 @@ #include "devmgr.h" #include "hub.h" #include "umss.h" +#include "mouse.h" #include "uhciver.h" diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild index 04796ba9a89..f15c7bcf89c 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild +++ b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild @@ -18,6 +18,7 @@ compdrv.c etd.c gendrv.c + mouse.c usbdriver.rc usbdriver.h From 91b9b125dbd1bf7d3400cdc069e7dadf09da0402 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 29 Sep 2006 16:38:38 +0000 Subject: [PATCH 369/488] - fix the treeview so it displays parent and child devices - display the device icons for each item - other bits and bats I'm too lazy to list - it still load slowly due to multiple calls to SetupDiGetClassDevs. Need to think of a better way of gathering the info. For now though, it works. svn path=/trunk/; revision=24297 --- reactos/base/applications/devmgmt/En.rc | 23 ++++++--- reactos/base/applications/devmgmt/devmgmt.c | 3 ++ .../base/applications/devmgmt/enumdevices.c | 51 ++++++++++--------- reactos/base/applications/devmgmt/mainwnd.c | 7 +++ .../base/applications/devmgmt/manifest.xml | 2 +- reactos/base/applications/devmgmt/misc.c | 17 +++++++ reactos/base/applications/devmgmt/precomp.h | 21 +++----- reactos/base/applications/devmgmt/resource.h | 3 +- 8 files changed, 80 insertions(+), 47 deletions(-) diff --git a/reactos/base/applications/devmgmt/En.rc b/reactos/base/applications/devmgmt/En.rc index aee0a8fd9d7..abb911d0244 100644 --- a/reactos/base/applications/devmgmt/En.rc +++ b/reactos/base/applications/devmgmt/En.rc @@ -2,20 +2,27 @@ IDR_MAINMENU MENU BEGIN POPUP "&File" BEGIN - MENUITEM "E&xit", IDC_EXIT + MENUITEM "E&xit", IDC_EXIT END POPUP "Action" BEGIN - MENUITEM "Print", IDC_PRINT, GRAYED + MENUITEM "Print", IDC_PRINT, GRAYED MENUITEM SEPARATOR - MENUITEM "Properties...", IDC_PROP + MENUITEM "Properties...", IDC_PROP MENUITEM SEPARATOR - MENUITEM "Help", IDC_PROGHELP, GRAYED + MENUITEM "Help", IDC_PROGHELP, GRAYED + END + POPUP "View" + BEGIN + MENUITEM "Devices by type", IDC_STATIC + MENUITEM "Devices by connection", IDC_STATIC, GRAYED + MENUITEM "Resources by type", IDC_STATIC, GRAYED + MENUITEM "Resources by connection", IDC_STATIC, GRAYED END POPUP "Help" BEGIN - MENUITEM "Help", IDC_PROGHELP - MENUITEM "About", IDC_ABOUT + MENUITEM "Help", IDC_PROGHELP + MENUITEM "About", IDC_ABOUT END END @@ -23,9 +30,9 @@ IDR_POPUP MENU BEGIN POPUP "popup" BEGIN - MENUITEM "Properties...", IDC_PROP, GRAYED + MENUITEM "Properties...", IDC_PROP, GRAYED MENUITEM SEPARATOR - MENUITEM "Help", IDC_PROGHELP + MENUITEM "Help", IDC_PROGHELP END END diff --git a/reactos/base/applications/devmgmt/devmgmt.c b/reactos/base/applications/devmgmt/devmgmt.c index afb233b6176..678e4baddad 100644 --- a/reactos/base/applications/devmgmt/devmgmt.c +++ b/reactos/base/applications/devmgmt/devmgmt.c @@ -38,6 +38,9 @@ WinMain(HINSTANCE hThisInstance, return 1; } +// FreeConsole(); +// AllocConsole(); + if (InitMainWindowImpl()) { hMainWnd = CreateMainWindow(lpAppName, diff --git a/reactos/base/applications/devmgmt/enumdevices.c b/reactos/base/applications/devmgmt/enumdevices.c index 099d50b8545..f3cb9700940 100644 --- a/reactos/base/applications/devmgmt/enumdevices.c +++ b/reactos/base/applications/devmgmt/enumdevices.c @@ -31,7 +31,7 @@ InsertIntoTreeView(HWND hTV, tvi.iSelectedImage = DevImage; tvins.item = tvi; - tvins.hInsertAfter = hRoot; + tvins.hParent = hRoot; return TreeView_InsertItem(hTV, &tvins); } @@ -39,23 +39,23 @@ InsertIntoTreeView(HWND hTV, static INT EnumDeviceClasses(INT ClassIndex, - TCHAR *DeviceClassName, - TCHAR *DeviceClassDesc, - BOOL *DevicePresent, + LPTSTR DevClassName, + LPTSTR DevClassDesc, + BOOL *DevPresent, INT *ClassImage) { GUID ClassGuid; HKEY KeyClass; - HDEVINFO hDevInfo; TCHAR ClassName[MAX_CLASS_NAME_LEN]; DWORD RequiredSize = MAX_CLASS_NAME_LEN; UINT Ret; - *DevicePresent = FALSE; + *DevPresent = FALSE; Ret = CM_Enumerate_Classes(ClassIndex, &ClassGuid, 0); + if (Ret != CR_SUCCESS) { /* all classes enumerated */ @@ -73,11 +73,11 @@ EnumDeviceClasses(INT ClassIndex, RequiredSize, &RequiredSize)) { - lstrcpy(DeviceClassName, ClassName); + lstrcpy(DevClassName, ClassName); } else { - *DeviceClassName = _T('\0'); + *DevClassName = _T('\0'); } if (!SetupDiGetClassImageIndex(&ImageListData, @@ -88,13 +88,14 @@ EnumDeviceClasses(INT ClassIndex, *ClassImage = 41; } - /* FIXME: why are we calling this here? */ + /* FIXME: do we need this? hDevInfo = SetupDiGetClassDevs(&ClassGuid, 0, NULL, DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) - return -2; + return 0; + */ KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, MAXIMUM_ALLOWED, @@ -103,14 +104,15 @@ EnumDeviceClasses(INT ClassIndex, 0); if (KeyClass != INVALID_HANDLE_VALUE) { + DWORD dwSize = MAX_CLASS_NAME_LEN; if (RegQueryValue(KeyClass, NULL, - DeviceClassDesc, + DevClassDesc, &dwSize) != ERROR_SUCCESS) { - *DeviceClassDesc = _T('\0'); + *DevClassDesc = _T('\0'); } } else @@ -118,10 +120,10 @@ EnumDeviceClasses(INT ClassIndex, return -3; } - /* FIXME: Can we call this earlier, or see above? */ - SetupDiDestroyDeviceInfoList(hDevInfo); + /* FIXME: see above? + SetupDiDestroyDeviceInfoList(hDevInfo); */ - *DevicePresent = TRUE; + *DevPresent = TRUE; RegCloseKey(KeyClass); @@ -143,16 +145,16 @@ EnumDevices(INT index, *DeviceName = _T('\0'); bRet = SetupDiClassGuidsFromName(DeviceClassName, - NULL, - RequiredSize, - &RequiredSize); + NULL, + RequiredSize, + &RequiredSize); if (RequiredSize == 0) return -2; if (!bRet) { - guids = HeapAlloc(GetProcessHeap(), - 0, + guids = HeapAlloc(GetProcessHeap(), + 0, RequiredSize * sizeof(GUID)); if (guids == NULL) return -1; @@ -170,12 +172,13 @@ EnumDevices(INT index, } } +//TimerInfo(_T("IN")); /* get device info set for our device class */ hDevInfo = SetupDiGetClassDevs(guids, 0, NULL, DIGCF_PRESENT); - +//TimerInfo(_T("OUT")); HeapFree(GetProcessHeap(), 0, guids); if(hDevInfo == INVALID_HANDLE_VALUE) { @@ -322,7 +325,6 @@ InitTreeView(PMAIN_WND_INFO Info) TCHAR ComputerName[MAX_PATH]; DWORD dwSize = MAX_PATH; INT RootImage; - //COLORREF Mask = RGB(255, 0, 128); TreeView_DeleteAllItems(Info->hTreeView); @@ -337,8 +339,10 @@ InitTreeView(PMAIN_WND_INFO Info) hComp, NULL); + DeleteObject(hComp); + TreeView_SetImageList(Info->hTreeView, - &ImageListData.ImageList, + ImageListData.ImageList, TVSIL_NORMAL); if (!GetComputerName(ComputerName, @@ -349,6 +353,7 @@ InitTreeView(PMAIN_WND_INFO Info) RootImage = ImageList_GetImageCount(ImageListData.ImageList) - 1; + /* insert the root item into the tree */ hRoot = InsertIntoTreeView(Info->hTreeView, NULL, ComputerName, diff --git a/reactos/base/applications/devmgmt/mainwnd.c b/reactos/base/applications/devmgmt/mainwnd.c index baf530a0d11..00b89f83523 100644 --- a/reactos/base/applications/devmgmt/mainwnd.c +++ b/reactos/base/applications/devmgmt/mainwnd.c @@ -248,23 +248,30 @@ MainWndCommand(PMAIN_WND_INFO Info, break; case IDC_PROGHELP: + { DisplayString(_T("Help is not yet implemented\n")); SetFocus(Info->hTreeView); + } break; case IDC_EXIT: + { PostMessage(Info->hMainWnd, WM_CLOSE, 0, 0); + } break; case IDC_ABOUT: + { DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), Info->hMainWnd, (DLGPROC)AboutDialogProc); + SetFocus(Info->hTreeView); + } break; } diff --git a/reactos/base/applications/devmgmt/manifest.xml b/reactos/base/applications/devmgmt/manifest.xml index 4df22534fca..2320af6a533 100644 --- a/reactos/base/applications/devmgmt/manifest.xml +++ b/reactos/base/applications/devmgmt/manifest.xml @@ -7,7 +7,7 @@ processorArchitecture="x86" version="1.0.0.0" type="win32"/> -ReactOS Service Manager +ReactOS Device Manager -#include /* GET_X/Y_LPARAM */ +#include #include #include #include @@ -15,15 +15,8 @@ #pragma warning(disable : 4100) #endif -#ifndef SB_SIMPLEID -#define SB_SIMPLEID 0xFF -#endif - -#define NO_ITEM_SELECTED -1 -#define MAX_KEY_LENGTH 256 #define MAX_DEV_LEN 1000 - typedef struct _MAIN_WND_INFO { HWND hMainWnd; @@ -89,14 +82,16 @@ INT GetTextFromEdit(OUT LPTSTR lpString, IN HWND hDlg, IN UINT Res); -VOID GetError(VOID); - -VOID DisplayString(PTCHAR); - HIMAGELIST InitImageList(UINT NumButtons, UINT StartResource, UINT Width, UINT Height); +VOID GetError(VOID); + +VOID DisplayString(PTCHAR); + +VOID TimerInfo(LPTSTR); + #endif /* __DEVMGMT_PRECOMP_H */ diff --git a/reactos/base/applications/devmgmt/resource.h b/reactos/base/applications/devmgmt/resource.h index 2097e147753..283ee63cfa2 100644 --- a/reactos/base/applications/devmgmt/resource.h +++ b/reactos/base/applications/devmgmt/resource.h @@ -1,5 +1,4 @@ -#define IDC_STATIC -1 - +#define IDC_STATIC -1 #define IDI_MAIN_ICON 50 #define IDB_ROOT_IMAGE 51 From db3ddf3123f12ac49b03bc8af720e6e0231a2c96 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 29 Sep 2006 16:56:24 +0000 Subject: [PATCH 370/488] - Add the device imagelist icons to setupapi. - It appears SetupDiGetClassImageListExW will need some work before these are usable though. svn path=/trunk/; revision=24298 --- reactos/dll/win32/setupapi/res/icons/1.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/10.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/105.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/11.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/159.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/161.ico | Bin 0 -> 4286 bytes reactos/dll/win32/setupapi/res/icons/18.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/19.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/2.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/20.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/21.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/22.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/23.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/24.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/25.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/26.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/27.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/28.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/3.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/4.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/40.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/41.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/42.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/43.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/5.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/50.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/500.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/501.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/502.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/51.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/52.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/53.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/54.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/6.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/7.ico | Bin 0 -> 17542 bytes reactos/dll/win32/setupapi/res/icons/8.ico | Bin 0 -> 1078 bytes reactos/dll/win32/setupapi/res/icons/9.ico | Bin 0 -> 1078 bytes .../setupapi/res/icons/Icon_Licence/COPYING | 67 +++++++++ .../setupapi/res/icons/Icon_Licence/Tango.txt | 127 ++++++++++++++++++ .../dll/win32/setupapi/{ => res/lang}/Bg.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/Cs.rc | 76 +++++------ .../dll/win32/setupapi/{ => res/lang}/Da.rc | 70 +++++----- .../dll/win32/setupapi/{ => res/lang}/De.rc | 80 +++++------ .../dll/win32/setupapi/{ => res/lang}/En.rc | 80 +++++------ .../dll/win32/setupapi/{ => res/lang}/Eo.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/Es.rc | 82 +++++------ .../dll/win32/setupapi/{ => res/lang}/Fi.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/Fr.rc | 70 +++++----- .../dll/win32/setupapi/{ => res/lang}/Hu.rc | 0 .../dll/win32/setupapi/{ => res/lang}/It.rc | 70 +++++----- .../dll/win32/setupapi/{ => res/lang}/Ja.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/Ko.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/Nl.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/No.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/Pl.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/Pt.rc | 100 +++++++------- .../dll/win32/setupapi/{ => res/lang}/Ru.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/Sv.rc | 68 +++++----- .../dll/win32/setupapi/{ => res/lang}/Tr.rc | 68 +++++----- reactos/dll/win32/setupapi/resource.h | 55 +++++++- reactos/dll/win32/setupapi/setupapi.rc | 42 +++--- 61 files changed, 953 insertions(+), 714 deletions(-) create mode 100644 reactos/dll/win32/setupapi/res/icons/1.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/10.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/105.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/11.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/159.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/161.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/18.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/19.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/2.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/20.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/21.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/22.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/23.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/24.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/25.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/26.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/27.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/28.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/3.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/4.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/40.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/41.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/42.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/43.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/5.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/50.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/500.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/501.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/502.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/51.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/52.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/53.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/54.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/6.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/7.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/8.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/9.ico create mode 100644 reactos/dll/win32/setupapi/res/icons/Icon_Licence/COPYING create mode 100644 reactos/dll/win32/setupapi/res/icons/Icon_Licence/Tango.txt rename reactos/dll/win32/setupapi/{ => res/lang}/Bg.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Cs.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Da.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/De.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/En.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Eo.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Es.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Fi.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Fr.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Hu.rc (100%) rename reactos/dll/win32/setupapi/{ => res/lang}/It.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Ja.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Ko.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Nl.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/No.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Pl.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Pt.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Ru.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Sv.rc (97%) rename reactos/dll/win32/setupapi/{ => res/lang}/Tr.rc (97%) diff --git a/reactos/dll/win32/setupapi/res/icons/1.ico b/reactos/dll/win32/setupapi/res/icons/1.ico new file mode 100644 index 0000000000000000000000000000000000000000..85403e307ea82a1158e766409b8063c549daa683 GIT binary patch literal 17542 zcmeI32V7N0zQ=DiZg#V~u4WToih0JE#F%J|#>C#EMnR;BfQ2f}3W6f-7Vf2Y0eg#R zV(c|)?AR+!iin7U8eBZ~1(_&N=6vGxPt=%$YOu|Bo`+ zE3yW%cI{+Ho6DAdB9je}$z;u&>(3j@WY=)*op*HS(XY#7(>uy!jd7jt_iiAQHR~;t zwZb#VLgoVaI{zv0oavuZMzVkNFHr}tpdDWY4Zv&Q&uHtvfWLCe=ipD^kAUy{1K?-= zr`n&(W?RvNWq$|%0B?b}!MmU-c;5uR#=r4BeD53JZ^(o7{Z>L&2Iv>h3)(R zd<0qoe*HcNtxe!-{2SlH_wqCREa$;_u@-Kh{|+sjr?K5!k6ix8fNg36c*y9`ph1H! zO`0?r*!-jB4xfJdsavyV&FmUAYSbUUbpf6D9>DkVGyE)TX$Ck?*3l4UaUc7=`qm$i zC--HHafk8JF0?>Rb+xZ~pPTIDdp z@s5?Pb+!4B!4EC0hg|H_ug|j2+q4-Eo!#*~YiX;`i}U2Xxs1lJpZnFzYT*9DeVlFQ zcIJBGI_JLeRoCuaqb;n4-0>LWc{eOvPLXlZ6cHCi2`Nc5Yu;>HxcGZYpEaFg663`6 zh}cM)8XELyl&h0=u$9GcpSSsZJo4!b+UxV=ytxc6i#70j|1uh0Lp}`wzi-@ExsJFW zw?{o6bQ$fYjh~iC3zuZj)}7la`$R64ojXfs&X&>1l2cT0vWSXLmx%LXoF6!Rh}LXe zPc!Dt5?XDC4ZYjFSNC+}#~Qd#ao$`8m&IjrUuy7z8l*li)jjuje)qn>pR1k2usicI z7SP6DHqoAg`{ zu=^V$`?)Ns554|^_0Rq8PsoSI$|iu{E$*MK8#Zj%1@%@L6&LeJvWM$4J~{Cz;&9Cv z>HZ&AE+gN7Ne|2hn`a?U9-F@6yaAWNWpSB*XB%F^{sze7uYkWbn01LUQ}m%$ty($a z9V~NpbJ4~oB~ZpsKTt$WRGo19sG}pu*4|D#(0tIIx88Zn9QpD%B=sGxdoGL1{0nU7 ze!zA4JiPAf>)V*Iv$Jc`w{PF39XodX5H`1L(W1o{7}Gm6ZQ8W+`|rQsyIZdwi9@U{ zi!5!d?uRNBBv2q#$U&GO1gV6DrNvz{bF(AuG3LJc=9~TSt?2po+i!P%_uY3pAipn= ze@lEfKK$~_FPrx0(W8l#l@*Ue{9UWlet&=e52j3+vOXjvuK0ZDIZ*TAWo}Ql79v&Xm?(Xi@Zf4G7MANMEia?eb2>`SouQJmI!=|9lHkl~ zDwZfMp_8Sj=;Y~BR0Il77gJ%0j)IbtRB#Fu7g0Vqak9`rUQq$*$fw*w=7dPI@^WbW zgbBCJ%*_h;(Zmq|PJ z?bfk(H*J^LgJZC5&o0`QsblNzoh0$g?j0ntW!H9+*o<*lV$+VT#2m+WWyR{1WNl-; zyf*to!@@3}|Mddp6&F&@$$T9}`IKFBLI>(2t1wST0a9?hAeWBk>o}I5L&r|!h;g3B zmwAg8(*9$I=}2A{9m&;kIQKXm&e3rw=NKKz)^RZVC>_kwaUkmm9XPII|MA0gEH9hZ zZdgy&*4B$_vmbrC(T;rwAh=2M;ERC>%#wSO}t#ni4Z)2uZ}^IM&iqFw<_RXb*0OoPraycdaH6r|D!_3C$fjg2Dz2ps?@0BRO;~H9TI9Bt6@K*k${E> zJ&~|iA_~V*uw8)s=Amt+{*;UNdcpVKSDTxg``2c_CPK5WsQ4tEI$KJM#`;iDuU-_~ zzrTSH9EU&?6Dk3HtWoGR(kkhELaUKZ*841->TkcLj7h#Ey%Ri6&6+)1J7mZZk6P`I z)GRttkWZ&8%IK$%APVZBdM^pOtr9cMxGE*h+Tacb$q>@&lQ?IoqoprUTqDK!} zrdAo=Z6145rls75{SLL+uZ~bBXXob7ne*ppU3@Hs^z2DWYip9DZG+KYrohI4-o177 z=|hu^V2uWydaVYX&@1WWRMN?5jcwYoBdtqMHP~N#ri5bR;wo)yY|Lx3AKzK|(c{M+ zox4~;zs#RQL0!6#(#D1qMuej8PKFJW(6{`ckKtnpe;oTu8ujTDI-&UqttM^C`a(K% zpe;)liE)<4*b;mr)f&xB*x$1@`!QGW+kf!D{qjo}D0Ag<3hCOFltYJ-0*KVsmgIUZ zp?KFOp`Isn>qZmM&zOk}+Me;%BWV;mjkF4#CR!z(pz9fIcoty7-Po6*0E?S0W^=(GalL` zp3%L6*w|RJ4I4MyzI636eiK1BSw%CsD=+GB~Y*)Xkk5aPN9kQ z$U(4`6^%t78U6LwiFeXV!bl_Qm2^s4746#5QOp^ndB=rIzY^xDJXhuQ zz%%F3@$vE9SFc%p>+YSY80uQoJhs#$dNidtb=vw^~kw>^lcOdJ(KZ{ zd!Wu;(U092ypQfius(^JbgI7jTG%gXxOn*zVP5^PHrx5PgoK1Ie_Xn>^6HIiRCwkT zMfB)SY8Mv@cXk#Sbg&knWT1)LN5NW*^n{^peDOVVh274mPYDJ*~q@<)4i!w59U%Pcf*dN)eCu!W>Ne#l?+(_-}O5vzE zC8O74&;mU{7_&Su<~X)#LyoOm>rxyKm-ylf8lfk;PjBM6_|e>K%EkQs4AxCptCiPf zKYssndV2bUTemBP{n6j{rN}X3DALD=BB6t|NP5)JBY-B>qelCvB%n!!Hew8Vpo{ec z<30DmH_Q?BKkT#5bbS6f*&7ktzn}Q_&R@6yYnL1(MEolle%NPbVUEL z{q$48&{nM|!EBIN7xDYcYmp+XH?e*`Tp#<$6rU@lxPb#G2J7w^tiMHy^|#Oi zO{_<>jiiaSK$8Y3BlPGsg`=%h(4=BLk|yX;K#u@=rs91ckN15z-scp{A!6M&cm6!F zHqOKRA3lI>^|3!SHTBB18`r4>-|VEp<`m=WOL6}G6bD~IoSz@X;+(HVLsK-gF;UPJ z#hO5*UKeZO_R&b1(Dx)w20fA{?swcizz6U8^bwA_wJFxU#bu}IcuqFKm$R}y_NS$# zo&62puhSK0Db>bW*qa;}NJ;REB*HI}z`!>W4~%s^p~+MaG>Nv6v~c^d9uST;QlWh$ zP2QLjEf_b3_8i_%bLP#ZV)!x+9XU)Be0}HC%l`EA0v>O94m}&|&^Xj{T4*SxhJ*;F z1qV|KNDc}jgDz-$9$nl<5qhNdQA1NW@WxzXsUnoJ;Va-V=nVWJd-m<+{vT5>`_s}6 zojYGaWf#k7(ZunTfc`NnJe+2#R5U}Wr0MXjrOV}%9v1ebF6gUESG-X_tf{>s(f@d^ zv@SK7cET_7ea0f;f7-TV`$O0tR4@C}(|;+2Z|dBy=V?`>hE!-z-P+uYBCzI*z}O(t zK?6yHwXop30i?lt(g5ai8a-;v=NV1EZ%Ko>z6N8m8s8N)`nek8s5s`7!FnMCW9rTo z%P0rq{t@_ED&WugdGn@wcz?&$$9|0e%Zg4F)5R;7sQBz@Dk#jOLbPQe^3zd3h42j( z79(X&6$%PCEh&Pp?c`(F*9L_Dt+bd5PBXX$cw9Vz`vs?pC=bsI;CsqNz5@8se#KmP z)tc3J;D>askNqhrDdU%~Sbq2F^=owf*3BBZQF)Ujo^{XD*Kg4En{{&y_vpBe^g5NJ zFT>w@2jkCY^|3!DCZ-|A&Xi9ea_ar&qi5uYn%3Qix$WQ{nzA(Oqz=`QRi(x+Ii$#9!Yrl>o8gxh4jWHMxf z4D~4@gW~+3l}hE-klxkX^}D7YpkAJ;U%v48I&Yq64tfK_KCQ+$G5J&0vgZF^`WwgI zUj-cZ<9!qygXNUZ`8xmpOh3j8{`M-WjbpWM0*;?@47fRH0eDXV!^dbDvA>Ap!+%3r z4PLN3$$l=EW8A!Ngya67fHv>F_g+85K}WW0*Uq1%kFd(3;_qgJh3+YT@rv>vhCs}3WF-*fjGtsOIA>|MsqbF|ie zgyX#-Hda^q4d}nI#m6m1;2DmYvmMO=$NOvbFPYf)2i)Hfa9y|P-m|;Hez@b^h}ft{ z9BbLWYbPB%a)^#)AE#qES=jq=kai&E_XGAE#3sf+!v2f9ojP|?<5{kc&j7c}TPTD3 zNqzMH5%;t9rmwyB+Go~7ZK`L_pF=Cwt)^A$*NW75F9#n>=RYj}iBe~!(-0d=e&ss@ zj=gi=;5y(wQJ?aqcISOhA7Ss&8C8V(A@5`0Jqo;MrzWKR3v#vUA@)F&;Ms40)CSxq zpQjD}jQe@--23QjeXt*)81;I4N^szP1>zSq5ioU1wXOZoD(r_U#vTCPd%*j+SUb1l z-=Uq~&l>elo;=wuARyot$I{2~S_5l$_+`io>p=LI$Q^5Q_{qo_>v1Re7e>PGGaNoS z2dvG9!EXZpF~JAUaZo}$oh;yIL`;qlm!^SOOGx1QEyP;vOzoIDb?VJrtmQ9Vxh&wh z^{uIxS-Hr6R^~isSEC zukJv+da#AX%^J$Te+gx>Pe<~N*AxSm;=dgGUA|@&t^RpE?K^si_8vV*dyg;&us&w? z)1E`jKFUO_Jrl9^OdJ=&--0^1Z(2U)vX!hi7i$d7hs`Mpe!gf1J{$p#V+7riN<6+6 zi)*p)sXnHM;W!39&jsF|h&djieC#Pe8&sN>uT&{7T|oWv+9#?@XAygn;%kOjsXm4% z#Sf)8scC$aW1~_`l;fdltQRxLlN@`VPH!Dd;lDu@j*;O#BAV;km5Cln3O(N!*+^z zo8HbK_~N%?+|0w;JahkE9zQldReoaPl7gZlD#N=x&Dx5>;8PCO6N0!N6NGVP0_t4E zB@m|&u@}T&ycpE6H^VU(ecVN|b1Ho2d$w(+e5~bn?A}E#E-p(<%g35DJr{c+cuYyP zMO+l)8pnV*W)g<+EfnJ$+Y^E@ZVLLe7wUpz4I<8fRK!wH&m2n`t;d67MIadd_DJ~FMa%%@ zNbv$^_`;Mxcf+P)q3-ehAuE~C|J*WAZ9B*3(M z_yxT7?Axd1_~JZwSBhjmw;ti=#2)AG^&!*}f5iTL0ZTI}y9$`^ikeE&3zl*o~ z<@heLEfcUGz!`mUDEwVkAAd|rjK91OiN9GHOBUZo`NK`iNBx^`+Pt~)GJHcTHQ^ME za@emP&3<)Y?0Xh|bl4>MoQ3}!_bcIRW@AzEt>yrv>T!!q2iR zmi_id^~H9vZ#xctP2OXcxhIq0ce;hWg6&P~AHJ+l7A;y-$?=VYTenam;(ODu&xlFE zey3!NKgk#qlaMBHig7U!X###rz<3dd>v4RJ`c52XM~QeZ67h~EAWg$P>~rSWXGCN~ zCFWS4n3m7+Irum4uy3#OPF2kycEs@`iCZ`p+(s&>M5^N^(#PDQo6vRn+Ev0nMlIs~ zJQsgz9+;M%wgCO$0s11<2ecW*#bGWS6GQlZ5`1?Aza7D6NATIPZ;{}yBkbkmaw#w{ z@B!vIGixgQ|LZlK9|8aFdWGEw3iwk#fNO?n#PInpxM+S)%4D)XN#(Mif)@wvfaIre zc^xMvfB)j`^9uCATg4tMu}*A`l-EtX=I82ZjNj|Kc75W#!n1z?ypC)++RI~>>u9%y zE^e-y-91L{$NutFuI{c2t!%9Q@Ox{}4CTCD-@3;A>=Su!n4`VVAPci;epCD_5>t}y ztX{wN(RO_AXU?5{&p$BWhSwPH3QKEC4esS;{tz^*PZ_w6eIL!7T%9wPEdB984(3NY zvF~^7&+ElHc*~A$B7V6Cb2|Is4*PL0uXlM5eG}x*b^1hI)Nsx{?QN`EOV@AQa49)G z^>WGSjNQZvuA9L|^b zW%E8*5i`R6K@l(FI1$!vdH9WE>qoJ#I0s{XHr6{?1-Y2}V;?fsmb_n>_x^AmoY%AR zj~Q-@Ic1yYCd%H*uxGrs{5fyMpuVIu`&OVb?}t5~i07I27ib0}=4UYg`&kEIAM1Ap z_&I4`dR_Sk_3w#wP!HlX7=-liMWM`q-dLygCOI>(4=EVf!aPs@nqijMfB78+B5(g* zU9k7ED@|tlbj8}S8}^lU!+uiiGi6{0^IZ9l7)okKTR{lw!MA58ti!&>e!_3CkFcYF zulX^(It!jB|43&?(l|MgX4Ej!jI<*)+I$M?z`IjB9i7`_|5$tMjr$5~EgjF3f3$}a zMU5Usk!~X>(sejRxS%|gsc^8N@u(+PegAUr@CDW^IynFDe^^W#wrr}kfAW2?W85j$ z$BkmVT`Ahrg`z#2F>gkB?jtDzWy(=^erVg#&@ig)r-J9PKgn+lCHneM`~)wG8}CW6 zU(h0PK>z z`oc*0@;t0DXbz-#SnmcnG5Pzw>JQnz@Vo@izSO(}&%eyPg1_@GJa0h1ewq1!c$UB6 z1uyX3m)j{Px2XQwErYAZ!mtIeJj(kww?|j$PD-$n3-7bGqd26n2q1& zfVo(M^SxZA>GQL(zE8uNJqhd7WcW`~82EIi!Pk@u(%|Ds2em!Vd8A^UoeZBtJf4ri zx;Pf=U|tKyV=c_<;kusZJdBx!HG2|lPk2bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/105.ico b/reactos/dll/win32/setupapi/res/icons/105.ico new file mode 100644 index 0000000000000000000000000000000000000000..c8598c82dbc883f4718a0b8b67408d429fa4b0c4 GIT binary patch literal 17542 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 literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/11.ico b/reactos/dll/win32/setupapi/res/icons/11.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/159.ico b/reactos/dll/win32/setupapi/res/icons/159.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/161.ico b/reactos/dll/win32/setupapi/res/icons/161.ico new file mode 100644 index 0000000000000000000000000000000000000000..2f4358ac9f8119675d81d3c1ee847b2507efdff7 GIT binary patch literal 4286 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 Jv@tL)<8P;ZzGDCY literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/2.ico b/reactos/dll/win32/setupapi/res/icons/2.ico new file mode 100644 index 0000000000000000000000000000000000000000..54600cee5ed533ace91a27b7bb0104f9b2b5d96d GIT binary patch literal 17542 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 literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/20.ico b/reactos/dll/win32/setupapi/res/icons/20.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/21.ico b/reactos/dll/win32/setupapi/res/icons/21.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/22.ico b/reactos/dll/win32/setupapi/res/icons/22.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/23.ico b/reactos/dll/win32/setupapi/res/icons/23.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/24.ico b/reactos/dll/win32/setupapi/res/icons/24.ico new file mode 100644 index 0000000000000000000000000000000000000000..500a00ea5e8ab86a430acce9adb2ffb84d825baf GIT binary patch literal 17542 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 X*Tk4#m=g0wj}p^(a}~i2qu>7n8}lZv literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/25.ico b/reactos/dll/win32/setupapi/res/icons/25.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/26.ico b/reactos/dll/win32/setupapi/res/icons/26.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/27.ico b/reactos/dll/win32/setupapi/res/icons/27.ico new file mode 100644 index 0000000000000000000000000000000000000000..949f6b537e7eb63ccfe3dabe5c0cc0dfc2392b87 GIT binary patch literal 17542 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 TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/3.ico b/reactos/dll/win32/setupapi/res/icons/3.ico new file mode 100644 index 0000000000000000000000000000000000000000..ac5272ddc7150f3cf5ccb81fa466136d646ed077 GIT binary patch literal 17542 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 literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/41.ico b/reactos/dll/win32/setupapi/res/icons/41.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/42.ico b/reactos/dll/win32/setupapi/res/icons/42.ico new file mode 100644 index 0000000000000000000000000000000000000000..2636e9dac6c79da082d6b44a31a213f3945c0e72 GIT binary patch literal 17542 zcmeHPd3aStmamWiVNt>o5=;XLi^viQAX|tA2p}XZCP)G(Hk&l4C^k(Tlnz09K6@00 zX`N4W217OmL2RaF(LroOgVGJzx0k&4lDvdKSOpgpB2e@D)lI#;ge)(CNdIB@&R6%| zS9Q**Q|F#K=hV3f;Ue6GudhJsD?acLVu}#L11;~Dy9x0%t^)$9e(x_tq^A(x-p2hO z+X-2UG1}MaM0LSq!7UOFF#R@6@iNF>7bpUh$bi0ENI%@@B@I)0Gc zSRn>a5MtouI|sx!cp`9PWrQ#2w{zqH&oJj_W(e{ASs}K`mWB7v39%{y^jm8lK)<69 zTMNdGJ9=Z)Dw|xhrcD0scV+U$7fa;}FOfLhTIB5678xFHmNRFXWms6DoI15YPM%yKLqbe){CJamHd)8&{k8IaecaX-*J7-nj-1$o-QAIEJxaGHd$I)s-Uc_OrAV> zQbBonxjc31lstXpO+UdT#y$pUc}m2q^oP195*gU zcI>$Q24ww6ZTeL*cq<~}Xyv3yX4$G$s@%KR(jX5(K|yl#=+O=Gkd{^<+qO-U{rcs| zAwxd<3AF#OF4|Qx@a)v-e|}iI)++D4Hv{};$&!*1#eeZ&3efs2pMmpqNbPEsn+;fj4XnoLfC@U+M4?K`1y}h$wi_)RXiQfp3 zd~Xxz!yd%X9y;_d*PnT&M6Kc4wRw1#ixp@&xVpOHy>hMbev*exo6KrVSeRM%>b1KP z_U47A(5~w1;^LB!@!WGcH>f`z9_cbY-D>B7dIu&I6c!fRc`%#HWRD&h>V2Cw?F4LX zLOJlYX$F1D;E_IkcHdaD#wOj|(qR8{p^HU|htyQsXoG%wdb-_CMMoE?zEM#Y*}eM* zocrA7(AHzX!@&8z4kEdY{F;G;C7}D z=Ft;&xiU7^hIwVk;NUFmZ`K+-gob9z&Yd&l^5quDfOdA9zcaXtZUaD z*H^AIL+8wRCwI`!&TkH`=8i$EvKn*#4!ryb*w|b=w>i!gm zogxHuS3sV^71wsK;W+_)IuWj-F9H}sFqD2h0UNPY5bGi(A;r}ITU#I}bdvIFZv(Ce zOUFOvDHwSB0(72Yyc=$A`CGF^h_|_~fK*d}V>tFbu$qOj`Ar0l;n+3jg*YnTe*3ii z_SDD+%Q42-7nca}pVx*CwIVLNTx0C~`ST@# zcr*_7VPB3B;>9JyxTB7b8a_T?CktpXPzqKkw$BzNpMrQ%D*nah_iSD<4~{>DD+i*Ysl zFW^I-<3FyA9cw|%YQ(BfJn@7iFm~lL{>DD+>p)xcfO))>C&Z_6*RFCE^UjztLlPMO z@)>_)pSs5K8SsV(@$c7yg3Pj_;tYJI@d|j&XZ($Q>Kkw1ctVHy0*VG4N7 zXP|wep|Mpw1PZaKa>9f{6+bd=;x(Uvc3@-Ut9VEeV$aP#|G88Wcn#Vq&Wx?%VHotI za^OG{@-ClY{2Qb_%-Qi(JnYB5i+7Ch(*CB5t>OWh%jg3Jtn#jJJQl6SUo13{kb<{@ zU~6l@#sigzdX0w0Q-CRGs%SZ!yU_nRTW(U zcQP;B99;BonLDgu*Xoi5cx_+BZ%?%S093=f1^0vYKmc1mKo3BNy7=ZZ{s!;@^ac0> zMgfBEBEVjXM*wVx11LwzwNo8y;fCkT`NIl`Awv9N8{+s&^c!4UwjpMSZxC9wibu}q z&H-s^FnpIdxKgig7orX4&;$I}$VKD64W3gs`v|ddlc(qIt8?ZQ$R$f`^695-$S>HC zgD*kcQ6d*CC_x^+82&@CoIAHzMnx6LIdh8S^D`H1&2 zWQPvBe!xB%2OfO@_fTgX02W!fb-fTLSi{3})wnio(x6x^liPO|FZ0?S9vO1*V4gE< zLtd~w_8-ySfp zlXkCO+0xhdF#N=Xqt5WoKG2~~$f19?aG?dcc*aANL#q7zb8C&WnTF<&ot-VCqoWmM zWo0?7OU1?KkXKAsG`a4hM&;owBMCW&geLl_2`>*CbnwT>$Rhh1goS0Rye-$Dp>^Q7 zTWDw~1)*TdlqvQzug2bo-~P7xz3bmU2YUZkgwBZ{J1cvKe(jKV`ufQy3#FeQ-~CjT z|JuLb;?x|xyu9rEdwYA=I5Vqn4kptX*}lDDvw3zpc5E)zJrT0s+RuS6yPh}p47PMd z-@f~=aKB>ij&qnW!B~TmTIYPVb!p|wm3IDDuU>u2nOp5SFcw_8l<|~7XULE|*znH~ z-z3C0#%BY+yJ37qR8&6BmvZg6Km5>GgU04?^ypFf<(FSNWn0tIPC?HN+4Br9FfbQB zNdjb_M1R3)nb+Dv*&yT;S55c{V@)a@4u1Uf+a-!UpG%l$2!GpXB7^I?pWi9{0DuomBRXxVv`E zgfEm0eNFftvg2OcY}xCv;D4Hz*Y59^Ei=y5NQZl}6tixuU_XZTMFu(!|SiVZs&i~rcL%U zTiRAff8)Rb<}s@Mgup=V`3V=nbGtjix5fco9M`4Gt}826*wncqY4+=vf%6>WjF)S{ zH6T#_F)=ZA{@1TxU&CK=oWsKpSKDU#)!n-N?-kHmrs>|v7Hj&&lqsn<>91>zj>Q8QPzOa`5bSC;8U6fcwFY9Y478?6Wq+6UH9j zvu8SLX^b;w$M<2`vSoJud0l&dApgULY2PGG#W)@wyCM6y$2Gl{Xt4%+#*hEU^^lP2 zy=KFPe04Ue`De@gu9iQq9sLdZd|S6x`w84zMvgpA*_&E|XGffnPak*pWVHr7+oc|L z@18F6@{IFcJ%^byXWIFnHEUK4zptdER1O$W?VHb>X~BAa0DBoX$&pq|T|-WBfq`FE zGPc$4L3DIpjq~Y=6DQjF=QZW8Ve{tdwPSocV#G1}$H!WV-`aSwuXw|!y~0`(UH|6c zktQ=Ujamnu^V9yXTenUD?Z385R;vwujj?X5JzyQ4yE|i(_aCZFrzP*Xw~rW+a!uDw zaUE8!%)O;fK}y2=#VB) zoG{M#xdx8)7Mw?ZelcQF!*0<>V;yAc*2$24!u@s8Xz6EIgIE0h5B)fAUbP)xyg0{R zCsBJ2(a}5$(|&j%av~}8kCR%O&-(Bq&TP*ZXUP(aJ;rI_o)y6&+!~<@a%vApIlkEu*5FgxpTAa{Oh`z6)URahp;eI{y%-3RZ%JAQuqeptBBj58=Ja$g6L zhf3UcxA|%Ueddf_15^MmfcN(?woMbp-!(h>3y-&-Z~H}tzsS&89WZJW1qvGZhuR?| zZNz%i7O_PIN($SywOX8ZtLJEKRlnnaU-j25oO@M`pj(AE7~g90xo$y6@?N*Nk+Hb1 zYF*f-pg7a9wSgVp>lOq%@m{we*qisd1>s=c>lO^G=e=%utsqvnDCp#~6y2h@llL|h zb~?5!^5ng4ul6?XS@6l{{A;{rL4-FT0HEu%7PiApt-shikcYnw9P~NJRc8R%?G5k+ zuol7-z;BJ*nt{I+#uBG50Cg*>=H_9v69JQ|THcQW@b_Niqaiv%L_8tHE69UxgY<6) z*1=Z{pH-Wdi%ZNmqep*?`pGnW^T}_`G8NE2<2NB;VL7Nf$yG38Mjq+_@)gXQWkPLA z0cupt_-@pKS`^l7#xT!cW3R=t3-}HTx%o8vnW6TPPi zN&d;N&MWJjzOH|8tas3L4y{S7B+95_&pya4m?`^o#+I&dplf$r4Stv6IooS2615i;$0P2y(G z=f3;yQ}wC(d`r{d_kq)==OdncmAnVnho8@3B~JVM@4)wlX>#XIa}65&7L9bYtauii zoNU9HRu1Y^b|Rk_Thb721Aq89H@DczkdRd5Uo%v0koiI8XoG`;kz<%+KQ}EeKc#a0 z)GJrl804(N{Tst?(1z=+Oh;{yeB;6&uUCtz6VNz55gXXMndG!d2IA;HO`!R_iJ!Pd*O4VGi1= zzOnT4^TU}yu{tB0H0d8uh?l7|UFyQo*fSws&Fs?Uzpe)aWTI}|_@O;@a5y;@(R}B7}hXN9zAN7$B&!w{-yKVIPm_;4;b5^-K-C{eh%6G zsZXEHS08#P6Se1AsJ+WV4So*3eR~~piFjJ~Yi^4o^WFe%06ak3R$jWy5Y{BS-KD>fJ*u7Rr~^aL{616#oQ@R&1A8ShMA z&=?DuTx!)SwhY&Oof*@NK6gak&7fPaU7#~1V2bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/5.ico b/reactos/dll/win32/setupapi/res/icons/5.ico new file mode 100644 index 0000000000000000000000000000000000000000..f1afc649def5a4e75f1672112ca68e0bc44b5f4a GIT binary patch literal 17542 zcmeHOd2m+M6~A8sC=C`QQb8I`h*Hr(0$~gASR7G{3bMO^Y=I#9voW{h8K^M0t$IMrLOl0B`U|07-GJ+W>w#|oX+Sz~E0F2)@QnE;K-wR;5$Fx@ z8B%!Dz?ix0QTGc`cm)hCmSUFc)d*f+j&KM__SBIt1Kzy)jnfJLot2m ze%J8+@IP%4v$;B~Ka%g>ygq!tYxCML-))P%Pa2`W9~7rJ+jOEMu@(x zO+uYS=E3a&%6qpQ*c$%(O|8w!w?{vH?l6AVH0j>BT1dNYs#bdAu1(TscY~zuv$3LV z@12|UnfBf+*! z!qT0gSIjRXD6 zc;q}XLr%VbS|-hVM17I8sVbnmqxuJ}Dv{BT&sH5{9-XN)2XtU%q4JS-Q+Ipya}K&3 z`16~~+BS;()xTW{+NQOW`!9PyL=5pEmi!tl2@c1>AIH6p!s&CA3q4;d(gD8D@i(!H zlHfmc@A%bajIW>b*^aL7fi>MM|9nT* z-@uydKi|>yHN0j-+7BPl_V%ow(a*c}rM>H8^z$8A|7c_M^RE5&u5Z!LcXa)Vem=7O zi>*(b3D7? zFc}yGaLXSF?t_U`fcsk7K|0usA0t-`#ykq0+#3%B=uZdw$NA_6@bnK?zYMlL<;@>T zzI-lIUjKomKY7v8A6xq1n?JJGuO74X6`#KRf?j(&HrqZJ^KIzlo)p!O0Gu6+b02^) zXB@6&`}afd@Q>e@9#1w~dZ5YD)<&gYKiFcg@&2rGJL@F-SYhe95=&PXS-NVurM?~B-WKupY!PpFv(Ojb zPGCo)c-tE+wrvuxr5?Z@oi;|aZ#H930cgJ)sw}PZ?Wl>eW3BIp)xIC93aorZo*4MT zlrI&tB3Dc)_PiyF#S||RQ?yXb@&#fFo)B*<_FoCwrwvycVH*k;s4wERpIo<6vJdT& zF6c99GN`Gq6a!xv#KY8-NixQP%E13BgZ>+g34?1x9`Q&n%e68^i>wU$Pha5L+aAu- zaQx}}0ka>J(W8e+OG}H48Z%t!=$v7aG4~-cn_vUR#ekU)M95@Y89b9QbBY*@3)(SY z+I_KQrrxVIMC56p{gESvNKt9AEMB}=O3GF!EiEsDuA$g(R;dkfWkx{;MXg_BEJm}?k1KOqcp`%nXmk^i*&#K{wZ_RCjZ82`93$Pa`3O{fR?;T=HzDn|RX zdr98XK>Gzn%P;7ETp5=miS(=~67R{_?W^4?6&cLSu(>kKRnE4B@~0gmTxfUC!R4g9rN0o2bLhpYLp-jWF1lM|F-T`1O%`+AvG2~cbKUmM9&+jo_&e<>ReZ|W;hc;Q;n*=Z(w*ahRMT6hCxNllm z_hTRFbM}FAIcrah<=wR1duq4jp8KnU@5H(1{-W@n+|kDG+a^nJpBRUITbM_kCCsDF zvgGWa72{BYTMV8Ui+ao0wps`4lJ^4q-en-*YH`t&<17PU-`w{&981gx_J#7po&7oT zi4X>R-!PB*M3`Sy80JHj1#LX`p-v{WVrd(X?-a&BACXkNII>p3u{u%Pwzbtk;G@B@ z9nXIJN%NY0xLNJTdvNwYelMfXeuRC&3d#Pv&#x^3f5zUgF0%K}L8c1z7Rr#X$hR`& z%a%#@=VxRT^dyxnRbF+{{pq71DqfEV+^{Ro;|Nu`|&QH zdFpK$@w<1i?=F+flW&24PeP~xWS)4_@~DX@{{ik}@0t1D8#01C>O`6EzHWKc%`$)a zQ`M7H4*nP5DTDeM>vwDm?MBy9V_m!4<+$hfRGf!6_Bp2_dgDG(UE{}mVJ3|I!h5z= zZus6o8HU=b*;p>Uj~&oDY6!7NePN$u<9-OSNd4|Ud%wC^Qopm;@>PYBdSthisVI=t z!@Hp8B}pd#>`r^X6ty1YhTrBT(y^by@{rokoYno5zo$C9PeS!oGW7ZVTC)wI{*d+D z0ZBq%LWoBeWRuXB5OPELH6;>4ZYYm&6+&((k8#D^7;?B(k}JU@H?of4+45zmRk>O! z>Zq)xVmz^ar`U$ND)QUH)>XYNb>cM>wLp!Fotm#>2KMQhUIXf__+})8+Tu{yY3qxy zAA7|l)={ue%|ic@K$+XhV_X^9&-YePFFN32|T_=)#2x=K~CE~pr*|4sI;bRYpL3Ya6g_9 z+XveZ#v-Bpejn2DP1eo){tK~4+uJM|2T&hF4AS;ANydKg7)xop8zqA>h(+42&EQc( zL=4h)Hb@4(M`JAdZ?BWgR>&Y0Y1`{1V-IqdF$nj;^@DxzV}W`wYr<`@Kp#*eXFmdU zdPYFUzdwFxyN_gi({?9(*K2z%;;>2vp}vtyzP1wlE=k>1BS|$YWzbXLTQ+J=D8FTc zBq1Jy4(*iGrgaiRJZ{Gsbf2d6l7x5+I%jjmS6Vg~kFo;g6@lIYk2hGY);W zZj`~O@ATbPtF$X(Vwea1*+I94Y8j0D?ANjZ<9x65X#P6VAd2p6A8%S%;MIE@6-Ht zeHbwP{s_5YRv+aanyhn_i^YJclVi(0aCbPjBi=n|{RR1((zI5_j~^w)D@ygeg=Y;! zY55A7I3Y)_$5>$>QV@@Xat#=3n4?mVULQJiP(C|%PVK+A+*y79ICAXhMf5=q^Xx_C&i+%^i@-Tk4Expp z@K+(uyduAQrTz4OZ|8r;DUlrW1-?(gxpYD~A(UlYn9=biuK%AJKizB}#4x@g~BX?^VR55Mw^CE))RB{BUUSFRaz zDdyP}%vbblTsg#ta}?*NgmQcb!5qc2^hEYM|3{yP6_ymm9RCUB@Gj{58ea~6#XNga zIr<;#Mc|wt|wS8Qn218ltX+t&w8y9=Y%or zcmC&jT;!Qqe&O<%{=a-V_!aZ4^M8DOki$G1IOmLEKj-!lBZtWRh4W=m?h;vyv$ov) zWsyOzk*18aE=RE7}-;yZ}6IS*l9f%y~jY~Y+X zj{lv1&!0c9_B!hBM^pEAN2CAluJ!N838jpqz6WCd!92^o1^d8Q=--hON+aH(_%6sg zRHFIEwRP30{|*)TK5P4cesDZ-kIJ#dcR}rgeHV;pzlZnkFCVNKwABq*`>?R*u^!%~ zSq}^YXVigna*m$~V?Wb)a83KFfHrsjIz7*MSZPWfs`aayJnY&1QNd;ERKf1KP`m`3~KYF+;aPO?8E literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/50.ico b/reactos/dll/win32/setupapi/res/icons/50.ico new file mode 100644 index 0000000000000000000000000000000000000000..71a7077da1be39b9cfbfc96cda9d5c99e1f6bc57 GIT binary patch literal 17542 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 L6hanXMLPN)le3$i literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/500.ico b/reactos/dll/win32/setupapi/res/icons/500.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/501.ico b/reactos/dll/win32/setupapi/res/icons/501.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/502.ico b/reactos/dll/win32/setupapi/res/icons/502.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/51.ico b/reactos/dll/win32/setupapi/res/icons/51.ico new file mode 100644 index 0000000000000000000000000000000000000000..281e1b8f53b1b021dbac18aa546f553c6f906cab GIT binary patch literal 17542 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 Uh7aQUbBsq7!kmgdLS`|414?tSB>(^b literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/53.ico b/reactos/dll/win32/setupapi/res/icons/53.ico new file mode 100644 index 0000000000000000000000000000000000000000..960b642d2ccf33f7fdca7e36378cc644fa7e22e0 GIT binary patch literal 17542 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 DfN7&i literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/54.ico b/reactos/dll/win32/setupapi/res/icons/54.ico new file mode 100644 index 0000000000000000000000000000000000000000..8197c479659f65fe0f0a766c7103810d5d088301 GIT binary patch literal 17542 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 TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/7.ico b/reactos/dll/win32/setupapi/res/icons/7.ico new file mode 100644 index 0000000000000000000000000000000000000000..dac3ff0b85d840eddcacf8a7e47f5afac10c02f2 GIT binary patch literal 17542 zcmdU02UwM7mcA)7*_mv1%I@qWlT705#7QP)q9&%BXiSVoMWiX%dqI)j+oktjRBT95 zLBXzwD2j**ihv;fQbklOG&Lw^-}Bx3U#}MwF_YP6@AJHzzn<@$@B99*ocAD;JtKQw z_VUXz$RRSnU&&q)1_u= zXlkH(TxVU-%FXjfm3o$o{*SGCr{;3W>yw$+qR9irASD@@dKR6&!?@p&nP&1 zmJ*T@DLFZrB4eY;c-D+1(EC?_>q+|ka{l6l-*Fk6H*co&T|4PaK>?+1-`+2_@7N)p z%gf87quJRM9TOw$c9FXsaB_D&Y2#>b4#mHeltVtl=PNB%eZ^%w4VJE0KE~3{<_l-J zo4uF6Z;OU*%|mYU=iR(KDEmYX6}>l zYoNCRD1?0aFKr!DzjQ_CefUsgi(&5df*HrCOBtV3#4)zuJR z(*(a$TVE%9*VZeY3;nRse*DJ?0Lv#u0+(5>PzI$AR?M z)+xI9`BZ-!O7XLyZP3lw>TL;_L%$A%E%*VLpqBi6#*xE3uJjC~zeZ8p&d;a#*+Q=k zZS}RLtv*(?1^Sb{%qiJ}%a}^RbH5h|f|TqpEidaFP=9UhO@4kG^l$aCp)JszEOc8^ z5_BiY%_&iChPpDM;CT}$VCJ_%|Iri2=|tYiI|J!g)G69n{}$Hm&9J6qPu6Wgi9mw; zD!`03yRM*k7gLHcGkIWtS=r5j^w-qZwhH~;wx|yqO7gO%MCebHLpN;S4E^!0X0*v= zg}?@frE2?g^Ggw7ar+@9 z{X@OY{0Vg@-mR#ppr?VV+z(lHbac?on>VSbsEDpzyGB>9UVR9sPMxCM++2anmoH20 zJ(K;x`>{{qgNsxb{BBuU8MU>wJrOQkxbV=JFWLX3-wv0EU%xKiPYtl6^>*_pl*i)v4-ksuP>j+1K0m8nzVtqizsfP#hSplnqR3_X z6gYbv1*tI5`(oVl;&B_}pGxv^*y5?=XZ(#Q|Hh3Qeah#yXWcxWCAc#%X7aIo6>V0@ zNYm-!8GcsVe(pc~{w5b52Uqq3<#m3hzxSp3=lcVpzxVUdKUv36z#gzvxq{`aFsjrzmLkt1LJ@WT&Z z89sdYpFa5DgI5`R&e!?=*s){(^KrVgO)xe#uADY~TDQpzlUv3n#7=A136 zxIooSbxJft0=3QcKm*lWg1n@Z3O;VZeh#Qn$=a4is=bVTpgZ#rKCR4clg*5nmcdq{Z*@0EkMEQ{W=@5VBvzIgISrBl$4~##!VY( z-THM;1kLyO_+-Ip+8Dn{t&6W^WFMxPvu3t$*|J5EnwnaakdQE%%jO^YfJJ0XRQHCB z8)^Oe^*;$~+;<@6QVs zEVx@brc-#}8yZ&g-e7p@s~M4DOB}KYj@O zdkbYBL^~gs%4fNB>C!aV&;?t%Q6INw&z^l7ed9LzXV3KM(`mY~G2xh|;dt7#X=G?< zNc#Hv+@DF8p{q+%rc9y9lPA-pNt1ejI}DuP)zQ)ES+r$<3$7gI6n1z;58lHDYbHM&->fbw~O-pLjp+~L1Dp^ zvLls}w``$J@$tRRF3xSJL*v(9fBhZk;LscU!+!Pqv$3%;w6?ZxH#0M%6)RTI^5x43 z?LkYHEFshzp?LZPAXlFw{1}-roLJ zaoGiGy>?aL^0g~;`RWyFx!OvXu3Q#qZfzlsS2O{QEr?ApE@51|#PNj&szXdmfqu!T zZK$J~1_f2u*HU#|EmbLMs1kefBgeC8(&Wjv`YFGs6=j~gP(){n&(WEpb9B1sES)~D z#HsTIbgHm`@(S}Q?_55eJa>jtccxML{ymh7Z~a8UDLRqQ$fKMyjFXgenvqM#Pccr= zaU5T)s^B{5(JtTF*|~%LEv~#sUVj-vzF&SpevB_vz_Gu;myi-3TnoUpfKi$lr9Sun z^b^{+bTRDDr_zdx{C#w2m+vljZ@q;2Ev>E~-_JfJr|-Ta=W*i%Tp(S(|DIeKXiGQ7 zgbC!Xf*ftk@R&GJz!TDI(j)Up#>MH@OufHaSHLf#k7;Ixdb~>o+WE&mX#*aUyU6J8b zSXxB+=L#^6O)t?d-#;MW1mY>^uL=s8FrJ)rbjT6)Xbl~!P#-JN56l=i=5uof>|+}( zR5r4${n=?ZVgzL*Y(gyV0_B}KMKfp5KA~NHaB%RxO2jT}o9ZcS@+5M`c{BwbokdmEjqhzPU@Zpq&v9hG1l#ZV~!Q;oiKIMmm zB$btyQysqLh^e~dVqiedDmdxs5yJsvyBX?x(a4ds=%bHlF(hLN19iNV0sGj-Whxul zR{LSYDCh7&Dy=G~Bge97?%cUa+U19YghUsYmWVMWQeThUFs``*E|_OrFuplsu3>we zFyGjsPcMPrbK%!K73QOk84EuAkQS=IHZmOl@ej(ww_jdUMHz=P+5c$m@`Hkc~V%Y0cgXnNcLhu!O>k`n;5>X7)`I6T9@lZKzXx-OwRZVo zVPQ*ha&vFDU<_WrU>^A_Tu7cO$mh>j+5?+}J+R4b)+_;6*yIA69MDFK(f^HLgTY&G z2^hZpHZfdBenk5-4^rw5@C!S(-^N_VoWw&vw7@%LP5v6!>KjdY@X zlZOh&3F?31frAG-uHLv#JG?x|59Rn{F7{iwQozU5lzcEJd&4F#%*$+(C))(b*(Sgp z_2iB^a$~SPfDQVq*XXZl=ic3P;NSs@TNl@{c=6(i+U2AEze?Yk-rjce1|5uzp&;lF zv$dsA8ygC?wx(b!D+;u*pg?o;K6ZJ-F1E>2Ws?W$$%E}dJ+V!G4sQPZKlOh2=PU~Qr%ddbZey?1gLQh3&J>-V$=Dn5ehD#?C&fLiVFv{C-Fs4< zSd(^PAD1$a@36nM2fz~hD*C-$zb>`(GVHQEEg}6y~b3+Dclmc)^cv zzWL@j*!u>+k;X^*f%R8QA?kk5o;|d8@7{-yigl{?wI@B_xo>yB@9so?1NT*qXKCx& zy?Zz1mlTrDlqrp{`D1|h>&Tdq{SN4NOo06XDe2pL(sm*qp%ounzi|Ua#whEB>xSzq zTF6)&$5PB105W#XY8r6o}8{L`FvXV19dK#Crbx`OSG}&xpJf#B}KA0^&!a?i02o^(iBM zb37eGTw#i?u42T95#J!LX@+&|YOG@pA3b`s3w^B;$CLXs04~6O?~MuZJ$v!ZC2!sG zvtj?CgQD+eA?}j4E1kH%Y){`o+tYT?fkPRbBXoDnm@z!=aDRCb5PcqYPefCQNt@Hum`?CMM3$$jE4qjg95+xz7*rG-t%u z4lP``FlXL^1t;-cpP4aZ#yMjXlOpIXH83zJ$DC3P?%=Y4p<$=dG^6{5(~Nq-PxK;& z02ud9gETNS=*4rrnA3YPr}LcKiJ05fapT4{VoX=SzG}?Z<+y$U^K2pFZv}Yv6z1E* znD8s zOm5!p6dDswaS0nJc?V+qdw0_IJ!zD%Es@r2ile~LKyY1hvU9TUon|ua-k7mt>R)>4 zrAX-FJf>v;@0)n<@+H9I4A<+w1HVEn_Y>rtd7!_X$jQm+&dSQVia75k)ctR8|8YOg zLge`9TL6#0-vI_g-x?aKYpDODv%3r8<`J|dZ5v{*skC`(0?pEt>UJkb_>E+Sb2UjP-+c?QxXwHJU_tD?#u!cXoZrwV? zzJ2?;_wV1|o}Qjwg;@Ggu4DM&gnOT(+^5axf3|--=8)Or#*gb>YPytc9PG%< z(wvZwN7gv@_V;}(%&~W$i}=Ap#5ef3q3H{N)|68aI| z`C#Jc(W5_t@sC{RJkGII78U`hn@;TWIR=LI-MT!7fW!1;5OUwD?zsBjvw zTP5=8G}aBQD=Ygbb50!3?su)GZ9AVc|A;xai|yz6J1h4XWu0JTE0L2;hjWf9aU2rJ zJbr{S!Cx{C9m}Fa;7S=8jH5~%L|&bQ16i4v^OV?+IZ(nr%xw}fp_gNl;JrIANBp%v zTl>3)Hl4mLHKnT-Jd3n95&IR@9!BhI5bxrc*V$6kE$W(4fEZvwi4vQVHq+V->xt)3 ziEnun=c38GNZiXwti2c)t1FpP?M5HsG5m>s;JGFu4%bnKJjb)(Bv$K9rC2>ZfTb1? z+lkRYtiINL)$=is51>mih++2&JePYqPst&{{tDDT__H4|S3mJsg!s)@>o;s@Xa1`I zT$DHB-ORaof^%U=+>00D)Xcv~@If43f-hp}68v!Nhj^C11_ChtNZ`1Zh;N~e{83ge zcrI=SMkRPP^#A*)_$TiF_;!cKu8wWzSU2xky%C?)=9Ju3oRT)T#2ix}Up0JWUnL(| z`Z83$vY-CownTqY*0_2=>1j9ueNj+$7uYgZQo!_z{MhGgEO`$g9^^@#SVU0s(44i>y1`& zk7^E5<)fybYF{<|#IfXO2>gboa;3@3yzRva|juedezBBB1!8qZ9F~o(B z;RpNUgg$ElA69{Y=>Hf&+#WJTQDk`D%*i*36wP z>}Ma!(DwT?4sb3@;9%_!3<^5K|9e%{P)loP&mw#D5$0(bf;(p3Sj8Q)FM>Z-`NDpz zK!2YPo|yS!2@Am$OAs74cx{%#SJ=K3Ty8w}2^=qE`zz4)>AQFJBA(_nSo;y%I$VRi zn3~2qieG6;_V`ZKoU@6E;CKbktKyv{F5DSy!@f8{T49c!2m1xjJbbv|!_}Plh!Hdo z5WF~^VPBWL^A7Sb+{GG@?XN=lDXFP<@%@?&)_&|&cHnApN@KG9~TWBN_+7? zZHJB?ro-7sM2=BHQUd3y%^R%!!J)x%7cQ1jeM=MV4G$qZjLRP2ZJBdd^X}kp1@|ub z#J(`!&4545!3)5jm6$7Lz<%c88O*&4fcu}J!s5UF4;@NQ5NmPnL!2)aw|-qG?B{sR zpnm8-{^yZP(||nFBUsCGo{r$_!TEYHG&y_CJOa)o09+Xw{y4)QC-|{~{XktCfjeg| zf0_nNQUBTC7xv+sJ(imzay25NB0CVvN!N@i2JW6}fqNKVG_ena&`u)CFr9DL+7+BcRF?ka8C!UY>IW*eA|mQ0EMA z4g*7#$H495!hk>a_|{ioooDs-Ti6fh)2_XHh-2!PvHrz6tONNB?+w;|e7|$Dk00y4 z+;)Wu3r>+7{hxCke35&|@L`ym3jUt`5k5hBs`3mx&`uu6ePEyDfIEERybR$F{1Q13 zDxWwHf_=eymI{-l~$IK7uG<5h&6GJ zL;&YVa4rG^IUK(5OZX%C1i!pgc^twY_@wqn@=29H;Rc`FRQ}k%|DNCl(|7L_xqO^Y zfW7P;*w1;QgZiQWe7Ae=p7yI)Lo>JIi}npgzDEf1D?%WH5x)sS{3gf>c^_JSiM$jo zzr5Kev-3l;%^7T;@r z4$cKe-ZIDDp62%~IKGy1MdzsnId2c673Z2z-EW0d;Swb0%L-r}%WGK);(w}PTXPHY zmGM8&%Kx!O-ZG9Ee611xSG{HH)_aJT#y^em{0`!_pMyt8L*9;JAVfq(DZ(Qn6nIC0 zZ$}Xl8lpfhlp-h?2ntdJ1OzDj{QVTZet@s90=Ya2jO_~K@+c7VRk+ImcXtJHdK8HJ zDv-xh?cnGbf$`_RpVt2WPw(M>C;8teIWI}Z3`@TfOj8}-e?d!vp}EP|5g`*2*=IuD zk>P(jak*Y5<3aEl+-J$}3+X14p-9GlXI-G7Xf^!+R4Gq8ut O>raaMz2bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/9.ico b/reactos/dll/win32/setupapi/res/icons/9.ico new file mode 100644 index 0000000000000000000000000000000000000000..43521de70d69f3ed0af849f88f0cd7d6a5151e7d GIT binary patch literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ literal 0 HcmV?d00001 diff --git a/reactos/dll/win32/setupapi/res/icons/Icon_Licence/COPYING b/reactos/dll/win32/setupapi/res/icons/Icon_Licence/COPYING new file mode 100644 index 00000000000..e709d0c050b --- /dev/null +++ b/reactos/dll/win32/setupapi/res/icons/Icon_Licence/COPYING @@ -0,0 +1,67 @@ +Creative Commons Attribution-ShareAlike 2.5 License Agreement + +CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. + +License + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. + +1. Definitions + + 1. "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License. + 2. "Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this License. + 3. "Licensor" means the individual or entity that offers the Work under the terms of this License. + 4. "Original Author" means the individual or entity who created the Work. + 5. "Work" means the copyrightable work of authorship offered under the terms of this License. + 6. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. + 7. "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike. + +2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: + + 1. to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works; + 2. to create and reproduce Derivative Works; + 3. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works; + 4. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission Derivative Works. + 5. + + For the avoidance of doubt, where the work is a musical composition: + 1. Performance Royalties Under Blanket Licenses. Licensor waives the exclusive right to collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public digital performance (e.g. webcast) of the Work. + 2. Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right to collect, whether individually or via a music rights society or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover version") and distribute, subject to the compulsory license created by 17 USC Section 115 of the US Copyright Act (or the equivalent in other jurisdictions). + 6. Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is a sound recording, Licensor waives the exclusive right to collect, whether individually or via a performance-rights society (e.g. SoundExchange), royalties for the public digital performance (e.g. webcast) of the Work, subject to the compulsory license created by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions). + +The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved. + +4. Restrictions.The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: + + 1. You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any credit as required by clause 4(c), as requested. If You create a Derivative Work, upon notice from any Licensor You must, to the extent practicable, remove from the Derivative Work any credit as required by clause 4(c), as requested. + 2. You may distribute, publicly display, publicly perform, or publicly digitally perform a Derivative Work only under the terms of this License, a later version of this License with the same License Elements as this License, or a Creative Commons iCommons license that contains the same License Elements as this License (e.g. Attribution-ShareAlike 2.5 Japan). You must include a copy of, or the Uniform Resource Identifier for, this License or other license specified in the previous sentence with every copy or phonorecord of each Derivative Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Derivative Works that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder, and You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Derivative Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Derivative Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Derivative Work itself to be made subject to the terms of this License. + 3. If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Derivative Works or Collective Works, You must keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or (ii) if the Original Author and/or Licensor designate another party or parties (e.g. a sponsor institute, publishing entity, journal) for attribution in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; the title of the Work if supplied; to the extent reasonably practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and in the case of a Derivative Work, a credit identifying the use of the Work in the Derivative Work (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Derivative Work or Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit. + +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + + 1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Derivative Works or Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. + 2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. + +8. Miscellaneous + + 1. Each time You distribute or publicly digitally perform the Work or a Collective Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. + 2. Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. + 3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + 4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. + 5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. + +Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor. + +Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, neither party will use the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. + +Creative Commons may be contacted at http://creativecommons.org/. diff --git a/reactos/dll/win32/setupapi/res/icons/Icon_Licence/Tango.txt b/reactos/dll/win32/setupapi/res/icons/Icon_Licence/Tango.txt new file mode 100644 index 00000000000..09bae21977c --- /dev/null +++ b/reactos/dll/win32/setupapi/res/icons/Icon_Licence/Tango.txt @@ -0,0 +1,127 @@ +The following icons are the property of the Tango project and are +released under Creative Commons Attribution-ShareAlike 2.5 License. +Please see COPYING for details + +1.ico +2.ico +3.ico +4.ico +5.ico +6.ico +7.ico +8.ico +9.ico +10.ico +11.ico +12.ico +13.ico +14.ico +15.ico +16.ico +17.ico +18.ico +19.ico +20.ico +21.ico +22.ico +23.ico +24.ico +25.ico +28.ico +29.ico +30.ico +32.ico +33.ico +35.ico +36.ico +37.ico +38.ico +39.ico +41.ico +44.ico +45.ico +46.ico +47.ico +48.ico +54.ico +137.ico +138.ico +151.ico +152.ico +153.ico +154.ico +155.ico +156.ico +157.ico +160.ico +161.ico +172.ico +173.ico +191.ico +192.ico +210.ico +220.ico +221.ico +222.ico +224.ico +225.ico +226.ico +228.ico +233.ico +235.ico +236.ico +237.ico +238.ico +240.ico +245.ico +246.ico +248.ico +249.ico +250.ico +252.ico +254.ico +255.ico +263.ico +265.ico +268.ico +269.ico +270.ico +271.ico +277.ico +279.ico +289.ico +290.ico +291.ico +292.ico +293.ico +294.ico +295.ico +296.ico +297.ico +298.ico +299.ico +302.ico +304.ico +305.ico +309.ico +315.ico +317.ico +318.ico +319.ico +322.ico +323.ico +324.ico +325.ico +326.ico +327.ico +328.ico +329.ico +330.ico +1001.ico +1004.ico +8240.ico +16710.ico +16715.ico +16717.ico +16718.ico +16721.ico \ No newline at end of file diff --git a/reactos/dll/win32/setupapi/Bg.rc b/reactos/dll/win32/setupapi/res/lang/Bg.rc similarity index 97% rename from reactos/dll/win32/setupapi/Bg.rc rename to reactos/dll/win32/setupapi/res/lang/Bg.rc index 1527cdeea05..5f342c00521 100644 --- a/reactos/dll/win32/setupapi/Bg.rc +++ b/reactos/dll/win32/setupapi/res/lang/Bg.rc @@ -1,34 +1,34 @@ -/* - * Bulgarian resources for SETUPAPI - * - * Copyright 2005 Milko Krachounov - * - * 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 - */ - -LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Ęîďčđŕíĺ íŕ ôŕéëîâĺ..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Îňěĺíč", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Čçňî÷íčę:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Öĺë:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Bulgarian resources for SETUPAPI + * + * Copyright 2005 Milko Krachounov + * + * 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 + */ + +LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Ęîďčđŕíĺ íŕ ôŕéëîâĺ..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Îňěĺíč", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Čçňî÷íčę:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Öĺë:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Cs.rc b/reactos/dll/win32/setupapi/res/lang/Cs.rc similarity index 97% rename from reactos/dll/win32/setupapi/Cs.rc rename to reactos/dll/win32/setupapi/res/lang/Cs.rc index 9f30d3defcf..74db2429d7f 100644 --- a/reactos/dll/win32/setupapi/Cs.rc +++ b/reactos/dll/win32/setupapi/res/lang/Cs.rc @@ -1,38 +1,38 @@ -/* Hey, Emacs, open this file with -*- coding: cp1250 -*- - * - * Czech resources for SETUPAPI - * - * Copyright 2001 Andreas Mohr - * Copyright 2004 David Kredba - * - * 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 - */ - -LANGUAGE LANG_CZECH, SUBLANG_DEFAULT - -/* Czech strings in CP1250 */ - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Kopíruji soubory..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Storno", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Zdroj:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Cíl:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* Hey, Emacs, open this file with -*- coding: cp1250 -*- + * + * Czech resources for SETUPAPI + * + * Copyright 2001 Andreas Mohr + * Copyright 2004 David Kredba + * + * 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 + */ + +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +/* Czech strings in CP1250 */ + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Kopíruji soubory..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Storno", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Zdroj:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Cíl:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Da.rc b/reactos/dll/win32/setupapi/res/lang/Da.rc similarity index 97% rename from reactos/dll/win32/setupapi/Da.rc rename to reactos/dll/win32/setupapi/res/lang/Da.rc index 907b2d5ab9f..b699de003c8 100644 --- a/reactos/dll/win32/setupapi/Da.rc +++ b/reactos/dll/win32/setupapi/res/lang/Da.rc @@ -1,35 +1,35 @@ -/* - * Danish resources for SETUPAPI - * - * Copyright 2005 Thomas Larsen - * - * 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 - */ - -LANGUAGE LANG_DANISH, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Overfřrere Filer..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Fortryd", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Kilde:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | -WS_VISIBLE | WS_TABSTOP -END +/* + * Danish resources for SETUPAPI + * + * Copyright 2005 Thomas Larsen + * + * 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 + */ + +LANGUAGE LANG_DANISH, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Overfřrere Filer..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Fortryd", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Kilde:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | +WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/De.rc b/reactos/dll/win32/setupapi/res/lang/De.rc similarity index 97% rename from reactos/dll/win32/setupapi/De.rc rename to reactos/dll/win32/setupapi/res/lang/De.rc index 4f7d37ca4e3..2c8a563e22f 100644 --- a/reactos/dll/win32/setupapi/De.rc +++ b/reactos/dll/win32/setupapi/res/lang/De.rc @@ -1,40 +1,40 @@ -/* - * German resources for SETUPAPI - * - * Copyright 2004 Henning Gerhardt ( added some stuff in 2006-1-20 by Friedrich Stange (dj_smith_reactos@online.de) ) - * - * 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 - */ - -LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Dateien kopieren..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Abbrechen", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Quelle:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Ziel:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_QUERY_REBOOT_TEXT "Ihr Computer muss zum Beenden der Installation neugestartet werden. Wollen Sie fortfahren?" - IDS_QUERY_REBOOT_CAPTION "Neustarten" -END +/* + * German resources for SETUPAPI + * + * Copyright 2004 Henning Gerhardt ( added some stuff in 2006-1-20 by Friedrich Stange (dj_smith_reactos@online.de) ) + * + * 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 + */ + +LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Dateien kopieren..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Abbrechen", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Quelle:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Ziel:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_QUERY_REBOOT_TEXT "Ihr Computer muss zum Beenden der Installation neugestartet werden. Wollen Sie fortfahren?" + IDS_QUERY_REBOOT_CAPTION "Neustarten" +END diff --git a/reactos/dll/win32/setupapi/En.rc b/reactos/dll/win32/setupapi/res/lang/En.rc similarity index 97% rename from reactos/dll/win32/setupapi/En.rc rename to reactos/dll/win32/setupapi/res/lang/En.rc index cfee66f02a7..38ac079f322 100644 --- a/reactos/dll/win32/setupapi/En.rc +++ b/reactos/dll/win32/setupapi/res/lang/En.rc @@ -1,40 +1,40 @@ -/* - * English resources for SETUPAPI - * - * Copyright 2001 Andreas Mohr - * - * 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 - */ - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Copying Files..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Cancel", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Source:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_QUERY_REBOOT_TEXT "Your computer needs to be rebooted to finish installation. Do you want to proceed?" - IDS_QUERY_REBOOT_CAPTION "Reboot" -END +/* + * English resources for SETUPAPI + * + * Copyright 2001 Andreas Mohr + * + * 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 + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Copying Files..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Cancel", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Source:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_QUERY_REBOOT_TEXT "Your computer needs to be rebooted to finish installation. Do you want to proceed?" + IDS_QUERY_REBOOT_CAPTION "Reboot" +END diff --git a/reactos/dll/win32/setupapi/Eo.rc b/reactos/dll/win32/setupapi/res/lang/Eo.rc similarity index 97% rename from reactos/dll/win32/setupapi/Eo.rc rename to reactos/dll/win32/setupapi/res/lang/Eo.rc index c7210739c34..0dcf4e49820 100644 --- a/reactos/dll/win32/setupapi/Eo.rc +++ b/reactos/dll/win32/setupapi/res/lang/Eo.rc @@ -1,34 +1,34 @@ -/* - * Esperanto resources for SETUPAPI - * - * Copyright 2006 Antonio Codazzi - * - * 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 - */ - -LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Plenume dosierkopiadon..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Rezigni", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Fonto:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Finpunkto:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Esperanto resources for SETUPAPI + * + * Copyright 2006 Antonio Codazzi + * + * 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 + */ + +LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Plenume dosierkopiadon..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Rezigni", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Fonto:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Finpunkto:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Es.rc b/reactos/dll/win32/setupapi/res/lang/Es.rc similarity index 97% rename from reactos/dll/win32/setupapi/Es.rc rename to reactos/dll/win32/setupapi/res/lang/Es.rc index 1e1bc11ea9b..4eca7dee95a 100644 --- a/reactos/dll/win32/setupapi/Es.rc +++ b/reactos/dll/win32/setupapi/res/lang/Es.rc @@ -1,41 +1,41 @@ -/* - * Spanish resources for SETUPAPI - * - * Copyright 2003 José Manuel Ferrer Ortiz - * - * 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 - */ - -LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Copiando archivos..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Origen:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_QUERY_REBOOT_TEXT "Su computadora debe ser reinicializada para completar la instalación. żDesea proceguir?" - IDS_QUERY_REBOOT_CAPTION "Reinicialize" -END - +/* + * Spanish resources for SETUPAPI + * + * Copyright 2003 José Manuel Ferrer Ortiz + * + * 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 + */ + +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Copiando archivos..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Origen:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_QUERY_REBOOT_TEXT "Su computadora debe ser reinicializada para completar la instalación. żDesea proceguir?" + IDS_QUERY_REBOOT_CAPTION "Reinicialize" +END + diff --git a/reactos/dll/win32/setupapi/Fi.rc b/reactos/dll/win32/setupapi/res/lang/Fi.rc similarity index 97% rename from reactos/dll/win32/setupapi/Fi.rc rename to reactos/dll/win32/setupapi/res/lang/Fi.rc index c3a9cd18166..114cdad3057 100644 --- a/reactos/dll/win32/setupapi/Fi.rc +++ b/reactos/dll/win32/setupapi/res/lang/Fi.rc @@ -1,34 +1,34 @@ -/* - * Finnish resources for SETUPAPI - * - * Copyright 2005 Kimmo Myllyvirta - * - * 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 - */ - -LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Kopioidaan Tiedostoja..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Peruuta", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Lähde:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Kohde:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Finnish resources for SETUPAPI + * + * Copyright 2005 Kimmo Myllyvirta + * + * 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 + */ + +LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Kopioidaan Tiedostoja..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Peruuta", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Lähde:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Kohde:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Fr.rc b/reactos/dll/win32/setupapi/res/lang/Fr.rc similarity index 97% rename from reactos/dll/win32/setupapi/Fr.rc rename to reactos/dll/win32/setupapi/res/lang/Fr.rc index 54e45d93e81..bafd28ae39d 100644 --- a/reactos/dll/win32/setupapi/Fr.rc +++ b/reactos/dll/win32/setupapi/res/lang/Fr.rc @@ -1,35 +1,35 @@ -/* - * French resources for SETUPAPI - * - * Copyright 2001 Andreas Mohr - * Copyright 2003 Vincent Béron - * - * 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 - */ - -LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Copie de fichiers..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Annuler", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Source:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * French resources for SETUPAPI + * + * Copyright 2001 Andreas Mohr + * Copyright 2003 Vincent Béron + * + * 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 + */ + +LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Copie de fichiers..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Annuler", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Source:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Hu.rc b/reactos/dll/win32/setupapi/res/lang/Hu.rc similarity index 100% rename from reactos/dll/win32/setupapi/Hu.rc rename to reactos/dll/win32/setupapi/res/lang/Hu.rc diff --git a/reactos/dll/win32/setupapi/It.rc b/reactos/dll/win32/setupapi/res/lang/It.rc similarity index 97% rename from reactos/dll/win32/setupapi/It.rc rename to reactos/dll/win32/setupapi/res/lang/It.rc index 71f1267db05..f33881e274a 100644 --- a/reactos/dll/win32/setupapi/It.rc +++ b/reactos/dll/win32/setupapi/res/lang/It.rc @@ -1,35 +1,35 @@ -/* - * Italian resources for SETUPAPI - * - * Copyright 2001 Andreas Mohr - * Copyright 2003 Ivan Leo Puoti - * - * 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 - */ - -LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Copia dei file in corso..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Anulla", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Origine:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Destinazione:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Italian resources for SETUPAPI + * + * Copyright 2001 Andreas Mohr + * Copyright 2003 Ivan Leo Puoti + * + * 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 + */ + +LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Copia dei file in corso..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Anulla", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Origine:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Destinazione:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Ja.rc b/reactos/dll/win32/setupapi/res/lang/Ja.rc similarity index 97% rename from reactos/dll/win32/setupapi/Ja.rc rename to reactos/dll/win32/setupapi/res/lang/Ja.rc index dc75dfbf88b..0ae3a99339e 100644 --- a/reactos/dll/win32/setupapi/Ja.rc +++ b/reactos/dll/win32/setupapi/res/lang/Ja.rc @@ -1,34 +1,34 @@ -/* - * Japanese resources for SETUPAPI - * - * Copyright 2004 Hajime Segawa - * - * 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 - */ - -LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "t@C‹‚đRs[‚µ‚Ä‚˘‚Ü‚·..." -FONT 9, "MS UI Gothic" -BEGIN - PUSHBUTTON "L“Z‹", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Rs[Śł:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Rs[ć:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Japanese resources for SETUPAPI + * + * Copyright 2004 Hajime Segawa + * + * 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 + */ + +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "t@C‹‚đRs[‚µ‚Ä‚˘‚Ü‚·..." +FONT 9, "MS UI Gothic" +BEGIN + PUSHBUTTON "L“Z‹", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Rs[Śł:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Rs[ć:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Ko.rc b/reactos/dll/win32/setupapi/res/lang/Ko.rc similarity index 97% rename from reactos/dll/win32/setupapi/Ko.rc rename to reactos/dll/win32/setupapi/res/lang/Ko.rc index e7fb1ce35d0..a72dcae3212 100644 --- a/reactos/dll/win32/setupapi/Ko.rc +++ b/reactos/dll/win32/setupapi/res/lang/Ko.rc @@ -1,34 +1,34 @@ -/* - * Korean resources for SETUPAPI - * - * Copyright 2005 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 - */ - -LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "ĆÄŔĎ şą»çÁß..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "ĂëĽŇ", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "żřş»:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "¸ńŔűÁö:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Korean resources for SETUPAPI + * + * Copyright 2005 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 + */ + +LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "ĆÄŔĎ şą»çÁß..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "ĂëĽŇ", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "żřş»:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "¸ńŔűÁö:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Nl.rc b/reactos/dll/win32/setupapi/res/lang/Nl.rc similarity index 97% rename from reactos/dll/win32/setupapi/Nl.rc rename to reactos/dll/win32/setupapi/res/lang/Nl.rc index f91d8251bec..56aebbaa479 100644 --- a/reactos/dll/win32/setupapi/Nl.rc +++ b/reactos/dll/win32/setupapi/res/lang/Nl.rc @@ -1,34 +1,34 @@ -/* - * setupapi (Dutch resources) - * - * Copyright 2003 Hans Leidekker - * - * 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 - */ - -LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Bestanden worden gekopiëerd..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Annuleren", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Bron:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Bestemming:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * setupapi (Dutch resources) + * + * Copyright 2003 Hans Leidekker + * + * 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 + */ + +LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Bestanden worden gekopiëerd..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Annuleren", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Bron:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Bestemming:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/No.rc b/reactos/dll/win32/setupapi/res/lang/No.rc similarity index 97% rename from reactos/dll/win32/setupapi/No.rc rename to reactos/dll/win32/setupapi/res/lang/No.rc index 7466f29fcc9..c0284c03f8e 100644 --- a/reactos/dll/win32/setupapi/No.rc +++ b/reactos/dll/win32/setupapi/res/lang/No.rc @@ -1,34 +1,34 @@ -/* - * Norwegian Bokmĺl resources for SETUPAPI - * - * Copyright 2005 Alexander N. Sřrnes - * - * 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 - */ - -LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Kopierer filer . . ." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Cancel", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Kilde:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Mĺl:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Norwegian Bokmĺl resources for SETUPAPI + * + * Copyright 2005 Alexander N. Sřrnes + * + * 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 + */ + +LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Kopierer filer . . ." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Cancel", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Kilde:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Mĺl:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Pl.rc b/reactos/dll/win32/setupapi/res/lang/Pl.rc similarity index 97% rename from reactos/dll/win32/setupapi/Pl.rc rename to reactos/dll/win32/setupapi/res/lang/Pl.rc index 27a48e94379..49646c4ff8c 100644 --- a/reactos/dll/win32/setupapi/Pl.rc +++ b/reactos/dll/win32/setupapi/res/lang/Pl.rc @@ -1,34 +1,34 @@ -/* - * Polish resources for SETUPAPI - * - * Copyright 2005 Sebastian Gasiorek - * - * 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 - */ - -LANGUAGE LANG_POLISH, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Kopiowanie plików..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Anuluj", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Kopiuj pliki z:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Kopiuj pliki do:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Polish resources for SETUPAPI + * + * Copyright 2005 Sebastian Gasiorek + * + * 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 + */ + +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Kopiowanie plików..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Anuluj", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Kopiuj pliki z:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Kopiuj pliki do:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Pt.rc b/reactos/dll/win32/setupapi/res/lang/Pt.rc similarity index 97% rename from reactos/dll/win32/setupapi/Pt.rc rename to reactos/dll/win32/setupapi/res/lang/Pt.rc index be71b27bbca..a40b4d0d873 100644 --- a/reactos/dll/win32/setupapi/Pt.rc +++ b/reactos/dll/win32/setupapi/res/lang/Pt.rc @@ -1,50 +1,50 @@ -/* - * Portuguese resources for SETUPAPI - * - * Copyright 2003 Marcelo Duarte - * Copyright 2004 Américo José Melo - * - * 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 - */ - -LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Copiando arquivos..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Origem:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END - -LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "A copiar ficheiros..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Origem:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Portuguese resources for SETUPAPI + * + * Copyright 2003 Marcelo Duarte + * Copyright 2004 Américo José Melo + * + * 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 + */ + +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Copiando arquivos..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Origem:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "A copiar ficheiros..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Origem:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Ru.rc b/reactos/dll/win32/setupapi/res/lang/Ru.rc similarity index 97% rename from reactos/dll/win32/setupapi/Ru.rc rename to reactos/dll/win32/setupapi/res/lang/Ru.rc index dafd2eaeb1c..5a09bd448ba 100644 --- a/reactos/dll/win32/setupapi/Ru.rc +++ b/reactos/dll/win32/setupapi/res/lang/Ru.rc @@ -1,34 +1,34 @@ -/* - * SETUPAPI (Russian resources) - * - * Copyright 2003 Igor Stepin - * - * 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 - */ - -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Ęîďčđîâŕíčĺ ôŕéëîâ..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Îňěĺíŕ", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Îňęóäŕ:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Ęóäŕ:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * SETUPAPI (Russian resources) + * + * Copyright 2003 Igor Stepin + * + * 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 + */ + +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Ęîďčđîâŕíčĺ ôŕéëîâ..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Îňěĺíŕ", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Îňęóäŕ:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Ęóäŕ:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Sv.rc b/reactos/dll/win32/setupapi/res/lang/Sv.rc similarity index 97% rename from reactos/dll/win32/setupapi/Sv.rc rename to reactos/dll/win32/setupapi/res/lang/Sv.rc index 72f51a7ff7f..9594f1a71f8 100644 --- a/reactos/dll/win32/setupapi/Sv.rc +++ b/reactos/dll/win32/setupapi/res/lang/Sv.rc @@ -1,34 +1,34 @@ -/* - * Swedish resources for SETUPAPI - * - * Copyright 2005 Anders Bergh - * - * 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 - */ - -LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Kopierar filer..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Avbryt", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Källa:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Swedish resources for SETUPAPI + * + * Copyright 2005 Anders Bergh + * + * 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 + */ + +LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Kopierar filer..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Avbryt", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Källa:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/Tr.rc b/reactos/dll/win32/setupapi/res/lang/Tr.rc similarity index 97% rename from reactos/dll/win32/setupapi/Tr.rc rename to reactos/dll/win32/setupapi/res/lang/Tr.rc index 3b922eeb167..6a786ddb7b8 100644 --- a/reactos/dll/win32/setupapi/Tr.rc +++ b/reactos/dll/win32/setupapi/res/lang/Tr.rc @@ -1,34 +1,34 @@ -/* - * Turkish resources for SETUPAPI - * - * Copyright 2006 Fatih Aţýcý - * - * 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 - */ - -LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT - -COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 -STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Dosyalar Kopyalanýyor..." -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "Ýptal", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Kaynak:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Hedef:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP - CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP -END +/* + * Turkish resources for SETUPAPI + * + * Copyright 2006 Fatih Aţýcý + * + * 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 + */ + +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105 +STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Dosyalar Kopyalanýyor..." +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "Ýptal", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Kaynak:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "Hedef:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP + CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END diff --git a/reactos/dll/win32/setupapi/resource.h b/reactos/dll/win32/setupapi/resource.h index bbb37ccc504..ccfa1175c81 100644 --- a/reactos/dll/win32/setupapi/resource.h +++ b/reactos/dll/win32/setupapi/resource.h @@ -1,7 +1,50 @@ -#define IDS_QUERY_REBOOT_TEXT 1 -#define IDS_QUERY_REBOOT_CAPTION 2 +#define IDS_QUERY_REBOOT_TEXT 1000 +#define IDS_QUERY_REBOOT_CAPTION 2000 + +#define COPYFILEDLGORD 3000 +#define SOURCESTRORD 3001 +#define DESTSTRORD 3002 +#define PROGRESSORD 3003 + +#define IDI_SETUPAPI_DISP_ADAPT 1 +#define IDI_SETUPAPI_MOUSE 2 +#define IDI_SETUPAPI_KEYBOARD 3 +#define IDI_SETUPAPI_PRINTER 4 +#define IDI_SETUPAPI_NETCARD 5 +#define IDI_SETUPAPI_NODE 6 +#define IDI_SETUPAPI_COMPUTER 7 +#define IDI_SETUPAPI_SHCOMPUTER 8 +#define IDI_SETUPAPI_DRV_CONTROL 9 +#define IDI_SETUPAPI_POWER 10 +#define IDI_SETUPAPI_CARD 11 + +#define IDI_SETUPAPI_UNKNOWN 18 +#define IDI_SETUPAPI_LEGACY_DRV 19 +#define IDI_SETUPAPI_USB 20 +#define IDI_SETUPAPI_REM_DRIVE 21 +#define IDI_SETUPAPI_SATELLITE 22 +#define IDI_SETUPAPI_PORTS 23 +#define IDI_SETUPAPI_HID 24 +#define IDI_SETUPAPI_NEEDSNAME1 25 +#define IDI_SETUPAPI_NEEDSNAME2 26 +#define IDI_SETUPAPI_MYCOMPUTER 27 +#define IDI_SETUPAPI_PROCESSOR 28 + +#define IDI_SETUPAPI_SIGNED_DRV 40 +#define IDI_SETUPAPI_BLANK 41 +#define IDI_SETUPAPI_WARNING 42 +#define IDI_SETUPAPI_DEVICES 43 + +#define IDI_SETUPAPI_FLOPPY 50 +#define IDI_SETUPAPI_CDROM 51 +#define IDI_SETUPAPI_NETDRIVE 52 +#define IDI_SETUPAPI_HARDDRIVE 53 +#define IDI_SETUPAPI_NEEDSNAME3 54 + +#define IDI_SETUPAPI_314FLOP 105 +#define IDI_SETUPAPI_CHIP 159 +#define IDI_SETUPAPI_ERROR 161 +#define IDI_SETUPAPI_WARN_OVERLAY 500 +#define IDI_SETUPAPI_ERR_OVERLAY 501 +#define IDI_SETUPAPI_INFO_OVERLAY 502 -#define COPYFILEDLGORD 1000 -#define SOURCESTRORD 500 -#define DESTSTRORD 501 -#define PROGRESSORD 502 diff --git a/reactos/dll/win32/setupapi/setupapi.rc b/reactos/dll/win32/setupapi/setupapi.rc index 3177fbdfc45..6753513e472 100644 --- a/reactos/dll/win32/setupapi/setupapi.rc +++ b/reactos/dll/win32/setupapi/setupapi.rc @@ -21,23 +21,25 @@ #include #include "resource.h" -#include "Bg.rc" -#include "Cs.rc" -#include "Da.rc" -#include "De.rc" -#include "En.rc" -#include "Eo.rc" -#include "Es.rc" -#include "Fi.rc" -#include "Fr.rc" -#include "Hu.rc" -#include "It.rc" -#include "Ja.rc" -#include "Ko.rc" -#include "Nl.rc" -#include "No.rc" -#include "Pl.rc" -#include "Pt.rc" -#include "Ru.rc" -#include "Sv.rc" -#include "Tr.rc" +#include "res/icons/icons_res.rc" + +#include "res/lang/Bg.rc" +#include "res/lang/Cs.rc" +#include "res/lang/Da.rc" +#include "res/lang/De.rc" +#include "res/lang/En.rc" +#include "res/lang/Eo.rc" +#include "res/lang/Es.rc" +#include "res/lang/Fi.rc" +#include "res/lang/Fr.rc" +#include "res/lang/Hu.rc" +#include "res/lang/It.rc" +#include "res/lang/Ja.rc" +#include "res/lang/Ko.rc" +#include "res/lang/Nl.rc" +#include "res/lang/No.rc" +#include "res/lang/Pl.rc" +#include "res/lang/Pt.rc" +#include "res/lang/Ru.rc" +#include "res/lang/Sv.rc" +#include "res/lang/Tr.rc" From c89da0aef01d7f25ad6f52365840e6bd3ad3b856 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 29 Sep 2006 17:07:17 +0000 Subject: [PATCH 371/488] there's always one that gets away ... svn path=/trunk/; revision=24299 --- .../dll/win32/setupapi/res/icons/icons_res.rc | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 reactos/dll/win32/setupapi/res/icons/icons_res.rc diff --git a/reactos/dll/win32/setupapi/res/icons/icons_res.rc b/reactos/dll/win32/setupapi/res/icons/icons_res.rc new file mode 100644 index 00000000000..f6a61164855 --- /dev/null +++ b/reactos/dll/win32/setupapi/res/icons/icons_res.rc @@ -0,0 +1,41 @@ +IDI_SETUPAPI_DISP_ADAPT ICON "res/icons/1.ico" +IDI_SETUPAPI_MOUSE ICON "res/icons/2.ico" +IDI_SETUPAPI_KEYBOARD ICON "res/icons/3.ico" +IDI_SETUPAPI_PRINTER ICON "res/icons/4.ico" +IDI_SETUPAPI_NETCARD ICON "res/icons/5.ico" +IDI_SETUPAPI_NODE ICON "res/icons/6.ico" // what's this? +IDI_SETUPAPI_COMPUTER ICON "res/icons/7.ico" +IDI_SETUPAPI_SHCOMPUTER ICON "res/icons/8.ico" +IDI_SETUPAPI_DRV_CONTROL ICON "res/icons/9.ico" +IDI_SETUPAPI_POWER ICON "res/icons/10.ico" // what's this? +IDI_SETUPAPI_CARD ICON "res/icons/11.ico" // what's this, PCMCIA? + +IDI_SETUPAPI_UNKNOWN ICON "res/icons/18.ico" +IDI_SETUPAPI_LEGACY_DRV ICON "res/icons/19.ico" +IDI_SETUPAPI_USB ICON "res/icons/20.ico" +IDI_SETUPAPI_REM_DRIVE ICON "res/icons/21.ico" +IDI_SETUPAPI_SATELLITE ICON "res/icons/22.ico" // what's this? +IDI_SETUPAPI_PORTS ICON "res/icons/23.ico" +IDI_SETUPAPI_HID ICON "res/icons/24.ico" +IDI_SETUPAPI_NEEDSNAME1 ICON "res/icons/25.ico" // what's this? +IDI_SETUPAPI_NEEDSNAME2 ICON "res/icons/26.ico" // what's this? +IDI_SETUPAPI_MYCOMPUTER ICON "res/icons/27.ico" +IDI_SETUPAPI_PROCESSOR ICON "res/icons/28.ico" + +IDI_SETUPAPI_SIGNED_DRV ICON "res/icons/40.ico" +IDI_SETUPAPI_BLANK ICON "res/icons/41.ico" +IDI_SETUPAPI_WARNING ICON "res/icons/42.ico" +IDI_SETUPAPI_DEVICES ICON "res/icons/43.ico" + +IDI_SETUPAPI_FLOPPY ICON "res/icons/50.ico" +IDI_SETUPAPI_CDROM ICON "res/icons/51.ico" +IDI_SETUPAPI_NETDRIVE ICON "res/icons/52.ico" +IDI_SETUPAPI_HARDDRIVE ICON "res/icons/53.ico" +IDI_SETUPAPI_NEEDSNAME3 ICON "res/icons/54.ico" + +IDI_SETUPAPI_314FLOP ICON "res/icons/105.ico" +IDI_SETUPAPI_CHIP ICON "res/icons/159.ico" +IDI_SETUPAPI_ERROR ICON "res/icons/161.ico" +IDI_SETUPAPI_WARN_OVERLAY ICON "res/icons/500.ico" +IDI_SETUPAPI_ERR_OVERLAY ICON "res/icons/501.ico" +IDI_SETUPAPI_INFO_OVERLAY ICON "res/icons/502.ico" From b652b371dbfaf68c4a4d0a47230ba2bce746406b Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 29 Sep 2006 17:07:48 +0000 Subject: [PATCH 372/488] - Implement device creating, with the specified DeviceExtension - Add stub for processing IRPs sent to the mouse driver TODO (will be done once problem with load-order will be resolved): - Store mouclass's callback address - Actually call it thus making driver working - Cleanup routines svn path=/trunk/; revision=24300 --- .../drivers/usb/nt4compat/usbdriver/mouse.c | 353 +++++++++++++++--- 1 file changed, 309 insertions(+), 44 deletions(-) diff --git a/reactos/drivers/usb/nt4compat/usbdriver/mouse.c b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c index 6e79298c6d4..d04c2b57d4f 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/mouse.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c @@ -9,12 +9,21 @@ #include "usbdriver.h" #include "ntddmou.h" +//FIXME: is it needed at all? +typedef struct _USBMP_DEVICE_EXTENSION +{ + BOOLEAN IsFDO; +} USBMP_DEVICE_EXTENSION, *PUSBMP_DEVICE_EXTENSION; + +PDEVICE_OBJECT MouseFdo = NULL; + + BOOLEAN mouse_connect(PCONNECT_DATA dev_mgr, DEV_HANDLE dev_handle); BOOLEAN mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); BOOLEAN mouse_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); - VOID mouse_irq(PURB purb, PVOID pcontext); -VOID mouse_set_cfg_completion(PURB purb, PVOID pcontext); +static NTSTATUS +MouseCreateDevice(IN PDRIVER_OBJECT DriverObject); BOOLEAN @@ -55,6 +64,9 @@ mouse_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) pdriver->disp_tbl.dev_stop = mouse_stop; pdriver->disp_tbl.dev_reserved = NULL; + // Create the device + MouseCreateDevice(dev_mgr->usb_driver_obj); + usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_driver_init(): mouse driver is initialized\n")); return TRUE; } @@ -203,48 +215,6 @@ mouse_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) return TRUE; } -// pcontext == device extension -VOID -mouse_set_cfg_completion(PURB purb, PVOID pcontext) -{ - PMOUSE_DRVR_EXTENSION pdev_ext = (PMOUSE_DRVR_EXTENSION)pcontext; - DEV_HANDLE endp_handle; - NTSTATUS status; - - if (purb->status != STATUS_SUCCESS) - { - usb_free_mem(purb); - return; - } - - endp_handle = purb->endp_handle; - - //usb_free_mem(purb); - //purb = NULL; - - usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_set_cfg_completion() endpoint handle=0x%x\n", endp_handle)); - - // Build a URB for our interrupt transfer - UsbBuildInterruptOrBulkTransferRequest(purb, - endp_handle, - /*usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx, - pdev_ext->int_endp_idx),*/ - (PUCHAR)&pdev_ext->mouse_data, - 4, // FIXME: use max packet size! - mouse_irq, - pdev_ext, - 0); - - // Call USB driver stack - status = usb_submit_urb(pdev_ext->dev_mgr, purb); - if (status != STATUS_PENDING) - { - usb_free_mem(purb); - purb = NULL; - } -} - - VOID mouse_irq(PURB purb, PVOID pcontext) { @@ -363,3 +333,298 @@ mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) return TRUE;//umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE); } + +// Dispatch routine for our IRPs +NTSTATUS +MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + //NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; + + usb_dbg_print(DBGLVL_MAXIMUM, ("MouseDispatch(DO %p, code 0x%lx) called\n", + DeviceObject, + IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode)); +#if 0 + if (DeviceObject == KeyboardFdo) + { + // it's keyboard's IOCTL + PIO_STACK_LOCATION Stk; + + Irp->IoStatus.Information = 0; + Stk = IoGetCurrentIrpStackLocation(Irp); + + switch (Stk->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_INTERNAL_KEYBOARD_CONNECT: + DPRINT("IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); + if (Stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) { + DPRINT1("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT " + "invalid buffer size\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + goto intcontfailure; + } + + RtlCopyMemory(&KbdClassInformation, + Stk->Parameters.DeviceIoControl.Type3InputBuffer, + sizeof(CONNECT_DATA)); + + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + + case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER: + DPRINT("IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER\n"); + if (Stk->Parameters.DeviceIoControl.InputBufferLength < 1) { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + goto intcontfailure; + } + /* if (!DevExt->KeyboardInterruptObject) { + Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; + goto intcontfailure; + }*/ + + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: + DPRINT("IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"); + if (Stk->Parameters.DeviceIoControl.OutputBufferLength < + sizeof(KEYBOARD_ATTRIBUTES)) { + DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES: " + "invalid buffer size\n"); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + goto intcontfailure; + } + /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, + &DevExt->KeyboardAttributes, + sizeof(KEYBOARD_ATTRIBUTES));*/ + + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + case IOCTL_KEYBOARD_QUERY_INDICATORS: + DPRINT("IOCTL_KEYBOARD_QUERY_INDICATORS\n"); + if (Stk->Parameters.DeviceIoControl.OutputBufferLength < + sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { + DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_INDICATORS: " + "invalid buffer size\n"); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + goto intcontfailure; + } + /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, + &DevExt->KeyboardIndicators, + sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/ + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + break; + case IOCTL_KEYBOARD_QUERY_TYPEMATIC: + DPRINT("IOCTL_KEYBOARD_QUERY_TYPEMATIC\n"); + if (Stk->Parameters.DeviceIoControl.OutputBufferLength < + sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) { + DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC: " + "invalid buffer size\n"); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + goto intcontfailure; + } + /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, + &DevExt->KeyboardTypematic, + sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/ + + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + case IOCTL_KEYBOARD_SET_INDICATORS: + DPRINT("IOCTL_KEYBOARD_SET_INDICATORS\n"); + if (Stk->Parameters.DeviceIoControl.InputBufferLength < + sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { + DPRINT("Keyboard IOCTL_KEYBOARD_SET_INDICTATORS: " + "invalid buffer size\n"); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + goto intcontfailure; + } + + /*RtlCopyMemory(&DevExt->KeyboardIndicators, + Irp->AssociatedIrp.SystemBuffer, + sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/ + + //DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags); + + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + case IOCTL_KEYBOARD_SET_TYPEMATIC: + DPRINT("IOCTL_KEYBOARD_SET_TYPEMATIC\n"); + if (Stk->Parameters.DeviceIoControl.InputBufferLength < + sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) { + DPRINT("Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC " + "invalid buffer size\n"); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + goto intcontfailure; + } + + /*RtlCopyMemory(&DevExt->KeyboardTypematic, + Irp->AssociatedIrp.SystemBuffer, + sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/ + + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: + /* We should check the UnitID, but it's kind of pointless as + * all keyboards are supposed to have the same one + */ + /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, + &IndicatorTranslation, + sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION));*/ + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + break; + case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: + /* Nothing to do here */ + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + default: + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + +intcontfailure: + Status = Irp->IoStatus.Status; + } + else if (DeviceObject == MouseFdo) + { + // it's mouse's IOCTL + PIO_STACK_LOCATION Stk; + + Irp->IoStatus.Information = 0; + Stk = IoGetCurrentIrpStackLocation(Irp); + + switch (Stk->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_INTERNAL_MOUSE_CONNECT: + DPRINT("IOCTL_INTERNAL_MOUSE_CONNECT\n"); + if (Stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) { + DPRINT1("IOCTL_INTERNAL_MOUSE_CONNECT: " + "invalid buffer size\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + goto intcontfailure2; + } + + RtlCopyMemory(&MouseClassInformation, + Stk->Parameters.DeviceIoControl.Type3InputBuffer, + sizeof(CONNECT_DATA)); + + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + + default: + Irp->IoStatus.Status = STATUS_SUCCESS;//STATUS_INVALID_DEVICE_REQUEST; + break; + } +intcontfailure2: + Status = Irp->IoStatus.Status; + } + else + { + return UsbMpPdoInternalDeviceControlCore(DeviceObject, Irp); + } + + + if (Status == STATUS_INVALID_DEVICE_REQUEST) { + DPRINT1("Invalid internal device request!\n"); + } + + if (Status != STATUS_PENDING) + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; + +#endif + + // Default handler + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS +AddRegistryEntry( + IN PCWSTR PortTypeName, + IN PUNICODE_STRING DeviceName, + IN PCWSTR RegistryPath) +{ + UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hDeviceMapKey = (HANDLE)-1; + HANDLE hPortKey = (HANDLE)-1; + UNICODE_STRING PortTypeNameU; + NTSTATUS Status; + + InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); + Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + usb_dbg_print(DBGLVL_MINIMUM, ("ZwOpenKey() failed with status 0x%08lx\n", Status)); + goto cleanup; + } + + RtlInitUnicodeString(&PortTypeNameU, PortTypeName); + InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL); + Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); + if (!NT_SUCCESS(Status)) + { + usb_dbg_print(DBGLVL_MINIMUM, ("ZwCreateKey() failed with status 0x%08lx\n", Status)); + goto cleanup; + } + + Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); + if (!NT_SUCCESS(Status)) + { + usb_dbg_print(DBGLVL_MINIMUM, ("ZwSetValueKey() failed with status 0x%08lx\n", Status)); + goto cleanup; + } + + Status = STATUS_SUCCESS; + +cleanup: + if (hDeviceMapKey != (HANDLE)-1) + ZwClose(hDeviceMapKey); + if (hPortKey != (HANDLE)-1) + ZwClose(hPortKey); + return Status; +} + +static NTSTATUS +MouseCreateDevice(IN PDRIVER_OBJECT DriverObject) +{ + UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerPortUSB"); + PDEVEXT_HEADER DeviceExtension; + PDEVICE_OBJECT Fdo; + NTSTATUS Status; + + Status = AddRegistryEntry(L"PointerPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbdriver"); + if (!NT_SUCCESS(Status)) + { + usb_dbg_print(DBGLVL_MINIMUM, ("AddRegistryEntry() for usb mouse driver failed with status 0x%08lx\n", Status)); + return Status; + } + + Status = IoCreateDevice(DriverObject, + sizeof(DEVEXT_HEADER), + &DeviceName, + FILE_DEVICE_MOUSE, + FILE_DEVICE_SECURE_OPEN, + TRUE, + &Fdo); + + if (!NT_SUCCESS(Status)) + { + usb_dbg_print(DBGLVL_MINIMUM, ("IoCreateDevice() for usb mouse driver failed with status 0x%08lx\n", Status)); + return Status; + } + DeviceExtension = (PDEVEXT_HEADER)Fdo->DeviceExtension; + RtlZeroMemory(DeviceExtension, sizeof(DEVEXT_HEADER)); + + DeviceExtension->dispatch = MouseDispatch; + + MouseFdo = Fdo; + Fdo->Flags &= ~DO_DEVICE_INITIALIZING; + usb_dbg_print(DBGLVL_MEDIUM, ("Created mouse Fdo: %p\n", Fdo)); + + return STATUS_SUCCESS; +} + From 1533a93526ebf6ddb88ff49c0ce2aeae6a3b787e Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 29 Sep 2006 17:34:50 +0000 Subject: [PATCH 373/488] add devmgmt.exe as it's usable in ROS now svn path=/trunk/; revision=24301 --- reactos/boot/bootdata/packages/reactos.dff | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index f58d4ae39fb..d077127e1b1 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -36,6 +36,7 @@ base\applications\cmdutils\find\find.exe 1 base\applications\cmdutils\more\more.exe 1 base\applications\control\control.exe 1 base\applications\devmgr\devmgrapp.exe 1 +base\applications\devmgmt\devmgmt.exe 1 base\applications\games\solitaire\sol.exe 1 base\applications\games\winemine\winemine.exe 1 base\applications\getfirefox\getfirefox.exe 1 From cad356e2d812edfebca01746399674a9a448ae2b Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 29 Sep 2006 17:57:20 +0000 Subject: [PATCH 374/488] Add devmgmt to the build system, thus fixing make bootcd svn path=/trunk/; revision=24302 --- reactos/base/applications/applications.rbuild | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reactos/base/applications/applications.rbuild b/reactos/base/applications/applications.rbuild index a2e60035dff..de108400735 100644 --- a/reactos/base/applications/applications.rbuild +++ b/reactos/base/applications/applications.rbuild @@ -10,6 +10,9 @@ + + + From 79e7a437857afdfb8cc7f82b1b58482516c1a1e3 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 29 Sep 2006 18:04:15 +0000 Subject: [PATCH 375/488] - update french timedate resource file - patch by Sylvain Petreolle svn path=/trunk/; revision=24303 --- reactos/dll/cpl/timedate/Fr.rc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/reactos/dll/cpl/timedate/Fr.rc b/reactos/dll/cpl/timedate/Fr.rc index 70a8f1c109a..86d278605fe 100644 --- a/reactos/dll/cpl/timedate/Fr.rc +++ b/reactos/dll/cpl/timedate/Fr.rc @@ -39,17 +39,17 @@ END IDD_INETTIMEPAGE DIALOGEX 0, 0, 252, 146 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Internet Time" +CAPTION "Temps Internet" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN COMBOBOX IDC_SERVERLIST, 65, 22, 117, 136, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Automatically synchronize with an Internet time server", IDC_AUTODAYLIGHT, + CONTROL "Synchroniser automatiquement avec un serveur d'heure Internet", IDC_AUTODAYLIGHT, "Button", BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,11,7,241,10 - LTEXT "Server:", -1, 34, 22, 28, 13 - PUSHBUTTON "Update Now", IDC_UPDATEBUTTON, 187, 22, 49, 14 + LTEXT "Serveur:", -1, 34, 22, 28, 13 + PUSHBUTTON "Mettre ŕ jour maintenant", IDC_UPDATEBUTTON, 187, 22, 49, 14 LTEXT "", IDC_SUCSYNC, 16, 54, 214, 23 LTEXT "", IDC_NEXTSYNC, 12, 96, 137, 12 - LTEXT "Synchronazation can only occur when your computer is connected to the internet.", -1, 12, 114, 225, 25 + LTEXT "La synchronisation ne peut se faire que si votre ordinateur est connecté ŕ Internet.", -1, 12, 114, 225, 25 END @@ -60,6 +60,6 @@ BEGIN IDS_TIMEZONETEXT "Fuseau horaire actuel: %s" IDS_TIMEZONEINVALID "Invalide" IDS_TIMEZONEUNKNOWN "Inconnu" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" - IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" + IDS_INETTIMESUCSYNC "L'heure a été synchronisée avec %s le %s ŕ %s" + IDS_INETTIMENEXTSYNC "Prochaine synchronisation: %s ŕ %s" END From 723627e679b2cbc22fc5149261428e6932314901 Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Sat, 30 Sep 2006 02:54:20 +0000 Subject: [PATCH 376/488] Merge 24208, 24236, 24242, and 24259 from trunk. LiveCD fixes. svn path=/branches/ros-branch-0_3_1/; revision=24304 --- reactos/Makefile | 4 ++++ reactos/config.rbuild | 4 ++-- reactos/tools/buildno/buildno.cpp | 37 +++++++++++++++++++++++-------- reactos/tools/mkhive/cmi.c | 2 +- reactos/tools/mkhive/mkhive.mak | 2 +- reactos/tools/mkhive/registry.c | 4 ++-- reactos/tools/mkhive/rtl.c | 24 +++++++++++++++++--- reactos/tools/widl/widl.mak | 2 +- 8 files changed, 60 insertions(+), 19 deletions(-) diff --git a/reactos/Makefile b/reactos/Makefile index 8ec2925c90c..b35d99fcce8 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -152,11 +152,15 @@ ifeq ($(word 1,$(shell gcc -dumpmachine)),mingw32) ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) export OSTYPE = msys HOST=mingw32-linux +CFLAGS+=-fshort-wchar +CPPFLAGS+=-fshort-wchar else HOST=mingw32-windows endif else HOST=mingw32-linux +CFLAGS+=-fshort-wchar +CPPFLAGS+=-fshort-wchar endif endif diff --git a/reactos/config.rbuild b/reactos/config.rbuild index f6678d2e32b..0f259c47349 100644 --- a/reactos/config.rbuild +++ b/reactos/config.rbuild @@ -44,14 +44,14 @@ - + - + diff --git a/reactos/hal/halx86/include/hal.h b/reactos/hal/halx86/include/hal.h index b15a4d9800d..fcac7ee8bdb 100644 --- a/reactos/hal/halx86/include/hal.h +++ b/reactos/hal/halx86/include/hal.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #define KPCR_BASE 0xFF000000 // HACK! diff --git a/reactos/hal/halx86/mp/halinit_mp.c b/reactos/hal/halx86/mp/halinit_mp.c index 8d48d8c2a63..9756923bb7b 100644 --- a/reactos/hal/halx86/mp/halinit_mp.c +++ b/reactos/hal/halx86/mp/halinit_mp.c @@ -22,7 +22,7 @@ ULONG_PTR KernelBase; /***************************************************************************/ VOID -HalpInitPhase0(PROS_LOADER_PARAMETER_BLOCK LoaderBlock) +HalpInitPhase0(PLOADER_PARAMETER_BLOCK LoaderBlock) { static BOOLEAN MPSInitialized = FALSE; @@ -35,7 +35,7 @@ HalpInitPhase0(PROS_LOADER_PARAMETER_BLOCK LoaderBlock) DPRINT("HalpInitPhase0()\n"); - if (MPSInitialized) + if (MPSInitialized) { KEBUGCHECK(0); } @@ -48,7 +48,7 @@ HalpInitPhase0(PROS_LOADER_PARAMETER_BLOCK LoaderBlock) } /* store the kernel base for later use */ - KernelBase = ((PLOADER_MODULE)LoaderBlock->ModsAddr)[0].ModStart; + KernelBase = (ULONG_PTR)CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks)->DllBase; } From fbe45c71809aa35c58cb161c7dc8ed248a0d57f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 30 Sep 2006 23:37:44 +0000 Subject: [PATCH 398/488] Give enough space to retrieve full device class description svn path=/trunk/; revision=24326 --- reactos/base/applications/devmgmt/enumdevices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/applications/devmgmt/enumdevices.c b/reactos/base/applications/devmgmt/enumdevices.c index eef1046b0d5..e56bcbf0f43 100644 --- a/reactos/base/applications/devmgmt/enumdevices.c +++ b/reactos/base/applications/devmgmt/enumdevices.c @@ -105,7 +105,7 @@ EnumDeviceClasses(INT ClassIndex, if (KeyClass != INVALID_HANDLE_VALUE) { - LONG dwSize = MAX_CLASS_NAME_LEN; + LONG dwSize = MAX_DEV_LEN; if (RegQueryValue(KeyClass, NULL, From 786ac12c99342fe6bba6ec85f7d237d4b6813537 Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Sun, 1 Oct 2006 04:47:34 +0000 Subject: [PATCH 399/488] Oops. I forgot the branch has a config.rbuild... svn path=/branches/ros-branch-0_3_1/; revision=24329 --- reactos/config.rbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/config.rbuild b/reactos/config.rbuild index c10cb253653..0f259c47349 100644 --- a/reactos/config.rbuild +++ b/reactos/config.rbuild @@ -67,6 +67,6 @@ enable this (except they/you purchased a license from the patent owner). This settings is disabled (0) by default. --> - + From 32b3c2fdf9e699aab3cc70c8cc146ca4fb5d2257 Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Sun, 1 Oct 2006 04:57:50 +0000 Subject: [PATCH 400/488] WaxDragon curses BrandonTurner. svn path=/branches/ros-branch-0_3_1/; revision=24330 --- reactos/config.rbuild | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/config.rbuild b/reactos/config.rbuild index 0f259c47349..f6678d2e32b 100644 --- a/reactos/config.rbuild +++ b/reactos/config.rbuild @@ -44,14 +44,14 @@ - + - + + -ffreestanding -fno-builtin -fno-inline @@ -67,7 +68,10 @@ video.c + conversion.c + peloader.c winldr.c + wlmemory.c freeldr.c debug.c diff --git a/reactos/boot/freeldr/freeldr/include/debug.h b/reactos/boot/freeldr/freeldr/include/debug.h index 07371aa32aa..848c9dd74f0 100644 --- a/reactos/boot/freeldr/freeldr/include/debug.h +++ b/reactos/boot/freeldr/freeldr/include/debug.h @@ -35,6 +35,7 @@ #define DPRINT_REACTOS 0x00000100 // OR this with DebugPrintMask to enable ReactOS messages #define DPRINT_LINUX 0x00000200 // OR this with DebugPrintMask to enable Linux messages #define DPRINT_HWDETECT 0x00000400 // OR this with DebugPrintMask to enable hardware detection messages + #define DPRINT_WINDOWS 0x00000800 // OR this with DebugPrintMask to enable messages from Windows loader VOID DebugInit(VOID); VOID DebugPrint(ULONG Mask, char *format, ...); diff --git a/reactos/boot/freeldr/freeldr/include/winldr.h b/reactos/boot/freeldr/freeldr/include/winldr.h index f3607fd29ba..c4c973ba59c 100644 --- a/reactos/boot/freeldr/freeldr/include/winldr.h +++ b/reactos/boot/freeldr/freeldr/include/winldr.h @@ -29,5 +29,49 @@ /////////////////////////////////////////////////////////////////////////////////////// VOID LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion); +/* Entry-point to kernel */ +typedef +VOID +NTAPI +(*KERNEL_ENTRY_POINT) (PLOADER_PARAMETER_BLOCK LoaderBlock); + + +// Some definitions +#define SECTOR_SIZE 512 + +// Descriptors +#define NUM_GDT 28 //15. The kernel wants 0xD8 as a last GDT entry offset +#define NUM_IDT 0x100 // only 16 are used though + +// conversion.c +PVOID VaToPa(PVOID Va); +PVOID PaToVa(PVOID Pa); +VOID List_PaToVa(LIST_ENTRY *ListEntry); +VOID ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start); + +// peloader.c +BOOLEAN +WinLdrLoadImage(IN PCHAR FileName, + OUT PVOID *ImageBasePA); + + +BOOLEAN +WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PCCH BaseDllName, + IN PCCH FullDllName, + IN PVOID BasePA, + OUT PLDR_DATA_TABLE_ENTRY *NewEntry); + +BOOLEAN +WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PCCH DirectoryPath, + IN PLDR_DATA_TABLE_ENTRY ScanDTE); + +// wlmemory.c +BOOLEAN +WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + ULONG PcrBasePage, + ULONG TssBasePage, + PVOID GdtIdt); #endif // defined __WINLDR_H diff --git a/reactos/boot/freeldr/freeldr/windows/conversion.c b/reactos/boot/freeldr/freeldr/windows/conversion.c new file mode 100644 index 00000000000..8d29c1eeba7 --- /dev/null +++ b/reactos/boot/freeldr/freeldr/windows/conversion.c @@ -0,0 +1,123 @@ +/* + * PROJECT: EFI Windows Loader + * LICENSE: GPL - See COPYING in the top level directory + * FILE: freeldr/winldr/conversion.c + * PURPOSE: Physical <-> Virtual addressing mode conversions + * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + */ + +/* INCLUDES ***************************************************************/ + +#include + +//#include + +#define NDEBUG +#include + +/* FUNCTIONS **************************************************************/ + +/* Arch-specific addresses translation implementation */ +PVOID +VaToPa(PVOID Va) +{ + return (PVOID)((ULONG_PTR)Va & ~KSEG0_BASE); +} + +PVOID +PaToVa(PVOID Pa) +{ + return (PVOID)((ULONG_PTR)Pa | KSEG0_BASE); +} + +VOID +List_PaToVa(LIST_ENTRY *ListEntry) +{ + LIST_ENTRY *ListHead = ListEntry; + LIST_ENTRY *Next = ListEntry->Flink; + LIST_ENTRY *NextPA; + + //Print(L"\n\nList_Entry: %X, First Next: %X\n", ListEntry, Next); + // + // Walk through the whole list + // + if (Next != NULL) + { + while (Next != PaToVa(ListHead)) + { + NextPA = VaToPa(Next); + //Print(L"Current: %X, Flink: %X, Blink: %X\n", Next, NextPA->Flink, NextPA->Blink); + + NextPA->Flink = PaToVa((PVOID)NextPA->Flink); + NextPA->Blink = PaToVa((PVOID)NextPA->Blink); + + //Print(L"After converting Flink: %X, Blink: %X\n", NextPA->Flink, NextPA->Blink); + + Next = NextPA->Flink; + } + + // + // Finally convert first Flink/Blink + // + ListEntry->Flink = PaToVa((PVOID)ListEntry->Flink); + if (ListEntry->Blink) + ListEntry->Blink = PaToVa((PVOID)ListEntry->Blink); + } +} + +// This function converts only Child->Child, and calls itself for each Sibling +VOID +ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start) +{ + PCONFIGURATION_COMPONENT_DATA Child; + PCONFIGURATION_COMPONENT_DATA Sibling; + + DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)", Start)); + Child = Start; + + while (Child != NULL) + { + if (Child->ConfigurationData) + Child->ConfigurationData = PaToVa(Child->ConfigurationData); + + if (Child->Child) + Child->Child = PaToVa(Child->Child); + + if (Child->Parent) + Child->Parent = PaToVa(Child->Parent); + + if (Child->Sibling) + Child->Sibling = PaToVa(Child->Sibling); + + DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Child, Child->ComponentEntry.Class)); + + // If the child has a sibling list, then search the sibling list + // for an entry that matches the specified class, type, and key. + Sibling = Child->Sibling; + while (Sibling != NULL) + { + if (Sibling->ConfigurationData) + Sibling->ConfigurationData = PaToVa(Sibling->ConfigurationData); + + if (Sibling->Child) + Sibling->Child = PaToVa(Sibling->Child); + + if (Sibling->Parent) + Sibling->Parent = PaToVa(Sibling->Parent); + + if (Sibling->Sibling) + Sibling->Sibling = PaToVa(Sibling->Sibling); + + DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Sibling, Sibling->ComponentEntry.Class)); + + // If the sibling has a child tree, then search the child tree + // for an entry that matches the specified class, type, and key. + if (VaToPa(Sibling->Child) != NULL) + ConvertConfigToVA(VaToPa(Sibling->Child)); + + Sibling = VaToPa(Sibling->Sibling); + } + + Child = VaToPa(Child->Child); + } +} diff --git a/reactos/boot/freeldr/freeldr/windows/peloader.c b/reactos/boot/freeldr/freeldr/windows/peloader.c new file mode 100644 index 00000000000..c8f58f32141 --- /dev/null +++ b/reactos/boot/freeldr/freeldr/windows/peloader.c @@ -0,0 +1,55 @@ +/* + * PROJECT: WinLoader + * LICENSE: GPL - See COPYING in the top level directory + * FILE: freeldr/winldr/peloader.c + * PURPOSE: Provides routines for loading PE files. To be merged with + * arch/i386/loader.c in future + * This article was very handy during development: + * http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/ + * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + * The source code in this file is based on the work of respective + * authors of PE loading code in ReactOS and Brian Palmer and + * Alex Ionescu's arch/i386/loader.c, and my research project + * (creating a native EFI loader for Windows) + */ + +/* INCLUDES ***************************************************************/ +#include + +#define NDEBUG +#include + +/* FUNCTIONS **************************************************************/ + +BOOLEAN +WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PCCH DirectoryPath, + IN PLDR_DATA_TABLE_ENTRY ScanDTE) +{ + return FALSE; +} + +BOOLEAN +WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PCCH BaseDllName, + IN PCCH FullDllName, + IN PVOID BasePA, + OUT PLDR_DATA_TABLE_ENTRY *NewEntry) +{ + return FALSE; +} + +/* WinLdrLoadImage loads the specified image from the file (it doesn't + perform any additional operations on the filename, just directly + calls the file I/O routines), and relocates it so that it's ready + to be used when paging is enabled. + Addressing mode: physical + */ +BOOLEAN +WinLdrLoadImage(IN PCHAR FileName, + OUT PVOID *ImageBasePA) +{ + return FALSE; +} + +/* PRIVATE FUNCTIONS *******************************************************/ diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index 6f20403b21f..45c86f4ee8c 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -24,13 +24,178 @@ #define NDEBUG #include +VOID DumpMemoryAllocMap(VOID); +VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); + VOID LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) { CHAR MsgBuffer[256]; + CHAR SystemPath[1024], SearchPath[1024]; + CHAR FileName[1024]; + CHAR BootPath[256]; + PVOID NtosBase = NULL, HalBase = NULL; + BOOLEAN Status; + ULONG SectionId; + ULONG BootDevice; + PLOADER_PARAMETER_BLOCK LoaderBlock=NULL, LoaderBlockVA; + PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE; + KERNEL_ENTRY_POINT KiSystemStartup; + // Mm-related things + PVOID GdtIdt=NULL; + ULONG PcrBasePage=0; + ULONG TssBasePage=0; - sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion); - UiMessageBox(MsgBuffer); + //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion); + //UiMessageBox(MsgBuffer); + + // + // Open the operating system section + // specified in the .ini file + // + if (!IniOpenSection(OperatingSystemName, &SectionId)) + { + sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName); + UiMessageBox(MsgBuffer); + return; + } + + /* + * Make sure the system path is set in the .ini file + */ + if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath))) + { + UiMessageBox("System path not specified for selected operating system."); + return; + } + + if (!MachDiskNormalizeSystemPath(SystemPath, + sizeof(SystemPath))) + { + UiMessageBox("Invalid system path"); + return; + } + + UiDrawStatusText("Loading..."); + + /* + * Try to open system drive + */ + BootDevice = 0xffffffff; + if (!FsOpenSystemVolume(SystemPath, BootPath, &BootDevice)) + { + UiMessageBox("Failed to open boot drive."); + return; + } + + /* append a backslash */ + if ((strlen(BootPath)==0) || + BootPath[strlen(BootPath)] != '\\') + strcat(BootPath, "\\"); + + DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath)); + + /* Allocate and minimalistic-initialize LPB */ + //AllocateAndInitLPB(&LoaderBlock); + + // Load kernel + strcpy(FileName, BootPath); + strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE"); + Status = WinLdrLoadImage(FileName, &NtosBase); + DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d\n", Status)); + + // Load HAL + strcpy(FileName, BootPath); + strcat(FileName, "SYSTEM32\\HAL.DLL"); + Status = WinLdrLoadImage(FileName, &HalBase); + DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d\n", Status)); + + WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe", + "WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE); + WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll", + "WINNT\\SYSTEM32\\HAL.EXE", HalBase, &HalDTE); + + /* Load all referenced DLLs for kernel and HAL */ + strcpy(SearchPath, BootPath); + strcat(SearchPath, "SYSTEM32\\"); + WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KernelDTE); + WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE); + + /* Initialize Phase 1 - before NLS */ + //WinLdrInitializePhase1(LoaderBlock); + + /* Load SYSTEM hive and its LOG file */ + strcpy(SearchPath, BootPath); + strcat(SearchPath, "SYSTEM32\\CONFIG\\"); + //Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM"); + DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status)); + + /* Load NLS data */ + strcpy(SearchPath, BootPath); + strcat(SearchPath, "SYSTEM32\\"); + //Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, + // "c_1252.nls", "c_437.nls", "l_intl.nls"); + DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status)); + + /* Load OEM HAL font */ + + /* Load boot drivers */ + + /* Alloc PCR, TSS, do magic things with the GDT/IDT */ + //WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage); + + /* Save entry-point pointer (VA) */ + KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint; + LoaderBlockVA = PaToVa(LoaderBlock); + + /* Debugging... */ + //DumpMemoryAllocMap(); + + /* Turn on paging mode of CPU*/ + WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt); + + DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n", + KiSystemStartup, LoaderBlockVA)); + + WinLdrpDumpMemoryDescriptors(LoaderBlockVA); + + /*__asm + { + or esp, KSEG0_BASE; + or ebp, KSEG0_BASE; + }*/ + + /* + { + ULONG *trrr = (ULONG *)(512*1024*1024); + + *trrr = 0x13131414; + } + + //FIXME! + while (1) {};*/ + + (KiSystemStartup)(LoaderBlockVA); return; } + +VOID +WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PLIST_ENTRY NextMd; + PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor; + + NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; + + while (NextMd != &LoaderBlock->MemoryDescriptorListHead) + { + MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry); + + + DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage, + MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType)); + + NextMd = MemoryDescriptor->ListEntry.Flink; + } +} diff --git a/reactos/boot/freeldr/freeldr/windows/wlmemory.c b/reactos/boot/freeldr/freeldr/windows/wlmemory.c new file mode 100644 index 00000000000..a9393a6e98f --- /dev/null +++ b/reactos/boot/freeldr/freeldr/windows/wlmemory.c @@ -0,0 +1,35 @@ +/* + * PROJECT: EFI Windows Loader + * LICENSE: GPL - See COPYING in the top level directory + * FILE: freeldr/winldr/wlmemory.c + * PURPOSE: Memory related routines + * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + */ + +/* INCLUDES ***************************************************************/ + +#include + +#include + +#define NDEBUG +#include + +// This is needed because headers define wrong one for ReactOS +#undef KIP0PCRADDRESS +#define KIP0PCRADDRESS 0xffdff000 + +#define HYPER_SPACE_ENTRY 0x300 + +/* GLOBALS ***************************************************************/ + +/* FUNCTIONS **************************************************************/ + +BOOLEAN +WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + ULONG PcrBasePage, + ULONG TssBasePage, + PVOID GdtIdt) +{ + return FALSE; +} From 2855e1f08f13131e27499e01dbe8d9b4adf2eceb Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 1 Oct 2006 19:43:18 +0000 Subject: [PATCH 420/488] - Do MmInit1 in KiInitializeKernel so we can access SharedUserData from it (we'll need to setup the CPU Features there). - Cleanup some external/prototype mess and put them nicely into headers. svn path=/trunk/; revision=24351 --- reactos/ntoskrnl/ex/init.c | 64 ++------------------------ reactos/ntoskrnl/include/internal/ke.h | 6 +++ reactos/ntoskrnl/include/internal/ps.h | 6 +++ reactos/ntoskrnl/ke/clock.c | 1 - reactos/ntoskrnl/ke/i386/kiinit.c | 12 ++++- 5 files changed, 28 insertions(+), 61 deletions(-) diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index e48b6581727..1ee785e56a4 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -24,35 +24,18 @@ ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(4, 0); ULONG NtBuildNumber = KERNEL_VERSION_BUILD; ULONG NtGlobalFlag = 0; -ULONG InitSafeBootMode = 0; /* KB83764 */ - extern ULONG MmCoreDumpType; -extern CHAR KiTimerSystemAuditing; -extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS]; -extern ADDRESS_RANGE KeMemoryMap[64]; -extern ULONG KeMemoryMapRangeCount; -extern ULONG_PTR FirstKrnlPhysAddr; -extern ULONG_PTR LastKrnlPhysAddr; -extern ULONG_PTR LastKernelAddress; extern LOADER_MODULE KeLoaderModules[64]; extern ULONG KeLoaderModuleCount; extern PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages; - BOOLEAN NoGuiBoot = FALSE; -static BOOLEAN BootLog = FALSE; -static ULONG MaxMem = 0; static BOOLEAN ForceAcpiDisable = FALSE; -BOOLEAN -NTAPI -PspInitPhase0( - VOID -); - /* Init flags and settings */ ULONG ExpInitializationPhase; BOOLEAN ExpInTextModeSetup; BOOLEAN IoRemoteBootClient; +ULONG InitSafeBootMode; /* Boot NLS information */ PVOID ExpNlsTableBase; @@ -251,9 +234,7 @@ InitSystemSharedUserPage (PCSZ ParameterLine) __inline VOID STDCALL -ParseCommandLine(PULONG MaxMem, - PBOOLEAN NoGuiBoot, - PBOOLEAN BootLog, +ParseCommandLine(PBOOLEAN NoGuiBoot, PBOOLEAN ForceAcpiDisable) { PCHAR p1, p2; @@ -262,26 +243,7 @@ ParseCommandLine(PULONG MaxMem, while(*p1 && (p2 = strchr(p1, '/'))) { p2++; - if (!_strnicmp(p2, "MAXMEM", 6)) { - - p2 += 6; - while (isspace(*p2)) p2++; - - if (*p2 == '=') { - - p2++; - - while(isspace(*p2)) p2++; - - if (isdigit(*p2)) { - while (isdigit(*p2)) { - *MaxMem = *MaxMem * 10 + *p2 - '0'; - p2++; - } - break; - } - } - } else if (!_strnicmp(p2, "NOGUIBOOT", 9)) { + if (!_strnicmp(p2, "NOGUIBOOT", 9)) { p2 += 9; *NoGuiBoot = TRUE; @@ -301,10 +263,6 @@ ParseCommandLine(PULONG MaxMem, MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE; } } - } else if (!_strnicmp(p2, "BOOTLOG", 7)) { - - p2 += 7; - *BootLog = TRUE; } else if (!_strnicmp(p2, "NOACPI", 6)) { p2 += 6; @@ -514,19 +472,8 @@ ExpInitializeExecutive(IN ULONG Cpu, { PNLS_DATA_BLOCK NlsData; - /* Initialize Kernel Memory Address Space */ - MmInit1(FirstKrnlPhysAddr, - LastKrnlPhysAddr, - LastKernelAddress, - (PADDRESS_RANGE)&KeMemoryMap, - KeMemoryMapRangeCount, - MaxMem > 8 ? MaxMem : 4096); - - /* Sets up the Text Sections of the Kernel and HAL for debugging */ - LdrInit1(); - /* Parse Command Line Settings */ - ParseCommandLine(&MaxMem, &NoGuiBoot, &BootLog, &ForceAcpiDisable); + ParseCommandLine(&NoGuiBoot, &ForceAcpiDisable); /* FIXME: Deprecate soon */ ParseAndCacheLoadedModules(); @@ -726,7 +673,7 @@ ExPhase2Init(PVOID Context) DbgBreakPoint(); /* Setup Drivers and Root Device Node */ - IoInit2(BootLog); + IoInit2(FALSE); /* Display the boot screen image if not disabled */ if (!NoGuiBoot) InbvEnableBootDriver(TRUE); @@ -826,7 +773,6 @@ ExPhase2Init(PVOID Context) } /* Enable the Clock, close remaining handles */ - KiTimerSystemAuditing = 1; ZwClose(ThreadHandle); ZwClose(ProcessHandle); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index bde53e3aa71..d901f374913 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -67,6 +67,12 @@ struct _KPCR; struct _KPRCB; struct _KEXCEPTION_FRAME; +extern ADDRESS_RANGE KeMemoryMap[64]; +extern ULONG KeMemoryMapRangeCount; +extern ULONG_PTR FirstKrnlPhysAddr; +extern ULONG_PTR LastKrnlPhysAddr; +extern ULONG_PTR LastKernelAddress; + extern PVOID KeUserApcDispatcher; extern PVOID KeUserCallbackDispatcher; extern PVOID KeUserExceptionDispatcher; diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index 60d3acfed36..e62e472242d 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -79,6 +79,12 @@ PspShutdownProcessManager( VOID ); +BOOLEAN +NTAPI +PspInitPhase0( + VOID +); + // // Utility Routines // diff --git a/reactos/ntoskrnl/ke/clock.c b/reactos/ntoskrnl/ke/clock.c index 2bca7c9f630..e294543a093 100644 --- a/reactos/ntoskrnl/ke/clock.c +++ b/reactos/ntoskrnl/ke/clock.c @@ -35,7 +35,6 @@ LARGE_INTEGER SystemBootTime = (LARGE_INTEGER)0LL; LARGE_INTEGER SystemBootTime = { 0 }; #endif -CHAR KiTimerSystemAuditing = 0; KDPC KiExpireTimerDpc; BOOLEAN KiClockSetupComplete = FALSE; diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index dba13f77e54..8e4f8112349 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -11,7 +11,6 @@ #include #define NDEBUG #include -#include /* GLOBALS *******************************************************************/ @@ -164,6 +163,17 @@ KiInitializeKernel(IN PKPROCESS InitProcess, DPRINT1("SMP Boot support not yet present\n"); } + /* Initialize Kernel Memory Address Space */ + MmInit1(FirstKrnlPhysAddr, + LastKrnlPhysAddr, + LastKernelAddress, + (PADDRESS_RANGE)&KeMemoryMap, + KeMemoryMapRangeCount, + 4096); + + /* Sets up the Text Sections of the Kernel and HAL for debugging */ + LdrInit1(); + /* Setup the Idle Thread */ KeInitializeThread(InitProcess, InitThread, From 0c1b724e798d551d34c916e52f412c6a15978ead Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 1 Oct 2006 20:27:36 +0000 Subject: [PATCH 421/488] - Un-optimize KeGetPcr and make it use fs:20h instead of hard-coding the 0xFF.... address, because someone decided that ROS should have a different KPCR address then NT. - This gets NTLDR working with ReactOS and I can boot all the way to MmInit1 (which fails due to missing KeMemoryMap & freeldr data). - Serial port output works with DPRINT1 as well ;-) svn path=/trunk/; revision=24352 --- reactos/hal/halx86/generic/processor.c | 8 ++++---- reactos/include/ndk/ketypes.h | 4 ++++ reactos/ntoskrnl/kd/kdinit.c | 9 +++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/reactos/hal/halx86/generic/processor.c b/reactos/hal/halx86/generic/processor.c index f2b3a60d892..c93778751ff 100644 --- a/reactos/hal/halx86/generic/processor.c +++ b/reactos/hal/halx86/generic/processor.c @@ -20,11 +20,11 @@ /* FUNCTIONS *****************************************************************/ -VOID STDCALL -HalInitializeProcessor(ULONG ProcessorNumber, - PLOADER_PARAMETER_BLOCK LoaderBlock) +VOID +NTAPI +HalInitializeProcessor(IN ULONG ProcessorNumber, + IN PLOADER_PARAMETER_BLOCK LoaderBlock) { - DPRINT("HalInitializeProcessor(%lu %p)\n", ProcessorNumber, LoaderBlock); /* Set default IDR */ KeGetPcr()->IDR = 0xFFFFFFFB; KeGetPcr()->StallScaleFactor = INITIAL_STALL_COUNT; diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index 6c8e9ce3f11..9ed3830f458 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -92,7 +92,11 @@ Author: // #define K0IPCR ((ULONG_PTR)(KIP0PCRADDRESS)) #define PCR ((volatile KPCR * const)K0IPCR) +#ifdef _WE_USE_THE_SAME_PCR_ADDRESS #define KeGetPcr() PCR +#else +#define KeGetPcr() ((volatile KPCR * const)__readfsdword(0x1C)) +#endif // // Number of dispatch codes supported by KINTERRUPT diff --git a/reactos/ntoskrnl/kd/kdinit.c b/reactos/ntoskrnl/kd/kdinit.c index 26fed4a47f7..71655be72c2 100644 --- a/reactos/ntoskrnl/kd/kdinit.c +++ b/reactos/ntoskrnl/kd/kdinit.c @@ -168,6 +168,15 @@ KdInitSystem(ULONG BootPhase, ULONG i; PCHAR p1, p2; +#if 0 + /* NTLDR HACK */ + KdpSerialInit(&DispatchTable[KdSerial], 0); + KdpDebugMode.Serial = TRUE; + SerialPortInfo.ComPort = 1; + KdpPort = 1; + KdDebuggerEnabled = TRUE; +#endif + /* Set Default Port Options */ if (BootPhase == 0) { From eb998b4eaf0a339812c7852ce4bfec3f968839de Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 1 Oct 2006 21:07:25 +0000 Subject: [PATCH 422/488] - Comment out xbox memory detection for now (until fully switched to NT-style LPB) - Fix HalpInitializePhase0() prototype - Add halxbox back to build svn path=/trunk/; revision=24353 --- reactos/hal/halx86/directory.rbuild | 4 ++-- reactos/hal/halx86/xbox/display_xbox.c | 6 ++++-- reactos/hal/halx86/xbox/halinit_xbox.c | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/reactos/hal/halx86/directory.rbuild b/reactos/hal/halx86/directory.rbuild index c92f9b7f41c..5303d6cd7a9 100644 --- a/reactos/hal/halx86/directory.rbuild +++ b/reactos/hal/halx86/directory.rbuild @@ -7,6 +7,6 @@ - + diff --git a/reactos/hal/halx86/xbox/display_xbox.c b/reactos/hal/halx86/xbox/display_xbox.c index be52bd2a5fb..7cf157109ac 100644 --- a/reactos/hal/halx86/xbox/display_xbox.c +++ b/reactos/hal/halx86/xbox/display_xbox.c @@ -301,11 +301,13 @@ HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock) if (! DisplayInitialized) { PhysBuffer.u.HighPart = 0; - if (0 != (LoaderBlock->Flags & MB_FLAGS_MEM_INFO)) + //FIXME: We always assume 64Mb Xbox for now, until switch to + // NT-style LPB is finished + /*if (0 != (LoaderBlock->Flags & MB_FLAGS_MEM_INFO)) { PhysBuffer.u.LowPart = (LoaderBlock->MemHigher + 1024) * 1024; } - else + else*/ { /* Assume a 64Mb Xbox, last 4MB for video buf */ PhysBuffer.u.LowPart = 60 * 1024 * 1024; diff --git a/reactos/hal/halx86/xbox/halinit_xbox.c b/reactos/hal/halx86/xbox/halinit_xbox.c index ddcec9f45e2..c18d48c2495 100644 --- a/reactos/hal/halx86/xbox/halinit_xbox.c +++ b/reactos/hal/halx86/xbox/halinit_xbox.c @@ -19,7 +19,7 @@ /* FUNCTIONS ***************************************************************/ VOID -HalpInitPhase0(PROS_LOADER_PARAMETER_BLOCK LoaderBlock) +HalpInitPhase0(PLOADER_PARAMETER_BLOCK LoaderBlock) { HalpHooks.InitPciBus = HalpXboxInitPciBus; From 5cf4352021d3370a05c8cbec743250e33a889f0a Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 1 Oct 2006 21:15:15 +0000 Subject: [PATCH 423/488] - Implement loading of NLS data, SYSTEM hive data (just simple loading into memory, without any kind of parsing or even checking if that data is correct) - Add a function for creating a stub of hardware config (config consisting of only one node - root) - Implement two steps of LPB initialization (names Phase 0 and Phase 1 are used internally by me, and doesn't correspond to anything) - Implement a WinLdrSetupForNt, which allocates and initializes some specific structures (PCR, TSS, GDT, IDT) - Respectively enable calls to these functions from LoadAndBootWindows() svn path=/trunk/; revision=24354 --- reactos/boot/freeldr/freeldr/windows/winldr.c | 428 +++++++++++++++++- 1 file changed, 422 insertions(+), 6 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index 45c86f4ee8c..89dae9c925e 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -27,6 +27,422 @@ VOID DumpMemoryAllocMap(VOID); VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); +BOOLEAN +WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath, + IN LPCSTR AnsiFileName, + IN LPCSTR OemFileName, + IN LPCSTR LanguageFileName) +{ + CHAR FileName[255]; + PFILE AnsiFileHandle; + PFILE OemFileHandle; + PFILE LanguageFileHandle; + ULONG AnsiFileSize, OemFileSize, LanguageFileSize; + ULONG TotalSize; + ULONG_PTR NlsDataBase; + PVOID NlsVirtual; + BOOLEAN Status, AnsiEqualsOem = FALSE; + + /* There may be a case, when OEM and ANSI page coincide */ + if (!strcmp(AnsiFileName, OemFileName)) + AnsiEqualsOem = TRUE; + + /* Open file with ANSI and store its size */ + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, AnsiFileName); + AnsiFileHandle = FsOpenFile(FileName); + + if (AnsiFileHandle == NULL) + goto Failure; + + AnsiFileSize = FsGetFileSize(AnsiFileHandle); + DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize)); + FsCloseFile(AnsiFileHandle); + + /* Open OEM file and store its length */ + if (AnsiEqualsOem) + { + OemFileSize = 0; + } + else + { + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, OemFileName); + OemFileHandle = FsOpenFile(FileName); + + if (OemFileHandle == NULL) + goto Failure; + + OemFileSize = FsGetFileSize(OemFileHandle); + FsCloseFile(OemFileHandle); + } + DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize)); + + /* And finally open the language codepage file and store its length */ + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, LanguageFileName); + LanguageFileHandle = FsOpenFile(FileName); + + if (LanguageFileHandle == NULL) + goto Failure; + + LanguageFileSize = FsGetFileSize(LanguageFileHandle); + FsCloseFile(LanguageFileHandle); + DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize)); + + /* Sum up all three length, having in mind that every one of them + must start at a page boundary => thus round up each file to a page */ + TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + + MM_SIZE_TO_PAGES(OemFileSize) + + MM_SIZE_TO_PAGES(LanguageFileSize); + + NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); + + if (NlsDataBase == 0) + goto Failure; + + NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase); + LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; + LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); + LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + + (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); + + /* Ansi and OEM data are the same - just set pointers to the same area */ + if (AnsiEqualsOem) + LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; + + + /* Now actually read the data into memory, starting with Ansi file */ + strcpy(FileName, DirectoryPath); + strcat(FileName, AnsiFileName); + AnsiFileHandle = FsOpenFile(FileName); + + if (AnsiFileHandle == NULL) + goto Failure; + + Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(AnsiFileHandle); + + /* OEM now, if it doesn't equal Ansi of course */ + if (!AnsiEqualsOem) + { + strcpy(FileName, DirectoryPath); + strcat(FileName, OemFileName); + OemFileHandle = FsOpenFile(FileName); + + if (OemFileHandle == NULL) + goto Failure; + + Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(AnsiFileHandle); + } + + /* finally the language file */ + strcpy(FileName, DirectoryPath); + strcat(FileName, LanguageFileName); + LanguageFileHandle = FsOpenFile(FileName); + + if (LanguageFileHandle == NULL) + goto Failure; + + Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(LanguageFileHandle); + + // + // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK + // Should go to WinLdrLoadOemHalFont(), when it will be implemented + // + LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); + + /* Convert NlsTables address to VA */ + LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); + + return TRUE; + +Failure: + //UiMessageBox("Error reading NLS file %s\n", Filename); + UiMessageBox("Error reading NLS file!"); + return FALSE; +} + +BOOLEAN +WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath, + IN LPCSTR HiveName) +{ + PFILE FileHandle; + CHAR FullHiveName[256]; + BOOLEAN Status; + ULONG HiveFileSize; + ULONG_PTR HiveDataPhysical; + PVOID HiveDataVirtual; + + /* Concatenate path and filename to get the full name */ + strcpy(FullHiveName, DirectoryPath); + strcat(FullHiveName, HiveName); + //Print(L"Loading %s...\n", FullHiveName); + FileHandle = FsOpenFile(FullHiveName); + + if (FileHandle == NULL) + { + UiMessageBox("Opening hive file failed!"); + return FALSE; + } + + /* Get the file length */ + HiveFileSize = FsGetFileSize(FileHandle); + + if (HiveFileSize == 0) + { + FsCloseFile(FileHandle); + UiMessageBox("Hive file has 0 size!"); + return FALSE; + } + + /* Round up the size to page boundary and alloc memory */ + HiveDataPhysical = (ULONG_PTR)MmAllocateMemory( + MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT); + + if (HiveDataPhysical == 0) + { + FsCloseFile(FileHandle); + UiMessageBox("Unable to alloc memory for a hive!"); + return FALSE; + } + + /* Convert address to virtual */ + HiveDataVirtual = (PVOID)(KSEG0_BASE | HiveDataPhysical); + + /* Fill LoaderBlock's entries */ + LoaderBlock->RegistryLength = HiveFileSize; + LoaderBlock->RegistryBase = HiveDataVirtual; + + /* Finally read from file to the memory */ + Status = FsReadFile(FileHandle, HiveFileSize, NULL, (PVOID)HiveDataPhysical); + FsCloseFile(FileHandle); + if (!Status) + { + UiMessageBox("Unable to read from hive file!"); + return FALSE; + } + + return TRUE; +} + +void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PCONFIGURATION_COMPONENT_DATA ConfigurationRoot; + PCONFIGURATION_COMPONENT Component; + PCONFIGURATION_COMPONENT_DATA /*CurrentEntry,*/ PreviousEntry, AdapterEntry; + BOOLEAN IsNextEntryChild; + + DbgPrint((DPRINT_WINDOWS, "InitializeHWConfig()\n")); + + LoaderBlock->ConfigurationRoot = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + RtlZeroMemory(LoaderBlock->ConfigurationRoot, sizeof(CONFIGURATION_COMPONENT_DATA)); + + /* Fill root == SystemClass */ + ConfigurationRoot = LoaderBlock->ConfigurationRoot; + Component = &LoaderBlock->ConfigurationRoot->ComponentEntry; + + Component->Class = SystemClass; + Component->Type = MaximumType; + Component->Version = 0; // FIXME: ? + Component->Key = 0; + Component->AffinityMask = 0; + + IsNextEntryChild = TRUE; + PreviousEntry = ConfigurationRoot; + + /* Enumerate all PCI buses */ + AdapterEntry = ConfigurationRoot; + + /* TODO: Disk Geometry */ + /* TODO: Keyboard */ + + /* TODO: Serial port */ + + //Config->ConfigurationData = alloc(sizeof(CONFIGURATION_COMPONENT_DATA), EfiLoaderData); + + /* Convert everything to VA */ + ConvertConfigToVA(LoaderBlock->ConfigurationRoot); + LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot); +} + + +// Init "phase 0" +VOID +AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock) +{ + PLOADER_PARAMETER_BLOCK LoaderBlock; + + /* Allocate and zero-init the LPB */ + LoaderBlock = MmAllocateMemory(sizeof(LOADER_PARAMETER_BLOCK)); + RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK)); + + /* Init three critical lists, used right away */ + InitializeListHead(&LoaderBlock->LoadOrderListHead); + InitializeListHead(&LoaderBlock->MemoryDescriptorListHead); + InitializeListHead(&LoaderBlock->BootDriverListHead); + + + *OutLoaderBlock = LoaderBlock; +} + +// Init "phase 1" +VOID +WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + //CHAR Options[] = "/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200"; + CHAR Options[] = "/NODEBUG"; + CHAR SystemRoot[] = "\\WINNT"; + CHAR HalPath[] = "\\"; + CHAR ArcBoot[] = "multi(0)"; + CHAR ArcHal[] = "multi(0)"; + + PLOADER_PARAMETER_EXTENSION Extension; + + LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support + + /* Fill Arc BootDevice */ + LoaderBlock->ArcBootDeviceName = MmAllocateMemory(strlen(ArcBoot)+1); + strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot); + LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName); + + /* Fill Arc HalDevice */ + LoaderBlock->ArcHalDeviceName = MmAllocateMemory(strlen(ArcHal)+1); + strcpy(LoaderBlock->ArcHalDeviceName, ArcHal); + LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName); + + /* Fill SystemRoot */ + LoaderBlock->NtBootPathName = MmAllocateMemory(strlen(SystemRoot)+1); + strcpy(LoaderBlock->NtBootPathName, SystemRoot); + LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName); + + /* Fill NtHalPathName */ + LoaderBlock->NtHalPathName = MmAllocateMemory(strlen(HalPath)+1); + strcpy(LoaderBlock->NtHalPathName, HalPath); + LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName); + + /* Fill load options */ + LoaderBlock->LoadOptions = MmAllocateMemory(strlen(Options)+1); + strcpy(LoaderBlock->LoadOptions, Options); + LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions); + + /* Arc devices */ + LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION)); + InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); + List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); + LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation); + + /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */ + LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK)); + if (LoaderBlock->NlsData == NULL) + { + UiMessageBox("Failed to allocate memory for NLS table data!"); + return; + } + RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK)); + + /* Create configuration entries */ + InitializeHWConfig(LoaderBlock); + + /* Convert all DTE into virtual addresses */ + //TODO: !!! + + /* Convert all list's to Virtual address */ + List_PaToVa(&LoaderBlock->LoadOrderListHead); + + /* this one will be converted right before switching to + virtual paging mode */ + //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead); + + List_PaToVa(&LoaderBlock->BootDriverListHead); + + /* Initialize Extension now */ + Extension = MmAllocateMemory(sizeof(LOADER_PARAMETER_EXTENSION)); + if (Extension == NULL) + { + UiMessageBox("Failed to allocate LPB Extension!"); + return; + } + RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION)); + + Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION); + Extension->MajorVersion = 4; + Extension->MinorVersion = 0; + + + LoaderBlock->Extension = PaToVa(Extension); +} + +// Last step before going virtual +void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock, + PVOID *GdtIdt, + ULONG *PcrBasePage, + ULONG *TssBasePage) +{ + ULONG TssSize; + ULONG TssPages; + ULONG_PTR Pcr = 0; + ULONG_PTR Tss = 0; + ULONG BlockSize, NumPages; + + LoaderBlock->u.I386.CommonDataArea = NULL;//CommonDataArea; + //LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType? + + /* Allocate 2 pages for PCR */ + Pcr = (ULONG_PTR)MmAllocateMemory(2 * MM_PAGE_SIZE); + *PcrBasePage = Pcr >> MM_PAGE_SHIFT; + + if (Pcr == 0) + { + UiMessageBox("Can't allocate PCR\n"); + return; + } + + /* Allocate TSS */ + TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1); + TssPages = TssSize / MM_PAGE_SIZE; + + Tss = (ULONG_PTR)MmAllocateMemory(TssSize); + + *TssBasePage = Tss >> MM_PAGE_SHIFT; + + /* Allocate space for new GDT + IDT */ + BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here? + NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT; + *GdtIdt = (PKGDTENTRY)MmAllocateMemory(NumPages * MM_PAGE_SIZE); + + if (*GdtIdt == NULL) + { + UiMessageBox("Can't allocate pages for GDT+IDT!\n"); + return; + } + + /* Zero newly prepared GDT+IDT */ + RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT); +} + + VOID LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) { @@ -96,7 +512,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath)); /* Allocate and minimalistic-initialize LPB */ - //AllocateAndInitLPB(&LoaderBlock); + AllocateAndInitLPB(&LoaderBlock); // Load kernel strcpy(FileName, BootPath); @@ -122,19 +538,19 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE); /* Initialize Phase 1 - before NLS */ - //WinLdrInitializePhase1(LoaderBlock); + WinLdrInitializePhase1(LoaderBlock); /* Load SYSTEM hive and its LOG file */ strcpy(SearchPath, BootPath); strcat(SearchPath, "SYSTEM32\\CONFIG\\"); - //Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM"); + Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM"); DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status)); /* Load NLS data */ strcpy(SearchPath, BootPath); strcat(SearchPath, "SYSTEM32\\"); - //Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, - // "c_1252.nls", "c_437.nls", "l_intl.nls"); + Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, + "c_1252.nls", "c_437.nls", "l_intl.nls"); DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status)); /* Load OEM HAL font */ @@ -142,7 +558,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) /* Load boot drivers */ /* Alloc PCR, TSS, do magic things with the GDT/IDT */ - //WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage); + WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage); /* Save entry-point pointer (VA) */ KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint; From 5c112af711c90a908d8d1e0e6fe7788c2da89508 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 1 Oct 2006 21:48:05 +0000 Subject: [PATCH 424/488] - Add a check to the boot.ini-changing code, to prevent creation of a new ReactOS entry after each installation. svn path=/trunk/; revision=24356 --- reactos/base/setup/usetup/bootsup.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/reactos/base/setup/usetup/bootsup.c b/reactos/base/setup/usetup/bootsup.c index 3ee55733f9f..4e5b0d721f7 100644 --- a/reactos/base/setup/usetup/bootsup.c +++ b/reactos/base/setup/usetup/bootsup.c @@ -1665,6 +1665,7 @@ UpdateBootIni(PWSTR BootIniPath, PINICACHESECTION Section = NULL; NTSTATUS Status; ULONG FileAttribute; + PWCHAR OldValue = NULL; RtlInitUnicodeString(&Name, BootIniPath); @@ -1685,11 +1686,20 @@ UpdateBootIni(PWSTR BootIniPath, return(STATUS_UNSUCCESSFUL); } - IniCacheInsertKey(Section, + /* Check - maybe record already exists */ + Status = IniCacheGetKey(Section, + EntryName, + &OldValue); + + /* If either key was not found, or contains something else - add new one */ + if (!NT_SUCCESS(Status) || wcscmp(OldValue, EntryValue)) + { + IniCacheInsertKey(Section, NULL, INSERT_LAST, EntryName, EntryValue); + } Status = UnprotectBootIni(BootIniPath, &FileAttribute); From 7fcf928e38dc5913442c09aabc9979726aa9cfaa Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 2 Oct 2006 05:40:36 +0000 Subject: [PATCH 425/488] - Continue implementation of KiRosFrldrLpbToNtLpb by parsing the FreeLDR command line and: * Removing the ARC Boot path and splitting it into the ARC Boot Device Name, the ARC HAL Device Name, and the NT Boot and HAL Path Names, saved in their respective LoaderBlock pointers. * Converting every slash to a space. ("/DEBUGPORT" -> " DEBUGPORT") * Now we can fully parse and read NTLDR command lines. - Update various code in the kernel to: * Use LoaderBlock->ArcDeviceNamePath & friends instead of the command line. * Stop depending on slashes, and instead use strstr for parameters. svn path=/trunk/; revision=24358 --- reactos/ntoskrnl/ex/init.c | 91 ++-------------- reactos/ntoskrnl/include/internal/io.h | 2 +- reactos/ntoskrnl/include/internal/po.h | 2 +- reactos/ntoskrnl/io/iomgr/arcname.c | 41 ++------ reactos/ntoskrnl/io/iomgr/iomgr.c | 2 +- reactos/ntoskrnl/kd/kdinit.c | 137 ++++++++++++------------- reactos/ntoskrnl/kd/kdio.c | 9 +- reactos/ntoskrnl/ke/freeldr.c | 36 +++++++ reactos/ntoskrnl/po/power.c | 13 ++- 9 files changed, 143 insertions(+), 190 deletions(-) diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 1ee785e56a4..4f07213eddd 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -29,7 +29,6 @@ extern LOADER_MODULE KeLoaderModules[64]; extern ULONG KeLoaderModuleCount; extern PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages; BOOLEAN NoGuiBoot = FALSE; -static BOOLEAN ForceAcpiDisable = FALSE; /* Init flags and settings */ ULONG ExpInitializationPhase; @@ -48,7 +47,7 @@ NLSTABLEINFO ExpNlsTableInfo; static VOID INIT_FUNCTION -InitSystemSharedUserPage (PCSZ ParameterLine) +InitSystemSharedUserPage (IN PLOADER_PARAMETER_BLOCK LoaderBlock) { UNICODE_STRING ArcDeviceName; UNICODE_STRING ArcName; @@ -56,9 +55,7 @@ InitSystemSharedUserPage (PCSZ ParameterLine) UNICODE_STRING DriveDeviceName; UNICODE_STRING DriveName; WCHAR DriveNameBuffer[20]; - PCHAR ParamBuffer; PWCHAR ArcNameBuffer; - PCHAR p; NTSTATUS Status; ULONG Length; OBJECT_ATTRIBUTES ObjectAttributes; @@ -86,39 +83,16 @@ InitSystemSharedUserPage (PCSZ ParameterLine) * Format: "\ [options...]" */ - /* Create local parameter line copy */ - ParamBuffer = ExAllocatePool(PagedPool, 256); - strcpy (ParamBuffer, (const char *)ParameterLine); - DPRINT("%s\n", ParamBuffer); + RtlCreateUnicodeStringFromAsciiz(&BootPath, LoaderBlock->NtBootPathName); - /* Cut options off */ - p = strchr (ParamBuffer, ' '); - if (p) *p = 0; - DPRINT("%s\n", ParamBuffer); - - /* Extract path */ - p = strchr (ParamBuffer, '\\'); - if (p) { - - DPRINT("Boot path: %s\n", p); - RtlCreateUnicodeStringFromAsciiz (&BootPath, p); - *p = 0; - - } else { - - DPRINT("Boot path: %s\n", "\\"); - RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\"); - } - DPRINT("Arc name: %s\n", ParamBuffer); + /* Remove the trailing backslash */ + BootPath.Length -= sizeof(WCHAR); + BootPath.MaximumLength -= sizeof(WCHAR); /* Only ARC Name left - Build full ARC Name */ ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR)); - swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer); + swprintf (ArcNameBuffer, L"\\ArcName\\%S", LoaderBlock->ArcBootDeviceName); RtlInitUnicodeString (&ArcName, ArcNameBuffer); - DPRINT("Arc name: %wZ\n", &ArcName); - - /* Free ParamBuffer */ - ExFreePool (ParamBuffer); /* Allocate ARC Device Name string */ ArcDeviceName.Length = 0; @@ -163,7 +137,6 @@ InitSystemSharedUserPage (PCSZ ParameterLine) CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status); KEBUGCHECK(0); } - DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName); /* Allocate Device Name string */ DriveDeviceName.Length = 0; @@ -231,48 +204,6 @@ InitSystemSharedUserPage (PCSZ ParameterLine) } } -__inline -VOID -STDCALL -ParseCommandLine(PBOOLEAN NoGuiBoot, - PBOOLEAN ForceAcpiDisable) -{ - PCHAR p1, p2; - - p1 = KeLoaderBlock->LoadOptions; - while(*p1 && (p2 = strchr(p1, '/'))) { - - p2++; - if (!_strnicmp(p2, "NOGUIBOOT", 9)) { - - p2 += 9; - *NoGuiBoot = TRUE; - - } else if (!_strnicmp(p2, "CRASHDUMP", 9)) { - - p2 += 9; - if (*p2 == ':') { - - p2++; - if (!_strnicmp(p2, "FULL", 4)) { - - MmCoreDumpType = MM_CORE_DUMP_TYPE_FULL; - - } else { - - MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE; - } - } - } else if (!_strnicmp(p2, "NOACPI", 6)) { - - p2 += 6; - *ForceAcpiDisable = TRUE; - } - - p1 = p2; - } -} - VOID FORCEINLINE ParseAndCacheLoadedModules(VOID) @@ -472,9 +403,6 @@ ExpInitializeExecutive(IN ULONG Cpu, { PNLS_DATA_BLOCK NlsData; - /* Parse Command Line Settings */ - ParseCommandLine(&NoGuiBoot, &ForceAcpiDisable); - /* FIXME: Deprecate soon */ ParseAndCacheLoadedModules(); @@ -630,7 +558,7 @@ ExPhase2Init(PVOID Context) IoInit(); /* TBD */ - PoInit(AcpiTableDetected, ForceAcpiDisable); + PoInit(AcpiTableDetected, KeLoaderBlock); /* Initialize the Registry (Hives are NOT yet loaded!) */ CmInitializeRegistry(); @@ -650,6 +578,9 @@ ExPhase2Init(PVOID Context) /* Clear the screen to blue */ HalInitSystem(2, KeLoaderBlock); + /* Check if GUI Boot is enabled */ + if (strstr(KeLoaderBlock->LoadOptions, "NOGUIBOOT")) NoGuiBoot = TRUE; + /* Display version number and copyright/warranty message */ if (NoGuiBoot) ExpDisplayNotice(); @@ -685,7 +616,7 @@ ExPhase2Init(PVOID Context) PsLocateSystemDll(); /* Initialize shared user page. Set dos system path, dos device map, etc. */ - InitSystemSharedUserPage (KeLoaderBlock->LoadOptions); + InitSystemSharedUserPage(KeLoaderBlock); /* Create 'ReactOSInitDone' event */ RtlInitUnicodeString(&EventName, L"\\ReactOSInitDone"); diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index 3bca882854f..e80adc1789f 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -568,7 +568,7 @@ IoCreateArcNames( NTSTATUS IoCreateSystemRootLink( - IN PCHAR ParameterLine + IN PLOADER_PARAMETER_BLOCK LoaderBlock ); // diff --git a/reactos/ntoskrnl/include/internal/po.h b/reactos/ntoskrnl/include/internal/po.h index def455703bc..3bd20aa259d 100644 --- a/reactos/ntoskrnl/include/internal/po.h +++ b/reactos/ntoskrnl/include/internal/po.h @@ -39,7 +39,7 @@ VOID NTAPI PoInit( BOOLEAN HaveAcpiTable, - BOOLEAN ForceAcpiDisable + IN PLOADER_PARAMETER_BLOCK LoaderBlock ); VOID diff --git a/reactos/ntoskrnl/io/iomgr/arcname.c b/reactos/ntoskrnl/io/iomgr/arcname.c index 59a9e95bf00..05d0f5f378a 100644 --- a/reactos/ntoskrnl/io/iomgr/arcname.c +++ b/reactos/ntoskrnl/io/iomgr/arcname.c @@ -679,7 +679,7 @@ IopCheckCdromDevices(PULONG DeviceNumber) NTSTATUS INIT_FUNCTION -IoCreateSystemRootLink(PCHAR ParameterLine) +IoCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; @@ -694,33 +694,14 @@ IoCreateSystemRootLink(PCHAR ParameterLine) ULONG Length; HANDLE Handle; - /* Create local parameter line copy */ - ParamBuffer = ExAllocatePool(PagedPool, 256); - strcpy(ParamBuffer, (char *)ParameterLine); + RtlCreateUnicodeStringFromAsciiz(&BootPath, LoaderBlock->NtBootPathName); - DPRINT("%s\n", ParamBuffer); - /* Format: \ [options...] */ + /* Remove the trailing backslash */ + BootPath.Length -= sizeof(WCHAR); + BootPath.MaximumLength -= sizeof(WCHAR); - /* cut options off */ - p = strchr(ParamBuffer, ' '); - if (p) - *p = 0; - DPRINT("%s\n", ParamBuffer); - - /* extract path */ - p = strchr(ParamBuffer, '\\'); - if (p) - { - DPRINT("Boot path: %s\n", p); - RtlCreateUnicodeStringFromAsciiz(&BootPath, p); - *p = 0; - } - else - { - DPRINT("Boot path: %s\n", "\\"); - RtlCreateUnicodeStringFromAsciiz(&BootPath, "\\"); - } - DPRINT("ARC name: %s\n", ParamBuffer); + /* Only ARC Name left - Build full ARC Name */ + ParamBuffer = LoaderBlock->ArcBootDeviceName; p = strstr(ParamBuffer, "cdrom"); if (p != NULL) @@ -740,7 +721,7 @@ IoCreateSystemRootLink(PCHAR ParameterLine) DPRINT("New ARC name: %s\n", ParamBuffer); /* Adjust original command line */ - p = strstr(ParameterLine, "cdrom"); + p = strstr(LoaderBlock->ArcBootDeviceName, "cdrom"); if (p != NULL); { char temp[256]; @@ -763,10 +744,6 @@ IoCreateSystemRootLink(PCHAR ParameterLine) swprintf(ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer); RtlInitUnicodeString(&ArcName, ArcNameBuffer); - DPRINT("Arc name: %wZ\n", &ArcName); - - /* free ParamBuffer */ - ExFreePool(ParamBuffer); /* allocate device name string */ DeviceName.Length = 0; @@ -808,13 +785,11 @@ IoCreateSystemRootLink(PCHAR ParameterLine) return(Status); } - DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName); RtlAppendUnicodeStringToString(&DeviceName, &BootPath); RtlFreeUnicodeString(&BootPath); - DPRINT("DeviceName: %wZ\n", &DeviceName); /* create the '\SystemRoot' link */ Status = IoCreateSymbolicLink(&LinkName, diff --git a/reactos/ntoskrnl/io/iomgr/iomgr.c b/reactos/ntoskrnl/io/iomgr/iomgr.c index df34e60e937..a42a0d3a907 100644 --- a/reactos/ntoskrnl/io/iomgr/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr/iomgr.c @@ -483,7 +483,7 @@ IoInit3(VOID) /* Create the SystemRoot symbolic link */ DPRINT("CommandLine: %s\n", KeLoaderBlock->LoadOptions); - Status = IoCreateSystemRootLink(KeLoaderBlock->LoadOptions); + Status = IoCreateSystemRootLink(KeLoaderBlock); if (!NT_SUCCESS(Status)) { CPRINT("IoCreateSystemRootLink FAILED: (0x%x) - ", Status); KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE); diff --git a/reactos/ntoskrnl/kd/kdinit.c b/reactos/ntoskrnl/kd/kdinit.c index 71655be72c2..263faaa865a 100644 --- a/reactos/ntoskrnl/kd/kdinit.c +++ b/reactos/ntoskrnl/kd/kdinit.c @@ -166,87 +166,83 @@ KdInitSystem(ULONG BootPhase, { ULONG Value; ULONG i; - PCHAR p1, p2; - -#if 0 - /* NTLDR HACK */ - KdpSerialInit(&DispatchTable[KdSerial], 0); - KdpDebugMode.Serial = TRUE; - SerialPortInfo.ComPort = 1; - KdpPort = 1; - KdDebuggerEnabled = TRUE; -#endif + PCHAR CommandLine, Port, BaudRate, Irq; /* Set Default Port Options */ if (BootPhase == 0) { + /* Get the Command Line */ + CommandLine = LoaderBlock->LoadOptions; - /* Parse the Command Line */ - p1 = LoaderBlock->LoadOptions; - while (p1 && (p2 = strchr(p1, '/'))) + /* Upcase it */ + _strupr(CommandLine); + + /* Check for settings that we support */ + if (strstr(CommandLine, "BREAK")) KdpEarlyBreak = TRUE; + if (strstr(CommandLine, "NODEBUG")) KdDebuggerEnabled = FALSE; + if (strstr(CommandLine, "CRASHDEBUG")) KdDebuggerEnabled = FALSE; + if (strstr(CommandLine, "DEBUG")) { - /* Move past the slash */ - p2++; + /* Enable on the serial port */ + KdDebuggerEnabled = TRUE; + KdpDebugMode.Serial = TRUE; + } - /* Identify the Debug Type being Used */ - if (!_strnicmp(p2, "DEBUGPORT=", 10)) - { - p2 += 10; - p2 = KdpGetDebugMode(p2); - p2 = KdpGetWrapperDebugMode(p2, LoaderBlock); - KdDebuggerEnabled = TRUE; - } - /* Check for early breakpoint */ - else if (!_strnicmp(p2, "BREAK", 5)) - { - p2 += 5; - KdpEarlyBreak = TRUE; - } - /* Check for Kernel Debugging Enable */ - else if (!_strnicmp(p2, "DEBUG", 5)) - { - /* Enable it on the Serial Port */ - p2 += 5; - KdDebuggerEnabled = TRUE; - KdpDebugMode.Serial = TRUE; - } - /* Check for Kernel Debugging Bypass */ - else if (!_strnicmp(p2, "NODEBUG", 7)) - { - /* Disable Debugging */ - p2 += 7; - KdDebuggerEnabled = FALSE; - } - /* Check for Kernel Debugging Bypass unless STOP Error */ - else if (!_strnicmp(p2, "CRASHDEBUG", 10)) - { - /* Disable Debugging */ - p2 += 10; - KdDebuggerEnabled = FALSE; - } - /* Check Serial Port Settings [Baud Rate] */ - else if (!_strnicmp(p2, "BAUDRATE=", 9)) - { - /* Get the Baud Rate */ - p2 += 9; - Value = (ULONG)atol(p2); + /* Get the port and baud rate */ + Port = strstr(CommandLine, "DEBUGPORT"); + BaudRate = strstr(CommandLine, "BAUDRATE"); + Irq = strstr(CommandLine, "IRQ"); - /* Check if it's valid and Set it */ - if (0 < Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value; - } - /* Check Serial Port Settings [IRQ] */ - else if (!_strnicmp(p2, "IRQ=", 4)) + /* Check if we got the /DEBUGPORT parameter */ + if (Port) + { + /* Move past the actual string, to reach the port*/ + Port += strlen("DEBUGPORT"); + + /* Now get past any spaces and skip the equal sign */ + while (*Port == ' ') Port++; + Port++; + + /* Get the debug mode and wrapper */ + Port = KdpGetDebugMode(Port); + Port = KdpGetWrapperDebugMode(Port, LoaderBlock); + KdDebuggerEnabled = TRUE; + } + + /* Check if we got a baud rate */ + if (BaudRate) + { + /* Move past the actual string, to reach the rate */ + BaudRate += strlen("BAUDRATE"); + + /* Now get past any spaces */ + while (*BaudRate == ' ') BaudRate++; + + /* And make sure we have a rate */ + if (*BaudRate) { - /* Get the IRQ */ - p2 += 3; - Value = (ULONG)atol(p2); - - /* Check if it's valid and set it */ - if (0 < Value) KdpPortIrq = Value; + /* Read and set it */ + Value = atol(BaudRate + 1); + if (Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value; } + } - /* Move to next */ - p1 = p2; + /* Check Serial Port Settings [IRQ] */ + if (Irq) + { + /* Move past the actual string, to reach the rate */ + Irq += strlen("IRQ"); + + /* Now get past any spaces */ + while (*Irq == ' ') Irq++; + + /* And make sure we have an IRQ */ + if (*Irq) + { + /* Read and set it */ + Value = atol(Irq + 1); + if (Value) KdpPortIrq = Value; + } } /* Call Providers at Phase 0 */ @@ -257,7 +253,6 @@ KdInitSystem(ULONG BootPhase, /* Call Wrapper at Phase 0 */ if (WrapperInitRoutine) WrapperInitRoutine(&WrapperTable, 0); - return; } diff --git a/reactos/ntoskrnl/kd/kdio.c b/reactos/ntoskrnl/kd/kdio.c index 811d22f7a64..c0c140493e0 100644 --- a/reactos/ntoskrnl/kd/kdio.c +++ b/reactos/ntoskrnl/kd/kdio.c @@ -188,10 +188,15 @@ KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable, /* Register as a Provider */ InsertTailList(&KdProviders, &DispatchTable->KdProvidersList); - + /* Display separator + ReactOS version at start of the debug log */ - DPRINT1("---------------------------------------------------------------\n"); + DPRINT1("-----------------------------------------------------\n"); DPRINT1("ReactOS "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n"); + DPRINT1("Command Line: %s\n", KeLoaderBlock->LoadOptions); + DPRINT1("ARC Paths: %s %s %s %s\n", KeLoaderBlock->ArcBootDeviceName, + KeLoaderBlock->NtHalPathName, + KeLoaderBlock->ArcHalDeviceName, + KeLoaderBlock->NtBootPathName); } else if (BootPhase == 2) { diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 685293d924f..a7dadda2473 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -43,6 +43,10 @@ extern LDR_DATA_TABLE_ENTRY HalModuleObject; LOADER_PARAMETER_BLOCK BldrLoaderBlock; LOADER_PARAMETER_EXTENSION BldrExtensionBlock; CHAR BldrCommandLine[256]; +CHAR BldrArcBootPath[64]; +CHAR BldrArcHalPath[64]; +CHAR BldrNtHalPath[64]; +CHAR BldrNtBootPath[64]; LDR_DATA_TABLE_ENTRY BldrModules[64]; MEMORY_ALLOCATION_DESCRIPTOR BldrMemoryDescriptors[64]; WCHAR BldrModuleStrings[64][260]; @@ -63,6 +67,8 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, ULONG i, j, ModSize; PVOID ModStart; PCHAR DriverName; + PCHAR BootPath, HalPath; + CHAR CommandLine[256]; /* First get some kernel-loader globals */ AcpiTableDetected = (RosLoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE; @@ -256,6 +262,36 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, /* All we'll setup right now is the flag for text-mode setup */ LoaderBlock->SetupLdrBlock->Flags = 1; } + + /* Make a copy of the command line */ + strcpy(CommandLine, LoaderBlock->LoadOptions); + + /* Find the first \, separating the ARC path from NT path */ + BootPath = strchr(CommandLine, '\\'); + *BootPath = ANSI_NULL; + strncpy(BldrArcBootPath, CommandLine, 63); + LoaderBlock->ArcBootDeviceName = BldrArcBootPath; + + /* The rest of the string is the NT path */ + HalPath = strchr(BootPath + 1, ' '); + *HalPath = ANSI_NULL; + BldrNtBootPath[0] = '\\'; + strncat(BldrNtBootPath, BootPath + 1, 63); + strcat(BldrNtBootPath,"\\"); + LoaderBlock->NtBootPathName = BldrNtBootPath; + + /* Set the HAL paths */ + strncpy(BldrArcHalPath, BldrArcBootPath, 63); + LoaderBlock->ArcHalDeviceName = BldrArcHalPath; + strcpy(BldrNtHalPath, "\\"); + LoaderBlock->NtHalPathName = BldrNtHalPath; + + /* Use this new command line */ + strncpy(LoaderBlock->LoadOptions, HalPath + 2, 255); + + /* Parse it and change every slash to a space */ + BootPath = LoaderBlock->LoadOptions; + do {if (*BootPath == '/') *BootPath = ' ';} while (*BootPath++); } VOID diff --git a/reactos/ntoskrnl/po/power.c b/reactos/ntoskrnl/po/power.c index 1d336223195..ef7f7b8e37b 100644 --- a/reactos/ntoskrnl/po/power.c +++ b/reactos/ntoskrnl/po/power.c @@ -307,9 +307,20 @@ VOID INIT_FUNCTION NTAPI PoInit(BOOLEAN HaveAcpiTable, - BOOLEAN ForceAcpiDisable) + IN PLOADER_PARAMETER_BLOCK LoaderBlock) { PVOID NotificationEntry; + PCHAR CommandLine; + BOOLEAN ForceAcpiDisable = FALSE; + + /* Get the Command Line */ + CommandLine = KeLoaderBlock->LoadOptions; + + /* Upcase it */ + _strupr(CommandLine); + + /* Check for ACPI disable */ + if (strstr(CommandLine, "NOACPI")) ForceAcpiDisable = TRUE; if (ForceAcpiDisable) { From 526efd2ee756c52b3cc479b04e058c60cc4eeeb0 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Mon, 2 Oct 2006 12:22:17 +0000 Subject: [PATCH 426/488] Define NTOSAPI before including ntddk.h to avoid including function prototypes with dllimport svn path=/trunk/; revision=24359 --- reactos/boot/freeldr/freeldr/include/freeldr.h | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/boot/freeldr/freeldr/include/freeldr.h b/reactos/boot/freeldr/freeldr/include/freeldr.h index a094987de39..5bf2981b29e 100644 --- a/reactos/boot/freeldr/freeldr/include/freeldr.h +++ b/reactos/boot/freeldr/freeldr/include/freeldr.h @@ -25,6 +25,7 @@ #include #include #include +#define NTOSAPI #include #include #include From afa1de7c812fb7d92f7bebd63a704797876f8577 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 2 Oct 2006 13:23:03 +0000 Subject: [PATCH 427/488] - Implement Phase 0 Ex initialization (Resource, Lookaside initialization) and generic Ex initialization routine. - Clear the crypto exponent on boot-up. - Set default global flags for checked builds. - Set NtSystemRoot (SharedUserData) to C: on startup. - Cleanup lookas.c file and implement routines to initialize the system lookaside list in phase 0. svn path=/trunk/; revision=24360 --- reactos/ntoskrnl/ex/init.c | 105 +++++++++++++++--- reactos/ntoskrnl/ex/lookas.c | 147 ++++++++++++++++--------- reactos/ntoskrnl/ex/sysinfo.c | 4 + reactos/ntoskrnl/include/internal/ex.h | 14 +++ 4 files changed, 208 insertions(+), 62 deletions(-) diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 4f07213eddd..a3091c14890 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -22,7 +22,8 @@ ULONG NtMajorVersion = 5; ULONG NtMinorVersion = 0; ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(4, 0); ULONG NtBuildNumber = KERNEL_VERSION_BUILD; -ULONG NtGlobalFlag = 0; +ULONG NtGlobalFlag; +ULONG ExSuiteMask; extern ULONG MmCoreDumpType; extern LOADER_MODULE KeLoaderModules[64]; @@ -36,6 +37,9 @@ BOOLEAN ExpInTextModeSetup; BOOLEAN IoRemoteBootClient; ULONG InitSafeBootMode; +/* NT Boot Path */ +UNICODE_STRING NtSystemRoot; + /* Boot NLS information */ PVOID ExpNlsTableBase; ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset; @@ -348,14 +352,6 @@ ExpLoadInitialProcess(PHANDLE ProcessHandle, return STATUS_SUCCESS; } -VOID -NTAPI -ExInit2(VOID) -{ - ExpInitLookasideLists(); - ExpInitializeHandleTables(); -} - VOID NTAPI ExInit3(VOID) @@ -371,6 +367,61 @@ ExInit3(VOID) ExpInitUuids(); } +BOOLEAN +NTAPI +ExpInitSystemPhase0(VOID) +{ + /* Initialize EXRESOURCE Support */ + ExpResourceInitialization(); + + /* Initialize the environment lock */ + ExInitializeFastMutex(&ExpEnvironmentLock); + + /* Initialize the lookaside lists and locks */ + ExpInitLookasideLists(); + + /* Initialize the Firmware Table resource and listhead */ + InitializeListHead(&ExpFirmwareTableProviderListHead); + ExInitializeResourceLite(&ExpFirmwareTableResource); + + /* Set the suite mask to maximum and return */ + ExSuiteMask = 0xFFFFFFFF; + return TRUE; +} + +BOOLEAN +NTAPI +ExpInitSystemPhase1(VOID) +{ + /* Not yet done */ + return FALSE; +} + +BOOLEAN +NTAPI +ExInitSystem(VOID) +{ + /* Check the initialization phase */ + switch (ExpInitializationPhase) + { + case 0: + + /* Do Phase 0 */ + return ExpInitSystemPhase0(); + + case 1: + + /* Do Phase 1 */ + return ExpInitSystemPhase1(); + + default: + + /* Don't know any other phase! Bugcheck! */ + KeBugCheck(UNEXPECTED_INITIALIZATION_CALL); + return FALSE; + } +} + BOOLEAN NTAPI ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock) @@ -402,6 +453,9 @@ ExpInitializeExecutive(IN ULONG Cpu, IN PLOADER_PARAMETER_BLOCK LoaderBlock) { PNLS_DATA_BLOCK NlsData; + CHAR Buffer[256]; + ANSI_STRING AnsiPath; + NTSTATUS Status; /* FIXME: Deprecate soon */ ParseAndCacheLoadedModules(); @@ -487,6 +541,31 @@ ExpInitializeExecutive(IN ULONG Cpu, /* Make sure interrupts are active now */ _enable(); + /* Clear the crypto exponent */ + SharedUserData->CryptoExponent = 0; + + /* Set global flags for the checked build */ +#if DBG + NtGlobalFlag |= FLG_ENABLE_CLOSE_EXCEPTIONS | + FLG_ENABLE_KDEBUG_SYMBOL_LOAD; +#endif + + /* Setup NT System Root Path */ + sprintf(Buffer, "C:%s", LoaderBlock->NtBootPathName); + + /* Convert to ANSI_STRING and null-terminate it */ + RtlInitString(&AnsiPath, Buffer ); + Buffer[--AnsiPath.Length] = UNICODE_NULL; + + /* Get the string from KUSER_SHARED_DATA's buffer */ + NtSystemRoot.Buffer = SharedUserData->NtSystemRoot; + NtSystemRoot.MaximumLength = sizeof(SharedUserData->NtSystemRoot) / sizeof(WCHAR); + NtSystemRoot.Length = 0; + + /* Now fill it in */ + Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &AnsiPath, FALSE); + if (!NT_SUCCESS(Status)) KEBUGCHECK(SESSION3_INITIALIZATION_FAILED); + /* Setup bugcheck messages */ KiInitializeBugCheck(); @@ -496,14 +575,14 @@ ExpInitializeExecutive(IN ULONG Cpu, /* Initialize the second stage of the kernel */ KeInit2(); - /* Initialize resources */ - ExpResourceInitialization(); + /* Initialize the executive at phase 0 */ + if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED); /* Load basic Security for other Managers */ if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED); - /* Initialize Lookaside Lists and Handle Table */ - ExInit2(); + /* Initialize the Handle Table */ + ExpInitializeHandleTables(); /* Create the Basic Object Manager Types to allow new Object Types */ ObInit(); diff --git a/reactos/ntoskrnl/ex/lookas.c b/reactos/ntoskrnl/ex/lookas.c index 32654a521eb..4619ce58768 100644 --- a/reactos/ntoskrnl/ex/lookas.c +++ b/reactos/ntoskrnl/ex/lookas.c @@ -1,18 +1,16 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ex/lookas.c - * PURPOSE: Lookaside lists - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * David Welch (welch@mcmail.com) - * Casper S. Hornstrup (chorns@users.sourceforge.net) - */ +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/ex/lookas.c +* PURPOSE: Lookaside Lists +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG -#include +#include #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, ExpInitLookasideLists) @@ -24,10 +22,41 @@ LIST_ENTRY ExpNonPagedLookasideListHead; KSPIN_LOCK ExpNonPagedLookasideListLock; LIST_ENTRY ExpPagedLookasideListHead; KSPIN_LOCK ExpPagedLookasideListLock; +LIST_ENTRY ExSystemLookasideListHead; +LIST_ENTRY ExPoolLookasideListHead; NPAGED_LOOKASIDE_LIST ExpSmallNPagedPoolLookasideLists[MAXIMUM_PROCESSORS]; PAGED_LOOKASIDE_LIST ExpSmallPagedPoolLookasideLists[MAXIMUM_PROCESSORS]; -/* FUNCTIONS *****************************************************************/ +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +ExInitializeSystemLookasideList(IN PGENERAL_LOOKASIDE List, + IN POOL_TYPE Type, + IN ULONG Size, + IN ULONG Tag, + IN USHORT MaximumDepth, + IN PLIST_ENTRY ListHead) +{ + /* Initialize the list */ + List->Tag = Tag; + List->Type = Type; + List->Size = Size; + InsertHeadList(ListHead, &List->ListEntry); + List->MaximumDepth = MaximumDepth; + List->Depth = 2; + List->Allocate = ExAllocatePoolWithTag; + List->Free = ExFreePool; + List->ListHead.Next.Next = NULL; + List->ListHead.Depth = 0; + List->ListHead.Sequence = 0; + List->TotalAllocates = 0; + List->AllocateHits = 0; + List->TotalFrees = 0; + List->FreeHits = 0; + List->LastTotalAllocates = 0; + List->LastAllocateHits = 0; +} VOID NTAPI @@ -60,23 +89,49 @@ ExInitPoolLookasidePointers(VOID) Entry->P = &PagedListEntry->L; } } + VOID -INIT_FUNCTION -STDCALL +NTAPI ExpInitLookasideLists() { - /* Initialize Lock and Listhead */ + ULONG i, j; + + /* Initialize locks and lists */ InitializeListHead(&ExpNonPagedLookasideListHead); - KeInitializeSpinLock(&ExpNonPagedLookasideListLock); InitializeListHead(&ExpPagedLookasideListHead); + InitializeListHead(&ExSystemLookasideListHead); + InitializeListHead(&ExPoolLookasideListHead); + KeInitializeSpinLock(&ExpNonPagedLookasideListLock); KeInitializeSpinLock(&ExpPagedLookasideListLock); + + /* Initialize the system lookaside lists */ + for (i = 0, j = 1; i < (MAXIMUM_PROCESSORS - 1); j++, i++) + { + /* Initialize the non-paged list */ + ExInitializeSystemLookasideList(&ExpSmallNPagedPoolLookasideLists[i].L, + NonPagedPool, + j * 8, + TAG('P', 'o', 'o', 'l'), + 256, + &ExPoolLookasideListHead); + + /* Initialize the paged list */ + ExInitializeSystemLookasideList(&ExpSmallPagedPoolLookasideLists[i].L, + PagedPool, + j * 8, + TAG('P', 'o', 'o', 'l'), + 256, + &ExPoolLookasideListHead); + } } +/* PUBLIC FUNCTIONS **********************************************************/ + /* * @implemented */ PVOID -STDCALL +NTAPI ExiAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside) { PVOID Entry; @@ -87,7 +142,7 @@ ExiAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside) { Lookaside->L.AllocateMisses++; Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, - Lookaside->L.Size, + Lookaside->L.Size, Lookaside->L.Tag); } return Entry; @@ -97,7 +152,7 @@ ExiAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside) * @implemented */ VOID -STDCALL +NTAPI ExiFreeToPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry) { @@ -117,21 +172,20 @@ ExiFreeToPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, * @implemented */ VOID -STDCALL -ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside) +NTAPI +ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside) { KIRQL OldIrql; PVOID Entry; - /* Pop all entries off the stack and release the resources allocated - for them */ + /* Pop all entries off the stack and release their resources */ for (;;) { Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); if (!Entry) break; (*Lookaside->L.Free)(Entry); } - + /* Remove from list */ KeAcquireSpinLock(&ExpNonPagedLookasideListLock, &OldIrql); RemoveEntryList(&Lookaside->L.ListEntry); @@ -142,21 +196,20 @@ ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside) * @implemented */ VOID -STDCALL -ExDeletePagedLookasideList(PPAGED_LOOKASIDE_LIST Lookaside) +NTAPI +ExDeletePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside) { KIRQL OldIrql; PVOID Entry; - /* Pop all entries off the stack and release the resources allocated - for them */ + /* Pop all entries off the stack and release their resources */ for (;;) { Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); if (!Entry) break; (*Lookaside->L.Free)(Entry); } - + /* Remove from list */ KeAcquireSpinLock(&ExpPagedLookasideListLock, &OldIrql); RemoveEntryList(&Lookaside->L.ListEntry); @@ -167,17 +220,15 @@ ExDeletePagedLookasideList(PPAGED_LOOKASIDE_LIST Lookaside) * @implemented */ VOID -STDCALL -ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside, - PALLOCATE_FUNCTION Allocate, - PFREE_FUNCTION Free, - ULONG Flags, - ULONG Size, - ULONG Tag, - USHORT Depth) +NTAPI +ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, + IN PALLOCATE_FUNCTION Allocate OPTIONAL, + IN PFREE_FUNCTION Free OPTIONAL, + IN ULONG Flags, + IN ULONG Size, + IN ULONG Tag, + IN USHORT Depth) { - DPRINT("Initializing nonpaged lookaside list at 0x%p\n", Lookaside); - /* Initialize the Header */ ExInitializeSListHead(&Lookaside->L.ListHead); Lookaside->L.TotalAllocates = 0; @@ -221,17 +272,15 @@ ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside, * @implemented */ VOID -STDCALL -ExInitializePagedLookasideList (PPAGED_LOOKASIDE_LIST Lookaside, - PALLOCATE_FUNCTION Allocate, - PFREE_FUNCTION Free, - ULONG Flags, - ULONG Size, - ULONG Tag, - USHORT Depth) +NTAPI +ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, + IN PALLOCATE_FUNCTION Allocate OPTIONAL, + IN PFREE_FUNCTION Free OPTIONAL, + IN ULONG Flags, + IN ULONG Size, + IN ULONG Tag, + IN USHORT Depth) { - DPRINT("Initializing paged lookaside list at 0x%p\n", Lookaside); - /* Initialize the Header */ ExInitializeSListHead(&Lookaside->L.ListHead); Lookaside->L.TotalAllocates = 0; @@ -264,7 +313,7 @@ ExInitializePagedLookasideList (PPAGED_LOOKASIDE_LIST Lookaside, { Lookaside->L.Free = ExFreePool; } - + /* Insert it into the list */ ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead, &Lookaside->L.ListEntry, diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 5cced43ab6c..a9e1778af23 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -21,6 +21,10 @@ ULONGLONG STDCALL KeQueryInterruptTime(VOID); VOID MmPrintMemoryStatistic(VOID); +FAST_MUTEX ExpEnvironmentLock; +ERESOURCE ExpFirmwareTableResource; +LIST_ENTRY ExpFirmwareTableProviderListHead; + /* FUNCTIONS *****************************************************************/ /* diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 96a060420f9..39fa724ca3e 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -10,6 +10,9 @@ extern POBJECT_TYPE ExEventPairObjectType; extern ULONG NtBuildNumber; extern ULONG NtMajorVersion; extern ULONG NtMinorVersion; +extern FAST_MUTEX ExpEnvironmentLock; +extern ERESOURCE ExpFirmwareTableResource; +extern LIST_ENTRY ExpFirmwareTableProviderListHead; #define MAX_FAST_REFS 7 @@ -66,6 +69,17 @@ VOID NTAPI ExpInitLookasideLists(VOID); +VOID +NTAPI +ExInitializeSystemLookasideList( + IN PGENERAL_LOOKASIDE List, + IN POOL_TYPE Type, + IN ULONG Size, + IN ULONG Tag, + IN USHORT MaximumDepth, + IN PLIST_ENTRY ListHead +); + VOID NTAPI ExpInitializeCallbacks(VOID); From 62ac7ad5c979fa59d3abc67cfb1231eb8805e1bf Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Mon, 2 Oct 2006 13:29:55 +0000 Subject: [PATCH 428/488] Fix some warnings svn path=/trunk/; revision=24361 --- reactos/tools/mkhive/cmi.c | 2 +- reactos/tools/mkhive/mkhive.h | 1 + reactos/tools/mkhive/rtl.c | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/reactos/tools/mkhive/cmi.c b/reactos/tools/mkhive/cmi.c index cb79a18c3b5..71550c7895f 100644 --- a/reactos/tools/mkhive/cmi.c +++ b/reactos/tools/mkhive/cmi.c @@ -31,7 +31,7 @@ CmpAllocate( IN SIZE_T Size, IN BOOLEAN Paged) { - return (PVOID) malloc(Size); + return (PVOID) malloc((size_t)Size); } static VOID diff --git a/reactos/tools/mkhive/mkhive.h b/reactos/tools/mkhive/mkhive.h index bb7da55512c..6a1aaff68f6 100644 --- a/reactos/tools/mkhive/mkhive.h +++ b/reactos/tools/mkhive/mkhive.h @@ -28,6 +28,7 @@ #define __MKHIVE_H__ #include +#include /* We have to do this because psdk/windef.h will _always_ define _WIN32... */ #if defined(_WIN32) || defined(_WIN64) diff --git a/reactos/tools/mkhive/rtl.c b/reactos/tools/mkhive/rtl.c index ed6711dd075..913a79eaa40 100644 --- a/reactos/tools/mkhive/rtl.c +++ b/reactos/tools/mkhive/rtl.c @@ -4,6 +4,8 @@ * PURPOSE: Runtime Library */ +#include + #define RTL_H #define NTOS_MODE_USER @@ -11,7 +13,7 @@ #include #include -SIZE_T xwcslen( PWSTR String ) { +SIZE_T xwcslen( PCWSTR String ) { SIZE_T i; for( i = 0; String[i]; i++ ); From 06142d4e0dd154372a36ecbd089913677a28d9b7 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 2 Oct 2006 15:05:03 +0000 Subject: [PATCH 429/488] - Setup memory limits in shared user data. - Loop security descriptors to find NLS data and make a copy of it in kernel pool, because the NLS buffer from NTLDR will be freed on NT. Also discovered a bug in Freeldr where it doesn't allocate ths NLS files sequentially, leaving a hole of 0x1000 between them. Added a hack to compensate (won't break NTLDR booting, just will waste 8KB of memory). - Allocate the system call count table on checked builds. - Refactor Ob/Se booting to match more closely NT, and so that we can do Se initialization in one shot. svn path=/trunk/; revision=24362 --- reactos/ntoskrnl/ex/init.c | 95 ++++++++++++++++++-- reactos/ntoskrnl/include/internal/ntoskrnl.h | 2 +- reactos/ntoskrnl/ke/krnlinit.c | 5 +- reactos/ntoskrnl/ob/obinit.c | 73 +++++++++------ 4 files changed, 138 insertions(+), 37 deletions(-) diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index a3091c14890..6fbd3f32bc6 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -25,10 +25,9 @@ ULONG NtBuildNumber = KERNEL_VERSION_BUILD; ULONG NtGlobalFlag; ULONG ExSuiteMask; -extern ULONG MmCoreDumpType; extern LOADER_MODULE KeLoaderModules[64]; extern ULONG KeLoaderModuleCount; -extern PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages; +extern ULONG KiServiceLimit; BOOLEAN NoGuiBoot = FALSE; /* Init flags and settings */ @@ -45,6 +44,7 @@ PVOID ExpNlsTableBase; ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset; ULONG ExpUnicodeCaseTableDataOffset; NLSTABLEINFO ExpNlsTableInfo; +ULONG ExpNlsTableSize; /* FUNCTIONS ****************************************************************/ @@ -456,6 +456,8 @@ ExpInitializeExecutive(IN ULONG Cpu, CHAR Buffer[256]; ANSI_STRING AnsiPath; NTSTATUS Status; + PLIST_ENTRY NextEntry, ListHead; + PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; /* FIXME: Deprecate soon */ ParseAndCacheLoadedModules(); @@ -578,22 +580,97 @@ ExpInitializeExecutive(IN ULONG Cpu, /* Initialize the executive at phase 0 */ if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED); - /* Load basic Security for other Managers */ - if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED); + /* Set system ranges */ + SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress; + SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart; + + /* Loop the memory descriptors */ + ListHead = &LoaderBlock->MemoryDescriptorListHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the current block */ + MdBlock = CONTAINING_RECORD(NextEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + + /* Check if this is an NLS block */ + if (MdBlock->MemoryType == LoaderNlsData) + { + /* Increase the table size */ + ExpNlsTableSize += MdBlock->PageCount * PAGE_SIZE; + } + + /* Go to the next block */ + NextEntry = MdBlock->ListEntry.Flink; + } + + /* + * In NT, the memory blocks are contiguous, but in ReactOS they are not, + * so unless someone fixes FreeLdr, we'll have to use this icky hack. + */ + ExpNlsTableSize += 2 * PAGE_SIZE; // BIAS FOR FREELDR. HACK! + + /* + * Allocate the table in pool memory, so we can stop depending on the + * memory given to use by the loader, which is freed later. + */ + ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool, + ExpNlsTableSize, + TAG('R', 't', 'l', 'i')); + if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED); + + /* Copy the codepage data in its new location. */ + RtlMoveMemory(ExpNlsTableBase, + LoaderBlock->NlsData->AnsiCodePageData, + ExpNlsTableSize); + + /* Initialize and reset the NLS TAbles */ + RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + + ExpAnsiCodePageDataOffset), + (PVOID)((ULONG_PTR)ExpNlsTableBase + + ExpOemCodePageDataOffset), + (PVOID)((ULONG_PTR)ExpNlsTableBase + + ExpUnicodeCaseTableDataOffset), + &ExpNlsTableInfo); + RtlResetRtlTranslations(&ExpNlsTableInfo); /* Initialize the Handle Table */ ExpInitializeHandleTables(); +#if DBG + /* On checked builds, allocate the system call count table */ + KeServiceDescriptorTable[0].Count = + ExAllocatePoolWithTag(NonPagedPool, + KiServiceLimit * sizeof(ULONG), + TAG('C', 'a', 'l', 'l')); + + /* Use it for the shadow table too */ + KeServiceDescriptorTableShadow[0].Count = KeServiceDescriptorTable[0].Count; + + /* Make sure allocation succeeded */ + if (KeServiceDescriptorTable[0].Count) + { + /* Zero the call counts to 0 */ + RtlZeroMemory(KeServiceDescriptorTable[0].Count, + KiServiceLimit * sizeof(ULONG)); + } +#endif + /* Create the Basic Object Manager Types to allow new Object Types */ - ObInit(); + if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED); + + /* Load basic Security for other Managers */ + if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED); + if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED); /* Set up Region Maps, Sections and the Paging File */ MmInit2(); - /* Initialize Tokens now that the Object Manager is ready */ - if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED); + /* Call OB initialization again */ + if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED); - /* Initalize the Process Manager */ + /* Initialize the Process Manager */ PspInitPhase0(); /* Break into the Debugger if requested */ @@ -602,7 +679,7 @@ ExpInitializeExecutive(IN ULONG Cpu, /* Initialize all processors */ HalAllProcessorsStarted(); - /* Do Phase 1 HAL Initalization */ + /* Do Phase 1 HAL Initialization */ HalInitSystem(1, KeLoaderBlock); } diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index f6e13e049d3..bd3859d3cab 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -63,7 +63,7 @@ VOID MmInitSystem(ULONG Phase, PLOADER_PARAMETER_BLOCK LoaderBlock, ULONG LastKe VOID IoInit(VOID); VOID IoInit2(BOOLEAN BootLog); VOID NTAPI IoInit3(VOID); -VOID ObInit(VOID); +BOOLEAN NTAPI ObInit(VOID); VOID PsInit(VOID); VOID CmInitializeRegistry(VOID); VOID NTAPI CmInitHives(BOOLEAN SetupBoot); diff --git a/reactos/ntoskrnl/ke/krnlinit.c b/reactos/ntoskrnl/ke/krnlinit.c index 041ed88f283..ccdd281239b 100644 --- a/reactos/ntoskrnl/ke/krnlinit.c +++ b/reactos/ntoskrnl/ke/krnlinit.c @@ -15,6 +15,9 @@ /* GLOBALS *******************************************************************/ +/* System call count */ +ULONG KiServiceLimit = NUMBER_OF_SYSCALLS; + /* ARC Loader Block */ PLOADER_PARAMETER_BLOCK KeLoaderBlock; @@ -96,7 +99,7 @@ KiInitSystem(VOID) /* Initialize the syscall table */ KeServiceDescriptorTable[0].Base = MainSSDT; KeServiceDescriptorTable[0].Count = NULL; - KeServiceDescriptorTable[0].Limit = NUMBER_OF_SYSCALLS; + KeServiceDescriptorTable[0].Limit = KiServiceLimit; KeServiceDescriptorTable[1].Limit = 0; KeServiceDescriptorTable[0].Number = MainSSPT; diff --git a/reactos/ntoskrnl/ob/obinit.c b/reactos/ntoskrnl/ob/obinit.c index 3ac6e0304cd..0834bbf13bc 100644 --- a/reactos/ntoskrnl/ob/obinit.c +++ b/reactos/ntoskrnl/ob/obinit.c @@ -44,34 +44,19 @@ VOID NTAPI PsInitializeQuotaSystem(VOID); +ULONG ObpInitializationPhase; + /* PRIVATE FUNCTIONS *********************************************************/ -VOID +BOOLEAN INIT_FUNCTION +NTAPI ObInit2(VOID) { ULONG i; PKPRCB Prcb; PNPAGED_LOOKASIDE_LIST CurrentList = NULL; - /* Initialize the OBJECT_CREATE_INFORMATION List */ - ExInitializeNPagedLookasideList(&ObpCiLookasideList, - NULL, - NULL, - 0, - sizeof(OBJECT_CREATE_INFORMATION), - TAG('O', 'b', 'C', 'I'), - 32); - - /* Set the captured UNICODE_STRING Object Name List */ - ExInitializeNPagedLookasideList(&ObpNmLookasideList, - NULL, - NULL, - 0, - 248, - TAG('O', 'b', 'N', 'M'), - 16); - /* Now allocate the per-processor lists */ for (i = 0; i < KeNumberProcessors; i++) { @@ -128,10 +113,13 @@ ObInit2(VOID) /* Link it */ Prcb->PPLookasideList[LookasideNameBufferList].P = &CurrentList->L; } + + return TRUE; } -VOID +BOOLEAN INIT_FUNCTION +NTAPI ObInit(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; @@ -139,6 +127,34 @@ ObInit(VOID) SECURITY_DESCRIPTOR SecurityDescriptor; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; OBP_LOOKUP_CONTEXT Context; + PKPRCB Prcb = KeGetCurrentPrcb(); + + /* Check if this is actually Phase 1 initialization */ + if (ObpInitializationPhase != 0) goto ObPostPhase0; + + /* Initialize the OBJECT_CREATE_INFORMATION List */ + ExInitializeNPagedLookasideList(&ObpCiLookasideList, + NULL, + NULL, + 0, + sizeof(OBJECT_CREATE_INFORMATION), + TAG('O', 'b', 'C', 'I'), + 32); + + /* Set the captured UNICODE_STRING Object Name List */ + ExInitializeNPagedLookasideList(&ObpNmLookasideList, + NULL, + NULL, + 0, + 248, + TAG('O', 'b', 'N', 'M'), + 16); + + /* Temporarily setup both pointers to the shared list */ + Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCiLookasideList.L; + Prcb->PPLookasideList[LookasideCreateInfoList].P = &ObpCiLookasideList.L; + Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNmLookasideList.L; + Prcb->PPLookasideList[LookasideNameBufferList].P = &ObpNmLookasideList.L; /* Initialize the security descriptor cache */ ObpInitSdCache(); @@ -149,9 +165,6 @@ ObInit(VOID) /* Setup the Object Reaper */ ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL); - /* Initialize lookaside lists */ - ObInit2(); - /* Initialize default Quota block */ PsInitializeQuotaSystem(); @@ -160,7 +173,6 @@ ObInit(VOID) ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable; /* Create the Type Type */ - DPRINT("Creating Type Type\n"); RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Type"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); @@ -173,7 +185,6 @@ ObInit(VOID) ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObTypeObjectType); /* Create the Directory Type */ - DPRINT("Creating Directory Type\n"); RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Directory"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); @@ -184,6 +195,15 @@ ObInit(VOID) ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY); ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObDirectoryType); + /* Phase 0 initialization complete */ + ObpInitializationPhase++; + return TRUE; + +ObPostPhase0: + + /* Re-initialize lookaside lists */ + ObInit2(); + /* Create security descriptor */ RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION1); @@ -199,7 +219,6 @@ ObInit(VOID) FALSE); /* Create root directory */ - DPRINT("Creating Root Directory\n"); InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_PERMANENT, @@ -271,5 +290,7 @@ ObInit(VOID) /* FIXME: Hack Hack! */ ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm')); RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap)); + return TRUE; } + /* EOF */ From 04c5f926214e1b9afd67ec4bdfdceb9fc7fb8241 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 2 Oct 2006 15:52:58 +0000 Subject: [PATCH 430/488] - Combine SeInit1 and SeInit2 into SeInit since both can be done together now. - Call PsInitSystem instead of PspInitPhase0, since PsInitsystem is the "external" phase-choosing routine. - Implement ExComputeTickCountMultiplier to create a 24-bit precision remainder + whole integer of the ms/clock tick used in SharedUserData. - Set the OS version and Machine Type (i386/PPC (<3 Arty) in SharedUserData. - Move some HAL calls in Phase 2 (actually Phase 1...), same for KeInit2. - Break into KDBG a bit earlier. svn path=/trunk/; revision=24363 --- reactos/ntoskrnl/ex/init.c | 79 ++++++++++++++++---- reactos/ntoskrnl/ex/time.c | 1 + reactos/ntoskrnl/include/internal/ex.h | 1 + reactos/ntoskrnl/include/internal/ntoskrnl.h | 1 - reactos/ntoskrnl/include/internal/ps.h | 2 +- reactos/ntoskrnl/include/internal/se.h | 6 +- reactos/ntoskrnl/ps/psmgr.c | 8 ++ reactos/ntoskrnl/se/semgr.c | 37 ++++----- 8 files changed, 88 insertions(+), 47 deletions(-) diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 6fbd3f32bc6..b445f99d80b 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -367,6 +367,38 @@ ExInit3(VOID) ExpInitUuids(); } +ULONG +NTAPI +ExComputeTickCountMultiplier(IN ULONG ClockIncrement) +{ + ULONG MsRemainder = 0, MsIncrement; + ULONG IncrementRemainder; + ULONG i; + + /* Count the number of milliseconds for each clock interrupt */ + MsIncrement = ClockIncrement / (10 * 1000); + + /* Count the remainder from the division above, with 24-bit precision */ + IncrementRemainder = ClockIncrement - (MsIncrement * (10 * 1000)); + for (i= 0; i < 24; i++) + { + /* Shift the remainders */ + MsRemainder <<= 1; + IncrementRemainder <<= 1; + + /* Check if we've went past 1 ms */ + if (IncrementRemainder >= (10 * 1000)) + { + /* Increase the remainder by one, and substract from increment */ + IncrementRemainder -= (10 * 1000); + MsRemainder |= 1; + } + } + + /* Return the increment */ + return (MsIncrement << 24) | MsRemainder; +} + BOOLEAN NTAPI ExpInitSystemPhase0(VOID) @@ -574,12 +606,12 @@ ExpInitializeExecutive(IN ULONG Cpu, /* Setup system time */ KiInitializeSystemClock(); - /* Initialize the second stage of the kernel */ - KeInit2(); - /* Initialize the executive at phase 0 */ if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED); + /* Break into the Debugger if requested */ + if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); + /* Set system ranges */ SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress; SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart; @@ -611,10 +643,7 @@ ExpInitializeExecutive(IN ULONG Cpu, */ ExpNlsTableSize += 2 * PAGE_SIZE; // BIAS FOR FREELDR. HACK! - /* - * Allocate the table in pool memory, so we can stop depending on the - * memory given to use by the loader, which is freed later. - */ + /* Allocate the NLS buffer in the pool since loader memory will be freed */ ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool, ExpNlsTableSize, TAG('R', 't', 'l', 'i')); @@ -661,8 +690,7 @@ ExpInitializeExecutive(IN ULONG Cpu, if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED); /* Load basic Security for other Managers */ - if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED); - if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED); + if (!SeInit()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED); /* Set up Region Maps, Sections and the Paging File */ MmInit2(); @@ -671,16 +699,26 @@ ExpInitializeExecutive(IN ULONG Cpu, if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED); /* Initialize the Process Manager */ - PspInitPhase0(); + if (!PsInitSystem()) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED); - /* Break into the Debugger if requested */ - if (KdPollBreakIn()) DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C); + /* Calculate the tick count multiplier */ + ExpTickCountMultiplier = ExComputeTickCountMultiplier(KeMaximumIncrement); + SharedUserData->TickCountMultiplier = ExpTickCountMultiplier; - /* Initialize all processors */ - HalAllProcessorsStarted(); + /* Set the OS Version */ + SharedUserData->NtMajorVersion = NtMajorVersion; + SharedUserData->NtMinorVersion = NtMinorVersion; - /* Do Phase 1 HAL Initialization */ - HalInitSystem(1, KeLoaderBlock); + /* Set the machine type */ +#if defined(_X86_) + SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_I386; + SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_I386; +#elif defined(_PPC_) // <3 Arty + SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_POWERPC; + SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_POWERPC; +#elif +#error "Unsupported ReactOS Target" +#endif } VOID @@ -698,6 +736,15 @@ ExPhase2Init(PVOID Context) /* Set us at maximum priority */ KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY); + /* Initialize the second stage of the kernel */ + KeInit2(); + + /* Initialize all processors */ + HalAllProcessorsStarted(); + + /* Do Phase 1 HAL Initialization */ + HalInitSystem(1, KeLoaderBlock); + /* Initialize Basic System Objects and Worker Threads */ ExInit3(); diff --git a/reactos/ntoskrnl/ex/time.c b/reactos/ntoskrnl/ex/time.c index 5671b7e755e..bc618fd82a1 100644 --- a/reactos/ntoskrnl/ex/time.c +++ b/reactos/ntoskrnl/ex/time.c @@ -25,6 +25,7 @@ TIME_ZONE_INFORMATION ExpTimeZoneInfo; LARGE_INTEGER ExpTimeZoneBias; ULONG ExpTimeZoneId; +ULONG ExpTickCountMultiplier; /* FUNCTIONS ****************************************************************/ diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 39fa724ca3e..caa6aab5659 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -6,6 +6,7 @@ extern TIME_ZONE_INFORMATION ExpTimeZoneInfo; extern LARGE_INTEGER ExpTimeZoneBias; extern ULONG ExpTimeZoneId; +extern ULONG ExpTickCountMultiplier; extern POBJECT_TYPE ExEventPairObjectType; extern ULONG NtBuildNumber; extern ULONG NtMajorVersion; diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index bd3859d3cab..ba21d3fe351 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -64,7 +64,6 @@ VOID IoInit(VOID); VOID IoInit2(BOOLEAN BootLog); VOID NTAPI IoInit3(VOID); BOOLEAN NTAPI ObInit(VOID); -VOID PsInit(VOID); VOID CmInitializeRegistry(VOID); VOID NTAPI CmInitHives(BOOLEAN SetupBoot); VOID CmInit2(PCHAR CommandLine); diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index e62e472242d..2b26031037b 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -81,7 +81,7 @@ PspShutdownProcessManager( BOOLEAN NTAPI -PspInitPhase0( +PsInitSystem( VOID ); diff --git a/reactos/ntoskrnl/include/internal/se.h b/reactos/ntoskrnl/include/internal/se.h index a158320434f..112deace2fb 100644 --- a/reactos/ntoskrnl/include/internal/se.h +++ b/reactos/ntoskrnl/include/internal/se.h @@ -86,11 +86,7 @@ extern PSECURITY_DESCRIPTOR SeUnrestrictedSd; /* Functions */ BOOLEAN NTAPI -SeInit1(VOID); - -BOOLEAN -NTAPI -SeInit2(VOID); +SeInit(VOID); BOOLEAN NTAPI diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index 158a443db72..a02e4398ad4 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -397,6 +397,14 @@ PspInitPhase0(VOID) return TRUE; } +BOOLEAN +NTAPI +PsInitSystem(VOID) +{ + /* For now, do only Phase 0 */ + return PspInitPhase0(); +} + /* PUBLIC FUNCTIONS **********************************************************/ /* diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index da9b141d681..9f3f82740fc 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -27,8 +27,7 @@ static ERESOURCE SepSubjectContextLock; static BOOLEAN SepInitExports(VOID); #if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, SeInit1) -#pragma alloc_text(INIT, SeInit2) +#pragma alloc_text(INIT, SeInit) #pragma alloc_text(INIT, SepInitExports) #endif @@ -37,7 +36,7 @@ static BOOLEAN SepInitExports(VOID); BOOLEAN INIT_FUNCTION NTAPI -SeInit1(VOID) +SeInit(VOID) { SepInitLuid(); @@ -58,30 +57,20 @@ SeInit1(VOID) /* Initialize the subject context lock */ ExInitializeResource(&SepSubjectContextLock); + /* Initialize token objects */ + SepInitializeTokenImplementation(); + + /* Clear impersonation info for the idle thread */ + PsGetCurrentThread()->ImpersonationInfo = NULL; + PspClearCrossThreadFlag(PsGetCurrentThread(), CT_ACTIVE_IMPERSONATION_INFO_BIT); + + /* Initailize the boot token */ + ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL); + ObInitializeFastReference(&PsGetCurrentProcess()->Token, + SepCreateSystemProcessToken()); return TRUE; } - -BOOLEAN -INIT_FUNCTION -NTAPI -SeInit2(VOID) -{ - /* Initialize token objects */ - SepInitializeTokenImplementation(); - - /* Clear impersonation info for the idle thread */ - PsGetCurrentThread()->ImpersonationInfo = NULL; - PspClearCrossThreadFlag(PsGetCurrentThread(), CT_ACTIVE_IMPERSONATION_INFO_BIT); - - /* Initailize the boot token */ - ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL); - ObInitializeFastReference(&PsGetCurrentProcess()->Token, - SepCreateSystemProcessToken()); - return TRUE; -} - - BOOLEAN NTAPI SeInitSRM(VOID) From 4cfbdb6f639d06e372b3a079bf5ac751707daa02 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Mon, 2 Oct 2006 18:14:58 +0000 Subject: [PATCH 431/488] - Only call SetupDiGetClassDevs once for each class, this makes load time 3 times faster although I'm still not happy with it. We may have to enumerate the drivers in the background. - use UINT for 1 bit flags, reduce the width a little and check the menu. svn path=/trunk/; revision=24364 --- reactos/base/applications/devmgmt/En.rc | 2 +- .../base/applications/devmgmt/enumdevices.c | 39 ++++++++++--------- reactos/base/applications/devmgmt/mainwnd.c | 2 +- reactos/base/applications/devmgmt/precomp.h | 2 +- reactos/base/applications/devmgmt/resource.h | 1 + 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/reactos/base/applications/devmgmt/En.rc b/reactos/base/applications/devmgmt/En.rc index abb911d0244..36913e20d75 100644 --- a/reactos/base/applications/devmgmt/En.rc +++ b/reactos/base/applications/devmgmt/En.rc @@ -14,7 +14,7 @@ BEGIN END POPUP "View" BEGIN - MENUITEM "Devices by type", IDC_STATIC + MENUITEM "Devices by type", IDC_DEVBYTYPE, CHECKED MENUITEM "Devices by connection", IDC_STATIC, GRAYED MENUITEM "Resources by type", IDC_STATIC, GRAYED MENUITEM "Resources by connection", IDC_STATIC, GRAYED diff --git a/reactos/base/applications/devmgmt/enumdevices.c b/reactos/base/applications/devmgmt/enumdevices.c index e56bcbf0f43..186befa879c 100644 --- a/reactos/base/applications/devmgmt/enumdevices.c +++ b/reactos/base/applications/devmgmt/enumdevices.c @@ -9,8 +9,9 @@ #include "precomp.h" -SP_CLASSIMAGELIST_DATA ImageListData; +static SP_CLASSIMAGELIST_DATA ImageListData; +static HDEVINFO hDevInfo; static HTREEITEM InsertIntoTreeView(HWND hTV, @@ -60,7 +61,10 @@ EnumDeviceClasses(INT ClassIndex, { /* all classes enumerated */ if(Ret == CR_NO_SUCH_VALUE) + { + hDevInfo = NULL; return -1; + } if (Ret == CR_INVALID_DATA) ; /*FIXME: what should we do here? */ @@ -84,18 +88,23 @@ EnumDeviceClasses(INT ClassIndex, &ClassGuid, ClassImage)) { - /* set the blank icon */ + /* FIXME: can we do this? + * Set the blank icon: IDI_SETUPAPI_BLANK = 41 + * it'll be image 24 in the imagelist */ *ClassImage = 41; } - /* FIXME: do we need this? + /* Get device info for all devices of a particular class */ hDevInfo = SetupDiGetClassDevs(&ClassGuid, 0, NULL, DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) + { + hDevInfo = NULL; return 0; - */ + } + KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, MAXIMUM_ALLOWED, @@ -120,9 +129,6 @@ EnumDeviceClasses(INT ClassIndex, return -3; } - /* FIXME: see above? - SetupDiDestroyDeviceInfoList(hDevInfo); */ - *DevPresent = TRUE; RegCloseKey(KeyClass); @@ -136,7 +142,6 @@ EnumDevices(INT index, TCHAR* DeviceClassName, TCHAR* DeviceName) { - HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; DWORD RequiredSize = 0; GUID *guids = NULL; @@ -172,13 +177,6 @@ EnumDevices(INT index, } } -//TimerInfo(_T("IN")); - /* get device info set for our device class */ - hDevInfo = SetupDiGetClassDevs(guids, - 0, - NULL, - DIGCF_PRESENT); -//TimerInfo(_T("OUT")); HeapFree(GetProcessHeap(), 0, guids); if(hDevInfo == INVALID_HANDLE_VALUE) { @@ -198,8 +196,7 @@ EnumDevices(INT index, if (!bRet) { - //no such device: - SetupDiDestroyDeviceInfoList(hDevInfo); + /* no such device */ return -1; } @@ -223,7 +220,6 @@ EnumDevices(INT index, if (!bRet) { /* if the description fails, just give up! */ - SetupDiDestroyDeviceInfoList(hDevInfo); return -5; } } @@ -289,6 +285,13 @@ ListDevicesByType(PMAIN_WND_INFO Info, } while (Ret != -1); + /* kill InfoList initialized in EnumDeviceClasses */ + if (hDevInfo) + { + SetupDiDestroyDeviceInfoList(hDevInfo); + hDevInfo = NULL; + } + if (!TreeView_GetChild(Info->hTreeView, hDevItem)) { diff --git a/reactos/base/applications/devmgmt/mainwnd.c b/reactos/base/applications/devmgmt/mainwnd.c index 7c00e7a5189..91cff10668f 100644 --- a/reactos/base/applications/devmgmt/mainwnd.c +++ b/reactos/base/applications/devmgmt/mainwnd.c @@ -546,7 +546,7 @@ CreateMainWindow(LPCTSTR lpCaption, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, - 650, + 600, 450, NULL, NULL, diff --git a/reactos/base/applications/devmgmt/precomp.h b/reactos/base/applications/devmgmt/precomp.h index beb567afdc7..a23f1bf8f0d 100644 --- a/reactos/base/applications/devmgmt/precomp.h +++ b/reactos/base/applications/devmgmt/precomp.h @@ -28,7 +28,7 @@ typedef struct _MAIN_WND_INFO int nCmdShow; /* status flags */ - BOOL InMenuLoop : 1; + UINT InMenuLoop : 1; } MAIN_WND_INFO, *PMAIN_WND_INFO; diff --git a/reactos/base/applications/devmgmt/resource.h b/reactos/base/applications/devmgmt/resource.h index 283ee63cfa2..ad94561340e 100644 --- a/reactos/base/applications/devmgmt/resource.h +++ b/reactos/base/applications/devmgmt/resource.h @@ -19,6 +19,7 @@ /* menus */ #define IDR_MAINMENU 102 #define IDR_POPUP 103 +#define IDC_DEVBYTYPE 104 /* tooltips */ #define IDS_TOOLTIP_PROP 6000 From b2aeafcad4885ef74457763f069044364b99bc4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 2 Oct 2006 18:46:39 +0000 Subject: [PATCH 432/488] Implement CMP_WaitNoPendingInstallEvents Wait for Pnp manager to finish its job before displaying the 2nd stage setup Thanks Filip for his precious help on the umpnpmgr.exe side (not thread-safe as Single linked list functions are not implemented in ntdll) svn path=/trunk/; revision=24365 --- reactos/base/services/umpnpmgr/umpnpmgr.c | 116 ++++++++++++++++++++-- reactos/dll/win32/setupapi/cfgmgr.c | 19 ++++ reactos/dll/win32/setupapi/setupapi.spec | 2 +- reactos/dll/win32/syssetup/install.c | 8 ++ 4 files changed, 138 insertions(+), 7 deletions(-) diff --git a/reactos/base/services/umpnpmgr/umpnpmgr.c b/reactos/base/services/umpnpmgr/umpnpmgr.c index 55ea0c267e5..d51a8f331aa 100644 --- a/reactos/base/services/umpnpmgr/umpnpmgr.c +++ b/reactos/base/services/umpnpmgr/umpnpmgr.c @@ -26,6 +26,7 @@ */ /* INCLUDES *****************************************************************/ +//#define HAVE_SLIST_ENTRY_IMPLEMENTED #define WIN32_NO_STATUS #include #include @@ -61,7 +62,24 @@ static HKEY hClassKey = NULL; static HANDLE hUserToken = NULL; static HANDLE hInstallEvent = NULL; +static HANDLE hNoPendingInstalls = NULL; +#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED +static SLIST_HEADER DeviceInstallListHead; +#else +static LIST_ENTRY DeviceInstallListHead; +#endif +static HANDLE hDeviceInstallListNotEmpty; + +typedef struct +{ +#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED + SLIST_ENTRY ListEntry; +#else + LIST_ENTRY ListEntry; +#endif + WCHAR DeviceIds[1]; +} DeviceInstallParams; /* FUNCTIONS *****************************************************************/ @@ -1437,6 +1455,51 @@ cleanup: } +/* Loop to install all queued devices installations */ +static DWORD WINAPI +DeviceInstallThread(LPVOID lpParameter) +{ +#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED + PSLIST_ENTRY ListEntry; +#else + PLIST_ENTRY ListEntry; +#endif + DeviceInstallParams* Params; + BOOL setupActive; + + setupActive = SetupIsActive(); + + SetEnvironmentVariable(L"USERPROFILE", L"."); /* FIXME: why is it needed? */ + + while (TRUE) + { +#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED + ListEntry = InterlockedPopEntrySList(&DeviceInstallListHead); +#else + if (IsListEmpty(&DeviceInstallListHead)) + ListEntry = NULL; + else + ListEntry = RemoveHeadList(&DeviceInstallListHead); +#endif + if (ListEntry == NULL) + { + SetEvent(hNoPendingInstalls); + DPRINT1("*** EVENT SETTED\n"); + WaitForSingleObject(hDeviceInstallListNotEmpty, INFINITE); + } + else + { + ResetEvent(hNoPendingInstalls); + DPRINT1("*** EVENT RESETTED\n"); + Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry); + InstallDevice(Params->DeviceIds, setupActive); + } + } + + return 0; +} + + static DWORD WINAPI PnpEventThread(LPVOID lpParameter) { @@ -1444,15 +1507,12 @@ PnpEventThread(LPVOID lpParameter) ULONG PnpEventSize; NTSTATUS Status; RPC_STATUS RpcStatus; - BOOL setupActive; PnpEventSize = 0x1000; PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize); if (PnpEvent == NULL) return ERROR_OUTOFMEMORY; - setupActive = SetupIsActive(); - for (;;) { DPRINT("Calling NtGetPlugPlayEvent()\n"); @@ -1476,19 +1536,35 @@ PnpEventThread(LPVOID lpParameter) break; } + /* Process the pnp event */ DPRINT("Received PnP Event\n"); if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus)) { + DeviceInstallParams* Params; + DWORD len; + DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds); - InstallDevice(PnpEvent->TargetDevice.DeviceIds, setupActive); + + /* Queue device install (will be dequeued by DeviceInstallThread */ + len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + + wcslen(PnpEvent->TargetDevice.DeviceIds) * sizeof(WCHAR) + sizeof(UNICODE_NULL); + Params = HeapAlloc(GetProcessHeap(), 0, len); + if (Params) + { + wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds); +#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED + InterlockedPushEntrySList(&DeviceInstallListHead, &Params->ListEntry); +#else + InsertTailList(&DeviceInstallListHead, &Params->ListEntry); +#endif + SetEvent(hDeviceInstallListNotEmpty); + } } else { DPRINT1("Unknown event\n"); } - /* FIXME: Process the pnp event */ - /* Dequeue the current pnp event and signal the next one */ NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0); } @@ -1507,6 +1583,11 @@ ServiceMain(DWORD argc, LPTSTR *argv) DPRINT("ServiceMain() called\n"); + hNoPendingInstalls = CreateEventW(NULL, + TRUE, + FALSE, + L"Global\\PnP_No_Pending_Install_Events"); + hThread = CreateThread(NULL, 0, PnpEventThread, @@ -1516,6 +1597,15 @@ ServiceMain(DWORD argc, LPTSTR *argv) if (hThread != NULL) CloseHandle(hThread); + hThread = CreateThread(NULL, + 0, + DeviceInstallThread, + NULL, + 0, + &dwThreadId); + if (hThread != NULL) + CloseHandle(hThread); + hThread = CreateThread(NULL, 0, RpcServerThread, @@ -1544,6 +1634,20 @@ main(int argc, char *argv[]) return dwError; } + hDeviceInstallListNotEmpty = CreateEvent(NULL, FALSE, FALSE, NULL); + if (hDeviceInstallListNotEmpty == NULL) + { + dwError = GetLastError(); + DPRINT1("Could not create the Event! (Error %lu)\n", dwError); + return dwError; + } + +#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED + InitializeSListHead(&DeviceInstallListHead); +#else + InitializeListHead(&DeviceInstallListHead); +#endif + dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Enum", 0, diff --git a/reactos/dll/win32/setupapi/cfgmgr.c b/reactos/dll/win32/setupapi/cfgmgr.c index 2a2d4b4fe67..c9d196fa52a 100644 --- a/reactos/dll/win32/setupapi/cfgmgr.c +++ b/reactos/dll/win32/setupapi/cfgmgr.c @@ -76,6 +76,25 @@ static BOOL GuidToString(LPGUID Guid, LPWSTR String) } +/*********************************************************************** + * CMP_WaitNoPendingInstallEvents [SETUPAPI.@] + */ +DWORD WINAPI CMP_WaitNoPendingInstallEvents( + DWORD dwTimeout) +{ + HANDLE hEvent; + DWORD ret; + + hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events"); + if (hEvent == NULL) + return WAIT_FAILED; + + ret = WaitForSingleObject(hEvent, dwTimeout); + CloseHandle(hEvent); + return ret; +} + + /*********************************************************************** * CMP_Init_Detection [SETUPAPI.@] */ diff --git a/reactos/dll/win32/setupapi/setupapi.spec b/reactos/dll/win32/setupapi/setupapi.spec index 87887db48b0..fcd4708a581 100644 --- a/reactos/dll/win32/setupapi/setupapi.spec +++ b/reactos/dll/win32/setupapi/setupapi.spec @@ -7,7 +7,7 @@ @ stub CMP_RegisterNotification @ stdcall CMP_Report_LogOn(long long) @ stub CMP_UnregisterNotification -@ stub CMP_WaitNoPendingInstallEvents +@ stdcall CMP_WaitNoPendingInstallEvents(long) @ stub CMP_WaitServicesAvailable @ stdcall CM_Add_Empty_Log_Conf(ptr ptr long long) @ stdcall CM_Add_Empty_Log_Conf_Ex(ptr ptr long long ptr) diff --git a/reactos/dll/win32/syssetup/install.c b/reactos/dll/win32/syssetup/install.c index 5a2749d8b6f..0561ac2f195 100644 --- a/reactos/dll/win32/syssetup/install.c +++ b/reactos/dll/win32/syssetup/install.c @@ -49,6 +49,8 @@ #include "globals.h" #include "resource.h" +DWORD WINAPI +CMP_WaitNoPendingInstallEvents(DWORD dwTimeout); /* GLOBALS ******************************************************************/ @@ -656,6 +658,12 @@ InstallReactOS (HINSTANCE hInstance) return 0; } + if (CMP_WaitNoPendingInstallEvents(INFINITE) != WAIT_OBJECT_0) + { + DebugPrint("CMP_WaitNoPendingInstallEvents() failed!\n"); + return 0; + } + InstallWizard(); SetupCloseInfFile(hSysSetupInf); From 3193a5d7e9deb451a78ea1292a9444abfc7e2c9d Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Mon, 2 Oct 2006 18:51:31 +0000 Subject: [PATCH 433/488] - display system RAM on the general page. - fixes bug 1835 svn path=/trunk/; revision=24366 --- reactos/dll/cpl/sysdm/general.c | 28 ++++++++++++++++++++++++---- reactos/dll/cpl/sysdm/precomp.h | 3 +++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index 26e56081f9c..229e9ccf131 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -70,12 +70,32 @@ InitImageInfo(PIMGINFO ImgInfo) } -DWORD WINAPI +static VOID GetSystemInformation(HWND hwnd) { - UNREFERENCED_PARAMETER(hwnd); + MEMORYSTATUS MemStat; + TCHAR Buf[32]; + INT Ret = 0; - return 0; + /* Get total physical RAM */ + MemStat.dwLength = sizeof(MemStat); + GlobalMemoryStatus(&MemStat); + + if (MemStat.dwTotalPhys < KB_DIV) + Ret = wsprintf(Buf, _T("%luKB of RAM"), MemStat.dwTotalPhys/1024); + else if (MemStat.dwTotalPhys >= KB_DIV && MemStat.dwTotalPhys < GB_DIV) + Ret = wsprintf(Buf, _T("%luMB of RAM"), MemStat.dwTotalPhys/1048576); + else if (MemStat.dwTotalPhys > GB_DIV) + Ret = wsprintf(Buf, _T("%luGB of RAM"), MemStat.dwTotalPhys/1073741824); + + if (Ret) + { + SendDlgItemMessage(hwnd, + IDC_SYSTEMMEMORY, + WM_SETTEXT, + 0, + (LPARAM)Buf); + } } @@ -97,7 +117,7 @@ GeneralPageProc(HWND hwndDlg, { HWND hLink = GetDlgItem(hwndDlg, IDC_ROSHOMEPAGE_LINK); - TextToLink(hLink, + TextToLink(hLink, _T("http://www.reactos.org"), NULL); diff --git a/reactos/dll/cpl/sysdm/precomp.h b/reactos/dll/cpl/sysdm/precomp.h index 9a8762c4a95..d5696eb58c3 100644 --- a/reactos/dll/cpl/sysdm/precomp.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -11,6 +11,9 @@ #include "resource.h" #define NUM_APPLETS (1) +#define KB_DIV 1024 +#define MB_DIV 1048576 +#define GB_DIV 1.0737e9 typedef LONG (CALLBACK *APPLET_INITPROC)(VOID); From 3674f2ef32ff3bad1e197b14927b347c164c54b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 2 Oct 2006 19:36:14 +0000 Subject: [PATCH 434/488] Fix 2 typos (spotted by Fireball) svn path=/trunk/; revision=24367 --- reactos/drivers/input/kbdclass/kbdclass.c | 2 +- reactos/drivers/input/mouclass/mouclass.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/drivers/input/kbdclass/kbdclass.c b/reactos/drivers/input/kbdclass/kbdclass.c index 97b8bb53146..8441d9a4818 100644 --- a/reactos/drivers/input/kbdclass/kbdclass.c +++ b/reactos/drivers/input/kbdclass/kbdclass.c @@ -893,7 +893,7 @@ SearchForLegacyDrivers( Status = IoGetDeviceObjectPointer(&PortName, FILE_READ_ATTRIBUTES, &FileObject, &PortDeviceObject); if (!NT_SUCCESS(Status)) { - DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status); + DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", &PortName, Status); continue; } DPRINT("Legacy driver found: %wZ\n", &PortDeviceObject->DriverObject->DriverName); diff --git a/reactos/drivers/input/mouclass/mouclass.c b/reactos/drivers/input/mouclass/mouclass.c index 99ceada27c3..46a3feeb674 100644 --- a/reactos/drivers/input/mouclass/mouclass.c +++ b/reactos/drivers/input/mouclass/mouclass.c @@ -869,7 +869,7 @@ SearchForLegacyDrivers( Status = IoGetDeviceObjectPointer(&PortName, FILE_READ_ATTRIBUTES, &FileObject, &PortDeviceObject); if (!NT_SUCCESS(Status)) { - DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status); + DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", &PortName, Status); continue; } DPRINT("Legacy driver found: %wZ\n", &PortDeviceObject->DriverObject->DriverName); From c99914fdacb170d47fc4c72cb1f0fbb574023f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 2 Oct 2006 21:14:40 +0000 Subject: [PATCH 435/488] Disable keyboard and mouse before checking the i8042 controller. Flush queue before enabling them svn path=/trunk/; revision=24368 --- reactos/drivers/input/i8042prt/pnp.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/reactos/drivers/input/i8042prt/pnp.c b/reactos/drivers/input/i8042prt/pnp.c index b60fb1bc0d1..a7e086a182d 100644 --- a/reactos/drivers/input/i8042prt/pnp.c +++ b/reactos/drivers/input/i8042prt/pnp.c @@ -80,6 +80,10 @@ i8042BasicDetect( NTSTATUS Status; UCHAR Value = 0; + /* Don't enable keyboard and mouse interrupts, disable keyboard/mouse */ + if (!i8042ChangeMode(DeviceExtension, CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB, CCB_KBD_DISAB | CCB_MOUSE_DISAB)) + return STATUS_IO_DEVICE_ERROR; + i8042Flush(DeviceExtension); if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST)) @@ -101,10 +105,6 @@ i8042BasicDetect( return STATUS_IO_DEVICE_ERROR; } - /* Don't enable keyboard and mouse interrupts, disable keyboard/mouse */ - if (!i8042ChangeMode(DeviceExtension, CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB, CCB_KBD_DISAB | CCB_MOUSE_DISAB)) - return STATUS_IO_DEVICE_ERROR; - /* * We used to send a KBD_LINE_TEST (0xAB) command here, but on at least HP * Pavilion notebooks the response to that command was incorrect. @@ -132,11 +132,6 @@ i8042DetectKeyboard( { NTSTATUS Status; - if (!i8042ChangeMode(DeviceExtension, 0, CCB_KBD_DISAB)) - return FALSE; - - i8042Flush(DeviceExtension); - /* Set LEDs (that is not fatal if some error occurs) */ Status = i8042SynchWritePort(DeviceExtension, 0, KBD_CMD_SET_LEDS, TRUE); if (NT_SUCCESS(Status)) @@ -333,6 +328,8 @@ EnableInterrupts( UCHAR FlagsToDisable = 0; UCHAR FlagsToEnable = 0; + i8042Flush(DeviceExtension); + /* Select the devices we have */ if (DeviceExtension->Flags & KEYBOARD_PRESENT) { From 903c277247ffa5d4c106e20f51b3adc7f6fa2995 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 2 Oct 2006 21:23:41 +0000 Subject: [PATCH 436/488] - Change CONNECT_DATA to DEV_CONNECT_DATA - Add the last bit to the usb mouse driver to make it functional - recognition by mouclass.sys, and sending input data to it - Misc small changes Now USB mouse works in 2nd stage (you need to add usbdriver.sys as a legacy driver to the registry certainly) TODO, but not of the top priority: - Make unloading correct svn path=/trunk/; revision=24369 --- .../drivers/usb/nt4compat/usbdriver/compdrv.c | 6 +- .../drivers/usb/nt4compat/usbdriver/devmgr.c | 6 +- .../drivers/usb/nt4compat/usbdriver/devmgr.h | 6 +- .../drivers/usb/nt4compat/usbdriver/gendrv.c | 6 +- reactos/drivers/usb/nt4compat/usbdriver/hub.c | 4 +- .../drivers/usb/nt4compat/usbdriver/mouse.c | 58 +++++++++---------- .../drivers/usb/nt4compat/usbdriver/uhci.c | 2 +- .../drivers/usb/nt4compat/usbdriver/umss.c | 6 +- 8 files changed, 46 insertions(+), 48 deletions(-) diff --git a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c index 6ca86d1ba4a..8760a4f6fe3 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c @@ -24,7 +24,7 @@ VOID compdev_set_cfg_completion(PURB purb, PVOID context); VOID compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); -BOOLEAN compdev_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle); +BOOLEAN compdev_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle); BOOLEAN compdev_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); BOOLEAN compdev_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); @@ -72,7 +72,7 @@ compdev_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) } BOOLEAN -compdev_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) +compdev_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle) { PURB purb; PUSB_CTRL_SETUP_PACKET psetup; @@ -403,7 +403,7 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) if (credit) { // ok, we find one - CONNECT_DATA param; + DEV_CONNECT_DATA param; if (pcand->disp_tbl.dev_connect) { diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c index d99dbddfe30..e938fb5ac55 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c @@ -1080,9 +1080,9 @@ dev_mgr_connect_to_dev(PVOID Parameter) DEV_HANDLE dev_handle; NTSTATUS status; PUSB_DRIVER pdriver; - PCONNECT_DATA pcd = (PCONNECT_DATA) Parameter; + PDEV_CONNECT_DATA pcd = (PDEV_CONNECT_DATA) Parameter; PUSB_DEV_MANAGER dev_mgr; - CONNECT_DATA param; + DEV_CONNECT_DATA param; if (pcd == NULL) return FALSE; @@ -1111,7 +1111,7 @@ dev_mgr_event_select_driver(PUSB_DEV pdev, ULONG event, ULONG context, ULONG par PUSB_DRIVER pdriver, pcand; LONG credit, match, i; DEV_HANDLE handle = 0; - CONNECT_DATA cd; + DEV_CONNECT_DATA cd; USE_BASIC_NON_PENDING_IRQL; diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h index 91b4c1d4273..5f14655b2fa 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h +++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h @@ -1,16 +1,16 @@ #ifndef __DEVMGR_H__ #define __DEVMGR_H__ -typedef struct _CONNECT_DATA +typedef struct _DEV_CONNECT_DATA { DEV_HANDLE dev_handle; struct _USB_DRIVER *pdriver; struct _USB_DEV_MANAGER *dev_mgr; PUSB_INTERFACE_DESC if_desc; -} CONNECT_DATA, *PCONNECT_DATA; +} DEV_CONNECT_DATA, *PDEV_CONNECT_DATA; -typedef BOOLEAN ( *PDEV_CONNECT_EX )( PCONNECT_DATA init_param, DEV_HANDLE dev_handle ); +typedef BOOLEAN ( *PDEV_CONNECT_EX )( PDEV_CONNECT_DATA init_param, DEV_HANDLE dev_handle ); typedef BOOLEAN ( *PDEV_CONNECT )( struct _USB_DEV_MANAGER *dev_mgr, DEV_HANDLE dev_handle ); typedef BOOLEAN ( *PDRVR_INIT )( struct _USB_DEV_MANAGER *dev_mgr, struct _USB_DRIVER *pdriver ); diff --git a/reactos/drivers/usb/nt4compat/usbdriver/gendrv.c b/reactos/drivers/usb/nt4compat/usbdriver/gendrv.c index f7c15e03982..cd1bdbc9f96 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/gendrv.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/gendrv.c @@ -75,7 +75,7 @@ BOOLEAN gendrv_if_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver); VOID gendrv_set_cfg_completion(PURB purb, PVOID context); -BOOLEAN gendrv_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle); +BOOLEAN gendrv_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle); BOOLEAN gendrv_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); @@ -168,7 +168,7 @@ gendrv_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) } BOOLEAN -gendrv_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) +gendrv_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle) { PURB purb; PUSB_CTRL_SETUP_PACKET psetup; @@ -717,7 +717,7 @@ gendrv_send_pnp_msg(ULONG msg, PDEVICE_OBJECT pdev_obj, PVOID pctx) BOOLEAN -gendrv_if_connect(PCONNECT_DATA params, DEV_HANDLE if_handle) +gendrv_if_connect(PDEV_CONNECT_DATA params, DEV_HANDLE if_handle) { // // try to search the registry to find one driver. diff --git a/reactos/drivers/usb/nt4compat/usbdriver/hub.c b/reactos/drivers/usb/nt4compat/usbdriver/hub.c index cbae8b32a21..b0ac6df9046 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/hub.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/hub.c @@ -79,7 +79,7 @@ void hub_get_hub_desc_completion(PURB purb, PVOID pcontext); NTSTATUS hub_start_int_request(PUSB_DEV pdev); -BOOLEAN hub_connect(PCONNECT_DATA init_param, DEV_HANDLE dev_handle); +BOOLEAN hub_connect(PDEV_CONNECT_DATA init_param, DEV_HANDLE dev_handle); BOOLEAN hub_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); @@ -1908,7 +1908,7 @@ hub_reexamine_port_status_queue(PUSB_DEV hub_dev, ULONG port_idx, BOOLEAN from_d } BOOLEAN -hub_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) +hub_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle) { URB urb, *purb; CHAR buf[512]; diff --git a/reactos/drivers/usb/nt4compat/usbdriver/mouse.c b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c index d04c2b57d4f..da0b6c9678c 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/mouse.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c @@ -8,6 +8,7 @@ #include "usbdriver.h" #include "ntddmou.h" +#include "kbdmou.h" //FIXME: is it needed at all? typedef struct _USBMP_DEVICE_EXTENSION @@ -15,10 +16,14 @@ typedef struct _USBMP_DEVICE_EXTENSION BOOLEAN IsFDO; } USBMP_DEVICE_EXTENSION, *PUSBMP_DEVICE_EXTENSION; +/* Data for embedded drivers */ +//CONNECT_DATA KbdClassInformation; +CONNECT_DATA MouseClassInformation; + PDEVICE_OBJECT MouseFdo = NULL; -BOOLEAN mouse_connect(PCONNECT_DATA dev_mgr, DEV_HANDLE dev_handle); +BOOLEAN mouse_connect(PDEV_CONNECT_DATA dev_mgr, DEV_HANDLE dev_handle); BOOLEAN mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); BOOLEAN mouse_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); VOID mouse_irq(PURB purb, PVOID pcontext); @@ -64,6 +69,9 @@ mouse_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) pdriver->disp_tbl.dev_stop = mouse_stop; pdriver->disp_tbl.dev_reserved = NULL; + // Zero out the class information structure + RtlZeroMemory(&MouseClassInformation, sizeof(CONNECT_DATA)); + // Create the device MouseCreateDevice(dev_mgr->usb_driver_obj); @@ -91,7 +99,7 @@ mouse_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver) } BOOLEAN -mouse_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) +mouse_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle) { PURB purb; NTSTATUS status; @@ -219,7 +227,7 @@ VOID mouse_irq(PURB purb, PVOID pcontext) { MOUSE_INPUT_DATA MouseInputData; - //ULONG InputDataConsumed; + ULONG InputDataConsumed; NTSTATUS status; PMOUSE_DRVR_EXTENSION pdev_ext = (PMOUSE_DRVR_EXTENSION)pcontext; signed char *data = pdev_ext->mouse_data; @@ -275,18 +283,18 @@ mouse_irq(PURB purb, PVOID pcontext) } // Commit the input data somewhere... - /*if (UsbPortInterface.MouseConnectData->ClassService) + if (MouseClassInformation.ClassService) { KIRQL OldIrql; KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - (*(PSERVICE_CALLBACK_ROUTINE)UsbPortInterface.MouseConnectData->ClassService)( - UsbPortInterface.MouseConnectData->ClassDeviceObject, + (*(PSERVICE_CALLBACK_ROUTINE)MouseClassInformation.ClassService)( + MouseClassInformation.ClassDeviceObject, &MouseInputData, (&MouseInputData)+1, &InputDataConsumed); KeLowerIrql(OldIrql); - }*/ + } // Save old button data pdev_ext->btn_old = data[0]; @@ -338,7 +346,7 @@ mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle) NTSTATUS MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) { - //NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; + NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; usb_dbg_print(DBGLVL_MAXIMUM, ("MouseDispatch(DO %p, code 0x%lx) called\n", DeviceObject, @@ -356,7 +364,7 @@ MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) { case IOCTL_INTERNAL_KEYBOARD_CONNECT: DPRINT("IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) { + if (Stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(DEV_CONNECT_DATA)) { DPRINT1("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT " "invalid buffer size\n"); Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; @@ -365,7 +373,7 @@ MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) RtlCopyMemory(&KbdClassInformation, Stk->Parameters.DeviceIoControl.Type3InputBuffer, - sizeof(CONNECT_DATA)); + sizeof(DEV_CONNECT_DATA)); Irp->IoStatus.Status = STATUS_SUCCESS; break; @@ -484,7 +492,9 @@ MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) intcontfailure: Status = Irp->IoStatus.Status; } - else if (DeviceObject == MouseFdo) + else +#endif + if (DeviceObject == MouseFdo) { // it's mouse's IOCTL PIO_STACK_LOCATION Stk; @@ -495,10 +505,10 @@ intcontfailure: switch (Stk->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_INTERNAL_MOUSE_CONNECT: - DPRINT("IOCTL_INTERNAL_MOUSE_CONNECT\n"); + usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_INTERNAL_MOUSE_CONNECT\n")); if (Stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) { - DPRINT1("IOCTL_INTERNAL_MOUSE_CONNECT: " - "invalid buffer size\n"); + usb_dbg_print(DBGLVL_MINIMUM, ("IOCTL_INTERNAL_MOUSE_CONNECT: " + "invalid buffer size\n")); Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; goto intcontfailure2; } @@ -517,28 +527,16 @@ intcontfailure: intcontfailure2: Status = Irp->IoStatus.Status; } - else + + if (Status == STATUS_INVALID_DEVICE_REQUEST) { - return UsbMpPdoInternalDeviceControlCore(DeviceObject, Irp); - } - - - if (Status == STATUS_INVALID_DEVICE_REQUEST) { - DPRINT1("Invalid internal device request!\n"); + usb_dbg_print(DBGLVL_MINIMUM, ("Invalid internal device request!\n")); } if (Status != STATUS_PENDING) IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; - -#endif - - // Default handler - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_SUPPORTED; } NTSTATUS @@ -571,7 +569,7 @@ AddRegistryEntry( goto cleanup; } - Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); + Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, (ULONG)(wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL))); if (!NT_SUCCESS(Status)) { usb_dbg_print(DBGLVL_MINIMUM, ("ZwSetValueKey() failed with status 0x%08lx\n", Status)); diff --git a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c index f54c61fac9b..7a6c776e566 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c @@ -128,7 +128,7 @@ extern VOID rh_timer_svc_reset_port_completion(PUSB_DEV dev, PVOID context); extern VOID rh_timer_svc_int_completion(PUSB_DEV dev, PVOID context); -ULONG debug_level = DBGLVL_MAXIMUM; +ULONG debug_level = DBGLVL_MINIMUM;//DBGLVL_MAXIMUM; PDRIVER_OBJECT usb_driver_obj = NULL; extern USB_DEV_MANAGER g_dev_mgr; diff --git a/reactos/drivers/usb/nt4compat/usbdriver/umss.c b/reactos/drivers/usb/nt4compat/usbdriver/umss.c index 3a4d811e144..5c5d0e9a175 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/umss.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/umss.c @@ -65,7 +65,7 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, VOID NTAPI umss_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp); NTSTATUS umss_port_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp); -BOOLEAN umss_connect(PCONNECT_DATA dev_mgr, DEV_HANDLE dev_handle); +BOOLEAN umss_connect(PDEV_CONNECT_DATA dev_mgr, DEV_HANDLE dev_handle); BOOLEAN umss_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); BOOLEAN umss_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle); NTSTATUS umss_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp); @@ -384,7 +384,7 @@ umss_create_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER umss_drvr, DEV_HANDLE d } BOOLEAN -umss_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle) +umss_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle) { PURB purb; NTSTATUS status; @@ -1475,7 +1475,7 @@ umss_complete_request(PUMSS_DEVICE_EXTENSION pdev_ext, NTSTATUS status) } BOOLEAN -umss_if_connect(PCONNECT_DATA params, DEV_HANDLE if_handle) +umss_if_connect(PDEV_CONNECT_DATA params, DEV_HANDLE if_handle) { PURB purb; LONG if_idx, i; From 835bb801575acd1765a9603e37358d49c4cb7d75 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 2 Oct 2006 21:28:01 +0000 Subject: [PATCH 437/488] - Add registry entry for usbdriver.sys's legacy loading. Commented out by default. - Add usbdriver.sys to bootcd svn path=/trunk/; revision=24370 --- reactos/boot/bootdata/hivesys.inf | 7 +++++++ reactos/boot/bootdata/packages/reactos.dff | 1 + 2 files changed, 8 insertions(+) diff --git a/reactos/boot/bootdata/hivesys.inf b/reactos/boot/bootdata/hivesys.inf index 4cb1a01bc29..1cd1d5bcc02 100644 --- a/reactos/boot/bootdata/hivesys.inf +++ b/reactos/boot/bootdata/hivesys.inf @@ -710,6 +710,13 @@ HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSe HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\Vga\Device0","DefaultSettings.XResolution",0x00010001,640 HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\Vga\Device0","DefaultSettings.YResolution",0x00010001,480 +; USB uhci/ehci driver +;HKLM,"SYSTEM\CurrentControlSet\Services\usbdriver","ErrorControl",0x00010001,0x00000000 +;HKLM,"SYSTEM\CurrentControlSet\Services\usbdriver","Group",0x00000000,"Base" +;HKLM,"SYSTEM\CurrentControlSet\Services\usbdriver","ImagePath",0x00020000,"system32\drivers\usbdriver.sys" +;HKLM,"SYSTEM\CurrentControlSet\Services\usbdriver","Start",0x00010001,0x00000001 +;HKLM,"SYSTEM\CurrentControlSet\Services\usbdriver","Type",0x00010001,0x00000001 + ; Windows Installer Service HKLM,"SYSTEM\CurrentControlSet\Services\MSIserver","Description",0x00000000,"Adds, modifies, and removes applications provided as a Windows Installer (*.msi) package. If this service is disabled, any services that explicitly depend on it will fail to start." HKLM,"SYSTEM\CurrentControlSet\Services\MSIserver","Group",0x00000000,"Windows Installer" diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index d077127e1b1..8e0845dc85a 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -270,6 +270,7 @@ drivers\storage\pciidex\pciidex.sys 2 ;drivers\usb\miniport\usbuhci\usbuhci.sys 2 ;drivers\usb\usbhub\usbhub.sys 2 ;drivers\usb\usbport\usbport.sys 2 +drivers\usb\nt4compat\usbdriver\usbdriver.sys 2 drivers\video\displays\vga\vgaddi.dll 1 drivers\video\displays\framebuf\framebuf.dll 1 From 2167cc7a6198fd88c302078e4f632baebbd87b51 Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Mon, 2 Oct 2006 22:21:37 +0000 Subject: [PATCH 438/488] Patch from ShadowFlare, bug 1838. "The current implementation continues to register or unregister additional DLLs that were specified, even if one of the earlier ones failed. The behavior on the Microsoft version is different; if one fails, it stops there instead of continuing. Some installers may possibly depend on this behavior." svn path=/trunk/; revision=24371 --- reactos/base/system/regsvr32/regsvr32.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/reactos/base/system/regsvr32/regsvr32.c b/reactos/base/system/regsvr32/regsvr32.c index 096f8328bd1..f0f9dd489b6 100644 --- a/reactos/base/system/regsvr32/regsvr32.c +++ b/reactos/base/system/regsvr32/regsvr32.c @@ -1,10 +1,10 @@ /* * ReactOS regsvr32 - * Copyright (C) 2004 ReactOS Team + * Copyright (C) 2004-2006 ReactOS Team * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS regsvr32.exe - * FILE: apps/utils/regsvr32/regsvr32.c + * FILE: base/system/regsvr32/regsvr32.c * PURPOSE: Register a COM component in the registry * PROGRAMMER: ShadowFlare (blakflare@hotmail.com) */ @@ -59,13 +59,13 @@ LPCWSTR tszDllInstall = L"DllInstall"; LPCTSTR ModuleTitle = _T("RegSvr32"); TCHAR UsageMessage[RC_STRING_MAX_SIZE]; -TCHAR NoDllSpecified[RC_STRING_MAX_SIZE]; -TCHAR InvalidFlag[RC_STRING_MAX_SIZE]; -TCHAR SwitchN_NoI[RC_STRING_MAX_SIZE]; +TCHAR NoDllSpecified[RC_STRING_MAX_SIZE]; +TCHAR InvalidFlag[RC_STRING_MAX_SIZE]; +TCHAR SwitchN_NoI[RC_STRING_MAX_SIZE]; TCHAR DllNotLoaded[RC_STRING_MAX_SIZE]; TCHAR MissingEntry[RC_STRING_MAX_SIZE]; -TCHAR FailureMessage[RC_STRING_MAX_SIZE]; -TCHAR SuccessMessage[RC_STRING_MAX_SIZE]; +TCHAR FailureMessage[RC_STRING_MAX_SIZE]; +TCHAR SuccessMessage[RC_STRING_MAX_SIZE]; // The macro CommandLineToArgv maps to a function that converts @@ -271,12 +271,12 @@ int WINAPI WinMain( // Get Langues msg LoadString( GetModuleHandle(NULL), IDS_UsageMessage, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE); - LoadString( GetModuleHandle(NULL), IDS_NoDllSpecified, (LPTSTR) NoDllSpecified,RC_STRING_MAX_SIZE); + LoadString( GetModuleHandle(NULL), IDS_NoDllSpecified, (LPTSTR) NoDllSpecified,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_InvalidFlag, (LPTSTR) InvalidFlag,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_SwitchN_NoI, (LPTSTR) SwitchN_NoI,RC_STRING_MAX_SIZE); - LoadString( GetModuleHandle(NULL), IDS_DllNotLoaded, (LPTSTR) DllNotLoaded,RC_STRING_MAX_SIZE); - LoadString( GetModuleHandle(NULL), IDS_MissingEntry, (LPTSTR) MissingEntry,RC_STRING_MAX_SIZE); + LoadString( GetModuleHandle(NULL), IDS_DllNotLoaded, (LPTSTR) DllNotLoaded,RC_STRING_MAX_SIZE); + LoadString( GetModuleHandle(NULL), IDS_MissingEntry, (LPTSTR) MissingEntry,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_FailureMessage, (LPTSTR) FailureMessage,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_SuccessMessage, (LPTSTR) SuccessMessage,RC_STRING_MAX_SIZE); @@ -384,7 +384,7 @@ int WINAPI WinMain( OleInitialize(0); // (Un)register every dll whose filename was passed in the command-line string - for (i = 1; i < argc; i++) { + for (i = 1; i < argc && nRetValue == EXITCODE_SUCCESS; i++) { // Arguments that do not start with a slash (/) are filenames if (*argv[i] != _T('/')) { lptDllName = argv[i]; @@ -425,7 +425,7 @@ int WINAPI WinMain( } } - if (bInstall) { + if (bInstall && nRetValue == EXITCODE_SUCCESS) { // Get the address of DllInstall fnDllInstall = (DLLINSTALL)GetProcAddress(hDll,szDllInstall); if (fnDllInstall) { From 640d89daada6e6bde5c5b77b19d714c2845c1203 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Mon, 2 Oct 2006 23:35:43 +0000 Subject: [PATCH 439/488] set processor information in the sysdm control panel applet svn path=/trunk/; revision=24372 --- reactos/dll/cpl/sysdm/general.c | 122 +++++++++++++++++++++++++++++--- 1 file changed, 114 insertions(+), 8 deletions(-) diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index 229e9ccf131..d8a09cc07e9 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -70,31 +70,137 @@ InitImageInfo(PIMGINFO ImgInfo) } +static VOID +SetRegTextData(HWND hwnd, + HKEY hKey, + LPTSTR Value, + UINT uID) +{ + LPTSTR lpBuf = NULL; + DWORD BufSize = 0; + DWORD Type; + + if (RegQueryValueEx(hKey, + Value, + NULL, + &Type, + NULL, + &BufSize) == ERROR_SUCCESS) + { + lpBuf = HeapAlloc(GetProcessHeap(), + 0, + BufSize); + if (!lpBuf) return; + + if (RegQueryValueEx(hKey, + Value, + NULL, + &Type, + (PBYTE)lpBuf, + &BufSize) == ERROR_SUCCESS) + { + SetDlgItemText(hwnd, + uID, + lpBuf); + } + + HeapFree(GetProcessHeap(), + 0, + lpBuf); + } +} + +static VOID +SetProcSpeed(HWND hwnd, + HKEY hKey, + LPTSTR Value, + UINT uID) + +{ + TCHAR szBuf[64]; + DWORD dwBuf; + DWORD BufSize = sizeof(DWORD); + DWORD Type = REG_SZ; + + if (RegQueryValueEx(hKey, + Value, + NULL, + &Type, + (PBYTE)&dwBuf, + &BufSize) == ERROR_SUCCESS) + { + if (dwBuf < 1000) + { + wsprintf(szBuf, _T("%lu MHz"), dwBuf); + } + else + { + double flt = dwBuf / 1000.0; + wsprintf(szBuf, _T("%l GHz"), flt); + } + + SetDlgItemText(hwnd, + uID, + szBuf); + } +} + + static VOID GetSystemInformation(HWND hwnd) { + HKEY hKey; + TCHAR ProcKey[] = _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"); MEMORYSTATUS MemStat; TCHAR Buf[32]; INT Ret = 0; + + + + /* Get Processor information * + * although undocumented, this information is being pulled + * directly out of the registry instead of via setupapi as it + * contains all the info we need, and should remain static + */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, + ProcKey, + 0, + KEY_READ, + &hKey) == ERROR_SUCCESS) + { + SetRegTextData(hwnd, + hKey, + _T("VendorIdentifier"), + IDC_PROCESSORMANUFACTURER); + + SetRegTextData(hwnd, + hKey, + _T("ProcessorNameString"), + IDC_PROCESSOR); + + SetProcSpeed(hwnd, + hKey, + _T("~MHz"), + IDC_PROCESSORSPEED); + } + /* Get total physical RAM */ MemStat.dwLength = sizeof(MemStat); GlobalMemoryStatus(&MemStat); if (MemStat.dwTotalPhys < KB_DIV) - Ret = wsprintf(Buf, _T("%luKB of RAM"), MemStat.dwTotalPhys/1024); + Ret = wsprintf(Buf, _T("%luKB of RAM"), MemStat.dwTotalPhys/KB_DIV); else if (MemStat.dwTotalPhys >= KB_DIV && MemStat.dwTotalPhys < GB_DIV) - Ret = wsprintf(Buf, _T("%luMB of RAM"), MemStat.dwTotalPhys/1048576); + Ret = wsprintf(Buf, _T("%luMB of RAM"), MemStat.dwTotalPhys/MB_DIV); else if (MemStat.dwTotalPhys > GB_DIV) - Ret = wsprintf(Buf, _T("%luGB of RAM"), MemStat.dwTotalPhys/1073741824); + Ret = wsprintf(Buf, _T("%luGB of RAM"), MemStat.dwTotalPhys/GB_DIV); if (Ret) { - SendDlgItemMessage(hwnd, - IDC_SYSTEMMEMORY, - WM_SETTEXT, - 0, - (LPARAM)Buf); + SetDlgItemText(hwnd, + IDC_SYSTEMMEMORY, + Buf); } } From 30189808bf9e065c6460a3af28e2d2c7596677c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 3 Oct 2006 14:28:21 +0000 Subject: [PATCH 440/488] Fix a few warnings svn path=/trunk/; revision=24373 --- reactos/base/services/umpnpmgr/umpnpmgr.c | 159 +++++++++++++++++++--- 1 file changed, 138 insertions(+), 21 deletions(-) diff --git a/reactos/base/services/umpnpmgr/umpnpmgr.c b/reactos/base/services/umpnpmgr/umpnpmgr.c index d51a8f331aa..ff4bb2db414 100644 --- a/reactos/base/services/umpnpmgr/umpnpmgr.c +++ b/reactos/base/services/umpnpmgr/umpnpmgr.c @@ -88,6 +88,8 @@ RpcServerThread(LPVOID lpParameter) { RPC_STATUS Status; + UNREFERENCED_PARAMETER(lpParameter); + DPRINT("RpcServerThread() called\n"); Status = RpcServerUseProtseqEpW(L"ncacn_np", @@ -157,6 +159,8 @@ CONFIGRET PNP_GetVersion(handle_t BindingHandle, unsigned short *Version) { + UNREFERENCED_PARAMETER(BindingHandle); + *Version = 0x0400; return CR_SUCCESS; } @@ -168,6 +172,9 @@ PNP_GetGlobalState(handle_t BindingHandle, unsigned long *State, unsigned long Flags) { + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Flags); + *State = CM_GLOBAL_STATE_CAN_DO_UI | CM_GLOBAL_STATE_SERVICES_AVAILABLE; return CR_SUCCESS; } @@ -177,6 +184,8 @@ PNP_GetGlobalState(handle_t BindingHandle, CONFIGRET PNP_InitDetection(handle_t BindingHandle) { + UNREFERENCED_PARAMETER(BindingHandle); + DPRINT("PNP_InitDetection() called\n"); return CR_SUCCESS; } @@ -190,6 +199,8 @@ PNP_ReportLogOn(handle_t BindingHandle, { HANDLE hProcess; + UNREFERENCED_PARAMETER(BindingHandle); + DPRINT1("PNP_ReportLogOn(%lu, %lu) called\n", Admin, ProcessId); /* Get the users token */ @@ -225,23 +236,13 @@ PNP_ValidateDeviceInstance(handle_t BindingHandle, unsigned long Flags) { CONFIGRET ret = CR_SUCCESS; - HKEY hEnumKey = NULL; HKEY hDeviceKey = NULL; + UNREFERENCED_PARAMETER(BindingHandle); + DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n", DeviceInstance, Flags); - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"System\\CurrentControlSet\\Enum", - 0, - KEY_ALL_ACCESS, - &hEnumKey)) - { - DPRINT("Could not open the Enum Key!\n"); - ret = CR_FAILURE; - goto Done; - } - if (RegOpenKeyExW(hEnumKey, DeviceInstance, 0, @@ -259,9 +260,6 @@ Done: if (hDeviceKey != NULL) RegCloseKey(hDeviceKey); - if (hEnumKey != NULL) - RegCloseKey(hEnumKey); - DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret); return ret; @@ -276,6 +274,8 @@ PNP_GetRootDeviceInstance(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + DPRINT("PNP_GetRootDeviceInstance() called\n"); if (Length < lstrlenW(szRootDeviceId) + 1) @@ -307,6 +307,9 @@ PNP_GetRelatedDeviceInstance(handle_t BindingHandle, CONFIGRET ret = CR_SUCCESS; NTSTATUS Status; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_GetRelatedDeviceInstance() called\n"); DPRINT(" Relationship %ld\n", Relationship); DPRINT(" DeviceId %S\n", DeviceId); @@ -351,6 +354,9 @@ PNP_EnumerateSubKeys(handle_t BindingHandle, HKEY hKey; DWORD dwError; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_EnumerateSubKeys() called\n"); switch (Branch) @@ -398,6 +404,10 @@ PNP_GetDeviceListSize(handle_t BindingHandle, unsigned long *Length, DWORD Flags) { + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Filter); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_GetDeviceListSize() called\n"); /* FIXME */ @@ -418,6 +428,9 @@ PNP_GetDepth(handle_t BindingHandle, CONFIGRET ret = CR_SUCCESS; NTSTATUS Status; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_GetDepth() called\n"); RtlInitUnicodeString(&PlugPlayData.DeviceInstance, @@ -458,6 +471,9 @@ PNP_GetDeviceRegProp(handle_t BindingHandle, HKEY hKey = 0; NTSTATUS Status; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_GetDeviceRegProp() called\n"); switch (Property) @@ -643,6 +659,9 @@ PNP_SetDeviceRegProp(handle_t BindingHandle, LPWSTR lpValueName = NULL; HKEY hKey = 0; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_SetDeviceRegProp() called\n"); DPRINT("DeviceId: %S\n", DeviceId); @@ -751,6 +770,11 @@ PNP_GetClassInstance(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceId); + UNREFERENCED_PARAMETER(Buffer); + UNREFERENCED_PARAMETER(Length); + DPRINT("PNP_Get_Class_Instance() called\n"); DPRINT("PNP_Get_Class_Instance() done (returns %lx)\n", ret); @@ -768,6 +792,11 @@ PNP_CreateKey(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(SubKey); + UNREFERENCED_PARAMETER(samDesired); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_CreateKey() called\n"); DPRINT("PNP_CreateKey() done (returns %lx)\n", ret); @@ -786,6 +815,12 @@ PNP_DeleteRegistryKey(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceId); + UNREFERENCED_PARAMETER(ParentKey); + UNREFERENCED_PARAMETER(ChildKey); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_DeleteRegistryKey() called\n"); DPRINT("PNP_DeleteRegistryKey() done (returns %lx)\n", ret); @@ -804,6 +839,8 @@ PNP_GetClassCount(handle_t BindingHandle, HANDLE hKey = NULL; DWORD dwError; + UNREFERENCED_PARAMETER(BindingHandle); + dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, pszRegPathClass, 0, @@ -846,6 +883,9 @@ PNP_GetClassName(handle_t BindingHandle, HKEY hKey = NULL; ULONG ulSize; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_GetClassName() called\n"); lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class"); @@ -893,6 +933,8 @@ PNP_DeleteClassKey(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid, Flags); if (Flags & CM_DELETE_CLASS_SUBKEYS) @@ -922,6 +964,12 @@ PNP_CreateDevInst(handle_t BindingHandle, { CONFIGRET ret = CR_CALL_NOT_IMPLEMENTED; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceId); + UNREFERENCED_PARAMETER(ParentDeviceId); + UNREFERENCED_PARAMETER(Length); + UNREFERENCED_PARAMETER(Flags); + DPRINT1("PNP_CreateDevInst() called\n"); DPRINT1("PNP_CreateDevInst() done (returns %lx)\n", ret); @@ -940,6 +988,11 @@ PNP_DeviceInstanceAction(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(MinorAction); + UNREFERENCED_PARAMETER(DeviceInstance1); + UNREFERENCED_PARAMETER(DeviceInstance2); + DPRINT("PNP_DeviceInstanceAction() called\n"); switch (MajorAction) @@ -997,6 +1050,9 @@ PNP_GetDeviceStatus(handle_t BindingHandle, CONFIGRET ret = CR_SUCCESS; NTSTATUS Status; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_GetDeviceStatus() called\n"); RtlInitUnicodeString(&PlugPlayData.DeviceInstance, @@ -1031,6 +1087,11 @@ PNP_SetDeviceProblem(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceInstance); + UNREFERENCED_PARAMETER(Problem); + UNREFERENCED_PARAMETER(Flags); + DPRINT1("PNP_SetDeviceProblem() called\n"); /* FIXME */ @@ -1049,6 +1110,10 @@ PNP_UninstallDevInst(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceInstance); + UNREFERENCED_PARAMETER(Flags); + DPRINT1("PNP_UninstallDevInst() called\n"); /* FIXME */ @@ -1070,7 +1135,7 @@ CheckForDeviceId(LPWSTR lpDeviceIdList, while (*lpPtr != 0) { dwLength = wcslen(lpPtr); - if (!_wcsicmp(lpPtr, lpDeviceId)) + if (0 == _wcsicmp(lpPtr, lpDeviceId)) return TRUE; lpPtr += (dwLength + 1); @@ -1114,6 +1179,8 @@ PNP_AddID(handle_t BindingHandle, DWORD dwDeviceIdListSize; WCHAR szDeviceIdList[512]; + UNREFERENCED_PARAMETER(BindingHandle); + DPRINT("PNP_AddID() called\n"); DPRINT(" DeviceInstance: %S\n", DeviceInstance); DPRINT(" DeviceId: %S\n", DeviceId); @@ -1186,6 +1253,8 @@ PNP_IsDockStationPresent(handle_t BindingHandle, DWORD dwSize; CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + DPRINT1("PNP_IsDockStationPresent() called\n"); *Present = FALSE; @@ -1232,6 +1301,8 @@ PNP_RequestEjectPC(handle_t BindingHandle) { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + DPRINT1("PNP_RequestEjectPC() called\n"); ret = CR_FAILURE; /* FIXME */ @@ -1253,6 +1324,13 @@ PNP_HwProfFlags(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Action); + UNREFERENCED_PARAMETER(DeviceId); + UNREFERENCED_PARAMETER(ProfileId); + UNREFERENCED_PARAMETER(Value); + UNREFERENCED_PARAMETER(Flags); + DPRINT1("PNP_HwProfFlags() called\n"); ret = CR_CALL_NOT_IMPLEMENTED; /* FIXME */ @@ -1273,6 +1351,11 @@ PNP_AddEmptyLogConf(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceInstance); + UNREFERENCED_PARAMETER(ulPriority); + UNREFERENCED_PARAMETER(ulFlags); + DPRINT1("PNP_AddEmptyLogConf() called\n"); *pulLogConfTag = 0; /* FIXME */ @@ -1293,6 +1376,12 @@ PNP_FreeLogConf(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceInstance); + UNREFERENCED_PARAMETER(ulType); + UNREFERENCED_PARAMETER(ulLogConfTag); + UNREFERENCED_PARAMETER(ulFlags); + DPRINT1("PNP_FreeLogConf() called\n"); @@ -1312,6 +1401,11 @@ PNP_GetFirstLogConf(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceInstance); + UNREFERENCED_PARAMETER(ulPriority); + UNREFERENCED_PARAMETER(ulFlags); + DPRINT1("PNP_GetFirstLogConf() called\n"); *pulLogConfTag = 0; /* FIXME */ @@ -1333,6 +1427,12 @@ PNP_GetNextLogConf(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceInstance); + UNREFERENCED_PARAMETER(ulLogConfType); + UNREFERENCED_PARAMETER(ulCurrentTag); + UNREFERENCED_PARAMETER(ulFlags); + DPRINT1("PNP_GetNextLogConf() called\n"); *pulNextTag = 0; /* FIXME */ @@ -1354,6 +1454,12 @@ PNP_GetLogConfPriority(handle_t BindingHandle, { CONFIGRET ret = CR_SUCCESS; + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(DeviceInstance); + UNREFERENCED_PARAMETER(ulLogConfType); + UNREFERENCED_PARAMETER(ulCurrentTag); + UNREFERENCED_PARAMETER(ulFlags); + DPRINT1("PNP_GetLogConfPriority() called\n"); *pPriority = 0; /* FIXME */ @@ -1369,6 +1475,9 @@ CONFIGRET PNP_RunDetection(handle_t BindingHandle, unsigned long Flags) { + UNREFERENCED_PARAMETER(BindingHandle); + UNREFERENCED_PARAMETER(Flags); + DPRINT("PNP_RunDetection() called\n"); return CR_CALL_NOT_IMPLEMENTED; } @@ -1396,12 +1505,12 @@ InstallDevice(PCWSTR DeviceInstance, BOOL SetupIsActive) if (!NT_SUCCESS(Status)) return FALSE; - if (PlugPlayData.DeviceStatus & DNF_STARTED || PlugPlayData.DeviceStatus & DNF_START_FAILED) + if ((PlugPlayData.DeviceStatus & (DNF_STARTED | DNF_START_FAILED)) != 0) /* Device is already started, or disabled due to some problem. Don't install it */ return TRUE; /* Install device */ - SetEnvironmentVariable(L"USERPROFILE", L"."); /* FIXME: why is it needed? */ + SetEnvironmentVariableW(L"USERPROFILE", L"."); /* FIXME: why is it needed? */ hNewDev = LoadLibraryW(L"newdev.dll"); if (!hNewDev) @@ -1467,6 +1576,8 @@ DeviceInstallThread(LPVOID lpParameter) DeviceInstallParams* Params; BOOL setupActive; + UNREFERENCED_PARAMETER(lpParameter); + setupActive = SetupIsActive(); SetEnvironmentVariable(L"USERPROFILE", L"."); /* FIXME: why is it needed? */ @@ -1476,7 +1587,7 @@ DeviceInstallThread(LPVOID lpParameter) #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED ListEntry = InterlockedPopEntrySList(&DeviceInstallListHead); #else - if (IsListEmpty(&DeviceInstallListHead)) + if ((BOOL)IsListEmpty(&DeviceInstallListHead)) ListEntry = NULL; else ListEntry = RemoveHeadList(&DeviceInstallListHead); @@ -1484,13 +1595,11 @@ DeviceInstallThread(LPVOID lpParameter) if (ListEntry == NULL) { SetEvent(hNoPendingInstalls); - DPRINT1("*** EVENT SETTED\n"); WaitForSingleObject(hDeviceInstallListNotEmpty, INFINITE); } else { ResetEvent(hNoPendingInstalls); - DPRINT1("*** EVENT RESETTED\n"); Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry); InstallDevice(Params->DeviceIds, setupActive); } @@ -1508,6 +1617,8 @@ PnpEventThread(LPVOID lpParameter) NTSTATUS Status; RPC_STATUS RpcStatus; + UNREFERENCED_PARAMETER(lpParameter); + PnpEventSize = 0x1000; PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize); if (PnpEvent == NULL) @@ -1581,6 +1692,9 @@ ServiceMain(DWORD argc, LPTSTR *argv) HANDLE hThread; DWORD dwThreadId; + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + DPRINT("ServiceMain() called\n"); hNoPendingInstalls = CreateEventW(NULL, @@ -1624,6 +1738,9 @@ main(int argc, char *argv[]) { DWORD dwError; + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + DPRINT("Umpnpmgr: main() started\n"); hInstallEvent = CreateEvent(NULL, TRUE, FALSE, NULL); From 7b5fcdd9fa7d14c89770516f071158e5c90e100e Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Tue, 3 Oct 2006 16:25:13 +0000 Subject: [PATCH 441/488] Fix displaying the size of the RAM svn path=/trunk/; revision=24374 --- reactos/dll/cpl/sysdm/en.rc | 4 ++ reactos/dll/cpl/sysdm/general.c | 64 ++++++++++++++++++++++++------ reactos/dll/cpl/sysdm/precomp.h | 3 -- reactos/dll/cpl/sysdm/resource.h | 5 +++ reactos/dll/cpl/sysdm/sysdm.rbuild | 2 +- 5 files changed, 62 insertions(+), 16 deletions(-) diff --git a/reactos/dll/cpl/sysdm/en.rc b/reactos/dll/cpl/sysdm/en.rc index 7c48d116693..8bbd0f5aadc 100644 --- a/reactos/dll/cpl/sysdm/en.rc +++ b/reactos/dll/cpl/sysdm/en.rc @@ -283,4 +283,8 @@ STRINGTABLE DISCARDABLE BEGIN IDS_CPLSYSTEMNAME "System" IDS_CPLSYSTEMDESCRIPTION "See information about your computer and change various system and hardware settings." + IDS_MEGABYTE "MB of RAM" + IDS_GIGABYTE "GB of RAM" + IDS_TERABYTE "TB of RAM" + IDS_PETABYTE "PB of RAM" END diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index d8a09cc07e9..f8061ef38c1 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -131,12 +131,12 @@ SetProcSpeed(HWND hwnd, { if (dwBuf < 1000) { - wsprintf(szBuf, _T("%lu MHz"), dwBuf); + _stprintf(szBuf, _T("%lu MHz"), dwBuf); } else { double flt = dwBuf / 1000.0; - wsprintf(szBuf, _T("%l GHz"), flt); + _stprintf(szBuf, _T("%l GHz"), flt); } SetDlgItemText(hwnd, @@ -145,16 +145,14 @@ SetProcSpeed(HWND hwnd, } } - static VOID GetSystemInformation(HWND hwnd) { HKEY hKey; TCHAR ProcKey[] = _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"); - MEMORYSTATUS MemStat; + MEMORYSTATUSEX MemStat; TCHAR Buf[32]; INT Ret = 0; - /* Get Processor information * @@ -187,14 +185,56 @@ GetSystemInformation(HWND hwnd) /* Get total physical RAM */ MemStat.dwLength = sizeof(MemStat); - GlobalMemoryStatus(&MemStat); + if (GlobalMemoryStatusEx(&MemStat)) + { + TCHAR szStr[32]; + double dTotalPhys; + UINT i = 0; + static const UINT uStrId[] = { + IDS_MEGABYTE, + IDS_GIGABYTE, + IDS_TERABYTE, + IDS_PETABYTE + }; - if (MemStat.dwTotalPhys < KB_DIV) - Ret = wsprintf(Buf, _T("%luKB of RAM"), MemStat.dwTotalPhys/KB_DIV); - else if (MemStat.dwTotalPhys >= KB_DIV && MemStat.dwTotalPhys < GB_DIV) - Ret = wsprintf(Buf, _T("%luMB of RAM"), MemStat.dwTotalPhys/MB_DIV); - else if (MemStat.dwTotalPhys > GB_DIV) - Ret = wsprintf(Buf, _T("%luGB of RAM"), MemStat.dwTotalPhys/GB_DIV); + if (MemStat.ullTotalPhys > 1024 * 1024 * 1024) + { + /* We're dealing with GBs or more */ + MemStat.ullTotalPhys /= 1024 * 1024; + i++; + + if (MemStat.ullTotalPhys > 1024 * 1024) + { + /* We're dealing with TBs or more */ + MemStat.ullTotalPhys /= 1024; + i++; + + if (MemStat.ullTotalPhys > 1024 * 1024) + { + /* We're dealing with PBs or more */ + + MemStat.ullTotalPhys /= 1024; + i++; + + dTotalPhys = (double)MemStat.ullTotalPhys / 1024; + } + else + dTotalPhys = (double)MemStat.ullTotalPhys / 1024; + } + else + dTotalPhys = (double)MemStat.ullTotalPhys / 1024; + } + else + { + /* We're daling with MBs */ + dTotalPhys = (double)MemStat.ullTotalPhys / 1024 / 1024; + } + + if (LoadString(hApplet, uStrId[i], szStr, sizeof(szStr) / sizeof(szStr[0]))) + { + Ret = _stprintf(Buf, _T("%.2f %s"), dTotalPhys, szStr); + } + } if (Ret) { diff --git a/reactos/dll/cpl/sysdm/precomp.h b/reactos/dll/cpl/sysdm/precomp.h index d5696eb58c3..9a8762c4a95 100644 --- a/reactos/dll/cpl/sysdm/precomp.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -11,9 +11,6 @@ #include "resource.h" #define NUM_APPLETS (1) -#define KB_DIV 1024 -#define MB_DIV 1048576 -#define GB_DIV 1.0737e9 typedef LONG (CALLBACK *APPLET_INITPROC)(VOID); diff --git a/reactos/dll/cpl/sysdm/resource.h b/reactos/dll/cpl/sysdm/resource.h index c1eb5ae4798..7bd5040ffdc 100644 --- a/reactos/dll/cpl/sysdm/resource.h +++ b/reactos/dll/cpl/sysdm/resource.h @@ -14,6 +14,11 @@ #define IDS_CPLSYSTEMNAME 60 #define IDS_CPLSYSTEMDESCRIPTION 61 +#define IDS_MEGABYTE 62 +#define IDS_GIGABYTE 63 +#define IDS_TERABYTE 64 +#define IDS_PETABYTE 65 + /* propsheet - general */ #define IDD_PROPPAGEGENERAL 100 diff --git a/reactos/dll/cpl/sysdm/sysdm.rbuild b/reactos/dll/cpl/sysdm/sysdm.rbuild index 0bb5bea4b06..6fc66ab083c 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rbuild +++ b/reactos/dll/cpl/sysdm/sysdm.rbuild @@ -8,12 +8,12 @@ 0x501 kernel32 advapi32 + msvcrt user32 gdi32 comctl32 netapi32 ntdll - msvcrt msimg32 shell32 advanced.c From fd990e9ada9a2323ab34aa6f2d5bcadf484b4fcf Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Tue, 3 Oct 2006 17:02:36 +0000 Subject: [PATCH 442/488] Fix displaying Win32 errors (the Reg* APIs don't set the last error code!) svn path=/trunk/; revision=24375 --- reactos/dll/cpl/timedate/internettime.c | 26 ++++++++++++++----------- reactos/dll/cpl/timedate/ntpclient.c | 2 +- reactos/dll/cpl/timedate/timedate.c | 21 ++++++++++++++++---- reactos/dll/cpl/timedate/timedate.h | 9 +++++++-- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/reactos/dll/cpl/timedate/internettime.c b/reactos/dll/cpl/timedate/internettime.c index a246e965c3c..3c8b9a4ed57 100644 --- a/reactos/dll/cpl/timedate/internettime.c +++ b/reactos/dll/cpl/timedate/internettime.c @@ -116,7 +116,7 @@ SetNTPServer(HWND hwnd) &hKey); if (Ret != ERROR_SUCCESS) { - GetError(); + DisplayWin32Error(Ret); return; } @@ -127,7 +127,7 @@ SetNTPServer(HWND hwnd) (LPBYTE)szSel, sizeof(szSel)); if (Ret != ERROR_SUCCESS) - GetError(); + DisplayWin32Error(Ret); RegCloseKey(hKey); @@ -180,7 +180,10 @@ GetNTPServerAddress(LPSTR* lpAddress) 0, dwSize); if (buf == NULL) + { + Ret = ERROR_NOT_ENOUGH_MEMORY; goto fail; + } Ret = RegQueryValueExW(hKey, szSel, @@ -212,6 +215,7 @@ GetNTPServerAddress(LPSTR* lpAddress) NULL, NULL)) { + Ret = GetLastError(); goto fail; } @@ -223,7 +227,7 @@ GetNTPServerAddress(LPSTR* lpAddress) return TRUE; fail: - GetError(); + DisplayWin32Error(Ret); if (hKey) RegCloseKey(hKey); HeapFree(GetProcessHeap(), 0, buf); HeapFree(GetProcessHeap(), 0, *lpAddress); @@ -242,7 +246,7 @@ GetTimeFromServer(VOID) if (! GetNTPServerAddress(&lpAddress)) return 0; - if (InitialiseConnection(lpAddress)) + if (InitializeConnection(lpAddress)) { if (SendData()) { @@ -283,7 +287,7 @@ UpdateSystemTime(ULONG ulTime) /* convert to a file time */ if (! SystemTimeToFileTime(&stNew, &ftNew)) { - GetError(); + DisplayWin32Error(GetLastError()); return; } @@ -295,7 +299,7 @@ UpdateSystemTime(ULONG ulTime) /* convert back to a system time */ if (! FileTimeToSystemTime(&ftNew, &stNew)) { - GetError(); + DisplayWin32Error(GetLastError()); return; } @@ -304,7 +308,7 @@ UpdateSystemTime(ULONG ulTime) I thought SetSystemTime already dealt with this */ if (! SetSystemTime(&stNew)) - GetError(); + DisplayWin32Error(GetLastError()); } @@ -342,7 +346,7 @@ GetSyncSetting(HWND hwnd) &hKey); if (Ret != ERROR_SUCCESS) { - GetError(); + DisplayWin32Error(Ret); return; } @@ -355,7 +359,7 @@ GetSyncSetting(HWND hwnd) &Size); if (Ret != ERROR_SUCCESS) { - GetError(); + DisplayWin32Error(Ret); } if (lstrcmp(Data, L"NTP") == 0) @@ -369,7 +373,7 @@ GetSyncSetting(HWND hwnd) static VOID -InitialiseDialog(HWND hwnd) +InitializeDialog(HWND hwnd) { GetSyncSetting(hwnd); @@ -390,7 +394,7 @@ InetTimePageProc(HWND hwndDlg, { case WM_INITDIALOG: { - InitialiseDialog(hwndDlg); + InitializeDialog(hwndDlg); } break; diff --git a/reactos/dll/cpl/timedate/ntpclient.c b/reactos/dll/cpl/timedate/ntpclient.c index ca6e8c9b219..b6b5981e85b 100644 --- a/reactos/dll/cpl/timedate/ntpclient.c +++ b/reactos/dll/cpl/timedate/ntpclient.c @@ -15,7 +15,7 @@ SOCKET Sock; SOCKADDR_IN myAddr, ntpAddr; BOOL -InitialiseConnection(LPSTR lpAddress) +InitializeConnection(LPSTR lpAddress) { WSADATA wsaData; HOSTENT *he; diff --git a/reactos/dll/cpl/timedate/timedate.c b/reactos/dll/cpl/timedate/timedate.c index 8bd4f4096a9..8a6513684ce 100644 --- a/reactos/dll/cpl/timedate/timedate.c +++ b/reactos/dll/cpl/timedate/timedate.c @@ -22,22 +22,35 @@ APPLET Applets[NUM_APPLETS] = {IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, Applet} }; - -VOID GetError(VOID) +#if DBG +VOID DisplayWin32ErrorDbg(DWORD dwErrorCode, const char *file, int line) +#else +VOID DisplayWin32Error(DWORD dwErrorCode) +#endif { LPVOID lpMsgBuf; +#if DBG + TCHAR szMsg[255]; +#endif FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - GetLastError(), + dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); - MessageBox(NULL, lpMsgBuf, _T("Error!"), MB_OK | MB_ICONERROR); +#if DBG + if (_stprintf(szMsg, _T("%hs:%d: %s"), file, line, lpMsgBuf)) + { + MessageBox(NULL, szMsg, NULL, MB_OK | MB_ICONERROR); + } +#else + MessageBox(NULL, lpMsgBuf, NULL, MB_OK | MB_ICONERROR); +#endif LocalFree(lpMsgBuf); } diff --git a/reactos/dll/cpl/timedate/timedate.h b/reactos/dll/cpl/timedate/timedate.h index 86605942368..47fb347ba78 100644 --- a/reactos/dll/cpl/timedate/timedate.h +++ b/reactos/dll/cpl/timedate/timedate.h @@ -42,7 +42,12 @@ INT_PTR CALLBACK InetTimePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM /* timedate.c */ -VOID GetError(VOID); +#if DBG +VOID DisplayWin32ErrorDbg(DWORD dwErrorCode, const char *file, int line); +#define DisplayWin32Error(e) DisplayWin32ErrorDbg(e, __FILE__, __LINE__); +#else +VOID DisplayWin32Error(DWORD dwErrorCode); +#endif /* clock.c */ @@ -51,7 +56,7 @@ VOID UnregisterClockControl(VOID); /* ntpclient.c */ -BOOL InitialiseConnection(CHAR *szIpAddr); +BOOL InitializeConnection(CHAR *szIpAddr); VOID DestroyConnection(VOID); BOOL SendData(VOID); ULONG RecieveData(VOID); From b207566c12a07d41e97bf8cfe496e08f46957166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 3 Oct 2006 17:57:29 +0000 Subject: [PATCH 443/488] Add back registry entries from i8042prt/kbdclass/mouclass svn path=/trunk/; revision=24376 --- reactos/boot/bootdata/hivesys.inf | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/reactos/boot/bootdata/hivesys.inf b/reactos/boot/bootdata/hivesys.inf index 1cd1d5bcc02..b39f8c057ae 100644 --- a/reactos/boot/bootdata/hivesys.inf +++ b/reactos/boot/bootdata/hivesys.inf @@ -564,6 +564,13 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","ImagePath",0x00020000,"system32 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Type",0x00010001,0x00000008 +; i8042 port driver +HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","Group",0x00000000,"Keyboard Port" +HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","Type",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt\Parameters","BreakOnSysRq",0x00010001,0x00000001 + ; Kernel-Mode Tests ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ErrorControl",0x00010001,0x00000000 ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Group",0x00000000,"Base" @@ -571,8 +578,14 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Type",0x00010001,0x00000008 ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Start",0x00010001,0x00000001 ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Type",0x00010001,0x00000001 -; Keyboard parameters +; Keyboard class driver +HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","Group",0x00000000,"Keyboard Class" +HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","ImagePath",0x00020000,"system32\drivers\kbdclass.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","Type",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass\Parameters","ConnectMultiplePorts",0x00010001,1 +HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E96B-E325-11CE-BFC1-08002BE10318}","UpperFilters",0x00010000,"kbdclass" ; SB16 driver HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Group",0x00000000,"Base" @@ -597,6 +610,14 @@ HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ImagePath",0x00020000,"system32\drivers\mpu401.sys" +; Mouse class driver +HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Group",0x00000000,"Pointer Class" +HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","ImagePath",0x00020000,"system32\drivers\mouclass.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Type",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E96F-E325-11CE-BFC1-08002BE10318}","UpperFilters",0x00010000,"mouclass" + ; Mailslot filesystem driver HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","Group",0x00000000,"File System" From 90b4dc09c75c88da2509963d2d1fab62f7bcef38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 3 Oct 2006 18:03:28 +0000 Subject: [PATCH 444/488] Of course, I've added one level in directory structure in 24377. Delete the whole i8042prt driver and retry (Sorry, this revision won't build) svn path=/trunk/; revision=24378 --- reactos/drivers/input/i8042prt/README.txt | 80 -- reactos/drivers/input/i8042prt/createclose.c | 55 - reactos/drivers/input/i8042prt/i8042prt.c | 524 -------- reactos/drivers/input/i8042prt/i8042prt.h | 488 -------- .../drivers/input/i8042prt/i8042prt.rbuild | 18 - reactos/drivers/input/i8042prt/i8042prt.rc | 5 - .../input/i8042prt/i8042prt/README.txt | 83 -- .../input/i8042prt/i8042prt/i8042prt.c | 927 -------------- .../input/i8042prt/i8042prt/i8042prt.h | 378 ------ .../input/i8042prt/i8042prt/i8042prt.rbuild | 14 - .../input/i8042prt/i8042prt/i8042prt.rc | 5 - .../input/i8042prt/i8042prt/keyboard.c | 776 ------------ .../drivers/input/i8042prt/i8042prt/mouse.c | 948 --------------- .../drivers/input/i8042prt/i8042prt/ps2pp.c | 137 --- .../input/i8042prt/i8042prt/registry.c | 211 ---- reactos/drivers/input/i8042prt/keyboard.c | 875 -------------- reactos/drivers/input/i8042prt/misc.c | 68 -- reactos/drivers/input/i8042prt/mouse.c | 1070 ----------------- reactos/drivers/input/i8042prt/pnp.c | 663 ---------- reactos/drivers/input/i8042prt/ps2pp.c | 141 --- reactos/drivers/input/i8042prt/readwrite.c | 218 ---- reactos/drivers/input/i8042prt/registry.c | 251 ---- reactos/drivers/input/i8042prt/setup.c | 273 ----- 23 files changed, 8208 deletions(-) delete mode 100644 reactos/drivers/input/i8042prt/README.txt delete mode 100644 reactos/drivers/input/i8042prt/createclose.c delete mode 100644 reactos/drivers/input/i8042prt/i8042prt.c delete mode 100644 reactos/drivers/input/i8042prt/i8042prt.h delete mode 100644 reactos/drivers/input/i8042prt/i8042prt.rbuild delete mode 100644 reactos/drivers/input/i8042prt/i8042prt.rc delete mode 100644 reactos/drivers/input/i8042prt/i8042prt/README.txt delete mode 100644 reactos/drivers/input/i8042prt/i8042prt/i8042prt.c delete mode 100644 reactos/drivers/input/i8042prt/i8042prt/i8042prt.h delete mode 100644 reactos/drivers/input/i8042prt/i8042prt/i8042prt.rbuild delete mode 100644 reactos/drivers/input/i8042prt/i8042prt/i8042prt.rc delete mode 100644 reactos/drivers/input/i8042prt/i8042prt/keyboard.c delete mode 100644 reactos/drivers/input/i8042prt/i8042prt/mouse.c delete mode 100644 reactos/drivers/input/i8042prt/i8042prt/ps2pp.c delete mode 100644 reactos/drivers/input/i8042prt/i8042prt/registry.c delete mode 100644 reactos/drivers/input/i8042prt/keyboard.c delete mode 100644 reactos/drivers/input/i8042prt/misc.c delete mode 100644 reactos/drivers/input/i8042prt/mouse.c delete mode 100644 reactos/drivers/input/i8042prt/pnp.c delete mode 100644 reactos/drivers/input/i8042prt/ps2pp.c delete mode 100644 reactos/drivers/input/i8042prt/readwrite.c delete mode 100644 reactos/drivers/input/i8042prt/registry.c delete mode 100644 reactos/drivers/input/i8042prt/setup.c diff --git a/reactos/drivers/input/i8042prt/README.txt b/reactos/drivers/input/i8042prt/README.txt deleted file mode 100644 index 16bb6c791fb..00000000000 --- a/reactos/drivers/input/i8042prt/README.txt +++ /dev/null @@ -1,80 +0,0 @@ -Intel 8042 port driver - -This directory contains a driver for Intels 8042 and compatible controllers. -It is based on the information in the DDK documentation on MSDN. It is intended -to be compatible with keyboard and mouse drivers written for Windows. It is -not based on the i8042prt example driver that's included with the DDK. - -The directory contains these files: - -createclose.c: open/close devices functionnality - -i8042prt.c: Main controller functionality, things shared by keyboards and mice - -keyboard.c: keyboard functionality: detection, interrupt handling - -misc.c: misc things, mostly related to Irp passing - -mouse.c: mouse functionality: detection, interrupt handling, packet parsing for - standard ps2 and microsoft mice - -pnp.c: Plug&Play functionnality - -ps2pp.c: logitech ps2++ mouse packat parsing (basic) - -readwrite.c: read/write to the i8042 controller - -registry.c: registry reading - -setup.c: add keyboard support during the 1st stage setup - -i8042prt.rc: obvious - - -Some parts of the driver make little sense. This is because it implements -an interface that has evolved over a long time, and because the ps/2 -'standard' is really awful. - -Things to add: - -- Better AT (before ps2) keyboard handling -- SiS keyboard controller detection -- Mouse identification -- General robustness: reset mouse if things go wrong -- Handling all registry settings -- ACPI - -Things not to add: - -- Other mouse protocols, touchpad handling etc. : Write a filter driver instead -- Keyboard lights handling: Should be in win32k -- Keyboard scancode translation: Should be in win32k - -Things requiring work elsewhere: - -- Debugger interface (TAB + key): - Currently this interface wants translated keycodes, which are not - implemented by this driver. As it just uses a giant switch with - hardcoded cases, this should not be hard to fix. - -- Class drivers: - The class drivers should be able to handle reads for more than one packet - at a time (kbdclass should, mouclass does not). Win32k should send such - requests. - - -I put a lot of work in making it work like Microsofts driver does, so third party drivers can work. Please keep it that way. - - -Links: - -Here's a link describing most of the registry settings: - -http://www.microsoft.com/resources/documentation/Windows/2000/server/reskit/en-us/Default.asp?url=/resources/documentation/Windows/2000/server/reskit/en-us/regentry/31493.asp - -PS/2 protocol documentation: - -http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html - -It also contains a link to a description of the ps2++ protocol, which has -since disappeared. Archive.org still has it. diff --git a/reactos/drivers/input/i8042prt/createclose.c b/reactos/drivers/input/i8042prt/createclose.c deleted file mode 100644 index e895dbee3cc..00000000000 --- a/reactos/drivers/input/i8042prt/createclose.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/createclose.c - * PURPOSE: IRP_MJ_CREATE, IRP_MJ_CLEANUP and IRP_MJ_CLOSE operations - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS NTAPI -i8042Create( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - DPRINT("IRP_MJ_CREATE\n"); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} - -NTSTATUS NTAPI -i8042Cleanup( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - DPRINT("IRP_MJ_CLEANUP\n"); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} - -NTSTATUS NTAPI -i8042Close( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - DPRINT("IRP_MJ_CLOSE\n"); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/input/i8042prt/i8042prt.c b/reactos/drivers/input/i8042prt/i8042prt.c deleted file mode 100644 index ebffde03621..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/i8042prt.c - * PURPOSE: Driver entry function - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#define INITGUID -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS NTAPI -i8042AddDevice( - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT Pdo) -{ - PI8042_DRIVER_EXTENSION DriverExtension; - PFDO_DEVICE_EXTENSION DeviceExtension = NULL; - PDEVICE_OBJECT Fdo = NULL; - ULONG DeviceExtensionSize; - NTSTATUS Status; - - DPRINT("i8042AddDevice(%p %p)\n", DriverObject, Pdo); - - DriverExtension = (PI8042_DRIVER_EXTENSION)IoGetDriverObjectExtension(DriverObject, DriverObject); - - if (Pdo == NULL) - { - /* We're getting a NULL Pdo at the first call as - * we are a legacy driver. Ignore it */ - return STATUS_SUCCESS; - } - - /* Create new device object. As we don't know if the device would be a keyboard - * or a mouse, we have to allocate the biggest device extension. */ - DeviceExtensionSize = MAX(sizeof(I8042_KEYBOARD_EXTENSION), sizeof(I8042_MOUSE_EXTENSION)); - Status = IoCreateDevice( - DriverObject, - DeviceExtensionSize, - NULL, - Pdo->DeviceType, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension; - RtlZeroMemory(DeviceExtension, DeviceExtensionSize); - DeviceExtension->Type = Unknown; - DeviceExtension->Fdo = Fdo; - DeviceExtension->Pdo = Pdo; - DeviceExtension->PortDeviceExtension = &DriverExtension->Port; - Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice); - - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - return STATUS_SUCCESS; - -cleanup: - if (DeviceExtension && DeviceExtension->LowerDevice) - IoDetachDevice(DeviceExtension->LowerDevice); - if (Fdo) - IoDeleteDevice(Fdo); - return Status; -} - -VOID NTAPI -i8042SendHookWorkItem( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - PI8042_HOOK_WORKITEM WorkItemData; - PFDO_DEVICE_EXTENSION FdoDeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - PDEVICE_OBJECT TopOfStack = NULL; - ULONG IoControlCode; - PVOID InputBuffer; - ULONG InputBufferLength; - IO_STATUS_BLOCK IoStatus; - KEVENT Event; - PIRP NewIrp; - NTSTATUS Status; - - DPRINT("i8042SendHookWorkItem(%p %p)\n", DeviceObject, Context); - - WorkItemData = (PI8042_HOOK_WORKITEM)Context; - FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - PortDeviceExtension = FdoDeviceExtension->PortDeviceExtension; - - switch (FdoDeviceExtension->Type) - { - case Keyboard: - { - PI8042_KEYBOARD_EXTENSION DeviceExtension; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension; - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD; - InputBuffer = &DeviceExtension->KeyboardHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD); - break; - } - case Mouse: - { - PI8042_MOUSE_EXTENSION DeviceExtension; - DeviceExtension = (PI8042_MOUSE_EXTENSION)FdoDeviceExtension; - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE; - InputBuffer = &DeviceExtension->MouseHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE); - break; - } - default: - { - DPRINT1("Unknown FDO type %u\n", FdoDeviceExtension->Type); - ASSERT(FALSE); - WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; - goto cleanup; - } - } - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - TopOfStack = IoGetAttachedDeviceReference(DeviceObject); - - NewIrp = IoBuildDeviceIoControlRequest( - IoControlCode, - TopOfStack, - InputBuffer, - InputBufferLength, - NULL, - 0, - TRUE, - &Event, - &IoStatus); - - if (!NewIrp) - { - DPRINT("IoBuildDeviceIoControlRequest() failed\n"); - WorkItemData->Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - - Status = IoCallDriver(TopOfStack, NewIrp); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject( - &Event, - Executive, - KernelMode, - FALSE, - NULL); - Status = IoStatus.Status; - } - if (!NT_SUCCESS(Status)) - { - DPRINT("IoCallDriver() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - if (FdoDeviceExtension->Type == Keyboard) - { - PI8042_KEYBOARD_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension; - /* Call the hooked initialization if it exists */ - if (DeviceExtension->KeyboardHook.InitializationRoutine) - { - Status = DeviceExtension->KeyboardHook.InitializationRoutine( - DeviceExtension->KeyboardHook.Context, - PortDeviceExtension, - i8042SynchReadPort, - i8042SynchWritePortKbd, - FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT("KeyboardHook.InitializationRoutine() failed with status 0x%08lx\n", Status); - WorkItemData->Irp->IoStatus.Status = Status; - goto cleanup; - } - } - } -#if 0 - else - { - /* Mouse doesn't have this, but we need to send a - * reset to start the detection. - */ - KIRQL Irql; - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - - i8042Write(PortDeviceExtension, PortDeviceExtension->ControlPort, CTRL_WRITE_MOUSE); - i8042Write(PortDeviceExtension, PortDeviceExtension->DataPort, MOU_CMD_RESET); - - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); - } -#endif - - WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS; - -cleanup: - if (TopOfStack != NULL) - ObDereferenceObject(TopOfStack); - WorkItemData->Irp->IoStatus.Information = 0; - IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT); - - IoFreeWorkItem(WorkItemData->WorkItem); - ExFreePool(WorkItemData); -} - -static VOID NTAPI -i8042StartIo( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - switch (DeviceExtension->Type) - { - case Keyboard: - i8042KbdStartIo(DeviceObject, Irp); - break; - default: - DPRINT1("Unknown FDO type %u\n", DeviceExtension->Type); - ASSERT(FALSE); - break; - } -} - -/* Write the current byte of the packet. Returns FALSE in case - * of problems. - */ -static BOOLEAN -i8042PacketWrite( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - UCHAR Port = DeviceExtension->PacketPort; - - if (Port) - { - if (!i8042Write(DeviceExtension, - DeviceExtension->ControlPort, - Port)) - { - /* something is really wrong! */ - DPRINT1("Failed to send packet byte!\n"); - return FALSE; - } - } - - return i8042Write(DeviceExtension, - DeviceExtension->DataPort, - DeviceExtension->Packet.Bytes[DeviceExtension->Packet.CurrentByte]); -} - -BOOLEAN -i8042PacketIsr( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Output) -{ - if (DeviceExtension->Packet.State == Idle) - return FALSE; - - switch (Output) - { - case KBD_RESEND: - DeviceExtension->PacketResends++; - if (DeviceExtension->PacketResends > DeviceExtension->Settings.ResendIterations) - { - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketComplete = TRUE; - DeviceExtension->PacketResult = STATUS_IO_TIMEOUT; - DeviceExtension->PacketResends = 0; - return TRUE; - } - DeviceExtension->Packet.CurrentByte--; - break; - - case KBD_NACK: - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketComplete = TRUE; - DeviceExtension->PacketResult = STATUS_UNEXPECTED_IO_ERROR; - DeviceExtension->PacketResends = 0; - return TRUE; - - default: - DeviceExtension->PacketResends = 0; - } - - if (DeviceExtension->Packet.CurrentByte >= DeviceExtension->Packet.ByteCount) - { - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketComplete = TRUE; - DeviceExtension->PacketResult = STATUS_SUCCESS; - return TRUE; - } - - if (!i8042PacketWrite(DeviceExtension)) - { - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketComplete = TRUE; - DeviceExtension->PacketResult = STATUS_IO_TIMEOUT; - return TRUE; - } - DeviceExtension->Packet.CurrentByte++; - - return TRUE; -} - -/* - * This function starts a packet. It must be called with the - * correct DIRQL. - */ -NTSTATUS -i8042StartPacket( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, - IN PUCHAR Bytes, - IN ULONG ByteCount, - IN PIRP Irp) -{ - KIRQL Irql; - NTSTATUS Status; - - Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); - - if (DeviceExtension->Packet.State != Idle) - { - Status = STATUS_DEVICE_BUSY; - goto done; - } - - switch (FdoDeviceExtension->Type) - { - case Keyboard: DeviceExtension->PacketPort = 0; break; - case Mouse: DeviceExtension->PacketPort = CTRL_WRITE_MOUSE; break; - default: - DPRINT1("Unknown FDO type %u\n", FdoDeviceExtension->Type); - ASSERT(FALSE); - Status = STATUS_INTERNAL_ERROR; - goto done; - } - - DeviceExtension->Packet.Bytes = Bytes; - DeviceExtension->Packet.CurrentByte = 0; - DeviceExtension->Packet.ByteCount = ByteCount; - DeviceExtension->Packet.State = SendingBytes; - DeviceExtension->PacketResult = Status = STATUS_PENDING; - DeviceExtension->CurrentIrp = Irp; - DeviceExtension->CurrentIrpDevice = FdoDeviceExtension->Fdo; - - if (!i8042PacketWrite(DeviceExtension)) - { - Status = STATUS_IO_TIMEOUT; - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketResult = STATUS_ABANDONED; - goto done; - } - - DeviceExtension->Packet.CurrentByte++; - -done: - KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); - - if (Status != STATUS_PENDING) - { - DeviceExtension->CurrentIrp = NULL; - DeviceExtension->CurrentIrpDevice = NULL; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - return Status; -} - -static NTSTATUS NTAPI -IrpStub( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - KEBUGCHECK(0); - return STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS NTAPI -i8042DeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - NTSTATUS Status; - - DPRINT("i8042DeviceControl(%p %p)\n", DeviceObject, Irp); - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - switch (DeviceExtension->Type) - { - case Keyboard: - return i8042KbdDeviceControl(DeviceObject, Irp); - break; - default: - return IrpStub(DeviceObject, Irp); - } - - return Status; -} - -static NTSTATUS NTAPI -i8042InternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - ULONG ControlCode; - NTSTATUS Status; - - DPRINT("i8042InternalDeviceControl(%p %p)\n", DeviceObject, Irp); - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - switch (DeviceExtension->Type) - { - case Unknown: - { - ControlCode = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode; - switch (ControlCode) - { - case IOCTL_INTERNAL_KEYBOARD_CONNECT: - Status = i8042KbdInternalDeviceControl(DeviceObject, Irp); - break; - case IOCTL_INTERNAL_MOUSE_CONNECT: - Status = i8042MouInternalDeviceControl(DeviceObject, Irp); - break; - default: - DPRINT1("Unknown IO control code 0x%lx\n", ControlCode); - ASSERT(FALSE); - Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - break; - } - case Keyboard: - Status = i8042KbdInternalDeviceControl(DeviceObject, Irp); - break; - case Mouse: - Status = i8042MouInternalDeviceControl(DeviceObject, Irp); - break; - default: - DPRINT1("Unknown FDO type %u\n", DeviceExtension->Type); - ASSERT(FALSE); - Status = STATUS_INTERNAL_ERROR; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - break; - } - - return Status; -} - -NTSTATUS NTAPI -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath) -{ - PI8042_DRIVER_EXTENSION DriverExtension; - ULONG i; - NTSTATUS Status; - - Status = IoAllocateDriverObjectExtension( - DriverObject, - DriverObject, - sizeof(I8042_DRIVER_EXTENSION), - (PVOID*)&DriverExtension); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status); - return Status; - } - RtlZeroMemory(DriverExtension, sizeof(I8042_DRIVER_EXTENSION)); - KeInitializeSpinLock(&DriverExtension->Port.SpinLock); - - Status = RtlDuplicateUnicodeString( - RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, - RegistryPath, - &DriverExtension->RegistryPath); - if (!NT_SUCCESS(Status)) - { - DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); - return Status; - } - - Status = ReadRegistryEntries(RegistryPath, &DriverExtension->Port.Settings); - if (!NT_SUCCESS(Status)) - { - DPRINT("ReadRegistryEntries() failed with status 0x%08lx\n", Status); - return Status; - } - - DriverObject->DriverExtension->AddDevice = i8042AddDevice; - DriverObject->DriverStartIo = i8042StartIo; - - for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) - DriverObject->MajorFunction[i] = IrpStub; - - DriverObject->MajorFunction[IRP_MJ_CREATE] = i8042Create; - DriverObject->MajorFunction[IRP_MJ_CLEANUP] = i8042Cleanup; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl; - DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl; - DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp; - - if (IsFirstStageSetup()) - return i8042AddLegacyKeyboard(DriverObject, RegistryPath); - - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/input/i8042prt/i8042prt.h b/reactos/drivers/input/i8042prt/i8042prt.h deleted file mode 100644 index 9df68e61f2b..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt.h +++ /dev/null @@ -1,488 +0,0 @@ -#ifndef _I8042PRT_H_ -#define _I8042PRT_H_ - -#include -#include -#include -#include -#include -#include - -/*----------------------------------------------------- - * Structures - * --------------------------------------------------*/ - -typedef enum -{ - dsStopped, - dsStarted, - dsPaused, - dsRemoved, - dsSurpriseRemoved -} DEVICE_STATE; - -typedef struct _I8042_SETTINGS -{ - /* Registry settings */ - ULONG KeyboardDataQueueSize; /* done */ - UNICODE_STRING KeyboardDeviceBaseName; - ULONG MouseDataQueueSize; /* done */ - ULONG MouseResolution; - ULONG MouseSynchIn100ns; - ULONG NumberOfButtons; - UNICODE_STRING PointerDeviceBaseName; - ULONG PollStatusIterations; /* done */ - ULONG OverrideKeyboardType; - ULONG OverrideKeyboardSubtype; - ULONG PollingIterations; /* done */ - ULONG PollingIterationsMaximum; - ULONG ResendIterations; /* done */ - ULONG SampleRate; - ULONG CrashOnCtrlScroll; /* done */ -} I8042_SETTINGS, *PI8042_SETTINGS; - -typedef enum _MOUSE_TIMEOUT_STATE -{ - NoChange, - TimeoutStart, - TimeoutCancel -} MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE; - -typedef struct _INTERRUPT_DATA -{ - PKINTERRUPT Object; - ULONG Vector; - KIRQL Dirql; - KINTERRUPT_MODE InterruptMode; - BOOLEAN ShareInterrupt; - KAFFINITY Affinity; -} INTERRUPT_DATA, *PINTERRUPT_DATA; - -#define WHEEL_DELTA 120 - -struct _I8042_KEYBOARD_EXTENSION; -typedef struct _I8042_KEYBOARD_EXTENSION *PI8042_KEYBOARD_EXTENSION; -struct _I8042_MOUSE_EXTENSION; -typedef struct _I8042_MOUSE_EXTENSION *PI8042_MOUSE_EXTENSION; - -/* PORT_DEVICE_EXTENSION.Flags */ -#define KEYBOARD_PRESENT 0x01 /* A keyboard is attached */ -#define MOUSE_PRESENT 0x02 /* A mouse is attached */ -#define KEYBOARD_CONNECTED 0x04 /* Keyboard received IOCTL_INTERNAL_KEYBOARD_CONNECT */ -#define MOUSE_CONNECTED 0x08 /* Mouse received IOCTL_INTERNAL_MOUSE_CONNECT */ -#define KEYBOARD_STARTED 0x04 /* Keyboard FDO received IRP_MN_START_DEVICE */ -#define MOUSE_STARTED 0x08 /* Mouse FDO received IRP_MN_START_DEVICE */ -#define KEYBOARD_INITIALIZED 0x10 /* Keyboard interrupt is connected */ -#define MOUSE_INITIALIZED 0x20 /* Mouse interrupt is connected */ - -typedef struct _PORT_DEVICE_EXTENSION -{ - PUCHAR DataPort; /* Usually 0x60 */ - PUCHAR ControlPort; /* Usually 0x64 */ - I8042_SETTINGS Settings; - ULONG Flags; - - PI8042_KEYBOARD_EXTENSION KeyboardExtension; - INTERRUPT_DATA KeyboardInterrupt; - PI8042_MOUSE_EXTENSION MouseExtension; - INTERRUPT_DATA MouseInterrupt; - PKINTERRUPT HighestDIRQLInterrupt; - KSPIN_LOCK SpinLock; - KIRQL HighestDirql; - - OUTPUT_PACKET Packet; - ULONG PacketResends; - BOOLEAN PacketComplete; - NTSTATUS PacketResult; - UCHAR PacketBuffer[16]; - UCHAR PacketPort; - - PIRP CurrentIrp; - PDEVICE_OBJECT CurrentIrpDevice; -} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION; - -typedef struct _I8042_DRIVER_EXTENSION -{ - UNICODE_STRING RegistryPath; - - PORT_DEVICE_EXTENSION Port; -} I8042_DRIVER_EXTENSION, *PI8042_DRIVER_EXTENSION; - -typedef enum _I8042_DEVICE_TYPE -{ - Unknown, - Keyboard, - Mouse, - PhysicalDeviceObject -} I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE; - -typedef struct _FDO_DEVICE_EXTENSION -{ - I8042_DEVICE_TYPE Type; - // Associated device object (FDO) - PDEVICE_OBJECT Fdo; - // Associated device object (PDO) - PDEVICE_OBJECT Pdo; - // Lower device object - PDEVICE_OBJECT LowerDevice; - // Current state of the driver - DEVICE_STATE PnpState; - - PPORT_DEVICE_EXTENSION PortDeviceExtension; -} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; - -typedef struct _I8042_KEYBOARD_EXTENSION -{ - FDO_DEVICE_EXTENSION Common; - CONNECT_DATA KeyboardData; - INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; - KDPC DpcKeyboard; - - KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; - - KEYBOARD_SCAN_STATE KeyboardScanState; - BOOLEAN KeyComplete; - PKEYBOARD_INPUT_DATA KeyboardBuffer; - ULONG KeysInBuffer; - - /* Power keys items */ - ULONG ReportedCaps; - ULONG NewCaps; - ULONG LastPowerKey; - UNICODE_STRING PowerInterfaceName; - PIO_WORKITEM PowerWorkItem; - PIRP PowerIrp; - - /* Debug items */ - ULONG ComboPosition; - PIO_WORKITEM DebugWorkItem; -#ifdef __REACTOS__ - ULONG DebugKey; - BOOLEAN TabPressed; -#endif -} I8042_KEYBOARD_EXTENSION; - -typedef enum _I8042_MOUSE_TYPE -{ - GenericPS2, - Intellimouse, - IntellimouseExplorer, - Ps2pp -} I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE; - -typedef struct _I8042_MOUSE_EXTENSION -{ - FDO_DEVICE_EXTENSION Common; - CONNECT_DATA MouseData; - INTERNAL_I8042_HOOK_MOUSE MouseHook; - KDPC DpcMouse; - - MOUSE_ATTRIBUTES MouseAttributes; - - MOUSE_STATE MouseState; - BOOLEAN MouseComplete; - MOUSE_RESET_SUBSTATE MouseResetState; - PMOUSE_INPUT_DATA MouseBuffer; - ULONG MouseInBuffer; - USHORT MouseButtonState; - ULARGE_INTEGER MousePacketStartTime; - - KTIMER TimerMouseTimeout; - KDPC DpcMouseTimeout; - MOUSE_TIMEOUT_STATE MouseTimeoutState; - BOOLEAN MouseTimeoutActive; - - UCHAR MouseLogiBuffer[3]; - I8042_MOUSE_TYPE MouseType; -} I8042_MOUSE_EXTENSION; - -typedef struct _I8042_HOOK_WORKITEM -{ - PIO_WORKITEM WorkItem; - PIRP Irp; -} I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM; - -/*----------------------------------------------------- - * Some defines - * --------------------------------------------------*/ - -#define MAX(a, b) ((a) >= (b) ? (a) : (b)) - -#define KEYBOARD_POWER_CODE 0x5E -#define KEYBOARD_SLEEP_CODE 0x5F -#define KEYBOARD_WAKE_CODE 0x63 - -/*----------------------------------------------------- - * Controller commands - * --------------------------------------------------*/ - -#define KBD_READ_MODE 0x20 -#define KBD_WRITE_MODE 0x60 -#define KBD_LINE_TEST 0xAB -#define MOUSE_LINE_TEST 0xA9 -#define CTRL_SELF_TEST 0xAA -#define CTRL_WRITE_MOUSE 0xD4 - -/*----------------------------------------------------- - * Keyboard commands - * --------------------------------------------------*/ - -#define KBD_CMD_SET_LEDS 0xED -#define KBD_CMD_GET_ID 0xF2 - -/*----------------------------------------------------- - * Keyboard responses - * --------------------------------------------------*/ - -#define KBD_ACK 0xFA -#define KBD_NACK 0xFC -#define KBD_RESEND 0xFE - -/*----------------------------------------------------- - * Controller status register bits - * --------------------------------------------------*/ - -#define KBD_OBF 0x01 -#define KBD_IBF 0x02 -#define MOU_OBF 0x20 -#define KBD_PERR 0x80 - -/*----------------------------------------------------- - * Controller command byte bits - * --------------------------------------------------*/ - -#define CCB_KBD_INT_ENAB 0x01 -#define CCB_MOUSE_INT_ENAB 0x02 -#define CCB_SYSTEM_FLAG 0x04 -#define CCB_KBD_DISAB 0x10 -#define CCB_MOUSE_DISAB 0x20 -#define CCB_TRANSLATE 0x40 - -/*----------------------------------------------------- - * LED bits - * --------------------------------------------------*/ - -#define KBD_LED_SCROLL 0x01 -#define KBD_LED_NUM 0x02 -#define KBD_LED_CAPS 0x04 - -/*----------------------------------------------------- - * Mouse commands - * --------------------------------------------------*/ - -#define MOU_CMD_GET_ID 0xF2 -#define MOU_CMD_RESET 0xFF - -/*----------------------------------------------------- - * Mouse responses - * --------------------------------------------------*/ - -#define MOUSE_ACK 0xFA -#define MOUSE_ERROR 0xFC -#define MOUSE_NACK 0xFE - -/*----------------------------------------------------- - * Prototypes - * --------------------------------------------------*/ - -/* createclose.c */ - -VOID NTAPI -i8042SendHookWorkItem( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context); - -NTSTATUS NTAPI -i8042Create( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS NTAPI -i8042Cleanup( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS NTAPI -i8042Close( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -/* keyboard.c */ - -NTSTATUS NTAPI -i8042SynchWritePortKbd( - IN PVOID Context, - IN UCHAR Value, - IN BOOLEAN WaitForAck); - -BOOLEAN -i8042KbdStartIo( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS -i8042KbdDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS -i8042KbdInternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -BOOLEAN NTAPI -i8042KbdInterruptService( - IN PKINTERRUPT Interrupt, - PVOID Context); - -/* i8042prt.c */ - -NTSTATUS NTAPI -i8042AddDevice( - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT Pdo); - -BOOLEAN -i8042PacketIsr( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Output); - -NTSTATUS -i8042StartPacket( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, - IN PUCHAR Bytes, - IN ULONG ByteCount, - IN PIRP Irp); - -/* misc.c */ - -NTSTATUS NTAPI -ForwardIrpAndForget( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS -ForwardIrpAndWait( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -/* mouse.c */ - -VOID -i8042MouHandle( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Output); - -VOID -i8042MouHandleButtons( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN USHORT Mask); - -NTSTATUS -i8042MouInitialize( - IN PI8042_MOUSE_EXTENSION DeviceExtension); - -NTSTATUS -i8042MouInternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -BOOLEAN NTAPI -i8042MouInterruptService( - IN PKINTERRUPT Interrupt, - PVOID Context); - -VOID NTAPI -i8042MouQueuePacket( - IN PVOID Context); - -/* pnp.c */ - -BOOLEAN -i8042ChangeMode( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR FlagsToDisable, - IN UCHAR FlagsToEnable); - -NTSTATUS NTAPI -i8042Pnp( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -/* ps2pp.c */ -VOID -i8042MouHandlePs2pp( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Input); - -/* readwrite.c */ - -VOID -i8042Flush( - IN PPORT_DEVICE_EXTENSION DeviceExtension); - -VOID -i8042IsrWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Value, - IN UCHAR SelectCmd OPTIONAL); - -NTSTATUS -i8042ReadData( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR StatusFlags, - OUT PUCHAR Data); -#define i8042ReadKeyboardData(DeviceExtension, Data) \ - i8042ReadData(DeviceExtension, KBD_OBF, Data) -#define i8042ReadMouseData(DeviceExtension, Data) \ - i8042ReadData(DeviceExtension, MOU_OBF, Data) - -NTSTATUS -i8042ReadDataWait( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Data); - -NTSTATUS -i8042ReadStatus( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Status); - -NTSTATUS NTAPI -i8042SynchReadPort( - IN PVOID Context, - IN PUCHAR Value, - IN BOOLEAN WaitForAck); - -NTSTATUS NTAPI -i8042SynchWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Port, - IN UCHAR Value, - IN BOOLEAN WaitForAck); - -BOOLEAN -i8042Write( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PUCHAR addr, - IN UCHAR data); - -/* registry.c */ - -NTSTATUS -ReadRegistryEntries( - IN PUNICODE_STRING RegistryPath, - OUT PI8042_SETTINGS Settings); - -/* setup.c */ - -BOOLEAN -IsFirstStageSetup( - VOID); - -NTSTATUS -i8042AddLegacyKeyboard( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath); - -#endif // _I8042PRT_H_ diff --git a/reactos/drivers/input/i8042prt/i8042prt.rbuild b/reactos/drivers/input/i8042prt/i8042prt.rbuild deleted file mode 100644 index 1c4a264012b..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt.rbuild +++ /dev/null @@ -1,18 +0,0 @@ - - - - - ntoskrnl - hal - createclose.c - i8042prt.c - keyboard.c - misc.c - mouse.c - pnp.c - ps2pp.c - readwrite.c - registry.c - setup.c - i8042prt.rc - diff --git a/reactos/drivers/input/i8042prt/i8042prt.rc b/reactos/drivers/input/i8042prt/i8042prt.rc deleted file mode 100644 index eaed77a9427..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt.rc +++ /dev/null @@ -1,5 +0,0 @@ -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "i8042 Port Device Driver\0" -#define REACTOS_STR_INTERNAL_NAME "i8042prt\0" -#define REACTOS_STR_ORIGINAL_FILENAME "i8042prt.sys\0" -#include diff --git a/reactos/drivers/input/i8042prt/i8042prt/README.txt b/reactos/drivers/input/i8042prt/i8042prt/README.txt deleted file mode 100644 index a8f09ff5f59..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/README.txt +++ /dev/null @@ -1,83 +0,0 @@ -Intel 8042 port driver - -This directory contains a driver for Intels 8042 and compatible controllers. -It is based on the information in the DDK documentation on MSDN. It is intended -to be compatible with keyboard and mouse drivers written for Windows. It is -not based on the i8042prt example driver that's included with the DDK. - -The directory contains these files: - -i8042prt.c: Main controller functionality, things shared by keyboards and mice - -keyboard.c: keyboard functionality: detection, interrupt handling - -mouse.c: mouse functionality: detection, interrupt handling, packet parsing for - standard ps2 and microsoft mice - -ps2pp.c: logitech ps2++ mouse packat parsing (basic) - -registry.c: registry reading - -makefile, i8042prt.rc: obvious - - -Some parts of the driver make little sense. This is because it implements -an interface that has evolved over a long time, and because the ps/2 -'standard' is really awful. - -Things to add: - -- Better AT (before ps2) keyboard handling -- SiS keyboard controller detection -- Mouse identification -- General robustness: reset mouse if things go wrong -- Handling all registry settings -- ACPI -- Make it work more like a WDM driver - -Things not to add: - -- Other mouse protocols, touchpad handling etc. : Write a filter driver instead -- Keyboard lights handling: Should be in win32k -- Keyboard scancode translation: Should be in win32k - -Things requiring work elsewhere: - -- Debugger interface (TAB + key): - Currently this interface wants translated keycodes, which are not - implemented by this driver. As it just uses a giant switch with - hardcoded cases, this should not be hard to fix. - -- Class drivers: - I wrote a keyboard class driver, which does keycode translations. It - should not do this, win32k should get untranslated keycodes and do - the translation itself. - - I changed the mouse class driver (mouclass) to work like Microsofts mouclass. - Unfortunately this means that the original psaux driver doesn't work - anymore (the same holds for the other mice drivers, probably). - - The keyboard class driver passes on ioctls from win32k, so it can change - keyboard settings. As far as I could see, the mouse class driver does not - do this yet. - - The class drivers should be able to handle reads for more than one packet - at a time (kbdclass should, mouclass does not). Win32k should send such - requests. - - -I put a lot of work in making it work like Microsofts driver does, so third party drivers can work. Please keep it that way. - - -Links: - -Here's a link describing most of the registry settings: - -http://www.microsoft.com/resources/documentation/Windows/2000/server/reskit/en-us/Default.asp?url=/resources/documentation/Windows/2000/server/reskit/en-us/regentry/31493.asp - -PS/2 protocol documentation: - -http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html - -It also contains a link to a description of the ps2++ protocol, which has -since disappeared. Archive.org still has it. diff --git a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.c b/reactos/drivers/input/i8042prt/i8042prt/i8042prt.c deleted file mode 100644 index 04625caa859..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.c +++ /dev/null @@ -1,927 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/i8042prt.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus - */ - -/* INCLUDES ****************************************************************/ - -#define NDEBUG -#include - -#include "i8042prt.h" - -/* GLOBALS *******************************************************************/ - -/* - * Driver data - */ -#define I8042_TIMEOUT 500000 - -#define I8042_MAX_COMMAND_LENGTH 16 -#define I8042_MAX_UPWARDS_STACK 5 - -UNICODE_STRING I8042RegistryPath; - -/* FUNCTIONS *****************************************************************/ - -/* - * FUNCTION: Write data to a port, waiting first for it to become ready - */ -BOOLEAN I8042Write(PDEVICE_EXTENSION DevExt, PUCHAR addr, UCHAR data) -{ - ULONG ResendIterations = DevExt->Settings.PollingIterations; - - while ((KBD_IBF & READ_PORT_UCHAR(I8042_CTRL_PORT)) && - (ResendIterations--)) - { - KeStallExecutionProcessor(50); - } - - if (ResendIterations) { - WRITE_PORT_UCHAR(addr,data); - DPRINT("Sent %x to %x\n", data, addr); - return TRUE; - } - return FALSE; -} - -#if 0 /* function is not needed */ -/* - * FUNCTION: Write data to a port, without waiting first - */ -static BOOLEAN I8042WriteNoWait(PDEVICE_EXTENSION DevExt, int addr, UCHAR data) -{ - WRITE_PORT_UCHAR((PUCHAR)addr,data); - DPRINT("Sent %x to %x\n", data, addr); - return TRUE; -} -#endif - -/* - * FUNCTION: Read data from port 0x60 - */ -NTSTATUS I8042ReadData(UCHAR *Data) -{ - UCHAR Status; - Status=READ_PORT_UCHAR(I8042_CTRL_PORT); - - // If data is available - if ((Status & KBD_OBF)) { - Data[0]=READ_PORT_UCHAR((PUCHAR)I8042_DATA_PORT); - DPRINT("Read: %x (status: %x)\n", Data[0], Status); - - // If the data is valid (not timeout, not parity error) - if (0 == (Status & KBD_PERR)) - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS I8042ReadStatus(UCHAR *Status) -{ - Status[0]=READ_PORT_UCHAR(I8042_CTRL_PORT); - return STATUS_SUCCESS; -} - -/* - * FUNCTION: Read data from port 0x60 - */ -NTSTATUS I8042ReadDataWait(PDEVICE_EXTENSION DevExt, UCHAR *Data) -{ - ULONG Counter = DevExt->Settings.PollingIterations; - NTSTATUS Status; - - while (Counter--) { - Status = I8042ReadData(Data); - - if (STATUS_SUCCESS == Status) - return Status; - - KeStallExecutionProcessor(50); - } - // Timed out - return STATUS_IO_TIMEOUT; -} - -VOID I8042Flush() -{ - UCHAR Ignore; - - while (STATUS_SUCCESS == I8042ReadData(&Ignore)) { - DPRINT("Data flushed\n"); /* drop */ - } -} - -VOID STDCALL I8042IsrWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Value, - UCHAR SelectCmd) -{ - if (SelectCmd) - if (!I8042Write(DevExt, I8042_CTRL_PORT, SelectCmd)) - return; - - I8042Write(DevExt, I8042_DATA_PORT, Value); -} - -/* - * These functions are callbacks for filter driver custom - * initialization routines. - */ -NTSTATUS STDCALL I8042SynchWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Port, - UCHAR Value, - BOOLEAN WaitForAck) -{ - NTSTATUS Status; - UCHAR Ack; - ULONG ResendIterations = DevExt->Settings.ResendIterations + 1; - - do { - if (Port) - if (!I8042Write(DevExt, I8042_DATA_PORT, Port)) - { - DPRINT1("Failed to write Port\n"); - return STATUS_IO_TIMEOUT; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) - { - DPRINT1("Failed to write Value\n"); - return STATUS_IO_TIMEOUT; - } - - if (WaitForAck) { - Status = I8042ReadDataWait(DevExt, &Ack); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to read Ack\n"); - return Status; - } - if (Ack == KBD_ACK) - return STATUS_SUCCESS; - if (Ack != KBD_RESEND) - { - DPRINT1("Unexpected Ack 0x%x\n", Ack); - return STATUS_UNEXPECTED_IO_ERROR; - } - } else { - return STATUS_SUCCESS; - } - DPRINT("Reiterating\n"); - ResendIterations--; - } while (ResendIterations); - return STATUS_IO_TIMEOUT; -} - -/* - * This one reads a value from the port; You don't have to specify - * which one, it'll always be from the one you talked to, so one function - * is enough this time. Note how MSDN specifies the - * WaitForAck parameter to be ignored. - */ -static NTSTATUS STDCALL I8042SynchReadPort(PVOID Context, - PUCHAR Value, - BOOLEAN WaitForAck) -{ - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)Context; - - return I8042ReadDataWait(DevExt, Value); -} - -/* Write the current byte of the packet. Returns FALSE in case - * of problems. - */ -static BOOLEAN STDCALL I8042PacketWrite(PDEVICE_EXTENSION DevExt) -{ - UCHAR Port = DevExt->PacketPort; - - if (Port) { - if (!I8042Write(DevExt, - I8042_CTRL_PORT, - Port)) { - /* something is really wrong! */ - DPRINT1("Failed to send packet byte!\n"); - return FALSE; - } - } - - return I8042Write(DevExt, - I8042_DATA_PORT, - DevExt->Packet.Bytes[DevExt->Packet.CurrentByte]); -} - - -/* - * This function starts a packet. It must be called with the - * correct DIRQL. - */ -NTSTATUS STDCALL I8042StartPacket(PDEVICE_EXTENSION DevExt, - PDEVICE_OBJECT Device, - PUCHAR Bytes, - ULONG ByteCount, - PIRP Irp) -{ - KIRQL Irql; - NTSTATUS Status; - PFDO_DEVICE_EXTENSION FdoDevExt = Device->DeviceExtension; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->CurrentIrp = Irp; - DevExt->CurrentIrpDevice = Device; - - if (Idle != DevExt->Packet.State) { - Status = STATUS_DEVICE_BUSY; - goto startpacketdone; - } - - DevExt->Packet.Bytes = Bytes; - DevExt->Packet.CurrentByte = 0; - DevExt->Packet.ByteCount = ByteCount; - DevExt->Packet.State = SendingBytes; - DevExt->PacketResult = Status = STATUS_PENDING; - - if (Mouse == FdoDevExt->Type) - DevExt->PacketPort = 0xD4; - else - DevExt->PacketPort = 0; - - if (!I8042PacketWrite(DevExt)) { - Status = STATUS_IO_TIMEOUT; - DevExt->Packet.State = Idle; - DevExt->PacketResult = STATUS_ABANDONED; - goto startpacketdone; - } - - DevExt->Packet.CurrentByte++; - -startpacketdone: - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - - if (STATUS_PENDING != Status) { - DevExt->CurrentIrp = NULL; - DevExt->CurrentIrpDevice = NULL; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - return Status; -} - -BOOLEAN STDCALL I8042PacketIsr(PDEVICE_EXTENSION DevExt, - UCHAR Output) -{ - if (Idle == DevExt->Packet.State) - return FALSE; - - switch (Output) { - case KBD_RESEND: - DevExt->PacketResends++; - if (DevExt->PacketResends > DevExt->Settings.ResendIterations) { - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_IO_TIMEOUT; - DevExt->PacketResends = 0; - return TRUE; - } - DevExt->Packet.CurrentByte--; - break; - - case KBD_NACK: - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_UNEXPECTED_IO_ERROR; - DevExt->PacketResends = 0; - return TRUE; - - default: - DevExt->PacketResends = 0; - } - - if (DevExt->Packet.CurrentByte >= DevExt->Packet.ByteCount) { - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_SUCCESS; - return TRUE; - } - - if (!I8042PacketWrite(DevExt)) { - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_IO_TIMEOUT; - return TRUE; - } - DevExt->Packet.CurrentByte++; - - return TRUE; -} - -VOID I8042PacketDpc(PDEVICE_EXTENSION DevExt) -{ - BOOLEAN FinishIrp = FALSE; - NTSTATUS Result = STATUS_INTERNAL_ERROR; /* Shouldn't happen */ - KIRQL Irql; - - /* If the interrupt happens before this is setup, the key - * was already in the buffer. Too bad! */ - if (!DevExt->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - if (Idle == DevExt->Packet.State && - DevExt->PacketComplete) { - FinishIrp = TRUE; - Result = DevExt->PacketResult; - DevExt->PacketComplete = FALSE; - } - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, - Irql); - - if (!FinishIrp) - return; - - if (DevExt->CurrentIrp) { - DevExt->CurrentIrp->IoStatus.Status = Result; - IoCompleteRequest(DevExt->CurrentIrp, IO_NO_INCREMENT); - IoStartNextPacket(DevExt->CurrentIrpDevice, FALSE); - DevExt->CurrentIrp = NULL; - DevExt->CurrentIrpDevice = NULL; - } -} - -VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context) -{ - KEVENT Event; - IO_STATUS_BLOCK IoStatus; - NTSTATUS Status; - PDEVICE_EXTENSION DevExt; - PFDO_DEVICE_EXTENSION FdoDevExt; - PIRP NewIrp; - PI8042_HOOK_WORKITEM WorkItemData = (PI8042_HOOK_WORKITEM)Context; - - ULONG IoControlCode; - PVOID InputBuffer; - ULONG InputBufferLength; - BOOLEAN IsKbd; - - DPRINT("HookWorkItem\n"); - - FdoDevExt = (PFDO_DEVICE_EXTENSION) - DeviceObject->DeviceExtension; - - DevExt = FdoDevExt->PortDevExt; - - if (WorkItemData->Target == DevExt->KeyboardData.ClassDeviceObject) { - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD; - InputBuffer = &DevExt->KeyboardHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD); - IsKbd = TRUE; - DPRINT ("is for keyboard.\n"); - } else if (WorkItemData->Target == DevExt->MouseData.ClassDeviceObject){ - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE; - InputBuffer = &DevExt->MouseHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE); - IsKbd = FALSE; - DPRINT ("is for mouse.\n"); - } else { - DPRINT1("I8042SendHookWorkItem: Can't find DeviceObject\n"); - WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; - goto hookworkitemdone; - } - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - NewIrp = IoBuildDeviceIoControlRequest( - IoControlCode, - WorkItemData->Target, - InputBuffer, - InputBufferLength, - NULL, - 0, - TRUE, - &Event, - &IoStatus); - - if (!NewIrp) { - DPRINT("IOCTL_INTERNAL_(device)_CONNECT: " - "Can't allocate IRP\n"); - WorkItemData->Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - goto hookworkitemdone; - } - -#if 0 - Status = IoCallDriver( - WorkItemData->Target, - NewIrp); - - if (STATUS_PENDING == Status) - KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); -#endif - - if (IsKbd) { - /* Call the hooked initialization if it exists */ - if (DevExt->KeyboardHook.InitializationRoutine) { - Status = DevExt->KeyboardHook.InitializationRoutine( - DevExt->KeyboardHook.Context, - DevExt, - I8042SynchReadPort, - I8042SynchWritePortKbd, - FALSE); - if (!NT_SUCCESS(Status)) { - WorkItemData->Irp->IoStatus.Status = Status; - goto hookworkitemdone; - } - } - /* TODO: Now would be the right time to enable the interrupt */ - - DevExt->KeyboardClaimed = TRUE; - } else { - /* Mouse doesn't have this, but we need to send a - * reset to start the detection. - */ - KIRQL Irql; - - Irql = KeAcquireInterruptSpinLock( - DevExt->HighestDIRQLInterrupt); - - I8042Write(DevExt, I8042_CTRL_PORT, 0xD4); - I8042Write(DevExt, I8042_DATA_PORT, 0xFF); - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - } - - WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS; - -hookworkitemdone: - WorkItemData->Irp->IoStatus.Information = 0; - IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT); - - IoFreeWorkItem(WorkItemData->WorkItem); - ExFreePool(WorkItemData); - DPRINT("HookWorkItem done\n"); -} - -static VOID STDCALL I8042StartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - if (!I8042StartIoKbd(DeviceObject, Irp)) { - DPRINT1("Unhandled StartIo!\n"); - } -} - -static NTSTATUS STDCALL I8042InternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - - DPRINT("InternalDeviceControl\n"); - - switch (FdoDevExt->Type) { - case Keyboard: - Status = I8042InternalDeviceControlKbd(DeviceObject, Irp); - break; - case Mouse: - Status = I8042InternalDeviceControlMouse(DeviceObject, Irp); - break; - } - - if (Status == STATUS_INVALID_DEVICE_REQUEST) { - DPRINT1("Invalid internal device request!\n"); - } - - if (Status != STATUS_PENDING) - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; -} - -static NTSTATUS STDCALL I8042CreateDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status; - - DPRINT ("I8042CreateDispatch\n"); - - Status = STATUS_SUCCESS; - - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; -} - -static NTSTATUS STDCALL I8042BasicDetect(PDEVICE_EXTENSION DevExt) -{ - NTSTATUS Status; - UCHAR Value = 0; - ULONG Counter; - - DevExt->MouseExists = FALSE; - DevExt->KeyboardExists = FALSE; - - I8042Flush(); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_SELF_TEST)) { - DPRINT1("Writing KBD_SELF_TEST command failed\n"); - return STATUS_IO_TIMEOUT; - } - - // Wait longer? - Counter = 10; - do { - Status = I8042ReadDataWait(DevExt, &Value); - } while ((Counter--) && (STATUS_IO_TIMEOUT == Status)); - - if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to read KBD_SELF_TEST response, status 0x%x\n", - Status); - return Status; - } - - if (Value != 0x55) { - DPRINT1("Got %x instead of 55\n", Value); - return STATUS_IO_DEVICE_ERROR; - } - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= CCB_KBD_DISAB | CCB_MOUSE_DISAB; /* disable keyboard/mouse */ - Value &= ~(CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB); - /* don't enable keyboard and mouse interrupts */ - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - /* - * We used to send a KBD_LINE_TEST command here, but on at least HP - * Pavilion notebooks the response to that command was incorrect. - * So now we just assume that a keyboard is attached. - */ - DevExt->KeyboardExists = TRUE; - - if (I8042Write(DevExt, I8042_CTRL_PORT, MOUSE_LINE_TEST)) - { - Status = I8042ReadDataWait(DevExt, &Value); - if (NT_SUCCESS(Status) && Value == 0) - DevExt->MouseExists = TRUE; - } - - return STATUS_SUCCESS; -} - -static NTSTATUS STDCALL I8042Initialize(PDEVICE_EXTENSION DevExt) -{ - NTSTATUS Status; - - Status = I8042BasicDetect(DevExt); - if (!NT_SUCCESS(Status)) { - DPRINT1("Basic keyboard detection failed: %x\n", Status); - return Status; - } - - if (DevExt->MouseExists) { - DPRINT("Aux port detected\n"); - DevExt->MouseExists = I8042DetectMouse(DevExt); - } - - if (!DevExt->KeyboardExists) { - DPRINT("Keyboard port not detected\n"); - if (DevExt->Settings.Headless) - /* Act as if it exists regardless */ - DevExt->KeyboardExists = TRUE; - } else { - DPRINT("Keyboard port detected\n"); - DevExt->KeyboardExists = I8042DetectKeyboard(DevExt); - } - - if (DevExt->KeyboardExists) { - DPRINT("Keyboard detected\n"); - I8042KeyboardEnable(DevExt); - I8042KeyboardEnableInterrupt(DevExt); - } - - if (DevExt->MouseExists) { - DPRINT("Mouse detected\n"); - I8042MouseEnable(DevExt); - } - - return STATUS_SUCCESS; -} - -static NTSTATUS -AddRegistryEntry( - IN PCWSTR PortTypeName, - IN PUNICODE_STRING DeviceName, - IN PCWSTR RegistryPath) -{ - UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP"); - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hDeviceMapKey = (HANDLE)-1; - HANDLE hPortKey = (HANDLE)-1; - UNICODE_STRING PortTypeNameU; - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - RtlInitUnicodeString(&PortTypeNameU, PortTypeName); - InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL); - Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - Status = STATUS_SUCCESS; - -cleanup: - if (hDeviceMapKey != (HANDLE)-1) - ZwClose(hDeviceMapKey); - if (hPortKey != (HANDLE)-1) - ZwClose(hPortKey); - return Status; -} - -static NTSTATUS STDCALL I8042AddDevice(PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT Pdo) -{ - UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042"); - UNICODE_STRING MouseName = RTL_CONSTANT_STRING(L"\\Device\\PointerPort8042"); - ULONG MappedIrqKeyboard = 0, MappedIrqMouse = 0; - KIRQL DirqlKeyboard = 0; - KIRQL DirqlMouse = 0; - KIRQL DirqlMax; - KAFFINITY Affinity; - NTSTATUS Status; - PDEVICE_EXTENSION DevExt; - PFDO_DEVICE_EXTENSION FdoDevExt; - PDEVICE_OBJECT Fdo; - - DPRINT("I8042AddDevice\n"); - - if (Pdo != NULL) - { - /* Device detected by pnpmgr. Ignore it, as we already have - * detected the keyboard and mouse at first call */ - return STATUS_UNSUCCESSFUL; - } - - Status = IoCreateDevice(DriverObject, - sizeof(DEVICE_EXTENSION), - NULL, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - - if (!NT_SUCCESS(Status)) - return Status; - - DevExt = Fdo->DeviceExtension; - - RtlZeroMemory(DevExt, sizeof(DEVICE_EXTENSION)); - - I8042ReadRegistry(DriverObject, DevExt); - - KeInitializeSpinLock(&DevExt->SpinLock); - InitializeListHead(&DevExt->BusDevices); - - KeInitializeDpc(&DevExt->DpcKbd, - I8042DpcRoutineKbd, - DevExt); - - KeInitializeDpc(&DevExt->DpcMouse, - I8042DpcRoutineMouse, - DevExt); - - KeInitializeDpc(&DevExt->DpcMouseTimeout, - I8042DpcRoutineMouseTimeout, - DevExt); - - KeInitializeTimer(&DevExt->TimerMouseTimeout); - - Status = I8042Initialize(DevExt); - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - if (!NT_SUCCESS(STATUS_SUCCESS)) { - DPRINT1("Initialization failure: %x\n", Status); - return Status; - } - - if (DevExt->KeyboardExists) { - MappedIrqKeyboard = HalGetInterruptVector(Internal, - 0, - 0, - KEYBOARD_IRQ, - &DirqlKeyboard, - &Affinity); - - Status = IoCreateDevice(DriverObject, - sizeof(FDO_DEVICE_EXTENSION), - &DeviceName, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - - if (NT_SUCCESS(Status)) - { - AddRegistryEntry(L"KeyboardPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt"); - FdoDevExt = Fdo->DeviceExtension; - - RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION)); - - FdoDevExt->PortDevExt = DevExt; - FdoDevExt->Type = Keyboard; - FdoDevExt->DeviceObject = Fdo; - - Fdo->Flags |= DO_BUFFERED_IO; - - DevExt->DebugWorkItem = IoAllocateWorkItem(Fdo); - DevExt->KeyboardObject = Fdo; - - DevExt->KeyboardBuffer = ExAllocatePoolWithTag( - NonPagedPool, - DevExt->KeyboardAttributes.InputDataQueueLength * - sizeof(KEYBOARD_INPUT_DATA), - TAG_I8042); - - if (!DevExt->KeyboardBuffer) { - DPRINT1("No memory for keyboardbuffer\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - InsertTailList(&DevExt->BusDevices, &FdoDevExt->BusDevices); - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - } - else - DevExt->KeyboardExists = FALSE; - } - - if (DevExt->MouseExists) { - MappedIrqMouse = HalGetInterruptVector(Internal, - 0, - 0, - MOUSE_IRQ, - &DirqlMouse, - &Affinity); - - Status = IoCreateDevice(DriverObject, - sizeof(FDO_DEVICE_EXTENSION), - &MouseName, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - - if (NT_SUCCESS(Status)) - { - AddRegistryEntry(L"PointerPort", &MouseName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt"); - FdoDevExt = Fdo->DeviceExtension; - - RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION)); - - FdoDevExt->PortDevExt = DevExt; - FdoDevExt->Type = Mouse; - FdoDevExt->DeviceObject = Fdo; - - Fdo->Flags |= DO_BUFFERED_IO; - DevExt->MouseObject = Fdo; - - DevExt->MouseBuffer = ExAllocatePoolWithTag( - NonPagedPool, - DevExt->MouseAttributes.InputDataQueueLength * - sizeof(MOUSE_INPUT_DATA), - TAG_I8042); - - if (!DevExt->MouseBuffer) { - ExFreePoolWithTag(DevExt->KeyboardBuffer, TAG_I8042); - DPRINT1("No memory for mouse buffer\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - InsertTailList(&DevExt->BusDevices, &FdoDevExt->BusDevices); - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - } - else - DevExt->MouseExists = FALSE; - } - - if (DirqlKeyboard > DirqlMouse) - DirqlMax = DirqlKeyboard; - else - DirqlMax = DirqlMouse; - - if (DevExt->KeyboardExists) { - Status = IoConnectInterrupt(&DevExt->KeyboardInterruptObject, - I8042InterruptServiceKbd, - (PVOID)DevExt, - &DevExt->SpinLock, - MappedIrqKeyboard, - DirqlKeyboard, - DirqlMax, - LevelSensitive, - FALSE, - Affinity, - FALSE); - - DPRINT("Keyboard Irq Status: %x\n", Status); - } - - if (DevExt->MouseExists) { - Status = IoConnectInterrupt(&DevExt->MouseInterruptObject, - I8042InterruptServiceMouse, - (PVOID)DevExt, - &DevExt->SpinLock, - MappedIrqMouse, - DirqlMouse, - DirqlMax, - LevelSensitive, - FALSE, - Affinity, - FALSE); - - DPRINT("Mouse Irq Status: %x\n", Status); - } - - if (DirqlKeyboard > DirqlMouse) - DevExt->HighestDIRQLInterrupt = DevExt->KeyboardInterruptObject; - else - DevExt->HighestDIRQLInterrupt = DevExt->MouseInterruptObject; - - DPRINT("I8042AddDevice done\n"); - - return(STATUS_SUCCESS); -} - -NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath) -/* - * FUNCTION: Module entry point - */ -{ - DPRINT("I8042 Driver 0.0.1\n"); - - I8042RegistryPath.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters"); - I8042RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, - I8042RegistryPath.MaximumLength, - TAG_I8042); - if (I8042RegistryPath.Buffer == NULL) { - - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlCopyUnicodeString(&I8042RegistryPath, RegistryPath); - RtlAppendUnicodeToString(&I8042RegistryPath, L"\\Parameters"); - I8042RegistryPath.Buffer[I8042RegistryPath.Length / sizeof(WCHAR)] = 0; - - - - DriverObject->MajorFunction[IRP_MJ_CREATE] = I8042CreateDispatch; - DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = - I8042InternalDeviceControl; - - DriverObject->DriverStartIo = I8042StartIo; - DriverObject->DriverExtension->AddDevice = I8042AddDevice; - - return(STATUS_SUCCESS); -} diff --git a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.h b/reactos/drivers/input/i8042prt/i8042prt/i8042prt.h deleted file mode 100644 index 9abf7a91883..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.h +++ /dev/null @@ -1,378 +0,0 @@ -#ifndef _I8042DRV_H -#define _I8042DRV_H - -#include -#include -#include - -#ifdef _MSC_VER - #define STDCALL - #define DDKAPI -#endif - -#define KEYBOARD_IRQ 1 -#define MOUSE_IRQ 12 -#define KBD_BUFFER_SIZE 32 - -#define WHEEL_DELTA 120 - -/*----------------------------------------------------- - * DeviceExtension - * --------------------------------------------------*/ -typedef struct _COMMAND_CONTEXT -{ - int NumInput; - int CurInput; - UCHAR * Input; - int NumOutput; - int CurOutput; - UCHAR * Output; - NTSTATUS Status; - - BOOLEAN GotAck; - KEVENT Event; - - PVOID DevExt; -} COMMAND_CONTEXT, *PCOMMAND_CONTEXT; - -typedef enum _MOUSE_TIMEOUT_STATE -{ - NoChange, - TimeoutStart, - TimeoutCancel -} MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE; - -/* TODO: part of this should be in the _ATTRIBUTES structs instead */ -typedef struct _I8042_SETTINGS -{ - ULONG Headless; /* done */ - ULONG CrashScroll; - ULONG CrashSysRq; /* done */ - ULONG ReportResetErrors; - ULONG PollStatusIterations; /* done */ - ULONG ResendIterations; /* done */ - ULONG PollingIterations; - ULONG PollingIterationsMaximum; - ULONG OverrideKeyboardType; - ULONG OverrideKeyboardSubtype; - ULONG MouseResendStallTime; - ULONG MouseSynchIn100ns; /* done */ - ULONG MouseResolution; /* done */ - ULONG NumberOfButtons; - ULONG EnableWheelDetection; -} I8042_SETTINGS, *PI8042_SETTINGS; - -typedef enum _I8042_MOUSE_TYPE -{ - GenericPS2, - Intellimouse, - IntellimouseExplorer, - Ps2pp -} I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE; - -typedef enum _I8042_DEVICE_TYPE -{ - Keyboard, - Mouse -} I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE; - -typedef struct _I8042_DEVICE -{ - LIST_ENTRY ListEntry; - PDEVICE_OBJECT Pdo; -} I8042_DEVICE, *PI8042_DEVICE; - -typedef struct _DEVICE_EXTENSION -{ - PDEVICE_OBJECT KeyboardObject; - PDEVICE_OBJECT MouseObject; - - CONNECT_DATA KeyboardData; - CONNECT_DATA MouseData; - - BOOLEAN KeyboardExists; - BOOLEAN KeyboardIsAT; - BOOLEAN MouseExists; - - BOOLEAN KeyboardClaimed; - BOOLEAN MouseClaimed; - - ULONG BusNumber; - LIST_ENTRY BusDevices; - - INTERNAL_I8042_START_INFORMATION KeyboardStartInformation; - INTERNAL_I8042_START_INFORMATION MouseStartInformation; - - INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; - INTERNAL_I8042_HOOK_MOUSE MouseHook; - - PKINTERRUPT KeyboardInterruptObject; - PKINTERRUPT MouseInterruptObject; - PKINTERRUPT HighestDIRQLInterrupt; - KSPIN_LOCK SpinLock; - KDPC DpcKbd; - KDPC DpcMouse; - - KTIMER TimerMouseTimeout; - KDPC DpcMouseTimeout; - MOUSE_TIMEOUT_STATE MouseTimeoutState; - BOOLEAN MouseTimeoutActive; - - KEYBOARD_ATTRIBUTES KeyboardAttributes; - KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; - KEYBOARD_TYPEMATIC_PARAMETERS KeyboardTypematic; - - BOOLEAN WantAck; - BOOLEAN WantOutput; - BOOLEAN SignalEvent; - - KEYBOARD_SCAN_STATE KeyboardScanState; - BOOLEAN KeyComplete; - KEYBOARD_INPUT_DATA *KeyboardBuffer; - ULONG KeysInBuffer; - - MOUSE_ATTRIBUTES MouseAttributes; - - MOUSE_STATE MouseState; - BOOLEAN MouseComplete; - MOUSE_RESET_SUBSTATE MouseResetState; - MOUSE_INPUT_DATA *MouseBuffer; - ULONG MouseInBuffer; - USHORT MouseButtonState; - ULARGE_INTEGER MousePacketStartTime; - - UCHAR MouseLogiBuffer[3]; - UCHAR MouseLogitechID; - I8042_MOUSE_TYPE MouseType; - - OUTPUT_PACKET Packet; - ULONG PacketResends; - BOOLEAN PacketComplete; - NTSTATUS PacketResult; - UCHAR PacketBuffer[16]; - UCHAR PacketPort; - - PIRP CurrentIrp; - PDEVICE_OBJECT CurrentIrpDevice; - - /* registry config values */ - I8042_SETTINGS Settings; - - /* Debugger stuff */ - BOOLEAN TabPressed; - ULONG DebugKey; - PIO_WORKITEM DebugWorkItem; -} DEVICE_EXTENSION, *PDEVICE_EXTENSION; - -typedef struct _FDO_DEVICE_EXTENSION -{ - PDEVICE_EXTENSION PortDevExt; - I8042_DEVICE_TYPE Type; - PDEVICE_OBJECT DeviceObject; - - LIST_ENTRY BusDevices; -} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; - -typedef struct _I8042_HOOK_WORKITEM -{ - PIO_WORKITEM WorkItem; - PDEVICE_OBJECT Target; - PIRP Irp; -} I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM; - -/* - * Some defines - */ -#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) -#define TAG_I8042 TAG('8', '0', '4', '2') - -#define KBD_WRAP_MASK 0x1F - -#define ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) -#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) - - -/* - * Keyboard controller ports - */ - -#define I8042_DATA_PORT ((PUCHAR)0x60) -#define I8042_CTRL_PORT ((PUCHAR)0x64) - - -/* - * Controller commands - */ - -#define KBD_READ_MODE 0x20 -#define KBD_WRITE_MODE 0x60 -#define KBD_SELF_TEST 0xAA -#define KBD_LINE_TEST 0xAB -#define KBD_CTRL_ENABLE 0xAE - -#define MOUSE_LINE_TEST 0xA9 -#define MOUSE_CTRL_ENABLE 0xA8 - -#define KBD_READ_OUTPUT_PORT 0xD0 -#define KBD_WRITE_OUTPUT_PORT 0xD1 - -/* - * Keyboard commands - */ - -#define KBD_SET_LEDS 0xED -#define KBD_GET_ID 0xF2 -#define KBD_ENABLE 0xF4 -#define KBD_DISABLE 0xF5 -#define KBD_RESET 0xFF - - -/* - * Keyboard responces - */ - -#define KBD_BATCC 0xAA -#define KBD_ACK 0xFA -#define KBD_NACK 0xFC -#define KBD_RESEND 0xFE - -/* - * Controller status register bits - */ - -#define KBD_OBF 0x01 -#define KBD_IBF 0x02 -#define KBD_AUX 0x10 -#define KBD_GTO 0x40 -#define KBD_PERR 0x80 - -/* - * Controller command byte bits - */ -#define CCB_KBD_INT_ENAB 0x01 -#define CCB_MOUSE_INT_ENAB 0x02 -#define CCB_SYSTEM_FLAG 0x04 -#define CCB_IGN_KEY_LOCK 0x08 -#define CCB_KBD_DISAB 0x10 -#define CCB_MOUSE_DISAB 0x20 -#define CCB_TRANSLATE 0x40 - - -/* - * LED bits - */ - -#define KBD_LED_SCROLL 0x01 -#define KBD_LED_NUM 0x02 -#define KBD_LED_CAPS 0x04 - -/* - * Mouse responses - */ -#define MOUSE_ACK 0xFA -#define MOUSE_ERROR 0xFC -#define MOUSE_NACK 0xFE - -/* i8042prt.c */ -extern UNICODE_STRING I8042RegistryPath; - -NTSTATUS I8042ReadData(UCHAR *Data); - -NTSTATUS I8042ReadStatus(UCHAR *Status); - -NTSTATUS I8042ReadDataWait(PDEVICE_EXTENSION DevExt, UCHAR *Data); - -VOID I8042Flush(); - -VOID STDCALL I8042IsrWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Value, - UCHAR SelectCmd); - -NTSTATUS STDCALL I8042SynchWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Port, - UCHAR Value, - BOOLEAN WaitForAck); - -NTSTATUS STDCALL I8042StartPacket(PDEVICE_EXTENSION DevExt, - PDEVICE_OBJECT Device, - PUCHAR Bytes, - ULONG ByteCount, - PIRP Irp); - -BOOLEAN STDCALL I8042PacketIsr(PDEVICE_EXTENSION DevExt, - UCHAR Output); - -VOID I8042PacketDpc(PDEVICE_EXTENSION DevExt); - -VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context); - -BOOLEAN I8042Write(PDEVICE_EXTENSION DevExt, PUCHAR addr, UCHAR data); - -NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath); - -/* keyboard.c */ -VOID STDCALL I8042IsrWritePortKbd(PVOID Context, - UCHAR Value); - -NTSTATUS STDCALL I8042SynchWritePortKbd(PVOID Context, - UCHAR Value, - BOOLEAN WaitForAck); - -BOOLEAN STDCALL I8042InterruptServiceKbd(struct _KINTERRUPT *Interrupt, - VOID * Context); - -VOID STDCALL I8042DpcRoutineKbd(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); - -BOOLEAN STDCALL I8042StartIoKbd(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -NTSTATUS STDCALL I8042InternalDeviceControlKbd(PDEVICE_OBJECT DeviceObject, - PIRP Irp); - -BOOLEAN STDCALL I8042KeyboardEnable(PDEVICE_EXTENSION DevExt); - -BOOLEAN STDCALL I8042KeyboardEnableInterrupt(PDEVICE_EXTENSION DevExt); - -BOOLEAN STDCALL I8042DetectKeyboard(PDEVICE_EXTENSION DevExt); - -/* registry.c */ -VOID STDCALL I8042ReadRegistry(PDRIVER_OBJECT DriverObject, - PDEVICE_EXTENSION DevExt); - -/* mouse.c */ -VOID STDCALL I8042DpcRoutineMouse(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); - -VOID STDCALL I8042DpcRoutineMouseTimeout(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); - -BOOLEAN STDCALL I8042InterruptServiceMouse(struct _KINTERRUPT *Interrupt, - VOID *Context); - -NTSTATUS STDCALL I8042InternalDeviceControlMouse(PDEVICE_OBJECT DeviceObject, - PIRP Irp); - -VOID STDCALL I8042QueueMousePacket(PVOID Context); - -VOID STDCALL I8042MouseHandleButtons(PDEVICE_EXTENSION DevExt, - USHORT Mask); - -VOID STDCALL I8042MouseHandle(PDEVICE_EXTENSION DevExt, - UCHAR Output); - -BOOLEAN STDCALL I8042MouseEnable(PDEVICE_EXTENSION DevExt); -BOOLEAN STDCALL I8042MouseDisable(PDEVICE_EXTENSION DevExt); -BOOLEAN STDCALL I8042DetectMouse(PDEVICE_EXTENSION DevExt); - -/* ps2pp.c */ -VOID I8042MouseHandlePs2pp(PDEVICE_EXTENSION DevExt, UCHAR Input); - -#endif // _KEYBOARD_H_ diff --git a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rbuild b/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rbuild deleted file mode 100644 index ca4085c16de..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rbuild +++ /dev/null @@ -1,14 +0,0 @@ - - - . - - - ntoskrnl - hal - i8042prt.c - keyboard.c - mouse.c - ps2pp.c - registry.c - i8042prt.rc - diff --git a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rc b/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rc deleted file mode 100644 index 6c44176265e..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rc +++ /dev/null @@ -1,5 +0,0 @@ -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "I8042 Port Device Driver\0" -#define REACTOS_STR_INTERNAL_NAME "i8042prt\0" -#define REACTOS_STR_ORIGINAL_FILENAME "i8042prt.sys\0" -#include diff --git a/reactos/drivers/input/i8042prt/i8042prt/keyboard.c b/reactos/drivers/input/i8042prt/i8042prt/keyboard.c deleted file mode 100644 index a301d2ee129..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/keyboard.c +++ /dev/null @@ -1,776 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/keyboard.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * keyboard specifics - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -static UCHAR TypematicTable[] = { - 0x00, 0x00, 0x00, 0x05, 0x08, 0x0B, 0x0D, 0x0F, 0x10, 0x12, /* 0-9 */ - 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1A, /* 10-19 */ - 0x1B, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E }; - -typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION { - USHORT NumberOfIndicatorKeys; - INDICATOR_LIST IndicatorList[3]; -} LOCAL_KEYBOARD_INDICATOR_TRANSLATION, *PLOCAL_KEYBOARD_INDICATOR_TRANSLATION; - -static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = { 3, { - {0x3A, KEYBOARD_CAPS_LOCK_ON}, - {0x45, KEYBOARD_NUM_LOCK_ON}, - {0x46, KEYBOARD_SCROLL_LOCK_ON}}}; - -static VOID STDCALL I8042DebugWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context); - -/* FUNCTIONS *****************************************************************/ - -/* - * These functions are callbacks for filter driver custom interrupt - * service routines. - */ -VOID STDCALL I8042IsrWritePortKbd(PVOID Context, - UCHAR Value) -{ - I8042IsrWritePort(Context, Value, 0); -} - -static VOID STDCALL I8042QueueKeyboardPacket(PVOID Context) -{ - PDEVICE_OBJECT DeviceObject = Context; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DevExt->KeyComplete = TRUE; - DevExt->KeysInBuffer++; - if (DevExt->KeysInBuffer > - DevExt->KeyboardAttributes.InputDataQueueLength) { - DPRINT1("Keyboard buffer overflow\n"); - DevExt->KeysInBuffer--; - } - - DPRINT("Irq completes key\n"); - KeInsertQueueDpc(&DevExt->DpcKbd, DevExt, NULL); -} - -/* - * These functions are callbacks for filter driver custom - * initialization routines. - */ -NTSTATUS STDCALL I8042SynchWritePortKbd(PVOID Context, - UCHAR Value, - BOOLEAN WaitForAck) -{ - return I8042SynchWritePort((PDEVICE_EXTENSION)Context, - 0, - Value, - WaitForAck); -} - -BOOLEAN STDCALL I8042InterruptServiceKbd(struct _KINTERRUPT *Interrupt, - VOID * Context) -{ - UCHAR Output; - UCHAR PortStatus; - NTSTATUS Status; - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION) Context; - BOOLEAN HookContinue = FALSE, HookReturn; - ULONG Iterations = 0; - - KEYBOARD_INPUT_DATA *InputData = - DevExt->KeyboardBuffer + DevExt->KeysInBuffer; - - do { - Status = I8042ReadStatus(&PortStatus); - DPRINT("PortStatus: %x\n", PortStatus); - Status = I8042ReadData(&Output); - Iterations++; - if (STATUS_SUCCESS == Status) - break; - KeStallExecutionProcessor(1); - } while (Iterations < DevExt->Settings.PollStatusIterations); - - if (STATUS_SUCCESS != Status) { - DPRINT("Spurious I8042 interrupt\n"); - return FALSE; - } - - DPRINT("Got: %x\n", Output); - - if (DevExt->KeyboardHook.IsrRoutine) { - HookReturn = DevExt->KeyboardHook.IsrRoutine( - DevExt->KeyboardHook.Context, - InputData, - &DevExt->Packet, - PortStatus, - &Output, - &HookContinue, - &DevExt->KeyboardScanState); - - if (!HookContinue) - return HookReturn; - } - - if (I8042PacketIsr(DevExt, Output)) { - if (DevExt->PacketComplete) { - DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DevExt->DpcKbd, DevExt, NULL); - } - DPRINT("Irq eaten by packet\n"); - return TRUE; - } - - DPRINT("Irq is keyboard input\n"); - - if (Normal == DevExt->KeyboardScanState) { - switch (Output) { - case 0xe0: - DevExt->KeyboardScanState = GotE0; - return TRUE; - case 0xe1: - DevExt->KeyboardScanState = GotE1; - return TRUE; - default: - ;/* continue */ - } - } - - InputData->Flags = 0; - - switch (DevExt->KeyboardScanState) { - case GotE0: - InputData->Flags |= KEY_E0; - break; - case GotE1: - InputData->Flags |= KEY_E1; - break; - default: - ; - } - DevExt->KeyboardScanState = Normal; - - if (Output & 0x80) - InputData->Flags |= KEY_BREAK; - else - InputData->Flags |= KEY_MAKE; - - InputData->MakeCode = Output & 0x7f; - - I8042QueueKeyboardPacket(DevExt->KeyboardObject); - - return TRUE; -} - -VOID STDCALL I8042DpcRoutineKbd(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)SystemArgument1; - ULONG KeysTransferred = 0; - ULONG KeysInBufferCopy; - KIRQL Irql; - - I8042PacketDpc(DevExt); - - if (!DevExt->KeyComplete) - return; - - /* We got the interrupt as it was being enabled, too bad */ - if (!DevExt->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->KeyComplete = FALSE; - KeysInBufferCopy = DevExt->KeysInBuffer; - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - - /* Test for TAB (debugging) */ - if (DevExt->Settings.CrashSysRq) { - PKEYBOARD_INPUT_DATA InputData = DevExt->KeyboardBuffer + - KeysInBufferCopy - 1; - if (InputData->MakeCode == 0x0F) { - DPRINT("Tab!\n"); - DevExt->TabPressed = !(InputData->Flags & KEY_BREAK); - } else if (DevExt->TabPressed) { - DPRINT ("Queueing work item %x\n", DevExt->DebugWorkItem); - DevExt->DebugKey = InputData->MakeCode; - DevExt->TabPressed = FALSE; - - IoQueueWorkItem(DevExt->DebugWorkItem, - &(I8042DebugWorkItem), - DelayedWorkQueue, - DevExt); - } - } - - DPRINT ("Send a key\n"); - - if (!DevExt->KeyboardData.ClassService) - return; - - ((PSERVICE_CALLBACK_ROUTINE) DevExt->KeyboardData.ClassService)( - DevExt->KeyboardData.ClassDeviceObject, - DevExt->KeyboardBuffer, - DevExt->KeyboardBuffer + KeysInBufferCopy, - &KeysTransferred); - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - DevExt->KeysInBuffer -= KeysTransferred; - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); -} - -/* You have to send the rate/delay in a somewhat awkward format */ -static UCHAR I8042GetTypematicByte(USHORT Rate, USHORT Delay) -{ - UCHAR ret; - - if (Rate < 3) { - ret = 0x0; - } else if (Rate > 26) { - ret = 0x1F; - } else { - ret = TypematicTable[Rate]; - } - - if (Delay < 375) { - ; - } else if (Delay < 625) { - ret |= 0x20; - } else if (Delay < 875) { - ret |= 0x40; - } else { - ret |= 0x60; - } - return ret; -} -/* - * Process the keyboard internal device requests - * returns FALSE if it doesn't understand the - * call so someone else can handle it. - */ -BOOLEAN STDCALL I8042StartIoKbd(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER: - I8042StartPacket( - DevExt, - DeviceObject, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - Stk->Parameters.DeviceIoControl.InputBufferLength, - Irp); - break; - - case IOCTL_KEYBOARD_SET_INDICATORS: - DevExt->PacketBuffer[0] = 0xED; - DevExt->PacketBuffer[1] = 0; - if (DevExt->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON) - DevExt->PacketBuffer[1] |= 0x04; - - if (DevExt->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON) - DevExt->PacketBuffer[1] |= 0x02; - - if (DevExt->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON) - DevExt->PacketBuffer[1] |= 0x01; - - I8042StartPacket(DevExt, - DeviceObject, - DevExt->PacketBuffer, - 2, - Irp); - break; - case IOCTL_KEYBOARD_SET_TYPEMATIC: - DevExt->PacketBuffer[0] = 0xF3; - DevExt->PacketBuffer[1] = I8042GetTypematicByte( - DevExt->KeyboardTypematic.Rate, - DevExt->KeyboardTypematic.Delay); - - I8042StartPacket(DevExt, - DeviceObject, - DevExt->PacketBuffer, - 2, - Irp); - break; - default: - return FALSE; - } - - return TRUE; -} - -/* - * Runs the keyboard IOCTL_INTERNAL dispatch. - * Returns NTSTATUS_INVALID_DEVICE_REQUEST if it doesn't handle this request - * so someone else can have a try at it. - */ -NTSTATUS STDCALL I8042InternalDeviceControlKbd(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DPRINT("InternalDeviceControl\n"); - - Irp->IoStatus.Information = 0; - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - - case IOCTL_INTERNAL_KEYBOARD_CONNECT: - DPRINT("IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(CONNECT_DATA)) { - DPRINT1("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - - if (!DevExt->KeyboardExists) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; - goto intcontfailure; - } - - if (DevExt->KeyboardClaimed) { - DPRINT1("IOCTL_INTERNAL_KEYBOARD_CONNECT: " - "Keyboard is already claimed\n"); - Irp->IoStatus.Status = STATUS_SHARING_VIOLATION; - goto intcontfailure; - } - - memcpy(&DevExt->KeyboardData, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - sizeof(CONNECT_DATA)); - DevExt->KeyboardHook.IsrWritePort = I8042IsrWritePortKbd; - DevExt->KeyboardHook.QueueKeyboardPacket = - I8042QueueKeyboardPacket; - DevExt->KeyboardHook.CallContext = DevExt; - - { - PIO_WORKITEM WorkItem; - PI8042_HOOK_WORKITEM WorkItemData; - - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) { - DPRINT ("IOCTL_INTERNAL_KEYBOARD_CONNECT: " - "Can't allocate work item\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - goto intcontfailure; - } - - WorkItemData = ExAllocatePoolWithTag( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM), - TAG_I8042); - if (!WorkItemData) { - DPRINT ("IOCTL_INTERNAL_KEYBOARD_CONNECT: " - "Can't allocate work item data\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - IoFreeWorkItem(WorkItem); - goto intcontfailure; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Target = - DevExt->KeyboardData.ClassDeviceObject; - WorkItemData->Irp = Irp; - - IoMarkIrpPending(Irp); - IoQueueWorkItem(WorkItem, - I8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - - Irp->IoStatus.Status = STATUS_PENDING; - } - - break; - case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER: - DPRINT("IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < 1) { - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - if (!DevExt->KeyboardInterruptObject) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; - goto intcontfailure; - } - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: - DPRINT("IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"); - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(KEYBOARD_ATTRIBUTES)) { - DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->KeyboardAttributes, - sizeof(KEYBOARD_ATTRIBUTES)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_KEYBOARD_QUERY_INDICATORS: - DPRINT("IOCTL_KEYBOARD_QUERY_INDICATORS\n"); - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_INDICATORS " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->KeyboardIndicators, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_KEYBOARD_QUERY_TYPEMATIC: - DPRINT("IOCTL_KEYBOARD_QUERY_TYPEMATIC\n"); - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->KeyboardTypematic, - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_KEYBOARD_SET_INDICATORS: - DPRINT("IOCTL_KEYBOARD_SET_INDICATORS\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_SET_INDICTATORS " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - - memcpy(&DevExt->KeyboardIndicators, - Irp->AssociatedIrp.SystemBuffer, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - - DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags); - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_KEYBOARD_SET_TYPEMATIC: - DPRINT("IOCTL_KEYBOARD_SET_TYPEMATIC\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - - memcpy(&DevExt->KeyboardTypematic, - Irp->AssociatedIrp.SystemBuffer, - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)); - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: - /* We should check the UnitID, but it's kind of pointless as - * all keyboards are supposed to have the same one - */ - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) { - DPRINT("IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: " - "invalid buffer size (expected)\n"); - /* It's to query the buffer size */ - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - Irp->IoStatus.Information = - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); - - memcpy(Irp->AssociatedIrp.SystemBuffer, - &IndicatorTranslation, - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: - /* Nothing to do here */ - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - default: - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - -intcontfailure: - return Irp->IoStatus.Status; -} - -/* This is all pretty confusing. There's more than one way to - * disable/enable the keyboard. You can send KBD_ENABLE to the - * keyboard, and it will start scanning keys. Sending KBD_DISABLE - * will disable the key scanning but also reset the parameters to - * defaults. - * - * You can also send 0xAE to the controller for enabling the - * keyboard clock line and 0xAD for disabling it. Then it'll - * automatically get turned on at the next command. The last - * way is by modifying the bit that drives the clock line in the - * 'command byte' of the controller. This is almost, but not quite, - * the same as the AE/AD thing. The difference can be used to detect - * some really old broken keyboard controllers which I hope won't be - * necessary. - * - * We change the command byte, sending KBD_ENABLE/DISABLE seems to confuse - * some kvm switches. - */ - -BOOLEAN STDCALL I8042KeyboardEnable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Enable keyboard\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~CCB_KBD_DISAB; // don't disable keyboard - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -static BOOLEAN STDCALL I8042KeyboardDefaultsAndDisable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Disabling keyboard\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= CCB_KBD_DISAB; // disable keyboard - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -BOOLEAN STDCALL I8042KeyboardEnableInterrupt(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Enabling keyboard interrupt\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~CCB_KBD_DISAB; // don't disable keyboard - Value |= CCB_KBD_INT_ENAB; // enable keyboard interrupts - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -BOOLEAN STDCALL I8042DetectKeyboard(PDEVICE_EXTENSION DevExt) -{ - NTSTATUS Status; - UCHAR Value; - UCHAR Value2; - ULONG RetryCount = 10; - - DPRINT("Detecting keyboard\n"); - - I8042KeyboardDefaultsAndDisable(DevExt); - - do { - I8042Flush(); - Status = I8042SynchWritePort(DevExt, 0, KBD_GET_ID, TRUE); - } while (STATUS_IO_TIMEOUT == Status && RetryCount--); - - if (!NT_SUCCESS(Status)) { - DPRINT1("Can't write GET_ID (%x)\n", Status); - /* Could be an AT keyboard */ - DevExt->KeyboardIsAT = TRUE; - goto detectsetleds; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after GET_ID\n"); - /* Could be an AT keyboard */ - DevExt->KeyboardIsAT = TRUE; - goto detectsetleds; - } - DevExt->KeyboardIsAT = FALSE; - - if (Value != 0xAB && Value != 0xAC) { - DPRINT("Bad ID: %x\n", Value); - /* This is certainly not a keyboard */ - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value2); - if (!NT_SUCCESS(Status)) { - DPRINT("Partial ID\n"); - return FALSE; - } - - DPRINT("Keyboard ID: 0x%x 0x%x\n", Value, Value2); - -detectsetleds: - I8042Flush(); /* Flush any bytes left over from GET_ID */ - - Status = I8042SynchWritePort(DevExt, 0, KBD_SET_LEDS, TRUE); - if (!NT_SUCCESS(Status)) { - DPRINT("Can't write SET_LEDS (%x)\n", Status); - return FALSE; - } - Status = I8042SynchWritePort(DevExt, 0, 0, TRUE); - if (!NT_SUCCESS(Status)) { - DPRINT("Can't finish SET_LEDS (%x)\n", Status); - return FALSE; - } - - // Turn on translation - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= 0x40; // enable keyboard translation - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -/* debug stuff */ -VOID STDCALL -KdpServiceDispatcher(ULONG Code, PVOID Context1, PVOID Context2); -#define EnterDebugger ((PVOID)0x25) - -static VOID STDCALL I8042DebugWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context) -{ - ULONG Key; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - Key = InterlockedExchange((PLONG)&DevExt->DebugKey, 0); - DPRINT("Debug key: %x\n", Key); - - if (!Key) - return; - -#ifdef __REACTOS__ - /* We hope kernel would understand this. If - * that's not the case, nothing would happen. - */ - KdpServiceDispatcher(TAG('R', 'o', 's', ' '), (PVOID)Key, NULL); -#endif /* __REACTOS__ */ -} diff --git a/reactos/drivers/input/i8042prt/i8042prt/mouse.c b/reactos/drivers/input/i8042prt/i8042prt/mouse.c deleted file mode 100644 index 5a8afb5ebf3..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/mouse.c +++ /dev/null @@ -1,948 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/mouse.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * mouse specifics - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* - * These functions are callbacks for filter driver custom interrupt - * service routines. - */ -static VOID STDCALL I8042IsrWritePortMouse(PVOID Context, - UCHAR Value) -{ - I8042IsrWritePort(Context, Value, 0xD4); -} - -#if 0 -static NTSTATUS STDCALL I8042SynchWritePortMouse(PVOID Context, - UCHAR Value, - BOOLEAN WaitForAck) -{ - return I8042SynchWritePort((PDEVICE_EXTENSION)Context, - 0xD4, - Value, - WaitForAck); -} -#endif - -/* Test if packets are taking too long to come in. If they do, we - * might have gotten out of sync and should just drop what we have. - * - * If we want to be totally right, we'd also have to keep a count of - * errors, and totally reset the mouse after too much of them (can - * happen if the user is using a KVM switch and an OS on another port - * resets the mouse, or if the user hotplugs the mouse, or if we're just - * generally unlucky). Also note the input parsing routine where we - * drop invalid input packets. - */ -static VOID STDCALL I8042MouseInputTestTimeout(PDEVICE_EXTENSION DevExt) -{ - ULARGE_INTEGER Now; - - if (DevExt->MouseState == MouseExpectingACK || - DevExt->MouseState == MouseResetting) - return; - - Now.QuadPart = KeQueryInterruptTime(); - - if (DevExt->MouseState != MouseIdle) { - /* Check if the last byte came too long ago */ - if (Now.QuadPart - DevExt->MousePacketStartTime.QuadPart > - DevExt->Settings.MouseSynchIn100ns) { - DPRINT("Mouse input packet timeout\n"); - DevExt->MouseState = MouseIdle; - } - } - - if (DevExt->MouseState == MouseIdle) - DevExt->MousePacketStartTime.QuadPart = Now.QuadPart; -} - -/* - * Call the customization hook. The Ret2 parameter is about wether - * we should go on with the interrupt. The return value is what - * we should return (indicating to the system wether someone else - * should try to handle the interrupt) - */ -static BOOLEAN STDCALL I8042MouseCallIsrHook(PDEVICE_EXTENSION DevExt, - UCHAR Status, - PUCHAR Input, - PBOOLEAN ToReturn) -{ - BOOLEAN HookReturn, HookContinue; - - HookContinue = FALSE; - - if (DevExt->MouseHook.IsrRoutine) { - HookReturn = DevExt->MouseHook.IsrRoutine( - DevExt->MouseHook.Context, - DevExt->MouseBuffer + DevExt->MouseInBuffer, - &DevExt->Packet, - Status, - Input, - &HookContinue, - &DevExt->MouseState, - &DevExt->MouseResetState); - - if (!HookContinue) { - *ToReturn = HookReturn; - return TRUE; - } - } - return FALSE; -} - -static BOOLEAN STDCALL I8042MouseResetIsr(PDEVICE_EXTENSION DevExt, - UCHAR Status, - PUCHAR Value) -{ - BOOLEAN ToReturn = FALSE; - - if (I8042MouseCallIsrHook(DevExt, Status, Value, &ToReturn)) - return ToReturn; - - if (MouseResetting != DevExt->MouseState) { - return FALSE; - } - DevExt->MouseTimeoutState = TimeoutStart; - - switch (DevExt->MouseResetState) { - case 1100: /* the first ack, drop it. */ - DevExt->MouseResetState = ExpectingReset; - return TRUE; - /* First, 0xFF is sent. The mouse is supposed to say AA00 if ok, - * FC00 if not. - */ - case ExpectingReset: - if (0xAA == *Value) { - DevExt->MouseResetState++; - } else { - DevExt->MouseExists = FALSE; - DevExt->MouseState = MouseIdle; - DPRINT("Mouse returned bad reset reply: " - "%x (expected aa)\n", *Value); - } - return TRUE; - case ExpectingResetId: - if (0x00 == *Value) { - DevExt->MouseResetState++; - DevExt->MouseType = GenericPS2; - I8042IsrWritePortMouse(DevExt, 0xF2); - } else { - DevExt->MouseExists = FALSE; - DevExt->MouseState = MouseIdle; - DPRINT1("Mouse returned bad reset reply part two: " - "%x (expected 0)\n", *Value); - } - return TRUE; - case ExpectingGetDeviceIdACK: - if (MOUSE_ACK == *Value) { - DevExt->MouseResetState++; - } else if (MOUSE_NACK == *Value || - MOUSE_ERROR == *Value) { - DevExt->MouseResetState++; - /* Act as if 00 (normal mouse) was received */ - DPRINT("Mouse doesn't support 0xd2, " - "(returns %x, expected %x), faking.\n", - *Value, MOUSE_ACK); - *Value = 0; - I8042MouseResetIsr(DevExt, Status, Value); - } - return TRUE; - case ExpectingGetDeviceIdValue: - switch (*Value) { - case 0x02: - DevExt->MouseAttributes.MouseIdentifier = - BALLPOINT_I8042_HARDWARE; - break; - case 0x03: - case 0x04: - DevExt->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - break; - default: - DevExt->MouseAttributes.MouseIdentifier = - MOUSE_I8042_HARDWARE; - } - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0xE8); - return TRUE; - case ExpectingSetResolutionDefaultACK: - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0x00); - return TRUE; - case ExpectingSetResolutionDefaultValueACK: - DevExt->MouseResetState = ExpectingSetScaling1to1ACK; - I8042IsrWritePortMouse(DevExt, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK: - case ExpectingSetScaling1to1ACK2: - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK3: - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0xE9); - return TRUE; - case ExpectingReadMouseStatusACK: - DevExt->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte1: - DevExt->MouseLogiBuffer[0] = *Value; - DevExt->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte2: - DevExt->MouseLogiBuffer[1] = *Value; - DevExt->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte3: - DevExt->MouseLogiBuffer[2] = *Value; - /* Now MouseLogiBuffer is a set of info. If the second - * byte is 0, the mouse didn't understand the magic - * code. Otherwise, it it a Logitech and the second byte - * is the number of buttons, bit 7 of the first byte tells - * if it understands special E7 commands, the rest is an ID. - */ - if (DevExt->MouseLogiBuffer[1]) { - DevExt->MouseAttributes.NumberOfButtons = - DevExt->MouseLogiBuffer[1]; - /* For some reason the ID is the wrong way around */ - DevExt->MouseLogitechID = - ((DevExt->MouseLogiBuffer[0] >> 4) & 0x07) | - ((DevExt->MouseLogiBuffer[0] << 3) & 0x78); - DevExt->MouseType = Ps2pp; - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - /* TODO: Go through EnableWheel and Enable5Buttons */ - } - DevExt->MouseResetState = EnableWheel; - I8042MouseResetIsr(DevExt, Status, Value); - return TRUE; - case EnableWheel: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = 1001; - return TRUE; - case 1001: - I8042IsrWritePortMouse(DevExt, 0xc8); - DevExt->MouseResetState++; - return TRUE; - case 1002: - case 1004: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState++; - return TRUE; - case 1003: - I8042IsrWritePortMouse(DevExt, 0x64); - DevExt->MouseResetState++; - return TRUE; - case 1005: - I8042IsrWritePortMouse(DevExt, 0x50); - DevExt->MouseResetState++; - return TRUE; - case 1006: - I8042IsrWritePortMouse(DevExt, 0xf2); - DevExt->MouseResetState++; - return TRUE; - case 1007: - /* Ignore ACK */ - DevExt->MouseResetState++; - return TRUE; - case 1008: - /* Now if the value == 3, it's either an Intellimouse - * or Intellimouse Explorer. */ - if (0x03 == *Value) { - DevExt->MouseAttributes.NumberOfButtons = 3; - DevExt->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DevExt->MouseType = Intellimouse; - DevExt->MouseResetState = Enable5Buttons; - I8042MouseResetIsr(DevExt, Status, Value); - return TRUE; - } /* Else, just set the default settings and be done */ - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - case Enable5Buttons: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = 1021; - return TRUE; - case 1022: - case 1024: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState++; - return TRUE; - case 1021: - case 1023: - I8042IsrWritePortMouse(DevExt, 0xc8); - DevExt->MouseResetState++; - return TRUE; - case 1025: - I8042IsrWritePortMouse(DevExt, 0x50); - DevExt->MouseResetState++; - return TRUE; - case 1026: - I8042IsrWritePortMouse(DevExt, 0xf2); - DevExt->MouseResetState++; - return TRUE; - case 1027: - if (0x04 == *Value) { - DevExt->MouseAttributes.NumberOfButtons = 5; - DevExt->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DevExt->MouseType = IntellimouseExplorer; - } - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - case ExpectingSetSamplingRateACK: - I8042IsrWritePortMouse(DevExt, - (UCHAR)DevExt->MouseAttributes.SampleRate); - DevExt->MouseResetState++; - return TRUE; - case ExpectingSetSamplingRateValueACK: - if (MOUSE_NACK == *Value) { - I8042IsrWritePortMouse(DevExt, 0x3c); - DevExt->MouseAttributes.SampleRate = 60; - DevExt->MouseResetState = 1040; - return TRUE; - } - case 1040: /* Fallthrough */ - I8042IsrWritePortMouse(DevExt, 0xe8); - DevExt->MouseResetState = ExpectingFinalResolutionACK; - return TRUE; - case ExpectingFinalResolutionACK: - I8042IsrWritePortMouse(DevExt, - (UCHAR)(DevExt->Settings.MouseResolution & 0xff)); - DPRINT("%x\n", DevExt->Settings.MouseResolution); - DevExt->MouseResetState = ExpectingFinalResolutionValueACK; - return TRUE; - case ExpectingFinalResolutionValueACK: - I8042IsrWritePortMouse(DevExt, 0xf4); - DevExt->MouseResetState = ExpectingEnableACK; - return TRUE; - case ExpectingEnableACK: - DevExt->MouseState = MouseIdle; - DevExt->MouseTimeoutState = TimeoutCancel; - DPRINT("Mouse type = %d\n", DevExt->MouseType); - return TRUE; - default: - if (DevExt->MouseResetState < 100 || - DevExt->MouseResetState > 999) - DPRINT1("MouseResetState went out of range: %d\n", - DevExt->MouseResetState); - return FALSE; - } -} - -/* - * Prepare for reading the next packet and queue the dpc for handling - * this one. - * - * Context is the device object. - */ -VOID STDCALL I8042QueueMousePacket(PVOID Context) -{ - PDEVICE_OBJECT DeviceObject = Context; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DevExt->MouseComplete = TRUE; - DevExt->MouseInBuffer++; - if (DevExt->MouseInBuffer > - DevExt->MouseAttributes.InputDataQueueLength) { - DPRINT1("Mouse buffer overflow\n"); - DevExt->MouseInBuffer--; - } - - DPRINT("Irq completes mouse packet\n"); - KeInsertQueueDpc(&DevExt->DpcMouse, DevExt, NULL); -} - -/* - * Updates ButtonFlags according to RawButtons and a saved state; - * Only takes in account the bits that are set in Mask - */ -VOID STDCALL I8042MouseHandleButtons(PDEVICE_EXTENSION DevExt, - USHORT Mask) -{ - PMOUSE_INPUT_DATA MouseInput = DevExt->MouseBuffer + - DevExt->MouseInBuffer; - USHORT NewButtonData = (USHORT)(MouseInput->RawButtons & Mask); - USHORT ButtonDiff = (NewButtonData ^ DevExt->MouseButtonState) & Mask; - - /* Note that the defines are such: - * MOUSE_LEFT_BUTTON_DOWN 1 - * MOUSE_LEFT_BUTTON_UP 2 - */ - MouseInput->ButtonFlags |= (NewButtonData & ButtonDiff) | - (((~(NewButtonData)) << 1) & - (ButtonDiff << 1)) | - (MouseInput->RawButtons & 0xfc00); - - DPRINT("Left raw/up/down: %d/%d/%d\n", MouseInput->RawButtons & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_UP); - - DevExt->MouseButtonState = (DevExt->MouseButtonState & ~Mask) | - (NewButtonData & Mask); -} - -VOID STDCALL I8042MouseHandle(PDEVICE_EXTENSION DevExt, - UCHAR Output) -{ - PMOUSE_INPUT_DATA MouseInput = DevExt->MouseBuffer + - DevExt->MouseInBuffer; - CHAR Scroll; - - switch (DevExt->MouseState) { - case MouseIdle: - /* This bit should be 1, if not drop the packet, we - * might be lucky and get in sync again - */ - if (!(Output & 8)) { - DPRINT1("Bad input, dropping..\n"); - return; - } - - MouseInput->Buttons = 0; - MouseInput->RawButtons = 0; - MouseInput->Flags = MOUSE_MOVE_RELATIVE; - - /* Note how we ignore the overflow bits, like Windows - * is said to do. There's no reasonable thing to do - * anyway. - */ - - if (Output & 16) - MouseInput->LastX = 1; - else - MouseInput->LastX = 0; - - if (Output & 32) - MouseInput->LastY = 1; - else - MouseInput->LastY = 0; - - if (Output & 1) { - MouseInput->RawButtons |= MOUSE_LEFT_BUTTON_DOWN; - } - - if (Output & 2) { - MouseInput->RawButtons |= MOUSE_RIGHT_BUTTON_DOWN; - } - - if (Output & 4) { - MouseInput->RawButtons |= MOUSE_MIDDLE_BUTTON_DOWN; - } - DevExt->MouseState = XMovement; - break; - case XMovement: - if (MouseInput->LastX) - MouseInput->LastX = (LONG) Output - 256; - else - MouseInput->LastX = Output; - - DevExt->MouseState = YMovement; - break; - case YMovement: - if (MouseInput->LastY) - MouseInput->LastY = (LONG)Output - 256; - else - MouseInput->LastY = (LONG)Output; - - /* Windows wants it the other way around */ - MouseInput->LastY = -MouseInput->LastY; - - if (DevExt->MouseType == GenericPS2 || - DevExt->MouseType == Ps2pp) { - I8042MouseHandleButtons(DevExt, - MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN); - I8042QueueMousePacket( - DevExt->MouseObject); - DevExt->MouseState = MouseIdle; - } else { - DevExt->MouseState = ZMovement; - } - break; - case ZMovement: - Scroll = Output & 0x0f; - if (Scroll & 8) - Scroll |= 0xf0; - - if (Scroll) { - MouseInput->RawButtons |= MOUSE_WHEEL; - MouseInput->ButtonData = (USHORT)(Scroll * -WHEEL_DELTA); - } - - if (DevExt->MouseType == IntellimouseExplorer) { - if (Output & 16) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - - if (Output & 32) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - } - I8042MouseHandleButtons(DevExt, MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN | - MOUSE_BUTTON_4_DOWN | - MOUSE_BUTTON_5_DOWN); - I8042QueueMousePacket(DevExt->MouseObject); - DevExt->MouseState = MouseIdle; - break; - default: - DPRINT1("Unexpected state!\n"); - } -} - -BOOLEAN STDCALL I8042InterruptServiceMouse(struct _KINTERRUPT *Interrupt, - VOID *Context) -{ - UCHAR Output, PortStatus; - NTSTATUS Status; - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION) Context; - ULONG Iterations = 0; - - do { - Status = I8042ReadStatus(&PortStatus); - Status = I8042ReadData(&Output); - Iterations++; - if (STATUS_SUCCESS == Status) - break; - KeStallExecutionProcessor(1); - } while (Iterations < DevExt->Settings.PollStatusIterations); - - if (STATUS_SUCCESS != Status) { - DPRINT1("Spurious I8042 mouse interrupt\n"); - return FALSE; - } - - DPRINT("Got: %x\n", Output); - - if (I8042PacketIsr(DevExt, Output)) { - if (DevExt->PacketComplete) { - DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DevExt->DpcKbd, DevExt, NULL); - } - DPRINT("Irq eaten by packet\n"); - return TRUE; - } - - I8042MouseInputTestTimeout(DevExt); - - if (I8042MouseResetIsr(DevExt, PortStatus, &Output)) { - DPRINT("Handled by ResetIsr or hooked Isr\n"); - if (NoChange != DevExt->MouseTimeoutState) { - KeInsertQueueDpc(&DevExt->DpcMouse, DevExt, NULL); - } - return TRUE; - } - - if (DevExt->MouseType == Ps2pp) - I8042MouseHandlePs2pp(DevExt, Output); - else - I8042MouseHandle(DevExt, Output); - - return TRUE; -} - -VOID STDCALL I8042DpcRoutineMouse(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)SystemArgument1; - ULONG MouseTransferred = 0; - ULONG MouseInBufferCopy; - KIRQL Irql; - LARGE_INTEGER Timeout; - - switch (DevExt->MouseTimeoutState) { - case TimeoutStart: - DevExt->MouseTimeoutState = NoChange; - if (DevExt->MouseTimeoutActive && - !KeCancelTimer(&DevExt->TimerMouseTimeout)) { - /* The timer fired already, give up */ - DevExt->MouseTimeoutActive = FALSE; - return; - } - - Timeout.QuadPart = -15000000; - /* 1.5 seconds, should be enough */ - - KeSetTimer(&DevExt->TimerMouseTimeout, - Timeout, - &DevExt->DpcMouseTimeout); - DevExt->MouseTimeoutActive = TRUE; - return; - case TimeoutCancel: - DevExt->MouseTimeoutState = NoChange; - KeCancelTimer(&DevExt->TimerMouseTimeout); - DevExt->MouseTimeoutActive = FALSE; - default: - /* nothing, don't want a warning */ ; - } - - /* Should be unlikely */ - if (!DevExt->MouseComplete) - return; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->MouseComplete = FALSE; - MouseInBufferCopy = DevExt->MouseInBuffer; - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - - DPRINT ("Send a mouse packet\n"); - - if (!DevExt->MouseData.ClassService) - return; - - ((PSERVICE_CALLBACK_ROUTINE) DevExt->MouseData.ClassService)( - DevExt->MouseData.ClassDeviceObject, - DevExt->MouseBuffer, - DevExt->MouseBuffer + MouseInBufferCopy, - &MouseTransferred); - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->MouseInBuffer -= MouseTransferred; - if (DevExt->MouseInBuffer) - RtlMoveMemory(DevExt->MouseBuffer, - DevExt->MouseBuffer+MouseTransferred, - DevExt->MouseInBuffer * sizeof(MOUSE_INPUT_DATA)); - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); -} - -/* This timer DPC will be called when the mouse reset times out. - * I'll just send the 'disable mouse port' command to the controller - * and say the mouse doesn't exist. - */ -VOID STDCALL I8042DpcRoutineMouseTimeout(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)DeferredContext; - KIRQL Irql; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DPRINT1("Mouse initialization timeout! (substate %x) " - "Disabling mouse.\n", - DevExt->MouseResetState); - - if (!I8042MouseDisable(DevExt)) { - DPRINT1("Failed to disable mouse.\n"); - } - - DevExt->MouseExists = FALSE; - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); -} - -/* - * Process the mouse internal device requests - * returns FALSE if it doesn't understand the - * call so someone else can handle it. - */ -#if 0 -static BOOLEAN STDCALL I8042StartIoMouse(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - case IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER: - I8042StartPacket( - DevExt, - DeviceObject, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - Stk->Parameters.DeviceIoControl.InputBufferLength, - Irp); - break; - - default: - return FALSE; - } - - return TRUE; -} -#endif - -/* - * Runs the mouse IOCTL_INTERNAL dispatch. - * Returns NTSTATUS_INVALID_DEVICE_REQUEST if it doesn't handle this request - * so someone else can have a try at it. - */ -NTSTATUS STDCALL I8042InternalDeviceControlMouse(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DPRINT("InternalDeviceControl\n"); - - Irp->IoStatus.Information = 0; - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - - case IOCTL_INTERNAL_MOUSE_CONNECT: - DPRINT("IOCTL_INTERNAL_MOUSE_CONNECT\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(CONNECT_DATA)) { - DPRINT1("Mouse IOCTL_INTERNAL_MOUSE_CONNECT " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - - if (!DevExt->MouseExists) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; - goto intcontfailure; - } - - if (DevExt->MouseClaimed) { - DPRINT1("IOCTL_INTERNAL_MOUSE_CONNECT: " - "Mouse is already claimed\n"); - Irp->IoStatus.Status = STATUS_SHARING_VIOLATION; - goto intcontfailure; - } - - memcpy(&DevExt->MouseData, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - sizeof(CONNECT_DATA)); - DevExt->MouseHook.IsrWritePort = I8042IsrWritePortMouse; - DevExt->MouseHook.QueueMousePacket = - I8042QueueMousePacket; - DevExt->MouseHook.CallContext = DevExt; - - { - PIO_WORKITEM WorkItem; - PI8042_HOOK_WORKITEM WorkItemData; - - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) { - DPRINT ("IOCTL_INTERNAL_MOUSE_CONNECT: " - "Can't allocate work item\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - goto intcontfailure; - } - - WorkItemData = ExAllocatePoolWithTag( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM), - TAG_I8042); - if (!WorkItemData) { - DPRINT ("IOCTL_INTERNAL_MOUSE_CONNECT: " - "Can't allocate work item data\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - IoFreeWorkItem(WorkItem); - goto intcontfailure; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Target = - DevExt->MouseData.ClassDeviceObject; - WorkItemData->Irp = Irp; - - IoMarkIrpPending(Irp); - DevExt->MouseState = MouseResetting; - DevExt->MouseResetState = 1100; - IoQueueWorkItem(WorkItem, - I8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - - Irp->IoStatus.Status = STATUS_PENDING; - } - - break; - case IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER: - DPRINT("IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < 1) { - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - if (!DevExt->MouseInterruptObject) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; - goto intcontfailure; - } - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_MOUSE_QUERY_ATTRIBUTES: - DPRINT("IOCTL_MOUSE_QUERY_ATTRIBUTES\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(MOUSE_ATTRIBUTES)) { - DPRINT("Mouse IOCTL_MOUSE_QUERY_ATTRIBUTES " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->MouseAttributes, - sizeof(MOUSE_ATTRIBUTES)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - default: - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - -intcontfailure: - return Irp->IoStatus.Status; -} - -BOOLEAN STDCALL I8042MouseEnable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Enabling mouse\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~(0x20); // don't disable mouse - Value |= 0x02; // enable mouse interrupts - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -BOOLEAN STDCALL I8042MouseDisable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Disabling mouse\n"); - - I8042Flush(); /* Just to be (kind of) sure */ - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= 0x20; // don't disable mouse - Value &= ~(0x02); // enable mouse interrupts - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - I8042Flush(); - /* Just to be (kind of) sure; if the mouse would - * say something while we are disabling it, these bytes would - * block the keyboard. - */ - - return TRUE; -} - -BOOLEAN STDCALL I8042DetectMouse(PDEVICE_EXTENSION DevExt) -{ - BOOLEAN Ok = TRUE; - NTSTATUS Status; - UCHAR Value; - UCHAR ExpectedReply[] = { 0xFA, 0xAA, 0x00 }; - unsigned ReplyByte; - - if (! I8042Write(DevExt, I8042_CTRL_PORT, 0xD4) || - ! I8042Write(DevExt, I8042_DATA_PORT, 0xFF)) - { - DPRINT1("Failed to write reset command to mouse\n"); - Ok = FALSE; - } - - for (ReplyByte = 0; - ReplyByte < sizeof(ExpectedReply) / sizeof(ExpectedReply[0]) && Ok; - ReplyByte++) - { - Status = I8042ReadDataWait(DevExt, &Value); - if (! NT_SUCCESS(Status)) - { - DPRINT1("No ACK after mouse reset, status 0x%08x\n", - Status); - Ok = FALSE; - } - else if (Value != ExpectedReply[ReplyByte]) - { - DPRINT1("Unexpected reply: 0x%02x (expected 0x%02x)\n", - Value, ExpectedReply[ReplyByte]); - Ok = FALSE; - } - } - - if (! Ok) - { - /* There is probably no mouse present. On some systems, - the probe locks the entire keyboard controller. Let's - try to get access to the keyboard again by sending a - reset */ - I8042Flush(); - I8042Write(DevExt, I8042_CTRL_PORT, KBD_SELF_TEST); - I8042ReadDataWait(DevExt, &Value); - I8042Flush(); - } - - DPRINT("Mouse %sdetected\n", Ok ? "" : "not "); - - return Ok; -} diff --git a/reactos/drivers/input/i8042prt/i8042prt/ps2pp.c b/reactos/drivers/input/i8042prt/i8042prt/ps2pp.c deleted file mode 100644 index 3b183ec8617..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/ps2pp.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/ps2pp.c - * PURPOSE: i8042prt driver - * ps2pp protocol handling - * PROGRAMMER: Tinus - */ - -/* INCLUDES ****************************************************************/ - -#ifndef NDEBUG -#define NDEBUG -#endif -#include - -#include "i8042prt.h" - - -VOID I8042MouseHandlePs2pp(PDEVICE_EXTENSION DevExt, UCHAR Input) -{ - UCHAR PktType; - PMOUSE_INPUT_DATA MouseInput = DevExt->MouseBuffer + - DevExt->MouseInBuffer; - -/* First, collect 3 bytes for a packet - * We can detect out-of-sync only by checking - * the whole packet anyway. - * - * If bit 7 and 8 of the first byte are 0, its - * a normal packet. - * - * Otherwise, the packet is different, like this: - * 1: E 1 b3 b2 x x x x - * 2: x x b1 b0 x1 x0 1 0 - * 3: x x x x x x x1 x0 - * - * b3-0 form a code that specifies the packet type: - * - * 0 Device Type - * 1 Rollers and buttons - * 2 Reserved - * 3 Reserved - * 4 Device ID - * 5 Channel & Battery - * 6 Wireless notifications - * 7 Reserved - * 8 ShortID LSB (ShortID is a number that is supposed to differentiate - * 9 ShortID MSB between your mouse and your neighbours') - * 10 Reserved - * 11 Mouse capabilities - * 12 Remote control LSB - * 13 Remote control MSB - * 14 Reserved - * 15 Extended packet - */ - - switch (DevExt->MouseState) { - case MouseIdle: - case XMovement: - DevExt->MouseLogiBuffer[DevExt->MouseState] = Input; - DevExt->MouseState++; - break; - - case YMovement: - DevExt->MouseLogiBuffer[2] = Input; - DevExt->MouseState = MouseIdle; - - /* first check if it's a normal packet */ - - if (!(DevExt->MouseLogiBuffer[0] & 0xC0)) { - DevExt->MouseState = MouseIdle; - I8042MouseHandle(DevExt, DevExt->MouseLogiBuffer[0]); - I8042MouseHandle(DevExt, DevExt->MouseLogiBuffer[1]); - I8042MouseHandle(DevExt, DevExt->MouseLogiBuffer[2]); - /* We could care about wether MouseState really - * advances, but we don't need to because we're - * only doing three bytes anyway, so the packet - * will never complete if it's broken. - */ - return; - } - - /* sanity check */ - - if (((DevExt->MouseLogiBuffer[0] & 0x48) != 0x48) || - (((DevExt->MouseLogiBuffer[1] & 0x0C) >> 2) != - (DevExt->MouseLogiBuffer[2] & 0x03))) { - DPRINT1("Ps2pp packet fails sanity checks\n"); - return; - } - - /* Now get the packet type */ - - PktType = ((DevExt->MouseLogiBuffer[0] & 0x30) >> 4) & - ((DevExt->MouseLogiBuffer[1] & 0x30) >> 6); - - switch (PktType) { - case 0: - /* The packet contains the device ID, but we - * already read that in the initialization - * sequence. Ignore it. - */ - return; - case 1: - RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA)); - if (DevExt->MouseLogiBuffer[2] & 0x10) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - - if (DevExt->MouseLogiBuffer[2] & 0x20) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - - if (DevExt->MouseLogiBuffer[2] & 0x0F) { - MouseInput->ButtonFlags |= MOUSE_WHEEL; - if (DevExt->MouseLogiBuffer[2] & 0x08) - MouseInput->ButtonData = - (DevExt->MouseLogiBuffer[2] & 0x07) - - 8; - else - MouseInput->ButtonData = - DevExt->MouseLogiBuffer[2] & 0x07; - } - I8042MouseHandleButtons(DevExt, MOUSE_BUTTON_4_DOWN | - MOUSE_BUTTON_5_DOWN); - I8042QueueMousePacket( - DevExt->MouseObject); - return; - default: - /* These are for things that would probably - * be handled by logitechs own driver. - */ - return; - } - default: - DPRINT1("Unexpected input state for ps2pp!\n"); - } -} diff --git a/reactos/drivers/input/i8042prt/i8042prt/registry.c b/reactos/drivers/input/i8042prt/i8042prt/registry.c deleted file mode 100644 index 8c25872cd31..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/registry.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/registry.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * Reading the registry - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus - */ - -/* INCLUDES ****************************************************************/ - -#ifndef NDEBUG -#define NDEBUG -#endif -#include - -#include "i8042prt.h" - -/* FUNCTIONS *****************************************************************/ - -/* - * Read the registry keys associated with this device. The RegistryPath - * var is a hack. This should be more like what microsoft does, but I - * don't know exactly what they do except that it's a hack too... - */ -VOID STDCALL I8042ReadRegistry(PDRIVER_OBJECT DriverObject, - PDEVICE_EXTENSION DevExt) - -{ - RTL_QUERY_REGISTRY_TABLE Parameters[19]; - - NTSTATUS Status; - - ULONG DefaultHeadless = 0; - ULONG DefaultCrashScroll = 0; - ULONG DefaultCrashSysRq = 0; - ULONG DefaultReportResetErrors = 0; - ULONG DefaultPollStatusIterations = 1; - ULONG DefaultResendIterations = 3; - ULONG DefaultPollingIterations = 12000; - ULONG DefaultPollingIterationsMaximum = 12000; - ULONG DefaultKeyboardDataQueueSize = 100; - ULONG DefaultOverrideKeyboardType = 0; - ULONG DefaultOverrideKeyboardSubtype = 0; - ULONG DefaultMouseDataQueueSize = 100; - ULONG DefaultMouseResendStallTime = 1000; - ULONG DefaultMouseSynchIn100ns = 20000000; - ULONG DefaultMouseResolution = 3; - ULONG DefaultSampleRate = 60; - ULONG DefaultNumberOfButtons = 2; - ULONG DefaultEnableWheelDetection = 1; - - RtlZeroMemory(Parameters, sizeof(Parameters)); - - Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[0].Name = L"Headless"; - Parameters[0].EntryContext = &DevExt->Settings.Headless; - Parameters[0].DefaultType = REG_DWORD; - Parameters[0].DefaultData = &DefaultHeadless; - Parameters[0].DefaultLength = sizeof(ULONG); - - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[1].Name = L"CrashOnCtrlScroll"; - Parameters[1].EntryContext = &DevExt->Settings.CrashScroll; - Parameters[1].DefaultType = REG_DWORD; - Parameters[1].DefaultData = &DefaultCrashScroll; - Parameters[1].DefaultLength = sizeof(ULONG); - - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[2].Name = L"BreakOnSysRq"; - Parameters[2].EntryContext = &DevExt->Settings.CrashSysRq; - Parameters[2].DefaultType = REG_DWORD; - Parameters[2].DefaultData = &DefaultCrashSysRq; - Parameters[2].DefaultLength = sizeof(ULONG); - - Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[3].Name = L"ReportResetErrors"; - Parameters[3].EntryContext = &DevExt->Settings.ReportResetErrors; - Parameters[3].DefaultType = REG_DWORD; - Parameters[3].DefaultData = &DefaultReportResetErrors; - Parameters[3].DefaultLength = sizeof(ULONG); - - Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[4].Name = L"PollStatusIterations"; - Parameters[4].EntryContext = &DevExt->Settings.PollStatusIterations; - Parameters[4].DefaultType = REG_DWORD; - Parameters[4].DefaultData = &DefaultPollStatusIterations; - Parameters[4].DefaultLength = sizeof(ULONG); - - Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[5].Name = L"ResendIterations"; - Parameters[5].EntryContext = &DevExt->Settings.ResendIterations; - Parameters[5].DefaultType = REG_DWORD; - Parameters[5].DefaultData = &DefaultResendIterations; - Parameters[5].DefaultLength = sizeof(ULONG); - - Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[6].Name = L"PollingIterations"; - Parameters[6].EntryContext = &DevExt->Settings.PollingIterations; - Parameters[6].DefaultType = REG_DWORD; - Parameters[6].DefaultData = &DefaultPollingIterations; - Parameters[6].DefaultLength = sizeof(ULONG); - - Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[7].Name = L"PollingIterationsMaximum"; - Parameters[7].EntryContext = &DevExt->Settings.PollingIterationsMaximum; - Parameters[7].DefaultType = REG_DWORD; - Parameters[7].DefaultData = &DefaultPollingIterationsMaximum; - Parameters[7].DefaultLength = sizeof(ULONG); - - Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[8].Name = L"KeyboardDataQueueSize"; - Parameters[8].EntryContext = - &DevExt->KeyboardAttributes.InputDataQueueLength; - Parameters[8].DefaultType = REG_DWORD; - Parameters[8].DefaultData = &DefaultKeyboardDataQueueSize; - Parameters[8].DefaultLength = sizeof(ULONG); - - Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[9].Name = L"OverrideKeyboardType"; - Parameters[9].EntryContext = &DevExt->Settings.OverrideKeyboardType; - Parameters[9].DefaultType = REG_DWORD; - Parameters[9].DefaultData = &DefaultOverrideKeyboardType; - Parameters[9].DefaultLength = sizeof(ULONG); - - Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[10].Name = L"OverrideKeyboardSubtype"; - Parameters[10].EntryContext = &DevExt->Settings.OverrideKeyboardSubtype; - Parameters[10].DefaultType = REG_DWORD; - Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype; - Parameters[10].DefaultLength = sizeof(ULONG); - - Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[11].Name = L"MouseDataQueueSize"; - Parameters[11].EntryContext = - &DevExt->MouseAttributes.InputDataQueueLength; - Parameters[11].DefaultType = REG_DWORD; - Parameters[11].DefaultData = &DefaultMouseDataQueueSize; - Parameters[11].DefaultLength = sizeof(ULONG); - - Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[12].Name = L"MouseResendStallTime"; - Parameters[12].EntryContext = &DevExt->Settings.MouseResendStallTime; - Parameters[12].DefaultType = REG_DWORD; - Parameters[12].DefaultData = &DefaultMouseResendStallTime; - Parameters[12].DefaultLength = sizeof(ULONG); - - Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[13].Name = L"MouseSynchIn100ns"; - Parameters[13].EntryContext = &DevExt->Settings.MouseSynchIn100ns; - Parameters[13].DefaultType = REG_DWORD; - Parameters[13].DefaultData = &DefaultMouseSynchIn100ns; - Parameters[13].DefaultLength = sizeof(ULONG); - - Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[14].Name = L"MouseResolution"; - Parameters[14].EntryContext = &DevExt->Settings.MouseResolution; - Parameters[14].DefaultType = REG_DWORD; - Parameters[14].DefaultData = &DefaultMouseResolution; - Parameters[14].DefaultLength = sizeof(ULONG); - - Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[15].Name = L"SampleRate"; - Parameters[15].EntryContext = &DevExt->MouseAttributes.SampleRate; - Parameters[15].DefaultType = REG_DWORD; - Parameters[15].DefaultData = &DefaultSampleRate; - Parameters[15].DefaultLength = sizeof(ULONG); - - Parameters[16].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[16].Name = L"NumberOfButtons"; - Parameters[16].EntryContext = &DevExt->Settings.NumberOfButtons; - Parameters[16].DefaultType = REG_DWORD; - Parameters[16].DefaultData = &DefaultNumberOfButtons; - Parameters[16].DefaultLength = sizeof(ULONG); - - Parameters[17].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[17].Name = L"EnableWheelDetection"; - Parameters[17].EntryContext = &DevExt->Settings.EnableWheelDetection; - Parameters[17].DefaultType = REG_DWORD; - Parameters[17].DefaultData = &DefaultEnableWheelDetection; - Parameters[17].DefaultLength = sizeof(ULONG); - - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, - I8042RegistryPath.Buffer, - Parameters, - NULL, - NULL); - - if (!NT_SUCCESS(Status)) { - /* Actually, the defaults are not set when the function - * fails, as would happen during setup, so you have to - * set them manually anyway... - */ - RTL_QUERY_REGISTRY_TABLE *Current = Parameters; - DPRINT1 ("Can't read registry: %x\n", Status); - while (Current->Name) { - *((PULONG)Current->EntryContext) = - *((PULONG)Current->DefaultData); - Current++; - } - DPRINT1 ("Manually set defaults\n"); - - } - - if (DevExt->Settings.MouseResolution > 3) - DevExt->Settings.MouseResolution = 3; - - DPRINT("Done reading registry\n"); -} diff --git a/reactos/drivers/input/i8042prt/keyboard.c b/reactos/drivers/input/i8042prt/keyboard.c deleted file mode 100644 index 132ef7bd1ae..00000000000 --- a/reactos/drivers/input/i8042prt/keyboard.c +++ /dev/null @@ -1,875 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/keyboard.c - * PURPOSE: Keyboard specific functions - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -/* This structure starts with the same layout as KEYBOARD_INDICATOR_TRANSLATION */ -typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION { - USHORT NumberOfIndicatorKeys; - INDICATOR_LIST IndicatorList[3]; -} LOCAL_KEYBOARD_INDICATOR_TRANSLATION, *PLOCAL_KEYBOARD_INDICATOR_TRANSLATION; - -static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = { 3, { - {0x3A, KEYBOARD_CAPS_LOCK_ON}, - {0x45, KEYBOARD_NUM_LOCK_ON}, - {0x46, KEYBOARD_SCROLL_LOCK_ON}}}; - -/* FUNCTIONS *****************************************************************/ - -#ifdef __REACTOS__ -/* Debug stuff */ -VOID NTAPI -KdpServiceDispatcher(IN ULONG Code, IN PVOID Context1, IN PVOID Context2); -#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) - -static VOID NTAPI -i8042DebugWorkItem( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - ULONG Key; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - Key = InterlockedExchange((PLONG)&DeviceExtension->DebugKey, 0); - - DPRINT("Debug key: 0x%02x\n", Key); - - if (!Key) - return; - - /* We hope kernel would understand this. If - * that's not the case, nothing would happen. - */ - KdpServiceDispatcher(TAG('R', 'o', 's', ' '), (PVOID)Key, NULL); -} -#endif - -/* - * These functions are callbacks for filter driver custom interrupt - * service routines. - */ -/*static VOID NTAPI -i8042KbdIsrWritePort( - IN PVOID Context, - IN UCHAR Value) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - - if (DeviceExtension->KeyboardHook.IsrWritePort) - { - DeviceExtension->KeyboardHook.IsrWritePort( - DeviceExtension->KeyboardHook.CallContext, - Value); - } - else - i8042IsrWritePort(Context, Value, 0); -}*/ - -static VOID NTAPI -i8042KbdQueuePacket( - IN PVOID Context) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - - if (DeviceExtension->KeyboardHook.QueueKeyboardPacket) - { - DeviceExtension->KeyboardHook.QueueKeyboardPacket( - DeviceExtension->KeyboardHook.CallContext); - return; - } - - DeviceExtension->KeyComplete = TRUE; - DeviceExtension->KeysInBuffer++; - if (DeviceExtension->KeysInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize) - { - DPRINT1("Keyboard buffer overflow\n"); - DeviceExtension->KeysInBuffer--; - } - - DPRINT("Irq completes key\n"); - KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); -} - -/* - * These functions are callbacks for filter driver custom - * initialization routines. - */ -NTSTATUS NTAPI -i8042SynchWritePortKbd( - IN PVOID Context, - IN UCHAR Value, - IN BOOLEAN WaitForAck) -{ - return i8042SynchWritePort( - (PPORT_DEVICE_EXTENSION)Context, - 0, - Value, - WaitForAck); -} - -/* - * Process the keyboard internal device requests - * returns FALSE if it doesn't understand the - * call so someone else can handle it. - */ -BOOLEAN -i8042KbdStartIo( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - BOOLEAN Result = FALSE; - - Stack = IoGetCurrentIrpStackLocation(Irp); - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_KEYBOARD_SET_INDICATORS: - { - DPRINT("IOCTL_KEYBOARD_SET_INDICATORS\n"); - - PortDeviceExtension->PacketBuffer[0] = KBD_CMD_SET_LEDS; - PortDeviceExtension->PacketBuffer[1] = 0; - if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON) - PortDeviceExtension->PacketBuffer[1] |= KBD_LED_CAPS; - - if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON) - PortDeviceExtension->PacketBuffer[1] |= KBD_LED_NUM; - - if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON) - PortDeviceExtension->PacketBuffer[1] |= KBD_LED_SCROLL; - - i8042StartPacket( - PortDeviceExtension, - &DeviceExtension->Common, - PortDeviceExtension->PacketBuffer, - 2, - Irp); - break; - } - default: - { - DPRINT("Unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - } - } - - return Result; -} - -static VOID -i8042PacketDpc( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - BOOLEAN FinishIrp = FALSE; - KIRQL Irql; - NTSTATUS Result = STATUS_INTERNAL_ERROR; /* Shouldn't happen */ - - /* If the interrupt happens before this is setup, the key - * was already in the buffer. Too bad! */ - if (!DeviceExtension->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); - - if (DeviceExtension->Packet.State == Idle - && DeviceExtension->PacketComplete) - { - FinishIrp = TRUE; - Result = DeviceExtension->PacketResult; - DeviceExtension->PacketComplete = FALSE; - } - - KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); - - if (!FinishIrp) - return; - - if (DeviceExtension->CurrentIrp) - { - DeviceExtension->CurrentIrp->IoStatus.Status = Result; - IoCompleteRequest(DeviceExtension->CurrentIrp, IO_NO_INCREMENT); - IoStartNextPacket(DeviceExtension->CurrentIrpDevice, FALSE); - DeviceExtension->CurrentIrp = NULL; - DeviceExtension->CurrentIrpDevice = NULL; - } -} - -static VOID NTAPI -i8042PowerWorkItem( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - NTSTATUS Status; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - - /* See http://blogs.msdn.com/doronh/archive/2006/09/08/746961.aspx */ - - /* Register GUID_DEVICE_SYS_BUTTON interface and report capability */ - if (DeviceExtension->NewCaps != DeviceExtension->ReportedCaps) - { - if (DeviceExtension->PowerInterfaceName.MaximumLength == 0) - { - /* We have never registred this interface ; do it */ - Status = IoRegisterDeviceInterface( - DeviceExtension->Common.Pdo, - &GUID_DEVICE_SYS_BUTTON, - NULL, - &DeviceExtension->PowerInterfaceName); - if (!NT_SUCCESS(Status)) - { - /* We can't do more yet, ignore the keypress... */ - DPRINT("IoRegisterDeviceInterface(GUID_DEVICE_SYS_BUTTON) failed with status 0x%08lx\n", - Status); - DeviceExtension->PowerInterfaceName.MaximumLength = 0; - return; - } - } - else - { - /* Disable the interface. Once activated again, capabilities would be asked again */ - Status = IoSetDeviceInterfaceState( - &DeviceExtension->PowerInterfaceName, - FALSE); - if (!NT_SUCCESS(Status)) - { - /* Ignore the key press... */ - DPRINT("Disabling interface %wZ failed with status 0x%08lx\n", - &DeviceExtension->PowerInterfaceName, Status); - return; - } - } - /* Enable the interface. This leads to receving a IOCTL_GET_SYS_BUTTON_CAPS, - * so we can report new capability */ - Status = IoSetDeviceInterfaceState( - &DeviceExtension->PowerInterfaceName, - TRUE); - if (!NT_SUCCESS(Status)) - { - /* Ignore the key press... */ - DPRINT("Enabling interface %wZ failed with status 0x%08lx\n", - &DeviceExtension->PowerInterfaceName, Status); - return; - } - } - - /* Directly complete the IOCTL_GET_SYS_BUTTON_EVENT Irp (if any) */ - if (DeviceExtension->PowerIrp) - { - PULONG pEvent = (PULONG)DeviceExtension->PowerIrp->AssociatedIrp.SystemBuffer; - - DeviceExtension->PowerIrp->IoStatus.Status = STATUS_SUCCESS; - DeviceExtension->PowerIrp->IoStatus.Information = sizeof(ULONG); - *pEvent = DeviceExtension->LastPowerKey; - - IoCompleteRequest(DeviceExtension->PowerIrp, IO_NO_INCREMENT); - DeviceExtension->PowerIrp = NULL; - } -} - -/* Return TRUE if it was a power key */ -static BOOLEAN -HandlePowerKeys( - IN PI8042_KEYBOARD_EXTENSION DeviceExtension) -{ - PKEYBOARD_INPUT_DATA InputData; - ULONG KeyPress; - - InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer - 1; - if (!(InputData->Flags & KEY_E0)) - return FALSE; - - if (InputData->Flags & KEY_BREAK) - /* We already took care of the key press */ - return TRUE; - - switch (InputData->MakeCode) - { - case 0x52: /* VK_INSERT */ - DPRINT1("FIXME: Remove debug code\n"); - case KEYBOARD_POWER_CODE: - KeyPress = SYS_BUTTON_POWER; - break; - case KEYBOARD_SLEEP_CODE: - KeyPress = SYS_BUTTON_SLEEP; - break; - - case KEYBOARD_WAKE_CODE: - KeyPress = SYS_BUTTON_WAKE; - break; - default: - return FALSE; - } - - /* Our work can only be done at passive level, so use a workitem */ - DeviceExtension->NewCaps |= KeyPress; - DeviceExtension->LastPowerKey = KeyPress; - IoQueueWorkItem( - DeviceExtension->PowerWorkItem, - &i8042PowerWorkItem, - DelayedWorkQueue, - DeviceExtension); - return TRUE; -} - -static VOID NTAPI -i8042KbdDpcRoutine( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - ULONG KeysTransferred = 0; - ULONG KeysInBufferCopy; - KIRQL Irql; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeferredContext; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - if (HandlePowerKeys(DeviceExtension)) - { - DeviceExtension->KeyComplete = FALSE; - return; - } - - i8042PacketDpc(PortDeviceExtension); - if (!DeviceExtension->KeyComplete) - return; - /* We got the interrupt as it was being enabled, too bad */ - if (!PortDeviceExtension->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - - DeviceExtension->KeyComplete = FALSE; - KeysInBufferCopy = DeviceExtension->KeysInBuffer; - - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); - -#ifdef __REACTOS__ - if (PortDeviceExtension->Settings.CrashOnCtrlScroll) - { - PKEYBOARD_INPUT_DATA InputData; - InputData = DeviceExtension->KeyboardBuffer + KeysInBufferCopy - 1; - - /* Test for TAB + key combination */ - if (InputData->MakeCode == 0x0F) - DeviceExtension->TabPressed = !(InputData->Flags & KEY_BREAK); - else if (DeviceExtension->TabPressed) - { - DeviceExtension->DebugKey = InputData->MakeCode; - DeviceExtension->TabPressed = FALSE; - - IoQueueWorkItem( - DeviceExtension->DebugWorkItem, - &i8042DebugWorkItem, - DelayedWorkQueue, - DeviceExtension); - } - } -#endif - - DPRINT("Send a key\n"); - - if (!DeviceExtension->KeyboardData.ClassService) - return; - - DPRINT("Sending %lu key(s)\n", KeysInBufferCopy); - (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->KeyboardData.ClassService)( - DeviceExtension->KeyboardData.ClassDeviceObject, - DeviceExtension->KeyboardBuffer, - DeviceExtension->KeyboardBuffer + KeysInBufferCopy, - &KeysTransferred); - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - DeviceExtension->KeysInBuffer -= KeysTransferred; - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); -} - -#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003) - -/* - * Runs the keyboard IOCTL dispatch. - */ -NTSTATUS -i8042KbdDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - PI8042_KEYBOARD_EXTENSION DeviceExtension; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - Irp->IoStatus.Information = 0; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_GET_SYS_BUTTON_CAPS: - { - /* Part of GUID_DEVICE_SYS_BUTTON interface */ - PULONG pCaps; - DPRINT("IOCTL_GET_SYS_BUTTON_CAPS\n"); - - if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) - Status = STATUS_INVALID_PARAMETER; - else - { - pCaps = (PULONG)Irp->AssociatedIrp.SystemBuffer; - *pCaps = DeviceExtension->NewCaps; - DeviceExtension->ReportedCaps = DeviceExtension->NewCaps; - Irp->IoStatus.Information = sizeof(ULONG); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_GET_SYS_BUTTON_EVENT: - { - /* Part of GUID_DEVICE_SYS_BUTTON interface */ - PIRP WaitingIrp; - DPRINT("IOCTL_GET_SYS_BUTTON_EVENT\n"); - - if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) - Status = STATUS_INVALID_PARAMETER; - else - { - /* FIXME: Race condition here: - * If an interrupt comes before we can mark the Irp - * as pending, it might be possible to complete the - * Irp before pending it, leading to a crash! */ - WaitingIrp = InterlockedCompareExchangePointer( - &DeviceExtension->PowerIrp, - Irp, - NULL); - /* Check if an Irp is already pending */ - if (WaitingIrp != NULL) - { - /* Unable to have a 2nd pending IRP for this IOCTL */ - DPRINT("Unable to pend a second IRP for IOCTL_GET_SYS_BUTTON_EVENT\n"); - Status = STATUS_INVALID_PARAMETER; - } - else - { - Status = STATUS_PENDING; - } - } - break; - } - default: - { - DPRINT("IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - Irp->IoStatus.Status = Status; - if (Status == STATUS_PENDING) - IoMarkIrpPending(Irp); - else - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - /* Special case for IOCTL_GET_SYS_BUTTON_CAPS */ - if (Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_SYS_BUTTON_CAPS - && DeviceExtension->PowerIrp) - { - /* Also complete the pending IOCTL_GET_SYS_BUTTON_EVENT Irp */ - PULONG pEvent = (PULONG)DeviceExtension->PowerIrp->AssociatedIrp.SystemBuffer; - - DeviceExtension->PowerIrp->IoStatus.Status = STATUS_SUCCESS; - DeviceExtension->PowerIrp->IoStatus.Information = sizeof(ULONG); - *pEvent = DeviceExtension->LastPowerKey; - DeviceExtension->LastPowerKey = 0; - - IoCompleteRequest(DeviceExtension->PowerIrp, IO_NO_INCREMENT); - DeviceExtension->PowerIrp = NULL; - } - return Status; -} - -/* - * Runs the keyboard IOCTL_INTERNAL dispatch. - */ -NTSTATUS -i8042KbdInternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - PI8042_KEYBOARD_EXTENSION DeviceExtension; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - Irp->IoStatus.Information = 0; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_INTERNAL_KEYBOARD_CONNECT: - { - SIZE_T Size; - PIO_WORKITEM WorkItem = NULL; - PI8042_HOOK_WORKITEM WorkItemData = NULL; - - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); - if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA)) - { - Status = STATUS_INVALID_PARAMETER; - goto cleanup; - } - - DeviceExtension->KeyboardData = - *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); - - /* Send IOCTL_INTERNAL_I8042_HOOK_KEYBOARD to device stack */ - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - DPRINT("IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - WorkItemData = ExAllocatePool( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM)); - if (!WorkItemData) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Irp = Irp; - - /* Initialize extension */ - DeviceExtension->Common.Type = Keyboard; - Size = DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA); - DeviceExtension->KeyboardBuffer = ExAllocatePool( - NonPagedPool, - Size); - if (!DeviceExtension->KeyboardBuffer) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - RtlZeroMemory(DeviceExtension->KeyboardBuffer, Size); - KeInitializeDpc( - &DeviceExtension->DpcKeyboard, - i8042KbdDpcRoutine, - DeviceExtension); - DeviceExtension->PowerWorkItem = IoAllocateWorkItem(DeviceObject); - if (!DeviceExtension->PowerWorkItem) - { - DPRINT("IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - DeviceExtension->DebugWorkItem = IoAllocateWorkItem(DeviceObject); - if (!DeviceExtension->DebugWorkItem) - { - DPRINT("IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - DeviceExtension->Common.PortDeviceExtension->KeyboardExtension = DeviceExtension; - DeviceExtension->Common.PortDeviceExtension->Flags |= KEYBOARD_CONNECTED; - - IoMarkIrpPending(Irp); - IoQueueWorkItem(WorkItem, - i8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - Status = STATUS_PENDING; - break; - -cleanup: - if (DeviceExtension->KeyboardBuffer) - ExFreePool(DeviceExtension->KeyboardBuffer); - if (DeviceExtension->PowerWorkItem) - IoFreeWorkItem(DeviceExtension->PowerWorkItem); - if (DeviceExtension->DebugWorkItem) - IoFreeWorkItem(DeviceExtension->DebugWorkItem); - if (WorkItem) - IoFreeWorkItem(WorkItem); - if (WorkItemData) - ExFreePool(WorkItemData); - break; - } - case IOCTL_INTERNAL_KEYBOARD_DISCONNECT: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_DISCONNECT\n"); - /* MSDN says that operation is to implemented. - * To implement it, we just have to do: - * DeviceExtension->KeyboardData.ClassService = NULL; - */ - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_KEYBOARD\n"); - /* Nothing to do here */ - Status = STATUS_SUCCESS; - break; - } - case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n"); - - /* We should check the UnitID, but it's kind of pointless as - * all keyboards are supposed to have the same one - */ - if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) - { - Status = STATUS_BUFFER_TOO_SMALL; - } - else - { - RtlCopyMemory( - Irp->AssociatedIrp.SystemBuffer, - &IndicatorTranslation, - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)); - Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_KEYBOARD_QUERY_INDICATORS: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATORS\n"); - - if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) - { - Status = STATUS_BUFFER_TOO_SMALL; - } - else - { - RtlCopyMemory( - Irp->AssociatedIrp.SystemBuffer, - &DeviceExtension->KeyboardIndicators, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_KEYBOARD_SET_INDICATORS: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_SET_INDICATORS\n"); - - if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) - { - Status = STATUS_BUFFER_TOO_SMALL; - } - else - { - RtlCopyMemory( - &DeviceExtension->KeyboardIndicators, - Irp->AssociatedIrp.SystemBuffer, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - Status = STATUS_PENDING; - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - } - break; - } - default: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - Irp->IoStatus.Status = Status; - if (Status != STATUS_PENDING) - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; -} - -/* - * Call the customization hook. The ToReturn parameter is about wether - * we should go on with the interrupt. The return value is what - * we should return (indicating to the system wether someone else - * should try to handle the interrupt) - */ -static BOOLEAN -i8042KbdCallIsrHook( - IN PI8042_KEYBOARD_EXTENSION DeviceExtension, - IN UCHAR Status, - IN UCHAR Input, - OUT PBOOLEAN ToReturn) -{ - BOOLEAN HookReturn, HookContinue; - - HookContinue = FALSE; - - if (DeviceExtension->KeyboardHook.IsrRoutine) - { - HookReturn = DeviceExtension->KeyboardHook.IsrRoutine( - DeviceExtension->KeyboardHook.Context, - DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer, - &DeviceExtension->Common.PortDeviceExtension->Packet, - Status, - &Input, - &HookContinue, - &DeviceExtension->KeyboardScanState); - - if (!HookContinue) - { - *ToReturn = HookReturn; - return TRUE; - } - } - return FALSE; -} - -BOOLEAN NTAPI -i8042KbdInterruptService( - IN PKINTERRUPT Interrupt, - PVOID Context) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - PKEYBOARD_INPUT_DATA InputData; - ULONG Counter; - UCHAR PortStatus, Output; - BOOLEAN ToReturn = FALSE; - NTSTATUS Status; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer; - Counter = PortDeviceExtension->Settings.PollStatusIterations; - - while (Counter) - { - Status = i8042ReadStatus(PortDeviceExtension, &PortStatus); - if (!NT_SUCCESS(Status)) - { - DPRINT("i8042ReadStatus() failed with status 0x%08lx\n", Status); - return FALSE; - } - Status = i8042ReadKeyboardData(PortDeviceExtension, &Output); - if (NT_SUCCESS(Status)) - break; - KeStallExecutionProcessor(1); - Counter--; - } - if (Counter == 0) - { - DPRINT("Spurious i8042 keyboard interrupt\n"); - return FALSE; - } - - DPRINT("Got: 0x%02x\n", Output); - - if (PortDeviceExtension->Settings.CrashOnCtrlScroll) - { - /* Test for CTRL + SCROLL LOCK twice */ - static UCHAR ScanCodes[] = { 0x1d, 0x46, 0x46, 0 }; - - if (!(Output & 0x80)) - { - if ((Output & 0x7f) == ScanCodes[DeviceExtension->ComboPosition]) - { - DeviceExtension->ComboPosition++; - if (ScanCodes[DeviceExtension->ComboPosition] == 0) - KeBugCheck(MANUALLY_INITIATED_CRASH); - } - else if ((Output & 0x7f) == ScanCodes[0]) - DeviceExtension->ComboPosition = 1; - else - DeviceExtension->ComboPosition = 0; - } - } - - if (i8042KbdCallIsrHook(DeviceExtension, PortStatus, Output, &ToReturn)) - return ToReturn; - - if (i8042PacketIsr(PortDeviceExtension, Output)) - { - if (PortDeviceExtension->PacketComplete) - { - DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); - } - DPRINT("Irq eaten by packet\n"); - return TRUE; - } - - DPRINT("Irq is keyboard input\n"); - - if (DeviceExtension->KeyboardScanState == Normal) - { - switch (Output) - { - case 0xe0: - DeviceExtension->KeyboardScanState = GotE0; - return TRUE; - case 0xe1: - DeviceExtension->KeyboardScanState = GotE1; - return TRUE; - default: - break; - } - } - - /* Update InputData */ - InputData->Flags = 0; - switch (DeviceExtension->KeyboardScanState) - { - case GotE0: - InputData->Flags |= KEY_E0; - break; - case GotE1: - InputData->Flags |= KEY_E1; - break; - default: - break; - } - DeviceExtension->KeyboardScanState = Normal; - if (Output & 0x80) - InputData->Flags |= KEY_BREAK; - else - InputData->Flags |= KEY_MAKE; - InputData->MakeCode = Output & 0x7f; - InputData->Reserved = 0; - - i8042KbdQueuePacket(DeviceExtension); - - return TRUE; -} diff --git a/reactos/drivers/input/i8042prt/misc.c b/reactos/drivers/input/i8042prt/misc.c deleted file mode 100644 index 82200c72d02..00000000000 --- a/reactos/drivers/input/i8042prt/misc.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/misc.c - * PURPOSE: Misceallenous operations - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -static NTSTATUS NTAPI -ForwardIrpAndWaitCompletion( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context) -{ - if (Irp->PendingReturned) - KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); - return STATUS_MORE_PROCESSING_REQUIRED; -} - -NTSTATUS -ForwardIrpAndWait( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; - KEVENT Event; - NTSTATUS Status; - - ASSERT(LowerDevice); - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - IoCopyCurrentIrpStackLocationToNext(Irp); - - DPRINT("Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName); - IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE); - - Status = IoCallDriver(LowerDevice, Irp); - if (Status == STATUS_PENDING) - { - Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); - if (NT_SUCCESS(Status)) - Status = Irp->IoStatus.Status; - } - - return Status; -} - -NTSTATUS NTAPI -ForwardIrpAndForget( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; - - ASSERT(LowerDevice); - - IoSkipCurrentIrpStackLocation(Irp); - return IoCallDriver(LowerDevice, Irp); -} diff --git a/reactos/drivers/input/i8042prt/mouse.c b/reactos/drivers/input/i8042prt/mouse.c deleted file mode 100644 index 1d7d65070d1..00000000000 --- a/reactos/drivers/input/i8042prt/mouse.c +++ /dev/null @@ -1,1070 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/mouse.c - * PURPOSE: Mouse specific functions - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/* - * These functions are callbacks for filter driver custom interrupt - * service routines. - */ -static VOID NTAPI -i8042MouIsrWritePort( - IN PVOID Context, - IN UCHAR Value) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; - - if (DeviceExtension->MouseHook.IsrWritePort) - { - DeviceExtension->MouseHook.IsrWritePort( - DeviceExtension->MouseHook.CallContext, - Value); - } - else - i8042IsrWritePort(Context, Value, 0xD4); -} - -VOID NTAPI -i8042MouQueuePacket( - IN PVOID Context) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; - - if (DeviceExtension->MouseHook.QueueMousePacket) - { - DeviceExtension->MouseHook.QueueMousePacket( - DeviceExtension->MouseHook.CallContext); - return; - } - - DeviceExtension->MouseComplete = TRUE; - DeviceExtension->MouseInBuffer++; - if (DeviceExtension->MouseInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize) - { - DPRINT1("Mouse buffer overflow\n"); - DeviceExtension->MouseInBuffer--; - } - - DPRINT("Irq completes mouse packet\n"); - KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL); -} - -VOID -i8042MouHandle( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Output) -{ - PMOUSE_INPUT_DATA MouseInput; - CHAR Scroll; - - MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; - - switch (DeviceExtension->MouseState) - { - case MouseIdle: - /* This bit should be 1, if not drop the packet, we - * might be lucky and get in sync again - */ - if (!(Output & 8)) { - DPRINT1("Bad input, dropping..\n"); - return; - } - - MouseInput->Buttons = 0; - MouseInput->RawButtons = 0; - MouseInput->Flags = MOUSE_MOVE_RELATIVE; - - /* Note how we ignore the overflow bits, like Windows - * is said to do. There's no reasonable thing to do - * anyway. - */ - - if (Output & 16) - MouseInput->LastX = 1; - else - MouseInput->LastX = 0; - if (Output & 32) - MouseInput->LastY = 1; - else - MouseInput->LastY = 0; - - if (Output & 1) - MouseInput->RawButtons |= MOUSE_LEFT_BUTTON_DOWN; - if (Output & 2) - MouseInput->RawButtons |= MOUSE_RIGHT_BUTTON_DOWN; - if (Output & 4) - MouseInput->RawButtons |= MOUSE_MIDDLE_BUTTON_DOWN; - - DeviceExtension->MouseState = XMovement; - break; - - case XMovement: - if (MouseInput->LastX) - MouseInput->LastX = (LONG) Output - 256; - else - MouseInput->LastX = Output; - - DeviceExtension->MouseState = YMovement; - break; - - case YMovement: - if (MouseInput->LastY) - MouseInput->LastY = (LONG)Output - 256; - else - MouseInput->LastY = (LONG)Output; - - /* Windows wants it the other way around */ - MouseInput->LastY = -MouseInput->LastY; - - if (DeviceExtension->MouseType == GenericPS2 || - DeviceExtension->MouseType == Ps2pp) - { - i8042MouHandleButtons( - DeviceExtension, - MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN); - i8042MouQueuePacket(DeviceExtension); - DeviceExtension->MouseState = MouseIdle; - } - else - { - DeviceExtension->MouseState = ZMovement; - } - break; - - case ZMovement: - Scroll = Output & 0x0f; - if (Scroll & 8) - Scroll |= 0xf0; - - if (Scroll) - { - MouseInput->RawButtons |= MOUSE_WHEEL; - MouseInput->ButtonData = (USHORT)(Scroll * -WHEEL_DELTA); - } - - if (DeviceExtension->MouseType == IntellimouseExplorer) - { - if (Output & 16) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - if (Output & 32) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - } - i8042MouHandleButtons( - DeviceExtension, - MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN | - MOUSE_BUTTON_4_DOWN | - MOUSE_BUTTON_5_DOWN); - i8042MouQueuePacket(DeviceExtension); - DeviceExtension->MouseState = MouseIdle; - break; - - default: - DPRINT1("Unexpected state 0x%u!\n", DeviceExtension->MouseState); - ASSERT(FALSE); - } -} - -/* - * Updates ButtonFlags according to RawButtons and a saved state; - * Only takes in account the bits that are set in Mask - */ -VOID -i8042MouHandleButtons( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN USHORT Mask) -{ - PMOUSE_INPUT_DATA MouseInput; - USHORT NewButtonData; - USHORT ButtonDiff; - - MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; - NewButtonData = (USHORT)(MouseInput->RawButtons & Mask); - ButtonDiff = (NewButtonData ^ DeviceExtension->MouseButtonState) & Mask; - - /* Note that the defines are such: - * MOUSE_LEFT_BUTTON_DOWN 1 - * MOUSE_LEFT_BUTTON_UP 2 - */ - MouseInput->ButtonFlags |= (NewButtonData & ButtonDiff) | - (((~(NewButtonData)) << 1) & (ButtonDiff << 1)) | - (MouseInput->RawButtons & 0xfc00); - - DPRINT("Left raw/up/down: %u/%u/%u\n", - MouseInput->RawButtons & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_UP); - - DeviceExtension->MouseButtonState = - (DeviceExtension->MouseButtonState & ~Mask) | (NewButtonData & Mask); -} - -static NTSTATUS OldInitialization(PPORT_DEVICE_EXTENSION); /* FIXME */ - -/* Does lastest initializations for the mouse. This method - * is called just before connecting the interrupt. - */ -NTSTATUS -i8042MouInitialize( - IN PI8042_MOUSE_EXTENSION DeviceExtension) -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - -/* FIXME */ OldInitialization(PortDeviceExtension); - - return STATUS_SUCCESS; -} - -static VOID NTAPI -i8042MouDpcRoutine( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - ULONG MouseTransferred = 0; - ULONG MouseInBufferCopy; - KIRQL Irql; - LARGE_INTEGER Timeout; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)DeferredContext; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - switch (DeviceExtension->MouseTimeoutState) - { - case TimeoutStart: - { - DeviceExtension->MouseTimeoutState = NoChange; - if (DeviceExtension->MouseTimeoutActive && - !KeCancelTimer(&DeviceExtension->TimerMouseTimeout)) - { - /* The timer fired already, give up */ - DeviceExtension->MouseTimeoutActive = FALSE; - return; - } - - Timeout.QuadPart = -15000000; /* 1.5 seconds, should be enough */ - - KeSetTimer( - &DeviceExtension->TimerMouseTimeout, - Timeout, - &DeviceExtension->DpcMouseTimeout); - DeviceExtension->MouseTimeoutActive = TRUE; - return; - } - - case TimeoutCancel: - { - DeviceExtension->MouseTimeoutState = NoChange; - KeCancelTimer(&DeviceExtension->TimerMouseTimeout); - DeviceExtension->MouseTimeoutActive = FALSE; - } - - default: - ;/* nothing, don't want a warning */ - } - - /* Should be unlikely */ - if (!DeviceExtension->MouseComplete) - return; - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - - DeviceExtension->MouseComplete = FALSE; - MouseInBufferCopy = DeviceExtension->MouseInBuffer; - - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); - - DPRINT("Send a mouse packet\n"); - - if (!DeviceExtension->MouseData.ClassService) - return; - - DPRINT("Sending %lu mouse move(s)\n", MouseInBufferCopy); - (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->MouseData.ClassService)( - DeviceExtension->MouseData.ClassDeviceObject, - DeviceExtension->MouseBuffer, - DeviceExtension->MouseBuffer + MouseInBufferCopy, - &MouseTransferred); - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - DeviceExtension->MouseInBuffer -= MouseTransferred; - if (DeviceExtension->MouseInBuffer) - RtlMoveMemory( - DeviceExtension->MouseBuffer, - DeviceExtension->MouseBuffer + MouseTransferred, - DeviceExtension->MouseInBuffer * sizeof(MOUSE_INPUT_DATA)); - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); -} - -/* This timer DPC will be called when the mouse reset times out. - * I'll just send the 'disable mouse port' command to the controller - * and say the mouse doesn't exist. - */ -static VOID NTAPI -i8042DpcRoutineMouseTimeout( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - KIRQL Irql; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)DeferredContext; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - - DPRINT1("Mouse initialization timeout! (substate %x). Disabling mouse.\n", - DeviceExtension->MouseResetState); - - i8042Flush(PortDeviceExtension); - i8042ChangeMode(PortDeviceExtension, CCB_MOUSE_INT_ENAB, CCB_MOUSE_DISAB); - i8042Flush(PortDeviceExtension); - - PortDeviceExtension->Flags &= ~MOUSE_PRESENT; - - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); -} - -/* - * Runs the mouse IOCTL_INTERNAL dispatch. - */ -NTSTATUS -i8042MouInternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - PI8042_MOUSE_EXTENSION DeviceExtension; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - Irp->IoStatus.Information = 0; - DeviceExtension = (PI8042_MOUSE_EXTENSION)DeviceObject->DeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_INTERNAL_MOUSE_CONNECT: - { - SIZE_T Size; - PIO_WORKITEM WorkItem = NULL; - PI8042_HOOK_WORKITEM WorkItemData = NULL; - - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_CONNECT\n"); - if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA)) - { - Status = STATUS_INVALID_PARAMETER; - goto cleanup; - } - - DeviceExtension->MouseData = - *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); - - /* Send IOCTL_INTERNAL_I8042_HOOK_MOUSE to device stack */ - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - DPRINT("IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - WorkItemData = ExAllocatePool( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM)); - if (!WorkItemData) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Irp = Irp; - - /* Initialize extension */ - DeviceExtension->Common.Type = Mouse; - Size = DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize * sizeof(MOUSE_INPUT_DATA); - DeviceExtension->MouseBuffer = ExAllocatePool( - NonPagedPool, - Size); - if (!DeviceExtension->MouseBuffer) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - RtlZeroMemory(DeviceExtension->MouseBuffer, Size); - DeviceExtension->MouseAttributes.InputDataQueueLength = - DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize; - KeInitializeDpc( - &DeviceExtension->DpcMouse, - i8042MouDpcRoutine, - DeviceExtension); - KeInitializeDpc( - &DeviceExtension->DpcMouseTimeout, - i8042DpcRoutineMouseTimeout, - DeviceExtension); - KeInitializeTimer(&DeviceExtension->TimerMouseTimeout); - DeviceExtension->Common.PortDeviceExtension->MouseExtension = DeviceExtension; - DeviceExtension->Common.PortDeviceExtension->Flags |= MOUSE_CONNECTED; - - IoMarkIrpPending(Irp); - IoQueueWorkItem(WorkItem, - i8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - Status = STATUS_PENDING; - break; - -cleanup: - if (DeviceExtension->MouseBuffer) - ExFreePool(DeviceExtension->MouseBuffer); - if (WorkItem) - IoFreeWorkItem(WorkItem); - if (WorkItemData) - ExFreePool(WorkItemData); - break; - } - case IOCTL_INTERNAL_MOUSE_DISCONNECT: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_DISCONNECT\n"); - /* MSDN says that operation is to implemented. - * To implement it, we just have to do: - * DeviceExtension->MouseData.ClassService = NULL; - */ - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_INTERNAL_I8042_HOOK_MOUSE: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_MOUSE\n"); - /* Nothing to do here */ - Status = STATUS_SUCCESS; - break; - } - default: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - Irp->IoStatus.Status = Status; - if (Status != STATUS_PENDING) - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; -} - -/* Test if packets are taking too long to come in. If they do, we - * might have gotten out of sync and should just drop what we have. - * - * If we want to be totally right, we'd also have to keep a count of - * errors, and totally reset the mouse after too much of them (can - * happen if the user is using a KVM switch and an OS on another port - * resets the mouse, or if the user hotplugs the mouse, or if we're just - * generally unlucky). Also note the input parsing routine where we - * drop invalid input packets. - */ -static VOID -i8042MouInputTestTimeout( - IN PI8042_MOUSE_EXTENSION DeviceExtension) -{ - ULARGE_INTEGER Now; - - if (DeviceExtension->MouseState == MouseExpectingACK || - DeviceExtension->MouseState == MouseResetting) - return; - - Now.QuadPart = KeQueryInterruptTime(); - - if (DeviceExtension->MouseState != MouseIdle) { - /* Check if the last byte came too long ago */ - if (Now.QuadPart - DeviceExtension->MousePacketStartTime.QuadPart > - DeviceExtension->Common.PortDeviceExtension->Settings.MouseSynchIn100ns) - { - DPRINT("Mouse input packet timeout\n"); - DeviceExtension->MouseState = MouseIdle; - } - } - - if (DeviceExtension->MouseState == MouseIdle) - DeviceExtension->MousePacketStartTime.QuadPart = Now.QuadPart; -} - -/* - * Call the customization hook. The ToReturn parameter is about wether - * we should go on with the interrupt. The return value is what - * we should return (indicating to the system wether someone else - * should try to handle the interrupt) - */ -static BOOLEAN -i8042MouCallIsrHook( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Status, - IN UCHAR Input, - OUT PBOOLEAN ToReturn) -{ - BOOLEAN HookReturn, HookContinue; - - HookContinue = FALSE; - - if (DeviceExtension->MouseHook.IsrRoutine) - { - DPRINT1("IsrRoutine(%p %p %p 0x%x 0x%x %p %lu %lu)\n", - DeviceExtension->MouseHook.Context, DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer, - &DeviceExtension->Common.PortDeviceExtension->Packet, Status, &Input, &HookContinue, - DeviceExtension->MouseState, DeviceExtension->MouseResetState); - HookReturn = DeviceExtension->MouseHook.IsrRoutine( - DeviceExtension->MouseHook.Context, - DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer, - &DeviceExtension->Common.PortDeviceExtension->Packet, - Status, - &Input, - &HookContinue, - &DeviceExtension->MouseState, - &DeviceExtension->MouseResetState); - DPRINT1("IsrRoutine(%p %p %p 0x%x 0x%x %p %lu %lu)\n", - DeviceExtension->MouseHook.Context, DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer, - &DeviceExtension->Common.PortDeviceExtension->Packet, Status, &Input, &HookContinue, - DeviceExtension->MouseState, DeviceExtension->MouseResetState); - - if (!HookContinue) - { - *ToReturn = HookReturn; - return TRUE; - } - } - return FALSE; -} - -static BOOLEAN -i8042MouResetIsr( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Status, - IN UCHAR Value) -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - BOOLEAN ToReturn = FALSE; - - if (i8042MouCallIsrHook(DeviceExtension, Status, Value, &ToReturn)) - return ToReturn; - - if (MouseResetting != DeviceExtension->MouseState) - return FALSE; - DeviceExtension->MouseTimeoutState = TimeoutStart; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - switch (DeviceExtension->MouseResetState) - { - case 1100: /* the first ack, drop it. */ - DeviceExtension->MouseResetState = ExpectingReset; - return TRUE; - case ExpectingReset: - /* First, 0xFF is sent. The mouse is supposed to say AA00 if ok, FC00 if not. */ - if (0xAA == Value) - { - DeviceExtension->MouseResetState++; - } - else - { - PortDeviceExtension->Flags &= ~MOUSE_PRESENT; - DeviceExtension->MouseState = MouseIdle; - DPRINT("Mouse returned bad reset reply: %x (expected aa)\n", Value); - } - return TRUE; - case ExpectingResetId: - if (0x00 == Value) - { - DeviceExtension->MouseResetState++; - DeviceExtension->MouseType = GenericPS2; - i8042MouIsrWritePort(PortDeviceExtension, 0xF2); - } - else - { - PortDeviceExtension->Flags &= ~MOUSE_PRESENT; - DeviceExtension->MouseState = MouseIdle; - DPRINT1("Mouse returned bad reset reply part two: %x (expected 0)\n", Value); - } - return TRUE; - case ExpectingGetDeviceIdACK: - if (MOUSE_ACK == Value) - { - DeviceExtension->MouseResetState++; - } - else if (MOUSE_NACK == Value || MOUSE_ERROR == Value) - { - DeviceExtension->MouseResetState++; - /* Act as if 00 (normal mouse) was received */ - DPRINT("Mouse doesn't support 0xd2, (returns %x, expected %x), faking\n", Value, MOUSE_ACK); - i8042MouResetIsr(DeviceExtension, Status, 0); - } - return TRUE; - case ExpectingGetDeviceIdValue: - switch (Value) - { - case 0x02: - DeviceExtension->MouseAttributes.MouseIdentifier = - BALLPOINT_I8042_HARDWARE; - break; - case 0x03: - case 0x04: - DeviceExtension->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - break; - default: - DeviceExtension->MouseAttributes.MouseIdentifier = - MOUSE_I8042_HARDWARE; - } - DeviceExtension->MouseResetState++; - i8042MouIsrWritePort(PortDeviceExtension, 0xE8); - return TRUE; - case ExpectingSetResolutionDefaultACK: - DeviceExtension->MouseResetState++; - i8042MouIsrWritePort(PortDeviceExtension, 0x00); - return TRUE; - case ExpectingSetResolutionDefaultValueACK: - DeviceExtension->MouseResetState = ExpectingSetScaling1to1ACK; - i8042MouIsrWritePort(PortDeviceExtension, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK: - case ExpectingSetScaling1to1ACK2: - DeviceExtension->MouseResetState++; - i8042MouIsrWritePort(PortDeviceExtension, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK3: - DeviceExtension->MouseResetState++; - i8042MouIsrWritePort(PortDeviceExtension, 0xE9); - return TRUE; - case ExpectingReadMouseStatusACK: - DeviceExtension->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte1: - DeviceExtension->MouseLogiBuffer[0] = Value; - DeviceExtension->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte2: - DeviceExtension->MouseLogiBuffer[1] = Value; - DeviceExtension->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte3: - DeviceExtension->MouseLogiBuffer[2] = Value; - /* Now MouseLogiBuffer is a set of info. If the second - * byte is 0, the mouse didn't understand the magic - * code. Otherwise, it it a Logitech and the second byte - * is the number of buttons, bit 7 of the first byte tells - * if it understands special E7 commands, the rest is an ID. - */ - if (DeviceExtension->MouseLogiBuffer[1]) - { - DeviceExtension->MouseAttributes.NumberOfButtons = - DeviceExtension->MouseLogiBuffer[1]; - DeviceExtension->MouseType = Ps2pp; - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK; - /* TODO: Go through EnableWheel and Enable5Buttons */ - return TRUE; - } - DeviceExtension->MouseResetState = EnableWheel; - i8042MouResetIsr(DeviceExtension, Status, Value); - return TRUE; - case EnableWheel: - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = 1001; - return TRUE; - case 1001: - i8042MouIsrWritePort(PortDeviceExtension, 0xC8); - DeviceExtension->MouseResetState++; - return TRUE; - case 1002: - case 1004: - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState++; - return TRUE; - case 1003: - i8042MouIsrWritePort(PortDeviceExtension, 0x64); - DeviceExtension->MouseResetState++; - return TRUE; - case 1005: - i8042MouIsrWritePort(PortDeviceExtension, 0x50); - DeviceExtension->MouseResetState++; - return TRUE; - case 1006: - i8042MouIsrWritePort(PortDeviceExtension, 0xF2); - DeviceExtension->MouseResetState++; - return TRUE; - case 1007: - /* Ignore ACK */ - DeviceExtension->MouseResetState++; - return TRUE; - case 1008: - if (0x03 == Value) { - /* It's either an Intellimouse or Intellimouse Explorer. */ - DeviceExtension->MouseAttributes.NumberOfButtons = 3; - DeviceExtension->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DeviceExtension->MouseType = Intellimouse; - DeviceExtension->MouseResetState = Enable5Buttons; - i8042MouResetIsr(DeviceExtension, Status, Value); - } - else - { - /* Just set the default settings and be done */ - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK; - } - return TRUE; - case Enable5Buttons: - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = 1021; - return TRUE; - case 1022: - case 1024: - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState++; - return TRUE; - case 1021: - case 1023: - i8042MouIsrWritePort(PortDeviceExtension, 0xC8); - DeviceExtension->MouseResetState++; - return TRUE; - case 1025: - i8042MouIsrWritePort(PortDeviceExtension, 0x50); - DeviceExtension->MouseResetState++; - return TRUE; - case 1026: - i8042MouIsrWritePort(PortDeviceExtension, 0xF2); - DeviceExtension->MouseResetState++; - return TRUE; - case 1027: - if (0x04 == Value) - { - DeviceExtension->MouseAttributes.NumberOfButtons = 5; - DeviceExtension->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DeviceExtension->MouseType = IntellimouseExplorer; - } - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - case ExpectingSetSamplingRateACK: - i8042MouIsrWritePort(PortDeviceExtension, - (UCHAR)DeviceExtension->MouseAttributes.SampleRate); - DeviceExtension->MouseResetState++; - return TRUE; - case ExpectingSetSamplingRateValueACK: - if (MOUSE_NACK == Value) - { - i8042MouIsrWritePort(PortDeviceExtension, 0x3C); - DeviceExtension->MouseAttributes.SampleRate = PortDeviceExtension->Settings.SampleRate; - DeviceExtension->MouseResetState = 1040; - return TRUE; - } - case 1040: /* Fallthrough */ - i8042MouIsrWritePort(PortDeviceExtension, 0xE8); - DeviceExtension->MouseResetState = ExpectingFinalResolutionACK; - return TRUE; - case ExpectingFinalResolutionACK: - i8042MouIsrWritePort(PortDeviceExtension, - (UCHAR)(PortDeviceExtension->Settings.MouseResolution & 0xff)); - DPRINT("Mouse resolution %lu\n", - PortDeviceExtension->Settings.MouseResolution); - DeviceExtension->MouseResetState = ExpectingFinalResolutionValueACK; - return TRUE; - case ExpectingFinalResolutionValueACK: - i8042MouIsrWritePort(PortDeviceExtension, 0xF4); - DeviceExtension->MouseResetState = ExpectingEnableACK; - return TRUE; - case ExpectingEnableACK: - DeviceExtension->MouseState = MouseIdle; - DeviceExtension->MouseTimeoutState = TimeoutCancel; - DPRINT("Mouse type = %u\n", DeviceExtension->MouseType); - return TRUE; - default: - if (DeviceExtension->MouseResetState < 100 || DeviceExtension->MouseResetState > 999) - DPRINT1("MouseResetState went out of range: %lu\n", DeviceExtension->MouseResetState); - return FALSE; - } -} - -BOOLEAN NTAPI -i8042MouInterruptService( - IN PKINTERRUPT Interrupt, - PVOID Context) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - ULONG Counter; - UCHAR Output, PortStatus; - NTSTATUS Status; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - Counter = PortDeviceExtension->Settings.PollStatusIterations; - - while (Counter) - { - Status = i8042ReadStatus(PortDeviceExtension, &PortStatus); - if (!NT_SUCCESS(Status)) - { - DPRINT("i8042ReadStatus() failed with status 0x%08lx\n", Status); - return FALSE; - } - Status = i8042ReadMouseData(PortDeviceExtension, &Output); - if (NT_SUCCESS(Status)) - break; - KeStallExecutionProcessor(1); - Counter--; - } - if (Counter == 0) - { - DPRINT("Spurious i8042 mouse interrupt\n"); - return FALSE; - } - - DPRINT("Got: 0x%02x\n", Output); - - if (i8042PacketIsr(PortDeviceExtension, Output)) - { - if (PortDeviceExtension->PacketComplete) - { - DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL); - } - DPRINT("Irq eaten by packet\n"); - return TRUE; - } - - DPRINT("Irq is mouse input\n"); - - i8042MouInputTestTimeout(DeviceExtension); - - if (i8042MouResetIsr(DeviceExtension, PortStatus, Output)) - { - DPRINT("Handled by ResetIsr or hooked Isr\n"); - if (NoChange != DeviceExtension->MouseTimeoutState) { - KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL); - } - return TRUE; - } - - if (DeviceExtension->MouseType == Ps2pp) - i8042MouHandlePs2pp(DeviceExtension, Output); - else - i8042MouHandle(DeviceExtension, Output); - - return TRUE; -} - -/* ================================================ - * FIXME: this part is taken from psaux.sys driver, - * and doesn't follow the coding style of this file - * ===============================================*/ - -#define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8 -#define PSMOUSE_CMD_ENABLE 0x00f4 -#define PSMOUSE_CMD_GETID (0x0200 | MOU_CMD_GET_ID) -#define PSMOUSE_CMD_RESET_BAT (0x0200 | MOU_CMD_RESET) -#define PSMOUSE_RET_ACK MOUSE_ACK -#define PSMOUSE_RET_NAK MOUSE_NACK -#define MOUSE_INTERRUPTS_ON (CCB_TRANSLATE | \ - CCB_SYSTEM_FLAG | \ - CCB_MOUSE_INT_ENAB) - -typedef struct _I8042_MOUSE_EXTENSION_OLD -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - UCHAR pkt[8]; - UCHAR ack; - UINT RepliesExpected; -} I8042_MOUSE_EXTENSION_OLD, *PI8042_MOUSE_EXTENSION_OLD; - -/* Sends a byte to the mouse */ -static INT SendByte( - IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension, - IN UCHAR byte) -{ - INT timeout = 100; /* 100 msec */ - UCHAR scancode; - LARGE_INTEGER Millisecond_Timeout; - - Millisecond_Timeout.QuadPart = -10000L; - - DeviceExtension->ack = 0; - - i8042IsrWritePort(DeviceExtension->PortDeviceExtension, byte, CTRL_WRITE_MOUSE); - while ((DeviceExtension->ack == 0) && timeout--) - { - if (i8042ReadKeyboardData(DeviceExtension->PortDeviceExtension, &scancode)) - { - switch(scancode) - { - case PSMOUSE_RET_ACK: - DeviceExtension->ack = 1; - break; - case PSMOUSE_RET_NAK: - DeviceExtension->ack = -1; - break; - default: - DeviceExtension->ack = 1; /* Workaround for mice which don't ACK the Get ID command */ - if (DeviceExtension->RepliesExpected) - DeviceExtension->pkt[--DeviceExtension->RepliesExpected] = scancode; - break; - } - return (INT)(-(DeviceExtension->ack <= 0)); - } - KeDelayExecutionThread(KernelMode, FALSE, &Millisecond_Timeout); - } - return (INT)(-(DeviceExtension->ack <= 0)); -} - -/* Send a PS/2 command to the mouse. */ -static INT SendCommand( - IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension, - IN PUCHAR param, - IN INT command) -{ - LARGE_INTEGER Millisecond_Timeout; - UCHAR scancode; - INT timeout = 500; /* 500 msec */ - UCHAR send = (command >> 12) & 0xf; - UCHAR receive = (command >> 8) & 0xf; - UCHAR i; - - Millisecond_Timeout.QuadPart = -10000L; - - DeviceExtension->RepliesExpected = receive; - if (command == PSMOUSE_CMD_RESET_BAT) - timeout = 2000; /* 2 sec */ - - if (command & 0xff) - if (SendByte(DeviceExtension, command & 0xff)) - return (INT)(DeviceExtension->RepliesExpected = 0) - 1; - - for (i = 0; i < send; i++) - if (SendByte(DeviceExtension, param[i])) - return (INT)(DeviceExtension->RepliesExpected = 0) - 1; - - while (DeviceExtension->RepliesExpected && timeout--) - { - if (DeviceExtension->RepliesExpected == 1 && command == PSMOUSE_CMD_RESET_BAT) - timeout = 100; - - if (DeviceExtension->RepliesExpected == 1 && command == PSMOUSE_CMD_GETID && - DeviceExtension->pkt[1] != 0xab && DeviceExtension->pkt[1] != 0xac) - { - DeviceExtension->RepliesExpected = 0; - break; - } - - if (i8042ReadKeyboardData(DeviceExtension->PortDeviceExtension, &scancode)) - { - DeviceExtension->pkt[--DeviceExtension->RepliesExpected] = scancode; - } - - KeDelayExecutionThread (KernelMode, FALSE, &Millisecond_Timeout); - } - - for (i = 0; i < receive; i++) - param[i] = DeviceExtension->pkt[(receive - 1) - i]; - - if (DeviceExtension->RepliesExpected) - return (int)(DeviceExtension->RepliesExpected = 0) - 1; - - return 0; -} - -/* Detect if mouse is just a standard ps/2 mouse */ -static BOOLEAN TestMouse( - IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension) -{ - UCHAR param[4]; - - param[0] = param[1] = 0xa5; - - /* - * First, we check if it's a mouse. It should send 0x00 or 0x03 - * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. - */ - if(SendCommand(DeviceExtension, param, PSMOUSE_CMD_GETID)) - return -1; - - if(param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) - return -1; - - /* - * Then we reset and disable the mouse so that it doesn't generate events. - */ - - return TRUE; -} - -/* Initialize the PS/2 mouse support */ -static BOOLEAN SetupMouse( - IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension) -{ - LARGE_INTEGER Millisecond_Timeout; - - Millisecond_Timeout.QuadPart = -10000L; - - /* setup */ - DeviceExtension->RepliesExpected = 0; - DeviceExtension->ack = 0; - - /* Enable the PS/2 mouse port */ - i8042Write(DeviceExtension->PortDeviceExtension, DeviceExtension->PortDeviceExtension->ControlPort, CONTROLLER_COMMAND_MOUSE_ENABLE); - - if(TestMouse(DeviceExtension)) - { - DPRINT("Detected Mouse\n"); - - if(SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_ENABLE)) - DPRINT1("Failed to enable mouse!\n"); - - /* Enable controller interrupts */ - i8042Write(DeviceExtension->PortDeviceExtension, DeviceExtension->PortDeviceExtension->ControlPort, KBD_WRITE_MODE); - i8042Write(DeviceExtension->PortDeviceExtension, DeviceExtension->PortDeviceExtension->DataPort, MOUSE_INTERRUPTS_ON); - } - - return TRUE; -} - -static NTSTATUS OldInitialization( - IN PPORT_DEVICE_EXTENSION PortDeviceExtension) -{ - I8042_MOUSE_EXTENSION_OLD DeviceExtension; - - RtlZeroMemory(&DeviceExtension, sizeof(I8042_MOUSE_EXTENSION_OLD)); - DeviceExtension.PortDeviceExtension = PortDeviceExtension; - SetupMouse(&DeviceExtension); - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/input/i8042prt/pnp.c b/reactos/drivers/input/i8042prt/pnp.c deleted file mode 100644 index a7e086a182d..00000000000 --- a/reactos/drivers/input/i8042prt/pnp.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/pnp.c - * PURPOSE: IRP_MJ_PNP operations - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/* This is all pretty confusing. There's more than one way to - * disable/enable the keyboard. You can send KBD_ENABLE to the - * keyboard, and it will start scanning keys. Sending KBD_DISABLE - * will disable the key scanning but also reset the parameters to - * defaults. - * - * You can also send 0xAE to the controller for enabling the - * keyboard clock line and 0xAD for disabling it. Then it'll - * automatically get turned on at the next command. The last - * way is by modifying the bit that drives the clock line in the - * 'command byte' of the controller. This is almost, but not quite, - * the same as the AE/AD thing. The difference can be used to detect - * some really old broken keyboard controllers which I hope won't be - * necessary. - * - * We change the command byte, sending KBD_ENABLE/DISABLE seems to confuse - * some kvm switches. - */ -BOOLEAN -i8042ChangeMode( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR FlagsToDisable, - IN UCHAR FlagsToEnable) -{ - UCHAR Value; - NTSTATUS Status; - - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, KBD_READ_MODE)) - { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = i8042ReadDataWait(DeviceExtension, &Value); - if (!NT_SUCCESS(Status)) - { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~FlagsToDisable; - Value |= FlagsToEnable; - - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, KBD_WRITE_MODE)) - { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value)) - { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -static NTSTATUS -i8042BasicDetect( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - NTSTATUS Status; - UCHAR Value = 0; - - /* Don't enable keyboard and mouse interrupts, disable keyboard/mouse */ - if (!i8042ChangeMode(DeviceExtension, CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB, CCB_KBD_DISAB | CCB_MOUSE_DISAB)) - return STATUS_IO_DEVICE_ERROR; - - i8042Flush(DeviceExtension); - - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST)) - { - DPRINT1("Writing CTRL_SELF_TEST command failed\n"); - return STATUS_IO_TIMEOUT; - } - - Status = i8042ReadDataWait(DeviceExtension, &Value); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to read CTRL_SELF_TEST response, status 0x%08lx\n", Status); - return Status; - } - - if (Value != 0x55) - { - DPRINT1("Got 0x%02x instead of 0x55\n", Value); - return STATUS_IO_DEVICE_ERROR; - } - - /* - * We used to send a KBD_LINE_TEST (0xAB) command here, but on at least HP - * Pavilion notebooks the response to that command was incorrect. - * So now we just assume that a keyboard is attached. - */ - DeviceExtension->Flags |= KEYBOARD_PRESENT; - - if (i8042Write(DeviceExtension, DeviceExtension->ControlPort, MOUSE_LINE_TEST)) - { - Status = i8042ReadDataWait(DeviceExtension, &Value); - if (NT_SUCCESS(Status) && Value == 0) - DeviceExtension->Flags |= MOUSE_PRESENT; - } - - if (IsFirstStageSetup()) - /* Ignore the mouse */ - DeviceExtension->Flags &= ~MOUSE_PRESENT; - - return STATUS_SUCCESS; -} - -static BOOLEAN -i8042DetectKeyboard( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - NTSTATUS Status; - - /* Set LEDs (that is not fatal if some error occurs) */ - Status = i8042SynchWritePort(DeviceExtension, 0, KBD_CMD_SET_LEDS, TRUE); - if (NT_SUCCESS(Status)) - { - Status = i8042SynchWritePort(DeviceExtension, 0, 0, TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Can't finish SET_LEDS (0x%08lx)\n", Status); - return FALSE; - } - } - else - { - DPRINT("Warning: can't write SET_LEDS (0x%08lx)\n", Status); - } - - /* Turn on translation */ - if (!i8042ChangeMode(DeviceExtension, 0, CCB_TRANSLATE)) - return FALSE; - - return TRUE; -} - -static BOOLEAN -i8042DetectMouse( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - BOOLEAN Ok = FALSE; - NTSTATUS Status; - UCHAR Value; - UCHAR ExpectedReply[] = { MOUSE_ACK, 0xAA, 0x00 }; - UCHAR ReplyByte; - - i8042Flush(DeviceExtension); - - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_WRITE_MOUSE) - ||!i8042Write(DeviceExtension, DeviceExtension->DataPort, MOU_CMD_RESET)) - { - DPRINT1("Failed to write reset command to mouse\n"); - goto cleanup; - } - - for (ReplyByte = 0; - ReplyByte < sizeof(ExpectedReply) / sizeof(ExpectedReply[0]); - ReplyByte++) - { - Status = i8042ReadDataWait(DeviceExtension, &Value); - if (!NT_SUCCESS(Status)) - { - DPRINT1("No ACK after mouse reset, status 0x%08lx\n", Status); - goto cleanup; - } - else if (Value != ExpectedReply[ReplyByte]) - { - DPRINT1("Unexpected reply: 0x%02x (expected 0x%02x)\n", - Value, ExpectedReply[ReplyByte]); - goto cleanup; - } - } - - Ok = TRUE; - -cleanup: - if (!Ok) - { - /* There is probably no mouse present. On some systems, - the probe locks the entire keyboard controller. Let's - try to get access to the keyboard again by sending a - reset */ - i8042Flush(DeviceExtension); - i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST); - i8042ReadDataWait(DeviceExtension, &Value); - i8042Flush(DeviceExtension); - } - - DPRINT("Mouse %sdetected\n", Ok ? "" : "not "); - - return Ok; -} - -static NTSTATUS -i8042ConnectKeyboardInterrupt( - IN PI8042_KEYBOARD_EXTENSION DeviceExtension) -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - KIRQL DirqlMax; - NTSTATUS Status; - - DPRINT("i8042ConnectKeyboardInterrupt()\n"); - - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - DirqlMax = MAX( - PortDeviceExtension->KeyboardInterrupt.Dirql, - PortDeviceExtension->MouseInterrupt.Dirql); - - DPRINT("KeyboardInterrupt.Vector %lu\n", - PortDeviceExtension->KeyboardInterrupt.Vector); - DPRINT("KeyboardInterrupt.Dirql %lu\n", - PortDeviceExtension->KeyboardInterrupt.Dirql); - DPRINT("KeyboardInterrupt.DirqlMax %lu\n", - DirqlMax); - DPRINT("KeyboardInterrupt.InterruptMode %s\n", - PortDeviceExtension->KeyboardInterrupt.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"); - DPRINT("KeyboardInterrupt.ShareInterrupt %s\n", - PortDeviceExtension->KeyboardInterrupt.ShareInterrupt ? "yes" : "no"); - DPRINT("KeyboardInterrupt.Affinity 0x%lx\n", - PortDeviceExtension->KeyboardInterrupt.Affinity); - Status = IoConnectInterrupt( - &PortDeviceExtension->KeyboardInterrupt.Object, - i8042KbdInterruptService, - DeviceExtension, &PortDeviceExtension->SpinLock, - PortDeviceExtension->KeyboardInterrupt.Vector, PortDeviceExtension->KeyboardInterrupt.Dirql, DirqlMax, - PortDeviceExtension->KeyboardInterrupt.InterruptMode, PortDeviceExtension->KeyboardInterrupt.ShareInterrupt, - PortDeviceExtension->KeyboardInterrupt.Affinity, FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoConnectInterrupt() failed with status 0x%08x\n", Status); - return Status; - } - - if (DirqlMax == PortDeviceExtension->KeyboardInterrupt.Dirql) - PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object; - PortDeviceExtension->Flags |= KEYBOARD_INITIALIZED; - return STATUS_SUCCESS; -} - -static NTSTATUS -i8042ConnectMouseInterrupt( - IN PI8042_MOUSE_EXTENSION DeviceExtension) -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - KIRQL DirqlMax; - NTSTATUS Status; - - DPRINT("i8042ConnectMouseInterrupt()\n"); - - Status = i8042MouInitialize(DeviceExtension); - if (!NT_SUCCESS(Status)) - return Status; - - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - DirqlMax = MAX( - PortDeviceExtension->KeyboardInterrupt.Dirql, - PortDeviceExtension->MouseInterrupt.Dirql); - - DPRINT("MouseInterrupt.Vector %lu\n", - PortDeviceExtension->MouseInterrupt.Vector); - DPRINT("MouseInterrupt.Dirql %lu\n", - PortDeviceExtension->MouseInterrupt.Dirql); - DPRINT("MouseInterrupt.DirqlMax %lu\n", - DirqlMax); - DPRINT("MouseInterrupt.InterruptMode %s\n", - PortDeviceExtension->MouseInterrupt.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"); - DPRINT("MouseInterrupt.ShareInterrupt %s\n", - PortDeviceExtension->MouseInterrupt.ShareInterrupt ? "yes" : "no"); - DPRINT("MouseInterrupt.Affinity 0x%lx\n", - PortDeviceExtension->MouseInterrupt.Affinity); - Status = IoConnectInterrupt( - &PortDeviceExtension->MouseInterrupt.Object, - i8042MouInterruptService, - DeviceExtension, &PortDeviceExtension->SpinLock, - PortDeviceExtension->MouseInterrupt.Vector, PortDeviceExtension->MouseInterrupt.Dirql, DirqlMax, - PortDeviceExtension->MouseInterrupt.InterruptMode, PortDeviceExtension->MouseInterrupt.ShareInterrupt, - PortDeviceExtension->MouseInterrupt.Affinity, FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoConnectInterrupt() failed with status 0x%08x\n", Status); - goto cleanup; - } - - if (DirqlMax == PortDeviceExtension->MouseInterrupt.Dirql) - PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->MouseInterrupt.Object; - - PortDeviceExtension->Flags |= MOUSE_INITIALIZED; - Status = STATUS_SUCCESS; - -cleanup: - if (!NT_SUCCESS(Status)) - { - PortDeviceExtension->Flags &= ~MOUSE_INITIALIZED; - if (PortDeviceExtension->MouseInterrupt.Object) - { - IoDisconnectInterrupt(PortDeviceExtension->MouseInterrupt.Object); - PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object; - } - } - return Status; -} - -static NTSTATUS -EnableInterrupts( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - UCHAR FlagsToDisable = 0; - UCHAR FlagsToEnable = 0; - - i8042Flush(DeviceExtension); - - /* Select the devices we have */ - if (DeviceExtension->Flags & KEYBOARD_PRESENT) - { - FlagsToDisable |= CCB_KBD_DISAB; - FlagsToEnable |= CCB_KBD_INT_ENAB; - } - if (DeviceExtension->Flags & MOUSE_PRESENT) - { - FlagsToDisable |= CCB_MOUSE_DISAB; - FlagsToEnable |= CCB_MOUSE_INT_ENAB; - } - if (!i8042ChangeMode(DeviceExtension, FlagsToDisable, FlagsToEnable)) - return STATUS_UNSUCCESSFUL; - - return STATUS_SUCCESS; -} - -static NTSTATUS -StartProcedure( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - NTSTATUS Status; - - if (DeviceExtension->DataPort == 0) - { - /* Unable to do something at the moment */ - return STATUS_SUCCESS; - } - - if (!(DeviceExtension->Flags & (KEYBOARD_PRESENT | MOUSE_PRESENT))) - { - /* Try to detect them */ - DPRINT("Check if the controller is really a i8042\n"); - Status = i8042BasicDetect(DeviceExtension); - if (!NT_SUCCESS(Status)) - { - DPRINT("i8042BasicDetect() failed with status 0x%08lx\n", Status); - return STATUS_UNSUCCESSFUL; - } - DPRINT("Detecting keyboard\n"); - if (!i8042DetectKeyboard(DeviceExtension)) - return STATUS_UNSUCCESSFUL; - DPRINT("Detecting mouse\n"); - if (!i8042DetectMouse(DeviceExtension)) - return STATUS_UNSUCCESSFUL; - DPRINT("Keyboard present: %s\n", DeviceExtension->Flags & KEYBOARD_PRESENT ? "YES" : "NO"); - DPRINT("Mouse present : %s\n", DeviceExtension->Flags & MOUSE_PRESENT ? "YES" : "NO"); - } - - /* Connect interrupts */ - if (DeviceExtension->Flags & KEYBOARD_PRESENT && - DeviceExtension->Flags & KEYBOARD_CONNECTED && - DeviceExtension->Flags & KEYBOARD_STARTED && - !(DeviceExtension->Flags & (MOUSE_PRESENT | KEYBOARD_INITIALIZED))) - { - /* No mouse, and the keyboard is ready */ - Status = i8042ConnectKeyboardInterrupt(DeviceExtension->KeyboardExtension); - if (NT_SUCCESS(Status)) - { - DeviceExtension->Flags |= KEYBOARD_INITIALIZED; - Status = EnableInterrupts(DeviceExtension); - } - } - else if (DeviceExtension->Flags & MOUSE_PRESENT && - DeviceExtension->Flags & MOUSE_CONNECTED && - DeviceExtension->Flags & MOUSE_STARTED && - !(DeviceExtension->Flags & (KEYBOARD_PRESENT | MOUSE_INITIALIZED))) - { - /* No keyboard, and the mouse is ready */ - Status = i8042ConnectMouseInterrupt(DeviceExtension->MouseExtension); - if (NT_SUCCESS(Status)) - { - DeviceExtension->Flags |= MOUSE_INITIALIZED; - Status = EnableInterrupts(DeviceExtension); - } - } - else if (DeviceExtension->Flags & KEYBOARD_PRESENT && - DeviceExtension->Flags & KEYBOARD_CONNECTED && - DeviceExtension->Flags & KEYBOARD_STARTED && - DeviceExtension->Flags & MOUSE_PRESENT && - DeviceExtension->Flags & MOUSE_CONNECTED && - DeviceExtension->Flags & MOUSE_STARTED && - !(DeviceExtension->Flags & (KEYBOARD_INITIALIZED | MOUSE_INITIALIZED))) - { - /* The keyboard and mouse are ready */ - Status = i8042ConnectKeyboardInterrupt(DeviceExtension->KeyboardExtension); - if (NT_SUCCESS(Status)) - { - DeviceExtension->Flags |= KEYBOARD_INITIALIZED; - Status = i8042ConnectMouseInterrupt(DeviceExtension->MouseExtension); - if (NT_SUCCESS(Status)) - { - DeviceExtension->Flags |= MOUSE_INITIALIZED; - Status = EnableInterrupts(DeviceExtension); - } - } - } - else - { - /* Nothing to do */ - Status = STATUS_SUCCESS; - } - - return Status; -} - -static NTSTATUS -i8042PnpStartDevice( - IN PDEVICE_OBJECT DeviceObject, - IN PCM_RESOURCE_LIST AllocatedResources, - IN PCM_RESOURCE_LIST AllocatedResourcesTranslated) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor, ResourceDescriptorTranslated; - INTERRUPT_DATA InterruptData; - BOOLEAN FoundDataPort = FALSE; - BOOLEAN FoundControlPort = FALSE; - BOOLEAN FoundIrq = FALSE; - ULONG i; - NTSTATUS Status; - - DPRINT("i8042PnpStartDevice(%p)\n", DeviceObject); - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - PortDeviceExtension = DeviceExtension->PortDeviceExtension; - - ASSERT(DeviceExtension->PnpState == dsStopped); - - if (!AllocatedResources) - { - DPRINT("No allocated resources sent to driver\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - if (AllocatedResources->Count != 1) - { - DPRINT("Wrong number of allocated resources sent to driver\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - if (AllocatedResources->List[0].PartialResourceList.Version != 1 - || AllocatedResources->List[0].PartialResourceList.Revision != 1 - || AllocatedResourcesTranslated->List[0].PartialResourceList.Version != 1 - || AllocatedResourcesTranslated->List[0].PartialResourceList.Revision != 1) - { - DPRINT("Revision mismatch: %u.%u != 1.1 or %u.%u != 1.1\n", - AllocatedResources->List[0].PartialResourceList.Version, - AllocatedResources->List[0].PartialResourceList.Revision, - AllocatedResourcesTranslated->List[0].PartialResourceList.Version, - AllocatedResourcesTranslated->List[0].PartialResourceList.Revision); - return STATUS_REVISION_MISMATCH; - } - - /* Get Irq and optionally control port and data port */ - for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++) - { - ResourceDescriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i]; - ResourceDescriptorTranslated = &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i]; - switch (ResourceDescriptor->Type) - { - case CmResourceTypePort: - { - if (ResourceDescriptor->u.Port.Length == 1) - { - /* We assume that the first ressource will - * be the control port and the second one - * will be the data port... - */ - if (!FoundDataPort) - { - PortDeviceExtension->DataPort = (PUCHAR)ResourceDescriptor->u.Port.Start.u.LowPart; - DPRINT("Found data port: 0x%lx\n", PortDeviceExtension->DataPort); - FoundDataPort = TRUE; - } - else if (!FoundControlPort) - { - PortDeviceExtension->ControlPort = (PUCHAR)ResourceDescriptor->u.Port.Start.u.LowPart; - DPRINT("Found control port: 0x%lx\n", PortDeviceExtension->ControlPort); - FoundControlPort = TRUE; - } - else - { - DPRINT("Too much I/O ranges provided\n", ResourceDescriptor->u.Port.Length); - return STATUS_INVALID_PARAMETER; - } - } - else - DPRINT1("Invalid I/O range length: 0x%lx\n", ResourceDescriptor->u.Port.Length); - break; - } - case CmResourceTypeInterrupt: - { - if (FoundIrq) - return STATUS_INVALID_PARAMETER; - InterruptData.Dirql = (KIRQL)ResourceDescriptorTranslated->u.Interrupt.Level; - InterruptData.Vector = ResourceDescriptorTranslated->u.Interrupt.Vector; - InterruptData.Affinity = ResourceDescriptorTranslated->u.Interrupt.Affinity; - if (ResourceDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED) - InterruptData.InterruptMode = Latched; - else - InterruptData.InterruptMode = LevelSensitive; - InterruptData.ShareInterrupt = (ResourceDescriptorTranslated->ShareDisposition == CmResourceShareShared); - DPRINT("Found irq resource: %lu\n", ResourceDescriptor->u.Interrupt.Vector); - FoundIrq = TRUE; - break; - } - default: - DPRINT("Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type); - } - } - - if (!FoundIrq) - { - DPRINT("Interrupt resource was not found in allocated resources list\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - else if (DeviceExtension->Type == Keyboard && (!FoundDataPort || !FoundControlPort)) - { - DPRINT("Some required resources were not found in allocated resources list\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - else if (DeviceExtension->Type == Mouse && (FoundDataPort || FoundControlPort)) - { - DPRINT("Too much resources were provided in allocated resources list\n"); - return STATUS_INVALID_PARAMETER; - } - - switch (DeviceExtension->Type) - { - case Keyboard: - { - RtlCopyMemory( - &PortDeviceExtension->KeyboardInterrupt, - &InterruptData, - sizeof(INTERRUPT_DATA)); - PortDeviceExtension->Flags |= KEYBOARD_STARTED; - Status = StartProcedure(PortDeviceExtension); - break; - } - case Mouse: - { - RtlCopyMemory( - &PortDeviceExtension->MouseInterrupt, - &InterruptData, - sizeof(INTERRUPT_DATA)); - PortDeviceExtension->Flags |= MOUSE_STARTED; - Status = StartProcedure(PortDeviceExtension); - break; - } - default: - { - DPRINT1("Unknown FDO type %u\n", DeviceExtension->Type); - ASSERT(FALSE); - Status = STATUS_INVALID_DEVICE_REQUEST; - } - } - - if (NT_SUCCESS(Status)) - DeviceExtension->PnpState = dsStarted; - - return Status; -} - -NTSTATUS NTAPI -i8042Pnp( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - ULONG MinorFunction; - I8042_DEVICE_TYPE DeviceType; - ULONG_PTR Information = 0; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = Stack->MinorFunction; - DeviceType = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type; - - switch (MinorFunction) - { - case IRP_MN_START_DEVICE: /* 0x0 */ - { - DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); - - /* Call lower driver (if any) */ - if (DeviceType != PhysicalDeviceObject) - { - Status = ForwardIrpAndWait(DeviceObject, Irp); - if (NT_SUCCESS(Status)) - Status = i8042PnpStartDevice( - DeviceObject, - Stack->Parameters.StartDevice.AllocatedResources, - Stack->Parameters.StartDevice.AllocatedResourcesTranslated); - } - else - Status = STATUS_SUCCESS; - break; - } - case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */ - { - switch (Stack->Parameters.QueryDeviceRelations.Type) - { - case BusRelations: - { - DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); - return ForwardIrpAndForget(DeviceObject, Irp); - } - case RemovalRelations: - { - DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); - return ForwardIrpAndForget(DeviceObject, Irp); - } - default: - DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", - Stack->Parameters.QueryDeviceRelations.Type); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - break; - } - default: - { - DPRINT1("IRP_MJ_PNP / unknown minor function 0x%x\n", MinorFunction); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - Irp->IoStatus.Information = Information; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; -} diff --git a/reactos/drivers/input/i8042prt/ps2pp.c b/reactos/drivers/input/i8042prt/ps2pp.c deleted file mode 100644 index c9746d70f43..00000000000 --- a/reactos/drivers/input/i8042prt/ps2pp.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/ps2pp.c - * PURPOSE: ps2pp protocol handling - * PROGRAMMERS: Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - * Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -VOID -i8042MouHandlePs2pp( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Input) -{ - UCHAR PktType; - PMOUSE_INPUT_DATA MouseInput; - - MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; - - /* First, collect 3 bytes for a packet - * We can detect out-of-sync only by checking - * the whole packet anyway. - * - * If bit 7 and 8 of the first byte are 0, its - * a normal packet. - * - * Otherwise, the packet is different, like this: - * 1: E 1 b3 b2 x x x x - * 2: x x b1 b0 x1 x0 1 0 - * 3: x x x x x x x1 x0 - * - * b3-0 form a code that specifies the packet type: - * - * 0 Device Type - * 1 Rollers and buttons - * 2 Reserved - * 3 Reserved - * 4 Device ID - * 5 Channel & Battery - * 6 Wireless notifications - * 7 Reserved - * 8 ShortID LSB (ShortID is a number that is supposed to differentiate - * 9 ShortID MSB between your mouse and your neighbours') - * 10 Reserved - * 11 Mouse capabilities - * 12 Remote control LSB - * 13 Remote control MSB - * 14 Reserved - * 15 Extended packet - */ - - switch (DeviceExtension->MouseState) - { - case MouseIdle: - case XMovement: - DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input; - DeviceExtension->MouseState++; - break; - - case YMovement: - DeviceExtension->MouseLogiBuffer[2] = Input; - DeviceExtension->MouseState = MouseIdle; - - /* first check if it's a normal packet */ - - if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0)) - { - DeviceExtension->MouseState = MouseIdle; - i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]); - i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]); - i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]); - /* We could care about wether MouseState really - * advances, but we don't need to because we're - * only doing three bytes anyway, so the packet - * will never complete if it's broken. - */ - return; - } - - /* sanity check */ - if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) || - (((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) != - (DeviceExtension->MouseLogiBuffer[2] & 0x03))) - { - DPRINT1("Ps2pp packet fails sanity checks\n"); - return; - } - - /* Now get the packet type */ - PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 4) & - ((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 6); - - switch (PktType) - { - case 0: - /* The packet contains the device ID, but we - * already read that in the initialization - * sequence. Ignore it. - */ - return; - case 1: - RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA)); - if (DeviceExtension->MouseLogiBuffer[2] & 0x10) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - - if (DeviceExtension->MouseLogiBuffer[2] & 0x20) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - - if (DeviceExtension->MouseLogiBuffer[2] & 0x0F) - { - MouseInput->ButtonFlags |= MOUSE_WHEEL; - if (DeviceExtension->MouseLogiBuffer[2] & 0x08) - MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8; - else - MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07; - } - i8042MouHandleButtons( - DeviceExtension, - MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN); - i8042MouQueuePacket(DeviceExtension); - return; - default: - /* These are for things that would probably - * be handled by logitechs own driver. - */ - return; - } - - default: - DPRINT1("Unexpected input state for ps2pp!\n"); - } -} diff --git a/reactos/drivers/input/i8042prt/readwrite.c b/reactos/drivers/input/i8042prt/readwrite.c deleted file mode 100644 index 6ebf68e850c..00000000000 --- a/reactos/drivers/input/i8042prt/readwrite.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/readwrite.c - * PURPOSE: Read/write port functions - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -VOID -i8042Flush( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - UCHAR Ignore; - - while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_OBF | MOU_OBF, &Ignore))) { - DPRINT("Data flushed\n"); /* drop */ - } -} - -VOID -i8042IsrWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Value, - IN UCHAR SelectCmd OPTIONAL) -{ - if (SelectCmd) - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, SelectCmd)) - return; - - i8042Write(DeviceExtension, DeviceExtension->DataPort, Value); -} - -/* - * FUNCTION: Read data from port 0x60 - */ -NTSTATUS -i8042ReadData( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR StatusFlags, - OUT PUCHAR Data) -{ - UCHAR PortStatus; - NTSTATUS Status; - - Status = i8042ReadStatus(DeviceExtension, &PortStatus); - if (!NT_SUCCESS(Status)) - return Status; - - // If data is available - if (PortStatus & StatusFlags) - { - *Data = READ_PORT_UCHAR(DeviceExtension->DataPort); - DPRINT("Read: 0x%02x (status: 0x%x)\n", Data[0], PortStatus); - - // If the data is valid (not timeout, not parity error) - if ((PortStatus & KBD_PERR) == 0) - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -i8042ReadStatus( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Status) -{ - ASSERT(DeviceExtension->ControlPort != NULL); - *Status = READ_PORT_UCHAR(DeviceExtension->ControlPort); - return STATUS_SUCCESS; -} - -/* - * FUNCTION: Read data from data port - */ -NTSTATUS -i8042ReadDataWait( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Data) -{ - ULONG Counter; - NTSTATUS Status; - - Counter = DeviceExtension->Settings.PollingIterations; - - while (Counter--) - { - Status = i8042ReadKeyboardData(DeviceExtension, Data); - - if (NT_SUCCESS(Status)) - return Status; - - KeStallExecutionProcessor(50); - } - - /* Timed out */ - return STATUS_IO_TIMEOUT; -} - -/* - * This one reads a value from the port; You don't have to specify - * which one, it'll always be from the one you talked to, so one function - * is enough this time. Note how MSDN specifies the - * WaitForAck parameter to be ignored. - */ -NTSTATUS NTAPI -i8042SynchReadPort( - IN PVOID Context, - OUT PUCHAR Value, - IN BOOLEAN WaitForAck) -{ - PPORT_DEVICE_EXTENSION DeviceExtension; - - DeviceExtension = (PPORT_DEVICE_EXTENSION)Context; - - return i8042ReadDataWait(DeviceExtension, Value); -} - -/* - * These functions are callbacks for filter driver custom - * initialization routines. - */ -NTSTATUS NTAPI -i8042SynchWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Port, - IN UCHAR Value, - IN BOOLEAN WaitForAck) -{ - NTSTATUS Status; - UCHAR Ack; - ULONG ResendIterations; - - ResendIterations = DeviceExtension->Settings.ResendIterations + 1; - - do - { - if (Port) - if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Port)) - { - DPRINT1("Failed to write Port\n"); - return STATUS_IO_TIMEOUT; - } - - if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value)) - { - DPRINT1("Failed to write Value\n"); - return STATUS_IO_TIMEOUT; - } - - if (WaitForAck) - { - Status = i8042ReadDataWait(DeviceExtension, &Ack); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to read Ack\n"); - return Status; - } - if (Ack == KBD_ACK) - return STATUS_SUCCESS; - if (Ack != KBD_RESEND) - { - DPRINT1("Unexpected Ack 0x%02x\n", Ack); - return STATUS_UNEXPECTED_IO_ERROR; - } - } - else - { - return STATUS_SUCCESS; - } - DPRINT("Reiterating\n"); - ResendIterations--; - } while (ResendIterations); - - return STATUS_IO_TIMEOUT; -} - -/* - * FUNCTION: Write data to a port, waiting first for it to become ready - */ -BOOLEAN -i8042Write( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PUCHAR addr, - IN UCHAR data) -{ - ULONG ResendIterations; - - ASSERT(addr); - ASSERT(DeviceExtension->ControlPort != NULL); - - ResendIterations = DeviceExtension->Settings.ResendIterations; - - while ((KBD_IBF & READ_PORT_UCHAR(DeviceExtension->ControlPort)) && - (ResendIterations--)) - { - KeStallExecutionProcessor(50); - } - - if (ResendIterations) - { - WRITE_PORT_UCHAR(addr, data); - DPRINT("Sent 0x%x to port 0x%x\n", data, addr); - return TRUE; - } - return FALSE; -} diff --git a/reactos/drivers/input/i8042prt/registry.c b/reactos/drivers/input/i8042prt/registry.c deleted file mode 100644 index 41e9a857c21..00000000000 --- a/reactos/drivers/input/i8042prt/registry.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/i8042prt.c - * PURPOSE: Reading the registry - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS -ReadRegistryEntries( - IN PUNICODE_STRING RegistryPath, - OUT PI8042_SETTINGS Settings) -{ - UNICODE_STRING ParametersRegistryKey; - RTL_QUERY_REGISTRY_TABLE Parameters[16]; - NTSTATUS Status; - - ULONG DefaultKeyboardDataQueueSize = 0x64; - UNICODE_STRING DefaultKeyboardDeviceBaseName = RTL_CONSTANT_STRING(L"KeyboardPort"); - ULONG DefaultMouseDataQueueSize = 0x64; - ULONG DefaultMouseResolution = 3; - ULONG DefaultMouseSynchIn100ns = 20000000; - ULONG DefaultNumberOfButtons = 2; - UNICODE_STRING DefaultPointerDeviceBaseName = RTL_CONSTANT_STRING(L"PointerPort"); - ULONG DefaultPollStatusIterations = 1; - ULONG DefaultOverrideKeyboardType = 4; - ULONG DefaultOverrideKeyboardSubtype = 0; - ULONG DefaultPollingIterations = 12000; - ULONG DefaultPollingIterationsMaximum = 12000; - ULONG DefaultResendIterations = 0x3; - ULONG DefaultSampleRate = 60; - ULONG DefaultCrashOnCtrlScroll; - - /* Default value for CrashOnCtrlScroll depends if we're - * running a debug build or a normal build. - */ -#ifdef DBG - DefaultCrashOnCtrlScroll = 1; -#else - DefaultCrashOnCtrlScroll = 0; -#endif - - ParametersRegistryKey.Length = 0; - ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL); - ParametersRegistryKey.Buffer = ExAllocatePool(PagedPool, ParametersRegistryKey.MaximumLength); - if (!ParametersRegistryKey.Buffer) - { - DPRINT("ExAllocatePool() failed\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - RtlCopyUnicodeString(&ParametersRegistryKey, RegistryPath); - RtlAppendUnicodeToString(&ParametersRegistryKey, L"\\Parameters"); - ParametersRegistryKey.Buffer[ParametersRegistryKey.Length / sizeof(WCHAR)] = UNICODE_NULL; - - RtlZeroMemory(Parameters, sizeof(Parameters)); - - Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[0].Name = L"KeyboardDataQueueSize"; - Parameters[0].EntryContext = &Settings->KeyboardDataQueueSize; - Parameters[0].DefaultType = REG_DWORD; - Parameters[0].DefaultData = &DefaultKeyboardDataQueueSize; - Parameters[0].DefaultLength = sizeof(ULONG); - - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[1].Name = L"KeyboardDeviceBaseName"; - Parameters[1].EntryContext = &Settings->KeyboardDeviceBaseName; - Parameters[1].DefaultType = REG_SZ; - Parameters[1].DefaultData = &DefaultKeyboardDeviceBaseName; - Parameters[1].DefaultLength = 0; - - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[2].Name = L"MouseDataQueueSize"; - Parameters[2].EntryContext = &Settings->MouseDataQueueSize; - Parameters[2].DefaultType = REG_DWORD; - Parameters[2].DefaultData = &DefaultMouseDataQueueSize; - Parameters[2].DefaultLength = sizeof(ULONG); - - Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[3].Name = L"MouseResolution"; - Parameters[3].EntryContext = &Settings->MouseResolution; - Parameters[3].DefaultType = REG_DWORD; - Parameters[3].DefaultData = &DefaultMouseResolution; - Parameters[3].DefaultLength = sizeof(ULONG); - - Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[4].Name = L"MouseSynchIn100ns"; - Parameters[4].EntryContext = &Settings->MouseSynchIn100ns; - Parameters[4].DefaultType = REG_DWORD; - Parameters[4].DefaultData = &DefaultMouseSynchIn100ns; - Parameters[4].DefaultLength = sizeof(ULONG); - - Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[5].Name = L"NumberOfButtons"; - Parameters[5].EntryContext = &Settings->NumberOfButtons; - Parameters[5].DefaultType = REG_DWORD; - Parameters[5].DefaultData = &DefaultNumberOfButtons; - Parameters[5].DefaultLength = sizeof(ULONG); - - Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[6].Name = L"PointerDeviceBaseName"; - Parameters[6].EntryContext = &Settings->PointerDeviceBaseName; - Parameters[6].DefaultType = REG_SZ; - Parameters[6].DefaultData = &DefaultPointerDeviceBaseName; - Parameters[6].DefaultLength = 0; - - Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[7].Name = L"PollStatusIterations"; - Parameters[7].EntryContext = &Settings->PollStatusIterations; - Parameters[7].DefaultType = REG_DWORD; - Parameters[7].DefaultData = &DefaultPollStatusIterations; - Parameters[7].DefaultLength = sizeof(ULONG); - - Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[8].Name = L"OverrideKeyboardType"; - Parameters[8].EntryContext = &Settings->OverrideKeyboardType; - Parameters[8].DefaultType = REG_DWORD; - Parameters[8].DefaultData = &DefaultOverrideKeyboardType; - Parameters[8].DefaultLength = sizeof(ULONG); - - Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[9].Name = L"OverrideKeyboardSubtype"; - Parameters[9].EntryContext = &Settings->OverrideKeyboardSubtype; - Parameters[9].DefaultType = REG_DWORD; - Parameters[9].DefaultData = &DefaultOverrideKeyboardSubtype; - Parameters[9].DefaultLength = sizeof(ULONG); - - Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[10].Name = L"PollingIterations"; - Parameters[10].EntryContext = &Settings->PollingIterations; - Parameters[10].DefaultType = REG_DWORD; - Parameters[10].DefaultData = &DefaultPollingIterations; - Parameters[10].DefaultLength = sizeof(ULONG); - - Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[11].Name = L"PollingIterationsMaximum"; - Parameters[11].EntryContext = &Settings->PollingIterationsMaximum; - Parameters[11].DefaultType = REG_DWORD; - Parameters[11].DefaultData = &DefaultPollingIterationsMaximum; - Parameters[11].DefaultLength = sizeof(ULONG); - - Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[12].Name = L"ResendIterations"; - Parameters[12].EntryContext = &Settings->ResendIterations; - Parameters[12].DefaultType = REG_DWORD; - Parameters[12].DefaultData = &DefaultResendIterations; - Parameters[12].DefaultLength = sizeof(ULONG); - - Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[13].Name = L"SampleRate"; - Parameters[13].EntryContext = &Settings->SampleRate; - Parameters[13].DefaultType = REG_DWORD; - Parameters[13].DefaultData = &DefaultSampleRate; - Parameters[13].DefaultLength = sizeof(ULONG); - - Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[14].Name = L"CrashOnCtrlScroll"; - Parameters[14].EntryContext = &Settings->CrashOnCtrlScroll; - Parameters[14].DefaultType = REG_DWORD; - Parameters[14].DefaultData = &DefaultCrashOnCtrlScroll; - Parameters[14].DefaultLength = sizeof(ULONG); - - Status = RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, - ParametersRegistryKey.Buffer, - Parameters, - NULL, - NULL); - - if (NT_SUCCESS(Status)) - { - /* Check values */ - if (Settings->KeyboardDataQueueSize < 1) - Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; - if (Settings->MouseDataQueueSize < 1) - Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; - if (Settings->NumberOfButtons < 1) - Settings->NumberOfButtons = DefaultNumberOfButtons; - if (Settings->PollingIterations < 0x400) - Settings->PollingIterations = DefaultPollingIterations; - if (Settings->PollingIterationsMaximum < 0x400) - Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; - if (Settings->ResendIterations < 1) - Settings->ResendIterations = DefaultResendIterations; - } - else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - { - /* Registry path doesn't exist. Set defaults */ - Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; - Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; - Settings->MouseResolution = DefaultMouseResolution; - Settings->MouseSynchIn100ns = DefaultMouseSynchIn100ns; - Settings->NumberOfButtons = DefaultNumberOfButtons; - Settings->PollStatusIterations = DefaultPollStatusIterations; - Settings->OverrideKeyboardType = DefaultOverrideKeyboardType; - Settings->OverrideKeyboardSubtype = DefaultOverrideKeyboardSubtype; - Settings->PollingIterations = DefaultPollingIterations; - Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; - Settings->ResendIterations = DefaultResendIterations; - Settings->SampleRate = DefaultSampleRate; - Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll; - Status = RtlDuplicateUnicodeString( - RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, - &DefaultKeyboardDeviceBaseName, - &Settings->KeyboardDeviceBaseName); - if (!NT_SUCCESS(Status)) - { - DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); - } - else - { - Status = RtlDuplicateUnicodeString( - RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, - &DefaultPointerDeviceBaseName, - &Settings->PointerDeviceBaseName); - if (!NT_SUCCESS(Status)) - DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); - } - } - - if (NT_SUCCESS(Status)) - { - DPRINT("KeyboardDataQueueSize : 0x%lx\n", Settings->KeyboardDataQueueSize); - DPRINT("KeyboardDeviceBaseName : %wZ\n", &Settings->KeyboardDeviceBaseName); - DPRINT("MouseDataQueueSize : 0x%lx\n", Settings->MouseDataQueueSize); - DPRINT("MouseResolution : 0x%lx\n", Settings->MouseResolution); - DPRINT("MouseSynchIn100ns : %lu\n", Settings->MouseSynchIn100ns); - DPRINT("NumberOfButtons : 0x%lx\n", Settings->NumberOfButtons); - DPRINT("PointerDeviceBaseName : %wZ\n", &Settings->PointerDeviceBaseName); - DPRINT("PollStatusIterations : 0x%lx\n", Settings->PollStatusIterations); - DPRINT("OverrideKeyboardType : 0x%lx\n", Settings->OverrideKeyboardType); - DPRINT("OverrideKeyboardSubtype : 0x%lx\n", Settings->OverrideKeyboardSubtype); - DPRINT("PollingIterations : 0x%lx\n", Settings->PollingIterations); - DPRINT("PollingIterationsMaximum : %lu\n", Settings->PollingIterationsMaximum); - DPRINT("ResendIterations : 0x%lx\n", Settings->ResendIterations); - DPRINT("SampleRate : %lu\n", Settings->SampleRate); - } - - return Status; -} diff --git a/reactos/drivers/input/i8042prt/setup.c b/reactos/drivers/input/i8042prt/setup.c deleted file mode 100644 index b33181c3f89..00000000000 --- a/reactos/drivers/input/i8042prt/setup.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/setup.c - * PURPOSE: Create a legacy PDO during ReactOS installation - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* NOTE: - * All this file is a big hack and should be removed one day... - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -#define KEYBOARD_DATA_PORT 0x60 -#define KEYBOARD_CONTROL_PORT 0x64 -#define KEYBOARD_IRQ 1 - -/* FUNCTIONS *****************************************************************/ - -BOOLEAN -IsFirstStageSetup( - VOID) -{ - UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\Setup"); - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hSetupKey = (HANDLE)NULL; - NTSTATUS Status; - BOOLEAN ret = TRUE; - - InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = ZwOpenKey(&hSetupKey, KEY_QUERY_VALUE, &ObjectAttributes); - - if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - ret = TRUE; - else - ret = FALSE; - - if (hSetupKey != (HANDLE)NULL) - ZwClose(hSetupKey); - DPRINT("IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO"); - return ret; -} - -static VOID NTAPI -SendStartDevice( - IN PDRIVER_OBJECT DriverObject, - IN PVOID Context, - IN ULONG Count) -{ - PDEVICE_OBJECT Pdo; - PCM_RESOURCE_LIST AllocatedResources = NULL; - PCM_RESOURCE_LIST AllocatedResourcesTranslated = NULL; - PDEVICE_OBJECT TopDeviceObject = NULL; - KEVENT Event; - IO_STATUS_BLOCK IoStatusBlock; - PIRP Irp; - PIO_STACK_LOCATION Stack; - ULONG ResourceListSize; - NTSTATUS Status; - - Pdo = (PDEVICE_OBJECT)Context; - DPRINT("SendStartDevice(%p)\n", Pdo); - - /* Create default resource list */ - ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); - AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize); - if (!AllocatedResources) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - AllocatedResources->Count = 1; - AllocatedResources->List[0].PartialResourceList.Version = 1; - AllocatedResources->List[0].PartialResourceList.Revision = 1; - AllocatedResources->List[0].PartialResourceList.Count = 3; - /* Data port */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Flags = 0; /* FIXME */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.HighPart = 0; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.LowPart = KEYBOARD_DATA_PORT; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1; - /* Control port */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Type = CmResourceTypePort; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition = CmResourceShareDeviceExclusive; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Flags = 0; /* FIXME */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.HighPart = 0; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.LowPart = KEYBOARD_CONTROL_PORT; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Length = 1; - /* Interrupt */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Type = CmResourceTypeInterrupt; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level = 0; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = KEYBOARD_IRQ; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1; - - /* Create default resource list translated */ - AllocatedResourcesTranslated = ExAllocatePool(PagedPool, ResourceListSize); - if (!AllocatedResources) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - RtlCopyMemory(AllocatedResourcesTranslated, AllocatedResources, ResourceListSize); - AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = HalGetInterruptVector( - Internal, 0, - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level, - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector, - (PKIRQL)&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level, - &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity); - - /* Send IRP_MN_START_DEVICE */ - TopDeviceObject = IoGetAttachedDeviceReference(Pdo); - KeInitializeEvent( - &Event, - NotificationEvent, - FALSE); - Irp = IoBuildSynchronousFsdRequest( - IRP_MJ_PNP, - TopDeviceObject, - NULL, - 0, - NULL, - &Event, - &IoStatusBlock); - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - Irp->IoStatus.Information = 0; - Stack = IoGetNextIrpStackLocation(Irp); - Stack->MinorFunction = IRP_MN_START_DEVICE; - Stack->Parameters.StartDevice.AllocatedResources = AllocatedResources; - Stack->Parameters.StartDevice.AllocatedResourcesTranslated = AllocatedResourcesTranslated; - Status = IoCallDriver(TopDeviceObject, Irp); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject( - &Event, - Executive, - KernelMode, - FALSE, - NULL); - Status = IoStatusBlock.Status; - } - if (!NT_SUCCESS(Status)) - { - DPRINT("IoCallDriver() failed with status 0x%08lx\n", Status); - goto cleanup; - } - -cleanup: - if (TopDeviceObject) - ObDereferenceObject(TopDeviceObject); - if (AllocatedResources) - ExFreePool(AllocatedResources); - if (AllocatedResourcesTranslated) - ExFreePool(AllocatedResourcesTranslated); -} - -static NTSTATUS -AddRegistryEntry( - IN PCWSTR PortTypeName, - IN PUNICODE_STRING DeviceName, - IN PCWSTR RegistryPath) -{ - UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP"); - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hDeviceMapKey = (HANDLE)-1; - HANDLE hPortKey = (HANDLE)-1; - UNICODE_STRING PortTypeNameU; - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - RtlInitUnicodeString(&PortTypeNameU, PortTypeName); - InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL); - Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - Status = STATUS_SUCCESS; - -cleanup: - if (hDeviceMapKey != (HANDLE)-1) - ZwClose(hDeviceMapKey); - if (hPortKey != (HANDLE)-1) - ZwClose(hPortKey); - return Status; -} - -NTSTATUS -i8042AddLegacyKeyboard( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath) -{ - UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042"); - PI8042_DEVICE_TYPE DeviceExtension = NULL; - PDEVICE_OBJECT Pdo = NULL; - NTSTATUS Status; - - DPRINT("i8042AddLegacyKeyboard()\n"); - - /* Create a named PDO */ - Status = IoCreateDevice( - DriverObject, - sizeof(I8042_DEVICE_TYPE), - &KeyboardName, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Pdo); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - /* Initialize device extension */ - DeviceExtension = (PI8042_DEVICE_TYPE)Pdo->DeviceExtension; - RtlZeroMemory(DeviceExtension, sizeof(I8042_DEVICE_TYPE)); - *DeviceExtension = PhysicalDeviceObject; - Pdo->Flags &= ~DO_DEVICE_INITIALIZING; - - /* Add FDO at the top of the PDO */ - Status = i8042AddDevice(DriverObject, Pdo); - if (!NT_SUCCESS(Status)) - { - DPRINT("i8042AddDevice() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - /* We will send the IRP_MN_START_DEVICE later, once kbdclass is loaded */ - AddRegistryEntry(L"KeyboardPort", &KeyboardName, RegistryPath->Buffer); - IoRegisterBootDriverReinitialization( - DriverObject, - SendStartDevice, - Pdo); - - Status = STATUS_SUCCESS; - -cleanup: - if (!NT_SUCCESS(Status)) - { - if (Pdo) - IoDeleteDevice(Pdo); - } - return Status; -} From a2d3c5fe3304e22922dc0f48d130c444b0b1517a Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 3 Oct 2006 19:55:15 +0000 Subject: [PATCH 445/488] - Implement the context menu (mouse only at the moment) makeing it accessable when the cursor over the item only - open the propsheet when double clicking child items - make 'properties' bold svn path=/trunk/; revision=24380 --- reactos/base/applications/devmgmt/En.rc | 4 +- .../base/applications/devmgmt/enumdevices.c | 12 +- reactos/base/applications/devmgmt/mainwnd.c | 201 +++++++++++------- reactos/base/applications/devmgmt/precomp.h | 5 +- 4 files changed, 133 insertions(+), 89 deletions(-) diff --git a/reactos/base/applications/devmgmt/En.rc b/reactos/base/applications/devmgmt/En.rc index 36913e20d75..9016db75c4e 100644 --- a/reactos/base/applications/devmgmt/En.rc +++ b/reactos/base/applications/devmgmt/En.rc @@ -8,7 +8,7 @@ BEGIN BEGIN MENUITEM "Print", IDC_PRINT, GRAYED MENUITEM SEPARATOR - MENUITEM "Properties...", IDC_PROP + MENUITEM "Properties", IDC_PROP MENUITEM SEPARATOR MENUITEM "Help", IDC_PROGHELP, GRAYED END @@ -30,7 +30,7 @@ IDR_POPUP MENU BEGIN POPUP "popup" BEGIN - MENUITEM "Properties...", IDC_PROP, GRAYED + MENUITEM "Properties", IDC_PROP MENUITEM SEPARATOR MENUITEM "Help", IDC_PROGHELP END diff --git a/reactos/base/applications/devmgmt/enumdevices.c b/reactos/base/applications/devmgmt/enumdevices.c index 186befa879c..da9e04a521c 100644 --- a/reactos/base/applications/devmgmt/enumdevices.c +++ b/reactos/base/applications/devmgmt/enumdevices.c @@ -9,10 +9,16 @@ #include "precomp.h" - static SP_CLASSIMAGELIST_DATA ImageListData; static HDEVINFO hDevInfo; + +VOID OpenPropSheet(HTREEITEM hItem) +{ + DisplayString(_T("Device Propsheet not yet implemented")); +} + + static HTREEITEM InsertIntoTreeView(HWND hTV, HTREEITEM hRoot, @@ -91,12 +97,12 @@ EnumDeviceClasses(INT ClassIndex, /* FIXME: can we do this? * Set the blank icon: IDI_SETUPAPI_BLANK = 41 * it'll be image 24 in the imagelist */ - *ClassImage = 41; + *ClassImage = 24; } /* Get device info for all devices of a particular class */ hDevInfo = SetupDiGetClassDevs(&ClassGuid, - 0, + NULL, NULL, DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) diff --git a/reactos/base/applications/devmgmt/mainwnd.c b/reactos/base/applications/devmgmt/mainwnd.c index 91cff10668f..a4eee455c94 100644 --- a/reactos/base/applications/devmgmt/mainwnd.c +++ b/reactos/base/applications/devmgmt/mainwnd.c @@ -11,6 +11,7 @@ static const TCHAR szMainWndClass[] = TEXT("DevMgmtWndClass"); + /* Toolbar buttons */ TBBUTTON Buttons [] = { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */ @@ -39,6 +40,7 @@ static const MENU_HINT MainMenuHintTable[] = { {IDC_PROGHELP, IDS_HINT_HELP}, {IDC_ABOUT, IDS_HINT_ABOUT} }; + /* system menu hints */ static const MENU_HINT SystemMenuHintTable[] = { {SC_RESTORE, IDS_HINT_SYS_RESTORE}, @@ -153,11 +155,11 @@ CreateTreeView(PMAIN_WND_INFO Info) Info->hTreeView = CreateWindowEx(0, WC_TREEVIEW, NULL, - WS_CHILD | WS_VISIBLE | WS_BORDER | - TVS_HASLINES | TVS_HASBUTTONS | TVS_SHOWSELALWAYS | TVS_LINESATROOT, + WS_CHILD | WS_VISIBLE | WS_BORDER | TVS_HASLINES | + TVS_HASBUTTONS | TVS_SHOWSELALWAYS | TVS_LINESATROOT, 0, 0, 0, 0, Info->hMainWnd, - (HMENU) IDC_TREEVIEW, + (HMENU)IDC_TREEVIEW, hInstance, NULL); if (Info->hTreeView == NULL) @@ -200,6 +202,7 @@ CreateStatusBar(PMAIN_WND_INFO Info) static VOID InitMainWnd(PMAIN_WND_INFO Info) { + HMENU hMenu; HTREEITEM hRoot; if (!CreateToolbar(Info)) @@ -214,18 +217,125 @@ InitMainWnd(PMAIN_WND_INFO Info) if (!CreateStatusBar(Info)) DisplayString(_T("error creating status bar")); + /* make 'properties' bold */ + hMenu = GetMenu(Info->hMainWnd); + hMenu = GetSubMenu(hMenu, 1); + SetMenuDefaultItem(hMenu, IDC_PROP, FALSE); + /* Create Popup Menu */ Info->hShortcutMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_POPUP)); Info->hShortcutMenu = GetSubMenu(Info->hShortcutMenu, 0); + SetMenuDefaultItem(Info->hShortcutMenu, IDC_PROP, FALSE); + /* emum all devices */ hRoot = InitTreeView(Info); if (hRoot) ListDevicesByType(Info, hRoot); } +static VOID +OnContext(PMAIN_WND_INFO Info, + LPARAM lParam) +{ + HTREEITEM hSelected; + POINT pt; + RECT rc; + + INT xPos = GET_X_LPARAM(lParam); + INT yPos = GET_Y_LPARAM(lParam); + + hSelected = TreeView_GetSelection(Info->hTreeView); + + if (TreeView_GetItemRect(Info->hTreeView, + hSelected, + &rc, + TRUE)) + { + if (GetCursorPos(&pt) && + ScreenToClient(Info->hTreeView, &pt) && + PtInRect(&rc, pt)) + { + TrackPopupMenuEx(Info->hShortcutMenu, + TPM_RIGHTBUTTON, + xPos, + yPos, + Info->hMainWnd, + NULL); + } + } +} + + +static VOID +OnNotify(PMAIN_WND_INFO Info, + LPARAM lParam) +{ + + LPNMHDR pnmhdr = (LPNMHDR)lParam; + + switch (pnmhdr->code) + { + case NM_DBLCLK: + { + HTREEITEM hSelected = TreeView_GetSelection(Info->hTreeView); + + if (!TreeView_GetChild(Info->hTreeView, + hSelected)) + { + OpenPropSheet(hSelected); + } + } + break; + + case NM_RCLICK: + { + TV_HITTESTINFO HitTest; + + if (GetCursorPos(&HitTest.pt) && + ScreenToClient(Info->hTreeView, &HitTest.pt)) + { + if (TreeView_HitTest(Info->hTreeView, &HitTest)) + TreeView_SelectItem(Info->hTreeView, HitTest.hItem); + } + } + break; + + case TTN_GETDISPINFO: + { + LPTOOLTIPTEXT lpttt; + UINT idButton; + + lpttt = (LPTOOLTIPTEXT)lParam; + + idButton = (UINT)lpttt->hdr.idFrom; + switch (idButton) + { + case IDC_PROP: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP); + break; + + case IDC_REFRESH: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH); + break; + + case IDC_PROGHELP: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_HELP); + break; + + case IDC_EXIT: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT); + break; + + } + } + break; + } +} + + static VOID MainWndCommand(PMAIN_WND_INFO Info, WORD CmdId, @@ -237,7 +347,8 @@ MainWndCommand(PMAIN_WND_INFO Info, { case IDC_PROP: { - // call builtin driver prop sheet + HTREEITEM hSelected = TreeView_GetSelection(Info->hTreeView); + OpenPropSheet(hSelected); } break; @@ -360,88 +471,14 @@ MainWndProc(HWND hwnd, case WM_NOTIFY: { - LPNMHDR pnmhdr = (LPNMHDR)lParam; - - switch (pnmhdr->code) - { - case NM_DBLCLK: - { - POINT pt; - RECT rect; - - GetCursorPos(&pt); - GetWindowRect(Info->hTreeView, &rect); - - if (PtInRect(&rect, pt)) - { - SendMessage(hwnd, - WM_COMMAND, - //ID_PROP, - MAKEWPARAM((WORD)IDC_PROP, (WORD)0), - 0); - } - - //OpenPropSheet(Info); - } - break; - - case TTN_GETDISPINFO: - { - LPTOOLTIPTEXT lpttt; - UINT idButton; - - lpttt = (LPTOOLTIPTEXT)lParam; - - /* Specify the resource identifier of the descriptive - * text for the given button. */ - idButton = (UINT)lpttt->hdr.idFrom; - switch (idButton) - { - case IDC_PROP: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP); - break; - - case IDC_REFRESH: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH); - break; - - case IDC_PROGHELP: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_HELP); - break; - - case IDC_EXIT: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT); - break; - - } - } - break; - } + OnNotify(Info, lParam); } break; case WM_CONTEXTMENU: - { - POINT pt; - RECT lvRect; - - INT xPos = GET_X_LPARAM(lParam); - INT yPos = GET_Y_LPARAM(lParam); - - GetCursorPos(&pt); - - /* display popup when cursor is in the list view */ - GetWindowRect(Info->hTreeView, &lvRect); - if (PtInRect(&lvRect, pt)) - { - TrackPopupMenuEx(Info->hShortcutMenu, - TPM_RIGHTBUTTON, - xPos, - yPos, - Info->hMainWnd, - NULL); - } - } + { + OnContext(Info, lParam); + } break; case WM_COMMAND: diff --git a/reactos/base/applications/devmgmt/precomp.h b/reactos/base/applications/devmgmt/precomp.h index a23f1bf8f0d..2c038a72843 100644 --- a/reactos/base/applications/devmgmt/precomp.h +++ b/reactos/base/applications/devmgmt/precomp.h @@ -15,7 +15,7 @@ #pragma warning(disable : 4100) #endif -#define MAX_DEV_LEN 1000 +#define MAX_DEV_LEN 256 typedef struct _MAIN_WND_INFO { @@ -36,7 +36,7 @@ typedef struct _MAIN_WND_INFO BOOL CALLBACK AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); -/* servman.c */ +/* devmgmt.c */ extern HINSTANCE hInstance; extern HANDLE ProcessHeap; @@ -53,6 +53,7 @@ HWND CreateMainWindow(LPCTSTR lpCaption, int nCmdShow); /* enumdevices.c */ +VOID OpenPropSheet(HTREEITEM hItem); HTREEITEM InitTreeView(PMAIN_WND_INFO Info); VOID ListDevicesByType(PMAIN_WND_INFO Info, HTREEITEM hRoot); From 99379a7e2ceef56697529b5cb7ff4a3b5e925c4b Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Tue, 3 Oct 2006 20:04:39 +0000 Subject: [PATCH 446/488] Fix warning svn path=/trunk/; revision=24381 --- reactos/base/applications/devmgmt/mainwnd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/applications/devmgmt/mainwnd.c b/reactos/base/applications/devmgmt/mainwnd.c index a4eee455c94..2a7c95c8281 100644 --- a/reactos/base/applications/devmgmt/mainwnd.c +++ b/reactos/base/applications/devmgmt/mainwnd.c @@ -298,7 +298,7 @@ OnNotify(PMAIN_WND_INFO Info, ScreenToClient(Info->hTreeView, &HitTest.pt)) { if (TreeView_HitTest(Info->hTreeView, &HitTest)) - TreeView_SelectItem(Info->hTreeView, HitTest.hItem); + (void)TreeView_SelectItem(Info->hTreeView, HitTest.hItem); } } break; From f1775cc055f4ef3ed4b9b52ea73bebf5f92d5e38 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 3 Oct 2006 20:51:35 +0000 Subject: [PATCH 447/488] fix processor display svn path=/trunk/; revision=24382 --- reactos/dll/cpl/sysdm/general.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index f8061ef38c1..158f4ab0c97 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -131,12 +131,12 @@ SetProcSpeed(HWND hwnd, { if (dwBuf < 1000) { - _stprintf(szBuf, _T("%lu MHz"), dwBuf); + _stprintf(szBuf, _T("%.2f MHz"), dwBuf); } else { double flt = dwBuf / 1000.0; - _stprintf(szBuf, _T("%l GHz"), flt); + _stprintf(szBuf, _T("%.2f GHz"), flt); } SetDlgItemText(hwnd, From 2ef79f3efe496509aa45d2fc6c704cd49fae56d9 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 3 Oct 2006 22:43:46 +0000 Subject: [PATCH 448/488] add LPCDLGTEMPLATE definition svn path=/trunk/; revision=24383 --- reactos/include/psdk/winuser.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reactos/include/psdk/winuser.h b/reactos/include/psdk/winuser.h index dfe2dcbb678..fc76526ca88 100644 --- a/reactos/include/psdk/winuser.h +++ b/reactos/include/psdk/winuser.h @@ -2631,6 +2631,13 @@ typedef struct { short cy; } DLGTEMPLATE,*LPDLGTEMPLATE,*LPDLGTEMPLATEA,*LPDLGTEMPLATEW; typedef const DLGTEMPLATE *LPCDLGTEMPLATE; +typedef const DLGTEMPLATE *LPCDLGTEMPLATEA; +typedef const DLGTEMPLATE *LPCDLGTEMPLATEW; +#ifdef UNICODE +typedef LPCDLGTEMPLATEW LPCDLGTEMPLATE; +#else +typedef LPCDLGTEMPLATEA LPCDLGTEMPLATE; +#endif // UNICODE #pragma pack(pop) typedef struct tagDRAWITEMSTRUCT { UINT CtlType; From ad0184614ea4211f844d3b032a1042600630773a Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 3 Oct 2006 22:46:26 +0000 Subject: [PATCH 449/488] update comctl32 to Wine-0.9.22 to get the new imagelist code. svn path=/trunk/; revision=24384 --- reactos/dll/win32/comctl32/comctl32.h | 1 + reactos/dll/win32/comctl32/comctl_Pl.rc | 5 + reactos/dll/win32/comctl32/commctrl.c | 61 +++ reactos/dll/win32/comctl32/header.c | 277 +++++-------- reactos/dll/win32/comctl32/imagelist.c | 5 +- reactos/dll/win32/comctl32/toolbar.c | 491 ++++++++++-------------- 6 files changed, 379 insertions(+), 461 deletions(-) diff --git a/reactos/dll/win32/comctl32/comctl32.h b/reactos/dll/win32/comctl32/comctl32.h index f6d233ff2fd..66a0973183c 100644 --- a/reactos/dll/win32/comctl32/comctl32.h +++ b/reactos/dll/win32/comctl32/comctl32.h @@ -143,6 +143,7 @@ extern COMCTL32_SysColor comctl32_color; HWND COMCTL32_CreateToolTip (HWND); VOID COMCTL32_RefreshSysColors(void); void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal); +void COMCTL32_EnsureBitmapSize(HBITMAP *pBitmap, int cxMinWidth, int cyMinHeight, COLORREF crBackground); INT Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen); BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc); BOOL Str_SetPtrWtoA (LPSTR *lppDest, LPCWSTR lpSrc); diff --git a/reactos/dll/win32/comctl32/comctl_Pl.rc b/reactos/dll/win32/comctl32/comctl_Pl.rc index 252c43eb1a3..91441344597 100644 --- a/reactos/dll/win32/comctl32/comctl_Pl.rc +++ b/reactos/dll/win32/comctl32/comctl_Pl.rc @@ -81,3 +81,8 @@ STRINGTABLE DISCARDABLE { IDS_SEPARATOR "Odstęp" } + +STRINGTABLE DISCARDABLE +{ + HKY_NONE "Brak" +} diff --git a/reactos/dll/win32/comctl32/commctrl.c b/reactos/dll/win32/comctl32/commctrl.c index 5cfc24cf844..81f5f86e000 100644 --- a/reactos/dll/win32/comctl32/commctrl.c +++ b/reactos/dll/win32/comctl32/commctrl.c @@ -1448,6 +1448,67 @@ void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark DeleteObject(hPen); } +/*********************************************************************** + * COMCTL32_EnsureBitmapSize [internal] + * + * If needed enlarge the bitmap so that the width is at least cxMinWidth + * the height is at least cyMinHeight. If the bitmap already have these + * dimensions nothing changes. + * + * PARAMS + * hBitmap [I/O] Bitmap to modify. The handle may change + * cxMinWidth [I] If the width of the bitmap is smaller then it will + * be enlarged to this value + * cyMinHeight [I] If the height of the bitmap is smaller then it will + * be enlarged to this value + * cyBackground [I] The color with which the new area will be filled + * + * RETURNS + * none + */ +void COMCTL32_EnsureBitmapSize(HBITMAP *pBitmap, int cxMinWidth, int cyMinHeight, COLORREF crBackground) +{ + int cxNew, cyNew; + BITMAP bmp; + HBITMAP hNewBitmap; + HBITMAP hNewDCBitmap, hOldDCBitmap; + HBRUSH hNewDCBrush; + HDC hdcNew, hdcOld; + + if (!GetObjectW(*pBitmap, sizeof(BITMAP), &bmp)) + return; + cxNew = (cxMinWidth > bmp.bmWidth ? cxMinWidth : bmp.bmWidth); + cyNew = (cyMinHeight > bmp.bmHeight ? cyMinHeight : bmp.bmHeight); + if (cxNew == bmp.bmWidth && cyNew == bmp.bmHeight) + return; + + hdcNew = CreateCompatibleDC(NULL); + hNewBitmap = CreateBitmap(cxNew, cyNew, bmp.bmPlanes, bmp.bmBitsPixel, NULL); + hNewDCBitmap = SelectObject(hdcNew, hNewBitmap); + hNewDCBrush = SelectObject(hdcNew, CreateSolidBrush(crBackground)); + + hdcOld = CreateCompatibleDC(NULL); + hOldDCBitmap = SelectObject(hdcOld, *pBitmap); + + BitBlt(hdcNew, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcOld, 0, 0, SRCCOPY); + if (bmp.bmWidth < cxMinWidth) + PatBlt(hdcNew, bmp.bmWidth, 0, cxNew, bmp.bmHeight, PATCOPY); + if (bmp.bmHeight < cyMinHeight) + PatBlt(hdcNew, 0, bmp.bmHeight, bmp.bmWidth, cyNew, PATCOPY); + if (bmp.bmWidth < cxMinWidth && bmp.bmHeight < cyMinHeight) + PatBlt(hdcNew, bmp.bmWidth, bmp.bmHeight, cxNew, cyNew, PATCOPY); + + SelectObject(hdcNew, hNewDCBitmap); + DeleteObject(SelectObject(hdcNew, hNewDCBrush)); + DeleteDC(hdcNew); + SelectObject(hdcOld, hOldDCBitmap); + DeleteDC(hdcOld); + + DeleteObject(*pBitmap); + *pBitmap = hNewBitmap; + return; +} + /*********************************************************************** * MirrorIcon [COMCTL32.414] * diff --git a/reactos/dll/win32/comctl32/header.c b/reactos/dll/win32/comctl32/header.c index 41c4071ca81..1d4f1fdb5e7 100644 --- a/reactos/dll/win32/comctl32/header.c +++ b/reactos/dll/win32/comctl32/header.c @@ -4,6 +4,7 @@ * Copyright 1998 Eric Kohl * Copyright 2000 Eric Kohl for CodeWeavers * Copyright 2003 Maxime Bellenge + * Copyright 2006 Mikolaj Zalewski * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,15 +21,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * TODO: - * - Imagelist support (partially). - * - Callback items (under construction). - * - Hottrack support (partially). - * - Custom draw support (including Notifications). - * - Drag and Drop support (including Notifications). - * - New messages. - * - Use notification format - * - Correct the order maintenance code to preserve valid order - * + * - Imagelist support (completed?) + * - Hottrack support (completed?) + * - Custom draw support (completed?) + * - Filters support (HDS_FILTER, HDI_FILTER, HDM_*FILTER*, HDN_*FILTER*) + * - New Windows Vista features */ #include @@ -84,7 +81,6 @@ typedef struct INT iMoveItem; /* index of tracked item. (Tracking mode) */ INT xTrackOffset; /* distance between the right side of the tracked item and the cursor */ INT xOldTrack; /* track offset (see above) after the last WM_MOUSEMOVE */ - INT nOldWidth; /* width of a sizing item after the last WM_MOUSEMOVE */ INT iHotItem; /* index of hot item (cursor is over this item) */ INT iHotDivider; /* index of the hot divider (used while dragging an item or by HDM_SETHOTDIVIDER) */ INT iMargin; /* width of the margin that surrounds a bitmap */ @@ -802,32 +798,11 @@ HEADER_SendSimpleNotify (HWND hwnd, UINT code) } static BOOL -HEADER_SendHeaderNotifyT (HWND hwnd, UINT code, INT iItem, INT mask, HDITEMW *lpItem) +HEADER_SendNotifyWithHDItemT(HWND hwnd, UINT code, INT iItem, HDITEMW *lpItem) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); NMHEADERW nmhdr; - HDITEMW nmitem; - if (lpItem == NULL) - { - /* lpItem == NULL means that we should take the actual data from the item */ - if (mask & HDI_TEXT) - { - FIXME("(): invalid parameters - lpItem == NULL and (mask & HDI_TEXT)\n"); - mask &= ~HDI_TEXT; - } - nmitem.mask = mask; - nmitem.cxy = infoPtr->items[iItem].cxy; - nmitem.hbm = infoPtr->items[iItem].hbm; - nmitem.pszText = NULL; - nmitem.cchTextMax = 0; - nmitem.fmt = infoPtr->items[iItem].fmt; - nmitem.lParam = infoPtr->items[iItem].lParam; - nmitem.iOrder = infoPtr->items[iItem].iOrder; - nmitem.iImage = infoPtr->items[iItem].iImage; - lpItem = &nmitem; - } - nmhdr.hdr.hwndFrom = hwnd; nmhdr.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID); nmhdr.hdr.code = (infoPtr->nNotifyFormat == NFR_UNICODE ? code : HEADER_NotifyCodeWtoA(code)); @@ -839,6 +814,38 @@ HEADER_SendHeaderNotifyT (HWND hwnd, UINT code, INT iItem, INT mask, HDITEMW *lp (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr); } +static BOOL +HEADER_SendNotifyWithIntFieldT(HWND hwnd, UINT code, INT iItem, INT mask, INT iValue) +{ + HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); + HDITEMW nmitem; + + /* copying only the iValue should be ok but to make the code more robust we copy everything */ + nmitem.cxy = infoPtr->items[iItem].cxy; + nmitem.hbm = infoPtr->items[iItem].hbm; + nmitem.pszText = NULL; + nmitem.cchTextMax = 0; + nmitem.fmt = infoPtr->items[iItem].fmt; + nmitem.lParam = infoPtr->items[iItem].lParam; + nmitem.iOrder = infoPtr->items[iItem].iOrder; + nmitem.iImage = infoPtr->items[iItem].iImage; + + nmitem.mask = mask; + switch (mask) + { + case HDI_WIDTH: + nmitem.cxy = iValue; + break; + case HDI_ORDER: + nmitem.iOrder = iValue; + break; + default: + ERR("invalid mask value 0x%x\n", iValue); + } + + return HEADER_SendNotifyWithHDItemT(hwnd, code, iItem, &nmitem); +} + /** * Prepare callback items * depends on NMHDDISPINFOW having same structure as NMHDDISPINFOA @@ -952,23 +959,6 @@ HEADER_FreeCallbackItems(HEADER_ITEM *lpItem) lpItem->iImage = I_IMAGECALLBACK; } -static BOOL -HEADER_SendClickNotify (HWND hwnd, UINT code, INT iItem) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - NMHEADERA nmhdr; - - nmhdr.hdr.hwndFrom = hwnd; - nmhdr.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID); - nmhdr.hdr.code = code; - nmhdr.iItem = iItem; - nmhdr.iButton = 0; - nmhdr.pitem = NULL; - - return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, - (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr); -} - static LRESULT HEADER_CreateDragImage (HWND hwnd, WPARAM wParam) { @@ -1060,67 +1050,40 @@ HEADER_DeleteItem (HWND hwnd, WPARAM wParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd); INT iItem = (INT)wParam; + INT iOrder; + INT i; TRACE("[iItem=%d]\n", iItem); if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem)) return FALSE; - if (infoPtr->uNumItem == 1) { - TRACE("Simple delete!\n"); - HEADER_DisposeItem(&infoPtr->items[0]); - Free (infoPtr->items); - Free(infoPtr->order); - infoPtr->items = 0; - infoPtr->order = 0; - infoPtr->uNumItem = 0; - } - else { - HEADER_ITEM *oldItems = infoPtr->items; - INT i; - INT iOrder; - TRACE("Complex delete! [iItem=%d]\n", iItem); - - for (i = 0; i < infoPtr->uNumItem; i++) - TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder); - HEADER_DisposeItem(&infoPtr->items[iItem]); - iOrder = infoPtr->items[iItem].iOrder; - - infoPtr->uNumItem--; - infoPtr->items = Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem); - /* pre delete copy */ - if (iItem > 0) { - memcpy (&infoPtr->items[0], &oldItems[0], - iItem * sizeof(HEADER_ITEM)); - } - - /* post delete copy */ - if (iItem < infoPtr->uNumItem) { - memcpy (&infoPtr->items[iItem], &oldItems[iItem+1], - (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM)); - } - - /* Correct the orders */ - if (iOrder < infoPtr->uNumItem) - { - memmove(&infoPtr->order[iOrder], &infoPtr->order[iOrder + 1], - (infoPtr->uNumItem - iOrder) * sizeof(INT)); - for (i = 0; i < infoPtr->uNumItem; i++) - { - if (infoPtr->order[i] > iItem) - infoPtr->order[i]--; - if (i >= iOrder) - infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i]; - } - } - - for (i = 0; i < infoPtr->uNumItem; i++) - TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder); - Free (oldItems); + for (i = 0; i < infoPtr->uNumItem; i++) + TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder); + + iOrder = infoPtr->items[iItem].iOrder; + HEADER_DisposeItem(&infoPtr->items[iItem]); + + infoPtr->uNumItem--; + memmove(&infoPtr->items[iItem], &infoPtr->items[iItem + 1], + (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM)); + memmove(&infoPtr->order[iOrder], &infoPtr->order[iOrder + 1], + (infoPtr->uNumItem - iOrder) * sizeof(INT)); + infoPtr->items = ReAlloc(infoPtr->items, sizeof(HEADER_ITEM) * infoPtr->uNumItem); + infoPtr->order = ReAlloc(infoPtr->order, sizeof(INT) * infoPtr->uNumItem); + + /* Correct the orders */ + for (i = 0; i < infoPtr->uNumItem; i++) + { + if (infoPtr->order[i] > iItem) + infoPtr->order[i]--; + if (i >= iOrder) + infoPtr->items[infoPtr->order[i]].iOrder = i; } + for (i = 0; i < infoPtr->uNumItem; i++) + TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder); HEADER_SetItemBounds (hwnd); - InvalidateRect(hwnd, NULL, FALSE); return TRUE; @@ -1299,51 +1262,23 @@ HEADER_InsertItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) else if (infoPtr->uNumItem < iOrder) iOrder = infoPtr->uNumItem; - if (infoPtr->uNumItem == 0) { - infoPtr->items = Alloc (sizeof (HEADER_ITEM)); - infoPtr->order = Alloc(sizeof(INT)); - infoPtr->uNumItem++; - } - else { - HEADER_ITEM *oldItems = infoPtr->items; - INT *oldOrder = infoPtr->order; - - infoPtr->uNumItem++; - infoPtr->items = Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem); - if (nItem == 0) { - memcpy (&infoPtr->items[1], &oldItems[0], - (infoPtr->uNumItem-1) * sizeof(HEADER_ITEM)); - } - else - { - /* pre insert copy */ - if (nItem > 0) { - memcpy (&infoPtr->items[0], &oldItems[0], - nItem * sizeof(HEADER_ITEM)); - } - - /* post insert copy */ - if (nItem < infoPtr->uNumItem - 1) { - memcpy (&infoPtr->items[nItem+1], &oldItems[nItem], - (infoPtr->uNumItem - nItem - 1) * sizeof(HEADER_ITEM)); - } - } - - infoPtr->order = Alloc(sizeof(INT) * infoPtr->uNumItem); - memcpy(infoPtr->order, oldOrder, iOrder * sizeof(INT)); - infoPtr->order[iOrder] = nItem; - memcpy(&infoPtr->order[iOrder + 1], &oldOrder[iOrder], - (infoPtr->uNumItem - iOrder - 1) * sizeof(INT)); - - Free (oldItems); - Free(oldOrder); - } + infoPtr->uNumItem++; + infoPtr->items = ReAlloc(infoPtr->items, sizeof(HEADER_ITEM) * infoPtr->uNumItem); + infoPtr->order = ReAlloc(infoPtr->order, sizeof(INT) * infoPtr->uNumItem); + + /* make space for the new item */ + memmove(&infoPtr->items[nItem + 1], &infoPtr->items[nItem], + (infoPtr->uNumItem - nItem - 1) * sizeof(HEADER_ITEM)); + memmove(&infoPtr->order[iOrder + 1], &infoPtr->order[iOrder], + (infoPtr->uNumItem - iOrder - 1) * sizeof(INT)); + /* update the order array */ + infoPtr->order[iOrder] = nItem; for (i = 0; i < infoPtr->uNumItem; i++) { if (i != iOrder && infoPtr->order[i] >= nItem) infoPtr->order[i]++; - infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i]; + infoPtr->items[infoPtr->order[i]].iOrder = i; } lpItem = &infoPtr->items[nItem]; @@ -1351,6 +1286,7 @@ HEADER_InsertItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) /* cxy, fmt and lParam are copied even if not in the HDITEM mask */ copyMask = phdi->mask | HDI_WIDTH | HDI_FORMAT | HDI_LPARAM; HEADER_StoreHDItemInHeader(lpItem, copyMask, phdi, bUnicode); + lpItem->iOrder = iOrder; /* set automatically some format bits */ if (phdi->mask & HDI_TEXT) @@ -1366,10 +1302,7 @@ HEADER_InsertItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) if (phdi->mask & HDI_IMAGE) lpItem->fmt |= HDF_IMAGE; - lpItem->iOrder = iOrder; - HEADER_SetItemBounds (hwnd); - InvalidateRect(hwnd, NULL, FALSE); return nItem; @@ -1456,7 +1389,7 @@ HEADER_SetItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) TRACE("[nItem=%d]\n", nItem); HEADER_CopyHDItemForNotify(infoPtr, &hdNotify, phdi, bUnicode, &pvScratch); - if (HEADER_SendHeaderNotifyT (hwnd, HDN_ITEMCHANGINGW, nItem, phdi->mask, &hdNotify)) + if (HEADER_SendNotifyWithHDItemT(hwnd, HDN_ITEMCHANGINGW, nItem, &hdNotify)) { if (pvScratch) Free(pvScratch); return FALSE; @@ -1469,7 +1402,7 @@ HEADER_SetItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) if (phdi->iOrder >= 0 && phdi->iOrder < infoPtr->uNumItem) HEADER_ChangeItemOrder(infoPtr, nItem, phdi->iOrder); - HEADER_SendHeaderNotifyT (hwnd, HDN_ITEMCHANGEDW, nItem, phdi->mask, &hdNotify); + HEADER_SendNotifyWithHDItemT(hwnd, HDN_ITEMCHANGEDW, nItem, &hdNotify); HEADER_SetItemBounds (hwnd); @@ -1597,9 +1530,9 @@ HEADER_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam) HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem); if ((GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS) && (flags == HHT_ONHEADER)) - HEADER_SendHeaderNotifyT (hwnd, HDN_ITEMDBLCLICKW, nItem, 0, NULL); + HEADER_SendNotifyWithHDItemT(hwnd, HDN_ITEMDBLCLICKW, nItem, NULL); else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) - HEADER_SendHeaderNotifyT (hwnd, HDN_DIVIDERDBLCLICKW, nItem, 0, NULL); + HEADER_SendNotifyWithHDItemT(hwnd, HDN_DIVIDERDBLCLICKW, nItem, NULL); return 0; } @@ -1637,12 +1570,13 @@ HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam) TRACE("Pressed item %d!\n", nItem); } else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) { - if (!(HEADER_SendHeaderNotifyT (hwnd, HDN_BEGINTRACKW, nItem, HDI_WIDTH, NULL))) { + INT iCurrWidth = infoPtr->items[nItem].cxy; + if (!HEADER_SendNotifyWithIntFieldT(hwnd, HDN_BEGINTRACKW, nItem, HDI_WIDTH, iCurrWidth)) + { SetCapture (hwnd); infoPtr->bCaptured = TRUE; infoPtr->bTracking = TRUE; infoPtr->iMoveItem = nItem; - infoPtr->nOldWidth = infoPtr->items[nItem].cxy; infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x; if (!(dwStyle & HDS_FULLDRAG)) { @@ -1667,7 +1601,7 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE); POINT pt; UINT flags; - INT nItem, nWidth; + INT nItem; HDC hdc; pt.x = (INT)(SHORT)LOWORD(lParam); @@ -1695,9 +1629,8 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) iNewOrder--; } - /* FIXME: the new order field should be sent, not the old one */ if (iNewOrder != -1 && - !HEADER_SendHeaderNotifyT(hwnd, HDN_ENDDRAG, infoPtr->iMoveItem, HDI_ORDER, NULL)) + !HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ENDDRAG, infoPtr->iMoveItem, HDI_ORDER, iNewOrder)) { HEADER_ChangeItemOrder(infoPtr, infoPtr->iMoveItem, iNewOrder); infoPtr->bRectsValid = FALSE; @@ -1715,17 +1648,20 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem); ReleaseDC (hwnd, hdc); - HEADER_SendClickNotify (hwnd, HDN_ITEMCLICKA, infoPtr->iMoveItem); + HEADER_SendNotifyWithHDItemT(hwnd, HDN_ITEMCLICKW, infoPtr->iMoveItem, NULL); } TRACE("Released item %d!\n", infoPtr->iMoveItem); infoPtr->bPressed = FALSE; } else if (infoPtr->bTracking) { + INT iNewWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset; + if (iNewWidth < 0) + iNewWidth = 0; TRACE("End tracking item %d!\n", infoPtr->iMoveItem); infoPtr->bTracking = FALSE; - HEADER_SendHeaderNotifyT (hwnd, HDN_ENDTRACKW, infoPtr->iMoveItem, HDI_WIDTH, NULL); + HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ENDTRACKW, infoPtr->iMoveItem, HDI_WIDTH, iNewWidth); if (!(dwStyle & HDS_FULLDRAG)) { hdc = GetDC (hwnd); @@ -1733,20 +1669,14 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) ReleaseDC (hwnd, hdc); } - if (HEADER_SendHeaderNotifyT(hwnd, HDN_ITEMCHANGINGW, infoPtr->iMoveItem, HDI_WIDTH, NULL)) - { - infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth; - } - else { - nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset; - if (nWidth < 0) - nWidth = 0; - infoPtr->items[infoPtr->iMoveItem].cxy = nWidth; + if (!HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ITEMCHANGINGW, infoPtr->iMoveItem, HDI_WIDTH, iNewWidth)) + { + infoPtr->items[infoPtr->iMoveItem].cxy = iNewWidth; + HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ITEMCHANGEDW, infoPtr->iMoveItem, HDI_WIDTH, iNewWidth); } HEADER_SetItemBounds (hwnd); InvalidateRect(hwnd, NULL, TRUE); - HEADER_SendHeaderNotifyT(hwnd, HDN_ITEMCHANGEDW, infoPtr->iMoveItem, HDI_WIDTH, NULL); } if (infoPtr->bCaptured) { @@ -1826,7 +1756,7 @@ HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) if (infoPtr->bPressed && !infoPtr->bDragging && dwStyle&HDS_DRAGDROP && HEADER_IsDragDistance(infoPtr, &pt)) { - if (!HEADER_SendHeaderNotifyT(hwnd, HDN_BEGINDRAG, infoPtr->iMoveItem, 0, NULL)) + if (!HEADER_SendNotifyWithHDItemT(hwnd, HDN_BEGINDRAG, infoPtr->iMoveItem, NULL)) { HIMAGELIST hDragItem = (HIMAGELIST)HEADER_CreateDragImage(hwnd, infoPtr->iMoveItem); if (hDragItem != NULL) @@ -1867,14 +1797,14 @@ HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) } else if (infoPtr->bTracking) { if (dwStyle & HDS_FULLDRAG) { - if (!HEADER_SendHeaderNotifyT (hwnd, HDN_ITEMCHANGINGW, infoPtr->iMoveItem, HDI_WIDTH, NULL)) + HEADER_ITEM *lpItem = &infoPtr->items[infoPtr->iMoveItem]; + nWidth = pt.x - lpItem->rect.left + infoPtr->xTrackOffset; + if (!HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ITEMCHANGINGW, infoPtr->iMoveItem, HDI_WIDTH, nWidth)) { - HEADER_ITEM *lpItem = &infoPtr->items[infoPtr->iMoveItem]; INT nOldWidth = lpItem->rect.right - lpItem->rect.left; RECT rcClient; RECT rcScroll; - nWidth = pt.x - lpItem->rect.left + infoPtr->xTrackOffset; if (nWidth < 0) nWidth = 0; infoPtr->items[infoPtr->iMoveItem].cxy = nWidth; HEADER_SetItemBounds(hwnd); @@ -1886,20 +1816,21 @@ HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) InvalidateRect(hwnd, &lpItem->rect, FALSE); UpdateWindow(hwnd); - HEADER_SendHeaderNotifyT(hwnd, HDN_ITEMCHANGEDW, infoPtr->iMoveItem, HDI_WIDTH, NULL); + HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ITEMCHANGEDW, infoPtr->iMoveItem, HDI_WIDTH, nWidth); } } else { + INT iTrackWidth; hdc = GetDC (hwnd); HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack); infoPtr->xOldTrack = pt.x + infoPtr->xTrackOffset; if (infoPtr->xOldTrack < infoPtr->items[infoPtr->iMoveItem].rect.left) infoPtr->xOldTrack = infoPtr->items[infoPtr->iMoveItem].rect.left; - infoPtr->items[infoPtr->iMoveItem].cxy = - infoPtr->xOldTrack - infoPtr->items[infoPtr->iMoveItem].rect.left; HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack); ReleaseDC (hwnd, hdc); - HEADER_SendHeaderNotifyT (hwnd, HDN_TRACKW, infoPtr->iMoveItem, HDI_WIDTH, NULL); + iTrackWidth = infoPtr->xOldTrack - infoPtr->items[infoPtr->iMoveItem].rect.left; + /* FIXME: should stop tracking if HDN_TRACK returnes TRUE */ + HEADER_SendNotifyWithIntFieldT(hwnd, HDN_TRACKW, infoPtr->iMoveItem, HDI_WIDTH, iTrackWidth); } TRACE("Tracking item %d!\n", infoPtr->iMoveItem); diff --git a/reactos/dll/win32/comctl32/imagelist.c b/reactos/dll/win32/comctl32/imagelist.c index cc3078ea463..faf537183bb 100644 --- a/reactos/dll/win32/comctl32/imagelist.c +++ b/reactos/dll/win32/comctl32/imagelist.c @@ -2546,11 +2546,12 @@ ImageList_SetImageCount (HIMAGELIST himl, UINT iImageCount) if (!is_valid(himl)) return FALSE; - if (himl->cCurImage >= iImageCount) - return FALSE; + if (iImageCount < 0) + return FALSE; if (himl->cMaxImage > iImageCount) { himl->cCurImage = iImageCount; + /* TODO: shrink the bitmap when cMaxImage-cCurImage>cGrow ? */ return TRUE; } diff --git a/reactos/dll/win32/comctl32/toolbar.c b/reactos/dll/win32/comctl32/toolbar.c index 108bf048f12..9de8e768798 100644 --- a/reactos/dll/win32/comctl32/toolbar.c +++ b/reactos/dll/win32/comctl32/toolbar.c @@ -250,6 +250,7 @@ static HIMAGELIST TOOLBAR_InsertImageList(PIMLENTRY **pies, INT *cies, HIMAGELIS static LRESULT TOOLBAR_LButtonDown(HWND hwnd, WPARAM wParam, LPARAM lParam); static void TOOLBAR_SetHotItemEx (TOOLBAR_INFO *infoPtr, INT nHit, DWORD dwReason); static LRESULT TOOLBAR_AutoSize(HWND hwnd); +static void TOOLBAR_CheckImageListIconSize(TOOLBAR_INFO *infoPtr); static LRESULT TOOLBAR_NotifyFormat(TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam); @@ -1091,6 +1092,9 @@ TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps) TOOLBAR_DumpToolbar (infoPtr, __LINE__); + /* change the imagelist icon size if we manage the list and it is necessary */ + TOOLBAR_CheckImageListIconSize(infoPtr); + /* Send initial notify */ ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW)); tbcd.nmcd.dwDrawStage = CDDS_PREPAINT; @@ -2568,6 +2572,101 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } } +static BOOL +TOOLBAR_AddBitmapToImageList(TOOLBAR_INFO *infoPtr, HIMAGELIST himlDef, const TBITMAP_INFO *bitmap) +{ + HBITMAP hbmLoad; + INT nCountBefore = ImageList_GetImageCount(himlDef); + INT nCountAfter; + INT cxIcon, cyIcon; + INT nAdded; + INT nIndex; + + TRACE("adding hInst=%p nID=%d nButtons=%d\n", bitmap->hInst, bitmap->nID, bitmap->nButtons); + /* Add bitmaps to the default image list */ + if (bitmap->hInst == NULL) /* a handle was passed */ + { + BITMAP bmp; + HBITMAP hOldBitmapBitmap, hOldBitmapLoad; + HDC hdcImage, hdcBitmap; + + /* copy the bitmap before adding it so that the user's bitmap + * doesn't get modified. + */ + GetObjectW ((HBITMAP)bitmap->nID, sizeof(BITMAP), (LPVOID)&bmp); + + hdcImage = CreateCompatibleDC(0); + hdcBitmap = CreateCompatibleDC(0); + + /* create new bitmap */ + hbmLoad = CreateBitmap (bmp.bmWidth, bmp.bmHeight, bmp.bmPlanes, bmp.bmBitsPixel, NULL); + hOldBitmapBitmap = SelectObject(hdcBitmap, (HBITMAP)bitmap->nID); + hOldBitmapLoad = SelectObject(hdcImage, hbmLoad); + + /* Copy the user's image */ + BitBlt (hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, + hdcBitmap, 0, 0, SRCCOPY); + + SelectObject (hdcImage, hOldBitmapLoad); + SelectObject (hdcBitmap, hOldBitmapBitmap); + DeleteDC (hdcImage); + DeleteDC (hdcBitmap); + } + else + hbmLoad = CreateMappedBitmap(bitmap->hInst, bitmap->nID, 0, NULL, 0); + + /* enlarge the bitmap if needed */ + ImageList_GetIconSize(himlDef, &cxIcon, &cyIcon); + COMCTL32_EnsureBitmapSize(&hbmLoad, cxIcon*(INT)bitmap->nButtons, cyIcon, comctl32_color.clrBtnFace); + + nIndex = ImageList_AddMasked(himlDef, hbmLoad, comctl32_color.clrBtnFace); + DeleteObject(hbmLoad); + if (nIndex == -1) + return FALSE; + + nCountAfter = ImageList_GetImageCount(himlDef); + nAdded = nCountAfter - nCountBefore; + if (bitmap->nButtons == 0) /* wParam == 0 is special and means add only one image */ + { + ImageList_SetImageCount(himlDef, nCountBefore + 1); + } else if (nAdded > (INT)bitmap->nButtons) { + TRACE("Added more images than wParam: Previous image number %i added %i while wParam %i. Images in list %i\n", + nCountBefore, nAdded, bitmap->nButtons, nCountAfter); + } + + infoPtr->nNumBitmaps += nAdded; + return TRUE; +} + +static void +TOOLBAR_CheckImageListIconSize(TOOLBAR_INFO *infoPtr) +{ + HIMAGELIST himlDef; + HIMAGELIST himlNew; + INT cx, cy; + INT i; + + himlDef = GETDEFIMAGELIST(infoPtr, 0); + if (himlDef == NULL || himlDef != infoPtr->himlInt) + return; + if (!ImageList_GetIconSize(himlDef, &cx, &cy)) + return; + if (cx == infoPtr->nBitmapWidth && cy == infoPtr->nBitmapHeight) + return; + + TRACE("Update icon size: %dx%d -> %dx%d\n", + cx, cy, infoPtr->nBitmapWidth, infoPtr->nBitmapHeight); + + himlNew = ImageList_Create(infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, + ILC_COLORDDB|ILC_MASK, 8, 2); + for (i = 0; i < infoPtr->nNumBitmapInfos; i++) + TOOLBAR_AddBitmapToImageList(infoPtr, himlNew, &infoPtr->bitmaps[i]); + TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlNew, 0); + infoPtr->himlInt = himlNew; + + infoPtr->nNumBitmaps -= ImageList_GetImageCount(himlDef); + ImageList_Destroy(himlDef); +} /*********************************************************************** * TOOLBAR_AddBitmap: Add the bitmaps to the default image list. @@ -2578,8 +2677,8 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) { TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam; - INT nIndex = 0, nButtons, nCount; - HBITMAP hbmLoad; + TBITMAP_INFO info; + INT iSumButtons, i; HIMAGELIST himlDef; TRACE("hwnd=%p wParam=%x lParam=%lx\n", hwnd, wParam, lParam); @@ -2588,16 +2687,38 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) if (lpAddBmp->hInst == HINST_COMMCTRL) { - if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR) - nButtons = 15; - else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR) - nButtons = 13; - else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR) - nButtons = 5; - else - return -1; + info.hInst = COMCTL32_hModule; + switch (lpAddBmp->nID) + { + case IDB_STD_SMALL_COLOR: + info.nButtons = 15; + info.nID = IDB_STD_SMALL; + break; + case IDB_STD_LARGE_COLOR: + info.nButtons = 15; + info.nID = IDB_STD_LARGE; + break; + case IDB_VIEW_SMALL_COLOR: + info.nButtons = 12; + info.nID = IDB_VIEW_SMALL; + break; + case IDB_VIEW_LARGE_COLOR: + info.nButtons = 12; + info.nID = IDB_VIEW_LARGE; + break; + case IDB_HIST_SMALL_COLOR: + info.nButtons = 5; + info.nID = IDB_HIST_SMALL; + break; + case IDB_HIST_LARGE_COLOR: + info.nButtons = 5; + info.nID = IDB_HIST_LARGE; + break; + default: + return -1; + } - TRACE ("adding %d internal bitmaps!\n", nButtons); + TRACE ("adding %d internal bitmaps!\n", info.nButtons); /* Windows resize all the buttons to the size of a newly added standard image */ if (lpAddBmp->nID & 1) @@ -2624,11 +2745,20 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) } else { - nButtons = (INT)wParam; - if (nButtons <= 0) - return -1; - - TRACE ("adding %d bitmaps!\n", nButtons); + info.nButtons = (INT)wParam; + info.hInst = lpAddBmp->hInst; + info.nID = lpAddBmp->nID; + TRACE("adding %d bitmaps!\n", info.nButtons); + } + + /* check if the bitmap is already loaded and compute iSumButtons */ + iSumButtons = 0; + for (i = 0; i < infoPtr->nNumBitmapInfos; i++) + { + if (infoPtr->bitmaps[i].hInst == info.hInst && + infoPtr->bitmaps[i].nID == info.nID) + return iSumButtons; + iSumButtons += infoPtr->bitmaps[i].nButtons; } if (!infoPtr->cimlDef) { @@ -2636,7 +2766,7 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) TRACE ("creating default image list!\n"); himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, - ILC_COLORDDB | ILC_MASK, nButtons, 2); + ILC_COLORDDB | ILC_MASK, info.nButtons, 2); TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlDef, 0); infoPtr->himlInt = himlDef; } @@ -2649,145 +2779,17 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) return -1; } - nCount = ImageList_GetImageCount(himlDef); - - /* Add bitmaps to the default image list */ - if (lpAddBmp->hInst == NULL) - { - BITMAP bmp; - HBITMAP hOldBitmapBitmap, hOldBitmapLoad; - HDC hdcImage, hdcBitmap; - - /* copy the bitmap before adding it so that the user's bitmap - * doesn't get modified. - */ - GetObjectW ((HBITMAP)lpAddBmp->nID, sizeof(BITMAP), (LPVOID)&bmp); - - hdcImage = CreateCompatibleDC(0); - hdcBitmap = CreateCompatibleDC(0); - - /* create new bitmap */ - hbmLoad = CreateBitmap (bmp.bmWidth, bmp.bmHeight, bmp.bmPlanes, bmp.bmBitsPixel, NULL); - hOldBitmapBitmap = SelectObject(hdcBitmap, (HBITMAP)lpAddBmp->nID); - hOldBitmapLoad = SelectObject(hdcImage, hbmLoad); - - /* Copy the user's image */ - BitBlt (hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, - hdcBitmap, 0, 0, SRCCOPY); - - SelectObject (hdcImage, hOldBitmapLoad); - SelectObject (hdcBitmap, hOldBitmapBitmap); - DeleteDC (hdcImage); - DeleteDC (hdcBitmap); - - nIndex = ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - } - else if (lpAddBmp->hInst == HINST_COMMCTRL) - { - /* Add system bitmaps */ - switch (lpAddBmp->nID) - { - case IDB_STD_SMALL_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_STD_SMALL, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_STD_LARGE_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_STD_LARGE, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_VIEW_SMALL_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_VIEW_SMALL, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_VIEW_LARGE_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_VIEW_LARGE, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_HIST_SMALL_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_HIST_SMALL, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_HIST_LARGE_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_HIST_LARGE, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - default: - nIndex = ImageList_GetImageCount (himlDef); - ERR ("invalid imagelist!\n"); - break; - } - } - else - { - hbmLoad = CreateMappedBitmap(lpAddBmp->hInst, lpAddBmp->nID, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - } + if (!TOOLBAR_AddBitmapToImageList(infoPtr, himlDef, &info)) + return -1; TRACE("Number of bitmap infos: %d\n", infoPtr->nNumBitmapInfos); - - if (infoPtr->nNumBitmapInfos == 0) - { - infoPtr->bitmaps = Alloc(sizeof(TBITMAP_INFO)); - } - else - { - TBITMAP_INFO *oldBitmaps = infoPtr->bitmaps; - infoPtr->bitmaps = Alloc((infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO)); - memcpy(&infoPtr->bitmaps[0], &oldBitmaps[0], infoPtr->nNumBitmapInfos * sizeof(TBITMAP_INFO)); - } - - infoPtr->bitmaps[infoPtr->nNumBitmapInfos].nButtons = nButtons; - infoPtr->bitmaps[infoPtr->nNumBitmapInfos].hInst = lpAddBmp->hInst; - infoPtr->bitmaps[infoPtr->nNumBitmapInfos].nID = lpAddBmp->nID; - + infoPtr->bitmaps = ReAlloc(infoPtr->bitmaps, (infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO)); + infoPtr->bitmaps[infoPtr->nNumBitmapInfos] = info; infoPtr->nNumBitmapInfos++; TRACE("Number of bitmap infos: %d\n", infoPtr->nNumBitmapInfos); - if (nIndex != -1) - { - INT imagecount = ImageList_GetImageCount(himlDef); - - if (infoPtr->nNumBitmaps + nButtons != imagecount) - { - WARN("Desired images do not match received images : Previous image number %i Previous images in list %i added %i expecting total %i, Images in list %i\n", - infoPtr->nNumBitmaps, nCount, imagecount - nCount, - infoPtr->nNumBitmaps+nButtons,imagecount); - - infoPtr->nNumBitmaps = imagecount; - } - else - infoPtr->nNumBitmaps += nButtons; - } - InvalidateRect(hwnd, NULL, TRUE); - - return nIndex; + return iSumButtons; } @@ -2929,64 +2931,57 @@ TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam) +TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam) { +#define MAX_RESOURCE_STRING_LENGTH 512 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); - INT nIndex; + INT nIndex = infoPtr->nNumStrings; if ((wParam) && (HIWORD(lParam) == 0)) { - char szString[256]; + WCHAR szString[MAX_RESOURCE_STRING_LENGTH]; + WCHAR delimiter; + WCHAR *next_delim; + WCHAR *p; INT len; TRACE("adding string from resource!\n"); - len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam, szString, sizeof(szString)); + LoadStringW ((HINSTANCE)wParam, (UINT)lParam, + szString, MAX_RESOURCE_STRING_LENGTH); + len = lstrlenW(szString); - TRACE("len=%d \"%s\"\n", len, szString); - nIndex = infoPtr->nNumStrings; - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } + TRACE("len=%d %s\n", len, debugstr_w(szString)); + if (len == 0 || len == 1) + return nIndex; - /*Alloc zeros out the allocated memory*/ - Str_SetPtrAtoW (&infoPtr->strings[infoPtr->nNumStrings], szString ); - infoPtr->nNumStrings++; + TRACE("Delimiter: 0x%x\n", *szString); + delimiter = *szString; + p = szString + 1; + if (szString[len-1] == delimiter) + szString[len-1] = 0; + + while ((next_delim = strchrW(p, delimiter)) != NULL) { + *next_delim = 0; + + infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1)); + Str_SetPtrW(&infoPtr->strings[infoPtr->nNumStrings], p); + infoPtr->nNumStrings++; + + p = next_delim + 1; + } } else { - LPSTR p = (LPSTR)lParam; + LPWSTR p = (LPWSTR)lParam; INT len; if (p == NULL) return -1; TRACE("adding string(s) from array!\n"); - - nIndex = infoPtr->nNumStrings; while (*p) { - len = strlen (p); - TRACE("len=%d \"%s\"\n", len, p); + len = strlenW (p); - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } - - Str_SetPtrAtoW (&infoPtr->strings[infoPtr->nNumStrings], p ); + TRACE("len=%d %s\n", len, debugstr_w(p)); + infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1)); + Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], p); infoPtr->nNumStrings++; p += (len+1); @@ -2998,109 +2993,31 @@ TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam) +TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam) { -#define MAX_RESOURCE_STRING_LENGTH 512 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); + LPSTR p; INT nIndex; + INT len; - if ((wParam) && (HIWORD(lParam) == 0)) { - WCHAR szString[MAX_RESOURCE_STRING_LENGTH]; - INT len; - TRACE("adding string from resource!\n"); + if ((wParam) && (HIWORD(lParam) == 0)) /* load from resources */ + return TOOLBAR_AddStringW(hwnd, wParam, lParam); - len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam, - szString, MAX_RESOURCE_STRING_LENGTH); + p = (LPSTR)lParam; + if (p == NULL) + return -1; - TRACE("len=%d %s\n", len, debugstr_w(szString)); - TRACE("First char: 0x%x\n", *szString); - if (szString[0] == L'|') - { - PWSTR p = szString + 1; + TRACE("adding string(s) from array!\n"); + nIndex = infoPtr->nNumStrings; + while (*p) { + len = strlen (p); + TRACE("len=%d \"%s\"\n", len, p); - nIndex = infoPtr->nNumStrings; - while (*p != L'|' && *p != L'\0') { - PWSTR np; + infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1)); + Str_SetPtrAtoW(&infoPtr->strings[infoPtr->nNumStrings], p); + infoPtr->nNumStrings++; - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = Alloc (sizeof(LPWSTR)); - } - else - { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = Alloc(sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy(&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free(oldStrings); - } - - np=strchrW (p, '|'); - if (np!=NULL) { - len = np - p; - np++; - } else { - len = strlenW(p); - np = p + len; - } - TRACE("len=%d %s\n", len, debugstr_w(p)); - infoPtr->strings[infoPtr->nNumStrings] = - Alloc (sizeof(WCHAR)*(len+1)); - lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len+1); - infoPtr->nNumStrings++; - - p = np; - } - } - else - { - nIndex = infoPtr->nNumStrings; - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } - - Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], szString); - infoPtr->nNumStrings++; - } - } - else { - LPWSTR p = (LPWSTR)lParam; - INT len; - - if (p == NULL) - return -1; - TRACE("adding string(s) from array!\n"); - nIndex = infoPtr->nNumStrings; - while (*p) { - len = strlenW (p); - - TRACE("len=%d %s\n", len, debugstr_w(p)); - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } - - Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], p); - infoPtr->nNumStrings++; - - p += (len+1); - } + p += (len+1); } return nIndex; @@ -3301,7 +3218,7 @@ TOOLBAR_Customize (HWND hwnd) return FALSE; ret = DialogBoxIndirectParamW ((HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE), - (LPDLGTEMPLATEW)template, + (LPCDLGTEMPLATEW)template, hwnd, TOOLBAR_CustomizeDialogProc, (LPARAM)&custInfo); @@ -4746,6 +4663,7 @@ TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam) infoPtr->nBitmapHeight); } + InvalidateRect(infoPtr->hwndSelf, NULL, FALSE); return TRUE; } @@ -5672,6 +5590,7 @@ TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam) /* delete temporary buffer for tooltip text */ Free (infoPtr->pszTooltipText); + Free (infoPtr->bitmaps); /* bitmaps list */ /* delete button data */ if (infoPtr->buttons) From 917979cceb421e40d1444db14e6c162ac9b6544a Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 4 Oct 2006 03:37:11 +0000 Subject: [PATCH 450/488] - Make Kernel initialization (KeInit2) portable/more complete. KeInit2 becomes KeInitSystem, the portable part, with a call to KiInitMachineDependent, the arch-specific part. - Do all CPU configuration through IPIs and synchronize with potential multiple CPUs. - Add mtrr.c and patpge.c for future support of MTRR, AMD K6 MTRR, PGE and PAT support, with initilization calls in each of them (which only print out a "Sorry" message). - Add some stubbed code for extra initizliation to do later once some detection things are fixed. svn path=/trunk/; revision=24385 --- reactos/ntoskrnl/ex/init.c | 4 +- reactos/ntoskrnl/include/internal/ke.h | 98 +++++++++--------- reactos/ntoskrnl/ke/dpc.c | 1 + reactos/ntoskrnl/ke/i386/cpu.c | 55 ++++++++++- reactos/ntoskrnl/ke/i386/kiinit.c | 131 +++++++++++++++++++++++++ reactos/ntoskrnl/ke/i386/mtrr.c | 33 +++++++ reactos/ntoskrnl/ke/i386/patpge.c | 63 ++++++++++++ reactos/ntoskrnl/ke/krnlinit.c | 63 ++---------- reactos/ntoskrnl/ntoskrnl.rbuild | 2 + 9 files changed, 344 insertions(+), 106 deletions(-) create mode 100644 reactos/ntoskrnl/ke/i386/mtrr.c create mode 100644 reactos/ntoskrnl/ke/i386/patpge.c diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index b445f99d80b..beb7392b542 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -736,8 +736,8 @@ ExPhase2Init(PVOID Context) /* Set us at maximum priority */ KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY); - /* Initialize the second stage of the kernel */ - KeInit2(); + /* Initialize the later stages of the kernel */ + KeInitSystem(); /* Initialize all processors */ HalAllProcessorsStarted(); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index d901f374913..d36d30142d1 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -116,6 +116,7 @@ extern ULONG KiMaximumDpcQueueDepth; extern ULONG KiMinimumDpcRate; extern ULONG KiAdjustDpcThreshold; extern ULONG KiIdealDpcRate; +extern BOOLEAN KeThreadDpcEnable; extern LARGE_INTEGER KiTimeIncrementReciprocal; extern UCHAR KiTimeIncrementShiftCount; extern LIST_ENTRY BugcheckCallbackListHead, BugcheckReasonCallbackListHead; @@ -135,6 +136,7 @@ extern ULONG KiMask32Array[MAXIMUM_PRIORITY]; extern ULONG KiIdleSummary; extern VOID KiTrap8(VOID); extern VOID KiTrap2(VOID); +extern VOID KiFastCallEntry(VOID); extern PVOID KeUserApcDispatcher; extern PVOID KeUserCallbackDispatcher; extern PVOID KeUserExceptionDispatcher; @@ -550,10 +552,6 @@ KiWaitTest( KPRIORITY Increment ); -PULONG -NTAPI -KeGetStackTopThread(struct _ETHREAD* Thread); - VOID NTAPI KeContextToTrapFrame( @@ -636,6 +634,10 @@ KiActivateWaiterQueue(IN PKQUEUE Queue); /* INITIALIZATION FUNCTIONS *************************************************/ +VOID +NTAPI +KeInitSystem(VOID); + VOID NTAPI KeInitExceptions(VOID); @@ -646,34 +648,18 @@ KeInitInterrupts(VOID); VOID NTAPI -KeInitTimer(VOID); - -VOID -NTAPI -KeInitDispatcher(VOID); +KiInitializeBugCheck(VOID); VOID NTAPI KiInitializeSystemClock(VOID); -VOID -NTAPI -KiInitializeBugCheck(VOID); - -VOID -NTAPI -Phase1Initialization(PVOID Context); - VOID NTAPI KiSystemStartup( IN PLOADER_PARAMETER_BLOCK LoaderBlock ); -VOID -NTAPI -KeInit2(VOID); - BOOLEAN NTAPI KiDeliverUserApc(PKTRAP_FRAME TrapFrame); @@ -710,33 +696,6 @@ KeTrapFrameToContext( IN OUT PCONTEXT Context ); -VOID -NTAPI -KeApplicationProcessorInit(VOID); - -VOID -NTAPI -KePrepareForApplicationProcessorInit(ULONG id); - -ULONG -NTAPI -KiUserTrapHandler( - PKTRAP_FRAME Tf, - ULONG ExceptionNr, - PVOID Cr2 -); - -VOID -NTAPI -KePushAndStackSwitchAndSysRet( - ULONG Push, - PVOID NewStack -); - -VOID -NTAPI -KeStackSwitchAndRet(PVOID NewStack); - VOID NTAPI KeBugCheckWithTf( @@ -813,7 +772,6 @@ KeI386VdmInitialize( VOID ); - VOID NTAPI KiInitializeMachineType( @@ -866,6 +824,48 @@ KiGetUserModeStackAddress( VOID ); +ULONG_PTR +NTAPI +Ki386EnableGlobalPage(IN volatile ULONG_PTR Context); + +VOID +NTAPI +KiInitializePAT(VOID); + +VOID +NTAPI +KiInitializeMTRR(IN BOOLEAN FinalCpu); + +VOID +NTAPI +KiAmdK6InitializeMTRR(VOID); + +VOID +NTAPI +KiRestoreFastSyscallReturnState(VOID); + +ULONG_PTR +NTAPI +Ki386EnableDE(IN ULONG_PTR Context); + +ULONG_PTR +NTAPI +Ki386EnableFxsr(IN ULONG_PTR Context); + +ULONG_PTR +NTAPI +Ki386EnableXMMIExceptions(IN ULONG_PTR Context); + +VOID +NTAPI +KiInitMachineDependent(VOID); + +VOID +WRMSR( + IN ULONG Register, + IN LONGLONG Value +); + #include "ke_x.h" #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */ diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 926a874f6f8..0788738a08b 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -22,6 +22,7 @@ ULONG KiMaximumDpcQueueDepth = 4; ULONG KiMinimumDpcRate = 3; ULONG KiAdjustDpcThreshold = 20; ULONG KiIdealDpcRate = 20; +BOOLEAN KeThreadDpcEnable; KMUTEX KiGenericCallDpcMutex; /* PRIVATE FUNCTIONS *********************************************************/ diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 7f87e9ec989..65164978018 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -63,7 +63,6 @@ ULONG KeI386XMMIPresent = 0; ULONG KeI386FxsrPresent = 0; ULONG KeI386MachineType; ULONG Ke386Pae = FALSE; -ULONG Ke386GlobalPagesEnabled = FALSE; ULONG Ke386NoExecute = FALSE; BOOLEAN KiI386PentiumLockErrataPresent; ULONG KeLargestCacheLine = 0x40; @@ -760,6 +759,60 @@ KiInitializeMachineType(VOID) KeI386MachineType = KeLoaderBlock->u.I386.MachineType & 0x000FF; } +ULONG_PTR +NTAPI +KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context) +{ + /* Set CS and ESP */ + Ke386Wrmsr(0x174, KGDT_R0_CODE, 0); + Ke386Wrmsr(0x175, 0, 0); + + /* Set LSTAR */ + Ke386Wrmsr(0x176, KiFastCallEntry, 0); + return 0; +} + +VOID +NTAPI +KiRestoreFastSyscallReturnState(VOID) +{ + /* FIXME: NT has support for SYSCALL, IA64-SYSENTER, etc. */ + + /* Check if the CPU Supports fast system call */ + if (KeFeatureBits & KF_FAST_SYSCALL) + { + /* Do an IPI to enable it */ + KeIpiGenericCall(KiLoadFastSyscallMachineSpecificRegisters, 0); + } +} + +ULONG_PTR +NTAPI +Ki386EnableDE(IN ULONG_PTR Context) +{ + /* Enable DE */ + Ke386SetCr4(Ke386GetCr4() | CR4_DE); + return 0; +} + +ULONG_PTR +NTAPI +Ki386EnableFxsr(IN ULONG_PTR Context) +{ + /* Enable FXSR */ + Ke386SetCr4(Ke386GetCr4() | CR4_FXSR); + return 0; +} + +ULONG_PTR +NTAPI +Ki386EnableXMMIExceptions(IN ULONG_PTR Context) +{ + /* FIXME: Support this */ + DPRINT1("Your machine supports XMMI exceptions but ReactOS doesn't\n"); + return 0; +} + /* PUBLIC FUNCTIONS **********************************************************/ /* diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index 8e4f8112349..a94815b8c95 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -20,6 +20,137 @@ KSPIN_LOCK Ki486CompatibilityLock; /* FUNCTIONS *****************************************************************/ +VOID +NTAPI +KiInitMachineDependent(VOID) +{ + ULONG Protect; + ULONG CpuCount; + BOOLEAN FbCaching = FALSE; + NTSTATUS Status; + //ULONG ReturnLength; + ULONG i, Affinity; + + /* Check for large page support */ + if (KeFeatureBits & KF_LARGE_PAGE) + { + /* FIXME: Support this */ + DPRINT1("Your machine supports PGE but ReactOS doesn't yet.\n"); + } + + /* Check for global page support */ + if (KeFeatureBits & KF_GLOBAL_PAGE) + { + /* Do an IPI to enable it on all CPUs */ + CpuCount = KeNumberProcessors; + KeIpiGenericCall(Ki386EnableGlobalPage, (ULONG_PTR)&CpuCount); + } + + /* Check for PAT and/or MTRR support */ + if (KeFeatureBits & (KF_PAT | KF_MTRR)) + { + /* FIXME: ROS HAL Doesn't initialize this! */ +#if 1 + Status = STATUS_UNSUCCESSFUL; +#else + /* Query the HAL to make sure we can use it */ + Status = HalQuerySystemInformation(HalFrameBufferCachingInformation, + sizeof(BOOLEAN), + &FbCaching, + &ReturnLength); +#endif + if ((NT_SUCCESS(Status)) && (FbCaching)) + { + /* We can't, disable it */ + KeFeatureBits &= ~(KF_PAT | KF_MTRR); + } + } + + /* Check for PAT support and enable it */ + if (KeFeatureBits & KF_PAT) KiInitializePAT(); + + /* Check for CR4 support */ + if (KeFeatureBits & KF_CR4) + { + /* Do an IPI call to enable the Debug Exceptions */ + CpuCount = KeNumberProcessors; + KeIpiGenericCall(Ki386EnableDE, (ULONG_PTR)&CpuCount); + } + + /* Check if FXSR was found */ + if (KeFeatureBits & KF_FXSR) + { + /* Do an IPI call to enable the FXSR */ + CpuCount = KeNumberProcessors; + KeIpiGenericCall(Ki386EnableFxsr, (ULONG_PTR)&CpuCount); + + /* Check if XMM was found too */ + if (KeFeatureBits & KF_XMMI) + { + /* Do an IPI call to enable XMMI exceptions */ + CpuCount = KeNumberProcessors; + KeIpiGenericCall(Ki386EnableXMMIExceptions, (ULONG_PTR)&CpuCount); + + /* FIXME: Implement and enable XMM Page Zeroing for Mm */ + + /* Patch the RtlPrefetchMemoryNonTemporal routine to enable it */ + Protect = MmGetPageProtect(NULL, RtlPrefetchMemoryNonTemporal); + MmSetPageProtect(NULL, + RtlPrefetchMemoryNonTemporal, + Protect | PAGE_IS_WRITABLE); + *(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90; + MmSetPageProtect(NULL, RtlPrefetchMemoryNonTemporal, Protect); + } + } + + /* Check for, and enable SYSENTER support */ + KiRestoreFastSyscallReturnState(); + + /* Loop every CPU */ + i = KeActiveProcessors; + for (Affinity = 1; i; Affinity <<= 1) + { + /* Check if this is part of the set */ + if (i & Affinity) + { + /* Run on this CPU */ + i &= ~Affinity; + KeSetSystemAffinityThread(Affinity); + + /* Reset MHz to 0 for this CPU */ + KeGetCurrentPrcb()->MHz = 0; + + /* Check if we can use RDTSC */ + if (KeFeatureBits & KF_RDTSC) + { + /* Start sampling loop */ + for (;;) + { + // + // FIXME: TODO + // + break; + } + } + + /* Check if we have MTRR without PAT */ + if (!(KeFeatureBits & KF_PAT) && (KeFeatureBits & KF_MTRR)) + { + /* Then manually initialize MTRR for the CPU */ + KiInitializeMTRR((BOOLEAN)i); + } + + /* Check if we have AMD MTRR and initialize it for the CPU */ + if (KeFeatureBits & KF_AMDK6MTRR) KiAmdK6InitializeMTRR(); + + /* FIXME: Apply P5 LOCK Errata fixups */ + } + } + + /* Return affinity back to where it was */ + KeRevertToUserAffinityThread(); +} + VOID NTAPI KiInitializePcr(IN ULONG ProcessorNumber, diff --git a/reactos/ntoskrnl/ke/i386/mtrr.c b/reactos/ntoskrnl/ke/i386/mtrr.c new file mode 100644 index 00000000000..41fc221741c --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/mtrr.c @@ -0,0 +1,33 @@ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/ke/i386/mtrr.c +* PURPOSE: Support for MTRR and AMD K6 MTRR +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +VOID +NTAPI +KiInitializeMTRR(IN BOOLEAN FinalCpu) +{ + /* FIXME: Support this */ + DPRINT1("Your machine supports MTRR but ReactOS doesn't yet.\n"); +} + +VOID +NTAPI +KiAmdK6InitializeMTRR(VOID) +{ + /* FIXME: Support this */ + DPRINT1("Your machine supports AMD MTRR but ReactOS doesn't yet.\n"); +} diff --git a/reactos/ntoskrnl/ke/i386/patpge.c b/reactos/ntoskrnl/ke/i386/patpge.c new file mode 100644 index 00000000000..e09f2e62e4f --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/patpge.c @@ -0,0 +1,63 @@ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/ke/i386/patpge.c +* PURPOSE: Support for PAT and PGE (Large Pages) +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +ULONG Ke386GlobalPagesEnabled; + +/* FUNCTIONS *****************************************************************/ + +ULONG_PTR +NTAPI +Ki386EnableGlobalPage(IN volatile ULONG_PTR Context) +{ + volatile PLONG Count = (PLONG)Context; + ULONG Cr4, Cr3; + + /* Disable interrupts */ + _disable(); + + /* Decrease CPU Count and loop until it's reached 0 */ + do {InterlockedDecrement(Count);} while (!*Count); + + /* Now check if this is the Boot CPU */ + if (!KeGetPcr()->Number) + { + /* It is.FIXME: Patch KeFlushCurrentTb */ + } + + /* Now get CR4 and make sure PGE is masked out */ + Cr4 = Ke386GetCr4(); + Ke386SetCr4(Cr4 & ~CR4_PGE); + + /* Flush the TLB */ + Ke386GetPageTableDirectory(Cr3); + Ke386SetPageTableDirectory(Cr3); + + /* Now enable PGE */ + Ke386SetCr4(Cr4 | CR4_PGE); + Ke386GlobalPagesEnabled = TRUE; + + /* Restore interrupts */ + _enable(); + return 0; +} + +VOID +NTAPI +KiInitializePAT(VOID) +{ + /* FIXME: Support this */ + DPRINT1("Your machine supports PAT but ReactOS doesn't yet.\n"); +} diff --git a/reactos/ntoskrnl/ke/krnlinit.c b/reactos/ntoskrnl/ke/krnlinit.c index ccdd281239b..236613ba43c 100644 --- a/reactos/ntoskrnl/ke/krnlinit.c +++ b/reactos/ntoskrnl/ke/krnlinit.c @@ -6,7 +6,7 @@ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG @@ -273,63 +273,18 @@ KiInitSpinLocks(IN PKPRCB Prcb, } } -/* FIXME: Rename and make portable */ VOID NTAPI -KeInit2(VOID) +KeInitSystem(VOID) { - ULONG Protect; - - /* Check if Fxsr was found */ - if (KeI386FxsrPresent) + /* Check if Threaded DPCs are enabled */ + if (KeThreadDpcEnable) { - /* Enable it. FIXME: Send an IPI */ - Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSFXSR); - - /* Check if XMM was found too */ - if (KeI386XMMIPresent) - { - /* Enable it: FIXME: Send an IPI. */ - Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT); - - /* FIXME: Implement and enable XMM Page Zeroing for Mm */ - } + /* FIXME: TODO */ + DPRINT1("Threaded DPCs not yet supported\n"); } - if (KeFeatureBits & KF_GLOBAL_PAGE) - { - ULONG Flags; - /* Enable global pages */ - Ke386GlobalPagesEnabled = TRUE; - Ke386SaveFlags(Flags); - Ke386DisableInterrupts(); - Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE); - Ke386RestoreFlags(Flags); - } - - if (KeFeatureBits & KF_FAST_SYSCALL) - { - extern void KiFastCallEntry(void); - - /* CS Selector of the target segment. */ - Ke386Wrmsr(0x174, KGDT_R0_CODE, 0); - /* Target ESP. */ - Ke386Wrmsr(0x175, 0, 0); - /* Target EIP. */ - Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0); - } - - /* Does the CPU Support 'prefetchnta' (SSE) */ - if(KeFeatureBits & KF_XMMI) - { - Protect = MmGetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal); - MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect | PAGE_IS_WRITABLE); - /* Replace the ret by a nop */ - *(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90; - MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect); - } - - /* Set IDT to writable */ - Protect = MmGetPageProtect(NULL, (PVOID)KiIdt); - MmSetPageProtect(NULL, (PVOID)KiIdt, Protect | PAGE_IS_WRITABLE); + /* Initialize non-portable parts of the kernel */ + KiInitMachineDependent(); } + diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 02925121c28..f8ca060552e 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -37,6 +37,8 @@ kiinit.c ldt.c + mtrr.c + patpge.c thread.c trap.s usercall_asm.S From 1e4f1415555e353037c61e441dd3d2c149840f39 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 4 Oct 2006 05:29:30 +0000 Subject: [PATCH 451/488] - Add KF_XMMI64 feature flag for SSE2 and detect it. - Detect Hyper-Threading and set Local APIC ID (put back Thomas's code that he added in an old revision and that I had accidentally removed and forgotten to re-convert into the new KiGetFeatureBits function). - Add code to set the kernel MX Csr Mask in the FX Save Area. - Startup the sysenter handler on the DPC stack. - Detect and notify users with broken Pentiums. - Do some NPX checks to forcefully disable any FPU flags that might be set (SSE, MMX, 3DNOW) if the NPX is disabled. svn path=/trunk/; revision=24386 --- reactos/include/ndk/ketypes.h | 1 + reactos/ntoskrnl/include/internal/ke.h | 7 ++ reactos/ntoskrnl/include/internal/ntoskrnl.h | 1 + reactos/ntoskrnl/ke/clock.c | 2 +- reactos/ntoskrnl/ke/i386/cpu.c | 35 +++++++- reactos/ntoskrnl/ke/i386/kiinit.c | 89 +++++++++++++++++++- reactos/ntoskrnl/ke/i386/trap.s | 6 +- 7 files changed, 136 insertions(+), 5 deletions(-) diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index 9ed3830f458..5510e35d732 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -86,6 +86,7 @@ Author: #define KF_XMMI 0x00002000 #define KF_3DNOW 0x00004000 #define KF_AMDK6MTRR 0x00008000 +#define KF_XMMI64 0x00010000 // // KPCR Access for non-IA64 builds diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index d36d30142d1..24e515666ac 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -82,6 +82,7 @@ extern ULONG_PTR KERNEL_BASE; extern ULONG KeI386NpxPresent; extern ULONG KeI386XMMIPresent; extern ULONG KeI386FxsrPresent; +extern ULONG KiMXCsrMask; extern ULONG KeI386CpuType; extern ULONG KeI386CpuStep; extern ULONG KeProcessorArchitecture; @@ -89,6 +90,7 @@ extern ULONG KeProcessorLevel; extern ULONG KeProcessorRevision; extern ULONG KeFeatureBits; extern ULONG Ke386GlobalPagesEnabled; +extern BOOLEAN KiI386PentiumLockErrataPresent; extern KNODE KiNode0; extern PKNODE KeNodeBlock[1]; extern UCHAR KeNumberNodes; @@ -119,6 +121,7 @@ extern ULONG KiIdealDpcRate; extern BOOLEAN KeThreadDpcEnable; extern LARGE_INTEGER KiTimeIncrementReciprocal; extern UCHAR KiTimeIncrementShiftCount; +extern ULONG KiTimeLimitIsrMicroseconds; extern LIST_ENTRY BugcheckCallbackListHead, BugcheckReasonCallbackListHead; extern KSPIN_LOCK BugCheckCallbackLock; extern KDPC KiExpireTimerDpc; @@ -860,6 +863,10 @@ VOID NTAPI KiInitMachineDependent(VOID); +VOID +NTAPI +KiI386PentiumLockErrataFixup(VOID); + VOID WRMSR( IN ULONG Register, diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index ba21d3fe351..de6d82e0f84 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -318,6 +318,7 @@ C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == K C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD); C_ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0); C_ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE); +C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, DpcStack) == KPCR_PRCB_DPC_STACK); C_ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA); #endif /* INCLUDE_INTERNAL_NTOSKRNL_H */ diff --git a/reactos/ntoskrnl/ke/clock.c b/reactos/ntoskrnl/ke/clock.c index e294543a093..63ee0c083da 100644 --- a/reactos/ntoskrnl/ke/clock.c +++ b/reactos/ntoskrnl/ke/clock.c @@ -37,7 +37,7 @@ LARGE_INTEGER SystemBootTime = { 0 }; KDPC KiExpireTimerDpc; BOOLEAN KiClockSetupComplete = FALSE; - +ULONG KiTimeLimitIsrMicroseconds; /* * Number of timer interrupts since initialisation diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 65164978018..e8f88e0bebb 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -58,19 +58,21 @@ ULONG KeProcessorRevision; ULONG KeFeatureBits; ULONG KiFastSystemCallDisable = 1; ULONG KeI386NpxPresent = 0; +ULONG KiMXCsrMask = 0; ULONG MxcsrFeatureMask = 0; ULONG KeI386XMMIPresent = 0; ULONG KeI386FxsrPresent = 0; ULONG KeI386MachineType; ULONG Ke386Pae = FALSE; ULONG Ke386NoExecute = FALSE; -BOOLEAN KiI386PentiumLockErrataPresent; ULONG KeLargestCacheLine = 0x40; ULONG KeDcacheFlushCount = 0; ULONG KeIcacheFlushCount = 0; ULONG KiDmaIoCoherency = 0; CHAR KeNumberProcessors; KAFFINITY KeActiveProcessors = 1; +BOOLEAN KiI386PentiumLockErrataPresent; +BOOLEAN KiSMTProcessorsPresent; /* CPU Signatures */ CHAR CmpIntelID[] = "GenuineIntel"; @@ -255,6 +257,9 @@ KiGetFeatureBits(VOID) /* Get the CPUID Info. Features are in Reg[3]. */ CPUID(Reg, 1); + /* Set the initial APIC ID */ + Prcb->InitialApicId = (UCHAR)(Reg[1] >> 24); + /* Check for AMD CPU */ if (Vendor == CPU_AMD) { @@ -351,6 +356,24 @@ KiGetFeatureBits(VOID) if (CpuFeatures & 0x00800000) FeatureBits |= KF_MMX; if (CpuFeatures & 0x01000000) FeatureBits |= KF_FXSR; if (CpuFeatures & 0x02000000) FeatureBits |= KF_XMMI; + if (CpuFeatures & 0x04000000) FeatureBits |= KF_XMMI64; + + /* Check if the CPU has hyper-threading */ + if (CpuFeatures & 0x10000000) + { + /* Set the number of logical CPUs */ + Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(Reg[1] >> 16); + if (Prcb->LogicalProcessorsPerPhysicalProcessor > 1) + { + /* We're on dual-core */ + KiSMTProcessorsPresent = TRUE; + } + } + else + { + /* We only have a single CPU */ + Prcb->LogicalProcessorsPerPhysicalProcessor = 1; + } /* Check if CPUID 0x80000000 is supported */ if (ExtendedCPUID) @@ -765,7 +788,7 @@ KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context) { /* Set CS and ESP */ Ke386Wrmsr(0x174, KGDT_R0_CODE, 0); - Ke386Wrmsr(0x175, 0, 0); + Ke386Wrmsr(0x175, KeGetCurrentPrcb()->DpcStack, 0); /* Set LSTAR */ Ke386Wrmsr(0x176, KiFastCallEntry, 0); @@ -813,6 +836,14 @@ Ki386EnableXMMIExceptions(IN ULONG_PTR Context) return 0; } +VOID +NTAPI +KiI386PentiumLockErrataFixup(VOID) +{ + /* FIXME: Support this */ + DPRINT1("WARNING: Your machine has a CPU bug that ReactOS can't bypass!\n"); +} + /* PUBLIC FUNCTIONS **********************************************************/ /* diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index a94815b8c95..cf3a3b5356b 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -30,6 +30,8 @@ KiInitMachineDependent(VOID) NTSTATUS Status; //ULONG ReturnLength; ULONG i, Affinity; + PFX_SAVE_AREA FxSaveArea; + ULONG MXCsrMask = 0xFFBF, NewMask; /* Check for large page support */ if (KeFeatureBits & KF_LARGE_PAGE) @@ -69,6 +71,30 @@ KiInitMachineDependent(VOID) /* Check for PAT support and enable it */ if (KeFeatureBits & KF_PAT) KiInitializePAT(); + /* Assume no errata for now */ + SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = 0; + + /* If there's no NPX, then we're emulating the FPU */ + SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = + !KeI386NpxPresent; + + /* Check if there's no NPX, so that we can disable associated features */ + if (!KeI386NpxPresent) + { + /* Remove NPX-related bits */ + KeFeatureBits &= ~(KF_XMMI64 | KF_XMMI | KF_FXSR | KF_MMX); + + /* Disable kernel flags */ + KeI386FxsrPresent = KeI386XMMIPresent = FALSE; + + /* Disable processor features that might've been set until now */ + SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = + SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = + SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = + SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = + SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = 0; + } + /* Check for CR4 support */ if (KeFeatureBits & KF_CR4) { @@ -143,12 +169,67 @@ KiInitMachineDependent(VOID) /* Check if we have AMD MTRR and initialize it for the CPU */ if (KeFeatureBits & KF_AMDK6MTRR) KiAmdK6InitializeMTRR(); - /* FIXME: Apply P5 LOCK Errata fixups */ + /* Check if this is a buggy Pentium and apply the fixup if so */ + if (KiI386PentiumLockErrataPresent) KiI386PentiumLockErrataFixup(); + + /* Get the current thread NPX state */ + FxSaveArea = (PVOID) + ((ULONG_PTR)KeGetCurrentThread()->InitialStack - + NPX_FRAME_LENGTH); + + /* 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 + /* Check if the current mask doesn't match the reserved bits */ + if (FxSaveArea->U.FxArea.MXCsrMask != MXCsrMask) + { + /* Then use whatever it's holding */ + MXCsrMask = FxSaveArea->U.FxArea.MXCsrMask; + } + + /* Check if nobody set the kernel-wide mask */ + if (!KiMXCsrMask) + { + /* Then use the one we calculated above */ + NewMask = MXCsrMask; + } + else + { + /* Use the existing mask */ + NewMask = KiMXCsrMask; + + /* Was it set to the same value we found now? */ + if (NewMask != MXCsrMask) + { + /* No, something is definitely wrong */ + KEBUGCHECKEX(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED, + KF_FXSR, + NewMask, + MXCsrMask, + 0); + } + } + + /* Now set the kernel mask */ + KiMXCsrMask = NewMask & MXCsrMask; } } /* Return affinity back to where it was */ KeRevertToUserAffinityThread(); + + /* NT allows limiting the duration of an ISR with a registry key */ + if (KiTimeLimitIsrMicroseconds) + { + /* FIXME: TODO */ + DPRINT1("ISR Time Limit not yet supported\n"); + } } VOID @@ -519,11 +600,17 @@ AppCpuInit: /* Align stack and make space for the trap frame and NPX frame */ InitialStack &= ~KTRAP_FRAME_ALIGN; +#ifdef __GNUC__ __asm__ __volatile__("movl %0,%%esp" : :"r" (InitialStack)); __asm__ __volatile__("subl %0,%%esp" : :"r" (NPX_FRAME_LENGTH + KTRAP_FRAME_LENGTH + KTRAP_FRAME_ALIGN)); __asm__ __volatile__("push %0" : :"r" (CR0_EM + CR0_TS + CR0_MP)); +#else + __asm mov esp, InitialStack; + __asm sub esp, NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH; + __asm push CR0_EM + CR0_TS + CR0_MP +#endif /* Call main kernel initialization */ KiInitializeKernel(&KiInitialProcess.Pcb, diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index f2ad0f7ad0d..85bfd88817d 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -111,9 +111,13 @@ _KiFastCallEntry: /* Set FS to PCR */ mov ecx, KGDT_R0_PCR mov fs, cx + //push KGDT_R0_PCR + //pop fs + + /* Set user selector */ + mov ecx, KGDT_R3_DATA | RPL_MASK /* Set DS/ES to User Selector */ - mov ecx, KGDT_R3_DATA | RPL_MASK mov ds, cx mov es, cx From a6056d1fa9ba70e5f8841b7ecf8646d1367ebd3f Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 4 Oct 2006 05:48:46 +0000 Subject: [PATCH 452/488] - Fix KUSER_SHARED_DATA in winddk.h - Scanfor NOEXECUTE/EXECUTE/OPTIN/OPTOUT/ALWAYSON/ALWAYSOFF load strings and set the appropriate NX policy in KUSER_SHARED_DATA as well as kernel CPU Feature flags. svn path=/trunk/; revision=24387 --- reactos/include/ddk/winddk.h | 25 ++++++++++++++++++++++++- reactos/include/ndk/ketypes.h | 2 ++ reactos/ntoskrnl/ke/i386/cpu.c | 2 +- reactos/ntoskrnl/ke/i386/kiinit.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 5240ef84272..1c13d8ced3d 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -458,6 +458,9 @@ typedef struct _KUSER_SHARED_DATA LARGE_INTEGER SystemExpirationDate; ULONG SuiteMask; BOOLEAN KdDebuggerEnabled; +#if (NTDDI_VERSION >= NTDDI_WINXPSP2) + UCHAR NXSupportPolicy; +#endif volatile ULONG ActiveConsoleId; volatile ULONG DismountCount; ULONG ComPlusPackage; @@ -475,9 +478,29 @@ typedef struct _KUSER_SHARED_DATA volatile ULONG64 TickCountQuad; }; ULONG Cookie; +#if (NTDDI_VERSION >= NTDDI_WS03) LONGLONG ConsoleSessionForegroundProcessId; ULONG Wow64SharedInformation[MAX_WOW64_SHARED_ENTRIES]; - ULONG UserModeGlobalLogging; +#endif +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + USHORT UserModeGlobalLogger[8]; + ULONG HeapTracingPid[2]; + ULONG CritSecTracingPid[2]; + union + { + ULONG SharedDataFlags; + struct + { + ULONG DbgErrorPortPresent:1; + ULONG DbgElevationEnabled:1; + ULONG DbgVirtEnabled:1; + ULONG DbgInstallerDetectEnabled:1; + ULONG SpareBits:28; + }; + }; + ULONG ImageFileExecutionOptions; + KAFFINITY ActiveProcessorAffinity; +#endif } KUSER_SHARED_DATA, *PKUSER_SHARED_DATA; /* diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index 5510e35d732..ca11ac4341d 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -87,6 +87,8 @@ Author: #define KF_3DNOW 0x00004000 #define KF_AMDK6MTRR 0x00008000 #define KF_XMMI64 0x00010000 +#define KF_NX_DISABLED 0x00400000 +#define KF_NX_ENABLED 0x00800000 // // KPCR Access for non-IA64 builds diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index e8f88e0bebb..23366d4f632 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -303,7 +303,7 @@ KiGetFeatureBits(VOID) } else { - /* Familes below 5 don't support PGE, PSE or CMOV at all */ + /* Families below 5 don't support PGE, PSE or CMOV at all */ Reg[3] &= ~(0x08 | 0x2000 | 0x8000); /* They also don't support advanced CPUID functions. */ diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index cf3a3b5356b..ad1bb5f2181 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -8,6 +8,7 @@ /* INCLUDES *****************************************************************/ +#define NTDDI_VERSION NTDDI_WS03SP1 #include #define NDEBUG #include @@ -318,6 +319,36 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Save feature bits */ Prcb->FeatureBits = FeatureBits; + /* Set the default NX policy (opt-in) */ + SharedUserData->NXSupportPolicy = 2; + + /* Check if NPX is always on */ + if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSON")) + { + /* Set it always on */ + SharedUserData->NXSupportPolicy = 1; + KeFeatureBits |= KF_NX_ENABLED; + } + else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT")) + { + /* Set it in opt-out mode */ + SharedUserData->NXSupportPolicy = 3; + KeFeatureBits |= KF_NX_ENABLED; + } + else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) || + (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE"))) + { + /* Set the feature bits */ + KeFeatureBits |= KF_NX_ENABLED; + } + else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSOFF")) || + (strstr(KeLoaderBlock->LoadOptions, "EXECUTE"))) + { + /* Set disabled mode */ + SharedUserData->NXSupportPolicy = 0; + KeFeatureBits |= KF_NX_DISABLED; + } + /* Save CPU state */ KiSaveProcessorControlState(&Prcb->ProcessorState); From 38a5188c8e6045cfaf3aaf85888db6676ade4761 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 4 Oct 2006 05:59:56 +0000 Subject: [PATCH 453/488] - Fix boot crash due to last patch, forgot that SharedUserDAta wasn't available yet. svn path=/trunk/; revision=24388 --- reactos/ntoskrnl/ke/i386/kiinit.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index ad1bb5f2181..9630bf5666d 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -297,6 +297,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess, ULONG FeatureBits; LARGE_INTEGER PageDirectory; PVOID DpcStack; + ULONG NXSupportPolicy; /* Detect and set the CPU Type */ KiSetProcessorType(); @@ -316,39 +317,39 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Get the processor features for the CPU */ FeatureBits = KiGetFeatureBits(); - /* Save feature bits */ - Prcb->FeatureBits = FeatureBits; - /* Set the default NX policy (opt-in) */ - SharedUserData->NXSupportPolicy = 2; + NXSupportPolicy = 2; /* Check if NPX is always on */ if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSON")) { /* Set it always on */ - SharedUserData->NXSupportPolicy = 1; - KeFeatureBits |= KF_NX_ENABLED; + NXSupportPolicy = 1; + FeatureBits |= KF_NX_ENABLED; } else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT")) { /* Set it in opt-out mode */ - SharedUserData->NXSupportPolicy = 3; - KeFeatureBits |= KF_NX_ENABLED; + NXSupportPolicy = 3; + FeatureBits |= KF_NX_ENABLED; } else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) || (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE"))) { /* Set the feature bits */ - KeFeatureBits |= KF_NX_ENABLED; + FeatureBits |= KF_NX_ENABLED; } else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSOFF")) || (strstr(KeLoaderBlock->LoadOptions, "EXECUTE"))) { /* Set disabled mode */ - SharedUserData->NXSupportPolicy = 0; - KeFeatureBits |= KF_NX_DISABLED; + NXSupportPolicy = 0; + FeatureBits |= KF_NX_DISABLED; } + /* Save feature bits */ + Prcb->FeatureBits = FeatureBits; + /* Save CPU state */ KiSaveProcessorControlState(&Prcb->ProcessorState); @@ -417,6 +418,9 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Sets up the Text Sections of the Kernel and HAL for debugging */ LdrInit1(); + /* Set the NX Support policy */ + SharedUserData->NXSupportPolicy = NXSupportPolicy; + /* Setup the Idle Thread */ KeInitializeThread(InitProcess, InitThread, From 07725072f37dc9709486cc00488955092384e025 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Wed, 4 Oct 2006 06:58:03 +0000 Subject: [PATCH 454/488] 1. move all languages file to own folder 2. fixed sub languages on allot languages rc files 3. add LMH1 Norwegian translations. See issue #1698 for more details. svn path=/trunk/; revision=24389 --- .../winefile/{cs.rc => lang/Cs.rc} | 2 +- .../winefile/{de.rc => lang/De.rc} | 0 .../winefile/{en.rc => lang/En.rc} | 0 .../winefile/{es.rc => lang/Es.rc} | 0 .../winefile/{fr.rc => lang/Fr.rc} | 0 .../winefile/{hu.rc => lang/Hu.rc} | 3 +- .../winefile/{it.rc => lang/It.rc} | 0 .../winefile/{nl.rc => lang/Nl.rc} | 0 reactos/base/applications/winefile/lang/No.rc | 290 ++++++++++++++++++ .../winefile/{pl.rc => lang/Pl.rc} | 2 +- .../winefile/{pt.rc => lang/Pt.rc} | 0 .../winefile/{ru.rc => lang/Ru.rc} | 2 +- .../winefile/{si.rc => lang/Si.rc} | 2 +- .../applications/winefile/{ => lang}/Sv.rc | 0 .../winefile/{zh.rc => lang/Zh.rc} | 0 .../base/applications/winefile/winefile.rc | 30 +- 16 files changed, 310 insertions(+), 21 deletions(-) rename reactos/base/applications/winefile/{cs.rc => lang/Cs.rc} (96%) rename reactos/base/applications/winefile/{de.rc => lang/De.rc} (100%) rename reactos/base/applications/winefile/{en.rc => lang/En.rc} (100%) rename reactos/base/applications/winefile/{es.rc => lang/Es.rc} (100%) rename reactos/base/applications/winefile/{fr.rc => lang/Fr.rc} (100%) rename reactos/base/applications/winefile/{hu.rc => lang/Hu.rc} (99%) rename reactos/base/applications/winefile/{it.rc => lang/It.rc} (100%) rename reactos/base/applications/winefile/{nl.rc => lang/Nl.rc} (100%) create mode 100644 reactos/base/applications/winefile/lang/No.rc rename reactos/base/applications/winefile/{pl.rc => lang/Pl.rc} (96%) rename reactos/base/applications/winefile/{pt.rc => lang/Pt.rc} (100%) rename reactos/base/applications/winefile/{ru.rc => lang/Ru.rc} (99%) rename reactos/base/applications/winefile/{si.rc => lang/Si.rc} (99%) rename reactos/base/applications/winefile/{ => lang}/Sv.rc (100%) rename reactos/base/applications/winefile/{zh.rc => lang/Zh.rc} (100%) diff --git a/reactos/base/applications/winefile/cs.rc b/reactos/base/applications/winefile/lang/Cs.rc similarity index 96% rename from reactos/base/applications/winefile/cs.rc rename to reactos/base/applications/winefile/lang/Cs.rc index 26b10d8e7c7..e1e589ed975 100644 --- a/reactos/base/applications/winefile/cs.rc +++ b/reactos/base/applications/winefile/lang/Cs.rc @@ -22,7 +22,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -LANGUAGE LANG_CZECH, SUBLANG_NEUTRAL +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT #pragma code_page(1250) diff --git a/reactos/base/applications/winefile/de.rc b/reactos/base/applications/winefile/lang/De.rc similarity index 100% rename from reactos/base/applications/winefile/de.rc rename to reactos/base/applications/winefile/lang/De.rc diff --git a/reactos/base/applications/winefile/en.rc b/reactos/base/applications/winefile/lang/En.rc similarity index 100% rename from reactos/base/applications/winefile/en.rc rename to reactos/base/applications/winefile/lang/En.rc diff --git a/reactos/base/applications/winefile/es.rc b/reactos/base/applications/winefile/lang/Es.rc similarity index 100% rename from reactos/base/applications/winefile/es.rc rename to reactos/base/applications/winefile/lang/Es.rc diff --git a/reactos/base/applications/winefile/fr.rc b/reactos/base/applications/winefile/lang/Fr.rc similarity index 100% rename from reactos/base/applications/winefile/fr.rc rename to reactos/base/applications/winefile/lang/Fr.rc diff --git a/reactos/base/applications/winefile/hu.rc b/reactos/base/applications/winefile/lang/Hu.rc similarity index 99% rename from reactos/base/applications/winefile/hu.rc rename to reactos/base/applications/winefile/lang/Hu.rc index 07193db32c1..5221f947197 100644 --- a/reactos/base/applications/winefile/hu.rc +++ b/reactos/base/applications/winefile/lang/Hu.rc @@ -22,8 +22,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -LANGUAGE LANG_HUNGARIAN, SUBLANG_NEUTRAL - +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT /* Menu */ IDM_WINEFILE MENU FIXED IMPURE diff --git a/reactos/base/applications/winefile/it.rc b/reactos/base/applications/winefile/lang/It.rc similarity index 100% rename from reactos/base/applications/winefile/it.rc rename to reactos/base/applications/winefile/lang/It.rc diff --git a/reactos/base/applications/winefile/nl.rc b/reactos/base/applications/winefile/lang/Nl.rc similarity index 100% rename from reactos/base/applications/winefile/nl.rc rename to reactos/base/applications/winefile/lang/Nl.rc diff --git a/reactos/base/applications/winefile/lang/No.rc b/reactos/base/applications/winefile/lang/No.rc new file mode 100644 index 00000000000..682909e6013 --- /dev/null +++ b/reactos/base/applications/winefile/lang/No.rc @@ -0,0 +1,290 @@ +/* + * WineFile + * English Language Support + * + * Copyright 2000 Martin Fuchs + * Copyright 2002 Steven Edwards + * Copyright 2002 Alexandre Julliard + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL +#pragma code_page(850) + + +/* Menu */ + +IDM_WINEFILE MENU FIXED IMPURE +{ + POPUP "&Fil" { + MENUITEM "&Ĺpne\tEnter", ID_ACTIVATE + MENUITEM "&Flytt...\tF7", ID_FILE_MOVE + MENUITEM "&Kopiere...\tF8", ID_FILE_COPY + MENUITEM "&I utklippstavle...\tF9", 118 + MENUITEM "&Slett\tDel", ID_FILE_DELETE + MENUITEM "Endre &navn...", 109 + MENUITEM "E&genskaper...\tAlt+Enter", ID_EDIT_PROPERTIES + MENUITEM SEPARATOR + MENUITEM "k&omprimere...", 119 + MENUITEM "&dekomprimere ...", 120 + MENUITEM SEPARATOR + MENUITEM "&Kjřr...", ID_EXECUTE + MENUITEM "&Skriv ut...", 102 + MENUITEM "Tilknyttet...", 103 + MENUITEM SEPARATOR + MENUITEM "Opp&rett mappe...", 111 + MENUITEM "S&řk...", 104 + MENUITEM "&Velg Filer...", 116 + MENUITEM SEPARATOR +#ifndef _NO_EXTENSIONS + MENUITEM "A&vslutt\tAlt+X", ID_FILE_EXIT +#else + MENUITEM "A&vslutt", ID_FILE_EXIT +#endif + } + + POPUP "&Disk" { + MENUITEM "&Kopiere disk...", 201 + MENUITEM "&Merke disk...", 202 + MENUITEM SEPARATOR + MENUITEM "&Formatere Disk...", ID_FORMAT_DISK +#ifdef _WIN95 + MENUITEM "&Lag system Disk...", -1 /*TODO*/ +#endif + MENUITEM SEPARATOR + MENUITEM "Koble &til nettverk stasjon", ID_CONNECT_NETWORK_DRIVE + MENUITEM "Koble &fra nettverks stasjon", ID_DISCONNECT_NETWORK_DRIVE + MENUITEM SEPARATOR + MENUITEM "Del som...", 254 + MENUITEM "&Fjern deling...", 255 + MENUITEM SEPARATOR + MENUITEM "&Velg stasjon...", 251 + } + + POPUP "&Mappe" { + MENUITEM "&Neste nivĺ\t+", 301 + MENUITEM "Utvide &Tre\t*", 302 + MENUITEM "Utvide &alt\tStrg+*", 303 + MENUITEM "Kollaps &Tre\t-", 304 + MENUITEM SEPARATOR + MENUITEM "&Merker barn", 505 + } + + POPUP "&Vis" { + MENUITEM "T&re og kataloger", 413 + MENUITEM "Bare Tr&e ", 411 + MENUITEM "&Bare kataloger", 412 + MENUITEM SEPARATOR + MENUITEM "Sp&litt", ID_VIEW_SPLIT + MENUITEM SEPARATOR + MENUITEM "&Navn", ID_VIEW_NAME + MENUITEM "&Alle fil detaljer", ID_VIEW_ALL_ATTRIBUTES, CHECKED + MENUITEM "&begrenset detaljer...", ID_VIEW_SELECTED_ATTRIBUTES + MENUITEM SEPARATOR + MENUITEM "Sorter etter &navn", ID_VIEW_SORT_NAME + MENUITEM "Sorter etter &type", ID_VIEW_SORT_TYPE + MENUITEM "Sorter etter &střrrelse", ID_VIEW_SORT_SIZE + MENUITEM "Sorter etter &dato", ID_VIEW_SORT_DATE + MENUITEM SEPARATOR + MENUITEM "Filter etter &...", ID_VIEW_FILTER + } + + POPUP "&Innstillinger" { + MENUITEM "&bekreftelse...", 501 + MENUITEM "&Skrifttype ...", ID_SELECT_FONT + MENUITEM "Spesial verktřy&linje...", 512 + MENUITEM SEPARATOR + MENUITEM "&Verktřylinje", ID_VIEW_TOOL_BAR, CHECKED + MENUITEM "&Stasjonlinje", ID_VIEW_DRIVE_BAR, CHECKED + MENUITEM "Status &linje", ID_VIEW_STATUSBAR, CHECKED +#ifndef _NO_EXTENSIONS + MENUITEM "F&ull Skjerm\tCtrl+Shift+S", ID_VIEW_FULLSCREEN +#endif + MENUITEM SEPARATOR + MENUITEM "&Minimalisere ved kjřr", 504 + MENUITEM "&Lagre innstillinger ved avslutt", 511 + } + + + POPUP "&Sikkerhet" { + MENUITEM "&Adgang...", 605 + MENUITEM "&Logging...", 606 + MENUITEM "&Eier...", 607 + } + + POPUP "&Vindu" { + MENUITEM "Ny &vindu", ID_WINDOW_NEW + MENUITEM "Som liste\tCtrl+F5", ID_WINDOW_CASCADE + MENUITEM "Sorter &Horisontalt", ID_WINDOW_TILE_HORZ + MENUITEM "Sorter &Vertikalt\tCtrl+F4", ID_WINDOW_TILE_VERT +#ifndef _NO_EXTENSIONS + MENUITEM "Ordne automatisk", ID_WINDOW_AUTOSORT +#endif + MENUITEM "Ordne &Symboler", ID_WINDOW_ARRANGE + MENUITEM "&Oppdater\tF5", ID_REFRESH + } + + POPUP "&?" { + MENUITEM "&Emner i hjelp\tF1", ID_HELP + MENUITEM "Hjelp &Sřk...\tF1", ID_HELP + MENUITEM "&Bruke Hjelp\tF1", ID_HELP_USING + MENUITEM SEPARATOR + MENUITEM "&Info om Winefile...", ID_ABOUT +#ifdef __WINE__ + MENUITEM "Info om &Wine...", ID_ABOUT_WINE +#endif + } +} + + +IDD_EXECUTE DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Utfřre" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 + CONTROL "&Kommando:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 + EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL + CONTROL "Som &symbol", 214, "Button", BS_AUTOCHECKBOX|WS_TABSTOP,3, 45, 71, 12 + DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 + PUSHBUTTON "Avbryt", 2, 158, 23, 47, 14 + PUSHBUTTON "&Hjelp", 254, 158, 43, 47, 14 +} + +IDD_SELECT_DESTINATION DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Velg destinasjon" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", 101, "statisk", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 + CONTROL "&Mappe:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 + EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL + DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 + PUSHBUTTON "Avbryt", 2, 158, 23, 47, 14 + PUSHBUTTON "&Utforsk", 254, 158, 43, 47, 14 +} + +IDD_DIALOG_VIEW_TYPE DIALOG DISCARDABLE 15, 13, 161, 97 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Etter fil type" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Navn:",-1,7,8,22,10 + EDITTEXT IDC_VIEW_PATTERN,31,7,63,12,ES_AUTOHSCROLL + GROUPBOX "Fil type",-1,7,23,87,56 + CONTROL "&Mapper",IDC_VIEW_TYPE_DIRECTORIES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,32,70,10 + CONTROL "&Programmer",IDC_VIEW_TYPE_PROGRAMS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,43,70,10 + CONTROL "Doku&menter",IDC_VIEW_TYPE_DOCUMENTS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,54,70,10 + CONTROL "&Andre filer",IDC_VIEW_TYPE_OTHERS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,65,70,10 + CONTROL "Vise skjulte/&System Filer",IDC_VIEW_TYPE_HIDDEN, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,81,106,9 + DEFPUSHBUTTON "OK",IDOK,104,7,50,14 + PUSHBUTTON "Avbryt",IDCANCEL,104,24,50,14 +END + +IDD_DIALOG_PROPERTIES DIALOG DISCARDABLE 0, 0, 248, 215 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Egenskaper for %s" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "OK",IDOK,191,7,50,14 + PUSHBUTTON "Avbryt",IDCANCEL,191,29,50,14 + LTEXT "&Fil navn:",-1,7,7,59,9 + EDITTEXT IDC_STATIC_PROP_FILENAME,71,7,120,9,ES_READONLY | NOT WS_BORDER | WS_TABSTOP + LTEXT "Full &mappe:",-1,7,18,59,9 + EDITTEXT IDC_STATIC_PROP_PATH,71,18,120,9, ES_READONLY | NOT WS_BORDER | WS_TABSTOP + LTEXT "Sist endret:",-1,7,29,59,9 + EDITTEXT IDC_STATIC_PROP_LASTCHANGE,71,29,120,9,ES_READONLY | NOT WS_BORDER | WS_TABSTOP + LTEXT "Versjon:",-1,7,40,59,9 + EDITTEXT IDC_STATIC_PROP_VERSION,71,40,120,9,ES_READONLY | NOT WS_BORDER | WS_TABSTOP + LTEXT "Ene&rett:",-1,7,51,59,9 + EDITTEXT IDC_STATIC_PROP_COPYRIGHT,71,51,120,9,ES_READONLY | NOT WS_BORDER | WS_TABSTOP + LTEXT "Střrrelse:",-1,7,62,59,9 + EDITTEXT IDC_STATIC_PROP_SIZE,71,62,120,9,ES_READONLY | NOT WS_BORDER | WS_TABSTOP + GROUPBOX "Attributter",-1,7,79,158,46 + CONTROL "&Bare lese",IDC_CHECK_READONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,91,68,9 + CONTROL "S&kjult",IDC_CHECK_HIDDEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,92,91,68,9 + CONTROL "&Arkiv",IDC_CHECK_ARCHIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,101,68,9 + CONTROL "&System",IDC_CHECK_SYSTEM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,92,101,68,9 + CONTROL "&komprimert",IDC_CHECK_COMPRESSED,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,17,111,68,9 + GROUPBOX "&Versjon Informasjon",-1,7,129,234,79 + LISTBOX IDC_LIST_PROP_VERSION_TYPES,13,139,107,63,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_LIST_PROP_VERSION_VALUES,123,139,111,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL +END + + +STRINGTABLE +{ + IDS_FONT_SEL_DLG_NAME "kjřre skrift innstillinger" + IDS_FONT_SEL_ERROR "Feil mens valgt ny skrift." +} + +STRINGTABLE +{ + IDS_WINEFILE "Winefile" + IDS_ERROR "Feil" + IDS_ROOT_FS "root fs" + IDS_UNIXFS "unixfs" + IDS_DESKTOP "Skrivebord" + IDS_SHELL "Shell" + IDS_TITLEFMT "%s - %s" + IDS_NO_IMPL "ikke enda implementert" + IDS_WINE "WINE" + IDS_WINE_FILE "Wine Fil" +} + +STRINGTABLE +{ + IDS_COL_NAME "Navn" + IDS_COL_SIZE "Střrrelse" + IDS_COL_CDATE "CDate" + IDS_COL_ADATE "ADate" + IDS_COL_MDATE "MDate" + IDS_COL_IDX "Index/Inode" + IDS_COL_LINKS "Lenker" + IDS_COL_ATTR "Attributter" + IDS_COL_SEC "Sikkerhet" + + IDS_FREE_SPACE_FMT "%s av %s fri" +} + +STRINGTABLE +{ +IDS_LICENSE_CAPTION, "LISENS" +IDS_LICENSE, +"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.\n\ +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.\n\ +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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA" + +IDS_WARRANTY_CAPTION, "INGEN GARANTI" +IDS_WARRANTY, +"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." +} diff --git a/reactos/base/applications/winefile/pl.rc b/reactos/base/applications/winefile/lang/Pl.rc similarity index 96% rename from reactos/base/applications/winefile/pl.rc rename to reactos/base/applications/winefile/lang/Pl.rc index afeaea148dc..c5fa1e14bae 100644 --- a/reactos/base/applications/winefile/pl.rc +++ b/reactos/base/applications/winefile/lang/Pl.rc @@ -22,7 +22,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -LANGUAGE LANG_POLISH, SUBLANG_NEUTRAL +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT /* Menu */ diff --git a/reactos/base/applications/winefile/pt.rc b/reactos/base/applications/winefile/lang/Pt.rc similarity index 100% rename from reactos/base/applications/winefile/pt.rc rename to reactos/base/applications/winefile/lang/Pt.rc diff --git a/reactos/base/applications/winefile/ru.rc b/reactos/base/applications/winefile/lang/Ru.rc similarity index 99% rename from reactos/base/applications/winefile/ru.rc rename to reactos/base/applications/winefile/lang/Ru.rc index 26a8fe83534..a7cefdab425 100644 --- a/reactos/base/applications/winefile/ru.rc +++ b/reactos/base/applications/winefile/lang/Ru.rc @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -LANGUAGE LANG_RUSSIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT /* Menu */ diff --git a/reactos/base/applications/winefile/si.rc b/reactos/base/applications/winefile/lang/Si.rc similarity index 99% rename from reactos/base/applications/winefile/si.rc rename to reactos/base/applications/winefile/lang/Si.rc index bcafccb4df0..3f68186ad7c 100644 --- a/reactos/base/applications/winefile/si.rc +++ b/reactos/base/applications/winefile/lang/Si.rc @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -LANGUAGE LANG_SLOVENIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT /* Menu */ diff --git a/reactos/base/applications/winefile/Sv.rc b/reactos/base/applications/winefile/lang/Sv.rc similarity index 100% rename from reactos/base/applications/winefile/Sv.rc rename to reactos/base/applications/winefile/lang/Sv.rc diff --git a/reactos/base/applications/winefile/zh.rc b/reactos/base/applications/winefile/lang/Zh.rc similarity index 100% rename from reactos/base/applications/winefile/zh.rc rename to reactos/base/applications/winefile/lang/Zh.rc diff --git a/reactos/base/applications/winefile/winefile.rc b/reactos/base/applications/winefile/winefile.rc index d4cbc8e0bb5..e2b66448e92 100644 --- a/reactos/base/applications/winefile/winefile.rc +++ b/reactos/base/applications/winefile/winefile.rc @@ -27,18 +27,18 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* include localised resources */ -#include "en.rc" -#include "cs.rc" -#include "de.rc" -#include "es.rc" -#include "fr.rc" -#include "hu.rc" -#include "it.rc" -#include "nl.rc" -#include "pl.rc" -#include "pt.rc" -#include "ru.rc" -#include "si.rc" -#include "zh.rc" -#include "Sv.rc" - +#include "lang/En.rc" +#include "lang/Cs.rc" +#include "lang/De.rc" +#include "lang/Es.rc" +#include "lang/Fr.rc" +#include "lang/Hu.rc" +#include "lang/It.rc" +#include "lang/Nl.rc" +#include "lang/Pl.rc" +#include "lang/Pt.rc" +#include "lang/Ru.rc" +#include "lang/Si.rc" +#include "lang/Zh.rc" +#include "lang/Sv.rc" +#include "lang/No.rc" From 41dea7535408b304c2ff8fa6eff3a7ac698d06ec Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Wed, 4 Oct 2006 10:59:01 +0000 Subject: [PATCH 455/488] this file some have forget set eol-style native fixed svn path=/trunk/; revision=24391 --- reactos/base/applications/winefile/lang/Cs.rc | 424 +++++++++--------- reactos/base/applications/winefile/lang/Pl.rc | 366 +++++++-------- reactos/base/applications/winefile/lang/Sv.rc | 418 ++++++++--------- 3 files changed, 604 insertions(+), 604 deletions(-) diff --git a/reactos/base/applications/winefile/lang/Cs.rc b/reactos/base/applications/winefile/lang/Cs.rc index e1e589ed975..0996ad2b924 100644 --- a/reactos/base/applications/winefile/lang/Cs.rc +++ b/reactos/base/applications/winefile/lang/Cs.rc @@ -1,212 +1,212 @@ -/* - * WineFile - * Czech Language Support - * - * Copyright 2000 Martin Fuchs - * Copyright 2002 Steven Edwards - * Copyright 2002 Alexandre Julliard - * Copyright 2004 David Kredba - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_CZECH, SUBLANG_DEFAULT -#pragma code_page(1250) - - -/* Menu */ - -IDM_WINEFILE MENU FIXED IMPURE -{ - POPUP "&Soubor" { - MENUITEM "&Otevřít\tEnter", ID_ACTIVATE - MENUITEM "&Přesunout...\tF7", ID_FILE_MOVE - MENUITEM "&Kopírovat...\tF8", ID_FILE_COPY - MENUITEM "&Ve schránce...\tF9", 118 - MENUITEM "&Smazat\tDel", ID_FILE_DELETE - MENUITEM "Př&ejmenovat...", 109 - MENUITEM "V&lastnosti...\tAlt+Enter", ID_EDIT_PROPERTIES - MENUITEM SEPARATOR - MENUITEM "&Komprese...", 119 - MENUITEM "&Dekomprese...", 120 - MENUITEM SEPARATOR - MENUITEM "&Spustit...", ID_EXECUTE - MENUITEM "&Tisknout...", 102 - MENUITEM "Asociovat...", 103 - MENUITEM SEPARATOR - MENUITEM "V&ytvořit adresář...", 111 - MENUITEM "&Hledat...", 104 - MENUITEM "&Zvolit voubory...", 116 - MENUITEM SEPARATOR -#ifndef _NO_EXTENSIONS - MENUITEM "K&onec\tAlt+X", ID_FILE_EXIT -#else - MENUITEM "K&onec", ID_FILE_EXIT -#endif - } - - POPUP "&Disk" { - MENUITEM "&Kopírovat disk...", 201 - MENUITEM "&Jmenovka disk...", 202 - MENUITEM SEPARATOR - MENUITEM "&Formátovat disk...", ID_FORMAT_DISK -#ifdef _WIN95 - MENUITEM "&Vytvořit systemový disk...", -1 /*TODO*/ -#endif - MENUITEM SEPARATOR - MENUITEM "Připojit &síťové zařízení", ID_CONNECT_NETWORK_DRIVE - MENUITEM "&Odpojit &síťové zařízení", ID_DISCONNECT_NETWORK_DRIVE - MENUITEM SEPARATOR - MENUITEM "Sdílet jako...", 254 - MENUITEM "&Odstranit sdílení...", 255 - MENUITEM SEPARATOR - MENUITEM "&Zvolit zařízení...", 251 - } - - POPUP "&Adresáře" { - MENUITEM "&Další úroveň\t+", 301 - MENUITEM "Rozbalit &strom\t*", 302 - MENUITEM "Rozbalit &vše\tStrg+*", 303 - MENUITEM "Sbalit &strom\t-", 304 - MENUITEM SEPARATOR - MENUITEM "&Označit potomky", 505 - } - - POPUP "&Zobrazení" { - MENUITEM "&Strom a adresáře", 413 - MENUITEM "&Jen strom", 411 - MENUITEM "Jen &adresáře", 412 - MENUITEM SEPARATOR - MENUITEM "&Rozdělit", ID_VIEW_SPLIT - MENUITEM SEPARATOR - MENUITEM "&Jméno", ID_VIEW_NAME - MENUITEM "&Detaily všech souborů", ID_VIEW_ALL_ATTRIBUTES, CHECKED - MENUITEM "Čá&stečné detaily...", ID_VIEW_SELECTED_ATTRIBUTES - MENUITEM SEPARATOR - MENUITEM "&Třídit podle jména", ID_VIEW_SORT_NAME - MENUITEM "Třídit &podle typu", ID_VIEW_SORT_TYPE - MENUITEM "Třídit podle &velikosti", ID_VIEW_SORT_SIZE - MENUITEM "Třídit podle &data", ID_VIEW_SORT_DATE - MENUITEM SEPARATOR - MENUITEM "Třídit podle &...", ID_VIEW_FILTER - } - - POPUP "&Nastavení" { - MENUITEM "&Potvrzování...", 501 - MENUITEM "&Písmo...", ID_SELECT_FONT - MENUITEM "Upravit panel &nástrojů...", 512 - MENUITEM SEPARATOR - MENUITEM "&Panel nástrojů", ID_VIEW_TOOL_BAR, CHECKED - MENUITEM "&Panel zaříení", ID_VIEW_DRIVE_BAR, CHECKED - MENUITEM "&Stavový řádek", ID_VIEW_STATUSBAR, CHECKED -#ifndef _NO_EXTENSIONS - MENUITEM "&Celaá obrazovka\tCtrl+Shift+S", ID_VIEW_FULLSCREEN -#endif - MENUITEM SEPARATOR - MENUITEM "&Minimalizovat při spuštění", 504 - MENUITEM "&Uložit nastavení při vypnutí",511 - } - - - POPUP "&Zabezpečení" { - MENUITEM "&Přístup...", 605 - MENUITEM "&Logování...", 606 - MENUITEM "&Vlastník...", 607 - } - - POPUP "&Okno" { - MENUITEM "Nové &okno", ID_WINDOW_NEW - MENUITEM "Kaskádování\tCtrl+F5", ID_WINDOW_CASCADE - MENUITEM "Uspořádat &horizontálně", ID_WINDOW_TILE_HORZ - MENUITEM "Uspořádat &vertikálně\tCtrl+F4",ID_WINDOW_TILE_VERT -#ifndef _NO_EXTENSIONS - MENUITEM "Zarovnat automaticky", ID_WINDOW_AUTOSORT -#endif - MENUITEM "Zarovnat &symboly", ID_WINDOW_ARRANGE - MENUITEM "&Aktualizovat\tF5", ID_REFRESH - } - - POPUP "&?" { - MENUITEM "&Témata nápovědy\tF1", ID_HELP - MENUITEM "Hledání v &nápovědě...\tF1", ID_HELP - MENUITEM "&Jak používat nápovědu\tF1", ID_HELP_USING - MENUITEM SEPARATOR - MENUITEM "&Informace o Winefile...", ID_ABOUT -#ifdef __WINE__ - MENUITEM "Informace o &Wine...", ID_ABOUT_WINE -#endif - } -} - - -IDD_EXECUTE DIALOG FIXED IMPURE 15, 13, 210, 63 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Spustit" -FONT 8, "MS Shell Dlg" -{ - CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 - CONTROL "&Příkaz:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 - EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL - CONTROL "Jako &Symbol", 214, "Button", BS_AUTOCHECKBOX|WS_TABSTOP,3, 45, 71, 12 - DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 - PUSHBUTTON "Zrušit", 2, 158, 23, 47, 14 - PUSHBUTTON "&Pomoc", 254, 158, 43, 47, 14 -} - -IDD_SELECT_DESTINATION DIALOG FIXED IMPURE 15, 13, 210, 63 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Zvolte cíl" -FONT 8, "MS Shell Dlg" -{ - CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 - CONTROL "&Cesta:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 - EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL - DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 - PUSHBUTTON "Zrušit", 2, 158, 23, 47, 14 - PUSHBUTTON "&Procházet", 254, 158, 43, 47, 14 -} - -STRINGTABLE -{ - IDS_FONT_SEL_DLG_NAME "Aplikování nastavení písma" - IDS_FONT_SEL_ERROR "Chyba při volbě nového písma." -} - -STRINGTABLE -{ - IDS_WINEFILE "Winefile" - IDS_ERROR "Chyba" - IDS_ROOT_FS "root fs" - IDS_UNIXFS "unixfs" - IDS_DESKTOP "Plocha" - IDS_SHELL "Příkazový řádek" - IDS_TITLEFMT "%s - %s" - IDS_NO_IMPL "Zatím neimplementováno" - IDS_WINE "WINE" - IDS_WINE_FILE "Wine File" -} - -STRINGTABLE -{ - IDS_COL_NAME "Jméno" - IDS_COL_SIZE "Velikost" - IDS_COL_CDATE "Datum vytvoření" - IDS_COL_ADATE "Datum posledního přístupu" - IDS_COL_MDATE "Datum poslední modifikace" - IDS_COL_IDX "Index/Inode" - IDS_COL_LINKS "Linky" - IDS_COL_ATTR "Atributy" - IDS_COL_SEC "Zabezpečení" -} +/* + * WineFile + * Czech Language Support + * + * Copyright 2000 Martin Fuchs + * Copyright 2002 Steven Edwards + * Copyright 2002 Alexandre Julliard + * Copyright 2004 David Kredba + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) + + +/* Menu */ + +IDM_WINEFILE MENU FIXED IMPURE +{ + POPUP "&Soubor" { + MENUITEM "&Otevřít\tEnter", ID_ACTIVATE + MENUITEM "&Přesunout...\tF7", ID_FILE_MOVE + MENUITEM "&Kopírovat...\tF8", ID_FILE_COPY + MENUITEM "&Ve schránce...\tF9", 118 + MENUITEM "&Smazat\tDel", ID_FILE_DELETE + MENUITEM "Př&ejmenovat...", 109 + MENUITEM "V&lastnosti...\tAlt+Enter", ID_EDIT_PROPERTIES + MENUITEM SEPARATOR + MENUITEM "&Komprese...", 119 + MENUITEM "&Dekomprese...", 120 + MENUITEM SEPARATOR + MENUITEM "&Spustit...", ID_EXECUTE + MENUITEM "&Tisknout...", 102 + MENUITEM "Asociovat...", 103 + MENUITEM SEPARATOR + MENUITEM "V&ytvořit adresář...", 111 + MENUITEM "&Hledat...", 104 + MENUITEM "&Zvolit voubory...", 116 + MENUITEM SEPARATOR +#ifndef _NO_EXTENSIONS + MENUITEM "K&onec\tAlt+X", ID_FILE_EXIT +#else + MENUITEM "K&onec", ID_FILE_EXIT +#endif + } + + POPUP "&Disk" { + MENUITEM "&Kopírovat disk...", 201 + MENUITEM "&Jmenovka disk...", 202 + MENUITEM SEPARATOR + MENUITEM "&Formátovat disk...", ID_FORMAT_DISK +#ifdef _WIN95 + MENUITEM "&Vytvořit systemový disk...", -1 /*TODO*/ +#endif + MENUITEM SEPARATOR + MENUITEM "Připojit &síťové zařízení", ID_CONNECT_NETWORK_DRIVE + MENUITEM "&Odpojit &síťové zařízení", ID_DISCONNECT_NETWORK_DRIVE + MENUITEM SEPARATOR + MENUITEM "Sdílet jako...", 254 + MENUITEM "&Odstranit sdílení...", 255 + MENUITEM SEPARATOR + MENUITEM "&Zvolit zařízení...", 251 + } + + POPUP "&Adresáře" { + MENUITEM "&Další úroveň\t+", 301 + MENUITEM "Rozbalit &strom\t*", 302 + MENUITEM "Rozbalit &vše\tStrg+*", 303 + MENUITEM "Sbalit &strom\t-", 304 + MENUITEM SEPARATOR + MENUITEM "&Označit potomky", 505 + } + + POPUP "&Zobrazení" { + MENUITEM "&Strom a adresáře", 413 + MENUITEM "&Jen strom", 411 + MENUITEM "Jen &adresáře", 412 + MENUITEM SEPARATOR + MENUITEM "&Rozdělit", ID_VIEW_SPLIT + MENUITEM SEPARATOR + MENUITEM "&Jméno", ID_VIEW_NAME + MENUITEM "&Detaily všech souborů", ID_VIEW_ALL_ATTRIBUTES, CHECKED + MENUITEM "Čá&stečné detaily...", ID_VIEW_SELECTED_ATTRIBUTES + MENUITEM SEPARATOR + MENUITEM "&Třídit podle jména", ID_VIEW_SORT_NAME + MENUITEM "Třídit &podle typu", ID_VIEW_SORT_TYPE + MENUITEM "Třídit podle &velikosti", ID_VIEW_SORT_SIZE + MENUITEM "Třídit podle &data", ID_VIEW_SORT_DATE + MENUITEM SEPARATOR + MENUITEM "Třídit podle &...", ID_VIEW_FILTER + } + + POPUP "&Nastavení" { + MENUITEM "&Potvrzování...", 501 + MENUITEM "&Písmo...", ID_SELECT_FONT + MENUITEM "Upravit panel &nástrojů...", 512 + MENUITEM SEPARATOR + MENUITEM "&Panel nástrojů", ID_VIEW_TOOL_BAR, CHECKED + MENUITEM "&Panel zaříení", ID_VIEW_DRIVE_BAR, CHECKED + MENUITEM "&Stavový řádek", ID_VIEW_STATUSBAR, CHECKED +#ifndef _NO_EXTENSIONS + MENUITEM "&Celaá obrazovka\tCtrl+Shift+S", ID_VIEW_FULLSCREEN +#endif + MENUITEM SEPARATOR + MENUITEM "&Minimalizovat při spuštění", 504 + MENUITEM "&Uložit nastavení při vypnutí",511 + } + + + POPUP "&Zabezpečení" { + MENUITEM "&Přístup...", 605 + MENUITEM "&Logování...", 606 + MENUITEM "&Vlastník...", 607 + } + + POPUP "&Okno" { + MENUITEM "Nové &okno", ID_WINDOW_NEW + MENUITEM "Kaskádování\tCtrl+F5", ID_WINDOW_CASCADE + MENUITEM "Uspořádat &horizontálně", ID_WINDOW_TILE_HORZ + MENUITEM "Uspořádat &vertikálně\tCtrl+F4",ID_WINDOW_TILE_VERT +#ifndef _NO_EXTENSIONS + MENUITEM "Zarovnat automaticky", ID_WINDOW_AUTOSORT +#endif + MENUITEM "Zarovnat &symboly", ID_WINDOW_ARRANGE + MENUITEM "&Aktualizovat\tF5", ID_REFRESH + } + + POPUP "&?" { + MENUITEM "&Témata nápovědy\tF1", ID_HELP + MENUITEM "Hledání v &nápovědě...\tF1", ID_HELP + MENUITEM "&Jak používat nápovědu\tF1", ID_HELP_USING + MENUITEM SEPARATOR + MENUITEM "&Informace o Winefile...", ID_ABOUT +#ifdef __WINE__ + MENUITEM "Informace o &Wine...", ID_ABOUT_WINE +#endif + } +} + + +IDD_EXECUTE DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Spustit" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 + CONTROL "&Příkaz:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 + EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL + CONTROL "Jako &Symbol", 214, "Button", BS_AUTOCHECKBOX|WS_TABSTOP,3, 45, 71, 12 + DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 + PUSHBUTTON "Zrušit", 2, 158, 23, 47, 14 + PUSHBUTTON "&Pomoc", 254, 158, 43, 47, 14 +} + +IDD_SELECT_DESTINATION DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Zvolte cíl" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 + CONTROL "&Cesta:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 + EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL + DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 + PUSHBUTTON "Zrušit", 2, 158, 23, 47, 14 + PUSHBUTTON "&Procházet", 254, 158, 43, 47, 14 +} + +STRINGTABLE +{ + IDS_FONT_SEL_DLG_NAME "Aplikování nastavení písma" + IDS_FONT_SEL_ERROR "Chyba při volbě nového písma." +} + +STRINGTABLE +{ + IDS_WINEFILE "Winefile" + IDS_ERROR "Chyba" + IDS_ROOT_FS "root fs" + IDS_UNIXFS "unixfs" + IDS_DESKTOP "Plocha" + IDS_SHELL "Příkazový řádek" + IDS_TITLEFMT "%s - %s" + IDS_NO_IMPL "Zatím neimplementováno" + IDS_WINE "WINE" + IDS_WINE_FILE "Wine File" +} + +STRINGTABLE +{ + IDS_COL_NAME "Jméno" + IDS_COL_SIZE "Velikost" + IDS_COL_CDATE "Datum vytvoření" + IDS_COL_ADATE "Datum posledního přístupu" + IDS_COL_MDATE "Datum poslední modifikace" + IDS_COL_IDX "Index/Inode" + IDS_COL_LINKS "Linky" + IDS_COL_ATTR "Atributy" + IDS_COL_SEC "Zabezpečení" +} diff --git a/reactos/base/applications/winefile/lang/Pl.rc b/reactos/base/applications/winefile/lang/Pl.rc index c5fa1e14bae..34fe0165b3e 100644 --- a/reactos/base/applications/winefile/lang/Pl.rc +++ b/reactos/base/applications/winefile/lang/Pl.rc @@ -1,183 +1,183 @@ -/* - * WineFile - * Polish Language Support - * - * Copyright 2000 Martin Fuchs - * Copyright 2002 Steven Edwards - * Copyright 2002 Alexandre Julliard - * Copyright 2004 Piotr Caban - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_POLISH, SUBLANG_DEFAULT - -/* Menu */ - -IDM_WINEFILE MENU FIXED IMPURE -{ - POPUP "&Plik" { - MENUITEM "&Otwórz\tEnter", ID_ACTIVATE - MENUITEM "&Przenieś...\tF7", ID_FILE_MOVE - MENUITEM "&Kopiuj...\tF8", ID_FILE_COPY - MENUITEM "W s&chowku...\tF9", 118 - MENUITEM "&Usuń\tDel", ID_FILE_DELETE - MENUITEM "&Zmień nazwę...", 109 - MENUITEM "Ustawie&nia...\tAlt+Enter", ID_EDIT_PROPERTIES - MENUITEM SEPARATOR - MENUITEM "&Kompresja...", 119 - MENUITEM "&Dekompresja...", 120 - MENUITEM SEPARATOR - MENUITEM "&Uruchom...", ID_EXECUTE - MENUITEM "&Drukuj...", 102 - MENUITEM "Skojarz...", 103 - MENUITEM SEPARATOR - MENUITEM "U&twórz folder...", 111 - MENUITEM "&Szukaj...", 104 - MENUITEM "&Zaznacz pliki...", 116 - MENUITEM SEPARATOR -#ifndef _NO_EXTENSIONS - MENUITEM "&Wyjście\tAlt+X", ID_FILE_EXIT -#else - MENUITEM "&Wyjście", ID_FILE_EXIT -#endif - } - - POPUP "&Dysk" { - MENUITEM "&Kopiuj dusk...", 201 - MENUITEM "&Etykieta dysku...", 202 - MENUITEM SEPARATOR - MENUITEM "&Formatuj dysk...", ID_FORMAT_DISK -#ifdef _WIN95 - MENUITEM "&Stwórz dysk systemowy...", -1 /*TODO*/ -#endif - MENUITEM SEPARATOR - MENUITEM "&Podłącz Dysk Sieciowy", ID_CONNECT_NETWORK_DRIVE - MENUITEM "&Odłącz Dysk Sieciowy", ID_DISCONNECT_NETWORK_DRIVE - MENUITEM SEPARATOR - MENUITEM "Udostępnij jako...", 254 - MENUITEM "&Nie udostępniaj...", 255 - MENUITEM SEPARATOR - MENUITEM "Wybór &dysku...", 251 - } - - POPUP "&Katalogi" { - MENUITEM "&Następny poziom\t+", 301 - MENUITEM "&Rozwiń drzewo\t*", 302 - MENUITEM "Rozwiń &wszystko\tStrg+*", 303 - MENUITEM "&Zwiń drzewo\t-", 304 - MENUITEM SEPARATOR - MENUITEM "Zaznacz &podkatalogi", 505 - } - - POPUP "&Widok" { - MENUITEM "&Drzewo i katalogi", 413 - MENUITEM "D&rzewo", 411 - MENUITEM "&Katalogi", 412 - MENUITEM SEPARATOR - MENUITEM "&Połącz", ID_VIEW_SPLIT - MENUITEM SEPARATOR - MENUITEM "&Nazwa", ID_VIEW_NAME - MENUITEM "&Wszystkie atrybuty pliku", ID_VIEW_ALL_ATTRIBUTES, CHECKED - MENUITEM "Wybrane &atrybuty pliku...", ID_VIEW_SELECTED_ATTRIBUTES - MENUITEM SEPARATOR - MENUITEM "P&osortuj alfabetycznie", 404 - MENUITEM "Posortuj po &typie", 405 - MENUITEM "Rozmieść &po wielkości", 406 - MENUITEM "&Sortuj po dacie", 407 - MENUITEM SEPARATOR - MENUITEM "Sortuj po &...", ID_VIEW_FILTER - } - - POPUP "&Opcje" { - MENUITEM "&Potwierdzenie...", 501 - MENUITEM "&Czcionka...", ID_SELECT_FONT - MENUITEM "&Ustawienia paska narzędzi...", 512 - MENUITEM SEPARATOR - MENUITEM "Pasek &narzędzi", ID_VIEW_TOOL_BAR, CHECKED - MENUITEM "Pasek &dysków", ID_VIEW_DRIVE_BAR, CHECKED - MENUITEM "Pasek &statusu", ID_VIEW_STATUSBAR, CHECKED -#ifndef _NO_EXTENSIONS - MENUITEM "Pełny &ekran\tCtrl+Shift+S", ID_VIEW_FULLSCREEN -#endif - MENUITEM SEPARATOR - MENUITEM "&Zminimalizuj przy starcie", 504 - MENUITEM "Z&apisz ustawienia przed zakończeniem",511 - } - - - POPUP "&Bezpieczeństwo" { - MENUITEM "&Dostęp...", 605 - MENUITEM "&Logowanie...", 606 - MENUITEM "&Właściciel...", 607 - } - - POPUP "&Okno" { - MENUITEM "&Nowe okno", ID_WINDOW_NEW - MENUITEM "&Kaskadująco\tCtrl+F5", ID_WINDOW_CASCADE - MENUITEM "&Tytuł pionowo", ID_WINDOW_TILE_HORZ - MENUITEM "Tytuł &poziomo\tCtrl+F4", ID_WINDOW_TILE_VERT -#ifndef _NO_EXTENSIONS - MENUITEM "Rozmieść automatycznie", ID_WINDOW_AUTOSORT -#endif - MENUITEM "Rozmieść &symbole", ID_WINDOW_ARRANGE - MENUITEM "&Odświerz\tF5", ID_REFRESH - } - - POPUP "&?" { - MENUITEM "&Tematu pomocy\tF1", ID_HELP - MENUITEM "&Szukaj...", ID_HELP - MENUITEM "&Używanie pomocy", ID_HELP_USING - MENUITEM SEPARATOR - MENUITEM "&Winefile...", ID_ABOUT -#ifdef __WINE__ - MENUITEM "W&ine...", ID_ABOUT_WINE -#endif - } -} - - -IDD_EXECUTE DIALOG FIXED IMPURE 15, 13, 210, 63 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Uruchom" -FONT 8, "MS Shell Dlg" -{ - CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 - CONTROL "&Polecenie:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 - EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL - CONTROL "Jako &symbol", 214, "Button", BS_AUTOCHECKBOX|WS_TABSTOP,3, 45, 71, 12 - DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 - PUSHBUTTON "Anuluj", 2, 158, 23, 47, 14 - PUSHBUTTON "&Pomoc", 254, 158, 43, 47, 14 -} - -IDD_SELECT_DESTINATION DIALOG FIXED IMPURE 15, 13, 210, 63 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Wybór celu" -FONT 8, "MS Shell Dlg" -{ - CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 - CONTROL "&Ścieżka:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 - EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL - DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 - PUSHBUTTON "Anuluj", 2, 158, 23, 47, 14 - PUSHBUTTON "&Przeglądaj", 254, 158, 43, 47, 14 -} - -STRINGTABLE -{ - IDS_FONT_SEL_DLG_NAME "Wprowadzanie ustawień czcionki" - IDS_FONT_SEL_ERROR "Błąd przy wybieraniu czcionki" -} +/* + * WineFile + * Polish Language Support + * + * Copyright 2000 Martin Fuchs + * Copyright 2002 Steven Edwards + * Copyright 2002 Alexandre Julliard + * Copyright 2004 Piotr Caban + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT + +/* Menu */ + +IDM_WINEFILE MENU FIXED IMPURE +{ + POPUP "&Plik" { + MENUITEM "&Otwórz\tEnter", ID_ACTIVATE + MENUITEM "&Przenieś...\tF7", ID_FILE_MOVE + MENUITEM "&Kopiuj...\tF8", ID_FILE_COPY + MENUITEM "W s&chowku...\tF9", 118 + MENUITEM "&Usuń\tDel", ID_FILE_DELETE + MENUITEM "&Zmień nazwę...", 109 + MENUITEM "Ustawie&nia...\tAlt+Enter", ID_EDIT_PROPERTIES + MENUITEM SEPARATOR + MENUITEM "&Kompresja...", 119 + MENUITEM "&Dekompresja...", 120 + MENUITEM SEPARATOR + MENUITEM "&Uruchom...", ID_EXECUTE + MENUITEM "&Drukuj...", 102 + MENUITEM "Skojarz...", 103 + MENUITEM SEPARATOR + MENUITEM "U&twórz folder...", 111 + MENUITEM "&Szukaj...", 104 + MENUITEM "&Zaznacz pliki...", 116 + MENUITEM SEPARATOR +#ifndef _NO_EXTENSIONS + MENUITEM "&Wyjście\tAlt+X", ID_FILE_EXIT +#else + MENUITEM "&Wyjście", ID_FILE_EXIT +#endif + } + + POPUP "&Dysk" { + MENUITEM "&Kopiuj dusk...", 201 + MENUITEM "&Etykieta dysku...", 202 + MENUITEM SEPARATOR + MENUITEM "&Formatuj dysk...", ID_FORMAT_DISK +#ifdef _WIN95 + MENUITEM "&Stwórz dysk systemowy...", -1 /*TODO*/ +#endif + MENUITEM SEPARATOR + MENUITEM "&Podłącz Dysk Sieciowy", ID_CONNECT_NETWORK_DRIVE + MENUITEM "&Odłącz Dysk Sieciowy", ID_DISCONNECT_NETWORK_DRIVE + MENUITEM SEPARATOR + MENUITEM "Udostępnij jako...", 254 + MENUITEM "&Nie udostępniaj...", 255 + MENUITEM SEPARATOR + MENUITEM "Wybór &dysku...", 251 + } + + POPUP "&Katalogi" { + MENUITEM "&Następny poziom\t+", 301 + MENUITEM "&Rozwiń drzewo\t*", 302 + MENUITEM "Rozwiń &wszystko\tStrg+*", 303 + MENUITEM "&Zwiń drzewo\t-", 304 + MENUITEM SEPARATOR + MENUITEM "Zaznacz &podkatalogi", 505 + } + + POPUP "&Widok" { + MENUITEM "&Drzewo i katalogi", 413 + MENUITEM "D&rzewo", 411 + MENUITEM "&Katalogi", 412 + MENUITEM SEPARATOR + MENUITEM "&Połącz", ID_VIEW_SPLIT + MENUITEM SEPARATOR + MENUITEM "&Nazwa", ID_VIEW_NAME + MENUITEM "&Wszystkie atrybuty pliku", ID_VIEW_ALL_ATTRIBUTES, CHECKED + MENUITEM "Wybrane &atrybuty pliku...", ID_VIEW_SELECTED_ATTRIBUTES + MENUITEM SEPARATOR + MENUITEM "P&osortuj alfabetycznie", 404 + MENUITEM "Posortuj po &typie", 405 + MENUITEM "Rozmieść &po wielkości", 406 + MENUITEM "&Sortuj po dacie", 407 + MENUITEM SEPARATOR + MENUITEM "Sortuj po &...", ID_VIEW_FILTER + } + + POPUP "&Opcje" { + MENUITEM "&Potwierdzenie...", 501 + MENUITEM "&Czcionka...", ID_SELECT_FONT + MENUITEM "&Ustawienia paska narzędzi...", 512 + MENUITEM SEPARATOR + MENUITEM "Pasek &narzędzi", ID_VIEW_TOOL_BAR, CHECKED + MENUITEM "Pasek &dysków", ID_VIEW_DRIVE_BAR, CHECKED + MENUITEM "Pasek &statusu", ID_VIEW_STATUSBAR, CHECKED +#ifndef _NO_EXTENSIONS + MENUITEM "Pełny &ekran\tCtrl+Shift+S", ID_VIEW_FULLSCREEN +#endif + MENUITEM SEPARATOR + MENUITEM "&Zminimalizuj przy starcie", 504 + MENUITEM "Z&apisz ustawienia przed zakończeniem",511 + } + + + POPUP "&Bezpieczeństwo" { + MENUITEM "&Dostęp...", 605 + MENUITEM "&Logowanie...", 606 + MENUITEM "&Właściciel...", 607 + } + + POPUP "&Okno" { + MENUITEM "&Nowe okno", ID_WINDOW_NEW + MENUITEM "&Kaskadująco\tCtrl+F5", ID_WINDOW_CASCADE + MENUITEM "&Tytuł pionowo", ID_WINDOW_TILE_HORZ + MENUITEM "Tytuł &poziomo\tCtrl+F4", ID_WINDOW_TILE_VERT +#ifndef _NO_EXTENSIONS + MENUITEM "Rozmieść automatycznie", ID_WINDOW_AUTOSORT +#endif + MENUITEM "Rozmieść &symbole", ID_WINDOW_ARRANGE + MENUITEM "&Odświerz\tF5", ID_REFRESH + } + + POPUP "&?" { + MENUITEM "&Tematu pomocy\tF1", ID_HELP + MENUITEM "&Szukaj...", ID_HELP + MENUITEM "&Używanie pomocy", ID_HELP_USING + MENUITEM SEPARATOR + MENUITEM "&Winefile...", ID_ABOUT +#ifdef __WINE__ + MENUITEM "W&ine...", ID_ABOUT_WINE +#endif + } +} + + +IDD_EXECUTE DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Uruchom" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 + CONTROL "&Polecenie:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 + EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL + CONTROL "Jako &symbol", 214, "Button", BS_AUTOCHECKBOX|WS_TABSTOP,3, 45, 71, 12 + DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 + PUSHBUTTON "Anuluj", 2, 158, 23, 47, 14 + PUSHBUTTON "&Pomoc", 254, 158, 43, 47, 14 +} + +IDD_SELECT_DESTINATION DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Wybór celu" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 + CONTROL "&Ścieżka:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 + EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL + DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 + PUSHBUTTON "Anuluj", 2, 158, 23, 47, 14 + PUSHBUTTON "&Przeglądaj", 254, 158, 43, 47, 14 +} + +STRINGTABLE +{ + IDS_FONT_SEL_DLG_NAME "Wprowadzanie ustawień czcionki" + IDS_FONT_SEL_ERROR "Błąd przy wybieraniu czcionki" +} diff --git a/reactos/base/applications/winefile/lang/Sv.rc b/reactos/base/applications/winefile/lang/Sv.rc index 99984cf9cf3..5b2f366d604 100644 --- a/reactos/base/applications/winefile/lang/Sv.rc +++ b/reactos/base/applications/winefile/lang/Sv.rc @@ -1,209 +1,209 @@ -/* - * WineFile - * Swedish Language Support - * - * Copyright 2005 David Nordenberg - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL -#pragma code_page(1252) - - -/* Menu */ - - -IDM_WINEFILE MENU FIXED IMPURE -{ - POPUP "&Arkiv" { - MENUITEM "&Öppna\tEnter", ID_ACTIVATE - MENUITEM "&Flytta...\tF7", ID_FILE_MOVE - MENUITEM "&Kopiera...\tF8", ID_FILE_COPY - MENUITEM "&I urklipp...\tF9", 118 - MENUITEM "&Ta bort\tDel", ID_FILE_DELETE - MENUITEM "&Byt namn...", 109 - MENUITEM "&Egenskaper...\tAlt+Enter", ID_EDIT_PROPERTIES - MENUITEM SEPARATOR - MENUITEM "&Komprimera...", 119 - MENUITEM "Packa &upp...", 120 - MENUITEM SEPARATOR - MENUITEM "&Kör...", ID_EXECUTE - MENUITEM "&Skriv ut...", 102 - MENUITEM "Associera...", 103 - MENUITEM SEPARATOR - MENUITEM "Skapa mapp...", 111 - MENUITEM "&Sök...", 104 - MENUITEM "&Välj filer...", 116 - MENUITEM SEPARATOR -#ifndef _NO_EXTENSIONS - MENUITEM "&Avsluta\tAlt+X", ID_FILE_EXIT -#else - MENUITEM "&Avsluta", ID_FILE_EXIT -#endif - } - - POPUP "&Disk" { - MENUITEM "&Kopiera disk...", 201 - MENUITEM "&Namnge disk...", 202 - MENUITEM SEPARATOR - MENUITEM "&Formatera disk...", ID_FORMAT_DISK -#ifdef _WIN95 - MENUITEM "&Skapa systemdisk...", -1 /*TODO*/ -#endif - MENUITEM SEPARATOR - MENUITEM "Anslut &Nätverksenhet", ID_CONNECT_NETWORK_DRIVE - MENUITEM "&Koppla ifrĺn Nätverksenhet", ID_DISCONNECT_NETWORK_DRIVE - MENUITEM SEPARATOR - MENUITEM "Dela ut...", 254 - MENUITEM "&Ta bort utdelning...", 255 - MENUITEM SEPARATOR - MENUITEM "&Välj enhet...", 251 - } - - POPUP "&Träd" { - MENUITEM "&Nästa nivĺ\t+", 301 - MENUITEM "Utöka &träd\t*", 302 - MENUITEM "Utöka &alla\tCtrl+*", 303 - MENUITEM "Kollapsa &träd\t-", 304 - MENUITEM SEPARATOR - MENUITEM "&Markera undermappar", 505 - } - - POPUP "&Visa" { - MENUITEM "&Träd och mapp", 413 - MENUITEM "Bara tr&äd", 411 - MENUITEM "Bara &mapp", 412 - MENUITEM SEPARATOR - MENUITEM "De&la", ID_VIEW_SPLIT - MENUITEM SEPARATOR - MENUITEM "&Namn", ID_VIEW_NAME - MENUITEM "&Alla Fildetaljer", ID_VIEW_ALL_ATTRIBUTES, CHECKED - MENUITEM "&Vissa detaljer...", ID_VIEW_SELECTED_ATTRIBUTES - MENUITEM SEPARATOR - MENUITEM "&Sortera efter namn", ID_VIEW_SORT_NAME - MENUITEM "Sortera efter t&yp", ID_VIEW_SORT_TYPE - MENUITEM "Sortera efter st&orlek", ID_VIEW_SORT_SIZE - MENUITEM "Sortera efter &datum", ID_VIEW_SORT_DATE - MENUITEM SEPARATOR - MENUITEM "Sortera efter &...", ID_VIEW_FILTER - } - - POPUP "&Inställningar" { - MENUITEM "&Bekräftelse...", 501 - MENUITEM "&Teckensnitt...", ID_SELECT_FONT - MENUITEM "&Konfigurera verktygsfält...", 512 - MENUITEM SEPARATOR - MENUITEM "&Verktygsfält", ID_VIEW_TOOL_BAR, CHECKED - MENUITEM "&Enhetsfält", ID_VIEW_DRIVE_BAR, CHECKED - MENUITEM "St&atusfält", ID_VIEW_STATUSBAR, CHECKED -#ifndef _NO_EXTENSIONS - MENUITEM "F&ullskärm\tCtrl+Shift+S", ID_VIEW_FULLSCREEN -#endif - MENUITEM SEPARATOR - MENUITEM "&Minimera vid körning", 504 - MENUITEM "&Spara ändringar vid stängning", 511 - } - - POPUP "&Säkerhet" { - MENUITEM "&Ĺtkomst...", 605 - MENUITEM "&Loggning...", 606 - MENUITEM "&Ägare...", 607 - } - - POPUP "&Fönster" { - MENUITEM "Nytt &fönster", ID_WINDOW_NEW - MENUITEM "Överlappande\tCtrl+F5", ID_WINDOW_CASCADE - MENUITEM "Ordna &horizontellt", ID_WINDOW_TILE_HORZ - MENUITEM "Ordna &vertikalt\tCtrl+F4", ID_WINDOW_TILE_VERT -#ifndef _NO_EXTENSIONS - MENUITEM "Ordna automatiskt", ID_WINDOW_AUTOSORT -#endif - MENUITEM "Ordna &symboler", ID_WINDOW_ARRANGE - MENUITEM "&Uppdatera\tF5", ID_REFRESH - } - - POPUP "&?" { - MENUITEM "&Hjälpavsnitt\tF1", ID_HELP - MENUITEM "Hjälp &sök...\tF1", ID_HELP - MENUITEM "&Använda hjälpen\tF1", ID_HELP_USING - MENUITEM SEPARATOR - MENUITEM "Information om &Winefile...", ID_ABOUT -#ifdef __WINE__ - MENUITEM "Info about &Wine...", ID_ABOUT_WINE -#endif - } -} - - -IDD_EXECUTE DIALOG FIXED IMPURE 15, 13, 210, 63 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Kör" -FONT 8, "MS Shell Dlg" -{ - CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 - CONTROL "&Kommando:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 - EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL - CONTROL "Som &symbol", 214, "Button", BS_AUTOCHECKBOX|WS_TABSTOP,3, 45, 71, 12 - DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 - PUSHBUTTON "Avbryt", 2, 158, 23, 47, 14 - PUSHBUTTON "&Hjälp", 254, 158, 43, 47, 14 -} - -IDD_SELECT_DESTINATION DIALOG FIXED IMPURE 15, 13, 210, 63 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Välj mĺl" -FONT 8, "MS Shell Dlg" -{ - CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 - CONTROL "&Sökväg:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 - EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL - DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 - PUSHBUTTON "Avbryt", 2, 158, 23, 47, 14 - PUSHBUTTON "&Bläddra", 254, 158, 43, 47, 14 -} - -STRINGTABLE -{ - IDS_FONT_SEL_DLG_NAME "Verkställ teckensnittsinställningar" - IDS_FONT_SEL_ERROR "Ett fel uppstog när ett nytt teckensnitt valdes." -} - -STRINGTABLE -{ - IDS_WINEFILE "Winefile" - IDS_ERROR "Fel" - IDS_ROOT_FS "root fs" - IDS_UNIXFS "unixfs" - IDS_DESKTOP "Skrivbord" - IDS_SHELL "Skal" - IDS_TITLEFMT "%s - %s" - IDS_NO_IMPL "Ej implementerat ännu" - IDS_WINE "WINE" - IDS_WINE_FILE "Wine File" -} - -STRINGTABLE -{ - IDS_COL_NAME "Namn" - IDS_COL_SIZE "Storlek" - IDS_COL_CDATE "CDatum" - IDS_COL_ADATE "ADatum" - IDS_COL_MDATE "MDatum" - IDS_COL_IDX "Index/Inode" - IDS_COL_LINKS "Länkar" - IDS_COL_ATTR "Attribut" - IDS_COL_SEC "Säkerhet" -} +/* + * WineFile + * Swedish Language Support + * + * Copyright 2005 David Nordenberg + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL +#pragma code_page(1252) + + +/* Menu */ + + +IDM_WINEFILE MENU FIXED IMPURE +{ + POPUP "&Arkiv" { + MENUITEM "&Öppna\tEnter", ID_ACTIVATE + MENUITEM "&Flytta...\tF7", ID_FILE_MOVE + MENUITEM "&Kopiera...\tF8", ID_FILE_COPY + MENUITEM "&I urklipp...\tF9", 118 + MENUITEM "&Ta bort\tDel", ID_FILE_DELETE + MENUITEM "&Byt namn...", 109 + MENUITEM "&Egenskaper...\tAlt+Enter", ID_EDIT_PROPERTIES + MENUITEM SEPARATOR + MENUITEM "&Komprimera...", 119 + MENUITEM "Packa &upp...", 120 + MENUITEM SEPARATOR + MENUITEM "&Kör...", ID_EXECUTE + MENUITEM "&Skriv ut...", 102 + MENUITEM "Associera...", 103 + MENUITEM SEPARATOR + MENUITEM "Skapa mapp...", 111 + MENUITEM "&Sök...", 104 + MENUITEM "&Välj filer...", 116 + MENUITEM SEPARATOR +#ifndef _NO_EXTENSIONS + MENUITEM "&Avsluta\tAlt+X", ID_FILE_EXIT +#else + MENUITEM "&Avsluta", ID_FILE_EXIT +#endif + } + + POPUP "&Disk" { + MENUITEM "&Kopiera disk...", 201 + MENUITEM "&Namnge disk...", 202 + MENUITEM SEPARATOR + MENUITEM "&Formatera disk...", ID_FORMAT_DISK +#ifdef _WIN95 + MENUITEM "&Skapa systemdisk...", -1 /*TODO*/ +#endif + MENUITEM SEPARATOR + MENUITEM "Anslut &Nätverksenhet", ID_CONNECT_NETWORK_DRIVE + MENUITEM "&Koppla ifrĺn Nätverksenhet", ID_DISCONNECT_NETWORK_DRIVE + MENUITEM SEPARATOR + MENUITEM "Dela ut...", 254 + MENUITEM "&Ta bort utdelning...", 255 + MENUITEM SEPARATOR + MENUITEM "&Välj enhet...", 251 + } + + POPUP "&Träd" { + MENUITEM "&Nästa nivĺ\t+", 301 + MENUITEM "Utöka &träd\t*", 302 + MENUITEM "Utöka &alla\tCtrl+*", 303 + MENUITEM "Kollapsa &träd\t-", 304 + MENUITEM SEPARATOR + MENUITEM "&Markera undermappar", 505 + } + + POPUP "&Visa" { + MENUITEM "&Träd och mapp", 413 + MENUITEM "Bara tr&äd", 411 + MENUITEM "Bara &mapp", 412 + MENUITEM SEPARATOR + MENUITEM "De&la", ID_VIEW_SPLIT + MENUITEM SEPARATOR + MENUITEM "&Namn", ID_VIEW_NAME + MENUITEM "&Alla Fildetaljer", ID_VIEW_ALL_ATTRIBUTES, CHECKED + MENUITEM "&Vissa detaljer...", ID_VIEW_SELECTED_ATTRIBUTES + MENUITEM SEPARATOR + MENUITEM "&Sortera efter namn", ID_VIEW_SORT_NAME + MENUITEM "Sortera efter t&yp", ID_VIEW_SORT_TYPE + MENUITEM "Sortera efter st&orlek", ID_VIEW_SORT_SIZE + MENUITEM "Sortera efter &datum", ID_VIEW_SORT_DATE + MENUITEM SEPARATOR + MENUITEM "Sortera efter &...", ID_VIEW_FILTER + } + + POPUP "&Inställningar" { + MENUITEM "&Bekräftelse...", 501 + MENUITEM "&Teckensnitt...", ID_SELECT_FONT + MENUITEM "&Konfigurera verktygsfält...", 512 + MENUITEM SEPARATOR + MENUITEM "&Verktygsfält", ID_VIEW_TOOL_BAR, CHECKED + MENUITEM "&Enhetsfält", ID_VIEW_DRIVE_BAR, CHECKED + MENUITEM "St&atusfält", ID_VIEW_STATUSBAR, CHECKED +#ifndef _NO_EXTENSIONS + MENUITEM "F&ullskärm\tCtrl+Shift+S", ID_VIEW_FULLSCREEN +#endif + MENUITEM SEPARATOR + MENUITEM "&Minimera vid körning", 504 + MENUITEM "&Spara ändringar vid stängning", 511 + } + + POPUP "&Säkerhet" { + MENUITEM "&Ĺtkomst...", 605 + MENUITEM "&Loggning...", 606 + MENUITEM "&Ägare...", 607 + } + + POPUP "&Fönster" { + MENUITEM "Nytt &fönster", ID_WINDOW_NEW + MENUITEM "Överlappande\tCtrl+F5", ID_WINDOW_CASCADE + MENUITEM "Ordna &horizontellt", ID_WINDOW_TILE_HORZ + MENUITEM "Ordna &vertikalt\tCtrl+F4", ID_WINDOW_TILE_VERT +#ifndef _NO_EXTENSIONS + MENUITEM "Ordna automatiskt", ID_WINDOW_AUTOSORT +#endif + MENUITEM "Ordna &symboler", ID_WINDOW_ARRANGE + MENUITEM "&Uppdatera\tF5", ID_REFRESH + } + + POPUP "&?" { + MENUITEM "&Hjälpavsnitt\tF1", ID_HELP + MENUITEM "Hjälp &sök...\tF1", ID_HELP + MENUITEM "&Använda hjälpen\tF1", ID_HELP_USING + MENUITEM SEPARATOR + MENUITEM "Information om &Winefile...", ID_ABOUT +#ifdef __WINE__ + MENUITEM "Info about &Wine...", ID_ABOUT_WINE +#endif + } +} + + +IDD_EXECUTE DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Kör" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 + CONTROL "&Kommando:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 + EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL + CONTROL "Som &symbol", 214, "Button", BS_AUTOCHECKBOX|WS_TABSTOP,3, 45, 71, 12 + DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 + PUSHBUTTON "Avbryt", 2, 158, 23, 47, 14 + PUSHBUTTON "&Hjälp", 254, 158, 43, 47, 14 +} + +IDD_SELECT_DESTINATION DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Välj mĺl" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", 101, "Static", SS_SIMPLE|SS_NOPREFIX, 3, 6, 162, 10 + CONTROL "&Sökväg:", -1, "Static", SS_LEFTNOWORDWRAP|WS_GROUP, 3, 18, 60, 10 + EDITTEXT 201, 3, 29, 134, 12, ES_AUTOHSCROLL + DEFPUSHBUTTON "OK", 1, 158, 6, 47, 14 + PUSHBUTTON "Avbryt", 2, 158, 23, 47, 14 + PUSHBUTTON "&Bläddra", 254, 158, 43, 47, 14 +} + +STRINGTABLE +{ + IDS_FONT_SEL_DLG_NAME "Verkställ teckensnittsinställningar" + IDS_FONT_SEL_ERROR "Ett fel uppstog när ett nytt teckensnitt valdes." +} + +STRINGTABLE +{ + IDS_WINEFILE "Winefile" + IDS_ERROR "Fel" + IDS_ROOT_FS "root fs" + IDS_UNIXFS "unixfs" + IDS_DESKTOP "Skrivbord" + IDS_SHELL "Skal" + IDS_TITLEFMT "%s - %s" + IDS_NO_IMPL "Ej implementerat ännu" + IDS_WINE "WINE" + IDS_WINE_FILE "Wine File" +} + +STRINGTABLE +{ + IDS_COL_NAME "Namn" + IDS_COL_SIZE "Storlek" + IDS_COL_CDATE "CDatum" + IDS_COL_ADATE "ADatum" + IDS_COL_MDATE "MDatum" + IDS_COL_IDX "Index/Inode" + IDS_COL_LINKS "Länkar" + IDS_COL_ATTR "Attribut" + IDS_COL_SEC "Säkerhet" +} From 778bad347c6bc2c6efe5aae9df498da636812d6b Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 4 Oct 2006 12:26:12 +0000 Subject: [PATCH 456/488] - Format code of InstallFatBootcodeToPartition(), changing from tabs+spaces mix to tabs only (use "ignore whitespaces" settings to view other changes) - Change installation logic when installing to a NTLDR's boot.ini: Firstly freeldr.ini is checked for existence, and either created or updated, then boot.ini is checked for having a proper entry, and if needed - entry is added. Fixes related bugs (having more and more ReactOS entries, no entry added if freeldr.ini already exists in the root folder) svn path=/trunk/; revision=24392 --- reactos/base/setup/usetup/bootsup.c | 586 ++++++++++++++-------------- 1 file changed, 293 insertions(+), 293 deletions(-) diff --git a/reactos/base/setup/usetup/bootsup.c b/reactos/base/setup/usetup/bootsup.c index 4e5b0d721f7..ddf5e208113 100644 --- a/reactos/base/setup/usetup/bootsup.c +++ b/reactos/base/setup/usetup/bootsup.c @@ -1751,311 +1751,311 @@ InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath, PUNICODE_STRING DestinationArcPath, UCHAR PartitionType) { - WCHAR SrcPath[MAX_PATH]; - WCHAR DstPath[MAX_PATH]; - NTSTATUS Status; + WCHAR SrcPath[MAX_PATH]; + WCHAR DstPath[MAX_PATH]; + NTSTATUS Status; - /* FAT or FAT32 partition */ - DPRINT1("System path: '%wZ'\n", SystemRootPath); + /* FAT or FAT32 partition */ + DPRINT1("System path: '%wZ'\n", SystemRootPath); - if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE || - DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE) - { - /* Search root directory for 'ntldr' and 'boot.ini'. */ - DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n"); - - /* Copy FreeLoader to the boot partition */ - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\freeldr.sys"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.sys"); - - DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); - Status = SetupCopyFile(SrcPath, DstPath); - if (!NT_SUCCESS(Status)) - { - DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); - return Status; - } - - /* Create or update freeldr.ini */ - if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) - { - /* Create new 'freeldr.ini' */ - DPRINT1("Create new 'freeldr.ini'\n"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); - - Status = CreateFreeLoaderIniForReactos(DstPath, - DestinationArcPath->Buffer); - if (!NT_SUCCESS(Status)) + if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE || + DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE) { - DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status); - return Status; + /* Search root directory for 'ntldr' and 'boot.ini'. */ + DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n"); + + /* Copy FreeLoader to the boot partition */ + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\freeldr.sys"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.sys"); + + DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = SetupCopyFile(SrcPath, DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + return Status; + } + + /* Create or update freeldr.ini */ + if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) + { + /* Create new 'freeldr.ini' */ + DPRINT1("Create new 'freeldr.ini'\n"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = CreateFreeLoaderIniForReactos(DstPath, + DestinationArcPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status); + return Status; + } + + /* Install new bootcode */ + if (PartitionType == PARTITION_FAT32 || + PartitionType == PARTITION_FAT32_XINT13) + { + /* Install FAT32 bootcode */ + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\fat32.bin"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\bootsect.ros"); + + DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath); + Status = InstallFat32BootCodeToFile(SrcPath, + DstPath, + SystemRootPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status); + return Status; + } + } + else + { + /* Install FAT16 bootcode */ + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\fat.bin"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\bootsect.ros"); + + DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath); + Status = InstallFat16BootCodeToFile(SrcPath, + DstPath, + SystemRootPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status); + return Status; + } + } + } + else + { + /* Update existing 'freeldr.ini' */ + DPRINT1("Update existing 'freeldr.ini'\n"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = UpdateFreeLoaderIni(DstPath, + DestinationArcPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); + return Status; + } + } + + /* Update 'boot.ini' */ + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\boot.ini"); + + DPRINT1("Update 'boot.ini': %S\n", DstPath); + Status = UpdateBootIni(DstPath, + L"C:\\bootsect.ros", + L"\"ReactOS\""); + if (!NT_SUCCESS(Status)) + { + DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status); + return Status; + } } - - /* Install new bootcode */ - if (PartitionType == PARTITION_FAT32 || - PartitionType == PARTITION_FAT32_XINT13) + else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") == TRUE || + DoesFileExist(SystemRootPath->Buffer, L"msdos.sys") == TRUE) { - /* Install FAT32 bootcode */ - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\fat32.bin"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\bootsect.ros"); + /* Search for root directory for 'io.sys' and 'msdos.sys'. */ + DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n"); - DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath); - Status = InstallFat32BootCodeToFile(SrcPath, - DstPath, - SystemRootPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status); - return Status; - } + /* Copy FreeLoader to the boot partition */ + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\freeldr.sys"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.sys"); + + DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = SetupCopyFile(SrcPath, DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + return Status; + } + + /* Create or update 'freeldr.ini' */ + if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) + { + /* Create new 'freeldr.ini' */ + DPRINT1("Create new 'freeldr.ini'\n"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = CreateFreeLoaderIniForDos(DstPath, + DestinationArcPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status); + return Status; + } + + /* Save current bootsector as 'BOOTSECT.DOS' */ + wcscpy(SrcPath, SystemRootPath->Buffer); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\bootsect.dos"); + + DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath); + Status = SaveCurrentBootSector(SrcPath, + DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); + return Status; + } + + /* Install new bootsector */ + if (PartitionType == PARTITION_FAT32 || + PartitionType == PARTITION_FAT32_XINT13) + { + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\fat32.bin"); + + DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); + Status = InstallFat32BootCodeToDisk(SrcPath, + SystemRootPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); + return Status; + } + } + else + { + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\fat.bin"); + + DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); + Status = InstallFat16BootCodeToDisk(SrcPath, + SystemRootPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); + return Status; + } + } + } + else + { + /* Update existing 'freeldr.ini' */ + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = UpdateFreeLoaderIni(DstPath, + DestinationArcPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); + return Status; + } + } } else { - /* Install FAT16 bootcode */ - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\fat.bin"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\bootsect.ros"); + /* No or unknown boot loader */ + DPRINT1("No or unknown boot loader found\n"); - DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath); - Status = InstallFat16BootCodeToFile(SrcPath, - DstPath, - SystemRootPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status); - return Status; - } + /* Copy FreeLoader to the boot partition */ + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\freeldr.sys"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.sys"); + + DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = SetupCopyFile(SrcPath, DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + return Status; + } + + /* Create or update 'freeldr.ini' */ + if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) + { + /* Create new freeldr.ini */ + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = CreateFreeLoaderIniForReactos(DstPath, + DestinationArcPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status); + return Status; + } + + /* Save current bootsector as 'BOOTSECT.OLD' */ + wcscpy(SrcPath, SystemRootPath->Buffer); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\bootsect.old"); + + DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath); + Status = SaveCurrentBootSector(SrcPath, + DstPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); + return Status; + } + + /* Install new bootsector */ + if (PartitionType == PARTITION_FAT32 || + PartitionType == PARTITION_FAT32_XINT13) + { + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\fat32.bin"); + + DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); + Status = InstallFat32BootCodeToDisk(SrcPath, + SystemRootPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); + return Status; + } + } + else + { + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\fat.bin"); + + DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); + Status = InstallFat16BootCodeToDisk(SrcPath, + SystemRootPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); + return Status; + } + } + } + else + { + /* Update existing 'freeldr.ini' */ + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + Status = UpdateFreeLoaderIni(DstPath, + DestinationArcPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); + return Status; + } + } } - /* Update 'boot.ini' */ - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\boot.ini"); - - DPRINT1("Update 'boot.ini': %S\n", DstPath); - Status = UpdateBootIni(DstPath, - L"C:\\bootsect.ros", - L"\"ReactOS\""); - if (!NT_SUCCESS(Status)) - { - DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status); - return Status; - } - } - else - { - /* Update existing 'freeldr.ini' */ - DPRINT1("Update existing 'freeldr.ini'\n"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); - - Status = UpdateFreeLoaderIni(DstPath, - DestinationArcPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); - return Status; - } - } - } - else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") == TRUE || - DoesFileExist(SystemRootPath->Buffer, L"msdos.sys") == TRUE) - { - /* Search for root directory for 'io.sys' and 'msdos.sys'. */ - DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n"); - - /* Copy FreeLoader to the boot partition */ - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\freeldr.sys"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.sys"); - - DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); - Status = SetupCopyFile(SrcPath, DstPath); - if (!NT_SUCCESS(Status)) - { - DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); - return Status; - } - - /* Create or update 'freeldr.ini' */ - if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) - { - /* Create new 'freeldr.ini' */ - DPRINT1("Create new 'freeldr.ini'\n"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); - - Status = CreateFreeLoaderIniForDos(DstPath, - DestinationArcPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status); - return Status; - } - - /* Save current bootsector as 'BOOTSECT.DOS' */ - wcscpy(SrcPath, SystemRootPath->Buffer); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\bootsect.dos"); - - DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath); - Status = SaveCurrentBootSector(SrcPath, - DstPath); - if (!NT_SUCCESS(Status)) - { - DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); - return Status; - } - - /* Install new bootsector */ - if (PartitionType == PARTITION_FAT32 || - PartitionType == PARTITION_FAT32_XINT13) - { - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\fat32.bin"); - - DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); - Status = InstallFat32BootCodeToDisk(SrcPath, - SystemRootPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); - return Status; - } - } - else - { - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\fat.bin"); - - DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); - Status = InstallFat16BootCodeToDisk(SrcPath, - SystemRootPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); - return Status; - } - } - } - else - { - /* Update existing 'freeldr.ini' */ - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); - - Status = UpdateFreeLoaderIni(DstPath, - DestinationArcPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); - return Status; - } - } - } - else - { - /* No or unknown boot loader */ - DPRINT1("No or unknown boot loader found\n"); - - /* Copy FreeLoader to the boot partition */ - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\freeldr.sys"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.sys"); - - DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath); - Status = SetupCopyFile(SrcPath, DstPath); - if (!NT_SUCCESS(Status)) - { - DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); - return Status; - } - - /* Create or update 'freeldr.ini' */ - if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) - { - /* Create new freeldr.ini */ - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); - - DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath); - Status = CreateFreeLoaderIniForReactos(DstPath, - DestinationArcPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status); - return Status; - } - - /* Save current bootsector as 'BOOTSECT.OLD' */ - wcscpy(SrcPath, SystemRootPath->Buffer); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\bootsect.old"); - - DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath); - Status = SaveCurrentBootSector(SrcPath, - DstPath); - if (!NT_SUCCESS(Status)) - { - DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); - return Status; - } - - /* Install new bootsector */ - if (PartitionType == PARTITION_FAT32 || - PartitionType == PARTITION_FAT32_XINT13) - { - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\fat32.bin"); - - DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); - Status = InstallFat32BootCodeToDisk(SrcPath, - SystemRootPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); - return Status; - } - } - else - { - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\fat.bin"); - - DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); - Status = InstallFat16BootCodeToDisk(SrcPath, - SystemRootPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); - return Status; - } - } - } - else - { - /* Update existing 'freeldr.ini' */ - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); - - Status = UpdateFreeLoaderIni(DstPath, - DestinationArcPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); - return Status; - } - } - } - - return STATUS_SUCCESS; + return STATUS_SUCCESS; } From 48236aa6421a93294eb22eba3182772fb3c72cca Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 4 Oct 2006 15:19:23 +0000 Subject: [PATCH 457/488] Don't compile with -Wconversion since we have function callbacks that have parameters with sizes different from int without forward declarations. Fixes superfluous warnings. svn path=/trunk/; revision=24394 --- reactos/lib/cmlib/cmlib.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/lib/cmlib/cmlib.mak b/reactos/lib/cmlib/cmlib.mak index f4114943cdc..467cf66d844 100644 --- a/reactos/lib/cmlib/cmlib.mak +++ b/reactos/lib/cmlib/cmlib.mak @@ -30,7 +30,7 @@ CMLIB_HOST_SOURCES = $(addprefix $(CMLIB_BASE_), \ CMLIB_HOST_OBJECTS = \ $(subst $(CMLIB_BASE), $(CMLIB_INT), $(CMLIB_HOST_SOURCES:.c=.o)) -CMLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +CMLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith \ -D_X86_ -D__i386__ -D_REACTOS_ -D_NTOSKRNL_\ -DCMLIB_HOST -D_M_IX86 -I$(CMLIB_BASE) -Iinclude/reactos -Iinclude/psdk -Iinclude/ddk -Iinclude/crt \ -D__NO_CTYPE_INLINES From d0cb64ce3d4995807597e9d5894aba13f6eed830 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 4 Oct 2006 16:00:36 +0000 Subject: [PATCH 458/488] - Implement XPSP2+ syscall stub that uses indirect pointer instead of executable code inside KUSER_SHARED_DATA. - Someone (FILIP!) please fix LdrGetProcedureAddress. It's broken and I had to rename an ntdll export to make it work (see comments). - Make sure you REBUILD CLEAN. This commit changes NCITool!!! - Setup some NPX-related CPU features in SharedUserData during KiInitializeKernel. - Remove some now-deprecated initialization functions. svn path=/trunk/; revision=24395 --- reactos/dll/ntdll/def/ntdll.def | 3 + reactos/dll/ntdll/main/i386/dispatch.S | 29 ++++++++ reactos/ntoskrnl/KrnlFun.c | 4 +- reactos/ntoskrnl/ex/init.c | 11 +--- reactos/ntoskrnl/ke/i386/cpu.c | 91 -------------------------- reactos/ntoskrnl/ke/i386/kiinit.c | 14 ++++ reactos/ntoskrnl/ke/i386/trap.s | 2 +- reactos/ntoskrnl/ldr/rtl.c | 6 ++ reactos/ntoskrnl/ps/psmgr.c | 31 +++++++++ reactos/tools/nci/ncitool.c | 2 +- 10 files changed, 89 insertions(+), 104 deletions(-) diff --git a/reactos/dll/ntdll/def/ntdll.def b/reactos/dll/ntdll/def/ntdll.def index b06e82606ab..bbb4dbd703c 100644 --- a/reactos/dll/ntdll/def/ntdll.def +++ b/reactos/dll/ntdll/def/ntdll.def @@ -37,6 +37,9 @@ KiRaiseUserExceptionDispatcher@0 KiUserApcDispatcher@16 KiUserCallbackDispatcher@12 KiUserExceptionDispatcher@8 +KiIntSystemCall@0 +KeFastSystemCallRet@0 ; big hack since LdrGetProcedureAddress is broken +KiFastSystemCall@0 LdrAccessResource@16 LdrAddRefDll@8 LdrDisableThreadCalloutsForDll@4 diff --git a/reactos/dll/ntdll/main/i386/dispatch.S b/reactos/dll/ntdll/main/i386/dispatch.S index 33237242df1..552ee7d0a4b 100644 --- a/reactos/dll/ntdll/main/i386/dispatch.S +++ b/reactos/dll/ntdll/main/i386/dispatch.S @@ -236,6 +236,35 @@ Exit: ret 8 .endfunc +.func KiIntSystemCall@0 +.globl _KiIntSystemCall@0 +_KiIntSystemCall@0: + + /* Set stack in EDX and do the interrupt */ + lea edx, [esp+8] + int 0x2E + + /* Return to caller */ + ret +.endfunc + +.func KiFastSystemCall@0 +.globl _KiFastSystemCall@0 +_KiFastSystemCall@0: + + /* Put ESP in EDX and do the SYSENTER */ + mov edx, esp + sysenter +.endfunc + +.func KeFastSystemCallRet@0 +.globl _KeFastSystemCallRet@0 +_KeFastSystemCallRet@0: + + /* Just return to caller */ + ret +.endfunc + .func RtlpGetStackLimits@8 .globl _RtlpGetStackLimits@8 _RtlpGetStackLimits@8: diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index b0e9f4546a1..932c2d090ad 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -27,8 +27,10 @@ // Ke: // // - FIXES: -// * Get rid of KiRosPrintAddress and use KiDumpParameterImages instead. +// * Stop using CachedModules. +// * Try to make MmInit1 NTLDR compatible. // * Sanitize some context fields during conversions. +// * Figure out why the DPC stack doesn't really work. // * Add DR macro/save and VM macro/save. // - FEATURES: // * New optimized table-based tick-hashed timer implementation. diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index beb7392b542..07b4d779be9 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -67,18 +67,9 @@ InitSystemSharedUserPage (IN PLOADER_PARAMETER_BLOCK LoaderBlock) ULONG i; BOOLEAN BootDriveFound = FALSE; - /* - * NOTE: - * The shared user page has been zeroed-out right after creation. - * There is NO need to do this again. - */ - Ki386SetProcessorFeatures(); - - /* Set the Version Data */ + /* Set the Product Type */ SharedUserData->NtProductType = NtProductWinNt; SharedUserData->ProductTypeIsValid = TRUE; - SharedUserData->NtMajorVersion = 5; - SharedUserData->NtMinorVersion = 0; /* * Retrieve the current dos system path diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 23366d4f632..8996231d1ae 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -649,97 +649,6 @@ Ki386InitializeTss(IN PKTSS Tss, TssEntry->LimitLow = KTSS_IO_MAPS; } -VOID -INIT_FUNCTION -Ki386SetProcessorFeatures(VOID) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName = - RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Kernel"); - UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"FastSystemCallDisable"); - HANDLE KeyHandle; - ULONG ResultLength; - struct - { - KEY_VALUE_PARTIAL_INFORMATION Info; - UCHAR Buffer[20]; - } ValueData; - NTSTATUS Status; - ULONG FastSystemCallDisable = 0; - - SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE; - SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE; - SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = - (KeFeatureBits & KF_CMPXCHG8B) ? TRUE : FALSE; - SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = - (KeFeatureBits & KF_MMX) ? TRUE : FALSE; - SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE; - SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE; - SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = - (KeFeatureBits & KF_XMMI) ? TRUE : FALSE; - SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = - (KeFeatureBits & KF_RDTSC) ? TRUE : FALSE; - - /* Does the CPU Support Fast System Call? */ - if (KeFeatureBits & KF_FAST_SYSCALL) { - - /* FIXME: Check for Family == 6, Model < 3 and Stepping < 3 and disable */ - - /* Make sure it's not disabled in registry */ - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = ZwOpenKey(&KeyHandle, - KEY_QUERY_VALUE, - &ObjectAttributes); - - if (NT_SUCCESS(Status)) { - - /* Read the Value then Close the Key */ - Status = ZwQueryValueKey(KeyHandle, - &ValueName, - KeyValuePartialInformation, - &ValueData, - sizeof(ValueData), - &ResultLength); - if (NT_SUCCESS(Status)) - { - if (ResultLength == sizeof(ValueData) && - ValueData.Info.Type == REG_DWORD) - { - FastSystemCallDisable = *(PULONG)ValueData.Info.Data != 0; - } - - ZwClose(KeyHandle); - } - } - - } else { - - /* Disable SYSENTER/SYSEXIT, because the CPU doesn't support it */ - FastSystemCallDisable = 1; - - } - - if (FastSystemCallDisable) { - /* Use INT2E */ - const unsigned char Entry[7] = {0x8D, 0x54, 0x24, 0x08, /* lea 0x8(%esp),%edx */ - 0xCD, 0x2E, /* int 0x2e */ - 0xC3}; /* ret */ - memcpy(&SharedUserData->SystemCall, Entry, sizeof(Entry)); - } else { - /* Use SYSENTER */ - const unsigned char Entry[5] = {0x8B, 0xD4, /* movl %esp,%edx */ - 0x0F, 0x34, /* sysenter */ - 0xC3}; /* ret */ - memcpy(&SharedUserData->SystemCall, Entry, sizeof(Entry)); - /* Enable SYSENTER/SYSEXIT */ - KiFastSystemCallDisable = 0; - } -} - VOID NTAPI KeFlushCurrentTb(VOID) diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index 9630bf5666d..74d21b6500d 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -421,6 +421,20 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Set the NX Support policy */ SharedUserData->NXSupportPolicy = NXSupportPolicy; + /* Set basic CPU Features that user mode can read */ + SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_MMX); + SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = + (KeFeatureBits & KF_CMPXCHG8B); + SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = + ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI)); + SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = + ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI64)); + SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_3DNOW); + SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = + (KeFeatureBits & KF_RDTSC); + /* Setup the Idle Thread */ KeInitializeThread(InitProcess, InitThread, diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 85bfd88817d..501b7074bb7 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -134,7 +134,7 @@ _KiFastCallEntry: popf /* Set our EFLAGS */ or dword ptr [esp], EFLAGS_INTERRUPT_MASK /* Re-enable IRQs in EFLAGS, to fake INT */ push KGDT_R3_CODE + RPL_MASK - push KUSER_SHARED_SYSCALL_RET + push dword ptr ds:KUSER_SHARED_SYSCALL_RET /* Setup the Trap Frame stack */ push 0 diff --git a/reactos/ntoskrnl/ldr/rtl.c b/reactos/ntoskrnl/ldr/rtl.c index 02e9e5a4369..0212889ff8c 100644 --- a/reactos/ntoskrnl/ldr/rtl.c +++ b/reactos/ntoskrnl/ldr/rtl.c @@ -55,6 +55,12 @@ LdrGetProcedureAddress (IN PVOID BaseAddress, * -- Filip Navara, August 1st, 2005 */ + /* + * I don't know who wrote this code but it's not working. + * Test case: KiFastSystemCall and KiFastSystemCallRet in ntdll. + * Former can't be found even though it's exported. + */ + OrdinalPtr = (PUSHORT)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals); NamePtr = (PULONG)RVA(BaseAddress, ExportDir->AddressOfNames); diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index a02e4398ad4..7ec0e4f5a6f 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -41,6 +41,9 @@ ANSI_STRING ApcName = RTL_CONSTANT_STRING("KiUserApcDispatcher"); ANSI_STRING ExceptName = RTL_CONSTANT_STRING("KiUserExceptionDispatcher"); ANSI_STRING CallbackName = RTL_CONSTANT_STRING("KiUserCallbackDispatcher"); ANSI_STRING RaiseName = RTL_CONSTANT_STRING("KiRaiseUserExceptionDispatcher"); +ANSI_STRING FastName = RTL_CONSTANT_STRING("KiFastSystemCall"); +ANSI_STRING FastReturnName = RTL_CONSTANT_STRING("KeFastSystemCallRet"); +ANSI_STRING InterruptName = RTL_CONSTANT_STRING("KiIntSystemCall"); PHANDLE_TABLE PspCidTable; @@ -97,6 +100,34 @@ PspLookupKernelUserEntryPoints(VOID) /* Get user-mode exception raise trampoline */ Status = PspLookupSystemDllEntryPoint(&RaiseName, &KeRaiseUserExceptionDispatcher); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if this is a machine that supports SYSENTER */ + if (KeFeatureBits & KF_FAST_SYSCALL) + { + /* Get user-mode sysenter stub */ + Status = PspLookupSystemDllEntryPoint(&FastName, + (PVOID)&SharedUserData-> + SystemCall); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode sysenter return stub */ + Status = PspLookupSystemDllEntryPoint(&FastReturnName, + (PVOID)&SharedUserData-> + SystemCallReturn); + } + else + { + /* Get the user-mode interrupt stub */ + Status = PspLookupSystemDllEntryPoint(&InterruptName, + (PVOID)&SharedUserData-> + SystemCall); + } + + /* Set the test instruction */ + if (!NT_SUCCESS(Status)) SharedUserData->TestRetInstruction = 0xC3; + + /* Return the status */ return Status; } diff --git a/reactos/tools/nci/ncitool.c b/reactos/tools/nci/ncitool.c index bdfdab8f362..6083b90b410 100644 --- a/reactos/tools/nci/ncitool.c +++ b/reactos/tools/nci/ncitool.c @@ -51,7 +51,7 @@ #if defined(__GNUC__) #define UserModeStub_x86 " movl $0x%x, %%eax\n" \ " movl $KUSER_SHARED_SYSCALL, %%ecx\n" \ - " call *%%ecx\n" \ + " call *(%%ecx)\n" \ " ret $0x%x\n\n" #elif defined(_MSC_VER) #define UserModeStub_x86 " asm { \n" \ From 7e6d549b19373a35f7fb05c10ab7df3f8cffe6fc Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Wed, 4 Oct 2006 16:39:45 +0000 Subject: [PATCH 459/488] - Open the device propsheet for child items (not parents as there isn't much point) - Tag the Device ID onto the treeview items and provide functionality to tear it down - Remove/change some code which wasn't needed to speed up opening time3 - We now have a pretty functional device manager. However it's heavily reliant on devmgr.dll, therefore functionality per device will rely on how complete this lib is. svn path=/trunk/; revision=24396 --- .../base/applications/devmgmt/devmgmt.rbuild | 1 + .../base/applications/devmgmt/enumdevices.c | 202 ++++++++++++------ reactos/base/applications/devmgmt/mainwnd.c | 15 +- reactos/base/applications/devmgmt/precomp.h | 24 ++- 4 files changed, 168 insertions(+), 74 deletions(-) diff --git a/reactos/base/applications/devmgmt/devmgmt.rbuild b/reactos/base/applications/devmgmt/devmgmt.rbuild index f126ab078bf..4c41615c3ca 100644 --- a/reactos/base/applications/devmgmt/devmgmt.rbuild +++ b/reactos/base/applications/devmgmt/devmgmt.rbuild @@ -15,6 +15,7 @@ user32 comctl32 advapi32 + devmgr about.c devmgmt.c diff --git a/reactos/base/applications/devmgmt/enumdevices.c b/reactos/base/applications/devmgmt/enumdevices.c index da9e04a521c..2a22d0ed6e1 100644 --- a/reactos/base/applications/devmgmt/enumdevices.c +++ b/reactos/base/applications/devmgmt/enumdevices.c @@ -12,10 +12,84 @@ static SP_CLASSIMAGELIST_DATA ImageListData; static HDEVINFO hDevInfo; - -VOID OpenPropSheet(HTREEITEM hItem) +VOID +FreeDeviceStrings(HWND hTV) { - DisplayString(_T("Device Propsheet not yet implemented")); + HTREEITEM hItem; + + hItem = TreeView_GetRoot(hTV); + + if (hItem) + { + hItem = TreeView_GetChild(hTV, + hItem); + /* loop the parent items */ + while (hItem) + { + hItem = TreeView_GetChild(hTV, + hItem); + if (hItem == NULL) + break; + + /* loop the child items and free the DeviceID */ + while (TRUE) + { + HTREEITEM hOldItem; + TV_ITEM tvItem; + //TCHAR Buf[100]; + + tvItem.hItem = hItem; + tvItem.mask = TVIF_PARAM;// | TVIF_TEXT; + //tvItem.pszText = Buf; + //tvItem.cchTextMax = 99; + + (void)TreeView_GetItem(hTV, &tvItem); + + //MessageBox(NULL, Buf, NULL, 0); + + HeapFree(GetProcessHeap(), + 0, + (LPTSTR)tvItem.lParam); + + hOldItem = hItem; + + hItem = TreeView_GetNextSibling(hTV, + hItem); + if (hItem == NULL) + { + hItem = hOldItem; + break; + } + } + + hItem = TreeView_GetParent(hTV, + hItem); + hItem = TreeView_GetNextSibling(hTV, + hItem); + } + } +} + + +VOID +OpenPropSheet(HWND hTV, + HTREEITEM hItem) +{ + TV_ITEM tvItem; + + tvItem.hItem = hItem; + tvItem.mask = TVIF_PARAM; + + if (TreeView_GetItem(hTV, &tvItem) && + (LPTSTR)tvItem.lParam != NULL) + { + DevicePropertiesExW(hTV, + NULL, + (LPTSTR)tvItem.lParam, + 0, + FALSE); + } + } @@ -23,6 +97,7 @@ static HTREEITEM InsertIntoTreeView(HWND hTV, HTREEITEM hRoot, LPTSTR lpLabel, + LPTSTR DeviceID, INT DevImage) { TV_ITEM tvi; @@ -31,9 +106,10 @@ InsertIntoTreeView(HWND hTV, ZeroMemory(&tvi, sizeof(tvi)); ZeroMemory(&tvins, sizeof(tvins)); - tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvi.pszText = lpLabel; tvi.cchTextMax = lstrlen(lpLabel); + tvi.lParam = (LPARAM)DeviceID; tvi.iImage = DevImage; tvi.iSelectedImage = DevImage; @@ -58,11 +134,11 @@ EnumDeviceClasses(INT ClassIndex, UINT Ret; *DevPresent = FALSE; + *DevClassName = _T('\0'); Ret = CM_Enumerate_Classes(ClassIndex, &ClassGuid, 0); - if (Ret != CR_SUCCESS) { /* all classes enumerated */ @@ -85,10 +161,6 @@ EnumDeviceClasses(INT ClassIndex, { lstrcpy(DevClassName, ClassName); } - else - { - *DevClassName = _T('\0'); - } if (!SetupDiGetClassImageIndex(&ImageListData, &ClassGuid, @@ -111,7 +183,6 @@ EnumDeviceClasses(INT ClassIndex, return 0; } - KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, MAXIMUM_ALLOWED, DIOCR_INSTALLER, @@ -145,67 +216,56 @@ EnumDeviceClasses(INT ClassIndex, static INT EnumDevices(INT index, - TCHAR* DeviceClassName, - TCHAR* DeviceName) + LPTSTR DeviceClassName, + LPTSTR DeviceName, + LPTSTR *DeviceID) { SP_DEVINFO_DATA DeviceInfoData; - DWORD RequiredSize = 0; - GUID *guids = NULL; - BOOL bRet; + DWORD DevIdSize; *DeviceName = _T('\0'); - - bRet = SetupDiClassGuidsFromName(DeviceClassName, - NULL, - RequiredSize, - &RequiredSize); - if (RequiredSize == 0) - return -2; - - if (!bRet) - { - guids = HeapAlloc(GetProcessHeap(), - 0, - RequiredSize * sizeof(GUID)); - if (guids == NULL) - return -1; - - bRet = SetupDiClassGuidsFromName(DeviceClassName, - guids, - RequiredSize, - &RequiredSize); - - if (!bRet || RequiredSize == 0) - { - /* incorrect class name */ - HeapFree(GetProcessHeap(), 0, guids); - return -3; - } - } - - HeapFree(GetProcessHeap(), 0, guids); - if(hDevInfo == INVALID_HANDLE_VALUE) - { - if(!bRet) - { - /* device info is unavailable */ - return -4; - } - } + *DeviceID = NULL; ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - bRet = SetupDiEnumDeviceInfo(hDevInfo, - index, - &DeviceInfoData); - - if (!bRet) + if (!SetupDiEnumDeviceInfo(hDevInfo, + index, + &DeviceInfoData)) { /* no such device */ return -1; } + /* get the device ID */ + if (!SetupDiGetDeviceInstanceId(hDevInfo, + &DeviceInfoData, + NULL, + 0, + &DevIdSize)) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + (*DeviceID) = (LPTSTR)HeapAlloc(GetProcessHeap(), + 0, + DevIdSize * sizeof(TCHAR)); + if (*DeviceID) + { + if (!SetupDiGetDeviceInstanceId(hDevInfo, + &DeviceInfoData, + *DeviceID, + DevIdSize, + NULL)) + { + HeapFree(GetProcessHeap(), + 0, + *DeviceID); + *DeviceID = NULL; + } + } + } + } + /* get the device's friendly name */ if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, @@ -216,17 +276,16 @@ EnumDevices(INT index, NULL)) { /* if the friendly name fails, try the description instead */ - bRet = SetupDiGetDeviceRegistryProperty(hDevInfo, - &DeviceInfoData, - SPDRP_DEVICEDESC, - 0, - (BYTE*)DeviceName, - MAX_DEV_LEN, - NULL); - if (!bRet) + if (!SetupDiGetDeviceRegistryProperty(hDevInfo, + &DeviceInfoData, + SPDRP_DEVICEDESC, + 0, + (BYTE*)DeviceName, + MAX_DEV_LEN, + NULL)) { /* if the description fails, just give up! */ - return -5; + return -2; } } @@ -241,6 +300,7 @@ ListDevicesByType(PMAIN_WND_INFO Info, HTREEITEM hDevItem; TCHAR DevName[MAX_DEV_LEN]; TCHAR DevDesc[MAX_DEV_LEN]; + LPTSTR DeviceID = NULL; BOOL DevExist = FALSE; INT ClassRet; INT index = 0; @@ -264,6 +324,7 @@ ListDevicesByType(PMAIN_WND_INFO Info, hDevItem = InsertIntoTreeView(Info->hTreeView, hRoot, DevDesc, + NULL, DevImage); } else @@ -271,6 +332,7 @@ ListDevicesByType(PMAIN_WND_INFO Info, hDevItem = InsertIntoTreeView(Info->hTreeView, hRoot, DevName, + NULL, DevImage); } @@ -278,12 +340,14 @@ ListDevicesByType(PMAIN_WND_INFO Info, { Ret = EnumDevices(DevIndex, DevName, - DeviceName); + DeviceName, + &DeviceID); if (Ret == 0) { InsertIntoTreeView(Info->hTreeView, hDevItem, DeviceName, + DeviceID, DevImage); } @@ -298,6 +362,7 @@ ListDevicesByType(PMAIN_WND_INFO Info, hDevInfo = NULL; } + /* don't insert classes with no devices */ if (!TreeView_GetChild(Info->hTreeView, hDevItem)) { @@ -366,6 +431,7 @@ InitTreeView(PMAIN_WND_INFO Info) hRoot = InsertIntoTreeView(Info->hTreeView, NULL, ComputerName, + NULL, RootImage); return hRoot; diff --git a/reactos/base/applications/devmgmt/mainwnd.c b/reactos/base/applications/devmgmt/mainwnd.c index 2a7c95c8281..218a98f5d11 100644 --- a/reactos/base/applications/devmgmt/mainwnd.c +++ b/reactos/base/applications/devmgmt/mainwnd.c @@ -285,7 +285,8 @@ OnNotify(PMAIN_WND_INFO Info, if (!TreeView_GetChild(Info->hTreeView, hSelected)) { - OpenPropSheet(hSelected); + OpenPropSheet(Info->hTreeView, + hSelected); } } break; @@ -348,13 +349,18 @@ MainWndCommand(PMAIN_WND_INFO Info, case IDC_PROP: { HTREEITEM hSelected = TreeView_GetSelection(Info->hTreeView); - OpenPropSheet(hSelected); + OpenPropSheet(Info->hTreeView, + hSelected); } break; case IDC_REFRESH: { - HTREEITEM hRoot = InitTreeView(Info); + HTREEITEM hRoot; + + FreeDeviceStrings(Info->hTreeView); + + hRoot = InitTreeView(Info); if (hRoot) ListDevicesByType(Info, hRoot); } @@ -525,6 +531,7 @@ MainWndProc(HWND hwnd, case WM_CLOSE: { + FreeDeviceStrings(Info->hTreeView); DestroyMenu(Info->hShortcutMenu); DestroyWindow(hwnd); } @@ -532,8 +539,6 @@ MainWndProc(HWND hwnd, case WM_DESTROY: { - //DestroyMainWnd(Info); - HeapFree(ProcessHeap, 0, Info); diff --git a/reactos/base/applications/devmgmt/precomp.h b/reactos/base/applications/devmgmt/precomp.h index 2c038a72843..83a27089cff 100644 --- a/reactos/base/applications/devmgmt/precomp.h +++ b/reactos/base/applications/devmgmt/precomp.h @@ -53,7 +53,29 @@ HWND CreateMainWindow(LPCTSTR lpCaption, int nCmdShow); /* enumdevices.c */ -VOID OpenPropSheet(HTREEITEM hItem); +// undocumented API's from devmgr +#ifdef _UNICODE +#define DevicePropertiesEx DevicePropertiesExW +INT_PTR +WINAPI +DevicePropertiesExW(IN HWND hWndParent OPTIONAL, + IN LPCWSTR lpMachineName OPTIONAL, + IN LPCWSTR lpDeviceID OPTIONAL, + IN DWORD dwFlags OPTIONAL, + IN BOOL bShowDevMgr); +#else +#define DevicePropertiesEx DevicePropertiesExA +INT_PTR +WINAPI +DevicePropertiesExA(IN HWND hWndParent OPTIONAL, + IN LPCSTR lpMachineName OPTIONAL, + IN LPCSTR lpDeviceID OPTIONAL, + IN DWORD dwFlags OPTIONAL, + IN BOOL bShowDevMgr); +#endif + +VOID FreeDeviceStrings(HWND hTV); +VOID OpenPropSheet(HWND hTV, HTREEITEM hItem); HTREEITEM InitTreeView(PMAIN_WND_INFO Info); VOID ListDevicesByType(PMAIN_WND_INFO Info, HTREEITEM hRoot); From 80da4a434ce6ada136eee762aa15e44d7881fd1a Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 4 Oct 2006 16:51:51 +0000 Subject: [PATCH 460/488] - Fix binary search algorithm in LdrGetProcedureAddress - Fix temporary ntdll export hack (r24395) svn path=/trunk/; revision=24397 --- reactos/dll/ntdll/def/ntdll.def | 2 +- reactos/dll/ntdll/main/i386/dispatch.S | 6 +++--- reactos/ntoskrnl/ldr/rtl.c | 13 +++---------- reactos/ntoskrnl/ps/psmgr.c | 2 +- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/reactos/dll/ntdll/def/ntdll.def b/reactos/dll/ntdll/def/ntdll.def index bbb4dbd703c..4e54efdad44 100644 --- a/reactos/dll/ntdll/def/ntdll.def +++ b/reactos/dll/ntdll/def/ntdll.def @@ -38,7 +38,7 @@ KiUserApcDispatcher@16 KiUserCallbackDispatcher@12 KiUserExceptionDispatcher@8 KiIntSystemCall@0 -KeFastSystemCallRet@0 ; big hack since LdrGetProcedureAddress is broken +KiFastSystemCallRet@0 KiFastSystemCall@0 LdrAccessResource@16 LdrAddRefDll@8 diff --git a/reactos/dll/ntdll/main/i386/dispatch.S b/reactos/dll/ntdll/main/i386/dispatch.S index 552ee7d0a4b..f6daf51e3e5 100644 --- a/reactos/dll/ntdll/main/i386/dispatch.S +++ b/reactos/dll/ntdll/main/i386/dispatch.S @@ -257,9 +257,9 @@ _KiFastSystemCall@0: sysenter .endfunc -.func KeFastSystemCallRet@0 -.globl _KeFastSystemCallRet@0 -_KeFastSystemCallRet@0: +.func KiFastSystemCallRet@0 +.globl _KiFastSystemCallRet@0 +_KiFastSystemCallRet@0: /* Just return to caller */ ret diff --git a/reactos/ntoskrnl/ldr/rtl.c b/reactos/ntoskrnl/ldr/rtl.c index 0212889ff8c..8e8ff37d5db 100644 --- a/reactos/ntoskrnl/ldr/rtl.c +++ b/reactos/ntoskrnl/ldr/rtl.c @@ -69,22 +69,15 @@ LdrGetProcedureAddress (IN PVOID BaseAddress, { mid = (minn + maxn) / 2; CurrentNamePtr = (PCHAR)RVA(BaseAddress, NamePtr[mid]); - res = strncmp(CurrentNamePtr, Name->Buffer, Name->Length); + res = strcmp(CurrentNamePtr, Name->Buffer); if (res == 0) { /* * Check if the beginning of the name matched, but it's still * not the whole name. */ - if (CurrentNamePtr[Name->Length] != 0) - { - res = -1; - } - else - { - *ProcedureAddress = (PVOID)RVA(BaseAddress, AddressPtr[OrdinalPtr[mid]]); - return STATUS_SUCCESS; - } + *ProcedureAddress = (PVOID)RVA(BaseAddress, AddressPtr[OrdinalPtr[mid]]); + return STATUS_SUCCESS; } if (res > 0) maxn = mid - 1; diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index 7ec0e4f5a6f..1877930314f 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -42,7 +42,7 @@ ANSI_STRING ExceptName = RTL_CONSTANT_STRING("KiUserExceptionDispatcher"); ANSI_STRING CallbackName = RTL_CONSTANT_STRING("KiUserCallbackDispatcher"); ANSI_STRING RaiseName = RTL_CONSTANT_STRING("KiRaiseUserExceptionDispatcher"); ANSI_STRING FastName = RTL_CONSTANT_STRING("KiFastSystemCall"); -ANSI_STRING FastReturnName = RTL_CONSTANT_STRING("KeFastSystemCallRet"); +ANSI_STRING FastReturnName = RTL_CONSTANT_STRING("KiFastSystemCallRet"); ANSI_STRING InterruptName = RTL_CONSTANT_STRING("KiIntSystemCall"); PHANDLE_TABLE PspCidTable; From 948a1f90457b53dd6d78d5279ef6610fc26eed65 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 4 Oct 2006 18:46:57 +0000 Subject: [PATCH 461/488] Fix almost the same bug in LdrGetProcedureAddress as in r24397 svn path=/trunk/; revision=24398 --- reactos/subsystems/win32/win32k/ldr/loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/ldr/loader.c b/reactos/subsystems/win32/win32k/ldr/loader.c index 8fb5a5ca876..a63eb950ccf 100644 --- a/reactos/subsystems/win32/win32k/ldr/loader.c +++ b/reactos/subsystems/win32/win32k/ldr/loader.c @@ -66,7 +66,7 @@ LdrGetProcedureAddress (IN PVOID BaseAddress, NamePtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNames); for( i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++) { - if (!_strnicmp(Name->Buffer, (char*)((ULONG_PTR)BaseAddress + *NamePtr), Name->Length)) + if (!strcmp(Name->Buffer, (char*)((ULONG_PTR)BaseAddress + *NamePtr))) { *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG)AddressPtr[*OrdinalPtr]); return STATUS_SUCCESS; From a595b4c7dac1b1d2d5354d3521da3f6dda2fd70c Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Wed, 4 Oct 2006 19:04:16 +0000 Subject: [PATCH 462/488] add some overlay icons needed for devmgmt svn path=/trunk/; revision=24399 --- reactos/dll/win32/setupapi/res/icons/500.ico | Bin 1078 -> 13270 bytes reactos/dll/win32/setupapi/res/icons/501.ico | Bin 1078 -> 13270 bytes reactos/dll/win32/setupapi/res/icons/502.ico | Bin 1078 -> 13270 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/reactos/dll/win32/setupapi/res/icons/500.ico b/reactos/dll/win32/setupapi/res/icons/500.ico index 43521de70d69f3ed0af849f88f0cd7d6a5151e7d..9b43419728d61a4d8be46a6065a0cf09a19a1d8d 100644 GIT binary patch literal 13270 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 TI0~L_iAebhpZ9(9ox8^qxWUWJ diff --git a/reactos/dll/win32/setupapi/res/icons/501.ico b/reactos/dll/win32/setupapi/res/icons/501.ico index 43521de70d69f3ed0af849f88f0cd7d6a5151e7d..e187e8ccc04fdd96b955acc4da3728e4713508fe 100644 GIT binary patch literal 13270 zcmeHN30TxemVZqnXWQH$2u%xiLnDYcU{o*xIpn^K8jsD!jH@Ow(PW~=4B0PE+)?9f zKEG_tj82l#43kZEHJ)RLB8nG>2Lg(KEtjZV-6$%7s{K_1PK)AzX7}6Op}y}&)xYXh zz4w3pr{1ggibz6cq*M}W3(B-0dX6Mg;{%KA< z^h#O}+B#Jay^DbW*faY`%{`b_xH4F)mD0U)pm+c{Fb7lzo(?+U6ej+ z7smI{+?RII{Q3K6;XmxBg$obU(xqAS&O3+6$|{eB%FmFcWdT{s3P?8eEXi%plAU87 zP)N@1`Jg#Z*47tECMy9hlU!a-4o>IE&c1|PJuc8NkBek)Urx?0mE`7jmE1?3Bu~w8 z8t#=x?%sK%P@h4akN!eZcwZu=`XqU2j?oC8Gc-bThI|6^$ji5o{QOUoCg3djk3C6a z#vi3|LHQIsIS=oe2ihXgoG0&qbL8!Pg_Noa^7SnvP2eTcXevlE?jmW%UZ#-eF3`lu zWfUA-PQla4Y4~t0d5^qCqep9L(xht?6jV!7rPdml6{5DLLg7 zrKO#s#N+~+H7lQH&&i|t3r?dhq!(sfps?plC?c{Lx;;lTW>iu{^i_&axI*#Cm6Vur zp3-KYr#W*k(xO+7(kqK{Y01)TTDB~gR=$0L*1VTX@4tVX-hA^6>U?_Tm5cQJ^VL}A z8ij|~Vl6Gj%+zA-T8fLS!*5%U{w9iyt;cVCgAx*M(ag9;ichMc_*5XViIUT+C@HO$ zX3f72{`HiWUQbC$4V0YLK&fesG((aPv7-*Cr_9V-w0n0W9XixZUw^GfTTgrU zwoq1^k*)YQ~ORaH8wsnL^8r|bG>_&fT`Ie)6RwXrre86xX*s%7v*lriSmr5;n> z4U5otisC(a_G5-AG)S#hdw6(wdXAX*(xU|7(LNYgt35&CHF;%kg13`X0|R_OqC!#o zKi_+N{-zHy-b;^-jgF0pj?wrZjR{rmPMMJKxSB6$7FO+V&{as=hO z)gRgS8h`E6uYNe%RkDx%=Z715>tODepJ#q=D7$v;TKD1Fw|mWhGjq#lTMXrcEgx+8 z@Wo!kL>Zrc_E|T@mJc?)@yPgFUw#9EE{Yw$cx0Gp-llK1Z3D%&ZJCQ6Gfec>(o9f% zleuB;V~5eX;$>0#8XfHazoY@|0Vpk@oNH}3&oBq1*cK$5JpiF?42fZ!6X*neHs*=> zPgjJW0@sJe06l(6n2C`Fjr*YC*F^E+~I*iBAOd(r-Z6pF(%X3Q5fb?R5}kq(iU zR~C&Lb&vuA4grT@n}38&+76qs8TM)?Y;7iN%D1pjNAP?IHu68{<(K!tejFhWk7G2< zwScTFyZjHi{1W_*3uI?kOwP{5;8%=x896$ZL56b3PzjrViQL`cBPg@sBjm#NpCGlm z0PQn0etZs1oCx1yTrTR9G-b*$$a;oCLe7Bx98d~>;sW`Nx`;WK(Jq7RmE`YVL1O|d zF|Qc3rFgdz%&(wnQ!B}3n3mjJt01cusKq=j*13+k*MK^_{|y@HeTznpyoIp_tXB_N z8ffg;Yw$^`C}gr0Yu4hq5zoyO7IuuLPd^D?06xl$(-a?nnv#=qpqu09ub@SXa^S)3$B5>5qSGrky)m=*ZzabnMt2 zI)1#3PMo+$r%v4`t@ggrhcVdvd(i-PmS=ob3lph{IZjRw7ia59AtAvN%8WmxQKQCdP= zOhQVpZX7H_mo8fxYAj68GzXjBo=nfk|C3sLLk4u%5N|ODq{OuX65`oL5YM7t(A)zp z3+QaRMIZ+{40M;o%{d+yC`A>aJ8Mlx`3B5qUc}cpE+bcQyG(I7`6n zF-YD4CdLqbV$47TlaH;lzWqbz;W>3mbx|i`zzp$XW@Vkv5JyIx#}G?q zh#51t5vT9UY`@PkG5H046RU^4v!_ynow@0d760U>$ZzuSy3{#Tevw&Q7lH2u;2dz4 zSy~nX1!(6pJI4a%s?7UIX1nW3{n6(&t|cFQS6+?fp>TE=9uOF$_{ zOq?S&E@VM{fg@Hfh7 zL(H1v?8--ty2>@0N}vKL=f1vIfHL4Rx3@3h$PsX*`h17fbi=a#^Xp9+6dDwAqB1SL zfu*K4a>SDv;>QeeWR7?;-?{S!15np<#F*KR9oJFUapV9Pas?du0A^{mc}MS6`~N&C zIy|c2dSYTTOG#bZ{*Xudr)V!sog*P`hKLo_YIb!@A@p>+|{p4W(`Sqp@ zikK3bUz3oaXNb*n#LQWBwVoqJZh&Z4SL-<9=0J-9;u*1c9y7C^C#KbMxy>iLdav65 z=b*rm>Z64zX|0{eA8^F~+0v!0fSx19FMzhFTYx6Cn?%i#vtZHDH+guJw$s9L^Sb`? z>rLq=v$6epN7^iXdt~HYHe-gs9o~i8JR+hM&;vT4MF8JtGtkJ8Ghq{gOIoGUcfxwF zI*@0nbWP&4u*zoSN5K0&a1Z1=_)1phup&Xt$xijYUS@VJYdlPQQSBt*L3^4A@0j@n0D+4VL=QWiEoh-y%t*0#FOfAlo!q!>?hzl6frXudp1Cd4*5hM|Z zumD6XqQ7TxK_}K0krWkxxCY@YO>sanklNi2MJ?hCu7KdvU)wMIK_Rz0!YS|_Mz687 z{LN__n?E($+3oI-%m3VJVexUXL=v%;$Vu?R8QQ=@yvLJD&-;n>;rH3ArPAe_-Q4!v z(rAjf#_tM4K9#A|mpSsS%+2k`cBynN&L-aBpcmPlzqNi3Z=riLsq~+J>En~5LvEHK z|H_@5D;Z+)%--$_cW@|U$OUt6@7#M*>4rbxRXs7Mzxn~`5_ebEzucZQshWFuRC8C? zDvn&Q;K3aoD{#KO!fkEKxZvUDcI2K!vUxTp^}Iitf2*us5gc5Kb8{VJuZ66F$2A5X z%-Q*>;DK}g71U*H#E5gu!s6d?ju=Q;lZhNK_wuS|$m25PYJux!^wk9g&mg0RdOJo!y@H0j~cA^48qPr-30?&5)1g z$V;=$oAqqd$9leLqmFId*uq_0t}=iBa%N+*`|1GKU-aB_rHErRbCtTm@E*_=zRT-e zp{V2T?lpY4TQ&Fetm3#2z%4Dm9bgRMr6IT%Q5qRp!;sr&YE=WrJphLL0IZt_Q+U?$ zapSc3?SH5tS{FPp`LO|+EKXOek6aZzf`Xb6cWGd_XMniJ4a8>Z8SWLJ?|8FR`u-|x zMNe@Sva%37#CuGcQp%H)Z?L&@n^|Jg4L*5tDgJ*C-Ihu}T8_2FKJ^UcCH!BmSp<9` zzAGRTSOJK=bg&F+U{C}9LmJ>2@W;BrdfM6O%Qni%8@ILH`FW9>?;{s)-0w@qd3hzC za3@}PMguD5<`T(@d2;!_Y$vCKdPm2Dtuoo(Y|)22kol9BGDjxw^|iPYrbiy1xww=t zN5^8=_9EE%(|S|W*WP>58iI#Lb5@U>KWwJR1C$`aORrLC8SZr{RZyr-1mH}osByS9CsEt?k6D5Tg!0Y zjN{${?0hBcXDPR_+1IE1CMGNAO_)%m_w}s?FD-aoh5jqxua(2@iX1|r{z>{1zm0{( z8}ErVgdDg-!Eoo!kc05|Kc~lU`^4X`OE2c;LJsjR(1%{B%+ibB#l)mP-%nqf9qj)( UHNfCW<5>7a2%5*`q($F<0VU-ZaR2}S literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ diff --git a/reactos/dll/win32/setupapi/res/icons/502.ico b/reactos/dll/win32/setupapi/res/icons/502.ico index 43521de70d69f3ed0af849f88f0cd7d6a5151e7d..a93976d12a4afe3802669dc1fbfb6d9a3ea3e693 100644 GIT binary patch literal 13270 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 TI0~L_iAebhpZ9(9ox8^qxWUWJ From 32dcc834ed4e43d37137493bb840a1ad24969534 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 4 Oct 2006 19:55:53 +0000 Subject: [PATCH 463/488] Fix broken resources svn path=/trunk/; revision=24400 --- reactos/base/applications/imagesoft/imagesoft.rc | 6 ------ reactos/base/applications/imagesoft/lang/En.rc | 8 ++++++++ reactos/base/applications/imagesoft/lang/No.rc | 6 ++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/reactos/base/applications/imagesoft/imagesoft.rc b/reactos/base/applications/imagesoft/imagesoft.rc index 6b61776f4d4..4892fdce134 100644 --- a/reactos/base/applications/imagesoft/imagesoft.rc +++ b/reactos/base/applications/imagesoft/imagesoft.rc @@ -11,12 +11,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 1 24 DISCARDABLE "manifest.xml" -STRINGTABLE DISCARDABLE -BEGIN - IDS_APPNAME "ImageSoft" - IDS_VERSION "v0.1" -END - IDI_IMAGESOFTICON ICON "res/imagesoft.ico" /* main toolbar icons */ diff --git a/reactos/base/applications/imagesoft/lang/En.rc b/reactos/base/applications/imagesoft/lang/En.rc index 7a0892eb1f5..a11b8e27b06 100644 --- a/reactos/base/applications/imagesoft/lang/En.rc +++ b/reactos/base/applications/imagesoft/lang/En.rc @@ -1,3 +1,11 @@ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APPNAME "ImageSoft" + IDS_VERSION "v0.1" +END + IDR_MAINMENU MENU BEGIN POPUP "&File" diff --git a/reactos/base/applications/imagesoft/lang/No.rc b/reactos/base/applications/imagesoft/lang/No.rc index d10a7ef9aa7..ad738a5d7f0 100644 --- a/reactos/base/applications/imagesoft/lang/No.rc +++ b/reactos/base/applications/imagesoft/lang/No.rc @@ -1,5 +1,11 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL +STRINGTABLE DISCARDABLE +BEGIN + IDS_APPNAME "ImageSoft" + IDS_VERSION "v0.1" +END + IDR_MAINMENU MENU BEGIN POPUP "&Fil" From 76abbb4423eab4d70908e1b75f75318aedfa7b63 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 4 Oct 2006 21:11:16 +0000 Subject: [PATCH 464/488] - Remove some crap from the LoadAndBootWindows() - Change debugging checkpoint to online-asm (all this is temporary), since any code after while(1){}; seems to be just optimized away by gcc - Uncomment NDEBUG for now svn path=/trunk/; revision=24401 --- reactos/boot/freeldr/freeldr/windows/winldr.c | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index 89dae9c925e..c2471560385 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -21,7 +21,9 @@ #include -#define NDEBUG +#include + +//#define NDEBUG #include VOID DumpMemoryAllocMap(VOID); @@ -442,7 +444,6 @@ void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock, RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT); } - VOID LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) { @@ -454,14 +455,17 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) BOOLEAN Status; ULONG SectionId; ULONG BootDevice; - PLOADER_PARAMETER_BLOCK LoaderBlock=NULL, LoaderBlockVA; - PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE; + PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA; KERNEL_ENTRY_POINT KiSystemStartup; + PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE; + PIMAGE_NT_HEADERS NtosHeader; // Mm-related things - PVOID GdtIdt=NULL; + PVOID GdtIdt; ULONG PcrBasePage=0; ULONG TssBasePage=0; + + //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion); //UiMessageBox(MsgBuffer); @@ -562,6 +566,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) /* Save entry-point pointer (VA) */ KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint; + LoaderBlockVA = PaToVa(LoaderBlock); /* Debugging... */ @@ -575,23 +580,17 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) WinLdrpDumpMemoryDescriptors(LoaderBlockVA); - /*__asm - { - or esp, KSEG0_BASE; - or ebp, KSEG0_BASE; - }*/ + // temp: offset C9000 - /* - { - ULONG *trrr = (ULONG *)(512*1024*1024); + //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below + //while (1) {}; + asm(".intel_syntax noprefix\n"); + asm("test1:\n"); + asm("jmp test1\n"); + asm(".att_syntax\n"); - *trrr = 0x13131414; - } - //FIXME! - while (1) {};*/ - - (KiSystemStartup)(LoaderBlockVA); + (*KiSystemStartup)(LoaderBlockVA); return; } From 602923e572c9458ad7504cfba404f87171c1f43a Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 4 Oct 2006 21:36:56 +0000 Subject: [PATCH 465/488] - Fix warning in winldr.c - Implement WinLdrAllocateDataTableEntry() used for allocating and initializing the DTE - Implement WinLdrLoadImage(), which uses LdrRelocateImageWithBias() from RTL, calling it with loader name "FLx86" (RTL should treat it differently -- ROS/WinLdr-specific behavior) svn path=/trunk/; revision=24402 --- .../boot/freeldr/freeldr/windows/peloader.c | 240 +++++++++++++++++- reactos/boot/freeldr/freeldr/windows/winldr.c | 1 - 2 files changed, 238 insertions(+), 3 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/windows/peloader.c b/reactos/boot/freeldr/freeldr/windows/peloader.c index c8f58f32141..9419dd40539 100644 --- a/reactos/boot/freeldr/freeldr/windows/peloader.c +++ b/reactos/boot/freeldr/freeldr/windows/peloader.c @@ -36,7 +36,74 @@ WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, IN PVOID BasePA, OUT PLDR_DATA_TABLE_ENTRY *NewEntry) { - return FALSE; + PVOID BaseVA = PaToVa(BasePA); + PWSTR Buffer; + PLDR_DATA_TABLE_ENTRY DataTableEntry; + PIMAGE_NT_HEADERS NtHeaders; + USHORT Length; + + /* Allocate memory for a data table entry, zero-initialize it */ + DataTableEntry = (PLDR_DATA_TABLE_ENTRY)MmAllocateMemory(sizeof(LDR_DATA_TABLE_ENTRY)); + if (DataTableEntry == NULL) + return FALSE; + RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY)); + + /* Get NT headers from the image */ + NtHeaders = RtlImageNtHeader(BasePA); + + /* Initialize corresponding fields of DTE based on NT headers value */ + DataTableEntry->DllBase = BaseVA; + DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; + DataTableEntry->EntryPoint = (PVOID)((ULONG)BaseVA + + NtHeaders->OptionalHeader.AddressOfEntryPoint); + DataTableEntry->SectionPointer = 0; + DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum; + + /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName + by simple conversion - copying each character */ + Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR)); + Buffer = (PWSTR)MmAllocateMemory(Length); + if (Buffer == NULL) + return FALSE; + RtlZeroMemory(Buffer, Length); + + DataTableEntry->BaseDllName.Length = Length; + DataTableEntry->BaseDllName.MaximumLength = Length; + DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer); + while (*BaseDllName != 0) + { + *Buffer++ = *BaseDllName++; + } + + /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName + using the same method */ + Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR)); + Buffer = (PWSTR)MmAllocateMemory(Length); + if (Buffer == NULL) + return FALSE; + RtlZeroMemory(Buffer, Length); + + DataTableEntry->FullDllName.Length = Length; + DataTableEntry->FullDllName.MaximumLength = Length; + DataTableEntry->FullDllName.Buffer = PaToVa(Buffer); + while (*FullDllName != 0) + { + *Buffer++ = *FullDllName++; + } + + /* Initialize what's left - LoadCount which is 1, and set Flags so that + we know this entry is processed */ + DataTableEntry->Flags = LDRP_ENTRY_PROCESSED; + DataTableEntry->LoadCount = 1; + + /* Insert this DTE to a list in the LPB */ + InsertTailList(&WinLdrBlock->LoadOrderListHead, &DataTableEntry->InLoadOrderLinks); + + /* Save pointer to a newly allocated and initialized entry */ + *NewEntry = DataTableEntry; + + /* Return success */ + return TRUE; } /* WinLdrLoadImage loads the specified image from the file (it doesn't @@ -49,7 +116,176 @@ BOOLEAN WinLdrLoadImage(IN PCHAR FileName, OUT PVOID *ImageBasePA) { - return FALSE; + PFILE FileHandle; + PVOID PhysicalBase; + PVOID VirtualBase = NULL; + UCHAR HeadersBuffer[SECTOR_SIZE * 2]; + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_SECTION_HEADER SectionHeader; + ULONG VirtualSize, SizeOfRawData, NumberOfSections; + BOOLEAN Status; + ULONG i, BytesRead; + + //Print(L"Loading %s... ", FileName); + + /* Open the image file */ + FileHandle = FsOpenFile(FileName); + + if (FileHandle == NULL) + { + //Print(L"Can not open the file %s\n",FileName); + UiMessageBox("Can not open the file"); + return FALSE; + } + + /* Load the first 2 sectors of the image so we can read the PE header */ + Status = FsReadFile(FileHandle, SECTOR_SIZE * 2, NULL, HeadersBuffer); + if (!Status) + { + //Print(L"Error reading from file %s\n", FileName); + UiMessageBox("Error reading from file"); + FsCloseFile(FileHandle); + return FALSE; + } + + /* Now read the MZ header to get the offset to the PE Header */ + NtHeaders = RtlImageNtHeader(HeadersBuffer); + + if (!NtHeaders) + { + //Print(L"Error - no NT header found in %s\n", FileName); + UiMessageBox("Error - no NT header found"); + FsCloseFile(FileHandle); + return FALSE; + } + + /* Ensure this is executable image */ + if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0)) + { + //Print(L"Not an executable image %s\n", FileName); + UiMessageBox("Not an executable image"); + FsCloseFile(FileHandle); + return FALSE; + } + + /* Store number of sections to read and a pointer to the first section */ + NumberOfSections = NtHeaders->FileHeader.NumberOfSections; + SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); + + /* Try to allocate this memory, if fails - allocate somewhere else */ + PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage, + (PVOID)NtHeaders->OptionalHeader.ImageBase); + + if (PhysicalBase == NULL) + { + /* It's ok, we don't panic - let's allocate again at any other "low" place */ + MmChangeAllocationPolicy(FALSE); + PhysicalBase = MmAllocateMemory(NtHeaders->OptionalHeader.SizeOfImage); + MmChangeAllocationPolicy(TRUE); + + if (PhysicalBase == NULL) + { + //Print(L"Failed to alloc pages for image %s\n", FileName); + UiMessageBox("Failed to alloc pages for image"); + FsCloseFile(FileHandle); + return FALSE; + } + } + + /* This is the real image base - in form of a virtual address */ + VirtualBase = PaToVa(PhysicalBase); + + DbgPrint((DPRINT_WINDOWS, "Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase)); + + /* Set to 0 position and fully load the file image */ + FsSetFilePointer(FileHandle, 0); + + Status = FsReadFile(FileHandle, NtHeaders->OptionalHeader.SizeOfHeaders, NULL, PhysicalBase); + + if (!Status) + { + //Print(L"Error reading headers %s\n", FileName); + UiMessageBox("Error reading headers"); + FsCloseFile(FileHandle); + return FALSE; + } + + /* Reload the NT Header */ + NtHeaders = RtlImageNtHeader(PhysicalBase); + + /* Load the first section */ + SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); + + /* Fill output parameters */ + *ImageBasePA = PhysicalBase; + + /* Walk through each section and read it (check/fix any possible + bad situations, if they arise) */ + for (i = 0; i < NumberOfSections; i++) + { + VirtualSize = SectionHeader->Misc.VirtualSize; + SizeOfRawData = SectionHeader->SizeOfRawData; + + /* Handle a case when VirtualSize equals 0 */ + if (VirtualSize == 0) + VirtualSize = SizeOfRawData; + + /* If PointerToRawData is 0, then force its size to be also 0 */ + if (SectionHeader->PointerToRawData == 0) + { + SizeOfRawData = 0; + } + else + { + /* Cut the loaded size to the VirtualSize extents */ + if (SizeOfRawData > VirtualSize) + SizeOfRawData = VirtualSize; + } + + /* Actually read the section (if its size is not 0) */ + if (SizeOfRawData != 0) + { + /* Seek to the correct position */ + FsSetFilePointer(FileHandle, SectionHeader->PointerToRawData); + + DbgPrint((DPRINT_WINDOWS, "SH->VA: 0x%X\n", SectionHeader->VirtualAddress)); + + /* Read this section from the file, size = SizeOfRawData */ + Status = FsReadFile(FileHandle, SizeOfRawData, &BytesRead, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress); + + if (!Status && (BytesRead == 0)) + break; + } + + /* Size of data is less than the virtual size - fill up the remainder with zeroes */ + if (SizeOfRawData < VirtualSize) + RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData); + + SectionHeader++; + } + + /* We are done with the file - close it */ + FsCloseFile(FileHandle); + + /* If loading failed - return right now */ + if (!Status) + return FALSE; + + + /* Relocate the image, if it needs it */ + if (NtHeaders->OptionalHeader.ImageBase != (ULONG)VirtualBase) + { + DbgPrint((DPRINT_WINDOWS, "Relocating %p -> %p\n", + NtHeaders->OptionalHeader.ImageBase, VirtualBase)); + Status = (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase, + 0, + "FLx86", + TRUE, + 3, + FALSE); + } + + return Status; } /* PRIVATE FUNCTIONS *******************************************************/ diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index c2471560385..22c3fc6010a 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -458,7 +458,6 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA; KERNEL_ENTRY_POINT KiSystemStartup; PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE; - PIMAGE_NT_HEADERS NtosHeader; // Mm-related things PVOID GdtIdt; ULONG PcrBasePage=0; From 245dca159aa5cf395dc7b228ef12e24d9d459000 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Wed, 4 Oct 2006 21:47:08 +0000 Subject: [PATCH 466/488] -don't use GetLastError with Reg* functions -remove @16 from def file (msvc doesn't like it) svn path=/trunk/; revision=24403 --- reactos/dll/cpl/timedate/internettime.c | 37 ++++++++++--------------- reactos/dll/cpl/timedate/timedate.def | 2 +- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/reactos/dll/cpl/timedate/internettime.c b/reactos/dll/cpl/timedate/internettime.c index 3c8b9a4ed57..1427085676f 100644 --- a/reactos/dll/cpl/timedate/internettime.c +++ b/reactos/dll/cpl/timedate/internettime.c @@ -335,40 +335,31 @@ GetSyncSetting(HWND hwnd) { HKEY hKey; HWND hCheck; - LONG Ret; WCHAR Data[8]; DWORD Size; - Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Parameters", 0, KEY_QUERY_VALUE, - &hKey); - if (Ret != ERROR_SUCCESS) - { - DisplayWin32Error(Ret); - return; - } - - Size = sizeof(Data); - Ret = RegQueryValueExW(hKey, + &hKey) == ERROR_SUCCESS) + { + Size = sizeof(Data); + if (RegQueryValueExW(hKey, L"Type", NULL, NULL, (LPBYTE)Data, - &Size); - if (Ret != ERROR_SUCCESS) - { - DisplayWin32Error(Ret); + &Size) == ERROR_SUCCESS) + { + if (lstrcmp(Data, L"NTP") == 0) + { + hCheck = GetDlgItem(hwnd, IDC_AUTOSYNC); + SendMessageW(hCheck, BM_SETCHECK, 0, 0); + } + } + RegCloseKey(hKey); } - - if (lstrcmp(Data, L"NTP") == 0) - { - hCheck = GetDlgItem(hwnd, IDC_AUTOSYNC); - SendMessageW(hCheck, BM_SETCHECK, 0, 0); - } - - RegCloseKey(hKey); } diff --git a/reactos/dll/cpl/timedate/timedate.def b/reactos/dll/cpl/timedate/timedate.def index 8d67834a2ec..52c811fe993 100644 --- a/reactos/dll/cpl/timedate/timedate.def +++ b/reactos/dll/cpl/timedate/timedate.def @@ -1,6 +1,6 @@ LIBRARY timedate.cpl EXPORTS -CPlApplet@16 +CPlApplet ; EOF From a3613669884aea25c90e7243fe359fda0f0f2b80 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Wed, 4 Oct 2006 21:47:43 +0000 Subject: [PATCH 467/488] -support debugging of control panel applets svn path=/trunk/; revision=24404 --- reactos/tools/rbuild/backend/msvc/msvc.cpp | 9 +++ .../tools/rbuild/backend/msvc/vcprojmaker.cpp | 61 ++++++++++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/reactos/tools/rbuild/backend/msvc/msvc.cpp b/reactos/tools/rbuild/backend/msvc/msvc.cpp index 858ee2f2f10..789543129ac 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.cpp +++ b/reactos/tools/rbuild/backend/msvc/msvc.cpp @@ -384,6 +384,15 @@ MSVCBackend::_clean_project_files ( void ) remove ( SuoFileName ( module ).c_str () ); remove ( VcprojFileName ( module ).c_str () ); + string username = getenv ( "USERNAME" ); + string computername = getenv ( "COMPUTERNAME" ); + string vcproj_file_user = ""; + + if ((computername != "") && (username != "")) + vcproj_file_user = VcprojFileName ( module ) + "." + computername + "." + username + ".user"; + + remove ( vcproj_file_user.c_str () ); + _get_object_files ( module, out ); for ( size_t j = 0; j < out.size (); j++) { diff --git a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp index 756f05611d3..6f07c4cbc67 100644 --- a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp @@ -70,6 +70,14 @@ MSVCBackend::_generate_vcproj ( const Module& module ) size_t i; string vcproj_file = VcprojFileName(module); + + string username = getenv ( "USERNAME" ); + string computername = getenv ( "COMPUTERNAME" ); + string vcproj_file_user = ""; + + if ((computername != "") && (username != "")) + vcproj_file_user = vcproj_file + "." + computername + "." + username + ".user"; + printf ( "Creating MSVC.NET project: '%s'\n", vcproj_file.c_str() ); FILE* OUT = fopen ( vcproj_file.c_str(), "wb" ); @@ -616,7 +624,57 @@ MSVCBackend::_generate_vcproj ( const Module& module ) fprintf ( OUT, "\t\r\n" ); fprintf ( OUT, "\t\r\n" ); fprintf ( OUT, "\r\n" ); - fclose(OUT); + fclose ( OUT ); + + /* User configuration file */ + if (vcproj_file_user != "") + { + OUT = fopen ( vcproj_file_user.c_str(), "wb" ); + fprintf ( OUT, "\r\n" ); + fprintf ( OUT, "\r\n" ); + + fprintf ( OUT, "\t\r\n" ); + for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ ) + { + const MSVCConfiguration& cfg = *m_configurations[icfg]; + fprintf ( OUT, "\t\t\r\n" ); + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\r\n" ); + } + fprintf ( OUT, "\t\r\n" ); + fprintf ( OUT, "\r\n" ); + fclose ( OUT ); + } + } std::string @@ -754,6 +812,7 @@ MSVCBackend::_generate_sln ( FILE* OUT ) Module& module = *ProjectNode.modules[i]; std::string vcproj_file = VcprojFileName ( module ); + std::string vcproj_file_user = vcproj_file + "CHRIS-NOTEBOOK.Christoph.user"; _generate_sln_project ( OUT, module, vcproj_file, sln_guid, module.guid, module.non_if_data.libraries ); } _generate_sln_footer ( OUT ); From b103aa1eced97ad25c9b0bd66d10f61df154b177 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 4 Oct 2006 21:58:36 +0000 Subject: [PATCH 468/488] - Add most needed memory-manipulating functions. Some places are really crappy (like WinLdrSetProcessorContext's IDT filling), will be fixed soon. - FIXME: Since FreeLdr doesn't really keep track of which memory is of which type, this code has a massive hack for guessing the memory type, which is incorrect for future usage svn path=/trunk/; revision=24405 --- .../boot/freeldr/freeldr/windows/wlmemory.c | 913 +++++++++++++++++- 1 file changed, 912 insertions(+), 1 deletion(-) diff --git a/reactos/boot/freeldr/freeldr/windows/wlmemory.c b/reactos/boot/freeldr/freeldr/windows/wlmemory.c index a9393a6e98f..1a814739b41 100644 --- a/reactos/boot/freeldr/freeldr/windows/wlmemory.c +++ b/reactos/boot/freeldr/freeldr/windows/wlmemory.c @@ -19,17 +19,928 @@ #undef KIP0PCRADDRESS #define KIP0PCRADDRESS 0xffdff000 +// +// This is the zone which is used by the OS loader +// +#define LOADER_HIGH_ZONE ((16*1024*1024) >> MM_PAGE_SHIFT) //16Mb page + #define HYPER_SPACE_ENTRY 0x300 +//TODO: Check if this is correct +PCHAR MemTypeDesc[] = { + "ExceptionBlock ", + "SystemBlock ", + "Free ", + "Bad ", + "LoadedProgram ", + "FirmwareTemporary ", + "FirmwarePermanent ", + "OsloaderHeap ", + "OsloaderStack ", + "SystemCode ", + "HalCode ", + "BootDriver ", + "ConsoleInDriver ", + "ConsoleOutDriver ", + "StartupDpcStack ", + "StartupKernelStack", + "StartupPanicStack ", + "StartupPcrPage ", + "StartupPdrPage ", + "RegistryData ", + "MemoryData ", + "NlsData ", + "SpecialMemory ", + "BBTMemory ", + "Maximum " + }; + +VOID +WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); + + +VOID +MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + UINT64 BasePage, + UINT64 PageCount, + ULONG Type); +VOID +WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor); + +VOID +WinLdrRemoveDescriptor(IN PMEMORY_ALLOCATION_DESCRIPTOR Descriptor); + +VOID +WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss); + +// This is needed only for SetProcessorContext routine +#pragma pack(2) + typedef struct + { + USHORT Limit; + ULONG Base; + } GDTIDT; +#pragma pack(4) + +// this is needed for new IDT filling +#if 0 +extern ULONG_PTR i386DivideByZero; +extern ULONG_PTR i386DebugException; +extern ULONG_PTR i386NMIException; +extern ULONG_PTR i386Breakpoint; +extern ULONG_PTR i386Overflow; +extern ULONG_PTR i386BoundException; +extern ULONG_PTR i386InvalidOpcode; +extern ULONG_PTR i386FPUNotAvailable; +extern ULONG_PTR i386DoubleFault; +extern ULONG_PTR i386CoprocessorSegment; +extern ULONG_PTR i386InvalidTSS; +extern ULONG_PTR i386SegmentNotPresent; +extern ULONG_PTR i386StackException; +extern ULONG_PTR i386GeneralProtectionFault; +extern ULONG_PTR i386PageFault; // exc 14 +extern ULONG_PTR i386CoprocessorError; // exc 16 +extern ULONG_PTR i386AlignmentCheck; // exc 17 +#endif + /* GLOBALS ***************************************************************/ +PHARDWARE_PTE PDE; +PHARDWARE_PTE HalPT; + +PUCHAR PhysicalPageTablesBuffer; +PUCHAR KernelPageTablesBuffer; +ULONG PhysicalPageTables; +ULONG KernelPageTables; + +MEMORY_ALLOCATION_DESCRIPTOR Mad[1024]; +ULONG MadCount = 0; + + /* FUNCTIONS **************************************************************/ +BOOLEAN +MempAllocatePageTables() +{ + ULONG NumPageTables, TotalSize; + PUCHAR Buffer; + // It's better to allocate PDE + PTEs contigiuos + + // Max number of entries = MaxPageNum >> 10 + // FIXME: This is a number to describe ALL physical memory + // and windows doesn't expect ALL memory mapped... + NumPageTables = (GetSystemMemorySize() >> MM_PAGE_SHIFT) >> 10; + + DbgPrint((DPRINT_WINDOWS, "NumPageTables = %d\n", NumPageTables)); + + // Allocate memory block for all these things: + // PDE, HAL mapping page table, physical mapping, kernel mapping + TotalSize = (1+1+NumPageTables*2)*MM_PAGE_SIZE; + Buffer = MmAllocateMemory(TotalSize); + + if (Buffer == NULL) + { + UiMessageBox("Impossible to allocate memory block for page tables!"); + return FALSE; + } + + // Zero all this memory block + RtlZeroMemory(Buffer, TotalSize); + + // Set up pointers correctly now + PDE = (PHARDWARE_PTE)Buffer; + + // Map the page directory at 0xC0000000 (maps itself) + PDE[HYPER_SPACE_ENTRY].PageFrameNumber = (ULONG)PDE >> MM_PAGE_SHIFT; + PDE[HYPER_SPACE_ENTRY].Valid = 1; + PDE[HYPER_SPACE_ENTRY].Write = 1; + + // The last PDE slot is allocated for HAL's memory mapping (Virtual Addresses 0xFFC00000 - 0xFFFFFFFF) + HalPT = (PHARDWARE_PTE)&Buffer[MM_PAGE_SIZE*1]; + + // Map it + PDE[1023].PageFrameNumber = (ULONG)HalPT >> MM_PAGE_SHIFT; + PDE[1023].Valid = 1; + PDE[1023].Write = 1; + + // Store pointers to the tables for easier access + PhysicalPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2]; + KernelPageTablesBuffer = PhysicalPageTablesBuffer + NumPageTables*MM_PAGE_SIZE; + + // Zero counters of page tables used + PhysicalPageTables = 0; + KernelPageTables = 0; + + return TRUE; +} + +VOID +MempAllocatePTE(ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT) +{ + //Print(L"Creating PDE Entry %X\n", Entry); + + // Identity mapping + *PhysicalPT = (PHARDWARE_PTE)&PhysicalPageTablesBuffer[PhysicalPageTables*MM_PAGE_SIZE]; + PhysicalPageTables++; + + PDE[Entry].PageFrameNumber = (ULONG)*PhysicalPT >> MM_PAGE_SHIFT; + PDE[Entry].Valid = 1; + PDE[Entry].Write = 1; + + if (Entry+(KSEG0_BASE >> 22) > 1023) + { + DbgPrint((DPRINT_WINDOWS, "WARNING! Entry: %X > 1023\n", Entry+(KSEG0_BASE >> 22))); + } + + // Kernel-mode mapping + *KernelPT = (PHARDWARE_PTE)&KernelPageTablesBuffer[KernelPageTables*MM_PAGE_SIZE]; + KernelPageTables++; + + PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber = ((ULONG)*KernelPT >> MM_PAGE_SHIFT); + PDE[Entry+(KSEG0_BASE >> 22)].Valid = 1; + PDE[Entry+(KSEG0_BASE >> 22)].Write = 1; +} + +BOOLEAN +MempSetupPaging(IN ULONG StartPage, + IN ULONG NumberOfPages) +{ + PHARDWARE_PTE PhysicalPT; + PHARDWARE_PTE KernelPT; + ULONG Entry, Page; + + //Print(L"MempSetupPaging: SP 0x%X, Number: 0x%X\n", StartPage, NumberOfPages); + + // HACK + if (StartPage+NumberOfPages >= 0x80000) + { + // + // We can't map this as it requires more than 1 PDE + // and in fact it's not possible at all ;) + // + //Print(L"skipping...\n"); + return TRUE; + } + + // + // Now actually set up the page tables for identity mapping + // + for (Page=StartPage; Page < StartPage+NumberOfPages; Page++) + { + Entry = Page >> 10; + + if (((PULONG)PDE)[Entry] == 0) + { + MempAllocatePTE(Entry, &PhysicalPT, &KernelPT); + } + else + { + PhysicalPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT); + KernelPT = (PHARDWARE_PTE)(PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber << MM_PAGE_SHIFT); + } + + if (Page == 0) + { + PhysicalPT[Page & 0x3ff].PageFrameNumber = Page; + PhysicalPT[Page & 0x3ff].Valid = 0; + PhysicalPT[Page & 0x3ff].Write = 0; + + KernelPT[Page & 0x3ff].PageFrameNumber = Page; + KernelPT[Page & 0x3ff].Valid = 0; + KernelPT[Page & 0x3ff].Write = 0; + } + else + { + PhysicalPT[Page & 0x3ff].PageFrameNumber = Page; + PhysicalPT[Page & 0x3ff].Valid = 1; + PhysicalPT[Page & 0x3ff].Write = 1; + + KernelPT[Page & 0x3ff].PageFrameNumber = Page; + KernelPT[Page & 0x3ff].Valid = 1; + KernelPT[Page & 0x3ff].Write = 1; + } + } + + return TRUE; +} + +VOID +MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + UINT64 BasePage, + UINT64 PageCount, + ULONG Type) +{ + BOOLEAN Status; + + // + // Check for some weird stuff at the top + // + if (BasePage + PageCount > 0xF0000) + { + // + // Just skip this, without even adding to MAD list + // + return; + } + + // + // Base page and page count are always set + // + Mad[MadCount].BasePage = BasePage; + Mad[MadCount].PageCount = PageCount; + + // + // Check if it's more than the allowed for OS loader + // if yes - don't map the pages, just add as FirmwareTemporary + // + if (BasePage + PageCount > LOADER_HIGH_ZONE) + { + Mad[MadCount].MemoryType = LoaderFirmwareTemporary; + + WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]); + MadCount++; + + Status = MempSetupPaging(BasePage, PageCount); + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "Error during WinLdrpSetupPaging\n")); + return; + } + return; + } + + if (BasePage == 0xFFF && PageCount == 1) + { + Mad[MadCount].MemoryType = LoaderSpecialMemory; + + WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]); + MadCount++; + + // + // Map it + // + Status = MempSetupPaging(BasePage, PageCount); + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n")); + return; + } + } + else if (BasePage == 0 && PageCount == 1) + { + Mad[MadCount].MemoryType = LoaderFirmwarePermanent; + + WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]); + MadCount++; + + // + // Map it + // + Status = MempSetupPaging(BasePage, PageCount); + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n")); + return; + } + } + else + { + // + // Now choose memory type as usual. FIXME!!! + // + if (Type == 0) + { + Mad[MadCount].MemoryType = LoaderFree; + } + else if (Type != 0 && Type != 1) + { + Mad[MadCount].MemoryType = LoaderFirmwarePermanent; + } + else if (Type == 1) + { + Mad[MadCount].MemoryType = LoaderSystemCode; + } + else + { + Mad[MadCount].MemoryType = LoaderFirmwarePermanent; + } + + // + // Add descriptor + // + WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]); + MadCount++; + + // + // Map it + // + Status = MempSetupPaging(BasePage, PageCount); + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n")); + return; + } + } +} + BOOLEAN WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, ULONG PcrBasePage, ULONG TssBasePage, PVOID GdtIdt) { - return FALSE; + ULONG i, PagesCount; + ULONG LastPageIndex, LastPageType; + PPAGE_LOOKUP_TABLE_ITEM MemoryMap; + ULONG NoEntries; + PKTSS Tss; + + // + // Creating a suitable memory map for the Windows can be tricky, so let's + // give a few advices: + // 1) One must not map the whole available memory pages to PDE! + // Map only what's needed - 16Mb, 24Mb, 32Mb max I think, + // thus occupying 4, 6 or 8 PDE entries for identical mapping, + // the same quantity for KSEG0_BASE mapping, one more entry for + // hyperspace and one more entry for HAL physical pages mapping. + // 2) Memory descriptors must map *the whole* physical memory + // showing any memory above 16/24/32 as FirmwareTemporary + // + // 3) Overall memory blocks count must not exceed 30 + // + + // + // During MmInitMachineDependent, the kernel zeroes PDE at the following address + // 0xC0300000 - 0xC03007FC + // + // Then it finds the best place for non-paged pool: + // StartPde C0300F70, EndPde C0300FF8, NumberOfPages C13, NextPhysPage 3AD + // + + // Before we start mapping pages, create a block of memory, which will contain + // PDE and PTEs + if (MempAllocatePageTables() == FALSE) + return FALSE; + + // Setup an entry for each descriptor + MemoryMap = MmGetMemoryMap(&NoEntries); + if (MemoryMap == NULL) + { + UiMessageBox("Can not retrieve the current memory map"); + return FALSE; + } + + DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries\n")); + + // Construct a good memory map from what we've got + PagesCount = 1; + LastPageIndex = 0; + LastPageType = MemoryMap[0].PageAllocated; + for(i=1;i> MM_PAGE_SHIFT, OsLoaderSize >> MM_PAGE_SHIFT); + if (!Status) + { + UiMessageBox("Error during MempSetupPaging"); + return; + }*/ + + //VideoDisplayString(L"Hello from VGA, going into the kernel\n"); + DbgPrint((DPRINT_WINDOWS, "HalPT: 0x%X\n", HalPT)); + + // Page Tables have been setup, make special handling for PCR and TSS + // (which is done in BlSetupFotNt in usual ntldr) + HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage+1; + HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1; + HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1; + + HalPT[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage; + HalPT[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1; + HalPT[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1; + + // Map VGA memory + //VideoMemoryBase = MmMapIoSpace(0xb8000, 4000, MmNonCached); + //DbgPrint((DPRINT_WINDOWS, "VideoMemoryBase: 0x%X\n", VideoMemoryBase)); + + Tss = (PKTSS)(KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT)); + + // Fill the memory descriptor list and + //PrepareMemoryDescriptorList(); + DbgPrint((DPRINT_WINDOWS, "Memory Descriptor List prepared, printing PDE\n")); + List_PaToVa(&LoaderBlock->MemoryDescriptorListHead); + + { + ULONG *PDE_Addr=(ULONG *)PDE;//0xC0300000; + int j; + + DbgPrint((DPRINT_WINDOWS, "\nPDE\n")); + + for (i=0; i<128; i++) + { + DbgPrint((DPRINT_WINDOWS, "0x%04X | ", i*8)); + + for (j=0; j<8; j++) + { + DbgPrint((DPRINT_WINDOWS, "0x%08X ", PDE_Addr[i*8+j])); + } + + DbgPrint((DPRINT_WINDOWS, "\n")); + } + } + + + // Enable paging + //BS->ExitBootServices(ImageHandle,MapKey); + + // Disable Interrupts + Ke386DisableInterrupts(); + + // Re-initalize EFLAGS + Ke386EraseFlags(); + + // Set the PDBR + Ke386SetPageTableDirectory((ULONG_PTR)PDE); + + // Enable paging by modifying CR0 + Ke386SetCr0(Ke386GetCr0() | CR0_PG); + + // Set processor context + WinLdrSetProcessorContext(GdtIdt, KIP0PCRADDRESS, KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT)); + + // Zero KI_USER_SHARED_DATA page + memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE); + + return TRUE; +} + +// Two special things this func does: it sorts descriptors, +// and it merges free ones +VOID +WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor) +{ + PLIST_ENTRY ListHead = &LoaderBlock->MemoryDescriptorListHead; + PLIST_ENTRY PreviousEntry, NextEntry; + PMEMORY_ALLOCATION_DESCRIPTOR PreviousDescriptor = NULL, NextDescriptor = NULL; + + DbgPrint((DPRINT_WINDOWS, "BP=0x%X PC=0x%X %s\n", NewDescriptor->BasePage, + NewDescriptor->PageCount, MemTypeDesc[NewDescriptor->MemoryType])); + + /* Find a place where to insert the new descriptor to */ + PreviousEntry = ListHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + NextDescriptor = CONTAINING_RECORD(NextEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + if (NewDescriptor->BasePage < NextDescriptor->BasePage) + break; + + PreviousEntry = NextEntry; + PreviousDescriptor = NextDescriptor; + NextEntry = NextEntry->Flink; + } + + /* Don't forget about merging free areas */ + if (NewDescriptor->MemoryType != LoaderFree) + { + /* Just insert, nothing to merge */ + InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry); + } + else + { + /* Previous block also free? */ + if ((PreviousEntry != ListHead) && (PreviousDescriptor->MemoryType == LoaderFree) && + ((PreviousDescriptor->BasePage + PreviousDescriptor->PageCount) == + NewDescriptor->BasePage)) + { + /* Just enlarge previous descriptor's PageCount */ + PreviousDescriptor->PageCount += NewDescriptor->PageCount; + NewDescriptor = PreviousDescriptor; + } + else + { + /* Nope, just insert */ + InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry); + } + + /* Next block is free ?*/ + if ((NextEntry != ListHead) && + (NextDescriptor->MemoryType == LoaderFree) && + ((NewDescriptor->BasePage + NewDescriptor->PageCount) == NextDescriptor->BasePage)) + { + /* Enlarge next descriptor's PageCount */ + NewDescriptor->PageCount += NextDescriptor->PageCount; + RemoveEntryList(&NextDescriptor->ListEntry); + } + } + + return; +} + +VOID +WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss) +{ + GDTIDT GdtDesc, IdtDesc, OldIdt; + PKGDTENTRY pGdt; + PKIDTENTRY pIdt; + ULONG Ldt = 0; + //ULONG i; + + DbgPrint((DPRINT_WINDOWS, "GDtIdt %p, Pcr %p, Tss 0x%08X\n", + GdtIdt, Pcr, Tss)); + + // Kernel expects the PCR to be zero-filled on startup + // FIXME: Why zero it here when we can zero it right after allocation? + RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE); //FIXME: Why zero only 1 page when we allocate 2? + + // Get old values of GDT and IDT + Ke386GetGlobalDescriptorTable(GdtDesc); + Ke386GetInterruptDescriptorTable(IdtDesc); + + // Save old IDT + OldIdt.Base = IdtDesc.Base; + OldIdt.Limit = IdtDesc.Limit; + + // Prepare new IDT+GDT + GdtDesc.Base = KSEG0_BASE | (ULONG_PTR)GdtIdt; + GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1; + IdtDesc.Base = (ULONG)((PUCHAR)GdtDesc.Base + GdtDesc.Limit + 1); + IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1; + + // ======================== + // Fill all descriptors now + // ======================== + + pGdt = (PKGDTENTRY)GdtDesc.Base; + pIdt = (PKIDTENTRY)IdtDesc.Base; + + // + // Code selector (0x8) + // Flat 4Gb + // + pGdt[1].LimitLow = 0xFFFF; + pGdt[1].BaseLow = 0; + pGdt[1].HighWord.Bytes.BaseMid = 0; + pGdt[1].HighWord.Bytes.Flags1 = 0x9A; + pGdt[1].HighWord.Bytes.Flags2 = 0xCF; + pGdt[1].HighWord.Bytes.BaseHi = 0; + + // + // Data selector (0x10) + // Flat 4Gb + // + pGdt[2].LimitLow = 0xFFFF; + pGdt[2].BaseLow = 0; + pGdt[2].HighWord.Bytes.BaseMid = 0; + pGdt[2].HighWord.Bytes.Flags1 = 0x92; + pGdt[2].HighWord.Bytes.Flags2 = 0xCF; + pGdt[2].HighWord.Bytes.BaseHi = 0; + + // + // Selector (0x18) + // Flat 2Gb + // + pGdt[3].LimitLow = 0xFFFF; + pGdt[3].BaseLow = 0; + pGdt[3].HighWord.Bytes.BaseMid = 0; + pGdt[3].HighWord.Bytes.Flags1 = 0xFA; + pGdt[3].HighWord.Bytes.Flags2 = 0xCF; + pGdt[3].HighWord.Bytes.BaseHi = 0; + + // + // Selector (0x20) + // Flat 2Gb + // + pGdt[4].LimitLow = 0xFFFF; + pGdt[4].BaseLow = 0; + pGdt[4].HighWord.Bytes.BaseMid = 0; + pGdt[4].HighWord.Bytes.Flags1 = 0xF2; + pGdt[4].HighWord.Bytes.Flags2 = 0xCF; + pGdt[4].HighWord.Bytes.BaseHi = 0; + + // + // TSS Selector (0x28) + // + pGdt[5].LimitLow = 0x78-1; // 60 dwords + pGdt[5].BaseLow = (USHORT)(Tss & 0xffff); + pGdt[5].HighWord.Bytes.BaseMid = (UCHAR)((Tss >> 16) & 0xff); + pGdt[5].HighWord.Bytes.Flags1 = 0x89; + pGdt[5].HighWord.Bytes.Flags2 = 0x00; + pGdt[5].HighWord.Bytes.BaseHi = (UCHAR)((Tss >> 24) & 0xff); + + // + // PCR Selector (0x30) + // + pGdt[6].LimitLow = 0x01; + pGdt[6].BaseLow = (USHORT)(Pcr & 0xffff); + pGdt[6].HighWord.Bytes.BaseMid = (UCHAR)((Pcr >> 16) & 0xff); + pGdt[6].HighWord.Bytes.Flags1 = 0x92; + pGdt[6].HighWord.Bytes.Flags2 = 0xC0; + pGdt[6].HighWord.Bytes.BaseHi = (UCHAR)((Pcr >> 24) & 0xff); + + // + // Selector (0x38) + // + pGdt[7].LimitLow = 0xFFFF; + pGdt[7].BaseLow = 0; + pGdt[7].HighWord.Bytes.BaseMid = 0; + pGdt[7].HighWord.Bytes.Flags1 = 0xF3; + pGdt[7].HighWord.Bytes.Flags2 = 0x40; + pGdt[7].HighWord.Bytes.BaseHi = 0; + + // + // Some BIOS fuck (0x40) + // + pGdt[8].LimitLow = 0xFFFF; + pGdt[8].BaseLow = 0x400; + pGdt[8].HighWord.Bytes.BaseMid = 0; + pGdt[8].HighWord.Bytes.Flags1 = 0xF2; + pGdt[8].HighWord.Bytes.Flags2 = 0x0; + pGdt[8].HighWord.Bytes.BaseHi = 0; + + // + // Selector (0x48) + // + pGdt[9].LimitLow = 0; + pGdt[9].BaseLow = 0; + pGdt[9].HighWord.Bytes.BaseMid = 0; + pGdt[9].HighWord.Bytes.Flags1 = 0; + pGdt[9].HighWord.Bytes.Flags2 = 0; + pGdt[9].HighWord.Bytes.BaseHi = 0; + + // + // Selector (0x50) + // + pGdt[10].LimitLow = 0xFFFF; //FIXME: Not correct! + pGdt[10].BaseLow = 0; + pGdt[10].HighWord.Bytes.BaseMid = 0x2; + pGdt[10].HighWord.Bytes.Flags1 = 0x89; + pGdt[10].HighWord.Bytes.Flags2 = 0; + pGdt[10].HighWord.Bytes.BaseHi = 0; + + // + // Selector (0x58) + // + pGdt[11].LimitLow = 0xFFFF; + pGdt[11].BaseLow = 0; + pGdt[11].HighWord.Bytes.BaseMid = 0x2; + pGdt[11].HighWord.Bytes.Flags1 = 0x9A; + pGdt[11].HighWord.Bytes.Flags2 = 0; + pGdt[11].HighWord.Bytes.BaseHi = 0; + + // + // Selector (0x60) + // + pGdt[12].LimitLow = 0xFFFF; + pGdt[12].BaseLow = 0; //FIXME: Maybe not correct, but noone cares + pGdt[12].HighWord.Bytes.BaseMid = 0x2; + pGdt[12].HighWord.Bytes.Flags1 = 0x92; + pGdt[12].HighWord.Bytes.Flags2 = 0; + pGdt[12].HighWord.Bytes.BaseHi = 0; + + // + // Video buffer Selector (0x68) + // + pGdt[13].LimitLow = 0x3FFF; + pGdt[13].BaseLow = 0x8000; //FIXME: I guess not correct for UGA + pGdt[13].HighWord.Bytes.BaseMid = 0x0B; + pGdt[13].HighWord.Bytes.Flags1 = 0x92; + pGdt[13].HighWord.Bytes.Flags2 = 0; + pGdt[13].HighWord.Bytes.BaseHi = 0; + + // + // Points to GDT (0x70) + // + pGdt[14].LimitLow = NUM_GDT*sizeof(KGDTENTRY) - 1; + pGdt[14].BaseLow = 0x7000; + pGdt[14].HighWord.Bytes.BaseMid = 0xFF; + pGdt[14].HighWord.Bytes.Flags1 = 0x92; + pGdt[14].HighWord.Bytes.Flags2 = 0; + pGdt[14].HighWord.Bytes.BaseHi = 0xFF; + + // + // Some unused descriptors should go here + // ... + + // + // Fill IDT with Traps + // +#if 0 + pIdt[0].Offset = (i386DivideByZero | KSEG0_BASE) & 0xFFFF; + pIdt[0].ExtendedOffset = 0x8; // Selector + pIdt[0].Access = 0x8F00; + pIdt[0].Selector = (i386DivideByZero | KSEG0_BASE) >> 16; // Extended Offset + + pIdt[1].Offset = (i386DebugException | KSEG0_BASE) & 0xFFFF; + pIdt[1].ExtendedOffset = 0x8; // Selector + pIdt[1].Access = 0x8F00; + pIdt[1].Selector = (i386DebugException | KSEG0_BASE) >> 16; // Extended Offset + + pIdt[2].Offset = (i386NMIException | KSEG0_BASE) & 0xFFFF; + pIdt[2].ExtendedOffset = 0x8; // Selector + pIdt[2].Access = 0x8F00; + pIdt[2].Selector = (i386NMIException | KSEG0_BASE) >> 16; // Extended Offset + + pIdt[3].Offset = (i386Breakpoint | KSEG0_BASE) & 0xFFFF; + pIdt[3].ExtendedOffset = 0x8; // Selector + pIdt[3].Access = 0x8F00; + pIdt[3].Selector = (i386Breakpoint | KSEG0_BASE) >> 16; // Extended Offset + + pIdt[4].Offset = (i386Overflow | KSEG0_BASE) & 0xFFFF; + pIdt[4].ExtendedOffset = 0x8; // Selector + pIdt[4].Access = 0x8F00; + pIdt[4].Selector = (i386Overflow | KSEG0_BASE) >> 16; // Extended Offset + + pIdt[5].Selector = (i386BoundException | KSEG0_BASE) >> 16; // Extended Offset + pIdt[5].Offset = (i386BoundException | KSEG0_BASE) & 0xFFFF; + pIdt[5].ExtendedOffset = 0x8; // Selector + pIdt[5].Access = 0x8F00; + + pIdt[6].Selector = (i386InvalidOpcode | KSEG0_BASE) >> 16; // Extended Offset + pIdt[6].Offset = (i386InvalidOpcode | KSEG0_BASE) & 0xFFFF; + pIdt[6].ExtendedOffset = 0x8; // Selector + pIdt[6].Access = 0x8F00; + + pIdt[7].Selector = (i386FPUNotAvailable | KSEG0_BASE) >> 16; // Extended Offset + pIdt[7].Offset = (i386FPUNotAvailable | KSEG0_BASE) & 0xFFFF; + pIdt[7].ExtendedOffset = 0x8; // Selector + pIdt[7].Access = 0x8F00; + + pIdt[8].Selector = (i386DoubleFault | KSEG0_BASE) >> 16; // Extended Offset + pIdt[8].Offset = (i386DoubleFault | KSEG0_BASE) & 0xFFFF; + pIdt[8].ExtendedOffset = 0x8; // Selector + pIdt[8].Access = 0x8F00; + + pIdt[9].Selector = (i386CoprocessorSegment | KSEG0_BASE) >> 16; // Extended Offset + pIdt[9].Offset = (i386CoprocessorSegment | KSEG0_BASE) & 0xFFFF; + pIdt[9].ExtendedOffset = 0x8; // Selector + pIdt[9].Access = 0x8F00; + + pIdt[10].Selector = (i386InvalidTSS | KSEG0_BASE) >> 16; // Extended Offset + pIdt[10].Offset = (i386InvalidTSS | KSEG0_BASE) & 0xFFFF; + pIdt[10].ExtendedOffset = 0x8; // Selector + pIdt[10].Access = 0x8F00; + + pIdt[11].Selector = (i386SegmentNotPresent | KSEG0_BASE) >> 16; // Extended Offset + pIdt[11].Offset = (i386SegmentNotPresent | KSEG0_BASE) & 0xFFFF; + pIdt[11].ExtendedOffset = 0x8; // Selector + pIdt[11].Access = 0x8F00; + + pIdt[12].Selector = (i386StackException | KSEG0_BASE) >> 16; // Extended Offset + pIdt[12].Offset = (i386StackException | KSEG0_BASE) & 0xFFFF; + pIdt[12].ExtendedOffset = 0x8; // Selector + pIdt[12].Access = 0x8F00; + + pIdt[13].Selector = (i386GeneralProtectionFault | KSEG0_BASE) >> 16; // Extended Offset + pIdt[13].Offset = (i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF; + pIdt[13].ExtendedOffset = 0x8; // Selector + pIdt[13].Access = 0x8F00; + + pIdt[14].Selector = (i386PageFault | KSEG0_BASE) >> 16; // Extended Offset + pIdt[14].Offset = (i386PageFault | KSEG0_BASE) & 0xFFFF; + pIdt[14].ExtendedOffset = 0x8; // Selector + pIdt[14].Access = 0x8F00; + + pIdt[15].Selector = 0; // Extended Offset + pIdt[15].Offset = 0; + pIdt[15].ExtendedOffset = 0; // Selector + pIdt[15].Access = 0; + + pIdt[16].Selector = (i386CoprocessorError | KSEG0_BASE) >> 16; // Extended Offset + pIdt[16].Offset = (i386CoprocessorError | KSEG0_BASE) & 0xFFFF; + pIdt[16].ExtendedOffset = 0x8; // Selector + pIdt[16].Access = 0x8F00; + + pIdt[17].Selector = (i386AlignmentCheck | KSEG0_BASE) >> 16; // Extended Offset + pIdt[17].Offset = (i386AlignmentCheck | KSEG0_BASE) & 0xFFFF; + pIdt[17].ExtendedOffset = 0x8; // Selector + pIdt[17].Access = 0x8F00; +#endif + + /*for (i=0; i<16; i++) + { + //pIdt[i].Offset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF; + //pIdt[i].ExtendedOffset = 0x8; // Selector + //pIdt[i].Access = 0x8F00; + //pIdt[i].Selector = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) >> 16; // Extended Offset + + pIdt[i].Offset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF; + pIdt[i].ExtendedOffset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) >> 16; // Extended Offset + pIdt[i].Access = 0x8F00; + pIdt[i].Selector = 0x8; + }*/ + + // Copy the old IDT + RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit); + + + // Mask interrupts + //asm("cli\n"); // they are already masked before enabling paged mode + + // Load GDT+IDT + Ke386SetGlobalDescriptorTable(GdtDesc); + Ke386SetInterruptDescriptorTable(IdtDesc); + + // Jump to proper CS and clear prefetch queue + asm("ljmp $0x08, $mb1\n" + "mb1:\n"); + + // Set SS selector + asm(".intel_syntax noprefix\n"); + asm("mov ax, 0x10\n"); // DataSelector=0x10 + asm("mov ss, ax\n"); + asm(".att_syntax\n"); + + // Set DS and ES selectors + Ke386SetDs(0x10); + Ke386SetEs(0x10); // this is vital for rep stosd + + // LDT = not used ever, thus set to 0 + Ke386SetLocalDescriptorTable(Ldt); + + // Load TSR + Ke386SetTr(0x28); + + // Clear GS + asm(".intel_syntax noprefix\n"); + asm("push 0\n"); + asm("pop gs\n"); + asm(".att_syntax\n"); + + // Set FS to PCR + Ke386SetFs(0x30); + + // Real end of the function, just for information + /* do not uncomment! + pop edi; + pop esi; + pop ebx; + mov esp, ebp; + pop ebp; + ret + */ } From a387e6f9f8223e7df744965a581ec07c06668765 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Wed, 4 Oct 2006 22:06:00 +0000 Subject: [PATCH 469/488] -removed unused var svn path=/trunk/; revision=24406 --- reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp index 6f07c4cbc67..89ea4df7910 100644 --- a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp @@ -812,7 +812,6 @@ MSVCBackend::_generate_sln ( FILE* OUT ) Module& module = *ProjectNode.modules[i]; std::string vcproj_file = VcprojFileName ( module ); - std::string vcproj_file_user = vcproj_file + "CHRIS-NOTEBOOK.Christoph.user"; _generate_sln_project ( OUT, module, vcproj_file, sln_guid, module.guid, module.non_if_data.libraries ); } _generate_sln_footer ( OUT ); From 52d60b023b6309b1904ecb3b73270eb49bc9fe15 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Wed, 4 Oct 2006 22:29:18 +0000 Subject: [PATCH 470/488] add a few more icons to the device imagelist svn path=/trunk/; revision=24407 --- reactos/dll/win32/setupapi/res/icons/10.ico | Bin 1078 -> 13270 bytes reactos/dll/win32/setupapi/res/icons/20.ico | Bin 1078 -> 13270 bytes reactos/dll/win32/setupapi/res/icons/28.ico | Bin 1078 -> 13270 bytes reactos/dll/win32/setupapi/res/icons/501.ico | Bin 13270 -> 13270 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/reactos/dll/win32/setupapi/res/icons/10.ico b/reactos/dll/win32/setupapi/res/icons/10.ico index 43521de70d69f3ed0af849f88f0cd7d6a5151e7d..d39b4fccfd961d8a3c83c4172143fd3409fd2110 100644 GIT binary patch literal 13270 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 literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ diff --git a/reactos/dll/win32/setupapi/res/icons/20.ico b/reactos/dll/win32/setupapi/res/icons/20.ico index 43521de70d69f3ed0af849f88f0cd7d6a5151e7d..a0bd095a26448ee72ea3a7603fe6c0b85f803cbf 100644 GIT binary patch literal 13270 zcmeHN30PFevi_L?W(H<}85UWGVHE^LKro032qGY|iij*C$STO9h&!mbi-00)3>uAs zq6uz^Mg#5|V^)_Nuc$FGdo*gi(SX$L0WlEKcwh8=@8(f_|8#eCb=T=Shg02E2T*`A zWHPXlk6J#E2tZf2qkT#lP!j+e8XfIqCE$WO9?8p4%lN~!JLP3q#$>;?=#-ZsSrM3O z2UxK=nF_cw$n~@n>w8QJtR@E|tw6vakP9PUB^U+>p*Dd7)hG@m!3xk0=0GD1(2U{3 zaDoa0bQVZqu*ekp1s2dNvVvjB z07%OQLR#$vlNC0Qt+9hukppZC9pRGi3X3%kur79j?OIpZmc0U-N>`X|VD&AY=(l+! zENe%=dDAF3yx|9z%{~}Z>w_V+qcN;L07G{K!D(L*TpAMAKn{zPiNGwJki^G@`$r$}{Is!hPis)n682gV| zSg>+FmX=S);;I~E99@XC^ZA&1br~{0D@5M8BFt)Dg}kek$h-V1;;%17+KrW%{RQKH zRf0L!%8+}v8uME=pQF>zwD!#2n_02jge6Se>3`?mFtJ~^P(zX*-_Zslpy*;RW*nnNP-owT_yRq@! zKGfdXg*Wc)NA0}>c=OJC*naOIcHBFJw^|Nj|Mw@c=hi9gxqBFgem#PHbQ}lnpTK+f zkK-LWiDNCNaq|9$IP>r$oP78x&i{4^-?e;;AAY-q7Ha8uz6iwClBn}o$Bb+*<2RA zb@H(G#t@HAUZ8JWtfhNL%Wl>@;~aT)XjFiPO9yXM{`#tHFH1|yzJ2?ST$gCh$lBZ{ zqda?zhBK3hA75EjRasqKvx(8>-J3SEqNb+0ys~m}+-N2+#cxT)&TVs7ZeCkhxLQty zg@vnD&0SMpK0VCXlTDx-w{z22{XWwY^bL%RB#guoiH308N`HgF?H7=)X{akjl7E46 zO2-Ase`lz0Tz_xLYg+StnEM&go!O=J%E%H+o|Y-ktqZSPRpOsFZcbe^ryH|t!^$*m z-`jsjm_@C^Eb^))e|18oZQWvj7UQ>#?H z3E<|l9fTaL&O6L&Go~d>EZ>a{VYtTdGsFEndKSs|DQxQl`F}*`KE=K3J(l0kNB2~B zyb7!*>cB4402;A;h}oV(zK1YNGk|%v6gE*NaE`KsG|vRK@g|UEn8G2+2DUktaL#eW zz??yFn(d6i^IhQ);|!m~p$JZNMc^zqj861`SGos$lRXfY;g0c%qcI}W1KwGq;4{w? z@iYA~IV~JX^TuJ?+$qqK?-L5lV6@l@#w%=Lw$KU|MFU~C+!4c;xMA?JA?RQ145#8@ z7*gVeK{X>Ww8k65DtzEj>kFq{fruywM|AN7Brb?X>aqxUZV7?!wy_vfKN0Q?p$Oa; zgM^x7%v+j`xodNfS&@y<#w3j0n}Udg$(ZzZ8fMn!VDh0XBp=L1>cJeOADjW-6AAD= zoq{oEQjye@gM?G_k$Pq}ir3Fa=H*qG*SrRCUoXSduM08d+trwLtpqtY%Q5HYDlDyE zfJK)}u%NjVi<`@^w7CL{KVOe!&6Oy)R*F?OUPbYj8?fg4*W3O28rq4PTf0&HfPwbm ztviSC&b>zL{?`#SK6oD|9-PI=o1fsqgG*>`ZN|?nci9c?rCtj>zXjO)`^jQ?Mcb^sIebvq7?IRSPfsmq zm_T1&S7r22p$Y4;7@wFB9vT@F6Pp?z8yOQC8j�kqfAfO-UaWkmT#@CnsOuQL!oh zRyu5e`N;mp>LE%U&Ki(e^9|Y+z#Ew0GEl3d0R(qe>ByMg&BFn@)UUw(vqa2XWZ(d4!iKe}B-8;_0U zGAv>^$K*B*dJXh0K%l5dX<+%)PK2b1oJl_op%}WM{_}7t64go#VDYIE16$oyFzfuKd2f z-de8(dM)rw3;Z=d)~Ea2mX7*e88&7EIy{g$Uyt#{awo#hTR`7|{iIS8J8KgY!~Rxm zW36IuXkjE4i$o$-8%-8mgb1QXK0xj*+DX9E?)vHilpUCd=}Ph~`~QgKuKY2svU(8% zi*K&Z1@f6vIX?RpxSt2KGPHG-XZ7xJOGHx;QRsL;xr8>o>^ zP`_Fal8oh$-BvGh-4{Z#Bu&z_7X>`8UiDBNE^M$AZuk_=I13fz3LHgp$JZl?{S+5F z?ewD$*m@n`^dpfYj>-j%$Ermd2dYjn_R-dr`ReP6^>9=uLcO9I_mv(e>STuDoL+@3 z4L%i3j_-w#C|^R*Lj%`HVLaCWQ5-`=DHsYHqb z7E3i!jNt2W!UejVaJ~*_oNhlHAAB&BEQ<$_nV%AAs^N%|3ddh$Cg>VD12;xFL#xn~ z5`QSBt#pt!F!-O(B3`bD1hdpgWu`i*=BknE3=s))L?p@t4Svg?R1>6~P4gGrq` zRnvYdrX93`wowu7WY^L}^>mDJj?gYT#b!A}2bjg*r4QT7bL>fbr|mSm+OurrS=RqP z?V;237CU_HpyO1>#uc#NLfTFhtY;CMclbvsWL#xOGCf>+tUrlUr(0>y^fu5u+QhVe zKqp&1r3Dw)(y~hxbm+kuD*vXAO8!|xrOmI?y5`MP*1U<;H@27Su56~#E3Z?@m5o$% zrG^TxuBR1Ot7%DdIj#PBBYQeOWg*X;{~IYAAnZD7__STqg6N>ts)<^s(GVT zJd$AqTD3gTDj5zk-Zq>{zu7|CMV6!)0J62kKP?bNpBUi?7IL8K`};|>+LR=0Z5$=Uspw;xP!n5~1jrJYbtbN#oZWgj zC(^`?_hfYCNztcrB%|@MV6F~rYCBHIRwl78v%>_CLKdsD`y*1r-lqYtL)u8?&Jd*BI`*5w+&g)2Mr1 zQwBN33fha_pTCI(1QyE5e3>%uWh_U{St-Z3#E$f*Nm~_FFy%$*Fb*|Qha(!j&P<{f zYGpg(FUT<4kc8%{Dt}dnMVz@%Ws=J6jkJ%>(WSOu=oa0eAKENe+K|wKuliT#=Laaf zSNUKEmEW!_dZ7Tzy6Mg=BXU`>2}O*9>Fl zkrSlkkMCu^2An=Ve0NGD(DZ zlds8r9A{C?QKhBqry@gi&xRKV~*-qtm>S^80I(9lbM-@NRQTfmH zRCaeemEPS(tMAs*@>`o|?ys-WdUm>+MVrZ?F_bKP`J}3jj*xF6TGLvpSkDpqioSms z+muDgM{;RT+v$f>4&^?aekz})AJ3<(qjMj=L$8Zd$#9VwnL8g_0OUIqnLFRHllNz(ew;*^ zt)X?vkK0JRSV{;4sjf985j)ecJ#);Tjenkg(@EMc^1W!>nS5G%bI(J$ukmY4B#|DP zo@e~?$XHC$HWIqvBb&0Jbf3-Nw|o#u^zrBaPtP-X7a4Xh_re_yjqI^cHo8x@I7Jt+ z-s=A|3$RD7dp=#BlW%onIeBB2lb6E{N1J$$a`G%c#FFUp9Q`p~5n5SJzD=H&m*XhI zALnB2?s<7xyLH`PO62nY{*BZ2m-G{-N)M@6E4RNR|C1{gc=M;HoSnl=OcZ`Fo|JT< z^t|IG*R&T~+-Enf5K|zd!2)<7#UoNJ&6B(3pDu+^zPp6GP zzD3hMTtsO{XE5Ya!l9|OnEBJRUy7;ktiGfnhNnUz93A!su?XGw6ux63O+T4W6ZfaK zg}xd>Ayq*XUL8W=RiPAC5lmx>e5mB-IvVkA6v?6_mkkH&foV;+annX)BGw>&7GaLC=!=Z|`HT3ikeZ1bI%H e?dscDURs`y?xg&9fPE?i_Q_CtZu+r28~1OQNSrVL literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ diff --git a/reactos/dll/win32/setupapi/res/icons/28.ico b/reactos/dll/win32/setupapi/res/icons/28.ico index 43521de70d69f3ed0af849f88f0cd7d6a5151e7d..52ffe9ec3ec4225f2e8682ea2aa9fe4de6bf5820 100644 GIT binary patch literal 13270 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 X`eiX`wl;8xJ&YnQ{lMzQxb*)4Q}kt1 literal 1078 zcmeH`!4ZHU32bY9gUd%-bnv_x`FFGb^lN4ir z=OC@Kl<6h7L!WaPvtt+{idj!YN|jQ`F4T5at5=ZYEe}6F{R4R5QMk_|Oz`q~p&rBV TI0~L_iAebhpZ9(9ox8^qxWUWJ diff --git a/reactos/dll/win32/setupapi/res/icons/501.ico b/reactos/dll/win32/setupapi/res/icons/501.ico index e187e8ccc04fdd96b955acc4da3728e4713508fe..c07cbb663dd197c7674fd444826a97ed080bde70 100644 GIT binary patch literal 13270 zcmeHN4^WiV7C*}ZyKMUpmRw|N6deE{V0q5BnH0G%=zZm)p` zs!vfm+G}77we5{?wAa82Pk_=GfJl-_Dj#5!A5E|MDCev$R zFf_o_sZFqOVI9nxwGZyU|8J0;{SG|&=sB*{}6I=T1kEz%$wH( z%a?xw%a)y@y7Q2qe*u;*y#QrpXW^M=E<;Jl4S4)maiY`o^zfjK>ZiynC_cp!C;O=u{6EZKXlB6J4T57$Lo{7F zrUHp6Y?#8w6rh-tJjYHkdXKRL_=hG9J)fc*^Z7jy%BglzYh5=?rzn-qXpWAKHk*xp z&N{b(C?U~K)A(-HBR8U%X|rdihKomPMwJ3Za=9R6R3&%IA;3BUvMBA_AV^_Fn$WTJ}{No;isgzE=w0b#bS93Vq&(D->{o}fjaUVYRK={ zM?TBnVdl&R@&R6gw6r}?TwF`Oz)tdEUW0q@eH}6~8X!0KACQ&xF05J81U^1T$j9ga znXHF=j&_KO`j~u*4`KTBk02r8D9LLlzvDRhL1!U8{tV2W+X0!GpAh%J;>A5sRCEdM zyYD9CL*gE!tl`0l#_&Zl7gi{%9V-VmUzX53R2 zi+m-+VU24aAFWQOGrI08Lr=pdF%&+!hg2QOxF7+e?Y}?~J%uQ6wBI3D1_cxO-(v7p zdV|5B552|G`)Q&ko3#|%-9mC9MSC2vjR5lvAqoI(d}1EppbIniOg&Z;Gwtr289PRy zIcSI-cFYl9Q`JzcJ^Y!KlvKl_MGa(|4w9|f3qe80$c~+cxVTobZzsu?9S4i$B-x_V zWQ%&pcD0kO>3|0w_?%+dBd~JiH&9yI2Twh99V#o^pr(e4UF{fiKO6$TVFZ5Oj(N)5 zEtg0r6beRWBbTaFDmv_QlDAkab~PY;h0@R6!1+7d{&otCDaYnvu5>96P?>pl8+Jd} z)YvEXEVJ?c$|RL0@g$Oj;T`?gR35n!AfXK)rxzgeJis(MP!$y`6p5}M1M33{2q;hi zWOXlG_)n~??86;9$XZqpVtIKF8Vt4c)=VErBt|-!W}kwBR?vrC*jrI?35$yQFfZ>C z=H_0c>qWX=!qU>~n3;Ki#$Y@mlO^8;9CEi56m+1)@;^*WJcmh1?rgD~!~Fa!sMGDD zG58d-jetNgPT#QY{#suPSPLC9I&%Setw$+Vq*4^+)uHwv6Hs2 zu_-?OFvi7wP3^MJOCenh2Na9@F)ZvF>A8t! zvkgrqD@H`zz@VT3^zpfYTJ5`}KbrOjc1a}qlU69)gcTJ?YaemlIz-B);1f@vy{@VX zX)RtR-SfNI)jT3iCaancP>GK|+K=zOhuGSR*wTVX`5Ri3?WDV~SD{!&d(_<{z5W#~ zK*<4sDq4eeC=mRa^p;-r_Fl3@uV3eGeDB^c?2;!>{tK;(-2r!54JV#MfJ1;ofJ1;o zfJ1;o;Qs~z3JFpvSLw)Uy5utt(-{N9&K##pZj?40Sy~op2oyLY9f#AWe^74KxE*`KgTJ!@h zS<-K-sIcLrNma<_hot^89ZS|07G9v3?MsT2zQCxcAvPM%U}51knny;@FOjcSKX=^U zzYDi-|IGTr3#Y7Gx1K^`Yi(_}H8}Vv>3b7BJxvpS9|psoivWk1kI_2J&ay_+jB54! z=3bQ%za|wP12FDccQW#{dl~!yR)-T;{N?ZvEadjh|8BVX8?=4e0|rj z5|1gBl?wpY6IM0!J~kZ}i5@9)=;y8+0vrMy0vrMpN5GzQcgx9B4rtK9OkSRt$=gpL zC(rb8&&zA<15F$Kw~jj=e(W58_&)-Kr`~B-wR-KLRjaPz#*K*d|8zRHO>G>n43Vg; zC?(}0%H_u>7jP8){7%r>=V|2e4C5L{Xy{*eEm+XO_z_MrnNE|voI`WDJ&8nBs}+iG z$WJ&)enTf+JJH|&EArKn36JrSMpJ*bwifL+d($RFsr0c!Mb literal 13270 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 UHNfCW<5>7a2%5*`q($F<0VU-ZaR2}S From 0bfcd778838d79fa322fb00525c4bf5dbe413ce4 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 5 Oct 2006 01:44:54 +0000 Subject: [PATCH 471/488] - Implement ExpInitNls to initialize the NLS Section using the new semantics recently implemented. Works pretty much like the previous code in rtl/nls.c except it uses the new variable names as well as maps a view of the NLS Table into the system process.c - Delete rtl/nls.c and all the associated deprecated code. - Do MmInit1 and SharedUserData stuff *after* initializing the initial thread, to avoid an ASSERT during bootup. svn path=/trunk/; revision=24408 --- reactos/ntoskrnl/ex/init.c | 99 ++++++++++++- reactos/ntoskrnl/include/internal/ex.h | 3 + reactos/ntoskrnl/include/internal/rtl.h | 42 ------ reactos/ntoskrnl/ke/i386/kiinit.c | 38 ++--- reactos/ntoskrnl/mm/process.c | 8 +- reactos/ntoskrnl/ntoskrnl.rbuild | 1 - reactos/ntoskrnl/rtl/libsupp.c | 3 - reactos/ntoskrnl/rtl/nls.c | 178 ------------------------ 8 files changed, 123 insertions(+), 249 deletions(-) delete mode 100644 reactos/ntoskrnl/rtl/nls.c diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 07b4d779be9..9152bedf7ef 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -45,9 +45,104 @@ ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset; ULONG ExpUnicodeCaseTableDataOffset; NLSTABLEINFO ExpNlsTableInfo; ULONG ExpNlsTableSize; +PVOID ExpNlsSectionPointer; /* FUNCTIONS ****************************************************************/ +VOID +NTAPI +ExpInitNls(VOID) +{ + LARGE_INTEGER SectionSize; + NTSTATUS Status; + HANDLE NlsSection; + PVOID SectionBase = NULL; + ULONG ViewSize = 0; + LARGE_INTEGER SectionOffset = {{0}}; + + /* Set the section size */ + SectionSize.QuadPart = ExpNlsTableSize; + + /* Create the NLS Section */ + Status = ZwCreateSection(&NlsSection, + SECTION_ALL_ACCESS, + NULL, + &SectionSize, + PAGE_READWRITE, + SEC_COMMIT, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 1, 0, 0); + } + + /* Get a pointer to the section */ + Status = ObReferenceObjectByHandle(NlsSection, + SECTION_ALL_ACCESS, + MmSectionObjectType, + KernelMode, + &ExpNlsSectionPointer, + NULL); + ZwClose(NlsSection); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 2, 0, 0); + } + + /* Map the NLS Section in system space */ + Status = MmMapViewInSystemSpace(ExpNlsSectionPointer, + &SectionBase, + &ExpNlsTableSize); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 3, 0, 0); + } + + /* Copy the codepage data in its new location. */ + RtlMoveMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize); + + /* Free the previously allocated buffer and set the new location */ + ExFreePool(ExpNlsTableBase); + ExpNlsTableBase = SectionBase; + + /* Initialize the NLS Tables */ + RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + + ExpAnsiCodePageDataOffset), + (PVOID)((ULONG_PTR)ExpNlsTableBase + + ExpOemCodePageDataOffset), + (PVOID)((ULONG_PTR)ExpNlsTableBase + + ExpUnicodeCaseTableDataOffset), + &ExpNlsTableInfo); + RtlResetRtlTranslations(&ExpNlsTableInfo); + + /* Reset the base to 0 */ + SectionBase = NULL; + + /* Map the section in the system process */ + Status = MmMapViewOfSection(ExpNlsSectionPointer, + PsGetCurrentProcess(), + &SectionBase, + 0L, + 0L, + &SectionOffset, + &ViewSize, + ViewShare, + 0L, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 5, 0, 0); + } + + /* Copy the table into the system process and set this as the base */ + RtlMoveMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize); + ExpNlsTableBase = SectionBase; +} + static VOID INIT_FUNCTION @@ -781,8 +876,8 @@ ExPhase2Init(PVOID Context) /* Call KD Providers at Phase 2 */ KdInitSystem(2, KeLoaderBlock); - /* Import and create NLS Data and Sections */ - RtlpInitNls(); + /* Create NLS section */ + ExpInitNls(); /* Import and Load Registry Hives */ CmInitHives(ExpInTextModeSetup); diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index caa6aab5659..a68f552fbb9 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -14,6 +14,9 @@ extern ULONG NtMinorVersion; extern FAST_MUTEX ExpEnvironmentLock; extern ERESOURCE ExpFirmwareTableResource; extern LIST_ENTRY ExpFirmwareTableProviderListHead; +ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset; +ULONG ExpUnicodeCaseTableDataOffset; +PVOID ExpNlsSectionPointer; #define MAX_FAST_REFS 7 diff --git a/reactos/ntoskrnl/include/internal/rtl.h b/reactos/ntoskrnl/include/internal/rtl.h index 7aa46a163db..45c506a58e9 100644 --- a/reactos/ntoskrnl/include/internal/rtl.h +++ b/reactos/ntoskrnl/include/internal/rtl.h @@ -1,48 +1,6 @@ #ifndef __NTOSKRNL_INCLUDE_INTERNAL_NLS_H #define __NTOSKRNL_INCLUDE_INTERNAL_NLS_H -extern PVOID NlsSectionObject; - -extern ULONG NlsAnsiTableOffset; -extern ULONG NlsOemTableOffset; -extern ULONG NlsUnicodeTableOffset; - -extern PUSHORT NlsUnicodeUpcaseTable; -extern PUSHORT NlsUnicodeLowercaseTable; - -VOID -NTAPI -RtlpInitNls(VOID); - -VOID -NTAPI -RtlpImportAnsiCodePage( - PUSHORT TableBase, - ULONG Size -); - -VOID -NTAPI -RtlpImportOemCodePage( - PUSHORT TableBase, - ULONG Size -); - -VOID -NTAPI -RtlpImportUnicodeCasemap( - PUSHORT TableBase, - ULONG Size -); - -VOID -NTAPI -RtlpCreateInitialNlsTables(VOID); - -VOID -NTAPI -RtlpCreateNlsSection(VOID); - NTSTATUS NTAPI RtlQueryAtomListInAtomTable( diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index 74d21b6500d..e9a831bad12 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -407,6 +407,25 @@ KiInitializeKernel(IN PKPROCESS InitProcess, DPRINT1("SMP Boot support not yet present\n"); } + /* Setup the Idle Thread */ + KeInitializeThread(InitProcess, + InitThread, + NULL, + NULL, + NULL, + NULL, + NULL, + IdleStack); + InitThread->NextProcessor = Number; + InitThread->Priority = HIGH_PRIORITY; + InitThread->State = Running; + InitThread->Affinity = 1 << Number; + InitThread->WaitIrql = DISPATCH_LEVEL; + InitProcess->ActiveProcessors = 1 << Number; + + /* HACK for MmUpdatePageDir */ + ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess; + /* Initialize Kernel Memory Address Space */ MmInit1(FirstKrnlPhysAddr, LastKrnlPhysAddr, @@ -435,25 +454,6 @@ KiInitializeKernel(IN PKPROCESS InitProcess, SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = (KeFeatureBits & KF_RDTSC); - /* Setup the Idle Thread */ - KeInitializeThread(InitProcess, - InitThread, - NULL, - NULL, - NULL, - NULL, - NULL, - IdleStack); - InitThread->NextProcessor = Number; - InitThread->Priority = HIGH_PRIORITY; - InitThread->State = Running; - InitThread->Affinity = 1 << Number; - InitThread->WaitIrql = DISPATCH_LEVEL; - InitProcess->ActiveProcessors = 1 << Number; - - /* HACK for MmUpdatePageDir */ - ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess; - /* Set up the thread-related fields in the PRCB */ Prcb->CurrentThread = InitThread; Prcb->NextThread = NULL; diff --git a/reactos/ntoskrnl/mm/process.c b/reactos/ntoskrnl/mm/process.c index 5be30d7e250..9d5d783e307 100644 --- a/reactos/ntoskrnl/mm/process.c +++ b/reactos/ntoskrnl/mm/process.c @@ -291,7 +291,7 @@ MmCreatePeb(PEPROCESS Process) /* Map NLS Tables */ DPRINT("Mapping NLS\n"); - Status = MmMapViewOfSection(NlsSectionObject, + Status = MmMapViewOfSection(ExpNlsSectionPointer, (PEPROCESS)Process, &TableBase, 0, @@ -322,9 +322,9 @@ MmCreatePeb(PEPROCESS Process) Peb->Mutant = NULL; /* NLS */ - Peb->AnsiCodePageData = (char*)TableBase + NlsAnsiTableOffset; - Peb->OemCodePageData = (char*)TableBase + NlsOemTableOffset; - Peb->UnicodeCaseTableData = (char*)TableBase + NlsUnicodeTableOffset; + Peb->AnsiCodePageData = (PCHAR)TableBase + ExpAnsiCodePageDataOffset; + Peb->OemCodePageData = (PCHAR)TableBase + ExpOemCodePageDataOffset; + Peb->UnicodeCaseTableData = (PCHAR)TableBase + ExpUnicodeCaseTableDataOffset; /* Default Version Data (could get changed below) */ Peb->OSMajorVersion = NtMajorVersion; diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index f8ca060552e..544277c8a3a 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -315,7 +315,6 @@ libsupp.c misc.c - nls.c regio.c strtok.c diff --git a/reactos/ntoskrnl/rtl/libsupp.c b/reactos/ntoskrnl/rtl/libsupp.c index 6caf3670670..fafe20bf6e8 100644 --- a/reactos/ntoskrnl/rtl/libsupp.c +++ b/reactos/ntoskrnl/rtl/libsupp.c @@ -198,9 +198,6 @@ RtlpCaptureStackLimits(IN ULONG_PTR Ebp, /* FIXME: Super native implementation */ - /* FIXME: ROS HACK */ - if (!Thread) return FALSE; - /* Start with defaults */ *StackBegin = Thread->StackLimit; *StackEnd = (ULONG_PTR)Thread->StackBase; diff --git a/reactos/ntoskrnl/rtl/nls.c b/reactos/ntoskrnl/rtl/nls.c deleted file mode 100644 index 2f984c256bb..00000000000 --- a/reactos/ntoskrnl/rtl/nls.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/rtl/nls.c - * PURPOSE: Bitmap functions - * - * PROGRAMMERS: Eric Kohl - */ - -#include -#define NDEBUG -#include - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, RtlpInitNls) -#pragma alloc_text(INIT, RtlpImportAnsiCodePage) -#pragma alloc_text(INIT, RtlpImportOemCodePage) -#pragma alloc_text(INIT, RtlpImportUnicodeCasemap) -#pragma alloc_text(INIT, RtlpCreateInitialNlsTables) -#pragma alloc_text(INIT, RtlpCreateNlsSection) -#endif - - -/* GLOBALS *******************************************************************/ - - -static PUSHORT NlsAnsiCodePageTable = NULL; -static ULONG NlsAnsiCodePageTableSize = 0; - -static PUSHORT NlsOemCodePageTable = NULL; -static ULONG NlsOemCodePageTableSize = 0; - -static PUSHORT NlsUnicodeCasemapTable = NULL; -static ULONG NlsUnicodeCasemapTableSize = 0; - -PVOID NlsSectionObject = NULL; -static PVOID NlsSectionBase = NULL; -static ULONG NlsSectionViewSize = 0; - -ULONG NlsAnsiTableOffset = 0; -ULONG NlsOemTableOffset = 0; -ULONG NlsUnicodeTableOffset = 0; - - -/* FUNCTIONS *****************************************************************/ - -VOID -INIT_FUNCTION -STDCALL -RtlpInitNls(VOID) -{ - ULONG_PTR BaseAddress; - - /* Import NLS Data */ - BaseAddress = CachedModules[AnsiCodepage]->ModStart; - RtlpImportAnsiCodePage((PUSHORT)BaseAddress, - CachedModules[AnsiCodepage]->ModEnd - BaseAddress); - - BaseAddress = CachedModules[OemCodepage]->ModStart; - RtlpImportOemCodePage((PUSHORT)BaseAddress, - CachedModules[OemCodepage]->ModEnd - BaseAddress); - - BaseAddress = CachedModules[UnicodeCasemap]->ModStart; - RtlpImportUnicodeCasemap((PUSHORT)BaseAddress, - CachedModules[UnicodeCasemap]->ModEnd - BaseAddress); - - /* Create the NLS section */ - RtlpCreateNlsSection(); -} - -VOID -INIT_FUNCTION -NTAPI -RtlpImportAnsiCodePage(PUSHORT TableBase, - ULONG Size) -{ - NlsAnsiCodePageTable = TableBase; - NlsAnsiCodePageTableSize = Size; -} - - -VOID -INIT_FUNCTION -NTAPI -RtlpImportOemCodePage(PUSHORT TableBase, - ULONG Size) -{ - NlsOemCodePageTable = TableBase; - NlsOemCodePageTableSize = Size; -} - - -VOID -NTAPI -INIT_FUNCTION -RtlpImportUnicodeCasemap(PUSHORT TableBase, - ULONG Size) -{ - NlsUnicodeCasemapTable = TableBase; - NlsUnicodeCasemapTableSize = Size; -} - -VOID -NTAPI -INIT_FUNCTION -RtlpCreateNlsSection(VOID) -{ - NLSTABLEINFO NlsTable; - LARGE_INTEGER SectionSize; - NTSTATUS Status; - - DPRINT("RtlpCreateNlsSection() called\n"); - - NlsSectionViewSize = ROUND_UP(NlsAnsiCodePageTableSize, PAGE_SIZE) + - ROUND_UP(NlsOemCodePageTableSize, PAGE_SIZE) + - ROUND_UP(NlsUnicodeCasemapTableSize, PAGE_SIZE); - - DPRINT("NlsSectionViewSize %lx\n", NlsSectionViewSize); - - SectionSize.QuadPart = (LONGLONG)NlsSectionViewSize; - Status = MmCreateSection(&NlsSectionObject, - SECTION_ALL_ACCESS, - NULL, - &SectionSize, - PAGE_READWRITE, - SEC_COMMIT, - NULL, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmCreateSection() failed\n"); - KEBUGCHECKEX(0x32, Status, 1, 1, 0); - } - Status = ObInsertObject(NlsSectionObject, - NULL, - SECTION_ALL_ACCESS, - 0, - NULL, - NULL); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(NlsSectionObject); - } - Status = MmMapViewInSystemSpace(NlsSectionObject, - &NlsSectionBase, - &NlsSectionViewSize); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmMapViewInSystemSpace() failed\n"); - KEBUGCHECKEX(0x32, Status, 1, 3, 0); - } - - DPRINT("NlsSection: Base %p Size %lx\n", - NlsSectionBase, - NlsSectionViewSize); - - NlsAnsiTableOffset = 0; - RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset), - NlsAnsiCodePageTable, - NlsAnsiCodePageTableSize); - - NlsOemTableOffset = NlsAnsiTableOffset + ROUND_UP(NlsAnsiCodePageTableSize, PAGE_SIZE); - RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset), - NlsOemCodePageTable, - NlsOemCodePageTableSize); - - NlsUnicodeTableOffset = NlsOemTableOffset + ROUND_UP(NlsOemCodePageTableSize, PAGE_SIZE); - RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset), - NlsUnicodeCasemapTable, - NlsUnicodeCasemapTableSize); - - RtlInitNlsTables ((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset), - (PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset), - (PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset), - &NlsTable); - - RtlResetRtlTranslations (&NlsTable); -} From 5162751ab38db1a35eb93cb04ba9c989ad2370e2 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 5 Oct 2006 02:02:27 +0000 Subject: [PATCH 472/488] - Use KeLoaderBlock for registry hive loading. - Get rid of the CACHED_MODULE array and associated structures and stop using them, get rid of ParseAndCacheLoadedModules. Stop using KeLoadedModules and KeLoadedModuleCount outside of freeldr.c. - Except for MmInit1, the kernel should now be totally isolated from FreeLDR-specific data. svn path=/trunk/; revision=24409 --- reactos/ntoskrnl/KrnlFun.c | 3 +- reactos/ntoskrnl/cm/registry.c | 42 ++++++++++++++++--- reactos/ntoskrnl/ex/init.c | 56 +------------------------- reactos/ntoskrnl/include/internal/ke.h | 13 +----- reactos/ntoskrnl/ke/freeldr.c | 5 --- 5 files changed, 40 insertions(+), 79 deletions(-) diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index 932c2d090ad..66824c1c978 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -27,10 +27,9 @@ // Ke: // // - FIXES: -// * Stop using CachedModules. -// * Try to make MmInit1 NTLDR compatible. // * Sanitize some context fields during conversions. // * Figure out why the DPC stack doesn't really work. +// * Try to make MmInit1 NTLDR compatible. // * Add DR macro/save and VM macro/save. // - FEATURES: // * New optimized table-based tick-hashed timer implementation. diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 08a9d10c21e..2546cdc4520 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -136,18 +136,48 @@ STDCALL CmInitHives(BOOLEAN SetupBoot) { PCHAR BaseAddress; + PLIST_ENTRY ListHead, NextEntry; + PMEMORY_ALLOCATION_DESCRIPTOR MdBlock = NULL; /* Load Registry Hives. This one can be missing. */ - if (CachedModules[SystemRegistry]) { - BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart; + BaseAddress = KeLoaderBlock->RegistryBase; + if (BaseAddress) + { CmImportSystemHive(BaseAddress, - CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress); + KeLoaderBlock->RegistryLength); } - BaseAddress = (PCHAR)CachedModules[HardwareRegistry]->ModStart; - CmImportHardwareHive(BaseAddress, - CachedModules[HardwareRegistry]->ModEnd - (ULONG_PTR)BaseAddress); + /* Loop the memory descriptors */ + ListHead = &KeLoaderBlock->MemoryDescriptorListHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the current block */ + MdBlock = CONTAINING_RECORD(NextEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + /* Check if this is an registry block */ + if (MdBlock->MemoryType == LoaderRegistryData) + { + /* Check if it's not the SYSTEM hive that we already initialized */ + if ((MdBlock->BasePage) != ((ULONG_PTR)BaseAddress >> PAGE_SHIFT)) + { + /* Hardware hive break out */ + break; + } + } + + /* Go to the next block */ + NextEntry = MdBlock->ListEntry.Flink; + } + + /* We need a hardware hive */ + ASSERT(MdBlock); + + BaseAddress = (PCHAR)(MdBlock->BasePage << PAGE_SHIFT); + CmImportHardwareHive(BaseAddress, + MdBlock->PageCount << PAGE_SHIFT); /* Create dummy keys if no hardware hive was found */ CmImportHardwareHive (NULL, 0); diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 9152bedf7ef..4d676024763 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -25,17 +25,14 @@ ULONG NtBuildNumber = KERNEL_VERSION_BUILD; ULONG NtGlobalFlag; ULONG ExSuiteMask; -extern LOADER_MODULE KeLoaderModules[64]; -extern ULONG KeLoaderModuleCount; -extern ULONG KiServiceLimit; -BOOLEAN NoGuiBoot = FALSE; - /* Init flags and settings */ ULONG ExpInitializationPhase; BOOLEAN ExpInTextModeSetup; BOOLEAN IoRemoteBootClient; ULONG InitSafeBootMode; +BOOLEAN NoGuiBoot = FALSE; + /* NT Boot Path */ UNICODE_STRING NtSystemRoot; @@ -294,52 +291,6 @@ InitSystemSharedUserPage (IN PLOADER_PARAMETER_BLOCK LoaderBlock) } } -VOID -FORCEINLINE -ParseAndCacheLoadedModules(VOID) -{ - ULONG i; - PCHAR Name; - - /* Loop the Module List and get the modules we want */ - for (i = 1; i < KeLoaderModuleCount; i++) - { - /* Get the Name of this Module */ - if (!(Name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'))) - { - /* Save the name */ - Name = (PCHAR)KeLoaderModules[i].String; - } - else - { - /* No name, skip */ - Name++; - } - - /* Now check for any of the modules we will need later */ - if (!_stricmp(Name, "ansi.nls")) - { - CachedModules[AnsiCodepage] = &KeLoaderModules[i]; - } - else if (!_stricmp(Name, "oem.nls")) - { - CachedModules[OemCodepage] = &KeLoaderModules[i]; - } - else if (!_stricmp(Name, "casemap.nls")) - { - CachedModules[UnicodeCasemap] = &KeLoaderModules[i]; - } - else if (!_stricmp(Name, "system") || !_stricmp(Name, "system.hiv")) - { - CachedModules[SystemRegistry] = &KeLoaderModules[i]; - } - else if (!_stricmp(Name, "hardware") || !_stricmp(Name, "hardware.hiv")) - { - CachedModules[HardwareRegistry] = &KeLoaderModules[i]; - } - } -} - VOID INIT_FUNCTION ExpDisplayNotice(VOID) @@ -577,9 +528,6 @@ ExpInitializeExecutive(IN ULONG Cpu, PLIST_ENTRY NextEntry, ListHead; PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; - /* FIXME: Deprecate soon */ - ParseAndCacheLoadedModules(); - /* Validate Loader */ if (!ExpIsLoaderValid(LoaderBlock)) { diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 24e515666ac..0d56a9a61c2 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -18,18 +18,6 @@ typedef struct _KPROFILE_SOURCE_OBJECT LIST_ENTRY ListEntry; } KPROFILE_SOURCE_OBJECT, *PKPROFILE_SOURCE_OBJECT; -/* Cached modules from the loader block */ -typedef enum _CACHED_MODULE_TYPE -{ - AnsiCodepage, - OemCodepage, - UnicodeCasemap, - SystemRegistry, - HardwareRegistry, - MaximumCachedModuleType, -} CACHED_MODULE_TYPE, *PCACHED_MODULE_TYPE; -extern PLOADER_MODULE CachedModules[MaximumCachedModuleType]; - typedef enum _CONNECT_TYPE { NoConnect, @@ -122,6 +110,7 @@ extern BOOLEAN KeThreadDpcEnable; extern LARGE_INTEGER KiTimeIncrementReciprocal; extern UCHAR KiTimeIncrementShiftCount; extern ULONG KiTimeLimitIsrMicroseconds; +extern ULONG KiServiceLimit; extern LIST_ENTRY BugcheckCallbackListHead, BugcheckReasonCallbackListHead; extern KSPIN_LOCK BugCheckCallbackLock; extern KDPC KiExpireTimerDpc; diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index a7dadda2473..76f9a77783f 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -18,7 +18,6 @@ LOADER_MODULE KeLoaderModules[64]; ULONG KeLoaderModuleCount; static CHAR KeLoaderModuleStrings[64][256]; -PLOADER_MODULE CachedModules[MaximumCachedModuleType]; /* FreeLDR Memory Data */ ADDRESS_RANGE KeMemoryMap[64]; @@ -171,10 +170,6 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, if (!(_stricmp(DriverName, "hardware")) || !(_stricmp(DriverName, "hardware.hiv"))) { - /* Save registry data */ - LoaderBlock->RegistryBase = ModStart; - LoaderBlock->RegistryLength = ModSize; - /* Create an MD for it */ MdEntry = &BldrMemoryDescriptors[i]; MdEntry->MemoryType = LoaderRegistryData; From 3727f8fc7d60a52cfe7f417df0c3e16bac139136 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 5 Oct 2006 09:15:44 +0000 Subject: [PATCH 473/488] - Add #ifdef DEBUG / #endif to fix compile. FreeLdr's debug macros needs some improvement in the future... svn path=/trunk/; revision=24410 --- reactos/boot/freeldr/freeldr/windows/wlmemory.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/boot/freeldr/freeldr/windows/wlmemory.c b/reactos/boot/freeldr/freeldr/windows/wlmemory.c index 1a814739b41..243c3a1b2ba 100644 --- a/reactos/boot/freeldr/freeldr/windows/wlmemory.c +++ b/reactos/boot/freeldr/freeldr/windows/wlmemory.c @@ -491,6 +491,7 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, DbgPrint((DPRINT_WINDOWS, "Memory Descriptor List prepared, printing PDE\n")); List_PaToVa(&LoaderBlock->MemoryDescriptorListHead); + #if DEBUG { ULONG *PDE_Addr=(ULONG *)PDE;//0xC0300000; int j; @@ -509,6 +510,7 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, DbgPrint((DPRINT_WINDOWS, "\n")); } } + #endif // Enable paging From 3f66fcf6051a20baf4afce8f4f030f2dd82a3aa6 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 5 Oct 2006 14:49:20 +0000 Subject: [PATCH 474/488] - Rewrite ExpLoadInitialProcess by inlining and simplifying what the call to RtlCreateProcsesParameters should do, and also create our own custom environment with the same arguments that NT's smss gets. - This optimizes booting as well as gets use the differnet SESSIONY_INITIALIZATION_FAILED, where Y is a number representing which step of the process parameter/envieonment creation failed. svn path=/trunk/; revision=24411 --- reactos/ntoskrnl/ex/init.c | 152 ++++++++++++++++++++++++++++--------- 1 file changed, 116 insertions(+), 36 deletions(-) diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 4d676024763..222cb1cf6ff 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -332,60 +332,140 @@ NTSTATUS ExpLoadInitialProcess(PHANDLE ProcessHandle, PHANDLE ThreadHandle) { - UNICODE_STRING CurrentDirectory; - UNICODE_STRING ImagePath = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\smss.exe"); + PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; NTSTATUS Status; - PRTL_USER_PROCESS_PARAMETERS Params=NULL; - RTL_USER_PROCESS_INFORMATION Info; + ULONG Size; + RTL_USER_PROCESS_INFORMATION ProcessInformation; + PWSTR p; + UNICODE_STRING NullString = RTL_CONSTANT_STRING(L""); + UNICODE_STRING SmssName, Environment, SystemDriveString; - RtlInitUnicodeString(&CurrentDirectory, - SharedUserData->NtSystemRoot); - - /* Create the Parameters */ - Status = RtlCreateProcessParameters(&Params, - &ImagePath, - NULL, - &CurrentDirectory, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - if(!NT_SUCCESS(Status)) + /* Allocate memory for the process parameters */ + Size = sizeof(RTL_USER_PROCESS_PARAMETERS) + + ((MAX_PATH * 4) * sizeof(WCHAR)); + Status = ZwAllocateVirtualMemory(NtCurrentProcess(), + (PVOID)&ProcessParameters, + 0, + &Size, + MEM_COMMIT, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to create ppb!\n"); - return Status; + /* Failed */ + KeBugCheckEx(SESSION1_INITIALIZATION_FAILED, Status, 0, 0, 0); } - DPRINT("Creating process\n"); - Status = RtlCreateUserProcess(&ImagePath, + /* Setup the basic header, and give the process the low 1MB to itself */ + ProcessParameters->Length = Size; + ProcessParameters->MaximumLength = Size; + ProcessParameters->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED | + RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB; + + /* Allocate a page for the environment */ + Size = PAGE_SIZE; + Status = ZwAllocateVirtualMemory(NtCurrentProcess(), + (PVOID)&ProcessParameters->Environment, + 0, + &Size, + MEM_COMMIT, + PAGE_READWRITE + ); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0); + } + + /* Make a buffer for the DOS path */ + p = (PWSTR)(ProcessParameters + 1); + ProcessParameters->CurrentDirectory.DosPath.Buffer = p; + ProcessParameters-> + CurrentDirectory.DosPath.MaximumLength = MAX_PATH * sizeof(WCHAR); + + /* Copy the DOS path */ + RtlCopyUnicodeString(&ProcessParameters->CurrentDirectory.DosPath, + &NtSystemRoot); + + /* Make a buffer for the DLL Path */ + p = (PWSTR)((PCHAR)ProcessParameters->CurrentDirectory.DosPath.Buffer + + ProcessParameters->CurrentDirectory.DosPath.MaximumLength); + ProcessParameters->DllPath.Buffer = p; + ProcessParameters->DllPath.MaximumLength = MAX_PATH * sizeof(WCHAR); + + /* Copy the DLL path and append the system32 directory */ + RtlCopyUnicodeString(&ProcessParameters->DllPath, + &ProcessParameters->CurrentDirectory.DosPath); + RtlAppendUnicodeToString(&ProcessParameters->DllPath, L"\\System32"); + + /* Make a buffer for the image name */ + p = (PWSTR)((PCHAR)ProcessParameters->DllPath.Buffer + + ProcessParameters->DllPath.MaximumLength); + ProcessParameters->ImagePathName.Buffer = p; + ProcessParameters->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR); + + /* Append the system path and session manager name */ + RtlAppendUnicodeToString(&ProcessParameters->ImagePathName, + L"\\SystemRoot\\System32"); + RtlAppendUnicodeToString(&ProcessParameters->ImagePathName, + L"\\smss.exe"); + + /* Create the environment string */ + RtlInitEmptyUnicodeString(&Environment, + ProcessParameters->Environment, + Size); + + /* Append the DLL path to it */ + RtlAppendUnicodeToString(&Environment, L"Path=" ); + RtlAppendUnicodeStringToString(&Environment, &ProcessParameters->DllPath); + RtlAppendUnicodeStringToString(&Environment, &NullString ); + + /* Create the system drive string */ + SystemDriveString = NtSystemRoot; + SystemDriveString.Length = 2 * sizeof(WCHAR); + + /* Append it to the environment */ + RtlAppendUnicodeToString(&Environment, L"SystemDrive="); + RtlAppendUnicodeStringToString(&Environment, &SystemDriveString); + RtlAppendUnicodeStringToString(&Environment, &NullString); + + /* Append the system root to the environment */ + RtlAppendUnicodeToString(&Environment, L"SystemRoot="); + RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot); + RtlAppendUnicodeStringToString(&Environment, &NullString); + + /* Get and set the command line equal to the image path */ + ProcessParameters->CommandLine = ProcessParameters->ImagePathName; + SmssName = ProcessParameters->ImagePathName; + + /* Create SMSS process */ + Status = RtlCreateUserProcess(&SmssName, OBJ_CASE_INSENSITIVE, - Params, + RtlDeNormalizeProcessParams( + ProcessParameters), NULL, NULL, NULL, FALSE, NULL, NULL, - &Info); - - /* Close the handle and free the params */ - RtlDestroyProcessParameters(Params); - + &ProcessInformation); if (!NT_SUCCESS(Status)) { - DPRINT1("NtCreateProcess() failed (Status %lx)\n", Status); - return(Status); + /* Failed */ + KeBugCheckEx(SESSION3_INITIALIZATION_FAILED, Status, 0, 0, 0); } - /* Start it up */ - ZwResumeThread(Info.ThreadHandle, NULL); + /* Resume the thread */ + Status = ZwResumeThread(ProcessInformation.ThreadHandle, NULL); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0); + } /* Return Handles */ - *ProcessHandle = Info.ProcessHandle; - *ThreadHandle = Info.ThreadHandle; - DPRINT("Process created successfully\n"); + *ProcessHandle = ProcessInformation.ProcessHandle; + *ThreadHandle = ProcessInformation.ThreadHandle; return STATUS_SUCCESS; } From eb8c705ce9a467a7204a56acbe1590143687b2bd Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 5 Oct 2006 15:13:59 +0000 Subject: [PATCH 475/488] - Put all Phase 1 Ex* Initialization in ExpInitSystemPhase1 and clean up associated deprecated calls. - Call ExpInitializePushLocks since we weren't doing this before. svn path=/trunk/; revision=24412 --- reactos/ntoskrnl/ex/init.c | 68 ++++++++++++++++---------- reactos/ntoskrnl/include/internal/ex.h | 4 ++ 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 222cb1cf6ff..e6f546f5723 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -327,10 +327,10 @@ ExpDisplayNotice(VOID) } -INIT_FUNCTION NTSTATUS -ExpLoadInitialProcess(PHANDLE ProcessHandle, - PHANDLE ThreadHandle) +NTAPI +ExpLoadInitialProcess(IN PHANDLE ProcessHandle, + IN PHANDLE ThreadHandle) { PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; NTSTATUS Status; @@ -469,21 +469,6 @@ ExpLoadInitialProcess(PHANDLE ProcessHandle, return STATUS_SUCCESS; } -VOID -NTAPI -ExInit3(VOID) -{ - ExpInitializeEventImplementation(); - ExpInitializeEventPairImplementation(); - ExpInitializeMutantImplementation(); - ExpInitializeSemaphoreImplementation(); - ExpInitializeTimerImplementation(); - LpcpInitSystem(); - ExpInitializeProfileImplementation(); - ExpWin32kInit(); - ExpInitUuids(); -} - ULONG NTAPI ExComputeTickCountMultiplier(IN ULONG ClockIncrement) @@ -542,8 +527,37 @@ BOOLEAN NTAPI ExpInitSystemPhase1(VOID) { - /* Not yet done */ - return FALSE; + /* Initialize worker threads */ + ExpInitializeWorkerThreads(); + + /* Initialize pushlocks */ + ExpInitializePushLocks(); + + /* Initialize events and event pairs */ + ExpInitializeEventImplementation(); + ExpInitializeEventPairImplementation(); + + /* Initialize callbacks */ + ExpInitializeCallbacks(); + + /* Initialize mutants */ + ExpInitializeMutantImplementation(); + + /* Initialize semaphores */ + ExpInitializeSemaphoreImplementation(); + + /* Initialize timers */ + ExpInitializeTimerImplementation(); + + /* Initialize profiling */ + ExpInitializeProfileImplementation(); + + /* Initialize UUIDs */ + ExpInitUuids(); + + /* Initialize Win32K */ + ExpWin32kInit(); + return TRUE; } BOOLEAN @@ -847,6 +861,9 @@ ExPhase2Init(PVOID Context) HANDLE ThreadHandle; NTSTATUS Status; + /* Set to phase 1 */ + ExpInitializationPhase = 1; + /* Set us at maximum priority */ KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY); @@ -860,13 +877,7 @@ ExPhase2Init(PVOID Context) HalInitSystem(1, KeLoaderBlock); /* Initialize Basic System Objects and Worker Threads */ - ExInit3(); - - /* initialize the worker threads */ - ExpInitializeWorkerThreads(); - - /* initialize callbacks */ - ExpInitializeCallbacks(); + ExInitSystem(); /* Call KD Providers at Phase 1 */ KdInitSystem(1, KeLoaderBlock); @@ -907,6 +918,9 @@ ExPhase2Init(PVOID Context) /* Create NLS section */ ExpInitNls(); + /* Initialize LPC */ + LpcpInitSystem(); + /* Import and Load Registry Hives */ CmInitHives(ExpInTextModeSetup); diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index a68f552fbb9..d539acd9bb9 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -61,6 +61,10 @@ ExPhase2Init( IN PVOID Context ); +VOID +NTAPI +ExpInitializePushLocks(VOID); + VOID NTAPI ExpInitTimeZoneInfo(VOID); From 093d1a3aba5c25ad8c14f9228a54403c06bc5747 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 5 Oct 2006 16:14:28 +0000 Subject: [PATCH 476/488] - Get rid of the completely convoluted way that Phase 1 initialization was being ended, with umpteen events and waits and timeouts all synchronized from user-mode and do a simple 5-second wait to determine if smss started OK or not. - Promote the Phase 1 initialization thread by jumping directly into the zero-page thread, and remove manual zero-page thread initialization code since we simply jump into its main routine. - 100 less lines of code :) svn path=/trunk/; revision=24413 --- reactos/ntoskrnl/ex/init.c | 119 +++++-------------------- reactos/ntoskrnl/include/internal/mm.h | 4 +- reactos/ntoskrnl/mm/freelist.c | 53 +++-------- reactos/ntoskrnl/mm/mminit.c | 1 - 4 files changed, 34 insertions(+), 143 deletions(-) diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index e6f546f5723..d6d2fba7567 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -853,9 +853,6 @@ VOID NTAPI ExPhase2Init(PVOID Context) { - UNICODE_STRING EventName; - HANDLE InitDoneEventHandle; - OBJECT_ATTRIBUTES ObjectAttributes; LARGE_INTEGER Timeout; HANDLE ProcessHandle; HANDLE ThreadHandle; @@ -949,113 +946,37 @@ ExPhase2Init(PVOID Context) /* Initialize shared user page. Set dos system path, dos device map, etc. */ InitSystemSharedUserPage(KeLoaderBlock); - /* Create 'ReactOSInitDone' event */ - RtlInitUnicodeString(&EventName, L"\\ReactOSInitDone"); - InitializeObjectAttributes(&ObjectAttributes, - &EventName, - 0, - NULL, - NULL); - Status = ZwCreateEvent(&InitDoneEventHandle, - EVENT_ALL_ACCESS, - &ObjectAttributes, - SynchronizationEvent, - FALSE); - - /* Check for Success */ - if (!NT_SUCCESS(Status)) { - - DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status); - InitDoneEventHandle = INVALID_HANDLE_VALUE; - } - /* Launch initial process */ Status = ExpLoadInitialProcess(&ProcessHandle, &ThreadHandle); - /* Check for success, Bugcheck if we failed */ - if (!NT_SUCCESS(Status)) { - - KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0); + /* Wait 5 seconds for it to initialize */ + Timeout.QuadPart = Int32x32To64(5, -10000000); + Status = ZwWaitForSingleObject(ProcessHandle, FALSE, &Timeout); + if (Status == STATUS_SUCCESS) + { + /* Bugcheck the system if SMSS couldn't initialize */ + KeBugCheck(SESSION5_INITIALIZATION_FAILED); } - - /* Wait on the Completion Event */ - if (InitDoneEventHandle != INVALID_HANDLE_VALUE) { - - HANDLE Handles[2]; /* Init event, Initial process */ - - /* Setup the Handles to wait on */ - Handles[0] = InitDoneEventHandle; - Handles[1] = ProcessHandle; - - /* Wait for the system to be initialized */ - Timeout.QuadPart = (LONGLONG)-1200000000; /* 120 second timeout */ - Status = ZwWaitForMultipleObjects(2, - Handles, - WaitAny, - FALSE, - &Timeout); - if (!NT_SUCCESS(Status)) { - - DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status); - - } else if (Status == STATUS_TIMEOUT) { - - DPRINT1("WARNING: System not initialized after 120 seconds.\n"); - - } else if (Status == STATUS_WAIT_0 + 1) { - - /* Crash the system if the initial process was terminated. */ - KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0); - } + else + { + /* Close process handles */ + ZwClose(ThreadHandle); + ZwClose(ProcessHandle); /* - * FIXME: FILIP! - * Disable the Boot Logo - */ + * FIXME: FILIP! + * Disable the Boot Logo + */ if (!NoGuiBoot) InbvEnableBootDriver(FALSE); - /* Signal the Event and close the handle */ - ZwSetEvent(InitDoneEventHandle, NULL); - ZwClose(InitDoneEventHandle); + /* FIXME: We should free the initial process' memory!*/ - } else { + /* Increase init phase */ + ExpInitializationPhase += 1; - /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */ - if (!NoGuiBoot) InbvEnableBootDriver(FALSE); - - /* Crash the system if the initial process terminates within 5 seconds. */ - Timeout.QuadPart = (LONGLONG)-50000000; /* 5 second timeout */ - Status = ZwWaitForSingleObject(ProcessHandle, - FALSE, - &Timeout); - - /* Check for timeout, crash if the initial process didn't initalize */ - if (Status != STATUS_TIMEOUT) KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 1, 0, 0); - } - - /* Enable the Clock, close remaining handles */ - ZwClose(ThreadHandle); - ZwClose(ProcessHandle); - - DPRINT1("System initialization complete\n"); - { - /* FIXME: We should instead jump to zero-page thread */ - /* Free initial kernel memory */ - MiFreeInitMemory(); - - /* Set our priority to 0 */ - KeGetCurrentThread()->BasePriority = 0; - KeSetPriorityThread(KeGetCurrentThread(), 0); - - /* Wait ad-infinitum */ - for (;;) - { - LARGE_INTEGER Timeout; - Timeout.QuadPart = 0x7fffffffffffffffLL; - KeDelayExecutionThread(KernelMode, FALSE, &Timeout); - } + /* Jump into zero page thread */ + MmZeroPageThreadMain(NULL); } } - /* EOF */ diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index db296c65c8b..21d5fee28ca 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -974,7 +974,9 @@ MmGetContinuousPages( NTSTATUS NTAPI -MmInitZeroPageThread(VOID); +MmZeroPageThreadMain( + PVOID Context +); /* i386/page.c *********************************************************/ diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 1fd2ca996db..a5718ce15a2 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -17,7 +17,6 @@ #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, MmInitializePageList) -#pragma alloc_text(INIT, MmInitZeroPageThread) #endif @@ -62,8 +61,6 @@ static LIST_ENTRY FreeZeroedPageListHead; static LIST_ENTRY FreeUnzeroedPageListHead; static LIST_ENTRY BiosPageListHead; -static PETHREAD ZeroPageThread; -static CLIENT_ID ZeroPageThreadId; static KEVENT ZeroPageThreadEvent; static BOOLEAN ZeroPageThreadShouldTerminate = FALSE; @@ -1139,7 +1136,8 @@ MmAllocPagesSpecifyRange(ULONG Consumer, return NumberOfPagesFound; } -VOID STDCALL +NTSTATUS +NTAPI MmZeroPageThreadMain(PVOID Ignored) { NTSTATUS Status; @@ -1149,6 +1147,13 @@ MmZeroPageThreadMain(PVOID Ignored) PFN_TYPE Pfn; ULONG Count; + /* Free initial kernel memory */ + MiFreeInitMemory(); + + /* Set our priority to 0 */ + KeGetCurrentThread()->BasePriority = 0; + KeSetPriorityThread(KeGetCurrentThread(), 0); + while(1) { Status = KeWaitForSingleObject(&ZeroPageThreadEvent, @@ -1160,13 +1165,12 @@ MmZeroPageThreadMain(PVOID Ignored) { DbgPrint("ZeroPageThread: Wait failed\n"); KEBUGCHECK(0); - return; } if (ZeroPageThreadShouldTerminate) { DbgPrint("ZeroPageThread: Terminating\n"); - return; + return STATUS_SUCCESS; } Count = 0; KeAcquireSpinLock(&PageListLock, &oldIrql); @@ -1201,46 +1205,11 @@ MmZeroPageThreadMain(PVOID Ignored) } } - DPRINT("Zeroed %d pages.\n", Count); + DPRINT1("Zeroed %d pages.\n", Count); KeResetEvent(&ZeroPageThreadEvent); KeReleaseSpinLock(&PageListLock, oldIrql); } -} -NTSTATUS -INIT_FUNCTION -NTAPI -MmInitZeroPageThread(VOID) -{ - NTSTATUS Status; - HANDLE ThreadHandle; - - ZeroPageThreadShouldTerminate = FALSE; - Status = PsCreateSystemThread(&ThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &ZeroPageThreadId, - MmZeroPageThreadMain, - NULL); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_ALL_ACCESS, - PsThreadType, - KernelMode, - (PVOID*)&ZeroPageThread, - NULL); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - - KeSetPriorityThread(&ZeroPageThread->Tcb, LOW_PRIORITY); - NtClose(ThreadHandle); return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index a44a503fb67..43a4016b560 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -455,7 +455,6 @@ MmInit3(VOID) MmDeletePageTable(NULL, 0); #endif - MmInitZeroPageThread(); MmCreatePhysicalMemorySection(); MiInitBalancerThread(); From 88594636231afe383974bf4e95ceb3fa21d90149 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 5 Oct 2006 16:38:58 +0000 Subject: [PATCH 477/488] - Remove SMSS's code for signaling the "init" event. - Make ExpInitNls responsible for NLS initialization in Phase 0 as well, to clean up the code in ExpInitailizeExecutive a bit. - Initialize the system time/clock in Phase 1, not in Phase 0. - Do HAL Phase1 initialization as the first step in Phase 1 initialization, then initialize the system clock (since the HAL's RTC is now configured). - Do Ob Phase 1 init in Phase 1 initialization, not in phase 0. - Do Ke Phase 1 init after HAL, Ob and Ex phase 1 inits. - Initialize NLS for Phase 1 after Ke Phase 1, instead of much later. svn path=/trunk/; revision=24414 --- reactos/base/system/smss/init.c | 40 +------ reactos/ntoskrnl/ex/init.c | 138 +++++++++++++------------ reactos/ntoskrnl/include/internal/ke.h | 2 +- reactos/ntoskrnl/ke/krnlinit.c | 3 +- 4 files changed, 77 insertions(+), 106 deletions(-) diff --git a/reactos/base/system/smss/init.c b/reactos/base/system/smss/init.c index b7266c891c6..cb4ed0d3678 100644 --- a/reactos/base/system/smss/init.c +++ b/reactos/base/system/smss/init.c @@ -31,43 +31,6 @@ /* FUNCTIONS ****************************************************************/ -static NTSTATUS -SmpSignalInitEvent(VOID) -{ - NTSTATUS Status = STATUS_SUCCESS; - OBJECT_ATTRIBUTES ObjectAttributes = {0}; - UNICODE_STRING EventName ={0}; - HANDLE ReactOSInitEvent = (HANDLE) 0; - - RtlInitUnicodeString (& EventName, L"\\ReactOSInitDone"); - InitializeObjectAttributes(&ObjectAttributes, - & EventName, - 0, - 0, - NULL); - Status = NtOpenEvent(&ReactOSInitEvent, - EVENT_ALL_ACCESS, - &ObjectAttributes); - if (NT_SUCCESS(Status)) - { - LARGE_INTEGER Timeout; - /* This will cause the boot screen image to go away (if displayed) */ - NtPulseEvent(ReactOSInitEvent, NULL); - - /* Wait for the display mode to be changed (if in graphics mode) */ - Timeout.QuadPart = -50000000LL; /* 5 second timeout */ - NtWaitForSingleObject(ReactOSInitEvent, FALSE, &Timeout); - - NtClose(ReactOSInitEvent); - } - else - { - /* We don't really care if this fails */ - DPRINT1("SM: Failed to open ReactOS init notification event\n"); - } - return Status; -} - typedef NTSTATUS (* SM_INIT_ROUTINE)(VOID); struct { @@ -88,8 +51,7 @@ struct { {TRUE, SmInitializeRegistry, "initialize the registry"}, {FALSE, SmUpdateEnvironment, "update environment variables"}, {TRUE, SmInitializeClientManagement, "initialize client management"}, - {TRUE, SmLoadSubsystems, "load subsystems"}, - {FALSE, SmpSignalInitEvent, "open ReactOS init notification event"}, + {TRUE, SmLoadSubsystems, "load subsystems"} }; NTSTATUS diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index d6d2fba7567..8748c6d5167 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -48,7 +48,7 @@ PVOID ExpNlsSectionPointer; VOID NTAPI -ExpInitNls(VOID) +ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { LARGE_INTEGER SectionSize; NTSTATUS Status; @@ -56,6 +56,61 @@ ExpInitNls(VOID) PVOID SectionBase = NULL; ULONG ViewSize = 0; LARGE_INTEGER SectionOffset = {{0}}; + PLIST_ENTRY ListHead, NextEntry; + PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; + + /* Check if this is boot-time phase 0 initialization */ + if (!ExpInitializationPhase) + { + /* Loop the memory descriptors */ + ListHead = &LoaderBlock->MemoryDescriptorListHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the current block */ + MdBlock = CONTAINING_RECORD(NextEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + + /* Check if this is an NLS block */ + if (MdBlock->MemoryType == LoaderNlsData) + { + /* Increase the table size */ + ExpNlsTableSize += MdBlock->PageCount * PAGE_SIZE; + } + + /* Go to the next block */ + NextEntry = MdBlock->ListEntry.Flink; + } + + /* + * In NT, the memory blocks are contiguous, but in ReactOS they aren't, + * so unless someone fixes FreeLdr, we'll have to use this icky hack. + */ + ExpNlsTableSize += 2 * PAGE_SIZE; // BIAS FOR FREELDR. HACK! + + /* Allocate the a new buffer since loader memory will be freed */ + ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool, + ExpNlsTableSize, + TAG('R', 't', 'l', 'i')); + if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED); + + /* Copy the codepage data in its new location. */ + RtlMoveMemory(ExpNlsTableBase, + LoaderBlock->NlsData->AnsiCodePageData, + ExpNlsTableSize); + + /* Initialize and reset the NLS TAbles */ + RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + + ExpAnsiCodePageDataOffset), + (PVOID)((ULONG_PTR)ExpNlsTableBase + + ExpOemCodePageDataOffset), + (PVOID)((ULONG_PTR)ExpNlsTableBase + + ExpUnicodeCaseTableDataOffset), + &ExpNlsTableInfo); + RtlResetRtlTranslations(&ExpNlsTableInfo); + return; + } /* Set the section size */ SectionSize.QuadPart = ExpNlsTableSize; @@ -619,8 +674,6 @@ ExpInitializeExecutive(IN ULONG Cpu, CHAR Buffer[256]; ANSI_STRING AnsiPath; NTSTATUS Status; - PLIST_ENTRY NextEntry, ListHead; - PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; /* Validate Loader */ if (!ExpIsLoaderValid(LoaderBlock)) @@ -731,9 +784,6 @@ ExpInitializeExecutive(IN ULONG Cpu, /* Setup bugcheck messages */ KiInitializeBugCheck(); - /* Setup system time */ - KiInitializeSystemClock(); - /* Initialize the executive at phase 0 */ if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED); @@ -744,53 +794,8 @@ ExpInitializeExecutive(IN ULONG Cpu, SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress; SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart; - /* Loop the memory descriptors */ - ListHead = &LoaderBlock->MemoryDescriptorListHead; - NextEntry = ListHead->Flink; - while (NextEntry != ListHead) - { - /* Get the current block */ - MdBlock = CONTAINING_RECORD(NextEntry, - MEMORY_ALLOCATION_DESCRIPTOR, - ListEntry); - - /* Check if this is an NLS block */ - if (MdBlock->MemoryType == LoaderNlsData) - { - /* Increase the table size */ - ExpNlsTableSize += MdBlock->PageCount * PAGE_SIZE; - } - - /* Go to the next block */ - NextEntry = MdBlock->ListEntry.Flink; - } - - /* - * In NT, the memory blocks are contiguous, but in ReactOS they are not, - * so unless someone fixes FreeLdr, we'll have to use this icky hack. - */ - ExpNlsTableSize += 2 * PAGE_SIZE; // BIAS FOR FREELDR. HACK! - - /* Allocate the NLS buffer in the pool since loader memory will be freed */ - ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool, - ExpNlsTableSize, - TAG('R', 't', 'l', 'i')); - if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED); - - /* Copy the codepage data in its new location. */ - RtlMoveMemory(ExpNlsTableBase, - LoaderBlock->NlsData->AnsiCodePageData, - ExpNlsTableSize); - - /* Initialize and reset the NLS TAbles */ - RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + - ExpAnsiCodePageDataOffset), - (PVOID)((ULONG_PTR)ExpNlsTableBase + - ExpOemCodePageDataOffset), - (PVOID)((ULONG_PTR)ExpNlsTableBase + - ExpUnicodeCaseTableDataOffset), - &ExpNlsTableInfo); - RtlResetRtlTranslations(&ExpNlsTableInfo); + /* Make a copy of the NLS Tables */ + ExpInitNls(LoaderBlock); /* Initialize the Handle Table */ ExpInitializeHandleTables(); @@ -823,9 +828,6 @@ ExpInitializeExecutive(IN ULONG Cpu, /* Set up Region Maps, Sections and the Paging File */ MmInit2(); - /* Call OB initialization again */ - if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED); - /* Initialize the Process Manager */ if (!PsInitSystem()) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED); @@ -864,17 +866,26 @@ ExPhase2Init(PVOID Context) /* Set us at maximum priority */ KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY); - /* Initialize the later stages of the kernel */ - KeInitSystem(); + /* Do Phase 1 HAL Initialization */ + HalInitSystem(1, KeLoaderBlock); + + /* Setup system time */ + KiInitializeSystemClock(); /* Initialize all processors */ HalAllProcessorsStarted(); - /* Do Phase 1 HAL Initialization */ - HalInitSystem(1, KeLoaderBlock); + /* Call OB initialization again */ + if (!ObInit()) KEBUGCHECK(OBJECT1_INITIALIZATION_FAILED); /* Initialize Basic System Objects and Worker Threads */ - ExInitSystem(); + if (!ExInitSystem()) KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); + + /* Initialize the later stages of the kernel */ + if (!KeInitSystem()) KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); + + /* Create NLS section */ + ExpInitNls(KeLoaderBlock); /* Call KD Providers at Phase 1 */ KdInitSystem(1, KeLoaderBlock); @@ -888,7 +899,7 @@ ExPhase2Init(PVOID Context) /* Initialize the Registry (Hives are NOT yet loaded!) */ CmInitializeRegistry(); - /* Unmap Low memory, initialize the Page Zeroing and the Balancer Thread */ + /* Unmap Low memory, and initialize the MPW and Balancer Thread */ MmInit3(); /* Initialize Cache Views */ @@ -912,9 +923,6 @@ ExPhase2Init(PVOID Context) /* Call KD Providers at Phase 2 */ KdInitSystem(2, KeLoaderBlock); - /* Create NLS section */ - ExpInitNls(); - /* Initialize LPC */ LpcpInitSystem(); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 0d56a9a61c2..7412402e2e2 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -626,7 +626,7 @@ KiActivateWaiterQueue(IN PKQUEUE Queue); /* INITIALIZATION FUNCTIONS *************************************************/ -VOID +BOOLEAN NTAPI KeInitSystem(VOID); diff --git a/reactos/ntoskrnl/ke/krnlinit.c b/reactos/ntoskrnl/ke/krnlinit.c index 236613ba43c..aa5b05b4b3a 100644 --- a/reactos/ntoskrnl/ke/krnlinit.c +++ b/reactos/ntoskrnl/ke/krnlinit.c @@ -273,7 +273,7 @@ KiInitSpinLocks(IN PKPRCB Prcb, } } -VOID +BOOLEAN NTAPI KeInitSystem(VOID) { @@ -286,5 +286,6 @@ KeInitSystem(VOID) /* Initialize non-portable parts of the kernel */ KiInitMachineDependent(); + return TRUE; } From 45d84c966862b59f10f15a43aba8a4e6c069a0e4 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 5 Oct 2006 23:01:38 +0000 Subject: [PATCH 478/488] - Guard some current cmlib includes against new cm branch - Remove NTSYSAPI from NtBuildNumber definition in NDK. svn path=/trunk/; revision=24416 --- reactos/include/ndk/extypes.h | 2 +- reactos/lib/cmlib/cmdata.h | 4 ++++ reactos/lib/cmlib/cmlib.h | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/reactos/include/ndk/extypes.h b/reactos/include/ndk/extypes.h index 30437447db8..302a44d5855 100644 --- a/reactos/include/ndk/extypes.h +++ b/reactos/include/ndk/extypes.h @@ -63,7 +63,7 @@ extern POBJECT_TYPE NTSYSAPI ExTimerType; // // Exported NT Build Number // -extern ULONG NTSYSAPI NtBuildNumber; +extern ULONG NtBuildNumber; // // Invalid Handle Value Constant diff --git a/reactos/lib/cmlib/cmdata.h b/reactos/lib/cmlib/cmdata.h index 04b949f2304..d0266ee01e5 100644 --- a/reactos/lib/cmlib/cmdata.h +++ b/reactos/lib/cmlib/cmdata.h @@ -18,6 +18,8 @@ #define REG_VALUE_CELL_ID 0x6b76 #define REG_SECURITY_CELL_ID 0x6b73 +#ifndef _CM_ + #include typedef struct _CM_VIEW_OF_FILE @@ -147,4 +149,6 @@ typedef struct _CM_KEY_SECURITY #include +#endif + #endif /* CMLIB_CMDATA_H */ diff --git a/reactos/lib/cmlib/cmlib.h b/reactos/lib/cmlib/cmlib.h index ab699d63906..91a2229a198 100644 --- a/reactos/lib/cmlib/cmlib.h +++ b/reactos/lib/cmlib/cmlib.h @@ -64,7 +64,7 @@ typedef struct _HMAP_ENTRY { ULONG_PTR Bin; ULONG_PTR Block; - PCM_VIEW_OF_FILE CmHive; + struct _CM_VIEW_OF_FILE *CmHive; ULONG MemAlloc; } HMAP_ENTRY, *PHMAP_ENTRY; @@ -118,6 +118,7 @@ typedef struct _HHIVE DUAL Storage[HvMaxStorageType]; } HHIVE, *PHHIVE; +#ifndef _CM_ typedef struct _EREGISTRY_HIVE { HHIVE Hive; @@ -129,6 +130,7 @@ typedef struct _EREGISTRY_HIVE HANDLE HiveHandle; HANDLE LogHandle; } EREGISTRY_HIVE, *PEREGISTRY_HIVE; +#endif /* * Public functions. From a4c366b659d787f8cbf7c8e1f25dc75534e192b3 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Fri, 6 Oct 2006 06:36:35 +0000 Subject: [PATCH 479/488] - Add internal EX_CALLBACK Object to NDK. (Callback blocks are a new NT 5.2 kernel mechanism much like RunOncs blocks in Vista user-mode). They're managed by rundown protection and fast-referencing through interlocked calls to push/pop/sychrnonize system callbacks. - Add ObOpenObjectByName to NDK, since this API is not documented in official headers. svn path=/trunk/; revision=24422 --- reactos/include/ndk/extypes.h | 18 ++++++++++++++++++ reactos/include/ndk/obfuncs.h | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/reactos/include/ndk/extypes.h b/reactos/include/ndk/extypes.h index 302a44d5855..4ca7a30886d 100644 --- a/reactos/include/ndk/extypes.h +++ b/reactos/include/ndk/extypes.h @@ -485,6 +485,24 @@ typedef struct _CALLBACK_OBJECT ULONG AllowMultipleCallbacks; } CALLBACK_OBJECT , *PCALLBACK_OBJECT; +// +// Internal Callback Object +// +typedef struct _EX_CALLBACK_ROUTINE_BLOCK +{ + EX_RUNDOWN_REF RundownProtect; + PVOID Function; + PVOID Context; +} EX_CALLBACK_ROUTINE_BLOCK, *PEX_CALLBACK_ROUTINE_BLOCK; + +// +// Internal Callback Handle +// +typedef struct _EX_CALLBACK +{ + EX_FAST_REF RoutineBlock; +} EX_CALLBACK, *PEX_CALLBACK; + // // Profile Object // diff --git a/reactos/include/ndk/obfuncs.h b/reactos/include/ndk/obfuncs.h index ad54633e9c4..f8c4ad9ed8f 100644 --- a/reactos/include/ndk/obfuncs.h +++ b/reactos/include/ndk/obfuncs.h @@ -68,6 +68,18 @@ ObGetObjectPointerCount( IN PVOID Object ); +NTSTATUS +NTAPI +ObOpenObjectByName( + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN POBJECT_TYPE ObjectType, + IN KPROCESSOR_MODE AccessMode, + IN PACCESS_STATE PassedAccessState, + IN ACCESS_MASK DesiredAccess, + IN OUT PVOID ParseContext, + OUT PHANDLE Handle +); + NTKERNELAPI NTSTATUS NTAPI From 2380e7bb33805636bf06ded83ba131d4c98061d8 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 6 Oct 2006 16:08:54 +0000 Subject: [PATCH 480/488] implemented DeviceProperties_RunDLLW and DeviceProperties_RunDLLA svn path=/trunk/; revision=24424 --- reactos/dll/win32/devmgr/advprop.c | 155 ++++++++++++++++++++++++++++- reactos/dll/win32/devmgr/stubs.c | 74 +------------- 2 files changed, 154 insertions(+), 75 deletions(-) diff --git a/reactos/dll/win32/devmgr/advprop.c b/reactos/dll/win32/devmgr/advprop.c index f4b667d78ed..048a84b92d8 100644 --- a/reactos/dll/win32/devmgr/advprop.c +++ b/reactos/dll/win32/devmgr/advprop.c @@ -16,12 +16,13 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: hwpage.c 19599 2005-11-26 02:12:58Z weiden $ +/* * * PROJECT: ReactOS devmgr.dll * FILE: lib/devmgr/advprop.c * PURPOSE: ReactOS Device Manager * PROGRAMMER: Thomas Weidenmueller + * Ged Murphy * UPDATE HISTORY: * 04-04-2004 Created */ @@ -1742,7 +1743,7 @@ Cleanup: * 1: if bShowDevMgr is non-zero and no error occured * -1: a call to GetLastError returns 0 if successful * - * @unimplemented + * @implemented */ INT_PTR WINAPI @@ -1814,3 +1815,153 @@ DevicePropertiesExW(IN HWND hWndParent OPTIONAL, return Ret; } + + +/*************************************************************************** + * NAME EXPORTED + * DeviceProperties_RunDLLA + * + * DESCRIPTION + * Invokes the device properties dialog + * + * ARGUMENTS + * hWndParent: Handle to the parent window + * hInst: Handle to the application instance + * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown, + * also see NOTEs + * nCmdShow: Specifies how the window should be shown + * + * RETURN VALUE + * + * REVISIONS + * + * NOTE + * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH" + * (/MachineName is optional). This function only parses this string and eventually + * calls DeviceProperties(). + * + * @implemented + */ +VOID +WINAPI +DeviceProperties_RunDLLA(HWND hWndParent, + HINSTANCE hInst, + LPCSTR lpDeviceCmd, + int nCmdShow) +{ + LPWSTR lpDeviceCmdW = NULL; + + if (lpDeviceCmd != NULL) + { + if ((lpDeviceCmdW = ConvertMultiByteToUnicode(lpDeviceCmd, + CP_ACP))) + { + DeviceProperties_RunDLLW(hWndParent, + hInst, + lpDeviceCmdW, + nCmdShow); + } + } + + if (lpDeviceCmdW != NULL) + { + HeapFree(GetProcessHeap(), + 0, + lpDeviceCmdW); + } +} + + +/*************************************************************************** + * NAME EXPORTED + * DeviceProperties_RunDLLW + * + * DESCRIPTION + * Invokes the device properties dialog + * + * ARGUMENTS + * hWndParent: Handle to the parent window + * hInst: Handle to the application instance + * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown, + * also see NOTEs + * nCmdShow: Specifies how the window should be shown + * + * RETURN VALUE + * + * REVISIONS + * + * NOTE + * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH" + * (/MachineName is optional). This function only parses this string and eventually + * calls DeviceProperties(). + * + * @implemented + */ +VOID +WINAPI +DeviceProperties_RunDLLW(HWND hWndParent, + HINSTANCE hInst, + LPCWSTR lpDeviceCmd, + int nCmdShow) +{ + WCHAR szDeviceID[MAX_DEVICE_ID_LEN+1]; + WCHAR szMachineName[MAX_COMPUTERNAME_LENGTH+1]; + LPTSTR lpString = (LPTSTR)lpDeviceCmd; + + szDeviceID[0] = L'\0'; + szMachineName[0] = L'\0'; + + while (*lpString != L'\0') + { + if (*lpString == L'/') + { + lpString++; + if(!wcsnicmp(lpString, L"DeviceID", 8)) + { + lpString += 9; + if (*lpString != L'\0') + { + int i = 0; + while ((*lpString != L' ') && + (*lpString != L'\0') && + (i <= MAX_DEVICE_ID_LEN)) + { + szDeviceID[i++] = *lpString++; + } + szDeviceID[i] = L'\0'; + } + } + else if (!wcsnicmp(lpString, L"MachineName", 11)) + { + lpString += 12; + if (*lpString != L'\0') + { + int i = 0; + while ((*lpString != L' ') && + (*lpString != L'\0') && + (i <= MAX_COMPUTERNAME_LENGTH)) + { + szMachineName[i++] = *lpString++; + } + szMachineName[i] = L'\0'; + } + } + /* knock the pointer back one and let the next + * pointer deal with incrementing, otherwise we + * go past the end of the string */ + lpString--; + } + lpString++; + } + + //DPRINT("DeviceID: %S, MachineName: %S\n", szDeviceID, szMachineName); + + if (szDeviceID == L'\0') + return; + + DevicePropertiesW(hWndParent, + hInst, + szMachineName, + szDeviceID, + 0); +} diff --git a/reactos/dll/win32/devmgr/stubs.c b/reactos/dll/win32/devmgr/stubs.c index e53c96e97ac..b66d7a328c8 100644 --- a/reactos/dll/win32/devmgr/stubs.c +++ b/reactos/dll/win32/devmgr/stubs.c @@ -1,4 +1,4 @@ -/* $Id$ +/* * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS devmgr.dll @@ -94,78 +94,6 @@ DeviceManager_ExecuteW(HWND hWndParent, } -/*************************************************************************** - * NAME EXPORTED - * DeviceProperties_RunDLLA - * - * DESCRIPTION - * Invokes the device properties dialog - * - * ARGUMENTS - * hWndParent: Handle to the parent window - * hInst: Handle to the application instance - * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown, - * also see NOTEs - * nCmdShow: Specifies how the window should be shown - * - * RETURN VALUE - * - * REVISIONS - * - * NOTE - * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH" - * (/MachineName is optional). This function only parses this string and eventually - * calls DeviceProperties(). - * - * @unimplemented - */ -VOID -WINAPI -DeviceProperties_RunDLLA(HWND hWndParent, - HINSTANCE hInst, - LPCSTR lpDeviceCmd, - int nCmdShow) -{ - UNIMPLEMENTED; -} - - -/*************************************************************************** - * NAME EXPORTED - * DeviceProperties_RunDLLW - * - * DESCRIPTION - * Invokes the device properties dialog - * - * ARGUMENTS - * hWndParent: Handle to the parent window - * hInst: Handle to the application instance - * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown, - * also see NOTEs - * nCmdShow: Specifies how the window should be shown - * - * RETURN VALUE - * - * REVISIONS - * - * NOTE - * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH" - * (/MachineName is optional). This function only parses this string and eventually - * calls DeviceProperties(). - * - * @unimplemented - */ -VOID -WINAPI -DeviceProperties_RunDLLW(HWND hWndParent, - HINSTANCE hInst, - LPCWSTR lpDeviceCmd, - int nCmdShow) -{ - UNIMPLEMENTED; -} - - /*************************************************************************** * NAME EXPORTED * DevicePropertiesA From 6318f42ad08ca7043f825eaa5788b34788b32ef1 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 6 Oct 2006 17:10:57 +0000 Subject: [PATCH 481/488] fix a TCHAR brain lapse... svn path=/trunk/; revision=24425 --- reactos/dll/win32/devmgr/advprop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/devmgr/advprop.c b/reactos/dll/win32/devmgr/advprop.c index 048a84b92d8..7ff9baa9ad2 100644 --- a/reactos/dll/win32/devmgr/advprop.c +++ b/reactos/dll/win32/devmgr/advprop.c @@ -1906,7 +1906,7 @@ DeviceProperties_RunDLLW(HWND hWndParent, { WCHAR szDeviceID[MAX_DEVICE_ID_LEN+1]; WCHAR szMachineName[MAX_COMPUTERNAME_LENGTH+1]; - LPTSTR lpString = (LPTSTR)lpDeviceCmd; + LPWSTR lpString = (LPWSTR)lpDeviceCmd; szDeviceID[0] = L'\0'; szMachineName[0] = L'\0'; From 9bfa61479faa5c0b091ab210fad4502f5de2f946 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Fri, 6 Oct 2006 19:29:25 +0000 Subject: [PATCH 482/488] - Add PROFILE_ACPI_DOCKING_STATE. - Fix HvInitialize definition to match more closely NT's since I need some of the extra parameters for the cm rewrite. - Implement ExInitializePushLock and ExConvertPushLockSharedToExclusive macros. svn path=/trunk/; revision=24426 --- reactos/include/reactos/arc/arc.h | 10 ++++ reactos/lib/cmlib/cmlib.h | 11 +++- reactos/lib/cmlib/hiveinit.c | 2 + reactos/ntoskrnl/cm/import.c | 2 +- reactos/ntoskrnl/cm/regfile.c | 6 +- reactos/ntoskrnl/include/internal/ex.h | 77 ++++++++++++++++++++++++-- 6 files changed, 99 insertions(+), 9 deletions(-) diff --git a/reactos/include/reactos/arc/arc.h b/reactos/include/reactos/arc/arc.h index 2393e3ee149..1ebad32003b 100644 --- a/reactos/include/reactos/arc/arc.h +++ b/reactos/include/reactos/arc/arc.h @@ -150,6 +150,16 @@ typedef struct _NLS_DATA_BLOCK PVOID UnicodeCodePageData; } NLS_DATA_BLOCK, *PNLS_DATA_BLOCK; +// +// ACPI Docking State +// +typedef struct _PROFILE_ACPI_DOCKING_STATE +{ + USHORT DockingState; + USHORT SerialLength; + WCHAR SerialNumber[1]; +} PROFILE_ACPI_DOCKING_STATE, *PPROFILE_ACPI_DOCKING_STATE; + // // Subsystem Specific Loader Blocks // diff --git a/reactos/lib/cmlib/cmlib.h b/reactos/lib/cmlib/cmlib.h index 91a2229a198..7e590c2cd58 100644 --- a/reactos/lib/cmlib/cmlib.h +++ b/reactos/lib/cmlib/cmlib.h @@ -18,7 +18,7 @@ #define ROUND_DOWN(a,b) (((a)/(b))*(b)) #endif -#define CMAPI +#define CMAPI NTAPI struct _HHIVE; @@ -110,6 +110,10 @@ typedef struct _HHIVE BOOLEAN ReadOnly; BOOLEAN Log; BOOLEAN DirtyFlag; + ULONG HvBinHeadersUse; + ULONG HvFreeCellsUse; + ULONG HvUsedcellsUse; + ULONG CmUsedCellsUse; ULONG HiveFlags; ULONG LogSize; ULONG RefreshCount; @@ -146,6 +150,8 @@ HvInitialize( ULONG Operation, ULONG_PTR HiveData OPTIONAL, ULONG Cluster OPTIONAL, + ULONG Flags, + ULONG FileType, PALLOCATE_ROUTINE Allocate, PFREE_ROUTINE Free, PFILE_READ_ROUTINE FileRead, @@ -163,6 +169,9 @@ HvGetCell( PHHIVE RegistryHive, HCELL_INDEX CellOffset); +#define HvReleaseCell(h, c) \ + if (h->ReleaseCellRoutine) h->ReleaseCellRoutine(h, c) + LONG CMAPI HvGetCellSize( PHHIVE RegistryHive, diff --git a/reactos/lib/cmlib/hiveinit.c b/reactos/lib/cmlib/hiveinit.c index 1c3fc5dea0d..e1c2b7c3195 100644 --- a/reactos/lib/cmlib/hiveinit.c +++ b/reactos/lib/cmlib/hiveinit.c @@ -306,6 +306,8 @@ NTSTATUS CMAPI HvInitialize( PHHIVE RegistryHive, ULONG Operation, + ULONG HiveType, + ULONG HiveFlags, ULONG_PTR HiveData OPTIONAL, ULONG Cluster OPTIONAL, PALLOCATE_ROUTINE Allocate, diff --git a/reactos/ntoskrnl/cm/import.c b/reactos/ntoskrnl/cm/import.c index 955e14203d0..900fed9f95a 100644 --- a/reactos/ntoskrnl/cm/import.c +++ b/reactos/ntoskrnl/cm/import.c @@ -52,7 +52,7 @@ CmImportBinaryHive (PCHAR ChunkBase, /* Allocate hive header */ ((PHBASE_BLOCK)ChunkBase)->Length = ChunkSize; - Status = HvInitialize(&Hive->Hive, HV_OPERATION_MEMORY, + Status = HvInitialize(&Hive->Hive, HV_OPERATION_MEMORY, 0, 0, (ULONG_PTR)ChunkBase, 0, CmpAllocate, CmpFree, CmpFileRead, CmpFileWrite, CmpFileSetSize, diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index 8ccb8a09e3c..6ec8914af16 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -141,7 +141,7 @@ CmiCreateNewRegFile(HANDLE FileHandle) CmHive = CmpAllocate(sizeof(EREGISTRY_HIVE), TRUE); CmHive->HiveHandle = FileHandle; - Status = HvInitialize(&CmHive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, + Status = HvInitialize(&CmHive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0, CmpAllocate, CmpFree, CmpFileRead, CmpFileWrite, CmpFileSetSize, CmpFileFlush, NULL); @@ -570,7 +570,7 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive, DPRINT("ViewBase %p ViewSize %lx\n", ViewBase, ViewSize); ((PHBASE_BLOCK)ViewBase)->Length = ViewSize; - Status = HvInitialize(&RegistryHive->Hive, HV_OPERATION_MEMORY, + Status = HvInitialize(&RegistryHive->Hive, HV_OPERATION_MEMORY, 0, 0, (ULONG_PTR)ViewBase, 0, CmpAllocate, CmpFree, CmpFileRead, CmpFileWrite, CmpFileSetSize, @@ -622,7 +622,7 @@ CmiCreateTempHive(PEREGISTRY_HIVE *RegistryHive) DPRINT("Hive 0x%p\n", Hive); - Status = HvInitialize(&Hive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, + Status = HvInitialize(&Hive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0, CmpAllocate, CmpFree, CmpFileRead, CmpFileWrite, CmpFileSetSize, CmpFileFlush, NULL); diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index d539acd9bb9..3161cd4dabf 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -14,6 +14,7 @@ extern ULONG NtMinorVersion; extern FAST_MUTEX ExpEnvironmentLock; extern ERESOURCE ExpFirmwareTableResource; extern LIST_ENTRY ExpFirmwareTableProviderListHead; +extern BOOLEAN ExpIsWinPEMode; ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset; ULONG ExpUnicodeCaseTableDataOffset; PVOID ExpNlsSectionPointer; @@ -139,6 +140,14 @@ VOID NTAPI ExInitPoolLookasidePointers(VOID); +/* Callback Functions ********************************************************/ + +VOID +NTAPI +ExInitializeCallBack( + IN PEX_CALLBACK Callback +); + /* Rundown Functions ********************************************************/ VOID @@ -312,6 +321,7 @@ static __inline _SEH_FILTER(_SEH_ExSystemExceptionFilter) #define ExpSetRundown(x, y) InterlockedExchange64((PLONGLONG)x, y) #else #define ExpChangeRundown(x, y, z) InterlockedCompareExchange((PLONG)x, PtrToLong(y), PtrToLong(z)) +#define ExpChangePushlock(x, y, z) LongToPtr(InterlockedCompareExchange((PLONG)x, PtrToLong(y), PtrToLong(z))) #define ExpSetRundown(x, y) InterlockedExchange((PLONG)x, y) #endif @@ -483,6 +493,28 @@ _ExRundownCompleted(IN PEX_RUNDOWN_REF RunRef) /* PUSHLOCKS *****************************************************************/ +/*++ + * @name ExInitializePushLock + * INTERNAL MACRO + * + * The ExInitializePushLock macro initializes a PushLock. + * + * @params PushLock + * Pointer to the pushlock which is to be initialized. + * + * @return None. + * + * @remarks None. + * + *--*/ +VOID +FORCEINLINE +ExInitializePushLock(IN PEX_PUSH_LOCK PushLock) +{ + /* Set the value to 0 */ + PushLock->Value = 0; +} + /*++ * @name ExAcquirePushLockExclusive * INTERNAL MACRO @@ -545,7 +577,7 @@ ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock) /* Try acquiring the lock */ NewValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC; - if (InterlockedCompareExchangePointer(PushLock, NewValue.Ptr, 0)) + if (ExpChangePushlock(PushLock, NewValue.Ptr, 0)) { /* Someone changed it, use the slow path */ DbgPrint("%s - Contention!\n", __FUNCTION__); @@ -557,6 +589,44 @@ ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock) ASSERT(PushLock->Waiting || PushLock->Shared > 0); } +/*++ + * @name ExConvertPushLockSharedToExclusive + * INTERNAL MACRO + * + * The ExConvertPushLockSharedToExclusive macro converts an exclusive + * pushlock to a shared pushlock. + * + * @params PushLock + * Pointer to the pushlock which is to be converted. + * + * @return FALSE if conversion failed, TRUE otherwise. + * + * @remarks The function attempts the quickest route to convert the lock, which is + * to simply set the lock bit and remove any other bits. + * + *--*/ +BOOLEAN +FORCEINLINE +ExConvertPushLockSharedToExclusive(IN PEX_PUSH_LOCK PushLock) +{ + EX_PUSH_LOCK OldValue; + + /* Set the expected old value */ + OldValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC; + + /* Try converting the lock */ + if (ExpChangePushlock(PushLock, EX_PUSH_LOCK_LOCK, OldValue.Value) != + OldValue.Ptr) + { + /* Conversion failed */ + return FALSE; + } + + /* Sanity check */ + ASSERT(PushLock->Locked); + return TRUE; +} + /*++ * @name ExWaitOnPushLock * INTERNAL MACRO @@ -617,8 +687,7 @@ ExReleasePushLockShared(PEX_PUSH_LOCK PushLock) /* Try to clear the pushlock */ OldValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC; - if (InterlockedCompareExchangePointer(PushLock, 0, OldValue.Ptr) != - OldValue.Ptr) + if (ExpChangePushlock(PushLock, 0, OldValue.Ptr) != OldValue.Ptr) { /* There are still other people waiting on it */ DbgPrint("%s - Contention!\n", __FUNCTION__); @@ -716,7 +785,7 @@ ExReleasePushLock(PEX_PUSH_LOCK PushLock) /* Check if nobody is waiting on us and try clearing the lock here */ if ((OldValue.Waiting) || - (InterlockedCompareExchangePointer(PushLock, NewValue.Ptr, OldValue.Ptr) == + (ExpChangePushlock(PushLock, NewValue.Ptr, OldValue.Ptr) == OldValue.Ptr)) { /* We have waiters, use the long path */ From 0b9fa0e21a019d8f42e645cd4a94a888d3468c79 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 6 Oct 2006 20:28:55 +0000 Subject: [PATCH 483/488] - Make arc-path passed to the kernel look a bit more correct (still a hack of course) - Add KdCom.dll loading along with ntoskrnl.exe and hal.dll - Move registry-related code to a new file wlregistry.c - WinLdrLoadAndScanSystemHive() is going to combine loading, initializing and parsing registry. NLS / OEM font data loading is marked with FIXMEs now, since it needs going into that routine (because registry tells the file names, not hardcoding them) svn path=/trunk/; revision=24427 --- .../boot/freeldr/freeldr/freeldr_base.rbuild | 1 + reactos/boot/freeldr/freeldr/include/winldr.h | 5 + .../boot/freeldr/freeldr/windows/conversion.c | 246 ++-- reactos/boot/freeldr/freeldr/windows/winldr.c | 1174 ++++++++--------- .../boot/freeldr/freeldr/windows/wlregistry.c | 104 ++ 5 files changed, 792 insertions(+), 738 deletions(-) create mode 100644 reactos/boot/freeldr/freeldr/windows/wlregistry.c diff --git a/reactos/boot/freeldr/freeldr/freeldr_base.rbuild b/reactos/boot/freeldr/freeldr/freeldr_base.rbuild index 654eb398025..198a6421858 100644 --- a/reactos/boot/freeldr/freeldr/freeldr_base.rbuild +++ b/reactos/boot/freeldr/freeldr/freeldr_base.rbuild @@ -72,6 +72,7 @@ peloader.c winldr.c wlmemory.c + wlregistry.c freeldr.c debug.c diff --git a/reactos/boot/freeldr/freeldr/include/winldr.h b/reactos/boot/freeldr/freeldr/include/winldr.h index c4c973ba59c..021cd51c9ba 100644 --- a/reactos/boot/freeldr/freeldr/include/winldr.h +++ b/reactos/boot/freeldr/freeldr/include/winldr.h @@ -74,4 +74,9 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, ULONG TssBasePage, PVOID GdtIdt); +// wlregistry.c +BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath); + + #endif // defined __WINLDR_H diff --git a/reactos/boot/freeldr/freeldr/windows/conversion.c b/reactos/boot/freeldr/freeldr/windows/conversion.c index 8d29c1eeba7..a42184bbfb4 100644 --- a/reactos/boot/freeldr/freeldr/windows/conversion.c +++ b/reactos/boot/freeldr/freeldr/windows/conversion.c @@ -1,123 +1,123 @@ -/* - * PROJECT: EFI Windows Loader - * LICENSE: GPL - See COPYING in the top level directory - * FILE: freeldr/winldr/conversion.c - * PURPOSE: Physical <-> Virtual addressing mode conversions - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - */ - -/* INCLUDES ***************************************************************/ - -#include - -//#include - -#define NDEBUG -#include - -/* FUNCTIONS **************************************************************/ - -/* Arch-specific addresses translation implementation */ -PVOID -VaToPa(PVOID Va) -{ - return (PVOID)((ULONG_PTR)Va & ~KSEG0_BASE); -} - -PVOID -PaToVa(PVOID Pa) -{ - return (PVOID)((ULONG_PTR)Pa | KSEG0_BASE); -} - -VOID -List_PaToVa(LIST_ENTRY *ListEntry) -{ - LIST_ENTRY *ListHead = ListEntry; - LIST_ENTRY *Next = ListEntry->Flink; - LIST_ENTRY *NextPA; - - //Print(L"\n\nList_Entry: %X, First Next: %X\n", ListEntry, Next); - // - // Walk through the whole list - // - if (Next != NULL) - { - while (Next != PaToVa(ListHead)) - { - NextPA = VaToPa(Next); - //Print(L"Current: %X, Flink: %X, Blink: %X\n", Next, NextPA->Flink, NextPA->Blink); - - NextPA->Flink = PaToVa((PVOID)NextPA->Flink); - NextPA->Blink = PaToVa((PVOID)NextPA->Blink); - - //Print(L"After converting Flink: %X, Blink: %X\n", NextPA->Flink, NextPA->Blink); - - Next = NextPA->Flink; - } - - // - // Finally convert first Flink/Blink - // - ListEntry->Flink = PaToVa((PVOID)ListEntry->Flink); - if (ListEntry->Blink) - ListEntry->Blink = PaToVa((PVOID)ListEntry->Blink); - } -} - -// This function converts only Child->Child, and calls itself for each Sibling -VOID -ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start) -{ - PCONFIGURATION_COMPONENT_DATA Child; - PCONFIGURATION_COMPONENT_DATA Sibling; - - DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)", Start)); - Child = Start; - - while (Child != NULL) - { - if (Child->ConfigurationData) - Child->ConfigurationData = PaToVa(Child->ConfigurationData); - - if (Child->Child) - Child->Child = PaToVa(Child->Child); - - if (Child->Parent) - Child->Parent = PaToVa(Child->Parent); - - if (Child->Sibling) - Child->Sibling = PaToVa(Child->Sibling); - - DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Child, Child->ComponentEntry.Class)); - - // If the child has a sibling list, then search the sibling list - // for an entry that matches the specified class, type, and key. - Sibling = Child->Sibling; - while (Sibling != NULL) - { - if (Sibling->ConfigurationData) - Sibling->ConfigurationData = PaToVa(Sibling->ConfigurationData); - - if (Sibling->Child) - Sibling->Child = PaToVa(Sibling->Child); - - if (Sibling->Parent) - Sibling->Parent = PaToVa(Sibling->Parent); - - if (Sibling->Sibling) - Sibling->Sibling = PaToVa(Sibling->Sibling); - - DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Sibling, Sibling->ComponentEntry.Class)); - - // If the sibling has a child tree, then search the child tree - // for an entry that matches the specified class, type, and key. - if (VaToPa(Sibling->Child) != NULL) - ConvertConfigToVA(VaToPa(Sibling->Child)); - - Sibling = VaToPa(Sibling->Sibling); - } - - Child = VaToPa(Child->Child); - } -} +/* + * PROJECT: EFI Windows Loader + * LICENSE: GPL - See COPYING in the top level directory + * FILE: freeldr/winldr/conversion.c + * PURPOSE: Physical <-> Virtual addressing mode conversions + * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + */ + +/* INCLUDES ***************************************************************/ + +#include + +//#include + +#define NDEBUG +#include + +/* FUNCTIONS **************************************************************/ + +/* Arch-specific addresses translation implementation */ +PVOID +VaToPa(PVOID Va) +{ + return (PVOID)((ULONG_PTR)Va & ~KSEG0_BASE); +} + +PVOID +PaToVa(PVOID Pa) +{ + return (PVOID)((ULONG_PTR)Pa | KSEG0_BASE); +} + +VOID +List_PaToVa(LIST_ENTRY *ListEntry) +{ + LIST_ENTRY *ListHead = ListEntry; + LIST_ENTRY *Next = ListEntry->Flink; + LIST_ENTRY *NextPA; + + //Print(L"\n\nList_Entry: %X, First Next: %X\n", ListEntry, Next); + // + // Walk through the whole list + // + if (Next != NULL) + { + while (Next != PaToVa(ListHead)) + { + NextPA = VaToPa(Next); + //Print(L"Current: %X, Flink: %X, Blink: %X\n", Next, NextPA->Flink, NextPA->Blink); + + NextPA->Flink = PaToVa((PVOID)NextPA->Flink); + NextPA->Blink = PaToVa((PVOID)NextPA->Blink); + + //Print(L"After converting Flink: %X, Blink: %X\n", NextPA->Flink, NextPA->Blink); + + Next = NextPA->Flink; + } + + // + // Finally convert first Flink/Blink + // + ListEntry->Flink = PaToVa((PVOID)ListEntry->Flink); + if (ListEntry->Blink) + ListEntry->Blink = PaToVa((PVOID)ListEntry->Blink); + } +} + +// This function converts only Child->Child, and calls itself for each Sibling +VOID +ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start) +{ + PCONFIGURATION_COMPONENT_DATA Child; + PCONFIGURATION_COMPONENT_DATA Sibling; + + DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)", Start)); + Child = Start; + + while (Child != NULL) + { + if (Child->ConfigurationData) + Child->ConfigurationData = PaToVa(Child->ConfigurationData); + + if (Child->Child) + Child->Child = PaToVa(Child->Child); + + if (Child->Parent) + Child->Parent = PaToVa(Child->Parent); + + if (Child->Sibling) + Child->Sibling = PaToVa(Child->Sibling); + + DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Child, Child->ComponentEntry.Class)); + + // If the child has a sibling list, then search the sibling list + // for an entry that matches the specified class, type, and key. + Sibling = Child->Sibling; + while (Sibling != NULL) + { + if (Sibling->ConfigurationData) + Sibling->ConfigurationData = PaToVa(Sibling->ConfigurationData); + + if (Sibling->Child) + Sibling->Child = PaToVa(Sibling->Child); + + if (Sibling->Parent) + Sibling->Parent = PaToVa(Sibling->Parent); + + if (Sibling->Sibling) + Sibling->Sibling = PaToVa(Sibling->Sibling); + + DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Sibling, Sibling->ComponentEntry.Class)); + + // If the sibling has a child tree, then search the child tree + // for an entry that matches the specified class, type, and key. + if (VaToPa(Sibling->Child) != NULL) + ConvertConfigToVA(VaToPa(Sibling->Child)); + + Sibling = VaToPa(Sibling->Sibling); + } + + Child = VaToPa(Child->Child); + } +} diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index 22c3fc6010a..6f668f65e5a 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -1,615 +1,559 @@ -/* - * FreeLoader - * - * Copyright (C) 1998-2003 Brian Palmer - * Copyright (C) 2006 Aleksey Bragin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include - -//#define NDEBUG -#include - -VOID DumpMemoryAllocMap(VOID); -VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); - -BOOLEAN -WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, - IN LPCSTR DirectoryPath, - IN LPCSTR AnsiFileName, - IN LPCSTR OemFileName, - IN LPCSTR LanguageFileName) -{ - CHAR FileName[255]; - PFILE AnsiFileHandle; - PFILE OemFileHandle; - PFILE LanguageFileHandle; - ULONG AnsiFileSize, OemFileSize, LanguageFileSize; - ULONG TotalSize; - ULONG_PTR NlsDataBase; - PVOID NlsVirtual; - BOOLEAN Status, AnsiEqualsOem = FALSE; - - /* There may be a case, when OEM and ANSI page coincide */ - if (!strcmp(AnsiFileName, OemFileName)) - AnsiEqualsOem = TRUE; - - /* Open file with ANSI and store its size */ - //Print(L"Loading %s...\n", Filename); - strcpy(FileName, DirectoryPath); - strcat(FileName, AnsiFileName); - AnsiFileHandle = FsOpenFile(FileName); - - if (AnsiFileHandle == NULL) - goto Failure; - - AnsiFileSize = FsGetFileSize(AnsiFileHandle); - DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize)); - FsCloseFile(AnsiFileHandle); - - /* Open OEM file and store its length */ - if (AnsiEqualsOem) - { - OemFileSize = 0; - } - else - { - //Print(L"Loading %s...\n", Filename); - strcpy(FileName, DirectoryPath); - strcat(FileName, OemFileName); - OemFileHandle = FsOpenFile(FileName); - - if (OemFileHandle == NULL) - goto Failure; - - OemFileSize = FsGetFileSize(OemFileHandle); - FsCloseFile(OemFileHandle); - } - DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize)); - - /* And finally open the language codepage file and store its length */ - //Print(L"Loading %s...\n", Filename); - strcpy(FileName, DirectoryPath); - strcat(FileName, LanguageFileName); - LanguageFileHandle = FsOpenFile(FileName); - - if (LanguageFileHandle == NULL) - goto Failure; - - LanguageFileSize = FsGetFileSize(LanguageFileHandle); - FsCloseFile(LanguageFileHandle); - DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize)); - - /* Sum up all three length, having in mind that every one of them - must start at a page boundary => thus round up each file to a page */ - TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + - MM_SIZE_TO_PAGES(OemFileSize) + - MM_SIZE_TO_PAGES(LanguageFileSize); - - NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); - - if (NlsDataBase == 0) - goto Failure; - - NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase); - LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; - LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + - (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); - LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + - (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + - (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); - - /* Ansi and OEM data are the same - just set pointers to the same area */ - if (AnsiEqualsOem) - LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; - - - /* Now actually read the data into memory, starting with Ansi file */ - strcpy(FileName, DirectoryPath); - strcat(FileName, AnsiFileName); - AnsiFileHandle = FsOpenFile(FileName); - - if (AnsiFileHandle == NULL) - goto Failure; - - Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData)); - - if (!Status) - goto Failure; - - FsCloseFile(AnsiFileHandle); - - /* OEM now, if it doesn't equal Ansi of course */ - if (!AnsiEqualsOem) - { - strcpy(FileName, DirectoryPath); - strcat(FileName, OemFileName); - OemFileHandle = FsOpenFile(FileName); - - if (OemFileHandle == NULL) - goto Failure; - - Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData)); - - if (!Status) - goto Failure; - - FsCloseFile(AnsiFileHandle); - } - - /* finally the language file */ - strcpy(FileName, DirectoryPath); - strcat(FileName, LanguageFileName); - LanguageFileHandle = FsOpenFile(FileName); - - if (LanguageFileHandle == NULL) - goto Failure; - - Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData)); - - if (!Status) - goto Failure; - - FsCloseFile(LanguageFileHandle); - - // - // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK - // Should go to WinLdrLoadOemHalFont(), when it will be implemented - // - LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); - - /* Convert NlsTables address to VA */ - LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); - - return TRUE; - -Failure: - //UiMessageBox("Error reading NLS file %s\n", Filename); - UiMessageBox("Error reading NLS file!"); - return FALSE; -} - -BOOLEAN -WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, - IN LPCSTR DirectoryPath, - IN LPCSTR HiveName) -{ - PFILE FileHandle; - CHAR FullHiveName[256]; - BOOLEAN Status; - ULONG HiveFileSize; - ULONG_PTR HiveDataPhysical; - PVOID HiveDataVirtual; - - /* Concatenate path and filename to get the full name */ - strcpy(FullHiveName, DirectoryPath); - strcat(FullHiveName, HiveName); - //Print(L"Loading %s...\n", FullHiveName); - FileHandle = FsOpenFile(FullHiveName); - - if (FileHandle == NULL) - { - UiMessageBox("Opening hive file failed!"); - return FALSE; - } - - /* Get the file length */ - HiveFileSize = FsGetFileSize(FileHandle); - - if (HiveFileSize == 0) - { - FsCloseFile(FileHandle); - UiMessageBox("Hive file has 0 size!"); - return FALSE; - } - - /* Round up the size to page boundary and alloc memory */ - HiveDataPhysical = (ULONG_PTR)MmAllocateMemory( - MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT); - - if (HiveDataPhysical == 0) - { - FsCloseFile(FileHandle); - UiMessageBox("Unable to alloc memory for a hive!"); - return FALSE; - } - - /* Convert address to virtual */ - HiveDataVirtual = (PVOID)(KSEG0_BASE | HiveDataPhysical); - - /* Fill LoaderBlock's entries */ - LoaderBlock->RegistryLength = HiveFileSize; - LoaderBlock->RegistryBase = HiveDataVirtual; - - /* Finally read from file to the memory */ - Status = FsReadFile(FileHandle, HiveFileSize, NULL, (PVOID)HiveDataPhysical); - FsCloseFile(FileHandle); - if (!Status) - { - UiMessageBox("Unable to read from hive file!"); - return FALSE; - } - - return TRUE; -} - -void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock) -{ - PCONFIGURATION_COMPONENT_DATA ConfigurationRoot; - PCONFIGURATION_COMPONENT Component; - PCONFIGURATION_COMPONENT_DATA /*CurrentEntry,*/ PreviousEntry, AdapterEntry; - BOOLEAN IsNextEntryChild; - - DbgPrint((DPRINT_WINDOWS, "InitializeHWConfig()\n")); - - LoaderBlock->ConfigurationRoot = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); - RtlZeroMemory(LoaderBlock->ConfigurationRoot, sizeof(CONFIGURATION_COMPONENT_DATA)); - - /* Fill root == SystemClass */ - ConfigurationRoot = LoaderBlock->ConfigurationRoot; - Component = &LoaderBlock->ConfigurationRoot->ComponentEntry; - - Component->Class = SystemClass; - Component->Type = MaximumType; - Component->Version = 0; // FIXME: ? - Component->Key = 0; - Component->AffinityMask = 0; - - IsNextEntryChild = TRUE; - PreviousEntry = ConfigurationRoot; - - /* Enumerate all PCI buses */ - AdapterEntry = ConfigurationRoot; - - /* TODO: Disk Geometry */ - /* TODO: Keyboard */ - - /* TODO: Serial port */ - - //Config->ConfigurationData = alloc(sizeof(CONFIGURATION_COMPONENT_DATA), EfiLoaderData); - - /* Convert everything to VA */ - ConvertConfigToVA(LoaderBlock->ConfigurationRoot); - LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot); -} - - -// Init "phase 0" -VOID -AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock) -{ - PLOADER_PARAMETER_BLOCK LoaderBlock; - - /* Allocate and zero-init the LPB */ - LoaderBlock = MmAllocateMemory(sizeof(LOADER_PARAMETER_BLOCK)); - RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK)); - - /* Init three critical lists, used right away */ - InitializeListHead(&LoaderBlock->LoadOrderListHead); - InitializeListHead(&LoaderBlock->MemoryDescriptorListHead); - InitializeListHead(&LoaderBlock->BootDriverListHead); - - - *OutLoaderBlock = LoaderBlock; -} - -// Init "phase 1" -VOID -WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock) -{ - //CHAR Options[] = "/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200"; - CHAR Options[] = "/NODEBUG"; - CHAR SystemRoot[] = "\\WINNT"; - CHAR HalPath[] = "\\"; - CHAR ArcBoot[] = "multi(0)"; - CHAR ArcHal[] = "multi(0)"; - - PLOADER_PARAMETER_EXTENSION Extension; - - LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support - - /* Fill Arc BootDevice */ - LoaderBlock->ArcBootDeviceName = MmAllocateMemory(strlen(ArcBoot)+1); - strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot); - LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName); - - /* Fill Arc HalDevice */ - LoaderBlock->ArcHalDeviceName = MmAllocateMemory(strlen(ArcHal)+1); - strcpy(LoaderBlock->ArcHalDeviceName, ArcHal); - LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName); - - /* Fill SystemRoot */ - LoaderBlock->NtBootPathName = MmAllocateMemory(strlen(SystemRoot)+1); - strcpy(LoaderBlock->NtBootPathName, SystemRoot); - LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName); - - /* Fill NtHalPathName */ - LoaderBlock->NtHalPathName = MmAllocateMemory(strlen(HalPath)+1); - strcpy(LoaderBlock->NtHalPathName, HalPath); - LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName); - - /* Fill load options */ - LoaderBlock->LoadOptions = MmAllocateMemory(strlen(Options)+1); - strcpy(LoaderBlock->LoadOptions, Options); - LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions); - - /* Arc devices */ - LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION)); - InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); - List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); - LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation); - - /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */ - LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK)); - if (LoaderBlock->NlsData == NULL) - { - UiMessageBox("Failed to allocate memory for NLS table data!"); - return; - } - RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK)); - - /* Create configuration entries */ - InitializeHWConfig(LoaderBlock); - - /* Convert all DTE into virtual addresses */ - //TODO: !!! - - /* Convert all list's to Virtual address */ - List_PaToVa(&LoaderBlock->LoadOrderListHead); - - /* this one will be converted right before switching to - virtual paging mode */ - //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead); - - List_PaToVa(&LoaderBlock->BootDriverListHead); - - /* Initialize Extension now */ - Extension = MmAllocateMemory(sizeof(LOADER_PARAMETER_EXTENSION)); - if (Extension == NULL) - { - UiMessageBox("Failed to allocate LPB Extension!"); - return; - } - RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION)); - - Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION); - Extension->MajorVersion = 4; - Extension->MinorVersion = 0; - - - LoaderBlock->Extension = PaToVa(Extension); -} - -// Last step before going virtual -void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock, - PVOID *GdtIdt, - ULONG *PcrBasePage, - ULONG *TssBasePage) -{ - ULONG TssSize; - ULONG TssPages; - ULONG_PTR Pcr = 0; - ULONG_PTR Tss = 0; - ULONG BlockSize, NumPages; - - LoaderBlock->u.I386.CommonDataArea = NULL;//CommonDataArea; - //LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType? - - /* Allocate 2 pages for PCR */ - Pcr = (ULONG_PTR)MmAllocateMemory(2 * MM_PAGE_SIZE); - *PcrBasePage = Pcr >> MM_PAGE_SHIFT; - - if (Pcr == 0) - { - UiMessageBox("Can't allocate PCR\n"); - return; - } - - /* Allocate TSS */ - TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1); - TssPages = TssSize / MM_PAGE_SIZE; - - Tss = (ULONG_PTR)MmAllocateMemory(TssSize); - - *TssBasePage = Tss >> MM_PAGE_SHIFT; - - /* Allocate space for new GDT + IDT */ - BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here? - NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT; - *GdtIdt = (PKGDTENTRY)MmAllocateMemory(NumPages * MM_PAGE_SIZE); - - if (*GdtIdt == NULL) - { - UiMessageBox("Can't allocate pages for GDT+IDT!\n"); - return; - } - - /* Zero newly prepared GDT+IDT */ - RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT); -} - -VOID -LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) -{ - CHAR MsgBuffer[256]; - CHAR SystemPath[1024], SearchPath[1024]; - CHAR FileName[1024]; - CHAR BootPath[256]; - PVOID NtosBase = NULL, HalBase = NULL; - BOOLEAN Status; - ULONG SectionId; - ULONG BootDevice; - PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA; - KERNEL_ENTRY_POINT KiSystemStartup; - PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE; - // Mm-related things - PVOID GdtIdt; - ULONG PcrBasePage=0; - ULONG TssBasePage=0; - - - - //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion); - //UiMessageBox(MsgBuffer); - - // - // Open the operating system section - // specified in the .ini file - // - if (!IniOpenSection(OperatingSystemName, &SectionId)) - { - sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName); - UiMessageBox(MsgBuffer); - return; - } - - /* - * Make sure the system path is set in the .ini file - */ - if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath))) - { - UiMessageBox("System path not specified for selected operating system."); - return; - } - - if (!MachDiskNormalizeSystemPath(SystemPath, - sizeof(SystemPath))) - { - UiMessageBox("Invalid system path"); - return; - } - - UiDrawStatusText("Loading..."); - - /* - * Try to open system drive - */ - BootDevice = 0xffffffff; - if (!FsOpenSystemVolume(SystemPath, BootPath, &BootDevice)) - { - UiMessageBox("Failed to open boot drive."); - return; - } - - /* append a backslash */ - if ((strlen(BootPath)==0) || - BootPath[strlen(BootPath)] != '\\') - strcat(BootPath, "\\"); - - DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath)); - - /* Allocate and minimalistic-initialize LPB */ - AllocateAndInitLPB(&LoaderBlock); - - // Load kernel - strcpy(FileName, BootPath); - strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE"); - Status = WinLdrLoadImage(FileName, &NtosBase); - DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d\n", Status)); - - // Load HAL - strcpy(FileName, BootPath); - strcat(FileName, "SYSTEM32\\HAL.DLL"); - Status = WinLdrLoadImage(FileName, &HalBase); - DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d\n", Status)); - - WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe", - "WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE); - WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll", - "WINNT\\SYSTEM32\\HAL.EXE", HalBase, &HalDTE); - - /* Load all referenced DLLs for kernel and HAL */ - strcpy(SearchPath, BootPath); - strcat(SearchPath, "SYSTEM32\\"); - WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KernelDTE); - WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE); - - /* Initialize Phase 1 - before NLS */ - WinLdrInitializePhase1(LoaderBlock); - - /* Load SYSTEM hive and its LOG file */ - strcpy(SearchPath, BootPath); - strcat(SearchPath, "SYSTEM32\\CONFIG\\"); - Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM"); - DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status)); - - /* Load NLS data */ - strcpy(SearchPath, BootPath); - strcat(SearchPath, "SYSTEM32\\"); - Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, - "c_1252.nls", "c_437.nls", "l_intl.nls"); - DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status)); - - /* Load OEM HAL font */ - - /* Load boot drivers */ - - /* Alloc PCR, TSS, do magic things with the GDT/IDT */ - WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage); - - /* Save entry-point pointer (VA) */ - KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint; - - LoaderBlockVA = PaToVa(LoaderBlock); - - /* Debugging... */ - //DumpMemoryAllocMap(); - - /* Turn on paging mode of CPU*/ - WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt); - - DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n", - KiSystemStartup, LoaderBlockVA)); - - WinLdrpDumpMemoryDescriptors(LoaderBlockVA); - - // temp: offset C9000 - - //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below - //while (1) {}; - asm(".intel_syntax noprefix\n"); - asm("test1:\n"); - asm("jmp test1\n"); - asm(".att_syntax\n"); - - - (*KiSystemStartup)(LoaderBlockVA); - - return; -} - -VOID -WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock) -{ - PLIST_ENTRY NextMd; - PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor; - - NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; - - while (NextMd != &LoaderBlock->MemoryDescriptorListHead) - { - MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry); - - - DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage, - MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType)); - - NextMd = MemoryDescriptor->ListEntry.Flink; - } -} +/* + * FreeLoader + * + * Copyright (C) 1998-2003 Brian Palmer + * Copyright (C) 2006 Aleksey Bragin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include + +//#define NDEBUG +#include + +VOID DumpMemoryAllocMap(VOID); +VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); + +BOOLEAN +WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath, + IN LPCSTR AnsiFileName, + IN LPCSTR OemFileName, + IN LPCSTR LanguageFileName) +{ + CHAR FileName[255]; + PFILE AnsiFileHandle; + PFILE OemFileHandle; + PFILE LanguageFileHandle; + ULONG AnsiFileSize, OemFileSize, LanguageFileSize; + ULONG TotalSize; + ULONG_PTR NlsDataBase; + PVOID NlsVirtual; + BOOLEAN Status, AnsiEqualsOem = FALSE; + + /* There may be a case, when OEM and ANSI page coincide */ + if (!strcmp(AnsiFileName, OemFileName)) + AnsiEqualsOem = TRUE; + + /* Open file with ANSI and store its size */ + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, AnsiFileName); + AnsiFileHandle = FsOpenFile(FileName); + + if (AnsiFileHandle == NULL) + goto Failure; + + AnsiFileSize = FsGetFileSize(AnsiFileHandle); + DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize)); + FsCloseFile(AnsiFileHandle); + + /* Open OEM file and store its length */ + if (AnsiEqualsOem) + { + OemFileSize = 0; + } + else + { + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, OemFileName); + OemFileHandle = FsOpenFile(FileName); + + if (OemFileHandle == NULL) + goto Failure; + + OemFileSize = FsGetFileSize(OemFileHandle); + FsCloseFile(OemFileHandle); + } + DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize)); + + /* And finally open the language codepage file and store its length */ + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, LanguageFileName); + LanguageFileHandle = FsOpenFile(FileName); + + if (LanguageFileHandle == NULL) + goto Failure; + + LanguageFileSize = FsGetFileSize(LanguageFileHandle); + FsCloseFile(LanguageFileHandle); + DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize)); + + /* Sum up all three length, having in mind that every one of them + must start at a page boundary => thus round up each file to a page */ + TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + + MM_SIZE_TO_PAGES(OemFileSize) + + MM_SIZE_TO_PAGES(LanguageFileSize); + + NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); + + if (NlsDataBase == 0) + goto Failure; + + NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase); + LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; + LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); + LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + + (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); + + /* Ansi and OEM data are the same - just set pointers to the same area */ + if (AnsiEqualsOem) + LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; + + + /* Now actually read the data into memory, starting with Ansi file */ + strcpy(FileName, DirectoryPath); + strcat(FileName, AnsiFileName); + AnsiFileHandle = FsOpenFile(FileName); + + if (AnsiFileHandle == NULL) + goto Failure; + + Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(AnsiFileHandle); + + /* OEM now, if it doesn't equal Ansi of course */ + if (!AnsiEqualsOem) + { + strcpy(FileName, DirectoryPath); + strcat(FileName, OemFileName); + OemFileHandle = FsOpenFile(FileName); + + if (OemFileHandle == NULL) + goto Failure; + + Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(AnsiFileHandle); + } + + /* finally the language file */ + strcpy(FileName, DirectoryPath); + strcat(FileName, LanguageFileName); + LanguageFileHandle = FsOpenFile(FileName); + + if (LanguageFileHandle == NULL) + goto Failure; + + Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(LanguageFileHandle); + + // + // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK + // Should go to WinLdrLoadOemHalFont(), when it will be implemented + // + LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); + + /* Convert NlsTables address to VA */ + LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); + + return TRUE; + +Failure: + //UiMessageBox("Error reading NLS file %s\n", Filename); + UiMessageBox("Error reading NLS file!"); + return FALSE; +} + +void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PCONFIGURATION_COMPONENT_DATA ConfigurationRoot; + PCONFIGURATION_COMPONENT Component; + PCONFIGURATION_COMPONENT_DATA /*CurrentEntry,*/ PreviousEntry, AdapterEntry; + BOOLEAN IsNextEntryChild; + + DbgPrint((DPRINT_WINDOWS, "InitializeHWConfig()\n")); + + LoaderBlock->ConfigurationRoot = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + RtlZeroMemory(LoaderBlock->ConfigurationRoot, sizeof(CONFIGURATION_COMPONENT_DATA)); + + /* Fill root == SystemClass */ + ConfigurationRoot = LoaderBlock->ConfigurationRoot; + Component = &LoaderBlock->ConfigurationRoot->ComponentEntry; + + Component->Class = SystemClass; + Component->Type = MaximumType; + Component->Version = 0; // FIXME: ? + Component->Key = 0; + Component->AffinityMask = 0; + + IsNextEntryChild = TRUE; + PreviousEntry = ConfigurationRoot; + + /* Enumerate all PCI buses */ + AdapterEntry = ConfigurationRoot; + + /* TODO: Disk Geometry */ + /* TODO: Keyboard */ + + /* TODO: Serial port */ + + //Config->ConfigurationData = alloc(sizeof(CONFIGURATION_COMPONENT_DATA), EfiLoaderData); + + /* Convert everything to VA */ + ConvertConfigToVA(LoaderBlock->ConfigurationRoot); + LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot); +} + + +// Init "phase 0" +VOID +AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock) +{ + PLOADER_PARAMETER_BLOCK LoaderBlock; + + /* Allocate and zero-init the LPB */ + LoaderBlock = MmAllocateMemory(sizeof(LOADER_PARAMETER_BLOCK)); + RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK)); + + /* Init three critical lists, used right away */ + InitializeListHead(&LoaderBlock->LoadOrderListHead); + InitializeListHead(&LoaderBlock->MemoryDescriptorListHead); + InitializeListHead(&LoaderBlock->BootDriverListHead); + + + *OutLoaderBlock = LoaderBlock; +} + +// Init "phase 1" +VOID +WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + //CHAR Options[] = "/CRASHDEBUG /DEBUGPORT=COM1 /BAUDRATE=115200"; + CHAR Options[] = "/NODEBUG"; + CHAR SystemRoot[] = "\\WINNT"; + CHAR HalPath[] = "\\"; + CHAR ArcBoot[] = "multi(0)disk(0)rdisk(1)partition(1)"; + CHAR ArcHal[] = "multi(0)disk(0)rdisk(1)partition(1)"; + + PLOADER_PARAMETER_EXTENSION Extension; + + LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support + + /* Fill Arc BootDevice */ + LoaderBlock->ArcBootDeviceName = MmAllocateMemory(strlen(ArcBoot)+1); + strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot); + LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName); + + /* Fill Arc HalDevice */ + LoaderBlock->ArcHalDeviceName = MmAllocateMemory(strlen(ArcHal)+1); + strcpy(LoaderBlock->ArcHalDeviceName, ArcHal); + LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName); + + /* Fill SystemRoot */ + LoaderBlock->NtBootPathName = MmAllocateMemory(strlen(SystemRoot)+1); + strcpy(LoaderBlock->NtBootPathName, SystemRoot); + LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName); + + /* Fill NtHalPathName */ + LoaderBlock->NtHalPathName = MmAllocateMemory(strlen(HalPath)+1); + strcpy(LoaderBlock->NtHalPathName, HalPath); + LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName); + + /* Fill load options */ + LoaderBlock->LoadOptions = MmAllocateMemory(strlen(Options)+1); + strcpy(LoaderBlock->LoadOptions, Options); + LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions); + + /* Arc devices */ + LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION)); + InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); + List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); + LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation); + + /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */ + LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK)); + if (LoaderBlock->NlsData == NULL) + { + UiMessageBox("Failed to allocate memory for NLS table data!"); + return; + } + RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK)); + + /* Create configuration entries */ + InitializeHWConfig(LoaderBlock); + + /* Convert all DTE into virtual addresses */ + //TODO: !!! + + /* Convert all list's to Virtual address */ + List_PaToVa(&LoaderBlock->LoadOrderListHead); + + /* this one will be converted right before switching to + virtual paging mode */ + //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead); + + List_PaToVa(&LoaderBlock->BootDriverListHead); + + /* Initialize Extension now */ + Extension = MmAllocateMemory(sizeof(LOADER_PARAMETER_EXTENSION)); + if (Extension == NULL) + { + UiMessageBox("Failed to allocate LPB Extension!"); + return; + } + RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION)); + + Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION); + Extension->MajorVersion = 4; + Extension->MinorVersion = 0; + + + LoaderBlock->Extension = PaToVa(Extension); +} + +// Last step before going virtual +void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock, + PVOID *GdtIdt, + ULONG *PcrBasePage, + ULONG *TssBasePage) +{ + ULONG TssSize; + ULONG TssPages; + ULONG_PTR Pcr = 0; + ULONG_PTR Tss = 0; + ULONG BlockSize, NumPages; + + LoaderBlock->u.I386.CommonDataArea = NULL;//CommonDataArea; + //LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType? + + /* Allocate 2 pages for PCR */ + Pcr = (ULONG_PTR)MmAllocateMemory(2 * MM_PAGE_SIZE); + *PcrBasePage = Pcr >> MM_PAGE_SHIFT; + + if (Pcr == 0) + { + UiMessageBox("Can't allocate PCR\n"); + return; + } + + /* Allocate TSS */ + TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1); + TssPages = TssSize / MM_PAGE_SIZE; + + Tss = (ULONG_PTR)MmAllocateMemory(TssSize); + + *TssBasePage = Tss >> MM_PAGE_SHIFT; + + /* Allocate space for new GDT + IDT */ + BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here? + NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT; + *GdtIdt = (PKGDTENTRY)MmAllocateMemory(NumPages * MM_PAGE_SIZE); + + if (*GdtIdt == NULL) + { + UiMessageBox("Can't allocate pages for GDT+IDT!\n"); + return; + } + + /* Zero newly prepared GDT+IDT */ + RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT); +} + +VOID +LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) +{ + CHAR MsgBuffer[256]; + CHAR SystemPath[1024], SearchPath[1024]; + CHAR FileName[1024]; + CHAR BootPath[256]; + PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL; + BOOLEAN Status; + ULONG SectionId; + ULONG BootDevice; + PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA; + KERNEL_ENTRY_POINT KiSystemStartup; + PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE; + // Mm-related things + PVOID GdtIdt; + ULONG PcrBasePage=0; + ULONG TssBasePage=0; + + + + //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion); + //UiMessageBox(MsgBuffer); + + // Open the operating system section + // specified in the .ini file + if (!IniOpenSection(OperatingSystemName, &SectionId)) + { + sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName); + UiMessageBox(MsgBuffer); + return; + } + + /* Make sure the system path is set in the .ini file */ + if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath))) + { + UiMessageBox("System path not specified for selected operating system."); + return; + } + + if (!MachDiskNormalizeSystemPath(SystemPath, + sizeof(SystemPath))) + { + UiMessageBox("Invalid system path"); + return; + } + + UiDrawStatusText("Loading..."); + + /* Try to open system drive */ + BootDevice = 0xffffffff; + if (!FsOpenSystemVolume(SystemPath, BootPath, &BootDevice)) + { + UiMessageBox("Failed to open boot drive."); + return; + } + + /* append a backslash */ + if ((strlen(BootPath)==0) || + BootPath[strlen(BootPath)] != '\\') + strcat(BootPath, "\\"); + + DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath)); + + // Allocate and minimalistic-initialize LPB + AllocateAndInitLPB(&LoaderBlock); + + // Load kernel + strcpy(FileName, BootPath); + strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE"); + Status = WinLdrLoadImage(FileName, &NtosBase); + DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase)); + + // Load HAL + strcpy(FileName, BootPath); + strcat(FileName, "SYSTEM32\\HAL.DLL"); + Status = WinLdrLoadImage(FileName, &HalBase); + DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase)); + + // Load kernel-debugger support dll + if (OperatingSystemVersion > _WIN32_WINNT_NT4) + { + strcpy(FileName, BootPath); + strcat(FileName, "SYSTEM32\\KDCOM.DLL"); + Status = WinLdrLoadImage(FileName, &KdComBase); + DbgPrint((DPRINT_WINDOWS, "KdCom loaded with status %d at %p\n", Status, KdComBase)); + } + + // Allocate data table entries for above-loaded modules + WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe", + "WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE); + WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll", + "WINNT\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE); + if (OperatingSystemVersion > _WIN32_WINNT_NT4) + { + WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll", + "WINNT\\SYSTEM32\\KDCOM.DLL", KdComBase, &KdComDTE); + } + + /* Load all referenced DLLs for kernel, HAL and kdcom.dll */ + strcpy(SearchPath, BootPath); + strcat(SearchPath, "SYSTEM32\\"); + WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KernelDTE); + WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE); + if (KdComDTE) + WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KdComDTE); + + /* Initialize Phase 1 - before NLS */ + WinLdrInitializePhase1(LoaderBlock); + + /* Load Hive, and then NLS data, OEM font, and prepare boot drivers list */ + Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath); + DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status)); + + /* FIXME: Load NLS data, should be moved to WinLdrLoadAndScanSystemHive() */ + strcpy(SearchPath, BootPath); + strcat(SearchPath, "SYSTEM32\\"); + Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, + "c_1252.nls", "c_437.nls", "l_intl.nls"); + DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status)); + + /* FIXME: Load OEM HAL font, should be moved to WinLdrLoadAndScanSystemHive() */ + + /* Load boot drivers */ + //WinLdrLoadBootDrivers(); + + /* Alloc PCR, TSS, do magic things with the GDT/IDT */ + WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage); + + /* Save entry-point pointer (VA) */ + KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint; + + LoaderBlockVA = PaToVa(LoaderBlock); + + /* Debugging... */ + //DumpMemoryAllocMap(); + + /* Turn on paging mode of CPU*/ + WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt); + + DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n", + KiSystemStartup, LoaderBlockVA)); + + WinLdrpDumpMemoryDescriptors(LoaderBlockVA); + + //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below + //while (1) {}; + /*asm(".intel_syntax noprefix\n"); + asm("test1:\n"); + asm("jmp test1\n"); + asm(".att_syntax\n");*/ + + + (*KiSystemStartup)(LoaderBlockVA); + + return; +} + +VOID +WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PLIST_ENTRY NextMd; + PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor; + + NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; + + while (NextMd != &LoaderBlock->MemoryDescriptorListHead) + { + MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry); + + + DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage, + MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType)); + + NextMd = MemoryDescriptor->ListEntry.Flink; + } +} diff --git a/reactos/boot/freeldr/freeldr/windows/wlregistry.c b/reactos/boot/freeldr/freeldr/windows/wlregistry.c new file mode 100644 index 00000000000..c14fd64bdf2 --- /dev/null +++ b/reactos/boot/freeldr/freeldr/windows/wlregistry.c @@ -0,0 +1,104 @@ +/* + * PROJECT: EFI Windows Loader + * LICENSE: GPL - See COPYING in the top level directory + * FILE: freeldr/winldr/wlregistry.c + * PURPOSE: Registry support functions + * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + */ + +/* INCLUDES ***************************************************************/ + +#include + +#define NDEBUG +#include + +/* FUNCTIONS **************************************************************/ + +BOOLEAN +WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath, + IN LPCSTR HiveName) +{ + PFILE FileHandle; + CHAR FullHiveName[256]; + BOOLEAN Status; + ULONG HiveFileSize; + ULONG_PTR HiveDataPhysical; + PVOID HiveDataVirtual; + + /* Concatenate path and filename to get the full name */ + strcpy(FullHiveName, DirectoryPath); + strcat(FullHiveName, HiveName); + //Print(L"Loading %s...\n", FullHiveName); + FileHandle = FsOpenFile(FullHiveName); + + if (FileHandle == NULL) + { + UiMessageBox("Opening hive file failed!"); + return FALSE; + } + + /* Get the file length */ + HiveFileSize = FsGetFileSize(FileHandle); + + if (HiveFileSize == 0) + { + FsCloseFile(FileHandle); + UiMessageBox("Hive file has 0 size!"); + return FALSE; + } + + /* Round up the size to page boundary and alloc memory */ + HiveDataPhysical = (ULONG_PTR)MmAllocateMemory( + MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT); + + if (HiveDataPhysical == 0) + { + FsCloseFile(FileHandle); + UiMessageBox("Unable to alloc memory for a hive!"); + return FALSE; + } + + /* Convert address to virtual */ + HiveDataVirtual = (PVOID)(KSEG0_BASE | HiveDataPhysical); + + /* Fill LoaderBlock's entries */ + LoaderBlock->RegistryLength = HiveFileSize; + LoaderBlock->RegistryBase = HiveDataVirtual; + + /* Finally read from file to the memory */ + Status = FsReadFile(FileHandle, HiveFileSize, NULL, (PVOID)HiveDataPhysical); + FsCloseFile(FileHandle); + if (!Status) + { + UiMessageBox("Unable to read from hive file!"); + return FALSE; + } + + return TRUE; +} + + +BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath) +{ + CHAR SearchPath[1024]; + BOOLEAN Status; + + // There is a simple logic here: try to load usual hive (system), if it + // fails, then give system.alt a try, and finally try a system.sav + + // FIXME: For now we only try system + strcpy(SearchPath, DirectoryPath); + strcat(SearchPath, "SYSTEM32\\CONFIG\\"); + Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM"); + + // Fail if failed... + if (!Status) + return FALSE; + + + + return TRUE; +} From e2295b6e85ab8e2ed659b9c8626fa1c7d9c6f8a3 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Fri, 6 Oct 2006 20:52:50 +0000 Subject: [PATCH 484/488] - Fix calls to HvInitializeHive due to my last patch. Proof that Fireball doesn't properly test his commits... I broke Freeldr building before his commit, yet he commited it anyway even though freeldr couldn't build ;). Just kidding. svn path=/trunk/; revision=24428 --- reactos/boot/freeldr/freeldr/reactos/binhive.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/reactos/binhive.c b/reactos/boot/freeldr/freeldr/reactos/binhive.c index 6e564e6146c..520e4f4d9be 100644 --- a/reactos/boot/freeldr/freeldr/reactos/binhive.c +++ b/reactos/boot/freeldr/freeldr/reactos/binhive.c @@ -28,6 +28,7 @@ /* FUNCTIONS ****************************************************************/ static PVOID +NTAPI CmpAllocate (ULONG Size, BOOLEAN Paged) { return MmAllocateMemory(Size); @@ -35,6 +36,7 @@ CmpAllocate (ULONG Size, BOOLEAN Paged) static VOID +NTAPI CmpFree (PVOID Ptr) { return MmFreeMemory(Ptr); @@ -714,7 +716,7 @@ RegImportBinaryHive(PCHAR ChunkBase, DbgPrint((DPRINT_REGISTRY, "RegImportBinaryHive(%x, %u) called\n",ChunkBase,ChunkSize)); CmHive = CmpAllocate(sizeof(EREGISTRY_HIVE), TRUE); - Status = HvInitialize (&CmHive->Hive, HV_OPERATION_MEMORY_INPLACE, + Status = HvInitialize (&CmHive->Hive, HV_OPERATION_MEMORY_INPLACE, 0, 0, (ULONG_PTR)ChunkBase, 0, CmpAllocate, CmpFree, NULL, NULL, NULL, NULL, NULL); @@ -813,7 +815,7 @@ RegExportBinaryHive(PCWSTR KeyName, DbgPrint((DPRINT_REGISTRY, "Creating binary hardware hive\n")); CmHive = CmpAllocate(sizeof(EREGISTRY_HIVE), TRUE); - Status = HvInitialize (&CmHive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, + Status = HvInitialize (&CmHive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0, CmpAllocate, CmpFree, NULL, NULL, NULL, NULL, NULL); Hive = &CmHive->Hive; From 41c87410411f469d4d7c370d21866dc8fa258884 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 6 Oct 2006 21:20:36 +0000 Subject: [PATCH 485/488] - Load and initialize in-memory registry - Query NLS file names from registry instead of hardcoding - Move loading of NLS data to WinLdrLoadAndScanSystemHive() svn path=/trunk/; revision=24429 --- reactos/boot/freeldr/freeldr/windows/winldr.c | 165 +--------- .../boot/freeldr/freeldr/windows/wlregistry.c | 288 +++++++++++++++++- 2 files changed, 288 insertions(+), 165 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index 6f668f65e5a..bef20f48ccd 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -29,162 +29,6 @@ VOID DumpMemoryAllocMap(VOID); VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); -BOOLEAN -WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, - IN LPCSTR DirectoryPath, - IN LPCSTR AnsiFileName, - IN LPCSTR OemFileName, - IN LPCSTR LanguageFileName) -{ - CHAR FileName[255]; - PFILE AnsiFileHandle; - PFILE OemFileHandle; - PFILE LanguageFileHandle; - ULONG AnsiFileSize, OemFileSize, LanguageFileSize; - ULONG TotalSize; - ULONG_PTR NlsDataBase; - PVOID NlsVirtual; - BOOLEAN Status, AnsiEqualsOem = FALSE; - - /* There may be a case, when OEM and ANSI page coincide */ - if (!strcmp(AnsiFileName, OemFileName)) - AnsiEqualsOem = TRUE; - - /* Open file with ANSI and store its size */ - //Print(L"Loading %s...\n", Filename); - strcpy(FileName, DirectoryPath); - strcat(FileName, AnsiFileName); - AnsiFileHandle = FsOpenFile(FileName); - - if (AnsiFileHandle == NULL) - goto Failure; - - AnsiFileSize = FsGetFileSize(AnsiFileHandle); - DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize)); - FsCloseFile(AnsiFileHandle); - - /* Open OEM file and store its length */ - if (AnsiEqualsOem) - { - OemFileSize = 0; - } - else - { - //Print(L"Loading %s...\n", Filename); - strcpy(FileName, DirectoryPath); - strcat(FileName, OemFileName); - OemFileHandle = FsOpenFile(FileName); - - if (OemFileHandle == NULL) - goto Failure; - - OemFileSize = FsGetFileSize(OemFileHandle); - FsCloseFile(OemFileHandle); - } - DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize)); - - /* And finally open the language codepage file and store its length */ - //Print(L"Loading %s...\n", Filename); - strcpy(FileName, DirectoryPath); - strcat(FileName, LanguageFileName); - LanguageFileHandle = FsOpenFile(FileName); - - if (LanguageFileHandle == NULL) - goto Failure; - - LanguageFileSize = FsGetFileSize(LanguageFileHandle); - FsCloseFile(LanguageFileHandle); - DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize)); - - /* Sum up all three length, having in mind that every one of them - must start at a page boundary => thus round up each file to a page */ - TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + - MM_SIZE_TO_PAGES(OemFileSize) + - MM_SIZE_TO_PAGES(LanguageFileSize); - - NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); - - if (NlsDataBase == 0) - goto Failure; - - NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase); - LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; - LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + - (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); - LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + - (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + - (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); - - /* Ansi and OEM data are the same - just set pointers to the same area */ - if (AnsiEqualsOem) - LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; - - - /* Now actually read the data into memory, starting with Ansi file */ - strcpy(FileName, DirectoryPath); - strcat(FileName, AnsiFileName); - AnsiFileHandle = FsOpenFile(FileName); - - if (AnsiFileHandle == NULL) - goto Failure; - - Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData)); - - if (!Status) - goto Failure; - - FsCloseFile(AnsiFileHandle); - - /* OEM now, if it doesn't equal Ansi of course */ - if (!AnsiEqualsOem) - { - strcpy(FileName, DirectoryPath); - strcat(FileName, OemFileName); - OemFileHandle = FsOpenFile(FileName); - - if (OemFileHandle == NULL) - goto Failure; - - Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData)); - - if (!Status) - goto Failure; - - FsCloseFile(AnsiFileHandle); - } - - /* finally the language file */ - strcpy(FileName, DirectoryPath); - strcat(FileName, LanguageFileName); - LanguageFileHandle = FsOpenFile(FileName); - - if (LanguageFileHandle == NULL) - goto Failure; - - Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData)); - - if (!Status) - goto Failure; - - FsCloseFile(LanguageFileHandle); - - // - // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK - // Should go to WinLdrLoadOemHalFont(), when it will be implemented - // - LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); - - /* Convert NlsTables address to VA */ - LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); - - return TRUE; - -Failure: - //UiMessageBox("Error reading NLS file %s\n", Filename); - UiMessageBox("Error reading NLS file!"); - return FALSE; -} - void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock) { PCONFIGURATION_COMPONENT_DATA ConfigurationRoot; @@ -393,7 +237,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) ULONG BootDevice; PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA; KERNEL_ENTRY_POINT KiSystemStartup; - PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE; + PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL; // Mm-related things PVOID GdtIdt; ULONG PcrBasePage=0; @@ -494,13 +338,6 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath); DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status)); - /* FIXME: Load NLS data, should be moved to WinLdrLoadAndScanSystemHive() */ - strcpy(SearchPath, BootPath); - strcat(SearchPath, "SYSTEM32\\"); - Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, - "c_1252.nls", "c_437.nls", "l_intl.nls"); - DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status)); - /* FIXME: Load OEM HAL font, should be moved to WinLdrLoadAndScanSystemHive() */ /* Load boot drivers */ diff --git a/reactos/boot/freeldr/freeldr/windows/wlregistry.c b/reactos/boot/freeldr/freeldr/windows/wlregistry.c index c14fd64bdf2..3498c3149a3 100644 --- a/reactos/boot/freeldr/freeldr/windows/wlregistry.c +++ b/reactos/boot/freeldr/freeldr/windows/wlregistry.c @@ -13,6 +13,14 @@ #define NDEBUG #include +BOOLEAN +WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath, + IN LPCSTR AnsiFileName, + IN LPCSTR OemFileName, + IN LPCSTR LanguageFileName); + + /* FUNCTIONS **************************************************************/ BOOLEAN @@ -79,11 +87,99 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, return TRUE; } +// Queries registry for those three file names +BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName, + LPSTR OemName, + LPSTR LangName) +{ + LONG rc = ERROR_SUCCESS; + FRLDRHKEY hKey; + WCHAR szIdBuffer[80]; + WCHAR NameBuffer[80]; + ULONG BufferSize; + + /* open the codepage key */ + rc = RegOpenKey(NULL, + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage", + &hKey); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't open CodePage registry key"); + return FALSE; + } + + /* get ANSI codepage */ + BufferSize = sizeof(szIdBuffer); + rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't get ACP NLS setting"); + return FALSE; + } + + BufferSize = sizeof(NameBuffer); + rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable"); + return FALSE; + } + sprintf(AnsiName, "%S", NameBuffer); + + /* get OEM codepage */ + BufferSize = sizeof(szIdBuffer); + rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting"); + return FALSE; + } + + BufferSize = sizeof(NameBuffer); + rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable"); + return FALSE; + } + sprintf(OemName, "%S", NameBuffer); + + /* open the language key */ + rc = RegOpenKey(NULL, + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language", + &hKey); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't open Language registry key"); + return FALSE; + } + + /* get the Unicode case table */ + BufferSize = sizeof(szIdBuffer); + rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't get Language Default setting"); + return FALSE; + } + + BufferSize = sizeof(NameBuffer); + rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Language Default setting exists, but isn't readable"); + return FALSE; + } + sprintf(LangName, "%S", NameBuffer); + + return TRUE; +} BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath) { CHAR SearchPath[1024]; + CHAR AnsiName[256], OemName[256], LangName[256]; BOOLEAN Status; // There is a simple logic here: try to load usual hive (system), if it @@ -98,7 +194,197 @@ BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, if (!Status) return FALSE; - + // Initialize in-memory registry + RegInitializeRegistry(); + + // Import what was loaded + Status = RegImportBinaryHive((PCHAR)VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength); + if (!Status) + { + UiMessageBox("Importing binary hive failed!"); + return FALSE; + } + + // Initialize the 'CurrentControlSet' link + if (RegInitCurrentControlSet(FALSE) != ERROR_SUCCESS) + { + UiMessageBox("Initializing CurrentControlSet link failed!"); + return FALSE; + } + + Status = WinLdrGetNLSNames(AnsiName, OemName, LangName); + if (!Status) + { + UiMessageBox("Getting NLS names from registry failed!"); + return FALSE; + } + + DbgPrint((DPRINT_WINDOWS, "NLS data %s %s %s\n", AnsiName, OemName, LangName)); + + /* Load NLS data, should be moved to WinLdrLoadAndScanSystemHive() */ + strcpy(SearchPath, DirectoryPath); + strcat(SearchPath, "SYSTEM32\\"); + Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName); + DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status)); return TRUE; } + + +/* PRIVATE FUNCTIONS ******************************************************/ + +BOOLEAN +WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath, + IN LPCSTR AnsiFileName, + IN LPCSTR OemFileName, + IN LPCSTR LanguageFileName) +{ + CHAR FileName[255]; + PFILE AnsiFileHandle; + PFILE OemFileHandle; + PFILE LanguageFileHandle; + ULONG AnsiFileSize, OemFileSize, LanguageFileSize; + ULONG TotalSize; + ULONG_PTR NlsDataBase; + PVOID NlsVirtual; + BOOLEAN Status, AnsiEqualsOem = FALSE; + + /* There may be a case, when OEM and ANSI page coincide */ + if (!strcmp(AnsiFileName, OemFileName)) + AnsiEqualsOem = TRUE; + + /* Open file with ANSI and store its size */ + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, AnsiFileName); + AnsiFileHandle = FsOpenFile(FileName); + + if (AnsiFileHandle == NULL) + goto Failure; + + AnsiFileSize = FsGetFileSize(AnsiFileHandle); + DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize)); + FsCloseFile(AnsiFileHandle); + + /* Open OEM file and store its length */ + if (AnsiEqualsOem) + { + OemFileSize = 0; + } + else + { + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, OemFileName); + OemFileHandle = FsOpenFile(FileName); + + if (OemFileHandle == NULL) + goto Failure; + + OemFileSize = FsGetFileSize(OemFileHandle); + FsCloseFile(OemFileHandle); + } + DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize)); + + /* And finally open the language codepage file and store its length */ + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, LanguageFileName); + LanguageFileHandle = FsOpenFile(FileName); + + if (LanguageFileHandle == NULL) + goto Failure; + + LanguageFileSize = FsGetFileSize(LanguageFileHandle); + FsCloseFile(LanguageFileHandle); + DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize)); + + /* Sum up all three length, having in mind that every one of them + must start at a page boundary => thus round up each file to a page */ + TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + + MM_SIZE_TO_PAGES(OemFileSize) + + MM_SIZE_TO_PAGES(LanguageFileSize); + + NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); + + if (NlsDataBase == 0) + goto Failure; + + NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase); + LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; + LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); + LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + + (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); + + /* Ansi and OEM data are the same - just set pointers to the same area */ + if (AnsiEqualsOem) + LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; + + + /* Now actually read the data into memory, starting with Ansi file */ + strcpy(FileName, DirectoryPath); + strcat(FileName, AnsiFileName); + AnsiFileHandle = FsOpenFile(FileName); + + if (AnsiFileHandle == NULL) + goto Failure; + + Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(AnsiFileHandle); + + /* OEM now, if it doesn't equal Ansi of course */ + if (!AnsiEqualsOem) + { + strcpy(FileName, DirectoryPath); + strcat(FileName, OemFileName); + OemFileHandle = FsOpenFile(FileName); + + if (OemFileHandle == NULL) + goto Failure; + + Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(AnsiFileHandle); + } + + /* finally the language file */ + strcpy(FileName, DirectoryPath); + strcat(FileName, LanguageFileName); + LanguageFileHandle = FsOpenFile(FileName); + + if (LanguageFileHandle == NULL) + goto Failure; + + Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(LanguageFileHandle); + + // + // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK + // Should go to WinLdrLoadOemHalFont(), when it will be implemented + // + LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); + + /* Convert NlsTables address to VA */ + LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); + + return TRUE; + +Failure: + //UiMessageBox("Error reading NLS file %s\n", Filename); + UiMessageBox("Error reading NLS file!"); + return FALSE; +} From 2db2156bb36457011abd7ac240bcfc072022bd85 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Fri, 6 Oct 2006 21:59:42 +0000 Subject: [PATCH 486/488] Fixed control apps windows, Let me known if it create any regress. svn path=/trunk/; revision=24430 --- reactos/subsystems/win32/win32k/ntuser/winpos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/winpos.c b/reactos/subsystems/win32/win32k/ntuser/winpos.c index 765e1299084..360f7a69015 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winpos.c +++ b/reactos/subsystems/win32/win32k/ntuser/winpos.c @@ -1221,7 +1221,7 @@ co_WinPosSetWindowPos( } if (RgnType != ERROR && RgnType != NULLREGION) { - if (Window->Parent) + if ((Window->Parent == UserGetDesktopWindow()) && (Window->Style & WS_VISIBLE)) { NtGdiOffsetRgn(DirtyRgn, Window->WindowRect.left - Window->Parent->ClientRect.left, @@ -1229,7 +1229,7 @@ co_WinPosSetWindowPos( co_UserRedrawWindow(Window->Parent, NULL, DirtyRgn, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); } - else + else { NtGdiOffsetRgn(DirtyRgn, Window->WindowRect.left - Window->ClientRect.left, From b53f1795838bc439eb851a6430f07c8639da01b6 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Fri, 6 Oct 2006 23:11:49 +0000 Subject: [PATCH 487/488] - Fix calls to HvInitializeHive svn path=/trunk/; revision=24431 --- reactos/tools/mkhive/cmi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/reactos/tools/mkhive/cmi.c b/reactos/tools/mkhive/cmi.c index 71550c7895f..111e0f9daf9 100644 --- a/reactos/tools/mkhive/cmi.c +++ b/reactos/tools/mkhive/cmi.c @@ -27,6 +27,7 @@ #include "mkhive.h" static PVOID +NTAPI CmpAllocate( IN SIZE_T Size, IN BOOLEAN Paged) @@ -35,6 +36,7 @@ CmpAllocate( } static VOID +NTAPI CmpFree( IN PVOID Ptr) { @@ -42,6 +44,7 @@ CmpFree( } static BOOLEAN +NTAPI CmpFileRead( IN PHHIVE RegistryHive, IN ULONG FileType, @@ -54,6 +57,7 @@ CmpFileRead( } static BOOLEAN +NTAPI CmpFileWrite( IN PHHIVE RegistryHive, IN ULONG FileType, @@ -69,6 +73,7 @@ CmpFileWrite( } static BOOLEAN +NTAPI CmpFileSetSize( IN PHHIVE RegistryHive, IN ULONG FileType, @@ -79,6 +84,7 @@ CmpFileSetSize( } static BOOLEAN +NTAPI CmpFileFlush( IN PHHIVE RegistryHive, IN ULONG FileType) @@ -102,7 +108,7 @@ CmiInitializeTempHive( Status = HvInitialize( &Hive->Hive, - HV_OPERATION_CREATE_HIVE, 0, 0, + HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0, CmpAllocate, CmpFree, CmpFileRead, CmpFileWrite, CmpFileSetSize, CmpFileFlush, NULL); From a40bc5ff5ffc62a8393d8ad289431c854d9ccab7 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 7 Oct 2006 13:07:25 +0000 Subject: [PATCH 488/488] - Add structure for describing boot-loaded drivers svn path=/trunk/; revision=24432 --- reactos/include/reactos/arc/arc.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/reactos/include/reactos/arc/arc.h b/reactos/include/reactos/arc/arc.h index 1ebad32003b..f91bde3dddb 100644 --- a/reactos/include/reactos/arc/arc.h +++ b/reactos/include/reactos/arc/arc.h @@ -65,6 +65,14 @@ typedef struct _MEMORY_ALLOCATION_DESCRIPTOR ULONG PageCount; } MEMORY_ALLOCATION_DESCRIPTOR, *PMEMORY_ALLOCATION_DESCRIPTOR; +typedef struct _BOOT_DRIVER_LIST_ENTRY +{ + LIST_ENTRY ListEntry; + UNICODE_STRING FilePath; + UNICODE_STRING RegistryPath; + struct _LDR_DATA_TABLE_ENTRY *DataTableEntry; +} BOOT_DRIVER_LIST_ENTRY, *PBOOT_DRIVER_LIST_ENTRY; + typedef struct _CONFIGURATION_COMPONENT { CONFIGURATION_CLASS Class;

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 Bw(tM| delta 32696 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 VPM<>y43gVwy1FuRHQn;a{{R9v7KZ=; delta 4892 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 Y_}k0qb$tE;D|gOM3$y*XikcVyA3}{bB>(^b diff --git a/reactos/media/fonts/DejaVuSerifCondensed-Oblique.ttf b/reactos/media/fonts/DejaVuSerifCondensed-Oblique.ttf index 89c7c16c1ab96e052bb0124394787964516cad86..71aee060a43e1dbb283ab536fe7d331392630cb9 100644 GIT binary patch delta 5494 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 delta 4585 zcmai03sh9q8vge_=gc6FafZi0MKLqH5w!*aM6a(fyDJx!H?37(gLD9uSA&`cHM-K& z?3ydZ!y;enE?0}YA|>kH>2_T!RI(D~F#;ljLbq<@b-BE)(gbF>|2}6A3`z-W&iVG< z|M~vM{{MgPsvG|M2mE*29eyVOtj_~LR$gg-(GQ#c*NEf&INq6`TUH8M{D+hT90%qX zZp_R0Vjv2~sX$KcEwJUT{K5Fmav(Rq#`UxUoCtbR=MUr-4k4zXXzhk0TU&;390L&f z#u}Twc-e|2X+T4c07M)uELoAe#!-9mEYRd<0d$LsayOI)yzaLEXy#!gFcp>9H~dL> z;VOc^u*Bl3!H?`DmD_yrya}#LoH2`UO zslBB1)~i2!1+;z<0BHq+tbvF&;G4oM5Mb3OrDXCWgznj74buYA043TttE|o{E0MPu zC1lwuHlnNszcNoEW`kMU;#}}KSuZV>Mg(cA6pJJfZZI1p$uX=k-R@JU$JQ`<;rNw+ z5`|*@Pq5@NixI8h<8~ZuXzt{0_ZiG9jHR1 z&dX~XNCJ`M11K#iMDkg6=9dOyK)R7+chU5qDIiS6KK$x%&zX4@lycMW+6)50Vk8hS2UieO?Skm}tx z>`WL98qv^?B+KY#(3(L_(QIiAD#s*@i) zLlWeyGbCM7$mC6DNQ}AU_dgQ$$Wzae$VflXju7chDIO+42s{Y!Fdfoi4lHE3;XXqa zKHeRdmS|0$lk(WZ!mBBX)2F`h=<2ZWhM@!s+I-R_;iDdh+JYxRJeN7}QNn(D~)iFQn5cr1~XJ%&3 zG?rIalcI#U#Q6BcxZasF!o$MC zB&Wem8*+MmEgj?Z10z5PBSd2jUP~RSv!f|8cy+v`G}N=XAt$GSI6Sj`d0CZkV-;e; z+(&~Abey%)13XbXR^Q1>9E{iD+5DTtfp9+-7>@!o+U&JjHF_)*EY9w~{Z>Hkwtmcb zhlIJVD4Cd@E}4k+E~Bvxct+@#SiD&1N*)<_1|6$YGUs+DW{uJ=#^eCqutgiJ;j|IU z7xP}|Wa*_zVhJ{KedLZ5muyiy+tyRxq$vE^ZnX+#$+XWgbh7MgLCt0m{W|KEg4W<;Bb~BI@Sgv2G5JNEOqwE);7{MRYHqcYc#MFRxKDaYP3>UsmUfk z>>}a3MJ#fW2!piR+X+_jKDo|CP8+?)pTIVa9i+-ZAU|`S7#$O@Nshq*`n>#I@iGunoU zMk@+tDOl}Wn1}I(I}QtyTwdY17Di3(zAzH1rlF_3yu!C*OLOISJ4slcud@5^Ru-G4 z_Hpbvs?PAclvqzsM0qHDh@H<;n+tG*Qj+(>5+*f>6i57Vm>RNdZznCu8_HjQoT7oL?3L@%KB8Lh#lvfB2 zR60I_s41`uuWqqjkx9qWqXVoDiGpylz67TOZgGOZ=6Wm(G` zEr(l#wfQT&G<&WOh-D&Au-dWw*bHVRI+J!9_y1R7Cx}NB&>NWlT=^SfW}-raq&`=?9yUz&UA?MpS6KD%_bN8huo$KJEO$JNu_OM4S~YkGgW zY`y&173-C%zKp(Ief#@deSQ5A{R#b<{n`Bm{agAE_J7)cMsCcc)BOFP#sp#6BFMv; z^Z|MLOloxgc_yu-&Z~22A#uL-7&T~wxq?Qn{v%!B2%t}4O|U-=MAAx*{lGvwISzma zg&2;5Chak<=2!=*rUH)j5NL98Yyg94K*dNLVH)I^z$Ei#jw#}Lh8Fu~m_=fvf<+{aG_T~C8Ct_J1+Dos z#{znv#IXpGmTeHtJP?V53;*T|80zRpIM#w8`W^Y?lXSszMw*Uok%*HpQ8MU@9Q%O< zdx$z80GV`v%>YD)5YN}JEbleSgGrup`DD++9oZ7VBVSDedMUqfjdEVS8* WO)uMR>(X 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 N=yJ#WrF6;s{{wQ=>YxAs delta 4625 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 diff --git a/reactos/media/fonts/doc/DejaVu_NEWS.txt b/reactos/media/fonts/doc/DejaVu_NEWS.txt index b8608983b15..33dab108589 100644 --- a/reactos/media/fonts/doc/DejaVu_NEWS.txt +++ b/reactos/media/fonts/doc/DejaVu_NEWS.txt @@ -1,3 +1,46 @@ +Changes from 2.9 to 2.10: +- added U+0242, U+024A-U+024B, U+024E-U+024F, U+037C-U+037D, U+0E3F, + U+1D2C-U+1D2E, U+1D30-U+1D42, U+1D5D-U+1D6A, U+1D78, U+1DB8, + U+2090-U+2094, U+20D0-U+20D1, U+2C60-U+2C66, U+2C6B-U+2C6C, U+2C74 and + U+FB29 to Sans (by Gee Fung Sit) +- added Lao glyphs : U+0E81-0E82, U+E084, U+0E87-0E88, U+0E8A, U+0E8D, + U+0E94-0E97, U+0E99-0E9F, U+0EA1-0EA3, U+0EA5, U+0EA7, U+0EAA-0EAB, + U+0EAD-0EB9, U+0EBB-0EBD, U+0EC0-0EC4, U+0EC6, U+0EC8-0ECD, U+0EDC-0EDD + (by RĂ©my Oudompheng) +- fixed U+0193 not showing in Windows (bug #7897) (by Ben Laenen) +- changes to U+222B-222D in Sans Mono (by RĂ©my Oudompheng) +- ported the three remaining currency symbols from Arev (U+20B0, + U+20B2-U+20B3), and replaced one (U+20AF) in Sans (by Lars Naesbye + Christensen) +- corrected U+20A5 in Sans (by Gee Fung Sit) +- merged Double-Struck Letters from Arev: U+2102, U+210D, U+2115, + U+2119-U+211A, U+2124, U+213C-U+2140 (by Gee Fung Sit) +- added U+2308-U+230B and U+2329-U+232A to Sans Mono and Serif faces, + fixed incorrect direction of U+2329 in Sans faces, and improved + U+2308-U+230B in Sans faces per Ben Laenen's suggestions (by David + Lawrence Ramsey) +- added U+06D5 and final form of it (needed for Kurdish) (by Ben Laenen) +- added two special glyphs U+F000 and U+F001 in Sans Book that show the + current ppem size (horizontal and vertical) (by Ben Laenen) +- added U+2318 and U+2325 to Sans Mono faces, based on the Sans versions + (by David Lawrence Ramsey) +- added U+2B14-U+2B1A to all faces except Sans ExtraLight (by David + Lawrence Ramsey) +- respaced all Geometric Shapes characters in Serif faces to match those + in Sans faces again, respaced U+23CF in Sans, Sans ExtraLight, and + Serif faces to match U+25A0 (or Sans in Sans ExtraLight's case) again, + and respaced U+2B12-U+2B13 in Sans and Serif faces to match U+25A1 + again (by David Lawrence Ramsey) +- corrected width of Modifier Small Letters U+1D43-1D5B in Sans Oblique + and U+1D9B-U+1DBF in Sans Oblique and Sans Bold Oblique (by Gee Fung Sit) +- added a bunch of glyphs to Sans ExtraLight (see SVN for details) (by + Gee Fung Sit) +- adjusted Cyrillic descenders in Sans ExtraLight to sync with Sans (by + Gee Fung Sit) +- added U+0242, U+0245 to Serif (by Gee Fung Sit) +- replaced the SHPIX routines which gave them bad spacing at certain + sizes in FreeType for A, V, Z, v and z in Sans Bold (by Ben Laenen) + Changes from 2.8 to 2.9: - DejaVuSansExtraLight.sfd: changed family name from "DejaVu Sans" to diff --git a/reactos/media/fonts/doc/DejaVu_README.txt b/reactos/media/fonts/doc/DejaVu_README.txt index da7d84199f2..96e88b3a9a1 100644 --- a/reactos/media/fonts/doc/DejaVu_README.txt +++ b/reactos/media/fonts/doc/DejaVu_README.txt @@ -1,4 +1,4 @@ -DejaVu fonts 2.9 (c)2004-2006 DejaVu fonts team +DejaVu fonts 2.10 (c)2004-2006 DejaVu fonts team ----------------------------------------------- The DejaVu fonts are a font family based on the Bitstream Vera Fonts @@ -50,8 +50,10 @@ U+01ba, U+01bf, U+01f7, U+021c, U+021d, U+0220, U+0222, U+0223, U+02b9, U+02ba, U+02bd, U+02c2, U+02c3, U+02c4, U+02c5, U+02d4, U+02d5, U+02d7, U+02ec, U+02ed, U+02ee, U+0346-034e, U+0360, U+0362, U+03e2-03ef, U+0460-0463, U+0466-0486, U+0488-0489, U+04a8-04a9, -U+0500-050f, U+2055-205e, U+210f, U+2111, U+2113, U+2118, -U+211c-0211d, U+2135, U+2295-2298, U+2308-230b, U+2701-2704, +U+0500-050f, U+2055-205e, U+20B0, U+20B2-20B3, U+2102, U+210D, U+210f, +U+2111, U+2113, U+2115, U+2118-U+211A, U+211c-211d, U+2124,U+2135, +U+213C-U+2140, U+2295-2298, U+2308-230b, U+26A2-U+26B1, U+2701-2704, U+2706-2709, U+270c-274b, U+2758-275a, U+2761-2775, U+2780-2794, U+2798-27af, U+27b1-27be, U+fb05-fb06 -$Id: README 1072 2006-08-13 12:10:14Z ben_laenen $ + +$Id: README 1127 2006-09-06 14:31:14Z ben_laenen $ diff --git a/reactos/media/fonts/doc/DejaVu_langcover.txt b/reactos/media/fonts/doc/DejaVu_langcover.txt index 51750b389eb..e299b5a862f 100644 --- a/reactos/media/fonts/doc/DejaVu_langcover.txt +++ b/reactos/media/fonts/doc/DejaVu_langcover.txt @@ -1,5 +1,5 @@ This is the language coverage file for DejaVu fonts -($Id: langcover.txt 1068 2006-08-08 21:22:42Z ben_laenen $) +($Id$) Sans Serif Sans Mono aa Afar 100% (62/62) 100% (62/62) 100% (62/62) @@ -7,6 +7,7 @@ ab Abkhazia 100% (90/90) 93% (84/90) af Afrikaans 100% (69/69) 100% (69/69) 100% (69/69) am Amharic (0/264) (0/264) (0/264) ar Arabic 100% (125/125) (0/125) (0/125) +as (0/89) (0/89) (0/89) ast Asturian 100% (72/72) 100% (72/72) 100% (72/72) ava Avaric 100% (67/67) 100% (67/67) 100% (67/67) ay Aymara 100% (60/60) 100% (60/60) 100% (60/60) @@ -30,25 +31,25 @@ ce Chechen 100% (67/67) 100% (67/67) ch Chamorro 100% (58/58) 100% (58/58) 100% (58/58) chm Mari (Lower Cheremis / Upper Cheremis) 100% (76/76) 100% (76/76) 97% (74/76) chr Cherokee (0/85) (0/85) (0/85) -co Corsican 100% (84/84) 100% (84/84) 100% (84/84) +co Corsican 100% (85/85) 100% (85/85) 100% (85/85) cs Czech 100% (82/82) 100% (82/82) 100% (82/82) cu Old Church Slavonic 100% (103/103) 78% (81/103) 74% (77/103) cv Chuvash 100% (74/74) 100% (74/74) 100% (74/74) cy Welsh 100% (78/78) 100% (78/78) 100% (78/78) da Danish 100% (70/70) 100% (70/70) 100% (70/70) -de German 100% (59/59) 100% (59/59) 100% (59/59) +de German 100% (60/60) 100% (60/60) 100% (60/60) dz Dzongkha (0/95) (0/95) (0/95) -el Greek 100% (69/69) 100% (69/69) 100% (69/69) -en English 100% (72/72) 100% (72/72) 100% (72/72) +el Greek 100% (70/70) 100% (70/70) 100% (70/70) +en English 100% (73/73) 100% (73/73) 100% (73/73) eo Esperanto 100% (64/64) 100% (64/64) 100% (64/64) -es Spanish 100% (66/66) 100% (66/66) 100% (66/66) +es Spanish 100% (67/67) 100% (67/67) 100% (67/67) et Estonian 100% (64/64) 100% (64/64) 100% (64/64) eu Basque 100% (56/56) 100% (56/56) 100% (56/56) fa Persian 100% (129/129) (0/129) (0/129) -fi Finnish 100% (62/62) 100% (62/62) 100% (62/62) +fi Finnish 100% (63/63) 100% (63/63) 100% (63/63) fj Fijian 100% (52/52) 100% (52/52) 100% (52/52) fo Faroese 100% (68/68) 100% (68/68) 100% (68/68) -fr French 100% (84/84) 100% (84/84) 100% (84/84) +fr French 100% (85/85) 100% (85/85) 100% (85/85) ful Fulah (Fula) 100% (62/62) 100% (62/62) 100% (62/62) fur Friulian 100% (66/66) 100% (66/66) 100% (66/66) fy Frisian 100% (75/75) 100% (75/75) 100% (75/75) @@ -74,10 +75,10 @@ ie Interlingue 100% (52/52) 100% (52/52) ik Inupiaq (Inupiak, Eskimo) 100% (68/68) 100% (68/68) 100% (68/68) io Ido 100% (52/52) 100% (52/52) 100% (52/52) is Icelandic 100% (70/70) 100% (70/70) 100% (70/70) -it Italian 100% (72/72) 100% (72/72) 100% (72/72) +it Italian 100% (73/73) 100% (73/73) 100% (73/73) iu Inuktitut (0/161) (0/161) (0/161) ja Japanese (0/6538) (0/6538) (0/6538) -ka Georgian (0/34) (0/34) (0/34) +ka Georgian (0/33) (0/33) (0/33) kaa Kara-Kalpak (Karakalpak) 100% (78/78) 100% (78/78) 100% (78/78) ki Kikuyu 100% (56/56) 100% (56/56) 100% (56/56) kk Kazakh 100% (77/77) 100% (77/77) 100% (77/77) @@ -96,7 +97,8 @@ ky Kirgiz 100% (70/70) 100% (70/70) la Latin 100% (68/68) 100% (68/68) 100% (68/68) lb Luxembourgish (Letzeburgesch) 100% (75/75) 100% (75/75) 100% (75/75) lez Lezghian (Lezgian) 100% (67/67) 100% (67/67) 100% (67/67) -lo Lao (0/65) (0/65) (0/65) +ln Lingala 100% (81/81) 100% (81/81) 100% (81/81) +lo Lao 84% (55/65) (0/65) (0/65) lt Lithuanian 100% (70/70) 100% (70/70) 100% (70/70) lv Latvian 100% (78/78) 100% (78/78) 100% (78/78) mg Malagasy 100% (56/56) 100% (56/56) 100% (56/56) @@ -112,7 +114,7 @@ my Burmese (Myanmar) (0/48) (0/48) nb Norwegian Bokmal 100% (70/70) 100% (70/70) 100% (70/70) nds Low Saxon 100% (59/59) 100% (59/59) 100% (59/59) ne Nepali (Devanagari script) (0/68) (0/68) (0/68) -nl Dutch 100% (82/82) 100% (82/82) 100% (82/82) +nl Dutch 100% (83/83) 100% (83/83) 100% (83/83) nn Norwegian Nynorsk 100% (76/76) 100% (76/76) 100% (76/76) no Norwegian (Bokmal) 100% (70/70) 100% (70/70) 100% (70/70) ny Chichewa 100% (54/54) 100% (54/54) 100% (54/54) @@ -124,7 +126,7 @@ pa Punjabi (Gurumukhi script) (0/63) (0/63) pl Polish 100% (70/70) 100% (70/70) 100% (70/70) ps-af Pashto in Afghanistan 83% (41/49) (0/49) (0/49) ps-pk Pashto in Pakistan 81% (40/49) (0/49) (0/49) -pt Portuguese 100% (82/82) 100% (82/82) 100% (82/82) +pt Portuguese 100% (83/83) 100% (83/83) 100% (83/83) rm Rhaeto-Romance (Romansch) 100% (66/66) 100% (66/66) 100% (66/66) ro Romanian 100% (62/62) 100% (62/62) 100% (62/62) ru Russian 100% (66/66) 100% (66/66) 100% (66/66) @@ -151,7 +153,7 @@ syr Syriac (0/45) (0/45) ta Tamil (0/48) (0/48) (0/48) te Telugu (0/80) (0/80) (0/80) tg Tajik 100% (78/78) 100% (78/78) 97% (76/78) -th Thai (0/87) (0/87) (0/87) +th Thai 1% (1/87) (0/87) (0/87) ti-er Eritrean Tigrinya (0/256) (0/256) (0/256) ti-et Ethiopian Tigrinya (0/282) (0/282) (0/282) tig Tigre (0/221) (0/221) (0/221) @@ -181,7 +183,7 @@ yi Yiddish 100% (27/27) (0/27) yo Yoruba 100% (119/119) 100% (119/119) 100% (119/119) zh-cn Chinese (simplified) 0% (2/6765) 0% (2/6765) 0% (1/6765) zh-hk Chinese Hong Kong Supplementary Character Set (0/2213) (0/2213) (0/2213) -zh-mo Chinese in Macau (0/13063) (0/13063) (0/13063) +zh-mo Chinese in Macau (0/2213) (0/2213) (0/2213) zh-sg Chinese in Singapore 0% (2/6765) 0% (2/6765) 0% (1/6765) zh-tw Chinese (traditional) (0/13063) (0/13063) (0/13063) zu Zulu 100% (52/52) 100% (52/52) 100% (52/52) diff --git a/reactos/media/fonts/doc/DejaVu_status.txt b/reactos/media/fonts/doc/DejaVu_status.txt index 4a74bedb31d..a755128856c 100644 --- a/reactos/media/fonts/doc/DejaVu_status.txt +++ b/reactos/media/fonts/doc/DejaVu_status.txt @@ -507,8 +507,8 @@ U+0234 uni0234 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+0235 uni0235 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+0236 uni0236 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+0237 dotlessj 1.5 -U+0238 uni0238 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) -U+0239 uni0239 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0238 uni0238 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+0239 uni0239 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) U+023a uni023A 2.3 U+023b uni023B 2.3 U+023c uni023C 2.3 @@ -517,15 +517,20 @@ U+023e uni023E 2.3 U+023f uni023F 2.3 U+0240 uni0240 2.3 U+0241 uni0241 2.3 +U+0242 uni0242 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) U+0243 uni0243 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+0244 uni0244 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+0245 uni0245 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0245 uni0245 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) U+0246 uni0246 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+0247 uni0247 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+0248 uni0248 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+0249 uni0249 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+024a uni024A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+024b uni024B 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+024c uni024C 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+024d uni024D 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+024e uni024E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+024f uni024F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+0250 uni0250 1.14 U+0251 uni0251 1.14 U+0252 uni0252 1.14 @@ -777,7 +782,9 @@ U+0362 uni0362 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+0374 uni0374 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) U+0375 uni0375 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) U+037a uni037A 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) -U+037b uni037B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+037b uni037B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+037c uni037C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans ExtraLight, Sans Oblique) +U+037d uni037D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans ExtraLight, Sans Oblique) U+037e uni037E 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) U+0384 tonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) U+0385 dieresistonos 1.14 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 1.15 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.2 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.4 (Sans ExtraLight) @@ -996,7 +1003,7 @@ U+045d uni045D 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Obliqu U+045e afii10110 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.4 (Sans ExtraLight) U+045f afii10193 1.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) 1.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold) 1.6 (Serif Bold Oblique, Serif Oblique) 1.7 (Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique) 2.5 (Sans ExtraLight) U+0460 uni0460 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+0461 uni0461 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0461 uni0461 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+0462 afii10146 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+0463 afii10194 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+0464 uni0464 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) @@ -1011,9 +1018,9 @@ U+046c uni046C 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+046d uni046D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+046e uni046E 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+046f uni046F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+0470 uni0470 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+0471 uni0471 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+0472 afii10147 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+0470 uni0470 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+0471 uni0471 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+0472 afii10147 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) U+0473 afii10195 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+0474 afii10148 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+0475 afii10196 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) @@ -1063,8 +1070,8 @@ U+04a0 uni04A0 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+04a1 uni04A1 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+04a2 uni04A2 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+04a3 uni04A3 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) -U+04a4 uni04A4 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) -U+04a5 uni04A5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04a4 uni04A4 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+04a5 uni04A5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) U+04a6 uni04A6 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+04a7 uni04A7 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+04a8 uni04A8 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) @@ -1079,8 +1086,8 @@ U+04b0 uni04B0 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+04b1 uni04B1 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+04b2 uni04B2 1.14 U+04b3 uni04B3 1.14 -U+04b4 uni04B4 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) -U+04b5 uni04B5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+04b4 uni04B4 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) +U+04b5 uni04B5 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) U+04b6 uni04B6 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+04b7 uni04B7 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+04b8 uni04B8 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) @@ -1224,9 +1231,9 @@ U+0569 uni0569 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+056a uni056A 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+056b uni056B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans ExtraLight) U+056c uni056C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+056d uni056D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+056d uni056D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+056e uni056E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+056f uni056F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+056f uni056F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+0570 uni0570 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) U+0571 uni0571 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+0572 uni0572 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) @@ -1242,11 +1249,11 @@ U+057b uni057B 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+057c uni057C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+057d uni057D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) U+057e uni057E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+057f uni057F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+057f uni057F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+0580 uni0580 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) U+0581 uni0581 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) U+0582 uni0582 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+0583 uni0583 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+0583 uni0583 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+0584 uni0584 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+0585 uni0585 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) U+0586 uni0586 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) @@ -1404,6 +1411,7 @@ U+06bf uni06BF 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed U+06c6 uni06C6 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) U+06cc uni06CC 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) U+06ce uni06CE 2.7 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+06d5 uni06D5 2.10 (Sans, Sans Bold) U+06f0 uni06F0 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) U+06f1 uni06F1 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) U+06f2 uni06F2 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) @@ -1414,26 +1422,82 @@ U+06f6 uni06F6 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed U+06f7 uni06F7 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) U+06f8 uni06F8 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) U+06f9 uni06F9 2.4 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold) +U+0e3f uni0E3F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e81 uni0E81 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e82 uni0E82 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e84 uni0E84 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e87 uni0E87 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e88 uni0E88 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e8a uni0E8A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e8d uni0E8D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e94 uni0E94 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e95 uni0E95 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e96 uni0E96 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e97 uni0E97 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e99 uni0E99 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e9a uni0E9A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e9b uni0E9B 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e9c uni0E9C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e9d uni0E9D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e9e uni0E9E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0e9f uni0E9F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ea1 uni0EA1 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ea2 uni0EA2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ea3 uni0EA3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ea5 uni0EA5 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ea7 uni0EA7 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eaa uni0EAA 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eab uni0EAB 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ead uni0EAD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eae uni0EAE 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eaf uni0EAF 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb0 uni0EB0 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb1 uni0EB1 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb2 uni0EB2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb3 uni0EB3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb4 uni0EB4 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb5 uni0EB5 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb6 uni0EB6 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb7 uni0EB7 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb8 uni0EB8 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eb9 uni0EB9 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ebb uni0EBB 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ebc uni0EBC 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ebd uni0EBD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ec0 uni0EC0 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ec1 uni0EC1 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ec2 uni0EC2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ec3 uni0EC3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ec4 uni0EC4 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ec6 uni0EC6 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ec8 uni0EC8 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ec9 uni0EC9 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0eca uni0ECA 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ecb uni0ECB 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ecc uni0ECC 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0ecd uni0ECD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0edc uni0EDC 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+0edd uni0EDD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+1d00 uni1D00 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+1d01 uni1D01 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+1d02 uni1D02 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) U+1d03 uni1D03 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d04 uni1D04 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d04 uni1D04 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+1d05 uni1D05 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+1d06 uni1D06 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+1d07 uni1D07 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+1d08 uni1D08 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+1d09 uni1D09 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) U+1d0a uni1D0A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d0b uni1D0B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d0b uni1D0B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+1d0c uni1D0C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d0d uni1D0D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d0e uni1D0E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d0f uni1D0F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d10 uni1D10 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d11 uni1D11 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d12 uni1D12 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d13 uni1D13 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d0d uni1D0D 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d0e uni1D0E 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d0f uni1D0F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d10 uni1D10 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d11 uni1D11 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d12 uni1D12 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d13 uni1D13 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+1d14 uni1D14 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) U+1d16 uni1D16 2.3 U+1d17 uni1D17 2.3 @@ -1445,16 +1509,38 @@ U+1d1c uni1D1C 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+1d1d uni1D1D 2.3 U+1d1e uni1D1E 2.3 U+1d1f uni1D1F 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) -U+1d20 uni1D20 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d21 uni1D21 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d22 uni1D22 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d20 uni1D20 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d21 uni1D21 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d22 uni1D22 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+1d23 uni1D23 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d26 uni1D26 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d27 uni1D27 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+1d28 uni1D28 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d26 uni1D26 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d27 uni1D27 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) +U+1d28 uni1D28 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+1d29 uni1D29 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+1d2a uni1D2A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+1d2b uni1D2B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+1d2c uni1D2C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d2d uni1D2D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d2e uni1D2E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d30 uni1D30 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d31 uni1D31 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d32 uni1D32 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d33 uni1D33 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d34 uni1D34 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d35 uni1D35 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d36 uni1D36 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d37 uni1D37 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d38 uni1D38 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d39 uni1D39 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d3a uni1D3A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d3b uni1D3B 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d3c uni1D3C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d3d uni1D3D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d3e uni1D3E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d3f uni1D3F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d40 uni1D40 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d41 uni1D41 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d42 uni1D42 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+1d43 uni1D43 2.3 U+1d44 uni1D44 2.3 U+1d45 uni1D45 2.3 @@ -1480,7 +1566,23 @@ U+1d58 uni1D58 2.3 U+1d59 uni1D59 2.3 U+1d5a uni1D5A 2.3 U+1d5b uni1D5B 2.3 +U+1d5c uni1D5C 2.10 (Sans Oblique) +U+1d5d uni1D5D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d5e uni1D5E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d5f uni1D5F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d60 uni1D60 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d61 uni1D61 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d62 uni1D62 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d63 uni1D63 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d64 uni1D64 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d65 uni1D65 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d66 uni1D66 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d67 uni1D67 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d68 uni1D68 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d69 uni1D69 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+1d6a uni1D6A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+1d77 uni1D77 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.3 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) +U+1d78 uni1D78 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+1d7b uni1D7B 2.3 U+1d85 uni1D85 2.3 U+1d9b uni1D9B 2.3 @@ -1512,6 +1614,7 @@ U+1db4 uni1DB4 2.3 U+1db5 uni1DB5 2.3 U+1db6 uni1DB6 2.3 U+1db7 uni1DB7 2.3 +U+1db8 uni1DB8 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+1db9 uni1DB9 2.3 U+1dba uni1DBA 2.3 U+1dbb uni1DBB 2.3 @@ -1673,7 +1776,7 @@ U+1e96 uni1E96 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+1e97 uni1E97 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+1e98 uni1E98 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+1e99 uni1E99 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) -U+1e9a uni1E9A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+1e9a uni1E9A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans ExtraLight) U+1e9b uni1E9B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+1ea0 uni1EA0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+1ea1 uni1EA1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) @@ -1953,7 +2056,7 @@ U+1fc8 uni1FC8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+1fc9 uni1FC9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+1fca uni1FCA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+1fcb uni1FCB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) -U+1fcc uni1FCC 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1fcc uni1FCC 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.10 (Sans ExtraLight) U+1fcd uni1FCD 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) U+1fce uni1FCE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) U+1fcf uni1FCF 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) @@ -1994,7 +2097,7 @@ U+1ff7 uni1FF7 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+1ff8 uni1FF8 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+1ff9 uni1FF9 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+1ffa uni1FFA 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) -U+1ffb uni1FFB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+1ffb uni1FFB 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.10 (Sans ExtraLight) U+1ffc uni1FFC 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) U+1ffd uni1FFD 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+1ffe uni1FFE 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.5 (Sans ExtraLight) @@ -2114,6 +2217,11 @@ U+208b uni208B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+208c uni208C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+208d uni208D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+208e uni208E 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2090 uni2090 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2091 uni2091 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2092 uni2092 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2093 uni2093 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2094 uni2094 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+20a0 uni20A0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+20a1 colonmonetary 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+20a2 uni20A2 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) @@ -2130,40 +2238,61 @@ U+20ac Euro original U+20ad uni20AD 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+20ae uni20AE 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+20af uni20AF 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+20b0 uni20B0 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+20b1 uni20B1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+20b2 uni20B2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+20b3 uni20B3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+20b4 uni20B4 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+20b5 uni20B5 2.2 +U+20d0 uni20D0 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+20d1 uni20D1 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+20d6 uni20D6 2.8 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+20d7 uni20D7 2.8 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2100 uni2100 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2102 uni2102 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+2103 uni2103 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) U+2104 uni2104 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2105 afii61248 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2106 uni2106 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2109 uni2109 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) +U+210d uni210D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+210e uni210E 2.5 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) U+210f uni210F 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2111 Ifraktur 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2113 afii61289 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2115 uni2115 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+2116 afii61352 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.4 (Sans ExtraLight) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+2117 uni2117 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) U+2118 weierstrass 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2119 uni2119 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+211a uni211A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+211c Rfraktur 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+211d uni211D 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+211e prescription 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2120 uni2120 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2121 uni2121 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2122 trademark original +U+2124 uni2124 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+2126 uni2126 2.2 U+2127 uni2127 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) U+212a uni212A 2.2 U+212b uni212B 2.2 U+212e estimated 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) -U+2132 uni2132 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2132 uni2132 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+2134 uni2134 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) U+2135 aleph 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+213b uni213B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+214b uni214B 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+213c uni213C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+213d uni213D 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+213e uni213E 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+213f uni213F 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2140 uni2140 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2145 uni2145 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2146 uni2146 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2147 uni2147 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2148 uni2148 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2149 uni2149 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+214b uni214B 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+2153 onethird 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+2154 twothirds 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+2155 uni2155 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.5 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.6 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) @@ -2209,11 +2338,11 @@ U+217c uni217C 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+217d uni217D 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) U+217e uni217E 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) U+217f uni217F 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) -U+2180 uni2180 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2180 uni2180 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+2181 uni2181 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2182 uni2182 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2183 uni2183 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.4 (Sans ExtraLight) -U+2184 uni2184 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2184 uni2184 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+2190 arrowleft 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+2191 arrowup 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+2192 arrowright 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) @@ -2326,10 +2455,10 @@ U+21fc uni21FC 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+21fd uni21FD 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+21fe uni21FE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+21ff uni21FF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) -U+2200 universal 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2200 universal 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+2201 uni2201 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2202 partialdiff original -U+2203 existential 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2203 existential 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans ExtraLight) U+2204 uni2204 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2205 emptyset 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2206 Delta original @@ -2370,8 +2499,8 @@ U+2228 logicalor 2.1 U+2229 intersection 2.1 U+222a union 2.1 U+222b integral original -U+222c uni222C 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) -U+222d uni222D 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+222c uni222C 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) +U+222d uni222D 2.1 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.9 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+222e uni222E 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+222f uni222F 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2230 uni2230 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) @@ -2562,20 +2691,20 @@ U+22fe uni22FE 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+22ff uni22FF 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2302 house 1.14 U+2306 uni2306 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+2308 uni2308 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+2309 uni2309 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+230a uni230A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+230b uni230B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2308 uni2308 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+2309 uni2309 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+230a uni230A 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+230b uni230B 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) U+2310 revlogicalnot 1.14 U+2311 uni2311 1.15 -U+2318 uni2318 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2318 uni2318 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+2319 uni2319 1.14 U+2320 integraltp 2.3 U+2321 integralbt 2.3 -U+2325 uni2325 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) +U+2325 uni2325 2.2 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) U+2328 uni2328 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) -U+2329 angleleft 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) -U+232a angleright 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2329 angleleft 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+232a angleright 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.10 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) U+237d uni237D 1.15 U+239b uni239B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) U+239c uni239C 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique) @@ -3025,6 +3154,20 @@ U+269b uni269B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+269c uni269C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) U+26a0 uni26A0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) U+26a1 uni26A1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.7 (Sans Mono, Sans Mono Bold) +U+26a2 uni26A2 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26a3 uni26A3 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26a4 uni26A4 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26a5 uni26A5 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26a6 uni26A6 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26a7 uni26A7 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26a8 uni26A8 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26a9 uni26A9 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26aa uni26AA 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26ab uni26AB 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26ac uni26AC 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26ad uni26AD 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26ae uni26AE 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+26af uni26AF 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+26b0 uni26B0 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) U+26b1 uni26B1 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans ExtraLight, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) U+2701 uni2701 2.5 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) 2.8 (Sans Mono, Sans Mono Bold) @@ -3545,10 +3688,27 @@ U+2af9 uni2AF9 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+2afa uni2AFA 2.7 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2b12 uni2B12 2.3 U+2b13 uni2B13 2.3 +U+2b14 uni2B14 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+2b15 uni2B15 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+2b16 uni2B16 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+2b17 uni2B17 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+2b18 uni2B18 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+2b19 uni2B19 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+2b1a uni2B1A 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique, Sans Oblique, Serif, Serif Bold, Serif Bold Oblique, Serif Oblique) +U+2c60 uni2C60 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2c61 uni2C61 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2c62 uni2C62 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2c63 uni2C63 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2c64 uni2C64 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2c65 uni2C65 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2c66 uni2C66 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+2c67 uni2C67 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2c68 uni2C68 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2c69 uni2C69 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2c6a uni2C6A 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+2c6b uni2C6B 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2c6c uni2C6C 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) +U+2c74 uni2C74 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans Oblique) U+2c75 uni2C75 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2c76 uni2C76 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+2c77 uni2C77 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) @@ -3582,6 +3742,8 @@ U+e01a uniE01A 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+e01b uniE01B 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+e01c uniE01C 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+e01d uniE01D 2.4 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+f000 uniF000 2.10 (Sans) +U+f001 uniF001 2.10 (Sans) U+f208 uniF208 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+f20a uniF20A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+f215 uniF215 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) @@ -3591,6 +3753,7 @@ U+f21a uniF21A 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+f21b uniF21B 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+f25f uniF25F 2.6 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+f5c5 afii10064 2.9 (Sans Bold Oblique, Sans Condensed Bold Oblique) +U+f6c4 afii10063 2.10 (Serif Bold Oblique, Serif Oblique) U+f6c5 afii10064 2.5 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) 2.7 (Sans Mono, Sans Mono Bold, Sans Mono Bold Oblique, Sans Mono Oblique) 2.9 (Sans, Sans Bold, Sans Condensed, Sans Condensed Bold, Sans Condensed Oblique, Sans Oblique) U+f6c6 afii10192 2.5 (Serif Bold Oblique, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) U+f6d1 cyrBreve 2.5 (Serif, Serif Bold, Serif Bold Oblique, Serif Condensed, Serif Condensed Bold, Serif Condensed Bold Oblique, Serif Condensed Oblique, Serif Oblique) @@ -3610,6 +3773,7 @@ U+fb17 uniFB17 2.3 (Sans, Sans Bold, Sans Bold Oblique, Sans Conden U+fb1d uniFB1D 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+fb1f uniFB1F 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+fb20 uniFB20 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) +U+fb29 uniFB29 2.10 (Sans, Sans Bold, Sans Bold Oblique, Sans ExtraLight, Sans Oblique) U+fb2a uniFB2A 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+fb2b uniFB2B 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) U+fb2c uniFB2C 2.9 (Sans, Sans Bold, Sans Bold Oblique, Sans Condensed, Sans Condensed Bold, Sans Condensed Bold Oblique, Sans Condensed Oblique, Sans Oblique) diff --git a/reactos/media/fonts/doc/DejaVu_unicover.txt b/reactos/media/fonts/doc/DejaVu_unicover.txt index 2e2508f0549..d345bf04037 100644 --- a/reactos/media/fonts/doc/DejaVu_unicover.txt +++ b/reactos/media/fonts/doc/DejaVu_unicover.txt @@ -1,5 +1,5 @@ This is the Unicode coverage file for DejaVu fonts -($Id: unicover.txt 1068 2006-08-08 21:22:42Z ben_laenen $) +($Id$) Control and similar characters are discounted from totals. @@ -7,16 +7,16 @@ Control and similar characters are discounted from totals. U+0000 Basic Latin 100% (95/95) 100% (95/95) 100% (95/95) U+0080 Latin-1 Supplement 100% (96/96) 100% (96/96) 100% (96/96) U+0100 Latin Extended-A 100% (128/128) 100% (128/128) 100% (128/128) -U+0180 Latin Extended-B 97% (203/208) 88% (185/208) 57% (119/208) +U+0180 Latin Extended-B 100% (208/208) 89% (187/208) 57% (119/208) U+0250 IPA Extensions 100% (96/96) 100% (96/96) 100% (96/96) U+02b0 Spacing Modifier Letters 78% (63/80) 55% (44/80) 52% (42/80) U+0300 Combining Diacritical Marks 79% (89/112) 58% (66/112) 58% (66/112) -U+0370 Greek and Coptic 98% (125/127) 86% (110/127) 86% (110/127) +U+0370 Greek and Coptic 100% (127/127) 86% (110/127) 86% (110/127) U+0400 Cyrillic 97% (249/255) 73% (188/255) 66% (170/255) U+0500 Cyrillic Supplement 90% (18/20) (0/20) (0/20) U+0530 Armenian 100% (86/86) (0/86) (0/86) U+0590 Hebrew 57% (50/87) (0/87) (0/87) -U+0600 Arabic 46% (110/235) (0/235) (0/235) +U+0600 Arabic 47% (111/235) (0/235) (0/235) U+0700 Syriac (0/77) (0/77) (0/77) U+0750 Arabic Supplement (0/30) (0/30) (0/30) U+0780 Thaana (0/50) (0/50) (0/50) @@ -31,8 +31,8 @@ U+0c00 Telugu (0/80) (0/80) U+0c80 Kannada (0/86) (0/86) (0/86) U+0d00 Malayalam (0/78) (0/78) (0/78) U+0d80 Sinhala (0/80) (0/80) (0/80) -U+0e00 Thai (0/87) (0/87) (0/87) -U+0e80 Lao (0/65) (0/65) (0/65) +U+0e00 Thai 1% (1/87) (0/87) (0/87) +U+0e80 Lao 84% (55/65) (0/65) (0/65) U+0f00 Tibetan (0/195) (0/195) (0/195) U+1000 Myanmar (0/78) (0/78) (0/78) U+10a0 Georgian (0/83) (0/83) (0/83) @@ -55,27 +55,27 @@ U+1980 New Tai Lue (0/80) (0/80) U+19e0 Khmer Symbols (0/32) (0/32) (0/32) U+1a00 Buginese (0/30) (0/30) (0/30) U+1b00 Balinese (0/121) (0/121) (0/121) -U+1d00 Phonetic Extensions 53% (68/128) 28% (36/128) 28% (36/128) -U+1d80 Phonetic Extensions Supplement 57% (37/64) 57% (37/64) 57% (37/64) +U+1d00 Phonetic Extensions 82% (105/128) 28% (36/128) 28% (36/128) +U+1d80 Phonetic Extensions Supplement 59% (38/64) 57% (37/64) 57% (37/64) U+1dc0 Combining Diacritical Marks Supplement (0/13) (0/13) (0/13) U+1e00 Latin Extended Additional 100% (246/246) 77% (190/246) 27% (67/246) U+1f00 Greek Extended 100% (233/233) 100% (233/233) 100% (233/233) U+2000 General Punctuation 82% (87/106) 44% (47/106) 37% (40/106) -U+2070 Superscripts and Subscripts 85% (29/34) 52% (18/34) 52% (18/34) -U+20a0 Currency Symbols 86% (19/22) 22% (5/22) 18% (4/22) -U+20d0 Combining Diacritical Marks for Symbols 6% (2/32) (0/32) (0/32) -U+2100 Letterlike Symbols 36% (29/79) 7% (6/79) 7% (6/79) +U+2070 Superscripts and Subscripts 100% (34/34) 52% (18/34) 52% (18/34) +U+20a0 Currency Symbols 100% (22/22) 22% (5/22) 18% (4/22) +U+20d0 Combining Diacritical Marks for Symbols 12% (4/32) (0/32) (0/32) +U+2100 Letterlike Symbols 56% (45/79) 7% (6/79) 7% (6/79) U+2150 Number Forms 100% (50/50) 26% (13/50) 26% (13/50) U+2190 Arrows 100% (112/112) 3% (4/112) 100% (112/112) -U+2200 Mathematical Operators 91% (234/256) 10% (27/256) 53% (138/256) -U+2300 Miscellaneous Technical 16% (38/232) 5% (12/232) 12% (29/232) +U+2200 Mathematical Operators 91% (234/256) 10% (27/256) 54% (140/256) +U+2300 Miscellaneous Technical 16% (38/232) 7% (18/232) 15% (37/232) U+2400 Control Pictures 5% (2/39) 2% (1/39) 2% (1/39) U+2440 Optical Character Recognition (0/11) (0/11) (0/11) U+2460 Enclosed Alphanumerics 6% (10/160) (0/160) (0/160) U+2500 Box Drawing (0/128) (0/128) 100% (128/128) U+2580 Block Elements 100% (32/32) 100% (32/32) 100% (32/32) U+25a0 Geometric Shapes 100% (96/96) 100% (96/96) 100% (96/96) -U+2600 Miscellaneous Symbols 91% (161/176) 17% (30/176) 84% (149/176) +U+2600 Miscellaneous Symbols 99% (175/176) 17% (30/176) 84% (149/176) U+2700 Dingbats 100% (174/174) (0/174) 82% (144/174) U+27c0 Miscellaneous Mathematical Symbols-A 12% (5/39) 2% (1/39) 2% (1/39) U+27f0 Supplemental Arrows-A (0/16) (0/16) (0/16) @@ -83,9 +83,9 @@ U+2800 Braille Patterns 100% (256/256) (0/256) U+2900 Supplemental Arrows-B (0/128) (0/128) (0/128) U+2980 Miscellaneous Mathematical Symbols-B 7% (9/128) 0% (1/128) 0% (1/128) U+2a00 Supplemental Mathematical Operators 27% (71/256) 1% (3/256) (0/256) -U+2b00 Miscellaneous Symbols and Arrows 6% (2/31) 6% (2/31) 6% (2/31) +U+2b00 Miscellaneous Symbols and Arrows 29% (9/31) 29% (9/31) 29% (9/31) U+2c00 Glagolitic (0/94) (0/94) (0/94) -U+2c60 Latin Extended-C 41% (7/17) (0/17) (0/17) +U+2c60 Latin Extended-C 100% (17/17) (0/17) (0/17) U+2c80 Coptic (0/114) (0/114) (0/114) U+2d00 Georgian Supplement (0/38) (0/38) (0/38) U+2d30 Tifinagh (0/55) (0/55) (0/55) @@ -120,7 +120,7 @@ U+db80 High Private Use Surrogates (0/0) (0/0) U+dc00 Low Surrogates (0/0) (0/0) (0/0) U+e000 Private Use Area (0/0) (0/0) (0/0) U+f900 CJK Compatibility Ideographs (0/467) (0/467) (0/467) -U+fb00 Alphabetic Presentation Forms 81% (47/58) 12% (7/58) 3% (2/58) +U+fb00 Alphabetic Presentation Forms 82% (48/58) 12% (7/58) 3% (2/58) U+fb50 Arabic Presentation Forms-A 11% (70/595) (0/595) (0/595) U+fe00 Variation Selectors (0/16) (0/16) (0/16) U+fe10 Vertical Forms (0/10) (0/10) (0/10) From 551811ac52b31d5341ba18229262ff057e5572a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 17 Sep 2006 14:27:17 +0000 Subject: [PATCH 245/488] Disable some code I did during the last day to repair ReactOS boot. Let's hope it is enough svn path=/trunk/; revision=24168 --- reactos/drivers/bus/pci/pci.c | 2 ++ reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 11 +++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/reactos/drivers/bus/pci/pci.c b/reactos/drivers/bus/pci/pci.c index 9cd4b47fc76..f5590a086d4 100644 --- a/reactos/drivers/bus/pci/pci.c +++ b/reactos/drivers/bus/pci/pci.c @@ -135,6 +135,8 @@ PciAddDevice( NTSTATUS Status; DPRINT("Called\n"); + if (PhysicalDeviceObject == NULL) + return STATUS_SUCCESS; Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo); diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 5f47531f800..8b97c5bc01d 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -2624,9 +2624,9 @@ IopEnumerateDetectedDevices( const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI BIOS"); UNICODE_STRING HardwareIdPci = RTL_CONSTANT_STRING(L"*PNP0A03\0"); static ULONG DeviceIndexPci = 0; - const UNICODE_STRING IdentifierAcpi = RTL_CONSTANT_STRING(L"ACPI BIOS"); + /*const UNICODE_STRING IdentifierAcpi = RTL_CONSTANT_STRING(L"ACPI BIOS"); UNICODE_STRING HardwareIdAcpi = RTL_CONSTANT_STRING(L"*PNP0C08\0"); - static ULONG DeviceIndexAcpi = 0; + static ULONG DeviceIndexAcpi = 0;*/ const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController"); UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0"); static ULONG DeviceIndexSerial = 0; @@ -2774,11 +2774,11 @@ IopEnumerateDetectedDevices( pHardwareId = &HardwareIdPci; DeviceIndex = DeviceIndexPci++; } - else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0) + /*else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0) { pHardwareId = &HardwareIdAcpi; DeviceIndex = DeviceIndexAcpi++; - } + }*/ else if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0) { pHardwareId = &HardwareIdSerial; @@ -2932,6 +2932,8 @@ cleanup: static BOOLEAN INIT_FUNCTION IopIsAcpiComputer(VOID) { + return FALSE; +#if 0 UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"); UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); UNICODE_STRING AcpiBiosIdentifier = RTL_CONSTANT_STRING(L"ACPI BIOS"); @@ -3063,6 +3065,7 @@ cleanup: if (hDeviceKey) ZwClose(hDeviceKey); return ret; +#endif } static NTSTATUS INIT_FUNCTION From adb93d9531b7089ceb7397be974795035f913427 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 17 Sep 2006 15:01:57 +0000 Subject: [PATCH 246/488] - A missing "return" statement to KiDispatchException which was causing all user-mode exceptions to become second-chance and thus crash the app. mIRC works again, and probably numerous other apps (mozilla as well i think, since it had the same issue) svn path=/trunk/; revision=24169 --- reactos/ntoskrnl/ke/i386/exp.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 93cc1b2bd2b..798c69540e3 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -594,11 +594,11 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, VOID NTAPI -KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, - PKEXCEPTION_FRAME ExceptionFrame, - PKTRAP_FRAME TrapFrame, - KPROCESSOR_MODE PreviousMode, - BOOLEAN FirstChance) +KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PKTRAP_FRAME TrapFrame, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN FirstChance) { CONTEXT Context; ULONG_PTR Stack, NewStack; @@ -636,6 +636,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, Context.Eip--; } + /* Sanity check */ ASSERT(!((PreviousMode == KernelMode) && (Context.EFlags & EFLAGS_V86_MASK))); @@ -784,6 +785,9 @@ DispatchToUser: } } _SEH_END; + + /* Dispatch exception to user-mode */ + return; } /* Try second chance */ From 3ab77c0239a9542d0375294fc9c2bc07bfdf86d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 17 Sep 2006 15:24:55 +0000 Subject: [PATCH 247/488] DeviceNode->ResourceList and DeviceNode->ResourceListTranslated should not share memory with DeviceNode->BootResources svn path=/trunk/; revision=24170 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 8b97c5bc01d..22c1b2c65f0 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -132,6 +132,12 @@ IopStartDevice( Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList; Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated; + /* FIXME: Not sure of this! */ + if (!Stack.Parameters.StartDevice.AllocatedResources) + Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->BootResources; + if (!Stack.Parameters.StartDevice.AllocatedResourcesTranslated) + Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->BootResources; + Status = IopInitiatePnpIrp( Fdo, &IoStatusBlock, @@ -1233,13 +1239,6 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) ULONG i; NTSTATUS Status; - if (DeviceNode->BootResources) - { - /* FIXME: Not sure of this! */ - DeviceNode->ResourceList = DeviceNode->ResourceListTranslated = DeviceNode->BootResources; - return STATUS_SUCCESS; - } - /* Fill DeviceNode->ResourceList and DeviceNode->ResourceListTranslated; * by using DeviceNode->ResourceRequirements */ From 6afc1a0152decf374b61480daaca026fc6e3f391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 17 Sep 2006 15:42:50 +0000 Subject: [PATCH 248/488] Define some registry entries as not volatile, to prevent new installation of device at each boot svn path=/trunk/; revision=24171 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 22c1b2c65f0..c0047ae1cca 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -2808,7 +2808,7 @@ IopEnumerateDetectedDevices( &ObjectAttributes, 0, NULL, - REG_OPTION_VOLATILE, + REG_OPTION_NON_VOLATILE, NULL); if (!NT_SUCCESS(Status)) { @@ -2824,7 +2824,7 @@ IopEnumerateDetectedDevices( &ObjectAttributes, 0, NULL, - REG_OPTION_VOLATILE, + REG_OPTION_NON_VOLATILE, NULL); ZwClose(hLevel1Key); if (!NT_SUCCESS(Status)) From 4493c993273bd275b3c79eafaeaeffd0e9cbd9eb Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 17 Sep 2006 15:47:29 +0000 Subject: [PATCH 249/488] fast implemet of NtGdiCloseEnhMetaFile follow thing need be done before it is finish but it will slov leaked memory and filehandle from NtGdiCreateEnhMetaFile for we have NtGdiCreateEnhMetaFile implement. NtGdiCloseEnhMetaFile is base on wine cvs 15/9-2006 Todo 1. Rewrite it to own api call IntGdiCloseEmhMetaFile 2. Use Zw and Int direcly so we do not need todo context swith each call 3. Translate follow api to kernel api // hMapping = CreateFileMappingW(Dc->hFile, NULL, PAGE_READONLY, 0, 0, NULL); // Dc->emh = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); // hmf = EMF_Create_HENHMETAFILE( Dc->emh, (Dc->hFile != 0) ); svn path=/trunk/; revision=24172 --- .../win32/win32k/objects/metafile.c | 167 +++++++++++++++++- 1 file changed, 158 insertions(+), 9 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/metafile.c b/reactos/subsystems/win32/win32k/objects/metafile.c index e817318b16c..135564eed59 100644 --- a/reactos/subsystems/win32/win32k/objects/metafile.c +++ b/reactos/subsystems/win32/win32k/objects/metafile.c @@ -23,15 +23,165 @@ #define NDEBUG #include -#define FILE_FLAG_POSIX_SEMANTICS 16777216 - - HENHMETAFILE STDCALL NtGdiCloseEnhMetaFile(HDC hDC) { - UNIMPLEMENTED; - return 0; + LPENHMETAHEADER emh; + HENHMETAFILE hmf = 0; + HANDLE hMapping = 0; + EMREOF emr; + PDC Dc; + + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + + + /* Todo + Rewrite it to own api call IntGdiCloseEmhMetaFile + Use Zw and Int direcly so we do not need todo context swith each call + + Translate follow api to kernel api + // hMapping = CreateFileMappingW(Dc->hFile, NULL, PAGE_READONLY, 0, 0, NULL); + // Dc->emh = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); + // hmf = EMF_Create_HENHMETAFILE( Dc->emh, (Dc->hFile != 0) ); + + */ + + + Dc = DC_LockDc(hDC); + if (Dc == NULL) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return NULL; + } + + emr.emr.iType = EMR_EOF; + emr.emr.nSize = sizeof(EMREOF); + emr.nPalEntries = 0; + emr.offPalEntries = 0; + emr.nSizeLast = emr.emr.nSize; + + if(Dc->hFile) + { + Status = NtWriteFile(Dc->hFile, NULL, NULL, NULL, &Iosb, (PVOID)&emr, emr.emr.nSize, NULL, NULL); + if (Status == STATUS_PENDING) + { + Status = NtWaitForSingleObject(Dc->hFile,FALSE,NULL); + if (NT_SUCCESS(Status)) + { + Status = Iosb.Status; + } + } + + if (NT_SUCCESS(Status)) + { + DWORD len = Dc->emh->nBytes + emr.emr.nSize; + /* always resize the buffer */ + emh = EngAllocMem(FL_ZERO_MEMORY, len, 0); + if (emh != NULL) + { + memcpy(emh,Dc->emh,Dc->emh->nBytes); + EngFreeMem(Dc->emh); + Dc->emh = emh; + + memcpy(Dc->emh + Dc->emh->nBytes, &emr, emr.emr.nSize); + } + else + { + EngFreeMem(Dc->emh); + Dc->emh=NULL; + } + + } + else + { + Dc->hFile = NULL; + DPRINT1("Write to EnhMetaFile fail\n"); + } + } + + Dc->emh->nBytes += emr.emr.nSize; + Dc->emh->nRecords++; + + if(Dc->emh->rclFrame.left > Dc->emh->rclFrame.right) + { + Dc->emh->rclFrame.left = Dc->emh->rclBounds.left * Dc->emh->szlMillimeters.cx * 100 / Dc->emh->szlDevice.cx; + Dc->emh->rclFrame.top = Dc->emh->rclBounds.top * Dc->emh->szlMillimeters.cy * 100 / Dc->emh->szlDevice.cy; + Dc->emh->rclFrame.right = Dc->emh->rclBounds.right * Dc->emh->szlMillimeters.cx * 100 / Dc->emh->szlDevice.cx; + Dc->emh->rclFrame.bottom = Dc->emh->rclBounds.bottom * Dc->emh->szlMillimeters.cy * 100 / Dc->emh->szlDevice.cy; + } + + if (Dc->hFile) /* disk based metafile */ + { + FILE_POSITION_INFORMATION FilePosition; + LARGE_INTEGER Distance ; + IO_STATUS_BLOCK IoStatusBlock; + + Distance.u.LowPart = 0; + Distance.u.HighPart = 0; + FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart; + + Status = NtSetInformationFile(Dc->hFile, &IoStatusBlock, &FilePosition, + sizeof(FILE_POSITION_INFORMATION), FilePositionInformation); + + if (!NT_SUCCESS(Status)) + { + /* FIXME */ + // SetLastErrorByStatus(errCode); + SetLastWin32Error(ERROR_INVALID_HANDLE); + + NtClose( Dc->hFile ); + DC_UnlockDc(Dc); + NtGdiDeleteObjectApp(hDC); + return hmf; + } + + if (FilePosition.CurrentByteOffset.u.LowPart != 0) + { + /* FIXME */ + // SetLastErrorByStatus(errCode); + SetLastWin32Error(ERROR_INVALID_HANDLE); + + NtClose( Dc->hFile ); + DC_UnlockDc(Dc); + NtGdiDeleteObjectApp(hDC); + return hmf; + } + + Status = NtWriteFile(Dc->hFile, NULL, NULL, NULL, &Iosb, (PVOID)&Dc->emh, sizeof(*Dc->emh), NULL, NULL); + if (Status == STATUS_PENDING) + { + Status = NtWaitForSingleObject(Dc->hFile,FALSE,NULL); + if (NT_SUCCESS(Status)) + { + Status = Iosb.Status; + } + } + + if (!NT_SUCCESS(Status)) + { + NtClose( Dc->hFile ); + DC_UnlockDc(Dc); + NtGdiDeleteObjectApp(hDC); + return hmf; + } + + EngFreeMem(Dc->emh); + + // hMapping = CreateFileMappingW(Dc->hFile, NULL, PAGE_READONLY, 0, 0, NULL); + + // Dc->emh = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); + NtClose( hMapping ); + NtClose( Dc->hFile ); + } + + + // hmf = EMF_Create_HENHMETAFILE( Dc->emh, (Dc->hFile != 0) ); + Dc->emh = NULL; /* So it won't be deleted */ + DC_UnlockDc(Dc); + NtGdiDeleteObjectApp(hDC); + return hmf; } HMETAFILE @@ -68,8 +218,7 @@ NtGdiCreateEnhMetaFile(HDC hDCRef, LPCWSTR Description) { PDC Dc; - HDC ret = NULL; - IO_STATUS_BLOCK Iosb; + HDC ret = NULL; DWORD length = 0; HDC tempHDC; DWORD MemSize; @@ -174,10 +323,10 @@ NtGdiCreateEnhMetaFile(HDC hDCRef, DPRINT1("Trying Create EnhMetaFile\n"); /* disk based metafile */ - DWORD dwDesiredAccess = GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES; - + DWORD dwDesiredAccess = GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; + IO_STATUS_BLOCK Iosb; UNICODE_STRING NtPathU; NTSTATUS Status; ULONG FileAttributes = (FILE_ATTRIBUTE_VALID_FLAGS & ~FILE_ATTRIBUTE_DIRECTORY); From b820ec49303149b1acd1cc17283b132d8214be51 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 17 Sep 2006 17:31:52 +0000 Subject: [PATCH 250/488] - Fix a bug in KeRaiseUserExceptionDispatcher which was causing us not to set the Exception Address (EIP) in the EH record. - Fix a terrible stack corruption bug in KeRaiseUserExceptionDispatcher which was causing us to eventually fuck up the stack in user mode (0x14 bytes instead of 0x50 bytes were reserved). - Protect User-mode Callbacks with SEH, and use STATUS_POP_CALLBACK_STACK. - Fix another nasty stack corruption bug in user-mode APC delivery. - Protect User-mode APC delivery with SEH. - Fix SEH handlers to return EXCEPTION_EXECUTE_HANDLER isntead of ExceptionContinueSearch. svn path=/trunk/; revision=24173 --- reactos/dll/ntdll/main/i386/dispatch.S | 111 +++++++++++++++++-------- reactos/include/ndk/asm.h | 19 +++++ reactos/lib/rtl/i386/exception.c | 19 +---- reactos/ntoskrnl/ke/i386/usercall.c | 16 ++-- reactos/ntoskrnl/rtl/i386/seh.s | 16 +--- 5 files changed, 110 insertions(+), 71 deletions(-) diff --git a/reactos/dll/ntdll/main/i386/dispatch.S b/reactos/dll/ntdll/main/i386/dispatch.S index ab5123599bf..33237242df1 100644 --- a/reactos/dll/ntdll/main/i386/dispatch.S +++ b/reactos/dll/ntdll/main/i386/dispatch.S @@ -11,17 +11,9 @@ #include .intel_syntax noprefix -#define EXCEPTION_NONCONTINUABLE 1 -#define EXCEPTION_UNWINDING 2 -#define EXCEPTION_EXIT_UNWIND 4 -#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND) - -#define STATUS_CALLBACK_POP_STACK 0xC0000423 - -#define ExceptionContinueSearch 1 - /* FUNCTIONS ****************************************************************/ +.func LdrInitializeThunk@16 .globl _LdrInitializeThunk@16 _LdrInitializeThunk@16: @@ -36,44 +28,72 @@ _LdrInitializeThunk@16: /* Jump into the C initialization routine */ jmp _LdrpInit@12 +.endfunc -.globl _KiUserExceptionApcHandler@16 -_KiUserApcExceptionHandler@16: +.func KiUserApcExceptionHandler +_KiUserApcExceptionHandler: /* Put the exception record in ECX and check the Flags */ mov ecx, [esp+4] - test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND + test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING jz .return /* Test alert the thread */ call _NtTestAlert@0 .return: - /* We'll continue */ - mov eax, ExceptionContinueSearch + /* We'll execute handler */ + mov eax, EXCEPTION_EXECUTE_HANDLER ret 16 - +.endfunc + +.func KiUserApcDispatcher@16 .globl _KiUserApcDispatcher@16 _KiUserApcDispatcher@16: - /* Put the Context in EDI */ - lea edi, [esp+16] + /* Setup SEH stack */ + lea eax, [esp+CONTEXT_ALIGNED_SIZE+16] + mov ecx, fs:[TEB_EXCEPTION_LIST] + mov edx, offset _KiUserApcExceptionHandler + mov [eax], ecx + mov [eax+4], edx - /* Get the ApcRoutine and call it */ + /* Enable SEH */ + mov fs:[TEB_EXCEPTION_LIST], eax + + /* Put the Context in EDI */ pop eax + lea edi, [esp+12] + + /* Call the APC Routine */ call eax + /* Restore exception list */ + mov ecx, [edi+CONTEXT_ALIGNED_SIZE] + mov fs:[TEB_EXCEPTION_LIST], ecx + /* Switch back to the context */ push 1 push edi call _ZwContinue@8 -.globl _KiUserCallbackExceptionHandler@16 -_KiUserCallbackExceptionHandler@16: + /* Save callback return value */ + mov esi, eax + + /* Raise status */ +StatusRaiseApc: + push esi + call _RtlRaiseStatus@4 + jmp StatusRaiseApc + ret 16 +.endfunc + +.func KiUserCallbackExceptionHandler +_KiUserCallbackExceptionHandler: /* Put the exception record in ECX and check the Flags */ mov ecx, [esp+4] - test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND + test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING jz return /* Tell the kernel to invalidate the stack */ @@ -83,13 +103,25 @@ _KiUserCallbackExceptionHandler@16: call _ZwCallbackReturn@12 return: - /* We'll continue */ - mov eax, ExceptionContinueSearch + /* We'll execute the handler */ + mov eax, EXCEPTION_EXECUTE_HANDLER ret 16 +.endfunc +.func KiUserCallbackDispatcher@12 .globl _KiUserCallbackDispatcher@12 _KiUserCallbackDispatcher@12: - + + /* Setup SEH stack */ + mov ecx, fs:[TEB_EXCEPTION_LIST] + mov edx, offset _KiUserCallbackExceptionHandler + lea eax, [esp+16] + mov [esp+16], ecx + mov [esp+20], edx + + /* Enable SEH */ + mov fs:[TEB_EXCEPTION_LIST], eax + /* Get the callback Index */ add esp, 4 pop edx @@ -107,15 +139,28 @@ _KiUserCallbackDispatcher@12: push 0 call _ZwCallbackReturn@12 + /* Save callback return value */ + mov esi, eax + + /* Raise status */ +StatusRaise: + push esi + call _RtlRaiseStatus@4 + jmp StatusRaise + ret 12 +.endfunc + +.func KiRaiseUserExceptionDispatcher@0 .globl _KiRaiseUserExceptionDispatcher@0 _KiRaiseUserExceptionDispatcher@0: /* Setup stack for EXCEPTION_RECORD */ push ebp mov ebp, esp - sub esp, SIZEOF_EXCEPTION_RECORD + sub esp, EXCEPTION_RECORD_LENGTH /* Fill out the record */ + mov [esp+EXCEPTION_RECORD_EXCEPTION_ADDRESS], eax mov eax, [fs:KPCR_TEB] mov eax, [eax+TEB_EXCEPTION_CODE] mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax @@ -132,7 +177,9 @@ _KiRaiseUserExceptionDispatcher@0: mov esp, ebp pop ebp ret +.endfunc +.func KiUserExceptionDispatcher@8 .globl _KiUserExceptionDispatcher@8 _KiUserExceptionDispatcher@8: @@ -140,17 +187,9 @@ _KiUserExceptionDispatcher@8: mov ecx, [esp+4] mov ebx, [esp] - /* Call the vectored exception handler */ + /* Dispatch the exception */ push ecx push ebx - call _RtlpExecuteVectoredExceptionHandlers@8 - - /* Check for success */ - or al, al - jnz ContinueExecution - - /* Dispatch the exception */ - sub esp, 8 call _RtlDispatchException@8 /* Check for success */ @@ -195,7 +234,9 @@ Exit: push esp call _RtlRaiseException@4 ret 8 +.endfunc +.func RtlpGetStackLimits@8 .globl _RtlpGetStackLimits@8 _RtlpGetStackLimits@8: @@ -211,4 +252,4 @@ _RtlpGetStackLimits@8: /* return */ ret 8 - +.endfunc diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 568e6b117d1..9ce3ef517d4 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -310,6 +310,7 @@ Author: #define CONTEXT_FLOAT_SAVE_CONTROL_WORD CONTEXT_FLOAT_SAVE + FN_CONTROL_WORD #define CONTEXT_FLOAT_SAVE_STATUS_WORD CONTEXT_FLOAT_SAVE + FN_STATUS_WORD #define CONTEXT_FLOAT_SAVE_TAG_WORD CONTEXT_FLOAT_SAVE + FN_TAG_WORD +#define CONTEXT_ALIGNED_SIZE 0x2CC // // EXCEPTION_RECORD Offsets @@ -322,6 +323,24 @@ Author: #define SIZEOF_EXCEPTION_RECORD 0x14 #define EXCEPTION_RECORD_LENGTH 0x50 +// +// Exception types +// +#ifdef __ASM__ +#define EXCEPTION_NONCONTINUABLE 0x0001 +#define EXCEPTION_UNWINDING 0x0002 +#define EXCEPTION_EXIT_UNWIND 0x0004 +#define EXCEPTION_STACK_INVALID 0x0008 +#define EXCEPTION_NESTED_CALL 0x00010 +#define EXCEPTION_TARGET_UNWIND 0x00020 +#define EXCEPTION_COLLIDED_UNWIND 0x00040 +#define EXCEPTION_UNWIND 0x00066 +#define EXCEPTION_EXECUTE_HANDLER 0x00001 +#define EXCEPTION_CONTINUE_SEARCH 0x00000 +#define EXCEPTION_CONTINUE_EXECUTION 0xFFFFFFFF +#define EXCEPTION_CHAIN_END 0xFFFFFFFF +#endif + // // TEB Offsets // diff --git a/reactos/lib/rtl/i386/exception.c b/reactos/lib/rtl/i386/exception.c index 37cc00ae5e0..696dcd860c3 100644 --- a/reactos/lib/rtl/i386/exception.c +++ b/reactos/lib/rtl/i386/exception.c @@ -56,19 +56,17 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, EXCEPTION_DISPOSITION ReturnValue; ULONG_PTR StackLow, StackHigh; ULONG_PTR RegistrationFrameEnd; - DPRINT("RtlDispatchException(): %p, %p \n", ExceptionRecord, Context); /* Get the current stack limits and registration frame */ RtlpGetStackLimits(&StackLow, &StackHigh); RegistrationFrame = RtlpGetExceptionList(); - DPRINT("RegistrationFrame is 0x%p\n", RegistrationFrame); /* Now loop every frame */ while (RegistrationFrame != EXCEPTION_CHAIN_END) { /* Find out where it ends */ RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame + - sizeof(*RegistrationFrame); + sizeof(EXCEPTION_REGISTRATION_RECORD); /* Make sure the registration frame is located within the stack */ if ((RegistrationFrameEnd > StackHigh) || @@ -87,25 +85,24 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, /* Set invalid stack and return false */ ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID; - DPRINT1("Invalid exception frame\n"); + DPRINT1("Invalid exception frame: %p %p %p %p\n", + RegistrationFrame, RegistrationFrameEnd, + StackHigh, StackLow); return FALSE; } /* Check if logging is enabled */ - DPRINT("Checking for logging\n"); RtlpCheckLogException(ExceptionRecord, Context, RegistrationFrame, sizeof(*RegistrationFrame)); /* Call the handler */ - DPRINT("Executing handler: %p\n", RegistrationFrame->Handler); ReturnValue = RtlpExecuteHandlerForException(ExceptionRecord, RegistrationFrame, Context, &DispatcherContext, RegistrationFrame->Handler); - DPRINT("Handler returned: %p\n", (PVOID)ReturnValue); /* Check if this is a nested frame */ if (RegistrationFrame == NestedFrame) @@ -128,7 +125,6 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, ExceptionRecord2.NumberParameters = 0; /* Raise the exception */ - DPRINT("Non-continuable\n"); RtlRaiseException(&ExceptionRecord2); } else @@ -166,7 +162,6 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, } /* Unhandled, return false */ - DPRINT("FALSE\n"); return FALSE; } @@ -188,7 +183,6 @@ RtlUnwind(PVOID RegistrationFrame OPTIONAL, ULONG_PTR RegistrationFrameEnd; CONTEXT LocalContext; PCONTEXT Context; - DPRINT("RtlUnwind(). RegistrationFrame 0x%p\n", RegistrationFrame); /* Get the current stack limits */ RtlpGetStackLimits(&StackLow, &StackHigh); @@ -242,8 +236,6 @@ RtlUnwind(PVOID RegistrationFrame OPTIONAL, /* Now loop every frame */ while (RegistrationFrame2 != EXCEPTION_CHAIN_END) { - DPRINT("RegistrationFrame is 0x%p\n", RegistrationFrame2); - /* If this is the target */ if (RegistrationFrame2 == RegistrationFrame) { @@ -262,7 +254,6 @@ RtlUnwind(PVOID RegistrationFrame OPTIONAL, ExceptionRecord2.NumberParameters = 0; /* Raise the exception */ - DPRINT1("Frame is invalid\n"); RtlRaiseException(&ExceptionRecord2); } @@ -298,13 +289,11 @@ RtlUnwind(PVOID RegistrationFrame OPTIONAL, else { /* Call the handler */ - DPRINT("Executing unwind handler: %p\n", RegistrationFrame2->Handler); ReturnValue = RtlpExecuteHandlerForUnwind(ExceptionRecord, RegistrationFrame2, Context, &DispatcherContext, RegistrationFrame2->Handler); - DPRINT("Handler returned: %p\n", (PVOID)ReturnValue); /* Handle the dispositions */ if (ReturnValue == ExceptionContinueSearch) diff --git a/reactos/ntoskrnl/ke/i386/usercall.c b/reactos/ntoskrnl/ke/i386/usercall.c index 722c8e6c487..65b83380c02 100644 --- a/reactos/ntoskrnl/ke/i386/usercall.c +++ b/reactos/ntoskrnl/ke/i386/usercall.c @@ -65,8 +65,8 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, IN PVOID SystemArgument2) { CONTEXT Context; - ULONG_PTR Stack; - ULONG Size; + ULONG_PTR Stack, AlignedEsp; + ULONG ContextLength; EXCEPTION_RECORD SehExceptRecord; _SEH_DECLARE_LOCALS(KiCopyInfo); @@ -84,11 +84,15 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode); /* Get the aligned size */ - Size = ((sizeof(CONTEXT) + 3) & ~3) + 4 * sizeof(ULONG_PTR); - Stack = (Context.Esp & ~3) - Size; + AlignedEsp = Context.Esp & ~3; + ContextLength = CONTEXT_ALIGNED_SIZE + (4 * sizeof(ULONG_PTR)); + Stack = ((AlignedEsp - 8) & ~3) - ContextLength; - /* Probe and copy */ - ProbeForWrite((PVOID)Stack, Size, 4); + /* Probe the stack */ + ProbeForWrite((PVOID)Stack, AlignedEsp - Stack, 1); + ASSERT(!(Stack & 3)); + + /* Copy data into it */ RtlMoveMemory((PVOID)(Stack + (4 * sizeof(ULONG_PTR))), &Context, sizeof(CONTEXT)); diff --git a/reactos/ntoskrnl/rtl/i386/seh.s b/reactos/ntoskrnl/rtl/i386/seh.s index 8255cf87ced..584fcf1556b 100755 --- a/reactos/ntoskrnl/rtl/i386/seh.s +++ b/reactos/ntoskrnl/rtl/i386/seh.s @@ -16,20 +16,6 @@ #define ExceptionNestedException 2 #define ExceptionCollidedUnwind 3 -#define EXCEPTION_NONCONTINUABLE 0x01 -#define EXCEPTION_UNWINDING 0x02 -#define EXCEPTION_EXIT_UNWIND 0x04 -#define EXCEPTION_STACK_INVALID 0x08 -#define EXCEPTION_NESTED_CALL 0x10 -#define EXCEPTION_TARGET_UNWIND 0x20 -#define EXCEPTION_COLLIDED_UNWIND 0x40 - -#define EXCEPTION_UNWIND_MODE \ -( EXCEPTION_UNWINDING \ - | EXCEPTION_EXIT_UNWIND \ - | EXCEPTION_TARGET_UNWIND \ - | EXCEPTION_COLLIDED_UNWIND) - #define EREC_CODE 0x00 #define EREC_FLAGS 0x04 #define EREC_RECORD 0x08 @@ -178,7 +164,7 @@ __except_handler3: // Either we're called to handle an exception or we're called to unwind movl EH3_ERECORD(%ebp), %eax - testl $EXCEPTION_UNWIND_MODE, EREC_FLAGS(%eax) + testl $EXCEPTION_UNWIND, EREC_FLAGS(%eax) jnz .eh3_unwind // Keep a pointer to the exception registration in EBX From 23dc37d5752201498f165c741d4dd00bbf219b3c Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 17 Sep 2006 18:44:52 +0000 Subject: [PATCH 251/488] - Cleanup except_asm.s and add .func/.endfunc and fix some double definitions. svn path=/trunk/; revision=24174 --- reactos/lib/rtl/i386/except_asm.s | 42 +++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/reactos/lib/rtl/i386/except_asm.s b/reactos/lib/rtl/i386/except_asm.s index 9da7d7468fb..9effeb0d34b 100644 --- a/reactos/lib/rtl/i386/except_asm.s +++ b/reactos/lib/rtl/i386/except_asm.s @@ -12,24 +12,22 @@ #include .intel_syntax noprefix -#define EXCEPTION_UNWINDING 2 -#define EXCEPTION_EXIT_UNWIND 4 -#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND) - -#define ExceptionContinueExecution 0 #define ExceptionContinueSearch 1 #define ExceptionNestedException 2 #define ExceptionCollidedUnwind 3 /* FUNCTIONS ****************************************************************/ +.func RtlpGetExceptionList@0 .globl _RtlpGetExceptionList@0 _RtlpGetExceptionList@0: /* Return the exception list */ mov eax, [fs:TEB_EXCEPTION_LIST] ret +.endfunc +.func RtlpSetExceptionList@4 .globl _RtlpSetExceptionList@4 _RtlpSetExceptionList@4: @@ -42,7 +40,9 @@ _RtlpSetExceptionList@4: /* Return */ ret 4 +.endfunc +.func RtlpGetExceptionAddress@0 .globl _RtlpGetExceptionAddress@0 _RtlpGetExceptionAddress@0: @@ -51,7 +51,9 @@ _RtlpGetExceptionAddress@0: /* Return */ ret +.endfunc +.func RtlCaptureContext@4 .globl _RtlCaptureContext@4 _RtlCaptureContext@4: @@ -63,21 +65,23 @@ _RtlCaptureContext@4: mov [ebx+CONTEXT_EAX], eax mov [ebx+CONTEXT_ECX], ecx mov [ebx+CONTEXT_EDX], edx - mov eax, [esp] /* We pushed EBX, remember? ;) */ + mov eax, [esp] mov [ebx+CONTEXT_EBX], eax mov [ebx+CONTEXT_ESI], esi mov [ebx+CONTEXT_EDI], edi /* Capture the other regs */ jmp CaptureRest +.endfunc +.func RtlpCaptureContext@4 .globl _RtlpCaptureContext@4 _RtlpCaptureContext@4: /* Preserve EBX and put the context in it */ push ebx mov ebx, [esp+8] - + /* Clear the basic register context */ mov dword ptr [ebx+CONTEXT_EAX], 0 mov dword ptr [ebx+CONTEXT_ECX], 0 @@ -85,7 +89,7 @@ _RtlpCaptureContext@4: mov dword ptr [ebx+CONTEXT_EBX], 0 mov dword ptr [ebx+CONTEXT_ESI], 0 mov dword ptr [ebx+CONTEXT_EDI], 0 - + CaptureRest: /* Capture the segment registers */ mov [ebx+CONTEXT_SEGCS], cs @@ -114,7 +118,9 @@ CaptureRest: /* Return to the caller */ pop ebx ret 4 +.endfunc +.func RtlpExecuteHandlerForException@20 .globl _RtlpExecuteHandlerForException@20 _RtlpExecuteHandlerForException@20: @@ -123,21 +129,23 @@ _RtlpExecuteHandlerForException@20: /* Jump to common routine */ jmp _RtlpExecuteHandler@20 +.endfunc +.func RtlpExecuteHandlerForUnwind@20 .globl _RtlpExecuteHandlerForUnwind@20 _RtlpExecuteHandlerForUnwind@20: - /* Copy the routine in EDX */ mov edx, offset _RtlpExceptionProtector +.endfunc - /* Run the common routine */ +.func RtlpExecuteHandler@20 _RtlpExecuteHandler@20: /* Save non-volatile */ push ebx push esi push edi - + /* Clear registers */ xor eax, eax xor ebx, ebx @@ -157,7 +165,9 @@ _RtlpExecuteHandler@20: pop esi pop ebx ret 0x14 +.endfunc +.func RtlpExecuteHandler2@20 .globl _RtlpExecuteHandler2@20 _RtlpExecuteHandler2@20: @@ -195,7 +205,9 @@ _RtlpExecuteHandler2@20: mov esp, ebp pop ebp ret 0x14 +.endfunc +.func RtlpExceptionProtector _RtlpExceptionProtector: /* Assume we'll continue */ @@ -203,7 +215,7 @@ _RtlpExceptionProtector: /* Put the exception record in ECX and check the Flags */ mov ecx, [esp+4] - test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND + test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND jnz return /* Save the frame in ECX and Context in EDX */ @@ -221,14 +233,17 @@ _RtlpExceptionProtector: return: ret 16 +.endfunc +.func RtlpUnwindProtector _RtlpUnwindProtector: + /* Assume we'll continue */ mov eax, ExceptionContinueSearch /* Put the exception record in ECX and check the Flags */ mov ecx, [esp+4] - test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND + test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND jnz .return /* Save the frame in ECX and Context in EDX */ @@ -246,4 +261,5 @@ _RtlpUnwindProtector: .return: ret 16 +.endfunc From d3eeef4046d65dcdb8666cec571523ab598a1e51 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 17 Sep 2006 20:21:01 +0000 Subject: [PATCH 252/488] NtGdiCloseEnhMetaFile 1. translate EMF_Create_HENHMETAFILE to reactos 2. Delete hdc. NtGdiCreateEnhMetaFile 1. Set hdc ownership. svn path=/trunk/; revision=24175 --- reactos/subsystems/win32/win32k/include/dc.h | 10 +++- .../win32/win32k/objects/metafile.c | 49 ++++++++++++++----- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index 542a19de282..00afe1ec3ea 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -122,7 +122,7 @@ typedef struct _DC WIN_DC_INFO w; - HANDLE hFile; + HANDLE hFile; LPENHMETAHEADER emh; } DC, *PDC; @@ -188,4 +188,12 @@ VOID FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner); VOID FASTCALL DC_UpdateXforms(PDC dc); BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest); +/* For Metafile and MetaEnhFile not in windows this struct taken from wine cvs 15/9-2006*/ +typedef struct +{ + LPENHMETAHEADER emh; + BOOL on_disk; /* true if metafile is on disk */ +} DD_ENHMETAFILEOBJ, *PDD_ENHMETAFILEOBJ; + + #endif diff --git a/reactos/subsystems/win32/win32k/objects/metafile.c b/reactos/subsystems/win32/win32k/objects/metafile.c index 135564eed59..de847fc3e74 100644 --- a/reactos/subsystems/win32/win32k/objects/metafile.c +++ b/reactos/subsystems/win32/win32k/objects/metafile.c @@ -28,7 +28,8 @@ STDCALL NtGdiCloseEnhMetaFile(HDC hDC) { LPENHMETAHEADER emh; - HENHMETAFILE hmf = 0; + HANDLE hmf = 0; + PDD_ENHMETAFILEOBJ phmf; HANDLE hMapping = 0; EMREOF emr; PDC Dc; @@ -36,16 +37,18 @@ NtGdiCloseEnhMetaFile(HDC hDC) IO_STATUS_BLOCK Iosb; NTSTATUS Status; + DPRINT1("NtGdiCloseEnhMetaFile\n"); /* Todo Rewrite it to own api call IntGdiCloseEmhMetaFile - Use Zw and Int direcly so we do not need todo context swith each call - + Translate follow api to kernel api // hMapping = CreateFileMappingW(Dc->hFile, NULL, PAGE_READONLY, 0, 0, NULL); // Dc->emh = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); // hmf = EMF_Create_HENHMETAFILE( Dc->emh, (Dc->hFile != 0) ); + + DC_SetOwnership(hdc, */ @@ -55,15 +58,15 @@ NtGdiCloseEnhMetaFile(HDC hDC) SetLastWin32Error(ERROR_INVALID_HANDLE); return NULL; } - + emr.emr.iType = EMR_EOF; emr.emr.nSize = sizeof(EMREOF); emr.nPalEntries = 0; emr.offPalEntries = 0; emr.nSizeLast = emr.emr.nSize; - + if(Dc->hFile) - { + { Status = NtWriteFile(Dc->hFile, NULL, NULL, NULL, &Iosb, (PVOID)&emr, emr.emr.nSize, NULL, NULL); if (Status == STATUS_PENDING) { @@ -100,7 +103,7 @@ NtGdiCloseEnhMetaFile(HDC hDC) DPRINT1("Write to EnhMetaFile fail\n"); } } - + Dc->emh->nBytes += emr.emr.nSize; Dc->emh->nRecords++; @@ -166,21 +169,39 @@ NtGdiCloseEnhMetaFile(HDC hDC) NtGdiDeleteObjectApp(hDC); return hmf; } - + EngFreeMem(Dc->emh); + /* FIXME */ // hMapping = CreateFileMappingW(Dc->hFile, NULL, PAGE_READONLY, 0, 0, NULL); + /* FIXME */ // Dc->emh = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); NtClose( hMapping ); NtClose( Dc->hFile ); } + + hmf = GDIOBJ_AllocObj(GdiHandleTable, GDI_OBJECT_TYPE_ENHMETAFILE); + if (hmf != NULL) + { + phmf = GDIOBJ_LockObj(GdiHandleTable, hmf, GDI_OBJECT_TYPE_ENHMETAFILE); + if (phmf != NULL) + { + if (Dc->hFile != NULL) + { + phmf->on_disk = TRUE; + } + else + { + phmf->on_disk = FALSE; + } + GDIOBJ_UnlockObjByPtr(GdiHandleTable, phmf); + phmf->emh = Dc->emh; + } + } - - // hmf = EMF_Create_HENHMETAFILE( Dc->emh, (Dc->hFile != 0) ); Dc->emh = NULL; /* So it won't be deleted */ DC_UnlockDc(Dc); - NtGdiDeleteObjectApp(hDC); return hmf; } @@ -231,9 +252,11 @@ NtGdiCreateEnhMetaFile(HDC hDCRef, */ UNICODE_STRING DriverName; RtlInitUnicodeString(&DriverName, L"DISPLAY"); - tempHDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE); + tempHDC = NtGdiCreateDC(&DriverName, NULL, NULL, NULL); //IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE); } - + + GDIOBJ_SetOwnership(GdiHandleTable, tempHDC, PsGetCurrentProcess()); + DC_SetOwnership(tempHDC, PsGetCurrentProcess()); Dc = DC_LockDc(tempHDC); if (Dc == NULL) From fa61787952d51a790a2aba589170cdaac208ca8c Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 17 Sep 2006 20:22:27 +0000 Subject: [PATCH 253/488] Activate CloseEnhMetaFile in gdi32. We do not leak memory from CreateEnhMetaFile. svn path=/trunk/; revision=24176 --- reactos/dll/win32/gdi32/misc/stubs.c | 14 +------------- reactos/dll/win32/gdi32/objects/metafile.c | 11 +++++++++++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/reactos/dll/win32/gdi32/misc/stubs.c b/reactos/dll/win32/gdi32/misc/stubs.c index 3b06aa56b5b..7a7a5efa08d 100644 --- a/reactos/dll/win32/gdi32/misc/stubs.c +++ b/reactos/dll/win32/gdi32/misc/stubs.c @@ -464,19 +464,7 @@ EnumMetaFile( } -/* - * @unimplemented - */ -HENHMETAFILE -STDCALL -CloseEnhMetaFile( - HDC hdc - ) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} + /* diff --git a/reactos/dll/win32/gdi32/objects/metafile.c b/reactos/dll/win32/gdi32/objects/metafile.c index 9ca1f02c93b..15a93909ced 100644 --- a/reactos/dll/win32/gdi32/objects/metafile.c +++ b/reactos/dll/win32/gdi32/objects/metafile.c @@ -1,5 +1,16 @@ #include "precomp.h" +/* + * @unimplemented + */ +HENHMETAFILE +STDCALL +CloseEnhMetaFile( + HDC hdc) +{ + return NtGdiCloseEnhMetaFile(hdc); +} + /* * @implemented */ From 45f71f78c808a6376b6a3b675c94ee24e0faf3f3 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 17 Sep 2006 20:42:59 +0000 Subject: [PATCH 254/488] did delete NtGdiDeleteObjectApp at end of NtGdiCloseEnhMetaFile by mistake. radding it svn path=/trunk/; revision=24177 --- reactos/subsystems/win32/win32k/objects/metafile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/subsystems/win32/win32k/objects/metafile.c b/reactos/subsystems/win32/win32k/objects/metafile.c index de847fc3e74..908e2cdcfbd 100644 --- a/reactos/subsystems/win32/win32k/objects/metafile.c +++ b/reactos/subsystems/win32/win32k/objects/metafile.c @@ -202,6 +202,7 @@ NtGdiCloseEnhMetaFile(HDC hDC) Dc->emh = NULL; /* So it won't be deleted */ DC_UnlockDc(Dc); + NtGdiDeleteObjectApp(hDC); return hmf; } From 3e709fbbd96650e48aaf9c5932b06ddeeb0c9790 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 17 Sep 2006 21:09:10 +0000 Subject: [PATCH 255/488] - Fix some insidious bugs in exception handling, mostly related to the art of unwinding (RtlUnwind). - Can't name specifics, but probably fixes multiple SEH/application bugs/regressions since about 6-8 months ago. Fixes my personal SEH test from 22 failures/crashes/BSODs to 22 succeesses... - Also fixes some crashes in kernel-kqemu mode. svn path=/trunk/; revision=24178 --- reactos/lib/rtl/exception.c | 3 - reactos/lib/rtl/i386/except_asm.s | 4 +- reactos/lib/rtl/i386/exception.c | 198 ++++++++++++++++-------------- 3 files changed, 107 insertions(+), 98 deletions(-) diff --git a/reactos/lib/rtl/exception.c b/reactos/lib/rtl/exception.c index 44c5d162ce0..99b49ab0aef 100644 --- a/reactos/lib/rtl/exception.c +++ b/reactos/lib/rtl/exception.c @@ -26,14 +26,12 @@ RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord) { CONTEXT Context; NTSTATUS Status; - DPRINT1("RtlRaiseException(Status %p)\n", ExceptionRecord); /* Capture the context */ RtlCaptureContext(&Context); /* Save the exception address */ ExceptionRecord->ExceptionAddress = RtlpGetExceptionAddress(); - DPRINT1("ExceptionAddress %p\n", ExceptionRecord->ExceptionAddress); /* Write the context flag */ Context.ContextFlags = CONTEXT_FULL; @@ -72,7 +70,6 @@ RtlRaiseStatus(NTSTATUS Status) { EXCEPTION_RECORD ExceptionRecord; CONTEXT Context; - DPRINT1("RtlRaiseStatus(Status 0x%.08lx)\n", Status); /* Capture the context */ RtlCaptureContext(&Context); diff --git a/reactos/lib/rtl/i386/except_asm.s b/reactos/lib/rtl/i386/except_asm.s index 9effeb0d34b..d8683822444 100644 --- a/reactos/lib/rtl/i386/except_asm.s +++ b/reactos/lib/rtl/i386/except_asm.s @@ -23,7 +23,7 @@ _RtlpGetExceptionList@0: /* Return the exception list */ - mov eax, [fs:TEB_EXCEPTION_LIST] + mov eax, fs:[TEB_EXCEPTION_LIST] ret .endfunc @@ -36,7 +36,7 @@ _RtlpSetExceptionList@4: mov ecx, [ecx] /* Write it */ - mov [fs:TEB_EXCEPTION_LIST], ecx + mov fs:[TEB_EXCEPTION_LIST], ecx /* Return */ ret 4 diff --git a/reactos/lib/rtl/i386/exception.c b/reactos/lib/rtl/i386/exception.c index 696dcd860c3..feb2ef07154 100644 --- a/reactos/lib/rtl/i386/exception.c +++ b/reactos/lib/rtl/i386/exception.c @@ -29,6 +29,11 @@ VOID NTAPI RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList); +typedef struct _DISPATCHER_CONTEXT +{ + PEXCEPTION_REGISTRATION_RECORD RegistrationPointer; +} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; + /* PUBLIC FUNCTIONS **********************************************************/ /* @@ -51,9 +56,9 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context) { PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, NestedFrame = NULL; - PEXCEPTION_REGISTRATION_RECORD DispatcherContext; + DISPATCHER_CONTEXT DispatcherContext; EXCEPTION_RECORD ExceptionRecord2; - EXCEPTION_DISPOSITION ReturnValue; + EXCEPTION_DISPOSITION Disposition; ULONG_PTR StackLow, StackHigh; ULONG_PTR RegistrationFrameEnd; @@ -85,9 +90,6 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, /* Set invalid stack and return false */ ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID; - DPRINT1("Invalid exception frame: %p %p %p %p\n", - RegistrationFrame, RegistrationFrameEnd, - StackHigh, StackLow); return FALSE; } @@ -98,11 +100,12 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, sizeof(*RegistrationFrame)); /* Call the handler */ - ReturnValue = RtlpExecuteHandlerForException(ExceptionRecord, + Disposition = RtlpExecuteHandlerForException(ExceptionRecord, RegistrationFrame, Context, &DispatcherContext, - RegistrationFrame->Handler); + RegistrationFrame-> + Handler); /* Check if this is a nested frame */ if (RegistrationFrame == NestedFrame) @@ -113,48 +116,60 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, } /* Handle the dispositions */ - if (ReturnValue == ExceptionContinueExecution) + switch (Disposition) { - /* Check if it was non-continuable */ - if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) - { + /* Continue searching */ + case ExceptionContinueExecution: + + /* Check if it was non-continuable */ + if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) + { + /* Set up the exception record */ + ExceptionRecord2.ExceptionRecord = ExceptionRecord; + ExceptionRecord2.ExceptionCode = + STATUS_NONCONTINUABLE_EXCEPTION; + ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + ExceptionRecord2.NumberParameters = 0; + + /* Raise the exception */ + RtlRaiseException(&ExceptionRecord2); + } + else + { + /* Return to caller */ + return TRUE; + } + + /* Continue searching */ + case ExceptionContinueSearch: + break; + + /* Nested exception */ + case ExceptionNestedException: + + /* Turn the nested flag on */ + ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL; + + /* Update the current nested frame */ + if (DispatcherContext.RegistrationPointer > NestedFrame) + { + /* Get the frame from the dispatcher context */ + NestedFrame = DispatcherContext.RegistrationPointer; + } + break; + + /* Anything else */ + default: + /* Set up the exception record */ ExceptionRecord2.ExceptionRecord = ExceptionRecord; - ExceptionRecord2.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; + ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION; ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; ExceptionRecord2.NumberParameters = 0; /* Raise the exception */ RtlRaiseException(&ExceptionRecord2); - } - else - { - /* Return to caller */ - return TRUE; - } - } - else if (ReturnValue == ExceptionNestedException) - { - /* Turn the nested flag on */ - ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL; - - /* Update the current nested frame */ - if (NestedFrame < DispatcherContext) NestedFrame = DispatcherContext; - } - else if (ReturnValue == ExceptionContinueSearch) - { - /* Do nothing */ - } - else - { - /* Set up the exception record */ - ExceptionRecord2.ExceptionRecord = ExceptionRecord; - ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION; - ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - ExceptionRecord2.NumberParameters = 0; - - /* Raise the exception */ - RtlRaiseException(&ExceptionRecord2); + break; } /* Go to the next frame */ @@ -170,15 +185,15 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, */ VOID NTAPI -RtlUnwind(PVOID RegistrationFrame OPTIONAL, - PVOID ReturnAddress OPTIONAL, - PEXCEPTION_RECORD ExceptionRecord OPTIONAL, - PVOID EaxValue) +RtlUnwind(IN PVOID TargetFrame OPTIONAL, + IN PVOID TargetIp OPTIONAL, + IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL, + IN PVOID ReturnValue) { - PEXCEPTION_REGISTRATION_RECORD RegistrationFrame2, OldFrame; - PEXCEPTION_REGISTRATION_RECORD DispatcherContext; + PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, OldFrame; + DISPATCHER_CONTEXT DispatcherContext; EXCEPTION_RECORD ExceptionRecord2, ExceptionRecord3; - EXCEPTION_DISPOSITION ReturnValue; + EXCEPTION_DISPOSITION Disposition; ULONG_PTR StackLow, StackHigh; ULONG_PTR RegistrationFrameEnd; CONTEXT LocalContext; @@ -202,7 +217,7 @@ RtlUnwind(PVOID RegistrationFrame OPTIONAL, } /* Check if we have a frame */ - if (RegistrationFrame) + if (TargetFrame) { /* Set it as unwinding */ ExceptionRecord->ExceptionFlags |= EXCEPTION_UNWINDING; @@ -222,30 +237,26 @@ RtlUnwind(PVOID RegistrationFrame OPTIONAL, RtlpCaptureContext(Context); /* Pop the current arguments off */ - Context->Esp += sizeof(RegistrationFrame) + - sizeof(ReturnAddress) + + Context->Esp += sizeof(TargetFrame) + + sizeof(TargetIp) + sizeof(ExceptionRecord) + sizeof(ReturnValue); /* Set the new value for EAX */ - Context->Eax = (ULONG)EaxValue; + Context->Eax = (ULONG)ReturnValue; /* Get the current frame */ - RegistrationFrame2 = RtlpGetExceptionList(); + RegistrationFrame = RtlpGetExceptionList(); /* Now loop every frame */ - while (RegistrationFrame2 != EXCEPTION_CHAIN_END) + while (RegistrationFrame != EXCEPTION_CHAIN_END) { /* If this is the target */ - if (RegistrationFrame2 == RegistrationFrame) - { - /* Continue execution */ - ZwContinue(Context, FALSE); - } + if (RegistrationFrame == TargetFrame) ZwContinue(Context, FALSE); /* Check if the frame is too low */ - if ((RegistrationFrame) && ((ULONG_PTR)RegistrationFrame < - (ULONG_PTR)RegistrationFrame2)) + if ((TargetFrame) && + ((ULONG_PTR)TargetFrame < (ULONG_PTR)RegistrationFrame)) { /* Create an invalid unwind exception */ ExceptionRecord2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET; @@ -258,8 +269,8 @@ RtlUnwind(PVOID RegistrationFrame OPTIONAL, } /* Find out where it ends */ - RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame2 + - sizeof(*RegistrationFrame2); + RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame + + sizeof(EXCEPTION_REGISTRATION_RECORD); /* Make sure the registration frame is located within the stack */ if ((RegistrationFrameEnd > StackHigh) || @@ -283,54 +294,55 @@ RtlUnwind(PVOID RegistrationFrame OPTIONAL, ExceptionRecord2.NumberParameters = 0; /* Raise the exception */ - DPRINT1("Frame has bad stack\n"); RtlRaiseException(&ExceptionRecord2); } else { /* Call the handler */ - ReturnValue = RtlpExecuteHandlerForUnwind(ExceptionRecord, - RegistrationFrame2, + Disposition = RtlpExecuteHandlerForUnwind(ExceptionRecord, + RegistrationFrame, Context, &DispatcherContext, - RegistrationFrame2->Handler); + RegistrationFrame-> + Handler); + switch (Disposition) + { + /* Continue searching */ + case ExceptionContinueSearch: + break; - /* Handle the dispositions */ - if (ReturnValue == ExceptionContinueSearch) - { - /* Do nothing */ - } - else if (ReturnValue == ExceptionCollidedUnwind) - { - /* Get the previous frame */ - RegistrationFrame2 = DispatcherContext; - } - else - { - /* Set up the exception record */ - ExceptionRecord2.ExceptionRecord = ExceptionRecord; - ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION; - ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - ExceptionRecord2.NumberParameters = 0; + /* Collission */ + case ExceptionCollidedUnwind : - /* Raise the exception */ - RtlRaiseException(&ExceptionRecord2); + /* Get the original frame */ + RegistrationFrame = DispatcherContext.RegistrationPointer; + break; + + /* Anything else */ + default: + + /* Set up the exception record */ + ExceptionRecord2.ExceptionRecord = ExceptionRecord; + ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION; + ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + ExceptionRecord2.NumberParameters = 0; + + /* Raise the exception */ + RtlRaiseException(&ExceptionRecord2); + break; } /* Go to the next frame */ - OldFrame = RegistrationFrame2; - RegistrationFrame2 = RegistrationFrame2->Next; + OldFrame = RegistrationFrame; + RegistrationFrame = RegistrationFrame->Next; /* Remove this handler */ - if (RegistrationFrame2 != RegistrationFrame) - { - RtlpSetExceptionList(OldFrame); - } + RtlpSetExceptionList(OldFrame); } } /* Check if we reached the end */ - if (RegistrationFrame == EXCEPTION_CHAIN_END) + if (TargetFrame == EXCEPTION_CHAIN_END) { /* Unwind completed, so we don't exit */ ZwContinue(Context, FALSE); From 70cca480e5528e70b0e519cf0cebaea59aa1643b Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 17 Sep 2006 22:10:24 +0000 Subject: [PATCH 256/488] implemet GdiReleaseDC it redirect to NtUserReleaseDC(HWD hwd, HDC hdc) now svn path=/trunk/; revision=24179 --- reactos/dll/win32/gdi32/include/precomp.h | 2 ++ reactos/dll/win32/gdi32/misc/stubs.c | 11 ----------- reactos/dll/win32/gdi32/objects/dc.c | 10 ++++++++++ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/reactos/dll/win32/gdi32/include/precomp.h b/reactos/dll/win32/gdi32/include/precomp.h index aff53ed0616..37765a4f641 100644 --- a/reactos/dll/win32/gdi32/include/precomp.h +++ b/reactos/dll/win32/gdi32/include/precomp.h @@ -31,4 +31,6 @@ /* Deprecated NTGDI calls which shouldn't exist */ #include +#include +#include /* EOF */ diff --git a/reactos/dll/win32/gdi32/misc/stubs.c b/reactos/dll/win32/gdi32/misc/stubs.c index 7a7a5efa08d..0b23fd0ad18 100644 --- a/reactos/dll/win32/gdi32/misc/stubs.c +++ b/reactos/dll/win32/gdi32/misc/stubs.c @@ -1838,17 +1838,6 @@ GdiIsPlayMetafileDC(HDC hdc) return 0; } -/* - * @unimplemented - */ -BOOL -STDCALL -GdiReleaseDC(HDC hdc) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} /* * @unimplemented diff --git a/reactos/dll/win32/gdi32/objects/dc.c b/reactos/dll/win32/gdi32/objects/dc.c index 714f0fdd463..328ad29303e 100644 --- a/reactos/dll/win32/gdi32/objects/dc.c +++ b/reactos/dll/win32/gdi32/objects/dc.c @@ -458,3 +458,13 @@ GetObjectType( SetLastError(ERROR_INVALID_HANDLE); return Ret; } + +/* + * @implemented + */ +BOOL +STDCALL +GdiReleaseDC(HDC hdc) +{ + return NtUserReleaseDC(NULL,hdc); +} From b52483ba9a13a0409987b0aa299056f5a3caebb9 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 17 Sep 2006 23:17:07 +0000 Subject: [PATCH 257/488] - Add func.endfunc decoration. - Add code to wait for SwapBusy == FALSE on SMP. - Add stub code to check for new PCR fields in 2003. Currently disabled because thread swap code still uses XP fields. - Check for active DPCs at the end of thread swap, not at the beginning. - Set PRCB->IdleThread outside of the thread swap routine. - Don't set the thread state to running inside the swap routine, we already do it outside. svn path=/trunk/; revision=24180 --- reactos/ntoskrnl/ke/i386/ctxswitch.S | 47 ++++++++++++++++++++-------- reactos/ntoskrnl/ke/thrdschd.c | 1 + 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 6dbcfa69692..1aa84812060 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -229,6 +229,7 @@ Return: * If a return from a system thread is detected, a bug check will occur. * *--*/ + .func KiThreadStartup@156 .globl _KiThreadStartup@156 _KiThreadStartup@156: @@ -268,6 +269,7 @@ BadThread: /* A system thread returned...this is very bad! */ int 3 +.endfunc /*++ * KiSwapContextInternal @@ -287,22 +289,32 @@ BadThread: * Absolutely all registers except ESP can be trampled here for maximum code flexibility. * *--*/ -.globl @KiSwapContextInternal@0 +.func @KiSwapContextInternal@0, @KiSwapContextInternal@0 @KiSwapContextInternal@0: - /* Set the Thread to running */ - mov byte ptr es:[esi+KTHREAD_STATE], Running - /* Save the IRQL */ push ecx +#ifdef CONFIG_SMP +GetSwapLock: + /* Acquire the swap lock */ + cmp [esi+KTHREAD_SWAP_BUSY], 0 + jz NotBusy + pause + jmp GetSwapLock +#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] - /* DPC shouldn't be active */ - cmp byte ptr [ebx+KPCR_PRCB_DPC_ROUTINE_ACTIVE], 0 - jnz BugCheckDpc + /* Check for WMI */ + //cmp dword ptr [ebx+KPCR_PERF_GLOBAL_GROUP_MASK], 0 + //jnz WmiTrace +AfterTrace: /* Switching, disable interrupts now */ cli @@ -391,7 +403,6 @@ SameProcess: /* Increase context switches */ inc dword ptr [esi+KTHREAD_CONTEXT_SWITCHES] - //inc dword ptr [esi+KPRC_PRCB_CONTEXT_SWITCHES] /* Restore exception list */ pop [ebx+KPCR_EXCEPTION_LIST] @@ -399,6 +410,10 @@ SameProcess: /* 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 @@ -446,9 +461,18 @@ LdtStuff: mov eax, KGDT_LDT jmp LoadLdt +WmiTrace: + + /* No WMI support yet */ + int 3 + + /* Jump back */ + jmp AfterTrace + BugCheckDpc: push ATTEMPTED_SWITCH_FROM_DPC call _KeBugCheck@4 +.endfunc /*++ * KiSwapContext @@ -460,7 +484,7 @@ BugCheckDpc: * switch to. * * Returns: - * The WaitStatus of the Target Thread. NOT YET SUPPORTED. + * The WaitStatus of the Target Thread. * * Remarks: * This is a wrapper around KiSwapContextInternal which will save all the @@ -472,7 +496,7 @@ BugCheckDpc: * *--*/ .globl @KiSwapContext@8 -.func @KiSwapContext@8, @KiSwapContext@8 +.func @KiSwapContext@8, @KiSwapContext@8 @KiSwapContext@8: /* Note, we CANNOT touch ebp */ @@ -494,9 +518,6 @@ BugCheckDpc: /* Get the New Thread */ mov esi, edx - /* Save it as Current thread */ - mov fs:[KPCR_CURRENT_THREAD], esi - /* Get the wait IRQL */ movzx ecx, byte ptr [edi+KTHREAD_WAIT_IRQL] diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c index fea767e046a..95a49bd8342 100644 --- a/reactos/ntoskrnl/ke/thrdschd.c +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -154,6 +154,7 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus) /* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */ DPRINT("You are : %x, swapping to: %x.\n", OldThread, CurrentThread); + KeGetCurrentPrcb()->CurrentThread = CurrentThread; ApcState = KiSwapContext(OldThread, CurrentThread); DPRINT("You are : %x, swapped from: %x\n", OldThread, CurrentThread); return ApcState; From eaf28f05097c7ba17b37b9e804cbafe2a8b1f761 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 18 Sep 2006 00:02:46 +0000 Subject: [PATCH 258/488] - Stop doing cli/sti doing context switching (For now, since it's only needed for FPU, which isn't yet done). - Stop using XP KPCR fields for storing stack values, they're not used inside the kernel anymore and now have 2003 values (WMI tracing, etc). - Move parts of the process switch (LDT reload) out-of-line. svn path=/trunk/; revision=24181 --- reactos/ntoskrnl/ke/i386/ctxswitch.S | 54 ++++++++++++---------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 1aa84812060..f3ae9d2d283 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -311,13 +311,10 @@ GetSwapLock: push [ebx+KPCR_EXCEPTION_LIST] /* Check for WMI */ - //cmp dword ptr [ebx+KPCR_PERF_GLOBAL_GROUP_MASK], 0 + cmp dword ptr [ebx+KPCR_PERF_GLOBAL_GROUP_MASK], 0 //jnz WmiTrace AfterTrace: - /* Switching, disable interrupts now */ - cli - /* Update kernel stack */ mov [edi+KTHREAD_KERNEL_STACK], esp @@ -328,12 +325,6 @@ AfterTrace: /* Make space for the NPX Frame */ sub eax, NPX_FRAME_LENGTH - /* Set the KPCR stack values */ - mov [ebx+KPCR_INITIAL_STACK], eax - mov [ebx+KPCR_STACK_LIMIT], ecx - - /* FIXME Check and update CR0 */ - /* Check if this isn't V86 Mode, so we can bias the Esp0 */ test dword ptr [eax - KTRAP_FRAME_SIZE + KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM jnz NoAdjust @@ -354,31 +345,20 @@ NoAdjust: mov eax, [esi+KTHREAD_TEB] mov [ebx+KPCR_TEB], eax - /* Stack is OK, safe to enable interrupts now */ - sti - /* Check if address space switch is needed */ - mov eax, [esi+KTHREAD_APCSTATE_PROCESS] - cmp eax, [edi+KTHREAD_APCSTATE_PROCESS] + mov ebp, [esi+KTHREAD_APCSTATE_PROCESS] + mov eax, [edi+KTHREAD_APCSTATE_PROCESS] + cmp ebp, eax jz SameProcess - /* Get the new Process. */ - mov edi, [esi+KTHREAD_APCSTATE_PROCESS] - /* Check if we need an LDT */ - xor eax, eax - cmp [edi+KPROCESS_LDT_DESCRIPTOR0], eax - jnz LdtStuff - -LoadLdt: - /* Load LDT */ - lldt ax - - /* Clear gs */ - xor eax, eax - mov gs, ax + mov ecx, [ebp+KPROCESS_LDT_DESCRIPTOR0] + or ecx, [eax+KPROCESS_LDT_DESCRIPTOR0] + jnz LdtReload +UpdateCr3: /* Get the address space */ + mov edi, ebp mov eax, [edi+KPROCESS_DIRECTORY_TABLE_BASE] /* Get the IOPM and TSS */ @@ -393,6 +373,10 @@ LoadLdt: mov [ebp+KTSS_IOMAPBASE], cx SameProcess: + /* Clear gs */ + xor eax, eax + mov gs, ax + /* Set the TEB */ mov eax, [esi+KTHREAD_TEB] mov ecx, [ebx+KPCR_GDT] @@ -441,11 +425,14 @@ ApcReturn: setz al ret -LdtStuff: +LdtReload: + /* Check if it's empty */ + mov eax, [edi+KPROCESS_LDT_DESCRIPTOR0] + test eax, eax + jz LoadLdt /* Write the LDT Selector */ mov ecx, [ebx+KPCR_GDT] - mov eax, [edi+KPROCESS_LDT_DESCRIPTOR0] mov [ecx+KGDT_LDT], eax mov eax, [edi+KPROCESS_LDT_DESCRIPTOR1] mov [ecx+KGDT_LDT+4], eax @@ -459,7 +446,10 @@ LdtStuff: /* Save LDT Selector */ mov eax, KGDT_LDT - jmp LoadLdt + +LoadLdt: + lldt ax + jmp UpdateCr3 WmiTrace: From 8de07ee7b4b9602e7d1a886ea4c6df279563c753 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 18 Sep 2006 00:10:58 +0000 Subject: [PATCH 259/488] - Don't update CR3 in KTSS, it's not used. - Don't read a useless stack pointer anymore. - Update KTSS_ESP0 near the end of context switching, not at the beginning anymore. - Same for IOPM and I/O Redirection Map Base Address. svn path=/trunk/; revision=24182 --- reactos/ntoskrnl/ke/i386/ctxswitch.S | 56 ++++++++++++---------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index f3ae9d2d283..140f5aaa7aa 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -318,26 +318,6 @@ AfterTrace: /* Update kernel stack */ mov [edi+KTHREAD_KERNEL_STACK], esp - /* Get stack pointers */ - mov eax, [esi+KTHREAD_INITIAL_STACK] - mov ecx, [esi+KTHREAD_STACK_LIMIT] - - /* 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], X86_EFLAGS_VM - 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 - /* Switch to new stack */ mov esp, [esi+KTHREAD_KERNEL_STACK] @@ -357,21 +337,10 @@ NoAdjust: jnz LdtReload UpdateCr3: - /* Get the address space */ - mov edi, ebp - mov eax, [edi+KPROCESS_DIRECTORY_TABLE_BASE] - - /* Get the IOPM and TSS */ - mov ebp, [ebx+KPCR_TSS] - mov ecx, [edi+KPROCESS_IOPM_OFFSET] - /* Switch address space */ - mov [ebp+KTSS_CR3], eax + mov eax, [ebp+KPROCESS_DIRECTORY_TABLE_BASE] mov cr3, eax - /* Set current IOPM offset in the TSS */ - mov [ebp+KTSS_IOMAPBASE], cx - SameProcess: /* Clear gs */ xor eax, eax @@ -385,6 +354,29 @@ SameProcess: 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], X86_EFLAGS_VM + 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] From 63da586075152168959d7af49e868fdf1d8a9ac8 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 18 Sep 2006 00:17:53 +0000 Subject: [PATCH 260/488] - Fix some bugs in LDT switch (EDI->EBP) - Turn simple bugcheck into BugCheckEx with information that the helpfile says it should have. svn path=/trunk/; revision=24183 --- reactos/ntoskrnl/ke/i386/ctxswitch.S | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 140f5aaa7aa..98295f4b5f7 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -305,14 +305,14 @@ GetSwapLock: #endif /* Increase context switches (use ES for lazy load) */ - //inc dword ptr es:[ebx+KPCR_CONTEXT_SWITCHES] + 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 + jnz WmiTrace AfterTrace: /* Update kernel stack */ @@ -419,14 +419,14 @@ ApcReturn: LdtReload: /* Check if it's empty */ - mov eax, [edi+KPROCESS_LDT_DESCRIPTOR0] + 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, [edi+KPROCESS_LDT_DESCRIPTOR1] + mov eax, [ebp+KPROCESS_LDT_DESCRIPTOR1] mov [ecx+KGDT_LDT+4], eax /* Write the INT21 handler */ @@ -452,8 +452,15 @@ WmiTrace: 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 _KeBugCheck@4 + call _KeBugCheckEx@20 .endfunc /*++ From 2ea699f94ea0c03fc9e2c0305e5ce423e723e21a Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 18 Sep 2006 00:30:30 +0000 Subject: [PATCH 261/488] - Assert that the current CPU is the one the thread is supposed to be running on. - Get CR0, read the KTHREAD NPX State, disable interrupts and verify if the NPX state is dirty. If it is, then reload CR0 with the new value. Re-enable interrupts. This sequence should make FPU work during context switching, but I haven't tested yet. At the very least, it should get rid of TRAP_FAULT_UNKNOWN blue screen. - Set TEB in the same time as the selector is being configured, not way earlier. svn path=/trunk/; revision=24184 --- reactos/ntoskrnl/ke/i386/ctxswitch.S | 66 +++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 98295f4b5f7..f60cda462d7 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -315,15 +315,45 @@ GetSwapLock: jnz WmiTrace AfterTrace: - /* Update kernel stack */ +#ifdef DBG + /* Assert that we're on the right CPU */ + mov cl, [esi+KTHREAD_NEXT_PROCESSOR] + cmp cl, [ebx+KPCR_PROCESSOR_NUMBER] + jnz WrongCpu +#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 +#endif + +SetStack: + /* Set new stack */ mov [edi+KTHREAD_KERNEL_STACK], esp - /* Switch to new stack */ - mov esp, [esi+KTHREAD_KERNEL_STACK] + /* Checking NPX, disable interrupts now */ + mov eax, [esi+KTHREAD_INITIAL_STACK] + cli - /* Set TEB pointer */ - mov eax, [esi+KTHREAD_TEB] - mov [ebx+KPCR_TEB], eax + /* 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] @@ -348,6 +378,7 @@ SameProcess: /* 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 @@ -443,6 +474,20 @@ LoadLdt: lldt ax jmp UpdateCr3 +NewCr0: + +#ifdef 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_MP + CR0_EM + CR0_TS) + jnz InvalidNpx +#endif + + /* Update CR0 */ + mov cr0, ecx + jmp StackOk + WmiTrace: /* No WMI support yet */ @@ -461,6 +506,15 @@ BugCheckDpc: push edi push ATTEMPTED_SWITCH_FROM_DPC call _KeBugCheckEx@20 + +#ifdef DBG +InvalidNpx: + int 3 +WrongActiveCpu: + int 3 +WrongCpu: + int 3 +#endif .endfunc /*++ From d228dcccadba2828f47584d3d48e701940fc67ce Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 18 Sep 2006 00:34:13 +0000 Subject: [PATCH 262/488] - On SMP systems, update KPROCESS->ActiveProcessors and assert their validty. Needed for a similar assertion and check in KiSwapProcess which we already have. - Also on SMP, make sure to clear the KTHREAD's swap-busy lock after the actual swap has been done. svn path=/trunk/; revision=24185 --- reactos/ntoskrnl/ke/i386/ctxswitch.S | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index f60cda462d7..45256cfbe45 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -361,6 +361,21 @@ StackOk: 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 */ +#ifdef DBG + test [ebp+KPROCESS_ACTIVE_PROCESSORS], ecx + jz WrongActiveCpu + test [eax+KPROCESS_ACTIVE_PROCESSORS], ecx + jz WrongActiveCpu +#endif +#endif + /* Check if we need an LDT */ mov ecx, [ebp+KPROCESS_LDT_DESCRIPTOR0] or ecx, [eax+KPROCESS_LDT_DESCRIPTOR0] @@ -372,6 +387,12 @@ UpdateCr3: 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 From 03c36d1a358b85ba1c958ae2dc689ea504449571 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 18 Sep 2006 01:07:13 +0000 Subject: [PATCH 263/488] - Implement Trap 16: Math Coprocessor Fault. Happens during Floating Point precision error test that I wrote. Simply calls shared NPX handler in KiTrap7. - Implement some extra checks in KiTrap7 and start coding the NPX shared handler. We *almost* have full FPU support now... (trying to get this done for tomorrow morning so that Greatlord can sent me the 15 000$ he promised...) svn path=/trunk/; revision=24186 --- reactos/ntoskrnl/ke/i386/trap.s | 82 +++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 6d061dfb8ff..a8c449784f7 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -1170,13 +1170,64 @@ AfterRestore: cli jmp StartTrapHandle +KernelNpx: + + /* Set delayed error */ + or dword ptr [ecx+FN_CR0_NPX_STATE], CR0_TS + + /* Check if this happened during restore */ + cmp dword ptr [ebp+KTRAP_FRAME_EIP], offset FrRestore + jnz UserNpx + + /* Skip instruction and dispatch the exception */ + add dword ptr [ebp+KTRAP_FRAME_EIP], 3 + jmp _Kei386EoiHelper@0 + IsLoaded: /* Check if TS is set */ test bl, CR0_TS jnz TsSetOnLoadedState - /* Check if the trap came from user-mode */ +HandleNpxFault: + /* Check if the trap came from V86 mode */ + test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK + jnz V86Npx + + /* Check if it came from kernel mode */ + test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK + jz KernelNpx + + /* Check if it came from a VDM */ + cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK + jne V86Npx + +UserNpx: + /* Get the current thread */ + mov eax, fs:[KPCR_CURRENT_THREAD] + + /* Check NPX state */ + cmp byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED + + /* Get the NPX save area */ + mov ecx, [eax+KTHREAD_INITIAL_STACK] + lea ecx, [ecx-NPX_FRAME_LENGTH] + jz NoSaveRestore + +HandleUserNpx: + + /* Set new CR0 */ + mov ebx, cr0 + and ebx, ~(CR0_MP + CR0_EM + CR0_TS) + mov cr0, ebx + + /* FIXME: Implement the rest */ int 3 + jmp $ + +NoSaveRestore: + /* FIXME: Implement the rest */ + int 3 + jmp $ EmulationEnabled: /* Did this come from kernel-mode? */ @@ -1196,6 +1247,17 @@ TsSetOnLoadedState: clts jmp _Kei386EoiHelper@0 +V86Npx: + /* Check if this is a VDM */ + mov eax, fs:[KPCR_CURRENT_THREAD] + mov ebx, [eax+KTHREAD_APCSTATE_PROCESS] + cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 + jz HandleUserNpx + + /* V86 NPX not handled */ + int 3 + jmp $ + BogusTrap2: /* Cause a bugcheck */ sti @@ -1535,9 +1597,21 @@ _KiTrap16: /* Enter trap */ TRAP_PROLOG(16) - /* FIXME: ROS Doesn't handle FPU faults yet */ - mov eax, 16 - jmp _KiSystemFatalException + /* Check if this is the NPX Thread */ + mov eax, fs:[KPCR_CURRENT_THREAD] + cmp eax, fs:[KPCR_NPX_THREAD] + + /* Get the initial stack and NPX frame */ + mov ecx, [eax+KTHREAD_INITIAL_STACK] + lea ecx, [ecx-NPX_FRAME_LENGTH] + + /* If this is a valid fault, handle it */ + jz HandleNpxFault + + /* Otherwise, re-enable interrupts and set delayed error */ + sti + or dword ptr [ecx+FN_CR0_NPX_STATE], CR0_TS + jmp _Kei386EoiHelper@0 .endfunc .func KiTrap17 From 8b094bf09343774eea39aacda20402393cc14017 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 18 Sep 2006 02:33:21 +0000 Subject: [PATCH 264/488] - Implement FPU Exception Handler. - We can now properly handle FPU faults (wrote a small test for invalid fpu precision). - OpenGL probably still doesn't work, as there might be some bugs around the place. However, you should not see FPU Bugchecks anymore. svn path=/trunk/; revision=24187 --- reactos/include/ndk/asm.h | 32 +++++- reactos/ntoskrnl/ke/i386/trap.s | 169 ++++++++++++++++++++++++++------ 2 files changed, 168 insertions(+), 33 deletions(-) diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 9ce3ef517d4..15cada7f0c7 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -200,14 +200,29 @@ Author: // // FPU Save Area Offsets // -#define FN_CONTROL_WORD 0x0 -#define FN_STATUS_WORD 0x4 -#define FN_TAG_WORD 0x8 -#define FN_DATA_SELECTOR 0x18 +#define FP_CONTROL_WORD 0x0 +#define FP_STATUS_WORD 0x4 +#define FP_TAG_WORD 0x8 +#define FP_ERROR_OFFSET 0xC +#define FP_ERROR_SELECTOR 0x10 +#define FP_DATA_OFFSET 0x14 +#define FP_DATA_SELECTOR 0x18 #define FN_CR0_NPX_STATE 0x20C #define SIZEOF_FX_SAVE_AREA 528 #define NPX_FRAME_LENGTH 0x210 +// +// FX Save Area Offsets +// +#define FX_CONTROL_WORD 0x0 +#define FX_STATUS_WORD 0x2 +#define FX_TAG_WORD 0x4 +#define FX_ERROR_OPCODE 0x6 +#define FX_ERROR_OFFSET 0x8 +#define FX_ERROR_SELECTOR 0xC +#define FX_DATA_OFFSET 0x10 +#define FX_DATA_SELECTOR 0x14 + // // NPX States // @@ -464,6 +479,15 @@ Author: #define STATUS_SINGLE_STEP 0x80000004 #define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094 #define STATUS_INTEGER_OVERFLOW 0xC0000095 +#define STATUS_FLOAT_DENORMAL_OPERAND 0xC000008D +#define STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008E +#define STATUS_FLOAT_INEXACT_RESULT 0xC000008F +#define STATUS_FLOAT_INVALID_OPERATION 0xC0000090 +#define STATUS_FLOAT_OVERFLOW 0xC0000091 +#define STATUS_FLOAT_STACK_CHECK 0xC0000092 +#define STATUS_FLOAT_UNDERFLOW 0xC0000093 +#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4 +#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5 #define APC_INDEX_MISMATCH 0x01 #define TRAP_CAUSE_UNKNOWN 0x12 #define KMODE_EXCEPTION_NOT_HANDLED 0x13 diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index a8c449784f7..30a952d8499 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -1220,32 +1220,135 @@ HandleUserNpx: and ebx, ~(CR0_MP + CR0_EM + CR0_TS) mov cr0, ebx - /* FIXME: Implement the rest */ - int 3 - jmp $ + /* Check if we have FX support */ + test byte ptr _KeI386FxsrPresent, 1 + jz FnSave2 + + /* Save the state */ + fxsave [ecx] + jmp MakeCr0Dirty +FnSave2: + fnsave [ecx] + wait + +MakeCr0Dirty: + /* Make CR0 state not loaded */ + or ebx, NPX_STATE_NOT_LOADED + or ebx, [ecx+FN_CR0_NPX_STATE] + mov cr0, ebx + + /* Update NPX state */ + mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED + mov dword ptr fs:[KPCR_NPX_THREAD], 0 NoSaveRestore: - /* FIXME: Implement the rest */ - int 3 - jmp $ + /* Clear the TS bit and re-enable interrupts */ + and dword ptr [ecx+FN_CR0_NPX_STATE], ~CR0_TS + sti -EmulationEnabled: - /* Did this come from kernel-mode? */ - cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R0_CODE - jz CheckState + /* Check if we have FX support */ + test byte ptr _KeI386FxsrPresent, 1 + jz FnError - /* It came from user-mode, so this would only be valid inside a VDM */ - /* Since we don't actually have VDMs in ROS, bugcheck. */ - jmp BogusTrap2 + /* Get error offset, control and status words */ + mov ebx, [ecx+FX_ERROR_OFFSET] + movzx eax, word ptr [ecx+FX_CONTROL_WORD] + movzx edx, word ptr [ecx+FX_STATUS_WORD] -TsSetOnLoadedState: - /* TS shouldn't be set, unless this we don't have a Math Processor */ - test bl, CR0_MP - jnz BogusTrap + /* Get the faulting opcode */ + mov esi, [ecx+FX_DATA_OFFSET] + jmp CheckError - /* Strange that we got a trap at all, but ignore and continue */ - clts - jmp _Kei386EoiHelper@0 +FnError: + /* Get error offset, control and status words */ + mov ebx, [ecx+FP_ERROR_OFFSET] + movzx eax, word ptr [ecx+FP_CONTROL_WORD] + movzx edx, word ptr [ecx+FP_STATUS_WORD] + + /* Get the faulting opcode */ + mov esi, [ecx+FP_DATA_OFFSET] + +CheckError: + /* Mask exceptions */ + and eax, 0x3F + not eax + and eax, edx + + /* Check if what's left is invalid */ + test al, 1 + jz ValidNpxOpcode + + /* Check if it was a stack fault */ + test al, 64 + jnz InvalidStack + + /* Raise exception */ + mov eax, STATUS_FLOAT_INVALID_OPERATION + jmp _DispatchOneParam + +InvalidStack: + + /* Raise exception */ + mov eax, STATUS_FLOAT_STACK_CHECK + jmp _DispatchTwoParam + +ValidNpxOpcode: + + /* Check for divide by 0 */ + test al, 4 + jz 1f + + /* Raise exception */ + mov eax, STATUS_FLOAT_DIVIDE_BY_ZERO + jmp _DispatchOneParam + +1: + /* Check for denormal */ + test al, 2 + jz 1f + + /* Raise exception */ + mov eax, STATUS_FLOAT_INVALID_OPERATION + jmp _DispatchOneParam + +1: + /* Check for overflow */ + test al, 8 + jz 1f + + /* Raise exception */ + mov eax, STATUS_FLOAT_OVERFLOW + jmp _DispatchOneParam + +1: + /* Check for underflow */ + test al, 16 + jz 1f + + /* Raise exception */ + mov eax, STATUS_FLOAT_UNDERFLOW + jmp _DispatchOneParam + +1: + /* Check for precision fault */ + test al, 32 + jz UnexpectedNpx + + /* Raise exception */ + mov eax, STATUS_FLOAT_INEXACT_RESULT + jmp _DispatchOneParam + +UnexpectedNpx: + + /* Strange result, bugcheck the OS */ + sti + push ebp + push 0 + push 0 + push eax + push 1 + push TRAP_CAUSE_UNKNOWN + call _KeBugCheckWithTf@24 V86Npx: /* Check if this is a VDM */ @@ -1258,15 +1361,23 @@ V86Npx: int 3 jmp $ -BogusTrap2: - /* Cause a bugcheck */ - sti - push 0 - push 0 - push eax - push 1 - push TRAP_CAUSE_UNKNOWN - call _KeBugCheckEx@20 +EmulationEnabled: + /* Did this come from kernel-mode? */ + cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R0_CODE + jz CheckState + + /* It came from user-mode, so this would only be valid inside a VDM */ + /* Since we don't actually have VDMs in ROS, bugcheck. */ + jmp UnexpectedNpx + +TsSetOnLoadedState: + /* TS shouldn't be set, unless this we don't have a Math Processor */ + test bl, CR0_MP + jnz BogusTrap + + /* Strange that we got a trap at all, but ignore and continue */ + clts + jmp _Kei386EoiHelper@0 BogusTrap: /* Cause a bugcheck */ From 6e100cf43fa17cd16dab60af8b339b23fe2becc9 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Mon, 18 Sep 2006 05:13:17 +0000 Subject: [PATCH 265/488] revert 24179 it was bad idea. and wrong way todo it on See issue #21478 for more details. svn path=/trunk/; revision=24188 --- reactos/dll/win32/gdi32/include/precomp.h | 2 -- reactos/dll/win32/gdi32/misc/stubs.c | 11 +++++++++++ reactos/dll/win32/gdi32/objects/dc.c | 10 ---------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/reactos/dll/win32/gdi32/include/precomp.h b/reactos/dll/win32/gdi32/include/precomp.h index 37765a4f641..aff53ed0616 100644 --- a/reactos/dll/win32/gdi32/include/precomp.h +++ b/reactos/dll/win32/gdi32/include/precomp.h @@ -31,6 +31,4 @@ /* Deprecated NTGDI calls which shouldn't exist */ #include -#include -#include /* EOF */ diff --git a/reactos/dll/win32/gdi32/misc/stubs.c b/reactos/dll/win32/gdi32/misc/stubs.c index 0b23fd0ad18..7a7a5efa08d 100644 --- a/reactos/dll/win32/gdi32/misc/stubs.c +++ b/reactos/dll/win32/gdi32/misc/stubs.c @@ -1838,6 +1838,17 @@ GdiIsPlayMetafileDC(HDC hdc) return 0; } +/* + * @unimplemented + */ +BOOL +STDCALL +GdiReleaseDC(HDC hdc) +{ + UNIMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} /* * @unimplemented diff --git a/reactos/dll/win32/gdi32/objects/dc.c b/reactos/dll/win32/gdi32/objects/dc.c index 328ad29303e..714f0fdd463 100644 --- a/reactos/dll/win32/gdi32/objects/dc.c +++ b/reactos/dll/win32/gdi32/objects/dc.c @@ -458,13 +458,3 @@ GetObjectType( SetLastError(ERROR_INVALID_HANDLE); return Ret; } - -/* - * @implemented - */ -BOOL -STDCALL -GdiReleaseDC(HDC hdc) -{ - return NtUserReleaseDC(NULL,hdc); -} From a42c7ad8768471cbcf09f14a5a0523458e2473b5 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 18 Sep 2006 08:56:28 +0000 Subject: [PATCH 266/488] Fix some defines used in fiber.S in kernel32.dll (fixes build) svn path=/trunk/; revision=24189 --- reactos/include/ndk/asm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 15cada7f0c7..5851bcaa5ad 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -322,9 +322,9 @@ Author: #define CONTEXT_EFLAGS 0xC0 #define CONTEXT_ESP 0xC4 #define CONTEXT_SEGSS 0xC8 -#define CONTEXT_FLOAT_SAVE_CONTROL_WORD CONTEXT_FLOAT_SAVE + FN_CONTROL_WORD -#define CONTEXT_FLOAT_SAVE_STATUS_WORD CONTEXT_FLOAT_SAVE + FN_STATUS_WORD -#define CONTEXT_FLOAT_SAVE_TAG_WORD CONTEXT_FLOAT_SAVE + FN_TAG_WORD +#define CONTEXT_FLOAT_SAVE_CONTROL_WORD CONTEXT_FLOAT_SAVE + FP_CONTROL_WORD +#define CONTEXT_FLOAT_SAVE_STATUS_WORD CONTEXT_FLOAT_SAVE + FP_STATUS_WORD +#define CONTEXT_FLOAT_SAVE_TAG_WORD CONTEXT_FLOAT_SAVE + FP_TAG_WORD #define CONTEXT_ALIGNED_SIZE 0x2CC // From f8b5e46f8b3ea2c53dc48566114dc0b6435304b8 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 18 Sep 2006 10:58:00 +0000 Subject: [PATCH 267/488] * fix build svn path=/trunk/; revision=24190 --- reactos/ntoskrnl/ke/i386/usercall_asm.S | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/usercall_asm.S b/reactos/ntoskrnl/ke/i386/usercall_asm.S index 475234a7e7d..11ea1ad213d 100644 --- a/reactos/ntoskrnl/ke/i386/usercall_asm.S +++ b/reactos/ntoskrnl/ke/i386/usercall_asm.S @@ -138,14 +138,14 @@ StackOk: cli /* Now copy the NPX State */ - mov ecx, [esi+FN_CONTROL_WORD] - mov [esp+FN_CONTROL_WORD], ecx - mov ecx, [esi+FN_STATUS_WORD] - mov [esp+FN_STATUS_WORD], ecx - mov ecx, [esi+FN_TAG_WORD] - mov [esp+FN_TAG_WORD], ecx - mov ecx, [esi+FN_DATA_SELECTOR] - mov [esp+FN_DATA_SELECTOR], ecx + mov ecx, [esi+FP_CONTROL_WORD] + mov [esp+FP_CONTROL_WORD], ecx + mov ecx, [esi+FP_STATUS_WORD] + mov [esp+FP_STATUS_WORD], ecx + mov ecx, [esi+FP_TAG_WORD] + mov [esp+FP_TAG_WORD], ecx + mov ecx, [esi+FP_DATA_SELECTOR] + mov [esp+FP_DATA_SELECTOR], ecx mov ecx, [esi+FN_CR0_NPX_STATE] mov [esp+FN_CR0_NPX_STATE], ecx @@ -293,14 +293,14 @@ _NtCallbackReturn@12: sub ebx, NPX_FRAME_LENGTH /* Copy NPX Data */ - mov edx, [esi+FN_CONTROL_WORD] - mov [ebx+FN_CONTROL_WORD], edx - mov edx, [esi+FN_STATUS_WORD] - mov [ebx+FN_STATUS_WORD], edx - mov edx, [esi+FN_TAG_WORD] - mov [ebx+FN_TAG_WORD], edx - mov edx, [esi+FN_DATA_SELECTOR] - mov [ebx+FN_DATA_SELECTOR], edx + mov edx, [esi+FP_CONTROL_WORD] + mov [ebx+FP_CONTROL_WORD], edx + mov edx, [esi+FP_STATUS_WORD] + mov [ebx+FP_STATUS_WORD], edx + mov edx, [esi+FP_TAG_WORD] + mov [ebx+FP_TAG_WORD], edx + mov edx, [esi+FP_DATA_SELECTOR] + mov [ebx+FP_DATA_SELECTOR], edx mov edx, [esi+FN_CR0_NPX_STATE] mov [ebx+FN_CR0_NPX_STATE], edx From ed5305eeae76ead9e940f24acef8e15198f838ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 18 Sep 2006 14:34:40 +0000 Subject: [PATCH 268/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24191 --- reactos/dll/win32/mpr/mpr.rc | 3 +++ reactos/dll/win32/mpr/mpr_Ru.rc | 46 +++++++++++++++++++++++++++++++++ reactos/dll/win32/mpr/mpr_Sv.rc | 46 +++++++++++++++++++++++++++++++++ reactos/dll/win32/mpr/mpr_Uk.rc | 46 +++++++++++++++++++++++++++++++++ reactos/dll/win32/mpr/wnet.c | 6 +++-- 5 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 reactos/dll/win32/mpr/mpr_Ru.rc create mode 100644 reactos/dll/win32/mpr/mpr_Sv.rc create mode 100644 reactos/dll/win32/mpr/mpr_Uk.rc diff --git a/reactos/dll/win32/mpr/mpr.rc b/reactos/dll/win32/mpr/mpr.rc index aa7db7fa693..47bc244a70f 100644 --- a/reactos/dll/win32/mpr/mpr.rc +++ b/reactos/dll/win32/mpr/mpr.rc @@ -38,4 +38,7 @@ #include "mpr_Nl.rc" #include "mpr_No.rc" #include "mpr_Pt.rc" +#include "mpr_Ru.rc" +#include "mpr_Sv.rc" #include "mpr_Tr.rc" +#include "mpr_Uk.rc" diff --git a/reactos/dll/win32/mpr/mpr_Ru.rc b/reactos/dll/win32/mpr/mpr_Ru.rc new file mode 100644 index 00000000000..a81051b0350 --- /dev/null +++ b/reactos/dll/win32/mpr/mpr_Ru.rc @@ -0,0 +1,46 @@ +/* + * MPR dll resources + * + * Copyright (C) 2005 Mikhail Y. Zvyozdochkin + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Âń˙ ńĺňü" +} + +IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Ââĺäčňĺ Ńĺňĺâîé Ďŕđîëü" +FONT 8, "MS Shell Dlg" +{ + LTEXT "Ďîćŕëóéńňŕ, ââĺäčňĺ Âŕřč čě˙ č ďŕđîëü:", IDC_EXPLAIN, 40, 6, 150, 15 + LTEXT "Ďđîęńč-ńĺđâĺđ", -1, 40, 26, 50, 10 +/* LTEXT "Realm", -1, 40, 46, 50, 10 */ + LTEXT "Čě˙ ďîëüçîâŕňĺë˙", -1, 40, 66, 50, 10 + LTEXT "Ďŕđîëü", -1, 40, 86, 50, 10 + LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 + LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 + EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD + CHECKBOX "&Ńîőđŕíčňü ďŕđîëü (íĺáĺçîďŕńíî)", IDC_SAVEPASSWORD, + 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Îňěĺíŕ", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP +} diff --git a/reactos/dll/win32/mpr/mpr_Sv.rc b/reactos/dll/win32/mpr/mpr_Sv.rc new file mode 100644 index 00000000000..eeaa71a5c90 --- /dev/null +++ b/reactos/dll/win32/mpr/mpr_Sv.rc @@ -0,0 +1,46 @@ +/* + * MPR dll Swedish resources + * + * Copyright (C) 2005 Andreas Bjerkeholt + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Hela nätverket" +} + +IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Ange nätverkslösenord" +FONT 8, "MS Shell Dlg" +{ + LTEXT "Ange ditt användarnamn och lösenord:", IDC_EXPLAIN, 40, 6, 150, 15 + LTEXT "Proxy", -1, 40, 26, 50, 10 +/* LTEXT "Realm", -1, 40, 46, 50, 10 */ + LTEXT "Användare", -1, 40, 66, 50, 10 + LTEXT "Lösenord", -1, 40, 86, 50, 10 + LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 + LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 + EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD + CHECKBOX "&Spara detta lösenord (Osäkert)", IDC_SAVEPASSWORD, + 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Avbryt", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP +} diff --git a/reactos/dll/win32/mpr/mpr_Uk.rc b/reactos/dll/win32/mpr/mpr_Uk.rc new file mode 100644 index 00000000000..2b9732a8d34 --- /dev/null +++ b/reactos/dll/win32/mpr/mpr_Uk.rc @@ -0,0 +1,46 @@ +/* + * MPR dll resources (Ukrainian) + * + * Copyright 2006 Artem Reznikov + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_ENTIRENETWORK "Âń˙ Ěĺđĺćŕ" +} + +IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Ââĺäłňü Ěĺđĺćíčé Ďŕđîëü" +FONT 8, "MS Shell Dlg" +{ + LTEXT "Áóäü ëŕńęŕ, ââĺäłňü Âŕřł łě'˙ ňŕ ďŕđîëü:", IDC_EXPLAIN, 40, 6, 150, 15 + LTEXT "Ďđîęńł", -1, 40, 26, 50, 10 +/* LTEXT "Realm", -1, 40, 46, 50, 10 */ + LTEXT "Ęîđčńňóâŕ÷", -1, 40, 66, 50, 10 + LTEXT "Ďŕđîëü", -1, 40, 86, 50, 10 + LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 + LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 + EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD + CHECKBOX "&Çáĺđĺăňč öĺé ďŕđîëü (íĺáĺçďĺ÷íî)", IDC_SAVEPASSWORD, + 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Ńęŕńóâŕňč", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP +} diff --git a/reactos/dll/win32/mpr/wnet.c b/reactos/dll/win32/mpr/wnet.c index 804b4571322..c099c68d1ee 100644 --- a/reactos/dll/win32/mpr/wnet.c +++ b/reactos/dll/win32/mpr/wnet.c @@ -260,8 +260,10 @@ void wnetInit(HINSTANCE hInstDll) for (ptr = providers, numToAllocate = 1; ptr; ) { ptr = strchrW(ptr, ','); - if (ptr) + if (ptr) { numToAllocate++; + ptr++; + } } providerTable = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, @@ -287,7 +289,7 @@ void wnetInit(HINSTANCE hInstDll) ptrPrev = ptr; ptr = strchrW(ptr, ','); if (ptr) - *ptr = '\0'; + *ptr++ = '\0'; _tryLoadProvider(ptrPrev); } } From fab72e48ec3d029541e15668073fc3f2dc34708d Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:28:29 +0000 Subject: [PATCH 269/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24192 --- reactos/dll/win32/advpack/files.c | 13 ++-- reactos/dll/win32/advpack/install.c | 98 +++++++++++++++++++++++------ 2 files changed, 85 insertions(+), 26 deletions(-) diff --git a/reactos/dll/win32/advpack/files.c b/reactos/dll/win32/advpack/files.c index 86cf70f6809..1d024438591 100644 --- a/reactos/dll/win32/advpack/files.c +++ b/reactos/dll/win32/advpack/files.c @@ -116,7 +116,7 @@ HRESULT WINAPI AddDelBackupEntryW(LPCWSTR lpcszFileList, LPCWSTR lpcszBackupDir, LPCWSTR lpcszBaseName, DWORD dwFlags) { WCHAR szIniPath[MAX_PATH]; - LPWSTR szString = NULL; + LPCWSTR szString = NULL; static const WCHAR szBackupEntry[] = { '-','1',',','0',',','0',',','0',',','0',',','0',',','-','1',0 @@ -144,7 +144,7 @@ HRESULT WINAPI AddDelBackupEntryW(LPCWSTR lpcszFileList, LPCWSTR lpcszBackupDir, SetFileAttributesW(szIniPath, FILE_ATTRIBUTE_NORMAL); if (dwFlags & AADBE_ADD_ENTRY) - szString = (LPWSTR)szBackupEntry; + szString = szBackupEntry; else if (dwFlags & AADBE_DEL_ENTRY) szString = NULL; @@ -249,7 +249,8 @@ HRESULT WINAPI AdvInstallFileW(HWND hwnd, LPCWSTR lpszSourceDir, LPCWSTR lpszSou DWORD dwFlags, DWORD dwReserved) { PSP_FILE_CALLBACK_W pFileCallback; - LPWSTR szPath, szDestFilename; + LPWSTR szDestFilename; + LPCWSTR szPath; WCHAR szRootPath[ROOT_LENGTH]; DWORD dwLen, dwLastError; HSPFILEQ fileQueue; @@ -270,7 +271,7 @@ HRESULT WINAPI AdvInstallFileW(HWND hwnd, LPCWSTR lpszSourceDir, LPCWSTR lpszSou dwLastError = ERROR_SUCCESS; lstrcpynW(szRootPath, lpszSourceDir, ROOT_LENGTH); - szPath = (LPWSTR)lpszSourceDir + ROOT_LENGTH; + szPath = lpszSourceDir + ROOT_LENGTH; /* use lpszSourceFile as destination filename if lpszDestFile is NULL */ if (lpszDestFile) @@ -547,8 +548,8 @@ static HRESULT (WINAPI *pExtract)(EXTRACTdest*, LPCSTR); static LPSTR convert_file_list(LPCSTR FileList, DWORD *dwNumFiles) { DWORD dwLen; - char *first = (char *)FileList; - char *last = (char *)FileList + strlen(FileList) - 1; + const char *first = FileList; + const char *last = FileList + strlen(FileList) - 1; LPSTR szConvertedList, temp; /* any number of these chars before the list is OK */ diff --git a/reactos/dll/win32/advpack/install.c b/reactos/dll/win32/advpack/install.c index 2398b7587cb..8f356bac08a 100644 --- a/reactos/dll/win32/advpack/install.c +++ b/reactos/dll/win32/advpack/install.c @@ -50,6 +50,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(advpack); typedef struct _ADVInfo { HINF hinf; + LPWSTR inf_path; LPWSTR inf_filename; LPWSTR install_sec; LPWSTR working_dir; @@ -326,7 +327,7 @@ static HRESULT spapi_install(ADVInfo *info) SetupTermDefaultQueueCallback(context); ret = SetupInstallFromInfSectionW(NULL, info->hinf, info->install_sec, - SPINST_INIFILES | SPINST_REGISTRY, + SPINST_INIFILES | SPINST_REGISTRY | SPINST_REGSVR, HKEY_LOCAL_MACHINE, NULL, 0, NULL, NULL, NULL, NULL); if (!ret) @@ -372,24 +373,80 @@ static HRESULT adv_install(ADVInfo *info) return hr; } +/* determines the proper working directory for the INF file */ +static HRESULT get_working_dir(ADVInfo *info, LPCWSTR inf_filename, LPCWSTR working_dir) +{ + WCHAR path[MAX_PATH]; + LPCWSTR ptr; + DWORD len; + + static const WCHAR backslash[] = {'\\',0}; + static const WCHAR inf_dir[] = {'\\','I','N','F',0}; + + if ((ptr = strrchrW(inf_filename, '\\'))) + { + len = ptr - inf_filename + 1; + ptr = inf_filename; + } + else if (working_dir && *working_dir) + { + len = lstrlenW(working_dir) + 1; + ptr = working_dir; + } + else + { + GetCurrentDirectoryW(MAX_PATH, path); + lstrcatW(path, backslash); + lstrcatW(path, inf_filename); + + /* check if the INF file is in the current directory */ + if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES) + { + GetCurrentDirectoryW(MAX_PATH, path); + } + else + { + /* default to the windows\inf directory if all else fails */ + GetWindowsDirectoryW(path, MAX_PATH); + lstrcatW(path, inf_dir); + } + + len = lstrlenW(path) + 1; + ptr = path; + } + + info->working_dir = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!info->working_dir) + return E_OUTOFMEMORY; + + lstrcpynW(info->working_dir, ptr, len); + + return S_OK; +} + /* loads the INF file and performs checks on it */ HRESULT install_init(LPCWSTR inf_filename, LPCWSTR install_sec, LPCWSTR working_dir, DWORD flags, ADVInfo *info) { DWORD len; - LPCWSTR ptr; + HRESULT hr; + LPCWSTR ptr, path; + static const WCHAR backslash[] = {'\\',0}; static const WCHAR default_install[] = { 'D','e','f','a','u','l','t','I','n','s','t','a','l','l',0 }; - len = lstrlenW(inf_filename); + if (!(ptr = strrchrW(inf_filename, '\\'))) + ptr = inf_filename; + + len = lstrlenW(ptr); info->inf_filename = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); if (!info->inf_filename) return E_OUTOFMEMORY; - lstrcpyW(info->inf_filename, inf_filename); + lstrcpyW(info->inf_filename, ptr); /* FIXME: determine the proper platform to install (NTx86, etc) */ if (!install_sec || !*install_sec) @@ -409,26 +466,26 @@ HRESULT install_init(LPCWSTR inf_filename, LPCWSTR install_sec, lstrcpyW(info->install_sec, ptr); - /* FIXME: need to get the real working directory */ - if (!working_dir || !*working_dir) - { - ptr = strrchrW(info->inf_filename, '\\'); - len = ptr - info->inf_filename + 1; - ptr = info->inf_filename; - } - else - { - len = lstrlenW(working_dir) + 1; - ptr = working_dir; - } + hr = get_working_dir(info, inf_filename, working_dir); + if (FAILED(hr)) + return hr; - info->working_dir = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - if (!info->working_dir) + len = lstrlenW(info->working_dir) + lstrlenW(info->inf_filename) + 2; + info->inf_path = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!info->inf_path) return E_OUTOFMEMORY; - lstrcpynW(info->working_dir, ptr, len); + lstrcpyW(info->inf_path, info->working_dir); + lstrcatW(info->inf_path, backslash); + lstrcatW(info->inf_path, info->inf_filename); - info->hinf = SetupOpenInfFileW(info->inf_filename, NULL, INF_STYLE_WIN4, NULL); + /* RunSetupCommand opens unmodifed filename parameter */ + if (flags & RSC_FLAG_INF) + path = inf_filename; + else + path = info->inf_path; + + info->hinf = SetupOpenInfFileW(path, NULL, INF_STYLE_WIN4, NULL); if (info->hinf == INVALID_HANDLE_VALUE) return ADV_HRESULT(GetLastError()); @@ -448,6 +505,7 @@ void install_release(ADVInfo *info) if (info->hinf && info->hinf != INVALID_HANDLE_VALUE) SetupCloseInfFile(info->hinf); + HeapFree(GetProcessHeap(), 0, info->inf_path); HeapFree(GetProcessHeap(), 0, info->inf_filename); HeapFree(GetProcessHeap(), 0, info->install_sec); HeapFree(GetProcessHeap(), 0, info->working_dir); From 8bde95b20e1895fca6509baa64eac733fc56a4d5 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:32:05 +0000 Subject: [PATCH 270/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24193 --- reactos/dll/win32/avifil32/acmstream.c | 48 ++++---- reactos/dll/win32/avifil32/api.c | 75 ++++++------ reactos/dll/win32/avifil32/avifil32.rbuild | 16 ++- reactos/dll/win32/avifil32/avifil32_ros.diff | 10 -- reactos/dll/win32/avifil32/avifile.c | 114 +++++++++---------- reactos/dll/win32/avifil32/avifile_Cs.rc | 19 ++-- reactos/dll/win32/avifil32/avifile_De.rc | 2 +- reactos/dll/win32/avifil32/avifile_En.rc | 4 +- reactos/dll/win32/avifil32/avifile_Es.rc | 2 +- reactos/dll/win32/avifil32/avifile_Fr.rc | 2 +- reactos/dll/win32/avifil32/avifile_Hu.rc | 50 ++++++++ reactos/dll/win32/avifil32/avifile_It.rc | 4 +- reactos/dll/win32/avifil32/avifile_Ja.rc | 2 +- reactos/dll/win32/avifil32/avifile_Ko.rc | 2 +- reactos/dll/win32/avifil32/avifile_Nl.rc | 4 +- reactos/dll/win32/avifil32/avifile_No.rc | 2 +- reactos/dll/win32/avifil32/avifile_Pl.rc | 4 +- reactos/dll/win32/avifil32/avifile_Pt.rc | 4 +- reactos/dll/win32/avifil32/avifile_Ru.rc | 4 +- reactos/dll/win32/avifil32/avifile_Si.rc | 4 +- reactos/dll/win32/avifil32/avifile_Tr.rc | 50 ++++++++ reactos/dll/win32/avifil32/avifile_private.h | 2 +- reactos/dll/win32/avifil32/editstream.c | 34 +++--- reactos/dll/win32/avifil32/extrachunk.c | 16 ++- reactos/dll/win32/avifil32/extrachunk.h | 2 +- reactos/dll/win32/avifil32/factory.c | 9 +- reactos/dll/win32/avifil32/getframe.c | 30 ++--- reactos/dll/win32/avifil32/icmstream.c | 39 +++---- reactos/dll/win32/avifil32/regsvr.c | 9 +- reactos/dll/win32/avifil32/rsrc.rc | 4 +- reactos/dll/win32/avifil32/tmpfile.c | 12 +- reactos/dll/win32/avifil32/wavfile.c | 37 +++--- 32 files changed, 332 insertions(+), 284 deletions(-) create mode 100644 reactos/dll/win32/avifil32/avifile_Hu.rc create mode 100644 reactos/dll/win32/avifil32/avifile_Tr.rc diff --git a/reactos/dll/win32/avifil32/acmstream.c b/reactos/dll/win32/avifil32/acmstream.c index 68bab9ef07d..19dc98150da 100644 --- a/reactos/dll/win32/avifil32/acmstream.c +++ b/reactos/dll/win32/avifil32/acmstream.c @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COM_NO_WINDOWS_H @@ -26,9 +26,7 @@ #include "winuser.h" #include "winnls.h" #include "winerror.h" -#include "windowsx.h" #include "mmsystem.h" -#include "mmreg.h" #include "vfw.h" #include "msacm.h" @@ -117,7 +115,7 @@ HRESULT AVIFILE_CreateACMStream(REFIID riid, LPVOID *ppv) *ppv = NULL; - pstream = (IAVIStreamImpl*)LocalAlloc(LPTR, sizeof(IAVIStreamImpl)); + pstream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIStreamImpl)); if (pstream == NULL) return AVIERR_MEMORY; @@ -125,7 +123,7 @@ HRESULT AVIFILE_CreateACMStream(REFIID riid, LPVOID *ppv) hr = IAVIStream_QueryInterface((IAVIStream*)pstream, riid, ppv); if (FAILED(hr)) - LocalFree((HLOCAL)pstream); + HeapFree(GetProcessHeap(), 0, pstream); return hr; } @@ -177,21 +175,17 @@ static ULONG WINAPI ACMStream_fnRelease(IAVIStream* iface) acmStreamClose(This->has, 0); This->has = NULL; } - if (This->acmStreamHdr.pbSrc != NULL) { - GlobalFreePtr(This->acmStreamHdr.pbSrc); - This->acmStreamHdr.pbSrc = NULL; - } - if (This->acmStreamHdr.pbDst != NULL) { - GlobalFreePtr(This->acmStreamHdr.pbDst); - This->acmStreamHdr.pbDst = NULL; - } + HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc); + This->acmStreamHdr.pbSrc = NULL; + HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbDst); + This->acmStreamHdr.pbDst = NULL; if (This->lpInFormat != NULL) { - GlobalFreePtr(This->lpInFormat); + HeapFree(GetProcessHeap(), 0, This->lpInFormat); This->lpInFormat = NULL; This->cbInFormat = 0; } if (This->lpOutFormat != NULL) { - GlobalFreePtr(This->lpOutFormat); + HeapFree(GetProcessHeap(), 0, This->lpOutFormat); This->lpOutFormat = NULL; This->cbOutFormat = 0; } @@ -199,7 +193,7 @@ static ULONG WINAPI ACMStream_fnRelease(IAVIStream* iface) IAVIStream_Release(This->pStream); This->pStream = NULL; } - LocalFree((HLOCAL)This); + HeapFree(GetProcessHeap(), 0, This); return 0; } @@ -251,7 +245,7 @@ static HRESULT WINAPI ACMStream_fnCreate(IAVIStream *iface, LPARAM lParam1, else This->cbOutFormat = sizeof(PCMWAVEFORMAT); - This->lpOutFormat = (LPWAVEFORMATEX)GlobalAllocPtr(GHND, This->cbOutFormat); + This->lpOutFormat = HeapAlloc(GetProcessHeap(), 0, This->cbOutFormat); if (This->lpOutFormat == NULL) return AVIERR_MEMORY; @@ -384,7 +378,7 @@ static HRESULT WINAPI ACMStream_fnSetFormat(IAVIStream *iface, LONG pos, if ((This->sInfo.dwCaps & AVIFILECAPS_CANWRITE) == 0) return AVIERR_READONLY; - This->lpInFormat = (LPWAVEFORMATEX)GlobalAllocPtr(GMEM_MOVEABLE, formatsize); + This->lpInFormat = HeapAlloc(GetProcessHeap(), 0, formatsize); if (This->lpInFormat == NULL) return AVIERR_MEMORY; This->cbInFormat = formatsize; @@ -464,7 +458,7 @@ static HRESULT WINAPI ACMStream_fnRead(IAVIStream *iface, LONG start, /* Need to free destination buffer used for writing? */ if (This->acmStreamHdr.pbDst != NULL) { - GlobalFreePtr(This->acmStreamHdr.pbDst); + HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbDst); This->acmStreamHdr.pbDst = NULL; This->acmStreamHdr.dwDstUser = 0; } @@ -473,10 +467,9 @@ static HRESULT WINAPI ACMStream_fnRead(IAVIStream *iface, LONG start, if (This->acmStreamHdr.pbSrc == NULL || This->acmStreamHdr.dwSrcUser < size) { if (This->acmStreamHdr.pbSrc == NULL) - This->acmStreamHdr.pbSrc = GlobalAllocPtr(GMEM_MOVEABLE, size); + This->acmStreamHdr.pbSrc = HeapAlloc(GetProcessHeap(), 0, size); else - This->acmStreamHdr.pbSrc = GlobalReAllocPtr(This->acmStreamHdr.pbSrc, - size, GMEM_MOVEABLE); + This->acmStreamHdr.pbDst = HeapReAlloc(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc, size); if (This->acmStreamHdr.pbSrc == NULL) return AVIERR_MEMORY; This->acmStreamHdr.dwSrcUser = size; @@ -568,7 +561,7 @@ static HRESULT WINAPI ACMStream_fnWrite(IAVIStream *iface, LONG start, /* Need to free source buffer used for reading? */ if (This->acmStreamHdr.pbSrc != NULL) { - GlobalFreePtr(This->acmStreamHdr.pbSrc); + HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc); This->acmStreamHdr.pbSrc = NULL; This->acmStreamHdr.dwSrcUser = 0; } @@ -577,10 +570,9 @@ static HRESULT WINAPI ACMStream_fnWrite(IAVIStream *iface, LONG start, if (This->acmStreamHdr.pbDst == NULL || This->acmStreamHdr.dwDstUser < size) { if (This->acmStreamHdr.pbDst == NULL) - This->acmStreamHdr.pbDst = GlobalAllocPtr(GMEM_MOVEABLE, size); + This->acmStreamHdr.pbDst = HeapAlloc(GetProcessHeap(), 0, size); else - This->acmStreamHdr.pbDst = GlobalReAllocPtr(This->acmStreamHdr.pbDst, - size, GMEM_MOVEABLE); + This->acmStreamHdr.pbDst = HeapReAlloc(GetProcessHeap(), 0, This->acmStreamHdr.pbDst, size); if (This->acmStreamHdr.pbDst == NULL) return AVIERR_MEMORY; This->acmStreamHdr.dwDstUser = size; @@ -704,7 +696,7 @@ static HRESULT AVIFILE_OpenCompressor(IAVIStreamImpl *This) hr = AVIStreamFormatSize(This->pStream, This->sInfo.dwStart, &This->cbInFormat); if (FAILED(hr)) return hr; - This->lpInFormat = (LPWAVEFORMATEX)GlobalAllocPtr(GMEM_MOVEABLE, This->cbInFormat); + This->lpInFormat = HeapAlloc(GetProcessHeap(), 0, This->cbInFormat); if (This->lpInFormat == NULL) return AVIERR_MEMORY; @@ -716,7 +708,7 @@ static HRESULT AVIFILE_OpenCompressor(IAVIStreamImpl *This) if (This->lpOutFormat == NULL) { /* we must decode to default format */ This->cbOutFormat = sizeof(PCMWAVEFORMAT); - This->lpOutFormat = (LPWAVEFORMATEX)GlobalAllocPtr(GHND, This->cbOutFormat); + This->lpOutFormat = HeapAlloc(GetProcessHeap(), 0, This->cbOutFormat); if (This->lpOutFormat == NULL) return AVIERR_MEMORY; diff --git a/reactos/dll/win32/avifil32/api.c b/reactos/dll/win32/avifil32/api.c index 1b89f1075c9..182e72fea3e 100644 --- a/reactos/dll/win32/avifil32/api.c +++ b/reactos/dll/win32/avifil32/api.c @@ -14,7 +14,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -30,12 +30,10 @@ #include "winuser.h" #include "winreg.h" #include "winerror.h" -#include "windowsx.h" #include "ole2.h" #include "shellapi.h" #include "shlobj.h" -#include "mmreg.h" #include "vfw.h" #include "msacm.h" @@ -216,7 +214,7 @@ HRESULT WINAPI AVIFileOpenA(PAVIFILE *ppfile, LPCSTR szFile, UINT uMode, if (len <= 0) return AVIERR_BADPARAM; - wszFile = (LPWSTR)LocalAlloc(LPTR, len * sizeof(WCHAR)); + wszFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if (wszFile == NULL) return AVIERR_MEMORY; @@ -224,7 +222,7 @@ HRESULT WINAPI AVIFileOpenA(PAVIFILE *ppfile, LPCSTR szFile, UINT uMode, hr = AVIFileOpenW(ppfile, wszFile, uMode, lpHandler); - LocalFree((HLOCAL)wszFile); + HeapFree(GetProcessHeap(), 0, wszFile); return hr; } @@ -1010,7 +1008,7 @@ HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving) szFilter[0] = 0; szFilter[1] = 0; - wszFilter = (LPWSTR)GlobalAllocPtr(GHND, cbFilter * sizeof(WCHAR)); + wszFilter = HeapAlloc(GetProcessHeap(), 0, cbFilter * sizeof(WCHAR)); if (wszFilter == NULL) return AVIERR_MEMORY; @@ -1020,7 +1018,7 @@ HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving) szFilter, cbFilter, NULL, NULL); } - GlobalFreePtr(wszFilter); + HeapFree(GetProcessHeap(), 0, wszFilter); return hr; } @@ -1052,7 +1050,7 @@ HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving) if (cbFilter < 2) return AVIERR_BADSIZE; - lp = (AVIFilter*)GlobalAllocPtr(GHND, MAX_FILTERS * sizeof(AVIFilter)); + lp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_FILTERS * sizeof(AVIFilter)); if (lp == NULL) return AVIERR_MEMORY; @@ -1066,7 +1064,7 @@ HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving) * collection of all possible extensions except "*.*". */ if (RegOpenKeyW(HKEY_CLASSES_ROOT, szAVIFileExtensions, &hKey) != S_OK) { - GlobalFreePtr(lp); + HeapFree(GetProcessHeap(), 0, lp); return AVIERR_ERROR; } for (n = 0;RegEnumKeyW(hKey, n, szFileExt, sizeof(szFileExt)) == S_OK;n++) { @@ -1114,7 +1112,7 @@ HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving) /* 2. get descriptions for the CLSIDs and fill out szFilter */ if (RegOpenKeyW(HKEY_CLASSES_ROOT, szClsid, &hKey) != S_OK) { - GlobalFreePtr(lp); + HeapFree(GetProcessHeap(), 0, lp); return AVIERR_ERROR; } for (n = 0; n <= count; n++) { @@ -1133,7 +1131,7 @@ HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving) if (cbFilter < size + lstrlenW(lp[n].szExtensions) + 2) { szFilter[0] = 0; szFilter[1] = 0; - GlobalFreePtr(lp); + HeapFree(GetProcessHeap(), 0, lp); RegCloseKey(hKey); return AVIERR_BUFFERTOOSMALL; } @@ -1148,7 +1146,7 @@ HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving) } RegCloseKey(hKey); - GlobalFreePtr(lp); + HeapFree(GetProcessHeap(), 0, lp); /* add "All files" "*.*" filter if enough space left */ size = LoadStringW(AVIFILE_hModule, IDS_ALLFILES, @@ -1259,10 +1257,10 @@ static BOOL AVISaveOptionsFmtChoose(HWND hWnd) acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &size); if ((pOptions->cbFormat == 0 || pOptions->lpFormat == NULL) && size != 0) { - pOptions->lpFormat = GlobalAllocPtr(GMEM_MOVEABLE, size); + pOptions->lpFormat = HeapAlloc(GetProcessHeap(), 0, size); pOptions->cbFormat = size; } else if (pOptions->cbFormat < (DWORD)size) { - pOptions->lpFormat = GlobalReAllocPtr(pOptions->lpFormat, size, GMEM_MOVEABLE); + pOptions->lpFormat = HeapReAlloc(GetProcessHeap(), 0, pOptions->lpFormat, size); pOptions->cbFormat = size; } if (pOptions->lpFormat == NULL) @@ -1275,7 +1273,7 @@ static BOOL AVISaveOptionsFmtChoose(HWND hWnd) sInfo.dwStart, &size); if (size < (LONG)sizeof(PCMWAVEFORMAT)) size = sizeof(PCMWAVEFORMAT); - afmtc.pwfxEnum = GlobalAllocPtr(GHND, size); + afmtc.pwfxEnum = HeapAlloc(GetProcessHeap(), 0, size); if (afmtc.pwfxEnum != NULL) { AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent], sInfo.dwStart, afmtc.pwfxEnum, &size); @@ -1286,9 +1284,7 @@ static BOOL AVISaveOptionsFmtChoose(HWND hWnd) if (ret == S_OK) pOptions->dwFlags |= AVICOMPRESSF_VALID; - if (afmtc.pwfxEnum != NULL) - GlobalFreePtr(afmtc.pwfxEnum); - + HeapFree(GetProcessHeap(), 0, afmtc.pwfxEnum); return (ret == S_OK ? TRUE : FALSE); } else { ERR(": unknown streamtype 0x%08lX\n", sInfo.fccType); @@ -1320,7 +1316,7 @@ static void AVISaveOptionsUpdate(HWND hWnd) szFormat[0] = 0; /* read format to build format description string */ - lpFormat = GlobalAllocPtr(GHND, size); + lpFormat = HeapAlloc(GetProcessHeap(), 0, size); if (lpFormat != NULL) { if (SUCCEEDED(AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,lpFormat, &size))) { if (sInfo.fccType == streamtypeVIDEO) { @@ -1367,7 +1363,7 @@ static void AVISaveOptionsUpdate(HWND hWnd) } } } - GlobalFreePtr(lpFormat); + HeapFree(GetProcessHeap(), 0, lpFormat); } /* set text for format description */ @@ -1411,8 +1407,7 @@ static INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg, /* select first stream */ SendDlgItemMessageW(hWnd, IDC_STREAM, CB_SETCURSEL, 0, 0); - SendMessageW(hWnd, WM_COMMAND, - GET_WM_COMMAND_MPS(IDC_STREAM, hWnd, CBN_SELCHANGE)); + SendMessageW(hWnd, WM_COMMAND, MAKELONG(IDC_STREAM, CBN_SELCHANGE), (LPARAM)hWnd); /* initialize interleave */ if (SaveOpts.ppOptions[0] != NULL && @@ -1428,7 +1423,7 @@ static INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg, EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), bIsInterleaved); break; case WM_COMMAND: - switch (GET_WM_COMMAND_ID(wParam, lParam)) { + switch (LOWORD(wParam)) { case IDOK: /* get data from controls and save them */ dwInterleave = GetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, NULL, 0); @@ -1444,14 +1439,14 @@ static INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg, } /* fall through */ case IDCANCEL: - EndDialog(hWnd, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); + EndDialog(hWnd, LOWORD(wParam) == IDOK); break; case IDC_INTERLEAVE: EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), IsDlgButtonChecked(hWnd, IDC_INTERLEAVE)); break; case IDC_STREAM: - if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) { + if (HIWORD(wParam) == CBN_SELCHANGE) { /* update control elements */ AVISaveOptionsUpdate(hWnd); } @@ -1484,7 +1479,7 @@ BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams, /* save options in case the user presses cancel */ if (ppOptions != NULL && nStreams > 1) { - pSavedOptions = GlobalAllocPtr(GHND,nStreams * sizeof(AVICOMPRESSOPTIONS)); + pSavedOptions = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(AVICOMPRESSOPTIONS)); if (pSavedOptions == NULL) return FALSE; @@ -1513,7 +1508,7 @@ BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams, memcpy(ppOptions[n], pSavedOptions + n, sizeof(AVICOMPRESSOPTIONS)); } } - GlobalFreePtr(pSavedOptions); + HeapFree(GetProcessHeap(), 0, pSavedOptions); } return (BOOL)ret; @@ -1535,12 +1530,12 @@ HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions) ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID; if (ppOptions[nStreams]->lpParms != NULL) { - GlobalFreePtr(ppOptions[nStreams]->lpParms); + HeapFree(GetProcessHeap(), 0, ppOptions[nStreams]->lpParms); ppOptions[nStreams]->lpParms = NULL; ppOptions[nStreams]->cbParms = 0; } if (ppOptions[nStreams]->lpFormat != NULL) { - GlobalFreePtr(ppOptions[nStreams]->lpFormat); + HeapFree(GetProcessHeap(), 0, ppOptions[nStreams]->lpFormat); ppOptions[nStreams]->lpFormat = NULL; ppOptions[nStreams]->cbFormat = 0; } @@ -1572,7 +1567,7 @@ HRESULT WINAPI AVISaveVA(LPCSTR szFile, CLSID *pclsidHandler, if (len <= 0) return AVIERR_BADPARAM; - wszFile = LocalAlloc(LPTR, len * sizeof(WCHAR)); + wszFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if (wszFile == NULL) return AVIERR_MEMORY; @@ -1581,7 +1576,7 @@ HRESULT WINAPI AVISaveVA(LPCSTR szFile, CLSID *pclsidHandler, hr = AVISaveVW(wszFile, pclsidHandler, lpfnCallback, nStream, ppavi, plpOptions); - LocalFree((HLOCAL)wszFile); + HeapFree(GetProcessHeap(), 0, wszFile); return hr; } @@ -1722,7 +1717,8 @@ HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler, } /* allocate buffer for formats, data, etc. of an initial size of 64 kBytes*/ - lpBuffer = GlobalAllocPtr(GPTR, cbBuffer = 0x00010000); + cbBuffer = 0x00010000; + lpBuffer = HeapAlloc(GetProcessHeap(), 0, cbBuffer); if (lpBuffer == NULL) { hres = AVIERR_MEMORY; goto error; @@ -1865,7 +1861,7 @@ HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler, lFirstVideo - lStart[curStream], lpBuffer, cbBuffer, &lReadBytes, &lReadSamples); } while ((hres == AVIERR_BUFFERTOOSMALL) && - (lpBuffer = GlobalReAllocPtr(lpBuffer, cbBuffer *= 2, GPTR)) != NULL); + (lpBuffer = HeapReAlloc(GetProcessHeap(), 0, lpBuffer, cbBuffer *= 2)) != NULL); if (lpBuffer == NULL) hres = AVIERR_MEMORY; if (FAILED(hres)) @@ -1934,7 +1930,7 @@ HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler, hres = AVIStreamRead(pInStreams[curStream],sInfo.dwStart,lSamples, lpBuffer,cbBuffer,&lReadBytes,&lReadSamples); } while ((hres == AVIERR_BUFFERTOOSMALL) && - (lpBuffer = GlobalReAllocPtr(lpBuffer, cbBuffer *= 2, GPTR)) != NULL); + (lpBuffer = HeapReAlloc(GetProcessHeap(), 0, lpBuffer, cbBuffer *= 2)) != NULL); if (lpBuffer == NULL) hres = AVIERR_MEMORY; if (FAILED(hres)) @@ -1980,7 +1976,7 @@ HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler, hres = AVIStreamRead(pInStreams[curStream], sInfo.dwStart, 1, lpBuffer, cbBuffer,&lReadBytes,&lReadSamples); } while ((hres == AVIERR_BUFFERTOOSMALL) && - (lpBuffer = GlobalReAllocPtr(lpBuffer, cbBuffer *= 2, GPTR)) != NULL); + (lpBuffer = HeapReAlloc(GetProcessHeap(), 0, lpBuffer, cbBuffer *= 2)) != NULL); if (lpBuffer == NULL) hres = AVIERR_MEMORY; if (FAILED(hres)) @@ -2009,8 +2005,7 @@ HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler, } error: - if (lpBuffer != NULL) - GlobalFreePtr(lpBuffer); + HeapFree(GetProcessHeap(), 0, lpBuffer); if (pfile != NULL) { for (curStream = 0; curStream < nStreams; curStream++) { if (pOutStreams[curStream] != NULL) @@ -2194,7 +2189,7 @@ HRESULT WINAPI EditStreamSetInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi, memcpy(&asiw, asi, sizeof(asiw) - sizeof(asiw.szName)); MultiByteToWideChar(CP_ACP, 0, asi->szName, -1, - asiw.szName, sizeof(asiw.szName)); + asiw.szName, sizeof(asiw.szName)/sizeof(WCHAR)); return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw)); } @@ -2320,7 +2315,7 @@ HRESULT WINAPI AVIPutFileOnClipboard(PAVIFILE pfile) return AVIERR_UNSUPPORTED; } -HRESULT CDECL AVISaveA(LPCSTR szFile, CLSID * pclsidHandler, AVISAVECALLBACK lpfnCallback, +HRESULT WINAPIV AVISaveA(LPCSTR szFile, CLSID * pclsidHandler, AVISAVECALLBACK lpfnCallback, int nStreams, PAVISTREAM pavi, LPAVICOMPRESSOPTIONS lpOptions, ...) { FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_a(szFile), pclsidHandler, lpfnCallback, @@ -2329,7 +2324,7 @@ HRESULT CDECL AVISaveA(LPCSTR szFile, CLSID * pclsidHandler, AVISAVECALLBACK lpf return AVIERR_UNSUPPORTED; } -HRESULT CDECL AVISaveW(LPCWSTR szFile, CLSID * pclsidHandler, AVISAVECALLBACK lpfnCallback, +HRESULT WINAPIV AVISaveW(LPCWSTR szFile, CLSID * pclsidHandler, AVISAVECALLBACK lpfnCallback, int nStreams, PAVISTREAM pavi, LPAVICOMPRESSOPTIONS lpOptions, ...) { FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_w(szFile), pclsidHandler, lpfnCallback, diff --git a/reactos/dll/win32/avifil32/avifil32.rbuild b/reactos/dll/win32/avifil32/avifil32.rbuild index bf68667f587..e973dd58435 100644 --- a/reactos/dll/win32/avifil32/avifil32.rbuild +++ b/reactos/dll/win32/avifil32/avifil32.rbuild @@ -3,18 +3,22 @@ . include/reactos/wine + + + 0x600 0x501 + 0x501 wine - uuid - ntdll + msacm32 + msvfw32 winmm ole32 - msvfw32 - msacm32 - kernel32 - advapi32 user32 + advapi32 + kernel32 + uuid + ntdll acmstream.c api.c avifile.c diff --git a/reactos/dll/win32/avifil32/avifil32_ros.diff b/reactos/dll/win32/avifil32/avifil32_ros.diff index 0b3ed5cd352..fe187246703 100644 --- a/reactos/dll/win32/avifil32/avifil32_ros.diff +++ b/reactos/dll/win32/avifil32/avifil32_ros.diff @@ -1,13 +1,3 @@ -Index: avifil32.rbuild -=================================================================== ---- avifil32.rbuild (revision 23782) -+++ avifil32.rbuild (working copy) -@@ -1,4 +1,5 @@ - -+ - - . - include/reactos/wine Index: avifile_private.h =================================================================== --- avifile_private.h (revision 23782) diff --git a/reactos/dll/win32/avifil32/avifile.c b/reactos/dll/win32/avifil32/avifile.c index 9efaab926cd..180562349db 100644 --- a/reactos/dll/win32/avifil32/avifile.c +++ b/reactos/dll/win32/avifil32/avifile.c @@ -14,7 +14,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ /* TODO: @@ -40,9 +40,7 @@ #include "winuser.h" #include "winnls.h" #include "winerror.h" -#include "windowsx.h" #include "mmsystem.h" -#include "mmreg.h" #include "vfw.h" #include "avifile_private.h" @@ -241,7 +239,7 @@ HRESULT AVIFILE_CreateAVIFile(REFIID riid, LPVOID *ppv) *ppv = NULL; - pfile = (IAVIFileImpl*)LocalAlloc(LPTR, sizeof(IAVIFileImpl)); + pfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIFileImpl)); if (pfile == NULL) return AVIERR_MEMORY; @@ -252,7 +250,7 @@ HRESULT AVIFILE_CreateAVIFile(REFIID riid, LPVOID *ppv) hr = IAVIFile_QueryInterface((IAVIFile*)pfile, riid, ppv); if (FAILED(hr)) - LocalFree((HLOCAL)pfile); + HeapFree(GetProcessHeap(), 0, pfile); return hr; } @@ -311,33 +309,32 @@ static ULONG WINAPI IAVIFile_fnRelease(IAVIFile *iface) This->ppStreams[i]->ref, i, This->ppStreams[i]); } AVIFILE_DestructAVIStream(This->ppStreams[i]); - LocalFree((HLOCAL)This->ppStreams[i]); + HeapFree(GetProcessHeap(), 0, This->ppStreams[i]); This->ppStreams[i] = NULL; } } if (This->idxRecords != NULL) { - GlobalFreePtr(This->idxRecords); + HeapFree(GetProcessHeap(), 0, This->idxRecords); This->idxRecords = NULL; This->nIdxRecords = 0; } if (This->fileextra.lp != NULL) { - GlobalFreePtr(This->fileextra.lp); + HeapFree(GetProcessHeap(), 0, This->fileextra.lp); This->fileextra.lp = NULL; This->fileextra.cb = 0; } - if (This->szFileName != NULL) { - LocalFree((HLOCAL)This->szFileName); - This->szFileName = NULL; - } + HeapFree(GetProcessHeap(), 0, This->szFileName); + This->szFileName = NULL; + if (This->hmmio != NULL) { mmioClose(This->hmmio, 0); This->hmmio = NULL; } - LocalFree((HLOCAL)This); + HeapFree(GetProcessHeap(), 0, This); } return ref; } @@ -423,7 +420,7 @@ static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile *iface,PAVISTREAM *avis, /* now it seems to be save to add the stream */ assert(This->ppStreams[n] == NULL); - This->ppStreams[n] = (IAVIStreamImpl*)LocalAlloc(LPTR, + This->ppStreams[n] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIStreamImpl)); if (This->ppStreams[n] == NULL) return AVIERR_MEMORY; @@ -540,7 +537,7 @@ static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile *iface, DWORD fccType, if (nStream < This->fInfo.dwStreams && This->ppStreams[nStream] != NULL) { /* ... so delete it now */ - LocalFree((HLOCAL)This->ppStreams[nStream]); + HeapFree(GetProcessHeap(), 0, This->ppStreams[nStream]); if (This->fInfo.dwStreams - nStream > 0) memcpy(This->ppStreams + nStream, This->ppStreams + nStream + 1, @@ -631,7 +628,7 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, This->paf->uMode = dwMode; len = lstrlenW(pszFileName) + 1; - This->paf->szFileName = (LPWSTR)LocalAlloc(LPTR, len * sizeof(WCHAR)); + This->paf->szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if (This->paf->szFileName == NULL) return AVIERR_MEMORY; lstrcpyW(This->paf->szFileName, pszFileName); @@ -645,7 +642,7 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, len = WideCharToMultiByte(CP_ACP, 0, This->paf->szFileName, -1, NULL, 0, NULL, NULL); - szFileName = LocalAlloc(LPTR, len * sizeof(CHAR)); + szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR)); if (szFileName == NULL) return AVIERR_MEMORY; @@ -653,7 +650,7 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, len, NULL, NULL); This->paf->hmmio = mmioOpenA(szFileName, NULL, MMIO_ALLOCBUF | dwMode); - LocalFree((HLOCAL)szFileName); + HeapFree(GetProcessHeap(), 0, szFileName); if (This->paf->hmmio == NULL) return AVIERR_FILEOPEN; } @@ -705,7 +702,7 @@ static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile *iface, if (This->paf->szFileName != NULL) { int len = lstrlenW(This->paf->szFileName) + 1; - *ppszFileName = (LPOLESTR)GlobalAllocPtr(GHND, len * sizeof(WCHAR)); + *ppszFileName = CoTaskMemAlloc(len * sizeof(WCHAR)); if (*ppszFileName == NULL) return AVIERR_MEMORY; @@ -957,7 +954,7 @@ static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos, if (This->paf->dwMoviChunkPos != 0) return AVIERR_ERROR; /* user has used API in wrong sequnece! */ - This->lpFormat = GlobalAllocPtr(GMEM_MOVEABLE, formatsize); + This->lpFormat = HeapAlloc(GetProcessHeap(), 0, formatsize); if (This->lpFormat == NULL) return AVIERR_MEMORY; This->cbFormat = formatsize; @@ -1008,7 +1005,7 @@ static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos, /* simply say all colors have changed */ ck.ckid = MAKEAVICKID(cktypePALchange, This->nStream); ck.cksize = 2 * sizeof(WORD) + lpbiOld->biClrUsed * sizeof(PALETTEENTRY); - lppc = (AVIPALCHANGE*)GlobalAllocPtr(GMEM_MOVEABLE, ck.cksize); + lppc = HeapAlloc(GetProcessHeap(), 0, ck.cksize); if (lppc == NULL) return AVIERR_MEMORY; @@ -1032,7 +1029,7 @@ static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos, return AVIERR_FILEWRITE; This->paf->dwNextFramePos += ck.cksize + 2 * sizeof(DWORD); - GlobalFreePtr(lppc); + HeapFree(GetProcessHeap(), 0, lppc); return AVIFILE_AddFrame(This, cktypePALchange, n, ck.dwDataOffset, 0); } @@ -1342,7 +1339,7 @@ static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream *iface, DWORD fcc, return AVIERR_UNSUPPORTED; } - This->lpHandlerData = GlobalAllocPtr(GMEM_MOVEABLE, size); + This->lpHandlerData = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpHandlerData == NULL) return AVIERR_MEMORY; This->cbHandlerData = size; @@ -1391,11 +1388,11 @@ static HRESULT AVIFILE_AddFrame(IAVIStreamImpl *This, DWORD ckid, DWORD size, DW This->nIdxFmtChanges += 16; if (This->idxFmtChanges == NULL) This->idxFmtChanges = - GlobalAllocPtr(GHND, This->nIdxFmtChanges * sizeof(AVIINDEXENTRY)); + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->nIdxFmtChanges * sizeof(AVIINDEXENTRY)); else This->idxFmtChanges = - GlobalReAllocPtr(This->idxFmtChanges, - This->nIdxFmtChanges * sizeof(AVIINDEXENTRY), GHND); + HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->idxFmtChanges, + This->nIdxFmtChanges * sizeof(AVIINDEXENTRY)); if (This->idxFmtChanges == NULL) return AVIERR_MEMORY; @@ -1427,12 +1424,10 @@ static HRESULT AVIFILE_AddFrame(IAVIStreamImpl *This, DWORD ckid, DWORD size, DW if (This->idxFrames == NULL || This->lLastFrame + 1 >= This->nIdxFrames) { This->nIdxFrames += 512; if (This->idxFrames == NULL) - This->idxFrames = - GlobalAllocPtr(GHND, This->nIdxFrames * sizeof(AVIINDEXENTRY)); + This->idxFrames = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->nIdxFrames * sizeof(AVIINDEXENTRY)); else - This->idxFrames = - GlobalReAllocPtr(This->idxFrames, - This->nIdxFrames * sizeof(AVIINDEXENTRY), GHND); + This->idxFrames = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->idxFrames, + This->nIdxFrames * sizeof(AVIINDEXENTRY)); if (This->idxFrames == NULL) return AVIERR_MEMORY; } @@ -1457,7 +1452,7 @@ static HRESULT AVIFILE_AddRecord(IAVIFileImpl *This) if (This->idxRecords == NULL || This->cbIdxRecords == 0) { This->cbIdxRecords += 1024 * sizeof(AVIINDEXENTRY); - This->idxRecords = GlobalAllocPtr(GHND, This->cbIdxRecords); + This->idxRecords = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->cbIdxRecords); if (This->idxRecords == NULL) return AVIERR_MEMORY; } @@ -1532,14 +1527,14 @@ static void AVIFILE_ConstructAVIStream(IAVIFileImpl *paf, DWORD nr, LPAVISTRE if (asi->dwLength > 0) { /* pre-allocate mem for frame-index structure */ pstream->idxFrames = - (AVIINDEXENTRY*)GlobalAllocPtr(GHND, asi->dwLength * sizeof(AVIINDEXENTRY)); + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, asi->dwLength * sizeof(AVIINDEXENTRY)); if (pstream->idxFrames != NULL) pstream->nIdxFrames = asi->dwLength; } if (asi->dwFormatChangeCount > 0) { /* pre-allocate mem for formatchange-index structure */ pstream->idxFmtChanges = - (AVIINDEXENTRY*)GlobalAllocPtr(GHND, asi->dwFormatChangeCount * sizeof(AVIINDEXENTRY)); + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, asi->dwFormatChangeCount * sizeof(AVIINDEXENTRY)); if (pstream->idxFmtChanges != NULL) pstream->nIdxFmtChanges = asi->dwFormatChangeCount; } @@ -1565,31 +1560,29 @@ static void AVIFILE_DestructAVIStream(IAVIStreamImpl *This) This->lLastFrame = -1; This->paf = NULL; if (This->idxFrames != NULL) { - GlobalFreePtr(This->idxFrames); + HeapFree(GetProcessHeap(), 0, This->idxFrames); This->idxFrames = NULL; This->nIdxFrames = 0; } - if (This->idxFmtChanges != NULL) { - GlobalFreePtr(This->idxFmtChanges); - This->idxFmtChanges = NULL; - } + HeapFree(GetProcessHeap(), 0, This->idxFmtChanges); + This->idxFmtChanges = NULL; if (This->lpBuffer != NULL) { - GlobalFreePtr(This->lpBuffer); + HeapFree(GetProcessHeap(), 0, This->lpBuffer); This->lpBuffer = NULL; This->cbBuffer = 0; } if (This->lpHandlerData != NULL) { - GlobalFreePtr(This->lpHandlerData); + HeapFree(GetProcessHeap(), 0, This->lpHandlerData); This->lpHandlerData = NULL; This->cbHandlerData = 0; } if (This->extra.lp != NULL) { - GlobalFreePtr(This->extra.lp); + HeapFree(GetProcessHeap(), 0, This->extra.lp); This->extra.lp = NULL; This->extra.cb = 0; } if (This->lpFormat != NULL) { - GlobalFreePtr(This->lpFormat); + HeapFree(GetProcessHeap(), 0, This->lpFormat); This->lpFormat = NULL; This->cbFormat = 0; } @@ -1679,7 +1672,7 @@ static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This) if (ckLIST2.ckid == FOURCC_LIST && ckLIST2.fccType == listtypeSTREAMHEADER) { pStream = This->ppStreams[nStream] = - (IAVIStreamImpl*)LocalAlloc(LPTR, sizeof(IAVIStreamImpl)); + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIStreamImpl)); if (pStream == NULL) return AVIERR_MEMORY; AVIFILE_ConstructAVIStream(This, nStream, NULL); @@ -1690,8 +1683,7 @@ static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This) case ckidSTREAMHANDLERDATA: if (pStream->lpHandlerData != NULL) return AVIERR_BADFORMAT; - pStream->lpHandlerData = GlobalAllocPtr(GMEM_DDESHARE|GMEM_MOVEABLE, - ck.cksize); + pStream->lpHandlerData = HeapAlloc(GetProcessHeap(), 0, ck.cksize); if (pStream->lpHandlerData == NULL) return AVIERR_MEMORY; pStream->cbHandlerData = ck.cksize; @@ -1705,8 +1697,7 @@ static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This) if (ck.cksize == 0) break; - pStream->lpFormat = GlobalAllocPtr(GMEM_DDESHARE|GMEM_MOVEABLE, - ck.cksize); + pStream->lpFormat = HeapAlloc(GetProcessHeap(), 0, ck.cksize); if (pStream->lpFormat == NULL) return AVIERR_MEMORY; pStream->cbFormat = ck.cksize; @@ -1800,20 +1791,20 @@ static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This) break; case ckidSTREAMNAME: { /* streamname will be saved as ASCII string */ - LPSTR str = (LPSTR)LocalAlloc(LMEM_FIXED, ck.cksize); + LPSTR str = HeapAlloc(GetProcessHeap(), 0, ck.cksize); if (str == NULL) return AVIERR_MEMORY; if (mmioRead(This->hmmio, (HPSTR)str, ck.cksize) != ck.cksize) { - LocalFree((HLOCAL)str); + HeapFree(GetProcessHeap(), 0, str); return AVIERR_FILEREAD; } MultiByteToWideChar(CP_ACP, 0, str, -1, pStream->sInfo.szName, sizeof(pStream->sInfo.szName)/sizeof(pStream->sInfo.szName[0])); - LocalFree((HLOCAL)str); + HeapFree(GetProcessHeap(), 0, str); } break; case ckidAVIPADDING: @@ -1919,8 +1910,7 @@ static HRESULT AVIFILE_LoadIndex(IAVIFileImpl *This, DWORD size, DWORD offset) HRESULT hr = AVIERR_OK; BOOL bAbsolute = TRUE; - lp = (AVIINDEXENTRY*)GlobalAllocPtr(GMEM_MOVEABLE, - IDX_PER_BLOCK * sizeof(AVIINDEXENTRY)); + lp = HeapAlloc(GetProcessHeap(), 0, IDX_PER_BLOCK * sizeof(AVIINDEXENTRY)); if (lp == NULL) return AVIERR_MEMORY; @@ -1931,7 +1921,7 @@ static HRESULT AVIFILE_LoadIndex(IAVIFileImpl *This, DWORD size, DWORD offset) pStream->lLastFrame = -1; if (pStream->idxFrames != NULL) { - GlobalFreePtr(pStream->idxFrames); + HeapFree(GetProcessHeap(), 0, pStream->idxFrames); pStream->idxFrames = NULL; pStream->nIdxFrames = 0; } @@ -1947,7 +1937,7 @@ static HRESULT AVIFILE_LoadIndex(IAVIFileImpl *This, DWORD size, DWORD offset) pStream->nIdxFrames = pStream->sInfo.dwLength; pStream->idxFrames = - (AVIINDEXENTRY*)GlobalAllocPtr(GHND, pStream->nIdxFrames * sizeof(AVIINDEXENTRY)); + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pStream->nIdxFrames * sizeof(AVIINDEXENTRY)); if (pStream->idxFrames == NULL && pStream->nIdxFrames > 0) { pStream->nIdxFrames = 0; return AVIERR_MEMORY; @@ -1971,8 +1961,7 @@ static HRESULT AVIFILE_LoadIndex(IAVIFileImpl *This, DWORD size, DWORD offset) pos, &bAbsolute); } - if (lp != NULL) - GlobalFreePtr(lp); + HeapFree(GetProcessHeap(), 0, lp); /* checking ... */ for (n = 0; n < This->fInfo.dwStreams; n++) { @@ -2041,10 +2030,9 @@ static HRESULT AVIFILE_ReadBlock(IAVIStreamImpl *This, DWORD pos, DWORD maxSize = max(size, This->sInfo.dwSuggestedBufferSize); if (This->lpBuffer == NULL) - This->lpBuffer = (LPDWORD)GlobalAllocPtr(GMEM_MOVEABLE, maxSize); + This->lpBuffer = HeapAlloc(GetProcessHeap(), 0, maxSize); else - This->lpBuffer = - (LPDWORD)GlobalReAllocPtr(This->lpBuffer, maxSize, GMEM_MOVEABLE); + This->lpBuffer = HeapReAlloc(GetProcessHeap(), 0, This->lpBuffer, maxSize); if (This->lpBuffer == NULL) return AVIERR_MEMORY; This->cbBuffer = max(size, This->sInfo.dwSuggestedBufferSize); @@ -2255,18 +2243,18 @@ static HRESULT AVIFILE_SaveFile(IAVIFileImpl *This) return AVIERR_FILEWRITE; /* the streamname must be saved in ASCII not Unicode */ - str = (LPSTR)LocalAlloc(LPTR, ck.cksize); + str = HeapAlloc(GetProcessHeap(), 0, ck.cksize); if (str == NULL) return AVIERR_MEMORY; WideCharToMultiByte(CP_ACP, 0, pStream->sInfo.szName, -1, str, ck.cksize, NULL, NULL); if (mmioWrite(This->hmmio, (HPSTR)str, ck.cksize) != ck.cksize) { - LocalFree((HLOCAL)str); + HeapFree(GetProcessHeap(), 0, str); return AVIERR_FILEWRITE; } - LocalFree((HLOCAL)str); + HeapFree(GetProcessHeap(), 0, str); if (mmioAscend(This->hmmio, &ck, 0) != S_OK) return AVIERR_FILEWRITE; } diff --git a/reactos/dll/win32/avifil32/avifile_Cs.rc b/reactos/dll/win32/avifil32/avifile_Cs.rc index f60613fd6ae..25d4ce56df9 100644 --- a/reactos/dll/win32/avifil32/avifile_Cs.rc +++ b/reactos/dll/win32/avifil32/avifile_Cs.rc @@ -1,4 +1,5 @@ -/* +/* Hey, Emacs, open this file with -*- coding: cp1250 -*- + * * Copyright 2002 Michael Günnewig * * Czech resources for avifile @@ -16,10 +17,12 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_CZECH, SUBLANG_NEUTRAL +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +/* Czech strings in CP1250 */ IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU @@ -30,21 +33,21 @@ BEGIN COMBOBOX IDC_STREAM,2,18,134,61,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "V&olby...",IDC_OPTIONS,145,17,45,14 - AUTOCHECKBOX "Proloľ&it kaľdých",IDC_INTERLEAVE,3,42,60,11,WS_TABSTOP + AUTOCHECKBOX "Prolož&it každých",IDC_INTERLEAVE,3,42,60,11,WS_TABSTOP EDITTEXT IDC_INTERLEAVEEVERY,66,41,32,12,ES_AUTOHSCROLL LTEXT "rámců",-1,104,43,36,9 LTEXT "Současný formát:",-1,3,56,53,9 LTEXT "Zbývající místo",IDC_FORMATTEXT,55,56,90,26 - DEFPUSHBUTTON "Budiľ",IDOK,145,42,45,14 - PUSHBUTTON "Zruąit",IDCANCEL,145,61,45,14 + DEFPUSHBUTTON "Budiž",IDOK,145,42,45,14 + PUSHBUTTON "Zrušit",IDCANCEL,145,61,45,14 END STRINGTABLE DISCARDABLE { IDS_WAVESTREAMFORMAT "Waveform: %s" IDS_WAVEFILETYPE "Waveform" - IDS_ALLMULTIMEDIA "Vąechny soubory multimédií" - IDS_ALLFILES "Vąechny soubory (*.*)@*.*" + IDS_ALLMULTIMEDIA "Všechny soubory multimédií" + IDS_ALLFILES "Všechny soubory (*.*)@*.*" IDS_VIDEO "video" IDS_AUDIO "audio" IDS_AVISTREAMFORMAT "%s %s #%d" diff --git a/reactos/dll/win32/avifil32/avifile_De.rc b/reactos/dll/win32/avifil32/avifile_De.rc index f6550227c9d..83b81051a74 100644 --- a/reactos/dll/win32/avifil32/avifile_De.rc +++ b/reactos/dll/win32/avifil32/avifile_De.rc @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_GERMAN, SUBLANG_GERMAN diff --git a/reactos/dll/win32/avifil32/avifile_En.rc b/reactos/dll/win32/avifil32/avifile_En.rc index b5d5b3e8d58..2fc5b451cb6 100644 --- a/reactos/dll/win32/avifil32/avifile_En.rc +++ b/reactos/dll/win32/avifil32/avifile_En.rc @@ -13,10 +13,10 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU diff --git a/reactos/dll/win32/avifil32/avifile_Es.rc b/reactos/dll/win32/avifil32/avifile_Es.rc index c2b51c3962b..ee3e73a4c81 100644 --- a/reactos/dll/win32/avifil32/avifile_Es.rc +++ b/reactos/dll/win32/avifil32/avifile_Es.rc @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL diff --git a/reactos/dll/win32/avifil32/avifile_Fr.rc b/reactos/dll/win32/avifil32/avifile_Fr.rc index b9ee5d91ee7..1570fe19bd1 100644 --- a/reactos/dll/win32/avifil32/avifile_Fr.rc +++ b/reactos/dll/win32/avifil32/avifile_Fr.rc @@ -17,7 +17,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL diff --git a/reactos/dll/win32/avifil32/avifile_Hu.rc b/reactos/dll/win32/avifil32/avifile_Hu.rc new file mode 100644 index 00000000000..8eb98250219 --- /dev/null +++ b/reactos/dll/win32/avifil32/avifile_Hu.rc @@ -0,0 +1,50 @@ +/* + * Copyright 2006 Andras Kovacs + * + * 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 + */ + +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT + +IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Tömörítési beállítások" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Válassuon folyamot:",-1,2,5,114,10 + COMBOBOX IDC_STREAM,2,18,134,61,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "&Opciók...",IDC_OPTIONS,145,17,45,14 + AUTOCHECKBOX "&Beékel minden",IDC_INTERLEAVE,3,42,60,11,WS_TABSTOP + EDITTEXT IDC_INTERLEAVEEVERY,66,41,32,12,ES_AUTOHSCROLL + LTEXT "képkockát",-1,104,43,36,9 + LTEXT "Jelenlegi formátum:",-1,3,56,53,9 + LTEXT "Ez hely kölcsönzésre",IDC_FORMATTEXT,55,56,90,26 + DEFPUSHBUTTON "OK",IDOK,145,42,45,14 + PUSHBUTTON "Mégse",IDCANCEL,145,61,45,14 +END + +STRINGTABLE DISCARDABLE +{ + IDS_WAVESTREAMFORMAT "Hullámforma: %s" + IDS_WAVEFILETYPE "Hullámforma" + IDS_ALLMULTIMEDIA "Minden multimédia fájl" + IDS_ALLFILES "Minden fájl (*.*)@*.*" + IDS_VIDEO "video" + IDS_AUDIO "hang" + IDS_AVISTREAMFORMAT "%s %s #%d" + IDS_AVIFILETYPE "Wine AVI-alapértelmezett-fájlkezelő" + IDS_UNCOMPRESSED "tömörítetlen" +} diff --git a/reactos/dll/win32/avifil32/avifile_It.rc b/reactos/dll/win32/avifil32/avifile_It.rc index 4c65f2f42ce..8e67e8c716f 100644 --- a/reactos/dll/win32/avifil32/avifile_It.rc +++ b/reactos/dll/win32/avifil32/avifile_It.rc @@ -14,10 +14,10 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU diff --git a/reactos/dll/win32/avifil32/avifile_Ja.rc b/reactos/dll/win32/avifil32/avifile_Ja.rc index 3bb780ef44c..38fc247611b 100644 --- a/reactos/dll/win32/avifil32/avifile_Ja.rc +++ b/reactos/dll/win32/avifil32/avifile_Ja.rc @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT diff --git a/reactos/dll/win32/avifil32/avifile_Ko.rc b/reactos/dll/win32/avifil32/avifile_Ko.rc index 496763857ca..c5a7a326640 100644 --- a/reactos/dll/win32/avifil32/avifile_Ko.rc +++ b/reactos/dll/win32/avifil32/avifile_Ko.rc @@ -14,7 +14,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT diff --git a/reactos/dll/win32/avifil32/avifile_Nl.rc b/reactos/dll/win32/avifil32/avifile_Nl.rc index 0c33d102904..e002c6ab229 100644 --- a/reactos/dll/win32/avifil32/avifile_Nl.rc +++ b/reactos/dll/win32/avifil32/avifile_Nl.rc @@ -15,10 +15,10 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL +LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU diff --git a/reactos/dll/win32/avifil32/avifile_No.rc b/reactos/dll/win32/avifil32/avifile_No.rc index d75e042155f..8ead416b76e 100644 --- a/reactos/dll/win32/avifil32/avifile_No.rc +++ b/reactos/dll/win32/avifil32/avifile_No.rc @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL diff --git a/reactos/dll/win32/avifil32/avifile_Pl.rc b/reactos/dll/win32/avifil32/avifile_Pl.rc index 0fea2d33ef2..dbd35001d4f 100644 --- a/reactos/dll/win32/avifil32/avifile_Pl.rc +++ b/reactos/dll/win32/avifil32/avifile_Pl.rc @@ -14,10 +14,10 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_POLISH, SUBLANG_NEUTRAL +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU diff --git a/reactos/dll/win32/avifil32/avifile_Pt.rc b/reactos/dll/win32/avifil32/avifile_Pt.rc index a87c11b20f4..6eac551dd45 100644 --- a/reactos/dll/win32/avifil32/avifile_Pt.rc +++ b/reactos/dll/win32/avifil32/avifile_Pt.rc @@ -13,10 +13,10 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL +LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU diff --git a/reactos/dll/win32/avifil32/avifile_Ru.rc b/reactos/dll/win32/avifil32/avifile_Ru.rc index 20669f14f3c..88f313c5ec0 100644 --- a/reactos/dll/win32/avifil32/avifile_Ru.rc +++ b/reactos/dll/win32/avifil32/avifile_Ru.rc @@ -15,10 +15,10 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_RUSSIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU diff --git a/reactos/dll/win32/avifil32/avifile_Si.rc b/reactos/dll/win32/avifil32/avifile_Si.rc index d80c4ed407d..1b5d7dc70aa 100644 --- a/reactos/dll/win32/avifil32/avifile_Si.rc +++ b/reactos/dll/win32/avifil32/avifile_Si.rc @@ -13,10 +13,10 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_SLOVENIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU diff --git a/reactos/dll/win32/avifil32/avifile_Tr.rc b/reactos/dll/win32/avifil32/avifile_Tr.rc new file mode 100644 index 00000000000..b9caa67e463 --- /dev/null +++ b/reactos/dll/win32/avifil32/avifile_Tr.rc @@ -0,0 +1,50 @@ +/* + * Copyright 2006 Fatih Aţýcý + * + * 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 + */ + +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +IDD_SAVEOPTIONS DIALOG FIXED IMPURE 43, 37, 196, 82 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Sýkýţtýrma seçenekleri" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Bir akýţ se&çin:",-1,2,5,114,10 + COMBOBOX IDC_STREAM,2,18,134,61,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "&Seçenekler...",IDC_OPTIONS,145,17,45,14 + AUTOCHECKBOX "&Interleave every",IDC_INTERLEAVE,3,42,60,11,WS_TABSTOP + EDITTEXT IDC_INTERLEAVEEVERY,66,41,32,12,ES_AUTOHSCROLL + LTEXT "frames",-1,104,43,36,9 + LTEXT "Geçerli biçim:",-1,3,56,53,9 + LTEXT "This space for rent",IDC_FORMATTEXT,55,56,90,26 + DEFPUSHBUTTON "Tamam",IDOK,145,42,45,14 + PUSHBUTTON "Ýptal",IDCANCEL,145,61,45,14 +END + +STRINGTABLE DISCARDABLE +{ + IDS_WAVESTREAMFORMAT "Waveform: %s" + IDS_WAVEFILETYPE "Waveform" + IDS_ALLMULTIMEDIA "Tüm çokluortam dosyalarý" + IDS_ALLFILES "Tüm dosyalar (*.*)@*.*" + IDS_VIDEO "vidyo" + IDS_AUDIO "ses" + IDS_AVISTREAMFORMAT "%s %s #%d" + IDS_AVIFILETYPE "Wine AVI-default-filehandler" + IDS_UNCOMPRESSED "sýkýţtýrýlmamýţ" +} diff --git a/reactos/dll/win32/avifil32/avifile_private.h b/reactos/dll/win32/avifil32/avifile_private.h index d29c00c07af..5223970db56 100644 --- a/reactos/dll/win32/avifil32/avifile_private.h +++ b/reactos/dll/win32/avifil32/avifile_private.h @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __AVIFILE_PRIVATE_H diff --git a/reactos/dll/win32/avifil32/editstream.c b/reactos/dll/win32/avifil32/editstream.c index 40a19e6de5c..899014f6863 100644 --- a/reactos/dll/win32/avifil32/editstream.c +++ b/reactos/dll/win32/avifil32/editstream.c @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COM_NO_WINDOWS_H @@ -22,13 +22,11 @@ #include "windef.h" #include "winbase.h" -#include "wingdi.h" #include "winuser.h" +#include "wingdi.h" #include "winnls.h" #include "winerror.h" -#include "windowsx.h" #include "mmsystem.h" -#include "mmreg.h" #include "vfw.h" #include "avifile_private.h" @@ -189,7 +187,7 @@ PAVIEDITSTREAM AVIFILE_CreateEditStream(PAVISTREAM pstream) { IAVIEditStreamImpl *pedit = NULL; - pedit = (IAVIEditStreamImpl*)LocalAlloc(LPTR,sizeof(IAVIEditStreamImpl)); + pedit = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIEditStreamImpl)); if (pedit == NULL) return NULL; @@ -331,20 +329,19 @@ static BOOL AVIFILE_FormatsEqual(PAVISTREAM avi1, PAVISTREAM avi2) return FALSE; /* sizes match, now get formats and compare them */ - fmt1 = GlobalAllocPtr(GHND, size1); + fmt1 = HeapAlloc(GetProcessHeap(), 0, size1); if (fmt1 == NULL) return FALSE; if (SUCCEEDED(AVIStreamReadFormat(avi1, start1, fmt1, &size1))) { - fmt2 = GlobalAllocPtr(GHND, size1); + fmt2 = HeapAlloc(GetProcessHeap(), 0, size1); if (fmt2 != NULL) { if (SUCCEEDED(AVIStreamReadFormat(avi2, start2, fmt2, &size1))) status = (memcmp(fmt1, fmt2, size1) == 0); } } - if (fmt2 != NULL) - GlobalFreePtr(fmt2); - GlobalFreePtr(fmt1); + HeapFree(GetProcessHeap(), 0, fmt2); + HeapFree(GetProcessHeap(), 0, fmt1); return status; } @@ -405,10 +402,10 @@ static ULONG WINAPI IAVIEditStream_fnRelease(IAVIEditStream*iface) if (This->pStreams[i].pStream != NULL) IAVIStream_Release(This->pStreams[i].pStream); } - GlobalFreePtr(This->pStreams); + HeapFree(GetProcessHeap(), 0, This->pStreams); } - LocalFree((HLOCAL)This); + HeapFree(GetProcessHeap(), 0, This); return 0; } return ref; @@ -471,8 +468,8 @@ static HRESULT WINAPI IAVIEditStream_fnCut(IAVIEditStream*iface,LONG*plStart, } else { /* splitting */ if (This->nStreams + 1 >= This->nTableSize) { - This->pStreams = - GlobalReAllocPtr(This->pStreams, (This->nTableSize + 32) * sizeof(EditStreamTable), GMEM_SHARE|GHND); + This->pStreams = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pStreams, + (This->nTableSize + 32) * sizeof(EditStreamTable)); if (This->pStreams == NULL) return AVIERR_MEMORY; This->nTableSize += 32; @@ -663,8 +660,7 @@ static HRESULT WINAPI IAVIEditStream_fnPaste(IAVIEditStream*iface,LONG*plStart, if (This->nStreams + nStreams + 1 > This->nTableSize) { n = This->nStreams + nStreams + 33; - This->pStreams = - GlobalReAllocPtr(This->pStreams, n * sizeof(EditStreamTable), GMEM_SHARE|GHND); + This->pStreams = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pStreams, n * sizeof(EditStreamTable)); if (This->pStreams == NULL) return AVIERR_MEMORY; This->nTableSize = n; @@ -753,7 +749,8 @@ static HRESULT WINAPI IAVIEditStream_fnClone(IAVIEditStream*iface, if (pEdit == NULL) return AVIERR_MEMORY; if (This->nStreams > pEdit->nTableSize) { - pEdit->pStreams = GlobalReAllocPtr(pEdit->pStreams, This->nStreams * sizeof(EditStreamTable),GMEM_SHARE|GHND); + pEdit->pStreams = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pEdit->pStreams, + This->nStreams * sizeof(EditStreamTable)); if (pEdit->pStreams == NULL) return AVIERR_MEMORY; pEdit->nTableSize = This->nStreams; @@ -841,8 +838,7 @@ static HRESULT WINAPI IEditAVIStream_fnCreate(IAVIStream*iface, return AVIERR_ERROR; if (This->pStreams == NULL) { - This->pStreams = - GlobalAllocPtr(GMEM_SHARE|GHND, 256 * sizeof(EditStreamTable)); + This->pStreams = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256 * sizeof(EditStreamTable)); if (This->pStreams == NULL) return AVIERR_MEMORY; This->nTableSize = 256; diff --git a/reactos/dll/win32/avifil32/extrachunk.c b/reactos/dll/win32/avifil32/extrachunk.c index 5343db2bd6e..573dda3116d 100644 --- a/reactos/dll/win32/avifil32/extrachunk.c +++ b/reactos/dll/win32/avifil32/extrachunk.c @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COM_NO_WINDOWS_H @@ -23,8 +23,6 @@ #include "winbase.h" #include "wingdi.h" #include "winuser.h" -#include "windowsx.h" -#include "mmreg.h" #include "vfw.h" #include "wine/debug.h" @@ -82,9 +80,9 @@ HRESULT WriteExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lpData, assert(size > 0); if (extra->lp) - lp = (LPDWORD)GlobalReAllocPtr(extra->lp, extra->cb + size + 2 * sizeof(DWORD), GHND); + lp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, extra->lp, extra->cb + size + 2 * sizeof(DWORD)); else - lp = (LPDWORD)GlobalAllocPtr(GHND, size + 2 * sizeof(DWORD)); + lp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 2 * sizeof(DWORD)); if (lp == NULL) return AVIERR_MEMORY; @@ -117,10 +115,10 @@ HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck) cb = lpck->cksize + 2 * sizeof(DWORD); cb += (cb & 1); - if (extra->lp != NULL) { - lp = (LPDWORD)GlobalReAllocPtr(extra->lp, extra->cb + cb, GHND); - } else - lp = (LPDWORD)GlobalAllocPtr(GHND, cb); + if (extra->lp != NULL) + lp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, extra->lp, extra->cb + cb); + else + lp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb); if (lp == NULL) return AVIERR_MEMORY; diff --git a/reactos/dll/win32/avifil32/extrachunk.h b/reactos/dll/win32/avifil32/extrachunk.h index 35f4bc01239..b30e9d82c31 100644 --- a/reactos/dll/win32/avifil32/extrachunk.h +++ b/reactos/dll/win32/avifil32/extrachunk.h @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_EXTRACHUNK_H diff --git a/reactos/dll/win32/avifil32/factory.c b/reactos/dll/win32/avifil32/factory.c index e6c2886a1fc..817c79af003 100644 --- a/reactos/dll/win32/avifil32/factory.c +++ b/reactos/dll/win32/avifil32/factory.c @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -30,7 +30,6 @@ #include "winerror.h" #include "ole2.h" -#include "mmreg.h" #include "vfw.h" #include "wine/debug.h" @@ -76,7 +75,7 @@ static HRESULT AVIFILE_CreateClassFactory(const CLSID *pclsid, const IID *riid, *ppv = NULL; - pClassFactory = (IClassFactoryImpl*)LocalAlloc(LPTR, sizeof(*pClassFactory)); + pClassFactory = HeapAlloc(GetProcessHeap(), 0, sizeof(*pClassFactory)); if (pClassFactory == NULL) return E_OUTOFMEMORY; @@ -86,7 +85,7 @@ static HRESULT AVIFILE_CreateClassFactory(const CLSID *pclsid, const IID *riid, hr = IClassFactory_QueryInterface((IClassFactory*)pClassFactory, riid, ppv); if (FAILED(hr)) { - LocalFree((HLOCAL)pClassFactory); + HeapFree(GetProcessHeap(), 0, pClassFactory); *ppv = NULL; } @@ -125,6 +124,8 @@ static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface) if ((--(This->dwRef)) > 0) return This->dwRef; + HeapFree(GetProcessHeap(), 0, This); + return 0; } diff --git a/reactos/dll/win32/avifil32/getframe.c b/reactos/dll/win32/avifil32/getframe.c index 6f9a685e0df..172a0b08c2c 100644 --- a/reactos/dll/win32/avifil32/getframe.c +++ b/reactos/dll/win32/avifil32/getframe.c @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COM_NO_WINDOWS_H @@ -23,12 +23,9 @@ #include "windef.h" #include "winbase.h" #include "winnls.h" -#include "windowsx.h" #include "wingdi.h" #include "winuser.h" - #include "vfw.h" -#include "mmreg.h" #include "avifile_private.h" @@ -100,14 +97,12 @@ typedef struct _IGetFrameImpl { static void AVIFILE_CloseCompressor(IGetFrameImpl *This) { - if (This->lpOutFormat != NULL && This->lpInFormat != This->lpOutFormat) { - GlobalFreePtr(This->lpOutFormat); + if (This->lpInFormat != This->lpOutFormat) { + HeapFree(GetProcessHeap(), 0, This->lpOutFormat); This->lpOutFormat = NULL; } - if (This->lpInFormat != NULL) { - GlobalFreePtr(This->lpInFormat); - This->lpInFormat = NULL; - } + HeapFree(GetProcessHeap(), 0, This->lpInFormat); + This->lpInFormat = NULL; if (This->hic != NULL) { if (This->bResize) ICDecompressExEnd(This->hic); @@ -126,7 +121,7 @@ PGETFRAME AVIFILE_CreateGetFrame(PAVISTREAM pStream) if (pStream == NULL) return NULL; - pg = (IGetFrameImpl*)LocalAlloc(LPTR, sizeof(IGetFrameImpl)); + pg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGetFrameImpl)); if (pg != NULL) { pg->lpVtbl = &igetframeVtbl; pg->ref = 1; @@ -178,7 +173,7 @@ static ULONG WINAPI IGetFrame_fnRelease(IGetFrame *iface) This->pStream = NULL; } - LocalFree((HLOCAL)iface); + HeapFree(GetProcessHeap(), 0, iface); return 0; } @@ -268,7 +263,7 @@ static LPVOID WINAPI IGetFrame_fnGetFrame(IGetFrame *iface, LONG lPos) if (This->cbInBuffer >= readBytes) break; This->cbInBuffer = This->cbInFormat + readBytes; - This->lpInFormat = GlobalReAllocPtr(This->lpInFormat, This->cbInBuffer, 0); + This->lpInFormat = HeapReAlloc(GetProcessHeap(), 0, This->lpInFormat, This->cbInBuffer); if (This->lpInFormat == NULL) return NULL; /* out of memory */ This->lpInBuffer = (BYTE*)This->lpInFormat + This->cbInFormat; @@ -369,8 +364,7 @@ static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame *iface, IAVIStream_ReadFormat(This->pStream, sInfo.dwStart, NULL, &This->cbInFormat); - This->lpInFormat = - (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, This->cbInFormat + This->cbInBuffer); + This->lpInFormat = HeapAlloc(GetProcessHeap(), 0, This->cbInFormat + This->cbInBuffer); if (This->lpInFormat == NULL) { AVIFILE_CloseCompressor(This); return AVIERR_MEMORY; @@ -410,8 +404,7 @@ static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame *iface, /* need memory for output format? */ if (This->lpOutFormat == NULL) { This->lpOutFormat = - (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, sizeof(BITMAPINFOHEADER) - + 256 * sizeof(RGBQUAD)); + HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); if (This->lpOutFormat == NULL) { AVIFILE_CloseCompressor(This); return AVIERR_MEMORY; @@ -480,8 +473,7 @@ static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame *iface, register DWORD size = This->lpOutFormat->biClrUsed * sizeof(RGBQUAD); size += This->lpOutFormat->biSize + This->lpOutFormat->biSizeImage; - This->lpOutFormat = - (LPBITMAPINFOHEADER)GlobalReAllocPtr(This->lpOutFormat, size, GMEM_MOVEABLE); + This->lpOutFormat = HeapReAlloc(GetProcessHeap(), 0, This->lpOutFormat, size); if (This->lpOutFormat == NULL) { AVIFILE_CloseCompressor(This); return AVIERR_MEMORY; diff --git a/reactos/dll/win32/avifil32/icmstream.c b/reactos/dll/win32/avifil32/icmstream.c index 13ff004fc23..af71fc43d08 100644 --- a/reactos/dll/win32/avifil32/icmstream.c +++ b/reactos/dll/win32/avifil32/icmstream.c @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COM_NO_WINDOWS_H @@ -26,10 +26,8 @@ #include "winuser.h" #include "winnls.h" #include "winerror.h" -#include "windowsx.h" #include "mmsystem.h" #include "vfw.h" -#include "mmreg.h" #include "msacm.h" #include "avifile_private.h" @@ -129,7 +127,7 @@ HRESULT AVIFILE_CreateICMStream(REFIID riid, LPVOID *ppv) *ppv = NULL; - pstream = (IAVIStreamImpl*)LocalAlloc(LPTR, sizeof(IAVIStreamImpl)); + pstream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIStreamImpl)); if (pstream == NULL) return AVIERR_MEMORY; @@ -138,7 +136,7 @@ HRESULT AVIFILE_CreateICMStream(REFIID riid, LPVOID *ppv) hr = IAVIStream_QueryInterface((IAVIStream*)pstream, riid, ppv); if (FAILED(hr)) - LocalFree((HLOCAL)pstream); + HeapFree(GetProcessHeap(), 0, pstream); return hr; } @@ -195,7 +193,7 @@ static ULONG WINAPI ICMStream_fnRelease(IAVIStream* iface) if (This->hic != NULL) { if (This->lpbiPrev != NULL) { ICDecompressEnd(This->hic); - GlobalFreePtr(This->lpbiPrev); + HeapFree(GetProcessHeap(), 0, This->lpbiPrev); This->lpbiPrev = NULL; This->lpPrev = NULL; } @@ -203,22 +201,22 @@ static ULONG WINAPI ICMStream_fnRelease(IAVIStream* iface) This->hic = NULL; } if (This->lpbiCur != NULL) { - GlobalFreePtr(This->lpbiCur); + HeapFree(GetProcessHeap(), 0, This->lpbiCur); This->lpbiCur = NULL; This->lpCur = NULL; } if (This->lpbiOutput != NULL) { - GlobalFreePtr(This->lpbiOutput); + HeapFree(GetProcessHeap(), 0, This->lpbiOutput); This->lpbiOutput = NULL; This->cbOutput = 0; } if (This->lpbiInput != NULL) { - GlobalFreePtr(This->lpbiInput); + HeapFree(GetProcessHeap(), 0, This->lpbiInput); This->lpbiInput = NULL; This->cbInput = 0; } - LocalFree((HLOCAL)This); + HeapFree(GetProcessHeap(), 0, This); return 0; } @@ -480,7 +478,7 @@ static HRESULT WINAPI ICMStream_fnSetFormat(IAVIStream *iface, LONG pos, assert(This->hic != NULL); /* get memory for input format */ - This->lpbiInput = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, formatsize); + This->lpbiInput = HeapAlloc(GetProcessHeap(), 0, formatsize); if (This->lpbiInput == NULL) return AVIERR_MEMORY; This->cbInput = formatsize; @@ -490,7 +488,7 @@ static HRESULT WINAPI ICMStream_fnSetFormat(IAVIStream *iface, LONG pos, size = ICCompressGetFormatSize(This->hic, This->lpbiInput); if (size < sizeof(BITMAPINFOHEADER)) return AVIERR_COMPRESSOR; - This->lpbiOutput = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, size); + This->lpbiOutput = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiOutput == NULL) return AVIERR_MEMORY; This->cbOutput = size; @@ -509,8 +507,7 @@ static HRESULT WINAPI ICMStream_fnSetFormat(IAVIStream *iface, LONG pos, /* allocate memory for compressed frame */ size = ICCompressGetSize(This->hic, This->lpbiInput, This->lpbiOutput); - This->lpbiCur = - (LPBITMAPINFOHEADER)GlobalAllocPtr(GMEM_MOVEABLE, This->cbOutput + size); + This->lpbiCur = HeapAlloc(GetProcessHeap(), 0, This->cbOutput + size); if (This->lpbiCur == NULL) return AVIERR_MEMORY; memcpy(This->lpbiCur, This->lpbiOutput, This->cbOutput); @@ -520,7 +517,7 @@ static HRESULT WINAPI ICMStream_fnSetFormat(IAVIStream *iface, LONG pos, if (This->lKeyFrameEvery != 1 && (This->dwICMFlags & VIDCF_FASTTEMPORALC) == 0) { size = ICDecompressGetFormatSize(This->hic, This->lpbiOutput); - This->lpbiPrev = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, size); + This->lpbiPrev = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiPrev == NULL) return AVIERR_MEMORY; if (ICDecompressGetFormat(This->hic, This->lpbiOutput, This->lpbiPrev) < S_OK) @@ -533,8 +530,7 @@ static HRESULT WINAPI ICMStream_fnSetFormat(IAVIStream *iface, LONG pos, /* get memory for format and picture */ size += This->lpbiPrev->biSizeImage; - This->lpbiPrev = - (LPBITMAPINFOHEADER)GlobalReAllocPtr(This->lpbiPrev,size,GMEM_MOVEABLE); + This->lpbiPrev = HeapReAlloc(GetProcessHeap(), 0, This->lpbiPrev, size); if (This->lpbiPrev == NULL) return AVIERR_MEMORY; This->lpPrev = DIBPTR(This->lpbiPrev); @@ -917,7 +913,7 @@ static HRESULT AVIFILE_OpenGetFrame(IAVIStreamImpl *This) size = ICCompressGetFormatSize(This->hic, lpbi); if ((LONG)size < (LONG)sizeof(BITMAPINFOHEADER)) return AVIERR_COMPRESSOR; - This->lpbiOutput = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, size); + This->lpbiOutput = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiOutput == NULL) return AVIERR_MEMORY; This->cbOutput = size; @@ -939,7 +935,7 @@ static HRESULT AVIFILE_OpenGetFrame(IAVIStreamImpl *This) /* allocate memory for current frame */ size += This->sInfo.dwSuggestedBufferSize; - This->lpbiCur = (LPBITMAPINFOHEADER)GlobalAllocPtr(GMEM_MOVEABLE, size); + This->lpbiCur = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiCur == NULL) return AVIERR_MEMORY; memcpy(This->lpbiCur, This->lpbiOutput, This->cbOutput); @@ -949,7 +945,7 @@ static HRESULT AVIFILE_OpenGetFrame(IAVIStreamImpl *This) if (This->lKeyFrameEvery != 1 && (This->dwICMFlags & VIDCF_FASTTEMPORALC) == 0) { size = ICDecompressGetFormatSize(This->hic, This->lpbiOutput); - This->lpbiPrev = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, size); + This->lpbiPrev = HeapAlloc(GetProcessHeap(), 0, size); if (This->lpbiPrev == NULL) return AVIERR_MEMORY; if (ICDecompressGetFormat(This->hic, This->lpbiOutput, This->lpbiPrev) < S_OK) @@ -962,8 +958,7 @@ static HRESULT AVIFILE_OpenGetFrame(IAVIStreamImpl *This) /* get memory for format and picture */ size += This->lpbiPrev->biSizeImage; - This->lpbiPrev = - (LPBITMAPINFOHEADER)GlobalReAllocPtr(This->lpbiPrev,size,GMEM_MOVEABLE); + This->lpbiPrev = HeapReAlloc(GetProcessHeap(), 0, This->lpbiPrev, size ); if (This->lpbiPrev == NULL) return AVIERR_MEMORY; This->lpPrev = DIBPTR(This->lpbiPrev); diff --git a/reactos/dll/win32/avifil32/regsvr.c b/reactos/dll/win32/avifil32/regsvr.c index 87d6d8d4d52..57badd1d013 100644 --- a/reactos/dll/win32/avifil32/regsvr.c +++ b/reactos/dll/win32/avifil32/regsvr.c @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COM_NO_WINDOWS_H @@ -30,7 +30,6 @@ #include "winerror.h" #include "mmsystem.h" -#include "mmreg.h" #include "vfw.h" #include "avifile_private.h" @@ -152,7 +151,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list) } if (list->base_iid) { - register_key_guid(iid_key, base_ifa_keyname, list->base_iid); + res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid); if (res != ERROR_SUCCESS) goto error_close_iid_key; } @@ -174,12 +173,12 @@ static HRESULT register_interfaces(struct regsvr_interface const *list) } if (list->ps_clsid) { - register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid); + res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid); if (res != ERROR_SUCCESS) goto error_close_iid_key; } if (list->ps_clsid32) { - register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32); + res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32); if (res != ERROR_SUCCESS) goto error_close_iid_key; } diff --git a/reactos/dll/win32/avifil32/rsrc.rc b/reactos/dll/win32/avifil32/rsrc.rc index 0821ae52800..a1bc0a1eaed 100644 --- a/reactos/dll/win32/avifil32/rsrc.rc +++ b/reactos/dll/win32/avifil32/rsrc.rc @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "windef.h" @@ -43,6 +43,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #include "avifile_En.rc" #include "avifile_Es.rc" #include "avifile_Fr.rc" +#include "avifile_Hu.rc" #include "avifile_It.rc" #include "avifile_Ja.rc" #include "avifile_Ko.rc" @@ -52,3 +53,4 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #include "avifile_Pt.rc" #include "avifile_Ru.rc" #include "avifile_Si.rc" +#include "avifile_Tr.rc" diff --git a/reactos/dll/win32/avifil32/tmpfile.c b/reactos/dll/win32/avifil32/tmpfile.c index 02c14a0ec1a..1bac19e2fc5 100644 --- a/reactos/dll/win32/avifil32/tmpfile.c +++ b/reactos/dll/win32/avifil32/tmpfile.c @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COM_NO_WINDOWS_H @@ -26,9 +26,7 @@ #include "winuser.h" #include "winnls.h" #include "winerror.h" -#include "windowsx.h" #include "mmsystem.h" -#include "mmreg.h" #include "vfw.h" #include "avifile_private.h" @@ -78,7 +76,7 @@ PAVIFILE AVIFILE_CreateAVITempFile(int nStreams, PAVISTREAM *ppStreams) { ITmpFileImpl *tmpFile; int i; - tmpFile = LocalAlloc(LPTR, sizeof(ITmpFileImpl)); + tmpFile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ITmpFileImpl)); if (tmpFile == NULL) return NULL; @@ -87,9 +85,9 @@ PAVIFILE AVIFILE_CreateAVITempFile(int nStreams, PAVISTREAM *ppStreams) { memset(&tmpFile->fInfo, 0, sizeof(tmpFile->fInfo)); tmpFile->fInfo.dwStreams = nStreams; - tmpFile->ppStreams = LocalAlloc(LPTR, nStreams * sizeof(PAVISTREAM)); + tmpFile->ppStreams = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(PAVISTREAM)); if (tmpFile->ppStreams == NULL) { - LocalFree((HLOCAL)tmpFile); + HeapFree(GetProcessHeap(), 0, tmpFile); return NULL; } @@ -178,7 +176,7 @@ static ULONG WINAPI ITmpFile_fnRelease(IAVIFile *iface) } } - LocalFree((HLOCAL)This); + HeapFree(GetProcessHeap(), 0, This); return 0; } diff --git a/reactos/dll/win32/avifil32/wavfile.c b/reactos/dll/win32/avifil32/wavfile.c index 146550b63df..8a0f6ab3792 100644 --- a/reactos/dll/win32/avifil32/wavfile.c +++ b/reactos/dll/win32/avifil32/wavfile.c @@ -13,7 +13,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COM_NO_WINDOWS_H @@ -26,9 +26,7 @@ #include "winuser.h" #include "winnls.h" #include "winerror.h" -#include "windowsx.h" #include "mmsystem.h" -#include "mmreg.h" #include "vfw.h" #include "msacm.h" @@ -226,7 +224,7 @@ HRESULT AVIFILE_CreateWAVFile(REFIID riid, LPVOID *ppv) *ppv = NULL; - pfile = (IAVIFileImpl*)LocalAlloc(LPTR, sizeof(IAVIFileImpl)); + pfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIFileImpl)); if (pfile == NULL) return AVIERR_MEMORY; @@ -239,7 +237,7 @@ HRESULT AVIFILE_CreateWAVFile(REFIID riid, LPVOID *ppv) hr = IAVIFile_QueryInterface((IAVIFile*)pfile, riid, ppv); if (FAILED(hr)) - LocalFree((HLOCAL)pfile); + HeapFree(GetProcessHeap(), 0, pfile); return hr; } @@ -290,25 +288,23 @@ static ULONG WINAPI IAVIFile_fnRelease(IAVIFile *iface) } if (This->lpFormat != NULL) { - GlobalFreePtr(This->lpFormat); + HeapFree(GetProcessHeap(), 0, This->lpFormat); This->lpFormat = NULL; This->cbFormat = 0; } if (This->extra.lp != NULL) { - GlobalFreePtr(This->extra.lp); + HeapFree(GetProcessHeap(), 0, This->extra.lp); This->extra.lp = NULL; This->extra.cb = 0; } - if (This->szFileName != NULL) { - LocalFree((HLOCAL)This->szFileName); - This->szFileName = NULL; - } + HeapFree(GetProcessHeap(), 0, This->szFileName); + This->szFileName = NULL; if (This->hmmio != NULL) { mmioClose(This->hmmio, 0); This->hmmio = NULL; } - LocalFree((HLOCAL)This); + HeapFree(GetProcessHeap(), 0, This); return 0; } return ref; @@ -486,7 +482,7 @@ static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile *iface, DWORD fccType, if ((This->uMode & MMIO_RWMODE) == 0) return AVIERR_READONLY; - GlobalFreePtr(This->lpFormat); + HeapFree(GetProcessHeap(), 0, This->lpFormat); This->lpFormat = NULL; This->cbFormat = 0; @@ -583,7 +579,7 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, This->uMode = dwMode; len = lstrlenW(pszFileName) + 1; - This->szFileName = LocalAlloc(LPTR, len * sizeof(WCHAR)); + This->szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if (This->szFileName == NULL) return AVIERR_MEMORY; lstrcpyW(This->szFileName, pszFileName); @@ -595,7 +591,7 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, LPSTR szFileName; len = WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, NULL, 0, NULL, NULL); - szFileName = LocalAlloc(LPTR, len * sizeof(CHAR)); + szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR)); if (szFileName == NULL) return AVIERR_MEMORY; @@ -603,7 +599,7 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, len, NULL, NULL); This->hmmio = mmioOpenA(szFileName, NULL, MMIO_ALLOCBUF | dwMode); - LocalFree((HLOCAL)szFileName); + HeapFree(GetProcessHeap(), 0, szFileName); if (This->hmmio == NULL) return AVIERR_FILEOPEN; } @@ -664,7 +660,7 @@ static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile *iface, if (This->paf->szFileName != NULL) { int len = lstrlenW(This->paf->szFileName) + 1; - *ppszFileName = GlobalAllocPtr(GHND, len * sizeof(WCHAR)); + *ppszFileName = CoTaskMemAlloc(len * sizeof(WCHAR)); if (*ppszFileName == NULL) return AVIERR_MEMORY; @@ -827,7 +823,7 @@ static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos, return AVIERR_READONLY; /* get memory for format and copy it */ - This->lpFormat = (LPWAVEFORMATEX)GlobalAllocPtr(GMEM_MOVEABLE, formatsize); + This->lpFormat = HeapAlloc(GetProcessHeap(), 0, formatsize); if (This->lpFormat == NULL) return AVIERR_MEMORY; @@ -1080,7 +1076,7 @@ static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This) return AVIERR_FILEREAD; /* get memory for format and read it */ - This->lpFormat = (LPWAVEFORMATEX)GlobalAllocPtr(GMEM_MOVEABLE, ck.cksize); + This->lpFormat = HeapAlloc(GetProcessHeap(), 0, ck.cksize); if (This->lpFormat == NULL) return AVIERR_FILEREAD; This->cbFormat = ck.cksize; @@ -1169,8 +1165,7 @@ static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This) This->cbFormat = sizeof(WAVEFORMATEX); break; }; - This->lpFormat = - (LPWAVEFORMATEX)GlobalAllocPtr(GMEM_MOVEABLE, This->cbFormat); + This->lpFormat = HeapAlloc(GetProcessHeap(), 0, This->cbFormat); if (This->lpFormat == NULL) return AVIERR_MEMORY; From 82845620c67505146e9b676730977d930d6fe930 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:36:06 +0000 Subject: [PATCH 271/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24194 --- reactos/dll/win32/cabinet/cabinet.rbuild | 2 +- reactos/dll/win32/cabinet/fci.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/reactos/dll/win32/cabinet/cabinet.rbuild b/reactos/dll/win32/cabinet/cabinet.rbuild index 2a3b0ae61c4..a14559f57c9 100644 --- a/reactos/dll/win32/cabinet/cabinet.rbuild +++ b/reactos/dll/win32/cabinet/cabinet.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/cabinet/fci.c b/reactos/dll/win32/cabinet/fci.c index 87e76d5ffb4..a43c6810c20 100644 --- a/reactos/dll/win32/cabinet/fci.c +++ b/reactos/dll/win32/cabinet/fci.c @@ -64,8 +64,6 @@ There is still some work to be done: if (B) SetLastError(B); } while(0) -WINE_DEFAULT_DEBUG_CHANNEL(cabinet); - typedef struct { cab_UBYTE signature[4]; /* !CAB for unfinished cabinets else MSCF */ cab_ULONG reserved1; From a11691c3c45b57e2429d1e3607ad9c0cca67ce00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 18 Sep 2006 16:41:29 +0000 Subject: [PATCH 272/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24195 --- reactos/dll/win32/lz32/lz32.rbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/lz32/lz32.rbuild b/reactos/dll/win32/lz32/lz32.rbuild index 90982abe250..ec9470a9e3d 100644 --- a/reactos/dll/win32/lz32/lz32.rbuild +++ b/reactos/dll/win32/lz32/lz32.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine From 04b927e3ffe9c7385d18b98cf2ab347f2fb5bdd8 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:45:21 +0000 Subject: [PATCH 273/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24196 --- reactos/dll/win32/msi/action.c | 223 -------------------------- reactos/dll/win32/msi/action.h | 1 + reactos/dll/win32/msi/classes.c | 5 + reactos/dll/win32/msi/cond.y | 10 +- reactos/dll/win32/msi/database.c | 28 +++- reactos/dll/win32/msi/dialog.c | 33 ++++ reactos/dll/win32/msi/font.c | 262 +++++++++++++++++++++++++++++++ reactos/dll/win32/msi/msi.rbuild | 1 + reactos/dll/win32/msi/msipriv.h | 2 + reactos/dll/win32/msi/msiquery.c | 22 ++- reactos/dll/win32/msi/sql.y | 10 +- reactos/dll/win32/msi/table.c | 8 + reactos/dll/win32/msi/tokenize.c | 3 - 13 files changed, 363 insertions(+), 245 deletions(-) create mode 100644 reactos/dll/win32/msi/font.c diff --git a/reactos/dll/win32/msi/action.c b/reactos/dll/win32/msi/action.c index 40fbd912569..fec14a4f4ef 100644 --- a/reactos/dll/win32/msi/action.c +++ b/reactos/dll/win32/msi/action.c @@ -3860,229 +3860,6 @@ static UINT ACTION_ExecuteAction(MSIPACKAGE *package) } -/* - * Code based off of code located here - * http://www.codeproject.com/gdi/fontnamefromfile.asp - * - * Using string index 4 (full font name) instead of 1 (family name) - */ -static LPWSTR load_ttfname_from(LPCWSTR filename) -{ - HANDLE handle; - LPWSTR ret = NULL; - int i; - - typedef struct _tagTT_OFFSET_TABLE{ - USHORT uMajorVersion; - USHORT uMinorVersion; - USHORT uNumOfTables; - USHORT uSearchRange; - USHORT uEntrySelector; - USHORT uRangeShift; - }TT_OFFSET_TABLE; - - typedef struct _tagTT_TABLE_DIRECTORY{ - char szTag[4]; /* table name */ - ULONG uCheckSum; /* Check sum */ - ULONG uOffset; /* Offset from beginning of file */ - ULONG uLength; /* length of the table in bytes */ - }TT_TABLE_DIRECTORY; - - typedef struct _tagTT_NAME_TABLE_HEADER{ - USHORT uFSelector; /* format selector. Always 0 */ - USHORT uNRCount; /* Name Records count */ - USHORT uStorageOffset; /* Offset for strings storage, - * from start of the table */ - }TT_NAME_TABLE_HEADER; - - typedef struct _tagTT_NAME_RECORD{ - USHORT uPlatformID; - USHORT uEncodingID; - USHORT uLanguageID; - USHORT uNameID; - USHORT uStringLength; - USHORT uStringOffset; /* from start of storage area */ - }TT_NAME_RECORD; - -#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) -#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) - - handle = CreateFileW(filename ,GENERIC_READ, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, 0 ); - if (handle != INVALID_HANDLE_VALUE) - { - TT_TABLE_DIRECTORY tblDir; - BOOL bFound = FALSE; - TT_OFFSET_TABLE ttOffsetTable; - DWORD dwRead; - - ReadFile(handle,&ttOffsetTable, sizeof(TT_OFFSET_TABLE),&dwRead,NULL); - ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables); - ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion); - ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion); - - if (ttOffsetTable.uMajorVersion != 1 || - ttOffsetTable.uMinorVersion != 0) - return NULL; - - for (i=0; i< ttOffsetTable.uNumOfTables; i++) - { - ReadFile(handle,&tblDir, sizeof(TT_TABLE_DIRECTORY),&dwRead,NULL); - if (strncmp(tblDir.szTag,"name",4)==0) - { - bFound = TRUE; - tblDir.uLength = SWAPLONG(tblDir.uLength); - tblDir.uOffset = SWAPLONG(tblDir.uOffset); - break; - } - } - - if (bFound) - { - TT_NAME_TABLE_HEADER ttNTHeader; - TT_NAME_RECORD ttRecord; - - SetFilePointer(handle, tblDir.uOffset, NULL, FILE_BEGIN); - ReadFile(handle,&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER), - &dwRead,NULL); - - ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount); - ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset); - bFound = FALSE; - for(i=0; i 0) - { - strcat(buf,tt); - ret = strdupAtoW(buf); - msi_free(buf); - break; - } - - msi_free(buf); - SetFilePointer(handle,nPos, NULL, FILE_BEGIN); - } - } - } - CloseHandle(handle); - } - else - ERR("Unable to open font file %s\n", debugstr_w(filename)); - - TRACE("Returning fontname %s\n",debugstr_w(ret)); - return ret; -} - -static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) -{ - MSIPACKAGE *package = (MSIPACKAGE*)param; - LPWSTR name; - LPCWSTR filename; - MSIFILE *file; - static const WCHAR regfont1[] = - {'S','o','f','t','w','a','r','e','\\', - 'M','i','c','r','o','s','o','f','t','\\', - 'W','i','n','d','o','w','s',' ','N','T','\\', - 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', - 'F','o','n','t','s',0}; - static const WCHAR regfont2[] = - {'S','o','f','t','w','a','r','e','\\', - 'M','i','c','r','o','s','o','f','t','\\', - 'W','i','n','d','o','w','s','\\', - 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', - 'F','o','n','t','s',0}; - HKEY hkey1; - HKEY hkey2; - MSIRECORD *uirow; - LPWSTR uipath, p; - - filename = MSI_RecordGetString( row, 1 ); - file = get_loaded_file( package, filename ); - if (!file) - { - ERR("Unable to load file\n"); - return ERROR_SUCCESS; - } - - /* check to make sure that component is installed */ - if (!ACTION_VerifyComponentForAction( file->Component, INSTALLSTATE_LOCAL)) - { - TRACE("Skipping: Component not scheduled for install\n"); - return ERROR_SUCCESS; - } - - RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont1,&hkey1); - RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2); - - if (MSI_RecordIsNull(row,2)) - name = load_ttfname_from( file->TargetPath ); - else - name = msi_dup_record_field(row,2); - - if (name) - { - msi_reg_set_val_str( hkey1, name, file->FileName ); - msi_reg_set_val_str( hkey2, name, file->FileName ); - } - - msi_free(name); - RegCloseKey(hkey1); - RegCloseKey(hkey2); - - /* the UI chunk */ - uirow = MSI_CreateRecord( 1 ); - uipath = strdupW( file->TargetPath ); - p = strrchrW(uipath,'\\'); - if (p) p++; - else p = uipath; - MSI_RecordSetStringW( uirow, 1, p ); - ui_actiondata( package, szRegisterFonts, uirow); - msiobj_release( &uirow->hdr ); - msi_free( uipath ); - /* FIXME: call ui_progress? */ - - return ERROR_SUCCESS; -} - -static UINT ACTION_RegisterFonts(MSIPACKAGE *package) -{ - UINT rc; - MSIQUERY * view; - static const WCHAR ExecSeqQuery[] = - {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - '`','F','o','n','t','`',0}; - - rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view); - if (rc != ERROR_SUCCESS) - { - TRACE("MSI_DatabaseOpenViewW failed: %d\n", rc); - return ERROR_SUCCESS; - } - - MSI_IterateRecords(view, NULL, ITERATE_RegisterFonts, package); - msiobj_release(&view->hdr); - - return ERROR_SUCCESS; -} - static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param) { MSIPACKAGE *package = (MSIPACKAGE*)param; diff --git a/reactos/dll/win32/msi/action.h b/reactos/dll/win32/msi/action.h index 22ad1beb98e..785c4e3fda2 100644 --- a/reactos/dll/win32/msi/action.h +++ b/reactos/dll/win32/msi/action.h @@ -253,6 +253,7 @@ extern UINT ACTION_RegisterClassInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package); +extern UINT ACTION_RegisterFonts(MSIPACKAGE *package); /* Helpers */ diff --git a/reactos/dll/win32/msi/classes.c b/reactos/dll/win32/msi/classes.c index b91d96bb738..43e89579a86 100644 --- a/reactos/dll/win32/msi/classes.c +++ b/reactos/dll/win32/msi/classes.c @@ -845,6 +845,11 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) RegCreateKeyW( hkey2, cls->Context, &hkey3 ); file = get_loaded_file( package, comp->KeyPath ); + if (!file) + { + TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid)); + continue; + } /* * FIXME: Implement install on demand (advertised components). diff --git a/reactos/dll/win32/msi/cond.y b/reactos/dll/win32/msi/cond.y index fda2c69f1dc..dd8252ad171 100644 --- a/reactos/dll/win32/msi/cond.y +++ b/reactos/dll/win32/msi/cond.y @@ -40,7 +40,7 @@ #define YYLEX_PARAM info #define YYPARSE_PARAM info -static int COND_error(const char *str); +static int cond_error(const char *str); WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -59,7 +59,7 @@ struct cond_str { static LPWSTR COND_GetString( struct cond_str *str ); static LPWSTR COND_GetLiteral( struct cond_str *str ); -static int COND_lex( void *COND_lval, COND_input *info); +static int cond_lex( void *COND_lval, COND_input *info); static const WCHAR szEmpty[] = { 0 }; static INT compare_int( INT a, INT operator, INT b ); @@ -667,7 +667,7 @@ static int COND_GetOne( struct cond_str *str, COND_input *cond ) return rc; } -static int COND_lex( void *COND_lval, COND_input *cond ) +static int cond_lex( void *COND_lval, COND_input *cond ) { int rc; struct cond_str *str = COND_lval; @@ -707,7 +707,7 @@ static LPWSTR COND_GetLiteral( struct cond_str *str ) return ret; } -static int COND_error(const char *str) +static int cond_error(const char *str) { TRACE("%s\n", str ); return 0; @@ -728,7 +728,7 @@ MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition ) cond.n = 0; cond.result = MSICONDITION_ERROR; - if ( !COND_parse( &cond ) ) + if ( !cond_parse( &cond ) ) r = cond.result; else r = MSICONDITION_ERROR; diff --git a/reactos/dll/win32/msi/database.c b/reactos/dll/win32/msi/database.c index b92d3bf27a6..d98461355a4 100644 --- a/reactos/dll/win32/msi/database.c +++ b/reactos/dll/win32/msi/database.c @@ -64,6 +64,11 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg ) r = IStorage_Release( db->storage ); if( r ) ERR("database reference count was not zero (%ld)\n", r); + if (db->deletefile) + { + DeleteFileW( db->deletefile ); + msi_free( db->deletefile ); + } } UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) @@ -74,6 +79,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) UINT ret = ERROR_FUNCTION_FAILED; LPCWSTR szMode; STATSTG stat; + BOOL created = FALSE; TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) ); @@ -83,12 +89,15 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) szMode = szPersist; if( HIWORD( szPersist ) ) { - /* UINT len = lstrlenW( szPerist ) + 1; */ - FIXME("don't support persist files yet\b"); - return ERROR_INVALID_PARAMETER; - /* szMode = msi_alloc( len * sizeof (DWORD) ); */ + if (!CopyFileW( szDBPath, szPersist, FALSE )) + return ERROR_OPEN_FAILED; + + szDBPath = szPersist; + szPersist = MSIDBOPEN_TRANSACT; + created = TRUE; } - else if( szPersist == MSIDBOPEN_READONLY ) + + if( szPersist == MSIDBOPEN_READONLY ) { r = StgOpenStorage( szDBPath, NULL, STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg); @@ -97,13 +106,14 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) { /* FIXME: MSIDBOPEN_CREATE should case STGM_TRANSACTED flag to be * used here: */ - r = StgCreateDocfile( szDBPath, - STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg); + r = StgCreateDocfile( szDBPath, + STGM_CREATE|STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg); if( r == ERROR_SUCCESS ) { IStorage_SetClass( stg, &CLSID_MsiDatabase ); r = init_string_table( stg ); } + created = TRUE; } else if( szPersist == MSIDBOPEN_TRANSACT ) { @@ -157,6 +167,10 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) db->storage = stg; db->mode = szMode; + if (created) + db->deletefile = strdupW( szDBPath ); + else + db->deletefile = NULL; list_init( &db->tables ); list_init( &db->transforms ); diff --git a/reactos/dll/win32/msi/dialog.c b/reactos/dll/win32/msi/dialog.c index aa0e2ae88b4..0b63966435f 100644 --- a/reactos/dll/win32/msi/dialog.c +++ b/reactos/dll/win32/msi/dialog.c @@ -2328,6 +2328,38 @@ static void msi_dialog_vcl_add_columns( msi_dialog *dialog, msi_control *control } } +static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control ) +{ + LPWSTR drives, ptr; + LVITEMW lvitem; + DWORD size; + int i = 0; + + size = GetLogicalDriveStringsW( 0, NULL ); + if ( !size ) return; + + drives = msi_alloc( (size + 1) * sizeof(WCHAR) ); + if ( !drives ) return; + + GetLogicalDriveStringsW( size, drives ); + + ptr = drives; + while (*ptr) + { + lvitem.mask = LVIF_TEXT; + lvitem.iItem = i; + lvitem.iSubItem = 0; + lvitem.pszText = ptr; + lvitem.cchTextMax = lstrlenW(ptr) + 1; + SendMessageW( control->hwnd, LVM_INSERTITEMW, 0, (LPARAM)&lvitem ); + + ptr += lstrlenW(ptr) + 1; + i++; + } + + msi_free( drives ); +} + static UINT msi_dialog_volumecost_list( msi_dialog *dialog, MSIRECORD *rec ) { msi_control *control; @@ -2341,6 +2373,7 @@ static UINT msi_dialog_volumecost_list( msi_dialog *dialog, MSIRECORD *rec ) return ERROR_FUNCTION_FAILED; msi_dialog_vcl_add_columns( dialog, control, rec ); + msi_dialog_vcl_add_drives( dialog, control ); return ERROR_SUCCESS; } diff --git a/reactos/dll/win32/msi/font.c b/reactos/dll/win32/msi/font.c new file mode 100644 index 00000000000..ce75520ddec --- /dev/null +++ b/reactos/dll/win32/msi/font.c @@ -0,0 +1,262 @@ +/* + * Implementation of the Microsoft Installer (msi.dll) + * + * Copyright 2004,2005 Aric Stewart for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" +#include "wine/debug.h" +#include "msipriv.h" +#include "wine/unicode.h" +#include "action.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msi); + +typedef struct _tagTT_OFFSET_TABLE { + USHORT uMajorVersion; + USHORT uMinorVersion; + USHORT uNumOfTables; + USHORT uSearchRange; + USHORT uEntrySelector; + USHORT uRangeShift; +} TT_OFFSET_TABLE; + +typedef struct _tagTT_TABLE_DIRECTORY { + char szTag[4]; /* table name */ + ULONG uCheckSum; /* Check sum */ + ULONG uOffset; /* Offset from beginning of file */ + ULONG uLength; /* length of the table in bytes */ +} TT_TABLE_DIRECTORY; + +typedef struct _tagTT_NAME_TABLE_HEADER { + USHORT uFSelector; /* format selector. Always 0 */ + USHORT uNRCount; /* Name Records count */ + USHORT uStorageOffset; /* Offset for strings storage, + * from start of the table */ +} TT_NAME_TABLE_HEADER; + +typedef struct _tagTT_NAME_RECORD { + USHORT uPlatformID; + USHORT uEncodingID; + USHORT uLanguageID; + USHORT uNameID; + USHORT uStringLength; + USHORT uStringOffset; /* from start of storage area */ +} TT_NAME_RECORD; + +#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) +#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) + +static const WCHAR szRegisterFonts[] = + {'R','e','g','i','s','t','e','r','F','o','n','t','s',0}; + +/* + * Code based off of code located here + * http://www.codeproject.com/gdi/fontnamefromfile.asp + * + * Using string index 4 (full font name) instead of 1 (family name) + */ +static LPWSTR load_ttfname_from(LPCWSTR filename) +{ + TT_TABLE_DIRECTORY tblDir; + BOOL bFound = FALSE; + TT_OFFSET_TABLE ttOffsetTable; + TT_NAME_TABLE_HEADER ttNTHeader; + TT_NAME_RECORD ttRecord; + DWORD dwRead; + HANDLE handle; + LPWSTR ret = NULL; + int i; + + handle = CreateFileW(filename ,GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0 ); + if (handle == INVALID_HANDLE_VALUE) + { + ERR("Unable to open font file %s\n", debugstr_w(filename)); + return NULL; + } + + if (!ReadFile(handle,&ttOffsetTable, sizeof(TT_OFFSET_TABLE),&dwRead,NULL)) + goto end; + + ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables); + ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion); + ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion); + + if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0) + goto end; + + for (i=0; i< ttOffsetTable.uNumOfTables; i++) + { + if (!ReadFile(handle,&tblDir, sizeof(TT_TABLE_DIRECTORY),&dwRead,NULL)) + break; + if (memcmp(tblDir.szTag,"name",4)==0) + { + bFound = TRUE; + tblDir.uLength = SWAPLONG(tblDir.uLength); + tblDir.uOffset = SWAPLONG(tblDir.uOffset); + break; + } + } + + if (!bFound) + goto end; + + SetFilePointer(handle, tblDir.uOffset, NULL, FILE_BEGIN); + if (!ReadFile(handle,&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER), &dwRead,NULL)) + goto end; + + ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount); + ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset); + bFound = FALSE; + for(i=0; i 0) + { + strcat(buf,tt); + ret = strdupAtoW(buf); + msi_free(buf); + break; + } + + msi_free(buf); + SetFilePointer(handle,nPos, NULL, FILE_BEGIN); + } + } + +end: + CloseHandle(handle); + + TRACE("Returning fontname %s\n",debugstr_w(ret)); + return ret; +} + +static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) +{ + MSIPACKAGE *package = (MSIPACKAGE*)param; + LPWSTR name; + LPCWSTR filename; + MSIFILE *file; + static const WCHAR regfont1[] = + {'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s',' ','N','T','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'F','o','n','t','s',0}; + static const WCHAR regfont2[] = + {'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'F','o','n','t','s',0}; + HKEY hkey1; + HKEY hkey2; + MSIRECORD *uirow; + LPWSTR uipath, p; + + filename = MSI_RecordGetString( row, 1 ); + file = get_loaded_file( package, filename ); + if (!file) + { + ERR("Unable to load file\n"); + return ERROR_SUCCESS; + } + + /* check to make sure that component is installed */ + if (!ACTION_VerifyComponentForAction( file->Component, INSTALLSTATE_LOCAL)) + { + TRACE("Skipping: Component not scheduled for install\n"); + return ERROR_SUCCESS; + } + + RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont1,&hkey1); + RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2); + + if (MSI_RecordIsNull(row,2)) + name = load_ttfname_from( file->TargetPath ); + else + name = msi_dup_record_field(row,2); + + if (name) + { + msi_reg_set_val_str( hkey1, name, file->FileName ); + msi_reg_set_val_str( hkey2, name, file->FileName ); + } + + msi_free(name); + RegCloseKey(hkey1); + RegCloseKey(hkey2); + + /* the UI chunk */ + uirow = MSI_CreateRecord( 1 ); + uipath = strdupW( file->TargetPath ); + p = strrchrW(uipath,'\\'); + if (p) p++; + else p = uipath; + MSI_RecordSetStringW( uirow, 1, p ); + ui_actiondata( package, szRegisterFonts, uirow); + msiobj_release( &uirow->hdr ); + msi_free( uipath ); + /* FIXME: call ui_progress? */ + + return ERROR_SUCCESS; +} + +UINT ACTION_RegisterFonts(MSIPACKAGE *package) +{ + UINT rc; + MSIQUERY * view; + static const WCHAR ExecSeqQuery[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','F','o','n','t','`',0}; + + rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view); + if (rc != ERROR_SUCCESS) + { + TRACE("MSI_DatabaseOpenViewW failed: %d\n", rc); + return ERROR_SUCCESS; + } + + MSI_IterateRecords(view, NULL, ITERATE_RegisterFonts, package); + msiobj_release(&view->hdr); + + return ERROR_SUCCESS; +} diff --git a/reactos/dll/win32/msi/msi.rbuild b/reactos/dll/win32/msi/msi.rbuild index 54503dc25c5..cbeb9deeb7a 100644 --- a/reactos/dll/win32/msi/msi.rbuild +++ b/reactos/dll/win32/msi/msi.rbuild @@ -38,6 +38,7 @@ distinct.c events.c files.c + font.c format.c handle.c helpers.c diff --git a/reactos/dll/win32/msi/msipriv.h b/reactos/dll/win32/msi/msipriv.h index 9a9b8b4bac3..a10be59e955 100644 --- a/reactos/dll/win32/msi/msipriv.h +++ b/reactos/dll/win32/msi/msipriv.h @@ -71,6 +71,7 @@ typedef struct tagMSIDATABASE MSIOBJECTHDR hdr; IStorage *storage; string_table *strings; + LPWSTR deletefile; LPCWSTR mode; struct list tables; struct list transforms; @@ -337,6 +338,7 @@ extern UINT msi_string_get_codepage( string_table *st ); extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name ); +extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table ); extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname, USHORT **pdata, UINT *psz ); diff --git a/reactos/dll/win32/msi/msiquery.c b/reactos/dll/win32/msi/msiquery.c index fe1a68fa318..f063ac0578f 100644 --- a/reactos/dll/win32/msi/msiquery.c +++ b/reactos/dll/win32/msi/msiquery.c @@ -754,6 +754,12 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb ) msiobj_release( &db->hdr ); + if (r == ERROR_SUCCESS) + { + msi_free( db->deletefile ); + db->deletefile = NULL; + } + return r; } @@ -893,6 +899,18 @@ MSICONDITION WINAPI MsiDatabaseIsTablePersistentA( MSICONDITION WINAPI MsiDatabaseIsTablePersistentW( MSIHANDLE hDatabase, LPCWSTR szTableName) { - FIXME("%lx %s\n", hDatabase, debugstr_w(szTableName)); - return MSICONDITION_FALSE; + MSIDATABASE *db; + MSICONDITION r; + + TRACE("%lx %s\n", hDatabase, debugstr_w(szTableName)); + + db = msihandle2msiinfo( hDatabase, MSIHANDLETYPE_DATABASE ); + if( !db ) + return MSICONDITION_ERROR; + + r = MSI_DatabaseIsTablePersistent( db, szTableName ); + + msiobj_release( &db->hdr ); + + return r; } diff --git a/reactos/dll/win32/msi/sql.y b/reactos/dll/win32/msi/sql.y index 8fa0fb340c3..abffb2f45b2 100644 --- a/reactos/dll/win32/msi/sql.y +++ b/reactos/dll/win32/msi/sql.y @@ -36,7 +36,7 @@ #define YYLEX_PARAM info #define YYPARSE_PARAM info -extern int SQL_error(const char *str); +static int sql_error(const char *str); WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -51,7 +51,7 @@ typedef struct tag_SQL_input static LPWSTR SQL_getstring( void *info, struct sql_str *str ); static INT SQL_getint( void *info ); -static int SQL_lex( void *SQL_lval, SQL_input *info ); +static int sql_lex( void *SQL_lval, SQL_input *info ); static void *parser_alloc( void *info, unsigned int sz ); static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ); @@ -686,7 +686,7 @@ static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR colu return col; } -int SQL_lex( void *SQL_lval, SQL_input *sql ) +static int sql_lex( void *SQL_lval, SQL_input *sql ) { int token; struct sql_str * str = SQL_lval; @@ -752,7 +752,7 @@ INT SQL_getint( void *info ) return r; } -int SQL_error( const char *str ) +static int sql_error( const char *str ) { return 0; } @@ -851,7 +851,7 @@ UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, sql.view = phview; sql.mem = mem; - r = SQL_parse(&sql); + r = sql_parse(&sql); TRACE("Parse returned %d\n", r); if( r ) diff --git a/reactos/dll/win32/msi/table.c b/reactos/dll/win32/msi/table.c index 1c05e797d2e..4eb3f523437 100644 --- a/reactos/dll/win32/msi/table.c +++ b/reactos/dll/win32/msi/table.c @@ -1643,6 +1643,14 @@ UINT MSI_CommitTables( MSIDATABASE *db ) return ERROR_SUCCESS; } +MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table ) +{ + if (!table) + return MSICONDITION_ERROR; + + return MSICONDITION_FALSE; +} + static MSIRECORD *msi_get_transform_record( MSITABLEVIEW *tv, string_table *st, USHORT *rawdata ) { UINT i, val, ofs = 0; diff --git a/reactos/dll/win32/msi/tokenize.c b/reactos/dll/win32/msi/tokenize.c index e8e41e31721..a63dd1fd071 100644 --- a/reactos/dll/win32/msi/tokenize.c +++ b/reactos/dll/win32/msi/tokenize.c @@ -22,13 +22,10 @@ #include "windef.h" #include "winbase.h" -#include "wine/debug.h" #include "wine/unicode.h" #include "query.h" #include "sql.tab.h" -WINE_DEFAULT_DEBUG_CHANNEL(msi); - /* ** All the keywords of the SQL language are stored as in a hash ** table composed of instances of the following structure. From 11c17d1dc0015b5fefe61d838f11b1e430352ebd Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:46:41 +0000 Subject: [PATCH 274/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24197 --- reactos/dll/win32/objsel/objsel_ros.diff | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 reactos/dll/win32/objsel/objsel_ros.diff diff --git a/reactos/dll/win32/objsel/objsel_ros.diff b/reactos/dll/win32/objsel/objsel_ros.diff deleted file mode 100644 index de2161daf7d..00000000000 --- a/reactos/dll/win32/objsel/objsel_ros.diff +++ /dev/null @@ -1,10 +0,0 @@ -Index: objsel.rbuild -=================================================================== ---- objsel.rbuild (revision 23122) -+++ objsel.rbuild (working copy) -@@ -1,4 +1,5 @@ - -+ - - . - include/reactos/wine From 2cb8454522fda51c5c9654697970485131215423 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:47:55 +0000 Subject: [PATCH 275/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24198 --- reactos/dll/win32/oleacc/oleacc.rbuild | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/oleacc/oleacc.rbuild b/reactos/dll/win32/oleacc/oleacc.rbuild index 21772894a16..75ed320a33d 100644 --- a/reactos/dll/win32/oleacc/oleacc.rbuild +++ b/reactos/dll/win32/oleacc/oleacc.rbuild @@ -1,4 +1,5 @@ - + + . include/reactos/wine From 446242dfb23b5dad2efd6c1aca071903c7f7bbf9 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:49:02 +0000 Subject: [PATCH 276/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24199 --- reactos/dll/win32/olepro32/olepro32.rbuild | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/olepro32/olepro32.rbuild b/reactos/dll/win32/olepro32/olepro32.rbuild index e1402f59f9d..f4debe204eb 100644 --- a/reactos/dll/win32/olepro32/olepro32.rbuild +++ b/reactos/dll/win32/olepro32/olepro32.rbuild @@ -1,4 +1,5 @@ - + + . include/reactos/wine From 1b0a889e2b51b54ed3c98f87e7d1c6e06d208a92 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:50:11 +0000 Subject: [PATCH 277/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24200 --- reactos/dll/win32/riched32/riched32.rbuild | 1 + reactos/dll/win32/riched32/version.rc | 24 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 reactos/dll/win32/riched32/version.rc diff --git a/reactos/dll/win32/riched32/riched32.rbuild b/reactos/dll/win32/riched32/riched32.rbuild index 80ae80e850d..c1a509f3666 100644 --- a/reactos/dll/win32/riched32/riched32.rbuild +++ b/reactos/dll/win32/riched32/riched32.rbuild @@ -14,5 +14,6 @@ kernel32 ntdll richedit.c + version.rc riched32.spec diff --git a/reactos/dll/win32/riched32/version.rc b/reactos/dll/win32/riched32/version.rc new file mode 100644 index 00000000000..f17a7836634 --- /dev/null +++ b/reactos/dll/win32/riched32/version.rc @@ -0,0 +1,24 @@ +/* + * 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 + */ + +#define WINE_FILEDESCRIPTION_STR "Wrapper Dll for Richedit" +#define WINE_FILENAME_STR "riched32.dll" +#define WINE_FILEVERSION 5,1,2600,0 +#define WINE_FILEVERSION_STR "5,1,2600,0" +#define WINE_PRODUCTVERSION 5,1,2600,0 +#define WINE_PRODUCTVERSION_STR "5,1,2600,0" + +#include "wine/wine_common_ver.rc" From 9e9bd06847c2a45ca21521bc39bb507dbf1abeb1 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:51:34 +0000 Subject: [PATCH 278/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24201 --- reactos/dll/win32/shfolder/shfolder.rbuild | 3 ++- reactos/dll/win32/shfolder/version.rc | 25 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 reactos/dll/win32/shfolder/version.rc diff --git a/reactos/dll/win32/shfolder/shfolder.rbuild b/reactos/dll/win32/shfolder/shfolder.rbuild index 269632814ca..9d0ad94316e 100644 --- a/reactos/dll/win32/shfolder/shfolder.rbuild +++ b/reactos/dll/win32/shfolder/shfolder.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine @@ -13,5 +13,6 @@ kernel32 ntdll shfolder_main.c + version.rc shfolder.spec diff --git a/reactos/dll/win32/shfolder/version.rc b/reactos/dll/win32/shfolder/version.rc new file mode 100644 index 00000000000..726bd7f464c --- /dev/null +++ b/reactos/dll/win32/shfolder/version.rc @@ -0,0 +1,25 @@ +/* + * 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 + */ + +#define WINE_OLESELFREGISTER +#define WINE_FILEDESCRIPTION_STR "Wine Shell Folder Service" +#define WINE_FILENAME_STR "shfolder.dll" +#define WINE_FILEVERSION 6,00,2800,1106 +#define WINE_FILEVERSION_STR "6,00,2800,1106" +#define WINE_PRODUCTVERSION 6,00,2800,1106 +#define WINE_PRODUCTVERSION_STR "6,00,2800,1106" + +#include "wine/wine_common_ver.rc" From d88a99e18e47164bb411f573cdd8846b76829f8d Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:52:25 +0000 Subject: [PATCH 279/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24202 --- reactos/dll/win32/uxtheme/stylemap.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/reactos/dll/win32/uxtheme/stylemap.c b/reactos/dll/win32/uxtheme/stylemap.c index 4be9819c63f..a310d4031d4 100644 --- a/reactos/dll/win32/uxtheme/stylemap.c +++ b/reactos/dll/win32/uxtheme/stylemap.c @@ -29,10 +29,6 @@ #define TMT_ENUM 200 -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); - typedef struct _MSSTYLES_PROPERTY_MAP { WORD dwPrimitiveType; WORD dwPropertyID; From d3cd32d90d2ac307d424d3e951b16044b3eb92d0 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Mon, 18 Sep 2006 16:59:16 +0000 Subject: [PATCH 280/488] Autosyncing with Wine HEAD svn path=/trunk/; revision=24203 --- reactos/dll/win32/comctl32/comctl32_ros.diff | 12 +--- reactos/dll/win32/comctl32/listview.c | 64 +++++++++++++++++++- reactos/dll/win32/comctl32/propsheet.c | 4 +- reactos/dll/win32/comctl32/theme_dialog.c | 2 - reactos/dll/win32/comctl32/theme_edit.c | 2 - reactos/dll/win32/comctl32/theme_listbox.c | 2 - reactos/dll/win32/comctl32/trackbar.c | 4 +- 7 files changed, 66 insertions(+), 24 deletions(-) diff --git a/reactos/dll/win32/comctl32/comctl32_ros.diff b/reactos/dll/win32/comctl32/comctl32_ros.diff index 463bb689f03..d14857c23c4 100644 --- a/reactos/dll/win32/comctl32/comctl32_ros.diff +++ b/reactos/dll/win32/comctl32/comctl32_ros.diff @@ -1,18 +1,8 @@ -Index: comctl32.rbuild -=================================================================== ---- comctl32.rbuild (revision 23123) -+++ comctl32.rbuild (working copy) -@@ -1,4 +1,5 @@ - -+ - - . - include/reactos/wine Index: listview.c =================================================================== --- listview.c (revision 23123) +++ listview.c (working copy) -@@ -3770,9 +3770,8 @@ +@@ -3777,9 +3777,8 @@ if (himl && lvItem.iImage >= 0 && !IsRectEmpty(&rcIcon)) { TRACE("iImage=%d\n", lvItem.iImage); diff --git a/reactos/dll/win32/comctl32/listview.c b/reactos/dll/win32/comctl32/listview.c index 9865746b69c..3631766d584 100644 --- a/reactos/dll/win32/comctl32/listview.c +++ b/reactos/dll/win32/comctl32/listview.c @@ -240,6 +240,12 @@ typedef struct tagITERATOR INT index; } ITERATOR; +typedef struct tagDELAYED_ITEM_EDIT +{ + BOOL fEnabled; + INT iItem; +} DELAYED_ITEM_EDIT; + typedef struct tagLISTVIEW_INFO { HWND hwndSelf; @@ -310,6 +316,7 @@ typedef struct tagLISTVIEW_INFO BOOL bIsDrawing; INT nMeasureItemHeight; INT xTrackLine; /* The x coefficient of the track line or -1 if none */ + DELAYED_ITEM_EDIT itemEdit; /* Pointer to this structure will be the timer ID */ } LISTVIEW_INFO; /* @@ -7614,7 +7621,32 @@ static BOOL LISTVIEW_DrawTrackLine(LISTVIEW_INFO *infoPtr) return TRUE; } - +/*** + * DESCRIPTION: + * Called when an edit control should be displayed. This function is called after + * we are sure that there was a single click - not a double click (this is a TIMERPROC). + * + * PARAMETER(S): + * [I] hwnd : Handle to the listview + * [I] uMsg : WM_TIMER (ignored) + * [I] idEvent : The timer ID interpreted as a pointer to a DELAYED_EDIT_ITEM struct + * [I] dwTimer : The elapsed time (ignored) + * + * RETURN: + * None. + */ +static CALLBACK VOID LISTVIEW_DelayedEditItem(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + DELAYED_ITEM_EDIT *editItem = (DELAYED_ITEM_EDIT *)idEvent; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(hwnd, 0); + + KillTimer(hwnd, idEvent); + editItem->fEnabled = FALSE; + /* check if the item is still selected */ + if (infoPtr->bFocus && LISTVIEW_GetItemState(infoPtr, editItem->iItem, LVIS_SELECTED)) + LISTVIEW_EditLabelT(infoPtr, editItem->iItem, TRUE); +} + /*** * DESCRIPTION: * Creates the listview control. @@ -7667,6 +7699,7 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) infoPtr->dwHoverTime = -1; /* default system hover time */ infoPtr->nMeasureItemHeight = 0; infoPtr->xTrackLine = -1; /* no track line */ + infoPtr->itemEdit.fEnabled = FALSE; /* get default font (icon title) */ SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0); @@ -8219,6 +8252,13 @@ static LRESULT LISTVIEW_LButtonDblClk(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, LVHITTESTINFO htInfo; TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, x, y); + + /* Cancel the item edition if any */ + if (infoPtr->itemEdit.fEnabled) + { + KillTimer(infoPtr->hwndSelf, (UINT_PTR)&infoPtr->itemEdit); + infoPtr->itemEdit.fEnabled = FALSE; + } /* send NM_RELEASEDCAPTURE notification */ if (!notify(infoPtr, NM_RELEASEDCAPTURE)) return 0; @@ -8252,6 +8292,7 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN { LVHITTESTINFO lvHitTestInfo; static BOOL bGroupSelect = TRUE; + BOOL bReceivedFocus = FALSE; POINT pt = { x, y }; INT nItem; @@ -8260,7 +8301,11 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN /* send NM_RELEASEDCAPTURE notification */ if (!notify(infoPtr, NM_RELEASEDCAPTURE)) return 0; - if (!infoPtr->bFocus) SetFocus(infoPtr->hwndSelf); + if (!infoPtr->bFocus) + { + bReceivedFocus = TRUE; + SetFocus(infoPtr->hwndSelf); + } /* set left button down flag and record the click position */ infoPtr->bLButtonDown = TRUE; @@ -8347,6 +8392,9 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN LISTVIEW_DeselectAll(infoPtr); ReleaseCapture(); } + + if (bReceivedFocus) + infoPtr->nEditLabelItem = -1; return 0; } @@ -8383,7 +8431,17 @@ static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT /* if we clicked on a selected item, edit the label */ if(lvHitTestInfo.iItem == infoPtr->nEditLabelItem && (lvHitTestInfo.flags & LVHT_ONITEMLABEL)) - LISTVIEW_EditLabelT(infoPtr, lvHitTestInfo.iItem, TRUE); + { + /* we want to make sure the user doesn't want to do a double click. So we will + * delay the edit. WM_LBUTTONDBLCLICK will cancel the timer + */ + infoPtr->itemEdit.fEnabled = TRUE; + infoPtr->itemEdit.iItem = lvHitTestInfo.iItem; + SetTimer(infoPtr->hwndSelf, + (UINT_PTR)&infoPtr->itemEdit, + GetDoubleClickTime(), + LISTVIEW_DelayedEditItem); + } return 0; } diff --git a/reactos/dll/win32/comctl32/propsheet.c b/reactos/dll/win32/comctl32/propsheet.c index 972f862129b..185b843cb21 100644 --- a/reactos/dll/win32/comctl32/propsheet.c +++ b/reactos/dll/win32/comctl32/propsheet.c @@ -448,7 +448,7 @@ static BOOL PROPSHEET_CollectPageInfo(LPCPROPSHEETPAGEW lppsp, else { HRSRC hResource = FindResourceA(lppsp->hInstance, - (LPSTR)lppsp->u.pszTemplate, + (LPCSTR)lppsp->u.pszTemplate, (LPSTR)RT_DIALOG); HGLOBAL hTemplate = LoadResource(lppsp->hInstance, hResource); @@ -1424,7 +1424,7 @@ static BOOL PROPSHEET_CreatePage(HWND hwndParent, HANDLE hTemplate; hResource = FindResourceA(ppshpage->hInstance, - (LPSTR)ppshpage->u.pszTemplate, + (LPCSTR)ppshpage->u.pszTemplate, (LPSTR)RT_DIALOG); if(!hResource) return FALSE; diff --git a/reactos/dll/win32/comctl32/theme_dialog.c b/reactos/dll/win32/comctl32/theme_dialog.c index cfcb56f937b..92859418e76 100644 --- a/reactos/dll/win32/comctl32/theme_dialog.c +++ b/reactos/dll/win32/comctl32/theme_dialog.c @@ -32,8 +32,6 @@ #include "comctl32.h" #include "wine/debug.h" -WINE_DEFAULT_DEBUG_CHANNEL(themingdialog); - /********************************************************************** * The dialog subclass window proc. */ diff --git a/reactos/dll/win32/comctl32/theme_edit.c b/reactos/dll/win32/comctl32/theme_edit.c index 3cbf7608121..b3b142a11db 100644 --- a/reactos/dll/win32/comctl32/theme_edit.c +++ b/reactos/dll/win32/comctl32/theme_edit.c @@ -32,8 +32,6 @@ #include "comctl32.h" #include "wine/debug.h" -WINE_DEFAULT_DEBUG_CHANNEL(themingedit); - /* Draw themed border */ static void nc_paint (HTHEME theme, HWND hwnd, HRGN region) { diff --git a/reactos/dll/win32/comctl32/theme_listbox.c b/reactos/dll/win32/comctl32/theme_listbox.c index 93e9ac7d926..8147ba4cf15 100644 --- a/reactos/dll/win32/comctl32/theme_listbox.c +++ b/reactos/dll/win32/comctl32/theme_listbox.c @@ -32,8 +32,6 @@ #include "comctl32.h" #include "wine/debug.h" -WINE_DEFAULT_DEBUG_CHANNEL(theminglistbox); - /* Draw themed border */ static void nc_paint (HTHEME theme, HWND hwnd, HRGN region) { diff --git a/reactos/dll/win32/comctl32/trackbar.c b/reactos/dll/win32/comctl32/trackbar.c index 1acccc43d93..615df572a50 100644 --- a/reactos/dll/win32/comctl32/trackbar.c +++ b/reactos/dll/win32/comctl32/trackbar.c @@ -1048,8 +1048,8 @@ TRACKBAR_GetNumTics (TRACKBAR_INFO *infoPtr) static int comp_tics(const void *ap, const void *bp) { - DWORD a = *((DWORD *)ap); - DWORD b = *((DWORD *)bp); + const DWORD a = *(const DWORD *)ap; + const DWORD b = *(const DWORD *)bp; TRACE("(a=%ld, b=%ld)\n", a, b); if (a < b) return -1; From d00d45c34e2c8606d62940152aad3aa9a29a392d Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Mon, 18 Sep 2006 21:49:12 +0000 Subject: [PATCH 281/488] Reapply entrypoint fix, patch from Usurp. svn path=/trunk/; revision=24204 --- reactos/dll/win32/cabinet/cabinet.rbuild | 2 +- reactos/dll/win32/lz32/lz32.rbuild | 2 +- reactos/dll/win32/oleacc/oleacc.rbuild | 2 +- reactos/dll/win32/olepro32/olepro32.rbuild | 2 +- reactos/dll/win32/shfolder/shfolder.rbuild | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/reactos/dll/win32/cabinet/cabinet.rbuild b/reactos/dll/win32/cabinet/cabinet.rbuild index a14559f57c9..2a3b0ae61c4 100644 --- a/reactos/dll/win32/cabinet/cabinet.rbuild +++ b/reactos/dll/win32/cabinet/cabinet.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/lz32/lz32.rbuild b/reactos/dll/win32/lz32/lz32.rbuild index ec9470a9e3d..90982abe250 100644 --- a/reactos/dll/win32/lz32/lz32.rbuild +++ b/reactos/dll/win32/lz32/lz32.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/oleacc/oleacc.rbuild b/reactos/dll/win32/oleacc/oleacc.rbuild index 75ed320a33d..415545628a6 100644 --- a/reactos/dll/win32/oleacc/oleacc.rbuild +++ b/reactos/dll/win32/oleacc/oleacc.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/win32/olepro32/olepro32.rbuild b/reactos/dll/win32/olepro32/olepro32.rbuild index f4debe204eb..7d812ab23eb 100644 --- a/reactos/dll/win32/olepro32/olepro32.rbuild +++ b/reactos/dll/win32/olepro32/olepro32.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/reactos/dll/win32/shfolder/shfolder.rbuild b/reactos/dll/win32/shfolder/shfolder.rbuild index 9d0ad94316e..fc01399d1eb 100644 --- a/reactos/dll/win32/shfolder/shfolder.rbuild +++ b/reactos/dll/win32/shfolder/shfolder.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine From 3f0a7fb997a71b15e054839544f066cf77e356f9 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Mon, 18 Sep 2006 22:25:00 +0000 Subject: [PATCH 282/488] - Add a cute custom control to sysdm allowing dialogs to display hyperlink style text which can open web pages and run exe's. - see the general page, and the user account dialog for examples. svn path=/trunk/; revision=24205 --- reactos/dll/cpl/sysdm/custclicklink.c | 209 ++++++++++++++++++++++++++ reactos/dll/cpl/sysdm/en.rc | 22 +-- reactos/dll/cpl/sysdm/general.c | 19 ++- reactos/dll/cpl/sysdm/precomp.h | 2 + reactos/dll/cpl/sysdm/resource.h | 7 +- reactos/dll/cpl/sysdm/sysdm.rbuild | 1 + reactos/dll/cpl/sysdm/userprofile.c | 7 + 7 files changed, 249 insertions(+), 18 deletions(-) create mode 100644 reactos/dll/cpl/sysdm/custclicklink.c diff --git a/reactos/dll/cpl/sysdm/custclicklink.c b/reactos/dll/cpl/sysdm/custclicklink.c new file mode 100644 index 00000000000..8622d7f8d15 --- /dev/null +++ b/reactos/dll/cpl/sysdm/custclicklink.c @@ -0,0 +1,209 @@ +/* + * PROJECT: ReactOS System Control Panel Applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/custclicklink.c + * PURPOSE: Subclass static control to link to apps + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +#define LINK_COLOR RGB(0,0,128) +#define MAX_PARAMS 256 + +typedef struct _LINKCTL +{ + HWND hSelf; + WNDPROC OldProc; + TCHAR szApp[MAX_PATH]; + TCHAR szParams[MAX_PARAMS]; + HFONT hFont; + BOOL bClicked; +} LINKCTL, *PLINKCTL; + + + +static VOID +DoLButtonUp(PLINKCTL pLink, LPARAM lParam) +{ + ReleaseCapture(); + if (pLink->bClicked) + { + POINT pt; + RECT rc; + + pt.x = (short)LOWORD(lParam); + pt.y = (short)HIWORD(lParam); + ClientToScreen(pLink->hSelf, &pt); + GetWindowRect(pLink->hSelf, &rc); + if (PtInRect(&rc, pt)) + { + ShellExecute(NULL, + _T("open"), + pLink->szApp, + pLink->szParams, + NULL, + SW_SHOWNORMAL); + } + + pLink->bClicked = FALSE; + } +} + + +static VOID +DoPaint(PLINKCTL pLink, HDC hdc) +{ + TCHAR szText[MAX_PATH]; + DWORD WinStyle, DrawStyle; + RECT rc; + HANDLE hOld; + + WinStyle = GetWindowLongPtr(pLink->hSelf, GWL_STYLE); + DrawStyle = DT_SINGLELINE; + + if (WinStyle & SS_CENTER) + DrawStyle |= DT_CENTER; + if (WinStyle & SS_RIGHT) + DrawStyle |= DT_RIGHT; + if (WinStyle & SS_CENTERIMAGE) + DrawStyle |= DT_VCENTER; + + SetTextColor(hdc, LINK_COLOR); + SetBkMode(hdc, TRANSPARENT); + hOld = SelectObject(hdc, pLink->hFont); + SetBkColor(hdc, GetSysColor(COLOR_3DFACE)); + + GetClientRect(pLink->hSelf, &rc); + + GetWindowText(pLink->hSelf, szText, sizeof(szText)); + DrawText(hdc, szText, -1, &rc, DrawStyle); + +} + + +static LRESULT CALLBACK +LinkCtlWndProc(HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + PLINKCTL pLink = (PLINKCTL)GetWindowLongPtr(hwnd, GWL_USERDATA); + WNDPROC oldproc = pLink->OldProc; + + switch(msg) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc; + + hdc = BeginPaint(hwnd, &ps); + DoPaint(pLink, hdc); + EndPaint(hwnd, &ps); + return 0; + } + + case WM_SETCURSOR: + { + HCURSOR hCur = LoadCursor(NULL, IDC_HAND); + SetCursor(hCur); + return TRUE; + } + + case WM_SETFONT: + { + LOGFONT LogFont; + HFONT hOldFont; + + hOldFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); + GetObject(hOldFont, sizeof(LogFont), &LogFont); + LogFont.lfUnderline = TRUE; + if (pLink->hFont) DeleteObject(hwnd); + pLink->hFont = CreateFontIndirect(&LogFont); + + CallWindowProc(pLink->OldProc, hwnd, msg, wParam, lParam); + + if (LOWORD(lParam)) + { + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + return 0; + } + + case WM_NCHITTEST: + return HTCLIENT; + + case WM_LBUTTONDOWN: + { + SetFocus(hwnd); + SetCapture(hwnd); + pLink->bClicked = TRUE; + } + break; + + case WM_LBUTTONUP: + { + DoLButtonUp(pLink, lParam); + } + break; + + case WM_NCDESTROY: + { + HeapFree(GetProcessHeap(), + 0, + pLink); + } + break; + } + + return CallWindowProc(oldproc, + hwnd, + msg, + wParam, + lParam); +} + + +BOOL +TextToLink(HWND hwnd, + LPTSTR lpApp, + LPTSTR lpParams) +{ + PLINKCTL pLink; + HFONT hFont; + + /* error checking */ + if (lstrlen(lpApp) >= (MAX_PATH - 1) || + lstrlen(lpParams) >= (MAX_PARAMS -1)) + { + return FALSE; + } + + pLink = (PLINKCTL)HeapAlloc(GetProcessHeap(), + 0, + sizeof(LINKCTL)); + if (pLink == NULL) + return FALSE; + + pLink->hSelf = hwnd; + lstrcpyn(pLink->szApp, lpApp, MAX_PATH); + lstrcpyn(pLink->szParams, lpParams, MAX_PARAMS); + pLink->bClicked = FALSE; + + hFont=(HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); + + + pLink->OldProc = (WNDPROC)SetWindowLongPtr(hwnd, + GWL_WNDPROC, + (LONG_PTR)LinkCtlWndProc); + SetWindowLongPtr(hwnd, + GWL_USERDATA, + (LONG_PTR)pLink); + + SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, 0); + + return TRUE; +} diff --git a/reactos/dll/cpl/sysdm/en.rc b/reactos/dll/cpl/sysdm/en.rc index 109506f89b1..7c48d116693 100644 --- a/reactos/dll/cpl/sysdm/en.rc +++ b/reactos/dll/cpl/sysdm/en.rc @@ -15,7 +15,8 @@ BEGIN LTEXT "", IDC_PROCESSOR, 130, 153, 118, 9 LTEXT "", IDC_PROCESSORSPEED, 130, 162, 118, 9 LTEXT "", IDC_SYSTEMMEMORY, 130, 171, 118, 9 - PUSHBUTTON "View licence...", IDC_LICENCE, 90, 199, 78, 13 + LTEXT "Visit the ReactOS Homepage", IDC_ROSHOMEPAGE_LINK, 20, 200, 93, 8 + PUSHBUTTON "View licence...", IDC_LICENCE, 170, 199, 78, 13 END @@ -132,9 +133,9 @@ END IDD_USERPROFILE DIALOGEX 0, 0, 256, 218 -STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CONTEXTHELP | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "User Profiles" -FONT 8, "MS Shell Dlg", 0, 0, 0x0 +FONT 8, "MS Shell Dlg" BEGIN ICON IDI_USERPROF, IDC_STATIC, 6, 11, 16, 16, SS_ICON LTEXT "User profiles contain desktop settings and other information related to your login. A different profile can be created on each computer you use, or you can select a roaming profile that is the same on every computer you use.", @@ -142,15 +143,16 @@ BEGIN LTEXT "Profiles stored on this computer:", IDC_STATIC, 16, 51, 204, 9 CONTROL "", IDC_USERPROFILE_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, 6, 66, 244, 85, WS_EX_CLIENTEDGE - PUSHBUTTON "Change Type...", IDC_USERPROFILE_CHANGE, 134, 156, 62, 13 + PUSHBUTTON "Change Type", IDC_USERPROFILE_CHANGE, 90, 156, 50, 13 + PUSHBUTTON "Delete", IDC_USERPROFILE_DELETE, 145, 156, 50, 13 + PUSHBUTTON "Copy To", IDC_USERPROFILE_COPY, 200, 156, 50, 13 - LTEXT "To create new user accounts, open ", IDC_STATIC, 10, 175, 116, 9 - // FIXME: needs custom control writing - //CONTROL "", IDC_CUST_LINK, "LinkCtlProc", WS_CHILD | VS_VISIBLE | WS_TABSTOP, 127, 175, 60, 9 - LTEXT "in Control Panel.", IDC_STATIC, 184, 175, 64, 9 + LTEXT "To create new user accounts, open ", IDC_STATIC, 7, 175, 116, 8 + LTEXT "User Accounts", IDC_USERACCOUNT_LINK, 123, 175, 48, 8 + LTEXT "in Control Panel.", IDC_STATIC, 173, 175, 64, 8 - DEFPUSHBUTTON "OK", IDOK, 134, 197, 54, 13 - PUSHBUTTON "Cancel", IDCANCEL, 196, 197, 54, 13 + DEFPUSHBUTTON "OK", IDOK, 134, 200, 54, 13 + PUSHBUTTON "Cancel", IDCANCEL, 196, 200, 54, 13 END diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index 84d66a745ff..26e56081f9c 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -95,6 +95,12 @@ GeneralPageProc(HWND hwndDlg, { case WM_INITDIALOG: { + HWND hLink = GetDlgItem(hwndDlg, IDC_ROSHOMEPAGE_LINK); + + TextToLink(hLink, + _T("http://www.reactos.org"), + NULL); + InitImageInfo(&ImgInfo); GetSystemInformation(hwndDlg); } @@ -108,6 +114,7 @@ GeneralPageProc(HWND hwndDlg, MAKEINTRESOURCE(IDD_LICENCE), hwndDlg, LicenceDlgProc); + return TRUE; } } @@ -129,21 +136,21 @@ GeneralPageProc(HWND hwndDlg, if (hdcMem != NULL) { SelectObject(hdcMem, ImgInfo.hBitmap); - BitBlt(lpDrawItem->hDC, - left, + BitBlt(lpDrawItem->hDC, + left, lpDrawItem->rcItem.top, lpDrawItem->rcItem.right - lpDrawItem->rcItem.left, lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top, - hdcMem, - 0, - 0, + hdcMem, + 0, + 0, SRCCOPY); DeleteDC(hdcMem); } } return TRUE; } - + } return FALSE; diff --git a/reactos/dll/cpl/sysdm/precomp.h b/reactos/dll/cpl/sysdm/precomp.h index 0e3a8fb9207..3b5b31b591d 100644 --- a/reactos/dll/cpl/sysdm/precomp.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -39,6 +39,8 @@ INT_PTR CALLBACK StartRecDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM INT_PTR CALLBACK VirtMemDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK LicenceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +BOOL TextToLink(HWND hwnd, LPTSTR lpApp, LPTSTR lpParams); + typedef struct _PAGEFILE { TCHAR szDrive[3]; diff --git a/reactos/dll/cpl/sysdm/resource.h b/reactos/dll/cpl/sysdm/resource.h index 8b402c260f0..c1eb5ae4798 100644 --- a/reactos/dll/cpl/sysdm/resource.h +++ b/reactos/dll/cpl/sysdm/resource.h @@ -21,8 +21,9 @@ #define IDC_PROCESSOR 102 #define IDC_PROCESSORSPEED 103 #define IDC_SYSTEMMEMORY 104 -#define IDC_LICENCE 105 +#define IDC_LICENCE 105 #define IDC_ROSIMG 106 +#define IDC_ROSHOMEPAGE_LINK 107 /* propsheet - computer name */ @@ -56,7 +57,9 @@ #define IDD_USERPROFILE 500 #define IDC_USERPROFILE_LIST 501 #define IDC_USERPROFILE_CHANGE 503 -#define IDC_CUST_LINK 504 +#define IDC_USERPROFILE_DELETE 504 +#define IDC_USERPROFILE_COPY 505 +#define IDC_USERACCOUNT_LINK 506 /* environment variables */ diff --git a/reactos/dll/cpl/sysdm/sysdm.rbuild b/reactos/dll/cpl/sysdm/sysdm.rbuild index eb574d67635..40fd8dc0972 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rbuild +++ b/reactos/dll/cpl/sysdm/sysdm.rbuild @@ -20,6 +20,7 @@ shell32 advanced.c computer.c + custclicklink.c environment.c general.c hardprof.c diff --git a/reactos/dll/cpl/sysdm/userprofile.c b/reactos/dll/cpl/sysdm/userprofile.c index c1ed603c542..da0fc8a833b 100644 --- a/reactos/dll/cpl/sysdm/userprofile.c +++ b/reactos/dll/cpl/sysdm/userprofile.c @@ -20,10 +20,17 @@ UserProfileDlgProc(HWND hwndDlg, UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(hwndDlg); + switch(uMsg) { case WM_INITDIALOG: { + HWND hLink = GetDlgItem(hwndDlg, IDC_USERACCOUNT_LINK); + + TextToLink(hLink, + _T("rundll32.exe"), + _T("shell32.dll, Control_RunDLL nusrmgr.cpl")); + MessageBox(hwndDlg, _T("Dialog not yet implemented!"), NULL, 0); } break; From ece02ec90c751b486db02fb11c86c0a5a453361b Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Mon, 18 Sep 2006 22:59:55 +0000 Subject: [PATCH 283/488] Bump to 0.3.1-SVN svn path=/branches/ros-branch-0_3_1/; revision=24207 --- reactos/include/reactos/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/include/reactos/version.h b/reactos/include/reactos/version.h index f5ed7db536d..b72e5327a7d 100644 --- a/reactos/include/reactos/version.h +++ b/reactos/include/reactos/version.h @@ -18,8 +18,8 @@ #define __VERSION_H #define KERNEL_VERSION_MAJOR 0 -#define KERNEL_VERSION_MINOR 4 -#define KERNEL_VERSION_PATCH_LEVEL 0 +#define KERNEL_VERSION_MINOR 3 +#define KERNEL_VERSION_PATCH_LEVEL 1 /* KERNEL_VERSION_BUILD_TYPE is L"SVN", L"RC1", L"RC2" or L"RELEASE" */ #define KERNEL_VERSION_BUILD_TYPE L"SVN" From f8fcca6f0647aa66ed403a1e2dba96a6765efbac Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 18 Sep 2006 23:37:22 +0000 Subject: [PATCH 284/488] Kill some warnings. svn path=/trunk/; revision=24208 --- reactos/tools/mkhive/cmi.c | 2 +- reactos/tools/mkhive/registry.c | 2 +- reactos/tools/mkhive/rtl.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/tools/mkhive/cmi.c b/reactos/tools/mkhive/cmi.c index b84c1d25776..cb79a18c3b5 100644 --- a/reactos/tools/mkhive/cmi.c +++ b/reactos/tools/mkhive/cmi.c @@ -31,7 +31,7 @@ CmpAllocate( IN SIZE_T Size, IN BOOLEAN Paged) { - return malloc(Size); + return (PVOID) malloc(Size); } static VOID diff --git a/reactos/tools/mkhive/registry.c b/reactos/tools/mkhive/registry.c index 9a7aca0243a..fcae34a3602 100644 --- a/reactos/tools/mkhive/registry.c +++ b/reactos/tools/mkhive/registry.c @@ -122,7 +122,7 @@ RegpOpenOrCreateKey( LocalKeyName = (PWSTR)KeyName; for (;;) { - End = wcschr(LocalKeyName, '\\'); + End = (PWSTR) wcschr(LocalKeyName, '\\'); if (End) { KeyString.Buffer = LocalKeyName; diff --git a/reactos/tools/mkhive/rtl.c b/reactos/tools/mkhive/rtl.c index 4ff2be3dd50..08cdeb71deb 100644 --- a/reactos/tools/mkhive/rtl.c +++ b/reactos/tools/mkhive/rtl.c @@ -84,7 +84,7 @@ RtlAnsiStringToUnicodeString( if (AllocateDestinationString) { UniDest->MaximumLength = (USHORT)Length + sizeof(WCHAR); - UniDest->Buffer = malloc(UniDest->MaximumLength); + UniDest->Buffer = (PWSTR) malloc(UniDest->MaximumLength); if (!UniDest->Buffer) return STATUS_NO_MEMORY; } @@ -131,7 +131,7 @@ ExAllocatePool( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes) { - return malloc(NumberOfBytes); + return (PVOID) malloc(NumberOfBytes); } VOID NTAPI From 14d0c5f34afdf2f9e38340d536741baa3dd55e5f Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Tue, 19 Sep 2006 04:25:14 +0000 Subject: [PATCH 285/488] Initialize h_alises with a length 1 array containing a terminating null as specified. Patch by arty. (Fixes ncftp connection) svn path=/trunk/; revision=24209 --- reactos/dll/win32/ws2_32/misc/ns.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/reactos/dll/win32/ws2_32/misc/ns.c b/reactos/dll/win32/ws2_32/misc/ns.c index 9e166e65ef8..f6103b09c14 100644 --- a/reactos/dll/win32/ws2_32/misc/ns.c +++ b/reactos/dll/win32/ws2_32/misc/ns.c @@ -488,7 +488,10 @@ void populate_hostent(struct hostent *he, char* name, DNS_A_DATA addr) name, MAX_HOSTNAME_LEN); - he->h_aliases = 0; + if( !he->h_aliases ) { + he->h_aliases = HeapAlloc(GlobalHeap, 0, sizeof(char *)); + he->h_aliases[0] = 0; + } he->h_addrtype = AF_INET; he->h_length = sizeof(IN_ADDR); //sizeof(struct in_addr); @@ -518,12 +521,20 @@ void free_hostent(struct hostent *he) { if(he) { + char *next = 0; HFREE(he->h_name); - char *next = he->h_aliases[0]; - while(next) { HFREE(next); next++; } - next = he->h_addr_list[0]; - while(next) { HFREE(next); next++; } + if(he->h_aliases) + { + next = he->h_aliases[0]; + while(next) { HFREE(next); next++; } + } + if(he->h_addr_list) + { + next = he->h_addr_list[0]; + while(next) { HFREE(next); next++; } + } HFREE(he->h_addr_list); + HFREE(he->h_aliases); HFREE(he); } } From 59c2e127cc3ec86712872a14b7ecc266d30ac575 Mon Sep 17 00:00:00 2001 From: Brandon Turner Date: Tue, 19 Sep 2006 17:38:10 +0000 Subject: [PATCH 286/488] Add a config.rbuild and set DBG=0 svn path=/branches/ros-branch-0_3_1/; revision=24210 --- reactos/config.rbuild | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 reactos/config.rbuild diff --git a/reactos/config.rbuild b/reactos/config.rbuild new file mode 100644 index 00000000000..f6678d2e32b --- /dev/null +++ b/reactos/config.rbuild @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d0e354f6c147be64206a447adf0c82bd02081248 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 20 Sep 2006 09:27:59 +0000 Subject: [PATCH 287/488] Fix warnings svn path=/trunk/; revision=24211 --- reactos/dll/cpl/sysdm/virtmem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/dll/cpl/sysdm/virtmem.c b/reactos/dll/cpl/sysdm/virtmem.c index ac6acda2f3c..43563f6e737 100644 --- a/reactos/dll/cpl/sysdm/virtmem.c +++ b/reactos/dll/cpl/sysdm/virtmem.c @@ -138,7 +138,7 @@ ParseMemSettings(PVIRTMEM pVirtMem) Item.mask = LVIF_TEXT; Item.iItem = ListView_GetItemCount(pVirtMem->hListView); Item.pszText = szDrive; - ListView_InsertItem(pVirtMem->hListView, &Item); + (void)ListView_InsertItem(pVirtMem->hListView, &Item); /* set a volume label if there is one */ if (GetVolumeInformation(DrivePtr, @@ -158,7 +158,7 @@ ParseMemSettings(PVIRTMEM pVirtMem) Item.iSubItem = 1; Item.pszText = szVol; - ListView_InsertItem(pVirtMem->hListView, &Item); + (void)ListView_InsertItem(pVirtMem->hListView, &Item); } } @@ -170,7 +170,7 @@ ParseMemSettings(PVIRTMEM pVirtMem) Item.iSubItem = 2; Item.pszText = szSize; - ListView_InsertItem(pVirtMem->hListView, &Item); + (void)ListView_InsertItem(pVirtMem->hListView, &Item); } PgCnt++; From 8e90ccee4d3d613333c848fad1b855571ad0d33b Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 20 Sep 2006 09:54:00 +0000 Subject: [PATCH 288/488] Some tchar fixes svn path=/trunk/; revision=24212 --- reactos/dll/cpl/sysdm/precomp.h | 3 ++- reactos/dll/cpl/sysdm/sysdm.rbuild | 5 ++--- reactos/dll/cpl/sysdm/virtmem.c | 14 ++++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/reactos/dll/cpl/sysdm/precomp.h b/reactos/dll/cpl/sysdm/precomp.h index 3b5b31b591d..9a8762c4a95 100644 --- a/reactos/dll/cpl/sysdm/precomp.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -4,9 +4,10 @@ #include #include #include +#include #include #include -#include //shellexecute +#include #include "resource.h" #define NUM_APPLETS (1) diff --git a/reactos/dll/cpl/sysdm/sysdm.rbuild b/reactos/dll/cpl/sysdm/sysdm.rbuild index 40fd8dc0972..0bb5bea4b06 100644 --- a/reactos/dll/cpl/sysdm/sysdm.rbuild +++ b/reactos/dll/cpl/sysdm/sysdm.rbuild @@ -1,8 +1,6 @@ - + . - - 0x600 @@ -31,4 +29,5 @@ userprofile.c virtmem.c sysdm.rc + precomp.h diff --git a/reactos/dll/cpl/sysdm/virtmem.c b/reactos/dll/cpl/sysdm/virtmem.c index 43563f6e737..08da8ae65bc 100644 --- a/reactos/dll/cpl/sysdm/virtmem.c +++ b/reactos/dll/cpl/sysdm/virtmem.c @@ -41,6 +41,8 @@ ReadPageFileSettings(PVIRTMEM pVirtMem) dwDataSize); if (pVirtMem->szPagingFiles != NULL) { + ZeroMemory(pVirtMem->szPagingFiles, + dwDataSize); if(RegQueryValueEx(hkey, _T("PagingFiles"), NULL, @@ -154,7 +156,7 @@ ParseMemSettings(PVIRTMEM pVirtMem) { TCHAR szVol[MAX_PATH + 2]; - wsprintf(szVol, _T("[%s]"), szVolume); + _stprintf(szVol, _T("[%s]"), szVolume); Item.iSubItem = 1; Item.pszText = szVol; @@ -166,7 +168,7 @@ ParseMemSettings(PVIRTMEM pVirtMem) { TCHAR szSize[64]; - wsprintf(szSize, _T("%i - %i"), InitialSize, MaxSize); + _stprintf(szSize, _T("%i - %i"), InitialSize, MaxSize); Item.iSubItem = 2; Item.pszText = szSize; @@ -198,10 +200,10 @@ WritePageFileSettings(PVIRTMEM pVirtMem) { TCHAR szText[256]; - wsprintf(szText, _T("%s\\pagefile.sys %i %i"), - pVirtMem->Pagefile[i].szDrive, - pVirtMem->Pagefile[i].InitialValue, - pVirtMem->Pagefile[i].MaxValue); + _stprintf(szText, _T("%s\\pagefile.sys %i %i"), + pVirtMem->Pagefile[i].szDrive, + pVirtMem->Pagefile[i].InitialValue, + pVirtMem->Pagefile[i].MaxValue); /* Add it to our overall registry string */ lstrcat(szPagingFiles + nPos, szText); From 3138af456a36c43a8f280f46189d2c40f8eda7df Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Wed, 20 Sep 2006 14:38:37 +0000 Subject: [PATCH 289/488] commit rc languages to xml parser for the webservre and standalone. svn path=/trunk/; revision=24213 --- rosapps/devutils/directory.rbuild | 6 + rosapps/devutils/roswebparser/roswebparser.c | 1751 +++++++++++++++++ .../devutils/roswebparser/roswebparser.rbuild | 8 + 3 files changed, 1765 insertions(+) create mode 100644 rosapps/devutils/roswebparser/roswebparser.c create mode 100644 rosapps/devutils/roswebparser/roswebparser.rbuild diff --git a/rosapps/devutils/directory.rbuild b/rosapps/devutils/directory.rbuild index e96f8f60d66..df7afbbccb1 100644 --- a/rosapps/devutils/directory.rbuild +++ b/rosapps/devutils/directory.rbuild @@ -6,6 +6,12 @@ + + + + + + diff --git a/rosapps/devutils/roswebparser/roswebparser.c b/rosapps/devutils/roswebparser/roswebparser.c new file mode 100644 index 00000000000..5b345097f99 --- /dev/null +++ b/rosapps/devutils/roswebparser/roswebparser.c @@ -0,0 +1,1751 @@ +/* + * This is a standalone rc langues to xml parser + * do not use windows or linux specfiy syntax or functions + * use only pure ansi C, this program is also runing on + * linux apachie webserver and being use in ReactOS website + * + * CopyRight 20/9-2006 by Magnus Olsen (magnus@greatlord.com) + * Licen GPL version 2.0 + */ + + +#include +#include +#include +#include + +#define true 1 +#define false 0 + + +int paraser1(char *buf, long buf_size, char * output_text, char * output_resid, char * output_format, char *iso_type); + +void find_str(char asc,char *buf, long *foundPos); +void find_str2(char *asc,char *buf, long *foundPos, char * output_resid, char *output_text ); +void trim(char* buf); +void stringbugs(char *buf, int shift2); +void stringbugs2(char *buf, int shift2); + +void ParserCMD1(char *text, char *output_resid, char *output_text, char *output_format); +void ParserCMD2(char *text, char *output_resid, char *output_text, char *output_format); +void ParserCMD3(char *text, char *output_resid, char *output_text, char *output_format); + +void ParserComment(long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format); +void ParserLang(char *text, char *output_resid, char *output_text, char *output_format); +void ParserString(long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format); +void ParserDialog(char *text, long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format); +void DialogCMDBuild1(char *output_resid, char *output_format, long pos, char * text); +void DialogCMDBuild2(char *output_resid, char *output_format, long pos, char * text); +void DialogCMDBuild3(char *output_resid, char *output_format, long pos, char * text); +void ParserAccelerators(long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format); +void ParserMenu(char *text, long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format); + +/* + return -1 : No file found + return -2 : Fail open file + return -3 : Fail seek + return -4 : Fail get size + return -5 : Fail size of the file is 0 bytes + return -6 : Fail malloc memory + return -7 : Fail to read the file +*/ + +int main(int argc, char * argv[]) +{ + FILE * fp; + char * buffer; + char * output_text; + char * output_resid; + char * output_format; + + long buf_size; + long buf_size_calc = 0; + + if (argc!=3) + { + printf("Help\n"); + printf("%s inputfile iso-type\n\n",argv[0]); + printf("example %s en.rc UTF-8\n\n",argv[0]); + printf("Contry table\n"); + printf("en (English = \n"); + printf("se (Swedish = \n"); + printf("jp (Japanice = \n"); + return -1; + } + + + if ((fp = fopen(argv[1],"rb"))==NULL) + { + printf("Fail open file %s by %s\n",argv[1],argv[0]); + return -2; + } + + + + fseek(fp,0,SEEK_END); + if (ferror(fp) !=0) + { + fclose(fp); + printf("Fail seek\n"); + return -3; + } + buf_size = ftell(fp); + if (ferror(fp) !=0) + { + fclose(fp); + printf("Fail get size\n"); + return -4; + } + + /* + We make sure it is least 4 times + 2K biger + for we can grow around 2-3 times biger + so it better to make safe assume how + much memory we need + */ + + buf_size_calc = (buf_size*4) + 2048; + + fseek(fp,0,SEEK_SET); + if (ferror(fp) !=0) + { + fclose(fp); + printf("Fail seek\n"); + return -3; + } + + if (buf_size==0) + { + fclose(fp); + printf("Fail size of the file is 0 bytes\n"); + return -5; + } + + buffer =(char *)malloc(buf_size_calc); + if (buffer == NULL) + { + fclose(fp); + printf("Fail malloc memory\n"); + return -6; + } + + output_text =(char *)malloc(buf_size_calc); + if (output_text == NULL) + { + free(buffer); + fclose(fp); + printf("Fail malloc memory\n"); + return -6; + } + + output_resid =(char *)malloc(buf_size_calc); + if (output_resid == NULL) + { + free(buffer); + free(output_text); + fclose(fp); + printf("Fail malloc memory\n"); + return -6; + } + + output_format =(char *)malloc(buf_size_calc); + if (output_format == NULL) + { + free(buffer); + free(output_text); + free(output_resid); + fclose(fp); + printf("Fail malloc memory\n"); + return -6; + } + + //fread(buffer,1,buf_size,fp); + fread(buffer,buf_size,1,fp); + if (ferror(fp) !=0) + { + fclose(fp); + printf("Fail to read the file\n"); + return -7; + } + fclose(fp); + + /* Now we can write our parser */ + + paraser1(buffer, buf_size, output_text, output_resid, output_format,argv[2]); + printf ("%s",output_format); + + + if(buffer!=NULL) + free(buffer); + if(output_text!=NULL) + free(output_text); + if(output_resid!=NULL) + free(output_resid); + if(output_format!=NULL) + free(output_format); + + + return 0; +} + +int paraser1(char *buf, long buf_size, char * output_text, char * output_resid, char * output_format, char *iso_type) +{ + char *row; + long foundPos=0; + long foundNextPos=0; + long row_size=0; + long pos=0; + + memset(output_text,0,buf_size); + memset(output_resid,0,buf_size); + memset(output_format,0,buf_size); + + sprintf(output_format,"\n\n",iso_type); + + row = output_text; + while(pos < buf_size) + { + foundPos=0; + foundNextPos=0; + row_size=0; + + /* create a row string so we can easy scan it */ + find_str('\n',&buf[pos],&foundPos); + + if (foundPos !=0) + { + row_size = foundPos - 1; + + /* found a new row */ + strncpy(row, &buf[pos], row_size); + pos+=foundPos; + if (foundPos >=2) + row[row_size -1]=0; + + } + else + { + row_size = buf_size - pos; + + /* no new row found in the buffer */ + strncpy(row, &buf[pos], buf_size - pos); + pos= buf_size; + } + + trim(row); + foundPos=0; + + /* Detect Basic command and send it to own paraser */ + if (*row==0) + continue; + + if (strncmp("/*",row,2)==0) + { + ParserComment(&pos, buf, buf_size, output_text, output_resid, output_format); + continue; + } + + if (strncmp("//",row,2)==0) + { + ParserComment(&pos, buf, buf_size, output_text, output_resid, output_format); + continue; + } + if (strncmp("#",row,1)==0) + { + ParserComment(&pos, buf, buf_size, output_text, output_resid, output_format); + continue; + } + + stringbugs(row,true); + + if (foundPos == 0) + { + find_str2 ("LANGUAGE ",row,&foundPos,output_resid,output_text); + if (foundPos != 0) + { + ParserLang("LANGUAGE", output_resid, output_text, output_format); + continue; + } + } + + if (foundPos == 0) + { + find_str2 ("STRINGTABLE ",row,&foundPos,output_resid,output_text); + if (foundPos != 0) + { + ParserCMD3("STRINGTABLE", output_resid, output_text, output_format); + ParserString(&pos, buf, buf_size, output_text, output_resid, output_format); + continue; + } + } + + if (foundPos == 0) + { + find_str2 (" DIALOGEX ",row,&foundPos,output_resid,output_text); + if (foundPos != 0) + { + ParserCMD2("DIALOGEX", output_resid, output_text, output_format); + ParserDialog("DIALOGEX",&pos, buf, buf_size, output_text, output_resid, output_format); + continue; + } + } + + if (foundPos == 0) + { + find_str2 (" DIALOG ",row,&foundPos,output_resid,output_text); + if (foundPos != 0) + { + ParserCMD2("DIALOG", output_resid, output_text, output_format); + ParserDialog("DIALOG",&pos, buf, buf_size, output_text, output_resid, output_format); + continue; + } + } + + if (foundPos == 0) + { + find_str2 (" ACCELERATORS\0",row,&foundPos,output_resid,output_text); + if (foundPos != 0) + { + ParserCMD1("ACCELERATORS", output_resid, output_text, output_format); + ParserAccelerators(&pos, buf, buf_size, output_text, output_resid, output_format); + continue; + } + } + + if (foundPos == 0) + { + find_str2 (" MENU\0",row,&foundPos,output_resid,output_text); + if (foundPos != 0) + { + ParserCMD1("MENU", output_resid, output_text, output_format); + ParserMenu("MENU",&pos, buf, buf_size, output_text, output_resid, output_format); + continue; + } + } + + + } // end while + sprintf(output_format,"%s\n",output_format); + return false; +} + +/* + ParserCMD + data + input : IDM_MDIFRAME MENU DISCARDABLE LANG LANG_TAG LANG_TAG + input : IDM_MDIFRAME MENU DISCARDABLE + input : IDM_MDIFRAME MENU + input : IDM_MDIFRAME ACCELERATORS DISCARDABLE LANG LANG_TAG LANG_TAG + input : IDM_MDIFRAME ACCELERATORS DISCARDABLE + input : IDM_MDIFRAME ACCELERATORS + + + output : DISCARDABLE + output : DISCARDABLE + output : + output : DISCARDABLE + output : DISCARDABLE + output : + + param : output_resid = rc_name ID + param : output_text = MENU DISCARDABLE LANG LANG_TAG LANG_TAG + param : text = type example MENU + param : output_format = xml data store buffer +*/ + +void ParserCMD1(char *text, char *output_resid, char *output_text, char *output_format) +{ + long le; + + stringbugs(output_resid,false); + stringbugs(output_text,false); + + le = strlen(text); + + if (strlen(output_text) == le) + { + sprintf(output_format,"%s\n \n",output_format,text,text,output_resid); + } + else if (output_text[le]==' ') + { + sprintf(output_format,"%s\n DISCARDABLE\n",output_format,text,text,output_resid); + } + +} + +/* + ParserCMD2 + data + input : IDM_MDIFRAME DIALOG DISCARDABLE 15, 13, 210, 63 LANG LANG_TAG LANG_TAG + input : IDM_MDIFRAME DIALOG DISCARDABLE 15, 13, 210, 63 + input : IDM_MDIFRAME DIALOGEX DISCARDABLE 15, 13, 210, 63 LANG LANG_TAG LANG_TAG + input : IDM_MDIFRAME DIALOGEX DISCARDABLE 15, 13, 210, 63 + + + output : DISCARDABLE + output : + output : DISCARDABLE + output : + + + param : output_resid = rc_name ID + param : output_text = DIALOG DISCARDABLE 15, 13, 210, 63 LANG LANG_TAG LANG_TAG + param : text = type example DIALOG + param : output_format = xml data store buffer + +*/ + +void ParserCMD2(char *text, char *output_resid, char *output_text, char *output_format) +{ + long le; + long flag = 0; + + stringbugs(output_resid,false); + stringbugs(output_text,false); + + le=strlen(text); + + sprintf(output_format,"%s\n \n",output_format,output_resid,output_text); + else + sprintf(output_format,"%swidth=\"%s\" height=\"%s\">DISCARDABLE\n",output_format,output_resid,output_text); +} + +/* + ParserCMD3 + data + input : STRINGTABLE DISCARDABLE LANG LANG_TAG LANG_TAG + input : STRINGTABLE DISCARDABLE LANG + input : STRINGTABLE LANG LANG_TAG LANG_TAG + input : STRINGTABLE + + + output : DISCARDABLE + output : DISCARDABLE + output : + output : + + + param : output_resid = empty + param : output_text = DIALOG DISCARDABLE 15, 13, 210, 63 LANG LANG_TAG LANG_TAG + param : text = type example DIALOG + param : output_format = xml data store buffer + +*/ +void ParserCMD3(char *text, char *output_resid, char *output_text, char *output_format) +{ + long foundPos=0; + + stringbugs(output_resid,false); + stringbugs(output_text,false); + + find_str2 (" ",output_text,&foundPos,output_resid,output_text); + trim(output_resid); + trim(output_text); + + if(strncmp("STRINGTABLE",output_text,11)) + sprintf(output_format,"%s\n DISCARDABLE\n",output_format,output_text,output_resid); + else + sprintf(output_format,"%s\n \n",output_format,output_resid,output_text); + +} +/* + ParserLang + data + input : LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + input : LANGUAGE LANG_ENGLISH SUBLANG_ENGLISH_US + output : lang + output : lang + + param : output_resid = not in use + param : output_text = LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + param : text = type example LANGUAGE + param : output_format = xml data store buffer +*/ + +void ParserLang(char *text, char *output_resid, char *output_text, char *output_format) +{ + long foundPos=0; + + stringbugs(output_resid,false); + stringbugs(output_text,false); + + sprintf(output_text,"%s",&output_text[strlen(text)+1]); + + /* split the lang into two string */ + find_str2 (" ",output_text,&foundPos,output_resid,output_text); + trim(output_resid); + trim(output_text); + sprintf(output_format,"%s\n %s\n\n",output_format,text,text,output_text,output_resid); +} + + +/* + ParserComment + data + input : / * sadasdas asdasd asdas ... * / + output : + + input : / * sadasdas asdasd asdas ... * / + output : + + input : #if x + output : + + input : // hi + output : + + param : pos = current buf position + param : buf = read in buffer from file rc + param : buf_size = buf max size + param : output_text = using internal instead alloc more memory + param : output_resid = using internal instead alloc more memory + param : output_format = xml data store buffer +*/ + +void ParserComment(long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format) +{ + long foundPos=0; + long foundNextPos=0; + long row_size=0; + char *row = output_text; + + + row_size = strlen(row); + if (strncmp("//",&row[0],2)==0) + { + sprintf(output_format,"%s\n \n\n",output_format,row); + return; + } + if (strncmp("#",&row[0],1)==0) + { + sprintf(output_format,"%s\n \n\n",output_format,row); + return; + } + + for (foundNextPos=0;foundNextPos\n \n\n",output_format,row); + return; + } + + } + + + sprintf(output_format,"%s\n =2) + { + row[row_size -1]=0; + } + + } + else + { + row_size = buf_size - *pos; + + /* no new row found in the buffer */ + strncpy(row, &buf[*pos], buf_size - *pos); + *pos= buf_size; + } + + /* Search now after end of comment */ + row_size=strlen(row); + for (foundNextPos=0;foundNextPos\n\n",output_format,row); + return; + } + } + sprintf(output_format,"%s%s\n",output_format,row); + } + +} + +/* + ParserAccelerators + data + input : BEGIN + input : "^A", CMD_SELECT_ALL + input : END + + output : + output : + output : + + param : pos = current buf position + param : buf = read in buffer from file rc + param : buf_size = buf max size + param : output_text = using internal instead alloc more memory + param : output_resid = using internal instead alloc more memory + param : output_format = xml data store buffer +*/ +void ParserAccelerators(long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format) +{ + long foundPos=0; + long foundNextPos=0; + long row_size=0; + char *row = output_text; + int start=false; + long le; + + while(*pos < buf_size) + { + foundPos=0; + row_size=0; + + /* create a row string so we can easy scan it */ + find_str('\n',&buf[*pos],&foundPos); + if (foundPos !=0) + { + row_size = foundPos - 1; + + /* found a new row */ + strncpy(row, &buf[*pos], foundPos); + *pos+=foundPos; + if (foundPos >=2) + { + row[row_size -1]=0; + } + + } + else + { + row_size = buf_size - *pos; + + /* no new row found in the buffer */ + strncpy(row, &buf[*pos], buf_size - *pos); + *pos= buf_size; + } + + stringbugs(row,true); + if (start == false) + { + if ((strcmp(row,"BEGIN")==0) || (strcmp(row,"{")==0)) + { + start=true; + sprintf(output_format,"%s \n",output_format); + + } + continue; + } + + if ((strcmp(row,"END")==0) || (strcmp(row,"}")==0)) + { + sprintf(output_format,"%s \n\n",output_format); + + *output_resid = '\0'; + break; + } + + foundPos=0; + foundNextPos=0; + find_str('"',row,&foundPos); + find_str('"',&row[foundPos],&foundNextPos); + + if ((foundPos!=0) && (foundNextPos!=0)) + { + + sprintf(output_format,"%s \n",output_format,row); + } + } +} + +/* + ParserString + data + input : BEGIN + input : IDS_HINT_BLANK "text" + input : END + + output : + output : text + output : + + param : pos = current buf position + param : buf = read in buffer from file rc + param : buf_size = buf max size + param : output_text = using internal instead alloc more memory + param : output_resid = using internal instead alloc more memory + param : output_format = xml data store buffer +*/ +void ParserString(long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format) +{ + long foundPos=0; + long row_size=0; + char *row = output_text; + int start=false; + + while(*pos < buf_size) + { + foundPos=0; + row_size=0; + + /* create a row string so we can easy scan it */ + find_str('\n',&buf[*pos],&foundPos); + + if (foundPos !=0) + { + row_size = foundPos - 1; + + /* found a new row */ + strncpy(row, &buf[*pos], foundPos); + *pos+=foundPos; + if (foundPos >=2) + { + row[row_size -1]=0; + } + + } + else + { + row_size = buf_size - *pos; + + /* no new row found in the buffer */ + strncpy(row, &buf[*pos], buf_size - *pos); + *pos= buf_size; + } + + stringbugs(row,true); + + + if (start == false) + { + if ((strcmp(row,"BEGIN")==0) || (strcmp(row,"{")==0)) + { + + start=true; + sprintf(output_format,"%s \n",output_format); + } + continue; + } + + if ((strcmp(row,"END")==0) || (strcmp(row,"}")==0)) + { + sprintf(output_format,"%s \n\n",output_format); + + *output_resid = '\0'; + break; + } + + + + /* the split code here */ + foundPos=0; + find_str2 (" ",row,&foundPos,output_resid,output_text); + + if (foundPos != 0) + { + trim(output_text); + trim(output_resid); + + if (*output_resid!='\0') + sprintf(output_format,"%s \n",output_format,output_resid,output_text); + else + sprintf(output_format,"%s \n",output_format,output_resid); + } + + } +} + +/* + ParserDialog + data + + input : BEGIN + output : + output : + + input : END + output : + output : + + input : { + output : + output : + + input : } + output : + output : + + input : FONT 8, "MS Shell Dlg" + output : + + input : FONT 8, "MS Shell Dlg", 0, 0, 0x1 + output : 0 0 0x1 + + input : CONTROL "",101,"Static",SS_SIMPLE | SS_NOPREFIX,3,6,150,10 + output : + + + Builder1 + input : DEFPUSHBUTTON "&OK",1,158,6,47,14 xx + input : PUSHBUTTON "&Cancel",2,158,23,47,14 xx + input : LTEXT "&Tooltip Text:",IDC_LABEL1,7,44,40,8 xx + input : GROUPBOX "&Display Mode",IDC_LABEL4,7,96,157,28 xx + input : ICON "",IDC_PICTURE,173,101,21,20 xx + + input : EDITTEXT 201,3,29,134,12,ES_AUTOHSCROLL + input : LISTBOX IDC_LIST, 4, 16, 104, 46, WS_TABSTOP + input : COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + output : + output : + + output : + output : + + builder2 + input : CAPTION "Execute" + input : EXSTYLE WS_EX_APPWINDOW + input : STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU + + output : DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU + + param : pos = current buf position + param : buf = read in buffer from file rc + param : buf_size = buf max size + param : output_text = using internal instead alloc more memory + param : output_resid = using internal instead alloc more memory + param : output_format = xml data store buffer +*/ +void ParserDialog(char *text, long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format) +{ + long foundPos=0; + long foundNextPos=0; + long row_size=0; + char *row = output_text; + long commandfound=0; + long le; + + *output_resid='\0'; + le=0; + + while(*pos < buf_size) + { + foundPos=0; + row_size=0; + + /* create a row string so we can easy scan it */ + find_str('\n',&buf[*pos],&foundPos); + if (foundPos !=0) + { + row_size = foundPos - 1; + + /* found a new row */ + strncpy(row, &buf[*pos], foundPos); + *pos+=foundPos; + if (foundPos >=2) + { + row[row_size -1]=0; + } + + } + else + { + row_size = buf_size - *pos; + + /* no new row found in the buffer */ + strncpy(row, &buf[*pos], buf_size - *pos); + *pos= buf_size; + } + + //stringbugs(row,true); + trim(row); + + if ((strcmp(row,"BEGIN")==0) || (strcmp(row,"{")==0)) + commandfound=1; + if ((strcmp(row,"END")==0) || (strcmp(row,"}")==0)) + commandfound=2; + + if (strncmp("STYLE ",row,6)==0) + commandfound=3; + if (strncmp("CAPTION ",row,8)==0) + commandfound=3; + if (strncmp("FONT ",row,5)==0) + commandfound=3; + if (strncmp("CONTROL ",row,8)==0) + commandfound=3; + if (strncmp("EDITTEXT ",row,9)==0) + commandfound=3; + if (strncmp("DEFPUSHBUTTON ",row,14)==0) + commandfound=3; + if (strncmp("PUSHBUTTON ",row,11)==0) + commandfound=3; + if (strncmp("LTEXT ",row,6)==0) + commandfound=3; + if (strncmp("GROUPBOX ",row,9)==0) + commandfound=3; + if (strncmp("ICON ",row,5)==0) + commandfound=3; + if (strncmp("EXSTYLE ",row,8)==0) + commandfound=3; + if (strncmp(row,"LISTBOX ",8)==0) + commandfound=3; + if (strncmp(row,"COMBOBOX ",9)==0) + commandfound=3; + + if ((*output_resid!=0) && (commandfound!=0)) + { + /* Builder 1*/ + if (strncmp(output_resid,"LTEXT ",6)==0) + DialogCMDBuild1(output_resid, output_format, 5, "LTEXT"); + if (strncmp(output_resid,"GROUPBOX ",9)==0) + DialogCMDBuild1(output_resid, output_format, 8, "GROUPBOX"); + if (strncmp(output_resid,"DEFPUSHBUTTON ",14)==0) + DialogCMDBuild1(output_resid, output_format, 13, "DEFPUSHBUTTON"); + if (strncmp(output_resid,"PUSHBUTTON ",11)==0) + DialogCMDBuild1(output_resid, output_format, 10, "PUSHBUTTON"); + if (strncmp("ICON ",output_resid,5)==0) + DialogCMDBuild1(output_resid, output_format, 4, "ICON"); + if (strncmp("EDITTEXT ",output_resid,9)==0) + DialogCMDBuild1(output_resid, output_format, 8, "EDITTEXT"); + if (strncmp("LISTBOX ",output_resid,8)==0) + DialogCMDBuild1(output_resid, output_format, 7, "LISTBOX"); + if (strncmp("COMBOBOX ",output_resid,9)==0) + DialogCMDBuild1(output_resid, output_format, 8, "COMBOBOX"); + + /* Builder 2*/ + if (strncmp("STYLE ",output_resid,6)==0) + DialogCMDBuild2(output_resid, output_format, 5, "STYLE"); + if (strncmp("EXSTYLE ",output_resid,8)==0) + DialogCMDBuild2(output_resid, output_format, 7, "EXSTYLE"); + if (strncmp("CAPTION ",output_resid,8)==0) + DialogCMDBuild2(output_resid, output_format, 7, "CAPTION"); + if (strncmp("CONTROL ",output_resid,8)==0) + DialogCMDBuild3(output_resid, output_format, 7, "CONTROL"); + + /* no builder */ + if (strncmp(output_resid,"FONT ",5)==0) + { + stringbugs(output_resid,true); + /* FONT */ + sprintf(output_resid,"%s",&output_resid[5]); + trim(output_resid); + sprintf(output_format,"%s \n",output_format); + } + else + { + sprintf(output_format,"%s\">%s\n",output_format,&output_resid[foundPos]); + } + + *output_resid=0; + } + + *output_resid='\0'; + } + + if (commandfound==1) + { + sprintf(output_format,"%s \n",output_format,text); + } + if (commandfound==2) + { + sprintf(output_format,"%s \n\n",output_format,text); + break; + } + + sprintf(output_resid,"%s%s",output_resid,row); + commandfound=0; + } + +} +////////////////////////// +/* + ParserDialog + data + + input : BEGIN + output : + output : + + input : END + output : + output : + + input : { + output : + output : + + input : } + output : + output : + + param : pos = current buf position + param : buf = read in buffer from file rc + param : buf_size = buf max size + param : output_text = using internal instead alloc more memory + param : output_resid = using internal instead alloc more memory + param : output_format = xml data store buffer +*/ +void ParserMenu(char *text, long *pos, char *buf, long buf_size, char * output_text, char * output_resid, char * output_format) +{ + long foundPos=0; + long foundNextPos=0; + long row_size=0; + char *row = output_text; + long commandfound=0; + long le; + long count=0; + + *output_resid='\0'; + le=0; + + while(*pos < buf_size) + { + foundPos=0; + row_size=0; + + /* create a row string so we can easy scan it */ + find_str('\n',&buf[*pos],&foundPos); + if (foundPos !=0) + { + row_size = foundPos - 1; + + /* found a new row */ + strncpy(row, &buf[*pos], foundPos); + *pos+=foundPos; + if (foundPos >=2) + { + row[row_size -1]=0; + } + + } + else + { + row_size = buf_size - *pos; + + /* no new row found in the buffer */ + strncpy(row, &buf[*pos], buf_size - *pos); + *pos= buf_size; + } + + //stringbugs(row,true); + stringbugs2(row,true); + + if ((strcmp(row,"BEGIN")==0) || (strcmp(row,"{")==0)) + commandfound=1; + if ((strcmp(row,"END")==0) || (strcmp(row,"}")==0)) + commandfound=2; + + if (strncmp("POPUP ",row,6)==0) + commandfound=3; + if (strncmp("MENUITEM ",row,8)==0) + commandfound=3; + + + if ((*output_resid!=0) && (commandfound!=0)) + { + if (strncmp(output_resid,"POPUP ",6)==0) + { + sprintf(output_resid,"%s",&output_resid[5]); + trim(output_resid); + sprintf(output_format,"%s\n",output_format,output_resid); + *output_resid='\0'; + } + + if (strncmp(output_resid,"MENUITEM ",9)==0) + { + sprintf(output_resid,"%s",&output_resid[8]); + trim(output_resid); + if (strcmp(output_resid,"SEPARATOR")==0) + { + sprintf(output_format,"%s\n",output_format); + *output_resid='\0'; + } + else + { + foundPos=0; + foundNextPos=0; + find_str('"',output_resid,&foundPos); + find_str('"',&output_resid[foundPos],&foundNextPos); + + stringbugs(&output_resid[foundPos+foundNextPos],true); + + if ((foundPos+foundNextPos)==0) + { + sprintf(output_format,"%s\n",output_format,&output_resid[foundPos+foundNextPos]); + } + else + { + sprintf(output_format,"%s",output_format,&output_resid[foundPos+foundNextPos]); + + output_resid[foundPos+foundNextPos]='\0'; + trim(output_resid); + + sprintf(output_format,"%s\n",output_format,output_resid); + } + + + + *output_resid='\0'; + } + } + + + + *output_resid='\0'; + } + + if (commandfound==1) + { + count++; + if (count==1) + sprintf(output_format,"%s\n",output_format,text); + else + sprintf(output_format,"%s\n",output_format); + + *output_resid='\0'; + } + if (commandfound==2) + { + count--; + *output_resid='\0'; + + if (count<1) + sprintf(output_format,"%s\n",output_format,text); + else + sprintf(output_format,"%s\n",output_format); + + if (count<1) + { + sprintf(output_format,"%s\n",output_format); + break; + } + } + + sprintf(output_resid,"%s%s",output_resid,row); + commandfound=0; + } + +} + +void stringbugs(char *buf, int shift2) +{ + long foundPos=0; + long foundNextPos=0; + long t=0; + + /* remove , */ + if (shift2== false) + { + for (t=0;t0) + { + + if (isspace(buf[le-1])!=0) + { + buf[le-1]=0; + le=strlen(buf); + } + else + { + break; + } + } + + le=strlen(buf); + while(le>0) + { + if (isspace(buf[0])!=0) + { + strncpy(&buf[0],&buf[1],le-1); + buf[le-1]=0; + le=strlen(buf); + } + else + { + break; + } + } +} +void find_str(char asc,char *buf, long *foundPos) +{ + int t; + size_t le; + + le=strlen(buf); + + for (t=0;t\n",output_format,output_resid); + else + sprintf(output_format,"%s\">\n",output_format); + + *output_resid='\0'; +} + + +void DialogCMDBuild2(char *output_resid, char *output_format, long pos, char * text) +{ + long le; + + stringbugs(output_resid,true); + sprintf(output_resid,"%s",&output_resid[pos]); + trim(output_resid); + + le = strlen(output_resid); + if (*output_resid=='"') + *output_resid=' '; + if (output_resid[le-1]=='"') + output_resid[le-1]=' '; + + trim(output_resid); + sprintf(output_format,"%s \n",output_format,text,output_resid); + *output_resid='\0'; +} + +// input : CONTROL "",101,"Static",SS_SIMPLE | SS_NOPREFIX,3,6,150,10 +void DialogCMDBuild3(char *output_resid, char *output_format, long pos, char * text) +{ + long foundPos=0; + long foundNextPos=0; + long le; + long count=0; + long save1; + long save2; + + sprintf(output_resid,"%s",&output_resid[pos]); + trim(output_resid); + + find_str('"',output_resid,&foundPos); + find_str('"',&output_resid[foundPos],&foundNextPos); + + save1=foundPos; + save2=foundNextPos; + + sprintf(output_format,"%s \n",output_format,output_resid); + else + sprintf(output_format,"%s\">\n",output_format); + + *output_resid='\0'; +} + diff --git a/rosapps/devutils/roswebparser/roswebparser.rbuild b/rosapps/devutils/roswebparser/roswebparser.rbuild new file mode 100644 index 00000000000..21af3157f59 --- /dev/null +++ b/rosapps/devutils/roswebparser/roswebparser.rbuild @@ -0,0 +1,8 @@ + + . + 0x0501 + 0x0501 + + kernel32 + roswebparser.c + From 9907e96a49ad01a41ae92463d408fa2330459df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 20 Sep 2006 14:46:21 +0000 Subject: [PATCH 290/488] Save correct boot resources lists in registry svn path=/trunk/; revision=24214 --- .../boot/freeldr/freeldr/arch/i386/hardware.c | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c index ad37d57fbe2..fdfa068d1e7 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c @@ -348,6 +348,8 @@ DetectPnpBios(FRLDRHKEY SystemKey, ULONG *BusNumber) /* Initialize resource descriptor */ FullResourceDescriptor->InterfaceType = Internal; FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = 1; FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific; @@ -442,6 +444,8 @@ SetHarddiskConfigurationData(FRLDRHKEY DiskKey, memset(FullResourceDescriptor, 0, Size); FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined; FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = 1; FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific; @@ -630,6 +634,8 @@ DetectBiosDisks(FRLDRHKEY SystemKey, memset(FullResourceDescriptor, 0, Size); FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined; FullResourceDescriptor->BusNumber = -1; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = 1; FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific; @@ -798,6 +804,8 @@ DetectBiosFloppyPeripheral(FRLDRHKEY ControllerKey) memset(FullResourceDescriptor, 0, Size); FullResourceDescriptor->InterfaceType = Isa; FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = 1; PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0]; @@ -898,6 +906,8 @@ DetectBiosFloppyController(FRLDRHKEY SystemKey, /* Initialize resource descriptor */ FullResourceDescriptor->InterfaceType = Isa; FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = 3; /* Set IO Port */ @@ -914,7 +924,7 @@ DetectBiosFloppyController(FRLDRHKEY SystemKey, PartialDescriptor->Type = CmResourceTypeInterrupt; PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; - PartialDescriptor->u.Interrupt.Level = 6; + PartialDescriptor->u.Interrupt.Level = 0; PartialDescriptor->u.Interrupt.Vector = 6; PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF; @@ -1269,9 +1279,9 @@ DetectSerialPointerPeripheral(FRLDRHKEY ControllerKey, memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR)); FullResourceDescriptor.InterfaceType = Isa; FullResourceDescriptor.BusNumber = 0; - FullResourceDescriptor.PartialResourceList.Count = 0; FullResourceDescriptor.PartialResourceList.Version = 1; FullResourceDescriptor.PartialResourceList.Revision = 1; + FullResourceDescriptor.PartialResourceList.Count = 0; Error = RegSetValue(PeripheralKey, L"Configuration Data", @@ -1370,6 +1380,8 @@ DetectSerialPorts(FRLDRHKEY BusKey) /* Initialize resource descriptor */ FullResourceDescriptor->InterfaceType = Isa; FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = 3; /* Set IO Port */ @@ -1386,7 +1398,7 @@ DetectSerialPorts(FRLDRHKEY BusKey) PartialDescriptor->Type = CmResourceTypeInterrupt; PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; - PartialDescriptor->u.Interrupt.Level = Irq[i]; + PartialDescriptor->u.Interrupt.Level = 0; PartialDescriptor->u.Interrupt.Vector = Irq[i]; PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF; @@ -1514,6 +1526,8 @@ DetectParallelPorts(FRLDRHKEY BusKey) /* Initialize resource descriptor */ FullResourceDescriptor->InterfaceType = Isa; FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = (Irq[i] != (ULONG)-1) ? 2 : 1; /* Set IO Port */ @@ -1532,7 +1546,7 @@ DetectParallelPorts(FRLDRHKEY BusKey) PartialDescriptor->Type = CmResourceTypeInterrupt; PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; - PartialDescriptor->u.Interrupt.Level = Irq[i]; + PartialDescriptor->u.Interrupt.Level = 0; PartialDescriptor->u.Interrupt.Vector = Irq[i]; PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF; } @@ -1682,6 +1696,8 @@ DetectKeyboardPeripheral(FRLDRHKEY ControllerKey) memset(FullResourceDescriptor, 0, Size); FullResourceDescriptor->InterfaceType = Isa; FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = 1; PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0]; @@ -1689,7 +1705,7 @@ DetectKeyboardPeripheral(FRLDRHKEY ControllerKey) PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_KEYBOARD_DEVICE_DATA); - KeyboardData = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR)); + KeyboardData = (PCM_KEYBOARD_DEVICE_DATA)(PartialDescriptor + 1); KeyboardData->Version = 1; KeyboardData->Revision = 1; KeyboardData->Type = 4; @@ -1767,6 +1783,8 @@ DetectKeyboardController(FRLDRHKEY BusKey) memset(FullResourceDescriptor, 0, Size); FullResourceDescriptor->InterfaceType = Isa; FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = 3; /* Set Interrupt */ @@ -1774,7 +1792,7 @@ DetectKeyboardController(FRLDRHKEY BusKey) PartialDescriptor->Type = CmResourceTypeInterrupt; PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; - PartialDescriptor->u.Interrupt.Level = 1; + PartialDescriptor->u.Interrupt.Level = 0; PartialDescriptor->u.Interrupt.Vector = 1; PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF; @@ -1954,13 +1972,15 @@ DetectPS2Mouse(FRLDRHKEY BusKey) /* Initialize resource descriptor */ FullResourceDescriptor.InterfaceType = Isa; FullResourceDescriptor.BusNumber = 0; + FullResourceDescriptor.PartialResourceList.Version = 1; + FullResourceDescriptor.PartialResourceList.Revision = 1; FullResourceDescriptor.PartialResourceList.Count = 1; /* Set Interrupt */ FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeInterrupt; FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined; FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED; - FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Level = 12; + FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Level = 0; FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector = 12; FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF; @@ -2004,6 +2024,8 @@ DetectPS2Mouse(FRLDRHKEY BusKey) memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR)); FullResourceDescriptor.InterfaceType = Isa; FullResourceDescriptor.BusNumber = 0; + FullResourceDescriptor.PartialResourceList.Version = 1; + FullResourceDescriptor.PartialResourceList.Revision = 1; FullResourceDescriptor.PartialResourceList.Count = 0; /* Set 'Configuration Data' value */ @@ -2165,6 +2187,8 @@ DetectIsaBios(FRLDRHKEY SystemKey, ULONG *BusNumber) memset(FullResourceDescriptor, 0, Size); FullResourceDescriptor->InterfaceType = Isa; FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; FullResourceDescriptor->PartialResourceList.Count = 0; /* Set 'Configuration Data' value */ From b9ade034f9ad8bdeb8fe8d73bfaf40a5137eb439 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Wed, 20 Sep 2006 15:00:17 +0000 Subject: [PATCH 291/488] Fix booting with /DEBUGPORT=GDB and Pice too. svn path=/trunk/; revision=24215 --- reactos/ntoskrnl/kd/kdinit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/kd/kdinit.c b/reactos/ntoskrnl/kd/kdinit.c index 91112cf7064..52ee7f5992d 100644 --- a/reactos/ntoskrnl/kd/kdinit.c +++ b/reactos/ntoskrnl/kd/kdinit.c @@ -57,6 +57,7 @@ KdpGetWrapperDebugMode(PCHAR Currentp2, /* Enable Debugging */ KdDebuggerEnabled = TRUE; + KdDebuggerNotPresent = FALSE; WrapperInitRoutine = KdpGdbStubInit; } @@ -69,6 +70,7 @@ KdpGetWrapperDebugMode(PCHAR Currentp2, /* Enable Debugging */ KdDebuggerEnabled = TRUE; + KdDebuggerNotPresent = FALSE; } #ifdef KDBG @@ -136,7 +138,7 @@ KdpCallInitRoutine(ULONG BootPhase) { PLIST_ENTRY CurrentEntry; PKD_DISPATCH_TABLE CurrentTable; - + /* Call the registered handlers */ CurrentEntry = KdProviders.Flink; while (CurrentEntry != &KdProviders) From 364cdf195167d3443b6d2782c9edf1afeb31e8a1 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 20 Sep 2006 16:54:54 +0000 Subject: [PATCH 292/488] - Add ability to allocate either "low" or "high" pages - Don't display a warning to user if allocating memory at certain address fails - Change debug prints so they tell in which function allocation failed - Include RTL and LDR headers from NDK, so that it's possible to use functions from RTL in FreeLdr in future svn path=/trunk/; revision=24216 --- .../boot/freeldr/freeldr/include/freeldr.h | 3 ++ reactos/boot/freeldr/freeldr/include/mm.h | 8 ++- reactos/boot/freeldr/freeldr/mm/meminit.c | 52 ++++++++++++++----- reactos/boot/freeldr/freeldr/mm/mm.c | 32 ++++++++---- 4 files changed, 72 insertions(+), 23 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/include/freeldr.h b/reactos/boot/freeldr/freeldr/include/freeldr.h index 5aa3e5cbc6c..a094987de39 100644 --- a/reactos/boot/freeldr/freeldr/include/freeldr.h +++ b/reactos/boot/freeldr/freeldr/include/freeldr.h @@ -43,6 +43,9 @@ #include #include #include +/* NDK, needed for ReactOS/Windows loaders */ +#include +#include #include #include #include diff --git a/reactos/boot/freeldr/freeldr/include/mm.h b/reactos/boot/freeldr/freeldr/include/mm.h index f9e8f05d93e..d3b4369762a 100644 --- a/reactos/boot/freeldr/freeldr/include/mm.h +++ b/reactos/boot/freeldr/freeldr/include/mm.h @@ -38,6 +38,11 @@ typedef struct #if defined(__i386__) || defined(_PPC_) #define MM_PAGE_SIZE 4096 +#define MM_PAGE_MASK 0xFFF +#define MM_PAGE_SHIFT 12 + +#define MM_SIZE_TO_PAGES(a) \ + ( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) ) #endif // defined __i386__ or _PPC_ @@ -74,7 +79,7 @@ VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_ME VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, ULONG PageAllocated); // Marks the specified pages as allocated or free in the lookup table VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount); // Allocates the specified pages in the lookup table ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount); // Returns the number of free pages in the lookup table -ULONG MmFindAvailablePagesFromEnd(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded); // Returns the page number of the first available page range from the end of memory +ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, BOOLEAN FromEnd); // Returns the page number of the first available page range from the beginning or end of memory ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, ULONG LastPage); // Returns the page number of the first available page range before the specified page VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount); // Removes entries in the memory map that describe memory above 4G VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount); // Sets the LastFreePageHint to the last usable page of memory @@ -87,6 +92,7 @@ ULONG GetSystemMemorySize(VOID); // Returns the amount of total memory i BOOLEAN MmInitializeMemoryManager(VOID); PVOID MmAllocateMemory(ULONG MemorySize); VOID MmFreeMemory(PVOID MemoryPointer); +VOID MmChangeAllocationPolicy(BOOLEAN PolicyAllocatePagesFromEnd); //PVOID MmAllocateLowMemory(ULONG MemorySize); //VOID MmFreeLowMemory(PVOID MemoryPointer); PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress); diff --git a/reactos/boot/freeldr/freeldr/mm/meminit.c b/reactos/boot/freeldr/freeldr/mm/meminit.c index 7c60ff64707..8f3668aa150 100644 --- a/reactos/boot/freeldr/freeldr/mm/meminit.c +++ b/reactos/boot/freeldr/freeldr/mm/meminit.c @@ -311,7 +311,7 @@ ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount) return FreePageCount; } -ULONG MmFindAvailablePagesFromEnd(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded) +ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, BOOLEAN FromEnd) { PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable; ULONG AvailablePagesSoFar; @@ -323,21 +323,47 @@ ULONG MmFindAvailablePagesFromEnd(PVOID PageLookupTable, ULONG TotalPageCount, U } AvailablePagesSoFar = 0; - for (Index=LastFreePageHint-1; Index>0; Index--) + if (FromEnd) { - if (RealPageLookupTable[Index].PageAllocated != 0) + /* Allocate "high" (from end) pages */ + for (Index=LastFreePageHint-1; Index>0; Index--) { - AvailablePagesSoFar = 0; - continue; - } - else - { - AvailablePagesSoFar++; - } + if (RealPageLookupTable[Index].PageAllocated != 0) + { + AvailablePagesSoFar = 0; + continue; + } + else + { + AvailablePagesSoFar++; + } - if (AvailablePagesSoFar >= PagesNeeded) + if (AvailablePagesSoFar >= PagesNeeded) + { + return Index; + } + } + } + else + { + DbgPrint((DPRINT_MEMORY, "Alloc low memory, LastFreePageHint %d, TPC %d\n", LastFreePageHint, TotalPageCount)); + /* Allocate "low" pages */ + for (Index=1; Index < LastFreePageHint; Index++) { - return Index; + if (RealPageLookupTable[Index].PageAllocated != 0) + { + AvailablePagesSoFar = 0; + continue; + } + else + { + AvailablePagesSoFar++; + } + + if (AvailablePagesSoFar >= PagesNeeded) + { + return Index; + } } } @@ -352,7 +378,7 @@ ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount if (LastPage > TotalPageCount) { - return MmFindAvailablePagesFromEnd(PageLookupTable, TotalPageCount, PagesNeeded); + return MmFindAvailablePages(PageLookupTable, TotalPageCount, PagesNeeded, TRUE); } AvailablePagesSoFar = 0; diff --git a/reactos/boot/freeldr/freeldr/mm/mm.c b/reactos/boot/freeldr/freeldr/mm/mm.c index 31513936882..928fe94e566 100644 --- a/reactos/boot/freeldr/freeldr/mm/mm.c +++ b/reactos/boot/freeldr/freeldr/mm/mm.c @@ -52,6 +52,13 @@ VOID MemAllocTest(VOID); static PVOID SubAllocationPage = NULL; static unsigned SubAllocationRest = 0; +BOOLEAN AllocateFromEnd = TRUE; + +VOID MmChangeAllocationPolicy(BOOLEAN PolicyAllocatePagesFromEnd) +{ + AllocateFromEnd = PolicyAllocatePagesFromEnd; +} + PVOID MmAllocateMemory(ULONG MemorySize) { ULONG PagesNeeded; @@ -81,16 +88,16 @@ PVOID MmAllocateMemory(ULONG MemorySize) // then return NULL if (FreePagesInLookupTable < PagesNeeded) { - DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); + DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); UiMessageBoxCritical("Memory allocation failed: out of memory."); return NULL; } - FirstFreePageFromEnd = MmFindAvailablePagesFromEnd(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded); + FirstFreePageFromEnd = MmFindAvailablePages(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded, AllocateFromEnd); - if (FirstFreePageFromEnd == 0) + if (FirstFreePageFromEnd == (ULONG)-1) { - DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); + DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); UiMessageBoxCritical("Memory allocation failed: out of memory."); return NULL; } @@ -142,15 +149,22 @@ PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress) // then return NULL if (FreePagesInLookupTable < PagesNeeded) { - DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); + DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemoryAtAddress(). " + "Not enough free memory to allocate %d bytes (requesting %d pages but have only %d). " + "AllocationCount: %d\n", MemorySize, PagesNeeded, FreePagesInLookupTable, AllocationCount)); UiMessageBoxCritical("Memory allocation failed: out of memory."); return NULL; } if (MmAreMemoryPagesAvailable(PageLookupTableAddress, TotalPagesInLookupTable, DesiredAddress, PagesNeeded) == FALSE) { - DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); - UiMessageBoxCritical("Memory allocation failed: out of memory."); + DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateMemoryAtAddress(). " + "Not enough free memory to allocate %d bytes at address %p. AllocationCount: %d\n", + MemorySize, DesiredAddress, AllocationCount)); + + // Don't tell this to user since caller should try to alloc this memory + // at a different address + //UiMessageBoxCritical("Memory allocation failed: out of memory."); return NULL; } @@ -195,7 +209,7 @@ PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress // then return NULL if (FreePagesInLookupTable < PagesNeeded) { - DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); + DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); UiMessageBoxCritical("Memory allocation failed: out of memory."); return NULL; } @@ -204,7 +218,7 @@ PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress if (FirstFreePageFromEnd == 0) { - DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); + DbgPrint((DPRINT_MEMORY, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount)); UiMessageBoxCritical("Memory allocation failed: out of memory."); return NULL; } From d2241f8ec437bf7873ae25a7a7bbc193d2495a35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 20 Sep 2006 18:16:24 +0000 Subject: [PATCH 293/488] If boot resources are provided, use them instead of using resource requirements. In all cases, translate the resource list before calling the driver svn path=/trunk/; revision=24217 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 506 +++++++++++++++++++--------- 1 file changed, 340 insertions(+), 166 deletions(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index c0047ae1cca..9d664858a5b 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -132,12 +132,6 @@ IopStartDevice( Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList; Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated; - /* FIXME: Not sure of this! */ - if (!Stack.Parameters.StartDevice.AllocatedResources) - Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->BootResources; - if (!Stack.Parameters.StartDevice.AllocatedResourcesTranslated) - Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->BootResources; - Status = IopInitiatePnpIrp( Fdo, &IoStatusBlock, @@ -1229,30 +1223,70 @@ IopSetDeviceInstanceData(HANDLE InstanceKey, } -NTSTATUS -IopAssignDeviceResources(PDEVICE_NODE DeviceNode) +static NTSTATUS +IopAssignDeviceResources( + IN PDEVICE_NODE DeviceNode, + OUT ULONG *pRequiredSize) { PIO_RESOURCE_LIST ResourceList; PIO_RESOURCE_DESCRIPTOR ResourceDescriptor; - PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated; + PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw; + PCM_PARTIAL_RESOURCE_LIST pPartialResourceList; ULONG NumberOfResources = 0; - ULONG i; + ULONG Size; + ULONG i, j; NTSTATUS Status; - /* Fill DeviceNode->ResourceList and DeviceNode->ResourceListTranslated; - * by using DeviceNode->ResourceRequirements */ - - if (!DeviceNode->ResourceRequirements - || DeviceNode->ResourceRequirements->AlternativeLists == 0) + if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements) { - DeviceNode->ResourceList = DeviceNode->ResourceListTranslated = NULL; + /* No resource needed for this device */ + DeviceNode->ResourceList = NULL; return STATUS_SUCCESS; } + /* Fill DeviceNode->ResourceList + * FIXME: the PnP arbiter should go there! + * Actually, use the BootResources if provided, else the resource list #0 + */ + + IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); + + if (DeviceNode->BootResources) + { + /* Browse the boot resources to know if we have some custom structures */ + Size = FIELD_OFFSET(CM_RESOURCE_LIST, List); + for (i = 0; i < DeviceNode->BootResources->Count; i++) + { + pPartialResourceList = &DeviceNode->BootResources->List[i].PartialResourceList; + if (pPartialResourceList->Version != 1 || pPartialResourceList->Revision != 1) + { + Status = STATUS_REVISION_MISMATCH; + goto ByeBye; + } + Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors) + + pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + for (j = 0; j < pPartialResourceList->Count; j++) + { + if (pPartialResourceList->PartialDescriptors[j].Type == CmResourceTypeDeviceSpecific) + Size += pPartialResourceList->PartialDescriptors[j].u.DeviceSpecificData.DataSize; + } + } + + DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size); + if (!DeviceNode->ResourceList) + { + Status = STATUS_NO_MEMORY; + goto ByeBye; + } + RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, Size); + + *pRequiredSize = Size; + return STATUS_SUCCESS; + } + + /* Ok, here, we have to use the device requirement list */ IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); - /* FIXME: that's here that PnP arbiter should go */ - /* Actually, simply use resource list #0 as assigned resource list */ ResourceList = &DeviceNode->ResourceRequirements->List[0]; if (ResourceList->Version != 1 || ResourceList->Revision != 1) { @@ -1260,19 +1294,12 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) goto ByeBye; } - DeviceNode->ResourceList = ExAllocatePool(PagedPool, - sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + Size = sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + *pRequiredSize = Size; + DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size); if (!DeviceNode->ResourceList) { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto ByeBye; - } - - DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, - sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); - if (!DeviceNode->ResourceListTranslated) - { - Status = STATUS_INSUFFICIENT_RESOURCES; + Status = STATUS_NO_MEMORY; goto ByeBye; } @@ -1282,12 +1309,6 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) DeviceNode->ResourceList->List[0].PartialResourceList.Version = 1; DeviceNode->ResourceList->List[0].PartialResourceList.Revision = 1; - DeviceNode->ResourceListTranslated->Count = 1; - DeviceNode->ResourceListTranslated->List[0].InterfaceType = DeviceNode->ResourceRequirements->InterfaceType; - DeviceNode->ResourceListTranslated->List[0].BusNumber = DeviceNode->ResourceRequirements->BusNumber; - DeviceNode->ResourceListTranslated->List[0].PartialResourceList.Version = 1; - DeviceNode->ResourceListTranslated->List[0].PartialResourceList.Revision = 1; - for (i = 0; i < ResourceList->Count; i++) { ResourceDescriptor = &ResourceList->Descriptors[i]; @@ -1295,31 +1316,18 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) if (ResourceDescriptor->Option == 0 || ResourceDescriptor->Option == IO_RESOURCE_PREFERRED) { DescriptorRaw = &DeviceNode->ResourceList->List[0].PartialResourceList.PartialDescriptors[NumberOfResources]; - DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[NumberOfResources]; NumberOfResources++; /* Copy ResourceDescriptor to DescriptorRaw and DescriptorTranslated */ - DescriptorRaw->Type = DescriptorTranslated->Type = ResourceDescriptor->Type; - DescriptorRaw->ShareDisposition = DescriptorTranslated->ShareDisposition = ResourceDescriptor->ShareDisposition; - DescriptorRaw->Flags = DescriptorTranslated->Flags = ResourceDescriptor->Flags; + DescriptorRaw->Type = ResourceDescriptor->Type; + DescriptorRaw->ShareDisposition = ResourceDescriptor->ShareDisposition; + DescriptorRaw->Flags = ResourceDescriptor->Flags; switch (ResourceDescriptor->Type) { case CmResourceTypePort: { - ULONG AddressSpace = 0; /* IO space */ DescriptorRaw->u.Port.Start = ResourceDescriptor->u.Port.MinimumAddress; - DescriptorRaw->u.Port.Length = DescriptorTranslated->u.Port.Length - = ResourceDescriptor->u.Port.Length; - if (!HalTranslateBusAddress( - DeviceNode->ResourceRequirements->InterfaceType, - DeviceNode->ResourceRequirements->BusNumber, - DescriptorRaw->u.Port.Start, - &AddressSpace, - &DescriptorTranslated->u.Port.Start)) - { - Status = STATUS_UNSUCCESSFUL; - goto ByeBye; - } + DescriptorRaw->u.Port.Length = ResourceDescriptor->u.Port.Length; break; } case CmResourceTypeInterrupt: @@ -1379,54 +1387,26 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) } } } - - DescriptorTranslated->u.Interrupt.Level = 0; - DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector( - DeviceNode->ResourceRequirements->InterfaceType, - DeviceNode->ResourceRequirements->BusNumber, - DescriptorRaw->u.Interrupt.Level, - DescriptorRaw->u.Interrupt.Vector, - (PKIRQL)&DescriptorTranslated->u.Interrupt.Level, - &DescriptorRaw->u.Interrupt.Affinity); - DescriptorTranslated->u.Interrupt.Affinity = DescriptorRaw->u.Interrupt.Affinity; break; } case CmResourceTypeMemory: { - ULONG AddressSpace = 1; /* Memory space */ DescriptorRaw->u.Memory.Start = ResourceDescriptor->u.Memory.MinimumAddress; - DescriptorRaw->u.Memory.Length = DescriptorTranslated->u.Memory.Length - = ResourceDescriptor->u.Memory.Length; - if (!HalTranslateBusAddress( - DeviceNode->ResourceRequirements->InterfaceType, - DeviceNode->ResourceRequirements->BusNumber, - DescriptorRaw->u.Memory.Start, - &AddressSpace, - &DescriptorTranslated->u.Memory.Start)) - { - Status = STATUS_UNSUCCESSFUL; - goto ByeBye; - } + DescriptorRaw->u.Memory.Length = ResourceDescriptor->u.Memory.Length; break; } case CmResourceTypeDma: { - DescriptorRaw->u.Dma.Channel = DescriptorTranslated->u.Dma.Channel - = ResourceDescriptor->u.Dma.MinimumChannel; - DescriptorRaw->u.Dma.Port = DescriptorTranslated->u.Dma.Port - = 0; /* FIXME */ - DescriptorRaw->u.Dma.Reserved1 = DescriptorTranslated->u.Dma.Reserved1 - = 0; + DescriptorRaw->u.Dma.Channel = ResourceDescriptor->u.Dma.MinimumChannel; + DescriptorRaw->u.Dma.Port = 0; /* FIXME */ + DescriptorRaw->u.Dma.Reserved1 = 0; break; } case CmResourceTypeBusNumber: { - DescriptorRaw->u.BusNumber.Start = DescriptorTranslated->u.BusNumber.Start - = ResourceDescriptor->u.BusNumber.MinBusNumber; - DescriptorRaw->u.BusNumber.Length = DescriptorTranslated->u.BusNumber.Length - = ResourceDescriptor->u.BusNumber.Length; - DescriptorRaw->u.BusNumber.Reserved = DescriptorTranslated->u.BusNumber.Reserved - = ResourceDescriptor->u.BusNumber.Reserved; + DescriptorRaw->u.BusNumber.Start = ResourceDescriptor->u.BusNumber.MinBusNumber; + DescriptorRaw->u.BusNumber.Length = ResourceDescriptor->u.BusNumber.Length; + DescriptorRaw->u.BusNumber.Reserved = ResourceDescriptor->u.BusNumber.Reserved; break; } /*CmResourceTypeDevicePrivate: @@ -1452,10 +1432,7 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode) } DeviceNode->ResourceList->List[0].PartialResourceList.Count = NumberOfResources; - DeviceNode->ResourceListTranslated->List[0].PartialResourceList.Count = NumberOfResources; - IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); - IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED); return STATUS_SUCCESS; ByeBye: @@ -1464,13 +1441,111 @@ ByeBye: ExFreePool(DeviceNode->ResourceList); DeviceNode->ResourceList = NULL; } + return Status; +} + + +static NTSTATUS +IopTranslateDeviceResources( + IN PDEVICE_NODE DeviceNode, + IN ULONG RequiredSize) +{ + PCM_PARTIAL_RESOURCE_LIST pPartialResourceList; + PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated; + ULONG i, j; + NTSTATUS Status; + + if (!DeviceNode->ResourceList) + { + DeviceNode->ResourceListTranslated = NULL; + return STATUS_SUCCESS; + } + + /* That's easy to translate a resource list. Just copy the + * untranslated one and change few fields in the copy + */ + DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, RequiredSize); + if (!DeviceNode->ResourceListTranslated) + { + Status =STATUS_NO_MEMORY; + goto cleanup; + } + RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, RequiredSize); + + for (i = 0; i < DeviceNode->ResourceList->Count; i++) + { + pPartialResourceList = &DeviceNode->ResourceList->List[i].PartialResourceList; + for (j = 0; j < pPartialResourceList->Count; j++) + { + DescriptorRaw = &pPartialResourceList->PartialDescriptors[j]; + DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j]; + switch (DescriptorRaw->Type) + { + case CmResourceTypePort: + { + ULONG AddressSpace = 0; /* IO space */ + if (!HalTranslateBusAddress( + DeviceNode->ResourceList->List[i].InterfaceType, + DeviceNode->ResourceList->List[i].BusNumber, + DescriptorRaw->u.Port.Start, + &AddressSpace, + &DescriptorTranslated->u.Port.Start)) + { + Status = STATUS_UNSUCCESSFUL; + goto cleanup; + } + break; + } + case CmResourceTypeInterrupt: + { + DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector( + DeviceNode->ResourceList->List[i].InterfaceType, + DeviceNode->ResourceList->List[i].BusNumber, + DescriptorRaw->u.Interrupt.Level, + DescriptorRaw->u.Interrupt.Vector, + (PKIRQL)&DescriptorTranslated->u.Interrupt.Level, + &DescriptorRaw->u.Interrupt.Affinity); + break; + } + case CmResourceTypeMemory: + { + ULONG AddressSpace = 1; /* Memory space */ + if (!HalTranslateBusAddress( + DeviceNode->ResourceList->List[i].InterfaceType, + DeviceNode->ResourceList->List[i].BusNumber, + DescriptorRaw->u.Memory.Start, + &AddressSpace, + &DescriptorTranslated->u.Memory.Start)) + { + Status = STATUS_UNSUCCESSFUL; + goto cleanup; + } + } + + case CmResourceTypeDma: + case CmResourceTypeBusNumber: + case CmResourceTypeDeviceSpecific: + /* Nothing to do */ + break; + default: + DPRINT1("Unknown resource descriptor type 0x%x\n", DescriptorRaw->Type); + Status = STATUS_NOT_IMPLEMENTED; + goto cleanup; + } + } + } + return STATUS_SUCCESS; + +cleanup: + /* Yes! Also delete ResourceList because ResourceList and + * ResourceListTranslated should be a pair! */ + ExFreePool(DeviceNode->ResourceList); + DeviceNode->ResourceList = NULL; if (DeviceNode->ResourceListTranslated) { ExFreePool(DeviceNode->ResourceListTranslated); - DeviceNode->ResourceListTranslated = NULL; + DeviceNode->ResourceList = NULL; } - - IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); return Status; } @@ -2030,11 +2105,25 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, ZwClose(InstanceKey); - Status = IopAssignDeviceResources(DeviceNode); - if (!NT_SUCCESS(Status)) + IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); + Status = IopAssignDeviceResources(DeviceNode, &RequiredLength); + if (NT_SUCCESS(Status)) { - DPRINT("IopAssignDeviceResources() failed (Status %x)\n", Status); + Status = IopTranslateDeviceResources(DeviceNode, RequiredLength); + if (NT_SUCCESS(Status)) + { + IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED); + } + else + { + DPRINT("IopTranslateDeviceResources() failed (Status 0x08lx)\n", Status); + } } + else + { + DPRINT("IopAssignDeviceResources() failed (Status 0x08lx)\n", Status); + } + IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); DeviceNode->Flags |= DNF_PROCESSED; @@ -2596,7 +2685,9 @@ IopEnumerateDetectedDevices( IN HANDLE hBaseKey, IN PUNICODE_STRING RelativePath, IN HANDLE hRootKey, - IN BOOLEAN EnumerateSubKeys) + IN BOOLEAN EnumerateSubKeys, + IN PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources, + IN ULONG ParentBootResourcesLength) { UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc"); @@ -2618,6 +2709,8 @@ IopEnumerateDetectedDevices( ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR); UNICODE_STRING DeviceName, ValueName; ULONG RequiredSize; + PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL; + ULONG BootResourcesLength; NTSTATUS Status; const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI BIOS"); @@ -2701,6 +2794,87 @@ IopEnumerateDetectedDevices( goto cleanup; } + /* Read boot resources, and add then to parent ones */ + Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + if (Status == STATUS_BUFFER_OVERFLOW) + { + ExFreePool(pValueInformation); + ValueInfoLength = RequiredSize; + pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); + if (!pValueInformation) + { + DPRINT("ExAllocatePool() failed\n"); + ZwDeleteKey(hLevel2Key); + Status = STATUS_NO_MEMORY; + goto cleanup; + } + Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); + } + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + BootResources = ParentBootResources; + BootResourcesLength = ParentBootResourcesLength; + } + else if (!NT_SUCCESS(Status)) + { + DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } + else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR) + { + DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR); + goto nextdevice; + } + else if (((PCM_FULL_RESOURCE_DESCRIPTOR)pValueInformation->Data)->PartialResourceList.Count == 0) + { + BootResources = ParentBootResources; + BootResourcesLength = ParentBootResourcesLength; + } + else + { + static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors); + + /* Concatenate current resources and parent ones */ + if (ParentBootResourcesLength == 0) + BootResourcesLength = pValueInformation->DataLength; + else + BootResourcesLength = ParentBootResourcesLength + + pValueInformation->DataLength + - Header; + BootResources = ExAllocatePool(PagedPool, BootResourcesLength); + if (!BootResources) + { + DPRINT("ExAllocatePool() failed\n"); + goto nextdevice; + } + if (ParentBootResourcesLength == 0) + { + RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength); + } + else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific) + { + RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength); + RtlCopyMemory( + (PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength), + (PVOID)((ULONG_PTR)ParentBootResources + Header), + ParentBootResourcesLength - Header); + BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count; + } + else + { + RtlCopyMemory(BootResources, pValueInformation->Data, Header); + RtlCopyMemory( + (PVOID)((ULONG_PTR)BootResources + Header), + (PVOID)((ULONG_PTR)ParentBootResources + Header), + ParentBootResourcesLength - Header); + RtlCopyMemory( + (PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength), + pValueInformation->Data + Header, + pValueInformation->DataLength - Header); + BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count; + } + } + if (EnumerateSubKeys) { IndexSubKey = 0; @@ -2731,7 +2905,13 @@ IopEnumerateDetectedDevices( DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength; DeviceName.Buffer = pDeviceInformation->Name; - Status = IopEnumerateDetectedDevices(hDeviceKey, &DeviceName, hRootKey, TRUE); + Status = IopEnumerateDetectedDevices( + hDeviceKey, + &DeviceName, + hRootKey, + TRUE, + BootResources, + BootResourcesLength); if (!NT_SUCCESS(Status)) goto cleanup; } @@ -2754,31 +2934,27 @@ IopEnumerateDetectedDevices( } if (!NT_SUCCESS(Status)) { - DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); - goto nextdevice; + if (Status != STATUS_OBJECT_NAME_NOT_FOUND) + { + DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); + goto nextdevice; + } } else if (pValueInformation->Type != REG_SZ) { DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); goto nextdevice; } - - /* Assign hardware id to this device */ - ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; - ValueName.Buffer = (PWCHAR)pValueInformation->Data; - if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) - ValueName.Length -= sizeof(WCHAR); - if (RtlCompareUnicodeString(&ValueName, &IdentifierPci, FALSE) == 0) + else { - pHardwareId = &HardwareIdPci; - DeviceIndex = DeviceIndexPci++; + /* Assign hardware id to this device */ + ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; + ValueName.Buffer = (PWCHAR)pValueInformation->Data; + if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) + ValueName.Length -= sizeof(WCHAR); } - /*else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0) - { - pHardwareId = &HardwareIdAcpi; - DeviceIndex = DeviceIndexAcpi++; - }*/ - else if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0) + + if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0) { pHardwareId = &HardwareIdSerial; DeviceIndex = DeviceIndexSerial++; @@ -2793,10 +2969,30 @@ IopEnumerateDetectedDevices( pHardwareId = &HardwareIdMouse; DeviceIndex = DeviceIndexMouse++; } + else if (NT_SUCCESS(Status)) + { + /* Try to also match the device identifier */ + if (RtlCompareUnicodeString(&ValueName, &IdentifierPci, FALSE) == 0) + { + pHardwareId = &HardwareIdPci; + DeviceIndex = DeviceIndexPci++; + } + /*else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0) + { + pHardwareId = &HardwareIdAcpi; + DeviceIndex = DeviceIndexAcpi++; + }*/ + else + { + /* Unknown device */ + DPRINT("Unknown device '%wZ'\n", &ValueName); + goto nextdevice; + } + } else { - /* Unknown device */ - DPRINT("Unknown device %wZ in %wZ\n", &ValueName, RelativePath); + /* Unknown key path */ + DPRINT("Unknown key path %wZ\n", RelativePath); goto nextdevice; } @@ -2847,61 +3043,37 @@ IopEnumerateDetectedDevices( ZwDeleteKey(hLevel2Key); goto nextdevice; } - /* Copy 'Configuration Data' to 'LogConf\BootConfig' */ - Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); - if (Status == STATUS_BUFFER_OVERFLOW) + if (BootResourcesLength > 0) { - ExFreePool(pValueInformation); - ValueInfoLength = RequiredSize; - pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength); - if (!pValueInformation) + /* Save boot resources to 'LogConf\BootConfig' */ + InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE, hLevel2Key, NULL); + Status = ZwCreateKey( + &hLogConf, + KEY_SET_VALUE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) { - DPRINT("ExAllocatePool() failed\n"); + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); ZwDeleteKey(hLevel2Key); - Status = STATUS_NO_MEMORY; - goto cleanup; + goto nextdevice; + } + Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_FULL_RESOURCE_DESCRIPTOR, BootResources, BootResourcesLength); + ZwClose(hLogConf); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); + ZwDeleteKey(hLevel2Key); + goto nextdevice; } - Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); - } - if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - goto nextdevice; - else if (!NT_SUCCESS(Status)) - { - DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR) - { - DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE, hLevel2Key, NULL); - Status = ZwCreateKey( - &hLogConf, - KEY_SET_VALUE, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, pValueInformation->Type, pValueInformation->Data, pValueInformation->DataLength); - ZwClose(hLogConf); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); - ZwDeleteKey(hLevel2Key); - goto nextdevice; } nextdevice: + if (BootResources && BootResources != ParentBootResources) + ExFreePool(BootResources); if (hLevel2Key) { ZwClose(hLevel2Key); @@ -3119,7 +3291,9 @@ IopUpdateRootKey(VOID) NULL, &MultiKeyPathU, hRoot, - TRUE); + TRUE, + NULL, + 0); ZwClose(hRoot); return Status; } From f1cf836837652fa7002945ccd1744bb36bbb573c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 20 Sep 2006 18:56:04 +0000 Subject: [PATCH 294/488] Big update of i8042prt driver. The driver is now plug&play compliant and some mouse driver filters may be installed. svn path=/trunk/; revision=24218 --- reactos/boot/bootdata/hivesys.inf | 23 +- reactos/drivers/input/i8042prt/README.txt | 25 +- reactos/drivers/input/i8042prt/createclose.c | 55 + reactos/drivers/input/i8042prt/i8042prt.c | 1233 ++++-------- reactos/drivers/input/i8042prt/i8042prt.h | 628 +++--- .../drivers/input/i8042prt/i8042prt.rbuild | 6 +- reactos/drivers/input/i8042prt/i8042prt.rc | 2 +- reactos/drivers/input/i8042prt/keyboard.c | 1491 +++++++------- reactos/drivers/input/i8042prt/misc.c | 68 + reactos/drivers/input/i8042prt/mouse.c | 1744 +++++++++-------- reactos/drivers/input/i8042prt/pnp.c | 666 +++++++ reactos/drivers/input/i8042prt/ps2pp.c | 238 +-- reactos/drivers/input/i8042prt/readwrite.c | 218 +++ reactos/drivers/input/i8042prt/registry.c | 336 ++-- reactos/drivers/input/i8042prt/setup.c | 273 +++ 15 files changed, 4119 insertions(+), 2887 deletions(-) create mode 100644 reactos/drivers/input/i8042prt/createclose.c create mode 100644 reactos/drivers/input/i8042prt/misc.c create mode 100644 reactos/drivers/input/i8042prt/pnp.c create mode 100644 reactos/drivers/input/i8042prt/readwrite.c create mode 100644 reactos/drivers/input/i8042prt/setup.c diff --git a/reactos/boot/bootdata/hivesys.inf b/reactos/boot/bootdata/hivesys.inf index c0f44f258ed..4cb1a01bc29 100644 --- a/reactos/boot/bootdata/hivesys.inf +++ b/reactos/boot/bootdata/hivesys.inf @@ -564,13 +564,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","ImagePath",0x00020000,"system32 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Type",0x00010001,0x00000008 -; i8042 port driver -HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","ErrorControl",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","Group",0x00000000,"Keyboard Port" -HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","Start",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt","Type",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt\Parameters","BreakOnSysRq",0x00010001,0x00000001 - ; Kernel-Mode Tests ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ErrorControl",0x00010001,0x00000000 ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Group",0x00000000,"Base" @@ -578,14 +571,8 @@ HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt\Parameters","BreakOnSysRq",0x00 ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Start",0x00010001,0x00000001 ;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Type",0x00010001,0x00000001 -; Keyboard class driver -HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","ErrorControl",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","Group",0x00000000,"Keyboard Class" -HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","ImagePath",0x00020000,"system32\drivers\kbdclass.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","Start",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","Type",0x00010001,0x00000001 +; Keyboard parameters HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass\Parameters","ConnectMultiplePorts",0x00010001,1 -HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E96B-E325-11CE-BFC1-08002BE10318}","UpperFilters",0x00010000,"kbdclass" ; SB16 driver HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Group",0x00000000,"Base" @@ -610,14 +597,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ImagePath",0x00020000,"system32\drivers\mpu401.sys" -; Mouse class driver -HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","ErrorControl",0x00010001,0x00000000 -HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Group",0x00000000,"Pointer Class" -HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","ImagePath",0x00020000,"system32\drivers\mouclass.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Start",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\mouclass","Type",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E96F-E325-11CE-BFC1-08002BE10318}","UpperFilters",0x00010000,"mouclass" - ; Mailslot filesystem driver HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","Group",0x00000000,"File System" diff --git a/reactos/drivers/input/i8042prt/README.txt b/reactos/drivers/input/i8042prt/README.txt index a8f09ff5f59..16bb6c791fb 100644 --- a/reactos/drivers/input/i8042prt/README.txt +++ b/reactos/drivers/input/i8042prt/README.txt @@ -7,18 +7,28 @@ not based on the i8042prt example driver that's included with the DDK. The directory contains these files: +createclose.c: open/close devices functionnality + i8042prt.c: Main controller functionality, things shared by keyboards and mice keyboard.c: keyboard functionality: detection, interrupt handling +misc.c: misc things, mostly related to Irp passing + mouse.c: mouse functionality: detection, interrupt handling, packet parsing for standard ps2 and microsoft mice +pnp.c: Plug&Play functionnality + ps2pp.c: logitech ps2++ mouse packat parsing (basic) +readwrite.c: read/write to the i8042 controller + registry.c: registry reading -makefile, i8042prt.rc: obvious +setup.c: add keyboard support during the 1st stage setup + +i8042prt.rc: obvious Some parts of the driver make little sense. This is because it implements @@ -33,7 +43,6 @@ Things to add: - General robustness: reset mouse if things go wrong - Handling all registry settings - ACPI -- Make it work more like a WDM driver Things not to add: @@ -49,18 +58,6 @@ Things requiring work elsewhere: hardcoded cases, this should not be hard to fix. - Class drivers: - I wrote a keyboard class driver, which does keycode translations. It - should not do this, win32k should get untranslated keycodes and do - the translation itself. - - I changed the mouse class driver (mouclass) to work like Microsofts mouclass. - Unfortunately this means that the original psaux driver doesn't work - anymore (the same holds for the other mice drivers, probably). - - The keyboard class driver passes on ioctls from win32k, so it can change - keyboard settings. As far as I could see, the mouse class driver does not - do this yet. - The class drivers should be able to handle reads for more than one packet at a time (kbdclass should, mouclass does not). Win32k should send such requests. diff --git a/reactos/drivers/input/i8042prt/createclose.c b/reactos/drivers/input/i8042prt/createclose.c new file mode 100644 index 00000000000..e895dbee3cc --- /dev/null +++ b/reactos/drivers/input/i8042prt/createclose.c @@ -0,0 +1,55 @@ +/* + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/createclose.c + * PURPOSE: IRP_MJ_CREATE, IRP_MJ_CLEANUP and IRP_MJ_CLOSE operations + * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "i8042prt.h" + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS NTAPI +i8042Create( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("IRP_MJ_CREATE\n"); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +i8042Cleanup( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("IRP_MJ_CLEANUP\n"); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +i8042Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("IRP_MJ_CLOSE\n"); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/input/i8042prt/i8042prt.c b/reactos/drivers/input/i8042prt/i8042prt.c index 04625caa859..ebffde03621 100644 --- a/reactos/drivers/input/i8042prt/i8042prt.c +++ b/reactos/drivers/input/i8042prt/i8042prt.c @@ -1,927 +1,524 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/i8042prt.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/i8042prt.c + * PURPOSE: Driver entry function + * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) + Copyright Jason Filby (jasonfilby@yahoo.com) + Copyright Martijn Vernooij (o112w8r02@sneakemail.com) + Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) */ -/* INCLUDES ****************************************************************/ +/* INCLUDES ******************************************************************/ + +#define INITGUID +#include "i8042prt.h" #define NDEBUG #include -#include "i8042prt.h" - -/* GLOBALS *******************************************************************/ - -/* - * Driver data - */ -#define I8042_TIMEOUT 500000 - -#define I8042_MAX_COMMAND_LENGTH 16 -#define I8042_MAX_UPWARDS_STACK 5 - -UNICODE_STRING I8042RegistryPath; - /* FUNCTIONS *****************************************************************/ -/* - * FUNCTION: Write data to a port, waiting first for it to become ready - */ -BOOLEAN I8042Write(PDEVICE_EXTENSION DevExt, PUCHAR addr, UCHAR data) +NTSTATUS NTAPI +i8042AddDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT Pdo) { - ULONG ResendIterations = DevExt->Settings.PollingIterations; + PI8042_DRIVER_EXTENSION DriverExtension; + PFDO_DEVICE_EXTENSION DeviceExtension = NULL; + PDEVICE_OBJECT Fdo = NULL; + ULONG DeviceExtensionSize; + NTSTATUS Status; - while ((KBD_IBF & READ_PORT_UCHAR(I8042_CTRL_PORT)) && - (ResendIterations--)) + DPRINT("i8042AddDevice(%p %p)\n", DriverObject, Pdo); + + DriverExtension = (PI8042_DRIVER_EXTENSION)IoGetDriverObjectExtension(DriverObject, DriverObject); + + if (Pdo == NULL) { - KeStallExecutionProcessor(50); + /* We're getting a NULL Pdo at the first call as + * we are a legacy driver. Ignore it */ + return STATUS_SUCCESS; } - if (ResendIterations) { - WRITE_PORT_UCHAR(addr,data); - DPRINT("Sent %x to %x\n", data, addr); - return TRUE; + /* Create new device object. As we don't know if the device would be a keyboard + * or a mouse, we have to allocate the biggest device extension. */ + DeviceExtensionSize = MAX(sizeof(I8042_KEYBOARD_EXTENSION), sizeof(I8042_MOUSE_EXTENSION)); + Status = IoCreateDevice( + DriverObject, + DeviceExtensionSize, + NULL, + Pdo->DeviceType, + FILE_DEVICE_SECURE_OPEN, + TRUE, + &Fdo); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); + goto cleanup; } - return FALSE; -} -#if 0 /* function is not needed */ -/* - * FUNCTION: Write data to a port, without waiting first - */ -static BOOLEAN I8042WriteNoWait(PDEVICE_EXTENSION DevExt, int addr, UCHAR data) -{ - WRITE_PORT_UCHAR((PUCHAR)addr,data); - DPRINT("Sent %x to %x\n", data, addr); - return TRUE; -} -#endif + DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension; + RtlZeroMemory(DeviceExtension, DeviceExtensionSize); + DeviceExtension->Type = Unknown; + DeviceExtension->Fdo = Fdo; + DeviceExtension->Pdo = Pdo; + DeviceExtension->PortDeviceExtension = &DriverExtension->Port; + Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice); -/* - * FUNCTION: Read data from port 0x60 - */ -NTSTATUS I8042ReadData(UCHAR *Data) -{ - UCHAR Status; - Status=READ_PORT_UCHAR(I8042_CTRL_PORT); - - // If data is available - if ((Status & KBD_OBF)) { - Data[0]=READ_PORT_UCHAR((PUCHAR)I8042_DATA_PORT); - DPRINT("Read: %x (status: %x)\n", Data[0], Status); - - // If the data is valid (not timeout, not parity error) - if (0 == (Status & KBD_PERR)) - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS I8042ReadStatus(UCHAR *Status) -{ - Status[0]=READ_PORT_UCHAR(I8042_CTRL_PORT); + Fdo->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; + +cleanup: + if (DeviceExtension && DeviceExtension->LowerDevice) + IoDetachDevice(DeviceExtension->LowerDevice); + if (Fdo) + IoDeleteDevice(Fdo); + return Status; } -/* - * FUNCTION: Read data from port 0x60 - */ -NTSTATUS I8042ReadDataWait(PDEVICE_EXTENSION DevExt, UCHAR *Data) +VOID NTAPI +i8042SendHookWorkItem( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) { - ULONG Counter = DevExt->Settings.PollingIterations; + PI8042_HOOK_WORKITEM WorkItemData; + PFDO_DEVICE_EXTENSION FdoDeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + PDEVICE_OBJECT TopOfStack = NULL; + ULONG IoControlCode; + PVOID InputBuffer; + ULONG InputBufferLength; + IO_STATUS_BLOCK IoStatus; + KEVENT Event; + PIRP NewIrp; NTSTATUS Status; - while (Counter--) { - Status = I8042ReadData(Data); + DPRINT("i8042SendHookWorkItem(%p %p)\n", DeviceObject, Context); - if (STATUS_SUCCESS == Status) - return Status; + WorkItemData = (PI8042_HOOK_WORKITEM)Context; + FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + PortDeviceExtension = FdoDeviceExtension->PortDeviceExtension; - KeStallExecutionProcessor(50); - } - // Timed out - return STATUS_IO_TIMEOUT; -} - -VOID I8042Flush() -{ - UCHAR Ignore; - - while (STATUS_SUCCESS == I8042ReadData(&Ignore)) { - DPRINT("Data flushed\n"); /* drop */ - } -} - -VOID STDCALL I8042IsrWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Value, - UCHAR SelectCmd) -{ - if (SelectCmd) - if (!I8042Write(DevExt, I8042_CTRL_PORT, SelectCmd)) - return; - - I8042Write(DevExt, I8042_DATA_PORT, Value); -} - -/* - * These functions are callbacks for filter driver custom - * initialization routines. - */ -NTSTATUS STDCALL I8042SynchWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Port, - UCHAR Value, - BOOLEAN WaitForAck) -{ - NTSTATUS Status; - UCHAR Ack; - ULONG ResendIterations = DevExt->Settings.ResendIterations + 1; - - do { - if (Port) - if (!I8042Write(DevExt, I8042_DATA_PORT, Port)) - { - DPRINT1("Failed to write Port\n"); - return STATUS_IO_TIMEOUT; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) + switch (FdoDeviceExtension->Type) + { + case Keyboard: { - DPRINT1("Failed to write Value\n"); - return STATUS_IO_TIMEOUT; + PI8042_KEYBOARD_EXTENSION DeviceExtension; + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension; + IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD; + InputBuffer = &DeviceExtension->KeyboardHook; + InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD); + break; } + case Mouse: + { + PI8042_MOUSE_EXTENSION DeviceExtension; + DeviceExtension = (PI8042_MOUSE_EXTENSION)FdoDeviceExtension; + IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE; + InputBuffer = &DeviceExtension->MouseHook; + InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE); + break; + } + default: + { + DPRINT1("Unknown FDO type %u\n", FdoDeviceExtension->Type); + ASSERT(FALSE); + WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; + goto cleanup; + } + } - if (WaitForAck) { - Status = I8042ReadDataWait(DevExt, &Ack); + KeInitializeEvent(&Event, NotificationEvent, FALSE); + TopOfStack = IoGetAttachedDeviceReference(DeviceObject); + + NewIrp = IoBuildDeviceIoControlRequest( + IoControlCode, + TopOfStack, + InputBuffer, + InputBufferLength, + NULL, + 0, + TRUE, + &Event, + &IoStatus); + + if (!NewIrp) + { + DPRINT("IoBuildDeviceIoControlRequest() failed\n"); + WorkItemData->Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + + Status = IoCallDriver(TopOfStack, NewIrp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject( + &Event, + Executive, + KernelMode, + FALSE, + NULL); + Status = IoStatus.Status; + } + if (!NT_SUCCESS(Status)) + { + DPRINT("IoCallDriver() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + if (FdoDeviceExtension->Type == Keyboard) + { + PI8042_KEYBOARD_EXTENSION DeviceExtension; + + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension; + /* Call the hooked initialization if it exists */ + if (DeviceExtension->KeyboardHook.InitializationRoutine) + { + Status = DeviceExtension->KeyboardHook.InitializationRoutine( + DeviceExtension->KeyboardHook.Context, + PortDeviceExtension, + i8042SynchReadPort, + i8042SynchWritePortKbd, + FALSE); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to read Ack\n"); - return Status; + DPRINT("KeyboardHook.InitializationRoutine() failed with status 0x%08lx\n", Status); + WorkItemData->Irp->IoStatus.Status = Status; + goto cleanup; } - if (Ack == KBD_ACK) - return STATUS_SUCCESS; - if (Ack != KBD_RESEND) - { - DPRINT1("Unexpected Ack 0x%x\n", Ack); - return STATUS_UNEXPECTED_IO_ERROR; - } - } else { - return STATUS_SUCCESS; } - DPRINT("Reiterating\n"); - ResendIterations--; - } while (ResendIterations); - return STATUS_IO_TIMEOUT; + } +#if 0 + else + { + /* Mouse doesn't have this, but we need to send a + * reset to start the detection. + */ + KIRQL Irql; + + Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); + + i8042Write(PortDeviceExtension, PortDeviceExtension->ControlPort, CTRL_WRITE_MOUSE); + i8042Write(PortDeviceExtension, PortDeviceExtension->DataPort, MOU_CMD_RESET); + + KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); + } +#endif + + WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS; + +cleanup: + if (TopOfStack != NULL) + ObDereferenceObject(TopOfStack); + WorkItemData->Irp->IoStatus.Information = 0; + IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT); + + IoFreeWorkItem(WorkItemData->WorkItem); + ExFreePool(WorkItemData); } -/* - * This one reads a value from the port; You don't have to specify - * which one, it'll always be from the one you talked to, so one function - * is enough this time. Note how MSDN specifies the - * WaitForAck parameter to be ignored. - */ -static NTSTATUS STDCALL I8042SynchReadPort(PVOID Context, - PUCHAR Value, - BOOLEAN WaitForAck) +static VOID NTAPI +i8042StartIo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)Context; + PFDO_DEVICE_EXTENSION DeviceExtension; - return I8042ReadDataWait(DevExt, Value); + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + switch (DeviceExtension->Type) + { + case Keyboard: + i8042KbdStartIo(DeviceObject, Irp); + break; + default: + DPRINT1("Unknown FDO type %u\n", DeviceExtension->Type); + ASSERT(FALSE); + break; + } } /* Write the current byte of the packet. Returns FALSE in case * of problems. */ -static BOOLEAN STDCALL I8042PacketWrite(PDEVICE_EXTENSION DevExt) +static BOOLEAN +i8042PacketWrite( + IN PPORT_DEVICE_EXTENSION DeviceExtension) { - UCHAR Port = DevExt->PacketPort; + UCHAR Port = DeviceExtension->PacketPort; - if (Port) { - if (!I8042Write(DevExt, - I8042_CTRL_PORT, - Port)) { + if (Port) + { + if (!i8042Write(DeviceExtension, + DeviceExtension->ControlPort, + Port)) + { /* something is really wrong! */ DPRINT1("Failed to send packet byte!\n"); return FALSE; } } - return I8042Write(DevExt, - I8042_DATA_PORT, - DevExt->Packet.Bytes[DevExt->Packet.CurrentByte]); + return i8042Write(DeviceExtension, + DeviceExtension->DataPort, + DeviceExtension->Packet.Bytes[DeviceExtension->Packet.CurrentByte]); } +BOOLEAN +i8042PacketIsr( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR Output) +{ + if (DeviceExtension->Packet.State == Idle) + return FALSE; + + switch (Output) + { + case KBD_RESEND: + DeviceExtension->PacketResends++; + if (DeviceExtension->PacketResends > DeviceExtension->Settings.ResendIterations) + { + DeviceExtension->Packet.State = Idle; + DeviceExtension->PacketComplete = TRUE; + DeviceExtension->PacketResult = STATUS_IO_TIMEOUT; + DeviceExtension->PacketResends = 0; + return TRUE; + } + DeviceExtension->Packet.CurrentByte--; + break; + + case KBD_NACK: + DeviceExtension->Packet.State = Idle; + DeviceExtension->PacketComplete = TRUE; + DeviceExtension->PacketResult = STATUS_UNEXPECTED_IO_ERROR; + DeviceExtension->PacketResends = 0; + return TRUE; + + default: + DeviceExtension->PacketResends = 0; + } + + if (DeviceExtension->Packet.CurrentByte >= DeviceExtension->Packet.ByteCount) + { + DeviceExtension->Packet.State = Idle; + DeviceExtension->PacketComplete = TRUE; + DeviceExtension->PacketResult = STATUS_SUCCESS; + return TRUE; + } + + if (!i8042PacketWrite(DeviceExtension)) + { + DeviceExtension->Packet.State = Idle; + DeviceExtension->PacketComplete = TRUE; + DeviceExtension->PacketResult = STATUS_IO_TIMEOUT; + return TRUE; + } + DeviceExtension->Packet.CurrentByte++; + + return TRUE; +} /* * This function starts a packet. It must be called with the * correct DIRQL. */ -NTSTATUS STDCALL I8042StartPacket(PDEVICE_EXTENSION DevExt, - PDEVICE_OBJECT Device, - PUCHAR Bytes, - ULONG ByteCount, - PIRP Irp) +NTSTATUS +i8042StartPacket( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, + IN PUCHAR Bytes, + IN ULONG ByteCount, + IN PIRP Irp) { KIRQL Irql; NTSTATUS Status; - PFDO_DEVICE_EXTENSION FdoDevExt = Device->DeviceExtension; - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); + Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); - DevExt->CurrentIrp = Irp; - DevExt->CurrentIrpDevice = Device; - - if (Idle != DevExt->Packet.State) { + if (DeviceExtension->Packet.State != Idle) + { Status = STATUS_DEVICE_BUSY; - goto startpacketdone; + goto done; } - DevExt->Packet.Bytes = Bytes; - DevExt->Packet.CurrentByte = 0; - DevExt->Packet.ByteCount = ByteCount; - DevExt->Packet.State = SendingBytes; - DevExt->PacketResult = Status = STATUS_PENDING; + switch (FdoDeviceExtension->Type) + { + case Keyboard: DeviceExtension->PacketPort = 0; break; + case Mouse: DeviceExtension->PacketPort = CTRL_WRITE_MOUSE; break; + default: + DPRINT1("Unknown FDO type %u\n", FdoDeviceExtension->Type); + ASSERT(FALSE); + Status = STATUS_INTERNAL_ERROR; + goto done; + } - if (Mouse == FdoDevExt->Type) - DevExt->PacketPort = 0xD4; - else - DevExt->PacketPort = 0; + DeviceExtension->Packet.Bytes = Bytes; + DeviceExtension->Packet.CurrentByte = 0; + DeviceExtension->Packet.ByteCount = ByteCount; + DeviceExtension->Packet.State = SendingBytes; + DeviceExtension->PacketResult = Status = STATUS_PENDING; + DeviceExtension->CurrentIrp = Irp; + DeviceExtension->CurrentIrpDevice = FdoDeviceExtension->Fdo; - if (!I8042PacketWrite(DevExt)) { + if (!i8042PacketWrite(DeviceExtension)) + { Status = STATUS_IO_TIMEOUT; - DevExt->Packet.State = Idle; - DevExt->PacketResult = STATUS_ABANDONED; - goto startpacketdone; + DeviceExtension->Packet.State = Idle; + DeviceExtension->PacketResult = STATUS_ABANDONED; + goto done; } - DevExt->Packet.CurrentByte++; + DeviceExtension->Packet.CurrentByte++; -startpacketdone: - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); +done: + KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); - if (STATUS_PENDING != Status) { - DevExt->CurrentIrp = NULL; - DevExt->CurrentIrpDevice = NULL; + if (Status != STATUS_PENDING) + { + DeviceExtension->CurrentIrp = NULL; + DeviceExtension->CurrentIrpDevice = NULL; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); } return Status; } -BOOLEAN STDCALL I8042PacketIsr(PDEVICE_EXTENSION DevExt, - UCHAR Output) +static NTSTATUS NTAPI +IrpStub( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - if (Idle == DevExt->Packet.State) - return FALSE; - - switch (Output) { - case KBD_RESEND: - DevExt->PacketResends++; - if (DevExt->PacketResends > DevExt->Settings.ResendIterations) { - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_IO_TIMEOUT; - DevExt->PacketResends = 0; - return TRUE; - } - DevExt->Packet.CurrentByte--; - break; - - case KBD_NACK: - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_UNEXPECTED_IO_ERROR; - DevExt->PacketResends = 0; - return TRUE; - - default: - DevExt->PacketResends = 0; - } - - if (DevExt->Packet.CurrentByte >= DevExt->Packet.ByteCount) { - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_SUCCESS; - return TRUE; - } - - if (!I8042PacketWrite(DevExt)) { - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_IO_TIMEOUT; - return TRUE; - } - DevExt->Packet.CurrentByte++; - - return TRUE; + KEBUGCHECK(0); + return STATUS_NOT_IMPLEMENTED; } -VOID I8042PacketDpc(PDEVICE_EXTENSION DevExt) +static NTSTATUS NTAPI +i8042DeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - BOOLEAN FinishIrp = FALSE; - NTSTATUS Result = STATUS_INTERNAL_ERROR; /* Shouldn't happen */ - KIRQL Irql; - - /* If the interrupt happens before this is setup, the key - * was already in the buffer. Too bad! */ - if (!DevExt->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - if (Idle == DevExt->Packet.State && - DevExt->PacketComplete) { - FinishIrp = TRUE; - Result = DevExt->PacketResult; - DevExt->PacketComplete = FALSE; - } - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, - Irql); - - if (!FinishIrp) - return; - - if (DevExt->CurrentIrp) { - DevExt->CurrentIrp->IoStatus.Status = Result; - IoCompleteRequest(DevExt->CurrentIrp, IO_NO_INCREMENT); - IoStartNextPacket(DevExt->CurrentIrpDevice, FALSE); - DevExt->CurrentIrp = NULL; - DevExt->CurrentIrpDevice = NULL; - } -} - -VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context) -{ - KEVENT Event; - IO_STATUS_BLOCK IoStatus; + PFDO_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status; - PDEVICE_EXTENSION DevExt; - PFDO_DEVICE_EXTENSION FdoDevExt; - PIRP NewIrp; - PI8042_HOOK_WORKITEM WorkItemData = (PI8042_HOOK_WORKITEM)Context; - ULONG IoControlCode; - PVOID InputBuffer; - ULONG InputBufferLength; - BOOLEAN IsKbd; + DPRINT("i8042DeviceControl(%p %p)\n", DeviceObject, Irp); + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - DPRINT("HookWorkItem\n"); - - FdoDevExt = (PFDO_DEVICE_EXTENSION) - DeviceObject->DeviceExtension; - - DevExt = FdoDevExt->PortDevExt; - - if (WorkItemData->Target == DevExt->KeyboardData.ClassDeviceObject) { - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD; - InputBuffer = &DevExt->KeyboardHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD); - IsKbd = TRUE; - DPRINT ("is for keyboard.\n"); - } else if (WorkItemData->Target == DevExt->MouseData.ClassDeviceObject){ - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE; - InputBuffer = &DevExt->MouseHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE); - IsKbd = FALSE; - DPRINT ("is for mouse.\n"); - } else { - DPRINT1("I8042SendHookWorkItem: Can't find DeviceObject\n"); - WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; - goto hookworkitemdone; + switch (DeviceExtension->Type) + { + case Keyboard: + return i8042KbdDeviceControl(DeviceObject, Irp); + break; + default: + return IrpStub(DeviceObject, Irp); } - KeInitializeEvent(&Event, NotificationEvent, FALSE); + return Status; +} - NewIrp = IoBuildDeviceIoControlRequest( - IoControlCode, - WorkItemData->Target, - InputBuffer, - InputBufferLength, - NULL, - 0, - TRUE, - &Event, - &IoStatus); +static NTSTATUS NTAPI +i8042InternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDO_DEVICE_EXTENSION DeviceExtension; + ULONG ControlCode; + NTSTATUS Status; - if (!NewIrp) { - DPRINT("IOCTL_INTERNAL_(device)_CONNECT: " - "Can't allocate IRP\n"); - WorkItemData->Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - goto hookworkitemdone; - } + DPRINT("i8042InternalDeviceControl(%p %p)\n", DeviceObject, Irp); + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; -#if 0 - Status = IoCallDriver( - WorkItemData->Target, - NewIrp); - - if (STATUS_PENDING == Status) - KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); -#endif - - if (IsKbd) { - /* Call the hooked initialization if it exists */ - if (DevExt->KeyboardHook.InitializationRoutine) { - Status = DevExt->KeyboardHook.InitializationRoutine( - DevExt->KeyboardHook.Context, - DevExt, - I8042SynchReadPort, - I8042SynchWritePortKbd, - FALSE); - if (!NT_SUCCESS(Status)) { - WorkItemData->Irp->IoStatus.Status = Status; - goto hookworkitemdone; + switch (DeviceExtension->Type) + { + case Unknown: + { + ControlCode = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode; + switch (ControlCode) + { + case IOCTL_INTERNAL_KEYBOARD_CONNECT: + Status = i8042KbdInternalDeviceControl(DeviceObject, Irp); + break; + case IOCTL_INTERNAL_MOUSE_CONNECT: + Status = i8042MouInternalDeviceControl(DeviceObject, Irp); + break; + default: + DPRINT1("Unknown IO control code 0x%lx\n", ControlCode); + ASSERT(FALSE); + Status = STATUS_INVALID_DEVICE_REQUEST; + break; } + break; } - /* TODO: Now would be the right time to enable the interrupt */ - - DevExt->KeyboardClaimed = TRUE; - } else { - /* Mouse doesn't have this, but we need to send a - * reset to start the detection. - */ - KIRQL Irql; - - Irql = KeAcquireInterruptSpinLock( - DevExt->HighestDIRQLInterrupt); - - I8042Write(DevExt, I8042_CTRL_PORT, 0xD4); - I8042Write(DevExt, I8042_DATA_PORT, 0xFF); - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); + case Keyboard: + Status = i8042KbdInternalDeviceControl(DeviceObject, Irp); + break; + case Mouse: + Status = i8042MouInternalDeviceControl(DeviceObject, Irp); + break; + default: + DPRINT1("Unknown FDO type %u\n", DeviceExtension->Type); + ASSERT(FALSE); + Status = STATUS_INTERNAL_ERROR; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + break; } - WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS; - -hookworkitemdone: - WorkItemData->Irp->IoStatus.Information = 0; - IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT); - - IoFreeWorkItem(WorkItemData->WorkItem); - ExFreePool(WorkItemData); - DPRINT("HookWorkItem done\n"); -} - -static VOID STDCALL I8042StartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - if (!I8042StartIoKbd(DeviceObject, Irp)) { - DPRINT1("Unhandled StartIo!\n"); - } -} - -static NTSTATUS STDCALL I8042InternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - - DPRINT("InternalDeviceControl\n"); - - switch (FdoDevExt->Type) { - case Keyboard: - Status = I8042InternalDeviceControlKbd(DeviceObject, Irp); - break; - case Mouse: - Status = I8042InternalDeviceControlMouse(DeviceObject, Irp); - break; - } - - if (Status == STATUS_INVALID_DEVICE_REQUEST) { - DPRINT1("Invalid internal device request!\n"); - } - - if (Status != STATUS_PENDING) - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; } -static NTSTATUS STDCALL I8042CreateDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) +NTSTATUS NTAPI +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) { + PI8042_DRIVER_EXTENSION DriverExtension; + ULONG i; NTSTATUS Status; - DPRINT ("I8042CreateDispatch\n"); - - Status = STATUS_SUCCESS; - - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; -} - -static NTSTATUS STDCALL I8042BasicDetect(PDEVICE_EXTENSION DevExt) -{ - NTSTATUS Status; - UCHAR Value = 0; - ULONG Counter; - - DevExt->MouseExists = FALSE; - DevExt->KeyboardExists = FALSE; - - I8042Flush(); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_SELF_TEST)) { - DPRINT1("Writing KBD_SELF_TEST command failed\n"); - return STATUS_IO_TIMEOUT; + Status = IoAllocateDriverObjectExtension( + DriverObject, + DriverObject, + sizeof(I8042_DRIVER_EXTENSION), + (PVOID*)&DriverExtension); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status); + return Status; } + RtlZeroMemory(DriverExtension, sizeof(I8042_DRIVER_EXTENSION)); + KeInitializeSpinLock(&DriverExtension->Port.SpinLock); - // Wait longer? - Counter = 10; - do { - Status = I8042ReadDataWait(DevExt, &Value); - } while ((Counter--) && (STATUS_IO_TIMEOUT == Status)); - - if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to read KBD_SELF_TEST response, status 0x%x\n", - Status); + Status = RtlDuplicateUnicodeString( + RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, + RegistryPath, + &DriverExtension->RegistryPath); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); return Status; } - if (Value != 0x55) { - DPRINT1("Got %x instead of 55\n", Value); - return STATUS_IO_DEVICE_ERROR; - } - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= CCB_KBD_DISAB | CCB_MOUSE_DISAB; /* disable keyboard/mouse */ - Value &= ~(CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB); - /* don't enable keyboard and mouse interrupts */ - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - /* - * We used to send a KBD_LINE_TEST command here, but on at least HP - * Pavilion notebooks the response to that command was incorrect. - * So now we just assume that a keyboard is attached. - */ - DevExt->KeyboardExists = TRUE; - - if (I8042Write(DevExt, I8042_CTRL_PORT, MOUSE_LINE_TEST)) + Status = ReadRegistryEntries(RegistryPath, &DriverExtension->Port.Settings); + if (!NT_SUCCESS(Status)) { - Status = I8042ReadDataWait(DevExt, &Value); - if (NT_SUCCESS(Status) && Value == 0) - DevExt->MouseExists = TRUE; + DPRINT("ReadRegistryEntries() failed with status 0x%08lx\n", Status); + return Status; } + DriverObject->DriverExtension->AddDevice = i8042AddDevice; + DriverObject->DriverStartIo = i8042StartIo; + + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) + DriverObject->MajorFunction[i] = IrpStub; + + DriverObject->MajorFunction[IRP_MJ_CREATE] = i8042Create; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = i8042Cleanup; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl; + DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp; + + if (IsFirstStageSetup()) + return i8042AddLegacyKeyboard(DriverObject, RegistryPath); + return STATUS_SUCCESS; } - -static NTSTATUS STDCALL I8042Initialize(PDEVICE_EXTENSION DevExt) -{ - NTSTATUS Status; - - Status = I8042BasicDetect(DevExt); - if (!NT_SUCCESS(Status)) { - DPRINT1("Basic keyboard detection failed: %x\n", Status); - return Status; - } - - if (DevExt->MouseExists) { - DPRINT("Aux port detected\n"); - DevExt->MouseExists = I8042DetectMouse(DevExt); - } - - if (!DevExt->KeyboardExists) { - DPRINT("Keyboard port not detected\n"); - if (DevExt->Settings.Headless) - /* Act as if it exists regardless */ - DevExt->KeyboardExists = TRUE; - } else { - DPRINT("Keyboard port detected\n"); - DevExt->KeyboardExists = I8042DetectKeyboard(DevExt); - } - - if (DevExt->KeyboardExists) { - DPRINT("Keyboard detected\n"); - I8042KeyboardEnable(DevExt); - I8042KeyboardEnableInterrupt(DevExt); - } - - if (DevExt->MouseExists) { - DPRINT("Mouse detected\n"); - I8042MouseEnable(DevExt); - } - - return STATUS_SUCCESS; -} - -static NTSTATUS -AddRegistryEntry( - IN PCWSTR PortTypeName, - IN PUNICODE_STRING DeviceName, - IN PCWSTR RegistryPath) -{ - UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP"); - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hDeviceMapKey = (HANDLE)-1; - HANDLE hPortKey = (HANDLE)-1; - UNICODE_STRING PortTypeNameU; - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - RtlInitUnicodeString(&PortTypeNameU, PortTypeName); - InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL); - Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - Status = STATUS_SUCCESS; - -cleanup: - if (hDeviceMapKey != (HANDLE)-1) - ZwClose(hDeviceMapKey); - if (hPortKey != (HANDLE)-1) - ZwClose(hPortKey); - return Status; -} - -static NTSTATUS STDCALL I8042AddDevice(PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT Pdo) -{ - UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042"); - UNICODE_STRING MouseName = RTL_CONSTANT_STRING(L"\\Device\\PointerPort8042"); - ULONG MappedIrqKeyboard = 0, MappedIrqMouse = 0; - KIRQL DirqlKeyboard = 0; - KIRQL DirqlMouse = 0; - KIRQL DirqlMax; - KAFFINITY Affinity; - NTSTATUS Status; - PDEVICE_EXTENSION DevExt; - PFDO_DEVICE_EXTENSION FdoDevExt; - PDEVICE_OBJECT Fdo; - - DPRINT("I8042AddDevice\n"); - - if (Pdo != NULL) - { - /* Device detected by pnpmgr. Ignore it, as we already have - * detected the keyboard and mouse at first call */ - return STATUS_UNSUCCESSFUL; - } - - Status = IoCreateDevice(DriverObject, - sizeof(DEVICE_EXTENSION), - NULL, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - - if (!NT_SUCCESS(Status)) - return Status; - - DevExt = Fdo->DeviceExtension; - - RtlZeroMemory(DevExt, sizeof(DEVICE_EXTENSION)); - - I8042ReadRegistry(DriverObject, DevExt); - - KeInitializeSpinLock(&DevExt->SpinLock); - InitializeListHead(&DevExt->BusDevices); - - KeInitializeDpc(&DevExt->DpcKbd, - I8042DpcRoutineKbd, - DevExt); - - KeInitializeDpc(&DevExt->DpcMouse, - I8042DpcRoutineMouse, - DevExt); - - KeInitializeDpc(&DevExt->DpcMouseTimeout, - I8042DpcRoutineMouseTimeout, - DevExt); - - KeInitializeTimer(&DevExt->TimerMouseTimeout); - - Status = I8042Initialize(DevExt); - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - if (!NT_SUCCESS(STATUS_SUCCESS)) { - DPRINT1("Initialization failure: %x\n", Status); - return Status; - } - - if (DevExt->KeyboardExists) { - MappedIrqKeyboard = HalGetInterruptVector(Internal, - 0, - 0, - KEYBOARD_IRQ, - &DirqlKeyboard, - &Affinity); - - Status = IoCreateDevice(DriverObject, - sizeof(FDO_DEVICE_EXTENSION), - &DeviceName, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - - if (NT_SUCCESS(Status)) - { - AddRegistryEntry(L"KeyboardPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt"); - FdoDevExt = Fdo->DeviceExtension; - - RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION)); - - FdoDevExt->PortDevExt = DevExt; - FdoDevExt->Type = Keyboard; - FdoDevExt->DeviceObject = Fdo; - - Fdo->Flags |= DO_BUFFERED_IO; - - DevExt->DebugWorkItem = IoAllocateWorkItem(Fdo); - DevExt->KeyboardObject = Fdo; - - DevExt->KeyboardBuffer = ExAllocatePoolWithTag( - NonPagedPool, - DevExt->KeyboardAttributes.InputDataQueueLength * - sizeof(KEYBOARD_INPUT_DATA), - TAG_I8042); - - if (!DevExt->KeyboardBuffer) { - DPRINT1("No memory for keyboardbuffer\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - InsertTailList(&DevExt->BusDevices, &FdoDevExt->BusDevices); - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - } - else - DevExt->KeyboardExists = FALSE; - } - - if (DevExt->MouseExists) { - MappedIrqMouse = HalGetInterruptVector(Internal, - 0, - 0, - MOUSE_IRQ, - &DirqlMouse, - &Affinity); - - Status = IoCreateDevice(DriverObject, - sizeof(FDO_DEVICE_EXTENSION), - &MouseName, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - - if (NT_SUCCESS(Status)) - { - AddRegistryEntry(L"PointerPort", &MouseName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt"); - FdoDevExt = Fdo->DeviceExtension; - - RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION)); - - FdoDevExt->PortDevExt = DevExt; - FdoDevExt->Type = Mouse; - FdoDevExt->DeviceObject = Fdo; - - Fdo->Flags |= DO_BUFFERED_IO; - DevExt->MouseObject = Fdo; - - DevExt->MouseBuffer = ExAllocatePoolWithTag( - NonPagedPool, - DevExt->MouseAttributes.InputDataQueueLength * - sizeof(MOUSE_INPUT_DATA), - TAG_I8042); - - if (!DevExt->MouseBuffer) { - ExFreePoolWithTag(DevExt->KeyboardBuffer, TAG_I8042); - DPRINT1("No memory for mouse buffer\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - InsertTailList(&DevExt->BusDevices, &FdoDevExt->BusDevices); - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - } - else - DevExt->MouseExists = FALSE; - } - - if (DirqlKeyboard > DirqlMouse) - DirqlMax = DirqlKeyboard; - else - DirqlMax = DirqlMouse; - - if (DevExt->KeyboardExists) { - Status = IoConnectInterrupt(&DevExt->KeyboardInterruptObject, - I8042InterruptServiceKbd, - (PVOID)DevExt, - &DevExt->SpinLock, - MappedIrqKeyboard, - DirqlKeyboard, - DirqlMax, - LevelSensitive, - FALSE, - Affinity, - FALSE); - - DPRINT("Keyboard Irq Status: %x\n", Status); - } - - if (DevExt->MouseExists) { - Status = IoConnectInterrupt(&DevExt->MouseInterruptObject, - I8042InterruptServiceMouse, - (PVOID)DevExt, - &DevExt->SpinLock, - MappedIrqMouse, - DirqlMouse, - DirqlMax, - LevelSensitive, - FALSE, - Affinity, - FALSE); - - DPRINT("Mouse Irq Status: %x\n", Status); - } - - if (DirqlKeyboard > DirqlMouse) - DevExt->HighestDIRQLInterrupt = DevExt->KeyboardInterruptObject; - else - DevExt->HighestDIRQLInterrupt = DevExt->MouseInterruptObject; - - DPRINT("I8042AddDevice done\n"); - - return(STATUS_SUCCESS); -} - -NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath) -/* - * FUNCTION: Module entry point - */ -{ - DPRINT("I8042 Driver 0.0.1\n"); - - I8042RegistryPath.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters"); - I8042RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, - I8042RegistryPath.MaximumLength, - TAG_I8042); - if (I8042RegistryPath.Buffer == NULL) { - - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlCopyUnicodeString(&I8042RegistryPath, RegistryPath); - RtlAppendUnicodeToString(&I8042RegistryPath, L"\\Parameters"); - I8042RegistryPath.Buffer[I8042RegistryPath.Length / sizeof(WCHAR)] = 0; - - - - DriverObject->MajorFunction[IRP_MJ_CREATE] = I8042CreateDispatch; - DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = - I8042InternalDeviceControl; - - DriverObject->DriverStartIo = I8042StartIo; - DriverObject->DriverExtension->AddDevice = I8042AddDevice; - - return(STATUS_SUCCESS); -} diff --git a/reactos/drivers/input/i8042prt/i8042prt.h b/reactos/drivers/input/i8042prt/i8042prt.h index 9abf7a91883..9df68e61f2b 100644 --- a/reactos/drivers/input/i8042prt/i8042prt.h +++ b/reactos/drivers/input/i8042prt/i8042prt.h @@ -1,39 +1,45 @@ -#ifndef _I8042DRV_H -#define _I8042DRV_H +#ifndef _I8042PRT_H_ +#define _I8042PRT_H_ -#include +#include #include #include - -#ifdef _MSC_VER - #define STDCALL - #define DDKAPI -#endif - -#define KEYBOARD_IRQ 1 -#define MOUSE_IRQ 12 -#define KBD_BUFFER_SIZE 32 - -#define WHEEL_DELTA 120 +#include +#include +#include /*----------------------------------------------------- - * DeviceExtension + * Structures * --------------------------------------------------*/ -typedef struct _COMMAND_CONTEXT + +typedef enum { - int NumInput; - int CurInput; - UCHAR * Input; - int NumOutput; - int CurOutput; - UCHAR * Output; - NTSTATUS Status; + dsStopped, + dsStarted, + dsPaused, + dsRemoved, + dsSurpriseRemoved +} DEVICE_STATE; - BOOLEAN GotAck; - KEVENT Event; - - PVOID DevExt; -} COMMAND_CONTEXT, *PCOMMAND_CONTEXT; +typedef struct _I8042_SETTINGS +{ + /* Registry settings */ + ULONG KeyboardDataQueueSize; /* done */ + UNICODE_STRING KeyboardDeviceBaseName; + ULONG MouseDataQueueSize; /* done */ + ULONG MouseResolution; + ULONG MouseSynchIn100ns; + ULONG NumberOfButtons; + UNICODE_STRING PointerDeviceBaseName; + ULONG PollStatusIterations; /* done */ + ULONG OverrideKeyboardType; + ULONG OverrideKeyboardSubtype; + ULONG PollingIterations; /* done */ + ULONG PollingIterationsMaximum; + ULONG ResendIterations; /* done */ + ULONG SampleRate; + ULONG CrashOnCtrlScroll; /* done */ +} I8042_SETTINGS, *PI8042_SETTINGS; typedef enum _MOUSE_TIMEOUT_STATE { @@ -42,108 +48,47 @@ typedef enum _MOUSE_TIMEOUT_STATE TimeoutCancel } MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE; -/* TODO: part of this should be in the _ATTRIBUTES structs instead */ -typedef struct _I8042_SETTINGS +typedef struct _INTERRUPT_DATA { - ULONG Headless; /* done */ - ULONG CrashScroll; - ULONG CrashSysRq; /* done */ - ULONG ReportResetErrors; - ULONG PollStatusIterations; /* done */ - ULONG ResendIterations; /* done */ - ULONG PollingIterations; - ULONG PollingIterationsMaximum; - ULONG OverrideKeyboardType; - ULONG OverrideKeyboardSubtype; - ULONG MouseResendStallTime; - ULONG MouseSynchIn100ns; /* done */ - ULONG MouseResolution; /* done */ - ULONG NumberOfButtons; - ULONG EnableWheelDetection; -} I8042_SETTINGS, *PI8042_SETTINGS; + PKINTERRUPT Object; + ULONG Vector; + KIRQL Dirql; + KINTERRUPT_MODE InterruptMode; + BOOLEAN ShareInterrupt; + KAFFINITY Affinity; +} INTERRUPT_DATA, *PINTERRUPT_DATA; -typedef enum _I8042_MOUSE_TYPE +#define WHEEL_DELTA 120 + +struct _I8042_KEYBOARD_EXTENSION; +typedef struct _I8042_KEYBOARD_EXTENSION *PI8042_KEYBOARD_EXTENSION; +struct _I8042_MOUSE_EXTENSION; +typedef struct _I8042_MOUSE_EXTENSION *PI8042_MOUSE_EXTENSION; + +/* PORT_DEVICE_EXTENSION.Flags */ +#define KEYBOARD_PRESENT 0x01 /* A keyboard is attached */ +#define MOUSE_PRESENT 0x02 /* A mouse is attached */ +#define KEYBOARD_CONNECTED 0x04 /* Keyboard received IOCTL_INTERNAL_KEYBOARD_CONNECT */ +#define MOUSE_CONNECTED 0x08 /* Mouse received IOCTL_INTERNAL_MOUSE_CONNECT */ +#define KEYBOARD_STARTED 0x04 /* Keyboard FDO received IRP_MN_START_DEVICE */ +#define MOUSE_STARTED 0x08 /* Mouse FDO received IRP_MN_START_DEVICE */ +#define KEYBOARD_INITIALIZED 0x10 /* Keyboard interrupt is connected */ +#define MOUSE_INITIALIZED 0x20 /* Mouse interrupt is connected */ + +typedef struct _PORT_DEVICE_EXTENSION { - GenericPS2, - Intellimouse, - IntellimouseExplorer, - Ps2pp -} I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE; + PUCHAR DataPort; /* Usually 0x60 */ + PUCHAR ControlPort; /* Usually 0x64 */ + I8042_SETTINGS Settings; + ULONG Flags; -typedef enum _I8042_DEVICE_TYPE -{ - Keyboard, - Mouse -} I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE; - -typedef struct _I8042_DEVICE -{ - LIST_ENTRY ListEntry; - PDEVICE_OBJECT Pdo; -} I8042_DEVICE, *PI8042_DEVICE; - -typedef struct _DEVICE_EXTENSION -{ - PDEVICE_OBJECT KeyboardObject; - PDEVICE_OBJECT MouseObject; - - CONNECT_DATA KeyboardData; - CONNECT_DATA MouseData; - - BOOLEAN KeyboardExists; - BOOLEAN KeyboardIsAT; - BOOLEAN MouseExists; - - BOOLEAN KeyboardClaimed; - BOOLEAN MouseClaimed; - - ULONG BusNumber; - LIST_ENTRY BusDevices; - - INTERNAL_I8042_START_INFORMATION KeyboardStartInformation; - INTERNAL_I8042_START_INFORMATION MouseStartInformation; - - INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; - INTERNAL_I8042_HOOK_MOUSE MouseHook; - - PKINTERRUPT KeyboardInterruptObject; - PKINTERRUPT MouseInterruptObject; + PI8042_KEYBOARD_EXTENSION KeyboardExtension; + INTERRUPT_DATA KeyboardInterrupt; + PI8042_MOUSE_EXTENSION MouseExtension; + INTERRUPT_DATA MouseInterrupt; PKINTERRUPT HighestDIRQLInterrupt; KSPIN_LOCK SpinLock; - KDPC DpcKbd; - KDPC DpcMouse; - - KTIMER TimerMouseTimeout; - KDPC DpcMouseTimeout; - MOUSE_TIMEOUT_STATE MouseTimeoutState; - BOOLEAN MouseTimeoutActive; - - KEYBOARD_ATTRIBUTES KeyboardAttributes; - KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; - KEYBOARD_TYPEMATIC_PARAMETERS KeyboardTypematic; - - BOOLEAN WantAck; - BOOLEAN WantOutput; - BOOLEAN SignalEvent; - - KEYBOARD_SCAN_STATE KeyboardScanState; - BOOLEAN KeyComplete; - KEYBOARD_INPUT_DATA *KeyboardBuffer; - ULONG KeysInBuffer; - - MOUSE_ATTRIBUTES MouseAttributes; - - MOUSE_STATE MouseState; - BOOLEAN MouseComplete; - MOUSE_RESET_SUBSTATE MouseResetState; - MOUSE_INPUT_DATA *MouseBuffer; - ULONG MouseInBuffer; - USHORT MouseButtonState; - ULARGE_INTEGER MousePacketStartTime; - - UCHAR MouseLogiBuffer[3]; - UCHAR MouseLogitechID; - I8042_MOUSE_TYPE MouseType; + KIRQL HighestDirql; OUTPUT_PACKET Packet; ULONG PacketResends; @@ -154,225 +99,390 @@ typedef struct _DEVICE_EXTENSION PIRP CurrentIrp; PDEVICE_OBJECT CurrentIrpDevice; +} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION; - /* registry config values */ - I8042_SETTINGS Settings; +typedef struct _I8042_DRIVER_EXTENSION +{ + UNICODE_STRING RegistryPath; - /* Debugger stuff */ - BOOLEAN TabPressed; - ULONG DebugKey; - PIO_WORKITEM DebugWorkItem; -} DEVICE_EXTENSION, *PDEVICE_EXTENSION; + PORT_DEVICE_EXTENSION Port; +} I8042_DRIVER_EXTENSION, *PI8042_DRIVER_EXTENSION; + +typedef enum _I8042_DEVICE_TYPE +{ + Unknown, + Keyboard, + Mouse, + PhysicalDeviceObject +} I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE; typedef struct _FDO_DEVICE_EXTENSION { - PDEVICE_EXTENSION PortDevExt; I8042_DEVICE_TYPE Type; - PDEVICE_OBJECT DeviceObject; + // Associated device object (FDO) + PDEVICE_OBJECT Fdo; + // Associated device object (PDO) + PDEVICE_OBJECT Pdo; + // Lower device object + PDEVICE_OBJECT LowerDevice; + // Current state of the driver + DEVICE_STATE PnpState; - LIST_ENTRY BusDevices; + PPORT_DEVICE_EXTENSION PortDeviceExtension; } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; +typedef struct _I8042_KEYBOARD_EXTENSION +{ + FDO_DEVICE_EXTENSION Common; + CONNECT_DATA KeyboardData; + INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; + KDPC DpcKeyboard; + + KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; + + KEYBOARD_SCAN_STATE KeyboardScanState; + BOOLEAN KeyComplete; + PKEYBOARD_INPUT_DATA KeyboardBuffer; + ULONG KeysInBuffer; + + /* Power keys items */ + ULONG ReportedCaps; + ULONG NewCaps; + ULONG LastPowerKey; + UNICODE_STRING PowerInterfaceName; + PIO_WORKITEM PowerWorkItem; + PIRP PowerIrp; + + /* Debug items */ + ULONG ComboPosition; + PIO_WORKITEM DebugWorkItem; +#ifdef __REACTOS__ + ULONG DebugKey; + BOOLEAN TabPressed; +#endif +} I8042_KEYBOARD_EXTENSION; + +typedef enum _I8042_MOUSE_TYPE +{ + GenericPS2, + Intellimouse, + IntellimouseExplorer, + Ps2pp +} I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE; + +typedef struct _I8042_MOUSE_EXTENSION +{ + FDO_DEVICE_EXTENSION Common; + CONNECT_DATA MouseData; + INTERNAL_I8042_HOOK_MOUSE MouseHook; + KDPC DpcMouse; + + MOUSE_ATTRIBUTES MouseAttributes; + + MOUSE_STATE MouseState; + BOOLEAN MouseComplete; + MOUSE_RESET_SUBSTATE MouseResetState; + PMOUSE_INPUT_DATA MouseBuffer; + ULONG MouseInBuffer; + USHORT MouseButtonState; + ULARGE_INTEGER MousePacketStartTime; + + KTIMER TimerMouseTimeout; + KDPC DpcMouseTimeout; + MOUSE_TIMEOUT_STATE MouseTimeoutState; + BOOLEAN MouseTimeoutActive; + + UCHAR MouseLogiBuffer[3]; + I8042_MOUSE_TYPE MouseType; +} I8042_MOUSE_EXTENSION; + typedef struct _I8042_HOOK_WORKITEM { PIO_WORKITEM WorkItem; - PDEVICE_OBJECT Target; PIRP Irp; } I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM; -/* +/*----------------------------------------------------- * Some defines - */ -#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) -#define TAG_I8042 TAG('8', '0', '4', '2') + * --------------------------------------------------*/ -#define KBD_WRAP_MASK 0x1F +#define MAX(a, b) ((a) >= (b) ? (a) : (b)) -#define ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) -#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) +#define KEYBOARD_POWER_CODE 0x5E +#define KEYBOARD_SLEEP_CODE 0x5F +#define KEYBOARD_WAKE_CODE 0x63 - -/* - * Keyboard controller ports - */ - -#define I8042_DATA_PORT ((PUCHAR)0x60) -#define I8042_CTRL_PORT ((PUCHAR)0x64) - - -/* +/*----------------------------------------------------- * Controller commands - */ + * --------------------------------------------------*/ #define KBD_READ_MODE 0x20 #define KBD_WRITE_MODE 0x60 -#define KBD_SELF_TEST 0xAA #define KBD_LINE_TEST 0xAB -#define KBD_CTRL_ENABLE 0xAE - #define MOUSE_LINE_TEST 0xA9 -#define MOUSE_CTRL_ENABLE 0xA8 +#define CTRL_SELF_TEST 0xAA +#define CTRL_WRITE_MOUSE 0xD4 -#define KBD_READ_OUTPUT_PORT 0xD0 -#define KBD_WRITE_OUTPUT_PORT 0xD1 - -/* +/*----------------------------------------------------- * Keyboard commands - */ + * --------------------------------------------------*/ -#define KBD_SET_LEDS 0xED -#define KBD_GET_ID 0xF2 -#define KBD_ENABLE 0xF4 -#define KBD_DISABLE 0xF5 -#define KBD_RESET 0xFF +#define KBD_CMD_SET_LEDS 0xED +#define KBD_CMD_GET_ID 0xF2 +/*----------------------------------------------------- + * Keyboard responses + * --------------------------------------------------*/ -/* - * Keyboard responces - */ - -#define KBD_BATCC 0xAA #define KBD_ACK 0xFA #define KBD_NACK 0xFC #define KBD_RESEND 0xFE -/* +/*----------------------------------------------------- * Controller status register bits - */ + * --------------------------------------------------*/ #define KBD_OBF 0x01 #define KBD_IBF 0x02 -#define KBD_AUX 0x10 -#define KBD_GTO 0x40 +#define MOU_OBF 0x20 #define KBD_PERR 0x80 -/* +/*----------------------------------------------------- * Controller command byte bits - */ + * --------------------------------------------------*/ + #define CCB_KBD_INT_ENAB 0x01 #define CCB_MOUSE_INT_ENAB 0x02 #define CCB_SYSTEM_FLAG 0x04 -#define CCB_IGN_KEY_LOCK 0x08 #define CCB_KBD_DISAB 0x10 #define CCB_MOUSE_DISAB 0x20 #define CCB_TRANSLATE 0x40 - -/* +/*----------------------------------------------------- * LED bits - */ + * --------------------------------------------------*/ #define KBD_LED_SCROLL 0x01 #define KBD_LED_NUM 0x02 #define KBD_LED_CAPS 0x04 -/* +/*----------------------------------------------------- + * Mouse commands + * --------------------------------------------------*/ + +#define MOU_CMD_GET_ID 0xF2 +#define MOU_CMD_RESET 0xFF + +/*----------------------------------------------------- * Mouse responses - */ + * --------------------------------------------------*/ + #define MOUSE_ACK 0xFA #define MOUSE_ERROR 0xFC #define MOUSE_NACK 0xFE -/* i8042prt.c */ -extern UNICODE_STRING I8042RegistryPath; +/*----------------------------------------------------- + * Prototypes + * --------------------------------------------------*/ -NTSTATUS I8042ReadData(UCHAR *Data); +/* createclose.c */ -NTSTATUS I8042ReadStatus(UCHAR *Status); +VOID NTAPI +i8042SendHookWorkItem( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context); -NTSTATUS I8042ReadDataWait(PDEVICE_EXTENSION DevExt, UCHAR *Data); +NTSTATUS NTAPI +i8042Create( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); -VOID I8042Flush(); +NTSTATUS NTAPI +i8042Cleanup( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); -VOID STDCALL I8042IsrWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Value, - UCHAR SelectCmd); - -NTSTATUS STDCALL I8042SynchWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Port, - UCHAR Value, - BOOLEAN WaitForAck); - -NTSTATUS STDCALL I8042StartPacket(PDEVICE_EXTENSION DevExt, - PDEVICE_OBJECT Device, - PUCHAR Bytes, - ULONG ByteCount, - PIRP Irp); - -BOOLEAN STDCALL I8042PacketIsr(PDEVICE_EXTENSION DevExt, - UCHAR Output); - -VOID I8042PacketDpc(PDEVICE_EXTENSION DevExt); - -VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context); - -BOOLEAN I8042Write(PDEVICE_EXTENSION DevExt, PUCHAR addr, UCHAR data); - -NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath); +NTSTATUS NTAPI +i8042Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); /* keyboard.c */ -VOID STDCALL I8042IsrWritePortKbd(PVOID Context, - UCHAR Value); -NTSTATUS STDCALL I8042SynchWritePortKbd(PVOID Context, - UCHAR Value, - BOOLEAN WaitForAck); +NTSTATUS NTAPI +i8042SynchWritePortKbd( + IN PVOID Context, + IN UCHAR Value, + IN BOOLEAN WaitForAck); -BOOLEAN STDCALL I8042InterruptServiceKbd(struct _KINTERRUPT *Interrupt, - VOID * Context); +BOOLEAN +i8042KbdStartIo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); -VOID STDCALL I8042DpcRoutineKbd(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); +NTSTATUS +i8042KbdDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); -BOOLEAN STDCALL I8042StartIoKbd(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS +i8042KbdInternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); -NTSTATUS STDCALL I8042InternalDeviceControlKbd(PDEVICE_OBJECT DeviceObject, - PIRP Irp); +BOOLEAN NTAPI +i8042KbdInterruptService( + IN PKINTERRUPT Interrupt, + PVOID Context); -BOOLEAN STDCALL I8042KeyboardEnable(PDEVICE_EXTENSION DevExt); +/* i8042prt.c */ -BOOLEAN STDCALL I8042KeyboardEnableInterrupt(PDEVICE_EXTENSION DevExt); +NTSTATUS NTAPI +i8042AddDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT Pdo); -BOOLEAN STDCALL I8042DetectKeyboard(PDEVICE_EXTENSION DevExt); +BOOLEAN +i8042PacketIsr( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR Output); -/* registry.c */ -VOID STDCALL I8042ReadRegistry(PDRIVER_OBJECT DriverObject, - PDEVICE_EXTENSION DevExt); +NTSTATUS +i8042StartPacket( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, + IN PUCHAR Bytes, + IN ULONG ByteCount, + IN PIRP Irp); + +/* misc.c */ + +NTSTATUS NTAPI +ForwardIrpAndForget( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +ForwardIrpAndWait( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); /* mouse.c */ -VOID STDCALL I8042DpcRoutineMouse(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); -VOID STDCALL I8042DpcRoutineMouseTimeout(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); +VOID +i8042MouHandle( + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN UCHAR Output); -BOOLEAN STDCALL I8042InterruptServiceMouse(struct _KINTERRUPT *Interrupt, - VOID *Context); +VOID +i8042MouHandleButtons( + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN USHORT Mask); -NTSTATUS STDCALL I8042InternalDeviceControlMouse(PDEVICE_OBJECT DeviceObject, - PIRP Irp); +NTSTATUS +i8042MouInitialize( + IN PI8042_MOUSE_EXTENSION DeviceExtension); -VOID STDCALL I8042QueueMousePacket(PVOID Context); +NTSTATUS +i8042MouInternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); -VOID STDCALL I8042MouseHandleButtons(PDEVICE_EXTENSION DevExt, - USHORT Mask); +BOOLEAN NTAPI +i8042MouInterruptService( + IN PKINTERRUPT Interrupt, + PVOID Context); -VOID STDCALL I8042MouseHandle(PDEVICE_EXTENSION DevExt, - UCHAR Output); +VOID NTAPI +i8042MouQueuePacket( + IN PVOID Context); -BOOLEAN STDCALL I8042MouseEnable(PDEVICE_EXTENSION DevExt); -BOOLEAN STDCALL I8042MouseDisable(PDEVICE_EXTENSION DevExt); -BOOLEAN STDCALL I8042DetectMouse(PDEVICE_EXTENSION DevExt); +/* pnp.c */ + +BOOLEAN +i8042ChangeMode( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR FlagsToDisable, + IN UCHAR FlagsToEnable); + +NTSTATUS NTAPI +i8042Pnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); /* ps2pp.c */ -VOID I8042MouseHandlePs2pp(PDEVICE_EXTENSION DevExt, UCHAR Input); +VOID +i8042MouHandlePs2pp( + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN UCHAR Input); -#endif // _KEYBOARD_H_ +/* readwrite.c */ + +VOID +i8042Flush( + IN PPORT_DEVICE_EXTENSION DeviceExtension); + +VOID +i8042IsrWritePort( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR Value, + IN UCHAR SelectCmd OPTIONAL); + +NTSTATUS +i8042ReadData( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR StatusFlags, + OUT PUCHAR Data); +#define i8042ReadKeyboardData(DeviceExtension, Data) \ + i8042ReadData(DeviceExtension, KBD_OBF, Data) +#define i8042ReadMouseData(DeviceExtension, Data) \ + i8042ReadData(DeviceExtension, MOU_OBF, Data) + +NTSTATUS +i8042ReadDataWait( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + OUT PUCHAR Data); + +NTSTATUS +i8042ReadStatus( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + OUT PUCHAR Status); + +NTSTATUS NTAPI +i8042SynchReadPort( + IN PVOID Context, + IN PUCHAR Value, + IN BOOLEAN WaitForAck); + +NTSTATUS NTAPI +i8042SynchWritePort( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR Port, + IN UCHAR Value, + IN BOOLEAN WaitForAck); + +BOOLEAN +i8042Write( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN PUCHAR addr, + IN UCHAR data); + +/* registry.c */ + +NTSTATUS +ReadRegistryEntries( + IN PUNICODE_STRING RegistryPath, + OUT PI8042_SETTINGS Settings); + +/* setup.c */ + +BOOLEAN +IsFirstStageSetup( + VOID); + +NTSTATUS +i8042AddLegacyKeyboard( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath); + +#endif // _I8042PRT_H_ diff --git a/reactos/drivers/input/i8042prt/i8042prt.rbuild b/reactos/drivers/input/i8042prt/i8042prt.rbuild index ca4085c16de..1c4a264012b 100644 --- a/reactos/drivers/input/i8042prt/i8042prt.rbuild +++ b/reactos/drivers/input/i8042prt/i8042prt.rbuild @@ -1,14 +1,18 @@ - . ntoskrnl hal + createclose.c i8042prt.c keyboard.c + misc.c mouse.c + pnp.c ps2pp.c + readwrite.c registry.c + setup.c i8042prt.rc diff --git a/reactos/drivers/input/i8042prt/i8042prt.rc b/reactos/drivers/input/i8042prt/i8042prt.rc index 6c44176265e..eaed77a9427 100644 --- a/reactos/drivers/input/i8042prt/i8042prt.rc +++ b/reactos/drivers/input/i8042prt/i8042prt.rc @@ -1,5 +1,5 @@ #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "I8042 Port Device Driver\0" +#define REACTOS_STR_FILE_DESCRIPTION "i8042 Port Device Driver\0" #define REACTOS_STR_INTERNAL_NAME "i8042prt\0" #define REACTOS_STR_ORIGINAL_FILENAME "i8042prt.sys\0" #include diff --git a/reactos/drivers/input/i8042prt/keyboard.c b/reactos/drivers/input/i8042prt/keyboard.c index a301d2ee129..132ef7bd1ae 100644 --- a/reactos/drivers/input/i8042prt/keyboard.c +++ b/reactos/drivers/input/i8042prt/keyboard.c @@ -1,12 +1,12 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/keyboard.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * keyboard specifics - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/keyboard.c + * PURPOSE: Keyboard specific functions + * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) + Copyright Jason Filby (jasonfilby@yahoo.com) + Copyright Martijn Vernooij (o112w8r02@sneakemail.com) + Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) */ /* INCLUDES ****************************************************************/ @@ -18,11 +18,7 @@ /* GLOBALS *******************************************************************/ -static UCHAR TypematicTable[] = { - 0x00, 0x00, 0x00, 0x05, 0x08, 0x0B, 0x0D, 0x0F, 0x10, 0x12, /* 0-9 */ - 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1A, /* 10-19 */ - 0x1B, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E }; - +/* This structure starts with the same layout as KEYBOARD_INDICATOR_TRANSLATION */ typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION { USHORT NumberOfIndicatorKeys; INDICATOR_LIST IndicatorList[3]; @@ -33,101 +29,803 @@ static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = { 3, { {0x45, KEYBOARD_NUM_LOCK_ON}, {0x46, KEYBOARD_SCROLL_LOCK_ON}}}; -static VOID STDCALL I8042DebugWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context); - /* FUNCTIONS *****************************************************************/ +#ifdef __REACTOS__ +/* Debug stuff */ +VOID NTAPI +KdpServiceDispatcher(IN ULONG Code, IN PVOID Context1, IN PVOID Context2); +#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) + +static VOID NTAPI +i8042DebugWorkItem( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PI8042_KEYBOARD_EXTENSION DeviceExtension; + ULONG Key; + + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; + Key = InterlockedExchange((PLONG)&DeviceExtension->DebugKey, 0); + + DPRINT("Debug key: 0x%02x\n", Key); + + if (!Key) + return; + + /* We hope kernel would understand this. If + * that's not the case, nothing would happen. + */ + KdpServiceDispatcher(TAG('R', 'o', 's', ' '), (PVOID)Key, NULL); +} +#endif + /* * These functions are callbacks for filter driver custom interrupt * service routines. */ -VOID STDCALL I8042IsrWritePortKbd(PVOID Context, - UCHAR Value) +/*static VOID NTAPI +i8042KbdIsrWritePort( + IN PVOID Context, + IN UCHAR Value) { - I8042IsrWritePort(Context, Value, 0); -} + PI8042_KEYBOARD_EXTENSION DeviceExtension; -static VOID STDCALL I8042QueueKeyboardPacket(PVOID Context) + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; + + if (DeviceExtension->KeyboardHook.IsrWritePort) + { + DeviceExtension->KeyboardHook.IsrWritePort( + DeviceExtension->KeyboardHook.CallContext, + Value); + } + else + i8042IsrWritePort(Context, Value, 0); +}*/ + +static VOID NTAPI +i8042KbdQueuePacket( + IN PVOID Context) { - PDEVICE_OBJECT DeviceObject = Context; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; + PI8042_KEYBOARD_EXTENSION DeviceExtension; - DevExt->KeyComplete = TRUE; - DevExt->KeysInBuffer++; - if (DevExt->KeysInBuffer > - DevExt->KeyboardAttributes.InputDataQueueLength) { + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; + + if (DeviceExtension->KeyboardHook.QueueKeyboardPacket) + { + DeviceExtension->KeyboardHook.QueueKeyboardPacket( + DeviceExtension->KeyboardHook.CallContext); + return; + } + + DeviceExtension->KeyComplete = TRUE; + DeviceExtension->KeysInBuffer++; + if (DeviceExtension->KeysInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize) + { DPRINT1("Keyboard buffer overflow\n"); - DevExt->KeysInBuffer--; + DeviceExtension->KeysInBuffer--; } DPRINT("Irq completes key\n"); - KeInsertQueueDpc(&DevExt->DpcKbd, DevExt, NULL); + KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); } /* * These functions are callbacks for filter driver custom * initialization routines. */ -NTSTATUS STDCALL I8042SynchWritePortKbd(PVOID Context, - UCHAR Value, - BOOLEAN WaitForAck) +NTSTATUS NTAPI +i8042SynchWritePortKbd( + IN PVOID Context, + IN UCHAR Value, + IN BOOLEAN WaitForAck) { - return I8042SynchWritePort((PDEVICE_EXTENSION)Context, - 0, - Value, - WaitForAck); + return i8042SynchWritePort( + (PPORT_DEVICE_EXTENSION)Context, + 0, + Value, + WaitForAck); } -BOOLEAN STDCALL I8042InterruptServiceKbd(struct _KINTERRUPT *Interrupt, - VOID * Context) +/* + * Process the keyboard internal device requests + * returns FALSE if it doesn't understand the + * call so someone else can handle it. + */ +BOOLEAN +i8042KbdStartIo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - UCHAR Output; - UCHAR PortStatus; + PIO_STACK_LOCATION Stack; + PI8042_KEYBOARD_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + BOOLEAN Result = FALSE; + + Stack = IoGetCurrentIrpStackLocation(Irp); + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_KEYBOARD_SET_INDICATORS: + { + DPRINT("IOCTL_KEYBOARD_SET_INDICATORS\n"); + + PortDeviceExtension->PacketBuffer[0] = KBD_CMD_SET_LEDS; + PortDeviceExtension->PacketBuffer[1] = 0; + if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON) + PortDeviceExtension->PacketBuffer[1] |= KBD_LED_CAPS; + + if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON) + PortDeviceExtension->PacketBuffer[1] |= KBD_LED_NUM; + + if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON) + PortDeviceExtension->PacketBuffer[1] |= KBD_LED_SCROLL; + + i8042StartPacket( + PortDeviceExtension, + &DeviceExtension->Common, + PortDeviceExtension->PacketBuffer, + 2, + Irp); + break; + } + default: + { + DPRINT("Unknown ioctl code 0x%lx\n", + Stack->Parameters.DeviceIoControl.IoControlCode); + ASSERT(FALSE); + } + } + + return Result; +} + +static VOID +i8042PacketDpc( + IN PPORT_DEVICE_EXTENSION DeviceExtension) +{ + BOOLEAN FinishIrp = FALSE; + KIRQL Irql; + NTSTATUS Result = STATUS_INTERNAL_ERROR; /* Shouldn't happen */ + + /* If the interrupt happens before this is setup, the key + * was already in the buffer. Too bad! */ + if (!DeviceExtension->HighestDIRQLInterrupt) + return; + + Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); + + if (DeviceExtension->Packet.State == Idle + && DeviceExtension->PacketComplete) + { + FinishIrp = TRUE; + Result = DeviceExtension->PacketResult; + DeviceExtension->PacketComplete = FALSE; + } + + KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); + + if (!FinishIrp) + return; + + if (DeviceExtension->CurrentIrp) + { + DeviceExtension->CurrentIrp->IoStatus.Status = Result; + IoCompleteRequest(DeviceExtension->CurrentIrp, IO_NO_INCREMENT); + IoStartNextPacket(DeviceExtension->CurrentIrpDevice, FALSE); + DeviceExtension->CurrentIrp = NULL; + DeviceExtension->CurrentIrpDevice = NULL; + } +} + +static VOID NTAPI +i8042PowerWorkItem( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PI8042_KEYBOARD_EXTENSION DeviceExtension; NTSTATUS Status; - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION) Context; - BOOLEAN HookContinue = FALSE, HookReturn; - ULONG Iterations = 0; - KEYBOARD_INPUT_DATA *InputData = - DevExt->KeyboardBuffer + DevExt->KeysInBuffer; + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - do { - Status = I8042ReadStatus(&PortStatus); - DPRINT("PortStatus: %x\n", PortStatus); - Status = I8042ReadData(&Output); - Iterations++; - if (STATUS_SUCCESS == Status) + /* See http://blogs.msdn.com/doronh/archive/2006/09/08/746961.aspx */ + + /* Register GUID_DEVICE_SYS_BUTTON interface and report capability */ + if (DeviceExtension->NewCaps != DeviceExtension->ReportedCaps) + { + if (DeviceExtension->PowerInterfaceName.MaximumLength == 0) + { + /* We have never registred this interface ; do it */ + Status = IoRegisterDeviceInterface( + DeviceExtension->Common.Pdo, + &GUID_DEVICE_SYS_BUTTON, + NULL, + &DeviceExtension->PowerInterfaceName); + if (!NT_SUCCESS(Status)) + { + /* We can't do more yet, ignore the keypress... */ + DPRINT("IoRegisterDeviceInterface(GUID_DEVICE_SYS_BUTTON) failed with status 0x%08lx\n", + Status); + DeviceExtension->PowerInterfaceName.MaximumLength = 0; + return; + } + } + else + { + /* Disable the interface. Once activated again, capabilities would be asked again */ + Status = IoSetDeviceInterfaceState( + &DeviceExtension->PowerInterfaceName, + FALSE); + if (!NT_SUCCESS(Status)) + { + /* Ignore the key press... */ + DPRINT("Disabling interface %wZ failed with status 0x%08lx\n", + &DeviceExtension->PowerInterfaceName, Status); + return; + } + } + /* Enable the interface. This leads to receving a IOCTL_GET_SYS_BUTTON_CAPS, + * so we can report new capability */ + Status = IoSetDeviceInterfaceState( + &DeviceExtension->PowerInterfaceName, + TRUE); + if (!NT_SUCCESS(Status)) + { + /* Ignore the key press... */ + DPRINT("Enabling interface %wZ failed with status 0x%08lx\n", + &DeviceExtension->PowerInterfaceName, Status); + return; + } + } + + /* Directly complete the IOCTL_GET_SYS_BUTTON_EVENT Irp (if any) */ + if (DeviceExtension->PowerIrp) + { + PULONG pEvent = (PULONG)DeviceExtension->PowerIrp->AssociatedIrp.SystemBuffer; + + DeviceExtension->PowerIrp->IoStatus.Status = STATUS_SUCCESS; + DeviceExtension->PowerIrp->IoStatus.Information = sizeof(ULONG); + *pEvent = DeviceExtension->LastPowerKey; + + IoCompleteRequest(DeviceExtension->PowerIrp, IO_NO_INCREMENT); + DeviceExtension->PowerIrp = NULL; + } +} + +/* Return TRUE if it was a power key */ +static BOOLEAN +HandlePowerKeys( + IN PI8042_KEYBOARD_EXTENSION DeviceExtension) +{ + PKEYBOARD_INPUT_DATA InputData; + ULONG KeyPress; + + InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer - 1; + if (!(InputData->Flags & KEY_E0)) + return FALSE; + + if (InputData->Flags & KEY_BREAK) + /* We already took care of the key press */ + return TRUE; + + switch (InputData->MakeCode) + { + case 0x52: /* VK_INSERT */ + DPRINT1("FIXME: Remove debug code\n"); + case KEYBOARD_POWER_CODE: + KeyPress = SYS_BUTTON_POWER; + break; + case KEYBOARD_SLEEP_CODE: + KeyPress = SYS_BUTTON_SLEEP; + break; + + case KEYBOARD_WAKE_CODE: + KeyPress = SYS_BUTTON_WAKE; + break; + default: + return FALSE; + } + + /* Our work can only be done at passive level, so use a workitem */ + DeviceExtension->NewCaps |= KeyPress; + DeviceExtension->LastPowerKey = KeyPress; + IoQueueWorkItem( + DeviceExtension->PowerWorkItem, + &i8042PowerWorkItem, + DelayedWorkQueue, + DeviceExtension); + return TRUE; +} + +static VOID NTAPI +i8042KbdDpcRoutine( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +{ + PI8042_KEYBOARD_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + ULONG KeysTransferred = 0; + ULONG KeysInBufferCopy; + KIRQL Irql; + + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeferredContext; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + + if (HandlePowerKeys(DeviceExtension)) + { + DeviceExtension->KeyComplete = FALSE; + return; + } + + i8042PacketDpc(PortDeviceExtension); + if (!DeviceExtension->KeyComplete) + return; + /* We got the interrupt as it was being enabled, too bad */ + if (!PortDeviceExtension->HighestDIRQLInterrupt) + return; + + Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); + + DeviceExtension->KeyComplete = FALSE; + KeysInBufferCopy = DeviceExtension->KeysInBuffer; + + KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); + +#ifdef __REACTOS__ + if (PortDeviceExtension->Settings.CrashOnCtrlScroll) + { + PKEYBOARD_INPUT_DATA InputData; + InputData = DeviceExtension->KeyboardBuffer + KeysInBufferCopy - 1; + + /* Test for TAB + key combination */ + if (InputData->MakeCode == 0x0F) + DeviceExtension->TabPressed = !(InputData->Flags & KEY_BREAK); + else if (DeviceExtension->TabPressed) + { + DeviceExtension->DebugKey = InputData->MakeCode; + DeviceExtension->TabPressed = FALSE; + + IoQueueWorkItem( + DeviceExtension->DebugWorkItem, + &i8042DebugWorkItem, + DelayedWorkQueue, + DeviceExtension); + } + } +#endif + + DPRINT("Send a key\n"); + + if (!DeviceExtension->KeyboardData.ClassService) + return; + + DPRINT("Sending %lu key(s)\n", KeysInBufferCopy); + (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->KeyboardData.ClassService)( + DeviceExtension->KeyboardData.ClassDeviceObject, + DeviceExtension->KeyboardBuffer, + DeviceExtension->KeyboardBuffer + KeysInBufferCopy, + &KeysTransferred); + + Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); + DeviceExtension->KeysInBuffer -= KeysTransferred; + KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); +} + +#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003) + +/* + * Runs the keyboard IOCTL dispatch. + */ +NTSTATUS +i8042KbdDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + PI8042_KEYBOARD_EXTENSION DeviceExtension; + NTSTATUS Status; + + Stack = IoGetCurrentIrpStackLocation(Irp); + Irp->IoStatus.Information = 0; + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; + + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_GET_SYS_BUTTON_CAPS: + { + /* Part of GUID_DEVICE_SYS_BUTTON interface */ + PULONG pCaps; + DPRINT("IOCTL_GET_SYS_BUTTON_CAPS\n"); + + if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) + Status = STATUS_INVALID_PARAMETER; + else + { + pCaps = (PULONG)Irp->AssociatedIrp.SystemBuffer; + *pCaps = DeviceExtension->NewCaps; + DeviceExtension->ReportedCaps = DeviceExtension->NewCaps; + Irp->IoStatus.Information = sizeof(ULONG); + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_GET_SYS_BUTTON_EVENT: + { + /* Part of GUID_DEVICE_SYS_BUTTON interface */ + PIRP WaitingIrp; + DPRINT("IOCTL_GET_SYS_BUTTON_EVENT\n"); + + if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) + Status = STATUS_INVALID_PARAMETER; + else + { + /* FIXME: Race condition here: + * If an interrupt comes before we can mark the Irp + * as pending, it might be possible to complete the + * Irp before pending it, leading to a crash! */ + WaitingIrp = InterlockedCompareExchangePointer( + &DeviceExtension->PowerIrp, + Irp, + NULL); + /* Check if an Irp is already pending */ + if (WaitingIrp != NULL) + { + /* Unable to have a 2nd pending IRP for this IOCTL */ + DPRINT("Unable to pend a second IRP for IOCTL_GET_SYS_BUTTON_EVENT\n"); + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = STATUS_PENDING; + } + } + break; + } + default: + { + DPRINT("IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", + Stack->Parameters.DeviceIoControl.IoControlCode); + ASSERT(FALSE); + return ForwardIrpAndForget(DeviceObject, Irp); + } + } + + Irp->IoStatus.Status = Status; + if (Status == STATUS_PENDING) + IoMarkIrpPending(Irp); + else + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + /* Special case for IOCTL_GET_SYS_BUTTON_CAPS */ + if (Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_SYS_BUTTON_CAPS + && DeviceExtension->PowerIrp) + { + /* Also complete the pending IOCTL_GET_SYS_BUTTON_EVENT Irp */ + PULONG pEvent = (PULONG)DeviceExtension->PowerIrp->AssociatedIrp.SystemBuffer; + + DeviceExtension->PowerIrp->IoStatus.Status = STATUS_SUCCESS; + DeviceExtension->PowerIrp->IoStatus.Information = sizeof(ULONG); + *pEvent = DeviceExtension->LastPowerKey; + DeviceExtension->LastPowerKey = 0; + + IoCompleteRequest(DeviceExtension->PowerIrp, IO_NO_INCREMENT); + DeviceExtension->PowerIrp = NULL; + } + return Status; +} + +/* + * Runs the keyboard IOCTL_INTERNAL dispatch. + */ +NTSTATUS +i8042KbdInternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + PI8042_KEYBOARD_EXTENSION DeviceExtension; + NTSTATUS Status; + + Stack = IoGetCurrentIrpStackLocation(Irp); + Irp->IoStatus.Information = 0; + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; + + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_INTERNAL_KEYBOARD_CONNECT: + { + SIZE_T Size; + PIO_WORKITEM WorkItem = NULL; + PI8042_HOOK_WORKITEM WorkItemData = NULL; + + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); + if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA)) + { + Status = STATUS_INVALID_PARAMETER; + goto cleanup; + } + + DeviceExtension->KeyboardData = + *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); + + /* Send IOCTL_INTERNAL_I8042_HOOK_KEYBOARD to device stack */ + WorkItem = IoAllocateWorkItem(DeviceObject); + if (!WorkItem) + { + DPRINT("IoAllocateWorkItem() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + WorkItemData = ExAllocatePool( + NonPagedPool, + sizeof(I8042_HOOK_WORKITEM)); + if (!WorkItemData) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + WorkItemData->WorkItem = WorkItem; + WorkItemData->Irp = Irp; + + /* Initialize extension */ + DeviceExtension->Common.Type = Keyboard; + Size = DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA); + DeviceExtension->KeyboardBuffer = ExAllocatePool( + NonPagedPool, + Size); + if (!DeviceExtension->KeyboardBuffer) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + RtlZeroMemory(DeviceExtension->KeyboardBuffer, Size); + KeInitializeDpc( + &DeviceExtension->DpcKeyboard, + i8042KbdDpcRoutine, + DeviceExtension); + DeviceExtension->PowerWorkItem = IoAllocateWorkItem(DeviceObject); + if (!DeviceExtension->PowerWorkItem) + { + DPRINT("IoAllocateWorkItem() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + DeviceExtension->DebugWorkItem = IoAllocateWorkItem(DeviceObject); + if (!DeviceExtension->DebugWorkItem) + { + DPRINT("IoAllocateWorkItem() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + DeviceExtension->Common.PortDeviceExtension->KeyboardExtension = DeviceExtension; + DeviceExtension->Common.PortDeviceExtension->Flags |= KEYBOARD_CONNECTED; + + IoMarkIrpPending(Irp); + IoQueueWorkItem(WorkItem, + i8042SendHookWorkItem, + DelayedWorkQueue, + WorkItemData); + Status = STATUS_PENDING; + break; + +cleanup: + if (DeviceExtension->KeyboardBuffer) + ExFreePool(DeviceExtension->KeyboardBuffer); + if (DeviceExtension->PowerWorkItem) + IoFreeWorkItem(DeviceExtension->PowerWorkItem); + if (DeviceExtension->DebugWorkItem) + IoFreeWorkItem(DeviceExtension->DebugWorkItem); + if (WorkItem) + IoFreeWorkItem(WorkItem); + if (WorkItemData) + ExFreePool(WorkItemData); + break; + } + case IOCTL_INTERNAL_KEYBOARD_DISCONNECT: + { + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_DISCONNECT\n"); + /* MSDN says that operation is to implemented. + * To implement it, we just have to do: + * DeviceExtension->KeyboardData.ClassService = NULL; + */ + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: + { + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_KEYBOARD\n"); + /* Nothing to do here */ + Status = STATUS_SUCCESS; + break; + } + case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: + { + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n"); + + /* We should check the UnitID, but it's kind of pointless as + * all keyboards are supposed to have the same one + */ + if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + RtlCopyMemory( + Irp->AssociatedIrp.SystemBuffer, + &IndicatorTranslation, + sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)); + Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_KEYBOARD_QUERY_INDICATORS: + { + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATORS\n"); + + if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + RtlCopyMemory( + Irp->AssociatedIrp.SystemBuffer, + &DeviceExtension->KeyboardIndicators, + sizeof(KEYBOARD_INDICATOR_PARAMETERS)); + Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); + Status = STATUS_SUCCESS; + } + break; + } + case IOCTL_KEYBOARD_SET_INDICATORS: + { + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_SET_INDICATORS\n"); + + if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + RtlCopyMemory( + &DeviceExtension->KeyboardIndicators, + Irp->AssociatedIrp.SystemBuffer, + sizeof(KEYBOARD_INDICATOR_PARAMETERS)); + Status = STATUS_PENDING; + IoMarkIrpPending(Irp); + IoStartPacket(DeviceObject, Irp, NULL, NULL); + } + break; + } + default: + { + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", + Stack->Parameters.DeviceIoControl.IoControlCode); + ASSERT(FALSE); + return ForwardIrpAndForget(DeviceObject, Irp); + } + } + + Irp->IoStatus.Status = Status; + if (Status != STATUS_PENDING) + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +/* + * Call the customization hook. The ToReturn parameter is about wether + * we should go on with the interrupt. The return value is what + * we should return (indicating to the system wether someone else + * should try to handle the interrupt) + */ +static BOOLEAN +i8042KbdCallIsrHook( + IN PI8042_KEYBOARD_EXTENSION DeviceExtension, + IN UCHAR Status, + IN UCHAR Input, + OUT PBOOLEAN ToReturn) +{ + BOOLEAN HookReturn, HookContinue; + + HookContinue = FALSE; + + if (DeviceExtension->KeyboardHook.IsrRoutine) + { + HookReturn = DeviceExtension->KeyboardHook.IsrRoutine( + DeviceExtension->KeyboardHook.Context, + DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer, + &DeviceExtension->Common.PortDeviceExtension->Packet, + Status, + &Input, + &HookContinue, + &DeviceExtension->KeyboardScanState); + + if (!HookContinue) + { + *ToReturn = HookReturn; + return TRUE; + } + } + return FALSE; +} + +BOOLEAN NTAPI +i8042KbdInterruptService( + IN PKINTERRUPT Interrupt, + PVOID Context) +{ + PI8042_KEYBOARD_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + PKEYBOARD_INPUT_DATA InputData; + ULONG Counter; + UCHAR PortStatus, Output; + BOOLEAN ToReturn = FALSE; + NTSTATUS Status; + + DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer; + Counter = PortDeviceExtension->Settings.PollStatusIterations; + + while (Counter) + { + Status = i8042ReadStatus(PortDeviceExtension, &PortStatus); + if (!NT_SUCCESS(Status)) + { + DPRINT("i8042ReadStatus() failed with status 0x%08lx\n", Status); + return FALSE; + } + Status = i8042ReadKeyboardData(PortDeviceExtension, &Output); + if (NT_SUCCESS(Status)) break; KeStallExecutionProcessor(1); - } while (Iterations < DevExt->Settings.PollStatusIterations); - - if (STATUS_SUCCESS != Status) { - DPRINT("Spurious I8042 interrupt\n"); + Counter--; + } + if (Counter == 0) + { + DPRINT("Spurious i8042 keyboard interrupt\n"); return FALSE; } - DPRINT("Got: %x\n", Output); + DPRINT("Got: 0x%02x\n", Output); - if (DevExt->KeyboardHook.IsrRoutine) { - HookReturn = DevExt->KeyboardHook.IsrRoutine( - DevExt->KeyboardHook.Context, - InputData, - &DevExt->Packet, - PortStatus, - &Output, - &HookContinue, - &DevExt->KeyboardScanState); + if (PortDeviceExtension->Settings.CrashOnCtrlScroll) + { + /* Test for CTRL + SCROLL LOCK twice */ + static UCHAR ScanCodes[] = { 0x1d, 0x46, 0x46, 0 }; - if (!HookContinue) - return HookReturn; + if (!(Output & 0x80)) + { + if ((Output & 0x7f) == ScanCodes[DeviceExtension->ComboPosition]) + { + DeviceExtension->ComboPosition++; + if (ScanCodes[DeviceExtension->ComboPosition] == 0) + KeBugCheck(MANUALLY_INITIATED_CRASH); + } + else if ((Output & 0x7f) == ScanCodes[0]) + DeviceExtension->ComboPosition = 1; + else + DeviceExtension->ComboPosition = 0; + } } - if (I8042PacketIsr(DevExt, Output)) { - if (DevExt->PacketComplete) { + if (i8042KbdCallIsrHook(DeviceExtension, PortStatus, Output, &ToReturn)) + return ToReturn; + + if (i8042PacketIsr(PortDeviceExtension, Output)) + { + if (PortDeviceExtension->PacketComplete) + { DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DevExt->DpcKbd, DevExt, NULL); + KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); } DPRINT("Irq eaten by packet\n"); return TRUE; @@ -135,642 +833,43 @@ BOOLEAN STDCALL I8042InterruptServiceKbd(struct _KINTERRUPT *Interrupt, DPRINT("Irq is keyboard input\n"); - if (Normal == DevExt->KeyboardScanState) { - switch (Output) { - case 0xe0: - DevExt->KeyboardScanState = GotE0; - return TRUE; - case 0xe1: - DevExt->KeyboardScanState = GotE1; - return TRUE; - default: - ;/* continue */ + if (DeviceExtension->KeyboardScanState == Normal) + { + switch (Output) + { + case 0xe0: + DeviceExtension->KeyboardScanState = GotE0; + return TRUE; + case 0xe1: + DeviceExtension->KeyboardScanState = GotE1; + return TRUE; + default: + break; } } + /* Update InputData */ InputData->Flags = 0; - - switch (DevExt->KeyboardScanState) { - case GotE0: - InputData->Flags |= KEY_E0; - break; - case GotE1: - InputData->Flags |= KEY_E1; - break; - default: - ; + switch (DeviceExtension->KeyboardScanState) + { + case GotE0: + InputData->Flags |= KEY_E0; + break; + case GotE1: + InputData->Flags |= KEY_E1; + break; + default: + break; } - DevExt->KeyboardScanState = Normal; - + DeviceExtension->KeyboardScanState = Normal; if (Output & 0x80) InputData->Flags |= KEY_BREAK; else InputData->Flags |= KEY_MAKE; - InputData->MakeCode = Output & 0x7f; + InputData->Reserved = 0; - I8042QueueKeyboardPacket(DevExt->KeyboardObject); + i8042KbdQueuePacket(DeviceExtension); return TRUE; } - -VOID STDCALL I8042DpcRoutineKbd(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)SystemArgument1; - ULONG KeysTransferred = 0; - ULONG KeysInBufferCopy; - KIRQL Irql; - - I8042PacketDpc(DevExt); - - if (!DevExt->KeyComplete) - return; - - /* We got the interrupt as it was being enabled, too bad */ - if (!DevExt->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->KeyComplete = FALSE; - KeysInBufferCopy = DevExt->KeysInBuffer; - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - - /* Test for TAB (debugging) */ - if (DevExt->Settings.CrashSysRq) { - PKEYBOARD_INPUT_DATA InputData = DevExt->KeyboardBuffer + - KeysInBufferCopy - 1; - if (InputData->MakeCode == 0x0F) { - DPRINT("Tab!\n"); - DevExt->TabPressed = !(InputData->Flags & KEY_BREAK); - } else if (DevExt->TabPressed) { - DPRINT ("Queueing work item %x\n", DevExt->DebugWorkItem); - DevExt->DebugKey = InputData->MakeCode; - DevExt->TabPressed = FALSE; - - IoQueueWorkItem(DevExt->DebugWorkItem, - &(I8042DebugWorkItem), - DelayedWorkQueue, - DevExt); - } - } - - DPRINT ("Send a key\n"); - - if (!DevExt->KeyboardData.ClassService) - return; - - ((PSERVICE_CALLBACK_ROUTINE) DevExt->KeyboardData.ClassService)( - DevExt->KeyboardData.ClassDeviceObject, - DevExt->KeyboardBuffer, - DevExt->KeyboardBuffer + KeysInBufferCopy, - &KeysTransferred); - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - DevExt->KeysInBuffer -= KeysTransferred; - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); -} - -/* You have to send the rate/delay in a somewhat awkward format */ -static UCHAR I8042GetTypematicByte(USHORT Rate, USHORT Delay) -{ - UCHAR ret; - - if (Rate < 3) { - ret = 0x0; - } else if (Rate > 26) { - ret = 0x1F; - } else { - ret = TypematicTable[Rate]; - } - - if (Delay < 375) { - ; - } else if (Delay < 625) { - ret |= 0x20; - } else if (Delay < 875) { - ret |= 0x40; - } else { - ret |= 0x60; - } - return ret; -} -/* - * Process the keyboard internal device requests - * returns FALSE if it doesn't understand the - * call so someone else can handle it. - */ -BOOLEAN STDCALL I8042StartIoKbd(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER: - I8042StartPacket( - DevExt, - DeviceObject, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - Stk->Parameters.DeviceIoControl.InputBufferLength, - Irp); - break; - - case IOCTL_KEYBOARD_SET_INDICATORS: - DevExt->PacketBuffer[0] = 0xED; - DevExt->PacketBuffer[1] = 0; - if (DevExt->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON) - DevExt->PacketBuffer[1] |= 0x04; - - if (DevExt->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON) - DevExt->PacketBuffer[1] |= 0x02; - - if (DevExt->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON) - DevExt->PacketBuffer[1] |= 0x01; - - I8042StartPacket(DevExt, - DeviceObject, - DevExt->PacketBuffer, - 2, - Irp); - break; - case IOCTL_KEYBOARD_SET_TYPEMATIC: - DevExt->PacketBuffer[0] = 0xF3; - DevExt->PacketBuffer[1] = I8042GetTypematicByte( - DevExt->KeyboardTypematic.Rate, - DevExt->KeyboardTypematic.Delay); - - I8042StartPacket(DevExt, - DeviceObject, - DevExt->PacketBuffer, - 2, - Irp); - break; - default: - return FALSE; - } - - return TRUE; -} - -/* - * Runs the keyboard IOCTL_INTERNAL dispatch. - * Returns NTSTATUS_INVALID_DEVICE_REQUEST if it doesn't handle this request - * so someone else can have a try at it. - */ -NTSTATUS STDCALL I8042InternalDeviceControlKbd(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DPRINT("InternalDeviceControl\n"); - - Irp->IoStatus.Information = 0; - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - - case IOCTL_INTERNAL_KEYBOARD_CONNECT: - DPRINT("IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(CONNECT_DATA)) { - DPRINT1("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - - if (!DevExt->KeyboardExists) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; - goto intcontfailure; - } - - if (DevExt->KeyboardClaimed) { - DPRINT1("IOCTL_INTERNAL_KEYBOARD_CONNECT: " - "Keyboard is already claimed\n"); - Irp->IoStatus.Status = STATUS_SHARING_VIOLATION; - goto intcontfailure; - } - - memcpy(&DevExt->KeyboardData, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - sizeof(CONNECT_DATA)); - DevExt->KeyboardHook.IsrWritePort = I8042IsrWritePortKbd; - DevExt->KeyboardHook.QueueKeyboardPacket = - I8042QueueKeyboardPacket; - DevExt->KeyboardHook.CallContext = DevExt; - - { - PIO_WORKITEM WorkItem; - PI8042_HOOK_WORKITEM WorkItemData; - - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) { - DPRINT ("IOCTL_INTERNAL_KEYBOARD_CONNECT: " - "Can't allocate work item\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - goto intcontfailure; - } - - WorkItemData = ExAllocatePoolWithTag( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM), - TAG_I8042); - if (!WorkItemData) { - DPRINT ("IOCTL_INTERNAL_KEYBOARD_CONNECT: " - "Can't allocate work item data\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - IoFreeWorkItem(WorkItem); - goto intcontfailure; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Target = - DevExt->KeyboardData.ClassDeviceObject; - WorkItemData->Irp = Irp; - - IoMarkIrpPending(Irp); - IoQueueWorkItem(WorkItem, - I8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - - Irp->IoStatus.Status = STATUS_PENDING; - } - - break; - case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER: - DPRINT("IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < 1) { - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - if (!DevExt->KeyboardInterruptObject) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; - goto intcontfailure; - } - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: - DPRINT("IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"); - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(KEYBOARD_ATTRIBUTES)) { - DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->KeyboardAttributes, - sizeof(KEYBOARD_ATTRIBUTES)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_KEYBOARD_QUERY_INDICATORS: - DPRINT("IOCTL_KEYBOARD_QUERY_INDICATORS\n"); - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_INDICATORS " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->KeyboardIndicators, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_KEYBOARD_QUERY_TYPEMATIC: - DPRINT("IOCTL_KEYBOARD_QUERY_TYPEMATIC\n"); - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->KeyboardTypematic, - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_KEYBOARD_SET_INDICATORS: - DPRINT("IOCTL_KEYBOARD_SET_INDICATORS\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_SET_INDICTATORS " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - - memcpy(&DevExt->KeyboardIndicators, - Irp->AssociatedIrp.SystemBuffer, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - - DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags); - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_KEYBOARD_SET_TYPEMATIC: - DPRINT("IOCTL_KEYBOARD_SET_TYPEMATIC\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - - memcpy(&DevExt->KeyboardTypematic, - Irp->AssociatedIrp.SystemBuffer, - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)); - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: - /* We should check the UnitID, but it's kind of pointless as - * all keyboards are supposed to have the same one - */ - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) { - DPRINT("IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: " - "invalid buffer size (expected)\n"); - /* It's to query the buffer size */ - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - Irp->IoStatus.Information = - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); - - memcpy(Irp->AssociatedIrp.SystemBuffer, - &IndicatorTranslation, - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: - /* Nothing to do here */ - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - default: - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - -intcontfailure: - return Irp->IoStatus.Status; -} - -/* This is all pretty confusing. There's more than one way to - * disable/enable the keyboard. You can send KBD_ENABLE to the - * keyboard, and it will start scanning keys. Sending KBD_DISABLE - * will disable the key scanning but also reset the parameters to - * defaults. - * - * You can also send 0xAE to the controller for enabling the - * keyboard clock line and 0xAD for disabling it. Then it'll - * automatically get turned on at the next command. The last - * way is by modifying the bit that drives the clock line in the - * 'command byte' of the controller. This is almost, but not quite, - * the same as the AE/AD thing. The difference can be used to detect - * some really old broken keyboard controllers which I hope won't be - * necessary. - * - * We change the command byte, sending KBD_ENABLE/DISABLE seems to confuse - * some kvm switches. - */ - -BOOLEAN STDCALL I8042KeyboardEnable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Enable keyboard\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~CCB_KBD_DISAB; // don't disable keyboard - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -static BOOLEAN STDCALL I8042KeyboardDefaultsAndDisable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Disabling keyboard\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= CCB_KBD_DISAB; // disable keyboard - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -BOOLEAN STDCALL I8042KeyboardEnableInterrupt(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Enabling keyboard interrupt\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~CCB_KBD_DISAB; // don't disable keyboard - Value |= CCB_KBD_INT_ENAB; // enable keyboard interrupts - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -BOOLEAN STDCALL I8042DetectKeyboard(PDEVICE_EXTENSION DevExt) -{ - NTSTATUS Status; - UCHAR Value; - UCHAR Value2; - ULONG RetryCount = 10; - - DPRINT("Detecting keyboard\n"); - - I8042KeyboardDefaultsAndDisable(DevExt); - - do { - I8042Flush(); - Status = I8042SynchWritePort(DevExt, 0, KBD_GET_ID, TRUE); - } while (STATUS_IO_TIMEOUT == Status && RetryCount--); - - if (!NT_SUCCESS(Status)) { - DPRINT1("Can't write GET_ID (%x)\n", Status); - /* Could be an AT keyboard */ - DevExt->KeyboardIsAT = TRUE; - goto detectsetleds; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after GET_ID\n"); - /* Could be an AT keyboard */ - DevExt->KeyboardIsAT = TRUE; - goto detectsetleds; - } - DevExt->KeyboardIsAT = FALSE; - - if (Value != 0xAB && Value != 0xAC) { - DPRINT("Bad ID: %x\n", Value); - /* This is certainly not a keyboard */ - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value2); - if (!NT_SUCCESS(Status)) { - DPRINT("Partial ID\n"); - return FALSE; - } - - DPRINT("Keyboard ID: 0x%x 0x%x\n", Value, Value2); - -detectsetleds: - I8042Flush(); /* Flush any bytes left over from GET_ID */ - - Status = I8042SynchWritePort(DevExt, 0, KBD_SET_LEDS, TRUE); - if (!NT_SUCCESS(Status)) { - DPRINT("Can't write SET_LEDS (%x)\n", Status); - return FALSE; - } - Status = I8042SynchWritePort(DevExt, 0, 0, TRUE); - if (!NT_SUCCESS(Status)) { - DPRINT("Can't finish SET_LEDS (%x)\n", Status); - return FALSE; - } - - // Turn on translation - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= 0x40; // enable keyboard translation - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -/* debug stuff */ -VOID STDCALL -KdpServiceDispatcher(ULONG Code, PVOID Context1, PVOID Context2); -#define EnterDebugger ((PVOID)0x25) - -static VOID STDCALL I8042DebugWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context) -{ - ULONG Key; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - Key = InterlockedExchange((PLONG)&DevExt->DebugKey, 0); - DPRINT("Debug key: %x\n", Key); - - if (!Key) - return; - -#ifdef __REACTOS__ - /* We hope kernel would understand this. If - * that's not the case, nothing would happen. - */ - KdpServiceDispatcher(TAG('R', 'o', 's', ' '), (PVOID)Key, NULL); -#endif /* __REACTOS__ */ -} diff --git a/reactos/drivers/input/i8042prt/misc.c b/reactos/drivers/input/i8042prt/misc.c new file mode 100644 index 00000000000..82200c72d02 --- /dev/null +++ b/reactos/drivers/input/i8042prt/misc.c @@ -0,0 +1,68 @@ +/* + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/misc.c + * PURPOSE: Misceallenous operations + * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "i8042prt.h" + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +static NTSTATUS NTAPI +ForwardIrpAndWaitCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + if (Irp->PendingReturned) + KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +ForwardIrpAndWait( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; + KEVENT Event; + NTSTATUS Status; + + ASSERT(LowerDevice); + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + IoCopyCurrentIrpStackLocationToNext(Irp); + + DPRINT("Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName); + IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE); + + Status = IoCallDriver(LowerDevice, Irp); + if (Status == STATUS_PENDING) + { + Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); + if (NT_SUCCESS(Status)) + Status = Irp->IoStatus.Status; + } + + return Status; +} + +NTSTATUS NTAPI +ForwardIrpAndForget( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; + + ASSERT(LowerDevice); + + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(LowerDevice, Irp); +} diff --git a/reactos/drivers/input/i8042prt/mouse.c b/reactos/drivers/input/i8042prt/mouse.c index 5a8afb5ebf3..1d7d65070d1 100644 --- a/reactos/drivers/input/i8042prt/mouse.c +++ b/reactos/drivers/input/i8042prt/mouse.c @@ -1,12 +1,12 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/mouse.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * mouse specifics - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/mouse.c + * PURPOSE: Mouse specific functions + * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) + Copyright Jason Filby (jasonfilby@yahoo.com) + Copyright Martijn Vernooij (o112w8r02@sneakemail.com) + Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) */ /* INCLUDES ****************************************************************/ @@ -16,27 +16,474 @@ #define NDEBUG #include +/* FUNCTIONS *****************************************************************/ + /* * These functions are callbacks for filter driver custom interrupt * service routines. */ -static VOID STDCALL I8042IsrWritePortMouse(PVOID Context, - UCHAR Value) +static VOID NTAPI +i8042MouIsrWritePort( + IN PVOID Context, + IN UCHAR Value) { - I8042IsrWritePort(Context, Value, 0xD4); + PI8042_MOUSE_EXTENSION DeviceExtension; + + DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; + + if (DeviceExtension->MouseHook.IsrWritePort) + { + DeviceExtension->MouseHook.IsrWritePort( + DeviceExtension->MouseHook.CallContext, + Value); + } + else + i8042IsrWritePort(Context, Value, 0xD4); } -#if 0 -static NTSTATUS STDCALL I8042SynchWritePortMouse(PVOID Context, - UCHAR Value, - BOOLEAN WaitForAck) +VOID NTAPI +i8042MouQueuePacket( + IN PVOID Context) { - return I8042SynchWritePort((PDEVICE_EXTENSION)Context, - 0xD4, - Value, - WaitForAck); + PI8042_MOUSE_EXTENSION DeviceExtension; + + DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; + + if (DeviceExtension->MouseHook.QueueMousePacket) + { + DeviceExtension->MouseHook.QueueMousePacket( + DeviceExtension->MouseHook.CallContext); + return; + } + + DeviceExtension->MouseComplete = TRUE; + DeviceExtension->MouseInBuffer++; + if (DeviceExtension->MouseInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize) + { + DPRINT1("Mouse buffer overflow\n"); + DeviceExtension->MouseInBuffer--; + } + + DPRINT("Irq completes mouse packet\n"); + KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL); +} + +VOID +i8042MouHandle( + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN UCHAR Output) +{ + PMOUSE_INPUT_DATA MouseInput; + CHAR Scroll; + + MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; + + switch (DeviceExtension->MouseState) + { + case MouseIdle: + /* This bit should be 1, if not drop the packet, we + * might be lucky and get in sync again + */ + if (!(Output & 8)) { + DPRINT1("Bad input, dropping..\n"); + return; + } + + MouseInput->Buttons = 0; + MouseInput->RawButtons = 0; + MouseInput->Flags = MOUSE_MOVE_RELATIVE; + + /* Note how we ignore the overflow bits, like Windows + * is said to do. There's no reasonable thing to do + * anyway. + */ + + if (Output & 16) + MouseInput->LastX = 1; + else + MouseInput->LastX = 0; + if (Output & 32) + MouseInput->LastY = 1; + else + MouseInput->LastY = 0; + + if (Output & 1) + MouseInput->RawButtons |= MOUSE_LEFT_BUTTON_DOWN; + if (Output & 2) + MouseInput->RawButtons |= MOUSE_RIGHT_BUTTON_DOWN; + if (Output & 4) + MouseInput->RawButtons |= MOUSE_MIDDLE_BUTTON_DOWN; + + DeviceExtension->MouseState = XMovement; + break; + + case XMovement: + if (MouseInput->LastX) + MouseInput->LastX = (LONG) Output - 256; + else + MouseInput->LastX = Output; + + DeviceExtension->MouseState = YMovement; + break; + + case YMovement: + if (MouseInput->LastY) + MouseInput->LastY = (LONG)Output - 256; + else + MouseInput->LastY = (LONG)Output; + + /* Windows wants it the other way around */ + MouseInput->LastY = -MouseInput->LastY; + + if (DeviceExtension->MouseType == GenericPS2 || + DeviceExtension->MouseType == Ps2pp) + { + i8042MouHandleButtons( + DeviceExtension, + MOUSE_LEFT_BUTTON_DOWN | + MOUSE_RIGHT_BUTTON_DOWN | + MOUSE_MIDDLE_BUTTON_DOWN); + i8042MouQueuePacket(DeviceExtension); + DeviceExtension->MouseState = MouseIdle; + } + else + { + DeviceExtension->MouseState = ZMovement; + } + break; + + case ZMovement: + Scroll = Output & 0x0f; + if (Scroll & 8) + Scroll |= 0xf0; + + if (Scroll) + { + MouseInput->RawButtons |= MOUSE_WHEEL; + MouseInput->ButtonData = (USHORT)(Scroll * -WHEEL_DELTA); + } + + if (DeviceExtension->MouseType == IntellimouseExplorer) + { + if (Output & 16) + MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; + if (Output & 32) + MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; + } + i8042MouHandleButtons( + DeviceExtension, + MOUSE_LEFT_BUTTON_DOWN | + MOUSE_RIGHT_BUTTON_DOWN | + MOUSE_MIDDLE_BUTTON_DOWN | + MOUSE_BUTTON_4_DOWN | + MOUSE_BUTTON_5_DOWN); + i8042MouQueuePacket(DeviceExtension); + DeviceExtension->MouseState = MouseIdle; + break; + + default: + DPRINT1("Unexpected state 0x%u!\n", DeviceExtension->MouseState); + ASSERT(FALSE); + } +} + +/* + * Updates ButtonFlags according to RawButtons and a saved state; + * Only takes in account the bits that are set in Mask + */ +VOID +i8042MouHandleButtons( + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN USHORT Mask) +{ + PMOUSE_INPUT_DATA MouseInput; + USHORT NewButtonData; + USHORT ButtonDiff; + + MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; + NewButtonData = (USHORT)(MouseInput->RawButtons & Mask); + ButtonDiff = (NewButtonData ^ DeviceExtension->MouseButtonState) & Mask; + + /* Note that the defines are such: + * MOUSE_LEFT_BUTTON_DOWN 1 + * MOUSE_LEFT_BUTTON_UP 2 + */ + MouseInput->ButtonFlags |= (NewButtonData & ButtonDiff) | + (((~(NewButtonData)) << 1) & (ButtonDiff << 1)) | + (MouseInput->RawButtons & 0xfc00); + + DPRINT("Left raw/up/down: %u/%u/%u\n", + MouseInput->RawButtons & MOUSE_LEFT_BUTTON_DOWN, + MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN, + MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_UP); + + DeviceExtension->MouseButtonState = + (DeviceExtension->MouseButtonState & ~Mask) | (NewButtonData & Mask); +} + +static NTSTATUS OldInitialization(PPORT_DEVICE_EXTENSION); /* FIXME */ + +/* Does lastest initializations for the mouse. This method + * is called just before connecting the interrupt. + */ +NTSTATUS +i8042MouInitialize( + IN PI8042_MOUSE_EXTENSION DeviceExtension) +{ + PPORT_DEVICE_EXTENSION PortDeviceExtension; + + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + +/* FIXME */ OldInitialization(PortDeviceExtension); + + return STATUS_SUCCESS; +} + +static VOID NTAPI +i8042MouDpcRoutine( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +{ + PI8042_MOUSE_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + ULONG MouseTransferred = 0; + ULONG MouseInBufferCopy; + KIRQL Irql; + LARGE_INTEGER Timeout; + + DeviceExtension = (PI8042_MOUSE_EXTENSION)DeferredContext; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + + switch (DeviceExtension->MouseTimeoutState) + { + case TimeoutStart: + { + DeviceExtension->MouseTimeoutState = NoChange; + if (DeviceExtension->MouseTimeoutActive && + !KeCancelTimer(&DeviceExtension->TimerMouseTimeout)) + { + /* The timer fired already, give up */ + DeviceExtension->MouseTimeoutActive = FALSE; + return; + } + + Timeout.QuadPart = -15000000; /* 1.5 seconds, should be enough */ + + KeSetTimer( + &DeviceExtension->TimerMouseTimeout, + Timeout, + &DeviceExtension->DpcMouseTimeout); + DeviceExtension->MouseTimeoutActive = TRUE; + return; + } + + case TimeoutCancel: + { + DeviceExtension->MouseTimeoutState = NoChange; + KeCancelTimer(&DeviceExtension->TimerMouseTimeout); + DeviceExtension->MouseTimeoutActive = FALSE; + } + + default: + ;/* nothing, don't want a warning */ + } + + /* Should be unlikely */ + if (!DeviceExtension->MouseComplete) + return; + + Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); + + DeviceExtension->MouseComplete = FALSE; + MouseInBufferCopy = DeviceExtension->MouseInBuffer; + + KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); + + DPRINT("Send a mouse packet\n"); + + if (!DeviceExtension->MouseData.ClassService) + return; + + DPRINT("Sending %lu mouse move(s)\n", MouseInBufferCopy); + (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->MouseData.ClassService)( + DeviceExtension->MouseData.ClassDeviceObject, + DeviceExtension->MouseBuffer, + DeviceExtension->MouseBuffer + MouseInBufferCopy, + &MouseTransferred); + + Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); + DeviceExtension->MouseInBuffer -= MouseTransferred; + if (DeviceExtension->MouseInBuffer) + RtlMoveMemory( + DeviceExtension->MouseBuffer, + DeviceExtension->MouseBuffer + MouseTransferred, + DeviceExtension->MouseInBuffer * sizeof(MOUSE_INPUT_DATA)); + KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); +} + +/* This timer DPC will be called when the mouse reset times out. + * I'll just send the 'disable mouse port' command to the controller + * and say the mouse doesn't exist. + */ +static VOID NTAPI +i8042DpcRoutineMouseTimeout( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +{ + PI8042_MOUSE_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + KIRQL Irql; + + DeviceExtension = (PI8042_MOUSE_EXTENSION)DeferredContext; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + + Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); + + DPRINT1("Mouse initialization timeout! (substate %x). Disabling mouse.\n", + DeviceExtension->MouseResetState); + + i8042Flush(PortDeviceExtension); + i8042ChangeMode(PortDeviceExtension, CCB_MOUSE_INT_ENAB, CCB_MOUSE_DISAB); + i8042Flush(PortDeviceExtension); + + PortDeviceExtension->Flags &= ~MOUSE_PRESENT; + + KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); +} + +/* + * Runs the mouse IOCTL_INTERNAL dispatch. + */ +NTSTATUS +i8042MouInternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + PI8042_MOUSE_EXTENSION DeviceExtension; + NTSTATUS Status; + + Stack = IoGetCurrentIrpStackLocation(Irp); + Irp->IoStatus.Information = 0; + DeviceExtension = (PI8042_MOUSE_EXTENSION)DeviceObject->DeviceExtension; + + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_INTERNAL_MOUSE_CONNECT: + { + SIZE_T Size; + PIO_WORKITEM WorkItem = NULL; + PI8042_HOOK_WORKITEM WorkItemData = NULL; + + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_CONNECT\n"); + if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA)) + { + Status = STATUS_INVALID_PARAMETER; + goto cleanup; + } + + DeviceExtension->MouseData = + *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); + + /* Send IOCTL_INTERNAL_I8042_HOOK_MOUSE to device stack */ + WorkItem = IoAllocateWorkItem(DeviceObject); + if (!WorkItem) + { + DPRINT("IoAllocateWorkItem() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + WorkItemData = ExAllocatePool( + NonPagedPool, + sizeof(I8042_HOOK_WORKITEM)); + if (!WorkItemData) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + WorkItemData->WorkItem = WorkItem; + WorkItemData->Irp = Irp; + + /* Initialize extension */ + DeviceExtension->Common.Type = Mouse; + Size = DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize * sizeof(MOUSE_INPUT_DATA); + DeviceExtension->MouseBuffer = ExAllocatePool( + NonPagedPool, + Size); + if (!DeviceExtension->MouseBuffer) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + RtlZeroMemory(DeviceExtension->MouseBuffer, Size); + DeviceExtension->MouseAttributes.InputDataQueueLength = + DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize; + KeInitializeDpc( + &DeviceExtension->DpcMouse, + i8042MouDpcRoutine, + DeviceExtension); + KeInitializeDpc( + &DeviceExtension->DpcMouseTimeout, + i8042DpcRoutineMouseTimeout, + DeviceExtension); + KeInitializeTimer(&DeviceExtension->TimerMouseTimeout); + DeviceExtension->Common.PortDeviceExtension->MouseExtension = DeviceExtension; + DeviceExtension->Common.PortDeviceExtension->Flags |= MOUSE_CONNECTED; + + IoMarkIrpPending(Irp); + IoQueueWorkItem(WorkItem, + i8042SendHookWorkItem, + DelayedWorkQueue, + WorkItemData); + Status = STATUS_PENDING; + break; + +cleanup: + if (DeviceExtension->MouseBuffer) + ExFreePool(DeviceExtension->MouseBuffer); + if (WorkItem) + IoFreeWorkItem(WorkItem); + if (WorkItemData) + ExFreePool(WorkItemData); + break; + } + case IOCTL_INTERNAL_MOUSE_DISCONNECT: + { + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_DISCONNECT\n"); + /* MSDN says that operation is to implemented. + * To implement it, we just have to do: + * DeviceExtension->MouseData.ClassService = NULL; + */ + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_INTERNAL_I8042_HOOK_MOUSE: + { + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_MOUSE\n"); + /* Nothing to do here */ + Status = STATUS_SUCCESS; + break; + } + default: + { + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", + Stack->Parameters.DeviceIoControl.IoControlCode); + ASSERT(FALSE); + return ForwardIrpAndForget(DeviceObject, Irp); + } + } + + Irp->IoStatus.Status = Status; + if (Status != STATUS_PENDING) + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; } -#endif /* Test if packets are taking too long to come in. If they do, we * might have gotten out of sync and should just drop what we have. @@ -48,56 +495,71 @@ static NTSTATUS STDCALL I8042SynchWritePortMouse(PVOID Context, * generally unlucky). Also note the input parsing routine where we * drop invalid input packets. */ -static VOID STDCALL I8042MouseInputTestTimeout(PDEVICE_EXTENSION DevExt) +static VOID +i8042MouInputTestTimeout( + IN PI8042_MOUSE_EXTENSION DeviceExtension) { ULARGE_INTEGER Now; - if (DevExt->MouseState == MouseExpectingACK || - DevExt->MouseState == MouseResetting) + if (DeviceExtension->MouseState == MouseExpectingACK || + DeviceExtension->MouseState == MouseResetting) return; Now.QuadPart = KeQueryInterruptTime(); - if (DevExt->MouseState != MouseIdle) { + if (DeviceExtension->MouseState != MouseIdle) { /* Check if the last byte came too long ago */ - if (Now.QuadPart - DevExt->MousePacketStartTime.QuadPart > - DevExt->Settings.MouseSynchIn100ns) { + if (Now.QuadPart - DeviceExtension->MousePacketStartTime.QuadPart > + DeviceExtension->Common.PortDeviceExtension->Settings.MouseSynchIn100ns) + { DPRINT("Mouse input packet timeout\n"); - DevExt->MouseState = MouseIdle; + DeviceExtension->MouseState = MouseIdle; } } - if (DevExt->MouseState == MouseIdle) - DevExt->MousePacketStartTime.QuadPart = Now.QuadPart; + if (DeviceExtension->MouseState == MouseIdle) + DeviceExtension->MousePacketStartTime.QuadPart = Now.QuadPart; } /* - * Call the customization hook. The Ret2 parameter is about wether + * Call the customization hook. The ToReturn parameter is about wether * we should go on with the interrupt. The return value is what * we should return (indicating to the system wether someone else * should try to handle the interrupt) */ -static BOOLEAN STDCALL I8042MouseCallIsrHook(PDEVICE_EXTENSION DevExt, - UCHAR Status, - PUCHAR Input, - PBOOLEAN ToReturn) +static BOOLEAN +i8042MouCallIsrHook( + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN UCHAR Status, + IN UCHAR Input, + OUT PBOOLEAN ToReturn) { BOOLEAN HookReturn, HookContinue; HookContinue = FALSE; - if (DevExt->MouseHook.IsrRoutine) { - HookReturn = DevExt->MouseHook.IsrRoutine( - DevExt->MouseHook.Context, - DevExt->MouseBuffer + DevExt->MouseInBuffer, - &DevExt->Packet, - Status, - Input, - &HookContinue, - &DevExt->MouseState, - &DevExt->MouseResetState); + if (DeviceExtension->MouseHook.IsrRoutine) + { + DPRINT1("IsrRoutine(%p %p %p 0x%x 0x%x %p %lu %lu)\n", + DeviceExtension->MouseHook.Context, DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer, + &DeviceExtension->Common.PortDeviceExtension->Packet, Status, &Input, &HookContinue, + DeviceExtension->MouseState, DeviceExtension->MouseResetState); + HookReturn = DeviceExtension->MouseHook.IsrRoutine( + DeviceExtension->MouseHook.Context, + DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer, + &DeviceExtension->Common.PortDeviceExtension->Packet, + Status, + &Input, + &HookContinue, + &DeviceExtension->MouseState, + &DeviceExtension->MouseResetState); + DPRINT1("IsrRoutine(%p %p %p 0x%x 0x%x %p %lu %lu)\n", + DeviceExtension->MouseHook.Context, DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer, + &DeviceExtension->Common.PortDeviceExtension->Packet, Status, &Input, &HookContinue, + DeviceExtension->MouseState, DeviceExtension->MouseResetState); - if (!HookContinue) { + if (!HookContinue) + { *ToReturn = HookReturn; return TRUE; } @@ -105,844 +567,504 @@ static BOOLEAN STDCALL I8042MouseCallIsrHook(PDEVICE_EXTENSION DevExt, return FALSE; } -static BOOLEAN STDCALL I8042MouseResetIsr(PDEVICE_EXTENSION DevExt, - UCHAR Status, - PUCHAR Value) +static BOOLEAN +i8042MouResetIsr( + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN UCHAR Status, + IN UCHAR Value) { + PPORT_DEVICE_EXTENSION PortDeviceExtension; BOOLEAN ToReturn = FALSE; - if (I8042MouseCallIsrHook(DevExt, Status, Value, &ToReturn)) + if (i8042MouCallIsrHook(DeviceExtension, Status, Value, &ToReturn)) return ToReturn; - if (MouseResetting != DevExt->MouseState) { + if (MouseResetting != DeviceExtension->MouseState) return FALSE; - } - DevExt->MouseTimeoutState = TimeoutStart; + DeviceExtension->MouseTimeoutState = TimeoutStart; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - switch (DevExt->MouseResetState) { - case 1100: /* the first ack, drop it. */ - DevExt->MouseResetState = ExpectingReset; - return TRUE; - /* First, 0xFF is sent. The mouse is supposed to say AA00 if ok, - * FC00 if not. - */ - case ExpectingReset: - if (0xAA == *Value) { - DevExt->MouseResetState++; - } else { - DevExt->MouseExists = FALSE; - DevExt->MouseState = MouseIdle; - DPRINT("Mouse returned bad reset reply: " - "%x (expected aa)\n", *Value); - } - return TRUE; - case ExpectingResetId: - if (0x00 == *Value) { - DevExt->MouseResetState++; - DevExt->MouseType = GenericPS2; - I8042IsrWritePortMouse(DevExt, 0xF2); - } else { - DevExt->MouseExists = FALSE; - DevExt->MouseState = MouseIdle; - DPRINT1("Mouse returned bad reset reply part two: " - "%x (expected 0)\n", *Value); - } - return TRUE; - case ExpectingGetDeviceIdACK: - if (MOUSE_ACK == *Value) { - DevExt->MouseResetState++; - } else if (MOUSE_NACK == *Value || - MOUSE_ERROR == *Value) { - DevExt->MouseResetState++; - /* Act as if 00 (normal mouse) was received */ - DPRINT("Mouse doesn't support 0xd2, " - "(returns %x, expected %x), faking.\n", - *Value, MOUSE_ACK); - *Value = 0; - I8042MouseResetIsr(DevExt, Status, Value); - } - return TRUE; - case ExpectingGetDeviceIdValue: - switch (*Value) { - case 0x02: - DevExt->MouseAttributes.MouseIdentifier = - BALLPOINT_I8042_HARDWARE; - break; - case 0x03: - case 0x04: - DevExt->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - break; + switch (DeviceExtension->MouseResetState) + { + case 1100: /* the first ack, drop it. */ + DeviceExtension->MouseResetState = ExpectingReset; + return TRUE; + case ExpectingReset: + /* First, 0xFF is sent. The mouse is supposed to say AA00 if ok, FC00 if not. */ + if (0xAA == Value) + { + DeviceExtension->MouseResetState++; + } + else + { + PortDeviceExtension->Flags &= ~MOUSE_PRESENT; + DeviceExtension->MouseState = MouseIdle; + DPRINT("Mouse returned bad reset reply: %x (expected aa)\n", Value); + } + return TRUE; + case ExpectingResetId: + if (0x00 == Value) + { + DeviceExtension->MouseResetState++; + DeviceExtension->MouseType = GenericPS2; + i8042MouIsrWritePort(PortDeviceExtension, 0xF2); + } + else + { + PortDeviceExtension->Flags &= ~MOUSE_PRESENT; + DeviceExtension->MouseState = MouseIdle; + DPRINT1("Mouse returned bad reset reply part two: %x (expected 0)\n", Value); + } + return TRUE; + case ExpectingGetDeviceIdACK: + if (MOUSE_ACK == Value) + { + DeviceExtension->MouseResetState++; + } + else if (MOUSE_NACK == Value || MOUSE_ERROR == Value) + { + DeviceExtension->MouseResetState++; + /* Act as if 00 (normal mouse) was received */ + DPRINT("Mouse doesn't support 0xd2, (returns %x, expected %x), faking\n", Value, MOUSE_ACK); + i8042MouResetIsr(DeviceExtension, Status, 0); + } + return TRUE; + case ExpectingGetDeviceIdValue: + switch (Value) + { + case 0x02: + DeviceExtension->MouseAttributes.MouseIdentifier = + BALLPOINT_I8042_HARDWARE; + break; + case 0x03: + case 0x04: + DeviceExtension->MouseAttributes.MouseIdentifier = + WHEELMOUSE_I8042_HARDWARE; + break; + default: + DeviceExtension->MouseAttributes.MouseIdentifier = + MOUSE_I8042_HARDWARE; + } + DeviceExtension->MouseResetState++; + i8042MouIsrWritePort(PortDeviceExtension, 0xE8); + return TRUE; + case ExpectingSetResolutionDefaultACK: + DeviceExtension->MouseResetState++; + i8042MouIsrWritePort(PortDeviceExtension, 0x00); + return TRUE; + case ExpectingSetResolutionDefaultValueACK: + DeviceExtension->MouseResetState = ExpectingSetScaling1to1ACK; + i8042MouIsrWritePort(PortDeviceExtension, 0xE6); + return TRUE; + case ExpectingSetScaling1to1ACK: + case ExpectingSetScaling1to1ACK2: + DeviceExtension->MouseResetState++; + i8042MouIsrWritePort(PortDeviceExtension, 0xE6); + return TRUE; + case ExpectingSetScaling1to1ACK3: + DeviceExtension->MouseResetState++; + i8042MouIsrWritePort(PortDeviceExtension, 0xE9); + return TRUE; + case ExpectingReadMouseStatusACK: + DeviceExtension->MouseResetState++; + return TRUE; + case ExpectingReadMouseStatusByte1: + DeviceExtension->MouseLogiBuffer[0] = Value; + DeviceExtension->MouseResetState++; + return TRUE; + case ExpectingReadMouseStatusByte2: + DeviceExtension->MouseLogiBuffer[1] = Value; + DeviceExtension->MouseResetState++; + return TRUE; + case ExpectingReadMouseStatusByte3: + DeviceExtension->MouseLogiBuffer[2] = Value; + /* Now MouseLogiBuffer is a set of info. If the second + * byte is 0, the mouse didn't understand the magic + * code. Otherwise, it it a Logitech and the second byte + * is the number of buttons, bit 7 of the first byte tells + * if it understands special E7 commands, the rest is an ID. + */ + if (DeviceExtension->MouseLogiBuffer[1]) + { + DeviceExtension->MouseAttributes.NumberOfButtons = + DeviceExtension->MouseLogiBuffer[1]; + DeviceExtension->MouseType = Ps2pp; + i8042MouIsrWritePort(PortDeviceExtension, 0xF3); + DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK; + /* TODO: Go through EnableWheel and Enable5Buttons */ + return TRUE; + } + DeviceExtension->MouseResetState = EnableWheel; + i8042MouResetIsr(DeviceExtension, Status, Value); + return TRUE; + case EnableWheel: + i8042MouIsrWritePort(PortDeviceExtension, 0xF3); + DeviceExtension->MouseResetState = 1001; + return TRUE; + case 1001: + i8042MouIsrWritePort(PortDeviceExtension, 0xC8); + DeviceExtension->MouseResetState++; + return TRUE; + case 1002: + case 1004: + i8042MouIsrWritePort(PortDeviceExtension, 0xF3); + DeviceExtension->MouseResetState++; + return TRUE; + case 1003: + i8042MouIsrWritePort(PortDeviceExtension, 0x64); + DeviceExtension->MouseResetState++; + return TRUE; + case 1005: + i8042MouIsrWritePort(PortDeviceExtension, 0x50); + DeviceExtension->MouseResetState++; + return TRUE; + case 1006: + i8042MouIsrWritePort(PortDeviceExtension, 0xF2); + DeviceExtension->MouseResetState++; + return TRUE; + case 1007: + /* Ignore ACK */ + DeviceExtension->MouseResetState++; + return TRUE; + case 1008: + if (0x03 == Value) { + /* It's either an Intellimouse or Intellimouse Explorer. */ + DeviceExtension->MouseAttributes.NumberOfButtons = 3; + DeviceExtension->MouseAttributes.MouseIdentifier = + WHEELMOUSE_I8042_HARDWARE; + DeviceExtension->MouseType = Intellimouse; + DeviceExtension->MouseResetState = Enable5Buttons; + i8042MouResetIsr(DeviceExtension, Status, Value); + } + else + { + /* Just set the default settings and be done */ + i8042MouIsrWritePort(PortDeviceExtension, 0xF3); + DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK; + } + return TRUE; + case Enable5Buttons: + i8042MouIsrWritePort(PortDeviceExtension, 0xF3); + DeviceExtension->MouseResetState = 1021; + return TRUE; + case 1022: + case 1024: + i8042MouIsrWritePort(PortDeviceExtension, 0xF3); + DeviceExtension->MouseResetState++; + return TRUE; + case 1021: + case 1023: + i8042MouIsrWritePort(PortDeviceExtension, 0xC8); + DeviceExtension->MouseResetState++; + return TRUE; + case 1025: + i8042MouIsrWritePort(PortDeviceExtension, 0x50); + DeviceExtension->MouseResetState++; + return TRUE; + case 1026: + i8042MouIsrWritePort(PortDeviceExtension, 0xF2); + DeviceExtension->MouseResetState++; + return TRUE; + case 1027: + if (0x04 == Value) + { + DeviceExtension->MouseAttributes.NumberOfButtons = 5; + DeviceExtension->MouseAttributes.MouseIdentifier = + WHEELMOUSE_I8042_HARDWARE; + DeviceExtension->MouseType = IntellimouseExplorer; + } + i8042MouIsrWritePort(PortDeviceExtension, 0xF3); + DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK; + return TRUE; + case ExpectingSetSamplingRateACK: + i8042MouIsrWritePort(PortDeviceExtension, + (UCHAR)DeviceExtension->MouseAttributes.SampleRate); + DeviceExtension->MouseResetState++; + return TRUE; + case ExpectingSetSamplingRateValueACK: + if (MOUSE_NACK == Value) + { + i8042MouIsrWritePort(PortDeviceExtension, 0x3C); + DeviceExtension->MouseAttributes.SampleRate = PortDeviceExtension->Settings.SampleRate; + DeviceExtension->MouseResetState = 1040; + return TRUE; + } + case 1040: /* Fallthrough */ + i8042MouIsrWritePort(PortDeviceExtension, 0xE8); + DeviceExtension->MouseResetState = ExpectingFinalResolutionACK; + return TRUE; + case ExpectingFinalResolutionACK: + i8042MouIsrWritePort(PortDeviceExtension, + (UCHAR)(PortDeviceExtension->Settings.MouseResolution & 0xff)); + DPRINT("Mouse resolution %lu\n", + PortDeviceExtension->Settings.MouseResolution); + DeviceExtension->MouseResetState = ExpectingFinalResolutionValueACK; + return TRUE; + case ExpectingFinalResolutionValueACK: + i8042MouIsrWritePort(PortDeviceExtension, 0xF4); + DeviceExtension->MouseResetState = ExpectingEnableACK; + return TRUE; + case ExpectingEnableACK: + DeviceExtension->MouseState = MouseIdle; + DeviceExtension->MouseTimeoutState = TimeoutCancel; + DPRINT("Mouse type = %u\n", DeviceExtension->MouseType); + return TRUE; default: - DevExt->MouseAttributes.MouseIdentifier = - MOUSE_I8042_HARDWARE; - } - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0xE8); - return TRUE; - case ExpectingSetResolutionDefaultACK: - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0x00); - return TRUE; - case ExpectingSetResolutionDefaultValueACK: - DevExt->MouseResetState = ExpectingSetScaling1to1ACK; - I8042IsrWritePortMouse(DevExt, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK: - case ExpectingSetScaling1to1ACK2: - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK3: - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0xE9); - return TRUE; - case ExpectingReadMouseStatusACK: - DevExt->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte1: - DevExt->MouseLogiBuffer[0] = *Value; - DevExt->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte2: - DevExt->MouseLogiBuffer[1] = *Value; - DevExt->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte3: - DevExt->MouseLogiBuffer[2] = *Value; - /* Now MouseLogiBuffer is a set of info. If the second - * byte is 0, the mouse didn't understand the magic - * code. Otherwise, it it a Logitech and the second byte - * is the number of buttons, bit 7 of the first byte tells - * if it understands special E7 commands, the rest is an ID. - */ - if (DevExt->MouseLogiBuffer[1]) { - DevExt->MouseAttributes.NumberOfButtons = - DevExt->MouseLogiBuffer[1]; - /* For some reason the ID is the wrong way around */ - DevExt->MouseLogitechID = - ((DevExt->MouseLogiBuffer[0] >> 4) & 0x07) | - ((DevExt->MouseLogiBuffer[0] << 3) & 0x78); - DevExt->MouseType = Ps2pp; - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - /* TODO: Go through EnableWheel and Enable5Buttons */ - } - DevExt->MouseResetState = EnableWheel; - I8042MouseResetIsr(DevExt, Status, Value); - return TRUE; - case EnableWheel: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = 1001; - return TRUE; - case 1001: - I8042IsrWritePortMouse(DevExt, 0xc8); - DevExt->MouseResetState++; - return TRUE; - case 1002: - case 1004: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState++; - return TRUE; - case 1003: - I8042IsrWritePortMouse(DevExt, 0x64); - DevExt->MouseResetState++; - return TRUE; - case 1005: - I8042IsrWritePortMouse(DevExt, 0x50); - DevExt->MouseResetState++; - return TRUE; - case 1006: - I8042IsrWritePortMouse(DevExt, 0xf2); - DevExt->MouseResetState++; - return TRUE; - case 1007: - /* Ignore ACK */ - DevExt->MouseResetState++; - return TRUE; - case 1008: - /* Now if the value == 3, it's either an Intellimouse - * or Intellimouse Explorer. */ - if (0x03 == *Value) { - DevExt->MouseAttributes.NumberOfButtons = 3; - DevExt->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DevExt->MouseType = Intellimouse; - DevExt->MouseResetState = Enable5Buttons; - I8042MouseResetIsr(DevExt, Status, Value); - return TRUE; - } /* Else, just set the default settings and be done */ - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - case Enable5Buttons: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = 1021; - return TRUE; - case 1022: - case 1024: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState++; - return TRUE; - case 1021: - case 1023: - I8042IsrWritePortMouse(DevExt, 0xc8); - DevExt->MouseResetState++; - return TRUE; - case 1025: - I8042IsrWritePortMouse(DevExt, 0x50); - DevExt->MouseResetState++; - return TRUE; - case 1026: - I8042IsrWritePortMouse(DevExt, 0xf2); - DevExt->MouseResetState++; - return TRUE; - case 1027: - if (0x04 == *Value) { - DevExt->MouseAttributes.NumberOfButtons = 5; - DevExt->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DevExt->MouseType = IntellimouseExplorer; - } - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - case ExpectingSetSamplingRateACK: - I8042IsrWritePortMouse(DevExt, - (UCHAR)DevExt->MouseAttributes.SampleRate); - DevExt->MouseResetState++; - return TRUE; - case ExpectingSetSamplingRateValueACK: - if (MOUSE_NACK == *Value) { - I8042IsrWritePortMouse(DevExt, 0x3c); - DevExt->MouseAttributes.SampleRate = 60; - DevExt->MouseResetState = 1040; - return TRUE; - } - case 1040: /* Fallthrough */ - I8042IsrWritePortMouse(DevExt, 0xe8); - DevExt->MouseResetState = ExpectingFinalResolutionACK; - return TRUE; - case ExpectingFinalResolutionACK: - I8042IsrWritePortMouse(DevExt, - (UCHAR)(DevExt->Settings.MouseResolution & 0xff)); - DPRINT("%x\n", DevExt->Settings.MouseResolution); - DevExt->MouseResetState = ExpectingFinalResolutionValueACK; - return TRUE; - case ExpectingFinalResolutionValueACK: - I8042IsrWritePortMouse(DevExt, 0xf4); - DevExt->MouseResetState = ExpectingEnableACK; - return TRUE; - case ExpectingEnableACK: - DevExt->MouseState = MouseIdle; - DevExt->MouseTimeoutState = TimeoutCancel; - DPRINT("Mouse type = %d\n", DevExt->MouseType); - return TRUE; - default: - if (DevExt->MouseResetState < 100 || - DevExt->MouseResetState > 999) - DPRINT1("MouseResetState went out of range: %d\n", - DevExt->MouseResetState); - return FALSE; + if (DeviceExtension->MouseResetState < 100 || DeviceExtension->MouseResetState > 999) + DPRINT1("MouseResetState went out of range: %lu\n", DeviceExtension->MouseResetState); + return FALSE; } } -/* - * Prepare for reading the next packet and queue the dpc for handling - * this one. - * - * Context is the device object. - */ -VOID STDCALL I8042QueueMousePacket(PVOID Context) -{ - PDEVICE_OBJECT DeviceObject = Context; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DevExt->MouseComplete = TRUE; - DevExt->MouseInBuffer++; - if (DevExt->MouseInBuffer > - DevExt->MouseAttributes.InputDataQueueLength) { - DPRINT1("Mouse buffer overflow\n"); - DevExt->MouseInBuffer--; - } - - DPRINT("Irq completes mouse packet\n"); - KeInsertQueueDpc(&DevExt->DpcMouse, DevExt, NULL); -} - -/* - * Updates ButtonFlags according to RawButtons and a saved state; - * Only takes in account the bits that are set in Mask - */ -VOID STDCALL I8042MouseHandleButtons(PDEVICE_EXTENSION DevExt, - USHORT Mask) -{ - PMOUSE_INPUT_DATA MouseInput = DevExt->MouseBuffer + - DevExt->MouseInBuffer; - USHORT NewButtonData = (USHORT)(MouseInput->RawButtons & Mask); - USHORT ButtonDiff = (NewButtonData ^ DevExt->MouseButtonState) & Mask; - - /* Note that the defines are such: - * MOUSE_LEFT_BUTTON_DOWN 1 - * MOUSE_LEFT_BUTTON_UP 2 - */ - MouseInput->ButtonFlags |= (NewButtonData & ButtonDiff) | - (((~(NewButtonData)) << 1) & - (ButtonDiff << 1)) | - (MouseInput->RawButtons & 0xfc00); - - DPRINT("Left raw/up/down: %d/%d/%d\n", MouseInput->RawButtons & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_UP); - - DevExt->MouseButtonState = (DevExt->MouseButtonState & ~Mask) | - (NewButtonData & Mask); -} - -VOID STDCALL I8042MouseHandle(PDEVICE_EXTENSION DevExt, - UCHAR Output) -{ - PMOUSE_INPUT_DATA MouseInput = DevExt->MouseBuffer + - DevExt->MouseInBuffer; - CHAR Scroll; - - switch (DevExt->MouseState) { - case MouseIdle: - /* This bit should be 1, if not drop the packet, we - * might be lucky and get in sync again - */ - if (!(Output & 8)) { - DPRINT1("Bad input, dropping..\n"); - return; - } - - MouseInput->Buttons = 0; - MouseInput->RawButtons = 0; - MouseInput->Flags = MOUSE_MOVE_RELATIVE; - - /* Note how we ignore the overflow bits, like Windows - * is said to do. There's no reasonable thing to do - * anyway. - */ - - if (Output & 16) - MouseInput->LastX = 1; - else - MouseInput->LastX = 0; - - if (Output & 32) - MouseInput->LastY = 1; - else - MouseInput->LastY = 0; - - if (Output & 1) { - MouseInput->RawButtons |= MOUSE_LEFT_BUTTON_DOWN; - } - - if (Output & 2) { - MouseInput->RawButtons |= MOUSE_RIGHT_BUTTON_DOWN; - } - - if (Output & 4) { - MouseInput->RawButtons |= MOUSE_MIDDLE_BUTTON_DOWN; - } - DevExt->MouseState = XMovement; - break; - case XMovement: - if (MouseInput->LastX) - MouseInput->LastX = (LONG) Output - 256; - else - MouseInput->LastX = Output; - - DevExt->MouseState = YMovement; - break; - case YMovement: - if (MouseInput->LastY) - MouseInput->LastY = (LONG)Output - 256; - else - MouseInput->LastY = (LONG)Output; - - /* Windows wants it the other way around */ - MouseInput->LastY = -MouseInput->LastY; - - if (DevExt->MouseType == GenericPS2 || - DevExt->MouseType == Ps2pp) { - I8042MouseHandleButtons(DevExt, - MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN); - I8042QueueMousePacket( - DevExt->MouseObject); - DevExt->MouseState = MouseIdle; - } else { - DevExt->MouseState = ZMovement; - } - break; - case ZMovement: - Scroll = Output & 0x0f; - if (Scroll & 8) - Scroll |= 0xf0; - - if (Scroll) { - MouseInput->RawButtons |= MOUSE_WHEEL; - MouseInput->ButtonData = (USHORT)(Scroll * -WHEEL_DELTA); - } - - if (DevExt->MouseType == IntellimouseExplorer) { - if (Output & 16) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - - if (Output & 32) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - } - I8042MouseHandleButtons(DevExt, MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN | - MOUSE_BUTTON_4_DOWN | - MOUSE_BUTTON_5_DOWN); - I8042QueueMousePacket(DevExt->MouseObject); - DevExt->MouseState = MouseIdle; - break; - default: - DPRINT1("Unexpected state!\n"); - } -} - -BOOLEAN STDCALL I8042InterruptServiceMouse(struct _KINTERRUPT *Interrupt, - VOID *Context) +BOOLEAN NTAPI +i8042MouInterruptService( + IN PKINTERRUPT Interrupt, + PVOID Context) { + PI8042_MOUSE_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + ULONG Counter; UCHAR Output, PortStatus; NTSTATUS Status; - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION) Context; - ULONG Iterations = 0; - do { - Status = I8042ReadStatus(&PortStatus); - Status = I8042ReadData(&Output); - Iterations++; - if (STATUS_SUCCESS == Status) + DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + Counter = PortDeviceExtension->Settings.PollStatusIterations; + + while (Counter) + { + Status = i8042ReadStatus(PortDeviceExtension, &PortStatus); + if (!NT_SUCCESS(Status)) + { + DPRINT("i8042ReadStatus() failed with status 0x%08lx\n", Status); + return FALSE; + } + Status = i8042ReadMouseData(PortDeviceExtension, &Output); + if (NT_SUCCESS(Status)) break; KeStallExecutionProcessor(1); - } while (Iterations < DevExt->Settings.PollStatusIterations); - - if (STATUS_SUCCESS != Status) { - DPRINT1("Spurious I8042 mouse interrupt\n"); + Counter--; + } + if (Counter == 0) + { + DPRINT("Spurious i8042 mouse interrupt\n"); return FALSE; } - DPRINT("Got: %x\n", Output); + DPRINT("Got: 0x%02x\n", Output); - if (I8042PacketIsr(DevExt, Output)) { - if (DevExt->PacketComplete) { + if (i8042PacketIsr(PortDeviceExtension, Output)) + { + if (PortDeviceExtension->PacketComplete) + { DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DevExt->DpcKbd, DevExt, NULL); + KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL); } DPRINT("Irq eaten by packet\n"); return TRUE; } - I8042MouseInputTestTimeout(DevExt); + DPRINT("Irq is mouse input\n"); - if (I8042MouseResetIsr(DevExt, PortStatus, &Output)) { + i8042MouInputTestTimeout(DeviceExtension); + + if (i8042MouResetIsr(DeviceExtension, PortStatus, Output)) + { DPRINT("Handled by ResetIsr or hooked Isr\n"); - if (NoChange != DevExt->MouseTimeoutState) { - KeInsertQueueDpc(&DevExt->DpcMouse, DevExt, NULL); + if (NoChange != DeviceExtension->MouseTimeoutState) { + KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL); } return TRUE; } - if (DevExt->MouseType == Ps2pp) - I8042MouseHandlePs2pp(DevExt, Output); + if (DeviceExtension->MouseType == Ps2pp) + i8042MouHandlePs2pp(DeviceExtension, Output); else - I8042MouseHandle(DevExt, Output); + i8042MouHandle(DeviceExtension, Output); return TRUE; } -VOID STDCALL I8042DpcRoutineMouse(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) +/* ================================================ + * FIXME: this part is taken from psaux.sys driver, + * and doesn't follow the coding style of this file + * ===============================================*/ + +#define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8 +#define PSMOUSE_CMD_ENABLE 0x00f4 +#define PSMOUSE_CMD_GETID (0x0200 | MOU_CMD_GET_ID) +#define PSMOUSE_CMD_RESET_BAT (0x0200 | MOU_CMD_RESET) +#define PSMOUSE_RET_ACK MOUSE_ACK +#define PSMOUSE_RET_NAK MOUSE_NACK +#define MOUSE_INTERRUPTS_ON (CCB_TRANSLATE | \ + CCB_SYSTEM_FLAG | \ + CCB_MOUSE_INT_ENAB) + +typedef struct _I8042_MOUSE_EXTENSION_OLD { - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)SystemArgument1; - ULONG MouseTransferred = 0; - ULONG MouseInBufferCopy; - KIRQL Irql; - LARGE_INTEGER Timeout; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + UCHAR pkt[8]; + UCHAR ack; + UINT RepliesExpected; +} I8042_MOUSE_EXTENSION_OLD, *PI8042_MOUSE_EXTENSION_OLD; - switch (DevExt->MouseTimeoutState) { - case TimeoutStart: - DevExt->MouseTimeoutState = NoChange; - if (DevExt->MouseTimeoutActive && - !KeCancelTimer(&DevExt->TimerMouseTimeout)) { - /* The timer fired already, give up */ - DevExt->MouseTimeoutActive = FALSE; - return; - } - - Timeout.QuadPart = -15000000; - /* 1.5 seconds, should be enough */ - - KeSetTimer(&DevExt->TimerMouseTimeout, - Timeout, - &DevExt->DpcMouseTimeout); - DevExt->MouseTimeoutActive = TRUE; - return; - case TimeoutCancel: - DevExt->MouseTimeoutState = NoChange; - KeCancelTimer(&DevExt->TimerMouseTimeout); - DevExt->MouseTimeoutActive = FALSE; - default: - /* nothing, don't want a warning */ ; - } - - /* Should be unlikely */ - if (!DevExt->MouseComplete) - return; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->MouseComplete = FALSE; - MouseInBufferCopy = DevExt->MouseInBuffer; - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - - DPRINT ("Send a mouse packet\n"); - - if (!DevExt->MouseData.ClassService) - return; - - ((PSERVICE_CALLBACK_ROUTINE) DevExt->MouseData.ClassService)( - DevExt->MouseData.ClassDeviceObject, - DevExt->MouseBuffer, - DevExt->MouseBuffer + MouseInBufferCopy, - &MouseTransferred); - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->MouseInBuffer -= MouseTransferred; - if (DevExt->MouseInBuffer) - RtlMoveMemory(DevExt->MouseBuffer, - DevExt->MouseBuffer+MouseTransferred, - DevExt->MouseInBuffer * sizeof(MOUSE_INPUT_DATA)); - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); -} - -/* This timer DPC will be called when the mouse reset times out. - * I'll just send the 'disable mouse port' command to the controller - * and say the mouse doesn't exist. - */ -VOID STDCALL I8042DpcRoutineMouseTimeout(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) +/* Sends a byte to the mouse */ +static INT SendByte( + IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension, + IN UCHAR byte) { - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)DeferredContext; - KIRQL Irql; + INT timeout = 100; /* 100 msec */ + UCHAR scancode; + LARGE_INTEGER Millisecond_Timeout; - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); + Millisecond_Timeout.QuadPart = -10000L; - DPRINT1("Mouse initialization timeout! (substate %x) " - "Disabling mouse.\n", - DevExt->MouseResetState); - - if (!I8042MouseDisable(DevExt)) { - DPRINT1("Failed to disable mouse.\n"); - } - - DevExt->MouseExists = FALSE; - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); -} - -/* - * Process the mouse internal device requests - * returns FALSE if it doesn't understand the - * call so someone else can handle it. - */ -#if 0 -static BOOLEAN STDCALL I8042StartIoMouse(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - case IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER: - I8042StartPacket( - DevExt, - DeviceObject, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - Stk->Parameters.DeviceIoControl.InputBufferLength, - Irp); - break; - - default: - return FALSE; - } - - return TRUE; -} -#endif - -/* - * Runs the mouse IOCTL_INTERNAL dispatch. - * Returns NTSTATUS_INVALID_DEVICE_REQUEST if it doesn't handle this request - * so someone else can have a try at it. - */ -NTSTATUS STDCALL I8042InternalDeviceControlMouse(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DPRINT("InternalDeviceControl\n"); - - Irp->IoStatus.Information = 0; - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - - case IOCTL_INTERNAL_MOUSE_CONNECT: - DPRINT("IOCTL_INTERNAL_MOUSE_CONNECT\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(CONNECT_DATA)) { - DPRINT1("Mouse IOCTL_INTERNAL_MOUSE_CONNECT " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - - if (!DevExt->MouseExists) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; - goto intcontfailure; - } - - if (DevExt->MouseClaimed) { - DPRINT1("IOCTL_INTERNAL_MOUSE_CONNECT: " - "Mouse is already claimed\n"); - Irp->IoStatus.Status = STATUS_SHARING_VIOLATION; - goto intcontfailure; - } - - memcpy(&DevExt->MouseData, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - sizeof(CONNECT_DATA)); - DevExt->MouseHook.IsrWritePort = I8042IsrWritePortMouse; - DevExt->MouseHook.QueueMousePacket = - I8042QueueMousePacket; - DevExt->MouseHook.CallContext = DevExt; + DeviceExtension->ack = 0; + i8042IsrWritePort(DeviceExtension->PortDeviceExtension, byte, CTRL_WRITE_MOUSE); + while ((DeviceExtension->ack == 0) && timeout--) + { + if (i8042ReadKeyboardData(DeviceExtension->PortDeviceExtension, &scancode)) { - PIO_WORKITEM WorkItem; - PI8042_HOOK_WORKITEM WorkItemData; - - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) { - DPRINT ("IOCTL_INTERNAL_MOUSE_CONNECT: " - "Can't allocate work item\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - goto intcontfailure; + switch(scancode) + { + case PSMOUSE_RET_ACK: + DeviceExtension->ack = 1; + break; + case PSMOUSE_RET_NAK: + DeviceExtension->ack = -1; + break; + default: + DeviceExtension->ack = 1; /* Workaround for mice which don't ACK the Get ID command */ + if (DeviceExtension->RepliesExpected) + DeviceExtension->pkt[--DeviceExtension->RepliesExpected] = scancode; + break; } - - WorkItemData = ExAllocatePoolWithTag( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM), - TAG_I8042); - if (!WorkItemData) { - DPRINT ("IOCTL_INTERNAL_MOUSE_CONNECT: " - "Can't allocate work item data\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - IoFreeWorkItem(WorkItem); - goto intcontfailure; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Target = - DevExt->MouseData.ClassDeviceObject; - WorkItemData->Irp = Irp; - - IoMarkIrpPending(Irp); - DevExt->MouseState = MouseResetting; - DevExt->MouseResetState = 1100; - IoQueueWorkItem(WorkItem, - I8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - - Irp->IoStatus.Status = STATUS_PENDING; + return (INT)(-(DeviceExtension->ack <= 0)); } - - break; - case IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER: - DPRINT("IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < 1) { - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - if (!DevExt->MouseInterruptObject) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; - goto intcontfailure; - } - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_MOUSE_QUERY_ATTRIBUTES: - DPRINT("IOCTL_MOUSE_QUERY_ATTRIBUTES\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(MOUSE_ATTRIBUTES)) { - DPRINT("Mouse IOCTL_MOUSE_QUERY_ATTRIBUTES " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->MouseAttributes, - sizeof(MOUSE_ATTRIBUTES)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - default: - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - break; + KeDelayExecutionThread(KernelMode, FALSE, &Millisecond_Timeout); } - -intcontfailure: - return Irp->IoStatus.Status; + return (INT)(-(DeviceExtension->ack <= 0)); } -BOOLEAN STDCALL I8042MouseEnable(PDEVICE_EXTENSION DevExt) +/* Send a PS/2 command to the mouse. */ +static INT SendCommand( + IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension, + IN PUCHAR param, + IN INT command) { - UCHAR Value; - NTSTATUS Status; + LARGE_INTEGER Millisecond_Timeout; + UCHAR scancode; + INT timeout = 500; /* 500 msec */ + UCHAR send = (command >> 12) & 0xf; + UCHAR receive = (command >> 8) & 0xf; + UCHAR i; - DPRINT("Enabling mouse\n"); + Millisecond_Timeout.QuadPart = -10000L; - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; + DeviceExtension->RepliesExpected = receive; + if (command == PSMOUSE_CMD_RESET_BAT) + timeout = 2000; /* 2 sec */ + + if (command & 0xff) + if (SendByte(DeviceExtension, command & 0xff)) + return (INT)(DeviceExtension->RepliesExpected = 0) - 1; + + for (i = 0; i < send; i++) + if (SendByte(DeviceExtension, param[i])) + return (INT)(DeviceExtension->RepliesExpected = 0) - 1; + + while (DeviceExtension->RepliesExpected && timeout--) + { + if (DeviceExtension->RepliesExpected == 1 && command == PSMOUSE_CMD_RESET_BAT) + timeout = 100; + + if (DeviceExtension->RepliesExpected == 1 && command == PSMOUSE_CMD_GETID && + DeviceExtension->pkt[1] != 0xab && DeviceExtension->pkt[1] != 0xac) + { + DeviceExtension->RepliesExpected = 0; + break; + } + + if (i8042ReadKeyboardData(DeviceExtension->PortDeviceExtension, &scancode)) + { + DeviceExtension->pkt[--DeviceExtension->RepliesExpected] = scancode; + } + + KeDelayExecutionThread (KernelMode, FALSE, &Millisecond_Timeout); } - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } + for (i = 0; i < receive; i++) + param[i] = DeviceExtension->pkt[(receive - 1) - i]; - Value &= ~(0x20); // don't disable mouse - Value |= 0x02; // enable mouse interrupts + if (DeviceExtension->RepliesExpected) + return (int)(DeviceExtension->RepliesExpected = 0) - 1; - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; + return 0; } -BOOLEAN STDCALL I8042MouseDisable(PDEVICE_EXTENSION DevExt) +/* Detect if mouse is just a standard ps/2 mouse */ +static BOOLEAN TestMouse( + IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension) { - UCHAR Value; - NTSTATUS Status; + UCHAR param[4]; - DPRINT("Disabling mouse\n"); + param[0] = param[1] = 0xa5; - I8042Flush(); /* Just to be (kind of) sure */ + /* + * First, we check if it's a mouse. It should send 0x00 or 0x03 + * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. + */ + if(SendCommand(DeviceExtension, param, PSMOUSE_CMD_GETID)) + return -1; - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } + if(param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) + return -1; - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= 0x20; // don't disable mouse - Value &= ~(0x02); // enable mouse interrupts - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - I8042Flush(); - /* Just to be (kind of) sure; if the mouse would - * say something while we are disabling it, these bytes would - * block the keyboard. + /* + * Then we reset and disable the mouse so that it doesn't generate events. */ return TRUE; } -BOOLEAN STDCALL I8042DetectMouse(PDEVICE_EXTENSION DevExt) +/* Initialize the PS/2 mouse support */ +static BOOLEAN SetupMouse( + IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension) { - BOOLEAN Ok = TRUE; - NTSTATUS Status; - UCHAR Value; - UCHAR ExpectedReply[] = { 0xFA, 0xAA, 0x00 }; - unsigned ReplyByte; + LARGE_INTEGER Millisecond_Timeout; - if (! I8042Write(DevExt, I8042_CTRL_PORT, 0xD4) || - ! I8042Write(DevExt, I8042_DATA_PORT, 0xFF)) + Millisecond_Timeout.QuadPart = -10000L; + + /* setup */ + DeviceExtension->RepliesExpected = 0; + DeviceExtension->ack = 0; + + /* Enable the PS/2 mouse port */ + i8042Write(DeviceExtension->PortDeviceExtension, DeviceExtension->PortDeviceExtension->ControlPort, CONTROLLER_COMMAND_MOUSE_ENABLE); + + if(TestMouse(DeviceExtension)) { - DPRINT1("Failed to write reset command to mouse\n"); - Ok = FALSE; + DPRINT("Detected Mouse\n"); + + if(SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_ENABLE)) + DPRINT1("Failed to enable mouse!\n"); + + /* Enable controller interrupts */ + i8042Write(DeviceExtension->PortDeviceExtension, DeviceExtension->PortDeviceExtension->ControlPort, KBD_WRITE_MODE); + i8042Write(DeviceExtension->PortDeviceExtension, DeviceExtension->PortDeviceExtension->DataPort, MOUSE_INTERRUPTS_ON); } - for (ReplyByte = 0; - ReplyByte < sizeof(ExpectedReply) / sizeof(ExpectedReply[0]) && Ok; - ReplyByte++) - { - Status = I8042ReadDataWait(DevExt, &Value); - if (! NT_SUCCESS(Status)) - { - DPRINT1("No ACK after mouse reset, status 0x%08x\n", - Status); - Ok = FALSE; - } - else if (Value != ExpectedReply[ReplyByte]) - { - DPRINT1("Unexpected reply: 0x%02x (expected 0x%02x)\n", - Value, ExpectedReply[ReplyByte]); - Ok = FALSE; - } - } - - if (! Ok) - { - /* There is probably no mouse present. On some systems, - the probe locks the entire keyboard controller. Let's - try to get access to the keyboard again by sending a - reset */ - I8042Flush(); - I8042Write(DevExt, I8042_CTRL_PORT, KBD_SELF_TEST); - I8042ReadDataWait(DevExt, &Value); - I8042Flush(); - } - - DPRINT("Mouse %sdetected\n", Ok ? "" : "not "); - - return Ok; + return TRUE; +} + +static NTSTATUS OldInitialization( + IN PPORT_DEVICE_EXTENSION PortDeviceExtension) +{ + I8042_MOUSE_EXTENSION_OLD DeviceExtension; + + RtlZeroMemory(&DeviceExtension, sizeof(I8042_MOUSE_EXTENSION_OLD)); + DeviceExtension.PortDeviceExtension = PortDeviceExtension; + SetupMouse(&DeviceExtension); + return STATUS_SUCCESS; } diff --git a/reactos/drivers/input/i8042prt/pnp.c b/reactos/drivers/input/i8042prt/pnp.c new file mode 100644 index 00000000000..b60fb1bc0d1 --- /dev/null +++ b/reactos/drivers/input/i8042prt/pnp.c @@ -0,0 +1,666 @@ +/* + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/pnp.c + * PURPOSE: IRP_MJ_PNP operations + * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "i8042prt.h" + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +/* This is all pretty confusing. There's more than one way to + * disable/enable the keyboard. You can send KBD_ENABLE to the + * keyboard, and it will start scanning keys. Sending KBD_DISABLE + * will disable the key scanning but also reset the parameters to + * defaults. + * + * You can also send 0xAE to the controller for enabling the + * keyboard clock line and 0xAD for disabling it. Then it'll + * automatically get turned on at the next command. The last + * way is by modifying the bit that drives the clock line in the + * 'command byte' of the controller. This is almost, but not quite, + * the same as the AE/AD thing. The difference can be used to detect + * some really old broken keyboard controllers which I hope won't be + * necessary. + * + * We change the command byte, sending KBD_ENABLE/DISABLE seems to confuse + * some kvm switches. + */ +BOOLEAN +i8042ChangeMode( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR FlagsToDisable, + IN UCHAR FlagsToEnable) +{ + UCHAR Value; + NTSTATUS Status; + + if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, KBD_READ_MODE)) + { + DPRINT1("Can't read i8042 mode\n"); + return FALSE; + } + + Status = i8042ReadDataWait(DeviceExtension, &Value); + if (!NT_SUCCESS(Status)) + { + DPRINT1("No response after read i8042 mode\n"); + return FALSE; + } + + Value &= ~FlagsToDisable; + Value |= FlagsToEnable; + + if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, KBD_WRITE_MODE)) + { + DPRINT1("Can't set i8042 mode\n"); + return FALSE; + } + + if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value)) + { + DPRINT1("Can't send i8042 mode\n"); + return FALSE; + } + + return TRUE; +} + +static NTSTATUS +i8042BasicDetect( + IN PPORT_DEVICE_EXTENSION DeviceExtension) +{ + NTSTATUS Status; + UCHAR Value = 0; + + i8042Flush(DeviceExtension); + + if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST)) + { + DPRINT1("Writing CTRL_SELF_TEST command failed\n"); + return STATUS_IO_TIMEOUT; + } + + Status = i8042ReadDataWait(DeviceExtension, &Value); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to read CTRL_SELF_TEST response, status 0x%08lx\n", Status); + return Status; + } + + if (Value != 0x55) + { + DPRINT1("Got 0x%02x instead of 0x55\n", Value); + return STATUS_IO_DEVICE_ERROR; + } + + /* Don't enable keyboard and mouse interrupts, disable keyboard/mouse */ + if (!i8042ChangeMode(DeviceExtension, CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB, CCB_KBD_DISAB | CCB_MOUSE_DISAB)) + return STATUS_IO_DEVICE_ERROR; + + /* + * We used to send a KBD_LINE_TEST (0xAB) command here, but on at least HP + * Pavilion notebooks the response to that command was incorrect. + * So now we just assume that a keyboard is attached. + */ + DeviceExtension->Flags |= KEYBOARD_PRESENT; + + if (i8042Write(DeviceExtension, DeviceExtension->ControlPort, MOUSE_LINE_TEST)) + { + Status = i8042ReadDataWait(DeviceExtension, &Value); + if (NT_SUCCESS(Status) && Value == 0) + DeviceExtension->Flags |= MOUSE_PRESENT; + } + + if (IsFirstStageSetup()) + /* Ignore the mouse */ + DeviceExtension->Flags &= ~MOUSE_PRESENT; + + return STATUS_SUCCESS; +} + +static BOOLEAN +i8042DetectKeyboard( + IN PPORT_DEVICE_EXTENSION DeviceExtension) +{ + NTSTATUS Status; + + if (!i8042ChangeMode(DeviceExtension, 0, CCB_KBD_DISAB)) + return FALSE; + + i8042Flush(DeviceExtension); + + /* Set LEDs (that is not fatal if some error occurs) */ + Status = i8042SynchWritePort(DeviceExtension, 0, KBD_CMD_SET_LEDS, TRUE); + if (NT_SUCCESS(Status)) + { + Status = i8042SynchWritePort(DeviceExtension, 0, 0, TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT("Can't finish SET_LEDS (0x%08lx)\n", Status); + return FALSE; + } + } + else + { + DPRINT("Warning: can't write SET_LEDS (0x%08lx)\n", Status); + } + + /* Turn on translation */ + if (!i8042ChangeMode(DeviceExtension, 0, CCB_TRANSLATE)) + return FALSE; + + return TRUE; +} + +static BOOLEAN +i8042DetectMouse( + IN PPORT_DEVICE_EXTENSION DeviceExtension) +{ + BOOLEAN Ok = FALSE; + NTSTATUS Status; + UCHAR Value; + UCHAR ExpectedReply[] = { MOUSE_ACK, 0xAA, 0x00 }; + UCHAR ReplyByte; + + i8042Flush(DeviceExtension); + + if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_WRITE_MOUSE) + ||!i8042Write(DeviceExtension, DeviceExtension->DataPort, MOU_CMD_RESET)) + { + DPRINT1("Failed to write reset command to mouse\n"); + goto cleanup; + } + + for (ReplyByte = 0; + ReplyByte < sizeof(ExpectedReply) / sizeof(ExpectedReply[0]); + ReplyByte++) + { + Status = i8042ReadDataWait(DeviceExtension, &Value); + if (!NT_SUCCESS(Status)) + { + DPRINT1("No ACK after mouse reset, status 0x%08lx\n", Status); + goto cleanup; + } + else if (Value != ExpectedReply[ReplyByte]) + { + DPRINT1("Unexpected reply: 0x%02x (expected 0x%02x)\n", + Value, ExpectedReply[ReplyByte]); + goto cleanup; + } + } + + Ok = TRUE; + +cleanup: + if (!Ok) + { + /* There is probably no mouse present. On some systems, + the probe locks the entire keyboard controller. Let's + try to get access to the keyboard again by sending a + reset */ + i8042Flush(DeviceExtension); + i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST); + i8042ReadDataWait(DeviceExtension, &Value); + i8042Flush(DeviceExtension); + } + + DPRINT("Mouse %sdetected\n", Ok ? "" : "not "); + + return Ok; +} + +static NTSTATUS +i8042ConnectKeyboardInterrupt( + IN PI8042_KEYBOARD_EXTENSION DeviceExtension) +{ + PPORT_DEVICE_EXTENSION PortDeviceExtension; + KIRQL DirqlMax; + NTSTATUS Status; + + DPRINT("i8042ConnectKeyboardInterrupt()\n"); + + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + DirqlMax = MAX( + PortDeviceExtension->KeyboardInterrupt.Dirql, + PortDeviceExtension->MouseInterrupt.Dirql); + + DPRINT("KeyboardInterrupt.Vector %lu\n", + PortDeviceExtension->KeyboardInterrupt.Vector); + DPRINT("KeyboardInterrupt.Dirql %lu\n", + PortDeviceExtension->KeyboardInterrupt.Dirql); + DPRINT("KeyboardInterrupt.DirqlMax %lu\n", + DirqlMax); + DPRINT("KeyboardInterrupt.InterruptMode %s\n", + PortDeviceExtension->KeyboardInterrupt.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"); + DPRINT("KeyboardInterrupt.ShareInterrupt %s\n", + PortDeviceExtension->KeyboardInterrupt.ShareInterrupt ? "yes" : "no"); + DPRINT("KeyboardInterrupt.Affinity 0x%lx\n", + PortDeviceExtension->KeyboardInterrupt.Affinity); + Status = IoConnectInterrupt( + &PortDeviceExtension->KeyboardInterrupt.Object, + i8042KbdInterruptService, + DeviceExtension, &PortDeviceExtension->SpinLock, + PortDeviceExtension->KeyboardInterrupt.Vector, PortDeviceExtension->KeyboardInterrupt.Dirql, DirqlMax, + PortDeviceExtension->KeyboardInterrupt.InterruptMode, PortDeviceExtension->KeyboardInterrupt.ShareInterrupt, + PortDeviceExtension->KeyboardInterrupt.Affinity, FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoConnectInterrupt() failed with status 0x%08x\n", Status); + return Status; + } + + if (DirqlMax == PortDeviceExtension->KeyboardInterrupt.Dirql) + PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object; + PortDeviceExtension->Flags |= KEYBOARD_INITIALIZED; + return STATUS_SUCCESS; +} + +static NTSTATUS +i8042ConnectMouseInterrupt( + IN PI8042_MOUSE_EXTENSION DeviceExtension) +{ + PPORT_DEVICE_EXTENSION PortDeviceExtension; + KIRQL DirqlMax; + NTSTATUS Status; + + DPRINT("i8042ConnectMouseInterrupt()\n"); + + Status = i8042MouInitialize(DeviceExtension); + if (!NT_SUCCESS(Status)) + return Status; + + PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; + DirqlMax = MAX( + PortDeviceExtension->KeyboardInterrupt.Dirql, + PortDeviceExtension->MouseInterrupt.Dirql); + + DPRINT("MouseInterrupt.Vector %lu\n", + PortDeviceExtension->MouseInterrupt.Vector); + DPRINT("MouseInterrupt.Dirql %lu\n", + PortDeviceExtension->MouseInterrupt.Dirql); + DPRINT("MouseInterrupt.DirqlMax %lu\n", + DirqlMax); + DPRINT("MouseInterrupt.InterruptMode %s\n", + PortDeviceExtension->MouseInterrupt.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"); + DPRINT("MouseInterrupt.ShareInterrupt %s\n", + PortDeviceExtension->MouseInterrupt.ShareInterrupt ? "yes" : "no"); + DPRINT("MouseInterrupt.Affinity 0x%lx\n", + PortDeviceExtension->MouseInterrupt.Affinity); + Status = IoConnectInterrupt( + &PortDeviceExtension->MouseInterrupt.Object, + i8042MouInterruptService, + DeviceExtension, &PortDeviceExtension->SpinLock, + PortDeviceExtension->MouseInterrupt.Vector, PortDeviceExtension->MouseInterrupt.Dirql, DirqlMax, + PortDeviceExtension->MouseInterrupt.InterruptMode, PortDeviceExtension->MouseInterrupt.ShareInterrupt, + PortDeviceExtension->MouseInterrupt.Affinity, FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoConnectInterrupt() failed with status 0x%08x\n", Status); + goto cleanup; + } + + if (DirqlMax == PortDeviceExtension->MouseInterrupt.Dirql) + PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->MouseInterrupt.Object; + + PortDeviceExtension->Flags |= MOUSE_INITIALIZED; + Status = STATUS_SUCCESS; + +cleanup: + if (!NT_SUCCESS(Status)) + { + PortDeviceExtension->Flags &= ~MOUSE_INITIALIZED; + if (PortDeviceExtension->MouseInterrupt.Object) + { + IoDisconnectInterrupt(PortDeviceExtension->MouseInterrupt.Object); + PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object; + } + } + return Status; +} + +static NTSTATUS +EnableInterrupts( + IN PPORT_DEVICE_EXTENSION DeviceExtension) +{ + UCHAR FlagsToDisable = 0; + UCHAR FlagsToEnable = 0; + + /* Select the devices we have */ + if (DeviceExtension->Flags & KEYBOARD_PRESENT) + { + FlagsToDisable |= CCB_KBD_DISAB; + FlagsToEnable |= CCB_KBD_INT_ENAB; + } + if (DeviceExtension->Flags & MOUSE_PRESENT) + { + FlagsToDisable |= CCB_MOUSE_DISAB; + FlagsToEnable |= CCB_MOUSE_INT_ENAB; + } + if (!i8042ChangeMode(DeviceExtension, FlagsToDisable, FlagsToEnable)) + return STATUS_UNSUCCESSFUL; + + return STATUS_SUCCESS; +} + +static NTSTATUS +StartProcedure( + IN PPORT_DEVICE_EXTENSION DeviceExtension) +{ + NTSTATUS Status; + + if (DeviceExtension->DataPort == 0) + { + /* Unable to do something at the moment */ + return STATUS_SUCCESS; + } + + if (!(DeviceExtension->Flags & (KEYBOARD_PRESENT | MOUSE_PRESENT))) + { + /* Try to detect them */ + DPRINT("Check if the controller is really a i8042\n"); + Status = i8042BasicDetect(DeviceExtension); + if (!NT_SUCCESS(Status)) + { + DPRINT("i8042BasicDetect() failed with status 0x%08lx\n", Status); + return STATUS_UNSUCCESSFUL; + } + DPRINT("Detecting keyboard\n"); + if (!i8042DetectKeyboard(DeviceExtension)) + return STATUS_UNSUCCESSFUL; + DPRINT("Detecting mouse\n"); + if (!i8042DetectMouse(DeviceExtension)) + return STATUS_UNSUCCESSFUL; + DPRINT("Keyboard present: %s\n", DeviceExtension->Flags & KEYBOARD_PRESENT ? "YES" : "NO"); + DPRINT("Mouse present : %s\n", DeviceExtension->Flags & MOUSE_PRESENT ? "YES" : "NO"); + } + + /* Connect interrupts */ + if (DeviceExtension->Flags & KEYBOARD_PRESENT && + DeviceExtension->Flags & KEYBOARD_CONNECTED && + DeviceExtension->Flags & KEYBOARD_STARTED && + !(DeviceExtension->Flags & (MOUSE_PRESENT | KEYBOARD_INITIALIZED))) + { + /* No mouse, and the keyboard is ready */ + Status = i8042ConnectKeyboardInterrupt(DeviceExtension->KeyboardExtension); + if (NT_SUCCESS(Status)) + { + DeviceExtension->Flags |= KEYBOARD_INITIALIZED; + Status = EnableInterrupts(DeviceExtension); + } + } + else if (DeviceExtension->Flags & MOUSE_PRESENT && + DeviceExtension->Flags & MOUSE_CONNECTED && + DeviceExtension->Flags & MOUSE_STARTED && + !(DeviceExtension->Flags & (KEYBOARD_PRESENT | MOUSE_INITIALIZED))) + { + /* No keyboard, and the mouse is ready */ + Status = i8042ConnectMouseInterrupt(DeviceExtension->MouseExtension); + if (NT_SUCCESS(Status)) + { + DeviceExtension->Flags |= MOUSE_INITIALIZED; + Status = EnableInterrupts(DeviceExtension); + } + } + else if (DeviceExtension->Flags & KEYBOARD_PRESENT && + DeviceExtension->Flags & KEYBOARD_CONNECTED && + DeviceExtension->Flags & KEYBOARD_STARTED && + DeviceExtension->Flags & MOUSE_PRESENT && + DeviceExtension->Flags & MOUSE_CONNECTED && + DeviceExtension->Flags & MOUSE_STARTED && + !(DeviceExtension->Flags & (KEYBOARD_INITIALIZED | MOUSE_INITIALIZED))) + { + /* The keyboard and mouse are ready */ + Status = i8042ConnectKeyboardInterrupt(DeviceExtension->KeyboardExtension); + if (NT_SUCCESS(Status)) + { + DeviceExtension->Flags |= KEYBOARD_INITIALIZED; + Status = i8042ConnectMouseInterrupt(DeviceExtension->MouseExtension); + if (NT_SUCCESS(Status)) + { + DeviceExtension->Flags |= MOUSE_INITIALIZED; + Status = EnableInterrupts(DeviceExtension); + } + } + } + else + { + /* Nothing to do */ + Status = STATUS_SUCCESS; + } + + return Status; +} + +static NTSTATUS +i8042PnpStartDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PCM_RESOURCE_LIST AllocatedResources, + IN PCM_RESOURCE_LIST AllocatedResourcesTranslated) +{ + PFDO_DEVICE_EXTENSION DeviceExtension; + PPORT_DEVICE_EXTENSION PortDeviceExtension; + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor, ResourceDescriptorTranslated; + INTERRUPT_DATA InterruptData; + BOOLEAN FoundDataPort = FALSE; + BOOLEAN FoundControlPort = FALSE; + BOOLEAN FoundIrq = FALSE; + ULONG i; + NTSTATUS Status; + + DPRINT("i8042PnpStartDevice(%p)\n", DeviceObject); + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + PortDeviceExtension = DeviceExtension->PortDeviceExtension; + + ASSERT(DeviceExtension->PnpState == dsStopped); + + if (!AllocatedResources) + { + DPRINT("No allocated resources sent to driver\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + if (AllocatedResources->Count != 1) + { + DPRINT("Wrong number of allocated resources sent to driver\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + if (AllocatedResources->List[0].PartialResourceList.Version != 1 + || AllocatedResources->List[0].PartialResourceList.Revision != 1 + || AllocatedResourcesTranslated->List[0].PartialResourceList.Version != 1 + || AllocatedResourcesTranslated->List[0].PartialResourceList.Revision != 1) + { + DPRINT("Revision mismatch: %u.%u != 1.1 or %u.%u != 1.1\n", + AllocatedResources->List[0].PartialResourceList.Version, + AllocatedResources->List[0].PartialResourceList.Revision, + AllocatedResourcesTranslated->List[0].PartialResourceList.Version, + AllocatedResourcesTranslated->List[0].PartialResourceList.Revision); + return STATUS_REVISION_MISMATCH; + } + + /* Get Irq and optionally control port and data port */ + for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++) + { + ResourceDescriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i]; + ResourceDescriptorTranslated = &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i]; + switch (ResourceDescriptor->Type) + { + case CmResourceTypePort: + { + if (ResourceDescriptor->u.Port.Length == 1) + { + /* We assume that the first ressource will + * be the control port and the second one + * will be the data port... + */ + if (!FoundDataPort) + { + PortDeviceExtension->DataPort = (PUCHAR)ResourceDescriptor->u.Port.Start.u.LowPart; + DPRINT("Found data port: 0x%lx\n", PortDeviceExtension->DataPort); + FoundDataPort = TRUE; + } + else if (!FoundControlPort) + { + PortDeviceExtension->ControlPort = (PUCHAR)ResourceDescriptor->u.Port.Start.u.LowPart; + DPRINT("Found control port: 0x%lx\n", PortDeviceExtension->ControlPort); + FoundControlPort = TRUE; + } + else + { + DPRINT("Too much I/O ranges provided\n", ResourceDescriptor->u.Port.Length); + return STATUS_INVALID_PARAMETER; + } + } + else + DPRINT1("Invalid I/O range length: 0x%lx\n", ResourceDescriptor->u.Port.Length); + break; + } + case CmResourceTypeInterrupt: + { + if (FoundIrq) + return STATUS_INVALID_PARAMETER; + InterruptData.Dirql = (KIRQL)ResourceDescriptorTranslated->u.Interrupt.Level; + InterruptData.Vector = ResourceDescriptorTranslated->u.Interrupt.Vector; + InterruptData.Affinity = ResourceDescriptorTranslated->u.Interrupt.Affinity; + if (ResourceDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED) + InterruptData.InterruptMode = Latched; + else + InterruptData.InterruptMode = LevelSensitive; + InterruptData.ShareInterrupt = (ResourceDescriptorTranslated->ShareDisposition == CmResourceShareShared); + DPRINT("Found irq resource: %lu\n", ResourceDescriptor->u.Interrupt.Vector); + FoundIrq = TRUE; + break; + } + default: + DPRINT("Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type); + } + } + + if (!FoundIrq) + { + DPRINT("Interrupt resource was not found in allocated resources list\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + else if (DeviceExtension->Type == Keyboard && (!FoundDataPort || !FoundControlPort)) + { + DPRINT("Some required resources were not found in allocated resources list\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + else if (DeviceExtension->Type == Mouse && (FoundDataPort || FoundControlPort)) + { + DPRINT("Too much resources were provided in allocated resources list\n"); + return STATUS_INVALID_PARAMETER; + } + + switch (DeviceExtension->Type) + { + case Keyboard: + { + RtlCopyMemory( + &PortDeviceExtension->KeyboardInterrupt, + &InterruptData, + sizeof(INTERRUPT_DATA)); + PortDeviceExtension->Flags |= KEYBOARD_STARTED; + Status = StartProcedure(PortDeviceExtension); + break; + } + case Mouse: + { + RtlCopyMemory( + &PortDeviceExtension->MouseInterrupt, + &InterruptData, + sizeof(INTERRUPT_DATA)); + PortDeviceExtension->Flags |= MOUSE_STARTED; + Status = StartProcedure(PortDeviceExtension); + break; + } + default: + { + DPRINT1("Unknown FDO type %u\n", DeviceExtension->Type); + ASSERT(FALSE); + Status = STATUS_INVALID_DEVICE_REQUEST; + } + } + + if (NT_SUCCESS(Status)) + DeviceExtension->PnpState = dsStarted; + + return Status; +} + +NTSTATUS NTAPI +i8042Pnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + ULONG MinorFunction; + I8042_DEVICE_TYPE DeviceType; + ULONG_PTR Information = 0; + NTSTATUS Status; + + Stack = IoGetCurrentIrpStackLocation(Irp); + MinorFunction = Stack->MinorFunction; + DeviceType = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type; + + switch (MinorFunction) + { + case IRP_MN_START_DEVICE: /* 0x0 */ + { + DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); + + /* Call lower driver (if any) */ + if (DeviceType != PhysicalDeviceObject) + { + Status = ForwardIrpAndWait(DeviceObject, Irp); + if (NT_SUCCESS(Status)) + Status = i8042PnpStartDevice( + DeviceObject, + Stack->Parameters.StartDevice.AllocatedResources, + Stack->Parameters.StartDevice.AllocatedResourcesTranslated); + } + else + Status = STATUS_SUCCESS; + break; + } + case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */ + { + switch (Stack->Parameters.QueryDeviceRelations.Type) + { + case BusRelations: + { + DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); + return ForwardIrpAndForget(DeviceObject, Irp); + } + case RemovalRelations: + { + DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); + return ForwardIrpAndForget(DeviceObject, Irp); + } + default: + DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", + Stack->Parameters.QueryDeviceRelations.Type); + ASSERT(FALSE); + return ForwardIrpAndForget(DeviceObject, Irp); + } + break; + } + default: + { + DPRINT1("IRP_MJ_PNP / unknown minor function 0x%x\n", MinorFunction); + ASSERT(FALSE); + return ForwardIrpAndForget(DeviceObject, Irp); + } + } + + Irp->IoStatus.Information = Information; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} diff --git a/reactos/drivers/input/i8042prt/ps2pp.c b/reactos/drivers/input/i8042prt/ps2pp.c index 3b183ec8617..c9746d70f43 100644 --- a/reactos/drivers/input/i8042prt/ps2pp.c +++ b/reactos/drivers/input/i8042prt/ps2pp.c @@ -1,137 +1,141 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/ps2pp.c - * PURPOSE: i8042prt driver - * ps2pp protocol handling - * PROGRAMMER: Tinus + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/ps2pp.c + * PURPOSE: ps2pp protocol handling + * PROGRAMMERS: Copyright Martijn Vernooij (o112w8r02@sneakemail.com) + * Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) */ /* INCLUDES ****************************************************************/ -#ifndef NDEBUG -#define NDEBUG -#endif -#include - #include "i8042prt.h" +#define NDEBUG +#include -VOID I8042MouseHandlePs2pp(PDEVICE_EXTENSION DevExt, UCHAR Input) +/* FUNCTIONS *****************************************************************/ + +VOID +i8042MouHandlePs2pp( + IN PI8042_MOUSE_EXTENSION DeviceExtension, + IN UCHAR Input) { UCHAR PktType; - PMOUSE_INPUT_DATA MouseInput = DevExt->MouseBuffer + - DevExt->MouseInBuffer; + PMOUSE_INPUT_DATA MouseInput; -/* First, collect 3 bytes for a packet - * We can detect out-of-sync only by checking - * the whole packet anyway. - * - * If bit 7 and 8 of the first byte are 0, its - * a normal packet. - * - * Otherwise, the packet is different, like this: - * 1: E 1 b3 b2 x x x x - * 2: x x b1 b0 x1 x0 1 0 - * 3: x x x x x x x1 x0 - * - * b3-0 form a code that specifies the packet type: - * - * 0 Device Type - * 1 Rollers and buttons - * 2 Reserved - * 3 Reserved - * 4 Device ID - * 5 Channel & Battery - * 6 Wireless notifications - * 7 Reserved - * 8 ShortID LSB (ShortID is a number that is supposed to differentiate - * 9 ShortID MSB between your mouse and your neighbours') - * 10 Reserved - * 11 Mouse capabilities - * 12 Remote control LSB - * 13 Remote control MSB - * 14 Reserved - * 15 Extended packet - */ + MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; - switch (DevExt->MouseState) { - case MouseIdle: - case XMovement: - DevExt->MouseLogiBuffer[DevExt->MouseState] = Input; - DevExt->MouseState++; - break; + /* First, collect 3 bytes for a packet + * We can detect out-of-sync only by checking + * the whole packet anyway. + * + * If bit 7 and 8 of the first byte are 0, its + * a normal packet. + * + * Otherwise, the packet is different, like this: + * 1: E 1 b3 b2 x x x x + * 2: x x b1 b0 x1 x0 1 0 + * 3: x x x x x x x1 x0 + * + * b3-0 form a code that specifies the packet type: + * + * 0 Device Type + * 1 Rollers and buttons + * 2 Reserved + * 3 Reserved + * 4 Device ID + * 5 Channel & Battery + * 6 Wireless notifications + * 7 Reserved + * 8 ShortID LSB (ShortID is a number that is supposed to differentiate + * 9 ShortID MSB between your mouse and your neighbours') + * 10 Reserved + * 11 Mouse capabilities + * 12 Remote control LSB + * 13 Remote control MSB + * 14 Reserved + * 15 Extended packet + */ - case YMovement: - DevExt->MouseLogiBuffer[2] = Input; - DevExt->MouseState = MouseIdle; + switch (DeviceExtension->MouseState) + { + case MouseIdle: + case XMovement: + DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input; + DeviceExtension->MouseState++; + break; - /* first check if it's a normal packet */ + case YMovement: + DeviceExtension->MouseLogiBuffer[2] = Input; + DeviceExtension->MouseState = MouseIdle; - if (!(DevExt->MouseLogiBuffer[0] & 0xC0)) { - DevExt->MouseState = MouseIdle; - I8042MouseHandle(DevExt, DevExt->MouseLogiBuffer[0]); - I8042MouseHandle(DevExt, DevExt->MouseLogiBuffer[1]); - I8042MouseHandle(DevExt, DevExt->MouseLogiBuffer[2]); - /* We could care about wether MouseState really - * advances, but we don't need to because we're - * only doing three bytes anyway, so the packet - * will never complete if it's broken. - */ - return; - } + /* first check if it's a normal packet */ - /* sanity check */ - - if (((DevExt->MouseLogiBuffer[0] & 0x48) != 0x48) || - (((DevExt->MouseLogiBuffer[1] & 0x0C) >> 2) != - (DevExt->MouseLogiBuffer[2] & 0x03))) { - DPRINT1("Ps2pp packet fails sanity checks\n"); - return; - } - - /* Now get the packet type */ - - PktType = ((DevExt->MouseLogiBuffer[0] & 0x30) >> 4) & - ((DevExt->MouseLogiBuffer[1] & 0x30) >> 6); - - switch (PktType) { - case 0: - /* The packet contains the device ID, but we - * already read that in the initialization - * sequence. Ignore it. - */ - return; - case 1: - RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA)); - if (DevExt->MouseLogiBuffer[2] & 0x10) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - - if (DevExt->MouseLogiBuffer[2] & 0x20) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - - if (DevExt->MouseLogiBuffer[2] & 0x0F) { - MouseInput->ButtonFlags |= MOUSE_WHEEL; - if (DevExt->MouseLogiBuffer[2] & 0x08) - MouseInput->ButtonData = - (DevExt->MouseLogiBuffer[2] & 0x07) - - 8; - else - MouseInput->ButtonData = - DevExt->MouseLogiBuffer[2] & 0x07; + if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0)) + { + DeviceExtension->MouseState = MouseIdle; + i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]); + i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]); + i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]); + /* We could care about wether MouseState really + * advances, but we don't need to because we're + * only doing three bytes anyway, so the packet + * will never complete if it's broken. + */ + return; } - I8042MouseHandleButtons(DevExt, MOUSE_BUTTON_4_DOWN | - MOUSE_BUTTON_5_DOWN); - I8042QueueMousePacket( - DevExt->MouseObject); - return; + + /* sanity check */ + if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) || + (((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) != + (DeviceExtension->MouseLogiBuffer[2] & 0x03))) + { + DPRINT1("Ps2pp packet fails sanity checks\n"); + return; + } + + /* Now get the packet type */ + PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 4) & + ((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 6); + + switch (PktType) + { + case 0: + /* The packet contains the device ID, but we + * already read that in the initialization + * sequence. Ignore it. + */ + return; + case 1: + RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA)); + if (DeviceExtension->MouseLogiBuffer[2] & 0x10) + MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; + + if (DeviceExtension->MouseLogiBuffer[2] & 0x20) + MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; + + if (DeviceExtension->MouseLogiBuffer[2] & 0x0F) + { + MouseInput->ButtonFlags |= MOUSE_WHEEL; + if (DeviceExtension->MouseLogiBuffer[2] & 0x08) + MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8; + else + MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07; + } + i8042MouHandleButtons( + DeviceExtension, + MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN); + i8042MouQueuePacket(DeviceExtension); + return; + default: + /* These are for things that would probably + * be handled by logitechs own driver. + */ + return; + } + default: - /* These are for things that would probably - * be handled by logitechs own driver. - */ - return; - } - default: - DPRINT1("Unexpected input state for ps2pp!\n"); + DPRINT1("Unexpected input state for ps2pp!\n"); } } diff --git a/reactos/drivers/input/i8042prt/readwrite.c b/reactos/drivers/input/i8042prt/readwrite.c new file mode 100644 index 00000000000..6ebf68e850c --- /dev/null +++ b/reactos/drivers/input/i8042prt/readwrite.c @@ -0,0 +1,218 @@ +/* + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/readwrite.c + * PURPOSE: Read/write port functions + * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) + Copyright Jason Filby (jasonfilby@yahoo.com) + Copyright Martijn Vernooij (o112w8r02@sneakemail.com) + Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "i8042prt.h" + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +VOID +i8042Flush( + IN PPORT_DEVICE_EXTENSION DeviceExtension) +{ + UCHAR Ignore; + + while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_OBF | MOU_OBF, &Ignore))) { + DPRINT("Data flushed\n"); /* drop */ + } +} + +VOID +i8042IsrWritePort( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR Value, + IN UCHAR SelectCmd OPTIONAL) +{ + if (SelectCmd) + if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, SelectCmd)) + return; + + i8042Write(DeviceExtension, DeviceExtension->DataPort, Value); +} + +/* + * FUNCTION: Read data from port 0x60 + */ +NTSTATUS +i8042ReadData( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR StatusFlags, + OUT PUCHAR Data) +{ + UCHAR PortStatus; + NTSTATUS Status; + + Status = i8042ReadStatus(DeviceExtension, &PortStatus); + if (!NT_SUCCESS(Status)) + return Status; + + // If data is available + if (PortStatus & StatusFlags) + { + *Data = READ_PORT_UCHAR(DeviceExtension->DataPort); + DPRINT("Read: 0x%02x (status: 0x%x)\n", Data[0], PortStatus); + + // If the data is valid (not timeout, not parity error) + if ((PortStatus & KBD_PERR) == 0) + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +i8042ReadStatus( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + OUT PUCHAR Status) +{ + ASSERT(DeviceExtension->ControlPort != NULL); + *Status = READ_PORT_UCHAR(DeviceExtension->ControlPort); + return STATUS_SUCCESS; +} + +/* + * FUNCTION: Read data from data port + */ +NTSTATUS +i8042ReadDataWait( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + OUT PUCHAR Data) +{ + ULONG Counter; + NTSTATUS Status; + + Counter = DeviceExtension->Settings.PollingIterations; + + while (Counter--) + { + Status = i8042ReadKeyboardData(DeviceExtension, Data); + + if (NT_SUCCESS(Status)) + return Status; + + KeStallExecutionProcessor(50); + } + + /* Timed out */ + return STATUS_IO_TIMEOUT; +} + +/* + * This one reads a value from the port; You don't have to specify + * which one, it'll always be from the one you talked to, so one function + * is enough this time. Note how MSDN specifies the + * WaitForAck parameter to be ignored. + */ +NTSTATUS NTAPI +i8042SynchReadPort( + IN PVOID Context, + OUT PUCHAR Value, + IN BOOLEAN WaitForAck) +{ + PPORT_DEVICE_EXTENSION DeviceExtension; + + DeviceExtension = (PPORT_DEVICE_EXTENSION)Context; + + return i8042ReadDataWait(DeviceExtension, Value); +} + +/* + * These functions are callbacks for filter driver custom + * initialization routines. + */ +NTSTATUS NTAPI +i8042SynchWritePort( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN UCHAR Port, + IN UCHAR Value, + IN BOOLEAN WaitForAck) +{ + NTSTATUS Status; + UCHAR Ack; + ULONG ResendIterations; + + ResendIterations = DeviceExtension->Settings.ResendIterations + 1; + + do + { + if (Port) + if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Port)) + { + DPRINT1("Failed to write Port\n"); + return STATUS_IO_TIMEOUT; + } + + if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value)) + { + DPRINT1("Failed to write Value\n"); + return STATUS_IO_TIMEOUT; + } + + if (WaitForAck) + { + Status = i8042ReadDataWait(DeviceExtension, &Ack); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to read Ack\n"); + return Status; + } + if (Ack == KBD_ACK) + return STATUS_SUCCESS; + if (Ack != KBD_RESEND) + { + DPRINT1("Unexpected Ack 0x%02x\n", Ack); + return STATUS_UNEXPECTED_IO_ERROR; + } + } + else + { + return STATUS_SUCCESS; + } + DPRINT("Reiterating\n"); + ResendIterations--; + } while (ResendIterations); + + return STATUS_IO_TIMEOUT; +} + +/* + * FUNCTION: Write data to a port, waiting first for it to become ready + */ +BOOLEAN +i8042Write( + IN PPORT_DEVICE_EXTENSION DeviceExtension, + IN PUCHAR addr, + IN UCHAR data) +{ + ULONG ResendIterations; + + ASSERT(addr); + ASSERT(DeviceExtension->ControlPort != NULL); + + ResendIterations = DeviceExtension->Settings.ResendIterations; + + while ((KBD_IBF & READ_PORT_UCHAR(DeviceExtension->ControlPort)) && + (ResendIterations--)) + { + KeStallExecutionProcessor(50); + } + + if (ResendIterations) + { + WRITE_PORT_UCHAR(addr, data); + DPRINT("Sent 0x%x to port 0x%x\n", data, addr); + return TRUE; + } + return FALSE; +} diff --git a/reactos/drivers/input/i8042prt/registry.c b/reactos/drivers/input/i8042prt/registry.c index 8c25872cd31..1e07ebff77d 100644 --- a/reactos/drivers/input/i8042prt/registry.c +++ b/reactos/drivers/input/i8042prt/registry.c @@ -1,211 +1,251 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/registry.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * Reading the registry - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/i8042prt.c + * PURPOSE: Reading the registry + * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) + Copyright Jason Filby (jasonfilby@yahoo.com) + Copyright Martijn Vernooij (o112w8r02@sneakemail.com) + Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) */ -/* INCLUDES ****************************************************************/ - -#ifndef NDEBUG -#define NDEBUG -#endif -#include +/* INCLUDES ******************************************************************/ #include "i8042prt.h" +#define NDEBUG +#include + /* FUNCTIONS *****************************************************************/ -/* - * Read the registry keys associated with this device. The RegistryPath - * var is a hack. This should be more like what microsoft does, but I - * don't know exactly what they do except that it's a hack too... - */ -VOID STDCALL I8042ReadRegistry(PDRIVER_OBJECT DriverObject, - PDEVICE_EXTENSION DevExt) - +NTSTATUS +ReadRegistryEntries( + IN PUNICODE_STRING RegistryPath, + OUT PI8042_SETTINGS Settings) { - RTL_QUERY_REGISTRY_TABLE Parameters[19]; - + UNICODE_STRING ParametersRegistryKey; + RTL_QUERY_REGISTRY_TABLE Parameters[16]; NTSTATUS Status; - ULONG DefaultHeadless = 0; - ULONG DefaultCrashScroll = 0; - ULONG DefaultCrashSysRq = 0; - ULONG DefaultReportResetErrors = 0; - ULONG DefaultPollStatusIterations = 1; - ULONG DefaultResendIterations = 3; - ULONG DefaultPollingIterations = 12000; - ULONG DefaultPollingIterationsMaximum = 12000; - ULONG DefaultKeyboardDataQueueSize = 100; - ULONG DefaultOverrideKeyboardType = 0; - ULONG DefaultOverrideKeyboardSubtype = 0; - ULONG DefaultMouseDataQueueSize = 100; - ULONG DefaultMouseResendStallTime = 1000; - ULONG DefaultMouseSynchIn100ns = 20000000; + ULONG DefaultKeyboardDataQueueSize = 0x64; + UNICODE_STRING DefaultKeyboardDeviceBaseName = RTL_CONSTANT_STRING(L"KeyboardPort"); + ULONG DefaultMouseDataQueueSize = 0x64; ULONG DefaultMouseResolution = 3; - ULONG DefaultSampleRate = 60; + ULONG DefaultMouseSynchIn100ns = 20000000; ULONG DefaultNumberOfButtons = 2; - ULONG DefaultEnableWheelDetection = 1; + UNICODE_STRING DefaultPointerDeviceBaseName = RTL_CONSTANT_STRING(L"PointerPort"); + ULONG DefaultPollStatusIterations = 1; + ULONG DefaultOverrideKeyboardType = 4; + ULONG DefaultOverrideKeyboardSubtype = 0; + ULONG DefaultPollingIterations = 0x400; + ULONG DefaultPollingIterationsMaximum = 12000; + ULONG DefaultResendIterations = 0x3; + ULONG DefaultSampleRate = 60; + ULONG DefaultCrashOnCtrlScroll; + + /* Default value for CrashOnCtrlScroll depends if we're + * running a debug build or a normal build. + */ +#ifdef DBG + DefaultCrashOnCtrlScroll = 1; +#else + DefaultCrashOnCtrlScroll = 0; +#endif + + ParametersRegistryKey.Length = 0; + ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL); + ParametersRegistryKey.Buffer = ExAllocatePool(PagedPool, ParametersRegistryKey.MaximumLength); + if (!ParametersRegistryKey.Buffer) + { + DPRINT("ExAllocatePool() failed\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + RtlCopyUnicodeString(&ParametersRegistryKey, RegistryPath); + RtlAppendUnicodeToString(&ParametersRegistryKey, L"\\Parameters"); + ParametersRegistryKey.Buffer[ParametersRegistryKey.Length / sizeof(WCHAR)] = UNICODE_NULL; RtlZeroMemory(Parameters, sizeof(Parameters)); - Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[0].Name = L"Headless"; - Parameters[0].EntryContext = &DevExt->Settings.Headless; + Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[0].Name = L"KeyboardDataQueueSize"; + Parameters[0].EntryContext = &Settings->KeyboardDataQueueSize; Parameters[0].DefaultType = REG_DWORD; - Parameters[0].DefaultData = &DefaultHeadless; + Parameters[0].DefaultData = &DefaultKeyboardDataQueueSize; Parameters[0].DefaultLength = sizeof(ULONG); - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[1].Name = L"CrashOnCtrlScroll"; - Parameters[1].EntryContext = &DevExt->Settings.CrashScroll; - Parameters[1].DefaultType = REG_DWORD; - Parameters[1].DefaultData = &DefaultCrashScroll; - Parameters[1].DefaultLength = sizeof(ULONG); + Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[1].Name = L"KeyboardDeviceBaseName"; + Parameters[1].EntryContext = &Settings->KeyboardDeviceBaseName; + Parameters[1].DefaultType = REG_SZ; + Parameters[1].DefaultData = &DefaultKeyboardDeviceBaseName; + Parameters[1].DefaultLength = 0; - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[2].Name = L"BreakOnSysRq"; - Parameters[2].EntryContext = &DevExt->Settings.CrashSysRq; + Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[2].Name = L"MouseDataQueueSize"; + Parameters[2].EntryContext = &Settings->MouseDataQueueSize; Parameters[2].DefaultType = REG_DWORD; - Parameters[2].DefaultData = &DefaultCrashSysRq; + Parameters[2].DefaultData = &DefaultMouseDataQueueSize; Parameters[2].DefaultLength = sizeof(ULONG); - Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[3].Name = L"ReportResetErrors"; - Parameters[3].EntryContext = &DevExt->Settings.ReportResetErrors; + Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[3].Name = L"MouseResolution"; + Parameters[3].EntryContext = &Settings->MouseResolution; Parameters[3].DefaultType = REG_DWORD; - Parameters[3].DefaultData = &DefaultReportResetErrors; + Parameters[3].DefaultData = &DefaultMouseResolution; Parameters[3].DefaultLength = sizeof(ULONG); - Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[4].Name = L"PollStatusIterations"; - Parameters[4].EntryContext = &DevExt->Settings.PollStatusIterations; + Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[4].Name = L"MouseSynchIn100ns"; + Parameters[4].EntryContext = &Settings->MouseSynchIn100ns; Parameters[4].DefaultType = REG_DWORD; - Parameters[4].DefaultData = &DefaultPollStatusIterations; + Parameters[4].DefaultData = &DefaultMouseSynchIn100ns; Parameters[4].DefaultLength = sizeof(ULONG); - Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[5].Name = L"ResendIterations"; - Parameters[5].EntryContext = &DevExt->Settings.ResendIterations; + Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[5].Name = L"NumberOfButtons"; + Parameters[5].EntryContext = &Settings->NumberOfButtons; Parameters[5].DefaultType = REG_DWORD; - Parameters[5].DefaultData = &DefaultResendIterations; + Parameters[5].DefaultData = &DefaultNumberOfButtons; Parameters[5].DefaultLength = sizeof(ULONG); - Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[6].Name = L"PollingIterations"; - Parameters[6].EntryContext = &DevExt->Settings.PollingIterations; - Parameters[6].DefaultType = REG_DWORD; - Parameters[6].DefaultData = &DefaultPollingIterations; - Parameters[6].DefaultLength = sizeof(ULONG); + Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[6].Name = L"PointerDeviceBaseName"; + Parameters[6].EntryContext = &Settings->PointerDeviceBaseName; + Parameters[6].DefaultType = REG_SZ; + Parameters[6].DefaultData = &DefaultPointerDeviceBaseName; + Parameters[6].DefaultLength = 0; - Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[7].Name = L"PollingIterationsMaximum"; - Parameters[7].EntryContext = &DevExt->Settings.PollingIterationsMaximum; + Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[7].Name = L"PollStatusIterations"; + Parameters[7].EntryContext = &Settings->PollStatusIterations; Parameters[7].DefaultType = REG_DWORD; - Parameters[7].DefaultData = &DefaultPollingIterationsMaximum; + Parameters[7].DefaultData = &DefaultPollStatusIterations; Parameters[7].DefaultLength = sizeof(ULONG); - Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[8].Name = L"KeyboardDataQueueSize"; - Parameters[8].EntryContext = - &DevExt->KeyboardAttributes.InputDataQueueLength; + Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[8].Name = L"OverrideKeyboardType"; + Parameters[8].EntryContext = &Settings->OverrideKeyboardType; Parameters[8].DefaultType = REG_DWORD; - Parameters[8].DefaultData = &DefaultKeyboardDataQueueSize; + Parameters[8].DefaultData = &DefaultOverrideKeyboardType; Parameters[8].DefaultLength = sizeof(ULONG); - Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[9].Name = L"OverrideKeyboardType"; - Parameters[9].EntryContext = &DevExt->Settings.OverrideKeyboardType; + Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[9].Name = L"OverrideKeyboardSubtype"; + Parameters[9].EntryContext = &Settings->OverrideKeyboardSubtype; Parameters[9].DefaultType = REG_DWORD; - Parameters[9].DefaultData = &DefaultOverrideKeyboardType; + Parameters[9].DefaultData = &DefaultOverrideKeyboardSubtype; Parameters[9].DefaultLength = sizeof(ULONG); - Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[10].Name = L"OverrideKeyboardSubtype"; - Parameters[10].EntryContext = &DevExt->Settings.OverrideKeyboardSubtype; + Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[10].Name = L"PollingIterations"; + Parameters[10].EntryContext = &Settings->PollingIterations; Parameters[10].DefaultType = REG_DWORD; - Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype; + Parameters[10].DefaultData = &DefaultPollingIterations; Parameters[10].DefaultLength = sizeof(ULONG); - Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[11].Name = L"MouseDataQueueSize"; - Parameters[11].EntryContext = - &DevExt->MouseAttributes.InputDataQueueLength; + Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[11].Name = L"PollingIterationsMaximum"; + Parameters[11].EntryContext = &Settings->PollingIterationsMaximum; Parameters[11].DefaultType = REG_DWORD; - Parameters[11].DefaultData = &DefaultMouseDataQueueSize; + Parameters[11].DefaultData = &DefaultPollingIterationsMaximum; Parameters[11].DefaultLength = sizeof(ULONG); - Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[12].Name = L"MouseResendStallTime"; - Parameters[12].EntryContext = &DevExt->Settings.MouseResendStallTime; + Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[12].Name = L"ResendIterations"; + Parameters[12].EntryContext = &Settings->ResendIterations; Parameters[12].DefaultType = REG_DWORD; - Parameters[12].DefaultData = &DefaultMouseResendStallTime; + Parameters[12].DefaultData = &DefaultResendIterations; Parameters[12].DefaultLength = sizeof(ULONG); - Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[13].Name = L"MouseSynchIn100ns"; - Parameters[13].EntryContext = &DevExt->Settings.MouseSynchIn100ns; + Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[13].Name = L"SampleRate"; + Parameters[13].EntryContext = &Settings->SampleRate; Parameters[13].DefaultType = REG_DWORD; - Parameters[13].DefaultData = &DefaultMouseSynchIn100ns; + Parameters[13].DefaultData = &DefaultSampleRate; Parameters[13].DefaultLength = sizeof(ULONG); - Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[14].Name = L"MouseResolution"; - Parameters[14].EntryContext = &DevExt->Settings.MouseResolution; + Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[14].Name = L"CrashOnCtrlScroll"; + Parameters[14].EntryContext = &Settings->CrashOnCtrlScroll; Parameters[14].DefaultType = REG_DWORD; - Parameters[14].DefaultData = &DefaultMouseResolution; + Parameters[14].DefaultData = &DefaultCrashOnCtrlScroll; Parameters[14].DefaultLength = sizeof(ULONG); - Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[15].Name = L"SampleRate"; - Parameters[15].EntryContext = &DevExt->MouseAttributes.SampleRate; - Parameters[15].DefaultType = REG_DWORD; - Parameters[15].DefaultData = &DefaultSampleRate; - Parameters[15].DefaultLength = sizeof(ULONG); + Status = RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + ParametersRegistryKey.Buffer, + Parameters, + NULL, + NULL); - Parameters[16].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[16].Name = L"NumberOfButtons"; - Parameters[16].EntryContext = &DevExt->Settings.NumberOfButtons; - Parameters[16].DefaultType = REG_DWORD; - Parameters[16].DefaultData = &DefaultNumberOfButtons; - Parameters[16].DefaultLength = sizeof(ULONG); - - Parameters[17].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[17].Name = L"EnableWheelDetection"; - Parameters[17].EntryContext = &DevExt->Settings.EnableWheelDetection; - Parameters[17].DefaultType = REG_DWORD; - Parameters[17].DefaultData = &DefaultEnableWheelDetection; - Parameters[17].DefaultLength = sizeof(ULONG); - - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, - I8042RegistryPath.Buffer, - Parameters, - NULL, - NULL); - - if (!NT_SUCCESS(Status)) { - /* Actually, the defaults are not set when the function - * fails, as would happen during setup, so you have to - * set them manually anyway... - */ - RTL_QUERY_REGISTRY_TABLE *Current = Parameters; - DPRINT1 ("Can't read registry: %x\n", Status); - while (Current->Name) { - *((PULONG)Current->EntryContext) = - *((PULONG)Current->DefaultData); - Current++; + if (NT_SUCCESS(Status)) + { + /* Check values */ + if (Settings->KeyboardDataQueueSize < 1) + Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; + if (Settings->MouseDataQueueSize < 1) + Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; + if (Settings->NumberOfButtons < 1) + Settings->NumberOfButtons = DefaultNumberOfButtons; + if (Settings->PollingIterations < 0x400) + Settings->PollingIterations = DefaultPollingIterations; + if (Settings->PollingIterationsMaximum < 0x400) + Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; + if (Settings->ResendIterations < 1) + Settings->ResendIterations = DefaultResendIterations; + } + else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + /* Registry path doesn't exist. Set defaults */ + Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; + Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; + Settings->MouseResolution = DefaultMouseResolution; + Settings->MouseSynchIn100ns = DefaultMouseSynchIn100ns; + Settings->NumberOfButtons = DefaultNumberOfButtons; + Settings->PollStatusIterations = DefaultPollStatusIterations; + Settings->OverrideKeyboardType = DefaultOverrideKeyboardType; + Settings->OverrideKeyboardSubtype = DefaultOverrideKeyboardSubtype; + Settings->PollingIterations = DefaultPollingIterations; + Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; + Settings->ResendIterations = DefaultResendIterations; + Settings->SampleRate = DefaultSampleRate; + Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll; + Status = RtlDuplicateUnicodeString( + RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, + &DefaultKeyboardDeviceBaseName, + &Settings->KeyboardDeviceBaseName); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); + } + else + { + Status = RtlDuplicateUnicodeString( + RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, + &DefaultPointerDeviceBaseName, + &Settings->PointerDeviceBaseName); + if (!NT_SUCCESS(Status)) + DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); } - DPRINT1 ("Manually set defaults\n"); - } - if (DevExt->Settings.MouseResolution > 3) - DevExt->Settings.MouseResolution = 3; + if (NT_SUCCESS(Status)) + { + DPRINT("KeyboardDataQueueSize : 0x%lx\n", Settings->KeyboardDataQueueSize); + DPRINT("KeyboardDeviceBaseName : %wZ\n", &Settings->KeyboardDeviceBaseName); + DPRINT("MouseDataQueueSize : 0x%lx\n", Settings->MouseDataQueueSize); + DPRINT("MouseResolution : 0x%lx\n", Settings->MouseResolution); + DPRINT("MouseSynchIn100ns : %lu\n", Settings->MouseSynchIn100ns); + DPRINT("NumberOfButtons : 0x%lx\n", Settings->NumberOfButtons); + DPRINT("PointerDeviceBaseName : %wZ\n", &Settings->PointerDeviceBaseName); + DPRINT("PollStatusIterations : 0x%lx\n", Settings->PollStatusIterations); + DPRINT("OverrideKeyboardType : 0x%lx\n", Settings->OverrideKeyboardType); + DPRINT("OverrideKeyboardSubtype : 0x%lx\n", Settings->OverrideKeyboardSubtype); + DPRINT("PollingIterations : 0x%lx\n", Settings->PollingIterations); + DPRINT("PollingIterationsMaximum : %lu\n", Settings->PollingIterationsMaximum); + DPRINT("ResendIterations : 0x%lx\n", Settings->ResendIterations); + DPRINT("SampleRate : %lu\n", Settings->SampleRate); + } - DPRINT("Done reading registry\n"); + return Status; } diff --git a/reactos/drivers/input/i8042prt/setup.c b/reactos/drivers/input/i8042prt/setup.c new file mode 100644 index 00000000000..b33181c3f89 --- /dev/null +++ b/reactos/drivers/input/i8042prt/setup.c @@ -0,0 +1,273 @@ +/* + * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/input/i8042prt/setup.c + * PURPOSE: Create a legacy PDO during ReactOS installation + * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) + */ + +/* NOTE: + * All this file is a big hack and should be removed one day... + */ + +/* INCLUDES ******************************************************************/ + +#include "i8042prt.h" + +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_CONTROL_PORT 0x64 +#define KEYBOARD_IRQ 1 + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +IsFirstStageSetup( + VOID) +{ + UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\Setup"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hSetupKey = (HANDLE)NULL; + NTSTATUS Status; + BOOLEAN ret = TRUE; + + InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); + Status = ZwOpenKey(&hSetupKey, KEY_QUERY_VALUE, &ObjectAttributes); + + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + ret = TRUE; + else + ret = FALSE; + + if (hSetupKey != (HANDLE)NULL) + ZwClose(hSetupKey); + DPRINT("IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO"); + return ret; +} + +static VOID NTAPI +SendStartDevice( + IN PDRIVER_OBJECT DriverObject, + IN PVOID Context, + IN ULONG Count) +{ + PDEVICE_OBJECT Pdo; + PCM_RESOURCE_LIST AllocatedResources = NULL; + PCM_RESOURCE_LIST AllocatedResourcesTranslated = NULL; + PDEVICE_OBJECT TopDeviceObject = NULL; + KEVENT Event; + IO_STATUS_BLOCK IoStatusBlock; + PIRP Irp; + PIO_STACK_LOCATION Stack; + ULONG ResourceListSize; + NTSTATUS Status; + + Pdo = (PDEVICE_OBJECT)Context; + DPRINT("SendStartDevice(%p)\n", Pdo); + + /* Create default resource list */ + ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize); + if (!AllocatedResources) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + AllocatedResources->Count = 1; + AllocatedResources->List[0].PartialResourceList.Version = 1; + AllocatedResources->List[0].PartialResourceList.Revision = 1; + AllocatedResources->List[0].PartialResourceList.Count = 3; + /* Data port */ + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Flags = 0; /* FIXME */ + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.HighPart = 0; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.LowPart = KEYBOARD_DATA_PORT; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1; + /* Control port */ + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Type = CmResourceTypePort; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition = CmResourceShareDeviceExclusive; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Flags = 0; /* FIXME */ + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.HighPart = 0; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.LowPart = KEYBOARD_CONTROL_PORT; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Length = 1; + /* Interrupt */ + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Type = CmResourceTypeInterrupt; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level = 0; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = KEYBOARD_IRQ; + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1; + + /* Create default resource list translated */ + AllocatedResourcesTranslated = ExAllocatePool(PagedPool, ResourceListSize); + if (!AllocatedResources) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + RtlCopyMemory(AllocatedResourcesTranslated, AllocatedResources, ResourceListSize); + AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = HalGetInterruptVector( + Internal, 0, + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level, + AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector, + (PKIRQL)&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level, + &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity); + + /* Send IRP_MN_START_DEVICE */ + TopDeviceObject = IoGetAttachedDeviceReference(Pdo); + KeInitializeEvent( + &Event, + NotificationEvent, + FALSE); + Irp = IoBuildSynchronousFsdRequest( + IRP_MJ_PNP, + TopDeviceObject, + NULL, + 0, + NULL, + &Event, + &IoStatusBlock); + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + Stack = IoGetNextIrpStackLocation(Irp); + Stack->MinorFunction = IRP_MN_START_DEVICE; + Stack->Parameters.StartDevice.AllocatedResources = AllocatedResources; + Stack->Parameters.StartDevice.AllocatedResourcesTranslated = AllocatedResourcesTranslated; + Status = IoCallDriver(TopDeviceObject, Irp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject( + &Event, + Executive, + KernelMode, + FALSE, + NULL); + Status = IoStatusBlock.Status; + } + if (!NT_SUCCESS(Status)) + { + DPRINT("IoCallDriver() failed with status 0x%08lx\n", Status); + goto cleanup; + } + +cleanup: + if (TopDeviceObject) + ObDereferenceObject(TopDeviceObject); + if (AllocatedResources) + ExFreePool(AllocatedResources); + if (AllocatedResourcesTranslated) + ExFreePool(AllocatedResourcesTranslated); +} + +static NTSTATUS +AddRegistryEntry( + IN PCWSTR PortTypeName, + IN PUNICODE_STRING DeviceName, + IN PCWSTR RegistryPath) +{ + UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hDeviceMapKey = (HANDLE)-1; + HANDLE hPortKey = (HANDLE)-1; + UNICODE_STRING PortTypeNameU; + NTSTATUS Status; + + InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); + Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + RtlInitUnicodeString(&PortTypeNameU, PortTypeName); + InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL); + Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + Status = STATUS_SUCCESS; + +cleanup: + if (hDeviceMapKey != (HANDLE)-1) + ZwClose(hDeviceMapKey); + if (hPortKey != (HANDLE)-1) + ZwClose(hPortKey); + return Status; +} + +NTSTATUS +i8042AddLegacyKeyboard( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042"); + PI8042_DEVICE_TYPE DeviceExtension = NULL; + PDEVICE_OBJECT Pdo = NULL; + NTSTATUS Status; + + DPRINT("i8042AddLegacyKeyboard()\n"); + + /* Create a named PDO */ + Status = IoCreateDevice( + DriverObject, + sizeof(I8042_DEVICE_TYPE), + &KeyboardName, + FILE_DEVICE_8042_PORT, + FILE_DEVICE_SECURE_OPEN, + TRUE, + &Pdo); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + /* Initialize device extension */ + DeviceExtension = (PI8042_DEVICE_TYPE)Pdo->DeviceExtension; + RtlZeroMemory(DeviceExtension, sizeof(I8042_DEVICE_TYPE)); + *DeviceExtension = PhysicalDeviceObject; + Pdo->Flags &= ~DO_DEVICE_INITIALIZING; + + /* Add FDO at the top of the PDO */ + Status = i8042AddDevice(DriverObject, Pdo); + if (!NT_SUCCESS(Status)) + { + DPRINT("i8042AddDevice() failed with status 0x%08lx\n", Status); + goto cleanup; + } + + /* We will send the IRP_MN_START_DEVICE later, once kbdclass is loaded */ + AddRegistryEntry(L"KeyboardPort", &KeyboardName, RegistryPath->Buffer); + IoRegisterBootDriverReinitialization( + DriverObject, + SendStartDevice, + Pdo); + + Status = STATUS_SUCCESS; + +cleanup: + if (!NT_SUCCESS(Status)) + { + if (Pdo) + IoDeleteDevice(Pdo); + } + return Status; +} From fff3bf11fa3e831dda7ba3dfbf49f12f9862e09c Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 20 Sep 2006 20:36:27 +0000 Subject: [PATCH 295/488] Gdi32 font.c: - Patch by Dmitry Timoshkov - If there is no space for strings GetOutlineTextMetricsA should not indicate that they present. svn path=/trunk/; revision=24219 --- reactos/dll/win32/gdi32/objects/font.c | 109 +++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 6 deletions(-) diff --git a/reactos/dll/win32/gdi32/objects/font.c b/reactos/dll/win32/gdi32/objects/font.c index 96e59690635..afac417e7ea 100644 --- a/reactos/dll/win32/gdi32/objects/font.c +++ b/reactos/dll/win32/gdi32/objects/font.c @@ -42,6 +42,31 @@ static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA ) ptmA->tmCharSet = ptmW->tmCharSet; } +/*********************************************************************** + * FONT_mbtowc + * + * Returns a Unicode translation of str. If count is -1 then str is + * assumed to be '\0' terminated, otherwise it contains the number of + * bytes to convert. If plenW is non-NULL, on return it will point to + * the number of WCHARs that have been written. The caller should free + * the returned LPWSTR from the process heap itself. + */ +static LPWSTR FONT_mbtowc(LPCSTR str, INT count, INT *plenW) +{ + UINT cp = CP_ACP; + INT lenW; + LPWSTR strW; + + if(count == -1) count = strlen(str); + lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0); + strW = HeapAlloc(GetProcessHeap(), 0, lenW*sizeof(WCHAR)); + MultiByteToWideChar(cp, 0, str, count, strW, lenW); + DPRINT1("mapped %s -> %s \n", str, strW); + if(plenW) *plenW = lenW; + return strW; +} + + static BOOL FASTCALL MetricsCharConvert(WCHAR w, UCHAR *b) { @@ -358,6 +383,8 @@ GetCharWidthA ( LPINT lpBuffer ) { +DPRINT1("GCWA iFirstChar %x\n",iFirstChar); + return GetCharWidth32A ( hdc, iFirstChar, iLastChar, lpBuffer ); } @@ -374,8 +401,35 @@ GetCharWidth32A( LPINT lpBuffer ) { - /* FIXME should be NtGdiGetCharWidthW */ - return NtGdiGetCharWidth32(hdc, iFirstChar, iLastChar, lpBuffer); + INT i, wlen, count = (INT)(iLastChar - iFirstChar + 1); + LPSTR str; + LPWSTR wstr; + BOOL ret = TRUE; +DPRINT1("GCW32A iFirstChar %x\n",iFirstChar); + + if(count <= 0) return FALSE; + + str = HeapAlloc(GetProcessHeap(), 0, count); + for(i = 0; i < count; i++) + str[i] = (BYTE)(iFirstChar + i); + + wstr = FONT_mbtowc(str, count, &wlen); + + for(i = 0; i < wlen; i++) + { + /* FIXME should be NtGdiGetCharWidthW */ + if(!NtGdiGetCharWidth32 (hdc, wstr[i], wstr[i], lpBuffer)) + { + ret = FALSE; + break; + } + lpBuffer++; + } + + HeapFree(GetProcessHeap(), 0, str); + HeapFree(GetProcessHeap(), 0, wstr); + + return ret; } @@ -391,6 +445,8 @@ GetCharWidthW ( LPINT lpBuffer ) { +DPRINT1("GCW32w uFirstChar %x\n",iFirstChar); + /* FIXME should be NtGdiGetCharWidthW */ return NtGdiGetCharWidth32 ( hdc, iFirstChar, iLastChar, lpBuffer ); } @@ -496,7 +552,7 @@ GetCharWidthFloatA( /* - * @unimplemented + * @implemented */ BOOL APIENTRY @@ -507,8 +563,9 @@ GetCharABCWidthsA( LPABC lpabc ) { - /* FIXME what to do with uFirstChar and uLastChar ??? */ - return NtGdiGetCharABCWidths ( hdc, uFirstChar, uLastChar, lpabc ); +DPRINT1("GCABCWA uFirstChar %x\n",uFirstChar); + +return NtGdiGetCharABCWidths(hdc, uFirstChar, uLastChar, lpabc); } @@ -524,6 +581,8 @@ GetCharABCWidthsFloatA( LPABCFLOAT lpABCF ) { +DPRINT1("GCABCWFA iFirstChar %x\n",iFirstChar); + /* FIXME what to do with iFirstChar and iLastChar ??? */ return NtGdiGetCharABCWidthsFloat ( hdc, iFirstChar, iLastChar, lpABCF ); } @@ -544,9 +603,32 @@ GetGlyphOutlineA( CONST MAT2 *lpmat2 ) { - return NtGdiGetGlyphOutline ( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); + + LPWSTR p = NULL; + DWORD ret; + UINT c; + DPRINT1("GetGlyphOutlineA uChar %x\n", uChar); + if(!(uFormat & GGO_GLYPH_INDEX)) { + int len; + char mbchs[2]; + if(uChar > 0xff) { /* but, 2 bytes character only */ + len = 2; + mbchs[0] = (uChar & 0xff00) >> 8; + mbchs[1] = (uChar & 0xff); + } else { + len = 1; + mbchs[0] = (uChar & 0xff); + } + p = FONT_mbtowc(mbchs, len, NULL); + c = p[0]; + } else + c = uChar; + ret = NtGdiGetGlyphOutline(hdc, c, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); + HeapFree(GetProcessHeap(), 0, p); + return ret; } + /* * @implemented */ @@ -562,6 +644,7 @@ GetGlyphOutlineW( CONST MAT2 *lpmat2 ) { + DPRINT1("GetGlyphOutlineW uChar %x\n", uChar); return NtGdiGetGlyphOutline ( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); } @@ -696,6 +779,20 @@ GetOutlineTextMetricsA( if(output != lpOTM) { memcpy(lpOTM, output, cbData); HeapFree(GetProcessHeap(), 0, output); + + /* check if the string offsets really fit into the provided size */ + /* FIXME: should we check string length as well? */ + if ((UINT_PTR)lpOTM->otmpFamilyName >= lpOTM->otmSize) + lpOTM->otmpFamilyName = 0; /* doesn't fit */ + + if ((UINT_PTR)lpOTM->otmpFaceName >= lpOTM->otmSize) + lpOTM->otmpFaceName = 0; /* doesn't fit */ + + if ((UINT_PTR)lpOTM->otmpStyleName >= lpOTM->otmSize) + lpOTM->otmpStyleName = 0; /* doesn't fit */ + + if ((UINT_PTR)lpOTM->otmpFullName >= lpOTM->otmSize) + lpOTM->otmpFullName = 0; /* doesn't fit */ } end: From 18733c439795adcf6834269e84a575f7ff5ce960 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 20 Sep 2006 21:09:30 +0000 Subject: [PATCH 296/488] Kill debug prints. svn path=/trunk/; revision=24220 --- reactos/dll/win32/gdi32/objects/font.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/reactos/dll/win32/gdi32/objects/font.c b/reactos/dll/win32/gdi32/objects/font.c index afac417e7ea..ee5818ba8b7 100644 --- a/reactos/dll/win32/gdi32/objects/font.c +++ b/reactos/dll/win32/gdi32/objects/font.c @@ -61,7 +61,7 @@ static LPWSTR FONT_mbtowc(LPCSTR str, INT count, INT *plenW) lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0); strW = HeapAlloc(GetProcessHeap(), 0, lenW*sizeof(WCHAR)); MultiByteToWideChar(cp, 0, str, count, strW, lenW); - DPRINT1("mapped %s -> %s \n", str, strW); + DPRINT("mapped %s -> %s \n", str, strW); if(plenW) *plenW = lenW; return strW; } @@ -383,7 +383,7 @@ GetCharWidthA ( LPINT lpBuffer ) { -DPRINT1("GCWA iFirstChar %x\n",iFirstChar); +DPRINT("GCWA iFirstChar %x\n",iFirstChar); return GetCharWidth32A ( hdc, iFirstChar, iLastChar, lpBuffer ); } @@ -405,7 +405,7 @@ GetCharWidth32A( LPSTR str; LPWSTR wstr; BOOL ret = TRUE; -DPRINT1("GCW32A iFirstChar %x\n",iFirstChar); +DPRINT("GCW32A iFirstChar %x\n",iFirstChar); if(count <= 0) return FALSE; @@ -445,7 +445,7 @@ GetCharWidthW ( LPINT lpBuffer ) { -DPRINT1("GCW32w uFirstChar %x\n",iFirstChar); +DPRINT("GCW32w uFirstChar %x\n",iFirstChar); /* FIXME should be NtGdiGetCharWidthW */ return NtGdiGetCharWidth32 ( hdc, iFirstChar, iLastChar, lpBuffer ); @@ -563,7 +563,7 @@ GetCharABCWidthsA( LPABC lpabc ) { -DPRINT1("GCABCWA uFirstChar %x\n",uFirstChar); +DPRINT("GCABCWA uFirstChar %x\n",uFirstChar); return NtGdiGetCharABCWidths(hdc, uFirstChar, uLastChar, lpabc); } @@ -581,7 +581,7 @@ GetCharABCWidthsFloatA( LPABCFLOAT lpABCF ) { -DPRINT1("GCABCWFA iFirstChar %x\n",iFirstChar); +DPRINT("GCABCWFA iFirstChar %x\n",iFirstChar); /* FIXME what to do with iFirstChar and iLastChar ??? */ return NtGdiGetCharABCWidthsFloat ( hdc, iFirstChar, iLastChar, lpABCF ); @@ -607,7 +607,7 @@ GetGlyphOutlineA( LPWSTR p = NULL; DWORD ret; UINT c; - DPRINT1("GetGlyphOutlineA uChar %x\n", uChar); + DPRINT("GetGlyphOutlineA uChar %x\n", uChar); if(!(uFormat & GGO_GLYPH_INDEX)) { int len; char mbchs[2]; @@ -644,7 +644,7 @@ GetGlyphOutlineW( CONST MAT2 *lpmat2 ) { - DPRINT1("GetGlyphOutlineW uChar %x\n", uChar); + DPRINT("GetGlyphOutlineW uChar %x\n", uChar); return NtGdiGetGlyphOutline ( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); } From 6d8ba42532a0cd2a0603652d106a2d9004b43de3 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 20 Sep 2006 21:34:08 +0000 Subject: [PATCH 297/488] Fix CreateFontIndirectA so it will not bigcheck with a null pointer. svn path=/trunk/; revision=24221 --- reactos/dll/win32/gdi32/objects/font.c | 27 ++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/reactos/dll/win32/gdi32/objects/font.c b/reactos/dll/win32/gdi32/objects/font.c index ee5818ba8b7..a1f68fc846b 100644 --- a/reactos/dll/win32/gdi32/objects/font.c +++ b/reactos/dll/win32/gdi32/objects/font.c @@ -61,7 +61,7 @@ static LPWSTR FONT_mbtowc(LPCSTR str, INT count, INT *plenW) lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0); strW = HeapAlloc(GetProcessHeap(), 0, lenW*sizeof(WCHAR)); MultiByteToWideChar(cp, 0, str, count, strW, lenW); - DPRINT("mapped %s -> %s \n", str, strW); + DPRINT1("mapped %s -> %s \n", str, strW); if(plenW) *plenW = lenW; return strW; } @@ -383,7 +383,7 @@ GetCharWidthA ( LPINT lpBuffer ) { -DPRINT("GCWA iFirstChar %x\n",iFirstChar); +DPRINT1("GCWA iFirstChar %x\n",iFirstChar); return GetCharWidth32A ( hdc, iFirstChar, iLastChar, lpBuffer ); } @@ -405,7 +405,7 @@ GetCharWidth32A( LPSTR str; LPWSTR wstr; BOOL ret = TRUE; -DPRINT("GCW32A iFirstChar %x\n",iFirstChar); +DPRINT1("GCW32A iFirstChar %x\n",iFirstChar); if(count <= 0) return FALSE; @@ -445,7 +445,7 @@ GetCharWidthW ( LPINT lpBuffer ) { -DPRINT("GCW32w uFirstChar %x\n",iFirstChar); +DPRINT1("GCW32w uFirstChar %x\n",iFirstChar); /* FIXME should be NtGdiGetCharWidthW */ return NtGdiGetCharWidth32 ( hdc, iFirstChar, iLastChar, lpBuffer ); @@ -563,7 +563,7 @@ GetCharABCWidthsA( LPABC lpabc ) { -DPRINT("GCABCWA uFirstChar %x\n",uFirstChar); +DPRINT1("GCABCWA uFirstChar %x\n",uFirstChar); return NtGdiGetCharABCWidths(hdc, uFirstChar, uLastChar, lpabc); } @@ -581,7 +581,7 @@ GetCharABCWidthsFloatA( LPABCFLOAT lpABCF ) { -DPRINT("GCABCWFA iFirstChar %x\n",iFirstChar); +DPRINT1("GCABCWFA iFirstChar %x\n",iFirstChar); /* FIXME what to do with iFirstChar and iLastChar ??? */ return NtGdiGetCharABCWidthsFloat ( hdc, iFirstChar, iLastChar, lpABCF ); @@ -607,7 +607,7 @@ GetGlyphOutlineA( LPWSTR p = NULL; DWORD ret; UINT c; - DPRINT("GetGlyphOutlineA uChar %x\n", uChar); + DPRINT1("GetGlyphOutlineA uChar %x\n", uChar); if(!(uFormat & GGO_GLYPH_INDEX)) { int len; char mbchs[2]; @@ -644,7 +644,7 @@ GetGlyphOutlineW( CONST MAT2 *lpmat2 ) { - DPRINT("GetGlyphOutlineW uChar %x\n", uChar); + DPRINT1("GetGlyphOutlineW uChar %x\n", uChar); return NtGdiGetGlyphOutline ( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); } @@ -828,10 +828,13 @@ CreateFontIndirectA( ) { LOGFONTW tlf; - - LogFontA2W(&tlf, lplf); - - return NtGdiCreateFontIndirect(&tlf); + + if (lplf) + { + LogFontA2W(&tlf, lplf); + return NtGdiCreateFontIndirect(&tlf); + } + else return (HFONT) 0; //or call NtGdiCreateFontIndirect(NULL)? } From d42d3c29c0f3d7d856d4cf6e2ac5921b3e778421 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 21 Sep 2006 02:47:37 +0000 Subject: [PATCH 298/488] set GetLastErrorMsg if CreateFontIndirectA(NULL) are use as inputparam . it make same beauvoir as CreateFontIndirectW svn path=/trunk/; revision=24222 --- reactos/dll/win32/gdi32/objects/font.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/gdi32/objects/font.c b/reactos/dll/win32/gdi32/objects/font.c index a1f68fc846b..d4e5139bd27 100644 --- a/reactos/dll/win32/gdi32/objects/font.c +++ b/reactos/dll/win32/gdi32/objects/font.c @@ -834,7 +834,7 @@ CreateFontIndirectA( LogFontA2W(&tlf, lplf); return NtGdiCreateFontIndirect(&tlf); } - else return (HFONT) 0; //or call NtGdiCreateFontIndirect(NULL)? + else return NtGdiCreateFontIndirect(NULL); } From 7d1faef9eeadd2e14fe3d7e31f1df1a180947364 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Thu, 21 Sep 2006 07:42:21 +0000 Subject: [PATCH 299/488] Fix boot with /DEBUGPORT=GDB and /DEBUGPORT=COM1. I don't know why, but this works... svn path=/trunk/; revision=24223 --- reactos/ntoskrnl/kd/kdio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/kd/kdio.c b/reactos/ntoskrnl/kd/kdio.c index 811d22f7a64..e8c638325aa 100644 --- a/reactos/ntoskrnl/kd/kdio.c +++ b/reactos/ntoskrnl/kd/kdio.c @@ -188,13 +188,14 @@ KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable, /* Register as a Provider */ InsertTailList(&KdProviders, &DispatchTable->KdProvidersList); - - /* Display separator + ReactOS version at start of the debug log */ - DPRINT1("---------------------------------------------------------------\n"); - DPRINT1("ReactOS "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n"); } else if (BootPhase == 2) { + /* Display separator + ReactOS version at start of the debug log */ + DbgPrint("---------------------------------------------------------------\n"); + DbgPrint("ReactOS "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n"); + DbgPrint("---------------------------------------------------------------\n"); + HalDisplayString("\n Serial debugging enabled\n\n"); } } From 2a0160473e75af278ba1a031cf8cd0ba982efa0f Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 21 Sep 2006 17:25:41 +0000 Subject: [PATCH 300/488] Add an MM api to get the memory map from Freeldr's memory manager (as opposed to MachGetMemoryMap which gets architecture-specfic memory map returned by BIOS/firmware/etc). Currently this api is unused, it's going to be used by windows/reactos bootloader in future. svn path=/trunk/; revision=24224 --- reactos/boot/freeldr/freeldr/include/mm.h | 1 + reactos/boot/freeldr/freeldr/mm/mm.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/reactos/boot/freeldr/freeldr/include/mm.h b/reactos/boot/freeldr/freeldr/include/mm.h index d3b4369762a..24fce2d4b33 100644 --- a/reactos/boot/freeldr/freeldr/include/mm.h +++ b/reactos/boot/freeldr/freeldr/include/mm.h @@ -86,6 +86,7 @@ VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount); // S BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount); // Returns TRUE if the specified pages of memory are available, otherwise FALSE ULONG GetSystemMemorySize(VOID); // Returns the amount of total memory in the system +PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(ULONG *NoEntries); // Returns a pointer to the memory mapping table and a number of entries in it //BOOLEAN MmInitializeMemoryManager(ULONG LowMemoryStart, ULONG LowMemoryLength); diff --git a/reactos/boot/freeldr/freeldr/mm/mm.c b/reactos/boot/freeldr/freeldr/mm/mm.c index 928fe94e566..d5ad60f0c26 100644 --- a/reactos/boot/freeldr/freeldr/mm/mm.c +++ b/reactos/boot/freeldr/freeldr/mm/mm.c @@ -456,3 +456,12 @@ ULONG GetSystemMemorySize(VOID) { return (TotalPagesInLookupTable * MM_PAGE_SIZE); } + +PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(ULONG *NoEntries) +{ + PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress; + + *NoEntries = TotalPagesInLookupTable; + + return RealPageLookupTable; +} From 50ee081131825657e25e731dcf43f02f88eae5fa Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 22 Sep 2006 06:36:16 +0000 Subject: [PATCH 301/488] ARP query support. Thanks to WaxDragon for encouragement and debugging. svn path=/branches/ros-branch-0_3_1/; revision=24226 --- reactos/dll/win32/iphlpapi/ifenum_reactos.c | 33 +++++- reactos/dll/win32/iphlpapi/iphlpapi_private.h | 5 +- reactos/dll/win32/iphlpapi/ipstats_reactos.c | 100 +++++++++++++++++- reactos/drivers/network/tcpip/include/info.h | 16 +++ .../drivers/network/tcpip/include/neighbor.h | 4 + .../drivers/network/tcpip/include/precomp.h | 2 +- reactos/drivers/network/tcpip/tcpip/iinfo.c | 51 ++++++++- reactos/drivers/network/tcpip/tcpip/info.c | 29 +++++ reactos/include/psdk/tcpioctl.h | 1 + reactos/lib/drivers/ip/network/neighbor.c | 40 +++++++ 10 files changed, 271 insertions(+), 10 deletions(-) diff --git a/reactos/dll/win32/iphlpapi/ifenum_reactos.c b/reactos/dll/win32/iphlpapi/ifenum_reactos.c index 69f7dbd204b..37425705880 100644 --- a/reactos/dll/win32/iphlpapi/ifenum_reactos.c +++ b/reactos/dll/win32/iphlpapi/ifenum_reactos.c @@ -40,7 +40,7 @@ #include "ifenum.h" #include -#define NDEBUG +//#define NDEBUG #include "debug.h" /* Globals */ @@ -124,6 +124,7 @@ NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, DWORD toiType, DWORD toiId, DWORD teiEntity, + DWORD teiInstance, DWORD fixedPart, DWORD entrySize, PVOID *tdiEntitySet, @@ -148,6 +149,7 @@ NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, req.ID.toi_type = toiType; req.ID.toi_id = toiId; req.ID.toi_entity.tei_entity = teiEntity; + req.ID.toi_entity.tei_instance = teiInstance; /* There's a subtle problem here... * If an interface is added at this exact instant, (as if by a PCMCIA @@ -168,7 +170,7 @@ NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, &allocationSizeForEntityArray, NULL ); - if(!status) + if(!NT_SUCCESS(status)) { DPRINT("IOCTL Failed\n"); return STATUS_UNSUCCESSFUL; @@ -285,6 +287,7 @@ NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile, INFO_TYPE_PROVIDER, ENTITY_LIST_ID, GENERIC_ENTITY, + 0, 0, sizeof(TDIEntityID), (PVOID *)entitySet, @@ -303,7 +306,7 @@ NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile, return status; } -static BOOL isInterface( TDIEntityID *if_maybe ) { +BOOL isInterface( TDIEntityID *if_maybe ) { return if_maybe->tei_entity == IF_ENTITY; } @@ -348,6 +351,30 @@ NTSTATUS tdiGetEntityType( HANDLE tcpFile, TDIEntityID *ent, PULONG type ) { return (status ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); } +BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ) { + TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT; + NTSTATUS status = STATUS_SUCCESS; + DWORD returnSize, type; + + req.ID.toi_class = INFO_CLASS_GENERIC; + req.ID.toi_type = INFO_TYPE_PROVIDER; + req.ID.toi_id = ENTITY_TYPE_ID; + req.ID.toi_entity.tei_entity = AT_ENTITY; + req.ID.toi_entity.tei_instance = arp_maybe->tei_instance; + + status = DeviceIoControl( tcpFile, + IOCTL_TCP_QUERY_INFORMATION_EX, + &req, + sizeof(req), + &type, + sizeof(type), + &returnSize, + NULL ); + + if( !NT_SUCCESS(status) ) return FALSE; + return type == AT_ENTITY; +} + static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile, IFInfo **infoSet, PDWORD numInterfaces ) { diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_private.h b/reactos/dll/win32/iphlpapi/iphlpapi_private.h index 4d4fb1ed47c..40c4a0bd5d3 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_private.h +++ b/reactos/dll/win32/iphlpapi/iphlpapi_private.h @@ -118,7 +118,8 @@ VOID closeTcpFile(HANDLE tcpFile); NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile, TDIEntityID **entitySet, PDWORD numEntities ); NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, DWORD toiClass, DWORD toiType, - DWORD toiId, DWORD teiEntity, DWORD fixedPart, + DWORD toiId, DWORD teiEntity, DWORD teiInstance, + DWORD fixedPart, DWORD entrySize, PVOID *tdiEntitySet, PDWORD numEntries ); VOID tdiFreeThingSet( PVOID things ); @@ -134,6 +135,8 @@ PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ); void ConsumeChildKeyName( PWCHAR Name ); PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ); void ConsumeRegValueString( PWCHAR NameServer ); +BOOL isInterface( TDIEntityID *if_maybe ); +BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ); #include /* This is here until we switch to version 2.5 of the mingw headers */ diff --git a/reactos/dll/win32/iphlpapi/ipstats_reactos.c b/reactos/dll/win32/iphlpapi/ipstats_reactos.c index 4322937fedb..b6b160c4fb7 100644 --- a/reactos/dll/win32/iphlpapi/ipstats_reactos.c +++ b/reactos/dll/win32/iphlpapi/ipstats_reactos.c @@ -183,6 +183,7 @@ NTSTATUS tdiGetRoutesForIpEntity INFO_TYPE_PROVIDER, IP_MIB_ROUTETABLE_ENTRY_ID, ent->tei_entity, + 0, 0, sizeof(IPRouteEntry), (PVOID *)routes, @@ -203,6 +204,7 @@ NTSTATUS tdiGetIpAddrsForIpEntity INFO_TYPE_PROVIDER, IP_MIB_ADDRTABLE_ENTRY_ID, ent->tei_entity, + 0, 0, sizeof(IPAddrEntry), (PVOID *)addrs, @@ -507,12 +509,106 @@ RouteTable *getRouteTable(void) DWORD getNumArpEntries(void) { - return getNumWithOneHeader("/proc/net/arp"); + DWORD numEntities; + TDIEntityID *entitySet = NULL; + HANDLE tcpFile; + int i, totalNumber = 0; + NTSTATUS status; + PMIB_IPNETROW IpArpTable = NULL; + DWORD returnSize; + + TRACE("called.\n"); + + status = openTcpFile( &tcpFile ); + + if( !NT_SUCCESS(status) ) { + TRACE("failure: %08x\n", (int)status ); + return 0; + } + + status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); + + for( i = 0; i < numEntities; i++ ) { + if( isInterface( &entitySet[i] ) && + hasArp( tcpFile, &entitySet[i] ) ) { + + status = tdiGetSetOfThings( tcpFile, + INFO_CLASS_PROTOCOL, + INFO_TYPE_PROVIDER, + IP_MIB_ARPTABLE_ENTRY_ID, + AT_ENTITY, + entitySet[i].tei_instance, + 0, + sizeof(MIB_IPNETROW), + (PVOID *)&IpArpTable, + &returnSize ); + + if( status == STATUS_SUCCESS ) totalNumber += returnSize; + if( IpArpTable ) tdiFreeThingSet( IpArpTable ); + } + } + + closeTcpFile( tcpFile ); + if( IpArpTable ) tdiFreeThingSet( IpArpTable ); + if( entitySet ) tdiFreeThingSet( entitySet ); + return totalNumber; } PMIB_IPNETTABLE getArpTable(void) { - return 0; + DWORD numEntities, returnSize; + TDIEntityID *entitySet; + HANDLE tcpFile; + int i, row = 0, totalNumber; + NTSTATUS status; + PMIB_IPNETTABLE IpArpTable = NULL; + PMIB_IPNETROW AdapterArpTable = NULL; + + TRACE("called.\n"); + + totalNumber = getNumArpEntries(); + + status = openTcpFile( &tcpFile ); + + if( !NT_SUCCESS(status) ) { + TRACE("failure: %08x\n", (int)status ); + return 0; + } + + IpArpTable = HeapAlloc + ( GetProcessHeap(), 0, + sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber) ); + + status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); + + for( i = 0; i < numEntities; i++ ) { + if( isIpEntity( tcpFile, &entitySet[i] ) && + hasArp( tcpFile, &entitySet[i] ) ) { + + status = tdiGetSetOfThings( tcpFile, + INFO_CLASS_PROTOCOL, + INFO_TYPE_PROVIDER, + IP_MIB_ARPTABLE_ENTRY_ID, + AT_ENTITY, + entitySet[i].tei_instance, + 0, + sizeof(MIB_IPNETROW), + (PVOID *)&AdapterArpTable, + &returnSize ); + + if( status == STATUS_SUCCESS ) { + for( row = 0; row < returnSize; row++ ) + IpArpTable->table[row] = AdapterArpTable[row]; + } + + if( AdapterArpTable ) tdiFreeThingSet( AdapterArpTable ); + } + } + + tdiFreeThingSet( entitySet ); + IpArpTable->dwNumEntries = row; + + return IpArpTable; } DWORD getNumUdpEntries(void) diff --git a/reactos/drivers/network/tcpip/include/info.h b/reactos/drivers/network/tcpip/include/info.h index eb066773b21..50cfa9a5bc2 100644 --- a/reactos/drivers/network/tcpip/include/info.h +++ b/reactos/drivers/network/tcpip/include/info.h @@ -46,6 +46,19 @@ typedef struct IPADDR_ENTRY { USHORT Pad; } IPADDR_ENTRY, *PIPADDR_ENTRY; +#define ARP_ENTRY_STATIC 4 +#define ARP_ENTRY_DYNAMIC 3 +#define ARP_ENTRY_INVALID 2 +#define ARP_ENTRY_OTHER 1 + +typedef struct IPARP_ENTRY { + ULONG Index; + ULONG AddrSize; + UCHAR PhysAddr[8]; + ULONG LogAddr; + ULONG Type; +} IPARP_ENTRY, *PIPARP_ENTRY; + typedef struct IPROUTE_ENTRY { ULONG Dest; ULONG Index; //matches if_index in IFEntry and iae_index in IPAddrEntry @@ -96,6 +109,9 @@ typedef struct IFENTRY { #ifndef IP_MIB_ADDRTABLE_ENTRY_ID #define IP_MIB_ADDRTABLE_ENTRY_ID 0x102 #endif +#ifndef IP_MIB_ARPTABLE_ENTRY_ID +#define IP_MIB_ARPTABLE_ENTRY_ID 0x101 +#endif #ifndef MAX_PHYSADDR_SIZE #define MAX_PHYSADDR_SIZE 8 #endif diff --git a/reactos/drivers/network/tcpip/include/neighbor.h b/reactos/drivers/network/tcpip/include/neighbor.h index 4d30cb346ec..aa1859426a9 100644 --- a/reactos/drivers/network/tcpip/include/neighbor.h +++ b/reactos/drivers/network/tcpip/include/neighbor.h @@ -107,6 +107,10 @@ BOOLEAN NBQueuePacket( VOID NBRemoveNeighbor( PNEIGHBOR_CACHE_ENTRY NCE); +DWORD NBCopyNeighbors( + PIP_INTERFACE Interface, + PIPARP_ENTRY ArpTable); + #endif /* __NEIGHBOR_H */ /* EOF */ diff --git a/reactos/drivers/network/tcpip/include/precomp.h b/reactos/drivers/network/tcpip/include/precomp.h index 680d9dd01ec..5906ced640f 100644 --- a/reactos/drivers/network/tcpip/include/precomp.h +++ b/reactos/drivers/network/tcpip/include/precomp.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/reactos/drivers/network/tcpip/tcpip/iinfo.c b/reactos/drivers/network/tcpip/tcpip/iinfo.c index 8e3eaf97e52..7a6fe06f49c 100644 --- a/reactos/drivers/network/tcpip/tcpip/iinfo.c +++ b/reactos/drivers/network/tcpip/tcpip/iinfo.c @@ -78,6 +78,42 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID, return Status; } +TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID *ID, + PIP_INTERFACE Interface, + PNDIS_BUFFER Buffer, + PUINT BufferSize) { + NTSTATUS Status; + DWORD NumNeighbors = NBCopyNeighbors( Interface, NULL ); + DWORD MemSize = NumNeighbors * sizeof(IPARP_ENTRY); + PIPARP_ENTRY ArpEntries = + ExAllocatePoolWithTag + ( NonPagedPool, MemSize, FOURCC('A','R','P','t') ); + + if( !ArpEntries ) return STATUS_NO_MEMORY; + NBCopyNeighbors( Interface, ArpEntries ); + + Status = InfoCopyOut( (PVOID)ArpEntries, MemSize, Buffer, BufferSize ); + + ExFreePool( ArpEntries ); + + return Status; +} + +TDI_STATUS InfoTdiQueryGetArpCapability(TDIEntityID *ID, + PIP_INTERFACE Interface, + PNDIS_BUFFER Buffer, + PUINT BufferSize) { + NTSTATUS Status; + DWORD Capability = 0x280; + + TI_DbgPrint(MID_TRACE,("Copying out %d bytes (AT_ENTITY capability)\n", + sizeof(Capability))); + Status = InfoCopyOut + ( (PVOID)&Capability, sizeof(Capability), Buffer, BufferSize ); + + return Status; +} + TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass, UINT InfoType, UINT InfoId, @@ -87,13 +123,22 @@ TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass, PUINT BufferSize ) { if( InfoClass == INFO_CLASS_GENERIC && InfoType == INFO_TYPE_PROVIDER && - InfoId == ENTITY_TYPE_ID ) { - ULONG Temp = IF_MIB; - return InfoCopyOut( (PCHAR)&Temp, sizeof(Temp), Buffer, BufferSize ); + InfoId == ENTITY_TYPE_ID && + id->tei_entity == AT_ENTITY ) { + return InfoTdiQueryGetArpCapability( id, Context, Buffer, BufferSize ); } else if( InfoClass == INFO_CLASS_PROTOCOL && InfoType == INFO_TYPE_PROVIDER && InfoId == IF_MIB_STATS_ID ) { return InfoTdiQueryGetInterfaceMIB( id, Context, Buffer, BufferSize ); + } else if( InfoClass == INFO_CLASS_GENERIC && + InfoType == INFO_TYPE_PROVIDER && + InfoId == ENTITY_TYPE_ID ) { + ULONG Temp = IF_MIB; + return InfoCopyOut( (PCHAR)&Temp, sizeof(Temp), Buffer, BufferSize ); + } else if( InfoClass == INFO_CLASS_PROTOCOL && + InfoType == INFO_TYPE_PROVIDER && + InfoId == IP_MIB_ARPTABLE_ENTRY_ID ) { + return InfoTdiQueryGetArptableMIB( id, Context, Buffer, BufferSize ); } else return TDI_INVALID_REQUEST; } diff --git a/reactos/drivers/network/tcpip/tcpip/info.c b/reactos/drivers/network/tcpip/tcpip/info.c index 10d466180cb..fb4305c5919 100644 --- a/reactos/drivers/network/tcpip/tcpip/info.c +++ b/reactos/drivers/network/tcpip/tcpip/info.c @@ -164,6 +164,35 @@ TDI_STATUS InfoTdiQueryInformationEx( Status = TDI_INVALID_PARAMETER; } else Status = InfoTdiQueryListEntities(Buffer, BufferSize); + } else if (ID->toi_entity.tei_entity == AT_ENTITY) { + TcpipAcquireSpinLock( &EntityListLock, &OldIrql ); + + for( i = 0; i < EntityCount; i++ ) { + if( EntityList[i].tei_entity == IF_ENTITY && + EntityList[i].tei_instance == ID->toi_entity.tei_instance ) { + InfoRequest = EntityList[i].info_req; + context = EntityList[i].context; + FoundEntity = TRUE; + break; + } + } + + TcpipReleaseSpinLock( &EntityListLock, OldIrql ); + + if( FoundEntity ) { + TI_DbgPrint(DEBUG_INFO, + ("Calling AT Entity %d (%04x:%d) InfoEx (%x,%x,%x)\n", + i, ID->toi_entity.tei_entity, + ID->toi_entity.tei_instance, + ID->toi_class, ID->toi_type, ID->toi_id)); + Status = InfoRequest( ID->toi_class, + ID->toi_type, + ID->toi_id, + context, + &ID->toi_entity, + Buffer, + BufferSize ); + } } else { TcpipAcquireSpinLock( &EntityListLock, &OldIrql ); diff --git a/reactos/include/psdk/tcpioctl.h b/reactos/include/psdk/tcpioctl.h index 708641d6faf..d04411ff707 100644 --- a/reactos/include/psdk/tcpioctl.h +++ b/reactos/include/psdk/tcpioctl.h @@ -45,6 +45,7 @@ #define IF_MIB_STATS_ID 1 #define IP_MIB_STATS_ID 1 +#define IP_MIB_ARPTABLE_ENTRY_ID 0x101 #define IP_MIB_ADDRTABLE_ENTRY_ID 0x102 #define IP_INTFC_INFO_ID 0x103 #define MAX_PHYSADDR_SIZE 8 diff --git a/reactos/lib/drivers/ip/network/neighbor.c b/reactos/lib/drivers/ip/network/neighbor.c index 6d5248a67ae..330caa48117 100644 --- a/reactos/lib/drivers/ip/network/neighbor.c +++ b/reactos/lib/drivers/ip/network/neighbor.c @@ -514,3 +514,43 @@ VOID NBRemoveNeighbor( TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql); } + +ULONG NBCopyNeighbors +(PIP_INTERFACE Interface, + PIPARP_ENTRY ArpTable) +{ + PNEIGHBOR_CACHE_ENTRY CurNCE; + KIRQL OldIrql; + UINT Size = 0, i; + + for (i = 0; i <= NB_HASHMASK; i++) { + TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql); + for( CurNCE = NeighborCache[i].Cache; + CurNCE; + CurNCE = CurNCE->Next ) { + if( CurNCE->Interface == Interface ) { + if( ArpTable ) { + ArpTable[Size].Index = Interface->Index; + ArpTable[Size].AddrSize = CurNCE->LinkAddressLength; + RtlCopyMemory + (ArpTable[Size].PhysAddr, + CurNCE->LinkAddress, + CurNCE->LinkAddressLength); + ArpTable[Size].LogAddr = CurNCE->Address.Address.IPv4Address; + if( CurNCE->State & NUD_PERMANENT ) + ArpTable[Size].Type = ARP_ENTRY_STATIC; + else if( CurNCE->State & NUD_CONNECTED ) + ArpTable[Size].Type = ARP_ENTRY_DYNAMIC; + else if( !(CurNCE->State & NUD_VALID) ) + ArpTable[Size].Type = ARP_ENTRY_INVALID; + else + ArpTable[Size].Type = ARP_ENTRY_OTHER; + } + Size++; + } + } + TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql); + } + + return Size; +} From 230edc01b6a20d2f980424d771f6a748a501ec3d Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Fri, 22 Sep 2006 08:10:11 +0000 Subject: [PATCH 302/488] merges ros-branch-0_3_1 r24226 to trunk with arty permission. "ARP query support. Thanks to WaxDragon for encouragement and debugging." svn path=/trunk/; revision=24227 --- reactos/dll/win32/iphlpapi/ifenum_reactos.c | 33 +++++- reactos/dll/win32/iphlpapi/iphlpapi_private.h | 5 +- reactos/dll/win32/iphlpapi/ipstats_reactos.c | 100 +++++++++++++++++- reactos/drivers/network/tcpip/include/info.h | 16 +++ .../drivers/network/tcpip/include/neighbor.h | 4 + .../drivers/network/tcpip/include/precomp.h | 2 +- reactos/drivers/network/tcpip/tcpip/iinfo.c | 51 ++++++++- reactos/drivers/network/tcpip/tcpip/info.c | 29 +++++ reactos/include/psdk/tcpioctl.h | 1 + reactos/lib/drivers/ip/network/neighbor.c | 40 +++++++ 10 files changed, 271 insertions(+), 10 deletions(-) diff --git a/reactos/dll/win32/iphlpapi/ifenum_reactos.c b/reactos/dll/win32/iphlpapi/ifenum_reactos.c index 69f7dbd204b..37425705880 100644 --- a/reactos/dll/win32/iphlpapi/ifenum_reactos.c +++ b/reactos/dll/win32/iphlpapi/ifenum_reactos.c @@ -40,7 +40,7 @@ #include "ifenum.h" #include -#define NDEBUG +//#define NDEBUG #include "debug.h" /* Globals */ @@ -124,6 +124,7 @@ NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, DWORD toiType, DWORD toiId, DWORD teiEntity, + DWORD teiInstance, DWORD fixedPart, DWORD entrySize, PVOID *tdiEntitySet, @@ -148,6 +149,7 @@ NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, req.ID.toi_type = toiType; req.ID.toi_id = toiId; req.ID.toi_entity.tei_entity = teiEntity; + req.ID.toi_entity.tei_instance = teiInstance; /* There's a subtle problem here... * If an interface is added at this exact instant, (as if by a PCMCIA @@ -168,7 +170,7 @@ NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, &allocationSizeForEntityArray, NULL ); - if(!status) + if(!NT_SUCCESS(status)) { DPRINT("IOCTL Failed\n"); return STATUS_UNSUCCESSFUL; @@ -285,6 +287,7 @@ NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile, INFO_TYPE_PROVIDER, ENTITY_LIST_ID, GENERIC_ENTITY, + 0, 0, sizeof(TDIEntityID), (PVOID *)entitySet, @@ -303,7 +306,7 @@ NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile, return status; } -static BOOL isInterface( TDIEntityID *if_maybe ) { +BOOL isInterface( TDIEntityID *if_maybe ) { return if_maybe->tei_entity == IF_ENTITY; } @@ -348,6 +351,30 @@ NTSTATUS tdiGetEntityType( HANDLE tcpFile, TDIEntityID *ent, PULONG type ) { return (status ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); } +BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ) { + TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT; + NTSTATUS status = STATUS_SUCCESS; + DWORD returnSize, type; + + req.ID.toi_class = INFO_CLASS_GENERIC; + req.ID.toi_type = INFO_TYPE_PROVIDER; + req.ID.toi_id = ENTITY_TYPE_ID; + req.ID.toi_entity.tei_entity = AT_ENTITY; + req.ID.toi_entity.tei_instance = arp_maybe->tei_instance; + + status = DeviceIoControl( tcpFile, + IOCTL_TCP_QUERY_INFORMATION_EX, + &req, + sizeof(req), + &type, + sizeof(type), + &returnSize, + NULL ); + + if( !NT_SUCCESS(status) ) return FALSE; + return type == AT_ENTITY; +} + static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile, IFInfo **infoSet, PDWORD numInterfaces ) { diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_private.h b/reactos/dll/win32/iphlpapi/iphlpapi_private.h index 4d4fb1ed47c..40c4a0bd5d3 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_private.h +++ b/reactos/dll/win32/iphlpapi/iphlpapi_private.h @@ -118,7 +118,8 @@ VOID closeTcpFile(HANDLE tcpFile); NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile, TDIEntityID **entitySet, PDWORD numEntities ); NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, DWORD toiClass, DWORD toiType, - DWORD toiId, DWORD teiEntity, DWORD fixedPart, + DWORD toiId, DWORD teiEntity, DWORD teiInstance, + DWORD fixedPart, DWORD entrySize, PVOID *tdiEntitySet, PDWORD numEntries ); VOID tdiFreeThingSet( PVOID things ); @@ -134,6 +135,8 @@ PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ); void ConsumeChildKeyName( PWCHAR Name ); PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ); void ConsumeRegValueString( PWCHAR NameServer ); +BOOL isInterface( TDIEntityID *if_maybe ); +BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ); #include /* This is here until we switch to version 2.5 of the mingw headers */ diff --git a/reactos/dll/win32/iphlpapi/ipstats_reactos.c b/reactos/dll/win32/iphlpapi/ipstats_reactos.c index 4322937fedb..b6b160c4fb7 100644 --- a/reactos/dll/win32/iphlpapi/ipstats_reactos.c +++ b/reactos/dll/win32/iphlpapi/ipstats_reactos.c @@ -183,6 +183,7 @@ NTSTATUS tdiGetRoutesForIpEntity INFO_TYPE_PROVIDER, IP_MIB_ROUTETABLE_ENTRY_ID, ent->tei_entity, + 0, 0, sizeof(IPRouteEntry), (PVOID *)routes, @@ -203,6 +204,7 @@ NTSTATUS tdiGetIpAddrsForIpEntity INFO_TYPE_PROVIDER, IP_MIB_ADDRTABLE_ENTRY_ID, ent->tei_entity, + 0, 0, sizeof(IPAddrEntry), (PVOID *)addrs, @@ -507,12 +509,106 @@ RouteTable *getRouteTable(void) DWORD getNumArpEntries(void) { - return getNumWithOneHeader("/proc/net/arp"); + DWORD numEntities; + TDIEntityID *entitySet = NULL; + HANDLE tcpFile; + int i, totalNumber = 0; + NTSTATUS status; + PMIB_IPNETROW IpArpTable = NULL; + DWORD returnSize; + + TRACE("called.\n"); + + status = openTcpFile( &tcpFile ); + + if( !NT_SUCCESS(status) ) { + TRACE("failure: %08x\n", (int)status ); + return 0; + } + + status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); + + for( i = 0; i < numEntities; i++ ) { + if( isInterface( &entitySet[i] ) && + hasArp( tcpFile, &entitySet[i] ) ) { + + status = tdiGetSetOfThings( tcpFile, + INFO_CLASS_PROTOCOL, + INFO_TYPE_PROVIDER, + IP_MIB_ARPTABLE_ENTRY_ID, + AT_ENTITY, + entitySet[i].tei_instance, + 0, + sizeof(MIB_IPNETROW), + (PVOID *)&IpArpTable, + &returnSize ); + + if( status == STATUS_SUCCESS ) totalNumber += returnSize; + if( IpArpTable ) tdiFreeThingSet( IpArpTable ); + } + } + + closeTcpFile( tcpFile ); + if( IpArpTable ) tdiFreeThingSet( IpArpTable ); + if( entitySet ) tdiFreeThingSet( entitySet ); + return totalNumber; } PMIB_IPNETTABLE getArpTable(void) { - return 0; + DWORD numEntities, returnSize; + TDIEntityID *entitySet; + HANDLE tcpFile; + int i, row = 0, totalNumber; + NTSTATUS status; + PMIB_IPNETTABLE IpArpTable = NULL; + PMIB_IPNETROW AdapterArpTable = NULL; + + TRACE("called.\n"); + + totalNumber = getNumArpEntries(); + + status = openTcpFile( &tcpFile ); + + if( !NT_SUCCESS(status) ) { + TRACE("failure: %08x\n", (int)status ); + return 0; + } + + IpArpTable = HeapAlloc + ( GetProcessHeap(), 0, + sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber) ); + + status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); + + for( i = 0; i < numEntities; i++ ) { + if( isIpEntity( tcpFile, &entitySet[i] ) && + hasArp( tcpFile, &entitySet[i] ) ) { + + status = tdiGetSetOfThings( tcpFile, + INFO_CLASS_PROTOCOL, + INFO_TYPE_PROVIDER, + IP_MIB_ARPTABLE_ENTRY_ID, + AT_ENTITY, + entitySet[i].tei_instance, + 0, + sizeof(MIB_IPNETROW), + (PVOID *)&AdapterArpTable, + &returnSize ); + + if( status == STATUS_SUCCESS ) { + for( row = 0; row < returnSize; row++ ) + IpArpTable->table[row] = AdapterArpTable[row]; + } + + if( AdapterArpTable ) tdiFreeThingSet( AdapterArpTable ); + } + } + + tdiFreeThingSet( entitySet ); + IpArpTable->dwNumEntries = row; + + return IpArpTable; } DWORD getNumUdpEntries(void) diff --git a/reactos/drivers/network/tcpip/include/info.h b/reactos/drivers/network/tcpip/include/info.h index eb066773b21..50cfa9a5bc2 100644 --- a/reactos/drivers/network/tcpip/include/info.h +++ b/reactos/drivers/network/tcpip/include/info.h @@ -46,6 +46,19 @@ typedef struct IPADDR_ENTRY { USHORT Pad; } IPADDR_ENTRY, *PIPADDR_ENTRY; +#define ARP_ENTRY_STATIC 4 +#define ARP_ENTRY_DYNAMIC 3 +#define ARP_ENTRY_INVALID 2 +#define ARP_ENTRY_OTHER 1 + +typedef struct IPARP_ENTRY { + ULONG Index; + ULONG AddrSize; + UCHAR PhysAddr[8]; + ULONG LogAddr; + ULONG Type; +} IPARP_ENTRY, *PIPARP_ENTRY; + typedef struct IPROUTE_ENTRY { ULONG Dest; ULONG Index; //matches if_index in IFEntry and iae_index in IPAddrEntry @@ -96,6 +109,9 @@ typedef struct IFENTRY { #ifndef IP_MIB_ADDRTABLE_ENTRY_ID #define IP_MIB_ADDRTABLE_ENTRY_ID 0x102 #endif +#ifndef IP_MIB_ARPTABLE_ENTRY_ID +#define IP_MIB_ARPTABLE_ENTRY_ID 0x101 +#endif #ifndef MAX_PHYSADDR_SIZE #define MAX_PHYSADDR_SIZE 8 #endif diff --git a/reactos/drivers/network/tcpip/include/neighbor.h b/reactos/drivers/network/tcpip/include/neighbor.h index 4d30cb346ec..aa1859426a9 100644 --- a/reactos/drivers/network/tcpip/include/neighbor.h +++ b/reactos/drivers/network/tcpip/include/neighbor.h @@ -107,6 +107,10 @@ BOOLEAN NBQueuePacket( VOID NBRemoveNeighbor( PNEIGHBOR_CACHE_ENTRY NCE); +DWORD NBCopyNeighbors( + PIP_INTERFACE Interface, + PIPARP_ENTRY ArpTable); + #endif /* __NEIGHBOR_H */ /* EOF */ diff --git a/reactos/drivers/network/tcpip/include/precomp.h b/reactos/drivers/network/tcpip/include/precomp.h index 680d9dd01ec..5906ced640f 100644 --- a/reactos/drivers/network/tcpip/include/precomp.h +++ b/reactos/drivers/network/tcpip/include/precomp.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/reactos/drivers/network/tcpip/tcpip/iinfo.c b/reactos/drivers/network/tcpip/tcpip/iinfo.c index 8e3eaf97e52..7a6fe06f49c 100644 --- a/reactos/drivers/network/tcpip/tcpip/iinfo.c +++ b/reactos/drivers/network/tcpip/tcpip/iinfo.c @@ -78,6 +78,42 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID, return Status; } +TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID *ID, + PIP_INTERFACE Interface, + PNDIS_BUFFER Buffer, + PUINT BufferSize) { + NTSTATUS Status; + DWORD NumNeighbors = NBCopyNeighbors( Interface, NULL ); + DWORD MemSize = NumNeighbors * sizeof(IPARP_ENTRY); + PIPARP_ENTRY ArpEntries = + ExAllocatePoolWithTag + ( NonPagedPool, MemSize, FOURCC('A','R','P','t') ); + + if( !ArpEntries ) return STATUS_NO_MEMORY; + NBCopyNeighbors( Interface, ArpEntries ); + + Status = InfoCopyOut( (PVOID)ArpEntries, MemSize, Buffer, BufferSize ); + + ExFreePool( ArpEntries ); + + return Status; +} + +TDI_STATUS InfoTdiQueryGetArpCapability(TDIEntityID *ID, + PIP_INTERFACE Interface, + PNDIS_BUFFER Buffer, + PUINT BufferSize) { + NTSTATUS Status; + DWORD Capability = 0x280; + + TI_DbgPrint(MID_TRACE,("Copying out %d bytes (AT_ENTITY capability)\n", + sizeof(Capability))); + Status = InfoCopyOut + ( (PVOID)&Capability, sizeof(Capability), Buffer, BufferSize ); + + return Status; +} + TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass, UINT InfoType, UINT InfoId, @@ -87,13 +123,22 @@ TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass, PUINT BufferSize ) { if( InfoClass == INFO_CLASS_GENERIC && InfoType == INFO_TYPE_PROVIDER && - InfoId == ENTITY_TYPE_ID ) { - ULONG Temp = IF_MIB; - return InfoCopyOut( (PCHAR)&Temp, sizeof(Temp), Buffer, BufferSize ); + InfoId == ENTITY_TYPE_ID && + id->tei_entity == AT_ENTITY ) { + return InfoTdiQueryGetArpCapability( id, Context, Buffer, BufferSize ); } else if( InfoClass == INFO_CLASS_PROTOCOL && InfoType == INFO_TYPE_PROVIDER && InfoId == IF_MIB_STATS_ID ) { return InfoTdiQueryGetInterfaceMIB( id, Context, Buffer, BufferSize ); + } else if( InfoClass == INFO_CLASS_GENERIC && + InfoType == INFO_TYPE_PROVIDER && + InfoId == ENTITY_TYPE_ID ) { + ULONG Temp = IF_MIB; + return InfoCopyOut( (PCHAR)&Temp, sizeof(Temp), Buffer, BufferSize ); + } else if( InfoClass == INFO_CLASS_PROTOCOL && + InfoType == INFO_TYPE_PROVIDER && + InfoId == IP_MIB_ARPTABLE_ENTRY_ID ) { + return InfoTdiQueryGetArptableMIB( id, Context, Buffer, BufferSize ); } else return TDI_INVALID_REQUEST; } diff --git a/reactos/drivers/network/tcpip/tcpip/info.c b/reactos/drivers/network/tcpip/tcpip/info.c index 10d466180cb..fb4305c5919 100644 --- a/reactos/drivers/network/tcpip/tcpip/info.c +++ b/reactos/drivers/network/tcpip/tcpip/info.c @@ -164,6 +164,35 @@ TDI_STATUS InfoTdiQueryInformationEx( Status = TDI_INVALID_PARAMETER; } else Status = InfoTdiQueryListEntities(Buffer, BufferSize); + } else if (ID->toi_entity.tei_entity == AT_ENTITY) { + TcpipAcquireSpinLock( &EntityListLock, &OldIrql ); + + for( i = 0; i < EntityCount; i++ ) { + if( EntityList[i].tei_entity == IF_ENTITY && + EntityList[i].tei_instance == ID->toi_entity.tei_instance ) { + InfoRequest = EntityList[i].info_req; + context = EntityList[i].context; + FoundEntity = TRUE; + break; + } + } + + TcpipReleaseSpinLock( &EntityListLock, OldIrql ); + + if( FoundEntity ) { + TI_DbgPrint(DEBUG_INFO, + ("Calling AT Entity %d (%04x:%d) InfoEx (%x,%x,%x)\n", + i, ID->toi_entity.tei_entity, + ID->toi_entity.tei_instance, + ID->toi_class, ID->toi_type, ID->toi_id)); + Status = InfoRequest( ID->toi_class, + ID->toi_type, + ID->toi_id, + context, + &ID->toi_entity, + Buffer, + BufferSize ); + } } else { TcpipAcquireSpinLock( &EntityListLock, &OldIrql ); diff --git a/reactos/include/psdk/tcpioctl.h b/reactos/include/psdk/tcpioctl.h index 708641d6faf..d04411ff707 100644 --- a/reactos/include/psdk/tcpioctl.h +++ b/reactos/include/psdk/tcpioctl.h @@ -45,6 +45,7 @@ #define IF_MIB_STATS_ID 1 #define IP_MIB_STATS_ID 1 +#define IP_MIB_ARPTABLE_ENTRY_ID 0x101 #define IP_MIB_ADDRTABLE_ENTRY_ID 0x102 #define IP_INTFC_INFO_ID 0x103 #define MAX_PHYSADDR_SIZE 8 diff --git a/reactos/lib/drivers/ip/network/neighbor.c b/reactos/lib/drivers/ip/network/neighbor.c index 6d5248a67ae..330caa48117 100644 --- a/reactos/lib/drivers/ip/network/neighbor.c +++ b/reactos/lib/drivers/ip/network/neighbor.c @@ -514,3 +514,43 @@ VOID NBRemoveNeighbor( TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql); } + +ULONG NBCopyNeighbors +(PIP_INTERFACE Interface, + PIPARP_ENTRY ArpTable) +{ + PNEIGHBOR_CACHE_ENTRY CurNCE; + KIRQL OldIrql; + UINT Size = 0, i; + + for (i = 0; i <= NB_HASHMASK; i++) { + TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql); + for( CurNCE = NeighborCache[i].Cache; + CurNCE; + CurNCE = CurNCE->Next ) { + if( CurNCE->Interface == Interface ) { + if( ArpTable ) { + ArpTable[Size].Index = Interface->Index; + ArpTable[Size].AddrSize = CurNCE->LinkAddressLength; + RtlCopyMemory + (ArpTable[Size].PhysAddr, + CurNCE->LinkAddress, + CurNCE->LinkAddressLength); + ArpTable[Size].LogAddr = CurNCE->Address.Address.IPv4Address; + if( CurNCE->State & NUD_PERMANENT ) + ArpTable[Size].Type = ARP_ENTRY_STATIC; + else if( CurNCE->State & NUD_CONNECTED ) + ArpTable[Size].Type = ARP_ENTRY_DYNAMIC; + else if( !(CurNCE->State & NUD_VALID) ) + ArpTable[Size].Type = ARP_ENTRY_INVALID; + else + ArpTable[Size].Type = ARP_ENTRY_OTHER; + } + Size++; + } + } + TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql); + } + + return Size; +} From 391e807b81adeb87916a102cbf86c75a2200a701 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Fri, 22 Sep 2006 17:26:20 +0000 Subject: [PATCH 303/488] finish implement NtGdiCloseEnhMetaFile it is not fully tested it can contain bugs svn path=/trunk/; revision=24228 --- .../win32/win32k/objects/metafile.c | 103 +++++++++++++----- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/metafile.c b/reactos/subsystems/win32/win32k/objects/metafile.c index 908e2cdcfbd..fbe95b61bdc 100644 --- a/reactos/subsystems/win32/win32k/objects/metafile.c +++ b/reactos/subsystems/win32/win32k/objects/metafile.c @@ -37,21 +37,8 @@ NtGdiCloseEnhMetaFile(HDC hDC) IO_STATUS_BLOCK Iosb; NTSTATUS Status; - DPRINT1("NtGdiCloseEnhMetaFile\n"); - - /* Todo - Rewrite it to own api call IntGdiCloseEmhMetaFile - - Translate follow api to kernel api - // hMapping = CreateFileMappingW(Dc->hFile, NULL, PAGE_READONLY, 0, 0, NULL); - // Dc->emh = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); - // hmf = EMF_Create_HENHMETAFILE( Dc->emh, (Dc->hFile != 0) ); - - - DC_SetOwnership(hdc, - */ - - + + Dc = DC_LockDc(hDC); if (Dc == NULL) { @@ -121,34 +108,47 @@ NtGdiCloseEnhMetaFile(HDC hDC) LARGE_INTEGER Distance ; IO_STATUS_BLOCK IoStatusBlock; + POBJECT_ATTRIBUTES ObjectAttributes = NULL; + ACCESS_MASK DesiredAccess; + PLARGE_INTEGER SectionSize = NULL; + DWORD flProtect; + ULONG Attributes; + LARGE_INTEGER SectionOffset; + ULONG ViewSize; + ULONG Protect; + LPVOID ViewBase; + Distance.u.LowPart = 0; Distance.u.HighPart = 0; FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart; + DPRINT1("Trying write to metafile and map it\n"); + Status = NtSetInformationFile(Dc->hFile, &IoStatusBlock, &FilePosition, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation); if (!NT_SUCCESS(Status)) { - /* FIXME */ - // SetLastErrorByStatus(errCode); + // SetLastErrorByStatus(Status); SetLastWin32Error(ERROR_INVALID_HANDLE); NtClose( Dc->hFile ); DC_UnlockDc(Dc); NtGdiDeleteObjectApp(hDC); + + DPRINT1("NtSetInformationFile fail\n"); return hmf; } if (FilePosition.CurrentByteOffset.u.LowPart != 0) { - /* FIXME */ - // SetLastErrorByStatus(errCode); + // SetLastErrorByStatus(Status); SetLastWin32Error(ERROR_INVALID_HANDLE); NtClose( Dc->hFile ); DC_UnlockDc(Dc); NtGdiDeleteObjectApp(hDC); + DPRINT1("FilePosition.CurrentByteOffset.u.LowPart is not 0\n"); return hmf; } @@ -166,19 +166,68 @@ NtGdiCloseEnhMetaFile(HDC hDC) { NtClose( Dc->hFile ); DC_UnlockDc(Dc); - NtGdiDeleteObjectApp(hDC); + NtGdiDeleteObjectApp(hDC); + DPRINT1("fail to write 0\n"); return hmf; } EngFreeMem(Dc->emh); - /* FIXME */ - // hMapping = CreateFileMappingW(Dc->hFile, NULL, PAGE_READONLY, 0, 0, NULL); - - /* FIXME */ - // Dc->emh = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); - NtClose( hMapping ); - NtClose( Dc->hFile ); + /* create maping */ + DesiredAccess = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ; + Attributes = (PAGE_READONLY & (SEC_FILE | SEC_IMAGE | SEC_RESERVE | SEC_NOCACHE | SEC_COMMIT)); + flProtect = PAGE_READONLY ^ (PAGE_READONLY & (SEC_FILE | SEC_IMAGE | SEC_RESERVE | SEC_NOCACHE | SEC_COMMIT)); + + if (!Attributes) Attributes = SEC_COMMIT; + + if (Dc->hFile == INVALID_HANDLE_VALUE) + { + Dc->hFile = NULL; + if (!SectionSize) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + hMapping = NULL; + DPRINT1("fail !SectionSize \n"); + } + } + else + { + Status = NtCreateSection(&hMapping, DesiredAccess, ObjectAttributes, SectionSize, flProtect, Attributes, Dc->hFile); + if (!NT_SUCCESS(Status)) + { + //SetLastErrorByStatus(Status); + SetLastWin32Error(ERROR_INVALID_HANDLE); + hMapping = NULL; + DPRINT1("fail NtCreateSection \n"); + } + } + + /* MapViewOfFile */ + SectionOffset.LowPart = 0; + SectionOffset.HighPart = 0; + ViewBase = NULL; + ViewSize = 0; + + Protect = PAGE_READONLY; + + Status = ZwMapViewOfSection(&hMapping, NtCurrentProcess(), &ViewBase, 0, + 0, &SectionOffset, &ViewSize, ViewShare, 0, Protect); + if (!NT_SUCCESS(Status)) + { + //SetLastErrorByStatus(Status); + SetLastWin32Error(ERROR_INVALID_HANDLE); + Dc->emh = NULL; + DPRINT1("fail ZwMapViewOfSection \n"); + } + else + { + Dc->emh = ViewBase; + } + /* Close */ + if (hMapping != NULL) + NtClose( hMapping ); + if (Dc->hFile != NULL) + NtClose( Dc->hFile ); } hmf = GDIOBJ_AllocObj(GdiHandleTable, GDI_OBJECT_TYPE_ENHMETAFILE); From cfe10b7a75ee9981318fc58070f9d84bb48eab02 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Fri, 22 Sep 2006 20:19:49 +0000 Subject: [PATCH 304/488] Implement BRUSH_GetObject it is not perfect, it return wrong color in some case. But we get down from 20 to 11 fails in wine test. Wine say GetObject (HANDLE obj, INT Count, PVOID * Buffer) if Buffer is NULL return the requeuer size in bytes svn path=/trunk/; revision=24229 --- reactos/subsystems/win32/win32k/include/brush.h | 2 ++ reactos/subsystems/win32/win32k/objects/brush.c | 13 +++++++++++++ reactos/subsystems/win32/win32k/objects/dc.c | 8 +++++--- reactos/subsystems/win32/win32k/objects/text.c | 15 +++++++++------ 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/brush.h b/reactos/subsystems/win32/win32k/include/brush.h index 54b2a4b7369..c1e854ab02a 100644 --- a/reactos/subsystems/win32/win32k/include/brush.h +++ b/reactos/subsystems/win32/win32k/include/brush.h @@ -72,6 +72,8 @@ typedef struct #define BRUSHOBJ_FreeBrush(hBrush) GDIOBJ_FreeObj(GdiHandleTable, (HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH) #define BRUSHOBJ_LockBrush(hBrush) ((PGDIBRUSHOBJ)GDIOBJ_LockObj(GdiHandleTable, (HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH)) #define BRUSHOBJ_UnlockBrush(pBrush) GDIOBJ_UnlockObjByPtr(GdiHandleTable, pBrush) + +INT FASTCALL BRUSH_GetObject (PGDIBRUSHOBJ GdiObject, INT Count, BRUSHOBJ * Buffer); BOOL INTERNAL_CALL BRUSH_Cleanup(PVOID ObjectBody); #endif diff --git a/reactos/subsystems/win32/win32k/objects/brush.c b/reactos/subsystems/win32/win32k/objects/brush.c index ca2dbdea09c..426a05774ad 100644 --- a/reactos/subsystems/win32/win32k/objects/brush.c +++ b/reactos/subsystems/win32/win32k/objects/brush.c @@ -49,6 +49,19 @@ BRUSH_Cleanup(PVOID ObjectBody) return TRUE; } +INT FASTCALL +BRUSH_GetObject (PGDIBRUSHOBJ BrushObj, INT Count, BRUSHOBJ * Buffer) +{ + if (Buffer) + { + Buffer->iSolidColor = BrushObj->BrushAttr.lbColor; + Buffer->pvRbrush = BrushObj->ulRealization; + Buffer->flColorType = 0; + } + return sizeof(BRUSHOBJ); +} + + XLATEOBJ* FASTCALL IntGdiCreateBrushXlate(PDC Dc, GDIBRUSHOBJ *BrushObj, BOOLEAN *Failed) { diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index f3a43d4607e..4fd4a2bf545 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -1716,6 +1716,7 @@ NtGdiGetDeviceCaps(HDC hDC, DC_GET_VAL( INT, NtGdiGetMapMode, w.MapMode ) DC_GET_VAL( INT, NtGdiGetPolyFillMode, w.polyFillMode ) + INT FASTCALL IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer) { @@ -1737,10 +1738,11 @@ IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer) case GDI_OBJECT_TYPE_PEN: Result = PEN_GetObject((PENOBJ *) GdiObject, Count, Buffer); break; - case GDI_OBJECT_TYPE_BRUSH: - Result = BRUSH_GetObject((BRUSHOBJ *) GdiObject, Count, Buffer); - break; #endif + case GDI_OBJECT_TYPE_BRUSH: + Result = BRUSH_GetObject((PGDIBRUSHOBJ ) GdiObject, Count, (BRUSHOBJ *)Buffer); + break; + case GDI_OBJECT_TYPE_BITMAP: Result = BITMAP_GetObject((BITMAPOBJ *) GdiObject, Count, Buffer); break; diff --git a/reactos/subsystems/win32/win32k/objects/text.c b/reactos/subsystems/win32/win32k/objects/text.c index 9e5549c0022..84229a78d9c 100644 --- a/reactos/subsystems/win32/win32k/objects/text.c +++ b/reactos/subsystems/win32/win32k/objects/text.c @@ -3917,13 +3917,16 @@ TextIntRealizeFont(HFONT FontHandle) INT FASTCALL FontGetObject(PTEXTOBJ Font, INT Count, PVOID Buffer) { - if (Count < sizeof(LOGFONTW)) - { - SetLastWin32Error(ERROR_BUFFER_OVERFLOW); - return 0; - } + if (Buffer) + { + if (Count < sizeof(LOGFONTW)) + { + SetLastWin32Error(ERROR_BUFFER_OVERFLOW); + return 0; + } - RtlCopyMemory(Buffer, &Font->logfont, sizeof(LOGFONTW)); + RtlCopyMemory(Buffer, &Font->logfont, sizeof(LOGFONTW)); + } return sizeof(LOGFONTW); } From 8f9a18cfff136354fc4fd411b887e5c8bc6ef45c Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Fri, 22 Sep 2006 21:45:35 +0000 Subject: [PATCH 305/488] Merge 24219-24222, and 24209 from trunk. svn path=/branches/ros-branch-0_3_1/; revision=24230 --- reactos/dll/win32/gdi32/objects/font.c | 120 ++++++++++++++++++++++--- reactos/dll/win32/ws2_32/misc/ns.c | 21 +++-- 2 files changed, 126 insertions(+), 15 deletions(-) diff --git a/reactos/dll/win32/gdi32/objects/font.c b/reactos/dll/win32/gdi32/objects/font.c index 96e59690635..d4e5139bd27 100644 --- a/reactos/dll/win32/gdi32/objects/font.c +++ b/reactos/dll/win32/gdi32/objects/font.c @@ -42,6 +42,31 @@ static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA ) ptmA->tmCharSet = ptmW->tmCharSet; } +/*********************************************************************** + * FONT_mbtowc + * + * Returns a Unicode translation of str. If count is -1 then str is + * assumed to be '\0' terminated, otherwise it contains the number of + * bytes to convert. If plenW is non-NULL, on return it will point to + * the number of WCHARs that have been written. The caller should free + * the returned LPWSTR from the process heap itself. + */ +static LPWSTR FONT_mbtowc(LPCSTR str, INT count, INT *plenW) +{ + UINT cp = CP_ACP; + INT lenW; + LPWSTR strW; + + if(count == -1) count = strlen(str); + lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0); + strW = HeapAlloc(GetProcessHeap(), 0, lenW*sizeof(WCHAR)); + MultiByteToWideChar(cp, 0, str, count, strW, lenW); + DPRINT1("mapped %s -> %s \n", str, strW); + if(plenW) *plenW = lenW; + return strW; +} + + static BOOL FASTCALL MetricsCharConvert(WCHAR w, UCHAR *b) { @@ -358,6 +383,8 @@ GetCharWidthA ( LPINT lpBuffer ) { +DPRINT1("GCWA iFirstChar %x\n",iFirstChar); + return GetCharWidth32A ( hdc, iFirstChar, iLastChar, lpBuffer ); } @@ -374,8 +401,35 @@ GetCharWidth32A( LPINT lpBuffer ) { - /* FIXME should be NtGdiGetCharWidthW */ - return NtGdiGetCharWidth32(hdc, iFirstChar, iLastChar, lpBuffer); + INT i, wlen, count = (INT)(iLastChar - iFirstChar + 1); + LPSTR str; + LPWSTR wstr; + BOOL ret = TRUE; +DPRINT1("GCW32A iFirstChar %x\n",iFirstChar); + + if(count <= 0) return FALSE; + + str = HeapAlloc(GetProcessHeap(), 0, count); + for(i = 0; i < count; i++) + str[i] = (BYTE)(iFirstChar + i); + + wstr = FONT_mbtowc(str, count, &wlen); + + for(i = 0; i < wlen; i++) + { + /* FIXME should be NtGdiGetCharWidthW */ + if(!NtGdiGetCharWidth32 (hdc, wstr[i], wstr[i], lpBuffer)) + { + ret = FALSE; + break; + } + lpBuffer++; + } + + HeapFree(GetProcessHeap(), 0, str); + HeapFree(GetProcessHeap(), 0, wstr); + + return ret; } @@ -391,6 +445,8 @@ GetCharWidthW ( LPINT lpBuffer ) { +DPRINT1("GCW32w uFirstChar %x\n",iFirstChar); + /* FIXME should be NtGdiGetCharWidthW */ return NtGdiGetCharWidth32 ( hdc, iFirstChar, iLastChar, lpBuffer ); } @@ -496,7 +552,7 @@ GetCharWidthFloatA( /* - * @unimplemented + * @implemented */ BOOL APIENTRY @@ -507,8 +563,9 @@ GetCharABCWidthsA( LPABC lpabc ) { - /* FIXME what to do with uFirstChar and uLastChar ??? */ - return NtGdiGetCharABCWidths ( hdc, uFirstChar, uLastChar, lpabc ); +DPRINT1("GCABCWA uFirstChar %x\n",uFirstChar); + +return NtGdiGetCharABCWidths(hdc, uFirstChar, uLastChar, lpabc); } @@ -524,6 +581,8 @@ GetCharABCWidthsFloatA( LPABCFLOAT lpABCF ) { +DPRINT1("GCABCWFA iFirstChar %x\n",iFirstChar); + /* FIXME what to do with iFirstChar and iLastChar ??? */ return NtGdiGetCharABCWidthsFloat ( hdc, iFirstChar, iLastChar, lpABCF ); } @@ -544,9 +603,32 @@ GetGlyphOutlineA( CONST MAT2 *lpmat2 ) { - return NtGdiGetGlyphOutline ( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); + + LPWSTR p = NULL; + DWORD ret; + UINT c; + DPRINT1("GetGlyphOutlineA uChar %x\n", uChar); + if(!(uFormat & GGO_GLYPH_INDEX)) { + int len; + char mbchs[2]; + if(uChar > 0xff) { /* but, 2 bytes character only */ + len = 2; + mbchs[0] = (uChar & 0xff00) >> 8; + mbchs[1] = (uChar & 0xff); + } else { + len = 1; + mbchs[0] = (uChar & 0xff); + } + p = FONT_mbtowc(mbchs, len, NULL); + c = p[0]; + } else + c = uChar; + ret = NtGdiGetGlyphOutline(hdc, c, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); + HeapFree(GetProcessHeap(), 0, p); + return ret; } + /* * @implemented */ @@ -562,6 +644,7 @@ GetGlyphOutlineW( CONST MAT2 *lpmat2 ) { + DPRINT1("GetGlyphOutlineW uChar %x\n", uChar); return NtGdiGetGlyphOutline ( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE); } @@ -696,6 +779,20 @@ GetOutlineTextMetricsA( if(output != lpOTM) { memcpy(lpOTM, output, cbData); HeapFree(GetProcessHeap(), 0, output); + + /* check if the string offsets really fit into the provided size */ + /* FIXME: should we check string length as well? */ + if ((UINT_PTR)lpOTM->otmpFamilyName >= lpOTM->otmSize) + lpOTM->otmpFamilyName = 0; /* doesn't fit */ + + if ((UINT_PTR)lpOTM->otmpFaceName >= lpOTM->otmSize) + lpOTM->otmpFaceName = 0; /* doesn't fit */ + + if ((UINT_PTR)lpOTM->otmpStyleName >= lpOTM->otmSize) + lpOTM->otmpStyleName = 0; /* doesn't fit */ + + if ((UINT_PTR)lpOTM->otmpFullName >= lpOTM->otmSize) + lpOTM->otmpFullName = 0; /* doesn't fit */ } end: @@ -731,10 +828,13 @@ CreateFontIndirectA( ) { LOGFONTW tlf; - - LogFontA2W(&tlf, lplf); - - return NtGdiCreateFontIndirect(&tlf); + + if (lplf) + { + LogFontA2W(&tlf, lplf); + return NtGdiCreateFontIndirect(&tlf); + } + else return NtGdiCreateFontIndirect(NULL); } diff --git a/reactos/dll/win32/ws2_32/misc/ns.c b/reactos/dll/win32/ws2_32/misc/ns.c index 9e166e65ef8..f6103b09c14 100644 --- a/reactos/dll/win32/ws2_32/misc/ns.c +++ b/reactos/dll/win32/ws2_32/misc/ns.c @@ -488,7 +488,10 @@ void populate_hostent(struct hostent *he, char* name, DNS_A_DATA addr) name, MAX_HOSTNAME_LEN); - he->h_aliases = 0; + if( !he->h_aliases ) { + he->h_aliases = HeapAlloc(GlobalHeap, 0, sizeof(char *)); + he->h_aliases[0] = 0; + } he->h_addrtype = AF_INET; he->h_length = sizeof(IN_ADDR); //sizeof(struct in_addr); @@ -518,12 +521,20 @@ void free_hostent(struct hostent *he) { if(he) { + char *next = 0; HFREE(he->h_name); - char *next = he->h_aliases[0]; - while(next) { HFREE(next); next++; } - next = he->h_addr_list[0]; - while(next) { HFREE(next); next++; } + if(he->h_aliases) + { + next = he->h_aliases[0]; + while(next) { HFREE(next); next++; } + } + if(he->h_addr_list) + { + next = he->h_addr_list[0]; + while(next) { HFREE(next); next++; } + } HFREE(he->h_addr_list); + HFREE(he->h_aliases); HFREE(he); } } From 63535f6e1594bbfd5b693a4d6c308bbb49d73ff3 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sat, 23 Sep 2006 06:19:28 +0000 Subject: [PATCH 306/488] remove folder gdi for all gdi test are in gdi32 svn path=/trunk/; revision=24231 --- reactos/regtests/winetests/gdi/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 reactos/regtests/winetests/gdi/.gitignore diff --git a/reactos/regtests/winetests/gdi/.gitignore b/reactos/regtests/winetests/gdi/.gitignore deleted file mode 100644 index e69de29bb2d..00000000000 From cc70b77eca1385ab525e275f8ce1877b8fd9d70a Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sat, 23 Sep 2006 07:28:44 +0000 Subject: [PATCH 307/488] add NULL termate on ansi string when WideCharToMultiByteCP doing wchar to ansi converting. svn path=/trunk/; revision=24232 --- reactos/dll/win32/kernel32/misc/nls.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/kernel32/misc/nls.c b/reactos/dll/win32/kernel32/misc/nls.c index 6da28161557..e355ff7accf 100644 --- a/reactos/dll/win32/kernel32/misc/nls.c +++ b/reactos/dll/win32/kernel32/misc/nls.c @@ -569,7 +569,7 @@ IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags, WideCharCount = MultiByteCount; SetLastError(ERROR_INSUFFICIENT_BUFFER); } - + for (TempLength = WideCharCount; TempLength > 0; WideCharString++, TempLength--) @@ -577,6 +577,12 @@ IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags, *MultiByteString++ = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]; } + if (WideCharCount>2) + { + MultiByteString--; + *MultiByteString = 0; + } + /* FIXME */ if (UsedDefaultChar != NULL) *UsedDefaultChar = FALSE; From e126931cb050cbdd0d93b6f3af10913c86908ac2 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 23 Sep 2006 09:34:34 +0000 Subject: [PATCH 308/488] - Issue a synchronous invalidate device relations request instead of asynchronous (eliminates the "can't open \SystemRoot\ bugcheck during 2nd stage startup) - Comment out usbport/usbhub/etc from bootcd, they will be enabled once they don't crash and/or slow down system. svn path=/trunk/; revision=24233 --- reactos/boot/bootdata/packages/reactos.dff | 8 ++++---- reactos/ntoskrnl/io/iomgr/iomgr.c | 11 ++++++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index d78742bc0ef..f58d4ae39fb 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -265,10 +265,10 @@ drivers\network\dd\pcnet\pcnet.sys 2 drivers\storage\pciide\pciide.sys 2 drivers\storage\pciidex\pciidex.sys 2 -drivers\usb\miniport\usbohci\usbohci.sys 2 -drivers\usb\miniport\usbuhci\usbuhci.sys 2 -drivers\usb\usbhub\usbhub.sys 2 -drivers\usb\usbport\usbport.sys 2 +;drivers\usb\miniport\usbohci\usbohci.sys 2 +;drivers\usb\miniport\usbuhci\usbuhci.sys 2 +;drivers\usb\usbhub\usbhub.sys 2 +;drivers\usb\usbport\usbport.sys 2 drivers\video\displays\vga\vgaddi.dll 1 drivers\video\displays\framebuf\framebuf.dll 1 diff --git a/reactos/ntoskrnl/io/iomgr/iomgr.c b/reactos/ntoskrnl/io/iomgr/iomgr.c index 6e656d69600..2c1149fdc4e 100644 --- a/reactos/ntoskrnl/io/iomgr/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr/iomgr.c @@ -15,6 +15,15 @@ ULONG IopTraceLevel = IO_IRP_DEBUG; +// should go into a proper header +VOID +NTAPI +IoSynchronousInvalidateDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN DEVICE_RELATION_TYPE Type +); + + /* DATA ********************************************************************/ POBJECT_TYPE IoDeviceObjectType = NULL; @@ -448,7 +457,7 @@ IoInit2(BOOLEAN BootLog) /* * Initialize PnP root releations */ - IoInvalidateDeviceRelations( + IoSynchronousInvalidateDeviceRelations( IopRootDeviceNode->PhysicalDeviceObject, BusRelations); From 2d2431695997ad696bd13ec6178a9e335cc6cb84 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sat, 23 Sep 2006 12:33:54 +0000 Subject: [PATCH 309/488] fixed some more setpixel bugs svn path=/trunk/; revision=24234 --- .../subsystems/win32/win32k/objects/brush.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/reactos/subsystems/win32/win32k/objects/brush.c b/reactos/subsystems/win32/win32k/objects/brush.c index 426a05774ad..11c28689b83 100644 --- a/reactos/subsystems/win32/win32k/objects/brush.c +++ b/reactos/subsystems/win32/win32k/objects/brush.c @@ -415,6 +415,26 @@ IntGdiCreateSolidBrush( ASSERT(BrushObject != NULL); BrushObject->flAttrs |= GDIBRUSH_IS_SOLID; + + if (((Color>>24) & 0xff)==0x10) + { + if (Color == 0x10ff0002) + Color = 0xFF; + else if ((Color & 0xff) !=0) + Color = Color & 0xFFFFFF; + else if ((Color & 0xff) ==0x00) + Color = ((Color>>16) & 0x0000ff) | ((Color<<16) & 0xff0000) | (Color & 0x00ff00); + else if ((Color & 0xff) ==0x01) + Color = ((Color>>16) & 0x0000ff) | ((Color<<16) & 0xff0000) | (Color & 0x00ff00); + } + + + if (((Color>>24) & 0xff)==0xff) + { + Color = ((Color>>16) & 0x0000ff) | ((Color<<16) & 0xff0000) | (Color & 0x00ff00); + } + + BrushObject->BrushAttr.lbColor = Color & 0xFFFFFF; /* FIXME: Fill in the rest of fields!!! */ From 52b43f7ae9ef81eeb936870564964c670b60a501 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sat, 23 Sep 2006 15:54:11 +0000 Subject: [PATCH 310/488] IntGdiCreateSolidBrush Remove the if table I did. Remove Color = Color & 0xffffff to Color = Color that gave same result and pass equal many wine test. we still have some werid xlate bugs some where, for set/get pixel. I should have remove Color & 0xffffff in frist place. but the code did look right. svn path=/trunk/; revision=24235 --- .../subsystems/win32/win32k/objects/brush.c | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/brush.c b/reactos/subsystems/win32/win32k/objects/brush.c index 11c28689b83..c004116305d 100644 --- a/reactos/subsystems/win32/win32k/objects/brush.c +++ b/reactos/subsystems/win32/win32k/objects/brush.c @@ -416,26 +416,7 @@ IntGdiCreateSolidBrush( BrushObject->flAttrs |= GDIBRUSH_IS_SOLID; - if (((Color>>24) & 0xff)==0x10) - { - if (Color == 0x10ff0002) - Color = 0xFF; - else if ((Color & 0xff) !=0) - Color = Color & 0xFFFFFF; - else if ((Color & 0xff) ==0x00) - Color = ((Color>>16) & 0x0000ff) | ((Color<<16) & 0xff0000) | (Color & 0x00ff00); - else if ((Color & 0xff) ==0x01) - Color = ((Color>>16) & 0x0000ff) | ((Color<<16) & 0xff0000) | (Color & 0x00ff00); - } - - - if (((Color>>24) & 0xff)==0xff) - { - Color = ((Color>>16) & 0x0000ff) | ((Color<<16) & 0xff0000) | (Color & 0x00ff00); - } - - - BrushObject->BrushAttr.lbColor = Color & 0xFFFFFF; + BrushObject->BrushAttr.lbColor = Color; /* FIXME: Fill in the rest of fields!!! */ BRUSHOBJ_UnlockBrush(BrushObject); From edeb548dd18ef31acfea2015cf8082e6e8d97721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 23 Sep 2006 16:01:02 +0000 Subject: [PATCH 311/488] Subkeys names should be case insensitive. Fixes the 'make install' problem, where shell was not starting at third boot svn path=/trunk/; revision=24236 --- reactos/tools/mkhive/registry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/tools/mkhive/registry.c b/reactos/tools/mkhive/registry.c index fcae34a3602..c1977544aa7 100644 --- a/reactos/tools/mkhive/registry.c +++ b/reactos/tools/mkhive/registry.c @@ -153,7 +153,7 @@ RegpOpenOrCreateKey( ParentKey->RegistryHive, ParentKey->KeyCell, &KeyString, - 0, + OBJ_CASE_INSENSITIVE, &SubKeyCell, &BlockOffset); if (AllowCreation && Status == STATUS_OBJECT_NAME_NOT_FOUND) From 0e779901fc805b9bb1ef8f20d1dc8f68b9494a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 23 Sep 2006 16:06:15 +0000 Subject: [PATCH 312/488] Do not display the group name of a service if it doesn't exists svn path=/trunk/; revision=24237 --- reactos/base/system/services/database.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/reactos/base/system/services/database.c b/reactos/base/system/services/database.c index 4d75727f0cf..6cdccb65e0b 100644 --- a/reactos/base/system/services/database.c +++ b/reactos/base/system/services/database.c @@ -279,7 +279,10 @@ CreateServiceListEntry(LPWSTR lpServiceName, } DPRINT("ServiceName: '%S'\n", lpService->lpServiceName); - DPRINT("Group: '%S'\n", lpService->lpGroup->lpGroupName); + if (lpService->lpGroup != NULL) + { + DPRINT("Group: '%S'\n", lpService->lpGroup->lpGroupName); + } DPRINT("Start %lx Type %lx Tag %lx ErrorControl %lx\n", lpService->dwStartType, lpService->Status.dwServiceType, From cd007816d8df3451771c35053f8eb2f1e596e272 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 23 Sep 2006 16:50:39 +0000 Subject: [PATCH 313/488] Change #defines of bios memory types to a proper enum. Makes it easier to distinguish BIOS memory types and FreeLoader's memory types (in future). svn path=/trunk/; revision=24238 --- .../boot/freeldr/freeldr/arch/i386/pcmem.c | 4 ++-- .../boot/freeldr/freeldr/arch/i386/xboxmem.c | 4 ++-- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 2 +- reactos/boot/freeldr/freeldr/include/mm.h | 12 +++++----- reactos/boot/freeldr/freeldr/mm/meminit.c | 22 +++++++++---------- reactos/boot/freeldr/freeldr/mm/mm.c | 6 ++--- .../boot/freeldr/freeldr/reactos/reactos.c | 4 ++-- .../boot/freeldr/freeldr/reactos/setupldr.c | 4 ++-- 8 files changed, 30 insertions(+), 28 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c b/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c index 9a85fee3c48..a0c4d357782 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c @@ -235,11 +235,11 @@ PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) /* Conventional memory */ BiosMemoryMap[0].BaseAddress = 0; BiosMemoryMap[0].Length = PcMemGetConventionalMemorySize() * 1024; - BiosMemoryMap[0].Type = MEMTYPE_USABLE; + BiosMemoryMap[0].Type = BiosMemoryUsable; /* Extended memory */ BiosMemoryMap[1].BaseAddress = 1024 * 1024; BiosMemoryMap[1].Length = PcMemGetExtendedMemorySize() * 1024; - BiosMemoryMap[1].Type = MEMTYPE_USABLE; + BiosMemoryMap[1].Type = BiosMemoryUsable; EntryCount = 2; } diff --git a/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c b/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c index 5c19934ef88..9efa0d35da3 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c @@ -86,7 +86,7 @@ XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) /* Available RAM block */ BiosMemoryMap[0].BaseAddress = 0; BiosMemoryMap[0].Length = AvailableMemoryMb * 1024 * 1024; - BiosMemoryMap[0].Type = MEMTYPE_USABLE; + BiosMemoryMap[0].Type = BiosMemoryUsable; EntryCount = 1; } @@ -95,7 +95,7 @@ XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) /* Video memory */ BiosMemoryMap[1].BaseAddress = AvailableMemoryMb * 1024 * 1024; BiosMemoryMap[1].Length = (InstalledMemoryMb - AvailableMemoryMb) * 1024 * 1024; - BiosMemoryMap[1].Type = MEMTYPE_RESERVED; + BiosMemoryMap[1].Type = BiosMemoryReserved; EntryCount = 2; } diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 0f339440a27..c79d5062bc7 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -256,7 +256,7 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize ) { printf("GetMemoryMap(chosen=%x)\n", chosen_package); - BiosMemoryMap[0].Type = MEMTYPE_USABLE; + BiosMemoryMap[0].Type = BiosMemoryUsable; BiosMemoryMap[0].BaseAddress = 0; BiosMemoryMap[0].Length = 32 * 1024 * 1024; /* Assume 32 meg for now */ diff --git a/reactos/boot/freeldr/freeldr/include/mm.h b/reactos/boot/freeldr/freeldr/include/mm.h index 24fce2d4b33..813bf2cc2eb 100644 --- a/reactos/boot/freeldr/freeldr/include/mm.h +++ b/reactos/boot/freeldr/freeldr/include/mm.h @@ -21,11 +21,13 @@ #ifndef __MEMORY_H #define __MEMORY_H - -#define MEMTYPE_USABLE 0x01 -#define MEMTYPE_RESERVED 0x02 -#define MEMTYPE_ACPI_RECLAIM 0x03 -#define MEMTYPE_ACPI_NVS 0x04 +typedef enum +{ + BiosMemoryUsable=1, + BiosMemoryReserved, + BiosMemoryAcpiReclaim, + BiosMemoryAcpiNvs +} BIOS_MEMORY_TYPE; typedef struct { diff --git a/reactos/boot/freeldr/freeldr/mm/meminit.c b/reactos/boot/freeldr/freeldr/mm/meminit.c index 8f3668aa150..9fe607d615b 100644 --- a/reactos/boot/freeldr/freeldr/mm/meminit.c +++ b/reactos/boot/freeldr/freeldr/mm/meminit.c @@ -27,16 +27,16 @@ typedef struct { ULONG Type; UCHAR TypeString[20]; -} MEMORY_TYPE, *PMEMORY_TYPE; +} FREELDR_MEMORY_TYPE, *PFREELDR_MEMORY_TYPE; ULONG MemoryTypeCount = 5; -MEMORY_TYPE MemoryTypeArray[] = +FREELDR_MEMORY_TYPE MemoryTypeArray[] = { { 0, "Unknown Memory" }, - { MEMTYPE_USABLE, "Usable Memory" }, - { MEMTYPE_RESERVED, "Reserved Memory" }, - { MEMTYPE_ACPI_RECLAIM, "ACPI Reclaim Memory" }, - { MEMTYPE_ACPI_NVS, "ACPI NVS Memory" }, + { BiosMemoryUsable, "Usable Memory" }, + { BiosMemoryReserved, "Reserved Memory" }, + { BiosMemoryAcpiReclaim, "ACPI Reclaim Memory" }, + { BiosMemoryAcpiNvs, "ACPI NVS Memory" }, }; #endif @@ -192,7 +192,7 @@ PVOID MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG Map { // If this is usable memory with a big enough length // then we'll put our page lookup table here - if (TempBiosMemoryMap[Index].Type == MEMTYPE_USABLE && TempBiosMemoryMap[Index].Length >= PageLookupTableSize) + if (TempBiosMemoryMap[Index].Type == BiosMemoryUsable && TempBiosMemoryMap[Index].Length >= PageLookupTableSize) { PageLookupTableMemAddress = (PVOID)(ULONG)(TempBiosMemoryMap[Index].BaseAddress + (TempBiosMemoryMap[Index].Length - PageLookupTableSize)); break; @@ -248,20 +248,20 @@ VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_ME MemoryMapStartPage = MmGetPageNumberFromAddress((PVOID)(ULONG)BiosMemoryMap[Index].BaseAddress); MemoryMapEndPage = MmGetPageNumberFromAddress((PVOID)(ULONG)(BiosMemoryMap[Index].BaseAddress + BiosMemoryMap[Index].Length - 1)); MemoryMapPageCount = (MemoryMapEndPage - MemoryMapStartPage) + 1; - MemoryMapPageAllocated = (BiosMemoryMap[Index].Type == MEMTYPE_USABLE) ? 0 : BiosMemoryMap[Index].Type; + MemoryMapPageAllocated = (BiosMemoryMap[Index].Type == BiosMemoryUsable) ? 0 : BiosMemoryMap[Index].Type; DbgPrint((DPRINT_MEMORY, "Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryMapStartPage, MemoryMapPageCount)); MmMarkPagesInLookupTable(PageLookupTable, MemoryMapStartPage, MemoryMapPageCount, MemoryMapPageAllocated); } // Mark the low memory region below 1MB as reserved (256 pages in region) DbgPrint((DPRINT_MEMORY, "Marking the low 1MB region as reserved.\n")); - MmMarkPagesInLookupTable(PageLookupTable, 0, 256, MEMTYPE_RESERVED); + MmMarkPagesInLookupTable(PageLookupTable, 0, 256, BiosMemoryReserved); // Mark the pages that the lookup tabel occupies as reserved PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable); PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage; DbgPrint((DPRINT_MEMORY, "Marking the page lookup table pages as reserved StartPage: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount)); - MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, MEMTYPE_RESERVED); + MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, BiosMemoryReserved); } VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, ULONG PageAllocated) @@ -414,7 +414,7 @@ VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount) // If the entry type isn't usable then remove // it from the memory map (this will help reduce // the size of our lookup table) - if (BiosMemoryMap[Index].Type != MEMTYPE_USABLE) + if (BiosMemoryMap[Index].Type != BiosMemoryUsable) { // Slide every entry after this down one for (Index2=Index; Index2<(*MapCount - 1); Index2++) diff --git a/reactos/boot/freeldr/freeldr/mm/mm.c b/reactos/boot/freeldr/freeldr/mm/mm.c index d5ad60f0c26..e1d7fcc7f3b 100644 --- a/reactos/boot/freeldr/freeldr/mm/mm.c +++ b/reactos/boot/freeldr/freeldr/mm/mm.c @@ -392,13 +392,13 @@ VOID DumpMemoryAllocMap(VOID) case 1: DbgPrint((DPRINT_MEMORY, "A")); break; - case MEMTYPE_RESERVED: + case BiosMemoryReserved: DbgPrint((DPRINT_MEMORY, "R")); break; - case MEMTYPE_ACPI_RECLAIM: + case BiosMemoryAcpiReclaim: DbgPrint((DPRINT_MEMORY, "M")); break; - case MEMTYPE_ACPI_NVS: + case BiosMemoryAcpiNvs: DbgPrint((DPRINT_MEMORY, "N")); break; default: diff --git a/reactos/boot/freeldr/freeldr/reactos/reactos.c b/reactos/boot/freeldr/freeldr/reactos/reactos.c index f76d8d280fe..15f0e90ffa4 100644 --- a/reactos/boot/freeldr/freeldr/reactos/reactos.c +++ b/reactos/boot/freeldr/freeldr/reactos/reactos.c @@ -615,7 +615,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) DbgPrint((DPRINT_REACTOS, "dumping memory map:\n")); for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++) { - if (MEMTYPE_USABLE == reactos_memory_map[i].type && + if (BiosMemoryUsable == reactos_memory_map[i].type && 0 == reactos_memory_map[i].base_addr_low) { LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024; @@ -624,7 +624,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) LoaderBlock.MemLower = 640; } } - if (MEMTYPE_USABLE == reactos_memory_map[i].type && + if (BiosMemoryUsable == reactos_memory_map[i].type && reactos_memory_map[i].base_addr_low <= 1024 * 1024 && 1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) { diff --git a/reactos/boot/freeldr/freeldr/reactos/setupldr.c b/reactos/boot/freeldr/freeldr/reactos/setupldr.c index 369d9b824cf..a03b648f48e 100644 --- a/reactos/boot/freeldr/freeldr/reactos/setupldr.c +++ b/reactos/boot/freeldr/freeldr/reactos/setupldr.c @@ -325,7 +325,7 @@ VOID RunLoader(VOID) reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24 for (i = 0; i < (LoaderBlock.MmapLength / sizeof(memory_map_t)); i++) { - if (MEMTYPE_USABLE == reactos_memory_map[i].type && + if (BiosMemoryUsable == reactos_memory_map[i].type && 0 == reactos_memory_map[i].base_addr_low) { LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024; @@ -334,7 +334,7 @@ VOID RunLoader(VOID) LoaderBlock.MemLower = 640; } } - if (MEMTYPE_USABLE == reactos_memory_map[i].type && + if (BiosMemoryUsable == reactos_memory_map[i].type && reactos_memory_map[i].base_addr_low <= 1024 * 1024 && 1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) { From 9e314810aece2a266a170a4ef85f222b15c8e765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 23 Sep 2006 20:21:41 +0000 Subject: [PATCH 314/488] Skip keyboard detection in freeldr, as it doesn't work in Qemu 0.8.2 svn path=/trunk/; revision=24239 --- reactos/boot/freeldr/freeldr/arch/i386/hardware.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c index fdfa068d1e7..a609304c3c2 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c @@ -1662,7 +1662,8 @@ DetectKeyboardPeripheral(FRLDRHKEY ControllerKey) ULONG Size; LONG Error; - if (DetectKeyboardDevice()) + /* HACK: don't call DetectKeyboardDevice() as it fails in Qemu 0.8.2 */ + if (TRUE || DetectKeyboardDevice()) { /* Create controller key */ Error = RegCreateKey(ControllerKey, From 68434f2227795cbd0fffe82db21e8f39c45d0855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 23 Sep 2006 22:09:18 +0000 Subject: [PATCH 315/488] Add default destination for driver files in keyboard.inf svn path=/trunk/; revision=24240 --- reactos/media/inf/keyboard.inf | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/reactos/media/inf/keyboard.inf b/reactos/media/inf/keyboard.inf index ce57bf04671..b632f7d03d9 100644 --- a/reactos/media/inf/keyboard.inf +++ b/reactos/media/inf/keyboard.inf @@ -9,7 +9,10 @@ LayoutFile = layout.inf Class = Keyboard ClassGUID = {4D36E96B-E325-11CE-BFC1-08002BE10318} Provider = %ReactOS% -DriverVer = 04/30/2005,1.02 +DriverVer = 09/24/2006,1.03 + +[DestinationDirs] +DefaultDestDir = 12 [ClassInstall32.NT] AddReg = KeyboardClass.NT.AddReg @@ -25,13 +28,12 @@ HKR, , UpperFilters, 0x00010000, "kbdclass" %StdMfg% = StdMfg [StdMfg] -%*PNP0303.DeviceDesc% = PS2_Inst,*PNP0303 +%*PNP0303.DeviceDesc% = PS2_Inst.NT,*PNP0303 ;------------------------------ PS/2 DRIVER ----------------------------- [PS2_Inst.NT] CopyFiles = PS2_CopyFiles.NT, kbdclass_CopyFiles.NT -AddReg = PS2_AddReg [PS2_CopyFiles.NT] i8042prt.sys From 939cbfc4c7a032a5df2a97f030e4cfc253b7fb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 23 Sep 2006 22:26:28 +0000 Subject: [PATCH 316/488] Report correct interrupt resources to ntoskrnl svn path=/trunk/; revision=24241 --- reactos/drivers/bus/acpi/ospm/fdo.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/reactos/drivers/bus/acpi/ospm/fdo.c b/reactos/drivers/bus/acpi/ospm/fdo.c index 76657ae0a29..a628e0ad3e2 100644 --- a/reactos/drivers/bus/acpi/ospm/fdo.c +++ b/reactos/drivers/bus/acpi/ospm/fdo.c @@ -174,7 +174,6 @@ AcpiCreateResourceList(PCM_RESOURCE_LIST* pResourceList, PIO_RESOURCE_DESCRIPTOR RequirementDescriptor; RESOURCE* resource; ULONG i; - KIRQL Dirql; /* Count number of resources */ Done = FALSE; @@ -263,11 +262,9 @@ AcpiCreateResourceList(PCM_RESOURCE_LIST* pResourceList, (irq_data->shared_exclusive == SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); ResourceDescriptor->Flags = (irq_data->edge_level == LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); - ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector( - Internal, 0, 0, irq_data->interrupts[i], - &Dirql, - &ResourceDescriptor->u.Interrupt.Affinity); - ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql; + ResourceDescriptor->u.Interrupt.Level = 0; + ResourceDescriptor->u.Interrupt.Vector = irq_data->interrupts[i]; + ResourceDescriptor->u.Interrupt.Affinity = (KAFFINITY)(-1); RequirementDescriptor->Option = 0; /* Required */ RequirementDescriptor->Type = ResourceDescriptor->Type; From 5d46ef1a267a53263646d4e3e34307bbb6b06cdd Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 24 Sep 2006 02:58:31 +0000 Subject: [PATCH 317/488] Fix mkhive on unix. svn path=/trunk/; revision=24242 --- reactos/Makefile | 4 ++++ reactos/tools/mkhive/mkhive.mak | 2 +- reactos/tools/mkhive/registry.c | 2 +- reactos/tools/mkhive/rtl.c | 20 +++++++++++++++++++- reactos/tools/widl/widl.mak | 2 +- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/reactos/Makefile b/reactos/Makefile index 8ec2925c90c..b35d99fcce8 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -152,11 +152,15 @@ ifeq ($(word 1,$(shell gcc -dumpmachine)),mingw32) ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) export OSTYPE = msys HOST=mingw32-linux +CFLAGS+=-fshort-wchar +CPPFLAGS+=-fshort-wchar else HOST=mingw32-windows endif else HOST=mingw32-linux +CFLAGS+=-fshort-wchar +CPPFLAGS+=-fshort-wchar endif endif diff --git a/reactos/tools/mkhive/mkhive.mak b/reactos/tools/mkhive/mkhive.mak index a4d20753d32..252bc80f7d9 100644 --- a/reactos/tools/mkhive/mkhive.mak +++ b/reactos/tools/mkhive/mkhive.mak @@ -30,7 +30,7 @@ MKHIVE_SOURCES = $(addprefix $(MKHIVE_BASE_), \ MKHIVE_OBJECTS = \ $(addprefix $(INTERMEDIATE_), $(MKHIVE_SOURCES:.c=.o)) -MKHIVE_HOST_CFLAGS = $(xTOOLS_CFLAGS) -I$(INFLIB_BASE) -I$(CMLIB_BASE) \ +MKHIVE_HOST_CFLAGS = -fshort-wchar $(xTOOLS_CFLAGS) -I$(INFLIB_BASE) -I$(CMLIB_BASE) \ -D_NTOSKRNL_ \ -Iinclude/reactos -Iinclude/ddk -Iinclude/ndk -Iinclude/psdk -Iinclude -Iinclude/crt -g3 diff --git a/reactos/tools/mkhive/registry.c b/reactos/tools/mkhive/registry.c index c1977544aa7..6ef405167b7 100644 --- a/reactos/tools/mkhive/registry.c +++ b/reactos/tools/mkhive/registry.c @@ -122,7 +122,7 @@ RegpOpenOrCreateKey( LocalKeyName = (PWSTR)KeyName; for (;;) { - End = (PWSTR) wcschr(LocalKeyName, '\\'); + End = (PWSTR) xwcschr(LocalKeyName, '\\'); if (End) { KeyString.Buffer = LocalKeyName; diff --git a/reactos/tools/mkhive/rtl.c b/reactos/tools/mkhive/rtl.c index 08cdeb71deb..ed6711dd075 100644 --- a/reactos/tools/mkhive/rtl.c +++ b/reactos/tools/mkhive/rtl.c @@ -11,6 +11,24 @@ #include #include +SIZE_T xwcslen( PWSTR String ) { + SIZE_T i; + + for( i = 0; String[i]; i++ ); + + return i; +} + +PWSTR xwcschr( PWSTR String, WCHAR Char ) +{ + SIZE_T i; + + for( i = 0; String[i] && String[i] != Char; i++ ); + + if( String[i] ) return &String[i]; + else return NULL; +} + /* * @implemented * @@ -54,7 +72,7 @@ RtlInitUnicodeString( if(SourceString) { - DestSize = wcslen(SourceString) * sizeof(WCHAR); + DestSize = xwcslen(SourceString) * sizeof(WCHAR); DestinationString->Length = (USHORT)DestSize; DestinationString->MaximumLength = (USHORT)DestSize + sizeof(WCHAR); } diff --git a/reactos/tools/widl/widl.mak b/reactos/tools/widl/widl.mak index a93263d4c8e..4407d163c3c 100644 --- a/reactos/tools/widl/widl.mak +++ b/reactos/tools/widl/widl.mak @@ -55,7 +55,7 @@ WIDL_OBJECTS = \ $(addprefix $(INTERMEDIATE_), $(WIDL_SOURCES:.c=.o)) WIDL_HOST_CFLAGS = $(TOOLS_CFLAGS) \ - -DINT16=SHORT -D__USE_W32API -DYYDEBUG=1 \ + -DINT16=SHORT -D__USE_W32API -DYYDEBUG=1 -D__REACTOS__=1 \ -I$(WIDL_BASE) -I$(WPP_BASE) \ -Iinclude/reactos/wine -Iinclude/reactos -Iinclude -Iinclude/psdk From 7bfdc5ceb794838986cba7be4cd8f2d0bcb8e563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 24 Sep 2006 06:25:49 +0000 Subject: [PATCH 318/488] Allow digits in computer name. http://www.reactos.org/bugzilla/show_bug.cgi?id=1806#c2 still needs to be checked See issue #1806 for more details. svn path=/trunk/; revision=24243 --- reactos/dll/win32/kernel32/misc/computername.c | 4 ++-- reactos/dll/win32/syssetup/wizard.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/computername.c b/reactos/dll/win32/kernel32/misc/computername.c index be065b96568..11351b91c37 100644 --- a/reactos/dll/win32/kernel32/misc/computername.c +++ b/reactos/dll/win32/kernel32/misc/computername.c @@ -298,7 +298,7 @@ IsValidComputerName ( p = (PWCHAR)lpComputerName; while (*p != 0) { - if (!(iswctype (*p, _ALPHA || _DIGIT) || + if ((!iswctype (*p, _ALPHA) && !iswctype (*p, _DIGIT)) || *p == L'!' || *p == L'@' || *p == L'#' || @@ -314,7 +314,7 @@ IsValidComputerName ( *p == L'_' || *p == L'{' || *p == L'}' || - *p == L'~')) + *p == L'~') return FALSE; Length++; diff --git a/reactos/dll/win32/syssetup/wizard.c b/reactos/dll/win32/syssetup/wizard.c index 4019a2870e6..fd72f546cc6 100644 --- a/reactos/dll/win32/syssetup/wizard.c +++ b/reactos/dll/win32/syssetup/wizard.c @@ -537,7 +537,7 @@ WriteComputerSettings(TCHAR * ComputerName, HWND hwndDlg) return FALSE; } - /* Try to also set DNS hostname */ + /* Try to also set DNS hostname */ SetComputerNameEx(ComputerNamePhysicalDnsHostname, ComputerName); return TRUE; @@ -612,7 +612,8 @@ ComputerPageDlgProc(HWND hwndDlg, return TRUE; } - /* FIXME: check computer name for invalid characters */ + /* No need to check computer name for invalid characters, + * SetComputerName() will do it for us */ if (!WriteComputerSettings(ComputerName, hwndDlg)) { From c32cdd8bfbc4e80bbe982a3dc675dad9a6154b88 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 07:30:43 +0000 Subject: [PATCH 319/488] revers 24232 for cause some other unknown regress. I need found a better way to solv the null termeting strings svn path=/trunk/; revision=24244 --- reactos/dll/win32/kernel32/misc/nls.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/nls.c b/reactos/dll/win32/kernel32/misc/nls.c index e355ff7accf..6da28161557 100644 --- a/reactos/dll/win32/kernel32/misc/nls.c +++ b/reactos/dll/win32/kernel32/misc/nls.c @@ -569,7 +569,7 @@ IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags, WideCharCount = MultiByteCount; SetLastError(ERROR_INSUFFICIENT_BUFFER); } - + for (TempLength = WideCharCount; TempLength > 0; WideCharString++, TempLength--) @@ -577,12 +577,6 @@ IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags, *MultiByteString++ = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]; } - if (WideCharCount>2) - { - MultiByteString--; - *MultiByteString = 0; - } - /* FIXME */ if (UsedDefaultChar != NULL) *UsedDefaultChar = FALSE; From 2abe11c82a856f32c2f1d5878086e3fc5638f30e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 24 Sep 2006 07:38:53 +0000 Subject: [PATCH 320/488] Revert r24233, which leads to have the header written too late in debug log and was preventing a crash during the first DbgPrint calls when using GDB Replace it by another fix (not tested) svn path=/trunk/; revision=24245 --- reactos/ntoskrnl/kd/kdinit.c | 1 - reactos/ntoskrnl/kd/kdio.c | 9 ++++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/reactos/ntoskrnl/kd/kdinit.c b/reactos/ntoskrnl/kd/kdinit.c index 52ee7f5992d..0cb5a8688a7 100644 --- a/reactos/ntoskrnl/kd/kdinit.c +++ b/reactos/ntoskrnl/kd/kdinit.c @@ -77,7 +77,6 @@ KdpGetWrapperDebugMode(PCHAR Currentp2, /* Get the KDBG Settings and enable it */ KdDebuggerEnabled = TRUE; KdDebuggerNotPresent = FALSE; - KdpDebugMode.Gdb = TRUE; KdbpGetCommandLineSettings((PCHAR)LoaderBlock->CommandLine); #endif return p2; diff --git a/reactos/ntoskrnl/kd/kdio.c b/reactos/ntoskrnl/kd/kdio.c index e8c638325aa..811d22f7a64 100644 --- a/reactos/ntoskrnl/kd/kdio.c +++ b/reactos/ntoskrnl/kd/kdio.c @@ -188,14 +188,13 @@ KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable, /* Register as a Provider */ InsertTailList(&KdProviders, &DispatchTable->KdProvidersList); + + /* Display separator + ReactOS version at start of the debug log */ + DPRINT1("---------------------------------------------------------------\n"); + DPRINT1("ReactOS "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n"); } else if (BootPhase == 2) { - /* Display separator + ReactOS version at start of the debug log */ - DbgPrint("---------------------------------------------------------------\n"); - DbgPrint("ReactOS "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n"); - DbgPrint("---------------------------------------------------------------\n"); - HalDisplayString("\n Serial debugging enabled\n\n"); } } From 7f9492fc2fe7d029d94dce376c97cf20b4b9a728 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 08:36:56 +0000 Subject: [PATCH 321/488] tested in dib16 Fixed all wine test for brush, zero fualt now passing all 32 test fine. gdi32 bitmap test only 7 fails now svn path=/trunk/; revision=24246 --- .../subsystems/win32/win32k/include/brush.h | 2 +- .../subsystems/win32/win32k/objects/bitmaps.c | 5 -- .../subsystems/win32/win32k/objects/brush.c | 56 +++++++++++++++++-- reactos/subsystems/win32/win32k/objects/dc.c | 2 +- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/brush.h b/reactos/subsystems/win32/win32k/include/brush.h index c1e854ab02a..e33e952fb90 100644 --- a/reactos/subsystems/win32/win32k/include/brush.h +++ b/reactos/subsystems/win32/win32k/include/brush.h @@ -73,7 +73,7 @@ typedef struct #define BRUSHOBJ_LockBrush(hBrush) ((PGDIBRUSHOBJ)GDIOBJ_LockObj(GdiHandleTable, (HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH)) #define BRUSHOBJ_UnlockBrush(pBrush) GDIOBJ_UnlockObjByPtr(GdiHandleTable, pBrush) -INT FASTCALL BRUSH_GetObject (PGDIBRUSHOBJ GdiObject, INT Count, BRUSHOBJ * Buffer); +INT FASTCALL BRUSH_GetObject (PGDIBRUSHOBJ GdiObject, INT Count, LPLOGBRUSH Buffer); BOOL INTERNAL_CALL BRUSH_Cleanup(PVOID ObjectBody); #endif diff --git a/reactos/subsystems/win32/win32k/objects/bitmaps.c b/reactos/subsystems/win32/win32k/objects/bitmaps.c index f2cd1180f35..2040b81297f 100644 --- a/reactos/subsystems/win32/win32k/objects/bitmaps.c +++ b/reactos/subsystems/win32/win32k/objects/bitmaps.c @@ -1071,10 +1071,6 @@ NtGdiSetPixel( DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); - if (((Color>>24) & 0xff)<0x10) - { - Color = ((Color>>16) & 0x0000ff) | ((Color<<16) & 0xff0000) | (Color & 0x00ff00); - } DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); @@ -1083,7 +1079,6 @@ NtGdiSetPixel( Color = NtGdiGetPixel(hDC,X,Y); DPRINT("1 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color); return Color; - } Color = ((COLORREF) -1); diff --git a/reactos/subsystems/win32/win32k/objects/brush.c b/reactos/subsystems/win32/win32k/objects/brush.c index c004116305d..4e74f8fc8f0 100644 --- a/reactos/subsystems/win32/win32k/objects/brush.c +++ b/reactos/subsystems/win32/win32k/objects/brush.c @@ -50,13 +50,61 @@ BRUSH_Cleanup(PVOID ObjectBody) } INT FASTCALL -BRUSH_GetObject (PGDIBRUSHOBJ BrushObj, INT Count, BRUSHOBJ * Buffer) +BRUSH_GetObject (PGDIBRUSHOBJ BrushObject, INT Count, LPLOGBRUSH Buffer) { if (Buffer) { - Buffer->iSolidColor = BrushObj->BrushAttr.lbColor; - Buffer->pvRbrush = BrushObj->ulRealization; - Buffer->flColorType = 0; + + /* Set colour */ + Buffer->lbColor = BrushObject->BrushAttr.lbColor; + + /* set Hatch */ + if ((BrushObject->flAttrs & GDIBRUSH_IS_HATCH)!=0) + { + /* FIXME : is this right value */ + Buffer->lbHatch = (LONG)BrushObject->hbmPattern; + } + else + { + Buffer->lbHatch = 0; + } + + Buffer->lbStyle = 0; + + /* Get the type of style */ + if ((BrushObject->flAttrs & GDIBRUSH_IS_SOLID)!=0) + { + Buffer->lbStyle = BS_SOLID; + } + else if ((BrushObject->flAttrs & GDIBRUSH_IS_NULL)!=0) + { + Buffer->lbStyle = BS_NULL; // BS_HOLLOW + } + else if ((BrushObject->flAttrs & GDIBRUSH_IS_HATCH)!=0) + { + Buffer->lbStyle = BS_HATCHED; + } + else if ((BrushObject->flAttrs & GDIBRUSH_IS_BITMAP)!=0) + { + Buffer->lbStyle = BS_PATTERN; + } + else if ((BrushObject->flAttrs & GDIBRUSH_IS_DIB)!=0) + { + Buffer->lbStyle = BS_DIBPATTERN; + } + + /* FIXME + else if ((BrushObject->flAttrs & )!=0) + { + Buffer->lbStyle = BS_INDEXED; + } + + else if ((BrushObject->flAttrs & )!=0) + { + Buffer->lbStyle = BS_DIBPATTERNPT; + } + */ + } return sizeof(BRUSHOBJ); } diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index 4fd4a2bf545..0f46955d9c0 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -1740,7 +1740,7 @@ IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer) break; #endif case GDI_OBJECT_TYPE_BRUSH: - Result = BRUSH_GetObject((PGDIBRUSHOBJ ) GdiObject, Count, (BRUSHOBJ *)Buffer); + Result = BRUSH_GetObject((PGDIBRUSHOBJ ) GdiObject, Count, (LPLOGBRUSH)Buffer); break; case GDI_OBJECT_TYPE_BITMAP: From 9f553707a1ff834d3e1dbedf881c1b95e0ee7d54 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 09:24:23 +0000 Subject: [PATCH 322/488] adding OBJ_COLORSPACE it was missing, need it soon svn path=/trunk/; revision=24247 --- reactos/include/psdk/wingdi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/include/psdk/wingdi.h b/reactos/include/psdk/wingdi.h index 823b0c69f1e..7d0bb2c2f95 100644 --- a/reactos/include/psdk/wingdi.h +++ b/reactos/include/psdk/wingdi.h @@ -614,6 +614,7 @@ extern "C" { #define OBJ_METADC 4 #define OBJ_ENHMETAFILE 13 #define OBJ_ENHMETADC 12 +#define OBJ_COLORSPACE 14 #define DRIVERVERSION 0 #define TECHNOLOGY 2 #define DT_PLOTTER 0 From 9e99515740e5f09b88b44c1d32ee3720c931b5d7 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 09:41:28 +0000 Subject: [PATCH 323/488] adding two more missing define svn path=/trunk/; revision=24248 --- reactos/include/psdk/wingdi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/include/psdk/wingdi.h b/reactos/include/psdk/wingdi.h index 7d0bb2c2f95..e3430bcbf6a 100644 --- a/reactos/include/psdk/wingdi.h +++ b/reactos/include/psdk/wingdi.h @@ -934,6 +934,8 @@ extern "C" { #define SP_NOTREPORTED 0x4000 #define PR_JOBSTATUS 0 #define ASPECT_FILTERING 1 +#define GS_8BIT_INDICES 0x00000001 +#define GGI_MARK_NONEXISTING_GLYPHS 0X0001 #define BS_SOLID 0 #define BS_NULL 1 #define BS_HOLLOW 1 From 595ffab5960845ce1e57197a92899a803db1ec96 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 09:43:16 +0000 Subject: [PATCH 324/488] Update some gdi32 winetest svn path=/trunk/; revision=24249 --- reactos/regtests/winetests/gdi32/bitmap.c | 885 ++++++++++++++- reactos/regtests/winetests/gdi32/brush.c | 4 +- reactos/regtests/winetests/gdi32/clipping.c | 125 ++ reactos/regtests/winetests/gdi32/dc.c | 180 +++ reactos/regtests/winetests/gdi32/font.c | 441 ++++++++ reactos/regtests/winetests/gdi32/gdi32.rbuild | 3 + reactos/regtests/winetests/gdi32/gdiobj.c | 381 +++---- reactos/regtests/winetests/gdi32/metafile.c | 1005 ++++++++++++++++- reactos/regtests/winetests/gdi32/testlist.c | 6 +- 9 files changed, 2747 insertions(+), 283 deletions(-) create mode 100644 reactos/regtests/winetests/gdi32/clipping.c create mode 100644 reactos/regtests/winetests/gdi32/dc.c create mode 100644 reactos/regtests/winetests/gdi32/font.c diff --git a/reactos/regtests/winetests/gdi32/bitmap.c b/reactos/regtests/winetests/gdi32/bitmap.c index dbbb81b8068..62a57ebf2da 100755 --- a/reactos/regtests/winetests/gdi32/bitmap.c +++ b/reactos/regtests/winetests/gdi32/bitmap.c @@ -2,6 +2,7 @@ * Unit test suite for bitmaps * * Copyright 2004 Huw Davies + * Copyright 2006 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -15,11 +16,12 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include +#include #include "windef.h" #include "winbase.h" @@ -31,11 +33,88 @@ static BOOL is_win9x; +static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp ) +{ + 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: + trace("Unknown depth %d, please report.\n", bpp ); + assert(0); + } + return -1; +} + +static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih) +{ + BITMAP bm; + INT ret, width_bytes; + char buf[512], buf_cmp[512]; + + ret = GetObject(hbm, sizeof(bm), &bm); + ok(ret == sizeof(bm), "GetObject returned %d\n", ret); + + ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType); + ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth); + ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight); + width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel); + ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes); + ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes); + ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth); + ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits); + + assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight); + assert(sizeof(buf) == sizeof(buf_cmp)); + + ret = GetBitmapBits(hbm, 0, NULL); + ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); + + memset(buf_cmp, 0xAA, sizeof(buf_cmp)); + memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight); + + memset(buf, 0xAA, sizeof(buf)); + ret = GetBitmapBits(hbm, sizeof(buf), buf); + ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); + ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n"); + + /* test various buffer sizes for GetObject */ + ret = GetObject(hbm, 0, NULL); + ok(ret == sizeof(bm), "wrong size %d\n", ret); + + ret = GetObject(hbm, sizeof(bm) * 2, &bm); + ok(ret == sizeof(bm), "wrong size %d\n", ret); + + ret = GetObject(hbm, sizeof(bm) / 2, &bm); + ok(ret == 0, "%d != 0\n", ret); + + ret = GetObject(hbm, 0, &bm); + ok(ret == 0, "%d != 0\n", ret); + + ret = GetObject(hbm, 1, &bm); + ok(ret == 0, "%d != 0\n", ret); +} + static void test_createdibitmap(void) { HDC hdc, hdcmem; BITMAPINFOHEADER bmih; - BITMAP bm; HBITMAP hbm, hbm_colour, hbm_old; INT screen_depth; @@ -56,27 +135,21 @@ static void test_createdibitmap(void) /* First try 32 bits */ hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + test_bitmap_info(hbm, screen_depth, &bmih); DeleteObject(hbm); /* Then 16 */ bmih.biBitCount = 16; hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + test_bitmap_info(hbm, screen_depth, &bmih); DeleteObject(hbm); /* Then 1 */ bmih.biBitCount = 1; hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + test_bitmap_info(hbm, screen_depth, &bmih); DeleteObject(hbm); /* Now with a monochrome dc we expect a monochrome bitmap */ @@ -86,27 +159,21 @@ static void test_createdibitmap(void) bmih.biBitCount = 32; hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + test_bitmap_info(hbm, 1, &bmih); DeleteObject(hbm); /* Then 16 */ bmih.biBitCount = 16; hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + test_bitmap_info(hbm, 1, &bmih); DeleteObject(hbm); /* Then 1 */ bmih.biBitCount = 1; hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + test_bitmap_info(hbm, 1, &bmih); DeleteObject(hbm); /* Now select a polychrome bitmap into the dc and we expect @@ -118,27 +185,21 @@ static void test_createdibitmap(void) bmih.biBitCount = 32; hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + test_bitmap_info(hbm, screen_depth, &bmih); DeleteObject(hbm); /* Then 16 */ bmih.biBitCount = 16; hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + test_bitmap_info(hbm, screen_depth, &bmih); DeleteObject(hbm); /* Then 1 */ bmih.biBitCount = 1; hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + test_bitmap_info(hbm, screen_depth, &bmih); DeleteObject(hbm); SelectObject(hdcmem, hbm_old); @@ -150,15 +211,124 @@ static void test_createdibitmap(void) bmih.biBitCount = 32; hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0); ok(hbm != NULL, "CreateDIBitmap failed\n"); - ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); - - ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + test_bitmap_info(hbm, 1, &bmih); DeleteObject(hbm); } ReleaseDC(0, hdc); } +static INT DIB_GetWidthBytes( int width, int bpp ) +{ + int words; + + switch (bpp) + { + case 1: words = (width + 31) / 32; break; + case 4: words = (width + 7) / 8; break; + case 8: words = (width + 3) / 4; break; + case 15: + case 16: words = (width + 1) / 2; break; + case 24: words = (width * 3 + 3)/4; break; + case 32: words = width; break; + + default: + words=0; + trace("Unknown depth %d, please report.\n", bpp ); + assert(0); + break; + } + return 4 * words; +} + +static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih) +{ + BITMAP bm; + DIBSECTION ds; + INT ret, width_bytes; + BYTE *buf; + + ret = GetObject(hbm, sizeof(bm), &bm); + ok(ret == sizeof(bm), "GetObject returned %d\n", ret); + + ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType); + ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth); + ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight); + width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel); + ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes); + ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes); + ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount); + ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits); + + buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096); + + width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel); + + /* GetBitmapBits returns not 32-bit aligned data */ + ret = GetBitmapBits(hbm, 0, NULL); + ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight); + + memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096); + ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf); + ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight); + + HeapFree(GetProcessHeap(), 0, buf); + + /* test various buffer sizes for GetObject */ + memset(&ds, 0xAA, sizeof(ds)); + ret = GetObject(hbm, sizeof(bm) * 2, &bm); + ok(ret == sizeof(bm), "wrong size %d\n", ret); + ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth); + ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight); + ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits); + + ret = GetObject(hbm, sizeof(bm) / 2, &bm); + ok(ret == 0, "%d != 0\n", ret); + + ret = GetObject(hbm, 0, &bm); + ok(ret == 0, "%d != 0\n", ret); + + ret = GetObject(hbm, 1, &bm); + ok(ret == 0, "%d != 0\n", ret); + + /* test various buffer sizes for GetObject */ + ret = GetObject(hbm, 0, NULL); + ok(ret == sizeof(bm), "wrong size %d\n", ret); + + memset(&ds, 0xAA, sizeof(ds)); + ret = GetObject(hbm, sizeof(ds) * 2, &ds); + ok(ret == sizeof(ds), "wrong size %d\n", ret); + + ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits); + ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%lu != %u\n", + ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight); + ok(bmih->biSizeImage == 0, "%lu != 0\n", bmih->biSizeImage); + ds.dsBmih.biSizeImage = 0; + + ok(ds.dsBmih.biSize == bmih->biSize, "%lu != %lu\n", ds.dsBmih.biSize, bmih->biSize); + ok(ds.dsBmih.biWidth == bmih->biWidth, "%lu != %lu\n", ds.dsBmih.biWidth, bmih->biWidth); + ok(ds.dsBmih.biHeight == bmih->biHeight, "%lu != %lu\n", ds.dsBmih.biHeight, bmih->biHeight); + ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes); + ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount); + ok(ds.dsBmih.biCompression == bmih->biCompression, "%lu != %lu\n", ds.dsBmih.biCompression, bmih->biCompression); + ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%lu != %lu\n", ds.dsBmih.biSizeImage, bmih->biSizeImage); + ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%lu != %lu\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter); + ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%lu != %lu\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter); + + memset(&ds, 0xAA, sizeof(ds)); + ret = GetObject(hbm, sizeof(ds) - 4, &ds); + ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret); + ok(ds.dsBm.bmWidth == bmih->biWidth, "%lu != %lu\n", ds.dsBmih.biWidth, bmih->biWidth); + ok(ds.dsBm.bmHeight == bmih->biHeight, "%lu != %lu\n", ds.dsBmih.biHeight, bmih->biHeight); + ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits); + + ret = GetObject(hbm, 0, &ds); + ok(ret == 0, "%d != 0\n", ret); + + ret = GetObject(hbm, 1, &ds); + ok(ret == 0, "%d != 0\n", ret); +} + #define test_color_todo(got, exp, txt, todo) \ if (!todo && got != exp && screen_depth < 24) { \ todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \ @@ -194,12 +364,73 @@ static void test_dibsections(void) WORD *index; DWORD *bits32; HPALETTE hpal, oldpal; + DIBSECTION dibsec; COLORREF c0, c1; int i; int screen_depth; + MEMORY_BASIC_INFORMATION info; hdc = GetDC(0); screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES); + + memset(pbmi, 0, sizeof(bmibuf)); + pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader); + pbmi->bmiHeader.biHeight = 100; + pbmi->bmiHeader.biWidth = 512; + pbmi->bmiHeader.biBitCount = 24; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biCompression = BI_RGB; + + SetLastError(0xdeadbeef); + hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok(hdib != NULL, "CreateDIBSection error %ld\n", GetLastError()); + ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n"); + ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits); + + /* test the DIB memory */ + ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info), + "VirtualQuery failed\n"); + ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits); + ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits); + ok(info.AllocationProtect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.AllocationProtect); + ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize); + ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State); + ok(info.Protect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.Protect); + ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type); + + test_dib_info(hdib, bits, &pbmi->bmiHeader); + DeleteObject(hdib); + + pbmi->bmiHeader.biBitCount = 8; + pbmi->bmiHeader.biCompression = BI_RLE8; + SetLastError(0xdeadbeef); + hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n"); + ok(GetLastError() == 0xdeadbeef, "wrong error %ld\n", GetLastError()); + + pbmi->bmiHeader.biBitCount = 16; + pbmi->bmiHeader.biCompression = BI_BITFIELDS; + ((PDWORD)pbmi->bmiColors)[0] = 0xf800; + ((PDWORD)pbmi->bmiColors)[1] = 0x07e0; + ((PDWORD)pbmi->bmiColors)[2] = 0x001f; + SetLastError(0xdeadbeef); + hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok(hdib != NULL, "CreateDIBSection error %ld\n", GetLastError()); + + /* test the DIB memory */ + ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info), + "VirtualQuery failed\n"); + ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits); + ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits); + ok(info.AllocationProtect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.AllocationProtect); + ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize); + ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State); + ok(info.Protect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.Protect); + ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type); + + test_dib_info(hdib, bits, &pbmi->bmiHeader); + DeleteObject(hdib); + memset(pbmi, 0, sizeof(bmibuf)); pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader); pbmi->bmiHeader.biHeight = 16; @@ -216,6 +447,9 @@ static void test_dibsections(void) hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); ok(hdib != NULL, "CreateDIBSection failed\n"); + ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n"); + ok(dibsec.dsBmih.biClrUsed == 2, + "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 2); /* Test if the old BITMAPCOREINFO structure is supported */ @@ -280,6 +514,45 @@ static void test_dibsections(void) SelectObject(hdcmem, oldbm); DeleteObject(hdib); + pbmi->bmiColors[0].rgbRed = 0xff; + pbmi->bmiColors[0].rgbGreen = 0xff; + pbmi->bmiColors[0].rgbBlue = 0xff; + pbmi->bmiColors[1].rgbRed = 0; + pbmi->bmiColors[1].rgbGreen = 0; + pbmi->bmiColors[1].rgbBlue = 0; + + hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok(hdib != NULL, "CreateDIBSection failed\n"); + + test_dib_info(hdib, bits, &pbmi->bmiHeader); + + oldbm = SelectObject(hdcmem, hdib); + + ret = GetDIBColorTable(hdcmem, 0, 2, rgb); + ok(ret == 2, "GetDIBColorTable returned %d\n", ret); + ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)), + "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n", + rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved, + rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved); + + SelectObject(hdcmem, oldbm); + test_dib_info(hdib, bits, &pbmi->bmiHeader); + DeleteObject(hdib); + + pbmi->bmiHeader.biBitCount = 4; + for (i = 0; i < 16; i++) { + pbmi->bmiColors[i].rgbRed = i; + pbmi->bmiColors[i].rgbGreen = 16-i; + pbmi->bmiColors[i].rgbBlue = 0; + } + hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok(hdib != NULL, "CreateDIBSection failed\n"); + ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); + ok(dibsec.dsBmih.biClrUsed == 16, + "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 16); + test_dib_info(hdib, bits, &pbmi->bmiHeader); + DeleteObject(hdib); + pbmi->bmiHeader.biBitCount = 8; for (i = 0; i < 128; i++) { @@ -292,6 +565,10 @@ static void test_dibsections(void) } hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); ok(hdib != NULL, "CreateDIBSection failed\n"); + ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); + ok(dibsec.dsBmih.biClrUsed == 256, + "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 256); + oldbm = SelectObject(hdcmem, hdib); for (i = 0; i < 256; i++) { @@ -302,6 +579,7 @@ static void test_dibsections(void) } SelectObject(hdcmem, oldbm); + test_dib_info(hdib, bits, &pbmi->bmiHeader); DeleteObject(hdib); pbmi->bmiHeader.biBitCount = 1; @@ -322,6 +600,9 @@ static void test_dibsections(void) oldpal = SelectPalette(hdc, hpal, TRUE); hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); ok(hdib != NULL, "CreateDIBSection failed\n"); + ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); + ok(dibsec.dsBmih.biClrUsed == 2, + "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 2); /* The colour table has already been grabbed from the dc, so we select back the old palette */ @@ -362,6 +643,7 @@ static void test_dibsections(void) bits[0] = bits[1] = 0xff; bits[13 * 4] = bits[13*4 + 1] = 0xff; + test_dib_info(hdib, bits, &pbmi->bmiHeader); pbmi->bmiHeader.biBitCount = 32; @@ -376,6 +658,7 @@ static void test_dibsections(void) ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08lx\n", bits32[17]); SelectObject(hdcmem2, oldbm2); + test_dib_info(hdib2, bits32, &pbmi->bmiHeader); DeleteObject(hdib2); SelectObject(hdcmem, oldbm); @@ -409,6 +692,11 @@ static void test_dibsections(void) oldpal = SelectPalette(hdc, hpal, TRUE); hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); ok(hdib != NULL, "CreateDIBSection failed\n"); + ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); + ok(dibsec.dsBmih.biClrUsed == 256, + "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 256); + + test_dib_info(hdib, bits, &pbmi->bmiHeader); SelectPalette(hdc, oldpal, TRUE); oldbm = SelectObject(hdcmem, hdib); @@ -443,17 +731,534 @@ static void test_dibsections(void) ReleaseDC(0, hdc); } +void test_mono_dibsection(void) +{ + HDC hdc, memdc; + HBITMAP old_bm, mono_ds; + char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)]; + BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf; + BYTE bits[10 * 4]; + BYTE *ds_bits; + int num; + + hdc = GetDC(0); + + memdc = CreateCompatibleDC(hdc); + + memset(pbmi, 0, sizeof(bmibuf)); + pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader); + pbmi->bmiHeader.biHeight = 10; + pbmi->bmiHeader.biWidth = 10; + pbmi->bmiHeader.biBitCount = 1; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiColors[0].rgbRed = 0xff; + pbmi->bmiColors[0].rgbGreen = 0xff; + pbmi->bmiColors[0].rgbBlue = 0xff; + pbmi->bmiColors[1].rgbRed = 0x0; + pbmi->bmiColors[1].rgbGreen = 0x0; + pbmi->bmiColors[1].rgbBlue = 0x0; + + /* + * First dib section is 'inverted' ie color[0] is white, color[1] is black + */ + + mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0); + ok(mono_ds != NULL, "CreateDIBSection rets NULL\n"); + old_bm = SelectObject(memdc, mono_ds); + + /* black border, white interior */ + Rectangle(memdc, 0, 0, 10, 10); + ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]); + ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]); + + /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */ + + memset(bits, 0, sizeof(bits)); + bits[0] = 0xaa; + + SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); + ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]); + + /* SetDIBitsToDevice with a normal bmi -> inverted dib section */ + + pbmi->bmiColors[0].rgbRed = 0x0; + pbmi->bmiColors[0].rgbGreen = 0x0; + pbmi->bmiColors[0].rgbBlue = 0x0; + pbmi->bmiColors[1].rgbRed = 0xff; + pbmi->bmiColors[1].rgbGreen = 0xff; + pbmi->bmiColors[1].rgbBlue = 0xff; + + SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); + ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]); + + SelectObject(memdc, old_bm); + DeleteObject(mono_ds); + + /* + * Next dib section is 'normal' ie color[0] is black, color[1] is white + */ + + pbmi->bmiColors[0].rgbRed = 0x0; + pbmi->bmiColors[0].rgbGreen = 0x0; + pbmi->bmiColors[0].rgbBlue = 0x0; + pbmi->bmiColors[1].rgbRed = 0xff; + pbmi->bmiColors[1].rgbGreen = 0xff; + pbmi->bmiColors[1].rgbBlue = 0xff; + + mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0); + ok(mono_ds != NULL, "CreateDIBSection rets NULL\n"); + old_bm = SelectObject(memdc, mono_ds); + + /* black border, white interior */ + Rectangle(memdc, 0, 0, 10, 10); + ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]); + ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]); + + /* SetDIBitsToDevice with a normal bmi -> normal dib section */ + + SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); + ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]); + + /* SetDIBitsToDevice with a inverted bmi -> normal dib section */ + + pbmi->bmiColors[0].rgbRed = 0xff; + pbmi->bmiColors[0].rgbGreen = 0xff; + pbmi->bmiColors[0].rgbBlue = 0xff; + pbmi->bmiColors[1].rgbRed = 0x0; + pbmi->bmiColors[1].rgbGreen = 0x0; + pbmi->bmiColors[1].rgbBlue = 0x0; + + SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); + ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]); + + /* + * Take that 'normal' dibsection and change its colour table to an 'inverted' one + */ + + pbmi->bmiColors[0].rgbRed = 0xff; + pbmi->bmiColors[0].rgbGreen = 0xff; + pbmi->bmiColors[0].rgbBlue = 0xff; + pbmi->bmiColors[1].rgbRed = 0x0; + pbmi->bmiColors[1].rgbGreen = 0x0; + pbmi->bmiColors[1].rgbBlue = 0x0; + num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors); + ok(num == 2, "num = %d\n", num); + + /* black border, white interior */ + Rectangle(memdc, 0, 0, 10, 10); +todo_wine { + ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]); + ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]); + } + /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */ + + memset(bits, 0, sizeof(bits)); + bits[0] = 0xaa; + + SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); + ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]); + + /* SetDIBitsToDevice with a normal bmi -> inverted dib section */ + + pbmi->bmiColors[0].rgbRed = 0x0; + pbmi->bmiColors[0].rgbGreen = 0x0; + pbmi->bmiColors[0].rgbBlue = 0x0; + pbmi->bmiColors[1].rgbRed = 0xff; + pbmi->bmiColors[1].rgbGreen = 0xff; + pbmi->bmiColors[1].rgbBlue = 0xff; + + SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); + ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]); + + SelectObject(memdc, old_bm); + DeleteObject(mono_ds); + + /* + * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one. + */ + + pbmi->bmiColors[0].rgbRed = 0xff; + pbmi->bmiColors[0].rgbGreen = 0x0; + pbmi->bmiColors[0].rgbBlue = 0x0; + pbmi->bmiColors[1].rgbRed = 0xfe; + pbmi->bmiColors[1].rgbGreen = 0x0; + pbmi->bmiColors[1].rgbBlue = 0x0; + + mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0); + ok(mono_ds != NULL, "CreateDIBSection rets NULL\n"); + old_bm = SelectObject(memdc, mono_ds); + + /* black border, white interior */ + Rectangle(memdc, 0, 0, 10, 10); + ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]); + ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]); + + /* SetDIBitsToDevice with a normal bmi -> inverted dib section */ + + pbmi->bmiColors[0].rgbRed = 0x0; + pbmi->bmiColors[0].rgbGreen = 0x0; + pbmi->bmiColors[0].rgbBlue = 0x0; + pbmi->bmiColors[1].rgbRed = 0xff; + pbmi->bmiColors[1].rgbGreen = 0xff; + pbmi->bmiColors[1].rgbBlue = 0xff; + + SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); + ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]); + + /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */ + + pbmi->bmiColors[0].rgbRed = 0xff; + pbmi->bmiColors[0].rgbGreen = 0xff; + pbmi->bmiColors[0].rgbBlue = 0xff; + pbmi->bmiColors[1].rgbRed = 0x0; + pbmi->bmiColors[1].rgbGreen = 0x0; + pbmi->bmiColors[1].rgbBlue = 0x0; + + SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); + ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]); + + SelectObject(memdc, old_bm); + DeleteObject(mono_ds); + + DeleteDC(memdc); + ReleaseDC(0, hdc); +} + +static void test_bitmap(void) +{ + char buf[256], buf_cmp[256]; + HBITMAP hbmp, hbmp_old; + HDC hdc; + BITMAP bm; + INT ret; + + hdc = CreateCompatibleDC(0); + assert(hdc != 0); + + hbmp = CreateBitmap(15, 15, 1, 1, NULL); + assert(hbmp != NULL); + + ret = GetObject(hbmp, sizeof(bm), &bm); + ok(ret == sizeof(bm), "wrong size %d\n", ret); + + ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType); + ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth); + ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight); + ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes); + ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes); + ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel); + ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits); + + assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight); + assert(sizeof(buf) == sizeof(buf_cmp)); + + ret = GetBitmapBits(hbmp, 0, NULL); + ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); + + memset(buf_cmp, 0xAA, sizeof(buf_cmp)); + memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight); + + memset(buf, 0xAA, sizeof(buf)); + ret = GetBitmapBits(hbmp, sizeof(buf), buf); + ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); + ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n"); + + hbmp_old = SelectObject(hdc, hbmp); + + ret = GetObject(hbmp, sizeof(bm), &bm); + ok(ret == sizeof(bm), "wrong size %d\n", ret); + + ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType); + ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth); + ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight); + ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes); + ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes); + ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel); + ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits); + + memset(buf, 0xAA, sizeof(buf)); + ret = GetBitmapBits(hbmp, sizeof(buf), buf); + ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); + ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n"); + + hbmp_old = SelectObject(hdc, hbmp_old); + ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old); + + /* test various buffer sizes for GetObject */ + ret = GetObject(hbmp, sizeof(bm) * 2, &bm); + ok(ret == sizeof(bm), "wrong size %d\n", ret); + + ret = GetObject(hbmp, sizeof(bm) / 2, &bm); + ok(ret == 0, "%d != 0\n", ret); + + ret = GetObject(hbmp, 0, &bm); + ok(ret == 0, "%d != 0\n", ret); + + ret = GetObject(hbmp, 1, &bm); + ok(ret == 0, "%d != 0\n", ret); + + DeleteObject(hbmp); + DeleteDC(hdc); +} + +static void test_bmBits(void) +{ + BYTE bits[4]; + HBITMAP hbmp; + BITMAP bmp; + + memset(bits, 0, sizeof(bits)); + hbmp = CreateBitmap(2, 2, 1, 4, bits); + ok(hbmp != NULL, "CreateBitmap failed\n"); + + memset(&bmp, 0xFF, sizeof(bmp)); + ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp), + "GetObject failed or returned a wrong structure size\n"); + ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n"); + + DeleteObject(hbmp); +} + +static void test_GetDIBits_selected_DIB(UINT bpp) +{ + HBITMAP dib; + BITMAPINFO * info; + BITMAPINFO * info2; + void * bits; + void * bits2; + UINT dib_size; + HDC dib_dc, dc; + HBITMAP old_bmp; + BOOL equalContents; + UINT i; + int res; + + /* Create a DIB section with a color table */ + + info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD)); + info2 = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD)); + assert(info); + assert(info2); + + info->bmiHeader.biSize = sizeof(info->bmiHeader); + + /* Choose width and height such that the row length (in bytes) + is a multiple of 4 (makes things easier) */ + info->bmiHeader.biWidth = 32; + info->bmiHeader.biHeight = 32; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = bpp; + info->bmiHeader.biCompression = BI_RGB; + + for (i=0; i < (1 << bpp); i++) + { + BYTE c = i * (1 << (8 - bpp)); + info->bmiColors[i].rgbRed = c; + info->bmiColors[i].rgbGreen = c; + info->bmiColors[i].rgbBlue = c; + info->bmiColors[i].rgbReserved = 0; + } + + dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0); + assert(dib); + dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8; + + /* Set the bits of the DIB section */ + for (i=0; i < dib_size; i++) + { + ((BYTE *)bits)[i] = i % 256; + } + + /* Select the DIB into a DC */ + dib_dc = CreateCompatibleDC(NULL); + old_bmp = (HBITMAP) SelectObject(dib_dc, dib); + dc = CreateCompatibleDC(NULL); + bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size); + assert(bits2); + + /* Copy the DIB attributes but not the color table */ + memcpy(info2, info, sizeof(BITMAPINFOHEADER)); + + res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS); + ok(res, "GetDIBits failed\n"); + + /* Compare the color table and the bits */ + equalContents = TRUE; + for (i=0; i < (1 << bpp); i++) + { + if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed) + || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen) + || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue) + || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved)) + { + equalContents = FALSE; + break; + } + } + todo_wine + { + ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n"); + } + + equalContents = TRUE; + for (i=0; i < dib_size / sizeof(DWORD); i++) + { + if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i]) + { + equalContents = FALSE; + break; + } + } + todo_wine + { + ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB bits\n"); + } + + HeapFree(GetProcessHeap(), 0, bits2); + DeleteDC(dc); + + SelectObject(dib_dc, old_bmp); + DeleteDC(dib_dc); + DeleteObject(dib); + + HeapFree(GetProcessHeap(), 0, info2); + HeapFree(GetProcessHeap(), 0, info); +} + +static void test_GetDIBits_selected_DDB(BOOL monochrome) +{ + HBITMAP ddb; + BITMAPINFO * info; + BITMAPINFO * info2; + void * bits; + void * bits2; + HDC ddb_dc, dc; + HBITMAP old_bmp; + BOOL equalContents; + UINT width, height; + UINT bpp; + UINT i, j; + int res; + + width = height = 16; + + /* Create a DDB (device-dependent bitmap) */ + if (monochrome) + { + bpp = 1; + ddb = CreateBitmap(width, height, 1, 1, NULL); + } + else + { + HDC screen_dc = GetDC(NULL); + bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES); + ddb = CreateCompatibleBitmap(screen_dc, width, height); + ReleaseDC(NULL, screen_dc); + } + + /* Set the pixels */ + ddb_dc = CreateCompatibleDC(NULL); + old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb); + for (i = 0; i < width; i++) + { + for (j=0; j < height; j++) + { + BYTE c = (i * width + j) % 256; + SetPixelV(ddb_dc, i, j, RGB(c, c, c)); + } + } + SelectObject(ddb_dc, old_bmp); + + info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); + info2 = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); + assert(info); + assert(info2); + + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biWidth = width; + info->bmiHeader.biHeight = height; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = bpp; + info->bmiHeader.biCompression = BI_RGB; + + dc = CreateCompatibleDC(NULL); + + /* Fill in biSizeImage */ + GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS); + ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n"); + + bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage); + bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage); + assert(bits); + assert(bits2); + + /* Get the bits */ + res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS); + ok(res, "GetDIBits failed\n"); + + /* Copy the DIB attributes but not the color table */ + memcpy(info2, info, sizeof(BITMAPINFOHEADER)); + + /* Select the DDB into another DC */ + old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb); + + /* Get the bits */ + res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS); + ok(res, "GetDIBits failed\n"); + + /* Compare the color table and the bits */ + if (bpp <= 8) + { + equalContents = TRUE; + for (i=0; i < (1 << bpp); i++) + { + if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed) + || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen) + || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue) + || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved)) + { + equalContents = FALSE; + break; + } + } + ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n"); + } + + equalContents = TRUE; + for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++) + { + if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i]) + { + equalContents = FALSE; + } + } + ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n"); + + HeapFree(GetProcessHeap(), 0, bits2); + HeapFree(GetProcessHeap(), 0, bits); + DeleteDC(dc); + + SelectObject(ddb_dc, old_bmp); + DeleteDC(ddb_dc); + DeleteObject(ddb); + + HeapFree(GetProcessHeap(), 0, info2); + HeapFree(GetProcessHeap(), 0, info); +} + START_TEST(bitmap) { - HWND hWnd; - - hWnd = CreateWindowExA(0, "EDIT", NULL, 0, - 10, 10, 300, 300, - NULL, NULL, NULL, NULL); - assert(hWnd); - is_win9x = GetWindowLongW(hWnd, GWL_WNDPROC) == 0; - DestroyWindow(hWnd); + is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0; test_createdibitmap(); test_dibsections(); + test_mono_dibsection(); + test_bitmap(); + test_bmBits(); + test_GetDIBits_selected_DIB(1); + test_GetDIBits_selected_DIB(4); + test_GetDIBits_selected_DIB(8); + test_GetDIBits_selected_DDB(TRUE); + test_GetDIBits_selected_DDB(FALSE); } diff --git a/reactos/regtests/winetests/gdi32/brush.c b/reactos/regtests/winetests/gdi32/brush.c index f4e22b6b30d..c2aee7c138e 100755 --- a/reactos/regtests/winetests/gdi32/brush.c +++ b/reactos/regtests/winetests/gdi32/brush.c @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -56,7 +56,7 @@ static void test_solidbrush(void) } else stockBrush = NULL; - memset(&br, sizeof(br), 0); + memset(&br, 0, sizeof(br)); ret = GetObject(solidBrush, sizeof(br), &br); ok( ret !=0, "GetObject on solid %s brush failed, error=%ld\n", stock[i].name, GetLastError()); ok(br.lbStyle==BS_SOLID, "%s brush has wrong style, got %d expected %d\n", stock[i].name, br.lbStyle, BS_SOLID); diff --git a/reactos/regtests/winetests/gdi32/clipping.c b/reactos/regtests/winetests/gdi32/clipping.c new file mode 100644 index 00000000000..079fbcc804c --- /dev/null +++ b/reactos/regtests/winetests/gdi32/clipping.c @@ -0,0 +1,125 @@ +/* + * Unit test suite for clipping + * + * Copyright 2005 Huw Davies + * + * 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 "wine/test.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +static void test_GetRandomRgn(void) +{ + HWND hwnd = CreateWindowExA(0,"BUTTON","test",WS_VISIBLE|WS_POPUP,0,0,100,100,GetDesktopWindow(),0,0,0); + HDC hdc; + HRGN hrgn = CreateRectRgn(0, 0, 0, 0); + int ret; + RECT rc, rc2; + RECT ret_rc, window_rc; + + ok( hwnd != 0, "CreateWindow failed\n" ); + + SetRect(&window_rc, 400, 300, 500, 400); + MoveWindow(hwnd, window_rc.left, window_rc.top, window_rc.right - window_rc.left, window_rc.bottom - window_rc.top, FALSE); + hdc = GetDC(hwnd); + + ret = GetRandomRgn(hdc, hrgn, 1); + ok(ret == 0, "GetRandomRgn rets %d\n", ret); + ret = GetRandomRgn(hdc, hrgn, 2); + ok(ret == 0, "GetRandomRgn rets %d\n", ret); + ret = GetRandomRgn(hdc, hrgn, 3); + ok(ret == 0, "GetRandomRgn rets %d\n", ret); + + /* Set a clip region */ + SetRect(&rc, 20, 20, 80, 80); + IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom); + + ret = GetRandomRgn(hdc, hrgn, 1); + ok(ret != 0, "GetRandomRgn rets %d\n", ret); + GetRgnBox(hrgn, &ret_rc); + ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %ld,%ld - %ld,%ld\n", + ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); + + ret = GetRandomRgn(hdc, hrgn, 2); + ok(ret == 0, "GetRandomRgn rets %d\n", ret); + + ret = GetRandomRgn(hdc, hrgn, 3); + ok(ret != 0, "GetRandomRgn rets %d\n", ret); + GetRgnBox(hrgn, &ret_rc); + ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %ld,%ld - %ld,%ld\n", + ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); + + /* Move the clip to the meta and clear the clip */ + SetMetaRgn(hdc); + + ret = GetRandomRgn(hdc, hrgn, 1); + ok(ret == 0, "GetRandomRgn rets %d\n", ret); + ret = GetRandomRgn(hdc, hrgn, 2); + ok(ret != 0, "GetRandomRgn rets %d\n", ret); + GetRgnBox(hrgn, &ret_rc); + ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %ld,%ld - %ld,%ld\n", + ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); + + ret = GetRandomRgn(hdc, hrgn, 3); + ok(ret != 0, "GetRandomRgn rets %d\n", ret); + GetRgnBox(hrgn, &ret_rc); + ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %ld,%ld - %ld,%ld\n", + ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); + + /* Set a new clip (still got the meta) */ + SetRect(&rc2, 10, 30, 70, 90); + IntersectClipRect(hdc, rc2.left, rc2.top, rc2.right, rc2.bottom); + + ret = GetRandomRgn(hdc, hrgn, 1); + ok(ret != 0, "GetRandomRgn rets %d\n", ret); + GetRgnBox(hrgn, &ret_rc); + ok(EqualRect(&rc2, &ret_rc), "GetRandomRgn %ld,%ld - %ld,%ld\n", + ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); + + ret = GetRandomRgn(hdc, hrgn, 2); + ok(ret != 0, "GetRandomRgn rets %d\n", ret); + GetRgnBox(hrgn, &ret_rc); + ok(EqualRect(&rc, &ret_rc), "GetRandomRgn %ld,%ld - %ld,%ld\n", + ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); + + IntersectRect(&rc2, &rc, &rc2); + + ret = GetRandomRgn(hdc, hrgn, 3); + ok(ret != 0, "GetRandomRgn rets %d\n", ret); + GetRgnBox(hrgn, &ret_rc); + ok(EqualRect(&rc2, &ret_rc), "GetRandomRgn %ld,%ld - %ld,%ld\n", + ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); + + + ret = GetRandomRgn(hdc, hrgn, SYSRGN); + ok(ret != 0, "GetRandomRgn rets %d\n", ret); + GetRgnBox(hrgn, &ret_rc); + if(GetVersion() & 0x80000000) + OffsetRect(&window_rc, -window_rc.left, -window_rc.top); + ok(EqualRect(&window_rc, &ret_rc), "GetRandomRgn %ld,%ld - %ld,%ld\n", + ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom); + + DeleteObject(hrgn); + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); +} + +START_TEST(clipping) +{ + test_GetRandomRgn(); +} diff --git a/reactos/regtests/winetests/gdi32/dc.c b/reactos/regtests/winetests/gdi32/dc.c new file mode 100644 index 00000000000..5b50632750d --- /dev/null +++ b/reactos/regtests/winetests/gdi32/dc.c @@ -0,0 +1,180 @@ +/* + * Unit tests for dc functions + * + * Copyright (c) 2005 Huw Davies + * Copyright (c) 2005 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "wine/test.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winerror.h" + +static void dump_region(HRGN hrgn) +{ + DWORD i, size; + RGNDATA *data = NULL; + RECT *rect; + + if (!hrgn) + { + printf( "(null) region\n" ); + return; + } + if (!(size = GetRegionData( hrgn, 0, NULL ))) return; + if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return; + GetRegionData( hrgn, size, data ); + printf( "%ld rects:", data->rdh.nCount ); + for (i = 0, rect = (RECT *)data->Buffer; i < data->rdh.nCount; i++, rect++) + printf( " (%ld,%ld)-(%ld,%ld)", rect->left, rect->top, rect->right, rect->bottom ); + printf( "\n" ); + HeapFree( GetProcessHeap(), 0, data ); +} + +static void test_savedc_2(void) +{ + HWND hwnd; + HDC hdc; + HRGN hrgn; + RECT rc, rc_clip; + int ret; + + hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100, + 0, 0, 0, NULL); + assert(hwnd != 0); + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + + hrgn = CreateRectRgn(0, 0, 0, 0); + assert(hrgn != 0); + + hdc = GetDC(hwnd); + ok(hdc != NULL, "CreateDC rets %p\n", hdc); + + ret = GetClipBox(hdc, &rc_clip); + ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret); + ret = GetClipRgn(hdc, hrgn); + ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret); + ret = GetRgnBox(hrgn, &rc); + ok(ret == NULLREGION, "GetRgnBox returned %d (%ld,%ld-%ld,%ld) instead of NULLREGION\n", + ret, rc.left, rc.top, rc.right, rc.bottom); + /*dump_region(hrgn);*/ + SetRect(&rc, 0, 0, 100, 100); + ok(EqualRect(&rc, &rc_clip), + "rects are not equal: (%ld,%ld-%ld,%ld) - (%ld,%ld-%ld,%ld)\n", + rc.left, rc.top, rc.right, rc.bottom, + rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom); + + ret = SaveDC(hdc); +todo_wine +{ + ok(ret == 1, "ret = %d\n", ret); +} + + ret = IntersectClipRect(hdc, 0, 0, 50, 50); +#if 0 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */ + ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret); +#endif + if (ret != SIMPLEREGION) + { + trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret); + /* let's make sure that it's a simple region */ + ret = GetClipRgn(hdc, hrgn); + ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret); + dump_region(hrgn); + } + + ret = GetClipBox(hdc, &rc_clip); + ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret); + SetRect(&rc, 0, 0, 50, 50); + ok(EqualRect(&rc, &rc_clip), "rects are not equal\n"); + + ret = RestoreDC(hdc, 1); + ok(ret, "ret = %d\n", ret); + + ret = GetClipBox(hdc, &rc_clip); + ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret); + SetRect(&rc, 0, 0, 100, 100); + ok(EqualRect(&rc, &rc_clip), "rects are not equal\n"); + + DeleteObject(hrgn); + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); +} + +static void test_savedc(void) +{ + HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); + int ret; + + ok(hdc != NULL, "CreateDC rets %p\n", hdc); + + ret = SaveDC(hdc); + ok(ret == 1, "ret = %d\n", ret); + ret = SaveDC(hdc); + ok(ret == 2, "ret = %d\n", ret); + ret = SaveDC(hdc); + ok(ret == 3, "ret = %d\n", ret); + ret = RestoreDC(hdc, -1); + ok(ret, "ret = %d\n", ret); + ret = SaveDC(hdc); + ok(ret == 3, "ret = %d\n", ret); + ret = RestoreDC(hdc, 1); + ok(ret, "ret = %d\n", ret); + ret = SaveDC(hdc); + ok(ret == 1, "ret = %d\n", ret); + ret = SaveDC(hdc); + ok(ret == 2, "ret = %d\n", ret); + ret = SaveDC(hdc); + ok(ret == 3, "ret = %d\n", ret); + ret = RestoreDC(hdc, -2); + ok(ret, "ret = %d\n", ret); + ret = SaveDC(hdc); + ok(ret == 2, "ret = %d\n", ret); + ret = RestoreDC(hdc, -2); + ok(ret, "ret = %d\n", ret); + ret = SaveDC(hdc); + ok(ret == 1, "ret = %d\n", ret); + ret = SaveDC(hdc); + ok(ret == 2, "ret = %d\n", ret); + ret = RestoreDC(hdc, -4); + ok(!ret, "ret = %d\n", ret); + ret = RestoreDC(hdc, 3); + ok(!ret, "ret = %d\n", ret); + + /* Under win98 the following two succeed and both clear the save stack + ret = RestoreDC(hdc, -3); + ok(!ret, "ret = %d\n", ret); + ret = RestoreDC(hdc, 0); + ok(!ret, "ret = %d\n", ret); + */ + + ret = RestoreDC(hdc, 1); + ok(ret, "ret = %d\n", ret); + + DeleteDC(hdc); +} + +START_TEST(dc) +{ + test_savedc(); + test_savedc_2(); +} diff --git a/reactos/regtests/winetests/gdi32/font.c b/reactos/regtests/winetests/gdi32/font.c new file mode 100644 index 00000000000..699d9b28e08 --- /dev/null +++ b/reactos/regtests/winetests/gdi32/font.c @@ -0,0 +1,441 @@ +/* + * Unit test suite for fonts + * + * Copyright 2002 Mike McCormack + * Copyright 2004 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +#include "wine/test.h" + +static void check_font(const char* test, const LOGFONTA* lf, HFONT hfont) +{ + LOGFONTA getobj_lf; + int ret, minlen = 0; + + if (!hfont) + return; + + ret = GetObject(hfont, sizeof(getobj_lf), &getobj_lf); + /* NT4 tries to be clever and only returns the minimum length */ + while (lf->lfFaceName[minlen] && minlen < LF_FACESIZE-1) + minlen++; + minlen += FIELD_OFFSET(LOGFONTA, lfFaceName) + 1; + ok(ret == sizeof(LOGFONTA) || ret == minlen, "%s: GetObject returned %d\n", test, ret); + ok(!memcmp(&lf, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "%s: fonts don't match\n", test); + ok(!lstrcmpA(lf->lfFaceName, getobj_lf.lfFaceName), + "%s: font names don't match: %s != %s\n", test, lf->lfFaceName, getobj_lf.lfFaceName); +} + +static HFONT create_font(const char* test, const LOGFONTA* lf) +{ + HFONT hfont = CreateFontIndirectA(lf); + ok(hfont != 0, "%s: CreateFontIndirect failed\n", test); + if (hfont) + check_font(test, lf, hfont); + return hfont; +} + +static void test_logfont(void) +{ + LOGFONTA lf; + HFONT hfont; + + memset(&lf, 0, sizeof lf); + + lf.lfCharSet = ANSI_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfWeight = FW_DONTCARE; + lf.lfHeight = 16; + lf.lfWidth = 16; + lf.lfQuality = DEFAULT_QUALITY; + + lstrcpyA(lf.lfFaceName, "Arial"); + hfont = create_font("Arial", &lf); + DeleteObject(hfont); + + memset(&lf, 'A', sizeof(lf)); + hfont = CreateFontIndirectA(&lf); + ok(hfont != 0, "CreateFontIndirectA with strange LOGFONT failed\n"); + + lf.lfFaceName[LF_FACESIZE - 1] = 0; + check_font("AAA...", &lf, hfont); + DeleteObject(hfont); +} + +static INT CALLBACK font_enum_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) +{ + if (type & RASTER_FONTTYPE) + { + LOGFONT *lf = (LOGFONT *)lParam; + *lf = *elf; + return 0; /* stop enumeration */ + } + + return 1; /* continue enumeration */ +} + +static void test_font_metrics(HDC hdc, HFONT hfont, const char *test_str, + INT test_str_len, const TEXTMETRICA *tm_orig, + const SIZE *size_orig, INT width_orig, + INT scale_x, INT scale_y) +{ + HFONT old_hfont; + TEXTMETRICA tm; + SIZE size; + INT width; + + if (!hfont) + return; + + old_hfont = SelectObject(hdc, hfont); + + GetTextMetricsA(hdc, &tm); + + ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "%ld != %ld\n", tm.tmHeight, tm_orig->tmHeight * scale_y); + ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "%ld != %ld\n", tm.tmAscent, tm_orig->tmAscent * scale_y); + ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "%ld != %ld\n", tm.tmDescent, tm_orig->tmDescent * scale_y); + ok(tm.tmAveCharWidth == tm_orig->tmAveCharWidth * scale_x, "%ld != %ld\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x); + + GetTextExtentPoint32A(hdc, test_str, test_str_len, &size); + + ok(size.cx == size_orig->cx * scale_x, "%ld != %ld\n", size.cx, size_orig->cx * scale_x); + ok(size.cy == size_orig->cy * scale_y, "%ld != %ld\n", size.cy, size_orig->cy * scale_y); + + GetCharWidthA(hdc, 'A', 'A', &width); + + ok(width == width_orig * scale_x, "%d != %d\n", width, width_orig * scale_x); + + SelectObject(hdc, old_hfont); +} + +/* see whether GDI scales bitmap font metrics */ +static void test_bitmap_font(void) +{ + static const char test_str[11] = "Test String"; + HDC hdc; + LOGFONTA bitmap_lf; + HFONT hfont, old_hfont; + TEXTMETRICA tm_orig; + SIZE size_orig; + INT ret, i, width_orig, height_orig; + + hdc = GetDC(0); + + /* "System" has only 1 pixel size defined, otherwise the test breaks */ + ret = EnumFontFamiliesA(hdc, "System", font_enum_proc, (LPARAM)&bitmap_lf); + if (ret) + { + ReleaseDC(0, hdc); + trace("no bitmap fonts were found, skipping the test\n"); + return; + } + + trace("found bitmap font %s, height %ld\n", bitmap_lf.lfFaceName, bitmap_lf.lfHeight); + + height_orig = bitmap_lf.lfHeight; + hfont = create_font("bitmap", &bitmap_lf); + + old_hfont = SelectObject(hdc, hfont); + ok(GetTextMetricsA(hdc, &tm_orig), "GetTextMetricsA failed\n"); + ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n"); + ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n"); + SelectObject(hdc, old_hfont); + DeleteObject(hfont); + + /* test fractional scaling */ + for (i = 1; i < height_orig; i++) + { + hfont = create_font("fractional", &bitmap_lf); + test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, 1); + DeleteObject(hfont); + } + + /* test integer scaling 3x2 */ + bitmap_lf.lfHeight = height_orig * 2; + bitmap_lf.lfWidth *= 3; + hfont = create_font("3x2", &bitmap_lf); +todo_wine +{ + test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2); +} + DeleteObject(hfont); + + /* test integer scaling 3x3 */ + bitmap_lf.lfHeight = height_orig * 3; + bitmap_lf.lfWidth = 0; + hfont = create_font("3x3", &bitmap_lf); + +todo_wine +{ + test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3); +} + DeleteObject(hfont); + + ReleaseDC(0, hdc); +} + +static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) +{ + LOGFONT *lf = (LOGFONT *)lParam; + + if (elf->lfHeight == lf->lfHeight && !strcmp(elf->lfFaceName, lf->lfFaceName)) + { + *lf = *elf; + return 0; /* stop enumeration */ + } + return 1; /* continue enumeration */ +} + +static void test_bitmap_font_metrics(void) +{ + static const struct font_data + { + const char face_name[LF_FACESIZE]; + int weight, height, ascent, descent, int_leading, ext_leading; + int ave_char_width, max_char_width; + } fd[] = + { + { "MS Sans Serif", FW_NORMAL, 13, 11, 2, 2, 0, 5, 11 }, + { "MS Sans Serif", FW_NORMAL, 16, 13, 3, 3, 0, 7, 14 }, + { "MS Sans Serif", FW_NORMAL, 20, 16, 4, 4, 0, 8, 16 }, + { "MS Sans Serif", FW_NORMAL, 24, 19, 5, 6, 0, 9, 20 }, + { "MS Sans Serif", FW_NORMAL, 29, 23, 6, 5, 0, 12, 25 }, + { "MS Sans Serif", FW_NORMAL, 37, 29, 8, 5, 0, 16, 32 }, + { "MS Serif", FW_NORMAL, 10, 8, 2, 2, 0, 5, 8 }, + { "MS Serif", FW_NORMAL, 11, 9, 2, 2, 0, 5, 9 }, + { "MS Serif", FW_NORMAL, 13, 11, 2, 2, 0, 5, 12 }, + { "MS Serif", FW_NORMAL, 16, 13, 3, 3, 0, 6, 16 }, + { "MS Serif", FW_NORMAL, 19, 15, 4, 3, 0, 8, 19 }, + { "MS Serif", FW_NORMAL, 21, 16, 5, 3, 0, 9, 23 }, + { "MS Serif", FW_NORMAL, 27, 21, 6, 3, 0, 12, 27 }, + { "MS Serif", FW_NORMAL, 35, 27, 8, 3, 0, 16, 34 }, + { "Courier", FW_NORMAL, 13, 11, 2, 0, 0, 8, 8 }, + { "Courier", FW_NORMAL, 16, 13, 3, 0, 0, 9, 9 }, + { "Courier", FW_NORMAL, 20, 16, 4, 0, 0, 12, 12 }, + { "System", FW_BOLD, 16, 13, 3, 3, 0, 7, 15 }, + { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 1, 2 }, + { "Small Fonts", FW_NORMAL, 5, 4, 1, 1, 0, 3, 4 }, + { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 13 }, + { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 7 }, + { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 4, 8 }, + { "Small Fonts", FW_NORMAL, 11, 9, 2, 2, 0, 5, 9 } + /* FIXME: add "Fixedsys", "Terminal" */ + }; + HDC hdc; + LOGFONT lf; + HFONT hfont, old_hfont; + TEXTMETRIC tm; + INT ret, i; + + hdc = CreateCompatibleDC(0); + assert(hdc); + + for (i = 0; i < sizeof(fd)/sizeof(fd[0]); i++) + { + memset(&lf, 0, sizeof(lf)); + + lf.lfHeight = fd[i].height; + strcpy(lf.lfFaceName, fd[i].face_name); + ret = EnumFontFamilies(hdc, fd[i].face_name, find_font_proc, (LPARAM)&lf); + if (ret) + { + trace("font %s height %d not found\n", fd[i].face_name, fd[i].height); + continue; + } + + trace("found font %s, height %ld\n", lf.lfFaceName, lf.lfHeight); + + hfont = create_font(lf.lfFaceName, &lf); + old_hfont = SelectObject(hdc, hfont); + ok(GetTextMetrics(hdc, &tm), "GetTextMetrics error %ld\n", GetLastError()); + + ok(tm.tmWeight == fd[i].weight, "%s(%d): tm.tmWeight %ld != %d\n", fd[i].face_name, fd[i].height, tm.tmWeight, fd[i].weight); + ok(tm.tmHeight == fd[i].height, "%s(%d): tm.tmHeight %ld != %d\n", fd[i].face_name, fd[i].height, tm.tmHeight, fd[i].height); + ok(tm.tmAscent == fd[i].ascent, "%s(%d): tm.tmAscent %ld != %d\n", fd[i].face_name, fd[i].height, tm.tmAscent, fd[i].ascent); + ok(tm.tmDescent == fd[i].descent, "%s(%d): tm.tmDescent %ld != %d\n", fd[i].face_name, fd[i].height, tm.tmDescent, fd[i].descent); + ok(tm.tmInternalLeading == fd[i].int_leading, "%s(%d): tm.tmInternalLeading %ld != %d\n", fd[i].face_name, fd[i].height, tm.tmInternalLeading, fd[i].int_leading); + ok(tm.tmExternalLeading == fd[i].ext_leading, "%s(%d): tm.tmExternalLeading %ld != %d\n", fd[i].face_name, fd[i].height, tm.tmExternalLeading, fd[i].ext_leading); + ok(tm.tmAveCharWidth == fd[i].ave_char_width, "%s(%d): tm.tmAveCharWidth %ld != %d\n", fd[i].face_name, fd[i].height, tm.tmAveCharWidth, fd[i].ave_char_width); + ok(tm.tmMaxCharWidth == fd[i].max_char_width, "%s(%d): tm.tmMaxCharWidth %ld != %d\n", fd[i].face_name, fd[i].height, tm.tmMaxCharWidth, fd[i].max_char_width); + + SelectObject(hdc, old_hfont); + DeleteObject(hfont); + } + + DeleteDC(hdc); +} + +static void test_GdiGetCharDimensions(void) +{ + HDC hdc; + TEXTMETRICW tm; + LONG ret; + SIZE size; + LONG avgwidth, height; + static const char szAlphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + typedef LONG (WINAPI *fnGdiGetCharDimensions)(HDC hdc, LPTEXTMETRICW lptm, LONG *height); + fnGdiGetCharDimensions GdiGetCharDimensions = (fnGdiGetCharDimensions)GetProcAddress(LoadLibrary("gdi32"), "GdiGetCharDimensions"); + if (!GdiGetCharDimensions) return; + + hdc = CreateCompatibleDC(NULL); + + GetTextExtentPoint(hdc, szAlphabet, strlen(szAlphabet), &size); + avgwidth = ((size.cx / 26) + 1) / 2; + + ret = GdiGetCharDimensions(hdc, &tm, &height); + ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + ok(height == tm.tmHeight, "GdiGetCharDimensions should have set height to %ld instead of %ld\n", tm.tmHeight, height); + + ret = GdiGetCharDimensions(hdc, &tm, NULL); + ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + + ret = GdiGetCharDimensions(hdc, NULL, NULL); + ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + + height = 0; + ret = GdiGetCharDimensions(hdc, NULL, &height); + ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + ok(height == size.cy, "GdiGetCharDimensions should have set height to %ld instead of %ld\n", size.cy, height); + + DeleteDC(hdc); +} + +static void test_GetCharABCWidthsW(void) +{ + BOOL ret; + ABC abc[1]; + typedef BOOL (WINAPI *fnGetCharABCWidthsW)(HDC hdc, UINT first, UINT last, LPABC abc); + fnGetCharABCWidthsW GetCharABCWidthsW = (fnGetCharABCWidthsW)GetProcAddress(LoadLibrary("gdi32"), "GetCharABCWidthsW"); + if (!GetCharABCWidthsW) return; + + ret = GetCharABCWidthsW(NULL, 'a', 'a', abc); + ok(!ret, "GetCharABCWidthsW should have returned FALSE\n"); +} + +static void test_text_extents(void) +{ + static const WCHAR wt[] = {'O','n','e','\n','t','w','o',' ','3',0}; + LPINT extents; + INT i, len, fit1, fit2; + LOGFONTA lf; + TEXTMETRICA tm; + HDC hdc; + HFONT hfont; + SIZE sz; + SIZE sz1, sz2; + + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, "Arial"); + lf.lfHeight = 20; + + hfont = CreateFontIndirectA(&lf); + hdc = GetDC(0); + hfont = SelectObject(hdc, hfont); + GetTextMetricsA(hdc, &tm); + GetTextExtentPointA(hdc, "o", 1, &sz); + ok(sz.cy == tm.tmHeight, "cy %ld tmHeight %ld\n", sz.cy, tm.tmHeight); + + len = lstrlenW(wt); + extents = HeapAlloc(GetProcessHeap(), 0, len * sizeof extents[0]); + memset(extents, 0, len * sizeof extents[0]); + extents[0] = 1; /* So that the increasing sequence test will fail + if the extents array is untouched. */ + GetTextExtentExPointW(hdc, wt, len, 32767, &fit1, extents, &sz1); + GetTextExtentPointW(hdc, wt, len, &sz2); + ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy, + "results from GetTextExtentExPointW and GetTextExtentPointW differ\n"); + for (i = 1; i < len; ++i) + ok(extents[i-1] <= extents[i], + "GetTextExtentExPointW generated a non-increasing sequence of partial extents (at position %d)\n", + i); + ok(extents[len-1] == sz1.cx, "GetTextExtentExPointW extents and size don't match\n"); + ok(0 <= fit1 && fit1 <= len, "GetTextExtentExPointW generated illegal value %d for fit\n", fit1); + ok(0 < fit1, "GetTextExtentExPointW says we can't even fit one letter in 32767 logical units\n"); + GetTextExtentExPointW(hdc, wt, len, extents[2], &fit2, NULL, &sz2); + ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy, "GetTextExtentExPointW returned different sizes for the same string\n"); + ok(fit2 == 3, "GetTextExtentExPointW extents isn't consistent with fit\n"); + GetTextExtentExPointW(hdc, wt, len, extents[2]-1, &fit2, NULL, &sz2); + ok(fit2 == 2, "GetTextExtentExPointW extents isn't consistent with fit\n"); + GetTextExtentExPointW(hdc, wt, 2, 0, NULL, extents + 2, &sz2); + ok(extents[0] == extents[2] && extents[1] == extents[3], + "GetTextExtentExPointW with lpnFit == NULL returns incorrect results\n"); + GetTextExtentExPointW(hdc, wt, 2, 0, NULL, NULL, &sz1); + ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy, + "GetTextExtentExPointW with lpnFit and alpDx both NULL returns incorrect results\n"); + HeapFree(GetProcessHeap(), 0, extents); + + SelectObject(hdc, hfont); + DeleteObject(hfont); + ReleaseDC(NULL, hdc); +} + +static void test_GetGlyphIndices() +{ + HDC hdc; + HFONT hfont; + DWORD charcount; + LOGFONTA lf; + DWORD flags = 0; + WCHAR testtext[] = {'T','e','s','t',0xffff,0}; + WORD glyphs[(sizeof(testtext)/2)-1]; + TEXTMETRIC textm; + + typedef BOOL (WINAPI *fnGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags); + fnGetGlyphIndicesW GetGlyphIndicesW = (fnGetGlyphIndicesW)GetProcAddress(LoadLibrary("gdi32"), + "GetGlyphIndicesW"); + if (!GetGlyphIndicesW) { + trace("GetGlyphIndices not available on platform\n"); + return; + } + + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, "Symbol"); + lf.lfHeight = 20; + + hfont = CreateFontIndirectA(&lf); + hdc = GetDC(0); + + ok(GetTextMetrics(hdc, &textm), "GetTextMetric failed\n"); + flags |= GGI_MARK_NONEXISTING_GLYPHS; + charcount = GetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags); + ok(charcount == 5, "GetGlyphIndices count of glyphs should = 5 not %ld\n", charcount); + ok(glyphs[4] == 0x001f, "GetGlyphIndices should have returned a nonexistent char not %04x\n", glyphs[4]); + flags = 0; + charcount = GetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags); + ok(charcount == 5, "GetGlyphIndices count of glyphs should = 5 not %ld\n", charcount); + ok(glyphs[4] == textm.tmDefaultChar, "GetGlyphIndices should have returned a %04x not %04x\n", + textm.tmDefaultChar, glyphs[4]); +} + +START_TEST(font) +{ + test_logfont(); + test_bitmap_font(); + test_bitmap_font_metrics(); + test_GdiGetCharDimensions(); + test_GetCharABCWidthsW(); + test_text_extents(); + test_GetGlyphIndices(); +} diff --git a/reactos/regtests/winetests/gdi32/gdi32.rbuild b/reactos/regtests/winetests/gdi32/gdi32.rbuild index d9d1e40945f..448a0fa8d16 100644 --- a/reactos/regtests/winetests/gdi32/gdi32.rbuild +++ b/reactos/regtests/winetests/gdi32/gdi32.rbuild @@ -8,7 +8,10 @@ advapi32 bitmap.c brush.c + clipping.c + dc.c gdiobj.c + font.c metafile.c testlist.c diff --git a/reactos/regtests/winetests/gdi32/gdiobj.c b/reactos/regtests/winetests/gdi32/gdiobj.c index deed86fc3b1..21310b11685 100755 --- a/reactos/regtests/winetests/gdi32/gdiobj.c +++ b/reactos/regtests/winetests/gdi32/gdiobj.c @@ -16,10 +16,11 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include +#include #include "windef.h" #include "winbase.h" @@ -28,175 +29,6 @@ #include "wine/test.h" - -static void check_font(const char* test, const LOGFONTA* lf, HFONT hfont) -{ - LOGFONTA getobj_lf; - int ret, minlen = 0; - - if (!hfont) - return; - - ret = GetObject(hfont, sizeof(getobj_lf), &getobj_lf); - /* NT4 tries to be clever and only returns the minimum length */ - while (lf->lfFaceName[minlen] && minlen < LF_FACESIZE-1) - minlen++; - minlen += FIELD_OFFSET(LOGFONTA, lfFaceName) + 1; - ok(ret == sizeof(LOGFONTA) || ret == minlen, - "%s: GetObject returned %d expected %d or %d\n", test, ret, sizeof(LOGFONTA), minlen); - ok(!memcmp(&lf, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "%s: fonts don't match\n", test); - ok(!lstrcmpA(lf->lfFaceName, getobj_lf.lfFaceName), - "%s: font names don't match: %s != %s\n", test, lf->lfFaceName, getobj_lf.lfFaceName); -} - -static HFONT create_font(const char* test, const LOGFONTA* lf) -{ - HFONT hfont = CreateFontIndirectA(lf); - ok(hfont != 0, "%s: CreateFontIndirect failed\n", test); - if (hfont) - check_font(test, lf, hfont); - return hfont; -} - -static void test_logfont(void) -{ - LOGFONTA lf; - HFONT hfont; - - memset(&lf, 0, sizeof lf); - - lf.lfCharSet = ANSI_CHARSET; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfWeight = FW_DONTCARE; - lf.lfHeight = 16; - lf.lfWidth = 16; - lf.lfQuality = DEFAULT_QUALITY; - - lstrcpyA(lf.lfFaceName, "Arial"); - hfont = create_font("Arial", &lf); - DeleteObject(hfont); - - memset(&lf, 'A', sizeof(lf)); - hfont = CreateFontIndirectA(&lf); - ok(hfont != 0, "CreateFontIndirectA with strange LOGFONT failed\n"); - - lf.lfFaceName[LF_FACESIZE - 1] = 0; - check_font("AAA...", &lf, hfont); - DeleteObject(hfont); -} - -static INT CALLBACK font_enum_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) -{ - if (type & RASTER_FONTTYPE) - { - LOGFONT *lf = (LOGFONT *)lParam; - *lf = *elf; - return 0; /* stop enumeration */ - } - - return 1; /* continue enumeration */ -} - -static void test_font_metrics(HDC hdc, HFONT hfont, const char *test_str, - INT test_str_len, const TEXTMETRICA *tm_orig, - const SIZE *size_orig, INT width_orig, - INT scale_x, INT scale_y) -{ - HFONT old_hfont; - TEXTMETRICA tm; - SIZE size; - INT width; - - if (!hfont) - return; - - old_hfont = SelectObject(hdc, hfont); - - GetTextMetricsA(hdc, &tm); - - ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "%ld != %ld\n", tm.tmHeight, tm_orig->tmHeight * scale_y); - ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "%ld != %ld\n", tm.tmAscent, tm_orig->tmAscent * scale_y); - ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "%ld != %ld\n", tm.tmDescent, tm_orig->tmDescent * scale_y); - ok(tm.tmAveCharWidth == tm_orig->tmAveCharWidth * scale_x, "%ld != %ld\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x); - - GetTextExtentPoint32A(hdc, test_str, test_str_len, &size); - - ok(size.cx == size_orig->cx * scale_x, "%ld != %ld\n", size.cx, size_orig->cx * scale_x); - ok(size.cy == size_orig->cy * scale_y, "%ld != %ld\n", size.cy, size_orig->cy * scale_y); - - GetCharWidthA(hdc, 'A', 'A', &width); - - ok(width == width_orig * scale_x, "%d != %d\n", width, width_orig * scale_x); - - SelectObject(hdc, old_hfont); -} - -/* see whether GDI scales bitmap font metrics */ -static void test_bitmap_font(void) -{ - static const char test_str[11] = "Test String"; - HDC hdc; - LOGFONTA bitmap_lf; - HFONT hfont, old_hfont; - TEXTMETRICA tm_orig; - SIZE size_orig; - INT ret, i, width_orig, height_orig; - - hdc = GetDC(0); - - /* "System" has only 1 pixel size defined, otherwise the test breaks */ - ret = EnumFontFamiliesA(hdc, "System", font_enum_proc, (LPARAM)&bitmap_lf); - if (ret) - { - ReleaseDC(0, hdc); - trace("no bitmap fonts were found, skipping the test\n"); - return; - } - - trace("found bitmap font %s, height %ld\n", bitmap_lf.lfFaceName, bitmap_lf.lfHeight); - - height_orig = bitmap_lf.lfHeight; - hfont = create_font("bitmap", &bitmap_lf); - - old_hfont = SelectObject(hdc, hfont); - ok(GetTextMetricsA(hdc, &tm_orig), "GetTextMetricsA failed\n"); - ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n"); - ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n"); - SelectObject(hdc, old_hfont); - DeleteObject(hfont); - - /* test fractional scaling */ - for (i = 1; i < height_orig; i++) - { - hfont = create_font("fractional", &bitmap_lf); - test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, 1); - DeleteObject(hfont); - } - - /* test integer scaling 3x2 */ - bitmap_lf.lfHeight = height_orig * 2; - bitmap_lf.lfWidth *= 3; - hfont = create_font("3x2", &bitmap_lf); -todo_wine -{ - test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2); -} - DeleteObject(hfont); - - /* test integer scaling 3x3 */ - bitmap_lf.lfHeight = height_orig * 3; - bitmap_lf.lfWidth = 0; - hfont = create_font("3x3", &bitmap_lf); - -todo_wine -{ - test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3); -} - DeleteObject(hfont); - - ReleaseDC(0, hdc); -} - static void test_gdi_objects(void) { BYTE buff[256]; @@ -266,70 +98,177 @@ static void test_gdi_objects(void) ReleaseDC(NULL, hdc); } -static void test_GdiGetCharDimensions(void) +struct hgdiobj_event { HDC hdc; - TEXTMETRICW tm; - LONG ret; - SIZE size; - LONG avgwidth, height; - static const char szAlphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - typedef LONG (WINAPI *fnGdiGetCharDimensions)(HDC hdc, LPTEXTMETRICW lptm, LONG *height); - fnGdiGetCharDimensions GdiGetCharDimensions = (fnGdiGetCharDimensions)GetProcAddress(LoadLibrary("gdi32"), "GdiGetCharDimensions"); - if (!GdiGetCharDimensions) return; + HGDIOBJ hgdiobj1; + HGDIOBJ hgdiobj2; + HANDLE stop_event; + HANDLE ready_event; +}; - hdc = CreateCompatibleDC(NULL); +static DWORD WINAPI thread_proc(void *param) +{ + LOGPEN lp; + struct hgdiobj_event *hgdiobj_event = (struct hgdiobj_event *)param; - GetTextExtentPoint(hdc, szAlphabet, strlen(szAlphabet), &size); - avgwidth = ((size.cx / 26) + 1) / 2; + hgdiobj_event->hdc = CreateDC("display", NULL, NULL, NULL); + ok(hgdiobj_event->hdc != NULL, "CreateDC error %ld\n", GetLastError()); - ret = GdiGetCharDimensions(hdc, &tm, &height); - ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); - ok(height == tm.tmHeight, "GdiGetCharDimensions should have set height to %ld instead of %ld\n", tm.tmHeight, height); + hgdiobj_event->hgdiobj1 = CreatePen(PS_DASHDOTDOT, 17, RGB(1, 2, 3)); + ok(hgdiobj_event->hgdiobj1 != 0, "Failed to create pen\n"); - ret = GdiGetCharDimensions(hdc, &tm, NULL); - ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + hgdiobj_event->hgdiobj2 = CreateRectRgn(0, 1, 12, 17); + ok(hgdiobj_event->hgdiobj2 != 0, "Failed to create pen\n"); - ret = GdiGetCharDimensions(hdc, NULL, NULL); - ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + SetEvent(hgdiobj_event->ready_event); + ok(WaitForSingleObject(hgdiobj_event->stop_event, INFINITE) == WAIT_OBJECT_0, + "WaitForSingleObject error %ld\n", GetLastError()); - height = 0; - ret = GdiGetCharDimensions(hdc, NULL, &height); - ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); - ok(height == size.cy, "GdiGetCharDimensions should have set height to %ld instead of %ld\n", size.cy, height); + ok(!GetObject(hgdiobj_event->hgdiobj1, sizeof(lp), &lp), "GetObject should fail\n"); + + ok(!GetDeviceCaps(hgdiobj_event->hdc, TECHNOLOGY), "GetDeviceCaps(TECHNOLOGY) should fail\n"); + + return 0; +} + +static void test_thread_objects(void) +{ + LOGPEN lp; + DWORD tid, type; + HANDLE hthread; + struct hgdiobj_event hgdiobj_event; + INT ret; + + hgdiobj_event.stop_event = CreateEvent(NULL, 0, 0, NULL); + ok(hgdiobj_event.stop_event != NULL, "CreateEvent error %ld\n", GetLastError()); + hgdiobj_event.ready_event = CreateEvent(NULL, 0, 0, NULL); + ok(hgdiobj_event.ready_event != NULL, "CreateEvent error %ld\n", GetLastError()); + + hthread = CreateThread(NULL, 0, thread_proc, &hgdiobj_event, 0, &tid); + ok(hthread != NULL, "CreateThread error %ld\n", GetLastError()); + + ok(WaitForSingleObject(hgdiobj_event.ready_event, INFINITE) == WAIT_OBJECT_0, + "WaitForSingleObject error %ld\n", GetLastError()); + + ok(GetObject(hgdiobj_event.hgdiobj1, sizeof(lp), &lp) == sizeof(lp), + "GetObject error %ld\n", GetLastError()); + ok(lp.lopnStyle == PS_DASHDOTDOT, "wrong pen style %d\n", lp.lopnStyle); + ok(lp.lopnWidth.x == 17, "wrong pen width.y %ld\n", lp.lopnWidth.x); + ok(lp.lopnWidth.y == 0, "wrong pen width.y %ld\n", lp.lopnWidth.y); + ok(lp.lopnColor == RGB(1, 2, 3), "wrong pen width.y %08lx\n", lp.lopnColor); + + ret = GetDeviceCaps(hgdiobj_event.hdc, TECHNOLOGY); + ok(ret == DT_RASDISPLAY, "GetDeviceCaps(TECHNOLOGY) should return DT_RASDISPLAY not %d\n", ret); + + ok(DeleteObject(hgdiobj_event.hgdiobj1), "DeleteObject error %ld\n", GetLastError()); + ok(DeleteDC(hgdiobj_event.hdc), "DeleteDC error %ld\n", GetLastError()); + + type = GetObjectType(hgdiobj_event.hgdiobj2); + ok(type == OBJ_REGION, "GetObjectType returned %lu\n", type); + + SetEvent(hgdiobj_event.stop_event); + ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, + "WaitForSingleObject error %ld\n", GetLastError()); + CloseHandle(hthread); + + type = GetObjectType(hgdiobj_event.hgdiobj2); + ok(type == OBJ_REGION, "GetObjectType returned %lu\n", type); + ok(DeleteObject(hgdiobj_event.hgdiobj2), "DeleteObject error %ld\n", GetLastError()); + + CloseHandle(hgdiobj_event.stop_event); + CloseHandle(hgdiobj_event.ready_event); +} + +static void test_GetCurrentObject(void) +{ + DWORD type; + HPEN hpen; + HBRUSH hbrush; + HPALETTE hpal; + HFONT hfont; + HBITMAP hbmp; + HRGN hrgn; + HDC hdc; + HCOLORSPACE hcs; + HGDIOBJ hobj; + LOGBRUSH lb; + LOGCOLORSPACEA lcs; + + hdc = CreateCompatibleDC(0); + assert(hdc != 0); + + type = GetObjectType(hdc); + ok(type == OBJ_MEMDC, "GetObjectType returned %lu\n", type); + + hpen = CreatePen(PS_SOLID, 10, RGB(10, 20, 30)); + assert(hpen != 0); + SelectObject(hdc, hpen); + hobj = GetCurrentObject(hdc, OBJ_PEN); + ok(hobj == hpen, "OBJ_PEN is wrong: %p\n", hobj); + hobj = GetCurrentObject(hdc, OBJ_EXTPEN); + ok(hobj == hpen, "OBJ_EXTPEN is wrong: %p\n", hobj); + + hbrush = CreateSolidBrush(RGB(10, 20, 30)); + assert(hbrush != 0); + SelectObject(hdc, hbrush); + hobj = GetCurrentObject(hdc, OBJ_BRUSH); + ok(hobj == hbrush, "OBJ_BRUSH is wrong: %p\n", hobj); + + hpal = CreateHalftonePalette(hdc); + assert(hpal != 0); + SelectPalette(hdc, hpal, FALSE); + hobj = GetCurrentObject(hdc, OBJ_PAL); + ok(hobj == hpal, "OBJ_PAL is wrong: %p\n", hobj); + + hfont = CreateFontA(10, 5, 0, 0, FW_DONTCARE, 0, 0, 0, ANSI_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + DEFAULT_PITCH, "MS Sans Serif"); + assert(hfont != 0); + SelectObject(hdc, hfont); + hobj = GetCurrentObject(hdc, OBJ_FONT); + ok(hobj == hfont, "OBJ_FONT is wrong: %p\n", hobj); + + hbmp = CreateBitmap(100, 100, 1, 1, NULL); + assert(hbmp != 0); + SelectObject(hdc, hbmp); + hobj = GetCurrentObject(hdc, OBJ_BITMAP); + ok(hobj == hbmp, "OBJ_BITMAP is wrong: %p\n", hobj); + + assert(GetObject(hbrush, sizeof(lb), &lb) == sizeof(lb)); + hpen = ExtCreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_SQUARE | PS_JOIN_BEVEL, + 10, &lb, 0, NULL); + assert(hpen != 0); + SelectObject(hdc, hpen); + hobj = GetCurrentObject(hdc, OBJ_PEN); + ok(hobj == hpen, "OBJ_PEN is wrong: %p\n", hobj); + hobj = GetCurrentObject(hdc, OBJ_EXTPEN); + ok(hobj == hpen, "OBJ_EXTPEN is wrong: %p\n", hobj); + + hcs = GetColorSpace(hdc); + if (hcs) + { + trace("current color space is not NULL\n"); + ok(GetLogColorSpaceA(hcs, &lcs, sizeof(lcs)), "GetLogColorSpace failed\n"); + hcs = CreateColorSpaceA(&lcs); + ok(hcs != 0, "CreateColorSpace failed\n"); + SelectObject(hdc, hcs); + hobj = GetCurrentObject(hdc, OBJ_COLORSPACE); + ok(hobj == hcs, "OBJ_COLORSPACE is wrong: %p\n", hobj); + } + + hrgn = CreateRectRgn(1, 1, 100, 100); + assert(hrgn != 0); + SelectObject(hdc, hrgn); + hobj = GetCurrentObject(hdc, OBJ_REGION); + ok(!hobj, "OBJ_REGION is wrong: %p\n", hobj); DeleteDC(hdc); } -static void test_text_extents(void) -{ - LOGFONTA lf; - TEXTMETRICA tm; - HDC hdc; - HFONT hfont; - SIZE sz; - - memset(&lf, 0, sizeof(lf)); - strcpy(lf.lfFaceName, "Arial"); - lf.lfHeight = 20; - - hfont = CreateFontIndirectA(&lf); - hdc = GetDC(0); - hfont = SelectObject(hdc, hfont); - GetTextMetricsA(hdc, &tm); - GetTextExtentPointA(hdc, "o", 1, &sz); - ok(sz.cy == tm.tmHeight, "cy %ld tmHeight %ld\n", sz.cy, tm.tmHeight); - - SelectObject(hdc, hfont); - DeleteObject(hfont); - ReleaseDC(NULL, hdc); -} - START_TEST(gdiobj) { - test_logfont(); - test_bitmap_font(); test_gdi_objects(); - test_GdiGetCharDimensions(); - test_text_extents(); + test_thread_objects(); + test_GetCurrentObject(); } diff --git a/reactos/regtests/winetests/gdi32/metafile.c b/reactos/regtests/winetests/gdi32/metafile.c index 17f0138c803..3610bf89265 100755 --- a/reactos/regtests/winetests/gdi32/metafile.c +++ b/reactos/regtests/winetests/gdi32/metafile.c @@ -15,7 +15,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -35,7 +35,28 @@ static BOOL emr_processed = FALSE; #define LINE_X 55.0f #define LINE_Y 15.0f -static int CALLBACK emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, +static INT (WINAPI * pGetRelAbs)(HDC, DWORD); +static INT (WINAPI * pSetRelAbs)(HDC, INT); + +#define GDI_GET_PROC(func) \ + p ## func = (void *)GetProcAddress(hGDI, #func); \ + if(!p ## func) \ + trace("GetProcAddress(hGDI, \"%s\") failed\n", #func); \ + +static void init_function_pointers(void) +{ + HMODULE hGDI; + + pGetRelAbs = NULL; + pSetRelAbs = NULL; + + hGDI = GetModuleHandleA("gdi32.dll"); + assert(hGDI); + GDI_GET_PROC(GetRelAbs); + GDI_GET_PROC(SetRelAbs); +} + +static int CALLBACK eto_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, const ENHMETARECORD *emr, int n_objs, LPARAM param) { static int n_record; @@ -55,6 +76,19 @@ static int CALLBACK emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, switch (emr->iType) { case EMR_HEADER: + ok(GetTextAlign(hdc) == 0, "text align %08x\n", GetTextAlign(hdc)); + ok(GetBkColor(hdc) == RGB(0xff, 0xff, 0xff), "bk color %08lx\n", GetBkColor(hdc)); + ok(GetTextColor(hdc) == RGB(0x0, 0x0, 0x0), "text color %08lx\n", GetTextColor(hdc)); + ok(GetROP2(hdc) == R2_COPYPEN, "rop %d\n", GetROP2(hdc)); + ok(GetArcDirection(hdc) == AD_COUNTERCLOCKWISE, "arc dir %d\n", GetArcDirection(hdc)); + ok(GetPolyFillMode(hdc) == ALTERNATE, "poly fill %d\n", GetPolyFillMode(hdc)); + ok(GetStretchBltMode(hdc) == BLACKONWHITE, "stretchblt mode %d\n", GetStretchBltMode(hdc)); + + /* GetBkMode, GetRelAbs do not get reset to the default value */ + ok(GetBkMode(hdc) == OPAQUE, "bk mode %d\n", GetBkMode(hdc)); + if(pSetRelAbs && pGetRelAbs) + ok(pGetRelAbs(hdc, 0) == RELATIVE, "relabs %d\n", pGetRelAbs(hdc, 0)); + n_record = 0; break; @@ -189,21 +223,147 @@ static void test_ExtTextOut(void) ret = PlayEnhMetaFile(hdcDisplay, hMetafile, &rc); ok( ret, "PlayEnhMetaFile error %ld\n", GetLastError()); - ret = EnumEnhMetaFile(hdcDisplay, hMetafile, emf_enum_proc, dx, &rc); + SetTextAlign(hdcDisplay, TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING ); + SetBkColor(hdcDisplay, RGB(0xff, 0, 0)); + SetTextColor(hdcDisplay, RGB(0, 0xff, 0)); + SetROP2(hdcDisplay, R2_NOT); + SetArcDirection(hdcDisplay, AD_CLOCKWISE); + SetPolyFillMode(hdcDisplay, WINDING); + SetStretchBltMode(hdcDisplay, HALFTONE); + + if(pSetRelAbs) pSetRelAbs(hdcDisplay, RELATIVE); + SetBkMode(hdcDisplay, OPAQUE); + + ret = EnumEnhMetaFile(hdcDisplay, hMetafile, eto_emf_enum_proc, dx, &rc); ok( ret, "EnumEnhMetaFile error %ld\n", GetLastError()); + ok( GetTextAlign(hdcDisplay) == (TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING), + "text align %08x\n", GetTextAlign(hdcDisplay)); + ok( GetBkColor(hdcDisplay) == RGB(0xff, 0, 0), "bk color %08lx\n", GetBkColor(hdcDisplay)); + ok( GetTextColor(hdcDisplay) == RGB(0, 0xff, 0), "text color %08lx\n", GetTextColor(hdcDisplay)); + ok( GetROP2(hdcDisplay) == R2_NOT, "rop2 %d\n", GetROP2(hdcDisplay)); + ok( GetArcDirection(hdcDisplay) == AD_CLOCKWISE, "arc dir %d\n", GetArcDirection(hdcDisplay)); + ok( GetPolyFillMode(hdcDisplay) == WINDING, "poly fill %d\n", GetPolyFillMode(hdcDisplay)); + ok( GetStretchBltMode(hdcDisplay) == HALFTONE, "stretchblt mode %d\n", GetStretchBltMode(hdcDisplay)); + ok(emr_processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTA or EMR_EXTTEXTOUTW record\n"); - ok(!EnumEnhMetaFile(hdcDisplay, hMetafile, emf_enum_proc, dx, NULL), + ok(!EnumEnhMetaFile(hdcDisplay, hMetafile, eto_emf_enum_proc, dx, NULL), "A valid hdc has to require a valid rc\n"); - ok(EnumEnhMetaFile(NULL, hMetafile, emf_enum_proc, dx, NULL), + ok(EnumEnhMetaFile(NULL, hMetafile, eto_emf_enum_proc, dx, NULL), "A null hdc does not require a valid rc\n"); ret = DeleteEnhMetaFile(hMetafile); ok( ret, "DeleteEnhMetaFile error %ld\n", GetLastError()); ret = ReleaseDC(hwnd, hdcDisplay); ok( ret, "ReleaseDC error %ld\n", GetLastError()); + DestroyWindow(hwnd); +} + +static int CALLBACK savedc_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, + const ENHMETARECORD *emr, int n_objs, LPARAM param) +{ + static int save_state; + static int restore_no; + + switch (emr->iType) + { + case EMR_HEADER: + save_state = 0; + restore_no = 0; + break; + + case EMR_SAVEDC: + save_state++; + break; + + case EMR_RESTOREDC: + { + EMRRESTOREDC *restoredc = (EMRRESTOREDC *)emr; + switch(++restore_no) + { + case 1: + ok(restoredc->iRelative == -1, "first restore %ld\n", restoredc->iRelative); + break; + + case 2: + ok(restoredc->iRelative == -3, "second restore %ld\n", restoredc->iRelative); + break; + case 3: + ok(restoredc->iRelative == -2, "third restore %ld\n", restoredc->iRelative); + break; + } + ok(restore_no <= 3, "restore_no %d\n", restore_no); + save_state += restoredc->iRelative; + break; + } + case EMR_EOF: + ok(save_state == 0, "EOF save_state %d\n", save_state); + break; + } + + + return 1; +} + +void test_SaveDC(void) +{ + HDC hdcMetafile, hdcDisplay; + HENHMETAFILE hMetafile; + HWND hwnd; + int ret; + static const RECT rc = { 0, 0, 100, 100 }; + + /* Win9x doesn't play EMFs on invisible windows */ + hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE, + 0, 0, 200, 200, 0, 0, 0, NULL); + ok(hwnd != 0, "CreateWindowExA error %ld\n", GetLastError()); + + hdcDisplay = GetDC(hwnd); + ok(hdcDisplay != 0, "GetDC error %ld\n", GetLastError()); + + hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL); + ok(hdcMetafile != 0, "CreateEnhMetaFileA error %ld\n", GetLastError()); + + /* Need to write something to the emf, otherwise Windows won't play it back */ + LineTo(hdcMetafile, 100, 100); + + ret = SaveDC(hdcMetafile); + ok(ret == 1, "ret = %d\n", ret); + + ret = SaveDC(hdcMetafile); + ok(ret == 2, "ret = %d\n", ret); + + ret = SaveDC(hdcMetafile); + ok(ret == 3, "ret = %d\n", ret); + + ret = RestoreDC(hdcMetafile, -1); + ok(ret, "ret = %d\n", ret); + + ret = SaveDC(hdcMetafile); + ok(ret == 3, "ret = %d\n", ret); + + ret = RestoreDC(hdcMetafile, 1); + ok(ret, "ret = %d\n", ret); + + ret = SaveDC(hdcMetafile); + ok(ret == 1, "ret = %d\n", ret); + + ret = SaveDC(hdcMetafile); + ok(ret == 2, "ret = %d\n", ret); + + hMetafile = CloseEnhMetaFile(hdcMetafile); + ok(hMetafile != 0, "CloseEnhMetaFile error %ld\n", GetLastError()); + + ret = EnumEnhMetaFile(hdcDisplay, hMetafile, savedc_emf_enum_proc, 0, &rc); + ok( ret == 1, "EnumEnhMetaFile rets %d\n", ret); + + ret = DeleteEnhMetaFile(hMetafile); + ok( ret, "DeleteEnhMetaFile error %ld\n", GetLastError()); + ret = ReleaseDC(hwnd, hdcDisplay); + ok( ret, "ReleaseDC error %ld\n", GetLastError()); + DestroyWindow(hwnd); } /* Win-format metafile (mfdrv) tests */ @@ -211,7 +371,7 @@ static void test_ExtTextOut(void) /* with the nominal results. */ /* Maximum size of sample metafiles in bytes. */ -#define MF_BUFSIZE 256 +#define MF_BUFSIZE 512 /* 8x8 bitmap data for a pattern brush */ static const unsigned char SAMPLE_PATTERN_BRUSH[] = { @@ -262,22 +422,205 @@ static const unsigned char MF_PATTERN_BRUSH_BITS[] = { 0x00, 0x00 }; +static const unsigned char MF_TEXTOUT_ON_PATH_BITS[] = +{ + 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a, + 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00, + 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +static const unsigned char EMF_TEXTOUT_ON_PATH_BITS[] = +{ + 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff, + 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, + 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00, + 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41, + 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00, + 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00 +}; + +static const unsigned char MF_LINETO_BITS[] = { + 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02, + 0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +static const unsigned char EMF_LINETO_BITS[] = { + 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x06, 0x00, 0x00, 0xb7, 0x01, 0x00, 0x00, + 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, + 0x38, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00, + 0xe0, 0x93, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, + 0x47, 0x44, 0x49, 0x43, 0x01, 0x00, 0x00, 0x80, + 0x00, 0x03, 0x00, 0x00, 0x60, 0xe5, 0xf4, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02, + 0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x80, 0x4b, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 +}; + +static const unsigned char EMF_LINETO_MM_ANISOTROPIC_BITS[] = { + 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, + 0x38, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00, + 0xe0, 0x93, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, + 0x47, 0x44, 0x49, 0x43, 0x01, 0x00, 0x00, 0x80, + 0x00, 0x03, 0x00, 0x00, 0xa4, 0xfe, 0xf4, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02, + 0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x80, 0x4b, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 +}; + +static const unsigned char EMF_LINETO_MM_TEXT_BITS[] = { + 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x06, 0x00, 0x00, 0xb7, 0x01, 0x00, 0x00, + 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, + 0xe4, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00, + 0xe0, 0x93, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, + 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x30, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x80, + 0x4b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00 +}; + +/* For debugging or dumping the raw metafiles produced by + * new test functions. + */ +static INT CALLBACK mf_enum_proc(HDC hdc, HANDLETABLE *ht, METARECORD *mr, + INT nobj, LPARAM param) +{ + trace("hdc %p, mr->rdFunction %04x, mr->rdSize %lu, param %p\n", + hdc, mr->rdFunction, mr->rdSize, (void *)param); + return TRUE; +} + /* For debugging or dumping the raw metafiles produced by * new test functions. */ static void dump_mf_bits (const HMETAFILE mf, const char *desc) { - char buf[MF_BUFSIZE]; + BYTE buf[MF_BUFSIZE]; UINT mfsize, i; + if (!winetest_debug) return; + mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf); ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc); printf ("MetaFile %s has bits:\n{\n ", desc); for (i=0; i 0, "%s: GetEnhMetaFileBits failed\n", desc); + + printf("EMF %s has bits:\n{\n ", desc); + for (i = 0; i < mfsize; i++) + { + printf ("0x%02x", buf[i]); + if (i == mfsize-1) + printf ("\n"); + else if (i % 8 == 7) + printf (",\n "); + else + printf (", "); + } + printf ("};\n"); +} + +static void dump_emf_records(const HENHMETAFILE mf, const char *desc) +{ + BYTE *emf; + BYTE buf[MF_BUFSIZE]; + UINT mfsize, offset; + + if (!winetest_debug) return; + + mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf); + ok (mfsize > 0, "%s: GetEnhMetaFileBits error %ld\n", desc, GetLastError()); + + printf("EMF %s has records:\n", desc); + + emf = buf; + offset = 0; + while(offset < mfsize) + { + EMR *emr = (EMR *)(emf + offset); + printf("emr->iType %ld, emr->nSize %lu\n", emr->iType, emr->nSize); + /*trace("emr->iType 0x%04lx, emr->nSize 0x%04lx\n", emr->iType, emr->nSize);*/ + offset += emr->nSize; + } +} + +/* Compare the EMF produced by a test function with the + * expected raw EMF data in "bits". + * Return value is 0 for a perfect match, + * -1 if lengths aren't equal, + * otherwise returns the number of non-matching bytes. + */ +static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits, + UINT bsize, const char *desc, BOOL todo) +{ + unsigned char buf[MF_BUFSIZE]; + UINT mfsize, i; + int diff; + + mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf); + ok (mfsize > 0, "%s: GetEnhMetaFileBits error %ld\n", desc, GetLastError()); + + if (mfsize < MF_BUFSIZE) + { + if (mfsize != bsize && todo) + { + todo_wine + ok(mfsize == bsize, "%s: mfsize=%d, bsize=%d\n", desc, mfsize, bsize); + } + else + ok(mfsize == bsize, "%s: mfsize=%d, bsize=%d\n", desc, mfsize, bsize); + } + else + ok(bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d\n", + desc, mfsize, bsize); + + if (mfsize != bsize) + return -1; + + diff = 0; + for (i = 0; i < bsize; i++) + { + if (buf[i] != bits[i]) + diff++; + } + if (diff != 0 && todo) + { + todo_wine + { + ok(diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n", + desc, mfsize, bsize, diff); + } + return diff; + } + else + { + ok(diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n", + desc, mfsize, bsize, diff); + + return diff; + } +} + /* Test a blank metafile. May be used as a template for new tests. */ static void test_mf_Blank(void) @@ -333,6 +820,7 @@ static void test_mf_Blank(void) HMETAFILE hMetafile; INT caps; BOOL ret; + INT type; hdcMetafile = CreateMetaFileA(NULL); ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError()); @@ -345,16 +833,155 @@ static void test_mf_Blank(void) hMetafile = CloseMetaFile(hdcMetafile); ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError()); + type = GetObjectType(hMetafile); + ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type); ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n"); if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS), "mf_blank") != 0) - dump_mf_bits (hMetafile, "mf_Blank"); + { + dump_mf_bits(hMetafile, "mf_Blank"); + EnumMetaFile(0, hMetafile, mf_enum_proc, 0); + } ret = DeleteMetaFile(hMetafile); ok( ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError()); } +static void test_CopyMetaFile(void) +{ + HDC hdcMetafile; + HMETAFILE hMetafile, hmf_copy; + BOOL ret; + char temp_path[MAX_PATH]; + char mf_name[MAX_PATH]; + INT type; + + hdcMetafile = CreateMetaFileA(NULL); + ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError()); + trace("hdcMetafile %p\n", hdcMetafile); + + hMetafile = CloseMetaFile(hdcMetafile); + ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError()); + type = GetObjectType(hMetafile); + ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type); + + if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS), + "mf_blank") != 0) + { + dump_mf_bits(hMetafile, "mf_Blank"); + EnumMetaFile(0, hMetafile, mf_enum_proc, 0); + } + + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "wmf", 0, mf_name); + + hmf_copy = CopyMetaFileA(hMetafile, mf_name); + ok(hmf_copy != 0, "CopyMetaFile error %ld\n", GetLastError()); + + type = GetObjectType(hmf_copy); + ok(type == OBJ_METAFILE, "CopyMetaFile created object with type %d\n", type); + + ret = DeleteMetaFile(hMetafile); + ok( ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError()); + + if (compare_mf_disk_bits(mf_name, MF_BLANK_BITS, sizeof(MF_BLANK_BITS), "mf_blank") != 0) + { + dump_mf_bits(hMetafile, "mf_Blank"); + EnumMetaFile(0, hMetafile, mf_enum_proc, 0); + } + + ret = DeleteMetaFile(hmf_copy); + ok( ret, "DeleteMetaFile(%p) error %ld\n", hmf_copy, GetLastError()); + + DeleteFileA(mf_name); +} + +static void test_SetMetaFileBits(void) +{ + HMETAFILE hmf; + INT type; + BOOL ret; + BYTE buf[256]; + METAHEADER *mh; + + hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), MF_GRAPHICS_BITS); + ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError()); + type = GetObjectType(hmf); + ok(type == OBJ_METAFILE, "SetMetaFileBitsEx created object with type %d\n", type); + + if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0) + { + dump_mf_bits(hmf, "mf_Graphics"); + EnumMetaFile(0, hmf, mf_enum_proc, 0); + } + + ret = DeleteMetaFile(hmf); + ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError()); + + /* NULL data crashes XP SP1 */ + /*hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), NULL);*/ + + /* Now with not zero size */ + SetLastError(0xdeadbeef); + hmf = SetMetaFileBitsEx(0, MF_GRAPHICS_BITS); + ok(!hmf, "SetMetaFileBitsEx should fail\n"); + ok(GetLastError() == ERROR_INVALID_DATA, "wrong error %ld\n", GetLastError()); + + /* Now with not even size */ + SetLastError(0xdeadbeef); + hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS) - 1, MF_GRAPHICS_BITS); + ok(!hmf, "SetMetaFileBitsEx should fail\n"); + ok(GetLastError() == 0xdeadbeef /* XP SP1 */, "wrong error %ld\n", GetLastError()); + + /* Now with zeroed out or faked some header fields */ + assert(sizeof(buf) >= sizeof(MF_GRAPHICS_BITS)); + memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS)); + mh = (METAHEADER *)buf; + /* corruption of any of the below fields leads to a failure */ + mh->mtType = 0; + mh->mtVersion = 0; + mh->mtHeaderSize = 0; + SetLastError(0xdeadbeef); + hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf); + ok(!hmf, "SetMetaFileBitsEx should fail\n"); + ok(GetLastError() == ERROR_INVALID_DATA, "wrong error %ld\n", GetLastError()); + + /* Now with corrupted mtSize field */ + memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS)); + mh = (METAHEADER *)buf; + /* corruption of mtSize doesn't lead to a failure */ + mh->mtSize *= 2; + hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf); + ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError()); + + if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0) + { + dump_mf_bits(hmf, "mf_Graphics"); + EnumMetaFile(0, hmf, mf_enum_proc, 0); + } + + ret = DeleteMetaFile(hmf); + ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError()); + + /* Now with zeroed out mtSize field */ + memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS)); + mh = (METAHEADER *)buf; + /* zeroing mtSize doesn't lead to a failure */ + mh->mtSize = 0; + hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf); + ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError()); + + if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0) + { + dump_mf_bits(hmf, "mf_Graphics"); + EnumMetaFile(0, hmf, mf_enum_proc, 0); + } + + ret = DeleteMetaFile(hmf); + ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError()); +} + /* Simple APIs from mfdrv/graphics.c */ @@ -393,7 +1020,10 @@ static void test_mf_Graphics(void) if (compare_mf_bits (hMetafile, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0) - dump_mf_bits (hMetafile, "mf_Graphics"); + { + dump_mf_bits(hMetafile, "mf_Graphics"); + EnumMetaFile(0, hMetafile, mf_enum_proc, 0); + } ret = DeleteMetaFile(hMetafile); ok( ret, "DeleteMetaFile(%p) error %ld\n", @@ -412,8 +1042,8 @@ static void test_mf_PatternBrush(void) orig_lb->lbStyle = BS_PATTERN; orig_lb->lbColor = RGB(0, 0, 0); - orig_lb->lbHatch = (INT) CreateBitmap (8, 8, 1, 1, SAMPLE_PATTERN_BRUSH); - ok((HBITMAP *)orig_lb->lbHatch != NULL, "CreateBitmap error %ld.\n", GetLastError()); + orig_lb->lbHatch = (ULONG_PTR)CreateBitmap (8, 8, 1, 1, SAMPLE_PATTERN_BRUSH); + ok((HBITMAP)orig_lb->lbHatch != NULL, "CreateBitmap error %ld.\n", GetLastError()); hBrush = CreateBrushIndirect (orig_lb); ok(hBrush != 0, "CreateBrushIndirect error %ld\n", GetLastError()); @@ -431,18 +1061,103 @@ static void test_mf_PatternBrush(void) if (compare_mf_bits (hMetafile, MF_PATTERN_BRUSH_BITS, sizeof(MF_PATTERN_BRUSH_BITS), "mf_Pattern_Brush") != 0) - dump_mf_bits (hMetafile, "mf_Pattern_Brush"); + { + dump_mf_bits(hMetafile, "mf_Pattern_Brush"); + EnumMetaFile(0, hMetafile, mf_enum_proc, 0); + } ret = DeleteMetaFile(hMetafile); ok( ret, "DeleteMetaFile error %ld\n", GetLastError()); ret = DeleteObject(hBrush); ok( ret, "DeleteObject(HBRUSH) error %ld\n", GetLastError()); - ret = DeleteObject((HBITMAP *)orig_lb->lbHatch); + ret = DeleteObject((HBITMAP)orig_lb->lbHatch); ok( ret, "DeleteObject(HBITMAP) error %ld\n", GetLastError()); HeapFree (GetProcessHeap(), 0, orig_lb); } +static void test_mf_ExtTextOut_on_path(void) +{ + HDC hdcMetafile; + HMETAFILE hMetafile; + BOOL ret; + static const INT dx[4] = { 3, 5, 8, 12 }; + + hdcMetafile = CreateMetaFileA(NULL); + ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError()); + trace("hdcMetafile %p\n", hdcMetafile); + + ret = BeginPath(hdcMetafile); + ok(!ret, "BeginPath on metafile DC should fail\n"); + + ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx); + ok(ret, "ExtTextOut error %ld\n", GetLastError()); + + ret = EndPath(hdcMetafile); + ok(!ret, "EndPath on metafile DC should fail\n"); + + hMetafile = CloseMetaFile(hdcMetafile); + ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError()); + + if (compare_mf_bits(hMetafile, MF_TEXTOUT_ON_PATH_BITS, sizeof(MF_TEXTOUT_ON_PATH_BITS), + "mf_TextOut_on_path") != 0) + { + dump_mf_bits(hMetafile, "mf_TextOut_on_path"); + EnumMetaFile(0, hMetafile, mf_enum_proc, 0); + } + + ret = DeleteMetaFile(hMetafile); + ok(ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError()); +} + +static void test_emf_ExtTextOut_on_path(void) +{ + HWND hwnd; + HDC hdcDisplay, hdcMetafile; + HENHMETAFILE hMetafile; + BOOL ret; + static const INT dx[4] = { 3, 5, 8, 12 }; + + /* Win9x doesn't play EMFs on invisible windows */ + hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE, + 0, 0, 200, 200, 0, 0, 0, NULL); + ok(hwnd != 0, "CreateWindowExA error %ld\n", GetLastError()); + + hdcDisplay = GetDC(hwnd); + ok(hdcDisplay != 0, "GetDC error %ld\n", GetLastError()); + + hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL); + ok(hdcMetafile != 0, "CreateEnhMetaFileA error %ld\n", GetLastError()); + + ret = BeginPath(hdcMetafile); + ok(ret, "BeginPath error %ld\n", GetLastError()); + + ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx); + ok(ret, "ExtTextOut error %ld\n", GetLastError()); + + ret = EndPath(hdcMetafile); + ok(ret, "EndPath error %ld\n", GetLastError()); + + hMetafile = CloseEnhMetaFile(hdcMetafile); + ok(hMetafile != 0, "CloseEnhMetaFile error %ld\n", GetLastError()); + + /* this doesn't succeed yet: EMF has correct size, all EMF records + * are there, but their contents don't match for different reasons. + */ + if (compare_emf_bits(hMetafile, EMF_TEXTOUT_ON_PATH_BITS, sizeof(EMF_TEXTOUT_ON_PATH_BITS), + "emf_TextOut_on_path", TRUE) != 0) + { + dump_emf_bits(hMetafile, "emf_TextOut_on_path"); + dump_emf_records(hMetafile, "emf_TextOut_on_path"); + } + + ret = DeleteEnhMetaFile(hMetafile); + ok(ret, "DeleteEnhMetaFile error %ld\n", GetLastError()); + ret = ReleaseDC(hwnd, hdcDisplay); + ok(ret, "ReleaseDC error %ld\n", GetLastError()); + DestroyWindow(hwnd); +} + static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData) { LPMETAFILEPICT lpMFP = (LPMETAFILEPICT)lpData; @@ -451,7 +1166,10 @@ static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETAREC * until a record is played which actually outputs something */ PlayEnhMetaFileRecord(hdc, lpHTable, lpEMFR, nObj); LPtoDP(hdc, mapping, 2); - trace("Meta record: iType = %ld, (%ld,%ld)-(%ld,%ld)\n", lpEMFR->iType, mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y); + trace("Meta record: iType %ld, nSize %ld, (%ld,%ld)-(%ld,%ld)\n", + lpEMFR->iType, lpEMFR->nSize, + mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y); + if (lpEMFR->iType == EMR_LINETO) { INT x0, y0, x1, y1; @@ -493,6 +1211,13 @@ static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp) ok(ret, "LineTo failed with error %ld\n", GetLastError()); hmf = CloseMetaFile(hdcMf); ok(hmf != NULL, "CloseMetaFile failed with error %ld\n", GetLastError()); + + if (compare_mf_bits (hmf, MF_LINETO_BITS, sizeof(MF_LINETO_BITS), "mf_LineTo") != 0) + { + dump_mf_bits(hmf, "mf_LineTo"); + EnumMetaFile(0, hmf, mf_enum_proc, 0); + } + size = GetMetaFileBitsEx(hmf, 0, NULL); ok(size, "GetMetaFileBitsEx failed with error %ld\n", GetLastError()); pBits = HeapAlloc(GetProcessHeap(), 0, size); @@ -514,7 +1239,16 @@ static void test_mf_conversions(void) mfp.yExt = 100; mfp.hMF = NULL; hemf = create_converted_emf(&mfp); + + if (compare_emf_bits(hemf, EMF_LINETO_MM_ANISOTROPIC_BITS, sizeof(EMF_LINETO_MM_ANISOTROPIC_BITS), + "emf_LineTo MM_ANISOTROPIC", TRUE) != 0) + { + dump_emf_bits(hemf, "emf_LineTo MM_ANISOTROPIC"); + dump_emf_records(hemf, "emf_LineTo MM_ANISOTROPIC"); + } + EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect); + DeleteEnhMetaFile(hemf); DeleteDC(hdcOffscreen); } @@ -530,7 +1264,16 @@ static void test_mf_conversions(void) mfp.yExt = 0; mfp.hMF = NULL; hemf = create_converted_emf(&mfp); + + if (compare_emf_bits(hemf, EMF_LINETO_MM_TEXT_BITS, sizeof(EMF_LINETO_MM_TEXT_BITS), + "emf_LineTo MM_TEXT", TRUE) != 0) + { + dump_emf_bits(hemf, "emf_LineTo MM_TEXT"); + dump_emf_records(hemf, "emf_LineTo MM_TEXT"); + } + EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect); + DeleteEnhMetaFile(hemf); DeleteDC(hdcOffscreen); } @@ -541,12 +1284,232 @@ static void test_mf_conversions(void) HENHMETAFILE hemf; RECT rect = { 0, 0, 100, 100 }; hemf = create_converted_emf(NULL); + + if (compare_emf_bits(hemf, EMF_LINETO_BITS, sizeof(EMF_LINETO_BITS), + "emf_LineTo NULL", TRUE) != 0) + { + dump_emf_bits(hemf, "emf_LineTo NULL"); + dump_emf_records(hemf, "emf_LineTo NULL"); + } + EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, NULL, &rect); + DeleteEnhMetaFile(hemf); DeleteDC(hdcOffscreen); } } +static BOOL getConvertedFrameAndBounds(UINT buffer_size, BYTE * buffer, BOOL mfpIsNull, + LONG mm, LONG xExt, LONG yExt, + RECTL * rclBounds, RECTL * rclFrame) +{ + METAFILEPICT mfp; + METAFILEPICT * mfpPtr = NULL; + HENHMETAFILE emf; + ENHMETAHEADER header; + UINT res; + + if (!mfpIsNull) + { + mfp.mm = mm; + mfp.xExt = xExt; + mfp.yExt = yExt; + mfpPtr = &mfp; + } + + emf = SetWinMetaFileBits(buffer_size, buffer, NULL, mfpPtr); + ok(emf != NULL, "SetWinMetaFileBits failed\n"); + if (!emf) return FALSE; + res = GetEnhMetaFileHeader(emf, sizeof(header), &header); + ok(res != 0, "GetEnhMetaHeader failed\n"); + DeleteEnhMetaFile(emf); + if (!res) return FALSE; + + *rclBounds = header.rclBounds; + *rclFrame = header.rclFrame; + return TRUE; +} + +static void checkConvertedFrameAndBounds(UINT buffer_size, BYTE * buffer, BOOL mfpIsNull, + LONG mm, LONG xExt, LONG yExt, + RECTL * rclBoundsExpected, RECTL * rclFrameExpected) +{ + RECTL rclBounds, rclFrame; + + if (getConvertedFrameAndBounds(buffer_size, buffer, mfpIsNull, mm, xExt, yExt, &rclBounds, &rclFrame)) + { + const char * msg; + char buf[64]; + + if (mfpIsNull) + { + msg = "mfp == NULL"; + } + else + { + const char * mm_str; + switch (mm) + { + case MM_ANISOTROPIC: mm_str = "MM_ANISOTROPIC"; break; + case MM_ISOTROPIC: mm_str = "MM_ISOTROPIC"; break; + default: mm_str = "Unexpected"; + } + sprintf(buf, "mm=%s, xExt=%ld, yExt=%ld", mm_str, xExt, yExt); + msg = buf; + } + + ok(rclBounds.left == rclBoundsExpected->left, "rclBounds.left: Expected %ld, got %ld (%s)\n", rclBoundsExpected->left, rclBounds.left, msg); + ok(rclBounds.top == rclBoundsExpected->top, "rclBounds.top: Expected %ld, got %ld (%s)\n", rclBoundsExpected->top, rclBounds.top, msg); + ok(rclBounds.right == rclBoundsExpected->right, "rclBounds.right: Expected %ld, got %ld (%s)\n", rclBoundsExpected->right, rclBounds.right, msg); + ok(rclBounds.bottom == rclBoundsExpected->bottom, "rclBounds.bottom: Expected %ld, got %ld (%s)\n", rclBoundsExpected->bottom, rclBounds.bottom, msg); + ok(rclFrame.left == rclFrameExpected->left, "rclFrame.left: Expected %ld, got %ld (%s)\n", rclFrameExpected->left, rclFrame.left, msg); + ok(rclFrame.top == rclFrameExpected->top, "rclFrame.top: Expected %ld, got %ld (%s)\n", rclFrameExpected->top, rclFrame.top, msg); + ok(rclFrame.right == rclFrameExpected->right, "rclFrame.right: Expected %ld, got %ld (%s)\n", rclFrameExpected->right, rclFrame.right, msg); + ok(rclFrame.bottom == rclFrameExpected->bottom, "rclFrame.bottom: Expected %ld, got %ld (%s)\n", rclFrameExpected->bottom, rclFrame.bottom, msg); + } +} + +static void test_SetWinMetaFileBits(void) +{ + HMETAFILE wmf; + HDC wmfDC; + BYTE * buffer; + UINT buffer_size; + RECT rect; + UINT res; + RECTL rclBoundsAnisotropic, rclFrameAnisotropic; + RECTL rclBoundsIsotropic, rclFrameIsotropic; + RECTL rclBounds, rclFrame; + HDC dc; + LONG diffx, diffy; + + wmfDC = CreateMetaFile(NULL); + ok(wmfDC != NULL, "CreateMetaFile failed\n"); + if (!wmfDC) return; + + SetWindowExtEx(wmfDC, 100, 100, NULL); + rect.left = rect.top = 0; + rect.right = rect.bottom = 50; + FillRect(wmfDC, &rect, GetStockObject(BLACK_BRUSH)); + wmf = CloseMetaFile(wmfDC); + ok(wmf != NULL, "Metafile creation failed\n"); + if (!wmf) return; + + buffer_size = GetMetaFileBitsEx(wmf, 0, NULL); + ok(buffer_size != 0, "GetMetaFileBitsEx failed\n"); + if (buffer_size == 0) + { + DeleteMetaFile(wmf); + return; + } + + buffer = (BYTE *)HeapAlloc(GetProcessHeap(), 0, buffer_size); + ok(buffer != NULL, "HeapAlloc failed\n"); + if (!buffer) + { + DeleteMetaFile(wmf); + return; + } + + res = GetMetaFileBitsEx(wmf, buffer_size, buffer); + ok(res == buffer_size, "GetMetaFileBitsEx failed\n"); + DeleteMetaFile(wmf); + if (res != buffer_size) + { + HeapFree(GetProcessHeap(), 0, buffer); + return; + } + + /* Get the reference bounds and frame */ + getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 0, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic); + getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 0, 0, &rclBoundsIsotropic, &rclFrameIsotropic); + + ok(rclBoundsAnisotropic.left == 0 && rclBoundsAnisotropic.top == 0 && + rclBoundsIsotropic.left == 0 && rclBoundsIsotropic.top == 0, + "SetWinMetaFileBits: Reference bounds: Left and top bound must be zero\n"); + + ok(rclBoundsAnisotropic.right >= rclBoundsIsotropic.right, "SetWinMetaFileBits: Reference bounds: Invalid right bound\n"); + ok(rclBoundsAnisotropic.bottom >= rclBoundsIsotropic.bottom, "SetWinMetaFileBits: Reference bounds: Invalid bottom bound\n"); + diffx = rclBoundsIsotropic.right - rclBoundsIsotropic.bottom; + if (diffx < 0) diffx = -diffx; + ok(diffx <= 1, "SetWinMetaFileBits (MM_ISOTROPIC): Reference bounds are not isotropic\n"); + + dc = CreateCompatibleDC(NULL); + todo_wine + { + ok(rclBoundsAnisotropic.right == GetDeviceCaps(dc, HORZRES) / 2 - 1 && + rclBoundsAnisotropic.bottom == GetDeviceCaps(dc, VERTRES) / 2 - 1, + "SetWinMetaFileBits (MM_ANISOTROPIC): Reference bounds: The whole device surface must be used (%dx%d), but got (%ldx%ld)\n", + GetDeviceCaps(dc, HORZRES) / 2 - 1, GetDeviceCaps(dc, VERTRES) / 2 - 1, rclBoundsAnisotropic.right, rclBoundsAnisotropic.bottom); + } + + /* Allow 1 mm difference (rounding errors) */ + diffx = rclFrameAnisotropic.right / 100 - GetDeviceCaps(dc, HORZSIZE) / 2; + diffy = rclFrameAnisotropic.bottom / 100 - GetDeviceCaps(dc, VERTSIZE) / 2; + if (diffx < 0) diffx = -diffx; + if (diffy < 0) diffy = -diffy; + todo_wine + { + ok(diffx <= 1 && diffy <= 1, + "SetWinMetaFileBits (MM_ANISOTROPIC): Reference frame: The whole device surface must be used (%dx%d), but got (%ldx%ld)\n", + GetDeviceCaps(dc, HORZSIZE) / 2, GetDeviceCaps(dc, VERTSIZE) / 2, rclFrameAnisotropic.right / 100, rclFrameAnisotropic.bottom / 100); + } + DeleteDC(dc); + + /* If the METAFILEPICT pointer is NULL, the MM_ANISOTROPIC mapping mode and the whole device surface are used */ + checkConvertedFrameAndBounds(buffer_size, buffer, TRUE, 0, 0, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic); + + /* If xExt or yExt is zero or negative, the whole device surface is used */ + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 10000, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 10000, 0, &rclBoundsIsotropic, &rclFrameIsotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 0, 10000, &rclBoundsAnisotropic, &rclFrameAnisotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 0, 10000, &rclBoundsIsotropic, &rclFrameIsotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, -10000, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, -10000, 0, &rclBoundsIsotropic, &rclFrameIsotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 0, -10000, &rclBoundsAnisotropic, &rclFrameAnisotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 0, -10000, &rclBoundsIsotropic, &rclFrameIsotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, -10000, 10000, &rclBoundsAnisotropic, &rclFrameAnisotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, -10000, 10000, &rclBoundsIsotropic, &rclFrameIsotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 10000, -10000, &rclBoundsAnisotropic, &rclFrameAnisotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 10000, -10000, &rclBoundsIsotropic, &rclFrameIsotropic); + + /* MSDN says that negative xExt and yExt values specify a ratio. + Check that this is wrong and the whole device surface is used */ + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, -1000, -100, &rclBoundsAnisotropic, &rclFrameAnisotropic); + checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, -1000, -100, &rclBoundsIsotropic, &rclFrameIsotropic); + + /* Ordinary conversions */ + + if (getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 30000, 20000, &rclBounds, &rclFrame)) + { + ok(rclFrame.left == 0 && rclFrame.top == 0 && rclFrame.right == 30000 && rclFrame.bottom == 20000, + "SetWinMetaFileBits (MM_ANISOTROPIC): rclFrame contains invalid values\n"); + ok(rclBounds.left == 0 && rclBounds.top == 0 && rclBounds.right > rclBounds.bottom, + "SetWinMetaFileBits (MM_ANISOTROPIC): rclBounds contains invalid values\n"); + } + + if (getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 30000, 20000, &rclBounds, &rclFrame)) + { + ok(rclFrame.left == 0 && rclFrame.top == 0 && rclFrame.right == 30000 && rclFrame.bottom == 20000, + "SetWinMetaFileBits (MM_ISOTROPIC): rclFrame contains invalid values\n"); + ok(rclBounds.left == 0 && rclBounds.top == 0, + "SetWinMetaFileBits (MM_ISOTROPIC): rclBounds contains invalid values\n"); + + /* Wine has a rounding error */ + diffx = rclBounds.right - rclBounds.bottom; + if (diffx < 0) diffx = -diffx; + ok(diffx <= 1, "SetWinMetaFileBits (MM_ISOTROPIC): rclBounds is not isotropic\n"); + } + + if (getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_HIMETRIC, 30000, 20000, &rclBounds, &rclFrame)) + { + ok(rclFrame.right - rclFrame.left != 30000 && rclFrame.bottom - rclFrame.top != 20000, + "SetWinMetaFileBits: xExt and yExt must be ignored for mapping modes other than MM_ANISOTROPIC and MM_ISOTROPIC\n"); + } + + HeapFree(GetProcessHeap(), 0, buffer); +} + static BOOL (WINAPI *pGdiIsMetaPrintDC)(HDC); static BOOL (WINAPI *pGdiIsMetaFileDC)(HDC); static BOOL (WINAPI *pGdiIsPlayMetafileDC)(HDC); @@ -597,16 +1560,24 @@ static void test_gdiis(void) START_TEST(metafile) { + init_function_pointers(); + /* For enhanced metafiles (enhmfdrv) */ test_ExtTextOut(); + test_SaveDC(); /* For win-format metafiles (mfdrv) */ test_mf_Blank(); test_mf_Graphics(); test_mf_PatternBrush(); + test_CopyMetaFile(); + test_SetMetaFileBits(); + test_mf_ExtTextOut_on_path(); + test_emf_ExtTextOut_on_path(); /* For metafile conversions */ test_mf_conversions(); + test_SetWinMetaFileBits(); test_gdiis(); } diff --git a/reactos/regtests/winetests/gdi32/testlist.c b/reactos/regtests/winetests/gdi32/testlist.c index cf5319b1b99..875e34863a8 100644 --- a/reactos/regtests/winetests/gdi32/testlist.c +++ b/reactos/regtests/winetests/gdi32/testlist.c @@ -22,9 +22,9 @@ const struct test winetest_testlist[] = { { "bitmap", func_bitmap }, { "brush", func_brush }, -// { "clipping", func_clipping }, -// { "dc", func_dc }, -// { "font", func_font }, + { "clipping", func_clipping }, + { "dc", func_dc }, + { "font", func_font }, { "gdiobj", func_gdiobj }, // { "generated", func_generated }, // { "mapping", func_mapping }, From 7c4cca987087814ed8f68725e56edf896ae12879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 24 Sep 2006 10:39:43 +0000 Subject: [PATCH 325/488] Add a filter command in KDBG, which is a wrapper around NtSetDebugFilterState/NtSetDebugFilterState. svn path=/trunk/; revision=24250 --- reactos/ntoskrnl/kdbg/kdb_cli.c | 80 ++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/kdbg/kdb_cli.c b/reactos/ntoskrnl/kdbg/kdb_cli.c index 2eaf2647da7..de087a15813 100644 --- a/reactos/ntoskrnl/kdbg/kdb_cli.c +++ b/reactos/ntoskrnl/kdbg/kdb_cli.c @@ -16,8 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * +/* * PROJECT: ReactOS kernel * FILE: ntoskrnl/dbg/kdb_cli.c * PURPOSE: Kernel debugger command line interface @@ -78,6 +77,7 @@ STATIC BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]); STATIC BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]); STATIC BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]); +STATIC BOOLEAN KdbpCmdFilter(ULONG Argc, PCHAR Argv[]); STATIC BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[]); STATIC BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[]); @@ -146,6 +146,7 @@ STATIC CONST struct /* Others */ { NULL, NULL, "Others", NULL }, { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck }, + { "filter", "filter [componentid] [error|warning|trace|info|level] [on|off]", "Enable/disable debug channels", KdbpCmdFilter }, { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet }, { "help", "help", "Display help screen.", KdbpCmdHelp } }; @@ -244,6 +245,81 @@ KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[]) return TRUE; } +/*!\brief Display list of active debug channels + */ +STATIC BOOLEAN +KdbpCmdFilter(ULONG Argc, PCHAR Argv[]) +{ + ULONG ComponentId, Level; + BOOLEAN State; + PCHAR pend; + + if (Argc < 2) + { + KdbpPrint("filter: component id argument required!\n"); + return TRUE; + } + ComponentId = strtoul(Argv[1], &pend, 0); + if (Argv[1] == pend) + { + KdbpPrint("filter: '%s' is not a valid component id!\n", Argv[1]); + return TRUE; + } + + if (Argc < 3) + { + KdbpPrint("filter: level argument required!\n"); + return TRUE; + } + if (_stricmp(Argv[2], "error") == 0) + Level = DPFLTR_ERROR_LEVEL; + else if (_stricmp(Argv[2], "warning") == 0) + Level = DPFLTR_WARNING_LEVEL; + else if (_stricmp(Argv[2], "trace") == 0) + Level = DPFLTR_TRACE_LEVEL; + else if (_stricmp(Argv[2], "info") == 0) + Level = DPFLTR_INFO_LEVEL; + else + { + Level = strtoul(Argv[2], &pend, 0); + if (Argv[2] == pend) + { + KdbpPrint("filter: '%s' is not a valid level!\n", Argv[2]); + return TRUE; + } + } + if (Level < 31) + { + /* Interpret it as a bit shift */ + Level = 1 << Level; + } + + if (Argc < 4) + { + /* Display the state of the filter */ + if (NtQueryDebugFilterState(ComponentId, Level)) + KdbpPrint("Debug messages are enabled.\n"); + else + KdbpPrint("Debug messages are disabled.\n"); + return TRUE; + } + else + { + /* Set the filter state */ + if (_stricmp(Argv[3], "on") == 0) + State = TRUE; + else if (_stricmp(Argv[3], "off") == 0) + State = FALSE; + else + { + KdbpPrint("filter: '%s' is not a valid state!\n", Argv[3]); + return TRUE; + } + + return NT_SUCCESS(NtSetDebugFilterState(ComponentId, Level, State)); + } +} + /*!\brief Disassembles 10 instructions at eip or given address or * displays 16 dwords from memory at given address. */ From e84a6d47b1d30188d77748fc339c28fcf84e61d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 24 Sep 2006 11:08:27 +0000 Subject: [PATCH 326/488] [FORMATTING] Replace spaces by tabs svn path=/trunk/; revision=24251 --- reactos/base/system/format/format.c | 79 ++++++++++++++--------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/reactos/base/system/format/format.c b/reactos/base/system/format/format.c index 1bdf1f25778..ea4de4d6e84 100755 --- a/reactos/base/system/format/format.c +++ b/reactos/base/system/format/format.c @@ -15,22 +15,22 @@ BOOL Error = FALSE; // switches BOOL QuickFormat = FALSE; -DWORD ClusterSize = 0; +DWORD ClusterSize = 0; BOOL CompressDrive = FALSE; -BOOL GotALabel = FALSE; -LPTSTR Label = _T(""); -LPTSTR Drive = NULL; -LPTSTR Format = _T("FAT"); +BOOL GotALabel = FALSE; +LPTSTR Label = _T(""); +LPTSTR Drive = NULL; +LPTSTR Format = _T("FAT"); -TCHAR RootDirectory[MAX_PATH]; -TCHAR LabelString[12]; +TCHAR RootDirectory[MAX_PATH]; +TCHAR LabelString[12]; // // Size array // typedef struct { - TCHAR SizeString[16]; - DWORD ClusterSize; + TCHAR SizeString[16]; + DWORD ClusterSize; } SIZEDEFINITION, *PSIZEDEFINITION; SIZEDEFINITION LegalSizes[] = { @@ -57,7 +57,7 @@ SIZEDEFINITION LegalSizes[] = { //---------------------------------------------------------------------- static VOID PrintWin32Error( LPTSTR Message, DWORD ErrorCode ) { - LPTSTR lpMsgBuf; + LPTSTR lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, ErrorCode, @@ -169,9 +169,10 @@ static int ParseCommandLine( int argc, TCHAR *argv[] ) // //---------------------------------------------------------------------- BOOLEAN STDCALL -FormatExCallback (CALLBACKCOMMAND Command, - ULONG Modifier, - PVOID Argument) +FormatExCallback ( + CALLBACKCOMMAND Command, + ULONG Modifier, + PVOID Argument) { PDWORD percent; PTEXTOUTPUT output; @@ -185,8 +186,8 @@ FormatExCallback (CALLBACKCOMMAND Command, case PROGRESS: percent = (PDWORD) Argument; - LoadString( GetModuleHandle(NULL), STRING_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg, *percent); + LoadString( GetModuleHandle(NULL), STRING_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); + _tprintf(szMsg, *percent); break; case OUTPUT: @@ -199,7 +200,7 @@ FormatExCallback (CALLBACKCOMMAND Command, if( *status == FALSE ) { LoadString( GetModuleHandle(NULL), STRING_FORMAT_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf(szMsg); Error = TRUE; } break; @@ -217,7 +218,7 @@ FormatExCallback (CALLBACKCOMMAND Command, case UNKNOWND: case STRUCTUREPROGRESS: LoadString( GetModuleHandle(NULL), STRING_NO_SUPPORT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf(szMsg); return FALSE; } return TRUE; @@ -272,7 +273,7 @@ _tmain(int argc, TCHAR *argv[]) DWORD flags, maxComponent; ULARGE_INTEGER freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes; #ifndef UNICODE - WCHAR RootDirectoryW[MAX_PATH], FormatW[MAX_PATH], LabelW[MAX_PATH]; + WCHAR RootDirectoryW[MAX_PATH], FormatW[MAX_PATH], LabelW[MAX_PATH]; #endif TCHAR szMsg[RC_STRING_MAX_SIZE]; @@ -280,9 +281,8 @@ _tmain(int argc, TCHAR *argv[]) // Get function pointers // if( !LoadFMIFSEntryPoints()) { - LoadString( GetModuleHandle(NULL), STRING_FMIFS_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf(szMsg); return -1; } @@ -292,7 +292,7 @@ _tmain(int argc, TCHAR *argv[]) if( (badArg = ParseCommandLine( argc, argv ))) { LoadString( GetModuleHandle(NULL), STRING_UNKNOW_ARG, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg, argv[badArg] ); + _tprintf(szMsg, argv[badArg] ); Usage(argv[0]); return -1; @@ -304,7 +304,7 @@ _tmain(int argc, TCHAR *argv[]) if( !Drive ) { LoadString( GetModuleHandle(NULL), STRING_DRIVE_PARM, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf(szMsg); Usage( argv[0] ); return -1; @@ -321,14 +321,14 @@ _tmain(int argc, TCHAR *argv[]) driveType = GetDriveType( RootDirectory ); if( driveType == 0 ) { - LoadString( GetModuleHandle(NULL), STRING_ERROR_DRIVE_TYPE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); + LoadString( GetModuleHandle(NULL), STRING_ERROR_DRIVE_TYPE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); PrintWin32Error( szMsg, GetLastError()); return -1; } if( driveType != DRIVE_FIXED ) { LoadString( GetModuleHandle(NULL), STRING_INSERT_DISK, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg, RootDirectory[0] ); + _tprintf(szMsg, RootDirectory[0] ); _fgetts( input, sizeof(input)/2, stdin ); media = FMIFS_FLOPPY; @@ -357,7 +357,7 @@ _tmain(int argc, TCHAR *argv[]) return -1; } LoadString( GetModuleHandle(NULL), STRING_FILESYSTEM, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg, fileSystem ); + _tprintf(szMsg, fileSystem ); // // Make sure they want to do this @@ -369,7 +369,7 @@ _tmain(int argc, TCHAR *argv[]) while(1 ) { LoadString( GetModuleHandle(NULL), STRING_LABEL_NAME_EDIT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg, RootDirectory[0] ); + _tprintf(szMsg, RootDirectory[0] ); _fgetts( input, sizeof(input)/2, stdin ); input[ _tcslen( input ) - 1] = 0; @@ -378,21 +378,20 @@ _tmain(int argc, TCHAR *argv[]) break; } LoadString( GetModuleHandle(NULL), STRING_ERROR_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf(szMsg); } } while( 1 ) { LoadString( GetModuleHandle(NULL), STRING_YN_FORMAT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg, RootDirectory[0] ); + _tprintf(szMsg, RootDirectory[0] ); - LoadString( GetModuleHandle(NULL), STRING_YES_NO_FAQ, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - - if( _strnicmp(&input[0],&szMsg[0],1)) break; - if( _strnicmp(&input[0],&szMsg[1],1) ) { + if(_strnicmp(&input[0],&szMsg[0],1)) break; + + if(_strnicmp(&input[0],&szMsg[1],1) ) { _tprintf(_T("\n")); return 0; @@ -417,7 +416,7 @@ _tmain(int argc, TCHAR *argv[]) _tprintf(_T("%s %.1fM\n"),szMsg, ((float)(LONGLONG)totalNumberOfBytes.QuadPart)/(float)(1024.0*1024.0)); } - } else { + } else { LoadString( GetModuleHandle(NULL), STRING_FAST_FMT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); if( totalNumberOfBytes.QuadPart > 1024*1024*10 ) { @@ -430,7 +429,7 @@ _tmain(int argc, TCHAR *argv[]) ((float)(LONGLONG)totalNumberOfBytes.QuadPart)/(float)(1024.0*1024.0)); } LoadString( GetModuleHandle(NULL), STRING_CREATE_FSYS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf(szMsg); } // @@ -448,7 +447,7 @@ _tmain(int argc, TCHAR *argv[]) #endif if( Error ) return -1; LoadString( GetModuleHandle(NULL), STRING_FMT_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf(szMsg); // // Enable compression if desired @@ -463,7 +462,7 @@ _tmain(int argc, TCHAR *argv[]) #endif LoadString( GetModuleHandle(NULL), STRING_VOL_COMPRESS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf(szMsg); } } @@ -473,7 +472,7 @@ _tmain(int argc, TCHAR *argv[]) if( !GotALabel ) { LoadString( GetModuleHandle(NULL), STRING_ENTER_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf(szMsg); _fgetts( input, sizeof(LabelString)/2, stdin ); input[ _tcslen(input)-1] = 0; @@ -502,14 +501,14 @@ _tmain(int argc, TCHAR *argv[]) &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes )) { - + LoadString( 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); - _tprintf(szMsg, totalNumberOfBytes.QuadPart, totalNumberOfFreeBytes.QuadPart ); + _tprintf(szMsg, totalNumberOfBytes.QuadPart, totalNumberOfFreeBytes.QuadPart ); // // Get the drive's serial number @@ -524,7 +523,7 @@ _tmain(int argc, TCHAR *argv[]) return -1; } LoadString( GetModuleHandle(NULL), STRING_SERIAL_NUMBER, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg, (unsigned int)(serialNumber >> 16), + _tprintf(szMsg, (unsigned int)(serialNumber >> 16), (unsigned int)(serialNumber & 0xFFFF) ); return 0; From c492ac0ccc35047a23326463722990aba696fcf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 24 Sep 2006 11:55:58 +0000 Subject: [PATCH 327/488] Implement QueryAvailableFileSystemFormat and SetLabel in fmifs.dll Fix a few prototypes svn path=/trunk/; revision=24252 --- reactos/dll/win32/fmifs/fmifs.def | 6 +- reactos/dll/win32/fmifs/fmifs.rbuild | 2 +- reactos/dll/win32/fmifs/label.c | 18 ----- reactos/dll/win32/fmifs/media.c | 9 ++- reactos/dll/win32/fmifs/precomp.h | 92 +++++++++++----------- reactos/dll/win32/fmifs/query.c | 44 +++++++++++ reactos/include/reactos/libs/fmifs/fmifs.h | 33 +++++--- 7 files changed, 124 insertions(+), 80 deletions(-) delete mode 100644 reactos/dll/win32/fmifs/label.c create mode 100644 reactos/dll/win32/fmifs/query.c diff --git a/reactos/dll/win32/fmifs/fmifs.def b/reactos/dll/win32/fmifs/fmifs.def index 2391f1f56fb..e11b477941c 100644 --- a/reactos/dll/win32/fmifs/fmifs.def +++ b/reactos/dll/win32/fmifs/fmifs.def @@ -22,10 +22,10 @@ Format@0 FormatEx@28 ;FormatEx2 InitializeFmIfs@12 -;QueryAvailableFileSystemFormat +QueryAvailableFileSystemFormat@20 ;QueryDeviceInformation ;QueryDeviceInformationByHandle ;QueryFileSystemName ;QueryLatestFileSystemVersion -QuerySupportedMedia@0 -SetLabel@0 +QuerySupportedMedia@16 +SetLabel@8=KERNEL32.SetVolumeLabelW diff --git a/reactos/dll/win32/fmifs/fmifs.rbuild b/reactos/dll/win32/fmifs/fmifs.rbuild index d4498926012..6934bd39175 100644 --- a/reactos/dll/win32/fmifs/fmifs.rbuild +++ b/reactos/dll/win32/fmifs/fmifs.rbuild @@ -12,8 +12,8 @@ extend.c format.c init.c - label.c media.c + query.c fmifs.rc precomp.h diff --git a/reactos/dll/win32/fmifs/label.c b/reactos/dll/win32/fmifs/label.c deleted file mode 100644 index e4b0ee48e10..00000000000 --- a/reactos/dll/win32/fmifs/label.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: File Management IFS Utility functions - * FILE: reactos/dll/win32/fmifs/label.c - * PURPOSE: Set volume label - * - * PROGRAMMERS: (none) - */ - -#include "precomp.h" - -/* FMIFS.10 */ -VOID NTAPI -SetLabel (VOID) -{ -} - -/* EOF */ diff --git a/reactos/dll/win32/fmifs/media.c b/reactos/dll/win32/fmifs/media.c index 3837c99b2ff..0cdb32da7ba 100644 --- a/reactos/dll/win32/fmifs/media.c +++ b/reactos/dll/win32/fmifs/media.c @@ -10,9 +10,14 @@ #include "precomp.h" /* FMIFS.9 */ -VOID NTAPI -QuerySupportedMedia(VOID) +BOOL NTAPI +QuerySupportedMedia( + IN PWCHAR DriveRoot, + OUT FMIFS_MEDIA_FLAG *CurrentMedia OPTIONAL, + IN ULONG Unknown3, + OUT PULONG Unknown4) { + return FALSE; } /* EOF */ diff --git a/reactos/dll/win32/fmifs/precomp.h b/reactos/dll/win32/fmifs/precomp.h index 4e8d37713aa..647ce1c04f8 100644 --- a/reactos/dll/win32/fmifs/precomp.h +++ b/reactos/dll/win32/fmifs/precomp.h @@ -1,46 +1,46 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: File Management IFS Utility functions - * FILE: reactos/dll/win32/fmifs/precomp.h - * PURPOSE: Win32 FMIFS API Library Header - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#define WIN32_NO_STATUS -#define NTOS_MODE_USER -#define UNICODE -#define _UNICODE - -/* PSDK/NDK Headers */ -#include -#include - -/* FMIFS Public Header */ -#include - -/* VFATLIB Public Header */ -#include - -extern LIST_ENTRY ProviderListHead; - -typedef struct _IFS_PROVIDER -{ - LIST_ENTRY ListEntry; - - CHKDSKEX ChkdskEx; - PVOID Extend; - FORMATEX FormatEx; - - WCHAR Name[1]; -} IFS_PROVIDER, *PIFS_PROVIDER; - -/* init.c */ -PIFS_PROVIDER -GetProvider( - IN PWCHAR FileSytem); - -/* EOF */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/precomp.h + * PURPOSE: Win32 FMIFS API Library Header + * + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * Hervé Poussineau (hpoussin@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#define WIN32_NO_STATUS +#define NTOS_MODE_USER +#define UNICODE +#define _UNICODE + +/* PSDK/NDK Headers */ +#include +#include + +/* FMIFS Public Header */ +#include + +/* VFATLIB Public Header */ +#include + +extern LIST_ENTRY ProviderListHead; + +typedef struct _IFS_PROVIDER +{ + LIST_ENTRY ListEntry; + + CHKDSKEX ChkdskEx; + PVOID Extend; + FORMATEX FormatEx; + + WCHAR Name[1]; +} IFS_PROVIDER, *PIFS_PROVIDER; + +/* init.c */ +PIFS_PROVIDER +GetProvider( + IN PWCHAR FileSytem); + +/* EOF */ diff --git a/reactos/dll/win32/fmifs/query.c b/reactos/dll/win32/fmifs/query.c new file mode 100644 index 00000000000..93cfa8e00c9 --- /dev/null +++ b/reactos/dll/win32/fmifs/query.c @@ -0,0 +1,44 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: File Management IFS Utility functions + * FILE: reactos/dll/win32/fmifs/query.c + * PURPOSE: Query volume information + * + * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + */ + +#include "precomp.h" + +BOOLEAN NTAPI +QueryAvailableFileSystemFormat( + IN DWORD Index, + IN OUT PWCHAR FileSystem, /* FIXME: Probably one minimal size is mandatory, but which one? */ + OUT UCHAR* Major, + OUT UCHAR* Minor, + OUT BOOLEAN* LastestVersion) +{ + PLIST_ENTRY ListEntry; + PIFS_PROVIDER Provider; + + if (!FileSystem || !Major ||!Minor ||!LastestVersion) + return FALSE; + + ListEntry = ProviderListHead.Flink; + while (TRUE) + { + if (ListEntry == &ProviderListHead) + return FALSE; + if (Index == 0) + break; + ListEntry = ListEntry->Flink; + Index--; + } + + Provider = CONTAINING_RECORD(ListEntry, IFS_PROVIDER, ListEntry); + wcscpy(FileSystem, Provider->Name); + *Major = 0; /* FIXME */ + *Minor = 0; /* FIXME */ + *LastestVersion = TRUE; /* FIXME */ + + return TRUE; +} diff --git a/reactos/include/reactos/libs/fmifs/fmifs.h b/reactos/include/reactos/libs/fmifs/fmifs.h index 36a36c5fb0d..2296bee656b 100644 --- a/reactos/include/reactos/libs/fmifs/fmifs.h +++ b/reactos/include/reactos/libs/fmifs/fmifs.h @@ -43,7 +43,7 @@ typedef enum FMIFS_FLOPPY, FMIFS_UNKNOWN9, FMIFS_UNKNOWN10, - FMIFS_UNKNOWN11, + FMIFS_REMOVABLE, FMIFS_HARDDISK, FMIFS_UNKNOWN13, FMIFS_UNKNOWN14, @@ -140,10 +140,10 @@ FormatEx( BOOLEAN NTAPI QueryAvailableFileSystemFormat( IN DWORD Index, - IN OUT PWCHAR FileSystem OPTIONAL, /* FIXME: Probably one minimal size is mandatory, but which one? */ - OUT UCHAR* Major OPTIONAL, - OUT UCHAR* Minor OPTIONAL, - OUT BOOLEAN* LastestVersion OPTIONAL); + IN OUT PWCHAR FileSystem, /* FIXME: Probably one minimal size is mandatory, but which one? */ + OUT UCHAR* Major, + OUT UCHAR* Minor, + OUT BOOLEAN* LastestVersion); BOOL NTAPI QueryDeviceInformation( @@ -151,18 +151,31 @@ QueryDeviceInformation( OUT ULONG* Buffer, /* That is probably some 4-bytes structure */ IN ULONG BufferSize); /* 4 */ +BOOL NTAPI +QueryFileSystemName( + IN PWCHAR DriveRoot, + OUT PWCHAR FileSystem OPTIONAL, /* FIXME: Probably one minimal size is mandatory, but which one? */ + OUT UCHAR* Unknown2 OPTIONAL, /* Always 0? */ + OUT UCHAR* Unknown3 OPTIONAL, /* Always 0? */ + OUT ULONG* Unknown4 OPTIONAL); /* Always 0? */ + BOOLEAN NTAPI QueryLatestFileSystemVersion( IN PWCHAR FileSystem, OUT UCHAR* Major OPTIONAL, OUT UCHAR* Minor OPTIONAL); -/*ULONG NTAPI +BOOL NTAPI QuerySupportedMedia( - PVOID Unknown1, - ULONG Unknown2, - ULONG Unknown3, - ULONG Unknown4);*/ + IN PWCHAR DriveRoot, + OUT FMIFS_MEDIA_FLAG *CurrentMedia OPTIONAL, + IN ULONG Unknown3, + OUT PULONG Unknown4); /* Always 1? */ + +BOOL NTAPI +SetLabel( + IN PWCHAR DriveRoot, + IN PWCHAR Label); /* Functions provided by u*.dll */ From 9cea0fdddebe79aa1b34ce8e99f39b1f0845b31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 24 Sep 2006 12:50:51 +0000 Subject: [PATCH 328/488] Display available file systems in usage screen svn path=/trunk/; revision=24253 --- reactos/base/system/format/De.rc | 2 +- reactos/base/system/format/En.rc | 2 +- reactos/base/system/format/Fr.rc | 8 ++-- reactos/base/system/format/Hu.rc | 2 +- reactos/base/system/format/Ja.rc | 2 +- reactos/base/system/format/No.rc | 2 +- reactos/base/system/format/format.c | 67 ++++++++++++++++++++++------- 7 files changed, 61 insertions(+), 24 deletions(-) diff --git a/reactos/base/system/format/De.rc b/reactos/base/system/format/De.rc index c018dba8fd7..53bce37afd7 100644 --- a/reactos/base/system/format/De.rc +++ b/reactos/base/system/format/De.rc @@ -14,7 +14,7 @@ STRINGTABLE DISCARDABLE STRING_HELP, "Usage: %S drive: [-FS:file-system] [-V:label] [-Q] [-A:size] [-C]\n\n\ [Datenträger:] Legt das Laufwerk zum Formatieren fest.\n\ - -FS:file-system Legt das Dateisystem fest (z.B. FAT).\n\ + -FS:file-system Legt das Dateisystem fest (%s).\n\ -V:label Legt den Datentraegernamen fest.\n\ -Q Fuehre Schnellformatierung durch.\n\ -A:size Ueberschreibe Anweisung fuer Standartblockgroesse. Es wird dringend\n\ diff --git a/reactos/base/system/format/En.rc b/reactos/base/system/format/En.rc index 039ee42003d..3cfc9dbdd9a 100644 --- a/reactos/base/system/format/En.rc +++ b/reactos/base/system/format/En.rc @@ -9,7 +9,7 @@ STRINGTABLE DISCARDABLE { STRING_HELP, "Usage: %S drive: [-FS:file-system] [-V:label] [-Q] [-A:size] [-C]\n\n\ [drive:] Specifies the drive to format.\n\ - -FS:file-system Specifies the type of file system (e.g. FAT).\n\ + -FS:file-system Specifies the type of file system (%s).\n\ -V:label Specifies volume label.\n\ -Q Performs a quick format.\n\ -A:size Overrides the default allocation unit size. Default settings\n\ diff --git a/reactos/base/system/format/Fr.rc b/reactos/base/system/format/Fr.rc index f63b971e023..c687c41b8c5 100644 --- a/reactos/base/system/format/Fr.rc +++ b/reactos/base/system/format/Fr.rc @@ -12,11 +12,11 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { STRING_HELP, "Utilisation : %S disque: [-FS:systčme de fichier] [-V:nom] [-Q] [-A:taille] [-C]\n\n\ - [disque:] Indique le disque ŕ formater.\n\ - -FS:systčme de fichier Indique le type de systčme de fichier (p.e. FAT).\n\ - -V:nom Détermine le nom du disque.\n\ + [disque:] Indique le disque ŕ formater.\n\ + -FS:systčme de fichier Indique le type de systčme de fichier (%s).\n\ + -V:nom Détermine le nom du disque.\n\ -Q Effectue un formatage rapide.\n\ - -A:taille Force une taille pour les unités d'allocations. Les valeurs par défaut\n\ + -A:taille Force une taille pour les unités d'allocations. Les valeurs par défaut\n\ sont fortement recommandées pour une utilisation courante\n\ NTFS peut utiliser 512, 1024, 2048, 4096, 8192, 16K, 32K, 64K.\n\ FAT peut utiliser 8192, 16K, 32K, 64K, 128K, 256K.\n\ diff --git a/reactos/base/system/format/Hu.rc b/reactos/base/system/format/Hu.rc index d15faf7245a..e29b7906ff5 100644 --- a/reactos/base/system/format/Hu.rc +++ b/reactos/base/system/format/Hu.rc @@ -10,7 +10,7 @@ STRINGTABLE DISCARDABLE { STRING_HELP, "Használat: %S kötet: [-FS:állományrendszer] [-V:címke] [-Q] [-A:méret] [-C]\n\n\ [kötet:] A meghajtóbetűjelet adja meg (kettősponttal a végén).\n\ - -FS:állományrendszer Az állományrendszer típusát adja meg (pl.: FAT).\n\ + -FS:állományrendszer Az állományrendszer típusát adja meg (%s).\n\ -V:címke A Kötetcímke neve.\n\ -Q Gyorsformázást hajt végre.\n\ -A:méret Felülbírálja az alapértelmezett szektorcsoport-\n\ diff --git a/reactos/base/system/format/Ja.rc b/reactos/base/system/format/Ja.rc index 8778d48fbce..8b5e1ac1375 100644 --- a/reactos/base/system/format/Ja.rc +++ b/reactos/base/system/format/Ja.rc @@ -10,7 +10,7 @@ STRINGTABLE DISCARDABLE STRING_HELP, "Žg—p–@: %S h‰Cu: [-FS:t@C‹VXe€] [-V:‰x‹] [-Q] [-A:TCY] [-C]\n\n\ [h‰Cu:] tH[}bg‚·‚éh‰Cu‚đŽw’肵‚Ü‚·B\n\ -FS:t@C‹VXe€\n\ - t@C‹VXe€‚ĚŽí—Ţ‚đŽw’肵‚Ü‚· (—á: FAT)B\n\ + t@C‹VXe€‚ĚŽí—Ţ‚đŽw’肵‚Ü‚· (%s)B\n\ -V:‰x‹ {Š…[€ ‰x‹‚đŽw’肵‚Ü‚·B\n\ -Q NCbN tH[}bg‚đŽŔŤs‚µ‚Ü‚·B\n\ -A:TCY ‹K’č‚ĚAŤP[V‡“ †jbg TCY‚đŹăŹ‘‚«‚µ‚Ü‚·B\n\ diff --git a/reactos/base/system/format/No.rc b/reactos/base/system/format/No.rc index 198db869d33..8d71d4a4017 100644 --- a/reactos/base/system/format/No.rc +++ b/reactos/base/system/format/No.rc @@ -9,7 +9,7 @@ STRINGTABLE DISCARDABLE { STRING_HELP, "bruk: %S stasjon: [-FS:fil-system] [-V:merke] [-Q] [-A:střrrelse] [-C]\n\n\ [stasjon:] Spesifisere stasjon til formater.\n\ - -FS:file-system Spesifisere typen av fil system (f.eks. FAT).\n\ + -FS:file-system Spesifisere typen av fil system (%s).\n\ -V:merke Spesifisere volum merke.\n\ -Q Fullfřre en rask formatering.\n\ -A:střrrelse Dominerende standard fordeling enhet střrrelse. Standard innstilling\n\ diff --git a/reactos/base/system/format/format.c b/reactos/base/system/format/format.c index ea4de4d6e84..3e970647296 100755 --- a/reactos/base/system/format/format.c +++ b/reactos/base/system/format/format.c @@ -69,21 +69,6 @@ static VOID PrintWin32Error( LPTSTR Message, DWORD ErrorCode ) } -//---------------------------------------------------------------------- -// -// Usage -// -// Tell the user how to use the program -// -//---------------------------------------------------------------------- -static VOID Usage( LPTSTR ProgramName ) -{ - TCHAR szMsg[RC_STRING_MAX_SIZE]; - LoadString( GetModuleHandle(NULL), STRING_HELP, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg, ProgramName); -} - - //---------------------------------------------------------------------- // // ParseCommandLine @@ -245,9 +230,61 @@ BOOLEAN LoadFMIFSEntryPoints() return FALSE; } + + if( !((void *) GetProcAddress( hFmifs, + "QueryAvailableFileSystemFormat" )) ) { + + return FALSE; + } + return TRUE; } + +//---------------------------------------------------------------------- +// +// Usage +// +// Tell the user how to use the program +// +//---------------------------------------------------------------------- +static VOID Usage( LPTSTR ProgramName ) +{ + TCHAR szMsg[RC_STRING_MAX_SIZE]; + TCHAR szFormats[MAX_PATH]; +#ifndef UNICODE + TCHAR szFormatA[MAX_PATH]; +#endif + WCHAR szFormatW[MAX_PATH]; + DWORD Index = 0; + BYTE dummy; + BOOLEAN lastestVersion; + + LoadString( GetModuleHandle(NULL), STRING_HELP, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); + if (!LoadFMIFSEntryPoints()) + { + _tprintf(szMsg, ProgramName, ""); + return; + } + + szFormats[0] = 0; + while (QueryAvailableFileSystemFormat(Index++, szFormatW, &dummy, &dummy, &lastestVersion)) + { + if (!lastestVersion) + continue; + if (szFormats[0]) + _tcscat(szFormats, _T(", ")); +#ifdef UNICODE + _tcscat(szFormats, szFormatW); +#else + if (0 != WideCharToMultiByte(CP_ACP, 0, szFormatW, -1, szFormatA, sizeof(szFormatA), NULL, NULL)) + _tcscat(szFormats, szFormatA); +#endif + } + _tprintf(szMsg, ProgramName, szFormats); +} + + //---------------------------------------------------------------------- // // WMain From f1d365f7671b22b2bc7e89090efa68a5ecb95e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 24 Sep 2006 13:42:24 +0000 Subject: [PATCH 329/488] Don't hardcode the list of available filesystems in fmifs.dll, but store it in the registry. Adding a filesystem is now only a matter of creating a u{FS}.dll + one registry entry to be able to use normal format.exe/chkdsk.exe/... svn path=/trunk/; revision=24254 --- reactos/boot/bootdata/hivesft.inf | 4 ++ reactos/dll/win32/fmifs/init.c | 68 +++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/reactos/boot/bootdata/hivesft.inf b/reactos/boot/bootdata/hivesft.inf index 2d09fa12917..dcbe055c595 100644 --- a/reactos/boot/bootdata/hivesft.inf +++ b/reactos/boot/bootdata/hivesft.inf @@ -734,6 +734,10 @@ HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Tonga Standard Tim 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +; Available file systems +HKLM,"SOFTWARE\ReactOS\ReactOS\CurrentVersion\IFS","FAT",0x00000000,"ufat.dll" +HKLM,"SOFTWARE\ReactOS\ReactOS\CurrentVersion\IFS","FAT32",0x00000000,"ufat.dll" + HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","ConsoleShell",0x00020000,"%SystemRoot%\system32\cmd.exe" HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Shell",0x00020000,"%SystemRoot%\explorer.exe" HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","StartServices",0x00010001,0x00000001 diff --git a/reactos/dll/win32/fmifs/init.c b/reactos/dll/win32/fmifs/init.c index b6a0c15c478..0b3489d4ba8 100644 --- a/reactos/dll/win32/fmifs/init.c +++ b/reactos/dll/win32/fmifs/init.c @@ -35,7 +35,7 @@ GetProvider( static BOOLEAN AddProvider( - IN PWCHAR FileSystem, + IN PCUNICODE_STRING FileSystem, IN PWCHAR DllFile) { PIFS_PROVIDER Provider = NULL; @@ -48,7 +48,7 @@ AddProvider( goto cleanup; RequiredSize = FIELD_OFFSET(IFS_PROVIDER, Name) - + wcslen(FileSystem) * sizeof(WCHAR) + sizeof(UNICODE_NULL); + + FileSystem->Length + sizeof(UNICODE_NULL); Provider = (PIFS_PROVIDER)RtlAllocateHeap( RtlGetProcessHeap(), 0, @@ -62,7 +62,7 @@ AddProvider( //Provider->Extend = (EXTEND)GetProcAddress(hMod, "Extend"); Provider->FormatEx = (FORMATEX)GetProcAddress(hMod, "FormatEx"); - wcscpy(Provider->Name, FileSystem); + RtlCopyMemory(Provider->Name, FileSystem->Buffer, FileSystem->Length); InsertTailList(&ProviderListHead, &Provider->ListEntry); ret = TRUE; @@ -81,14 +81,66 @@ cleanup: static BOOLEAN InitializeFmIfsOnce(void) { + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING RegistryPath + = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\SOFTWARE\\ReactOS\\ReactOS\\CurrentVersion\\IFS"); + HANDLE hKey = NULL; + PKEY_VALUE_FULL_INFORMATION Buffer; + ULONG BufferSize = sizeof(KEY_VALUE_FULL_INFORMATION) + MAX_PATH; + ULONG RequiredSize; + ULONG i = 0; + UNICODE_STRING Name; + UNICODE_STRING Data; + NTSTATUS Status; + InitializeListHead(&ProviderListHead); - /* Add default providers */ - AddProvider(L"FAT", L"ufat"); - AddProvider(L"FAT32", L"ufat"); + /* Read IFS providers from HKLM\SOFTWARE\ReactOS\ReactOS\CurrentVersion\IFS */ + InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, 0, NULL, NULL); + Status = NtOpenKey(&hKey, KEY_QUERY_VALUE, &ObjectAttributes); + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + return TRUE; + else if (!NT_SUCCESS(Status)) + return FALSE; - /* TODO: Check how many IFS are installed in the system */ - /* TODO: and register a descriptor for each one */ + Buffer = (PKEY_VALUE_FULL_INFORMATION)RtlAllocateHeap( + RtlGetProcessHeap(), + 0, + BufferSize); + if (!Buffer) + { + NtClose(hKey); + return FALSE; + } + + while (TRUE) + { + Status = NtEnumerateValueKey( + hKey, + i++, + KeyValueFullInformation, + Buffer, + BufferSize, + &RequiredSize); + if (Status == STATUS_BUFFER_OVERFLOW) + continue; + else if (!NT_SUCCESS(Status)) + break; + else if (Buffer->Type != REG_SZ) + continue; + + Name.Length = Name.MaximumLength = Buffer->NameLength; + Name.Buffer = Buffer->Name; + Data.Length = Data.MaximumLength = Buffer->DataLength; + Data.Buffer = (PWCHAR)((ULONG_PTR)Buffer + Buffer->DataOffset); + if (Data.Length > sizeof(WCHAR) && Data.Buffer[Data.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) + Data.Length -= sizeof(WCHAR); + + AddProvider(&Name, Data.Buffer); + } + + NtClose(hKey); + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); return TRUE; } From a04da34bc07511a7fe48157c833d1812d71316ab Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Sun, 24 Sep 2006 17:01:46 +0000 Subject: [PATCH 330/488] More prototypes svn path=/trunk/; revision=24255 --- reactos/subsystems/win32/win32k/include/dc.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index 00afe1ec3ea..c23f894f3ff 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -188,6 +188,11 @@ VOID FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner); VOID FASTCALL DC_UpdateXforms(PDC dc); BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest); +VOID FASTCALL IntGetViewportExtEx(PDC dc, LPSIZE pt); +VOID FASTCALL IntGetViewportOrgEx(PDC dc, LPPOINT pt); +VOID FASTCALL IntGetWindowExtEx(PDC dc, LPSIZE pt); +VOID FASTCALL IntGetWindowOrgEx(PDC dc, LPPOINT pt); + /* For Metafile and MetaEnhFile not in windows this struct taken from wine cvs 15/9-2006*/ typedef struct { @@ -195,5 +200,4 @@ typedef struct BOOL on_disk; /* true if metafile is on disk */ } DD_ENHMETAFILEOBJ, *PDD_ENHMETAFILEOBJ; - -#endif +#endif /* __WIN32K_DC_H */ From a5b535fee4c32003a923920d7763ffb409300624 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Sun, 24 Sep 2006 17:02:29 +0000 Subject: [PATCH 331/488] - Implement NtGdiStrokePath and NtGdiStrokeAndFillPath (based on wine) - Get rid of PATH_GetPathFromDc() svn path=/trunk/; revision=24256 --- .../subsystems/win32/win32k/objects/path.c | 374 ++++++++++++------ 1 file changed, 248 insertions(+), 126 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/path.c b/reactos/subsystems/win32/win32k/objects/path.c index 27de4689ca5..91e41c1eda8 100644 --- a/reactos/subsystems/win32/win32k/objects/path.c +++ b/reactos/subsystems/win32/win32k/objects/path.c @@ -33,12 +33,11 @@ BOOL FASTCALL PATH_AddFlatBezier (GdiPath *pPath, POINT *pt, BOOL closed); BOOL FASTCALL PATH_DoArcPart (GdiPath *pPath, FLOAT_POINT corners[], double angleStart, double angleEnd, BOOL addMoveTo); BOOL FASTCALL PATH_FillPath( PDC dc, GdiPath *pPath ); BOOL FASTCALL PATH_FlattenPath (GdiPath *pPath); -VOID FASTCALL PATH_GetPathFromDC (PDC dc, GdiPath **ppPath); VOID FASTCALL PATH_NormalizePoint (FLOAT_POINT corners[], const FLOAT_POINT *pPoint, double *pX, double *pY); BOOL FASTCALL PATH_PathToRegion (GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn); BOOL FASTCALL PATH_ReserveEntries (GdiPath *pPath, INT numEntries); VOID FASTCALL PATH_ScaleNormalizedPoint (FLOAT_POINT corners[], double x, double y, POINT *pPoint); - +BOOL FASTCALL PATH_StrokePath(DC *dc, GdiPath *pPath); INT FASTCALL IntGdiGetArcDirection(DC *dc); @@ -51,16 +50,12 @@ BOOL STDCALL NtGdiAbortPath(HDC hDC) { - GdiPath *pPath; BOOL ret = TRUE; PDC dc = DC_LockDc ( hDC ); if( !dc ) return FALSE; - /* Get pointer to path */ - PATH_GetPathFromDC ( dc, &pPath ); - - PATH_EmptyPath( pPath ); + PATH_EmptyPath(&dc->w.path); DC_UnlockDc ( dc ); return ret; @@ -70,24 +65,20 @@ BOOL STDCALL NtGdiBeginPath( HDC hDC ) { - GdiPath *pPath; BOOL ret = TRUE; PDC dc = DC_LockDc ( hDC ); if( !dc ) return FALSE; - - /* Get pointer to path */ - PATH_GetPathFromDC ( dc, &pPath ); /* If path is already open, do nothing */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) { /* Make sure that path is empty */ - PATH_EmptyPath( pPath ); + PATH_EmptyPath( &dc->w.path ); /* Initialize variables for new path */ - pPath->newStroke = TRUE; - pPath->state = PATH_Open; + dc->w.path.newStroke = TRUE; + dc->w.path.state = PATH_Open; } DC_UnlockDc ( dc ); @@ -142,22 +133,18 @@ BOOL STDCALL NtGdiEndPath(HDC hDC) { - GdiPath *pPath; BOOL ret = TRUE; PDC dc = DC_LockDc ( hDC ); if ( !dc ) return FALSE; - /* Get pointer to path */ - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is currently being constructed */ - if( pPath->state != PATH_Open ) + if( dc->w.path.state != PATH_Open ) { ret = FALSE; } /* Set flag to indicate that path is finished */ - else pPath->state = PATH_Closed; + else dc->w.path.state = PATH_Closed; DC_UnlockDc ( dc ); return ret; @@ -167,21 +154,17 @@ BOOL STDCALL NtGdiFillPath(HDC hDC) { - GdiPath *pPath; BOOL ret = TRUE; PDC dc = DC_LockDc ( hDC ); if ( !dc ) return FALSE; - - /* Get pointer to path */ - PATH_GetPathFromDC ( dc, &pPath ); - ret = PATH_FillPath( dc, pPath ); + ret = PATH_FillPath( dc, &dc->w.path ); if( ret ) { /* FIXME: Should the path be emptied even if conversion failed? */ - PATH_EmptyPath( pPath ); + PATH_EmptyPath( &dc->w.path ); } DC_UnlockDc ( dc ); @@ -323,18 +306,39 @@ NtGdiSetMiterLimit( BOOL STDCALL -NtGdiStrokeAndFillPath(HDC hDC) +NtGdiStrokeAndFillPath(HDC hDC) { - UNIMPLEMENTED; - return FALSE; + DC *pDc; + BOOL bRet = FALSE; + + DPRINT("Enter %s\n", __FUNCTION__); + + if(!(pDc = DC_LockDc(hDC))) return FALSE; + + bRet = PATH_FillPath(pDc, &pDc->w.path); + if(bRet) bRet = PATH_StrokePath(pDc, &pDc->w.path); + if(bRet) PATH_EmptyPath(&pDc->w.path); + + DC_UnlockDc(pDc); + return bRet; } BOOL STDCALL -NtGdiStrokePath(HDC hDC) +NtGdiStrokePath(HDC hDC) { - UNIMPLEMENTED; - return FALSE; + DC *pDc; + BOOL bRet = FALSE; + + DPRINT("Enter %s\n", __FUNCTION__); + + if(!(pDc = DC_LockDc(hDC))) return FALSE; + + bRet = PATH_StrokePath(pDc, &pDc->w.path); + PATH_EmptyPath(&pDc->w.path); + + DC_UnlockDc(pDc); + return bRet; } BOOL @@ -348,30 +352,27 @@ NtGdiWidenPath(HDC hDC) BOOL STDCALL NtGdiSelectClipPath(HDC hDC, int Mode) { - GdiPath *pPath; HRGN hrgnPath; BOOL success = FALSE; PDC dc = DC_LockDc ( hDC ); if( !dc ) return FALSE; - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is closed */ - if( pPath->state != PATH_Closed ) + if( dc->w.path.state != PATH_Closed ) { SetLastWin32Error(ERROR_CAN_NOT_COMPLETE); return FALSE; } /* Construct a region from the path */ - else if( PATH_PathToRegion( pPath, dc->w.polyFillMode, &hrgnPath ) ) + else if( PATH_PathToRegion( &dc->w.path, dc->w.polyFillMode, &hrgnPath ) ) { success = IntGdiExtSelectClipRgn( dc, hrgnPath, Mode ) != ERROR; NtGdiDeleteObject( hrgnPath ); /* Empty the path */ if( success ) - PATH_EmptyPath( pPath ); + PATH_EmptyPath( &dc->w.path); /* FIXME: Should this function delete the path even if it failed? */ } @@ -532,18 +533,14 @@ BOOL FASTCALL PATH_MoveTo ( PDC dc ) { - GdiPath *pPath; - - /* Get pointer to path */ - PATH_GetPathFromDC ( dc, &pPath ); /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) /* FIXME: Do we have to call SetLastError? */ return FALSE; /* Start a new stroke */ - pPath->newStroke = TRUE; + dc->w.path.newStroke = TRUE; return TRUE; } @@ -559,14 +556,10 @@ BOOL FASTCALL PATH_LineTo ( PDC dc, INT x, INT y ) { - GdiPath *pPath; POINT point, pointCurPos; - /* Get pointer to path */ - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) return FALSE; /* Convert point to device coordinates */ @@ -575,17 +568,17 @@ PATH_LineTo ( PDC dc, INT x, INT y ) CoordLPtoDP ( dc, &point ); /* Add a PT_MOVETO if necessary */ - if ( pPath->newStroke ) + if ( dc->w.path.newStroke ) { - pPath->newStroke = FALSE; + dc->w.path.newStroke = FALSE; IntGetCurrentPositionEx ( dc, &pointCurPos ); CoordLPtoDP ( dc, &pointCurPos ); - if ( !PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO) ) + if ( !PATH_AddEntry(&dc->w.path, &pointCurPos, PT_MOVETO) ) return FALSE; } /* Add a PT_LINETO entry */ - return PATH_AddEntry(pPath, &point, PT_LINETO); + return PATH_AddEntry(&dc->w.path, &point, PT_LINETO); } /* PATH_Rectangle @@ -597,15 +590,11 @@ BOOL FASTCALL PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) { - GdiPath *pPath; POINT corners[2], pointTemp; INT temp; - /* Get pointer to path */ - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) return FALSE; /* Convert points to device coordinates */ @@ -642,15 +631,15 @@ PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) /* Add four points to the path */ pointTemp.x=corners[1].x; pointTemp.y=corners[0].y; - if ( !PATH_AddEntry(pPath, &pointTemp, PT_MOVETO) ) + if ( !PATH_AddEntry(&dc->w.path, &pointTemp, PT_MOVETO) ) return FALSE; - if ( !PATH_AddEntry(pPath, corners, PT_LINETO) ) + if ( !PATH_AddEntry(&dc->w.path, corners, PT_LINETO) ) return FALSE; pointTemp.x=corners[0].x; pointTemp.y=corners[1].y; - if ( !PATH_AddEntry(pPath, &pointTemp, PT_LINETO) ) + if ( !PATH_AddEntry(&dc->w.path, &pointTemp, PT_LINETO) ) return FALSE; - if ( !PATH_AddEntry(pPath, corners+1, PT_LINETO) ) + if ( !PATH_AddEntry(&dc->w.path, corners+1, PT_LINETO) ) return FALSE; /* Close the rectangle figure */ @@ -693,7 +682,6 @@ FASTCALL PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2, INT xStart, INT yStart, INT xEnd, INT yEnd) { - GdiPath *pPath; double angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0; /* Initialize angleEndQuadrant to silence gcc's warning */ double x, y; @@ -709,11 +697,8 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2, clockwise = ( IntGdiGetArcDirection(dc) == AD_CLOCKWISE ); - /* Get pointer to path */ - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) return FALSE; /* FIXME: Do we have to close the current figure? */ @@ -817,7 +802,7 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2, } /* Add the Bezier spline to the path */ - PATH_DoArcPart ( pPath, corners, angleStartQuadrant, angleEndQuadrant, start ); + PATH_DoArcPart ( &dc->w.path, corners, angleStartQuadrant, angleEndQuadrant, start ); start = FALSE; } while(!end); @@ -828,7 +813,6 @@ BOOL FASTCALL PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints ) { - GdiPath *pPath; POINT pt; ULONG i; @@ -836,19 +820,17 @@ PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints ) ASSERT ( pts ); ASSERT ( cbPoints ); - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) return FALSE; /* Add a PT_MOVETO if necessary */ - if ( pPath->newStroke ) + if ( dc->w.path.newStroke ) { - pPath->newStroke=FALSE; + dc->w.path.newStroke=FALSE; IntGetCurrentPositionEx ( dc, &pt ); CoordLPtoDP ( dc, &pt ); - if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) ) + if ( !PATH_AddEntry(&dc->w.path, &pt, PT_MOVETO) ) return FALSE; } @@ -856,7 +838,7 @@ PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints ) { pt = pts[i]; CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, PT_BEZIERTO); + PATH_AddEntry(&dc->w.path, &pt, PT_BEZIERTO); } return TRUE; } @@ -865,7 +847,6 @@ BOOL FASTCALL PATH_PolyBezier ( PDC dc, const POINT *pts, DWORD cbPoints ) { - GdiPath *pPath; POINT pt; ULONG i; @@ -873,17 +854,15 @@ PATH_PolyBezier ( PDC dc, const POINT *pts, DWORD cbPoints ) ASSERT ( pts ); ASSERT ( cbPoints ); - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) return FALSE; for ( i = 0; i < cbPoints; i++ ) { pt = pts[i]; CoordLPtoDP ( dc, &pt ); - PATH_AddEntry ( pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO ); + PATH_AddEntry ( &dc->w.path, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO ); } return TRUE; @@ -893,7 +872,6 @@ BOOL FASTCALL PATH_Polyline ( PDC dc, const POINT *pts, DWORD cbPoints ) { - GdiPath *pPath; POINT pt; ULONG i; @@ -901,17 +879,15 @@ PATH_Polyline ( PDC dc, const POINT *pts, DWORD cbPoints ) ASSERT ( pts ); ASSERT ( cbPoints ); - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) return FALSE; for ( i = 0; i < cbPoints; i++ ) { pt = pts[i]; CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO); + PATH_AddEntry(&dc->w.path, &pt, (i == 0) ? PT_MOVETO : PT_LINETO); } return TRUE; } @@ -920,7 +896,6 @@ BOOL FASTCALL PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints ) { - GdiPath *pPath; POINT pt; ULONG i; @@ -928,19 +903,17 @@ PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints ) ASSERT ( pts ); ASSERT ( cbPoints ); - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) return FALSE; /* Add a PT_MOVETO if necessary */ - if ( pPath->newStroke ) + if ( dc->w.path.newStroke ) { - pPath->newStroke = FALSE; + dc->w.path.newStroke = FALSE; IntGetCurrentPositionEx ( dc, &pt ); CoordLPtoDP ( dc, &pt ); - if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) ) + if ( !PATH_AddEntry(&dc->w.path, &pt, PT_MOVETO) ) return FALSE; } @@ -948,7 +921,7 @@ PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints ) { pt = pts[i]; CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, PT_LINETO); + PATH_AddEntry(&dc->w.path, &pt, PT_LINETO); } return TRUE; @@ -959,24 +932,21 @@ BOOL FASTCALL PATH_Polygon ( PDC dc, const POINT *pts, DWORD cbPoints ) { - GdiPath *pPath; POINT pt; ULONG i; ASSERT ( dc ); ASSERT ( pts ); - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) return FALSE; for(i = 0; i < cbPoints; i++) { pt = pts[i]; CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : + PATH_AddEntry(&dc->w.path, &pt, (i == 0) ? PT_MOVETO : ((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO)); } @@ -987,7 +957,6 @@ BOOL FASTCALL PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons ) { - GdiPath *pPath; POINT pt, startpt; ULONG poly, point, i; @@ -996,10 +965,8 @@ PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons ) ASSERT ( counts ); ASSERT ( polygons ); - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ); + if ( dc->w.path.state != PATH_Open ); return FALSE; for(i = 0, poly = 0; poly < polygons; poly++) @@ -1009,10 +976,10 @@ PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons ) pt = pts[i]; CoordLPtoDP ( dc, &pt ); if(point == 0) startpt = pt; - PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); + PATH_AddEntry(&dc->w.path, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); } /* win98 adds an extra line to close the figure for some reason */ - PATH_AddEntry(pPath, &startpt, PT_LINETO | PT_CLOSEFIGURE); + PATH_AddEntry(&dc->w.path, &startpt, PT_LINETO | PT_CLOSEFIGURE); } return TRUE; } @@ -1021,7 +988,6 @@ BOOL FASTCALL PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines ) { - GdiPath *pPath; POINT pt; ULONG poly, point, i; @@ -1030,10 +996,8 @@ PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylin ASSERT ( counts ); ASSERT ( polylines ); - PATH_GetPathFromDC ( dc, &pPath ); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) + if ( dc->w.path.state != PATH_Open ) return FALSE; for(i = 0, poly = 0; poly < polylines; poly++) @@ -1042,7 +1006,7 @@ PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylin { pt = pts[i]; CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); + PATH_AddEntry(&dc->w.path, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); } } return TRUE; @@ -1085,7 +1049,7 @@ PATH_FlattenPath(GdiPath *pPath) GdiPath newPath; INT srcpt; - memset(&newPath, 0, sizeof(newPath)); + RtlZeroMemory(&newPath, sizeof(newPath)); newPath.state = PATH_Open; for(srcpt = 0; srcpt < pPath->numEntriesUsed; srcpt++) { switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE) { @@ -1289,20 +1253,6 @@ PATH_ReserveEntries ( GdiPath *pPath, INT numEntries ) return TRUE; } -/* PATH_GetPathFromDC - * - * Retrieves a pointer to the GdiPath structure contained in an HDC and - * places it in *ppPath. TRUE is returned if successful, FALSE otherwise. - */ -VOID -FASTCALL -PATH_GetPathFromDC ( PDC dc, GdiPath **ppPath ) -{ - ASSERT ( dc ); - ASSERT ( ppPath ); - *ppPath = &dc->w.path; -} - /* PATH_DoArcPart * * Creates a Bezier spline that corresponds to part of an arc and appends the @@ -1401,4 +1351,176 @@ PATH_NormalizePoint ( FLOAT_POINT corners[], *pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) * 2.0 - 1.0; *pY=(double)(pPoint->y-corners[0].y)/(double)(corners[1].y-corners[0].y) * 2.0 - 1.0; } + + +BOOL FASTCALL PATH_StrokePath(DC *dc, GdiPath *pPath) +{ + BOOL ret = FALSE; + INT i=0; + INT nLinePts, nAlloc; + POINT *pLinePts = NULL; + POINT ptViewportOrg, ptWindowOrg; + SIZE szViewportExt, szWindowExt; + DWORD mapMode, graphicsMode; + XFORM xform; + + DPRINT("Enter %s\n", __FUNCTION__); + + if(pPath->state != PATH_Closed) + return FALSE; + + /* Save the mapping mode info */ + mapMode=dc->w.MapMode; + IntGetViewportExtEx(dc, &szViewportExt); + IntGetViewportOrgEx(dc, &ptViewportOrg); + IntGetWindowExtEx(dc, &szWindowExt); + IntGetWindowOrgEx(dc, &ptWindowOrg); + xform = dc->w.xformWorld2Wnd; + + /* Set MM_TEXT */ + dc->w.MapMode = MM_TEXT; + dc->vportOrgX = 0; + dc->vportOrgY = 0; + dc->wndOrgX = 0; + dc->wndOrgY = 0; + graphicsMode = dc->w.GraphicsMode; + dc->w.GraphicsMode = GM_ADVANCED; + IntGdiModifyWorldTransform(dc, &xform, MWT_IDENTITY); + dc->w.GraphicsMode = graphicsMode; + + /* Allocate enough memory for the worst case without beziers (one PT_MOVETO + * and the rest PT_LINETO with PT_CLOSEFIGURE at the end) plus some buffer + * space in case we get one to keep the number of reallocations small. */ + nAlloc = pPath->numEntriesUsed + 1 + 300; + pLinePts = ExAllocatePoolWithTag(PagedPool, nAlloc * sizeof(POINT), TAG_PATH); + if(!pLinePts) + { + DPRINT1("Can't allocate pool!\n"); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + goto end; + } + nLinePts = 0; + + for(i = 0; i < pPath->numEntriesUsed; i++) + { + if((i == 0 || (pPath->pFlags[i-1] & PT_CLOSEFIGURE)) + && (pPath->pFlags[i] != PT_MOVETO)) + { + DPRINT1("Expected PT_MOVETO %s, got path flag %d\n", + i == 0 ? "as first point" : "after PT_CLOSEFIGURE", + (INT)pPath->pFlags[i]); + goto end; + } + + switch(pPath->pFlags[i]) + { + case PT_MOVETO: + DPRINT("Got PT_MOVETO (%ld, %ld)\n", + pPath->pPoints[i].x, pPath->pPoints[i].y); + if(nLinePts >= 2) IntGdiPolyline(dc, pLinePts, nLinePts); + nLinePts = 0; + pLinePts[nLinePts++] = pPath->pPoints[i]; + break; + case PT_LINETO: + case (PT_LINETO | PT_CLOSEFIGURE): + DPRINT("Got PT_LINETO (%ld, %ld)\n", + pPath->pPoints[i].x, pPath->pPoints[i].y); + pLinePts[nLinePts++] = pPath->pPoints[i]; + break; + case PT_BEZIERTO: + DPRINT("Got PT_BEZIERTO\n"); + if(pPath->pFlags[i+1] != PT_BEZIERTO || + (pPath->pFlags[i+2] & ~PT_CLOSEFIGURE) != PT_BEZIERTO) + { + DPRINT1("Path didn't contain 3 successive PT_BEZIERTOs\n"); + ret = FALSE; + goto end; + } + else + { + INT nBzrPts, nMinAlloc; + POINT *pBzrPts = GDI_Bezier(&pPath->pPoints[i-1], 4, &nBzrPts); + /* Make sure we have allocated enough memory for the lines of + * this bezier and the rest of the path, assuming we won't get + * another one (since we won't reallocate again then). */ + nMinAlloc = nLinePts + (pPath->numEntriesUsed - i) + nBzrPts; + if(nAlloc < nMinAlloc) + { + // Reallocate memory + + POINT *Realloc = NULL; + nAlloc = nMinAlloc * 2; + + Realloc = ExAllocatePoolWithTag(PagedPool, + nAlloc * sizeof(POINT), + TAG_PATH); + + if(!Realloc) + { + DPRINT1("Can't allocate pool!\n"); + goto end; + } + + RtlCopyMemory(Realloc, pLinePts, nLinePts*sizeof(POINT)); + ExFreePool(pLinePts); + pLinePts = Realloc; + } + RtlCopyMemory(&pLinePts[nLinePts], &pBzrPts[1], (nBzrPts - 1) * sizeof(POINT)); + nLinePts += nBzrPts - 1; + ExFreePool(pBzrPts); + i += 2; + } + break; + default: + DPRINT1("Got path flag %d (not supported)\n", (INT)pPath->pFlags[i]); + goto end; + } + + if(pPath->pFlags[i] & PT_CLOSEFIGURE) + { + pLinePts[nLinePts++] = pLinePts[0]; + } + }//for + + if(nLinePts >= 2) + IntGdiPolyline(dc, pLinePts, nLinePts); + + ret = TRUE; + +end: + if(pLinePts)ExFreePool(pLinePts); + + /* Restore the old mapping mode */ + dc->w.MapMode = mapMode; + dc->wndExtX = szWindowExt.cx; + dc->wndExtY = szWindowExt.cy; + dc->wndOrgX = ptWindowOrg.x; + dc->wndOrgY = ptWindowOrg.y; + + dc->vportExtX = szViewportExt.cx; + dc->vportExtY = szViewportExt.cy; + dc->vportOrgX = ptViewportOrg.x; + dc->vportOrgY = ptViewportOrg.y; + + /* Restore the world transform */ + dc->w.xformWorld2Wnd = xform; + + /* If we've moved the current point then get its new position + which will be in device (MM_TEXT) co-ords, convert it to + logical co-ords and re-set it. This basically updates + dc->CurPosX|Y so that their values are in the correct mapping + mode. + */ + if(i > 0) + { + POINT pt; + IntGetCurrentPositionEx(dc, &pt); + IntDPtoLP(dc, &pt, 1); + IntGdiMoveToEx(dc, pt.x, pt.y, NULL); + } + + DPRINT("Leave %s, ret=%d\n", __FUNCTION__, ret); + return ret; +} + /* EOF */ From 2047460d026ac82d8da6e9a4b62e4171645685d7 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Sun, 24 Sep 2006 17:10:58 +0000 Subject: [PATCH 332/488] memcpy -> RtlCopyMemory assert -> ASSERT svn path=/trunk/; revision=24257 --- .../subsystems/win32/win32k/objects/path.c | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/path.c b/reactos/subsystems/win32/win32k/objects/path.c index 91e41c1eda8..67033a8f9f7 100644 --- a/reactos/subsystems/win32/win32k/objects/path.c +++ b/reactos/subsystems/win32/win32k/objects/path.c @@ -467,7 +467,7 @@ VOID FASTCALL PATH_InitGdiPath ( GdiPath *pPath ) { - assert(pPath!=NULL); + ASSERT(pPath!=NULL); pPath->state=PATH_Null; pPath->pPoints=NULL; @@ -484,7 +484,7 @@ VOID FASTCALL PATH_DestroyGdiPath ( GdiPath *pPath ) { - assert(pPath!=NULL); + ASSERT(pPath!=NULL); ExFreePool(pPath->pPoints); ExFreePool(pPath->pFlags); @@ -504,16 +504,16 @@ BOOL FASTCALL PATH_AssignGdiPath ( GdiPath *pPathDest, const GdiPath *pPathSrc ) { - assert(pPathDest!=NULL && pPathSrc!=NULL); + ASSERT(pPathDest!=NULL && pPathSrc!=NULL); /* Make sure destination arrays are big enough */ if ( !PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed) ) return FALSE; /* Perform the copy operation */ - memcpy(pPathDest->pPoints, pPathSrc->pPoints, + RtlCopyMemory(pPathDest->pPoints, pPathSrc->pPoints, sizeof(POINT)*pPathSrc->numEntriesUsed); - memcpy(pPathDest->pFlags, pPathSrc->pFlags, + RtlCopyMemory(pPathDest->pFlags, pPathSrc->pFlags, sizeof(BYTE)*pPathSrc->numEntriesUsed); pPathDest->state=pPathSrc->state; @@ -748,7 +748,7 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2, if ( angleEnd <= angleStart ) { angleEnd+=2*M_PI; - assert(angleEnd>=angleStart); + ASSERT(angleEnd>=angleStart); } } else @@ -756,7 +756,7 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2, if(angleEnd>=angleStart) { angleEnd-=2*M_PI; - assert(angleEnd<=angleStart); + ASSERT(angleEnd<=angleStart); } } @@ -1087,8 +1087,8 @@ PATH_PathToRegion ( GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn ) INT *pNumPointsInStroke; HRGN hrgn = 0; - assert ( pPath!=NULL ); - assert ( pHrgn!=NULL ); + ASSERT(pPath!=NULL); + ASSERT(pHrgn!=NULL); PATH_FlattenPath ( pPath ); @@ -1148,7 +1148,7 @@ VOID FASTCALL PATH_EmptyPath ( GdiPath *pPath ) { - assert(pPath!=NULL); + ASSERT(pPath!=NULL); pPath->state=PATH_Null; pPath->numEntriesUsed=0; @@ -1164,7 +1164,7 @@ BOOL FASTCALL PATH_AddEntry ( GdiPath *pPath, const POINT *pPoint, BYTE flags ) { - assert(pPath!=NULL); + ASSERT(pPath!=NULL); /* FIXME: If newStroke is true, perhaps we want to check that we're * getting a PT_MOVETO @@ -1206,8 +1206,8 @@ PATH_ReserveEntries ( GdiPath *pPath, INT numEntries ) POINT *pPointsNew; BYTE *pFlagsNew; - assert(pPath!=NULL); - assert(numEntries>=0); + ASSERT(pPath!=NULL); + ASSERT(numEntries>=0); /* Do we have to allocate more memory? */ if(numEntries > pPath->numEntriesAllocated) @@ -1237,10 +1237,10 @@ PATH_ReserveEntries ( GdiPath *pPath, INT numEntries ) /* Copy old arrays to new arrays and discard old arrays */ if(pPath->pPoints) { - assert(pPath->pFlags); + ASSERT(pPath->pFlags); - memcpy(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); - memcpy(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); + RtlCopyMemory(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); + RtlCopyMemory(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); ExFreePool(pPath->pPoints); ExFreePool(pPath->pFlags); @@ -1272,7 +1272,7 @@ PATH_DoArcPart ( GdiPath *pPath, FLOAT_POINT corners[], POINT point; int i; - assert(fabs(angleEnd-angleStart)<=M_PI_2); + ASSERT(fabs(angleEnd-angleStart)<=M_PI_2); /* FIXME: Is there an easier way of computing this? */ From 29b494be5671df53726826b2629edc25a5c0922c Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Sun, 24 Sep 2006 18:07:21 +0000 Subject: [PATCH 333/488] Cosmetic changes svn path=/trunk/; revision=24258 --- reactos/include/psdk/intrin.h | 146 +++++++++++++++++----------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/reactos/include/psdk/intrin.h b/reactos/include/psdk/intrin.h index 6b68ef1776e..32179830262 100644 --- a/reactos/include/psdk/intrin.h +++ b/reactos/include/psdk/intrin.h @@ -47,7 +47,7 @@ first, but they're only "as wrong" as they would be on Visual C++. Our priority is compatibility - NOTE: unlike most people who write __inline__ asm for GCC, I didn't pull the + NOTE: unlike most people who write inline asm for GCC, I didn't pull the constraints and the uses of __volatile__ out of my... hat. Do not touch them. I hate cargo cult programming @@ -274,155 +274,155 @@ static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(vo static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask) { - char x; - char y; + char x; + char y; - y = *value; + y = *value; - do + do { - x = y; - y = _InterlockedCompareExchange8(value, x & mask, x); - } + x = y; + y = _InterlockedCompareExchange8(value, x & mask, x); + } while(y != x); - return y; + return y; } static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask) { - short x; - short y; + short x; + short y; - y = *value; + y = *value; - do + do { - x = y; - y = _InterlockedCompareExchange16(value, x & mask, x); - } + x = y; + y = _InterlockedCompareExchange16(value, x & mask, x); + } while(y != x); - return y; + return y; } static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask) { - long x; - long y; + long x; + long y; - y = *value; + y = *value; - do + do { - x = y; - y = _InterlockedCompareExchange(value, x & mask, x); - } + x = y; + y = _InterlockedCompareExchange(value, x & mask, x); + } while(y != x); - return y; + return y; } static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask) { - char x; - char y; + char x; + char y; - y = *value; + y = *value; - do + do { - x = y; - y = _InterlockedCompareExchange8(value, x | mask, x); - } + x = y; + y = _InterlockedCompareExchange8(value, x | mask, x); + } while(y != x); - return y; + return y; } static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask) { - short x; - short y; + short x; + short y; - y = *value; + y = *value; - do + do { - x = y; - y = _InterlockedCompareExchange16(value, x | mask, x); - } + x = y; + y = _InterlockedCompareExchange16(value, x | mask, x); + } while(y != x); - return y; + return y; } static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask) { - long x; - long y; + long x; + long y; - y = *value; + y = *value; - do + do { - x = y; - y = _InterlockedCompareExchange(value, x | mask, x); - } + x = y; + y = _InterlockedCompareExchange(value, x | mask, x); + } while(y != x); - return y; + return y; } static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask) { - char x; - char y; + char x; + char y; - y = *value; + y = *value; - do + do { - x = y; - y = _InterlockedCompareExchange8(value, x ^ mask, x); - } + x = y; + y = _InterlockedCompareExchange8(value, x ^ mask, x); + } while(y != x); - return y; + return y; } static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask) { - short x; - short y; + short x; + short y; - y = *value; + y = *value; - do + do { - x = y; - y = _InterlockedCompareExchange16(value, x ^ mask, x); - } + x = y; + y = _InterlockedCompareExchange16(value, x ^ mask, x); + } while(y != x); - return y; + return y; } static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask) { - long x; - long y; + long x; + long y; - y = *value; + y = *value; - do + do { - x = y; - y = _InterlockedCompareExchange(value, x ^ mask, x); - } + x = y; + y = _InterlockedCompareExchange(value, x ^ mask, x); + } while(y != x); - return y; + return y; } #endif From 350e281e1ceb1c3992bcdf9b709f567bfedc0f01 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 24 Sep 2006 20:14:44 +0000 Subject: [PATCH 334/488] Fix use of unicode for unix host regardless of -fshort-wchar. svn path=/trunk/; revision=24259 --- reactos/tools/buildno/buildno.cpp | 37 +++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/reactos/tools/buildno/buildno.cpp b/reactos/tools/buildno/buildno.cpp index 9a49bbf6303..14e48e8acc7 100644 --- a/reactos/tools/buildno/buildno.cpp +++ b/reactos/tools/buildno/buildno.cpp @@ -38,6 +38,7 @@ static char * argv0 = ""; static char * filename = ""; +static char * kernel_version_build_type = 0; #ifdef DBG void @@ -55,6 +56,15 @@ tm_dump (const char *tag, struct tm * t) } #endif +int count_wide_string( wchar_t *str ) +{ + int i; + + for( i = 0; str[i]; i++ ); + + return i; +} + void write_h (int build, char *buildstr) { @@ -80,7 +90,7 @@ write_h (int build, char *buildstr) { s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL); } - s = s + sprintf (s, "-%S\\0\"\n", KERNEL_VERSION_BUILD_TYPE); + s = s + sprintf (s, "-%s\\0\"\n", kernel_version_build_type); s = s + sprintf (s, "#define KERNEL_RELEASE_STR\t\"%d.%d", KERNEL_VERSION_MAJOR, KERNEL_VERSION_MINOR); @@ -88,7 +98,7 @@ write_h (int build, char *buildstr) { s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL); } - s = s + sprintf (s, "-%S\"\n", KERNEL_VERSION_BUILD_TYPE); + s = s + sprintf (s, "-%s\"\n", kernel_version_build_type); s = s + sprintf (s, "#define KERNEL_VERSION_RC\t\"%d.%d", KERNEL_VERSION_MAJOR, KERNEL_VERSION_MINOR); @@ -96,7 +106,7 @@ write_h (int build, char *buildstr) { s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL); } - s = s + sprintf (s, "-%S\\0\"\n", KERNEL_VERSION_BUILD_TYPE); + s = s + sprintf (s, "-%s\\0\"\n", kernel_version_build_type); s = s + sprintf (s, "#define KERNEL_VERSION_STR\t\"%d.%d", KERNEL_VERSION_MAJOR, KERNEL_VERSION_MINOR); @@ -104,7 +114,7 @@ write_h (int build, char *buildstr) { s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL); } - s = s + sprintf (s, "-%S\"\n", KERNEL_VERSION_BUILD_TYPE); + s = s + sprintf (s, "-%s\"\n", kernel_version_build_type); s = s + sprintf (s, "#define REACTOS_DLL_VERSION_MAJOR\t%d\n", dllversion); s = s + sprintf (s, "#define REACTOS_DLL_RELEASE_RC\t\"%d.%d", dllversion, KERNEL_VERSION_MINOR); @@ -112,7 +122,7 @@ write_h (int build, char *buildstr) { s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL); } - s = s + sprintf (s, "-%S\\0\"\n", KERNEL_VERSION_BUILD_TYPE); + s = s + sprintf (s, "-%s\\0\"\n", kernel_version_build_type); s = s + sprintf (s, "#define REACTOS_DLL_RELEASE_STR\t\"%d.%d", dllversion, KERNEL_VERSION_MINOR); @@ -120,7 +130,7 @@ write_h (int build, char *buildstr) { s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL); } - s = s + sprintf (s, "-%S\"\n", KERNEL_VERSION_BUILD_TYPE); + s = s + sprintf (s, "-%s\"\n", kernel_version_build_type); s = s + sprintf (s, "#define REACTOS_DLL_VERSION_RC\t\"%d.%d", dllversion, KERNEL_VERSION_MINOR); @@ -128,7 +138,7 @@ write_h (int build, char *buildstr) { s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL); } - s = s + sprintf (s, "-%S\\0\"\n", KERNEL_VERSION_BUILD_TYPE); + s = s + sprintf (s, "-%s\\0\"\n", kernel_version_build_type); s = s + sprintf (s, "#define REACTOS_DLL_VERSION_STR\t\"%d.%d", dllversion, KERNEL_VERSION_MINOR); @@ -136,7 +146,7 @@ write_h (int build, char *buildstr) { s = s + sprintf (s, ".%d", KERNEL_VERSION_PATCH_LEVEL); } - s = s + sprintf (s, "-%S\"\n", KERNEL_VERSION_BUILD_TYPE); + s = s + sprintf (s, "-%s\"\n", kernel_version_build_type); s = s + sprintf (s, "#endif\n/* EOF */\n"); h = fopen (filename, "wb"); @@ -284,6 +294,7 @@ usage (void) int main (int argc, char * argv []) { + int i, length; int print_only = FALSE; int quiet = FALSE; @@ -341,6 +352,14 @@ main (int argc, char * argv []) printf ( "\nReactOS Build Number Generator\n\n"); } + /* Convert kernel_version_build_type to a host-friendly string */ + length = count_wide_string(KERNEL_VERSION_BUILD_TYPE); + kernel_version_build_type = (char *)malloc(length+1); + for( i = 0; KERNEL_VERSION_BUILD_TYPE[i]; i++ ) { + kernel_version_build_type[i] = KERNEL_VERSION_BUILD_TYPE[i]; + } + kernel_version_build_type[i] = 0; + time (& t1); /* current build time */ t1_tm = gmtime (& t1); @@ -378,7 +397,7 @@ main (int argc, char * argv []) { printf(".%d", KERNEL_VERSION_PATCH_LEVEL); } - printf("-%S (Build %s)\n\n", KERNEL_VERSION_BUILD_TYPE, buildstr); + printf("-%s (Build %s)\n\n", kernel_version_build_type, buildstr); } /* * (Over)write the include file, unless From 235dd5fe2b10f023527b99b5ab002e89daf275e7 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 20:28:57 +0000 Subject: [PATCH 335/488] adding more missing struct svn path=/trunk/; revision=24260 --- reactos/include/psdk/wingdi.h | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/reactos/include/psdk/wingdi.h b/reactos/include/psdk/wingdi.h index e3430bcbf6a..c759e50e049 100644 --- a/reactos/include/psdk/wingdi.h +++ b/reactos/include/psdk/wingdi.h @@ -1339,7 +1339,7 @@ typedef struct { typedef struct tagFONTSIGNATURE { DWORD fsUsb[4]; DWORD fsCsb[2]; -} FONTSIGNATURE,*LPFONTSIGNATURE; +} FONTSIGNATURE, *PFONTSIGNATURE,*LPFONTSIGNATURE; typedef struct { UINT ciCharset; UINT ciACP; @@ -2029,7 +2029,14 @@ typedef struct tagABORTPATH { typedef struct tagEMRSELECTCLIPPATH { EMR emr; DWORD iMode; -} EMRSELECTCLIPPATH,*PEMRSELECTCLIPPATH,EMRSETBKMODE,*PEMRSETBKMODE,EMRSETMAPMODE,*PEMRSETMAPMODE,EMRSETPOLYFILLMODE,*PEMRSETPOLYFILLMODE,EMRSETROP2,*PEMRSETROP2,EMRSETSTRETCHBLTMODE,*PEMRSETSTRETCHBLTMODE,EMRSETTEXTALIGN,*PEMRSETTEXTALIGN,EMRENABLEICM,*PEMRENABLEICM; +} EMRSELECTCLIPPATH,*PEMRSELECTCLIPPATH, EMRSETBKMODE,*PEMRSETBKMODE, EMRSETMAPMODE, *PEMRSETMAPMODE, + EMRSETPOLYFILLMODE, *PEMRSETPOLYFILLMODE, EMRSETROP2, *PEMRSETROP2, EMRSETSTRETCHBLTMODE, *PEMRSETSTRETCHBLTMODE, + EMRSETICMMODE, *PEMRSETICMMODE, EMRSETTEXTALIGN, +#if(WINVER >= 0x0500) + EMRSETLAYOUT, *PEMRSETLAYOUT, +#endif + *PEMRSETTEXTALIGN; + #include "pshpack2.h" typedef struct tagMETAHEADER { WORD mtType; @@ -2065,7 +2072,7 @@ typedef struct tagENHMETAHEADER { #if (WINVER >= 0x0500) SIZEL szlMicrometers; #endif -} ENHMETAHEADER,*LPENHMETAHEADER; +} ENHMETAHEADER,*PENHMETAHEADER,*LPENHMETAHEADER; typedef struct tagMETARECORD { DWORD rdSize; WORD rdFunction; @@ -2078,7 +2085,7 @@ typedef struct tagENHMETARECORD { } ENHMETARECORD,*LPENHMETARECORD; typedef struct tagHANDLETABLE { HGDIOBJ objectHandle[1]; -} HANDLETABLE,*LPHANDLETABLE; +} HANDLETABLE,*PHANDLETABLE, *LPHANDLETABLE; typedef struct tagTEXTMETRICA { LONG tmHeight; LONG tmAscent; @@ -2525,6 +2532,16 @@ typedef struct _DISPLAY_DEVICEW { WCHAR DeviceKey[128]; } DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW; +#if (_WIN32_WINNT >= 0x0500) +typedef struct _RGNDATAHEADER { + DWORD dwSize; + DWORD iType; + DWORD nCount; + DWORD nRgnSize; + RECT rcBound; +} RGNDATAHEADER, *PRGNDATAHEADER; +#endif + typedef BOOL (CALLBACK *ABORTPROC)(HDC,int); typedef int (CALLBACK *MFENUMPROC)(HDC,HANDLETABLE*,METARECORD*,int,LPARAM); typedef int (CALLBACK *ENHMFENUMPROC)(HDC,HANDLETABLE*,ENHMETARECORD*,int,LPARAM); From 9b6f293ce52813cb1f5e8c5e521ee6ef551b71bf Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 20:53:47 +0000 Subject: [PATCH 336/488] adding more missing struct need them later in winetest svn path=/trunk/; revision=24261 --- reactos/include/psdk/wingdi.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/reactos/include/psdk/wingdi.h b/reactos/include/psdk/wingdi.h index c759e50e049..574890c2f0d 100644 --- a/reactos/include/psdk/wingdi.h +++ b/reactos/include/psdk/wingdi.h @@ -1187,6 +1187,16 @@ extern "C" { #define CS_DISABLE 0x00000002 #define CS_DELETE_TRANSFORM 0x00000003 #endif + +#if(WINVER >= 0x0400) +typedef struct tagEMRGLSRECORD +{ + EMR emr; + DWORD cbData; + BYTE Data[1]; +} EMRGLSRECORD, *PEMRGLSRECORD; +#endif + #if (WINVER > 0x500) #define GRADIENT_FILL_RECT_H 0x00 #define GRADIENT_FILL_RECT_V 0x01 @@ -1760,6 +1770,19 @@ typedef struct tagEMRFORMAT { DWORD cbData; DWORD offData; } EMRFORMAT; + +typedef struct tagEMRPIXELFORMAT +{ + EMR emr; + PIXELFORMATDESCRIPTOR pfd; +} EMRPIXELFORMAT, *PEMRPIXELFORMAT; +typedef struct tagEMRSETCOLORSPACE +{ + EMR emr; + DWORD ihCS; +} EMRSETCOLORSPACE, *PEMRSETCOLORSPACE, EMRSELECTCOLORSPACE, *PEMRSELECTCOLORSPACE, + EMRDELETECOLORSPACE, *PEMRDELETECOLORSPACE; + typedef struct tagEMRFRAMERGN { EMR emr; RECTL rclBounds; From 08256d0670bbda41e6cbdd7683c48da0f6cdcd82 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 21:10:36 +0000 Subject: [PATCH 337/488] sorry I broken the build it fixed now svn path=/trunk/; revision=24262 --- reactos/include/psdk/wingdi.h | 37 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/reactos/include/psdk/wingdi.h b/reactos/include/psdk/wingdi.h index 574890c2f0d..9ccc3b7a7e3 100644 --- a/reactos/include/psdk/wingdi.h +++ b/reactos/include/psdk/wingdi.h @@ -1188,14 +1188,7 @@ extern "C" { #define CS_DELETE_TRANSFORM 0x00000003 #endif -#if(WINVER >= 0x0400) -typedef struct tagEMRGLSRECORD -{ - EMR emr; - DWORD cbData; - BYTE Data[1]; -} EMRGLSRECORD, *PEMRGLSRECORD; -#endif + #if (WINVER > 0x500) #define GRADIENT_FILL_RECT_H 0x00 @@ -1496,6 +1489,15 @@ typedef struct tagEMR { DWORD iType; DWORD nSize; } EMR,*PEMR; + +#if(WINVER >= 0x0400) +typedef struct tagEMRGLSRECORD +{ + EMR emr; + DWORD cbData; + BYTE Data[1]; +} EMRGLSRECORD, *PEMRGLSRECORD; +#endif typedef struct tagEMRANGLEARC { EMR emr; POINTL ptlCenter; @@ -1771,11 +1773,7 @@ typedef struct tagEMRFORMAT { DWORD offData; } EMRFORMAT; -typedef struct tagEMRPIXELFORMAT -{ - EMR emr; - PIXELFORMATDESCRIPTOR pfd; -} EMRPIXELFORMAT, *PEMRPIXELFORMAT; + typedef struct tagEMRSETCOLORSPACE { EMR emr; @@ -1935,10 +1933,8 @@ typedef struct tagEMRSCALEVIEWPORTEXTEX { LONG yNum; LONG yDenom; } EMRSCALEVIEWPORTEXTEX,*PEMRSCALEVIEWPORTEXTEX,EMRSCALEWINDOWEXTEX,*PEMRSCALEWINDOWEXTEX; -typedef struct tagEMRSELECTCOLORSPACE { - EMR emr; - DWORD ihCS; -} EMRSELECTCOLORSPACE,*PEMRSELECTCOLORSPACE,EMRDELETECOLORSPACE,*PEMRDELETECOLORSPACE; + + typedef struct tagEMRSELECTOBJECT { EMR emr; DWORD ihObject; @@ -2344,6 +2340,13 @@ typedef struct tagPIXELFORMATDESCRIPTOR { DWORD dwVisibleMask; DWORD dwDamageMask; } PIXELFORMATDESCRIPTOR,*PPIXELFORMATDESCRIPTOR,*LPPIXELFORMATDESCRIPTOR; + +typedef struct tagEMRPIXELFORMAT +{ + EMR emr; + PIXELFORMATDESCRIPTOR pfd; +} EMRPIXELFORMAT, *PEMRPIXELFORMAT; + typedef struct tagMETAFILEPICT { LONG mm; LONG xExt; From 2b9e96e55879200f2d960330a27d1c3003949a1c Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 21:17:31 +0000 Subject: [PATCH 338/488] fixed another build break by me :( svn path=/trunk/; revision=24263 --- reactos/include/psdk/wingdi.h | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/reactos/include/psdk/wingdi.h b/reactos/include/psdk/wingdi.h index 9ccc3b7a7e3..0375635fdd8 100644 --- a/reactos/include/psdk/wingdi.h +++ b/reactos/include/psdk/wingdi.h @@ -2149,6 +2149,7 @@ typedef struct tagTEXTMETRICW { BYTE tmPitchAndFamily; BYTE tmCharSet; } TEXTMETRICW,*PTEXTMETRICW,*LPTEXTMETRICW; + typedef struct _RGNDATAHEADER { DWORD dwSize; DWORD iType; @@ -2558,15 +2559,7 @@ typedef struct _DISPLAY_DEVICEW { WCHAR DeviceKey[128]; } DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW; -#if (_WIN32_WINNT >= 0x0500) -typedef struct _RGNDATAHEADER { - DWORD dwSize; - DWORD iType; - DWORD nCount; - DWORD nRgnSize; - RECT rcBound; -} RGNDATAHEADER, *PRGNDATAHEADER; -#endif + typedef BOOL (CALLBACK *ABORTPROC)(HDC,int); typedef int (CALLBACK *MFENUMPROC)(HDC,HANDLETABLE*,METARECORD*,int,LPARAM); From 6f10b47b941892118d49b26149290a01db654855 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 24 Sep 2006 22:27:00 +0000 Subject: [PATCH 339/488] update winetest gdi32 with more wine test svn path=/trunk/; revision=24264 --- reactos/regtests/winetests/gdi32/gdi32.rbuild | 2 + reactos/regtests/winetests/gdi32/mapping.c | 160 ++++++++++++++++++ reactos/regtests/winetests/gdi32/palette.c | 126 ++++++++++++++ reactos/regtests/winetests/gdi32/testlist.c | 4 +- 4 files changed, 290 insertions(+), 2 deletions(-) create mode 100644 reactos/regtests/winetests/gdi32/mapping.c create mode 100644 reactos/regtests/winetests/gdi32/palette.c diff --git a/reactos/regtests/winetests/gdi32/gdi32.rbuild b/reactos/regtests/winetests/gdi32/gdi32.rbuild index 448a0fa8d16..e34147f9d60 100644 --- a/reactos/regtests/winetests/gdi32/gdi32.rbuild +++ b/reactos/regtests/winetests/gdi32/gdi32.rbuild @@ -12,6 +12,8 @@ dc.c gdiobj.c font.c + mapping.c metafile.c + palette.c testlist.c diff --git a/reactos/regtests/winetests/gdi32/mapping.c b/reactos/regtests/winetests/gdi32/mapping.c new file mode 100644 index 00000000000..2baeb2d8004 --- /dev/null +++ b/reactos/regtests/winetests/gdi32/mapping.c @@ -0,0 +1,160 @@ +/* + * Unit tests for mapping functions + * + * Copyright (c) 2005 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include + +#include "wine/test.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winerror.h" + + +void test_modify_world_transform(void) +{ + HDC hdc = GetDC(0); + int ret; + + ret = SetGraphicsMode(hdc, GM_ADVANCED); + if(!ret) /* running in win9x so quit */ + { + ReleaseDC(0, hdc); + return; + } + + ret = ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); + ok(ret, "ret = %d\n", ret); + + ret = ModifyWorldTransform(hdc, NULL, MWT_LEFTMULTIPLY); + ok(!ret, "ret = %d\n", ret); + + ret = ModifyWorldTransform(hdc, NULL, MWT_RIGHTMULTIPLY); + ok(!ret, "ret = %d\n", ret); + + ReleaseDC(0, hdc); +} + +void test_SetWindowExt(HDC hdc, LONG cx, LONG cy, LONG expected_vp_cx, LONG expected_vp_cy) +{ + SIZE windowExt, viewportExt; + POINT windowOrg, windowOrgAfter, viewportOrg, viewportOrgAfter; + + GetWindowOrgEx(hdc, &windowOrg); + GetViewportOrgEx(hdc, &viewportOrg); + + SetWindowExtEx(hdc, cx, cy, NULL); + GetWindowExtEx(hdc, &windowExt); + ok(windowExt.cx == cx && windowExt.cy == cy, + "Window extension: Expected %ldx%ld, got %ldx%ld\n", + cx, cy, windowExt.cx, windowExt.cy); + + GetViewportExtEx(hdc, &viewportExt); + ok(viewportExt.cx == expected_vp_cx && viewportExt.cy == expected_vp_cy, + "Viewport extents have not been properly adjusted: Expected %ldx%ld, got %ldx%ld\n", + expected_vp_cx, expected_vp_cy, viewportExt.cx, viewportExt.cy); + + GetWindowOrgEx(hdc, &windowOrgAfter); + ok(windowOrg.x == windowOrgAfter.x && windowOrg.y == windowOrgAfter.y, + "Window origin changed from (%ld,%ld) to (%ld,%ld)\n", + windowOrg.x, windowOrg.y, windowOrgAfter.x, windowOrgAfter.y); + + GetViewportOrgEx(hdc, &viewportOrgAfter); + ok(viewportOrg.x == viewportOrgAfter.x && viewportOrg.y == viewportOrgAfter.y, + "Viewport origin changed from (%ld,%ld) to (%ld,%ld)\n", + viewportOrg.x, viewportOrg.y, viewportOrgAfter.x, viewportOrgAfter.y); +} + +void test_SetViewportExt(HDC hdc, LONG cx, LONG cy, LONG expected_vp_cx, LONG expected_vp_cy) +{ + SIZE windowExt, windowExtAfter, viewportExt; + POINT windowOrg, windowOrgAfter, viewportOrg, viewportOrgAfter; + + GetWindowOrgEx(hdc, &windowOrg); + GetViewportOrgEx(hdc, &viewportOrg); + GetWindowExtEx(hdc, &windowExt); + + SetViewportExtEx(hdc, cx, cy, NULL); + GetViewportExtEx(hdc, &viewportExt); + ok(viewportExt.cx == expected_vp_cx && viewportExt.cy == expected_vp_cy, + "Viewport extents have not been properly adjusted: Expected %ldx%ld, got %ldx%ld\n", + expected_vp_cx, expected_vp_cy, viewportExt.cx, viewportExt.cy); + + GetWindowExtEx(hdc, &windowExtAfter); + ok(windowExt.cx == windowExtAfter.cx && windowExt.cy == windowExtAfter.cy, + "Window extension changed from %ldx%ld to %ldx%ld\n", + windowExt.cx, windowExt.cy, windowExtAfter.cx, windowExtAfter.cy); + + GetWindowOrgEx(hdc, &windowOrgAfter); + ok(windowOrg.x == windowOrgAfter.x && windowOrg.y == windowOrgAfter.y, + "Window origin changed from (%ld,%ld) to (%ld,%ld)\n", + windowOrg.x, windowOrg.y, windowOrgAfter.x, windowOrgAfter.y); + + GetViewportOrgEx(hdc, &viewportOrgAfter); + ok(viewportOrg.x == viewportOrgAfter.x && viewportOrg.y == viewportOrgAfter.y, + "Viewport origin changed from (%ld,%ld) to (%ld,%ld)\n", + viewportOrg.x, viewportOrg.y, viewportOrgAfter.x, viewportOrgAfter.y); +} + +void test_isotropic_mapping(void) +{ + SIZE win, vp; + HDC hdc = GetDC(0); + + SetMapMode(hdc, MM_ISOTROPIC); + + /* MM_ISOTROPIC is set up like MM_LOMETRIC. + Initial values after SetMapMode(): + (1 inch = 25.4 mm) + + Windows 9x: Windows NT: + Window Ext: 254 x -254 HORZSIZE*10 x VERTSIZE*10 + Viewport Ext: LOGPIXELSX x LOGPIXELSY HORZRES x -VERTRES + + To test without rounding errors, we have to use multiples of + these values! + */ + + GetWindowExtEx(hdc, &win); + GetViewportExtEx(hdc, &vp); + + test_SetViewportExt(hdc, 10 * vp.cx, 10 * vp.cy, 10 * vp.cx, 10 * vp.cy); + test_SetWindowExt(hdc, win.cx, win.cy, 10 * vp.cx, 10 * vp.cy); + test_SetWindowExt(hdc, 2 * win.cx, win.cy, 10 * vp.cx, 5 * vp.cy); + test_SetWindowExt(hdc, win.cx, win.cy, 5 * vp.cx, 5 * vp.cy); + test_SetViewportExt(hdc, 4 * vp.cx, 2 * vp.cy, 2 * vp.cx, 2 * vp.cy); + test_SetViewportExt(hdc, vp.cx, 2 * vp.cy, vp.cx, vp.cy); + test_SetViewportExt(hdc, 2 * vp.cx, 2 * vp.cy, 2 * vp.cx, 2 * vp.cy); + test_SetViewportExt(hdc, 4 * vp.cx, 2 * vp.cy, 2 * vp.cx, 2 * vp.cy); + test_SetWindowExt(hdc, 4 * win.cx, 2 * win.cy, 2 * vp.cx, vp.cy); + test_SetViewportExt(hdc, -2 * vp.cx, -4 * vp.cy, -2 * vp.cx, -vp.cy); + test_SetViewportExt(hdc, -2 * vp.cx, -1 * vp.cy, -2 * vp.cx, -vp.cy); + test_SetWindowExt(hdc, -4 * win.cx, -2 * win.cy, -2 * vp.cx, -vp.cy); + test_SetWindowExt(hdc, 4 * win.cx, -4 * win.cy, -vp.cx, -vp.cy); + + ReleaseDC(0, hdc); +} + +START_TEST(mapping) +{ + test_modify_world_transform(); + test_isotropic_mapping(); +} diff --git a/reactos/regtests/winetests/gdi32/palette.c b/reactos/regtests/winetests/gdi32/palette.c new file mode 100644 index 00000000000..994763985f7 --- /dev/null +++ b/reactos/regtests/winetests/gdi32/palette.c @@ -0,0 +1,126 @@ +/* + * Unit test suite for palettes + * + * Copyright 2005 Glenn Wurster + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "mmsystem.h" + +#include "wine/test.h" + +static const PALETTEENTRY logpalettedata[8] = { + { 0x10, 0x20, 0x30, PC_NOCOLLAPSE }, + { 0x20, 0x30, 0x40, PC_NOCOLLAPSE }, + { 0x30, 0x40, 0x50, PC_NOCOLLAPSE }, + { 0x40, 0x50, 0x60, PC_NOCOLLAPSE }, + { 0x50, 0x60, 0x70, PC_NOCOLLAPSE }, + { 0x60, 0x70, 0x80, PC_NOCOLLAPSE }, + { 0x70, 0x80, 0x90, PC_NOCOLLAPSE }, + { 0x80, 0x90, 0xA0, PC_NOCOLLAPSE }, +}; + +static void test_DIB_PAL_COLORS(void) { + HDC hdc = GetDC( NULL ); + HDC memhdc = CreateCompatibleDC( hdc ); + HBITMAP hbmp, hbmpOld; + char bmpbuf[sizeof(BITMAPINFO) + 10 * sizeof(WORD)]; + PBITMAPINFO bmp = (PBITMAPINFO)bmpbuf; + WORD * bmpPalPtr; + char logpalettebuf[sizeof(LOGPALETTE) + sizeof(logpalettedata)]; + PLOGPALETTE logpalette = (PLOGPALETTE)logpalettebuf; + HPALETTE hpal, hpalOld; + COLORREF setColor, chkColor, getColor; + int i; + + /* Initalize the logical palette with a few colours */ + logpalette->palVersion = 0x300; + logpalette->palNumEntries = 8; + memcpy( logpalette->palPalEntry, logpalettedata, sizeof(logpalettedata) ); + hpal = CreatePalette( logpalette ); + hpalOld = SelectPalette( memhdc, hpal, FALSE ); + ok( hpalOld != NULL, "error=%ld\n", GetLastError() ); + + /* Create a DIB BMP which references colours in the logical palette */ + memset( bmp, 0x00, sizeof(BITMAPINFO) ); + bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmp->bmiHeader.biWidth = 1; + bmp->bmiHeader.biHeight = 1; + bmp->bmiHeader.biPlanes = 1; + bmp->bmiHeader.biBitCount = 8; + bmp->bmiHeader.biCompression = BI_RGB; + bmp->bmiHeader.biClrUsed = 10; + bmp->bmiHeader.biClrImportant = 0; + bmpPalPtr = (WORD *)&bmp->bmiColors; + for( i = 0; i < 8; i++ ) { + *bmpPalPtr++ = i; + } + *bmpPalPtr++ = 8; /* Pointer to logical palette index just outside range */ + *bmpPalPtr++ = 19; /* Pointer to bad logical palette index */ + + hbmp = CreateDIBSection( memhdc, bmp, DIB_PAL_COLORS, 0, 0, 0 ); + ok( hbmp != NULL, "error=%ld\n", GetLastError() ); + hbmpOld = SelectObject( memhdc, hbmp ); + ok( hbmpOld != NULL, "error=%ld\n", GetLastError() ); + + /* Test with a RGB to DIB_PAL_COLORS */ + setColor = RGB( logpalettedata[1].peRed, logpalettedata[1].peGreen, logpalettedata[1].peBlue ); + SetPixel( memhdc, 0, 0, setColor ); + chkColor = RGB( logpalettedata[1].peRed, logpalettedata[1].peGreen, logpalettedata[1].peBlue ); + getColor = GetPixel( memhdc, 0, 0 ); + ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor ); + + /* Test with a valid DIBINDEX to DIB_PAL_COLORS */ + setColor = DIBINDEX( 2 ); + SetPixel( memhdc, 0, 0, setColor ); + chkColor = RGB( logpalettedata[2].peRed, logpalettedata[2].peGreen, logpalettedata[2].peBlue ); + getColor = GetPixel( memhdc, 0, 0 ); + ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor ); + + /* Test with a invalid DIBINDEX to DIB_PAL_COLORS */ + setColor = DIBINDEX( 12 ); + SetPixel( memhdc, 0, 0, setColor ); + chkColor = RGB( 0, 0, 0 ); + getColor = GetPixel( memhdc, 0, 0 ); + ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor ); + + /* Test for double wraparound on logical palette references from */ + /* DIBINDEX by DIB_PAL_COLORS. */ + setColor = DIBINDEX( 9 ); + SetPixel( memhdc, 0, 0, setColor ); + chkColor = RGB( logpalettedata[3].peRed, logpalettedata[3].peGreen, logpalettedata[3].peBlue ); + getColor = GetPixel( memhdc, 0, 0 ); + ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor ); + + SelectPalette( memhdc, hpalOld, FALSE ); + DeleteObject( hpal ); + SelectObject( memhdc, hbmpOld ); + DeleteObject( hbmp ); + DeleteDC( memhdc ); + ReleaseDC( NULL, hdc ); +} + +START_TEST(palette) +{ + test_DIB_PAL_COLORS(); +} diff --git a/reactos/regtests/winetests/gdi32/testlist.c b/reactos/regtests/winetests/gdi32/testlist.c index 875e34863a8..139d5fa5339 100644 --- a/reactos/regtests/winetests/gdi32/testlist.c +++ b/reactos/regtests/winetests/gdi32/testlist.c @@ -27,9 +27,9 @@ const struct test winetest_testlist[] = { "font", func_font }, { "gdiobj", func_gdiobj }, // { "generated", func_generated }, -// { "mapping", func_mapping }, + { "mapping", func_mapping }, { "metafile", func_metafile }, -// { "palette", func_palette }, + { "palette", func_palette }, // { "pen", func_pen }, { 0, 0 } }; From 604ab3e4c0f17f716a56bf2d4b60ee72f96db227 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Mon, 25 Sep 2006 05:25:11 +0000 Subject: [PATCH 340/488] Fixed some bugs in win32k function BITMAP_GetObject. svn path=/trunk/; revision=24266 --- reactos/subsystems/win32/win32k/objects/bitmaps.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/objects/bitmaps.c b/reactos/subsystems/win32/win32k/objects/bitmaps.c index 2040b81297f..4ae2c8987bb 100644 --- a/reactos/subsystems/win32/win32k/objects/bitmaps.c +++ b/reactos/subsystems/win32/win32k/objects/bitmaps.c @@ -1556,8 +1556,12 @@ BITMAPOBJ_CopyBitmap(HBITMAP hBitmap) INT STDCALL BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer) { + if( !buffer ) return sizeof(BITMAP); + if (count < sizeof(BITMAP)) return 0; + if(bmp->dib) { + if(count < (INT) sizeof(DIBSECTION)) { if (count > (INT) sizeof(BITMAP)) count = sizeof(BITMAP); @@ -1579,7 +1583,8 @@ BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer) Bitmap.bmWidthBytes = abs(bmp->SurfObj.lDelta); Bitmap.bmPlanes = 1; Bitmap.bmBitsPixel = BitsPerFormat(bmp->SurfObj.iBitmapFormat); - Bitmap.bmBits = bmp->SurfObj.pvBits; + //Bitmap.bmBits = bmp->SurfObj.pvBits; + Bitmap.bmBits = NULL; /* not set accoring wine test confirm in win2k */ memcpy(buffer, &Bitmap, count); return count; } From b79a852fe55826ad036be5c55d74024ce9fede16 Mon Sep 17 00:00:00 2001 From: Saveliy Tretiakov Date: Mon, 25 Sep 2006 08:06:20 +0000 Subject: [PATCH 341/488] - PATH_RoundRect from wine - RtlCopyMemory -> memcpy svn path=/trunk/; revision=24267 --- .../subsystems/win32/win32k/include/path.h | 2 +- .../subsystems/win32/win32k/objects/path.c | 118 ++++++++++++++++-- 2 files changed, 106 insertions(+), 14 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/path.h b/reactos/subsystems/win32/win32k/include/path.h index 9fcce87cf83..3ba47d2d556 100644 --- a/reactos/subsystems/win32/win32k/include/path.h +++ b/reactos/subsystems/win32/win32k/include/path.h @@ -19,7 +19,7 @@ BOOL FASTCALL PATH_PolylineTo (PDC dc, const POINT *pts, DWORD cbPoints); BOOL FASTCALL PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons); BOOL FASTCALL PATH_PolyPolyline( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines); BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2); -BOOL FASTCALL PATH_RoundRect (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xradius, INT yradius); +BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height); BOOL FASTCALL PATH_PathToRegion (GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn); #endif /* _WIN32K_PATH_H */ diff --git a/reactos/subsystems/win32/win32k/objects/path.c b/reactos/subsystems/win32/win32k/objects/path.c index 67033a8f9f7..91862d5f3d5 100644 --- a/reactos/subsystems/win32/win32k/objects/path.c +++ b/reactos/subsystems/win32/win32k/objects/path.c @@ -38,6 +38,7 @@ BOOL FASTCALL PATH_PathToRegion (GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn) BOOL FASTCALL PATH_ReserveEntries (GdiPath *pPath, INT numEntries); VOID FASTCALL PATH_ScaleNormalizedPoint (FLOAT_POINT corners[], double x, double y, POINT *pPoint); BOOL FASTCALL PATH_StrokePath(DC *dc, GdiPath *pPath); +BOOL PATH_CheckCorners(DC *dc, POINT corners[], INT x1, INT y1, INT x2, INT y2); INT FASTCALL IntGdiGetArcDirection(DC *dc); @@ -242,8 +243,8 @@ NtGdiGetPath( { _SEH_TRY { - RtlCopyMemory(Points, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); - RtlCopyMemory(Types, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); + memcpy(Points, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); + memcpy(Types, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); /* Convert the points to logical coordinates */ IntDPtoLP(dc, Points, pPath->numEntriesUsed); @@ -511,9 +512,9 @@ PATH_AssignGdiPath ( GdiPath *pPathDest, const GdiPath *pPathSrc ) return FALSE; /* Perform the copy operation */ - RtlCopyMemory(pPathDest->pPoints, pPathSrc->pPoints, + memcpy(pPathDest->pPoints, pPathSrc->pPoints, sizeof(POINT)*pPathSrc->numEntriesUsed); - RtlCopyMemory(pPathDest->pFlags, pPathSrc->pFlags, + memcpy(pPathDest->pFlags, pPathSrc->pFlags, sizeof(BYTE)*pPathSrc->numEntriesUsed); pPathDest->state=pPathSrc->state; @@ -648,12 +649,63 @@ PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) return TRUE; } -BOOL -FASTCALL -PATH_RoundRect (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xradius, INT yradius) +/* PATH_RoundRect + * + * Should be called when a call to RoundRect is performed on a DC that has + * an open path. Returns TRUE if successful, else FALSE. + * + * FIXME: it adds the same entries to the path as windows does, but there + * is an error in the bezier drawing code so that there are small pixel-size + * gaps when the resulting path is drawn by StrokePath() + */ +FASTCALL BOOL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height) { - UNIMPLEMENTED; - return FALSE; + GdiPath *pPath = &dc->w.path; + POINT corners[2], pointTemp; + FLOAT_POINT ellCorners[2]; + + /* Check that path is open */ + if(pPath->state!=PATH_Open) + return FALSE; + + if(!PATH_CheckCorners(dc,corners,x1,y1,x2,y2)) + return FALSE; + + /* Add points to the roundrect path */ + ellCorners[0].x = corners[1].x-ell_width; + ellCorners[0].y = corners[0].y; + ellCorners[1].x = corners[1].x; + ellCorners[1].y = corners[0].y+ell_height; + if(!PATH_DoArcPart(pPath, ellCorners, 0, -M_PI_2, TRUE)) + return FALSE; + pointTemp.x = corners[0].x+ell_width/2; + pointTemp.y = corners[0].y; + if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) + return FALSE; + ellCorners[0].x = corners[0].x; + ellCorners[1].x = corners[0].x+ell_width; + if(!PATH_DoArcPart(pPath, ellCorners, -M_PI_2, -M_PI, FALSE)) + return FALSE; + pointTemp.x = corners[0].x; + pointTemp.y = corners[1].y-ell_height/2; + if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) + return FALSE; + ellCorners[0].y = corners[1].y-ell_height; + ellCorners[1].y = corners[1].y; + if(!PATH_DoArcPart(pPath, ellCorners, M_PI, M_PI_2, FALSE)) + return FALSE; + pointTemp.x = corners[1].x-ell_width/2; + pointTemp.y = corners[1].y; + if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) + return FALSE; + ellCorners[0].x = corners[1].x-ell_width; + ellCorners[1].x = corners[1].x; + if(!PATH_DoArcPart(pPath, ellCorners, M_PI_2, 0, FALSE)) + return FALSE; + + IntGdiCloseFigure(dc); + + return TRUE; } /* PATH_Ellipse @@ -1016,6 +1068,46 @@ PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylin * Internal functions */ +/* PATH_CheckCorners + * + * Helper function for PATH_RoundRect() and PATH_Rectangle() + */ +BOOL PATH_CheckCorners(DC *dc, POINT corners[], INT x1, INT y1, INT x2, INT y2) +{ + INT temp; + + /* Convert points to device coordinates */ + corners[0].x=x1; + corners[0].y=y1; + corners[1].x=x2; + corners[1].y=y2; + CoordLPtoDP(dc, &corners[0]); + CoordLPtoDP(dc, &corners[1]); + + /* Make sure first corner is top left and second corner is bottom right */ + if(corners[0].x>corners[1].x) + { + temp=corners[0].x; + corners[0].x=corners[1].x; + corners[1].x=temp; + } + if(corners[0].y>corners[1].y) + { + temp=corners[0].y; + corners[0].y=corners[1].y; + corners[1].y=temp; + } + + /* In GM_COMPATIBLE, don't include bottom and right edges */ + if(dc->w.GraphicsMode==GM_COMPATIBLE) + { + corners[1].x--; + corners[1].y--; + } + + return TRUE; +} + /* PATH_AddFlatBezier * @@ -1239,8 +1331,8 @@ PATH_ReserveEntries ( GdiPath *pPath, INT numEntries ) { ASSERT(pPath->pFlags); - RtlCopyMemory(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); - RtlCopyMemory(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); + memcpy(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); + memcpy(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); ExFreePool(pPath->pPoints); ExFreePool(pPath->pFlags); @@ -1461,11 +1553,11 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, GdiPath *pPath) goto end; } - RtlCopyMemory(Realloc, pLinePts, nLinePts*sizeof(POINT)); + memcpy(Realloc, pLinePts, nLinePts*sizeof(POINT)); ExFreePool(pLinePts); pLinePts = Realloc; } - RtlCopyMemory(&pLinePts[nLinePts], &pBzrPts[1], (nBzrPts - 1) * sizeof(POINT)); + memcpy(&pLinePts[nLinePts], &pBzrPts[1], (nBzrPts - 1) * sizeof(POINT)); nLinePts += nBzrPts - 1; ExFreePool(pBzrPts); i += 2; From 888f16ea6f6eec55ce69a3da6101f7dbbaab48d0 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Mon, 25 Sep 2006 18:50:40 +0000 Subject: [PATCH 342/488] NtGdiRestoreDC 1. fix do not delete all hdc and the restore hdc. 2. fix calc of SaveLevel the calc are not perfect we only have 6 fails when we try restore dc now with wine gdi32 test dc svn path=/trunk/; revision=24268 --- reactos/subsystems/win32/win32k/objects/dc.c | 76 ++++++++++---------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index 0f46955d9c0..72c9b51a6fb 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -1940,55 +1940,57 @@ NtGdiRestoreDC(HDC hDC, INT SaveLevel) return FALSE; } - if (SaveLevel == -1) - SaveLevel = dc->saveLevel; - - if ((SaveLevel < 1) || (SaveLevel > dc->saveLevel)) + if(abs(SaveLevel) > dc->saveLevel || SaveLevel == 0) { DC_UnlockDc(dc); return FALSE; } - success = TRUE; + /* FIXME this calc are not 100% correct I think ??*/ + if (SaveLevel < 0) SaveLevel = dc->saveLevel + SaveLevel + 1; + + success=TRUE; while (dc->saveLevel >= SaveLevel) { - HDC hdcs = DC_GetNextDC (dc); + HDC hdcs = DC_GetNextDC (dc); - dcs = DC_LockDc (hdcs); - if (dcs == NULL) - { - DC_UnlockDc(dc); - return FALSE; - } - DC_SetNextDC (dcs, DC_GetNextDC (dcs)); - if (--dc->saveLevel < SaveLevel) - { - DC_UnlockDc( dc ); - DC_UnlockDc( dcs ); - NtGdiSetDCState(hDC, hdcs); -#if 0 - if (!PATH_AssignGdiPath( &dc->w.path, &dcs->w.path )) - { - /* FIXME: This might not be quite right, since we're - * returning FALSE but still destroying the saved DC state */ - success = FALSE; - } -#endif - dc = DC_LockDc(hDC); - if(!dc) - { - return FALSE; - } - } - else - { - DC_UnlockDc( dcs ); - } - NtGdiDeleteObjectApp (hdcs); + dcs = DC_LockDc (hdcs); + if (dcs == NULL) + { + DC_UnlockDc(dc); + return FALSE; + } + + DC_SetNextDC (dc, DC_GetNextDC (dcs)); + dcs->hNext = 0; + + if (--dc->saveLevel < SaveLevel) + { + DC_UnlockDc( dc ); + DC_UnlockDc( dcs ); + + NtGdiSetDCState(hDC, hdcs); + //if (!PATH_AssignGdiPath( &dc->path, &dcs->path )) + /* FIXME: This might not be quite right, since we're + * returning FALSE but still destroying the saved DC state + */ + success=FALSE; + dc = DC_LockDc(hDC); + if(!dc) + { + return FALSE; + } + } + else + { + DC_UnlockDc( dcs ); + } + NtGdiDeleteObjectApp (hdcs); } DC_UnlockDc( dc ); return success; } + INT STDCALL NtGdiSaveDC(HDC hDC) From ff8121c676cf07266d44c0f0c7ef8fb9a59f6842 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 25 Sep 2006 19:28:40 +0000 Subject: [PATCH 343/488] * fix typo in german resource file spotted by pilic * fix bug 1797 * set svn-eolstyle:native property See issue #1797 for more details. svn path=/trunk/; revision=24269 --- reactos/base/applications/notepad/lang/Cs.rc | 330 +++++++-------- reactos/base/applications/notepad/lang/Da.rc | 326 +++++++-------- reactos/base/applications/notepad/lang/De.rc | 384 ++++++++--------- reactos/base/applications/notepad/lang/En.rc | 408 +++++++++---------- reactos/base/applications/notepad/lang/Es.rc | 348 ++++++++-------- reactos/base/applications/notepad/lang/Fi.rc | 322 +++++++-------- reactos/base/applications/notepad/lang/Fr.rc | 328 +++++++-------- reactos/base/applications/notepad/lang/Gr.rc | 406 +++++++++--------- reactos/base/applications/notepad/lang/Hu.rc | 328 +++++++-------- reactos/base/applications/notepad/lang/It.rc | 330 +++++++-------- reactos/base/applications/notepad/lang/Ja.rc | 408 +++++++++---------- reactos/base/applications/notepad/lang/Nl.rc | 322 +++++++-------- reactos/base/applications/notepad/lang/Pl.rc | 328 +++++++-------- reactos/base/applications/notepad/lang/Pt.rc | 328 +++++++-------- reactos/base/applications/notepad/lang/Ru.rc | 318 +++++++-------- reactos/base/applications/notepad/lang/Si.rc | 320 +++++++-------- reactos/base/applications/notepad/lang/Sk.rc | 334 +++++++-------- reactos/base/applications/notepad/lang/Sv.rc | 324 +++++++-------- reactos/base/applications/notepad/lang/Th.rc | 312 +++++++------- reactos/base/applications/notepad/lang/Uk.rc | 392 +++++++++--------- reactos/base/applications/notepad/lang/Wa.rc | 322 +++++++-------- reactos/base/applications/notepad/lang/Zh.rc | 320 +++++++-------- 22 files changed, 3769 insertions(+), 3769 deletions(-) diff --git a/reactos/base/applications/notepad/lang/Cs.rc b/reactos/base/applications/notepad/lang/Cs.rc index 420f25a450d..6bf0fff227c 100644 --- a/reactos/base/applications/notepad/lang/Cs.rc +++ b/reactos/base/applications/notepad/lang/Cs.rc @@ -1,165 +1,165 @@ -/* - * Notepad (Czech resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Copyright 2002 Sylvain Petreolle - * Copyright 2004 David Kredba - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_CZECH, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Soubor" - BEGIN - MENUITEM "&Nový...", CMD_NEW - MENUITEM "&Otevřít\tCtrl+O", CMD_OPEN - MENUITEM "&Uloľit\tCtrl+S", CMD_SAVE - MENUITEM "Uloľit j&ako...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "&Tisk", CMD_PRINT - MENUITEM "Nas&tavení stránky...", CMD_PAGE_SETUP - MENUITEM "Nastavení tiská&rny...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Konec", CMD_EXIT - END - POPUP "U&pravit" - BEGIN - MENUITEM "&Zpět\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "Vyjmou&t\tCtrl+X", CMD_CUT - MENUITEM "&Kopírovat\tCtrl+C", CMD_COPY - MENUITEM "&Vloľit\tCtrl+V", CMD_PASTE - MENUITEM "&Smazat\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Hledej\tCtrl+F", CMD_SEARCH - MENUITEM "&Najdi daląí\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "Vybrat vą&e\tCtrl+A", CMD_SELECT_ALL - MENUITEM "Č&as/Datum\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "Zalo&mit dlouhé řádky", CMD_WRAP - MENUITEM "&Písmo...", CMD_FONT - END - POPUP "&Nápověda" - BEGIN - MENUITEM "&Obsah", CMD_HELP_CONTENTS - MENUITEM "&Najít...", CMD_HELP_SEARCH - MENUITEM "&Pomoc k nápovědě", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Inf&o...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Nastavení stránky" -{ -LTEXT "Zá&hlaví:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Zápatí:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Okraje:", 0x144, 10, 43,160, 45 -LTEXT "&Levý:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Horní:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "P&ravý:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Dolní:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Storno", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Nápověda", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Strana &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Notepad" -STRING_ERROR, "CHYBA" -STRING_WARNING, "VAROVÁNÍ" -STRING_INFO, "Informace" - -STRING_UNTITLED, "(bez názvu)" - -STRING_ALL_FILES, "Vąechny soubory (*.*)" -STRING_TEXT_FILES_TXT, "Textové soubory (*.txt)" - -STRING_TOOLARGE, "Soubor '%s' je pro notepad přílią velký.\n \ -Pouľijte jiný editor, prosím." -STRING_NOTEXT, "Nebyl zadán ľádný text. \ -\nPlease type something and try again" -STRING_DOESNOTEXIST, "Soubor '%s'\nneexistuje.\n\n \ -Chcete ho vytvořit ?" -STRING_NOTSAVED, "Soubor '%s'\nbyl změněn.\n\n \ -Chcete uloľit změny ?" -STRING_NOTFOUND, "'%s' nebyl nalezen." -STRING_OUT_OF_MEMORY, "Není dost paměti na dokončení této úlohy. \ -\nUzavřete jednu či více aplikací abyste získali více \nvolné \ -paměti." - -} +/* + * Notepad (Czech resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * Copyright 2004 David Kredba + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Soubor" + BEGIN + MENUITEM "&Nový...", CMD_NEW + MENUITEM "&Otevřít\tCtrl+O", CMD_OPEN + MENUITEM "&Uloľit\tCtrl+S", CMD_SAVE + MENUITEM "Uloľit j&ako...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "&Tisk", CMD_PRINT + MENUITEM "Nas&tavení stránky...", CMD_PAGE_SETUP + MENUITEM "Nastavení tiská&rny...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Konec", CMD_EXIT + END + POPUP "U&pravit" + BEGIN + MENUITEM "&Zpět\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Vyjmou&t\tCtrl+X", CMD_CUT + MENUITEM "&Kopírovat\tCtrl+C", CMD_COPY + MENUITEM "&Vloľit\tCtrl+V", CMD_PASTE + MENUITEM "&Smazat\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Hledej\tCtrl+F", CMD_SEARCH + MENUITEM "&Najdi daląí\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "Vybrat vą&e\tCtrl+A", CMD_SELECT_ALL + MENUITEM "Č&as/Datum\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "Zalo&mit dlouhé řádky", CMD_WRAP + MENUITEM "&Písmo...", CMD_FONT + END + POPUP "&Nápověda" + BEGIN + MENUITEM "&Obsah", CMD_HELP_CONTENTS + MENUITEM "&Najít...", CMD_HELP_SEARCH + MENUITEM "&Pomoc k nápovědě", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Inf&o...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Nastavení stránky" +{ +LTEXT "Zá&hlaví:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Zápatí:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Okraje:", 0x144, 10, 43,160, 45 +LTEXT "&Levý:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Horní:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "P&ravý:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Dolní:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Storno", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Nápověda", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Strana &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notepad" +STRING_ERROR, "CHYBA" +STRING_WARNING, "VAROVÁNÍ" +STRING_INFO, "Informace" + +STRING_UNTITLED, "(bez názvu)" + +STRING_ALL_FILES, "Vąechny soubory (*.*)" +STRING_TEXT_FILES_TXT, "Textové soubory (*.txt)" + +STRING_TOOLARGE, "Soubor '%s' je pro notepad přílią velký.\n \ +Pouľijte jiný editor, prosím." +STRING_NOTEXT, "Nebyl zadán ľádný text. \ +\nPlease type something and try again" +STRING_DOESNOTEXIST, "Soubor '%s'\nneexistuje.\n\n \ +Chcete ho vytvořit ?" +STRING_NOTSAVED, "Soubor '%s'\nbyl změněn.\n\n \ +Chcete uloľit změny ?" +STRING_NOTFOUND, "'%s' nebyl nalezen." +STRING_OUT_OF_MEMORY, "Není dost paměti na dokončení této úlohy. \ +\nUzavřete jednu či více aplikací abyste získali více \nvolné \ +paměti." + +} diff --git a/reactos/base/applications/notepad/lang/Da.rc b/reactos/base/applications/notepad/lang/Da.rc index ca5bc959849..3f94cce81ad 100644 --- a/reactos/base/applications/notepad/lang/Da.rc +++ b/reactos/base/applications/notepad/lang/Da.rc @@ -1,163 +1,163 @@ -/* - * Notepad (Danish resources) - * - * Copyright 1998 Henrik Olsen - * Copyright 2002 Sylvain Petreolle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_DANISH, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Fil" - BEGIN - MENUITEM "&Ny...", CMD_NEW - MENUITEM "Ĺ&bn\tEnter", CMD_OPEN - MENUITEM "&Gem", CMD_SAVE - MENUITEM "Gem so&m...", CMD_SAVE_AS - MENUITEM "Side&opsćtning...", CMD_PAGE_SETUP - MENUITEM "&Udskriv", CMD_PRINT - MENUITEM "&Indstil printer...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Afslut", CMD_EXIT - END - POPUP "&Rediger" - BEGIN - MENUITEM "&Fortryd\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Klip\tCtrl+X", CMD_CUT - MENUITEM "K&opier\tCtrl+C", CMD_COPY - MENUITEM "Sćt &ind\tCtrl+V", CMD_PASTE - MENUITEM "&Slet\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "Marker &alt", CMD_SELECT_ALL - MENUITEM "&Dato/tid\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "Automatisk &linjeskift", CMD_WRAP - END - POPUP "&Sřg" - BEGIN - MENUITEM "&Sřg...", CMD_SEARCH - MENUITEM "&Find nćste\tF3", CMD_SEARCH_NEXT - END - POPUP "&Hjćlp" - BEGIN - MENUITEM "&Indhold", CMD_HELP_CONTENTS - MENUITEM "&Sřg efter hjćlp om...", CMD_HELP_SEARCH - MENUITEM "&Brug af Hjćlp", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "&Om Notesblok", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Sideopsćtning" -{ -LTEXT "&Sidehoved:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "Side&fod:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "Margener:", 0x144, 10, 43,160, 45 -LTEXT "&Venstre:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Top:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Hřjre:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Bund:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Annuller", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Hjćlp", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Side &s" -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Notesblok" -STRING_ERROR, "Fejl" -STRING_WARNING, "Advarsel" -STRING_INFO, "Information" - -STRING_UNTITLED, "(ikke-navngivet)" - -STRING_ALL_FILES, "Alle filer (*.*)" -STRING_TEXT_FILES_TXT, "Tekst filer (*.txt)" - -STRING_TOOLARGE, "Filen '%s' er for stor til Notesblok. \ -\nBrug en anden editor til at redigere filen." -STRING_NOTEXT, "Du har ikke skrevet noget tekst. \ -\nSkriv noget tekst, og prřv sĺ igen" -STRING_DOESNOTEXIST, "Filen '%s'\neksistere ikke\n\n \ -Řnkser du at oprette en ny fil?" -STRING_NOTSAVED, "Filen '%s'\ner blevet ćndret\n\n \ -Řnsker du at gemme ćndringerne?" -STRING_NOTFOUND, "Kan ikke finde '%s'." -STRING_OUT_OF_MEMORY, "Der er ikke nok hukommelse til at udfřre \ -denne operation. \nAfslut et eller flere aktive programmer for at frigřre \ -hukommelse, og prřv sĺ igen." - -} +/* + * Notepad (Danish resources) + * + * Copyright 1998 Henrik Olsen + * Copyright 2002 Sylvain Petreolle + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_DANISH, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Fil" + BEGIN + MENUITEM "&Ny...", CMD_NEW + MENUITEM "Ĺ&bn\tEnter", CMD_OPEN + MENUITEM "&Gem", CMD_SAVE + MENUITEM "Gem so&m...", CMD_SAVE_AS + MENUITEM "Side&opsćtning...", CMD_PAGE_SETUP + MENUITEM "&Udskriv", CMD_PRINT + MENUITEM "&Indstil printer...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Afslut", CMD_EXIT + END + POPUP "&Rediger" + BEGIN + MENUITEM "&Fortryd\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Klip\tCtrl+X", CMD_CUT + MENUITEM "K&opier\tCtrl+C", CMD_COPY + MENUITEM "Sćt &ind\tCtrl+V", CMD_PASTE + MENUITEM "&Slet\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "Marker &alt", CMD_SELECT_ALL + MENUITEM "&Dato/tid\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "Automatisk &linjeskift", CMD_WRAP + END + POPUP "&Sřg" + BEGIN + MENUITEM "&Sřg...", CMD_SEARCH + MENUITEM "&Find nćste\tF3", CMD_SEARCH_NEXT + END + POPUP "&Hjćlp" + BEGIN + MENUITEM "&Indhold", CMD_HELP_CONTENTS + MENUITEM "&Sřg efter hjćlp om...", CMD_HELP_SEARCH + MENUITEM "&Brug af Hjćlp", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "&Om Notesblok", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Sideopsćtning" +{ +LTEXT "&Sidehoved:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "Side&fod:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "Margener:", 0x144, 10, 43,160, 45 +LTEXT "&Venstre:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Top:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Hřjre:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Bund:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Annuller", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Hjćlp", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Side &s" +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notesblok" +STRING_ERROR, "Fejl" +STRING_WARNING, "Advarsel" +STRING_INFO, "Information" + +STRING_UNTITLED, "(ikke-navngivet)" + +STRING_ALL_FILES, "Alle filer (*.*)" +STRING_TEXT_FILES_TXT, "Tekst filer (*.txt)" + +STRING_TOOLARGE, "Filen '%s' er for stor til Notesblok. \ +\nBrug en anden editor til at redigere filen." +STRING_NOTEXT, "Du har ikke skrevet noget tekst. \ +\nSkriv noget tekst, og prřv sĺ igen" +STRING_DOESNOTEXIST, "Filen '%s'\neksistere ikke\n\n \ +Řnkser du at oprette en ny fil?" +STRING_NOTSAVED, "Filen '%s'\ner blevet ćndret\n\n \ +Řnsker du at gemme ćndringerne?" +STRING_NOTFOUND, "Kan ikke finde '%s'." +STRING_OUT_OF_MEMORY, "Der er ikke nok hukommelse til at udfřre \ +denne operation. \nAfslut et eller flere aktive programmer for at frigřre \ +hukommelse, og prřv sĺ igen." + +} diff --git a/reactos/base/applications/notepad/lang/De.rc b/reactos/base/applications/notepad/lang/De.rc index 209f4e48232..130ecadc0d3 100644 --- a/reactos/base/applications/notepad/lang/De.rc +++ b/reactos/base/applications/notepad/lang/De.rc @@ -1,192 +1,192 @@ -/* - * Notepad (German resources) - * - * Copyright 1997,98 Marcel Baur - * Copyright 2002 Sylvain Petreolle - * - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Datei" - BEGIN - MENUITEM "&Neu...", CMD_NEW - MENUITEM "Ö&ffnen...", CMD_OPEN - MENUITEM "&Speichern", CMD_SAVE - MENUITEM "Speichern &unter...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "Seite ein&richten...", CMD_PAGE_SETUP - MENUITEM "&Drucken", CMD_PRINT - MENUITEM "Drucker&einrichtung...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Beenden", CMD_EXIT - END - POPUP "&Bearbeiten" - BEGIN - MENUITEM "&Rückgängig\tStrg+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Ausschneiden\tStrg+X", CMD_CUT - MENUITEM "&Kopieren\tStrg+C", CMD_COPY - MENUITEM "&Einfügen\tStrg+V", CMD_PASTE - MENUITEM "&Löschen\tEntf", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "Suchen...", CMD_SEARCH - MENUITEM "&Weitersuchen\tF3", CMD_SEARCH_NEXT - MENUITEM "&Ersetzen\tCtrl+H", CMD_REPLACE - MENUITEM "Gehe zu...\tCtrl+G", CMD_GOTO - MENUITEM SEPARATOR - MENUITEM "Alles &markieren", CMD_SELECT_ALL - MENUITEM "&Uhrzeit/Datum\tF5", CMD_TIME_DATE - END - POPUP "F&ormat" - BEGIN - MENUITEM "&Zeilenumbruch", CMD_WRAP - MENUITEM "&Schriftart...", CMD_FONT - END - POPUP "&Anicht" - BEGIN - MENUITEM "Status&leiste", CMD_STATUSBAR - END - POPUP "&Hilfe" - BEGIN - MENUITEM "&Inhalt", CMD_HELP_CONTENTS - MENUITEM "&Suchen...", CMD_HELP_SEARCH - MENUITEM "&Hilfe benutzen", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&Über" CMD_ABOUT - MENUITEM "Inf&o", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Seite einrichten" -{ -LTEXT "&Kopfzeile:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Fußzeile:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "Ränder", 0x144, 10, 43,160, 45 -LTEXT "&Links:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Oben:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Rechts:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Unten:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", IDOK, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Abbrechen", IDCANCEL, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Hilfe", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -/* Dialog 'Gehe zu...' */ -DIALOG_GOTO DIALOG 0,0,165,50 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Gehe zu Zeile" -{ -EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Zeile Nummer:",0x155,5,12,45,12,WS_CHILD | WS_TABSTOP | ES_NUMBER -DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP -PUSHBUTTON "Abbrechen", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "Über ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL "", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Schließen",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "Dieses Programm ist kostenlos; Sie können es frei verteilen mit od. ohne Änderungen unter der GNU Lesser General Public License wie es von der Free Software Foundation veröffentlicht wurde; entweder Version 2.1 der Lizenz, oder eine spätere Version (ihrer Wahl).\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Seite &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Editor" -STRING_ERROR, "Fehler" -STRING_WARNING, "Achtung" -STRING_INFO, "Information" - -STRING_UNTITLED, "(unbenannt)" - -STRING_ALL_FILES, "Alle Dateien (*.*)" -STRING_TEXT_FILES_TXT, "Textdateien (*.txt)" - -STRING_TOOLARGE, "Die Datei '%s' ist zu groß für den Editor\n \ -Benutzen Sie bitte einen anderen Editor, um diese Datei zu bearbeiten." -STRING_NOTEXT, "Sie haben keinen Text eingegeben, der \ -gespeichert\n werden könnte. Geben Sie Text ein, und versuchen Sie es \ -\nerneut." -STRING_DOESNOTEXIST, "Die Datei '%s'\nexistiert nicht.\n\n \ -Möchten Sie eine neue Datei erstellen ?" -STRING_NOTSAVED, "Datei %s\n wurde geändert.\n\n \ -Möchten Sie die Änderungen speichern ?" -STRING_NOTFOUND, "'%s' kann nicht gefunden werden." -STRING_OUT_OF_MEMORY, "Nicht genügend Arbeitsspeicher, \ -um diese Funktion \nabzuschließen. Beenden Sie eine oder mehrere \ -\nAnwendungen, um den verfügbaren Arbeitsspeicher zu \nerhöhen." -STRING_CANNOTFIND "'%s' wurde nicht gefunden." -STRING_ANSI, "ANSI" -STRING_UNICODE, "Unicode" -STRING_UNICODE_BE, "Unicode (big endian)" -STRING_UTF8, "UTF-8" -STRING_CRLF, "Windows" -STRING_LF, "Unix" -STRING_CR, "Mac" -} +/* + * Notepad (German resources) + * + * Copyright 1997,98 Marcel Baur + * Copyright 2002 Sylvain Petreolle + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Datei" + BEGIN + MENUITEM "&Neu...", CMD_NEW + MENUITEM "Ö&ffnen...", CMD_OPEN + MENUITEM "&Speichern", CMD_SAVE + MENUITEM "Speichern &unter...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Seite ein&richten...", CMD_PAGE_SETUP + MENUITEM "&Drucken", CMD_PRINT + MENUITEM "Drucker&einrichtung...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Beenden", CMD_EXIT + END + POPUP "&Bearbeiten" + BEGIN + MENUITEM "&Rückgängig\tStrg+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Ausschneiden\tStrg+X", CMD_CUT + MENUITEM "&Kopieren\tStrg+C", CMD_COPY + MENUITEM "&Einfügen\tStrg+V", CMD_PASTE + MENUITEM "&Löschen\tEntf", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "Suchen...", CMD_SEARCH + MENUITEM "&Weitersuchen\tF3", CMD_SEARCH_NEXT + MENUITEM "&Ersetzen\tCtrl+H", CMD_REPLACE + MENUITEM "Gehe zu...\tCtrl+G", CMD_GOTO + MENUITEM SEPARATOR + MENUITEM "Alles &markieren", CMD_SELECT_ALL + MENUITEM "&Uhrzeit/Datum\tF5", CMD_TIME_DATE + END + POPUP "F&ormat" + BEGIN + MENUITEM "&Zeilenumbruch", CMD_WRAP + MENUITEM "&Schriftart...", CMD_FONT + END + POPUP "&Ansicht" + BEGIN + MENUITEM "Status&leiste", CMD_STATUSBAR + END + POPUP "&Hilfe" + BEGIN + MENUITEM "&Inhalt", CMD_HELP_CONTENTS + MENUITEM "&Suchen...", CMD_HELP_SEARCH + MENUITEM "&Hilfe benutzen", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&Über" CMD_ABOUT + MENUITEM "Inf&o", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Seite einrichten" +{ +LTEXT "&Kopfzeile:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Fußzeile:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "Ränder", 0x144, 10, 43,160, 45 +LTEXT "&Links:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Oben:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Rechts:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Unten:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", IDOK, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Abbrechen", IDCANCEL, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Hilfe", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +/* Dialog 'Gehe zu...' */ +DIALOG_GOTO DIALOG 0,0,165,50 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Gehe zu Zeile" +{ +EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Zeile Nummer:",0x155,5,12,45,12,WS_CHILD | WS_TABSTOP | ES_NUMBER +DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP +PUSHBUTTON "Abbrechen", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Über ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL "", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Schließen",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "Dieses Programm ist kostenlos; Sie können es frei verteilen mit od. ohne Änderungen unter der GNU Lesser General Public License wie es von der Free Software Foundation veröffentlicht wurde; entweder Version 2.1 der Lizenz, oder eine spätere Version (ihrer Wahl).\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Seite &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Editor" +STRING_ERROR, "Fehler" +STRING_WARNING, "Achtung" +STRING_INFO, "Information" + +STRING_UNTITLED, "(unbenannt)" + +STRING_ALL_FILES, "Alle Dateien (*.*)" +STRING_TEXT_FILES_TXT, "Textdateien (*.txt)" + +STRING_TOOLARGE, "Die Datei '%s' ist zu groß für den Editor\n \ +Benutzen Sie bitte einen anderen Editor, um diese Datei zu bearbeiten." +STRING_NOTEXT, "Sie haben keinen Text eingegeben, der \ +gespeichert\n werden könnte. Geben Sie Text ein, und versuchen Sie es \ +\nerneut." +STRING_DOESNOTEXIST, "Die Datei '%s'\nexistiert nicht.\n\n \ +Möchten Sie eine neue Datei erstellen ?" +STRING_NOTSAVED, "Datei %s\n wurde geändert.\n\n \ +Möchten Sie die Änderungen speichern ?" +STRING_NOTFOUND, "'%s' kann nicht gefunden werden." +STRING_OUT_OF_MEMORY, "Nicht genügend Arbeitsspeicher, \ +um diese Funktion \nabzuschließen. Beenden Sie eine oder mehrere \ +\nAnwendungen, um den verfügbaren Arbeitsspeicher zu \nerhöhen." +STRING_CANNOTFIND "'%s' wurde nicht gefunden." +STRING_ANSI, "ANSI" +STRING_UNICODE, "Unicode" +STRING_UNICODE_BE, "Unicode (big endian)" +STRING_UTF8, "UTF-8" +STRING_CRLF, "Windows" +STRING_LF, "Unix" +STRING_CR, "Mac" +} diff --git a/reactos/base/applications/notepad/lang/En.rc b/reactos/base/applications/notepad/lang/En.rc index 5f9a23d0bed..ab0145b767f 100644 --- a/reactos/base/applications/notepad/lang/En.rc +++ b/reactos/base/applications/notepad/lang/En.rc @@ -1,204 +1,204 @@ -/* - * Notepad (English resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Copyright 2002 Sylvain Petreolle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&New...", CMD_NEW - MENUITEM "&Open\tCtrl+O", CMD_OPEN - MENUITEM "&Save\tCtrl+S", CMD_SAVE - MENUITEM "Save &as...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "Page Se&tup...", CMD_PAGE_SETUP - MENUITEM "&Print", CMD_PRINT - MENUITEM "P&rinter Setup...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "E&xit", CMD_EXIT - END - POPUP "&Edit" - BEGIN - MENUITEM "&Undo\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "Cu&t\tCtrl+X", CMD_CUT - MENUITEM "&Copy\tCtrl+C", CMD_COPY - MENUITEM "&Paste\tCtrl+V", CMD_PASTE - MENUITEM "&Delete\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Find...\tCtrl+F", CMD_SEARCH - MENUITEM "Find &next\tF3", CMD_SEARCH_NEXT - MENUITEM "Replace\tCtrl+H", CMD_REPLACE - MENUITEM "Go To...\tCtrl+G", CMD_GOTO - MENUITEM SEPARATOR - MENUITEM "Select &all\tCtrl+A", CMD_SELECT_ALL - MENUITEM "&Time/Date\tF5", CMD_TIME_DATE - END - POPUP "F&ormat" - BEGIN - MENUITEM "&Wrap long lines", CMD_WRAP - MENUITEM "&Font...", CMD_FONT - END - POPUP "&View" - BEGIN - MENUITEM "Status&bar", CMD_STATUSBAR - END - POPUP "&Help" - BEGIN - MENUITEM "&Contents", CMD_HELP_CONTENTS - MENUITEM "&Search...", CMD_HELP_SEARCH - MENUITEM "&Help on help", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Inf&o", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Page Setup" -{ -LTEXT "&Header:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Footer:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Margins:", 0x144, 10, 43,160, 45 -LTEXT "&Left:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Top:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Right:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Bottom:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", IDOK, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Cancel", IDCANCEL, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Help", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -/* Dialog `Encoding' */ -DIALOG_ENCODING DIALOG 0, 0, 256, 44 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | - WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Encoding" -{ -COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP -LTEXT "Encoding:",0x155,5,2,41,12 -COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -LTEXT "Endlines:",0x156,5,20,41,12 -} - -/* Dialog 'Go To' */ -DIALOG_GOTO DIALOG 0,0,165,50 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Goto line" -{ -EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Line number:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER -DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP -PUSHBUTTON "Cancel", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Notepad" -STRING_ERROR, "ERROR" -STRING_WARNING, "WARNING" -STRING_INFO, "Information" - -STRING_UNTITLED, "(untitled)" - -STRING_ALL_FILES, "All files (*.*)" -STRING_TEXT_FILES_TXT, "Text files (*.txt)" - -STRING_TOOLARGE, "File '%s' is too large for notepad.\n \ -Please use a different editor." -STRING_NOTEXT, "You didn't enter any text. \ -\nPlease type something and try again" -STRING_DOESNOTEXIST, "File '%s'\ndoes not exist\n\n \ -Do you want to create a new file ?" -STRING_NOTSAVED, "File '%s'\nhas been modified\n\n \ -Would you like to save the changes ?" -STRING_NOTFOUND, "'%s' can not be found." -STRING_OUT_OF_MEMORY, "Not enough memory to complete this \ -task. \nClose one or more applications to increase the amount of \nfree \ -memory." -STRING_CANNOTFIND "Cannot find '%s'" -STRING_ANSI, "ANSI" -STRING_UNICODE, "Unicode" -STRING_UNICODE_BE, "Unicode (big endian)" -STRING_UTF8, "UTF-8" -STRING_CRLF, "Windows" -STRING_LF, "Unix" -STRING_CR, "Mac" -} +/* + * Notepad (English resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New...", CMD_NEW + MENUITEM "&Open\tCtrl+O", CMD_OPEN + MENUITEM "&Save\tCtrl+S", CMD_SAVE + MENUITEM "Save &as...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Page Se&tup...", CMD_PAGE_SETUP + MENUITEM "&Print", CMD_PRINT + MENUITEM "P&rinter Setup...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "E&xit", CMD_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "&Undo\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Cu&t\tCtrl+X", CMD_CUT + MENUITEM "&Copy\tCtrl+C", CMD_COPY + MENUITEM "&Paste\tCtrl+V", CMD_PASTE + MENUITEM "&Delete\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Find...\tCtrl+F", CMD_SEARCH + MENUITEM "Find &next\tF3", CMD_SEARCH_NEXT + MENUITEM "Replace\tCtrl+H", CMD_REPLACE + MENUITEM "Go To...\tCtrl+G", CMD_GOTO + MENUITEM SEPARATOR + MENUITEM "Select &all\tCtrl+A", CMD_SELECT_ALL + MENUITEM "&Time/Date\tF5", CMD_TIME_DATE + END + POPUP "F&ormat" + BEGIN + MENUITEM "&Wrap long lines", CMD_WRAP + MENUITEM "&Font...", CMD_FONT + END + POPUP "&View" + BEGIN + MENUITEM "Status&bar", CMD_STATUSBAR + END + POPUP "&Help" + BEGIN + MENUITEM "&Contents", CMD_HELP_CONTENTS + MENUITEM "&Search...", CMD_HELP_SEARCH + MENUITEM "&Help on help", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Inf&o", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Page Setup" +{ +LTEXT "&Header:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Footer:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Margins:", 0x144, 10, 43,160, 45 +LTEXT "&Left:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Top:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Right:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Bottom:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", IDOK, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Cancel", IDCANCEL, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Help", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +/* Dialog `Encoding' */ +DIALOG_ENCODING DIALOG 0, 0, 256, 44 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | + WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Encoding" +{ +COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP +LTEXT "Encoding:",0x155,5,2,41,12 +COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +LTEXT "Endlines:",0x156,5,20,41,12 +} + +/* Dialog 'Go To' */ +DIALOG_GOTO DIALOG 0,0,165,50 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Goto line" +{ +EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Line number:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER +DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP +PUSHBUTTON "Cancel", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notepad" +STRING_ERROR, "ERROR" +STRING_WARNING, "WARNING" +STRING_INFO, "Information" + +STRING_UNTITLED, "(untitled)" + +STRING_ALL_FILES, "All files (*.*)" +STRING_TEXT_FILES_TXT, "Text files (*.txt)" + +STRING_TOOLARGE, "File '%s' is too large for notepad.\n \ +Please use a different editor." +STRING_NOTEXT, "You didn't enter any text. \ +\nPlease type something and try again" +STRING_DOESNOTEXIST, "File '%s'\ndoes not exist\n\n \ +Do you want to create a new file ?" +STRING_NOTSAVED, "File '%s'\nhas been modified\n\n \ +Would you like to save the changes ?" +STRING_NOTFOUND, "'%s' can not be found." +STRING_OUT_OF_MEMORY, "Not enough memory to complete this \ +task. \nClose one or more applications to increase the amount of \nfree \ +memory." +STRING_CANNOTFIND "Cannot find '%s'" +STRING_ANSI, "ANSI" +STRING_UNICODE, "Unicode" +STRING_UNICODE_BE, "Unicode (big endian)" +STRING_UTF8, "UTF-8" +STRING_CRLF, "Windows" +STRING_LF, "Unix" +STRING_CR, "Mac" +} diff --git a/reactos/base/applications/notepad/lang/Es.rc b/reactos/base/applications/notepad/lang/Es.rc index 36621c97e28..f9cba0ed267 100644 --- a/reactos/base/applications/notepad/lang/Es.rc +++ b/reactos/base/applications/notepad/lang/Es.rc @@ -1,174 +1,174 @@ -/* - * Notepad (Spanish resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Proofread 1999 by Jose Marcos Lopez - * Copyright 2002 Sylvain Petreolle - * Copyright 2003,2004 José Manuel Ferrer Ortiz - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Archivo" - BEGIN - MENUITEM "&Nuevo...", CMD_NEW - MENUITEM "&Abrir\tCtrl+O", CMD_OPEN - MENUITEM "&Guardar\tCtrl+S", CMD_SAVE - MENUITEM "Guardar &como...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "&Imprimir", CMD_PRINT - MENUITEM "Configurar &página...", CMD_PAGE_SETUP - MENUITEM "Configuración &impresora...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Salir", CMD_EXIT - END - POPUP "&Editar" - BEGIN - MENUITEM "&Deshacer\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "Cor&tar\tCtrl+X", CMD_CUT - MENUITEM "&Copiar\tCtrl+C", CMD_COPY - MENUITEM "&Pegar\tCtrl+V", CMD_PASTE - MENUITEM "&Borrar\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Buscar\tCtrl+F", CMD_SEARCH - MENUITEM "Buscar &siguiente\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "Seleccionar t&odo\tCtrl+A", CMD_SELECT_ALL - MENUITEM "&Hora y fecha\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "&Ajuste de línea", CMD_WRAP - MENUITEM "Tipo de &letra...", CMD_FONT - END - POPUP "A&yuda" - BEGIN - MENUITEM "Í&ndice", CMD_HELP_CONTENTS - MENUITEM "&Buscar...", CMD_HELP_SEARCH - MENUITEM "A&yuda sobre la ayuda", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "&Información...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Ajuste de página" -{ -LTEXT "&Cabecera:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Pie:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Márgenes:", 0x144, 10, 43,160, 45 -LTEXT "&Izquierda:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "A&rriba:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Derecha:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Aba&jo:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "Aceptar", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Cancelar", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Ayuda", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Página &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Bloc de notas" -STRING_ERROR, "ERROR" -STRING_WARNING, "ADVERTENCIA" -STRING_INFO, "Información" - -STRING_UNTITLED, "(sin título)" - -STRING_ALL_FILES, "Todos los archivos (*.*)" -STRING_TEXT_FILES_TXT, "Documentos de texto (*.txt)" - -STRING_TOOLARGE, "El archivo '%s' es demasiado grande para el \ - bloc de notas.\n Use otro editor." -STRING_NOTEXT, "No escribió nada. \nPor favor escriba algo e \ - inténtelo de nuevo" -STRING_DOESNOTEXIST, "El archivo '%s'\nno existe\n\n żDesea crear \ - un nuevo archivo?" -STRING_NOTSAVED, "El texto en el archivo '%s' ha cambiado\n\n \ - żDesea guardar los cambios?" -STRING_NOTFOUND, "No se encontró '%s'." -STRING_OUT_OF_MEMORY, "No hay suficiente memoria para terminar esta \ - tarea. \nCierre una o más aplicaciones para \ - aumentar la cantidad \nde memoria libre." -STRING_CANNOTFIND "No pudo encontrar '%s'" -STRING_ANSI, "ANSI" -STRING_UNICODE, "Unicode" -STRING_UNICODE_BE, "Unicode (big endian)" -STRING_UTF8, "UTF-8" -STRING_CRLF, "Windows" -STRING_LF, "Unix" -STRING_CR, "Mac" - -} +/* + * Notepad (Spanish resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Proofread 1999 by Jose Marcos Lopez + * Copyright 2002 Sylvain Petreolle + * Copyright 2003,2004 José Manuel Ferrer Ortiz + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Archivo" + BEGIN + MENUITEM "&Nuevo...", CMD_NEW + MENUITEM "&Abrir\tCtrl+O", CMD_OPEN + MENUITEM "&Guardar\tCtrl+S", CMD_SAVE + MENUITEM "Guardar &como...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "&Imprimir", CMD_PRINT + MENUITEM "Configurar &página...", CMD_PAGE_SETUP + MENUITEM "Configuración &impresora...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Salir", CMD_EXIT + END + POPUP "&Editar" + BEGIN + MENUITEM "&Deshacer\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Cor&tar\tCtrl+X", CMD_CUT + MENUITEM "&Copiar\tCtrl+C", CMD_COPY + MENUITEM "&Pegar\tCtrl+V", CMD_PASTE + MENUITEM "&Borrar\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Buscar\tCtrl+F", CMD_SEARCH + MENUITEM "Buscar &siguiente\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "Seleccionar t&odo\tCtrl+A", CMD_SELECT_ALL + MENUITEM "&Hora y fecha\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "&Ajuste de línea", CMD_WRAP + MENUITEM "Tipo de &letra...", CMD_FONT + END + POPUP "A&yuda" + BEGIN + MENUITEM "Í&ndice", CMD_HELP_CONTENTS + MENUITEM "&Buscar...", CMD_HELP_SEARCH + MENUITEM "A&yuda sobre la ayuda", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "&Información...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Ajuste de página" +{ +LTEXT "&Cabecera:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Pie:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Márgenes:", 0x144, 10, 43,160, 45 +LTEXT "&Izquierda:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "A&rriba:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Derecha:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Aba&jo:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "Aceptar", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Cancelar", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Ayuda", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Página &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Bloc de notas" +STRING_ERROR, "ERROR" +STRING_WARNING, "ADVERTENCIA" +STRING_INFO, "Información" + +STRING_UNTITLED, "(sin título)" + +STRING_ALL_FILES, "Todos los archivos (*.*)" +STRING_TEXT_FILES_TXT, "Documentos de texto (*.txt)" + +STRING_TOOLARGE, "El archivo '%s' es demasiado grande para el \ + bloc de notas.\n Use otro editor." +STRING_NOTEXT, "No escribió nada. \nPor favor escriba algo e \ + inténtelo de nuevo" +STRING_DOESNOTEXIST, "El archivo '%s'\nno existe\n\n żDesea crear \ + un nuevo archivo?" +STRING_NOTSAVED, "El texto en el archivo '%s' ha cambiado\n\n \ + żDesea guardar los cambios?" +STRING_NOTFOUND, "No se encontró '%s'." +STRING_OUT_OF_MEMORY, "No hay suficiente memoria para terminar esta \ + tarea. \nCierre una o más aplicaciones para \ + aumentar la cantidad \nde memoria libre." +STRING_CANNOTFIND "No pudo encontrar '%s'" +STRING_ANSI, "ANSI" +STRING_UNICODE, "Unicode" +STRING_UNICODE_BE, "Unicode (big endian)" +STRING_UTF8, "UTF-8" +STRING_CRLF, "Windows" +STRING_LF, "Unix" +STRING_CR, "Mac" + +} diff --git a/reactos/base/applications/notepad/lang/Fi.rc b/reactos/base/applications/notepad/lang/Fi.rc index f3d82be8a5d..6cea70b875a 100644 --- a/reactos/base/applications/notepad/lang/Fi.rc +++ b/reactos/base/applications/notepad/lang/Fi.rc @@ -1,161 +1,161 @@ -/* - * Notepad (Finnish resources) - * - * Copyright 1999 by Jukka Iivonen - * Copyright 2002 Sylvain Petreolle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Tiedosto" - BEGIN - MENUITEM "&Uusi...", CMD_NEW - MENUITEM "&Avaa", CMD_OPEN - MENUITEM "Ta&lleta", CMD_SAVE - MENUITEM "Talleta &nimellä...", CMD_SAVE_AS - MENUITEM "T&ulosta", CMD_PRINT - MENUITEM "&Sivun asetukset...", CMD_PAGE_SETUP - MENUITEM "&Kirjoittimen asetukset...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Poistu", CMD_EXIT - END - POPUP "&Muokkaa" - BEGIN - MENUITEM "&Palauta\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Leikkaa\tCtrl+X", CMD_CUT - MENUITEM "&Kopioi\tCtrl+C", CMD_COPY - MENUITEM "L&iitä\tCtrl+V", CMD_PASTE - MENUITEM "P&oista\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "Etsi...", CMD_SEARCH - MENUITEM "Etsi &seuraava\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "&Valitse kaikki", CMD_SELECT_ALL - MENUITEM "&Aika/Päivämäärä\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "Ka&tkaise pitkä rivi", CMD_WRAP - END - POPUP "&Apua" - BEGIN - MENUITEM "&Sisältö", CMD_HELP_CONTENTS - MENUITEM "&Etsi...", CMD_HELP_SEARCH - MENUITEM "Apua &Opastuksesta", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Inf&o...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Sivun asetukset" -{ -LTEXT "&Yläotsikko:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "Alao&tsikko:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Marginaali:", 0x144, 10, 43,160, 45 -LTEXT "&Vasen:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Y&lä:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Oikea:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Ala:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Peruuta", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Apua", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Sivu &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Notepad" -STRING_ERROR, "VIRHE" -STRING_WARNING, "VAROITUS" -STRING_INFO, "Tiedoitus" - -STRING_UNTITLED, "(otsikoimaton)" - -STRING_ALL_FILES, "Kaikki tiedostot (*.*)" -STRING_TEXT_FILES_TXT, "Teksti tiedostot (*.txt)" - -STRING_TOOLARGE, "Tiedosto '%s' on liian suuri.\n \ -Please use a different editor." -STRING_NOTEXT, "Et syöttänyt lainkaan tekstiä. \ -\nKirjoita jotain ja yritä uudelleen" -STRING_DOESNOTEXIST, "File '%s'\ndoes not exist\n\n \ -Do you want to create a new file ?" -STRING_NOTSAVED, "File '%s'\nhas been modified\n\n \ -Would you like to save the changes ?" -STRING_NOTFOUND, "'%s' ei löydy." -STRING_OUT_OF_MEMORY, "Muistia ei ole riittävästi tämän \ -\ntehtävän tekemiseksi. Sulje jokin sovellus vapauttaaksesi\n \ -muistia." - -} +/* + * Notepad (Finnish resources) + * + * Copyright 1999 by Jukka Iivonen + * Copyright 2002 Sylvain Petreolle + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Tiedosto" + BEGIN + MENUITEM "&Uusi...", CMD_NEW + MENUITEM "&Avaa", CMD_OPEN + MENUITEM "Ta&lleta", CMD_SAVE + MENUITEM "Talleta &nimellä...", CMD_SAVE_AS + MENUITEM "T&ulosta", CMD_PRINT + MENUITEM "&Sivun asetukset...", CMD_PAGE_SETUP + MENUITEM "&Kirjoittimen asetukset...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Poistu", CMD_EXIT + END + POPUP "&Muokkaa" + BEGIN + MENUITEM "&Palauta\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Leikkaa\tCtrl+X", CMD_CUT + MENUITEM "&Kopioi\tCtrl+C", CMD_COPY + MENUITEM "L&iitä\tCtrl+V", CMD_PASTE + MENUITEM "P&oista\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "Etsi...", CMD_SEARCH + MENUITEM "Etsi &seuraava\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "&Valitse kaikki", CMD_SELECT_ALL + MENUITEM "&Aika/Päivämäärä\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "Ka&tkaise pitkä rivi", CMD_WRAP + END + POPUP "&Apua" + BEGIN + MENUITEM "&Sisältö", CMD_HELP_CONTENTS + MENUITEM "&Etsi...", CMD_HELP_SEARCH + MENUITEM "Apua &Opastuksesta", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Inf&o...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Sivun asetukset" +{ +LTEXT "&Yläotsikko:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "Alao&tsikko:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Marginaali:", 0x144, 10, 43,160, 45 +LTEXT "&Vasen:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Y&lä:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Oikea:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Ala:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Peruuta", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Apua", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Sivu &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notepad" +STRING_ERROR, "VIRHE" +STRING_WARNING, "VAROITUS" +STRING_INFO, "Tiedoitus" + +STRING_UNTITLED, "(otsikoimaton)" + +STRING_ALL_FILES, "Kaikki tiedostot (*.*)" +STRING_TEXT_FILES_TXT, "Teksti tiedostot (*.txt)" + +STRING_TOOLARGE, "Tiedosto '%s' on liian suuri.\n \ +Please use a different editor." +STRING_NOTEXT, "Et syöttänyt lainkaan tekstiä. \ +\nKirjoita jotain ja yritä uudelleen" +STRING_DOESNOTEXIST, "File '%s'\ndoes not exist\n\n \ +Do you want to create a new file ?" +STRING_NOTSAVED, "File '%s'\nhas been modified\n\n \ +Would you like to save the changes ?" +STRING_NOTFOUND, "'%s' ei löydy." +STRING_OUT_OF_MEMORY, "Muistia ei ole riittävästi tämän \ +\ntehtävän tekemiseksi. Sulje jokin sovellus vapauttaaksesi\n \ +muistia." + +} diff --git a/reactos/base/applications/notepad/lang/Fr.rc b/reactos/base/applications/notepad/lang/Fr.rc index 3c5e38293f3..3f4584e1136 100644 --- a/reactos/base/applications/notepad/lang/Fr.rc +++ b/reactos/base/applications/notepad/lang/Fr.rc @@ -1,164 +1,164 @@ -/* - * Notepad (French resources) - * - * Copyright 1997,98 Marcel Baur - * Translation by Laurent Buffler - * Copyright 2002 Sylvain Petreolle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Fichier" - BEGIN - MENUITEM "&Nouveau...", CMD_NEW - MENUITEM "&Ouvrir\tCtrl+O", CMD_OPEN - MENUITEM "&Enregistrer\tCtrl+S", CMD_SAVE - MENUITEM "Enregistrer &sous...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "Im&primer", CMD_PRINT - MENUITEM "&Mise en page...", CMD_PAGE_SETUP - MENUITEM "&Configuration de l'imprimante...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Quitter", CMD_EXIT - END - POPUP "&Edition" - BEGIN - MENUITEM "&Annuler\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "Co&uper\tCtrl+X", CMD_CUT - MENUITEM "&Copier\tCtrl+C", CMD_COPY - MENUITEM "C&oller\tCtrl+V", CMD_PASTE - MENUITEM "&Effacer\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Rechercher\tCtrl+F", CMD_SEARCH - MENUITEM "&Suivant\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "Tout &sélectionner\tCtrl+A", CMD_SELECT_ALL - MENUITEM "&Heure/Date\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "&Retour ŕ la ligne", CMD_WRAP - MENUITEM "&Police...", CMD_FONT - END - POPUP "&Aide" - BEGIN - MENUITEM "&Sommaire", CMD_HELP_CONTENTS - MENUITEM "&Rechercher...", CMD_HELP_SEARCH - MENUITEM "&Utiliser l'aide", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Inf&o...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Mise en page" -{ -LTEXT "&En-tęte :", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Pied de page :", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Marges :", 0x144, 10, 43,160, 45 -LTEXT "&Gauche :", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Haut :", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Droite :", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Bas :", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Annuler", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Aide", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Bloc-notes" -STRING_ERROR, "ERREUR" -STRING_WARNING, "ATTENTION" -STRING_INFO, "Information" - -STRING_UNTITLED, "(sans-titre)" - -STRING_ALL_FILES, "Tous fichiers (*.*)" -STRING_TEXT_FILES_TXT, "Fichiers texte (*.txt)" - -STRING_TOOLARGE, "Le fichier '%s' est trop grand pour le bloc-notes.\n \ -Veuillez utiliser un autre éditeur." -STRING_NOTEXT, "Vous n'avez pas entré de texte. \ -Veuillez taper quelque chose et recommencer" -STRING_DOESNOTEXIST, "Le fichier '%s'\nn'existe pas.\n\n \ -Voulez-vous créer un nouveau fichier ?" -STRING_NOTSAVED, "Le fichier '%s'\na été modifié\n\n \ -Voulez-vous enregistrer vos modifications ?" -STRING_NOTFOUND, "'%s' non trouvé." -STRING_OUT_OF_MEMORY, "Pas assez de mémoire pour compléter cette \ -tâche. \nFermez une ou plusieurs applications pour libérer\n\ -de la mémoire." - -} +/* + * Notepad (French resources) + * + * Copyright 1997,98 Marcel Baur + * Translation by Laurent Buffler + * Copyright 2002 Sylvain Petreolle + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Fichier" + BEGIN + MENUITEM "&Nouveau...", CMD_NEW + MENUITEM "&Ouvrir\tCtrl+O", CMD_OPEN + MENUITEM "&Enregistrer\tCtrl+S", CMD_SAVE + MENUITEM "Enregistrer &sous...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Im&primer", CMD_PRINT + MENUITEM "&Mise en page...", CMD_PAGE_SETUP + MENUITEM "&Configuration de l'imprimante...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Quitter", CMD_EXIT + END + POPUP "&Edition" + BEGIN + MENUITEM "&Annuler\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Co&uper\tCtrl+X", CMD_CUT + MENUITEM "&Copier\tCtrl+C", CMD_COPY + MENUITEM "C&oller\tCtrl+V", CMD_PASTE + MENUITEM "&Effacer\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Rechercher\tCtrl+F", CMD_SEARCH + MENUITEM "&Suivant\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "Tout &sélectionner\tCtrl+A", CMD_SELECT_ALL + MENUITEM "&Heure/Date\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "&Retour ŕ la ligne", CMD_WRAP + MENUITEM "&Police...", CMD_FONT + END + POPUP "&Aide" + BEGIN + MENUITEM "&Sommaire", CMD_HELP_CONTENTS + MENUITEM "&Rechercher...", CMD_HELP_SEARCH + MENUITEM "&Utiliser l'aide", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Inf&o...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Mise en page" +{ +LTEXT "&En-tęte :", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Pied de page :", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Marges :", 0x144, 10, 43,160, 45 +LTEXT "&Gauche :", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Haut :", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Droite :", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Bas :", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Annuler", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Aide", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Bloc-notes" +STRING_ERROR, "ERREUR" +STRING_WARNING, "ATTENTION" +STRING_INFO, "Information" + +STRING_UNTITLED, "(sans-titre)" + +STRING_ALL_FILES, "Tous fichiers (*.*)" +STRING_TEXT_FILES_TXT, "Fichiers texte (*.txt)" + +STRING_TOOLARGE, "Le fichier '%s' est trop grand pour le bloc-notes.\n \ +Veuillez utiliser un autre éditeur." +STRING_NOTEXT, "Vous n'avez pas entré de texte. \ +Veuillez taper quelque chose et recommencer" +STRING_DOESNOTEXIST, "Le fichier '%s'\nn'existe pas.\n\n \ +Voulez-vous créer un nouveau fichier ?" +STRING_NOTSAVED, "Le fichier '%s'\na été modifié\n\n \ +Voulez-vous enregistrer vos modifications ?" +STRING_NOTFOUND, "'%s' non trouvé." +STRING_OUT_OF_MEMORY, "Pas assez de mémoire pour compléter cette \ +tâche. \nFermez une ou plusieurs applications pour libérer\n\ +de la mémoire." + +} diff --git a/reactos/base/applications/notepad/lang/Gr.rc b/reactos/base/applications/notepad/lang/Gr.rc index 776a72db466..71f9a5ca266 100644 --- a/reactos/base/applications/notepad/lang/Gr.rc +++ b/reactos/base/applications/notepad/lang/Gr.rc @@ -1,203 +1,203 @@ -/* - * Notepad (Greek resources) - * - * Copyright 2005 Apostolos Alexiadis (djapal@gmail.com) - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_GREEK, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Áń÷ĺßď" - BEGIN - MENUITEM "&ÍÝď...", CMD_NEW - MENUITEM "&˘íďéăěá\tCtrl+O", CMD_OPEN - MENUITEM "ÁđďčŢęĺő&óç\tCtrl+S", CMD_SAVE - MENUITEM "ÁđďčŢęĺőóç &ůň...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "Ĺ&đéëďăÝň óĺëßäáň...", CMD_PAGE_SETUP - MENUITEM "&Ĺęôýđůóç", CMD_PRINT - MENUITEM "ĹđéëďăÝň ĺę&ôőđůôŢ ...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "¸&îďäďň", CMD_EXIT - END - POPUP "&Edit" - BEGIN - MENUITEM "Á&íáßńĺóç\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "Áđďęď&đŢ\tCtrl+X", CMD_CUT - MENUITEM "&ÁíôéăńáöŢ\tCtrl+C", CMD_COPY - MENUITEM "&Ĺđéęüëëçóç\tCtrl+V", CMD_PASTE - MENUITEM "&ÄéáăńáöŢ\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Ĺýńĺóç...\tCtrl+F", CMD_SEARCH - MENUITEM "Ĺýńĺóç ĺ&đüěĺíďő\tF3", CMD_SEARCH_NEXT - MENUITEM "ÁíôéęáôÜóôáóç\tCtrl+H", CMD_REPLACE - MENUITEM "&ĚĺôÜâáóç óôď...\tCtrl+G", CMD_GOTO - MENUITEM SEPARATOR - MENUITEM "ĹđéëďăŢ &Ľëůí\tCtrl+A", CMD_SELECT_ALL - MENUITEM "&żńá/Çěĺńďěçíßá\tF5", CMD_TIME_DATE - END - POPUP "Ö&ďńěÜ" - BEGIN - MENUITEM "&ĹěöÜíéóç ěĺăÜëůí ăńáěěţí", CMD_WRAP - MENUITEM "&ĂńáěěáôďóĺéńÜ...", CMD_FONT - END - POPUP "&ĹěöÜíéóç" - BEGIN - MENUITEM "ĂńáěěŢ &ęáôÜóôáóçň", CMD_STATUSBAR - END - POPUP "&ÂďŢčĺéá" - BEGIN - MENUITEM "&Đĺńéĺ÷üěĺíá", CMD_HELP_CONTENTS - MENUITEM "&ÁíáćŢôçóç...", CMD_HELP_SEARCH - MENUITEM "&ÂďŢčĺéá óôç âďŢčĺéá", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Đëçńď&öďńßĺň", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "ĹđéëďăÝň Óĺëßäáň" -{ -LTEXT "&ĘĺöáëŢ:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&ŐđďóÝëéäď:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Ľńéá:", 0x144, 10, 43,160, 45 -LTEXT "&ÁńéóôĺńÜ:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&ĐÜíů:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&ÄĺîéÜ:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&ĘÜôů:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Áęýńůóç", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&ÂďŢčĺéá", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -/* Dialog `Encoding' */ -DIALOG_ENCODING DIALOG 0, 0, 256, 44 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | - WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Ęůäéęďđďßçóç" -{ -COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP -LTEXT "Ęůäéęďđďßçóç:",0x155,5,2,41,12 -COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -LTEXT "Endlines:",0x156,5,20,41,12 -} - -/* Dialog 'Go To' */ -DIALOG_GOTO DIALOG 0,0,165,50 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "ĚĺôÜâáóç óôç ăńáěěŢ" -{ -EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Áńéčěüň ăńáěěŢň:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER -DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP -PUSHBUTTON "Áęýńůóç", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP -} - - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Óĺëßäá &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Notepad" -STRING_ERROR, "ERROR" -STRING_WARNING, "WARNING" -STRING_INFO, "Đëçńďöďńßĺň" - -STRING_UNTITLED, "(×ůńßň ôßôëď)" - -STRING_ALL_FILES, "Ľëá ôá áń÷ĺßá (*.*)" -STRING_TEXT_FILES_TXT, "Áń÷ĺßá ęĺéěÝíďő (*.txt)" - -STRING_TOOLARGE, "Ôď áń÷ĺßď '%s' ĺßíáé đďëý ěĺăÜëď ăéá ôď notepad.\n \ -Đáńáęáëţ ÷ńçóéěďđďéĺßóôĺ Üëëď đńüăńáěěá ĺđĺîĺńăáóßáň ęĺéěÝíďő." -STRING_NOTEXT, "Äĺí đëçęôńďëďăŢóáôĺ ęÜôé. \ -\nĐáńáęáëţ đëçęôńďëďăĺßóôĺ ęÜôé ęáé đńďóđáčĺßóôĺ îáíÜ" -STRING_DOESNOTEXIST, "Ôď áń÷ĺßď '%s'\näĺí őđÜń÷ĺé\n\n \ -ČÝëĺôĺ íá äçěéďőńăŢóĺôĺ Ýíá íÝď áń÷ĺßď;" -STRING_NOTSAVED, "Ôď áń÷ĺßď '%s'\nÝ÷ĺé ôńďđďđďéçčĺß\n\n \ -ČÝëĺôĺ íá áđďčçęĺýóĺôĺ ôéň áëëáăÝň;" -STRING_NOTFOUND, "Ôď áń÷ĺßď '%s' äĺ ěđďńĺß íá âńĺčĺß." -STRING_OUT_OF_MEMORY, "Äĺí őđÜń÷ĺé áńęĺôŢ ěíŢěç ăéá íá ďëďęëçńůčĺß áőôŢ ç \ -äéĺńăáóßá. \nĘëĺßóôĺ ěßá Ţ đĺńńéóüôĺńĺň ĺöáńěďăÝň ăéá íá áőîçčĺß ç \nĺëĺýčĺńç \ -ěíŢěç." -STRING_CANNOTFIND "Äĺ ěđďńĺß íá âńĺčĺß ôď '%s'" -STRING_ANSI, "ANSI" -STRING_UNICODE, "Unicode" -STRING_UNICODE_BE, "Unicode (big endian)" -STRING_UTF8, "UTF-8" -STRING_CRLF, "Windows" -STRING_LF, "Unix" -STRING_CR, "Mac" -} +/* + * Notepad (Greek resources) + * + * Copyright 2005 Apostolos Alexiadis (djapal@gmail.com) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_GREEK, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Áń÷ĺßď" + BEGIN + MENUITEM "&ÍÝď...", CMD_NEW + MENUITEM "&˘íďéăěá\tCtrl+O", CMD_OPEN + MENUITEM "ÁđďčŢęĺő&óç\tCtrl+S", CMD_SAVE + MENUITEM "ÁđďčŢęĺőóç &ůň...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Ĺ&đéëďăÝň óĺëßäáň...", CMD_PAGE_SETUP + MENUITEM "&Ĺęôýđůóç", CMD_PRINT + MENUITEM "ĹđéëďăÝň ĺę&ôőđůôŢ ...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "¸&îďäďň", CMD_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "Á&íáßńĺóç\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Áđďęď&đŢ\tCtrl+X", CMD_CUT + MENUITEM "&ÁíôéăńáöŢ\tCtrl+C", CMD_COPY + MENUITEM "&Ĺđéęüëëçóç\tCtrl+V", CMD_PASTE + MENUITEM "&ÄéáăńáöŢ\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Ĺýńĺóç...\tCtrl+F", CMD_SEARCH + MENUITEM "Ĺýńĺóç ĺ&đüěĺíďő\tF3", CMD_SEARCH_NEXT + MENUITEM "ÁíôéęáôÜóôáóç\tCtrl+H", CMD_REPLACE + MENUITEM "&ĚĺôÜâáóç óôď...\tCtrl+G", CMD_GOTO + MENUITEM SEPARATOR + MENUITEM "ĹđéëďăŢ &Ľëůí\tCtrl+A", CMD_SELECT_ALL + MENUITEM "&żńá/Çěĺńďěçíßá\tF5", CMD_TIME_DATE + END + POPUP "Ö&ďńěÜ" + BEGIN + MENUITEM "&ĹěöÜíéóç ěĺăÜëůí ăńáěěţí", CMD_WRAP + MENUITEM "&ĂńáěěáôďóĺéńÜ...", CMD_FONT + END + POPUP "&ĹěöÜíéóç" + BEGIN + MENUITEM "ĂńáěěŢ &ęáôÜóôáóçň", CMD_STATUSBAR + END + POPUP "&ÂďŢčĺéá" + BEGIN + MENUITEM "&Đĺńéĺ÷üěĺíá", CMD_HELP_CONTENTS + MENUITEM "&ÁíáćŢôçóç...", CMD_HELP_SEARCH + MENUITEM "&ÂďŢčĺéá óôç âďŢčĺéá", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Đëçńď&öďńßĺň", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "ĹđéëďăÝň Óĺëßäáň" +{ +LTEXT "&ĘĺöáëŢ:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&ŐđďóÝëéäď:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Ľńéá:", 0x144, 10, 43,160, 45 +LTEXT "&ÁńéóôĺńÜ:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&ĐÜíů:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&ÄĺîéÜ:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&ĘÜôů:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Áęýńůóç", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&ÂďŢčĺéá", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +/* Dialog `Encoding' */ +DIALOG_ENCODING DIALOG 0, 0, 256, 44 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | + WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Ęůäéęďđďßçóç" +{ +COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP +LTEXT "Ęůäéęďđďßçóç:",0x155,5,2,41,12 +COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +LTEXT "Endlines:",0x156,5,20,41,12 +} + +/* Dialog 'Go To' */ +DIALOG_GOTO DIALOG 0,0,165,50 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "ĚĺôÜâáóç óôç ăńáěěŢ" +{ +EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Áńéčěüň ăńáěěŢň:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER +DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP +PUSHBUTTON "Áęýńůóç", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP +} + + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Óĺëßäá &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notepad" +STRING_ERROR, "ERROR" +STRING_WARNING, "WARNING" +STRING_INFO, "Đëçńďöďńßĺň" + +STRING_UNTITLED, "(×ůńßň ôßôëď)" + +STRING_ALL_FILES, "Ľëá ôá áń÷ĺßá (*.*)" +STRING_TEXT_FILES_TXT, "Áń÷ĺßá ęĺéěÝíďő (*.txt)" + +STRING_TOOLARGE, "Ôď áń÷ĺßď '%s' ĺßíáé đďëý ěĺăÜëď ăéá ôď notepad.\n \ +Đáńáęáëţ ÷ńçóéěďđďéĺßóôĺ Üëëď đńüăńáěěá ĺđĺîĺńăáóßáň ęĺéěÝíďő." +STRING_NOTEXT, "Äĺí đëçęôńďëďăŢóáôĺ ęÜôé. \ +\nĐáńáęáëţ đëçęôńďëďăĺßóôĺ ęÜôé ęáé đńďóđáčĺßóôĺ îáíÜ" +STRING_DOESNOTEXIST, "Ôď áń÷ĺßď '%s'\näĺí őđÜń÷ĺé\n\n \ +ČÝëĺôĺ íá äçěéďőńăŢóĺôĺ Ýíá íÝď áń÷ĺßď;" +STRING_NOTSAVED, "Ôď áń÷ĺßď '%s'\nÝ÷ĺé ôńďđďđďéçčĺß\n\n \ +ČÝëĺôĺ íá áđďčçęĺýóĺôĺ ôéň áëëáăÝň;" +STRING_NOTFOUND, "Ôď áń÷ĺßď '%s' äĺ ěđďńĺß íá âńĺčĺß." +STRING_OUT_OF_MEMORY, "Äĺí őđÜń÷ĺé áńęĺôŢ ěíŢěç ăéá íá ďëďęëçńůčĺß áőôŢ ç \ +äéĺńăáóßá. \nĘëĺßóôĺ ěßá Ţ đĺńńéóüôĺńĺň ĺöáńěďăÝň ăéá íá áőîçčĺß ç \nĺëĺýčĺńç \ +ěíŢěç." +STRING_CANNOTFIND "Äĺ ěđďńĺß íá âńĺčĺß ôď '%s'" +STRING_ANSI, "ANSI" +STRING_UNICODE, "Unicode" +STRING_UNICODE_BE, "Unicode (big endian)" +STRING_UTF8, "UTF-8" +STRING_CRLF, "Windows" +STRING_LF, "Unix" +STRING_CR, "Mac" +} diff --git a/reactos/base/applications/notepad/lang/Hu.rc b/reactos/base/applications/notepad/lang/Hu.rc index ddc2a70328d..3ec88ba3b44 100644 --- a/reactos/base/applications/notepad/lang/Hu.rc +++ b/reactos/base/applications/notepad/lang/Hu.rc @@ -1,164 +1,164 @@ -/* - * Notepad (Hungarian resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Copyright 2002 Sylvain Petreolle - * Copyright 2002 Zoly Nagy - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Fájl" - BEGIN - MENUITEM "Ú&j", CMD_NEW - MENUITEM "Meg&nyitás...", CMD_OPEN - MENUITEM "&Mentés", CMD_SAVE - MENUITEM "Mentés má&sként...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "&Oldalbeállítás...", CMD_PAGE_SETUP - MENUITEM "Nyom&tatás...", CMD_PRINT - MENUITEM "Nyomtató &beállítás...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Kilépés", CMD_EXIT - END - POPUP "S&zerkesztés" - BEGIN - MENUITEM "&Visszavonás\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "Kivá&gás\tCtrl+X", CMD_CUT - MENUITEM "&Másolás\tCtrl+C", CMD_COPY - MENUITEM "&Beillesztés\tCtrl+V", CMD_PASTE - MENUITEM "Tör&lés\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Keresés...", CMD_SEARCH - MENUITEM "Köve&tkező keresése\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "&Az összes kijelölése", CMD_SELECT_ALL - MENUITEM "&Idő/dátum\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "&Hosszú sorok tördelése", CMD_WRAP - END - POPUP "&Súgó" - BEGIN - MENUITEM "&Témakörök", CMD_HELP_CONTENTS - MENUITEM "&Keresés...", CMD_HELP_SEARCH - MENUITEM "&Használat", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Inf&ormáció...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Oldalbeállítás" -{ -LTEXT "&Fejléc:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Lábléc:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Margók:", 0x144, 10, 43,160, 45 -LTEXT "&Bal:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Felső:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Jobb:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Alsó:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Mégse", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Súgó", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Oldalszám: &s." /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Jegyzettömb" -STRING_ERROR, "HIBA" -STRING_WARNING, "FIGYELMEZTETÉS" -STRING_INFO, "Információ" - -STRING_UNTITLED, "(névtelen)" - -STRING_ALL_FILES, "Minden fájl (*.*)" -STRING_TEXT_FILES_TXT, "Szövegfájlok (*.txt)" - -STRING_TOOLARGE, "'%s' fájl túl nagy méretű.\n \ -Kérem használjon másik szövegszerkesztő programot." -STRING_NOTEXT, "A szöveg nem tartalmaz karaktert! \ -\nKérem gépeljen be néhány karaktert és próbálja újra!" -STRING_DOESNOTEXIST, "A megadott '%s'\nfájl nem létezik!\n\n \ -Kíván létrehozni új fájlt?" -STRING_NOTSAVED, "'%s' fájl\nmódosult\n\n \ -Szeretné menteni a változásokat?" -STRING_NOTFOUND, "'%s' nem található!" -STRING_OUT_OF_MEMORY, "Nincs elegendő szabad memória!\ -\nZárjon be néhány alkalmazást, ezzel növelve a szabad memória méretét\ -!" - -} +/* + * Notepad (Hungarian resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * Copyright 2002 Zoly Nagy + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Fájl" + BEGIN + MENUITEM "Ú&j", CMD_NEW + MENUITEM "Meg&nyitás...", CMD_OPEN + MENUITEM "&Mentés", CMD_SAVE + MENUITEM "Mentés má&sként...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "&Oldalbeállítás...", CMD_PAGE_SETUP + MENUITEM "Nyom&tatás...", CMD_PRINT + MENUITEM "Nyomtató &beállítás...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Kilépés", CMD_EXIT + END + POPUP "S&zerkesztés" + BEGIN + MENUITEM "&Visszavonás\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Kivá&gás\tCtrl+X", CMD_CUT + MENUITEM "&Másolás\tCtrl+C", CMD_COPY + MENUITEM "&Beillesztés\tCtrl+V", CMD_PASTE + MENUITEM "Tör&lés\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Keresés...", CMD_SEARCH + MENUITEM "Köve&tkező keresése\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "&Az összes kijelölése", CMD_SELECT_ALL + MENUITEM "&Idő/dátum\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "&Hosszú sorok tördelése", CMD_WRAP + END + POPUP "&Súgó" + BEGIN + MENUITEM "&Témakörök", CMD_HELP_CONTENTS + MENUITEM "&Keresés...", CMD_HELP_SEARCH + MENUITEM "&Használat", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Inf&ormáció...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Oldalbeállítás" +{ +LTEXT "&Fejléc:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Lábléc:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Margók:", 0x144, 10, 43,160, 45 +LTEXT "&Bal:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Felső:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Jobb:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Alsó:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Mégse", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Súgó", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Oldalszám: &s." /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Jegyzettömb" +STRING_ERROR, "HIBA" +STRING_WARNING, "FIGYELMEZTETÉS" +STRING_INFO, "Információ" + +STRING_UNTITLED, "(névtelen)" + +STRING_ALL_FILES, "Minden fájl (*.*)" +STRING_TEXT_FILES_TXT, "Szövegfájlok (*.txt)" + +STRING_TOOLARGE, "'%s' fájl túl nagy méretű.\n \ +Kérem használjon másik szövegszerkesztő programot." +STRING_NOTEXT, "A szöveg nem tartalmaz karaktert! \ +\nKérem gépeljen be néhány karaktert és próbálja újra!" +STRING_DOESNOTEXIST, "A megadott '%s'\nfájl nem létezik!\n\n \ +Kíván létrehozni új fájlt?" +STRING_NOTSAVED, "'%s' fájl\nmódosult\n\n \ +Szeretné menteni a változásokat?" +STRING_NOTFOUND, "'%s' nem található!" +STRING_OUT_OF_MEMORY, "Nincs elegendő szabad memória!\ +\nZárjon be néhány alkalmazást, ezzel növelve a szabad memória méretét\ +!" + +} diff --git a/reactos/base/applications/notepad/lang/It.rc b/reactos/base/applications/notepad/lang/It.rc index ba6487a5a96..292b4fa1bb0 100644 --- a/reactos/base/applications/notepad/lang/It.rc +++ b/reactos/base/applications/notepad/lang/It.rc @@ -1,165 +1,165 @@ -/* - * Notepad (Italian resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Copyright 2002 Sylvain Petreolle - * Copyright 2003 Marcelo Duarte - * Copyright 2003-2004 Ivan Leo Puoti - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&Nuovo", CMD_NEW - MENUITEM "&Apri...\tCtrl+O", CMD_OPEN - MENUITEM "&Salva\tCtrl+S", CMD_SAVE - MENUITEM "Salva &con nome...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "&Stampa", CMD_PRINT - MENUITEM "&Imposta pagina...", CMD_PAGE_SETUP - MENUITEM "&Configurazione stampante...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "E&sci", CMD_EXIT - END - POPUP "&Modifica" - BEGIN - MENUITEM "&Anulla\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Taglia\tCtrl+X", CMD_CUT - MENUITEM "&Copia\tCtrl+C", CMD_COPY - MENUITEM "&Incolla\tCtrl+V", CMD_PASTE - MENUITEM "&Elimina\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Trova\tCtrl+F", CMD_SEARCH - MENUITEM "&Trova successivo\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "Seleziona &tutto\tCtrl+A", CMD_SELECT_ALL - MENUITEM "&Ora/Data\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "&A campo automatico", CMD_WRAP - MENUITEM "&Imposta carattere...", CMD_FONT - END - POPUP "&Aiuto" - BEGIN - MENUITEM "&Contenuti", CMD_HELP_CONTENTS - MENUITEM "&Trova...", CMD_HELP_SEARCH - MENUITEM "&Aiuto sulla Guida", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Inf&o...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Setup di pagina" -{ -LTEXT "&Note a inizio pagina:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Note a pič di pagina:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Margini:", 0x144, 10, 43,160, 45 -LTEXT "&Sinistro:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Superiore:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Destro:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Inferiore:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Cancella", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Aiuto", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Blocco note" -STRING_ERROR, "ERRORE" -STRING_WARNING, "ATTENZIONE" -STRING_INFO, "Info" - -STRING_UNTITLED, "(senza nome)" - -STRING_ALL_FILES, "Tutti i file (*.*)" -STRING_TEXT_FILES_TXT, "File di testo (*.txt)" - -STRING_TOOLARGE, "Il file '%s' č troppo grande per il blocco note.\n \ -Per favore usare un altro editor." -STRING_NOTEXT, "Non č stato inserito alcun testo. \ -\nPer favore digitare qualcosa e riprovare" -STRING_DOESNOTEXIST, "Il file '%s'\nnon esiste\n\n \ -Creare un nuovo file ?" -STRING_NOTSAVED, "Il file '%s'\ne' stato modificato\n\n \ -Salvare le modifiche ?" -STRING_NOTFOUND, "'%s' non č stato trovato." -STRING_OUT_OF_MEMORY, "Memoria insufficente per completare questa operazione \ -task. \nChiudere una o piů applicazioni per aumentare la quantita'\n di memoria libera." - -} +/* + * Notepad (Italian resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * Copyright 2003 Marcelo Duarte + * Copyright 2003-2004 Ivan Leo Puoti + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Nuovo", CMD_NEW + MENUITEM "&Apri...\tCtrl+O", CMD_OPEN + MENUITEM "&Salva\tCtrl+S", CMD_SAVE + MENUITEM "Salva &con nome...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "&Stampa", CMD_PRINT + MENUITEM "&Imposta pagina...", CMD_PAGE_SETUP + MENUITEM "&Configurazione stampante...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "E&sci", CMD_EXIT + END + POPUP "&Modifica" + BEGIN + MENUITEM "&Anulla\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Taglia\tCtrl+X", CMD_CUT + MENUITEM "&Copia\tCtrl+C", CMD_COPY + MENUITEM "&Incolla\tCtrl+V", CMD_PASTE + MENUITEM "&Elimina\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Trova\tCtrl+F", CMD_SEARCH + MENUITEM "&Trova successivo\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "Seleziona &tutto\tCtrl+A", CMD_SELECT_ALL + MENUITEM "&Ora/Data\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "&A campo automatico", CMD_WRAP + MENUITEM "&Imposta carattere...", CMD_FONT + END + POPUP "&Aiuto" + BEGIN + MENUITEM "&Contenuti", CMD_HELP_CONTENTS + MENUITEM "&Trova...", CMD_HELP_SEARCH + MENUITEM "&Aiuto sulla Guida", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Inf&o...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Setup di pagina" +{ +LTEXT "&Note a inizio pagina:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Note a pič di pagina:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Margini:", 0x144, 10, 43,160, 45 +LTEXT "&Sinistro:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Superiore:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Destro:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Inferiore:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Cancella", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Aiuto", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Blocco note" +STRING_ERROR, "ERRORE" +STRING_WARNING, "ATTENZIONE" +STRING_INFO, "Info" + +STRING_UNTITLED, "(senza nome)" + +STRING_ALL_FILES, "Tutti i file (*.*)" +STRING_TEXT_FILES_TXT, "File di testo (*.txt)" + +STRING_TOOLARGE, "Il file '%s' č troppo grande per il blocco note.\n \ +Per favore usare un altro editor." +STRING_NOTEXT, "Non č stato inserito alcun testo. \ +\nPer favore digitare qualcosa e riprovare" +STRING_DOESNOTEXIST, "Il file '%s'\nnon esiste\n\n \ +Creare un nuovo file ?" +STRING_NOTSAVED, "Il file '%s'\ne' stato modificato\n\n \ +Salvare le modifiche ?" +STRING_NOTFOUND, "'%s' non č stato trovato." +STRING_OUT_OF_MEMORY, "Memoria insufficente per completare questa operazione \ +task. \nChiudere una o piů applicazioni per aumentare la quantita'\n di memoria libera." + +} diff --git a/reactos/base/applications/notepad/lang/Ja.rc b/reactos/base/applications/notepad/lang/Ja.rc index 07594a04d4f..853568c12d2 100644 --- a/reactos/base/applications/notepad/lang/Ja.rc +++ b/reactos/base/applications/notepad/lang/Ja.rc @@ -1,204 +1,204 @@ -/* - * Notepad (Japanese resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Copyright 2002 Sylvain Petreolle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "t@C‹(&F)" - BEGIN - MENUITEM "V‹KŤě¬(&N)...", CMD_NEW - MENUITEM "ŠJ‚­(&O)\tCtrl+O", CMD_OPEN - MENUITEM "•Ű‘¶(&S)\tCtrl+S", CMD_SAVE - MENUITEM "–Ľ‘O‚đ•t‚Ż‚Ä•Ű‘¶(&A)...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "y[WÝ’č(&T)...", CMD_PAGE_SETUP - MENUITEM "óŤü(&P)", CMD_PRINT - MENUITEM "vŠ“^‚ĚÝ’č(&R)...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "ŹI—ą(&X)", CMD_EXIT - END - POPUP "•ŇŹW(&E)" - BEGIN - MENUITEM "Śł‚É–ß‚·(&U)\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "Ř‚čŽć‚č(&T)\tCtrl+X", CMD_CUT - MENUITEM "Rs[(&C)\tCtrl+C", CMD_COPY - MENUITEM "y[Xg(&P)\tCtrl+V", CMD_PASTE - MENUITEM "ŤíŹś(&D)\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "ŚźŤő(&S)\tCtrl+F", CMD_SEARCH - MENUITEM "Žź‚ĚŚó•â‚𦼫ő(&S)\tF3", CMD_SEARCH_NEXT - MENUITEM "’uŠ·\tCtrl+H", CMD_REPLACE - MENUITEM "Ťs‚ÖÚ“®...\tCtrl+G", CMD_GOTO - MENUITEM SEPARATOR - MENUITEM "‘S‚Ä‘I‘đ(&A)\tCtrl+A", CMD_SELECT_ALL - MENUITEM "“ú•t‚ĆŽžŤŹ‚Ě‘}“ü(&T)\tF5", CMD_TIME_DATE - END - POPUP "ʑޮ(&O)" - BEGIN - MENUITEM "’·‚˘Ťs‚đÜ‚č•Ô‚·(&W)", CMD_WRAP - MENUITEM "tH“g(&F)...", CMD_FONT - END - POPUP "•\\ަ(&V)" - BEGIN - MENUITEM "Xe[^X o[(&B)", CMD_STATUSBAR - END - POPUP "w‹v(&H)" - BEGIN - MENUITEM "–ÚŽź(&C)", CMD_HELP_CONTENTS - MENUITEM "ŚźŤő(&S)...", CMD_HELP_SEARCH - MENUITEM "w‹v‚ĚŽg‚˘•ű(&H)", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Źî•ń(&O)" CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 9, "MS UI Gothic" -CAPTION "y[WÝ’č" -{ -LTEXT "wb_(&H):", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "tb^(&F):", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "}[W“(&M):", 0x144, 10, 43,160, 45 -LTEXT "Ť¶(&L):", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Źă(&T):", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "‰E(&R):", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "‰ş(&B):", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "L“Z‹", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "w‹v(&H)", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -/* Dialog `Encoding' */ -DIALOG_ENCODING DIALOG 0, 0, 256, 44 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | - WS_CAPTION | WS_SYSMENU -FONT 9, "MS UI Gothic" -CAPTION "G“R[fB“O" -{ -COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP -LTEXT "•¶ŽšR[h:",0x155,5,2,41,12 -COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -LTEXT "‰üŤsR[h:",0x156,5,20,41,12 -} - -/* Dialog 'Go To' */ -DIALOG_GOTO DIALOG 0,0,165,50 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 9, "MS UI Gothic" -CAPTION "Ťs‚ÖÚ“®" -{ -EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Ťs”ÔŤ†:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER -DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP -PUSHBUTTON "L“Z‹", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "&s y[W" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "‚’ " -STRING_ERROR, "G‰[" -STRING_WARNING, "ŚxŤ" -STRING_INFO, "Źî•ń" - -STRING_UNTITLED, "(–ł‘č)" - -STRING_ALL_FILES, "‘S‚Ä‚Ět@C‹ (*.*)" -STRING_TEXT_FILES_TXT, "eLXgt@C‹ (*.txt)" - -STRING_TOOLARGE, "t@C‹ '%s' ‚ĚTCY‚͑傫‚·‚¬‚é‚˝‚ßA‚’ ‚ł͕ҏW‚Ĺ‚«‚Ü‚ą‚ńB\n \ -•Ę‚ĚGfB^‚đŽg—p‚µ‚ĉş‚ł‚˘B" -STRING_NOTEXT, "‰˝‚ŕ“ü—Í‚ł‚ę‚Ä‚˘‚Ü‚ą‚ńB\ -\n‰˝‚©“ü—Í‚µ‚Ä‚©‚çŽŔŤs‚µ‚ĉş‚ł‚˘B" -STRING_DOESNOTEXIST, "t@C‹ '%s'\n‚Í‘¶ŤÝ‚µ‚Ü‚ą‚ń\n\n \ -V‚µ‚˘t@C‹‚đŤě¬‚µ‚Ü‚·‚© ?" -STRING_NOTSAVED, "t@C‹ '%s'\n‚͕ύX‚ł‚ę‚Ä‚˘‚Ü‚·\n\n \ -•ĎŤX‚đ•Ű‘¶‚µ‚Ü‚·‚© ?" -STRING_NOTFOUND, "'%s' ‚ÍŚ©‚‚©‚č‚Ü‚ą‚ń‚Ĺ‚µ‚˝" -STRING_OUT_OF_MEMORY, "‚±‚Ě‘€Ťě‚đŽŔŤs‚·‚é‚˝‚ß‚Ě‚Š‚Ş\ -‘«‚č‚Ü‚ą‚ńB \n‚Š‚Ě‹ó‚«‚đ‘ť‚â‚·‚˝‚߂ɂ˘‚­‚‚©‚ĚAvŠP[V‡“‚đ\nŹI—ą‚µ‚Ä\ -‰ş‚ł‚˘B" -STRING_CANNOTFIND "'%s' ‚ŞŚ©‚‚©‚č‚Ü‚ą‚ń‚Ĺ‚µ‚˝B" -STRING_ANSI, "ANSI" -STRING_UNICODE, "Unicode" -STRING_UNICODE_BE, "Unicode (big endian)" -STRING_UTF8, "UTF-8" -STRING_CRLF, "Windows (CR+LF)" -STRING_LF, "Unix (LF)" -STRING_CR, "Mac (CR)" -} +/* + * Notepad (Japanese resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "t@C‹(&F)" + BEGIN + MENUITEM "V‹KŤě¬(&N)...", CMD_NEW + MENUITEM "ŠJ‚­(&O)\tCtrl+O", CMD_OPEN + MENUITEM "•Ű‘¶(&S)\tCtrl+S", CMD_SAVE + MENUITEM "–Ľ‘O‚đ•t‚Ż‚Ä•Ű‘¶(&A)...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "y[WÝ’č(&T)...", CMD_PAGE_SETUP + MENUITEM "óŤü(&P)", CMD_PRINT + MENUITEM "vŠ“^‚ĚÝ’č(&R)...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "ŹI—ą(&X)", CMD_EXIT + END + POPUP "•ŇŹW(&E)" + BEGIN + MENUITEM "Śł‚É–ß‚·(&U)\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Ř‚čŽć‚č(&T)\tCtrl+X", CMD_CUT + MENUITEM "Rs[(&C)\tCtrl+C", CMD_COPY + MENUITEM "y[Xg(&P)\tCtrl+V", CMD_PASTE + MENUITEM "ŤíŹś(&D)\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "ŚźŤő(&S)\tCtrl+F", CMD_SEARCH + MENUITEM "Žź‚ĚŚó•â‚𦼫ő(&S)\tF3", CMD_SEARCH_NEXT + MENUITEM "’uŠ·\tCtrl+H", CMD_REPLACE + MENUITEM "Ťs‚ÖÚ“®...\tCtrl+G", CMD_GOTO + MENUITEM SEPARATOR + MENUITEM "‘S‚Ä‘I‘đ(&A)\tCtrl+A", CMD_SELECT_ALL + MENUITEM "“ú•t‚ĆŽžŤŹ‚Ě‘}“ü(&T)\tF5", CMD_TIME_DATE + END + POPUP "ʑޮ(&O)" + BEGIN + MENUITEM "’·‚˘Ťs‚đÜ‚č•Ô‚·(&W)", CMD_WRAP + MENUITEM "tH“g(&F)...", CMD_FONT + END + POPUP "•\\ަ(&V)" + BEGIN + MENUITEM "Xe[^X o[(&B)", CMD_STATUSBAR + END + POPUP "w‹v(&H)" + BEGIN + MENUITEM "–ÚŽź(&C)", CMD_HELP_CONTENTS + MENUITEM "ŚźŤő(&S)...", CMD_HELP_SEARCH + MENUITEM "w‹v‚ĚŽg‚˘•ű(&H)", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Źî•ń(&O)" CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 9, "MS UI Gothic" +CAPTION "y[WÝ’č" +{ +LTEXT "wb_(&H):", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "tb^(&F):", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "}[W“(&M):", 0x144, 10, 43,160, 45 +LTEXT "Ť¶(&L):", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Źă(&T):", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "‰E(&R):", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "‰ş(&B):", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "L“Z‹", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "w‹v(&H)", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +/* Dialog `Encoding' */ +DIALOG_ENCODING DIALOG 0, 0, 256, 44 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | + WS_CAPTION | WS_SYSMENU +FONT 9, "MS UI Gothic" +CAPTION "G“R[fB“O" +{ +COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP +LTEXT "•¶ŽšR[h:",0x155,5,2,41,12 +COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +LTEXT "‰üŤsR[h:",0x156,5,20,41,12 +} + +/* Dialog 'Go To' */ +DIALOG_GOTO DIALOG 0,0,165,50 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 9, "MS UI Gothic" +CAPTION "Ťs‚ÖÚ“®" +{ +EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Ťs”ÔŤ†:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER +DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP +PUSHBUTTON "L“Z‹", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "&s y[W" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "‚’ " +STRING_ERROR, "G‰[" +STRING_WARNING, "ŚxŤ" +STRING_INFO, "Źî•ń" + +STRING_UNTITLED, "(–ł‘č)" + +STRING_ALL_FILES, "‘S‚Ä‚Ět@C‹ (*.*)" +STRING_TEXT_FILES_TXT, "eLXgt@C‹ (*.txt)" + +STRING_TOOLARGE, "t@C‹ '%s' ‚ĚTCY‚͑傫‚·‚¬‚é‚˝‚ßA‚’ ‚ł͕ҏW‚Ĺ‚«‚Ü‚ą‚ńB\n \ +•Ę‚ĚGfB^‚đŽg—p‚µ‚ĉş‚ł‚˘B" +STRING_NOTEXT, "‰˝‚ŕ“ü—Í‚ł‚ę‚Ä‚˘‚Ü‚ą‚ńB\ +\n‰˝‚©“ü—Í‚µ‚Ä‚©‚çŽŔŤs‚µ‚ĉş‚ł‚˘B" +STRING_DOESNOTEXIST, "t@C‹ '%s'\n‚Í‘¶ŤÝ‚µ‚Ü‚ą‚ń\n\n \ +V‚µ‚˘t@C‹‚đŤě¬‚µ‚Ü‚·‚© ?" +STRING_NOTSAVED, "t@C‹ '%s'\n‚͕ύX‚ł‚ę‚Ä‚˘‚Ü‚·\n\n \ +•ĎŤX‚đ•Ű‘¶‚µ‚Ü‚·‚© ?" +STRING_NOTFOUND, "'%s' ‚ÍŚ©‚‚©‚č‚Ü‚ą‚ń‚Ĺ‚µ‚˝" +STRING_OUT_OF_MEMORY, "‚±‚Ě‘€Ťě‚đŽŔŤs‚·‚é‚˝‚ß‚Ě‚Š‚Ş\ +‘«‚č‚Ü‚ą‚ńB \n‚Š‚Ě‹ó‚«‚đ‘ť‚â‚·‚˝‚߂ɂ˘‚­‚‚©‚ĚAvŠP[V‡“‚đ\nŹI—ą‚µ‚Ä\ +‰ş‚ł‚˘B" +STRING_CANNOTFIND "'%s' ‚ŞŚ©‚‚©‚č‚Ü‚ą‚ń‚Ĺ‚µ‚˝B" +STRING_ANSI, "ANSI" +STRING_UNICODE, "Unicode" +STRING_UNICODE_BE, "Unicode (big endian)" +STRING_UTF8, "UTF-8" +STRING_CRLF, "Windows (CR+LF)" +STRING_LF, "Unix (LF)" +STRING_CR, "Mac (CR)" +} diff --git a/reactos/base/applications/notepad/lang/Nl.rc b/reactos/base/applications/notepad/lang/Nl.rc index 2daf7e4c99f..026d436b68c 100644 --- a/reactos/base/applications/notepad/lang/Nl.rc +++ b/reactos/base/applications/notepad/lang/Nl.rc @@ -1,161 +1,161 @@ -/* - * Notepad (Dutch resources) - * - * Copyright 2003 Hans Leidekker - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Bestand" - BEGIN - MENUITEM "&Nieuw...", CMD_NEW - MENUITEM "&Openen\tCtrl+O", CMD_OPEN - MENUITEM "O&pslaan\tCtrl+p", CMD_SAVE - MENUITEM "Ops&laan als...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "&Afdrukken", CMD_PRINT - MENUITEM "Pagina-in&stelling...", CMD_PAGE_SETUP - MENUITEM "Printerinstellingen...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Afsluiten", CMD_EXIT - END - POPUP "Be&werken" - BEGIN - MENUITEM "&Ongedaan maken\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "K&nippen\tCtrl+X", CMD_CUT - MENUITEM "&Kopiëren\tCtrl+C", CMD_COPY - MENUITEM "&Plakken\tCtrl+V", CMD_PASTE - MENUITEM "&Verwijderen\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Zoeken\tCtrl+Z", CMD_SEARCH - MENUITEM "&Volgende zoeken\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "&Alles selecteren\tCtrl+A", CMD_SELECT_ALL - MENUITEM "Tijd/&datum\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "A&utomatische terugloop", CMD_WRAP - MENUITEM "&Lettertype instellen...", CMD_FONT - END - POPUP "&Help" - BEGIN - MENUITEM "&Help-onderwerpen", CMD_HELP_CONTENTS - MENUITEM "&Zoeken...", CMD_HELP_SEARCH - MENUITEM "&Hulp bij Help", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Inf&o...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Pagina-instelling" -{ -LTEXT "&Koptekst:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Voettekst:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Marges:", 0x144, 10, 43,160, 45 -LTEXT "Li&nks:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Boven:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Rechts:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Onder:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Annuleren", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Help", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Pagina &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Kladblok" -STRING_ERROR, "FOUT" -STRING_WARNING, "WAARSCHUWING" -STRING_INFO, "Informatie" - -STRING_UNTITLED, "(naamloos)" - -STRING_ALL_FILES, "Alle bestanden (*.*)" -STRING_TEXT_FILES_TXT, "Tekstbestanden (*.txt)" - -STRING_TOOLARGE, "Het bestand '%s' is te groot voor Kladblok.\n \ -Gebruik een andere editor." -STRING_NOTEXT, "U heeft geen tekst ingevoerd. \ -\nType uw tekst en probeer het nogmaals" -STRING_DOESNOTEXIST, "Het bestand '%s'\nbestaat niet\n\n \ -Wilt u een nieuw bestand maken?" -STRING_NOTSAVED, "Het bestand '%s'\nis gewijzigd\n\n \ -Wilt u de wijzigingen opslaan?" -STRING_NOTFOUND, "'%s' kan niet worden gevonden." -STRING_OUT_OF_MEMORY, "Onvoldoende geheugen. \ -\nSluit een of meer applicaties om de hoeveelheid \nbeschikbaar geheugen te vergroten." - -} +/* + * Notepad (Dutch resources) + * + * Copyright 2003 Hans Leidekker + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Bestand" + BEGIN + MENUITEM "&Nieuw...", CMD_NEW + MENUITEM "&Openen\tCtrl+O", CMD_OPEN + MENUITEM "O&pslaan\tCtrl+p", CMD_SAVE + MENUITEM "Ops&laan als...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "&Afdrukken", CMD_PRINT + MENUITEM "Pagina-in&stelling...", CMD_PAGE_SETUP + MENUITEM "Printerinstellingen...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Afsluiten", CMD_EXIT + END + POPUP "Be&werken" + BEGIN + MENUITEM "&Ongedaan maken\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "K&nippen\tCtrl+X", CMD_CUT + MENUITEM "&Kopiëren\tCtrl+C", CMD_COPY + MENUITEM "&Plakken\tCtrl+V", CMD_PASTE + MENUITEM "&Verwijderen\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Zoeken\tCtrl+Z", CMD_SEARCH + MENUITEM "&Volgende zoeken\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "&Alles selecteren\tCtrl+A", CMD_SELECT_ALL + MENUITEM "Tijd/&datum\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "A&utomatische terugloop", CMD_WRAP + MENUITEM "&Lettertype instellen...", CMD_FONT + END + POPUP "&Help" + BEGIN + MENUITEM "&Help-onderwerpen", CMD_HELP_CONTENTS + MENUITEM "&Zoeken...", CMD_HELP_SEARCH + MENUITEM "&Hulp bij Help", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Inf&o...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Pagina-instelling" +{ +LTEXT "&Koptekst:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Voettekst:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Marges:", 0x144, 10, 43,160, 45 +LTEXT "Li&nks:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Boven:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Rechts:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Onder:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Annuleren", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Help", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Pagina &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Kladblok" +STRING_ERROR, "FOUT" +STRING_WARNING, "WAARSCHUWING" +STRING_INFO, "Informatie" + +STRING_UNTITLED, "(naamloos)" + +STRING_ALL_FILES, "Alle bestanden (*.*)" +STRING_TEXT_FILES_TXT, "Tekstbestanden (*.txt)" + +STRING_TOOLARGE, "Het bestand '%s' is te groot voor Kladblok.\n \ +Gebruik een andere editor." +STRING_NOTEXT, "U heeft geen tekst ingevoerd. \ +\nType uw tekst en probeer het nogmaals" +STRING_DOESNOTEXIST, "Het bestand '%s'\nbestaat niet\n\n \ +Wilt u een nieuw bestand maken?" +STRING_NOTSAVED, "Het bestand '%s'\nis gewijzigd\n\n \ +Wilt u de wijzigingen opslaan?" +STRING_NOTFOUND, "'%s' kan niet worden gevonden." +STRING_OUT_OF_MEMORY, "Onvoldoende geheugen. \ +\nSluit een of meer applicaties om de hoeveelheid \nbeschikbaar geheugen te vergroten." + +} diff --git a/reactos/base/applications/notepad/lang/Pl.rc b/reactos/base/applications/notepad/lang/Pl.rc index 4f89f33c705..d17c181e580 100644 --- a/reactos/base/applications/notepad/lang/Pl.rc +++ b/reactos/base/applications/notepad/lang/Pl.rc @@ -1,164 +1,164 @@ -/* - * Notepad (Polish resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Copyright 2002 Sylvain Petreolle - * Copyright 2004 Jacek Caban - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_POLISH, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Plik" - BEGIN - MENUITEM "&Nowy...", CMD_NEW - MENUITEM "&Otwórz\tCtrl+O", CMD_OPEN - MENUITEM "&Zapisz\tCtrl+S", CMD_SAVE - MENUITEM "Z&apisz jako...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "&Drukuj", CMD_PRINT - MENUITEM "&Ustawienia strony...", CMD_PAGE_SETUP - MENUITEM "Ustawienia &drukarki...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "Zakoń&cz", CMD_EXIT - END - POPUP "&Edycja" - BEGIN - MENUITEM "&Cofnij\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Wytnij\tCtrl+X", CMD_CUT - MENUITEM "&Kopiuj\tCtrl+C", CMD_COPY - MENUITEM "Wkl&ej\tCtrl+V", CMD_PASTE - MENUITEM "&Usuń\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Znajdź\tCtrl+F", CMD_SEARCH - MENUITEM "Z&najdź następny\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "Zaznacz w&szystko\tCtrl+A", CMD_SELECT_ALL - MENUITEM "Godzina/&Data\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "&Zawijanie wierszy", CMD_WRAP - MENUITEM "Czci&onka...", CMD_FONT - END - POPUP "Pomo&c" - BEGIN - MENUITEM "&Tematy pomocy", CMD_HELP_CONTENTS - MENUITEM "&Szukaj...", CMD_HELP_SEARCH - MENUITEM "&Pomoc", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "In&fo...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Ustawienia strony" -{ -LTEXT "&Nagłówek:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Stopka:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Marginesy:", 0x144, 10, 43,160, 45 -LTEXT "&Lewy:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Górny:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "P&rawy:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Dolny:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Anuluj", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Pomoc", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Strona &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Notatnik" -STRING_ERROR, "BŁĄD" -STRING_WARNING, "OSTRZEŻENIE" -STRING_INFO, "Informacja" - -STRING_UNTITLED, "(bez tytułu)" - -STRING_ALL_FILES, "Wszystkie piki (*.*)" -STRING_TEXT_FILES_TXT, "Pliki tekstowe (*.txt)" - -STRING_TOOLARGE, "Plik '%s' jest za duży dla notatnika.\n \ -Proszę użyć innego edytora." -STRING_NOTEXT, "Nie wprowadziłeś żadnego tekstu. \ -\nProszę coś wpisać i spróbować ponownie." -STRING_DOESNOTEXIST, "Plik '%s' nie istnieje\n\n \ -Czy chcesz utworzyć nowy plik ?" -STRING_NOTSAVED, "Plik '%s'\nzostał zmodyfikowany\n\n \ -Czy chcesz zachować zmiany ?" -STRING_NOTFOUND, "Nie można odnaleźć '%s'." -STRING_OUT_OF_MEMORY, "Za mało pamięci do wykonania tego zadania.\n \ -Zamknij jedną lub więcej aplikacji aby zwiększyć ilość wolnej pamięci." - -} +/* + * Notepad (Polish resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * Copyright 2004 Jacek Caban + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Plik" + BEGIN + MENUITEM "&Nowy...", CMD_NEW + MENUITEM "&Otwórz\tCtrl+O", CMD_OPEN + MENUITEM "&Zapisz\tCtrl+S", CMD_SAVE + MENUITEM "Z&apisz jako...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "&Drukuj", CMD_PRINT + MENUITEM "&Ustawienia strony...", CMD_PAGE_SETUP + MENUITEM "Ustawienia &drukarki...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "Zakoń&cz", CMD_EXIT + END + POPUP "&Edycja" + BEGIN + MENUITEM "&Cofnij\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Wytnij\tCtrl+X", CMD_CUT + MENUITEM "&Kopiuj\tCtrl+C", CMD_COPY + MENUITEM "Wkl&ej\tCtrl+V", CMD_PASTE + MENUITEM "&Usuń\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Znajdź\tCtrl+F", CMD_SEARCH + MENUITEM "Z&najdź następny\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "Zaznacz w&szystko\tCtrl+A", CMD_SELECT_ALL + MENUITEM "Godzina/&Data\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "&Zawijanie wierszy", CMD_WRAP + MENUITEM "Czci&onka...", CMD_FONT + END + POPUP "Pomo&c" + BEGIN + MENUITEM "&Tematy pomocy", CMD_HELP_CONTENTS + MENUITEM "&Szukaj...", CMD_HELP_SEARCH + MENUITEM "&Pomoc", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "In&fo...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Ustawienia strony" +{ +LTEXT "&Nagłówek:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Stopka:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Marginesy:", 0x144, 10, 43,160, 45 +LTEXT "&Lewy:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Górny:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "P&rawy:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Dolny:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Anuluj", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Pomoc", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Strona &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notatnik" +STRING_ERROR, "BŁĄD" +STRING_WARNING, "OSTRZEŻENIE" +STRING_INFO, "Informacja" + +STRING_UNTITLED, "(bez tytułu)" + +STRING_ALL_FILES, "Wszystkie piki (*.*)" +STRING_TEXT_FILES_TXT, "Pliki tekstowe (*.txt)" + +STRING_TOOLARGE, "Plik '%s' jest za duży dla notatnika.\n \ +Proszę użyć innego edytora." +STRING_NOTEXT, "Nie wprowadziłeś żadnego tekstu. \ +\nProszę coś wpisać i spróbować ponownie." +STRING_DOESNOTEXIST, "Plik '%s' nie istnieje\n\n \ +Czy chcesz utworzyć nowy plik ?" +STRING_NOTSAVED, "Plik '%s'\nzostał zmodyfikowany\n\n \ +Czy chcesz zachować zmiany ?" +STRING_NOTFOUND, "Nie można odnaleźć '%s'." +STRING_OUT_OF_MEMORY, "Za mało pamięci do wykonania tego zadania.\n \ +Zamknij jedną lub więcej aplikacji aby zwiększyć ilość wolnej pamięci." + +} diff --git a/reactos/base/applications/notepad/lang/Pt.rc b/reactos/base/applications/notepad/lang/Pt.rc index c980d2c8de1..2f3a008fdfe 100644 --- a/reactos/base/applications/notepad/lang/Pt.rc +++ b/reactos/base/applications/notepad/lang/Pt.rc @@ -1,164 +1,164 @@ -/* - * Notepad - * Portuguese Language Support - * - * Copyright 1999 Marcel Baur - * Copyright 2002 Sylvain Petreolle - * Copyright 2003 Marcelo Duarte - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Arquivo" - BEGIN - MENUITEM "&Novo...", CMD_NEW - MENUITEM "A&brir", CMD_OPEN - MENUITEM "&Salvar", CMD_SAVE - MENUITEM "Salvar &como...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "&Imprimir", CMD_PRINT - MENUITEM "C&onfigurar página...", CMD_PAGE_SETUP - MENUITEM "Configurar i&mpressora...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "Sai&r", CMD_EXIT - END - POPUP "&Editar" - BEGIN - MENUITEM "&Desfazer\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Recortar\tCtrl+X", CMD_CUT - MENUITEM "&Copiar\tCtrl+C", CMD_COPY - MENUITEM "C&olar\tCtrl+V", CMD_PASTE - MENUITEM "E&xcluir\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Localizar...", CMD_SEARCH - MENUITEM "Localizar &próxima\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "Selecionar &tudo", CMD_SELECT_ALL - MENUITEM "&Data/Hora\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "&Quebrar automática de linha", CMD_WRAP - MENUITEM "&Fonte...", CMD_FONT - END - POPUP "&Ajuda" - BEGIN - MENUITEM "&Conteúdo", CMD_HELP_CONTENTS - MENUITEM "&Procurar...", CMD_HELP_SEARCH - MENUITEM "&Ajuda na ajuda", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "&Informaçőes...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Configurar página" -{ -LTEXT "&Cabeçalho:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Rodapé:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Margens:", 0x144, 10, 43,160, 45 -LTEXT "&Esquerda:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Superior:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Direita:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Inferior:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Cancelar", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Ajuda", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Página &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Notepad" -STRING_ERROR, "ERRO" -STRING_WARNING, "AVISO" -STRING_INFO, "Informaçăo" - -STRING_UNTITLED, "(sem nome)" - -STRING_ALL_FILES, "Todos os arquivos (*.*)" -STRING_TEXT_FILES_TXT, "Arquivos texto (*.txt)" - -STRING_TOOLARGE, "Arquivo '%s' é muito longo para o notepad.\n \ -Por favor use um editor diferente." -STRING_NOTEXT, "Vocę năo digitou nenhum texto. \ -\nPor favor digite alguma coisa e tente novamente" -STRING_DOESNOTEXIST, "Arquivo '%s'\nnăo existe\n\n \ -Vocę deseja criar um novo arquivo?" -STRING_NOTSAVED, "Arquivo '%s'\nfoi modificado\n\n \ -Gostaria de salvar as alteraçŐes?" -STRING_NOTFOUND, "'%s' năo pode ser encontrado." -STRING_OUT_OF_MEMORY, "Năo há memória suficiente para completar essa \ -tarefa. \nFeche uma ou mais aplicaçőes para aumentar a quantidade de memória livre." - -} +/* + * Notepad + * Portuguese Language Support + * + * Copyright 1999 Marcel Baur + * Copyright 2002 Sylvain Petreolle + * Copyright 2003 Marcelo Duarte + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Arquivo" + BEGIN + MENUITEM "&Novo...", CMD_NEW + MENUITEM "A&brir", CMD_OPEN + MENUITEM "&Salvar", CMD_SAVE + MENUITEM "Salvar &como...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "&Imprimir", CMD_PRINT + MENUITEM "C&onfigurar página...", CMD_PAGE_SETUP + MENUITEM "Configurar i&mpressora...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "Sai&r", CMD_EXIT + END + POPUP "&Editar" + BEGIN + MENUITEM "&Desfazer\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Recortar\tCtrl+X", CMD_CUT + MENUITEM "&Copiar\tCtrl+C", CMD_COPY + MENUITEM "C&olar\tCtrl+V", CMD_PASTE + MENUITEM "E&xcluir\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Localizar...", CMD_SEARCH + MENUITEM "Localizar &próxima\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "Selecionar &tudo", CMD_SELECT_ALL + MENUITEM "&Data/Hora\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "&Quebrar automática de linha", CMD_WRAP + MENUITEM "&Fonte...", CMD_FONT + END + POPUP "&Ajuda" + BEGIN + MENUITEM "&Conteúdo", CMD_HELP_CONTENTS + MENUITEM "&Procurar...", CMD_HELP_SEARCH + MENUITEM "&Ajuda na ajuda", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "&Informaçőes...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Configurar página" +{ +LTEXT "&Cabeçalho:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Rodapé:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Margens:", 0x144, 10, 43,160, 45 +LTEXT "&Esquerda:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Superior:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Direita:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Inferior:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Cancelar", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Ajuda", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Página &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notepad" +STRING_ERROR, "ERRO" +STRING_WARNING, "AVISO" +STRING_INFO, "Informaçăo" + +STRING_UNTITLED, "(sem nome)" + +STRING_ALL_FILES, "Todos os arquivos (*.*)" +STRING_TEXT_FILES_TXT, "Arquivos texto (*.txt)" + +STRING_TOOLARGE, "Arquivo '%s' é muito longo para o notepad.\n \ +Por favor use um editor diferente." +STRING_NOTEXT, "Vocę năo digitou nenhum texto. \ +\nPor favor digite alguma coisa e tente novamente" +STRING_DOESNOTEXIST, "Arquivo '%s'\nnăo existe\n\n \ +Vocę deseja criar um novo arquivo?" +STRING_NOTSAVED, "Arquivo '%s'\nfoi modificado\n\n \ +Gostaria de salvar as alteraçŐes?" +STRING_NOTFOUND, "'%s' năo pode ser encontrado." +STRING_OUT_OF_MEMORY, "Năo há memória suficiente para completar essa \ +tarefa. \nFeche uma ou mais aplicaçőes para aumentar a quantidade de memória livre." + +} diff --git a/reactos/base/applications/notepad/lang/Ru.rc b/reactos/base/applications/notepad/lang/Ru.rc index a16694d5186..9c2fcfbc9cc 100644 --- a/reactos/base/applications/notepad/lang/Ru.rc +++ b/reactos/base/applications/notepad/lang/Ru.rc @@ -1,159 +1,159 @@ -/* - * Notepad (Russian resources) - * - * Copyright 2003 Igor Stepin - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Ôŕéë" - BEGIN - MENUITEM "Ńîçä&ŕňü", CMD_NEW - MENUITEM "&Îňęđűňü...", CMD_OPEN - MENUITEM "&Ńîőđŕíčňü", CMD_SAVE - MENUITEM "Ńîőđŕíčňü &ęŕę...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "Ďŕđŕ&ěĺňđű ńňđŕíčöű...", CMD_PAGE_SETUP - MENUITEM "&Íŕńňđîéęŕ ďđčíňĺđŕ...", CMD_PRINTER_SETUP - MENUITEM "&Ďĺ÷ŕňŕňü", CMD_PRINT - MENUITEM SEPARATOR - MENUITEM "Â&űőîä", CMD_EXIT - END - POPUP "&Ďđŕâęŕ" - BEGIN - MENUITEM "&Îňěĺíčňü\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Âűđĺçŕňü\tCtrl+X", CMD_CUT - MENUITEM "&Ęîďčđîâŕňü\tCtrl+C", CMD_COPY - MENUITEM "Âńň&ŕâčňü\tCtrl+V", CMD_PASTE - MENUITEM "&Óäŕëčňü\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Íŕéňč", CMD_SEARCH - MENUITEM "Íŕéňč &äŕëĺĺ\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "Âűäĺëčňü â&ńĺ", CMD_SELECT_ALL - MENUITEM "Âđĺě&˙ č äŕňŕ\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "&Ďĺđĺíîń ďî ńëîâŕě", CMD_WRAP - END - POPUP "&Ńďđŕâęŕ" - BEGIN - MENUITEM "&Ńîäĺđćŕíčĺ", CMD_HELP_CONTENTS - MENUITEM "&Ďîčńę...", CMD_HELP_SEARCH - MENUITEM "&Čńďîëüçîâŕíčĺ ńďđŕâęč", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "&Ńâĺäĺíč˙...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Ďŕđŕěĺňđű ńňđŕíčöű" -{ -LTEXT "Â&ĺđőíčé ęîëîíňčňóë:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "Í&čćíčé ęîëîíňčňóë:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "Ďîë˙ (ěě):", 0x144, 10, 43,160, 45 -LTEXT "&Ëĺâîĺ:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Âĺđőíĺĺ:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Ďđŕâîĺ:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Íčćíĺĺ:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Îňěĺíŕ", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Ńďđŕâęŕ", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Ńňđŕíčöŕ &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 ěě" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 ěě" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 ěě" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 ěě" /* FIXME */ - -STRING_NOTEPAD, "Áëîęíîň" -STRING_ERROR, "ÎŘČÁĘŔ" -STRING_WARNING, "ÂÍČĚŔÍČĹ" -STRING_INFO, "Číôîđěŕöč˙" - -STRING_UNTITLED, "(áĺç çŕăîëîâęŕ)" - -STRING_ALL_FILES, "Âńĺ ôŕéëű (*.*)" -STRING_TEXT_FILES_TXT, "Ňĺęńňîâűĺ ôŕéëű (*.txt)" - -STRING_TOOLARGE, "Ôŕéë '%s' ńëčřęîě áîëüřîé äë˙ áëîęíîňŕ.\n \ -Čńďîëüçóéňĺ äđóăîé đĺäŕęňîđ." -STRING_NOTEXT, "Âű íĺ ââĺëč íčęŕęîăî ňĺęńňŕ. \ -\nÂâĺäčňĺ ÷ňî-íčáóäü č ďîďđîáóéňĺ ĺůĺ." -STRING_DOESNOTEXIST, "Ôŕéë '%s'\níĺ ńóůĺńňâóĺň\n\n \ -Őîňčňĺ ńîçäŕňü íîâűé ôŕéë?" -STRING_NOTSAVED, "Ôŕéë '%s'\náűë čçěĺíĺí\n\n \ -Őîňčňĺ ńîőđŕíčňü čçěĺíĺíč˙?" -STRING_NOTFOUND, "'%s' íĺ íŕéäĺí." -STRING_OUT_OF_MEMORY, "Íĺäîńňŕňî÷íî ďŕě˙ňč äë˙ çŕâĺđřĺíč˙ ýňîé îďĺđŕöčč \ -\nÇŕęđîéňĺ îäíî čëč íĺńęîëüęî ďđčëîćĺíčé č ďîâňîđčňĺ ďîďűňęó." - -} +/* + * Notepad (Russian resources) + * + * Copyright 2003 Igor Stepin + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Ôŕéë" + BEGIN + MENUITEM "Ńîçä&ŕňü", CMD_NEW + MENUITEM "&Îňęđűňü...", CMD_OPEN + MENUITEM "&Ńîőđŕíčňü", CMD_SAVE + MENUITEM "Ńîőđŕíčňü &ęŕę...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Ďŕđŕ&ěĺňđű ńňđŕíčöű...", CMD_PAGE_SETUP + MENUITEM "&Íŕńňđîéęŕ ďđčíňĺđŕ...", CMD_PRINTER_SETUP + MENUITEM "&Ďĺ÷ŕňŕňü", CMD_PRINT + MENUITEM SEPARATOR + MENUITEM "Â&űőîä", CMD_EXIT + END + POPUP "&Ďđŕâęŕ" + BEGIN + MENUITEM "&Îňěĺíčňü\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Âűđĺçŕňü\tCtrl+X", CMD_CUT + MENUITEM "&Ęîďčđîâŕňü\tCtrl+C", CMD_COPY + MENUITEM "Âńň&ŕâčňü\tCtrl+V", CMD_PASTE + MENUITEM "&Óäŕëčňü\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Íŕéňč", CMD_SEARCH + MENUITEM "Íŕéňč &äŕëĺĺ\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "Âűäĺëčňü â&ńĺ", CMD_SELECT_ALL + MENUITEM "Âđĺě&˙ č äŕňŕ\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "&Ďĺđĺíîń ďî ńëîâŕě", CMD_WRAP + END + POPUP "&Ńďđŕâęŕ" + BEGIN + MENUITEM "&Ńîäĺđćŕíčĺ", CMD_HELP_CONTENTS + MENUITEM "&Ďîčńę...", CMD_HELP_SEARCH + MENUITEM "&Čńďîëüçîâŕíčĺ ńďđŕâęč", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "&Ńâĺäĺíč˙...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Ďŕđŕěĺňđű ńňđŕíčöű" +{ +LTEXT "Â&ĺđőíčé ęîëîíňčňóë:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "Í&čćíčé ęîëîíňčňóë:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "Ďîë˙ (ěě):", 0x144, 10, 43,160, 45 +LTEXT "&Ëĺâîĺ:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Âĺđőíĺĺ:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Ďđŕâîĺ:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Íčćíĺĺ:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Îňěĺíŕ", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Ńďđŕâęŕ", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Ńňđŕíčöŕ &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 ěě" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 ěě" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 ěě" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 ěě" /* FIXME */ + +STRING_NOTEPAD, "Áëîęíîň" +STRING_ERROR, "ÎŘČÁĘŔ" +STRING_WARNING, "ÂÍČĚŔÍČĹ" +STRING_INFO, "Číôîđěŕöč˙" + +STRING_UNTITLED, "(áĺç çŕăîëîâęŕ)" + +STRING_ALL_FILES, "Âńĺ ôŕéëű (*.*)" +STRING_TEXT_FILES_TXT, "Ňĺęńňîâűĺ ôŕéëű (*.txt)" + +STRING_TOOLARGE, "Ôŕéë '%s' ńëčřęîě áîëüřîé äë˙ áëîęíîňŕ.\n \ +Čńďîëüçóéňĺ äđóăîé đĺäŕęňîđ." +STRING_NOTEXT, "Âű íĺ ââĺëč íčęŕęîăî ňĺęńňŕ. \ +\nÂâĺäčňĺ ÷ňî-íčáóäü č ďîďđîáóéňĺ ĺůĺ." +STRING_DOESNOTEXIST, "Ôŕéë '%s'\níĺ ńóůĺńňâóĺň\n\n \ +Őîňčňĺ ńîçäŕňü íîâűé ôŕéë?" +STRING_NOTSAVED, "Ôŕéë '%s'\náűë čçěĺíĺí\n\n \ +Őîňčňĺ ńîőđŕíčňü čçěĺíĺíč˙?" +STRING_NOTFOUND, "'%s' íĺ íŕéäĺí." +STRING_OUT_OF_MEMORY, "Íĺäîńňŕňî÷íî ďŕě˙ňč äë˙ çŕâĺđřĺíč˙ ýňîé îďĺđŕöčč \ +\nÇŕęđîéňĺ îäíî čëč íĺńęîëüęî ďđčëîćĺíčé č ďîâňîđčňĺ ďîďűňęó." + +} diff --git a/reactos/base/applications/notepad/lang/Si.rc b/reactos/base/applications/notepad/lang/Si.rc index d0d279acddc..8abf6aa93fe 100644 --- a/reactos/base/applications/notepad/lang/Si.rc +++ b/reactos/base/applications/notepad/lang/Si.rc @@ -1,160 +1,160 @@ -/* - * Notepad (Slovenian resources) - * - * Copyright 2002-2003 Rok Mandeljc - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Datoteka" - BEGIN - MENUITEM "&Nova", CMD_NEW - MENUITEM "&Odpri ...", CMD_OPEN - MENUITEM "&Shrani", CMD_SAVE - MENUITEM "Shrani &kot ...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "Na&tisni", CMD_PRINT - MENUITEM "P&riprava strani ...", CMD_PAGE_SETUP - MENUITEM "&Tiskalnik ...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "Iz&hod", CMD_EXIT - END - POPUP "&Urejanje" - BEGIN - MENUITEM "&Razveljavi\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Izreži\tCtrl+X", CMD_CUT - MENUITEM "&Kopiraj\tCtrl+C", CMD_COPY - MENUITEM "&Prilepi\tCtrl+V", CMD_PASTE - MENUITEM "Izbri&ši\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "&Najdi ...", CMD_SEARCH - MENUITEM "Na&daljuj iskanje\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "Izberi &vse", CMD_SELECT_ALL - MENUITEM "Čas/&Datum\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "Pr&elom vrstice", CMD_WRAP - END - POPUP "&Pomoč" - BEGIN - MENUITEM "&Teme pomoči", CMD_HELP_CONTENTS - MENUITEM "&Najdi ...", CMD_HELP_SEARCH - MENUITEM "&O pomoči", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Inf&ormacije ...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Page Setup" -{ -LTEXT "&Glava:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Noga:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "Robovi", 0x144, 10, 43,160, 45 -LTEXT "&Levo:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Desno:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Zgoraj:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Spodaj:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "V redu", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Prekliči", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Pomoč", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Stran &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Beležnica" -STRING_ERROR, "NAPAKA" -STRING_WARNING, "OPOZORILO" -STRING_INFO, "Informacija" - -STRING_UNTITLED, "Neimenovana" - -STRING_ALL_FILES, "Vse datoteke (*.*)" -STRING_TEXT_FILES_TXT, "Datoteke z besedilom (*.txt)" - -STRING_TOOLARGE, "Datoteka '%s' je prevelika za Beležnico.\n \ -Uporabite drug urejevalnik." -STRING_NOTEXT, "Niste vnesli besedila. \ -\nVnesite besedilo in poskusite znova." -STRING_DOESNOTEXIST, "Datoteka '%s' ne obstaja.\n\n \ -Ali želite ustvariti novo datoteko?" -STRING_NOTSAVED, "Vsebina datoteke '%s'je bila spremenjena.\n\n \ -Ali želite shraniti spremembe?" -STRING_NOTFOUND, "Ni mogoče najti '%s'." -STRING_OUT_OF_MEMORY, "Na voljo ni dovolj pomnilnika, da bi bilo mogoče dokončati to \ -operacijo. \nČe ga želite sprostiti, končajte enega ali več programov in poskusite znova. " - -} +/* + * Notepad (Slovenian resources) + * + * Copyright 2002-2003 Rok Mandeljc + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Datoteka" + BEGIN + MENUITEM "&Nova", CMD_NEW + MENUITEM "&Odpri ...", CMD_OPEN + MENUITEM "&Shrani", CMD_SAVE + MENUITEM "Shrani &kot ...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Na&tisni", CMD_PRINT + MENUITEM "P&riprava strani ...", CMD_PAGE_SETUP + MENUITEM "&Tiskalnik ...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "Iz&hod", CMD_EXIT + END + POPUP "&Urejanje" + BEGIN + MENUITEM "&Razveljavi\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Izreži\tCtrl+X", CMD_CUT + MENUITEM "&Kopiraj\tCtrl+C", CMD_COPY + MENUITEM "&Prilepi\tCtrl+V", CMD_PASTE + MENUITEM "Izbri&ši\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "&Najdi ...", CMD_SEARCH + MENUITEM "Na&daljuj iskanje\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "Izberi &vse", CMD_SELECT_ALL + MENUITEM "Čas/&Datum\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "Pr&elom vrstice", CMD_WRAP + END + POPUP "&Pomoč" + BEGIN + MENUITEM "&Teme pomoči", CMD_HELP_CONTENTS + MENUITEM "&Najdi ...", CMD_HELP_SEARCH + MENUITEM "&O pomoči", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Inf&ormacije ...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Page Setup" +{ +LTEXT "&Glava:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Noga:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "Robovi", 0x144, 10, 43,160, 45 +LTEXT "&Levo:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Desno:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Zgoraj:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Spodaj:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "V redu", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Prekliči", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Pomoč", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Stran &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Beležnica" +STRING_ERROR, "NAPAKA" +STRING_WARNING, "OPOZORILO" +STRING_INFO, "Informacija" + +STRING_UNTITLED, "Neimenovana" + +STRING_ALL_FILES, "Vse datoteke (*.*)" +STRING_TEXT_FILES_TXT, "Datoteke z besedilom (*.txt)" + +STRING_TOOLARGE, "Datoteka '%s' je prevelika za Beležnico.\n \ +Uporabite drug urejevalnik." +STRING_NOTEXT, "Niste vnesli besedila. \ +\nVnesite besedilo in poskusite znova." +STRING_DOESNOTEXIST, "Datoteka '%s' ne obstaja.\n\n \ +Ali želite ustvariti novo datoteko?" +STRING_NOTSAVED, "Vsebina datoteke '%s'je bila spremenjena.\n\n \ +Ali želite shraniti spremembe?" +STRING_NOTFOUND, "Ni mogoče najti '%s'." +STRING_OUT_OF_MEMORY, "Na voljo ni dovolj pomnilnika, da bi bilo mogoče dokončati to \ +operacijo. \nČe ga želite sprostiti, končajte enega ali več programov in poskusite znova. " + +} diff --git a/reactos/base/applications/notepad/lang/Sk.rc b/reactos/base/applications/notepad/lang/Sk.rc index 9190d2a43a2..ebd5f2d48d7 100644 --- a/reactos/base/applications/notepad/lang/Sk.rc +++ b/reactos/base/applications/notepad/lang/Sk.rc @@ -1,167 +1,167 @@ -/* - * Notepad (Slovak resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Copyright 2002 Sylvain Petreolle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -{ - POPUP "&File" - BEGIN - MENUITEM "&New...", CMD_NEW - MENUITEM "&Open", CMD_OPEN - MENUITEM "&Save", CMD_SAVE - MENUITEM "Save &as...", CMD_SAVE_AS - MENUITEM "&Print", CMD_PRINT - MENUITEM "Page Se&tup...", CMD_PAGE_SETUP - MENUITEM "P&rinter Setup...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Exit", CMD_EXIT - } - POPUP "&Edit" - BEGIN - MENUITEM "&Undo\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "Cu&t\tCtrl+X", CMD_CUT - MENUITEM "&Copy\tCtrl+C", CMD_COPY - MENUITEM "&Paste\tCtrl+V", CMD_PASTE - MENUITEM "&Delete\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "Select &all", CMD_SELECT_ALL - MENUITEM "&Time/Date\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "&Wrap long lines", CMD_WRAP - } - POPUP "&Search" - BEGIN - MENUITEM "&Search", CMD_SEARCH - MENUITEM "&Search next\tF3", CMD_SEARCH_NEXT - } - POPUP "&Help" - BEGIN - MENUITEM "&Contents", CMD_HELP_CONTENTS - MENUITEM "&Search...", CMD_HELP_SEARCH - MENUITEM "&Help on help", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - POPUP "Inf&o..." - BEGIN - MENUITEM "&About" CMD_ABOUT - MENUITEM "&About Wine", CMD_ABOUT_WINE - } - } -} - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Page Setup" -{ -LTEXT "&Header:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Footer:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Margins:", 0x144, 10, 43,160, 45 -LTEXT "&Left:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Top:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Right:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Bottom:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Cancel", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Help", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Notepad" -STRING_ERROR, "ERROR" -STRING_WARNING, "WARNING" -STRING_INFO, "Information" - -STRING_UNTITLED, "(untitled)" - -STRING_ALL_FILES, "All files (*.*)" -STRING_TEXT_FILES_TXT, "Text files (*.txt)" - -STRING_TOOLARGE, "File '%s' is too large for notepad.\n \ -Please use a different editor." -STRING_NOTEXT, "You didn't enter any text. \ -\nPlease type something and try again" -STRING_DOESNOTEXIST, "File '%s'\ndoes not exist\n\n \ -Do you want to create a new file ?" -STRING_NOTSAVED, "File '%s'\nhas been modified\n\n \ -Would you like to save the changes ?" -STRING_NOTFOUND, "'%s' can not be found." -STRING_OUT_OF_MEMORY, "Not enough memory to complete this \ -task. \nClose one or more applications to increase the amount of \nfree \ -memory." - -} +/* + * Notepad (Slovak resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +{ + POPUP "&File" + BEGIN + MENUITEM "&New...", CMD_NEW + MENUITEM "&Open", CMD_OPEN + MENUITEM "&Save", CMD_SAVE + MENUITEM "Save &as...", CMD_SAVE_AS + MENUITEM "&Print", CMD_PRINT + MENUITEM "Page Se&tup...", CMD_PAGE_SETUP + MENUITEM "P&rinter Setup...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Exit", CMD_EXIT + } + POPUP "&Edit" + BEGIN + MENUITEM "&Undo\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Cu&t\tCtrl+X", CMD_CUT + MENUITEM "&Copy\tCtrl+C", CMD_COPY + MENUITEM "&Paste\tCtrl+V", CMD_PASTE + MENUITEM "&Delete\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "Select &all", CMD_SELECT_ALL + MENUITEM "&Time/Date\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "&Wrap long lines", CMD_WRAP + } + POPUP "&Search" + BEGIN + MENUITEM "&Search", CMD_SEARCH + MENUITEM "&Search next\tF3", CMD_SEARCH_NEXT + } + POPUP "&Help" + BEGIN + MENUITEM "&Contents", CMD_HELP_CONTENTS + MENUITEM "&Search...", CMD_HELP_SEARCH + MENUITEM "&Help on help", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + POPUP "Inf&o..." + BEGIN + MENUITEM "&About" CMD_ABOUT + MENUITEM "&About Wine", CMD_ABOUT_WINE + } + } +} + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Page Setup" +{ +LTEXT "&Header:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Footer:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Margins:", 0x144, 10, 43,160, 45 +LTEXT "&Left:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Top:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Right:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Bottom:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Cancel", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Help", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notepad" +STRING_ERROR, "ERROR" +STRING_WARNING, "WARNING" +STRING_INFO, "Information" + +STRING_UNTITLED, "(untitled)" + +STRING_ALL_FILES, "All files (*.*)" +STRING_TEXT_FILES_TXT, "Text files (*.txt)" + +STRING_TOOLARGE, "File '%s' is too large for notepad.\n \ +Please use a different editor." +STRING_NOTEXT, "You didn't enter any text. \ +\nPlease type something and try again" +STRING_DOESNOTEXIST, "File '%s'\ndoes not exist\n\n \ +Do you want to create a new file ?" +STRING_NOTSAVED, "File '%s'\nhas been modified\n\n \ +Would you like to save the changes ?" +STRING_NOTFOUND, "'%s' can not be found." +STRING_OUT_OF_MEMORY, "Not enough memory to complete this \ +task. \nClose one or more applications to increase the amount of \nfree \ +memory." + +} diff --git a/reactos/base/applications/notepad/lang/Sv.rc b/reactos/base/applications/notepad/lang/Sv.rc index 0362e892a6b..11521e134e3 100644 --- a/reactos/base/applications/notepad/lang/Sv.rc +++ b/reactos/base/applications/notepad/lang/Sv.rc @@ -1,162 +1,162 @@ -/* - * Notepad (Swedish resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Copyright 2002 Sylvain Petreolle - * Fixed by Anders Bergh 2005 - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "&Arkiv" - BEGIN - MENUITEM "&Ny...", CMD_NEW - MENUITEM "&Öppna", CMD_OPEN - MENUITEM "&Spara", CMD_SAVE - MENUITEM "Spara so&m...", CMD_SAVE_AS - MENUITEM "Skriv &ut...", CMD_PRINT - MENUITEM "Utskrifts&format...", CMD_PAGE_SETUP - MENUITEM "Skrivar&inställningar...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "&Avsluta", CMD_EXIT - END - POPUP "&Redigera" - BEGIN - MENUITEM "&Ĺngra\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Klipp ut\tCtrl+X", CMD_CUT - MENUITEM "K&opiera\tCtrl+C", CMD_COPY - MENUITEM "K&listra in\tCtrl+V", CMD_PASTE - MENUITEM "&Ta bort\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "Sök...", CMD_SEARCH - MENUITEM "&Sök nästa\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "Markera &allt", CMD_SELECT_ALL - MENUITEM "&Tid/datum\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "&Automatiskt radbyte", CMD_WRAP - END - POPUP "&Hjälp" - BEGIN - MENUITEM "&Innehĺll", CMD_HELP_CONTENTS - MENUITEM "&Sök...", CMD_HELP_SEARCH - MENUITEM "Anvisningar för hjälpen", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "Inf&ormation...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Skrivarinställningar" -{ -LTEXT "&Huvudnot:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Fotnot:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "Marginaler:", 0x144, 10, 43,160, 45 -LTEXT "&Vänsterkant:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Överkant:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Högerkant:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Nederkant:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Avbryt", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Hjälp", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" -STRING_PAGESETUP_FOOTERVALUE, "Sida &s" -STRING_PAGESETUP_LEFTVALUE, "20 mm" -STRING_PAGESETUP_RIGHTVALUE, "20 mm" -STRING_PAGESETUP_TOPVALUE, "25 mm" -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" - -STRING_NOTEPAD, "Anteckningar" -STRING_ERROR, "FEL" -STRING_WARNING, "VARNING" -STRING_INFO, "Information" - -STRING_UNTITLED, "(namnlös)" - -STRING_ALL_FILES, "Alla filer (*.*)" -STRING_TEXT_FILES_TXT, "Textfiler (*.txt)" - -STRING_TOOLARGE, "Filen '%s' är för stor för Anteckningar.\n \ -Använd en annan editor." -STRING_NOTEXT, "Du skrev inte in nĺgon text. \ -\nSkriv nĺgot och försök sedan igen." -STRING_DOESNOTEXIST, "Filen '%s'\nexisterar inte.\n\n \ -Vill du skapa en ny fil?" -STRING_NOTSAVED, "Filen '%s'\nhar ändrats.\n\n \ -Vill du spara ändringarna?" -STRING_NOTFOUND, "'%s' hittades inte." -STRING_OUT_OF_MEMORY, "Det finns inte tillräckligt med minne för att kunna slutföra \ -den här ĺtgärden. \nAvsluta ett eller flera program för att frigöra mer minne." - -} +/* + * Notepad (Swedish resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * Fixed by Anders Bergh 2005 + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "&Arkiv" + BEGIN + MENUITEM "&Ny...", CMD_NEW + MENUITEM "&Öppna", CMD_OPEN + MENUITEM "&Spara", CMD_SAVE + MENUITEM "Spara so&m...", CMD_SAVE_AS + MENUITEM "Skriv &ut...", CMD_PRINT + MENUITEM "Utskrifts&format...", CMD_PAGE_SETUP + MENUITEM "Skrivar&inställningar...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "&Avsluta", CMD_EXIT + END + POPUP "&Redigera" + BEGIN + MENUITEM "&Ĺngra\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Klipp ut\tCtrl+X", CMD_CUT + MENUITEM "K&opiera\tCtrl+C", CMD_COPY + MENUITEM "K&listra in\tCtrl+V", CMD_PASTE + MENUITEM "&Ta bort\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "Sök...", CMD_SEARCH + MENUITEM "&Sök nästa\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "Markera &allt", CMD_SELECT_ALL + MENUITEM "&Tid/datum\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "&Automatiskt radbyte", CMD_WRAP + END + POPUP "&Hjälp" + BEGIN + MENUITEM "&Innehĺll", CMD_HELP_CONTENTS + MENUITEM "&Sök...", CMD_HELP_SEARCH + MENUITEM "Anvisningar för hjälpen", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "Inf&ormation...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Skrivarinställningar" +{ +LTEXT "&Huvudnot:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Fotnot:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "Marginaler:", 0x144, 10, 43,160, 45 +LTEXT "&Vänsterkant:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Överkant:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Högerkant:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Nederkant:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Avbryt", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Hjälp", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" +STRING_PAGESETUP_FOOTERVALUE, "Sida &s" +STRING_PAGESETUP_LEFTVALUE, "20 mm" +STRING_PAGESETUP_RIGHTVALUE, "20 mm" +STRING_PAGESETUP_TOPVALUE, "25 mm" +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" + +STRING_NOTEPAD, "Anteckningar" +STRING_ERROR, "FEL" +STRING_WARNING, "VARNING" +STRING_INFO, "Information" + +STRING_UNTITLED, "(namnlös)" + +STRING_ALL_FILES, "Alla filer (*.*)" +STRING_TEXT_FILES_TXT, "Textfiler (*.txt)" + +STRING_TOOLARGE, "Filen '%s' är för stor för Anteckningar.\n \ +Använd en annan editor." +STRING_NOTEXT, "Du skrev inte in nĺgon text. \ +\nSkriv nĺgot och försök sedan igen." +STRING_DOESNOTEXIST, "Filen '%s'\nexisterar inte.\n\n \ +Vill du skapa en ny fil?" +STRING_NOTSAVED, "Filen '%s'\nhar ändrats.\n\n \ +Vill du spara ändringarna?" +STRING_NOTFOUND, "'%s' hittades inte." +STRING_OUT_OF_MEMORY, "Det finns inte tillräckligt med minne för att kunna slutföra \ +den här ĺtgärden. \nAvsluta ett eller flera program för att frigöra mer minne." + +} diff --git a/reactos/base/applications/notepad/lang/Th.rc b/reactos/base/applications/notepad/lang/Th.rc index f878835a3da..e3109b391c3 100644 --- a/reactos/base/applications/notepad/lang/Th.rc +++ b/reactos/base/applications/notepad/lang/Th.rc @@ -1,156 +1,156 @@ -/* - * Notepad (Thai Resources) - * - * Copyright 2003 Jon Griffiths - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_THAI, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "áżéÁ" - BEGIN - MENUITEM "ĘĂéҧăËÁč...", CMD_NEW - MENUITEM "ŕ»Ô´...\tCtrl+O", CMD_OPEN - MENUITEM "şŃą·×ˇ\tCtrl+S", CMD_SAVE - MENUITEM "şŃą·×ˇŕ»çą...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "ľÔÁľě", CMD_PRINT - MENUITEM "»ĂŃşáµč§ËąéŇ...", CMD_PAGE_SETUP - MENUITEM "»ĂŃşáµč§ŕ¤Ă×čͧľÔÁľě...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "Í͡", CMD_EXIT - END - POPUP "áˇéä˘" - BEGIN - MENUITEM "ŕĂŐ¡¤×ą\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "µŃ´\tCtrl+X", CMD_CUT - MENUITEM "µŃ´Ĺ͡\tCtrl+C", CMD_COPY - MENUITEM "Çҧ\tCtrl+V", CMD_PASTE - MENUITEM "Ĺş\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "¤éąËŇ\tCtrl+F", CMD_SEARCH - MENUITEM "¤éąËҵčÍä»\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "ŕĹ×͡·Ńé§ËÁ´\tCtrl+A", CMD_SELECT_ALL - MENUITEM "ÇŃą·Őč/\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "ËčÍşĂĂ·Ń´ÂŇÇ", CMD_WRAP - MENUITEM "ĂٻẺ´ŃÇÍѡÉĂ...", CMD_FONT - END - POPUP "ŞčÇÂŕËĹŐÍ" - BEGIN - MENUITEM "ŕą×éÍËŇ", CMD_HELP_CONTENTS - MENUITEM "¤éąËŇ...", CMD_HELP_SEARCH - MENUITEM "ŕˇŐčÂǡѺŞčÇÂŕËĹŐÍ", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "ĂŇÂĹĐŕÍŐ´...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "»ĂŃşáµč§ËąéŇ" -{ -LTEXT "ËŃÇ:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Footer:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "˘ÍşˇĂĐ´ŇÉ:", 0x144, 10, 43,160, 45 -LTEXT "ŁéŇÂ:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "şą:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "˘ÇŇ:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Ĺčҧ:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "µˇĹ§", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "¡ŕĹÔˇ", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "ŞčÇÂŕËĹŐÍ", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "ËąéŇ &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 ÁÁ." /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 ÁÁ." /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 ÁÁ." /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 ÁÁ." /* FIXME */ - -STRING_NOTEPAD, "Notepad" -STRING_ERROR, "¤ÇŇÁ»Ô´" -STRING_WARNING, "¤íҵ×Íą" -STRING_INFO, "ĂŇÂĹĐŕÍŐ´" - -STRING_UNTITLED, "äÁčˇíŇËą´ŞÖčÍ" - -STRING_ALL_FILES, "·ŘˇáżéÁ (*.*)" -STRING_TEXT_FILES_TXT, "áżéÁµíŇĂŇ (*.txt)" - -STRING_TOOLARGE, "áżéÁ '%s' ăË­čŕˇÔąä»" -STRING_NOTEXT, "¤ŘłäÁčă´ŕ˘ŐÂąÍĐäĂ\nˇĂŘłŇĹͧăËÁč" -STRING_DOESNOTEXIST, "äÁčľşáżéÁ '%s' ·ŐčµéͧˇŇĂŕ»Ô´\n¤ŘłµéͧˇŇĂĘĂéҧăËÁčäÁč ?" -STRING_NOTSAVED, "ÁŐˇŇĂŕ»ĹŐčÂąá»Ĺ§ˇŃşŕ͡ĘŇĂ\n\n'%s'\n\n¤ŘłµéͧˇŇúѹ·ÖˇÁŃąËĂ×ÍäÁč ?" -STRING_NOTFOUND, "äÁčľş˘éͤÇŇÁ '%s' ·ŐčµéͧˇŇäéąËŇ" -STRING_OUT_OF_MEMORY, "¤ÇŇÁ¨íŇËÁ´\nˇĂŘłŇĹͧăËÁč" - -} +/* + * Notepad (Thai Resources) + * + * Copyright 2003 Jon Griffiths + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_THAI, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "áżéÁ" + BEGIN + MENUITEM "ĘĂéҧăËÁč...", CMD_NEW + MENUITEM "ŕ»Ô´...\tCtrl+O", CMD_OPEN + MENUITEM "şŃą·×ˇ\tCtrl+S", CMD_SAVE + MENUITEM "şŃą·×ˇŕ»çą...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "ľÔÁľě", CMD_PRINT + MENUITEM "»ĂŃşáµč§ËąéŇ...", CMD_PAGE_SETUP + MENUITEM "»ĂŃşáµč§ŕ¤Ă×čͧľÔÁľě...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "Í͡", CMD_EXIT + END + POPUP "áˇéä˘" + BEGIN + MENUITEM "ŕĂŐ¡¤×ą\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "µŃ´\tCtrl+X", CMD_CUT + MENUITEM "µŃ´Ĺ͡\tCtrl+C", CMD_COPY + MENUITEM "Çҧ\tCtrl+V", CMD_PASTE + MENUITEM "Ĺş\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "¤éąËŇ\tCtrl+F", CMD_SEARCH + MENUITEM "¤éąËҵčÍä»\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "ŕĹ×͡·Ńé§ËÁ´\tCtrl+A", CMD_SELECT_ALL + MENUITEM "ÇŃą·Őč/\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "ËčÍşĂĂ·Ń´ÂŇÇ", CMD_WRAP + MENUITEM "ĂٻẺ´ŃÇÍѡÉĂ...", CMD_FONT + END + POPUP "ŞčÇÂŕËĹŐÍ" + BEGIN + MENUITEM "ŕą×éÍËŇ", CMD_HELP_CONTENTS + MENUITEM "¤éąËŇ...", CMD_HELP_SEARCH + MENUITEM "ŕˇŐčÂǡѺŞčÇÂŕËĹŐÍ", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "ĂŇÂĹĐŕÍŐ´...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "»ĂŃşáµč§ËąéŇ" +{ +LTEXT "ËŃÇ:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Footer:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "˘ÍşˇĂĐ´ŇÉ:", 0x144, 10, 43,160, 45 +LTEXT "ŁéŇÂ:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "şą:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "˘ÇŇ:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Ĺčҧ:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "µˇĹ§", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "¡ŕĹÔˇ", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "ŞčÇÂŕËĹŐÍ", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "ËąéŇ &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 ÁÁ." /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 ÁÁ." /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 ÁÁ." /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 ÁÁ." /* FIXME */ + +STRING_NOTEPAD, "Notepad" +STRING_ERROR, "¤ÇŇÁ»Ô´" +STRING_WARNING, "¤íҵ×Íą" +STRING_INFO, "ĂŇÂĹĐŕÍŐ´" + +STRING_UNTITLED, "äÁčˇíŇËą´ŞÖčÍ" + +STRING_ALL_FILES, "·ŘˇáżéÁ (*.*)" +STRING_TEXT_FILES_TXT, "áżéÁµíŇĂŇ (*.txt)" + +STRING_TOOLARGE, "áżéÁ '%s' ăË­čŕˇÔąä»" +STRING_NOTEXT, "¤ŘłäÁčă´ŕ˘ŐÂąÍĐäĂ\nˇĂŘłŇĹͧăËÁč" +STRING_DOESNOTEXIST, "äÁčľşáżéÁ '%s' ·ŐčµéͧˇŇĂŕ»Ô´\n¤ŘłµéͧˇŇĂĘĂéҧăËÁčäÁč ?" +STRING_NOTSAVED, "ÁŐˇŇĂŕ»ĹŐčÂąá»Ĺ§ˇŃşŕ͡ĘŇĂ\n\n'%s'\n\n¤ŘłµéͧˇŇúѹ·ÖˇÁŃąËĂ×ÍäÁč ?" +STRING_NOTFOUND, "äÁčľş˘éͤÇŇÁ '%s' ·ŐčµéͧˇŇäéąËŇ" +STRING_OUT_OF_MEMORY, "¤ÇŇÁ¨íŇËÁ´\nˇĂŘłŇĹͧăËÁč" + +} diff --git a/reactos/base/applications/notepad/lang/Uk.rc b/reactos/base/applications/notepad/lang/Uk.rc index d1eddd7cd95..f65cb26408d 100644 --- a/reactos/base/applications/notepad/lang/Uk.rc +++ b/reactos/base/applications/notepad/lang/Uk.rc @@ -1,196 +1,196 @@ -/* - * Notepad (Ukrainian resources) - * - * Copyright 2005, 2006 Artem Reznikov - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -{ - POPUP "&Ôŕéë" { - MENUITEM "&Ńňâîđčňč", CMD_NEW - MENUITEM "&Âłäęđčňč...\tCtrl+O", CMD_OPEN - MENUITEM "&Ç&áĺđĺăňč\tCtrl+S", CMD_SAVE - MENUITEM "Çáĺđĺăňč &˙ę...", CMD_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "Ďŕđŕ&ěĺňđč ńňîđłíęč...", CMD_PAGE_SETUP - MENUITEM "Ä&đóę", CMD_PRINT - MENUITEM "Íŕńňđîéęŕ &ďđčíňĺđŕ...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "Â&čőłä", CMD_EXIT - } -POPUP "&Ďđŕâęŕ" { - MENUITEM "&Ńęŕńóâŕňč\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "&Âčđłçŕňč\tCtrl+X", CMD_CUT - MENUITEM "&Ęîďłţâŕňč\tCtrl+C", CMD_COPY - MENUITEM "Âńň&ŕâčňč\tCtrl+V", CMD_PASTE - MENUITEM "Â&čäŕëčňč\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "Ç&íŕéňč...\tCtrl+F", CMD_SEARCH - MENUITEM "Çíŕ&éňč äŕëł\tF3", CMD_SEARCH_NEXT - MENUITEM "&Çŕěłíčňč\tCtrl+H", CMD_REPLACE - MENUITEM "Ďĺđĺé&ňč...\tCtrl+G", CMD_GOTO - MENUITEM SEPARATOR - MENUITEM "Âčäł&ëčňč âńĺ\tCtrl+A", CMD_SELECT_ALL - MENUITEM "&Äŕňŕ é ÷ŕń\tF5", CMD_TIME_DATE - } -POPUP "Ôîđ&ěŕň" { - MENUITEM "&Ďĺđĺíîń ďî ńëîâŕő", CMD_WRAP - MENUITEM "&Řđčôň...", CMD_FONT -} -POPUP "&Âčăë˙ä" { - MENUITEM "&Đ˙äîę ńňŕíó", CMD_STATUSBAR -} -POPUP "&Äîâłäęŕ" { - MENUITEM "&Çěłńň", CMD_HELP_CONTENTS - MENUITEM "&Ďîřóę...", CMD_HELP_SEARCH - MENUITEM "&Help on help", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&Ďđî" CMD_ABOUT - MENUITEM "&Ďđî ďđîăđŕěó", CMD_ABOUT_WINE - } -} - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Ďŕđŕěĺňđč ńňîđłíęč" -{ -LTEXT "Â&ĺđőíłé ęîëîíňčňóë:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "Í&čćíłé ęîëîíňčňóë:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "Ďîë˙", 0x144, 10, 43,160, 45 -LTEXT "&Ëłâĺ:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Âĺđőíş:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Ďđŕâĺ:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Íčćíş:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Ńęŕńóâŕňč", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Äîâłäęŕ", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -/* Dialog `Encoding' */ -DIALOG_ENCODING DIALOG 0, 0, 256, 44 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | - WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Ęîäóâŕíí˙" -{ -COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP -LTEXT "Ęîäóâŕíí˙:",0x155,5,2,41,12 -COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -LTEXT "Đîçđčâč đ˙äęłâ:",0x156,5,20,41,12 -} - -/* Dialog 'Go To' */ -DIALOG_GOTO DIALOG 0,0,165,50 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Ďĺđĺőłä äî đ˙äęŕ" -{ -EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Íîěĺđ đ˙äęŕ:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER -DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP -PUSHBUTTON "Ńęŕńóâŕňč", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "Ďđî Áëîęíîň ReactOS" -FONT 8, "Tahoma" -BEGIN - CONTROL "Áëîęíîň ReactOS v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Çŕęđčňč",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Ńňîđłíęŕ &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 ěě" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 ěě" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 ěě" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 ěě" /* FIXME */ - -STRING_NOTEPAD, "Áëîęíîň" -STRING_ERROR, "ĎÎĚČËĘŔ" -STRING_WARNING, "ÓÂŔĂŔ" -STRING_INFO, "˛íôîđěŕöł˙" - -STRING_UNTITLED, "(áĺç çŕăîëîâęŕ)" - -STRING_ALL_FILES, "Óńł ôŕéëč (*.*)" -STRING_TEXT_FILES_TXT, "Ňĺęńňîâł ôŕéëč (*.txt)" - -STRING_TOOLARGE, "Ôŕéë '%s' çŕâĺëčęčé äë˙ áëîęíîňŕ.\n \ -Áóäü ëŕńęŕ âčęîđčńňŕéňĺ łířčé đĺäŕęňîđ." -STRING_NOTEXT, "Âč íĺ ââĺëč íł˙ęîăî ňĺęńňó. \ -\nÁóäü ëŕńęŕ ââĺäłňü ůî-íĺáóäü ł ńďđîáóéňĺ ůĺ đŕç" -STRING_DOESNOTEXIST, "Ôŕéë '%s'\níĺ łńíóş\n\n \ -Őî÷ĺňĺ ńňâîđčňč íîâčé ôŕéë ?" -STRING_NOTSAVED, "Ôŕéë '%s'\náóâ çěłíĺíčé\n\n \ -Őî÷ĺňĺ çáĺđĺăňč çěłíč ?" -STRING_NOTFOUND, "'%s' can not be found." -STRING_OUT_OF_MEMORY, "Íĺäîńňŕňíüî ďŕě'˙ňł äë˙ âčęîíŕíí˙ îďĺđŕöłż.\ -\nÇŕęđčéňĺ îäčí ŕáî äĺęłëüęŕ äîäŕňęłâ ł ďîâňîđłňü ńďđîáó." -STRING_CANNOTFIND "Íĺ ěîćó çíŕéňč '%s'" -STRING_ANSI, "ANSI" -STRING_UNICODE, "Ţíłęîä" -STRING_UNICODE_BE, "Ţíłęîä (big endian)" -STRING_UTF8, "UTF-8" -STRING_CRLF, "Windows" -STRING_LF, "Unix" -STRING_CR, "Mac" -} +/* + * Notepad (Ukrainian resources) + * + * Copyright 2005, 2006 Artem Reznikov + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +{ + POPUP "&Ôŕéë" { + MENUITEM "&Ńňâîđčňč", CMD_NEW + MENUITEM "&Âłäęđčňč...\tCtrl+O", CMD_OPEN + MENUITEM "&Ç&áĺđĺăňč\tCtrl+S", CMD_SAVE + MENUITEM "Çáĺđĺăňč &˙ę...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Ďŕđŕ&ěĺňđč ńňîđłíęč...", CMD_PAGE_SETUP + MENUITEM "Ä&đóę", CMD_PRINT + MENUITEM "Íŕńňđîéęŕ &ďđčíňĺđŕ...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "Â&čőłä", CMD_EXIT + } +POPUP "&Ďđŕâęŕ" { + MENUITEM "&Ńęŕńóâŕňč\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "&Âčđłçŕňč\tCtrl+X", CMD_CUT + MENUITEM "&Ęîďłţâŕňč\tCtrl+C", CMD_COPY + MENUITEM "Âńň&ŕâčňč\tCtrl+V", CMD_PASTE + MENUITEM "Â&čäŕëčňč\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "Ç&íŕéňč...\tCtrl+F", CMD_SEARCH + MENUITEM "Çíŕ&éňč äŕëł\tF3", CMD_SEARCH_NEXT + MENUITEM "&Çŕěłíčňč\tCtrl+H", CMD_REPLACE + MENUITEM "Ďĺđĺé&ňč...\tCtrl+G", CMD_GOTO + MENUITEM SEPARATOR + MENUITEM "Âčäł&ëčňč âńĺ\tCtrl+A", CMD_SELECT_ALL + MENUITEM "&Äŕňŕ é ÷ŕń\tF5", CMD_TIME_DATE + } +POPUP "Ôîđ&ěŕň" { + MENUITEM "&Ďĺđĺíîń ďî ńëîâŕő", CMD_WRAP + MENUITEM "&Řđčôň...", CMD_FONT +} +POPUP "&Âčăë˙ä" { + MENUITEM "&Đ˙äîę ńňŕíó", CMD_STATUSBAR +} +POPUP "&Äîâłäęŕ" { + MENUITEM "&Çěłńň", CMD_HELP_CONTENTS + MENUITEM "&Ďîřóę...", CMD_HELP_SEARCH + MENUITEM "&Help on help", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&Ďđî" CMD_ABOUT + MENUITEM "&Ďđî ďđîăđŕěó", CMD_ABOUT_WINE + } +} + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Ďŕđŕěĺňđč ńňîđłíęč" +{ +LTEXT "Â&ĺđőíłé ęîëîíňčňóë:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "Í&čćíłé ęîëîíňčňóë:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "Ďîë˙", 0x144, 10, 43,160, 45 +LTEXT "&Ëłâĺ:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Âĺđőíş:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Ďđŕâĺ:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Íčćíş:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "OK", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Ńęŕńóâŕňč", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Äîâłäęŕ", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +/* Dialog `Encoding' */ +DIALOG_ENCODING DIALOG 0, 0, 256, 44 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | + WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Ęîäóâŕíí˙" +{ +COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP +LTEXT "Ęîäóâŕíí˙:",0x155,5,2,41,12 +COMBOBOX ID_EOLN,54,18,156,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +LTEXT "Đîçđčâč đ˙äęłâ:",0x156,5,20,41,12 +} + +/* Dialog 'Go To' */ +DIALOG_GOTO DIALOG 0,0,165,50 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Ďĺđĺőłä äî đ˙äęŕ" +{ +EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "Íîěĺđ đ˙äęŕ:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER +DEFPUSHBUTTON "OK", IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP +PUSHBUTTON "Ńęŕńóâŕňč", IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Ďđî Áëîęíîň ReactOS" +FONT 8, "Tahoma" +BEGIN + CONTROL "Áëîęíîň ReactOS v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Çŕęđčňč",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Ńňîđłíęŕ &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 ěě" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 ěě" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 ěě" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 ěě" /* FIXME */ + +STRING_NOTEPAD, "Áëîęíîň" +STRING_ERROR, "ĎÎĚČËĘŔ" +STRING_WARNING, "ÓÂŔĂŔ" +STRING_INFO, "˛íôîđěŕöł˙" + +STRING_UNTITLED, "(áĺç çŕăîëîâęŕ)" + +STRING_ALL_FILES, "Óńł ôŕéëč (*.*)" +STRING_TEXT_FILES_TXT, "Ňĺęńňîâł ôŕéëč (*.txt)" + +STRING_TOOLARGE, "Ôŕéë '%s' çŕâĺëčęčé äë˙ áëîęíîňŕ.\n \ +Áóäü ëŕńęŕ âčęîđčńňŕéňĺ łířčé đĺäŕęňîđ." +STRING_NOTEXT, "Âč íĺ ââĺëč íł˙ęîăî ňĺęńňó. \ +\nÁóäü ëŕńęŕ ââĺäłňü ůî-íĺáóäü ł ńďđîáóéňĺ ůĺ đŕç" +STRING_DOESNOTEXIST, "Ôŕéë '%s'\níĺ łńíóş\n\n \ +Őî÷ĺňĺ ńňâîđčňč íîâčé ôŕéë ?" +STRING_NOTSAVED, "Ôŕéë '%s'\náóâ çěłíĺíčé\n\n \ +Őî÷ĺňĺ çáĺđĺăňč çěłíč ?" +STRING_NOTFOUND, "'%s' can not be found." +STRING_OUT_OF_MEMORY, "Íĺäîńňŕňíüî ďŕě'˙ňł äë˙ âčęîíŕíí˙ îďĺđŕöłż.\ +\nÇŕęđčéňĺ îäčí ŕáî äĺęłëüęŕ äîäŕňęłâ ł ďîâňîđłňü ńďđîáó." +STRING_CANNOTFIND "Íĺ ěîćó çíŕéňč '%s'" +STRING_ANSI, "ANSI" +STRING_UNICODE, "Ţíłęîä" +STRING_UNICODE_BE, "Ţíłęîä (big endian)" +STRING_UTF8, "UTF-8" +STRING_CRLF, "Windows" +STRING_LF, "Unix" +STRING_CR, "Mac" +} diff --git a/reactos/base/applications/notepad/lang/Wa.rc b/reactos/base/applications/notepad/lang/Wa.rc index e4efe8ba530..11c1f0c7bae 100644 --- a/reactos/base/applications/notepad/lang/Wa.rc +++ b/reactos/base/applications/notepad/lang/Wa.rc @@ -1,161 +1,161 @@ -/* - * Notepad (Walon resources) - * - * Copyright 1997,98 Marcel Baur - * Proofread 1998 by David Lee Lambert - * Copyright 2002 Sylvain Petreolle - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -LANGUAGE LANG_WALON, SUBLANG_NEUTRAL - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -{ - POPUP "&Fitchî" { - MENUITEM "&Novea...", CMD_NEW - MENUITEM "&Drovî", CMD_OPEN - MENUITEM "&Schaper", CMD_SAVE - MENUITEM "Schaper čt r&lomer...", CMD_SAVE_AS - MENUITEM "&Rexhe", CMD_PRINT - MENUITEM "Arrandjmint del &Pĺdje...", CMD_PAGE_SETUP - MENUITEM "&Apontiaedje del scrirece...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "Moussî &Foű", CMD_EXIT - } -POPUP "&Candjî" { - MENUITEM "&Disfé\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "Cô&per\tCtrl+X", CMD_CUT - MENUITEM "&Copyî\tCtrl+C", CMD_COPY - MENUITEM "C&laper\tCtrl+V", CMD_PASTE - MENUITEM "&Rafacer\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "Cwerî...", CMD_SEARCH - MENUITEM "&Shűvant\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "&Tchwezi totafwait", CMD_SELECT_ALL - MENUITEM "&Eure/Date\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "Côper les ro&yes", CMD_WRAP - } -POPUP "&Aide" { - MENUITEM "Ĺ&dvins", CMD_HELP_CONTENTS - MENUITEM "C&werî...", CMD_HELP_SEARCH - MENUITEM "&Aide so l' Aide", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "&Informĺcion...", CMD_ABOUT_WINE - } -} - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 8, "MS Shell Dlg" -CAPTION "Arindjmint del Pĺdje" -{ -LTEXT "&Tite:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "&Pînote:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "&Mardjes:", 0x144, 10, 43,160, 45 -LTEXT "&Hintche:", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Copete:", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Droete:", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "&Bas:", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "I Va", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "Rinoncî", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "&Aide", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Pĺdje &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "Notepad" -STRING_ERROR, "AROKE" -STRING_WARNING, "ADVERTIXHMINT" -STRING_INFO, "Informĺcion" - -STRING_UNTITLED, "(sin tite)" - -STRING_ALL_FILES, "Tos les fitchîs (*.*)" -STRING_TEXT_FILES_TXT, "Fitchîs tekse (*.txt)" - -STRING_TOOLARGE, "Li fitchî '%s' est trop gros pol notepad.\n \ -Eployoz on ôte aspougneu di tekse." -STRING_NOTEXT, "Vos n' avoz rén sicrît. \ -\nTapez ene sacwe čt rasayez" -STRING_DOESNOTEXIST, "File '%s'\ndoes not exist\n\n \ -Do you want to create a new file ?" -STRING_NOTSAVED, "Li fitchî '%s'\na candjî\n\n \ -El voloz schaper ?" -STRING_NOTFOUND, "'%s' pout nén esse trové." -STRING_OUT_OF_MEMORY, "Li memwere est plinne. \n\ -Cloyoz on programe ou pus po monter li memwere libe." - -} - - +/* + * Notepad (Walon resources) + * + * Copyright 1997,98 Marcel Baur + * Proofread 1998 by David Lee Lambert + * Copyright 2002 Sylvain Petreolle + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +LANGUAGE LANG_WALON, SUBLANG_NEUTRAL + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +{ + POPUP "&Fitchî" { + MENUITEM "&Novea...", CMD_NEW + MENUITEM "&Drovî", CMD_OPEN + MENUITEM "&Schaper", CMD_SAVE + MENUITEM "Schaper čt r&lomer...", CMD_SAVE_AS + MENUITEM "&Rexhe", CMD_PRINT + MENUITEM "Arrandjmint del &Pĺdje...", CMD_PAGE_SETUP + MENUITEM "&Apontiaedje del scrirece...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "Moussî &Foű", CMD_EXIT + } +POPUP "&Candjî" { + MENUITEM "&Disfé\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Cô&per\tCtrl+X", CMD_CUT + MENUITEM "&Copyî\tCtrl+C", CMD_COPY + MENUITEM "C&laper\tCtrl+V", CMD_PASTE + MENUITEM "&Rafacer\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "Cwerî...", CMD_SEARCH + MENUITEM "&Shűvant\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "&Tchwezi totafwait", CMD_SELECT_ALL + MENUITEM "&Eure/Date\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "Côper les ro&yes", CMD_WRAP + } +POPUP "&Aide" { + MENUITEM "Ĺ&dvins", CMD_HELP_CONTENTS + MENUITEM "C&werî...", CMD_HELP_SEARCH + MENUITEM "&Aide so l' Aide", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "&Informĺcion...", CMD_ABOUT_WINE + } +} + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +CAPTION "Arindjmint del Pĺdje" +{ +LTEXT "&Tite:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "&Pînote:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "&Mardjes:", 0x144, 10, 43,160, 45 +LTEXT "&Hintche:", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Copete:", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Droete:", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "&Bas:", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "I Va", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "Rinoncî", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "&Aide", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Pĺdje &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "Notepad" +STRING_ERROR, "AROKE" +STRING_WARNING, "ADVERTIXHMINT" +STRING_INFO, "Informĺcion" + +STRING_UNTITLED, "(sin tite)" + +STRING_ALL_FILES, "Tos les fitchîs (*.*)" +STRING_TEXT_FILES_TXT, "Fitchîs tekse (*.txt)" + +STRING_TOOLARGE, "Li fitchî '%s' est trop gros pol notepad.\n \ +Eployoz on ôte aspougneu di tekse." +STRING_NOTEXT, "Vos n' avoz rén sicrît. \ +\nTapez ene sacwe čt rasayez" +STRING_DOESNOTEXIST, "File '%s'\ndoes not exist\n\n \ +Do you want to create a new file ?" +STRING_NOTSAVED, "Li fitchî '%s'\na candjî\n\n \ +El voloz schaper ?" +STRING_NOTFOUND, "'%s' pout nén esse trové." +STRING_OUT_OF_MEMORY, "Li memwere est plinne. \n\ +Cloyoz on programe ou pus po monter li memwere libe." + +} + + diff --git a/reactos/base/applications/notepad/lang/Zh.rc b/reactos/base/applications/notepad/lang/Zh.rc index c323ea48643..b6671a3b4ce 100644 --- a/reactos/base/applications/notepad/lang/Zh.rc +++ b/reactos/base/applications/notepad/lang/Zh.rc @@ -1,160 +1,160 @@ -/* - * Notepad (Simplified Chinese resources) - * - * Copyright 2002 liuspider - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED - -ID_ACCEL ACCELERATORS -{ - "^A", CMD_SELECT_ALL - "^C", CMD_COPY - "^F", CMD_SEARCH - "^G", CMD_GOTO - "H", CMD_REPLACE, VIRTKEY, CONTROL - "^O", CMD_OPEN - "^S", CMD_SAVE - "^V", CMD_PASTE - "^X", CMD_CUT - "^Z", CMD_UNDO - VK_F3, CMD_SEARCH_NEXT, VIRTKEY - VK_F5, CMD_TIME_DATE, VIRTKEY -} - -MAIN_MENU MENU -BEGIN - POPUP "ÎÄĽţٍ&FŁ©" - BEGIN - MENUITEM "Đ½¨Ł¨&NŁ©...", CMD_NEW - MENUITEM "´ňżŞŁ¨&OŁ©", CMD_OPEN - MENUITEM "±Ł´ćٍ&SŁ©", CMD_SAVE - MENUITEM "Áí´ćÎŞ(&A)...", CMD_SAVE_AS - MENUITEM "´ňӎٍ&PŁ©", CMD_PRINT - MENUITEM "ŇłĂćÉčÖĂŁ¨&TŁ©...", CMD_PAGE_SETUP - MENUITEM "´ňÓˇÉčÖĂŁ¨&RŁ©...", CMD_PRINTER_SETUP - MENUITEM SEPARATOR - MENUITEM "ÍËłöٍ&EŁ©", CMD_EXIT - END - POPUP "±ŕĽ­Ł¨&EŁ©" - BEGIN - MENUITEM "ł·Ďűٍ&UŁ©\tCtrl+Z", CMD_UNDO - MENUITEM SEPARATOR - MENUITEM "ĽôÇĐŁ¨&TŁ©\tCtrl+X", CMD_CUT - MENUITEM "¸´ÖĆŁ¨&CŁ©\tCtrl+C", CMD_COPY - MENUITEM "ŐłĚůٍ&PŁ©\tCtrl+V", CMD_PASTE - MENUITEM "Éľłýٍ&DŁ©\tDel", CMD_DELETE - MENUITEM SEPARATOR - MENUITEM "ËŃË÷ٍ&SŁ©", CMD_SEARCH - MENUITEM "ËŃË÷ĎÂŇ»¸öٍ&SŁ©\tF3", CMD_SEARCH_NEXT - MENUITEM SEPARATOR - MENUITEM "ȫюٍ&AŁ©", CMD_SELECT_ALL - MENUITEM "˛ĺČëČŐĆÚˇ˘Ę±Ľäٍ&TŁ©\tF5", CMD_TIME_DATE - MENUITEM SEPARATOR - MENUITEM "×Ô¶Ż»»ĐĐŁ¨&WŁ©", CMD_WRAP - END - POPUP "°ďÖúٍ&HŁ©" - BEGIN - MENUITEM "ÄÚČÝŁ¨&CŁ©", CMD_HELP_CONTENTS - MENUITEM "ËŃË÷ٍ&SŁ©...", CMD_HELP_SEARCH - MENUITEM "ČçşÎĘąÓðďÖúٍ&HŁ©", CMD_HELP_ON_HELP - MENUITEM SEPARATOR - MENUITEM "&About" CMD_ABOUT - MENUITEM "×ĘÁĎĐĹĎ˘Ł¨&OŁ©...", CMD_ABOUT_WINE - END -END - -/* Dialog `Page setup' */ - -DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 -LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -FONT 10, "MS Shell Dlg" -CAPTION "ŇłĂćÉčÖĂ" -{ -LTEXT "ŇłĂĽŁ¨&HŁ©:", 0x140, 10, 07, 40, 15 -EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP -LTEXT "˝Ĺ×˘Ł¨&FŁ©:", 0x142, 10, 24, 40, 15 -EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP - -GROUPBOX "±ßÔµżŐ°×ٍ&MŁ©Łş", 0x144, 10, 43,160, 45 -LTEXT "×óٍ&LŁ©Łş", 0x145, 20, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "ÉĎŁ¨&TŁ©Łş", 0x148, 20, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "ÓŇŁ¨&RŁ©Łş", 0x14B, 100, 55, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "ĎÂŁ¨&BŁ©Łş", 0x14E,100, 73, 30, 10, WS_CHILD -EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP - -DEFPUSHBUTTON "Č·¶¨", 0x151, 180, 3, 40, 15, WS_TABSTOP -PUSHBUTTON "ȡĎű", 0x152, 180, 21, 40, 15, WS_TABSTOP -PUSHBUTTON "°ďÖúٍ&Ł©", 0x153, 180, 39, 40, 15, WS_TABSTOP -} - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About ReactOS Notepad" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", - -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 - CONTROL " ", - -1,"Static",0x50000000,8,48,272,11 - DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP - ICON IDI_NPICON,-1,12,9,20,30 - EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | - ES_READONLY | WS_VSCROLL -END - -STRINGTABLE DISCARDABLE -BEGIN - STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -STRINGTABLE DISCARDABLE -{ -STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ -STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ -STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ -STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ -STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ - -STRING_NOTEPAD, "ĽÇʱľ" -STRING_ERROR, "´íÎó" -STRING_WARNING, "ľŻ¸ć" -STRING_INFO, "ĐĹϢ" - -STRING_UNTITLED, "Ł¨Î´ĂüĂűŁ©" - -STRING_ALL_FILES, "ËůÓĐÎÄĽţ (*.*)" -STRING_TEXT_FILES_TXT, "ÎıľÎÄĽţ (*.txt)" - -STRING_TOOLARGE, "ĽÇʱľ˛»ÄÜ´ňżŞ '%s' ŐâĂ´´óµÄÎÄĽţˇŁ\n \ -ÇëĘąÓñđµÄ±ŕĽ­Ć÷ˇŁ" -STRING_NOTEXT, "ÄúĂ»ÓĐĘäČëČÎşÎÎıľˇŁ \ -\nÇëĘäČëһЩÔŮĘÔ" -STRING_DOESNOTEXIST, "ÎÄĽţ '%s'\n˛»´ćÔÚ\n\n \ -ÄúĎëĐ½¨Ň»¸öÎÄĽţÂđŁż" -STRING_NOTSAVED, "ÎÄĽţ '%s'\nŐýÎÄŇѸü¸Ä\n\n \ -ĘÇ·ń±Ł´ć¸ü¸ÄŁż" -STRING_NOTFOUND, "ŐҲ»µ˝ÎÄĽţ '%s'" -STRING_OUT_OF_MEMORY, "Ă»ÓĐ×ăą»µÄÄÚ´ćżÉŇÔÓĂŔ´ÍęłÉ´ËĎîČÎÎńˇŁ \ -\nÇëąŘ±ŐһЩłĚĐňĘ©·ĹÄÚ´ćşóÔŮĘÔˇŁ" - -} +/* + * Notepad (Simplified Chinese resources) + * + * Copyright 2002 liuspider + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED + +ID_ACCEL ACCELERATORS +{ + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^F", CMD_SEARCH + "^G", CMD_GOTO + "H", CMD_REPLACE, VIRTKEY, CONTROL + "^O", CMD_OPEN + "^S", CMD_SAVE + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + VK_F3, CMD_SEARCH_NEXT, VIRTKEY + VK_F5, CMD_TIME_DATE, VIRTKEY +} + +MAIN_MENU MENU +BEGIN + POPUP "ÎÄĽţٍ&FŁ©" + BEGIN + MENUITEM "Đ½¨Ł¨&NŁ©...", CMD_NEW + MENUITEM "´ňżŞŁ¨&OŁ©", CMD_OPEN + MENUITEM "±Ł´ćٍ&SŁ©", CMD_SAVE + MENUITEM "Áí´ćÎŞ(&A)...", CMD_SAVE_AS + MENUITEM "´ňӎٍ&PŁ©", CMD_PRINT + MENUITEM "ŇłĂćÉčÖĂŁ¨&TŁ©...", CMD_PAGE_SETUP + MENUITEM "´ňÓˇÉčÖĂŁ¨&RŁ©...", CMD_PRINTER_SETUP + MENUITEM SEPARATOR + MENUITEM "ÍËłöٍ&EŁ©", CMD_EXIT + END + POPUP "±ŕĽ­Ł¨&EŁ©" + BEGIN + MENUITEM "ł·Ďűٍ&UŁ©\tCtrl+Z", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "ĽôÇĐŁ¨&TŁ©\tCtrl+X", CMD_CUT + MENUITEM "¸´ÖĆŁ¨&CŁ©\tCtrl+C", CMD_COPY + MENUITEM "ŐłĚůٍ&PŁ©\tCtrl+V", CMD_PASTE + MENUITEM "Éľłýٍ&DŁ©\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "ËŃË÷ٍ&SŁ©", CMD_SEARCH + MENUITEM "ËŃË÷ĎÂŇ»¸öٍ&SŁ©\tF3", CMD_SEARCH_NEXT + MENUITEM SEPARATOR + MENUITEM "ȫюٍ&AŁ©", CMD_SELECT_ALL + MENUITEM "˛ĺČëČŐĆÚˇ˘Ę±Ľäٍ&TŁ©\tF5", CMD_TIME_DATE + MENUITEM SEPARATOR + MENUITEM "×Ô¶Ż»»ĐĐŁ¨&WŁ©", CMD_WRAP + END + POPUP "°ďÖúٍ&HŁ©" + BEGIN + MENUITEM "ÄÚČÝŁ¨&CŁ©", CMD_HELP_CONTENTS + MENUITEM "ËŃË÷ٍ&SŁ©...", CMD_HELP_SEARCH + MENUITEM "ČçşÎĘąÓðďÖúٍ&HŁ©", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About" CMD_ABOUT + MENUITEM "×ĘÁĎĐĹĎ˘Ł¨&OŁ©...", CMD_ABOUT_WINE + END +END + +/* Dialog `Page setup' */ + +DIALOG_PAGESETUP DIALOG 0, 0, 225, 95 +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +FONT 10, "MS Shell Dlg" +CAPTION "ŇłĂćÉčÖĂ" +{ +LTEXT "ŇłĂĽŁ¨&HŁ©:", 0x140, 10, 07, 40, 15 +EDITTEXT 0x141, 60, 05,110, 12, WS_BORDER | WS_TABSTOP +LTEXT "˝Ĺ×˘Ł¨&FŁ©:", 0x142, 10, 24, 40, 15 +EDITTEXT 0x143, 60, 22,110, 12, WS_BORDER | WS_TABSTOP + +GROUPBOX "±ßÔµżŐ°×ٍ&MŁ©Łş", 0x144, 10, 43,160, 45 +LTEXT "×óٍ&LŁ©Łş", 0x145, 20, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_LEFTVALUE,*/ 0x147, 50, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "ÉĎŁ¨&TŁ©Łş", 0x148, 20, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_TOPVALUE,*/ 0x14A, 50, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "ÓŇŁ¨&RŁ©Łş", 0x14B, 100, 55, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_RIGHTVALUE,*/ 0x14D, 130, 55, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP +LTEXT "ĎÂŁ¨&BŁ©Łş", 0x14E,100, 73, 30, 10, WS_CHILD +EDITTEXT /*STRING_PAGESETUP_BOTTOMVALUE,*/ 0x150, 130, 73, 35, 11, WS_CHILD | WS_BORDER | WS_TABSTOP + +DEFPUSHBUTTON "Č·¶¨", 0x151, 180, 3, 40, 15, WS_TABSTOP +PUSHBUTTON "ȡĎű", 0x152, 180, 21, 40, 15, WS_TABSTOP +PUSHBUTTON "°ďÖúٍ&Ł©", 0x153, 180, 39, 40, 15, WS_TABSTOP +} + +IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,284,170 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Notepad" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "ReactOS Notepad v1.0\r\nCopyright 1997,98 Marcel Baur \r\nCopyright 2000 Mike McCormack \r\nCopyright 2002 Sylvain Petreolle \r\nCopyright 2002 Andriy Palamarchuk\r\n ", + -1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,46,7,232,39 + CONTROL " ", + -1,"Static",0x50000000,8,48,272,11 + DEFPUSHBUTTON "Close",IDOK,114,149,44,15,WS_GROUP + ICON IDI_NPICON,-1,12,9,20,30 + EDITTEXT IDC_LICENSE,8,64,272,81,ES_MULTILINE | + ES_READONLY | WS_VSCROLL +END + +STRINGTABLE DISCARDABLE +BEGIN + STRING_LICENSE, "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +{ +STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */ +STRING_PAGESETUP_FOOTERVALUE, "Page &s" /* FIXME */ +STRING_PAGESETUP_LEFTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_RIGHTVALUE, "20 mm" /* FIXME */ +STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ +STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ + +STRING_NOTEPAD, "ĽÇʱľ" +STRING_ERROR, "´íÎó" +STRING_WARNING, "ľŻ¸ć" +STRING_INFO, "ĐĹϢ" + +STRING_UNTITLED, "Ł¨Î´ĂüĂűŁ©" + +STRING_ALL_FILES, "ËůÓĐÎÄĽţ (*.*)" +STRING_TEXT_FILES_TXT, "ÎıľÎÄĽţ (*.txt)" + +STRING_TOOLARGE, "ĽÇʱľ˛»ÄÜ´ňżŞ '%s' ŐâĂ´´óµÄÎÄĽţˇŁ\n \ +ÇëĘąÓñđµÄ±ŕĽ­Ć÷ˇŁ" +STRING_NOTEXT, "ÄúĂ»ÓĐĘäČëČÎşÎÎıľˇŁ \ +\nÇëĘäČëһЩÔŮĘÔ" +STRING_DOESNOTEXIST, "ÎÄĽţ '%s'\n˛»´ćÔÚ\n\n \ +ÄúĎëĐ½¨Ň»¸öÎÄĽţÂđŁż" +STRING_NOTSAVED, "ÎÄĽţ '%s'\nŐýÎÄŇѸü¸Ä\n\n \ +ĘÇ·ń±Ł´ć¸ü¸ÄŁż" +STRING_NOTFOUND, "ŐҲ»µ˝ÎÄĽţ '%s'" +STRING_OUT_OF_MEMORY, "Ă»ÓĐ×ăą»µÄÄÚ´ćżÉŇÔÓĂŔ´ÍęłÉ´ËĎîČÎÎńˇŁ \ +\nÇëąŘ±ŐһЩłĚĐňĘ©·ĹÄÚ´ćşóÔŮĘÔˇŁ" + +} From 4c2f6e8647a1f99e9f3144fc8424545068cd1d42 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Mon, 25 Sep 2006 20:12:43 +0000 Subject: [PATCH 344/488] implement PEN_GetObject, we can now get pen from GetopjectType. and manger pass some new wine test svn path=/trunk/; revision=24270 --- reactos/subsystems/win32/win32k/include/pen.h | 2 ++ reactos/subsystems/win32/win32k/objects/dc.c | 6 +++--- reactos/subsystems/win32/win32k/objects/pen.c | 19 ++++++++++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/pen.h b/reactos/subsystems/win32/win32k/include/pen.h index e8c2a51c2de..01cb035a686 100644 --- a/reactos/subsystems/win32/win32k/include/pen.h +++ b/reactos/subsystems/win32/win32k/include/pen.h @@ -11,4 +11,6 @@ #define PENOBJ_LockPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj(GdiHandleTable, (HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN)) #define PENOBJ_UnlockPen(pPenObj) GDIOBJ_UnlockObjByPtr(GdiHandleTable, pPenObj) +INT STDCALL PEN_GetObject(PGDIBRUSHOBJ hPen, INT Count, PLOGPEN Buffer); + #endif diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index 72c9b51a6fb..cb7b0278103 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -1734,11 +1734,11 @@ IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer) ObjectType = GDIOBJ_GetObjectType(Handle); switch (ObjectType) { -#if 0 + case GDI_OBJECT_TYPE_PEN: - Result = PEN_GetObject((PENOBJ *) GdiObject, Count, Buffer); + Result = PEN_GetObject((PGDIBRUSHOBJ) GdiObject, Count, (PLOGPEN) Buffer); // IntGdiCreatePenIndirect break; -#endif + case GDI_OBJECT_TYPE_BRUSH: Result = BRUSH_GetObject((PGDIBRUSHOBJ ) GdiObject, Count, (LPLOGBRUSH)Buffer); break; diff --git a/reactos/subsystems/win32/win32k/objects/pen.c b/reactos/subsystems/win32/win32k/objects/pen.c index 7ba325fbefb..795b94086cb 100644 --- a/reactos/subsystems/win32/win32k/objects/pen.c +++ b/reactos/subsystems/win32/win32k/objects/pen.c @@ -84,7 +84,7 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen) break; default: - DPRINT1("FIXME: IntGdiCreatePenIndirect is UNIMPLEMENTED\n"); + DPRINT1("FIXME: IntGdiCreatePenIndirect is UNIMPLEMENTED pen %x\n",LogPen->lopnStyle); } PENOBJ_UnlockPen(PenObject); @@ -92,6 +92,23 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen) return hPen; } +INT STDCALL +PEN_GetObject(PGDIBRUSHOBJ PenObject, INT Count, PLOGPEN Buffer) +{ + + LOGPEN LogPen; + + if( Buffer == NULL ) return sizeof(LOGPEN); + + LogPen.lopnWidth = PenObject->ptPenWidth; + LogPen.lopnStyle = PenObject->ulPenStyle; + LogPen.lopnColor = PenObject->BrushAttr.lbColor; + memcpy(Buffer, &LogPen, Count); + + return Count; + +} + /* PUBLIC FUNCTIONS ***********************************************************/ HPEN STDCALL From 56c76b3069f03043c242c633e769a09a87e2bf5d Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Mon, 25 Sep 2006 21:28:09 +0000 Subject: [PATCH 345/488] NtGdiSetViewportExtEx fix a bsd by moving in some value to seh last we can run gdi32_winetest mapping without bsd svn path=/trunk/; revision=24271 --- reactos/subsystems/win32/win32k/objects/coord.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/coord.c b/reactos/subsystems/win32/win32k/objects/coord.c index ea37b6a4b40..1b91251e947 100644 --- a/reactos/subsystems/win32/win32k/objects/coord.c +++ b/reactos/subsystems/win32/win32k/objects/coord.c @@ -795,6 +795,12 @@ NtGdiSetViewportExtEx(HDC hDC, 1); Size->cx = dc->vportExtX; Size->cy = dc->vportExtY; + + dc->vportExtX = XExtent; + dc->vportExtY = YExtent; + + if (dc->w.MapMode == MM_ISOTROPIC) + IntFixIsotropicMapping(dc); } _SEH_HANDLE { @@ -810,11 +816,7 @@ NtGdiSetViewportExtEx(HDC hDC, } } - dc->vportExtX = XExtent; - dc->vportExtY = YExtent; - - if (dc->w.MapMode == MM_ISOTROPIC) - IntFixIsotropicMapping(dc); + DC_UpdateXforms(dc); DC_UnlockDc(dc); From b3f30cb1004031618dc297c524b10d8ecdb33d55 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Mon, 25 Sep 2006 23:26:08 +0000 Subject: [PATCH 346/488] restore files mem.c and memgen.c restore no i386 arch define in rbuild do not remove it, it is for build on no i386 platform the was accident delete in r23830 svn path=/trunk/; revision=24272 --- reactos/lib/rtl/mem.c | 173 +++++++++++++++++++++++++++++++++++++ reactos/lib/rtl/memgen.c | 77 +++++++++++++++++ reactos/lib/rtl/rtl.rbuild | 6 ++ 3 files changed, 256 insertions(+) create mode 100644 reactos/lib/rtl/mem.c create mode 100644 reactos/lib/rtl/memgen.c diff --git a/reactos/lib/rtl/mem.c b/reactos/lib/rtl/mem.c new file mode 100644 index 00000000000..e5152b5dafd --- /dev/null +++ b/reactos/lib/rtl/mem.c @@ -0,0 +1,173 @@ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/rtl/mem.c + * PURPOSE: Memory functions + * PROGRAMMER: David Welch (welch@mcmail.com) + */ + +/* INCLUDES *****************************************************************/ + +#include + +#define NDEBUG +#include + + +/* FUNCTIONS *****************************************************************/ + +/****************************************************************************** + * RtlCompareMemory [NTDLL.@] + * + * Compare one block of memory with another + * + * PARAMS + * Source1 [I] Source block + * Source2 [I] Block to compare to Source1 + * Length [I] Number of bytes to fill + * + * RETURNS + * The length of the first byte at which Source1 and Source2 differ, or Length + * if they are the same. + * + * @implemented + */ +SIZE_T NTAPI +RtlCompareMemory(IN const VOID *Source1, + IN const VOID *Source2, + IN SIZE_T Length) +{ + SIZE_T i; + for(i=0; (i 0) + { + *Dest = Fill; + Dest++; + Count--; + } +} + + +#undef RtlMoveMemory +/* + * @implemented + */ +VOID +NTAPI +RtlMoveMemory ( + PVOID Destination, + CONST VOID * Source, + ULONG Length +) +{ + memmove ( + Destination, + Source, + Length + ); +} + +/* +* @implemented +*/ +VOID +FASTCALL +RtlPrefetchMemoryNonTemporal( + IN PVOID Source, + IN SIZE_T Length + ) +{ + /* By nature of prefetch, this is non-portable. */ + (void)Source; + (void)Length; +} + + +#undef RtlZeroMemory +/* + * @implemented + */ +VOID +NTAPI +RtlZeroMemory ( + PVOID Destination, + ULONG Length +) +{ + RtlFillMemory ( + Destination, + Length, + 0 + ); +} + +/* EOF */ diff --git a/reactos/lib/rtl/memgen.c b/reactos/lib/rtl/memgen.c new file mode 100644 index 00000000000..a1e2e9c6ae0 --- /dev/null +++ b/reactos/lib/rtl/memgen.c @@ -0,0 +1,77 @@ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/rtl/mem.c + * PURPOSE: Memory functions + * PROGRAMMER: David Welch (welch@mcmail.com) + */ + +/* INCLUDES *****************************************************************/ + +#include + +#define NDEBUG +#include + +#undef RtlUlonglongByteSwap +#undef RtlUlongByteSwap +#undef RtlUshortByteSwap + +/************************************************************************* + * RtlUshortByteSwap + * + * Swap the bytes of an unsigned short value. + * + * NOTES + * Based on the inline versions in Wine winternl.h + * + * @implemented + */ +USHORT FASTCALL +RtlUshortByteSwap (IN USHORT Source) +{ + return (Source >> 8) | (Source << 8); +} + + + +/************************************************************************* + * RtlUlongByteSwap [NTDLL.@] + * + * Swap the bytes of an unsigned int value. + * + * NOTES + * Based on the inline versions in Wine winternl.h + * + * @implemented + */ +ULONG +FASTCALL +RtlUlongByteSwap( + IN ULONG Source +) +{ + return ((ULONG)RtlUshortByteSwap((USHORT)Source) << 16) | RtlUshortByteSwap((USHORT)(Source >> 16)); +} + + +/************************************************************************* + * RtlUlonglongByteSwap + * + * Swap the bytes of an unsigned long long value. + * + * PARAMS + * i [I] Value to swap bytes of + * + * RETURNS + * The value with its bytes swapped. + * + * @implemented + */ +ULONGLONG FASTCALL +RtlUlonglongByteSwap (IN ULONGLONG Source) +{ + return ((ULONGLONG) RtlUlongByteSwap (Source) << 32) | RtlUlongByteSwap (Source>>32); +} + + +/* EOF */ diff --git a/reactos/lib/rtl/rtl.rbuild b/reactos/lib/rtl/rtl.rbuild index 3d28108a795..0c8917ea331 100644 --- a/reactos/lib/rtl/rtl.rbuild +++ b/reactos/lib/rtl/rtl.rbuild @@ -40,6 +40,12 @@ tan_asm.s + + + memgen.c + mem.c + + access.c acl.c atom.c From 7a0843f8af30c7b3af4970dff133e54a53d743dd Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Mon, 25 Sep 2006 23:46:32 +0000 Subject: [PATCH 347/488] fixed overlaping memory problem with RtlMoveMemory. The rewrite of RtlMoveMemory did not handling overlaping memory. it shows with ntdll_winetest rtl, use the old asm version from the string.a instead svn path=/trunk/; revision=24273 --- reactos/lib/rtl/RtlMoveMemory.c | 23 +++++++++++ reactos/lib/rtl/i386/rtlmem.s | 67 --------------------------------- reactos/lib/rtl/rtl.rbuild | 1 + 3 files changed, 24 insertions(+), 67 deletions(-) create mode 100644 reactos/lib/rtl/RtlMoveMemory.c diff --git a/reactos/lib/rtl/RtlMoveMemory.c b/reactos/lib/rtl/RtlMoveMemory.c new file mode 100644 index 00000000000..f4bfd61eade --- /dev/null +++ b/reactos/lib/rtl/RtlMoveMemory.c @@ -0,0 +1,23 @@ +#include + +#define NDEBUG +#include + +#undef RtlMoveMemory +/* + * @implemented + */ +VOID +NTAPI +RtlMoveMemory ( + PVOID Destination, + CONST VOID * Source, + ULONG Length +) +{ + memmove ( + Destination, + Source, + Length + ); +} diff --git a/reactos/lib/rtl/i386/rtlmem.s b/reactos/lib/rtl/i386/rtlmem.s index 3cc292c1d3a..d273f0f6713 100644 --- a/reactos/lib/rtl/i386/rtlmem.s +++ b/reactos/lib/rtl/i386/rtlmem.s @@ -214,73 +214,6 @@ ByteZero: ret 8 .endfunc -.func RtlMoveMemory@12 -_RtlMoveMemory@12: - - /* Save volatiles */ - push esi - push edi - - /* Get pointers and size */ - mov esi, [esp+16] - mov edi, [esp+12] - mov ecx, [esp+20] - cld - - /* Check if the destination is higher (or equal) */ - cmp esi, edi - jbe Overlap - - /* Set ULONG size and UCHAR remainder */ -DoMove: - mov edx, ecx - and edx, 3 - shr ecx, 2 - - /* Do the move */ - rep movsd - or ecx, edx - jnz ByteMove - - /* Return */ - pop edi - pop esi - ret 12 - -ByteMove: - /* Move what's left */ - rep stosb - -DoneMove: - /* Restore volatiles */ - pop edi - pop esi - ret 12 - -Overlap: - /* Don't copy if they're equal */ - jz DoneMove - - /* Compare pointer distance with given length and check for overlap */ - mov eax, edi - sub eax, esi - cmp ecx, eax - jbe DoMove - - /* Set direction flag for backward move */ - std - - /* Copy byte-by-byte the non-overlapping distance */ - add esi, ecx - add edi, ecx - dec esi - dec edi - - /* Do the move, reset flag and return */ - rep movsb - cld - jmp DoneMove -.endfunc .func @RtlPrefetchMemoryNonTemporal@8, @RtlPrefetchMemoryNonTemporal@8 @RtlPrefetchMemoryNonTemporal@8: diff --git a/reactos/lib/rtl/rtl.rbuild b/reactos/lib/rtl/rtl.rbuild index 0c8917ea331..9a21d45ad70 100644 --- a/reactos/lib/rtl/rtl.rbuild +++ b/reactos/lib/rtl/rtl.rbuild @@ -39,6 +39,7 @@ sqrt_asm.s tan_asm.s + RtlMoveMemory.c From 54403619f8c5ce452e92435475d78a51449bdc40 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 26 Sep 2006 05:29:46 +0000 Subject: [PATCH 348/488] - In some far, far away galaxy, a long, long time ago, Greatlord will learn to fix 1-line bugs and/or talk to the developers responsible instead of reverting their code...until then.... svn path=/trunk/; revision=24276 --- reactos/lib/rtl/RtlMoveMemory.c | 23 ----------- reactos/lib/rtl/i386/rtlmem.s | 67 +++++++++++++++++++++++++++++++++ reactos/lib/rtl/rtl.rbuild | 1 - 3 files changed, 67 insertions(+), 24 deletions(-) delete mode 100644 reactos/lib/rtl/RtlMoveMemory.c diff --git a/reactos/lib/rtl/RtlMoveMemory.c b/reactos/lib/rtl/RtlMoveMemory.c deleted file mode 100644 index f4bfd61eade..00000000000 --- a/reactos/lib/rtl/RtlMoveMemory.c +++ /dev/null @@ -1,23 +0,0 @@ -#include - -#define NDEBUG -#include - -#undef RtlMoveMemory -/* - * @implemented - */ -VOID -NTAPI -RtlMoveMemory ( - PVOID Destination, - CONST VOID * Source, - ULONG Length -) -{ - memmove ( - Destination, - Source, - Length - ); -} diff --git a/reactos/lib/rtl/i386/rtlmem.s b/reactos/lib/rtl/i386/rtlmem.s index d273f0f6713..76826af0861 100644 --- a/reactos/lib/rtl/i386/rtlmem.s +++ b/reactos/lib/rtl/i386/rtlmem.s @@ -214,6 +214,73 @@ ByteZero: ret 8 .endfunc +.func RtlMoveMemory@12 +_RtlMoveMemory@12: + + /* Save volatiles */ + push esi + push edi + + /* Get pointers and size */ + mov esi, [esp+16] + mov edi, [esp+12] + mov ecx, [esp+20] + cld + + /* Check if the destination is higher (or equal) */ + cmp esi, edi + jbe Overlap + + /* Set ULONG size and UCHAR remainder */ +DoMove: + mov edx, ecx + and edx, 3 + shr ecx, 2 + + /* Do the move */ + rep movsd + or ecx, edx + jnz ByteMove + + /* Return */ + pop edi + pop esi + ret 12 + +ByteMove: + /* Move what's left */ + rep movsb + +DoneMove: + /* Restore volatiles */ + pop edi + pop esi + ret 12 + +Overlap: + /* Don't copy if they're equal */ + jz DoneMove + + /* Compare pointer distance with given length and check for overlap */ + mov eax, edi + sub eax, esi + cmp ecx, eax + jbe DoMove + + /* Set direction flag for backward move */ + std + + /* Copy byte-by-byte the non-overlapping distance */ + add esi, ecx + add edi, ecx + dec esi + dec edi + + /* Do the move, reset flag and return */ + rep movsb + cld + jmp DoneMove +.endfunc .func @RtlPrefetchMemoryNonTemporal@8, @RtlPrefetchMemoryNonTemporal@8 @RtlPrefetchMemoryNonTemporal@8: diff --git a/reactos/lib/rtl/rtl.rbuild b/reactos/lib/rtl/rtl.rbuild index 9a21d45ad70..0c8917ea331 100644 --- a/reactos/lib/rtl/rtl.rbuild +++ b/reactos/lib/rtl/rtl.rbuild @@ -39,7 +39,6 @@ sqrt_asm.s tan_asm.s - RtlMoveMemory.c From 572541f16abf2b67be75009330b1ff50464e2703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 26 Sep 2006 19:12:39 +0000 Subject: [PATCH 349/488] Two more constants found in FMIFS... svn path=/trunk/; revision=24277 --- reactos/base/system/autochk/autochk.c | 20 ++++++++++++-------- reactos/include/reactos/libs/fmifs/fmifs.h | 7 ++++--- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/reactos/base/system/autochk/autochk.c b/reactos/base/system/autochk/autochk.c index 86f6cc29e44..f2762783914 100644 --- a/reactos/base/system/autochk/autochk.c +++ b/reactos/base/system/autochk/autochk.c @@ -176,14 +176,6 @@ ChkdskCallback( DPRINT("UNKNOWN5\r"); break; - case UNKNOWN7: - DPRINT("UNKNOWN7\r"); - break; - - case UNKNOWN8: - DPRINT("UNKNOWN8\r"); - break; - case UNKNOWN9: DPRINT("UNKNOWN9\r"); break; @@ -204,6 +196,14 @@ ChkdskCallback( DPRINT("INSUFFICIENTRIGHTS\r"); break; + case FSNOTSUPPORTED: + DPRINT("FSNOTSUPPORTED\r"); + break; + + case VOLUMEINUSE: + DPRINT("VOLUMEINUSE\r"); + break; + case STRUCTUREPROGRESS: DPRINT("STRUCTUREPROGRESS\r"); break; @@ -212,6 +212,10 @@ ChkdskCallback( DPRINT("DONEWITHSTRUCTURE\r"); break; + case CLUSTERSIZETOOSMALL: + DPRINT("CLUSTERSIZETOOSMALL\r"); + break; + case PROGRESS: Percent = (PDWORD) Argument; PrintString("%d percent completed.\r", *Percent); diff --git a/reactos/include/reactos/libs/fmifs/fmifs.h b/reactos/include/reactos/libs/fmifs/fmifs.h index 2296bee656b..d7c6ef9b6c4 100644 --- a/reactos/include/reactos/libs/fmifs/fmifs.h +++ b/reactos/include/reactos/libs/fmifs/fmifs.h @@ -68,15 +68,16 @@ typedef enum UNKNOWN4, UNKNOWN5, INSUFFICIENTRIGHTS, - UNKNOWN7, - UNKNOWN8, + FSNOTSUPPORTED, + VOLUMEINUSE, UNKNOWN9, UNKNOWNA, DONE, UNKNOWNC, UNKNOWND, OUTPUT, - STRUCTUREPROGRESS + STRUCTUREPROGRESS, + CLUSTERSIZETOOSMALL, } CALLBACKCOMMAND; /* FMIFS callback definition */ From 21ff1ddb3d21cda29f5e89acaa6da63c71ae7706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 26 Sep 2006 19:18:02 +0000 Subject: [PATCH 350/488] Fix some warnings in winlogon code Change winlogon registry key to "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" for compatibility reasons, as some programs read it directly svn path=/trunk/; revision=24278 --- reactos/base/system/userinit/userinit.c | 2 +- reactos/base/system/winlogon/sas.c | 15 +++--- reactos/base/system/winlogon/screensaver.c | 32 ++++++------ reactos/base/system/winlogon/setup.c | 2 +- reactos/base/system/winlogon/winlogon.c | 18 +++---- reactos/base/system/winlogon/winlogon.h | 5 +- reactos/base/system/winlogon/wlx.c | 61 +++++++++++++++++++++- reactos/boot/bootdata/hivesft.inf | 16 +++--- reactos/dll/win32/msgina/msgina.c | 4 +- 9 files changed, 106 insertions(+), 49 deletions(-) diff --git a/reactos/base/system/userinit/userinit.c b/reactos/base/system/userinit/userinit.c index 135dba92332..123f7735868 100644 --- a/reactos/base/system/userinit/userinit.c +++ b/reactos/base/system/userinit/userinit.c @@ -118,7 +118,7 @@ BOOL GetShell(WCHAR *CommandLine) BOOL ConsoleShell = IsConsoleShell(); if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, - L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\Winlogon", + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { Size = MAX_PATH * sizeof(WCHAR); diff --git a/reactos/base/system/winlogon/sas.c b/reactos/base/system/winlogon/sas.c index 31801b5f325..65bc33d958a 100644 --- a/reactos/base/system/winlogon/sas.c +++ b/reactos/base/system/winlogon/sas.c @@ -37,7 +37,7 @@ StartTaskManager( BOOL SetDefaultLanguage( - IN BOOL UserProfile) + IN BOOLEAN UserProfile) { HKEY BaseKey; LPCWSTR SubKey; @@ -114,7 +114,7 @@ SetDefaultLanguage( } /* Convert Value to a Lcid */ - ValueString.Length = ValueString.MaximumLength = dwSize; + ValueString.Length = ValueString.MaximumLength = (USHORT)dwSize; ValueString.Buffer = Value; Status = RtlUnicodeStringToInteger(&ValueString, 16, &Lcid); if (!NT_SUCCESS(Status)) @@ -146,7 +146,7 @@ static BOOL HandleLogon( IN OUT PWLSESSION Session) { - PROFILEINFOW ProfileInfo; + PROFILEINFOW ProfileInfo = { 0 }; LPVOID lpEnvironment = NULL; BOOLEAN Old; @@ -177,7 +177,8 @@ HandleLogon( TRUE)) { ERR("WL: CreateEnvironmentBlock() failed\n"); - UnloadUserProfile(WLSession->UserToken, ProfileInfo.hProfile); + if (!(Session->Options & WLX_LOGON_OPT_NO_PROFILE)) + UnloadUserProfile(WLSession->UserToken, ProfileInfo.hProfile); CloseHandle(Session->UserToken); return FALSE; } @@ -317,13 +318,15 @@ HandleLogoff( return STATUS_SUCCESS; } -static INT_PTR CALLBACK +static BOOL CALLBACK ShutdownComputerWindowProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam) { + UNREFERENCED_PARAMETER(lParam); + switch (uMsg) { case WM_COMMAND: @@ -689,7 +692,7 @@ SASWindowProc( Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams; /* Save the Session pointer */ - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)Session); + SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)Session); return RegisterHotKeys(Session, hwndDlg); } diff --git a/reactos/base/system/winlogon/screensaver.c b/reactos/base/system/winlogon/screensaver.c index 9e56fad9b9d..a1c61a8789e 100644 --- a/reactos/base/system/winlogon/screensaver.c +++ b/reactos/base/system/winlogon/screensaver.c @@ -202,29 +202,31 @@ InitializeScreenSaver( } #endif - if (!(Session->hScreenSaverParametersChanged = CreateEventW(NULL, FALSE, FALSE, NULL))) + Session->hScreenSaverParametersChanged = CreateEventW(NULL, FALSE, FALSE, NULL); + if (!Session->hScreenSaverParametersChanged) { WARN("WL: Unable to create screen saver event (error %lu)\n", GetLastError()); + return TRUE; } - else if (!(Session->hEndOfScreenSaverThread = CreateEventW(NULL, FALSE, FALSE, NULL))) + Session->hEndOfScreenSaverThread = CreateEventW(NULL, FALSE, FALSE, NULL); + if (!Session->hEndOfScreenSaverThread) { WARN("WL: Unable to create screen saver event (error %lu)\n", GetLastError()); CloseHandle(Session->hScreenSaverParametersChanged); + return TRUE; } + + ScreenSaverThread = CreateThread( + NULL, + 0, + ScreenSaverThreadMain, + Session, + 0, + NULL); + if (ScreenSaverThread) + CloseHandle(ScreenSaverThread); else - { - ScreenSaverThread = CreateThread( - NULL, - 0, - ScreenSaverThreadMain, - Session, - 0, - NULL); - if (ScreenSaverThread) - CloseHandle(ScreenSaverThread); - else - WARN("WL: Unable to start screen saver thread\n"); - } + WARN("WL: Unable to start screen saver thread\n"); return TRUE; } diff --git a/reactos/base/system/winlogon/setup.c b/reactos/base/system/winlogon/setup.c index 1421a6a8e33..c5e41b75376 100644 --- a/reactos/base/system/winlogon/setup.c +++ b/reactos/base/system/winlogon/setup.c @@ -109,7 +109,7 @@ RunSetup (VOID) STARTUPINFOW StartupInfo; WCHAR Shell[MAX_PATH]; WCHAR CommandLine[MAX_PATH]; - BOOLEAN Result; + BOOL Result; DWORD dwError; HKEY hKey; DWORD dwType; diff --git a/reactos/base/system/winlogon/winlogon.c b/reactos/base/system/winlogon/winlogon.c index 245720c9227..fbda5936356 100644 --- a/reactos/base/system/winlogon/winlogon.c +++ b/reactos/base/system/winlogon/winlogon.c @@ -24,7 +24,7 @@ PWLSESSION WLSession = NULL; static BOOL StartServicesManager(VOID) { - HANDLE ServicesInitEvent; + HANDLE ServicesInitEvent = NULL; STARTUPINFOW StartupInfo; PROCESS_INFORMATION ProcessInformation; DWORD Count; @@ -154,7 +154,7 @@ OpenRegistryKey( OUT HKEY *WinLogonKey) { return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, - L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon", + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon", 0, KEY_QUERY_VALUE, WinLogonKey); @@ -302,7 +302,7 @@ RemoveStatusMessage( return Session->Gina.Functions.WlxRemoveStatusMessage(Session->Gina.Context); } -static INT_PTR CALLBACK +static BOOL CALLBACK GinaLoadFailedWindowProc( IN HWND hwndDlg, IN UINT uMsg, @@ -362,6 +362,10 @@ WinMain( #endif MSG Msg; + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + UNREFERENCED_PARAMETER(nShowCmd); + hAppInstance = hInstance; if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE)) @@ -370,7 +374,6 @@ WinMain( HandleShutdown(NULL, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF); NtShutdownSystem(ShutdownNoReboot); ExitProcess(0); - return 0; } WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION)); @@ -380,7 +383,6 @@ WinMain( ERR("WL: Could not allocate memory for winlogon instance\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); ExitProcess(1); - return 1; } WLSession->DialogTimeout = 120; /* 2 minutes */ @@ -389,7 +391,6 @@ WinMain( ERR("WL: Could not create window station and desktops\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); ExitProcess(1); - return 1; } LockWorkstation(WLSession); @@ -398,7 +399,6 @@ WinMain( ERR("WL: Could not start services.exe\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); ExitProcess(1); - return 1; } /* Check for pending setup */ @@ -415,7 +415,6 @@ WinMain( HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT); ExitProcess(0); - return 0; } if (!StartLsass()) @@ -423,7 +422,6 @@ WinMain( DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError()); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); ExitProcess(1); - return 1; } /* Load and initialize gina */ @@ -433,7 +431,6 @@ WinMain( DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedWindowProc, (LPARAM)L""); HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT); ExitProcess(1); - return 1; } DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP); @@ -475,7 +472,6 @@ WinMain( { ERR("WL: Failed to initialize SAS\n"); ExitProcess(2); - return 2; } //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS); diff --git a/reactos/base/system/winlogon/winlogon.h b/reactos/base/system/winlogon/winlogon.h index ffc9692e04f..5e6b5032e6e 100644 --- a/reactos/base/system/winlogon/winlogon.h +++ b/reactos/base/system/winlogon/winlogon.h @@ -16,8 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * COPYRIGHT: See COPYING in the top level directory +/* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS winlogon * FILE: subsys/system/winlogon/winlogon.h * PURPOSE: Winlogon @@ -180,7 +179,7 @@ UpdatePerUserSystemParameters(DWORD dwUnknown, /* sas.c */ BOOL SetDefaultLanguage( - IN BOOL UserProfile); + IN BOOLEAN UserProfile); BOOL InitializeSAS( diff --git a/reactos/base/system/winlogon/wlx.c b/reactos/base/system/winlogon/wlx.c index 5dd0399d192..f81f65f4cea 100644 --- a/reactos/base/system/winlogon/wlx.c +++ b/reactos/base/system/winlogon/wlx.c @@ -18,7 +18,7 @@ static DLGPROC PreviousWindowProc; static UINT_PTR IdTimer; -static INT_PTR CALLBACK +static BOOL CALLBACK DefaultWlxWindowProc( IN HWND hwndDlg, IN UINT uMsg, @@ -120,6 +120,11 @@ WlxAssignShellProtection( HANDLE hProcess, HANDLE hThread) { + UNREFERENCED_PARAMETER(hWlx); + UNREFERENCED_PARAMETER(hToken); + UNREFERENCED_PARAMETER(hProcess); + UNREFERENCED_PARAMETER(hThread); + UNIMPLEMENTED; return 0; } @@ -135,6 +140,8 @@ WlxMessageBox( LPWSTR lpszTitle, UINT fuStyle) { + UNREFERENCED_PARAMETER(hWlx); + TRACE("WlxMessageBox()\n"); /* FIXME: Provide a custom window proc to be able to handle timeout */ return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle); @@ -151,6 +158,8 @@ WlxDialogBox( HWND hwndOwner, DLGPROC dlgprc) { + UNREFERENCED_PARAMETER(hWlx); + TRACE("WlxDialogBox()\n"); if (PreviousWindowProc != NULL) @@ -171,6 +180,8 @@ WlxDialogBoxParam( DLGPROC dlgprc, LPARAM dwInitParam) { + UNREFERENCED_PARAMETER(hWlx); + TRACE("WlxDialogBoxParam()\n"); if (PreviousWindowProc != NULL) @@ -190,6 +201,8 @@ WlxDialogBoxIndirect( HWND hwndOwner, DLGPROC dlgprc) { + UNREFERENCED_PARAMETER(hWlx); + TRACE("WlxDialogBoxIndirect()\n"); if (PreviousWindowProc != NULL) @@ -210,6 +223,8 @@ WlxDialogBoxIndirectParam( DLGPROC dlgprc, LPARAM dwInitParam) { + UNREFERENCED_PARAMETER(hWlx); + TRACE("WlxDialogBoxIndirectParam()\n"); if (PreviousWindowProc != NULL) @@ -255,6 +270,10 @@ WlxChangePasswordNotify( PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo) { + UNREFERENCED_PARAMETER(hWlx); + UNREFERENCED_PARAMETER(pMprInfo); + UNREFERENCED_PARAMETER(dwChangeInfo); + UNIMPLEMENTED; return 0; } @@ -267,6 +286,9 @@ WlxGetSourceDesktop( HANDLE hWlx, PWLX_DESKTOP* ppDesktop) { + UNREFERENCED_PARAMETER(hWlx); + UNREFERENCED_PARAMETER(ppDesktop); + UNIMPLEMENTED; return FALSE; } @@ -279,6 +301,9 @@ WlxSetReturnDesktop( HANDLE hWlx, PWLX_DESKTOP pDesktop) { + UNREFERENCED_PARAMETER(hWlx); + UNREFERENCED_PARAMETER(pDesktop); + UNIMPLEMENTED; return FALSE; } @@ -294,6 +319,12 @@ WlxCreateUserDesktop( PWSTR pszDesktopName, PWLX_DESKTOP* ppDesktop) { + UNREFERENCED_PARAMETER(hWlx); + UNREFERENCED_PARAMETER(hToken); + UNREFERENCED_PARAMETER(Flags); + UNREFERENCED_PARAMETER(pszDesktopName); + UNREFERENCED_PARAMETER(ppDesktop); + UNIMPLEMENTED; return FALSE; } @@ -309,6 +340,12 @@ WlxChangePasswordNotifyEx( PWSTR ProviderName, PVOID Reserved) { + UNREFERENCED_PARAMETER(hWlx); + UNREFERENCED_PARAMETER(pMprInfo); + UNREFERENCED_PARAMETER(dwChangeInfo); + UNREFERENCED_PARAMETER(ProviderName); + UNREFERENCED_PARAMETER(Reserved); + UNIMPLEMENTED; return 0; } @@ -322,6 +359,10 @@ WlxCloseUserDesktop( PWLX_DESKTOP pDesktop, HANDLE hToken) { + UNREFERENCED_PARAMETER(hWlx); + UNREFERENCED_PARAMETER(pDesktop); + UNREFERENCED_PARAMETER(hToken); + UNIMPLEMENTED; return FALSE; } @@ -422,6 +463,8 @@ VOID WINAPI WlxWin31Migrate( HANDLE hWlx) { + UNREFERENCED_PARAMETER(hWlx); + UNIMPLEMENTED; } @@ -432,6 +475,8 @@ BOOL WINAPI WlxQueryClientCredentials( PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred) { + UNREFERENCED_PARAMETER(pCred); + UNIMPLEMENTED; return FALSE; } @@ -443,6 +488,8 @@ BOOL WINAPI WlxQueryInetConnectorCredentials( PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred) { + UNREFERENCED_PARAMETER(pCred); + UNIMPLEMENTED; return FALSE; } @@ -467,6 +514,11 @@ WlxQueryTerminalServicesData( WCHAR* UserName, WCHAR* Domain) { + UNREFERENCED_PARAMETER(hWlx); + UNREFERENCED_PARAMETER(pTSData); + UNREFERENCED_PARAMETER(UserName); + UNREFERENCED_PARAMETER(Domain); + UNIMPLEMENTED; return 0; } @@ -478,6 +530,8 @@ DWORD WINAPI WlxQueryConsoleSwitchCredentials( PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred) { + UNREFERENCED_PARAMETER(pCred); + UNIMPLEMENTED; return 0; } @@ -489,6 +543,8 @@ BOOL WINAPI WlxQueryTsLogonCredentials( PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred) { + UNREFERENCED_PARAMETER(pCred); + UNIMPLEMENTED; return FALSE; } @@ -588,7 +644,8 @@ LoadGina( /* Terminate string */ GinaDll[MAX_PATH] = '\0'; - if (!(hGina = LoadLibraryW(GinaDll))) + hGina = LoadLibraryW(GinaDll); + if (!hGina) goto cleanup; Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate"); diff --git a/reactos/boot/bootdata/hivesft.inf b/reactos/boot/bootdata/hivesft.inf index dcbe055c595..ef7a5502222 100644 --- a/reactos/boot/bootdata/hivesft.inf +++ b/reactos/boot/bootdata/hivesft.inf @@ -738,14 +738,14 @@ HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Tonga Standard Tim HKLM,"SOFTWARE\ReactOS\ReactOS\CurrentVersion\IFS","FAT",0x00000000,"ufat.dll" HKLM,"SOFTWARE\ReactOS\ReactOS\CurrentVersion\IFS","FAT32",0x00000000,"ufat.dll" -HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","ConsoleShell",0x00020000,"%SystemRoot%\system32\cmd.exe" -HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Shell",0x00020000,"%SystemRoot%\explorer.exe" -HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","StartServices",0x00010001,0x00000001 -HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","StartLsass",0x00010001,0x00000001 -HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Userinit",0x00020000,"%SystemRoot%\system32\userinit.exe" -HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","AutoAdminLogon",0x00000000,"1" -HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","DefaultUserName",0x00000000,"Administrator" -HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","DefaultPassword",0x00000000,"Secret" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","ConsoleShell",0x00020000,"%SystemRoot%\system32\cmd.exe" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","Shell",0x00020000,"%SystemRoot%\explorer.exe" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","StartServices",0x00010001,0x00000001 +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","StartLsass",0x00010001,0x00000001 +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","Userinit",0x00020000,"%SystemRoot%\system32\userinit.exe" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","AutoAdminLogon",0x00000000,"1" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","DefaultUserName",0x00000000,"Administrator" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","DefaultPassword",0x00000000,"Secret" ;Time Zone Servers HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers","1",0x00000000,"pool.ntp.org" diff --git a/reactos/dll/win32/msgina/msgina.c b/reactos/dll/win32/msgina/msgina.c index 9285949a01a..47372109c6a 100644 --- a/reactos/dll/win32/msgina/msgina.c +++ b/reactos/dll/win32/msgina/msgina.c @@ -239,7 +239,7 @@ WlxActivateUserShell( TRACE("WlxActivateUserShell()\n"); /* get the path of userinit */ if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\Winlogon", + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) {ERR("GINA: Failed: 1\n"); VirtualFree(pEnvironment, 0, MEM_RELEASE); @@ -419,7 +419,7 @@ DoAutoLogon( rc = RegOpenKeyExW( HKEY_LOCAL_MACHINE, - L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon", + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon", 0, KEY_QUERY_VALUE, &WinLogonKey); From 2c56c7d7e881d25d0815d97d9ffe44d99bda660f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 26 Sep 2006 19:44:17 +0000 Subject: [PATCH 351/488] Merge from Wine: Frank Richter setupapi: Duplicate behaviour of native SetupGetInfInformation with NULL ReturnBuffer and certain ReturnBufferSizes. svn path=/trunk/; revision=24279 --- reactos/dll/win32/setupapi/query.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/reactos/dll/win32/setupapi/query.c b/reactos/dll/win32/setupapi/query.c index e09631e5abb..5df1157ee49 100644 --- a/reactos/dll/win32/setupapi/query.c +++ b/reactos/dll/win32/setupapi/query.c @@ -119,6 +119,7 @@ BOOL WINAPI SetupGetInfInformationW(LPCVOID InfSpec, DWORD SearchControl, { HINF inf; BOOL ret; + DWORD infSize; TRACE("(%p, %ld, %p, %ld, %p)\n", InfSpec, SearchControl, ReturnBuffer, ReturnBufferSize, RequiredSize); @@ -133,12 +134,6 @@ BOOL WINAPI SetupGetInfInformationW(LPCVOID InfSpec, DWORD SearchControl, return FALSE; } - if (!ReturnBuffer && ReturnBufferSize) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - switch (SearchControl) { case INFINFO_INF_SPEC_IS_HINF: @@ -170,7 +165,13 @@ BOOL WINAPI SetupGetInfInformationW(LPCVOID InfSpec, DWORD SearchControl, return FALSE; } - ret = fill_inf_info(inf, ReturnBuffer, ReturnBufferSize, RequiredSize); + ret = fill_inf_info(inf, ReturnBuffer, ReturnBufferSize, &infSize); + if (!ReturnBuffer && (ReturnBufferSize >= infSize)) + { + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + } + if (RequiredSize) *RequiredSize = infSize; if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE) SetupCloseInfFile(inf); From 36032a956d3f3e6ec6498758a23fbdd357f473b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 26 Sep 2006 19:52:55 +0000 Subject: [PATCH 352/488] Fix format build. Why dependency tracking didn't detect this problem? Another mystery... svn path=/trunk/; revision=24280 --- reactos/base/system/format/format.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reactos/base/system/format/format.c b/reactos/base/system/format/format.c index 3e970647296..99775e2fe83 100755 --- a/reactos/base/system/format/format.c +++ b/reactos/base/system/format/format.c @@ -195,13 +195,14 @@ FormatExCallback ( case UNKNOWN4: case UNKNOWN5: case INSUFFICIENTRIGHTS: - case UNKNOWN7: - case UNKNOWN8: + case FSNOTSUPPORTED: + case VOLUMEINUSE: case UNKNOWN9: case UNKNOWNA: case UNKNOWNC: case UNKNOWND: case STRUCTUREPROGRESS: + case CLUSTERSIZETOOSMALL: LoadString( GetModuleHandle(NULL), STRING_NO_SUPPORT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); _tprintf(szMsg); return FALSE; From fa9c62c9a0c60f16f646393819c5207b6b8b20fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 26 Sep 2006 21:08:11 +0000 Subject: [PATCH 353/488] Patch by Matthias Kupfer Fix tiny typo in all rc-files "%" -> "%s" See issue #1828 for more details. svn path=/trunk/; revision=24281 --- reactos/dll/cpl/timedate/Cz.rc | 2 +- reactos/dll/cpl/timedate/De.rc | 2 +- reactos/dll/cpl/timedate/Dk.rc | 2 +- reactos/dll/cpl/timedate/En.rc | 2 +- reactos/dll/cpl/timedate/Fr.rc | 2 +- reactos/dll/cpl/timedate/Gr.rc | 2 +- reactos/dll/cpl/timedate/Hu.rc | 2 +- reactos/dll/cpl/timedate/It.rc | 2 +- reactos/dll/cpl/timedate/Ja.rc | 2 +- reactos/dll/cpl/timedate/Nl.rc | 2 +- reactos/dll/cpl/timedate/Pl.rc | 2 +- reactos/dll/cpl/timedate/Ru.rc | 2 +- reactos/dll/cpl/timedate/Sv.rc | 2 +- reactos/dll/cpl/timedate/Uk.rc | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/reactos/dll/cpl/timedate/Cz.rc b/reactos/dll/cpl/timedate/Cz.rc index 58c9a7cf61a..495daf5f9ba 100644 --- a/reactos/dll/cpl/timedate/Cz.rc +++ b/reactos/dll/cpl/timedate/Cz.rc @@ -60,6 +60,6 @@ BEGIN IDS_TIMEZONETEXT "Aktuální časové pásmo: %s" IDS_TIMEZONEINVALID "Neplatné" IDS_TIMEZONEUNKNOWN "Neznámé" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on % at %s" + IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" END diff --git a/reactos/dll/cpl/timedate/De.rc b/reactos/dll/cpl/timedate/De.rc index 7c71b95fb92..0553d59b244 100644 --- a/reactos/dll/cpl/timedate/De.rc +++ b/reactos/dll/cpl/timedate/De.rc @@ -61,7 +61,7 @@ BEGIN IDS_TIMEZONETEXT "Aktuelle Zeitzone: %s" IDS_TIMEZONEINVALID "Ungültig" IDS_TIMEZONEUNKNOWN "Unbekannt" - IDS_INETTIMESUCSYNC "Die Zeit wurde erfolgreich mit %s am % um %s synchronisiert" + IDS_INETTIMESUCSYNC "Die Zeit wurde erfolgreich mit %s am %s um %s synchronisiert" IDS_INETTIMENEXTSYNC "Nächste Synchronisierung am %s um %s" END diff --git a/reactos/dll/cpl/timedate/Dk.rc b/reactos/dll/cpl/timedate/Dk.rc index 51708831b4e..f31feb63be5 100644 --- a/reactos/dll/cpl/timedate/Dk.rc +++ b/reactos/dll/cpl/timedate/Dk.rc @@ -61,6 +61,6 @@ BEGIN IDS_TIMEZONETEXT "Nuvćrende tidszone: %s" IDS_TIMEZONEINVALID "Ugyldig" IDS_TIMEZONEUNKNOWN "Ukendt" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on % at %s" + IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" END diff --git a/reactos/dll/cpl/timedate/En.rc b/reactos/dll/cpl/timedate/En.rc index 72fbc459d6a..73d4e58414f 100644 --- a/reactos/dll/cpl/timedate/En.rc +++ b/reactos/dll/cpl/timedate/En.rc @@ -61,7 +61,7 @@ BEGIN IDS_TIMEZONETEXT "Current time zone: %s" IDS_TIMEZONEINVALID "Invalid" IDS_TIMEZONEUNKNOWN "Unknown" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on % at %s" + IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" IDS_INETTIMESYNCING "Please wait while ReactOS synchronizes the time with %s" IDS_INETTIMEERROR "An error occured while ReactOS was synchronizing with %s" diff --git a/reactos/dll/cpl/timedate/Fr.rc b/reactos/dll/cpl/timedate/Fr.rc index 35d39bf488f..70a8f1c109a 100644 --- a/reactos/dll/cpl/timedate/Fr.rc +++ b/reactos/dll/cpl/timedate/Fr.rc @@ -60,6 +60,6 @@ BEGIN IDS_TIMEZONETEXT "Fuseau horaire actuel: %s" IDS_TIMEZONEINVALID "Invalide" IDS_TIMEZONEUNKNOWN "Inconnu" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on % at %s" + IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" END diff --git a/reactos/dll/cpl/timedate/Gr.rc b/reactos/dll/cpl/timedate/Gr.rc index e79f5b9d61b..d572e45673a 100644 --- a/reactos/dll/cpl/timedate/Gr.rc +++ b/reactos/dll/cpl/timedate/Gr.rc @@ -61,6 +61,6 @@ BEGIN IDS_TIMEZONETEXT "ÔůńéíŢ ÷ńďíéęŢ ćţíç: %s" IDS_TIMEZONEINVALID "Ěç Ýăăőńď" IDS_TIMEZONEUNKNOWN "˘ăíůóôď" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on % at %s" + IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" END diff --git a/reactos/dll/cpl/timedate/Hu.rc b/reactos/dll/cpl/timedate/Hu.rc index bd1ce498091..7bf28021dbe 100644 --- a/reactos/dll/cpl/timedate/Hu.rc +++ b/reactos/dll/cpl/timedate/Hu.rc @@ -60,6 +60,6 @@ BEGIN IDS_TIMEZONETEXT "Használt időzóna: %s" IDS_TIMEZONEINVALID "Érvénytelen" IDS_TIMEZONEUNKNOWN "Ismeretlen" - IDS_INETTIMESUCSYNC "A számítógép órája sikeresen szinkronizálva lett: %s (% %s-kor)" + IDS_INETTIMESUCSYNC "A számítógép órája sikeresen szinkronizálva lett: %s (%s %s-kor)" IDS_INETTIMENEXTSYNC "A következő szinkronizálás: %s %s-kor" END diff --git a/reactos/dll/cpl/timedate/It.rc b/reactos/dll/cpl/timedate/It.rc index 25bd322b1cd..26830eb9249 100644 --- a/reactos/dll/cpl/timedate/It.rc +++ b/reactos/dll/cpl/timedate/It.rc @@ -61,7 +61,7 @@ BEGIN IDS_TIMEZONETEXT "Fuso orario corrente: %s" IDS_TIMEZONEINVALID "Non valido" IDS_TIMEZONEUNKNOWN "Sconosciuto" - IDS_INETTIMESUCSYNC "L'ora č stata sincronizzata correttamente con %s % alle %s" + IDS_INETTIMESUCSYNC "L'ora č stata sincronizzata correttamente con %s %s alle %s" IDS_INETTIMENEXTSYNC "Prossima sincronizzazione: %s alle %s" IDS_INETTIMESYNCING "Sincronizzazione ora con %s" IDS_INETTIMEERROR "E' stato rilevato un errore mentre ReactOS si stava sincronizzando con %s" diff --git a/reactos/dll/cpl/timedate/Ja.rc b/reactos/dll/cpl/timedate/Ja.rc index ab70cd6cab9..8dcd9202c60 100644 --- a/reactos/dll/cpl/timedate/Ja.rc +++ b/reactos/dll/cpl/timedate/Ja.rc @@ -61,6 +61,6 @@ BEGIN IDS_TIMEZONETEXT "Ś»ŤÝ‚Ě^C€ ][“: %s" IDS_TIMEZONEINVALID "•sł‚Č’l" IDS_TIMEZONEUNKNOWN "•s–ľ" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on % at %s" + IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" END diff --git a/reactos/dll/cpl/timedate/Nl.rc b/reactos/dll/cpl/timedate/Nl.rc index 11c9f94136e..ec770a1f75b 100644 --- a/reactos/dll/cpl/timedate/Nl.rc +++ b/reactos/dll/cpl/timedate/Nl.rc @@ -60,6 +60,6 @@ BEGIN IDS_TIMEZONETEXT "Huidige tijdzone: %s" IDS_TIMEZONEINVALID "Ongelding" IDS_TIMEZONEUNKNOWN "Niet gekend" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on % at %s" + IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" END diff --git a/reactos/dll/cpl/timedate/Pl.rc b/reactos/dll/cpl/timedate/Pl.rc index 01360e2a67b..944ef464bd6 100644 --- a/reactos/dll/cpl/timedate/Pl.rc +++ b/reactos/dll/cpl/timedate/Pl.rc @@ -62,6 +62,6 @@ BEGIN IDS_TIMEZONETEXT "Aktualna strefa czasowa: %s" IDS_TIMEZONEINVALID "Nieprawidłowa" IDS_TIMEZONEUNKNOWN "Nieznana" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on % at %s" + IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" END diff --git a/reactos/dll/cpl/timedate/Ru.rc b/reactos/dll/cpl/timedate/Ru.rc index 41214001494..fd1d55144c1 100644 --- a/reactos/dll/cpl/timedate/Ru.rc +++ b/reactos/dll/cpl/timedate/Ru.rc @@ -60,6 +60,6 @@ BEGIN IDS_TIMEZONETEXT "Ňĺęóůčé ÷ŕńîâîé ďî˙ń: %s" IDS_TIMEZONEINVALID "Íĺäĺéńňâčňĺëüíŕ˙" IDS_TIMEZONEUNKNOWN "Íĺčçâĺńňíŕ˙" - IDS_INETTIMESUCSYNC "Âđĺě˙ áűëî óńďĺříî ńčíőđîíčçčđîâŕíî ń %s íŕ % â %s" + IDS_INETTIMESUCSYNC "Âđĺě˙ áűëî óńďĺříî ńčíőđîíčçčđîâŕíî ń %s íŕ %s â %s" IDS_INETTIMENEXTSYNC "Ńëĺäóţůŕ˙ ńčíőđîíčçŕöč˙ ÷ĺđĺç: %s â %s" END diff --git a/reactos/dll/cpl/timedate/Sv.rc b/reactos/dll/cpl/timedate/Sv.rc index f6f1251fb36..3008648550f 100644 --- a/reactos/dll/cpl/timedate/Sv.rc +++ b/reactos/dll/cpl/timedate/Sv.rc @@ -65,6 +65,6 @@ BEGIN IDS_TIMEZONETEXT "Aktuell tidszon: %s" IDS_TIMEZONEINVALID "Felaktig" IDS_TIMEZONEUNKNOWN "Okänd" - IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on % at %s" + IDS_INETTIMESUCSYNC "The time has been successfully synchronized with %s on %s at %s" IDS_INETTIMENEXTSYNC "Next synchronization: %s at %s" END diff --git a/reactos/dll/cpl/timedate/Uk.rc b/reactos/dll/cpl/timedate/Uk.rc index 9d033c48ca3..203d6fe4768 100644 --- a/reactos/dll/cpl/timedate/Uk.rc +++ b/reactos/dll/cpl/timedate/Uk.rc @@ -69,7 +69,7 @@ BEGIN IDS_TIMEZONETEXT "Ďîňî÷íčé ÷ŕńîâčé ďî˙ń: %s" IDS_TIMEZONEINVALID "Íĺäłéńíčé" IDS_TIMEZONEUNKNOWN "Íĺâłäîěčé" - IDS_INETTIMESUCSYNC "×ŕń áóëî óńďłříî ńčíőđîíłçîâŕíî ç %s íŕ % â %s" + IDS_INETTIMESUCSYNC "×ŕń áóëî óńďłříî ńčíőđîíłçîâŕíî ç %s íŕ %s â %s" IDS_INETTIMENEXTSYNC "Íŕńňóďíŕ ńčíőđîíłçŕöł˙: %s â %s" IDS_INETTIMESYNCING "Áóäü ëŕńęŕ çŕ÷ĺęŕéňĺ, ďîęč ReactOS ńčíőđîíłçóş ÷ŕń ç %s" IDS_INETTIMEERROR "Ďîěčëęŕ ďłä ÷ŕń ńčíőđîíłçŕöłż ç %s" From 87099f3ca64ddbb939fbad762aaac1e2a475f956 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 27 Sep 2006 12:28:25 +0000 Subject: [PATCH 354/488] Move the memory in RtlpDeleteData instead of copying it because the source and destination may be overlapping. svn path=/trunk/; revision=24282 --- reactos/lib/rtl/acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/lib/rtl/acl.c b/reactos/lib/rtl/acl.c index e3d68fd841f..0044bb20570 100644 --- a/reactos/lib/rtl/acl.c +++ b/reactos/lib/rtl/acl.c @@ -612,7 +612,7 @@ RtlpDeleteData(PVOID Ace, { if (AceSize < Offset) { - RtlCopyMemory(Ace, + RtlMoveMemory(Ace, (PVOID)((ULONG_PTR)Ace + AceSize), Offset - AceSize); } From 28d82c02296ccbc22cba39ab47456cfee4f8e297 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 27 Sep 2006 12:43:50 +0000 Subject: [PATCH 355/488] Don't use BOOL for 1 bit flags because it's signed. svn path=/trunk/; revision=24283 --- reactos/dll/win32/devmgr/advprop.c | 31 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/reactos/dll/win32/devmgr/advprop.c b/reactos/dll/win32/devmgr/advprop.c index 073598c4219..e1bfad607ed 100644 --- a/reactos/dll/win32/devmgr/advprop.c +++ b/reactos/dll/win32/devmgr/advprop.c @@ -57,18 +57,25 @@ typedef struct _DEVADVPROP_INFO DWORD nDevPropSheets; HPROPSHEETPAGE *DevPropSheets; - BOOL FreeDevPropSheets : 1; - BOOL CanDisable : 1; - BOOL DeviceStarted : 1; - BOOL DeviceUsageChanged : 1; - BOOL CloseDevInst : 1; - BOOL IsAdmin : 1; - BOOL DoDefaultDevAction : 1; - BOOL PageInitialized : 1; - BOOL ShowRemotePages : 1; - BOOL HasDriverPage : 1; - BOOL HasResourcePage : 1; - BOOL HasPowerPage : 1; + union + { + UINT Flags; + struct + { + UINT FreeDevPropSheets : 1; + UINT CanDisable : 1; + UINT DeviceStarted : 1; + UINT DeviceUsageChanged : 1; + UINT CloseDevInst : 1; + UINT IsAdmin : 1; + UINT DoDefaultDevAction : 1; + UINT PageInitialized : 1; + UINT ShowRemotePages : 1; + UINT HasDriverPage : 1; + UINT HasResourcePage : 1; + UINT HasPowerPage : 1; + }; + }; WCHAR szDevName[255]; WCHAR szTemp[255]; From 86e57e8c93829bb688cdc03426f49687d22555d4 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Wed, 27 Sep 2006 17:30:08 +0000 Subject: [PATCH 356/488] hpoussin forget change this regkey to SOFTWARE\\Microsoft\\WindowsNT\\CurrentVersion\\Winlogon" svn path=/trunk/; revision=24284 --- reactos/dll/win32/syssetup/install.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/syssetup/install.c b/reactos/dll/win32/syssetup/install.c index 9f62894bdc4..5a2749d8b6f 100644 --- a/reactos/dll/win32/syssetup/install.c +++ b/reactos/dll/win32/syssetup/install.c @@ -408,7 +408,7 @@ InstallLiveCD (HINSTANCE hInstance) /* Load the default shell */ rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, - TEXT("SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\Winlogon"), /* FIXME: should be REGSTR_PATH_WINLOGON */ + TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), /* FIXME: should be REGSTR_PATH_WINLOGON */ 0, KEY_QUERY_VALUE, &hKey); From c191e989a66ced066c4fff9a149cae64f112f39f Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Wed, 27 Sep 2006 22:40:18 +0000 Subject: [PATCH 357/488] update a few cpl icons svn path=/trunk/; revision=24285 --- reactos/dll/cpl/hdwwiz/resources/applet.ico | Bin 1398 -> 17542 bytes reactos/dll/cpl/intl/resources/applet.ico | Bin 17542 -> 17542 bytes reactos/dll/cpl/intl_new/resources/applet.ico | Bin 17542 -> 17542 bytes reactos/dll/cpl/sysdm/resources/applet.ico | Bin 29926 -> 17542 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/reactos/dll/cpl/hdwwiz/resources/applet.ico b/reactos/dll/cpl/hdwwiz/resources/applet.ico index 3eae16df58c7f5b9a6b80827d788f7416afccbda..22f0c653284ca9b3386852537396bb8abb3e7f94 100644 GIT binary patch literal 17542 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 MKQVRI!ab7Xj@&-27XSbN diff --git a/reactos/dll/cpl/intl/resources/applet.ico b/reactos/dll/cpl/intl/resources/applet.ico index d668a0db539fae9b61243d802313436f2ff98a2e..d02ca6df98ba38c6059ef6f0e838f0fc9f2fb103 100644 GIT binary patch literal 17542 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 diff --git a/reactos/dll/cpl/intl_new/resources/applet.ico b/reactos/dll/cpl/intl_new/resources/applet.ico index d668a0db539fae9b61243d802313436f2ff98a2e..d02ca6df98ba38c6059ef6f0e838f0fc9f2fb103 100644 GIT binary patch literal 17542 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 diff --git a/reactos/dll/cpl/sysdm/resources/applet.ico b/reactos/dll/cpl/sysdm/resources/applet.ico index 71e43775c1a1bc393a41a795ddca800a5cf47d83..dac3ff0b85d840eddcacf8a7e47f5afac10c02f2 100644 GIT binary patch literal 17542 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 O>raaMz0Xc(2}MS8coeqR20SK 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 From eeef3f67ba2beebea90afd88cbd63a9515cf7774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 28 Sep 2006 16:33:12 +0000 Subject: [PATCH 358/488] Support mount manager in disk.sys svn path=/trunk/; revision=24286 --- reactos/drivers/storage/disk/disk.c | 131 +++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) diff --git a/reactos/drivers/storage/disk/disk.c b/reactos/drivers/storage/disk/disk.c index 2d5eb2b1381..a461d02b63e 100644 --- a/reactos/drivers/storage/disk/disk.c +++ b/reactos/drivers/storage/disk/disk.c @@ -16,8 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: services/storage/disk/disk.c @@ -31,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -849,6 +850,62 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, DiskData->HiddenSectors = PartitionEntry->HiddenSectors; DiskData->BootIndicator = PartitionEntry->BootIndicator; DiskData->DriveNotReady = FALSE; + + /* Tell mount manager that we have a new partition for him. This should be replaced + * by the registration of MOUNTDEV_MOUNTED_DEVICE_GUID interface on partition PDO. + */ + { + UNICODE_STRING MountManagerU = RTL_CONSTANT_STRING(MOUNTMGR_DEVICE_NAME); + IO_STATUS_BLOCK IoStatusBlock; + ULONG Length = strlen(NameBuffer2) * sizeof(WCHAR); + PMOUNTMGR_TARGET_NAME TargetName; + HANDLE hMountManager; + InitializeObjectAttributes( + &ObjectAttributes, + &MountManagerU, + 0, + NULL, + NULL); + Status = NtOpenFile(&hMountManager, FILE_READ_ACCESS, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtOpenFile(%wZ) failed with status 0x%08lx\n", &MountManagerU, Status); + } + else + { + TargetName = ExAllocatePool(PagedPool, FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Length + sizeof(UNICODE_NULL)); + if (!TargetName) + { + DPRINT("ExAllocatePool() failed\n"); + } + else + { + TargetName->DeviceNameLength = Length; + swprintf( + TargetName->DeviceName, + L"\\Device\\Harddisk%lu\\Partition%lu", + DiskNumber, + PartitionNumber + 1); + Status = NtDeviceIoControlFile( + hMountManager, + NULL, + NULL, + NULL, + &IoStatusBlock, + IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION, + TargetName, FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Length, + NULL, 0); + if (NT_SUCCESS(Status)) + Status = NtWaitForSingleObject(hMountManager, FALSE, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtDeviceIoControlFile() failed with status 0x%08lx\n", Status); + } + ExFreePool(TargetName); + } + NtClose(hMountManager); + } + } } else { @@ -1589,6 +1646,76 @@ DiskClassDeviceControl(IN PDEVICE_OBJECT DeviceObject, break; } + case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: + { + WCHAR NameBuffer[80]; + PMOUNTDEV_NAME pMountDevName; + ULONG NameLength; + DPRINT("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME\n"); + if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) + { + Status = STATUS_BUFFER_TOO_SMALL; + Information = 0; + } + else + { + pMountDevName = (PMOUNTDEV_NAME)Irp->AssociatedIrp.SystemBuffer; + swprintf(NameBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + DeviceExtension->DeviceNumber, + ((PDISK_DATA)(DeviceExtension + 1))->PartitionNumber); + NameLength = wcslen(NameBuffer) * sizeof(WCHAR); + pMountDevName->NameLength = NameLength; + if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTDEV_NAME, Name) + NameLength) + { + Information = sizeof(MOUNTDEV_NAME); + Status = STATUS_BUFFER_OVERFLOW; + } + else + { + RtlCopyMemory(pMountDevName->Name, NameBuffer, NameLength); + Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) + NameLength; + Status = STATUS_SUCCESS; + } + } + break; + } + + case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: + { + WCHAR NameBuffer[80]; + PMOUNTDEV_UNIQUE_ID pMountDevUniqueId; + ULONG UniqueIdLength; + DPRINT("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID\n"); + if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) + { + Status = STATUS_BUFFER_TOO_SMALL; + Information = 0; + } + else + { + pMountDevUniqueId = (PMOUNTDEV_UNIQUE_ID)Irp->AssociatedIrp.SystemBuffer; + swprintf(NameBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + DeviceExtension->DeviceNumber, + ((PDISK_DATA)(DeviceExtension + 1))->PartitionNumber); + UniqueIdLength = wcslen(NameBuffer) * sizeof(WCHAR); + pMountDevUniqueId->UniqueIdLength = UniqueIdLength; + if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueIdLength) + { + Information = sizeof(MOUNTDEV_UNIQUE_ID); + Status = STATUS_BUFFER_OVERFLOW; + } + else + { + RtlCopyMemory(pMountDevUniqueId->UniqueId, NameBuffer, UniqueIdLength); + Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueIdLength; + Status = STATUS_SUCCESS; + } + } + break; + } + default: /* Call the common device control function */ return(ScsiClassDeviceControl(DeviceObject, Irp)); From 9e939c11e91e18d2d3d758d669ca93e52023d29c Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 28 Sep 2006 18:32:09 +0000 Subject: [PATCH 359/488] fix a hidden bug in IntCreateBitmapIndirect svn path=/trunk/; revision=24287 --- reactos/subsystems/win32/win32k/objects/bitmaps.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/objects/bitmaps.c b/reactos/subsystems/win32/win32k/objects/bitmaps.c index 4ae2c8987bb..5d0947f28cc 100644 --- a/reactos/subsystems/win32/win32k/objects/bitmaps.c +++ b/reactos/subsystems/win32/win32k/objects/bitmaps.c @@ -437,7 +437,12 @@ IntCreateBitmapIndirect(CONST BITMAP *BM) Size.cx, Size.cy, BitsPixel, hBitmap); bmp = BITMAPOBJ_LockBitmap( hBitmap ); - /* FIXME - bmp can be NULL!!!!!! */ + if (bmp == NULL) + { + /* FIXME should we free the hBitmap or return it ?? */ + return 0; + } + bmp->flFlags = BITMAPOBJ_IS_APIBITMAP; BITMAPOBJ_UnlockBitmap( bmp ); From 2e3507e05d8dddc4630a2c147c40825f3326787c Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Thu, 28 Sep 2006 19:08:07 +0000 Subject: [PATCH 360/488] NtGdiCreateDIBitmap fixed 2 more hiden bugs (cause some crash/bsod) but not the bug I am searching for. svn path=/trunk/; revision=24288 --- reactos/subsystems/win32/win32k/objects/dibobj.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/objects/dibobj.c b/reactos/subsystems/win32/win32k/objects/dibobj.c index 18b2eff6058..ca3eaa4d891 100644 --- a/reactos/subsystems/win32/win32k/objects/dibobj.c +++ b/reactos/subsystems/win32/win32k/objects/dibobj.c @@ -793,7 +793,16 @@ HBITMAP STDCALL NtGdiCreateDIBitmap(HDC hDc, const BITMAPINFOHEADER *Header, PDC Dc; HBITMAP Bmp; - + if (Header == NULL) + { + return NULL; + } + + if (Header->biSize == 0) + { + return NULL; + } + if (NULL == hDc) { BITMAPINFOHEADER *change_Header = (BITMAPINFOHEADER *)Header; From 7c67a5ec0d66da005cd844bdbfd2b675193b1d1d Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 28 Sep 2006 20:05:17 +0000 Subject: [PATCH 361/488] Initial development of a devmgmt.msc clone. Unusable at the moment though. svn path=/trunk/; revision=24289 --- reactos/base/applications/devmgmt/En.rc | 72 +++ reactos/base/applications/devmgmt/about.c | 62 ++ reactos/base/applications/devmgmt/devmgmt.c | 67 ++ .../base/applications/devmgmt/devmgmt.rbuild | 28 + reactos/base/applications/devmgmt/devmgmt.rc | 29 + .../base/applications/devmgmt/enumdevices.c | 356 +++++++++++ reactos/base/applications/devmgmt/mainwnd.c | 590 ++++++++++++++++++ .../base/applications/devmgmt/manifest.xml | 23 + reactos/base/applications/devmgmt/misc.c | 261 ++++++++ reactos/base/applications/devmgmt/precomp.h | 102 +++ .../applications/devmgmt/res/computer.ico | Bin 0 -> 7886 bytes .../base/applications/devmgmt/res/exit.bmp | Bin 0 -> 822 bytes .../base/applications/devmgmt/res/help.bmp | Bin 0 -> 822 bytes .../applications/devmgmt/res/properties.bmp | Bin 0 -> 822 bytes .../base/applications/devmgmt/res/refresh.bmp | Bin 0 -> 822 bytes .../base/applications/devmgmt/res/root.bmp | Bin 0 -> 822 bytes reactos/base/applications/devmgmt/resource.h | 63 ++ 17 files changed, 1653 insertions(+) create mode 100644 reactos/base/applications/devmgmt/En.rc create mode 100644 reactos/base/applications/devmgmt/about.c create mode 100644 reactos/base/applications/devmgmt/devmgmt.c create mode 100644 reactos/base/applications/devmgmt/devmgmt.rbuild create mode 100644 reactos/base/applications/devmgmt/devmgmt.rc create mode 100644 reactos/base/applications/devmgmt/enumdevices.c create mode 100644 reactos/base/applications/devmgmt/mainwnd.c create mode 100644 reactos/base/applications/devmgmt/manifest.xml create mode 100644 reactos/base/applications/devmgmt/misc.c create mode 100644 reactos/base/applications/devmgmt/precomp.h create mode 100644 reactos/base/applications/devmgmt/res/computer.ico create mode 100644 reactos/base/applications/devmgmt/res/exit.bmp create mode 100644 reactos/base/applications/devmgmt/res/help.bmp create mode 100644 reactos/base/applications/devmgmt/res/properties.bmp create mode 100644 reactos/base/applications/devmgmt/res/refresh.bmp create mode 100644 reactos/base/applications/devmgmt/res/root.bmp create mode 100644 reactos/base/applications/devmgmt/resource.h diff --git a/reactos/base/applications/devmgmt/En.rc b/reactos/base/applications/devmgmt/En.rc new file mode 100644 index 00000000000..aee0a8fd9d7 --- /dev/null +++ b/reactos/base/applications/devmgmt/En.rc @@ -0,0 +1,72 @@ +IDR_MAINMENU MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "E&xit", IDC_EXIT + END + POPUP "Action" + BEGIN + MENUITEM "Print", IDC_PRINT, GRAYED + MENUITEM SEPARATOR + MENUITEM "Properties...", IDC_PROP + MENUITEM SEPARATOR + MENUITEM "Help", IDC_PROGHELP, GRAYED + END + POPUP "Help" + BEGIN + MENUITEM "Help", IDC_PROGHELP + MENUITEM "About", IDC_ABOUT + END +END + +IDR_POPUP MENU +BEGIN + POPUP "popup" + BEGIN + MENUITEM "Properties...", IDC_PROP, GRAYED + MENUITEM SEPARATOR + MENUITEM "Help", IDC_PROGHELP + END +END + +IDD_ABOUTBOX DIALOGEX 22,16,190,182 +CAPTION "About Device Manager" +FONT 8,"Tahoma",0,0 +STYLE WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME +BEGIN + LTEXT "Device Manager v0.1\nCopyright (C) 2006\nby Ged Murphy (gedmurphy@gmail.com)", IDC_STATIC, 48, 7, 130, 26 + PUSHBUTTON "Close", IDOK, 75, 162, 44, 15 + ICON IDI_MAIN_ICON, IDC_STATIC, 10, 10, 7, 30 + EDITTEXT IDC_LICENSE_EDIT, 8, 44, 174, 107, WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | ES_READONLY | ES_MULTILINE +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_LICENSE "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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TOOLTIP_PROP "Properties" + IDS_TOOLTIP_REFRESH "Refresh" + IDS_TOOLTIP_HELP "Help" + IDS_TOOLTIP_EXIT "Exit" +END + +/* Hints */ +STRINGTABLE DISCARDABLE +BEGIN + IDS_HINT_BLANK " " + IDS_HINT_EXIT " Exits the program." + IDS_HINT_REFRESH " Refresh the service list." + IDS_HINT_PROP " Open property sheet for the current selection." + IDS_HINT_HELP " Display help window." + IDS_HINT_ABOUT " About ReactOS Device Manager." + + IDS_HINT_SYS_RESTORE " Restores this window to normal size." + IDS_HINT_SYS_MOVE " Moves this window." + IDS_HINT_SYS_SIZE " Resizes this window." + IDS_HINT_SYS_MINIMIZE " Collapses this window to an icon." + IDS_HINT_SYS_MAXIMIZE " Expands this window to fill this screen." + IDS_HINT_SYS_CLOSE " Closes this window." +END diff --git a/reactos/base/applications/devmgmt/about.c b/reactos/base/applications/devmgmt/about.c new file mode 100644 index 00000000000..b7766d2efb5 --- /dev/null +++ b/reactos/base/applications/devmgmt/about.c @@ -0,0 +1,62 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/about.c + * PURPOSE: About dialog box message handler + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +BOOL CALLBACK +AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND hLicenseEditWnd; + HICON hIcon = NULL; + TCHAR strLicense[700]; + + switch (message) + { + case WM_INITDIALOG: + + hIcon = LoadImage(hInstance, + MAKEINTRESOURCE(IDI_MAIN_ICON), + IMAGE_ICON, + 16, + 16, + 0); + + SendMessage(hDlg, + WM_SETICON, + ICON_SMALL, + (LPARAM)hIcon); + + hLicenseEditWnd = GetDlgItem(hDlg, + IDC_LICENSE_EDIT); + + LoadString(hInstance, + IDS_LICENSE, + strLicense, + sizeof(strLicense) / sizeof(TCHAR)); + + SetWindowText(hLicenseEditWnd, + strLicense); + + return TRUE; + + case WM_COMMAND: + + if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) + { + DestroyIcon(hIcon); + EndDialog(hDlg, + LOWORD(wParam)); + return TRUE; + } + + break; + } + + return FALSE; +} diff --git a/reactos/base/applications/devmgmt/devmgmt.c b/reactos/base/applications/devmgmt/devmgmt.c new file mode 100644 index 00000000000..afb233b6176 --- /dev/null +++ b/reactos/base/applications/devmgmt/devmgmt.c @@ -0,0 +1,67 @@ +/* + * PROJECT: ReactOS Device Managment + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/devmgmt.c + * PURPOSE: Program HQ + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +HINSTANCE hInstance; +HANDLE ProcessHeap; + +int WINAPI +WinMain(HINSTANCE hThisInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + LPTSTR lpAppName; + HWND hMainWnd; + MSG Msg; + int Ret = 1; + INITCOMMONCONTROLSEX icex; + + hInstance = hThisInstance; + ProcessHeap = GetProcessHeap(); + + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES; + InitCommonControlsEx(&icex); + + if (!AllocAndLoadString(&lpAppName, + hInstance, + IDS_APPNAME)) + { + return 1; + } + + if (InitMainWindowImpl()) + { + hMainWnd = CreateMainWindow(lpAppName, + nCmdShow); + if (hMainWnd != NULL) + { + /* pump the message queue */ + while( GetMessage( &Msg, NULL, 0, 0 ) ) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + + } + + Ret = 0; + } + + UninitMainWindowImpl(); + } + + LocalFree((HLOCAL)lpAppName); + + return Ret; +} + + + diff --git a/reactos/base/applications/devmgmt/devmgmt.rbuild b/reactos/base/applications/devmgmt/devmgmt.rbuild new file mode 100644 index 00000000000..8448678cf78 --- /dev/null +++ b/reactos/base/applications/devmgmt/devmgmt.rbuild @@ -0,0 +1,28 @@ + + + + . + + + + + 0x600 + 0x501 + ntdll + setupapi + gdi32 + kernel32 + user32 + comctl32 + advapi32 + + about.c + devmgmt.c + enumdevices.c + mainwnd.c + misc.c + + devmgmt.rc + precomp.h + + diff --git a/reactos/base/applications/devmgmt/devmgmt.rc b/reactos/base/applications/devmgmt/devmgmt.rc new file mode 100644 index 00000000000..79667eed93c --- /dev/null +++ b/reactos/base/applications/devmgmt/devmgmt.rc @@ -0,0 +1,29 @@ +#include +#include +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Device Manager\0" +#define REACTOS_STR_INTERNAL_NAME "devmgmt\0" +#define REACTOS_STR_ORIGINAL_FILENAME "devmgmt.exe\0" +//#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +//1 24 DISCARDABLE "manifest.xml" + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APPNAME "ReactOS Device Manager" +END + +IDI_MAIN_ICON ICON "res/computer.ico" +IDB_ROOT_IMAGE BITMAP "res/root.bmp" + +/* main toolbar icons */ +IDB_PROP BITMAP DISCARDABLE "res/properties.bmp" +IDB_REFRESH BITMAP DISCARDABLE "res/refresh.bmp" +IDB_HELP BITMAP DISCARDABLE "res/help.bmp" +IDB_EXIT BITMAP DISCARDABLE "res/exit.bmp" + + +#include "En.rc" diff --git a/reactos/base/applications/devmgmt/enumdevices.c b/reactos/base/applications/devmgmt/enumdevices.c new file mode 100644 index 00000000000..e48d5a25480 --- /dev/null +++ b/reactos/base/applications/devmgmt/enumdevices.c @@ -0,0 +1,356 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/enumdevices.c + * PURPOSE: Enumerates all devices on the local machine + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +SP_CLASSIMAGELIST_DATA ImageListData; + + +static HTREEITEM +InsertIntoTreeView(HWND hTV, + HTREEITEM hRoot, + LPTSTR lpLabel, + INT DevImage) +{ + TV_ITEM tvi; + TV_INSERTSTRUCT tvins; + + ZeroMemory(&tvi, sizeof(tvi)); + ZeroMemory(&tvins, sizeof(tvins)); + + tvi.mask = TVIF_TEXT | TVIF_IMAGE; + tvi.pszText = lpLabel; + tvi.cchTextMax = lstrlen(lpLabel); + tvi.iImage = DevImage; + tvi.iSelectedImage = DevImage; + + tvins.item = tvi; + tvins.hInsertAfter = hRoot; + + return TreeView_InsertItem(hTV, &tvins); +} + + +static INT +EnumDeviceClasses(INT ClassIndex, + TCHAR *DeviceClassName, + TCHAR *DeviceClassDesc, + BOOL *DevicePresent, + INT *ClassImage) +{ + GUID ClassGuid; + HKEY KeyClass; + HDEVINFO hDevInfo; + TCHAR ClassName[MAX_CLASS_NAME_LEN]; + DWORD RequiredSize = MAX_CLASS_NAME_LEN; + UINT Ret; + + *DevicePresent = FALSE; + + Ret = CM_Enumerate_Classes(ClassIndex, + &ClassGuid, + 0); + if (Ret != CR_SUCCESS) + { + /* all classes enumerated */ + if(Ret == CR_NO_SUCH_VALUE) + return -1; + + if (Ret == CR_INVALID_DATA) + ; /*FIXME: what should we do here? */ + + /* handle other errors... */ + } + + if (SetupDiClassNameFromGuid(&ClassGuid, + ClassName, + RequiredSize, + &RequiredSize)) + { + lstrcpy(DeviceClassName, ClassName); + } + else + { + *DeviceClassName = _T('\0'); + } + + if (!SetupDiGetClassImageIndex(&ImageListData, + &ClassGuid, + ClassImage)) + { + /* set the blank icon */ + *ClassImage = 41; + } + + /* FIXME: why are we calling this here? */ + hDevInfo = SetupDiGetClassDevs(&ClassGuid, + 0, + NULL, + DIGCF_PRESENT); + if (hDevInfo == INVALID_HANDLE_VALUE) + return -2; + + KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, + MAXIMUM_ALLOWED, + DIOCR_INSTALLER, + NULL, + 0); + if (KeyClass != INVALID_HANDLE_VALUE) + { + DWORD dwSize = MAX_CLASS_NAME_LEN; + + if (RegQueryValue(KeyClass, + NULL, + DeviceClassDesc, + &dwSize) != ERROR_SUCCESS) + { + *DeviceClassDesc = _T('\0'); + } + } + else + { + return -3; + } + + /* FIXME: Can we call this earlier, or see above? */ + SetupDiDestroyDeviceInfoList(hDevInfo); + + *DevicePresent = TRUE; + + RegCloseKey(KeyClass); + + return 0; +} + + +static INT +EnumDevices(INT index, + TCHAR* DeviceClassName, + TCHAR* DeviceName) +{ + HDEVINFO hDevInfo; + SP_DEVINFO_DATA DeviceInfoData; + DWORD RequiredSize = 0; + GUID *guids = NULL; + BOOL bRet; + + *DeviceName = _T('\0'); + + bRet = SetupDiClassGuidsFromName(DeviceClassName, + NULL, + RequiredSize, + &RequiredSize); + if (RequiredSize == 0) + return -2; + + if (!bRet) + { + guids = HeapAlloc(GetProcessHeap(), 0, RequiredSize); + if (guids == NULL) + return -1; + + bRet = SetupDiClassGuidsFromName(DeviceClassName, + guids, + RequiredSize, + &RequiredSize); + + if (!bRet || RequiredSize == 0) + { + /* incorrect class name */ + HeapFree(GetProcessHeap(), 0, guids); + return -3; + } + } + + /* get device info set for our device class */ + hDevInfo = SetupDiGetClassDevs(guids, + 0, + NULL, + DIGCF_PRESENT); + + HeapFree(GetProcessHeap(), 0, guids); + if(hDevInfo == INVALID_HANDLE_VALUE) + { + if(!bRet) + { + /* device info is unavailable */ + return -4; + } + } + + ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + bRet = SetupDiEnumDeviceInfo(hDevInfo, + index, + &DeviceInfoData); + + if (!bRet) + { + //no such device: + SetupDiDestroyDeviceInfoList(hDevInfo); + return -1; + } + + /* get the device's friendly name */ + if (!SetupDiGetDeviceRegistryProperty(hDevInfo, + &DeviceInfoData, + SPDRP_FRIENDLYNAME, + 0, + (BYTE*)DeviceName, + MAX_DEV_LEN, + NULL)) + { + /* if the friendly name fails, try the description instead */ + bRet = SetupDiGetDeviceRegistryProperty(hDevInfo, + &DeviceInfoData, + SPDRP_DEVICEDESC, + 0, + (BYTE*)DeviceName, + MAX_DEV_LEN, + NULL); + if (!bRet) + { + /* if the description fails, just give up! */ + SetupDiDestroyDeviceInfoList(hDevInfo); + return -5; + } + } + + return 0; +} + + +VOID +ListDevicesByType(PMAIN_WND_INFO Info, + HTREEITEM hRoot) +{ + HTREEITEM hDevItem; + TCHAR DevName[MAX_DEV_LEN]; + TCHAR DevDesc[MAX_DEV_LEN]; + BOOL DevExist = FALSE; + INT ClassRet; + INT index = 0; + INT DevImage; + + do + { + ClassRet = EnumDeviceClasses(index, + DevName, + DevDesc, + &DevExist, + &DevImage); + + if ((ClassRet != -1) && (DevExist)) + { + TCHAR DeviceName[MAX_DEV_LEN]; + INT Ret, DevIndex = 0; + + if (DevDesc[0] != _T('\0')) + { + hDevItem = InsertIntoTreeView(Info->hTreeView, + hRoot, + DevDesc, + DevImage); + } + else + { + hDevItem = InsertIntoTreeView(Info->hTreeView, + hRoot, + DevName, + DevImage); + } + + do + { + Ret = EnumDevices(DevIndex, + DevName, + DeviceName); + if (Ret == 0) + { + InsertIntoTreeView(Info->hTreeView, + hDevItem, + DeviceName, + DevImage); + } + + DevIndex++; + + } while (Ret != -1); + + if (!TreeView_GetChild(Info->hTreeView, + hDevItem)) + { + TreeView_DeleteItem(Info->hTreeView, + hDevItem); + } + else + { + TreeView_SortChildren(Info->hTreeView, + hDevItem, + 0); + } + } + + index++; + + } while (ClassRet != -1); + + TreeView_Expand(Info->hTreeView, + hRoot, + TVE_EXPAND); + + TreeView_SortChildren(Info->hTreeView, + hRoot, + 0); +} + + +HTREEITEM +InitTreeView(PMAIN_WND_INFO Info) +{ + HTREEITEM hRoot; + HBITMAP hComp; + TCHAR ComputerName[MAX_PATH]; + DWORD dwSize = MAX_PATH; + INT RootImage; + //COLORREF Mask = RGB(255, 0, 128); + + TreeView_DeleteAllItems(Info->hTreeView); + + /* get the device image List */ + ImageListData.cbSize = sizeof(ImageListData); + SetupDiGetClassImageList(&ImageListData); + + hComp = LoadBitmap(hInstance, + MAKEINTRESOURCE(IDB_ROOT_IMAGE)); + + ImageList_Add(ImageListData.ImageList, + hComp, + NULL); + + TreeView_SetImageList(Info->hTreeView, + &ImageListData.ImageList, + TVSIL_NORMAL); + + if (!GetComputerName(ComputerName, + &dwSize)) + { + ComputerName[0] = _T('\0'); + } + + RootImage = ImageList_GetImageCount(ImageListData.ImageList) - 1; + + hRoot = InsertIntoTreeView(Info->hTreeView, + NULL, + ComputerName, + RootImage); + + return hRoot; +} diff --git a/reactos/base/applications/devmgmt/mainwnd.c b/reactos/base/applications/devmgmt/mainwnd.c new file mode 100644 index 00000000000..a62540c95f4 --- /dev/null +++ b/reactos/base/applications/devmgmt/mainwnd.c @@ -0,0 +1,590 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/mainwnd.c + * PURPOSE: Main window message handler + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +static const TCHAR szMainWndClass[] = TEXT("DevMgmtWndClass"); + +/* Toolbar buttons */ +TBBUTTON Buttons [] = +{ /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */ + {TBICON_PROP, IDC_PROP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* properties */ + {TBICON_REFRESH, IDC_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* refresh */ + + /* Note: First item for a seperator is its width in pixels */ + {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */ + + {TBICON_HELP, IDC_PROGHELP,TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* help */ + {TBICON_EXIT, IDC_EXIT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* exit */ + +}; + + +/* menu hints */ +static const MENU_HINT MainMenuHintTable[] = { + /* File Menu */ + {IDC_EXIT, IDS_HINT_EXIT}, + + /* Action Menu */ + {IDC_REFRESH, IDS_HINT_REFRESH}, + {IDC_PROP, IDS_HINT_PROP}, + + /* Help Menu */ + {IDC_PROGHELP, IDS_HINT_HELP}, + {IDC_ABOUT, IDS_HINT_ABOUT} +}; +/* system menu hints */ +static const MENU_HINT SystemMenuHintTable[] = { + {SC_RESTORE, IDS_HINT_SYS_RESTORE}, + {SC_MOVE, IDS_HINT_SYS_MOVE}, + {SC_SIZE, IDS_HINT_SYS_SIZE}, + {SC_MINIMIZE, IDS_HINT_SYS_MINIMIZE}, + {SC_MAXIMIZE, IDS_HINT_SYS_MAXIMIZE}, + {SC_CLOSE, IDS_HINT_SYS_CLOSE}, +}; + + +static BOOL +MainWndMenuHint(PMAIN_WND_INFO Info, + WORD CmdId, + const MENU_HINT *HintArray, + DWORD HintsCount, + UINT DefHintId) +{ + BOOL Found = FALSE; + const MENU_HINT *LastHint; + UINT HintId = DefHintId; + + LastHint = HintArray + HintsCount; + while (HintArray != LastHint) + { + if (HintArray->CmdId == CmdId) + { + HintId = HintArray->HintId; + Found = TRUE; + break; + } + HintArray++; + } + + StatusBarLoadString(Info->hStatus, + SB_SIMPLEID, + hInstance, + HintId); + + return Found; +} + + +static VOID +UpdateMainStatusBar(PMAIN_WND_INFO Info) +{ + if (Info->hStatus != NULL) + { + SendMessage(Info->hStatus, + SB_SIMPLE, + (WPARAM)Info->InMenuLoop, + 0); + } +} + + +static BOOL +CreateToolbar(PMAIN_WND_INFO Info) +{ + INT NumButtons = sizeof(Buttons) / sizeof(Buttons[0]); + + Info->hTool = CreateWindowEx(0, + TOOLBARCLASSNAME, + NULL, + WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, + 0, 0, 0, 0, + Info->hMainWnd, + (HMENU)IDC_TOOLBAR, + hInstance, + NULL); + if(Info->hTool != NULL) + { + HIMAGELIST hImageList; + + SendMessage(Info->hTool, + TB_SETEXTENDEDSTYLE, + 0, + TBSTYLE_EX_HIDECLIPPEDBUTTONS); + + SendMessage(Info->hTool, + TB_BUTTONSTRUCTSIZE, + sizeof(Buttons[0]), + 0); + + hImageList = InitImageList(IDB_PROP, + IDB_EXIT, + 16, + 16); + if (hImageList == NULL) + return FALSE; + + ImageList_Destroy((HIMAGELIST)SendMessage(Info->hTool, + TB_SETIMAGELIST, + 0, + (LPARAM)hImageList)); + + SendMessage(Info->hTool, + TB_ADDBUTTONS, + NumButtons, + (LPARAM)Buttons); + + return TRUE; + } + + return FALSE; +} + + +static BOOL +CreateTreeView(PMAIN_WND_INFO Info) +{ + Info->hTreeView = CreateWindowEx(0, + WC_TREEVIEW, + NULL, + WS_CHILD | WS_VISIBLE | WS_BORDER | + TVS_HASLINES | TVS_HASBUTTONS | TVS_SHOWSELALWAYS, + 0, 0, 0, 0, + Info->hMainWnd, + (HMENU) IDC_TREEVIEW, + hInstance, + NULL); + if (Info->hTreeView == NULL) + { + DisplayString(_T("Could not create TreeView.")); + return FALSE; + } + + return TRUE; +} + +static BOOL +CreateStatusBar(PMAIN_WND_INFO Info) +{ + INT StatWidths[] = {110, -1}; /* widths of status bar */ + + Info->hStatus = CreateWindowEx(0, + STATUSCLASSNAME, + NULL, + WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, + 0, 0, 0, 0, + Info->hMainWnd, + (HMENU)IDC_STATUSBAR, + hInstance, + NULL); + if(Info->hStatus == NULL) + return FALSE; + + + SendMessage(Info->hStatus, + SB_SETPARTS, + sizeof(StatWidths) / sizeof(INT), + (LPARAM)StatWidths); + + return TRUE; +} + + + +static VOID +InitMainWnd(PMAIN_WND_INFO Info) +{ + HTREEITEM hRoot; + + if (!CreateToolbar(Info)) + DisplayString(_T("error creating toolbar")); + + if (!CreateTreeView(Info)) + { + DisplayString(_T("error creating list view")); + return; + } + + if (!CreateStatusBar(Info)) + DisplayString(_T("error creating status bar")); + + /* Create Popup Menu */ + Info->hShortcutMenu = LoadMenu(hInstance, + MAKEINTRESOURCE(IDR_POPUP)); + Info->hShortcutMenu = GetSubMenu(Info->hShortcutMenu, + 0); + + hRoot = InitTreeView(Info); + if (hRoot) + ListDevicesByType(Info, hRoot); +} + + +static VOID +MainWndCommand(PMAIN_WND_INFO Info, + WORD CmdId, + HWND hControl) +{ + UNREFERENCED_PARAMETER(hControl); + + switch (CmdId) + { + case IDC_PROP: + { + // call builtin driver prop sheet + } + break; + + case IDC_REFRESH: + { + // refresh treeview + } + break; + + case IDC_PROGHELP: + DisplayString(_T("Help is not yet implemented\n")); + SetFocus(Info->hTreeView); + break; + + case IDC_EXIT: + PostMessage(Info->hMainWnd, + WM_CLOSE, + 0, + 0); + break; + + case IDC_ABOUT: + DialogBox(hInstance, + MAKEINTRESOURCE(IDD_ABOUTBOX), + Info->hMainWnd, + (DLGPROC)AboutDialogProc); + SetFocus(Info->hTreeView); + break; + + } +} + + +static VOID CALLBACK +MainWndResize(PMAIN_WND_INFO Info, + WORD cx, + WORD cy) +{ + RECT rcClient, rcTool, rcStatus; + int lvHeight, iToolHeight, iStatusHeight; + + /* Size toolbar and get height */ + SendMessage(Info->hTool, TB_AUTOSIZE, 0, 0); + GetWindowRect(Info->hTool, &rcTool); + iToolHeight = rcTool.bottom - rcTool.top; + + /* Size status bar and get height */ + SendMessage(Info->hStatus, WM_SIZE, 0, 0); + GetWindowRect(Info->hStatus, &rcStatus); + iStatusHeight = rcStatus.bottom - rcStatus.top; + + /* Calculate remaining height and size list view */ + GetClientRect(Info->hMainWnd, &rcClient); + lvHeight = rcClient.bottom - iToolHeight - iStatusHeight; + SetWindowPos(Info->hTreeView, + NULL, + 0, + iToolHeight, + rcClient.right, + lvHeight, + SWP_NOZORDER); +} + + +static LRESULT CALLBACK +MainWndProc(HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + PMAIN_WND_INFO Info; + LRESULT Ret = 0; + + /* Get the window context */ + Info = (PMAIN_WND_INFO)GetWindowLongPtr(hwnd, + GWLP_USERDATA); + if (Info == NULL && msg != WM_CREATE) + { + goto HandleDefaultMessage; + } + + switch(msg) + { + case WM_CREATE: + { + Info = (PMAIN_WND_INFO)(((LPCREATESTRUCT)lParam)->lpCreateParams); + + /* Initialize the main window context */ + Info->hMainWnd = hwnd; + + SetWindowLongPtr(hwnd, + GWLP_USERDATA, + (LONG_PTR)Info); + + InitMainWnd(Info); + + /* Show the window */ + ShowWindow(hwnd, + Info->nCmdShow); + + } + break; + + case WM_SIZE: + { + MainWndResize(Info, + LOWORD(lParam), + HIWORD(lParam)); + } + break; + + case WM_NOTIFY: + { + LPNMHDR pnmhdr = (LPNMHDR)lParam; + + switch (pnmhdr->code) + { + case NM_DBLCLK: + { + POINT pt; + RECT rect; + + GetCursorPos(&pt); + GetWindowRect(Info->hTreeView, &rect); + + if (PtInRect(&rect, pt)) + { + SendMessage(hwnd, + WM_COMMAND, + //ID_PROP, + MAKEWPARAM((WORD)IDC_PROP, (WORD)0), + 0); + } + + //OpenPropSheet(Info); + } + break; + + case TTN_GETDISPINFO: + { + LPTOOLTIPTEXT lpttt; + UINT idButton; + + lpttt = (LPTOOLTIPTEXT)lParam; + + /* Specify the resource identifier of the descriptive + * text for the given button. */ + idButton = (UINT)lpttt->hdr.idFrom; + switch (idButton) + { + case IDC_PROP: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP); + break; + + case IDC_REFRESH: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH); + break; + + case IDC_PROGHELP: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_HELP); + break; + + case IDC_EXIT: + lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT); + break; + + } + } + break; + } + } + break; + + case WM_CONTEXTMENU: + { + POINT pt; + RECT lvRect; + + INT xPos = GET_X_LPARAM(lParam); + INT yPos = GET_Y_LPARAM(lParam); + + GetCursorPos(&pt); + + /* display popup when cursor is in the list view */ + GetWindowRect(Info->hTreeView, &lvRect); + if (PtInRect(&lvRect, pt)) + { + TrackPopupMenuEx(Info->hShortcutMenu, + TPM_RIGHTBUTTON, + xPos, + yPos, + Info->hMainWnd, + NULL); + } + } + break; + + case WM_COMMAND: + { + MainWndCommand(Info, + LOWORD(wParam), + (HWND)lParam); + goto HandleDefaultMessage; + } + + case WM_MENUSELECT: + { + if (Info->hStatus != NULL) + { + if (!MainWndMenuHint(Info, + LOWORD(wParam), + MainMenuHintTable, + sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]), + IDS_HINT_BLANK)) + { + MainWndMenuHint(Info, + LOWORD(wParam), + SystemMenuHintTable, + sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]), + IDS_HINT_BLANK); + } + } + } + break; + + case WM_ENTERMENULOOP: + { + Info->InMenuLoop = TRUE; + UpdateMainStatusBar(Info); + break; + } + + case WM_EXITMENULOOP: + { + Info->InMenuLoop = FALSE; + UpdateMainStatusBar(Info); + break; + } + + case WM_CLOSE: + { + DestroyMenu(Info->hShortcutMenu); + DestroyWindow(hwnd); + } + break; + + case WM_DESTROY: + { + //DestroyMainWnd(Info); + + HeapFree(ProcessHeap, + 0, + Info); + SetWindowLongPtr(hwnd, + GWLP_USERDATA, + 0); + + /* Break the message queue loop */ + PostQuitMessage(0); + } + break; + + default: + { +HandleDefaultMessage: + + Ret = DefWindowProc(hwnd, + msg, + wParam, + lParam); + } + break; + } + return Ret; +} + + + +HWND +CreateMainWindow(LPCTSTR lpCaption, + int nCmdShow) +{ + PMAIN_WND_INFO Info; + HWND hMainWnd = NULL; + + Info = HeapAlloc(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(MAIN_WND_INFO)); + + if (Info != NULL) + { + Info->nCmdShow = nCmdShow; + + hMainWnd = CreateWindowEx(WS_EX_WINDOWEDGE, + szMainWndClass, + lpCaption, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + CW_USEDEFAULT, + CW_USEDEFAULT, + 650, + 450, + NULL, + NULL, + hInstance, + Info); + if (hMainWnd == NULL) + { + GetError(); + HeapFree(ProcessHeap, + 0, + Info); + } + } + + return hMainWnd; +} + +BOOL +InitMainWindowImpl(VOID) +{ + WNDCLASSEX wc = {0}; + + wc.cbSize = sizeof(WNDCLASSEX); + wc.lpfnWndProc = MainWndProc; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, + MAKEINTRESOURCE(IDI_MAIN_ICON)); + wc.hCursor = LoadCursor(NULL, + IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); + wc.lpszClassName = szMainWndClass; + wc.hIconSm = (HICON)LoadImage(hInstance, + MAKEINTRESOURCE(IDI_MAIN_ICON), + IMAGE_ICON, + 16, + 16, + LR_SHARED); + + return RegisterClassEx(&wc) != (ATOM)0; +} + + +VOID +UninitMainWindowImpl(VOID) +{ + UnregisterClass(szMainWndClass, + hInstance); +} + diff --git a/reactos/base/applications/devmgmt/manifest.xml b/reactos/base/applications/devmgmt/manifest.xml new file mode 100644 index 00000000000..4df22534fca --- /dev/null +++ b/reactos/base/applications/devmgmt/manifest.xml @@ -0,0 +1,23 @@ + + + +ReactOS Service Manager + + + + + + diff --git a/reactos/base/applications/devmgmt/misc.c b/reactos/base/applications/devmgmt/misc.c new file mode 100644 index 00000000000..3a24fe720bd --- /dev/null +++ b/reactos/base/applications/devmgmt/misc.c @@ -0,0 +1,261 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/devmgmt/misc.c + * PURPOSE: miscallanous functions + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ + +#include "precomp.h" + +static INT +LengthOfStrResource(IN HINSTANCE hInst, + IN UINT uID) +{ + HRSRC hrSrc; + HGLOBAL hRes; + LPWSTR lpName, lpStr; + + if (hInst == NULL) + { + return -1; + } + + /* There are always blocks of 16 strings */ + lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1); + + /* Find the string table block */ + if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) && + (hRes = LoadResource(hInst, hrSrc)) && + (lpStr = LockResource(hRes))) + { + UINT x; + + /* Find the string we're looking for */ + uID &= 0xF; /* position in the block, same as % 16 */ + for (x = 0; x < uID; x++) + { + lpStr += (*lpStr) + 1; + } + + /* Found the string */ + return (int)(*lpStr); + } + return -1; +} + +INT +AllocAndLoadString(OUT LPTSTR *lpTarget, + IN HINSTANCE hInst, + IN UINT uID) +{ + INT ln; + + ln = LengthOfStrResource(hInst, + uID); + if (ln++ > 0) + { + (*lpTarget) = (LPTSTR)LocalAlloc(LMEM_FIXED, + ln * sizeof(TCHAR)); + if ((*lpTarget) != NULL) + { + INT Ret; + if (!(Ret = LoadString(hInst, uID, *lpTarget, ln))) + { + LocalFree((HLOCAL)(*lpTarget)); + } + return Ret; + } + } + return 0; +} + +DWORD +LoadAndFormatString(IN HINSTANCE hInstance, + IN UINT uID, + OUT LPTSTR *lpTarget, + ...) +{ + DWORD Ret = 0; + LPTSTR lpFormat; + va_list lArgs; + + if (AllocAndLoadString(&lpFormat, + hInstance, + uID) > 0) + { + va_start(lArgs, lpTarget); + /* let's use FormatMessage to format it because it has the ability to allocate + memory automatically */ + Ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, + lpFormat, + 0, + 0, + (LPTSTR)lpTarget, + 0, + &lArgs); + va_end(lArgs); + + LocalFree((HLOCAL)lpFormat); + } + + return Ret; +} + +BOOL +StatusBarLoadAndFormatString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID, + ...) +{ + BOOL Ret = FALSE; + LPTSTR lpFormat, lpStr; + va_list lArgs; + + if (AllocAndLoadString(&lpFormat, + hInstance, + uID) > 0) + { + va_start(lArgs, uID); + /* let's use FormatMessage to format it because it has the ability to allocate + memory automatically */ + Ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, + lpFormat, + 0, + 0, + (LPTSTR)&lpStr, + 0, + &lArgs); + va_end(lArgs); + + if (lpStr != NULL) + { + Ret = (BOOL)SendMessage(hStatusBar, + SB_SETTEXT, + (WPARAM)PartId, + (LPARAM)lpStr); + LocalFree((HLOCAL)lpStr); + } + + LocalFree((HLOCAL)lpFormat); + } + + return Ret; +} + +BOOL +StatusBarLoadString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID) +{ + BOOL Ret = FALSE; + LPTSTR lpStr; + + if (AllocAndLoadString(&lpStr, + hInstance, + uID) > 0) + { + Ret = (BOOL)SendMessage(hStatusBar, + SB_SETTEXT, + (WPARAM)PartId, + (LPARAM)lpStr); + LocalFree((HLOCAL)lpStr); + } + + return Ret; +} + + +INT +GetTextFromEdit(OUT LPTSTR lpString, + IN HWND hDlg, + IN UINT Res) +{ + INT len = GetWindowTextLength(GetDlgItem(hDlg, Res)); + if(len > 0) + { + GetDlgItemText(hDlg, + Res, + lpString, + len + 1); + } + else + lpString = NULL; + + return len; +} + + +HIMAGELIST +InitImageList(UINT StartResource, + UINT EndResource, + UINT Width, + UINT Height) +{ + HBITMAP hBitmap; + HIMAGELIST hImageList; + UINT i; + INT Ret; + + /* Create the toolbar icon image list */ + hImageList = ImageList_Create(Width, + Height, + ILC_MASK | ILC_COLOR24, + EndResource - StartResource, + 0); + if (hImageList == NULL) + return NULL; + + /* Add all icons to the image list */ + for (i = StartResource; i <= EndResource; i++) + { + hBitmap = LoadImage(hInstance, + MAKEINTRESOURCE(i), + IMAGE_BITMAP, + Width, + Height, + LR_LOADTRANSPARENT); + if (hBitmap == NULL) + return NULL; + + Ret = ImageList_AddMasked(hImageList, + hBitmap, + RGB(255, 0, 128)); + if (Ret == -1) + return NULL; + + DeleteObject(hBitmap); + } + + return hImageList; +} + + +VOID GetError(VOID) +{ + LPVOID lpMsgBuf; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + + MessageBox(NULL, lpMsgBuf, _T("Error!"), MB_OK | MB_ICONERROR); + + LocalFree(lpMsgBuf); +} + + +VOID DisplayString(PTCHAR Msg) +{ + MessageBox(NULL, Msg, _T("Note!"), MB_ICONEXCLAMATION|MB_OK); +} + diff --git a/reactos/base/applications/devmgmt/precomp.h b/reactos/base/applications/devmgmt/precomp.h new file mode 100644 index 00000000000..52c6c82c602 --- /dev/null +++ b/reactos/base/applications/devmgmt/precomp.h @@ -0,0 +1,102 @@ +#ifndef __DEVMGMT_PRECOMP_H +#define __DEVMGMT_PRECOMP_H + +//#define WIN32_LEAN_AND_MEAN +#include +#include /* GET_X/Y_LPARAM */ +#include +#include +#include +#include +#include +#include "resource.h" + +#ifdef _MSC_VER +#pragma warning(disable : 4100) +#endif + +#ifndef SB_SIMPLEID +#define SB_SIMPLEID 0xFF +#endif + +#define NO_ITEM_SELECTED -1 +#define MAX_KEY_LENGTH 256 +#define MAX_DEV_LEN 1000 + + +typedef struct _MAIN_WND_INFO +{ + HWND hMainWnd; + HWND hTreeView; + HWND hStatus; + HWND hTool; + HWND hProgDlg; + HMENU hShortcutMenu; + int nCmdShow; + + /* status flags */ + BOOL InMenuLoop : 1; + +} MAIN_WND_INFO, *PMAIN_WND_INFO; + + +BOOL CALLBACK AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + + +/* servman.c */ +extern HINSTANCE hInstance; +extern HANDLE ProcessHeap; + +/* mainwnd.c */ +typedef struct _MENU_HINT +{ + WORD CmdId; + UINT HintId; +} MENU_HINT, *PMENU_HINT; + +BOOL InitMainWindowImpl(VOID); +VOID UninitMainWindowImpl(VOID); +HWND CreateMainWindow(LPCTSTR lpCaption, int nCmdShow); + + +/* enumdevices.c */ +HTREEITEM InitTreeView(PMAIN_WND_INFO Info); +VOID ListDevicesByType(PMAIN_WND_INFO Info, HTREEITEM hRoot); + + +/* misc.c */ +INT AllocAndLoadString(OUT LPTSTR *lpTarget, + IN HINSTANCE hInst, + IN UINT uID); + +DWORD LoadAndFormatString(IN HINSTANCE hInstance, + IN UINT uID, + OUT LPTSTR *lpTarget, + ...); + +BOOL StatusBarLoadAndFormatString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID, + ...); + +BOOL StatusBarLoadString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID); + +INT GetTextFromEdit(OUT LPTSTR lpString, + IN HWND hDlg, + IN UINT Res); + +VOID GetError(VOID); + +VOID DisplayString(PTCHAR); + +HIMAGELIST InitImageList(UINT NumButtons, + UINT StartResource, + UINT Width, + UINT Height); + + +#endif /* __DEVMGMT_PRECOMP_H */ diff --git a/reactos/base/applications/devmgmt/res/computer.ico b/reactos/base/applications/devmgmt/res/computer.ico new file mode 100644 index 0000000000000000000000000000000000000000..deb7f520f20ffe7a1d9e8b5e5ca499021bc72119 GIT binary patch literal 7886 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 Z`YZT)z9l*4_49pM6@5*A8z{|){sTa=A_xEg literal 0 HcmV?d00001 diff --git a/reactos/base/applications/devmgmt/res/exit.bmp b/reactos/base/applications/devmgmt/res/exit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..97381f1f6f774edb3d5d4524d0da52d58e62b7d9 GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C7H0s;U*m;fhyVja1H*qa6FuS)ME%iYNB8XATT@dB z)F|o@!5Gj0K}?bT$OtG4QNMTJ-bITRZQs8Az`=tMU2-lF3=ZiaVaB->SxcMJ!{siDO09&c6I_aR#cWrN{Sg8 z8$uAW`hb8tKrKM^GiJ<~G-*;xYfD{SU4B70l`AbReL%&Pm6b(BMcLWeF)=aW;o*M%{=&k7nCACR>@O%T%+Ag6 f4+`+{^>uV|G&V8T)zec^QQ_w1#8eLqSRxSs(y#Wa literal 0 HcmV?d00001 diff --git a/reactos/base/applications/devmgmt/res/help.bmp b/reactos/base/applications/devmgmt/res/help.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4c958c2e9a056ae052583c47732d8e960dc603e2 GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C7H0s;3voj*M1X;zf#E+K?c2R$Sy$QgZ13)1Z6KPN z5~99Z9$H8DbedV&Seisfa2Pp+JJdhOJfwxn(C z$veB#clBjm+%)^y^)oYae7XWPzkYZ-CC;KRSZhkO@ysNv`I%0i-@X7k>B80p8|tGr zHOFmfP1rl7^vCB9-9g$A^^;@Fy8Klqgy~L=HJO!cy|p{{&+niA{{1^Rw`omP$l98) z?Y%kQKfmt|(t@~WO;c*SmqK@dI!H^53DA~93p;^Ue17v{X_5D`V&B6H+a6vzHa*K5 z7@>!kPPnjhB~U#O&Cl~*kncMs+Gs^pBvAd|Kff2|y3NmWzIAN-v6WMSib3HSW%BXW z)1?&=K=m6sa{m4O`|{qkZ=c=+)!#X_cSeH6=FV(jfcHllL(&E?C9G~t{q*|zvWmz# zneO+_9s2(H!^c<8F6>wiv}l1;>AV~rk(ZKYuqBj1+i^o8R0sS&9!5WBw zjElQgeR%m~MO^|=0X#hbbphEx?LZq3F6_O1a_^V-uYm~2IJl^{Kf(x@V2~BV6CNbG SfguJAWFP`EARdG(05SmSGt!Cx literal 0 HcmV?d00001 diff --git a/reactos/base/applications/devmgmt/res/properties.bmp b/reactos/base/applications/devmgmt/res/properties.bmp new file mode 100644 index 0000000000000000000000000000000000000000..15e080ec9234c1662b775c1133b2f78bbb7c493c GIT binary patch literal 822 zcmb7?v2KGf6h$3%%o26#C*%wA0ol8kl_3%lJ8LqqBX*doC=EqoL5i4xWawleCI)7p zw11G^`ZWj%Crys9Wtq#peh<%|XAev;!#u^9{EZQN68jAAAICIkgRvDm-TS<5w(A?% zyzR&t+S3g{*4KXu+P3`?d<)95^nE{yBKQsUX__7cM?n~dwr#tv>v`T#-!u&p;7<`* zmKla&nxxHIaeMO%n30l;zf;uMkuc``10_P%rv#4X2^l=;`f>Pj2;D<={I4UB#6a--h XAVR7~$F9@ehpqRH^}ht+9{24BrGpYR literal 0 HcmV?d00001 diff --git a/reactos/base/applications/devmgmt/res/refresh.bmp b/reactos/base/applications/devmgmt/res/refresh.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e7c12bbd3025cd7bbad4290c926fada655fee3aa GIT binary patch literal 822 zcmZ8fSx*yD6t3~n7vqyZ!5^Rnv1QS?Z(vL`QR7P4rUe@m5hO^^unGlf3zHbj&C?OEk3;ycbWZ;pxd^0wBV5IT3T7FzroH_L1jJ{nqWgq7O5GV@| z8oH|?u+jabEYH|@&4)JzjjuxH*MZ>{M~{ravaLgJd5WqibL{y|s=7d5cRAuVtbO5D zW^55oyT}aqsV1MQA)t8y6bEBL6uji{&uDN~-}5K_?f3U^a>47TJ9IS#cyR`l@RBUG zRIGh;PTyXR@SrojzMNW%q>|BPzg<^*iLSdkY1Tv4tW;3)lg8SMMClQ{Gz;OCMHzrk z%(1KUoU-r`U{D^s(=$z$ALB;eSi9tK%q_e`m`cXd$yjPFI%j$ZcjDySJOu*I>)}{N zDG{P1=z+EyCIJ(wiZV0}x3=SV#7>WQM+Sa%?G+$EQ*~DRIDf-x^0(_@R0__;y4)U~ z2!qqqU;jjRrq@?~Er;NM1SUdNWucJ7L@sp~dH=+eo#81KvKJJ_=Uj=P6K;>d#Hd6{ zbEt|uH6|uyxu*VB*2yxXYWm3)ORFRinocE_pg9=%A8$}RoK%#4=#`UYB4|jIiN>1m z&RYjzh@b=}=p&j}gC9vO8})ZgSO{rOfNonD?+Y`7F^?f0m{<>ce=L1o@lU{EHBWC0 zSDu0~@lwY%@8N~OE&*-FR|mOhCueotmX>>jG}lJ;0nCEG2ASxRodosZd&40UsnHDi5)>f>uieOX*|o%ze{VV&lSuhyhs` zH8Dmv8kZVHO-#$PR?&daa-sBLDbn`d@d!-LoSd2OJ2T%oGt~{{d&{;*IrsxG_wCL- zW&5}H%Xaad#f~S)EeeF?2<8Z4Ifmmg7739=G3fDPK@NHe_97(7B4#{(iIZf0E;>CE zodt`=Vl#8mui;2E_B|Y#2~SSVM!$WZpa1b|erk4l{$~smpHCwFXdtthP3KbKsfdzX zO=Z(7$;5gl1;NM96R+RCc|Y-PA+gB$1t)fAX#vSBC$XZ4eFJ@=08fxp;N7z5b@w|4 zIdABWjF1cSOdoRPXlaA0LQt9xf5|JqX)*hEIYv_pbR$mFi!>Lfe-c{q_vY$SY&L=f zoTu6*RUwz=(r0xQR^!oY^_AC8Rki32UN#->G#t8Ws<={D*;ZFwSXU71%hOVUYAoZS znYAucjo98aWN8Z6PKO-l0^LnwXFV+McC}h-t5ju476_2RM2^vvr5onzmxAkIPkYeP zz;_s=4r8e6OrWh^INxydL=8?!VjCEtD~+V9_P8R~9?tYGI! z+-$yPJ`Q{adqF>#+tW|eip8jV!aK(Xu0HqQ8fUv6i}pvz=D&OzUu*=3rdD`?0J%st zcw(B%bm%LGo%R<&?})d14BJPU>*K8Bx!=uSY6eJMTY<*~vPRWGp3rQ{V%ComSLmj7 z1UVjH$FRpf#`fOpu{~s*wgzKqH6e4jq!uaFf-IYlFI_O`+w{k*rfREM*IIi7yv0-n zCwCZht#t;PNewa#kZGwXV?6okgPLC7QsST!N-HUgG`URI;@WzmlvE1I)rIJch!E9O zNa1)E6Na!Dejqdr Date: Thu, 28 Sep 2006 21:15:51 +0000 Subject: [PATCH 362/488] clean up irregularities svn path=/trunk/; revision=24290 --- reactos/base/applications/devmgmt/about.c | 2 +- reactos/base/applications/devmgmt/devmgmt.rbuild | 12 ++++++------ reactos/base/applications/devmgmt/devmgmt.rc | 4 ++-- reactos/base/applications/devmgmt/enumdevices.c | 2 +- reactos/base/applications/devmgmt/mainwnd.c | 2 +- reactos/base/applications/devmgmt/misc.c | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/reactos/base/applications/devmgmt/about.c b/reactos/base/applications/devmgmt/about.c index b7766d2efb5..1e798a785bd 100644 --- a/reactos/base/applications/devmgmt/about.c +++ b/reactos/base/applications/devmgmt/about.c @@ -1,5 +1,5 @@ /* - * PROJECT: ReactOS Services + * PROJECT: ReactOS Device Managment * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/devmgmt/about.c * PURPOSE: About dialog box message handler diff --git a/reactos/base/applications/devmgmt/devmgmt.rbuild b/reactos/base/applications/devmgmt/devmgmt.rbuild index 8448678cf78..f126ab078bf 100644 --- a/reactos/base/applications/devmgmt/devmgmt.rbuild +++ b/reactos/base/applications/devmgmt/devmgmt.rbuild @@ -2,12 +2,12 @@ . - - - - - 0x600 - 0x501 + + + + + 0x600 + 0x501 ntdll setupapi gdi32 diff --git a/reactos/base/applications/devmgmt/devmgmt.rc b/reactos/base/applications/devmgmt/devmgmt.rc index 79667eed93c..9821767f69c 100644 --- a/reactos/base/applications/devmgmt/devmgmt.rc +++ b/reactos/base/applications/devmgmt/devmgmt.rc @@ -5,11 +5,11 @@ #define REACTOS_STR_FILE_DESCRIPTION "ReactOS Device Manager\0" #define REACTOS_STR_INTERNAL_NAME "devmgmt\0" #define REACTOS_STR_ORIGINAL_FILENAME "devmgmt.exe\0" -//#include +#include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -//1 24 DISCARDABLE "manifest.xml" +1 24 DISCARDABLE "manifest.xml" STRINGTABLE DISCARDABLE BEGIN diff --git a/reactos/base/applications/devmgmt/enumdevices.c b/reactos/base/applications/devmgmt/enumdevices.c index e48d5a25480..6dceb6061c1 100644 --- a/reactos/base/applications/devmgmt/enumdevices.c +++ b/reactos/base/applications/devmgmt/enumdevices.c @@ -1,5 +1,5 @@ /* - * PROJECT: ReactOS Services + * PROJECT: ReactOS Device Managment * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/devmgmt/enumdevices.c * PURPOSE: Enumerates all devices on the local machine diff --git a/reactos/base/applications/devmgmt/mainwnd.c b/reactos/base/applications/devmgmt/mainwnd.c index a62540c95f4..baf530a0d11 100644 --- a/reactos/base/applications/devmgmt/mainwnd.c +++ b/reactos/base/applications/devmgmt/mainwnd.c @@ -1,5 +1,5 @@ /* - * PROJECT: ReactOS Services + * PROJECT: ReactOS Device Managment * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/devmgmt/mainwnd.c * PURPOSE: Main window message handler diff --git a/reactos/base/applications/devmgmt/misc.c b/reactos/base/applications/devmgmt/misc.c index 3a24fe720bd..87f48ad1472 100644 --- a/reactos/base/applications/devmgmt/misc.c +++ b/reactos/base/applications/devmgmt/misc.c @@ -1,5 +1,5 @@ /* - * PROJECT: ReactOS Services + * PROJECT: ReactOS Device Managment * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/devmgmt/misc.c * PURPOSE: miscallanous functions From 4aa949d1df2ecc88e7e5ebbb64ce6092bf3931a0 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 28 Sep 2006 21:36:12 +0000 Subject: [PATCH 363/488] - Reserve enough space on the heap to store the GUID - Thanks to Thomas for restoring my sanity svn path=/trunk/; revision=24291 --- reactos/base/applications/devmgmt/enumdevices.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/reactos/base/applications/devmgmt/enumdevices.c b/reactos/base/applications/devmgmt/enumdevices.c index 6dceb6061c1..099d50b8545 100644 --- a/reactos/base/applications/devmgmt/enumdevices.c +++ b/reactos/base/applications/devmgmt/enumdevices.c @@ -151,7 +151,9 @@ EnumDevices(INT index, if (!bRet) { - guids = HeapAlloc(GetProcessHeap(), 0, RequiredSize); + guids = HeapAlloc(GetProcessHeap(), + 0, + RequiredSize * sizeof(GUID)); if (guids == NULL) return -1; From 0d942e1cef6114b45d908b7b7e066e324c51b153 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 28 Sep 2006 22:01:07 +0000 Subject: [PATCH 364/488] fix the floppy icons and add 2 new ones for network drives. svn path=/trunk/; revision=24292 --- reactos/dll/win32/shell32/res/icons/10.ico | Bin 17542 -> 17542 bytes reactos/dll/win32/shell32/res/icons/11.ico | Bin 17542 -> 17542 bytes reactos/dll/win32/shell32/res/icons/6.ico | Bin 17542 -> 17542 bytes reactos/dll/win32/shell32/res/icons/7.ico | Bin 17542 -> 17542 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/reactos/dll/win32/shell32/res/icons/10.ico b/reactos/dll/win32/shell32/res/icons/10.ico index b54e98d20bf3ea55ffbe3892088f464923ab4344..ed2f57ea02bd63a717f31f58dde4c611fb5f793a 100644 GIT binary patch literal 17542 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 Uh7aQUbBsq7!kmgdLS`|414?tSB>(^b literal 17542 zcmeHO2~?CDk)!IWv=VW~Q~1PHUg;j7CwSGKx!#TU??bQBjZ`WKqC<0XN)G z5fNmOeHGkr!wp0QR|I5>jRxFEYnyatGD%0HcfRkZek_Wrfq>CErm zMWgwpwMNquWk5pX05F|T5X$}k^Vih_qeqWEF?{%NF&868j=VQ)*sy>X)Ek|~k01XZ zW5$f}0kS^)@Wc91qek5W8h}3n_rdoAf_yJnu)u8i`T0F%S(Oe$E#1!%vYvZLD?t4r z9v&V)H?y6uczJnsb9HsKa&vS01my#PZFt}7?(TjG_#6;|JRo1Yz_KbGZP!^x8;WzU{HN?DZ-L((lNDY<{`+O?ZC zH8tgRb#+CxwYBNx<>hnCQ!Ypm_ZbLPyEdGqE8)};9Q`ii%=w=hi?K0ZFmH|8Ne{`lknLHXU- zgWkqo^ebK3>iY*DeDLPjv183$yT+RO3O@W4AU&L(nqLBM_vzDTy``n)lm7ktOTT{o z#KOWt*^3r0UM%+Z_Dz^MbEfi*d64%zYwQFC{__dbS>j-}ayb5#zI_klRuF(Bw zgd9iK_dB2u@IEjY7y*m{CcOLZy9&?PzXW@*f(a8Q$i#^gh2M~8A}|)9STO_`0FV}G zQbPE5;9r2h2iRxN^ZW#b*(dCqZa@#97hnmHZ}Ko6umNTO&OLhcQ24}{NZ-DFWze8O zGIZ!r!F&^bV;*28U<*tDJ_Ohf_62EE^yv<8j3E_4m@@OhoX<{iv5+4VQeFF1Bsp39 zzAa6`nv&pUizR8^SlRDCOfGGAeCar~YGPiBv&E6N^1o)y8d(*z9AnTAywBFdOK4BH z<73Q+Z`;a0_m8=A=SrHprCb32mm^)8V+Z0b;EXhL;e;|k#4}vNyCI~y^m`ER*^leO zSn0!M_#wcb1ZvIW2GnX^rqgXaLbjGYU_9GY^;xHHqNXa9O){t)%#kl=G2Z zQl7e~gWF(UUzDXRlKl%tmSPP%7-b$GF!!w>Gu3U}xKS1^TqyB#$I97l?oyexQm&;h zm-3XwQkodpLF3T&He5?vCb^5pRiXcRej9zjzcu9M&thU?BqSt65(6ek(RMGX%3dqi zGFCi8`ZA0O+LAP1u3~IEZf+TFQw8eITWtsaErN_Pj}PP@^44ctw{DfCOP5Nt-$XgH z-BYUetb4}0ZaetSaYMAw+HyY<(zddSPZCC0NWvn>&2+rlQD30pnq4e)mYKRLe1 zMQ$9A`C<6ijtBPv-94=;2m4?4dP#M+EH=eI?$tq%J?m3aQk4BObg7RVTsckZPN)2! z{BtaH+fb1eEY$}iB;E7G4rfQ4gu3%*;go#5hUy zw32&Q4!yko*X~JoF6VOpd}NCMS+i!vW8FU7zkk2%+__UQ7K$F_F8FUKJ@!&@@9I&7 z7gPK@I5-@Ee)Z9rGiQWt;5qPP(gP{HI9nRk=R)?$C*NGZl;L*m+NJEH(b3U@c_lk` z>`=}%u8pv;Frl1E@V?3YilE%b`-481uI6EWwJc>V(&Kr_@pf`@60F1ShWa_pweLR} zN>|gMtIp@%5BjMZ(6cwD~x|ltCwy1#pu#_s_5u&(aIsH+Fog4Y<1nUp^WBYW& z&f2&(L|5{ACnI5JC0*@r)mUjwx~iYnYl!?GePFu?gATC_xY`Qho~MbBZ+b)56asx& z2~Y!__h;~Rpr6HK`Wmzb6GHQ8kNPhrx9;{ByKLT$8@AU57I~hJ5 zmG8axUM0e>ah3^mG7300`2Gb@*{fHty~t0$hu;GK3Xq1m{tkbKGOq(~1HFKO0DT%h z24?i^*|TB5fB`~ZhQWgeEB-ofz4g|0d~*cozd%2XApreIxD}8O`dyfO;Ga+w<7D|g z?}AC5R!@&wZ7)fkglDaxu!& zg#FVG-k~{ zcv%_Thgm=M4^jR$axrF}RKT`b4jWS$ZGjzRXFj!IrW{-{g?>pb9@zIPsrv}`w?qB@ z&25v4JqWzO#znnrX@Y6Hkg@(K40Dx}Au|o$A#iro@Z5-4<|##yK2p7}726zmQgo=a zF)FsWM*d9o*E!fMPlmc~Y0-EjU>~ia4kC1+yJFkCp1ZaEx=HZHzS1AJ3(W7Z7hWdleD;LS3)idO?{KWRR zU#nZyw_R~vT}lqVW~hGXXzHkEiHq1G`&ZaV{h1E5jbJ=DXD?%KxRkoK-cbF}QPfjs z7QQu9vI57*t)i@sX}{VR@D<>?xRSoXpsfNjMLl&*)PH3_x8LFQgAdM0wEt^E?T2jB zWS`3LZ?uh&hmJ=1zU|8ONS_CseSf5mi@LW|?_rWTf1G3nj*|=`V61|4gy{ieB;DTt zn6AyIeZ|7Q^!QzD|IOYyE8C+Ar_|3mNT_^Jx2x*%xIdCE^`fkUx?bi}^}W4Rz9Iv5Q)^BSNgZ|2lN&P>c4f{h)^ISI7ws9Z{z)4f>XG z|L551f@4peF6Sb_IBem!b<4hl_YUcMMPE?xs-k9r?xCv|-JpM2flZ=Y9keHU=#03z z7=kj5fcm0N3)aoc$s0g#K-E(?;J;@-;)nj^**ajnO%LR&u0Ri95-=Z#1ug&&fbRhz zxCe8O;ax~gL--W<7PtxI0Dgcq&?L)3Kid`P0Zae_fEb_%xDPz$yygAo)~#F0e_9yl ze~g%h_ovA74NwCl0uDeQpvfi(ACPw@O`0?c@W*=ua2P&aHSn$Y3VhHur0`4n1Z{0< z8p5Z@_Z@H#Wln;|DqteOyR!Q5&dqx&r^K%S-l2K_eGgzh_Vv=qwl>NdWQh1OZ92a* z@9zQjNq2yEXx-WL)8G8IhjT~RT?hB=xfrx90senNeSSW9s*O~f&XMXv+u`pD-(bb( z6?eH<-shfy{=X$!Ki|fXe$XE9Ut1viHh4b`nb!ZoFW&scBoNl6|0?NcWu(f1&4Kdi zfl$bn{)!JO{ZLC2=1D2!n^M(>RS6sKX{Flx8s+usz3XM0+wi{(8D?z{`nq?qS4f{a z{@CSi@QX-ol>dZ$Sdsou z)XqWJiS$!>mO%!%nV+oOu_`iGN=0U{RAdAJ2;tMf_iIXgg;br)}Z6l(n+Mv44pn`s{!5|2*_7awABCI-zEdz2mH={(m0&EK44n z5l4jdJA!{>^j$pMI)s1D4MY5szRLgY;=RfoV&3+^7=2~_2RSSCGf#UF<}hHDe*b&< zdMma$%8YFVWmd|ooZGkqQeSEGA${^6O1};xm_Ey1Y^T|Y%_mc3ik+=Om$cnH+yjjg z)_zd=H)dnx_<$Dmn(cag=lTV+4t?C`ggOQt}^@bUE#PbYhs@rkXjd?EGq^$LoMikhX{O|_Nj zQ>Vyu+evph5Az{k#mu);d~d06=9DLG*2OYv``cTd`#am;-tt^y=C)s#f0kG4e^65-pO>F% z6PTAgtMx}Oc2wd_Yb#>CN7iuPVEw$0w+2-&z&=-(5zDjv5s~nhGXmz4*5XLVxdLoc%(~n(gSOU*@^ul<0{ezzU7#e*xoKiwOV# diff --git a/reactos/dll/win32/shell32/res/icons/11.ico b/reactos/dll/win32/shell32/res/icons/11.ico index 81594583608e843cb800b715cd269bef476ef1ae..0379c63a2ec861c1a4087d56d998362ddaeecc63 100644 GIT binary patch literal 17542 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 literal 17542 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 diff --git a/reactos/dll/win32/shell32/res/icons/6.ico b/reactos/dll/win32/shell32/res/icons/6.ico index eb32198de6785ebe78f1040a08635c75fa7dc822..096805107b17e9c900c8add052186fc6ffe0917c 100644 GIT binary patch literal 17542 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 diff --git a/reactos/dll/win32/shell32/res/icons/7.ico b/reactos/dll/win32/shell32/res/icons/7.ico index eb32198de6785ebe78f1040a08635c75fa7dc822..096805107b17e9c900c8add052186fc6ffe0917c 100644 GIT binary patch literal 17542 zcmeI3d5~4b6~?at#gs{DER(2ZluBY^Qdvk$Vx{s2s1!y~0ogtN z45Gq_Y=WR5pdcvsfM>7bDy>m8gS zd|!|S56%{TDEvr}g%8e;<2;o=7WnNP;RnK*0`;hWx^SuhZFtnj1s&vsHhkcVOcw|j z2|p8lA^b}Cjqp2xCFhUArNWfp*p8I<-xk zHob+V!m8G-Tdx+@2y0ulYE>i@Uw{4e>x2?v{dLz}S1N3XW8<~gUb`ud%_>tN{6=*) zdUZ>o7pJ=pKJbHYod0Ucvr?F<_rFcj5OjT-e#_6x%X2GMtZ+p|MIqL#S>sl(UhP(` zTIE)*TAZ@>MvD=aK@Z@u-FTe4({TfBI& zd*h8aLcI3cYi`k^MQ*`@1#bTQ`R;d+s?m zYt}3`bLLFC>mXXP$Y+O`A5&J^b*)?#3H$JaXA(mt81%8+h$t?45DL z4L6jPmX?NcBFECDOGB7EZ@&3vD9`J!zwVF;y!z^^ZsEd(m1KMQ<(D1sWqjd<7eYDb z%$bvrb@uGpmE<*eTR_cF@j#{rb6UuDPZs@_KDxoFo6?UAuNA^k#A*Bl<(m zWU`u^rq5)uqT8svreD+X(@#Gg>KU2A*s)_>adEMu%{)_o#E212<1QyIKXTjE5cxm- z^ivnrGxGaw@W(+qU8Ap5`c5`ROn$}+@{S%oIvlIC-Q>^B&2<{*10}RCd)S7yZQCB& zy?b{h`IGel@<-cXeZY7I$@&2OWzq+eCr@@`#*A^4$WJ?%pOUk`DcvuTf6tyhq5OUy zFrPpE_+$6UC!d7i9(?rCME{aqiJaA9asB@`xKXYE)YI6N@-r6Un@<1x_wP^0Z+&pjJ@>e-UAu<3_10URp-Y!84%~9fEg^2c`DOBQk z*-NuU{v5!jC$pKU<^gs-m91wU+g$eLXDreG>Gc2k=bu-S-}=DX;M<}4wxwoI88gY` zM;DCYbn+iOc+hR%zTMFe)q$~=3e2Nq*t>VH^MSpH0vnhN*aYlR8u_<=_0?By+qP|? zo!PQwi}SH{>sD7A_%zIhMaxt+&9`f|wo3lqzTLEYy$QTeG>o-Nk;I-Np7I*Aq`Xf&ROg%zjC~Fut+b?8$6jwrtrlXJB8HYH#Gv73kP} zXP(B! z)5qO+-+iuk@7^Kqz4uh(oLK=(TyKJ-mylrUo0pn2yMh;k3AOJI$Nh%i)>v+2du-ipLY9grrlAnZnM9V zY}+Mpb!V~Dw4NTsb}|M{ezVQAfxfXeOqw()>{r^r+9>9N=u_%g;S)i|ucxOqt^718W0)U~Rxo(+9MH zHPiMSlfH{?0H;r{UnLFRbJ`4KcF-0ZB+h~J&tHU@=K;g zRRm4*Lf;p$PI6vN)rONXjHE7m_p)w8^w6P0p+6wnhLbUl=wHrUk|nRkf_opT-dxrKd?Qi$dA2ruTjL1bvpz_U zT18$|uO)VJ=gyr;<*&&&VokuNW@?XENAMv@hC)xJncg{rFRpw@zW6-8$SXC!=}$z=EYpswSH^C5g#cf}VUb)7HK>CAe}dGO0G zzjVw8>?&u?0|yScFTVJ~ac*YM#Cei+kM?pFVhv~h@7S@!m6er+=Qqw{oPF$U#hHcu zB4d=Z2WysiF0QlS9s%0GT<+Gbn~UO(JMM5kZomC@XYk*1&wKx!eP^ZoF%{x9NBEw{ zK6{(hKvn};4P-S?&l+&y6$F`=K`_{YZ$9bDE3ce##T8dfyZrLYr#EZXY=$ti zY15{&3_SCm-}#R3sYiY2Ku@_J4=YAJM0|c95#&_uQ zUtvuC{+RsyG5PmnI{U}uZ;vVN6_YPNrt?rtzO0!1_A%uN#N@A!X`fy$|3k4EE$vuG>7|E0Sv{BE&Ci!Y{&Me>_{XZ8H} zBj*H#FMaPjAzpo`aw6yjJy{AG8rxAg6@dz&{pH=mwMlg{=`n14A@fhJ(>R!9U+7H zUWo%S7ol%4EQ?jFFVp0~5vUr-s(kza~ z+_xAYyop1}cBA{GF>aGXapZaEz~|4s-wzg>%%mTXSN(NVeArKY>nIo)kz6{m% zgT>=g^@G-~3eB-eDH;F!hX!ib;bcC^O#8v?FyoW;Qf(tww%SYI<&&%8x8LsR2lJ=b zv>&j~ny1^UWgP!N{C`c1lr_NkTA8XJEEW;%2j-;g3ghmsn)2s6#oFJuyi8p?8|wDN z)wW~%4n2F_}R3r(}(WbwQIt>=AxptVXkv=QE`|LUmVYY zE-6_T=2w(xAHZIqv~<1Op!gSi=|bh)8K9MnK6^-b?Af!sQV!b_(;tzWyOS6uanK#aHj`lIuE=}hpz&B}7!Oq)zTqrL%v0x}{WgAv z4j;CVb3A!R!^!=t1IACB5auon88&pW(N}+VV1LE=jD2=p01ftO(DdjxDNxP^Iivhm z7qAau&n5bp?!+}BKQG+3u@9;(ed>~{I521Mjs)TOjrc8`zhHjo6R0hHXtQ^sKa?5HSUmaJfB z0CRM{wfe}D?+=3 z(1P}TUyuY6l0Xtd8z3Zhvlxs`G5cZ!j?>0YWd8o&Jk8V9eS(J~S;{%}J?GPX_v+5S z%*>tnXa4VMG*4*0sd@HU4WAcj>c6kiyr$7;7A=~%{*Fd7#`m6j%5a_Z`x;H|GL7at zd>_y2zp2qYy+Wh;XD-7cG)@fM#}UKj=J|Mn^-0XL>PM=BO;0j@m%%lt`4;2bj6Y@k zIpZ%U@K=16koW$K?{RHw{)q7hjNfB$t!uu)fZVU*fNaR@6_%s`TQ1*8is3+7b>hEtEix~gN zfE}>!ImS}Pa>fgc|6;6QyvTS-0bH+O;Qx3I&!Zg5Lk{FY?ji>CKp*M~ZG^Ud?8AEL zKfLbvqwmvnShHpgeU+F_r}Ccj^2KK!$Jkp=y6?a$3Ha9%jG8^2M)suUz)a zmUw?^jj*Tf{;R3c|7QXXem|oIzqf_`)z#HhQBgsqrKMB+$jr>7^z?K}O--ewq$G-u zkEht!Sc;C0rih3L3JVLP4I4I4P*4#0`}>>t0Q-wwUZrB^SEvYZdW8y|UZz6Fm#M(v zCE*L&;$imVe{HEDU+#)>qUOMNs0j#IP1}J9U!Y_A_U%+(Ur#kPHRPdnGwDxS7iVLe zBqt|RLP7#<-n^M&Vqz#VGLklK+(;oIA+&z|dI|^#F!}-6rLM1031d1x&?e^WKTs4) zJJwrJ%lb9c610YzfeByW2XwTxwb70pJE*CtNn96c-=IpJ0VVElhSuYu7GetF&F7 z@r?Q%d7Qq5a^>3B87qY!YG0bdUCi1)Ql3byA(p}ir600QprgOPpL%qs7Z+1OK>_9F<{H~1EiH}IeG9THxE(9pUl&mNf;MT1bTe!JXhkx$g{~E7 z4OwgA3v>(*57Ykr`)Occ;Gy=TZ#6VDP;G53RaI3{d3m|9O_Y8p$1TXN(yyXQy`e8k zU!)&9qjhHOKU|ec?Hk{vU10{OeSwaVkr6t4_%Izhbm*b>qi^lpxs#fko2jv}k?QK| z2;-L04>|tIz6IIUoPX=#}AiKuvO{!rZ;72w5Q25dw=VjLZV|81pGs2nyA58s# zj(z*~iFaUdaPXn^kG_THdU|?j&z?Qh(a|ww+*0=~yd#iZ=lvGddcR4v@I&QGN20G; z`%g4v((XuW0qIAl@WbE>bYT2}U3iCaEyo>s#y#|{0|yQeeC+G%qrH3gP8qk9eM`P0 zC|B?MHr4yQMRkDE7jBQ;N&aT-Ke;`dx}t4pPm}>_U!Vhh0^=v@71z^^|FC~_bX2@6 z=xgY6%5iJDz6Duwo}bQ-uGAp2_Md9bq3#%4fv#v<6JMYMeHnck@2HQ5PWXWP68_$v zqTW&e7_0EU!x!baHC^9Ad3C%Z{FrEy9*)1v&A+F2T-0)J$iAciz&|C!bT>fP+Xus87o zzO+T!QIOu5EG;aI^)2gtHs>G@SE>)RoD#37W3PQ#VP@?=+g3#T;@Ez`=*RTFpj{sJ zo+#gWnNeV1V`$Nccgs)`>{}mI`$gKjWlcj z`OY#LNOYq91Owp9LLD-Ol(E-PezaNpFYKwH!6avafkbEF%R~*jt&aC|(^;FaTR9E%^F!&+u9~&E^ix)3`<&gT+vDa{Ef?4}7 z_SVwDG&ec`q`C=Tq`dh)t7FK~iX^l4U+Sx;;dCtxZ_(00fc;pg12Lp>96nr`V%GkT z2O4Q)t2-S6(%pq03uV7L_BvXfX4d}8gH1G=p`#IC!jFZrUmZsttxY#;|CRmCbU0Hl zFq)|ozDWD$`~6kNUdQV*%-VnTz)m`n?LkMfJm_$i!4GNwe4mvuBz!s9m}S=fYs0N{ zY?~(?1+qPbFY|4;)MtnxCu6Vonzos>|HjBJI-cuA$8)@len@%qeOAYjr(1H(+JAGj zolfL=(}`SfqaX8ax725hBPZhFGduIm+kd2!-plu)lK}i+$YZ|WUu6u5co?z0x%JDf zqr2%;p)b8x0Qd-Br2X@KMjR<)NceKDz1Xb%caC?_=^{S?_yH``ff!O5N1pF2HE;ik z9y(j>PiGj?kA<>d9Y=n!yWFh(pPbxF@0SG7SzyACg|c79kNpSav~l^Y;Vr~duImd zLgjk;paKXIzATje>NxV!zPd-+@AASA=-&H7bnomSV}Rhx*qMGx&A%g%l6QxabMH`6 z&TUHEWvCPnFegydW(RV^jj3YDc<~9e&u=rFf4ung!|eb1{?|1y z(;6_$O&SeR41>>?n9zbV1Vw8!pX1C7m-`dvOJAQweay5TChHl$P~V0#cv_1XD;P$e z78p3QJD%X;-(Z0E0v-=|I1;$Vef%HK&GvvCaFf9E0e=WwqVF-lFM@mE9D$!Bfot5y z|MA@4Fu)J`Lk4VnT$}LhA2YzudWHc`(+?To1pS2ZA_LU9Rg54W)Lu*Mk>#WGl&5c}LUCG78g`Aw2tKjHJ4h{}v zZ*Na_c6MZIYfCmZHneWtx+!?q(t@JieT5>|zD$vpFHr;|(&8lwUcExRc1k0%-PXR8 z?rHt28h_@Ia9%*>oAfS@B3BOni@UqK(GKulz`X#61e_l5N5JO+2S)OE?5!+G@+`o6 zk(`$>%NK7eb>nxsul>FH087CSF>*uL4i7hHkyG>Z^rTY#n{E0G$BRLvA zdN+|{^YQVSq95&o{6BKE;4FbxlAoV1coiEI6M_7@;zz!`aP6a9xl) zmN{hP!jYdvt`=?M!DS^s3>-I^`;K>c$3%ZYxc8Vcw<`B2!+qUJr_+&MuP0#xzlV4i z@jjqV&@a(8;O|M`8u!Ef^ahR>@{AKaHRODgv};ZD7e@GwA+IR&qkCiRO>)&}pUJ&z zC68mW&noku%J&#!3V3rE+fsB^Ci;t`0>-cxBKM{Y^XT0Dg)K5~nc`vniMs!lZ3-Hj z%gJuS(i@59?}~W14II=(m!4gt1<&zd9xS9`X`0zcSbQWzGb4WCgk1 zRqL-!jk>4KEzD*6PmXQ2gt1<&zdkMIzRV9G&oS4Ba%{^B(VOUR+`9Qb_LQ;5e~kC| z=lYPG32;C1H+q}u&)j?;`@(X68~W$6{*8OqJjPrM2x=BIrs_ZN$KuA1w;IpdxokFh+~-&6bFS&{RLTZdZc_DBoe8g3$e*fr9HUL*IA zYoy(9mE3}_lI!}bVIbgJ(t(JO(JmR zb2os1SATdjV)e2Hwg3NLuf==DJ2Jc<^X*H#e(#?r$oCry_NN%nGUPsm6TTAq?KrSj z=UpoC4Hxzk7Blc&(0@+gc|OC1zhhvp0hT}Vo1kj#lIN?nOYib|+>&{nmKM{)V$D0G z1fDH-T|!lE4DAx)^1uU@70)`w!PiTx-IxBnJKmWN=7k9!BzWOikKvmMtl_av#(Ev! zdf+<`#OjFU!JFKZ=s`V6p41H_>S=eZi_kGCf9cPAlQ~Ap-$*^N4njWGe^_%VIhOeD z2kT(0$FVPfZ(}Uj{k5wfwhtWy!7a=do!Ek@B(?nU|L!iMBim*lKOabQr&A57Ch{-!R&jhj z$^B5;G?U*4({*%)`?{)sj(^-&L&x)cjH15y;)~y?ehzKb)7h3R6ZuyL>gi;`?Bm-} z?jz?~x0%Slx_>*z@P3q6d3RPg%xka@cIBz%|N8pD7CKWBNKZa}YF0R!<0E21RsH|! z+JPpzInqi&vDYae<~sRDUnjq)>*O1Gjl3hSkyrRN^5EE1A9|JCIWE<5Tqplxv+m+&M&pPWs!W%bEb0s6xX;X@g@IOVw|tl_%+{SEd8R!eW_l` z|0>ViAvF&;an{dKQp_9!vJu1}J+z1+CCO;o9 z^5fsW{Cx}H<24Cyjx9=cFZ`lLzx;o=zK++pFB{$!Zu!f;oNx;C_Y-@y$RXf+TI`== zF2^1|Vg|$}zASfFoStI^578G{KOHHLqYjQuf&%=+w<*|%1Q6>WE|BpD;vCr49AZVi zX@ux3K`I00zV%LU}S{o#JoIO5+lohd7jr`Gd+%0 z#2L$9*j*xuKQ8ATbIggFWMlb@-Q_b?&vSuctmgI`#~d)zc?)p|+8*UE_t(u>|G8E% zmWc9KhPG3F)y&4%584Z)eldnV`ON7Vt?@tFQ)(=K<4~*MsDPUSUP@5x4GP%A<0Oxj yK9SeO7>V^e*6wm_M4iL`I{lBDC+Y#$a?Hb7Ip*QFa?BIs9gm+Cs^MV9m;VPJrW}I+ From c31fb83895e652736f5df8baa36636c423cb92cc Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 28 Sep 2006 22:03:03 +0000 Subject: [PATCH 365/488] rename folder to make it clear svn path=/trunk/; revision=24293 --- .../dll/win32/shell32/res/icons/{Licence => Icon_Licence}/COPYING | 0 .../win32/shell32/res/icons/{Licence => Icon_Licence}/Tango.txt | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename reactos/dll/win32/shell32/res/icons/{Licence => Icon_Licence}/COPYING (100%) rename reactos/dll/win32/shell32/res/icons/{Licence => Icon_Licence}/Tango.txt (100%) diff --git a/reactos/dll/win32/shell32/res/icons/Licence/COPYING b/reactos/dll/win32/shell32/res/icons/Icon_Licence/COPYING similarity index 100% rename from reactos/dll/win32/shell32/res/icons/Licence/COPYING rename to reactos/dll/win32/shell32/res/icons/Icon_Licence/COPYING diff --git a/reactos/dll/win32/shell32/res/icons/Licence/Tango.txt b/reactos/dll/win32/shell32/res/icons/Icon_Licence/Tango.txt similarity index 100% rename from reactos/dll/win32/shell32/res/icons/Licence/Tango.txt rename to reactos/dll/win32/shell32/res/icons/Icon_Licence/Tango.txt From cc033012dd61c9056331becb40f28e1e8f521c67 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 28 Sep 2006 22:14:00 +0000 Subject: [PATCH 366/488] new timedate and powercfg icons svn path=/trunk/; revision=24294 --- reactos/dll/cpl/powercfg/resources/ac.ico | Bin 318 -> 17542 bytes reactos/dll/cpl/timedate/resources/applet.ico | Bin 29926 -> 17542 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/reactos/dll/cpl/powercfg/resources/ac.ico b/reactos/dll/cpl/powercfg/resources/ac.ico index 2d355877fcd28036eb741ce25c82ea5eec44b823..e76a8c5852d37d7a89e13c1c11d9d56b13574e99 100644 GIT binary patch literal 17542 zcmd5@30PIvwZ2xHp>2kyeXq7@qpyugnxtvcA!+lP7t@zCF*PyKOpO|cL}QFY)u1xZ zGpHaA2#6vgiik1@h$tusGRr)P%-{&9DC1r4|M$J;=88C^P1<+AZ?VtW=bXL%z4qE` zuf5hrryHRgrF;5m9m=t~$ZvWId8#JMt31U5e4)|{9&p{`;e-V8PeC`7O?}F|FeIN7#&<{cXVI*F&j?ehc z_wdcPK_mV}7>AREhWj2@FZW`v)xP55=}~ppU3dKq_()?wV~xb?hd>YBefQlDx_G)* z@O?LLk7D4z*;oJ_wgF|(T{%gBmf|t#uP7Ot|;8*IxVS^Upv3i{Jd_H;+B@%rj4!;U9eZ zcTd0k=%bImG;Z9u{{_7~?y+&NjQi!dmmhijkv~82#1k+5;SYa!*&P21e}3Vq*I$4A zm+!v&?!yaLEd0qg+=n|HT%B5=FTK~2LH-`T-jM0gXV={K;CYXmx2I_GhYnpue+-0c zdpGAJ-%uZ@Gxs>UyGTw!o@C`6m+ZV;b*;(YbCtKcFE~*o1;wNjQcz+fUZXCruz-4I z!halXvAyj4T*)me5VrqM>Jn`Nb#Ww!HewV@>L};|wx4&RP&_gJyw|K!q~RwnTSo^| zz4m-)X)b?TC&T+*YkbkyB84A(z6+kWqxZym7v8@YL|gYDh_>SApoc-@jKujzv;8~b zFN92~E9Wj;P(=Jqtu3l9_0SFK66PL!2s`0u|3{yTt$ z^Zvo-{`sZ(ct zv}^MFQ-X+}e1_uRpLziH&{L8Q9Jnp~e4qVJNli83FRLuq@c-}z`0xJCcfK=v%6n6$ ze75NG5DV*-EmjUTy+NCUdv-+a9EgeCD{=edB{3;Ul2cM7@j$Y~B_>Er>^|8Qy<5L^ z`?dk%FRdsS&s9DqoW!Bw&&|s-)tk#*yVm5d;m>I z!fIuQ_v%&Mz&TjRIaOF8;So9F?Q>YHZ4Sui3le1dj98ic&K{XOC0eF^v`^;EkCPRa ziQ?{YK($|9U3ne;_>?527pEE;ZVNx(XTKYpo8|2J^Xj_#WUYq($7cAy{mNfod2-oG zi*#o%_wEABy<=HbvU+uvd@|>tyz}0EnKAP)uJeGiNInD2{q%%OpRK1)D+=Bks<3Yi3Bo*RmFBiKRr0#2r9~Qz)BvpYO-&NG zIYhl57!oX}8XFa{FDL6yY528uVC4Am;~$2eT-X~Q+h1ByBc9$_^6vXd^3jarz*`}f zR+vX_o#N?vMSOgF#dlSotXVT4>(=RI?OHwh*^g&E;_Q4$Z0#vi%gp)^8WiGZ@(?_*T0HPoG3DR zvY~GJbdirg7S(=T!ztMm8giYT^zmCQUxm!=YT)KzrAwG!df=w~M^WdOTd%xWR#_po z_D5ve^n6*dqFb!32j!DbMBaN(Qs@T^sHBpd^k+K`FobOyW}{qm%s+)VZ9`O6K-HGDKEpbGG(JmVGpk% ze8XpahyBy~!8T|U*q)t>V={2l{+RF| JAKRqw==j&0*4e2H5|8GOC-0(TSU1pIb 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 cBZn9S^V<=);qyCKE0FU13{Qv*} literal 318 zcmc(bD-wV(3`AdN@Km9Z+>R^sR@mMKiN%H87G@B5lI&+T6`4X(=bUjZ2_~!HWEK*G w7;57$Dxjg1E@D|~tx_+d4H0&N+L7t!>Ua2-8=Lfj{vr-IUfAW&Rr%Q8Uz&e0t^fc4 diff --git a/reactos/dll/cpl/timedate/resources/applet.ico b/reactos/dll/cpl/timedate/resources/applet.ico index e6a47054084aa2910807c26a19f1903e7d0e774d..9a20e3261377dda49974b1c84485b1ac09d72363 100644 GIT binary patch literal 17542 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 Is|Le=0*L6!i2wiq literal 29926 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 From 1d1b74fa1902eb2c5774580d464a8e9f9fdddc6b Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 28 Sep 2006 22:57:09 +0000 Subject: [PATCH 367/488] change run icon as a few people wanted something more fitting and add 2 more icons to the system imagelist svn path=/trunk/; revision=24295 --- reactos/dll/win32/shell32/icon_res.rc | 2 ++ reactos/dll/win32/shell32/res/icons/134.ico | Bin 0 -> 17542 bytes reactos/dll/win32/shell32/res/icons/25.ico | Bin 17542 -> 17542 bytes reactos/dll/win32/shell32/res/icons/328.ico | Bin 17542 -> 17542 bytes reactos/dll/win32/shell32/res/icons/40.ico | Bin 0 -> 17542 bytes reactos/dll/win32/shell32/shresdef.h | 3 +++ 6 files changed, 5 insertions(+) create mode 100644 reactos/dll/win32/shell32/res/icons/134.ico create mode 100644 reactos/dll/win32/shell32/res/icons/40.ico diff --git a/reactos/dll/win32/shell32/icon_res.rc b/reactos/dll/win32/shell32/icon_res.rc index ffa7f0c0273..d1330569c1f 100644 --- a/reactos/dll/win32/shell32/icon_res.rc +++ b/reactos/dll/win32/shell32/icon_res.rc @@ -33,6 +33,7 @@ IDI_SHELL_CONTROL_PANEL2 ICON "res/icons/36.ico" IDI_SHELL_PROGRAMS_FOLDER2 ICON "res/icons/37.ico" IDI_SHELL_PRINTERS_FOLDER ICON "res/icons/38.ico" IDI_SHELL_FONTS_FOLDER ICON "res/icons/39.ico" +IDI_SHELL_TSKBAR_STARTMENU ICON "res/icons/40.ico" IDI_SHELL_CD_MUSIC ICON "res/icons/41.ico" IDI_SHELL_FAVORITES ICON "res/icons/44.ico" IDI_SHELL_LOGOFF ICON "res/icons/45.ico" @@ -40,6 +41,7 @@ IDI_SHELL_EXPLORER ICON "res/icons/46.ico" // "res/icons/47.ico" IDI_SHELL_LOCKED ICON "res/icons/48.ico" // "res/icons/54.ico" +IDI_SHELL_FIND_IN_FILE ICON "res/icons/134.ico" IDI_SHELL_CONTROL_PANEL3 ICON "res/icons/137.ico" IDI_SHELL_PRINTER2 ICON "res/icons/138.ico" IDI_SHELL_INF_FILE ICON "res/icons/151.ico" diff --git a/reactos/dll/win32/shell32/res/icons/134.ico b/reactos/dll/win32/shell32/res/icons/134.ico new file mode 100644 index 0000000000000000000000000000000000000000..50faf15a017a7cb685dcb1386f6f1b99de652252 GIT binary patch literal 17542 zcmeHN2Xt0PcK&T|V#kgRc21H_P7-_9o1POpUYBz=K5Or;ZEOq%M03F`#`Gq7?@b^; z2qX|4frL7$AfbXJkWfRt_x`JQdJ$jlH!#ZM&o5M*oRgFIopb+r|Gf9+e)rCuJ9qAk z$@G-zC#Io8O;WyQn)MTt=@XO5^wXa{{J-OmOeTM+d+oJ{|GnhBcV9A@-hA`X|Gzbv z%Kye>`Um+&9!U!i>!mP#DBt}zTu<+I*aOn$ty?kB_V``cg$rGM&+e5Xe-Y|m$?|NrD