channels/rdpdr: add more server-side error checking
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 21 May 2015 20:50:29 +0000 (16:50 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 21 May 2015 20:50:29 +0000 (16:50 -0400)
channels/rdpdr/server/rdpdr_main.c

index e1bf9b4..23f839d 100644 (file)
@@ -62,7 +62,7 @@ static RDPDR_IRP* rdpdr_server_dequeue_irp(RdpdrServerContext* context, UINT32 c
        return irp;
 }
 
-static int rdpdr_server_send_announce_request(RdpdrServerContext* context)
+static BOOL rdpdr_server_send_announce_request(RdpdrServerContext* context)
 {
        wStream* s;
        BOOL status;
@@ -77,7 +77,7 @@ static int rdpdr_server_send_announce_request(RdpdrServerContext* context)
        s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 8);
 
        if (!s)
-               return -1;
+               return FALSE;
 
        Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */
        Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
@@ -93,17 +93,17 @@ static int rdpdr_server_send_announce_request(RdpdrServerContext* context)
 
        Stream_Free(s, TRUE);
 
-       return status ? 1 : -1;
+       return status;
 }
 
-static int rdpdr_server_receive_announce_response(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
+static BOOL rdpdr_server_receive_announce_response(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
 {
        UINT32 ClientId;
        UINT16 VersionMajor;
        UINT16 VersionMinor;
 
        if (Stream_GetRemainingLength(s) < 8)
-               return -1;
+               return FALSE;
 
        Stream_Read_UINT16(s, VersionMajor); /* VersionMajor (2 bytes) */
        Stream_Read_UINT16(s, VersionMinor); /* VersionMinor (2 bytes) */
@@ -114,23 +114,23 @@ static int rdpdr_server_receive_announce_response(RdpdrServerContext* context, w
 
        context->priv->ClientId = ClientId;
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_receive_client_name_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
+static BOOL rdpdr_server_receive_client_name_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
 {
        UINT32 UnicodeFlag;
        UINT32 ComputerNameLen;
 
        if (Stream_GetRemainingLength(s) < 12)
-               return -1;
+               return FALSE;
 
        Stream_Read_UINT32(s, UnicodeFlag); /* UnicodeFlag (4 bytes) */
        Stream_Seek_UINT32(s); /* CodePage (4 bytes), MUST be set to zero */
        Stream_Read_UINT32(s, ComputerNameLen); /* ComputerNameLen (4 bytes) */
 
        if (Stream_GetRemainingLength(s) < ComputerNameLen)
-               return -1;
+               return FALSE;
 
        /**
         * Caution: ComputerNameLen is given *bytes*,
@@ -157,34 +157,34 @@ static int rdpdr_server_receive_client_name_request(RdpdrServerContext* context,
 
        WLog_DBG(TAG, "ClientComputerName: %s", context->priv->ClientComputerName);
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_read_capability_set_header(wStream* s, RDPDR_CAPABILITY_HEADER* header)
+static BOOL rdpdr_server_read_capability_set_header(wStream* s, RDPDR_CAPABILITY_HEADER* header)
 {
        if (Stream_GetRemainingLength(s) < 8)
-               return -1;
+               return FALSE;
 
        Stream_Read_UINT16(s, header->CapabilityType); /* CapabilityType (2 bytes) */
        Stream_Read_UINT16(s, header->CapabilityLength); /* CapabilityLength (2 bytes) */
        Stream_Read_UINT32(s, header->Version); /* Version (4 bytes) */
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_write_capability_set_header(wStream* s, RDPDR_CAPABILITY_HEADER* header)
+static BOOL rdpdr_server_write_capability_set_header(wStream* s, RDPDR_CAPABILITY_HEADER* header)
 {
-       if (Stream_GetRemainingLength(s) < 8)
-               return -1;
+       if (!Stream_EnsureRemainingCapacity(s, 8))
+               return FALSE;
 
        Stream_Write_UINT16(s, header->CapabilityType); /* CapabilityType (2 bytes) */
        Stream_Write_UINT16(s, header->CapabilityLength); /* CapabilityLength (2 bytes) */
        Stream_Write_UINT32(s, header->Version); /* Version (4 bytes) */
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_read_general_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
+static BOOL rdpdr_server_read_general_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
 {
        UINT32 ioCode1;
        UINT32 extraFlags1;
@@ -194,7 +194,7 @@ static int rdpdr_server_read_general_capability_set(RdpdrServerContext* context,
        UINT32 SpecialTypeDeviceCap;
 
        if (Stream_GetRemainingLength(s) < 32)
-               return -1;
+               return FALSE;
 
        Stream_Seek_UINT32(s); /* osType (4 bytes), ignored on receipt */
        Stream_Seek_UINT32(s); /* osVersion (4 bytes), unused and must be set to zero */
@@ -209,17 +209,17 @@ static int rdpdr_server_read_general_capability_set(RdpdrServerContext* context,
        if (header->Version == GENERAL_CAPABILITY_VERSION_02)
        {
                if (Stream_GetRemainingLength(s) < 4)
-                       return -1;
+                       return FALSE;
 
                Stream_Read_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */
        }
 
        context->priv->UserLoggedOnPdu = (extendedPdu & RDPDR_USER_LOGGEDON_PDU) ? TRUE : FALSE;
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_write_general_capability_set(RdpdrServerContext* context, wStream* s)
+static BOOL rdpdr_server_write_general_capability_set(RdpdrServerContext* context, wStream* s)
 {
        UINT32 ioCode1;
        UINT32 extendedPdu;
@@ -259,7 +259,7 @@ static int rdpdr_server_write_general_capability_set(RdpdrServerContext* context
        SpecialTypeDeviceCap = 0;
 
        if (!Stream_EnsureRemainingCapacity(s, header.CapabilityLength))
-               return -1;
+               return FALSE;
 
        rdpdr_server_write_capability_set_header(s, &header);
 
@@ -274,15 +274,15 @@ static int rdpdr_server_write_general_capability_set(RdpdrServerContext* context
        Stream_Write_UINT32(s, 0); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */
        Stream_Write_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_read_printer_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
+static BOOL rdpdr_server_read_printer_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
 {
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_write_printer_capability_set(RdpdrServerContext* context, wStream* s)
+static BOOL rdpdr_server_write_printer_capability_set(RdpdrServerContext* context, wStream* s)
 {
        RDPDR_CAPABILITY_HEADER header;
 
@@ -291,19 +291,19 @@ static int rdpdr_server_write_printer_capability_set(RdpdrServerContext* context
        header.Version = PRINT_CAPABILITY_VERSION_01;
 
        if (!Stream_EnsureRemainingCapacity(s, header.CapabilityLength))
-               return -1;
+               return FALSE;
 
        rdpdr_server_write_capability_set_header(s, &header);
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_read_port_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
+static BOOL rdpdr_server_read_port_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
 {
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_write_port_capability_set(RdpdrServerContext* context, wStream* s)
+static BOOL rdpdr_server_write_port_capability_set(RdpdrServerContext* context, wStream* s)
 {
        RDPDR_CAPABILITY_HEADER header;
 
@@ -312,19 +312,19 @@ static int rdpdr_server_write_port_capability_set(RdpdrServerContext* context, w
        header.Version = PORT_CAPABILITY_VERSION_01;
 
        if (!Stream_EnsureRemainingCapacity(s, header.CapabilityLength))
-               return -1;
+               return FALSE;
 
        rdpdr_server_write_capability_set_header(s, &header);
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_read_drive_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
+static BOOL rdpdr_server_read_drive_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
 {
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_write_drive_capability_set(RdpdrServerContext* context, wStream* s)
+static BOOL rdpdr_server_write_drive_capability_set(RdpdrServerContext* context, wStream* s)
 {
        RDPDR_CAPABILITY_HEADER header;
 
@@ -333,19 +333,19 @@ static int rdpdr_server_write_drive_capability_set(RdpdrServerContext* context,
        header.Version = DRIVE_CAPABILITY_VERSION_02;
 
        if (!Stream_EnsureRemainingCapacity(s, header.CapabilityLength))
-               return -1;
+               return FALSE;
 
        rdpdr_server_write_capability_set_header(s, &header);
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_read_smartcard_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
+static BOOL rdpdr_server_read_smartcard_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header)
 {
        return 1;
 }
 
-static int rdpdr_server_write_smartcard_capability_set(RdpdrServerContext* context, wStream* s)
+static BOOL rdpdr_server_write_smartcard_capability_set(RdpdrServerContext* context, wStream* s)
 {
        RDPDR_CAPABILITY_HEADER header;
 
@@ -354,14 +354,14 @@ static int rdpdr_server_write_smartcard_capability_set(RdpdrServerContext* conte
        header.Version = SMARTCARD_CAPABILITY_VERSION_01;
 
        if (!Stream_EnsureRemainingCapacity(s, header.CapabilityLength))
-               return -1;
+               return FALSE;
 
        rdpdr_server_write_capability_set_header(s, &header);
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_send_core_capability_request(RdpdrServerContext* context)
+static BOOL rdpdr_server_send_core_capability_request(RdpdrServerContext* context)
 {
        wStream* s;
        BOOL status;
@@ -388,7 +388,7 @@ static int rdpdr_server_send_core_capability_request(RdpdrServerContext* context
        s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 512);
 
        if (!s)
-               return -1;
+               return FALSE;
 
        Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */
        Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
@@ -422,10 +422,10 @@ static int rdpdr_server_send_core_capability_request(RdpdrServerContext* context
 
        Stream_Free(s, TRUE);
 
-       return status ? 1 : -1;
+       return status;
 }
 
-static int rdpdr_server_receive_core_capability_response(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
+static BOOL rdpdr_server_receive_core_capability_response(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
 {
        int i;
        int status;
@@ -433,7 +433,7 @@ static int rdpdr_server_receive_core_capability_response(RdpdrServerContext* con
        RDPDR_CAPABILITY_HEADER capabilityHeader;
 
        if (Stream_GetRemainingLength(s) < 4)
-               return -1;
+               return FALSE;
 
        Stream_Read_UINT16(s, numCapabilities); /* numCapabilities (2 bytes) */
        Stream_Seek_UINT16(s); /* Padding (2 bytes) */
@@ -443,7 +443,7 @@ static int rdpdr_server_receive_core_capability_response(RdpdrServerContext* con
                status = rdpdr_server_read_capability_set_header(s, &capabilityHeader);
 
                if (status < 0)
-                       return -1;
+                       return FALSE;
 
                switch (capabilityHeader.CapabilityType)
                {
@@ -470,18 +470,18 @@ static int rdpdr_server_receive_core_capability_response(RdpdrServerContext* con
                        default:
                                WLog_DBG(TAG, "Unknown capabilityType %d", capabilityHeader.CapabilityType);
                                Stream_Seek(s, capabilityHeader.CapabilityLength - RDPDR_CAPABILITY_HEADER_LENGTH);
-                               status = -1;
+                               status = FALSE;
                                break;
                }
 
-               if (status < 0)
-                       return -1;
+               if (!status)
+                       return status;
        }
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_send_client_id_confirm(RdpdrServerContext* context)
+static BOOL rdpdr_server_send_client_id_confirm(RdpdrServerContext* context)
 {
        wStream* s;
        BOOL status;
@@ -496,7 +496,7 @@ static int rdpdr_server_send_client_id_confirm(RdpdrServerContext* context)
        s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 8);
 
        if (!s)
-               return -1;
+               return FALSE;
 
        Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */
        Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
@@ -512,10 +512,10 @@ static int rdpdr_server_send_client_id_confirm(RdpdrServerContext* context)
 
        Stream_Free(s, TRUE);
 
-       return status ? 1 : -1;
+       return status;
 }
 
-static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
+static BOOL rdpdr_server_receive_device_list_announce_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
 {
        int i;
        UINT32 DeviceCount;
@@ -526,7 +526,7 @@ static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext*
        BYTE* DeviceData;
 
        if (Stream_GetRemainingLength(s) < 4)
-               return -1;
+               return FALSE;
 
        Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */
 
@@ -537,7 +537,7 @@ static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext*
                ZeroMemory(PreferredDosName, sizeof(PreferredDosName));
 
                if (Stream_GetRemainingLength(s) < 20)
-                       return -1;
+                       return FALSE;
 
                Stream_Read_UINT32(s, DeviceType); /* DeviceType (4 bytes) */
                Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
@@ -545,7 +545,7 @@ static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext*
                Stream_Read_UINT32(s, DeviceDataLength); /* DeviceDataLength (4 bytes) */
 
                if (Stream_GetRemainingLength(s) < DeviceDataLength)
-                       return -1;
+                       return FALSE;
 
                DeviceData = Stream_Pointer(s);
 
@@ -590,10 +590,10 @@ static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext*
                Stream_Seek(s, DeviceDataLength);
        }
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
+static BOOL rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
 {
        int i;
        UINT32 DeviceCount;
@@ -601,7 +601,7 @@ static int rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* c
        UINT32 DeviceId;
 
        if (Stream_GetRemainingLength(s) < 4)
-               return -1;
+               return FALSE;
 
        Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */
 
@@ -610,7 +610,7 @@ static int rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* c
        for (i = 0; i < DeviceCount; i++)
        {
                if (Stream_GetRemainingLength(s) < 4)
-                       return -1;
+                       return FALSE;
 
                Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
 
@@ -654,10 +654,10 @@ static int rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* c
                }
        }
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_receive_device_io_completion(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
+static BOOL rdpdr_server_receive_device_io_completion(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
 {
        UINT32 deviceId;
        UINT32 completionId;
@@ -665,7 +665,7 @@ static int rdpdr_server_receive_device_io_completion(RdpdrServerContext* context
        RDPDR_IRP* irp;
 
        if (Stream_GetRemainingLength(s) < 12)
-               return -1;
+               return FALSE;
 
        Stream_Read_UINT32(s, deviceId);
        Stream_Read_UINT32(s, completionId);
@@ -678,7 +678,7 @@ static int rdpdr_server_receive_device_io_completion(RdpdrServerContext* context
        if (!irp)
        {
                WLog_ERR(TAG, "IRP not found for completionId=0x%x", completionId);
-               return -1;
+               return FALSE;
        }
 
        /* Invoke the callback. */
@@ -687,10 +687,10 @@ static int rdpdr_server_receive_device_io_completion(RdpdrServerContext* context
                (*irp->Callback)(context, s, irp, deviceId, completionId, ioStatus);
        }
 
-       return 1;
+       return TRUE;
 }
 
-static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context)
+static BOOL rdpdr_server_send_user_logged_on(RdpdrServerContext* context)
 {
        wStream* s;
        BOOL status;
@@ -705,7 +705,7 @@ static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context)
        s = Stream_New(NULL, RDPDR_HEADER_LENGTH);
 
        if (!s)
-               return -1;
+               return FALSE;
 
        Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */
        Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
@@ -718,12 +718,12 @@ static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context)
 
        Stream_Free(s, TRUE);
 
-       return status ? 1 : -1;
+       return status;
 }
 
-static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
+static BOOL rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
 {
-       int status = 1;
+       BOOL status = TRUE;
 
        WLog_DBG(TAG, "RdpdrServerReceivePdu: Component: 0x%04X PacketId: 0x%04X",
                         header->Component, header->PacketId);
@@ -741,26 +741,26 @@ static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDP
                        case PAKID_CORE_CLIENT_NAME:
                                status = rdpdr_server_receive_client_name_request(context, s, header);
 
-                               if (status < 0)
-                                       return -1;
+                               if (!status)
+                                       return FALSE;
 
                                status = rdpdr_server_send_core_capability_request(context);
 
-                               if (status < 0)
-                                       return -1;
+                               if (!status)
+                                       return FALSE;
 
                                status = rdpdr_server_send_client_id_confirm(context);
 
-                               if (status < 0)
-                                       return -1;
+                               if (!status)
+                                       return FALSE;
 
                                break;
 
                        case PAKID_CORE_CLIENT_CAPABILITY:
                                status = rdpdr_server_receive_core_capability_response(context, s, header);
 
-                               if (status < 0)
-                                       return -1;
+                               if (!status)
+                                       return FALSE;
 
                                if (context->priv->UserLoggedOnPdu)
                                        status = rdpdr_server_send_user_logged_on(context);
@@ -806,7 +806,7 @@ static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDP
        else
        {
                WLog_WARN(TAG, "Unknown RDPDR_HEADER.Component: 0x%04X", header->Component);
-               return -1;
+               return FALSE;
        }
 
        return status;
@@ -892,17 +892,30 @@ static int rdpdr_server_start(RdpdrServerContext* context)
                return -1;
 
        context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+       if (!context->priv->StopEvent)
+               return -1;
+
        context->priv->Thread = CreateThread(NULL, 0,
                                (LPTHREAD_START_ROUTINE) rdpdr_server_thread, (void*) context, 0, NULL);
 
+       if (!context->priv->Thread)
+               return -1;
+
        return 1;
 }
 
 static int rdpdr_server_stop(RdpdrServerContext* context)
 {
-       SetEvent(context->priv->StopEvent);
-       WaitForSingleObject(context->priv->Thread, INFINITE);
-       CloseHandle(context->priv->Thread);
+       if (context->priv->StopEvent)
+       {
+               SetEvent(context->priv->StopEvent);
+               WaitForSingleObject(context->priv->Thread, INFINITE);
+               CloseHandle(context->priv->Thread);
+               context->priv->Thread = NULL;
+               CloseHandle(context->priv->StopEvent);
+               context->priv->StopEvent = NULL;
+       }
 
        return 1;
 }
@@ -1266,7 +1279,10 @@ static BOOL rdpdr_server_drive_create_directory_callback1(RdpdrServerContext* co
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to close the file */
        status = rdpdr_server_send_device_close_request(context, deviceId, fileId, irp->CompletionId);
@@ -1295,7 +1311,10 @@ static BOOL rdpdr_server_drive_create_directory(RdpdrServerContext* context, voi
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to open the file. */
        status = rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName,
@@ -1357,7 +1376,10 @@ static BOOL rdpdr_server_drive_delete_directory_callback1(RdpdrServerContext* co
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to close the file */
        status = rdpdr_server_send_device_close_request(context, deviceId, fileId, irp->CompletionId);
@@ -1386,7 +1408,10 @@ static BOOL rdpdr_server_drive_delete_directory(RdpdrServerContext* context, voi
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to open the file. */
        status = rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName,
@@ -1440,7 +1465,10 @@ static BOOL rdpdr_server_drive_query_directory_callback2(RdpdrServerContext* con
                status = rdpdr_server_enqueue_irp(context, irp);
 
                if (!status)
+               {
+                       rdpdr_server_irp_free(irp);
                        return FALSE;
+               }
 
                /* Send a request to query the directory. */
                status = rdpdr_server_send_device_query_directory_request(context, irp->DeviceId, irp->FileId, irp->CompletionId, NULL);
@@ -1495,7 +1523,10 @@ static BOOL rdpdr_server_drive_query_directory_callback1(RdpdrServerContext* con
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to query the directory. */
        status = rdpdr_server_send_device_query_directory_request(context, deviceId, fileId, irp->CompletionId, irp->PathName);
@@ -1524,7 +1555,10 @@ static BOOL rdpdr_server_drive_query_directory(RdpdrServerContext* context, void
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to open the directory. */
        status = rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName,
@@ -1581,7 +1615,10 @@ static BOOL rdpdr_server_drive_open_file(RdpdrServerContext* context, void* call
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to open the file. */
        status = rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName,
@@ -1644,7 +1681,10 @@ static BOOL rdpdr_server_drive_read_file(RdpdrServerContext* context, void* call
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to open the directory. */
        status = rdpdr_server_send_device_read_request(context, deviceId, fileId, irp->CompletionId, length, offset);
@@ -1700,7 +1740,10 @@ static BOOL rdpdr_server_drive_write_file(RdpdrServerContext* context, void* cal
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to open the directory. */
        status = rdpdr_server_send_device_write_request(context, deviceId, fileId, irp->CompletionId, buffer, length, offset);
@@ -1745,7 +1788,10 @@ static BOOL rdpdr_server_drive_close_file(RdpdrServerContext* context, void* cal
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to open the directory. */
        status = rdpdr_server_send_device_close_request(context, deviceId, fileId, irp->CompletionId);
@@ -1806,7 +1852,10 @@ static BOOL rdpdr_server_drive_delete_file_callback1(RdpdrServerContext* context
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to close the file */
        status = rdpdr_server_send_device_close_request(context, deviceId, fileId, irp->CompletionId);
@@ -1835,7 +1884,10 @@ static BOOL rdpdr_server_drive_delete_file(RdpdrServerContext* context, void* ca
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to open the file. */
        status = rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName,
@@ -1884,7 +1936,10 @@ static BOOL rdpdr_server_drive_rename_file_callback2(RdpdrServerContext* context
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to close the file */
        status = rdpdr_server_send_device_close_request(context, deviceId, irp->FileId, irp->CompletionId);
@@ -1927,7 +1982,10 @@ static BOOL rdpdr_server_drive_rename_file_callback1(RdpdrServerContext* context
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to rename the file */
        status = rdpdr_server_send_device_file_rename_request(context, deviceId, fileId, irp->CompletionId, irp->ExtraBuffer);
@@ -1958,7 +2016,10 @@ static BOOL rdpdr_server_drive_rename_file(RdpdrServerContext* context, void* ca
        status = rdpdr_server_enqueue_irp(context, irp);
 
        if (!status)
+       {
+               rdpdr_server_irp_free(irp);
                return FALSE;
+       }
 
        /* Send a request to open the file. */
        status = rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName,
@@ -1992,15 +2053,25 @@ RdpdrServerContext* rdpdr_server_context_new(HANDLE vcm)
 
                context->priv = (RdpdrServerPrivate*) calloc(1, sizeof(RdpdrServerPrivate));
 
-               if (context->priv)
+               if (!context->priv)
                {
-                       context->priv->VersionMajor = RDPDR_VERSION_MAJOR;
-                       context->priv->VersionMinor = RDPDR_VERSION_MINOR_RDP6X;
-                       context->priv->ClientId = g_ClientId++;
-                       context->priv->UserLoggedOnPdu = TRUE;
+                       free(context);
+                       return NULL;
+               }
 
-                       context->priv->IrpList = ListDictionary_New(TRUE);
-                       context->priv->NextCompletionId = 1;
+               context->priv->VersionMajor = RDPDR_VERSION_MAJOR;
+               context->priv->VersionMinor = RDPDR_VERSION_MINOR_RDP6X;
+               context->priv->ClientId = g_ClientId++;
+               context->priv->UserLoggedOnPdu = TRUE;
+               context->priv->NextCompletionId = 1;
+
+               context->priv->IrpList = ListDictionary_New(TRUE);
+
+               if (!context->priv->IrpList)
+               {
+                       free(context->priv);
+                       free(context);
+                       return NULL;
                }
        }