/* * pj_file_size() */ PJ_DEF(pj_off_t) pj_file_size(const char *filename) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) HANDLE hFile; DWORD sizeLo, sizeHi; pj_off_t size; PJ_ASSERT_RETURN(filename != NULL, -1); hFile = CreateFile(PJ_STRING_TO_NATIVE(filename, wfilename,sizeof(wfilename)), CONTROL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return -1; sizeLo = GetFileSize(hFile, &sizeHi); if (sizeLo == INVALID_FILE_SIZE) { DWORD dwStatus = GetLastError(); if (dwStatus != NO_ERROR) { CloseHandle(hFile); return -1; } } size = sizeHi; size = (size << 32) + sizeLo; CloseHandle(hFile); return size; }
static void write_log(int level, const char *data, int len) { PJ_DECL_UNICODE_TEMP_BUF(wdata,256); PJ_UNUSED_ARG(level); PJ_UNUSED_ARG(len); SendMessage(hwndLog, EM_REPLACESEL, FALSE, (LPARAM)PJ_STRING_TO_NATIVE(data,wdata,256)); }
static void OnError (const wchar_t *title, pj_status_t status) { char errmsg[PJ_ERR_MSG_SIZE]; PJ_DECL_UNICODE_TEMP_BUF (werrmsg, PJ_ERR_MSG_SIZE); pj_strerror (status, errmsg, sizeof (errmsg)); MessageBox (NULL, PJ_STRING_TO_NATIVE (errmsg, werrmsg, PJ_ERR_MSG_SIZE), title, MB_OK); }
/* * pj_file_delete() */ PJ_DEF(pj_status_t) pj_file_delete(const char *filename) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) PJ_ASSERT_RETURN(filename != NULL, PJ_EINVAL); if (DeleteFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename))) == FALSE) return PJ_RETURN_OS_ERROR(GetLastError()); return PJ_SUCCESS; }
/* * pj_file_move() */ PJ_DEF(pj_status_t) pj_file_move( const char *oldname, const char *newname) { PJ_DECL_UNICODE_TEMP_BUF(woldname,256) PJ_DECL_UNICODE_TEMP_BUF(wnewname,256) BOOL rc; PJ_ASSERT_RETURN(oldname!=NULL && newname!=NULL, PJ_EINVAL); #if PJ_WIN32_WINNT >= 0x0400 rc = MoveFileEx(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)), MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING); #else rc = MoveFile(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname))); #endif if (!rc) return PJ_RETURN_OS_ERROR(GetLastError()); return PJ_SUCCESS; }
PJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool, const char *pathname, unsigned flags, pj_oshandle_t *fd) { PJ_DECL_UNICODE_TEMP_BUF(wpathname,256) HANDLE hFile; DWORD dwDesiredAccess = 0; DWORD dwShareMode = 0; DWORD dwCreationDisposition = 0; DWORD dwFlagsAndAttributes = 0; PJ_UNUSED_ARG(pool); PJ_ASSERT_RETURN(pathname!=NULL, PJ_EINVAL); if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY) { dwDesiredAccess |= GENERIC_WRITE; if ((flags & PJ_O_APPEND) == PJ_O_APPEND) { dwDesiredAccess |= FILE_APPEND_DATA; } else { dwDesiredAccess &= ~(FILE_APPEND_DATA); dwCreationDisposition |= CREATE_ALWAYS; } } if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY) { dwDesiredAccess |= GENERIC_READ; if (flags == PJ_O_RDONLY) dwCreationDisposition |= OPEN_EXISTING; } if (dwDesiredAccess == 0) { pj_assert(!"Invalid file open flags"); return PJ_EINVAL; } dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; hFile = CreateFile(PJ_STRING_TO_NATIVE(pathname,wpathname,sizeof(wpathname)), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); if (hFile == INVALID_HANDLE_VALUE) { *fd = 0; return PJ_RETURN_OS_ERROR(GetLastError()); } *fd = hFile; return PJ_SUCCESS; }
/* * pj_file_exists() */ PJ_DEF(pj_bool_t) pj_file_exists(const char *filename) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) HANDLE hFile; PJ_ASSERT_RETURN(filename != NULL, 0); hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)), CONTROL_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return 0; CloseHandle(hFile); return PJ_TRUE; }
/* * pj_file_getstat() */ PJ_DEF(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) HANDLE hFile; DWORD sizeLo, sizeHi; FILETIME creationTime, accessTime, writeTime; PJ_ASSERT_RETURN(filename!=NULL && stat!=NULL, PJ_EINVAL); hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)), CONTROL_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return PJ_RETURN_OS_ERROR(GetLastError()); sizeLo = GetFileSize(hFile, &sizeHi); if (sizeLo == INVALID_FILE_SIZE) { DWORD dwStatus = GetLastError(); if (dwStatus != NO_ERROR) { CloseHandle(hFile); return PJ_RETURN_OS_ERROR(dwStatus); } } stat->size = sizeHi; stat->size = (stat->size << 32) + sizeLo; if (GetFileTime(hFile, &creationTime, &accessTime, &writeTime)==FALSE) { DWORD dwStatus = GetLastError(); CloseHandle(hFile); return PJ_RETURN_OS_ERROR(dwStatus); } CloseHandle(hFile); if (file_time_to_time_val(&creationTime, &stat->ctime) != PJ_SUCCESS) return PJ_RETURN_OS_ERROR(GetLastError()); file_time_to_time_val(&accessTime, &stat->atime); file_time_to_time_val(&writeTime, &stat->mtime); return PJ_SUCCESS; }
/* * Convert IPv4/IPv6 address to text. */ PJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src, char *dst, int size) { PJ_ASSERT_RETURN(src && dst && size, PJ_EINVAL); *dst = '\0'; PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP); #if defined(PJ_SOCK_HAS_INET_NTOP) && PJ_SOCK_HAS_INET_NTOP != 0 /* * Implementation using inet_ntop() */ if (inet_ntop(af, src, dst, size) == NULL) { pj_status_t status = pj_get_netos_error(); if (status == PJ_SUCCESS) status = PJ_EUNKNOWN; return status; } return PJ_SUCCESS; #elif defined(PJ_WIN32) || defined(PJ_WIN32_WINCE) /* * Implementation on Windows, using WSAAddressToString(). * Should also work on Unicode systems. */ { PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN) pj_sockaddr sock_addr; DWORD addr_len, addr_str_len; int rc; pj_bzero(&sock_addr, sizeof(sock_addr)); sock_addr.addr.sa_family = (pj_uint16_t)af; if (af == PJ_AF_INET) { if (size < PJ_INET_ADDRSTRLEN) return PJ_ETOOSMALL; pj_memcpy(&sock_addr.ipv4.sin_addr, src, 4); addr_len = sizeof(pj_sockaddr_in); addr_str_len = PJ_INET_ADDRSTRLEN; } else if (af == PJ_AF_INET6) { if (size < PJ_INET6_ADDRSTRLEN) return PJ_ETOOSMALL; pj_memcpy(&sock_addr.ipv6.sin6_addr, src, 16); addr_len = sizeof(pj_sockaddr_in6); addr_str_len = PJ_INET6_ADDRSTRLEN; } else { pj_assert(!"Unsupported address family"); return PJ_EAFNOTSUP; } #if PJ_NATIVE_STRING_IS_UNICODE rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len, NULL, wtempaddr, &addr_str_len); if (rc == 0) { pj_unicode_to_ansi(wtempaddr, wcslen(wtempaddr), dst, size); } #else rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len, NULL, dst, &addr_str_len); #endif if (rc != 0) { pj_status_t status = pj_get_netos_error(); if (status == PJ_SUCCESS) status = PJ_EUNKNOWN; return status; } return PJ_SUCCESS; } #elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0 /* IPv6 support is disabled, just return error without raising assertion */ return PJ_EIPV6NOTSUP; #else pj_assert(!"Not supported"); return PJ_EIPV6NOTSUP; #endif }
/* * Convert text to IPv4/IPv6 address. */ PJ_DEF(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst) { char tempaddr[PJ_INET6_ADDRSTRLEN]; PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP); PJ_ASSERT_RETURN(src && src->slen && dst, PJ_EINVAL); /* Initialize output with PJ_IN_ADDR_NONE for IPv4 (to be * compatible with pj_inet_aton() */ if (af==PJ_AF_INET) { ((pj_in_addr*)dst)->s_addr = PJ_INADDR_NONE; } /* Caution: * this function might be called with cp->slen >= 46 * (i.e. when called with hostname to check if it's an IP addr). */ if (src->slen >= PJ_INET6_ADDRSTRLEN) { return PJ_ENAMETOOLONG; } pj_memcpy(tempaddr, src->ptr, src->slen); tempaddr[src->slen] = '\0'; #if defined(PJ_SOCK_HAS_INET_PTON) && PJ_SOCK_HAS_INET_PTON != 0 /* * Implementation using inet_pton() */ if (inet_pton(af, tempaddr, dst) != 1) { pj_status_t status = pj_get_netos_error(); if (status == PJ_SUCCESS) status = PJ_EUNKNOWN; return status; } return PJ_SUCCESS; #elif defined(PJ_WIN32) || defined(PJ_WIN32_WINCE) /* * Implementation on Windows, using WSAStringToAddress(). * Should also work on Unicode systems. */ { PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN) pj_sockaddr sock_addr; int addr_len = sizeof(sock_addr); int rc; sock_addr.addr.sa_family = (pj_uint16_t)af; rc = WSAStringToAddress( PJ_STRING_TO_NATIVE(tempaddr,wtempaddr,sizeof(wtempaddr)), af, NULL, (LPSOCKADDR)&sock_addr, &addr_len); if (rc != 0) { /* If you get rc 130022 Invalid argument (WSAEINVAL) with IPv6, * check that you have IPv6 enabled (install it in the network * adapter). */ pj_status_t status = pj_get_netos_error(); if (status == PJ_SUCCESS) status = PJ_EUNKNOWN; return status; } if (sock_addr.addr.sa_family == PJ_AF_INET) { pj_memcpy(dst, &sock_addr.ipv4.sin_addr, 4); return PJ_SUCCESS; } else if (sock_addr.addr.sa_family == PJ_AF_INET6) { pj_memcpy(dst, &sock_addr.ipv6.sin6_addr, 16); return PJ_SUCCESS; } else { pj_assert(!"Shouldn't happen"); return PJ_EBUG; } } #elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0 /* IPv6 support is disabled, just return error without raising assertion */ return PJ_EIPV6NOTSUP; #else pj_assert(!"Not supported"); return PJ_EIPV6NOTSUP; #endif }
/* * platform_strerror() * * Platform specific error message. This file is called by pj_strerror() * in errno.c */ int platform_strerror( pj_os_err_type os_errcode, char *buf, pj_size_t bufsize) { pj_size_t len = 0; PJ_DECL_UNICODE_TEMP_BUF(wbuf,128); pj_assert(buf != NULL); pj_assert(bufsize >= 0); /* * MUST NOT check stack here. * This function might be called from PJ_CHECK_STACK() itself! //PJ_CHECK_STACK(); */ if (!len) { #if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING!=0) int i; for (i = 0; gaErrorList[i].msg; ++i) { if (gaErrorList[i].code == os_errcode) { len = strlen(gaErrorList[i].msg); if ((pj_size_t)len >= bufsize) { len = bufsize-1; } pj_memcpy(buf, gaErrorList[i].msg, len); buf[len] = '\0'; break; } } #endif /* PJ_HAS_ERROR_STRING */ } if (!len) { #if PJ_NATIVE_STRING_IS_UNICODE len = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, os_errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), wbuf, sizeof(wbuf), NULL); if (len) { pj_unicode_to_ansi(wbuf, len, buf, bufsize); } #else len = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, os_errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (int)bufsize, NULL); buf[bufsize-1] = '\0'; #endif if (len) { /* Remove trailing newlines. */ while (len && (buf[len-1] == '\n' || buf[len-1] == '\r')) { buf[len-1] = '\0'; --len; } } } if (!len) { len = pj_ansi_snprintf( buf, bufsize, "Win32 error code %u", (unsigned)os_errcode); if (len < 0 || len >= (int)bufsize) len = bufsize-1; buf[len] = '\0'; } return (int)len; }
PJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool, const char *pathname, unsigned flags, pj_oshandle_t *fd) { PJ_DECL_UNICODE_TEMP_BUF(wpathname,256) HANDLE hFile; DWORD dwDesiredAccess = 0; DWORD dwShareMode = 0; DWORD dwCreationDisposition = 0; DWORD dwFlagsAndAttributes = 0; PJ_UNUSED_ARG(pool); PJ_ASSERT_RETURN(pathname!=NULL, PJ_EINVAL); if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY) { dwDesiredAccess |= GENERIC_WRITE; if ((flags & PJ_O_APPEND) == PJ_O_APPEND) { #if !defined(PJ_WIN32_WINCE) || !PJ_WIN32_WINCE /* FILE_APPEND_DATA is invalid on WM2003 and WM5, but it seems * to be working on WM6. All are tested on emulator though. * Removing this also seem to work (i.e. data is appended), so * I guess this flag is "optional". * See http://trac.pjsip.org/repos/ticket/825 */ dwDesiredAccess |= FILE_APPEND_DATA; #endif dwCreationDisposition |= OPEN_ALWAYS; } else { dwDesiredAccess &= ~(FILE_APPEND_DATA); dwCreationDisposition |= CREATE_ALWAYS; } } if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY) { dwDesiredAccess |= GENERIC_READ; if (flags == PJ_O_RDONLY) dwCreationDisposition |= OPEN_EXISTING; } if (dwDesiredAccess == 0) { pj_assert(!"Invalid file open flags"); return PJ_EINVAL; } dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; hFile = CreateFile(PJ_STRING_TO_NATIVE(pathname,wpathname,sizeof(wpathname)), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); if (hFile == INVALID_HANDLE_VALUE) { *fd = 0; return PJ_RETURN_OS_ERROR(GetLastError()); } if ((flags & PJ_O_APPEND) == PJ_O_APPEND) { pj_status_t status; status = pj_file_setpos(hFile, 0, PJ_SEEK_END); if (status != PJ_SUCCESS) { pj_file_close(hFile); return status; } } *fd = hFile; return PJ_SUCCESS; }