Synchronize up to trunk's revision r57784.

svn path=/branches/ros-csrss/; revision=57785
This commit is contained in:
Hermès Bélusca-Maïto 2012-11-30 21:32:42 +00:00
commit 24087a3b01
53 changed files with 1639 additions and 839 deletions

View file

@ -449,7 +449,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -437,7 +437,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -430,7 +430,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "L'ajout d'informations peut involontairement modifier ou supprimer des valeurs et endommager le fonctionnement de composants. Si vous n'êtes pas sûr de la source de ces informations dans '%1', ne les ajoutez pas au Registre.\n\nÊtes-vous sûr de vouloir continuer ?"
IDS_IMPORT_PROMPT "L'ajout d'informations peut involontairement modifier ou supprimer des valeurs et endommager le fonctionnement de composants.\nSi vous n'êtes pas sûr de la source de ces informations dans '%1', ne les ajoutez pas au Registre.\n\nÊtes-vous sûr de vouloir continuer ?"
IDS_IMPORT_OK "Les clés et valeurs contenues dans '%1' ont été correctement ajoutées au Registre."
IDS_IMPORT_ERROR "Impossible d'importer '%1' à la suite d'une erreur lors de la lecture de ce fichier. Il s'agit d'une erreur disque, ou le fichier est endommagé."
IDS_EXPORT_ERROR "Impossible d'exporter dans le fichier '%1' à la suite d'une erreur lors de sa création ou d'une tentative d'écriture, pouvant être due à une erreur de disque ou de système de fichiers."

View file

@ -435,7 +435,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -433,7 +433,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -436,7 +436,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -419,7 +419,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -441,7 +441,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -435,7 +435,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -436,7 +436,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -432,7 +432,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -431,7 +431,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -419,7 +419,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -435,7 +435,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -434,7 +434,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -435,7 +435,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly. If you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%1', do not add it to registry.\n\nAre you sure you want to continue?"
IDS_IMPORT_OK "The keys and values contained in '%1' have been successfully added to the registry."
IDS_IMPORT_ERROR "Cannot import '%1': Error opening the file. There may be a disk, file system error or file may not exist."
IDS_EXPORT_ERROR "Cannot export '%1': Error creating or writing to the file. There may be a disk or file system error."

View file

@ -213,7 +213,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
/* Perform application initialization */
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
return 0;
}
hAccel = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(ID_ACCEL));

View file

@ -158,10 +158,25 @@ BOOL PerformRegAction(REGEDIT_ACTION action, LPWSTR s, BOOL silent)
/* Request import confirmation */
if (!silent)
{
int choice;
LoadStringW(hInst, IDS_IMPORT_PROMPT, szText, COUNT_OF(szText));
if (InfoMessageBox(NULL, MB_YESNO | MB_ICONWARNING, szTitle, szText, filename) != IDYES)
goto cont;
choice = InfoMessageBox(NULL, MB_YESNOCANCEL | MB_ICONWARNING, szTitle, szText, filename);
switch (choice)
{
case IDNO:
goto cont;
case IDCANCEL:
/* The cancel case is useful if the user is importing more than one registry file
at a time, and wants to back out anytime during the import process. This way, the
user doesn't have to resort to ending the regedit process abruptly just to cancel
the operation. */
return TRUE;
default:
break;
}
}
/* Open the file */

View file

@ -1,6 +1,7 @@
add_subdirectory(packages)
#common hives
add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/txtsetup.sif DESTINATION reactos NO_CAB FOR bootcd regtest)
add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/hivecls_${ARCH}.inf DESTINATION reactos NO_CAB NAME_ON_CD hivecls.inf FOR bootcd regtest)
add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/hivedef_${ARCH}.inf DESTINATION reactos NO_CAB NAME_ON_CD hivedef.inf FOR bootcd regtest)
@ -45,6 +46,15 @@ add_cd_file(
#regtest
add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/bootcdregtest/regtest.cmd DESTINATION reactos/bin FOR all)
#autorun.inf
add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/autorun.inf DESTINATION root NO_CAB FOR all)
#icon.ico
add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/icon.ico DESTINATION root NO_CAB FOR all)
#readme.txt
add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/readme.txt DESTINATION root NO_CAB FOR all)
#freeldr.ini
add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/bootcd.ini DESTINATION root NO_CAB NAME_ON_CD freeldr.ini FOR bootcd regtest)
add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/livecd.ini DESTINATION root NAME_ON_CD freeldr.ini FOR livecd)

View file

