⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w32api.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		return retval;}/* }}} */static int php_w32api_get_type_size(int type_id, char *type_name, int flags){	TSRMLS_FETCH();	if(flags & BYREF_FORCE)	{		return sizeof(void *);								/* Pointers are always the same size */	}	switch(type_id)	{											case W32API_NULL:												return sizeof(void *);		case W32API_INT:					return sizeof(int);		case W32API_LONG:				return sizeof(long);		case W32API_DOUBLE:					return sizeof(double);		case W32API_FLOAT:					return sizeof(float);		case W32API_STRING:					return sizeof(char *);		case W32API_BYTE:					return sizeof(char);		case W32API_BOOL:					return sizeof(int);		case W32API_COMPLEX:			{				w32api_type_handle **th;								if(zend_hash_find(WG(types), type_name, strlen(type_name) +1, (void **)&th) != SUCCESS)				{						php_error(E_ERROR, "Unknown type %s", type_name);						return -1;				}				return (*th)->size;			}			break;				case W32API_UNKNOWN:		default:			php_error(E_ERROR, "Unknown type %s", type_name);			return -1;	}}static int php_w32api_get_type_id_from_name(char *type){	TSRMLS_FETCH();	if(!strcmp(type, "long"))	{		return W32API_LONG;	}	else if(!strcmp(type, "int"))	{		return W32API_INT;	}	else if (!strcmp(type, "string")) 	{		return W32API_STRING;	}	else if (!strcmp(type, "byte"))	{		return W32API_BYTE;	}	else if (!strcmp(type, "bool"))	{		return W32API_BOOL;	}	else if (!strcmp(type, "double"))	{		return W32API_DOUBLE;	}	else if (!strcmp(type, "float"))	{		return W32API_FLOAT;	}	else if (!strcmp(type, "void"))	{		return W32API_NULL;	}	else	{		if(zend_hash_exists(WG(types), type, strlen(type) +1))		{			return W32API_COMPLEX;		}		else		{			return W32API_UNKNOWN;		}	} }static void php_w32api_init_type(w32api_type_handle *th, zval *obj TSRMLS_DC){	w32api_type_instance *ti;	zval *rsrc_handle = NULL;	ti = emalloc(sizeof(w32api_type_instance));	if(!obj)		MAKE_STD_ZVAL(obj);	object_init_ex(obj, WG(type_ce));	ti->type = th;	ti->values = emalloc(sizeof(zval *) * th->member_count);	memset(ti->values, '\0', sizeof(zval *) * th->member_count);	MAKE_STD_ZVAL(rsrc_handle);	ZEND_REGISTER_RESOURCE(rsrc_handle, ti, WG(le_type_instance));	zend_hash_index_update(Z_OBJPROP_P(obj), 0, &rsrc_handle, sizeof(zval *), NULL);}static int php_w32api_do_prop_get(zval *object, zval *return_value, zend_llist_element **element TSRMLS_DC){	w32api_type_instance *th;	zval **type_instance_handle;	members *current_member;	char *property_name;	int i = 0;	zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &type_instance_handle);	th = (w32api_type_instance *)zend_fetch_resource(type_instance_handle TSRMLS_CC, 													  -1, "Complex Type Instance", NULL, 													   1, WG(le_type_instance));		if(!th)		return FAILURE;	property_name = Z_STRVAL(((zend_overloaded_element *)(*element)->data)->element);	current_member = th->type->member_list;	while(strcmp(current_member->member->member_name, property_name) != 0)	{		i++;		if(current_member->next_member != NULL)			current_member = current_member->next_member;		else			return FAILURE;	}	*return_value = *(th->values[i]);	zval_copy_ctor(return_value);	return SUCCESS;}static int php_w32api_do_prop_set(zval *object, zval *value, zend_llist_element **element TSRMLS_DC){	w32api_type_instance *th;	zval **type_instance_handle;	zval *new_var;	members *current_member;	char *property_name;	int i = 0;	zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &type_instance_handle);	th = (w32api_type_instance *)zend_fetch_resource(type_instance_handle TSRMLS_CC, 													  -1, "Complex Type Instance", NULL, 													   1, WG(le_type_instance));		if(!th)		return FAILURE;	property_name = Z_STRVAL(((zend_overloaded_element *)(*element)->data)->element);	current_member = th->type->member_list;	while(strcmp(current_member->member->member_name, property_name) != 0)	{		i++;		if(current_member->next_member != NULL)			current_member = current_member->next_member;		else			return FAILURE;	}		if(current_member->member->flags & BYREF_FORCE)	{		if(th->values[i])			zval_ptr_dtor(&th->values[i]);		MAKE_STD_ZVAL(new_var);		*new_var = *value;		zval_copy_ctor(new_var);		th->values[i] = new_var;	}	else	{		th->values[i] = value;		zval_add_ref(&value);	}	return SUCCESS;}w32api_result php_w32api_do_dynamic_dll_call(w32api_func_handle *fh, int argc, w32api_dynamic_param *params, void *return_buffer, int return_buffer_size){	/**	 * Theory Behind Implementation	 * ============================	 * We have four main jobs:	 * 1) Push arguments onto stach aligned at 4 bytes.	 * 2) Call Function	 * 3) Get Return Values	 * 4) Perform any cleanup needed.	 *	 * Pushing arguments onto the stack is fairly simple, just push from right to left	 * so for a function with the prototype int sum(int a, int b) we would push b and	 * then a in that order.	 *	 * Calling the function is fine as we already have the pointer to the function which	 * we can use with call [function_pointer] to make the actual call.	 *	 * Return values are where we begin to get complicated. Now for simple return values up	 * to 8 bytes they are returned via the EAX/EDX register pair. This means we can just	 * copy the EAX/EDX pair to the win32_result sturcture and be sure we get any simple	 * return type. If the return type is more than 8 bytes then things get complicated.	 * When calling we must pass a hidden argument on the stach which points to a tempory	 * buffer with enough memory to hold the return value, this return value is then copied	 * to the correct varaible by us. Microsoft being the nice bunnies they are, decided to	 * copy an optimization Borland introduced under win16 which is to pass structs of under	 * 8 bytes directly via EAX/EDX pair. One final notable exception is dealing with floating	 * point return types where we need to retrive the floating point number of the systems	 * math coprocessor stack using the fstp call.	 *	 * Finally if its a __cdecl call we have to clean up the stack, otherwise the callee does this.	 *	 */	w32api_result result = { 0 };	DWORD *stack_pointer, stack_size = 0, eaxv, edxv;	BYTE *arg_ptr = NULL;	int size = 0, i = 0;	FARPROC fp = fh->handle;	_asm mov stack_pointer, esp		// Store stack pointer (esp) in stack_pointer	_asm sub esp, 0x100				// Give ourselves 256 bytes on the stack	for(i = (argc - 1); i >= 0; i--)	{		size = (params[i].width + 3)/4 * 4;		arg_ptr = (unsigned char *)params[i].argument_ptr + size - 4;		stack_size += (unsigned long)size;		while(size > 0)		{			stack_pointer--;			if(params[i].flags == W32API_ARGPTR)			{				*stack_pointer = *(unsigned long *)arg_ptr;				arg_ptr -= 4;			}			else			{				*stack_pointer = params[i].argument;			}			size -= 4;		}	}	if((return_buffer) && ((fh->flags & W32API_BORLAND) || (return_buffer_size > 8)))	{		stack_size += 4;		stack_pointer--;		*stack_pointer = (unsigned long)return_buffer;	}	_asm add esp, 0x100	_asm sub esp, stack_size	_asm call [fp]	_asm mov eaxv, eax	_asm mov edxv, edx	if(fh->flags & W32API_CDECL)	{		_asm add esp, stack_size	}	if(fh->flags & W32API_REAL4)		_asm fstp dword ptr [result]	else if (fh->flags & W32API_REAL8)		_asm fstp qword ptr [result]	else if (!return_buffer)	{		_asm mov eax, [eaxv]		_asm mov edx, [edxv]		_asm mov DWORD PTR [result], eax		_asm mov DWORD PTR [result + 4], edx	}	else if (!(fh->flags & W32API_BORLAND) && (return_buffer_size <= 8))	{		_asm mov ecx, DWORD PTR [return_buffer]		_asm mov eax, [eaxv]		_asm mov DWORD PTR [ecx], eax		_asm mov edx, [edxv]		_asm mov DWORD PTR [ecx + 4], edx	}	return result;}void php_w32api_marshall_zval_to_c(argument *arg, w32api_dynamic_param *dp, zval *pzval TSRMLS_DC){	dp->flags = 0;	/* We should have been passed a write reference when	 * BYREF_FORCE is Set so we just add a reference	 * when we pass it to the function,	 * TODO: register the reference internally for safe unreferencing	 */	switch(arg->type_id)	{		case W32API_INT:			convert_to_long_ex(&pzval);			if(arg->flags & BYREF_FORCE)			{				dp->argument = (unsigned long)&pzval->value.lval;				dp->width = sizeof(int *);							}			else			{				dp->argument = (int)pzval->value.lval;				dp->width = sizeof(int);			}			break;		case W32API_LONG:			convert_to_long_ex(&pzval);			if(arg->flags & BYREF_FORCE)			{				dp->argument = (unsigned long)&pzval->value.lval;				dp->width = sizeof(int *);				zval_add_ref(&pzval);			}			else			{				dp->argument = pzval->value.lval;				dp->width = sizeof(int);			}			break;		case W32API_STRING:			convert_to_string_ex(&pzval);			if(!(arg->flags & BYREF_FORCE))			{				/* Need to free this when we demarshall */				dp->argument = (unsigned long)estrndup(Z_STRVAL_P(pzval), Z_STRLEN_P(pzval));			}			else			{				dp->argument = (unsigned long)Z_STRVAL_P(pzval);				zval_add_ref(&pzval);			}					dp->width = sizeof(char *);			break;		case W32API_DOUBLE:			convert_to_double_ex(&pzval);			if(arg->flags & BYREF_FORCE)			{				dp->argument = (unsigned long)&pzval->value.dval;				dp->width = sizeof(double *);				zval_add_ref(&pzval);			}			else			{				dp->argument_ptr = &pzval->value.dval;				dp->width = sizeof(double);				dp->flags = W32API_ARGPTR;			}			break;		case W32API_FLOAT:			convert_to_double_ex(&pzval);			if(arg->flags & BYREF_FORCE)			{				dp->argument = (unsigned long)&pzval->value.dval;				dp->width = sizeof(double *);				zval_add_ref(&pzval);			}			else			{				dp->argument_ptr = &pzval->value.dval;				dp->width = sizeof(float);				dp->flags = W32API_ARGPTR;			}			break;		case W32API_BYTE:					/* Thanks sterling */			convert_to_string_ex(&pzval);			if(arg->flags & BYREF_FORCE)			{				dp->argument = (unsigned long)&Z_STRVAL_P(pzval);				dp->width = sizeof(char *);				zval_add_ref(&pzval);			}			else			{				dp->argument = (char)Z_STRVAL_P(pzval)[0];				dp->width = sizeof(char);			}			break;		case W32API_BOOL:			convert_to_boolean_ex(&pzval);			if(arg->flags & BYREF_FORCE)			{				dp->argument = (unsigned long)&pzval->value.lval;				dp->width = sizeof(int *);				zval_add_ref(&pzval);			}			else			{				dp->argument = (int)pzval->value.lval;				dp->width = sizeof(int);			}			break;		case W32API_COMPLEX:			if(Z_TYPE_P(pzval) != IS_OBJECT)			{				php_error(E_ERROR, "Variable passed as complex value is not an object");				break;			}			if(arg->flags & BYREF_FORCE)			{				int width= 0;				void **ptr = NULL;				ptr = emalloc(sizeof(void *));				*ptr = php_w32api_complex_marshall_zval_to_c(pzval, &width, NULL TSRMLS_CC);				dp->argument = (unsigned long)ptr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -