ssl/libcrypto/src/crypto/libcrypto_wsd_solution.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2 Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
       
     3 
       
     4 Redistribution and use in source and binary forms, with or without 
       
     5 modification, are permitted provided that the following conditions are met:
       
     6 
       
     7 * Redistributions of source code must retain the above copyright notice, this 
       
     8   list of conditions and the following disclaimer.
       
     9 * Redistributions in binary form must reproduce the above copyright notice, 
       
    10   this list of conditions and the following disclaimer in the documentation 
       
    11   and/or other materials provided with the distribution.
       
    12 * Neither the name of Nokia Corporation nor the names of its contributors 
       
    13   may be used to endorse or promote products derived from this software 
       
    14   without specific prior written permission.
       
    15 
       
    16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
       
    17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
       
    18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
       
    19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
       
    20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
       
    21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
       
    22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
       
    23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
       
    24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
       
    25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    26 
       
    27 Description:  Contains the WSD solution
       
    28 */
       
    29 
       
    30 
       
    31 // INCLUDE FILES
       
    32 #ifndef EMULATOR
       
    33 #define EMULATOR (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
       
    34 #endif
       
    35 
       
    36 #include <e32std.h>
       
    37 #include <stddef.h>
       
    38 #include <windows.h>
       
    39 
       
    40 //definition of all WSD related funcitons 
       
    41 
       
    42 #define MAX_NUMBER_OF_PROCESSES	100
       
    43 
       
    44 struct TWsdArray
       
    45 {
       
    46 	TUint 		iPid;
       
    47 	TFullName 	iFullName;
       
    48 	void* 		iPtr;
       
    49 };
       
    50 
       
    51 #pragma data_seg(".wsd")
       
    52 TInt NumOfProcesses = 0;
       
    53 TInt MutexInitialized = 0;
       
    54 #pragma data_seg()
       
    55 
       
    56 #pragma bss_seg(".wsd")
       
    57 struct TWsdArray wsdArray[MAX_NUMBER_OF_PROCESSES];
       
    58 #pragma bss_seg()
       
    59 
       
    60 // This function frees up the used slots within the wsdArray
       
    61 // for use by other processes; internal to the implementation
       
    62 // that provides WSD support
       
    63 LOCAL_C TInt FindSlot();
       
    64 
       
    65 void *Pls()
       
    66 {
       
    67 	HANDLE mutexHandle = NULL;
       
    68 	LPCTSTR p = (unsigned short *)"libcrypto_mutex";
       
    69 	
       
    70 	if(!MutexInitialized)
       
    71 	{
       
    72 		// Keep an unused handle to the mutex object to prevent
       
    73 		// handle exhaustion
       
    74 		CreateMutex(NULL, FALSE, p);
       
    75 		MutexInitialized = 1;
       
    76 	}
       
    77 	
       
    78 	if(mutexHandle = CreateMutex(NULL, FALSE, p))
       
    79     {
       
    80 	    DWORD dwWaitResult = WaitForSingleObject(mutexHandle, INFINITE);
       
    81 	    switch (dwWaitResult) 
       
    82 		{
       
    83 		    // Cannot get mutex ownership due to time-out.
       
    84 		    case WAIT_TIMEOUT: 
       
    85 		        return NULL;
       
    86 		
       
    87 		    // Got ownership of the abandoned mutex object.
       
    88 		    case WAIT_ABANDONED: 
       
    89 		         return NULL; 
       
    90    	    }
       
    91 
       
    92 		if(dwWaitResult == WAIT_OBJECT_0)
       
    93 		{
       
    94 			// Thread got the mutex ownership
       
    95 			TProcessId procId = RProcess().Id();
       
    96 			TFullName fullName = RProcess().FullName();
       
    97 			TInt pid = *(TUint *)&procId;
       
    98 			TInt slot = -1;
       
    99 
       
   100 			for(int i=0 ; i < MAX_NUMBER_OF_PROCESSES ; ++i )
       
   101 			{
       
   102 				if(!wsdArray[i].iPid)
       
   103 				{
       
   104 					if(slot == -1)
       
   105 						slot = i;
       
   106 					
       
   107 					continue;
       
   108 				}
       
   109 				else if(wsdArray[i].iPid == pid)
       
   110 				{
       
   111 					ReleaseMutex(mutexHandle);
       
   112 					CloseHandle(mutexHandle);
       
   113 					return wsdArray[i].iPtr;
       
   114 				}
       
   115 			}
       
   116 			
       
   117 			// NEW PROCESS
       
   118 			
       
   119 			if(MAX_NUMBER_OF_PROCESSES == NumOfProcesses)
       
   120 			{
       
   121 				// Find out if one of the slots reserved for previous processes
       
   122 				// could be reused.
       
   123 				TInt returnValue = -1;
       
   124 				returnValue = FindSlot();
       
   125 				if(returnValue != -1)
       
   126 				{
       
   127 					slot = returnValue;
       
   128 				}
       
   129 				else
       
   130 				{
       
   131 					User::Panic(_L("Pls() Reached the naximum number for the processes"),KErrNoMemory);
       
   132 				}
       
   133 			}
       
   134 
       
   135 			wsdArray[slot].iPid = pid;
       
   136 			wsdArray[slot].iFullName = fullName;
       
   137 			wsdArray[slot].iPtr = NULL;
       
   138 			
       
   139 			// Increment the count for the number of processes
       
   140 			++NumOfProcesses;
       
   141 			
       
   142 			// Release the mutex
       
   143 			ReleaseMutex(mutexHandle);
       
   144 			CloseHandle(mutexHandle);
       
   145 			return wsdArray[slot].iPtr;
       
   146 		}
       
   147     }
       
   148 }
       
   149 
       
   150 LOCAL_C TInt FindSlot()
       
   151 {
       
   152 	TInt slot = -1;
       
   153 	TFullName fullName;
       
   154 	TInt currentCount = 0;
       
   155 	
       
   156 	for(int i = 0 ; i < MAX_NUMBER_OF_PROCESSES ; ++i)
       
   157 	{
       
   158 		TFindProcess search(wsdArray[i].iFullName);
       
   159 		if(search.Next(fullName) == KErrNone)
       
   160 		{
       
   161 			++currentCount;
       
   162 			continue;
       
   163 		}
       
   164 		
       
   165 		// Process with the given name does not exist in
       
   166 		// the system. So the slot could be reused.
       
   167 		wsdArray[i].iPid = 0;
       
   168 
       
   169 		// Free the VAS associated with this "process" (terminated)
       
   170 		if(wsdArray[i].iPtr)
       
   171 			{
       
   172 			VirtualFree(wsdArray[i].iPtr, 0, MEM_RELEASE);
       
   173 			}
       
   174 		wsdArray[i].iPtr = NULL;
       
   175 
       
   176 		if(slot == -1)
       
   177 		{
       
   178 			// Update
       
   179 			slot = i;
       
   180 		}
       
   181 	}
       
   182 	NumOfProcesses = currentCount;
       
   183 	return slot;
       
   184 }
       
   185 
       
   186 TInt SetPls(void *aArg)
       
   187 {
       
   188 	HANDLE mutexHandle = NULL;
       
   189 
       
   190 	LPCTSTR p = (unsigned short *)"libcrypto_mutex";
       
   191 	
       
   192 	if(!MutexInitialized)
       
   193 	{
       
   194 		// Keep an unused handle to the mutex object to prevent
       
   195 		// handle exhaustion
       
   196 		CreateMutex(NULL, FALSE, p);
       
   197 		MutexInitialized = 1;
       
   198 	}
       
   199 	
       
   200 	if(mutexHandle = CreateMutex(NULL, FALSE, p))
       
   201     {
       
   202 	    DWORD dwWaitResult = WaitForSingleObject(mutexHandle, INFINITE);
       
   203 	    switch (dwWaitResult) 
       
   204 		{
       
   205 		    // Cannot get mutex ownership due to time-out.
       
   206 		    case WAIT_TIMEOUT: 
       
   207 		        return KErrNotFound;
       
   208 		
       
   209 		    // Got ownership of the abandoned mutex object.
       
   210 		    case WAIT_ABANDONED: 
       
   211 		         return KErrNotFound; 
       
   212    	    }
       
   213 
       
   214 		if(dwWaitResult == WAIT_OBJECT_0)
       
   215 		{
       
   216 			// Thread got the mutex ownership
       
   217 			TProcessId procId = RProcess().Id();
       
   218 			TFullName fullName = RProcess().FullName();
       
   219 			TInt pid = *(TUint *)&procId;
       
   220 
       
   221 			for(int i=0 ; i < MAX_NUMBER_OF_PROCESSES ; ++i )
       
   222 			{
       
   223 				if(wsdArray[i].iPid == pid)
       
   224 				{
       
   225 					wsdArray[i].iPtr = aArg;
       
   226 					ReleaseMutex(mutexHandle);
       
   227 					CloseHandle(mutexHandle);
       
   228 					return KErrNone;
       
   229 				}
       
   230 			}
       
   231 			
       
   232 			ReleaseMutex(mutexHandle);
       
   233 			CloseHandle(mutexHandle);
       
   234 			return KErrNotFound;
       
   235 		}
       
   236     }
       
   237 }
       
   238 
       
   239 void* AllocatePls(TInt aSize)
       
   240 {
       
   241 	void *r = VirtualAlloc(NULL, 
       
   242 						   aSize,
       
   243 						   MEM_COMMIT | MEM_RESERVE,
       
   244 						   PAGE_READWRITE);
       
   245 	if(!r)
       
   246 	{
       
   247 		User::Panic(_L("AllocatePls() VIRTUALALLOC"),KErrNoMemory);
       
   248 	}
       
   249 	return r;
       
   250 }