< prev index next >

src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeJavaVMInstance.cpp

Print this page




 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 }
< prev index next >