CreateFile on Mailslot fails with Error 53 ERROR_BAD_NETPATH after 2018-05 Windows 10 Feature Update 1803

2k views Asked by At

commands such as CreateFile("\\mycomputer\mailslot\this_fails",...) fail with last error = 53 ERROR_BAD_NETPATH

That fails if used with any valid or non-existing computer name including the same computer on which the test is running. On computers where this works, it succeeds and returns a mailslot handle even if the referenced computer does not exist or does not have a mailslot created with that name. Note that if an non-existing computer name or mailslot is used, subsequent WriteFiles on the handle will fail, but the CreateFile does succeed.

However, the CreateFile above will succeed if the Mailslot reference is explicitly local: "\\.\mailslot\always_works"

This worked on all versions of Windows previously until the 2018-05 cumulative updates were installed. Specifically KB4103721 (Windows 10 home) seemed to be the culprit. [Edit: as noted in answers below, it is actually Feature Update Build 1803 that causes this issue.]

Test Client: (works with no parameter or "." but fails with any computername). Based on msdn sample

Syntax: testclient [server computername]

    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>

    LPTSTR SlotName = TEXT("\\\\%hs\\mailslot\\sample_mailslot");

    BOOL WriteSlot(HANDLE hSlot, LPTSTR lpszMessage)
    {
       BOOL fResult;
       DWORD cbWritten;

       fResult = WriteFile(hSlot,
         lpszMessage,
         (DWORD) (lstrlen(lpszMessage)+1)*sizeof(TCHAR),
         &cbWritten,
         (LPOVERLAPPED) NULL);

       if (!fResult)
       {
// this failure is valid if computername is not valid
          printf("WriteFile failed with %d.\n", GetLastError());
          return FALSE;
       }

       printf("Slot written to successfully.\n");

       return TRUE;
    }

    int main(int nArgs,char * arg[])
    {
       HANDLE hFile;
       TCHAR szSlot[256];

       _stprintf (szSlot,SlotName,nArgs > 1 ? arg[1] : ".");

       _tprintf(TEXT("Writing to slot %s\n"),szSlot);
       hFile = CreateFile(szSlot,
         GENERIC_WRITE,
         FILE_SHARE_READ,
         (LPSECURITY_ATTRIBUTES) NULL,
         OPEN_EXISTING,
         FILE_ATTRIBUTE_NORMAL,
         (HANDLE) NULL);

       if (hFile == INVALID_HANDLE_VALUE)
       {
// this is the failure I'm trying to debug
          printf("CreateFile failed with %d.\n", GetLastError());
          return FALSE;
       }

       WriteSlot(hFile, TEXT("Message one for mailslot."));
       WriteSlot(hFile, TEXT("Message two for mailslot."));
       Sleep(5000);
       WriteSlot(hFile, TEXT("Message three for mailslot."));
       CloseHandle(hFile);

       return TRUE;
    }

Test Server: (reads a displays sent messages) Note that duplicate messages may be received because Mailslot messages are transmitted over all possible protocols. Based on msdn sample.

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>

HANDLE hSlot;
LPTSTR SlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");

