/* This test program demonstrates that when a Windows 7 Client box issues a compound SMB2 CREATE/NOTIFY request, the client will time out because it has not recieved any reply for the CREATE request. Samba 3.5 appears to only send an interim reply to the NOTIFY request. Note: the reason we call GetFileAttributes() first is because this seams to get things in order so the client SMB2 driver will "compound" the CREATE/NOTIFY request precipated by the FindFirstChangeNotification() call. If FindFirstChangeNotification() is the only call, then Windows 7 client SMB2 driver doesn't send a compound request and no bug/problem/issue is exposed. */ #include "stdafx.h" #include int _tmain(int argc, _TCHAR* argv[]) { if (argc < 2) { printf("usage \n"); printf("This test program should be run on an idle Windows 7 box with a\n"); printf("protocol analyzer like WireShark up and running with\n"); printf("the display filter: (smb2 || tcp.flags.reset == 1)\n"); printf("Look for a compound CREATE+NOTIFY request from the client to the server\n"); printf("Notice no reply, then between 60 and 270 seconds later,\n"); printf("a disconect (TCP RST) is sent from the client to the server.\n"); printf("See source code for details\n"); return -1; } if (GetFileAttributes(argv[1]) == 0xFFFFFFFF) { printf("reproduction attempt failed:invalid path\n"); return -1; } DWORD flags = FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE; HANDLE h = FindFirstChangeNotification(argv[1], false, flags); if (h == INVALID_HANDLE_VALUE) { printf("reproduction attempt failed:Syserr:%d on %s\n", GetLastError(), argv[1]); return -1; } else { printf("waiting for changes (300 secs) but we don't expect any...\n"); for (int i = 0; i < 300; i++) { if (WaitForSingleObject(h, 1000) == WAIT_OBJECT_0) { printf("reproduction attempt failed:changes occured in %s\n", argv[1]); } else { printf("%i sec\r",i); } } } FindCloseChangeNotification(h); return 0; }