20 #include <freerdp/config.h>
22 #include <freerdp/freerdp.h>
23 #include <freerdp/channels/log.h>
24 #include <freerdp/server/rdpecam.h>
26 #define TAG CHANNELS_TAG("rdpecam.server")
30 CAMERA_DEVICE_INITIAL,
32 } eCameraDeviceChannelState;
36 CameraDeviceServerContext context;
49 eCameraDeviceChannelState state;
54 static UINT device_server_initialize(CameraDeviceServerContext* context, BOOL externalThread)
56 UINT error = CHANNEL_RC_OK;
57 device_server* device = (device_server*)context;
63 WLog_WARN(TAG,
"Application error: Camera channel already initialized, "
64 "calling in this state is not possible!");
65 return ERROR_INVALID_STATE;
68 device->externalThread = externalThread;
73 static UINT device_server_open_channel(device_server* device)
75 CameraDeviceServerContext* context = &device->context;
76 DWORD Error = ERROR_SUCCESS;
78 DWORD BytesReturned = 0;
79 PULONG pSessionId = NULL;
85 if (WTSQuerySessionInformationA(device->context.vcm, WTS_CURRENT_SESSION, WTSSessionId,
86 (LPSTR*)&pSessionId, &BytesReturned) == FALSE)
88 WLog_ERR(TAG,
"WTSQuerySessionInformationA failed!");
89 return ERROR_INTERNAL_ERROR;
92 device->SessionId = (DWORD)*pSessionId;
93 WTSFreeMemory(pSessionId);
94 hEvent = WTSVirtualChannelManagerGetEventHandle(device->context.vcm);
96 if (WaitForSingleObject(hEvent, 1000) == WAIT_FAILED)
98 Error = GetLastError();
99 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"!", Error);
103 device->device_channel = WTSVirtualChannelOpenEx(device->SessionId, context->virtualChannelName,
104 WTS_CHANNEL_OPTION_DYNAMIC);
105 if (!device->device_channel)
107 Error = GetLastError();
108 WLog_ERR(TAG,
"WTSVirtualChannelOpenEx failed with error %" PRIu32
"!", Error);
112 channelId = WTSChannelGetIdByHandle(device->device_channel);
114 IFCALLRET(context->ChannelIdAssigned, status, context, channelId);
117 WLog_ERR(TAG,
"context->ChannelIdAssigned failed!");
118 return ERROR_INTERNAL_ERROR;
124 static UINT device_server_handle_success_response(CameraDeviceServerContext* context,
wStream* s,
128 UINT error = CHANNEL_RC_OK;
130 WINPR_ASSERT(context);
131 WINPR_ASSERT(header);
133 pdu.Header = *header;
135 IFCALLRET(context->SuccessResponse, error, context, &pdu);
137 WLog_ERR(TAG,
"context->SuccessResponse failed with error %" PRIu32
"", error);
142 static UINT device_server_recv_error_response(CameraDeviceServerContext* context,
wStream* s,
146 UINT error = CHANNEL_RC_OK;
148 WINPR_ASSERT(context);
149 WINPR_ASSERT(header);
151 pdu.Header = *header;
153 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
154 return ERROR_NO_DATA;
156 Stream_Read_UINT32(s, pdu.ErrorCode);
158 IFCALLRET(context->ErrorResponse, error, context, &pdu);
160 WLog_ERR(TAG,
"context->ErrorResponse failed with error %" PRIu32
"", error);
165 static UINT device_server_recv_stream_list_response(CameraDeviceServerContext* context,
wStream* s,
169 UINT error = CHANNEL_RC_OK;
171 WINPR_ASSERT(context);
172 WINPR_ASSERT(header);
174 pdu.Header = *header;
176 if (!Stream_CheckAndLogRequiredLength(TAG, s, 5))
177 return ERROR_NO_DATA;
179 pdu.N_Descriptions = MIN(Stream_GetRemainingLength(s) / 5, 255);
181 for (BYTE i = 0; i < pdu.N_Descriptions; ++i)
185 Stream_Read_UINT16(s, StreamDescription->FrameSourceTypes);
186 Stream_Read_UINT8(s, StreamDescription->StreamCategory);
187 Stream_Read_UINT8(s, StreamDescription->Selected);
188 Stream_Read_UINT8(s, StreamDescription->CanBeShared);
191 IFCALLRET(context->StreamListResponse, error, context, &pdu);
193 WLog_ERR(TAG,
"context->StreamListResponse failed with error %" PRIu32
"", error);
198 static UINT device_server_recv_media_type_list_response(CameraDeviceServerContext* context,
203 UINT error = CHANNEL_RC_OK;
205 WINPR_ASSERT(context);
206 WINPR_ASSERT(header);
208 pdu.Header = *header;
210 if (!Stream_CheckAndLogRequiredLength(TAG, s, 26))
211 return ERROR_NO_DATA;
213 pdu.N_Descriptions = Stream_GetRemainingLength(s) / 26;
216 if (!pdu.MediaTypeDescriptions)
218 WLog_ERR(TAG,
"Failed to allocate %zu CAM_MEDIA_TYPE_DESCRIPTION structs",
220 return ERROR_NOT_ENOUGH_MEMORY;
223 for (
size_t i = 0; i < pdu.N_Descriptions; ++i)
227 Stream_Read_UINT8(s, MediaTypeDescriptions->Format);
228 Stream_Read_UINT32(s, MediaTypeDescriptions->Width);
229 Stream_Read_UINT32(s, MediaTypeDescriptions->Height);
230 Stream_Read_UINT32(s, MediaTypeDescriptions->FrameRateNumerator);
231 Stream_Read_UINT32(s, MediaTypeDescriptions->FrameRateDenominator);
232 Stream_Read_UINT32(s, MediaTypeDescriptions->PixelAspectRatioNumerator);
233 Stream_Read_UINT32(s, MediaTypeDescriptions->PixelAspectRatioDenominator);
234 Stream_Read_UINT8(s, MediaTypeDescriptions->Flags);
237 IFCALLRET(context->MediaTypeListResponse, error, context, &pdu);
239 WLog_ERR(TAG,
"context->MediaTypeListResponse failed with error %" PRIu32
"", error);
241 free(pdu.MediaTypeDescriptions);
246 static UINT device_server_recv_current_media_type_response(CameraDeviceServerContext* context,
251 UINT error = CHANNEL_RC_OK;
253 WINPR_ASSERT(context);
254 WINPR_ASSERT(header);
256 pdu.Header = *header;
258 if (!Stream_CheckAndLogRequiredLength(TAG, s, 26))
259 return ERROR_NO_DATA;
261 Stream_Read_UINT8(s, pdu.MediaTypeDescription.Format);
262 Stream_Read_UINT32(s, pdu.MediaTypeDescription.Width);
263 Stream_Read_UINT32(s, pdu.MediaTypeDescription.Height);
264 Stream_Read_UINT32(s, pdu.MediaTypeDescription.FrameRateNumerator);
265 Stream_Read_UINT32(s, pdu.MediaTypeDescription.FrameRateDenominator);
266 Stream_Read_UINT32(s, pdu.MediaTypeDescription.PixelAspectRatioNumerator);
267 Stream_Read_UINT32(s, pdu.MediaTypeDescription.PixelAspectRatioDenominator);
268 Stream_Read_UINT8(s, pdu.MediaTypeDescription.Flags);
270 IFCALLRET(context->CurrentMediaTypeResponse, error, context, &pdu);
272 WLog_ERR(TAG,
"context->CurrentMediaTypeResponse failed with error %" PRIu32
"", error);
277 static UINT device_server_recv_sample_response(CameraDeviceServerContext* context,
wStream* s,
281 UINT error = CHANNEL_RC_OK;
283 WINPR_ASSERT(context);
284 WINPR_ASSERT(header);
286 pdu.Header = *header;
288 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
289 return ERROR_NO_DATA;
291 Stream_Read_UINT8(s, pdu.StreamIndex);
293 pdu.SampleSize = Stream_GetRemainingLength(s);
294 pdu.Sample = Stream_Pointer(s);
296 IFCALLRET(context->SampleResponse, error, context, &pdu);
298 WLog_ERR(TAG,
"context->SampleResponse failed with error %" PRIu32
"", error);
303 static UINT device_server_recv_sample_error_response(CameraDeviceServerContext* context,
wStream* s,
307 UINT error = CHANNEL_RC_OK;
309 WINPR_ASSERT(context);
310 WINPR_ASSERT(header);
312 pdu.Header = *header;
314 if (!Stream_CheckAndLogRequiredLength(TAG, s, 5))
315 return ERROR_NO_DATA;
317 Stream_Read_UINT8(s, pdu.StreamIndex);
318 Stream_Read_UINT32(s, pdu.ErrorCode);
320 IFCALLRET(context->SampleErrorResponse, error, context, &pdu);
322 WLog_ERR(TAG,
"context->SampleErrorResponse failed with error %" PRIu32
"", error);
327 static UINT device_server_recv_property_list_response(CameraDeviceServerContext* context,
332 UINT error = CHANNEL_RC_OK;
334 WINPR_ASSERT(context);
335 WINPR_ASSERT(header);
337 pdu.Header = *header;
339 pdu.N_Properties = Stream_GetRemainingLength(s) / 19;
341 if (pdu.N_Properties > 0)
346 WLog_ERR(TAG,
"Failed to allocate %zu CAM_PROPERTY_DESCRIPTION structs",
348 return ERROR_NOT_ENOUGH_MEMORY;
351 for (
size_t i = 0; i < pdu.N_Properties; ++i)
353 Stream_Read_UINT8(s, pdu.Properties[i].PropertySet);
354 Stream_Read_UINT8(s, pdu.Properties[i].PropertyId);
355 Stream_Read_UINT8(s, pdu.Properties[i].Capabilities);
356 Stream_Read_INT32(s, pdu.Properties[i].MinValue);
357 Stream_Read_INT32(s, pdu.Properties[i].MaxValue);
358 Stream_Read_INT32(s, pdu.Properties[i].Step);
359 Stream_Read_INT32(s, pdu.Properties[i].DefaultValue);
363 IFCALLRET(context->PropertyListResponse, error, context, &pdu);
365 WLog_ERR(TAG,
"context->PropertyListResponse failed with error %" PRIu32
"", error);
367 free(pdu.Properties);
372 static UINT device_server_recv_property_value_response(CameraDeviceServerContext* context,
377 UINT error = CHANNEL_RC_OK;
379 WINPR_ASSERT(context);
380 WINPR_ASSERT(header);
382 pdu.Header = *header;
384 if (!Stream_CheckAndLogRequiredLength(TAG, s, 5))
385 return ERROR_NO_DATA;
387 Stream_Read_UINT8(s, pdu.PropertyValue.Mode);
388 Stream_Read_INT32(s, pdu.PropertyValue.Value);
390 IFCALLRET(context->PropertyValueResponse, error, context, &pdu);
392 WLog_ERR(TAG,
"context->PropertyValueResponse failed with error %" PRIu32
"", error);
397 static UINT device_process_message(device_server* device)
400 UINT error = ERROR_INTERNAL_ERROR;
401 ULONG BytesReturned = 0;
405 WINPR_ASSERT(device);
406 WINPR_ASSERT(device->device_channel);
411 Stream_SetPosition(s, 0);
412 rc = WTSVirtualChannelRead(device->device_channel, 0, NULL, 0, &BytesReturned);
416 if (BytesReturned < 1)
418 error = CHANNEL_RC_OK;
422 if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
424 WLog_ERR(TAG,
"Stream_EnsureRemainingCapacity failed!");
425 error = CHANNEL_RC_NO_MEMORY;
429 if (WTSVirtualChannelRead(device->device_channel, 0, Stream_BufferAs(s,
char),
430 (ULONG)Stream_Capacity(s), &BytesReturned) == FALSE)
432 WLog_ERR(TAG,
"WTSVirtualChannelRead failed!");
436 Stream_SetLength(s, BytesReturned);
437 if (!Stream_CheckAndLogRequiredLength(TAG, s, CAM_HEADER_SIZE))
438 return ERROR_NO_DATA;
440 Stream_Read_UINT8(s, header.Version);
441 Stream_Read_UINT8(s, header.MessageId);
443 switch (header.MessageId)
445 case CAM_MSG_ID_SuccessResponse:
446 error = device_server_handle_success_response(&device->context, s, &header);
448 case CAM_MSG_ID_ErrorResponse:
449 error = device_server_recv_error_response(&device->context, s, &header);
451 case CAM_MSG_ID_StreamListResponse:
452 error = device_server_recv_stream_list_response(&device->context, s, &header);
454 case CAM_MSG_ID_MediaTypeListResponse:
455 error = device_server_recv_media_type_list_response(&device->context, s, &header);
457 case CAM_MSG_ID_CurrentMediaTypeResponse:
458 error = device_server_recv_current_media_type_response(&device->context, s, &header);
460 case CAM_MSG_ID_SampleResponse:
461 error = device_server_recv_sample_response(&device->context, s, &header);
463 case CAM_MSG_ID_SampleErrorResponse:
464 error = device_server_recv_sample_error_response(&device->context, s, &header);
466 case CAM_MSG_ID_PropertyListResponse:
467 error = device_server_recv_property_list_response(&device->context, s, &header);
469 case CAM_MSG_ID_PropertyValueResponse:
470 error = device_server_recv_property_value_response(&device->context, s, &header);
473 WLog_ERR(TAG,
"device_process_message: unknown or invalid MessageId %" PRIu8
"",
480 WLog_ERR(TAG,
"Response failed with error %" PRIu32
"!", error);
485 static UINT device_server_context_poll_int(CameraDeviceServerContext* context)
487 device_server* device = (device_server*)context;
488 UINT error = ERROR_INTERNAL_ERROR;
490 WINPR_ASSERT(device);
492 switch (device->state)
494 case CAMERA_DEVICE_INITIAL:
495 error = device_server_open_channel(device);
497 WLog_ERR(TAG,
"device_server_open_channel failed with error %" PRIu32
"!", error);
499 device->state = CAMERA_DEVICE_OPENED;
501 case CAMERA_DEVICE_OPENED:
502 error = device_process_message(device);
511 static HANDLE device_server_get_channel_handle(device_server* device)
514 DWORD BytesReturned = 0;
515 HANDLE ChannelEvent = NULL;
517 WINPR_ASSERT(device);
519 if (WTSVirtualChannelQuery(device->device_channel, WTSVirtualEventHandle, &buffer,
520 &BytesReturned) == TRUE)
522 if (BytesReturned ==
sizeof(HANDLE))
523 CopyMemory(&ChannelEvent, buffer,
sizeof(HANDLE));
525 WTSFreeMemory(buffer);
531 static DWORD WINAPI device_server_thread_func(LPVOID arg)
534 HANDLE events[2] = { 0 };
535 device_server* device = (device_server*)arg;
536 UINT error = CHANNEL_RC_OK;
539 WINPR_ASSERT(device);
542 events[nCount++] = device->stopEvent;
544 while ((error == CHANNEL_RC_OK) && (WaitForSingleObject(events[0], 0) != WAIT_OBJECT_0))
546 switch (device->state)
548 case CAMERA_DEVICE_INITIAL:
549 error = device_server_context_poll_int(&device->context);
550 if (error == CHANNEL_RC_OK)
552 events[1] = device_server_get_channel_handle(device);
556 case CAMERA_DEVICE_OPENED:
557 status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
562 case WAIT_OBJECT_0 + 1:
564 error = device_server_context_poll_int(&device->context);
569 error = ERROR_INTERNAL_ERROR;
578 (void)WTSVirtualChannelClose(device->device_channel);
579 device->device_channel = NULL;
581 if (error && device->context.rdpcontext)
582 setChannelError(device->context.rdpcontext, error,
583 "device_server_thread_func reported an error");
589 static UINT device_server_open(CameraDeviceServerContext* context)
591 device_server* device = (device_server*)context;
593 WINPR_ASSERT(device);
595 if (!device->externalThread && (device->thread == NULL))
597 device->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
598 if (!device->stopEvent)
600 WLog_ERR(TAG,
"CreateEvent failed!");
601 return ERROR_INTERNAL_ERROR;
604 device->thread = CreateThread(NULL, 0, device_server_thread_func, device, 0, NULL);
607 WLog_ERR(TAG,
"CreateThread failed!");
608 (void)CloseHandle(device->stopEvent);
609 device->stopEvent = NULL;
610 return ERROR_INTERNAL_ERROR;
613 device->isOpened = TRUE;
615 return CHANNEL_RC_OK;
618 static UINT device_server_close(CameraDeviceServerContext* context)
620 UINT error = CHANNEL_RC_OK;
621 device_server* device = (device_server*)context;
623 WINPR_ASSERT(device);
625 if (!device->externalThread && device->thread)
627 (void)SetEvent(device->stopEvent);
629 if (WaitForSingleObject(device->thread, INFINITE) == WAIT_FAILED)
631 error = GetLastError();
632 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"", error);
636 (void)CloseHandle(device->thread);
637 (void)CloseHandle(device->stopEvent);
638 device->thread = NULL;
639 device->stopEvent = NULL;
641 if (device->externalThread)
643 if (device->state != CAMERA_DEVICE_INITIAL)
645 (void)WTSVirtualChannelClose(device->device_channel);
646 device->device_channel = NULL;
647 device->state = CAMERA_DEVICE_INITIAL;
650 device->isOpened = FALSE;
655 static UINT device_server_context_poll(CameraDeviceServerContext* context)
657 device_server* device = (device_server*)context;
659 WINPR_ASSERT(device);
661 if (!device->externalThread)
662 return ERROR_INTERNAL_ERROR;
664 return device_server_context_poll_int(context);
667 static BOOL device_server_context_handle(CameraDeviceServerContext* context, HANDLE* handle)
669 device_server* device = (device_server*)context;
671 WINPR_ASSERT(device);
672 WINPR_ASSERT(handle);
674 if (!device->externalThread)
676 if (device->state == CAMERA_DEVICE_INITIAL)
679 *handle = device_server_get_channel_handle(device);
684 static wStream* device_server_packet_new(
size_t size, BYTE version, BYTE messageId)
689 s = Stream_New(NULL, size + CAM_HEADER_SIZE);
692 WLog_ERR(TAG,
"Stream_New failed!");
696 Stream_Write_UINT8(s, version);
697 Stream_Write_UINT8(s, messageId);
702 static UINT device_server_packet_send(CameraDeviceServerContext* context,
wStream* s)
704 device_server* device = (device_server*)context;
705 UINT error = CHANNEL_RC_OK;
708 WINPR_ASSERT(context);
711 const size_t len = Stream_GetPosition(s);
712 WINPR_ASSERT(len <= UINT32_MAX);
713 if (!WTSVirtualChannelWrite(device->device_channel, Stream_BufferAs(s,
char), (UINT32)len,
716 WLog_ERR(TAG,
"WTSVirtualChannelWrite failed!");
717 error = ERROR_INTERNAL_ERROR;
721 if (written < Stream_GetPosition(s))
723 WLog_WARN(TAG,
"Unexpected bytes written: %" PRIu32
"/%" PRIuz
"", written,
724 Stream_GetPosition(s));
728 Stream_Free(s, TRUE);
732 static UINT device_server_write_and_send_header(CameraDeviceServerContext* context, BYTE messageId)
736 WINPR_ASSERT(context);
738 s = device_server_packet_new(0, context->protocolVersion, messageId);
740 return ERROR_NOT_ENOUGH_MEMORY;
742 return device_server_packet_send(context, s);
746 device_send_activate_device_request_pdu(CameraDeviceServerContext* context,
749 WINPR_ASSERT(context);
751 return device_server_write_and_send_header(context, CAM_MSG_ID_ActivateDeviceRequest);
754 static UINT device_send_deactivate_device_request_pdu(
755 CameraDeviceServerContext* context,
758 WINPR_ASSERT(context);
760 return device_server_write_and_send_header(context, CAM_MSG_ID_DeactivateDeviceRequest);
763 static UINT device_send_stream_list_request_pdu(CameraDeviceServerContext* context,
766 WINPR_ASSERT(context);
768 return device_server_write_and_send_header(context, CAM_MSG_ID_StreamListRequest);
772 device_send_media_type_list_request_pdu(CameraDeviceServerContext* context,
777 WINPR_ASSERT(context);
778 WINPR_ASSERT(mediaTypeListRequest);
780 s = device_server_packet_new(1, context->protocolVersion, CAM_MSG_ID_MediaTypeListRequest);
782 return ERROR_NOT_ENOUGH_MEMORY;
784 Stream_Write_UINT8(s, mediaTypeListRequest->StreamIndex);
786 return device_server_packet_send(context, s);
789 static UINT device_send_current_media_type_request_pdu(
790 CameraDeviceServerContext* context,
795 WINPR_ASSERT(context);
796 WINPR_ASSERT(currentMediaTypeRequest);
798 s = device_server_packet_new(1, context->protocolVersion, CAM_MSG_ID_CurrentMediaTypeRequest);
800 return ERROR_NOT_ENOUGH_MEMORY;
802 Stream_Write_UINT8(s, currentMediaTypeRequest->StreamIndex);
804 return device_server_packet_send(context, s);
808 device_send_start_streams_request_pdu(CameraDeviceServerContext* context,
813 WINPR_ASSERT(context);
814 WINPR_ASSERT(startStreamsRequest);
816 s = device_server_packet_new(startStreamsRequest->N_Infos * 27ul, context->protocolVersion,
817 CAM_MSG_ID_StartStreamsRequest);
819 return ERROR_NOT_ENOUGH_MEMORY;
821 for (
size_t i = 0; i < startStreamsRequest->N_Infos; ++i)
826 Stream_Write_UINT8(s, info->StreamIndex);
828 Stream_Write_UINT8(s, description->Format);
829 Stream_Write_UINT32(s, description->Width);
830 Stream_Write_UINT32(s, description->Height);
831 Stream_Write_UINT32(s, description->FrameRateNumerator);
832 Stream_Write_UINT32(s, description->FrameRateDenominator);
833 Stream_Write_UINT32(s, description->PixelAspectRatioNumerator);
834 Stream_Write_UINT32(s, description->PixelAspectRatioDenominator);
835 Stream_Write_UINT8(s, description->Flags);
838 return device_server_packet_send(context, s);
841 static UINT device_send_stop_streams_request_pdu(CameraDeviceServerContext* context,
844 WINPR_ASSERT(context);
846 return device_server_write_and_send_header(context, CAM_MSG_ID_StopStreamsRequest);
849 static UINT device_send_sample_request_pdu(CameraDeviceServerContext* context,
854 WINPR_ASSERT(context);
855 WINPR_ASSERT(sampleRequest);
857 s = device_server_packet_new(1, context->protocolVersion, CAM_MSG_ID_SampleRequest);
859 return ERROR_NOT_ENOUGH_MEMORY;
861 Stream_Write_UINT8(s, sampleRequest->StreamIndex);
863 return device_server_packet_send(context, s);
867 device_send_property_list_request_pdu(CameraDeviceServerContext* context,
870 WINPR_ASSERT(context);
872 return device_server_write_and_send_header(context, CAM_MSG_ID_PropertyListRequest);
876 device_send_property_value_request_pdu(CameraDeviceServerContext* context,
881 WINPR_ASSERT(context);
882 WINPR_ASSERT(propertyValueRequest);
884 s = device_server_packet_new(2, context->protocolVersion, CAM_MSG_ID_PropertyValueRequest);
886 return ERROR_NOT_ENOUGH_MEMORY;
888 Stream_Write_UINT8(s, propertyValueRequest->PropertySet);
889 Stream_Write_UINT8(s, propertyValueRequest->PropertyId);
891 return device_server_packet_send(context, s);
894 static UINT device_send_set_property_value_request_pdu(
895 CameraDeviceServerContext* context,
900 WINPR_ASSERT(context);
901 WINPR_ASSERT(setPropertyValueRequest);
903 s = device_server_packet_new(2 + 5, context->protocolVersion,
904 CAM_MSG_ID_SetPropertyValueRequest);
906 return ERROR_NOT_ENOUGH_MEMORY;
908 Stream_Write_UINT8(s, setPropertyValueRequest->PropertySet);
909 Stream_Write_UINT8(s, setPropertyValueRequest->PropertyId);
911 Stream_Write_UINT8(s, setPropertyValueRequest->PropertyValue.Mode);
912 Stream_Write_INT32(s, setPropertyValueRequest->PropertyValue.Value);
914 return device_server_packet_send(context, s);
917 CameraDeviceServerContext* camera_device_server_context_new(HANDLE vcm)
919 device_server* device = (device_server*)calloc(1,
sizeof(device_server));
924 device->context.vcm = vcm;
925 device->context.Initialize = device_server_initialize;
926 device->context.Open = device_server_open;
927 device->context.Close = device_server_close;
928 device->context.Poll = device_server_context_poll;
929 device->context.ChannelHandle = device_server_context_handle;
931 device->context.ActivateDeviceRequest = device_send_activate_device_request_pdu;
932 device->context.DeactivateDeviceRequest = device_send_deactivate_device_request_pdu;
934 device->context.StreamListRequest = device_send_stream_list_request_pdu;
935 device->context.MediaTypeListRequest = device_send_media_type_list_request_pdu;
936 device->context.CurrentMediaTypeRequest = device_send_current_media_type_request_pdu;
938 device->context.StartStreamsRequest = device_send_start_streams_request_pdu;
939 device->context.StopStreamsRequest = device_send_stop_streams_request_pdu;
940 device->context.SampleRequest = device_send_sample_request_pdu;
942 device->context.PropertyListRequest = device_send_property_list_request_pdu;
943 device->context.PropertyValueRequest = device_send_property_value_request_pdu;
944 device->context.SetPropertyValueRequest = device_send_set_property_value_request_pdu;
946 device->buffer = Stream_New(NULL, 4096);
950 return &device->context;
952 WINPR_PRAGMA_DIAG_PUSH
953 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
954 camera_device_server_context_free(&device->context);
955 WINPR_PRAGMA_DIAG_POP
959 void camera_device_server_context_free(CameraDeviceServerContext* context)
961 device_server* device = (device_server*)context;
965 device_server_close(context);
966 Stream_Free(device->buffer, TRUE);
969 free(context->virtualChannelName);