diff --git a/reactos/base/applications/games/solitaire/solitaire.cpp b/reactos/base/applications/games/solitaire/solitaire.cpp index 4046b92ff2a..e53efda79ce 100644 --- a/reactos/base/applications/games/solitaire/solitaire.cpp +++ b/reactos/base/applications/games/solitaire/solitaire.cpp @@ -196,6 +196,8 @@ int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int iCm SaveSettings(); + try { throw 0; } catch (int i) { } /* HACK */ + return msg.wParam; } diff --git a/reactos/base/applications/games/spider/lang/pl-PL.rc b/reactos/base/applications/games/spider/lang/pl-PL.rc new file mode 100644 index 00000000000..cdae2d82140 --- /dev/null +++ b/reactos/base/applications/games/spider/lang/pl-PL.rc @@ -0,0 +1,89 @@ +/* + * PROJECT: Spider Solitaire + * LICENSE: See COPYING in top level directory + * FILE: base/applications/games/spider/lang/pl-PL.rc + * PURPOSE: Polish Language File for Spider Solitaire + * TRANSLATOR: Maciej Bialas + */ + +#include "resource.h" + +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT + + +/* Dialogs */ + +IDD_CARDBACK DIALOGEX 6, 6, 186, 104 +CAPTION "Wybierz koszulkę talii" +FONT 8, "MS Shell Dlg" +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +BEGIN + CONTROL "", IDC_CARDBACK1, "Static", SS_NOTIFY, 4, 7, 26, 32 + CONTROL "", IDC_CARDBACK2, "Static", SS_NOTIFY, 34, 7, 26, 32 + CONTROL "", IDC_CARDBACK3, "Static", SS_NOTIFY, 64, 7, 26, 32 + CONTROL "", IDC_CARDBACK4, "Static", SS_NOTIFY, 94, 7, 26, 32 + CONTROL "", IDC_CARDBACK5, "Static", SS_NOTIFY, 124, 7, 26, 32 + CONTROL "", IDC_CARDBACK6, "Static", SS_NOTIFY, 154, 7, 26, 32 + CONTROL "", IDC_CARDBACK7, "Static", SS_NOTIFY, 4, 46, 26, 32 + CONTROL "", IDC_CARDBACK8, "Static", SS_NOTIFY, 34, 46, 26, 32 + CONTROL "", IDC_CARDBACK9, "Static", SS_NOTIFY, 64, 46, 26, 32 + CONTROL "", IDC_CARDBACK10, "Static", SS_NOTIFY, 94, 46, 26, 32 + CONTROL "", IDC_CARDBACK11, "Static", SS_NOTIFY, 124, 46, 26, 32 + CONTROL "", IDC_CARDBACK12, "Static", SS_NOTIFY, 154, 46, 26, 32 + DEFPUSHBUTTON "OK", IDOK, 66, 84, 54, 13 + PUSHBUTTON "Anuluj", IDCANCEL, 126, 84, 54, 13 +END + +IDD_DIFFICULTY DIALOGEX DISCARDABLE 100, 100, 106, 80 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "Poziom trudności" +FONT 8, "MS Shell Dlg" +BEGIN + AUTORADIOBUTTON "Łatwy: &Jeden kolor", IDC_DIF_ONECOLOR, 8, 10, 80, 10, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "Średni: &Dwa kolory", IDC_DIF_TWOCOLORS, 8, 23, 80, 10 + AUTORADIOBUTTON "Trudny: &Cztery kolory", IDC_DIF_FOURCOLORS, 8, 36, 80, 10 + + DEFPUSHBUTTON "OK", IDOK, 8, 58, 40, 14 + PUSHBUTTON "Anuluj", IDCANCEL, 58, 58, 40, 14 +END + +/* Strings */ + +STRINGTABLE +BEGIN + IDS_SPI_NAME "Pająk" + IDS_SPI_ABOUT "Pasjans - Pająk, autor: Gregor Schneider\n\nCardLib wersja 1.0" + IDS_SPI_QUIT "Czy na pewno chcesz zakończyć?" + IDS_SPI_WIN "Gratulacje, wygrałeś(aś)!" + IDS_SPI_DEAL "Rozdać ponownie?" +END + + +/* Menus */ + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&Gra" + BEGIN + MENUITEM "&Nowa Gra\tF2", IDM_GAME_NEW + MENUITEM SEPARATOR + MENUITEM "&Talia...", IDM_GAME_DECK + MENUITEM SEPARATOR + MENUITEM "&Wyjście", IDM_GAME_EXIT + END + POPUP "&Pomoc" + BEGIN + MENUITEM "&Zawartość\tF1", IDM_HELP_CONTENTS + MENUITEM "&O programie", IDM_HELP_ABOUT + END +END + + + +/* Accelerator */ + +IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE +BEGIN + VK_F1, IDM_HELP_CONTENTS, VIRTKEY, NOINVERT + VK_F2, IDM_GAME_NEW, VIRTKEY, NOINVERT +END diff --git a/reactos/base/applications/games/spider/rsrc.rc b/reactos/base/applications/games/spider/rsrc.rc index 7dc2d24c2a4..558a6903a32 100644 --- a/reactos/base/applications/games/spider/rsrc.rc +++ b/reactos/base/applications/games/spider/rsrc.rc @@ -10,5 +10,6 @@ IDI_SPIDER ICON DISCARDABLE "spider.ico" #include "lang/es-ES.rc" #include "lang/it-IT.rc" #include "lang/ja-JP.rc" +#include "lang/pl-PL.rc" #include "lang/ru-RU.rc" diff --git a/reactos/base/applications/games/spider/spider.cpp b/reactos/base/applications/games/spider/spider.cpp index c09a4853f96..b89d3290b16 100644 --- a/reactos/base/applications/games/spider/spider.cpp +++ b/reactos/base/applications/games/spider/spider.cpp @@ -154,6 +154,9 @@ int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int iCm DispatchMessage(&msg); } } + + try { throw 0; } catch (int i) { } /* HACK */ + return msg.wParam; } diff --git a/reactos/base/applications/games/spider/spigame.cpp b/reactos/base/applications/games/spider/spigame.cpp index 116698ab68e..e025d6c0639 100644 --- a/reactos/base/applications/games/spider/spigame.cpp +++ b/reactos/base/applications/games/spider/spigame.cpp @@ -98,13 +98,44 @@ void NewGame(void) fGameStarted = false; } +bool stackLookingGood(const CardStack &mystack, int numChecks) +{ + int i; + for (i = 0; i < numChecks; i++) + { + if (mystack[i].LoVal() != mystack[i + 1].LoVal() - 1) + { + return false; + } + if (mystack[i].Suit() != mystack[i + 1].Suit()) + { + return false; + } + } + return true; +} + +/* Card to be turned from a stack */ +void TurnStackCard(CardRegion &stackobj) +{ + int numfacedown; + + stackobj.GetFaceDirection(&numfacedown); + if (stackobj.NumCards() <= numfacedown) + { + if (numfacedown > 0) numfacedown--; + stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown); + stackobj.Redraw(); + } +} + /* Click on the deck */ void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int NumDragCards) { CardStack temp, fakeDeck = pDeck->GetCardStack(); fGameStarted = true; - int i; - + int i, j, facedown, faceup; + if (fakeDeck.NumCards() != 0 && deck.NumCards() != 0) { /* Add one card to every stack */ @@ -112,6 +143,25 @@ void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int NumDragCards) { temp = pStack[i]->GetCardStack(); temp.Push(deck.Pop()); + + /* Check if we accidentally finished a row */ + pStack[i]->GetFaceDirection(&facedown); + faceup = temp.NumCards() - facedown; + if (faceup >= NUM_ONECOLOR_CARDS) + { + /* Check stack finished, remove cards if so */ + if (stackLookingGood(temp, NUM_ONECOLOR_CARDS - 1)) + { + for (j = 0; j < NUM_ONECOLOR_CARDS; j++) + { + temp.RemoveCard(0); + } + cardsFinished += NUM_ONECOLOR_CARDS; + pStack[i]->SetCardStack(temp); + /* Turn now topmost card */ + TurnStackCard(*pStack[i]); + } + } pStack[i]->SetCardStack(temp); } /* Remove one card from the fake ones */ @@ -124,7 +174,7 @@ void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int NumDragCards) /* Cards dragged from a stack */ bool CARDLIBPROC StackDragProc(CardRegion &stackobj, int numDragCards) { - int numfacedown, numcards, i; + int numfacedown, numcards; stackobj.GetFaceDirection(&numfacedown); numcards = stackobj.NumCards(); @@ -134,30 +184,9 @@ bool CARDLIBPROC StackDragProc(CardRegion &stackobj, int numDragCards) { const CardStack &mystack = stackobj.GetCardStack(); /* Don't allow to drag unsuited cards */ - for (i = 0; i < numDragCards - 1; i++) - { - if (mystack[i].LoVal() != mystack[i + 1].LoVal() - 1) - { - return false; - } - switch (dwDifficulty) - { - case IDC_DIF_ONECOLOR: - break; - case IDC_DIF_TWOCOLORS: - if ((mystack[i].IsBlack() && mystack[i + 1].IsBlack()) || - (mystack[i].IsRed() && mystack[i + 1].IsRed())) - { - return false; - } - break; - case IDC_DIF_FOURCOLORS: - if (mystack[i].Suit() != mystack[i + 1].Suit()) - { - return false; - } - break; - } + if (!stackLookingGood(mystack, numDragCards - 1)) + { + return false; } /* Remember where the cards come from */ from = &stackobj; @@ -193,20 +222,6 @@ void CARDLIBPROC StackAddProc(CardRegion &stackobj, const CardStack &added) } } -/* Card to be turned from a stack */ -void TurnStackCard(CardRegion &stackobj) -{ - int numfacedown; - - stackobj.GetFaceDirection(&numfacedown); - if (stackobj.NumCards() <= numfacedown) - { - if (numfacedown > 0) numfacedown--; - stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown); - stackobj.Redraw(); - } -} - /* Cards dropped to a stack */ bool CARDLIBPROC StackDropProc(CardRegion &stackobj, CardStack &dragcards) { @@ -230,49 +245,20 @@ bool CARDLIBPROC StackDropProc(CardRegion &stackobj, CardStack &dragcards) return false; } - /* Can only drop if card matches colour rule */ - switch (dwDifficulty) - { - case IDC_DIF_ONECOLOR: - break; - case IDC_DIF_TWOCOLORS: - if ((mystack[0].IsBlack() && dragcard.IsRed()) || - (mystack[0].IsRed() && dragcard.IsBlack())) - { - return false; - } - break; - case IDC_DIF_FOURCOLORS: - if (mystack[0].Suit() != dragcard.Suit()) - { - return false; - } - break; - } /* Check if stack complete */ stackobj.GetFaceDirection(&facedown); faceup = stackobj.NumCards() - facedown; - + if (faceup + dragcards.NumCards() >= NUM_ONECOLOR_CARDS) { int i, max = NUM_ONECOLOR_CARDS - dragcards.NumCards() - 1; - BOOL remove = true; - - /* Dragged cards have been checked to be in order, start with the first stack card */ - for (i = 0; i < max; i++) - { - if (mystack[i].Suit() != mystack[i + 1].Suit() || - mystack[i].LoVal() != mystack[i + 1].LoVal() - 1) - { - remove = false; - break; - } - } - if (remove) + + /* Dragged cards have been checked to be in order, check stack cards */ + if (stackLookingGood(mystack, max)) { CardStack s = stackobj.GetCardStack(); CardStack f; - + /* Remove from card stack */ for (i = 0; i < max + 1; i++) { diff --git a/reactos/base/setup/usetup/interface/devinst.c b/reactos/base/setup/usetup/interface/devinst.c index 054cb9a94d9..8ea6444d2f0 100644 --- a/reactos/base/setup/usetup/interface/devinst.c +++ b/reactos/base/setup/usetup/interface/devinst.c @@ -81,7 +81,7 @@ InstallDriver( RtlCopyMemory(FullImagePath, PathPrefix.Buffer, PathPrefix.MaximumLength); wcscat(FullImagePath, ImagePath); - DPRINT1("Using driver '%S' for device '%S'\n", ImagePath, DeviceId); + DPRINT("Using driver '%S' for device '%S'\n", ImagePath, DeviceId); /* Create service key */ RtlInitUnicodeString(&StringU, Driver); @@ -368,7 +368,7 @@ EventThread(IN LPVOID lpParameter) DPRINT("Received PnP Event\n"); if (IsEqualIID(&PnpEvent->EventGuid, (REFGUID)&GUID_DEVICE_ENUMERATED)) { - DPRINT1("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds); + DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds); InstallDevice(hInf, hEnum, hServices, PnpEvent->TargetDevice.DeviceIds); } else diff --git a/reactos/base/shell/explorer/i386-stub-win32.c b/reactos/base/shell/explorer/i386-stub-win32.c index 3587612d704..9bd83d3ce08 100644 --- a/reactos/base/shell/explorer/i386-stub-win32.c +++ b/reactos/base/shell/explorer/i386-stub-win32.c @@ -547,7 +547,7 @@ getpacket (void) count = 0; /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) + while (count < BUFMAX - 1) { ch = getDebugChar (); if (ch == '$') diff --git a/reactos/boot/freeldr/freeldr/bootmgr.c b/reactos/boot/freeldr/freeldr/bootmgr.c index c3ec84aebfb..15863838731 100644 --- a/reactos/boot/freeldr/freeldr/bootmgr.c +++ b/reactos/boot/freeldr/freeldr/bootmgr.c @@ -21,12 +21,12 @@ VOID RunLoader(VOID) { - CHAR SettingName[80]; CHAR SettingValue[80]; ULONG_PTR SectionId; ULONG OperatingSystemCount; PCSTR *OperatingSystemSectionNames; PCSTR *OperatingSystemDisplayNames; + PCSTR SectionName; ULONG DefaultOperatingSystem; LONG TimeOut; ULONG SelectedOperatingSystem; @@ -93,28 +93,48 @@ VOID RunLoader(VOID) TimeOut = -1; // Try to open the operating system section in the .ini file - if (!IniOpenSection(OperatingSystemSectionNames[SelectedOperatingSystem], &SectionId)) + SettingValue[0] = ANSI_NULL; + SectionName = OperatingSystemSectionNames[SelectedOperatingSystem]; + if (IniOpenSection(SectionName, &SectionId)) { - sprintf(SettingName, "Section [%s] not found in freeldr.ini.", OperatingSystemSectionNames[SelectedOperatingSystem]); - UiMessageBox(SettingName); - continue; + // Try to read the boot type + IniReadSettingByName(SectionId, "BootType", SettingValue, sizeof(SettingValue)); } - // Try to read the boot type - if (!IniReadSettingByName(SectionId, "BootType", SettingValue, sizeof(SettingValue))) + if (SettingValue[0] == ANSI_NULL && SectionName[0] != ANSI_NULL) { - sprintf(SettingName, "BootType= line not found in section [%s] in freeldr.ini.", OperatingSystemSectionNames[SelectedOperatingSystem]); - UiMessageBox(SettingName); - continue; + // Try to infere boot type value +#ifdef __i386__ + CHAR LastChar; + LastChar = SectionName[strlen(SectionName) - 1]; + if (LastChar == '\\' || + (strstr(SectionName, ")partition(") != NULL && + strstr(SectionName, ")partition(0)") == NULL)) + { + strcpy(SettingValue, "Partition"); + } + else if (LastChar == ')' || LastChar == ':') + { + strcpy(SettingValue, "Drive"); + } + else if (TRUE) + { + strcpy(SettingValue, "BootSector"); + } + else +#endif + { + strcpy(SettingValue, "Windows2003"); + } } // Install the drive mapper according to this sections drive mappings #ifdef __i386__ - DriveMapMapDrivesInSection(OperatingSystemSectionNames[SelectedOperatingSystem]); + DriveMapMapDrivesInSection(SectionName); #endif if (_stricmp(SettingValue, "ReactOS") == 0) { - LoadAndBootReactOS(OperatingSystemSectionNames[SelectedOperatingSystem]); + LoadAndBootReactOS(SectionName); } #ifdef FREELDR_REACTOS_SETUP else if (_stricmp(SettingValue, "ReactOSSetup") == 0) @@ -136,27 +156,27 @@ VOID RunLoader(VOID) #ifdef __i386__ else if (_stricmp(SettingValue, "WindowsNT40") == 0) { - LoadAndBootWindows(OperatingSystemSectionNames[SelectedOperatingSystem], _WIN32_WINNT_NT4); + LoadAndBootWindows(SectionName, _WIN32_WINNT_NT4); } else if (_stricmp(SettingValue, "Windows2003") == 0) { - LoadAndBootWindows(OperatingSystemSectionNames[SelectedOperatingSystem], _WIN32_WINNT_WS03); + LoadAndBootWindows(SectionName, _WIN32_WINNT_WS03); } else if (_stricmp(SettingValue, "Linux") == 0) { - LoadAndBootLinux(OperatingSystemSectionNames[SelectedOperatingSystem], OperatingSystemDisplayNames[SelectedOperatingSystem]); + LoadAndBootLinux(SectionName, OperatingSystemDisplayNames[SelectedOperatingSystem]); } else if (_stricmp(SettingValue, "BootSector") == 0) { - LoadAndBootBootSector(OperatingSystemSectionNames[SelectedOperatingSystem]); + LoadAndBootBootSector(SectionName); } else if (_stricmp(SettingValue, "Partition") == 0) { - LoadAndBootPartition(OperatingSystemSectionNames[SelectedOperatingSystem]); + LoadAndBootPartition(SectionName); } else if (_stricmp(SettingValue, "Drive") == 0) { - LoadAndBootDrive(OperatingSystemSectionNames[SelectedOperatingSystem]); + LoadAndBootDrive(SectionName); } #endif } diff --git a/reactos/boot/freeldr/freeldr/fs/fat.c b/reactos/boot/freeldr/freeldr/fs/fat.c index 32b6f77d4e8..2019d85b8e8 100644 --- a/reactos/boot/freeldr/freeldr/fs/fat.c +++ b/reactos/boot/freeldr/freeldr/fs/fat.c @@ -1,6 +1,7 @@ /* * FreeLoader * Copyright (C) 1998-2003 Brian Palmer + * Copyright (C) 2009 Hervé Poussineau * * 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 @@ -598,6 +599,7 @@ BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID Directory // // We found the entry, now fill in the FAT_FILE_INFO struct // + FatFileInfoPointer->Attributes = DirEntry->Attr; FatFileInfoPointer->FileSize = DirEntry->Size; FatFileInfoPointer->FilePointer = 0; @@ -791,6 +793,14 @@ LONG FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, ULONG DeviceId, PFAT // if ((i+1) < NumberOfPathParts) { + // + // Check if current entry is a directory + // + if (!(FatFileInfo.Attributes & ATTR_DIRECTORY)) + { + MmFreeMemory(FatFileInfo.FileFatChain); + return ENOTDIR; + } DirectoryStartCluster = FatFileInfo.FileFatChain[0]; } MmFreeMemory(FatFileInfo.FileFatChain); @@ -1347,9 +1357,10 @@ LONG FatOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) FAT_FILE_INFO TempFileInfo; PFAT_FILE_INFO FileHandle; ULONG DeviceId; + BOOLEAN IsDirectory; LONG ret; - if (OpenMode != OpenReadOnly) + if (OpenMode != OpenReadOnly && OpenMode != OpenDirectory) return EACCES; DeviceId = FsGetDeviceId(*FileId); @@ -1362,6 +1373,15 @@ LONG FatOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) if (ret != ESUCCESS) return ENOENT; + // + // Check if caller opened what he expected (dir vs file) + // + IsDirectory = (TempFileInfo.Attributes & ATTR_DIRECTORY) != 0; + if (IsDirectory && OpenMode != OpenDirectory) + return EISDIR; + else if (!IsDirectory && OpenMode != OpenReadOnly) + return ENOTDIR; + FileHandle = MmHeapAlloc(sizeof(FAT_FILE_INFO)); if (!FileHandle) return ENOMEM; diff --git a/reactos/boot/freeldr/freeldr/include/fs/fat.h b/reactos/boot/freeldr/freeldr/include/fs/fat.h index a6ff834925e..9fb507fbe5b 100644 --- a/reactos/boot/freeldr/freeldr/include/fs/fat.h +++ b/reactos/boot/freeldr/freeldr/include/fs/fat.h @@ -148,6 +148,7 @@ typedef struct _FAT_VOLUME_INFO *PFAT_VOLUME_INFO; typedef struct { + UCHAR Attributes; /* File attributes */ ULONG FileSize; /* File size */ ULONG FilePointer; /* File pointer */ ULONG* FileFatChain; /* File fat chain array */ diff --git a/reactos/boot/freeldr/freeldr/oslist.c b/reactos/boot/freeldr/freeldr/oslist.c index 2461a8d3fe9..8ada8dc04a0 100644 --- a/reactos/boot/freeldr/freeldr/oslist.c +++ b/reactos/boot/freeldr/freeldr/oslist.c @@ -27,7 +27,6 @@ BOOLEAN InitOperatingSystemList(PCSTR **SectionNamesPointer, PCSTR **DisplayName CHAR SettingValue[260]; ULONG OperatingSystemCount; ULONG_PTR SectionId; - ULONG_PTR OperatingSystemSectionId; ULONG SectionSettingCount; PCHAR *OperatingSystemSectionNames; PCHAR *OperatingSystemDisplayNames; @@ -60,17 +59,14 @@ BOOLEAN InitOperatingSystemList(PCSTR **SectionNamesPointer, PCSTR **DisplayName { IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), SettingValue, sizeof(SettingValue)); - if (IniOpenSection(SettingName, &OperatingSystemSectionId)) - { - // Copy the section name - strcpy(OperatingSystemSectionNames[CurrentOperatingSystemIndex], SettingName); + // Copy the section name + strcpy(OperatingSystemSectionNames[CurrentOperatingSystemIndex], SettingName); - // Copy the display name - RemoveQuotes(SettingValue); - strcpy(OperatingSystemDisplayNames[CurrentOperatingSystemIndex], SettingValue); + // Copy the display name + RemoveQuotes(SettingValue); + strcpy(OperatingSystemDisplayNames[CurrentOperatingSystemIndex], SettingValue); - CurrentOperatingSystemIndex++; - } + CurrentOperatingSystemIndex++; } *OperatingSystemCountPointer = OperatingSystemCount; @@ -82,32 +78,7 @@ BOOLEAN InitOperatingSystemList(PCSTR **SectionNamesPointer, PCSTR **DisplayName ULONG CountOperatingSystems(ULONG SectionId) { - ULONG Idx; - CHAR SettingName[260]; - CHAR SettingValue[260]; - ULONG OperatingSystemCount = 0; - ULONG SectionSettingCount; - - // - // Loop through and count the operating systems - // - SectionSettingCount = IniGetNumSectionItems(SectionId); - for (Idx=0; IdxTheme.Effects.bTooltipAnimation = g->Theme.Effects.bMenuAnimation; g->Theme.Effects.bTooltipFade = g->Theme.Effects.bMenuFade; - SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, g->Theme.Effects.bDragFullWindows, (PVOID)&g->Theme.Effects.bDragFullWindows, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); + SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, g->Theme.Effects.bDragFullWindows, NULL, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); //UPDATE_USERPREF(KEYBOARDCUES, &g->Theme.Effects.bKeyboardCues); //UPDATE_USERPREF(ACTIVEWINDOWTRACKING, &g->Theme.Effects.bActiveWindowTracking); - UPDATE_USERPREF(MENUANIMATION, &g->Theme.Effects.bMenuAnimation); + //UPDATE_USERPREF(MENUANIMATION, &g->Theme.Effects.bMenuAnimation); //UPDATE_USERPREF(COMBOBOXANIMATION, &g->Theme.Effects.bComboBoxAnimation); //UPDATE_USERPREF(LISTBOXSMOOTHSCROLLING, &g->Theme.Effects.bListBoxSmoothScrolling); //UPDATE_USERPREF(GRADIENTCAPTIONS, &g->Theme.Effects.bGradientCaptions); diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index eb7661bd7ff..b413f3840bb 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -28,10 +28,6 @@ typedef BOOL ULONG ul_reason_for_call, LPVOID lpReserved); -#if defined(KDBG) || DBG -VOID -LdrpLoadUserModuleSymbols(PLDR_DATA_TABLE_ENTRY LdrModule); -#endif extern HANDLE WindowsApiPort; /* EOF */ diff --git a/reactos/dll/ntdll/ldr/startup.c b/reactos/dll/ntdll/ldr/startup.c index a87e0a9dfeb..c52c4354baf 100644 --- a/reactos/dll/ntdll/ldr/startup.c +++ b/reactos/dll/ntdll/ldr/startup.c @@ -428,12 +428,6 @@ LdrpInit2(PCONTEXT Context, InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, &NtModule->InInitializationOrderLinks); -#if DBG || defined(KDBG) - - LdrpLoadUserModuleSymbols(NtModule); - -#endif /* DBG || KDBG */ - /* add entry for executable (becomes first list entry) */ ExeModule = (PLDR_DATA_TABLE_ENTRY) RtlAllocateHeap(Peb->ProcessHeap, @@ -478,12 +472,6 @@ LdrpInit2(PCONTEXT Context, LdrpInitLoader(); -#if DBG || defined(KDBG) - - LdrpLoadUserModuleSymbols(ExeModule); - -#endif /* DBG || KDBG */ - EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL); ExeModule->EntryPoint = EntryPoint; diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 275381442db..16c7c75fbe4 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -63,22 +63,6 @@ static VOID LdrpDetachProcess(BOOLEAN UnloadAll); /* FUNCTIONS *****************************************************************/ -#if DBG || defined(KDBG) - -VOID -LdrpLoadUserModuleSymbols(PLDR_DATA_TABLE_ENTRY LdrModule) -{ - NtSystemDebugControl( - SysDbgQueryVersion, - (PVOID)LdrModule, - 0, - NULL, - 0, - NULL); -} - -#endif /* DBG || KDBG */ - BOOLEAN LdrMappedAsDataFile(PVOID *BaseAddress) { @@ -2269,9 +2253,7 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL, DPRINT1("LdrFixupImports failed for %wZ, status=%x\n", &(*Module)->BaseDllName, Status); return Status; } -#if DBG || defined(KDBG) - LdrpLoadUserModuleSymbols(*Module); -#endif /* DBG || KDBG */ + RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock); InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, &(*Module)->InInitializationOrderLinks); diff --git a/reactos/dll/win32/advapi32/reg/reg.c b/reactos/dll/win32/advapi32/reg/reg.c index a090cbf5838..4f06f1e5ca8 100644 --- a/reactos/dll/win32/advapi32/reg/reg.c +++ b/reactos/dll/win32/advapi32/reg/reg.c @@ -3272,6 +3272,9 @@ RegOpenKeyA(HKEY hKey, TRACE("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult); + if (!phkResult) + return ERROR_INVALID_PARAMETER; + if (!hKey && lpSubKey && phkResult) { return ERROR_INVALID_HANDLE; @@ -3308,6 +3311,9 @@ RegOpenKeyW(HKEY hKey, TRACE("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult); + if (!phkResult) + return ERROR_INVALID_PARAMETER; + if (!hKey && lpSubKey && phkResult) { return ERROR_INVALID_HANDLE; diff --git a/reactos/dll/win32/advapi32/sec/cred.c b/reactos/dll/win32/advapi32/sec/cred.c index d5b4b2efe83..c40871ce3ee 100644 --- a/reactos/dll/win32/advapi32/sec/cred.c +++ b/reactos/dll/win32/advapi32/sec/cred.c @@ -911,55 +911,63 @@ static DWORD mac_delete_credential(LPCWSTR TargetName) } #endif -static void convert_PCREDENTIALW_to_PCREDENTIALA(const CREDENTIALW *CredentialW, PCREDENTIALA CredentialA, DWORD *len) +static INT convert_PCREDENTIALW_to_PCREDENTIALA(const CREDENTIALW *CredentialW, PCREDENTIALA CredentialA, INT len) { - char *buffer = (char *)CredentialA + sizeof(CREDENTIALA); + char *buffer; INT string_len; + INT needed = sizeof(CREDENTIALA); - *len += sizeof(CREDENTIALA); if (!CredentialA) { - if (CredentialW->TargetName) *len += WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetName, -1, NULL, 0, NULL, NULL); - if (CredentialW->Comment) *len += WideCharToMultiByte(CP_ACP, 0, CredentialW->Comment, -1, NULL, 0, NULL, NULL); - *len += CredentialW->CredentialBlobSize; - if (CredentialW->TargetAlias) *len += WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetAlias, -1, NULL, 0, NULL, NULL); - if (CredentialW->UserName) *len += WideCharToMultiByte(CP_ACP, 0, CredentialW->UserName, -1, NULL, 0, NULL, NULL); + if (CredentialW->TargetName) + needed += WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetName, -1, NULL, 0, NULL, NULL); + if (CredentialW->Comment) + needed += WideCharToMultiByte(CP_ACP, 0, CredentialW->Comment, -1, NULL, 0, NULL, NULL); + needed += CredentialW->CredentialBlobSize; + if (CredentialW->TargetAlias) + needed += WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetAlias, -1, NULL, 0, NULL, NULL); + if (CredentialW->UserName) + needed += WideCharToMultiByte(CP_ACP, 0, CredentialW->UserName, -1, NULL, 0, NULL, NULL); - return; + return needed; } + + buffer = (char *)CredentialA + sizeof(CREDENTIALA); + len -= sizeof(CREDENTIALA); CredentialA->Flags = CredentialW->Flags; CredentialA->Type = CredentialW->Type; + if (CredentialW->TargetName) { CredentialA->TargetName = buffer; - - /* Buffer is guaranteed to be large enough */ - string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetName, -1, CredentialA->TargetName, 0x7FFFFFFF, NULL, NULL); - + string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetName, -1, buffer, len, NULL, NULL); buffer += string_len; - *len += string_len; + needed += string_len; + len -= string_len; } else CredentialA->TargetName = NULL; if (CredentialW->Comment) { CredentialA->Comment = buffer; - string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->Comment, -1, CredentialA->Comment, 0x7FFFFFFF, NULL, NULL); + string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->Comment, -1, buffer, len, NULL, NULL); buffer += string_len; - *len += string_len; + needed += string_len; + len -= string_len; } else CredentialA->Comment = NULL; CredentialA->LastWritten = CredentialW->LastWritten; CredentialA->CredentialBlobSize = CredentialW->CredentialBlobSize; - if (CredentialW->CredentialBlobSize) + if (CredentialW->CredentialBlobSize && (CredentialW->CredentialBlobSize <= len)) { CredentialA->CredentialBlob =(LPBYTE)buffer; memcpy(CredentialA->CredentialBlob, CredentialW->CredentialBlob, CredentialW->CredentialBlobSize); buffer += CredentialW->CredentialBlobSize; - *len += CredentialW->CredentialBlobSize; + needed += CredentialW->CredentialBlobSize; + len -= CredentialW->CredentialBlobSize; } else CredentialA->CredentialBlob = NULL; @@ -969,57 +977,67 @@ static void convert_PCREDENTIALW_to_PCREDENTIALA(const CREDENTIALW *CredentialW, if (CredentialW->TargetAlias) { CredentialA->TargetAlias = buffer; - string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetAlias, -1, CredentialA->TargetAlias, 0x7FFFFFFF, NULL, NULL); + string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetAlias, -1, buffer, len, NULL, NULL); buffer += string_len; - *len += string_len; + needed += string_len; + len -= string_len; } else CredentialA->TargetAlias = NULL; if (CredentialW->UserName) { CredentialA->UserName = buffer; - string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->UserName, -1, CredentialA->UserName, 0x7FFFFFFF, NULL, NULL); - buffer += string_len; - *len += string_len; + string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->UserName, -1, buffer, len, NULL, NULL); + needed += string_len; } else CredentialA->UserName = NULL; + + return needed; } -static void convert_PCREDENTIALA_to_PCREDENTIALW(const CREDENTIALA *CredentialA, PCREDENTIALW CredentialW, DWORD *len) +static INT convert_PCREDENTIALA_to_PCREDENTIALW(const CREDENTIALA *CredentialA, PCREDENTIALW CredentialW, INT len) { - char *buffer = (char *)CredentialW + sizeof(CREDENTIALW); + char *buffer; INT string_len; + INT needed = sizeof(CREDENTIALW); - *len += sizeof(CREDENTIALW); if (!CredentialW) { - if (CredentialA->TargetName) *len += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetName, -1, NULL, 0); - if (CredentialA->Comment) *len += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->Comment, -1, NULL, 0); - *len += CredentialA->CredentialBlobSize; - if (CredentialA->TargetAlias) *len += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetAlias, -1, NULL, 0); - if (CredentialA->UserName) *len += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->UserName, -1, NULL, 0); + if (CredentialA->TargetName) + needed += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetName, -1, NULL, 0); + if (CredentialA->Comment) + needed += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->Comment, -1, NULL, 0); + needed += CredentialA->CredentialBlobSize; + if (CredentialA->TargetAlias) + needed += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetAlias, -1, NULL, 0); + if (CredentialA->UserName) + needed += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->UserName, -1, NULL, 0); - return; + return needed; } + buffer = (char *)CredentialW + sizeof(CREDENTIALW); + len -= sizeof(CREDENTIALW); CredentialW->Flags = CredentialA->Flags; CredentialW->Type = CredentialA->Type; if (CredentialA->TargetName) { CredentialW->TargetName = (LPWSTR)buffer; - string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetName, -1, CredentialW->TargetName, 0x7FFFFFFF); + string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetName, -1, CredentialW->TargetName, len / sizeof(WCHAR)); buffer += sizeof(WCHAR) * string_len; - *len += sizeof(WCHAR) * string_len; + needed += sizeof(WCHAR) * string_len; + len -= sizeof(WCHAR) * string_len; } else CredentialW->TargetName = NULL; if (CredentialA->Comment) { CredentialW->Comment = (LPWSTR)buffer; - string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->Comment, -1, CredentialW->Comment, 0x7FFFFFFF); + string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->Comment, -1, CredentialW->Comment, len / sizeof(WCHAR)); buffer += sizeof(WCHAR) * string_len; - *len += sizeof(WCHAR) * string_len; + needed += sizeof(WCHAR) * string_len; + len -= sizeof(WCHAR) * string_len; } else CredentialW->Comment = NULL; @@ -1031,7 +1049,8 @@ static void convert_PCREDENTIALA_to_PCREDENTIALW(const CREDENTIALA *CredentialA, memcpy(CredentialW->CredentialBlob, CredentialA->CredentialBlob, CredentialA->CredentialBlobSize); buffer += CredentialA->CredentialBlobSize; - *len += CredentialA->CredentialBlobSize; + needed += CredentialA->CredentialBlobSize; + len -= CredentialA->CredentialBlobSize; } else CredentialW->CredentialBlob = NULL; @@ -1041,21 +1060,23 @@ static void convert_PCREDENTIALA_to_PCREDENTIALW(const CREDENTIALA *CredentialA, if (CredentialA->TargetAlias) { CredentialW->TargetAlias = (LPWSTR)buffer; - string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetAlias, -1, CredentialW->TargetAlias, 0x7FFFFFFF); + string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetAlias, -1, CredentialW->TargetAlias, len / sizeof(WCHAR)); buffer += sizeof(WCHAR) * string_len; - *len += sizeof(WCHAR) * string_len; + needed += sizeof(WCHAR) * string_len; + len -= sizeof(WCHAR) * string_len; } else CredentialW->TargetAlias = NULL; if (CredentialA->UserName) { CredentialW->UserName = (LPWSTR)buffer; - string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->UserName, -1, CredentialW->UserName, 0x7FFFFFFF); - buffer += sizeof(WCHAR) * string_len; - *len += sizeof(WCHAR) * string_len; + string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->UserName, -1, CredentialW->UserName, len / sizeof(WCHAR)); + needed += sizeof(WCHAR) * string_len; } else CredentialW->UserName = NULL; + + return needed; } /****************************************************************************** @@ -1161,7 +1182,8 @@ BOOL WINAPI CredEnumerateA(LPCSTR Filter, DWORD Flags, DWORD *Count, LPWSTR FilterW; PCREDENTIALW *CredentialsW; DWORD i; - DWORD len; + INT len; + INT needed; char *buffer; TRACE("(%s, 0x%x, %p, %p)\n", debugstr_a(Filter), Flags, Count, Credentials); @@ -1189,7 +1211,7 @@ BOOL WINAPI CredEnumerateA(LPCSTR Filter, DWORD Flags, DWORD *Count, len = *Count * sizeof(PCREDENTIALA); for (i = 0; i < *Count; i++) - convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], NULL, &len); + len += convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], NULL, 0); *Credentials = HeapAlloc(GetProcessHeap(), 0, len); if (!*Credentials) @@ -1200,12 +1222,13 @@ BOOL WINAPI CredEnumerateA(LPCSTR Filter, DWORD Flags, DWORD *Count, } buffer = (char *)&(*Credentials)[*Count]; + len -= *Count * sizeof(PCREDENTIALA); for (i = 0; i < *Count; i++) { - len = 0; (*Credentials)[i] = (PCREDENTIALA)buffer; - convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], (*Credentials)[i], &len); - buffer += len; + needed = convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], (*Credentials)[i], len); + buffer += needed; + len -= needed; } CredFree(CredentialsW); @@ -1334,7 +1357,7 @@ BOOL WINAPI CredReadA(LPCSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALA * { LPWSTR TargetNameW; PCREDENTIALW CredentialW; - DWORD len; + INT len; TRACE("(%s, %d, 0x%x, %p)\n", debugstr_a(TargetName), Type, Flags, Credential); @@ -1360,16 +1383,14 @@ BOOL WINAPI CredReadA(LPCSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALA * } HeapFree(GetProcessHeap(), 0, TargetNameW); - len = 0; - convert_PCREDENTIALW_to_PCREDENTIALA(CredentialW, NULL, &len); + len = convert_PCREDENTIALW_to_PCREDENTIALA(CredentialW, NULL, 0); *Credential = HeapAlloc(GetProcessHeap(), 0, len); if (!*Credential) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } - len = 0; - convert_PCREDENTIALW_to_PCREDENTIALA(CredentialW, *Credential, &len); + convert_PCREDENTIALW_to_PCREDENTIALA(CredentialW, *Credential, len); CredFree(CredentialW); @@ -1540,7 +1561,7 @@ BOOL WINAPI CredReadW(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW BOOL WINAPI CredWriteA(PCREDENTIALA Credential, DWORD Flags) { BOOL ret; - DWORD len; + INT len; PCREDENTIALW CredentialW; TRACE("(%p, 0x%x)\n", Credential, Flags); @@ -1551,16 +1572,15 @@ BOOL WINAPI CredWriteA(PCREDENTIALA Credential, DWORD Flags) return FALSE; } - len = 0; - convert_PCREDENTIALA_to_PCREDENTIALW(Credential, NULL, &len); + len = convert_PCREDENTIALA_to_PCREDENTIALW(Credential, NULL, 0); CredentialW = HeapAlloc(GetProcessHeap(), 0, len); if (!CredentialW) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } - len = 0; - convert_PCREDENTIALA_to_PCREDENTIALW(Credential, CredentialW, &len); + + convert_PCREDENTIALA_to_PCREDENTIALW(Credential, CredentialW, len); ret = CredWriteW(CredentialW, Flags); @@ -1722,7 +1742,7 @@ BOOL WINAPI CredReadDomainCredentialsA(PCREDENTIAL_TARGET_INFORMATIONA TargetInf DWORD Flags, DWORD *Size, PCREDENTIALA **Credentials) { PCREDENTIAL_TARGET_INFORMATIONW TargetInformationW; - DWORD len, i; + INT len, i; WCHAR *buffer, *end; BOOL ret; PCREDENTIALW* CredentialsW; @@ -1831,10 +1851,11 @@ BOOL WINAPI CredReadDomainCredentialsA(PCREDENTIAL_TARGET_INFORMATIONA TargetInf if (ret) { char *buf; + INT needed; len = *Size * sizeof(PCREDENTIALA); for (i = 0; i < *Size; i++) - convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], NULL, &len); + len += convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], NULL, 0); *Credentials = HeapAlloc(GetProcessHeap(), 0, len); if (!*Credentials) @@ -1845,12 +1866,13 @@ BOOL WINAPI CredReadDomainCredentialsA(PCREDENTIAL_TARGET_INFORMATIONA TargetInf } buf = (char *)&(*Credentials)[*Size]; + len -= *Size * sizeof(PCREDENTIALA); for (i = 0; i < *Size; i++) { - len = 0; (*Credentials)[i] = (PCREDENTIALA)buf; - convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], (*Credentials)[i], &len); - buf += len; + needed = convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], (*Credentials)[i], len); + buf += needed; + len -= needed; } CredFree(CredentialsW); diff --git a/reactos/dll/win32/cards/cards.rc b/reactos/dll/win32/cards/cards.rc index b17613f783a..34de75d7298 100644 --- a/reactos/dll/win32/cards/cards.rc +++ b/reactos/dll/win32/cards/cards.rc @@ -152,18 +152,18 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 51 BITMAP "res/bavarian/GrasOber.bmp" 52 BITMAP "res/bavarian/GrasKoenig.bmp" 53 BITMAP "res/bavarian/FreeCard.bmp" - 54 BITMAP "res/bavarian/Ruecken.bmp" - 55 BITMAP "res/bavarian/Ruecken.bmp" - 56 BITMAP "res/bavarian/Ruecken.bmp" - 57 BITMAP "res/bavarian/Ruecken.bmp" - 58 BITMAP "res/bavarian/Ruecken.bmp" - 59 BITMAP "res/bavarian/Ruecken.bmp" - 60 BITMAP "res/bavarian/Ruecken.bmp" - 61 BITMAP "res/bavarian/Ruecken.bmp" - 62 BITMAP "res/bavarian/Ruecken.bmp" - 63 BITMAP "res/bavarian/Ruecken.bmp" - 64 BITMAP "res/bavarian/Ruecken.bmp" - 65 BITMAP "res/bavarian/Ruecken.bmp" + 54 BITMAP "res/bavarian/Ruecken1.bmp" + 55 BITMAP "res/bavarian/Ruecken2.bmp" + 56 BITMAP "res/bavarian/Ruecken3.bmp" + 57 BITMAP "res/bavarian/Ruecken4.bmp" + 58 BITMAP "res/bavarian/Ruecken5.bmp" + 59 BITMAP "res/bavarian/Ruecken6.bmp" + 60 BITMAP "res/bavarian/Ruecken7.bmp" + 61 BITMAP "res/bavarian/Ruecken8.bmp" + 62 BITMAP "res/bavarian/Ruecken9.bmp" + 63 BITMAP "res/bavarian/Ruecken10.bmp" + 64 BITMAP "res/bavarian/Ruecken11.bmp" + 65 BITMAP "res/bavarian/Ruecken12.bmp" 66 BITMAP "res/bavarian/Joker.bmp" 67 BITMAP "res/bavarian/XSign.bmp" 68 BITMAP "res/bavarian/OSign.bmp" diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken1.bmp similarity index 100% rename from reactos/dll/win32/cards/res/bavarian/Ruecken.bmp rename to reactos/dll/win32/cards/res/bavarian/Ruecken1.bmp diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken10.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken10.bmp new file mode 100644 index 00000000000..1487e8a5fdc Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken10.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken11.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken11.bmp new file mode 100644 index 00000000000..60270db644c Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken11.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken12.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken12.bmp new file mode 100644 index 00000000000..c0ea235f0e6 Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken12.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken2.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken2.bmp new file mode 100644 index 00000000000..0bee44ff71d Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken2.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken3.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken3.bmp new file mode 100644 index 00000000000..654147f5bef Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken3.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken4.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken4.bmp new file mode 100644 index 00000000000..861414860d4 Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken4.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken5.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken5.bmp new file mode 100644 index 00000000000..db76a1d3bd9 Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken5.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken6.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken6.bmp new file mode 100644 index 00000000000..efeb9172f93 Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken6.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken7.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken7.bmp new file mode 100644 index 00000000000..b8775c1426d Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken7.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken8.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken8.bmp new file mode 100644 index 00000000000..29083ba89ff Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken8.bmp differ diff --git a/reactos/dll/win32/cards/res/bavarian/Ruecken9.bmp b/reactos/dll/win32/cards/res/bavarian/Ruecken9.bmp new file mode 100644 index 00000000000..ce4d38aabf1 Binary files /dev/null and b/reactos/dll/win32/cards/res/bavarian/Ruecken9.bmp differ diff --git a/reactos/dll/win32/gdi32/objects/font.c b/reactos/dll/win32/gdi32/objects/font.c index 2cb6f2c0f38..a1533f78642 100644 --- a/reactos/dll/win32/gdi32/objects/font.c +++ b/reactos/dll/win32/gdi32/objects/font.c @@ -916,6 +916,10 @@ GetGlyphIndicesA( INT countW; lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL); + + if (lpstrW == NULL) + return GDI_ERROR; + Ret = NtGdiGetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags); HeapFree(GetProcessHeap(), 0, lpstrW); return Ret; diff --git a/reactos/dll/win32/kernel32/mem/isbad.c b/reactos/dll/win32/kernel32/mem/isbad.c index 62cf1708cb1..1b186f10530 100644 --- a/reactos/dll/win32/kernel32/mem/isbad.c +++ b/reactos/dll/win32/kernel32/mem/isbad.c @@ -171,9 +171,6 @@ IsBadStringPtrW(IN LPCWSTR lpsz, /* Calculate the last page */ Last = (PWCHAR)((ULONG_PTR)lpsz + (ucchMax * 2) - 2); - /* Another quick failure case */ - if ((ULONG_PTR)Last < (ULONG_PTR)lpsz) return TRUE; - /* Enter SEH */ _SEH2_TRY { @@ -184,7 +181,7 @@ IsBadStringPtrW(IN LPCWSTR lpsz, { Char = *Current; Current++; - } while (Char && (Current <= Last)); + } while (Char && (Current != Last + 1)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -217,9 +214,6 @@ IsBadStringPtrA(IN LPCSTR lpsz, /* Calculate the last page */ Last = (PCHAR)((ULONG_PTR)lpsz + ucchMax - 1); - /* Another quick failure case */ - if ((ULONG_PTR)Last < (ULONG_PTR)lpsz) return TRUE; - /* Enter SEH */ _SEH2_TRY { @@ -230,7 +224,7 @@ IsBadStringPtrA(IN LPCSTR lpsz, { Char = *Current; Current++; - } while (Char && (Current <= Last)); + } while (Char && (Current != Last + 1)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { diff --git a/reactos/dll/win32/kernel32/mem/virtual.c b/reactos/dll/win32/kernel32/mem/virtual.c index f48269f1458..25bbf8c9997 100644 --- a/reactos/dll/win32/kernel32/mem/virtual.c +++ b/reactos/dll/win32/kernel32/mem/virtual.c @@ -170,14 +170,15 @@ NTAPI VirtualLock(IN LPVOID lpAddress, IN SIZE_T dwSize) { - ULONG BytesLocked; NTSTATUS Status; + ULONG RegionSize = dwSize; + PVOID BaseAddress = lpAddress; /* Lock the memory */ Status = NtLockVirtualMemory(NtCurrentProcess(), - lpAddress, - dwSize, - &BytesLocked); + &BaseAddress, + &RegionSize, + MAP_PROCESS); if (!NT_SUCCESS(Status)) { /* We failed */ @@ -244,14 +245,15 @@ NTAPI VirtualUnlock(IN LPVOID lpAddress, IN SIZE_T dwSize) { - ULONG BytesLocked; NTSTATUS Status; - - /* Unlock the memory */ + ULONG RegionSize = dwSize; + PVOID BaseAddress = lpAddress; + + /* Lock the memory */ Status = NtUnlockVirtualMemory(NtCurrentProcess(), - lpAddress, - dwSize, - &BytesLocked); + &BaseAddress, + &RegionSize, + MAP_PROCESS); if (!NT_SUCCESS(Status)) { /* We failed */ diff --git a/reactos/dll/win32/kernel32/misc/utils.c b/reactos/dll/win32/kernel32/misc/utils.c index b710d2334e4..190d4ef1f09 100644 --- a/reactos/dll/win32/kernel32/misc/utils.c +++ b/reactos/dll/win32/kernel32/misc/utils.c @@ -259,6 +259,8 @@ BasepCreateStack(HANDLE hProcess, /* Now set up some basic Initial TEB Parameters */ InitialTeb->AllocatedStackBase = (PVOID)Stack; InitialTeb->StackBase = (PVOID)(Stack + StackReserve); + InitialTeb->PreviousStackBase = NULL; + InitialTeb->PreviousStackLimit = NULL; /* Update the Stack Position */ Stack += StackReserve - StackCommit; diff --git a/reactos/dll/win32/msi/action.c b/reactos/dll/win32/msi/action.c index c8249045943..46249c20813 100644 --- a/reactos/dll/win32/msi/action.c +++ b/reactos/dll/win32/msi/action.c @@ -501,7 +501,7 @@ static UINT msi_apply_substorage_transform( MSIPACKAGE *package, return ERROR_SUCCESS; } -static UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ) +UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ) { static const WCHAR szProdCode[] = { 'P','r','o','d','u','c','t','C','o','d','e',0 }; LPWSTR guid_list, *guids, product_code; @@ -789,6 +789,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0}; static const WCHAR szAction[] = {'A','C','T','I','O','N',0}; static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0}; + static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0}; + static const WCHAR szInstalled[] = {'I','n','s','t','a','l','l','e','d',0}; + static const WCHAR szAll[] = {'A','L','L',0}; MSI_SetPropertyW(package, szAction, szInstall); @@ -837,6 +840,12 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, msi_apply_transforms( package ); msi_apply_patches( package ); + if (!szCommandLine && msi_get_property_int( package, szInstalled, 0 )) + { + TRACE("setting reinstall property\n"); + MSI_SetPropertyW( package, szReinstall, szAll ); + } + /* properties may have been added by a transform */ msi_clone_properties( package ); msi_set_context( package ); @@ -871,6 +880,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, /* finish up running custom actions */ ACTION_FinishCustomActions(package); + if (rc == ERROR_SUCCESS && package->need_reboot) + return ERROR_SUCCESS_REBOOT_REQUIRED; + return rc; } @@ -3378,16 +3390,12 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package) return ERROR_SUCCESS; res = CoInitialize( NULL ); - if (FAILED (res)) - { - ERR("CoInitialize failed\n"); - return ERROR_FUNCTION_FAILED; - } rc = MSI_IterateRecords(view, NULL, ITERATE_CreateShortcuts, package); msiobj_release(&view->hdr); - CoUninitialize(); + if (SUCCEEDED(res)) + CoUninitialize(); return rc; } @@ -5308,8 +5316,7 @@ static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags ) } } - if (!*flags || - check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) || + if (check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) || check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETABSENT) || check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETALWAYS) || check_flag_combo(*flags, ENV_ACT_SETABSENT | ENV_MOD_MASK)) @@ -5318,6 +5325,9 @@ static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags ) return ERROR_FUNCTION_FAILED; } + if (!*flags) + *flags = ENV_ACT_SETALWAYS | ENV_ACT_REMOVE; + return ERROR_SUCCESS; } @@ -5345,6 +5355,8 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param ) name = MSI_RecordGetString(rec, 2); value = MSI_RecordGetString(rec, 3); + TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value)); + res = env_set_flags(&name, &value, &flags); if (res != ERROR_SUCCESS) goto done; diff --git a/reactos/dll/win32/msi/custom.c b/reactos/dll/win32/msi/custom.c index 3476f0d376b..5ac9c1b24d3 100644 --- a/reactos/dll/win32/msi/custom.c +++ b/reactos/dll/win32/msi/custom.c @@ -679,7 +679,7 @@ static DWORD ACTION_CallDllFunction( const GUID *guid ) hModule = LoadLibraryW( dll ); if (!hModule) { - ERR("failed to load dll %s\n", debugstr_w( dll ) ); + ERR("failed to load dll %s (%u)\n", debugstr_w( dll ), GetLastError() ); return r; } @@ -1046,15 +1046,16 @@ static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source, if( row ) { LPCWSTR error = MSI_RecordGetString( row, 1 ); - MessageBoxW( NULL, error, NULL, MB_OK ); + if ((gUILevel & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE) + MessageBoxW( NULL, error, NULL, MB_OK ); msiobj_release( &row->hdr ); } - else + else if ((gUILevel & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE) MessageBoxW( NULL, deformated, NULL, MB_OK ); msi_free( deformated ); - return ERROR_FUNCTION_FAILED; + return ERROR_INSTALL_FAILURE; } static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source, diff --git a/reactos/dll/win32/msi/files.c b/reactos/dll/win32/msi/files.c index 01a80b7437c..d9cc0fffb61 100644 --- a/reactos/dll/win32/msi/files.c +++ b/reactos/dll/win32/msi/files.c @@ -139,7 +139,7 @@ static UINT copy_file(MSIFILE *file, LPWSTR source) return ERROR_SUCCESS; } -static UINT copy_install_file(MSIFILE *file, LPWSTR source) +static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) { UINT gle; @@ -153,7 +153,7 @@ static UINT copy_install_file(MSIFILE *file, LPWSTR source) if (gle == ERROR_ALREADY_EXISTS && file->state == msifs_overwrite) { TRACE("overwriting existing file\n"); - gle = ERROR_SUCCESS; + return ERROR_SUCCESS; } else if (gle == ERROR_ACCESS_DENIED) { @@ -162,6 +162,39 @@ static UINT copy_install_file(MSIFILE *file, LPWSTR source) gle = copy_file(file, source); TRACE("Overwriting existing file: %d\n", gle); } + if (gle == ERROR_SHARING_VIOLATION) + { + static const WCHAR msiW[] = {'m','s','i',0}; + static const WCHAR slashW[] = {'\\',0}; + WCHAR tmpfileW[MAX_PATH], *pathW, *p; + DWORD len; + + TRACE("file in use, scheduling rename operation\n"); + + GetTempFileNameW(slashW, msiW, 0, tmpfileW); + len = strlenW(file->TargetPath) + strlenW(tmpfileW) + 1; + if (!(pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) + return ERROR_OUTOFMEMORY; + + strcpyW(pathW, file->TargetPath); + if ((p = strrchrW(pathW, '\\'))) *p = 0; + strcatW(pathW, tmpfileW); + + if (CopyFileW(source, pathW, FALSE) && + MoveFileExW(file->TargetPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) && + MoveFileExW(pathW, file->TargetPath, MOVEFILE_DELAY_UNTIL_REBOOT)) + { + file->state = msifs_installed; + package->need_reboot = 1; + gle = ERROR_SUCCESS; + } + else + { + gle = GetLastError(); + WARN("failed to schedule rename operation: %d)\n", gle); + } + HeapFree(GetProcessHeap(), 0, pathW); + } return gle; } @@ -296,7 +329,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) debugstr_w(file->TargetPath)); msi_file_update_ui(package, file, szInstallFiles); - rc = copy_install_file(file, source); + rc = copy_install_file(package, file, source); if (rc != ERROR_SUCCESS) { ERR("Failed to copy %s to %s (%d)\n", debugstr_w(source), diff --git a/reactos/dll/win32/msi/media.c b/reactos/dll/win32/msi/media.c index 2de3252d79d..83f46985ed9 100644 --- a/reactos/dll/win32/msi/media.c +++ b/reactos/dll/win32/msi/media.c @@ -49,11 +49,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); #define _O_TEXT 0x4000 #define _O_BINARY 0x8000 -static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPWSTR source_root) +static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root) { WCHAR volume_name[MAX_PATH + 1]; + WCHAR root[MAX_PATH + 1]; - if (!GetVolumeInformationW(source_root, volume_name, MAX_PATH + 1, + strcpyW(root, source_root); + PathStripToRootW(root); + PathAddBackslashW(root); + + if (!GetVolumeInformationW(root, volume_name, MAX_PATH + 1, NULL, NULL, NULL, NULL, 0)) { ERR("Failed to get volume information\n"); @@ -80,7 +85,6 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi) error = generate_error_string(package, 1302, 1, mi->disk_prompt); error_dialog = msi_dup_property(package, error_prop); source_dir = msi_dup_property(package, cszSourceDir); - PathStripToRootW(source_dir); while (r == ERROR_SUCCESS && !source_matches_volume(mi, source_dir)) @@ -333,11 +337,56 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, NULL, CREATE_ALWAYS, attrs, NULL); if (handle == INVALID_HANDLE_VALUE) { - if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES) - ERR("failed to create %s (error %d)\n", - debugstr_w(path), GetLastError()); + DWORD err = GetLastError(); + DWORD attrs2 = GetFileAttributesW(path); - goto done; + if (attrs2 == INVALID_FILE_ATTRIBUTES) + { + ERR("failed to create %s (error %d)\n", debugstr_w(path), err); + goto done; + } + else if (err == ERROR_ACCESS_DENIED && (attrs2 & FILE_ATTRIBUTE_READONLY)) + { + TRACE("removing read-only attribute on %s\n", debugstr_w(path)); + SetFileAttributesW( path, attrs2 & ~FILE_ATTRIBUTE_READONLY ); + handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs2, NULL); + + if (handle != INVALID_HANDLE_VALUE) goto done; + err = GetLastError(); + } + if (err == ERROR_SHARING_VIOLATION) + { + static const WCHAR msiW[] = {'m','s','i',0}; + static const WCHAR slashW[] = {'\\',0}; + WCHAR tmpfileW[MAX_PATH], *tmppathW, *p; + DWORD len; + + TRACE("file in use, scheduling rename operation\n"); + + GetTempFileNameW(slashW, msiW, 0, tmpfileW); + len = strlenW(path) + strlenW(tmpfileW) + 1; + if (!(tmppathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) + return ERROR_OUTOFMEMORY; + + strcpyW(tmppathW, path); + if ((p = strrchrW(tmppathW, '\\'))) *p = 0; + strcatW(tmppathW, tmpfileW); + + handle = CreateFileW(tmppathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL); + + if (handle != INVALID_HANDLE_VALUE && + MoveFileExW(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) && + MoveFileExW(tmppathW, path, MOVEFILE_DELAY_UNTIL_REBOOT)) + { + data->package->need_reboot = 1; + } + else + WARN("failed to schedule rename operation %s (error %d)\n", debugstr_w(path), GetLastError()); + + HeapFree(GetProcessHeap(), 0, tmppathW); + } + else + WARN("failed to create %s (error %d)\n", debugstr_w(path), err); } done: @@ -455,6 +504,17 @@ void msi_free_media_info(MSIMEDIAINFO *mi) msi_free(mi); } +static UINT get_drive_type(const WCHAR *path) +{ + WCHAR root[MAX_PATH + 1]; + + strcpyW(root, path); + PathStripToRootW(root); + PathAddBackslashW(root); + + return GetDriveTypeW(root); +} + static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) { MSIRECORD *row; @@ -494,9 +554,7 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO source_dir = msi_dup_property(package, cszSourceDir); lstrcpyW(mi->source, source_dir); - - PathStripToRootW(source_dir); - mi->type = GetDriveTypeW(source_dir); + mi->type = get_drive_type(source_dir); if (file->IsCompressed && mi->cabinet) { @@ -576,7 +634,6 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) { /* FIXME: what about SourceDir */ lstrcpyW(mi->source, source); - lstrcatW(mi->source, mi->cabinet); return ERROR_SUCCESS; } } diff --git a/reactos/dll/win32/msi/msi.c b/reactos/dll/win32/msi/msi.c index be1ad93bf9f..2a66d601a8e 100644 --- a/reactos/dll/win32/msi/msi.c +++ b/reactos/dll/win32/msi/msi.c @@ -489,13 +489,86 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath, return ERROR_CALL_NOT_IMPLEMENTED; } +static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch ) +{ + MSISUMMARYINFO *si; + MSIDATABASE *patch_db; + UINT r = ERROR_SUCCESS; + + r = MSI_OpenDatabaseW( patch, MSIDBOPEN_READONLY, &patch_db ); + if (r != ERROR_SUCCESS) + { + WARN("failed to open patch file %s\n", debugstr_w(patch)); + return r; + } + + si = MSI_GetSummaryInformationW( patch_db->storage, 0 ); + if (!si) + { + r = ERROR_FUNCTION_FAILED; + goto done; + } + + r = msi_check_patch_applicable( package, si ); + if (r != ERROR_SUCCESS) + TRACE("patch not applicable\n"); + +done: + msiobj_release( &patch_db->hdr ); + msiobj_release( &si->hdr ); + return r; +} + UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo) { - FIXME("(%s, %d, %p): stub!\n", debugstr_w(szProductPackagePath), - cPatchInfo, pPatchInfo); + UINT i, r, ret = ERROR_FUNCTION_FAILED; + MSIPACKAGE *package; - return ERROR_CALL_NOT_IMPLEMENTED; + TRACE("(%s, %d, %p)\n", debugstr_w(szProductPackagePath), cPatchInfo, pPatchInfo); + + r = MSI_OpenPackageW( szProductPackagePath, &package ); + if (r != ERROR_SUCCESS) + { + ERR("failed to open package %u\n", r); + return r; + } + + for (i = 0; i < cPatchInfo; i++) + { + switch (pPatchInfo[i].ePatchDataType) + { + case MSIPATCH_DATATYPE_PATCHFILE: + { + FIXME("patch ordering not supported\n"); + r = MSI_ApplicablePatchW( package, pPatchInfo[i].szPatchData ); + if (r != ERROR_SUCCESS) + { + pPatchInfo[i].dwOrder = ~0u; + pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND; + } + else + { + pPatchInfo[i].dwOrder = i; + pPatchInfo[i].uStatus = ret = ERROR_SUCCESS; + } + break; + } + default: + { + FIXME("patch data type %u not supported\n", pPatchInfo[i].ePatchDataType); + pPatchInfo[i].dwOrder = ~0u; + pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND; + break; + } + } + + TRACE(" szPatchData: %s\n", debugstr_w(pPatchInfo[i].szPatchData)); + TRACE("ePatchDataType: %u\n", pPatchInfo[i].ePatchDataType); + TRACE(" dwOrder: %u\n", pPatchInfo[i].dwOrder); + TRACE(" uStatus: %u\n", pPatchInfo[i].uStatus); + } + return ret; } UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid, @@ -620,9 +693,6 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, if (szCommandLine) lstrcpyW(commandline,szCommandLine); - if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN) - lstrcatW(commandline,szInstalled); - if (eInstallState == INSTALLSTATE_ABSENT) lstrcatW(commandline, szRemoveAll); diff --git a/reactos/dll/win32/msi/msipriv.h b/reactos/dll/win32/msi/msipriv.h index b61d7b6f245..71c3b69bfa7 100644 --- a/reactos/dll/win32/msi/msipriv.h +++ b/reactos/dll/win32/msi/msipriv.h @@ -340,6 +340,7 @@ typedef struct tagMSIPACKAGE unsigned char scheduled_action_running : 1; unsigned char commit_action_running : 1; unsigned char rollback_action_running : 1; + unsigned char need_reboot : 1; } MSIPACKAGE; typedef struct tagMSIPREVIEW @@ -683,6 +684,8 @@ extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db, LPCWSTR szTransformFile, int iErrorCond ); extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg ); +extern UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ); + /* action internals */ extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR ); extern void ACTION_free_package_structures( MSIPACKAGE* ); diff --git a/reactos/dll/win32/msi/msiserver.idl b/reactos/dll/win32/msi/msiserver.idl index 546b75821ca..ac442dbd076 100644 --- a/reactos/dll/win32/msi/msiserver.idl +++ b/reactos/dll/win32/msi/msiserver.idl @@ -424,4 +424,4 @@ library WindowsInstaller properties: methods: } -} \ No newline at end of file +} diff --git a/reactos/dll/win32/msi/package.c b/reactos/dll/win32/msi/package.c index 82de944e7a7..f74bf05ab5c 100644 --- a/reactos/dll/win32/msi/package.c +++ b/reactos/dll/win32/msi/package.c @@ -453,13 +453,14 @@ static VOID set_installer_properties(MSIPACKAGE *package) static const WCHAR szTime[] = {'T','i','m','e',0}; static const WCHAR szUserLangID[] = {'U','s','e','r','L','a','n','g','u','a','g','e','I','D',0}; static const WCHAR szSystemLangID[] = {'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',0}; + static const WCHAR szProductState[] = {'P','r','o','d','u','c','t','S','t','a','t','e',0}; /* * Other things that probably should be set: * * ComputerName LogonUser VirtualMemory * ShellAdvSupport DefaultUIFont PackagecodeChanging - * ProductState CaptionHeight BorderTop BorderSide TextHeight + * CaptionHeight BorderTop BorderSide TextHeight * RedirectedDllSupport */ @@ -658,6 +659,9 @@ static VOID set_installer_properties(MSIPACKAGE *package) sprintfW(bufstr, szIntFormat, langid); MSI_SetPropertyW( package, szSystemLangID, bufstr ); + + sprintfW(bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode)); + MSI_SetPropertyW( package, szProductState, bufstr ); } static UINT msi_load_summary_properties( MSIPACKAGE *package ) @@ -804,12 +808,14 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) create_temp_property_table( package ); msi_clone_properties( package ); - set_installer_properties(package); - sprintfW(uilevel,szpi,gUILevel); - MSI_SetPropertyW(package, szLevel, uilevel); package->ProductCode = msi_dup_property( package, szProductCode ); set_installed_prop( package ); + set_installer_properties( package ); + + sprintfW(uilevel,szpi,gUILevel); + MSI_SetPropertyW(package, szLevel, uilevel); + r = msi_load_summary_properties( package ); if (r != ERROR_SUCCESS) { diff --git a/reactos/dll/win32/msi/suminfo.c b/reactos/dll/win32/msi/suminfo.c index a02f949cb24..ef16665b781 100644 --- a/reactos/dll/win32/msi/suminfo.c +++ b/reactos/dll/win32/msi/suminfo.c @@ -475,7 +475,9 @@ UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase, if( szDatabase ) { - ret = MSI_OpenDatabaseW( szDatabase, NULL, &db ); + LPCWSTR persist = uiUpdateCount ? MSIDBOPEN_TRANSACT : MSIDBOPEN_READONLY; + + ret = MSI_OpenDatabaseW( szDatabase, persist, &db ); if( ret != ERROR_SUCCESS ) return ret; } diff --git a/reactos/dll/win32/msi/table.c b/reactos/dll/win32/msi/table.c index b963a2022fd..86cd4be4a79 100644 --- a/reactos/dll/win32/msi/table.c +++ b/reactos/dll/win32/msi/table.c @@ -2777,7 +2777,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, r = TABLE_insert_row( &tv->view, rec, -1, FALSE ); if (r != ERROR_SUCCESS) - ERR("insert row failed\n"); + WARN("insert row failed\n"); if ( number != MSI_NULL_INTEGER && !lstrcmpW(name, szColumns) ) msi_update_table_columns( db, table ); @@ -2788,7 +2788,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg, r = msi_table_find_row( tv, rec, &row ); if (r != ERROR_SUCCESS) - ERR("no matching row to transform\n"); + WARN("no matching row to transform\n"); else if ( mask ) { TRACE("modifying row [%d]:\n", row); diff --git a/reactos/dll/win32/rasadhlp/autodial.c b/reactos/dll/win32/rasadhlp/autodial.c new file mode 100644 index 00000000000..20e4d5a0535 --- /dev/null +++ b/reactos/dll/win32/rasadhlp/autodial.c @@ -0,0 +1,123 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Winsock 2 SPI + * FILE: lib/mswsock/lib/init.c + * PURPOSE: DLL Initialization + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +WINAPI +AcsHlpSendCommand(IN PAUTODIAL_COMMAND Command) +{ + UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"\\Device\\RasAcd"); + NTSTATUS Status; + HANDLE DriverHandle; + HANDLE EventHandle = NULL; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + + /* Initialize the object attributes */ + InitializeObjectAttributes(&ObjectAttributes, + &DriverName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Open a handle to it */ + Status = NtCreateFile(&DriverHandle, + FILE_READ_DATA | FILE_WRITE_DATA, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN_IF, + 0, + NULL, + 0); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Create an event */ + EventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!EventHandle) + { + /* Event failed, fail us */ + CloseHandle(DriverHandle); + return FALSE; + } + + /* Connect to the driver */ + Status = NtDeviceIoControlFile(DriverHandle, + EventHandle, + NULL, + NULL, + &IoStatusBlock, + IOCTL_ACD_CONNECT_ADDRESS, + Command, + sizeof(AUTODIAL_COMMAND), + NULL, + 0); + + /* Check if we need to wait */ + if (Status == STATUS_PENDING) + { + /* Wait for the driver */ + Status = WaitForSingleObject(EventHandle, INFINITE); + + /* Update status */ + Status = IoStatusBlock.Status; + } + + /* Close handles and return */ + CloseHandle(EventHandle); + CloseHandle(DriverHandle); + return NT_SUCCESS(Status); +} + +/* + * @implemented + */ +BOOLEAN +WINAPI +AcsHlpAttemptConnection(IN PAUTODIAL_ADDR ConnectionAddress) +{ + AUTODIAL_COMMAND Command; + + /* Clear the command packet */ + RtlZeroMemory(&Command, sizeof(AUTODIAL_COMMAND)); + + /* Copy the address into the command packet */ + RtlCopyMemory(&Command.Address, ConnectionAddress, sizeof(AUTODIAL_ADDR)); + + /* Send it to the driver */ + return AcsHlpSendCommand(&Command); +} + +/* + * @implemented + */ +BOOLEAN +WINAPI +AcsHlpNoteNewConnection(IN PAUTODIAL_ADDR ConnectionAddress, + IN PAUTODIAL_CONN Connection) +{ + AUTODIAL_COMMAND Command; + + /* Copy the address into the command packet */ + RtlCopyMemory(&Command.Address, ConnectionAddress, sizeof(AUTODIAL_ADDR)); + + /* Set the New Connection flag and copy the connection data */ + Command.NewConnection = TRUE; + RtlCopyMemory(&Command.Connection, Connection, sizeof(AUTODIAL_CONN)); + + /* Send it to the driver */ + return AcsHlpSendCommand(&Command); +} + diff --git a/reactos/dll/win32/rasadhlp/init.c b/reactos/dll/win32/rasadhlp/init.c new file mode 100644 index 00000000000..c0c05350aaa --- /dev/null +++ b/reactos/dll/win32/rasadhlp/init.c @@ -0,0 +1,30 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Winsock 2 SPI + * FILE: lib/mswsock/lib/init.c + * PURPOSE: DLL Initialization + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +WINAPI +DllMain(HINSTANCE Instance, + DWORD Reason, + LPVOID Reserved) +{ + /* Check if we're being attached */ + if (Reason == DLL_PROCESS_ATTACH) + { + /* Let's disable TLC calls as an optimization */ + DisableThreadLibraryCalls(Instance); + } + + /* We're done */ + return TRUE; +} diff --git a/reactos/dll/win32/rasadhlp/precomp.h b/reactos/dll/win32/rasadhlp/precomp.h new file mode 100644 index 00000000000..db24ad64efa --- /dev/null +++ b/reactos/dll/win32/rasadhlp/precomp.h @@ -0,0 +1,102 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Ancillary Function Driver DLL + * FILE: include/msafd.h + * PURPOSE: Ancillary Function Driver DLL header + */ + +#define _WIN32_WINNT 0x502 +#define _CRT_SECURE_NO_DEPRECATE +#define WIN32_NO_STATUS + +/* PSDK Headers */ +#include +#include +#include +#include + +/* NDK */ +#include +#include + +/* Shared GUIDs */ +#include + +/* These should go in rasadhlp.h */ +#define FILE_DEVICE_ACD 0x000000F1 +#define _ACD_CTL_CODE(function, method, access) \ + CTL_CODE(FILE_DEVICE_ACD, function, method, access) + +#define IOCTL_ACD_RESET \ + _ACD_CTL_CODE(0, METHOD_BUFFERED, FILE_WRITE_ACCESS) +#define IOCTL_ACD_ENABLE \ + _ACD_CTL_CODE(1, METHOD_BUFFERED, FILE_WRITE_ACCESS) +#define IOCTL_ACD_NOTIFICATION \ + _ACD_CTL_CODE(2, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_ACD_KEEPALIVE \ + _ACD_CTL_CODE(3, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_ACD_COMPLETION \ + _ACD_CTL_CODE(4, METHOD_BUFFERED, FILE_WRITE_ACCESS) +#define IOCTL_ACD_CONNECT_ADDRESS \ + _ACD_CTL_CODE(5, METHOD_BUFFERED, FILE_READ_ACCESS) + +typedef enum +{ + AutoDialIp, + AutoDialIpx, + AutoDialNetBios, + AutoDialIpHost +} AUTODIAL_FAMILY; + +typedef enum +{ + ConnectionIpxLana, + ConnectionIp, + ConnectionIpHost, + ConnectionNetBiosMac, +} CONNECTION_FAMILY; + +typedef struct _AUTODIAL_ADDR +{ + AUTODIAL_FAMILY Family; + union + { + IN_ADDR Ip4Address; + CHAR IpxNode[6]; + CHAR NetBiosAddress[NETBIOS_NAME_LENGTH]; + CHAR HostName[INTERNET_MAX_PATH_LENGTH]; + }; +} AUTODIAL_ADDR, *PAUTODIAL_ADDR; + +typedef struct _AUTODIAL_CONN +{ + CONNECTION_FAMILY Family; + union + { + UCHAR IpxLana; + ULONG Ip4Address; + WCHAR ConnectionName[32]; + CHAR NetBiosMac[6]; + }; +} AUTODIAL_CONN, *PAUTODIAL_CONN; + +typedef struct _AUTODIAL_COMMAND +{ + AUTODIAL_ADDR Address; + BOOL NewConnection; + AUTODIAL_CONN Connection; +} AUTODIAL_COMMAND, *PAUTODIAL_COMMAND; + +BOOLEAN +WINAPI +AcsHlpNoteNewConnection( + IN PAUTODIAL_ADDR ConnectionAddress, + IN PAUTODIAL_CONN Connection +); + +BOOLEAN +WINAPI +AcsHlpAttemptConnection( + IN PAUTODIAL_ADDR ConnectionAddress +); + diff --git a/reactos/dll/win32/rasadhlp/rasadhlp.rbuild b/reactos/dll/win32/rasadhlp/rasadhlp.rbuild new file mode 100644 index 00000000000..efb5ed27779 --- /dev/null +++ b/reactos/dll/win32/rasadhlp/rasadhlp.rbuild @@ -0,0 +1,13 @@ + + + + + include/reactos/winsock + . + kernel32 + ntdll + ws2_32 + autodial.c + init.c + winsock.c + diff --git a/reactos/dll/win32/rasadhlp/rasadhlp.spec b/reactos/dll/win32/rasadhlp/rasadhlp.spec new file mode 100644 index 00000000000..baf38e8b01d --- /dev/null +++ b/reactos/dll/win32/rasadhlp/rasadhlp.spec @@ -0,0 +1,6 @@ +@ stdcall AcsHlpAttemptConnection(ptr) +@ stub AcsHlpNbConnection +@ stdcall AcsHlpNoteNewConnection(ptr ptr) +@ stdcall WSAttemptAutodialAddr(ptr long) +@ stdcall WSAttemptAutodialName(ptr) +@ stdcall WSNoteSuccessfulHostentLookup(ptr long) diff --git a/reactos/dll/win32/rasadhlp/winsock.c b/reactos/dll/win32/rasadhlp/winsock.c new file mode 100644 index 00000000000..f85661d33e6 --- /dev/null +++ b/reactos/dll/win32/rasadhlp/winsock.c @@ -0,0 +1,137 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Winsock 2 SPI + * FILE: lib/mswsock/lib/init.c + * PURPOSE: DLL Initialization + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +/* + * @implemented + */ +BOOL +WINAPI +WSAttemptAutodialAddr(IN CONST SOCKADDR FAR *Name, + IN INT NameLength) +{ + PSOCKADDR_IN Ip = (PSOCKADDR_IN)Name; + PSOCKADDR_NB NetBios = (PSOCKADDR_NB)Name; + AUTODIAL_ADDR AutodialAdddress; + + /* Check the family type */ + switch (Name->sa_family) + { + case AF_INET: + /* Normal IPv4, set the Autodial Address Data */ + AutodialAdddress.Family = AutoDialIp; + AutodialAdddress.Ip4Address = Ip->sin_addr; + break; + + case AF_NETBIOS: + /* NetBIOS, set the Autodial Address Data*/ + AutodialAdddress.Family = AutoDialNetBios; + RtlCopyMemory(&AutodialAdddress.NetBiosAddress, + NetBios->snb_name, + NETBIOS_NAME_LENGTH); + break; + + default: + /* Unsupported family type */ + return FALSE; + } + + /* Call the public routine */ + return AcsHlpAttemptConnection(&AutodialAdddress); +} + +/* + * @implemented + */ +BOOL +WINAPI +WSAttemptAutodialName(IN CONST LPWSAQUERYSETW Restrictions) +{ + AUTODIAL_ADDR AutodialAdddress; + CHAR AnsiIp[17]; + LPGUID Guid = Restrictions->lpServiceClassId; + + /* Make sure we actually have a name */ + if (!Restrictions->lpszServiceInstanceName) return FALSE; + + /* Check if this is the Hostname GUID */ + if (!memcmp(Guid, &HostnameGuid, sizeof(GUID))) + { + /* It is. Set up the Autodial Address Data */ + AutodialAdddress.Family = AutoDialIpHost; + WideCharToMultiByte(CP_ACP, + 0, + Restrictions->lpszServiceInstanceName, + -1, + AutodialAdddress.HostName, + INTERNET_MAX_PATH_LENGTH - 1, + 0, + 0); + + /* Call the public routine */ + return AcsHlpAttemptConnection(&AutodialAdddress); + } + else if (!memcmp(Guid, &AddressGuid, sizeof(GUID))) + { + /* It's actually the IP String GUID */ + AutodialAdddress.Family = AutoDialIp; + + /* Convert the IP String to ANSI and then convert it to IP */ + WideCharToMultiByte(CP_ACP, + 0, + Restrictions->lpszServiceInstanceName, + -1, + AnsiIp, + sizeof(AnsiIp) - 1, + 0, + 0); + _strlwr(AnsiIp); + AutodialAdddress.Ip4Address.S_un.S_addr = inet_addr(AnsiIp); + + /* Make sure the IP is valid */ + if (AutodialAdddress.Ip4Address.S_un.S_addr == -1) return FALSE; + + /* Call the public routine */ + return AcsHlpAttemptConnection(&AutodialAdddress); + } + else + { + /* Unknown GUID type */ + return FALSE; + } +} + +/* + * @implemented + */ +VOID +WINAPI +WSNoteSuccessfulHostentLookup(IN CONST CHAR FAR *Name, + IN CONST ULONG Address) +{ + AUTODIAL_ADDR AutodialAdddress; + AUTODIAL_CONN AutodialConnection; + + /* Make sure there actually is a name */ + if (!(Name) || !strlen(Name)) return; + + /* Setup the Address */ + AutodialAdddress.Family = AutoDialIpHost; + strcpy(AutodialAdddress.HostName, Name); + + /* Setup the new connection */ + AutodialConnection.Family = ConnectionIp; + AutodialConnection.Ip4Address = Address; + AcsHlpNoteNewConnection(&AutodialAdddress, &AutodialConnection); +} + diff --git a/reactos/dll/win32/shell32/shlview.c b/reactos/dll/win32/shell32/shlview.c index acfb45b9df0..9f5624d7a4b 100644 --- a/reactos/dll/win32/shell32/shlview.c +++ b/reactos/dll/win32/shell32/shlview.c @@ -1450,8 +1450,8 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn if (pds) { - DWORD dwEffect; - DoDragDrop(pda, pds, dwEffect, &dwEffect); + DWORD dwEffect2; + DoDragDrop(pda, pds, dwEffect, &dwEffect2); } IDataObject_Release(pda); } diff --git a/reactos/dll/win32/shlwapi/regstream.c b/reactos/dll/win32/shlwapi/regstream.c index 6aca8f937ef..eb906a7dc8d 100644 --- a/reactos/dll/win32/shlwapi/regstream.c +++ b/reactos/dll/win32/shlwapi/regstream.c @@ -43,6 +43,12 @@ typedef struct LPBYTE pbBuffer; DWORD dwLength; DWORD dwPos; + DWORD dwMode; + union { + LPSTR keyNameA; + LPWSTR keyNameW; + }u; + BOOL bUnicode; } ISHRegStream; /************************************************************************** @@ -98,11 +104,34 @@ static ULONG WINAPI IStream_fnRelease(IStream *iface) { TRACE(" destroying SHReg IStream (%p)\n",This); - HeapFree(GetProcessHeap(),0,This->pbBuffer); - if (This->hKey) - RegCloseKey(This->hKey); + { + /* write back data in REG_BINARY */ + if (This->dwMode == STGM_READWRITE || This->dwMode == STGM_WRITE) + { + if (This->dwLength) + { + if (This->bUnicode) + RegSetValueExW(This->hKey, This->u.keyNameW, 0, REG_BINARY, + (const BYTE *) This->pbBuffer, This->dwLength); + else + RegSetValueExA(This->hKey, This->u.keyNameA, 0, REG_BINARY, + (const BYTE *) This->pbBuffer, This->dwLength); + } + else + { + if (This->bUnicode) + RegDeleteValueW(This->hKey, This->u.keyNameW); + else + RegDeleteValueA(This->hKey, This->u.keyNameA); + } + } + RegCloseKey(This->hKey); + } + + HeapFree(GetProcessHeap(),0,This->u.keyNameA); + HeapFree(GetProcessHeap(),0,This->pbBuffer); HeapFree(GetProcessHeap(),0,This); return 0; } @@ -116,24 +145,21 @@ static ULONG WINAPI IStream_fnRelease(IStream *iface) static HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG* pcbRead) { ISHRegStream *This = (ISHRegStream *)iface; - - DWORD dwBytesToRead, dwBytesLeft; + DWORD dwBytesToRead; TRACE("(%p)->(%p,0x%08x,%p)\n",This, pv, cb, pcbRead); - if (!pv) - return STG_E_INVALIDPOINTER; + if (This->dwPos >= This->dwLength) + dwBytesToRead = 0; + else + dwBytesToRead = This->dwLength - This->dwPos; - dwBytesLeft = This->dwLength - This->dwPos; - - if ( 0 >= dwBytesLeft ) /* end of buffer */ - return S_FALSE; - - dwBytesToRead = ( cb > dwBytesLeft) ? dwBytesLeft : cb; - - memmove ( pv, (This->pbBuffer) + (This->dwPos), dwBytesToRead); - - This->dwPos += dwBytesToRead; /* adjust pointer */ + dwBytesToRead = (cb > dwBytesToRead) ? dwBytesToRead : cb; + if (dwBytesToRead != 0) /* not at end of buffer and we want to read something */ + { + memmove(pv, This->pbBuffer + This->dwPos, dwBytesToRead); + This->dwPos += dwBytesToRead; /* adjust pointer */ + } if (pcbRead) *pcbRead = dwBytesToRead; @@ -147,13 +173,29 @@ static HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG static HRESULT WINAPI IStream_fnWrite (IStream * iface, const void* pv, ULONG cb, ULONG* pcbWritten) { ISHRegStream *This = (ISHRegStream *)iface; + DWORD newLen = This->dwPos + cb; - TRACE("(%p)\n",This); + TRACE("(%p, %p, %d, %p)\n",This, pv, cb, pcbWritten); + + if (newLen < This->dwPos) /* overflow */ + return STG_E_INSUFFICIENTMEMORY; + + if (newLen > This->dwLength) + { + LPBYTE newBuf = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pbBuffer, newLen); + if (!newBuf) + return STG_E_INSUFFICIENTMEMORY; + + This->dwLength = newLen; + This->pbBuffer = newBuf; + } + memmove(This->pbBuffer + This->dwPos, pv, cb); + This->dwPos += cb; /* adjust pointer */ if (pcbWritten) - *pcbWritten = 0; + *pcbWritten = cb; - return E_NOTIMPL; + return S_OK; } /************************************************************************** @@ -162,12 +204,28 @@ static HRESULT WINAPI IStream_fnWrite (IStream * iface, const void* pv, ULONG cb static HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) { ISHRegStream *This = (ISHRegStream *)iface; + LARGE_INTEGER tmp; + TRACE("(%p, %s, %d %p)\n", This, + wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); - TRACE("(%p)\n",This); + if (dwOrigin == STREAM_SEEK_SET) + tmp = dlibMove; + else if (dwOrigin == STREAM_SEEK_CUR) + tmp.QuadPart = This->dwPos + dlibMove.QuadPart; + else if (dwOrigin == STREAM_SEEK_END) + tmp.QuadPart = This->dwLength + dlibMove.QuadPart; + else + return STG_E_INVALIDPARAMETER; + + if (tmp.QuadPart < 0) + return STG_E_INVALIDFUNCTION; + + /* we cut off the high part here */ + This->dwPos = tmp.LowPart; if (plibNewPosition) - plibNewPosition->QuadPart = 0; - return E_NOTIMPL; + plibNewPosition->QuadPart = This->dwPos; + return S_OK; } /************************************************************************** @@ -176,9 +234,21 @@ static HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, D static HRESULT WINAPI IStream_fnSetSize (IStream * iface, ULARGE_INTEGER libNewSize) { ISHRegStream *This = (ISHRegStream *)iface; + DWORD newLen; + LPBYTE newBuf; - TRACE("(%p)\n",This); - return E_NOTIMPL; + TRACE("(%p, %s)\n", This, wine_dbgstr_longlong(libNewSize.QuadPart)); + + /* we cut off the high part here */ + newLen = libNewSize.LowPart; + newBuf = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pbBuffer, newLen); + if (!newBuf) + return STG_E_INSUFFICIENTMEMORY; + + This->pbBuffer = newBuf; + This->dwLength = newLen; + + return S_OK; } /************************************************************************** @@ -193,6 +263,8 @@ static HRESULT WINAPI IStream_fnCopyTo (IStream * iface, IStream* pstm, ULARGE_I pcbRead->QuadPart = 0; if (pcbWritten) pcbWritten->QuadPart = 0; + + /* TODO implement */ return E_NOTIMPL; } @@ -205,6 +277,7 @@ static HRESULT WINAPI IStream_fnCommit (IStream * iface, DWORD grfCommitFlags) TRACE("(%p)\n",This); + /* commit not supported by this stream */ return E_NOTIMPL; } @@ -217,6 +290,7 @@ static HRESULT WINAPI IStream_fnRevert (IStream * iface) TRACE("(%p)\n",This); + /* revert not supported by this stream */ return E_NOTIMPL; } @@ -229,19 +303,35 @@ static HRESULT WINAPI IStream_fnLockUnlockRegion (IStream * iface, ULARGE_INTEGE TRACE("(%p)\n",This); + /* lock/unlock not supported by this stream */ return E_NOTIMPL; } /************************************************************************* * IStream_fnStat */ -static HRESULT WINAPI IStream_fnStat (IStream * iface, STATSTG* pstatstg, DWORD grfStatFlag) +static HRESULT WINAPI IStream_fnStat (IStream * iface, STATSTG* pstatstg, DWORD grfStatFlag) { ISHRegStream *This = (ISHRegStream *)iface; - TRACE("(%p)\n",This); + TRACE("(%p, %p, %d)\n",This,pstatstg,grfStatFlag); - return E_NOTIMPL; + pstatstg->pwcsName = NULL; + pstatstg->type = STGTY_STREAM; + pstatstg->cbSize.QuadPart = This->dwLength; + pstatstg->mtime.dwHighDateTime = 0; + pstatstg->mtime.dwLowDateTime = 0; + pstatstg->ctime.dwHighDateTime = 0; + pstatstg->ctime.dwLowDateTime = 0; + pstatstg->atime.dwHighDateTime = 0; + pstatstg->atime.dwLowDateTime = 0; + pstatstg->grfMode = This->dwMode; + pstatstg->grfLocksSupported = 0; + pstatstg->clsid = CLSID_NULL; + pstatstg->grfStateBits = 0; + pstatstg->reserved = 0; + + return S_OK; } /************************************************************************* @@ -252,8 +342,9 @@ static HRESULT WINAPI IStream_fnClone (IStream * iface, IStream** ppstm) ISHRegStream *This = (ISHRegStream *)iface; TRACE("(%p)\n",This); - if (ppstm) - *ppstm = NULL; + *ppstm = NULL; + + /* clone not supported by this stream */ return E_NOTIMPL; } @@ -333,7 +424,10 @@ static ISHRegStream rsDummyRegStream = NULL, NULL, 0, - 0 + 0, + STGM_READWRITE, + {NULL}, + FALSE }; /************************************************************************** @@ -341,7 +435,7 @@ static ISHRegStream rsDummyRegStream = * * Internal helper: Create and initialise a new registry stream object. */ -static IStream *IStream_Create(HKEY hKey, LPBYTE pbBuffer, DWORD dwLength) +static ISHRegStream *IStream_Create(HKEY hKey, LPBYTE pbBuffer, DWORD dwLength) { ISHRegStream* regStream; @@ -355,9 +449,12 @@ static IStream *IStream_Create(HKEY hKey, LPBYTE pbBuffer, DWORD dwLength) regStream->pbBuffer = pbBuffer; regStream->dwLength = dwLength; regStream->dwPos = 0; + regStream->dwMode = STGM_READWRITE; + regStream->u.keyNameA = NULL; + regStream->bUnicode = FALSE; } TRACE ("Returning %p\n", regStream); - return (IStream *)regStream; + return regStream; } /************************************************************************* @@ -378,21 +475,52 @@ static IStream *IStream_Create(HKEY hKey, LPBYTE pbBuffer, DWORD dwLength) IStream * WINAPI SHOpenRegStream2A(HKEY hKey, LPCSTR pszSubkey, LPCSTR pszValue,DWORD dwMode) { + ISHRegStream *tmp; HKEY hStrKey = NULL; LPBYTE lpBuff = NULL; - DWORD dwLength, dwType; + DWORD dwLength = 0; + LONG ret; TRACE("(%p,%s,%s,0x%08x)\n", hKey, pszSubkey, pszValue, dwMode); - /* Open the key, read in binary data and create stream */ - if (!RegOpenKeyExA (hKey, pszSubkey, 0, KEY_READ, &hStrKey) && - !RegQueryValueExA (hStrKey, pszValue, 0, 0, 0, &dwLength) && - (lpBuff = HeapAlloc (GetProcessHeap(), 0, dwLength)) && - !RegQueryValueExA (hStrKey, pszValue, 0, &dwType, lpBuff, &dwLength) && - dwType == REG_BINARY) - return IStream_Create(hStrKey, lpBuff, dwLength); + if (dwMode == STGM_READ) + ret = RegOpenKeyExA(hKey, pszSubkey, 0, KEY_READ, &hStrKey); + else /* in write mode we make sure the subkey exits */ + ret = RegCreateKeyExA(hKey, pszSubkey, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &hStrKey, NULL); - HeapFree (GetProcessHeap(), 0, lpBuff); + if (ret == ERROR_SUCCESS) + { + if (dwMode == STGM_READ || dwMode == STGM_READWRITE) + { + /* read initial data */ + ret = RegQueryValueExA(hStrKey, pszValue, 0, 0, 0, &dwLength); + if (ret == ERROR_SUCCESS && dwLength) + { + lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); + RegQueryValueExA(hStrKey, pszValue, 0, 0, lpBuff, &dwLength); + } + } + + if (!dwLength) + lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); + + tmp = IStream_Create(hStrKey, lpBuff, dwLength); + if(tmp) + { + if(pszValue) + { + int len = lstrlenA(pszValue) + 1; + tmp->u.keyNameA = HeapAlloc(GetProcessHeap(), 0, len); + memcpy(tmp->u.keyNameA, pszValue, len); + } + + tmp->dwMode = dwMode; + tmp->bUnicode = FALSE; + return (IStream *)tmp; + } + } + + HeapFree(GetProcessHeap(), 0, lpBuff); if (hStrKey) RegCloseKey(hStrKey); return NULL; @@ -406,22 +534,53 @@ IStream * WINAPI SHOpenRegStream2A(HKEY hKey, LPCSTR pszSubkey, IStream * WINAPI SHOpenRegStream2W(HKEY hKey, LPCWSTR pszSubkey, LPCWSTR pszValue, DWORD dwMode) { + ISHRegStream *tmp; HKEY hStrKey = NULL; LPBYTE lpBuff = NULL; - DWORD dwLength, dwType; + DWORD dwLength = 0; + LONG ret; TRACE("(%p,%s,%s,0x%08x)\n", hKey, debugstr_w(pszSubkey), debugstr_w(pszValue), dwMode); - /* Open the key, read in binary data and create stream */ - if (!RegOpenKeyExW (hKey, pszSubkey, 0, KEY_READ, &hStrKey) && - !RegQueryValueExW (hStrKey, pszValue, 0, 0, 0, &dwLength) && - (lpBuff = HeapAlloc (GetProcessHeap(), 0, dwLength)) && - !RegQueryValueExW (hStrKey, pszValue, 0, &dwType, lpBuff, &dwLength) && - dwType == REG_BINARY) - return IStream_Create(hStrKey, lpBuff, dwLength); + if (dwMode == STGM_READ) + ret = RegOpenKeyExW(hKey, pszSubkey, 0, KEY_READ, &hStrKey); + else /* in write mode we make sure the subkey exits */ + ret = RegCreateKeyExW(hKey, pszSubkey, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &hStrKey, NULL); - HeapFree (GetProcessHeap(), 0, lpBuff); + if (ret == ERROR_SUCCESS) + { + if (dwMode == STGM_READ || dwMode == STGM_READWRITE) + { + /* read initial data */ + ret = RegQueryValueExW(hStrKey, pszValue, 0, 0, 0, &dwLength); + if (ret == ERROR_SUCCESS && dwLength) + { + lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); + RegQueryValueExW(hStrKey, pszValue, 0, 0, lpBuff, &dwLength); + } + } + + if (!dwLength) + lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); + + tmp = IStream_Create(hStrKey, lpBuff, dwLength); + if(tmp) + { + if(pszValue) + { + int len = lstrlenW(pszValue) + 1; + tmp->u.keyNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + memcpy(tmp->u.keyNameW, pszValue, len * sizeof(WCHAR)); + } + + tmp->dwMode = dwMode; + tmp->bUnicode = TRUE; + return (IStream *)tmp; + } + } + + HeapFree(GetProcessHeap(), 0, lpBuff); if (hStrKey) RegCloseKey(hStrKey); return NULL; @@ -487,24 +646,25 @@ IStream * WINAPI SHOpenRegStreamW(HKEY hkey, LPCWSTR pszSubkey, * A copy of the memory pointed to by lpbData is made, and is freed * when the stream is released. */ -IStream * WINAPI SHCreateMemStream(LPBYTE lpbData, DWORD dwDataLen) +IStream * WINAPI SHCreateMemStream(const BYTE *lpbData, UINT dwDataLen) { IStream *iStrmRet = NULL; + LPBYTE lpbDup; TRACE("(%p,%d)\n", lpbData, dwDataLen); - if (lpbData) + if (!lpbData) + dwDataLen = 0; + + lpbDup = HeapAlloc(GetProcessHeap(), 0, dwDataLen); + + if (lpbDup) { - LPBYTE lpbDup = HeapAlloc(GetProcessHeap(), 0, dwDataLen); + memcpy(lpbDup, lpbData, dwDataLen); + iStrmRet = (IStream *)IStream_Create(NULL, lpbDup, dwDataLen); - if (lpbDup) - { - memcpy(lpbDup, lpbData, dwDataLen); - iStrmRet = IStream_Create(NULL, lpbDup, dwDataLen); - - if (!iStrmRet) - HeapFree(GetProcessHeap(), 0, lpbDup); - } + if (!iStrmRet) + HeapFree(GetProcessHeap(), 0, lpbDup); } return iStrmRet; } @@ -539,7 +699,7 @@ HRESULT WINAPI SHCreateStreamWrapper(LPBYTE lpbData, DWORD dwDataLen, if(dwReserved || !lppStream) return E_INVALIDARG; - lpStream = IStream_Create(NULL, lpbData, dwDataLen); + lpStream = (IStream *)IStream_Create(NULL, lpbData, dwDataLen); if(!lpStream) return E_OUTOFMEMORY; diff --git a/reactos/dll/win32/shlwapi/shlwapi.spec b/reactos/dll/win32/shlwapi/shlwapi.spec index 342772285cb..1a791745308 100644 --- a/reactos/dll/win32/shlwapi/shlwapi.spec +++ b/reactos/dll/win32/shlwapi/shlwapi.spec @@ -643,7 +643,7 @@ @ stdcall PathQuoteSpacesA (str) @ stdcall PathQuoteSpacesW (wstr) @ stdcall PathRelativePathToA(ptr str long str long) -@ stdcall PathRelativePathToW(ptr str long str long) +@ stdcall PathRelativePathToW(ptr wstr long wstr long) @ stdcall PathRemoveArgsA(str) @ stdcall PathRemoveArgsW(wstr) @ stdcall PathRemoveBackslashA (str) @@ -700,9 +700,9 @@ @ stdcall SHGetValueW ( long wstr wstr ptr ptr ptr ) @ stdcall SHIsLowMemoryMachine(long) @ stdcall SHOpenRegStream2A(long str str long) -@ stdcall SHOpenRegStream2W(long wstr str long) +@ stdcall SHOpenRegStream2W(long wstr wstr long) @ stdcall SHOpenRegStreamA(long str str long) -@ stdcall SHOpenRegStreamW(long wstr str long) +@ stdcall SHOpenRegStreamW(long wstr wstr long) @ stdcall SHQueryInfoKeyA(long ptr ptr ptr ptr) @ stdcall SHQueryInfoKeyW(long ptr ptr ptr ptr) @ stdcall SHQueryValueExA(long str ptr ptr ptr ptr) @@ -738,7 +738,7 @@ @ stdcall SHRegSetUSValueA ( str str long ptr long long) @ stdcall SHRegSetUSValueW ( wstr wstr long ptr long long) @ stdcall SHRegWriteUSValueA (long str long ptr long long) -@ stdcall SHRegWriteUSValueW (long str long ptr long long) +@ stdcall SHRegWriteUSValueW (long wstr long ptr long long) @ stdcall SHRegisterValidateTemplate(wstr long) @ stdcall SHReleaseThreadRef() @ stdcall SHSetThreadRef (ptr) @@ -785,7 +785,7 @@ @ stdcall StrPBrkW(wstr wstr) @ stdcall StrRChrA (str str long) @ stdcall StrRChrIA (str str long) -@ stdcall StrRChrIW (str str long) +@ stdcall StrRChrIW (wstr wstr long) @ stdcall StrRChrW (wstr wstr long) @ stdcall StrRStrIA (str str str) @ stdcall StrRStrIW (wstr wstr wstr) diff --git a/reactos/dll/win32/user32/controls/edit.c b/reactos/dll/win32/user32/controls/edit.c index 92d4c593810..901b0ad2128 100644 --- a/reactos/dll/win32/user32/controls/edit.c +++ b/reactos/dll/win32/user32/controls/edit.c @@ -164,6 +164,7 @@ typedef struct (LPARAM)(es->hwndSelf)); \ } while(0) + /********************************************************************* * * EM_CANUNDO @@ -1225,7 +1226,7 @@ static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force) { WARN("edit hwnd %p already destroyed\n", es->hwndSelf); return; - } + } if (!es->lock_count) { ERR("lock_count == 0 ... please report\n"); @@ -3676,8 +3677,8 @@ static LRESULT EDIT_WM_KeyDown(EDITSTATE *es, INT key) } break; case VK_ESCAPE: - if (!(es->style & ES_MULTILINE) && EDIT_IsInsideDialog(es)) - PostMessageW(es->hwndParent, WM_CLOSE, 0, 0); + if ((es->style & ES_MULTILINE) && EDIT_IsInsideDialog(es)) + PostMessageW(es->hwndParent, WM_CLOSE, 0, 0); break; case VK_TAB: if ((es->style & ES_MULTILINE) && EDIT_IsInsideDialog(es)) @@ -4601,8 +4602,8 @@ static LRESULT EDIT_WM_NCCreate(HWND hwnd, LPCREATESTRUCTW lpcs, BOOL unicode) * WM_XXX messages before WM_NCCREATE is completed. */ - es->is_unicode = unicode; - es->style = lpcs->style; + es->is_unicode = unicode; + es->style = lpcs->style; es->bEnableState = !(es->style & WS_DISABLED); @@ -4670,7 +4671,7 @@ static LRESULT EDIT_WM_NCCreate(HWND hwnd, LPCREATESTRUCTW lpcs, BOOL unicode) * If WS_BORDER without WS_EX_CLIENTEDGE is specified we shouldn't have * a nonclient area and we should handle painting the border ourselves. * - * When making modifications please ensure that the code still works + * When making modifications please ensure that the code still works * for edit controls created directly with style 0x50800000, exStyle 0 * (which should have a single pixel border) */ @@ -4691,7 +4692,7 @@ static LRESULT EDIT_WM_NCCreate(HWND hwnd, LPCREATESTRUCTW lpcs, BOOL unicode) static LRESULT EDIT_WM_Create(EDITSTATE *es, LPCWSTR name) { RECT clientRect; - + TRACE("%s\n", debugstr_w(name)); /* * To initialize some final structure members, we call some helper @@ -4701,7 +4702,7 @@ static LRESULT EDIT_WM_Create(EDITSTATE *es, LPCWSTR name) */ EDIT_WM_SetFont(es, 0, FALSE); EDIT_EM_EmptyUndoBuffer(es); - + /* We need to calculate the format rect (applications may send EM_SETMARGINS before the control gets visible) */ GetClientRect(es->hwndSelf, &clientRect); @@ -4803,7 +4804,7 @@ LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, LRESULT result = 0; TRACE("hwnd=%p msg=%x (%s) wparam=%lx lparam=%lx\n", hwnd, msg, SPY_GetMsgName(msg, hwnd), wParam, lParam); - + if (!es && msg != WM_NCCREATE) return DefWindowProcT(hwnd, msg, wParam, lParam, unicode); @@ -5121,6 +5122,9 @@ LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, case EM_SETREADONLY16: #endif case EM_SETREADONLY: + { + DWORD old_style = es->style; + if (wParam) { SetWindowLongPtrW( hwnd, GWL_STYLE, GetWindowLongPtrW( hwnd, GWL_STYLE ) | ES_READONLY ); @@ -5130,8 +5134,13 @@ LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, GetWindowLongPtrW( hwnd, GWL_STYLE ) & ~ES_READONLY ); es->style &= ~ES_READONLY; } - result = 1; - break; + + if (old_style ^ es->style) + InvalidateRect(es->hwndSelf, NULL, TRUE); + + result = 1; + break; + } #ifndef __REACTOS__ case EM_SETWORDBREAKPROC16: @@ -5208,7 +5217,7 @@ LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, case WM_GETDLGCODE: result = DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS; - + if (es->style & ES_MULTILINE) result |= DLGC_WANTALLKEYS; @@ -5483,12 +5492,12 @@ LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, case WM_IME_CONTROL: break; - + default: result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode); break; } - + if (es) EDIT_UnlockBuffer(es, FALSE); TRACE("hwnd=%p msg=%x (%s) -- 0x%08lx\n", hwnd, msg, SPY_GetMsgName(msg, hwnd), result); diff --git a/reactos/dll/win32/user32/windows/dialog.c b/reactos/dll/win32/user32/windows/dialog.c index 7011fc27ec1..2569b58804f 100644 --- a/reactos/dll/win32/user32/windows/dialog.c +++ b/reactos/dll/win32/user32/windows/dialog.c @@ -181,10 +181,11 @@ void DIALOG_EnableOwner( HWND hOwner ) if (hOwner) hOwner = GetAncestor( hOwner, GA_ROOT ); if (!hOwner) return; - EnableWindow( hOwner, TRUE ); + EnableWindow( hOwner, TRUE ); } - /*********************************************************************** + +/*********************************************************************** * DIALOG_DisableOwner * * Helper function for modal dialogs to disable the @@ -205,7 +206,7 @@ BOOL DIALOG_DisableOwner( HWND hOwner ) return FALSE; } - /*********************************************************************** +/*********************************************************************** * DIALOG_GetControl32 * * Return the class and text of the control pointed to by ptr, @@ -303,10 +304,11 @@ static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info, p++; /* Next control is on dword boundary */ - return (const WORD *)((((int)p) + 3) & ~3); + return (const WORD *)(((UINT_PTR)p + 3) & ~3); } - /*********************************************************************** + +/*********************************************************************** * DIALOG_CreateControls32 * * Create the control windows for a dialog. @@ -645,9 +647,9 @@ static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result ) /* Get the font name */ result->pointSize = 0; + result->faceName = NULL; result->weight = FW_DONTCARE; result->italic = FALSE; - result->faceName = NULL; if (result->style & DS_SETFONT) { @@ -660,18 +662,18 @@ static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result ) */ if (result->pointSize == 0x7fff) { - /* We could call SystemParametersInfo here, but then we'd have - * to convert from pixel size to point size (which can be - * imprecise). - */ + /* We could call SystemParametersInfo here, but then we'd have + * to convert from pixel size to point size (which can be + * imprecise). + */ TRACE(" FONT: Using message box font\n"); } else { if (result->dialogEx) { - result->weight = GET_WORD(p); p++; - result->italic = LOBYTE(GET_WORD(p)); p++; + result->weight = GET_WORD(p); p++; + result->italic = LOBYTE(GET_WORD(p)); p++; } result->faceName = (LPCWSTR)p; p += wcslen( result->faceName ) + 1; @@ -726,7 +728,7 @@ static void DEFDLG_RestoreFocus( HWND hwnd ) /* If no saved focus control exists, set focus to the first visible, non-disabled, WS_TABSTOP control in the dialog */ infoPtr->hwndFocus = GetNextDlgTabItem( hwnd, 0, FALSE ); - if (!IsWindow( infoPtr->hwndFocus )) return; + if (!IsWindow( infoPtr->hwndFocus )) return; } DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus ); @@ -783,20 +785,19 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate, ncMetrics.cbSize = sizeof(NONCLIENTMETRICSW); if (SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncMetrics, 0)) - { - hUserFont = CreateFontIndirectW( &ncMetrics.lfMessageFont ); - } + { + hUserFont = CreateFontIndirectW( &ncMetrics.lfMessageFont ); + } } - else + else { - /* We convert the size to pixels and then make it -ve. This works - * for both +ve and -ve template.pointSize */ - int pixels; - pixels = MulDiv(template.pointSize, GetDeviceCaps(dc , LOGPIXELSY), 72); - hUserFont = CreateFontW( -pixels, 0, 0, 0, template.weight, - template.italic, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, - PROOF_QUALITY, FF_DONTCARE, - template.faceName ); + /* We convert the size to pixels and then make it -ve. This works + * for both +ve and -ve template.pointSize */ + int pixels = MulDiv(template.pointSize, GetDeviceCaps(dc , LOGPIXELSY), 72); + hUserFont = CreateFontW( -pixels, 0, 0, 0, template.weight, + template.italic, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, + PROOF_QUALITY, FF_DONTCARE, + template.faceName ); } if (hUserFont) @@ -840,7 +841,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate, { HMONITOR monitor = 0; MONITORINFO mon_info; - + mon_info.cbSize = sizeof(mon_info); if (template.style & DS_CENTER) { @@ -947,7 +948,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate, dlgInfo->hMenu = hMenu; dlgInfo->xBaseUnit = xBaseUnit; dlgInfo->yBaseUnit = yBaseUnit; - dlgInfo->idResult = 0; + dlgInfo->idResult = IDOK; dlgInfo->flags = flags; /* dlgInfo->hDialogHeap = 0; */ @@ -994,6 +995,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate, return 0; } + /*********************************************************************** * DEFDLG_FindDefButton * diff --git a/reactos/dll/win32/win32.rbuild b/reactos/dll/win32/win32.rbuild index 256607f7752..5b8ed61ec9f 100644 --- a/reactos/dll/win32/win32.rbuild +++ b/reactos/dll/win32/win32.rbuild @@ -412,6 +412,9 @@ + + + diff --git a/reactos/dll/win32/winspool/stubs.c b/reactos/dll/win32/winspool/stubs.c index 9f5365f624c..ef2e05528d8 100644 --- a/reactos/dll/win32/winspool/stubs.c +++ b/reactos/dll/win32/winspool/stubs.c @@ -802,6 +802,35 @@ EnumPrinterDriversW(LPWSTR Name, LPWSTR Environment, DWORD Level, PBYTE Buffer, return FALSE; } +/* + * @unimplemented + */ +DWORD +WINAPI +EnumPrinterKeyA(HANDLE Printer, LPSTR KeyName, LPTSTR Subkey, DWORD SubkeySize, PDWORD SubkeyReturned) +{ + OutputDebugStringW(L"winspool EnumPrinterKeyA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + *SubkeyReturned = 0; + + return ERROR_FILE_NOT_FOUND; +} + +/* + * @unimplemented + */ +DWORD +WINAPI +EnumPrinterKeyW(HANDLE Printer, LPWSTR KeyName, LPTSTR Subkey, DWORD SubkeySize, PDWORD SubkeyReturned) +{ + OutputDebugStringW(L"winspool EnumPrinterKeyW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + *SubkeyReturned = 0; + + return ERROR_FILE_NOT_FOUND; +} /* * @unimplemented diff --git a/reactos/dll/win32/winspool/winspool.spec b/reactos/dll/win32/winspool/winspool.spec index 9d6bcfa7d5f..8227e5290cb 100644 --- a/reactos/dll/win32/winspool/winspool.spec +++ b/reactos/dll/win32/winspool/winspool.spec @@ -124,6 +124,8 @@ @ stdcall EnumPrinterDriversW(wstr wstr long ptr long ptr ptr) @ stdcall EnumPrintersA(long ptr long ptr long ptr ptr) @ stdcall EnumPrintersW(long ptr long ptr long ptr ptr) +@ stdcall EnumPrinterKeyA(long str str long ptr) +@ stdcall EnumPrinterKeyW(long wstr wstr long ptr) @ stdcall ExtDeviceMode(long long ptr str str ptr str long) @ stdcall EnumPrintProcessorDatatypesA(str str long ptr long ptr ptr) @ stdcall EnumPrintProcessorDatatypesW(wstr wstr long ptr long ptr ptr) diff --git a/reactos/dll/win32/ws2_32_new/src/getxbyxx.c b/reactos/dll/win32/ws2_32_new/src/getxbyxx.c index 1c9da671f54..53489e07d24 100644 --- a/reactos/dll/win32/ws2_32_new/src/getxbyxx.c +++ b/reactos/dll/win32/ws2_32_new/src/getxbyxx.c @@ -103,7 +103,7 @@ WSAAPI getxyDataEnt(IN OUT PCHAR *Results, IN DWORD Length, IN LPSTR Name, - IN LPGUID Type, + IN LPCGUID Type, IN LPSTR *NewName) { PWSAQUERYSETA WsaQuery = (PWSAQUERYSETA)*Results; @@ -119,7 +119,7 @@ getxyDataEnt(IN OUT PCHAR *Results, RtlZeroMemory(WsaQuery, sizeof(*WsaQuery)); WsaQuery->dwSize = sizeof(*WsaQuery); WsaQuery->lpszServiceInstanceName = Name; - WsaQuery->lpServiceClassId = Type; + WsaQuery->lpServiceClassId = (LPGUID)Type; WsaQuery->dwNameSpace = NS_ALL; WsaQuery->dwNumberOfProtocols = 2; WsaQuery->lpafpProtocols = &afp[0]; diff --git a/reactos/drivers/filesystems/fastfat_new/create.c b/reactos/drivers/filesystems/fastfat_new/create.c index f2555de7b0f..a3a7bfb05be 100644 --- a/reactos/drivers/filesystems/fastfat_new/create.c +++ b/reactos/drivers/filesystems/fastfat_new/create.c @@ -11,16 +11,6 @@ #define NDEBUG #include "fastfat.h" -NTSYSAPI -NTSTATUS -NTAPI -RtlUpcaseUnicodeStringToCountedOemString( - IN OUT POEM_STRING DestinationString, - IN PCUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString -); - - /* FUNCTIONS *****************************************************************/ IO_STATUS_BLOCK @@ -41,6 +31,110 @@ FatiOpenRootDcb(IN PFAT_IRP_CONTEXT IrpContext, return Iosb; } +FF_ERROR +NTAPI +FatiTryToOpen(IN PFILE_OBJECT FileObject, + IN PVCB Vcb) +{ + OEM_STRING AnsiName; + CHAR AnsiNameBuf[512]; + FF_ERROR Error; + NTSTATUS Status; + FF_FILE *FileHandle; + + /* Convert the name to ANSI */ + AnsiName.Buffer = AnsiNameBuf; + AnsiName.Length = 0; + AnsiName.MaximumLength = sizeof(AnsiNameBuf); + RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); + Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, &FileObject->FileName, FALSE); + if (!NT_SUCCESS(Status)) + { + ASSERT(FALSE); + } + + /* Open the file with FullFAT */ + FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, &Error); + + /* Close the handle */ + if (FileHandle) FF_Close(FileHandle); + + /* Return status */ + return Error; +} + +IO_STATUS_BLOCK +NTAPI +FatiOpenExistingDir(IN PFAT_IRP_CONTEXT IrpContext, + IN PFILE_OBJECT FileObject, + IN PVCB Vcb, + IN PFCB ParentDcb, + IN PACCESS_MASK DesiredAccess, + IN USHORT ShareAccess, + IN ULONG AllocationSize, + IN PFILE_FULL_EA_INFORMATION EaBuffer, + IN ULONG EaLength, + IN UCHAR FileAttributes, + IN ULONG CreateDisposition, + IN BOOLEAN DeleteOnClose) +{ + IO_STATUS_BLOCK Iosb = {{0}}; + OEM_STRING AnsiName; + CHAR AnsiNameBuf[512]; + PFCB Fcb; + NTSTATUS Status; + FF_FILE *FileHandle; + + /* Only open is permitted */ + if (CreateDisposition != FILE_OPEN && + CreateDisposition != FILE_OPEN_IF) + { + Iosb.Status = STATUS_OBJECT_NAME_COLLISION; + return Iosb; + } + + // TODO: Check dir access + + /* Convert the name to ANSI */ + AnsiName.Buffer = AnsiNameBuf; + AnsiName.Length = 0; + AnsiName.MaximumLength = sizeof(AnsiNameBuf); + RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); + Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, &FileObject->FileName, FALSE); + if (!NT_SUCCESS(Status)) + { + ASSERT(FALSE); + } + + /* Open the dir with FullFAT */ + FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_DIR, NULL); + + if (!FileHandle) + { + Iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND; // FIXME: A shortcut for now + return Iosb; + } + + /* Create a new DCB for this directory */ + Fcb = FatCreateDcb(IrpContext, Vcb, ParentDcb, FileHandle); + + /* Set share access */ + IoSetShareAccess(*DesiredAccess, ShareAccess, FileObject, &Fcb->ShareAccess); + + /* Set context and section object pointers */ + FatSetFileObject(FileObject, + UserDirectoryOpen, + Fcb, + FatCreateCcb()); + + Iosb.Status = STATUS_SUCCESS; + Iosb.Information = FILE_OPENED; + + DPRINT1("Successfully opened dir %s\n", AnsiNameBuf); + + return Iosb; +} + IO_STATUS_BLOCK NTAPI FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext, @@ -227,9 +321,9 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, ULONG CreateDisposition; /* Control blocks */ - PVCB Vcb, DecodedVcb; - PFCB Fcb, NextFcb; - PCCB Ccb; + PVCB Vcb, DecodedVcb, RelatedVcb; + PFCB Fcb, NextFcb, RelatedDcb; + PCCB Ccb, RelatedCcb; PFCB ParentDcb; /* IRP data */ @@ -249,8 +343,11 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, IO_STATUS_BLOCK Iosb; PIO_STACK_LOCATION IrpSp; BOOLEAN EndBackslash = FALSE, OpenedAsDos; - UNICODE_STRING RemainingPart, FirstName, NextName; + UNICODE_STRING RemainingPart, FirstName, NextName, FileNameUpcased; OEM_STRING AnsiFirstName; + FF_ERROR FfError; + TYPE_OF_OPEN TypeOfOpen; + BOOLEAN OplockPostIrp = FALSE; Iosb.Status = STATUS_SUCCESS; @@ -427,8 +524,42 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, /* Check if this is a relative open */ if (RelatedFO) { - // RelatedFO will be a parent directory - UNIMPLEMENTED; + /* Decode the file object */ + TypeOfOpen = FatDecodeFileObject(RelatedFO, + &RelatedVcb, + &RelatedDcb, + &RelatedCcb); + + /* Check open type */ + if (TypeOfOpen != UserFileOpen && + TypeOfOpen != UserDirectoryOpen) + { + DPRINT1("Invalid file object!\n"); + + /* Cleanup and return */ + FatReleaseVcb(IrpContext, Vcb); + return STATUS_OBJECT_PATH_NOT_FOUND; + } + + /* File path must be relative */ + if (FileName.Length != 0 && + FileName.Buffer[0] == L'\\') + { + /* The name is absolute, fail */ + FatReleaseVcb(IrpContext, Vcb); + return STATUS_OBJECT_NAME_INVALID; + } + + /* Make sure volume is the same */ + ASSERT(RelatedVcb == Vcb); + + /* Save VPB */ + FileObject->Vpb = RelatedFO->Vpb; + + /* Set parent DCB */ + ParentDcb = RelatedDcb; + + DPRINT1("Opening file '%wZ' relatively to '%wZ'\n", &FileName, &ParentDcb->FullFileName); } else { @@ -544,10 +675,22 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, &OpenedAsDos); } - /* Check if we found anything */ + /* If nothing found - try with unicode */ if (!NextFcb && Fcb->Dcb.SplayLinksUnicode) { - ASSERT(FALSE); + FileNameUpcased.Buffer = FsRtlAllocatePool(PagedPool, FirstName.Length); + FileNameUpcased.Length = 0; + FileNameUpcased.MaximumLength = FirstName.Length; + + /* Downcase and then upcase to normalize it */ + Status = RtlDowncaseUnicodeString(&FileNameUpcased, &FirstName, FALSE); + Status = RtlUpcaseUnicodeString(&FileNameUpcased, &FileNameUpcased, FALSE); + + /* Try to find FCB again using unicode name */ + NextFcb = FatFindFcb(IrpContext, + &Fcb->Dcb.SplayLinksUnicode, + (PSTRING)&FileNameUpcased, + &OpenedAsDos); } /* Move to the next FCB */ @@ -589,8 +732,116 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, /* We have a valid FCB now */ if (!RemainingPart.Length) { - DPRINT1("It's possible to open an existing FCB\n"); - ASSERT(FALSE); + /* Check for target dir open */ + if (OpenTargetDirectory) + { + DPRINT1("Opening target dir is missing\n"); + ASSERT(FALSE); + } + + /* Check this FCB's type */ + if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB || + FatNodeType(Fcb) == FAT_NTC_DCB) + { + /* Open a directory */ + if (NonDirectoryFile) + { + /* Forbidden */ + Iosb.Status = STATUS_FILE_IS_A_DIRECTORY; + ASSERT(FALSE); + return Iosb.Status; + } + + /* Open existing DCB */ + Iosb = FatiOpenExistingDcb(IrpContext, + FileObject, + Vcb, + Fcb, + DesiredAccess, + ShareAccess, + CreateDisposition, + NoEaKnowledge, + DeleteOnClose); + + /* Save information */ + Irp->IoStatus.Information = Iosb.Information; + + /* Unlock VCB */ + FatReleaseVcb(IrpContext, Vcb); + + /* Complete the request */ + FatCompleteRequest(IrpContext, Irp, Iosb.Status); + + return Iosb.Status; + } + else if (FatNodeType(Fcb) == FAT_NTC_FCB) + { + /* Open a file */ + if (OpenDirectory) + { + /* Forbidden */ + Iosb.Status = STATUS_NOT_A_DIRECTORY; + ASSERT(FALSE); + return Iosb.Status; + } + + /* Check for trailing backslash */ + if (EndBackslash) + { + /* Forbidden */ + Iosb.Status = STATUS_OBJECT_NAME_INVALID; + ASSERT(FALSE); + return Iosb.Status; + } + + Iosb = FatiOpenExistingFcb(IrpContext, + FileObject, + Vcb, + Fcb, + DesiredAccess, + ShareAccess, + AllocationSize, + EaBuffer, + EaLength, + FileAttributes, + CreateDisposition, + NoEaKnowledge, + DeleteOnClose, + OpenedAsDos, + &OplockPostIrp); + + /* Check if it's pending */ + if (Iosb.Status != STATUS_PENDING) + { + /* In case of success set cache supported flag */ + if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering) + { + SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED); + } + + /* Save information */ + Irp->IoStatus.Information = Iosb.Information; + + /* Unlock VCB */ + FatReleaseVcb(IrpContext, Vcb); + + /* Complete the request */ + FatCompleteRequest(IrpContext, Irp, Iosb.Status); + + return Iosb.Status; + } + else + { + /* Queue this IRP */ + UNIMPLEMENTED; + ASSERT(FALSE); + } + } + else + { + /* Unexpected FCB type */ + KeBugCheckEx(/*FAT_FILE_SYSTEM*/0x23, __LINE__, (ULONG_PTR)Fcb, 0, 0); + } } /* During parsing we encountered a part which has no attached FCB/DCB. @@ -637,13 +888,63 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, /* Create a DCB for this entry */ ParentDcb = FatCreateDcb(IrpContext, Vcb, - ParentDcb); + ParentDcb, + NULL); /* Set its name */ FatSetFullNameInFcb(ParentDcb, &FirstName); } - // TODO: Try to open directory + /* Try to open it and get a result, saying if this is a dir or a file */ + FfError = FatiTryToOpen(FileObject, Vcb); + + /* Check if we need to open target directory */ + if (OpenTargetDirectory) + { + // TODO: Open target directory + UNIMPLEMENTED; + } + + /* Check, if path is a directory or a file */ + if (FfError == FF_ERR_FILE_OBJECT_IS_A_DIR) + { + if (NonDirectoryFile) + { + DPRINT1("Can't open dir as a file\n"); + + /* Unlock VCB */ + FatReleaseVcb(IrpContext, Vcb); + + /* Complete the request */ + Iosb.Status = STATUS_FILE_IS_A_DIRECTORY; + FatCompleteRequest(IrpContext, Irp, Iosb.Status); + return Iosb.Status; + } + + /* Open this directory */ + Iosb = FatiOpenExistingDir(IrpContext, + FileObject, + Vcb, + ParentDcb, + DesiredAccess, + ShareAccess, + AllocationSize, + EaBuffer, + EaLength, + FileAttributes, + CreateDisposition, + DeleteOnClose); + + Irp->IoStatus.Information = Iosb.Information; + + /* Unlock VCB */ + FatReleaseVcb(IrpContext, Vcb); + + /* Complete the request */ + FatCompleteRequest(IrpContext, Irp, Iosb.Status); + + return Iosb.Status; + } /* If end backslash here, then it's definately not permitted, since we're opening files here */ diff --git a/reactos/drivers/filesystems/fastfat_new/dir.c b/reactos/drivers/filesystems/fastfat_new/dir.c index abab2306589..1bb7826ec5a 100644 --- a/reactos/drivers/filesystems/fastfat_new/dir.c +++ b/reactos/drivers/filesystems/fastfat_new/dir.c @@ -127,7 +127,8 @@ PFCB NTAPI FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb, - IN PFCB ParentDcb) + IN PFCB ParentDcb, + IN FF_FILE *FileHandle) { PFCB Fcb; @@ -162,7 +163,34 @@ FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext, /* Initialize parent dcb list */ InitializeListHead(&Fcb->Dcb.ParentDcbList); + /* Set FullFAT handle */ + Fcb->FatHandle = FileHandle; + + /* Set names */ + if (FileHandle) + FatSetFcbNames(IrpContext, Fcb); + return Fcb; } +IO_STATUS_BLOCK +NTAPI +FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFILE_OBJECT FileObject, + IN PVCB Vcb, + IN PFCB Dcb, + IN PACCESS_MASK DesiredAccess, + IN USHORT ShareAccess, + IN ULONG CreateDisposition, + IN BOOLEAN NoEaKnowledge, + IN BOOLEAN DeleteOnClose) +{ + IO_STATUS_BLOCK Iosb = {{0}}; + + Iosb.Status = STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + + return Iosb; +} + /* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.c b/reactos/drivers/filesystems/fastfat_new/fastfat.c index 52db0af1064..533e7520807 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.c +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.c @@ -385,6 +385,23 @@ FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext, } } +BOOLEAN +NTAPI +FatAcquireSharedVcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PVCB Vcb) +{ + /* Acquire VCB's resource if possible */ + if (ExAcquireResourceSharedLite(&Vcb->Resource, + BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) + { + return TRUE; + } + else + { + return FALSE; + } +} + VOID NTAPI FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext, diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.h b/reactos/drivers/filesystems/fastfat_new/fastfat.h index ccfb7a2feb4..2b843df45f6 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.h +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.h @@ -35,6 +35,15 @@ ExReleaseResourceLite(&(FatGlobalData.Resource)); \ } +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeStringToCountedOemString( + IN OUT POEM_STRING DestinationString, + IN PCUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString +); + /* ------------------------------------------------------ shutdown.c */ @@ -50,6 +59,13 @@ FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS NTAPI FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp); +VOID NTAPI +FatReadStreamFile(PVCB Vcb, + ULONGLONG ByteOffset, + ULONG ByteSize, + PBCB *Bcb, + PVOID *Buffer); + /* ------------------------------------------------------ blockdev.c */ NTSTATUS NTAPI @@ -77,7 +93,19 @@ FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext, PFCB NTAPI FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb, - IN PFCB ParentDcb); + IN PFCB ParentDcb, + IN FF_FILE *FileHandle); + +IO_STATUS_BLOCK NTAPI +FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFILE_OBJECT FileObject, + IN PVCB Vcb, + IN PFCB Dcb, + IN PACCESS_MASK DesiredAccess, + IN USHORT ShareAccess, + IN ULONG CreateDisposition, + IN BOOLEAN NoEaKnowledge, + IN BOOLEAN DeleteOnClose); /* -------------------------------------------------------- create.c */ @@ -143,6 +171,10 @@ BOOLEAN NTAPI FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb); +BOOLEAN NTAPI +FatAcquireSharedVcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PVCB Vcb); + VOID NTAPI FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb); @@ -188,6 +220,14 @@ FatReadBlocks(FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, NTSTATUS NTAPI FatLockControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); +VOID NTAPI +FatOplockComplete(IN PVOID Context, + IN PIRP Irp); + +VOID NTAPI +FatPrePostIrp(IN PVOID Context, + IN PIRP Irp); + /* --------------------------------------------------------- fsctl.c */ NTSTATUS NTAPI @@ -198,6 +238,10 @@ FatFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS NTAPI FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS NTAPI FatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); +/* --------------------------------------------------------- fullfat.c */ + +FF_FILE *FF_OpenW(FF_IOMAN *pIoman, PUNICODE_STRING pathW, FF_T_UINT8 Mode, FF_ERROR *pError); + /* --------------------------------------------------------- iface.c */ NTSTATUS @@ -284,6 +328,23 @@ FatCreateFcb( IN PFCB ParentDcb, IN FF_FILE *FileHandle); +IO_STATUS_BLOCK NTAPI +FatiOpenExistingFcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFILE_OBJECT FileObject, + IN PVCB Vcb, + IN PFCB Fcb, + IN PACCESS_MASK DesiredAccess, + IN USHORT ShareAccess, + IN ULONG AllocationSize, + IN PFILE_FULL_EA_INFORMATION EaBuffer, + IN ULONG EaLength, + IN UCHAR FileAttributes, + IN ULONG CreateDisposition, + IN BOOLEAN NoEaKnowledge, + IN BOOLEAN DeleteOnClose, + IN BOOLEAN OpenedAsDos, + OUT PBOOLEAN OplockPostIrp); + PFCB NTAPI FatFindFcb(PFAT_IRP_CONTEXT IrpContext, PRTL_SPLAY_LINKS *RootNode, diff --git a/reactos/drivers/filesystems/fastfat_new/fatstruc.h b/reactos/drivers/filesystems/fastfat_new/fatstruc.h index 04e97d515a4..fbf6bdb3bd4 100644 --- a/reactos/drivers/filesystems/fastfat_new/fatstruc.h +++ b/reactos/drivers/filesystems/fastfat_new/fatstruc.h @@ -133,9 +133,10 @@ typedef struct _FAT_METHODS { PFAT_SETFAT_VALUE_RUN_ROUTINE SetValueRun; } FAT_METHODS, *PFAT_METHODS; -#define VCB_STATE_FLAG_LOCKED 0x01 -#define VCB_STATE_FLAG_DIRTY 0x02 -#define VCB_STATE_MOUNTED_DIRTY 0x04 +#define VCB_STATE_FLAG_LOCKED 0x01 +#define VCB_STATE_FLAG_DIRTY 0x02 +#define VCB_STATE_MOUNTED_DIRTY 0x04 +#define VCB_STATE_CREATE_IN_PROGRESS 0x08 typedef enum _VCB_CONDITION { @@ -249,6 +250,8 @@ typedef enum _FCB_CONDITION #define FCB_STATE_HAS_NAMES 0x01 #define FCB_STATE_HAS_UNICODE_NAME 0x02 +#define FCB_STATE_PAGEFILE 0x04 +#define FCB_STATE_DELAY_CLOSE 0x08 typedef struct _FCB { @@ -264,7 +267,6 @@ typedef struct _FCB ERESOURCE Resource; // nonpaged! ERESOURCE PagingIoResource; // nonpaged! - FILE_LOCK Lock; /* First cluster in the fat allocation chain */ ULONG FirstClusterOfFile; /* A list of all FCBs of that DCB */ @@ -277,6 +279,8 @@ typedef struct _FCB ULONG State; /* Fcb condition */ FCB_CONDITION Condition; + /* Share access */ + SHARE_ACCESS ShareAccess; /* Mcb mapping Vbo->Lbo */ LARGE_MCB Mcb; ULONG FirstCluster; @@ -303,6 +307,13 @@ typedef struct _FCB PKEVENT OutstandingAsyncEvent; union { + struct + { + /* File and Op locks */ + FILE_LOCK Lock; + OPLOCK Oplock; + } Fcb; + struct { /* A list of all FCBs/DCBs opened under this DCB */ diff --git a/reactos/drivers/filesystems/fastfat_new/fcb.c b/reactos/drivers/filesystems/fastfat_new/fcb.c index bffdf7a556c..cbc8f57b84d 100644 --- a/reactos/drivers/filesystems/fastfat_new/fcb.c +++ b/reactos/drivers/filesystems/fastfat_new/fcb.c @@ -172,6 +172,266 @@ FatCreateCcb() return Ccb; } +IO_STATUS_BLOCK +NTAPI +FatiOpenExistingFcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFILE_OBJECT FileObject, + IN PVCB Vcb, + IN PFCB Fcb, + IN PACCESS_MASK DesiredAccess, + IN USHORT ShareAccess, + IN ULONG AllocationSize, + IN PFILE_FULL_EA_INFORMATION EaBuffer, + IN ULONG EaLength, + IN UCHAR FileAttributes, + IN ULONG CreateDisposition, + IN BOOLEAN NoEaKnowledge, + IN BOOLEAN DeleteOnClose, + IN BOOLEAN OpenedAsDos, + OUT PBOOLEAN OplockPostIrp) +{ + IO_STATUS_BLOCK Iosb = {{0}}; + ACCESS_MASK AddedAccess = 0; + BOOLEAN Hidden; + BOOLEAN System; + PCCB Ccb = NULL; + NTSTATUS Status; + + /* Acquire exclusive FCB lock */ + (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb); + + *OplockPostIrp = FALSE; + + /* Check if there is a batch oplock */ + if (FsRtlCurrentBatchOplock(&Fcb->Fcb.Oplock)) + { + /* Return with a special information field */ + Iosb.Information = FILE_OPBATCH_BREAK_UNDERWAY; + + /* Check the oplock */ + Iosb.Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock, + IrpContext->Irp, + IrpContext, + FatOplockComplete, + FatPrePostIrp); + + if (Iosb.Status != STATUS_SUCCESS && + Iosb.Status != STATUS_OPLOCK_BREAK_IN_PROGRESS) + { + /* The Irp needs to be queued */ + *OplockPostIrp = TRUE; + + /* Release the FCB and return */ + FatReleaseFcb(IrpContext, Fcb); + return Iosb; + } + } + + /* Validate parameters and modify access */ + if (CreateDisposition == FILE_CREATE) + { + Iosb.Status = STATUS_OBJECT_NAME_COLLISION; + + /* Release the FCB and return */ + FatReleaseFcb(IrpContext, Fcb); + return Iosb; + } + else if (CreateDisposition == FILE_SUPERSEDE) + { + SetFlag(AddedAccess, DELETE & ~(*DesiredAccess)); + *DesiredAccess |= DELETE; + } + else if ((CreateDisposition == FILE_OVERWRITE) || + (CreateDisposition == FILE_OVERWRITE_IF)) + { + SetFlag(AddedAccess, + (FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES) + & ~(*DesiredAccess) ); + + *DesiredAccess |= FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES; + } + + // TODO: Check desired access + + // TODO: Check if this file is readonly and DeleteOnClose is set + + /* Validate disposition information */ + if ((CreateDisposition == FILE_SUPERSEDE) || + (CreateDisposition == FILE_OVERWRITE) || + (CreateDisposition == FILE_OVERWRITE_IF)) + { + // TODO: Get this attributes from the dirent + Hidden = FALSE; + System = FALSE; + + if ((Hidden && !FlagOn(FileAttributes, FILE_ATTRIBUTE_HIDDEN)) || + (System && !FlagOn(FileAttributes, FILE_ATTRIBUTE_SYSTEM))) + { + DPRINT1("Hidden/system attributes don't match\n"); + + Iosb.Status = STATUS_ACCESS_DENIED; + + /* Release the FCB and return */ + FatReleaseFcb(IrpContext, Fcb); + return Iosb; + } + + // TODO: Check for write protected volume + } + + /* Check share access */ + Iosb.Status = IoCheckShareAccess(*DesiredAccess, + ShareAccess, + FileObject, + &Fcb->ShareAccess, + FALSE); + if (!NT_SUCCESS(Iosb.Status)) + { + /* Release the FCB and return */ + FatReleaseFcb(IrpContext, Fcb); + return Iosb; + } + + /* Check the oplock status after checking for share access */ + Iosb.Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock, + IrpContext->Irp, + IrpContext, + FatOplockComplete, + FatPrePostIrp ); + + if (Iosb.Status != STATUS_SUCCESS && + Iosb.Status != STATUS_OPLOCK_BREAK_IN_PROGRESS) + { + /* The Irp needs to be queued */ + *OplockPostIrp = TRUE; + + /* Release the FCB and return */ + FatReleaseFcb(IrpContext, Fcb); + return Iosb; + } + + /* Set Fast I/O flag */ + Fcb->Header.IsFastIoPossible = FALSE; //FatiIsFastIoPossible(Fcb); + + /* Make sure image is not mapped */ + if (DeleteOnClose || FlagOn(*DesiredAccess, FILE_WRITE_DATA)) + { + /* Try to flush the image section */ + if (!MmFlushImageSection(&Fcb->SectionObjectPointers, MmFlushForWrite)) + { + /* Yes, image section exists, set correct status code */ + if (DeleteOnClose) + Iosb.Status = STATUS_CANNOT_DELETE; + else + Iosb.Status = STATUS_SHARING_VIOLATION; + + /* Release the FCB and return */ + FatReleaseFcb(IrpContext, Fcb); + return Iosb; + } + } + + /* Flush the cache if it's non-cached non-pagefile access */ + if (FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING) && + Fcb->SectionObjectPointers.DataSectionObject && + !FlagOn(Fcb->State, FCB_STATE_PAGEFILE)) + { + /* Set the flag that create is in progress */ + SetFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS); + + /* Flush the cache */ + CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL); + + /* Acquire and release Paging I/O resource before purging the cache section + to let lazy writer finish */ + ExAcquireResourceExclusiveLite( Fcb->Header.PagingIoResource, TRUE); + ExReleaseResourceLite( Fcb->Header.PagingIoResource ); + + /* Delete the cache section */ + CcPurgeCacheSection(&Fcb->SectionObjectPointers, NULL, 0, FALSE); + + /* Clear the flag */ + ClearFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS); + } + + /* Check create disposition flags and branch accordingly */ + if (CreateDisposition == FILE_OPEN || + CreateDisposition == FILE_OPEN_IF) + { + DPRINT("Opening a file\n"); + + /* Check if we need to bother with EA */ + if (NoEaKnowledge && FALSE /* FatIsFat32(Vcb)*/) + { + UNIMPLEMENTED; + } + + /* Set up file object */ + Ccb = FatCreateCcb(IrpContext); + FatSetFileObject(FileObject, + UserFileOpen, + Fcb, + Ccb); + + FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; + + /* The file is opened */ + Iosb.Information = FILE_OPENED; + goto SuccComplete; + } + else if ((CreateDisposition == FILE_SUPERSEDE) || + (CreateDisposition == FILE_OVERWRITE) || + (CreateDisposition == FILE_OVERWRITE_IF)) + { + UNIMPLEMENTED; + ASSERT(FALSE); + } + else + { + /* We can't get here */ + KeBugCheckEx(0x23, CreateDisposition, 0, 0, 0); + } + + +SuccComplete: + /* If all is fine */ + if (Iosb.Status != STATUS_PENDING && + NT_SUCCESS(Iosb.Status)) + { + /* Update access if needed */ + if (AddedAccess) + { + /* Remove added access flags from desired access */ + ClearFlag(*DesiredAccess, AddedAccess); + + /* Check share access */ + Status = IoCheckShareAccess(*DesiredAccess, + ShareAccess, + FileObject, + &Fcb->ShareAccess, + TRUE); + + /* Make sure it's success */ + ASSERT(Status == STATUS_SUCCESS); + } + else + { + /* Update the share access */ + IoUpdateShareAccess(FileObject, &Fcb->ShareAccess); + } + + /* Clear the delay close */ + ClearFlag(Fcb->State, FCB_STATE_DELAY_CLOSE); + + /* Increase global volume counter */ + Vcb->OpenFileCount++; + + // TODO: Handle DeleteOnClose and OpenedAsDos by storing those flags in CCB + } + + return Iosb; +} + VOID NTAPI FatGetFcbUnicodeName(IN PFAT_IRP_CONTEXT IrpContext, @@ -187,11 +447,16 @@ FatGetFcbUnicodeName(IN PFAT_IRP_CONTEXT IrpContext, OEM_STRING LongNameOem; NTSTATUS Status; - /* We support only files now, not directories */ - if (Fcb->Header.NodeTypeCode != FAT_NTC_FCB) + /* Make sure this FCB has a FullFAT handle associated with it */ + if (Fcb->FatHandle == NULL && + FatNodeType(Fcb) == FAT_NTC_DCB) { - UNIMPLEMENTED; - ASSERT(FALSE); + /* Open the dir with FullFAT */ + Fcb->FatHandle = FF_OpenW(Fcb->Vcb->Ioman, &Fcb->FullFileName, FF_MODE_DIR, NULL); + if (!Fcb->FatHandle) + { + ASSERT(FALSE); + } } /* Get the dir entry */ @@ -502,7 +767,7 @@ FatSetFcbNames(IN PFAT_IRP_CONTEXT IrpContext, RtlDowncaseUnicodeString(UnicodeName, UnicodeName, FALSE); RtlUpcaseUnicodeString(UnicodeName, UnicodeName, FALSE); - DPRINT1("Converted long name: %wZ\n", UnicodeName); + DPRINT("Converted long name: %wZ\n", UnicodeName); /* Add the long unicode name link */ FatInsertName(IrpContext, &Fcb->ParentFcb->Dcb.SplayLinksUnicode, &Fcb->LongName); @@ -603,7 +868,7 @@ Fati8dot3ToString(IN PCHAR FileName, /* Set the length */ OutString->Length = BaseLen + ExtLen; - DPRINT1("'%s', len %d\n", OutString->Buffer, OutString->Length); + DPRINT("'%s', len %d\n", OutString->Buffer, OutString->Length); } VOID diff --git a/reactos/drivers/filesystems/fastfat_new/fsctl.c b/reactos/drivers/filesystems/fastfat_new/fsctl.c index b104e4c32ea..a40d065358b 100644 --- a/reactos/drivers/filesystems/fastfat_new/fsctl.c +++ b/reactos/drivers/filesystems/fastfat_new/fsctl.c @@ -47,6 +47,37 @@ FatiCleanVcbs(PFAT_IRP_CONTEXT IrpContext) ExReleaseResourceLite(&FatGlobalData.Resource); } +VOID +NTAPI +FatiUnpackBpb(PBIOS_PARAMETER_BLOCK Bpb, PPACKED_BIOS_PARAMETER_BLOCK PackedBpb) +{ + CopyUchar2(&Bpb->BytesPerSector, &PackedBpb->BytesPerSector[0]); + CopyUchar1(&Bpb->SectorsPerCluster, &PackedBpb->SectorsPerCluster[0]); + CopyUchar2(&Bpb->ReservedSectors, &PackedBpb->ReservedSectors[0]); + CopyUchar1(&Bpb->Fats, &PackedBpb->Fats[0]); + CopyUchar2(&Bpb->RootEntries, &PackedBpb->RootEntries[0]); + CopyUchar2(&Bpb->Sectors, &PackedBpb->Sectors[0]); + CopyUchar1(&Bpb->Media, &PackedBpb->Media[0]); + CopyUchar2(&Bpb->SectorsPerFat, &PackedBpb->SectorsPerFat[0]); + CopyUchar2(&Bpb->SectorsPerTrack, &PackedBpb->SectorsPerTrack[0]); + CopyUchar2(&Bpb->Heads, &PackedBpb->Heads[0]); + CopyUchar4(&Bpb->HiddenSectors, &PackedBpb->HiddenSectors[0]); + CopyUchar4(&Bpb->LargeSectors, &PackedBpb->LargeSectors[0]); + CopyUchar4(&Bpb->LargeSectorsPerFat, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->LargeSectorsPerFat[0]); + CopyUchar2(&Bpb->ExtendedFlags, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->ExtendedFlags[0]); + CopyUchar2(&Bpb->FsVersion, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->FsVersion[0]); + CopyUchar4(&Bpb->RootDirFirstCluster,&((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->RootDirFirstCluster[0]); + CopyUchar2(&Bpb->FsInfoSector, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->FsInfoSector[0]); + CopyUchar2(&Bpb->BackupBootSector, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->BackupBootSector[0]); +} + +BOOLEAN +NTAPI +FatiBpbFat32(PPACKED_BIOS_PARAMETER_BLOCK PackedBpb) +{ + return (*(USHORT *)(&PackedBpb->SectorsPerFat) == 0); +} + NTSTATUS NTAPI FatMountVolume(PFAT_IRP_CONTEXT IrpContext, @@ -60,6 +91,8 @@ FatMountVolume(PFAT_IRP_CONTEXT IrpContext, PVOLUME_DEVICE_OBJECT VolumeDevice; VCB *Vcb; FF_ERROR Error; + PBCB BootBcb; + PPACKED_BOOT_SECTOR BootSector; DPRINT1("FatMountVolume()\n"); @@ -167,7 +200,46 @@ FatMountVolume(PFAT_IRP_CONTEXT IrpContext, goto FatMountVolumeCleanup; } - // TODO: Read BPB and store it in Vcb->Bpb + /* Read the boot sector */ + FatReadStreamFile(Vcb, 0, sizeof(PACKED_BOOT_SECTOR), &BootBcb, (PVOID)&BootSector); + + /* Check if it's successful */ + if (!BootBcb) + { + Status = STATUS_UNRECOGNIZED_VOLUME; + goto FatMountVolumeCleanup; + } + + /* Unpack data */ + FatiUnpackBpb(&Vcb->Bpb, &BootSector->PackedBpb); + + /* Verify if sector size matches */ + if (DiskGeometry.BytesPerSector != Vcb->Bpb.BytesPerSector) + { + DPRINT1("Disk geometry BPS %d and bios BPS %d don't match!\n", + DiskGeometry.BytesPerSector, Vcb->Bpb.BytesPerSector); + + /* Fail */ + Status = STATUS_UNRECOGNIZED_VOLUME; + goto FatMountVolumeCleanup; + } + + /* If Sectors value is set, discard the LargeSectors value */ + if (Vcb->Bpb.Sectors) Vcb->Bpb.LargeSectors = 0; + + /* Copy serial number */ + if (FatiBpbFat32(&BootSector->PackedBpb)) + { + CopyUchar4(&Vpb->SerialNumber, ((PPACKED_BOOT_SECTOR_EX)BootSector)->Id); + } + else + { + /* This is FAT12/16 */ + CopyUchar4(&Vpb->SerialNumber, BootSector->Id); + } + + /* Unpin the BCB */ + CcUnpinData(BootBcb); /* Create root DCB for it */ FatCreateRootDcb(IrpContext, &VolumeDevice->Vcb); @@ -249,7 +321,7 @@ FatFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) PFAT_IRP_CONTEXT IrpContext; BOOLEAN CanWait = TRUE; - DPRINT1("FatFileSystemControl(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); + DPRINT("FatFileSystemControl(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); /* Get CanWait flag */ if (IoGetCurrentIrpStackLocation(Irp)->FileObject) diff --git a/reactos/drivers/filesystems/fastfat_new/fullfat.c b/reactos/drivers/filesystems/fastfat_new/fullfat.c index bb0947aad66..f140706808f 100644 --- a/reactos/drivers/filesystems/fastfat_new/fullfat.c +++ b/reactos/drivers/filesystems/fastfat_new/fullfat.c @@ -77,4 +77,27 @@ FatReadBlocks(FF_T_UINT8 *DestBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Cou return Count; } +FF_FILE *FF_OpenW(FF_IOMAN *pIoman, PUNICODE_STRING pathW, FF_T_UINT8 Mode, FF_ERROR *pError) +{ + OEM_STRING AnsiName; + CHAR AnsiNameBuf[512]; + NTSTATUS Status; + + /* Convert the name to ANSI */ + AnsiName.Buffer = AnsiNameBuf; + AnsiName.Length = 0; + AnsiName.MaximumLength = sizeof(AnsiNameBuf); + RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf)); + Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, pathW, FALSE); + if (!NT_SUCCESS(Status)) + { + ASSERT(FALSE); + } + + DPRINT1("Opening '%s'\n", AnsiName.Buffer); + + /* Call FullFAT's handler */ + return FF_Open(pIoman, AnsiName.Buffer, Mode, pError); +} + /* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/lock.c b/reactos/drivers/filesystems/fastfat_new/lock.c index b72488c1935..d56cbc2abbe 100644 --- a/reactos/drivers/filesystems/fastfat_new/lock.c +++ b/reactos/drivers/filesystems/fastfat_new/lock.c @@ -21,4 +21,20 @@ FatLockControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) return STATUS_NOT_IMPLEMENTED; } +VOID +NTAPI +FatOplockComplete(IN PVOID Context, + IN PIRP Irp) +{ + UNIMPLEMENTED; +} + +VOID +NTAPI +FatPrePostIrp(IN PVOID Context, + IN PIRP Irp) +{ + UNIMPLEMENTED; +} + /* EOF */ diff --git a/reactos/drivers/filesystems/fastfat_new/volume.c b/reactos/drivers/filesystems/fastfat_new/volume.c index 3bcb558327c..b8705085baf 100644 --- a/reactos/drivers/filesystems/fastfat_new/volume.c +++ b/reactos/drivers/filesystems/fastfat_new/volume.c @@ -8,17 +8,159 @@ /* INCLUDES *****************************************************************/ -#define NDEBUG +//#define NDEBUG #include "fastfat.h" /* FUNCTIONS ****************************************************************/ +NTSTATUS +NTAPI +FatiQueryFsVolumeInfo(PVCB Vcb, + PFILE_FS_VOLUME_INFORMATION Buffer, + PLONG Length) +{ + ULONG ByteSize; + NTSTATUS Status = STATUS_SUCCESS; + + /* Deduct the minimum written length */ + *Length -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]); + + /* Zero it */ + RtlZeroMemory(Buffer, sizeof(FILE_FS_VOLUME_INFORMATION)); + + DPRINT("Serial number 0x%x, label length %d\n", + Vcb->Vpb->SerialNumber, Vcb->Vpb->VolumeLabelLength); + + /* Save serial number */ + Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber; + + /* Set max byte size */ + ByteSize = Vcb->Vpb->VolumeLabelLength; + + /* Check buffer length and reduce byte size if needed */ + if (*Length < Vcb->Vpb->VolumeLabelLength) + { + /* Copy only up to what buffer size was provided */ + ByteSize = *Length; + Status = STATUS_BUFFER_OVERFLOW; + } + + /* Copy volume label */ + Buffer->VolumeLabelLength = Vcb->Vpb->VolumeLabelLength; + RtlCopyMemory(Buffer->VolumeLabel, Vcb->Vpb->VolumeLabel, ByteSize); + *Length -= ByteSize; + + return Status; +} + +NTSTATUS +NTAPI +FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) +{ + PFILE_OBJECT FileObject; + PIO_STACK_LOCATION IrpSp; + FILE_INFORMATION_CLASS InfoClass; + TYPE_OF_OPEN FileType; + PVCB Vcb; + PFCB Fcb; + PCCB Ccb; + LONG Length; + PVOID Buffer; + BOOLEAN VcbLocked = FALSE; + NTSTATUS Status = STATUS_SUCCESS; + + /* Get IRP stack location */ + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + /* Get the file object */ + FileObject = IrpSp->FileObject; + + /* Copy variables to something with shorter names */ + InfoClass = IrpSp->Parameters.QueryVolume.FsInformationClass; + Length = IrpSp->Parameters.QueryVolume.Length; + Buffer = Irp->AssociatedIrp.SystemBuffer; + + DPRINT("FatiQueryVolumeInfo\n", 0); + DPRINT("\tIrp = %08lx\n", Irp); + DPRINT("\tLength = %08lx\n", Length); + DPRINT("\tFsInformationClass = %08lx\n", InfoClass); + DPRINT("\tBuffer = %08lx\n", Buffer); + + FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); + + DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType); + + switch (InfoClass) + { + case FileFsVolumeInformation: + /* Acquired the shared VCB lock */ + if (!FatAcquireSharedVcb(IrpContext, Vcb)) + { + ASSERT(FALSE); + } + + /* Remember we locked it */ + VcbLocked = TRUE; + + /* Call FsVolumeInfo handler */ + Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length); + break; + default: + DPRINT1("Volume information class %d is not supported!\n", InfoClass); + UNIMPLEMENTED; + } + + /* Set IoStatus.Information to amount of filled bytes */ + Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length; + + /* Release VCB lock */ + if (VcbLocked) FatReleaseVcb(IrpContext, Vcb); + + /* Complete request and return status */ + FatCompleteRequest(IrpContext, Irp, Status); + return Status; +} + NTSTATUS NTAPI FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp) { - DPRINT1("FatQueryVolumeInfo()\n"); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + BOOLEAN TopLevel, CanWait; + PFAT_IRP_CONTEXT IrpContext; + + CanWait = TRUE; + TopLevel = FALSE; + Status = STATUS_INVALID_DEVICE_REQUEST; + + /* Get CanWait flag */ + if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL) + CanWait = IoIsOperationSynchronous(Irp); + + /* Enter FsRtl critical region */ + FsRtlEnterFileSystem(); + + /* Set Top Level IRP if not set */ + if (IoGetTopLevelIrp() == NULL) + { + IoSetTopLevelIrp(Irp); + TopLevel = TRUE; + } + + /* Build an irp context */ + IrpContext = FatBuildIrpContext(Irp, CanWait); + + /* Call the request handler */ + Status = FatiQueryVolumeInfo(IrpContext, Irp); + + /* Restore top level Irp */ + if (TopLevel) + IoSetTopLevelIrp(NULL); + + /* Leave FsRtl critical region */ + FsRtlExitFileSystem(); + + return Status; } NTSTATUS @@ -29,4 +171,27 @@ FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp) return STATUS_NOT_IMPLEMENTED; } +VOID +NTAPI +FatReadStreamFile(PVCB Vcb, + ULONGLONG ByteOffset, + ULONG ByteSize, + PBCB *Bcb, + PVOID *Buffer) +{ + LARGE_INTEGER Offset; + + Offset.QuadPart = ByteOffset; + + if (!CcMapData(Vcb->StreamFileObject, + &Offset, + ByteSize, + TRUE, // FIXME: CanWait + Bcb, + Buffer)) + { + ASSERT(FALSE); + } +} + /* EOF */ diff --git a/reactos/drivers/multimedia/bdasup/bdasup.c b/reactos/drivers/multimedia/bdasup/bdasup.c index 0d657c68d74..82a357ae5ce 100644 --- a/reactos/drivers/multimedia/bdasup/bdasup.c +++ b/reactos/drivers/multimedia/bdasup/bdasup.c @@ -691,7 +691,7 @@ NTAPI BdaPropertyNodeDescriptors( IN PIRP Irp, IN KSPROPERTY *pKSProperty, - OUT GUID *pguidProperty) + OUT BDANODE_DESCRIPTOR *pNodeDescriptorProperty) { UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; @@ -704,7 +704,7 @@ NTSTATUS NTAPI BdaPropertyNodeEvents( IN PIRP Irp, - IN KSPROPERTY *pKSProperty, + IN KSP_NODE *pKSProperty, OUT GUID *pguidProperty) { UNIMPLEMENTED @@ -718,7 +718,7 @@ NTSTATUS NTAPI BdaPropertyNodeMethods( IN PIRP Irp, - IN KSPROPERTY *pKSProperty, + IN KSP_NODE *pKSProperty, OUT GUID *pguidProperty) { UNIMPLEMENTED @@ -732,7 +732,7 @@ NTSTATUS NTAPI BdaPropertyNodeProperties( IN PIRP Irp, - IN KSPROPERTY *pKSProperty, + IN KSP_NODE *pKSProperty, OUT GUID *pguidProperty) { UNIMPLEMENTED diff --git a/reactos/drivers/storage/class/ramdisk/ramdisk.c b/reactos/drivers/storage/class/ramdisk/ramdisk.c index e6363e4c6f7..e3d3d8ecff9 100644 --- a/reactos/drivers/storage/class/ramdisk/ramdisk.c +++ b/reactos/drivers/storage/class/ramdisk/ramdisk.c @@ -2308,7 +2308,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, PCHAR BootDeviceName, CommandLine; PDEVICE_OBJECT PhysicalDeviceObject = NULL; NTSTATUS Status; - DPRINT1("RAM Disk Driver Initialized\n"); + DPRINT("RAM Disk Driver Initialized\n"); // // Query ramdisk parameters diff --git a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c index e5abe66014d..6c2ab8d8451 100644 --- a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c +++ b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c @@ -119,7 +119,7 @@ TestKs() // Allocate a KS Pin Connection Request Structure // Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX); - printf("Length %ld KSPIN %u DATAFORAMT %u\n", Length, sizeof(KSPIN_CONNECT), sizeof(KSDATAFORMAT_WAVEFORMATEX)); + printf("Length %ld KSPIN %u DATAFORMAT %u\n", Length, sizeof(KSPIN_CONNECT), sizeof(KSDATAFORMAT_WAVEFORMATEX)); PinConnect = (PKSPIN_CONNECT)HeapAlloc(GetProcessHeap(), 0, Length); DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)(PinConnect + 1); diff --git a/reactos/drivers/wdm/audio/backpln/portcls/api.cpp b/reactos/drivers/wdm/audio/backpln/portcls/api.cpp index 62739c85fac..bbc15e2b9b9 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/api.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/api.cpp @@ -238,8 +238,8 @@ NTAPI PcDmaSlaveDescription( IN PRESOURCELIST ResourceList OPTIONAL, IN ULONG DmaIndex, - IN BOOL DemandMode, - IN ULONG AutoInitialize, + IN BOOLEAN DemandMode, + IN BOOLEAN AutoInitialize, IN DMA_SPEED DmaSpeed, IN ULONG MaximumLength, IN ULONG DmaPort, diff --git a/reactos/drivers/wdm/audio/backpln/portcls/connection.cpp b/reactos/drivers/wdm/audio/backpln/portcls/connection.cpp index b10cab4970e..4b5276f9f6c 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/connection.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/connection.cpp @@ -156,7 +156,7 @@ RegisterConnection( IN PUNICODE_STRING ToString, IN ULONG ToPin) { - PSUBDEVICE_DESCRIPTOR FromSubDeviceDescriptor, ToSubDeviceDescriptor; + PSUBDEVICE_DESCRIPTOR FromSubDeviceDescriptor = NULL, ToSubDeviceDescriptor = NULL; PSYMBOLICLINK_ENTRY SymEntry; ISubdevice * FromSubDevice = NULL, *ToSubDevice = NULL; NTSTATUS Status; @@ -205,35 +205,49 @@ RegisterConnection( } - FromEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + ToString->MaximumLength, TAG_PORTCLASS); - if (!FromEntry) + if (FromSubDeviceDescriptor) { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; + FromEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + ToString->MaximumLength, TAG_PORTCLASS); + if (!FromEntry) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } } - ToEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + FromString->MaximumLength, TAG_PORTCLASS); - if (!ToEntry) + if (ToSubDeviceDescriptor) { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; + ToEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + FromString->MaximumLength, TAG_PORTCLASS); + if (!ToEntry) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } } - FromEntry->FromPin = FromPin; - FromEntry->Connection.Pin = ToPin; - FromEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + ToString->MaximumLength; - RtlMoveMemory(&FromEntry->Connection.SymbolicLinkName, ToString->Buffer, ToString->MaximumLength); - FromEntry->Connection.SymbolicLinkName[ToString->Length / sizeof(WCHAR)] = L'\0'; + if (FromSubDeviceDescriptor) + { + FromEntry->FromPin = FromPin; + FromEntry->Connection.Pin = ToPin; + FromEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + ToString->MaximumLength; + RtlMoveMemory(&FromEntry->Connection.SymbolicLinkName, ToString->Buffer, ToString->MaximumLength); + FromEntry->Connection.SymbolicLinkName[ToString->Length / sizeof(WCHAR)] = L'\0'; - ToEntry->FromPin = ToPin; - ToEntry->Connection.Pin = FromPin; - ToEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + FromString->MaximumLength; - RtlMoveMemory(&ToEntry->Connection.SymbolicLinkName, FromString->Buffer, FromString->MaximumLength); - ToEntry->Connection.SymbolicLinkName[FromString->Length / sizeof(WCHAR)] = L'\0'; + InsertTailList(&FromSubDeviceDescriptor->PhysicalConnectionList, &FromEntry->Entry); + } - InsertTailList(&FromSubDeviceDescriptor->PhysicalConnectionList, &FromEntry->Entry); - InsertTailList(&ToSubDeviceDescriptor->PhysicalConnectionList, &ToEntry->Entry); + if (ToSubDeviceDescriptor) + { + ToEntry->FromPin = ToPin; + ToEntry->Connection.Pin = FromPin; + ToEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + FromString->MaximumLength; + RtlMoveMemory(&ToEntry->Connection.SymbolicLinkName, FromString->Buffer, FromString->MaximumLength); + ToEntry->Connection.SymbolicLinkName[FromString->Length / sizeof(WCHAR)] = L'\0'; + + InsertTailList(&ToSubDeviceDescriptor->PhysicalConnectionList, &ToEntry->Entry); + + } return STATUS_SUCCESS; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp index 8e18937d0e8..53c41d55ff0 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp @@ -679,6 +679,10 @@ typedef IPortPinWavePci *PPORTPINWAVEPCI; #undef INTERFACE #define INTERFACE IPortFilterWaveRT +#ifndef PPORTWAVERT +typedef IPortWaveRT *PPORTWAVERT; +#endif + DECLARE_INTERFACE_(IPortFilterWaveRT, IIrpTarget) { DEFINE_ABSTRACT_UNKNOWN() @@ -1103,4 +1107,15 @@ DECLARE_INTERFACE_(IPortWaveRTStreamInit, IUnknown) IN ULONG Index \ ) +#ifndef IMP_IPortClsVersion + +#define IMP_IPortClsVersion \ + STDMETHODIMP_(DWORD) GetVersion(void); + +#endif + +#ifdef IMP_IPortWaveRT +#define IMP_IPortWaveRT IMP_IPort +#endif + #endif diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp b/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp index 22446780d16..d86f7de8257 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp @@ -97,8 +97,10 @@ CInterruptSynchronizedRoutine( IN PVOID ServiceContext) { CInterruptSync * This = (CInterruptSync*)ServiceContext; - DPRINT("CInterruptSynchronizedRoutine this %p SyncRoutine %p Context %p\n", This, This->m_SyncRoutine, This->m_DynamicContext); - return This->m_SyncRoutine(This, This->m_DynamicContext); + NTSTATUS Status = This->m_SyncRoutine(This, This->m_DynamicContext); + + DPRINT("CInterruptSynchronizedRoutine this %p SyncRoutine %p Context %p Status %x\n", This, This->m_SyncRoutine, This->m_DynamicContext, Status); + return NT_SUCCESS(Status); } NTSTATUS @@ -155,10 +157,10 @@ IInterruptServiceRoutine( NTSTATUS Status; BOOL Success; - //DPRINT("IInterruptServiceRoutine Mode %u\n", m_Mode); - CInterruptSync * This = (CInterruptSync*)ServiceContext; + DPRINT("IInterruptServiceRoutine Mode %u\n", This->m_Mode); + if (This->m_Mode == InterruptSyncModeNormal) { CurEntry = This->m_ServiceRoutines.Flink; @@ -234,8 +236,8 @@ CInterruptSync::Connect() (PVOID)this, &m_Lock, Descriptor->u.Interrupt.Vector, - Descriptor->u.Interrupt.Level, - Descriptor->u.Interrupt.Level, + (KIRQL)Descriptor->u.Interrupt.Level, + (KIRQL)Descriptor->u.Interrupt.Level, (KINTERRUPT_MODE)(Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED), (Descriptor->Flags != CM_RESOURCE_INTERRUPT_LATCHED), Descriptor->u.Interrupt.Affinity, diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp index e96c89e0775..358d1ead577 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp @@ -118,7 +118,10 @@ CIrpQueue::AddMapping( // ioctl from KsStudio // Wdmaud already probes buffers, therefore no need to probe it again // probe the stream irp - Status = KsProbeStreamIrp(Irp, KSSTREAM_READ | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0); + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM) + Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0); + else + Status = KsProbeStreamIrp(Irp, KSSTREAM_READ| KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0); // check for success if (!NT_SUCCESS(Status)) @@ -200,8 +203,7 @@ CIrpQueue::GetMapping( if (!Irp) { - DPRINT1("NoIrp\n"); - return STATUS_UNSUCCESSFUL; + DPRINT("NoIrp\n"); // no irp available, use silence buffer *Buffer = (PUCHAR)m_SilenceBuffer; *BufferSize = m_MaxFrameSize; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp index 6305a5ca7f0..3c273ebd3d6 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp @@ -358,7 +358,7 @@ CPortPinDMus::TransferMidiDataToDMus() //set up struct //Event->Event.usFlags = DMUS_KEF_EVENT_COMPLETE; Event->Event.cbStruct = sizeof(DMUS_KERNEL_EVENT); - Event->Event.cbEvent = BufferSize; + Event->Event.cbEvent = (USHORT)BufferSize; Event->Event.uData.pbData = (PBYTE)Buffer; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index b318a5c6b31..9b9376503e4 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -51,6 +51,7 @@ protected: friend NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); friend NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); friend NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + friend NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); IPortWaveCyclic * m_Port; IPortFilterWaveCyclic * m_Filter; @@ -75,6 +76,7 @@ protected: ULONG m_TotalPackets; ULONG m_StopCount; KSAUDIO_POSITION m_Position; + KSALLOCATOR_FRAMING m_AllocatorFraming; SUBDEVICE_DESCRIPTOR m_Descriptor; ULONG m_Delay; @@ -93,9 +95,9 @@ typedef struct NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); - -DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat); +DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat, PinWaveCyclicAllocatorFraming); DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet, PinWaveCyclicAudioPosition); KSPROPERTY_SET PinWaveCyclicPropertySet[] = @@ -144,7 +146,40 @@ CPortPinWaveCyclic::QueryInterface( return STATUS_UNSUCCESSFUL; } +NTSTATUS +NTAPI +PinWaveCyclicAllocatorFraming( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + CPortPinWaveCyclic *Pin; + PSUBDEVICE_DESCRIPTOR Descriptor; + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + // cast to pin impl + Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; + + + if (Request->Flags & KSPROPERTY_TYPE_GET) + { + // copy pin framing + RtlMoveMemory(Data, &Pin->m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); + + Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); + return STATUS_SUCCESS; + } + + // not supported + return STATUS_NOT_SUPPORTED; +} NTSTATUS NTAPI @@ -579,7 +614,7 @@ CPortPinWaveCyclic::RequestService() } Status = m_Stream->GetPosition(&Position); - DPRINT1("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture); + DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture); if (Position < m_CommonBufferOffset) { @@ -958,8 +993,9 @@ CPortPinWaveCyclic::Init( NTSTATUS Status; PKSDATAFORMAT DataFormat; PDEVICE_OBJECT DeviceObject; - BOOL Capture; + BOOLEAN Capture; PVOID SilenceBuffer; + PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; //IDrmAudioStream * DrmAudio = NULL; m_KsPinDescriptor = KsPinDescriptor; @@ -1015,6 +1051,8 @@ CPortPinWaveCyclic::Init( } #endif + DPRINT("CPortPinWaveCyclic::Init Status %x\n", Status); + if (!NT_SUCCESS(Status)) return Status; @@ -1025,8 +1063,6 @@ CPortPinWaveCyclic::Init( if (!NT_SUCCESS(Status)) return Status; - PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; - Status = Subdevice->GetDescriptor(&SubDeviceDescriptor); if (!NT_SUCCESS(Status)) { @@ -1044,11 +1080,10 @@ CPortPinWaveCyclic::Init( m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; m_Descriptor.PortPin = (PVOID)this; - DPRINT("CPortPinWaveCyclic::Init Status %x\n", Status); - // release subdevice descriptor Subdevice->Release(); + // add ourselves to service group Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); if (!NT_SUCCESS(Status)) { @@ -1072,6 +1107,15 @@ CPortPinWaveCyclic::Init( if (!SilenceBuffer) return STATUS_INSUFFICIENT_RESOURCES; + + /* set up allocator framing */ + m_AllocatorFraming.RequirementsFlags = KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY | KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY; + m_AllocatorFraming.PoolType = NonPagedPool; + m_AllocatorFraming.Frames = 8; + m_AllocatorFraming.FileAlignment = FILE_64_BYTE_ALIGNMENT; + m_AllocatorFraming.Reserved = 0; + m_AllocatorFraming.FrameSize = m_FrameSize; + m_Stream->Silence(SilenceBuffer, m_FrameSize); Status = m_IrpQueue->Init(ConnectDetails, DataFormat, DeviceObject, m_FrameSize, 0, SilenceBuffer); diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp index 7732b1a2aa6..336605cbc5f 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp @@ -41,6 +41,11 @@ public: VOID NTAPI CloseStream(); protected: + friend NTSTATUS NTAPI PinWavePciState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + friend NTSTATUS NTAPI PinWavePciDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + friend NTSTATUS NTAPI PinWavePciAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + friend NTSTATUS NTAPI PinWavePciAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + IPortWavePci * m_Port; IPortFilterWavePci * m_Filter; KSPIN_DESCRIPTOR * m_KsPinDescriptor; @@ -57,20 +62,23 @@ protected: IIrpQueue * m_IrpQueue; ULONG m_TotalPackets; - ULONG m_PreCompleted; - ULONG m_PostCompleted; + KSAUDIO_POSITION m_Position; ULONG m_StopCount; ULONG m_Delay; BOOL m_bUsePrefetch; ULONG m_PrefetchOffset; + SUBDEVICE_DESCRIPTOR m_Descriptor; KSALLOCATOR_FRAMING m_AllocatorFraming; LONG m_Ref; - NTSTATUS NTAPI HandleKsProperty(IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN PIO_STATUS_BLOCK IoStatusBlock); + NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); + NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); + + VOID NTAPI SetStreamState( IN KSSTATE State); }; @@ -81,6 +89,283 @@ typedef struct KSSTATE State; }SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; +NTSTATUS NTAPI PinWavePciState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI PinWavePciDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI PinWavePciAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI PinWavePciAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + +DEFINE_KSPROPERTY_CONNECTIONSET(PinWavePciConnectionSet, PinWavePciState, PinWavePciDataFormat, PinWavePciAllocatorFraming); +DEFINE_KSPROPERTY_AUDIOSET(PinWavePciAudioSet, PinWavePciAudioPosition); + +KSPROPERTY_SET PinWavePciPropertySet[] = +{ + { + &KSPROPSETID_Connection, + sizeof(PinWavePciConnectionSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PinWavePciConnectionSet, + 0, + NULL + }, + { + &KSPROPSETID_Audio, + sizeof(PinWavePciAudioSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PinWavePciAudioSet, + 0, + NULL + } +}; + + +NTSTATUS +NTAPI +PinWavePciAllocatorFraming( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + CPortPinWavePci *Pin; + PSUBDEVICE_DESCRIPTOR Descriptor; + + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + // cast to pin impl + Pin = (CPortPinWavePci*)Descriptor->PortPin; + + + if (Request->Flags & KSPROPERTY_TYPE_GET) + { + // copy pin framing + RtlMoveMemory(Data, &Pin->m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); + + Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); + return STATUS_SUCCESS; + } + + // not supported + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS +NTAPI +PinWavePciAudioPosition( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + CPortPinWavePci *Pin; + PSUBDEVICE_DESCRIPTOR Descriptor; + + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + // cast to pin impl + Pin = (CPortPinWavePci*)Descriptor->PortPin; + + //sanity check + PC_ASSERT(Pin->m_Stream); + + if (Request->Flags & KSPROPERTY_TYPE_GET) + { + // FIXME non multithreading-safe + // copy audio position + RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION)); + + DPRINT1("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset); + Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); + return STATUS_SUCCESS; + } + + // not supported + return STATUS_NOT_SUPPORTED; +} + + +NTSTATUS +NTAPI +PinWavePciState( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + NTSTATUS Status = STATUS_UNSUCCESSFUL; + CPortPinWavePci *Pin; + PSUBDEVICE_DESCRIPTOR Descriptor; + PKSSTATE State = (PKSSTATE)Data; + + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + // cast to pin impl + Pin = (CPortPinWavePci*)Descriptor->PortPin; + + //sanity check + PC_ASSERT(Pin->m_Stream); + + if (Request->Flags & KSPROPERTY_TYPE_SET) + { + // try set stream + Status = Pin->m_Stream->SetState(*State); + + DPRINT("Setting state %u %x\n", *State, Status); + if (NT_SUCCESS(Status)) + { + // store new state + Pin->m_State = *State; + } + // store result + Irp->IoStatus.Information = sizeof(KSSTATE); + return Status; + } + else if (Request->Flags & KSPROPERTY_TYPE_GET) + { + // get current stream state + *State = Pin->m_State; + // store result + Irp->IoStatus.Information = sizeof(KSSTATE); + + return STATUS_SUCCESS; + } + + // unsupported request + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS +NTAPI +PinWavePciDataFormat( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + NTSTATUS Status = STATUS_UNSUCCESSFUL; + CPortPinWavePci *Pin; + PSUBDEVICE_DESCRIPTOR Descriptor; + PIO_STACK_LOCATION IoStack; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + + // cast to pin impl + Pin = (CPortPinWavePci*)Descriptor->PortPin; + + //sanity check + PC_ASSERT(Pin->m_Stream); + PC_ASSERT(Pin->m_Format); + + if (Request->Flags & KSPROPERTY_TYPE_SET) + { + // try to change data format + PKSDATAFORMAT NewDataFormat, DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; + ULONG Size = min(Pin->m_Format->FormatSize, DataFormat->FormatSize); + + if (RtlCompareMemory(DataFormat, Pin->m_Format, Size) == Size) + { + // format is identical + Irp->IoStatus.Information = DataFormat->FormatSize; + return STATUS_SUCCESS; + } + + // new change request + PC_ASSERT(Pin->m_State == KSSTATE_STOP); + // FIXME queue a work item when Irql != PASSIVE_LEVEL + PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + + // allocate new data format + NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!NewDataFormat) + { + // not enough memory + return STATUS_NO_MEMORY; + } + + // copy new data format + RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); + + // set new format + Status = Pin->m_Stream->SetFormat(NewDataFormat); + if (NT_SUCCESS(Status)) + { + // free old format + FreeItem(Pin->m_Format, TAG_PORTCLASS); + + // update irp queue with new format + Pin->m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat); + + // store new format + Pin->m_Format = NewDataFormat; + Irp->IoStatus.Information = NewDataFormat->FormatSize; + +#if 0 + PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); + PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO)); + PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM)); + PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); + + + DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels, + ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample, + ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec); +#endif + + } + else + { + // failed to set format + FreeItem(NewDataFormat, TAG_PORTCLASS); + } + + + // done + return Status; + } + else if (Request->Flags & KSPROPERTY_TYPE_GET) + { + // get current data format + PC_ASSERT(Pin->m_Format); + + if (Pin->m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + // buffer too small + Irp->IoStatus.Information = Pin->m_Format->FormatSize; + return STATUS_MORE_ENTRIES; + } + // copy data format + RtlMoveMemory(Data, Pin->m_Format, Pin->m_Format->FormatSize); + // store result size + Irp->IoStatus.Information = Pin->m_Format->FormatSize; + + // done + return STATUS_SUCCESS; + } + + // unsupported request + return STATUS_NOT_SUPPORTED; +} + + //================================================================================================================================== NTSTATUS NTAPI @@ -185,7 +470,7 @@ CPortPinWavePci::SetState(KSSTATE State) // store minimum data threshold m_IrpQueue->SetMinimumDataThreshold(MinimumDataThreshold); - DPRINT1("Stopping PreCompleted %u PostCompleted %u StopCount %u MinimumDataThreshold %u\n", m_PreCompleted, m_PostCompleted, m_StopCount, MinimumDataThreshold); + DPRINT1("Stopping TotalCompleted %u StopCount %u MinimumDataThreshold %u\n", m_TotalPackets, m_StopCount, MinimumDataThreshold); } if (m_State == KSSTATE_RUN) { @@ -308,144 +593,50 @@ CPortPinWavePci::NewIrpTarget( NTSTATUS NTAPI CPortPinWavePci::HandleKsProperty( - IN PVOID InputBuffer, - IN ULONG InputBufferLength, - IN PVOID OutputBuffer, - IN ULONG OutputBufferLength, - IN PIO_STATUS_BLOCK IoStatusBlock) + IN PIRP Irp) { PKSPROPERTY Property; NTSTATUS Status; UNICODE_STRING GuidString; + PIO_STACK_LOCATION IoStack; - DPRINT("IPortPinWavePci_HandleKsProperty entered\n"); + IoStack = IoGetCurrentIrpStackLocation(Irp); - if (InputBufferLength < sizeof(KSPROPERTY)) + DPRINT("IPortPinWave_HandleKsProperty entered\n"); + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) { - IoStatusBlock->Information = 0; - IoStatusBlock->Status = STATUS_INVALID_PARAMETER; - return STATUS_INVALID_PARAMETER; + DPRINT1("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength); + + Irp->IoStatus.Status = STATUS_SUCCESS; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; } - Property = (PKSPROPERTY)InputBuffer; + Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); - if (IsEqualGUIDAligned(Property->Set, KSPROPSETID_Connection)) + if (Status == STATUS_NOT_FOUND) { - if (Property->Id == KSPROPERTY_CONNECTION_STATE) - { - PKSSTATE State = (PKSSTATE)OutputBuffer; + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - PC_ASSERT_IRQL(DISPATCH_LEVEL); - if (OutputBufferLength < sizeof(KSSTATE)) - { - IoStatusBlock->Information = sizeof(KSSTATE); - IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL; - return STATUS_BUFFER_TOO_SMALL; - } + RtlStringFromGUID(Property->Set, &GuidString); + DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); + RtlFreeUnicodeString(&GuidString); + } - if (Property->Flags & KSPROPERTY_TYPE_SET) - { - Status = STATUS_UNSUCCESSFUL; - IoStatusBlock->Information = 0; + if (Status != STATUS_PENDING) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } - if (m_Stream) - { - Status = m_Stream->SetState(*State); + return Status; +} - DPRINT1("Setting state %u %x\n", *State, Status); - if (NT_SUCCESS(Status)) - { - m_State = *State; - } - } - IoStatusBlock->Status = Status; - return Status; - } - else if (Property->Flags & KSPROPERTY_TYPE_GET) - { - *State = m_State; - IoStatusBlock->Information = sizeof(KSSTATE); - IoStatusBlock->Status = STATUS_SUCCESS; - return STATUS_SUCCESS; - } - } - else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT) - { - PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)OutputBuffer; - if (Property->Flags & KSPROPERTY_TYPE_SET) - { - PKSDATAFORMAT NewDataFormat; - if (!RtlCompareMemory(DataFormat, m_Format, DataFormat->FormatSize)) - { - IoStatusBlock->Information = DataFormat->FormatSize; - IoStatusBlock->Status = STATUS_SUCCESS; - return STATUS_SUCCESS; - } - - NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); - if (!NewDataFormat) - { - IoStatusBlock->Information = 0; - IoStatusBlock->Status = STATUS_NO_MEMORY; - return STATUS_NO_MEMORY; - } - RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); - - if (m_Stream) - { #if 0 - ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); - ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO)); - ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)); - ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); - - ASSERT(This->State == KSSTATE_STOP); -#endif - DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels, - ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample, - ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec); - - Status = m_Stream->SetFormat(NewDataFormat); - if (NT_SUCCESS(Status)) - { - if (m_Format) - ExFreePoolWithTag(m_Format, TAG_PORTCLASS); - - m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat); - m_Format = NewDataFormat; - IoStatusBlock->Information = DataFormat->FormatSize; - IoStatusBlock->Status = STATUS_SUCCESS; - return STATUS_SUCCESS; - } - } - DPRINT1("Failed to set format\n"); - IoStatusBlock->Information = 0; - IoStatusBlock->Status = STATUS_UNSUCCESSFUL; - return STATUS_UNSUCCESSFUL; - } - else if (Property->Flags & KSPROPERTY_TYPE_GET) - { - if (!m_Format) - { - DPRINT1("No format\n"); - IoStatusBlock->Information = 0; - IoStatusBlock->Status = STATUS_UNSUCCESSFUL; - return STATUS_UNSUCCESSFUL; - } - if (m_Format->FormatSize > OutputBufferLength) - { - IoStatusBlock->Information = m_Format->FormatSize; - IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL; - return STATUS_BUFFER_TOO_SMALL; - } - - RtlMoveMemory(DataFormat, m_Format, m_Format->FormatSize); - IoStatusBlock->Information = DataFormat->FormatSize; - IoStatusBlock->Status = STATUS_SUCCESS; - return STATUS_SUCCESS; - } - } else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING) { PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)OutputBuffer; @@ -466,16 +657,38 @@ CPortPinWavePci::HandleKsProperty( return STATUS_SUCCESS; } } +#endif - RtlStringFromGUID(Property->Set, &GuidString); - DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); - RtlFreeUnicodeString(&GuidString); +NTSTATUS +NTAPI +CPortPinWavePci::HandleKsStream( + IN PIRP Irp) +{ + NTSTATUS Status; + InterlockedIncrement((PLONG)&m_TotalPackets); - IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED; - IoStatusBlock->Information = 0; - return STATUS_NOT_IMPLEMENTED; + DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); + + Status = m_IrpQueue->AddMapping(NULL, 0, Irp); + + if (NT_SUCCESS(Status)) + { + + PKSSTREAM_HEADER Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; + PC_ASSERT(Header); + + if (m_Capture) + m_Position.WriteOffset += Header->FrameExtent; + else + m_Position.WriteOffset += Header->DataUsed; + + } + + + return STATUS_PENDING; } + NTSTATUS NTAPI CPortPinWavePci::DeviceIoControl( @@ -483,17 +696,17 @@ CPortPinWavePci::DeviceIoControl( IN PIRP Irp) { PIO_STACK_LOCATION IoStack; - NTSTATUS Status; IoStack = IoGetCurrentIrpStackLocation(Irp); if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) { - Status = HandleKsProperty(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &Irp->IoStatus); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; + return HandleKsProperty(Irp); + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM) + { + return HandleKsStream(Irp); } - UNIMPLEMENTED @@ -735,7 +948,7 @@ CPortPinWavePci::Init( { NTSTATUS Status; PKSDATAFORMAT DataFormat; - BOOL Capture; + BOOLEAN Capture; Port->AddRef(); Filter->AddRef(); @@ -810,6 +1023,34 @@ CPortPinWavePci::Init( DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n", m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment); + ISubdevice * Subdevice = NULL; + // get subdevice interface + Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice); + + if (!NT_SUCCESS(Status)) + return Status; + + PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; + + Status = Subdevice->GetDescriptor(&SubDeviceDescriptor); + if (!NT_SUCCESS(Status)) + { + // failed to get descriptor + Subdevice->Release(); + return Status; + } + + /* set up subdevice descriptor */ + RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR)); + m_Descriptor.FilterPropertySet = PinWavePciPropertySet; + m_Descriptor.FilterPropertySetCount = sizeof(PinWavePciPropertySet) / sizeof(KSPROPERTY_SET); + m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream; + m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor; + m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; + m_Descriptor.PortPin = (PVOID)this; + + + Status = NewIrpQueue(&m_IrpQueue); if (!NT_SUCCESS(Status)) return Status; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp index 3e6eb97a464..22ae5a6a600 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp @@ -8,8 +8,7 @@ #include "private.hpp" -class CPortPinWaveRT : public IPortPinWaveRT, - public IServiceSink //hack +class CPortPinWaveRT : public IPortPinWaveRT { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); @@ -31,7 +30,6 @@ public: return m_Ref; } IMP_IPortPinWaveRT; - IMP_IServiceSink; //HACK CPortPinWaveRT(IUnknown *OuterUnknown){} virtual ~CPortPinWaveRT(){} @@ -43,7 +41,6 @@ protected: PMINIPORTWAVERT m_Miniport; PMINIPORTWAVERTSTREAM m_Stream; PPORTWAVERTSTREAM m_PortStream; - PSERVICEGROUP m_ServiceGroup; KSSTATE m_State; PKSDATAFORMAT m_Format; KSPIN_CONNECT * m_ConnectDetails; @@ -70,8 +67,6 @@ protected: NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); VOID NTAPI SetStreamState(IN KSSTATE State); - VOID UpdateCommonBuffer(ULONG Position); - VOID UpdateCommonBufferOverlap(ULONG Position); friend VOID NTAPI SetStreamWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); friend VOID NTAPI CloseStreamRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); @@ -86,81 +81,6 @@ typedef struct }SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; -VOID -CPortPinWaveRT::UpdateCommonBuffer( - ULONG Position) -{ - ULONG BufferLength; - ULONG BytesToCopy; - ULONG BufferSize; - PUCHAR Buffer; - NTSTATUS Status; - - BufferLength = Position - m_CommonBufferOffset; - while(BufferLength) - { - Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); - if (!NT_SUCCESS(Status)) - return; - - BytesToCopy = min(BufferLength, BufferSize); - - if (m_Capture) - { - RtlMoveMemory(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); - } - else - { - RtlMoveMemory((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, Buffer, BytesToCopy); - } - - m_IrpQueue->UpdateMapping(BytesToCopy); - m_CommonBufferOffset += BytesToCopy; - - BufferLength = Position - m_CommonBufferOffset; - } -} - -VOID -CPortPinWaveRT::UpdateCommonBufferOverlap( - ULONG Position) -{ - ULONG BufferLength; - ULONG BytesToCopy; - ULONG BufferSize; - PUCHAR Buffer; - NTSTATUS Status; - - - BufferLength = m_CommonBufferSize - m_CommonBufferOffset; - while(BufferLength) - { - Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); - if (!NT_SUCCESS(Status)) - return; - - BytesToCopy = min(BufferLength, BufferSize); - - if (m_Capture) - { - RtlMoveMemory(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); - } - else - { - RtlMoveMemory((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, Buffer, BytesToCopy); - } - - m_IrpQueue->UpdateMapping(BytesToCopy); - m_CommonBufferOffset += BytesToCopy; - - BufferLength = m_CommonBufferSize - m_CommonBufferOffset; - } - m_CommonBufferOffset = 0; - UpdateCommonBuffer(Position); -} - - - //================================================================================================================================== NTSTATUS NTAPI @@ -170,13 +90,6 @@ CPortPinWaveRT::QueryInterface( { DPRINT("IServiceSink_fnQueryInterface entered\n"); - if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) - { - *Output = PVOID(PSERVICEGROUP(this)); - PUNKNOWN(*Output)->AddRef(); - return STATUS_SUCCESS; - } - if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || IsEqualGUIDAligned(refiid, IID_IUnknown)) { @@ -187,37 +100,6 @@ CPortPinWaveRT::QueryInterface( return STATUS_UNSUCCESSFUL; } -VOID -NTAPI -CPortPinWaveRT::RequestService() -{ - KSAUDIO_POSITION Position; - NTSTATUS Status; - PUCHAR Buffer; - ULONG BufferSize; - - PC_ASSERT_IRQL(DISPATCH_LEVEL); - - Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); - if (!NT_SUCCESS(Status)) - { - SetStreamState(KSSTATE_STOP); - return; - } - - Status = m_Stream->GetPosition(&Position); - DPRINT("PlayOffset %lu WriteOffset %lu Buffer %p BufferSize %u CommonBufferSize %u\n", Position.PlayOffset, Position.WriteOffset, Buffer, BufferSize, m_CommonBufferSize); - - if (Position.PlayOffset < m_CommonBufferOffset) - { - UpdateCommonBufferOverlap(Position.PlayOffset); - } - else if (Position.PlayOffset >= m_CommonBufferOffset) - { - UpdateCommonBuffer(Position.PlayOffset); - } -} - VOID NTAPI SetStreamWorkerRoutine( @@ -248,14 +130,12 @@ SetStreamWorkerRoutine( { // reset start stream This->m_IrpQueue->CancelBuffers(); //FIX function name - This->m_ServiceGroup->CancelDelayedService(); DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->m_PreCompleted, This->m_PostCompleted); } if (This->m_State == KSSTATE_RUN) { // start the notification timer - This->m_ServiceGroup->RequestDelayedService(This->m_Delay); } } } @@ -766,7 +646,7 @@ CPortPinWaveRT::Init( { NTSTATUS Status; PKSDATAFORMAT DataFormat; - BOOL Capture; + BOOLEAN Capture; KSRTAUDIO_HWLATENCY Latency; Port->AddRef(); @@ -806,15 +686,6 @@ CPortPinWaveRT::Init( goto cleanup; } - Status = PcNewServiceGroup(&m_ServiceGroup, NULL); - if (!NT_SUCCESS(Status)) - { - goto cleanup; - } - - m_ServiceGroup->AddMember(PSERVICESINK(this)); - m_ServiceGroup->SupportDelayedService(); - if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) { Capture = FALSE; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port.hpp b/reactos/drivers/wdm/audio/backpln/portcls/port.hpp deleted file mode 100644 index c10e47951e7..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/port.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS - * FILE: drivers/multimedia/portcls/port/port.h - * PURPOSE: Port Class driver / Private header for IPort - * PROGRAMMER: Andrew Greenwood - * - * HISTORY: - * 27 Jan 07 Created - */ - - -/* - Private header for Port implementations -*/ - -#ifndef PORT_PRIVATE_H -#define PORT_PRIVATE_H - -#include "private.h" -#include -#include - -#if 0 -typedef struct CPort -{ - union - { - IUnknown IUnknown; - IPort IPort; - }; - - LONG m_ref_count; - PUNKNOWN m_outer_unknown; -} CPort; -#endif - -#endif diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_factory.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_factory.cpp deleted file mode 100644 index 23def6b7b20..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_factory.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - ReactOS Operating System - Port Class API / Port Factory - - by Andrew Greenwood -*/ - -#define INITGUID - -#include "private.h" -#include -#include -#include -#include "port.h" - -/* - * @unimplemented - */ -PORTCLASSAPI NTSTATUS NTAPI -PcNewPort( - OUT PPORT* OutPort, - IN REFCLSID ClassId) -{ - /* - ClassId can be one of the following: - CLSID_PortDMus -> IPortDMus (dmusicks.h) -- TODO - CLSID_PortMidi -> IPortMidi - CLSID_PortTopology -> IPortTopology - CLSID_PortWaveCyclic -> IPortWaveCyclic - CLSID_PortWavePci -> IPortWavePci - - TODO: What about PortWavePciStream? - */ - - PPORT new_port = NULL; - NTSTATUS status = STATUS_UNSUCCESSFUL; - - if ( ! OutPort ) - { - DPRINT("PcNewPort was supplied a NULL OutPort parameter\n"); - return STATUS_INVALID_PARAMETER; - } - - if ( ( IsEqualGUIDAligned(ClassId, &CLSID_PortMidi) ) || - ( IsEqualGUIDAligned(ClassId, &CLSID_PortTopology) ) || - ( IsEqualGUIDAligned(ClassId, &CLSID_PortWaveCyclic) ) || - ( IsEqualGUIDAligned(ClassId, &CLSID_PortWavePci) ) ) - { - DPRINT("Calling KoCreateInstance\n"); - /* Call KS.SYS's Kernel-mode COM function */ - status = KoCreateInstance(ClassId, NULL, CLSCTX_KERNEL_SERVER, &IID_IPort, (PVOID*)&new_port); - } - else - { - - DPRINT("PcNewPort received a CLSID it does not deal with\n"); - status = STATUS_NOT_SUPPORTED; - } - - /* If an unsupported CLSID was handed to us, or the creation failed, we fail */ - if ( status != STATUS_SUCCESS ) - { - return status; - } - - /* Fill the caller's PPORT* to point to the new port */ - *OutPort = new_port; - - DPRINT("PcNewPort succeeded\n"); - - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp index 121e4bb6c45..4df32f05f3c 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp @@ -355,8 +355,8 @@ CPortWaveCyclic::NewMasterDmaChannel( IN PUNKNOWN OuterUnknown, IN PRESOURCELIST ResourceList OPTIONAL, IN ULONG MaximumLength, - IN BOOL Dma32BitAddresses, - IN BOOL Dma64BitAddresses, + IN BOOLEAN Dma32BitAddresses, + IN BOOLEAN Dma64BitAddresses, IN DMA_WIDTH DmaWidth, IN DMA_SPEED DmaSpeed) { @@ -388,7 +388,7 @@ CPortWaveCyclic::NewSlaveDmaChannel( IN PRESOURCELIST ResourceList OPTIONAL, IN ULONG DmaIndex, IN ULONG MaximumLength, - IN BOOL DemandMode, + IN BOOLEAN DemandMode, IN DMA_SPEED DmaSpeed) { DEVICE_DESCRIPTION DeviceDescription; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp index c141aabd32f..91b09940b0c 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp @@ -161,7 +161,7 @@ CPortWaveRTStreamInit::GetPhysicalPageAddress( return RtlConvertUlongToLargeInteger(0); } - Buffer = UlongToPtr(PtrToUlong(MmGetSystemAddressForMdl(MemoryDescriptorList)) + Index * PAGE_SIZE); + Buffer = (PVOID)UlongToPtr(PtrToUlong(MmGetSystemAddressForMdlSafe(MemoryDescriptorList, LowPagePriority)) + Index * PAGE_SIZE); Addr = MmGetPhysicalAddress(Buffer); Address->QuadPart = Addr.QuadPart; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild b/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild index c4ff5053411..9b008b652d3 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild +++ b/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild @@ -2,7 +2,6 @@ - 0x600 . ntoskrnl diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.hpp b/reactos/drivers/wdm/audio/backpln/portcls/private.hpp index ed8b45ced1c..1df2b4b9540 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.hpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.hpp @@ -9,6 +9,8 @@ //#define _KS_NO_ANONYMOUS_STRUCTURES_ #define PC_IMPLEMENTATION +#define COM_STDMETHOD_CAN_THROW +#define PC_NO_IMPORTS #include #include @@ -20,7 +22,7 @@ #include "interfaces.hpp" #include #include -#include +//#include #define TAG_PORTCLASS 'SLCP' @@ -244,8 +246,8 @@ NTAPI PcDmaSlaveDescription( IN PRESOURCELIST ResourceList OPTIONAL, IN ULONG DmaIndex, - IN BOOL DemandMode, - IN ULONG AutoInitialize, + IN BOOLEAN DemandMode, + IN BOOLEAN AutoInitialize, IN DMA_SPEED DmaSpeed, IN ULONG MaximumLength, IN ULONG DmaPort, @@ -315,10 +317,11 @@ PcHandlePropertyWithTable( IN PSUBDEVICE_DESCRIPTOR Descriptor); #define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\ - PropStateHandler, PropDataFormatHandler)\ + PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\ DEFINE_KSPROPERTY_TABLE(PinSet) {\ DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\ - DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler)\ + DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler),\ + DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(PropAllocatorFraming)\ } #define DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(GetHandler, SetHandler)\ @@ -336,9 +339,6 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\ DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(PropPositionHandler, PropPositionHandler)\ } - - - #define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\ PropGeneral, PropInstances, PropIntersection)\ DEFINE_KSPROPERTY_TABLE(PinSet) {\ diff --git a/reactos/drivers/wdm/audio/backpln/portcls/resource.cpp b/reactos/drivers/wdm/audio/backpln/portcls/resource.cpp index 2a2fc8c218e..03a72844a58 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/resource.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/resource.cpp @@ -34,6 +34,9 @@ public: } IMP_IResourceList; +#ifdef BUILD_WDK + ULONG NTAPI NumberOfEntries(); +#endif CResourceList(IUnknown * OuterUnknown) : m_OuterUnknown(OuterUnknown), m_PoolType(NonPagedPool), m_TranslatedResourceList(0), m_UntranslatedResourceList(0), m_NumberOfEntries(0) {} virtual ~CResourceList() {} @@ -72,15 +75,16 @@ CResourceList::QueryInterface( return STATUS_UNSUCCESSFUL; } - +#if 1 ULONG NTAPI CResourceList::NumberOfEntries() { - // ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); return m_NumberOfEntries; } +#endif ULONG NTAPI diff --git a/reactos/drivers/wdm/audio/backpln/portcls/service_group.cpp b/reactos/drivers/wdm/audio/backpln/portcls/service_group.cpp index af71d2cccc8..5268a3d2d3e 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/service_group.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/service_group.cpp @@ -117,6 +117,8 @@ CServiceGroup::RequestService() { KIRQL OldIrql; + DPRINT("CServiceGroup::RequestService() Dpc at Level %u\n", KeGetCurrentIrql()); + if (KeGetCurrentIrql() > DISPATCH_LEVEL) { KeInsertQueueDpc(&m_Dpc, NULL, NULL); diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index c448acc1ce2..a85409421a2 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -48,7 +48,7 @@ WdmAudControlDeviceType( IN PWDMAUD_CLIENT ClientInfo) { ULONG Result = 0; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PWDMAUD_DEVICE_EXTENSION DeviceExtension; DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -179,7 +179,7 @@ WdmAudFrameSize( Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { - DPRINT1("Invalid buffer handle %x\n", DeviceInfo->hDevice); + DPRINT1("Invalid buffer handle %p\n", DeviceInfo->hDevice); return SetIrpIoStatus(Irp, Status, 0); } @@ -343,7 +343,7 @@ WdmAudReadWrite( Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { - DPRINT1("Invalid pin handle %x\n", DeviceInfo->hDevice); + DPRINT1("Invalid pin handle %p\n", DeviceInfo->hDevice); return SetIrpIoStatus(Irp, Status, 0); } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c index cb46456f337..db59c0b25a9 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -863,7 +863,7 @@ GetControlsFromPinByConnectionIndex( if (bUpDirection) { /* add the sum / mux node to destination line */ - //Nodes[NodeIndex] = TRUE; + Nodes[NodeIndex] = TRUE; } return STATUS_SUCCESS; @@ -1005,7 +1005,27 @@ AddMixerControl( } MixerInfo->ControlId++; +#if 0 + if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUX) + { + KSNODEPROPERTY Property; + ULONG PinId = 2; + /* setup the request */ + RtlZeroMemory(&Property, sizeof(KSNODEPROPERTY)); + + Property.NodeId = NodeIndex; + Property.Property.Id = KSPROPERTY_AUDIO_MUX_SOURCE; + Property.Property.Flags = KSPROPERTY_TYPE_SET; + Property.Property.Set = KSPROPSETID_Audio; + + /* get node volume level info */ + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSNODEPROPERTY), (PVOID)&PinId, sizeof(ULONG), &BytesReturned); + + DPRINT1("Status %x NodeIndex %u PinId %u\n", Status, NodeIndex, PinId); + //DbgBreakPoint(); + }else +#endif if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) { KSNODEPROPERTY_AUDIO_CHANNEL Property; @@ -1041,37 +1061,42 @@ AddMixerControl( DPRINT("NodeIndex %u Range Min %d Max %d Steps %x UMin %x UMax %x\n", NodeIndex, Range->Bounds.SignedMinimum, Range->Bounds.SignedMaximum, Range->SteppingDelta, Range->Bounds.UnsignedMinimum, Range->Bounds.UnsignedMaximum); - VolumeData = ExAllocatePool(NonPagedPool, sizeof(MIXERVOLUME_DATA)); - if (!VolumeData) - return STATUS_INSUFFICIENT_RESOURCES; + MaxRange = Range->Bounds.UnsignedMaximum - Range->Bounds.UnsignedMinimum; - MaxRange = (abs(Range->Bounds.SignedMinimum) + abs(Range->Bounds.SignedMaximum)); - Steps = MaxRange / Range->SteppingDelta + 1; - - /* store mixer control info there */ - VolumeData->Header.dwControlID = MixerControl->dwControlID; - VolumeData->SignedMaximum = Range->Bounds.SignedMaximum; - VolumeData->SignedMinimum = Range->Bounds.SignedMinimum; - VolumeData->SteppingDelta = Range->SteppingDelta; - VolumeData->ValuesCount = Steps; - VolumeData->InputSteppingDelta = 0x10000 / Steps; - - VolumeData->Values = ExAllocatePool(NonPagedPool, sizeof(LONG) * Steps); - if (!VolumeData->Values) + if (MaxRange) { - ExFreePool(Desc); - ExFreePool(VolumeData); + ASSERT(MaxRange); + VolumeData = ExAllocatePool(NonPagedPool, sizeof(MIXERVOLUME_DATA)); + if (!VolumeData) + return STATUS_INSUFFICIENT_RESOURCES; - return STATUS_INSUFFICIENT_RESOURCES; - } + Steps = MaxRange / Range->SteppingDelta + 1; - Value = Range->Bounds.SignedMinimum; - for(Index = 0; Index < Steps; Index++) - { - VolumeData->Values[Index] = Value; - Value += Range->SteppingDelta; - } - InsertTailList(&MixerLine->LineControlsExtraData, &VolumeData->Header.Entry); + /* store mixer control info there */ + VolumeData->Header.dwControlID = MixerControl->dwControlID; + VolumeData->SignedMaximum = Range->Bounds.SignedMaximum; + VolumeData->SignedMinimum = Range->Bounds.SignedMinimum; + VolumeData->SteppingDelta = Range->SteppingDelta; + VolumeData->ValuesCount = Steps; + VolumeData->InputSteppingDelta = 0x10000 / Steps; + + VolumeData->Values = ExAllocatePool(NonPagedPool, sizeof(LONG) * Steps); + if (!VolumeData->Values) + { + ExFreePool(Desc); + ExFreePool(VolumeData); + + return STATUS_INSUFFICIENT_RESOURCES; + } + + Value = Range->Bounds.SignedMinimum; + for(Index = 0; Index < Steps; Index++) + { + VolumeData->Values[Index] = Value; + Value += Range->SteppingDelta; + } + InsertTailList(&MixerLine->LineControlsExtraData, &VolumeData->Header.Entry); + } } ExFreePool(Desc); } @@ -1445,6 +1470,7 @@ HandlePhysicalConnection( PinsSrcRef[Index] = TRUE; PinsSrcRef[OutConnection->Pin] = TRUE; } + PinsSrcRef[OutConnection->Pin] = TRUE; Status = AddMixerSourceLines(MixerInfo, FileObject, NodeConnections, NodeTypes, DeviceIndex, PinsRefCount, OutConnection->Pin, Index, PinsSrcRef); @@ -2208,6 +2234,7 @@ WdmAudGetControlDetails( } Status = STATUS_NOT_IMPLEMENTED; + DPRINT("dwLineId %x dwControlID %x dwControlType %x\n", MixerLine->Line.dwLineID, MixerControl->dwControlID, MixerControl->dwControlType); if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) { /* send the request */ diff --git a/reactos/drivers/wdm/audio/sysaudio/pin.c b/reactos/drivers/wdm/audio/sysaudio/pin.c index 07ef1b38763..ef1a4df6d6e 100644 --- a/reactos/drivers/wdm/audio/sysaudio/pin.c +++ b/reactos/drivers/wdm/audio/sysaudio/pin.c @@ -20,7 +20,7 @@ Pin_fnDeviceIoControl( PFILE_OBJECT FileObject; PIO_STACK_LOCATION IoStack; - DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); + DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject, Irp); /* Get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -136,7 +136,7 @@ Pin_fnClose( PDISPATCH_CONTEXT Context; PIO_STACK_LOCATION IoStack; - DPRINT("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject); + DPRINT("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject, Irp); /* Get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); diff --git a/reactos/include/crt/_mingw.h b/reactos/include/crt/_mingw.h index a71b387c3fd..3896fd1e99d 100644 --- a/reactos/include/crt/_mingw.h +++ b/reactos/include/crt/_mingw.h @@ -77,7 +77,7 @@ # define __unaligned #else # ifdef __GNUC__ -# define __unaligned __attribute((packed)) +# define __unaligned # elif defined(_MSC_VER) && !defined(_M_IA64) && !defined(_M_AMD64) # define __unaligned # else diff --git a/reactos/include/ddk/bdasup.h b/reactos/include/ddk/bdasup.h index 893bcde2b6c..0342ceaf696 100644 --- a/reactos/include/ddk/bdasup.h +++ b/reactos/include/ddk/bdasup.h @@ -96,21 +96,21 @@ STDMETHODIMP_(NTSTATUS) BdaPropertyGetPinControl( STDMETHODIMP_(NTSTATUS) BdaPropertyNodeDescriptors( IN PIRP Irp, IN KSPROPERTY *pKSProperty, - OUT GUID *pguidProperty); + OUT BDANODE_DESCRIPTOR *pNodeDescriptorProperty); STDMETHODIMP_(NTSTATUS) BdaPropertyNodeEvents( IN PIRP Irp, - IN KSPROPERTY *pKSProperty, + IN KSP_NODE *pKSProperty, OUT GUID *pguidProperty); STDMETHODIMP_(NTSTATUS) BdaPropertyNodeMethods( IN PIRP Irp, - IN KSPROPERTY *pKSProperty, + IN KSP_NODE *pKSProperty, OUT GUID *pguidProperty); STDMETHODIMP_(NTSTATUS) BdaPropertyNodeProperties( IN PIRP Irp, - IN KSPROPERTY *pKSProperty, + IN KSP_NODE *pKSProperty, OUT GUID *pguidProperty); STDMETHODIMP_(NTSTATUS) BdaPropertyNodeTypes( diff --git a/reactos/include/ddk/ntifs.h b/reactos/include/ddk/ntifs.h index 4a7657824b0..62d29154029 100644 --- a/reactos/include/ddk/ntifs.h +++ b/reactos/include/ddk/ntifs.h @@ -329,8 +329,6 @@ typedef enum _SECURITY_LOGON_TYPE #define MAILSLOT_SIZE_AUTO 0 -#define MAP_PROCESS 1L -#define MAP_SYSTEM 2L #define MEM_DOS_LIM 0x40000000 #define MCB_FLAG_RAISE_ON_ALLOCATION_FAILURE 1 diff --git a/reactos/include/ddk/portcls.h b/reactos/include/ddk/portcls.h index d5215901b0f..97becb4f51d 100644 --- a/reactos/include/ddk/portcls.h +++ b/reactos/include/ddk/portcls.h @@ -1187,7 +1187,7 @@ DECLARE_INTERFACE_(IPortWaveCyclic, IPort) IN PRESOURCELIST ResourceList OPTIONAL, IN ULONG DmaIndex, IN ULONG MaximumLength, - IN BOOL DemandMode, + IN BOOLEAN DemandMode, IN DMA_SPEED DmaSpeed) PURE; STDMETHOD_(NTSTATUS, NewMasterDmaChannel)(THIS_ @@ -1195,8 +1195,8 @@ DECLARE_INTERFACE_(IPortWaveCyclic, IPort) IN PUNKNOWN OuterUnknown, IN PRESOURCELIST ResourceList OPTIONAL, IN ULONG MaximumLength, - IN BOOL Dma32BitAddresses, - IN BOOL Dma64BitAddresses, + IN BOOLEAN Dma32BitAddresses, + IN BOOLEAN Dma64BitAddresses, IN DMA_WIDTH DmaWidth, IN DMA_SPEED DmaSpeed) PURE; @@ -1216,7 +1216,7 @@ typedef IPortWaveCyclic *PPORTWAVECYCLIC; IN PRESOURCELIST ResourceList OPTIONAL, \ IN ULONG DmaIndex, \ IN ULONG MaximumLength, \ - IN BOOL DemandMode, \ + IN BOOLEAN DemandMode, \ IN DMA_SPEED DmaSpeed); \ \ STDMETHODIMP_(NTSTATUS) NewMasterDmaChannel( \ @@ -1224,8 +1224,8 @@ typedef IPortWaveCyclic *PPORTWAVECYCLIC; IN PUNKNOWN OuterUnknown, \ IN PRESOURCELIST ResourceList OPTIONAL, \ IN ULONG MaximumLength, \ - IN BOOL Dma32BitAddresses, \ - IN BOOL Dma64BitAddresses, \ + IN BOOLEAN Dma32BitAddresses, \ + IN BOOLEAN Dma64BitAddresses, \ IN DMA_WIDTH DmaWidth, \ IN DMA_SPEED DmaSpeed) #endif diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 4bab620ed9f..d86119068f6 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -5674,6 +5674,14 @@ KefReleaseSpinLockFromDpcLevel( #elif defined(_M_ARM) // !defined (_X86_) + FORCEINLINE + VOID + KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock) + { + /* Clear the lock */ + *SpinLock = 0; + } + NTHALAPI KIRQL FASTCALL diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 67b6c042f00..feb0ea4441d 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -8,639 +8,22 @@ Header Name: Abstract: - ASM Offsets for dealing with de-referencing structures in registers. - C-compatible version of the file ks386.inc present in the newest WDK. + Portability header to choose the correct Architecture-specific header. Author: Alex Ionescu (alex.ionescu@reactos.com) 06-Oct-2004 --*/ -#ifdef _M_AMD64 -# include "amd64/asm.h" + +#if defined(_M_IX86) +#include +#elif defined(_M_AMD64) +#include +#elif defined(_M_ARM) || defined(_M_PPC) +// +// ARM and PPC ports don't use asm.h +// #else -#ifndef _ASM_H -#define _ASM_H - -// -// PCR Access -// -#ifdef __ASM__ -#ifdef CONFIG_SMP -#define PCR fs: -#else -#define PCR ds:[0xFFDFF000] +#error Unsupported Architecture #endif -#endif - -// -// CPU Modes -// -#define KernelMode 0x0 -#define UserMode 0x1 - -// -// CPU Types -// -#define CPU_NONE 0x0 -#define CPU_INTEL 0x1 -#define CPU_AMD 0x2 -#define CPU_CYRIX 0x3 -#define CPU_TRANSMETA 0x4 -#define CPU_CENTAUR 0x5 -#define CPU_RISE 0x6 -#define CPU_UNKNOWN 0x7 - -// -// Selector Names -// -#ifdef __ASM__ -#define RPL_MASK 0x0003 -#define MODE_MASK 0x0001 -#define KGDT_R0_CODE (0x8) -#define KGDT_R0_DATA (0x10) -#define KGDT_R3_CODE (0x18) -#define KGDT_R3_DATA (0x20) -#define KGDT_TSS (0x28) -#define KGDT_R0_PCR (0x30) -#define KGDT_R3_TEB (0x38) -#define KGDT_LDT (0x48) -#define KGDT_DF_TSS (0x50) -#define KGDT_NMI_TSS (0x58) -#endif - -// -// KV86M_REGISTERS Offsets -// -#define KV86M_REGISTERS_EBP 0x0 -#define KV86M_REGISTERS_EDI 0x4 -#define KV86M_REGISTERS_ESI 0x8 -#define KV86M_REGISTERS_EDX 0xC -#define KV86M_REGISTERS_ECX 0x10 -#define KV86M_REGISTERS_EBX 0x14 -#define KV86M_REGISTERS_EAX 0x18 -#define KV86M_REGISTERS_DS 0x1C -#define KV86M_REGISTERS_ES 0x20 -#define KV86M_REGISTERS_FS 0x24 -#define KV86M_REGISTERS_GS 0x28 -#define KV86M_REGISTERS_EIP 0x2C -#define KV86M_REGISTERS_CS 0x30 -#define KV86M_REGISTERS_EFLAGS 0x34 -#define KV86M_REGISTERS_ESP 0x38 -#define KV86M_REGISTERS_SS 0x3C -#define TF_SAVED_EXCEPTION_STACK 0x8C -#define TF_REGS 0x90 -#define TF_ORIG_EBP 0x94 - -// -// TSS Offsets -// -#define KTSS_ESP0 0x4 -#define KTSS_CR3 0x1C -#define KTSS_EFLAGS 0x24 -#define KTSS_IOMAPBASE 0x66 -#define KTSS_IO_MAPS 0x68 - -// -// KTHREAD Offsets -// -#define KTHREAD_DEBUG_ACTIVE 0x03 -#define KTHREAD_INITIAL_STACK 0x18 -#define KTHREAD_STACK_LIMIT 0x1C -#define KTHREAD_TEB 0x74 -#define KTHREAD_KERNEL_STACK 0x20 -#define KTHREAD_ALERTED 0x5E -#define KTHREAD_APCSTATE_PROCESS 0x28 + 0x10 -#define KTHREAD_PENDING_USER_APC 0x28 + 0x16 -#define KTHREAD_PENDING_KERNEL_APC 0x28 + 0x15 -#define KTHREAD_CONTEXT_SWITCHES 0x48 -#define KTHREAD_STATE_ 0x4C -#define KTHREAD_NPX_STATE 0x4D -#define KTHREAD_WAIT_IRQL 0x4E -#define KTHREAD_NEXT_PROCESSOR 0x40 -#define KTHREAD_WAIT_REASON 0x5A -#define KTHREAD_PRIORITY 0x5B -#define KTHREAD_SWAP_BUSY 0x5D -#define KTHREAD_SERVICE_TABLE 0x118 -#define KTHREAD_PREVIOUS_MODE 0xD7 -#define KTHREAD_COMBINED_APC_DISABLE 0x70 -#define KTHREAD_SPECIAL_APC_DISABLE 0x72 -#define KTHREAD_LARGE_STACK 0x107 -#define KTHREAD_TRAP_FRAME 0x110 -#define KTHREAD_CALLBACK_STACK 0x114 -#define KTHREAD_APC_STATE_INDEX 0x11C -#define KTHREAD_STACK_BASE 0x158 -#define KTHREAD_QUANTUM 0x15D -#define KTHREAD_KERNEL_TIME 0x160 -#define KTHREAD_USER_TIME 0x18C - -// -// KPROCESS Offsets -// -#define KPROCESS_DIRECTORY_TABLE_BASE 0x18 -#define KPROCESS_LDT_DESCRIPTOR0 0x20 -#define KPROCESS_LDT_DESCRIPTOR1 0x24 -#define KPROCESS_INT21_DESCRIPTOR0 0x28 -#define KPROCESS_INT21_DESCRIPTOR1 0x2C -#define KPROCESS_IOPM_OFFSET 0x30 -#define KPROCESS_ACTIVE_PROCESSORS 0x34 -#define EPROCESS_VDM_OBJECTS 0x144 - -// -// KTIMER_TABLE Offsets -// -#ifdef __ASM__ -#define KTIMER_TABLE_ENTRY 0x00 -#define KTIMER_TABLE_TIME 0x08 -#define TIMER_ENTRY_SIZE 0x10 -#define TIMER_TABLE_SIZE 0x200 -#endif - -// -// KPRCB Offsets -// -#define KPRCB_DR0 0x2F8 -#define KPRCB_DR1 0x2FC -#define KPRCB_DR2 0x300 -#define KPRCB_DR3 0x304 -#define KPRCB_DR6 0x308 -#define KPRCB_DR7 0x30C -#define KPRCB_TIMER_HAND 0x964 -#define KPRCB_TIMER_REQUEST 0x968 - -// -// KPCR Offsets -// -#define KPCR_EXCEPTION_LIST 0x0 -#define KPCR_INITIAL_STACK 0x4 -#define KPCR_STACK_LIMIT 0x8 -#define KPCR_PERF_GLOBAL_GROUP_MASK 0x8 -#define KPCR_CONTEXT_SWITCHES 0x10 -#define KPCR_SET_MEMBER_COPY 0x14 -#define KPCR_TEB 0x18 -#define KPCR_SELF 0x1C -#define KPCR_PRCB 0x20 -#define KPCR_IRQL 0x24 -#define KPCR_IRR 0x28 -#define KPCR_IRR_ACTIVE 0x2C -#define KPCR_IDR 0x30 -#define KPCR_KD_VERSION_BLOCK 0x34 -#define KPCR_IDT 0x38 -#define KPCR_GDT 0x3C -#define KPCR_TSS 0x40 -#define KPCR_STALL_SCALE_FACTOR 0x4C -#define KPCR_SET_MEMBER 0x48 -#define KPCR_NUMBER 0x51 -#define KPCR_VDM_ALERT 0x54 -#define KPCR_PRCB_DATA 0x120 -#define KPCR_CURRENT_THREAD 0x124 -#define KPCR_PRCB_NEXT_THREAD 0x128 -#define KPCR_PRCB_IDLE_THREAD 0x12C -#define KPCR_PROCESSOR_NUMBER 0x130 -#define KPCR_PRCB_SET_MEMBER 0x134 -#define KPCR_PRCB_CPU_TYPE 0x138 -#define KPCR_PRCB_PRCB_LOCK 0xA7C -#define KPCR_NPX_THREAD 0x640 -#define KPCR_DR6 0x428 -#define KPCR_DR7 0x42C -#define KPCR_PRCB_INTERRUPT_COUNT 0x644 -#define KPCR_PRCB_KERNEL_TIME 0x648 -#define KPCR_PRCB_USER_TIME 0x64C -#define KPCR_PRCB_DPC_TIME 0x650 -#define KPCR_PRCB_DEBUG_DPC_TIME 0x654 -#define KPCR_PRCB_INTERRUPT_TIME 0x658 -#define KPCR_PRCB_ADJUST_DPC_THRESHOLD 0x65C -#define KPCR_PRCB_SKIP_TICK 0x664 -#define KPCR_SYSTEM_CALLS 0x6B8 -#define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C -#define KPCR_PRCB_DPC_COUNT 0xA50 -#define KPCR_PRCB_DPC_STACK 0xA68 -#define KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH 0xA6C -#define KPCR_PRCB_DPC_REQUEST_RATE 0xA70 -#define KPCR_PRCB_DPC_INTERRUPT_REQUESTED 0xA78 -#define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0xA7A -#define KPCR_PRCB_DPC_LAST_COUNT 0xA80 -#define KPCR_PRCB_TIMER_REQUEST 0xA88 -#define KPCR_PRCB_QUANTUM_END 0xAA1 -#define KPCR_PRCB_IDLE_SCHEDULE 0xAA3 -#define KPCR_PRCB_DEFERRED_READY_LIST_HEAD 0xC10 -#define KPCR_PRCB_POWER_STATE_IDLE_FUNCTION 0xEC0 - -// -// KINTERRUPT Offsets -// -#define KINTERRUPT_INTERRUPT_LIST_HEAD 0x04 -#define KINTERRUPT_SERVICE_ROUTINE 0x0C -#define KINTERRUPT_SERVICE_CONTEXT 0x10 -#define KINTERRUPT_TICK_COUNT 0x18 -#define KINTERRUPT_ACTUAL_LOCK 0x1C -#define KINTERRUPT_VECTOR 0x24 -#define KINTERRUPT_IRQL 0x28 -#define KINTERRUPT_SYNCHRONIZE_IRQL 0x29 -#define KINTERRUPT_DISPATCH_COUNT 0x38 - -// -// KGDTENTRY Offsets -// -#define KGDT_BASE_LOW 0x2 -#define KGDT_BASE_MID 0x4 -#define KGDT_BASE_HI 0x7 -#define KGDT_LIMIT_HI 0x6 -#define KGDT_LIMIT_LOW 0x0 - -// -// FPU Save Area Offsets -// -#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 -#define FX_MXCSR 0x18 - -// -// NPX States -// -#define NPX_STATE_NOT_LOADED 0xA -#define NPX_STATE_LOADED 0x0 - -// -// Trap Frame Offsets -// -#define KTRAP_FRAME_DEBUGEBP 0x0 -#define KTRAP_FRAME_DEBUGEIP 0x4 -#define KTRAP_FRAME_DEBUGARGMARK 0x8 -#define KTRAP_FRAME_DEBUGPOINTER 0xC -#define KTRAP_FRAME_TEMPCS 0x10 -#define KTRAP_FRAME_TEMPESP 0x14 -#define KTRAP_FRAME_DR0 0x18 -#define KTRAP_FRAME_DR1 0x1C -#define KTRAP_FRAME_DR2 0x20 -#define KTRAP_FRAME_DR3 0x24 -#define KTRAP_FRAME_DR6 0x28 -#define KTRAP_FRAME_DR7 0x2C -#define KTRAP_FRAME_GS 0x30 -#define KTRAP_FRAME_RESERVED1 0x32 -#define KTRAP_FRAME_ES 0x34 -#define KTRAP_FRAME_RESERVED2 0x36 -#define KTRAP_FRAME_DS 0x38 -#define KTRAP_FRAME_RESERVED3 0x3A -#define KTRAP_FRAME_EDX 0x3C -#define KTRAP_FRAME_ECX 0x40 -#define KTRAP_FRAME_EAX 0x44 -#define KTRAP_FRAME_PREVIOUS_MODE 0x48 -#define KTRAP_FRAME_EXCEPTION_LIST 0x4C -#define KTRAP_FRAME_FS 0x50 -#define KTRAP_FRAME_RESERVED4 0x52 -#define KTRAP_FRAME_EDI 0x54 -#define KTRAP_FRAME_ESI 0x58 -#define KTRAP_FRAME_EBX 0x5C -#define KTRAP_FRAME_EBP 0x60 -#define KTRAP_FRAME_ERROR_CODE 0x64 -#define KTRAP_FRAME_EIP 0x68 -#define KTRAP_FRAME_CS 0x6C -#define KTRAP_FRAME_EFLAGS 0x70 -#define KTRAP_FRAME_ESP 0x74 -#define KTRAP_FRAME_SS 0x78 -#define KTRAP_FRAME_RESERVED5 0x7A -#define KTRAP_FRAME_V86_ES 0x7C -#define KTRAP_FRAME_RESERVED6 0x7E -#define KTRAP_FRAME_V86_DS 0x80 -#define KTRAP_FRAME_RESERVED7 0x82 -#define KTRAP_FRAME_V86_FS 0x84 -#define KTRAP_FRAME_RESERVED8 0x86 -#define KTRAP_FRAME_V86_GS 0x88 -#define KTRAP_FRAME_RESERVED9 0x8A -#define KTRAP_FRAME_SIZE 0x8C -#define KTRAP_FRAME_LENGTH 0x8C -#define KTRAP_FRAME_ALIGN 0x04 -#define FRAME_EDITED 0xFFF8 - -// -// KUSER_SHARED_DATA Offsets -// -#ifdef __ASM__ -#define USER_SHARED_DATA 0xFFDF0000 -#endif -#define USER_SHARED_DATA_INTERRUPT_TIME 0x8 -#define USER_SHARED_DATA_SYSTEM_TIME 0x14 -#define USER_SHARED_DATA_TICK_COUNT 0x320 - -// -// KUSER_SHARED_DATA Offsets (this stuff is trash) -// -#define KERNEL_USER_SHARED_DATA 0x7FFE0000 -#define KUSER_SHARED_PROCESSOR_FEATURES KERNEL_USER_SHARED_DATA + 0x274 -#define KUSER_SHARED_SYSCALL KERNEL_USER_SHARED_DATA + 0x300 -#define KUSER_SHARED_SYSCALL_RET KERNEL_USER_SHARED_DATA + 0x304 -#define PROCESSOR_FEATURE_FXSR KUSER_SHARED_PROCESSOR_FEATURES + 0x4 - -// -// CONTEXT Offsets -// -#define CONTEXT_FLAGS 0x0 -#define CONTEXT_DR6 0x14 -#define CONTEXT_FLOAT_SAVE 0x1C -#define CONTEXT_SEGGS 0x8C -#define CONTEXT_SEGFS 0x90 -#define CONTEXT_SEGES 0x94 -#define CONTEXT_SEGDS 0x98 -#define CONTEXT_EDI 0x9C -#define CONTEXT_ESI 0xA0 -#define CONTEXT_EBX 0xA4 -#define CONTEXT_EDX 0xA8 -#define CONTEXT_ECX 0xAC -#define CONTEXT_EAX 0xB0 -#define CONTEXT_EBP 0xB4 -#define CONTEXT_EIP 0xB8 -#define CONTEXT_SEGCS 0xBC -#define CONTEXT_EFLAGS 0xC0 -#define CONTEXT_ESP 0xC4 -#define CONTEXT_SEGSS 0xC8 -#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 - -// -// EXCEPTION_RECORD Offsets -// -#define EXCEPTION_RECORD_EXCEPTION_CODE 0x0 -#define EXCEPTION_RECORD_EXCEPTION_FLAGS 0x4 -#define EXCEPTION_RECORD_EXCEPTION_RECORD 0x8 -#define EXCEPTION_RECORD_EXCEPTION_ADDRESS 0xC -#define EXCEPTION_RECORD_NUMBER_PARAMETERS 0x10 -#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 -// -#define TEB_EXCEPTION_LIST 0x0 -#define TEB_STACK_BASE 0x4 -#define TEB_STACK_LIMIT 0x8 -#define TEB_FIBER_DATA 0x10 -#define TEB_SELF 0x18 -#define TEB_PEB 0x30 -#define TEB_EXCEPTION_CODE 0x1A4 -#define TEB_ACTIVATION_CONTEXT_STACK_POINTER 0x1A8 -#define TEB_DEALLOCATION_STACK 0xE0C -#define TEB_GDI_BATCH_COUNT 0xF70 -#define TEB_GUARANTEED_STACK_BYTES 0xF78 -#define TEB_FLS_DATA 0xFB4 - -// -// PEB Offsets -// -#define PEB_KERNEL_CALLBACK_TABLE 0x2C - -// -// FIBER Offsets -// -#define FIBER_PARAMETER 0x0 -#define FIBER_EXCEPTION_LIST 0x4 -#define FIBER_STACK_BASE 0x8 -#define FIBER_STACK_LIMIT 0xC -#define FIBER_DEALLOCATION_STACK 0x10 -#define FIBER_CONTEXT 0x14 -#define FIBER_GUARANTEED_STACK_BYTES 0x2E0 -#define FIBER_FLS_DATA 0x2E4 -#define FIBER_ACTIVATION_CONTEXT_STACK 0x2E8 -#define FIBER_CONTEXT_FLAGS FIBER_CONTEXT + CONTEXT_FLAGS -#define FIBER_CONTEXT_EAX FIBER_CONTEXT + CONTEXT_EAX -#define FIBER_CONTEXT_EBX FIBER_CONTEXT + CONTEXT_EBX -#define FIBER_CONTEXT_ECX FIBER_CONTEXT + CONTEXT_ECX -#define FIBER_CONTEXT_EDX FIBER_CONTEXT + CONTEXT_EDX -#define FIBER_CONTEXT_ESI FIBER_CONTEXT + CONTEXT_ESI -#define FIBER_CONTEXT_EDI FIBER_CONTEXT + CONTEXT_EDI -#define FIBER_CONTEXT_EBP FIBER_CONTEXT + CONTEXT_EBP -#define FIBER_CONTEXT_ESP FIBER_CONTEXT + CONTEXT_ESP -#define FIBER_CONTEXT_DR6 FIBER_CONTEXT + CONTEXT_DR6 -#define FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD FIBER_CONTEXT + CONTEXT_FLOAT_SAVE_STATUS_WORD -#define FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD FIBER_CONTEXT + CONTEXT_FLOAT_SAVE_CONTROL_WORD -#define FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD FIBER_CONTEXT + CONTEXT_FLOAT_SAVE_TAG_WORD - -// -// EFLAGS -// -#ifdef __ASM__ -#define EFLAGS_TF 0x100 -#define EFLAGS_INTERRUPT_MASK 0x200 -#define EFLAGS_IOPL 0x3000 -#define EFLAGS_NESTED_TASK 0x4000 -#define EFLAGS_V86_MASK 0x20000 -#define EFLAGS_ALIGN_CHECK 0x40000 -#define EFLAGS_VIF 0x80000 -#define EFLAGS_VIP 0x100000 -#define EFLAG_SIGN 0x8000 -#define EFLAG_ZERO 0x4000 -#define EFLAG_SELECT (EFLAG_SIGN + EFLAG_ZERO) -#endif -#define EFLAGS_USER_SANITIZE 0x3F4DD7 - -// -// CR0 -// -#define CR0_PE 0x1 -#define CR0_MP 0x2 -#define CR0_EM 0x4 -#define CR0_TS 0x8 -#define CR0_ET 0x10 -#define CR0_NE 0x20 -#define CR0_WP 0x10000 -#define CR0_AM 0x40000 -#define CR0_NW 0x20000000 -#define CR0_CD 0x40000000 -#define CR0_PG 0x80000000 - -// -// CR4 -// -#ifdef __ASM__ -#define CR4_VME 0x1 -#define CR4_PVI 0x2 -#define CR4_TSD 0x4 -#define CR4_DE 0x8 -#define CR4_PSE 0x10 -#define CR4_PAE 0x20 -#define CR4_MCE 0x40 -#define CR4_PGE 0x80 -#define CR4_FXSR 0x200 -#define CR4_XMMEXCPT 0x400 -#endif - -// -// DR6 and 7 Masks -// -#define DR6_LEGAL 0xE00F -#define DR7_LEGAL 0xFFFF0155 -#define DR7_ACTIVE 0x55 -#define DR7_OVERRIDE_V 0x04 -#define DR7_RESERVED_MASK 0xDC00 -#define DR7_OVERRIDE_MASK 0xF0000 - -// -// Usermode callout frame definitions -// -#define CBSTACK_STACK 0x0 -#define CBSTACK_TRAP_FRAME 0x4 -#define CBSTACK_CALLBACK_STACK 0x8 -#define CBSTACK_EBP 0x18 -#define CBSTACK_RESULT 0x20 -#define CBSTACK_RESULT_LENGTH 0x24 -#define CBSTACK_FRAME_POINTER CBSTACK_EBP - -// -// NTSTATUS, Bugcheck Codes and Debug Codes -// -#ifdef __ASM__ -#define STATUS_ACCESS_VIOLATION 0xC0000005 -#define STATUS_IN_PAGE_ERROR 0xC0000006 -#define STATUS_GUARD_PAGE_VIOLATION 0x80000001 -#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096 -#define STATUS_STACK_OVERFLOW 0xC00000FD -#define KI_EXCEPTION_ACCESS_VIOLATION 0x10000004 -#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C -#define STATUS_NO_CALLBACK_ACTIVE 0xC0000258 -#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 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 IRQL_NOT_GREATER_OR_EQUAL 0x09 -#define IRQL_NOT_LESS_OR_EQUAL 0x0A -#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 -#define HARDWARE_INTERRUPT_STORM 0xF2 -#define DBG_STATUS_CONTROL_C 0x01 - -// -// IRQL Levels -// -#define PASSIVE_LEVEL 0x0 -#define APC_LEVEL 0x1 -#define DISPATCH_LEVEL 0x2 -#define CLOCK2_LEVEL 0x1C -#define IPI_LEVEL 0x1D -#define HIGH_LEVEL 0x1F - -// -// Synchronization-level IRQL -// -#ifndef CONFIG_SMP -#define SYNCH_LEVEL DISPATCH_LEVEL -#else -#if (NTDDI_VERSION < NTDDI_WS03) -#define SYNCH_LEVEL (IPI_LEVEL - 0x1) -#else -#define SYNCH_LEVEL (IPI_LEVEL - 0x2) -#endif -#endif - -// -// Quantum Decrements -// -#define CLOCK_QUANTUM_DECREMENT 0x3 -#endif - -// -// System Call Table definitions -// -#define NUMBER_SERVICE_TABLES 0x0002 -#define SERVICE_NUMBER_MASK 0x0FFF -#define SERVICE_TABLE_SHIFT 0x0008 -#define SERVICE_TABLE_MASK 0x0010 -#define SERVICE_TABLE_TEST 0x0010 -#define SERVICE_DESCRIPTOR_BASE 0x0000 -#define SERVICE_DESCRIPTOR_COUNT 0x0004 -#define SERVICE_DESCRIPTOR_LIMIT 0x0008 -#define SERVICE_DESCRIPTOR_NUMBER 0x000C -#define SERVICE_DESCRIPTOR_LENGTH 0x0010 - -// -// VDM State Pointer -// -#define FIXED_NTVDMSTATE_LINEAR_PC_AT 0x714 - -// -// Machine types -// -#ifdef __ASM__ -#define MACHINE_TYPE_ISA 0x0000 -#define MACHINE_TYPE_EISA 0x0001 -#define MACHINE_TYPE_MCA 0x0002 - -// -// Kernel Feature Bits -// -#define KF_RDTSC 0x00000002 - -// -// Kernel Stack Size -// -#define KERNEL_STACK_SIZE 0x3000 -#endif - -// -// Generic Definitions -// -#define PRIMARY_VECTOR_BASE 0x30 // FIXME: HACK -#define MAXIMUM_IDTVECTOR 0xFF -#endif // !_ASM_H - - - -#endif - - diff --git a/reactos/include/ndk/i386/asm.h b/reactos/include/ndk/i386/asm.h new file mode 100644 index 00000000000..597010889f6 --- /dev/null +++ b/reactos/include/ndk/i386/asm.h @@ -0,0 +1,639 @@ +/*++ NDK Version: 0095 + +Copyright (c) Alex Ionescu. All rights reserved. + +Header Name: + + asm.h + +Abstract: + + ASM Offsets for dealing with de-referencing structures in registers. + C-compatible version of the file ks386.inc present in the newest WDK. + +Author: + + Alex Ionescu (alex.ionescu@reactos.com) 06-Oct-2004 + +--*/ + +#ifndef _ASM_X86_H +#define _ASM_X86_H + +// +// PCR Access +// +#ifdef __ASM__ +#ifdef CONFIG_SMP +#define PCR fs: +#else +#define PCR ds:[0xFFDFF000] +#endif +#endif + +// +// CPU Modes +// +#define KernelMode 0x0 +#define UserMode 0x1 + +// +// CPU Types +// +#define CPU_NONE 0x0 +#define CPU_INTEL 0x1 +#define CPU_AMD 0x2 +#define CPU_CYRIX 0x3 +#define CPU_TRANSMETA 0x4 +#define CPU_CENTAUR 0x5 +#define CPU_RISE 0x6 +#define CPU_UNKNOWN 0x7 + +// +// Selector Names +// +#ifdef __ASM__ +#define RPL_MASK 0x0003 +#define MODE_MASK 0x0001 +#define KGDT_R0_CODE (0x8) +#define KGDT_R0_DATA (0x10) +#define KGDT_R3_CODE (0x18) +#define KGDT_R3_DATA (0x20) +#define KGDT_TSS (0x28) +#define KGDT_R0_PCR (0x30) +#define KGDT_R3_TEB (0x38) +#define KGDT_LDT (0x48) +#define KGDT_DF_TSS (0x50) +#define KGDT_NMI_TSS (0x58) +#endif + +// +// KV86M_REGISTERS Offsets +// +#define KV86M_REGISTERS_EBP 0x0 +#define KV86M_REGISTERS_EDI 0x4 +#define KV86M_REGISTERS_ESI 0x8 +#define KV86M_REGISTERS_EDX 0xC +#define KV86M_REGISTERS_ECX 0x10 +#define KV86M_REGISTERS_EBX 0x14 +#define KV86M_REGISTERS_EAX 0x18 +#define KV86M_REGISTERS_DS 0x1C +#define KV86M_REGISTERS_ES 0x20 +#define KV86M_REGISTERS_FS 0x24 +#define KV86M_REGISTERS_GS 0x28 +#define KV86M_REGISTERS_EIP 0x2C +#define KV86M_REGISTERS_CS 0x30 +#define KV86M_REGISTERS_EFLAGS 0x34 +#define KV86M_REGISTERS_ESP 0x38 +#define KV86M_REGISTERS_SS 0x3C +#define TF_SAVED_EXCEPTION_STACK 0x8C +#define TF_REGS 0x90 +#define TF_ORIG_EBP 0x94 + +// +// TSS Offsets +// +#define KTSS_ESP0 0x4 +#define KTSS_CR3 0x1C +#define KTSS_EFLAGS 0x24 +#define KTSS_IOMAPBASE 0x66 +#define KTSS_IO_MAPS 0x68 + +// +// KTHREAD Offsets +// +#define KTHREAD_DEBUG_ACTIVE 0x03 +#define KTHREAD_INITIAL_STACK 0x18 +#define KTHREAD_STACK_LIMIT 0x1C +#define KTHREAD_TEB 0x74 +#define KTHREAD_KERNEL_STACK 0x20 +#define KTHREAD_ALERTED 0x5E +#define KTHREAD_APCSTATE_PROCESS 0x28 + 0x10 +#define KTHREAD_PENDING_USER_APC 0x28 + 0x16 +#define KTHREAD_PENDING_KERNEL_APC 0x28 + 0x15 +#define KTHREAD_CONTEXT_SWITCHES 0x48 +#define KTHREAD_STATE_ 0x4C +#define KTHREAD_NPX_STATE 0x4D +#define KTHREAD_WAIT_IRQL 0x4E +#define KTHREAD_NEXT_PROCESSOR 0x40 +#define KTHREAD_WAIT_REASON 0x5A +#define KTHREAD_PRIORITY 0x5B +#define KTHREAD_SWAP_BUSY 0x5D +#define KTHREAD_SERVICE_TABLE 0x118 +#define KTHREAD_PREVIOUS_MODE 0xD7 +#define KTHREAD_COMBINED_APC_DISABLE 0x70 +#define KTHREAD_SPECIAL_APC_DISABLE 0x72 +#define KTHREAD_LARGE_STACK 0x107 +#define KTHREAD_TRAP_FRAME 0x110 +#define KTHREAD_CALLBACK_STACK 0x114 +#define KTHREAD_APC_STATE_INDEX 0x11C +#define KTHREAD_STACK_BASE 0x158 +#define KTHREAD_QUANTUM 0x15D +#define KTHREAD_KERNEL_TIME 0x160 +#define KTHREAD_USER_TIME 0x18C + +// +// KPROCESS Offsets +// +#define KPROCESS_DIRECTORY_TABLE_BASE 0x18 +#define KPROCESS_LDT_DESCRIPTOR0 0x20 +#define KPROCESS_LDT_DESCRIPTOR1 0x24 +#define KPROCESS_INT21_DESCRIPTOR0 0x28 +#define KPROCESS_INT21_DESCRIPTOR1 0x2C +#define KPROCESS_IOPM_OFFSET 0x30 +#define KPROCESS_ACTIVE_PROCESSORS 0x34 +#define EPROCESS_VDM_OBJECTS 0x144 + +// +// KTIMER_TABLE Offsets +// +#ifdef __ASM__ +#define KTIMER_TABLE_ENTRY 0x00 +#define KTIMER_TABLE_TIME 0x08 +#define TIMER_ENTRY_SIZE 0x10 +#define TIMER_TABLE_SIZE 0x200 +#endif + +// +// KPRCB Offsets +// +#define KPRCB_DR0 0x2F8 +#define KPRCB_DR1 0x2FC +#define KPRCB_DR2 0x300 +#define KPRCB_DR3 0x304 +#define KPRCB_DR6 0x308 +#define KPRCB_DR7 0x30C +#define KPRCB_TIMER_HAND 0x964 +#define KPRCB_TIMER_REQUEST 0x968 + +// +// KPCR Offsets +// +#define KPCR_EXCEPTION_LIST 0x0 +#define KPCR_INITIAL_STACK 0x4 +#define KPCR_STACK_LIMIT 0x8 +#define KPCR_PERF_GLOBAL_GROUP_MASK 0x8 +#define KPCR_CONTEXT_SWITCHES 0x10 +#define KPCR_SET_MEMBER_COPY 0x14 +#define KPCR_TEB 0x18 +#define KPCR_SELF 0x1C +#define KPCR_PRCB 0x20 +#define KPCR_IRQL 0x24 +#define KPCR_IRR 0x28 +#define KPCR_IRR_ACTIVE 0x2C +#define KPCR_IDR 0x30 +#define KPCR_KD_VERSION_BLOCK 0x34 +#define KPCR_IDT 0x38 +#define KPCR_GDT 0x3C +#define KPCR_TSS 0x40 +#define KPCR_STALL_SCALE_FACTOR 0x4C +#define KPCR_SET_MEMBER 0x48 +#define KPCR_NUMBER 0x51 +#define KPCR_VDM_ALERT 0x54 +#define KPCR_PRCB_DATA 0x120 +#define KPCR_CURRENT_THREAD 0x124 +#define KPCR_PRCB_NEXT_THREAD 0x128 +#define KPCR_PRCB_IDLE_THREAD 0x12C +#define KPCR_PROCESSOR_NUMBER 0x130 +#define KPCR_PRCB_SET_MEMBER 0x134 +#define KPCR_PRCB_CPU_TYPE 0x138 +#define KPCR_PRCB_PRCB_LOCK 0xA7C +#define KPCR_NPX_THREAD 0x640 +#define KPCR_DR6 0x428 +#define KPCR_DR7 0x42C +#define KPCR_PRCB_INTERRUPT_COUNT 0x644 +#define KPCR_PRCB_KERNEL_TIME 0x648 +#define KPCR_PRCB_USER_TIME 0x64C +#define KPCR_PRCB_DPC_TIME 0x650 +#define KPCR_PRCB_DEBUG_DPC_TIME 0x654 +#define KPCR_PRCB_INTERRUPT_TIME 0x658 +#define KPCR_PRCB_ADJUST_DPC_THRESHOLD 0x65C +#define KPCR_PRCB_SKIP_TICK 0x664 +#define KPCR_SYSTEM_CALLS 0x6B8 +#define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C +#define KPCR_PRCB_DPC_COUNT 0xA50 +#define KPCR_PRCB_DPC_STACK 0xA68 +#define KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH 0xA6C +#define KPCR_PRCB_DPC_REQUEST_RATE 0xA70 +#define KPCR_PRCB_DPC_INTERRUPT_REQUESTED 0xA78 +#define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0xA7A +#define KPCR_PRCB_DPC_LAST_COUNT 0xA80 +#define KPCR_PRCB_TIMER_REQUEST 0xA88 +#define KPCR_PRCB_QUANTUM_END 0xAA1 +#define KPCR_PRCB_IDLE_SCHEDULE 0xAA3 +#define KPCR_PRCB_DEFERRED_READY_LIST_HEAD 0xC10 +#define KPCR_PRCB_POWER_STATE_IDLE_FUNCTION 0xEC0 + +// +// KINTERRUPT Offsets +// +#define KINTERRUPT_INTERRUPT_LIST_HEAD 0x04 +#define KINTERRUPT_SERVICE_ROUTINE 0x0C +#define KINTERRUPT_SERVICE_CONTEXT 0x10 +#define KINTERRUPT_TICK_COUNT 0x18 +#define KINTERRUPT_ACTUAL_LOCK 0x1C +#define KINTERRUPT_VECTOR 0x24 +#define KINTERRUPT_IRQL 0x28 +#define KINTERRUPT_SYNCHRONIZE_IRQL 0x29 +#define KINTERRUPT_DISPATCH_COUNT 0x38 + +// +// KGDTENTRY Offsets +// +#define KGDT_BASE_LOW 0x2 +#define KGDT_BASE_MID 0x4 +#define KGDT_BASE_HI 0x7 +#define KGDT_LIMIT_HI 0x6 +#define KGDT_LIMIT_LOW 0x0 + +// +// FPU Save Area Offsets +// +#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 +#define FX_MXCSR 0x18 + +// +// NPX States +// +#define NPX_STATE_NOT_LOADED 0xA +#define NPX_STATE_LOADED 0x0 + +// +// Trap Frame Offsets +// +#define KTRAP_FRAME_DEBUGEBP 0x0 +#define KTRAP_FRAME_DEBUGEIP 0x4 +#define KTRAP_FRAME_DEBUGARGMARK 0x8 +#define KTRAP_FRAME_DEBUGPOINTER 0xC +#define KTRAP_FRAME_TEMPCS 0x10 +#define KTRAP_FRAME_TEMPESP 0x14 +#define KTRAP_FRAME_DR0 0x18 +#define KTRAP_FRAME_DR1 0x1C +#define KTRAP_FRAME_DR2 0x20 +#define KTRAP_FRAME_DR3 0x24 +#define KTRAP_FRAME_DR6 0x28 +#define KTRAP_FRAME_DR7 0x2C +#define KTRAP_FRAME_GS 0x30 +#define KTRAP_FRAME_RESERVED1 0x32 +#define KTRAP_FRAME_ES 0x34 +#define KTRAP_FRAME_RESERVED2 0x36 +#define KTRAP_FRAME_DS 0x38 +#define KTRAP_FRAME_RESERVED3 0x3A +#define KTRAP_FRAME_EDX 0x3C +#define KTRAP_FRAME_ECX 0x40 +#define KTRAP_FRAME_EAX 0x44 +#define KTRAP_FRAME_PREVIOUS_MODE 0x48 +#define KTRAP_FRAME_EXCEPTION_LIST 0x4C +#define KTRAP_FRAME_FS 0x50 +#define KTRAP_FRAME_RESERVED4 0x52 +#define KTRAP_FRAME_EDI 0x54 +#define KTRAP_FRAME_ESI 0x58 +#define KTRAP_FRAME_EBX 0x5C +#define KTRAP_FRAME_EBP 0x60 +#define KTRAP_FRAME_ERROR_CODE 0x64 +#define KTRAP_FRAME_EIP 0x68 +#define KTRAP_FRAME_CS 0x6C +#define KTRAP_FRAME_EFLAGS 0x70 +#define KTRAP_FRAME_ESP 0x74 +#define KTRAP_FRAME_SS 0x78 +#define KTRAP_FRAME_RESERVED5 0x7A +#define KTRAP_FRAME_V86_ES 0x7C +#define KTRAP_FRAME_RESERVED6 0x7E +#define KTRAP_FRAME_V86_DS 0x80 +#define KTRAP_FRAME_RESERVED7 0x82 +#define KTRAP_FRAME_V86_FS 0x84 +#define KTRAP_FRAME_RESERVED8 0x86 +#define KTRAP_FRAME_V86_GS 0x88 +#define KTRAP_FRAME_RESERVED9 0x8A +#define KTRAP_FRAME_SIZE 0x8C +#define KTRAP_FRAME_LENGTH 0x8C +#define KTRAP_FRAME_ALIGN 0x04 +#define FRAME_EDITED 0xFFF8 + +// +// KUSER_SHARED_DATA Offsets +// +#ifdef __ASM__ +#define USER_SHARED_DATA 0xFFDF0000 +#endif +#define USER_SHARED_DATA_INTERRUPT_TIME 0x8 +#define USER_SHARED_DATA_SYSTEM_TIME 0x14 +#define USER_SHARED_DATA_TICK_COUNT 0x320 + +// +// KUSER_SHARED_DATA Offsets (this stuff is trash) +// +#define KERNEL_USER_SHARED_DATA 0x7FFE0000 +#define KUSER_SHARED_PROCESSOR_FEATURES KERNEL_USER_SHARED_DATA + 0x274 +#define KUSER_SHARED_SYSCALL KERNEL_USER_SHARED_DATA + 0x300 +#define KUSER_SHARED_SYSCALL_RET KERNEL_USER_SHARED_DATA + 0x304 +#define PROCESSOR_FEATURE_FXSR KUSER_SHARED_PROCESSOR_FEATURES + 0x4 + +// +// CONTEXT Offsets +// +#define CONTEXT_FLAGS 0x0 +#define CONTEXT_DR6 0x14 +#define CONTEXT_FLOAT_SAVE 0x1C +#define CONTEXT_SEGGS 0x8C +#define CONTEXT_SEGFS 0x90 +#define CONTEXT_SEGES 0x94 +#define CONTEXT_SEGDS 0x98 +#define CONTEXT_EDI 0x9C +#define CONTEXT_ESI 0xA0 +#define CONTEXT_EBX 0xA4 +#define CONTEXT_EDX 0xA8 +#define CONTEXT_ECX 0xAC +#define CONTEXT_EAX 0xB0 +#define CONTEXT_EBP 0xB4 +#define CONTEXT_EIP 0xB8 +#define CONTEXT_SEGCS 0xBC +#define CONTEXT_EFLAGS 0xC0 +#define CONTEXT_ESP 0xC4 +#define CONTEXT_SEGSS 0xC8 +#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 + +// +// EXCEPTION_RECORD Offsets +// +#define EXCEPTION_RECORD_EXCEPTION_CODE 0x0 +#define EXCEPTION_RECORD_EXCEPTION_FLAGS 0x4 +#define EXCEPTION_RECORD_EXCEPTION_RECORD 0x8 +#define EXCEPTION_RECORD_EXCEPTION_ADDRESS 0xC +#define EXCEPTION_RECORD_NUMBER_PARAMETERS 0x10 +#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 +// +#define TEB_EXCEPTION_LIST 0x0 +#define TEB_STACK_BASE 0x4 +#define TEB_STACK_LIMIT 0x8 +#define TEB_FIBER_DATA 0x10 +#define TEB_SELF 0x18 +#define TEB_PEB 0x30 +#define TEB_EXCEPTION_CODE 0x1A4 +#define TEB_ACTIVATION_CONTEXT_STACK_POINTER 0x1A8 +#define TEB_DEALLOCATION_STACK 0xE0C +#define TEB_GDI_BATCH_COUNT 0xF70 +#define TEB_GUARANTEED_STACK_BYTES 0xF78 +#define TEB_FLS_DATA 0xFB4 + +// +// PEB Offsets +// +#define PEB_KERNEL_CALLBACK_TABLE 0x2C + +// +// FIBER Offsets +// +#define FIBER_PARAMETER 0x0 +#define FIBER_EXCEPTION_LIST 0x4 +#define FIBER_STACK_BASE 0x8 +#define FIBER_STACK_LIMIT 0xC +#define FIBER_DEALLOCATION_STACK 0x10 +#define FIBER_CONTEXT 0x14 +#define FIBER_GUARANTEED_STACK_BYTES 0x2E0 +#define FIBER_FLS_DATA 0x2E4 +#define FIBER_ACTIVATION_CONTEXT_STACK 0x2E8 +#define FIBER_CONTEXT_FLAGS FIBER_CONTEXT + CONTEXT_FLAGS +#define FIBER_CONTEXT_EAX FIBER_CONTEXT + CONTEXT_EAX +#define FIBER_CONTEXT_EBX FIBER_CONTEXT + CONTEXT_EBX +#define FIBER_CONTEXT_ECX FIBER_CONTEXT + CONTEXT_ECX +#define FIBER_CONTEXT_EDX FIBER_CONTEXT + CONTEXT_EDX +#define FIBER_CONTEXT_ESI FIBER_CONTEXT + CONTEXT_ESI +#define FIBER_CONTEXT_EDI FIBER_CONTEXT + CONTEXT_EDI +#define FIBER_CONTEXT_EBP FIBER_CONTEXT + CONTEXT_EBP +#define FIBER_CONTEXT_ESP FIBER_CONTEXT + CONTEXT_ESP +#define FIBER_CONTEXT_DR6 FIBER_CONTEXT + CONTEXT_DR6 +#define FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD FIBER_CONTEXT + CONTEXT_FLOAT_SAVE_STATUS_WORD +#define FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD FIBER_CONTEXT + CONTEXT_FLOAT_SAVE_CONTROL_WORD +#define FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD FIBER_CONTEXT + CONTEXT_FLOAT_SAVE_TAG_WORD + +// +// EFLAGS +// +#ifdef __ASM__ +#define EFLAGS_TF 0x100 +#define EFLAGS_INTERRUPT_MASK 0x200 +#define EFLAGS_IOPL 0x3000 +#define EFLAGS_NESTED_TASK 0x4000 +#define EFLAGS_V86_MASK 0x20000 +#define EFLAGS_ALIGN_CHECK 0x40000 +#define EFLAGS_VIF 0x80000 +#define EFLAGS_VIP 0x100000 +#define EFLAG_SIGN 0x8000 +#define EFLAG_ZERO 0x4000 +#define EFLAG_SELECT (EFLAG_SIGN + EFLAG_ZERO) +#endif +#define EFLAGS_USER_SANITIZE 0x3F4DD7 + +// +// CR0 +// +#define CR0_PE 0x1 +#define CR0_MP 0x2 +#define CR0_EM 0x4 +#define CR0_TS 0x8 +#define CR0_ET 0x10 +#define CR0_NE 0x20 +#define CR0_WP 0x10000 +#define CR0_AM 0x40000 +#define CR0_NW 0x20000000 +#define CR0_CD 0x40000000 +#define CR0_PG 0x80000000 + +// +// CR4 +// +#ifdef __ASM__ +#define CR4_VME 0x1 +#define CR4_PVI 0x2 +#define CR4_TSD 0x4 +#define CR4_DE 0x8 +#define CR4_PSE 0x10 +#define CR4_PAE 0x20 +#define CR4_MCE 0x40 +#define CR4_PGE 0x80 +#define CR4_FXSR 0x200 +#define CR4_XMMEXCPT 0x400 +#endif + +// +// DR6 and 7 Masks +// +#define DR6_LEGAL 0xE00F +#define DR7_LEGAL 0xFFFF0155 +#define DR7_ACTIVE 0x55 +#define DR7_OVERRIDE_V 0x04 +#define DR7_RESERVED_MASK 0xDC00 +#define DR7_OVERRIDE_MASK 0xF0000 + +// +// Usermode callout frame definitions +// +#define CBSTACK_STACK 0x0 +#define CBSTACK_TRAP_FRAME 0x4 +#define CBSTACK_CALLBACK_STACK 0x8 +#define CBSTACK_EBP 0x18 +#define CBSTACK_RESULT 0x20 +#define CBSTACK_RESULT_LENGTH 0x24 +#define CBSTACK_FRAME_POINTER CBSTACK_EBP + +// +// NTSTATUS, Bugcheck Codes and Debug Codes +// +#ifdef __ASM__ +#define STATUS_SUCCESS 0x00000000 +#define STATUS_ACCESS_VIOLATION 0xC0000005 +#define STATUS_IN_PAGE_ERROR 0xC0000006 +#define STATUS_GUARD_PAGE_VIOLATION 0x80000001 +#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096 +#define STATUS_STACK_OVERFLOW 0xC00000FD +#define KI_EXCEPTION_ACCESS_VIOLATION 0x10000004 +#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C +#define STATUS_NO_CALLBACK_ACTIVE 0xC0000258 +#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 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 IRQL_NOT_GREATER_OR_EQUAL 0x09 +#define IRQL_NOT_LESS_OR_EQUAL 0x0A +#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 +#define HARDWARE_INTERRUPT_STORM 0xF2 +#define DBG_STATUS_CONTROL_C 0x01 + +// +// IRQL Levels +// +#define PASSIVE_LEVEL 0x0 +#define APC_LEVEL 0x1 +#define DISPATCH_LEVEL 0x2 +#define CLOCK2_LEVEL 0x1C +#define IPI_LEVEL 0x1D +#define HIGH_LEVEL 0x1F + +// +// Synchronization-level IRQL +// +#ifndef CONFIG_SMP +#define SYNCH_LEVEL DISPATCH_LEVEL +#else +#if (NTDDI_VERSION < NTDDI_WS03) +#define SYNCH_LEVEL (IPI_LEVEL - 0x1) +#else +#define SYNCH_LEVEL (IPI_LEVEL - 0x2) +#endif +#endif + +// +// Quantum Decrements +// +#define CLOCK_QUANTUM_DECREMENT 0x3 +#endif + +// +// System Call Table definitions +// +#define NUMBER_SERVICE_TABLES 0x0002 +#define SERVICE_NUMBER_MASK 0x0FFF +#define SERVICE_TABLE_SHIFT 0x0008 +#define SERVICE_TABLE_MASK 0x0010 +#define SERVICE_TABLE_TEST 0x0010 +#define SERVICE_DESCRIPTOR_BASE 0x0000 +#define SERVICE_DESCRIPTOR_COUNT 0x0004 +#define SERVICE_DESCRIPTOR_LIMIT 0x0008 +#define SERVICE_DESCRIPTOR_NUMBER 0x000C +#define SERVICE_DESCRIPTOR_LENGTH 0x0010 + +// +// VDM State Pointer +// +#define FIXED_NTVDMSTATE_LINEAR_PC_AT 0x714 + +// +// Machine types +// +#ifdef __ASM__ +#define MACHINE_TYPE_ISA 0x0000 +#define MACHINE_TYPE_EISA 0x0001 +#define MACHINE_TYPE_MCA 0x0002 + +// +// Kernel Feature Bits +// +#define KF_RDTSC 0x00000002 + +// +// Kernel Stack Size +// +#define KERNEL_STACK_SIZE 0x3000 +#endif + +// +// Generic Definitions +// +#define PRIMARY_VECTOR_BASE 0x30 // FIXME: HACK +#define MAXIMUM_IDTVECTOR 0xFF +#endif // !_ASM_X86_H diff --git a/reactos/include/ndk/lpctypes.h b/reactos/include/ndk/lpctypes.h index a917631dab7..44419618d5d 100644 --- a/reactos/include/ndk/lpctypes.h +++ b/reactos/include/ndk/lpctypes.h @@ -31,17 +31,6 @@ Author: #define N_ROUND_UP(x,s) \ (((ULONG)(x)+(s)-1) & ~((ULONG)(s)-1)) -// -// Maximum message size that can be sent through an LPC Port without a section -// -#ifdef NTOS_MODE_USER -#ifdef _WIN64 -#define PORT_MAXIMUM_MESSAGE_LENGTH 512 -#else -#define PORT_MAXIMUM_MESSAGE_LENGTH 256 -#endif -#endif - // // Port Object Access Masks // @@ -91,6 +80,15 @@ typedef enum _PORT_INFORMATION_CLASS #ifdef NTOS_MODE_USER +// +// Maximum message size that can be sent through an LPC Port without a section +// +#ifdef _WIN64 +#define PORT_MAXIMUM_MESSAGE_LENGTH 512 +#else +#define PORT_MAXIMUM_MESSAGE_LENGTH 256 +#endif + // // Portable LPC Types for 32/64-bit compatibility // diff --git a/reactos/include/ndk/mmfuncs.h b/reactos/include/ndk/mmfuncs.h index a1c7e8b3383..30347061554 100644 --- a/reactos/include/ndk/mmfuncs.h +++ b/reactos/include/ndk/mmfuncs.h @@ -173,10 +173,10 @@ NTSYSCALLAPI NTSTATUS NTAPI NtLockVirtualMemory( - HANDLE ProcessHandle, - PVOID BaseAddress, - SIZE_T NumberOfBytesToLock, - PSIZE_T NumberOfBytesLocked + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T NumberOfBytesToLock, + IN ULONG MapType ); NTSTATUS @@ -278,9 +278,9 @@ NTSTATUS NTAPI NtUnlockVirtualMemory( IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytesToUnlock, - OUT PSIZE_T NumberOfBytesUnlocked OPTIONAL + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T NumberOfBytesToUnlock, + IN ULONG MapType ); NTSYSCALLAPI @@ -367,10 +367,10 @@ NTSYSAPI NTSTATUS NTAPI ZwLockVirtualMemory( - HANDLE ProcessHandle, - PVOID BaseAddress, - SIZE_T NumberOfBytesToLock, - PSIZE_T NumberOfBytesLocked + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T NumberOfBytesToLock, + IN ULONG MapType ); NTSYSAPI @@ -448,9 +448,9 @@ NTSTATUS NTAPI ZwUnlockVirtualMemory( IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytesToUnlock, - OUT PSIZE_T NumberOfBytesUnlocked OPTIONAL + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T NumberOfBytesToUnlock, + IN ULONG MapType ); NTSYSAPI diff --git a/reactos/include/ndk/mmtypes.h b/reactos/include/ndk/mmtypes.h index e4dec2fb57f..bb0d6af146a 100644 --- a/reactos/include/ndk/mmtypes.h +++ b/reactos/include/ndk/mmtypes.h @@ -57,6 +57,12 @@ Author: #define MMPFNUSE_DRIVERLOCKPAGE 10 #define MMPFNUSE_KERNELSTACK 11 +// +// Lock/Unlock Virtuam Memory Flags +// +#define MAP_PROCESS 1 +#define MAP_SYSTEM 2 + #ifndef NTOS_MODE_USER // diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index 3bd6f2c41bb..77d7bf3def9 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -586,29 +586,63 @@ typedef struct _PEB_FREE_BLOCK ULONG Size; } PEB_FREE_BLOCK, *PPEB_FREE_BLOCK; +// +// Initial PEB +// +typedef struct _INITIAL_PEB +{ + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; + union + { + BOOLEAN BitField; +#if (NTDDI_VERSION >= NTDDI_WS03) + struct + { + BOOLEAN ImageUsesLargePages:1; +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + BOOLEAN IsProtectedProcess:1; + BOOLEAN IsLegacyProcess:1; + BOOLEAN SpareBits:5; +#else + BOOLEAN SpareBits:7; +#endif + }; +#else + BOOLEAN SpareBool; +#endif + }; + HANDLE Mutant; +} INITIAL_PEB, *PINITIAL_PEB; + // // Process Environment Block (PEB) // typedef struct _PEB { - UCHAR InheritedAddressSpace; - UCHAR ReadImageFileExecOptions; - UCHAR BeingDebugged; + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; #if (NTDDI_VERSION >= NTDDI_WS03) union { - UCHAR BitField; + BOOLEAN ImageUsesLargePages:1; + BOOLEAN BitField; struct { UCHAR ImageUsesLargePages:1; #if (NTDDI_VERSION >= NTDDI_LONGHORN) - UCHAR IsProtectedProcess:1; - UCHAR IsLegacyProcess:1; - UCHAR IsImageDynamicallyRelocated:1; - UCHAR SkipPatchingUser32Forwarders:1; - UCHAR SpareBits:3; + BOOLEAN IsProtectedProcess:1; + BOOLEAN IsLegacyProcess:1; + BOOLEAN SpareBits:5; + BOOLEAN IsProtectedProcess:1; + BOOLEAN IsLegacyProcess:1; + BOOLEAN IsImageDynamicallyRelocated:1; + BOOLEAN SkipPatchingUser32Forwarders:1; + BOOLEAN SpareBits:3; #else - UCHAR SpareBits:7; + BOOLEAN SpareBits:7; #endif }; }; diff --git a/reactos/include/psdk/ks.h b/reactos/include/psdk/ks.h index 5570bfdd366..158c6602fdd 100644 --- a/reactos/include/psdk/ks.h +++ b/reactos/include/psdk/ks.h @@ -390,6 +390,15 @@ typedef enum (SetHandler),\ NULL, 0, NULL, NULL, 0) +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_PRIORITY(GetHandler, SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CONNECTION_PRIORITY,\ + (GetHandler),\ + sizeof(KSPROPERTY),\ + sizeof(KSPRIORITY),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + #define DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(GetHandler, SetHandler)\ DEFINE_KSPROPERTY_ITEM(\ KSPROPERTY_CONNECTION_DATAFORMAT,\ @@ -399,6 +408,48 @@ typedef enum (SetHandler),\ NULL, 0, NULL, NULL, 0) +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CONNECTION_ALLOCATORFRAMING,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KSALLOCATOR_FRAMING),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING_EX(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX,\ + (Handler),\ + sizeof(KSPROPERTY),\ + 0,\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_PROPOSEDATAFORMAT(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT,\ + NULL,\ + sizeof(KSPROPERTY),\ + sizeof(KSDATAFORMAT),\ + (Handler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ACQUIREORDERING(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CONNECTION_ACQUIREORDERING,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(int),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_STARTAT(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CONNECTION_STARTAT,\ + NULL,\ + sizeof(KSPROPERTY),\ + sizeof(KSRELATIVEEVENT),\ + (Handler),\ + NULL, 0, NULL, NULL, 0) + #define KSEVENTSETID_Connection \ 0x7f4bcbe0L, 0x9ea5, 0x11cf, 0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00 diff --git a/reactos/include/psdk/msi.h b/reactos/include/psdk/msi.h index 5e68fdc278c..2c0a37fe43b 100644 --- a/reactos/include/psdk/msi.h +++ b/reactos/include/psdk/msi.h @@ -237,6 +237,8 @@ typedef struct tagMSIPATCHSEQUENCEINFOW #define MAX_FEATURE_CHARS 38 +#define ERROR_PATCH_TARGET_NOT_FOUND 1642 + /* Strings defined in msi.h */ /* Advertised Information */ diff --git a/reactos/include/psdk/windns.h b/reactos/include/psdk/windns.h index c037b679f6a..3e3714f1bd3 100644 --- a/reactos/include/psdk/windns.h +++ b/reactos/include/psdk/windns.h @@ -171,6 +171,10 @@ typedef struct _DnsRecordFlags { DWORD Unused :3; DWORD Reserved :24; } DNS_RECORD_FLAGS; +#define DNSREC_QUESTION 0 +#define DNSREC_ANSWER 1 +#define DNSREC_AUTHORITY 2 +#define DNSREC_ADDITIONAL 3 typedef struct { IP4_ADDRESS IpAddress; } DNS_A_DATA, *PDNS_A_DATA; diff --git a/reactos/include/psdk/wingdi.h b/reactos/include/psdk/wingdi.h index c304a5cb5da..b604a50295b 100644 --- a/reactos/include/psdk/wingdi.h +++ b/reactos/include/psdk/wingdi.h @@ -822,6 +822,8 @@ extern "C" { #define MM_TEXT 1 #define MM_TWIPS 6 #define MM_MAX_FIXEDSCALE MM_TWIPS +#define MM_MIN MM_TEXT +#define MM_MAX MM_ANISOTROPIC #define ABSOLUTE 1 #define RELATIVE 2 #define PC_EXPLICIT 2 diff --git a/reactos/include/psdk/winnt.h b/reactos/include/psdk/winnt.h index c9b7f61d23f..b1b61a8a66a 100644 --- a/reactos/include/psdk/winnt.h +++ b/reactos/include/psdk/winnt.h @@ -58,8 +58,9 @@ extern "C" { #include /* FIXME: add more architectures. Is there a way to specify this in GCC? */ -#ifdef _X86_ -#define UNALIGNED +#if defined(_M_AMD64) +#undef UNALIGNED +#define UNALIGNED __unaligned #else #undef UNALIGNED #define UNALIGNED @@ -108,7 +109,7 @@ extern "C" { #endif typedef char CHAR; typedef short SHORT; -#ifndef __ROS_LONG64__ +#if !defined(__ROS_LONG64__) || defined(_M_AMD64) typedef long LONG; #else typedef int LONG; diff --git a/reactos/include/psdk/ws2atm.h b/reactos/include/psdk/ws2atm.h new file mode 100644 index 00000000000..1049683ba9d --- /dev/null +++ b/reactos/include/psdk/ws2atm.h @@ -0,0 +1,333 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WS2ATM_H_ +#define _WS2ATM_H_ + +#include + +#define ATMPROTO_AALUSER 0x00 +#define ATMPROTO_AAL1 0x01 +#define ATMPROTO_AAL2 0x02 +#define ATMPROTO_AAL34 0x03 +#define ATMPROTO_AAL5 0x05 + +#define SAP_FIELD_ABSENT 0xFFFFFFFE +#define SAP_FIELD_ANY 0xFFFFFFFF +#define SAP_FIELD_ANY_AESA_SEL 0xFFFFFFFA +#define SAP_FIELD_ANY_AESA_REST 0xFFFFFFFB + +#define ATM_E164 0x01 +#define ATM_NSAP 0x02 +#define ATM_AESA 0x02 + +#define ATM_ADDR_SIZE 20 +typedef struct { + DWORD AddressType; + DWORD NumofDigits; + UCHAR Addr[ATM_ADDR_SIZE]; +} ATM_ADDRESS; + +#define BLLI_L2_ISO_1745 0x01 +#define BLLI_L2_Q921 0x02 +#define BLLI_L2_X25L 0x06 +#define BLLI_L2_X25M 0x07 +#define BLLI_L2_ELAPB 0x08 +#define BLLI_L2_HDLC_ARM 0x09 +#define BLLI_L2_HDLC_NRM 0x0A +#define BLLI_L2_HDLC_ABM 0x0B +#define BLLI_L2_LLC 0x0C +#define BLLI_L2_X75 0x0D +#define BLLI_L2_Q922 0x0E +#define BLLI_L2_USER_SPECIFIED 0x10 +#define BLLI_L2_ISO_7776 0x11 + +#define BLLI_L3_X25 0x06 +#define BLLI_L3_ISO_8208 0x07 +#define BLLI_L3_X223 0x08 +#define BLLI_L3_SIO_8473 0x09 +#define BLLI_L3_T70 0x0A +#define BLLI_L3_ISO_TR9577 0x0B +#define BLLI_L3_USER_SPECIFIED 0x10 + +#define BLLI_L3_IPI_SNAP 0x80 +#define BLLI_L3_IPI_IP 0xCC + +typedef struct { + DWORD Layer2Protocol; + DWORD Layer2UserSpecifiedProtocol; + DWORD Layer3Protocol; + DWORD Layer3UserSpecifiedProtocol; + DWORD Layer3IPI; + UCHAR SnapID[5]; +} ATM_BLLI; + +#define BHLI_ISO 0x00 +#define BHLI_UserSpecific 0x01 +#define BHLI_HighLayerProfile 0x02 +#define BHLI_VendorSpecificAppId 0x03 + +typedef struct { + DWORD HighLayerInfoType; + DWORD HighLayerInfoLength; + UCHAR HighLayerInfo[8]; +} ATM_BHLI; + +typedef struct sockaddr_atm { + u_short satm_family; + ATM_ADDRESS satm_number; + ATM_BLLI satm_blli; + ATM_BHLI satm_bhli; +} sockaddr_atm,SOCKADDR_ATM,*PSOCKADDR_ATM,*LPSOCKADDR_ATM; + +typedef enum { + IE_AALParameters,IE_TrafficDescriptor,IE_BroadbandBearerCapability,IE_BHLI,IE_BLLI,IE_CalledPartyNumber,IE_CalledPartySubaddress, + IE_CallingPartyNumber,IE_CallingPartySubaddress,IE_Cause,IE_QOSClass,IE_TransitNetworkSelection +} Q2931_IE_TYPE; + +typedef struct { + Q2931_IE_TYPE IEType; + ULONG IELength; + UCHAR IE[1]; +} Q2931_IE; + +typedef enum { + AALTYPE_5 = 5,AALTYPE_USER = 16 +} AAL_TYPE; + +#define AAL5_MODE_MESSAGE 0x01 +#define AAL5_MODE_STREAMING 0x02 + +#define AAL5_SSCS_NULL 0x00 +#define AAL5_SSCS_SSCOP_ASSURED 0x01 +#define AAL5_SSCS_SSCOP_NON_ASSURED 0x02 +#define AAL5_SSCS_FRAME_RELAY 0x04 + +typedef struct { + ULONG ForwardMaxCPCSSDUSize; + ULONG BackwardMaxCPCSSDUSize; + UCHAR Mode; + UCHAR SSCSType; +} AAL5_PARAMETERS; + +typedef struct { + ULONG UserDefined; +} AALUSER_PARAMETERS; + +typedef struct { + AAL_TYPE AALType; + union { + AAL5_PARAMETERS AAL5Parameters; + AALUSER_PARAMETERS AALUserParameters; + } AALSpecificParameters; +} AAL_PARAMETERS_IE; + +typedef struct { + ULONG PeakCellRate_CLP0; + ULONG PeakCellRate_CLP01; + ULONG SustainableCellRate_CLP0; + ULONG SustainableCellRate_CLP01; + ULONG MaxBurstSize_CLP0; + ULONG MaxBurstSize_CLP01; + WINBOOL Tagging; +} ATM_TD; + +typedef struct { + ATM_TD Forward; + ATM_TD Backward; + WINBOOL BestEffort; +} ATM_TRAFFIC_DESCRIPTOR_IE; + +#define BCOB_A 0x01 +#define BCOB_C 0x03 +#define BCOB_X 0x10 + +#define TT_NOIND 0x00 +#define TT_CBR 0x04 +#define TT_VBR 0x08 + +#define TR_NOIND 0x00 +#define TR_END_TO_END 0x01 +#define TR_NO_END_TO_END 0x02 + +#define CLIP_NOT 0x00 +#define CLIP_SUS 0x20 + +#define UP_P2P 0x00 +#define UP_P2MP 0x01 + +typedef struct { + UCHAR BearerClass; + UCHAR TrafficType; + UCHAR TimingRequirements; + UCHAR ClippingSusceptability; + UCHAR UserPlaneConnectionConfig; +} ATM_BROADBAND_BEARER_CAPABILITY_IE; + +typedef ATM_BHLI ATM_BHLI_IE; + +#define BLLI_L2_MODE_NORMAL 0x40 +#define BLLI_L2_MODE_EXT 0x80 + +#define BLLI_L3_MODE_NORMAL 0x40 +#define BLLI_L3_MODE_EXT 0x80 + +#define BLLI_L3_PACKET_16 0x04 +#define BLLI_L3_PACKET_32 0x05 +#define BLLI_L3_PACKET_64 0x06 +#define BLLI_L3_PACKET_128 0x07 +#define BLLI_L3_PACKET_256 0x08 +#define BLLI_L3_PACKET_512 0x09 +#define BLLI_L3_PACKET_1024 0x0A +#define BLLI_L3_PACKET_2048 0x0B +#define BLLI_L3_PACKET_4096 0x0C + +typedef struct { + DWORD Layer2Protocol; + UCHAR Layer2Mode; + UCHAR Layer2WindowSize; + DWORD Layer2UserSpecifiedProtocol; + DWORD Layer3Protocol; + UCHAR Layer3Mode; + UCHAR Layer3DefaultPacketSize; + UCHAR Layer3PacketWindowSize; + DWORD Layer3UserSpecifiedProtocol; + DWORD Layer3IPI; + UCHAR SnapID[5]; +} ATM_BLLI_IE; + +typedef ATM_ADDRESS ATM_CALLED_PARTY_NUMBER_IE; +typedef ATM_ADDRESS ATM_CALLED_PARTY_SUBADDRESS_IE; + +#define PI_ALLOWED 0x00 +#define PI_RESTRICTED 0x40 +#define PI_NUMBER_NOT_AVAILABLE 0x80 + +#define SI_USER_NOT_SCREENED 0x00 +#define SI_USER_PASSED 0x01 +#define SI_USER_FAILED 0x02 +#define SI_NETWORK 0x03 + +typedef struct { + ATM_ADDRESS ATM_Number; + UCHAR Presentation_Indication; + UCHAR Screening_Indicator; +} ATM_CALLING_PARTY_NUMBER_IE; + +typedef ATM_ADDRESS ATM_CALLING_PARTY_SUBADDRESS_IE; + +#define CAUSE_LOC_USER 0x00 +#define CAUSE_LOC_PRIVATE_LOCAL 0x01 +#define CAUSE_LOC_PUBLIC_LOCAL 0x02 +#define CAUSE_LOC_TRANSIT_NETWORK 0x03 +#define CAUSE_LOC_PUBLIC_REMOTE 0x04 +#define CAUSE_LOC_PRIVATE_REMOTE 0x05 +#define CAUSE_LOC_INTERNATIONAL_NETWORK 0x07 +#define CAUSE_LOC_BEYOND_INTERWORKING 0x0A + +#define CAUSE_UNALLOCATED_NUMBER 0x01 +#define CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK 0x02 +#define CAUSE_NO_ROUTE_TO_DESTINATION 0x03 +#define CAUSE_VPI_VCI_UNACCEPTABLE 0x0A +#define CAUSE_NORMAL_CALL_CLEARING 0x10 +#define CAUSE_USER_BUSY 0x11 +#define CAUSE_NO_USER_RESPONDING 0x12 +#define CAUSE_CALL_REJECTED 0x15 +#define CAUSE_NUMBER_CHANGED 0x16 +#define CAUSE_USER_REJECTS_CLIR 0x17 +#define CAUSE_DESTINATION_OUT_OF_ORDER 0x1B +#define CAUSE_INVALID_NUMBER_FORMAT 0x1C +#define CAUSE_STATUS_ENQUIRY_RESPONSE 0x1E +#define CAUSE_NORMAL_UNSPECIFIED 0x1F +#define CAUSE_VPI_VCI_UNAVAILABLE 0x23 +#define CAUSE_NETWORK_OUT_OF_ORDER 0x26 +#define CAUSE_TEMPORARY_FAILURE 0x29 +#define CAUSE_ACCESS_INFORMAION_DISCARDED 0x2B +#define CAUSE_NO_VPI_VCI_AVAILABLE 0x2D +#define CAUSE_RESOURCE_UNAVAILABLE 0x2F +#define CAUSE_QOS_UNAVAILABLE 0x31 +#define CAUSE_USER_CELL_RATE_UNAVAILABLE 0x33 +#define CAUSE_BEARER_CAPABILITY_UNAUTHORIZED 0x39 +#define CAUSE_BEARER_CAPABILITY_UNAVAILABLE 0x3A +#define CAUSE_OPTION_UNAVAILABLE 0x3F +#define CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED 0x41 +#define CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS 0x49 +#define CAUSE_INVALID_CALL_REFERENCE 0x51 +#define CAUSE_CHANNEL_NONEXISTENT 0x52 +#define CAUSE_INCOMPATIBLE_DESTINATION 0x58 +#define CAUSE_INVALID_ENDPOINT_REFERENCE 0x59 +#define CAUSE_INVALID_TRANSIT_NETWORK_SELECTION 0x5B +#define CAUSE_TOO_MANY_PENDING_ADD_PARTY 0x5C +#define CAUSE_AAL_PARAMETERS_UNSUPPORTED 0x5D +#define CAUSE_MANDATORY_IE_MISSING 0x60 +#define CAUSE_UNIMPLEMENTED_MESSAGE_TYPE 0x61 +#define CAUSE_UNIMPLEMENTED_IE 0x63 +#define CAUSE_INVALID_IE_CONTENTS 0x64 +#define CAUSE_INVALID_STATE_FOR_MESSAGE 0x65 +#define CAUSE_RECOVERY_ON_TIMEOUT 0x66 +#define CAUSE_INCORRECT_MESSAGE_LENGTH 0x68 +#define CAUSE_PROTOCOL_ERROR 0x6F + +#define CAUSE_COND_UNKNOWN 0x00 +#define CAUSE_COND_PERMANENT 0x01 +#define CAUSE_COND_TRANSIENT 0x02 + +#define CAUSE_REASON_USER 0x00 +#define CAUSE_REASON_IE_MISSING 0x04 +#define CAUSE_REASON_IE_INSUFFICIENT 0x08 + +#define CAUSE_PU_PROVIDER 0x00 +#define CAUSE_PU_USER 0x08 + +#define CAUSE_NA_NORMAL 0x00 +#define CAUSE_NA_ABNORMAL 0x04 + +typedef struct { + UCHAR Location; + UCHAR Cause; + UCHAR DiagnosticsLength; + UCHAR Diagnostics[4]; +} ATM_CAUSE_IE; + +#define QOS_CLASS0 0x00 +#define QOS_CLASS1 0x01 +#define QOS_CLASS2 0x02 +#define QOS_CLASS3 0x03 +#define QOS_CLASS4 0x04 + +typedef struct { + UCHAR QOSClassForward; + UCHAR QOSClassBackward; +} ATM_QOS_CLASS_IE; + +#define TNS_TYPE_NATIONAL 0x40 + +#define TNS_PLAN_CARRIER_ID_CODE 0x01 + +typedef struct { + UCHAR TypeOfNetworkId; + UCHAR NetworkIdPlan; + UCHAR NetworkIdLength; + UCHAR NetworkId[1]; +} ATM_TRANSIT_NETWORK_SELECTION_IE; + +#define SIO_GET_NUMBER_OF_ATM_DEVICES 0x50160001 +#define SIO_GET_ATM_ADDRESS 0xd0160002 +#define SIO_ASSOCIATE_PVC 0x90160003 +#define SIO_GET_ATM_CONNECTION_ID 0x50160004 + +typedef struct { + DWORD DeviceNumber; + DWORD VPI; + DWORD VCI; +} ATM_CONNECTION_ID; + +typedef struct { + ATM_CONNECTION_ID PvcConnectionId; + QOS PvcQos; +} ATM_PVC_PARAMS; + +#include +#endif diff --git a/reactos/include/reactos/winsock/nsp_dns.h b/reactos/include/reactos/winsock/nsp_dns.h index c8c0e0cb847..75b5e6167cb 100644 --- a/reactos/include/reactos/winsock/nsp_dns.h +++ b/reactos/include/reactos/winsock/nsp_dns.h @@ -11,14 +11,15 @@ /* Includes */ #include +#include /* Globals */ -GUID HostnameGuid = SVCID_HOSTNAME; -GUID AddressGuid = SVCID_INET_HOSTADDRBYINETSTRING; -GUID HostAddrByNameGuid = SVCID_INET_HOSTADDRBYNAME; -GUID IANAGuid = SVCID_INET_SERVICEBYNAME; -GUID InetHostName = SVCID_INET_HOSTADDRBYNAME; -GUID Ipv6Guid = SVCID_DNS_TYPE_AAAA; +const GUID DECLSPEC_SELECTANY HostnameGuid = SVCID_HOSTNAME; +const GUID DECLSPEC_SELECTANY AddressGuid = SVCID_INET_HOSTADDRBYINETSTRING; +const GUID DECLSPEC_SELECTANY HostAddrByNameGuid = SVCID_INET_HOSTADDRBYNAME; +const GUID DECLSPEC_SELECTANY IANAGuid = SVCID_INET_SERVICEBYNAME; +const GUID DECLSPEC_SELECTANY InetHostName = SVCID_INET_HOSTADDRBYNAME; +const GUID DECLSPEC_SELECTANY Ipv6Guid = SVCID_DNS_TYPE_AAAA; /* Macros and Defines */ #define RNR_BUFFER_SIZE 512 diff --git a/reactos/lib/cmlib/cminit.c b/reactos/lib/cmlib/cminit.c index 80f2893cf4f..59b3843432f 100644 --- a/reactos/lib/cmlib/cminit.c +++ b/reactos/lib/cmlib/cminit.c @@ -82,7 +82,10 @@ CmpPrepareIndexOfKeys( for (i = 0; i < IndexCell->Count; i++) { PCM_KEY_INDEX SubIndexCell = HvGetCell(RegistryHive, IndexCell->List[i]); - CmpPrepareIndexOfKeys(RegistryHive, SubIndexCell); + if (SubIndexCell->Signature == CM_KEY_NODE_SIGNATURE) + CmpPrepareKey(RegistryHive, (PCM_KEY_NODE)SubIndexCell); + else + CmpPrepareIndexOfKeys(RegistryHive, SubIndexCell); } } else if (IndexCell->Signature == CM_KEY_FAST_LEAF || diff --git a/reactos/lib/dnslib/addr.c b/reactos/lib/dnslib/addr.c new file mode 100644 index 00000000000..b91c532e49a --- /dev/null +++ b/reactos/lib/dnslib/addr.c @@ -0,0 +1,65 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/addr.c + * PURPOSE: Contains the Address Family Information Tables + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +DNS_FAMILY_INFO AddrFamilyTable[3] = +{ + { + AF_INET, + DNS_TYPE_A, + sizeof(IP4_ADDRESS), + sizeof(SOCKADDR_IN), + FIELD_OFFSET(SOCKADDR_IN, sin_addr) + }, + { + AF_INET6, + DNS_TYPE_AAAA, + sizeof(IP6_ADDRESS), + sizeof(SOCKADDR_IN6), + FIELD_OFFSET(SOCKADDR_IN6, sin6_addr) + }, + { + AF_ATM, + DNS_TYPE_ATMA, + sizeof(ATM_ADDRESS), + sizeof(SOCKADDR_ATM), + FIELD_OFFSET(SOCKADDR_ATM, satm_number) + } +}; + +/* FUNCTIONS *****************************************************************/ + +PDNS_FAMILY_INFO +WINAPI +FamilyInfo_GetForFamily(IN WORD AddressFamily) +{ + /* Check which family this is */ + switch (AddressFamily) + { + case AF_INET: + /* Return IPv4 Family Info */ + return &AddrFamilyTable[0]; + + case AF_INET6: + /* Return IPv6 Family Info */ + return &AddrFamilyTable[1]; + + case AF_ATM: + /* Return ATM Family Info */ + return &AddrFamilyTable[2]; + + default: + /* Invalid family */ + return NULL; + } + +} + diff --git a/reactos/lib/dnslib/debug.c b/reactos/lib/dnslib/debug.c new file mode 100644 index 00000000000..7ec359759b5 --- /dev/null +++ b/reactos/lib/dnslib/debug.c @@ -0,0 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/debug.c + * PURPOSE: Contains helpful debugging functions for DNSLIB structures. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + diff --git a/reactos/lib/dnslib/dnsaddr.c b/reactos/lib/dnslib/dnsaddr.c new file mode 100644 index 00000000000..310a0966f8b --- /dev/null +++ b/reactos/lib/dnslib/dnsaddr.c @@ -0,0 +1,200 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/dnsaddr.c + * PURPOSE: Functions dealing with DNS_ADDRESS and DNS_ARRAY addresses. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +PDNS_ARRAY +WINAPI +DnsAddrArray_Create(ULONG Count) +{ + PDNS_ARRAY DnsAddrArray; + + /* Allocate space for the array and the addresses within it */ + DnsAddrArray = Dns_AllocZero(sizeof(DNS_ARRAY) + + (Count * sizeof(DNS_ADDRESS))); + + /* Write the allocated address count */ + if (DnsAddrArray) DnsAddrArray->AllocatedAddresses = Count; + + /* Return it */ + return DnsAddrArray; +} + +VOID +WINAPI +DnsAddrArray_Free(IN PDNS_ARRAY DnsAddrArray) +{ + /* Just free the entire array */ + Dns_Free(DnsAddrArray); +} + +BOOL +WINAPI +DnsAddrArray_AddIp4(IN PDNS_ARRAY DnsAddrArray, + IN IN_ADDR Address, + IN DWORD AddressType) +{ + DNS_ADDRESS DnsAddress; + + /* Build the DNS Address */ + DnsAddr_BuildFromIp4(&DnsAddress, Address, 0); + + /* Add it to the array */ + return DnsAddrArray_AddAddr(DnsAddrArray, &DnsAddress, 0, AddressType); +} + +BOOL +WINAPI +DnsAddrArray_AddAddr(IN PDNS_ARRAY DnsAddrArray, + IN PDNS_ADDRESS DnsAddress, + IN WORD AddressFamily OPTIONAL, + IN DWORD AddressType OPTIONAL) +{ + /* Make sure we have an array */ + if (!DnsAddrArray) return FALSE; + + /* Check if we should validate the Address Family */ + if (AddressFamily) + { + /* Validate it */ + if (AddressFamily != DnsAddress->AddressFamily) return TRUE; + } + + /* Check if we should validate the Address Type */ + if (AddressType) + { + /* Make sure that this array contains this type of addresses */ + if (!DnsAddrArray_ContainsAddr(DnsAddrArray, DnsAddress, AddressType)) + { + /* Won't be adding it */ + return TRUE; + } + } + + /* Make sure we have space in the array */ + if (DnsAddrArray->AllocatedAddresses < DnsAddrArray->UsedAddresses) + { + return FALSE; + } + + /* Now add the address */ + RtlCopyMemory(&DnsAddrArray->Addresses[DnsAddrArray->UsedAddresses], + DnsAddress, + sizeof(DNS_ADDRESS)); + + /* Return success */ + return TRUE; +} + +VOID +WINAPI +DnsAddr_BuildFromIp4(IN PDNS_ADDRESS DnsAddress, + IN IN_ADDR Address, + IN WORD Port) +{ + /* Clear the address */ + RtlZeroMemory(DnsAddress, sizeof(DNS_ADDRESS)); + + /* Write data */ + DnsAddress->Ip4Address.sin_family = AF_INET; + DnsAddress->Ip4Address.sin_port = Port; + DnsAddress->Ip4Address.sin_addr = Address; + DnsAddress->AddressLength = sizeof(SOCKADDR_IN); +} + +VOID +WINAPI +DnsAddr_BuildFromIp6(IN PDNS_ADDRESS DnsAddress, + IN PIN6_ADDR Address, + IN ULONG ScopeId, + IN WORD Port) +{ + /* Clear the address */ + RtlZeroMemory(DnsAddress, sizeof(DNS_ADDRESS)); + + /* Write data */ + DnsAddress->Ip6Address.sin6_family = AF_INET6; + DnsAddress->Ip6Address.sin6_port = Port; + DnsAddress->Ip6Address.sin6_addr = *Address; + DnsAddress->Ip6Address.sin6_scope_id = ScopeId; + DnsAddress->AddressLength = sizeof(SOCKADDR_IN6); +} + +VOID +WINAPI +DnsAddr_BuildFromAtm(IN PDNS_ADDRESS DnsAddress, + IN DWORD AddressType, + IN PVOID AddressData) +{ + ATM_ADDRESS Address; + + /* Clear the address */ + RtlZeroMemory(DnsAddress, sizeof(DNS_ADDRESS)); + + /* Build an ATM Address */ + Address.AddressType = AddressType; + Address.NumofDigits = DNS_ATMA_MAX_ADDR_LENGTH; + RtlCopyMemory(&Address.Addr, AddressData, DNS_ATMA_MAX_ADDR_LENGTH); + + /* Write data */ + DnsAddress->AtmAddress = Address; + DnsAddress->AddressLength = sizeof(ATM_ADDRESS); +} + +BOOLEAN +WINAPI +DnsAddr_BuildFromDnsRecord(IN PDNS_RECORD DnsRecord, + OUT PDNS_ADDRESS DnsAddr) +{ + /* Check what kind of record this is */ + switch(DnsRecord->wType) + { + /* IPv4 */ + case DNS_TYPE_A: + /* Create the DNS Address */ + DnsAddr_BuildFromIp4(DnsAddr, + *(PIN_ADDR)&DnsRecord->Data.A.IpAddress, + 0); + break; + + /* IPv6 */ + case DNS_TYPE_AAAA: + /* Create the DNS Address */ + DnsAddr_BuildFromIp6(DnsAddr, + (PIN6_ADDR)&DnsRecord->Data.AAAA.Ip6Address, + DnsRecord->dwReserved, + 0); + break; + + /* ATM */ + case DNS_TYPE_ATMA: + /* Create the DNS Address */ + DnsAddr_BuildFromAtm(DnsAddr, + DnsRecord->Data.Atma.AddressType, + &DnsRecord->Data.Atma.Address); + break; + } + + /* Done! */ + return TRUE; +} + +BOOL +WINAPI +DnsAddrArray_ContainsAddr(IN PDNS_ARRAY DnsAddrArray, + IN PDNS_ADDRESS DnsAddress, + IN DWORD AddressType) +{ + /* FIXME */ + return TRUE; +} + diff --git a/reactos/lib/dnslib/dnslib.rbuild b/reactos/lib/dnslib/dnslib.rbuild new file mode 100644 index 00000000000..77806231ca6 --- /dev/null +++ b/reactos/lib/dnslib/dnslib.rbuild @@ -0,0 +1,22 @@ + + + + inc + addr.c + debug.c + dnsaddr.c + dnsutil.c + flatbuf.c + hostent.c + ip6.c + memory.c + name.c + print.c + record.c + rrprint.c + sablob.c + straddr.c + string.c + table.c + utf8.c + diff --git a/reactos/lib/dnslib/dnsutil.c b/reactos/lib/dnslib/dnsutil.c new file mode 100644 index 00000000000..1d0e814d911 --- /dev/null +++ b/reactos/lib/dnslib/dnsutil.c @@ -0,0 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/dnsutil.c + * PURPOSE: Contains misc. DNS utility functions, like DNS_STATUS->String. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + diff --git a/reactos/lib/dnslib/flatbuf.c b/reactos/lib/dnslib/flatbuf.c new file mode 100644 index 00000000000..dfceb3e82a3 --- /dev/null +++ b/reactos/lib/dnslib/flatbuf.c @@ -0,0 +1,116 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/flatbuf.c + * PURPOSE: Functions for managing the Flat Buffer Implementation (FLATBUF) + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +VOID +WINAPI +FlatBuf_Init(IN PFLATBUFF FlatBuffer, + IN PVOID Buffer, + IN SIZE_T Size) +{ + /* Set up the Flat Buffer start, current and ending position */ + FlatBuffer->Buffer = Buffer; + FlatBuffer->BufferPos = (ULONG_PTR)Buffer; + FlatBuffer->BufferEnd = (PVOID)(FlatBuffer->BufferPos + Size); + + /* Setup the current size and the available size */ + FlatBuffer->BufferSize = FlatBuffer->BufferFreeSize = Size; +} + +PVOID +WINAPI +FlatBuf_Arg_Reserve(IN OUT PULONG_PTR Position, + IN OUT PSIZE_T FreeSize, + IN SIZE_T Size, + IN ULONG Align) +{ + ULONG_PTR NewPosition, OldPosition = *Position; + SIZE_T NewFreeSize = *FreeSize; + + /* Start by aligning our position */ + if (Align) OldPosition += (Align - 1) & ~Align; + + /* Update it */ + NewPosition = OldPosition + Size; + + /* Update Free Size */ + NewFreeSize += (OldPosition - NewPosition); + + /* Save new values */ + *Position = NewPosition; + *FreeSize = NewFreeSize; + + /* Check if we're out of space or not */ + if (NewFreeSize > 0) return (PVOID)OldPosition; + return NULL; +} + +PVOID +WINAPI +FlatBuf_Arg_CopyMemory(IN OUT PULONG_PTR Position, + IN OUT PSIZE_T FreeSize, + IN PVOID Buffer, + IN SIZE_T Size, + IN ULONG Align) +{ + PVOID Destination; + + /* First reserve the memory */ + Destination = FlatBuf_Arg_Reserve(Position, FreeSize, Size, Align); + if (Destination) + { + /* We have space, do the copy */ + RtlCopyMemory(Destination, Buffer, Size); + } + + /* Return the pointer to the data */ + return Destination; +} + +PVOID +WINAPI +FlatBuf_Arg_WriteString(IN OUT PULONG_PTR Position, + IN OUT PSIZE_T FreeSize, + IN PVOID String, + IN BOOLEAN IsUnicode) +{ + PVOID Destination; + SIZE_T StringLength; + ULONG Align; + + /* Calculate the string length */ + if (IsUnicode) + { + /* Get the length in bytes and use WCHAR alignment */ + StringLength = (wcslen((LPWSTR)String) + 1) * sizeof(WCHAR); + Align = sizeof(WCHAR); + } + else + { + /* Get the length in bytes and use CHAR alignment */ + StringLength = strlen((LPSTR)String) + 1; + Align = sizeof(CHAR); + } + + /* Now reserve the memory */ + Destination = FlatBuf_Arg_Reserve(Position, FreeSize, StringLength, Align); + if (Destination) + { + /* We have space, do the copy */ + RtlCopyMemory(Destination, String, StringLength); + } + + /* Return the pointer to the data */ + return Destination; +} + diff --git a/reactos/lib/dnslib/hostent.c b/reactos/lib/dnslib/hostent.c new file mode 100644 index 00000000000..f7c9e64bb39 --- /dev/null +++ b/reactos/lib/dnslib/hostent.c @@ -0,0 +1,97 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/hostent.c + * PURPOSE: Functions for dealing with Host Entry structures + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +PHOSTENT +WINAPI +Hostent_Init(IN PVOID *Buffer, + IN WORD AddressFamily, + IN ULONG AddressSize, + IN ULONG AddressCount, + IN ULONG AliasCount) +{ + PHOSTENT Hostent; + ULONG_PTR BufferPosition = (ULONG_PTR)*Buffer; + + /* Align the hostent on the buffer's 4 byte boundary */ + BufferPosition += 3 & ~3; + + /* Set up the basic data */ + Hostent = (PHOSTENT)BufferPosition; + Hostent->h_length = (WORD)AddressSize; + Hostent->h_addrtype = AddressFamily; + + /* Put aliases after Hostent */ + Hostent->h_aliases = (PCHAR*)((ULONG_PTR)(Hostent + 1) & ~3); + + /* Zero it out */ + RtlZeroMemory(Hostent->h_aliases, AliasCount * sizeof(PCHAR)); + + /* Put addresses after aliases */ + Hostent->h_addr_list = (PCHAR*) + ((ULONG_PTR)Hostent->h_aliases + + (AliasCount * sizeof(PCHAR)) + sizeof(PCHAR)); + + /* Update the location */ + BufferPosition = (ULONG_PTR)Hostent->h_addr_list + + ((AddressCount * sizeof(PCHAR)) + sizeof(PCHAR)); + + /* Send it back */ + *Buffer = (PVOID)BufferPosition; + + /* Return the hostent */ + return Hostent; +} + +VOID +WINAPI +Dns_PtrArrayToOffsetArray(PCHAR *List, + ULONG_PTR Base) +{ + /* Loop every pointer in the list */ + do + { + /* Update the pointer */ + *List = (PCHAR)((ULONG_PTR)*List - Base); + } while(*List++); +} + +VOID +WINAPI +Hostent_ConvertToOffsets(IN PHOSTENT Hostent) +{ + /* Do we have a name? */ + if (Hostent->h_name) + { + /* Update it */ + Hostent->h_name -= (ULONG_PTR)Hostent; + } + + /* Do we have aliases? */ + if (Hostent->h_aliases) + { + /* Update the pointer */ + Hostent->h_aliases -= (ULONG_PTR)Hostent; + + /* Fix them up */ + Dns_PtrArrayToOffsetArray(Hostent->h_aliases, (ULONG_PTR)Hostent); + } + + /* Do we have addresses? */ + if (Hostent->h_addr_list) + { + /* Fix them up */ + Dns_PtrArrayToOffsetArray(Hostent->h_addr_list, (ULONG_PTR)Hostent); + } +} + diff --git a/reactos/lib/dnslib/inc/dnslib.h b/reactos/lib/dnslib/inc/dnslib.h new file mode 100644 index 00000000000..4c187f15b37 --- /dev/null +++ b/reactos/lib/dnslib/inc/dnslib.h @@ -0,0 +1,343 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Ancillary Function Driver DLL + * FILE: include/mswsock.h + * PURPOSE: Ancillary Function Driver DLL header + */ +#ifndef __DNSLIB_H +#define __DNSLIB_H + +/* INCLUDES ******************************************************************/ +#include + +/* ENUMERATIONS **************************************************************/ + +typedef enum _DNS_STRING_TYPE +{ + UnicodeString = 1, + Utf8String, + AnsiString, +} DNS_STRING_TYPE; + +#define IpV4Address 3 + +/* TYPES *********************************************************************/ + +typedef struct _DNS_IPV6_ADDRESS +{ + ULONG Unknown; + ULONG Unknown2; + IP6_ADDRESS Address; + ULONG Unknown3; + ULONG Unknown4; + DWORD Reserved; + ULONG Unknown5; +} DNS_IPV6_ADDRESS, *PDNS_IPV6_ADDRESS; + +typedef struct _DNS_ADDRESS +{ + union + { + struct + { + WORD AddressFamily; + WORD Port; + ATM_ADDRESS AtmAddress; + }; + SOCKADDR_IN Ip4Address; + SOCKADDR_IN6 Ip6Address; + }; + ULONG AddressLength; + DWORD Sub; + ULONG Flag; +} DNS_ADDRESS, *PDNS_ADDRESS; + +typedef struct _DNS_ARRAY +{ + ULONG AllocatedAddresses; + ULONG UsedAddresses; + ULONG Unknown[0x6]; + DNS_ADDRESS Addresses[1]; +} DNS_ARRAY, *PDNS_ARRAY; + +typedef struct _DNS_BLOB +{ + LPWSTR Name; + PDNS_ARRAY DnsAddrArray; + PHOSTENT Hostent; + ULONG AliasCount; + ULONG Unknown; + LPWSTR Aliases[8]; +} DNS_BLOB, *PDNS_BLOB; + +typedef struct _DNS_FAMILY_INFO +{ + WORD AddrType; + WORD DnsType; + DWORD AddressSize; + DWORD SockaddrSize; + DWORD AddressOffset; +} DNS_FAMILY_INFO, *PDNS_FAMILY_INFO; + +typedef struct _FLATBUFF +{ + PVOID Buffer; + PVOID BufferEnd; + ULONG_PTR BufferPos; + SIZE_T BufferSize; + SIZE_T BufferFreeSize; +} FLATBUFF, *PFLATBUFF; + +/* + * memory.c + */ +VOID +WINAPI +Dns_Free(IN PVOID Address); + +PVOID +WINAPI +Dns_AllocZero(IN SIZE_T Size); + +/* + * addr.c + */ +PDNS_FAMILY_INFO +WINAPI +FamilyInfo_GetForFamily(IN WORD AddressFamily); + +/* + * dnsaddr.c + */ +VOID +WINAPI +DnsAddr_BuildFromIp4( + IN PDNS_ADDRESS DnsAddress, + IN IN_ADDR Address, + IN WORD Unknown +); + +VOID +WINAPI +DnsAddr_BuildFromIp6( + IN PDNS_ADDRESS DnsAddress, + IN PIN6_ADDR Address, + IN ULONG ScopeId, + IN WORD Port +); + +PDNS_ARRAY +WINAPI +DnsAddrArray_Create(ULONG Count); + +BOOL +WINAPI +DnsAddrArray_AddAddr( + IN PDNS_ARRAY DnsAddrArray, + IN PDNS_ADDRESS DnsAddress, + IN WORD AddressFamily OPTIONAL, + IN DWORD AddressType OPTIONAL +); + +VOID +WINAPI +DnsAddrArray_Free(IN PDNS_ARRAY DnsAddrArray); + +BOOL +WINAPI +DnsAddrArray_AddIp4( + IN PDNS_ARRAY DnsAddrArray, + IN IN_ADDR Address, + IN DWORD AddressType +); + +BOOL +WINAPI +DnsAddrArray_ContainsAddr( + IN PDNS_ARRAY DnsAddrArray, + IN PDNS_ADDRESS DnsAddress, + IN DWORD AddressType +); + +BOOLEAN +WINAPI +DnsAddr_BuildFromDnsRecord( + IN PDNS_RECORD DnsRecord, + OUT PDNS_ADDRESS DnsAddr +); + +/* + * hostent.c + */ +PHOSTENT +WINAPI +Hostent_Init( + IN PVOID *Buffer, + IN WORD AddressFamily, + IN ULONG AddressSize, + IN ULONG AddressCount, + IN ULONG AliasCount +); + +VOID +WINAPI +Hostent_ConvertToOffsets(IN PHOSTENT Hostent); + +/* + * flatbuf.c + */ +VOID +WINAPI +FlatBuf_Init( + IN PFLATBUFF FlatBuffer, + IN PVOID Buffer, + IN SIZE_T Size +); + +PVOID +WINAPI +FlatBuf_Arg_CopyMemory( + IN OUT PULONG_PTR Position, + IN OUT PSIZE_T FreeSize, + IN PVOID Buffer, + IN SIZE_T Size, + IN ULONG Align +); + +PVOID +WINAPI +FlatBuf_Arg_Reserve( + IN OUT PULONG_PTR Position, + IN OUT PSIZE_T FreeSize, + IN SIZE_T Size, + IN ULONG Align +); + +PVOID +WINAPI +FlatBuf_Arg_WriteString( + IN OUT PULONG_PTR Position, + IN OUT PSIZE_T FreeSize, + IN PVOID String, + IN BOOLEAN IsUnicode +); + +/* + * sablob.c + */ +PDNS_BLOB +WINAPI +SaBlob_Create( + IN ULONG Count +); + +PDNS_BLOB +WINAPI +SaBlob_CreateFromIp4( + IN LPWSTR Name, + IN ULONG Count, + IN PIN_ADDR AddressArray +); + +VOID +WINAPI +SaBlob_Free(IN PDNS_BLOB Blob); + +PHOSTENT +WINAPI +SaBlob_CreateHostent( + IN OUT PULONG_PTR BufferPosition, + IN OUT PSIZE_T RemainingBufferSpace, + IN OUT PSIZE_T HostEntrySize, + IN PDNS_BLOB Blob, + IN DWORD StringType, + IN BOOLEAN Relative, + IN BOOLEAN BufferAllocated +); + +INT +WINAPI +SaBlob_WriteNameOrAlias( + IN PDNS_BLOB Blob, + IN LPWSTR String, + IN BOOLEAN IsAlias +); + +PDNS_BLOB +WINAPI +SaBlob_Query( + IN LPWSTR Name, + IN WORD DnsType, + IN ULONG Flags, + IN PVOID *Reserved, + IN DWORD AddressFamily +); + +/* + * string.c + */ +ULONG +WINAPI +Dns_StringCopy( + OUT PVOID Destination, + IN OUT PULONG DestinationSize, + IN PVOID String, + IN ULONG StringSize OPTIONAL, + IN DWORD InputType, + IN DWORD OutputType +); + +LPWSTR +WINAPI +Dns_CreateStringCopy_W(IN LPWSTR Name); + +ULONG +WINAPI +Dns_GetBufferLengthForStringCopy( + IN PVOID String, + IN ULONG Size OPTIONAL, + IN DWORD InputType, + IN DWORD OutputType +); + +/* + * straddr.c + */ +BOOLEAN +WINAPI +Dns_StringToAddressW( + OUT PVOID Address, + IN OUT PULONG AddressSize, + IN LPWSTR AddressName, + IN OUT PDWORD AddressFamily +); + +LPWSTR +WINAPI +Dns_Ip4AddressToReverseName_W( + OUT LPWSTR Name, + IN IN_ADDR Address +); + +LPWSTR +WINAPI +Dns_Ip6AddressToReverseName_W( + OUT LPWSTR Name, + IN IN6_ADDR Address +); + +BOOLEAN +WINAPI +Dns_ReverseNameToDnsAddr_W( + OUT PDNS_ADDRESS DnsAddr, + IN LPWSTR Name +); + +BOOLEAN +WINAPI +Dns_Ip4ReverseNameToAddress_W( + OUT PIN_ADDR Address, + IN LPWSTR Name +); + +#endif diff --git a/reactos/lib/dnslib/inc/precomp.h b/reactos/lib/dnslib/inc/precomp.h new file mode 100644 index 00000000000..b30cb072d00 --- /dev/null +++ b/reactos/lib/dnslib/inc/precomp.h @@ -0,0 +1,24 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/precomp.h + * PURPOSE: DNSLIB Precompiled Header + */ + +#define _CRT_SECURE_NO_DEPRECATE +#define _WIN32_WINNT 0x502 +#define WIN32_NO_STATUS + +/* PSDK Headers */ +#include +#include +#include + +/* DNSLIB and DNSAPI Headers */ +#include +#include + +/* NDK */ +#include + +/* EOF */ diff --git a/reactos/lib/dnslib/inc/windnsp.h b/reactos/lib/dnslib/inc/windnsp.h new file mode 100644 index 00000000000..48087eb134b --- /dev/null +++ b/reactos/lib/dnslib/inc/windnsp.h @@ -0,0 +1,28 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNSAPI Header + * FILE: include/libs/dns/windnsp.h + * PURPOSE: DNSLIB Precompiled Header + */ + +PVOID +WINAPI +DnsApiAlloc( + IN DWORD Size +); + +PVOID +WINAPI +DnsQueryConfigAllocEx( + IN DNS_CONFIG_TYPE Config, + OUT PVOID pBuffer, + IN OUT PDWORD pBufferLength +); + +PVOID +WINAPI +DnsApiFree( + IN PVOID pBuffer +); + +/* EOF */ diff --git a/reactos/lib/dnslib/ip6.c b/reactos/lib/dnslib/ip6.c new file mode 100644 index 00000000000..921fef41175 --- /dev/null +++ b/reactos/lib/dnslib/ip6.c @@ -0,0 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/ip6.c + * PURPOSE: Functions for dealing with IPv6 Specific issues. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + diff --git a/reactos/lib/dnslib/memory.c b/reactos/lib/dnslib/memory.c new file mode 100644 index 00000000000..183088c86b7 --- /dev/null +++ b/reactos/lib/dnslib/memory.c @@ -0,0 +1,66 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/memory.c + * PURPOSE: DNS Memory Manager Implementation and Heap. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +typedef PVOID +(WINAPI *PDNS_ALLOC_FUNCTION)(IN SIZE_T Size); +typedef VOID +(WINAPI *PDNS_FREE_FUNCTION)(IN PVOID Buffer); + +PDNS_ALLOC_FUNCTION pDnsAllocFunction; +PDNS_FREE_FUNCTION pDnsFreeFunction; + +/* FUNCTIONS *****************************************************************/ + +VOID +WINAPI +Dns_Free(IN PVOID Address) +{ + /* Check if whoever imported us specified a special free function */ + if (pDnsFreeFunction) + { + /* Use it */ + pDnsFreeFunction(Address); + } + else + { + /* Use our own */ + LocalFree(Address); + } +} + +PVOID +WINAPI +Dns_AllocZero(IN SIZE_T Size) +{ + PVOID Buffer; + + /* Check if whoever imported us specified a special allocation function */ + if (pDnsAllocFunction) + { + /* Use it to allocate the memory */ + Buffer = pDnsAllocFunction(Size); + if (Buffer) + { + /* Zero it out */ + RtlZeroMemory(Buffer, Size); + } + } + else + { + /* Use our default */ + Buffer = LocalAlloc(LMEM_ZEROINIT, Size); + } + + /* Return the allocate pointer */ + return Buffer; +} + diff --git a/reactos/lib/dnslib/name.c b/reactos/lib/dnslib/name.c new file mode 100644 index 00000000000..4004912315e --- /dev/null +++ b/reactos/lib/dnslib/name.c @@ -0,0 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/name.c + * PURPOSE: Functions dealing with DNS (Canonical, FQDN, Host) Names + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + diff --git a/reactos/lib/dnslib/print.c b/reactos/lib/dnslib/print.c new file mode 100644 index 00000000000..bead765eb3c --- /dev/null +++ b/reactos/lib/dnslib/print.c @@ -0,0 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/print.c + * PURPOSE: Callback Functions for printing a variety of DNSLIB Structures + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + diff --git a/reactos/lib/dnslib/record.c b/reactos/lib/dnslib/record.c new file mode 100644 index 00000000000..c0325a9b850 --- /dev/null +++ b/reactos/lib/dnslib/record.c @@ -0,0 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/record.c + * PURPOSE: Functions for managing DNS Record structures. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + diff --git a/reactos/lib/dnslib/rrprint.c b/reactos/lib/dnslib/rrprint.c new file mode 100644 index 00000000000..29a58ff86ed --- /dev/null +++ b/reactos/lib/dnslib/rrprint.c @@ -0,0 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/rrprint.c + * PURPOSE: Callback functions for printing RR Structures for each Record. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + diff --git a/reactos/lib/dnslib/sablob.c b/reactos/lib/dnslib/sablob.c new file mode 100644 index 00000000000..1d720d2bb16 --- /dev/null +++ b/reactos/lib/dnslib/sablob.c @@ -0,0 +1,640 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/sablob.c + * PURPOSE: Functions for the Saved Answer Blob Implementation + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +PVOID +WINAPI +FlatBuf_Arg_ReserveAlignPointer(IN PVOID Position, + IN PSIZE_T FreeSize, + IN SIZE_T Size) +{ + /* Just a little helper that we use */ + return FlatBuf_Arg_Reserve(Position, FreeSize, Size, sizeof(PVOID)); +} + +PDNS_BLOB +WINAPI +SaBlob_Create(IN ULONG Count) +{ + PDNS_BLOB Blob; + PDNS_ARRAY DnsAddrArray; + + /* Allocate the blob */ + Blob = Dns_AllocZero(sizeof(DNS_BLOB)); + if (Blob) + { + /* Check if it'll hold any addresses */ + if (Count) + { + /* Create the DNS Address Array */ + DnsAddrArray = DnsAddrArray_Create(Count); + if (!DnsAddrArray) + { + /* Failure, free the blob */ + SaBlob_Free(Blob); + SetLastError(ERROR_OUTOFMEMORY); + } + else + { + /* Link it with the blob */ + Blob->DnsAddrArray = DnsAddrArray; + } + } + } + + /* Return the blob */ + return Blob; +} + +PDNS_BLOB +WINAPI +SaBlob_CreateFromIp4(IN LPWSTR Name, + IN ULONG Count, + IN PIN_ADDR AddressArray) +{ + PDNS_BLOB Blob; + LPWSTR NameCopy; + ULONG i; + + /* Create the blob */ + Blob = SaBlob_Create(Count); + if (!Blob) goto Quickie; + + /* If we have a name */ + if (Name) + { + /* Create a copy of it */ + NameCopy = Dns_CreateStringCopy_W(Name); + if (!NameCopy) goto Quickie; + + /* Save the pointer to the name */ + Blob->Name = NameCopy; + } + + /* Loop all the addresses */ + for (i = 0; i < Count; i++) + { + /* Add an entry for this address */ + DnsAddrArray_AddIp4(Blob->DnsAddrArray, AddressArray[i], IpV4Address); + } + + /* Return the blob */ + return Blob; + +Quickie: + /* Free the blob, set error and fail */ + SaBlob_Free(Blob); + SetLastError(ERROR_OUTOFMEMORY); + return NULL; +} + +VOID +WINAPI +SaBlob_Free(IN PDNS_BLOB Blob) +{ + /* Make sure we got a blob */ + if (Blob) + { + /* Free the name */ + Dns_Free(Blob->Name); + + /* Loop the aliases */ + while (Blob->AliasCount) + { + /* Free the alias */ + Dns_Free(Blob->Aliases[Blob->AliasCount]); + + /* Decrease number of aliases */ + Blob->AliasCount--; + } + + /* Free the DNS Address Array */ + DnsAddrArray_Free(Blob->DnsAddrArray); + + /* Free the blob itself */ + Dns_Free(Blob); + } +} + +PHOSTENT +WINAPI +SaBlob_CreateHostent(IN OUT PULONG_PTR BufferPosition, + IN OUT PSIZE_T FreeBufferSpace, + IN OUT PSIZE_T HostEntrySize, + IN PDNS_BLOB Blob, + IN DWORD StringType, + IN BOOLEAN Relative, + IN BOOLEAN BufferAllocated) +{ + PDNS_ARRAY DnsAddrArray = Blob->DnsAddrArray; + ULONG AliasCount = Blob->AliasCount; + WORD AddressFamily = AF_UNSPEC; + ULONG AddressCount = 0, AddressSize = 0, TotalSize, NamePointerSize; + ULONG AliasPointerSize; + PDNS_FAMILY_INFO FamilyInfo = NULL; + ULONG StringLength = 0; + ULONG i; + ULONG HostentSize = 0; + PHOSTENT Hostent = NULL; + ULONG_PTR HostentPtr; + PVOID CurrentAddress; + + /* Check if we actually have any addresses */ + if (DnsAddrArray) + { + /* Get the address family */ + AddressFamily = DnsAddrArray->Addresses[0].AddressFamily; + + /* Get family information */ + FamilyInfo = FamilyInfo_GetForFamily(AddressFamily); + + /* Save the current address count and their size */ + AddressCount = DnsAddrArray->UsedAddresses; + AddressSize = FamilyInfo->AddressSize; + } + + /* Calculate total size for all the addresses, and their pointers */ + TotalSize = AddressSize * AddressCount; + NamePointerSize = AddressCount * sizeof(PVOID) + sizeof(PVOID); + + /* Check if we have a name */ + if (Blob->Name) + { + /* Find out the size we'll need for a copy */ + StringLength = (Dns_GetBufferLengthForStringCopy(Blob->Name, + 0, + UnicodeString, + StringType) + 1) & ~1; + } + + /* Now do the same for the aliases */ + for (i = AliasCount; i; i--) + { + /* Find out the size we'll need for a copy */ + HostentSize += (Dns_GetBufferLengthForStringCopy(Blob->Aliases[i], + 0, + UnicodeString, + StringType) + 1) & ~1; + } + + /* Find out how much the pointers will take */ + AliasPointerSize = AliasCount * sizeof(PVOID) + sizeof(PVOID); + + /* Calculate Hostent Size */ + HostentSize += TotalSize + + NamePointerSize + + AliasPointerSize + + StringLength + + sizeof(HOSTENT); + + /* Check if we already have a buffer */ + if (!BufferAllocated) + { + /* We don't, allocate space ourselves */ + HostentPtr = (ULONG_PTR)Dns_AllocZero(HostentSize); + } + else + { + /* We do, so allocate space in the buffer */ + HostentPtr = (ULONG_PTR)FlatBuf_Arg_ReserveAlignPointer(BufferPosition, + FreeBufferSpace, + HostentSize); + } + + /* Make sure we got space */ + if (HostentPtr) + { + /* Initialize it */ + Hostent = Hostent_Init((PVOID)&HostentPtr, + AddressFamily, + AddressSize, + AddressCount, + AliasCount); + } + + /* Loop the addresses */ + for (i = 0; i < AddressCount; i++) + { + /* Get the pointer of the current address */ + CurrentAddress = (PVOID)((ULONG_PTR)&DnsAddrArray->Addresses[i] + + FamilyInfo->AddressOffset); + + /* Write the pointer */ + Hostent->h_addr_list[i] = (PCHAR)HostentPtr; + + /* Copy the address */ + RtlCopyMemory((PVOID)HostentPtr, CurrentAddress, AddressSize); + + /* Advance the buffer */ + HostentPtr += AddressSize; + } + + /* Check if we have a name */ + if (Blob->Name) + { + /* Align our current position */ + HostentPtr += 1 & ~1; + + /* Save our name here */ + Hostent->h_name = (LPSTR)HostentPtr; + + /* Now copy it in the blob */ + HostentPtr += Dns_StringCopy((PVOID)HostentPtr, + NULL, + Blob->Name, + 0, + UnicodeString, + StringType); + } + + /* Loop the Aliases */ + for (i = AliasCount; i; i--) + { + /* Align our current position */ + HostentPtr += 1 & ~1; + + /* Save our alias here */ + Hostent->h_aliases[i] = (LPSTR)HostentPtr; + + /* Now copy it in the blob */ + HostentPtr += Dns_StringCopy((PVOID)HostentPtr, + NULL, + Blob->Aliases[i], + 0, + UnicodeString, + StringType); + } + + /* Check if the caller didn't have a buffer */ + if (!BufferAllocated) + { + /* Return the size; not needed if we had a blob, since it's internal */ + *HostEntrySize = *BufferPosition - (ULONG_PTR)HostentPtr; + } + + /* Convert to Offsets if requested */ + if(Relative) Hostent_ConvertToOffsets(Hostent); + + /* Return the full, complete, hostent */ + return Hostent; +} + +INT +WINAPI +SaBlob_WriteNameOrAlias(IN PDNS_BLOB Blob, + IN LPWSTR String, + IN BOOLEAN IsAlias) +{ + /* Check if this is an alias */ + if (!IsAlias) + { + /* It's not. Simply create a copy of the string */ + Blob->Name = Dns_CreateStringCopy_W(String); + if (!Blob->Name) return GetLastError(); + } + else + { + /* Does it have a name, and less then 8 aliases? */ + if ((Blob->Name) && (Blob->AliasCount <= 8)) + { + /* Yup, create a copy of the string and increase the alias count */ + Blob->Aliases[Blob->AliasCount] = Dns_CreateStringCopy_W(String); + Blob->AliasCount++; + } + else + { + /* Invalid request! */ + return ERROR_MORE_DATA; + } + } + + /* Return Success */ + return ERROR_SUCCESS; +} + +INT +WINAPI +SaBlob_WriteAddress(IN PDNS_BLOB Blob, + OUT PDNS_ADDRESS DnsAddr) +{ + /* Check if we have an array yet */ + if (!Blob->DnsAddrArray) + { + /* Allocate one! */ + Blob->DnsAddrArray = DnsAddrArray_Create(1); + if (!Blob->DnsAddrArray) return ERROR_OUTOFMEMORY; + } + + /* Add this address */ + return DnsAddrArray_AddAddr(Blob->DnsAddrArray, DnsAddr, AF_UNSPEC, 0) ? + ERROR_SUCCESS: + ERROR_MORE_DATA; +} + +BOOLEAN +WINAPI +SaBlob_IsSupportedAddrType(WORD DnsType) +{ + /* Check for valid Types that we support */ + return (DnsType == DNS_TYPE_A || + DnsType == DNS_TYPE_ATMA || + DnsType == DNS_TYPE_AAAA); +} + +INT +WINAPI +SaBlob_WriteRecords(OUT PDNS_BLOB Blob, + IN PDNS_RECORD DnsRecord, + IN BOOLEAN DoAlias) +{ + DNS_ADDRESS DnsAddress; + INT ErrorCode = STATUS_INVALID_PARAMETER; + BOOLEAN WroteOnce = FALSE; + + /* Zero out the Address */ + RtlZeroMemory(&DnsAddress, sizeof(DnsAddress)); + + /* Loop through all the Records */ + while (DnsRecord) + { + /* Is this not an answer? */ + if (DnsRecord->Flags.S.Section != DNSREC_ANSWER) + { + /* Then simply move on to the next DNS Record */ + DnsRecord = DnsRecord->pNext; + continue; + } + + /* Check the type of thsi record */ + switch(DnsRecord->wType) + { + /* Regular IPv4, v6 or ATM Record */ + case DNS_TYPE_A: + case DNS_TYPE_AAAA: + case DNS_TYPE_ATMA: + + /* Create a DNS Address from the record */ + DnsAddr_BuildFromDnsRecord(DnsRecord, &DnsAddress); + + /* Add it to the DNS Blob */ + ErrorCode = SaBlob_WriteAddress(Blob, &DnsAddress); + + /* Add the name, if needed */ + if ((DoAlias) && + (!WroteOnce) && + (!Blob->Name) && + (DnsRecord->pName)) + { + /* Write the name from the DNS Record */ + ErrorCode = SaBlob_WriteNameOrAlias(Blob, + DnsRecord->pName, + FALSE); + WroteOnce = TRUE; + } + break; + + case DNS_TYPE_CNAME: + + /* Just write the alias name */ + ErrorCode = SaBlob_WriteNameOrAlias(Blob, + DnsRecord->pName, + TRUE); + break; + + case DNS_TYPE_PTR: + + /* Check if we already have a name */ + if (Blob->Name) + { + /* We don't, so add this as a name */ + ErrorCode = SaBlob_WriteNameOrAlias(Blob, + DnsRecord->pName, + FALSE); + } + else + { + /* We do, so add it as an alias */ + ErrorCode = SaBlob_WriteNameOrAlias(Blob, + DnsRecord->pName, + TRUE); + } + break; + default: + break; + } + + /* Next record */ + DnsRecord = DnsRecord->pNext; + } + + /* Return error code */ + return ErrorCode; +} + +PDNS_BLOB +WINAPI +SaBlob_CreateFromRecords(IN PDNS_RECORD DnsRecord, + IN BOOLEAN DoAliases, + IN DWORD DnsType) +{ + PDNS_RECORD LocalDnsRecord; + ULONG ProcessedCount = 0; + PDNS_BLOB DnsBlob; + INT ErrorCode; + DNS_ADDRESS DnsAddress; + + /* Find out how many DNS Addresses to allocate */ + LocalDnsRecord = DnsRecord; + while (LocalDnsRecord) + { + /* Make sure this record is an answer */ + if ((LocalDnsRecord->Flags.S.Section == DNSREC_ANSWER) && + (SaBlob_IsSupportedAddrType(LocalDnsRecord->wType))) + { + /* Increase number of records to process */ + ProcessedCount++; + } + + /* Move to the next record */ + LocalDnsRecord = LocalDnsRecord->pNext; + } + + /* Create the DNS Blob */ + DnsBlob = SaBlob_Create(ProcessedCount); + if (!DnsBlob) + { + /* Fail */ + ErrorCode = GetLastError(); + goto Quickie; + } + + /* Write the record to the DNS Blob */ + ErrorCode = SaBlob_WriteRecords(DnsBlob, DnsRecord, TRUE); + if (ErrorCode != NO_ERROR) + { + /* We failed... but do we still have valid data? */ + if ((DnsBlob->Name) || (DnsBlob->AliasCount)) + { + /* We'll just assume success then */ + ErrorCode = NO_ERROR; + } + else + { + /* Ok, last chance..do you have a DNS Address Array? */ + if ((DnsBlob->DnsAddrArray) && + (DnsBlob->DnsAddrArray->UsedAddresses)) + { + /* Boy are you lucky! */ + ErrorCode = NO_ERROR; + } + } + + /* Buh-bye! */ + goto Quickie; + } + + /* Check if this is a PTR record */ + if ((DnsRecord->wType == DNS_TYPE_PTR) || + ((DnsType == DNS_TYPE_PTR) && + (DnsRecord->wType == DNS_TYPE_CNAME) && + (DnsRecord->Flags.S.Section == DNSREC_ANSWER))) + { + /* Get a DNS Address Structure */ + if (Dns_ReverseNameToDnsAddr_W(&DnsAddress, DnsRecord->pName)) + { + /* Add it to the Blob */ + if (SaBlob_WriteAddress(DnsBlob, &DnsAddress)) ErrorCode = NO_ERROR; + } + } + + /* Ok...do we still not have a name? */ + if (!(DnsBlob->Name) && (DoAliases) && (LocalDnsRecord)) + { + /* We have an local DNS Record, so just use it to write the name */ + ErrorCode = SaBlob_WriteNameOrAlias(DnsBlob, + LocalDnsRecord->pName, + FALSE); + } + +Quickie: + /* Check error code */ + if (ErrorCode != NO_ERROR) + { + /* Free the blob and set the error */ + SaBlob_Free(DnsBlob); + DnsBlob = NULL; + SetLastError(ErrorCode); + } + + /* Return */ + return DnsBlob; +} + +PDNS_BLOB +WINAPI +SaBlob_Query(IN LPWSTR Name, + IN WORD DnsType, + IN ULONG Flags, + IN PVOID *Reserved, + IN DWORD AddressFamily) +{ + PDNS_RECORD DnsRecord = NULL; + INT ErrorCode; + PDNS_BLOB DnsBlob = NULL; + LPWSTR LocalName, LocalNameCopy; + + /* If they want reserved data back, clear it out in case we fail */ + if (Reserved) *Reserved = NULL; + + /* Query DNS */ + ErrorCode = DnsQuery_W(Name, + DnsType, + Flags, + NULL, + &DnsRecord, + Reserved); + if (ErrorCode != ERROR_SUCCESS) + { + /* We failed... did the caller use reserved data? */ + if (Reserved && *Reserved) + { + /* He did, and it was valid. Free it */ + DnsApiFree(*Reserved); + *Reserved = NULL; + } + + /* Normalize error code */ + if (ErrorCode == RPC_S_SERVER_UNAVAILABLE) ErrorCode = WSATRY_AGAIN; + goto Quickie; + } + + /* Now create the Blob from the DNS Records */ + DnsBlob = SaBlob_CreateFromRecords(DnsRecord, TRUE, DnsType); + if (!DnsBlob) + { + /* Failed, get error code */ + ErrorCode = GetLastError(); + goto Quickie; + } + + /* Make sure it has a name */ + if (!DnsBlob->Name) + { + /* It doesn't, fail */ + ErrorCode = DNS_INFO_NO_RECORDS; + goto Quickie; + } + + /* Check if the name is local or loopback */ + if (!(DnsNameCompare_W(DnsBlob->Name, L"localhost")) && + !(DnsNameCompare_W(DnsBlob->Name, L"loopback"))) + { + /* Nothing left to do, exit! */ + goto Quickie; + } + + /* This is a local name...query it */ + LocalName = DnsQueryConfigAllocEx(DnsConfigFullHostName_W, NULL, NULL); + if (LocalName) + { + /* Create a copy for the caller */ + LocalNameCopy = Dns_CreateStringCopy_W(LocalName); + if (LocalNameCopy) + { + /* Overwrite the one in the blob */ + DnsBlob->Name = LocalNameCopy; + } + else + { + /* We failed to make a copy, free memory */ + DnsApiFree(LocalName); + } + } + +Quickie: + /* Free the DNS Record if we have one */ + if (DnsRecord) DnsRecordListFree(DnsRecord, DnsFreeRecordList); + + /* Check if this is a failure path with an active blob */ + if ((ErrorCode != ERROR_SUCCESS) && (DnsBlob)) + { + /* Free the blob */ + SaBlob_Free(DnsBlob); + DnsBlob = NULL; + } + + /* Set the last error and return */ + SetLastError(ErrorCode); + return DnsBlob; +} + diff --git a/reactos/lib/dnslib/straddr.c b/reactos/lib/dnslib/straddr.c new file mode 100644 index 00000000000..4215a80dbf0 --- /dev/null +++ b/reactos/lib/dnslib/straddr.c @@ -0,0 +1,462 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/straddr.c + * PURPOSE: Functions for address<->string conversion. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +LPWSTR +WINAPI +Dns_Ip6AddressToReverseName_W(OUT LPWSTR Name, + IN IN6_ADDR Address) +{ + /* FIXME */ + return NULL; +} + +LPWSTR +WINAPI +Dns_Ip4AddressToReverseName_W(OUT LPWSTR Name, + IN IN_ADDR Address) +{ + /* Simply append the ARPA string */ + return Name + (wsprintfW(Name, + L"%u.%u.%u.%u.in-addr.arpa.", + Address.S_un.S_addr >> 24, + Address.S_un.S_addr >> 10, + Address.S_un.S_addr >> 8, + Address.S_un.S_addr) * sizeof(WCHAR)); +} + +BOOLEAN +WINAPI +Dns_Ip4ReverseNameToAddress_A(OUT PIN_ADDR Address, + IN LPSTR Name) +{ + /* FIXME */ + return FALSE; +} + +BOOLEAN +WINAPI +Dns_Ip6ReverseNameToAddress_A(OUT PIN6_ADDR Address, + IN LPSTR Name) +{ + /* FIXME */ + return FALSE; +} + +BOOLEAN +WINAPI +Dns_Ip6StringToAddress_A(OUT PIN6_ADDR Address, + IN LPSTR Name) +{ + PCHAR Terminator; + NTSTATUS Status; + + /* Let RTL Do it for us */ + Status = RtlIpv6StringToAddressA(Name, &Terminator, Address); + if (NT_SUCCESS(Status)) return TRUE; + + /* We failed */ + return FALSE; +} + +BOOLEAN +WINAPI +Dns_Ip6StringToAddress_W(OUT PIN6_ADDR Address, + IN LPWSTR Name) +{ + PCHAR Terminator; + NTSTATUS Status; + + /* Let RTL Do it for us */ + Status = RtlIpv6StringToAddressW(Name, &Terminator, Address); + if (NT_SUCCESS(Status)) return TRUE; + + /* We failed */ + return FALSE; +} + +BOOLEAN +WINAPI +Dns_Ip4StringToAddress_A(OUT PIN_ADDR Address, + IN LPSTR Name) +{ + ULONG Addr; + + /* Use inet_addr to convert it... */ + Addr = inet_addr(Name); + if (Addr == -1) + { + /* Check if it's the wildcard (which is ok...) */ + if (strcmp("255.255.255.255", Name)) return FALSE; + } + + /* If we got here, then we suceeded... return the address */ + Address->S_un.S_addr = Addr; + return TRUE; +} + +BOOLEAN +WINAPI +Dns_Ip4StringToAddress_W(OUT PIN_ADDR Address, + IN LPWSTR Name) +{ + CHAR AnsiName[16]; + ULONG Size = sizeof(AnsiName); + INT ErrorCode; + + /* Make a copy of the name in ANSI */ + ErrorCode = Dns_StringCopy(&AnsiName, + &Size, + Name, + 0, + UnicodeString, + AnsiString); + if (ErrorCode) + { + /* Copy made sucesfully, now convert it */ + ErrorCode = Dns_Ip4StringToAddress_A(Address, AnsiName); + } + + /* Return either 0 bytes copied (failure == false) or conversion status */ + return ErrorCode; +} + +BOOLEAN +WINAPI +Dns_Ip4ReverseNameToAddress_W(OUT PIN_ADDR Address, + IN LPWSTR Name) +{ + CHAR AnsiName[32]; + ULONG Size = sizeof(AnsiName); + INT ErrorCode; + + /* Make a copy of the name in ANSI */ + ErrorCode = Dns_StringCopy(&AnsiName, + &Size, + Name, + 0, + UnicodeString, + AnsiString); + if (ErrorCode) + { + /* Copy made sucesfully, now convert it */ + ErrorCode = Dns_Ip4ReverseNameToAddress_A(Address, AnsiName); + } + + /* Return either 0 bytes copied (failure == false) or conversion status */ + return ErrorCode; +} + +BOOLEAN +WINAPI +Dns_StringToAddressEx(OUT PVOID Address, + IN OUT PULONG AddressSize, + IN PVOID AddressName, + IN OUT PDWORD AddressFamily, + IN BOOLEAN Unicode, + IN BOOLEAN Reverse) +{ + DWORD Af = *AddressFamily; + ULONG AddrSize = *AddressSize; + IN6_ADDR Addr; + BOOLEAN Return; + INT ErrorCode; + CHAR AnsiName[INET6_ADDRSTRLEN + sizeof("ip6.arpa.")]; + ULONG Size = sizeof(AnsiName); + + /* First check if this is a reverse address string */ + if (Reverse) + { + /* Convert it right now to ANSI as an optimization */ + Dns_StringCopy(AnsiName, + &Size, + AddressName, + 0, + UnicodeString, + AnsiString); + + /* Use the ANSI Name instead */ + AddressName = AnsiName; + } + + /* + * If the caller doesn't know what the family is, we'll assume IPv4 and + * check if we failed or not. If the caller told us it's IPv4, then just + * do IPv4... + */ + if ((Af == AF_UNSPEC) || (Af == AF_INET)) + { + /* Now check if the caller gave us the reverse name or not */ + if (Reverse) + { + /* Get the Address */ + Return = Dns_Ip4ReverseNameToAddress_A((PIN_ADDR)&Addr, AddressName); + } + else + { + /* Check if the caller gave us unicode or not */ + if (Unicode) + { + /* Get the Address */ + Return = Dns_Ip4StringToAddress_W((PIN_ADDR)&Addr, AddressName); + } + else + { + /* Get the Address */ + Return = Dns_Ip4StringToAddress_A((PIN_ADDR)&Addr, AddressName); + } + } + + /* Check if we suceeded */ + if (Return) + { + /* Save address family */ + Af = AF_INET; + + /* Check if the address size matches */ + if (AddrSize < sizeof(IN_ADDR)) + { + /* Invalid match, set error code */ + ErrorCode = ERROR_MORE_DATA; + } + else + { + /* It matches, save the address! */ + *(PIN_ADDR)Address = *(PIN_ADDR)&Addr; + } + } + } + + /* If we are here, either AF_INET6 was specified or IPv4 failed */ + if ((Af == AF_UNSPEC) || (Af == AF_INET6)) + { + /* Now check if the caller gave us the reverse name or not */ + if (Reverse) + { + /* Get the Address */ + Return = Dns_Ip6ReverseNameToAddress_A(&Addr, AddressName); + } + else + { + /* Check if the caller gave us unicode or not */ + if (Unicode) + { + /* Get the Address */ + Return = Dns_Ip6StringToAddress_W(&Addr, AddressName); + } + else + { + /* Get the Address */ + Return = Dns_Ip6StringToAddress_A(&Addr, AddressName); + } + } + + /* Check if we suceeded */ + if (Return) + { + /* Save address family */ + Af = AF_INET6; + + /* Check if the address size matches */ + if (AddrSize < sizeof(IN6_ADDR)) + { + /* Invalid match, set error code */ + ErrorCode = ERROR_MORE_DATA; + } + else + { + /* It matches, save the address! */ + *(PIN6_ADDR)Address = Addr; + } + } + } + else if (Af != AF_INET) + { + /* You're like.. ATM or something? Get outta here! */ + Af = AF_UNSPEC; + ErrorCode = WSA_INVALID_PARAMETER; + } + + /* Set error if we had one */ + if (ErrorCode) SetLastError(ErrorCode); + + /* Return the address family and size */ + *AddressFamily = Af; + *AddressSize = AddrSize; + + /* Return success or failure */ + return (ErrorCode == ERROR_SUCCESS); +} + +BOOLEAN +WINAPI +Dns_StringToAddressW(OUT PVOID Address, + IN OUT PULONG AddressSize, + IN LPWSTR AddressName, + IN OUT PDWORD AddressFamily) +{ + /* Call the common API */ + return Dns_StringToAddressEx(Address, + AddressSize, + AddressName, + AddressFamily, + TRUE, + FALSE); +} + +BOOLEAN +WINAPI +Dns_StringToDnsAddrEx(OUT PDNS_ADDRESS DnsAddr, + IN PVOID AddressName, + IN DWORD AddressFamily, + IN BOOLEAN Unicode, + IN BOOLEAN Reverse) +{ + IN6_ADDR Addr; + BOOLEAN Return; + INT ErrorCode = ERROR_SUCCESS; + CHAR AnsiName[INET6_ADDRSTRLEN + sizeof("ip6.arpa.")]; + ULONG Size = sizeof(AnsiName); + + /* First check if this is a reverse address string */ + if ((Reverse) && (Unicode)) + { + /* Convert it right now to ANSI as an optimization */ + Dns_StringCopy(AnsiName, + &Size, + AddressName, + 0, + UnicodeString, + AnsiString); + + /* Use the ANSI Name instead */ + AddressName = AnsiName; + } + + /* + * If the caller doesn't know what the family is, we'll assume IPv4 and + * check if we failed or not. If the caller told us it's IPv4, then just + * do IPv4... + */ + if ((AddressFamily == AF_UNSPEC) || (AddressFamily == AF_INET)) + { + /* Now check if the caller gave us the reverse name or not */ + if (Reverse) + { + /* Get the Address */ + Return = Dns_Ip4ReverseNameToAddress_A((PIN_ADDR)&Addr, AddressName); + } + else + { + /* Check if the caller gave us unicode or not */ + if (Unicode) + { + /* Get the Address */ + Return = Dns_Ip4StringToAddress_W((PIN_ADDR)&Addr, AddressName); + } + else + { + /* Get the Address */ + Return = Dns_Ip4StringToAddress_A((PIN_ADDR)&Addr, AddressName); + } + } + + /* Check if we suceeded */ + if (Return) + { + /* Build the IPv4 Address */ + DnsAddr_BuildFromIp4(DnsAddr, *(PIN_ADDR)&Addr, 0); + + /* So we don't go in the code below... */ + AddressFamily = AF_INET; + } + } + + /* If we are here, either AF_INET6 was specified or IPv4 failed */ + if ((AddressFamily == AF_UNSPEC) || (AddressFamily == AF_INET6)) + { + /* Now check if the caller gave us the reverse name or not */ + if (Reverse) + { + /* Get the Address */ + Return = Dns_Ip6ReverseNameToAddress_A(&Addr, AddressName); + if (Return) + { + /* Build the IPv6 Address */ + DnsAddr_BuildFromIp6(DnsAddr, &Addr, 0, 0); + } + else + { + goto Quickie; + } + } + else + { + /* Check if the caller gave us unicode or not */ + if (Unicode) + { + /* Get the Address */ + if (NT_SUCCESS(RtlIpv6StringToAddressExW(AddressName, + &DnsAddr->Ip6Address.sin6_addr, + &DnsAddr->Ip6Address.sin6_scope_id, + &DnsAddr->Ip6Address.sin6_port))) + Return = TRUE; + else + Return = FALSE; + } + else + { + /* Get the Address */ + if (NT_SUCCESS(RtlIpv6StringToAddressExA(AddressName, + &DnsAddr->Ip6Address.sin6_addr, + &DnsAddr->Ip6Address.sin6_scope_id, + &DnsAddr->Ip6Address.sin6_port))) + Return = TRUE; + else + Return = FALSE; + } + } + + /* Check if we suceeded */ + if (Return) + { + /* Finish setting up the structure */ + DnsAddr->Ip6Address.sin6_family = AF_INET6; + DnsAddr->AddressLength = sizeof(SOCKADDR_IN6); + } + } + else if (AddressFamily != AF_INET) + { + /* You're like.. ATM or something? Get outta here! */ + RtlZeroMemory(DnsAddr, sizeof(DNS_ADDRESS)); + SetLastError(WSA_INVALID_PARAMETER); + } + +Quickie: + /* Return success or failure */ + return (ErrorCode == ERROR_SUCCESS); +} + +BOOLEAN +WINAPI +Dns_ReverseNameToDnsAddr_W(OUT PDNS_ADDRESS DnsAddr, + IN LPWSTR Name) +{ + /* Call the common API */ + return Dns_StringToDnsAddrEx(DnsAddr, + Name, + AF_UNSPEC, + TRUE, + TRUE); +} + diff --git a/reactos/lib/dnslib/string.c b/reactos/lib/dnslib/string.c new file mode 100644 index 00000000000..e5ec0cfa935 --- /dev/null +++ b/reactos/lib/dnslib/string.c @@ -0,0 +1,257 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/string.c + * PURPOSE: functions for string manipulation and conversion. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +ULONG +WINAPI +Dns_StringCopy(OUT PVOID Destination, + IN OUT PULONG DestinationSize, + IN PVOID String, + IN ULONG StringSize OPTIONAL, + IN DWORD InputType, + IN DWORD OutputType) +{ + ULONG DestSize; + ULONG OutputSize = 0; + + /* Check if the caller already gave us the string size */ + if (!StringSize) + { + /* He didn't, get the input type */ + if (InputType == UnicodeString) + { + /* Unicode string, calculate the size */ + StringSize = (ULONG)wcslen((LPWSTR)String); + } + else + { + /* ANSI or UTF-8 sting, get the size */ + StringSize = (ULONG)strlen((LPSTR)String); + } + } + + /* Check if we have a limit on the desination size */ + if (DestinationSize) + { + /* Make sure that we can respect it */ + DestSize = Dns_GetBufferLengthForStringCopy(String, + StringSize, + InputType, + OutputType); + if (*DestinationSize < DestSize) + { + /* Fail due to missing buffer space */ + SetLastError(ERROR_MORE_DATA); + + /* Return how much data we actually need */ + *DestinationSize = DestSize; + return 0; + } + else if (!DestSize) + { + /* Fail due to invalid data */ + SetLastError(ERROR_INVALID_DATA); + return 0; + } + + /* Return how much data we actually need */ + *DestinationSize = DestSize; + } + + /* Now check if this is a Unicode String as input */ + if (InputType == UnicodeString) + { + /* Check if the output is ANSI */ + if (OutputType == AnsiString) + { + /* Convert and return the final desination size */ + OutputSize = WideCharToMultiByte(CP_ACP, + 0, + String, + StringSize, + Destination, + -1, + NULL, + NULL) + 1; + } + else if (OutputType == UnicodeString) + { + /* Copy the string */ + StringSize = StringSize * sizeof(WCHAR); + RtlMoveMemory(Destination, String, StringSize); + + /* Return output length */ + OutputSize = StringSize + 2; + } + else if (OutputType == Utf8String) + { + /* FIXME */ + OutputSize = 0; + } + } + else if (InputType == AnsiString) + { + /* It's ANSI, is the output ansi too? */ + if (OutputType == AnsiString) + { + /* Copy the string */ + RtlMoveMemory(Destination, String, StringSize); + + /* Return output length */ + OutputSize = StringSize + 1; + } + else if (OutputType == UnicodeString) + { + /* Convert to Unicode and return size */ + OutputSize = MultiByteToWideChar(CP_ACP, + 0, + String, + StringSize, + Destination, + -1) * sizeof(WCHAR) + 2; + } + else if (OutputType == Utf8String) + { + /* FIXME */ + OutputSize = 0; + } + } + else if (InputType == Utf8String) + { + /* FIXME */ + OutputSize = 0; + } + + /* Return the output size */ + return OutputSize; +} + +LPWSTR +WINAPI +Dns_CreateStringCopy_W(IN LPWSTR Name) +{ + SIZE_T StringLength; + LPWSTR NameCopy; + + /* Make sure that we have a name */ + if (!Name) + { + /* Fail */ + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* Find out the size of the string */ + StringLength = (wcslen(Name) + 1) * sizeof(WCHAR); + + /* Allocate space for the copy */ + NameCopy = Dns_AllocZero(StringLength); + if (NameCopy) + { + /* Copy it */ + RtlCopyMemory(NameCopy, Name, StringLength); + } + else + { + /* Fail */ + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + } + + /* Return the copy */ + return NameCopy; +} + +ULONG +WINAPI +Dns_GetBufferLengthForStringCopy(IN PVOID String, + IN ULONG Size OPTIONAL, + IN DWORD InputType, + IN DWORD OutputType) +{ + ULONG OutputSize = 0; + + /* Check what kind of string this is */ + if (InputType == UnicodeString) + { + /* Check if we have a size */ + if (!Size) + { + /* Get it ourselves */ + Size = (ULONG)wcslen(String); + } + + /* Check the output type */ + if (OutputType == UnicodeString) + { + /* Convert the size to bytes */ + OutputSize = (Size + 1) * sizeof(WCHAR); + } + else if (OutputType == Utf8String) + { + /* FIXME */ + OutputSize = 0; + } + else + { + /* Find out how much it will be in ANSI bytes */ + OutputSize = WideCharToMultiByte(CP_ACP, + 0, + String, + Size, + NULL, + 0, + NULL, + NULL) + 1; + } + } + else if (InputType == AnsiString) + { + /* Check if we have a size */ + if (!Size) + { + /* Get it ourselves */ + Size = (ULONG)strlen(String); + } + + /* Check the output type */ + if (OutputType == AnsiString) + { + /* Just add a byte for the null char */ + OutputSize = Size + 1; + } + else if (OutputType == UnicodeString) + { + /* Calculate the bytes for a Unicode string */ + OutputSize = (MultiByteToWideChar(CP_ACP, + 0, + String, + Size, + NULL, + 0) + 1) * sizeof(WCHAR); + } + else if (OutputType == Utf8String) + { + /* FIXME */ + OutputSize = 0; + } + } + else if (InputType == Utf8String) + { + /* FIXME */ + OutputSize = 0; + } + + /* Return the size required */ + return OutputSize; +} + diff --git a/reactos/lib/dnslib/table.c b/reactos/lib/dnslib/table.c new file mode 100644 index 00000000000..266c81b7296 --- /dev/null +++ b/reactos/lib/dnslib/table.c @@ -0,0 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/table.c + * PURPOSE: Functions for doing Table lookups, such as LUP Flags. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + diff --git a/reactos/lib/dnslib/utf8.c b/reactos/lib/dnslib/utf8.c new file mode 100644 index 00000000000..1cb6aa8bd59 --- /dev/null +++ b/reactos/lib/dnslib/utf8.c @@ -0,0 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS DNS Shared Library + * FILE: lib/dnslib/utf8.c + * PURPOSE: Functions for doing UTF8 string conversion and manipulation. + */ + +/* INCLUDES ******************************************************************/ +#include "precomp.h" + +/* DATA **********************************************************************/ + +/* FUNCTIONS *****************************************************************/ + diff --git a/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c b/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c index 147c301755e..e611a0b8d73 100644 --- a/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c +++ b/reactos/lib/drivers/sound/mmebuddy/wave/streaming.c @@ -65,6 +65,10 @@ DoWaveStreaming( HeaderExtension = (PWAVEHDR_EXTENSION) Header->reserved; SND_ASSERT( HeaderExtension ); + /* Saniy checks */ + SND_ASSERT(Header->dwFlags & WHDR_PREPARED); + SND_ASSERT(Header->dwFlags & WHDR_INQUEUE); + /* Can never be *above* the length */ SND_ASSERT( HeaderExtension->BytesCommitted <= Header->dwBufferLength ); @@ -170,6 +174,8 @@ CompleteIO( WaveHdr = (PWAVEHDR) SoundOverlapped->Header; SND_ASSERT( WaveHdr ); + SND_ASSERT( ERROR_SUCCESS == dwErrorCode ); + HdrExtension = (PWAVEHDR_EXTENSION) WaveHdr->reserved; SND_ASSERT( HdrExtension ); @@ -262,8 +268,7 @@ StopStreaming( if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); - /* FIXME: What about wave input? */ - if ( DeviceType != WAVE_OUT_DEVICE_TYPE ) + if ( DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceType != WAVE_IN_DEVICE_TYPE ) return MMSYSERR_NOTSUPPORTED; return CallSoundThread(SoundDeviceInstance, diff --git a/reactos/lib/lib.rbuild b/reactos/lib/lib.rbuild index 57c62f8c288..0b149cd1f84 100644 --- a/reactos/lib/lib.rbuild +++ b/reactos/lib/lib.rbuild @@ -13,6 +13,9 @@ + + + diff --git a/reactos/lib/rtl/heap.c b/reactos/lib/rtl/heap.c index 8bae735eb2a..539298a13cd 100644 --- a/reactos/lib/rtl/heap.c +++ b/reactos/lib/rtl/heap.c @@ -151,7 +151,7 @@ typedef struct tagHEAP SUBHEAP subheap; /* First sub-heap */ struct list entry; /* Entry in process heap list */ RTL_CRITICAL_SECTION critSection; /* Critical section for serialization */ - FREE_LIST_ENTRY freeList[HEAP_NB_FREE_LISTS] DECLSPEC_ALIGN(8); /* Free lists */ + DECLSPEC_ALIGN(8) FREE_LIST_ENTRY freeList[HEAP_NB_FREE_LISTS]; /* Free lists */ DWORD flags; /* Heap flags */ DWORD magic; /* Magic number */ PRTL_HEAP_COMMIT_ROUTINE commitRoutine; diff --git a/reactos/lib/rtl/unicode.c b/reactos/lib/rtl/unicode.c index c1f23583723..aa1c70e7439 100644 --- a/reactos/lib/rtl/unicode.c +++ b/reactos/lib/rtl/unicode.c @@ -401,40 +401,52 @@ RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString) /* * @implemented - * - * NOTES - * Check the oem-string to match the uincoded-string. * - * Functions who convert unicode strings to oem strings will set a DefaultChar from - * the OemCodepage when the character are unknown. So check it against the unicode string - * and return false when the unicode string not contain an TransDefaultChar. + * NOTES + * Check the OEM string to match the Unicode string. + * + * Functions which convert Unicode strings to OEM strings will set a + * DefaultChar from the OEM codepage when the characters are unknown. + * So check it against the Unicode string and return false when the + * Unicode string does not contain a TransDefaultChar. */ BOOLEAN NTAPI RtlpDidUnicodeToOemWork(IN PCUNICODE_STRING UnicodeString, IN POEM_STRING OemString) { - ULONG i = 0; + ULONG i = 0; - /* Go through all characters of a string */ - while ((OemString->Buffer[i] != 0) && - (i < OemString->Length)) - { - /* Check if it got translated into '?', but source char - wasn't '?' equivalent */ - if ((OemString->Buffer[i] == NlsOemDefaultChar) && - (UnicodeString->Buffer[i] != NlsUnicodeDefaultChar)) - { - /* Yes, it means unmappable characters were found */ - return FALSE; - } + if (NlsMbOemCodePageTag == FALSE) + { + /* single-byte code page */ + /* Go through all characters of a string */ + while (i < OemString->Length) + { + /* Check if it got translated into a default char, + * but source char wasn't a default char equivalent + */ + if ((OemString->Buffer[i] == NlsOemDefaultChar) && + (UnicodeString->Buffer[i] != NlsUnicodeDefaultChar)) + { + /* Yes, it means unmappable characters were found */ + return FALSE; + } - /* Move to the next char */ - i++; - } + /* Move to the next char */ + i++; + } - /* All chars were translated successfuly */ - return TRUE; + /* All chars were translated successfuly */ + return TRUE; + } + else + { + /* multibyte code page */ + + /* FIXME */ + return TRUE; + } } /* diff --git a/reactos/lib/sdk/crt/stdio/file.c b/reactos/lib/sdk/crt/stdio/file.c index cebe24ded96..ed28d63be8f 100644 --- a/reactos/lib/sdk/crt/stdio/file.c +++ b/reactos/lib/sdk/crt/stdio/file.c @@ -311,18 +311,19 @@ void msvcrt_init_io(void) InitializeCriticalSection(&FILE_cs); FILE_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FILE_cs"); GetStartupInfoA(&si); - if (si.cbReserved2 != 0 && si.lpReserved2 != NULL) + if (si.cbReserved2 >= sizeof(unsigned int) && si.lpReserved2 != NULL) { - char* wxflag_ptr; + BYTE* wxflag_ptr; HANDLE* handle_ptr; + unsigned int count; - fdend = *(unsigned*)si.lpReserved2; + count = *(unsigned*)si.lpReserved2; + wxflag_ptr = si.lpReserved2 + sizeof(unsigned); + handle_ptr = (HANDLE*)(wxflag_ptr + count); - wxflag_ptr = (char*)(si.lpReserved2 + sizeof(unsigned)); - handle_ptr = (HANDLE*)(wxflag_ptr + fdend * sizeof(char)); - - fdend = min(fdend, sizeof(fdesc) / sizeof(fdesc[0])); - for (i = 0; i < fdend; i++) + count = min(count, (si.cbReserved2 - sizeof(unsigned)) / (sizeof(HANDLE) + 1)); + count = min(count, sizeof(fdesc) / sizeof(fdesc[0])); + for (i = 0; i < count; i++) { if ((*wxflag_ptr & WX_OPEN) && *handle_ptr != INVALID_HANDLE_VALUE) { @@ -336,6 +337,7 @@ void msvcrt_init_io(void) } wxflag_ptr++; handle_ptr++; } + fdend = max( 3, count ); for (fdstart = 3; fdstart < fdend; fdstart++) if (fdesc[fdstart].handle == INVALID_HANDLE_VALUE) break; } @@ -905,10 +907,18 @@ int CDECL fseek(FILE* file, long offset, int whence) { /* Flush output if needed */ if(file->_flag & _IOWRT) - flush_buffer(file); + flush_buffer(file); if(whence == SEEK_CUR && file->_flag & _IOREAD ) { - offset -= file->_cnt; + offset -= file->_cnt; + if (fdesc[file->_file].wxflag & WX_TEXT) { + /* Black magic correction for CR removal */ + int i; + for (i=0; i_cnt; i++) { + if (file->_ptr[i] == '\n') + offset--; + } + } } /* Discard buffered input */ file->_cnt = 0; @@ -1559,27 +1569,6 @@ int CDECL _rmtmp(void) return num_removed; } -/********************************************************************* - * (internal) remove_cr - * - * Translate all \r\n to \n inplace. - * return the number of \r removed - * Corner cases required by some apps: - * \r\r\n -> \r\n - * BUG: should save state across calls somehow, so CR LF that - * straddles buffer boundary gets recognized properly? - */ -static unsigned int remove_cr(char *buf, unsigned int count) -{ - unsigned int i, j; - - for (i=0, j=0; j < count; j++) - if ((buf[j] != '\r') || ((j+1) < count && buf[j+1] != '\n')) - buf[i++] = buf[j]; - - return count - i; -} - /********************************************************************* * (internal) read_i */ @@ -1607,18 +1596,25 @@ static int read_i(int fd, void *buf, unsigned int count) { if (fdesc[fd].wxflag & WX_TEXT) { - int i; - /* in text mode, a ctrl-z signals EOF */ - for (i=0; i0 && fdesc[fd].wxflag & WX_TEXT) - { - num_read -= remove_cr(buf,num_read); - } return num_read; } @@ -1958,17 +1950,13 @@ int CDECL fgetc(FILE* file) { unsigned char *i; unsigned int j; - do { - if (file->_cnt>0) { - file->_cnt--; - i = (unsigned char *)file->_ptr++; - j = *i; - } else - j = _filbuf(file); - if (!(fdesc[file->_file].wxflag & WX_TEXT) - || ((j != '\r') || (file->_cnt && file->_ptr[0] != '\n'))) - return j; - } while(1); + if (file->_cnt>0) { + file->_cnt--; + i = (unsigned char *)file->_ptr++; + j = *i; + } else + j = _filbuf(file); + return j; } /********************************************************************* @@ -2303,11 +2291,13 @@ int CDECL _flsbuf(int c, FILE* file) } if(file->_bufsiz) { int res=flush_buffer(file); - return res?res : fputc(c, file); + return res?res : fputc(c, file); } else { - unsigned char cc=c; + unsigned char cc=c; int len; - len = _write(file->_file, &cc, 1); + /* set _cnt to 0 for unbuffered FILEs */ + file->_cnt = 0; + len = _write(file->_file, &cc, 1); if (len == 1) return c & 0xff; file->_flag |= _IOERR; return EOF; @@ -2339,8 +2329,6 @@ size_t CDECL fread(void *ptr, size_t size, size_t nmemb, FILE* file) memcpy(ptr, file->_ptr, pcnt); file->_cnt -= pcnt; file->_ptr += pcnt; - if (fdesc[file->_file].wxflag & WX_TEXT) - pcnt -= remove_cr(ptr,pcnt); read += pcnt ; rcnt -= pcnt ; ptr = (char*)ptr + pcnt; @@ -2496,17 +2484,26 @@ int CDECL fsetpos(FILE* file, const fpos_t *pos) */ LONG CDECL ftell(FILE* file) { + /* TODO: just call fgetpos and return lower half of result */ int off=0; long pos; - if(file->_bufsiz) { - if( file->_flag & _IOWRT ) { - off = file->_ptr - file->_base; - } else { - off = -file->_cnt; - } - } pos = _tell(file->_file); - if(pos == -1) return pos; + if(pos == -1) return -1; + if(file->_bufsiz) { + if( file->_flag & _IOWRT ) { + off = file->_ptr - file->_base; + } else { + off = -file->_cnt; + if (fdesc[file->_file].wxflag & WX_TEXT) { + /* Black magic correction for CR removal */ + int i; + for (i=0; i_cnt; i++) { + if (file->_ptr[i] == '\n') + off--; + } + } + } + } return off + pos; } @@ -2515,22 +2512,25 @@ LONG CDECL ftell(FILE* file) */ int CDECL fgetpos(FILE* file, fpos_t *pos) { - /* This code has been lifted form the ftell function */ int off=0; - *pos = _lseeki64(file->_file,0,SEEK_CUR); - - if (*pos == -1) return -1; - + if(*pos == -1) return -1; if(file->_bufsiz) { - if( file->_flag & _IOWRT ) { - off = file->_ptr - file->_base; - } else { - off = -file->_cnt; - } + if( file->_flag & _IOWRT ) { + off = file->_ptr - file->_base; + } else { + off = -file->_cnt; + if (fdesc[file->_file].wxflag & WX_TEXT) { + /* Black magic correction for CR removal */ + int i; + for (i=0; i_cnt; i++) { + if (file->_ptr[i] == '\n') + off--; + } + } + } } *pos += off; - return 0; } diff --git a/reactos/lib/sdk/crt/string/strtol.c b/reactos/lib/sdk/crt/string/strtol.c index 6e6706def8e..6dc42745771 100644 --- a/reactos/lib/sdk/crt/string/strtol.c +++ b/reactos/lib/sdk/crt/string/strtol.c @@ -79,6 +79,9 @@ strtol(const char *nptr, char **endptr, int base) if (any < 0) { acc = neg ? LONG_MIN : LONG_MAX; +#ifndef _LIBCNT_ + __set_errno(ERANGE); +#endif } else if (neg) acc = -acc; diff --git a/reactos/lib/sdk/crt/string/strtoul.c b/reactos/lib/sdk/crt/string/strtoul.c index 052d57a2c93..bbfa8fffe6e 100644 --- a/reactos/lib/sdk/crt/string/strtoul.c +++ b/reactos/lib/sdk/crt/string/strtoul.c @@ -63,6 +63,9 @@ strtoul(const char *nptr, char **endptr, int base) if (any < 0) { acc = ULONG_MAX; +#ifndef _LIBCNT_ + __set_errno(ERANGE); +#endif } else if (neg) acc = -acc; diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index 1be81e0383a..a453eccaf74 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -70,7 +70,7 @@ NPAGED_LOOKASIDE_LIST iBcbLookasideList; static NPAGED_LOOKASIDE_LIST BcbLookasideList; static NPAGED_LOOKASIDE_LIST CacheSegLookasideList; -#if DBG || defined(KDBG) +#if DBG static void CcRosCacheSegmentIncRefCount_ ( PCACHE_SEGMENT cs, const char* file, int line ) { ++cs->ReferenceCount; @@ -108,7 +108,7 @@ CcRosTraceCacheMap ( PBCB Bcb, BOOLEAN Trace ) { -#if DBG || defined(KDBG) +#if DBG KIRQL oldirql; PLIST_ENTRY current_entry; PCACHE_SEGMENT current; @@ -587,7 +587,7 @@ CcRosCreateCacheSegment(PBCB Bcb, current->PageOut = FALSE; current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize); current->Bcb = Bcb; -#if DBG || defined(KDBG) +#if DBG if ( Bcb->Trace ) { DPRINT1("CacheMap 0x%p: new Cache Segment: 0x%p\n", Bcb, current ); @@ -619,7 +619,7 @@ CcRosCreateCacheSegment(PBCB Bcb, { CcRosCacheSegmentIncRefCount(current); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); -#if DBG || defined(KDBG) +#if DBG if ( Bcb->Trace ) { DPRINT1("CacheMap 0x%p: deleting newly created Cache Segment 0x%p ( found existing one 0x%p )\n", @@ -865,7 +865,7 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg) KIRQL oldIrql; #endif DPRINT("Freeing cache segment 0x%p\n", CacheSeg); -#if DBG || defined(KDBG) +#if DBG if ( CacheSeg->Bcb->Trace ) { DPRINT1("CacheMap 0x%p: deleting Cache Segment: 0x%p\n", CacheSeg->Bcb, CacheSeg ); @@ -1065,7 +1065,7 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) } InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry); } -#if DBG || defined(KDBG) +#if DBG Bcb->Trace = FALSE; #endif KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 77b696cfdf8..fdbf7811789 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -488,9 +488,9 @@ QSI_DEF(SystemBasicInformation) Sbi->Reserved = 0; Sbi->TimerResolution = KeMaximumIncrement; Sbi->PageSize = PAGE_SIZE; - Sbi->NumberOfPhysicalPages = MmStats.NrTotalPages; - Sbi->LowestPhysicalPageNumber = 0; /* FIXME */ - Sbi->HighestPhysicalPageNumber = MmStats.NrTotalPages; /* FIXME */ + Sbi->NumberOfPhysicalPages = MmNumberOfPhysicalPages; + Sbi->LowestPhysicalPageNumber = MmLowestPhysicalPage; + Sbi->HighestPhysicalPageNumber = MmHighestPhysicalPage; Sbi->AllocationGranularity = MM_VIRTMEM_GRANULARITY; /* hard coded on Intel? */ Sbi->MinimumUserModeAddress = 0x10000; /* Top of 64k */ Sbi->MaximumUserModeAddress = (ULONG_PTR)MmHighestUserAddress; @@ -555,7 +555,7 @@ QSI_DEF(SystemPerformanceInformation) Spi->IoWriteOperationCount = IoWriteOperationCount; Spi->IoOtherOperationCount = IoOtherOperationCount; - Spi->AvailablePages = MmStats.NrFreePages; + Spi->AvailablePages = MmAvailablePages; /* * Add up all the used "Committed" memory + pagefile. * Not sure this is right. 8^\ @@ -570,7 +570,7 @@ QSI_DEF(SystemPerformanceInformation) * All this make Taskmgr happy but not sure it is the right numbers. * This too, fixes some of GlobalMemoryStatusEx numbers. */ - Spi->CommitLimit = MmStats.NrTotalPages + MiFreeSwapPages + MiUsedSwapPages; + Spi->CommitLimit = MmNumberOfPhysicalPages + MiFreeSwapPages + MiUsedSwapPages; Spi->PeakCommitment = 0; /* FIXME */ Spi->PageFaultCount = 0; /* FIXME */ @@ -596,7 +596,7 @@ QSI_DEF(SystemPerformanceInformation) Spi->FreeSystemPtes = 0; /* FIXME */ - Spi->ResidentSystemCodePage = MmStats.NrSystemPages; /* FIXME */ + Spi->ResidentSystemCodePage = 0; /* FIXME */ Spi->TotalSystemDriverPages = 0; /* FIXME */ Spi->TotalSystemCodePages = 0; /* FIXME */ diff --git a/reactos/ntoskrnl/include/internal/arm/mm.h b/reactos/ntoskrnl/include/internal/arm/mm.h index 0631351a99a..889ef77a8d0 100644 --- a/reactos/ntoskrnl/include/internal/arm/mm.h +++ b/reactos/ntoskrnl/include/internal/arm/mm.h @@ -175,6 +175,7 @@ typedef enum _ARM_DOMAIN #define MiGetPdeOffset(x) (((ULONG)(x)) >> 22) #define PTE_BASE 0xC0000000 +#define PTE_TOP 0xC03FFFFF #define PDE_BASE 0xC1000000 #define HYPER_SPACE 0xC1100000 @@ -203,6 +204,8 @@ PULONG MmGetPageDirectory(VOID); #define MI_MAKE_LOCAL_PAGE(x) ((x)->u.Hard.NonGlobal = 1) #define MI_MAKE_DIRTY_PAGE(x) +#define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Access = 1) // FIXFIX +#define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.ExtendedAccess = 1) // FIXFIX #define MI_PAGE_DISABLE_CACHE(x) ((x)->u.Hard.Cached = 0) #define MI_PAGE_WRITE_THROUGH(x) ((x)->u.Hard.Buffered = 0) #define MI_PAGE_WRITE_COMBINED(x) ((x)->u.Hard.Buffered = 1) diff --git a/reactos/ntoskrnl/include/internal/cc.h b/reactos/ntoskrnl/include/internal/cc.h index a2d769b646a..62221cb2ed8 100644 --- a/reactos/ntoskrnl/include/internal/cc.h +++ b/reactos/ntoskrnl/include/internal/cc.h @@ -116,7 +116,7 @@ typedef struct _BCB PVOID LazyWriteContext; KSPIN_LOCK BcbLock; ULONG RefCount; -#if DBG || defined(KDBG) +#if DBG BOOLEAN Trace; /* enable extra trace output for this BCB and it's cache segments */ #endif } BCB, *PBCB; diff --git a/reactos/ntoskrnl/include/internal/i386/mm.h b/reactos/ntoskrnl/include/internal/i386/mm.h index 80da0c48ed4..a649cbb4ae2 100644 --- a/reactos/ntoskrnl/include/internal/i386/mm.h +++ b/reactos/ntoskrnl/include/internal/i386/mm.h @@ -17,6 +17,7 @@ PULONG MmGetPageDirectory(VOID); #define PTE_BASE 0xC0000000 #define PDE_BASE 0xC0300000 +#define PTE_TOP 0xC03FFFFF #define HYPER_SPACE 0xC0400000 /* Converting address to a corresponding PDE or PTE entry */ @@ -47,5 +48,7 @@ PULONG MmGetPageDirectory(VOID); #define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Write == 1) #define MI_IS_PAGE_COPY_ON_WRITE(x)((x)->u.Hard.CopyOnWrite == 1) #define MI_IS_PAGE_DIRTY(x) ((x)->u.Hard.Dirty == 1) +#define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1) +#define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Write = 1) #endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_MM_H */ diff --git a/reactos/ntoskrnl/include/internal/kd.h b/reactos/ntoskrnl/include/internal/kd.h index c9bfec91e49..d42ffb359e4 100644 --- a/reactos/ntoskrnl/include/internal/kd.h +++ b/reactos/ntoskrnl/include/internal/kd.h @@ -22,6 +22,7 @@ extern BOOLEAN _KdDebuggerEnabled; extern BOOLEAN _KdDebuggerNotPresent; extern BOOLEAN KdBreakAfterSymbolLoad; extern BOOLEAN KdPitchDebugger; +extern BOOLEAN KdIgnoreUmExceptions; BOOLEAN NTAPI @@ -133,6 +134,14 @@ KD_CONTINUE_TYPE PKTRAP_FRAME TrapFrame ); +BOOLEAN +NTAPI +KdIsThisAKdTrap( + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN KPROCESSOR_MODE PreviousMode +); + /* INIT ROUTINES *************************************************************/ BOOLEAN diff --git a/reactos/ntoskrnl/include/internal/kd64.h b/reactos/ntoskrnl/include/internal/kd64.h index 213c83219a1..5961bd42d1a 100644 --- a/reactos/ntoskrnl/include/internal/kd64.h +++ b/reactos/ntoskrnl/include/internal/kd64.h @@ -71,6 +71,17 @@ KdUpdateDataBlock( VOID ); +// +// Determines if the kernel debugger must handle a particular trap +// +BOOLEAN +NTAPI +KdIsThisAKdTrap( + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN KPROCESSOR_MODE PreviousMode +); + // // Multi-Processor Switch Support // @@ -147,7 +158,7 @@ KdpPollBreakInWithPortLock( ); // -// Debugger Enable, Enter and Exit +// Debugger Enter, Exit, Enable and Disable // BOOLEAN NTAPI @@ -168,6 +179,12 @@ KdEnableDebuggerWithLock( IN BOOLEAN NeedLock ); +NTSTATUS +NTAPI +KdDisableDebuggerWithLock( + IN BOOLEAN NeedLock +); + // // Debug Event Handlers // @@ -242,10 +259,10 @@ KdpReportExceptionStateChange( // // Breakpoint Support // -VOID +ULONG NTAPI -KdpRestoreAllBreakpoints( - VOID +KdpAddBreakpoint( + IN PVOID Address ); BOOLEAN @@ -261,10 +278,22 @@ KdpDeleteBreakpointRange( IN PVOID Limit ); -ULONG +VOID NTAPI -KdpAddBreakpoint( - IN PVOID Address +KdpSuspendBreakPoint( + IN ULONG BpEntry +); + +VOID +NTAPI +KdpRestoreAllBreakpoints( + VOID +); + +VOID +NTAPI +KdpSuspendAllBreakPoints( + VOID ); // @@ -323,8 +352,8 @@ KdpSysReadBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, - IN PVOID Buffer, IN ULONG Offset, + IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength ); @@ -335,8 +364,8 @@ KdpSysWriteBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, - IN PVOID Buffer, IN ULONG Offset, + IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength ); @@ -428,6 +457,8 @@ extern BOOLEAN KdPitchDebugger; extern BOOLEAN _KdDebuggerNotPresent; extern BOOLEAN _KdDebuggerEnabled; extern BOOLEAN KdAutoEnableOnEvent; +extern BOOLEAN KdBlockEnable; +extern BOOLEAN KdIgnoreUmExceptions; extern BOOLEAN KdPreviouslyEnabled; extern BOOLEAN KdpDebuggerStructuresInitialized; extern BOOLEAN KdEnteredDebugger; diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 7f16d5d7337..4a95160bb59 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -192,6 +192,29 @@ extern ULONG KiDPCTimeout; /* INTERNAL KERNEL FUNCTIONS ************************************************/ +VOID +NTAPI +CPUID( + IN ULONG InfoType, + OUT PULONG CpuInfoEax, + OUT PULONG CpuInfoEbx, + OUT PULONG CpuInfoEcx, + OUT PULONG CpuInfoEdx +); + +LONGLONG +FASTCALL +RDMSR( + IN ULONG Register +); + +VOID +NTAPI +WRMSR( + IN ULONG Register, + IN LONGLONG Value +); + /* Finds a new thread to run */ LONG_PTR FASTCALL @@ -273,16 +296,6 @@ KiSelectNextThread( IN PKPRCB Prcb ); -VOID -NTAPI -CPUID( - IN ULONG InfoType, - OUT PULONG CpuInfoEax, - OUT PULONG CpuInfoEbx, - OUT PULONG CpuInfoEcx, - OUT PULONG CpuInfoEdx -); - BOOLEAN FASTCALL KiInsertTimerTable( @@ -1006,13 +1019,6 @@ VOID NTAPI KiI386PentiumLockErrataFixup(VOID); -VOID -NTAPI -WRMSR( - IN ULONG Register, - IN LONGLONG Value -); - BOOLEAN NTAPI KeFreezeExecution(IN PKTRAP_FRAME TrapFrame, diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 023efa84465..dfcd83e0920 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -16,6 +16,7 @@ extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress; extern ULONG MmNumberOfPhysicalPages; extern ULONG MmLowestPhysicalPage; extern ULONG MmHighestPhysicalPage; +extern ULONG MmAvailablePages; extern PVOID MmPagedPoolBase; extern ULONG MmPagedPoolSize; @@ -30,7 +31,23 @@ struct _MM_PAGEOP; typedef ULONG SWAPENTRY; typedef ULONG PFN_TYPE, *PPFN_TYPE; -#define MI_STATIC_MEMORY_AREAS (8) +// +//MmDbgCopyMemory Flags +// +#define MMDBG_COPY_WRITE 0x00000001 +#define MMDBG_COPY_PHYSICAL 0x00000002 +#define MMDBG_COPY_UNSAFE 0x00000004 +#define MMDBG_COPY_CACHED 0x00000008 +#define MMDBG_COPY_UNCACHED 0x00000010 +#define MMDBG_COPY_WRITE_COMBINED 0x00000020 + +// +// Maximum chunk size per copy +// +#define MMDBG_COPY_MAX_SIZE 0x8 + + +#define MI_STATIC_MEMORY_AREAS (12) #define MEMORY_AREA_INVALID (0) #define MEMORY_AREA_SECTION_VIEW (1) @@ -46,6 +63,7 @@ typedef ULONG PFN_TYPE, *PPFN_TYPE; #define MEMORY_AREA_PAGED_POOL (12) #define MEMORY_AREA_NO_ACCESS (13) #define MEMORY_AREA_PEB_OR_TEB (14) +#define MEMORY_AREA_OWNED_BY_ARM3 (15) #define MEMORY_AREA_STATIC (0x80000000) #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8) @@ -279,19 +297,6 @@ typedef struct _MEMORY_AREA } Data; } MEMORY_AREA, *PMEMORY_AREA; -typedef struct -{ - ULONG NrTotalPages; - ULONG NrSystemPages; - ULONG NrUserPages; - ULONG NrFreePages; - ULONG NrDirtyPages; - ULONG NrLockedPages; - ULONG PagingRequestsInLastMinute; - ULONG PagingRequestsInLastFiveMinutes; - ULONG PagingRequestsInLastFifteenMinutes; -} MM_STATS; - // // These two mappings are actually used by Windows itself, based on the ASSERTS // @@ -362,7 +367,6 @@ typedef struct _MMPFN } MMPFN, *PMMPFN; extern PMMPFN MmPfnDatabase; -extern MM_STATS MmStats; typedef struct _MM_PAGEOP { @@ -455,6 +459,18 @@ typedef VOID BOOLEAN Dirty ); +// +// Mm copy support for Kd +// +NTSTATUS +NTAPI +MmDbgCopyMemory( + IN ULONG64 Address, + IN PVOID Buffer, + IN ULONG Size, + IN ULONG Flags +); + /* marea.c *******************************************************************/ NTSTATUS @@ -748,14 +764,19 @@ MmInitializeProcessAddressSpace( NTSTATUS NTAPI -MmCreatePeb(struct _EPROCESS *Process); +MmCreatePeb( + IN PEPROCESS Process, + IN PINITIAL_PEB InitialPeb, + OUT PPEB *BasePeb +); -PTEB +NTSTATUS NTAPI MmCreateTeb( - struct _EPROCESS *Process, - PCLIENT_ID ClientId, - PINITIAL_TEB InitialTeb + IN PEPROCESS Process, + IN PCLIENT_ID ClientId, + IN PINITIAL_TEB InitialTeb, + OUT PTEB* BaseTeb ); VOID diff --git a/reactos/ntoskrnl/io/iomgr/deviface.c b/reactos/ntoskrnl/io/iomgr/deviface.c index 6d0390e98fe..cc6d5444de3 100644 --- a/reactos/ntoskrnl/io/iomgr/deviface.c +++ b/reactos/ntoskrnl/io/iomgr/deviface.c @@ -888,7 +888,7 @@ IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0'; /* Create symbolic link */ - DPRINT1("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name); + DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name); Status = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name); if (!NT_SUCCESS(Status) && ReferenceString == NULL) { @@ -977,7 +977,7 @@ IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, if (SymbolicLinkName == NULL) return STATUS_INVALID_PARAMETER_1; - DPRINT1("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName, Enable); + DPRINT("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName, Enable); /* Symbolic link name is \??\ACPI#PNP0501#1#{GUID}\ReferenceString */ /* Get GUID from SymbolicLinkName */ @@ -993,7 +993,7 @@ IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, SymLink.Buffer = SymbolicLinkName->Buffer; SymLink.MaximumLength = SymLink.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)SymLink.Buffer); - DPRINT1("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName, Enable); + DPRINT("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName, Enable); /* Get pointer to the PDO */ Status = IoGetDeviceObjectPointer( &SymLink, @@ -1015,7 +1015,7 @@ IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, (PVOID)SymbolicLinkName); ObDereferenceObject(FileObject); -DPRINT1("Status %x\n", Status); + DPRINT("Status %x\n", Status); return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/kd/kdmain.c b/reactos/ntoskrnl/kd/kdmain.c index 3f3a5340be3..0aa9c152792 100644 --- a/reactos/ntoskrnl/kd/kdmain.c +++ b/reactos/ntoskrnl/kd/kdmain.c @@ -18,8 +18,9 @@ BOOLEAN KdEnteredDebugger = FALSE; BOOLEAN KdDebuggerNotPresent = TRUE; BOOLEAN KiEnableTimerWatchdog = FALSE; BOOLEAN KdBreakAfterSymbolLoad = FALSE; -BOOLEAN KdpBreakPending; +BOOLEAN KdpBreakPending = FALSE; BOOLEAN KdPitchDebugger = TRUE; +BOOLEAN KdIgnoreUmExceptions = FALSE; VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads); typedef struct @@ -200,6 +201,16 @@ KdpCallGdb(IN PKTRAP_FRAME TrapFrame, return TRUE; } +BOOLEAN +NTAPI +KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN KPROCESSOR_MODE PreviousMode) +{ + /* KDBG has its own mechanism for ignoring user mode exceptions */ + return FALSE; +} + /* PUBLIC FUNCTIONS *********************************************************/ /* diff --git a/reactos/ntoskrnl/kd64/amd64/kdsup.c b/reactos/ntoskrnl/kd64/amd64/kdsup.c index 7b991f14979..0ec46469fff 100644 --- a/reactos/ntoskrnl/kd64/amd64/kdsup.c +++ b/reactos/ntoskrnl/kd64/amd64/kdsup.c @@ -142,8 +142,8 @@ NTAPI KdpSysReadBusData(IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, - IN PVOID Buffer, IN ULONG Offset, + IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength) { @@ -157,8 +157,8 @@ NTAPI KdpSysWriteBusData(IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, - IN PVOID Buffer, IN ULONG Offset, + IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength) { diff --git a/reactos/ntoskrnl/kd64/arm/kdsup.c b/reactos/ntoskrnl/kd64/arm/kdsup.c index 44857e65cb3..9ba90450c4e 100644 --- a/reactos/ntoskrnl/kd64/arm/kdsup.c +++ b/reactos/ntoskrnl/kd64/arm/kdsup.c @@ -68,8 +68,8 @@ NTAPI KdpSysReadBusData(IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, - IN PVOID Buffer, IN ULONG Offset, + IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength) { @@ -83,8 +83,8 @@ NTAPI KdpSysWriteBusData(IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, - IN PVOID Buffer, IN ULONG Offset, + IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength) { @@ -125,7 +125,7 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { @@ -140,7 +140,7 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { diff --git a/reactos/ntoskrnl/kd64/i386/kdsup.c b/reactos/ntoskrnl/kd64/i386/kdsup.c index 78cfad2e12a..5777388a43c 100644 --- a/reactos/ntoskrnl/kd64/i386/kdsup.c +++ b/reactos/ntoskrnl/kd64/i386/kdsup.c @@ -12,9 +12,6 @@ #define NDEBUG #include -#undef UNIMPLEMENTED -#define UNIMPLEMENTED KdpDprintf("%s is unimplemented\n", __FUNCTION__) - /* FUNCTIONS *****************************************************************/ VOID @@ -104,9 +101,21 @@ NTAPI KdpSysReadMsr(IN ULONG Msr, OUT PLARGE_INTEGER MsrValue) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_UNSUCCESSFUL; + /* Wrap this in SEH in case the MSR doesn't exist */ + //_SEH2_TRY + { + /* Read from the MSR */ + MsrValue->QuadPart = RDMSR(Msr); + } + //_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Invalid MSR */ + //_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE); + } + //_SEH2_END; + + /* Success */ + return STATUS_SUCCESS; } NTSTATUS @@ -114,9 +123,21 @@ NTAPI KdpSysWriteMsr(IN ULONG Msr, IN PLARGE_INTEGER MsrValue) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_UNSUCCESSFUL; + /* Wrap this in SEH in case the MSR doesn't exist */ + //_SEH2_TRY + { + /* Write to the MSR */ + WRMSR(Msr, MsrValue->QuadPart); + } + //_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Invalid MSR */ + //_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE); + } + //_SEH2_END; + + /* Success */ + return STATUS_SUCCESS; } NTSTATUS @@ -124,14 +145,21 @@ NTAPI KdpSysReadBusData(IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, - IN PVOID Buffer, IN ULONG Offset, + IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_UNSUCCESSFUL; + /* Just forward to HAL */ + *ActualLength = HalGetBusDataByOffset(BusDataType, + BusNumber, + SlotNumber, + Buffer, + Offset, + Length); + + /* Return status */ + return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; } NTSTATUS @@ -139,14 +167,21 @@ NTAPI KdpSysWriteBusData(IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, - IN PVOID Buffer, IN ULONG Offset, + IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_UNSUCCESSFUL; + /* Just forward to HAL */ + *ActualLength = HalSetBusDataByOffset(BusDataType, + BusNumber, + SlotNumber, + Buffer, + Offset, + Length); + + /* Return status */ + return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; } NTSTATUS @@ -161,7 +196,7 @@ KdpSysReadControlSpace(IN ULONG Processor, ULONG RealLength; /* Make sure that this is a valid request */ - if (((ULONG)BaseAddress < sizeof(KPROCESSOR_STATE)) && + if ((BaseAddress < sizeof(KPROCESSOR_STATE)) && (Processor < KeNumberProcessors)) { /* Get the actual length */ @@ -199,7 +234,7 @@ KdpSysWriteControlSpace(IN ULONG Processor, PVOID ControlStart; /* Make sure that this is a valid request */ - if ((((ULONG)BaseAddress + Length) <= sizeof(KPROCESSOR_STATE)) && + if (((BaseAddress + Length) <= sizeof(KPROCESSOR_STATE)) && (Processor < KeNumberProcessors)) { /* Set the proper address */ @@ -228,13 +263,79 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_UNSUCCESSFUL; + NTSTATUS Status; + + /* Verify parameters */ + if ((InterfaceType != Isa) || + (BusNumber != 0) || + (AddressSpace != 1)) + { + /* Fail, we don't support this */ + *ActualDataSize = 0; + return STATUS_UNSUCCESSFUL; + } + + /* Check the size */ + switch (DataSize) + { + case sizeof(UCHAR): + + /* Read 1 byte */ + *(PUCHAR)DataValue = + READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress); + *ActualDataSize = sizeof(UCHAR); + Status = STATUS_SUCCESS; + break; + + case sizeof(USHORT): + + /* Make sure the address is aligned */ + if ((IoAddress & (sizeof(USHORT) - 1)) != 0) + { + /* It isn't, bail out */ + *ActualDataSize = 0; + Status = STATUS_DATATYPE_MISALIGNMENT; + break; + } + + /* Read 2 bytes */ + *(PUSHORT)DataValue = + READ_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress); + *ActualDataSize = sizeof(USHORT); + Status = STATUS_SUCCESS; + break; + + case sizeof(ULONG): + + /* Make sure the address is aligned */ + if ((IoAddress & (sizeof(ULONG) - 1)) != 0) + { + /* It isn't, bail out */ + *ActualDataSize = 0; + Status = STATUS_DATATYPE_MISALIGNMENT; + break; + } + + /* Read 4 bytes */ + *(PULONG)DataValue = + READ_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress); + *ActualDataSize = sizeof(ULONG); + Status = STATUS_SUCCESS; + break; + + default: + + /* Invalid size, fail */ + *ActualDataSize = 0; + Status = STATUS_INVALID_PARAMETER; + } + + /* Return status */ + return Status; } NTSTATUS @@ -243,20 +344,85 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, - IN PULONG DataValue, + IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize) { - UNIMPLEMENTED; - while (TRUE); - return STATUS_UNSUCCESSFUL; + NTSTATUS Status; + + /* Verify parameters */ + if ((InterfaceType != Isa) || + (BusNumber != 0) || + (AddressSpace != 1)) + { + /* Fail, we don't support this */ + *ActualDataSize = 0; + return STATUS_UNSUCCESSFUL; + } + + /* Check the size */ + switch (DataSize) + { + case sizeof(UCHAR): + + /* Write 1 byte */ + WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress, + *(PUCHAR)DataValue); + *ActualDataSize = sizeof(UCHAR); + Status = STATUS_SUCCESS; + break; + + case sizeof(USHORT): + + /* Make sure the address is aligned */ + if ((IoAddress & (sizeof(USHORT) - 1)) != 0) + { + /* It isn't, bail out */ + *ActualDataSize = 0; + Status = STATUS_DATATYPE_MISALIGNMENT; + break; + } + + /* Write 2 bytes */ + WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress, + *(PUSHORT)DataValue); + *ActualDataSize = sizeof(USHORT); + Status = STATUS_SUCCESS; + break; + + case sizeof(ULONG): + + /* Make sure the address is aligned */ + if ((IoAddress & (sizeof(ULONG) - 1)) != 0) + { + /* It isn't, bail out */ + *ActualDataSize = 0; + Status = STATUS_DATATYPE_MISALIGNMENT; + break; + } + + /* Write 4 bytes */ + WRITE_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress, + *(PULONG)DataValue); + *ActualDataSize = sizeof(ULONG); + Status = STATUS_SUCCESS; + break; + + default: + + /* Invalid size, fail */ + *ActualDataSize = 0; + Status = STATUS_INVALID_PARAMETER; + } + + /* Return status */ + return Status; } NTSTATUS NTAPI KdpSysCheckLowMemory(IN ULONG Flags) { - UNIMPLEMENTED; - while (TRUE); + /* Stubbed as we don't support PAE */ return STATUS_UNSUCCESSFUL; } diff --git a/reactos/ntoskrnl/kd64/kdapi.c b/reactos/ntoskrnl/kd64/kdapi.c index 77173e20454..3d3ff38c3b2 100644 --- a/reactos/ntoskrnl/kd64/kdapi.c +++ b/reactos/ntoskrnl/kd64/kdapi.c @@ -14,6 +14,76 @@ /* PRIVATE FUNCTIONS *********************************************************/ +NTSTATUS +NTAPI +KdpCopyMemoryChunks(IN ULONG64 Address, + IN PVOID Buffer, + IN ULONG TotalSize, + IN ULONG ChunkSize, + IN ULONG Flags, + OUT PULONG ActualSize OPTIONAL) +{ + ULONG Length; + NTSTATUS Status; + + /* Check if this is physical or virtual copy */ + if (Flags & MMDBG_COPY_PHYSICAL) + { + /* Fail physical memory read/write for now */ + if (Flags & MMDBG_COPY_WRITE) + { + KdpDprintf("KdpCopyMemoryChunks: Failing write for Physical Address 0x%I64x Length: %x\n", + Address, + TotalSize); + } + else + { + KdpDprintf("KdpCopyMemoryChunks: Failing read for Physical Address 0x%I64x Length: %x\n", + Address, + TotalSize); + } + + /* Return an error */ + Length = 0; + Status = STATUS_UNSUCCESSFUL; + } + else + { + /* Protect against NULL */ + if (!Address) + { + if (ActualSize) *ActualSize = 0; + return STATUS_UNSUCCESSFUL; + } + + /* Check if this is read or write */ + if (Flags & MMDBG_COPY_WRITE) + { + /* Do the write */ + RtlCopyMemory((PVOID)(ULONG_PTR)Address, + Buffer, + TotalSize); + } + else + { + /* Do the read */ + RtlCopyMemory(Buffer, + (PVOID)(ULONG_PTR)Address, + TotalSize); + } + + /* Set size and status */ + Length = TotalSize; + Status = STATUS_SUCCESS; + } + + /* Return the actual length if requested */ + if (ActualSize) *ActualSize = Length; + + /* Return status */ + return Status; +} + VOID NTAPI KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State, @@ -264,11 +334,16 @@ KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State, IN PSTRING Data, IN PCONTEXT Context) { + PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory; STRING Header; - ULONG Length = State->u.ReadMemory.TransferCount; - NTSTATUS Status = STATUS_SUCCESS; + ULONG Length = ReadMemory->TransferCount; ULONG64 TargetBaseAddress = State->u.ReadMemory.TargetBaseAddress; + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + ASSERT(Data->Length == 0); + /* Validate length */ if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) { @@ -276,43 +351,16 @@ KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State, Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); } -#if 0 - if (!MmIsAddressValid((PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress)) - { - KdpDprintf("Tried to read invalid address %p\n", - (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress); - while (TRUE); - } -#endif + /* Do the read */ + State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress, + Data->Buffer, + Length, + 0, + MMDBG_COPY_UNSAFE, + &Length); - // HACK for x64, until KD stops sending bogus addresses to WinDbg - if (TargetBaseAddress < (ULONG_PTR)MM_LOWEST_SYSTEM_ADDRESS) - { - FrLdrDbgPrint("Trying to read memory at 0x%p\n", TargetBaseAddress); -// DPRINT1("Trying to read memory at 0x%p\n", TargetBaseAddress); - TargetBaseAddress = 0; - } - - if (!TargetBaseAddress) - { - Length = 0; - Status = STATUS_UNSUCCESSFUL; - } - else - { - RtlCopyMemory(Data->Buffer, - (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress, - Length); - } - - /* Fill out the header */ - Data->Length = Length; - Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); - Header.Buffer = (PCHAR)State; - - /* Fill out the state */ - State->ReturnStatus = Status; - State->u.ReadMemory.ActualBytesRead = Length; + /* Return the actual length read */ + Data->Length = ReadMemory->ActualBytesRead = Length; /* Send the packet */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, @@ -327,11 +375,27 @@ KdpWriteVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State, IN PSTRING Data, IN PCONTEXT Context) { - /* FIXME: STUB */ - KdpDprintf("KdpWriteVirtualMemory called for Address: %p Length %x\n", - (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress, - State->u.ReadMemory.TransferCount); - while (TRUE); + PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory; + STRING Header; + + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + + /* Do the write */ + State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress, + Data->Buffer, + Data->Length, + 0, + MMDBG_COPY_UNSAFE | + MMDBG_COPY_WRITE, + &WriteMemory->ActualBytesWritten); + + /* Send the packet */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + NULL, + &KdpContext); } VOID @@ -340,20 +404,56 @@ KdpReadPhysicalmemory(IN PDBGKD_MANIPULATE_STATE64 State, IN PSTRING Data, IN PCONTEXT Context) { + PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory; STRING Header; + ULONG Length = ReadMemory->TransferCount; + ULONG Flags, CacheFlags; - /* FIXME: STUB */ - KdpDprintf("KdpWritePhysicalMemory called for Address %I64x Length: %x\n", - State->u.ReadMemory.TargetBaseAddress, - State->u.ReadMemory.TransferCount); - - /* Setup an empty message, with failure */ + /* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); Header.Buffer = (PCHAR)State; - Data->Length = 0; - State->ReturnStatus = STATUS_UNSUCCESSFUL; + ASSERT(Data->Length == 0); - /* Send it */ + /* Validate length */ + if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) + { + /* Overflow, set it to maximum possible */ + Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); + } + + /* Start with the default flags */ + Flags = MMDBG_COPY_UNSAFE | MMDBG_COPY_PHYSICAL; + + /* Get the caching flags and check if a type is specified */ + CacheFlags = ReadMemory->ActualBytesRead; + if (CacheFlags == DBGKD_CACHING_CACHED) + { + /* Cached */ + Flags |= MMDBG_COPY_CACHED; + } + else if (CacheFlags == DBGKD_CACHING_UNCACHED) + { + /* Uncached */ + Flags |= MMDBG_COPY_UNCACHED; + } + else if (CacheFlags == DBGKD_CACHING_UNCACHED) + { + /* Write Combined */ + Flags |= DBGKD_CACHING_WRITE_COMBINED; + } + + /* Do the read */ + State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress, + Data->Buffer, + Length, + 0, + Flags, + &Length); + + /* Return the actual length read */ + Data->Length = ReadMemory->ActualBytesRead = Length; + + /* Send the packet */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Header, Data, @@ -366,23 +466,47 @@ KdpWritePhysicalmemory(IN PDBGKD_MANIPULATE_STATE64 State, IN PSTRING Data, IN PCONTEXT Context) { + PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory; STRING Header; + ULONG Flags, CacheFlags; - /* FIXME: STUB */ - KdpDprintf("KdpWritePhysicalMemory called for Address %I64x Length: %x\n", - State->u.ReadMemory.TargetBaseAddress, - State->u.ReadMemory.TransferCount); - - /* Setup an empty message, with failure */ + /* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); Header.Buffer = (PCHAR)State; - Data->Length = 0; - State->ReturnStatus = STATUS_UNSUCCESSFUL; - /* Send it */ + /* Start with the default flags */ + Flags = MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE | MMDBG_COPY_PHYSICAL; + + /* Get the caching flags and check if a type is specified */ + CacheFlags = WriteMemory->ActualBytesWritten; + if (CacheFlags == DBGKD_CACHING_CACHED) + { + /* Cached */ + Flags |= MMDBG_COPY_CACHED; + } + else if (CacheFlags == DBGKD_CACHING_UNCACHED) + { + /* Uncached */ + Flags |= MMDBG_COPY_UNCACHED; + } + else if (CacheFlags == DBGKD_CACHING_UNCACHED) + { + /* Write Combined */ + Flags |= DBGKD_CACHING_WRITE_COMBINED; + } + + /* Do the write */ + State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress, + Data->Buffer, + Data->Length, + 0, + Flags, + &WriteMemory->ActualBytesWritten); + + /* Send the packet */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Header, - Data, + NULL, &KdpContext); } @@ -434,7 +558,6 @@ KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State, { PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory; STRING Header; - ULONG Length; /* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); @@ -445,10 +568,7 @@ KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State, WriteMemory->TargetBaseAddress, Data->Buffer, Data->Length, - &Length); - - /* Return the length written */ - WriteMemory->ActualBytesWritten = Length; + &WriteMemory->ActualBytesWritten); /* Send the reply */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, @@ -483,7 +603,7 @@ KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State, else { /* SMP not yet handled */ - KdpDprintf("SMP UNHANDLED\n"); + KdpDprintf("KdpGetContext: SMP UNHANDLED\n"); ControlStart = NULL; while (TRUE); } @@ -534,7 +654,7 @@ KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State, else { /* SMP not yet handled */ - KdpDprintf("SMP UNHANDLED\n"); + KdpDprintf("KdpSetContext: SMP UNHANDLED\n"); ControlStart = NULL; while (TRUE); } @@ -651,8 +771,8 @@ KdpGetBusData(IN PDBGKD_MANIPULATE_STATE64 State, State->ReturnStatus = KdpSysReadBusData(GetBusData->BusDataType, GetBusData->BusNumber, GetBusData->SlotNumber, - Data->Buffer, GetBusData->Offset, + Data->Buffer, Length, &Length); @@ -684,8 +804,8 @@ KdpSetBusData(IN PDBGKD_MANIPULATE_STATE64 State, State->ReturnStatus = KdpSysWriteBusData(SetBusData->BusDataType, SetBusData->BusNumber, SetBusData->SlotNumber, - Data->Buffer, SetBusData->Offset, + Data->Buffer, SetBusData->Length, &Length); @@ -844,7 +964,7 @@ KdpCheckLowMemory(IN PDBGKD_MANIPULATE_STATE64 State) Header.Buffer = (PCHAR)State; /* Call the internal routine */ - State->ReturnStatus = KdpSysCheckLowMemory(0x4); + State->ReturnStatus = KdpSysCheckLowMemory(MMDBG_COPY_UNSAFE); /* Send the reply */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, @@ -1357,6 +1477,22 @@ KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame) return KeQueryPerformanceCounter(NULL); } +NTSTATUS +NTAPI +KdpAllowDisable(VOID) +{ + /* Check if we are on MP */ + if (KeNumberProcessors > 1) + { + /* TODO */ + KdpDprintf("KdpAllowDisable: SMP UNHANDLED\n"); + while (TRUE); + } + + /* Allow disable */ + return STATUS_SUCCESS; +} + BOOLEAN NTAPI KdEnterDebugger(IN PKTRAP_FRAME TrapFrame, @@ -1456,6 +1592,13 @@ KdEnableDebuggerWithLock(IN BOOLEAN NeedLock) OldIrql = PASSIVE_LEVEL; #endif + /* Check if enabling the debugger is blocked */ + if (KdBlockEnable) + { + /* It is, fail the enable */ + return STATUS_ACCESS_DENIED; + } + /* Check if we need to acquire the lock */ if (NeedLock) { @@ -1473,10 +1616,21 @@ KdEnableDebuggerWithLock(IN BOOLEAN NeedLock) /* Do the unlock */ KeLowerIrql(OldIrql); KdpPortUnlock(); - } - /* Fail: We're already enabled */ - return STATUS_INVALID_PARAMETER; + /* Fail: We're already enabled */ + return STATUS_INVALID_PARAMETER; + } + else + { + /* + * This can only happen if we are called from a bugcheck + * and were never initialized, so initialize the debugger now. + */ + KdInitSystem(0, NULL); + + /* Return success since we initialized */ + return STATUS_SUCCESS; + } } /* Decrease the disable count */ @@ -1503,6 +1657,98 @@ KdEnableDebuggerWithLock(IN BOOLEAN NeedLock) return STATUS_SUCCESS; } +NTSTATUS +NTAPI +KdDisableDebuggerWithLock(IN BOOLEAN NeedLock) +{ + KIRQL OldIrql; + NTSTATUS Status; + +#if defined(__GNUC__) + /* Make gcc happy */ + OldIrql = PASSIVE_LEVEL; +#endif + + /* + * If enabling the debugger is blocked + * then there is nothing to disable (duh) + */ + if (KdBlockEnable) + { + /* Fail */ + return STATUS_ACCESS_DENIED; + } + + /* Check if we need to acquire the lock */ + if (NeedLock) + { + /* Lock the port */ + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + KdpPortLock(); + } + + /* Check if we're not disabled */ + if (!KdDisableCount) + { + /* Check if the debugger was never actually initialized */ + if (!(KdDebuggerEnabled) && !(KdPitchDebugger)) + { + /* It wasn't, so don't re-enable it later */ + KdPreviouslyEnabled = FALSE; + } + else + { + /* It was, so we will re-enable it later */ + KdPreviouslyEnabled = TRUE; + } + + /* Check if we were called from the exported API and are enabled */ + if ((NeedLock) && (KdPreviouslyEnabled)) + { + /* Check if it is safe to disable the debugger */ + Status = KdpAllowDisable(); + if (!NT_SUCCESS(Status)) + { + /* Release the lock and fail */ + KeLowerIrql(OldIrql); + KdpPortUnlock(); + return Status; + } + } + + /* Only disable the debugger if it is enabled */ + if (KdDebuggerEnabled) + { + /* + * Disable the debugger; suspend breakpoints + * and reset the debug stub + */ + KdpSuspendAllBreakPoints(); + KiDebugRoutine = KdpStub; + + /* We are disabled now */ + KdDebuggerEnabled = FALSE; +#undef KdDebuggerEnabled + SharedUserData->KdDebuggerEnabled = FALSE; +#define KdDebuggerEnabled _KdDebuggerEnabled + } + } + + /* Increment the disable count */ + KdDisableCount++; + + /* Check if we had locked the port before */ + if (NeedLock) + { + /* Yes, now unlock it */ + KeLowerIrql(OldIrql); + KdpPortUnlock(); + } + + /* We're done */ + return STATUS_SUCCESS; +} + /* PUBLIC FUNCTIONS **********************************************************/ /* @@ -1513,11 +1759,20 @@ NTAPI KdEnableDebugger(VOID) { /* Use the internal routine */ - KdpDprintf("KdEnableDebugger called\n"); - while (TRUE); return KdEnableDebuggerWithLock(TRUE); } +/* + * @implemented + */ +NTSTATUS +NTAPI +KdDisableDebugger(VOID) +{ + /* Use the internal routine */ + return KdDisableDebuggerWithLock(TRUE); +} + /* * @unimplemented */ @@ -1562,17 +1817,6 @@ KdPowerTransition(IN DEVICE_POWER_STATE NewState) return STATUS_SUCCESS; } -/* - * @unimplemented - */ -NTSTATUS -NTAPI -KdDisableDebugger(VOID) -{ - /* HACK */ - return STATUS_SUCCESS; -} - /* * @unimplemented */ @@ -1602,4 +1846,3 @@ NtSetDebugFilterState(ULONG ComponentId, /* HACK */ return STATUS_SUCCESS; } - diff --git a/reactos/ntoskrnl/kd64/kdbreak.c b/reactos/ntoskrnl/kd64/kdbreak.c index 8cf62537b05..2583623bf18 100644 --- a/reactos/ntoskrnl/kd64/kdbreak.c +++ b/reactos/ntoskrnl/kd64/kdbreak.c @@ -183,7 +183,7 @@ KdpRestoreAllBreakpoints(VOID) BreakpointsSuspended = FALSE; /* Loop the breakpoints */ - for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++ ) + for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++) { /* Check if they are valid, suspended breakpoints */ if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) && @@ -195,3 +195,36 @@ KdpRestoreAllBreakpoints(VOID) } } } + +VOID +NTAPI +KdpSuspendBreakPoint(IN ULONG BpEntry) +{ + ULONG BpIndex = BpEntry - 1; + + /* Check if this is a valid, unsuspended breakpoint */ + if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) && + !(KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended)) + { + /* Suspend it */ + KdpBreakpointTable[BpIndex].Flags |= KdpBreakpointSuspended; + KdpLowWriteContent(BpIndex); + } +} + +VOID +NTAPI +KdpSuspendAllBreakPoints(VOID) +{ + ULONG BpEntry; + + /* Breakpoints are suspended */ + BreakpointsSuspended = TRUE; + + /* Loop every breakpoint */ + for (BpEntry = 1; BpEntry <= KD_BREAKPOINT_MAX; BpEntry++) + { + /* Suspend it */ + KdpSuspendBreakPoint(BpEntry); + } +} diff --git a/reactos/ntoskrnl/kd64/kddata.c b/reactos/ntoskrnl/kd64/kddata.c index 577b5e7e166..9af857afbd9 100644 --- a/reactos/ntoskrnl/kd64/kddata.c +++ b/reactos/ntoskrnl/kd64/kddata.c @@ -68,6 +68,8 @@ BOOLEAN KdPitchDebugger; BOOLEAN _KdDebuggerNotPresent; BOOLEAN _KdDebuggerEnabled; BOOLEAN KdAutoEnableOnEvent; +BOOLEAN KdBlockEnable; +BOOLEAN KdIgnoreUmExceptions; BOOLEAN KdPreviouslyEnabled; BOOLEAN KdpDebuggerStructuresInitialized; BOOLEAN KdEnteredDebugger; @@ -83,6 +85,9 @@ BOOLEAN KdpOweBreakpoint; BOOLEAN BreakpointsSuspended; ULONG KdpNumInternalBreakpoints; +// +// Symbol Data +// ULONG KdpCurrentSymbolStart, KdpCurrentSymbolEnd; // diff --git a/reactos/ntoskrnl/kd64/kdinit.c b/reactos/ntoskrnl/kd64/kdinit.c index f62e612cbbd..e5c487c8a3b 100644 --- a/reactos/ntoskrnl/kd64/kdinit.c +++ b/reactos/ntoskrnl/kd64/kdinit.c @@ -72,15 +72,20 @@ NTAPI KdInitSystem(IN ULONG BootPhase, IN PLOADER_PARAMETER_BLOCK LoaderBlock) { - BOOLEAN EnableKd; - LPSTR CommandLine, DebugLine; + BOOLEAN EnableKd, DisableKdAfterInit = FALSE, BlockEnable; + LPSTR CommandLine, DebugLine, DebugOptionStart, DebugOptionEnd; ANSI_STRING ImageName; PLDR_DATA_TABLE_ENTRY LdrEntry; PLIST_ENTRY NextEntry; - ULONG i, j, Length; + ULONG i, j, Length, DebugOptionLength; CHAR NameBuffer[256]; PWCHAR Name; +#if defined(__GNUC__) + /* Make gcc happy */ + BlockEnable = FALSE; +#endif + /* Check if this is Phase 1 */ if (BootPhase) { @@ -166,10 +171,87 @@ KdInitSystem(IN ULONG BootPhase, /* Enable KD */ EnableKd = TRUE; - /* Check if there was additional data */ + /* Check if there are any options */ if (DebugLine[5] == '=') { - /* FIXME: Check for NOUMEX, DISABLE, AUTOENABLE */ + /* Save pointers */ + DebugOptionStart = DebugOptionEnd = &DebugLine[6]; + + /* Scan the string for debug options */ + for (;;) + { + /* Loop until we reach the end of the string */ + while (*DebugOptionEnd != ANSI_NULL) + { + /* Check if this is a comma, a space or a tab */ + if ((*DebugOptionEnd == ',') || + (*DebugOptionEnd == ' ') || + (*DebugOptionEnd == ' ')) + { + /* + * We reached the end of the option or + * the end of the string, break out + */ + break; + } + else + { + /* Move on to the next character */ + DebugOptionEnd++; + } + } + + /* Calculate the length of the current option */ + DebugOptionLength = ((ULONG_PTR)DebugOptionEnd - + (ULONG_PTR)DebugOptionStart); + + /* + * Break out if we reached the last option + * or if there were no options at all + */ + if (!DebugOptionLength) break; + + /* Now check which option this is */ + if ((DebugOptionLength == 10) && + !(strncmp(DebugOptionStart, "AUTOENABLE", 10))) + { + /* + * Disable the debugger, but + * allow it to be reenabled + */ + DisableKdAfterInit = TRUE; + BlockEnable = FALSE; + KdAutoEnableOnEvent = TRUE; + } + else if ((DebugOptionLength == 7) && + !(strncmp(DebugOptionStart, "DISABLE", 7))) + { + /* Disable the debugger */ + DisableKdAfterInit = TRUE; + BlockEnable = TRUE; + KdAutoEnableOnEvent = FALSE; + } + else if ((DebugOptionLength == 6) && + !(strncmp(DebugOptionStart, "NOUMEX", 6))) + { + /* Ignore user mode exceptions */ + KdIgnoreUmExceptions = TRUE; + } + + /* + * If there are more options then + * the next character should be a comma + */ + if (*DebugOptionEnd != ',') + { + /* It isn't, break out */ + break; + } + + /* Move on to the next option */ + DebugOptionEnd++; + DebugOptionStart = DebugOptionEnd; + } } } } @@ -182,7 +264,7 @@ KdInitSystem(IN ULONG BootPhase, } else { - /* Called from a bugcheck...Save the Kernel Base */ + /* Called from a bugcheck or a re-enable. Save the Kernel Base */ KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)PsNtosImageBase; /* Unconditionally enable KD */ @@ -226,6 +308,20 @@ KdInitSystem(IN ULONG BootPhase, SharedUserData->KdDebuggerEnabled = TRUE; #define KdDebuggerEnabled _KdDebuggerEnabled + /* Check if the debugger should be disabled initially */ + if (DisableKdAfterInit) + { + /* Disable it */ + KdDisableDebuggerWithLock(FALSE); + + /* + * Save the enable block state and return initialized + * (the debugger is active but disabled). + */ + KdBlockEnable = BlockEnable; + return TRUE; + } + /* Check if we have a loader block */ if (LoaderBlock) { diff --git a/reactos/ntoskrnl/kd64/kdtrap.c b/reactos/ntoskrnl/kd64/kdtrap.c index 99f779daf61..409b2e9a5bb 100644 --- a/reactos/ntoskrnl/kd64/kdtrap.c +++ b/reactos/ntoskrnl/kd64/kdtrap.c @@ -289,3 +289,24 @@ KdpStub(IN PKTRAP_FRAME TrapFrame, return FALSE; } } + +BOOLEAN +NTAPI +KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN KPROCESSOR_MODE PreviousMode) +{ + /* Check if this is a breakpoint or a valid debug service */ + if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && + (ExceptionRecord->NumberParameters > 0) && + (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK)) + { + /* Then we have to handle it */ + return TRUE; + } + else + { + /* We don't have to handle it */ + return FALSE; + } +} diff --git a/reactos/ntoskrnl/ke/arm/kiinit.c b/reactos/ntoskrnl/ke/arm/kiinit.c index 71aa7d2f932..2a15609ca51 100644 --- a/reactos/ntoskrnl/ke/arm/kiinit.c +++ b/reactos/ntoskrnl/ke/arm/kiinit.c @@ -186,6 +186,11 @@ KiInitializeKernel(IN PKPROCESS InitProcess, // KdInitSystem(0, LoaderBlock); + // + // Check for break-in + // + if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); + // // Cleanup the rest of the processor block array // @@ -372,12 +377,12 @@ KiInitializeSystem(IN ULONG Magic, // // Set global d-cache fill and alignment values // - if (Pcr->SecondLevelDcacheSize) + if (!Pcr->SecondLevelDcacheSize) { // // Use the first level // - Pcr->DcacheFillSize = Pcr->SecondLevelDcacheSize; + Pcr->DcacheFillSize = Pcr->FirstLevelDcacheSize; } else { @@ -395,12 +400,12 @@ KiInitializeSystem(IN ULONG Magic, // // Set global i-cache fill and alignment values // - if (Pcr->SecondLevelIcacheSize) + if (!Pcr->SecondLevelIcacheSize) { // // Use the first level // - Pcr->IcacheFillSize = Pcr->SecondLevelIcacheSize; + Pcr->IcacheFillSize = Pcr->FirstLevelIcacheSize; } else { diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 5fa1ca14b98..bfb65d9c8dd 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -1295,6 +1295,9 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF); TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16); TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24); + + /* Set the TSS selector */ + Ke386SetTr(KGDT_TSS); #endif #if defined(_M_PPC) @@ -1360,5 +1363,3 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, /* Do general System Startup */ KiSystemStartupReal(NtLoaderBlock); } - -/* EOF */ diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 6ee3c74c088..bd0df7ac6ec 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -928,11 +928,19 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, /* User mode exception, was it first-chance? */ if (FirstChance) { - /* Make sure a debugger is present, and ignore user-mode if requested */ - if ((KiDebugRoutine) && - (!(PsGetCurrentProcess()->DebugPort))) + /* + * Break into the kernel debugger unless a user mode debugger + * is present or user mode exceptions are ignored, unless this is + * a breakpoint or a debug service in which case we have to + * handle it. + */ + if ((!(PsGetCurrentProcess()->DebugPort) && + !(KdIgnoreUmExceptions)) || + (KdIsThisAKdTrap(ExceptionRecord, + &Context, + PreviousMode))) { - /* Call the debugger */ + /* Call the kernel debugger */ if (KiDebugRoutine(TrapFrame, ExceptionFrame, ExceptionRecord, @@ -946,7 +954,7 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, } /* Forward exception to user mode debugger */ - if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) goto Exit; + if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) return; /* Set up the user-stack */ DispatchToUser: @@ -1032,12 +1040,12 @@ DispatchToUser: if (DbgkForwardException(ExceptionRecord, TRUE, TRUE)) { /* Handled, get out */ - goto Exit; + return; } else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE)) { /* Handled, get out */ - goto Exit; + return; } /* 3rd strike, kill the process */ @@ -1061,7 +1069,6 @@ Handled: TrapFrame, Context.ContextFlags, PreviousMode); -Exit: return; } diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index 70edc212f0e..1983aaf6559 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -40,7 +40,7 @@ KiInitMachineDependent(VOID) if (KeFeatureBits & KF_LARGE_PAGE) { /* FIXME: Support this */ - DPRINT1("Large Page support detected but not yet taken advantage of!\n"); + DPRINT("Large Page support detected but not yet taken advantage of!\n"); } /* Check for global page support */ @@ -621,7 +621,6 @@ KiGetMachineBootPointers(IN PKGDTENTRY *Gdt, /* Get TSS and FS Selectors */ Tr = Ke386GetTr(); - if (Tr != KGDT_TSS) Tr = KGDT_TSS; // FIXME: HACKHACK Fs = Ke386GetFs(); /* Get PCR Selector, mask it and get its GDT Entry */ @@ -753,7 +752,7 @@ AppCpuInit: KdInitSystem(0, KeLoaderBlock); /* Check for break-in */ - if (KdPollBreakIn()) DbgBreakPointWithStatus(1); + if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); } /* Raise to HIGH_LEVEL */ diff --git a/reactos/ntoskrnl/ke/i386/mtrr.c b/reactos/ntoskrnl/ke/i386/mtrr.c index bb9d8738930..c273fd7a5d4 100644 --- a/reactos/ntoskrnl/ke/i386/mtrr.c +++ b/reactos/ntoskrnl/ke/i386/mtrr.c @@ -21,7 +21,7 @@ NTAPI KiInitializeMTRR(IN BOOLEAN FinalCpu) { /* FIXME: Support this */ - DPRINT1("Your machine supports MTRR but ReactOS doesn't yet.\n"); + DPRINT("Your machine supports MTRR but ReactOS doesn't yet.\n"); } VOID @@ -29,5 +29,5 @@ NTAPI KiAmdK6InitializeMTRR(VOID) { /* FIXME: Support this */ - DPRINT1("Your machine supports AMD MTRR but ReactOS doesn't yet.\n"); + DPRINT("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 index 95e2307a0b4..a85e11cd84a 100644 --- a/reactos/ntoskrnl/ke/i386/patpge.c +++ b/reactos/ntoskrnl/ke/i386/patpge.c @@ -59,5 +59,5 @@ NTAPI KiInitializePAT(VOID) { /* FIXME: Support this */ - DPRINT1("Advanced Memory features detected but not yet taken advantage of.\n"); + DPRINT("Advanced Memory features detected but not yet taken advantage of.\n"); } diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index e46dfeab55a..190855fe6c8 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -781,7 +781,7 @@ _KiTrap3: TRAP_PROLOG kit3_a, kit3_t /* Set status code */ - mov eax, 0 //STATUS_SUCCESS + mov eax, STATUS_SUCCESS /* Check for V86 */ PrepareInt3: diff --git a/reactos/ntoskrnl/ke/powerpc/kiinit.c b/reactos/ntoskrnl/ke/powerpc/kiinit.c index 788994791b1..a08987aa275 100644 --- a/reactos/ntoskrnl/ke/powerpc/kiinit.c +++ b/reactos/ntoskrnl/ke/powerpc/kiinit.c @@ -329,7 +329,7 @@ AppCpuInit: /* Check for break-in */ if (KdPollBreakIn()) { - DbgBreakPointWithStatus(1); + DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); } /* Raise to HIGH_LEVEL */ diff --git a/reactos/ntoskrnl/mm/ARM3/arm/init.c b/reactos/ntoskrnl/mm/ARM3/arm/init.c index 7f2e21594c4..3d91ed60a5f 100644 --- a/reactos/ntoskrnl/mm/ARM3/arm/init.c +++ b/reactos/ntoskrnl/mm/ARM3/arm/init.c @@ -24,9 +24,36 @@ ULONG MmMaximumNonPagedPoolInBytes; PVOID MmNonPagedSystemStart; PVOID MmNonPagedPoolStart; PVOID MmNonPagedPoolExpansionStart; -PVOID MmNonPagedPoolEnd = (PVOID)0xFFBE0000; +PVOID MmNonPagedPoolEnd = MI_NONPAGED_POOL_END; +PVOID MmPagedPoolStart = MI_PAGED_POOL_START; +PVOID MmPagedPoolEnd; +ULONG MmSizeOfPagedPoolInBytes = MI_MIN_INIT_PAGED_POOLSIZE; +PVOID MiSessionSpaceEnd; +PVOID MiSessionImageEnd; +PVOID MiSessionImageStart; +PVOID MiSessionViewStart; +PVOID MiSessionPoolEnd; +PVOID MiSessionPoolStart; +PVOID MmSessionBase; +ULONG MmSessionSize; +ULONG MmSessionViewSize; +ULONG MmSessionPoolSize; +ULONG MmSessionImageSize; +PVOID MiSystemViewStart; +ULONG MmSystemViewSize; +PFN_NUMBER MmSystemPageDirectory; +PMMPTE MmSystemPagePtes; ULONG MmNumberOfSystemPtes; +ULONG MxPfnAllocation; +RTL_BITMAP MiPfnBitMap; PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock; +PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor; +MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor; +ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage = -1; +ULONG MmBootImageSize; +ULONG MmUserProbeAddress; +PVOID MmHighestUserAddress; +PVOID MmSystemRangeStart; /* PRIVATE FUNCTIONS **********************************************************/ diff --git a/reactos/ntoskrnl/mm/ARM3/expool.c b/reactos/ntoskrnl/mm/ARM3/expool.c index 5fdc201ac35..d6274e1f8a8 100644 --- a/reactos/ntoskrnl/mm/ARM3/expool.c +++ b/reactos/ntoskrnl/mm/ARM3/expool.c @@ -16,10 +16,14 @@ #define MODULE_INVOLVED_IN_ARM3 #include "../ARM3/miarm.h" +#undef ExAllocatePoolWithQuota +#undef ExAllocatePoolWithQuotaTag + /* GLOBALS ********************************************************************/ POOL_DESCRIPTOR NonPagedPoolDescriptor; PPOOL_DESCRIPTOR PoolVector[2]; +PKGUARDED_MUTEX ExpPagedPoolMutex; /* PRIVATE FUNCTIONS **********************************************************/ @@ -69,19 +73,108 @@ NTAPI InitializePool(IN POOL_TYPE PoolType, IN ULONG Threshold) { - ASSERT(PoolType == NonPagedPool); + PPOOL_DESCRIPTOR Descriptor; // - // Initialize the nonpaged pool descirptor + // Check what kind of pool this is // - PoolVector[PoolType] = &NonPagedPoolDescriptor; - ExInitializePoolDescriptor(PoolVector[PoolType], - PoolType, - 0, - Threshold, - NULL); + if (PoolType == NonPagedPool) + { + // + // Initialize the nonpaged pool descriptor + // + PoolVector[NonPagedPool] = &NonPagedPoolDescriptor; + ExInitializePoolDescriptor(PoolVector[NonPagedPool], + NonPagedPool, + 0, + Threshold, + NULL); + } + else + { + // + // Allocate the pool descriptor + // + Descriptor = ExAllocatePoolWithTag(NonPagedPool, + sizeof(KGUARDED_MUTEX) + + sizeof(POOL_DESCRIPTOR), + 'looP'); + if (!Descriptor) + { + // + // This is really bad... + // + KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY, + 0, + -1, + -1, + -1); + } + + // + // Setup the vector and guarded mutex for paged pool + // + PoolVector[PagedPool] = Descriptor; + ExpPagedPoolMutex = (PKGUARDED_MUTEX)(Descriptor + 1); + KeInitializeGuardedMutex(ExpPagedPoolMutex); + ExInitializePoolDescriptor(Descriptor, + PagedPool, + 0, + Threshold, + ExpPagedPoolMutex); + } } +FORCEINLINE +KIRQL +ExLockPool(IN PPOOL_DESCRIPTOR Descriptor) +{ + // + // Check if this is nonpaged pool + // + if ((Descriptor->PoolType & BASE_POOL_TYPE_MASK) == NonPagedPool) + { + // + // Use the queued spin lock + // + return KeAcquireQueuedSpinLock(LockQueueNonPagedPoolLock); + } + else + { + // + // Use the guarded mutex + // + KeAcquireGuardedMutex(Descriptor->LockAddress); + return APC_LEVEL; + } +} + +FORCEINLINE +VOID +ExUnlockPool(IN PPOOL_DESCRIPTOR Descriptor, + IN KIRQL OldIrql) +{ + // + // Check if this is nonpaged pool + // + if ((Descriptor->PoolType & BASE_POOL_TYPE_MASK) == NonPagedPool) + { + // + // Use the queued spin lock + // + KeReleaseQueuedSpinLock(LockQueueNonPagedPoolLock, OldIrql); + } + else + { + // + // Use the guarded mutex + // + KeReleaseGuardedMutex(Descriptor->LockAddress); + } +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + PVOID NTAPI ExAllocateArmPoolWithTag(IN POOL_TYPE PoolType, @@ -151,9 +244,9 @@ ExAllocateArmPoolWithTag(IN POOL_TYPE PoolType, if (!IsListEmpty(ListHead)) { // - // Acquire the nonpaged pool lock now + // Acquire the pool lock now // - OldIrql = KeAcquireQueuedSpinLock(LockQueueNonPagedPoolLock); + OldIrql = ExLockPool(PoolDesc); // // And make sure the list still has entries @@ -166,7 +259,7 @@ ExAllocateArmPoolWithTag(IN POOL_TYPE PoolType, // // Try again! // - KeReleaseQueuedSpinLock(LockQueueNonPagedPoolLock, OldIrql); + ExUnlockPool(PoolDesc, OldIrql); ListHead++; continue; } @@ -292,7 +385,7 @@ ExAllocateArmPoolWithTag(IN POOL_TYPE PoolType, // and release the lock since we're done // Entry->PoolType = PoolType + 1; - KeReleaseQueuedSpinLock(LockQueueNonPagedPoolLock, OldIrql); + ExUnlockPool(PoolDesc, OldIrql); // // Return the pool allocation @@ -330,9 +423,9 @@ ExAllocateArmPoolWithTag(IN POOL_TYPE PoolType, if (FragmentEntry->BlockSize != 1) { // - // Excellent -- acquire the nonpaged pool lock + // Excellent -- acquire the pool lock // - OldIrql = KeAcquireQueuedSpinLock(LockQueueNonPagedPoolLock); + OldIrql = ExLockPool(PoolDesc); // // And insert the free entry into the free list for this block size @@ -341,9 +434,9 @@ ExAllocateArmPoolWithTag(IN POOL_TYPE PoolType, (PLIST_ENTRY)FragmentEntry + 1); // - // Release the nonpaged pool lock + // Release the pool lock // - KeReleaseQueuedSpinLock(LockQueueNonPagedPoolLock, OldIrql); + ExUnlockPool(PoolDesc, OldIrql); } // @@ -397,7 +490,7 @@ ExFreeArmPoolWithTag(IN PVOID P, // for this pool type // BlockSize = Entry->BlockSize; - PoolType = (Entry->PoolType & BASE_POOL_TYPE_MASK) - 1; + PoolType = (Entry->PoolType & 3) - 1; PoolDesc = PoolVector[PoolType]; // @@ -406,9 +499,9 @@ ExFreeArmPoolWithTag(IN PVOID P, NextEntry = Entry + BlockSize; // - // Acquire the nonpaged pool lock + // Acquire the pool lock // - OldIrql = KeAcquireQueuedSpinLock(LockQueueNonPagedPoolLock); + OldIrql = ExLockPool(PoolDesc); // // Check if the next allocation is at the end of the page @@ -498,9 +591,9 @@ ExFreeArmPoolWithTag(IN PVOID P, (PAGE_ALIGN(Entry + Entry->BlockSize) == Entry + Entry->BlockSize)) { // - // In this case, release the nonpaged pool lock, and free the page + // In this case, release the pool lock, and free the page // - KeReleaseQueuedSpinLock(LockQueueNonPagedPoolLock, OldIrql); + ExUnlockPool(PoolDesc, OldIrql); MiFreePoolPages(Entry); return; } @@ -531,10 +624,10 @@ ExFreeArmPoolWithTag(IN PVOID P, } // - // Insert this new free block, and release the nonpaged pool lock + // Insert this new free block, and release the pool lock // InsertHeadList(&PoolDesc->ListHeads[BlockSize - 1], (PLIST_ENTRY)Entry + 1); - KeReleaseQueuedSpinLock(LockQueueNonPagedPoolLock, OldIrql); + ExUnlockPool(PoolDesc, OldIrql); } VOID @@ -547,4 +640,67 @@ ExFreeArmPool(PVOID P) ExFreeArmPoolWithTag(P, 0); } +/* + * @unimplemented + */ +SIZE_T +NTAPI +ExQueryPoolBlockSize(IN PVOID PoolBlock, + OUT PBOOLEAN QuotaCharged) +{ + // + // Not implemented + // + UNIMPLEMENTED; + return FALSE; +} + +/* + * @implemented + */ + +PVOID +NTAPI +ExAllocatePoolWithQuota(IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes) +{ + // + // Allocate the pool + // + return ExAllocatePoolWithQuotaTag(PoolType, NumberOfBytes, 'enoN'); +} + +/* + * @implemented + */ +PVOID +NTAPI +ExAllocatePoolWithTagPriority(IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag, + IN EX_POOL_PRIORITY Priority) +{ + // + // Allocate the pool + // + UNIMPLEMENTED; + return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); +} + +/* + * @implemented + */ +PVOID +NTAPI +ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag) +{ + // + // Allocate the pool + // + UNIMPLEMENTED; + return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); +} + /* EOF */ diff --git a/reactos/ntoskrnl/mm/ARM3/i386/init.c b/reactos/ntoskrnl/mm/ARM3/i386/init.c index 80cef6566fd..aae42aa4619 100644 --- a/reactos/ntoskrnl/mm/ARM3/i386/init.c +++ b/reactos/ntoskrnl/mm/ARM3/i386/init.c @@ -540,14 +540,15 @@ MiBuildPagedPool(VOID) // Size = Size * 1024; ASSERT(Size == MmSizeOfPagedPoolInPages); - BitMapSize = sizeof(RTL_BITMAP) + (((Size + 31) / 32) * sizeof(ULONG)); + BitMapSize = Size; + Size = sizeof(RTL_BITMAP) + (((Size + 31) / 32) * sizeof(ULONG)); // // Allocate the allocation bitmap, which tells us which regions have not yet // been mapped into memory // MmPagedPoolInfo.PagedPoolAllocationMap = ExAllocatePoolWithTag(NonPagedPool, - BitMapSize, + Size, ' mM'); ASSERT(MmPagedPoolInfo.PagedPoolAllocationMap); @@ -568,7 +569,7 @@ MiBuildPagedPool(VOID) // entire allocation is. // MmPagedPoolInfo.EndOfPagedPoolBitmap = ExAllocatePoolWithTag(NonPagedPool, - BitMapSize, + Size, ' mM'); ASSERT(MmPagedPoolInfo.EndOfPagedPoolBitmap); RtlInitializeBitMap(MmPagedPoolInfo.EndOfPagedPoolBitmap, @@ -583,7 +584,12 @@ MiBuildPagedPool(VOID) // // Initialize paged pool. // - //InitializePool(PagedPool, 0); + InitializePool(PagedPool, 0); + + // + // Initialize the paged pool mutex + // + KeInitializeGuardedMutex(&MmPagedPoolMutex); } NTSTATUS @@ -594,20 +600,16 @@ MmArmInitSystem(IN ULONG Phase, PLIST_ENTRY NextEntry; PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; ULONG FreePages = 0; - PMEMORY_AREA MArea; - PHYSICAL_ADDRESS BoundaryAddressMultiple; PFN_NUMBER PageFrameIndex; PMMPTE StartPde, EndPde, PointerPte, LastPte; MMPTE TempPde = HyperTemplatePte, TempPte = HyperTemplatePte; - PVOID NonPagedPoolExpansionVa, BaseAddress; - NTSTATUS Status; + PVOID NonPagedPoolExpansionVa; ULONG OldCount; BOOLEAN IncludeType[LoaderMaximum]; ULONG i; PVOID Bitmap; PPHYSICAL_MEMORY_RUN Run; PFN_NUMBER FreePage, FreePageCount, PagesLeft, BasePage, PageCount; - BoundaryAddressMultiple.QuadPart = 0; if (Phase == 0) { @@ -1078,37 +1080,6 @@ MmArmInitSystem(IN ULONG Phase, *PointerPte++ = TempPte; } - // - // ReactOS requires a memory area to keep the initial NP area off-bounds - // - BaseAddress = MmNonPagedPoolStart; - Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM | MEMORY_AREA_STATIC, - &BaseAddress, - MmSizeOfNonPagedPoolInBytes, - PAGE_READWRITE, - &MArea, - TRUE, - 0, - BoundaryAddressMultiple); - ASSERT(Status == STATUS_SUCCESS); - - // - // And we need one more for the system NP - // - BaseAddress = MmNonPagedSystemStart; - Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM | MEMORY_AREA_STATIC, - &BaseAddress, - (ULONG_PTR)MmNonPagedPoolEnd - - (ULONG_PTR)MmNonPagedSystemStart, - PAGE_READWRITE, - &MArea, - TRUE, - 0, - BoundaryAddressMultiple); - ASSERT(Status == STATUS_SUCCESS); - // // Sanity check: make sure we have properly defined the system PTE space // @@ -1318,9 +1289,7 @@ MmArmInitSystem(IN ULONG Phase, MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1)); MiSyncARM3WithROS(MmPfnDatabase, (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1)); MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1)); - } - else // NOW WE HAVE NONPAGED POOL - { + // // Instantiate memory that we don't consider RAM/usable // We use the same exclusions that Windows does, in order to try to be @@ -1394,53 +1363,6 @@ MmArmInitSystem(IN ULONG Phase, // Size up paged pool and build the shadow system page directory // MiBuildPagedPool(); - - // - // Print the memory layout - // - DPRINT1(" 0x%p - 0x%p\t%s\n", - MmSystemRangeStart, - (ULONG_PTR)MmSystemRangeStart + MmBootImageSize, - "Boot Loaded Image"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - MmPagedPoolBase, - (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize, - "Paged Pool"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - MmPfnDatabase, - (ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT), - "PFN Database"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - MmNonPagedPoolStart, - (ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes, - "ARMÂł Non Paged Pool"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - MiSystemViewStart, - (ULONG_PTR)MiSystemViewStart + MmSystemViewSize, - "System View Space"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - MmSessionBase, - MiSessionSpaceEnd, - "Session Space"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - PTE_BASE, PDE_BASE, - "Page Tables"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - PDE_BASE, HYPER_SPACE, - "Page Directories"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - HYPER_SPACE, HYPER_SPACE + (4 * 1024 * 1024), - "Hyperspace"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - MmPagedPoolStart, - (ULONG_PTR)MmPagedPoolStart + MmSizeOfPagedPoolInBytes, - "ARMÂł Paged Pool"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - MmNonPagedSystemStart, MmNonPagedPoolExpansionStart, - "System PTE Space"); - DPRINT1(" 0x%p - 0x%p\t%s\n", - MmNonPagedPoolExpansionStart, MmNonPagedPoolEnd, - "Non Paged Pool Expansion PTE Space"); } // diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index 3d9824c841d..96e62436bae 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -29,6 +29,10 @@ #define MI_PAGED_POOL_START (PVOID)0xE1000000 #define MI_NONPAGED_POOL_END (PVOID)0xFFBE0000 +#define MM_HIGHEST_VAD_ADDRESS \ + (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE)) + + // // FIXFIX: These should go in ex.h after the pool merge // @@ -142,6 +146,32 @@ extern MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor; extern ULONG MxPfnAllocation; extern MM_PAGED_POOL_INFO MmPagedPoolInfo; extern RTL_BITMAP MiPfnBitMap; +extern KGUARDED_MUTEX MmPagedPoolMutex; +extern PVOID MmPagedPoolStart; +extern PVOID MmPagedPoolEnd; +extern PVOID MmNonPagedSystemStart; +extern PVOID MiSystemViewStart; +extern ULONG MmSystemViewSize; +extern PVOID MmSessionBase; +extern PVOID MiSessionSpaceEnd; +extern ULONG MmSizeOfPagedPoolInBytes; +extern PMMPTE MmSystemPagePtes; + +NTSTATUS +NTAPI +MmArmInitSystem( + IN ULONG Phase, + IN PLOADER_PARAMETER_BLOCK LoaderBlock +); + +NTSTATUS +NTAPI +MmArmAccessFault( + IN BOOLEAN StoreInstruction, + IN PVOID Address, + IN KPROCESSOR_MODE Mode, + IN PVOID TrapInformation +); VOID NTAPI diff --git a/reactos/ntoskrnl/mm/ARM3/mmsup.c b/reactos/ntoskrnl/mm/ARM3/mmsup.c new file mode 100644 index 00000000000..ed73cdd9e56 --- /dev/null +++ b/reactos/ntoskrnl/mm/ARM3/mmsup.c @@ -0,0 +1,133 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/mm/ARM3/mmsup.c + * PURPOSE: ARM Memory Manager Support Routines + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +#line 15 "ARMÂł::MMSUP" +#define MODULE_INVOLVED_IN_ARM3 +#include "../ARM3/miarm.h" + +/* GLOBALS ********************************************************************/ + +BOOLEAN IsThisAnNtAsSystem = FALSE; +MM_SYSTEMSIZE MmSystemSize = MmSmallSystem; + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +MmMapUserAddressesToPage(IN PVOID BaseAddress, + IN SIZE_T NumberOfBytes, + IN PVOID PageAddress) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +MmAdjustWorkingSetSize(IN SIZE_T WorkingSetMinimumInBytes, + IN SIZE_T WorkingSetMaximumInBytes, + IN ULONG SystemCache, + IN BOOLEAN IncreaseOkay) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +MmSetAddressRangeModified(IN PVOID Address, + IN SIZE_T Length) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +MmIsNonPagedSystemAddressValid(IN PVOID VirtualAddress) +{ + DPRINT1("WARNING: %s returns bogus result\n", __FUNCTION__); + return MmIsAddressValid(VirtualAddress); +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +MmSetBankedSection(IN HANDLE ProcessHandle, + IN PVOID VirtualAddress, + IN ULONG BankLength, + IN BOOLEAN ReadWriteBank, + IN PVOID BankRoutine, + IN PVOID Context) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +MmIsRecursiveIoFault(VOID) +{ + PETHREAD Thread = PsGetCurrentThread(); + + // + // If any of these is true, this is a recursive fault + // + return ((Thread->DisablePageFaultClustering) | (Thread->ForwardClusterOnly)); +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +MmIsThisAnNtAsSystem(VOID) +{ + // + // Return if this is a server system + // + return IsThisAnNtAsSystem; +} + +/* + * @implemented + */ +MM_SYSTEMSIZE +NTAPI +MmQuerySystemSize(VOID) +{ + // + // Return the low, medium or high memory system type + // + return MmSystemSize; +} + +/* EOF */ diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c new file mode 100644 index 00000000000..e3b740114b8 --- /dev/null +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -0,0 +1,391 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/mm/ARM3/pagfault.c + * PURPOSE: ARM Memory Manager Page Fault Handling + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +#line 15 "ARMÂł::PAGFAULT" +#define MODULE_INVOLVED_IN_ARM3 +#include "../ARM3/miarm.h" + +/* GLOBALS ********************************************************************/ + +/* PRIVATE FUNCTIONS **********************************************************/ + +NTSTATUS +FASTCALL +MiCheckPdeForPagedPool(IN PVOID Address) +{ + PMMPTE PointerPde; + NTSTATUS Status = STATUS_SUCCESS; + + // + // Check if this is a fault while trying to access the page table itself + // + if ((Address >= (PVOID)MiAddressToPte(MmSystemRangeStart)) && + (Address < (PVOID)PTE_TOP)) + { + // + // Send a hint to the page fault handler that this is only a valid fault + // if we already detected this was access within the page table range + // + PointerPde = MiAddressToPte(Address); + Status = STATUS_WAIT_1; + } + else if (Address < MmSystemRangeStart) + { + // + // This is totally illegal + // + return STATUS_ACCESS_VIOLATION; + } + else + { + // + // Get the PDE for the address + // + PointerPde = MiAddressToPde(Address); + } + + // + // Check if it's not valid + // + if (PointerPde->u.Hard.Valid == 0) + { + // + // Copy it from our double-mapped system page directory + // + InterlockedExchangePte(PointerPde, + MmSystemPagePtes[((ULONG_PTR)PointerPde & + (PAGE_SIZE - 1)) / + sizeof(MMPTE)].u.Long); + } + + // + // Return status + // + return Status; +} + +NTSTATUS +NTAPI +MiResolveDemandZeroFault(IN PVOID Address, + IN PMMPTE PointerPte, + IN PEPROCESS Process, + IN KIRQL OldIrql) +{ + PFN_NUMBER PageFrameNumber; + MMPTE TempPte; + DPRINT("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n", + Address, + Process); + + // + // Lock the PFN database + // + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + ASSERT(PointerPte->u.Hard.Valid == 0); + + // + // Get a page + // + PageFrameNumber = MmAllocPage(MC_PPOOL, 0); + DPRINT("New pool page: %lx\n", PageFrameNumber); + + // + // Release PFN lock + // + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + + // + // Increment demand zero faults + // + InterlockedIncrement(&KeGetCurrentPrcb()->MmDemandZeroCount); + + // + // Build the PTE + // + TempPte = HyperTemplatePte; + TempPte.u.Hard.PageFrameNumber = PageFrameNumber; + *PointerPte = TempPte; + ASSERT(PointerPte->u.Hard.Valid == 1); + + // + // It's all good now + // + DPRINT("Paged pool page has now been paged in\n"); + return STATUS_PAGE_FAULT_DEMAND_ZERO; +} + +NTSTATUS +NTAPI +MiDispatchFault(IN BOOLEAN StoreInstruction, + IN PVOID Address, + IN PMMPTE PointerPte, + IN PMMPTE PrototypePte, + IN BOOLEAN Recursive, + IN PEPROCESS Process, + IN PVOID TrapInformation, + IN PVOID Vad) +{ + MMPTE TempPte; + KIRQL OldIrql; + NTSTATUS Status; + DPRINT("ARM3 Page Fault Dispatcher for address: %p in process: %p\n", + Address, + Process); + + // + // Make sure APCs are off and we're not at dispatch + // + OldIrql = KeGetCurrentIrql (); + ASSERT(OldIrql <= APC_LEVEL); + ASSERT(KeAreAllApcsDisabled () == TRUE); + + // + // Grab a copy of the PTE + // + TempPte = *PointerPte; + + // + // The PTE must be invalid, but not totally blank + // + ASSERT(TempPte.u.Hard.Valid == 0); + ASSERT(TempPte.u.Long != 0); + + // + // No prototype, transition or page file software PTEs in ARM3 yet + // + ASSERT(TempPte.u.Soft.Prototype == 0); + ASSERT(TempPte.u.Soft.Transition == 0); + ASSERT(TempPte.u.Soft.PageFileHigh == 0); + + // + // If we got this far, the PTE can only be a demand zero PTE, which is what + // we want. Go handle it! + // + Status = MiResolveDemandZeroFault(Address, + PointerPte, + Process, + -1); + if (NT_SUCCESS(Status)) + { + // + // Make sure we're returning in a sane state and pass the status down + // + ASSERT(OldIrql == KeGetCurrentIrql ()); + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + return Status; + } + + // + // Generate an access fault + // + return STATUS_ACCESS_VIOLATION; +} + +NTSTATUS +NTAPI +MmArmAccessFault(IN BOOLEAN StoreInstruction, + IN PVOID Address, + IN KPROCESSOR_MODE Mode, + IN PVOID TrapInformation) +{ + KIRQL OldIrql = KeGetCurrentIrql(), LockIrql; + PMMPTE PointerPde, PointerPte; + MMPTE TempPte; + PETHREAD CurrentThread; + NTSTATUS Status; + DPRINT("ARM3 FAULT AT: %p\n", Address); + + // + // Get the PTE and PDE + // + PointerPte = MiAddressToPte(Address); + PointerPde = MiAddressToPde(Address); + + // + // Check for dispatch-level snafu + // + if (OldIrql > APC_LEVEL) + { + // + // There are some special cases where this is okay, but not in ARM3 yet + // + DbgPrint("MM:***PAGE FAULT AT IRQL > 1 Va %p, IRQL %lx\n", + Address, + OldIrql); + ASSERT(OldIrql <= APC_LEVEL); + } + + // + // Check for kernel fault + // + if (Address >= MmSystemRangeStart) + { + // + // What are you even DOING here? + // + if (Mode == UserMode) return STATUS_ACCESS_VIOLATION; + + // + // Is the PDE valid? + // + if (!PointerPde->u.Hard.Valid == 0) + { + // + // Debug spew (eww!) + // + DPRINT("Invalid PDE\n"); + + // + // Handle mapping in "Special" PDE directoreis + // + MiCheckPdeForPagedPool(Address); + + // + // Now we SHOULD be good + // + if (PointerPde->u.Hard.Valid == 0) + { + // + // FIXFIX: Do the S-LIST hack + // + + // + // Kill the system + // + KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA, + (ULONG_PTR)Address, + StoreInstruction, + (ULONG_PTR)TrapInformation, + 2); + } + } + + // + // The PDE is valid, so read the PTE + // + TempPte = *PointerPte; + if (TempPte.u.Hard.Valid == 1) + { + // + // Only two things can go wrong here: + // Executing NX page (we couldn't care less) + // Writing to a read-only page (the stuff ARM3 works with is write, + // so again, moot point). + // + if (StoreInstruction) + { + DPRINT1("Should NEVER happen on ARM3!!!\n"); + return STATUS_ACCESS_VIOLATION; + } + + // + // Otherwise, the PDE was probably invalid, and all is good now + // + return STATUS_SUCCESS; + } + + // + // Check for a fault on the page table or hyperspace itself + // FIXME: Use MmHyperSpaceEnd + // + if ((Address >= (PVOID)PTE_BASE) && (Address <= (PVOID)0xC0800000)) + { + // + // This might happen...not sure yet + // + DPRINT1("FAULT ON PAGE TABLES!\n"); + return STATUS_ACCESS_VIOLATION; + } + + // + // Now we must raise to APC_LEVEL and mark the thread as owner + // We don't actually implement a working set pushlock, so this is only + // for internal consistency (and blocking APCs) + // + KeRaiseIrql(APC_LEVEL, &LockIrql); + CurrentThread = PsGetCurrentThread(); + KeEnterGuardedRegion(); + ASSERT((CurrentThread->OwnsSystemWorkingSetExclusive == 0) && + (CurrentThread->OwnsSystemWorkingSetShared == 0)); + CurrentThread->OwnsSystemWorkingSetExclusive = 1; + + // + // Re-read PTE now that the IRQL has been raised + // + TempPte = *PointerPte; + if (TempPte.u.Hard.Valid == 1) + { + // + // Only two things can go wrong here: + // Executing NX page (we couldn't care less) + // Writing to a read-only page (the stuff ARM3 works with is write, + // so again, moot point. + // + if (StoreInstruction) + { + DPRINT1("Should NEVER happen on ARM3!!!\n"); + return STATUS_ACCESS_VIOLATION; + } + + // + // Otherwise, the PDE was probably invalid, and all is good now + // + return STATUS_SUCCESS; + } + + // + // We don't implement prototype PTEs + // + ASSERT(TempPte.u.Soft.Prototype == 0); + + // + // We don't implement transition PTEs + // + ASSERT(TempPte.u.Soft.Transition == 0); + + // + // Now do the real fault handling + // + Status = MiDispatchFault(StoreInstruction, + Address, + PointerPte, + NULL, + FALSE, + NULL, + TrapInformation, + NULL); + + // + // Re-enable APCs + // + ASSERT(KeAreAllApcsDisabled() == TRUE); + CurrentThread->OwnsSystemWorkingSetExclusive = 0; + KeLeaveGuardedRegion(); + KeLowerIrql(LockIrql); + + // + // We are done! + // + DPRINT("Fault resolved with status: %lx\n", Status); + return Status; + } + + // + // DIE DIE DIE + // + DPRINT1("WARNING: USER MODE FAULT IN ARM3???\n"); + return STATUS_ACCESS_VIOLATION; +} + +/* EOF */ diff --git a/reactos/ntoskrnl/mm/ARM3/pool.c b/reactos/ntoskrnl/mm/ARM3/pool.c index d4f4b75f17e..889ed0a148e 100644 --- a/reactos/ntoskrnl/mm/ARM3/pool.c +++ b/reactos/ntoskrnl/mm/ARM3/pool.c @@ -22,7 +22,7 @@ LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]; PFN_NUMBER MmNumberOfFreeNonPagedPool, MiExpansionPoolPagesInitialCharge; PVOID MmNonPagedPoolEnd0; PFN_NUMBER MiStartOfInitialPoolFrame, MiEndOfInitialPoolFrame; - +KGUARDED_MUTEX MmPagedPoolMutex; MM_PAGED_POOL_INFO MmPagedPoolInfo; /* PRIVATE FUNCTIONS **********************************************************/ @@ -148,6 +148,83 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // SizeInPages = BYTES_TO_PAGES(SizeInBytes); + // + // Handle paged pool + // + if (PoolType == PagedPool) + { + // + // Lock the paged pool mutex + // + KeAcquireGuardedMutex(&MmPagedPoolMutex); + + // + // Find some empty allocation space + // + i = RtlFindClearBitsAndSet(MmPagedPoolInfo.PagedPoolAllocationMap, + SizeInPages, + MmPagedPoolInfo.PagedPoolHint); + if (i == 0xFFFFFFFF) + { + // + // Out of memory! + // + DPRINT1("OUT OF PAGED POOL!!!\n"); + KeReleaseGuardedMutex(&MmPagedPoolMutex); + return NULL; + } + + // + // Update the pool hint if the request was just one page + // + if (SizeInPages == 1) MmPagedPoolInfo.PagedPoolHint = i + 1; + + // + // Update the end bitmap so we know the bounds of this allocation when + // the time comes to free it + // + RtlSetBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, i + SizeInPages - 1); + + // + // Now we can release the lock (it mainly protects the bitmap) + // + KeReleaseGuardedMutex(&MmPagedPoolMutex); + + // + // Now figure out where this allocation starts + // + BaseVa = (PVOID)((ULONG_PTR)MmPagedPoolStart + (i << PAGE_SHIFT)); + + // + // Flush the TLB + // + KeFlushEntireTb(TRUE, TRUE); + + // + // Setup a demand-zero writable PTE + // + TempPte.u.Long = 0; + MI_MAKE_WRITE_PAGE(&TempPte); + + // + // Find the first and last PTE, then loop them all + // + PointerPte = MiAddressToPte(BaseVa); + StartPte = PointerPte + SizeInPages; + do + { + // + // Write the demand zero PTE and keep going + // + *PointerPte++ = TempPte; + } while (PointerPte < StartPte); + + // + // Return the allocation address to the caller + // + return BaseVa; + } + // // Allocations of less than 4 pages go into their individual buckets // @@ -346,7 +423,57 @@ MiFreePoolPages(IN PVOID StartingVa) PFN_NUMBER FreePages, NumberOfPages; KIRQL OldIrql; PMMFREE_POOL_ENTRY FreeEntry, NextEntry, LastEntry; - ULONG i; + ULONG i, End; + + // + // Handle paged pool + // + if ((StartingVa >= MmPagedPoolStart) && (StartingVa <= MmPagedPoolEnd)) + { + // + // Calculate the offset from the beginning of paged pool, and convert it + // into pages + // + i = ((ULONG_PTR)StartingVa - (ULONG_PTR)MmPagedPoolStart) >> PAGE_SHIFT; + End = i; + + // + // Now use the end bitmap to scan until we find a set bit, meaning that + // this allocation finishes here + // + while (!RtlTestBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, End)) End++; + + // + // Now calculate the total number of pages this allocation spans + // + NumberOfPages = End - i + 1; + + // + // Acquire the paged pool lock + // + KeAcquireGuardedMutex(&MmPagedPoolMutex); + + // + // Clear the allocation and free bits + // + RtlClearBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, i); + RtlClearBits(MmPagedPoolInfo.PagedPoolAllocationMap, i, NumberOfPages); + + // + // Update the hint if we need to + // + if (i < MmPagedPoolInfo.PagedPoolHint) MmPagedPoolInfo.PagedPoolHint = i; + + // + // Release the lock protecting the bitmaps + // + KeReleaseGuardedMutex(&MmPagedPoolMutex); + + // + // And finally return the number of pages freed + // + return NumberOfPages; + } // // Get the first PTE and its corresponding PFN entry @@ -584,4 +711,44 @@ MiFreePoolPages(IN PVOID StartingVa) return NumberOfPages; } + +BOOLEAN +NTAPI +MiRaisePoolQuota(IN POOL_TYPE PoolType, + IN ULONG CurrentMaxQuota, + OUT PULONG NewMaxQuota) +{ + // + // Not implemented + // + UNIMPLEMENTED; + *NewMaxQuota = CurrentMaxQuota + 65536; + return TRUE; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @unimplemented + */ +PVOID +NTAPI +MmAllocateMappingAddress(IN SIZE_T NumberOfBytes, + IN ULONG PoolTag) +{ + UNIMPLEMENTED; + return NULL; +} + +/* + * @unimplemented + */ +VOID +NTAPI +MmFreeMappingAddress(IN PVOID BaseAddress, + IN ULONG PoolTag) +{ + UNIMPLEMENTED; +} + /* EOF */ diff --git a/reactos/ntoskrnl/mm/ARM3/procsup.c b/reactos/ntoskrnl/mm/ARM3/procsup.c index 919b3e43de4..6064686d2b4 100644 --- a/reactos/ntoskrnl/mm/ARM3/procsup.c +++ b/reactos/ntoskrnl/mm/ARM3/procsup.c @@ -16,6 +16,13 @@ #define MODULE_INVOLVED_IN_ARM3 #include "../ARM3/miarm.h" +extern MM_SYSTEMSIZE MmSystemSize; + +PVOID +NTAPI +MiCreatePebOrTeb(PEPROCESS Process, + PVOID BaseAddress); + /* PRIVATE FUNCTIONS **********************************************************/ VOID @@ -278,4 +285,454 @@ MmGrowKernelStack(IN PVOID StackPointer) return MmGrowKernelStackEx(StackPointer, KERNEL_LARGE_STACK_COMMIT); } +NTSTATUS +NTAPI +MmSetMemoryPriorityProcess(IN PEPROCESS Process, + IN UCHAR MemoryPriority) +{ + UCHAR OldPriority; + + // + // Check if we have less then 16MB of Physical Memory + // + if ((MmSystemSize == MmSmallSystem) && + (MmNumberOfPhysicalPages < ((15 * 1024 * 1024) / PAGE_SIZE))) + { + // + // Always use background priority + // + MemoryPriority = MEMORY_PRIORITY_BACKGROUND; + } + + // + // Save the old priority and update it + // + OldPriority = (UCHAR)Process->Vm.Flags.MemoryPriority; + Process->Vm.Flags.MemoryPriority = MemoryPriority; + + // + // Return the old priority + // + return OldPriority; +} + +LCID +NTAPI +MmGetSessionLocaleId(VOID) +{ + PEPROCESS Process; + PAGED_CODE(); + + // + // Get the current process + // + Process = PsGetCurrentProcess(); + + // + // Check if it's the Session Leader + // + if (Process->Vm.Flags.SessionLeader) + { + // + // Make sure it has a valid Session + // + if (Process->Session) + { + // + // Get the Locale ID + // +#if ROS_HAS_SESSIONS + return ((PMM_SESSION_SPACE)Process->Session)->LocaleId; +#endif + } + } + + // + // Not a session leader, return the default + // + return PsDefaultThreadLocaleId; +} + +NTSTATUS +NTAPI +MmCreatePeb(IN PEPROCESS Process, + IN PINITIAL_PEB InitialPeb, + OUT PPEB *BasePeb) +{ + PPEB Peb = NULL; + LARGE_INTEGER SectionOffset; + SIZE_T ViewSize = 0; + PVOID TableBase = NULL; + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData; + NTSTATUS Status; + USHORT Characteristics; + KAFFINITY ProcessAffinityMask = 0; + SectionOffset.QuadPart = (ULONGLONG)0; + *BasePeb = NULL; + + // + // Attach to Process + // + KeAttachProcess(&Process->Pcb); + + // + // Allocate the PEB + // + Peb = MiCreatePebOrTeb(Process, + (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); + ASSERT(Peb == (PVOID)0x7FFDF000); + + // + // Map NLS Tables + // + Status = MmMapViewOfSection(ExpNlsSectionPointer, + (PEPROCESS)Process, + &TableBase, + 0, + 0, + &SectionOffset, + &ViewSize, + ViewShare, + MEM_TOP_DOWN, + PAGE_READONLY); + if (!NT_SUCCESS(Status)) return Status; + + // + // Use SEH in case we can't load the PEB + // + _SEH2_TRY + { + // + // Initialize the PEB + // + RtlZeroMemory(Peb, sizeof(PEB)); + + // + // Set up data + // + Peb->ImageBaseAddress = Process->SectionBaseAddress; + Peb->InheritedAddressSpace = InitialPeb->InheritedAddressSpace; + Peb->Mutant = InitialPeb->Mutant; + Peb->ImageUsesLargePages = InitialPeb->ImageUsesLargePages; + + // + // NLS + // + 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; + Peb->OSMinorVersion = NtMinorVersion; + Peb->OSBuildNumber = (USHORT)(NtBuildNumber & 0x3FFF); + Peb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */ + Peb->OSCSDVersion = (USHORT)CmNtCSDVersion; + + // + // Heap and Debug Data + // + Peb->NumberOfProcessors = KeNumberProcessors; + Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL ? TRUE : FALSE); + Peb->NtGlobalFlag = NtGlobalFlag; + /*Peb->HeapSegmentReserve = MmHeapSegmentReserve; + Peb->HeapSegmentCommit = MmHeapSegmentCommit; + Peb->HeapDeCommitTotalFreeThreshold = MmHeapDeCommitTotalFreeThreshold; + Peb->HeapDeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold; + Peb->CriticalSectionTimeout = MmCriticalSectionTimeout; + Peb->MinimumStackCommit = MmMinimumStackCommitInBytes; + */ + Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID); + Peb->ProcessHeaps = (PVOID*)(Peb + 1); + + // + // Session ID + // + if (Process->Session) Peb->SessionId = 0; // MmGetSessionId(Process); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Fail + // + KeDetachProcess(); + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + // + // Use SEH in case we can't load the image + // + _SEH2_TRY + { + // + // Get NT Headers + // + NtHeaders = RtlImageNtHeader(Peb->ImageBaseAddress); + Characteristics = NtHeaders->FileHeader.Characteristics; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Fail + // + KeDetachProcess(); + _SEH2_YIELD(return STATUS_INVALID_IMAGE_PROTECT); + } + _SEH2_END; + + // + // Parse the headers + // + if (NtHeaders) + { + // + // Use SEH in case we can't load the headers + // + _SEH2_TRY + { + // + // Get the Image Config Data too + // + ImageConfigData = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, + &ViewSize); + if (ImageConfigData) + { + // + // Probe it + // + ProbeForRead(ImageConfigData, + sizeof(IMAGE_LOAD_CONFIG_DIRECTORY), + sizeof(ULONG)); + } + + // + // Write subsystem data + // + Peb->ImageSubSystem = NtHeaders->OptionalHeader.Subsystem; + Peb->ImageSubSystemMajorVersion = NtHeaders->OptionalHeader.MajorSubsystemVersion; + Peb->ImageSubSystemMinorVersion = NtHeaders->OptionalHeader.MinorSubsystemVersion; + + // + // Check for version data + // + if (NtHeaders->OptionalHeader.Win32VersionValue) + { + // + // Extract values and write them + // + Peb->OSMajorVersion = NtHeaders->OptionalHeader.Win32VersionValue & 0xFF; + Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF; + Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF; + Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2; + } + + // + // Process the image config data overrides if specfied + // + if (ImageConfigData != NULL) + { + // + // Process CSD version override + // + if (ImageConfigData->CSDVersion) + { + // + // Set new data + // + Peb->OSCSDVersion = ImageConfigData->CSDVersion; + } + + // + // Process affinity mask ovverride + // + if (ImageConfigData->ProcessAffinityMask) + { + // + // Set new data + // + ProcessAffinityMask = ImageConfigData->ProcessAffinityMask; + } + } + + // + // Check if this is a UP image + if (Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) + { + // + // Force it to use CPU 0 + // + Peb->ImageProcessAffinityMask = 0; + } + else + { + // + // Whatever was configured + // + Peb->ImageProcessAffinityMask = ProcessAffinityMask; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Fail + // + KeDetachProcess(); + _SEH2_YIELD(return STATUS_INVALID_IMAGE_PROTECT); + } + _SEH2_END; + } + + // + // Detach from the Process + // + KeDetachProcess(); + *BasePeb = Peb; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +MmCreateTeb(IN PEPROCESS Process, + IN PCLIENT_ID ClientId, + IN PINITIAL_TEB InitialTeb, + OUT PTEB *BaseTeb) +{ + PTEB Teb; + NTSTATUS Status = STATUS_SUCCESS; + *BaseTeb = NULL; + + // + // Attach to Target + // + KeAttachProcess(&Process->Pcb); + + // + // Allocate the TEB + // + Teb = MiCreatePebOrTeb(Process, + (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); + if (!Teb) return STATUS_INSUFFICIENT_RESOURCES; + + // + // Use SEH in case we can't load the TEB + // + _SEH2_TRY + { + // + // Initialize the PEB + // + RtlZeroMemory(Teb, sizeof(TEB)); + + // + // Set TIB Data + // + Teb->Tib.ExceptionList = EXCEPTION_CHAIN_END; + Teb->Tib.Self = (PNT_TIB)Teb; + + // + // Identify this as an OS/2 V3.0 ("Cruiser") TIB + // + Teb->Tib.Version = 30 << 8; + + // + // Set TEB Data + // + Teb->ClientId = *ClientId; + Teb->RealClientId = *ClientId; + Teb->ProcessEnvironmentBlock = Process->Peb; + Teb->CurrentLocale = PsDefaultThreadLocaleId; + + // + // Check if we have a grandparent TEB + // + if ((InitialTeb->PreviousStackBase == NULL) && + (InitialTeb->PreviousStackLimit == NULL)) + { + // + // Use initial TEB values + // + Teb->Tib.StackBase = InitialTeb->StackBase; + Teb->Tib.StackLimit = InitialTeb->StackLimit; + Teb->DeallocationStack = InitialTeb->AllocatedStackBase; + } + else + { + // + // Use grandparent TEB values + // + Teb->Tib.StackBase = InitialTeb->PreviousStackBase; + Teb->Tib.StackLimit = InitialTeb->PreviousStackLimit; + } + + // + // Initialize the static unicode string + // + Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer); + Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get error code + // + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + // + // Return + // + KeDetachProcess(); + *BaseTeb = Teb; + return Status; +} + +/* SYSTEM CALLS ***************************************************************/ + +NTSTATUS +NTAPI +NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle, + IN OUT PULONG_PTR NumberOfPages, + IN OUT PULONG_PTR UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtMapUserPhysicalPages(IN PVOID VirtualAddresses, + IN ULONG_PTR NumberOfPages, + IN OUT PULONG_PTR UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses, + IN ULONG_PTR NumberOfPages, + IN OUT PULONG_PTR UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtFreeUserPhysicalPages(IN HANDLE ProcessHandle, + IN OUT PULONG_PTR NumberOfPages, + IN OUT PULONG_PTR UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + /* EOF */ diff --git a/reactos/ntoskrnl/mm/ARM3/syspte.c b/reactos/ntoskrnl/mm/ARM3/syspte.c index b9500477ba4..bbb385e5702 100644 --- a/reactos/ntoskrnl/mm/ARM3/syspte.c +++ b/reactos/ntoskrnl/mm/ARM3/syspte.c @@ -109,7 +109,6 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, // Decrement the free count and move to the next starting PTE // MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes; - KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql); PointerPte += (ClusterSize - NumberOfPtes); break; } @@ -158,8 +157,9 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, } // - // Flush the TLB and return the first PTE + // Release the lock, flush the TLB and return the first PTE // + KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql); KeFlushProcessTb(); return PointerPte; } diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c new file mode 100644 index 00000000000..d10bf87d417 --- /dev/null +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -0,0 +1,1757 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/mm/ARM3/virtual.c + * PURPOSE: ARM Memory Manager Virtual Memory Management + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +#line 15 "ARMÂł::VIRTUAL" +#define MODULE_INVOLVED_IN_ARM3 +#include "../ARM3/miarm.h" + +#define MI_MAPPED_COPY_PAGES 14 +#define MI_POOL_COPY_BYTES 512 +#define MI_MAX_TRANSFER_SIZE 64 * 1024 + +NTSTATUS NTAPI +MiProtectVirtualMemory(IN PEPROCESS Process, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T NumberOfBytesToProtect, + IN ULONG NewAccessProtection, + OUT PULONG OldAccessProtection OPTIONAL); + +/* PRIVATE FUNCTIONS **********************************************************/ + +LONG +MiGetExceptionInfo(IN PEXCEPTION_POINTERS ExceptionInfo, + OUT PBOOLEAN HaveBadAddress, + OUT PULONG_PTR BadAddress) +{ + PEXCEPTION_RECORD ExceptionRecord; + PAGED_CODE(); + + // + // Assume default + // + *HaveBadAddress = FALSE; + + // + // Get the exception record + // + ExceptionRecord = ExceptionInfo->ExceptionRecord; + + // + // Look at the exception code + // + if ((ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) || + (ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) || + (ExceptionRecord->ExceptionCode == STATUS_IN_PAGE_ERROR)) + { + // + // We can tell the address if we have more than one parameter + // + if (ExceptionRecord->NumberParameters > 1) + { + // + // Return the address + // + *HaveBadAddress = TRUE; + *BadAddress = ExceptionRecord->ExceptionInformation[1]; + } + } + + // + // Continue executing the next handler + // + return EXCEPTION_EXECUTE_HANDLER; +} + +NTSTATUS +NTAPI +MiDoMappedCopy(IN PEPROCESS SourceProcess, + IN PVOID SourceAddress, + IN PEPROCESS TargetProcess, + OUT PVOID TargetAddress, + IN SIZE_T BufferSize, + IN KPROCESSOR_MODE PreviousMode, + OUT PSIZE_T ReturnSize) +{ + PFN_NUMBER MdlBuffer[(sizeof(MDL) / sizeof(PFN_NUMBER)) + MI_MAPPED_COPY_PAGES + 1]; + PMDL Mdl = (PMDL)MdlBuffer; + SIZE_T TotalSize, CurrentSize, RemainingSize; + volatile BOOLEAN FailedInProbe = FALSE, FailedInMapping = FALSE, FailedInMoving; + volatile BOOLEAN PagesLocked; + PVOID CurrentAddress = SourceAddress, CurrentTargetAddress = TargetAddress; + volatile PVOID MdlAddress; + KAPC_STATE ApcState; + BOOLEAN HaveBadAddress; + ULONG_PTR BadAddress; + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + // + // Calculate the maximum amount of data to move + // + TotalSize = MI_MAPPED_COPY_PAGES * PAGE_SIZE; + if (BufferSize <= TotalSize) TotalSize = BufferSize; + CurrentSize = TotalSize; + RemainingSize = BufferSize; + + // + // Loop as long as there is still data + // + while (RemainingSize > 0) + { + // + // Check if this transfer will finish everything off + // + if (RemainingSize < CurrentSize) CurrentSize = RemainingSize; + + // + // Attach to the source address space + // + KeStackAttachProcess(&SourceProcess->Pcb, &ApcState); + + // + // Reset state for this pass + // + MdlAddress = NULL; + PagesLocked = FALSE; + FailedInMoving = FALSE; + ASSERT(FailedInProbe == FALSE); + + // + // Protect user-mode copy + // + _SEH2_TRY + { + // + // If this is our first time, probe the buffer + // + if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode)) + { + // + // Catch a failure here + // + FailedInProbe = TRUE; + + // + // Do the probe + // + ProbeForRead(SourceAddress, BufferSize, sizeof(CHAR)); + + // + // Passed + // + FailedInProbe = FALSE; + } + + // + // Initialize and probe and lock the MDL + // + MmInitializeMdl(Mdl, CurrentAddress, CurrentSize); + MmProbeAndLockPages(Mdl, PreviousMode, IoReadAccess); + PagesLocked = TRUE; + + // + // Now map the pages + // + MdlAddress = MmMapLockedPagesSpecifyCache(Mdl, + KernelMode, + MmCached, + NULL, + FALSE, + HighPagePriority); + if (!MdlAddress) + { + // + // Use our SEH handler to pick this up + // + FailedInMapping = TRUE; + ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); + } + + // + // Now let go of the source and grab to the target process + // + KeUnstackDetachProcess(&ApcState); + KeStackAttachProcess(&TargetProcess->Pcb, &ApcState); + + // + // Check if this is our first time through + // + if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode)) + { + // + // Catch a failure here + // + FailedInProbe = TRUE; + + // + // Do the probe + // + ProbeForWrite(TargetAddress, BufferSize, sizeof(CHAR)); + + // + // Passed + // + FailedInProbe = FALSE; + } + + // + // Now do the actual move + // + FailedInMoving = TRUE; + RtlCopyMemory(CurrentTargetAddress, MdlAddress, CurrentSize); + } + _SEH2_EXCEPT(MiGetExceptionInfo(_SEH2_GetExceptionInformation(), + &HaveBadAddress, + &BadAddress)) + { + // + // Detach from whoever we may be attached to + // + KeUnstackDetachProcess(&ApcState); + + // + // Check if we had mapped the pages + // + if (MdlAddress) MmUnmapLockedPages(MdlAddress, Mdl); + + // + // Check if we had locked the pages + // + if (PagesLocked) MmUnlockPages(Mdl); + + // + // Check if we hit working set quota + // + if (_SEH2_GetExceptionCode() == STATUS_WORKING_SET_QUOTA) + { + // + // Return the error + // + return STATUS_WORKING_SET_QUOTA; + } + + // + // Check if we failed during the probe or mapping + // + if ((FailedInProbe) || (FailedInMapping)) + { + // + // Exit + // + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(return Status); + } + + // + // Otherwise, we failed probably during the move + // + *ReturnSize = BufferSize - RemainingSize; + if (FailedInMoving) + { + // + // Check if we know exactly where we stopped copying + // + if (HaveBadAddress) + { + // + // Return the exact number of bytes copied + // + *ReturnSize = BadAddress - (ULONG_PTR)SourceAddress; + } + } + + // + // Return partial copy + // + Status = STATUS_PARTIAL_COPY; + } + _SEH2_END; + + // + // Check for SEH status + // + if (Status != STATUS_SUCCESS) return Status; + + // + // Detach from target + // + KeUnstackDetachProcess(&ApcState); + + // + // Unmap and unlock + // + MmUnmapLockedPages(MdlAddress, Mdl); + MmUnlockPages(Mdl); + + // + // Update location and size + // + RemainingSize -= CurrentSize; + CurrentAddress = (PVOID)((ULONG_PTR)CurrentAddress + CurrentSize); + CurrentTargetAddress = (PVOID)((ULONG_PTR)CurrentTargetAddress + CurrentSize); + } + + // + // All bytes read + // + *ReturnSize = BufferSize; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +MiDoPoolCopy(IN PEPROCESS SourceProcess, + IN PVOID SourceAddress, + IN PEPROCESS TargetProcess, + OUT PVOID TargetAddress, + IN SIZE_T BufferSize, + IN KPROCESSOR_MODE PreviousMode, + OUT PSIZE_T ReturnSize) +{ + UCHAR StackBuffer[MI_POOL_COPY_BYTES]; + SIZE_T TotalSize, CurrentSize, RemainingSize; + volatile BOOLEAN FailedInProbe = FALSE, FailedInMoving, HavePoolAddress = FALSE; + PVOID CurrentAddress = SourceAddress, CurrentTargetAddress = TargetAddress; + PVOID PoolAddress; + KAPC_STATE ApcState; + BOOLEAN HaveBadAddress; + ULONG_PTR BadAddress; + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + // + // Calculate the maximum amount of data to move + // + TotalSize = MI_MAX_TRANSFER_SIZE; + if (BufferSize <= MI_MAX_TRANSFER_SIZE) TotalSize = BufferSize; + CurrentSize = TotalSize; + RemainingSize = BufferSize; + + // + // Check if we can use the stack + // + if (BufferSize <= MI_POOL_COPY_BYTES) + { + // + // Use it + // + PoolAddress = (PVOID)StackBuffer; + } + else + { + // + // Allocate pool + // + PoolAddress = ExAllocatePoolWithTag(NonPagedPool, TotalSize, 'VmRw'); + if (!PoolAddress) ASSERT(FALSE); + HavePoolAddress = TRUE; + } + + // + // Loop as long as there is still data + // + while (RemainingSize > 0) + { + // + // Check if this transfer will finish everything off + // + if (RemainingSize < CurrentSize) CurrentSize = RemainingSize; + + // + // Attach to the source address space + // + KeStackAttachProcess(&SourceProcess->Pcb, &ApcState); + + // + // Reset state for this pass + // + FailedInMoving = FALSE; + ASSERT(FailedInProbe == FALSE); + + // + // Protect user-mode copy + // + _SEH2_TRY + { + // + // If this is our first time, probe the buffer + // + if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode)) + { + // + // Catch a failure here + // + FailedInProbe = TRUE; + + // + // Do the probe + // + ProbeForRead(SourceAddress, BufferSize, sizeof(CHAR)); + + // + // Passed + // + FailedInProbe = FALSE; + } + + // + // Do the copy + // + RtlCopyMemory(PoolAddress, CurrentAddress, CurrentSize); + + // + // Now let go of the source and grab to the target process + // + KeUnstackDetachProcess(&ApcState); + KeStackAttachProcess(&TargetProcess->Pcb, &ApcState); + + // + // Check if this is our first time through + // + if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode)) + { + // + // Catch a failure here + // + FailedInProbe = TRUE; + + // + // Do the probe + // + ProbeForWrite(TargetAddress, BufferSize, sizeof(CHAR)); + + // + // Passed + // + FailedInProbe = FALSE; + } + + // + // Now do the actual move + // + FailedInMoving = TRUE; + RtlCopyMemory(CurrentTargetAddress, PoolAddress, CurrentSize); + } + _SEH2_EXCEPT(MiGetExceptionInfo(_SEH2_GetExceptionInformation(), + &HaveBadAddress, + &BadAddress)) + { + // + // Detach from whoever we may be attached to + // + KeUnstackDetachProcess(&ApcState); + + // + // Check if we had allocated pool + // + if (HavePoolAddress) ExFreePool(PoolAddress); + + // + // Check if we failed during the probe + // + if (FailedInProbe) + { + // + // Exit + // + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(return Status); + } + + // + // Otherwise, we failed, probably during the move + // + *ReturnSize = BufferSize - RemainingSize; + if (FailedInMoving) + { + // + // Check if we know exactly where we stopped copying + // + if (HaveBadAddress) + { + // + // Return the exact number of bytes copied + // + *ReturnSize = BadAddress - (ULONG_PTR)SourceAddress; + } + } + + // + // Return partial copy + // + Status = STATUS_PARTIAL_COPY; + } + _SEH2_END; + + // + // Check for SEH status + // + if (Status != STATUS_SUCCESS) return Status; + + // + // Detach from target + // + KeUnstackDetachProcess(&ApcState); + + // + // Update location and size + // + RemainingSize -= CurrentSize; + CurrentAddress = (PVOID)((ULONG_PTR)CurrentAddress + CurrentSize); + CurrentTargetAddress = (PVOID)((ULONG_PTR)CurrentTargetAddress + + CurrentSize); + } + + // + // Check if we had allocated pool + // + if (HavePoolAddress) ExFreePool(PoolAddress); + + // + // All bytes read + // + *ReturnSize = BufferSize; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +MmCopyVirtualMemory(IN PEPROCESS SourceProcess, + IN PVOID SourceAddress, + IN PEPROCESS TargetProcess, + OUT PVOID TargetAddress, + IN SIZE_T BufferSize, + IN KPROCESSOR_MODE PreviousMode, + OUT PSIZE_T ReturnSize) +{ + NTSTATUS Status; + PEPROCESS Process = SourceProcess; + + // + // Don't accept zero-sized buffers + // + if (!BufferSize) return STATUS_SUCCESS; + + // + // If we are copying from ourselves, lock the target instead + // + if (SourceProcess == PsGetCurrentProcess()) Process = TargetProcess; + + // + // Acquire rundown protection + // + if (!ExAcquireRundownProtection(&Process->RundownProtect)) + { + // + // Fail + // + return STATUS_PROCESS_IS_TERMINATING; + } + + // + // See if we should use the pool copy + // + if (BufferSize > MI_POOL_COPY_BYTES) + { + // + // Use MDL-copy + // + Status = MiDoMappedCopy(SourceProcess, + SourceAddress, + TargetProcess, + TargetAddress, + BufferSize, + PreviousMode, + ReturnSize); + } + else + { + // + // Do pool copy + // + Status = MiDoPoolCopy(SourceProcess, + SourceAddress, + TargetProcess, + TargetAddress, + BufferSize, + PreviousMode, + ReturnSize); + } + + // + // Release the lock + // + ExReleaseRundownProtection(&Process->RundownProtect); + return Status; +} + +NTSTATUS +NTAPI +MmFlushVirtualMemory(IN PEPROCESS Process, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T RegionSize, + OUT PIO_STATUS_BLOCK IoStatusBlock) +{ + PAGED_CODE(); + UNIMPLEMENTED; + + // + // Fake success + // + return STATUS_SUCCESS; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @unimplemented + */ +PVOID +NTAPI +MmGetVirtualForPhysical(IN PHYSICAL_ADDRESS PhysicalAddress) +{ + UNIMPLEMENTED; + return 0; +} + +/* + * @unimplemented + */ +PVOID +NTAPI +MmSecureVirtualMemory(IN PVOID Address, + IN SIZE_T Length, + IN ULONG Mode) +{ + UNIMPLEMENTED; + return NULL; +} + +/* + * @unimplemented + */ +VOID +NTAPI +MmUnsecureVirtualMemory(IN PVOID SecureMem) +{ + UNIMPLEMENTED; +} + +/* SYSTEM CALLS ***************************************************************/ + +NTSTATUS +NTAPI +NtReadVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + OUT PVOID Buffer, + IN SIZE_T NumberOfBytesToRead, + OUT PSIZE_T NumberOfBytesRead OPTIONAL) +{ + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PEPROCESS Process; + NTSTATUS Status = STATUS_SUCCESS; + SIZE_T BytesRead = 0; + PAGED_CODE(); + + // + // Check if we came from user mode + // + if (PreviousMode != KernelMode) + { + // + // Validate the read addresses + // + if ((((ULONG_PTR)BaseAddress + NumberOfBytesToRead) < (ULONG_PTR)BaseAddress) || + (((ULONG_PTR)Buffer + NumberOfBytesToRead) < (ULONG_PTR)Buffer) || + (((ULONG_PTR)BaseAddress + NumberOfBytesToRead) > MmUserProbeAddress) || + (((ULONG_PTR)Buffer + NumberOfBytesToRead) > MmUserProbeAddress)) + { + // + // Don't allow to write into kernel space + // + return STATUS_ACCESS_VIOLATION; + } + + // + // Enter SEH for probe + // + _SEH2_TRY + { + // + // Probe the output value + // + if (NumberOfBytesRead) ProbeForWriteSize_t(NumberOfBytesRead); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + + // + // Don't do zero-byte transfers + // + if (NumberOfBytesToRead) + { + // + // Reference the process + // + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_READ, + PsProcessType, + PreviousMode, + (PVOID*)(&Process), + NULL); + if (NT_SUCCESS(Status)) + { + // + // Do the copy + // + Status = MmCopyVirtualMemory(Process, + BaseAddress, + PsGetCurrentProcess(), + Buffer, + NumberOfBytesToRead, + PreviousMode, + &BytesRead); + + // + // Dereference the process + // + ObDereferenceObject(Process); + } + } + + // + // Check if the caller sent this parameter + // + if (NumberOfBytesRead) + { + // + // Enter SEH to guard write + // + _SEH2_TRY + { + // + // Return the number of bytes read + // + *NumberOfBytesRead = BytesRead; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; + } + + // + // Return status + // + return Status; +} + +NTSTATUS +NTAPI +NtWriteVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN PVOID Buffer, + IN SIZE_T NumberOfBytesToWrite, + OUT PSIZE_T NumberOfBytesWritten OPTIONAL) +{ + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PEPROCESS Process; + NTSTATUS Status = STATUS_SUCCESS; + ULONG BytesWritten = 0; + PAGED_CODE(); + + // + // Check if we came from user mode + // + if (PreviousMode != KernelMode) + { + // + // Validate the read addresses + // + if ((((ULONG_PTR)BaseAddress + NumberOfBytesToWrite) < (ULONG_PTR)BaseAddress) || + (((ULONG_PTR)Buffer + NumberOfBytesToWrite) < (ULONG_PTR)Buffer) || + (((ULONG_PTR)BaseAddress + NumberOfBytesToWrite) > MmUserProbeAddress) || + (((ULONG_PTR)Buffer + NumberOfBytesToWrite) > MmUserProbeAddress)) + { + // + // Don't allow to write into kernel space + // + return STATUS_ACCESS_VIOLATION; + } + + // + // Enter SEH for probe + // + _SEH2_TRY + { + // + // Probe the output value + // + if (NumberOfBytesWritten) ProbeForWriteSize_t(NumberOfBytesWritten); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + + // + // Don't do zero-byte transfers + // + if (NumberOfBytesToWrite) + { + // + // Reference the process + // + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_WRITE, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (NT_SUCCESS(Status)) + { + // + // Do the copy + // + Status = MmCopyVirtualMemory(PsGetCurrentProcess(), + Buffer, + Process, + BaseAddress, + NumberOfBytesToWrite, + PreviousMode, + &BytesWritten); + + // + // Dereference the process + // + ObDereferenceObject(Process); + } + } + + // + // Check if the caller sent this parameter + // + if (NumberOfBytesWritten) + { + // + // Enter SEH to guard write + // + _SEH2_TRY + { + // + // Return the number of bytes written + // + *NumberOfBytesWritten = BytesWritten; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; + } + + // + // Return status + // + return Status; +} + +NTSTATUS +NTAPI +NtProtectVirtualMemory(IN HANDLE ProcessHandle, + IN OUT PVOID *UnsafeBaseAddress, + IN OUT SIZE_T *UnsafeNumberOfBytesToProtect, + IN ULONG NewAccessProtection, + OUT PULONG UnsafeOldAccessProtection) +{ + PEPROCESS Process; + ULONG OldAccessProtection; + ULONG Protection; + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + PVOID BaseAddress = NULL; + SIZE_T NumberOfBytesToProtect = 0; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status; + BOOLEAN Attached = FALSE; + KAPC_STATE ApcState; + PAGED_CODE(); + + // + // Check for valid protection flags + // + Protection = NewAccessProtection & ~(PAGE_GUARD|PAGE_NOCACHE); + if (Protection != PAGE_NOACCESS && + Protection != PAGE_READONLY && + Protection != PAGE_READWRITE && + Protection != PAGE_WRITECOPY && + Protection != PAGE_EXECUTE && + Protection != PAGE_EXECUTE_READ && + Protection != PAGE_EXECUTE_READWRITE && + Protection != PAGE_EXECUTE_WRITECOPY) + { + // + // Fail + // + return STATUS_INVALID_PAGE_PROTECTION; + } + + // + // Check if we came from user mode + // + if (PreviousMode != KernelMode) + { + // + // Enter SEH for probing + // + _SEH2_TRY + { + // + // Validate all outputs + // + ProbeForWritePointer(UnsafeBaseAddress); + ProbeForWriteSize_t(UnsafeNumberOfBytesToProtect); + ProbeForWriteUlong(UnsafeOldAccessProtection); + + // + // Capture them + // + BaseAddress = *UnsafeBaseAddress; + NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + // + // Capture directly + // + BaseAddress = *UnsafeBaseAddress; + NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect; + } + + // + // Catch illegal base address + // + if (BaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER_2; + + // + // Catch illegal region size + // + if ((MmUserProbeAddress - (ULONG_PTR)BaseAddress) < NumberOfBytesToProtect) + { + // + // Fail + // + return STATUS_INVALID_PARAMETER_3; + } + + // + // 0 is also illegal + // + if (!NumberOfBytesToProtect) return STATUS_INVALID_PARAMETER_3; + + // + // Get a reference to the process + // + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_OPERATION, + PsProcessType, + PreviousMode, + (PVOID*)(&Process), + NULL); + if (!NT_SUCCESS(Status)) return Status; + + // + // Check if we should attach + // + if (CurrentProcess != Process) + { + // + // Do it + // + KeStackAttachProcess(&Process->Pcb, &ApcState); + Attached = TRUE; + } + + // + // Do the actual work + // + Status = MiProtectVirtualMemory(Process, + &BaseAddress, + &NumberOfBytesToProtect, + NewAccessProtection, + &OldAccessProtection); + + // + // Detach if needed + // + if (Attached) KeUnstackDetachProcess(&ApcState); + + // + // Release reference + // + ObDereferenceObject(Process); + + // + // Enter SEH to return data + // + _SEH2_TRY + { + // + // Return data to user + // + *UnsafeOldAccessProtection = OldAccessProtection; + *UnsafeBaseAddress = BaseAddress; + *UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; + + // + // Return status + // + return Status; +} + +NTSTATUS +NTAPI +NtLockVirtualMemory(IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T NumberOfBytesToLock, + IN ULONG MapType) +{ + PEPROCESS Process; + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + NTSTATUS Status; + BOOLEAN Attached = FALSE; + KAPC_STATE ApcState; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PVOID CapturedBaseAddress; + SIZE_T CapturedBytesToLock; + PAGED_CODE(); + + // + // Validate flags + // + if ((MapType & ~(MAP_PROCESS | MAP_SYSTEM))) + { + // + // Invalid set of flags + // + return STATUS_INVALID_PARAMETER; + } + + // + // At least one flag must be specified + // + if (!(MapType & (MAP_PROCESS | MAP_SYSTEM))) + { + // + // No flag given + // + return STATUS_INVALID_PARAMETER; + } + + // + // Enter SEH for probing + // + _SEH2_TRY + { + // + // Validate output data + // + ProbeForWritePointer(BaseAddress); + ProbeForWriteSize_t(NumberOfBytesToLock); + + // + // Capture it + // + CapturedBaseAddress = *BaseAddress; + CapturedBytesToLock = *NumberOfBytesToLock; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + // + // Catch illegal base address + // + if (CapturedBaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER; + + // + // Catch illegal region size + // + if ((MmUserProbeAddress - (ULONG_PTR)CapturedBaseAddress) < CapturedBytesToLock) + { + // + // Fail + // + return STATUS_INVALID_PARAMETER; + } + + // + // 0 is also illegal + // + if (!CapturedBytesToLock) return STATUS_INVALID_PARAMETER; + + // + // Get a reference to the process + // + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_OPERATION, + PsProcessType, + PreviousMode, + (PVOID*)(&Process), + NULL); + if (!NT_SUCCESS(Status)) return Status; + + // + // Check if this is is system-mapped + // + if (MapType & MAP_SYSTEM) + { + // + // Check for required privilege + // + if (!SeSinglePrivilegeCheck(SeLockMemoryPrivilege, PreviousMode)) + { + // + // Fail: Don't have it + // + ObDereferenceObject(Process); + return STATUS_PRIVILEGE_NOT_HELD; + } + } + + // + // Check if we should attach + // + if (CurrentProcess != Process) + { + // + // Do it + // + KeStackAttachProcess(&Process->Pcb, &ApcState); + Attached = TRUE; + } + + // + // Oops :( + // + UNIMPLEMENTED; + + // + // Detach if needed + // + if (Attached) KeUnstackDetachProcess(&ApcState); + + // + // Release reference + // + ObDereferenceObject(Process); + + // + // Enter SEH to return data + // + _SEH2_TRY + { + // + // Return data to user + // + *BaseAddress = CapturedBaseAddress; + *NumberOfBytesToLock = 0; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + // + // Return status + // + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +NtUnlockVirtualMemory(IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T NumberOfBytesToUnlock, + IN ULONG MapType) +{ + PEPROCESS Process; + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + NTSTATUS Status; + BOOLEAN Attached = FALSE; + KAPC_STATE ApcState; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PVOID CapturedBaseAddress; + SIZE_T CapturedBytesToUnlock; + PAGED_CODE(); + + // + // Validate flags + // + if ((MapType & ~(MAP_PROCESS | MAP_SYSTEM))) + { + // + // Invalid set of flags + // + return STATUS_INVALID_PARAMETER; + } + + // + // At least one flag must be specified + // + if (!(MapType & (MAP_PROCESS | MAP_SYSTEM))) + { + // + // No flag given + // + return STATUS_INVALID_PARAMETER; + } + + // + // Enter SEH for probing + // + _SEH2_TRY + { + // + // Validate output data + // + ProbeForWritePointer(BaseAddress); + ProbeForWriteSize_t(NumberOfBytesToUnlock); + + // + // Capture it + // + CapturedBaseAddress = *BaseAddress; + CapturedBytesToUnlock = *NumberOfBytesToUnlock; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + // + // Catch illegal base address + // + if (CapturedBaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER; + + // + // Catch illegal region size + // + if ((MmUserProbeAddress - (ULONG_PTR)CapturedBaseAddress) < CapturedBytesToUnlock) + { + // + // Fail + // + return STATUS_INVALID_PARAMETER; + } + + // + // 0 is also illegal + // + if (!CapturedBytesToUnlock) return STATUS_INVALID_PARAMETER; + + // + // Get a reference to the process + // + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_OPERATION, + PsProcessType, + PreviousMode, + (PVOID*)(&Process), + NULL); + if (!NT_SUCCESS(Status)) return Status; + + // + // Check if this is is system-mapped + // + if (MapType & MAP_SYSTEM) + { + // + // Check for required privilege + // + if (!SeSinglePrivilegeCheck(SeLockMemoryPrivilege, PreviousMode)) + { + // + // Fail: Don't have it + // + ObDereferenceObject(Process); + return STATUS_PRIVILEGE_NOT_HELD; + } + } + + // + // Check if we should attach + // + if (CurrentProcess != Process) + { + // + // Do it + // + KeStackAttachProcess(&Process->Pcb, &ApcState); + Attached = TRUE; + } + + // + // Oops :( + // + UNIMPLEMENTED; + + // + // Detach if needed + // + if (Attached) KeUnstackDetachProcess(&ApcState); + + // + // Release reference + // + ObDereferenceObject(Process); + + // + // Enter SEH to return data + // + _SEH2_TRY + { + // + // Return data to user + // + *BaseAddress = PAGE_ALIGN(CapturedBaseAddress); + *NumberOfBytesToUnlock = 0; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + // + // Return status + // + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +NtFlushVirtualMemory(IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T NumberOfBytesToFlush, + OUT PIO_STATUS_BLOCK IoStatusBlock) +{ + PEPROCESS Process; + NTSTATUS Status; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PVOID CapturedBaseAddress; + SIZE_T CapturedBytesToFlush; + IO_STATUS_BLOCK LocalStatusBlock; + PAGED_CODE(); + + // + // Check if we came from user mode + // + if (PreviousMode != KernelMode) + { + // + // Enter SEH for probing + // + _SEH2_TRY + { + // + // Validate all outputs + // + ProbeForWritePointer(BaseAddress); + ProbeForWriteSize_t(NumberOfBytesToFlush); + ProbeForWriteIoStatusBlock(IoStatusBlock); + + // + // Capture them + // + CapturedBaseAddress = *BaseAddress; + CapturedBytesToFlush = *NumberOfBytesToFlush; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + // + // Capture directly + // + CapturedBaseAddress = *BaseAddress; + CapturedBytesToFlush = *NumberOfBytesToFlush; + } + + // + // Catch illegal base address + // + if (CapturedBaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER; + + // + // Catch illegal region size + // + if ((MmUserProbeAddress - (ULONG_PTR)CapturedBaseAddress) < CapturedBytesToFlush) + { + // + // Fail + // + return STATUS_INVALID_PARAMETER; + } + + // + // Get a reference to the process + // + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_OPERATION, + PsProcessType, + PreviousMode, + (PVOID*)(&Process), + NULL); + if (!NT_SUCCESS(Status)) return Status; + + // + // Do it + // + Status = MmFlushVirtualMemory(Process, + &CapturedBaseAddress, + &CapturedBytesToFlush, + &LocalStatusBlock); + + // + // Release reference + // + ObDereferenceObject(Process); + + // + // Enter SEH to return data + // + _SEH2_TRY + { + // + // Return data to user + // + *BaseAddress = PAGE_ALIGN(CapturedBaseAddress); + *NumberOfBytesToFlush = 0; + *IoStatusBlock = LocalStatusBlock; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; + + // + // Return status + // + return Status; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +NtGetWriteWatch(IN HANDLE ProcessHandle, + IN ULONG Flags, + IN PVOID BaseAddress, + IN SIZE_T RegionSize, + IN PVOID *UserAddressArray, + OUT PULONG_PTR EntriesInUserAddressArray, + OUT PULONG Granularity) +{ + PEPROCESS Process; + NTSTATUS Status; + PVOID EndAddress; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + ULONG_PTR CapturedEntryCount; + PAGED_CODE(); + + // + // Check if we came from user mode + // + if (PreviousMode != KernelMode) + { + // + // Enter SEH for probing + // + _SEH2_TRY + { + // + // Catch illegal base address + // + if (BaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER_2; + + // + // Catch illegal region size + // + if ((MmUserProbeAddress - (ULONG_PTR)BaseAddress) < RegionSize) + { + // + // Fail + // + return STATUS_INVALID_PARAMETER_3; + } + + // + // Validate all data + // + ProbeForWriteSize_t(EntriesInUserAddressArray); + ProbeForWriteUlong(Granularity); + + // + // Capture them + // + CapturedEntryCount = *EntriesInUserAddressArray; + + // + // Must have a count + // + if (CapturedEntryCount == 0) return STATUS_INVALID_PARAMETER_5; + + // + // Can't be larger than the maximum + // + if (CapturedEntryCount > (MAXULONG_PTR / sizeof(ULONG_PTR))) + { + // + // Fail + // + return STATUS_INVALID_PARAMETER_5; + } + + // + // Probe the actual array + // + ProbeForWrite(UserAddressArray, + CapturedEntryCount * sizeof(PVOID), + sizeof(PVOID)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + // + // Capture directly + // + CapturedEntryCount = *EntriesInUserAddressArray; + ASSERT(CapturedEntryCount != 0); + } + + // + // Check if this is a local request + // + if (ProcessHandle == NtCurrentProcess()) + { + // + // No need to reference the process + // + Process = PsGetCurrentProcess(); + } + else + { + // + // Reference the target + // + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_OPERATION, + PsProcessType, + PreviousMode, + (PVOID *)&Process, + NULL); + if (!NT_SUCCESS(Status)) return Status; + } + + // + // Compute the last address and validate it + // + EndAddress = (PVOID)((ULONG_PTR)BaseAddress + RegionSize - 1); + if (BaseAddress > EndAddress) + { + // + // Fail + // + if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process); + return STATUS_INVALID_PARAMETER_4; + } + + // + // Oops :( + // + UNIMPLEMENTED; + + // + // Dereference if needed + // + if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process); + + // + // Enter SEH to return data + // + _SEH2_TRY + { + // + // Return data to user + // + *EntriesInUserAddressArray = 0; + *Granularity = PAGE_SIZE; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get exception code + // + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + // + // Return success + // + return STATUS_SUCCESS; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +NtResetWriteWatch(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN SIZE_T RegionSize) +{ + PVOID EndAddress; + PEPROCESS Process; + NTSTATUS Status; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); + + // + // Catch illegal base address + // + if (BaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER_2; + + // + // Catch illegal region size + // + if ((MmUserProbeAddress - (ULONG_PTR)BaseAddress) < RegionSize) + { + // + // Fail + // + return STATUS_INVALID_PARAMETER_3; + } + + // + // Check if this is a local request + // + if (ProcessHandle == NtCurrentProcess()) + { + // + // No need to reference the process + // + Process = PsGetCurrentProcess(); + } + else + { + // + // Reference the target + // + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_OPERATION, + PsProcessType, + PreviousMode, + (PVOID *)&Process, + NULL); + if (!NT_SUCCESS(Status)) return Status; + } + + // + // Compute the last address and validate it + // + EndAddress = (PVOID)((ULONG_PTR)BaseAddress + RegionSize - 1); + if (BaseAddress > EndAddress) + { + // + // Fail + // + if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process); + return STATUS_INVALID_PARAMETER_3; + } + + // + // Oops :( + // + UNIMPLEMENTED; + + // + // Dereference if needed + // + if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process); + + // + // Return success + // + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/reactos/ntoskrnl/mm/arm/stubs.c b/reactos/ntoskrnl/mm/arm/stubs.c index d7c1a27b1e2..50bc6d6e64c 100644 --- a/reactos/ntoskrnl/mm/arm/stubs.c +++ b/reactos/ntoskrnl/mm/arm/stubs.c @@ -510,11 +510,6 @@ MmCreateVirtualMappingInternal(IN PEPROCESS Process, // OldPdeOffset = PdeOffset; - // - // Mark it as mapped - // - if (MarkAsMapped) MmMarkPageMapped(*Pages); - // // Set the PFN // @@ -676,7 +671,6 @@ MmDeleteVirtualMapping(IN PEPROCESS Process, // Unmap the PFN // Pfn = Pte.u.Hard.PageFrameNumber; - if (Pfn) MmMarkPageUnmapped(Pfn); // // Release the PFN if it was ours diff --git a/reactos/ntoskrnl/mm/balance.c b/reactos/ntoskrnl/mm/balance.c index a5e126bbb0d..9f6192bedf2 100644 --- a/reactos/ntoskrnl/mm/balance.c +++ b/reactos/ntoskrnl/mm/balance.c @@ -49,10 +49,10 @@ static LONG MiBalancerWork = 0; VOID MmPrintMemoryStatistic(VOID) { - DbgPrint("MC_CACHE %d, MC_USER %d, MC_PPOOL %d, MC_NPPOOL %d, MmStats.NrFreePages %d\n", + DbgPrint("MC_CACHE %d, MC_USER %d, MC_PPOOL %d, MC_NPPOOL %d, MmAvailablePages %d\n", MiMemoryConsumers[MC_CACHE].PagesUsed, MiMemoryConsumers[MC_USER].PagesUsed, MiMemoryConsumers[MC_PPOOL].PagesUsed, MiMemoryConsumers[MC_NPPOOL].PagesUsed, - MmStats.NrFreePages); + MmAvailablePages); } VOID @@ -117,7 +117,7 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_TYPE Page) if (MmGetReferenceCountPage(Page) == 1) { (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed); - if (IsListEmpty(&AllocationListHead) || MmStats.NrFreePages < MiMinimumAvailablePages) + if (IsListEmpty(&AllocationListHead) || MmAvailablePages < MiMinimumAvailablePages) { KeReleaseSpinLock(&AllocationListLock, OldIrql); OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); @@ -208,7 +208,7 @@ MmRebalanceMemoryConsumers(VOID) ULONG NrFreedPages; NTSTATUS Status; - Target = (MiMinimumAvailablePages - MmStats.NrFreePages) + MiPagesRequired; + Target = (MiMinimumAvailablePages - MmAvailablePages) + MiPagesRequired; Target = max(Target, (LONG) MiMinimumPagesPerRun); for (i = 0; i < MC_MAXIMUM && Target > 0; i++) @@ -269,7 +269,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, KeBugCheck(NO_PAGES_AVAILABLE); } *AllocatedPage = Page; - if (MmStats.NrFreePages <= MiMinimumAvailablePages && + if (MmAvailablePages <= MiMinimumAvailablePages && MiBalancerThreadHandle != NULL) { KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE); @@ -280,7 +280,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, /* * Make sure we don't exceed global targets. */ - if (MmStats.NrFreePages <= MiMinimumAvailablePages) + if (MmAvailablePages <= MiMinimumAvailablePages) { MM_ALLOCATION_REQUEST Request; @@ -369,7 +369,7 @@ MiBalancerThread(PVOID Unused) if (Status == STATUS_SUCCESS) { /* MiBalancerEvent */ - while (MmStats.NrFreePages < MiMinimumAvailablePages + 5) + while (MmAvailablePages < MiMinimumAvailablePages + 5) { for (i = 0; i < MC_MAXIMUM; i++) { @@ -389,7 +389,7 @@ MiBalancerThread(PVOID Unused) else if (Status == STATUS_SUCCESS + 1) { /* MiBalancerTimer */ - ShouldRun = MmStats.NrFreePages < MiMinimumAvailablePages + 5 ? TRUE : FALSE; + ShouldRun = MmAvailablePages < MiMinimumAvailablePages + 5 ? TRUE : FALSE; for (i = 0; i < MC_MAXIMUM; i++) { if (MiMemoryConsumers[i].Trim != NULL) diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 9bf2cd3fee9..f42e1392946 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -50,6 +50,8 @@ PPHYSICAL_PAGE MmPfnDatabase; +ULONG MmAvailablePages; + /* List of pages allocated to the MC_USER Consumer */ static LIST_ENTRY UserPageListHead; /* List of pages zeroed by the ZPW (MmZeroPageThreadMain) */ @@ -249,10 +251,9 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn, if (Pfn1->Flags.Zero == 0) UnzeroedPageCount--; // - // One less free page, one more system page + // One less free page // - MmStats.NrFreePages--; - MmStats.NrSystemPages++; + MmAvailablePages--; // // This PFN is now a used page, set it up @@ -465,8 +466,7 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, // // Decrease available pages // - MmStats.NrSystemPages++; - MmStats.NrFreePages--; + MmAvailablePages--; // // Save it into the MDL @@ -523,8 +523,7 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, // // Decrease available pages // - MmStats.NrSystemPages++; - MmStats.NrFreePages--; + MmAvailablePages--; // // Save this page into the MDL @@ -698,6 +697,7 @@ MmInitializePageList(VOID) PHYSICAL_PAGE UsedPage; PMEMORY_ALLOCATION_DESCRIPTOR Md; PLIST_ENTRY NextEntry; + ULONG NrSystemPages = 0; /* Initialize the page lists */ InitializeListHead(&UserPageListHead); @@ -746,7 +746,7 @@ MmInitializePageList(VOID) InsertTailList(&FreeUnzeroedPageListHead, &MmPfnDatabase[Md->BasePage + i].ListEntry); UnzeroedPageCount++; - MmStats.NrFreePages++; + MmAvailablePages++; } } else @@ -756,7 +756,7 @@ MmInitializePageList(VOID) { /* Everything else is used memory */ MmPfnDatabase[Md->BasePage + i] = UsedPage; - MmStats.NrSystemPages++; + NrSystemPages++; } } } @@ -769,13 +769,12 @@ MmInitializePageList(VOID) /* Mark it as used kernel memory */ MmPfnDatabase[i] = UsedPage; - MmStats.NrSystemPages++; + NrSystemPages++; } KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE); - DPRINT("Pages: %x %x\n", MmStats.NrFreePages, MmStats.NrSystemPages); - MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages; - MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages); + DPRINT("Pages: %x %x\n", MmAvailablePages, NrSystemPages); + MmInitializeBalancer(MmAvailablePages, NrSystemPages); } VOID @@ -912,8 +911,7 @@ MmDereferencePage(PFN_TYPE Pfn) Page->ReferenceCount--; if (Page->ReferenceCount == 0) { - MmStats.NrFreePages++; - MmStats.NrSystemPages--; + MmAvailablePages++; if (Page->Flags.Consumer == MC_USER) RemoveEntryList(&Page->ListEntry); if (Page->RmapListHead != (LONG)NULL) { @@ -1028,7 +1026,7 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry) if (IsListEmpty(&FreeUnzeroedPageListHead)) { /* Check if this allocation is for the PFN DB itself */ - if (MmStats.NrTotalPages == 0) + if (MmNumberOfPhysicalPages == 0) { ASSERT(FALSE); } @@ -1066,8 +1064,7 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry) PageDescriptor->LockCount = 0; PageDescriptor->SavedSwapEntry = SwapEntry; - MmStats.NrSystemPages++; - MmStats.NrFreePages--; + MmAvailablePages--; PfnOffset = PageDescriptor - MmPfnDatabase; if ((NeedClear) && (Consumer != MC_SYSTEM)) @@ -1077,6 +1074,25 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry) return PfnOffset; } +NTSTATUS +NTAPI +MiZeroPage(PFN_TYPE Page) +{ + KIRQL Irql; + PVOID TempAddress; + + Irql = KeRaiseIrqlToDpcLevel(); + TempAddress = MiMapPageToZeroInHyperSpace(Page); + if (TempAddress == NULL) + { + return(STATUS_NO_MEMORY); + } + memset(TempAddress, 0, PAGE_SIZE); + MiUnmapPagesInZeroSpace(TempAddress, 1); + KeLowerIrql(Irql); + return(STATUS_SUCCESS); +} + NTSTATUS NTAPI MmZeroPageThreadMain(PVOID Ignored) diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index a7c684f43c5..bd91612c470 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -1034,48 +1034,4 @@ MmInitGlobalKernelPageDirectory(VOID) } } -VOID -INIT_FUNCTION -NTAPI -MiInitPageDirectoryMap(VOID) -{ - MEMORY_AREA* kernel_map_desc = NULL; - MEMORY_AREA* hyperspace_desc = NULL; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - PVOID BaseAddress; - NTSTATUS Status; - - DPRINT("MiInitPageDirectoryMap()\n"); - - BoundaryAddressMultiple.QuadPart = 0; - BaseAddress = (PVOID)PAGETABLE_MAP; - Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM | MEMORY_AREA_STATIC, - &BaseAddress, - 0x400000, - PAGE_READWRITE, - &kernel_map_desc, - TRUE, - 0, - BoundaryAddressMultiple); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(MEMORY_MANAGEMENT); - } - BaseAddress = (PVOID)HYPERSPACE; - Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM | MEMORY_AREA_STATIC, - &BaseAddress, - 0x400000, - PAGE_READWRITE, - &hyperspace_desc, - TRUE, - 0, - BoundaryAddressMultiple); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(MEMORY_MANAGEMENT); - } -} - /* EOF */ diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index 7923faeff86..fc3c45afc21 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -996,6 +996,7 @@ MmCreateMemoryArea(PMMSUPPORT AddressSpace, // ASSERT(MiStaticMemoryAreaCount < MI_STATIC_MEMORY_AREAS); MemoryArea = &MiStaticMemoryAreas[MiStaticMemoryAreaCount++]; + Type &= ~MEMORY_AREA_STATIC; } else { diff --git a/reactos/ntoskrnl/mm/mmfault.c b/reactos/ntoskrnl/mm/mmfault.c index 01e309ef389..02b3463e4f9 100644 --- a/reactos/ntoskrnl/mm/mmfault.c +++ b/reactos/ntoskrnl/mm/mmfault.c @@ -12,6 +12,9 @@ #define NDEBUG #include +#define MODULE_INVOLVED_IN_ARM3 +#include "ARM3/miarm.h" + /* PRIVATE FUNCTIONS **********************************************************/ VOID @@ -256,6 +259,8 @@ MmAccessFault(IN BOOLEAN StoreInstruction, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation) { + PMEMORY_AREA MemoryArea; + /* Cute little hack for ROS */ if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart) { @@ -268,6 +273,18 @@ MmAccessFault(IN BOOLEAN StoreInstruction, } #endif } + + // + // Check if this is an ARM3 memory area + // + MemoryArea = MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address); + if ((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)) + { + // + // Hand it off to more competent hands... + // + return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation); + } /* Keep same old ReactOS Behaviour */ if (StoreInstruction) diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 25b099dbd8c..05c63624452 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -12,6 +12,9 @@ #define NDEBUG #include +#define MODULE_INVOLVED_IN_ARM3 +#include "ARM3/miarm.h" + /* GLOBALS *******************************************************************/ PCHAR @@ -47,11 +50,9 @@ MemType[] = PBOOLEAN Mm64BitPhysicalAddress = FALSE; ULONG MmReadClusterSize; -MM_STATS MmStats; PMMPTE MmSharedUserDataPte; PMMSUPPORT MmKernelAddressSpace; extern KMUTANT MmSystemLoadLock; -extern ULONG MmBootImageSize; BOOLEAN MiDbgEnableMdDump = #ifdef _ARM_ TRUE; @@ -69,19 +70,151 @@ MiInitSystemMemoryAreas() PVOID BaseAddress; PHYSICAL_ADDRESS BoundaryAddressMultiple; PMEMORY_AREA MArea; + NTSTATUS Status; BoundaryAddressMultiple.QuadPart = 0; // - // First initialize the page table and hyperspace memory areas + // Create the memory area to define the PTE base // - MiInitPageDirectoryMap(); + BaseAddress = (PVOID)PTE_BASE; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, + &BaseAddress, + 4 * 1024 * 1024, + PAGE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); + ASSERT(Status == STATUS_SUCCESS); + + // + // Create the memory area to define Hyperspace + // + BaseAddress = (PVOID)HYPER_SPACE; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, + &BaseAddress, + 4 * 1024 * 1024, + PAGE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); + ASSERT(Status == STATUS_SUCCESS); + + // + // Protect the PFN database + // + BaseAddress = MmPfnDatabase; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, + &BaseAddress, + (MxPfnAllocation << PAGE_SHIFT), + PAGE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); + ASSERT(Status == STATUS_SUCCESS); + + // + // ReactOS requires a memory area to keep the initial NP area off-bounds + // + BaseAddress = MmNonPagedPoolStart; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, + &BaseAddress, + MmSizeOfNonPagedPoolInBytes, + PAGE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); + ASSERT(Status == STATUS_SUCCESS); + + // + // And we need one more for the system NP + // + BaseAddress = MmNonPagedSystemStart; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, + &BaseAddress, + (ULONG_PTR)MmNonPagedPoolEnd - + (ULONG_PTR)MmNonPagedSystemStart, + PAGE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); + ASSERT(Status == STATUS_SUCCESS); + + // + // We also need one for system view space + // + BaseAddress = MiSystemViewStart; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, + &BaseAddress, + MmSystemViewSize, + PAGE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); + ASSERT(Status == STATUS_SUCCESS); + + // + // And another for session space + // + BaseAddress = MmSessionBase; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, + &BaseAddress, + (ULONG_PTR)MiSessionSpaceEnd - + (ULONG_PTR)MmSessionBase, + PAGE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); + ASSERT(Status == STATUS_SUCCESS); + + // + // One more for ARM paged pool + // + BaseAddress = MmPagedPoolStart; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, + &BaseAddress, + MmSizeOfPagedPoolInBytes, + PAGE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); + ASSERT(Status == STATUS_SUCCESS); + + // + // And now, ReactOS paged pool + // + BaseAddress = MmPagedPoolBase; + MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_PAGED_POOL | MEMORY_AREA_STATIC, + &BaseAddress, + MmPagedPoolSize, + PAGE_READWRITE, + &MArea, + TRUE, + 0, + BoundaryAddressMultiple); // // Next, the KPCR // BaseAddress = (PVOID)PCR; MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM | MEMORY_AREA_STATIC, + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, &BaseAddress, PAGE_SIZE * KeNumberProcessors, PAGE_READWRITE, @@ -89,13 +222,13 @@ MiInitSystemMemoryAreas() TRUE, 0, BoundaryAddressMultiple); - + // // Now the KUSER_SHARED_DATA // BaseAddress = (PVOID)KI_USER_SHARED_DATA; MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM | MEMORY_AREA_STATIC, + MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, &BaseAddress, PAGE_SIZE, PAGE_READWRITE, @@ -105,6 +238,58 @@ MiInitSystemMemoryAreas() BoundaryAddressMultiple); } +VOID +NTAPI +MiDbgDumpAddressSpace(VOID) +{ + // + // Print the memory layout + // + DPRINT1(" 0x%p - 0x%p\t%s\n", + MmSystemRangeStart, + (ULONG_PTR)MmSystemRangeStart + MmBootImageSize, + "Boot Loaded Image"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + MmPagedPoolBase, + (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize, + "Paged Pool"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + MmPfnDatabase, + (ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT), + "PFN Database"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + MmNonPagedPoolStart, + (ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes, + "ARMÂł Non Paged Pool"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + MiSystemViewStart, + (ULONG_PTR)MiSystemViewStart + MmSystemViewSize, + "System View Space"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + MmSessionBase, + MiSessionSpaceEnd, + "Session Space"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + PTE_BASE, PDE_BASE, + "Page Tables"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + PDE_BASE, HYPER_SPACE, + "Page Directories"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + HYPER_SPACE, HYPER_SPACE + (4 * 1024 * 1024), + "Hyperspace"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + MmPagedPoolStart, + (ULONG_PTR)MmPagedPoolStart + MmSizeOfPagedPoolInBytes, + "ARMÂł Paged Pool"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + MmNonPagedSystemStart, MmNonPagedPoolExpansionStart, + "System PTE Space"); + DPRINT1(" 0x%p - 0x%p\t%s\n", + MmNonPagedPoolExpansionStart, MmNonPagedPoolEnd, + "Non Paged Pool Expansion PTE Space"); +} + VOID NTAPI MiDbgDumpMemoryDescriptors(VOID) @@ -126,57 +311,6 @@ MiDbgDumpMemoryDescriptors(VOID) DPRINT1("Total: %08lX (%d MB)\n", TotalPages, (TotalPages * PAGE_SIZE) / 1024 / 1024); } -NTSTATUS -NTAPI -MmArmInitSystem(IN ULONG Phase, - IN PLOADER_PARAMETER_BLOCK LoaderBlock); - -VOID -INIT_FUNCTION -NTAPI -MmInit1(VOID) -{ - /* Initialize the kernel address space */ - KeInitializeGuardedMutex(&PsGetCurrentProcess()->AddressCreationLock); - MmKernelAddressSpace = MmGetCurrentAddressSpace(); - MmInitGlobalKernelPageDirectory(); - - /* Dump memory descriptors */ - if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors(); - - // - // Initialize ARMł in phase 0 - // - MmArmInitSystem(0, KeLoaderBlock); - - /* Intialize system memory areas */ - MiInitSystemMemoryAreas(); - - /* Initialize the page list */ - MmInitializePageList(); - - // - // Initialize ARMł in phase 1 - // - MmArmInitSystem(1, KeLoaderBlock); - - /* Put the paged pool after the loaded modules */ - MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MmSystemRangeStart + - MmBootImageSize); - MmPagedPoolSize = MM_PAGED_POOL_SIZE; - - // - // Initialize ARMł in phase 2 - // - MmArmInitSystem(2, KeLoaderBlock); - - /* Initialize paged pool */ - MmInitializePagedPool(); - - /* Initialize working sets */ - MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory); -} - BOOLEAN NTAPI MmInitSystem(IN ULONG Phase, @@ -189,8 +323,102 @@ MmInitSystem(IN ULONG Phase, if (Phase == 0) { - /* Initialize Mm bootstrap */ - MmInit1(); + /* Initialize the kernel address space */ + KeInitializeGuardedMutex(&PsGetCurrentProcess()->AddressCreationLock); + MmKernelAddressSpace = MmGetCurrentAddressSpace(); + MmInitGlobalKernelPageDirectory(); + + /* Dump memory descriptors */ + if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors(); + + // + // Initialize ARMÂł in phase 0 + // + MmArmInitSystem(0, KeLoaderBlock); + + /* Initialize the page list */ + MmInitializePageList(); + + // + // Initialize ARMÂł in phase 1 + // + MmArmInitSystem(1, KeLoaderBlock); + + /* Put the paged pool after the loaded modules */ + MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MmSystemRangeStart + + MmBootImageSize); + MmPagedPoolSize = MM_PAGED_POOL_SIZE; + + /* Intialize system memory areas */ + MiInitSystemMemoryAreas(); + + // + // STEP 1: Allocate and free a single page, repeatedly + // We should always get the same address back + // + if (1) + { + PULONG Test, OldTest; + ULONG i; + + OldTest = Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE); + ASSERT(Test); + for (i = 0; i < 16; i++) + { + MiFreePoolPages(Test); + Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE); + ASSERT(OldTest == Test); + } + MiFreePoolPages(Test); + } + + // + // STEP 2: Allocate 2048 pages without freeing them + // We should run out of space at 1024 pages, since we don't support + // expansion yet. + // + if (1) + { + PULONG Test[2048]; + ULONG i; + + for (i = 0; i < 2048; i++) + { + Test[i] = MiAllocatePoolPages(PagedPool, PAGE_SIZE); + if (!Test[i]) + { + ASSERT(i == 1024); + break; + } + } + + // + // Cleanup + // + while (--i) if (Test[i]) MiFreePoolPages(Test[i]); + } + + // + // STEP 3: Allocate a page and touch it. + // We should get an ARM3 page fault and it should handle the fault + // + if (1) + { + PULONG Test; + + Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE); + ASSERT(*Test == 0); + MiFreePoolPages(Test); + } + + /* Dump the address space */ + MiDbgDumpAddressSpace(); + + /* Initialize paged pool */ + MmInitializePagedPool(); + + /* Initialize working sets */ + MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory); /* Initialize the Loader Lock */ KeInitializeMutant(&MmSystemLoadLock, FALSE); @@ -203,7 +431,7 @@ MmInitSystem(IN ULONG Phase, /* Setup shared user data settings that NT does as well */ ASSERT(SharedUserData->NumberOfPhysicalPages == 0); - SharedUserData->NumberOfPhysicalPages = MmStats.NrTotalPages; + SharedUserData->NumberOfPhysicalPages = MmNumberOfPhysicalPages; SharedUserData->LargePageMinimum = 0; /* For now, we assume that we're always Server */ @@ -237,7 +465,7 @@ MmInitSystem(IN ULONG Phase, // // Now write a copy of it // - TempPte.u.Hard.Owner = 1; + MI_MAKE_OWNER_PAGE(&TempPte); TempPte.u.Hard.PageFrameNumber = PageFrameNumber; *MmSharedUserDataPte = TempPte; diff --git a/reactos/ntoskrnl/mm/mmsup.c b/reactos/ntoskrnl/mm/mmsup.c deleted file mode 100644 index d8302d96b71..00000000000 --- a/reactos/ntoskrnl/mm/mmsup.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/mmsup.c - * PURPOSE: Kernel memory managment functions - * PROGRAMMERS: David Welch (welch@cwcom.net) - */ - -/* INCLUDES *******************************************************************/ - -#include -#define NDEBUG -#include - -/* GLOBALS ********************************************************************/ - -BOOLEAN IsThisAnNtAsSystem = FALSE; -MM_SYSTEMSIZE MmSystemSize = MmSmallSystem; - -/* PRIVATE FUNCTIONS **********************************************************/ - -NTSTATUS -NTAPI -MiZeroPage(PFN_TYPE Page) -{ - KIRQL Irql; - PVOID TempAddress; - - Irql = KeRaiseIrqlToDpcLevel(); - TempAddress = MiMapPageToZeroInHyperSpace(Page); - if (TempAddress == NULL) - { - return(STATUS_NO_MEMORY); - } - memset(TempAddress, 0, PAGE_SIZE); - MiUnmapPagesInZeroSpace(TempAddress, 1); - KeLowerIrql(Irql); - return(STATUS_SUCCESS); -} - -NTSTATUS -NTAPI -MiCopyFromUserPage(PFN_TYPE DestPage, PVOID SourceAddress) -{ - PEPROCESS Process; - KIRQL Irql; - PVOID TempAddress; - - Process = PsGetCurrentProcess(); - TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql); - if (TempAddress == NULL) - { - return(STATUS_NO_MEMORY); - } - memcpy(TempAddress, SourceAddress, PAGE_SIZE); - MiUnmapPageInHyperSpace(Process, TempAddress, Irql); - return(STATUS_SUCCESS); -} - -/* PRIVATE FUNCTIONS **********************************************************/ - -/* Miscellanea functions: they may fit somewhere else */ - -/* - * @implemented - */ -BOOLEAN -NTAPI -MmIsRecursiveIoFault (VOID) -{ - PETHREAD Thread = PsGetCurrentThread(); - - return (Thread->DisablePageFaultClustering | Thread->ForwardClusterOnly); -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -MmMapUserAddressesToPage(IN PVOID BaseAddress, - IN SIZE_T NumberOfBytes, - IN PVOID PageAddress) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @unimplemented - */ -ULONG NTAPI -MmAdjustWorkingSetSize (ULONG Unknown0, - ULONG Unknown1, - ULONG Unknown2, - ULONG Unknown3) -{ - UNIMPLEMENTED; - return (0); -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -MmSetAddressRangeModified ( - IN PVOID Address, - IN ULONG Length -) -{ - UNIMPLEMENTED; - return (FALSE); -} - -/* - * @implemented - */ -BOOLEAN NTAPI MmIsNonPagedSystemAddressValid(PVOID VirtualAddress) -{ - DPRINT1("WARNING: %s returns bogus result\n", __FUNCTION__); - return MmIsAddressValid(VirtualAddress); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -MmIsThisAnNtAsSystem(VOID) -{ - return IsThisAnNtAsSystem; -} - -/* - * @implemented - */ -MM_SYSTEMSIZE -NTAPI -MmQuerySystemSize(VOID) -{ - return MmSystemSize; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/mm/pool.c b/reactos/ntoskrnl/mm/pool.c index fafe3625f5d..07132e80e85 100644 --- a/reactos/ntoskrnl/mm/pool.c +++ b/reactos/ntoskrnl/mm/pool.c @@ -23,7 +23,6 @@ extern PVOID MiNonPagedPoolStart; extern ULONG MiNonPagedPoolLength; extern ULONG MmTotalPagedPoolQuota; extern ULONG MmTotalNonPagedPoolQuota; -extern MM_STATS MmStats; /* FUNCTIONS ***************************************************************/ @@ -165,79 +164,6 @@ ExAllocatePoolWithTag (POOL_TYPE PoolType, SIZE_T NumberOfBytes, ULONG Tag) return(Block); } - -/* - * @implemented - */ -#undef ExAllocatePoolWithQuota -#undef ExAllocatePoolWithQuotaTag -PVOID NTAPI -ExAllocatePoolWithQuota (POOL_TYPE PoolType, SIZE_T NumberOfBytes) -{ - return(ExAllocatePoolWithQuotaTag(PoolType, NumberOfBytes, TAG_NONE)); -} - -/* - * @implemented - */ -PVOID -NTAPI -ExAllocatePoolWithTagPriority( - IN POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes, - IN ULONG Tag, - IN EX_POOL_PRIORITY Priority - ) -{ - /* Do the allocation */ - UNIMPLEMENTED; - return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); -} - -/* - * @implemented - */ -PVOID -NTAPI -ExAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes, - IN ULONG Tag) -{ - PEPROCESS Process; - PVOID Block; - - /* Allocate the Pool First */ - Block = EiAllocatePool(PoolType, - NumberOfBytes, - Tag, - &ExAllocatePoolWithQuotaTag); - - /* "Quota is not charged to the thread for allocations >= PAGE_SIZE" - OSR Docs */ - if (!(NumberOfBytes >= PAGE_SIZE)) - { - /* Get the Current Process */ - Process = PsGetCurrentProcess(); - - /* PsChargePoolQuota returns an exception, so this needs SEH */ - _SEH2_TRY - { - /* FIXME: Is there a way to get the actual Pool size allocated from the pool header? */ - PsChargePoolQuota(Process, - PoolType & PAGED_POOL_MASK, - NumberOfBytes); - } - _SEH2_EXCEPT((ExFreePool(Block), EXCEPTION_CONTINUE_SEARCH)) - { - /* Quota Exceeded and the caller had no SEH! */ - KeBugCheck(STATUS_QUOTA_EXCEEDED); - } - _SEH2_END; - } - - /* Return the allocated block */ - return Block; -} - /* * @implemented */ @@ -307,77 +233,4 @@ ExFreePoolWithTag( } } -/* - * @unimplemented - */ -SIZE_T -NTAPI -ExQueryPoolBlockSize ( - IN PVOID PoolBlock, - OUT PBOOLEAN QuotaCharged - ) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -PVOID -NTAPI -MmAllocateMappingAddress ( - IN SIZE_T NumberOfBytes, - IN ULONG PoolTag - ) -{ - UNIMPLEMENTED; - return 0; -} - - -/* - * @unimplemented - */ -VOID -NTAPI -MmFreeMappingAddress ( - IN PVOID BaseAddress, - IN ULONG PoolTag - ) -{ - UNIMPLEMENTED; -} - -BOOLEAN -NTAPI -MiRaisePoolQuota( - IN POOL_TYPE PoolType, - IN ULONG CurrentMaxQuota, - OUT PULONG NewMaxQuota - ) -{ - /* Different quota raises depending on the type (64K vs 512K) */ - if (PoolType == PagedPool) { - - /* Make sure that 4MB is still left */ - if ((MM_PAGED_POOL_SIZE >> 12) < ((MmPagedPoolSize + 4194304) >> 12)) { - return FALSE; - } - - /* Increase Paged Pool Quota by 512K */ - MmTotalPagedPoolQuota += 524288; - *NewMaxQuota = CurrentMaxQuota + 524288; - return TRUE; - - } else { /* Nonpaged Pool */ - - /* Check if we still have 200 pages free*/ - if (MmStats.NrFreePages < 200) return FALSE; - - *NewMaxQuota = CurrentMaxQuota + 65536; - return TRUE; - } -} - /* EOF */ diff --git a/reactos/ntoskrnl/mm/ppool.c b/reactos/ntoskrnl/mm/ppool.c index 44330702536..c105c25ffd3 100644 --- a/reactos/ntoskrnl/mm/ppool.c +++ b/reactos/ntoskrnl/mm/ppool.c @@ -51,23 +51,7 @@ VOID INIT_FUNCTION NTAPI MmInitializePagedPool(VOID) -{ - PVOID BaseAddress; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - PMEMORY_AREA MArea; - BoundaryAddressMultiple.QuadPart = 0; - - BaseAddress = MmPagedPoolBase; - MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_PAGED_POOL, - &BaseAddress, - MmPagedPoolSize, - PAGE_READWRITE, - &MArea, - TRUE, - 0, - BoundaryAddressMultiple); - +{ /* * We are still at a high IRQL level at this point so explicitly commit * the first page of the paged pool before writing the first block header. diff --git a/reactos/ntoskrnl/mm/procsup.c b/reactos/ntoskrnl/mm/procsup.c index 8a88014c831..ededba8ff46 100644 --- a/reactos/ntoskrnl/mm/procsup.c +++ b/reactos/ntoskrnl/mm/procsup.c @@ -13,67 +13,8 @@ #define NDEBUG #include -extern ULONG NtMajorVersion; -extern ULONG NtMinorVersion; -extern ULONG CmNtCSDVersion; -extern ULONG NtBuildNumber; -extern MM_SYSTEMSIZE MmSystemSize; - -#define MM_HIGHEST_VAD_ADDRESS \ - (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE)) - /* FUNCTIONS *****************************************************************/ -NTSTATUS -NTAPI -MmSetMemoryPriorityProcess(IN PEPROCESS Process, - IN UCHAR MemoryPriority) -{ - UCHAR OldPriority; - - /* Check if we have less then 16MB of Physical Memory */ - if ((MmSystemSize == MmSmallSystem) && - (MmStats.NrTotalPages < ((15 * 1024 * 1024) / PAGE_SIZE))) - { - /* Always use background priority */ - MemoryPriority = 0; - } - - /* Save the old priority and update it */ - OldPriority = (UCHAR)Process->Vm.Flags.MemoryPriority; - Process->Vm.Flags.MemoryPriority = MemoryPriority; - - /* Return the old priority */ - return OldPriority; -} - -LCID -NTAPI -MmGetSessionLocaleId(VOID) -{ - PEPROCESS Process; - PAGED_CODE(); - - /* Get the current process */ - Process = PsGetCurrentProcess(); - - /* Check if it's the Session Leader */ - if (Process->Vm.Flags.SessionLeader) - { - /* Make sure it has a valid Session */ - if (Process->Session) - { - /* Get the Locale ID */ -#if ROS_HAS_SESSIONS - return ((PMM_SESSION_SPACE)Process->Session)->LocaleId; -#endif - } - } - - /* Not a session leader, return the default */ - return PsDefaultThreadLocaleId; -} - PVOID NTAPI MiCreatePebOrTeb(PEPROCESS Process, @@ -148,211 +89,6 @@ MmDeleteTeb(PEPROCESS Process, MmUnlockAddressSpace(ProcessAddressSpace); } -NTSTATUS -NTAPI -MmCreatePeb(PEPROCESS Process) -{ - PPEB Peb = NULL; - LARGE_INTEGER SectionOffset; - SIZE_T ViewSize = 0; - PVOID TableBase = NULL; - PIMAGE_NT_HEADERS NtHeaders; - PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData; - NTSTATUS Status; - KAFFINITY ProcessAffinityMask = 0; - SectionOffset.QuadPart = (ULONGLONG)0; - DPRINT("MmCreatePeb\n"); - - /* Allocate the PEB */ - Peb = MiCreatePebOrTeb(Process, - (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); - ASSERT(Peb == (PVOID)0x7FFDF000); - - /* Map NLS Tables */ - DPRINT("Mapping NLS\n"); - Status = MmMapViewOfSection(ExpNlsSectionPointer, - (PEPROCESS)Process, - &TableBase, - 0, - 0, - &SectionOffset, - &ViewSize, - ViewShare, - MEM_TOP_DOWN, - PAGE_READONLY); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status); - return(Status); - } - DPRINT("TableBase %p ViewSize %lx\n", TableBase, ViewSize); - - /* Attach to Process */ - KeAttachProcess(&Process->Pcb); - - /* Initialize the PEB */ - DPRINT("Allocated: %x\n", Peb); - RtlZeroMemory(Peb, sizeof(PEB)); - - /* Set up data */ - DPRINT("Setting up PEB\n"); - Peb->ImageBaseAddress = Process->SectionBaseAddress; - Peb->InheritedAddressSpace = 0; - Peb->Mutant = NULL; - - /* NLS */ - 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; - Peb->OSMinorVersion = NtMinorVersion; - Peb->OSBuildNumber = (USHORT)(NtBuildNumber & 0x3FFF); - Peb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */ - Peb->OSCSDVersion = (USHORT)CmNtCSDVersion; - - /* Heap and Debug Data */ - Peb->NumberOfProcessors = KeNumberProcessors; - Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL ? TRUE : FALSE); - Peb->NtGlobalFlag = NtGlobalFlag; - /*Peb->HeapSegmentReserve = MmHeapSegmentReserve; - Peb->HeapSegmentCommit = MmHeapSegmentCommit; - Peb->HeapDeCommitTotalFreeThreshold = MmHeapDeCommitTotalFreeThreshold; - Peb->HeapDeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold;*/ - Peb->NumberOfHeaps = 0; - Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID); - Peb->ProcessHeaps = (PVOID*)(Peb + 1); - - /* Image Data */ - if ((NtHeaders = RtlImageNtHeader(Peb->ImageBaseAddress))) - { - /* Write subsystem data */ - Peb->ImageSubSystem = NtHeaders->OptionalHeader.Subsystem; - Peb->ImageSubSystemMajorVersion = NtHeaders->OptionalHeader.MajorSubsystemVersion; - Peb->ImageSubSystemMinorVersion = NtHeaders->OptionalHeader.MinorSubsystemVersion; - - /* Write Version Data */ - if (NtHeaders->OptionalHeader.Win32VersionValue) - { - Peb->OSMajorVersion = NtHeaders->OptionalHeader.Win32VersionValue & 0xFF; - Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF; - Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF; - - /* Set the Platform ID */ - Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2; - } - - /* Check if the image is not safe for SMP */ - if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) - { - /* FIXME: Choose one randomly */ - Peb->ImageProcessAffinityMask = 1; - } - else - { - /* Use affinity from Image Header */ - Peb->ImageProcessAffinityMask = ProcessAffinityMask; - } - - _SEH2_TRY - { - /* Get the Image Config Data too */ - ImageConfigData = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, - (PULONG)&ViewSize); - - ProbeForRead(ImageConfigData, - sizeof(IMAGE_LOAD_CONFIG_DIRECTORY), - sizeof(ULONG)); - - /* Process the image config data overrides if specfied. */ - if (ImageConfigData != NULL) - { - if (ImageConfigData->CSDVersion) - { - Peb->OSCSDVersion = ImageConfigData->CSDVersion; - } - if (ImageConfigData->ProcessAffinityMask) - { - ProcessAffinityMask = ImageConfigData->ProcessAffinityMask; - } - } - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } - - /* Misc data */ - Peb->SessionId = Process->Session; - Process->Peb = Peb; - - /* Detach from the Process */ - KeDetachProcess(); - - DPRINT("MmCreatePeb: Peb created at %p\n", Peb); - return Status; -} - -PTEB -NTAPI -MmCreateTeb(PEPROCESS Process, - PCLIENT_ID ClientId, - PINITIAL_TEB InitialTeb) -{ - PTEB Teb; - BOOLEAN Attached = FALSE; - - /* Attach to the process */ - DPRINT("MmCreateTeb\n"); - if (Process != PsGetCurrentProcess()) - { - /* Attach to Target */ - KeAttachProcess(&Process->Pcb); - Attached = TRUE; - } - - /* Allocate the TEB */ - Teb = MiCreatePebOrTeb(Process, - (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); - - /* Initialize the PEB */ - RtlZeroMemory(Teb, sizeof(TEB)); - - /* Set TIB Data */ - Teb->Tib.ExceptionList = (PVOID)0xFFFFFFFF; - Teb->Tib.Version = 1; - Teb->Tib.Self = (PNT_TIB)Teb; - - /* Set TEB Data */ - Teb->ClientId = *ClientId; - Teb->RealClientId = *ClientId; - Teb->ProcessEnvironmentBlock = Process->Peb; - Teb->CurrentLocale = PsDefaultThreadLocaleId; - - /* Store stack information from InitialTeb */ - if(InitialTeb != NULL) - { - Teb->Tib.StackBase = InitialTeb->StackBase; - Teb->Tib.StackLimit = InitialTeb->StackLimit; - Teb->DeallocationStack = InitialTeb->AllocatedStackBase; - } - - /* Initialize the static unicode string */ - Teb->StaticUnicodeString.Length = 0; - Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer); - Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer; - - /* Return TEB Address */ - DPRINT("Allocated: %x\n", Teb); - if (Attached) KeDetachProcess(); - return Teb; -} - NTSTATUS NTAPI MmInitializeHandBuiltProcess2(IN PEPROCESS Process) diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index e0bfcd83086..e741a430f5f 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -574,6 +574,25 @@ BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea, return FALSE; } +NTSTATUS +NTAPI +MiCopyFromUserPage(PFN_TYPE DestPage, PVOID SourceAddress) +{ + PEPROCESS Process; + KIRQL Irql; + PVOID TempAddress; + + Process = PsGetCurrentProcess(); + TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql); + if (TempAddress == NULL) + { + return(STATUS_NO_MEMORY); + } + memcpy(TempAddress, SourceAddress, PAGE_SIZE); + MiUnmapPageInHyperSpace(Process, TempAddress, Irql); + return(STATUS_SUCCESS); +} + NTSTATUS NTAPI MiReadPage(PMEMORY_AREA MemoryArea, @@ -4794,7 +4813,7 @@ MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, /* Something must gone wrong * how can we have a Section but no * reference? */ - DPRINT1("ERROR: DataSectionObject without reference!\n"); + DPRINT("ERROR: DataSectionObject without reference!\n"); } } @@ -4944,22 +4963,6 @@ MmUnmapViewInSessionSpace ( return STATUS_NOT_IMPLEMENTED; } -/* - * @unimplemented - */ -NTSTATUS NTAPI -MmSetBankedSection (ULONG Unknown0, - ULONG Unknown1, - ULONG Unknown2, - ULONG Unknown3, - ULONG Unknown4, - ULONG Unknown5) -{ - UNIMPLEMENTED; - return (STATUS_NOT_IMPLEMENTED); -} - - /********************************************************************** * NAME EXPORTED * MmCreateSection@ @@ -5073,46 +5076,6 @@ MmCreateSection (OUT PVOID * Section, AllocationAttributes)); } -NTSTATUS -NTAPI -NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle, - IN OUT PULONG_PTR NumberOfPages, - IN OUT PULONG_PTR UserPfnArray) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -NtMapUserPhysicalPages(IN PVOID VirtualAddresses, - IN ULONG_PTR NumberOfPages, - IN OUT PULONG_PTR UserPfnArray) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses, - IN ULONG_PTR NumberOfPages, - IN OUT PULONG_PTR UserPfnArray) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -NtFreeUserPhysicalPages(IN HANDLE ProcessHandle, - IN OUT PULONG_PTR NumberOfPages, - IN OUT PULONG_PTR UserPfnArray) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS NTAPI NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index 80581b59aad..8e6e845290b 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -13,392 +13,8 @@ #define NDEBUG #include -#define MI_MAPPED_COPY_PAGES 16 -#define MI_POOL_COPY_BYTES 512 -#define MI_MAX_TRANSFER_SIZE 64 * 1024 -#define TAG_VM 'wRmV' - /* PRIVATE FUNCTIONS **********************************************************/ -LONG -MiGetExceptionInfo(EXCEPTION_POINTERS *ExceptionInfo, BOOLEAN * HaveBadAddress, ULONG_PTR * BadAddress) -{ - PEXCEPTION_RECORD ExceptionRecord; - PAGED_CODE(); - - /* Assume default */ - *HaveBadAddress = FALSE; - - /* Get the exception record */ - ExceptionRecord = ExceptionInfo->ExceptionRecord; - - /* Look at the exception code */ - if ((ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) || - (ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) || - (ExceptionRecord->ExceptionCode == STATUS_IN_PAGE_ERROR)) - { - /* We can tell the address if we have more than one parameter */ - if (ExceptionRecord->NumberParameters > 1) - { - /* Return the address */ - *HaveBadAddress = TRUE; - *BadAddress = ExceptionRecord->ExceptionInformation[1]; - } - } - - /* Continue executing the next handler */ - return EXCEPTION_EXECUTE_HANDLER; -} - -NTSTATUS -NTAPI -MiDoMappedCopy(IN PEPROCESS SourceProcess, - IN PVOID SourceAddress, - IN PEPROCESS TargetProcess, - OUT PVOID TargetAddress, - IN SIZE_T BufferSize, - IN KPROCESSOR_MODE PreviousMode, - OUT PSIZE_T ReturnSize) -{ - PFN_NUMBER MdlBuffer[(sizeof(MDL) / sizeof(PFN_NUMBER)) + MI_MAPPED_COPY_PAGES + 1]; - PMDL Mdl = (PMDL)MdlBuffer; - SIZE_T TotalSize, CurrentSize, RemainingSize; - volatile BOOLEAN FailedInProbe = FALSE, FailedInMapping = FALSE, FailedInMoving; - volatile BOOLEAN PagesLocked; - PVOID CurrentAddress = SourceAddress, CurrentTargetAddress = TargetAddress; - volatile PVOID MdlAddress; - KAPC_STATE ApcState; - BOOLEAN HaveBadAddress; - ULONG_PTR BadAddress; - PAGED_CODE(); - - /* Calculate the maximum amount of data to move */ - TotalSize = (MI_MAPPED_COPY_PAGES - 2) * PAGE_SIZE; - if (BufferSize <= TotalSize) TotalSize = BufferSize; - CurrentSize = TotalSize; - RemainingSize = BufferSize; - - /* Loop as long as there is still data */ - while (RemainingSize > 0) - { - /* Check if this transfer will finish everything off */ - if (RemainingSize < CurrentSize) CurrentSize = RemainingSize; - - /* Attach to the source address space */ - KeStackAttachProcess(&SourceProcess->Pcb, &ApcState); - - /* Reset state for this pass */ - MdlAddress = NULL; - PagesLocked = FALSE; - FailedInMoving = FALSE; - ASSERT(FailedInProbe == FALSE); - - /* Protect user-mode copy */ - _SEH2_TRY - { - /* If this is our first time, probe the buffer */ - if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode)) - { - /* Catch a failure here */ - FailedInProbe = TRUE; - - /* Do the probe */ - ProbeForRead(SourceAddress, BufferSize, sizeof(CHAR)); - - /* Passed */ - FailedInProbe = FALSE; - } - - /* Initialize and probe and lock the MDL */ - MmInitializeMdl (Mdl, CurrentAddress, CurrentSize); - MmProbeAndLockPages (Mdl, PreviousMode, IoReadAccess); - PagesLocked = TRUE; - - /* Now map the pages */ - MdlAddress = MmMapLockedPagesSpecifyCache(Mdl, - KernelMode, - MmCached, - NULL, - FALSE, - HighPagePriority); - if (!MdlAddress) - { - /* Use our SEH handler to pick this up */ - FailedInMapping = TRUE; - ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); - } - - /* Now let go of the source and grab to the target process */ - KeUnstackDetachProcess(&ApcState); - KeStackAttachProcess(&TargetProcess->Pcb, &ApcState); - - /* Check if this is our first time through */ - if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode)) - { - /* Catch a failure here */ - FailedInProbe = TRUE; - - /* Do the probe */ - ProbeForWrite(TargetAddress, BufferSize, sizeof(CHAR)); - - /* Passed */ - FailedInProbe = FALSE; - } - - /* Now do the actual move */ - FailedInMoving = TRUE; - RtlCopyMemory(CurrentTargetAddress, MdlAddress, CurrentSize); - } - _SEH2_EXCEPT(MiGetExceptionInfo(_SEH2_GetExceptionInformation(), &HaveBadAddress, &BadAddress)) - { - /* Detach from whoever we may be attached to */ - KeUnstackDetachProcess(&ApcState); - - /* Check if we had mapped the pages */ - if (MdlAddress) MmUnmapLockedPages(MdlAddress, Mdl); - - /* Check if we had locked the pages */ - if (PagesLocked) MmUnlockPages(Mdl); - - /* Check if we failed during the probe or mapping */ - if ((FailedInProbe) || (FailedInMapping)) - { - /* Exit */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - - /* Otherwise, we failed probably during the move */ - *ReturnSize = BufferSize - RemainingSize; - if (FailedInMoving) - { - /* Check if we know exactly where we stopped copying */ - if (HaveBadAddress) - { - /* Return the exact number of bytes copied */ - *ReturnSize = BadAddress - (ULONG_PTR)SourceAddress; - } - } - - /* Return partial copy */ - _SEH2_YIELD(return STATUS_PARTIAL_COPY); - } - _SEH2_END; - - /* Detach from target */ - KeUnstackDetachProcess(&ApcState); - - /* Unmap and unlock */ - MmUnmapLockedPages(MdlAddress, Mdl); - MmUnlockPages(Mdl); - - /* Update location and size */ - RemainingSize -= CurrentSize; - CurrentAddress = (PVOID)((ULONG_PTR)CurrentAddress + CurrentSize); - CurrentTargetAddress = (PVOID)((ULONG_PTR)CurrentTargetAddress + CurrentSize); - } - - /* All bytes read */ - *ReturnSize = BufferSize; - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -MiDoPoolCopy(IN PEPROCESS SourceProcess, - IN PVOID SourceAddress, - IN PEPROCESS TargetProcess, - OUT PVOID TargetAddress, - IN SIZE_T BufferSize, - IN KPROCESSOR_MODE PreviousMode, - OUT PSIZE_T ReturnSize) -{ - UCHAR StackBuffer[MI_POOL_COPY_BYTES]; - SIZE_T TotalSize, CurrentSize, RemainingSize; - volatile BOOLEAN FailedInProbe = FALSE, FailedInMoving, HavePoolAddress = FALSE; - PVOID CurrentAddress = SourceAddress, CurrentTargetAddress = TargetAddress; - PVOID PoolAddress; - KAPC_STATE ApcState; - BOOLEAN HaveBadAddress; - ULONG_PTR BadAddress; - PAGED_CODE(); - - /* Calculate the maximum amount of data to move */ - TotalSize = MI_MAX_TRANSFER_SIZE; - if (BufferSize <= MI_MAX_TRANSFER_SIZE) TotalSize = BufferSize; - CurrentSize = TotalSize; - RemainingSize = BufferSize; - - /* Check if we can use the stack */ - if (BufferSize <= MI_POOL_COPY_BYTES) - { - /* Use it */ - PoolAddress = (PVOID)StackBuffer; - } - else - { - /* Allocate pool */ - PoolAddress = ExAllocatePoolWithTag(NonPagedPool, TotalSize, TAG_VM); - if (!PoolAddress) ASSERT(FALSE); - HavePoolAddress = TRUE; - } - - /* Loop as long as there is still data */ - while (RemainingSize > 0) - { - /* Check if this transfer will finish everything off */ - if (RemainingSize < CurrentSize) CurrentSize = RemainingSize; - - /* Attach to the source address space */ - KeStackAttachProcess(&SourceProcess->Pcb, &ApcState); - - /* Reset state for this pass */ - FailedInMoving = FALSE; - ASSERT(FailedInProbe == FALSE); - - /* Protect user-mode copy */ - _SEH2_TRY - { - /* If this is our first time, probe the buffer */ - if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode)) - { - /* Catch a failure here */ - FailedInProbe = TRUE; - - /* Do the probe */ - ProbeForRead(SourceAddress, BufferSize, sizeof(CHAR)); - - /* Passed */ - FailedInProbe = FALSE; - } - - /* Do the copy */ - RtlCopyMemory(PoolAddress, CurrentAddress, CurrentSize); - - /* Now let go of the source and grab to the target process */ - KeUnstackDetachProcess(&ApcState); - KeStackAttachProcess(&TargetProcess->Pcb, &ApcState); - - /* Check if this is our first time through */ - if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode)) - { - /* Catch a failure here */ - FailedInProbe = TRUE; - - /* Do the probe */ - ProbeForWrite(TargetAddress, BufferSize, sizeof(CHAR)); - - /* Passed */ - FailedInProbe = FALSE; - } - - /* Now do the actual move */ - FailedInMoving = TRUE; - RtlCopyMemory(CurrentTargetAddress, PoolAddress, CurrentSize); - } - _SEH2_EXCEPT(MiGetExceptionInfo(_SEH2_GetExceptionInformation(), &HaveBadAddress, &BadAddress)) - { - /* Detach from whoever we may be attached to */ - KeUnstackDetachProcess(&ApcState); - - /* Check if we had allocated pool */ - if (HavePoolAddress) ExFreePool(PoolAddress); - - /* Check if we failed during the probe */ - if (FailedInProbe) - { - /* Exit */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - - /* Otherwise, we failed probably during the move */ - *ReturnSize = BufferSize - RemainingSize; - if (FailedInMoving) - { - /* Check if we know exactly where we stopped copying */ - if (HaveBadAddress) - { - /* Return the exact number of bytes copied */ - *ReturnSize = BadAddress - (ULONG_PTR)SourceAddress; - } - } - - /* Return partial copy */ - _SEH2_YIELD(return STATUS_PARTIAL_COPY); - } - _SEH2_END; - - /* Detach from target */ - KeUnstackDetachProcess(&ApcState); - - /* Update location and size */ - RemainingSize -= CurrentSize; - CurrentAddress = (PVOID)((ULONG_PTR)CurrentAddress + CurrentSize); - CurrentTargetAddress = (PVOID)((ULONG_PTR)CurrentTargetAddress + CurrentSize); - } - - /* Check if we had allocated pool */ - if (HavePoolAddress) ExFreePool(PoolAddress); - - /* All bytes read */ - *ReturnSize = BufferSize; - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -MmCopyVirtualMemory(IN PEPROCESS SourceProcess, - IN PVOID SourceAddress, - IN PEPROCESS TargetProcess, - OUT PVOID TargetAddress, - IN SIZE_T BufferSize, - IN KPROCESSOR_MODE PreviousMode, - OUT PSIZE_T ReturnSize) -{ - NTSTATUS Status; - PEPROCESS Process = SourceProcess; - - /* Don't accept zero-sized buffers */ - if (!BufferSize) return STATUS_SUCCESS; - - /* If we are copying from ourselves, lock the target instead */ - if (SourceProcess == PsGetCurrentProcess()) Process = TargetProcess; - - /* Acquire rundown protection */ - if (!ExAcquireRundownProtection(&Process->RundownProtect)) - { - /* Fail */ - return STATUS_PROCESS_IS_TERMINATING; - } - - /* See if we should use the pool copy */ - if (BufferSize > MI_POOL_COPY_BYTES) - { - /* Use MDL-copy */ - Status = MiDoMappedCopy(SourceProcess, - SourceAddress, - TargetProcess, - TargetAddress, - BufferSize, - PreviousMode, - ReturnSize); - } - else - { - /* Do pool copy */ - Status = MiDoPoolCopy(SourceProcess, - SourceAddress, - TargetProcess, - TargetAddress, - BufferSize, - PreviousMode, - ReturnSize); - } - - /* Release the lock */ - ExReleaseRundownProtection(&Process->RundownProtect); - return Status; -} - NTSTATUS FASTCALL MiQueryVirtualMemory(IN HANDLE ProcessHandle, IN PVOID Address, @@ -721,323 +337,8 @@ MiUnmapLockedPagesInUserSpace(IN PVOID BaseAddress, NULL); } -/* PUBLIC FUNCTIONS ***********************************************************/ - -/* - * @unimplemented - */ -PVOID -NTAPI -MmGetVirtualForPhysical(IN PHYSICAL_ADDRESS PhysicalAddress) -{ - UNIMPLEMENTED; - return 0; -} - -/* - * @unimplemented - */ -PVOID -NTAPI -MmSecureVirtualMemory(IN PVOID Address, - IN SIZE_T Length, - IN ULONG Mode) -{ - UNIMPLEMENTED; - return NULL; -} - -/* - * @unimplemented - */ -VOID -NTAPI -MmUnsecureVirtualMemory(IN PVOID SecureMem) -{ - UNIMPLEMENTED; -} - /* SYSTEM CALLS ***************************************************************/ -NTSTATUS -NTAPI -NtReadVirtualMemory(IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - OUT PVOID Buffer, - IN SIZE_T NumberOfBytesToRead, - OUT PSIZE_T NumberOfBytesRead OPTIONAL) -{ - KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); - PEPROCESS Process; - NTSTATUS Status; - SIZE_T BytesRead = 0; - PAGED_CODE(); - - /* Check if we came from user mode */ - if (PreviousMode != KernelMode) - { - /* Validate the read addresses */ - if ((((ULONG_PTR)BaseAddress + NumberOfBytesToRead) < (ULONG_PTR)BaseAddress) || - (((ULONG_PTR)Buffer + NumberOfBytesToRead) < (ULONG_PTR)Buffer) || - (((ULONG_PTR)BaseAddress + NumberOfBytesToRead) > MmUserProbeAddress) || - (((ULONG_PTR)Buffer + NumberOfBytesToRead) > MmUserProbeAddress)) - { - /* Don't allow to write into kernel space */ - return STATUS_ACCESS_VIOLATION; - } - - /* Enter SEH for probe */ - _SEH2_TRY - { - /* Probe the output value */ - if (NumberOfBytesRead) ProbeForWriteSize_t(NumberOfBytesRead); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - } - - /* Reference the process */ - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_READ, - PsProcessType, - PreviousMode, - (PVOID*)(&Process), - NULL); - if (NT_SUCCESS(Status)) - { - /* Do the copy */ - Status = MmCopyVirtualMemory(Process, - BaseAddress, - PsGetCurrentProcess(), - Buffer, - NumberOfBytesToRead, - PreviousMode, - &BytesRead); - - /* Dereference the process */ - ObDereferenceObject(Process); - } - - /* Check if the caller sent this parameter */ - if (NumberOfBytesRead) - { - /* Enter SEH to guard write */ - _SEH2_TRY - { - /* Return the number of bytes read */ - *NumberOfBytesRead = BytesRead; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Handle exception */ - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } - - /* Return status */ - return Status; -} - -NTSTATUS -NTAPI -NtWriteVirtualMemory(IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN PVOID Buffer, - IN SIZE_T NumberOfBytesToWrite, - OUT PSIZE_T NumberOfBytesWritten OPTIONAL) -{ - KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); - PEPROCESS Process; - NTSTATUS Status; - SIZE_T BytesWritten = 0; - PAGED_CODE(); - - /* Check if we came from user mode */ - if (PreviousMode != KernelMode) - { - /* Validate the read addresses */ - if ((((ULONG_PTR)BaseAddress + NumberOfBytesToWrite) < (ULONG_PTR)BaseAddress) || - (((ULONG_PTR)Buffer + NumberOfBytesToWrite) < (ULONG_PTR)Buffer) || - (((ULONG_PTR)BaseAddress + NumberOfBytesToWrite) > MmUserProbeAddress) || - (((ULONG_PTR)Buffer + NumberOfBytesToWrite) > MmUserProbeAddress)) - { - /* Don't allow to write into kernel space */ - return STATUS_ACCESS_VIOLATION; - } - - /* Enter SEH for probe */ - _SEH2_TRY - { - /* Probe the output value */ - if (NumberOfBytesWritten) ProbeForWriteSize_t(NumberOfBytesWritten); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - } - - /* Reference the process */ - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_WRITE, - PsProcessType, - PreviousMode, - (PVOID*)&Process, - NULL); - if (NT_SUCCESS(Status)) - { - /* Do the copy */ - Status = MmCopyVirtualMemory(PsGetCurrentProcess(), - Buffer, - Process, - BaseAddress, - NumberOfBytesToWrite, - PreviousMode, - &BytesWritten); - - /* Dereference the process */ - ObDereferenceObject(Process); - } - - /* Check if the caller sent this parameter */ - if (NumberOfBytesWritten) - { - /* Enter SEH to guard write */ - _SEH2_TRY - { - /* Return the number of bytes read */ - *NumberOfBytesWritten = BytesWritten; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Handle exception */ - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } - - /* Return status */ - return Status; -} - -NTSTATUS -NTAPI -NtProtectVirtualMemory(IN HANDLE ProcessHandle, - IN OUT PVOID *UnsafeBaseAddress, - IN OUT SIZE_T *UnsafeNumberOfBytesToProtect, - IN ULONG NewAccessProtection, - OUT PULONG UnsafeOldAccessProtection) -{ - PEPROCESS Process; - ULONG OldAccessProtection; - ULONG Protection; - PVOID BaseAddress = NULL; - SIZE_T NumberOfBytesToProtect = 0; - KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); - NTSTATUS Status; - PAGED_CODE(); - - /* Check for valid protection flags */ - Protection = NewAccessProtection & ~(PAGE_GUARD|PAGE_NOCACHE); - if (Protection != PAGE_NOACCESS && - Protection != PAGE_READONLY && - Protection != PAGE_READWRITE && - Protection != PAGE_WRITECOPY && - Protection != PAGE_EXECUTE && - Protection != PAGE_EXECUTE_READ && - Protection != PAGE_EXECUTE_READWRITE && - Protection != PAGE_EXECUTE_WRITECOPY) - { - return STATUS_INVALID_PAGE_PROTECTION; - } - - /* Check if we came from user mode */ - if (PreviousMode != KernelMode) - { - /* Enter SEH for probing */ - _SEH2_TRY - { - /* Validate all outputs */ - ProbeForWritePointer(UnsafeBaseAddress); - ProbeForWriteSize_t(UnsafeNumberOfBytesToProtect); - ProbeForWriteUlong(UnsafeOldAccessProtection); - - /* Capture them */ - BaseAddress = *UnsafeBaseAddress; - NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - } - else - { - /* Capture directly */ - BaseAddress = *UnsafeBaseAddress; - NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect; - } - - /* Catch illegal base address */ - if (BaseAddress > (PVOID)MmUserProbeAddress) return STATUS_INVALID_PARAMETER_2; - - /* Catch illegal region size */ - if ((MmUserProbeAddress - (ULONG_PTR)BaseAddress) < NumberOfBytesToProtect) - { - /* Fail */ - return STATUS_INVALID_PARAMETER_3; - } - - /* 0 is also illegal */ - if (!NumberOfBytesToProtect) return STATUS_INVALID_PARAMETER_3; - - /* Get a reference to the process */ - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_OPERATION, - PsProcessType, - PreviousMode, - (PVOID*)(&Process), - NULL); - if (!NT_SUCCESS(Status)) return Status; - - /* Do the actual work */ - Status = MiProtectVirtualMemory(Process, - &BaseAddress, - &NumberOfBytesToProtect, - NewAccessProtection, - &OldAccessProtection); - - /* Release reference */ - ObDereferenceObject(Process); - - /* Enter SEH to return data */ - _SEH2_TRY - { - /* Return data to user */ - *UnsafeOldAccessProtection = OldAccessProtection; - *UnsafeBaseAddress = BaseAddress; - *UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Catch exception */ - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - /* Return status */ - return Status; -} - NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE ProcessHandle, IN PVOID Address, @@ -1202,92 +503,4 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle, return(Status); } -NTSTATUS -NTAPI -NtLockVirtualMemory(IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytesToLock, - OUT PSIZE_T NumberOfBytesLocked OPTIONAL) -{ - UNIMPLEMENTED; - if (NumberOfBytesLocked) *NumberOfBytesLocked = 0; - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -NtUnlockVirtualMemory(IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN SIZE_T NumberOfBytesToUnlock, - OUT PSIZE_T NumberOfBytesUnlocked OPTIONAL) -{ - UNIMPLEMENTED; - if (NumberOfBytesUnlocked) *NumberOfBytesUnlocked = 0; - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -NtFlushVirtualMemory(IN HANDLE ProcessHandle, - IN OUT PVOID *BaseAddress, - IN OUT PSIZE_T NumberOfBytesToFlush, - OUT PIO_STATUS_BLOCK IoStatusBlock) -{ - UNIMPLEMENTED; - return STATUS_SUCCESS; -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -NtGetWriteWatch(IN HANDLE ProcessHandle, - IN ULONG Flags, - IN PVOID BaseAddress, - IN SIZE_T RegionSize, - IN PVOID *UserAddressArray, - OUT PULONG_PTR EntriesInUserAddressArray, - OUT PULONG Granularity) -{ - if (!EntriesInUserAddressArray || !Granularity) - { - return STATUS_ACCESS_VIOLATION; - } - - if (!*EntriesInUserAddressArray || !RegionSize) - { - return STATUS_INVALID_PARAMETER; - } - - if (!UserAddressArray) - { - return STATUS_ACCESS_VIOLATION; - } - - /* HACK: Set granularity to PAGE_SIZE */ - *Granularity = PAGE_SIZE; - - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -NtResetWriteWatch(IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN SIZE_T RegionSize) -{ - if (!RegionSize) - { - return STATUS_INVALID_PARAMETER; - } - - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - /* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl-generic.rbuild b/reactos/ntoskrnl/ntoskrnl-generic.rbuild index 46e2ce3737b..c713973d48a 100644 --- a/reactos/ntoskrnl/ntoskrnl-generic.rbuild +++ b/reactos/ntoskrnl/ntoskrnl-generic.rbuild @@ -297,13 +297,15 @@ pnproot.c - - - - kdmemsup.c - - - + + + + + kdmemsup.c + + + + @@ -434,10 +436,13 @@ hypermap.c iosup.c mdlsup.c + mmsup.c ncache.c + pagfault.c pool.c procsup.c syspte.c + virtual.c anonmem.c balance.c @@ -445,7 +450,6 @@ freelist.c marea.c mmfault.c - mmsup.c mminit.c mpw.c pagefile.c diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 745389b50ce..31c01628822 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -379,6 +379,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, BOOLEAN Result, SdAllocated; PSECURITY_DESCRIPTOR SecurityDescriptor; SECURITY_SUBJECT_CONTEXT SubjectContext; + BOOLEAN NeedsPeb = FALSE; + INITIAL_PEB InitialPeb; PAGED_CODE(); PSTRACE(PS_PROCESS_DEBUG, "ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess); @@ -635,17 +637,27 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, SeAuditProcessCreationInfo. ImageFileName); if (!NT_SUCCESS(Status)) goto CleanupWithRef; + + // + // We need a PEB + // + NeedsPeb = TRUE; } else if (Parent) { /* Check if this is a child of the system process */ if (Parent != PsInitialSystemProcess) { + // + // We need a PEB + // + NeedsPeb = TRUE; + /* This is a clone! */ ASSERTMSG("No support for cloning yet\n", FALSE); } else - { + { /* This is the initial system process */ Flags &= ~PS_LARGE_PAGES; Status = MmInitializeProcessAddressSpace(Process, @@ -702,11 +714,34 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, } /* Create PEB only for User-Mode Processes */ - if (Parent) + if ((Parent) && (NeedsPeb)) { - /* Create it */ - Status = MmCreatePeb(Process); - if (!NT_SUCCESS(Status)) goto CleanupWithRef; + // + // Set up the initial PEB + // + RtlZeroMemory(&InitialPeb, sizeof(INITIAL_PEB)); + InitialPeb.Mutant = (HANDLE)-1; + InitialPeb.ImageUsesLargePages = 0; // FIXME: Not yet supported + + // + // Create it only if we have an image section + // + if (SectionHandle) + { + // + // Create it + // + Status = MmCreatePeb(Process, &InitialPeb, &Process->Peb); + if (!NT_SUCCESS(Status)) goto CleanupWithRef; + } + else + { + // + // We have to clone it + // + ASSERTMSG("No support for cloning yet\n", FALSE); + } + } /* The process can now be activated */ diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 78269bc8eac..c7f317ab9c1 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -310,13 +310,13 @@ PspCreateThread(OUT PHANDLE ThreadHandle, if (ThreadContext) { /* User-mode Thread, create Teb */ - TebBase = MmCreateTeb(Process, &Thread->Cid, InitialTeb); - if (!TebBase) + Status = MmCreateTeb(Process, &Thread->Cid, InitialTeb, &TebBase); + if (!NT_SUCCESS(Status)) { /* Failed to create the TEB. Release rundown and dereference */ ExReleaseRundownProtection(&Process->RundownProtect); ObDereferenceObject(Thread); - return STATUS_INSUFFICIENT_RESOURCES; + return Status; } /* Set the Start Addresses */ diff --git a/reactos/ntoskrnl/vdm/vdmmain.c b/reactos/ntoskrnl/vdm/vdmmain.c index 3dcf145a45b..17b7cde3c94 100644 --- a/reactos/ntoskrnl/vdm/vdmmain.c +++ b/reactos/ntoskrnl/vdm/vdmmain.c @@ -22,7 +22,7 @@ VOID NTAPI Ki386VdmEnablePentiumExtentions(VOID) { - DPRINT1("VME detected but not yet supported\n"); + DPRINT("VME detected but not yet supported\n"); } VOID diff --git a/reactos/subsystems/win32/win32k/include/msgqueue.h b/reactos/subsystems/win32/win32k/include/msgqueue.h index 637e236c087..234d0b59eeb 100644 --- a/reactos/subsystems/win32/win32k/include/msgqueue.h +++ b/reactos/subsystems/win32/win32k/include/msgqueue.h @@ -197,6 +197,8 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam); VOID FASTCALL MsqInsertSystemMessage(MSG* Msg); BOOL FASTCALL +MsqIsClkLck(LPMSG Msg, BOOL Remove); +BOOL FASTCALL MsqIsDblClk(LPMSG Msg, BOOL Remove); HWND FASTCALL MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd); diff --git a/reactos/subsystems/win32/win32k/ntuser/input.c b/reactos/subsystems/win32/win32k/ntuser/input.c index 650c9b1229b..8733f7facff 100644 --- a/reactos/subsystems/win32/win32k/ntuser/input.c +++ b/reactos/subsystems/win32/win32k/ntuser/input.c @@ -881,7 +881,7 @@ RawInputThreadMain(PVOID StartContext) } ptiRawInput = PsGetCurrentThreadWin32Thread(); - DPRINT1("\nRaw Input Thread 0x%x \n", ptiRawInput); + DPRINT("\nRaw Input Thread 0x%x \n", ptiRawInput); KeSetPriorityThread(&PsGetCurrentThread()->Tcb, diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index ad113288000..10342d1399b 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -673,6 +673,15 @@ co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT * *HitTest = HTCLIENT; } + if (gspv.bMouseClickLock && ((Msg->message == WM_LBUTTONUP) || (Msg->message == WM_LBUTTONDOWN))) + { + if (MsqIsClkLck(Msg, Remove)) + { + // FIXME: drop the message, hack: use WM_NULL + Msg->message = WM_NULL; + } + } + if(IS_BTN_MESSAGE(Msg->message, DOWN)) { /* generate double click messages, if necessary */ diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index 9b4c1d5fd62..1ed3ea3ef1a 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -232,6 +232,49 @@ MsqInsertSystemMessage(MSG* Msg) KeSetEvent(&HardwareMessageEvent, IO_NO_INCREMENT, FALSE); } +BOOL FASTCALL +MsqIsClkLck(LPMSG Msg, BOOL Remove) +{ + PTHREADINFO pti; + PWINSTATION_OBJECT WinStaObject; + PSYSTEM_CURSORINFO CurInfo; + BOOL Res = FALSE; + + pti = PsGetCurrentThreadWin32Thread(); + if (pti->Desktop == NULL) + { + return FALSE; + } + + WinStaObject = pti->Desktop->WindowStation; + + CurInfo = IntGetSysCursorInfo(WinStaObject); + + switch (Msg->message) + { + case WM_LBUTTONUP: + Res = ((Msg->time - CurInfo->ClickLockTime) >= gspv.dwMouseClickLockTime); + if (Res && (!CurInfo->ClickLockActive)) + { + CurInfo->ClickLockActive = TRUE; + } + break; + case WM_LBUTTONDOWN: + if (CurInfo->ClickLockActive) + { + Res = TRUE; + CurInfo->ClickLockActive = FALSE; + CurInfo->ClickLockTime = 0; + } + else + { + CurInfo->ClickLockTime = Msg->time; + } + break; + } + return Res; +} + BOOL FASTCALL MsqIsDblClk(LPMSG Msg, BOOL Remove) { diff --git a/reactos/subsystems/win32/win32k/ntuser/ntuser.c b/reactos/subsystems/win32/win32k/ntuser/ntuser.c index bcdf6ccc21a..e2ce8e2e6b3 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntuser.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntuser.c @@ -136,8 +136,8 @@ NtUserInitialize( { NTSTATUS Status; - DPRINT1("Enter NtUserInitialize(%lx, %p, %p)\n", - dwWinVersion, hPowerRequestEvent, hMediaRequestEvent); + DPRINT("Enter NtUserInitialize(%lx, %p, %p)\n", + dwWinVersion, hPowerRequestEvent, hMediaRequestEvent); /* Check the Windows version */ if (dwWinVersion != 0) diff --git a/reactos/subsystems/win32/win32k/objects/region.c b/reactos/subsystems/win32/win32k/objects/region.c index 4f65116f8c0..03647c2a512 100644 --- a/reactos/subsystems/win32/win32k/objects/region.c +++ b/reactos/subsystems/win32/win32k/objects/region.c @@ -2988,20 +2988,47 @@ BOOL FASTCALL REGION_RectInRegion( PROSRGNDATA Rgn, - const RECTL *rc + const RECTL *rect ) { PRECTL pCurRect, pRectEnd; + RECT rc; - // this is (just) a useful optimization - if ((Rgn->rdh.nCount > 0) && EXTENTCHECK(&Rgn->rdh.rcBound, rc)) + /* swap the coordinates to make right >= left and bottom >= top */ + /* (region building rectangles are normalized the same way) */ + if( rect->top > rect->bottom) { + rc.top = rect->bottom; + rc.bottom = rect->top; + } else { + rc.top = rect->top; + rc.bottom = rect->bottom; + } + if( rect->right < rect->left) { + rc.right = rect->left; + rc.left = rect->right; + } else { + rc.right = rect->right; + rc.left = rect->left; + } + + /* this is (just) a useful optimization */ + if ((Rgn->rdh.nCount > 0) && EXTENTCHECK(&Rgn->rdh.rcBound, &rc)) { - for (pCurRect = Rgn->Buffer, pRectEnd = pCurRect + Rgn->rdh.nCount; pCurRect < pRectEnd; pCurRect++) + for (pCurRect = Rgn->Buffer, pRectEnd = pCurRect + + Rgn->rdh.nCount; pCurRect < pRectEnd; pCurRect++) { - if (pCurRect->bottom <= rc->top) continue; // not far enough down yet - if (pCurRect->top >= rc->bottom) break; // too far down - if (pCurRect->right <= rc->left) continue; // not far enough over yet - if (pCurRect->left >= rc->right) continue; + if (pCurRect->bottom <= rc.top) + continue; /* not far enough down yet */ + + if (pCurRect->top >= rc.bottom) + break; /* too far down */ + + if (pCurRect->right <= rc.left) + continue; /* not far enough over yet */ + + if (pCurRect->left >= rc.right) { + continue; + } return TRUE; } diff --git a/reactos/tools/rbuild/rbuild.vcproj b/reactos/tools/rbuild/rbuild.vcproj index 26694baf745..1e800a44b9d 100644 --- a/reactos/tools/rbuild/rbuild.vcproj +++ b/reactos/tools/rbuild/rbuild.vcproj @@ -161,7 +161,7 @@ + + diff --git a/reactos/tools/rsym/rsym.h b/reactos/tools/rsym/rsym.h index 82261facec3..cae80e7c69a 100644 --- a/reactos/tools/rsym/rsym.h +++ b/reactos/tools/rsym/rsym.h @@ -45,7 +45,7 @@ typedef unsigned char UCHAR; typedef unsigned short WORD; typedef unsigned short USHORT; typedef unsigned long long ULONGLONG; -#if defined(__x86_64__) && defined(unix) +#if defined(__x86_64__) && !defined(_WIN64) typedef signed int LONG; typedef unsigned int ULONG; typedef unsigned int DWORD; @@ -57,7 +57,7 @@ typedef unsigned long DWORD; #if defined(_WIN64) typedef unsigned __int64 ULONG_PTR; #else -#if defined(__x86_64__) && defined(unix) +#if defined(__x86_64__) && !defined(_WIN64) typedef unsigned int ULONG_PTR; #else typedef unsigned long ULONG_PTR;