📄 xsupgui_windows.c
字号:
printf("Couldn't allocate memory!\n");
#endif
free(resdata);
return IPC_ERROR_CANT_MALLOC_LOCAL;
}
memset(resdata, 0x00, MAXBUF);
while (done == FALSE)
{
SetLastError(0); // Reset the system error code.
xsup_gui_trace("(%s) Pipe : %d Event : %d Connected : %d Error : %d\n",__FUNCTION__, pipehdl, ovr.hEvent, ctrl_connected, GetLastError());
if (HasOverlappedIoCompleted(&ovr) == TRUE)
{
xsup_gui_trace("Error before calling ReadFile : %d\n", GetLastError());
if (ReadFile(pipehdl, resdata, MAXBUF, &size, &ovr) != 0)
{
retval = GetLastError();
if ((retval != 0) && (retval != 997))
{
xsup_gui_trace("Couldn't read data! Error : %d\n", retval);
xsup_gui_trace("Pipe : %d Event : %d Size in : %d Size out : %d\n",eventpipe, eovr.hEvent, MAXBUF, resultsize);
free(resdata);
return IPC_ERROR_UNABLE_TO_READ;
}
}
}
switch (WaitForSingleObject(eventhdl, 30000))
{
case WAIT_OBJECT_0:
if (GetOverlappedResult(pipehdl, &ovr, &size, FALSE) != 0)
{
ResetEvent(eventhdl);
#ifdef TRACELOG
xsup_gui_trace("Overlapped result code : %d\n", GetLastError());
#endif
if (size < sizeof(ipc_header))
{
#ifdef TRACELOG
xsup_gui_trace("Size = %d\n", size);
#endif
return IPC_ERROR_UNABLE_TO_READ;
}
if (resdata[0] == 0x00)
{
size = (size - sizeof(ipc_header));
if (size <= 0)
{
free(resdata);
return IPC_ERROR_RECV_IPC_RUNT;
}
if (data == NULL)
{
data = malloc(size);
if (data == NULL)
{
free(resdata);
return IPC_ERROR_CANT_MALLOC_LOCAL;
}
memset(data, 0x00, size);
}
memcpy(&data[offset], &resdata[sizeof(ipc_header)], size);
free(resdata);
(*resultsize) = offset + size;
(*result) = data;
return REQUEST_SUCCESS;
}
if ((resdata[0] & IPC_MSG_TOTAL_SIZE) == IPC_MSG_TOTAL_SIZE)
{
// We need to allocate memory.
if (data != NULL)
{
return IPC_ERROR_NOT_INITIALIZED;
}
hdr = (ipc_header *)&resdata[0];
value32 = ntohl(hdr->length);
data = malloc(value32);
if (data == NULL)
{
free(resdata);
return IPC_ERROR_CANT_MALLOC_LOCAL;
}
memset(data, 0x00, value32);
}
// Copy the data.
memcpy(&data[offset], &resdata[sizeof(ipc_header)], (size - sizeof(ipc_header)));
offset += (size - sizeof(ipc_header));
}
break;
case WAIT_TIMEOUT:
// If we don't cancel the pending IO, then the next request gets hosed.
CancelIo(pipehdl);
return REQUEST_TIMEOUT;
break;
default:
#ifdef DEBUG_WINDOWS_GUI
printf("Read error!\n");
#endif
free(resdata);
return IPC_ERROR_READ_DEFAULT_FAILURE;
break;
}
}
return REQUEST_TIMEOUT; // Timeout waiting for response. (Shouldn't ever get here!)
}
/**
* \brief Read data from an already connected Windows pipe acting as an IPC event pipe.
*
* Get an unsolicited event from the pipe.
*
* @param[out] result A buffer to the data that was read. (This function will allocate it, the
* caller is expected to free it.)
* @param[out] resultsize The amount of data that the buffer contains.
*
* \retval REQUEST_SUCCESS on success
* \retval >=300 on error.
**/
int xsupgui_windows_recv_event(unsigned char **result, int *resultsize)
{
char *resdata = NULL;
int retval = 0;
int errval = 0;
(*result) = NULL;
(*resultsize) = 0;
if (evt_connected != TRUE) return IPC_ERROR_EVT_NOT_CONNECTED;
resdata = malloc(MAXBUF);
if (resdata == NULL)
{
#ifdef DEBUG_WINDOWS_GUI
printf("Couldn't allocate memory!\n");
#endif
return IPC_ERROR_CANT_MALLOC_LOCAL;
}
if (HasOverlappedIoCompleted(&eovr) == TRUE)
{
if (ReadFile(eventpipe, resdata, MAXBUF, resultsize, &eovr) != 0)
{
retval = GetLastError();
if ((retval != ERROR_SUCCESS) && (retval != ERROR_IO_PENDING)) // 997 = Overlapped I/O in progress, means that we already have a read handle going.
{
#ifdef DEBUG_WINDOWS_GUI
printf("Read failed!!!!\n");
#endif
xsup_gui_trace("Couldn't read data! Error : %d\n", retval);
xsup_gui_trace("Pipe : %d Event : %d Size in : %d Size out : %d\n",eventpipe, eovr.hEvent, MAXBUF, resultsize);
free(resdata);
return IPC_ERROR_UNABLE_TO_READ;
}
}
else
{
errval = GetLastError();
if (errval == ERROR_BROKEN_PIPE)
{
free(resdata);
return IPC_EVENT_COM_BROKEN;
}
}
}
switch (WaitForSingleObject(eventevent, INFINITE))
{
case WAIT_OBJECT_0:
retval = GetOverlappedResult(eventpipe, &eovr, resultsize, FALSE);
if (retval != 0)
{
(*result) = resdata;
return REQUEST_SUCCESS;
}
xsup_gui_trace("GetOverlappedResult returned %d\n", retval);
break;
case WAIT_TIMEOUT:
// If we don't cancel the pending IO, then the next request gets hosed.
CancelIo(eventpipe);
ResetEvent(eventevent);
free(resdata);
retval = GetLastError();
xsup_gui_trace("WAIT_TIMEOUT case Windows error : %d\n", retval);
return REQUEST_TIMEOUT;
break;
default:
#ifdef DEBUG_WINDOWS_GUI
printf("Read error! %d\n", GetLastError());
#endif
CancelIo(eventpipe);
ResetEvent(eventevent);
free(resdata);
retval = GetLastError();
xsup_gui_trace("Default case Windows error : %d\n", retval);
return IPC_ERROR_UNABLE_TO_READ;
break;
}
retval = GetLastError();
xsup_gui_trace("Bailout case Windows error : %d\n", retval);
CancelIo(eventpipe);
ResetEvent(eventevent);
free(resdata);
return REQUEST_TIMEOUT; // Timeout waiting for response. (Shouldn't ever get here!)
}
/**
* \brief Send an IPC request, and wait for a response.
*
* @param[in] tosend A memory buffer containing the message to be sent to the supplicant.
* @param[in] sendsize The size of the memory buffer that is being sent. (Note : On Windows,
* this can't be over 4k!!)
*
* @param[out] result The result message generated by the supplicant. The library will allocate
* the necessary memory to store the result, the caller is expected to free it!
* @param[out] resultsize A pointer to the size of the result generated by the supplicant.
*
* \retval REQUEST_SUCCESS for success
* \retval REQUEST_FAILURE for error
* \retval REQUEST_TIMEOUT for timeout waiting for a response.
**/
int xsupgui_windows_send(unsigned char *tosend, int sendsize, unsigned char **result, int *resultsize)
{
DWORD totalbytes = 0;
DWORD error = 0;
(*result) = NULL;
(*resultsize) = 0;
if (ctrl_connected != TRUE) return IPC_ERROR_CTRL_NOT_CONNECTED;
xsupgui_windows_flush_ctrl_pipe();
xsup_gui_trace("Sending data! Pipe : %d\n", pipehdl);
if (WriteFile(pipehdl, tosend, sendsize, &totalbytes, &ovr) == 0)
{
#ifdef DEBUG_WINDOWS_GUI
error = GetLastError();
printf("Error sending! %d\n", error);
if (error == 109) exit(1);
#endif
xsup_gui_trace("Error writing data : %d\n", GetLastError());
return IPC_ERROR_CANT_SEND_IPC_MSG;
}
if (totalbytes != sendsize)
{
#ifdef DEBUG_WINDOWS_GUI
printf("Sent size mismatch!\n");
#endif
return IPC_ERROR_SEND_SIZE_MISMATCH;
}
return xsupgui_windows_recv(result, resultsize);
}
/**
* \brief Send an IPC message via the allocated event socket.
*
* This function will send an IPC request for the \ref eventpipe to be converted to
* something else. (Usually taking a generic pipe, and converting it to an event
* pipe.)
*
* @param[in] buffer The buffer to be sent to down the event socket.
* @param[in] bufsize The size of the buffer to be sent.
*
* \retval REQUEST_SUCCESS buffer was sent, and acked.
* \retval REQUEST_FAILURE buffer couldn't be sent, or wasn't acked.
*
* \warning This function should *NEVER* be called outside of the
* libxsupgui library! And should *ONLY* be directly called by
* \ref xsupgui_send_to_event().
**/
int xsupgui_windows_send_to_event(char *buffer, int bufsize)
{
DWORD totalbytes = 0;
unsigned char *result = NULL;
DWORD resultsize = 0;
int retval = 0;
xmlDocPtr indoc = NULL;
if (evt_connected != TRUE) return IPC_ERROR_EVT_NOT_CONNECTED;
if (WriteFile(eventpipe, buffer, bufsize, &totalbytes, &eovr) == 0)
{
#ifdef DEBUG_WINDOWS_GUI
printf("Error sending!\n");
#endif
return IPC_ERROR_CANT_SEND_IPC_MSG;
}
if (totalbytes != bufsize)
{
#ifdef DEBUG_WINDOWS_GUI
printf("Sent size mismatch!\n");
#endif
return IPC_ERROR_SEND_SIZE_MISMATCH;
}
retval = xsupgui_windows_recv_event(&result, &resultsize);
if (retval != 0) return retval;
indoc = xsupgui_xml_common_validate_msg(&result[5], (resultsize-5));
if (indoc == NULL) return IPC_ERROR_BAD_RESPONSE_DATA;
free(result);
// Otherwise, make sure we have an ACK.
retval = xsupgui_request_is_ack(indoc);
xmlFreeDoc(indoc);
return retval;
}
/**
* \brief Free the XML document that held our event.
**/
void xsupgui_windows_free_event_doc()
{
if (recvmsg != NULL)
{
xmlFreeDoc(recvmsg);
recvmsg = NULL;
}
}
#endif /* WINDOWS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -