181 return 0; 182 } 183 184 // ----------------------- 185 186 /** 187 * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging 188 * with the Java AccessBridge DLL 189 * 190 * NOTE: WM_COPYDATA is only for one-way IPC; there 191 * is no way to return parameters (especially big ones) 192 * Use sendMemoryPackage() to do that! 193 */ 194 LRESULT 195 AccessBridgeJavaVMInstance::sendPackage(char *buffer, long bufsize) { 196 COPYDATASTRUCT toCopy; 197 toCopy.dwData = 0; // 32-bits we could use for something... 198 toCopy.cbData = bufsize; 199 toCopy.lpData = buffer; 200 201 PrintDebugString("In AccessBridgeVMInstance::sendPackage"); 202 PrintDebugString(" javaAccessBridgeWindow: %p", javaAccessBridgeWindow); 203 /* This was SendMessage. Normally that is a blocking call. However, if 204 * SendMessage is sent to another process, e.g. another JVM and an incoming 205 * SendMessage is pending, control will be passed to the DialogProc to handle 206 * the incoming message. A bug occurred where this allowed an AB_DLL_GOING_AWAY 207 * message to be processed deleting an AccessBridgeJavaVMInstance object in 208 * the javaVMs chain. SendMessageTimeout with SMTO_BLOCK set will prevent the 209 * calling thread from processing other requests while waiting, i.e control 210 * will not be passed to the DialogProc. Also note that PostMessage or 211 * SendNotifyMessage can't be used. Although they don't allow transfer to 212 * the DialogProc they can't be used in cases where pointers are passed. This 213 * is because the referenced memory needs to be available when the other thread 214 * gets control. 215 */ 216 UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG; 217 DWORD_PTR out; // not used 218 LRESULT lr = SendMessageTimeout( javaAccessBridgeWindow, WM_COPYDATA, 219 (WPARAM)ourAccessBridgeWindow, (LPARAM)&toCopy, 220 flags, 4000, &out ); 221 return lr; 222 } 263 { 264 // copy the package into shared memory 265 if (!goingAway) { 266 memcpy(memoryMappedView, buffer, bufsize); 267 268 DEBUG_CODE(PackageType *type = (PackageType *) memoryMappedView); 269 DEBUG_CODE(if (*type == cGetAccessibleTextItemsPackage) {) 270 DEBUG_CODE(AppendToCallInfo(" 'memoryMappedView' now contains:")); 271 DEBUG_CODE(GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType))); 272 DEBUG_CODE(sprintf(outputBuf, " PackageType = %X", *type)); 273 DEBUG_CODE(AppendToCallInfo(outputBuf)); 274 DEBUG_CODE(}) 275 } 276 277 if (!goingAway) { 278 // Let the recipient know there is a package waiting for them. The unset byte 279 // at end of buffer which will only be set if message is properly received 280 char *done = &memoryMappedView[bufsize]; 281 *done = 0; 282 283 PrintDebugString(" javaAccessBridgeWindow: %p", javaAccessBridgeWindow); 284 // See the comment above the call to SendMessageTimeout in SendPackage method above. 285 UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG; 286 DWORD_PTR out; // not used 287 SendMessageTimeout( javaAccessBridgeWindow, AB_MESSAGE_WAITING, (WPARAM)ourAccessBridgeWindow, (LPARAM)bufsize, 288 flags, 4000, &out ); 289 290 // only succeed if message has been properly received 291 if(!goingAway) retval = (*done == 1); 292 } 293 294 // copy the package back from shared memory 295 if (!goingAway) { 296 memcpy(buffer, memoryMappedView, bufsize); 297 } 298 } 299 LeaveCriticalSection(&sendMemoryIPCLock); 300 return retval; 301 } 302 303 304 /** 305 * findAccessBridgeWindow - walk through linked list from where we are, 306 * return the HWND of the ABJavaVMInstance that 307 * matches the passed in vmID; no match: return 0 308 * 309 */ 310 HWND 311 AccessBridgeJavaVMInstance::findAccessBridgeWindow(long javaVMID) { 312 PrintDebugString("In findAccessBridgeWindow"); 313 // no need to recurse really 314 if (vmID == javaVMID) { 315 return javaAccessBridgeWindow; 316 } else { 317 isVMInstanceChainInUse = true; 318 AccessBridgeJavaVMInstance *current = nextJVMInstance; 319 while (current != (AccessBridgeJavaVMInstance *) 0) { 320 if (current->vmID == javaVMID) { 321 isVMInstanceChainInUse = false; 322 return current->javaAccessBridgeWindow; 323 } 324 current = current->nextJVMInstance; 325 } 326 isVMInstanceChainInUse = false; 327 } 328 return 0; 329 } 330 331 /** 332 * findABJavaVMInstanceFromJavaHWND - walk through linked list from 333 * where we are. Return the 334 * AccessBridgeJavaVMInstance 335 * of the ABJavaVMInstance that 336 * matches the passed in vmID; 337 * no match: return 0 338 */ 339 AccessBridgeJavaVMInstance * 340 AccessBridgeJavaVMInstance::findABJavaVMInstanceFromJavaHWND(HWND window) { 341 PrintDebugString("In findABJavaInstanceFromJavaHWND"); 342 // no need to recurse really 343 if (javaAccessBridgeWindow == window) { 344 return this; 345 } else { 346 isVMInstanceChainInUse = true; 347 AccessBridgeJavaVMInstance *current = nextJVMInstance; 348 while (current != (AccessBridgeJavaVMInstance *) 0) { 349 if (current->javaAccessBridgeWindow == window) { 350 isVMInstanceChainInUse = false; 351 return current; 352 } 353 current = current->nextJVMInstance; 354 } 355 } 356 isVMInstanceChainInUse = false; 357 return (AccessBridgeJavaVMInstance *) 0; 358 } | 181 return 0; 182 } 183 184 // ----------------------- 185 186 /** 187 * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging 188 * with the Java AccessBridge DLL 189 * 190 * NOTE: WM_COPYDATA is only for one-way IPC; there 191 * is no way to return parameters (especially big ones) 192 * Use sendMemoryPackage() to do that! 193 */ 194 LRESULT 195 AccessBridgeJavaVMInstance::sendPackage(char *buffer, long bufsize) { 196 COPYDATASTRUCT toCopy; 197 toCopy.dwData = 0; // 32-bits we could use for something... 198 toCopy.cbData = bufsize; 199 toCopy.lpData = buffer; 200 201 PrintDebugString("[INFO]: In AccessBridgeVMInstance::sendPackage"); 202 PrintDebugString("[INFO]: javaAccessBridgeWindow: %p", javaAccessBridgeWindow); 203 /* This was SendMessage. Normally that is a blocking call. However, if 204 * SendMessage is sent to another process, e.g. another JVM and an incoming 205 * SendMessage is pending, control will be passed to the DialogProc to handle 206 * the incoming message. A bug occurred where this allowed an AB_DLL_GOING_AWAY 207 * message to be processed deleting an AccessBridgeJavaVMInstance object in 208 * the javaVMs chain. SendMessageTimeout with SMTO_BLOCK set will prevent the 209 * calling thread from processing other requests while waiting, i.e control 210 * will not be passed to the DialogProc. Also note that PostMessage or 211 * SendNotifyMessage can't be used. Although they don't allow transfer to 212 * the DialogProc they can't be used in cases where pointers are passed. This 213 * is because the referenced memory needs to be available when the other thread 214 * gets control. 215 */ 216 UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG; 217 DWORD_PTR out; // not used 218 LRESULT lr = SendMessageTimeout( javaAccessBridgeWindow, WM_COPYDATA, 219 (WPARAM)ourAccessBridgeWindow, (LPARAM)&toCopy, 220 flags, 4000, &out ); 221 return lr; 222 } 263 { 264 // copy the package into shared memory 265 if (!goingAway) { 266 memcpy(memoryMappedView, buffer, bufsize); 267 268 DEBUG_CODE(PackageType *type = (PackageType *) memoryMappedView); 269 DEBUG_CODE(if (*type == cGetAccessibleTextItemsPackage) {) 270 DEBUG_CODE(AppendToCallInfo(" 'memoryMappedView' now contains:")); 271 DEBUG_CODE(GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType))); 272 DEBUG_CODE(sprintf(outputBuf, " PackageType = %X", *type)); 273 DEBUG_CODE(AppendToCallInfo(outputBuf)); 274 DEBUG_CODE(}) 275 } 276 277 if (!goingAway) { 278 // Let the recipient know there is a package waiting for them. The unset byte 279 // at end of buffer which will only be set if message is properly received 280 char *done = &memoryMappedView[bufsize]; 281 *done = 0; 282 283 PrintDebugString("[INFO]: javaAccessBridgeWindow: %p", javaAccessBridgeWindow); 284 // See the comment above the call to SendMessageTimeout in SendPackage method above. 285 UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG; 286 DWORD_PTR out; // not used 287 SendMessageTimeout( javaAccessBridgeWindow, AB_MESSAGE_WAITING, (WPARAM)ourAccessBridgeWindow, (LPARAM)bufsize, 288 flags, 4000, &out ); 289 290 // only succeed if message has been properly received 291 if(!goingAway) retval = (*done == 1); 292 } 293 294 // copy the package back from shared memory 295 if (!goingAway) { 296 memcpy(buffer, memoryMappedView, bufsize); 297 } 298 } 299 LeaveCriticalSection(&sendMemoryIPCLock); 300 return retval; 301 } 302 303 304 /** 305 * findAccessBridgeWindow - walk through linked list from where we are, 306 * return the HWND of the ABJavaVMInstance that 307 * matches the passed in vmID; no match: return 0 308 * 309 */ 310 HWND 311 AccessBridgeJavaVMInstance::findAccessBridgeWindow(long javaVMID) { 312 PrintDebugString("[INFO]: In findAccessBridgeWindow"); 313 // no need to recurse really 314 if (vmID == javaVMID) { 315 return javaAccessBridgeWindow; 316 } else { 317 isVMInstanceChainInUse = true; 318 AccessBridgeJavaVMInstance *current = nextJVMInstance; 319 while (current != (AccessBridgeJavaVMInstance *) 0) { 320 if (current->vmID == javaVMID) { 321 isVMInstanceChainInUse = false; 322 return current->javaAccessBridgeWindow; 323 } 324 current = current->nextJVMInstance; 325 } 326 isVMInstanceChainInUse = false; 327 } 328 return 0; 329 } 330 331 /** 332 * findABJavaVMInstanceFromJavaHWND - walk through linked list from 333 * where we are. Return the 334 * AccessBridgeJavaVMInstance 335 * of the ABJavaVMInstance that 336 * matches the passed in vmID; 337 * no match: return 0 338 */ 339 AccessBridgeJavaVMInstance * 340 AccessBridgeJavaVMInstance::findABJavaVMInstanceFromJavaHWND(HWND window) { 341 PrintDebugString("[INFO]: In findABJavaInstanceFromJavaHWND"); 342 // no need to recurse really 343 if (javaAccessBridgeWindow == window) { 344 return this; 345 } else { 346 isVMInstanceChainInUse = true; 347 AccessBridgeJavaVMInstance *current = nextJVMInstance; 348 while (current != (AccessBridgeJavaVMInstance *) 0) { 349 if (current->javaAccessBridgeWindow == window) { 350 isVMInstanceChainInUse = false; 351 return current; 352 } 353 current = current->nextJVMInstance; 354 } 355 } 356 isVMInstanceChainInUse = false; 357 return (AccessBridgeJavaVMInstance *) 0; 358 } |