+}
+uint32_t IOPMrootDomain::checkForValidDebugData(const char *fname, vfs_context_t *ctx,
+ void *tmpBuf, struct vnode **vp)
+{
+ int rc;
+ uint64_t hdrOffset;
+ uint32_t error = 0;
+
+ struct vnode_attr va;
+ IOHibernateImageHeader *imageHdr;
+
+ *vp = NULL;
+ if (vnode_open(fname, (FREAD | O_NOFOLLOW), 0,
+ VNODE_LOOKUP_NOFOLLOW, vp, *ctx) != 0)
+ {
+ DMSG("sleepWakeDebugDumpFromFile: Failed to open the file %s\n", fname);
+ goto err;
+ }
+ VATTR_INIT(&va);
+ VATTR_WANTED(&va, va_nlink);
+ VATTR_WANTED(&va, va_data_alloc);
+ if ((*vp)->v_type != VREG ||
+ vnode_getattr((*vp), &va, *ctx) || va.va_nlink != 1) {
+ IOLog("sleepWakeDebugDumpFromFile: Bailing as %s is not a regular file\n", fname);
+ error = SWD_FILEOP_ERROR;
+ goto err;
+ }
+
+ /* Read the sleepimage file header */
+ rc = vn_rdwr(UIO_READ, *vp, (char *)tmpBuf, round_page(sizeof(IOHibernateImageHeader)), 0,
+ UIO_SYSSPACE, IO_SKIP_ENCRYPTION|IO_SYNC|IO_NODELOCKED|IO_UNIT|IO_NOCACHE,
+ vfs_context_ucred(*ctx), (int *) 0,
+ vfs_context_proc(*ctx));
+ if (rc != 0) {
+ IOLog("sleepWakeDebugDumpFromFile: Failed to read header size %llu(rc=%d) from %s\n",
+ mach_vm_round_page(sizeof(IOHibernateImageHeader)), rc, fname);
+ error = SWD_FILEOP_ERROR;
+ goto err;
+ }
+
+ imageHdr = ((IOHibernateImageHeader *)tmpBuf);
+ if (imageHdr->signature != kIOHibernateHeaderDebugDataSignature) {
+ IOLog("sleepWakeDebugDumpFromFile: File %s header has unexpected value 0x%x\n",
+ fname, imageHdr->signature);
+ error = SWD_HDR_SIGNATURE_ERROR;
+ goto err;
+ }
+
+ /* Sleep/Wake debug header(swd_hdr) is at the beggining of the second block */
+ hdrOffset = imageHdr->deviceBlockSize;
+ if (hdrOffset + sizeof(swd_hdr) >= va.va_data_alloc) {
+ IOLog("sleepWakeDebugDumpFromFile: header is crossing file size(0x%llx) in file %s\n",
+ va.va_data_alloc, fname);
+ error = SWD_HDR_SIZE_ERROR;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ if (*vp) vnode_close(*vp, FREAD, *ctx);
+ *vp = NULL;
+
+ return error;