Author: cfinck
Date: Sun Apr 23 15:00:26 2017
New Revision: 74393
URL: http://svn.reactos.org/svn/reactos?rev=74393&view=rev
Log:
[LOCALSPL]
Implement all corner cases of handling the Name parameter in EnumPrinters. This can be done in a common way for all levels.
Fixes more tests.
Modified:
trunk/reactos/win32ss/printing/providers/localspl/printers.c
Modified: trunk/reactos/win32ss/printing/providers/localspl/printers.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/printing/providers…
==============================================================================
--- trunk/reactos/win32ss/printing/providers/localspl/printers.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/printing/providers/localspl/printers.c [iso-8859-1] Sun Apr 23 15:00:26 2017
@@ -297,29 +297,61 @@
}
/**
- * @name _IsLocalComputerName
+ * @name _LocalEnumPrintersCheckName
*
- * Checks if the given Computer Name matches the local Computer Name.
+ * Checks the Name parameter supplied to a call to EnumPrinters.
+ *
+ * @param Flags
+ * Flags parameter of EnumPrinters.
*
* @param Name
- * Computer Name prepended with two backslashes to check.
+ * Name parameter of EnumPrinters to check.
*
* @param pwszComputerName
* Pointer to a string able to hold 2 + MAX_COMPUTERNAME_LENGTH + 1 + 1 characters.
- * Will contain a string "\\COMPUTERNAME\" on success that can be prepended in EnumPrinters.
+ * On return, it may contain a computer name to prepend in EnumPrinters depending on the case.
*
* @param pcchComputerName
- * On success, this pointer receives the length in characters of pwszComputerName.
+ * If a string to prepend is returned, this pointer receives its length in characters.
*
* @return
- * ERROR_SUCCESS on success or an error code on failure.
+ * ERROR_SUCCESS if processing in EnumPrinters can be continued.
+ * ERROR_INVALID_NAME if the Name parameter is invalid for the given flags and this Print Provider.
+ * Any other error code if GetComputerNameW fails. Error codes indicating failure should then be returned by EnumPrinters.
*/
static DWORD
-_IsLocalComputerName(PCWSTR Name, PWSTR pwszComputerName, PDWORD pcchComputerName)
-{
- DWORD dwErrorCode;
-
- // Prepend slashes to the computer name.
+_LocalEnumPrintersCheckName(DWORD Flags, PCWSTR Name, PWSTR pwszComputerName, PDWORD pcchComputerName)
+{
+ PCWSTR pName;
+ PCWSTR pComputerName;
+
+ // If there is no Name parameter to check, we can just continue in EnumPrinters.
+ if (!Name)
+ return ERROR_SUCCESS;
+
+ // Check if Name does not begin with two backslashes (required for specifying Computer Names).
+ if (Name[0] != L'\\' || Name[1] != L'\\')
+ {
+ if (Flags & PRINTER_ENUM_NAME)
+ {
+ // If PRINTER_ENUM_NAME is specified, any given Name parameter may only contain the
+ // Print Provider Name or the local Computer Name.
+
+ // Compare with the Print Provider Name.
+ if (wcsicmp(Name, wszPrintProviderInfo[0]) == 0)
+ return ERROR_SUCCESS;
+
+ // Dismiss anything else.
+ return ERROR_INVALID_NAME;
+ }
+ else
+ {
+ // If PRINTER_ENUM_NAME is not specified, we just ignore anything that is not a Computer Name.
+ return ERROR_SUCCESS;
+ }
+ }
+
+ // Prepend the backslashes to the output computer name.
pwszComputerName[0] = L'\\';
pwszComputerName[1] = L'\\';
@@ -327,29 +359,59 @@
*pcchComputerName = MAX_COMPUTERNAME_LENGTH + 1;
if (!GetComputerNameW(&pwszComputerName[2], pcchComputerName))
{
- dwErrorCode = GetLastError();
- ERR("GetComputerNameW failed with error %lu!\n", dwErrorCode);
- goto Cleanup;
+ ERR("GetComputerNameW failed with error %lu!\n", GetLastError());
+ return GetLastError();
}
// Add the leading slashes to the total length.
*pcchComputerName += 2;
- // Now compare this with the local computer name and reject it with ERROR_INVALID_NAME if it doesn't match.
- if (wcsicmp(&Name[2], &pwszComputerName[2]) != 0)
- {
- dwErrorCode = ERROR_INVALID_NAME;
- goto Cleanup;
- }
-
- // Add a trailing backslash to pwszComputerName, which will later be prepended in front of the printer names.
- pwszComputerName[(*pcchComputerName)++] = L'\\';
- pwszComputerName[*pcchComputerName] = 0;
-
- dwErrorCode = ERROR_SUCCESS;
-
-Cleanup:
- return dwErrorCode;
+ // Compare both names.
+ pComputerName = &pwszComputerName[2];
+ pName = &Name[2];
+ for (;;)
+ {
+ // Are we at the end of the local Computer Name string?
+ if (!*pComputerName)
+ {
+ // Are we also at the end of the supplied Name parameter?
+ // A terminating NUL character and a backslash are both treated as the end, but they are treated differently.
+ if (!*pName)
+ {
+ // If both names match and Name ends with a NUL character, the computer name will be prepended in EnumPrinters.
+ // Add a trailing backslash for that.
+ pwszComputerName[(*pcchComputerName)++] = L'\\';
+ pwszComputerName[*pcchComputerName] = 0;
+ return ERROR_SUCCESS;
+ }
+ else if (*pName == L'\\')
+ {
+ if (Flags & PRINTER_ENUM_NAME)
+ {
+ // If PRINTER_ENUM_NAME is specified and a Name parameter is given, it must be exactly the local
+ // Computer Name with two backslashes prepended. Anything else (like "\\COMPUTERNAME\") is dismissed.
+ return ERROR_INVALID_NAME;
+ }
+ else
+ {
+ // If PRINTER_ENUM_NAME is not specified and a Name parameter is given, it may also end with a backslash.
+ // Only the Computer Name between the backslashes is checked then.
+ // This is largely undocumented, but verified by tests (see winspool_apitest).
+ // In this case, no computer name is prepended in EnumPrinters though.
+ *pwszComputerName = 0;
+ *pcchComputerName = 0;
+ return ERROR_SUCCESS;
+ }
+ }
+ }
+
+ // Compare both Computer Names case-insensitively and reject with ERROR_INVALID_NAME if they don't match.
+ if (towlower(*pName) != towlower(*pComputerName))
+ return ERROR_INVALID_NAME;
+
+ pName++;
+ pComputerName++;
+ }
}
static DWORD
@@ -376,20 +438,19 @@
}
static DWORD
-_LocalEnumPrintersLevel0(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+_LocalEnumPrintersLevel0(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned, DWORD cchComputerName, PWSTR wszComputerName)
{
return ERROR_INVALID_LEVEL;
}
static DWORD
-_LocalEnumPrintersLevel1(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+_LocalEnumPrintersLevel1(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned, DWORD cchComputerName, PWSTR wszComputerName)
{
const WCHAR wszComma[] = L",";
size_t cbName;
size_t cbComment;
size_t cbDescription;
- DWORD cchComputerName = 0;
DWORD dwErrorCode;
DWORD i;
PBYTE pPrinterInfo;
@@ -398,34 +459,13 @@
PLOCAL_PRINTER pPrinter;
PWSTR p;
PWSTR pwszStrings[3];
- WCHAR wszComputerName[2 + MAX_COMPUTERNAME_LENGTH + 1 + 1] = { 0 };
-
- if (Flags & PRINTER_ENUM_NAME)
- {
- if (Name)
- {
- // The user supplied a Computer Name (with leading double backslashes) or Print Provider Name.
- // Only process what's directed at us.
- if (Name[0] == L'\\' && Name[1] == L'\\')
- {
- dwErrorCode = _IsLocalComputerName(Name, wszComputerName, &cchComputerName);
- if (dwErrorCode != ERROR_SUCCESS)
- goto Cleanup;
- }
- else if (wcsicmp(Name, wszPrintProviderInfo[0]) != 0)
- {
- // The user supplied a name that cannot be processed by the Local Print Provider.
- dwErrorCode = ERROR_INVALID_NAME;
- goto Cleanup;
- }
- }
- else
- {
- // The caller wants information about this Print Provider.
- // spoolss packs this into an array of information about all Print Providers.
- dwErrorCode = _DumpLevel1PrintProviderInformation(pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
- goto Cleanup;
- }
+
+ if (Flags & PRINTER_ENUM_NAME && !Name)
+ {
+ // The caller wants information about this Print Provider.
+ // spoolss packs this into an array of information about all Print Providers.
+ dwErrorCode = _DumpLevel1PrintProviderInformation(pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
+ goto Cleanup;
}
// Count the required buffer size and the number of printers.
@@ -513,19 +553,19 @@
}
static DWORD
-_LocalEnumPrintersLevel2(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+_LocalEnumPrintersLevel2(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned, DWORD cchComputerName, PWSTR wszComputerName)
{
return ERROR_INVALID_LEVEL;
}
static DWORD
-_LocalEnumPrintersLevel4(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+_LocalEnumPrintersLevel4(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned, DWORD cchComputerName, PWSTR wszComputerName)
{
return ERROR_INVALID_LEVEL;
}
static DWORD
-_LocalEnumPrintersLevel5(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+_LocalEnumPrintersLevel5(DWORD Flags, PCWSTR Name, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned, DWORD cchComputerName, PWSTR wszComputerName)
{
return ERROR_INVALID_LEVEL;
}
@@ -533,9 +573,12 @@
BOOL WINAPI
LocalEnumPrinters(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
{
+ DWORD cchComputerName = 0;
DWORD dwErrorCode;
-
- // Do no sanity checks here. This is verified by localspl_apitest!
+ WCHAR wszComputerName[2 + MAX_COMPUTERNAME_LENGTH + 1 + 1] = { 0 };
+
+ ASSERT(pcbNeeded);
+ ASSERT(pcReturned);
// Begin counting.
*pcbNeeded = 0;
@@ -558,25 +601,31 @@
goto Cleanup;
}
+ // Check the supplied Name parameter (if any).
+ // This may return a Computer Name string we later prepend to the output.
+ dwErrorCode = _LocalEnumPrintersCheckName(Flags, Name, wszComputerName, &cchComputerName);
+ if (dwErrorCode != ERROR_SUCCESS)
+ goto Cleanup;
+
if (Level == 0)
{
- dwErrorCode = _LocalEnumPrintersLevel0(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
+ dwErrorCode = _LocalEnumPrintersLevel0(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned, cchComputerName, wszComputerName);
}
else if (Level == 1)
{
- dwErrorCode = _LocalEnumPrintersLevel1(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
+ dwErrorCode = _LocalEnumPrintersLevel1(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned, cchComputerName, wszComputerName);
}
else if (Level == 2)
{
- dwErrorCode = _LocalEnumPrintersLevel2(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
+ dwErrorCode = _LocalEnumPrintersLevel2(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned, cchComputerName, wszComputerName);
}
else if (Level == 4)
{
- dwErrorCode = _LocalEnumPrintersLevel4(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
+ dwErrorCode = _LocalEnumPrintersLevel4(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned, cchComputerName, wszComputerName);
}
else if (Level == 5)
{
- dwErrorCode = _LocalEnumPrintersLevel5(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
+ dwErrorCode = _LocalEnumPrintersLevel5(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned, cchComputerName, wszComputerName);
}
else
{
Author: tfaber
Date: Sun Apr 23 09:38:45 2017
New Revision: 74391
URL: http://svn.reactos.org/svn/reactos?rev=74391&view=rev
Log:
[NTOS:MM]
- In NtMapViewOfSection, check for address alignment after validating the handles. This fixes the tests from the previous commit, but is also necessary because information about the section object is necessary to avoid the alignment checks for physical memory sections.
CORE-13113
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/section.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/section.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] Sun Apr 23 09:38:45 2017
@@ -3661,23 +3661,6 @@
}
}
- if (!(AllocationType & MEM_DOS_LIM))
- {
- /* Check for non-allocation-granularity-aligned BaseAddress */
- if (SafeBaseAddress != ALIGN_DOWN_POINTER_BY(SafeBaseAddress, MM_VIRTMEM_GRANULARITY))
- {
- DPRINT("BaseAddress is not at 64-kilobyte address boundary.");
- return STATUS_MAPPED_ALIGNMENT;
- }
-
- /* Do the same for the section offset */
- if (SafeSectionOffset.LowPart != ALIGN_DOWN_BY(SafeSectionOffset.LowPart, MM_VIRTMEM_GRANULARITY))
- {
- DPRINT("SectionOffset is not at 64-kilobyte address boundary.");
- return STATUS_MAPPED_ALIGNMENT;
- }
- }
-
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_VM_OPERATION,
@@ -3698,6 +3681,27 @@
{
ObDereferenceObject(Process);
return Status;
+ }
+
+ if (!(AllocationType & MEM_DOS_LIM))
+ {
+ /* Check for non-allocation-granularity-aligned BaseAddress */
+ if (SafeBaseAddress != ALIGN_DOWN_POINTER_BY(SafeBaseAddress, MM_VIRTMEM_GRANULARITY))
+ {
+ DPRINT("BaseAddress is not at 64-kilobyte address boundary.");
+ ObDereferenceObject(Section);
+ ObDereferenceObject(Process);
+ return STATUS_MAPPED_ALIGNMENT;
+ }
+
+ /* Do the same for the section offset */
+ if (SafeSectionOffset.LowPart != ALIGN_DOWN_BY(SafeSectionOffset.LowPart, MM_VIRTMEM_GRANULARITY))
+ {
+ DPRINT("SectionOffset is not at 64-kilobyte address boundary.");
+ ObDereferenceObject(Section);
+ ObDereferenceObject(Process);
+ return STATUS_MAPPED_ALIGNMENT;
+ }
}
/* Now do the actual mapping */
Author: tfaber
Date: Sun Apr 23 07:24:44 2017
New Revision: 74389
URL: http://svn.reactos.org/svn/reactos?rev=74389&view=rev
Log:
[NTOS:MM]
- Check for ROS section object before accessing the AllocationAttributes member in NtMapViewOfSection, since ARM3 sections use a different structure.
CORE-13113
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/section.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/section.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] Sun Apr 23 07:24:44 2017
@@ -3716,7 +3716,8 @@
if (NT_SUCCESS(Status))
{
/* Check if this is an image for the current process */
- if ((Section->AllocationAttributes & SEC_IMAGE) &&
+ if (MiIsRosSectionObject(Section) &&
+ (Section->AllocationAttributes & SEC_IMAGE) &&
(Process == PsGetCurrentProcess()) &&
(Status != STATUS_IMAGE_NOT_AT_BASE))
{