@ -20,6 +20,7 @@
*/
#include <freeldr.h>
#include <cportlib/cportlib.h>
#define NDEBUG
#include <debug.h>
@ -32,6 +33,10 @@
#define LATCH (CLOCK_TICK_RATE / HZ)
/* Maximum number of COM and LPT ports */
#define MAX_COM_PORTS 4
#define MAX_LPT_PORTS 3
/* No Mouse */
#define MOUSE_TYPE_NONE 0
/* Microsoft Mouse with 2 buttons */
@ -1042,7 +1047,7 @@ DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PCM_SERIAL_DEVICE_DATA SerialDeviceData;
ULONG Irq[4] = {4, 3, 4, 3};
ULONG Irq[MAX_COM_PORTS] = {4, 3, 4, 3};
ULONG Base;
CHAR Buffer[80];
PUSHORT BasePtr;
@ -1053,12 +1058,17 @@ DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
TRACE("DetectSerialPorts()\n");
ControllerNumber = 0;
/*
* The BIOS data area 0x400 holds the address of the first valid COM port.
* Each COM port address is stored in a 2-byte field.
* Infos at: http://www.bioscentral.com/misc/bda.htm
*/
BasePtr = (PUSHORT)0x400;
for (i = 0; i < 2; i++, BasePtr++)
for (i = 0; i < MAX_COM_PORTS; i++, BasePtr++)
{
Base = (ULONG)*BasePtr;
if (Base == 0)
if (Base == 0 || !CpDoesPortExist((PUCHAR)Base))
continue;
TRACE("Found COM%u port at 0x%x\n", i + 1, Base);
@ -1126,7 +1136,7 @@ DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
MmHeapFree(PartialResourceList);
if (!Rs232PortInUse(Base))
if (!Rs232PortInUse(UlongToPtr(Base)))
{
/* Detect serial mouse */
DetectSerialPointerPeripheral(ControllerKey, UlongToPtr(Base));
@ -1142,20 +1152,25 @@ DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
ULONG Irq[3] = {7, 5, (ULONG)-1};
ULONG Irq[MAX_LPT_PORTS] = {7, 5, (ULONG)-1};
CHAR Buffer[80];
PCONFIGURATION_COMPONENT_DATA ControllerKey;
PUSHORT BasePtr;
ULONG Base;
ULONG ControllerNumber;
ULONG ControllerNumber = 0;
ULONG i;
ULONG Size;
TRACE("DetectParallelPorts() called\n");
ControllerNumber = 0;
/*
* The BIOS data area 0x408 holds the address of the first valid LPT port.
* Each LPT port address is stored in a 2-byte field.
* Infos at: http://www.bioscentral.com/misc/bda.htm
*/
BasePtr = (PUSHORT)0x408;
for (i = 0; i < 3; i++, BasePtr++)
for (i = 0; i < MAX_LPT_PORTS; i++, BasePtr++)
{
Base = (ULONG)*BasePtr;
if (Base == 0)

View file

@ -22,267 +22,111 @@
#ifndef _M_ARM
#include <freeldr.h>
#include <cportlib/cportlib.h>
/* MACROS *******************************************************************/
#if DBG
#define DEFAULT_BAUD_RATE 19200
#define DEFAULT_BAUD_RATE 19200
#define SER_RBR(x) ((x)+0)
#define SER_THR(x) ((x)+0)
#define SER_DLL(x) ((x)+0)
#define SER_IER(x) ((x)+1)
#define SER_DLM(x) ((x)+1)
#define SER_IIR(x) ((x)+2)
#define SER_LCR(x) ((x)+3)
#define SR_LCR_CS5 0x00
#define SR_LCR_CS6 0x01
#define SR_LCR_CS7 0x02
#define SR_LCR_CS8 0x03
#define SR_LCR_ST1 0x00
#define SR_LCR_ST2 0x04
#define SR_LCR_PNO 0x00
#define SR_LCR_POD 0x08
#define SR_LCR_PEV 0x18
#define SR_LCR_PMK 0x28
#define SR_LCR_PSP 0x38
#define SR_LCR_BRK 0x40
#define SR_LCR_DLAB 0x80
#define SER_MCR(x) ((x)+4)
#define SR_MCR_DTR 0x01
#define SR_MCR_RTS 0x02
#define SER_LSR(x) ((x)+5)
#define SR_LSR_DR 0x01
#define SR_LSR_TBE 0x20
#define SER_MSR(x) ((x)+6)
#define SR_MSR_CTS 0x10
#define SR_MSR_DSR 0x20
#define SER_SCR(x) ((x)+7)
/* STATIC VARIABLES *********************************************************/
static ULONG Rs232ComPort = 0;
static ULONG Rs232BaudRate = 0;
static PUCHAR Rs232PortBase = (PUCHAR)0;
static ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
/* The com port must only be initialized once! */
/* The COM port must only be initialized once! */
static CPPORT Rs232ComPort;
static BOOLEAN PortInitialized = FALSE;
/* STATIC FUNCTIONS *********************************************************/
static BOOLEAN Rs232DoesComPortExist(PUCHAR BaseAddress)
{
BOOLEAN found;
UCHAR mcr;
UCHAR msr;
found = FALSE;
/* save Modem Control Register (MCR) */
mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress));
/* enable loop mode (set Bit 4 of the MCR) */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
/* clear all modem output bits */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
/* read the Modem Status Register */
msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
/*
* the upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits)
*/
if ((msr & 0xF0) == 0x00)
{
/* set all modem output bits */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F);
/* read the Modem Status Register */
msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
/*
* the upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits)
*/
if ((msr & 0xF0) == 0xF0)
found = TRUE;
}
/* restore MCR */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr);
return (found);
}
/* FUNCTIONS *********************************************************/
BOOLEAN Rs232PortInitialize(ULONG ComPort, ULONG BaudRate)
BOOLEAN Rs232PortInitialize(IN ULONG ComPort,
IN ULONG BaudRate)
{
ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
//char buffer[80];
ULONG divisor;
UCHAR lcr;
NTSTATUS Status;
PUCHAR Address;
if (PortInitialized == FALSE)
if (PortInitialized == FALSE)
{
if (BaudRate == 0)
{
if (BaudRate != 0)
{
Rs232BaudRate = BaudRate;
}
else
{
Rs232BaudRate = DEFAULT_BAUD_RATE;
}
if (ComPort == 0)
{
if (Rs232DoesComPortExist ((PUCHAR)(ULONG_PTR)BaseArray[2]))
{
Rs232PortBase = (PUCHAR)(ULONG_PTR)BaseArray[2];
Rs232ComPort = 2;
/*#ifndef NDEBUG
sprintf (buffer,
"\nSerial port COM%ld found at 0x%lx\n",
ComPort,
(ULONG)PortBase);
HalDisplayString (buffer);
#endif*/ /* NDEBUG */
}
else if (Rs232DoesComPortExist ((PUCHAR)(ULONG_PTR)BaseArray[1]))
{
Rs232PortBase = (PUCHAR)(ULONG_PTR)BaseArray[1];
Rs232ComPort = 1;
/*#ifndef NDEBUG
sprintf (buffer,
"\nSerial port COM%ld found at 0x%lx\n",
ComPort,
(ULONG)PortBase);
HalDisplayString (buffer);
#endif*/ /* NDEBUG */
}
else
{
/*sprintf (buffer,
"\nKernel Debugger: No COM port found!!!\n\n");
HalDisplayString (buffer);*/
return FALSE;
}
}
else
{
if (Rs232DoesComPortExist ((PUCHAR)(ULONG_PTR)BaseArray[ComPort]))
{
Rs232PortBase = (PUCHAR)(ULONG_PTR)BaseArray[ComPort];
Rs232ComPort = ComPort;
/*#ifndef NDEBUG
sprintf (buffer,
"\nSerial port COM%ld found at 0x%lx\n",
ComPort,
(ULONG)PortBase);
HalDisplayString (buffer);
#endif*/ /* NDEBUG */
}
else
{
/*sprintf (buffer,
"\nKernel Debugger: No serial port found!!!\n\n");
HalDisplayString (buffer);*/
return FALSE;
}
}
PortInitialized = TRUE;
BaudRate = DEFAULT_BAUD_RATE;
}
/*
* set baud rate and data format (8N1)
*/
if (ComPort == 0)
{
if (CpDoesPortExist(UlongToPtr(BaseArray[2])))
{
Address = UlongToPtr(BaseArray[2]);
}
else if (CpDoesPortExist(UlongToPtr(BaseArray[1])))
{
Address = UlongToPtr(BaseArray[1]);
}
else
{
return FALSE;
}
}
else if (ComPort <= 4) // 4 == MAX_COM_PORTS
{
if (CpDoesPortExist(UlongToPtr(BaseArray[ComPort])))
{
Address = UlongToPtr(BaseArray[ComPort]);
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
/* turn on DTR and RTS */
WRITE_PORT_UCHAR (SER_MCR(Rs232PortBase), SR_MCR_DTR | SR_MCR_RTS);
Status = CpInitialize(&Rs232ComPort, Address, BaudRate);
if (!NT_SUCCESS(Status)) return FALSE;
/* set DLAB */
lcr = READ_PORT_UCHAR (SER_LCR(Rs232PortBase)) | SR_LCR_DLAB;
WRITE_PORT_UCHAR (SER_LCR(Rs232PortBase), lcr);
PortInitialized = TRUE;
}
/* set baud rate */
divisor = 115200 / BaudRate;
WRITE_PORT_UCHAR (SER_DLL(Rs232PortBase), divisor & 0xff);
WRITE_PORT_UCHAR (SER_DLM(Rs232PortBase), (divisor >> 8) & 0xff);
/* reset DLAB and set 8N1 format */
WRITE_PORT_UCHAR (SER_LCR(Rs232PortBase),
SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
/* read junk out of the RBR */
lcr = READ_PORT_UCHAR (SER_RBR(Rs232PortBase));
/*
* set global info
*/
//KdComPortInUse = (ULONG)PortBase;
/*
* print message to blue screen
*/
/*sprintf (buffer,
"\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
ComPort,
(ULONG)PortBase,
BaudRate);
HalDisplayString (buffer);*/
return TRUE;
return TRUE;
}
BOOLEAN Rs232PortGetByte(PUCHAR ByteRecieved)
BOOLEAN Rs232PortGetByte(PUCHAR ByteReceived)
{
if (PortInitialized == FALSE)
return FALSE;
if (PortInitialized == FALSE)
return FALSE;
if ((READ_PORT_UCHAR (SER_LSR(Rs232PortBase)) & SR_LSR_DR))
{
*ByteRecieved = READ_PORT_UCHAR (SER_RBR(Rs232PortBase));
return TRUE;
}
return FALSE;
return (CpGetByte(&Rs232ComPort, ByteReceived, TRUE) == CP_GET_SUCCESS);
}
BOOLEAN Rs232PortPollByte(PUCHAR ByteRecieved)
/*
BOOLEAN Rs232PortPollByte(PUCHAR ByteReceived)
{
if (PortInitialized == FALSE)
return FALSE;
if (PortInitialized == FALSE)
return FALSE;
while ((READ_PORT_UCHAR (SER_LSR(Rs232PortBase)) & SR_LSR_DR) == 0)
;
*ByteRecieved = READ_PORT_UCHAR (SER_RBR(Rs232PortBase));
return TRUE;
return (CpGetByte(&Rs232ComPort, ByteReceived, FALSE) == CP_GET_SUCCESS);
}
*/
VOID Rs232PortPutByte(UCHAR ByteToSend)
{
if (PortInitialized == FALSE)
return;
if (PortInitialized == FALSE)
return;
while ((READ_PORT_UCHAR (SER_LSR(Rs232PortBase)) & SR_LSR_TBE) == 0)
;
WRITE_PORT_UCHAR (SER_THR(Rs232PortBase), ByteToSend);
CpPutByte(&Rs232ComPort, ByteToSend);
}
#endif /* DBG */
BOOLEAN Rs232PortInUse(ULONG Base)
BOOLEAN Rs232PortInUse(PUCHAR Base)
{
#if DBG
return PortInitialized && Rs232PortBase == (PUCHAR)(ULONG_PTR)Base ? TRUE : FALSE;
return ( (PortInitialized && (Rs232ComPort.Address == Base)) ? TRUE : FALSE );
#else
return FALSE;
#endif

View file

@ -23,6 +23,6 @@
BOOLEAN Rs232PortInitialize(ULONG ComPort, ULONG BaudRate);
BOOLEAN Rs232PortGetByte(PUCHAR ByteRecieved);
BOOLEAN Rs232PortPollByte(PUCHAR ByteRecieved);
// BOOLEAN Rs232PortPollByte(PUCHAR ByteRecieved);
VOID Rs232PortPutByte(UCHAR ByteToSend);
BOOLEAN Rs232PortInUse(ULONG Base);
BOOLEAN Rs232PortInUse(PUCHAR Base);

View file

@ -143,7 +143,7 @@ BOOLEAN
WinLdrPortGetByte(IN ULONG PortId,
OUT PUCHAR Data)
{
return CpGetByte(&Port[PortId], Data, TRUE, FALSE) == CP_GET_SUCCESS;
return CpGetByte(&Port[PortId], Data, TRUE) == CP_GET_SUCCESS;
}
BOOLEAN
@ -151,7 +151,7 @@ WinLdrPortPollOnly(IN ULONG PortId)
{
UCHAR Dummy;
return CpGetByte(&Port[PortId], &Dummy, FALSE, TRUE) == CP_GET_SUCCESS;
return CpGetByte(&Port[PortId], &Dummy, FALSE) == CP_GET_SUCCESS;
}
VOID

View file

@ -18,6 +18,7 @@ list(APPEND SOURCE
lsasrv.c
policy.c
privileges.c
registry.c
security.c
lsasrv.rc
${CMAKE_CURRENT_BINARY_DIR}/lsasrv_stubs.c

View file

@ -895,6 +895,66 @@ LsapCloseDbObject(PLSA_DB_OBJECT DbObject)
}
NTSTATUS
LsapDeleteDbObject(IN PLSA_DB_OBJECT DbObject)
{
PLSA_DB_OBJECT ParentObject = NULL;
WCHAR KeyName[64];
ULONG Index;
NTSTATUS Status = STATUS_SUCCESS;
DbObject->RefCount--;
if (DbObject->RefCount > 0)
return STATUS_SUCCESS;
if (DbObject->KeyHandle != NULL)
{
Index = 0;
while (TRUE)
{
Status = LsapRegEnumerateSubKey(DbObject->KeyHandle,
Index,
64 * sizeof(WCHAR),
KeyName);
if (!NT_SUCCESS(Status))
break;
TRACE("Index: %lu\n", Index);
TRACE("Key name: %S\n", KeyName);
Status = LsapRegDeleteSubKey(DbObject->KeyHandle,
KeyName);
if (!NT_SUCCESS(Status))
break;
}
if (Status == STATUS_NO_MORE_ENTRIES)
Status = STATUS_SUCCESS;
LsapRegDeleteKey(DbObject->KeyHandle);
NtClose(DbObject->KeyHandle);
}
if (DbObject->ParentObject != NULL)
ParentObject = DbObject->ParentObject;
RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
if (ParentObject != NULL)
{
ParentObject->RefCount--;
if (ParentObject->RefCount == 0)
Status = LsapCloseDbObject(ParentObject);
}
return Status;
}
NTSTATUS
LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject,
LPWSTR AttributeName,

View file

@ -97,8 +97,7 @@ NTSTATUS WINAPI LsarClose(
NTSTATUS WINAPI LsarDelete(
LSAPR_HANDLE ObjectHandle)
{
/* Deprecated */
return STATUS_NOT_SUPPORTED;
return LsarDeleteObject(&ObjectHandle);
}
@ -642,8 +641,203 @@ NTSTATUS WINAPI LsarEnumerateAccounts(
PLSAPR_ACCOUNT_ENUM_BUFFER EnumerationBuffer,
DWORD PreferedMaximumLength)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
LSAPR_ACCOUNT_ENUM_BUFFER EnumBuffer = {0, NULL};
PLSA_DB_OBJECT PolicyObject = NULL;
WCHAR AccountKeyName[64];
HANDLE AccountsKeyHandle = NULL;
HANDLE AccountKeyHandle;
HANDLE SidKeyHandle;
ULONG EnumIndex;
ULONG EnumCount;
ULONG RequiredLength;
ULONG DataLength;
ULONG i;
NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%p %p %p %lu)\n", PolicyHandle, EnumerationContext,
EnumerationBuffer, PreferedMaximumLength);
if (EnumerationContext == NULL ||
EnumerationBuffer == NULL)
return STATUS_INVALID_PARAMETER;
EnumerationBuffer->EntriesRead = 0;
EnumerationBuffer->Information = NULL;
/* Validate the PolicyHandle */
Status = LsapValidateDbObject(PolicyHandle,
LsaDbPolicyObject,
POLICY_VIEW_LOCAL_INFORMATION,
&PolicyObject);
if (!NT_SUCCESS(Status))
{
ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
return Status;
}
Status = LsapRegOpenKey(PolicyObject->KeyHandle,
L"Accounts",
KEY_READ,
&AccountsKeyHandle);
if (!NT_SUCCESS(Status))
return Status;
EnumIndex = *EnumerationContext;
EnumCount = 0;
RequiredLength = 0;
while (TRUE)
{
Status = LsapRegEnumerateSubKey(AccountsKeyHandle,
EnumIndex,
64 * sizeof(WCHAR),
AccountKeyName);
if (!NT_SUCCESS(Status))
break;
TRACE("EnumIndex: %lu\n", EnumIndex);
TRACE("Account key name: %S\n", AccountKeyName);
Status = LsapRegOpenKey(AccountsKeyHandle,
AccountKeyName,
KEY_READ,
&AccountKeyHandle);
TRACE("LsapRegOpenKey returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
Status = LsapRegOpenKey(AccountKeyHandle,
L"Sid",
KEY_READ,
&SidKeyHandle);
TRACE("LsapRegOpenKey returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
DataLength = 0;
Status = LsapRegQueryValue(SidKeyHandle,
NULL,
NULL,
NULL,
&DataLength);
TRACE("LsapRegQueryValue returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
TRACE("Data length: %lu\n", DataLength);
if ((RequiredLength + DataLength + sizeof(LSAPR_ACCOUNT_INFORMATION)) > PreferedMaximumLength)
break;
RequiredLength += (DataLength + sizeof(LSAPR_ACCOUNT_INFORMATION));
EnumCount++;
}
LsapRegCloseKey(SidKeyHandle);
}
LsapRegCloseKey(AccountKeyHandle);
}
EnumIndex++;
}
TRACE("EnumCount: %lu\n", EnumCount);
TRACE("RequiredLength: %lu\n", RequiredLength);
EnumBuffer.EntriesRead = EnumCount;
EnumBuffer.Information = midl_user_allocate(EnumCount * sizeof(LSAPR_ACCOUNT_INFORMATION));
if (EnumBuffer.Information == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
EnumIndex = *EnumerationContext;
for (i = 0; i < EnumCount; i++, EnumIndex++)
{
Status = LsapRegEnumerateSubKey(AccountsKeyHandle,
EnumIndex,
64 * sizeof(WCHAR),
AccountKeyName);
if (!NT_SUCCESS(Status))
break;
TRACE("EnumIndex: %lu\n", EnumIndex);
TRACE("Account key name: %S\n", AccountKeyName);
Status = LsapRegOpenKey(AccountsKeyHandle,
AccountKeyName,
KEY_READ,
&AccountKeyHandle);
TRACE("LsapRegOpenKey returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
Status = LsapRegOpenKey(AccountKeyHandle,
L"Sid",
KEY_READ,
&SidKeyHandle);
TRACE("LsapRegOpenKey returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
DataLength = 0;
Status = LsapRegQueryValue(SidKeyHandle,
NULL,
NULL,
NULL,
&DataLength);
TRACE("LsapRegQueryValue returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
EnumBuffer.Information[i].Sid = midl_user_allocate(DataLength);
if (EnumBuffer.Information[i].Sid == NULL)
{
LsapRegCloseKey(AccountKeyHandle);
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
Status = LsapRegQueryValue(SidKeyHandle,
NULL,
NULL,
EnumBuffer.Information[i].Sid,
&DataLength);
TRACE("SampRegQueryValue returned %08lX\n", Status);
}
LsapRegCloseKey(SidKeyHandle);
}
LsapRegCloseKey(AccountKeyHandle);
if (!NT_SUCCESS(Status))
goto done;
}
}
if (NT_SUCCESS(Status))
{
*EnumerationContext += EnumCount;
EnumerationBuffer->EntriesRead = EnumBuffer.EntriesRead;
EnumerationBuffer->Information = EnumBuffer.Information;
}
done:
if (!NT_SUCCESS(Status))
{
if (EnumBuffer.Information)
{
for (i = 0; i < EnumBuffer.EntriesRead; i++)
{
if (EnumBuffer.Information[i].Sid != NULL)
midl_user_free(EnumBuffer.Information[i].Sid);
}
midl_user_free(EnumBuffer.Information);
}
}
if (AccountsKeyHandle != NULL)
LsapRegCloseKey(AccountsKeyHandle);
return Status;
}
@ -1188,8 +1382,30 @@ NTSTATUS WINAPI LsarGetQuotasForAccount(
LSAPR_HANDLE AccountHandle,
PQUOTA_LIMITS QuotaLimits)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PLSA_DB_OBJECT AccountObject;
ULONG Size;
NTSTATUS Status;
TRACE("(%p %p)\n", AccountHandle, QuotaLimits);
/* Validate the account handle */
Status = LsapValidateDbObject(AccountHandle,
LsaDbAccountObject,
ACCOUNT_VIEW,
&AccountObject);
if (!NT_SUCCESS(Status))
{
ERR("Invalid handle (Status %lx)\n", Status);
return Status;
}
/* Get the quota attribute */
Status = LsapGetObjectAttribute(AccountObject,
L"DefQuota",
QuotaLimits,
&Size);
return Status;
}
@ -1198,8 +1414,59 @@ NTSTATUS WINAPI LsarSetQuotasForAccount(
LSAPR_HANDLE AccountHandle,
PQUOTA_LIMITS QuotaLimits)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PLSA_DB_OBJECT AccountObject;
QUOTA_LIMITS InternalQuotaLimits;
ULONG Size;
NTSTATUS Status;
TRACE("(%p %p)\n", AccountHandle, QuotaLimits);
/* Validate the account handle */
Status = LsapValidateDbObject(AccountHandle,
LsaDbAccountObject,
ACCOUNT_ADJUST_QUOTAS,
&AccountObject);
if (!NT_SUCCESS(Status))
{
ERR("Invalid handle (Status %lx)\n", Status);
return Status;
}
/* Get the quota limits attribute */
Size = sizeof(QUOTA_LIMITS);
Status = LsapGetObjectAttribute(AccountObject,
L"DefQuota",
&InternalQuotaLimits,
&Size);
if (!NT_SUCCESS(Status))
{
TRACE("LsapGetObjectAttribute() failed (Status 0x%08lx)\n", Status);
return Status;
}
/* Update the quota limits */
if (QuotaLimits->PagedPoolLimit != 0)
InternalQuotaLimits.PagedPoolLimit = QuotaLimits->PagedPoolLimit;
if (QuotaLimits->NonPagedPoolLimit != 0)
InternalQuotaLimits.NonPagedPoolLimit = QuotaLimits->NonPagedPoolLimit;
if (QuotaLimits->MinimumWorkingSetSize != 0)
InternalQuotaLimits.MinimumWorkingSetSize = QuotaLimits->MinimumWorkingSetSize;
if (QuotaLimits->MaximumWorkingSetSize != 0)
InternalQuotaLimits.MaximumWorkingSetSize = QuotaLimits->MaximumWorkingSetSize;
if (QuotaLimits->PagefileLimit != 0)
InternalQuotaLimits.PagefileLimit = QuotaLimits->PagefileLimit;
/* Set the quota limits attribute */
Status = LsapSetObjectAttribute(AccountObject,
L"DefQuota",
&InternalQuotaLimits,
sizeof(QUOTA_LIMITS));
return Status;
}
@ -1647,7 +1914,7 @@ NTSTATUS WINAPI LsarLookupPrivilegeValue(
TRACE("Privilege: %wZ\n", Name);
Status = LsarpLookupPrivilegeValue((PUNICODE_STRING)Name,
Status = LsarpLookupPrivilegeValue(Name,
Value);
return Status;
@ -1675,7 +1942,8 @@ NTSTATUS WINAPI LsarLookupPrivilegeName(
return Status;
}
Status = LsarpLookupPrivilegeName(Value, (PUNICODE_STRING*)Name);
Status = LsarpLookupPrivilegeName(Value,
Name);
return Status;
}
@ -1699,8 +1967,41 @@ NTSTATUS WINAPI LsarLookupPrivilegeDisplayName(
NTSTATUS WINAPI LsarDeleteObject(
LSAPR_HANDLE *ObjectHandle)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PLSA_DB_OBJECT DbObject;
NTSTATUS Status;
TRACE("(%p)\n", ObjectHandle);
if (ObjectHandle == NULL)
return STATUS_INVALID_PARAMETER;
/* Validate the ObjectHandle */
Status = LsapValidateDbObject(*ObjectHandle,
LsaDbIgnoreObject,
DELETE,
&DbObject);
if (!NT_SUCCESS(Status))
{
ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
return Status;
}
/* You cannot delete the policy object */
if (DbObject->ObjectType == LsaDbPolicyObject)
return STATUS_INVALID_PARAMETER;
/* Delete the database object */
Status = LsapDeleteDbObject(DbObject);
if (!NT_SUCCESS(Status))
{
ERR("LsapDeleteDbObject returned 0x%08lx\n", Status);
return Status;
}
/* Invalidate the object handle */
*ObjectHandle = NULL;
return STATUS_SUCCESS;
}
@ -1725,9 +2026,10 @@ NTSTATUS WINAPI LsarEnumerateAccountRights(
PLSAPR_PRIVILEGE_SET PrivilegeSet = NULL;
PRPC_UNICODE_STRING RightsBuffer = NULL;
PRPC_UNICODE_STRING PrivilegeString;
ACCESS_MASK SystemAccess;
ULONG RightsCount;
ULONG RightsIndex;
ULONG PrivIndex;
ULONG i;
NTSTATUS Status;
TRACE("LsarEnumerateAccountRights(%p %p %p)\n",
@ -1753,13 +2055,23 @@ NTSTATUS WINAPI LsarEnumerateAccountRights(
goto done;
}
/* FIXME: Get account rights */
/* Get account rights */
Status = LsarGetSystemAccessAccount(AccountHandle,
&SystemAccess);
if (!NT_SUCCESS(Status))
{
ERR("LsarGetSystemAccessAccount returned 0x%08lx\n", Status);
goto done;
}
RightsCount = PrivilegeSet->PrivilegeCount;
/* FIXME: Count account rights */
/* Count account rights */
for (i = 0; i < sizeof(ACCESS_MASK) * 8; i++)
{
if (SystemAccess & (1 << i))
RightsCount++;
}
/* We are done if there are no rights to be enumerated */
if (RightsCount == 0)
@ -1780,25 +2092,41 @@ NTSTATUS WINAPI LsarEnumerateAccountRights(
/* Copy the privileges into the buffer */
RightsIndex = 0;
for (PrivIndex = 0; PrivIndex < PrivilegeSet->PrivilegeCount; PrivIndex++)
for (i = 0; i < PrivilegeSet->PrivilegeCount; i++)
{
PrivilegeString = NULL;
Status = LsarLookupPrivilegeName(PolicyHandle,
(PLUID)&PrivilegeSet->Privilege[PrivIndex].Luid,
(PRPC_UNICODE_STRING *)&PrivilegeString);
(PLUID)&PrivilegeSet->Privilege[i].Luid,
&PrivilegeString);
if (!NT_SUCCESS(Status))
goto done;
RightsBuffer[RightsIndex].Length = PrivilegeString->Length;
RightsBuffer[RightsIndex].MaximumLength = PrivilegeString->MaximumLength;
RightsBuffer[RightsIndex].Buffer = PrivilegeString->Buffer;
RightsBuffer[i].Length = PrivilegeString->Length;
RightsBuffer[i].MaximumLength = PrivilegeString->MaximumLength;
RightsBuffer[i].Buffer = PrivilegeString->Buffer;
MIDL_user_free(PrivilegeString);
RightsIndex++;
}
/* FIXME: Copy account rights into the buffer */
/* Copy account rights into the buffer */
for (i = 0; i < sizeof(ACCESS_MASK) * 8; i++)
{
if (SystemAccess & (1 << i))
{
Status = LsapLookupAccountRightName(1 << i,
&PrivilegeString);
if (!NT_SUCCESS(Status))
goto done;
RightsBuffer[i].Length = PrivilegeString->Length;
RightsBuffer[i].MaximumLength = PrivilegeString->MaximumLength;
RightsBuffer[i].Buffer = PrivilegeString->Buffer;
MIDL_user_free(PrivilegeString);
RightsIndex++;
}
}
UserRights->Entries = RightsCount;
UserRights->UserRights = (PRPC_UNICODE_STRING)RightsBuffer;

View file

@ -106,6 +106,9 @@ LsapValidateDbObject(IN LSAPR_HANDLE Handle,
NTSTATUS
LsapCloseDbObject(IN PLSA_DB_OBJECT DbObject);
NTSTATUS
LsapDeleteDbObject(IN PLSA_DB_OBJECT DbObject);
NTSTATUS
LsapGetObjectAttribute(PLSA_DB_OBJECT DbObject,
LPWSTR AttributeName,
@ -252,10 +255,10 @@ LsarSetLocalAccountDomain(PLSA_DB_OBJECT PolicyObject,
/* privileges.c */
NTSTATUS
LsarpLookupPrivilegeName(PLUID Value,
PUNICODE_STRING *Name);
PRPC_UNICODE_STRING *Name);
NTSTATUS
LsarpLookupPrivilegeValue(PUNICODE_STRING Name,
LsarpLookupPrivilegeValue(PRPC_UNICODE_STRING Name,
PLUID Value);
NTSTATUS
@ -263,6 +266,71 @@ LsarpEnumeratePrivileges(DWORD *EnumerationContext,
PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer,
DWORD PreferedMaximumLength);
NTSTATUS
LsapLookupAccountRightName(ULONG RightValue,
PRPC_UNICODE_STRING *Name);
/* registry.h */
NTSTATUS
LsapRegCloseKey(IN HANDLE KeyHandle);
NTSTATUS
LsapRegCreateKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle);
NTSTATUS
LsapRegDeleteSubKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName);
NTSTATUS
LsapRegDeleteKey(IN HANDLE KeyHandle);
NTSTATUS
LsapRegEnumerateSubKey(IN HANDLE KeyHandle,
IN ULONG Index,
IN ULONG Length,
OUT LPWSTR Buffer);
NTSTATUS
LsapRegOpenKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle);
NTSTATUS
LsapRegQueryKeyInfo(IN HANDLE KeyHandle,
OUT PULONG SubKeyCount,
OUT PULONG ValueCount);
NTSTATUS
LsapRegDeleteValue(IN HANDLE KeyHandle,
IN LPWSTR ValueName);
NTSTATUS
LsapRegEnumerateValue(IN HANDLE KeyHandle,
IN ULONG Index,
OUT LPWSTR Name,
IN OUT PULONG NameLength,
OUT PULONG Type OPTIONAL,
OUT PVOID Data OPTIONAL,
IN OUT PULONG DataLength OPTIONAL);
NTSTATUS
LsapRegQueryValue(IN HANDLE KeyHandle,
IN LPWSTR ValueName,
OUT PULONG Type OPTIONAL,
OUT LPVOID Data OPTIONAL,
IN OUT PULONG DataLength OPTIONAL);
NTSTATUS
LsapRegSetValue(IN HANDLE KeyHandle,
IN LPWSTR ValueName,
IN ULONG Type,
IN LPVOID Data,
IN ULONG DataLength);
/* security.c */
NTSTATUS
LsapCreatePolicySd(PSECURITY_DESCRIPTOR *PolicySd,

View file

@ -18,6 +18,12 @@ typedef struct
LPCWSTR Name;
} PRIVILEGE_DATA;
typedef struct
{
ULONG Flag;
LPCWSTR Name;
} RIGHT_DATA;
/* GLOBALS *****************************************************************/
@ -54,14 +60,28 @@ static const PRIVILEGE_DATA WellKnownPrivileges[] =
{{SE_CREATE_GLOBAL_PRIVILEGE, 0}, SE_CREATE_GLOBAL_NAME}
};
static const RIGHT_DATA WellKnownRights[] =
{
{SECURITY_ACCESS_INTERACTIVE_LOGON, SE_INTERACTIVE_LOGON_NAME},
{SECURITY_ACCESS_NETWORK_LOGON, SE_NETWORK_LOGON_NAME},
{SECURITY_ACCESS_BATCH_LOGON, SE_BATCH_LOGON_NAME},
{SECURITY_ACCESS_SERVICE_LOGON, SE_SERVICE_LOGON_NAME},
{SECURITY_ACCESS_DENY_INTERACTIVE_LOGON, SE_DENY_INTERACTIVE_LOGON_NAME},
{SECURITY_ACCESS_DENY_NETWORK_LOGON, SE_DENY_NETWORK_LOGON_NAME},
{SECURITY_ACCESS_DENY_BATCH_LOGON, SE_DENY_BATCH_LOGON_NAME},
{SECURITY_ACCESS_DENY_SERVICE_LOGON, SE_DENY_SERVICE_LOGON_NAME},
{SECURITY_ACCESS_REMOTE_INTERACTIVE_LOGON, SE_REMOTE_INTERACTIVE_LOGON_NAME},
{SECURITY_ACCESS_DENY_REMOTE_INTERACTIVE_LOGON, SE_DENY_REMOTE_INTERACTIVE_LOGON_NAME}
};
/* FUNCTIONS ***************************************************************/
NTSTATUS
LsarpLookupPrivilegeName(PLUID Value,
PUNICODE_STRING *Name)
PRPC_UNICODE_STRING *Name)
{
PUNICODE_STRING NameBuffer;
PRPC_UNICODE_STRING NameBuffer;
ULONG Priv;
if (Value->HighPart != 0 ||
@ -76,7 +96,7 @@ LsarpLookupPrivilegeName(PLUID Value,
if (Value->LowPart == WellKnownPrivileges[Priv].Luid.LowPart &&
Value->HighPart == WellKnownPrivileges[Priv].Luid.HighPart)
{
NameBuffer = MIDL_user_allocate(sizeof(UNICODE_STRING));
NameBuffer = MIDL_user_allocate(sizeof(RPC_UNICODE_STRING));
if (NameBuffer == NULL)
return STATUS_NO_MEMORY;
@ -103,7 +123,7 @@ LsarpLookupPrivilegeName(PLUID Value,
NTSTATUS
LsarpLookupPrivilegeValue(PUNICODE_STRING Name,
LsarpLookupPrivilegeValue(PRPC_UNICODE_STRING Name,
PLUID Value)
{
ULONG Priv;
@ -218,4 +238,43 @@ done:
Status = STATUS_MORE_ENTRIES;
return Status;
}
}
NTSTATUS
LsapLookupAccountRightName(ULONG RightValue,
PRPC_UNICODE_STRING *Name)
{
PRPC_UNICODE_STRING NameBuffer;
ULONG i;
for (i = 0; i < sizeof(WellKnownRights) / sizeof(WellKnownRights[0]); i++)
{
if (WellKnownRights[i].Flag == RightValue)
{
NameBuffer = MIDL_user_allocate(sizeof(RPC_UNICODE_STRING));
if (NameBuffer == NULL)
return STATUS_NO_MEMORY;
NameBuffer->Length = wcslen(WellKnownRights[i].Name) * sizeof(WCHAR);
NameBuffer->MaximumLength = NameBuffer->Length + sizeof(WCHAR);
NameBuffer->Buffer = MIDL_user_allocate(NameBuffer->MaximumLength);
if (NameBuffer == NULL)
{
MIDL_user_free(NameBuffer);
return STATUS_INSUFFICIENT_RESOURCES;
}
wcscpy(NameBuffer->Buffer, WellKnownRights[i].Name);
*Name = NameBuffer;
return STATUS_SUCCESS;
}
}
return STATUS_NO_SUCH_PRIVILEGE;
}
/* EOF */

418
dll/win32/lsasrv/registry.c Normal file
View file

@ -0,0 +1,418 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: Security Account Manager (SAM) Server
* FILE: reactos/dll/win32/samsrv/registry.c
* PURPOSE: Registry helper functions
*
* PROGRAMMERS: Eric Kohl
*/
/* INCLUDES ****************************************************************/
#include "lsasrv.h"
WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
/* FUNCTIONS ***************************************************************/
static
BOOLEAN
IsStringType(ULONG Type)
{
return (Type == REG_SZ) || (Type == REG_EXPAND_SZ) || (Type == REG_MULTI_SZ);
}
NTSTATUS
LsapRegCloseKey(IN HANDLE KeyHandle)
{
return NtClose(KeyHandle);
}
NTSTATUS
LsapRegCreateKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
ULONG Disposition;
RtlInitUnicodeString(&Name, KeyName);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
ParentKeyHandle,
NULL);
/* Create the key */
return ZwCreateKey(KeyHandle,
DesiredAccess,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
}
NTSTATUS
LsapRegDeleteSubKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyName;
HANDLE TargetKey;
NTSTATUS Status;
RtlInitUnicodeString(&SubKeyName,
(LPWSTR)KeyName);
InitializeObjectAttributes(&ObjectAttributes,
&SubKeyName,
OBJ_CASE_INSENSITIVE,
ParentKeyHandle,
NULL);
Status = NtOpenKey(&TargetKey,
DELETE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
return Status;
Status = NtDeleteKey(TargetKey);
NtClose(TargetKey);
return Status;
}
NTSTATUS
LsapRegDeleteKey(IN HANDLE KeyHandle)
{
return NtDeleteKey(KeyHandle);
}
NTSTATUS
LsapRegEnumerateSubKey(IN HANDLE KeyHandle,
IN ULONG Index,
IN ULONG Length,
OUT LPWSTR Buffer)
{
PKEY_BASIC_INFORMATION KeyInfo = NULL;
ULONG BufferLength = 0;
ULONG ReturnedLength;
NTSTATUS Status;
/* Check if we have a name */
if (Length)
{
/* Allocate a buffer for it */
BufferLength = sizeof(KEY_BASIC_INFORMATION) + Length * sizeof(WCHAR);
KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
if (KeyInfo == NULL)
return STATUS_NO_MEMORY;
}
/* Enumerate the key */
Status = ZwEnumerateKey(KeyHandle,
Index,
KeyBasicInformation,
KeyInfo,
BufferLength,
&ReturnedLength);
if (NT_SUCCESS(Status))
{
/* Check if the name fits */
if (KeyInfo->NameLength < (Length * sizeof(WCHAR)))
{
/* Copy it */
RtlMoveMemory(Buffer,
KeyInfo->Name,
KeyInfo->NameLength);
/* Terminate the string */
Buffer[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
}
else
{
/* Otherwise, we ran out of buffer space */
Status = STATUS_BUFFER_OVERFLOW;
}
}
/* Free the buffer and return status */
if (KeyInfo)
RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
return Status;
}
NTSTATUS
LsapRegOpenKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
RtlInitUnicodeString(&Name, KeyName);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
ParentKeyHandle,
NULL);
return NtOpenKey(KeyHandle,
DesiredAccess,
&ObjectAttributes);
}
NTSTATUS
LsapRegQueryKeyInfo(IN HANDLE KeyHandle,
OUT PULONG SubKeyCount,
OUT PULONG ValueCount)
{
KEY_FULL_INFORMATION FullInfoBuffer;
ULONG Length;
NTSTATUS Status;
FullInfoBuffer.ClassLength = 0;
FullInfoBuffer.ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
Status = NtQueryKey(KeyHandle,
KeyFullInformation,
&FullInfoBuffer,
sizeof(KEY_FULL_INFORMATION),
&Length);
TRACE("NtQueryKey() returned status 0x%08lX\n", Status);
if (!NT_SUCCESS(Status))
return Status;
if (SubKeyCount != NULL)
*SubKeyCount = FullInfoBuffer.SubKeys;
if (ValueCount != NULL)
*ValueCount = FullInfoBuffer.Values;
return Status;
}
NTSTATUS
LsapRegDeleteValue(IN HANDLE KeyHandle,
IN LPWSTR ValueName)
{
UNICODE_STRING Name;
RtlInitUnicodeString(&Name,
ValueName);
return NtDeleteValueKey(KeyHandle,
&Name);
}
NTSTATUS
LsapRegEnumerateValue(IN HANDLE KeyHandle,
IN ULONG Index,
OUT LPWSTR Name,
IN OUT PULONG NameLength,
OUT PULONG Type OPTIONAL,
OUT PVOID Data OPTIONAL,
IN OUT PULONG DataLength OPTIONAL)
{
PKEY_VALUE_FULL_INFORMATION ValueInfo = NULL;
ULONG BufferLength = 0;
ULONG ReturnedLength;
NTSTATUS Status;
TRACE("Index: %lu\n", Index);
/* Calculate the required buffer length */
BufferLength = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name);
BufferLength += (MAX_PATH + 1) * sizeof(WCHAR);
if (Data != NULL)
BufferLength += *DataLength;
/* Allocate the value buffer */
ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
if (ValueInfo == NULL)
return STATUS_NO_MEMORY;
/* Enumerate the value*/
Status = ZwEnumerateValueKey(KeyHandle,
Index,
KeyValueFullInformation,
ValueInfo,
BufferLength,
&ReturnedLength);
if (NT_SUCCESS(Status))
{
if (Name != NULL)
{
/* Check if the name fits */
if (ValueInfo->NameLength < (*NameLength * sizeof(WCHAR)))
{
/* Copy it */
RtlMoveMemory(Name,
ValueInfo->Name,
ValueInfo->NameLength);
/* Terminate the string */
Name[ValueInfo->NameLength / sizeof(WCHAR)] = 0;
}
else
{
/* Otherwise, we ran out of buffer space */
Status = STATUS_BUFFER_OVERFLOW;
goto done;
}
}
if (Data != NULL)
{
/* Check if the data fits */
if (ValueInfo->DataLength <= *DataLength)
{
/* Copy it */
RtlMoveMemory(Data,
(PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
ValueInfo->DataLength);
/* if the type is REG_SZ and data is not 0-terminated
* and there is enough space in the buffer NT appends a \0 */
if (IsStringType(ValueInfo->Type) &&
ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
{
WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
if ((ptr > (WCHAR *)Data) && ptr[-1])
*ptr = 0;
}
}
else
{
Status = STATUS_BUFFER_OVERFLOW;
goto done;
}
}
}
done:
if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
{
if (Type != NULL)
*Type = ValueInfo->Type;
if (NameLength != NULL)
*NameLength = ValueInfo->NameLength;
if (DataLength != NULL)
*DataLength = ValueInfo->DataLength;
}
/* Free the buffer and return status */
if (ValueInfo)
RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
return Status;
}
NTSTATUS
LsapRegQueryValue(IN HANDLE KeyHandle,
IN LPWSTR ValueName,
OUT PULONG Type OPTIONAL,
OUT PVOID Data OPTIONAL,
IN OUT PULONG DataLength OPTIONAL)
{
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
UNICODE_STRING Name;
ULONG BufferLength = 0;
NTSTATUS Status;
RtlInitUnicodeString(&Name,
ValueName);
if (DataLength != NULL)
BufferLength = *DataLength;
BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
/* Allocate memory for the value */
ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
if (ValueInfo == NULL)
return STATUS_NO_MEMORY;
/* Query the value */
Status = ZwQueryValueKey(KeyHandle,
&Name,
KeyValuePartialInformation,
ValueInfo,
BufferLength,
&BufferLength);
if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
{
if (Type != NULL)
*Type = ValueInfo->Type;
if (DataLength != NULL)
*DataLength = ValueInfo->DataLength;
}
/* Check if the caller wanted data back, and we got it */
if ((NT_SUCCESS(Status)) && (Data != NULL))
{
/* Copy it */
RtlMoveMemory(Data,
ValueInfo->Data,
ValueInfo->DataLength);
/* if the type is REG_SZ and data is not 0-terminated
* and there is enough space in the buffer NT appends a \0 */
if (IsStringType(ValueInfo->Type) &&
ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
{
WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
if ((ptr > (WCHAR *)Data) && ptr[-1])
*ptr = 0;
}
}
/* Free the memory and return status */
RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
if ((Data == NULL) && (Status == STATUS_BUFFER_OVERFLOW))
Status = STATUS_SUCCESS;
return Status;
}
NTSTATUS
LsapRegSetValue(HANDLE KeyHandle,
LPWSTR ValueName,
ULONG Type,
LPVOID Data,
ULONG DataLength)
{
UNICODE_STRING Name;
RtlInitUnicodeString(&Name,
ValueName);
return ZwSetValueKey(KeyHandle,
&Name,
0,
Type,
Data,
DataLength);
}

View file

@ -2,11 +2,11 @@
spec2def(kdcom.dll kdcom.spec ADD_IMPORTLIB)
if(ARCH STREQUAL "i386")
list(APPEND SOURCE i386/kdbg.c)
list(APPEND SOURCE i386/kdbg.c)
elseif(ARCH STREQUAL "amd64")
list(APPEND SOURCE i386/kdbg.c)
list(APPEND SOURCE i386/kdbg.c)
elseif(ARCH STREQUAL "arm")
list(APPEND SOURCE arm/kdbg.c)
list(APPEND SOURCE arm/kdbg.c)
endif(ARCH STREQUAL "i386")
list(APPEND SOURCE ${CMAKE_CURRENT_BINARY_DIR}/kdcom.def)
@ -17,7 +17,7 @@ set_subsystem(kdcom native)
set_image_base(kdcom 0x00010000)
add_importlibs(kdcom ntoskrnl hal)
target_link_libraries(kdcom cportlib)
add_dependencies(kdcom psdk bugcodes)
add_cd_file(TARGET kdcom DESTINATION reactos/system32 NO_CAB FOR all)
add_cd_file(TARGET kdcom DESTINATION reactos/system32 NO_CAB FOR all)

View file

@ -11,14 +11,17 @@
#define NOEXTAPI
#include <ntifs.h>
#define NDEBUG
#include <halfuncs.h>
#include <stdio.h>
#include <debug.h>
#include "arc/arc.h"
#include "windbgkd.h"
#include <kddll.h>
#include <ioaccess.h> /* port intrinsics */
#include <cportlib/cportlib.h>
#define NDEBUG
#include <debug.h>
typedef struct _KD_PORT_INFORMATION
{
@ -54,14 +57,14 @@ KdPortPutByteEx(
#define DEFAULT_BAUD_RATE 19200
#ifdef _M_IX86
const ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
#if defined(_M_IX86) || defined(_M_AMD64)
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
#elif defined(_M_PPC)
const ULONG BaseArray[2] = {0, 0x800003f8};
const ULONG BaseArray[] = {0, 0x800003F8};
#elif defined(_M_MIPS)
const ULONG BaseArray[3] = {0, 0x80006000, 0x80007000};
const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
#elif defined(_M_ARM)
const ULONG BaseArray[2] = {0, 0xF1012000};
const ULONG BaseArray[] = {0, 0xF1012000};
#else
#error Unknown architecture
#endif
@ -122,68 +125,6 @@ static KD_PORT_INFORMATION DefaultPort = { 0, 0, 0 };
static BOOLEAN PortInitialized = FALSE;
/* STATIC FUNCTIONS *********************************************************/
static BOOLEAN
KdpDoesComPortExist(
IN ULONG BaseAddress)
{
BOOLEAN found;
UCHAR mcr;
UCHAR msr;
found = FALSE;
/* save Modem Control Register (MCR) */
mcr = READ_PORT_UCHAR(SER_MCR(BaseAddress));
/* enable loop mode (set Bit 4 of the MCR) */
WRITE_PORT_UCHAR(SER_MCR(BaseAddress), SR_MCR_LOOP);
/* clear all modem output bits */
WRITE_PORT_UCHAR(SER_MCR(BaseAddress), SR_MCR_LOOP);
/* read the Modem Status Register */
msr = READ_PORT_UCHAR(SER_MSR(BaseAddress));
/*
* the upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits)
*/
if ((msr & 0xF0) == 0x00)
{
/* set all modem output bits */
WRITE_PORT_UCHAR(SER_MCR(BaseAddress), SR_MCR_DTR | SR_MCR_RTS | SR_MCR_OUT1 | SR_MCR_OUT2 | SR_MCR_LOOP);
/* read the Modem Status Register */
msr = READ_PORT_UCHAR(SER_MSR(BaseAddress));
/*
* the upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits)
*/
if ((msr & 0xF0) == 0xF0)
{
/*
* setup a resonable state for the port:
* enable fifo and clear recieve/transmit buffers
*/
WRITE_PORT_UCHAR(SER_FCR(BaseAddress),
(SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT));
WRITE_PORT_UCHAR(SER_FCR(BaseAddress), 0);
READ_PORT_UCHAR(SER_RBR(BaseAddress));
WRITE_PORT_UCHAR(SER_IER(BaseAddress), 0);
found = TRUE;
}
}
/* restore MCR */
WRITE_PORT_UCHAR(SER_MCR(BaseAddress), mcr);
return found;
}
/* FUNCTIONS ****************************************************************/
/* HAL.KdPortInitialize */
@ -203,14 +144,18 @@ KdPortInitialize(
if (PortInformation->ComPort == 0)
{
/*
* Start enumerating COM ports from the last one to the first one,
* and break when we find a valid port.
* If we reach the first element of the list, the invalid COM port,
* then it means that no valid port was found.
*/
for (i = sizeof(BaseArray) / sizeof(BaseArray[0]) - 1; i > 0; i--)
{
if (KdpDoesComPortExist(BaseArray[i]))
if (CpDoesPortExist(UlongToPtr(BaseArray[i])))
{
DefaultPort.BaseAddress = BaseArray[i];
DefaultPort.ComPort = i;
PortInformation->BaseAddress = DefaultPort.BaseAddress;
PortInformation->ComPort = DefaultPort.ComPort;
PortInformation->BaseAddress = DefaultPort.BaseAddress = BaseArray[i];
PortInformation->ComPort = DefaultPort.ComPort = i;
break;
}
}
@ -237,7 +182,7 @@ KdPortInitialize(
}
/* HAL.KdPortInitializeEx */
/* HAL.KdPortInitializeEx ; ReactOS-specific */
BOOLEAN
NTAPI
KdPortInitializeEx(
@ -260,7 +205,7 @@ KdPortInitializeEx(
if (PortInformation->ComPort != 0)
{
if (!KdpDoesComPortExist(BaseArray[PortInformation->ComPort]))
if (!CpDoesPortExist(UlongToPtr(BaseArray[PortInformation->ComPort])))
{
sprintf(buffer,
"\nKernel Debugger: Serial port not found!\n\n");
@ -335,7 +280,7 @@ KdPortGetByte(
}
/* HAL.KdPortGetByteEx */
/* HAL.KdPortGetByteEx ; ReactOS-specific */
BOOLEAN
NTAPI
KdPortGetByteEx(
@ -366,7 +311,7 @@ KdPortPollByte(
}
/* HAL.KdPortPollByteEx */
/* HAL.KdPortPollByteEx ; ReactOS-specific */
BOOLEAN
NTAPI
KdPortPollByteEx(
@ -395,7 +340,7 @@ KdPortPutByte(
KdPortPutByteEx(&DefaultPort, ByteToSend);
}
/* HAL.KdPortPutByteEx */
/* HAL.KdPortPutByteEx ; ReactOS-specific */
VOID
NTAPI
KdPortPutByteEx(

View file

@ -10,7 +10,9 @@ add_library(kdcom SHARED
set_entrypoint(kdcom 0)
set_subsystem(kdcom native)
set_image_base(kdcom 0x00010000)
add_importlibs(kdcom ntoskrnl hal)
target_link_libraries(kdcom cportlib)
add_dependencies(kdcom psdk bugcodes)
add_cd_file(TARGET kdcom DESTINATION reactos/system32 NO_CAB FOR all)

View file

@ -7,9 +7,9 @@
*/
#include "kddll.h"
#include "kdcom.h"
#include <cportlib/cportlib.h>
/* serial debug connection */
/* Serial debug connection */
#define DEFAULT_DEBUG_PORT 2 /* COM2 */
#define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
#define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
@ -19,91 +19,46 @@
#if defined(_M_IX86) || defined(_M_AMD64)
const ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
#elif defined(_M_PPC)
const ULONG BaseArray[2] = {0, 0x800003f8};
const ULONG BaseArray[] = {0, 0x800003F8};
#elif defined(_M_MIPS)
const ULONG BaseArray[3] = {0, 0x80006000, 0x80007000};
const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
#elif defined(_M_ARM)
const ULONG BaseArray[2] = {0, 0xF1012000};
const ULONG BaseArray[] = {0, 0xF1012000};
#else
#error Unknown architecture
#endif
/* GLOBALS ********************************************************************/
PUCHAR ComPortBase;
ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
ULONG ComPortIrq = 0;
CPPORT KdDebugComPort;
ULONG KdDebugComPortIrq = 0; // Not used at the moment.
/* FUNCTIONS ******************************************************************/
NTSTATUS
NTAPI
KdpPortInitialize()
KdpPortInitialize(IN ULONG ComPortNumber,
IN ULONG ComPortBaudRate)
{
ULONG Mode;
NTSTATUS Status;
KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber);
/* Enable loop mode (set Bit 4 of the MCR) */
WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_LOOP);
/* Clear all modem output bits */
WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_LOOP);
/* The upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits) */
if ((READ_PORT_UCHAR(ComPortBase + COM_MSR) & 0xF0) != 0x00)
Status = CpInitialize(&KdDebugComPort,
UlongToPtr(BaseArray[ComPortNumber]),
ComPortBaudRate);
if (!NT_SUCCESS(Status))
{
return STATUS_INVALID_PARAMETER;
}
/* Set all modem output bits */
WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_ALL);
/* The upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits) */
if ((READ_PORT_UCHAR(ComPortBase + COM_MSR) & 0xF0) != 0xF0)
else
{
return STATUS_INVALID_PARAMETER;
KdComPortInUse = KdDebugComPort.Address;
return STATUS_SUCCESS;
}
/* Enable FIFO */
WRITE_PORT_UCHAR(ComPortBase + COM_FCR,
FCR_ENABLE_FIFO | FCR_CLEAR_RCVR | FCR_CLEAR_XMIT);
/* Disable interrupts */
WRITE_PORT_UCHAR(ComPortBase + COM_LCR, 0);
WRITE_PORT_UCHAR(ComPortBase + COM_IEN, 0);
/* Enable on DTR and RTS */
WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_DTR | MCR_RTS);
/* Set DLAB */
WRITE_PORT_UCHAR(ComPortBase + COM_LCR, LCR_DLAB);
/* Set baud rate */
Mode = 115200 / ComPortBaudRate;
WRITE_PORT_UCHAR(ComPortBase + COM_DLL, (UCHAR)(Mode & 0xff));
WRITE_PORT_UCHAR(ComPortBase + COM_DLM, (UCHAR)((Mode >> 8) & 0xff));
/* Reset DLAB and set 8 data bits, 1 stop bit, no parity, no break */
WRITE_PORT_UCHAR(ComPortBase + COM_LCR, LCR_CS8 | LCR_ST1 | LCR_PNO);
/* Check for 16450/16550 scratch register */
WRITE_PORT_UCHAR(ComPortBase + COM_SCR, 0xff);
if (READ_PORT_UCHAR(ComPortBase + COM_SCR) != 0xff)
{
return STATUS_INVALID_PARAMETER;
}
WRITE_PORT_UCHAR(ComPortBase + COM_SCR, 0x00);
if (READ_PORT_UCHAR(ComPortBase + COM_SCR) != 0x00)
{
return STATUS_INVALID_PARAMETER;
}
return STATUS_SUCCESS;
}
/******************************************************************************
@ -114,9 +69,11 @@ KdpPortInitialize()
*/
NTSTATUS
NTAPI
KdDebuggerInitialize0(
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
{
ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
PCHAR CommandLine, PortString, BaudString, IrqString;
ULONG Value;
@ -136,7 +93,7 @@ KdDebuggerInitialize0(
/* Get the port and baud rate */
PortString = strstr(CommandLine, "DEBUGPORT");
BaudString = strstr(CommandLine, "BAUDRATE");
IrqString = strstr(CommandLine, "IRQ");
IrqString = strstr(CommandLine, "IRQ");
/* Check if we got the /DEBUGPORT parameter */
if (PortString)
@ -154,10 +111,10 @@ KdDebuggerInitialize0(
return STATUS_INVALID_PARAMETER;
}
/* Gheck for a valid Serial Port */
/* Check for a valid Serial Port */
PortString += 3;
Value = atol(PortString);
if (Value > 4)
if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
{
return STATUS_INVALID_PARAMETER;
}
@ -198,57 +155,46 @@ KdDebuggerInitialize0(
{
/* Read and set it */
Value = atol(IrqString + 1);
if (Value) ComPortIrq = Value;
if (Value) KdDebugComPortIrq = Value;
}
}
}
/* Get base address */
ComPortBase = UlongToPtr(BaseArray[ComPortNumber]);
KdComPortInUse = ComPortBase;
/* Initialize the port */
return KdpPortInitialize();
return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
}
VOID
NTAPI
KdpSendByte(IN BYTE Byte)
{
/* Wait for the port to be ready */
while ((READ_PORT_UCHAR(ComPortBase + COM_LSR) & LSR_TBE) == 0);
/* This is needed due to subtle timing issues */
READ_PORT_UCHAR(ComPortBase + COM_MSR);
while ((READ_PORT_UCHAR(ComPortBase + COM_LSR) & LSR_TBE) == 0);
READ_PORT_UCHAR(ComPortBase + COM_MSR);
/* Send the byte */
WRITE_PORT_UCHAR(ComPortBase + COM_DAT, Byte);
CpPutByte(&KdDebugComPort, Byte);
}
KDP_STATUS
NTAPI
KdpPollByte(OUT PBYTE OutByte)
{
READ_PORT_UCHAR(ComPortBase + COM_MSR); // Timing
/* Check if data is available */
if ((READ_PORT_UCHAR(ComPortBase + COM_LSR) & LSR_DR))
/* Get the byte */
if (CpGetByte(&KdDebugComPort, OutByte, FALSE) == CP_GET_SUCCESS)
{
/* Yes, return the byte */
*OutByte = READ_PORT_UCHAR(ComPortBase + COM_DAT);
return KDP_PACKET_RECEIVED;
}
/* Timed out */
return KDP_PACKET_TIMEOUT;
else
{
/* Timed out */
return KDP_PACKET_TIMEOUT;
}
}
KDP_STATUS
NTAPI
KdpReceiveByte(OUT PBYTE OutByte)
{
// TODO: Use CpGetByte(&KdDebugComPort, OutByte, TRUE);
ULONG Repeats = KdpStallScaleFactor * 100;
while (Repeats--)
@ -267,7 +213,7 @@ KdpReceiveByte(OUT PBYTE OutByte)
KDP_STATUS
NTAPI
KdpPollBreakIn()
KdpPollBreakIn(VOID)
{
UCHAR Byte;
if (KdpPollByte(&Byte) == KDP_PACKET_RECEIVED)
@ -282,8 +228,7 @@ KdpPollBreakIn()
NTSTATUS
NTAPI
KdSave(
IN BOOLEAN SleepTransition)
KdSave(IN BOOLEAN SleepTransition)
{
/* Nothing to do on COM ports */
return STATUS_SUCCESS;
@ -291,10 +236,10 @@ KdSave(
NTSTATUS
NTAPI
KdRestore(
IN BOOLEAN SleepTransition)
KdRestore(IN BOOLEAN SleepTransition)
{
/* Nothing to do on COM ports */
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -1,54 +0,0 @@
/*
* COPYRIGHT: GPL, see COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/base/kddll/kdcom.h
* PURPOSE: COM port definitions for the kernel debugger.
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@ewactos.org)
*/
#pragma once
#define COM_DAT 0x00
#define COM_IEN 0x01 /* interrupt enable register */
#define COM_FCR 0x02 /* FIFO Control Register */
#define COM_LCR 0x03 /* line control registers */
#define COM_MCR 0x04 /* modem control reg */
#define COM_LSR 0x05 /* line status register */
#define COM_MSR 0x06 /* modem status register */
#define COM_SCR 0x07 /* scratch register */
#define COM_DLL 0x00 /* divisor latch least sig */
#define COM_DLM 0x01 /* divisor latch most sig */
#define IEN_ERDA 0x01
#define IEN_ETHRE 0x02
#define IEN_ERLSI 0x04
#define IEN_EMS 0x08
#define IEN_ALL 0x0F
#define FCR_ENABLE_FIFO 0x01
#define FCR_CLEAR_RCVR 0x02
#define FCR_CLEAR_XMIT 0x04
#define LCR_CS5 0x00
#define LCR_CS6 0x01
#define LCR_CS7 0x02
#define LCR_CS8 0x03
#define LCR_ST1 0x00
#define LCR_ST2 0x04
#define LCR_PNO 0x00
#define LCR_POD 0x08
#define LCR_PEV 0x18
#define LCR_PMK 0x28
#define LCR_PSP 0x38
#define LCR_BRK 0x40
#define LCR_DLAB 0x80
#define MCR_DTR 0x01
#define MCR_RTS 0x02
#define MCR_OUT1 0x04 /* general purpose output */
#define MCR_OUT2 0x08
#define MCR_LOOP 0x10 /* loopback testing mode */
#define MCR_ALL (MCR_DTR | MCR_RTS | MCR_OUT1 | MCR_OUT2 | MCR_LOOP)
#define LSR_DR 0x01
#define LSR_TBE 0x20
#define MSR_CTS 0x10 /* (complemented) state of clear to send (CTS). */
#define MSR_DSR 0x20 /* (complemented) state of data set ready (DSR). */
#define MSR_RI 0x40 /* (complemented) state of ring indicator (RI). */
#define MSR_DCD 0x80 /* (complemented) state of data carrier detect (DCD). */

View file

@ -12,15 +12,16 @@
#define NOEXTAPI
#include <ntifs.h>
#define NDEBUG
#include <halfuncs.h>
#include <debug.h>
#include "arc/arc.h"
#include "windbgkd.h"
#include <wdbgexts.h>
#include <ioaccess.h> /* port intrinsics */
#define NDEBUG
#include <debug.h>
long atol(const char *str);
typedef UCHAR BYTE, *PBYTE;

View file

@ -106,25 +106,25 @@ typedef struct _WORKITEM_DATA
#define CLOCKS_PER_BIT 16
/* UART registers and bits */
#define SER_RBR(x) ((x)+0) /* Receive Register */
#define SER_THR(x) ((x)+0) /* Transmit Register */
#define SER_DLL(x) ((x)+0) /* Baud Rate Divisor LSB */
#define SER_IER(x) ((x)+1) /* Interrupt Enable Register */
#define SER_RBR(x) ((PUCHAR)(x)+0) /* Receive Register */
#define SER_THR(x) ((PUCHAR)(x)+0) /* Transmit Register */
#define SER_DLL(x) ((PUCHAR)(x)+0) /* Baud Rate Divisor LSB */
#define SER_IER(x) ((PUCHAR)(x)+1) /* Interrupt Enable Register */
#define SR_IER_DATA_RECEIVED 0x01
#define SR_IER_THR_EMPTY 0x02
#define SR_IER_LSR_CHANGE 0x04
#define SR_IER_MSR_CHANGE 0x08
#define SR_IER_SLEEP_MODE 0x10 /* Uart >= 16750 */
#define SR_IER_LOW_POWER 0x20 /* Uart >= 16750 */
#define SER_DLM(x) ((x)+1) /* Baud Rate Divisor MSB */
#define SER_IIR(x) ((x)+2) /* Interrupt Identification Register */
#define SER_DLM(x) ((PUCHAR)(x)+1) /* Baud Rate Divisor MSB */
#define SER_IIR(x) ((PUCHAR)(x)+2) /* Interrupt Identification Register */
#define SR_IIR_SELF 0x00
#define SR_IIR_ID_MASK 0x07
#define SR_IIR_MSR_CHANGE SR_IIR_SELF
#define SR_IIR_THR_EMPTY (SR_IIR_SELF | 2)
#define SR_IIR_DATA_RECEIVED (SR_IIR_SELF | 4)
#define SR_IIR_ERROR (SR_IIR_SELF | 6)
#define SER_FCR(x) ((x)+2) /* FIFO Control Register (Uart >= 16550A) */
#define SER_FCR(x) ((PUCHAR)(x)+2) /* FIFO Control Register (Uart >= 16550A) */
#define SR_FCR_ENABLE_FIFO 0x01
#define SR_FCR_CLEAR_RCVR (0x02 | SR_FCR_ENABLE_FIFO)
#define SR_FCR_CLEAR_XMIT (0x04 | SR_FCR_ENABLE_FIFO)
@ -132,7 +132,7 @@ typedef struct _WORKITEM_DATA
#define SR_FCR_4_BYTES (0x40 | SR_FCR_ENABLE_FIFO)
#define SR_FCR_8_BYTES (0x80 | SR_FCR_ENABLE_FIFO)
#define SR_FCR_14_BYTES (0xC0 | SR_FCR_ENABLE_FIFO)
#define SER_LCR(x) ((x)+3) /* Line Control Register */
#define SER_LCR(x) ((PUCHAR)(x)+3) /* Line Control Register */
#define SR_LCR_CS5 0x00
#define SR_LCR_CS6 0x01
#define SR_LCR_CS7 0x02
@ -146,10 +146,10 @@ typedef struct _WORKITEM_DATA
#define SR_LCR_PSP 0x38
#define SR_LCR_BRK 0x40
#define SR_LCR_DLAB 0x80
#define SER_MCR(x) ((x)+4) /* Modem Control Register */
#define SER_MCR(x) ((PUCHAR)(x)+4) /* Modem Control Register */
#define SR_MCR_DTR SERIAL_DTR_STATE
#define SR_MCR_RTS SERIAL_RTS_STATE
#define SER_LSR(x) ((x)+5) /* Line Status Register */
#define SER_LSR(x) ((PUCHAR)(x)+5) /* Line Status Register */
#define SR_LSR_DATA_RECEIVED 0x01
#define SR_LSR_OVERRUN_ERROR 0x02
#define SR_LSR_PARITY_ERROR 0x04
@ -158,7 +158,7 @@ typedef struct _WORKITEM_DATA
#define SR_LSR_THR_EMPTY 0x20
#define SR_LSR_TSR_EMPTY 0x40
#define SR_LSR_ERROR_IN_FIFO 0x80 /* Uart >= 16550A */
#define SER_MSR(x) ((x)+6) /* Modem Status Register */
#define SER_MSR(x) ((PUCHAR)(x)+6) /* Modem Status Register */
#define SR_MSR_CTS_CHANGED 0x01
#define SR_MSR_DSR_CHANGED 0x02
#define SR_MSR_RI_CHANGED 0x04
@ -167,7 +167,7 @@ typedef struct _WORKITEM_DATA
#define SR_MSR_DSR SERIAL_DSR_STATE /* Data Set Ready */
#define SI_MSR_RI SERIAL_RI_STATE /* Ring Indicator */
#define SR_MSR_DCD SERIAL_DCD_STATE /* Data Carrier Detect */
#define SER_SCR(x) ((x)+7) /* Scratch Pad Register, Uart >= Uart16450 */
#define SER_SCR(x) ((PUCHAR)(x)+7) /* Scratch Pad Register, Uart >= Uart16450 */
/************************************ circularbuffer.c */

View file

@ -10,60 +10,93 @@
#pragma once
/* Note: These definitions are the internal definitions used by Microsoft serial
driver (see src/kernel/serial/serial.h in WDK source code). Linux uses its own, as
do most other OS.
/* Note: These definitions are the internal definitions used by Microsoft
Serial Driver (see src/serial/serial/serial.h in WDK source code).
Linux uses its own, as do most other OS.
*/
/* Baud master clock */
// #define BAUD_CLOCK 1843200
// #define CLOCKS_PER_BIT 16
#define CLOCK_RATE 115200 // UART clock rate == BAUD_CLOCK / CLOCKS_PER_BIT
// Define the spacing between registers.
#if !defined(SERIAL_REGISTER_STRIDE)
#define SERIAL_REGISTER_STRIDE 1
#endif
#define RECEIVE_BUFFER_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
#define TRANSMIT_HOLDING_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
#define INTERRUPT_ENABLE_REGISTER ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
#define INTERRUPT_IDENT_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
#define FIFO_CONTROL_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
#define LINE_CONTROL_REGISTER ((ULONG)((0x03)*SERIAL_REGISTER_STRIDE))
#define MODEM_CONTROL_REGISTER ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
#define LINE_STATUS_REGISTER ((ULONG)((0x05)*SERIAL_REGISTER_STRIDE))
#define MODEM_STATUS_REGISTER ((ULONG)((0x06)*SERIAL_REGISTER_STRIDE))
#define DIVISOR_LATCH_LSB ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
#define DIVISOR_LATCH_MSB ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
#define SERIAL_REGISTER_SPAN ((ULONG)(7*SERIAL_REGISTER_STRIDE))
#define SERIAL_STATUS_LENGTH ((ULONG)(1*SERIAL_REGISTER_STRIDE))
/*
* Offsets of the various registers, from the base register address.
*/
#define RECEIVE_BUFFER_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
#define TRANSMIT_HOLDING_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
#define INTERRUPT_ENABLE_REGISTER ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
#define INTERRUPT_IDENT_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
#define FIFO_CONTROL_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
#define LINE_CONTROL_REGISTER ((ULONG)((0x03)*SERIAL_REGISTER_STRIDE))
#define MODEM_CONTROL_REGISTER ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
#define LINE_STATUS_REGISTER ((ULONG)((0x05)*SERIAL_REGISTER_STRIDE))
#define MODEM_STATUS_REGISTER ((ULONG)((0x06)*SERIAL_REGISTER_STRIDE))
#define SCRATCH_REGISTER ((ULONG)((0x07)*SERIAL_REGISTER_STRIDE))
#define SERIAL_DATA_LENGTH_5 0x00
#define SERIAL_DATA_LENGTH_6 0x01
#define SERIAL_DATA_LENGTH_7 0x02
#define SERIAL_DATA_LENGTH_8 0x03
#define DIVISOR_LATCH_LSB ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
#define DIVISOR_LATCH_MSB ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
#define SERIAL_REGISTER_LENGTH ((ULONG)(7*SERIAL_REGISTER_STRIDE))
#define SERIAL_IER_RDA 0x01
#define SERIAL_IER_THR 0x02
#define SERIAL_IER_RLS 0x04
#define SERIAL_IER_MS 0x08
// Length of the interrupt status register.
#define SERIAL_STATUS_LENGTH ((ULONG)(1*SERIAL_REGISTER_STRIDE))
/*
* Start, Data, Parity, Stop number of data bits
* transmitted in the Serial Data Unit.
*/
#define SERIAL_DATA_LENGTH_5 0x00
#define SERIAL_DATA_LENGTH_6 0x01
#define SERIAL_DATA_LENGTH_7 0x02
#define SERIAL_DATA_LENGTH_8 0x03
/*
* Masks defining the interrupts that can be enabled or disabled.
*/
#define SERIAL_IER_RDA 0x01 // New incoming data available.
#define SERIAL_IER_THR 0x02 // Space available for another octet in the transmitter.
#define SERIAL_IER_RLS 0x04 // Error occurred with incoming data.
#define SERIAL_IER_MS 0x08 // Change occurred in the modem control line.
/*
* Interrupt Identification Register masks.
*/
#define SERIAL_IIR_RLS 0x06
#define SERIAL_IIR_RDA 0x04
#define SERIAL_IIR_CTI 0x0c
#define SERIAL_IIR_THR 0x02
#define SERIAL_IIR_MS 0x00
#define SERIAL_IIR_FIFOS_ENABLED 0xc0
#define SERIAL_IIR_FIFOS_ENABLED 0xc0
#define SERIAL_IIR_NO_INTERRUPT_PENDING 0x01
#define SERIAL_IIR_MUST_BE_ZERO 0x30
#define SERIAL_IIR_MUST_BE_ZERO 0x30
#define SERIAL_FCR_ENABLE ((UCHAR)0x01)
#define SERIAL_FCR_RCVR_RESET ((UCHAR)0x02)
#define SERIAL_FCR_TXMT_RESET ((UCHAR)0x04)
/*
* Fifo Control Register accessing masks.
*/
#define SERIAL_FCR_DISABLE ((UCHAR)0x00)
#define SERIAL_FCR_ENABLE ((UCHAR)0x01)
#define SERIAL_FCR_RCVR_RESET ((UCHAR)0x02)
#define SERIAL_FCR_TXMT_RESET ((UCHAR)0x04)
#define SERIAL_1_BYTE_HIGH_WATER ((UCHAR)0x00)
#define SERIAL_4_BYTE_HIGH_WATER ((UCHAR)0x40)
#define SERIAL_8_BYTE_HIGH_WATER ((UCHAR)0x80)
#define SERIAL_14_BYTE_HIGH_WATER ((UCHAR)0xc0)
#define SERIAL_1_BYTE_HIGH_WATER ((UCHAR)0x00)
#define SERIAL_4_BYTE_HIGH_WATER ((UCHAR)0x40)
#define SERIAL_8_BYTE_HIGH_WATER ((UCHAR)0x80)
#define SERIAL_14_BYTE_HIGH_WATER ((UCHAR)0xc0)
#define SERIAL_LCR_DLAB 0x80
#define SERIAL_LCR_BREAK 0x40
/*
* Line Control Register accessing masks.
*/
#define SERIAL_LCR_DLAB 0x80 // Divisor Latch Access Bit
#define SERIAL_LCR_BREAK 0x40 // Send a break
/*
* Line Control Register setting bits.
*/
#define SERIAL_5_DATA ((UCHAR)0x00)
#define SERIAL_6_DATA ((UCHAR)0x01)
#define SERIAL_7_DATA ((UCHAR)0x02)
@ -82,27 +115,38 @@
#define SERIAL_SPACE_PARITY ((UCHAR)0x38)
#define SERIAL_PARITY_MASK ((UCHAR)0x38)
#define SERIAL_MCR_DTR 0x01
#define SERIAL_MCR_RTS 0x02
#define SERIAL_MCR_OUT1 0x04
#define SERIAL_MCR_OUT2 0x08
#define SERIAL_MCR_LOOP 0x10
#define SERIAL_MCR_TL16C550CAFE 0x20
/*
* Modem Control Register accessing masks.
*/
#define SERIAL_MCR_DTR 0x01 // Controls the Data Terminal Ready line
#define SERIAL_MCR_RTS 0x02 // Controls the Ready To Send line
#define SERIAL_MCR_OUT1 0x04 // General purpose output
#define SERIAL_MCR_OUT2 0x08 // General purpose output
#define SERIAL_MCR_LOOP 0x10 // Controls the loopback testing mode
#define SERIAL_MCR_TL16C550CAFE 0x20 // Enables Auto Flow Control on a TI TL16C550C
#define SERIAL_LSR_DR 0x01
#define SERIAL_LSR_OE 0x02
#define SERIAL_LSR_PE 0x04
#define SERIAL_LSR_FE 0x08
#define SERIAL_LSR_BI 0x10
#define SERIAL_LSR_THRE 0x20
#define SERIAL_LSR_TEMT 0x40
#define SERIAL_LSR_FIFOERR 0x80
/*
* Line Status Register accessing masks.
*/
#define SERIAL_LSR_DR 0x01 // Data Ready indicator
#define SERIAL_LSR_OE 0x02 // Overrun indicator
#define SERIAL_LSR_PE 0x04 // Parity Error indicator
#define SERIAL_LSR_FE 0x08 // Framing Error indicator
#define SERIAL_LSR_BI 0x10 // Break Interrupt indicator
#define SERIAL_LSR_THRE 0x20 // Transmit Holding Register Empty indicator
#define SERIAL_LSR_TEMT 0x40 // Transmitter Empty indicator
#define SERIAL_LSR_FIFOERR 0x80 // Fifo Error indicator
#define SERIAL_MSR_DCTS 0x01
#define SERIAL_MSR_DDSR 0x02
#define SERIAL_MSR_TERI 0x04
#define SERIAL_MSR_DDCD 0x08
#define SERIAL_MSR_CTS 0x10
#define SERIAL_MSR_DSR 0x20
#define SERIAL_MSR_RI 0x40
#define SERIAL_MSR_DCD 0x80
/*
* Modem Status Register accessing masks.
*/
#define SERIAL_MSR_DCTS 0x01 // Delta Clear To Send
#define SERIAL_MSR_DDSR 0x02 // Delta Data Set Ready
#define SERIAL_MSR_TERI 0x04 // Trailing Edge Ring Indicator
#define SERIAL_MSR_DDCD 0x08 // Delta Data Carrier Detect
#define SERIAL_MSR_CTS 0x10 // Clear To Send
#define SERIAL_MSR_DSR 0x20 // Data Set Ready
#define SERIAL_MSR_RI 0x40 // Ring Indicator
#define SERIAL_MSR_DCD 0x80 // Data Carrier Detect
/* EOF */

View file

@ -10,65 +10,73 @@
#include <ntdef.h>
//
// Return error codes.
//
#define CP_GET_SUCCESS 0
#define CP_GET_NODATA 1
#define CP_GET_ERROR 2
#define CPPORT_FLAG_MODEM_CONTROL 0x02
//
// COM port flags.
//
#define CPPORT_FLAG_MODEM_CONTROL 0x02
typedef struct _CPPORT
{
PUCHAR Address;
ULONG Baud;
USHORT Flags;
PUCHAR Address;
ULONG BaudRate;
USHORT Flags;
} CPPORT, *PCPPORT;
VOID
NTAPI
CpInitialize(
IN PCPPORT Port,
IN PUCHAR Address,
IN ULONG Rate
);
VOID
NTAPI
CpEnableFifo(
IN PUCHAR Address,
IN BOOLEAN Enable
);
BOOLEAN
NTAPI
CpDoesPortExist(
IN PUCHAR Address
);
UCHAR
NTAPI
CpReadLsr(
IN PCPPORT Port,
IN UCHAR ExpectedValue
);
IN PUCHAR Address,
IN BOOLEAN Enable
);
VOID
NTAPI
CpSetBaud(
IN PCPPORT Port,
IN ULONG Rate
);
IN PCPPORT Port,
IN ULONG BaudRate
);
NTSTATUS
NTAPI
CpInitialize(
IN PCPPORT Port,
IN PUCHAR Address,
IN ULONG BaudRate
);
BOOLEAN
NTAPI
CpDoesPortExist(
IN PUCHAR Address
);
UCHAR
NTAPI
CpReadLsr(
IN PCPPORT Port,
IN UCHAR ExpectedValue
);
USHORT
NTAPI
CpGetByte(
IN PCPPORT Port,
IN PUCHAR Byte,
IN BOOLEAN Wait,
IN BOOLEAN Poll
);
IN PCPPORT Port,
OUT PUCHAR Byte,
IN BOOLEAN Wait
);
VOID
NTAPI
CpPutByte(
IN PCPPORT Port,
IN UCHAR Byte
);
IN PCPPORT Port,
IN UCHAR Byte
);
/* EOF */

View file

@ -11,6 +11,10 @@
* documented their serial algorithms, we use the same ones to stay "compliant".
* Do not change this code to "improve" it. It's done this way on purpose, at least on x86.
* -- sir_richard
*
* REPLY: I reworked the COM-port testing code because the original one
* (i.e. the Microsoft's documented one) doesn't work on Virtual PC 2007.
* -- hbelusca
*/
/* NOTE: This code is used by Headless Support (Ntoskrnl.exe and Osloader.exe) and
@ -20,8 +24,8 @@
/* NOTE: The original code supports Modem Control. We currently do not */
/* FIXMEs:
- Make this serial-port specific (NS16550 vs other serial port types)
- Get x64 KDCOM, KDBG, FREELDR, and other current code to use this
- Make this serial-port specific (NS16550 vs other serial port types)
- Get x64 KDCOM, KDBG, FREELDR, and other current code to use this
*/
/* INCLUDES *******************************************************************/
@ -30,100 +34,216 @@
#include <drivers/serial/ns16550.h>
#include <intrin.h>
#include <ioaccess.h>
#include <ntstatus.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
// Wait timeout value
#define TIMEOUT_COUNT 1024 * 200
UCHAR RingIndicator;
/* FUNCTIONS ******************************************************************/
VOID
NTAPI
CpInitialize(IN PCPPORT Port,
IN PUCHAR Address,
IN ULONG Rate)
CpEnableFifo(IN PUCHAR Address,
IN BOOLEAN Enable)
{
/* Reset port data */
Port->Address = Address;
Port->Baud = 0;
/* Set the baud rate */
CpSetBaud(Port, Rate);
/* Enable on DTR and RTS */
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER,
SERIAL_MCR_DTR | SERIAL_MCR_RTS);
/* Disable interrupts */
WRITE_PORT_UCHAR(Address + INTERRUPT_ENABLE_REGISTER, 0);
/* Set FIFO and clear the receive/transmit buffers */
WRITE_PORT_UCHAR(Address + FIFO_CONTROL_REGISTER,
Enable ? SERIAL_FCR_ENABLE | SERIAL_FCR_RCVR_RESET | SERIAL_FCR_TXMT_RESET
: SERIAL_FCR_DISABLE);
}
VOID
NTAPI
CpEnableFifo(IN PUCHAR Address,
IN BOOLEAN Enable)
CpSetBaud(IN PCPPORT Port,
IN ULONG BaudRate)
{
/* Set FIFO */
WRITE_PORT_UCHAR(Address + FIFO_CONTROL_REGISTER, Enable ? SERIAL_FCR_ENABLE : 0);
UCHAR Lcr;
ULONG Mode = CLOCK_RATE / BaudRate;
/* Set the DLAB on */
Lcr = READ_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER);
WRITE_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER, Lcr | SERIAL_LCR_DLAB);
/* Set the baud rate */
WRITE_PORT_UCHAR(Port->Address + DIVISOR_LATCH_LSB, (UCHAR)(Mode & 0xFF));
WRITE_PORT_UCHAR(Port->Address + DIVISOR_LATCH_MSB, (UCHAR)((Mode >> 8) & 0xFF));
/* Reset DLAB */
WRITE_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER, Lcr);
/* Save baud rate in port */
Port->BaudRate = BaudRate;
}
NTSTATUS
NTAPI
CpInitialize(IN PCPPORT Port,
IN PUCHAR Address,
IN ULONG BaudRate)
{
/* Validity checks */
if (Port == NULL || Address == NULL || BaudRate == 0)
return STATUS_INVALID_PARAMETER;
if (!CpDoesPortExist(Address))
return STATUS_NOT_FOUND;
/* Initialize port data */
Port->Address = Address;
Port->BaudRate = 0;
Port->Flags = 0;
/* Disable the interrupts */
WRITE_PORT_UCHAR(Address + LINE_CONTROL_REGISTER, 0);
WRITE_PORT_UCHAR(Address + INTERRUPT_ENABLE_REGISTER, 0);
/* Turn on DTR, RTS and OUT2 */
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER,
SERIAL_MCR_DTR | SERIAL_MCR_RTS | SERIAL_MCR_OUT2);
/* Set the baud rate */
CpSetBaud(Port, BaudRate);
/* Set 8 data bits, 1 stop bit, no parity, no break */
WRITE_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER,
SERIAL_8_DATA | SERIAL_1_STOP | SERIAL_NONE_PARITY);
/* Turn on FIFO */
// TODO: Check whether FIFO exists and turn it on in that case.
CpEnableFifo(Address, TRUE); // for 16550
/* Read junk out of the RBR */
(VOID)READ_PORT_UCHAR(Address + RECEIVE_BUFFER_REGISTER);
return STATUS_SUCCESS;
}
static BOOLEAN
ComPortTest1(IN PUCHAR Address)
{
/*
* See "Building Hardware and Firmware to Complement Microsoft Windows Headless Operation"
* Out-of-Band Management Port Device Requirements:
* The device must act as a 16550 or 16450 UART.
* Windows Server 2003 will test this device using the following process:
* 1. Save off the current modem status register.
* 2. Place the UART into diagnostic mode (The UART is placed into loopback mode
* by writing SERIAL_MCR_LOOP to the modem control register).
* 3. The modem status register is read and the high bits are checked. This means
* SERIAL_MSR_CTS, SERIAL_MSR_DSR, SERIAL_MSR_RI and SERIAL_MSR_DCD should
* all be clear.
* 4. Place the UART in diagnostic mode and turn on OUTPUT (Loopback Mode and
* OUTPUT are both turned on by writing (SERIAL_MCR_LOOP | SERIAL_MCR_OUT1)
* to the modem control register).
* 5. The modem status register is read and the ring indicator is checked.
* This means SERIAL_MSR_RI should be set.
* 6. Restore original modem status register.
*
* REMARK: Strangely enough, the Virtual PC 2007 virtual machine
* doesn't pass this test.
*/
BOOLEAN RetVal = FALSE;
UCHAR Mcr, Msr;
/* Save the Modem Control Register */
Mcr = READ_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER);
/* Enable loop (diagnostic) mode (set Bit 4 of the MCR) */
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, SERIAL_MCR_LOOP);
/* Clear all modem output bits */
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, SERIAL_MCR_LOOP);
/* Read the Modem Status Register */
Msr = READ_PORT_UCHAR(Address + MODEM_STATUS_REGISTER);
/*
* The upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits).
*/
if ((Msr & (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_DCD)) == 0x00)
{
/* Set all modem output bits */
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER,
SERIAL_MCR_OUT1 | SERIAL_MCR_LOOP); // Windows
/* ReactOS
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER,
SERIAL_MCR_DTR | SERIAL_MCR_RTS | SERIAL_MCR_OUT1 | SERIAL_MCR_OUT2 | SERIAL_MCR_LOOP);
*/
/* Read the Modem Status Register */
Msr = READ_PORT_UCHAR(Address + MODEM_STATUS_REGISTER);
/*
* The upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits).
*/
if (Msr & SERIAL_MSR_RI) // Windows
// if (Msr & (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_DCD) == 0xF0) // ReactOS
{
RetVal = TRUE;
}
}
/* Restore the MCR */
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, Mcr);
return RetVal;
}
static BOOLEAN
ComPortTest2(IN PUCHAR Address)
{
/*
* This test checks whether the 16450/16550 scratch register is available.
* If not, the serial port is considered as unexisting.
*/
UCHAR Byte = 0;
do
{
WRITE_PORT_UCHAR(Address + SCRATCH_REGISTER, Byte);
if (READ_PORT_UCHAR(Address + SCRATCH_REGISTER) != Byte)
return FALSE;
} while (++Byte != 0);
return TRUE;
}
BOOLEAN
NTAPI
CpDoesPortExist(IN PUCHAR Address)
{
UCHAR Old;
/*
* See "Building Hardware and Firmware to Complement Microsoft Windows Headless Operation"
* Out-of-Band Management Port Device Requirements:
* The device must act as a 16550 or 16450 UART.
* Windows Server 2003 will test this device using the following process.
* 1. Save off the current modem status register.
* 2. Place the UART into diagnostic mode (The UART is placed into loopback mode
* by writing SERIAL_MCR_LOOP to the modem control register).
* 3. The modem status register is read and the high bits are checked. This means
* SERIAL_MSR_CTS, SERIAL_MSR_DSR, SERIAL_MSR_RI and SERIAL_MSR_DCD should
* all be clear.
* 4. Place the UART in diagnostic mode and turn on OUTPUT (Loopback Mode and
* OUTPUT are both turned on by writing (SERIAL_MCR_LOOP | SERIAL_MCR_OUT1)
* to the modem control register).
* 5. The modem status register is read and the ring indicator is checked.
* This means SERIAL_MSR_RI should be set.
* 6. Restore original modem status register.
*/
Old = READ_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER);
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, SERIAL_MCR_LOOP);
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, SERIAL_MCR_LOOP);
if (!(READ_PORT_UCHAR(Address + MODEM_STATUS_REGISTER) &
(SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_DCD)))
{
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER,
(SERIAL_MCR_OUT1 | SERIAL_MCR_LOOP));
if (READ_PORT_UCHAR(Address + MODEM_STATUS_REGISTER) & SERIAL_MSR_RI)
{
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, Old);
return TRUE;
}
}
WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, Old);
return FALSE;
return ( ComPortTest1(Address) || ComPortTest2(Address) );
}
UCHAR
NTAPI
CpReadLsr(IN PCPPORT Port,
IN UCHAR ExpectedValue)
IN UCHAR ExpectedValue)
{
UCHAR Lsr, Msr;
UCHAR Lsr, Msr;
/* Read the LSR and check if the expected value is present */
/* Read the LSR and check if the expected value is present */
Lsr = READ_PORT_UCHAR(Port->Address + LINE_STATUS_REGISTER);
if (!(Lsr & ExpectedValue))
{
/* Check the MSR for ring indicator toggle */
{
/* Check the MSR for ring indicator toggle */
Msr = READ_PORT_UCHAR(Port->Address + MODEM_STATUS_REGISTER);
/* If the indicator reaches 3, we've seen this on/off twice */
/* If the indicator reaches 3, we've seen this on/off twice */
RingIndicator |= (Msr & SERIAL_MSR_RI) ? 1 : 2;
if (RingIndicator == 3) Port->Flags |= CPPORT_FLAG_MODEM_CONTROL;
}
@ -131,78 +251,48 @@ CpReadLsr(IN PCPPORT Port,
return Lsr;
}
VOID
NTAPI
CpSetBaud(IN PCPPORT Port,
IN ULONG Rate)
{
UCHAR Lcr;
USHORT Mode;
/* Add DLAB */
Lcr = READ_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER);
WRITE_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER, Lcr | SERIAL_LCR_DLAB);
/* Set baud rate */
Mode = (USHORT)(115200 / Rate);
WRITE_PORT_UCHAR(Port->Address + DIVISOR_LATCH_MSB, (UCHAR)((Mode >> 8) & 0xff));
WRITE_PORT_UCHAR(Port->Address + DIVISOR_LATCH_LSB, (UCHAR)(Mode & 0xff));
/* Reset DLAB and set 8 data bits, 1 stop bit, no parity, no break */
WRITE_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER,
SERIAL_8_DATA | SERIAL_1_STOP | SERIAL_NONE_PARITY);
/* Save baud rate in port */
Port->Baud = Rate;
}
USHORT
NTAPI
CpGetByte(IN PCPPORT Port,
IN PUCHAR Byte,
IN BOOLEAN Wait,
IN BOOLEAN Poll)
CpGetByte(IN PCPPORT Port,
OUT PUCHAR Byte,
IN BOOLEAN Wait)
{
UCHAR Lsr;
ULONG i;
UCHAR Lsr;
ULONG LimitCount = Wait ? TIMEOUT_COUNT : 1;
/* Handle early read-before-init */
if (!Port->Address) return CP_GET_NODATA;
/* Handle early read-before-init */
if (!Port->Address) return CP_GET_NODATA;
/* If "wait" mode enabled, spin many times, otherwise attempt just once */
i = Wait ? 204800 : 1;
while (i--)
{
/* Read LSR for data ready */
/* If "wait" mode enabled, spin many times, otherwise attempt just once */
while (LimitCount--)
{
/* Read LSR for data ready */
Lsr = CpReadLsr(Port, SERIAL_LSR_DR);
if ((Lsr & SERIAL_LSR_DR) == SERIAL_LSR_DR)
{
/* If an error happened, clear the byte and fail */
if (Lsr & (SERIAL_LSR_FE | SERIAL_LSR_PE))
{
{
/* If an error happened, clear the byte and fail */
if (Lsr & (SERIAL_LSR_FE | SERIAL_LSR_PE | SERIAL_LSR_OE))
{
*Byte = 0;
return CP_GET_ERROR;
}
/* If only polling was requested by caller, return now */
if (Poll) return CP_GET_SUCCESS;
/* Otherwise read the byte and return it */
/* Otherwise read the byte and return it */
*Byte = READ_PORT_UCHAR(Port->Address + RECEIVE_BUFFER_REGISTER);
/* Handle CD if port is in modem control mode */
/* Handle CD if port is in modem control mode */
if (Port->Flags & CPPORT_FLAG_MODEM_CONTROL)
{
/* Not implemented yet */
DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
{
/* Not implemented yet */
DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
}
/* Byte was read */
/* Byte was read */
return CP_GET_SUCCESS;
}
}
/* Reset LSR, no data was found */
/* Reset LSR, no data was found */
CpReadLsr(Port, 0);
return CP_GET_NODATA;
}
@ -210,18 +300,21 @@ CpGetByte(IN PCPPORT Port,
VOID
NTAPI
CpPutByte(IN PCPPORT Port,
IN UCHAR Byte)
IN UCHAR Byte)
{
/* Check if port is in modem control to handle CD */
while (Port->Flags & CPPORT_FLAG_MODEM_CONTROL)
{
/* Not implemented yet */
DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
/* Check if port is in modem control to handle CD */
// while (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) // Commented for the moment.
if (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) // To be removed when this becomes implemented.
{
/* Not implemented yet */
DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
}
/* Wait for LSR to say we can go ahead */
while (!(CpReadLsr(Port, SERIAL_LSR_THRE) & SERIAL_LSR_THRE));
/* Wait for LSR to say we can go ahead */
while ((CpReadLsr(Port, SERIAL_LSR_THRE) & SERIAL_LSR_THRE) == 0x00);
/* Send the byte */
WRITE_PORT_UCHAR(Port->Address + RECEIVE_BUFFER_REGISTER, Byte);
WRITE_PORT_UCHAR(Port->Address + TRANSMIT_HOLDING_REGISTER, Byte);
}
/* EOF */

View file

@ -15,107 +15,103 @@
CPPORT Port[4] =
{
{NULL, 0, TRUE},
{NULL, 0, TRUE},
{NULL, 0, TRUE},
{NULL, 0, TRUE}
{NULL, 0, TRUE},
{NULL, 0, TRUE},
{NULL, 0, TRUE},
{NULL, 0, TRUE}
};
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
InbvPortEnableFifo(
IN ULONG PortId,
IN BOOLEAN Enable
)
InbvPortEnableFifo(IN ULONG PortId,
IN BOOLEAN Enable)
{
/* Set FIFO as requested */
CpEnableFifo(Port[PortId].Address, Enable);
/* Set FIFO as requested */
CpEnableFifo(Port[PortId].Address, Enable);
}
VOID
NTAPI
InbvPortPutByte(
IN ULONG PortId,
IN BOOLEAN Output
)
InbvPortPutByte(IN ULONG PortId,
IN BOOLEAN Output)
{
/* Send the byte */
CpPutByte(&Port[PortId], Output);
/* Send the byte */
CpPutByte(&Port[PortId], Output);
}
VOID
NTAPI
InbvPortTerminate(
IN ULONG PortId
)
InbvPortTerminate(IN ULONG PortId)
{
/* The port is now available */
Port[PortId].Address = NULL;
/* The port is now available */
Port[PortId].Address = NULL;
}
BOOLEAN
NTAPI
InbvPortInitialize(
IN ULONG BaudRate,
IN ULONG PortNumber,
IN PUCHAR PortAddress,
OUT PULONG PortId,
IN BOOLEAN IsMMIODevice
)
InbvPortInitialize(IN ULONG BaudRate,
IN ULONG PortNumber,
IN PUCHAR PortAddress,
OUT PULONG PortId,
IN BOOLEAN IsMMIODevice)
{
/* Not yet supported */
ASSERT(IsMMIODevice == FALSE);
/* Not yet supported */
ASSERT(IsMMIODevice == FALSE);
/* Set default baud rate */
/* Set default baud rate */
if (BaudRate == 0) BaudRate = 19200;
/* Check if port or address given */
if (PortNumber)
{
/* Pick correct address for port */
if (!PortAddress)
{
/* Check if port or address given */
if (PortNumber)
{
/* Pick correct address for port */
if (!PortAddress)
{
switch (PortNumber)
{
case 1:
PortAddress = (PUCHAR)0x3F8;
break;
{
case 1:
PortAddress = (PUCHAR)0x3F8;
break;
case 2:
PortAddress = (PUCHAR)0x2F8;
break;
case 2:
PortAddress = (PUCHAR)0x2F8;
break;
case 3:
PortAddress = (PUCHAR)0x3E8;
break;
case 3:
PortAddress = (PUCHAR)0x3E8;
break;
default:
PortNumber = 4;
PortAddress = (PUCHAR)0x2E8;
}
}
}
else
{
/* Pick correct port for address */
PortAddress = (PUCHAR)0x2F8;
if (CpDoesPortExist(PortAddress))
{
PortNumber = 2;
default:
PortNumber = 4;
PortAddress = (PUCHAR)0x2E8;
}
}
else
{
PortAddress = (PUCHAR)0x3F8;
if (!CpDoesPortExist(PortAddress)) return FALSE;
PortNumber = 1;
}
}
}
else
{
/* Pick correct port for address */
PortAddress = (PUCHAR)0x2F8;
if (CpDoesPortExist(PortAddress))
{
PortNumber = 2;
}
else
{
PortAddress = (PUCHAR)0x3F8;
if (!CpDoesPortExist(PortAddress)) return FALSE;
PortNumber = 1;
}
}
/* Initialize the port unless it's already up, and then return it */
if (Port[PortNumber - 1].Address) return FALSE;
CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
*PortId = PortNumber - 1;
return TRUE;
/* Initialize the port unless it's already up, and then return it */
if (Port[PortNumber - 1].Address) return FALSE;
CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
*PortId = PortNumber - 1;
return TRUE;
}
/* EOF */

View file

@ -105,7 +105,9 @@ static PETHREAD GspEnumThread;
static FAST_MUTEX GspLock;
extern LIST_ENTRY PsActiveProcessHead;
KD_PORT_INFORMATION GdbPortInfo = { 2, 115200, 0 }; /* FIXME hardcoded for COM2, 115200 baud */
/* FIXME hardcoded for COM2, 115200 baud */
KD_PORT_INFORMATION GdbPortInfo = { 2, 115200, 0 };
/* Number of Registers. */
#define NUMREGS 16

View file

@ -193,7 +193,7 @@ KdInitSystem(IN ULONG BootPhase,
/* Check if this is a comma, a space or a tab */
if ((*DebugOptionEnd == ',') ||
(*DebugOptionEnd == ' ') ||
(*DebugOptionEnd == ' '))
(*DebugOptionEnd == '\t'))
{
/*
* We reached the end of the option or

View file

@ -1088,6 +1088,8 @@ NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* pUnsafePs)
RETURN(FALSE);
}
UserRefObjectCo(Window, &Ref); // Here for the exception.
_SEH2_TRY
{
ProbeForRead(pUnsafePs, sizeof(*pUnsafePs), 1);
@ -1103,8 +1105,6 @@ NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* pUnsafePs)
RETURN(FALSE);
}
UserRefObjectCo(Window, &Ref);
RETURN(IntEndPaint(Window, &Ps));
CLEANUP: