mirror of
https://github.com/reactos/reactos.git
synced 2024-07-22 04:08:08 +00:00
Synchronize up to trunk's revision r57784.
svn path=/branches/ros-csrss/; revision=57785
This commit is contained in:
commit
24087a3b01
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
418
dll/win32/lsasrv/registry.c
Normal 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);
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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). */
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue