1 krisbash 1.1 /*============================================================================
2 * Copyright (C) Microsoft Corporation, All rights reserved.
3 *============================================================================
4 */
5 #include <MI.h>
6 #include "Application.h"
7 #include "HostedProvider.h"
8
9 extern const MI_HostedProviderFT g_hostedProviderFT;
10
11 typedef struct _HostedProviderObject
12 {
13 /* Linked list for child application hosted providers. Includes clients hosted provider handle */
14 ChildListNode hostedProviderNode;
15
16 MI_Application clientApplication;
17
18 ProtocolHandlerCacheItem *protocolHandlerItem;
19
20 MI_HostedProvider protocolHandler_HP;
21 } HostedProviderObject;
22 krisbash 1.1
23 /* When thunk handle ref count gets to zero means no one is referencing this object any more
24 * so we can now delete the HostedProviderObject
25 */
26 void HostedProvider_Destructor(
27 _In_ ThunkHandle *thunkHandle)
28 {
29 HostedProviderObject *hostedProviderObject = (HostedProviderObject*)thunkHandle->u.object;
30
31 /* Unregister self from application */
32 Application_UnregisterHostedProvider(&hostedProviderObject->clientApplication, &hostedProviderObject->hostedProviderNode);
33
34 /* Free up object */
35 PAL_Free(hostedProviderObject);
36 }
37
38 _Success_(return == MI_RESULT_OK)
39 MI_Result MI_CALL HostedProvider_Create(
40 _In_ MI_Application *application,
41 _In_z_ const MI_Char * namespaceName,
42 _In_z_ const MI_Char * providerName,
43 krisbash 1.1 _In_ MI_MainFunction mi_Main,
44 _Outptr_opt_result_maybenull_ MI_Instance **extendedError,
45 _Out_ MI_HostedProvider *hostedProvider)
46 {
47 ProtocolHandlerCacheItem *protocolHandlerItem;
48 HostedProviderObject *hpObject;
49 MI_Result result;
50 GenericHandle *genericHandle = (GenericHandle*) hostedProvider;
51
52 if (hostedProvider)
53 {
54 memset(hostedProvider, 0, sizeof(MI_HostedProvider));
55 }
56 if (extendedError)
57 {
58 *extendedError = NULL;
59 }
60 if ((mi_Main == NULL) || (application == NULL) || (namespaceName == NULL) || (providerName == NULL) || (hostedProvider == NULL))
61 {
62 return MI_RESULT_INVALID_PARAMETER;
63 }
64 krisbash 1.1
65 result = Application_GetProtocolHandler(application, NULL, NULL, &protocolHandlerItem);
66 if (result != MI_RESULT_OK)
67 {
68 return result;
69 }
70
71 if (protocolHandlerItem->application.ft->NewHostedProvider == NULL)
72 {
73 return MI_RESULT_NOT_SUPPORTED;
74 }
75
76
77 hpObject = PAL_Malloc(sizeof(HostedProviderObject));
78 if (hpObject == NULL)
79 {
80 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
81 }
82 memset(hpObject, 0, sizeof(HostedProviderObject));
83
84 result = Application_NewGenericHandle(application, genericHandle);
85 krisbash 1.1 if (result != MI_RESULT_OK)
86 {
87 PAL_Free(hpObject);
88 return result;
89 }
90
91 genericHandle->thunkHandle->u.object = hpObject;
92 hpObject->clientApplication = *application;
93 hpObject->protocolHandlerItem = protocolHandlerItem;
94 hostedProvider->ft = &g_hostedProviderFT;
95
96 hpObject->hostedProviderNode.clientHandle = *(GenericHandle*) hostedProvider;
97
98 /* Need to register with application */
99 result = Application_RegisterHostedProvider(application, &hpObject->hostedProviderNode);
100 if (result != MI_RESULT_OK)
101 {
102 ThunkHandle_Shutdown(genericHandle->thunkHandle, HostedProvider_Destructor);
103 hostedProvider->reserved1 = 0;
104 hostedProvider->reserved2 = 0;
105 hostedProvider->ft = NULL;
106 krisbash 1.1 return result;
107
108 }
109
110 ProtocolHandlerCache_IncrementApiCount(protocolHandlerItem);
111 result = protocolHandlerItem->application.ft->NewHostedProvider(&protocolHandlerItem->application, namespaceName, providerName, mi_Main, extendedError, &hpObject->protocolHandler_HP);
112 ProtocolHandlerCache_DecrementApiCount(protocolHandlerItem);
113 if (result != MI_RESULT_OK)
114 {
115 ThunkHandle_Shutdown(genericHandle->thunkHandle, HostedProvider_Destructor);
116 hostedProvider->reserved1 = 0;
117 hostedProvider->reserved2 = 0;
118 hostedProvider->ft = NULL;
119 }
120 return result;
121 }
122
123
124 MI_Result MI_CALL HostedProvider_Close(
125 _In_ MI_HostedProvider *hostedProvider)
126 {
127 krisbash 1.1 MI_Result result = MI_RESULT_OK;
128 if (hostedProvider)
129 {
130 GenericHandle *genericHandle = (GenericHandle*) hostedProvider;
131 ThunkHandle *thunkHandle = NULL;
132
133 ThunkHandle_FromGeneric(genericHandle, &thunkHandle);
134 if (thunkHandle == NULL)
135 {
136 /* Failed means version was wrong or object was shutdown */
137 return MI_RESULT_INVALID_PARAMETER;
138 }
139
140 /* Trigger shutdown */
141 if (ThunkHandle_Shutdown(thunkHandle, HostedProvider_Destructor))
142 {
143 /* Only succeeds once so now call into provider */
144 HostedProviderObject *hpObject = (HostedProviderObject*) thunkHandle->u.object;
145 ProtocolHandlerCache_IncrementApiCount(hpObject->protocolHandlerItem);
146 result = hpObject->protocolHandler_HP.ft->Close(&hpObject->protocolHandler_HP);
147 ProtocolHandlerCache_DecrementApiCount(hpObject->protocolHandlerItem);
148 krisbash 1.1 }
149 ThunkHandle_Release(thunkHandle);
150 }
151 return result;
152 }
153
154 MI_Result MI_CALL HostedProvider_GetApplication(
155 _In_ MI_HostedProvider *hostedProvider,
156 _Out_ MI_Application *application)
157 {
158 if (application)
159 {
160 memset(application, 0, sizeof(MI_Application));
161 }
162 if (hostedProvider && application)
163 {
164 GenericHandle *genericHandle = (GenericHandle*) hostedProvider;
165 ThunkHandle *thunkHandle = NULL;
166 HostedProviderObject *hpObject = NULL;
167
168 ThunkHandle_FromGeneric(genericHandle, &thunkHandle);
169 krisbash 1.1 if (thunkHandle == NULL)
170 {
171 /* Failed means version was wrong or object was shutdown */
172 return MI_RESULT_INVALID_PARAMETER;
173 }
174 hpObject = (HostedProviderObject*) thunkHandle->u.object;
175 *application = hpObject->clientApplication;
176
177 ThunkHandle_Release(thunkHandle);
178 return MI_RESULT_OK;
179 }
180 else
181 {
182 return MI_RESULT_INVALID_PARAMETER;
183 }
184 }
185
186
187 const MI_HostedProviderFT g_hostedProviderFT = {
188 HostedProvider_Close,
189 HostedProvider_GetApplication
190 krisbash 1.1 };
|