Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Windows 7: CreateFile COM-Port Access denied

577 views
Skip to first unread message

Martin Eckel

unread,
Mar 5, 2012, 7:51:30 AM3/5/12
to
Hallo,

ich habe hier ein sehr seltsames Problem:

Ein Programm unter Visual Basic 6 soll einen COM-Port mit CreateFile öffnen.

Dies klappt unter Windows XP, auf einem anderen Rechner mit Windows 7
gibt es ERROR_ACCESS_DENIED zurück.

Nun wirds aber seltsam. Eine ältere Version des Programmes öffnet den
COM-Port unter Windows 7 problemlos.
Nun ist an diesem Programmteil aber ewig nichts geändert worden. Auch
der Sourcecode an dieser Stelle ist absolut identisch (direkt CreateFile
schlägt fehl).

Nun weiß ich spontanerweise nicht mehr weiter.
Woran kann es denn liegen wenn CreateFile mit ERROR_ACCESS_DENIED
fehlschlägt?

Gruß,
Martin

Edzard Egberts

unread,
Mar 5, 2012, 8:32:32 AM3/5/12
to
Martin Eckel schrieb:
> Ein Programm unter Visual Basic 6 soll einen COM-Port mit CreateFile
> öffnen.
> Nun weiß ich spontanerweise nicht mehr weiter.
> Woran kann es denn liegen wenn CreateFile mit ERROR_ACCESS_DENIED
> fehlschlägt?

Port ist schon in Verwendung?

Martin Eckel

unread,
Mar 5, 2012, 8:51:30 AM3/5/12
to
Am 05.03.2012 14:32, schrieb Edzard Egberts:
> Port ist schon in Verwendung?

Nein, ich mache das Programm zu, starte die alte Version - Sache läuft.
Mache die alte Version zu, starte die neue - geht nicht.

Gruß,
Martin

Jochen Kalmbach [MS MVP]

unread,
Mar 5, 2012, 9:00:57 AM3/5/12
to
Viren-Scanner?

Greetings
Jochen

Edzard Egberts

unread,
Mar 5, 2012, 9:19:59 AM3/5/12
to
Martin Eckel schrieb:
Na und, würde die neue Version nicht daran hindern, den gleichen Port
zweimal zu öffnen, wenn da was vermurkst ist.
Was macht ein minimales Beispielprogramm?

Wird denn überhaupt richtig geöffnet, alle Flags vorhanden?

m_Port= CreateFile(
"COM1",
GENERIC_READ|GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
0);

Martin Eckel

unread,
Mar 5, 2012, 9:27:47 AM3/5/12
to
Am 05.03.2012 15:19, schrieb Edzard Egberts:
> Na und, würde die neue Version nicht daran hindern, den gleichen Port
> zweimal zu öffnen, wenn da was vermurkst ist.

Würde aber nicht erklären, warum es unter Windows XP läuft...

Martin Richter [MVP]

unread,
Mar 5, 2012, 9:29:30 AM3/5/12
to
Hallo Martin!

> Nun weiß ich spontanerweise nicht mehr weiter.
> Woran kann es denn liegen wenn CreateFile mit ERROR_ACCESS_DENIED
> fehlschlägt?

Benutzt Du erweitere Rechte außer GENERIC_READ|GENERIC_WRITE?
Also GENERIC_ALL, oder FILE_ACCESS_ALL?

Die hättest Du nämlich nicht unter Windows 7 wenn Du nicht den
Admin-Token hast...

Nur eine Vermutung...

--
Martin Richter [MVP] WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written
program is its own hell!" The Tao of Programming
FAQ: http://www.mpdvc.de Samples: http://www.codeproject.com

René König

unread,
Mar 5, 2012, 9:30:42 AM3/5/12
to
Hallo!

Am 05.03.2012 15:19, schrieb Edzard Egberts:
> "COM1",

Das schreit doch geradezu nach Problemen, spätestens bei COM10 fängt es
an. Richtig heißt es \\.\COM1, oder in C ausgedrückt "\\\\.\\COM1".

> FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,

Was in aller Welt soll denn FILE_FLAG_WRITE_THROUGH bei einem seriellen
Anschluss bewirken?

Gruß,
René

Martin Eckel

unread,
Mar 5, 2012, 9:48:02 AM3/5/12
to
Am 05.03.2012 15:29, schrieb Martin Richter [MVP]:
> Benutzt Du erweitere Rechte außer GENERIC_READ|GENERIC_WRITE?

Nein, nur GENERIC_READ|GENERIC_WRITE.

Die CreateFile-Zeile ist in beiden Programmversionen identisch.

Achso, das Problem tritt auch in der Entwicklungsumgebung auf. Und
Visual Studio 6 läuft unter Windows 7 nur mit Admin-Privilegen. Daran
kanns also eigentlich nicht liegen.

Gruß,
Martin

Edzard Egberts

unread,
Mar 5, 2012, 10:02:28 AM3/5/12
to
René König schrieb:
> Hallo!
>
> Am 05.03.2012 15:19, schrieb Edzard Egberts:
>> "COM1",
>
> Das schreit doch geradezu nach Problemen, spätestens bei COM10 fängt
> es an.

Nein, *genau* mit COM10 fangen die Probleme an, ansonsten geht das so.

Außerdem war das ursprünglich ein Zeiger auf eine User-Eingabe, wenn der
also nicht richtig "\\.\COM10" eingibt, ist das doch nicht mein
Problem, soll sich gefälligst mit Windows beschäftigen. In der
Linux-Version muss er auch "/dev/" vor "ttyS10" eingeben, das ist dann
mal fair! :o)

>> FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
>
> Was in aller Welt soll denn FILE_FLAG_WRITE_THROUGH bei einem
> seriellen Anschluss bewirken?

Dass die Daten direkt raus gehen, statt erst gepuffert und dann
irgendwann mal geschrieben zu werden.

René König

unread,
Mar 5, 2012, 10:15:33 AM3/5/12
to
Am 05.03.2012 16:02, schrieb Edzard Egberts:
> Nein, *genau* mit COM10 fangen die Probleme an, ansonsten geht das so.

Mach es richtig, dann funktioniert das *immer*. Das tut auch überhaupt
nicht weh.

> Dass die Daten direkt raus gehen, statt erst gepuffert und dann
> irgendwann mal geschrieben zu werden.

Aber doch nicht beim seriellen Anschluss.

Edzard Egberts

unread,
Mar 5, 2012, 10:39:10 AM3/5/12
to
René König schrieb:
> Am 05.03.2012 16:02, schrieb Edzard Egberts:
>> Nein, *genau* mit COM10 fangen die Probleme an, ansonsten geht das so.
>
> Mach es richtig, dann funktioniert das *immer*. Das tut auch überhaupt
> nicht weh.

In mindestens einem Dutzend Programme Slashes in einen const char*
pfriemeln um Microsoft zu supporten? Doch, das tut weh!

Warum kann MS das nicht selber fixen - seit 17 Jahren benutze ich "COM"
plus Nummer, ist doch idiotisch, dass das im Jahr 2012 mit bestimmten
Nummern nicht funktioniert. Wenn es da keinen wirklich guten Grund für
gibt, bin ich lieber zickig.

>> Dass die Daten direkt raus gehen, statt erst gepuffert und dann
>> irgendwann mal geschrieben zu werden.
>
> Aber doch nicht beim seriellen Anschluss.

Hat sich da seit Win95 etwas geändert?

Stefan Reuther

unread,
Mar 5, 2012, 12:45:55 PM3/5/12
to
Edzard Egberts wrote:
> René König schrieb:
>> Das schreit doch geradezu nach Problemen, spätestens bei COM10 fängt
>> es an.
>
> Nein, *genau* mit COM10 fangen die Probleme an, ansonsten geht das so.

Es gibt auch COM-Anschlüsse, bei denen das deutlich eher anfängt. Es
kommt halt drauf an, ob der Treiber den Alias COM42 -> \\.\com42
einträgt oder nicht.

> Dass die Daten direkt raus gehen, statt erst gepuffert und dann
> irgendwann mal geschrieben zu werden.

Würde mich wundern, wenn da was gepuffert würde. Du redest ja mit dem
Kernel, nicht mit der C-Bibliothek.


Stefan

Edzard Egberts

