Gelöst in zwei Teilen, mit noch offenen Fragen. vom Fahrer WDK Start Proben auf GitHub, https://github.com/Microsoft/Windows-driver-samples
Auf der SerialReadSymName()
Funktion, änderte ich es den symbolischen Namen zurückkehren Ich wollte, anstatt haben sie den Index von ComDB vorgesehen verwenden. Beachten Sie, dass ich Serenum von UpperFilters Schlüssel in der Inf-Datei entfernen musste, damit es damit funktioniert.
Jetzt hatte ich den Arbeitsgerät-Namen (dh. COM1, COM2 usw.), die verwendet werden konnte, aber in diesem Stadium habe ich die serielle Schnittstelle "Friendly Name" sowieso umbenannt. Um dies zu lösen, die kontextuell, ich die SerialCreateOpen()
mit dem folgenden Code aktualisiert:
if (!extension->FriendlyNameSet) //Added this guard to the device extension { DWORD f_set = 1; HANDLE keyHandle; MySerialSetFriendlyName(extension); extension->FriendlyNameSet = TRUE; }
Mit der Funktion MySerialSetFriendlyName()
wie folgt definiert:
NTSTATUS MySerialSetFriendlyName(PSERIAL_DEVICE_EXTENSION pDevExt)
{
NTSTATUS status = STATUS_SUCCESS;
WCHAR *FriendlyName, *fnprefix, *fnsuffix, *instanceId;
ULONG FriendlyNameLength, instanceLength, temp, i;
fnprefix = BASE_FRIENDLY_NAME_PREFIX_STR;
fnsuffix = BASE_FRIENDLY_NAME_SUFFIX_STR;
temp = pDevExt->InstanceIdentifier;
instanceLength = 0;
while (temp)
{
instanceLength++;
if (temp < 10)
temp = 0;
else
{
temp /= 10;
if (!temp)
instanceLength++;
}
}
if (instanceLength)
{
instanceId = ExAllocatePool(NonPagedPool, instanceLength);
temp = pDevExt->InstanceIdentifier;
WCHAR digit = L'X';
for (i = 0; i < instanceLength; i++)
{
switch (temp % 10)
{
case 0: digit = L'0'; break;
case 1: digit = L'1'; break;
case 2: digit = L'2'; break;
case 3: digit = L'3'; break;
case 4: digit = L'4'; break;
case 5: digit = L'5'; break;
case 6: digit = L'6'; break;
case 7: digit = L'7'; break;
case 8: digit = L'8'; break;
case 9: digit = L'9'; break;
default: digit = L'X'; break;
}
instanceId[instanceLength - i - 1] = digit;
temp /= 10;
}
FriendlyNameLength = BASE_FRIENDLY_NAME_PREFIX_LEN + instanceLength + BASE_FRIENDLY_NAME_SUFFIX_LEN + 1;
FriendlyName = ExAllocatePool(NonPagedPool, FriendlyNameLength * sizeof(WCHAR));
RtlZeroMemory(FriendlyName, FriendlyNameLength * sizeof(WCHAR));
for (i = 0; i < BASE_FRIENDLY_NAME_PREFIX_LEN; i++)
{
FriendlyName[i] = fnprefix[i];
}
for (i = 0; i < instanceLength; i++)
{
FriendlyName[i + BASE_FRIENDLY_NAME_PREFIX_LEN] = instanceId[i];
}
for (i = 0; i < BASE_FRIENDLY_NAME_SUFFIX_LEN; i++)
{
FriendlyName[i + BASE_FRIENDLY_NAME_PREFIX_LEN + instanceLength] = fnsuffix[i];
}
if (pDevExt->PnpRegistryKey)
status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, (PCWSTR)pDevExt->PnpRegistryKey, (PCWSTR)L"FriendlyName", REG_SZ, FriendlyName, FriendlyNameLength * sizeof(WCHAR));
else
status = STATUS_INSUFFICIENT_RESOURCES;
KdPrintEx((DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, "%s :: Changed friendly name to %S (NTSTATUS %08X)\n", __FUNCTION__, FriendlyName, status));
if (!NT_SUCCESS(status))
{
status = STATUS_SUCCESS; //it is enough that we came through here
}
}
return status;
}
(BASE_FRIENDLY_NAME_...
sind Makros, die meine speichern gewählt freundlich Name Präfix (sagen wir L"Communications Port (COM"
) und Suffix (sagen wir L")"
. Sie können sie machen, was Sie brauchen, aber Sie müssen wirklich ihre Länge speichern in separaten Makros, dann)
Auf diese Weise würde der freundliche Name beim ersten Gerät geöffnet werden. Um sicher zu gehen, dass das Gerät sofort den richtigen Namen bekommt, habe ich einfach einen Device Coinstaller geschrieben, der auf dem DIF_INSTALLDEVICE
Befehl den Port nach der Verarbeitung schnell öffnet und schließt. Dies verdient einen Artikel in sich und es ist einfach genug, also werde ich das jetzt nicht veröffentlichen.
Das einzige offene Problem ist das: - Auf diese Weise speichert ComDB immer noch die falsche Nummerierungssequenz. Sie können es zwingen, sich wie gewünscht zu verhalten, indem Sie die Bitmasken Com Name Arbiter
in der Windows-Registrierung ändern, wie in der Verknüpfung in der Frage angegeben, aber Sie können dies nicht für COM1 und COM2 tun, die immer noch an bestimmte E/A-Bereiche gebunden sind und IRQs.
Also, es funktioniert, vorausgesetzt, Sie werden nie auf ComDB in Ihren Anwendungen zugreifen müssen!
In Zeiten, in denen feste serielle Schnittstellen selten sind und USB-Seriell-Adapter verwendet werden, ist dies ziemlich schwer zu erreichen ...Eine immer noch hässliche, aber wahrscheinlich die beste Lösung ist es, eine Art "Scannen" für Ihr Gerät über alle (derzeit nicht verwendeten) seriellen Schnittstellen zu implementieren (oder natürlich den richtigen zu wählen) – Ctx
Das war ich versuche zu vermeiden . Mein Treiber ist vollständig kompatibel mit den SerialPropPages, so dass Sie den Portnamen wie gewohnt über die Benutzeroberfläche ändern können. Mein Problem ist, dass ich zum Beispiel COM5 zu COM1 umbenennen muss, weil Namen schrecklich gegeben sind. –
Es ist der Treiber für den seriellen Port, der den alten DOS-Namen (wie "COM1") mit IoCreateSymbolicLink() erstellt. Umbenennen ist keine Option. Wenn Sie den Treiber nicht reparieren können, sollten Sie nachsehen. Backgrounder: http://www.osronline.com/article.cfm?id=381 –