BOOL ReadSlot()
{
    DWORD cbMessage, cMessage, cbRead;
    BOOL fResult;
    LPTSTR lpszBuffer;
    TCHAR achID[80];
    DWORD cAllMessages;
    HANDLE hEvent;
    OVERLAPPED ov;

    cbMessage = cMessage = cbRead = 0;

    hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot"));
    if( NULL == hEvent )
        return FALSE;
    ov.Offset = 0;
    ov.OffsetHigh = 0;
    ov.hEvent = hEvent;

    fResult = GetMailslotInfo( hSlot, // mailslot handle
        (LPDWORD) NULL,               // no maximum message size
        &cbMessage,                   // size of next message
        &cMessage,                    // number of messages
        (LPDWORD) NULL);              // no read time-out

    if (!fResult)
    {
        printf("GetMailslotInfo failed with %d.\n", GetLastError());
        return FALSE;
    }

    if (cbMessage == MAILSLOT_NO_MESSAGE)
    {
        printf("Waiting for a message...\n");
        return TRUE;
    }

    cAllMessages = cMessage;

    while (cMessage != 0)  // retrieve all messages
    {
        // Create a message-number string.

        StringCchPrintf((LPTSTR) achID,
            80,
            TEXT("\nMessage #%d of %d\n"),
            cAllMessages - cMessage + 1,
            cAllMessages);

        // Allocate memory for the message.

        lpszBuffer = (LPTSTR) GlobalAlloc(GPTR,
            lstrlen((LPTSTR) achID)*sizeof(TCHAR) + cbMessage);
        if( NULL == lpszBuffer )
            return FALSE;
        lpszBuffer[0] = '\0';

        fResult = ReadFile(hSlot,
            lpszBuffer,
            cbMessage,
            &cbRead,
            &ov);

        if (!fResult)
        {
            printf("ReadFile failed with %d.\n", GetLastError());
            GlobalFree((HGLOBAL) lpszBuffer);
            return FALSE;
        }

        // Concatenate the message and the message-number string.
        StringCbCat(lpszBuffer,
                    lstrlen((LPTSTR) achID)*sizeof(TCHAR)+cbMessage,
                    (LPTSTR) achID);

        // Display the message.
        _tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer);

        GlobalFree((HGLOBAL) lpszBuffer);

        fResult = GetMailslotInfo(hSlot,  // mailslot handle
            (LPDWORD) NULL,               // no maximum message size
            &cbMessage,                   // size of next message
            &cMessage,                    // number of messages
            (LPDWORD) NULL);              // no read time-out

        if (!fResult)
        {
            printf("GetMailslotInfo failed (%d)\n", GetLastError());
            return FALSE;
        }
    }
    CloseHandle(hEvent);
    return TRUE;
}

BOOL WINAPI MakeSlot(LPTSTR lpszSlotName)
{
    hSlot = CreateMailslot(lpszSlotName,
        0,                             // no maximum message size
        MAILSLOT_WAIT_FOREVER,         // no time-out for operations
        (LPSECURITY_ATTRIBUTES) NULL); // default security

    if (hSlot == INVALID_HANDLE_VALUE)
    {
        printf("CreateMailslot failed with %d\n", GetLastError());
        return FALSE;
    }
    return TRUE;
}

void main()
{
   MakeSlot(SlotName);

   while(TRUE)
   {
      ReadSlot();
      Sleep(3000);
   }
}

The test server to read messages, and the test client to send messages can be run in different cmd shells on the same computer, or run on different computers. When it fails, it fails immediately and seems to be a problem trying to resolve the network path name. On the same computer, file shares such as \\ThisComputer\share work properly from the same computer or a different one.

NetBIOS is enabled over TCP/IP for the network adapters in use. The network adapters are designated as Private. Firewall was disabled for testing. File and Printer sharing are enabled. Computers are in same workgroup. Computer name resolution works, and this fails even if IP addresses are used (even 127.0.0.1).

3

There are 3 answers

1
magicandre1981 On BEST ANSWER

The issue is already fixed since last Year

September 26, 2018—KB4458469 (OS Build 17134.320)

Addresses an issue that causes NTLTEST, DCLOCATOR, or joining an Active Directory and SAMBA domain to fail when using the NetBIOS domain name. The error is “An Active Directory domain Controller (AD DC) for the domain %domain% could not be contacted”. This also addresses connection issues for applications that use mailslots to communicate.

1
Martin Arith On

This seems to be a problem with the latest Feature Update from Windows 10 (1803), not a patch via Windows Update. Please check if you are using build 17134.48 (Also known as 1803)

Try a downgrade to 1709.

01/09/2019: With the latests 1809 Build Mailslots are working again

2
Martin Arith On

I didn`t find any information that mailslot communication is not longer supported in that way you do this. I think it is a bug. But the only way to find out is to open a support ticket via support.microsoft.com.

Or you could post here https://social.technet.microsoft.com/Forums

Until we get any new information from Microsoft everybody who needs mailslots should block the feature upgrade 1803.