📄 w32api.c
字号:
{ if(flags == 0) { lh->ref_count--; } if((flags == 1) || (lh->ref_count == 0)) { /* remove outselves from the hashtable */ zend_hash_del(WG(libraries), lh->library_name, strlen(lh->library_name) + 1); }}/* }}} *//* {{{ php_w32api_unload_function * Expects one argument, a pointer to a w32api_func_handle, unloads this * function from both the function table internally and the PHP function * table then it decrements the reference counter on the library. */static void php_w32api_unload_function (w32api_func_handle **fh TSRMLS_DC){ zend_function *function = NULL; efree((*fh)->return_type_name); php_w32api_free_arguments((*fh)->argument_list); /* If needs be we need to retrieve function ptr from hash table * and free anything we allocate when creating them at runtime (most notably * arg_types */ if(zend_hash_find( &WG(win32_ce)->function_table, (*fh)->function_name, strlen((*fh)->function_name) + 1, (void **)&function) == SUCCESS) { zend_internal_function *internal_function = (zend_internal_function *)function; if(internal_function->arg_types) efree(internal_function->arg_types); } /* Remove from Function Table */ zend_hash_del(&WG(win32_ce)->function_table, (*fh)->function_name, strlen((*fh)->function_name) + 1); php_w32api_unload_library((*fh)->lib, 0 TSRMLS_CC); efree((*fh)->function_name); efree(*fh);}/* }}} *//* {{{ php_w32api_load_function * Expects three arguments, The definition of the function in string format, the definitions length * and a pointer to a pointer to a function handle. returns SUCCESS or FAILURE. */static int php_w32api_load_function (char *definition, int definition_len, int flags TSRMLS_DC){ zend_function function; zend_internal_function *internal_function = (zend_internal_function *)&function; w32api_func_handle **fh; w32api_func_handle_ptr hnd; fh = emalloc(sizeof(w32api_func_handle *)); *fh = NULL; /* Parse function */ w32api_function_definition_scan_bytes(definition, definition_len); if((w32api_function_definition_parse((void *)&hnd) != 0)) { *fh = hnd.hnd; if(*fh != NULL) efree(*fh); efree(fh); return FAILURE; } *fh = hnd.hnd; if(!*fh) return FAILURE; if(zend_hash_exists(&WG(win32_ce)->function_table, (*fh)->function_name, strlen((*fh)->function_name) + 1)) { php_error( E_WARNING, "A function by the name %s already has been registered, cannot redefine function", (*fh)->function_name); /* We dont want to unload function as it already exists so lets just free it ourselves */ php_w32api_unload_library((*fh)->lib, 0 TSRMLS_CC); php_w32api_free_arguments((*fh)->argument_list); efree((*fh)->return_type_name); efree((*fh)->function_name); efree(*fh); efree(fh); return FAILURE; } /* Insert it into our hash table */ if(zend_hash_add( WG(funcs), (*fh)->function_name, strlen((*fh)->function_name) + 1, fh, sizeof(w32api_func_handle), NULL) != SUCCESS) { php_error( E_WARNING, "Loading of function %s failed: Could not insert function handle into hash", (*fh)->function_name); /* Tidy up */ zend_hash_del(WG(funcs), (*fh)->function_name, strlen((*fh)->function_name) +1); return FAILURE; } /* Insert function into win32_ce's function_table */ internal_function->type = ZEND_INTERNAL_FUNCTION; internal_function->handler = W32API_CLASS_FN(win32, invokefunction); internal_function->function_name = (*fh)->function_name; internal_function->arg_types = php_w32api_do_arg_types(&(*fh)->argument_list); if(zend_hash_add(&WG(win32_ce)->function_table, (*fh)->function_name, strlen((*fh)->function_name) + 1, &function, sizeof(zend_function), NULL) == FAILURE) { php_error(E_ERROR, "Could not register function %s into function table", (*fh)->function_name); zend_hash_del(WG(funcs), (*fh)->function_name, strlen((*fh)->function_name) +1); return FAILURE;; } if(flags) { (*fh)->flags = (*fh)->flags | flags; } return SUCCESS;}/* }}} *//* {{{ php_w32api_unload_type * Expects one argument, a pointer to a w32api_type_handle, unloads this * type. */static void php_w32api_unload_type (w32api_type_handle **th TSRMLS_DC){ php_w32api_free_members((*th)->member_list); zend_hash_del(WG(types), (*th)->type_name, strlen((*th)->type_name) + 1);}/* }}} *//* {{{ php_w32api_register_type */static int php_w32api_register_type(char *type_definition, int type_definition_len TSRMLS_DC){ w32api_type_handle **th; w32api_type_handle_ptr hnd; th = emalloc(sizeof(w32api_type_handle *)); *th = NULL; w32api_type_definition_scan_bytes(type_definition, type_definition_len); if(w32api_type_definition_parse((void *)&hnd) != 0) { *th = hnd.hnd; /* Leaks */ if(*th != NULL) efree(*th); efree(th); return FAILURE; } *th = hnd.hnd; if(!*th) return FAILURE; if((zend_hash_exists(WG(callbacks), (*th)->type_name, strlen((*th)->type_name) +1)) || (zend_hash_exists(WG(types), (*th)->type_name, strlen((*th)->type_name) + 1))) { php_error( E_WARNING, "A type or callback by the name %s already has been registered, cannot redefine type or callback", (*th)->type_name); /* We dont want to unload function as it already exists so lets just free it ourselves */ php_w32api_free_members((*th)->member_list); efree((*th)->type_name); efree(*th); efree(th); return FAILURE; } /* Insert it into our hash table */ if(zend_hash_add( WG(types), (*th)->type_name, strlen((*th)->type_name) + 1, th, sizeof(w32api_type_handle *), NULL) != SUCCESS) { php_error( E_WARNING, "Loading of type %s failed: Could not insert type handle into hash", (*th)->type_name); /* Tidy up */ zend_hash_del(WG(types), (*th)->type_name, strlen((*th)->type_name) + 1); return FAILURE; } return SUCCESS;}/* }}} *//* {{{ php_w32api_register_callback */static int php_w32api_register_callback(char *function_definition, int function_definition_len TSRMLS_DC){ w32api_func_handle **fh; w32api_func_handle_ptr hnd; char *new_definition = NULL; fh = emalloc(sizeof(w32api_func_handle *)); *fh = NULL; new_definition = emalloc(function_definition_len + sizeof(" from cb.cb")); snprintf(new_definition, function_definition_len + sizeof(" from cb.cb"), "%s from cb.cb", function_definition); /* Parse function */ w32api_function_definition_scan_bytes(new_definition, function_definition_len + sizeof(" from cb.cb")); if(w32api_function_definition_parse((void *)&hnd) != 0) { *fh = hnd.hnd; /* Leaks */ if(*fh != NULL) efree(*fh); efree(fh); return FAILURE; } *fh = hnd.hnd; if(!*fh) return FAILURE; if(zend_hash_exists(WG(callbacks), (*fh)->function_name, strlen((*fh)->function_name) + 1)) { php_error( E_WARNING, "A callback by the name %s already has been registered, cannot redefine type", (*fh)->function_name); /* We dont want to unload function as it already exists so lets just free it ourselves */ php_w32api_free_arguments((*fh)->argument_list); efree((*fh)->return_type_name); efree((*fh)->function_name); efree(*fh); efree(fh); return FAILURE; } /* Insert it into our hash table */ if(zend_hash_add( WG(callbacks), (*fh)->function_name, strlen((*fh)->function_name) + 1, fh, sizeof(w32api_func_handle *), NULL) != SUCCESS) { php_error( E_WARNING, "Loading of function %s failed: Could not insert function handle into hash", (*fh)->function_name); /* Tidy up */ zend_hash_del(WG(callbacks), (*fh)->function_name, strlen((*fh)->function_name) + 1); return FAILURE; } return SUCCESS;}/* }}} *//* {{{ php_w32api_free_arguments * Expects one argument, the head of a list of arguments to free */static void php_w32api_free_arguments(arguments *argument_list){ if(argument_list == NULL) return; efree(argument_list->arg->argument_name); efree(argument_list->arg->type_name); efree(argument_list->arg); if(argument_list->next_arg != NULL) { php_w32api_free_arguments(argument_list->next_arg); } efree(argument_list); return;}/* }}} *//* {{{ php_w32api_free_members * Expects one argument, the head of a list of members to free */static void php_w32api_free_members(members *member_list){ if(member_list == NULL) return; efree(member_list->member->member_name); if(member_list->member->member_type_name != NULL) efree(member_list->member->member_type_name); efree(member_list->member); php_w32api_free_members(member_list->next_member); efree(member_list); return;}/* }}} *//* {{{ php_w32api_load_library * Expects two parameters, first is libraries name the second is a pointer * to a pointer to w32api_lib_handle which will recieve the resultant handle. * returns SUCCESS on success and FAILURE on failure. */static int php_w32api_load_library (char *library_name, w32api_lib_handle **lh TSRMLS_DC){ if(zend_hash_find(WG(libraries), library_name, strlen(library_name) + 1, (void **)lh) == SUCCESS) { (*lh)->ref_count++; return SUCCESS; } *lh = (w32api_lib_handle *) emalloc( sizeof(w32api_lib_handle) ); (*lh)->ref_count = 1; (*lh)->library_name = estrdup(library_name); (*lh)->handle = LoadLibrary((*lh)->library_name); if(!(*lh)->handle) /* Could not load library */ { LPVOID message_buffer; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&message_buffer, 0, NULL); /* Tidy up */ efree((*lh)->library_name); efree(*lh); efree(lh); php_error(E_WARNING, "Loading of library failed: %s", message_buffer); LocalFree(message_buffer); return FAILURE; } /* Add to hash */ if(zend_hash_add( WG(libraries), (*lh)->library_name, strlen((*lh)->library_name) + 1, *lh, sizeof(w32api_lib_handle), NULL) != SUCCESS) { php_error( E_WARNING, "Loading of library %s failed: Could not insert library handle into hash", (*lh)->library_name); /* Tidy up */ efree((*lh)->library_name); efree(*lh); efree(lh); return FAILURE; } return SUCCESS;}/* }}} *//* {{{ php_w32api_do_arg_types */static unsigned char *php_w32api_do_arg_types(arguments **argument_list){ int i = 0; int j = 0; arguments *curr_arg = NULL; unsigned char *retval = NULL; if(!(argument_list) || !(*argument_list)) return NULL; curr_arg = *argument_list; /* See how much room we need to emalloc */ while(curr_arg) { i++; if(curr_arg->arg->flags & BYREF_FORCE) { j = i; } curr_arg = curr_arg->next_arg; } /* Check to see if any args are by ref */ if( j == 0 ) return NULL; retval = (unsigned char *)emalloc(sizeof(unsigned char) * j + 1); retval[0] = (unsigned char)j; curr_arg = *argument_list; for(i=1; i <= j; i++) { retval[i] = (unsigned char)curr_arg->arg->flags; curr_arg = curr_arg->next_arg; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -