int mixer_ctl_set_value(struct mixer_ctl *ctl, int count, char ** argv) { unsigned int size; unsigned int *tlv = NULL; long min, max; enum ctl_type type; unsigned int tlv_type; if (is_volume(ctl->info->id.name, &type)) { ALOGV("capability: volume\n"); tlv = calloc(1, DEFAULT_TLV_SIZE); if (tlv == NULL) { ALOGE("failed to allocate memory\n"); } else if (!mixer_ctl_read_tlv(ctl, tlv, &min, &max, &tlv_type)) { ALOGV("min = %x max = %x", min, max); if (set_volume_simple(ctl, argv, min, max, count)) mixer_ctl_mulvalues(ctl, count, argv); } else ALOGV("mixer_ctl_read_tlv failed\n"); free(tlv); } else { mixer_ctl_mulvalues(ctl, count, argv); } return 0; }
void mixer_ctl_get(struct mixer_ctl *ctl, unsigned *value) { struct snd_ctl_elem_value ev; unsigned int n; unsigned int *tlv = NULL; enum ctl_type type; unsigned int *tlv_type; long min, max; if (is_volume(ctl->info->id.name, &type)) { ALOGV("capability: volume\n"); tlv = calloc(1, DEFAULT_TLV_SIZE); if (tlv == NULL) { ALOGE("failed to allocate memory\n"); } else { mixer_ctl_read_tlv(ctl, tlv, &min, &max, &tlv_type); free(tlv); } } memset(&ev, 0, sizeof(ev)); ev.id.numid = ctl->info->id.numid; if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev)) return; ALOGV("%s:", ctl->info->id.name); switch (ctl->info->type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: for (n = 0; n < ctl->info->count; n++) ALOGV(" %s", ev.value.integer.value[n] ? "on" : "off"); *value = ev.value.integer.value[0]; break; case SNDRV_CTL_ELEM_TYPE_INTEGER: { for (n = 0; n < ctl->info->count; n++) ALOGV(" %ld", ev.value.integer.value[n]); *value = ev.value.integer.value[0]; break; } case SNDRV_CTL_ELEM_TYPE_INTEGER64: for (n = 0; n < ctl->info->count; n++) ALOGV(" %lld", ev.value.integer64.value[n]); *value = ev.value.integer64.value[0]; break; case SNDRV_CTL_ELEM_TYPE_ENUMERATED: for (n = 0; n < ctl->info->count; n++) { unsigned v = ev.value.enumerated.item[n]; ALOGV(" %d (%s)", v, (v < ctl->info->value.enumerated.items) ? ctl->ename[v] : "???"); *value = ev.value.enumerated.item[0]; } break; default: ALOGV(" ???"); } ALOGV("\n"); }
void mixer_dump(struct mixer *mixer) { unsigned n, m; ALOGV(" id iface dev sub idx num perms type isvolume name\n"); for (n = 0; n < mixer->count; n++) { enum ctl_type type; struct snd_ctl_elem_info *ei = mixer->info + n; ALOGV("%4d %5s %3d %3d %3d %3d %c%c%c%c%c%c%c%c%c %-6s %8d %s", ei->id.numid, elem_iface_name(ei->id.iface), ei->id.device, ei->id.subdevice, ei->id.index, ei->count, (ei->access & SNDRV_CTL_ELEM_ACCESS_READ) ? 'r' : ' ', (ei->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ? 'w' : ' ', (ei->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE) ? 'V' : ' ', (ei->access & SNDRV_CTL_ELEM_ACCESS_TIMESTAMP) ? 'T' : ' ', (ei->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) ? 'R' : ' ', (ei->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) ? 'W' : ' ', (ei->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND) ? 'C' : ' ', (ei->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) ? 'I' : ' ', (ei->access & SNDRV_CTL_ELEM_ACCESS_LOCK) ? 'L' : ' ', elem_type_name(ei->type), (is_volume(ei->id.name, &type)) ? 1 : 0, ei->id.name); switch (ei->type) { case SNDRV_CTL_ELEM_TYPE_INTEGER: ALOGV(ei->value.integer.step ? " { %ld-%ld, %ld }\n" : " { %ld-%ld }", ei->value.integer.min, ei->value.integer.max, ei->value.integer.step); break; case SNDRV_CTL_ELEM_TYPE_INTEGER64: ALOGV(ei->value.integer64.step ? " { %lld-%lld, %lld }\n" : " { %lld-%lld }", ei->value.integer64.min, ei->value.integer64.max, ei->value.integer64.step); break; case SNDRV_CTL_ELEM_TYPE_ENUMERATED: { unsigned m; ALOGV(" { %s=0", mixer->ctl[n].ename[0]); for (m = 1; m < ei->value.enumerated.items; m++) ALOGV(", %s=%d", mixer->ctl[n].ename[m],m); ALOGV(" }"); break; } } ALOGV("\n"); } }
int mixer_ctl_set(struct mixer_ctl *ctl, unsigned percent) { struct snd_ctl_elem_value ev; unsigned n; long min, max; unsigned int *tlv = NULL; enum ctl_type type; int volume = 0; unsigned int tlv_type; if (!ctl) { ALOGV("can't find control\n"); return -1; } if (is_volume(ctl->info->id.name, &type)) { ALOGV("capability: volume\n"); tlv = calloc(1, DEFAULT_TLV_SIZE); if (tlv == NULL) { ALOGE("failed to allocate memory\n"); } else if (!mixer_ctl_read_tlv(ctl, tlv, &min, &max, &tlv_type)) { switch(tlv_type) { case SNDRV_CTL_TLVT_DB_LINEAR: case SNDRV_CTL_TLVT_DB_MINMAX: ALOGV("tlv db linear/db minmax: b4 %d\n", percent); if (min < 0) { max = max - min; min = 0; } percent = check_range(percent, min, max); ALOGV("tlv db linear: %d %d %d\n", percent, min, max); volume = 1; break; default: percent = (long)percent_to_index(percent, min, max); percent = check_range(percent, min, max); volume = 1; break; } } else ALOGV("mixer_ctl_read_tlv failed\n"); free(tlv); } memset(&ev, 0, sizeof(ev)); ev.id.numid = ctl->info->id.numid; switch (ctl->info->type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: for (n = 0; n < ctl->info->count; n++) ev.value.integer.value[n] = !!percent; break; case SNDRV_CTL_ELEM_TYPE_INTEGER: { int value; if (!volume) value = scale_int(ctl->info, percent); else value = (int) percent; for (n = 0; n < ctl->info->count; n++) ev.value.integer.value[n] = value; break; } case SNDRV_CTL_ELEM_TYPE_INTEGER64: { long long value; if (!volume) value = scale_int64(ctl->info, percent); else value = (long long)percent; for (n = 0; n < ctl->info->count; n++) ev.value.integer64.value[n] = value; break; } case SNDRV_CTL_ELEM_TYPE_IEC958: { struct snd_aes_iec958 *iec958; iec958 = (struct snd_aes_iec958 *)percent; memcpy(ev.value.iec958.status,iec958->status,SPDIF_CHANNEL_STATUS_SIZE); break; } case SNDRV_CTL_ELEM_TYPE_ENUMERATED: { for (n = 0; n < ctl->info->count; n++) { ev.value.enumerated.item[n] = (unsigned int)percent; } break; } default: errno = EINVAL; return errno; } return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); }
std::vector<SFile> getFilesWin(const std::string &path, bool *has_error, bool exact_filesize, bool with_usn, bool ignore_other_fs) { if(has_error!=NULL) { *has_error=false; } std::vector<char> usn_buffer; usn_buffer.resize(1024); std::vector<SFile> tmp; HANDLE fHandle; WIN32_FIND_DATAW wfd; std::wstring tpath=ConvertToWchar(path); if(!tpath.empty() && tpath[tpath.size()-1]=='\\' ) tpath.erase(tpath.size()-1, 1); fHandle=FindFirstFileW((tpath+L"\\*").c_str(),&wfd); if(fHandle==INVALID_HANDLE_VALUE) { if(tpath.find(L"\\\\?\\UNC")==0) { tpath.erase(0, 7); tpath=L"\\"+tpath; fHandle=FindFirstFileW((tpath+L"\\*").c_str(),&wfd); } else if(tpath.find(L"\\\\?\\")==0) { tpath.erase(0, 4); fHandle=FindFirstFileW((tpath+L"\\*").c_str(),&wfd); } if(fHandle==INVALID_HANDLE_VALUE) { if(has_error!=NULL) { *has_error=true; } return tmp; } } do { SFile f; f.name=ConvertFromWchar(wfd.cFileName); if(f.name=="." || f.name==".." ) continue; f.usn=0; f.isdir=(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)>0; LARGE_INTEGER lwt; lwt.HighPart=wfd.ftLastWriteTime.dwHighDateTime; lwt.LowPart=wfd.ftLastWriteTime.dwLowDateTime; f.last_modified=os_windows_to_unix_time(lwt.QuadPart); LARGE_INTEGER size; size.HighPart=wfd.nFileSizeHigh; size.LowPart=wfd.nFileSizeLow; f.size=size.QuadPart; lwt.HighPart=wfd.ftCreationTime.dwHighDateTime; lwt.LowPart=wfd.ftCreationTime.dwLowDateTime; f.created=os_windows_to_unix_time(lwt.QuadPart); std::string reparse_target; if (ignore_other_fs && wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && wfd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT && os_get_symlink_target(os_file_prefix(path + os_file_sep() + f.name), reparse_target) && is_volume(reparse_target) ) { continue; } else if(wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && (wfd.dwReserved0== IO_REPARSE_TAG_SYMLINK || wfd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) ) { f.issym=true; f.isspecialf=true; } else if (wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && (wfd.dwReserved0 == 0x8000001b /*IO_REPARSE_TAG_APPEXECLINK*/ )) { f.isspecialf = true; } f.isencrypted = (wfd.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED)>0; if( (exact_filesize && !f.isdir && !f.issym ) || with_usn ) { if(with_usn) { HANDLE hFile = CreateFileW(os_file_prefix(tpath+L"\\"+ConvertToWchar(f.name)).c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); if(hFile!=INVALID_HANDLE_VALUE) { if (exact_filesize && !f.isdir && !f.issym) { BY_HANDLE_FILE_INFORMATION fileInformation; if (GetFileInformationByHandle(hFile, &fileInformation)!=0) { LARGE_INTEGER fsize; fsize.LowPart = fileInformation.nFileSizeLow; fsize.HighPart = fileInformation.nFileSizeHigh; f.size = fsize.QuadPart; f.nlinks = fileInformation.nNumberOfLinks; } } DWORD last_err=0; do { DWORD ret_bytes = 0; BOOL b = DeviceIoControl(hFile, FSCTL_READ_FILE_USN_DATA, NULL, 0, usn_buffer.data(), static_cast<DWORD>(usn_buffer.size()), &ret_bytes, NULL); if(b) { USN_RECORD* usnv2=reinterpret_cast<USN_RECORD*>(usn_buffer.data()); if(usnv2->MajorVersion==2) { f.usn = usnv2->Usn; } else if(usnv2->MajorVersion==3) { usn::USN_RECORD_V3* usnv3=reinterpret_cast<usn::USN_RECORD_V3*>(usn_buffer.data()); f.usn = usnv3->Usn; } else { Log("USN entry major version "+convert(usnv2->MajorVersion)+" of file \""+ConvertFromWchar(tpath)+"\\"+f.name+"\" not supported", LL_ERROR); } } else { last_err=GetLastError(); } if(last_err==ERROR_INSUFFICIENT_BUFFER) { usn_buffer.resize(usn_buffer.size()*2); } } while (last_err==ERROR_INSUFFICIENT_BUFFER); CloseHandle(hFile); } } else { WIN32_FILE_ATTRIBUTE_DATA fad; if( GetFileAttributesExW(os_file_prefix(tpath+L"\\"+ConvertToWchar(f.name)).c_str(), GetFileExInfoStandard, &fad) ) { size.HighPart = fad.nFileSizeHigh; size.LowPart = fad.nFileSizeLow; f.size = size.QuadPart; lwt.HighPart = fad.ftLastWriteTime.dwHighDateTime; lwt.LowPart = fad.ftLastWriteTime.dwLowDateTime; f.last_modified = os_windows_to_unix_time(lwt.QuadPart); lwt.HighPart=fad.ftCreationTime.dwHighDateTime; lwt.LowPart=fad.ftCreationTime.dwLowDateTime; f.created=os_windows_to_unix_time(lwt.QuadPart); } } } if(f.last_modified<0) f.last_modified*=-1; tmp.push_back(f); } while (FindNextFileW(fHandle,&wfd) ); if (GetLastError() != ERROR_NO_MORE_FILES) { DWORD err = GetLastError(); if (has_error != NULL) { *has_error = true; } FindClose(fHandle); std::sort(tmp.begin(), tmp.end()); SetLastError(err); return tmp; } FindClose(fHandle); std::sort(tmp.begin(), tmp.end()); return tmp; }