bool VirtualDiscFileSystem::RmDir(const std::string &dirname) { ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Cannot remove directory on virtual disc"); return false; }
/*---------------------------------------------------------------------------*/ struct xio_server *xio_bind(struct xio_context *ctx, struct xio_session_ops *ops, const char *uri, uint16_t *src_port, uint32_t session_flags, void *cb_private_data) { struct xio_server *server; int retval; int backlog = 4; if (!ctx || !ops || !uri) { ERROR_LOG("invalid parameters ctx:%p, ops:%p, uri:%p\n", ctx, ops, uri); xio_set_error(EINVAL); return NULL; } TRACE_LOG("bind to %s\n", uri); /* create the server */ server = (struct xio_server *) kcalloc(1, sizeof(struct xio_server), GFP_KERNEL); if (!server) { xio_set_error(ENOMEM); return NULL; } kref_init(&server->kref); /* fill server data*/ server->ctx = ctx; server->cb_private_data = cb_private_data; server->uri = kstrdup(uri, GFP_KERNEL); server->session_flags = session_flags; memcpy(&server->ops, ops, sizeof(*ops)); XIO_OBSERVER_INIT(&server->observer, server, xio_on_nexus_event); XIO_OBSERVABLE_INIT(&server->nexus_observable, server); server->listener = xio_nexus_open(ctx, uri, NULL, 0, 0, NULL); if (!server->listener) { ERROR_LOG("failed to create connection\n"); goto cleanup; } retval = xio_nexus_listen(server->listener, uri, src_port, backlog); if (retval != 0) { ERROR_LOG("connection listen failed\n"); goto cleanup1; } xio_nexus_set_server(server->listener, server); xio_idr_add_uobj(usr_idr, server, "xio_server"); return server; cleanup1: xio_nexus_close(server->listener, NULL); cleanup: kfree(server->uri); kfree(server); return NULL; }
static int __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSize, int waitMode, u32 resultAddr, u32 timeoutPtr, bool cbEnabled, bool poll, bool &needsResched, bool &needsWait) { u32 curReceiveAddr = receiveBufAddr; SceUID uid = m->GetUID(); // MsgPipe buffer size is 0, receiving directly from waiting send threads if (m->nmp.bufSize == 0) { m->SortSendThreads(); // While they're still sending waiting threads (which can send data) while (!m->sendWaitingThreads.empty() && receiveSize != 0) { MsgPipeWaitingThread *thread = &m->sendWaitingThreads.front(); // For send threads, "freeSize" is "free to be read". u32 bytesToReceive = std::min(thread->freeSize, receiveSize); if (bytesToReceive > 0) { thread->ReadBuffer(curReceiveAddr, bytesToReceive); receiveSize -= bytesToReceive; curReceiveAddr += bytesToReceive; if (thread->freeSize == 0 || thread->waitMode == SCE_KERNEL_MPW_ASAP) { thread->Complete(uid, 0); m->sendWaitingThreads.erase(m->sendWaitingThreads.begin()); needsResched = true; thread = NULL; } } } // All data hasn't been received and (mode isn't ASAP or nothing was received) if (receiveSize != 0 && (waitMode != SCE_KERNEL_MPW_ASAP || curReceiveAddr == receiveBufAddr)) { if (poll) { // Generally, result is not updated in this case. But for a 0 size buffer in ASAP mode, it is. if (Memory::IsValidAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP) Memory::Write_U32(curReceiveAddr - receiveBufAddr, resultAddr); return SCE_KERNEL_ERROR_MPP_EMPTY; } else { m->AddReceiveWaitingThread(__KernelGetCurThread(), curReceiveAddr, receiveSize, waitMode, resultAddr); needsWait = true; return 0; } } } // Getting data from the MsgPipe buffer else { if (receiveSize > (u32) m->nmp.bufSize) { ERROR_LOG(SCEKERNEL, "__KernelReceiveMsgPipe(%d): size %d too large for buffer", uid, receiveSize); return SCE_KERNEL_ERROR_ILLEGAL_SIZE; } while (m->GetUsedSize() > 0) { u32 bytesToReceive = std::min(receiveSize, m->GetUsedSize()); if (bytesToReceive != 0) { Memory::Memcpy(curReceiveAddr, m->buffer, bytesToReceive); m->nmp.freeSize += bytesToReceive; memmove(Memory::GetPointer(m->buffer), Memory::GetPointer(m->buffer) + bytesToReceive, m->GetUsedSize()); curReceiveAddr += bytesToReceive; receiveSize -= bytesToReceive; m->CheckSendThreads(); } else break; } if (receiveSize != 0 && (waitMode != SCE_KERNEL_MPW_ASAP || curReceiveAddr == receiveBufAddr)) { if (poll) return SCE_KERNEL_ERROR_MPP_EMPTY; else { m->AddReceiveWaitingThread(__KernelGetCurThread(), curReceiveAddr, receiveSize, waitMode, resultAddr); needsWait = true; return 0; } } } if (Memory::IsValidAddress(resultAddr)) Memory::Write_U32(curReceiveAddr - receiveBufAddr, resultAddr); return 0; }
int create_lost_req(xmlNode* location, char* service, loc_fmt d_loc_fmt, str* lost_req){ xmlDocPtr doc= NULL; xmlNodePtr root_node; xmlNodePtr loc_node = NULL, loc_copy=NULL; char * id = "1234"; char * profile; xmlChar * req_body = NULL; int req_len = 0; if(d_loc_fmt == ERR_LOC){ ERROR_LOG("cannot use location with errornous format\n"); goto error; } profile = map_profile[d_loc_fmt]; /* creating the xml doc for the LoST message*/ doc= xmlNewDoc(BAD_CAST "1.0"); if(doc== NULL){ ERROR_LOG("when creating new xml doc\n"); goto error; } root_node = xmlNewNode(NULL, BAD_CAST LOST_FIND_SERVICE_CMD); if(root_node==0){ ERROR_LOG("when adding new node %s\n", LOST_FIND_SERVICE_CMD); goto error; } xmlDocSetRootElement(doc, root_node); if(!xmlNewNs(root_node, BAD_CAST LOST_NS_HREF, NULL)){ ERROR_LOG("could not add the namespace %s to the root node\n", LOST_NS_HREF); goto error; } loc_node = xmlNewNode(NULL, BAD_CAST LOST_LOCATION_NODE); if(!loc_node){ ERROR_LOG("when creating new node %s\n", LOST_LOCATION_NODE); goto error; } if(!xmlNewProp(loc_node, BAD_CAST LOST_ID_PROP , BAD_CAST id)){ ERROR_LOG("could not add the property %s\n", LOST_ID_PROP); goto error; } if(!xmlNewProp(loc_node, BAD_CAST LOST_PROFILE_PROP , BAD_CAST profile)){ ERROR_LOG("could not add the property %s\n", LOST_ID_PROP); goto error; } //do a recursive copy of the location information loc_copy = xmlCopyNode(location, 1); if(!loc_copy){ ERROR_LOG("could not duplicate the location information node\n"); goto error; } if(!xmlAddChild(loc_node, loc_copy)){ ERROR_LOG("could not add the location information to the location node\n"); goto error; } loc_copy = NULL; if(!xmlAddChild(root_node, loc_node)){ ERROR_LOG("could not add the %s node to root\n", LOST_LOCATION_NODE); goto error; } loc_node = NULL; if(!xmlNewChild(root_node, NULL, BAD_CAST LOST_SERVICE_NODE, BAD_CAST service)){ ERROR_LOG("could not add the %s node to root\n", LOST_SERVICE_NODE); goto error; } //print_element_names(root_node); xmlDocDumpFormatMemoryEnc(doc, &req_body, &req_len, LOST_XML_ENC, 1); lost_req->s = (char*) req_body; lost_req->len = req_len; if(!lost_req->s || !lost_req->len){ ERROR_LOG("could not output the xml document\n"); goto error; } //DEBUG_LOG("lost request: %.*s\n", lost_req->len, lost_req->s); xmlFreeDoc(doc); return 0; error: if(loc_node) xmlFreeNode(loc_node); if(loc_copy) xmlFreeNode(loc_copy); if(doc) xmlFreeDoc(doc); return 1; }
/* Get the value of the returned psap URI from a LoST response * @param root - the root of an parsed xml LoST response other than error or redirect * @param exp_type - used to get the type of mapping: no-cache, no-expiration or with an expiration date * @param exp_timestamp- used to get the timestamp of when the mapping will expire * @param parsed_uri- used to get the parsed uri * @returns the name of the psap uri in shm memory */ str get_mapped_psap(xmlNode* root, expire_type * exp_type, time_t* exp_timestamp, struct sip_uri* parsed_uri){ xmlNode * mapping, *uri; xmlAttr * expires_attr; xmlChar* content; str uri_str, shm_uri={NULL, 0}; char * expires_str; if(!(mapping = child_named_node(root, LOST_MAPPING_NODE_NAME))){ ERROR_LOG("Could not find a mapping element in the LoST response\n"); return shm_uri; } if(!(uri = child_named_node(mapping, LOST_URI_NODE_NAME))){ ERROR_LOG("Could not find any uri child on the mapping element in the LoST response\n"); return shm_uri; } get_uri: content = xmlNodeGetContent((xmlNodePtr)uri); uri_str.s = (char*)content; if(!uri_str.s || (uri_str.s[0] == '\0')){ ERROR_LOG("Could not get the content of the uri element\n"); return shm_uri; } uri_str.len = strlen(uri_str.s); DEBUG_LOG("Found a uri: %.*s\n", uri_str.len, uri_str.s); //check if the uri is a well formed sip uri if((parse_uri(uri_str.s, uri_str.len, parsed_uri)<0) || ((parsed_uri->type != SIP_URI_T) && (parsed_uri->type != SIPS_URI_T))){ ERROR_LOG("the URI %.*s is no SIP/SIPS URI, for the moment only SIP/SIPS URIs are supported\n", uri_str.len, uri_str.s); if(!(uri = sibling_named_node(uri, LOST_URI_NODE_NAME))){ ERROR_LOG("Could not find any other uri child on the mapping element in the LoST response\n"); return shm_uri; } goto get_uri; } if(!(expires_attr = get_attr(mapping, LOST_EXPIRES_ATTR_NAME))){ ERROR_LOG("Could not find an expires attr of mapping element in the LoST response\n"); return shm_uri; } expires_str = (char*)expires_attr->children->content; if(!expires_str || !strlen(expires_str)){ ERROR_LOG("Expires attribute with null content\n"); return shm_uri; } DEBUG_LOG("expires is %s\n", expires_str); //get expiration time ISO 8601 if(get_time(expires_str, exp_type, exp_timestamp)){ ERROR_LOG("Invalid value for the attribute expires %s\n", expires_str); return shm_uri; } //copy in shm memory shm_uri.s = (char*)cds_malloc(uri_str.len*sizeof(char)); if(!shm_uri.s){ ERROR_LOG("Out of shm memory\n"); }else{ memcpy(shm_uri.s, uri_str.s, uri_str.len*sizeof(char)); shm_uri.len = uri_str.len; } xmlFree(content); return shm_uri; }
void StateManager::Apply() { if (!m_blendStates.empty()) { if (m_currentBlendState != m_blendStates.top().get()) { m_currentBlendState = (ID3D11BlendState*)m_blendStates.top().get(); D3D::context->OMSetBlendState(m_currentBlendState, nullptr, 0xFFFFFFFF); } } else ERROR_LOG(VIDEO, "Tried to apply without blend state!"); if (!m_depthStates.empty()) { if (m_currentDepthState != m_depthStates.top().get()) { m_currentDepthState = (ID3D11DepthStencilState*)m_depthStates.top().get(); D3D::context->OMSetDepthStencilState(m_currentDepthState, 0); } } else ERROR_LOG(VIDEO, "Tried to apply without depth state!"); if (!m_rasterizerStates.empty()) { if (m_currentRasterizerState != m_rasterizerStates.top().get()) { m_currentRasterizerState = (ID3D11RasterizerState*)m_rasterizerStates.top().get(); D3D::context->RSSetState(m_currentRasterizerState); } } else ERROR_LOG(VIDEO, "Tried to apply without rasterizer state!"); if (!m_dirtyFlags) { return; } if (m_dirtyFlags & DirtyFlag_Constants) { if (use_partial_buffer_update) { if (m_dirtyFlags & DirtyFlag_PixelConstants) { if (m_pending.pixelConstantsSize[0] == 0 && m_pending.pixelConstantsSize[1] == 0) { D3D::context->PSSetConstantBuffers(0, m_pending.pixelConstants[1] ? 2 : 1, m_pending.pixelConstants); } else { D3D::context1->PSSetConstantBuffers1(0, m_pending.pixelConstants[1] ? 2 : 1, m_pending.pixelConstants, m_pending.pixelConstantsOffset, m_pending.pixelConstantsSize); } m_current.pixelConstants[0] = m_pending.pixelConstants[0]; m_current.pixelConstantsOffset[0] = m_pending.pixelConstantsOffset[0]; m_current.pixelConstantsSize[0] = m_pending.pixelConstantsSize[0]; m_current.pixelConstants[1] = m_pending.pixelConstants[1]; m_current.pixelConstantsOffset[1] = m_pending.pixelConstantsOffset[1]; m_current.pixelConstantsSize[1] = m_pending.pixelConstantsSize[1]; } if (m_dirtyFlags & DirtyFlag_VertexConstants) { if (m_pending.vertexConstantsSize == 0) { D3D::context->VSSetConstantBuffers(0, 1, &m_pending.vertexConstants); } else { D3D::context1->VSSetConstantBuffers1(0, 1, &m_pending.vertexConstants, &m_pending.vertexConstantsOffset, &m_pending.vertexConstantsSize); } m_current.vertexConstants = m_pending.vertexConstants; m_current.vertexConstantsOffset = m_pending.vertexConstantsOffset; m_current.vertexConstantsSize = m_pending.vertexConstantsSize; } if (m_dirtyFlags & DirtyFlag_GeometryConstants) { if (m_pending.geometryConstantsSize == 0) { D3D::context->GSSetConstantBuffers(0, 1, &m_pending.geometryConstants); } else { D3D::context1->GSSetConstantBuffers1(0, 1, &m_pending.geometryConstants, &m_pending.geometryConstantsOffset, &m_pending.geometryConstantsSize); } m_current.geometryConstants = m_pending.geometryConstants; m_current.geometryConstantsOffset = m_pending.geometryConstantsOffset; m_current.geometryConstantsSize = m_pending.geometryConstantsSize; } if (m_dirtyFlags & DirtyFlag_HullDomainConstants) { if (g_ActiveConfig.backend_info.bSupportsTessellation) { if (m_pending.hulldomainConstantsSize == 0) { D3D::context->HSSetConstantBuffers(0, 3, m_pending.hulldomainConstants); D3D::context->DSSetConstantBuffers(0, 3, m_pending.hulldomainConstants); } else { D3D::context1->HSSetConstantBuffers1(0, 3, m_pending.hulldomainConstants, m_pending.hulldomainConstantsOffset, m_pending.hulldomainConstantsSize); D3D::context1->DSSetConstantBuffers1(0, 3, m_pending.hulldomainConstants, m_pending.hulldomainConstantsOffset, m_pending.hulldomainConstantsSize); } } m_current.hulldomainConstants[0] = m_pending.hulldomainConstants[0]; m_current.hulldomainConstantsOffset[0] = m_pending.hulldomainConstantsOffset[0]; m_current.hulldomainConstantsSize[0] = m_pending.hulldomainConstantsSize[0]; m_current.hulldomainConstants[1] = m_pending.hulldomainConstants[1]; m_current.hulldomainConstantsOffset[1] = m_pending.hulldomainConstantsOffset[1]; m_current.hulldomainConstantsSize[1] = m_pending.hulldomainConstantsSize[1]; m_current.hulldomainConstants[2] = m_pending.hulldomainConstants[2]; m_current.hulldomainConstantsOffset[2] = m_pending.hulldomainConstantsOffset[2]; m_current.hulldomainConstantsSize[2] = m_pending.hulldomainConstantsSize[2]; } } else { if (m_dirtyFlags & DirtyFlag_PixelConstants) { D3D::context->PSSetConstantBuffers(0, m_pending.pixelConstants[1] ? 2 : 1, m_pending.pixelConstants); m_current.pixelConstants[0] = m_pending.pixelConstants[0]; m_current.pixelConstants[1] = m_pending.pixelConstants[1]; } if (m_dirtyFlags & DirtyFlag_VertexConstants) { D3D::context->VSSetConstantBuffers(0, 1, &m_pending.vertexConstants); m_current.vertexConstants = m_pending.vertexConstants; } if (m_dirtyFlags & DirtyFlag_GeometryConstants) { D3D::context->GSSetConstantBuffers(0, 1, &m_pending.geometryConstants); m_current.geometryConstants = m_pending.geometryConstants; } if (m_dirtyFlags & DirtyFlag_HullDomainConstants) { if (g_ActiveConfig.backend_info.bSupportsTessellation) { D3D::context->HSSetConstantBuffers(0, 3, m_pending.hulldomainConstants); D3D::context->DSSetConstantBuffers(0, 3, m_pending.hulldomainConstants); } m_current.hulldomainConstants[0] = m_pending.hulldomainConstants[0]; m_current.hulldomainConstants[1] = m_pending.hulldomainConstants[1]; m_current.hulldomainConstants[2] = m_pending.hulldomainConstants[2]; } } } if (m_dirtyFlags & (DirtyFlag_Buffers | DirtyFlag_InputAssembler)) { if (m_dirtyFlags & DirtyFlag_VertexBuffer) { D3D::context->IASetVertexBuffers(0, 1, &m_pending.vertexBuffer, &m_pending.vertexBufferStride, &m_pending.vertexBufferOffset); m_current.vertexBuffer = m_pending.vertexBuffer; m_current.vertexBufferStride = m_pending.vertexBufferStride; m_current.vertexBufferOffset = m_pending.vertexBufferOffset; } if (m_dirtyFlags & DirtyFlag_IndexBuffer) { D3D::context->IASetIndexBuffer(m_pending.indexBuffer, DXGI_FORMAT_R16_UINT, 0); m_current.indexBuffer = m_pending.indexBuffer; } if (m_current.topology != m_pending.topology) { D3D::context->IASetPrimitiveTopology(m_pending.topology); m_current.topology = m_pending.topology; } if (m_current.inputLayout != m_pending.inputLayout) { D3D::context->IASetInputLayout(m_pending.inputLayout); m_current.inputLayout = m_pending.inputLayout; } } u32 dirty_elements = m_dirtyFlags & DirtyFlag_Textures; if (dirty_elements) { while (dirty_elements) { unsigned long index; _BitScanForward(&index, dirty_elements); D3D::context->PSSetShaderResources(index, 1, &m_pending.textures[index]); D3D::context->DSSetShaderResources(index, 1, &m_pending.textures[index]); m_current.textures[index] = m_pending.textures[index]; dirty_elements &= ~(1 << index); } } dirty_elements = (m_dirtyFlags & DirtyFlag_Samplers) >> 8; if (dirty_elements) { while (dirty_elements) { unsigned long index; _BitScanForward(&index, dirty_elements); D3D::context->PSSetSamplers(index, 1, &m_pending.samplers[index]); D3D::context->DSSetSamplers(index, 1, &m_pending.samplers[index]); m_current.samplers[index] = m_pending.samplers[index]; dirty_elements &= ~(1 << index); } } if (m_dirtyFlags & DirtyFlag_Shaders) { if (m_current.pixelShader != m_pending.pixelShader) { D3D::context->PSSetShader(m_pending.pixelShader, nullptr, 0); m_current.pixelShader = m_pending.pixelShader; } if (m_current.vertexShader != m_pending.vertexShader) { D3D::context->VSSetShader(m_pending.vertexShader, nullptr, 0); m_current.vertexShader = m_pending.vertexShader; } if (m_current.geometryShader != m_pending.geometryShader) { D3D::context->GSSetShader(m_pending.geometryShader, nullptr, 0); m_current.geometryShader = m_pending.geometryShader; } if (g_ActiveConfig.backend_info.bSupportsTessellation) { if (m_current.hullShader != m_pending.hullShader) { D3D::context->HSSetShader(m_pending.hullShader, nullptr, 0); m_current.hullShader = m_pending.hullShader; } if (m_current.domainShader != m_pending.domainShader) { D3D::context->DSSetShader(m_pending.domainShader, nullptr, 0); m_current.domainShader = m_pending.domainShader; } } } m_dirtyFlags = 0; }
/** * @brief standard NPE update handler * * @param portID id of the port to be updated * @param type record type to be pushed during this update * * The NPE update handler manages updating the NPE databases * given a certain record type. * * @internal */ IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type) { UINT32 epDelta, blockCount; IxNpeMhMessage message; UINT32 treeSize = 0; PortInfo *port = &ixEthDBPortInfo[portID]; /* size selection and type check */ if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD) { treeSize = FULL_ELT_BYTE_SIZE; } else if (type == IX_ETH_DB_FIREWALL_RECORD) { treeSize = FULL_FW_BYTE_SIZE; } else if (type == IX_ETH_DB_MASKED_FIREWALL_RECORD) { treeSize = FULL_FW_M_BYTE_SIZE; } else { return IX_ETH_DB_INVALID_ARG; } /* serialize tree into memory */ ixEthDBNPETreeWrite(type, treeSize, port->updateMethod.npeUpdateZone, port->updateMethod.searchTree, &epDelta, &blockCount); /* free internal copy */ if (port->updateMethod.searchTree != NULL) { ixEthDBFreeMacTreeNode(port->updateMethod.searchTree); } /* forget last used search tree */ port->updateMethod.searchTree = NULL; port->updateMethod.searchTreePendingWrite = FALSE; /* dependending on the update type we do different things */ if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD) { IX_STATUS result; FILL_SETMACADDRESSDATABASE_MSG(message, IX_ETHNPE_PHYSICAL_ID_TO_NODE_LOGICAL_ID(portID), epDelta, blockCount, IX_OSAL_MMU_VIRT_TO_PHYS(port->updateMethod.npeUpdateZone)); IX_ETHDB_SEND_NPE_MSG(IX_ETHNPE_PHYSICAL_ID_TO_NODE(portID), message, result); if (result == IX_SUCCESS) { IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Finished downloading NPE tree on port %d\n", portID); } else { ixEthDBPortInfo[portID].agingEnabled = FALSE; ixEthDBPortInfo[portID].updateMethod.updateEnabled = FALSE; ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE; ERROR_LOG("EthDB: (PortUpdate) disabling aging and updates on port %d (assumed dead)\n", portID); ixEthDBDatabaseClear(portID, IX_ETH_DB_ALL_RECORD_TYPES); return IX_ETH_DB_FAIL; } return IX_ETH_DB_SUCCESS; } else if (type & IX_ETH_DB_FIREWALL_RECORD) { return ixEthDBFirewallUpdate(portID, port->updateMethod.npeUpdateZone, epDelta); } return IX_ETH_DB_INVALID_ARG; }
void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root, size_t level) { for (u32 secnum = startsector, endsector = dirsize/2048 + startsector; secnum < endsector; ++secnum) { u8 theSector[2048]; blockDevice->ReadBlock(secnum, theSector); for (int offset = 0; offset < 2048; ) { DirectoryEntry &dir = *(DirectoryEntry *)&theSector[offset]; u8 sz = theSector[offset]; // Nothing left in this sector. There might be more in the next one. if (sz == 0) break; const int IDENTIFIER_OFFSET = 33; if (offset + IDENTIFIER_OFFSET + dir.identifierLength > 2048) { ERROR_LOG(FILESYS, "Directory entry crosses sectors, corrupt iso?"); return; } offset += dir.size; bool isFile = (dir.flags & 2) ? false : true; bool relative; TreeEntry *e = new TreeEntry(); if (dir.identifierLength == 1 && (dir.firstIdChar == '\x00' || dir.firstIdChar == '.')) { e->name = "."; relative = true; } else if (dir.identifierLength == 1 && dir.firstIdChar == '\x01') { e->name = ".."; relative = true; } else { e->name = std::string((char *)&dir.firstIdChar, dir.identifierLength); relative = false; } e->size = dir.dataLength(); e->startingPosition = dir.firstDataSector() * 2048; e->isDirectory = !isFile; e->flags = dir.flags; e->parent = root; // Let's not excessively spam the log - I commented this line out. //DEBUG_LOG(FILESYS, "%s: %s %08x %08x %i", e->isDirectory?"D":"F", e->name.c_str(), dir.firstDataSectorLE, e->startingPosition, e->startingPosition); if (e->isDirectory && !relative) { if (dir.firstDataSector() == startsector) { ERROR_LOG(FILESYS, "WARNING: Appear to have a recursive file system, breaking recursion"); } else { bool doRecurse = true; if (!restrictTree.empty()) doRecurse = level < restrictTree.size() && restrictTree[level] == e->name; if (doRecurse) ReadDirectory(dir.firstDataSector(), dir.dataLength(), e, level + 1); else continue; } } root->children.push_back(e); } } }
ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(std::string path, bool catchError) { if (path.length() == 0) { //Ah, the device! "umd0:" return &entireISO; } if (path.substr(0,2) == "./") path.erase(0,2); if (path[0] == '/') path.erase(0,1); if (path == "umd0") return &entireISO; TreeEntry *e = treeroot; if (path.length() == 0) return e; while (true) { TreeEntry *ne = 0; std::string name = ""; if (path.length()>0) { for (size_t i=0; i<e->children.size(); i++) { std::string n = (e->children[i]->name); for (size_t j = 0; j < n.size(); j++) { n[j] = tolower(n[j]); } std::string curPath = path.substr(0, path.find_first_of('/')); for (size_t j = 0; j < curPath.size(); j++) { curPath[j] = tolower(curPath[j]); } if (curPath == n) { //yay we got it ne = e->children[i]; name = n; break; } } } if (ne) { e = ne; size_t l = name.length(); path.erase(0, l); if (path.length() == 0 || (path.length()==1 && path[0] == '/')) return e; path.erase(0, 1); while (path[0] == '/') path.erase(0, 1); } else { if (catchError) { ERROR_LOG(FILESYS,"File %s not found", path.c_str()); } return 0; } } }
// A convoluted way of checking if a device is a Wii Balance Board and if it is a connectible Wiimote. // Because nothing on Windows should be easy. // (We can't seem to easily identify the Bluetooth device an HID device belongs to...) void WiimoteScanner::CheckDeviceType(std::basic_string<TCHAR> &devicepath, bool &real_wiimote, bool &is_bb) { real_wiimote = false; is_bb = false; #ifdef SHARE_WRITE_WIIMOTES std::lock_guard<std::mutex> lk(g_connected_wiimotes_lock); if (g_connected_wiimotes.count(devicepath) != 0) return; #endif HANDLE dev_handle = CreateFile(devicepath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr); if (dev_handle == INVALID_HANDLE_VALUE) return; // enable to only check for official nintendo wiimotes/bb's bool check_vidpid = false; HIDD_ATTRIBUTES attrib; attrib.Size = sizeof(attrib); if (!check_vidpid || (pHidD_GetAttributes(dev_handle, &attrib) && (attrib.VendorID == 0x057e) && (attrib.ProductID == 0x0306))) { // max_cycles insures we are never stuck here due to bad coding... int max_cycles = 20; u8 buf[MAX_PAYLOAD] = {0}; u8 const req_status_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REQUEST_STATUS, 0}; // The new way to initialize the extension is by writing 0x55 to 0x(4)A400F0, then writing 0x00 to 0x(4)A400FB // 52 16 04 A4 00 F0 01 55 // 52 16 04 A4 00 FB 01 00 u8 const disable_enc_pt1_report[MAX_PAYLOAD] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_WRITE_DATA, 0x04, 0xa4, 0x00, 0xf0, 0x01, 0x55}; u8 const disable_enc_pt2_report[MAX_PAYLOAD] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_WRITE_DATA, 0x04, 0xa4, 0x00, 0xfb, 0x01, 0x00}; CheckDeviceType_Write(dev_handle, disable_enc_pt1_report, sizeof(disable_enc_pt1_report), 1); CheckDeviceType_Write(dev_handle, disable_enc_pt2_report, sizeof(disable_enc_pt2_report), 1); int rc = CheckDeviceType_Write(dev_handle, req_status_report, sizeof(req_status_report), 1); while (rc > 0 && --max_cycles > 0) { if ((rc = CheckDeviceType_Read(dev_handle, buf, 1)) <= 0) { // DEBUG_LOG(WIIMOTE, "CheckDeviceType: Read failed..."); break; } switch (buf[1]) { case WM_STATUS_REPORT: { real_wiimote = true; // DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Status Report"); wm_status_report * wsr = (wm_status_report*)&buf[2]; if (wsr->extension) { // Wiimote with extension, we ask it what kind. u8 read_ext[MAX_PAYLOAD] = {0}; read_ext[0] = WM_SET_REPORT | WM_BT_OUTPUT; read_ext[1] = WM_READ_DATA; // Extension type register. *(u32*)&read_ext[2] = Common::swap32(0x4a400fa); // Size. *(u16*)&read_ext[6] = Common::swap16(6); rc = CheckDeviceType_Write(dev_handle, read_ext, 8, 1); } else { // Normal Wiimote, exit while and be happy. rc = -1; } break; } case WM_ACK_DATA: { real_wiimote = true; //wm_acknowledge * wm = (wm_acknowledge*)&buf[2]; //DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Ack Error: %X ReportID: %X", wm->errorID, wm->reportID); break; } case WM_READ_DATA_REPLY: { // DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Data Reply"); wm_read_data_reply * wrdr = (wm_read_data_reply*)&buf[2]; // Check if it has returned what we asked. if (Common::swap16(wrdr->address) == 0x00fa) { real_wiimote = true; // 0x020420A40000ULL means balance board. u64 ext_type = (*(u64*)&wrdr->data[0]); // DEBUG_LOG(WIIMOTE, // "CheckDeviceType: GOT EXT TYPE %llX", // ext_type); is_bb = (ext_type == 0x020420A40000ULL); } else { ERROR_LOG(WIIMOTE, "CheckDeviceType: GOT UNREQUESTED ADDRESS %X", Common::swap16(wrdr->address)); } // force end rc = -1; break; } default: { // We let read try again incase there is another packet waiting. // DEBUG_LOG(WIIMOTE, "CheckDeviceType: GOT UNKNOWN REPLY: %X", buf[1]); break; } } } } CloseHandle(dev_handle); }
int main(int argc, char **argv) { msk_trans_t *trans, *listen_trans; msk_trans_attr_t trans_attr; char errbuf[PCAP_ERRBUF_SIZE]; char *pcap_file; pcap_t *pcap; size_t block_size = 0; uint32_t recv_num = 0; int banner = 0; int i, rc; uint8_t *rdmabuf; struct ibv_mr *mr; msk_data_t *data, *wdata; struct privatedata priv; // argument handling int option_index = 0; int op, last_op; char *tmp_s; static struct option long_options[] = { { "client", required_argument, 0, 'c' }, { "server", required_argument, 0, 's' }, { "banner", no_argument, 0, 'B' }, { "help", no_argument, 0, 'h' }, { "verbose", no_argument, 0, 'v' }, { "quiet", no_argument, 0, 'q' }, { "block-size", required_argument, 0, 'b' }, { "file", required_argument, 0, 'f' }, { "recv-num", required_argument, 0, 'r' }, { "no-check", no_argument, 0, 'n' }, { 0, 0, 0, 0 } }; memset(&trans_attr, 0, sizeof(msk_trans_attr_t)); memset(&priv, 0, sizeof(struct privatedata)); priv.docheck = 1; trans_attr.server = -1; // put an incorrect value to check if we're either client or server // sane values for optional or non-configurable elements trans_attr.debug = 1; trans_attr.max_recv_sge = 1; trans_attr.disconnect_callback = callback_disconnect; trans_attr.worker_count = -1; pcap_file = "pcap.out"; last_op = 0; while ((op = getopt_long(argc, argv, "-@hvqc:s:S:r:b:r:t:f:Bn", long_options, &option_index)) != -1) { switch(op) { case 1: // this means double argument if (last_op == 'c') { trans_attr.port = optarg; } else if (last_op == 'S') { trans_attr.port = optarg; } else { ERROR_LOG("Failed to parse arguments"); print_help(argv); exit(EINVAL); } break; case '@': printf("%s compiled on %s at %s\n", argv[0], __DATE__, __TIME__); printf("Release = %s\n", VERSION); printf("Release comment = %s\n", VERSION_COMMENT); printf("Git HEAD = %s\n", _GIT_HEAD_COMMIT ) ; printf("Git Describe = %s\n", _GIT_DESCRIBE ) ; exit(0); case 'h': print_help(argv); exit(0); case 'v': trans_attr.debug = trans_attr.debug * 2 + 1; break; case 'c': trans_attr.server = 0; trans_attr.node = optarg; break; case 's': trans_attr.server = 10; trans_attr.node = "::"; trans_attr.port = optarg; break; case 'S': trans_attr.server = 10; trans_attr.node = optarg; break; case 'q': trans_attr.debug = 0; break; case 'f': pcap_file = optarg; break; case 'B': banner = 1; break; case 'n': priv.docheck = 0; break; case 'b': block_size = strtoul(optarg, &tmp_s, 0); if (errno || block_size == 0) { ERROR_LOG("Invalid block size, assuming default (%u)", DEFAULT_BLOCK_SIZE); break; } if (tmp_s[0] != 0) { set_size(block_size, tmp_s); } INFO_LOG(trans_attr.debug > 1, "block size: %zu", block_size); break; case 'r': recv_num = strtoul(optarg, NULL, 0); if (errno || recv_num == 0) ERROR_LOG("Invalid recv_num, assuming default (%u)", DEFAULT_RECV_NUM); break; default: ERROR_LOG("Failed to parse arguments"); print_help(argv); exit(EINVAL); } last_op = op; } if (trans_attr.server == -1) { ERROR_LOG("Must be either client or server!"); print_help(argv); exit(EINVAL); } if (block_size == 0) block_size = DEFAULT_BLOCK_SIZE; if (recv_num == 0) recv_num = DEFAULT_RECV_NUM; trans_attr.rq_depth = recv_num+1; trans_attr.sq_depth = recv_num+1; /* open pcap file */ pcap = pcap_open_offline( pcap_file, errbuf ); if (pcap == NULL) { ERROR_LOG("Couldn't open pcap file: %s", errbuf); return EINVAL; } /* msk init */ TEST_Z(msk_init(&trans, &trans_attr)); if (!trans) { ERROR_LOG("msk_init failed! panic!"); exit(-1); } /* finish msk init */ const size_t mr_size = (recv_num+1)*block_size; if (trans_attr.server == 0) TEST_Z(msk_connect(trans)); else { listen_trans = trans; TEST_Z(msk_bind_server(listen_trans)); TEST_NZ(trans = msk_accept_one(listen_trans)); } TEST_NZ(rdmabuf = malloc(mr_size)); memset(rdmabuf, 0, mr_size); TEST_NZ(mr = msk_reg_mr(trans, rdmabuf, mr_size, IBV_ACCESS_LOCAL_WRITE)); TEST_NZ(data = malloc((recv_num+1)*sizeof(msk_data_t))); for (i=0; i < recv_num + 1; i++) { data[i].data = rdmabuf+i*block_size; data[i].max_size = block_size; data[i].mr = mr; } wdata = &data[recv_num]; trans->private_data = &priv; pthread_mutex_init(&priv.lock, NULL); pthread_cond_init(&priv.cond, NULL); for (i=0; i<recv_num; i++) { TEST_Z(msk_post_recv(trans, &data[i], callback_recv, callback_error, NULL)); } pthread_mutex_lock(&priv.lock); if (trans->server == 0) TEST_Z(msk_finalize_connect(trans)); else TEST_Z(msk_finalize_accept(trans)); /* set on first packet */ uint32_t send_ip = 0; uint32_t recv_ip = 0; uint16_t send_port = 0; uint16_t recv_port = 0; i=0; while ((rc = pcap_next_ex(pcap, &priv.pcaphdr, (const u_char**)&priv.packet)) >= 0) { INFO_LOG(trans->debug & (MSK_DEBUG_SEND|MSK_DEBUG_RECV), "Iteration %d", i++); /* first packet: */ if (send_ip == 0) { /* who talks first? */ if ((trans->server == 0 && banner == 0) || (trans->server && banner == 1)) { send_ip = priv.packet->ipv6.ip_src.s6_addr32[3]; send_port = priv.packet->tcp.th_sport; recv_ip = priv.packet->ipv6.ip_dst.s6_addr32[3]; recv_port = priv.packet->tcp.th_dport; } else { send_ip = priv.packet->ipv6.ip_dst.s6_addr32[3]; send_port = priv.packet->tcp.th_dport; recv_ip = priv.packet->ipv6.ip_src.s6_addr32[3]; recv_port = priv.packet->tcp.th_sport; } } /* all packets: decide if we send it or if we wait till we receive another */ if (priv.packet->ipv6.ip_src.s6_addr32[3] == send_ip && priv.packet->tcp.th_sport == send_port) { if (priv.pcaphdr->len != priv.pcaphdr->caplen) { ERROR_LOG("Can't send truncated data! make sure you've stored all the capture (-t in rmitm)"); rc = EINVAL; break; } memcpy(wdata->data, priv.packet->data, priv.pcaphdr->len); wdata->size = priv.pcaphdr->len; rc = msk_post_send(trans, wdata, callback_send, callback_error, NULL); if (rc) { ERROR_LOG("msk_post_send failed with rc %d (%s)", rc, strerror(rc)); break; } } else if (priv.packet->ipv6.ip_src.s6_addr32[3] == recv_ip && priv.packet->tcp.th_sport == recv_port) { INFO_LOG(trans->debug & (MSK_DEBUG_SEND|MSK_DEBUG_RECV), "Waiting"); pthread_cond_wait(&priv.cond, &priv.lock); if (priv.rc != 0) { /* got an error in recv thread */ ERROR_LOG("Stopping loop"); rc = priv.rc; break; } } else { ERROR_LOG("Multiple streams in pcap file? Stopping loop."); break; } } pthread_mutex_unlock(&priv.lock); /* mooshika doesn't use negative return values, so hopefully -1 can only mean pcap error */ if (rc == -1) { ERROR_LOG("Pcap error: %s", pcap_geterr(pcap)); } pcap_close(pcap); msk_destroy_trans(&trans); /* -2 is pcap way of saying end of file */ if (rc == -2) { rc = 0; printf("Replay ended succesfully!\n"); } return rc; }
bool LineGeometryShader::SetShader(u32 components, float lineWidth, float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable) { if (!m_ready) return false; // Make sure geometry shader for "components" is available ComboMap::iterator shaderIt = m_shaders.find(components); if (shaderIt == m_shaders.end()) { // Generate new shader. Warning: not thread-safe. static char buffer[16384]; ShaderCode code; code.SetBuffer(buffer); GenerateVSOutputStructForGS(code, API_D3D); code.Write("\n%s", LINE_GS_COMMON); std::stringstream numTexCoordsStream; numTexCoordsStream << xfmem.numTexGen.numTexGens; INFO_LOG(VIDEO, "Compiling line geometry shader for components 0x%.08X (num texcoords %d)", components, xfmem.numTexGen.numTexGens); const std::string& numTexCoordsStr = numTexCoordsStream.str(); D3D_SHADER_MACRO macros[] = { { "NUM_TEXCOORDS", numTexCoordsStr.c_str() }, { nullptr, nullptr } }; ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code.GetBuffer(), macros); if (!newShader) { WARN_LOG(VIDEO, "Line geometry shader for components 0x%.08X failed to compile", components); // Add dummy shader to prevent trying to compile again m_shaders[components] = nullptr; return false; } shaderIt = m_shaders.insert(std::make_pair(components, newShader)).first; } if (shaderIt != m_shaders.end()) { if (shaderIt->second) { D3D11_MAPPED_SUBRESOURCE map; HRESULT hr = D3D::context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); if (SUCCEEDED(hr)) { LineGSParams* params = (LineGSParams*)map.pData; params->LineWidth = lineWidth; params->TexOffset = texOffset; params->VpWidth = vpWidth; params->VpHeight = vpHeight; for (int i = 0; i < 8; ++i) params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f; D3D::context->Unmap(m_paramsBuffer, 0); } else ERROR_LOG(VIDEO, "Failed to map line gs params buffer"); DEBUG_LOG(VIDEO, "Line params: width %f, texOffset %f, vpWidth %f, vpHeight %f", lineWidth, texOffset, vpWidth, vpHeight); D3D::context->GSSetShader(shaderIt->second, nullptr, 0); D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer); return true; } else return false; } else return false; }
bool VirtualDiscFileSystem::RemoveFile(const std::string &filename) { ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Cannot remove file on virtual disc"); return false; }
int VirtualDiscFileSystem::RenameFile(const std::string &from, const std::string &to) { ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Cannot rename file on virtual disc"); return -1; }
bool SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &saveDirName, int saveId, bool secureMode) { if (!param) { return false; } u8 *data_ = param->dataBuf; std::string dirPath = GetSaveFilePath(param, GetSaveDir(param, saveDirName)); if (saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it { if (saveDataList[saveId].size == 0) // don't read no existing file { return false; } } std::string filePath = dirPath+"/"+GetFileName(param); s64 readSize; INFO_LOG(HLE,"Loading file with size %u in %s",param->dataBufSize,filePath.c_str()); u8* saveData = 0; int saveSize = -1; if (!ReadPSPFile(filePath, &saveData, saveSize, &readSize)) { ERROR_LOG(HLE,"Error reading file %s",filePath.c_str()); return false; } saveSize = (int)readSize; // copy back save name in request strncpy(param->saveName, saveDirName.c_str(), 20); ParamSFOData sfoFile; std::string sfopath = dirPath+"/" + SFO_FILENAME; PSPFileInfo sfoInfo = pspFileSystem.GetFileInfo(sfopath); if(sfoInfo.exists) // Read sfo { u8 *sfoData = new u8[(size_t)sfoInfo.size]; size_t sfoSize = (size_t)sfoInfo.size; if(ReadPSPFile(sfopath,&sfoData,sfoSize, NULL)) { sfoFile.ReadSFO(sfoData,sfoSize); // copy back info in request strncpy(param->sfoParam.title,sfoFile.GetValueString("TITLE").c_str(),128); strncpy(param->sfoParam.savedataTitle,sfoFile.GetValueString("SAVEDATA_TITLE").c_str(),128); strncpy(param->sfoParam.detail,sfoFile.GetValueString("SAVEDATA_DETAIL").c_str(),1024); param->sfoParam.parentalLevel = sfoFile.GetValueInt("PARENTAL_LEVEL"); } delete[] sfoData; } // Don't know what it is, but PSP always respond this and this unlock some game param->bind = 1021; bool isCrypted = IsSaveEncrypted(param, saveDirName) && secureMode; bool saveDone = false; if(isCrypted)// Try to decrypt { int align_len = align16(saveSize); u8* data_base = new u8[align_len]; u8* cryptKey = new u8[0x10]; memset(cryptKey,0,0x10); if(param->key[0] != 0) { memcpy(cryptKey, param->key, 0x10); } memset(data_base + saveSize, 0, align_len - saveSize); memcpy(data_base, saveData, saveSize); int decryptMode = 1; if(param->key[0] != 0) { decryptMode = (GetSDKMainVersion(sceKernelGetCompiledSdkVersion()) >= 4 ? 5 : 3); } if(DecryptSave(decryptMode, data_base, &saveSize, &align_len, ((param->key[0] != 0)?cryptKey:0)) == 0) { memcpy(data_, data_base, saveSize); saveDone = true; } delete[] data_base; delete[] cryptKey; } if(!saveDone) // not crypted or decrypt fail { memcpy(data_, saveData, saveSize); } param->dataSize = (SceSize)saveSize; delete[] saveData; return true; }
u32 ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) { // LBN unittest /* u32 a, b; if (parseLBN("/sce_lbn0x307aa_size0xefffe000", &a, &b)) { ERROR_LOG(FILESYS, "lbn: %08x %08x", a, b); } else { ERROR_LOG(FILESYS, "faillbn: %08x %08x", a, b); }*/ OpenFileEntry entry; entry.isRawSector = false; entry.isBlockSectorMode = false; if (filename.compare(0,8,"/sce_lbn") == 0) { u32 sectorStart = 0xFFFFFFFF, readSize = 0xFFFFFFFF; parseLBN(filename, §orStart, &readSize); if (sectorStart >= blockDevice->GetNumBlocks()) { WARN_LOG(FILESYS, "Unable to open raw sector: %s, sector %08x, max %08x", filename.c_str(), sectorStart, blockDevice->GetNumBlocks()); return 0; } DEBUG_LOG(FILESYS, "Got a raw sector open: %s, sector %08x, size %08x", filename.c_str(), sectorStart, readSize); u32 newHandle = hAlloc->GetNewHandle(); entry.seekPos = 0; entry.file = 0; entry.isRawSector = true; entry.sectorStart = sectorStart; entry.openSize = readSize; // when open as "umd1:/sce_lbn0x0_size0x6B49D200", that mean open umd1 as a block device. // the param in sceIoLseek and sceIoRead is lba mode. we must mark it. if(strncmp(devicename, "umd0:", 5)==0 || strncmp(devicename, "umd1:", 5)==0) entry.isBlockSectorMode = true; entries[newHandle] = entry; return newHandle; } if (access & FILEACCESS_WRITE) { ERROR_LOG(FILESYS, "Can't open file %s with write access on an ISO partition", filename.c_str()); return 0; } // May return entireISO for "umd0:" entry.file = GetFromPath(filename); if (!entry.file){ return 0; } if (entry.file==&entireISO) entry.isBlockSectorMode = true; entry.seekPos = 0; u32 newHandle = hAlloc->GetNewHandle(); entries[newHandle] = entry; return newHandle; }
bool Ardb::Init(uint32 check_expire_period) { if (NULL == m_engine) { INFO_LOG("Start init storage engine."); m_engine = m_engine_factory->CreateDB( m_engine_factory->GetName().c_str()); KeyObject verkey(Slice(), KEY_END, ARDB_GLOBAL_DB); ValueObject ver; if (0 == GetValue(verkey, &ver)) { if (ver.v.int_v != ARDB_FORMAT_VERSION) { ERROR_LOG( "Incompatible data format version:%d in DB", ver.v.int_v); return false; } } else { ver.v.int_v = ARDB_FORMAT_VERSION; ver.type = INTEGER; SetValue(verkey, ver); } if (NULL != m_engine) { INFO_LOG("Init storage engine success."); //launch a threading task to check expired keys struct ExpireCheckThread: public Thread { Ardb* adb; volatile bool running; uint32 check_period; ExpireCheckThread(Ardb* db, uint32 period) : adb(db), running(true), check_period(period) { } void Run() { while (running) { DBID firstDB = 0, lastDB = 0; if (0 == adb->LastDB(lastDB) && 0 == adb->FirstDB(firstDB)) { for (DBID db = firstDB; db <= lastDB; db++) { DBID nexdb = db; if (adb->DBExist(db, nexdb)) { adb->CheckExpireKey(db); } else { if (nexdb == db) { break; } adb->CheckExpireKey(nexdb); db = nexdb; } } } uint64 end = get_current_epoch_micros(); uint64 sleep = check_period; if (adb->m_min_expireat > end) { sleep = (adb->m_min_expireat - end) / 1000; if (sleep > check_period) { sleep = check_period; } if (sleep == 0) { sleep = 1; } } Thread::Sleep(sleep); } } ~ExpireCheckThread() { running = false; } }; m_expire_check_thread = new ExpireCheckThread(this, check_expire_period); m_expire_check_thread->Start(); } } return m_engine != NULL; }
size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { EntryMap::iterator iter = entries.find(handle); if (iter != entries.end()) { OpenFileEntry &e = iter->second; if (e.isBlockSectorMode) { // Whole sectors! Shortcut to this simple code. for (int i = 0; i < size; i++) { blockDevice->ReadBlock(e.seekPos, pointer + i * 2048); e.seekPos++; } return (size_t)size; } u32 positionOnIso; if (e.isRawSector) { positionOnIso = e.sectorStart * 2048 + e.seekPos; if (e.seekPos + size > e.openSize) { size = e.openSize - e.seekPos; } } else { _dbg_assert_msg_(FILESYS, e.file != 0, "Expecting non-raw fd to have a tree entry."); //clamp read length if ((s64)e.seekPos > e.file->size - (s64)size) { size = e.file->size - (s64)e.seekPos; } positionOnIso = e.file->startingPosition + e.seekPos; } //okay, we have size and position, let's rock u32 totalRead = 0; int secNum = positionOnIso / 2048; int posInSector = positionOnIso & 2047; s64 remain = size; u8 theSector[2048]; while (remain > 0) { blockDevice->ReadBlock(secNum, theSector); size_t bytesToCopy = 2048 - posInSector; if ((s64)bytesToCopy > remain) bytesToCopy = (size_t)remain; memcpy(pointer, theSector + posInSector, bytesToCopy); totalRead += (u32)bytesToCopy; pointer += bytesToCopy; remain -= bytesToCopy; posInSector = 0; secNum++; } e.seekPos += (unsigned int)size; return totalRead; } else { //This shouldn't happen... ERROR_LOG(FILESYS, "Hey, what are you doing? Reading non-open files?"); return 0; } }
bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm) { if (!iIsTiled) { // currently, core creates grids for all maps, whether it has terrain tiles or not // so we need "fake" tile loads to know when we can unload map geometry iLoadedTiles[packTileID(tileX, tileY)] = false; return true; } if (!iTreeValues) { ERROR_LOG("StaticMapTree::LoadMapTile(): Tree has not been initialized! [%u,%u]", tileX, tileY); return false; } bool result = true; std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY); FILE* tf = fopen(tilefile.c_str(), "rb"); if (tf) { char chunk[8]; if (!readChunk(tf, chunk, VMAP_MAGIC, 8)) result = false; uint32 numSpawns; if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1) result = false; for (uint32 i = 0; i < numSpawns && result; ++i) { // read model spawns ModelSpawn spawn; result = ModelSpawn::readFromFile(tf, spawn); if (result) { // acquire model instance WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name); if (!model) ERROR_LOG("StaticMapTree::LoadMapTile() could not acquire WorldModel pointer for '%s'!", spawn.name.c_str()); // update tree uint32 referencedVal; fread(&referencedVal, sizeof(uint32), 1, tf); if (!iLoadedSpawns.count(referencedVal)) { #ifdef VMAP_DEBUG if (referencedVal > iNTreeValues) { DEBUG_LOG("invalid tree element! (%u/%u)", referencedVal, iNTreeValues); continue; } #endif iTreeValues[referencedVal] = ModelInstance(spawn, model); iLoadedSpawns[referencedVal] = 1; } else { ++iLoadedSpawns[referencedVal]; #ifdef VMAP_DEBUG if (iTreeValues[referencedVal].uniqueID != spawn.uniqueID) DEBUG_LOG("Error: trying to load wrong spawn in node!"); else if (iTreeValues[referencedVal].name != spawn.name) DEBUG_LOG("Error: name mismatch on GUID=%u", spawn.uniqueID); #endif } } } iLoadedTiles[packTileID(tileX, tileY)] = true; fclose(tf); } else iLoadedTiles[packTileID(tileX, tileY)] = false; return result; }
size_t ISOFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size) { ERROR_LOG(FILESYS, "Hey, what are you doing? You can't write to an ISO!"); return 0; }
/** * @brief inserts a mac descriptor into an tree * * @param searchTree tree where the insertion is to be performed (may be NULL) * @param descriptor descriptor to insert into tree * * @return the tree root * * @internal */ IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor) { MacTreeNode *currentNode = searchTree; MacTreeNode *insertLocation = NULL; MacTreeNode *newNode; INT32 insertPosition = RIGHT; if (descriptor == NULL) { return searchTree; } /* create a new node */ newNode = ixEthDBAllocMacTreeNode(); if (newNode == NULL) { /* out of memory */ ERROR_LOG("Warning: ixEthDBAllocMacTreeNode returned NULL in file %s:%d (out of memory?)\n", __FILE__, __LINE__); ixEthDBFreeMacDescriptor(descriptor); return NULL; } /* populate node */ newNode->descriptor = descriptor; /* an empty initial tree is a special case */ if (searchTree == NULL) { return newNode; } /* get insertion location */ while (insertLocation == NULL) { MacTreeNode *nextNode; /* compare given key with current node key */ insertPosition = ixEthDBAddressCompare(descriptor->macAddress, currentNode->descriptor->macAddress); /* navigate down */ if (insertPosition == RIGHT) { nextNode = currentNode->right; } else if (insertPosition == LEFT) { nextNode = currentNode->left; } else { /* error, duplicate key */ ERROR_LOG("Warning: trapped insertion of a duplicate MAC address in an NPE search tree\n"); /* this will free the MAC descriptor as well */ ixEthDBFreeMacTreeNode(newNode); return searchTree; } /* when we can no longer dive through the tree we found the insertion place */ if (nextNode != NULL) { currentNode = nextNode; } else { insertLocation = currentNode; } } /* insert node */ if (insertPosition == RIGHT) { insertLocation->right = newNode; } else { insertLocation->left = newNode; } return searchTree; }
Object* ObjectPool::CreateByIDType(int type) { ERROR_LOG(COMMON, "Unimplemented: %d.", type); return nullptr; }
/* Check if the response is an error, redirect response * or it includes a warning * @param response - the LoST response body * @param resp_type - the response type: ERROR, REDIRECT, WARNING or OK * @returns the root node of the parsed xml body */ xmlNode* get_LoST_resp_type(str response, lost_resp_type * resp_type, str * reason){ xmlNode * root, * node, * child; reason->s = NULL; reason->len = 0; root = xml_parse_string(response); if(!root) return root; #ifdef LOST_DEBUG print_element_names(root); #endif if(strcmp((char*)root->name, LOST_ERR_NODE_NAME) == 0){ DEBUG_LOG("LoST response has an error response\n"); node = child_node(root); if(node){ DEBUG_LOG("reason %s\n", node->name); reason->s = (char*)node->name; reason->len = strlen(reason->s); #ifdef LOST_DEBUG print_attr(node, LOST_MSG_ATTR_NAME); #endif }else { DEBUG_LOG("the message has no reason\n"); } *resp_type = LOST_ERR; } else if(strcmp((char*)root->name, LOST_REDIR_NODE_NAME) == 0){ DEBUG_LOG("LoST response has a redirect response\n"); #ifdef LOST_DEBUG print_attr(root, LOST_TGT_ATTR_NAME); #endif *resp_type = LOST_REDIR; } else if(strcmp((char*)root->name, LOST_FINDSRESP_NODE_NAME) != 0){ ERROR_LOG("invalid LoST response\n"); *resp_type = LOST_ERR; } else { node = child_named_node(root, LOST_WRNG_NODE_NAME); if(node){ DEBUG_LOG("LoST response has a response with warning\n"); if((child = child_node(node))){ DEBUG_LOG("reason %s\n", child->name); reason->s = (char*)child->name; reason->len = strlen(reason->s); #ifdef LOST_DEBUG print_attr(node, LOST_MSG_ATTR_NAME); #endif }else { DEBUG_LOG("warning without reason\n"); } *resp_type = LOST_WRNG; }else *resp_type = LOST_OK; } return root; }
void radio_button_cb(void *data, Evas_Object *obj, void *event_info) { __COMMON_FUNC_ENTER__; int ret = WLAN_MANAGER_ERR_UNKNOWN; Elm_Object_Item *it = (Elm_Object_Item *)event_info; wifi_device_info_t *device_info = (wifi_device_info_t *)data; if (!it || !device_info || device_info->ssid == NULL) { ERROR_LOG(UG_NAME_NORMAL, "Error!!! Invalid inout params"); __COMMON_FUNC_EXIT__; return; } ug_genlist_data_t *gdata = (ug_genlist_data_t *) elm_object_item_data_get((Elm_Object_Item*)it); if(NULL == gdata) { ERROR_LOG(UG_NAME_NORMAL, "Error!!! list item data null"); __COMMON_FUNC_EXIT__; return; } int item_state = gdata->radio_mode; int current_state = 0; INFO_LOG(UG_NAME_NORMAL, "ssid --- %s", device_info->ssid); INFO_LOG(UG_NAME_NORMAL, "current item_state state is --- %d\n", item_state); switch (item_state) { case VIEWER_ITEM_RADIO_MODE_OFF: current_state = viewer_manager_header_mode_get(); INFO_LOG(UG_NAME_NORMAL, "Clicked AP`s information\n"); INFO_LOG(UG_NAME_NORMAL, "header mode [%d]", current_state); switch (current_state) { case HEADER_MODE_CONNECTED: case HEADER_MODE_ON: ret = wlan_manager_request_connection(device_info); if (ret == WLAN_MANAGER_ERR_NONE) { viewer_manager_header_mode_set(HEADER_MODE_CONNECTING); } break; case HEADER_MODE_OFF: case HEADER_MODE_SEARCHING: case HEADER_MODE_ACTIVATING: case HEADER_MODE_CONNECTING: case HEADER_MODE_DISCONNECTING: case HEADER_MODE_DEACTIVATING: default: INFO_LOG(UG_NAME_NORMAL, "Ignore the item click"); break; } break; case VIEWER_ITEM_RADIO_MODE_CONNECTED: INFO_LOG(UG_NAME_NORMAL, "want to disconnect for connected item"); ret = wlan_manager_request_disconnection(device_info); if(ret == WLAN_MANAGER_ERR_NONE){ viewer_manager_header_mode_set(HEADER_MODE_DISCONNECTING); } break; case VIEWER_ITEM_RADIO_MODE_CONNECTING: INFO_LOG(UG_NAME_NORMAL, "want to cancel connecting for connected item"); ret = wlan_manager_request_cancel_connecting(device_info->profile_name); if(ret == WLAN_MANAGER_ERR_NONE){ viewer_manager_header_mode_set(HEADER_MODE_CANCEL_CONNECTING); } break; default: ret = WLAN_MANAGER_ERR_UNKNOWN; break; } switch (ret) { case WLAN_MANAGER_ERR_NONE: INFO_LOG(UG_NAME_NORMAL, "ERROR_NONE"); break; case WLAN_MANAGER_ERR_CONNECT_PASSWORD_NEEDED: { pswd_popup_create_req_data_t popup_info; popup_info.title = device_info->ssid; popup_info.ok_cb = _popup_ok_cb; popup_info.cancel_cb = _popup_cancel_cb; popup_info.show_wps_btn = device_info->wps_mode; popup_info.wps_btn_cb = _wps_btn_cb; popup_info.cb_data = g_strdup(gdata->device_info->profile_name); INFO_LOG(UG_NAME_NORMAL, "Going to create a popup. ug_app_state = 0x%x", ug_app_state); ug_app_state->passpopup = common_pswd_popup_create(ug_app_state->win_main, PACKAGE, &popup_info); INFO_LOG(UG_NAME_NORMAL, "After create a popup"); if (ug_app_state->passpopup == NULL) { INFO_LOG(UG_NAME_ERR, "pass popup create failed !"); } } break; case WLAN_MANAGER_ERR_CONNECT_EAP_SEC_TYPE: { Evas_Object* navi_frame = viewer_manager_get_naviframe(); if (navi_frame == NULL) { ERROR_LOG(UG_NAME_NORMAL, "Failed : get naviframe"); return; } ug_app_state->eap_view = create_eap_connect(ug_app_state->win_main, navi_frame, PACKAGE, device_info, eap_view_close_cb); } break; case WLAN_MANAGER_ERR_NOSERVICE: break; default: ERROR_LOG(UG_NAME_NORMAL, "errro code [%d]", ret); break; } __COMMON_FUNC_EXIT__; return; }
/* first message after new connection are going trough the server */ static int xio_on_new_message(struct xio_server *server, struct xio_nexus *nexus, int event, union xio_nexus_event_data *event_data) { struct xio_session *session = NULL; struct xio_connection *connection = NULL; struct xio_connection *connection1 = NULL; struct xio_task *task; uint32_t tlv_type; struct xio_session_params params; int locked = 0; if (!server || !nexus || !event_data || !event_data->msg.task) { ERROR_LOG("server [new session]: failed " \ "invalid parameter\n"); return -1; } task = event_data->msg.task; params.type = XIO_SESSION_SERVER; params.initial_sn = 0; params.ses_ops = &server->ops; params.uri = server->uri; params.private_data = NULL; params.private_data_len = 0; params.user_context = server->cb_private_data; /* read the first message type */ tlv_type = xio_read_tlv_type(&event_data->msg.task->mbuf); if (tlv_type == XIO_SESSION_SETUP_REQ) { /* create new session */ session = xio_session_create(¶ms); if (!session) { ERROR_LOG("server [new session]: failed " \ " allocating session failed\n"); return -1; } DEBUG_LOG("server [new session]: server:%p, " \ "session:%p, nexus:%p ,session_id:%d\n", server, session, nexus, session->session_id); /* get transport class routines */ session->validators_cls = xio_nexus_get_validators_cls(nexus); connection = xio_session_alloc_connection(session, server->ctx, 0, server->cb_private_data); if (!connection) { ERROR_LOG("server failed to allocate new connection\n"); goto cleanup; } connection1 = xio_session_assign_nexus(session, nexus); if (!connection1) { ERROR_LOG("server failed to assign new connection\n"); goto cleanup1; } connection = connection1; xio_idr_add_uobj(usr_idr, session, "xio_session"); xio_idr_add_uobj(usr_idr, connection, "xio_connection"); xio_connection_set_state(connection, XIO_CONNECTION_STATE_ONLINE); xio_connection_keepalive_start(connection); task->session = session; task->connection = connection; } else if (tlv_type == XIO_CONNECTION_HELLO_REQ) { struct xio_session *session1; /* find the old session without lock */ session = xio_find_session(event_data->msg.task); if (!session) { ERROR_LOG("server [new connection]: failed " \ "session not found. server:%p\n", server); xio_nexus_close(nexus, NULL); return -1; } /* lock it and retry find */ mutex_lock(&session->lock); /* session before destruction - try to lock before continue */ session1 = xio_find_session(event_data->msg.task); if (!session1) { ERROR_LOG("server [new connection]: failed " \ "session not found. server:%p\n", server); xio_nexus_close(nexus, NULL); mutex_unlock(&session->lock); return -1; } locked = 1; task->session = session; DEBUG_LOG("server [new connection]: server:%p, " \ "session:%p, nexus:%p, session_id:%d\n", server, session, nexus, session->session_id); connection = xio_session_alloc_connection( task->session, server->ctx, 0, server->cb_private_data); if (!connection) { ERROR_LOG("server failed to allocate new connection\n"); goto cleanup; } connection1 = xio_session_assign_nexus(task->session, nexus); if (!connection1) { ERROR_LOG("server failed to assign new connection\n"); goto cleanup1; } connection = connection1; /* copy the server attributes to the connection */ xio_connection_set_ops(connection, &server->ops); task->connection = connection; /* This in a multiple-portal situation */ session->state = XIO_SESSION_STATE_ONLINE; xio_connection_set_state(connection, XIO_CONNECTION_STATE_ONLINE); xio_connection_keepalive_start(connection); xio_idr_add_uobj(usr_idr, connection, "xio_connection"); } else { ERROR_LOG("server unexpected message\n"); return -1; } /* route the message to the session */ if (session) xio_nexus_notify_observer(nexus, &session->observer, event, event_data); if (locked) mutex_unlock(&session->lock); return 0; cleanup1: if (connection) xio_session_free_connection(connection); cleanup: if (session) xio_session_destroy(session); return -1; }
static void _popup_ok_cb(void *data, Evas_Object *obj, void *event_info) { __COMMON_FUNC_ENTER__; if (!ug_app_state->passpopup || !data) { return; } char *profile_name = (char *)data; wlan_security_mode_type_t sec_mode; view_datamodel_basic_info_t *basic_data_model = view_basic_detail_datamodel_create(profile_name); if (!basic_data_model) { common_pswd_popup_destroy(ug_app_state->passpopup); ug_app_state->passpopup = NULL; g_free(profile_name); return; } int ret = WLAN_MANAGER_ERR_NONE; int nLen = 0; const char* szPassword = common_pswd_popup_get_txt(ug_app_state->passpopup); nLen = strlen(szPassword); INFO_LOG(UG_NAME_NORMAL, "password = [%s]", szPassword); sec_mode = view_detail_datamodel_sec_mode_get(basic_data_model); switch (sec_mode) { case WLAN_SEC_MODE_WEP: if (nLen != 5 && nLen != 13 && nLen != 26 && nLen != 10) { winset_popup_mode_set(ug_app_state->popup_manager, POPUP_OPTION_WEP_PSWD_LEN_ERROR, NULL); goto popup_ok_cb_exit; } break; case WLAN_SEC_MODE_WPA_PSK: case WLAN_SEC_MODE_WPA2_PSK: if (nLen < 8 || nLen > 63) { winset_popup_mode_set(ug_app_state->popup_manager, POPUP_OPTION_WPA_PSWD_LEN_ERROR, NULL); goto popup_ok_cb_exit; } break; default: ERROR_LOG(UG_NAME_SCAN, "Fatal: Wrong security mode : %d", sec_mode); common_pswd_popup_destroy(ug_app_state->passpopup); ug_app_state->passpopup = NULL; g_free(profile_name); goto popup_ok_cb_exit; } common_pswd_popup_destroy(ug_app_state->passpopup); ug_app_state->passpopup = NULL; INFO_LOG(UG_NAME_SCAN, "connect with password comp"); wlan_manager_password_data param; memset(¶m, 0, sizeof(wlan_manager_password_data)); param.wlan_eap_type = WLAN_MANAGER_EAP_TYPE_NONE; param.password = szPassword; ret = wlan_manager_connect_with_password(profile_name, sec_mode, ¶m); if (WLAN_MANAGER_ERR_NONE == ret) { viewer_manager_header_mode_set(HEADER_MODE_CONNECTING); } else { ERROR_LOG(UG_NAME_SCAN, "wlan error %d", ret); viewer_manager_header_mode_set(HEADER_MODE_ON); } g_free(profile_name); popup_ok_cb_exit: g_free((gpointer)szPassword); view_basic_detail_datamodel_destroy(basic_data_model); __COMMON_FUNC_EXIT__; }
static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int waitMode, u32 resultAddr, u32 timeoutPtr, bool cbEnabled, bool poll, bool &needsResched, bool &needsWait) { u32 curSendAddr = sendBufAddr; SceUID uid = m->GetUID(); // If the buffer size is 0, nothing is buffered and all operations wait. if (m->nmp.bufSize == 0) { m->SortReceiveThreads(); while (!m->receiveWaitingThreads.empty() && sendSize != 0) { MsgPipeWaitingThread *thread = &m->receiveWaitingThreads.front(); u32 bytesToSend = std::min(thread->freeSize, sendSize); if (bytesToSend > 0) { thread->WriteBuffer(curSendAddr, bytesToSend); sendSize -= bytesToSend; curSendAddr += bytesToSend; if (thread->freeSize == 0 || thread->waitMode == SCE_KERNEL_MPW_ASAP) { thread->Complete(uid, 0); m->receiveWaitingThreads.erase(m->receiveWaitingThreads.begin()); needsResched = true; thread = NULL; } } } // If there is still data to send and (we want to send all of it or we didn't send anything) if (sendSize != 0 && (waitMode != SCE_KERNEL_MPW_ASAP || curSendAddr == sendBufAddr)) { if (poll) { // Generally, result is not updated in this case. But for a 0 size buffer in ASAP mode, it is. if (Memory::IsValidAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP) Memory::Write_U32(curSendAddr - sendBufAddr, resultAddr); return SCE_KERNEL_ERROR_MPP_FULL; } else { m->AddSendWaitingThread(__KernelGetCurThread(), curSendAddr, sendSize, waitMode, resultAddr); needsWait = true; return 0; } } } else { if (sendSize > (u32) m->nmp.bufSize) { ERROR_LOG(SCEKERNEL, "__KernelSendMsgPipe(%d): size %d too large for buffer", uid, sendSize); return SCE_KERNEL_ERROR_ILLEGAL_SIZE; } u32 bytesToSend = 0; // If others are already waiting, space or not, we have to get in line. m->SortSendThreads(); if (m->sendWaitingThreads.empty()) { if (sendSize <= (u32) m->nmp.freeSize) bytesToSend = sendSize; else if (waitMode == SCE_KERNEL_MPW_ASAP) bytesToSend = m->nmp.freeSize; } if (bytesToSend != 0) { Memory::Memcpy(m->buffer + (m->nmp.bufSize - m->nmp.freeSize), sendBufAddr, bytesToSend); m->nmp.freeSize -= bytesToSend; curSendAddr += bytesToSend; sendSize -= bytesToSend; if (m->CheckReceiveThreads()) needsResched = true; } else if (sendSize != 0) { if (poll) return SCE_KERNEL_ERROR_MPP_FULL; else { m->AddSendWaitingThread(__KernelGetCurThread(), curSendAddr, sendSize, waitMode, resultAddr); needsWait = true; return 0; } } } // We didn't wait, so update the number of bytes transferred now. if (Memory::IsValidAddress(resultAddr)) Memory::Write_U32(curSendAddr - sendBufAddr, resultAddr); return 0; }
bool SavedataParam::Save(SceUtilitySavedataParam* param, const std::string &saveDirName, bool secureMode) { if (!param) { return false; } std::string dirPath = GetSaveFilePath(param, GetSaveDir(param, saveDirName)); if (!pspFileSystem.GetFileInfo(dirPath).exists) pspFileSystem.MkDir(dirPath); u8* cryptedData = 0; int cryptedSize = 0; u8 cryptedHash[0x10]; memset(cryptedHash,0,0x10); // Encrypt save. // TODO: Is this the correct difference between MAKEDATA and MAKEDATASECURE? if (param->dataBuf != 0 && g_Config.bEncryptSave && secureMode) { cryptedSize = param->dataSize; if(cryptedSize == 0 || (SceSize)cryptedSize > param->dataBufSize) cryptedSize = param->dataBufSize; // fallback, should never use this u8 *data_ = param->dataBuf; int aligned_len = align16(cryptedSize); cryptedData = new u8[aligned_len + 0x10]; memcpy(cryptedData, data_, cryptedSize); int decryptMode = 1; if(param->key[0] != 0) { decryptMode = (GetSDKMainVersion(sceKernelGetCompiledSdkVersion()) >= 4 ? 5 : 3); } if(EncryptData(decryptMode, cryptedData, &cryptedSize, &aligned_len, cryptedHash, ((param->key[0] != 0)?param->key:0)) == 0) { } else { ERROR_LOG(HLE,"Save encryption failed. This save won't work on real PSP"); delete[] cryptedData; cryptedData = 0; } } // SAVE PARAM.SFO ParamSFOData sfoFile; std::string sfopath = dirPath+"/" + SFO_FILENAME; PSPFileInfo sfoInfo = pspFileSystem.GetFileInfo(sfopath); if(sfoInfo.exists) // Read old sfo if exist { u8 *sfoData = new u8[(size_t)sfoInfo.size]; size_t sfoSize = (size_t)sfoInfo.size; if(ReadPSPFile(sfopath,&sfoData,sfoSize, NULL)) { sfoFile.ReadSFO(sfoData,sfoSize); delete[] sfoData; } } // Update values sfoFile.SetValue("TITLE",param->sfoParam.title,128); sfoFile.SetValue("SAVEDATA_TITLE",param->sfoParam.savedataTitle,128); sfoFile.SetValue("SAVEDATA_DETAIL",param->sfoParam.detail,1024); sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4); sfoFile.SetValue("CATEGORY","MS",4); sfoFile.SetValue("SAVEDATA_DIRECTORY", GetSaveDir(param, saveDirName), 64); // For each file, 13 bytes for filename, 16 bytes for file hash (0 in PPSSPP), 3 byte for padding if (secureMode) { const int FILE_LIST_ITEM_SIZE = 13 + 16 + 3; const int FILE_LIST_COUNT_MAX = 99; const int FILE_LIST_TOTAL_SIZE = FILE_LIST_ITEM_SIZE * FILE_LIST_COUNT_MAX; u32 tmpDataSize = 0; u8 *tmpDataOrig = sfoFile.GetValueData("SAVEDATA_FILE_LIST", &tmpDataSize); u8 *tmpData = new u8[FILE_LIST_TOTAL_SIZE]; if (tmpDataOrig != NULL) memcpy(tmpData, tmpDataOrig, tmpDataSize > FILE_LIST_TOTAL_SIZE ? FILE_LIST_TOTAL_SIZE : tmpDataSize); else memset(tmpData, 0, FILE_LIST_TOTAL_SIZE); if (param->dataBuf != 0) { char *fName = (char*)tmpData; for(int i = 0; i < FILE_LIST_COUNT_MAX; i++) { if(fName[0] == 0) break; // End of list if(strncmp(fName,GetFileName(param).c_str(),20) == 0) break; fName += FILE_LIST_ITEM_SIZE; } if (fName + 13 <= (char*)tmpData + FILE_LIST_TOTAL_SIZE) snprintf(fName, 13, "%s",GetFileName(param).c_str()); if (fName + 13 + 16 <= (char*)tmpData + FILE_LIST_TOTAL_SIZE) memcpy(fName+13, cryptedHash, 16); } sfoFile.SetValue("SAVEDATA_FILE_LIST", tmpData, FILE_LIST_TOTAL_SIZE, FILE_LIST_TOTAL_SIZE); delete[] tmpData; } // Init param with 0. This will be used to detect crypted save or not on loading u8 *tmpData = new u8[128]; memset(tmpData, 0, 128); sfoFile.SetValue("SAVEDATA_PARAMS", tmpData, 128, 128); delete[] tmpData; u8 *sfoData; size_t sfoSize; sfoFile.WriteSFO(&sfoData,&sfoSize); // Calc SFO hash for PSP. if(cryptedData != 0) { int offset = sfoFile.GetDataOffset(sfoData,"SAVEDATA_PARAMS"); if(offset >= 0) UpdateHash(sfoData, (int)sfoSize, offset, (param->key[0] ? 3 : 1)); } WritePSPFile(sfopath, sfoData, (SceSize)sfoSize); delete[] sfoData; if(param->dataBuf != 0) // Can launch save without save data in mode 13 { std::string filePath = dirPath+"/"+GetFileName(param); u8 *data_ = 0; SceSize saveSize = 0; if(cryptedData == 0) // Save decrypted data { saveSize = param->dataSize; if(saveSize == 0 || saveSize > param->dataBufSize) saveSize = param->dataBufSize; // fallback, should never use this data_ = param->dataBuf; } else { data_ = cryptedData; saveSize = cryptedSize; } INFO_LOG(HLE,"Saving file with size %u in %s",saveSize,filePath.c_str()); // copy back save name in request strncpy(param->saveName, saveDirName.c_str(), 20); if (!WritePSPFile(filePath, data_, saveSize)) { ERROR_LOG(HLE,"Error writing file %s",filePath.c_str()); if(cryptedData != 0) { delete[] cryptedData; } return false; } delete[] cryptedData; } // SAVE ICON0 if (param->icon0FileData.buf.Valid()) { std::string icon0path = dirPath + "/" + ICON0_FILENAME; WritePSPFile(icon0path, param->icon0FileData.buf, param->icon0FileData.bufSize); } // SAVE ICON1 if (param->icon1FileData.buf.Valid()) { std::string icon1path = dirPath + "/" + ICON1_FILENAME; WritePSPFile(icon1path, param->icon1FileData.buf, param->icon1FileData.bufSize); } // SAVE PIC1 if (param->pic1FileData.buf.Valid()) { std::string pic1path = dirPath + "/" + PIC1_FILENAME; WritePSPFile(pic1path, param->pic1FileData.buf, param->pic1FileData.bufSize); } // Save SND if (param->snd0FileData.buf.Valid()) { std::string snd0path = dirPath + "/" + SND0_FILENAME; WritePSPFile(snd0path, param->snd0FileData.buf, param->snd0FileData.bufSize); } return true; }
// copies file srcFilename to destFilename, returns true on success bool Copy(const std::string &srcFilename, const std::string &destFilename) { INFO_LOG(COMMON, "Copy: %s --> %s", srcFilename.c_str(), destFilename.c_str()); #if defined(_WIN32) && !defined(__MINGW32__) if (CopyFile(ConvertUTF8ToWString(srcFilename).c_str(), ConvertUTF8ToWString(destFilename).c_str(), FALSE)) return true; ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); return false; #else // buffer size #define BSIZE 1024 char buffer[BSIZE]; // Open input file FILE *input = fopen(srcFilename.c_str(), "rb"); if (!input) { ERROR_LOG(COMMON, "Copy: input failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); return false; } // open output file FILE *output = fopen(destFilename.c_str(), "wb"); if (!output) { fclose(input); ERROR_LOG(COMMON, "Copy: output failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); return false; } // copy loop while (!feof(input)) { // read input int rnum = fread(buffer, sizeof(char), BSIZE, input); if (rnum != BSIZE) { if (ferror(input) != 0) { ERROR_LOG(COMMON, "Copy: failed reading from source, %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); fclose(input); fclose(output); return false; } } // write output int wnum = fwrite(buffer, sizeof(char), rnum, output); if (wnum != rnum) { ERROR_LOG(COMMON, "Copy: failed writing to output, %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); fclose(input); fclose(output); return false; } } // close flushs fclose(input); fclose(output); return true; #endif }
size_t VirtualDiscFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size, int &usec) { ERROR_LOG(FILESYS,"VirtualDiscFileSystem: Cannot write to file on virtual disc"); return 0; }