windows - ¿Cómo usar el método ReadDirectoryChangesW() con la rutina de finalización?
asynchronous (1)
Quiero utilizar la función ReadDirectoryChangesW()
en modo asíncrono con la rutina de finalización de E / S suministrada.
La pregunta es: no sé cómo recuperar la información exacta sobre el cambio en la rutina de finalización (una función CALLBACK
). La rutina de finalización se define así:
VOID CALLBACK FileIOCompletionRoutine(
[in] DWORD dwErrorCode,
[in] DWORD dwNumberOfBytesTransfered,
[in] LPOVERLAPPED lpOverlapped
);
Me pregunto si la información está incluida en la estructura LPOVERLAPPED
. Pero no sé cómo conseguirlo.
Excelente pregunta! Son 7 años de retraso, pero aquí hay algo de respuesta o, lo que es más importante, cómo encontrarla . Entonces, la documentación para ReadDirectoryChangesW:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v=vs.85%29.aspx
en la sección de Parámetros da un enlace a FileIOCompletionRoutine:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa364052%28v=vs.85%29.aspx
que en la sección Ejemplos da un enlace al Servidor de Tuberías Nombrado usando Rutinas de Terminación:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365601%28v=vs.85%29.aspx
que lo crean o no ni siquiera usa ReadDirectoryChangesW, pero en realidad da un ejemplo usando ReadFileEx, que también usa FileIOCompletionRoutine:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365468%28v=vs.85%29.aspx
y puede ver un ejemplo de ellos usando estas dos funciones (ReadFileEx y CompletedReadRoutine (que es una implementación de la función de devolución de llamada definida por la aplicación FileIOCompletionRoutine)) en este fragmento de código:
// CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED)
// This routine is called as a completion routine after writing to
// the pipe, or when a new client has connected to a pipe instance.
// It starts another read operation.
VOID WINAPI CompletedWriteRoutine(DWORD dwErr, DWORD cbWritten,
LPOVERLAPPED lpOverLap)
{
LPPIPEINST lpPipeInst;
BOOL fRead = FALSE;
// lpOverlap points to storage for this instance.
lpPipeInst = (LPPIPEINST) lpOverLap;
// The write operation has finished, so read the next request (if
// there is no error).
if ((dwErr == 0) && (cbWritten == lpPipeInst->cbToWrite))
fRead = ReadFileEx(
lpPipeInst->hPipeInst,
lpPipeInst->chRequest,
BUFSIZE*sizeof(TCHAR),
(LPOVERLAPPED) lpPipeInst,
(LPOVERLAPPED_COMPLETION_ROUTINE) CompletedReadRoutine);
// Disconnect if an error occurred.
if (! fRead)
DisconnectAndClose(lpPipeInst);
}
// CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED)
// This routine is called as an I/O completion routine after reading
// a request from the client. It gets data and writes it to the pipe.
VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead,
LPOVERLAPPED lpOverLap)
{
LPPIPEINST lpPipeInst;
BOOL fWrite = FALSE;
// lpOverlap points to storage for this instance.
lpPipeInst = (LPPIPEINST) lpOverLap;
// The read operation has finished, so write a response (if no
// error occurred).
if ((dwErr == 0) && (cbBytesRead != 0))
{
GetAnswerToRequest(lpPipeInst);
fWrite = WriteFileEx(
lpPipeInst->hPipeInst,
lpPipeInst->chReply,
lpPipeInst->cbToWrite,
(LPOVERLAPPED) lpPipeInst,
(LPOVERLAPPED_COMPLETION_ROUTINE) CompletedWriteRoutine);
}
// Disconnect if an error occurred.
if (! fWrite)
DisconnectAndClose(lpPipeInst);
}
No es una gran respuesta (solo estaba explorando si quería usar estas funciones, yo mismo), pero debería ayudar a la gente a comenzar.
Ver también:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365261%28v=vs.85%29.aspx