unread,
Mar 6, 2012, 2:23:47 AM3/6/12
to
Stefan Reuther schrieb:
> Es gibt auch COM-Anschlüsse, bei denen das deutlich eher anfängt. Es
> kommt halt drauf an, ob der Treiber den Alias COM42 -> \\.\com42
> einträgt oder nicht.

Was steckt eigentlich hinter dem "\\.\"? Ich würde das als "aktuelles
Verzeichnis des lokalen Rechners" interpretieren, oder irgend etwas mit
Netzlaufwerk. Kommt mir jedenfalls reichlich abstrus vor, wieder so eine
"Security by Obscurity"-Sache um Entwickler zu ärgern? Oder für die
Home-Version nur 4 Ports zulassen? Sind die vielleicht mit ihrem "COM" +
Nummer nicht klar gekommen und haben das als Netzzugriffe drangepfriemelt?

>> Dass die Daten direkt raus gehen, statt erst gepuffert und dann
>> irgendwann mal geschrieben zu werden.
>
> Würde mich wundern, wenn da was gepuffert würde. Du redest ja mit dem
> Kernel, nicht mit der C-Bibliothek.

Warum soll der denn keine Dateizugriffe puffern? Bei modernen
Betriebssystemen würde ich das eigentlich als Standard ansehen -
Programm schreibt, ist schon weiter gelaufen und irgendwann fängt die
Festplatte an zu rattern. FILE_FLAG_WRITE_THROUGH soll theoretisch auch
dazu führen, dass write() erst zurückkehrt, wenn alle Daten ausgegeben
sind. Das hat MS beim Übergang von Win98 auf 2000/XP aber alles
vermurkst - vorher konnte man mit WaitCommEvent() auf das *exakte* Ende
der Ausgabe warten (mit Oszi geprüft, war auf ein paar Millisekunden
genau), dann ging das plötzlich nicht mehr und ich hatte ein echtes
Problem mit dem Timing meines seriellen Bussystems. Meines Wissens hat
MS das natürlich nie repariert, ein neues Genuine Advantage Nervtool war
wahrscheinlich wichtiger, ************!

Uwe Sieber

unread,
Mar 6, 2012, 3:11:23 AM3/6/12
to
Stefan Reuther wrote:
> Edzard Egberts wrote:
>> René König schrieb:
>>> Das schreit doch geradezu nach Problemen, spätestens bei COM10 fängt
>>> es an.
>> Nein, *genau* mit COM10 fangen die Probleme an, ansonsten geht das so.
>
> Es gibt auch COM-Anschlüsse, bei denen das deutlich eher anfängt. Es
> kommt halt drauf an, ob der Treiber den Alias COM42 -> \\.\com42
> einträgt oder nicht.

Nein, es fängt immer bei COM10 an:
Jeder COM-Port hat einen Sysbolic Link vom "DosDeviceName"
auf dessen Kernel-Objekt, z.B. von COM1 auf \Device\Serial0.

Dass das Öffnen von COM1 bis COM9 ohne das Kennzeichen \\.\
für den Namensraum "Geräte", also im Namensraum "Dateien"
funktioniert, ist irgendwo in der Gegend "Dateisystem" fest
verdrahtet, COM1 bis COM9, AUX, LPT1 bis LPT9, PRN usw. sind
reservierte Dateinamen, die fest auf die jeweiligen Geräte
verweisen, der Treiber des Ports hat darauf keinen Einfluß.

Naming Files, Paths, and Namespaces:
> http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx


Gruß Uwe

Edzard Egberts

