ReadDirectoryChangesW issues

1.4k views Asked by At

I'am using ReadDirectoryChangesW to watch a directory changes asynchronously, based on this question I implement a function that watch a given directory, but I still get the error message GetQueuedCompletionStatus(): Timeout

void Filewatcher::OpenWatchDir(QString PathToOpen)
{

    QString path=QDir::fromNativeSeparators(PathToOpen);

    LPCTSTR  Dirname=(LPCTSTR)path.utf16();//.toStdWString().c_str();

    dirinfo_t* d =(dirinfo_t*) malloc(1*sizeof(dirinfo_t));
    d->CompletionKey = (ULONG_PTR)&somekey;
    dirinfo_init(d);

    /* set up */
    runthread = TRUE;
    d->hDirFH = CreateFile(Dirname,
                    FILE_LIST_DIRECTORY,
                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
                    NULL);

    d->hDirOPPort = CreateIoCompletionPort(d->hDirFH, NULL,
                          (ULONG_PTR)d->CompletionKey, 1);

    DWORD errorcode = 0;    // an error code
    BOOL bResultQ = FALSE;  // obvios=us
    BOOL bResultR = FALSE;
    DWORD NumBytes = 0;
    FILE_NOTIFY_INFORMATION* pInfo = NULL; // the data incoming is a pointer
                                           // to this struct.
    int i = 0;

    while ( runthread )
        {
            bResultR = ReadDirectoryChangesW(d->hDirFH, (void*)d->buffer,
                                              16777216, TRUE,
                   FILE_NOTIFY_CHANGE_FILE_NAME  | FILE_NOTIFY_CHANGE_CREATION  ,
                                              NULL,
                                              &d->o->overlapped,
                                              NULL );
            bResultQ = GetQueuedCompletionStatus(d->hDirOPPort,
                                                 &NumBytes, &(d->CompletionKey),
                                                 (LPOVERLAPPED*)(d->o), 1000);
            if ( bResultQ && bResultR )
                    {
                wprintf(L"\n");
                pInfo = (FILE_NOTIFY_INFORMATION*) d->buffer;
                wprintf(L"File %s", pInfo->FileName);
                wprintf(L" changes %d\n", pInfo->Action);

                qDebug()<<"file  "<<pInfo->FileName<<" was"<<pInfo->Action;
                memset(d->buffer, 0, 16777216);
            }
            else
                   {
                       errorcode = GetLastError();

                       if ( errorcode == WAIT_TIMEOUT )
                       {
                           qDebug()<<"GetQueuedCompletionStatus(): Timeout\n";
                       }
                       else
                       {
                           qDebug()<<"GetQueuedCompletionStatus(): Failed\n";
                           qDebug()<<"Error Code "<<errorcode;
                       }
                       Sleep(500);
                   }
               }


}

I need to know how use ReadDirectoryChangesW asynchronously with IoCompletionPort.

Any help please.

2

There are 2 answers

1
Oumaya On BEST ANSWER

thank you guys for your answers, after a deep research and retesting code I solve my problem based on this , I really appreciate your help.

3
Ben Voigt On

There's no reason to use a completion port here, simple overlapped I/O with an event will work fabulously.

The key is to wait for this operation (whether event or completion port) at the same time as all other events (possibly including GUI messages), and only check the status when the event becomes signaled. For that, use (Msg)WaitForMultipleObjects(Ex).

In Qt, you can add Win32 events (used by OVERLAPPED structure for async I/O) using QWinEventNotifier as described here: