void rts_empty_command_write(STREAM* s) { stream_write_UINT32(s, RTS_CMD_EMPTY); /* CommandType (4 bytes) */ }
static DWORD handle_Status(IRP *irp, BOOL wide) { LONG status; SCARDHANDLE hCard; DWORD state, protocol; DWORD readerLen = 0; DWORD atrLen = 0; char* readerName; BYTE pbAtr[MAX_ATR_SIZE]; UINT32 dataLength; int pos, poslen1, poslen2; #ifdef WITH_DEBUG_SCARD int i; #endif stream_seek(irp->input, 0x24); stream_read_UINT32(irp->input, readerLen); stream_read_UINT32(irp->input, atrLen); stream_seek(irp->input, 0x0c); stream_read_UINT32(irp->input, hCard); stream_seek(irp->input, 0x4); atrLen = MAX_ATR_SIZE; #ifdef SCARD_AUTOALLOCATE readerLen = SCARD_AUTOALLOCATE; status = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #else readerLen = 256; readerName = malloc(readerLen); status = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #endif if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); return smartcard_output_return(irp, status); } DEBUG_SCARD("Success (state: 0x%08x, proto: 0x%08x)", (unsigned) state, (unsigned) protocol); DEBUG_SCARD(" Reader: \"%s\"", readerName ? readerName : "NULL"); #ifdef WITH_DEBUG_SCARD printf(" ATR: "); for (i = 0; i < atrLen; i++) printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':'); printf("\n"); #endif state = smartcard_map_state(state); poslen1 = stream_get_pos(irp->output); stream_write_UINT32(irp->output, readerLen); stream_write_UINT32(irp->output, 0x00020000); stream_write_UINT32(irp->output, state); stream_write_UINT32(irp->output, protocol); stream_write(irp->output, pbAtr, atrLen); if (atrLen < 32) stream_write_zero(irp->output, 32 - atrLen); stream_write_UINT32(irp->output, atrLen); poslen2 = stream_get_pos(irp->output); stream_write_UINT32(irp->output, readerLen); dataLength = smartcard_output_string(irp, readerName, wide); dataLength += smartcard_output_string(irp, "\0", wide); smartcard_output_repos(irp, dataLength); pos = stream_get_pos(irp->output); stream_set_pos(irp->output, poslen1); stream_write_UINT32(irp->output,dataLength); stream_set_pos(irp->output, poslen2); stream_write_UINT32(irp->output,dataLength); stream_set_pos(irp->output, pos); smartcard_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE /* SCardFreeMemory(NULL, readerName); */ free(readerName); #else free(readerName); #endif return status; }
static UINT32 handle_Control(IRP* irp) { LONG status; SCARDCONTEXT hContext; SCARDHANDLE hCard; UINT32 map[3]; UINT32 controlCode; UINT32 controlFunction; BYTE* recvBuffer = NULL; BYTE* sendBuffer = NULL; UINT32 recvLength; DWORD nBytesReturned; DWORD outBufferSize; stream_seek(irp->input, 0x14); stream_read_UINT32(irp->input, map[0]); stream_seek(irp->input, 0x4); stream_read_UINT32(irp->input, map[1]); stream_read_UINT32(irp->input, controlCode); stream_read_UINT32(irp->input, recvLength); stream_read_UINT32(irp->input, map[2]); stream_seek(irp->input, 0x4); stream_read_UINT32(irp->input, outBufferSize); stream_seek(irp->input, 0x4); stream_read_UINT32(irp->input, hContext); stream_seek(irp->input, 0x4); stream_read_UINT32(irp->input, hCard); /* Translate Windows SCARD_CTL_CODE's to corresponding local code */ if (WIN_CTL_DEVICE_TYPE(controlCode) == WIN_FILE_DEVICE_SMARTCARD) { controlFunction = WIN_CTL_FUNCTION(controlCode); controlCode = SCARD_CTL_CODE(controlFunction); } DEBUG_SCARD("controlCode: 0x%08x", (unsigned) controlCode); if (map[2] & SCARD_INPUT_LINKED) { /* read real input size */ stream_read_UINT32(irp->input, recvLength); recvBuffer = malloc(recvLength); if (!recvBuffer) return smartcard_output_return(irp, SCARD_E_NO_MEMORY); stream_read(irp->input, recvBuffer, recvLength); } nBytesReturned = outBufferSize; sendBuffer = malloc(outBufferSize); if (!sendBuffer) return smartcard_output_return(irp, SCARD_E_NO_MEMORY); status = SCardControl(hCard, (DWORD) controlCode, recvBuffer, (DWORD) recvLength, sendBuffer, (DWORD) outBufferSize, &nBytesReturned); if (status != SCARD_S_SUCCESS) DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); else DEBUG_SCARD("Success (out: %u bytes)", (unsigned) nBytesReturned); stream_write_UINT32(irp->output, (UINT32) nBytesReturned); stream_write_UINT32(irp->output, 0x00000004); stream_write_UINT32(irp->output, nBytesReturned); if (nBytesReturned > 0) { stream_write(irp->output, sendBuffer, nBytesReturned); smartcard_output_repos(irp, nBytesReturned); } smartcard_output_alignment(irp, 8); free(recvBuffer); free(sendBuffer); return status; }
void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) { UINT32 pos; UINT32 result; UINT32 result_pos; UINT32 output_len; UINT32 input_len; UINT32 ioctl_code; UINT32 stream_len; UINT32 irp_result_pos; UINT32 output_len_pos; const UINT32 header_lengths = 16; /* MS-RPCE, Sections 2.2.6.1 and 2.2.6.2. */ stream_read_UINT32(irp->input, output_len); stream_read_UINT32(irp->input, input_len); stream_read_UINT32(irp->input, ioctl_code); stream_seek(irp->input, 20); /* padding */ // stream_seek(irp->input, 4); /* TODO: parse len, le, v1 */ // stream_seek(irp->input, 4); /* 0xcccccccc */ // stream_seek(irp->input, 4); /* rpce len */ /* [MS-RDPESC] 3.2.5.1 Sending Outgoing Messages */ stream_extend(irp->output, 2048); irp_result_pos = stream_get_pos(irp->output); stream_write_UINT32(irp->output, 0x00000000); /* MS-RDPEFS * OutputBufferLength * will be updated * later in this * function. */ /* [MS-RPCE] 2.2.6.1 */ stream_write_UINT32(irp->output, 0x00081001); /* len 8, LE, v1 */ stream_write_UINT32(irp->output, 0xcccccccc); /* filler */ output_len_pos = stream_get_pos(irp->output); stream_seek(irp->output, 4); /* size */ stream_write_UINT32(irp->output, 0x0); /* filler */ result_pos = stream_get_pos(irp->output); stream_seek(irp->output, 4); /* result */ /* body */ switch (ioctl_code) { case SCARD_IOCTL_ESTABLISH_CONTEXT: result = handle_EstablishContext(irp); break; case SCARD_IOCTL_IS_VALID_CONTEXT: result = handle_IsValidContext(irp); break; case SCARD_IOCTL_RELEASE_CONTEXT: result = handle_ReleaseContext(irp); break; case SCARD_IOCTL_LIST_READERS: result = handle_ListReaders(irp, 0); break; case SCARD_IOCTL_LIST_READERS + 4: result = handle_ListReaders(irp, 1); break; case SCARD_IOCTL_LIST_READER_GROUPS: case SCARD_IOCTL_LIST_READER_GROUPS + 4: /* typically not used unless list_readers fail */ result = SCARD_F_INTERNAL_ERROR; break; case SCARD_IOCTL_GET_STATUS_CHANGE: result = handle_GetStatusChange(irp, 0); break; case SCARD_IOCTL_GET_STATUS_CHANGE + 4: result = handle_GetStatusChange(irp, 1); break; case SCARD_IOCTL_CANCEL: result = handle_Cancel(irp); break; case SCARD_IOCTL_CONNECT: result = handle_Connect(irp, 0); break; case SCARD_IOCTL_CONNECT + 4: result = handle_Connect(irp, 1); break; case SCARD_IOCTL_RECONNECT: result = handle_Reconnect(irp); break; case SCARD_IOCTL_DISCONNECT: result = handle_Disconnect(irp); break; case SCARD_IOCTL_BEGIN_TRANSACTION: result = handle_BeginTransaction(irp); break; case SCARD_IOCTL_END_TRANSACTION: result = handle_EndTransaction(irp); break; case SCARD_IOCTL_STATE: result = handle_State(irp); break; case SCARD_IOCTL_STATUS: result = handle_Status(irp, 0); break; case SCARD_IOCTL_STATUS + 4: result = handle_Status(irp, 1); break; case SCARD_IOCTL_TRANSMIT: result = handle_Transmit(irp); break; case SCARD_IOCTL_CONTROL: result = handle_Control(irp); break; case SCARD_IOCTL_GETATTRIB: result = handle_GetAttrib(irp); break; case SCARD_IOCTL_ACCESS_STARTED_EVENT: result = handle_AccessStartedEvent(irp); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR: result = handle_LocateCardsByATR(irp, 0); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4: result = handle_LocateCardsByATR(irp, 1); break; default: result = 0xc0000001; printf("scard unknown ioctl 0x%x\n", ioctl_code); break; } /* look for NTSTATUS errors */ if ((result & 0xc0000000) == 0xc0000000) return scard_error(scard, irp, result); /* per Ludovic Rousseau, map different usage of this particular * error code between pcsc-lite & windows */ if (result == 0x8010001F) result = 0x80100022; /* handle response packet */ pos = stream_get_pos(irp->output); stream_len = pos - irp_result_pos - 4; /* Value of OutputBufferLength */ stream_set_pos(irp->output, irp_result_pos); stream_write_UINT32(irp->output, stream_len); stream_set_pos(irp->output, output_len_pos); /* Remove the effect of the MS-RPCE Common Type Header and Private * Header (Sections 2.2.6.1 and 2.2.6.2). */ stream_write_UINT32(irp->output, stream_len - header_lengths); stream_set_pos(irp->output, result_pos); stream_write_UINT32(irp->output, result); stream_set_pos(irp->output, pos); #ifdef WITH_DEBUG_SCARD winpr_HexDump(stream_get_data(irp->output), stream_get_length(irp->output)); #endif irp->IoStatus = 0; irp->Complete(irp); }
static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) { int i; LONG status; SCARDCONTEXT hContext; DWORD dwTimeout = 0; DWORD readerCount = 0; SCARD_READERSTATE *readerStates, *cur; stream_seek(irp->input, 0x18); stream_read_UINT32(irp->input, dwTimeout); stream_read_UINT32(irp->input, readerCount); stream_seek(irp->input, 8); stream_read_UINT32(irp->input, hContext); stream_seek(irp->input, 4); DEBUG_SCARD("context: 0x%08x, timeout: 0x%08x, count: %d", (unsigned) hContext, (unsigned) dwTimeout, (int) readerCount); if (readerCount > 0) { readerStates = malloc(readerCount * sizeof(SCARD_READERSTATE)); ZeroMemory(readerStates, readerCount * sizeof(SCARD_READERSTATE)); if (!readerStates) return smartcard_output_return(irp, SCARD_E_NO_MEMORY); for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; stream_seek(irp->input, 4); /* * TODO: on-wire is little endian; need to either * convert to host endian or fix the headers to * request the order we want */ stream_read_UINT32(irp->input, cur->dwCurrentState); stream_read_UINT32(irp->input, cur->dwEventState); stream_read_UINT32(irp->input, cur->cbAtr); stream_read(irp->input, cur->rgbAtr, 32); stream_seek(irp->input, 4); /* reset high bytes? */ cur->dwCurrentState &= 0x0000FFFF; cur->dwEventState = 0; } for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; UINT32 dataLength; stream_seek(irp->input, 8); stream_read_UINT32(irp->input, dataLength); smartcard_input_repos(irp, smartcard_input_string(irp, (char **) &cur->szReader, dataLength, wide)); DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x", (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, (unsigned) cur->dwEventState); if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0) cur->dwCurrentState |= SCARD_STATE_IGNORE; } } else { readerStates = NULL; } status = SCardGetStatusChange(hContext, (DWORD) dwTimeout, readerStates, (DWORD) readerCount); if (status != SCARD_S_SUCCESS) DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); else DEBUG_SCARD("Success"); stream_write_UINT32(irp->output, readerCount); stream_write_UINT32(irp->output, 0x00084dd8); stream_write_UINT32(irp->output, readerCount); for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x", (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, (unsigned) cur->dwEventState); /* TODO: do byte conversions if necessary */ stream_write_UINT32(irp->output, cur->dwCurrentState); stream_write_UINT32(irp->output, cur->dwEventState); stream_write_UINT32(irp->output, cur->cbAtr); stream_write(irp->output, cur->rgbAtr, 32); stream_write_zero(irp->output, 4); free((void *)cur->szReader); } smartcard_output_alignment(irp, 8); free(readerStates); return status; }
static void drive_process_irp_device_control(DRIVE_DEVICE* disk, IRP* irp) { stream_write_UINT32(irp->output, 0); /* OutputBufferLength */ irp->Complete(irp); }
static UINT32 handle_GetAttrib(IRP* irp) { LONG status; SCARDHANDLE hCard; DWORD dwAttrId = 0; DWORD dwAttrLen = 0; DWORD attrLen = 0; BYTE* pbAttr = NULL; stream_seek(irp->input, 0x20); stream_read_UINT32(irp->input, dwAttrId); stream_seek(irp->input, 0x4); stream_read_UINT32(irp->input, dwAttrLen); stream_seek(irp->input, 0xC); stream_read_UINT32(irp->input, hCard); DEBUG_SCARD("hcard: 0x%08x, attrib: 0x%08x (%d bytes)", (unsigned) hCard, (unsigned) dwAttrId, (int) dwAttrLen); #ifdef SCARD_AUTOALLOCATE if (dwAttrLen == 0) { attrLen = 0; } else { attrLen = SCARD_AUTOALLOCATE; } #endif status = SCardGetAttrib(hCard, dwAttrId, attrLen == 0 ? NULL : (BYTE*) &pbAttr, &attrLen); if (status != SCARD_S_SUCCESS) { #ifdef SCARD_AUTOALLOCATE if (dwAttrLen == 0) attrLen = 0; else attrLen = SCARD_AUTOALLOCATE; #endif } if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A && status == SCARD_E_UNSUPPORTED_FEATURE) { status = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W, attrLen == 0 ? NULL : (BYTE*) &pbAttr, &attrLen); if (status != SCARD_S_SUCCESS) { #ifdef SCARD_AUTOALLOCATE if (dwAttrLen == 0) attrLen = 0; else attrLen = SCARD_AUTOALLOCATE; #endif } } if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W && status == SCARD_E_UNSUPPORTED_FEATURE) { status = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A, attrLen == 0 ? NULL : (BYTE*) &pbAttr, &attrLen); if (status != SCARD_S_SUCCESS) { #ifdef SCARD_AUTOALLOCATE if (dwAttrLen == 0) attrLen = 0; else attrLen = SCARD_AUTOALLOCATE; #endif } } if (attrLen > dwAttrLen && pbAttr != NULL) { status = SCARD_E_INSUFFICIENT_BUFFER; } dwAttrLen = attrLen; if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned int) status); free(pbAttr); return smartcard_output_return(irp, status); } else { DEBUG_SCARD("Success (%d bytes)", (int) dwAttrLen); stream_write_UINT32(irp->output, dwAttrLen); stream_write_UINT32(irp->output, 0x00000200); stream_write_UINT32(irp->output, dwAttrLen); if (!pbAttr) { stream_write_zero(irp->output, dwAttrLen); } else { stream_write(irp->output, pbAttr, dwAttrLen); } smartcard_output_repos(irp, dwAttrLen); /* align to multiple of 4 */ stream_write_UINT32(irp->output, 0); } smartcard_output_alignment(irp, 8); free(pbAttr); return status; }
void rts_ping_traffic_sent_notify_command_write(STREAM* s, UINT32 PingTrafficSent) { stream_write_UINT32(s, RTS_CMD_PING_TRAFFIC_SENT_NOTIFY); /* CommandType (4 bytes) */ stream_write_UINT32(s, PingTrafficSent); /* PingTrafficSent (4 bytes) */ }
void gcc_write_client_core_data(STREAM* s, rdpSettings* settings) { UINT32 version; WCHAR* clientName; int clientNameLength; BYTE connectionType; UINT16 highColorDepth; UINT16 supportedColorDepths; UINT16 earlyCapabilityFlags; WCHAR* clientDigProductId; int clientDigProductIdLength; gcc_write_user_data_header(s, CS_CORE, 216); version = settings->RdpVersion >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; clientNameLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientHostname, -1, &clientName, 0); clientDigProductIdLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientProductId, -1, &clientDigProductId, 0); stream_write_UINT32(s, version); /* Version */ stream_write_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ stream_write_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ stream_write_UINT16(s, RNS_UD_COLOR_8BPP); /* ColorDepth, ignored because of postBeta2ColorDepth */ stream_write_UINT16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ stream_write_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ stream_write_UINT32(s, settings->ClientBuild); /* ClientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ if (clientNameLength >= 16) { clientNameLength = 16; clientName[clientNameLength-1] = 0; } stream_write(s, clientName, (clientNameLength * 2)); stream_write_zero(s, 32 - (clientNameLength * 2)); free(clientName); stream_write_UINT32(s, settings->KeyboardType); /* KeyboardType */ stream_write_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ stream_write_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ stream_write_zero(s, 64); /* imeFileName */ stream_write_UINT16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ stream_write_UINT16(s, 1); /* clientProductID */ stream_write_UINT32(s, 0); /* serialNumber (should be initialized to 0) */ highColorDepth = MIN(settings->ColorDepth, 24); supportedColorDepths = RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT; connectionType = settings->ConnectionType; earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU; if (settings->RemoteFxCodec) connectionType = CONNECTION_TYPE_LAN; if (connectionType != 0) earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; if (settings->ColorDepth == 32) { supportedColorDepths |= RNS_UD_32BPP_SUPPORT; earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; } stream_write_UINT16(s, highColorDepth); /* highColorDepth */ stream_write_UINT16(s, supportedColorDepths); /* supportedColorDepths */ stream_write_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ /* clientDigProductId (64 bytes, null-terminated unicode, truncated to 31 characters) */ if (clientDigProductIdLength >= 32) { clientDigProductIdLength = 32; clientDigProductId[clientDigProductIdLength-1] = 0; } stream_write(s, clientDigProductId, (clientDigProductIdLength * 2) ); stream_write_zero(s, 64 - (clientDigProductIdLength * 2) ); free(clientDigProductId); stream_write_BYTE(s, connectionType); /* connectionType */ stream_write_BYTE(s, 0); /* pad1octet */ stream_write_UINT32(s, settings->SelectedProtocol); /* serverSelectedProtocol */ }
void rts_association_group_id_command_write(STREAM* s, BYTE* associationGroupId) { stream_write_UINT32(s, RTS_CMD_ASSOCIATION_GROUP_ID); /* CommandType (4 bytes) */ stream_write(s, associationGroupId, 16); /* AssociationGroupId (16 bytes) */ }
void rts_destination_command_write(STREAM* s, UINT32 Destination) { stream_write_UINT32(s, RTS_CMD_DESTINATION); /* CommandType (4 bytes) */ stream_write_UINT32(s, Destination); /* Destination (4 bytes) */ }
void rts_ance_command_write(STREAM* s) { stream_write_UINT32(s, RTS_CMD_ANCE); /* CommandType (4 bytes) */ }
void rts_negative_ance_command_write(STREAM* s) { stream_write_UINT32(s, RTS_CMD_NEGATIVE_ANCE); /* CommandType (4 bytes) */ }
void rts_padding_command_write(STREAM* s, UINT32 ConformanceCount) { stream_write_UINT32(s, ConformanceCount); /* ConformanceCount (4 bytes) */ stream_write_zero(s, ConformanceCount); /* Padding (variable) */ }
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); }
void gcc_write_server_security_data(STREAM* s, rdpSettings* settings) { CryptoMd5 md5; BYTE* sigData; int expLen, keyLen, sigDataLen; BYTE encryptedSignature[TSSK_KEY_LENGTH]; BYTE signature[sizeof(initial_signature)]; UINT32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; if (!settings->DisableEncryption) { settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT; } if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; headerLen = 12; keyLen = 0; wPublicKeyBlobLen = 0; serverRandomLen = 0; serverCertLen = 0; if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE || settings->EncryptionLevel != ENCRYPTION_LEVEL_NONE) { serverRandomLen = 32; keyLen = settings->RdpServerRsaKey->ModulusLength; expLen = sizeof(settings->RdpServerRsaKey->exponent); wPublicKeyBlobLen = 4; /* magic (RSA1) */ wPublicKeyBlobLen += 4; /* keylen */ wPublicKeyBlobLen += 4; /* bitlen */ wPublicKeyBlobLen += 4; /* datalen */ wPublicKeyBlobLen += expLen; wPublicKeyBlobLen += keyLen; wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */ serverCertLen = 4; /* dwVersion */ serverCertLen += 4; /* dwSigAlgId */ serverCertLen += 4; /* dwKeyAlgId */ serverCertLen += 2; /* wPublicKeyBlobType */ serverCertLen += 2; /* wPublicKeyBlobLen */ serverCertLen += wPublicKeyBlobLen; serverCertLen += 2; /* wSignatureBlobType */ serverCertLen += 2; /* wSignatureBlobLen */ serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */ serverCertLen += 8; /* 8 bytes of zero padding */ headerLen += sizeof(serverRandomLen); headerLen += sizeof(serverCertLen); headerLen += serverRandomLen; headerLen += serverCertLen; } gcc_write_user_data_header(s, SC_SECURITY, headerLen); stream_write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ stream_write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE && settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE) { return; } stream_write_UINT32(s, serverRandomLen); /* serverRandomLen */ stream_write_UINT32(s, serverCertLen); /* serverCertLen */ settings->ServerRandomLength = serverRandomLen; settings->ServerRandom = (BYTE*) malloc(serverRandomLen); crypto_nonce(settings->ServerRandom, serverRandomLen); stream_write(s, settings->ServerRandom, serverRandomLen); sigData = stream_get_tail(s); stream_write_UINT32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ stream_write_UINT32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ stream_write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ stream_write_UINT16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ stream_write_UINT16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ stream_write(s, "RSA1", 4); /* magic */ stream_write_UINT32(s, keyLen + 8); /* keylen */ stream_write_UINT32(s, keyLen * 8); /* bitlen */ stream_write_UINT32(s, keyLen - 1); /* datalen */ stream_write(s, settings->RdpServerRsaKey->exponent, expLen); stream_write(s, settings->RdpServerRsaKey->Modulus, keyLen); stream_write_zero(s, 8); sigDataLen = stream_get_tail(s) - sigData; stream_write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ stream_write_UINT16(s, keyLen + 8); /* wSignatureBlobLen */ memcpy(signature, initial_signature, sizeof(initial_signature)); md5 = crypto_md5_init(); crypto_md5_update(md5, sigData, sigDataLen); crypto_md5_final(md5, signature); crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, tssk_modulus, tssk_privateExponent, encryptedSignature); stream_write(s, encryptedSignature, sizeof(encryptedSignature)); stream_write_zero(s, 8); }
static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP* irp) { UINT32 FsInformationClass; STREAM* 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 */ stream_write_UINT32(output, svfst.f_fsid); /* VolumeSerialNumber */ 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 */ stream_write_UINT32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */ 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); }
static void parallel_process_irp_device_control(PARALLEL_DEVICE* parallel, IRP* irp) { DEBUG_SVC("in"); stream_write_UINT32(irp->output, 0); /* OutputBufferLength */ irp->Complete(irp); }
BOOL nego_send_negotiation_response(rdpNego* nego) { STREAM* s; BYTE* bm; BYTE* em; int length; BOOL status; rdpSettings* settings; status = TRUE; settings = nego->transport->settings; s = transport_send_stream_init(nego->transport, 256); length = TPDU_CONNECTION_CONFIRM_LENGTH; stream_get_mark(s, bm); stream_seek(s, length); if (nego->selected_protocol > PROTOCOL_RDP) { /* RDP_NEG_DATA must be present for TLS and NLA */ stream_write_BYTE(s, TYPE_RDP_NEG_RSP); stream_write_BYTE(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ stream_write_UINT32(s, nego->selected_protocol); /* selectedProtocol */ length += 8; } else if (!settings->RdpSecurity) { stream_write_BYTE(s, TYPE_RDP_NEG_FAILURE); stream_write_BYTE(s, 0); /* flags */ stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ /* * TODO: Check for other possibilities, * like SSL_NOT_ALLOWED_BY_SERVER. */ printf("nego_send_negotiation_response: client supports only Standard RDP Security\n"); stream_write_UINT32(s, SSL_REQUIRED_BY_SERVER); length += 8; status = FALSE; } stream_get_mark(s, em); stream_set_mark(s, bm); tpkt_write_header(s, length); tpdu_write_connection_confirm(s, length - 5); stream_set_mark(s, em); if (transport_write(nego->transport, s) < 0) return FALSE; if (status) { /* update settings with negotiated protocol security */ settings->RequestedProtocols = nego->requested_protocols; settings->SelectedProtocol = nego->selected_protocol; if (settings->SelectedProtocol == PROTOCOL_RDP) { settings->TlsSecurity = FALSE; settings->NlaSecurity = FALSE; settings->RdpSecurity = TRUE; if (!settings->LocalConnection) { settings->DisableEncryption = TRUE; settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } if (settings->DisableEncryption && settings->RdpServerRsaKey == NULL && settings->RdpKeyFile == NULL) return FALSE; } else if (settings->SelectedProtocol == PROTOCOL_TLS) { settings->TlsSecurity = TRUE; settings->NlaSecurity = FALSE; settings->RdpSecurity = FALSE; settings->DisableEncryption = FALSE; settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } else if (settings->SelectedProtocol == PROTOCOL_NLA) { settings->TlsSecurity = TRUE; settings->NlaSecurity = TRUE; settings->RdpSecurity = FALSE; settings->DisableEncryption = FALSE; settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } } return status; }
void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* printer) { char* port; UINT32 Flags; int DriverNameLen; WCHAR* DriverName = NULL; int PrintNameLen; WCHAR* PrintName = NULL; UINT32 CachedFieldsLen; BYTE* CachedPrinterConfigData; PRINTER_DEVICE* printer_dev; port = malloc(10); snprintf(port, 10, "PRN%d", printer->id); printer_dev = (PRINTER_DEVICE*) malloc(sizeof(PRINTER_DEVICE)); ZeroMemory(printer_dev, sizeof(PRINTER_DEVICE)); printer_dev->device.type = RDPDR_DTYP_PRINT; printer_dev->device.name = port; printer_dev->device.IRPRequest = printer_irp_request; printer_dev->device.Free = printer_free; printer_dev->printer = printer; CachedFieldsLen = 0; CachedPrinterConfigData = NULL; DEBUG_SVC("Printer %s registered", printer->name); Flags = 0; if (printer->is_default) Flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER; DriverNameLen = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &DriverName, 0) * 2; PrintNameLen = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &PrintName, 0) * 2; printer_dev->device.data = stream_new(28 + DriverNameLen + PrintNameLen + CachedFieldsLen); stream_write_UINT32(printer_dev->device.data, Flags); stream_write_UINT32(printer_dev->device.data, 0); /* CodePage, reserved */ stream_write_UINT32(printer_dev->device.data, 0); /* PnPNameLen */ stream_write_UINT32(printer_dev->device.data, DriverNameLen + 2); stream_write_UINT32(printer_dev->device.data, PrintNameLen + 2); stream_write_UINT32(printer_dev->device.data, CachedFieldsLen); stream_write(printer_dev->device.data, DriverName, DriverNameLen); stream_write_UINT16(printer_dev->device.data, 0); stream_write(printer_dev->device.data, PrintName, PrintNameLen); stream_write_UINT16(printer_dev->device.data, 0); if (CachedFieldsLen > 0) { stream_write(printer_dev->device.data, CachedPrinterConfigData, CachedFieldsLen); } free(DriverName); free(PrintName); printer_dev->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); InitializeSListHead(printer_dev->pIrpList); printer_dev->thread = freerdp_thread_new(); pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) printer_dev); freerdp_thread_start(printer_dev->thread, printer_thread_func, printer_dev); }
static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) { LONG status; int i, j, k; SCARDCONTEXT hContext; UINT32 atrMaskCount = 0; UINT32 readerCount = 0; SCARD_READERSTATE* cur = NULL; SCARD_READERSTATE* rsCur = NULL; SCARD_READERSTATE* readerStates = NULL; SERVER_SCARD_ATRMASK* curAtr = NULL; SERVER_SCARD_ATRMASK* pAtrMasks = NULL; stream_seek(irp->input, 0x2C); stream_read_UINT32(irp->input, hContext); stream_read_UINT32(irp->input, atrMaskCount); pAtrMasks = malloc(atrMaskCount * sizeof(SERVER_SCARD_ATRMASK)); if (!pAtrMasks) return smartcard_output_return(irp, SCARD_E_NO_MEMORY); for (i = 0; i < atrMaskCount; i++) { stream_read_UINT32(irp->input, pAtrMasks[i].cbAtr); stream_read(irp->input, pAtrMasks[i].rgbAtr, 36); stream_read(irp->input, pAtrMasks[i].rgbMask, 36); } stream_read_UINT32(irp->input, readerCount); readerStates = malloc(readerCount * sizeof(SCARD_READERSTATE)); ZeroMemory(readerStates, readerCount * sizeof(SCARD_READERSTATE)); if (!readerStates) return smartcard_output_return(irp, SCARD_E_NO_MEMORY); for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; stream_seek(irp->input, 4); /* * TODO: on-wire is little endian; need to either * convert to host endian or fix the headers to * request the order we want */ stream_read_UINT32(irp->input, cur->dwCurrentState); stream_read_UINT32(irp->input, cur->dwEventState); stream_read_UINT32(irp->input, cur->cbAtr); stream_read(irp->input, cur->rgbAtr, 32); stream_seek(irp->input, 4); /* reset high bytes? */ cur->dwCurrentState &= 0x0000FFFF; cur->dwEventState &= 0x0000FFFF; cur->dwEventState = 0; } for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; UINT32 dataLength; stream_seek(irp->input, 8); stream_read_UINT32(irp->input, dataLength); smartcard_input_repos(irp, smartcard_input_string(irp, (char **) &cur->szReader, dataLength, wide)); DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x", (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, (unsigned) cur->dwEventState); if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0) cur->dwCurrentState |= SCARD_STATE_IGNORE; } status = SCardGetStatusChange(hContext, 0x00000001, readerStates, readerCount); if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); return smartcard_output_return(irp, status); } DEBUG_SCARD("Success"); for (i = 0, curAtr = pAtrMasks; i < atrMaskCount; i++, curAtr++) { for (j = 0, rsCur = readerStates; j < readerCount; j++, rsCur++) { BOOL equal = 1; for (k = 0; k < cur->cbAtr; k++) { if ((curAtr->rgbAtr[k] & curAtr->rgbMask[k]) != (rsCur->rgbAtr[k] & curAtr->rgbMask[k])) { equal = 0; break; } } if (equal) { rsCur->dwEventState |= 0x00000040; /* SCARD_STATE_ATRMATCH 0x00000040 */ } } } stream_write_UINT32(irp->output, readerCount); stream_write_UINT32(irp->output, 0x00084dd8); stream_write_UINT32(irp->output, readerCount); for (i = 0, rsCur = readerStates; i < readerCount; i++, rsCur++) { stream_write_UINT32(irp->output, cur->dwCurrentState); stream_write_UINT32(irp->output, cur->dwEventState); stream_write_UINT32(irp->output, cur->cbAtr); stream_write(irp->output, cur->rgbAtr, 32); stream_write_zero(irp->output, 4); free((void*) cur->szReader); } smartcard_output_alignment(irp, 8); free(readerStates); return status; }
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL user_loggedon) { int i; int pos; BYTE c; UINT32 count; int data_len; int count_pos; STREAM* data_out; DEVICE* device; LIST_ITEM* item; data_out = stream_new(256); stream_write_UINT16(data_out, RDPDR_CTYP_CORE); stream_write_UINT16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE); count_pos = stream_get_pos(data_out); count = 0; stream_seek_UINT32(data_out); /* deviceCount */ for (item = rdpdr->devman->devices->head; item; item = item->next) { device = (DEVICE*) item->data; /** * 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON * so all devices should be sent regardless of user_loggedon * 2. smartcard devices should be always sent * 3. other devices are sent only after user_loggedon */ if ((rdpdr->versionMinor == 0x0005) || (device->type == RDPDR_DTYP_SMARTCARD) || user_loggedon) { data_len = (device->data == NULL ? 0 : stream_get_length(device->data)); stream_check_size(data_out, 20 + data_len); stream_write_UINT32(data_out, device->type); /* deviceType */ stream_write_UINT32(data_out, device->id); /* deviceID */ strncpy((char*) stream_get_tail(data_out), device->name, 8); for (i = 0; i < 8; i++) { stream_peek_BYTE(data_out, c); if (c > 0x7F) stream_write_BYTE(data_out, '_'); else stream_seek_BYTE(data_out); } stream_write_UINT32(data_out, data_len); if (data_len > 0) stream_write(data_out, stream_get_data(device->data), data_len); count++; printf("registered device #%d: %s (type=%d id=%d)\n", count, device->name, device->type, device->id); } } pos = stream_get_pos(data_out); stream_set_pos(data_out, count_pos); stream_write_UINT32(data_out, count); stream_set_pos(data_out, pos); stream_seal(data_out); svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out); }
static UINT32 handle_ListReaders(IRP* irp, BOOL wide) { UINT32 len, status; SCARDCONTEXT hContext; DWORD dwReaders; char *readerList = NULL, *walker; int elemLength, dataLength; int pos, poslen1, poslen2; stream_seek(irp->input, 8); stream_read_UINT32(irp->input, len); stream_seek(irp->input, 0x1c); stream_read_UINT32(irp->input, len); if (len != 4) return SCARD_F_INTERNAL_ERROR; stream_read_UINT32(irp->input, hContext); /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ status = SCARD_S_SUCCESS; #ifdef SCARD_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; status = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders); #else status = SCardListReaders(hContext, NULL, NULL, &dwReaders); readerList = malloc(dwReaders); status = SCardListReaders(hContext, NULL, readerList, &dwReaders); #endif if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); return status; } /* DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/ poslen1 = stream_get_pos(irp->output); stream_seek_UINT32(irp->output); stream_write_UINT32(irp->output, 0x01760650); poslen2 = stream_get_pos(irp->output); stream_seek_UINT32(irp->output); walker = readerList; dataLength = 0; while (1) { elemLength = strlen(walker); if (elemLength == 0) break; dataLength += smartcard_output_string(irp, walker, wide); walker += elemLength + 1; elemLength = strlen(walker); } dataLength += smartcard_output_string(irp, "\0", wide); pos = stream_get_pos(irp->output); stream_set_pos(irp->output, poslen1); stream_write_UINT32(irp->output, dataLength); stream_set_pos(irp->output, poslen2); stream_write_UINT32(irp->output, dataLength); stream_set_pos(irp->output, pos); smartcard_output_repos(irp, dataLength); smartcard_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE SCardFreeMemory(hContext, readerList); #else free(readerList); #endif return status; }
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery, const char* path, STREAM* output) { int length; BOOL ret; WCHAR* ent_path; struct STAT st; struct dirent* ent; DEBUG_SVC("path %s FsInformationClass %d InitialQuery %d", path, FsInformationClass, InitialQuery); if (!file->dir) { stream_write_UINT32(output, 0); /* Length */ stream_write_BYTE(output, 0); /* Padding */ return FALSE; } if (InitialQuery != 0) { rewinddir(file->dir); free(file->pattern); if (path[0]) file->pattern = _strdup(strrchr(path, '\\') + 1); else file->pattern = NULL; } if (file->pattern) { do { ent = readdir(file->dir); if (ent == NULL) continue; if (FilePatternMatchA(ent->d_name, file->pattern)) break; } while (ent); } else { ent = readdir(file->dir); } if (ent == NULL) { DEBUG_SVC(" pattern %s not found.", file->pattern); stream_write_UINT32(output, 0); /* Length */ stream_write_BYTE(output, 0); /* Padding */ return FALSE; } memset(&st, 0, sizeof(struct STAT)); ent_path = (WCHAR*) malloc(strlen(file->fullpath) + strlen(ent->d_name) + 2); sprintf((char*) ent_path, "%s/%s", file->fullpath, ent->d_name); if (STAT((char*) ent_path, &st) != 0) { DEBUG_WARN("stat %s failed. errno = %d", (char*) ent_path, errno); } DEBUG_SVC(" pattern %s matched %s", file->pattern, ent_path); free(ent_path); ent_path = NULL; length = ConvertToUnicode(CP_UTF8, 0, ent->d_name, -1, &ent_path, 0) * 2; ret = TRUE; switch (FsInformationClass) { case FileDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232097.aspx */ stream_write_UINT32(output, 64 + length); /* Length */ stream_check_size(output, 64 + length); stream_write_UINT32(output, 0); /* NextEntryOffset */ stream_write_UINT32(output, 0); /* FileIndex */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_UINT64(output, st.st_size); /* EndOfFile */ stream_write_UINT64(output, st.st_size); /* AllocationSize */ stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_UINT32(output, length); /* FileNameLength */ stream_write(output, ent_path, length); break; case FileFullDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232068.aspx */ stream_write_UINT32(output, 68 + length); /* Length */ stream_check_size(output, 68 + length); stream_write_UINT32(output, 0); /* NextEntryOffset */ stream_write_UINT32(output, 0); /* FileIndex */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_UINT64(output, st.st_size); /* EndOfFile */ stream_write_UINT64(output, st.st_size); /* AllocationSize */ stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_UINT32(output, length); /* FileNameLength */ stream_write_UINT32(output, 0); /* EaSize */ stream_write(output, ent_path, length); break; case FileBothDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232095.aspx */ stream_write_UINT32(output, 93 + length); /* Length */ stream_check_size(output, 93 + length); stream_write_UINT32(output, 0); /* NextEntryOffset */ stream_write_UINT32(output, 0); /* FileIndex */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_UINT64(output, st.st_size); /* EndOfFile */ stream_write_UINT64(output, st.st_size); /* AllocationSize */ stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_UINT32(output, length); /* FileNameLength */ stream_write_UINT32(output, 0); /* EaSize */ stream_write_BYTE(output, 0); /* ShortNameLength */ /* Reserved(1), MUST NOT be added! */ stream_write_zero(output, 24); /* ShortName */ stream_write(output, ent_path, length); break; case FileNamesInformation: /* http://msdn.microsoft.com/en-us/library/cc232077.aspx */ stream_write_UINT32(output, 12 + length); /* Length */ stream_check_size(output, 12 + length); stream_write_UINT32(output, 0); /* NextEntryOffset */ stream_write_UINT32(output, 0); /* FileIndex */ stream_write_UINT32(output, length); /* FileNameLength */ stream_write(output, ent_path, length); break; default: stream_write_UINT32(output, 0); /* Length */ stream_write_BYTE(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = FALSE; break; } free(ent_path); return ret; }
static UINT32 handle_State(IRP* irp) { LONG status; SCARDHANDLE hCard; DWORD state = 0, protocol = 0; DWORD readerLen; DWORD atrLen = MAX_ATR_SIZE; char* readerName; BYTE pbAtr[MAX_ATR_SIZE]; #ifdef WITH_DEBUG_SCARD int i; #endif stream_seek(irp->input, 0x24); stream_seek_UINT32(irp->input); /* atrLen */ stream_seek(irp->input, 0x0c); stream_read_UINT32(irp->input, hCard); stream_seek(irp->input, 0x04); #ifdef SCARD_AUTOALLOCATE readerLen = SCARD_AUTOALLOCATE; status = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #else readerLen = 256; readerName = malloc(readerLen); status = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #endif if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); return smartcard_output_return(irp, status); } DEBUG_SCARD("Success (hcard: 0x%08x len: %d state: 0x%08x, proto: 0x%08x)", (unsigned) hCard, (int) atrLen, (unsigned) state, (unsigned) protocol); #ifdef WITH_DEBUG_SCARD printf(" ATR: "); for (i = 0; i < atrLen; i++) printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':'); printf("\n"); #endif state = smartcard_map_state(state); stream_write_UINT32(irp->output, state); stream_write_UINT32(irp->output, protocol); stream_write_UINT32(irp->output, atrLen); stream_write_UINT32(irp->output, 0x00000001); stream_write_UINT32(irp->output, atrLen); stream_write(irp->output, pbAtr, atrLen); smartcard_output_repos(irp, atrLen); smartcard_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE free(readerName); #else free(readerName); #endif return status; }
void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings) { UINT32 bias; INT32 sbias; UINT32 bias2c; WCHAR* standardName; WCHAR* daylightName; int standardNameLength; int daylightNameLength; TIME_ZONE_INFO* clientTimeZone; clientTimeZone = settings->ClientTimeZone; freerdp_time_zone_detect(clientTimeZone); standardNameLength = ConvertToUnicode(CP_UTF8, 0, clientTimeZone->standardName, -1, &standardName, 0) * 2; daylightNameLength = ConvertToUnicode(CP_UTF8, 0, clientTimeZone->daylightName, -1, &daylightName, 0) * 2; if (standardNameLength > 62) standardNameLength = 62; if (daylightNameLength > 62) daylightNameLength = 62; /* UTC = LocalTime + Bias <-> Bias = UTC - LocalTime */ /* Translate from biases used throughout libfreerdp-locale/timezone.c * to what RDP expects, which is minutes *west* of UTC. * Though MS-RDPBCGR specifies bias as unsigned, two's complement * (a negative integer) works fine for zones east of UTC. */ if (clientTimeZone->bias <= 720) bias = -1 * clientTimeZone->bias; else bias = 1440 - clientTimeZone->bias; stream_write_UINT32(s, bias); /* Bias */ /* standardName (64 bytes) */ stream_write(s, standardName, standardNameLength); stream_write_zero(s, 64 - standardNameLength); rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */ DEBUG_TIMEZONE("bias=%d stdName='%s' dlName='%s'", bias, clientTimeZone->standardName, clientTimeZone->daylightName); sbias = clientTimeZone->standardBias - clientTimeZone->bias; if (sbias < 0) bias2c = (UINT32) sbias; else bias2c = ~((UINT32) sbias) + 1; /* Note that StandardBias is ignored if no valid standardDate is provided. */ stream_write_UINT32(s, bias2c); /* StandardBias */ DEBUG_TIMEZONE("StandardBias=%d", bias2c); /* daylightName (64 bytes) */ stream_write(s, daylightName, daylightNameLength); stream_write_zero(s, 64 - daylightNameLength); rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */ sbias = clientTimeZone->daylightBias - clientTimeZone->bias; if (sbias < 0) bias2c = (UINT32) sbias; else bias2c = ~((UINT32) sbias) + 1; /* Note that DaylightBias is ignored if no valid daylightDate is provided. */ stream_write_UINT32(s, bias2c); /* DaylightBias */ DEBUG_TIMEZONE("DaylightBias=%d", bias2c); free(standardName); free(daylightName); }
static UINT32 handle_Transmit(IRP* irp) { LONG status; SCARDCONTEXT hCard; UINT32 map[7], linkedLen; SCARD_IO_REQUEST pioSendPci, pioRecvPci, *pPioRecvPci; DWORD cbSendLength = 0, cbRecvLength = 0; BYTE *sendBuf = NULL, *recvBuf = NULL; stream_seek(irp->input, 0x14); stream_read_UINT32(irp->input, map[0]); stream_seek(irp->input, 0x4); stream_read_UINT32(irp->input, map[1]); stream_read_UINT32(irp->input, pioSendPci.dwProtocol); stream_read_UINT32(irp->input, pioSendPci.cbPciLength); stream_read_UINT32(irp->input, map[2]); stream_read_UINT32(irp->input, cbSendLength); stream_read_UINT32(irp->input, map[3]); stream_read_UINT32(irp->input, map[4]); stream_read_UINT32(irp->input, map[5]); stream_read_UINT32(irp->input, cbRecvLength); if (map[0] & SCARD_INPUT_LINKED) smartcard_input_skip_linked(irp); stream_seek(irp->input, 4); stream_read_UINT32(irp->input, hCard); if (map[2] & SCARD_INPUT_LINKED) { /* sendPci */ stream_read_UINT32(irp->input, linkedLen); stream_read_UINT32(irp->input, pioSendPci.dwProtocol); stream_seek(irp->input, linkedLen - 4); smartcard_input_repos(irp, linkedLen); } pioSendPci.cbPciLength = sizeof(SCARD_IO_REQUEST); if (map[3] & SCARD_INPUT_LINKED) { /* send buffer */ stream_read_UINT32(irp->input, linkedLen); sendBuf = malloc(linkedLen); stream_read(irp->input, sendBuf, linkedLen); smartcard_input_repos(irp, linkedLen); } if (cbRecvLength) recvBuf = malloc(cbRecvLength); if (map[4] & SCARD_INPUT_LINKED) { /* recvPci */ stream_read_UINT32(irp->input, linkedLen); stream_read_UINT32(irp->input, pioRecvPci.dwProtocol); stream_seek(irp->input, linkedLen - 4); smartcard_input_repos(irp, linkedLen); stream_read_UINT32(irp->input, map[6]); if (map[6] & SCARD_INPUT_LINKED) { /* not sure what this is */ stream_read_UINT32(irp->input, linkedLen); stream_seek(irp->input, linkedLen); smartcard_input_repos(irp, linkedLen); } pioRecvPci.cbPciLength = sizeof(SCARD_IO_REQUEST); pPioRecvPci = &pioRecvPci; } else { pPioRecvPci = NULL; } pPioRecvPci = NULL; DEBUG_SCARD("SCardTransmit(hcard: 0x%08lx, send: %d bytes, recv: %d bytes)", (long unsigned) hCard, (int) cbSendLength, (int) cbRecvLength); status = SCardTransmit(hCard, &pioSendPci, sendBuf, cbSendLength, pPioRecvPci, recvBuf, &cbRecvLength); if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); } else { DEBUG_SCARD("Success (%d bytes)", (int) cbRecvLength); stream_write_UINT32(irp->output, 0); /* pioRecvPci 0x00; */ smartcard_output_buffer_start(irp, cbRecvLength); /* start of recvBuf output */ smartcard_output_buffer(irp, (char*) recvBuf, cbRecvLength); } smartcard_output_alignment(irp, 8); free(sendBuf); free(recvBuf); return status; }
static void audin_server_send_version(audin_server* audin, STREAM* s) { stream_write_BYTE(s, MSG_SNDIN_VERSION); stream_write_UINT32(s, 1); /* Version (4 bytes) */ WTSVirtualChannelWrite(audin->audin_channel, stream_get_head(s), stream_get_length(s), NULL); }
static void rfx_compose_message_tileset(RFX_CONTEXT* context, STREAM* s, BYTE* image_data, int width, int height, int rowstride) { int i; int size; int start_pos, end_pos; int numQuants; const UINT32* quantVals; const UINT32* quantValsPtr; int quantIdxY; int quantIdxCb; int quantIdxCr; int numTiles; int numTilesX; int numTilesY; int xIdx; int yIdx; int tilesDataSize; if (context->num_quants == 0) { numQuants = 1; quantVals = rfx_default_quantization_values; quantIdxY = 0; quantIdxCb = 0; quantIdxCr = 0; } else { numQuants = context->num_quants; quantVals = context->quants; quantIdxY = context->quant_idx_y; quantIdxCb = context->quant_idx_cb; quantIdxCr = context->quant_idx_cr; } numTilesX = (width + 63) / 64; numTilesY = (height + 63) / 64; numTiles = numTilesX * numTilesY; size = 22 + numQuants * 5; stream_check_size(s, size); start_pos = stream_get_pos(s); stream_write_UINT16(s, WBT_EXTENSION); /* CodecChannelT.blockType */ stream_seek_UINT32(s); /* set CodecChannelT.blockLen later */ stream_write_BYTE(s, 1); /* CodecChannelT.codecId */ stream_write_BYTE(s, 0); /* CodecChannelT.channelId */ stream_write_UINT16(s, CBT_TILESET); /* subtype */ stream_write_UINT16(s, 0); /* idx */ stream_write_UINT16(s, context->properties); /* properties */ stream_write_BYTE(s, numQuants); /* numQuants */ stream_write_BYTE(s, 0x40); /* tileSize */ stream_write_UINT16(s, numTiles); /* numTiles */ stream_seek_UINT32(s); /* set tilesDataSize later */ quantValsPtr = quantVals; for (i = 0; i < numQuants * 5; i++) { stream_write_BYTE(s, quantValsPtr[0] + (quantValsPtr[1] << 4)); quantValsPtr += 2; } DEBUG_RFX("width:%d height:%d rowstride:%d", width, height, rowstride); end_pos = stream_get_pos(s); for (yIdx = 0; yIdx < numTilesY; yIdx++) { for (xIdx = 0; xIdx < numTilesX; xIdx++) { rfx_compose_message_tile(context, s, image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel, (xIdx < numTilesX - 1) ? 64 : width - xIdx * 64, (yIdx < numTilesY - 1) ? 64 : height - yIdx * 64, rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx); } } tilesDataSize = stream_get_pos(s) - end_pos; size += tilesDataSize; end_pos = stream_get_pos(s); stream_set_pos(s, start_pos + 2); stream_write_UINT32(s, size); /* CodecChannelT.blockLen */ stream_set_pos(s, start_pos + 18); stream_write_UINT32(s, tilesDataSize); stream_set_pos(s, end_pos); }
void rts_version_command_write(STREAM* s) { stream_write_UINT32(s, RTS_CMD_VERSION); /* CommandType (4 bytes) */ stream_write_UINT32(s, 1); /* Version (4 bytes) */ }