unread,
Mar 6, 2012, 5:02:52 AM3/6/12
to
Uwe Sieber schrieb:
Danke, das ist ein interessanter Beitrag. Durchgelesen und die Hände
über den Kopf zusammengeschlagen - was für ein Murks! Und um die
Gerätehierarchie zu sehen, braucht man ein spezielles Tool? Kein Wunder,
dass ich bei Windows nie durchgestiegen bin, transparent wie eine
Jauchegrube. :o(

Uwe Sieber

unread,
Mar 6, 2012, 6:27:48 AM3/6/12
to
Edzard Egberts wrote:
> Uwe Sieber schrieb:
>> Naming Files, Paths, and Namespaces:
>> >
>> http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
>>
>
> Danke, das ist ein interessanter Beitrag. Durchgelesen und die Hände
> über den Kopf zusammengeschlagen - was für ein Murks!

Naja, Win32 sollte nur eine von mehreren Anwendungs-APIs
werden die auf den NT-Kernel aufsetzen, letztlich ist
es das einzige geblieben.
Meist muß es einen auch als Programierer nicht interessieren,
dass Win32-Datei- und Gerätenamen in Kernelnamen übersetzt
werden.

> Und um die Gerätehierarchie zu sehen, braucht man ein
> spezielles Tool?

Ja, um die Objekt-Vernüpfungen zwischen Win32 und Kernel zu
sehen. Für die Gerätehierarchie gibts im Geräte-Manager
"Ansicht" -> "Geräte nach Verbindung".


Gruß Uwe







Edzard Egberts

unread,
Mar 6, 2012, 7:58:10 AM3/6/12
to
Uwe Sieber schrieb:
> Meist muß es einen auch als Programierer nicht interessieren,
> dass Win32-Datei- und Gerätenamen in Kernelnamen übersetzt
> werden.

Jemand, der 15 Jahre für Win32 programmiert hat, sollte aber mal davon
gehört haben!

Das hat mich immer ganz verrückt gemacht - einen ganzen Stapel Bücher zu
Hause und auch im Netz viel gelesen, aber bis heute keine echte
Vorstellung, wie der ganze Kram zusammen hängt! Ich habe den Eindruck,
man muss sich die MSDN durchlesen und dann im Kopf integrieren, um ein
zusammenhängendes Bild zu bekommen. Und meine MSDN ist auf dem "vor
.NET-Stand", weil ich nach der Einführung von .NET nichts mehr gefunden
habe und ich habe eigentlich meistens nur gelesen, wo man klicken muss,
um mit einem bestimmten Tool eine bestimmte Aufgabe zu erfüllen. Man
muss also nicht nur alles lesen, sondern auch gleich genug verstehen, um
den ganzen Müll aussortieren zu können. In meinen Augen hat Windows
unnötige Komplexität zum Verkaufskonzept gemacht.

Seit ich vergleichsweise die Linux-Dokumentation kenne und weiß, dass
man als Programmierer richtig glücklich sein kann und "Workaround"
tatsächlich ein Fremdwort ist, kriege ich schon das Kotzen, wenn ich nur
das typische Windows-Festplattengerappel irgendwo höre...

> > Und um die Gerätehierarchie zu sehen, braucht man ein
> > spezielles Tool?
>
> Ja, um die Objekt-Vernüpfungen zwischen Win32 und Kernel zu
> sehen.

Okay, ich verstehe, dass das eine interne Sache des Betriebssystems ist,
aber wenn es schon nicht für den Anwender offengelegt wird, sollte man
auch nichts davon wissen müssen. Ich habe die Win32 API bisher
tatsächlich für das direkte und einzige Interface zum Kernel gehalten,
so dass man das als ein Gesamtsystem behandeln kann und dass auch Sachen
wie die clib darüber laufen.

Dann steckt die Inkonsistenz also in der API und CreateFile() müsste so
Sachen wie "COM32" richtig auf den Kernel abbilden? Bzw. müsste die API
dann doch eigentlich eine Funktion wie CreateDevice() oder
ConnectDevice() anbieten, habe ich die übersehen?

Stefan Reuther

unread,
Mar 6, 2012, 1:03:27 PM3/6/12
to
Uwe Sieber wrote:
> Stefan Reuther wrote:
>> Edzard Egberts wrote:
>>> Nein, *genau* mit COM10 fangen die Probleme an, ansonsten geht das so.
>>
>> Es gibt auch COM-Anschlüsse, bei denen das deutlich eher anfängt. Es
>> kommt halt drauf an, ob der Treiber den Alias COM42 -> \\.\com42
>> einträgt oder nicht.
>
> Nein, es fängt immer bei COM10 an:
> Jeder COM-Port hat einen Sysbolic Link vom "DosDeviceName"
> auf dessen Kernel-Objekt, z.B. von COM1 auf \Device\Serial0.

Da kann aber jeder Treiber einen solchen Link hinzufügen, und ich bin
mir ziemlich sicher, dass er das Hinzufügen auch vergessen kann.

Da jedoch nach Hinzufügen von "\\.\" bisher jeder funktioniert hat, hab
ich da nicht weiter geforscht.


Stefan

Uwe Sieber

unread,
Mar 7, 2012, 3:11:56 AM3/7/12
to
Stefan Reuther wrote:
> Uwe Sieber wrote:
>> Stefan Reuther wrote:
>>> Edzard Egberts wrote:
>>>> Nein, *genau* mit COM10 fangen die Probleme an, ansonsten geht das so.
>>> Es gibt auch COM-Anschlüsse, bei denen das deutlich eher anfängt. Es
>>> kommt halt drauf an, ob der Treiber den Alias COM42 -> \\.\com42
>>> einträgt oder nicht.
>> Nein, es fängt immer bei COM10 an:
>> Jeder COM-Port hat einen Sysbolic Link vom "DosDeviceName"
>> auf dessen Kernel-Objekt, z.B. von COM1 auf \Device\Serial0.
>
> Da kann aber jeder Treiber einen solchen Link hinzufügen, und ich bin
> mir ziemlich sicher, dass er das Hinzufügen auch vergessen kann.

Wenn er es vergißt, kann man den Port unter Win32
nicht öffnen, weder mit noch ohne "\\.\".
Der Treiber immer legt genau einen Link auf "COM1"
bis "COM255" an, immer im Namespace "Devices". Um
ein Gerät unter Win32 zu öffenen, muß man den
übergebenen Dateinamen entsprechend mit "\\.\"
kennzeichnen, sonst wird im aktuellen Verzeichnis
nach einer Datei mit diesem Namen gesucht, und
genau das funktioniert eben nur mit COM1-9, weil
es vordefinierte Dateinamen sind, die überall,
stets und ständig auf ihre gleichnamingen Geräte-
Pendants verweisen, ob sie derzeit existieren oder
nicht.
"\\.\" ist nicht Bestandteil des Links.


Uwe

Stefan Kanthak

unread,
Mar 15, 2012, 8:37:31 AM3/15/12
to
"Uwe Sieber" <ma...@uwe-sieber.de> schrieb:

> Stefan Reuther wrote:
>> Edzard Egberts wrote:
>>> René König schrieb:
>>>> Das schreit doch geradezu nach Problemen, spätestens bei COM10 fängt
>>>> es an.
>>> Nein, *genau* mit COM10 fangen die Probleme an, ansonsten geht das so.
>>
>> Es gibt auch COM-Anschlüsse, bei denen das deutlich eher anfängt. Es
>> kommt halt drauf an, ob der Treiber den Alias COM42 -> \\.\com42
>> einträgt oder nicht.
>
> Nein, es fängt immer bei COM10 an:
> Jeder COM-Port hat einen Sysbolic Link vom "DosDeviceName"
> auf dessen Kernel-Objekt, z.B. von COM1 auf \Device\Serial0.

Ergaenzend zum MSDN: <http://support.microsoft.com/kb/235128/en-us>

> Dass das Öffnen von COM1 bis COM9 ohne das Kennzeichen \\.\
> für den Namensraum "Geräte", also im Namensraum "Dateien"
> funktioniert, ist irgendwo in der Gegend "Dateisystem" fest
> verdrahtet, COM1 bis COM9, AUX, LPT1 bis LPT9, PRN usw. sind
> reservierte Dateinamen, die fest auf die jeweiligen Geräte
> verweisen, der Treiber des Ports hat darauf keinen Einfluß.
>
> Naming Files, Paths, and Namespaces:
> > http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx

JFTR: solche Links kannst (und solltest) Du kanonisieren:
<http://msdn.microsoft.com/en-us/aa365247.aspx> alias
<http://technet.microsoft.com/en-us/aa365247.aspx>

Stefan
[
--
Die unaufgeforderte Zusendung werbender E-Mails verstoesst gegen §823
Abs. 1 sowie §1004 Abs. 1 BGB und begruendet Anspruch auf Unterlassung.
Beschluss des OLG Bamberg vom 12.05.2005 (AZ: 1 U 143/04)


0 new messages