title: CreateFile to open an MS-DOS device created in another terminal session
body: <p>I have a (sort of a filter) driver that should communicate with user-mode components. It creates a device object by calling <code>IoCreateDevice</code>, and then it creates a so-called MS-DOS symbolic link for it by <code>IoCreateSymbolicLink</code>, to make it possible to access it from user-mode code (by <code>CreateFile</code>). This is a standard technique more-or-less. The driver creates a symbolic link of the form <code>\DosDevices\mydevicename</code>, whereas the user-mode code opens a file named <code>\\.\mydevicename</code>.</p>
  
  <p>Now, the problems start when the driver creates a device in the context of a terminal server session. The created symbolic link actually belongs to the <em>local session directory</em>, whereas my user-mode service runs under system account in "zero session", and it "sees" symbolic links that belong to <em>global directory</em>.</p>
  
  <p>It's mentioned in the documentation that usually there's no problem, because drivers mostly create device objects in the context of <code>DriverEntry</code> or <code>AddDevice</code> functions, which are guaranteed to run under system account. But my case is different. And I don't want to change this, what I really need is to be able to create/destroy device objects in the context of arbitrary thread, belonging to any session.</p>
  
  <p>According to the documentation there's a way to solve this. The driver may insist to create a symbolic link belonging to the <em>global directory</em>, by naming it this way: <code>\DosDevices\Global\mydevicename</code>. Moreover, if the user-mode code happens to run under some account, it may also insist to look for the link in the <em>global directory</em>, by naming the file this way: <code>\\.\Global\mydevicename</code>. Though this is not required usually, if the symbol doesn't exist in local directory, it's automatically checked in the global directory.</p>
  
  <p>I've tried this trick: it doesn't work for me. I'm using Windows 2008R2, 64-bit. No success so far. I'm consistently able to open devices created in the system account, but unable to open devices created in another sessions (the error code is "file not found"). I've tried all the combinations and variations of specifying <code>\Global</code> in kernel/user mode - so far the result is the same.</p>
  
  <p>This makes me suspect that there's one more level of symbol isolation. Perhaps using <code>\Global</code> creates a symbolic link that is global session-wide, but still not system-wide. </p>
  
  <p>Does this make sense? Is there a way to create a system-wide symbolic link? Or is there a way to open a file whose symbolic link belongs to another session?</p>
  
  <p><strong>EDIT</strong>:</p>
  
  <p>Thanks to @Hans Passant. I've tried WinObj utility to actually see which devices and symbolic links the driver actually creates.</p>
  
  <p>Everything seems ok at the first glance. I see all my devices under <code>\Device</code> directory, and all the symbolic links are under <code>\GLOBAL??</code>. Symbolic links point to correct device names.</p>
  
  <p>One thing is weird however. Trying to see the device properties from within WinObj: for devices created in zero session this works ok, but for devices created in other sessions WinObj responds with an error:</p>
  
  <ul>
  <li>Error opening \Device\mydevicename: The system cannot find the file specified.</li>
  </ul>
  
  <p>So, it displays this device object in its list, but OTOH it's "not found" when trying to open it.
  Very strange. But this explains my problem. But this is really strange.</p>
  
  <p>Any ideas? Thanks in advance.</p>