static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) { UINT16 component; UINT16 packetID; UINT32 deviceID; UINT32 status; rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin; stream_read_UINT16(data_in, component); stream_read_UINT16(data_in, packetID); if (component == RDPDR_CTYP_CORE) { switch (packetID) { case PAKID_CORE_SERVER_ANNOUNCE: DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_SERVER_ANNOUNCE"); rdpdr_process_server_announce_request(rdpdr, data_in); rdpdr_send_client_announce_reply(rdpdr); rdpdr_send_client_name_request(rdpdr); break; case PAKID_CORE_SERVER_CAPABILITY: DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_SERVER_CAPABILITY"); rdpdr_process_capability_request(rdpdr, data_in); rdpdr_send_capability_response(rdpdr); break; case PAKID_CORE_CLIENTID_CONFIRM: DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_CLIENTID_CONFIRM"); rdpdr_process_server_clientid_confirm(rdpdr, data_in); rdpdr_send_device_list_announce_request(rdpdr, FALSE); break; case PAKID_CORE_USER_LOGGEDON: DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_USER_LOGGEDON"); rdpdr_send_device_list_announce_request(rdpdr, TRUE); break; case PAKID_CORE_DEVICE_REPLY: /* connect to a specific resource */ stream_read_UINT32(data_in, deviceID); stream_read_UINT32(data_in, status); DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_DEVICE_REPLY (deviceID=%d status=0x%08X)", deviceID, status); break; case PAKID_CORE_DEVICE_IOREQUEST: DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_DEVICE_IOREQUEST"); if (rdpdr_process_irp(rdpdr, data_in)) data_in = NULL; break; default: DEBUG_WARN("RDPDR_CTYP_CORE / unknown packetID: 0x%02X", packetID); break; } } else if (component == RDPDR_CTYP_PRN) { DEBUG_SVC("RDPDR_CTYP_PRN"); } else { DEBUG_WARN("RDPDR component: 0x%02X packetID: 0x%02X", component, packetID); } stream_free(data_in); }
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, STREAM* input) { char* s = NULL; mode_t m; UINT64 size; int status; char* fullpath; struct STAT st; struct timeval tv[2]; UINT64 LastWriteTime; UINT32 FileAttributes; UINT32 FileNameLength; m = 0; switch (FsInformationClass) { case FileBasicInformation: /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */ stream_seek_UINT64(input); /* CreationTime */ stream_seek_UINT64(input); /* LastAccessTime */ stream_read_UINT64(input, LastWriteTime); stream_seek_UINT64(input); /* ChangeTime */ stream_read_UINT32(input, FileAttributes); if (FSTAT(file->fd, &st) != 0) return FALSE; tv[0].tv_sec = st.st_atime; tv[0].tv_usec = 0; tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime); tv[1].tv_usec = 0; #ifndef WIN32 /* TODO on win32 */ futimes(file->fd, tv); if (FileAttributes > 0) { m = st.st_mode; if ((FileAttributes & FILE_ATTRIBUTE_READONLY) == 0) m |= S_IWUSR; else m &= ~S_IWUSR; if (m != st.st_mode) fchmod(file->fd, st.st_mode); } #endif break; case FileEndOfFileInformation: /* http://msdn.microsoft.com/en-us/library/cc232067.aspx */ case FileAllocationInformation: /* http://msdn.microsoft.com/en-us/library/cc232076.aspx */ stream_read_UINT64(input, size); if (ftruncate(file->fd, size) != 0) return FALSE; break; case FileDispositionInformation: /* http://msdn.microsoft.com/en-us/library/cc232098.aspx */ /* http://msdn.microsoft.com/en-us/library/cc241371.aspx */ if (Length) stream_read_BYTE(input, file->delete_pending); else file->delete_pending = 1; break; case FileRenameInformation: /* http://msdn.microsoft.com/en-us/library/cc232085.aspx */ stream_seek_BYTE(input); /* ReplaceIfExists */ stream_seek_BYTE(input); /* RootDirectory */ stream_read_UINT32(input, FileNameLength); status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(input), FileNameLength / 2, &s, 0, NULL, NULL); if (status < 1) s = (char*) calloc(1, 1); fullpath = drive_file_combine_fullpath(file->basepath, s); free(s); /* TODO rename does not work on win32 */ if (rename(file->fullpath, fullpath) == 0) { DEBUG_SVC("renamed %s to %s", file->fullpath, fullpath); drive_file_set_fullpath(file, fullpath); } else { DEBUG_WARN("rename %s to %s failed, errno = %d", file->fullpath, fullpath, errno); free(fullpath); return FALSE; } break; default: DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); return FALSE; } return TRUE; }
BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate, wStream* s) { UINT32 dwSigAlgId; UINT32 dwKeyAlgId; UINT32 wPublicKeyBlobType; UINT32 wPublicKeyBlobLen; UINT32 wSignatureBlobType; UINT32 wSignatureBlobLen; BYTE* sigdata; int sigdatalen; if(stream_get_left(s) < 12) return FALSE; /* -4, because we need to include dwVersion */ sigdata = stream_get_tail(s) - 4; stream_read_UINT32(s, dwSigAlgId); stream_read_UINT32(s, dwKeyAlgId); if (!(dwSigAlgId == SIGNATURE_ALG_RSA && dwKeyAlgId == KEY_EXCHANGE_ALG_RSA)) { fprintf(stderr, "certificate_read_server_proprietary_certificate: parse error 1\n"); return FALSE; } stream_read_UINT16(s, wPublicKeyBlobType); if (wPublicKeyBlobType != BB_RSA_KEY_BLOB) { fprintf(stderr, "certificate_read_server_proprietary_certificate: parse error 2\n"); return FALSE; } stream_read_UINT16(s, wPublicKeyBlobLen); if(stream_get_left(s) < wPublicKeyBlobLen) return FALSE; if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen)) { fprintf(stderr, "certificate_read_server_proprietary_certificate: parse error 3\n"); return FALSE; } if(stream_get_left(s) < 4) return FALSE; sigdatalen = stream_get_tail(s) - sigdata; stream_read_UINT16(s, wSignatureBlobType); if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB) { fprintf(stderr, "certificate_read_server_proprietary_certificate: parse error 4\n"); return FALSE; } stream_read_UINT16(s, wSignatureBlobLen); if(stream_get_left(s) < wSignatureBlobLen) return FALSE; if (wSignatureBlobLen != 72) { fprintf(stderr, "certificate_process_server_public_signature: invalid signature length (got %d, expected %d)\n", wSignatureBlobLen, 64); return FALSE; } if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s, wSignatureBlobLen)) { fprintf(stderr, "certificate_read_server_proprietary_certificate: parse error 5\n"); return FALSE; } return TRUE; }
BOOL gcc_read_client_core_data(STREAM* s, rdpSettings* settings, UINT16 blockLength) { char* str; UINT32 version; UINT32 color_depth; UINT16 colorDepth = 0; UINT16 postBeta2ColorDepth = 0; UINT16 highColorDepth = 0; UINT16 supportedColorDepths = 0; UINT16 earlyCapabilityFlags = 0; UINT32 serverSelectedProtocol = 0; /* Length of all required fields, until imeFileName */ if (blockLength < 128) return FALSE; stream_read_UINT32(s, version); /* version */ settings->RdpVersion = (version == RDP_VERSION_4 ? 4 : 7); stream_read_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ stream_read_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ stream_read_UINT16(s, colorDepth); /* ColorDepth */ stream_seek_UINT16(s); /* SASSequence (Secure Access Sequence) */ stream_read_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ stream_read_UINT32(s, settings->ClientBuild); /* ClientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 32 / 2, &str, 0, NULL, NULL); stream_seek(s, 32); sprintf_s(settings->ClientHostname, 31, "%s", str); settings->ClientHostname[31] = 0; free(str); stream_read_UINT32(s, settings->KeyboardType); /* KeyboardType */ stream_read_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ stream_read_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ stream_seek(s, 64); /* imeFileName */ blockLength -= 128; /** * The following fields are all optional. If one field is present, all of the preceding * fields MUST also be present. If one field is not present, all of the subsequent fields * MUST NOT be present. * We must check the bytes left before reading each field. */ do { if (blockLength < 2) break; stream_read_UINT16(s, postBeta2ColorDepth); /* postBeta2ColorDepth */ blockLength -= 2; if (blockLength < 2) break; stream_seek_UINT16(s); /* clientProductID */ blockLength -= 2; if (blockLength < 4) break; stream_seek_UINT32(s); /* serialNumber */ blockLength -= 4; if (blockLength < 2) break; stream_read_UINT16(s, highColorDepth); /* highColorDepth */ blockLength -= 2; if (blockLength < 2) break; stream_read_UINT16(s, supportedColorDepths); /* supportedColorDepths */ blockLength -= 2; if (blockLength < 2) break; stream_read_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ blockLength -= 2; if (blockLength < 64) break; ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 64 / 2, &str, 0, NULL, NULL); stream_seek(s, 64); sprintf_s(settings->ClientProductId, 32, "%s", str); free(str); blockLength -= 64; if (blockLength < 1) break; stream_read_BYTE(s, settings->PerformanceFlags); /* connectionType */ blockLength -= 1; if (blockLength < 1) break; stream_seek_BYTE(s); /* pad1octet */ blockLength -= 1; if (blockLength < 4) break; stream_read_UINT32(s, serverSelectedProtocol); /* serverSelectedProtocol */ blockLength -= 4; if (settings->SelectedProtocol != serverSelectedProtocol) return FALSE; } while (0); if (highColorDepth > 0) { color_depth = highColorDepth; } else if (postBeta2ColorDepth > 0) { switch (postBeta2ColorDepth) { case RNS_UD_COLOR_4BPP: color_depth = 4; break; case RNS_UD_COLOR_8BPP: color_depth = 8; break; case RNS_UD_COLOR_16BPP_555: color_depth = 15; break; case RNS_UD_COLOR_16BPP_565: color_depth = 16; break; case RNS_UD_COLOR_24BPP: color_depth = 24; break; default: return FALSE; } } else { switch (colorDepth) { case RNS_UD_COLOR_4BPP: color_depth = 4; break; case RNS_UD_COLOR_8BPP: color_depth = 8; break; default: return FALSE; } } /* * If we are in server mode, accept client's color depth only if * it is smaller than ours. This is what Windows server does. */ if (color_depth < settings->ColorDepth || !settings->ServerMode) settings->ColorDepth = color_depth; return TRUE; }
BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, STREAM* s) { UINT16 flags; UINT16 length; rdpRedirection* redirection = rdp->redirection; if(stream_get_left(s) < 12) return FALSE; stream_read_UINT16(s, flags); /* flags (2 bytes) */ stream_read_UINT16(s, length); /* length (2 bytes) */ stream_read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */ stream_read_UINT32(s, redirection->flags); /* redirFlags (4 bytes) */ DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, redirection->sessionID); #ifdef WITH_DEBUG_REDIR rdp_print_redirection_flags(redirection->flags); #endif if (redirection->flags & LB_TARGET_NET_ADDRESS) { if(!freerdp_string_read_length32(s, &redirection->targetNetAddress)) return FALSE; DEBUG_REDIR("targetNetAddress: %s", redirection->targetNetAddress.ascii); } if (redirection->flags & LB_LOAD_BALANCE_INFO) { if(stream_get_left(s) < 4) return FALSE; stream_read_UINT32(s, redirection->LoadBalanceInfoLength); if(stream_get_left(s) < redirection->LoadBalanceInfoLength) return FALSE; redirection->LoadBalanceInfo = (BYTE*) malloc(redirection->LoadBalanceInfoLength); stream_read(s, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength); #ifdef WITH_DEBUG_REDIR DEBUG_REDIR("loadBalanceInfo:"); winpr_HexDump(redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength); #endif } if (redirection->flags & LB_USERNAME) { if(!freerdp_string_read_length32(s, &redirection->username)) return FALSE; DEBUG_REDIR("username: %s", redirection->username.ascii); } if (redirection->flags & LB_DOMAIN) { if(!freerdp_string_read_length32(s, &redirection->domain)) return FALSE; DEBUG_REDIR("domain: %s", redirection->domain.ascii); } if (redirection->flags & LB_PASSWORD) { /* Note: length (hopefully) includes double zero termination */ if(stream_get_left(s) < 4) return FALSE; stream_read_UINT32(s, redirection->PasswordCookieLength); redirection->PasswordCookie = (BYTE*) malloc(redirection->PasswordCookieLength); stream_read(s, redirection->PasswordCookie, redirection->PasswordCookieLength); #ifdef WITH_DEBUG_REDIR DEBUG_REDIR("password_cookie:"); winpr_HexDump(redirection->PasswordCookie, redirection->PasswordCookieLength); #endif } if (redirection->flags & LB_TARGET_FQDN) { if(!freerdp_string_read_length32(s, &redirection->targetFQDN)) return FALSE; DEBUG_REDIR("targetFQDN: %s", redirection->targetFQDN.ascii); } if (redirection->flags & LB_TARGET_NETBIOS_NAME) { if(!freerdp_string_read_length32(s, &redirection->targetNetBiosName)) return FALSE; DEBUG_REDIR("targetNetBiosName: %s", redirection->targetNetBiosName.ascii); } if (redirection->flags & LB_CLIENT_TSV_URL) { if(!freerdp_string_read_length32(s, &redirection->tsvUrl)) return FALSE; DEBUG_REDIR("tsvUrl: %s", redirection->tsvUrl.ascii); } if (redirection->flags & LB_TARGET_NET_ADDRESSES) { int i; UINT32 count; UINT32 targetNetAddressesLength; if(stream_get_left(s) < 8) return FALSE; stream_read_UINT32(s, targetNetAddressesLength); stream_read_UINT32(s, redirection->targetNetAddressesCount); count = redirection->targetNetAddressesCount; redirection->targetNetAddresses = (rdpString*) malloc(count * sizeof(rdpString)); ZeroMemory(redirection->targetNetAddresses, count * sizeof(rdpString)); for (i = 0; i < (int) count; i++) { if(!freerdp_string_read_length32(s, &redirection->targetNetAddresses[i])) return FALSE; DEBUG_REDIR("targetNetAddresses: %s", (&redirection->targetNetAddresses[i])->ascii); } } if (!stream_skip(s, 8)) /* pad (8 bytes) */ return FALSE; if (redirection->flags & LB_NOREDIRECT) return TRUE; else return rdp_client_redirect(rdp); }
BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) { int i; int size; if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) { if(stream_get_left(s) < 4) return FALSE; stream_read_UINT32(s, window_state->ownerWindowId); /* ownerWindowId (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) { if(stream_get_left(s) < 8) return FALSE; stream_read_UINT32(s, window_state->style); /* style (4 bytes) */ stream_read_UINT32(s, window_state->extendedStyle); /* extendedStyle (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) { if(stream_get_left(s) < 1) return FALSE; stream_read_BYTE(s, window_state->showState); /* showState (1 byte) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) { if(!rail_read_unicode_string(s, &window_state->titleInfo)) /* titleInfo */ return FALSE; } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) { if(stream_get_left(s) < 4) return FALSE; stream_read_UINT32(s, window_state->clientOffsetX); /* clientOffsetX (4 bytes) */ stream_read_UINT32(s, window_state->clientOffsetY); /* clientOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) { if(stream_get_left(s) < 4) return FALSE; stream_read_UINT32(s, window_state->clientAreaWidth); /* clientAreaWidth (4 bytes) */ stream_read_UINT32(s, window_state->clientAreaHeight); /* clientAreaHeight (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) { if(stream_get_left(s) < 1) return FALSE; stream_read_BYTE(s, window_state->RPContent); /* RPContent (1 byte) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) { if(stream_get_left(s) < 4) return FALSE; stream_read_UINT32(s, window_state->rootParentHandle);/* rootParentHandle (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) { if(stream_get_left(s) < 8) return FALSE; stream_read_UINT32(s, window_state->windowOffsetX); /* windowOffsetX (4 bytes) */ stream_read_UINT32(s, window_state->windowOffsetY); /* windowOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) { if(stream_get_left(s) < 8) return FALSE; stream_read_UINT32(s, window_state->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */ stream_read_UINT32(s, window_state->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) { if(stream_get_left(s) < 8) return FALSE; stream_read_UINT32(s, window_state->windowWidth); /* windowWidth (4 bytes) */ stream_read_UINT32(s, window_state->windowHeight); /* windowHeight (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) { if(stream_get_left(s) < 2) return FALSE; stream_read_UINT16(s, window_state->numWindowRects); /* numWindowRects (2 bytes) */ size = sizeof(RECTANGLE_16) * window_state->numWindowRects; window_state->windowRects = (RECTANGLE_16*) malloc(size); if(stream_get_left(s) < 8 * window_state->numWindowRects) return FALSE; /* windowRects */ for (i = 0; i < (int) window_state->numWindowRects; i++) { stream_read_UINT16(s, window_state->windowRects[i].left); /* left (2 bytes) */ stream_read_UINT16(s, window_state->windowRects[i].top); /* top (2 bytes) */ stream_read_UINT16(s, window_state->windowRects[i].right); /* right (2 bytes) */ stream_read_UINT16(s, window_state->windowRects[i].bottom); /* bottom (2 bytes) */ } } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) { if(stream_get_left(s) < 4) return FALSE; stream_read_UINT32(s, window_state->visibleOffsetX); /* visibleOffsetX (4 bytes) */ stream_read_UINT32(s, window_state->visibleOffsetY); /* visibleOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) { if(stream_get_left(s) < 2) return FALSE; stream_read_UINT16(s, window_state->numVisibilityRects); /* numVisibilityRects (2 bytes) */ size = sizeof(RECTANGLE_16) * window_state->numVisibilityRects; window_state->visibilityRects = (RECTANGLE_16*) malloc(size); if(stream_get_left(s) < window_state->numVisibilityRects * 8) return FALSE; /* visibilityRects */ for (i = 0; i < (int) window_state->numVisibilityRects; i++) { stream_read_UINT16(s, window_state->visibilityRects[i].left); /* left (2 bytes) */ stream_read_UINT16(s, window_state->visibilityRects[i].top); /* top (2 bytes) */ stream_read_UINT16(s, window_state->visibilityRects[i].right); /* right (2 bytes) */ stream_read_UINT16(s, window_state->visibilityRects[i].bottom); /* bottom (2 bytes) */ } } return TRUE; }
static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) { int i; UINT16 subtype; UINT32 blockLen; UINT32 blockType; UINT32 tilesDataSize; UINT32* quants; BYTE quant; int pos; stream_read_UINT16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */ if (subtype != CBT_TILESET) { DEBUG_WARN("invalid subtype, expected CBT_TILESET."); return; } stream_seek_UINT16(s); /* idx (2 bytes), must be set to 0x0000 */ stream_seek_UINT16(s); /* properties (2 bytes) */ stream_read_BYTE(s, context->num_quants); /* numQuant (1 byte) */ stream_seek_BYTE(s); /* tileSize (1 byte), must be set to 0x40 */ if (context->num_quants < 1) { DEBUG_WARN("no quantization value."); return; } stream_read_UINT16(s, message->num_tiles); /* numTiles (2 bytes) */ if (message->num_tiles < 1) { DEBUG_WARN("no tiles."); return; } stream_read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */ if (context->quants != NULL) context->quants = (UINT32*) realloc((void*) context->quants, context->num_quants * 10 * sizeof(UINT32)); else context->quants = (UINT32*) malloc(context->num_quants * 10 * sizeof(UINT32)); quants = context->quants; /* quantVals */ for (i = 0; i < context->num_quants; i++) { /* RFX_CODEC_QUANT */ stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); DEBUG_RFX("quant %d (%d %d %d %d %d %d %d %d %d %d).", i, context->quants[i * 10], context->quants[i * 10 + 1], context->quants[i * 10 + 2], context->quants[i * 10 + 3], context->quants[i * 10 + 4], context->quants[i * 10 + 5], context->quants[i * 10 + 6], context->quants[i * 10 + 7], context->quants[i * 10 + 8], context->quants[i * 10 + 9]); } message->tiles = rfx_pool_get_tiles(context->priv->pool, message->num_tiles); /* tiles */ for (i = 0; i < message->num_tiles; i++) { /* RFX_TILE */ stream_read_UINT16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */ stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */ pos = stream_get_pos(s) - 6 + blockLen; if (blockType != CBT_TILE) { DEBUG_WARN("unknown block type 0x%X, expected CBT_TILE (0xCAC3).", blockType); break; } rfx_process_message_tile(context, message->tiles[i], s); stream_set_pos(s, pos); } }
static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) { int i; int pos; BYTE quant; UINT32* quants; UINT16 subtype; UINT32 blockLen; UINT32 blockType; UINT32 tilesDataSize; PTP_WORK* work_objects = NULL; RFX_TILE_WORK_PARAM* params = NULL; stream_read_UINT16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */ if (subtype != CBT_TILESET) { DEBUG_WARN("invalid subtype, expected CBT_TILESET."); return; } stream_seek_UINT16(s); /* idx (2 bytes), must be set to 0x0000 */ stream_seek_UINT16(s); /* properties (2 bytes) */ stream_read_BYTE(s, context->num_quants); /* numQuant (1 byte) */ stream_seek_BYTE(s); /* tileSize (1 byte), must be set to 0x40 */ if (context->num_quants < 1) { DEBUG_WARN("no quantization value."); return; } stream_read_UINT16(s, message->num_tiles); /* numTiles (2 bytes) */ if (message->num_tiles < 1) { DEBUG_WARN("no tiles."); return; } stream_read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */ if (context->quants != NULL) context->quants = (UINT32*) realloc((void*) context->quants, context->num_quants * 10 * sizeof(UINT32)); else context->quants = (UINT32*) malloc(context->num_quants * 10 * sizeof(UINT32)); quants = context->quants; /* quantVals */ for (i = 0; i < context->num_quants; i++) { /* RFX_CODEC_QUANT */ stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); stream_read_BYTE(s, quant); *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); DEBUG_RFX("quant %d (%d %d %d %d %d %d %d %d %d %d).", i, context->quants[i * 10], context->quants[i * 10 + 1], context->quants[i * 10 + 2], context->quants[i * 10 + 3], context->quants[i * 10 + 4], context->quants[i * 10 + 5], context->quants[i * 10 + 6], context->quants[i * 10 + 7], context->quants[i * 10 + 8], context->quants[i * 10 + 9]); } message->tiles = (RFX_TILE**) malloc(sizeof(RFX_TILE*) * message->num_tiles); ZeroMemory(message->tiles, sizeof(RFX_TILE*) * message->num_tiles); if (context->priv->UseThreads) { work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->num_tiles); params = (RFX_TILE_WORK_PARAM*) malloc(sizeof(RFX_TILE_WORK_PARAM) * message->num_tiles); } /* tiles */ for (i = 0; i < message->num_tiles; i++) { /* RFX_TILE */ stream_read_UINT16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */ stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */ pos = stream_get_pos(s) - 6 + blockLen; if (blockType != CBT_TILE) { DEBUG_WARN("unknown block type 0x%X, expected CBT_TILE (0xCAC3).", blockType); break; } message->tiles[i] = rfx_tile_pool_take(context); if (context->priv->UseThreads) { params[i].context = context; params[i].tile = message->tiles[i]; CopyMemory(&(params[i].s), s, sizeof(STREAM)); work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_process_message_tile_work_callback, (void*) ¶ms[i], &context->priv->ThreadPoolEnv); SubmitThreadpoolWork(work_objects[i]); } else { rfx_process_message_tile(context, message->tiles[i], s); } stream_set_pos(s, pos); } if (context->priv->UseThreads) { for (i = 0; i < message->num_tiles; i++) WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE); free(work_objects); free(params); } }
void update_read_pointer_system(STREAM* s, POINTER_SYSTEM_UPDATE* pointer_system) { stream_read_UINT32(s, pointer_system->type); /* systemPointerType (4 bytes) */ }
int rts_recv_pdu_commands(rdpRpc* rpc, RTS_PDU* rts_pdu) { int i; STREAM* s; UINT32 CommandType; DEBUG_RTS("numberOfCommands:%d", rts_pdu->header.numberOfCommands); if (rts_pdu->header.flags & RTS_FLAG_PING) { rts_send_keep_alive_pdu(rpc); return 0; } s = stream_new(0); stream_attach(s, rts_pdu->content, rts_pdu->header.frag_length); for (i = 0; i < rts_pdu->header.numberOfCommands; i++) { stream_read_UINT32(s, CommandType); /* CommandType (4 bytes) */ DEBUG_RTS("CommandType: %s (0x%08X)", RTS_CMD_STRINGS[CommandType % 14], CommandType); switch (CommandType) { case RTS_CMD_RECEIVE_WINDOW_SIZE: rts_receive_window_size_command_read(rpc, s); break; case RTS_CMD_FLOW_CONTROL_ACK: rts_flow_control_ack_command_read(rpc, s); break; case RTS_CMD_CONNECTION_TIMEOUT: rts_connection_timeout_command_read(rpc, s); break; case RTS_CMD_COOKIE: rts_cookie_command_read(rpc, s); break; case RTS_CMD_CHANNEL_LIFETIME: rts_channel_lifetime_command_read(rpc, s); break; case RTS_CMD_CLIENT_KEEPALIVE: rts_client_keepalive_command_read(rpc, s); break; case RTS_CMD_VERSION: rts_version_command_read(rpc, s); break; case RTS_CMD_EMPTY: rts_empty_command_read(rpc, s); break; case RTS_CMD_PADDING: rts_padding_command_read(rpc, s); break; case RTS_CMD_NEGATIVE_ANCE: rts_negative_ance_command_read(rpc, s); break; case RTS_CMD_ANCE: rts_ance_command_read(rpc, s); break; case RTS_CMD_CLIENT_ADDRESS: rts_client_address_command_read(rpc, s); break; case RTS_CMD_ASSOCIATION_GROUP_ID: rts_association_group_id_command_read(rpc, s); break; case RTS_CMD_DESTINATION: rts_destination_command_read(rpc, s); break; case RTS_CMD_PING_TRAFFIC_SENT_NOTIFY: rts_ping_traffic_sent_notify_command_read(rpc, s); break; default: printf("Error: Unknown RTS Command Type: 0x%x\n", CommandType); stream_detach(s) ; stream_free(s) ; return -1; break; } } stream_detach(s); stream_free(s); return 0; }
void update_read_play_sound(STREAM* s, PLAY_SOUND_UPDATE* play_sound) { stream_read_UINT32(s, play_sound->duration); /* duration (4 bytes) */ stream_read_UINT32(s, play_sound->frequency); /* frequency (4 bytes) */ }
void rail_read_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info) { stream_read_UINT32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */ }
void rail_read_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake) { stream_read_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ }
static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s) { BYTE type; UINT16 length; UINT32 share_id; BYTE compressed_type; UINT16 compressed_len; if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len)) return FALSE; switch (type) { case DATA_PDU_TYPE_SYNCHRONIZE: if (!rdp_recv_client_synchronize_pdu(client->context->rdp, s)) return FALSE; break; case DATA_PDU_TYPE_CONTROL: if (!rdp_server_accept_client_control_pdu(client->context->rdp, s)) return FALSE; break; case DATA_PDU_TYPE_INPUT: if (!input_recv(client->context->rdp->input, s)) return FALSE; break; case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: /* TODO: notify server bitmap cache data */ break; case DATA_PDU_TYPE_FONT_LIST: if (!rdp_server_accept_client_font_list_pdu(client->context->rdp, s)) return FALSE; if (!client->connected) { /** * PostConnect should only be called once and should not be called * after a reactivation sequence. */ IFCALLRET(client->PostConnect, client->connected, client); if (!client->connected) return FALSE; } if (!client->activated) { /* Activate will be called everytime after the client is activated/reactivated. */ IFCALLRET(client->Activate, client->activated, client); if (!client->activated) return FALSE; } break; case DATA_PDU_TYPE_SHUTDOWN_REQUEST: mcs_send_disconnect_provider_ultimatum(client->context->rdp->mcs); return FALSE; case DATA_PDU_TYPE_FRAME_ACKNOWLEDGE: if(stream_get_left(s) < 4) return FALSE; stream_read_UINT32(s, client->ack_frame_id); break; case DATA_PDU_TYPE_REFRESH_RECT: if (!update_read_refresh_rect(client->update, s)) return FALSE; break; case DATA_PDU_TYPE_SUPPRESS_OUTPUT: if (!update_read_suppress_output(client->update, s)) return FALSE; break; default: fprintf(stderr, "Data PDU type %d\n", type); break; } return TRUE; }
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length) { int pos; STREAM* s; UINT32 blockLen; UINT32 blockType; RFX_MESSAGE* message; message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE)); ZeroMemory(message, sizeof(RFX_MESSAGE)); s = stream_new(0); stream_attach(s, data, length); while (stream_get_left(s) > 6) { /* RFX_BLOCKT */ stream_read_UINT16(s, blockType); /* blockType (2 bytes) */ stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */ DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen); if (blockLen == 0) { DEBUG_WARN("zero blockLen"); break; } pos = stream_get_pos(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ stream_seek(s, 2); } switch (blockType) { case WBT_SYNC: rfx_process_message_sync(context, s); break; case WBT_CODEC_VERSIONS: rfx_process_message_codec_versions(context, s); break; case WBT_CHANNELS: rfx_process_message_channels(context, s); break; case WBT_CONTEXT: rfx_process_message_context(context, s); break; case WBT_FRAME_BEGIN: rfx_process_message_frame_begin(context, message, s); break; case WBT_FRAME_END: rfx_process_message_frame_end(context, message, s); break; case WBT_REGION: rfx_process_message_region(context, message, s); break; case WBT_EXTENSION: rfx_process_message_tileset(context, message, s); break; default: DEBUG_WARN("unknown blockType 0x%X", blockType); break; } stream_set_pos(s, pos); } stream_detach(s); stream_free(s); return message; }
static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp) { char* path; int status; UINT32 FileId; DRIVE_FILE* file; BYTE Information; UINT32 DesiredAccess; UINT32 CreateDisposition; UINT32 CreateOptions; UINT32 PathLength; stream_read_UINT32(irp->input, DesiredAccess); stream_seek(irp->input, 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */ stream_read_UINT32(irp->input, CreateDisposition); stream_read_UINT32(irp->input, CreateOptions); stream_read_UINT32(irp->input, PathLength); status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input), PathLength / 2, &path, 0, NULL, NULL); if (status < 1) path = (char*) calloc(1, 1); FileId = irp->devman->id_sequence++; file = drive_file_new(disk->path, path, FileId, DesiredAccess, CreateDisposition, CreateOptions); if (file == NULL) { irp->IoStatus = STATUS_UNSUCCESSFUL; FileId = 0; Information = 0; DEBUG_WARN("failed to create %s.", path); } else if (file->err) { FileId = 0; Information = 0; /* map errno to windows result */ irp->IoStatus = drive_map_posix_err(file->err); drive_file_free(file); } else { list_enqueue(disk->files, file); switch (CreateDisposition) { case FILE_SUPERSEDE: case FILE_OPEN: case FILE_CREATE: case FILE_OVERWRITE: Information = FILE_SUPERSEDED; break; case FILE_OPEN_IF: Information = FILE_OPENED; break; case FILE_OVERWRITE_IF: Information = FILE_OVERWRITTEN; break; default: Information = 0; break; } DEBUG_SVC("%s(%d) created.", file->fullpath, file->id); } stream_write_UINT32(irp->output, FileId); stream_write_BYTE(irp->output, Information); free(path); irp->Complete(irp); }
static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP* irp) { UINT32 FsInformationClass; wStream* output = irp->output; struct STATVFS svfst; struct STAT st; char* volumeLabel = {"FREERDP"}; char* diskType = {"FAT32"}; WCHAR* outStr = NULL; int length; stream_read_UINT32(irp->input, FsInformationClass); STATVFS(disk->path, &svfst); STAT(disk->path, &st); switch (FsInformationClass) { case FileFsVolumeInformation: /* http://msdn.microsoft.com/en-us/library/cc232108.aspx */ length = ConvertToUnicode(CP_UTF8, 0, volumeLabel, -1, &outStr, 0) * 2; stream_write_UINT32(output, 17 + length); /* Length */ stream_check_size(output, 17 + length); stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */ #ifdef ANDROID stream_write_UINT32(output, svfst.f_fsid.__val[0]); /* VolumeSerialNumber */ #else stream_write_UINT32(output, svfst.f_fsid); /* VolumeSerialNumber */ #endif stream_write_UINT32(output, length); /* VolumeLabelLength */ stream_write_BYTE(output, 0); /* SupportsObjects */ /* Reserved(1), MUST NOT be added! */ stream_write(output, outStr, length); /* VolumeLabel (Unicode) */ free(outStr); break; case FileFsSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232107.aspx */ stream_write_UINT32(output, 24); /* Length */ stream_check_size(output, 24); stream_write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ stream_write_UINT64(output, svfst.f_bavail); /* AvailableAllocationUnits */ stream_write_UINT32(output, 1); /* SectorsPerAllocationUnit */ stream_write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsAttributeInformation: /* http://msdn.microsoft.com/en-us/library/cc232101.aspx */ length = ConvertToUnicode(CP_UTF8, 0, diskType, -1, &outStr, 0) * 2; stream_write_UINT32(output, 12 + length); /* Length */ stream_check_size(output, 12 + length); stream_write_UINT32(output, FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ #ifdef ANDROID stream_write_UINT32(output, 255); /* MaximumComponentNameLength */ #else stream_write_UINT32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */ #endif stream_write_UINT32(output, length); /* FileSystemNameLength */ stream_write(output, outStr, length); /* FileSystemName (Unicode) */ free(outStr); break; case FileFsFullSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232104.aspx */ stream_write_UINT32(output, 32); /* Length */ stream_check_size(output, 32); stream_write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ stream_write_UINT64(output, svfst.f_bavail); /* CallerAvailableAllocationUnits */ stream_write_UINT64(output, svfst.f_bfree); /* AvailableAllocationUnits */ stream_write_UINT32(output, 1); /* SectorsPerAllocationUnit */ stream_write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsDeviceInformation: /* http://msdn.microsoft.com/en-us/library/cc232109.aspx */ stream_write_UINT32(output, 8); /* Length */ stream_check_size(output, 8); stream_write_UINT32(output, FILE_DEVICE_DISK); /* DeviceType */ stream_write_UINT32(output, 0); /* Characteristics */ break; default: irp->IoStatus = STATUS_UNSUCCESSFUL; stream_write_UINT32(output, 0); /* Length */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); break; } irp->Complete(irp); }